Commit e0580b50 authored by David S. Miller's avatar David S. Miller
Browse files

Merge tag 'linux-can-next-for-5.5-20191111' of...

Merge tag 'linux-can-next-for-5.5-20191111' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can-next



Marc Kleine-Budde says:

====================
pull-request: can-next 2019-10-07

this is a pull request for net-next/master consisting of 32 patches.

The first patch is by Gustavo A. R. Silva and removes unused code in the
generic CAN infrastructure.

The next three patches target the mcp251x driver. The one by Andy
Shevchenko removes the legacy platform data support from the driver. The
other two are by Timo Schlüßler and reset the device only when needed,
to prevent glitches on the output when GPIO support is added.

I'm contributing two patches fixing checkpatch warnings in the
c_can_platform and peak_canfd driver.

Stephane Grosjean's patch for the peak_canfd driver adds hw timestamps
support in rx skbs.

The next three patches target the xilinx_can driver. One patch by me to
fix checkpatch warnings, one patch by Anssi Hannula to avoid non
requested bus error frames, and a patch by YueHaibing that switches the
driver to devm_platform_ioremap_resource().

Pankaj Sharma contributes two patches for the m_can driver, the first
one adds support for one shot mode, the other support for handling
arbitration errors.

Followed by four patches by YueHaibing, switching the grcan, ifi, rcar,
and sun4i drivers to devm_platform_ioremap_resource()

I'm contributing cleanup patches for the rx-offload helper, while Joakim
Zhang's patch prepares the rx-offload helper for CAN-FD support. The rx
offload users flexcan and ti_hecc are converted accordingly.

The remaining twelve patches target the flexcan driver. First Joakim
Zhang switches the driver to devm_platform_ioremap_resource(). The
remaining eleven patch are by me and clean up the abstract the access of
the iflag1 and iflag2 register both for RX and TX mailboxes. This is a
preparation for the upcoming CAN-FD support.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 9440a875 b9468ad8
Loading
Loading
Loading
Loading
+5 −4
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@

#include <linux/irq.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/gpio.h>

#include <asm/mach-types.h>
@@ -22,7 +23,6 @@

#include <linux/spi/spi.h>
#include <linux/spi/pxa2xx_spi.h>
#include <linux/can/platform/mcp251x.h>
#include <linux/regulator/machine.h>

#include "generic.h"
@@ -69,8 +69,9 @@ static struct pxa2xx_spi_chip mcp251x_chip_info4 = {
	.gpio_cs        = ICONTROL_MCP251x_nCS4
};

