Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

Merge tag 'linux-can-fixes-for-4.16-20180312' of...

Merge tag 'linux-can-fixes-for-4.16-20180312' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can



Marc Kleine-Budde says:

====================
pull-request: can 2018-03-12

this is a pull reqeust of 6 patches for net/master.

The first patch is by Wolfram Sang and fixes a bitshift vs. comparison mistake
in the m_can driver. Two patches of Marek Vasut repair the error handling in
the ifi driver. The two patches by Stephane Grosjean fix a "echo_skb is
occupied!" bug in the peak/pcie_fd driver. Bich HEMON's patch adds pinctrl
select state calls to the m_can's driver to further improve power saving during
suspend.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents bf2ae2e4 c9b3bce1
Loading
Loading
Loading
Loading
+47 −28
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@
#define IFI_CANFD_STCMD_ERROR_ACTIVE		BIT(2)
#define IFI_CANFD_STCMD_ERROR_PASSIVE		BIT(3)
#define IFI_CANFD_STCMD_BUSOFF			BIT(4)
#define IFI_CANFD_STCMD_ERROR_WARNING		BIT(5)
#define IFI_CANFD_STCMD_BUSMONITOR		BIT(16)
#define IFI_CANFD_STCMD_LOOPBACK		BIT(18)
#define IFI_CANFD_STCMD_DISABLE_CANFD		BIT(24)
@@ -52,7 +53,10 @@
#define IFI_CANFD_TXSTCMD_OVERFLOW		BIT(13)

#define IFI_CANFD_INTERRUPT			0xc
#define IFI_CANFD_INTERRUPT_ERROR_BUSOFF	BIT(0)
#define IFI_CANFD_INTERRUPT_ERROR_WARNING	BIT(1)
#define IFI_CANFD_INTERRUPT_ERROR_STATE_CHG	BIT(2)
#define IFI_CANFD_INTERRUPT_ERROR_REC_TEC_INC	BIT(3)
#define IFI_CANFD_INTERRUPT_ERROR_COUNTER	BIT(10)
#define IFI_CANFD_INTERRUPT_TXFIFO_EMPTY	BIT(16)
#define IFI_CANFD_INTERRUPT_TXFIFO_REMOVE	BIT(22)
@@ -61,6 +65,10 @@
#define IFI_CANFD_INTERRUPT_SET_IRQ		((u32)BIT(31))

#define IFI_CANFD_IRQMASK			0x10
#define IFI_CANFD_IRQMASK_ERROR_BUSOFF		BIT(0)
#define IFI_CANFD_IRQMASK_ERROR_WARNING		BIT(1)
#define IFI_CANFD_IRQMASK_ERROR_STATE_CHG	BIT(2)
#define IFI_CANFD_IRQMASK_ERROR_REC_TEC_INC	BIT(3)
#define IFI_CANFD_IRQMASK_SET_ERR		BIT(7)
#define IFI_CANFD_IRQMASK_SET_TS		BIT(15)
#define IFI_CANFD_IRQMASK_TXFIFO_EMPTY		BIT(16)
@@ -136,6 +144,8 @@
#define IFI_CANFD_SYSCLOCK			0x50

#define IFI_CANFD_VER				0x54
#define IFI_CANFD_VER_REV_MASK			0xff
#define IFI_CANFD_VER_REV_MIN_SUPPORTED		0x15

#define IFI_CANFD_IP_ID				0x58
#define IFI_CANFD_IP_ID_VALUE			0xD073CAFD
@@ -220,7 +230,10 @@ static void ifi_canfd_irq_enable(struct net_device *ndev, bool enable)

	if (enable) {
		enirq = IFI_CANFD_IRQMASK_TXFIFO_EMPTY |
			IFI_CANFD_IRQMASK_RXFIFO_NEMPTY;
			IFI_CANFD_IRQMASK_RXFIFO_NEMPTY |
			IFI_CANFD_IRQMASK_ERROR_STATE_CHG |
			IFI_CANFD_IRQMASK_ERROR_WARNING |
			IFI_CANFD_IRQMASK_ERROR_BUSOFF;
		if (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)
			enirq |= IFI_CANFD_INTERRUPT_ERROR_COUNTER;
	}
@@ -361,12 +374,13 @@ static int ifi_canfd_handle_lost_msg(struct net_device *ndev)
	return 1;
}

static int ifi_canfd_handle_lec_err(struct net_device *ndev, const u32 errctr)
static int ifi_canfd_handle_lec_err(struct net_device *ndev)
{
	struct ifi_canfd_priv *priv = netdev_priv(ndev);
	struct net_device_stats *stats = &ndev->stats;
	struct can_frame *cf;
	struct sk_buff *skb;
	u32 errctr = readl(priv->base + IFI_CANFD_ERROR_CTR);
	const u32 errmask = IFI_CANFD_ERROR_CTR_OVERLOAD_FIRST |
			    IFI_CANFD_ERROR_CTR_ACK_ERROR_FIRST |
			    IFI_CANFD_ERROR_CTR_BIT0_ERROR_FIRST |
@@ -449,6 +463,11 @@ static int ifi_canfd_handle_state_change(struct net_device *ndev,

	switch (new_state) {
	case CAN_STATE_ERROR_ACTIVE:
		/* error active state */
		priv->can.can_stats.error_warning++;
		priv->can.state = CAN_STATE_ERROR_ACTIVE;
		break;
	case CAN_STATE_ERROR_WARNING:
		/* error warning state */
		priv->can.can_stats.error_warning++;
		priv->can.state = CAN_STATE_ERROR_WARNING;
@@ -477,7 +496,7 @@ static int ifi_canfd_handle_state_change(struct net_device *ndev,
	ifi_canfd_get_berr_counter(ndev, &bec);

	switch (new_state) {
	case CAN_STATE_ERROR_ACTIVE:
	case CAN_STATE_ERROR_WARNING:
		/* error warning state */
		cf->can_id |= CAN_ERR_CRTL;
		cf->data[1] = (bec.txerr > bec.rxerr) ?
@@ -510,22 +529,21 @@ static int ifi_canfd_handle_state_change(struct net_device *ndev,
	return 1;
}

static int ifi_canfd_handle_state_errors(struct net_device *ndev, u32 stcmd)
static int ifi_canfd_handle_state_errors(struct net_device *ndev)
{
	struct ifi_canfd_priv *priv = netdev_priv(ndev);
	u32 stcmd = readl(priv->base + IFI_CANFD_STCMD);
	int work_done = 0;
	u32 isr;

	/*
	 * The ErrWarn condition is a little special, since the bit is
	 * located in the INTERRUPT register instead of STCMD register.
	 */
	isr = readl(priv->base + IFI_CANFD_INTERRUPT);
	if ((isr & IFI_CANFD_INTERRUPT_ERROR_WARNING) &&
	if ((stcmd & IFI_CANFD_STCMD_ERROR_ACTIVE) &&
	    (priv->can.state != CAN_STATE_ERROR_ACTIVE)) {
		netdev_dbg(ndev, "Error, entered active state\n");
		work_done += ifi_canfd_handle_state_change(ndev,
						CAN_STATE_ERROR_ACTIVE);
	}

	if ((stcmd & IFI_CANFD_STCMD_ERROR_WARNING) &&
	    (priv->can.state != CAN_STATE_ERROR_WARNING)) {
		/* Clear the interrupt */
		writel(IFI_CANFD_INTERRUPT_ERROR_WARNING,
		       priv->base + IFI_CANFD_INTERRUPT);
		netdev_dbg(ndev, "Error, entered warning state\n");
		work_done += ifi_canfd_handle_state_change(ndev,
						CAN_STATE_ERROR_WARNING);
@@ -552,18 +570,11 @@ static int ifi_canfd_poll(struct napi_struct *napi, int quota)
{
	struct net_device *ndev = napi->dev;
	struct ifi_canfd_priv *priv = netdev_priv(ndev);
	const u32 stcmd_state_mask = IFI_CANFD_STCMD_ERROR_PASSIVE |
				     IFI_CANFD_STCMD_BUSOFF;
	int work_done = 0;

	u32 stcmd = readl(priv->base + IFI_CANFD_STCMD);
	u32 rxstcmd = readl(priv->base + IFI_CANFD_RXSTCMD);
	u32 errctr = readl(priv->base + IFI_CANFD_ERROR_CTR);
	int work_done = 0;

	/* Handle bus state changes */
	if ((stcmd & stcmd_state_mask) ||
	    ((stcmd & IFI_CANFD_STCMD_ERROR_ACTIVE) == 0))
		work_done += ifi_canfd_handle_state_errors(ndev, stcmd);
	work_done += ifi_canfd_handle_state_errors(ndev);

	/* Handle lost messages on RX */
	if (rxstcmd & IFI_CANFD_RXSTCMD_OVERFLOW)
@@ -571,7 +582,7 @@ static int ifi_canfd_poll(struct napi_struct *napi, int quota)

	/* Handle lec errors on the bus */
	if (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)
		work_done += ifi_canfd_handle_lec_err(ndev, errctr);
		work_done += ifi_canfd_handle_lec_err(ndev);

	/* Handle normal messages on RX */
	if (!(rxstcmd & IFI_CANFD_RXSTCMD_EMPTY))
@@ -592,12 +603,13 @@ static irqreturn_t ifi_canfd_isr(int irq, void *dev_id)
	struct net_device_stats *stats = &ndev->stats;
	const u32 rx_irq_mask = IFI_CANFD_INTERRUPT_RXFIFO_NEMPTY |
				IFI_CANFD_INTERRUPT_RXFIFO_NEMPTY_PER |
				IFI_CANFD_INTERRUPT_ERROR_COUNTER |
				IFI_CANFD_INTERRUPT_ERROR_STATE_CHG |
				IFI_CANFD_INTERRUPT_ERROR_WARNING |
				IFI_CANFD_INTERRUPT_ERROR_COUNTER;
				IFI_CANFD_INTERRUPT_ERROR_BUSOFF;
	const u32 tx_irq_mask = IFI_CANFD_INTERRUPT_TXFIFO_EMPTY |
				IFI_CANFD_INTERRUPT_TXFIFO_REMOVE;
	const u32 clr_irq_mask = ~((u32)(IFI_CANFD_INTERRUPT_SET_IRQ |
					 IFI_CANFD_INTERRUPT_ERROR_WARNING));
	const u32 clr_irq_mask = ~((u32)IFI_CANFD_INTERRUPT_SET_IRQ);
	u32 isr;

	isr = readl(priv->base + IFI_CANFD_INTERRUPT);
@@ -933,7 +945,7 @@ static int ifi_canfd_plat_probe(struct platform_device *pdev)
	struct resource *res;
	void __iomem *addr;
	int irq, ret;
	u32 id;
	u32 id, rev;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	addr = devm_ioremap_resource(dev, res);
@@ -947,6 +959,13 @@ static int ifi_canfd_plat_probe(struct platform_device *pdev)
		return -EINVAL;
	}

	rev = readl(addr + IFI_CANFD_VER) & IFI_CANFD_VER_REV_MASK;
	if (rev < IFI_CANFD_VER_REV_MIN_SUPPORTED) {
		dev_err(dev, "This block is too old (rev %i), minimum supported is rev %i\n",
			rev, IFI_CANFD_VER_REV_MIN_SUPPORTED);
		return -EINVAL;
	}

	ndev = alloc_candev(sizeof(*priv), 1);
	if (!ndev)
		return -ENOMEM;
+6 −1
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@
#include <linux/pm_runtime.h>
#include <linux/iopoll.h>
#include <linux/can/dev.h>
#include <linux/pinctrl/consumer.h>

/* napi related */
#define M_CAN_NAPI_WEIGHT	64
@@ -253,7 +254,7 @@ enum m_can_mram_cfg {

/* Rx FIFO 0/1 Configuration (RXF0C/RXF1C) */
#define RXFC_FWM_SHIFT	24
#define RXFC_FWM_MASK	(0x7f < RXFC_FWM_SHIFT)
#define RXFC_FWM_MASK	(0x7f << RXFC_FWM_SHIFT)
#define RXFC_FS_SHIFT	16
#define RXFC_FS_MASK	(0x7f << RXFC_FS_SHIFT)

@@ -1700,6 +1701,8 @@ static __maybe_unused int m_can_suspend(struct device *dev)
		m_can_clk_stop(priv);
	}

	pinctrl_pm_select_sleep_state(dev);

	priv->can.state = CAN_STATE_SLEEPING;

	return 0;
@@ -1710,6 +1713,8 @@ static __maybe_unused int m_can_resume(struct device *dev)
	struct net_device *ndev = dev_get_drvdata(dev);
	struct m_can_priv *priv = netdev_priv(ndev);

	pinctrl_pm_select_default_state(dev);

	m_can_init_ram(priv);

	priv->can.state = CAN_STATE_ERROR_ACTIVE;
+8 −17
Original line number Diff line number Diff line
@@ -262,7 +262,6 @@ static int pucan_handle_can_rx(struct peak_canfd_priv *priv,

		spin_lock_irqsave(&priv->echo_lock, flags);
		can_get_echo_skb(priv->ndev, msg->client);
		spin_unlock_irqrestore(&priv->echo_lock, flags);

		/* count bytes of the echo instead of skb */
		stats->tx_bytes += cf_len;
@@ -271,6 +270,7 @@ static int pucan_handle_can_rx(struct peak_canfd_priv *priv,
		/* restart tx queue (a slot is free) */
		netif_wake_queue(priv->ndev);

		spin_unlock_irqrestore(&priv->echo_lock, flags);
		return 0;
	}

@@ -333,7 +333,6 @@ static int pucan_handle_status(struct peak_canfd_priv *priv,

	/* this STATUS is the CNF of the RX_BARRIER: Tx path can be setup */
	if (pucan_status_is_rx_barrier(msg)) {
		unsigned long flags;

		if (priv->enable_tx_path) {
			int err = priv->enable_tx_path(priv);
@@ -342,16 +341,8 @@ static int pucan_handle_status(struct peak_canfd_priv *priv,
				return err;
		}

		/* restart network queue only if echo skb array is free */
		spin_lock_irqsave(&priv->echo_lock, flags);

		if (!priv->can.echo_skb[priv->echo_idx]) {
			spin_unlock_irqrestore(&priv->echo_lock, flags);

			netif_wake_queue(ndev);
		} else {
			spin_unlock_irqrestore(&priv->echo_lock, flags);
		}
		/* start network queue (echo_skb array is empty) */
		netif_start_queue(ndev);

		return 0;
	}
@@ -726,11 +717,6 @@ static netdev_tx_t peak_canfd_start_xmit(struct sk_buff *skb,
	 */
	should_stop_tx_queue = !!(priv->can.echo_skb[priv->echo_idx]);

	spin_unlock_irqrestore(&priv->echo_lock, flags);

	/* write the skb on the interface */
	priv->write_tx_msg(priv, msg);

	/* stop network tx queue if not enough room to save one more msg too */
	if (priv->can.ctrlmode & CAN_CTRLMODE_FD)
		should_stop_tx_queue |= (room_left <
@@ -742,6 +728,11 @@ static netdev_tx_t peak_canfd_start_xmit(struct sk_buff *skb,
	if (should_stop_tx_queue)
		netif_stop_queue(ndev);

	spin_unlock_irqrestore(&priv->echo_lock, flags);

	/* write the skb on the interface */
	priv->write_tx_msg(priv, msg);

	return NETDEV_TX_OK;
}

+6 −2
Original line number Diff line number Diff line
@@ -349,8 +349,12 @@ static irqreturn_t pciefd_irq_handler(int irq, void *arg)
		priv->tx_pages_free++;
		spin_unlock_irqrestore(&priv->tx_lock, flags);

		/* wake producer up */
		/* wake producer up (only if enough room in echo_skb array) */
		spin_lock_irqsave(&priv->ucan.echo_lock, flags);
		if (!priv->ucan.can.echo_skb[priv->ucan.echo_idx])
			netif_wake_queue(priv->ucan.ndev);

		spin_unlock_irqrestore(&priv->ucan.echo_lock, flags);
	}

	/* re-enable Rx DMA transfer for this CAN */