static struct mcp251x_platform_data mcp251x_info = {
	.oscillator_frequency = 16E6,
static const struct property_entry mcp251x_properties[] = {
	PROPERTY_ENTRY_U32("clock-frequency", 16000000),
	{}
};

static struct spi_board_info mcp251x_board_info[] = {
@@ -79,7 +80,7 @@ static struct spi_board_info mcp251x_board_info[] = {
		.max_speed_hz    = 6500000,
		.bus_num         = 3,
		.chip_select     = 0,
		.platform_data   = &mcp251x_info,
		.properties      = mcp251x_properties,
		.controller_data = &mcp251x_chip_info1,
		.irq             = PXA_GPIO_TO_IRQ(ICONTROL_MCP251x_nIRQ1)
	},
+5 −4
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@
#include <linux/leds.h>
#include <linux/irq.h>
#include <linux/pm.h>
#include <linux/property.h>
#include <linux/gpio.h>
#include <linux/gpio/machine.h>
#include <linux/serial_8250.h>
@@ -27,7 +28,6 @@
#include <linux/platform_data/i2c-pxa.h>
#include <linux/platform_data/pca953x.h>
#include <linux/apm-emulation.h>
#include <linux/can/platform/mcp251x.h>
#include <linux/regulator/fixed.h>
#include <linux/regulator/machine.h>

@@ -428,14 +428,15 @@ static struct gpiod_lookup_table can_regulator_gpiod_table = {
	},
};

static struct mcp251x_platform_data zeus_mcp2515_pdata = {
	.oscillator_frequency	= 16*1000*1000,
static const struct property_entry mcp251x_properties[] = {
	PROPERTY_ENTRY_U32("clock-frequency", 16000000),
	{}
};

static struct spi_board_info zeus_spi_board_info[] = {
	[0] = {
		.modalias	= "mcp2515",
		.platform_data	= &zeus_mcp2515_pdata,
		.properties	= mcp251x_properties,
		.irq		= PXA_GPIO_TO_IRQ(ZEUS_CAN_GPIO),
		.max_speed_hz	= 1*1000*1000,
		.bus_num	= 3,
+11 −10
Original line number Diff line number Diff line
@@ -39,10 +39,11 @@

#include "c_can.h"

#define DCAN_RAM_INIT_BIT		(1 << 3)
#define DCAN_RAM_INIT_BIT BIT(3)

static DEFINE_SPINLOCK(raminit_lock);
/*
 * 16-bit c_can registers can be arranged differently in the memory

/* 16-bit c_can registers can be arranged differently in the memory
 * architecture of different implementations. For example: 16-bit
 * registers can be aligned to a 16-bit boundary or 32-bit boundary etc.
 * Handle the same by providing a common read/write interface.
@@ -149,8 +150,8 @@ static u32 c_can_plat_read_reg32(const struct c_can_priv *priv, enum reg index)
	return val;
}

static void c_can_plat_write_reg32(const struct c_can_priv *priv, enum reg index,
		u32 val)
static void c_can_plat_write_reg32(const struct c_can_priv *priv,
				   enum reg index, u32 val)
{
	priv->write_reg(priv, index + 1, val >> 16);
	priv->write_reg(priv, index, val);
@@ -161,8 +162,8 @@ static u32 d_can_plat_read_reg32(const struct c_can_priv *priv, enum reg index)
	return readl(priv->base + priv->regs[index]);
}

static void d_can_plat_write_reg32(const struct c_can_priv *priv, enum reg index,
		u32 val)
static void d_can_plat_write_reg32(const struct c_can_priv *priv,
				   enum reg index, u32 val)
{
	writel(val, priv->base + priv->regs[index]);
}
+2 −3
Original line number Diff line number Diff line
@@ -553,10 +553,9 @@ static void can_restart(struct net_device *dev)

	/* send restart message upstream */
	skb = alloc_can_err_skb(dev, &cf);
	if (!skb) {
		err = -ENOMEM;
	if (!skb)
		goto restart;
	}

	cf->can_id |= CAN_ERR_RESTARTED;

	netif_rx(skb);
+75 −56
Original line number Diff line number Diff line
@@ -142,7 +142,7 @@
#define FLEXCAN_TX_MB_RESERVED_OFF_FIFO		8
#define FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP	0
#define FLEXCAN_RX_MB_OFF_TIMESTAMP_FIRST	(FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP + 1)
#define FLEXCAN_IFLAG_MB(x)		BIT((x) & 0x1f)
#define FLEXCAN_IFLAG_MB(x)		BIT_ULL(x)
#define FLEXCAN_IFLAG_RX_FIFO_OVERFLOW	BIT(7)
#define FLEXCAN_IFLAG_RX_FIFO_WARN	BIT(6)
#define FLEXCAN_IFLAG_RX_FIFO_AVAILABLE	BIT(5)
@@ -277,9 +277,9 @@ struct flexcan_priv {
	u8 mb_size;
	u8 clk_src;	/* clock source of CAN Protocol Engine */

	u64 rx_mask;
	u64 tx_mask;
	u32 reg_ctrl_default;
	u32 reg_imask1_default;
	u32 reg_imask2_default;

	struct clk *clk_ipg;
	struct clk *clk_per;
@@ -743,8 +743,6 @@ static void flexcan_irq_state(struct net_device *dev, u32 reg_esr)
	u32 timestamp;
	int err;

	timestamp = priv->read(&regs->timer) << 16;

	flt = reg_esr & FLEXCAN_ESR_FLT_CONF_MASK;
	if (likely(flt == FLEXCAN_ESR_FLT_CONF_ACTIVE)) {
		tx_state = unlikely(reg_esr & FLEXCAN_ESR_TX_WRN) ?
@@ -764,6 +762,8 @@ static void flexcan_irq_state(struct net_device *dev, u32 reg_esr)
	if (likely(new_state == priv->can.state))
		return;

	timestamp = priv->read(&regs->timer) << 16;

	skb = alloc_can_err_skb(dev, &cf);
	if (unlikely(!skb))
		return;
@@ -778,21 +778,58 @@ static void flexcan_irq_state(struct net_device *dev, u32 reg_esr)
		dev->stats.rx_fifo_errors++;
}

static inline u64 flexcan_read64_mask(struct flexcan_priv *priv, void __iomem *addr, u64 mask)
{
	u64 reg = 0;

	if (upper_32_bits(mask))
		reg = (u64)priv->read(addr - 4) << 32;
	if (lower_32_bits(mask))
		reg |= priv->read(addr);

	return reg & mask;
}

static inline void flexcan_write64(struct flexcan_priv *priv, u64 val, void __iomem *addr)
{
	if (upper_32_bits(val))
		priv->write(upper_32_bits(val), addr - 4);
	if (lower_32_bits(val))
		priv->write(lower_32_bits(val), addr);
}

static inline u64 flexcan_read_reg_iflag_rx(struct flexcan_priv *priv)
{
	return flexcan_read64_mask(priv, &priv->regs->iflag1, priv->rx_mask);
}

static inline u64 flexcan_read_reg_iflag_tx(struct flexcan_priv *priv)
{
	return flexcan_read64_mask(priv, &priv->regs->iflag1, priv->tx_mask);
}

static inline struct flexcan_priv *rx_offload_to_priv(struct can_rx_offload *offload)
{
	return container_of(offload, struct flexcan_priv, offload);
}

static unsigned int flexcan_mailbox_read(struct can_rx_offload *offload,
					 struct can_frame *cf,
					 u32 *timestamp, unsigned int n)
static struct sk_buff *flexcan_mailbox_read(struct can_rx_offload *offload,
					    unsigned int n, u32 *timestamp,
					    bool drop)
{
	struct flexcan_priv *priv = rx_offload_to_priv(offload);
	struct flexcan_regs __iomem *regs = priv->regs;
	struct flexcan_mb __iomem *mb;
	struct sk_buff *skb;
	struct can_frame *cf;
	u32 reg_ctrl, reg_id, reg_iflag1;
	int i;

	if (unlikely(drop)) {
		skb = ERR_PTR(-ENOBUFS);
		goto mark_as_read;
	}

	mb = flexcan_get_mb(priv, n);

	if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) {
@@ -806,7 +843,7 @@ static unsigned int flexcan_mailbox_read(struct can_rx_offload *offload,
		code = reg_ctrl & FLEXCAN_MB_CODE_MASK;
		if ((code != FLEXCAN_MB_CODE_RX_FULL) &&
		    (code != FLEXCAN_MB_CODE_RX_OVERRUN))
			return 0;
			return NULL;

		if (code == FLEXCAN_MB_CODE_RX_OVERRUN) {
			/* This MB was overrun, we lost data */
@@ -816,11 +853,17 @@ static unsigned int flexcan_mailbox_read(struct can_rx_offload *offload,
	} else {
		reg_iflag1 = priv->read(&regs->iflag1);
		if (!(reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_AVAILABLE))
			return 0;
			return NULL;

		reg_ctrl = priv->read(&mb->can_ctrl);
	}

	skb = alloc_can_skb(offload->dev, &cf);
	if (!skb) {
		skb = ERR_PTR(-ENOMEM);
		goto mark_as_read;
	}

	/* increase timstamp to full 32 bit */
	*timestamp = reg_ctrl << 16;

@@ -839,16 +882,11 @@ static unsigned int flexcan_mailbox_read(struct can_rx_offload *offload,
		*(__be32 *)(cf->data + i) = data;
	}

	/* mark as read */
	if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) {
		/* Clear IRQ */
		if (n < 32)
			priv->write(BIT(n), &regs->iflag1);
 mark_as_read:
	if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP)
		flexcan_write64(priv, FLEXCAN_IFLAG_MB(n), &regs->iflag1);
	else
			priv->write(BIT(n - 32), &regs->iflag2);
	} else {
		priv->write(FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, &regs->iflag1);
	}

	/* Read the Free Running Timer. It is optional but recommended
	 * to unlock Mailbox as soon as possible and make it available
@@ -856,20 +894,7 @@ static unsigned int flexcan_mailbox_read(struct can_rx_offload *offload,
	 */
	priv->read(&regs->timer);

	return 1;
}


static inline u64 flexcan_read_reg_iflag_rx(struct flexcan_priv *priv)
{
	struct flexcan_regs __iomem *regs = priv->regs;
	u32 iflag1, iflag2;

	iflag2 = priv->read(&regs->iflag2) & priv->reg_imask2_default &
		~FLEXCAN_IFLAG_MB(priv->tx_mb_idx);
	iflag1 = priv->read(&regs->iflag1) & priv->reg_imask1_default;

	return (u64)iflag2 << 32 | iflag1;
	return skb;
}

static irqreturn_t flexcan_irq(int irq, void *dev_id)
@@ -879,18 +904,19 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
	struct flexcan_priv *priv = netdev_priv(dev);
	struct flexcan_regs __iomem *regs = priv->regs;
	irqreturn_t handled = IRQ_NONE;
	u32 reg_iflag2, reg_esr;
	u64 reg_iflag_tx;
	u32 reg_esr;
	enum can_state last_state = priv->can.state;

	/* reception interrupt */
	if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) {
		u64 reg_iflag;
		u64 reg_iflag_rx;
		int ret;

		while ((reg_iflag = flexcan_read_reg_iflag_rx(priv))) {
		while ((reg_iflag_rx = flexcan_read_reg_iflag_rx(priv))) {
			handled = IRQ_HANDLED;
			ret = can_rx_offload_irq_offload_timestamp(&priv->offload,
								   reg_iflag);
								   reg_iflag_rx);
			if (!ret)
				break;
		}
@@ -913,10 +939,10 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
		}
	}

	reg_iflag2 = priv->read(&regs->iflag2);
	reg_iflag_tx = flexcan_read_reg_iflag_tx(priv);

	/* transmission complete interrupt */
	if (reg_iflag2 & FLEXCAN_IFLAG_MB(priv->tx_mb_idx)) {
	if (reg_iflag_tx & priv->tx_mask) {
		u32 reg_ctrl = priv->read(&priv->tx_mb->can_ctrl);

		handled = IRQ_HANDLED;
@@ -928,7 +954,7 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
		/* after sending a RTR frame MB is in RX mode */
		priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
			    &priv->tx_mb->can_ctrl);
		priv->write(FLEXCAN_IFLAG_MB(priv->tx_mb_idx), &regs->iflag2);
		flexcan_write64(priv, priv->tx_mask, &regs->iflag1);
		netif_wake_queue(dev);
	}

@@ -1040,6 +1066,7 @@ static int flexcan_chip_start(struct net_device *dev)
	struct flexcan_priv *priv = netdev_priv(dev);
	struct flexcan_regs __iomem *regs = priv->regs;
	u32 reg_mcr, reg_ctrl, reg_ctrl2, reg_mecr;
	u64 reg_imask;
	int err, i;
	struct flexcan_mb __iomem *mb;

@@ -1214,8 +1241,9 @@ static int flexcan_chip_start(struct net_device *dev)
	/* enable interrupts atomically */
	disable_irq(dev->irq);
	priv->write(priv->reg_ctrl_default, &regs->ctrl);
	priv->write(priv->reg_imask1_default, &regs->imask1);
	priv->write(priv->reg_imask2_default, &regs->imask2);
	reg_imask = priv->rx_mask | priv->tx_mask;
	priv->write(upper_32_bits(reg_imask), &regs->imask2);
	priv->write(lower_32_bits(reg_imask), &regs->imask1);
	enable_irq(dev->irq);

	/* print chip status */
@@ -1283,26 +1311,19 @@ static int flexcan_open(struct net_device *dev)
			flexcan_get_mb(priv, FLEXCAN_TX_MB_RESERVED_OFF_FIFO);
	priv->tx_mb_idx = priv->mb_count - 1;
	priv->tx_mb = flexcan_get_mb(priv, priv->tx_mb_idx);

	priv->reg_imask1_default = 0;
	priv->reg_imask2_default = FLEXCAN_IFLAG_MB(priv->tx_mb_idx);
	priv->tx_mask = FLEXCAN_IFLAG_MB(priv->tx_mb_idx);

	priv->offload.mailbox_read = flexcan_mailbox_read;

	if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) {
		u64 imask;

		priv->offload.mb_first = FLEXCAN_RX_MB_OFF_TIMESTAMP_FIRST;
		priv->offload.mb_last = priv->mb_count - 2;

		imask = GENMASK_ULL(priv->offload.mb_last,
		priv->rx_mask = GENMASK_ULL(priv->offload.mb_last,
					    priv->offload.mb_first);
		priv->reg_imask1_default |= imask;
		priv->reg_imask2_default |= imask >> 32;

		err = can_rx_offload_add_timestamp(dev, &priv->offload);
	} else {
		priv->reg_imask1_default |= FLEXCAN_IFLAG_RX_FIFO_OVERFLOW |
		priv->rx_mask = FLEXCAN_IFLAG_RX_FIFO_OVERFLOW |
			FLEXCAN_IFLAG_RX_FIFO_AVAILABLE;
		err = can_rx_offload_add_fifo(dev, &priv->offload,
					      FLEXCAN_NAPI_WEIGHT);
@@ -1534,7 +1555,6 @@ static int flexcan_probe(struct platform_device *pdev)
	struct net_device *dev;
	struct flexcan_priv *priv;
	struct regulator *reg_xceiver;
	struct resource *mem;
	struct clk *clk_ipg = NULL, *clk_per = NULL;
	struct flexcan_regs __iomem *regs;
	int err, irq;
@@ -1569,12 +1589,11 @@ static int flexcan_probe(struct platform_device *pdev)
		clock_freq = clk_get_rate(clk_per);
	}

	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	irq = platform_get_irq(pdev, 0);
	if (irq <= 0)
		return -ENODEV;

	regs = devm_ioremap_resource(&pdev->dev, mem);
	regs = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(regs))
		return PTR_ERR(regs);

Loading