All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] can: flexcan: Remodel FlexCAN register r/w APIs for big endian FlexCAN controllers.
@ 2017-11-10  9:59 Pankaj Bansal
  2017-11-10  9:59 ` [PATCH 2/2] can: flexcan: adding platform specific details for LS1021A Pankaj Bansal
                   ` (3 more replies)
  0 siblings, 4 replies; 52+ messages in thread
From: Pankaj Bansal @ 2017-11-10  9:59 UTC (permalink / raw)
  To: wg, mkl, linux-can
  Cc: V.Sethi, poonam.aggrwal, Pankaj Bansal, Bhupesh Sharma, Sakar Arora

The FlexCAN driver assumed that FlexCAN controller is big endian for
powerpc architecture and little endian for other architectures.

But this may not be the case. FlexCAN controller can be little or
big endian on any architecture. For e.g. NXP LS1021A ARM based SOC
has big endian FlexCAN controller.

Therefore, the driver has been modified to add a provision for both
types of controllers using an additional device tree property. Big
Endian controllers should have "big-endian" set in the device tree.

Signed-off-by: Pankaj Bansal <pankaj.bansal@nxp.com>
Signed-off-by: Bhupesh Sharma <bhupesh.sharma@freescale.com>
Signed-off-by: Sakar Arora <Sakar.Arora@freescale.com>
Reviewed-by: Zhengxiong Jin <Jason.Jin@freescale.com>
Reviewed-by: Poonam Aggrwal <poonam.aggrwal@nxp.com>
---
Tested on Arm32 based NXP LS1021A-TWR board (linux-can-next/master branch)
Tested on PowerPC based NXP P1010RDB board (after back porting to Freescale SDK 1.4 linux)

 drivers/net/can/flexcan.c | 212 ++++++++++++++++++++----------------
 1 file changed, 116 insertions(+), 96 deletions(-)

diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
index a13a489..d4ce2df 100644
--- a/drivers/net/can/flexcan.c
+++ b/drivers/net/can/flexcan.c
@@ -279,6 +279,10 @@ struct flexcan_priv {
 	struct clk *clk_per;
 	const struct flexcan_devtype_data *devtype_data;
 	struct regulator *reg_xceiver;
+
+	/* Read and Write APIs */
+	u32 (*read)(void __iomem *addr);
+	void (*write)(u32 val, void __iomem *addr);
 };
 
 static const struct flexcan_devtype_data fsl_p1010_devtype_data = {
@@ -312,39 +316,45 @@ static const struct can_bittiming_const flexcan_bittiming_const = {
 	.brp_inc = 1,
 };
 
-/* Abstract off the read/write for arm versus ppc. This
- * assumes that PPC uses big-endian registers and everything
- * else uses little-endian registers, independent of CPU
- * endianness.
+/* FlexCAN module is essentially modelled as a little-endian IP in most
+ * SoCs, i.e the registers as well as the message buffer areas are
+ * implemented in a little-endian fashion.
+ *
+ * However there are some SoCs (e.g. LS1021A) which implement the FlexCAN
+ * module in a big-endian fashion (i.e the registers as well as the
+ * message buffer areas are implemented in a big-endian way).
+ *
+ * In addition, the FlexCAN module can be found on SoCs having ARM or
+ * PPC cores. So, we need to abstract off the register read/write
+ * functions, ensuring that these cater to all the combinations of module
+ * endianness and underlying CPU endianness.
  */
-#if defined(CONFIG_PPC)
-static inline u32 flexcan_read(void __iomem *addr)
+static inline u32 flexcan_read_le(void __iomem *addr)
 {
-	return in_be32(addr);
+	return ioread32(addr);
 }
 
-static inline void flexcan_write(u32 val, void __iomem *addr)
+static inline void flexcan_write_le(u32 val, void __iomem *addr)
 {
-	out_be32(addr, val);
+	iowrite32(val, addr);
 }
-#else
-static inline u32 flexcan_read(void __iomem *addr)
+
+static inline u32 flexcan_read_be(void __iomem *addr)
 {
-	return readl(addr);
+	return ioread32be(addr);
 }
 
-static inline void flexcan_write(u32 val, void __iomem *addr)
+static inline void flexcan_write_be(u32 val, void __iomem *addr)
 {
-	writel(val, addr);
+	iowrite32be(val, addr);
 }
-#endif
 
 static inline void flexcan_error_irq_enable(const struct flexcan_priv *priv)
 {
 	struct flexcan_regs __iomem *regs = priv->regs;
 	u32 reg_ctrl = (priv->reg_ctrl_default | FLEXCAN_CTRL_ERR_MSK);
 
-	flexcan_write(reg_ctrl, &regs->ctrl);
+	priv->write(reg_ctrl, &regs->ctrl);
 }
 
 static inline void flexcan_error_irq_disable(const struct flexcan_priv *priv)
@@ -352,7 +362,7 @@ static inline void flexcan_error_irq_disable(const struct flexcan_priv *priv)
 	struct flexcan_regs __iomem *regs = priv->regs;
 	u32 reg_ctrl = (priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_MSK);
 
-	flexcan_write(reg_ctrl, &regs->ctrl);
+	priv->write(reg_ctrl, &regs->ctrl);
 }
 
 static inline int flexcan_transceiver_enable(const struct flexcan_priv *priv)
@@ -377,14 +387,14 @@ static int flexcan_chip_enable(struct flexcan_priv *priv)
 	unsigned int timeout = FLEXCAN_TIMEOUT_US / 10;
 	u32 reg;
 
-	reg = flexcan_read(&regs->mcr);
+	reg = priv->read(&regs->mcr);
 	reg &= ~FLEXCAN_MCR_MDIS;
-	flexcan_write(reg, &regs->mcr);
+	priv->write(reg, &regs->mcr);
 
-	while (timeout-- && (flexcan_read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK))
+	while (timeout-- && (priv->read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK))
 		udelay(10);
 
-	if (flexcan_read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK)
+	if (priv->read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK)
 		return -ETIMEDOUT;
 
 	return 0;
@@ -396,14 +406,14 @@ static int flexcan_chip_disable(struct flexcan_priv *priv)
 	unsigned int timeout = FLEXCAN_TIMEOUT_US / 10;
 	u32 reg;
 
-	reg = flexcan_read(&regs->mcr);
+	reg = priv->read(&regs->mcr);
 	reg |= FLEXCAN_MCR_MDIS;
-	flexcan_write(reg, &regs->mcr);
+	priv->write(reg, &regs->mcr);
 
-	while (timeout-- && !(flexcan_read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK))
+	while (timeout-- && !(priv->read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK))
 		udelay(10);
 
-	if (!(flexcan_read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK))
+	if (!(priv->read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK))
 		return -ETIMEDOUT;
 
 	return 0;
@@ -415,14 +425,14 @@ static int flexcan_chip_freeze(struct flexcan_priv *priv)
 	unsigned int timeout = 1000 * 1000 * 10 / priv->can.bittiming.bitrate;
 	u32 reg;
 
-	reg = flexcan_read(&regs->mcr);
+	reg = priv->read(&regs->mcr);
 	reg |= FLEXCAN_MCR_HALT;
-	flexcan_write(reg, &regs->mcr);
+	priv->write(reg, &regs->mcr);
 
-	while (timeout-- && !(flexcan_read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK))
+	while (timeout-- && !(priv->read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK))
 		udelay(100);
 
-	if (!(flexcan_read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK))
+	if (!(priv->read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK))
 		return -ETIMEDOUT;
 
 	return 0;
@@ -434,14 +444,14 @@ static int flexcan_chip_unfreeze(struct flexcan_priv *priv)
 	unsigned int timeout = FLEXCAN_TIMEOUT_US / 10;
 	u32 reg;
 
-	reg = flexcan_read(&regs->mcr);
+	reg = priv->read(&regs->mcr);
 	reg &= ~FLEXCAN_MCR_HALT;
-	flexcan_write(reg, &regs->mcr);
+	priv->write(reg, &regs->mcr);
 
-	while (timeout-- && (flexcan_read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK))
+	while (timeout-- && (priv->read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK))
 		udelay(10);
 
-	if (flexcan_read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK)
+	if (priv->read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK)
 		return -ETIMEDOUT;
 
 	return 0;
@@ -452,11 +462,11 @@ static int flexcan_chip_softreset(struct flexcan_priv *priv)
 	struct flexcan_regs __iomem *regs = priv->regs;
 	unsigned int timeout = FLEXCAN_TIMEOUT_US / 10;
 
-	flexcan_write(FLEXCAN_MCR_SOFTRST, &regs->mcr);
-	while (timeout-- && (flexcan_read(&regs->mcr) & FLEXCAN_MCR_SOFTRST))
+	priv->write(FLEXCAN_MCR_SOFTRST, &regs->mcr);
+	while (timeout-- && (priv->read(&regs->mcr) & FLEXCAN_MCR_SOFTRST))
 		udelay(10);
 
-	if (flexcan_read(&regs->mcr) & FLEXCAN_MCR_SOFTRST)
+	if (priv->read(&regs->mcr) & FLEXCAN_MCR_SOFTRST)
 		return -ETIMEDOUT;
 
 	return 0;
@@ -467,7 +477,7 @@ static int __flexcan_get_berr_counter(const struct net_device *dev,
 {
 	const struct flexcan_priv *priv = netdev_priv(dev);
 	struct flexcan_regs __iomem *regs = priv->regs;
-	u32 reg = flexcan_read(&regs->ecr);
+	u32 reg = priv->read(&regs->ecr);
 
 	bec->txerr = (reg >> 0) & 0xff;
 	bec->rxerr = (reg >> 8) & 0xff;
@@ -523,24 +533,24 @@ static int flexcan_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	if (cf->can_dlc > 0) {
 		data = be32_to_cpup((__be32 *)&cf->data[0]);
-		flexcan_write(data, &priv->tx_mb->data[0]);
+		priv->write(data, &priv->tx_mb->data[0]);
 	}
 	if (cf->can_dlc > 3) {
 		data = be32_to_cpup((__be32 *)&cf->data[4]);
-		flexcan_write(data, &priv->tx_mb->data[1]);
+		priv->write(data, &priv->tx_mb->data[1]);
 	}
 
 	can_put_echo_skb(skb, dev, 0);
 
-	flexcan_write(can_id, &priv->tx_mb->can_id);
-	flexcan_write(ctrl, &priv->tx_mb->can_ctrl);
+	priv->write(can_id, &priv->tx_mb->can_id);
+	priv->write(ctrl, &priv->tx_mb->can_ctrl);
 
 	/* Errata ERR005829 step8:
 	 * Write twice INACTIVE(0x8) code to first MB.
 	 */
-	flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE,
+	priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
 		      &priv->tx_mb_reserved->can_ctrl);
-	flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE,
+	priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
 		      &priv->tx_mb_reserved->can_ctrl);
 
 	return NETDEV_TX_OK;
@@ -659,7 +669,7 @@ static unsigned int flexcan_mailbox_read(struct can_rx_offload *offload,
 		u32 code;
 
 		do {
-			reg_ctrl = flexcan_read(&mb->can_ctrl);
+			reg_ctrl = priv->read(&mb->can_ctrl);
 		} while (reg_ctrl & FLEXCAN_MB_CODE_RX_BUSY_BIT);
 
 		/* is this MB empty? */
@@ -674,17 +684,17 @@ static unsigned int flexcan_mailbox_read(struct can_rx_offload *offload,
 			offload->dev->stats.rx_errors++;
 		}
 	} else {
-		reg_iflag1 = flexcan_read(&regs->iflag1);
+		reg_iflag1 = priv->read(&regs->iflag1);
 		if (!(reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_AVAILABLE))
 			return 0;
 
-		reg_ctrl = flexcan_read(&mb->can_ctrl);
+		reg_ctrl = priv->read(&mb->can_ctrl);
 	}
 
 	/* increase timstamp to full 32 bit */
 	*timestamp = reg_ctrl << 16;
 
-	reg_id = flexcan_read(&mb->can_id);
+	reg_id = priv->read(&mb->can_id);
 	if (reg_ctrl & FLEXCAN_MB_CNT_IDE)
 		cf->can_id = ((reg_id >> 0) & CAN_EFF_MASK) | CAN_EFF_FLAG;
 	else
@@ -694,19 +704,19 @@ static unsigned int flexcan_mailbox_read(struct can_rx_offload *offload,
 		cf->can_id |= CAN_RTR_FLAG;
 	cf->can_dlc = get_can_dlc((reg_ctrl >> 16) & 0xf);
 
-	*(__be32 *)(cf->data + 0) = cpu_to_be32(flexcan_read(&mb->data[0]));
-	*(__be32 *)(cf->data + 4) = cpu_to_be32(flexcan_read(&mb->data[1]));
+	*(__be32 *)(cf->data + 0) = cpu_to_be32(priv->read(&mb->data[0]));
+	*(__be32 *)(cf->data + 4) = cpu_to_be32(priv->read(&mb->data[1]));
 
 	/* mark as read */
 	if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) {
 		/* Clear IRQ */
 		if (n < 32)
-			flexcan_write(BIT(n), &regs->iflag1);
+			priv->write(BIT(n), &regs->iflag1);
 		else
-			flexcan_write(BIT(n - 32), &regs->iflag2);
+			priv->write(BIT(n - 32), &regs->iflag2);
 	} else {
-		flexcan_write(FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, &regs->iflag1);
-		flexcan_read(&regs->timer);
+		priv->write(FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, &regs->iflag1);
+		priv->read(&regs->timer);
 	}
 
 	return 1;
@@ -718,8 +728,8 @@ static inline u64 flexcan_read_reg_iflag_rx(struct flexcan_priv *priv)
 	struct flexcan_regs __iomem *regs = priv->regs;
 	u32 iflag1, iflag2;
 
-	iflag2 = flexcan_read(&regs->iflag2) & priv->reg_imask2_default;
-	iflag1 = flexcan_read(&regs->iflag1) & priv->reg_imask1_default &
+	iflag2 = priv->read(&regs->iflag2) & priv->reg_imask2_default;
+	iflag1 = priv->read(&regs->iflag1) & priv->reg_imask1_default &
 		~FLEXCAN_IFLAG_MB(priv->tx_mb_idx);
 
 	return (u64)iflag2 << 32 | iflag1;
@@ -735,7 +745,7 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
 	u32 reg_iflag1, reg_esr;
 	enum can_state last_state = priv->can.state;
 
-	reg_iflag1 = flexcan_read(&regs->iflag1);
+	reg_iflag1 = priv->read(&regs->iflag1);
 
 	/* reception interrupt */
 	if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) {
@@ -758,7 +768,8 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
 		/* FIFO overflow interrupt */
 		if (reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_OVERFLOW) {
 			handled = IRQ_HANDLED;
-			flexcan_write(FLEXCAN_IFLAG_RX_FIFO_OVERFLOW, &regs->iflag1);
+			priv->write(FLEXCAN_IFLAG_RX_FIFO_OVERFLOW,
+				      &regs->iflag1);
 			dev->stats.rx_over_errors++;
 			dev->stats.rx_errors++;
 		}
@@ -772,18 +783,18 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
 		can_led_event(dev, CAN_LED_EVENT_TX);
 
 		/* after sending a RTR frame MB is in RX mode */
-		flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE,
+		priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
 			      &priv->tx_mb->can_ctrl);
-		flexcan_write(FLEXCAN_IFLAG_MB(priv->tx_mb_idx), &regs->iflag1);
+		priv->write(FLEXCAN_IFLAG_MB(priv->tx_mb_idx), &regs->iflag1);
 		netif_wake_queue(dev);
 	}
 
-	reg_esr = flexcan_read(&regs->esr);
+	reg_esr = priv->read(&regs->esr);
 
 	/* ACK all bus error and state change IRQ sources */
 	if (reg_esr & FLEXCAN_ESR_ALL_INT) {
 		handled = IRQ_HANDLED;
-		flexcan_write(reg_esr & FLEXCAN_ESR_ALL_INT, &regs->esr);
+		priv->write(reg_esr & FLEXCAN_ESR_ALL_INT, &regs->esr);
 	}
 
 	/* state change interrupt or broken error state quirk fix is enabled */
@@ -845,7 +856,7 @@ static void flexcan_set_bittiming(struct net_device *dev)
 	struct flexcan_regs __iomem *regs = priv->regs;
 	u32 reg;
 
-	reg = flexcan_read(&regs->ctrl);
+	reg = priv->read(&regs->ctrl);
 	reg &= ~(FLEXCAN_CTRL_PRESDIV(0xff) |
 		 FLEXCAN_CTRL_RJW(0x3) |
 		 FLEXCAN_CTRL_PSEG1(0x7) |
@@ -869,11 +880,11 @@ static void flexcan_set_bittiming(struct net_device *dev)
 		reg |= FLEXCAN_CTRL_SMP;
 
 	netdev_dbg(dev, "writing ctrl=0x%08x\n", reg);
-	flexcan_write(reg, &regs->ctrl);
+	priv->write(reg, &regs->ctrl);
 
 	/* print chip status */
 	netdev_dbg(dev, "%s: mcr=0x%08x ctrl=0x%08x\n", __func__,
-		   flexcan_read(&regs->mcr), flexcan_read(&regs->ctrl));
+		   priv->read(&regs->mcr), priv->read(&regs->ctrl));
 }
 
 /* flexcan_chip_start
@@ -912,7 +923,7 @@ static int flexcan_chip_start(struct net_device *dev)
 	 * choose format C
 	 * set max mailbox number
 	 */
-	reg_mcr = flexcan_read(&regs->mcr);
+	reg_mcr = priv->read(&regs->mcr);
 	reg_mcr &= ~FLEXCAN_MCR_MAXMB(0xff);
 	reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT | FLEXCAN_MCR_SUPV |
 		FLEXCAN_MCR_WRN_EN | FLEXCAN_MCR_SRX_DIS | FLEXCAN_MCR_IRMQ |
@@ -926,7 +937,7 @@ static int flexcan_chip_start(struct net_device *dev)
 			FLEXCAN_MCR_MAXMB(priv->tx_mb_idx);
 	}
 	netdev_dbg(dev, "%s: writing mcr=0x%08x", __func__, reg_mcr);
-	flexcan_write(reg_mcr, &regs->mcr);
+	priv->write(reg_mcr, &regs->mcr);
 
 	/* CTRL
 	 *
@@ -939,7 +950,7 @@ static int flexcan_chip_start(struct net_device *dev)
 	 * enable bus off interrupt
 	 * (== FLEXCAN_CTRL_ERR_STATE)
 	 */
-	reg_ctrl = flexcan_read(&regs->ctrl);
+	reg_ctrl = priv->read(&regs->ctrl);
 	reg_ctrl &= ~FLEXCAN_CTRL_TSYN;
 	reg_ctrl |= FLEXCAN_CTRL_BOFF_REC | FLEXCAN_CTRL_LBUF |
 		FLEXCAN_CTRL_ERR_STATE;
@@ -959,45 +970,45 @@ static int flexcan_chip_start(struct net_device *dev)
 	/* leave interrupts disabled for now */
 	reg_ctrl &= ~FLEXCAN_CTRL_ERR_ALL;
 	netdev_dbg(dev, "%s: writing ctrl=0x%08x", __func__, reg_ctrl);
-	flexcan_write(reg_ctrl, &regs->ctrl);
+	priv->write(reg_ctrl, &regs->ctrl);
 
 	if ((priv->devtype_data->quirks & FLEXCAN_QUIRK_ENABLE_EACEN_RRS)) {
-		reg_ctrl2 = flexcan_read(&regs->ctrl2);
+		reg_ctrl2 = priv->read(&regs->ctrl2);
 		reg_ctrl2 |= FLEXCAN_CTRL2_EACEN | FLEXCAN_CTRL2_RRS;
-		flexcan_write(reg_ctrl2, &regs->ctrl2);
+		priv->write(reg_ctrl2, &regs->ctrl2);
 	}
 
 	/* clear and invalidate all mailboxes first */
 	for (i = priv->tx_mb_idx; i < ARRAY_SIZE(regs->mb); i++) {
-		flexcan_write(FLEXCAN_MB_CODE_RX_INACTIVE,
+		priv->write(FLEXCAN_MB_CODE_RX_INACTIVE,
 			      &regs->mb[i].can_ctrl);
 	}
 
 	if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) {
 		for (i = priv->offload.mb_first; i <= priv->offload.mb_last; i++)
-			flexcan_write(FLEXCAN_MB_CODE_RX_EMPTY,
+			priv->write(FLEXCAN_MB_CODE_RX_EMPTY,
 				      &regs->mb[i].can_ctrl);
 	}
 
 	/* Errata ERR005829: mark first TX mailbox as INACTIVE */
-	flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE,
+	priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
 		      &priv->tx_mb_reserved->can_ctrl);
 
 	/* mark TX mailbox as INACTIVE */
-	flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE,
+	priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
 		      &priv->tx_mb->can_ctrl);
 
 	/* acceptance mask/acceptance code (accept everything) */
-	flexcan_write(0x0, &regs->rxgmask);
-	flexcan_write(0x0, &regs->rx14mask);
-	flexcan_write(0x0, &regs->rx15mask);
+	priv->write(0x0, &regs->rxgmask);
+	priv->write(0x0, &regs->rx14mask);
+	priv->write(0x0, &regs->rx15mask);
 
 	if (priv->devtype_data->quirks & FLEXCAN_QUIRK_DISABLE_RXFG)
-		flexcan_write(0x0, &regs->rxfgmask);
+		priv->write(0x0, &regs->rxfgmask);
 
 	/* clear acceptance filters */
 	for (i = 0; i < ARRAY_SIZE(regs->mb); i++)
-		flexcan_write(0, &regs->rximr[i]);
+		priv->write(0, &regs->rximr[i]);
 
 	/* On Vybrid, disable memory error detection interrupts
 	 * and freeze mode.
@@ -1010,16 +1021,16 @@ static int flexcan_chip_start(struct net_device *dev)
 		 * and Correction of Memory Errors" to write to
 		 * MECR register
 		 */
-		reg_ctrl2 = flexcan_read(&regs->ctrl2);
+		reg_ctrl2 = priv->read(&regs->ctrl2);
 		reg_ctrl2 |= FLEXCAN_CTRL2_ECRWRE;
-		flexcan_write(reg_ctrl2, &regs->ctrl2);
+		priv->write(reg_ctrl2, &regs->ctrl2);
 
-		reg_mecr = flexcan_read(&regs->mecr);
+		reg_mecr = priv->read(&regs->mecr);
 		reg_mecr &= ~FLEXCAN_MECR_ECRWRDIS;
-		flexcan_write(reg_mecr, &regs->mecr);
+		priv->write(reg_mecr, &regs->mecr);
 		reg_mecr &= ~(FLEXCAN_MECR_NCEFAFRZ | FLEXCAN_MECR_HANCEI_MSK |
 			      FLEXCAN_MECR_FANCEI_MSK);
-		flexcan_write(reg_mecr, &regs->mecr);
+		priv->write(reg_mecr, &regs->mecr);
 	}
 
 	err = flexcan_transceiver_enable(priv);
@@ -1035,14 +1046,14 @@ static int flexcan_chip_start(struct net_device *dev)
 
 	/* enable interrupts atomically */
 	disable_irq(dev->irq);
-	flexcan_write(priv->reg_ctrl_default, &regs->ctrl);
-	flexcan_write(priv->reg_imask1_default, &regs->imask1);
-	flexcan_write(priv->reg_imask2_default, &regs->imask2);
+	priv->write(priv->reg_ctrl_default, &regs->ctrl);
+	priv->write(priv->reg_imask1_default, &regs->imask1);
+	priv->write(priv->reg_imask2_default, &regs->imask2);
 	enable_irq(dev->irq);
 
 	/* print chip status */
 	netdev_dbg(dev, "%s: reading mcr=0x%08x ctrl=0x%08x\n", __func__,
-		   flexcan_read(&regs->mcr), flexcan_read(&regs->ctrl));
+		   priv->read(&regs->mcr), priv->read(&regs->ctrl));
 
 	return 0;
 
@@ -1067,9 +1078,9 @@ static void flexcan_chip_stop(struct net_device *dev)
 	flexcan_chip_disable(priv);
 
 	/* Disable all interrupts */
-	flexcan_write(0, &regs->imask2);
-	flexcan_write(0, &regs->imask1);
-	flexcan_write(priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_ALL,
+	priv->write(0, &regs->imask2);
+	priv->write(0, &regs->imask1);
+	priv->write(priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_ALL,
 		      &regs->ctrl);
 
 	flexcan_transceiver_disable(priv);
@@ -1185,26 +1196,26 @@ static int register_flexcandev(struct net_device *dev)
 	err = flexcan_chip_disable(priv);
 	if (err)
 		goto out_disable_per;
-	reg = flexcan_read(&regs->ctrl);
+	reg = priv->read(&regs->ctrl);
 	reg |= FLEXCAN_CTRL_CLK_SRC;
-	flexcan_write(reg, &regs->ctrl);
+	priv->write(reg, &regs->ctrl);
 
 	err = flexcan_chip_enable(priv);
 	if (err)
 		goto out_chip_disable;
 
 	/* set freeze, halt and activate FIFO, restrict register access */
-	reg = flexcan_read(&regs->mcr);
+	reg = priv->read(&regs->mcr);
 	reg |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT |
 		FLEXCAN_MCR_FEN | FLEXCAN_MCR_SUPV;
-	flexcan_write(reg, &regs->mcr);
+	priv->write(reg, &regs->mcr);
 
 	/* Currently we only support newer versions of this core
 	 * featuring a RX hardware FIFO (although this driver doesn't
 	 * make use of it on some cores). Older cores, found on some
 	 * Coldfire derivates are not tested.
 	 */
-	reg = flexcan_read(&regs->mcr);
+	reg = priv->read(&regs->mcr);
 	if (!(reg & FLEXCAN_MCR_FEN)) {
 		netdev_err(dev, "Could not enable RX FIFO, unsupported core\n");
 		err = -ENODEV;
@@ -1313,6 +1324,15 @@ static int flexcan_probe(struct platform_device *pdev)
 	dev->flags |= IFF_ECHO;
 
 	priv = netdev_priv(dev);
+
+	if (of_property_read_bool(pdev->dev.of_node, "big-endian")) {
+		priv->read = flexcan_read_be;
+		priv->write = flexcan_write_be;
+	} else {
+		priv->read = flexcan_read_le;
+		priv->write = flexcan_write_le;
+	}
+
 	priv->can.clock.freq = clock_freq;
 	priv->can.bittiming_const = &flexcan_bittiming_const;
 	priv->can.do_set_mode = flexcan_set_mode;
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH 2/2] can: flexcan: adding platform specific details for LS1021A
  2017-11-10  9:59 [PATCH 1/2] can: flexcan: Remodel FlexCAN register r/w APIs for big endian FlexCAN controllers Pankaj Bansal
@ 2017-11-10  9:59 ` Pankaj Bansal
  2017-11-10 10:06 ` [PATCH 1/2] can: flexcan: Remodel FlexCAN register r/w APIs for big endian FlexCAN controllers Marc Kleine-Budde
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 52+ messages in thread
From: Pankaj Bansal @ 2017-11-10  9:59 UTC (permalink / raw)
  To: wg, mkl, linux-can; +Cc: V.Sethi, poonam.aggrwal, Pankaj Bansal, Bhupesh Sharma

This patch adds platform specific details for NXP SOC LS1021A
to the flexcan driver code.

Signed-off-by: Pankaj Bansal <pankaj.bansal@nxp.com>
Signed-off-by: Bhupesh Sharma <bhupesh.sharma@freescale.com>
Reviewed-by: Zhengxiong Jin <Jason.Jin@freescale.com>
Reviewed-by: Poonam Aggrwal <poonam.aggrwal@nxp.com>
---
 drivers/net/can/flexcan.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
index d4ce2df..d8cac4c 100644
--- a/drivers/net/can/flexcan.c
+++ b/drivers/net/can/flexcan.c
@@ -304,6 +304,12 @@ static const struct flexcan_devtype_data fsl_vf610_devtype_data = {
 		FLEXCAN_QUIRK_DISABLE_MECR | FLEXCAN_QUIRK_USE_OFF_TIMESTAMP,
 };
 
+/* LS1021A-Rev2 has functional RX-FIFO mode
+ */
+static struct flexcan_devtype_data fsl_ls1021a_r2_devtype_data = {
+	.quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_DISABLE_MECR,
+};
+
 static const struct can_bittiming_const flexcan_bittiming_const = {
 	.name = DRV_NAME,
 	.tseg1_min = 4,
@@ -1245,6 +1251,8 @@ static const struct of_device_id flexcan_of_match[] = {
 	{ .compatible = "fsl,imx28-flexcan", .data = &fsl_imx28_devtype_data, },
 	{ .compatible = "fsl,p1010-flexcan", .data = &fsl_p1010_devtype_data, },
 	{ .compatible = "fsl,vf610-flexcan", .data = &fsl_vf610_devtype_data, },
+	{ .compatible = "fsl,ls1021ar2-flexcan",
+	  .data = &fsl_ls1021a_r2_devtype_data, },
 	{ /* sentinel */ },
 };
 MODULE_DEVICE_TABLE(of, flexcan_of_match);
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 52+ messages in thread

* Re: [PATCH 1/2] can: flexcan: Remodel FlexCAN register r/w APIs for big endian FlexCAN controllers.
  2017-11-10  9:59 [PATCH 1/2] can: flexcan: Remodel FlexCAN register r/w APIs for big endian FlexCAN controllers Pankaj Bansal
  2017-11-10  9:59 ` [PATCH 2/2] can: flexcan: adding platform specific details for LS1021A Pankaj Bansal
@ 2017-11-10 10:06 ` Marc Kleine-Budde
  2017-11-10 11:06   ` Pankaj Bansal
  2017-11-10 10:48 ` Marc Kleine-Budde
  2017-11-14 11:56 ` [PATCH v2 " Pankaj Bansal
  3 siblings, 1 reply; 52+ messages in thread
From: Marc Kleine-Budde @ 2017-11-10 10:06 UTC (permalink / raw)
  To: Pankaj Bansal, wg, linux-can
  Cc: V.Sethi, poonam.aggrwal, Bhupesh Sharma, Sakar Arora


[-- Attachment #1.1: Type: text/plain, Size: 22173 bytes --]

On 11/10/2017 10:59 AM, Pankaj Bansal wrote:
> The FlexCAN driver assumed that FlexCAN controller is big endian for
> powerpc architecture and little endian for other architectures.
> 
> But this may not be the case. FlexCAN controller can be little or
> big endian on any architecture. For e.g. NXP LS1021A ARM based SOC
> has big endian FlexCAN controller.
> 
> Therefore, the driver has been modified to add a provision for both
> types of controllers using an additional device tree property. Big
> Endian controllers should have "big-endian" set in the device tree.
> 
> Signed-off-by: Pankaj Bansal <pankaj.bansal@nxp.com>
> Signed-off-by: Bhupesh Sharma <bhupesh.sharma@freescale.com>
> Signed-off-by: Sakar Arora <Sakar.Arora@freescale.com>
> Reviewed-by: Zhengxiong Jin <Jason.Jin@freescale.com>
> Reviewed-by: Poonam Aggrwal <poonam.aggrwal@nxp.com>
> ---
> Tested on Arm32 based NXP LS1021A-TWR board (linux-can-next/master branch)
> Tested on PowerPC based NXP P1010RDB board (after back porting to Freescale SDK 1.4 linux)
> 
>  drivers/net/can/flexcan.c | 212 ++++++++++++++++++++----------------
>  1 file changed, 116 insertions(+), 96 deletions(-)
> 
> diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
> index a13a489..d4ce2df 100644
> --- a/drivers/net/can/flexcan.c
> +++ b/drivers/net/can/flexcan.c
> @@ -279,6 +279,10 @@ struct flexcan_priv {
>  	struct clk *clk_per;
>  	const struct flexcan_devtype_data *devtype_data;
>  	struct regulator *reg_xceiver;
> +
> +	/* Read and Write APIs */
> +	u32 (*read)(void __iomem *addr);
> +	void (*write)(u32 val, void __iomem *addr);
>  };
>  
>  static const struct flexcan_devtype_data fsl_p1010_devtype_data = {
> @@ -312,39 +316,45 @@ static const struct can_bittiming_const flexcan_bittiming_const = {
>  	.brp_inc = 1,
>  };
>  
> -/* Abstract off the read/write for arm versus ppc. This
> - * assumes that PPC uses big-endian registers and everything
> - * else uses little-endian registers, independent of CPU
> - * endianness.
> +/* FlexCAN module is essentially modelled as a little-endian IP in most
> + * SoCs, i.e the registers as well as the message buffer areas are
> + * implemented in a little-endian fashion.
> + *
> + * However there are some SoCs (e.g. LS1021A) which implement the FlexCAN
> + * module in a big-endian fashion (i.e the registers as well as the
> + * message buffer areas are implemented in a big-endian way).
> + *
> + * In addition, the FlexCAN module can be found on SoCs having ARM or
> + * PPC cores. So, we need to abstract off the register read/write
> + * functions, ensuring that these cater to all the combinations of module
> + * endianness and underlying CPU endianness.
>   */
> -#if defined(CONFIG_PPC)
> -static inline u32 flexcan_read(void __iomem *addr)
> +static inline u32 flexcan_read_le(void __iomem *addr)
>  {
> -	return in_be32(addr);
> +	return ioread32(addr);
>  }
>  
> -static inline void flexcan_write(u32 val, void __iomem *addr)
> +static inline void flexcan_write_le(u32 val, void __iomem *addr)
>  {
> -	out_be32(addr, val);
> +	iowrite32(val, addr);
>  }

Please make this the be variants, followed by the le below. Should make
the patch easier to read.

> -#else
> -static inline u32 flexcan_read(void __iomem *addr)
> +
> +static inline u32 flexcan_read_be(void __iomem *addr)
>  {
> -	return readl(addr);
> +	return ioread32be(addr);
>  }
>  
> -static inline void flexcan_write(u32 val, void __iomem *addr)
> +static inline void flexcan_write_be(u32 val, void __iomem *addr)
>  {
> -	writel(val, addr);
> +	iowrite32be(val, addr);
>  }
> -#endif
>  
>  static inline void flexcan_error_irq_enable(const struct flexcan_priv *priv)
>  {
>  	struct flexcan_regs __iomem *regs = priv->regs;
>  	u32 reg_ctrl = (priv->reg_ctrl_default | FLEXCAN_CTRL_ERR_MSK);
>  
> -	flexcan_write(reg_ctrl, &regs->ctrl);
> +	priv->write(reg_ctrl, &regs->ctrl);
>  }
>  
>  static inline void flexcan_error_irq_disable(const struct flexcan_priv *priv)
> @@ -352,7 +362,7 @@ static inline void flexcan_error_irq_disable(const struct flexcan_priv *priv)
>  	struct flexcan_regs __iomem *regs = priv->regs;
>  	u32 reg_ctrl = (priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_MSK);
>  
> -	flexcan_write(reg_ctrl, &regs->ctrl);
> +	priv->write(reg_ctrl, &regs->ctrl);
>  }
>  
>  static inline int flexcan_transceiver_enable(const struct flexcan_priv *priv)
> @@ -377,14 +387,14 @@ static int flexcan_chip_enable(struct flexcan_priv *priv)
>  	unsigned int timeout = FLEXCAN_TIMEOUT_US / 10;
>  	u32 reg;
>  
> -	reg = flexcan_read(&regs->mcr);
> +	reg = priv->read(&regs->mcr);
>  	reg &= ~FLEXCAN_MCR_MDIS;
> -	flexcan_write(reg, &regs->mcr);
> +	priv->write(reg, &regs->mcr);
>  
> -	while (timeout-- && (flexcan_read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK))
> +	while (timeout-- && (priv->read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK))
>  		udelay(10);
>  
> -	if (flexcan_read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK)
> +	if (priv->read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK)
>  		return -ETIMEDOUT;
>  
>  	return 0;
> @@ -396,14 +406,14 @@ static int flexcan_chip_disable(struct flexcan_priv *priv)
>  	unsigned int timeout = FLEXCAN_TIMEOUT_US / 10;
>  	u32 reg;
>  
> -	reg = flexcan_read(&regs->mcr);
> +	reg = priv->read(&regs->mcr);
>  	reg |= FLEXCAN_MCR_MDIS;
> -	flexcan_write(reg, &regs->mcr);
> +	priv->write(reg, &regs->mcr);
>  
> -	while (timeout-- && !(flexcan_read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK))
> +	while (timeout-- && !(priv->read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK))
>  		udelay(10);
>  
> -	if (!(flexcan_read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK))
> +	if (!(priv->read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK))
>  		return -ETIMEDOUT;
>  
>  	return 0;
> @@ -415,14 +425,14 @@ static int flexcan_chip_freeze(struct flexcan_priv *priv)
>  	unsigned int timeout = 1000 * 1000 * 10 / priv->can.bittiming.bitrate;
>  	u32 reg;
>  
> -	reg = flexcan_read(&regs->mcr);
> +	reg = priv->read(&regs->mcr);
>  	reg |= FLEXCAN_MCR_HALT;
> -	flexcan_write(reg, &regs->mcr);
> +	priv->write(reg, &regs->mcr);
>  
> -	while (timeout-- && !(flexcan_read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK))
> +	while (timeout-- && !(priv->read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK))
>  		udelay(100);
>  
> -	if (!(flexcan_read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK))
> +	if (!(priv->read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK))
>  		return -ETIMEDOUT;
>  
>  	return 0;
> @@ -434,14 +444,14 @@ static int flexcan_chip_unfreeze(struct flexcan_priv *priv)
>  	unsigned int timeout = FLEXCAN_TIMEOUT_US / 10;
>  	u32 reg;
>  
> -	reg = flexcan_read(&regs->mcr);
> +	reg = priv->read(&regs->mcr);
>  	reg &= ~FLEXCAN_MCR_HALT;
> -	flexcan_write(reg, &regs->mcr);
> +	priv->write(reg, &regs->mcr);
>  
> -	while (timeout-- && (flexcan_read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK))
> +	while (timeout-- && (priv->read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK))
>  		udelay(10);
>  
> -	if (flexcan_read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK)
> +	if (priv->read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK)
>  		return -ETIMEDOUT;
>  
>  	return 0;
> @@ -452,11 +462,11 @@ static int flexcan_chip_softreset(struct flexcan_priv *priv)
>  	struct flexcan_regs __iomem *regs = priv->regs;
>  	unsigned int timeout = FLEXCAN_TIMEOUT_US / 10;
>  
> -	flexcan_write(FLEXCAN_MCR_SOFTRST, &regs->mcr);
> -	while (timeout-- && (flexcan_read(&regs->mcr) & FLEXCAN_MCR_SOFTRST))
> +	priv->write(FLEXCAN_MCR_SOFTRST, &regs->mcr);
> +	while (timeout-- && (priv->read(&regs->mcr) & FLEXCAN_MCR_SOFTRST))
>  		udelay(10);
>  
> -	if (flexcan_read(&regs->mcr) & FLEXCAN_MCR_SOFTRST)
> +	if (priv->read(&regs->mcr) & FLEXCAN_MCR_SOFTRST)
>  		return -ETIMEDOUT;
>  
>  	return 0;
> @@ -467,7 +477,7 @@ static int __flexcan_get_berr_counter(const struct net_device *dev,
>  {
>  	const struct flexcan_priv *priv = netdev_priv(dev);
>  	struct flexcan_regs __iomem *regs = priv->regs;
> -	u32 reg = flexcan_read(&regs->ecr);
> +	u32 reg = priv->read(&regs->ecr);
>  
>  	bec->txerr = (reg >> 0) & 0xff;
>  	bec->rxerr = (reg >> 8) & 0xff;
> @@ -523,24 +533,24 @@ static int flexcan_start_xmit(struct sk_buff *skb, struct net_device *dev)
>  
>  	if (cf->can_dlc > 0) {
>  		data = be32_to_cpup((__be32 *)&cf->data[0]);
> -		flexcan_write(data, &priv->tx_mb->data[0]);
> +		priv->write(data, &priv->tx_mb->data[0]);
>  	}
>  	if (cf->can_dlc > 3) {
>  		data = be32_to_cpup((__be32 *)&cf->data[4]);
> -		flexcan_write(data, &priv->tx_mb->data[1]);
> +		priv->write(data, &priv->tx_mb->data[1]);
>  	}
>  
>  	can_put_echo_skb(skb, dev, 0);
>  
> -	flexcan_write(can_id, &priv->tx_mb->can_id);
> -	flexcan_write(ctrl, &priv->tx_mb->can_ctrl);
> +	priv->write(can_id, &priv->tx_mb->can_id);
> +	priv->write(ctrl, &priv->tx_mb->can_ctrl);
>  
>  	/* Errata ERR005829 step8:
>  	 * Write twice INACTIVE(0x8) code to first MB.
>  	 */
> -	flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE,
> +	priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
>  		      &priv->tx_mb_reserved->can_ctrl);
> -	flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE,
> +	priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
>  		      &priv->tx_mb_reserved->can_ctrl);
>  
>  	return NETDEV_TX_OK;
> @@ -659,7 +669,7 @@ static unsigned int flexcan_mailbox_read(struct can_rx_offload *offload,
>  		u32 code;
>  
>  		do {
> -			reg_ctrl = flexcan_read(&mb->can_ctrl);
> +			reg_ctrl = priv->read(&mb->can_ctrl);
>  		} while (reg_ctrl & FLEXCAN_MB_CODE_RX_BUSY_BIT);
>  
>  		/* is this MB empty? */
> @@ -674,17 +684,17 @@ static unsigned int flexcan_mailbox_read(struct can_rx_offload *offload,
>  			offload->dev->stats.rx_errors++;
>  		}
>  	} else {
> -		reg_iflag1 = flexcan_read(&regs->iflag1);
> +		reg_iflag1 = priv->read(&regs->iflag1);
>  		if (!(reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_AVAILABLE))
>  			return 0;
>  
> -		reg_ctrl = flexcan_read(&mb->can_ctrl);
> +		reg_ctrl = priv->read(&mb->can_ctrl);
>  	}
>  
>  	/* increase timstamp to full 32 bit */
>  	*timestamp = reg_ctrl << 16;
>  
> -	reg_id = flexcan_read(&mb->can_id);
> +	reg_id = priv->read(&mb->can_id);
>  	if (reg_ctrl & FLEXCAN_MB_CNT_IDE)
>  		cf->can_id = ((reg_id >> 0) & CAN_EFF_MASK) | CAN_EFF_FLAG;
>  	else
> @@ -694,19 +704,19 @@ static unsigned int flexcan_mailbox_read(struct can_rx_offload *offload,
>  		cf->can_id |= CAN_RTR_FLAG;
>  	cf->can_dlc = get_can_dlc((reg_ctrl >> 16) & 0xf);
>  
> -	*(__be32 *)(cf->data + 0) = cpu_to_be32(flexcan_read(&mb->data[0]));
> -	*(__be32 *)(cf->data + 4) = cpu_to_be32(flexcan_read(&mb->data[1]));
> +	*(__be32 *)(cf->data + 0) = cpu_to_be32(priv->read(&mb->data[0]));
> +	*(__be32 *)(cf->data + 4) = cpu_to_be32(priv->read(&mb->data[1]));
>  
>  	/* mark as read */
>  	if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) {
>  		/* Clear IRQ */
>  		if (n < 32)
> -			flexcan_write(BIT(n), &regs->iflag1);
> +			priv->write(BIT(n), &regs->iflag1);
>  		else
> -			flexcan_write(BIT(n - 32), &regs->iflag2);
> +			priv->write(BIT(n - 32), &regs->iflag2);
>  	} else {
> -		flexcan_write(FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, &regs->iflag1);
> -		flexcan_read(&regs->timer);
> +		priv->write(FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, &regs->iflag1);
> +		priv->read(&regs->timer);
>  	}
>  
>  	return 1;
> @@ -718,8 +728,8 @@ static inline u64 flexcan_read_reg_iflag_rx(struct flexcan_priv *priv)
>  	struct flexcan_regs __iomem *regs = priv->regs;
>  	u32 iflag1, iflag2;
>  
> -	iflag2 = flexcan_read(&regs->iflag2) & priv->reg_imask2_default;
> -	iflag1 = flexcan_read(&regs->iflag1) & priv->reg_imask1_default &
> +	iflag2 = priv->read(&regs->iflag2) & priv->reg_imask2_default;
> +	iflag1 = priv->read(&regs->iflag1) & priv->reg_imask1_default &
>  		~FLEXCAN_IFLAG_MB(priv->tx_mb_idx);
>  
>  	return (u64)iflag2 << 32 | iflag1;
> @@ -735,7 +745,7 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
>  	u32 reg_iflag1, reg_esr;
>  	enum can_state last_state = priv->can.state;
>  
> -	reg_iflag1 = flexcan_read(&regs->iflag1);
> +	reg_iflag1 = priv->read(&regs->iflag1);
>  
>  	/* reception interrupt */
>  	if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) {
> @@ -758,7 +768,8 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
>  		/* FIFO overflow interrupt */
>  		if (reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_OVERFLOW) {
>  			handled = IRQ_HANDLED;
> -			flexcan_write(FLEXCAN_IFLAG_RX_FIFO_OVERFLOW, &regs->iflag1);
> +			priv->write(FLEXCAN_IFLAG_RX_FIFO_OVERFLOW,
> +				      &regs->iflag1);
>  			dev->stats.rx_over_errors++;
>  			dev->stats.rx_errors++;
>  		}
> @@ -772,18 +783,18 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
>  		can_led_event(dev, CAN_LED_EVENT_TX);
>  
>  		/* after sending a RTR frame MB is in RX mode */
> -		flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE,
> +		priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
>  			      &priv->tx_mb->can_ctrl);
> -		flexcan_write(FLEXCAN_IFLAG_MB(priv->tx_mb_idx), &regs->iflag1);
> +		priv->write(FLEXCAN_IFLAG_MB(priv->tx_mb_idx), &regs->iflag1);
>  		netif_wake_queue(dev);
>  	}
>  
> -	reg_esr = flexcan_read(&regs->esr);
> +	reg_esr = priv->read(&regs->esr);
>  
>  	/* ACK all bus error and state change IRQ sources */
>  	if (reg_esr & FLEXCAN_ESR_ALL_INT) {
>  		handled = IRQ_HANDLED;
> -		flexcan_write(reg_esr & FLEXCAN_ESR_ALL_INT, &regs->esr);
> +		priv->write(reg_esr & FLEXCAN_ESR_ALL_INT, &regs->esr);
>  	}
>  
>  	/* state change interrupt or broken error state quirk fix is enabled */
> @@ -845,7 +856,7 @@ static void flexcan_set_bittiming(struct net_device *dev)
>  	struct flexcan_regs __iomem *regs = priv->regs;
>  	u32 reg;
>  
> -	reg = flexcan_read(&regs->ctrl);
> +	reg = priv->read(&regs->ctrl);
>  	reg &= ~(FLEXCAN_CTRL_PRESDIV(0xff) |
>  		 FLEXCAN_CTRL_RJW(0x3) |
>  		 FLEXCAN_CTRL_PSEG1(0x7) |
> @@ -869,11 +880,11 @@ static void flexcan_set_bittiming(struct net_device *dev)
>  		reg |= FLEXCAN_CTRL_SMP;
>  
>  	netdev_dbg(dev, "writing ctrl=0x%08x\n", reg);
> -	flexcan_write(reg, &regs->ctrl);
> +	priv->write(reg, &regs->ctrl);
>  
>  	/* print chip status */
>  	netdev_dbg(dev, "%s: mcr=0x%08x ctrl=0x%08x\n", __func__,
> -		   flexcan_read(&regs->mcr), flexcan_read(&regs->ctrl));
> +		   priv->read(&regs->mcr), priv->read(&regs->ctrl));
>  }
>  
>  /* flexcan_chip_start
> @@ -912,7 +923,7 @@ static int flexcan_chip_start(struct net_device *dev)
>  	 * choose format C
>  	 * set max mailbox number
>  	 */
> -	reg_mcr = flexcan_read(&regs->mcr);
> +	reg_mcr = priv->read(&regs->mcr);
>  	reg_mcr &= ~FLEXCAN_MCR_MAXMB(0xff);
>  	reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT | FLEXCAN_MCR_SUPV |
>  		FLEXCAN_MCR_WRN_EN | FLEXCAN_MCR_SRX_DIS | FLEXCAN_MCR_IRMQ |
> @@ -926,7 +937,7 @@ static int flexcan_chip_start(struct net_device *dev)
>  			FLEXCAN_MCR_MAXMB(priv->tx_mb_idx);
>  	}
>  	netdev_dbg(dev, "%s: writing mcr=0x%08x", __func__, reg_mcr);
> -	flexcan_write(reg_mcr, &regs->mcr);
> +	priv->write(reg_mcr, &regs->mcr);
>  
>  	/* CTRL
>  	 *
> @@ -939,7 +950,7 @@ static int flexcan_chip_start(struct net_device *dev)
>  	 * enable bus off interrupt
>  	 * (== FLEXCAN_CTRL_ERR_STATE)
>  	 */
> -	reg_ctrl = flexcan_read(&regs->ctrl);
> +	reg_ctrl = priv->read(&regs->ctrl);
>  	reg_ctrl &= ~FLEXCAN_CTRL_TSYN;
>  	reg_ctrl |= FLEXCAN_CTRL_BOFF_REC | FLEXCAN_CTRL_LBUF |
>  		FLEXCAN_CTRL_ERR_STATE;
> @@ -959,45 +970,45 @@ static int flexcan_chip_start(struct net_device *dev)
>  	/* leave interrupts disabled for now */
>  	reg_ctrl &= ~FLEXCAN_CTRL_ERR_ALL;
>  	netdev_dbg(dev, "%s: writing ctrl=0x%08x", __func__, reg_ctrl);
> -	flexcan_write(reg_ctrl, &regs->ctrl);
> +	priv->write(reg_ctrl, &regs->ctrl);
>  
>  	if ((priv->devtype_data->quirks & FLEXCAN_QUIRK_ENABLE_EACEN_RRS)) {
> -		reg_ctrl2 = flexcan_read(&regs->ctrl2);
> +		reg_ctrl2 = priv->read(&regs->ctrl2);
>  		reg_ctrl2 |= FLEXCAN_CTRL2_EACEN | FLEXCAN_CTRL2_RRS;
> -		flexcan_write(reg_ctrl2, &regs->ctrl2);
> +		priv->write(reg_ctrl2, &regs->ctrl2);
>  	}
>  
>  	/* clear and invalidate all mailboxes first */
>  	for (i = priv->tx_mb_idx; i < ARRAY_SIZE(regs->mb); i++) {
> -		flexcan_write(FLEXCAN_MB_CODE_RX_INACTIVE,
> +		priv->write(FLEXCAN_MB_CODE_RX_INACTIVE,
>  			      &regs->mb[i].can_ctrl);
>  	}
>  
>  	if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) {
>  		for (i = priv->offload.mb_first; i <= priv->offload.mb_last; i++)
> -			flexcan_write(FLEXCAN_MB_CODE_RX_EMPTY,
> +			priv->write(FLEXCAN_MB_CODE_RX_EMPTY,
>  				      &regs->mb[i].can_ctrl);
>  	}
>  
>  	/* Errata ERR005829: mark first TX mailbox as INACTIVE */
> -	flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE,
> +	priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
>  		      &priv->tx_mb_reserved->can_ctrl);
>  
>  	/* mark TX mailbox as INACTIVE */
> -	flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE,
> +	priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
>  		      &priv->tx_mb->can_ctrl);
>  
>  	/* acceptance mask/acceptance code (accept everything) */
> -	flexcan_write(0x0, &regs->rxgmask);
> -	flexcan_write(0x0, &regs->rx14mask);
> -	flexcan_write(0x0, &regs->rx15mask);
> +	priv->write(0x0, &regs->rxgmask);
> +	priv->write(0x0, &regs->rx14mask);
> +	priv->write(0x0, &regs->rx15mask);
>  
>  	if (priv->devtype_data->quirks & FLEXCAN_QUIRK_DISABLE_RXFG)
> -		flexcan_write(0x0, &regs->rxfgmask);
> +		priv->write(0x0, &regs->rxfgmask);
>  
>  	/* clear acceptance filters */
>  	for (i = 0; i < ARRAY_SIZE(regs->mb); i++)
> -		flexcan_write(0, &regs->rximr[i]);
> +		priv->write(0, &regs->rximr[i]);
>  
>  	/* On Vybrid, disable memory error detection interrupts
>  	 * and freeze mode.
> @@ -1010,16 +1021,16 @@ static int flexcan_chip_start(struct net_device *dev)
>  		 * and Correction of Memory Errors" to write to
>  		 * MECR register
>  		 */
> -		reg_ctrl2 = flexcan_read(&regs->ctrl2);
> +		reg_ctrl2 = priv->read(&regs->ctrl2);
>  		reg_ctrl2 |= FLEXCAN_CTRL2_ECRWRE;
> -		flexcan_write(reg_ctrl2, &regs->ctrl2);
> +		priv->write(reg_ctrl2, &regs->ctrl2);
>  
> -		reg_mecr = flexcan_read(&regs->mecr);
> +		reg_mecr = priv->read(&regs->mecr);
>  		reg_mecr &= ~FLEXCAN_MECR_ECRWRDIS;
> -		flexcan_write(reg_mecr, &regs->mecr);
> +		priv->write(reg_mecr, &regs->mecr);
>  		reg_mecr &= ~(FLEXCAN_MECR_NCEFAFRZ | FLEXCAN_MECR_HANCEI_MSK |
>  			      FLEXCAN_MECR_FANCEI_MSK);
> -		flexcan_write(reg_mecr, &regs->mecr);
> +		priv->write(reg_mecr, &regs->mecr);
>  	}
>  
>  	err = flexcan_transceiver_enable(priv);
> @@ -1035,14 +1046,14 @@ static int flexcan_chip_start(struct net_device *dev)
>  
>  	/* enable interrupts atomically */
>  	disable_irq(dev->irq);
> -	flexcan_write(priv->reg_ctrl_default, &regs->ctrl);
> -	flexcan_write(priv->reg_imask1_default, &regs->imask1);
> -	flexcan_write(priv->reg_imask2_default, &regs->imask2);
> +	priv->write(priv->reg_ctrl_default, &regs->ctrl);
> +	priv->write(priv->reg_imask1_default, &regs->imask1);
> +	priv->write(priv->reg_imask2_default, &regs->imask2);
>  	enable_irq(dev->irq);
>  
>  	/* print chip status */
>  	netdev_dbg(dev, "%s: reading mcr=0x%08x ctrl=0x%08x\n", __func__,
> -		   flexcan_read(&regs->mcr), flexcan_read(&regs->ctrl));
> +		   priv->read(&regs->mcr), priv->read(&regs->ctrl));
>  
>  	return 0;
>  
> @@ -1067,9 +1078,9 @@ static void flexcan_chip_stop(struct net_device *dev)
>  	flexcan_chip_disable(priv);
>  
>  	/* Disable all interrupts */
> -	flexcan_write(0, &regs->imask2);
> -	flexcan_write(0, &regs->imask1);
> -	flexcan_write(priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_ALL,
> +	priv->write(0, &regs->imask2);
> +	priv->write(0, &regs->imask1);
> +	priv->write(priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_ALL,
>  		      &regs->ctrl);
>  
>  	flexcan_transceiver_disable(priv);
> @@ -1185,26 +1196,26 @@ static int register_flexcandev(struct net_device *dev)
>  	err = flexcan_chip_disable(priv);
>  	if (err)
>  		goto out_disable_per;
> -	reg = flexcan_read(&regs->ctrl);
> +	reg = priv->read(&regs->ctrl);
>  	reg |= FLEXCAN_CTRL_CLK_SRC;
> -	flexcan_write(reg, &regs->ctrl);
> +	priv->write(reg, &regs->ctrl);
>  
>  	err = flexcan_chip_enable(priv);
>  	if (err)
>  		goto out_chip_disable;
>  
>  	/* set freeze, halt and activate FIFO, restrict register access */
> -	reg = flexcan_read(&regs->mcr);
> +	reg = priv->read(&regs->mcr);
>  	reg |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT |
>  		FLEXCAN_MCR_FEN | FLEXCAN_MCR_SUPV;
> -	flexcan_write(reg, &regs->mcr);
> +	priv->write(reg, &regs->mcr);
>  
>  	/* Currently we only support newer versions of this core
>  	 * featuring a RX hardware FIFO (although this driver doesn't
>  	 * make use of it on some cores). Older cores, found on some
>  	 * Coldfire derivates are not tested.
>  	 */
> -	reg = flexcan_read(&regs->mcr);
> +	reg = priv->read(&regs->mcr);
>  	if (!(reg & FLEXCAN_MCR_FEN)) {
>  		netdev_err(dev, "Could not enable RX FIFO, unsupported core\n");
>  		err = -ENODEV;
> @@ -1313,6 +1324,15 @@ static int flexcan_probe(struct platform_device *pdev)
>  	dev->flags |= IFF_ECHO;
>  
>  	priv = netdev_priv(dev);
> +
> +	if (of_property_read_bool(pdev->dev.of_node, "big-endian")) {

Don't do this. This is not backwards compatible with the existing PPC
boards. Please add all needed information to the devtype_data.

> +		priv->read = flexcan_read_be;
> +		priv->write = flexcan_write_be;
> +	} else {
> +		priv->read = flexcan_read_le;
> +		priv->write = flexcan_write_le;
> +	}
> +
>  	priv->can.clock.freq = clock_freq;
>  	priv->can.bittiming_const = &flexcan_bittiming_const;
>  	priv->can.do_set_mode = flexcan_set_mode;
> 

Marc

-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 1/2] can: flexcan: Remodel FlexCAN register r/w APIs for big endian FlexCAN controllers.
  2017-11-10  9:59 [PATCH 1/2] can: flexcan: Remodel FlexCAN register r/w APIs for big endian FlexCAN controllers Pankaj Bansal
  2017-11-10  9:59 ` [PATCH 2/2] can: flexcan: adding platform specific details for LS1021A Pankaj Bansal
  2017-11-10 10:06 ` [PATCH 1/2] can: flexcan: Remodel FlexCAN register r/w APIs for big endian FlexCAN controllers Marc Kleine-Budde
@ 2017-11-10 10:48 ` Marc Kleine-Budde
  2017-11-14 11:56 ` [PATCH v2 " Pankaj Bansal
  3 siblings, 0 replies; 52+ messages in thread
From: Marc Kleine-Budde @ 2017-11-10 10:48 UTC (permalink / raw)
  To: Pankaj Bansal, wg, linux-can; +Cc: V.Sethi, poonam.aggrwal


[-- Attachment #1.1: Type: text/plain, Size: 1268 bytes --]

On 11/10/2017 10:59 AM, Pankaj Bansal wrote:
> The FlexCAN driver assumed that FlexCAN controller is big endian for
> powerpc architecture and little endian for other architectures.
> 
> But this may not be the case. FlexCAN controller can be little or
> big endian on any architecture. For e.g. NXP LS1021A ARM based SOC
> has big endian FlexCAN controller.
> 
> Therefore, the driver has been modified to add a provision for both
> types of controllers using an additional device tree property. Big
> Endian controllers should have "big-endian" set in the device tree.
> 
> Signed-off-by: Pankaj Bansal <pankaj.bansal@nxp.com>
> Signed-off-by: Bhupesh Sharma <bhupesh.sharma@freescale.com>
> Signed-off-by: Sakar Arora <Sakar.Arora@freescale.com>
> Reviewed-by: Zhengxiong Jin <Jason.Jin@freescale.com>
> Reviewed-by: Poonam Aggrwal <poonam.aggrwal@nxp.com>

Can you fix the email addresses of sakar.arora and bhupesh.sharma? They
are not deliverable any more.

Marc

-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 52+ messages in thread

* RE: [PATCH 1/2] can: flexcan: Remodel FlexCAN register r/w APIs for big endian FlexCAN controllers.
  2017-11-10 10:06 ` [PATCH 1/2] can: flexcan: Remodel FlexCAN register r/w APIs for big endian FlexCAN controllers Marc Kleine-Budde
@ 2017-11-10 11:06   ` Pankaj Bansal
  2017-11-10 11:09     ` Marc Kleine-Budde
  0 siblings, 1 reply; 52+ messages in thread
From: Pankaj Bansal @ 2017-11-10 11:06 UTC (permalink / raw)
  To: Marc Kleine-Budde, wg, linux-can
  Cc: Varun Sethi, Poonam Aggrwal, Bhupesh Sharma, Sakar Arora

Hi Marc,

Thank you for reviewing my changes.

1. I will fix the le and be APIs order.
2. Some of the original team members that had contributed to these changes have left the organization. Please suggest on how to give them credit in these patches?
3. Regarding backward compatibility with PowerPC, I see that there is only one platform in PowerPC architecture that is using flexcan.
    There is only one platform in "arch/powerpc/boot/dts/" having flexcan node. p1010si-post.dtsi
    I have added the big-endian property in that platform and have tested it on P1010 platform after backporting the patch to Freescale SDK 1.4 linux.
    I have sent the patch for this. See "[PATCH 2/3] powerpc: dts: P1010: Add endianness property to flexcan node"
    I believe these changes can be accepted for both powerpc and arm and other architectures that use flexcan.

Thanks & Regards,
Pankaj Bansal

-----Original Message-----
From: Marc Kleine-Budde [mailto:mkl@pengutronix.de] 
Sent: Friday, November 10, 2017 3:37 PM
To: Pankaj Bansal <pankaj.bansal@nxp.com>; wg@grandegger.com; linux-can@vger.kernel.org
Cc: Varun Sethi <V.Sethi@nxp.com>; Poonam Aggrwal <poonam.aggrwal@nxp.com>; Bhupesh Sharma <bhupesh.sharma@freescale.com>; Sakar Arora <Sakar.Arora@freescale.com>
Subject: Re: [PATCH 1/2] can: flexcan: Remodel FlexCAN register r/w APIs for big endian FlexCAN controllers.

On 11/10/2017 10:59 AM, Pankaj Bansal wrote:
> The FlexCAN driver assumed that FlexCAN controller is big endian for 
> powerpc architecture and little endian for other architectures.
> 
> But this may not be the case. FlexCAN controller can be little or big 
> endian on any architecture. For e.g. NXP LS1021A ARM based SOC has big 
> endian FlexCAN controller.
> 
> Therefore, the driver has been modified to add a provision for both 
> types of controllers using an additional device tree property. Big 
> Endian controllers should have "big-endian" set in the device tree.
> 
> Signed-off-by: Pankaj Bansal <pankaj.bansal@nxp.com>
> Signed-off-by: Bhupesh Sharma <bhupesh.sharma@freescale.com>
> Signed-off-by: Sakar Arora <Sakar.Arora@freescale.com>
> Reviewed-by: Zhengxiong Jin <Jason.Jin@freescale.com>
> Reviewed-by: Poonam Aggrwal <poonam.aggrwal@nxp.com>
> ---
> Tested on Arm32 based NXP LS1021A-TWR board (linux-can-next/master 
> branch) Tested on PowerPC based NXP P1010RDB board (after back porting 
> to Freescale SDK 1.4 linux)
> 
>  drivers/net/can/flexcan.c | 212 ++++++++++++++++++++----------------
>  1 file changed, 116 insertions(+), 96 deletions(-)
> 
> diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c 
> index a13a489..d4ce2df 100644
> --- a/drivers/net/can/flexcan.c
> +++ b/drivers/net/can/flexcan.c
> @@ -279,6 +279,10 @@ struct flexcan_priv {
>  	struct clk *clk_per;
>  	const struct flexcan_devtype_data *devtype_data;
>  	struct regulator *reg_xceiver;
> +
> +	/* Read and Write APIs */
> +	u32 (*read)(void __iomem *addr);
> +	void (*write)(u32 val, void __iomem *addr);
>  };
>  
>  static const struct flexcan_devtype_data fsl_p1010_devtype_data = { 
> @@ -312,39 +316,45 @@ static const struct can_bittiming_const flexcan_bittiming_const = {
>  	.brp_inc = 1,
>  };
>  
> -/* Abstract off the read/write for arm versus ppc. This
> - * assumes that PPC uses big-endian registers and everything
> - * else uses little-endian registers, independent of CPU
> - * endianness.
> +/* FlexCAN module is essentially modelled as a little-endian IP in 
> +most
> + * SoCs, i.e the registers as well as the message buffer areas are
> + * implemented in a little-endian fashion.
> + *
> + * However there are some SoCs (e.g. LS1021A) which implement the 
> +FlexCAN
> + * module in a big-endian fashion (i.e the registers as well as the
> + * message buffer areas are implemented in a big-endian way).
> + *
> + * In addition, the FlexCAN module can be found on SoCs having ARM or
> + * PPC cores. So, we need to abstract off the register read/write
> + * functions, ensuring that these cater to all the combinations of 
> +module
> + * endianness and underlying CPU endianness.
>   */
> -#if defined(CONFIG_PPC)
> -static inline u32 flexcan_read(void __iomem *addr)
> +static inline u32 flexcan_read_le(void __iomem *addr)
>  {
> -	return in_be32(addr);
> +	return ioread32(addr);
>  }
>  
> -static inline void flexcan_write(u32 val, void __iomem *addr)
> +static inline void flexcan_write_le(u32 val, void __iomem *addr)
>  {
> -	out_be32(addr, val);
> +	iowrite32(val, addr);
>  }

Please make this the be variants, followed by the le below. Should make the patch easier to read.

> -#else
> -static inline u32 flexcan_read(void __iomem *addr)
> +
> +static inline u32 flexcan_read_be(void __iomem *addr)
>  {
> -	return readl(addr);
> +	return ioread32be(addr);
>  }
>  
> -static inline void flexcan_write(u32 val, void __iomem *addr)
> +static inline void flexcan_write_be(u32 val, void __iomem *addr)
>  {
> -	writel(val, addr);
> +	iowrite32be(val, addr);
>  }
> -#endif
>  
>  static inline void flexcan_error_irq_enable(const struct flexcan_priv 
> *priv)  {
>  	struct flexcan_regs __iomem *regs = priv->regs;
>  	u32 reg_ctrl = (priv->reg_ctrl_default | FLEXCAN_CTRL_ERR_MSK);
>  
> -	flexcan_write(reg_ctrl, &regs->ctrl);
> +	priv->write(reg_ctrl, &regs->ctrl);
>  }
>  
>  static inline void flexcan_error_irq_disable(const struct 
> flexcan_priv *priv) @@ -352,7 +362,7 @@ static inline void flexcan_error_irq_disable(const struct flexcan_priv *priv)
>  	struct flexcan_regs __iomem *regs = priv->regs;
>  	u32 reg_ctrl = (priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_MSK);
>  
> -	flexcan_write(reg_ctrl, &regs->ctrl);
> +	priv->write(reg_ctrl, &regs->ctrl);
>  }
>  
>  static inline int flexcan_transceiver_enable(const struct 
> flexcan_priv *priv) @@ -377,14 +387,14 @@ static int flexcan_chip_enable(struct flexcan_priv *priv)
>  	unsigned int timeout = FLEXCAN_TIMEOUT_US / 10;
>  	u32 reg;
>  
> -	reg = flexcan_read(&regs->mcr);
> +	reg = priv->read(&regs->mcr);
>  	reg &= ~FLEXCAN_MCR_MDIS;
> -	flexcan_write(reg, &regs->mcr);
> +	priv->write(reg, &regs->mcr);
>  
> -	while (timeout-- && (flexcan_read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK))
> +	while (timeout-- && (priv->read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK))
>  		udelay(10);
>  
> -	if (flexcan_read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK)
> +	if (priv->read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK)
>  		return -ETIMEDOUT;
>  
>  	return 0;
> @@ -396,14 +406,14 @@ static int flexcan_chip_disable(struct flexcan_priv *priv)
>  	unsigned int timeout = FLEXCAN_TIMEOUT_US / 10;
>  	u32 reg;
>  
> -	reg = flexcan_read(&regs->mcr);
> +	reg = priv->read(&regs->mcr);
>  	reg |= FLEXCAN_MCR_MDIS;
> -	flexcan_write(reg, &regs->mcr);
> +	priv->write(reg, &regs->mcr);
>  
> -	while (timeout-- && !(flexcan_read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK))
> +	while (timeout-- && !(priv->read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK))
>  		udelay(10);
>  
> -	if (!(flexcan_read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK))
> +	if (!(priv->read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK))
>  		return -ETIMEDOUT;
>  
>  	return 0;
> @@ -415,14 +425,14 @@ static int flexcan_chip_freeze(struct flexcan_priv *priv)
>  	unsigned int timeout = 1000 * 1000 * 10 / priv->can.bittiming.bitrate;
>  	u32 reg;
>  
> -	reg = flexcan_read(&regs->mcr);
> +	reg = priv->read(&regs->mcr);
>  	reg |= FLEXCAN_MCR_HALT;
> -	flexcan_write(reg, &regs->mcr);
> +	priv->write(reg, &regs->mcr);
>  
> -	while (timeout-- && !(flexcan_read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK))
> +	while (timeout-- && !(priv->read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK))
>  		udelay(100);
>  
> -	if (!(flexcan_read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK))
> +	if (!(priv->read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK))
>  		return -ETIMEDOUT;
>  
>  	return 0;
> @@ -434,14 +444,14 @@ static int flexcan_chip_unfreeze(struct flexcan_priv *priv)
>  	unsigned int timeout = FLEXCAN_TIMEOUT_US / 10;
>  	u32 reg;
>  
> -	reg = flexcan_read(&regs->mcr);
> +	reg = priv->read(&regs->mcr);
>  	reg &= ~FLEXCAN_MCR_HALT;
> -	flexcan_write(reg, &regs->mcr);
> +	priv->write(reg, &regs->mcr);
>  
> -	while (timeout-- && (flexcan_read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK))
> +	while (timeout-- && (priv->read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK))
>  		udelay(10);
>  
> -	if (flexcan_read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK)
> +	if (priv->read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK)
>  		return -ETIMEDOUT;
>  
>  	return 0;
> @@ -452,11 +462,11 @@ static int flexcan_chip_softreset(struct flexcan_priv *priv)
>  	struct flexcan_regs __iomem *regs = priv->regs;
>  	unsigned int timeout = FLEXCAN_TIMEOUT_US / 10;
>  
> -	flexcan_write(FLEXCAN_MCR_SOFTRST, &regs->mcr);
> -	while (timeout-- && (flexcan_read(&regs->mcr) & FLEXCAN_MCR_SOFTRST))
> +	priv->write(FLEXCAN_MCR_SOFTRST, &regs->mcr);
> +	while (timeout-- && (priv->read(&regs->mcr) & FLEXCAN_MCR_SOFTRST))
>  		udelay(10);
>  
> -	if (flexcan_read(&regs->mcr) & FLEXCAN_MCR_SOFTRST)
> +	if (priv->read(&regs->mcr) & FLEXCAN_MCR_SOFTRST)
>  		return -ETIMEDOUT;
>  
>  	return 0;
> @@ -467,7 +477,7 @@ static int __flexcan_get_berr_counter(const struct 
> net_device *dev,  {
>  	const struct flexcan_priv *priv = netdev_priv(dev);
>  	struct flexcan_regs __iomem *regs = priv->regs;
> -	u32 reg = flexcan_read(&regs->ecr);
> +	u32 reg = priv->read(&regs->ecr);
>  
>  	bec->txerr = (reg >> 0) & 0xff;
>  	bec->rxerr = (reg >> 8) & 0xff;
> @@ -523,24 +533,24 @@ static int flexcan_start_xmit(struct sk_buff 
> *skb, struct net_device *dev)
>  
>  	if (cf->can_dlc > 0) {
>  		data = be32_to_cpup((__be32 *)&cf->data[0]);
> -		flexcan_write(data, &priv->tx_mb->data[0]);
> +		priv->write(data, &priv->tx_mb->data[0]);
>  	}
>  	if (cf->can_dlc > 3) {
>  		data = be32_to_cpup((__be32 *)&cf->data[4]);
> -		flexcan_write(data, &priv->tx_mb->data[1]);
> +		priv->write(data, &priv->tx_mb->data[1]);
>  	}
>  
>  	can_put_echo_skb(skb, dev, 0);
>  
> -	flexcan_write(can_id, &priv->tx_mb->can_id);
> -	flexcan_write(ctrl, &priv->tx_mb->can_ctrl);
> +	priv->write(can_id, &priv->tx_mb->can_id);
> +	priv->write(ctrl, &priv->tx_mb->can_ctrl);
>  
>  	/* Errata ERR005829 step8:
>  	 * Write twice INACTIVE(0x8) code to first MB.
>  	 */
> -	flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE,
> +	priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
>  		      &priv->tx_mb_reserved->can_ctrl);
> -	flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE,
> +	priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
>  		      &priv->tx_mb_reserved->can_ctrl);
>  
>  	return NETDEV_TX_OK;
> @@ -659,7 +669,7 @@ static unsigned int flexcan_mailbox_read(struct can_rx_offload *offload,
>  		u32 code;
>  
>  		do {
> -			reg_ctrl = flexcan_read(&mb->can_ctrl);
> +			reg_ctrl = priv->read(&mb->can_ctrl);
>  		} while (reg_ctrl & FLEXCAN_MB_CODE_RX_BUSY_BIT);
>  
>  		/* is this MB empty? */
> @@ -674,17 +684,17 @@ static unsigned int flexcan_mailbox_read(struct can_rx_offload *offload,
>  			offload->dev->stats.rx_errors++;
>  		}
>  	} else {
> -		reg_iflag1 = flexcan_read(&regs->iflag1);
> +		reg_iflag1 = priv->read(&regs->iflag1);
>  		if (!(reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_AVAILABLE))
>  			return 0;
>  
> -		reg_ctrl = flexcan_read(&mb->can_ctrl);
> +		reg_ctrl = priv->read(&mb->can_ctrl);
>  	}
>  
>  	/* increase timstamp to full 32 bit */
>  	*timestamp = reg_ctrl << 16;
>  
> -	reg_id = flexcan_read(&mb->can_id);
> +	reg_id = priv->read(&mb->can_id);
>  	if (reg_ctrl & FLEXCAN_MB_CNT_IDE)
>  		cf->can_id = ((reg_id >> 0) & CAN_EFF_MASK) | CAN_EFF_FLAG;
>  	else
> @@ -694,19 +704,19 @@ static unsigned int flexcan_mailbox_read(struct can_rx_offload *offload,
>  		cf->can_id |= CAN_RTR_FLAG;
>  	cf->can_dlc = get_can_dlc((reg_ctrl >> 16) & 0xf);
>  
> -	*(__be32 *)(cf->data + 0) = cpu_to_be32(flexcan_read(&mb->data[0]));
> -	*(__be32 *)(cf->data + 4) = cpu_to_be32(flexcan_read(&mb->data[1]));
> +	*(__be32 *)(cf->data + 0) = cpu_to_be32(priv->read(&mb->data[0]));
> +	*(__be32 *)(cf->data + 4) = cpu_to_be32(priv->read(&mb->data[1]));
>  
>  	/* mark as read */
>  	if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) {
>  		/* Clear IRQ */
>  		if (n < 32)
> -			flexcan_write(BIT(n), &regs->iflag1);
> +			priv->write(BIT(n), &regs->iflag1);
>  		else
> -			flexcan_write(BIT(n - 32), &regs->iflag2);
> +			priv->write(BIT(n - 32), &regs->iflag2);
>  	} else {
> -		flexcan_write(FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, &regs->iflag1);
> -		flexcan_read(&regs->timer);
> +		priv->write(FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, &regs->iflag1);
> +		priv->read(&regs->timer);
>  	}
>  
>  	return 1;
> @@ -718,8 +728,8 @@ static inline u64 flexcan_read_reg_iflag_rx(struct flexcan_priv *priv)
>  	struct flexcan_regs __iomem *regs = priv->regs;
>  	u32 iflag1, iflag2;
>  
> -	iflag2 = flexcan_read(&regs->iflag2) & priv->reg_imask2_default;
> -	iflag1 = flexcan_read(&regs->iflag1) & priv->reg_imask1_default &
> +	iflag2 = priv->read(&regs->iflag2) & priv->reg_imask2_default;
> +	iflag1 = priv->read(&regs->iflag1) & priv->reg_imask1_default &
>  		~FLEXCAN_IFLAG_MB(priv->tx_mb_idx);
>  
>  	return (u64)iflag2 << 32 | iflag1;
> @@ -735,7 +745,7 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
>  	u32 reg_iflag1, reg_esr;
>  	enum can_state last_state = priv->can.state;
>  
> -	reg_iflag1 = flexcan_read(&regs->iflag1);
> +	reg_iflag1 = priv->read(&regs->iflag1);
>  
>  	/* reception interrupt */
>  	if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) { 
> @@ -758,7 +768,8 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
>  		/* FIFO overflow interrupt */
>  		if (reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_OVERFLOW) {
>  			handled = IRQ_HANDLED;
> -			flexcan_write(FLEXCAN_IFLAG_RX_FIFO_OVERFLOW, &regs->iflag1);
> +			priv->write(FLEXCAN_IFLAG_RX_FIFO_OVERFLOW,
> +				      &regs->iflag1);
>  			dev->stats.rx_over_errors++;
>  			dev->stats.rx_errors++;
>  		}
> @@ -772,18 +783,18 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
>  		can_led_event(dev, CAN_LED_EVENT_TX);
>  
>  		/* after sending a RTR frame MB is in RX mode */
> -		flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE,
> +		priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
>  			      &priv->tx_mb->can_ctrl);
> -		flexcan_write(FLEXCAN_IFLAG_MB(priv->tx_mb_idx), &regs->iflag1);
> +		priv->write(FLEXCAN_IFLAG_MB(priv->tx_mb_idx), &regs->iflag1);
>  		netif_wake_queue(dev);
>  	}
>  
> -	reg_esr = flexcan_read(&regs->esr);
> +	reg_esr = priv->read(&regs->esr);
>  
>  	/* ACK all bus error and state change IRQ sources */
>  	if (reg_esr & FLEXCAN_ESR_ALL_INT) {
>  		handled = IRQ_HANDLED;
> -		flexcan_write(reg_esr & FLEXCAN_ESR_ALL_INT, &regs->esr);
> +		priv->write(reg_esr & FLEXCAN_ESR_ALL_INT, &regs->esr);
>  	}
>  
>  	/* state change interrupt or broken error state quirk fix is enabled 
> */ @@ -845,7 +856,7 @@ static void flexcan_set_bittiming(struct net_device *dev)
>  	struct flexcan_regs __iomem *regs = priv->regs;
>  	u32 reg;
>  
> -	reg = flexcan_read(&regs->ctrl);
> +	reg = priv->read(&regs->ctrl);
>  	reg &= ~(FLEXCAN_CTRL_PRESDIV(0xff) |
>  		 FLEXCAN_CTRL_RJW(0x3) |
>  		 FLEXCAN_CTRL_PSEG1(0x7) |
> @@ -869,11 +880,11 @@ static void flexcan_set_bittiming(struct net_device *dev)
>  		reg |= FLEXCAN_CTRL_SMP;
>  
>  	netdev_dbg(dev, "writing ctrl=0x%08x\n", reg);
> -	flexcan_write(reg, &regs->ctrl);
> +	priv->write(reg, &regs->ctrl);
>  
>  	/* print chip status */
>  	netdev_dbg(dev, "%s: mcr=0x%08x ctrl=0x%08x\n", __func__,
> -		   flexcan_read(&regs->mcr), flexcan_read(&regs->ctrl));
> +		   priv->read(&regs->mcr), priv->read(&regs->ctrl));
>  }
>  
>  /* flexcan_chip_start
> @@ -912,7 +923,7 @@ static int flexcan_chip_start(struct net_device *dev)
>  	 * choose format C
>  	 * set max mailbox number
>  	 */
> -	reg_mcr = flexcan_read(&regs->mcr);
> +	reg_mcr = priv->read(&regs->mcr);
>  	reg_mcr &= ~FLEXCAN_MCR_MAXMB(0xff);
>  	reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT | FLEXCAN_MCR_SUPV |
>  		FLEXCAN_MCR_WRN_EN | FLEXCAN_MCR_SRX_DIS | FLEXCAN_MCR_IRMQ | @@ 
> -926,7 +937,7 @@ static int flexcan_chip_start(struct net_device *dev)
>  			FLEXCAN_MCR_MAXMB(priv->tx_mb_idx);
>  	}
>  	netdev_dbg(dev, "%s: writing mcr=0x%08x", __func__, reg_mcr);
> -	flexcan_write(reg_mcr, &regs->mcr);
> +	priv->write(reg_mcr, &regs->mcr);
>  
>  	/* CTRL
>  	 *
> @@ -939,7 +950,7 @@ static int flexcan_chip_start(struct net_device *dev)
>  	 * enable bus off interrupt
>  	 * (== FLEXCAN_CTRL_ERR_STATE)
>  	 */
> -	reg_ctrl = flexcan_read(&regs->ctrl);
> +	reg_ctrl = priv->read(&regs->ctrl);
>  	reg_ctrl &= ~FLEXCAN_CTRL_TSYN;
>  	reg_ctrl |= FLEXCAN_CTRL_BOFF_REC | FLEXCAN_CTRL_LBUF |
>  		FLEXCAN_CTRL_ERR_STATE;
> @@ -959,45 +970,45 @@ static int flexcan_chip_start(struct net_device *dev)
>  	/* leave interrupts disabled for now */
>  	reg_ctrl &= ~FLEXCAN_CTRL_ERR_ALL;
>  	netdev_dbg(dev, "%s: writing ctrl=0x%08x", __func__, reg_ctrl);
> -	flexcan_write(reg_ctrl, &regs->ctrl);
> +	priv->write(reg_ctrl, &regs->ctrl);
>  
>  	if ((priv->devtype_data->quirks & FLEXCAN_QUIRK_ENABLE_EACEN_RRS)) {
> -		reg_ctrl2 = flexcan_read(&regs->ctrl2);
> +		reg_ctrl2 = priv->read(&regs->ctrl2);
>  		reg_ctrl2 |= FLEXCAN_CTRL2_EACEN | FLEXCAN_CTRL2_RRS;
> -		flexcan_write(reg_ctrl2, &regs->ctrl2);
> +		priv->write(reg_ctrl2, &regs->ctrl2);
>  	}
>  
>  	/* clear and invalidate all mailboxes first */
>  	for (i = priv->tx_mb_idx; i < ARRAY_SIZE(regs->mb); i++) {
> -		flexcan_write(FLEXCAN_MB_CODE_RX_INACTIVE,
> +		priv->write(FLEXCAN_MB_CODE_RX_INACTIVE,
>  			      &regs->mb[i].can_ctrl);
>  	}
>  
>  	if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) {
>  		for (i = priv->offload.mb_first; i <= priv->offload.mb_last; i++)
> -			flexcan_write(FLEXCAN_MB_CODE_RX_EMPTY,
> +			priv->write(FLEXCAN_MB_CODE_RX_EMPTY,
>  				      &regs->mb[i].can_ctrl);
>  	}
>  
>  	/* Errata ERR005829: mark first TX mailbox as INACTIVE */
> -	flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE,
> +	priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
>  		      &priv->tx_mb_reserved->can_ctrl);
>  
>  	/* mark TX mailbox as INACTIVE */
> -	flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE,
> +	priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
>  		      &priv->tx_mb->can_ctrl);
>  
>  	/* acceptance mask/acceptance code (accept everything) */
> -	flexcan_write(0x0, &regs->rxgmask);
> -	flexcan_write(0x0, &regs->rx14mask);
> -	flexcan_write(0x0, &regs->rx15mask);
> +	priv->write(0x0, &regs->rxgmask);
> +	priv->write(0x0, &regs->rx14mask);
> +	priv->write(0x0, &regs->rx15mask);
>  
>  	if (priv->devtype_data->quirks & FLEXCAN_QUIRK_DISABLE_RXFG)
> -		flexcan_write(0x0, &regs->rxfgmask);
> +		priv->write(0x0, &regs->rxfgmask);
>  
>  	/* clear acceptance filters */
>  	for (i = 0; i < ARRAY_SIZE(regs->mb); i++)
> -		flexcan_write(0, &regs->rximr[i]);
> +		priv->write(0, &regs->rximr[i]);
>  
>  	/* On Vybrid, disable memory error detection interrupts
>  	 * and freeze mode.
> @@ -1010,16 +1021,16 @@ static int flexcan_chip_start(struct net_device *dev)
>  		 * and Correction of Memory Errors" to write to
>  		 * MECR register
>  		 */
> -		reg_ctrl2 = flexcan_read(&regs->ctrl2);
> +		reg_ctrl2 = priv->read(&regs->ctrl2);
>  		reg_ctrl2 |= FLEXCAN_CTRL2_ECRWRE;
> -		flexcan_write(reg_ctrl2, &regs->ctrl2);
> +		priv->write(reg_ctrl2, &regs->ctrl2);
>  
> -		reg_mecr = flexcan_read(&regs->mecr);
> +		reg_mecr = priv->read(&regs->mecr);
>  		reg_mecr &= ~FLEXCAN_MECR_ECRWRDIS;
> -		flexcan_write(reg_mecr, &regs->mecr);
> +		priv->write(reg_mecr, &regs->mecr);
>  		reg_mecr &= ~(FLEXCAN_MECR_NCEFAFRZ | FLEXCAN_MECR_HANCEI_MSK |
>  			      FLEXCAN_MECR_FANCEI_MSK);
> -		flexcan_write(reg_mecr, &regs->mecr);
> +		priv->write(reg_mecr, &regs->mecr);
>  	}
>  
>  	err = flexcan_transceiver_enable(priv); @@ -1035,14 +1046,14 @@ 
> static int flexcan_chip_start(struct net_device *dev)
>  
>  	/* enable interrupts atomically */
>  	disable_irq(dev->irq);
> -	flexcan_write(priv->reg_ctrl_default, &regs->ctrl);
> -	flexcan_write(priv->reg_imask1_default, &regs->imask1);
> -	flexcan_write(priv->reg_imask2_default, &regs->imask2);
> +	priv->write(priv->reg_ctrl_default, &regs->ctrl);
> +	priv->write(priv->reg_imask1_default, &regs->imask1);
> +	priv->write(priv->reg_imask2_default, &regs->imask2);
>  	enable_irq(dev->irq);
>  
>  	/* print chip status */
>  	netdev_dbg(dev, "%s: reading mcr=0x%08x ctrl=0x%08x\n", __func__,
> -		   flexcan_read(&regs->mcr), flexcan_read(&regs->ctrl));
> +		   priv->read(&regs->mcr), priv->read(&regs->ctrl));
>  
>  	return 0;
>  
> @@ -1067,9 +1078,9 @@ static void flexcan_chip_stop(struct net_device *dev)
>  	flexcan_chip_disable(priv);
>  
>  	/* Disable all interrupts */
> -	flexcan_write(0, &regs->imask2);
> -	flexcan_write(0, &regs->imask1);
> -	flexcan_write(priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_ALL,
> +	priv->write(0, &regs->imask2);
> +	priv->write(0, &regs->imask1);
> +	priv->write(priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_ALL,
>  		      &regs->ctrl);
>  
>  	flexcan_transceiver_disable(priv);
> @@ -1185,26 +1196,26 @@ static int register_flexcandev(struct net_device *dev)
>  	err = flexcan_chip_disable(priv);
>  	if (err)
>  		goto out_disable_per;
> -	reg = flexcan_read(&regs->ctrl);
> +	reg = priv->read(&regs->ctrl);
>  	reg |= FLEXCAN_CTRL_CLK_SRC;
> -	flexcan_write(reg, &regs->ctrl);
> +	priv->write(reg, &regs->ctrl);
>  
>  	err = flexcan_chip_enable(priv);
>  	if (err)
>  		goto out_chip_disable;
>  
>  	/* set freeze, halt and activate FIFO, restrict register access */
> -	reg = flexcan_read(&regs->mcr);
> +	reg = priv->read(&regs->mcr);
>  	reg |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT |
>  		FLEXCAN_MCR_FEN | FLEXCAN_MCR_SUPV;
> -	flexcan_write(reg, &regs->mcr);
> +	priv->write(reg, &regs->mcr);
>  
>  	/* Currently we only support newer versions of this core
>  	 * featuring a RX hardware FIFO (although this driver doesn't
>  	 * make use of it on some cores). Older cores, found on some
>  	 * Coldfire derivates are not tested.
>  	 */
> -	reg = flexcan_read(&regs->mcr);
> +	reg = priv->read(&regs->mcr);
>  	if (!(reg & FLEXCAN_MCR_FEN)) {
>  		netdev_err(dev, "Could not enable RX FIFO, unsupported core\n");
>  		err = -ENODEV;
> @@ -1313,6 +1324,15 @@ static int flexcan_probe(struct platform_device *pdev)
>  	dev->flags |= IFF_ECHO;
>  
>  	priv = netdev_priv(dev);
> +
> +	if (of_property_read_bool(pdev->dev.of_node, "big-endian")) {

Don't do this. This is not backwards compatible with the existing PPC boards. Please add all needed information to the devtype_data.

> +		priv->read = flexcan_read_be;
> +		priv->write = flexcan_write_be;
> +	} else {
> +		priv->read = flexcan_read_le;
> +		priv->write = flexcan_write_le;
> +	}
> +
>  	priv->can.clock.freq = clock_freq;
>  	priv->can.bittiming_const = &flexcan_bittiming_const;
>  	priv->can.do_set_mode = flexcan_set_mode;
> 

Marc

-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 1/2] can: flexcan: Remodel FlexCAN register r/w APIs for big endian FlexCAN controllers.
  2017-11-10 11:06   ` Pankaj Bansal
@ 2017-11-10 11:09     ` Marc Kleine-Budde
  2017-11-10 12:35       ` Pankaj Bansal
  0 siblings, 1 reply; 52+ messages in thread
From: Marc Kleine-Budde @ 2017-11-10 11:09 UTC (permalink / raw)
  To: Pankaj Bansal, wg, linux-can
  Cc: Varun Sethi, Poonam Aggrwal, Bhupesh Sharma, Sakar Arora


[-- Attachment #1.1: Type: text/plain, Size: 1343 bytes --]

On 11/10/2017 12:06 PM, Pankaj Bansal wrote:
> Hi Marc,
> 
> Thank you for reviewing my changes.
> 
> 2. Some of the original team members that had contributed to these changes have left the organization. Please suggest on how to give them credit in these patches?

Hmm, ok. Do they have a new email address?

> 3. Regarding backward compatibility with PowerPC, I see that there is only one platform in PowerPC architecture that is using flexcan.
>     There is only one platform in "arch/powerpc/boot/dts/" having flexcan node. p1010si-post.dtsi
>     I have added the big-endian property in that platform and have tested it on P1010 platform after backporting the patch to Freescale SDK 1.4 linux.
>     I have sent the patch for this. See "[PATCH 2/3] powerpc: dts: P1010: Add endianness property to flexcan node"
>     I believe these changes can be accepted for both powerpc and arm and other architectures that use flexcan.

No, this is not acceptable. You break the device tree. Please add the
le, be information to the devtype data.

Marc

-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 52+ messages in thread

* RE: [PATCH 1/2] can: flexcan: Remodel FlexCAN register r/w APIs for big endian FlexCAN controllers.
  2017-11-10 11:09     ` Marc Kleine-Budde
@ 2017-11-10 12:35       ` Pankaj Bansal
       [not found]         ` <AM0PR0402MB394051B0FAADBC45AF71439CF1540-mYCQpYF9suc3mfjNbz3WnI3W/0Ik+aLCnBOFsp37pqbUKgpGm//BTAC/G2K4zDHf@public.gmane.org>
  0 siblings, 1 reply; 52+ messages in thread
From: Pankaj Bansal @ 2017-11-10 12:35 UTC (permalink / raw)
  To: Marc Kleine-Budde, wg, linux-can
  Cc: Varun Sethi, Poonam Aggrwal, Bhupesh Sharma, Sakar Arora

Hi Marc,

>> Hi Marc,
>> 
>> Thank you for reviewing my changes.
>> 
>> 2. Some of the original team members that had contributed to these changes have left the organization. Please suggest on how to give them credit in these patches?
>
>Hmm, ok. Do they have a new email address?
>

I don't know their new email addresses.

>> 3. Regarding backward compatibility with PowerPC, I see that there is only one platform in PowerPC architecture that is using flexcan.
>>     There is only one platform in "arch/powerpc/boot/dts/" having flexcan node. p1010si-post.dtsi
>>     I have added the big-endian property in that platform and have tested it on P1010 platform after backporting the patch to Freescale SDK 1.4 linux.
>>     I have sent the patch for this. See "[PATCH 2/3] powerpc: dts: P1010: Add endianness property to flexcan node"
>>     I believe these changes can be accepted for both powerpc and arm and other architectures that use flexcan.
>
>No, this is not acceptable. You break the device tree. Please add the le, be information to the devtype data.

I don't understand how this breaks device tree? can you please elaborate? This method is already being used in other specifications.
You can refer "Documentation/devicetree/bindings/usb/usb-ehci.txt" or "Documentation/devicetree/bindings/i2c/i2c-mux-reg.txt"
Or "Documentation/devicetree/bindings/regmap/regmap.txt".

In my opinion, keeping this info in devtype data is not good idea. E.g. say two platforms which have same FlexCAN hardware revision, will have same quirks.
BUT these two platforms implement FlexCAN in le and be fashion respectively. With current FlexCAN driver, these two platforms can have same devtype data.
And we need not to change flexcan.c if we want to add support for a second platform. We can just add device tree for that platform (which would be needed anyway),
and it can work. We can mention endianness in device tree.

-----Original Message-----
From: linux-can-owner@vger.kernel.org [mailto:linux-can-owner@vger.kernel.org] On Behalf Of Marc Kleine-Budde
Sent: Friday, November 10, 2017 4:39 PM
To: Pankaj Bansal <pankaj.bansal@nxp.com>; wg@grandegger.com; linux-can@vger.kernel.org
Cc: Varun Sethi <V.Sethi@nxp.com>; Poonam Aggrwal <poonam.aggrwal@nxp.com>; Bhupesh Sharma <bhupesh.sharma@freescale.com>; Sakar Arora <Sakar.Arora@freescale.com>
Subject: Re: [PATCH 1/2] can: flexcan: Remodel FlexCAN register r/w APIs for big endian FlexCAN controllers.

On 11/10/2017 12:06 PM, Pankaj Bansal wrote:
> Hi Marc,
> 
> Thank you for reviewing my changes.
> 
> 2. Some of the original team members that had contributed to these changes have left the organization. Please suggest on how to give them credit in these patches?

Hmm, ok. Do they have a new email address?

> 3. Regarding backward compatibility with PowerPC, I see that there is only one platform in PowerPC architecture that is using flexcan.
>     There is only one platform in "arch/powerpc/boot/dts/" having flexcan node. p1010si-post.dtsi
>     I have added the big-endian property in that platform and have tested it on P1010 platform after backporting the patch to Freescale SDK 1.4 linux.
>     I have sent the patch for this. See "[PATCH 2/3] powerpc: dts: P1010: Add endianness property to flexcan node"
>     I believe these changes can be accepted for both powerpc and arm and other architectures that use flexcan.

No, this is not acceptable. You break the device tree. Please add the le, be information to the devtype data.

Marc

-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 1/2] can: flexcan: Remodel FlexCAN register r/w APIs for big endian FlexCAN controllers.
       [not found]         ` <AM0PR0402MB394051B0FAADBC45AF71439CF1540-mYCQpYF9suc3mfjNbz3WnI3W/0Ik+aLCnBOFsp37pqbUKgpGm//BTAC/G2K4zDHf@public.gmane.org>
@ 2017-11-10 12:49           ` Marc Kleine-Budde
  2017-11-10 16:32             ` Pankaj Bansal
  0 siblings, 1 reply; 52+ messages in thread
From: Marc Kleine-Budde @ 2017-11-10 12:49 UTC (permalink / raw)
  To: Pankaj Bansal, wg-5Yr1BZd7O62+XT7JhA+gdA,
	linux-can-u79uwXL29TY76Z2rM5mHXA
  Cc: Varun Sethi, Poonam Aggrwal, devicetree-u79uwXL29TY76Z2rM5mHXA


[-- Attachment #1.1: Type: text/plain, Size: 2326 bytes --]

On 11/10/2017 01:35 PM, Pankaj Bansal wrote:
>>> 3. Regarding backward compatibility with PowerPC, I see that there is only one platform in PowerPC architecture that is using flexcan.
>>>     There is only one platform in "arch/powerpc/boot/dts/" having flexcan node. p1010si-post.dtsi
>>>     I have added the big-endian property in that platform and have tested it on P1010 platform after backporting the patch to Freescale SDK 1.4 linux.
>>>     I have sent the patch for this. See "[PATCH 2/3] powerpc: dts: P1010: Add endianness property to flexcan node"
>>>     I believe these changes can be accepted for both powerpc and arm and other architectures that use flexcan.
>>
>> No, this is not acceptable. You break the device tree. Please add the le, be information to the devtype data.
> 
> I don't understand how this breaks device tree? can you please elaborate? This method is already being used in other specifications.

Boot a new kernel with an old tree on a PPC board -> flexcan will not work.

See this talk for more information for stable device tree ABI:

https://elinux.org/images/0/0e/OSELAS.Presentation-ELCE2017-DT.pdf
https://www.youtube.com/watch?v=6iguKSJJfxo

> You can refer "Documentation/devicetree/bindings/usb/usb-ehci.txt" or
> "Documentation/devicetree/bindings/i2c/i2c-mux-reg.txt" Or
> "Documentation/devicetree/bindings/regmap/regmap.txt".

> In my opinion, keeping this info in devtype data is not good idea.
> E.g. say two platforms which have same FlexCAN hardware revision,
> will have same quirks. BUT these two platforms implement FlexCAN in
> le and be fashion respectively.

Then it's two different platforms. Simply add another compatible to the
driver.

> With current FlexCAN driver, these two platforms can have same
> devtype data. And we need not to change flexcan.c if we want to add
> support for a second platform. We can just add device tree for that
> platform (which would be needed anyway), and it can work. We can
> mention endianness in device tree.

Marc

-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 52+ messages in thread

* RE: [PATCH 1/2] can: flexcan: Remodel FlexCAN register r/w APIs for big endian FlexCAN controllers.
  2017-11-10 12:49           ` Marc Kleine-Budde
@ 2017-11-10 16:32             ` Pankaj Bansal
       [not found]               ` <AM0PR0402MB3940DE05B2BA456D0FF54498F1540-mYCQpYF9suc3mfjNbz3WnI3W/0Ik+aLCnBOFsp37pqbUKgpGm//BTAC/G2K4zDHf@public.gmane.org>
  0 siblings, 1 reply; 52+ messages in thread
From: Pankaj Bansal @ 2017-11-10 16:32 UTC (permalink / raw)
  To: Marc Kleine-Budde, wg, linux-can; +Cc: Varun Sethi, Poonam Aggrwal, devicetree

Hi Marc,

Thanks for sharing the video and slides. It was really helpful.
But I would still like to solve this problem using device tree property.
My rationale behind it is that, if a platform designer uses same IP block whose support is present is linux kernel, but with different endianness.
Then he would not need to add his platform data in each driver to support his platform in linux.
He can just add endianness property in device tree and can use latest linux kernel right off the bat.
This is also mentioned in "Documentation/devicetree/bindings/regmap/regmap.txt".

Regmap defaults to little-endian register access on MMIO based
devices, this is by far the most common setting. On CPU
architectures that typically run big-endian operating systems
(e.g. PowerPC), registers can be defined as big-endian and must
be marked that way in the devicetree.

This rule was apparently not followed in P1010RDB flexcan node.

To solve this problem, I suggest that we define 2 optional device tree properties for flexcan.
little-endian : for powerpc architecture, if this property is defined then controller is little endian otherwise big endian (default)
big-endian : for other architectures, if this property is defined then controller is big endian otherwise little endian (default)

Although the controller drivers should be architecture independent, but apparently there is no way around it in flexcan.

let me know your thoughts.

Thanks & Regards,
Pankaj Bansal

-----Original Message-----
From: Marc Kleine-Budde [mailto:mkl@pengutronix.de] 
Sent: Friday, November 10, 2017 6:19 PM
To: Pankaj Bansal <pankaj.bansal@nxp.com>; wg@grandegger.com; linux-can@vger.kernel.org
Cc: Varun Sethi <V.Sethi@nxp.com>; Poonam Aggrwal <poonam.aggrwal@nxp.com>; devicetree@vger.kernel.org
Subject: Re: [PATCH 1/2] can: flexcan: Remodel FlexCAN register r/w APIs for big endian FlexCAN controllers.

On 11/10/2017 01:35 PM, Pankaj Bansal wrote:
>>> 3. Regarding backward compatibility with PowerPC, I see that there is only one platform in PowerPC architecture that is using flexcan.
>>>     There is only one platform in "arch/powerpc/boot/dts/" having flexcan node. p1010si-post.dtsi
>>>     I have added the big-endian property in that platform and have tested it on P1010 platform after backporting the patch to Freescale SDK 1.4 linux.
>>>     I have sent the patch for this. See "[PATCH 2/3] powerpc: dts: P1010: Add endianness property to flexcan node"
>>>     I believe these changes can be accepted for both powerpc and arm and other architectures that use flexcan.
>>
>> No, this is not acceptable. You break the device tree. Please add the le, be information to the devtype data.
> 
> I don't understand how this breaks device tree? can you please elaborate? This method is already being used in other specifications.

Boot a new kernel with an old tree on a PPC board -> flexcan will not work.

See this talk for more information for stable device tree ABI:

https://elinux.org/images/0/0e/OSELAS.Presentation-ELCE2017-DT.pdf
https://www.youtube.com/watch?v=6iguKSJJfxo

> You can refer "Documentation/devicetree/bindings/usb/usb-ehci.txt" or 
> "Documentation/devicetree/bindings/i2c/i2c-mux-reg.txt" Or 
> "Documentation/devicetree/bindings/regmap/regmap.txt".

> In my opinion, keeping this info in devtype data is not good idea.
> E.g. say two platforms which have same FlexCAN hardware revision, will 
> have same quirks. BUT these two platforms implement FlexCAN in le and 
> be fashion respectively.

Then it's two different platforms. Simply add another compatible to the driver.

> With current FlexCAN driver, these two platforms can have same devtype 
> data. And we need not to change flexcan.c if we want to add support 
> for a second platform. We can just add device tree for that platform 
> (which would be needed anyway), and it can work. We can mention 
> endianness in device tree.

Marc

-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH 1/2] can: flexcan: Remodel FlexCAN register r/w APIs for big endian FlexCAN controllers.
       [not found]               ` <AM0PR0402MB3940DE05B2BA456D0FF54498F1540-mYCQpYF9suc3mfjNbz3WnI3W/0Ik+aLCnBOFsp37pqbUKgpGm//BTAC/G2K4zDHf@public.gmane.org>
@ 2017-11-13 15:50                 ` Marc Kleine-Budde
  0 siblings, 0 replies; 52+ messages in thread
From: Marc Kleine-Budde @ 2017-11-13 15:50 UTC (permalink / raw)
  To: Pankaj Bansal, wg-5Yr1BZd7O62+XT7JhA+gdA,
	linux-can-u79uwXL29TY76Z2rM5mHXA
  Cc: Varun Sethi, Poonam Aggrwal, devicetree-u79uwXL29TY76Z2rM5mHXA


[-- Attachment #1.1: Type: text/plain, Size: 2323 bytes --]

On 11/10/2017 05:32 PM, Pankaj Bansal wrote:
> Thanks for sharing the video and slides. It was really helpful. But I
> would still like to solve this problem using device tree property. My
> rationale behind it is that, if a platform designer uses same IP
> block whose support is present is linux kernel, but with different
> endianness. Then he would not need to add his platform data in each
> driver to support his platform in linux. He can just add endianness
> property in device tree and can use latest linux kernel right off the
> bat. This is also mentioned in
> "Documentation/devicetree/bindings/regmap/regmap.txt".
> 
> Regmap defaults to little-endian register access on MMIO based
> devices, this is by far the most common setting. On CPU
> architectures that typically run big-endian operating systems
> (e.g. PowerPC), registers can be defined as big-endian and must
> be marked that way in the devicetree.
> 
> This rule was apparently not followed in P1010RDB flexcan node.
> 
> To solve this problem, I suggest that we define 2 optional device
> tree properties for flexcan. little-endian : for powerpc
> architecture, if this property is defined then controller is little
> endian otherwise big endian (default) big-endian : for other
> architectures, if this property is defined then controller is big
> endian otherwise little endian (default)
> 
> Although the controller drivers should be architecture independent,
> but apparently there is no way around it in flexcan.

Please keep the endianess as default es stated in the comment in the driver:

>> /* Abstract off the read/write for arm versus ppc. This
>>  * assumes that PPC uses big-endian registers and everything
>>  * else uses little-endian registers, independent of CPU
>>  * endianness.
>>  */

See description of commit 0e4b949e6620 ("can: flexcan: fix flexcan
driver build for big endian on ARM and little endian on PowerPc") for
more information.

I'll not ACK a change in the driver, that's breaking PPC.

Marc

-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 52+ messages in thread

* [PATCH v2 1/2] can: flexcan: Remodel FlexCAN register r/w APIs for big endian FlexCAN controllers.
  2017-11-10  9:59 [PATCH 1/2] can: flexcan: Remodel FlexCAN register r/w APIs for big endian FlexCAN controllers Pankaj Bansal
                   ` (2 preceding siblings ...)
  2017-11-10 10:48 ` Marc Kleine-Budde
@ 2017-11-14 11:56 ` Pankaj Bansal
  2017-11-14 11:56   ` [PATCH v2 2/2] can: flexcan: adding platform specific details for LS1021A Pankaj Bansal
                     ` (2 more replies)
  3 siblings, 3 replies; 52+ messages in thread
From: Pankaj Bansal @ 2017-11-14 11:56 UTC (permalink / raw)
  To: wg, mkl, linux-can
  Cc: V.Sethi, poonam.aggrwal, Pankaj Bansal, Bhupesh Sharma, Sakar Arora

The FlexCAN driver assumed that FlexCAN controller is big endian for
powerpc architecture and little endian for other architectures.

But this may not be the case. FlexCAN controller can be little or big
endian on any architecture. For e.g. NXP LS1021A ARM based SOC has big
endian FlexCAN controller.

Therefore, the driver has been modified to add a provision for both
types of controllers using an additional device tree property. Big
Endian controllers should have "big-endian" set in the device tree.

This is the standard practice followed in linux. for more info check:
Documentation/devicetree/bindings/common-properties.txt

Signed-off-by: Pankaj Bansal <pankaj.bansal@nxp.com>
Signed-off-by: Bhupesh Sharma <bhupesh.sharma@freescale.com>
Signed-off-by: Sakar Arora <Sakar.Arora@freescale.com>
Reviewed-by: Zhengxiong Jin <Jason.Jin@freescale.com>
Reviewed-by: Poonam Aggrwal <poonam.aggrwal@nxp.com>
---
Changes in v2:
  - Modified patch deciption to include common-properties.txt reference.
  - Reorder the LE/BE read/write APIs for better readability of code
  - Added an exception to force BE API selection, for powerpc based platform
    P1010. This ensures that new linux kernel works with old P1010
    device-tree, while future powerpc platforms that use big endian
    FlexCAN controller need to specify big-endian in device tree in
    FlexCAN node.
  - Tested on P1010 after backporting to freescale sdk 1.4 linux, without
    any change in device-tree.
  - Tested on NXP LS1021A arm based platform.

 drivers/net/can/flexcan.c | 230 ++++++++++++++++++++----------------
 1 file changed, 128 insertions(+), 102 deletions(-)

diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
index a13a489..100b451 100644
--- a/drivers/net/can/flexcan.c
+++ b/drivers/net/can/flexcan.c
@@ -279,6 +279,10 @@ struct flexcan_priv {
 	struct clk *clk_per;
 	const struct flexcan_devtype_data *devtype_data;
 	struct regulator *reg_xceiver;
+
+	/* Read and Write APIs */
+	u32 (*read)(void __iomem *addr);
+	void (*write)(u32 val, void __iomem *addr);
 };
 
 static const struct flexcan_devtype_data fsl_p1010_devtype_data = {
@@ -312,39 +316,45 @@ static const struct can_bittiming_const flexcan_bittiming_const = {
 	.brp_inc = 1,
 };
 
-/* Abstract off the read/write for arm versus ppc. This
- * assumes that PPC uses big-endian registers and everything
- * else uses little-endian registers, independent of CPU
- * endianness.
+/* FlexCAN module is essentially modelled as a little-endian IP in most
+ * SoCs, i.e the registers as well as the message buffer areas are
+ * implemented in a little-endian fashion.
+ *
+ * However there are some SoCs (e.g. LS1021A) which implement the FlexCAN
+ * module in a big-endian fashion (i.e the registers as well as the
+ * message buffer areas are implemented in a big-endian way).
+ *
+ * In addition, the FlexCAN module can be found on SoCs having ARM or
+ * PPC cores. So, we need to abstract off the register read/write
+ * functions, ensuring that these cater to all the combinations of module
+ * endianness and underlying CPU endianness.
  */
-#if defined(CONFIG_PPC)
-static inline u32 flexcan_read(void __iomem *addr)
+static inline u32 flexcan_read_be(void __iomem *addr)
 {
-	return in_be32(addr);
+	return ioread32be(addr);
 }
 
-static inline void flexcan_write(u32 val, void __iomem *addr)
+static inline void flexcan_write_be(u32 val, void __iomem *addr)
 {
-	out_be32(addr, val);
+	iowrite32be(val, addr);
 }
-#else
-static inline u32 flexcan_read(void __iomem *addr)
+
+static inline u32 flexcan_read_le(void __iomem *addr)
 {
-	return readl(addr);
+	return ioread32(addr);
 }
 
-static inline void flexcan_write(u32 val, void __iomem *addr)
+static inline void flexcan_write_le(u32 val, void __iomem *addr)
 {
-	writel(val, addr);
+	iowrite32(val, addr);
 }
-#endif
 
 static inline void flexcan_error_irq_enable(const struct flexcan_priv *priv)
 {
 	struct flexcan_regs __iomem *regs = priv->regs;
 	u32 reg_ctrl = (priv->reg_ctrl_default | FLEXCAN_CTRL_ERR_MSK);
 
-	flexcan_write(reg_ctrl, &regs->ctrl);
+	priv->write(reg_ctrl, &regs->ctrl);
 }
 
 static inline void flexcan_error_irq_disable(const struct flexcan_priv *priv)
@@ -352,7 +362,7 @@ static inline void flexcan_error_irq_disable(const struct flexcan_priv *priv)
 	struct flexcan_regs __iomem *regs = priv->regs;
 	u32 reg_ctrl = (priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_MSK);
 
-	flexcan_write(reg_ctrl, &regs->ctrl);
+	priv->write(reg_ctrl, &regs->ctrl);
 }
 
 static inline int flexcan_transceiver_enable(const struct flexcan_priv *priv)
@@ -377,14 +387,14 @@ static int flexcan_chip_enable(struct flexcan_priv *priv)
 	unsigned int timeout = FLEXCAN_TIMEOUT_US / 10;
 	u32 reg;
 
-	reg = flexcan_read(&regs->mcr);
+	reg = priv->read(&regs->mcr);
 	reg &= ~FLEXCAN_MCR_MDIS;
-	flexcan_write(reg, &regs->mcr);
+	priv->write(reg, &regs->mcr);
 
-	while (timeout-- && (flexcan_read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK))
+	while (timeout-- && (priv->read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK))
 		udelay(10);
 
-	if (flexcan_read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK)
+	if (priv->read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK)
 		return -ETIMEDOUT;
 
 	return 0;
@@ -396,14 +406,14 @@ static int flexcan_chip_disable(struct flexcan_priv *priv)
 	unsigned int timeout = FLEXCAN_TIMEOUT_US / 10;
 	u32 reg;
 
-	reg = flexcan_read(&regs->mcr);
+	reg = priv->read(&regs->mcr);
 	reg |= FLEXCAN_MCR_MDIS;
-	flexcan_write(reg, &regs->mcr);
+	priv->write(reg, &regs->mcr);
 
-	while (timeout-- && !(flexcan_read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK))
+	while (timeout-- && !(priv->read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK))
 		udelay(10);
 
-	if (!(flexcan_read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK))
+	if (!(priv->read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK))
 		return -ETIMEDOUT;
 
 	return 0;
@@ -415,14 +425,14 @@ static int flexcan_chip_freeze(struct flexcan_priv *priv)
 	unsigned int timeout = 1000 * 1000 * 10 / priv->can.bittiming.bitrate;
 	u32 reg;
 
-	reg = flexcan_read(&regs->mcr);
+	reg = priv->read(&regs->mcr);
 	reg |= FLEXCAN_MCR_HALT;
-	flexcan_write(reg, &regs->mcr);
+	priv->write(reg, &regs->mcr);
 
-	while (timeout-- && !(flexcan_read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK))
+	while (timeout-- && !(priv->read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK))
 		udelay(100);
 
-	if (!(flexcan_read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK))
+	if (!(priv->read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK))
 		return -ETIMEDOUT;
 
 	return 0;
@@ -434,14 +444,14 @@ static int flexcan_chip_unfreeze(struct flexcan_priv *priv)
 	unsigned int timeout = FLEXCAN_TIMEOUT_US / 10;
 	u32 reg;
 
-	reg = flexcan_read(&regs->mcr);
+	reg = priv->read(&regs->mcr);
 	reg &= ~FLEXCAN_MCR_HALT;
-	flexcan_write(reg, &regs->mcr);
+	priv->write(reg, &regs->mcr);
 
-	while (timeout-- && (flexcan_read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK))
+	while (timeout-- && (priv->read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK))
 		udelay(10);
 
-	if (flexcan_read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK)
+	if (priv->read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK)
 		return -ETIMEDOUT;
 
 	return 0;
@@ -452,11 +462,11 @@ static int flexcan_chip_softreset(struct flexcan_priv *priv)
 	struct flexcan_regs __iomem *regs = priv->regs;
 	unsigned int timeout = FLEXCAN_TIMEOUT_US / 10;
 
-	flexcan_write(FLEXCAN_MCR_SOFTRST, &regs->mcr);
-	while (timeout-- && (flexcan_read(&regs->mcr) & FLEXCAN_MCR_SOFTRST))
+	priv->write(FLEXCAN_MCR_SOFTRST, &regs->mcr);
+	while (timeout-- && (priv->read(&regs->mcr) & FLEXCAN_MCR_SOFTRST))
 		udelay(10);
 
-	if (flexcan_read(&regs->mcr) & FLEXCAN_MCR_SOFTRST)
+	if (priv->read(&regs->mcr) & FLEXCAN_MCR_SOFTRST)
 		return -ETIMEDOUT;
 
 	return 0;
@@ -467,7 +477,7 @@ static int __flexcan_get_berr_counter(const struct net_device *dev,
 {
 	const struct flexcan_priv *priv = netdev_priv(dev);
 	struct flexcan_regs __iomem *regs = priv->regs;
-	u32 reg = flexcan_read(&regs->ecr);
+	u32 reg = priv->read(&regs->ecr);
 
 	bec->txerr = (reg >> 0) & 0xff;
 	bec->rxerr = (reg >> 8) & 0xff;
@@ -523,24 +533,24 @@ static int flexcan_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	if (cf->can_dlc > 0) {
 		data = be32_to_cpup((__be32 *)&cf->data[0]);
-		flexcan_write(data, &priv->tx_mb->data[0]);
+		priv->write(data, &priv->tx_mb->data[0]);
 	}
 	if (cf->can_dlc > 3) {
 		data = be32_to_cpup((__be32 *)&cf->data[4]);
-		flexcan_write(data, &priv->tx_mb->data[1]);
+		priv->write(data, &priv->tx_mb->data[1]);
 	}
 
 	can_put_echo_skb(skb, dev, 0);
 
-	flexcan_write(can_id, &priv->tx_mb->can_id);
-	flexcan_write(ctrl, &priv->tx_mb->can_ctrl);
+	priv->write(can_id, &priv->tx_mb->can_id);
+	priv->write(ctrl, &priv->tx_mb->can_ctrl);
 
 	/* Errata ERR005829 step8:
 	 * Write twice INACTIVE(0x8) code to first MB.
 	 */
-	flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE,
+	priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
 		      &priv->tx_mb_reserved->can_ctrl);
-	flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE,
+	priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
 		      &priv->tx_mb_reserved->can_ctrl);
 
 	return NETDEV_TX_OK;
@@ -659,7 +669,7 @@ static unsigned int flexcan_mailbox_read(struct can_rx_offload *offload,
 		u32 code;
 
 		do {
-			reg_ctrl = flexcan_read(&mb->can_ctrl);
+			reg_ctrl = priv->read(&mb->can_ctrl);
 		} while (reg_ctrl & FLEXCAN_MB_CODE_RX_BUSY_BIT);
 
 		/* is this MB empty? */
@@ -674,17 +684,17 @@ static unsigned int flexcan_mailbox_read(struct can_rx_offload *offload,
 			offload->dev->stats.rx_errors++;
 		}
 	} else {
-		reg_iflag1 = flexcan_read(&regs->iflag1);
+		reg_iflag1 = priv->read(&regs->iflag1);
 		if (!(reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_AVAILABLE))
 			return 0;
 
-		reg_ctrl = flexcan_read(&mb->can_ctrl);
+		reg_ctrl = priv->read(&mb->can_ctrl);
 	}
 
 	/* increase timstamp to full 32 bit */
 	*timestamp = reg_ctrl << 16;
 
-	reg_id = flexcan_read(&mb->can_id);
+	reg_id = priv->read(&mb->can_id);
 	if (reg_ctrl & FLEXCAN_MB_CNT_IDE)
 		cf->can_id = ((reg_id >> 0) & CAN_EFF_MASK) | CAN_EFF_FLAG;
 	else
@@ -694,19 +704,19 @@ static unsigned int flexcan_mailbox_read(struct can_rx_offload *offload,
 		cf->can_id |= CAN_RTR_FLAG;
 	cf->can_dlc = get_can_dlc((reg_ctrl >> 16) & 0xf);
 
-	*(__be32 *)(cf->data + 0) = cpu_to_be32(flexcan_read(&mb->data[0]));
-	*(__be32 *)(cf->data + 4) = cpu_to_be32(flexcan_read(&mb->data[1]));
+	*(__be32 *)(cf->data + 0) = cpu_to_be32(priv->read(&mb->data[0]));
+	*(__be32 *)(cf->data + 4) = cpu_to_be32(priv->read(&mb->data[1]));
 
 	/* mark as read */
 	if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) {
 		/* Clear IRQ */
 		if (n < 32)
-			flexcan_write(BIT(n), &regs->iflag1);
+			priv->write(BIT(n), &regs->iflag1);
 		else
-			flexcan_write(BIT(n - 32), &regs->iflag2);
+			priv->write(BIT(n - 32), &regs->iflag2);
 	} else {
-		flexcan_write(FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, &regs->iflag1);
-		flexcan_read(&regs->timer);
+		priv->write(FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, &regs->iflag1);
+		priv->read(&regs->timer);
 	}
 
 	return 1;
@@ -718,8 +728,8 @@ static inline u64 flexcan_read_reg_iflag_rx(struct flexcan_priv *priv)
 	struct flexcan_regs __iomem *regs = priv->regs;
 	u32 iflag1, iflag2;
 
-	iflag2 = flexcan_read(&regs->iflag2) & priv->reg_imask2_default;
-	iflag1 = flexcan_read(&regs->iflag1) & priv->reg_imask1_default &
+	iflag2 = priv->read(&regs->iflag2) & priv->reg_imask2_default;
+	iflag1 = priv->read(&regs->iflag1) & priv->reg_imask1_default &
 		~FLEXCAN_IFLAG_MB(priv->tx_mb_idx);
 
 	return (u64)iflag2 << 32 | iflag1;
@@ -735,7 +745,7 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
 	u32 reg_iflag1, reg_esr;
 	enum can_state last_state = priv->can.state;
 
-	reg_iflag1 = flexcan_read(&regs->iflag1);
+	reg_iflag1 = priv->read(&regs->iflag1);
 
 	/* reception interrupt */
 	if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) {
@@ -758,7 +768,8 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
 		/* FIFO overflow interrupt */
 		if (reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_OVERFLOW) {
 			handled = IRQ_HANDLED;
-			flexcan_write(FLEXCAN_IFLAG_RX_FIFO_OVERFLOW, &regs->iflag1);
+			priv->write(FLEXCAN_IFLAG_RX_FIFO_OVERFLOW,
+				    &regs->iflag1);
 			dev->stats.rx_over_errors++;
 			dev->stats.rx_errors++;
 		}
@@ -772,18 +783,18 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
 		can_led_event(dev, CAN_LED_EVENT_TX);
 
 		/* after sending a RTR frame MB is in RX mode */
-		flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE,
-			      &priv->tx_mb->can_ctrl);
-		flexcan_write(FLEXCAN_IFLAG_MB(priv->tx_mb_idx), &regs->iflag1);
+		priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
+			    &priv->tx_mb->can_ctrl);
+		priv->write(FLEXCAN_IFLAG_MB(priv->tx_mb_idx), &regs->iflag1);
 		netif_wake_queue(dev);
 	}
 
-	reg_esr = flexcan_read(&regs->esr);
+	reg_esr = priv->read(&regs->esr);
 
 	/* ACK all bus error and state change IRQ sources */
 	if (reg_esr & FLEXCAN_ESR_ALL_INT) {
 		handled = IRQ_HANDLED;
-		flexcan_write(reg_esr & FLEXCAN_ESR_ALL_INT, &regs->esr);
+		priv->write(reg_esr & FLEXCAN_ESR_ALL_INT, &regs->esr);
 	}
 
 	/* state change interrupt or broken error state quirk fix is enabled */
@@ -845,7 +856,7 @@ static void flexcan_set_bittiming(struct net_device *dev)
 	struct flexcan_regs __iomem *regs = priv->regs;
 	u32 reg;
 
-	reg = flexcan_read(&regs->ctrl);
+	reg = priv->read(&regs->ctrl);
 	reg &= ~(FLEXCAN_CTRL_PRESDIV(0xff) |
 		 FLEXCAN_CTRL_RJW(0x3) |
 		 FLEXCAN_CTRL_PSEG1(0x7) |
@@ -869,11 +880,11 @@ static void flexcan_set_bittiming(struct net_device *dev)
 		reg |= FLEXCAN_CTRL_SMP;
 
 	netdev_dbg(dev, "writing ctrl=0x%08x\n", reg);
-	flexcan_write(reg, &regs->ctrl);
+	priv->write(reg, &regs->ctrl);
 
 	/* print chip status */
 	netdev_dbg(dev, "%s: mcr=0x%08x ctrl=0x%08x\n", __func__,
-		   flexcan_read(&regs->mcr), flexcan_read(&regs->ctrl));
+		   priv->read(&regs->mcr), priv->read(&regs->ctrl));
 }
 
 /* flexcan_chip_start
@@ -912,7 +923,7 @@ static int flexcan_chip_start(struct net_device *dev)
 	 * choose format C
 	 * set max mailbox number
 	 */
-	reg_mcr = flexcan_read(&regs->mcr);
+	reg_mcr = priv->read(&regs->mcr);
 	reg_mcr &= ~FLEXCAN_MCR_MAXMB(0xff);
 	reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT | FLEXCAN_MCR_SUPV |
 		FLEXCAN_MCR_WRN_EN | FLEXCAN_MCR_SRX_DIS | FLEXCAN_MCR_IRMQ |
@@ -926,7 +937,7 @@ static int flexcan_chip_start(struct net_device *dev)
 			FLEXCAN_MCR_MAXMB(priv->tx_mb_idx);
 	}
 	netdev_dbg(dev, "%s: writing mcr=0x%08x", __func__, reg_mcr);
-	flexcan_write(reg_mcr, &regs->mcr);
+	priv->write(reg_mcr, &regs->mcr);
 
 	/* CTRL
 	 *
@@ -939,7 +950,7 @@ static int flexcan_chip_start(struct net_device *dev)
 	 * enable bus off interrupt
 	 * (== FLEXCAN_CTRL_ERR_STATE)
 	 */
-	reg_ctrl = flexcan_read(&regs->ctrl);
+	reg_ctrl = priv->read(&regs->ctrl);
 	reg_ctrl &= ~FLEXCAN_CTRL_TSYN;
 	reg_ctrl |= FLEXCAN_CTRL_BOFF_REC | FLEXCAN_CTRL_LBUF |
 		FLEXCAN_CTRL_ERR_STATE;
@@ -959,45 +970,45 @@ static int flexcan_chip_start(struct net_device *dev)
 	/* leave interrupts disabled for now */
 	reg_ctrl &= ~FLEXCAN_CTRL_ERR_ALL;
 	netdev_dbg(dev, "%s: writing ctrl=0x%08x", __func__, reg_ctrl);
-	flexcan_write(reg_ctrl, &regs->ctrl);
+	priv->write(reg_ctrl, &regs->ctrl);
 
 	if ((priv->devtype_data->quirks & FLEXCAN_QUIRK_ENABLE_EACEN_RRS)) {
-		reg_ctrl2 = flexcan_read(&regs->ctrl2);
+		reg_ctrl2 = priv->read(&regs->ctrl2);
 		reg_ctrl2 |= FLEXCAN_CTRL2_EACEN | FLEXCAN_CTRL2_RRS;
-		flexcan_write(reg_ctrl2, &regs->ctrl2);
+		priv->write(reg_ctrl2, &regs->ctrl2);
 	}
 
 	/* clear and invalidate all mailboxes first */
 	for (i = priv->tx_mb_idx; i < ARRAY_SIZE(regs->mb); i++) {
-		flexcan_write(FLEXCAN_MB_CODE_RX_INACTIVE,
-			      &regs->mb[i].can_ctrl);
+		priv->write(FLEXCAN_MB_CODE_RX_INACTIVE,
+			    &regs->mb[i].can_ctrl);
 	}
 
 	if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) {
 		for (i = priv->offload.mb_first; i <= priv->offload.mb_last; i++)
-			flexcan_write(FLEXCAN_MB_CODE_RX_EMPTY,
-				      &regs->mb[i].can_ctrl);
+			priv->write(FLEXCAN_MB_CODE_RX_EMPTY,
+				    &regs->mb[i].can_ctrl);
 	}
 
 	/* Errata ERR005829: mark first TX mailbox as INACTIVE */
-	flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE,
-		      &priv->tx_mb_reserved->can_ctrl);
+	priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
+		    &priv->tx_mb_reserved->can_ctrl);
 
 	/* mark TX mailbox as INACTIVE */
-	flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE,
-		      &priv->tx_mb->can_ctrl);
+	priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
+		    &priv->tx_mb->can_ctrl);
 
 	/* acceptance mask/acceptance code (accept everything) */
-	flexcan_write(0x0, &regs->rxgmask);
-	flexcan_write(0x0, &regs->rx14mask);
-	flexcan_write(0x0, &regs->rx15mask);
+	priv->write(0x0, &regs->rxgmask);
+	priv->write(0x0, &regs->rx14mask);
+	priv->write(0x0, &regs->rx15mask);
 
 	if (priv->devtype_data->quirks & FLEXCAN_QUIRK_DISABLE_RXFG)
-		flexcan_write(0x0, &regs->rxfgmask);
+		priv->write(0x0, &regs->rxfgmask);
 
 	/* clear acceptance filters */
 	for (i = 0; i < ARRAY_SIZE(regs->mb); i++)
-		flexcan_write(0, &regs->rximr[i]);
+		priv->write(0, &regs->rximr[i]);
 
 	/* On Vybrid, disable memory error detection interrupts
 	 * and freeze mode.
@@ -1010,16 +1021,16 @@ static int flexcan_chip_start(struct net_device *dev)
 		 * and Correction of Memory Errors" to write to
 		 * MECR register
 		 */
-		reg_ctrl2 = flexcan_read(&regs->ctrl2);
+		reg_ctrl2 = priv->read(&regs->ctrl2);
 		reg_ctrl2 |= FLEXCAN_CTRL2_ECRWRE;
-		flexcan_write(reg_ctrl2, &regs->ctrl2);
+		priv->write(reg_ctrl2, &regs->ctrl2);
 
-		reg_mecr = flexcan_read(&regs->mecr);
+		reg_mecr = priv->read(&regs->mecr);
 		reg_mecr &= ~FLEXCAN_MECR_ECRWRDIS;
-		flexcan_write(reg_mecr, &regs->mecr);
+		priv->write(reg_mecr, &regs->mecr);
 		reg_mecr &= ~(FLEXCAN_MECR_NCEFAFRZ | FLEXCAN_MECR_HANCEI_MSK |
 			      FLEXCAN_MECR_FANCEI_MSK);
-		flexcan_write(reg_mecr, &regs->mecr);
+		priv->write(reg_mecr, &regs->mecr);
 	}
 
 	err = flexcan_transceiver_enable(priv);
@@ -1035,14 +1046,14 @@ static int flexcan_chip_start(struct net_device *dev)
 
 	/* enable interrupts atomically */
 	disable_irq(dev->irq);
-	flexcan_write(priv->reg_ctrl_default, &regs->ctrl);
-	flexcan_write(priv->reg_imask1_default, &regs->imask1);
-	flexcan_write(priv->reg_imask2_default, &regs->imask2);
+	priv->write(priv->reg_ctrl_default, &regs->ctrl);
+	priv->write(priv->reg_imask1_default, &regs->imask1);
+	priv->write(priv->reg_imask2_default, &regs->imask2);
 	enable_irq(dev->irq);
 
 	/* print chip status */
 	netdev_dbg(dev, "%s: reading mcr=0x%08x ctrl=0x%08x\n", __func__,
-		   flexcan_read(&regs->mcr), flexcan_read(&regs->ctrl));
+		   priv->read(&regs->mcr), priv->read(&regs->ctrl));
 
 	return 0;
 
@@ -1067,10 +1078,10 @@ static void flexcan_chip_stop(struct net_device *dev)
 	flexcan_chip_disable(priv);
 
 	/* Disable all interrupts */
-	flexcan_write(0, &regs->imask2);
-	flexcan_write(0, &regs->imask1);
-	flexcan_write(priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_ALL,
-		      &regs->ctrl);
+	priv->write(0, &regs->imask2);
+	priv->write(0, &regs->imask1);
+	priv->write(priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_ALL,
+		    &regs->ctrl);
 
 	flexcan_transceiver_disable(priv);
 	priv->can.state = CAN_STATE_STOPPED;
@@ -1185,26 +1196,26 @@ static int register_flexcandev(struct net_device *dev)
 	err = flexcan_chip_disable(priv);
 	if (err)
 		goto out_disable_per;
-	reg = flexcan_read(&regs->ctrl);
+	reg = priv->read(&regs->ctrl);
 	reg |= FLEXCAN_CTRL_CLK_SRC;
-	flexcan_write(reg, &regs->ctrl);
+	priv->write(reg, &regs->ctrl);
 
 	err = flexcan_chip_enable(priv);
 	if (err)
 		goto out_chip_disable;
 
 	/* set freeze, halt and activate FIFO, restrict register access */
-	reg = flexcan_read(&regs->mcr);
+	reg = priv->read(&regs->mcr);
 	reg |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT |
 		FLEXCAN_MCR_FEN | FLEXCAN_MCR_SUPV;
-	flexcan_write(reg, &regs->mcr);
+	priv->write(reg, &regs->mcr);
 
 	/* Currently we only support newer versions of this core
 	 * featuring a RX hardware FIFO (although this driver doesn't
 	 * make use of it on some cores). Older cores, found on some
 	 * Coldfire derivates are not tested.
 	 */
-	reg = flexcan_read(&regs->mcr);
+	reg = priv->read(&regs->mcr);
 	if (!(reg & FLEXCAN_MCR_FEN)) {
 		netdev_err(dev, "Could not enable RX FIFO, unsupported core\n");
 		err = -ENODEV;
@@ -1313,6 +1324,21 @@ static int flexcan_probe(struct platform_device *pdev)
 	dev->flags |= IFF_ECHO;
 
 	priv = netdev_priv(dev);
+
+	if (of_property_read_bool(pdev->dev.of_node, "big-endian")) {
+		priv->read = flexcan_read_be;
+		priv->write = flexcan_write_be;
+	} else {
+		if (of_device_is_compatible(pdev->dev.of_node,
+					    "fsl,p1010-flexcan")) {
+			priv->read = flexcan_read_be;
+			priv->write = flexcan_write_be;
+		} else {
+			priv->read = flexcan_read_le;
+			priv->write = flexcan_write_le;
+		}
+	}
+
 	priv->can.clock.freq = clock_freq;
 	priv->can.bittiming_const = &flexcan_bittiming_const;
 	priv->can.do_set_mode = flexcan_set_mode;
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH v2 2/2] can: flexcan: adding platform specific details for LS1021A
  2017-11-14 11:56 ` [PATCH v2 " Pankaj Bansal
@ 2017-11-14 11:56   ` Pankaj Bansal
  2017-11-14 12:59     ` Marc Kleine-Budde
  2017-11-14 15:24   ` [PATCH v2 1/2] can: flexcan: Remodel FlexCAN register r/w APIs for big endian FlexCAN controllers Marc Kleine-Budde
  2017-11-23  9:09   ` [PATCH v3 " Pankaj Bansal
  2 siblings, 1 reply; 52+ messages in thread
From: Pankaj Bansal @ 2017-11-14 11:56 UTC (permalink / raw)
  To: wg, mkl, linux-can; +Cc: V.Sethi, poonam.aggrwal, Pankaj Bansal, Bhupesh Sharma

This patch adds platform specific details for NXP SOC LS1021A to the
flexcan driver code.

Signed-off-by: Pankaj Bansal <pankaj.bansal@nxp.com>
Signed-off-by: Bhupesh Sharma <bhupesh.sharma@freescale.com>
Reviewed-by: Zhengxiong Jin <Jason.Jin@freescale.com>
Reviewed-by: Poonam Aggrwal <poonam.aggrwal@nxp.com>
---
Changes in v2:
  - No change.

 drivers/net/can/flexcan.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
index 100b451..fa2d4c9 100644
--- a/drivers/net/can/flexcan.c
+++ b/drivers/net/can/flexcan.c
@@ -304,6 +304,11 @@ static const struct flexcan_devtype_data fsl_vf610_devtype_data = {
 		FLEXCAN_QUIRK_DISABLE_MECR | FLEXCAN_QUIRK_USE_OFF_TIMESTAMP,
 };
 
+/* LS1021A-Rev2 has functional RX-FIFO mode  */
+static const struct flexcan_devtype_data fsl_ls1021a_r2_devtype_data = {
+	.quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_DISABLE_MECR,
+};
+
 static const struct can_bittiming_const flexcan_bittiming_const = {
 	.name = DRV_NAME,
 	.tseg1_min = 4,
@@ -1245,6 +1250,8 @@ static const struct of_device_id flexcan_of_match[] = {
 	{ .compatible = "fsl,imx28-flexcan", .data = &fsl_imx28_devtype_data, },
 	{ .compatible = "fsl,p1010-flexcan", .data = &fsl_p1010_devtype_data, },
 	{ .compatible = "fsl,vf610-flexcan", .data = &fsl_vf610_devtype_data, },
+	{ .compatible = "fsl,ls1021ar2-flexcan",
+	  .data = &fsl_ls1021a_r2_devtype_data, },
 	{ /* sentinel */ },
 };
 MODULE_DEVICE_TABLE(of, flexcan_of_match);
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 52+ messages in thread

* Re: [PATCH v2 2/2] can: flexcan: adding platform specific details for LS1021A
  2017-11-14 11:56   ` [PATCH v2 2/2] can: flexcan: adding platform specific details for LS1021A Pankaj Bansal
@ 2017-11-14 12:59     ` Marc Kleine-Budde
  2017-11-16  5:34       ` Pankaj Bansal
  0 siblings, 1 reply; 52+ messages in thread
From: Marc Kleine-Budde @ 2017-11-14 12:59 UTC (permalink / raw)
  To: Pankaj Bansal, wg, linux-can; +Cc: V.Sethi, poonam.aggrwal, Bhupesh Sharma


[-- Attachment #1.1: Type: text/plain, Size: 2706 bytes --]

On 11/14/2017 12:56 PM, Pankaj Bansal wrote:
> This patch adds platform specific details for NXP SOC LS1021A to the
> flexcan driver code.
> 
> Signed-off-by: Pankaj Bansal <pankaj.bansal@nxp.com>
> Signed-off-by: Bhupesh Sharma <bhupesh.sharma@freescale.com>
> Reviewed-by: Zhengxiong Jin <Jason.Jin@freescale.com>
> Reviewed-by: Poonam Aggrwal <poonam.aggrwal@nxp.com>
> ---
> Changes in v2:
>   - No change.
> 
>  drivers/net/can/flexcan.c | 7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
> index 100b451..fa2d4c9 100644
> --- a/drivers/net/can/flexcan.c
> +++ b/drivers/net/can/flexcan.c
> @@ -304,6 +304,11 @@ static const struct flexcan_devtype_data fsl_vf610_devtype_data = {
>  		FLEXCAN_QUIRK_DISABLE_MECR | FLEXCAN_QUIRK_USE_OFF_TIMESTAMP,
>  };
>  
> +/* LS1021A-Rev2 has functional RX-FIFO mode  */

How big is the RX-FIFO? If the normal mailboxes can receive RTR
messages, we definitely want to use FLEXCAN_QUIRK_USE_OFF_TIMESTAMP. As
you can buffer > 60 CAN frames compared to only 6 in FIFO mode.

Please add your IP core to the "FLEXCAN hardware feature flags" table
[1] in the driver. Also please test the transition interrupts for
changes in the CAN error state, see the commits of ZHU Yi
(ST-FIR/ENG1-Zhu) <Yi.Zhu5@cn.bosch.com> on the driver. [2]

> +static const struct flexcan_devtype_data fsl_ls1021a_r2_devtype_data = {
> +	.quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_DISABLE_MECR,
> +};
> +
>  static const struct can_bittiming_const flexcan_bittiming_const = {
>  	.name = DRV_NAME,
>  	.tseg1_min = 4,
> @@ -1245,6 +1250,8 @@ static const struct of_device_id flexcan_of_match[] = {
>  	{ .compatible = "fsl,imx28-flexcan", .data = &fsl_imx28_devtype_data, },
>  	{ .compatible = "fsl,p1010-flexcan", .data = &fsl_p1010_devtype_data, },
>  	{ .compatible = "fsl,vf610-flexcan", .data = &fsl_vf610_devtype_data, },
> +	{ .compatible = "fsl,ls1021ar2-flexcan",
> +	  .data = &fsl_ls1021a_r2_devtype_data, },

Please keep in in one line, even if it's more than 80 chars.

>  	{ /* sentinel */ },
>  };
>  MODULE_DEVICE_TABLE(of, flexcan_of_match);
> 

Marc

[1]
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/net/can/flexcan.c#n182
[2]
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/log/drivers/net/can/flexcan.c

-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH v2 1/2] can: flexcan: Remodel FlexCAN register r/w APIs for big endian FlexCAN controllers.
  2017-11-14 11:56 ` [PATCH v2 " Pankaj Bansal
  2017-11-14 11:56   ` [PATCH v2 2/2] can: flexcan: adding platform specific details for LS1021A Pankaj Bansal
@ 2017-11-14 15:24   ` Marc Kleine-Budde
  2017-11-16  5:24     ` Pankaj Bansal
  2017-11-21 12:18     ` Pankaj Bansal
  2017-11-23  9:09   ` [PATCH v3 " Pankaj Bansal
  2 siblings, 2 replies; 52+ messages in thread
From: Marc Kleine-Budde @ 2017-11-14 15:24 UTC (permalink / raw)
  To: Pankaj Bansal, wg, linux-can
  Cc: V.Sethi, poonam.aggrwal, Bhupesh Sharma, Sakar Arora


[-- Attachment #1.1: Type: text/plain, Size: 24012 bytes --]

On 11/14/2017 12:56 PM, Pankaj Bansal wrote:
> The FlexCAN driver assumed that FlexCAN controller is big endian for
> powerpc architecture and little endian for other architectures.
> 
> But this may not be the case. FlexCAN controller can be little or big
> endian on any architecture. For e.g. NXP LS1021A ARM based SOC has big
> endian FlexCAN controller.
> 
> Therefore, the driver has been modified to add a provision for both
> types of controllers using an additional device tree property. Big
> Endian controllers should have "big-endian" set in the device tree.
> 
> This is the standard practice followed in linux. for more info check:
> Documentation/devicetree/bindings/common-properties.txt

Looks better now. Please add note to
"Documentation/devicetree/bindings/net/can/fsl-flexcan.txt" that we now
support endianess and state the default endianess.

What about:

On a "fsl,p1010-flexcan" device BE is default, on all other devices LE is.

Please remove the existing "fsl,p1010-flexcan" from "arch/arm/boot/dts"
and add fsl,imx25-flexcan, fsl,imx35-flexcan and fsl,imx53-flexcan
support to the driver.

I'm not sure what happens with non DT arm boards. There's still a user
in tree:

arch/arm/mach-imx/mach-pcm043.c:388:	imx35_add_flexcan1();

> Signed-off-by: Pankaj Bansal <pankaj.bansal@nxp.com>
> Signed-off-by: Bhupesh Sharma <bhupesh.sharma@freescale.com>
> Signed-off-by: Sakar Arora <Sakar.Arora@freescale.com>
> Reviewed-by: Zhengxiong Jin <Jason.Jin@freescale.com>
> Reviewed-by: Poonam Aggrwal <poonam.aggrwal@nxp.com>
> ---
> Changes in v2:
>   - Modified patch deciption to include common-properties.txt reference.
>   - Reorder the LE/BE read/write APIs for better readability of code
>   - Added an exception to force BE API selection, for powerpc based platform
>     P1010. This ensures that new linux kernel works with old P1010
>     device-tree, while future powerpc platforms that use big endian
>     FlexCAN controller need to specify big-endian in device tree in
>     FlexCAN node.
>   - Tested on P1010 after backporting to freescale sdk 1.4 linux, without
>     any change in device-tree.
>   - Tested on NXP LS1021A arm based platform.
> 
>  drivers/net/can/flexcan.c | 230 ++++++++++++++++++++----------------
>  1 file changed, 128 insertions(+), 102 deletions(-)
> 
> diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
> index a13a489..100b451 100644
> --- a/drivers/net/can/flexcan.c
> +++ b/drivers/net/can/flexcan.c
> @@ -279,6 +279,10 @@ struct flexcan_priv {
>  	struct clk *clk_per;
>  	const struct flexcan_devtype_data *devtype_data;
>  	struct regulator *reg_xceiver;
> +
> +	/* Read and Write APIs */
> +	u32 (*read)(void __iomem *addr);
> +	void (*write)(u32 val, void __iomem *addr);
>  };
>  
>  static const struct flexcan_devtype_data fsl_p1010_devtype_data = {
> @@ -312,39 +316,45 @@ static const struct can_bittiming_const flexcan_bittiming_const = {
>  	.brp_inc = 1,
>  };
>  
> -/* Abstract off the read/write for arm versus ppc. This
> - * assumes that PPC uses big-endian registers and everything
> - * else uses little-endian registers, independent of CPU
> - * endianness.
> +/* FlexCAN module is essentially modelled as a little-endian IP in most
> + * SoCs, i.e the registers as well as the message buffer areas are
> + * implemented in a little-endian fashion.
> + *
> + * However there are some SoCs (e.g. LS1021A) which implement the FlexCAN
> + * module in a big-endian fashion (i.e the registers as well as the
> + * message buffer areas are implemented in a big-endian way).
> + *
> + * In addition, the FlexCAN module can be found on SoCs having ARM or
> + * PPC cores. So, we need to abstract off the register read/write
> + * functions, ensuring that these cater to all the combinations of module
> + * endianness and underlying CPU endianness.
>   */
> -#if defined(CONFIG_PPC)
> -static inline u32 flexcan_read(void __iomem *addr)
> +static inline u32 flexcan_read_be(void __iomem *addr)
>  {
> -	return in_be32(addr);
> +	return ioread32be(addr);
>  }
>  
> -static inline void flexcan_write(u32 val, void __iomem *addr)
> +static inline void flexcan_write_be(u32 val, void __iomem *addr)
>  {
> -	out_be32(addr, val);
> +	iowrite32be(val, addr);
>  }
> -#else
> -static inline u32 flexcan_read(void __iomem *addr)
> +
> +static inline u32 flexcan_read_le(void __iomem *addr)
>  {
> -	return readl(addr);
> +	return ioread32(addr);
>  }
>  
> -static inline void flexcan_write(u32 val, void __iomem *addr)
> +static inline void flexcan_write_le(u32 val, void __iomem *addr)
>  {
> -	writel(val, addr);
> +	iowrite32(val, addr);
>  }
> -#endif
>  
>  static inline void flexcan_error_irq_enable(const struct flexcan_priv *priv)
>  {
>  	struct flexcan_regs __iomem *regs = priv->regs;
>  	u32 reg_ctrl = (priv->reg_ctrl_default | FLEXCAN_CTRL_ERR_MSK);
>  
> -	flexcan_write(reg_ctrl, &regs->ctrl);
> +	priv->write(reg_ctrl, &regs->ctrl);
>  }
>  
>  static inline void flexcan_error_irq_disable(const struct flexcan_priv *priv)
> @@ -352,7 +362,7 @@ static inline void flexcan_error_irq_disable(const struct flexcan_priv *priv)
>  	struct flexcan_regs __iomem *regs = priv->regs;
>  	u32 reg_ctrl = (priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_MSK);
>  
> -	flexcan_write(reg_ctrl, &regs->ctrl);
> +	priv->write(reg_ctrl, &regs->ctrl);
>  }
>  
>  static inline int flexcan_transceiver_enable(const struct flexcan_priv *priv)
> @@ -377,14 +387,14 @@ static int flexcan_chip_enable(struct flexcan_priv *priv)
>  	unsigned int timeout = FLEXCAN_TIMEOUT_US / 10;
>  	u32 reg;
>  
> -	reg = flexcan_read(&regs->mcr);
> +	reg = priv->read(&regs->mcr);
>  	reg &= ~FLEXCAN_MCR_MDIS;
> -	flexcan_write(reg, &regs->mcr);
> +	priv->write(reg, &regs->mcr);
>  
> -	while (timeout-- && (flexcan_read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK))
> +	while (timeout-- && (priv->read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK))
>  		udelay(10);
>  
> -	if (flexcan_read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK)
> +	if (priv->read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK)
>  		return -ETIMEDOUT;
>  
>  	return 0;
> @@ -396,14 +406,14 @@ static int flexcan_chip_disable(struct flexcan_priv *priv)
>  	unsigned int timeout = FLEXCAN_TIMEOUT_US / 10;
>  	u32 reg;
>  
> -	reg = flexcan_read(&regs->mcr);
> +	reg = priv->read(&regs->mcr);
>  	reg |= FLEXCAN_MCR_MDIS;
> -	flexcan_write(reg, &regs->mcr);
> +	priv->write(reg, &regs->mcr);
>  
> -	while (timeout-- && !(flexcan_read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK))
> +	while (timeout-- && !(priv->read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK))
>  		udelay(10);
>  
> -	if (!(flexcan_read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK))
> +	if (!(priv->read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK))
>  		return -ETIMEDOUT;
>  
>  	return 0;
> @@ -415,14 +425,14 @@ static int flexcan_chip_freeze(struct flexcan_priv *priv)
>  	unsigned int timeout = 1000 * 1000 * 10 / priv->can.bittiming.bitrate;
>  	u32 reg;
>  
> -	reg = flexcan_read(&regs->mcr);
> +	reg = priv->read(&regs->mcr);
>  	reg |= FLEXCAN_MCR_HALT;
> -	flexcan_write(reg, &regs->mcr);
> +	priv->write(reg, &regs->mcr);
>  
> -	while (timeout-- && !(flexcan_read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK))
> +	while (timeout-- && !(priv->read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK))
>  		udelay(100);
>  
> -	if (!(flexcan_read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK))
> +	if (!(priv->read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK))
>  		return -ETIMEDOUT;
>  
>  	return 0;
> @@ -434,14 +444,14 @@ static int flexcan_chip_unfreeze(struct flexcan_priv *priv)
>  	unsigned int timeout = FLEXCAN_TIMEOUT_US / 10;
>  	u32 reg;
>  
> -	reg = flexcan_read(&regs->mcr);
> +	reg = priv->read(&regs->mcr);
>  	reg &= ~FLEXCAN_MCR_HALT;
> -	flexcan_write(reg, &regs->mcr);
> +	priv->write(reg, &regs->mcr);
>  
> -	while (timeout-- && (flexcan_read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK))
> +	while (timeout-- && (priv->read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK))
>  		udelay(10);
>  
> -	if (flexcan_read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK)
> +	if (priv->read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK)
>  		return -ETIMEDOUT;
>  
>  	return 0;
> @@ -452,11 +462,11 @@ static int flexcan_chip_softreset(struct flexcan_priv *priv)
>  	struct flexcan_regs __iomem *regs = priv->regs;
>  	unsigned int timeout = FLEXCAN_TIMEOUT_US / 10;
>  
> -	flexcan_write(FLEXCAN_MCR_SOFTRST, &regs->mcr);
> -	while (timeout-- && (flexcan_read(&regs->mcr) & FLEXCAN_MCR_SOFTRST))
> +	priv->write(FLEXCAN_MCR_SOFTRST, &regs->mcr);
> +	while (timeout-- && (priv->read(&regs->mcr) & FLEXCAN_MCR_SOFTRST))
>  		udelay(10);
>  
> -	if (flexcan_read(&regs->mcr) & FLEXCAN_MCR_SOFTRST)
> +	if (priv->read(&regs->mcr) & FLEXCAN_MCR_SOFTRST)
>  		return -ETIMEDOUT;
>  
>  	return 0;
> @@ -467,7 +477,7 @@ static int __flexcan_get_berr_counter(const struct net_device *dev,
>  {
>  	const struct flexcan_priv *priv = netdev_priv(dev);
>  	struct flexcan_regs __iomem *regs = priv->regs;
> -	u32 reg = flexcan_read(&regs->ecr);
> +	u32 reg = priv->read(&regs->ecr);
>  
>  	bec->txerr = (reg >> 0) & 0xff;
>  	bec->rxerr = (reg >> 8) & 0xff;
> @@ -523,24 +533,24 @@ static int flexcan_start_xmit(struct sk_buff *skb, struct net_device *dev)
>  
>  	if (cf->can_dlc > 0) {
>  		data = be32_to_cpup((__be32 *)&cf->data[0]);
> -		flexcan_write(data, &priv->tx_mb->data[0]);
> +		priv->write(data, &priv->tx_mb->data[0]);
>  	}
>  	if (cf->can_dlc > 3) {
>  		data = be32_to_cpup((__be32 *)&cf->data[4]);
> -		flexcan_write(data, &priv->tx_mb->data[1]);
> +		priv->write(data, &priv->tx_mb->data[1]);
>  	}
>  
>  	can_put_echo_skb(skb, dev, 0);
>  
> -	flexcan_write(can_id, &priv->tx_mb->can_id);
> -	flexcan_write(ctrl, &priv->tx_mb->can_ctrl);
> +	priv->write(can_id, &priv->tx_mb->can_id);
> +	priv->write(ctrl, &priv->tx_mb->can_ctrl);
>  
>  	/* Errata ERR005829 step8:
>  	 * Write twice INACTIVE(0x8) code to first MB.
>  	 */
> -	flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE,
> +	priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
>  		      &priv->tx_mb_reserved->can_ctrl);
> -	flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE,
> +	priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
>  		      &priv->tx_mb_reserved->can_ctrl);
>  
>  	return NETDEV_TX_OK;
> @@ -659,7 +669,7 @@ static unsigned int flexcan_mailbox_read(struct can_rx_offload *offload,
>  		u32 code;
>  
>  		do {
> -			reg_ctrl = flexcan_read(&mb->can_ctrl);
> +			reg_ctrl = priv->read(&mb->can_ctrl);
>  		} while (reg_ctrl & FLEXCAN_MB_CODE_RX_BUSY_BIT);
>  
>  		/* is this MB empty? */
> @@ -674,17 +684,17 @@ static unsigned int flexcan_mailbox_read(struct can_rx_offload *offload,
>  			offload->dev->stats.rx_errors++;
>  		}
>  	} else {
> -		reg_iflag1 = flexcan_read(&regs->iflag1);
> +		reg_iflag1 = priv->read(&regs->iflag1);
>  		if (!(reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_AVAILABLE))
>  			return 0;
>  
> -		reg_ctrl = flexcan_read(&mb->can_ctrl);
> +		reg_ctrl = priv->read(&mb->can_ctrl);
>  	}
>  
>  	/* increase timstamp to full 32 bit */
>  	*timestamp = reg_ctrl << 16;
>  
> -	reg_id = flexcan_read(&mb->can_id);
> +	reg_id = priv->read(&mb->can_id);
>  	if (reg_ctrl & FLEXCAN_MB_CNT_IDE)
>  		cf->can_id = ((reg_id >> 0) & CAN_EFF_MASK) | CAN_EFF_FLAG;
>  	else
> @@ -694,19 +704,19 @@ static unsigned int flexcan_mailbox_read(struct can_rx_offload *offload,
>  		cf->can_id |= CAN_RTR_FLAG;
>  	cf->can_dlc = get_can_dlc((reg_ctrl >> 16) & 0xf);
>  
> -	*(__be32 *)(cf->data + 0) = cpu_to_be32(flexcan_read(&mb->data[0]));
> -	*(__be32 *)(cf->data + 4) = cpu_to_be32(flexcan_read(&mb->data[1]));
> +	*(__be32 *)(cf->data + 0) = cpu_to_be32(priv->read(&mb->data[0]));
> +	*(__be32 *)(cf->data + 4) = cpu_to_be32(priv->read(&mb->data[1]));
>  
>  	/* mark as read */
>  	if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) {
>  		/* Clear IRQ */
>  		if (n < 32)
> -			flexcan_write(BIT(n), &regs->iflag1);
> +			priv->write(BIT(n), &regs->iflag1);
>  		else
> -			flexcan_write(BIT(n - 32), &regs->iflag2);
> +			priv->write(BIT(n - 32), &regs->iflag2);
>  	} else {
> -		flexcan_write(FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, &regs->iflag1);
> -		flexcan_read(&regs->timer);
> +		priv->write(FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, &regs->iflag1);
> +		priv->read(&regs->timer);
>  	}
>  
>  	return 1;
> @@ -718,8 +728,8 @@ static inline u64 flexcan_read_reg_iflag_rx(struct flexcan_priv *priv)
>  	struct flexcan_regs __iomem *regs = priv->regs;
>  	u32 iflag1, iflag2;
>  
> -	iflag2 = flexcan_read(&regs->iflag2) & priv->reg_imask2_default;
> -	iflag1 = flexcan_read(&regs->iflag1) & priv->reg_imask1_default &
> +	iflag2 = priv->read(&regs->iflag2) & priv->reg_imask2_default;
> +	iflag1 = priv->read(&regs->iflag1) & priv->reg_imask1_default &
>  		~FLEXCAN_IFLAG_MB(priv->tx_mb_idx);
>  
>  	return (u64)iflag2 << 32 | iflag1;
> @@ -735,7 +745,7 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
>  	u32 reg_iflag1, reg_esr;
>  	enum can_state last_state = priv->can.state;
>  
> -	reg_iflag1 = flexcan_read(&regs->iflag1);
> +	reg_iflag1 = priv->read(&regs->iflag1);
>  
>  	/* reception interrupt */
>  	if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) {
> @@ -758,7 +768,8 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
>  		/* FIFO overflow interrupt */
>  		if (reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_OVERFLOW) {
>  			handled = IRQ_HANDLED;
> -			flexcan_write(FLEXCAN_IFLAG_RX_FIFO_OVERFLOW, &regs->iflag1);
> +			priv->write(FLEXCAN_IFLAG_RX_FIFO_OVERFLOW,
> +				    &regs->iflag1);
>  			dev->stats.rx_over_errors++;
>  			dev->stats.rx_errors++;
>  		}
> @@ -772,18 +783,18 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
>  		can_led_event(dev, CAN_LED_EVENT_TX);
>  
>  		/* after sending a RTR frame MB is in RX mode */
> -		flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE,
> -			      &priv->tx_mb->can_ctrl);
> -		flexcan_write(FLEXCAN_IFLAG_MB(priv->tx_mb_idx), &regs->iflag1);
> +		priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
> +			    &priv->tx_mb->can_ctrl);
> +		priv->write(FLEXCAN_IFLAG_MB(priv->tx_mb_idx), &regs->iflag1);
>  		netif_wake_queue(dev);
>  	}
>  
> -	reg_esr = flexcan_read(&regs->esr);
> +	reg_esr = priv->read(&regs->esr);
>  
>  	/* ACK all bus error and state change IRQ sources */
>  	if (reg_esr & FLEXCAN_ESR_ALL_INT) {
>  		handled = IRQ_HANDLED;
> -		flexcan_write(reg_esr & FLEXCAN_ESR_ALL_INT, &regs->esr);
> +		priv->write(reg_esr & FLEXCAN_ESR_ALL_INT, &regs->esr);
>  	}
>  
>  	/* state change interrupt or broken error state quirk fix is enabled */
> @@ -845,7 +856,7 @@ static void flexcan_set_bittiming(struct net_device *dev)
>  	struct flexcan_regs __iomem *regs = priv->regs;
>  	u32 reg;
>  
> -	reg = flexcan_read(&regs->ctrl);
> +	reg = priv->read(&regs->ctrl);
>  	reg &= ~(FLEXCAN_CTRL_PRESDIV(0xff) |
>  		 FLEXCAN_CTRL_RJW(0x3) |
>  		 FLEXCAN_CTRL_PSEG1(0x7) |
> @@ -869,11 +880,11 @@ static void flexcan_set_bittiming(struct net_device *dev)
>  		reg |= FLEXCAN_CTRL_SMP;
>  
>  	netdev_dbg(dev, "writing ctrl=0x%08x\n", reg);
> -	flexcan_write(reg, &regs->ctrl);
> +	priv->write(reg, &regs->ctrl);
>  
>  	/* print chip status */
>  	netdev_dbg(dev, "%s: mcr=0x%08x ctrl=0x%08x\n", __func__,
> -		   flexcan_read(&regs->mcr), flexcan_read(&regs->ctrl));
> +		   priv->read(&regs->mcr), priv->read(&regs->ctrl));
>  }
>  
>  /* flexcan_chip_start
> @@ -912,7 +923,7 @@ static int flexcan_chip_start(struct net_device *dev)
>  	 * choose format C
>  	 * set max mailbox number
>  	 */
> -	reg_mcr = flexcan_read(&regs->mcr);
> +	reg_mcr = priv->read(&regs->mcr);
>  	reg_mcr &= ~FLEXCAN_MCR_MAXMB(0xff);
>  	reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT | FLEXCAN_MCR_SUPV |
>  		FLEXCAN_MCR_WRN_EN | FLEXCAN_MCR_SRX_DIS | FLEXCAN_MCR_IRMQ |
> @@ -926,7 +937,7 @@ static int flexcan_chip_start(struct net_device *dev)
>  			FLEXCAN_MCR_MAXMB(priv->tx_mb_idx);
>  	}
>  	netdev_dbg(dev, "%s: writing mcr=0x%08x", __func__, reg_mcr);
> -	flexcan_write(reg_mcr, &regs->mcr);
> +	priv->write(reg_mcr, &regs->mcr);
>  
>  	/* CTRL
>  	 *
> @@ -939,7 +950,7 @@ static int flexcan_chip_start(struct net_device *dev)
>  	 * enable bus off interrupt
>  	 * (== FLEXCAN_CTRL_ERR_STATE)
>  	 */
> -	reg_ctrl = flexcan_read(&regs->ctrl);
> +	reg_ctrl = priv->read(&regs->ctrl);
>  	reg_ctrl &= ~FLEXCAN_CTRL_TSYN;
>  	reg_ctrl |= FLEXCAN_CTRL_BOFF_REC | FLEXCAN_CTRL_LBUF |
>  		FLEXCAN_CTRL_ERR_STATE;
> @@ -959,45 +970,45 @@ static int flexcan_chip_start(struct net_device *dev)
>  	/* leave interrupts disabled for now */
>  	reg_ctrl &= ~FLEXCAN_CTRL_ERR_ALL;
>  	netdev_dbg(dev, "%s: writing ctrl=0x%08x", __func__, reg_ctrl);
> -	flexcan_write(reg_ctrl, &regs->ctrl);
> +	priv->write(reg_ctrl, &regs->ctrl);
>  
>  	if ((priv->devtype_data->quirks & FLEXCAN_QUIRK_ENABLE_EACEN_RRS)) {
> -		reg_ctrl2 = flexcan_read(&regs->ctrl2);
> +		reg_ctrl2 = priv->read(&regs->ctrl2);
>  		reg_ctrl2 |= FLEXCAN_CTRL2_EACEN | FLEXCAN_CTRL2_RRS;
> -		flexcan_write(reg_ctrl2, &regs->ctrl2);
> +		priv->write(reg_ctrl2, &regs->ctrl2);
>  	}
>  
>  	/* clear and invalidate all mailboxes first */
>  	for (i = priv->tx_mb_idx; i < ARRAY_SIZE(regs->mb); i++) {
> -		flexcan_write(FLEXCAN_MB_CODE_RX_INACTIVE,
> -			      &regs->mb[i].can_ctrl);
> +		priv->write(FLEXCAN_MB_CODE_RX_INACTIVE,
> +			    &regs->mb[i].can_ctrl);
>  	}
>  
>  	if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) {
>  		for (i = priv->offload.mb_first; i <= priv->offload.mb_last; i++)
> -			flexcan_write(FLEXCAN_MB_CODE_RX_EMPTY,
> -				      &regs->mb[i].can_ctrl);
> +			priv->write(FLEXCAN_MB_CODE_RX_EMPTY,
> +				    &regs->mb[i].can_ctrl);
>  	}
>  
>  	/* Errata ERR005829: mark first TX mailbox as INACTIVE */
> -	flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE,
> -		      &priv->tx_mb_reserved->can_ctrl);
> +	priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
> +		    &priv->tx_mb_reserved->can_ctrl);
>  
>  	/* mark TX mailbox as INACTIVE */
> -	flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE,
> -		      &priv->tx_mb->can_ctrl);
> +	priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
> +		    &priv->tx_mb->can_ctrl);
>  
>  	/* acceptance mask/acceptance code (accept everything) */
> -	flexcan_write(0x0, &regs->rxgmask);
> -	flexcan_write(0x0, &regs->rx14mask);
> -	flexcan_write(0x0, &regs->rx15mask);
> +	priv->write(0x0, &regs->rxgmask);
> +	priv->write(0x0, &regs->rx14mask);
> +	priv->write(0x0, &regs->rx15mask);
>  
>  	if (priv->devtype_data->quirks & FLEXCAN_QUIRK_DISABLE_RXFG)
> -		flexcan_write(0x0, &regs->rxfgmask);
> +		priv->write(0x0, &regs->rxfgmask);
>  
>  	/* clear acceptance filters */
>  	for (i = 0; i < ARRAY_SIZE(regs->mb); i++)
> -		flexcan_write(0, &regs->rximr[i]);
> +		priv->write(0, &regs->rximr[i]);
>  
>  	/* On Vybrid, disable memory error detection interrupts
>  	 * and freeze mode.
> @@ -1010,16 +1021,16 @@ static int flexcan_chip_start(struct net_device *dev)
>  		 * and Correction of Memory Errors" to write to
>  		 * MECR register
>  		 */
> -		reg_ctrl2 = flexcan_read(&regs->ctrl2);
> +		reg_ctrl2 = priv->read(&regs->ctrl2);
>  		reg_ctrl2 |= FLEXCAN_CTRL2_ECRWRE;
> -		flexcan_write(reg_ctrl2, &regs->ctrl2);
> +		priv->write(reg_ctrl2, &regs->ctrl2);
>  
> -		reg_mecr = flexcan_read(&regs->mecr);
> +		reg_mecr = priv->read(&regs->mecr);
>  		reg_mecr &= ~FLEXCAN_MECR_ECRWRDIS;
> -		flexcan_write(reg_mecr, &regs->mecr);
> +		priv->write(reg_mecr, &regs->mecr);
>  		reg_mecr &= ~(FLEXCAN_MECR_NCEFAFRZ | FLEXCAN_MECR_HANCEI_MSK |
>  			      FLEXCAN_MECR_FANCEI_MSK);
> -		flexcan_write(reg_mecr, &regs->mecr);
> +		priv->write(reg_mecr, &regs->mecr);
>  	}
>  
>  	err = flexcan_transceiver_enable(priv);
> @@ -1035,14 +1046,14 @@ static int flexcan_chip_start(struct net_device *dev)
>  
>  	/* enable interrupts atomically */
>  	disable_irq(dev->irq);
> -	flexcan_write(priv->reg_ctrl_default, &regs->ctrl);
> -	flexcan_write(priv->reg_imask1_default, &regs->imask1);
> -	flexcan_write(priv->reg_imask2_default, &regs->imask2);
> +	priv->write(priv->reg_ctrl_default, &regs->ctrl);
> +	priv->write(priv->reg_imask1_default, &regs->imask1);
> +	priv->write(priv->reg_imask2_default, &regs->imask2);
>  	enable_irq(dev->irq);
>  
>  	/* print chip status */
>  	netdev_dbg(dev, "%s: reading mcr=0x%08x ctrl=0x%08x\n", __func__,
> -		   flexcan_read(&regs->mcr), flexcan_read(&regs->ctrl));
> +		   priv->read(&regs->mcr), priv->read(&regs->ctrl));
>  
>  	return 0;
>  
> @@ -1067,10 +1078,10 @@ static void flexcan_chip_stop(struct net_device *dev)
>  	flexcan_chip_disable(priv);
>  
>  	/* Disable all interrupts */
> -	flexcan_write(0, &regs->imask2);
> -	flexcan_write(0, &regs->imask1);
> -	flexcan_write(priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_ALL,
> -		      &regs->ctrl);
> +	priv->write(0, &regs->imask2);
> +	priv->write(0, &regs->imask1);
> +	priv->write(priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_ALL,
> +		    &regs->ctrl);
>  
>  	flexcan_transceiver_disable(priv);
>  	priv->can.state = CAN_STATE_STOPPED;
> @@ -1185,26 +1196,26 @@ static int register_flexcandev(struct net_device *dev)
>  	err = flexcan_chip_disable(priv);
>  	if (err)
>  		goto out_disable_per;
> -	reg = flexcan_read(&regs->ctrl);
> +	reg = priv->read(&regs->ctrl);
>  	reg |= FLEXCAN_CTRL_CLK_SRC;
> -	flexcan_write(reg, &regs->ctrl);
> +	priv->write(reg, &regs->ctrl);
>  
>  	err = flexcan_chip_enable(priv);
>  	if (err)
>  		goto out_chip_disable;
>  
>  	/* set freeze, halt and activate FIFO, restrict register access */
> -	reg = flexcan_read(&regs->mcr);
> +	reg = priv->read(&regs->mcr);
>  	reg |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT |
>  		FLEXCAN_MCR_FEN | FLEXCAN_MCR_SUPV;
> -	flexcan_write(reg, &regs->mcr);
> +	priv->write(reg, &regs->mcr);
>  
>  	/* Currently we only support newer versions of this core
>  	 * featuring a RX hardware FIFO (although this driver doesn't
>  	 * make use of it on some cores). Older cores, found on some
>  	 * Coldfire derivates are not tested.
>  	 */
> -	reg = flexcan_read(&regs->mcr);
> +	reg = priv->read(&regs->mcr);
>  	if (!(reg & FLEXCAN_MCR_FEN)) {
>  		netdev_err(dev, "Could not enable RX FIFO, unsupported core\n");
>  		err = -ENODEV;
> @@ -1313,6 +1324,21 @@ static int flexcan_probe(struct platform_device *pdev)
>  	dev->flags |= IFF_ECHO;
>  
>  	priv = netdev_priv(dev);
> +
> +	if (of_property_read_bool(pdev->dev.of_node, "big-endian")) {
> +		priv->read = flexcan_read_be;
> +		priv->write = flexcan_write_be;
> +	} else {
> +		if (of_device_is_compatible(pdev->dev.of_node,
> +					    "fsl,p1010-flexcan")) {
> +			priv->read = flexcan_read_be;
> +			priv->write = flexcan_write_be;
> +		} else {
> +			priv->read = flexcan_read_le;
> +			priv->write = flexcan_write_le;
> +		}
> +	}
> +

What about this:

	/* set defaults */
	if (of_device_is_compatible(pdev->dev.of_node,
				    "fsl,p1010-flexcan")) {
		priv->read = flexcan_read_be;
		priv->write = flexcan_write_be;
	} else {
		priv->read = flexcan_read_le;
		priv->write = flexcan_write_le;
	}

	if (of_device_is_big_endian()) {
		priv->read = flexcan_read_be;
		priv->write = flexcan_write_be;
	} else {
		priv->read = flexcan_read_le;
		priv->write = flexcan_write_le;
	}

>  	priv->can.clock.freq = clock_freq;
>  	priv->can.bittiming_const = &flexcan_bittiming_const;
>  	priv->can.do_set_mode = flexcan_set_mode;
> 

Marc

-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 52+ messages in thread

* RE: [PATCH v2 1/2] can: flexcan: Remodel FlexCAN register r/w APIs for big endian FlexCAN controllers.
  2017-11-14 15:24   ` [PATCH v2 1/2] can: flexcan: Remodel FlexCAN register r/w APIs for big endian FlexCAN controllers Marc Kleine-Budde
@ 2017-11-16  5:24     ` Pankaj Bansal
  2017-11-16 12:04       ` Marc Kleine-Budde
  2017-11-21 12:18     ` Pankaj Bansal
  1 sibling, 1 reply; 52+ messages in thread
From: Pankaj Bansal @ 2017-11-16  5:24 UTC (permalink / raw)
  To: Marc Kleine-Budde, wg, linux-can
  Cc: Varun Sethi, Poonam Aggrwal, Bhupesh Sharma, Sakar Arora



> -----Original Message-----
> From: Marc Kleine-Budde [mailto:mkl@pengutronix.de]
> Sent: Tuesday, November 14, 2017 8:54 PM
> To: Pankaj Bansal <pankaj.bansal@nxp.com>; wg@grandegger.com; linux-
> can@vger.kernel.org
> Cc: Varun Sethi <V.Sethi@nxp.com>; Poonam Aggrwal
> <poonam.aggrwal@nxp.com>; Bhupesh Sharma
> <bhupesh.sharma@freescale.com>; Sakar Arora
> <Sakar.Arora@freescale.com>
> Subject: Re: [PATCH v2 1/2] can: flexcan: Remodel FlexCAN register r/w APIs
> for big endian FlexCAN controllers.
> 
> On 11/14/2017 12:56 PM, Pankaj Bansal wrote:
> > The FlexCAN driver assumed that FlexCAN controller is big endian for
> > powerpc architecture and little endian for other architectures.
> >
> > But this may not be the case. FlexCAN controller can be little or big
> > endian on any architecture. For e.g. NXP LS1021A ARM based SOC has big
> > endian FlexCAN controller.
> >
> > Therefore, the driver has been modified to add a provision for both
> > types of controllers using an additional device tree property. Big
> > Endian controllers should have "big-endian" set in the device tree.
> >
> > This is the standard practice followed in linux. for more info check:
> > Documentation/devicetree/bindings/common-properties.txt
> 
> Looks better now. Please add note to
> "Documentation/devicetree/bindings/net/can/fsl-flexcan.txt" that we now
> support endianess and state the default endianess.
> 
> What about:
> 
> On a "fsl,p1010-flexcan" device BE is default, on all other devices LE is.
> 
> Please remove the existing "fsl,p1010-flexcan" from "arch/arm/boot/dts"
> and add fsl,imx25-flexcan, fsl,imx35-flexcan and fsl,imx53-flexcan support to
> the driver.
> 

Ok, will do.

> I'm not sure what happens with non DT arm boards. There's still a user in
> tree:
> 
> arch/arm/mach-imx/mach-pcm043.c:388:	imx35_add_flexcan1();
> 
> > Signed-off-by: Pankaj Bansal <pankaj.bansal@nxp.com>
> > Signed-off-by: Bhupesh Sharma <bhupesh.sharma@freescale.com>
> > Signed-off-by: Sakar Arora <Sakar.Arora@freescale.com>
> > Reviewed-by: Zhengxiong Jin <Jason.Jin@freescale.com>
> > Reviewed-by: Poonam Aggrwal <poonam.aggrwal@nxp.com>
> > ---
> > Changes in v2:
> >   - Modified patch deciption to include common-properties.txt reference.
> >   - Reorder the LE/BE read/write APIs for better readability of code
> >   - Added an exception to force BE API selection, for powerpc based
> platform
> >     P1010. This ensures that new linux kernel works with old P1010
> >     device-tree, while future powerpc platforms that use big endian
> >     FlexCAN controller need to specify big-endian in device tree in
> >     FlexCAN node.
> >   - Tested on P1010 after backporting to freescale sdk 1.4 linux, without
> >     any change in device-tree.
> >   - Tested on NXP LS1021A arm based platform.
> >
> >  drivers/net/can/flexcan.c | 230 ++++++++++++++++++++----------------
> >  1 file changed, 128 insertions(+), 102 deletions(-)
> >
> > diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
> > index a13a489..100b451 100644
> > --- a/drivers/net/can/flexcan.c
> > +++ b/drivers/net/can/flexcan.c
> > @@ -279,6 +279,10 @@ struct flexcan_priv {
> >  	struct clk *clk_per;
> >  	const struct flexcan_devtype_data *devtype_data;
> >  	struct regulator *reg_xceiver;
> > +
> > +	/* Read and Write APIs */
> > +	u32 (*read)(void __iomem *addr);
> > +	void (*write)(u32 val, void __iomem *addr);
> >  };
> >
> >  static const struct flexcan_devtype_data fsl_p1010_devtype_data = {
> > @@ -312,39 +316,45 @@ static const struct can_bittiming_const
> flexcan_bittiming_const = {
> >  	.brp_inc = 1,
> >  };
> >
> > -/* Abstract off the read/write for arm versus ppc. This
> > - * assumes that PPC uses big-endian registers and everything
> > - * else uses little-endian registers, independent of CPU
> > - * endianness.
> > +/* FlexCAN module is essentially modelled as a little-endian IP in
> > +most
> > + * SoCs, i.e the registers as well as the message buffer areas are
> > + * implemented in a little-endian fashion.
> > + *
> > + * However there are some SoCs (e.g. LS1021A) which implement the
> > +FlexCAN
> > + * module in a big-endian fashion (i.e the registers as well as the
> > + * message buffer areas are implemented in a big-endian way).
> > + *
> > + * In addition, the FlexCAN module can be found on SoCs having ARM or
> > + * PPC cores. So, we need to abstract off the register read/write
> > + * functions, ensuring that these cater to all the combinations of
> > +module
> > + * endianness and underlying CPU endianness.
> >   */
> > -#if defined(CONFIG_PPC)
> > -static inline u32 flexcan_read(void __iomem *addr)
> > +static inline u32 flexcan_read_be(void __iomem *addr)
> >  {
> > -	return in_be32(addr);
> > +	return ioread32be(addr);
> >  }
> >
> > -static inline void flexcan_write(u32 val, void __iomem *addr)
> > +static inline void flexcan_write_be(u32 val, void __iomem *addr)
> >  {
> > -	out_be32(addr, val);
> > +	iowrite32be(val, addr);
> >  }
> > -#else
> > -static inline u32 flexcan_read(void __iomem *addr)
> > +
> > +static inline u32 flexcan_read_le(void __iomem *addr)
> >  {
> > -	return readl(addr);
> > +	return ioread32(addr);
> >  }
> >
> > -static inline void flexcan_write(u32 val, void __iomem *addr)
> > +static inline void flexcan_write_le(u32 val, void __iomem *addr)
> >  {
> > -	writel(val, addr);
> > +	iowrite32(val, addr);
> >  }
> > -#endif
> >
> >  static inline void flexcan_error_irq_enable(const struct flexcan_priv
> > *priv)  {
> >  	struct flexcan_regs __iomem *regs = priv->regs;
> >  	u32 reg_ctrl = (priv->reg_ctrl_default | FLEXCAN_CTRL_ERR_MSK);
> >
> > -	flexcan_write(reg_ctrl, &regs->ctrl);
> > +	priv->write(reg_ctrl, &regs->ctrl);
> >  }
> >
> >  static inline void flexcan_error_irq_disable(const struct
> > flexcan_priv *priv) @@ -352,7 +362,7 @@ static inline void
> flexcan_error_irq_disable(const struct flexcan_priv *priv)
> >  	struct flexcan_regs __iomem *regs = priv->regs;
> >  	u32 reg_ctrl = (priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_MSK);
> >
> > -	flexcan_write(reg_ctrl, &regs->ctrl);
> > +	priv->write(reg_ctrl, &regs->ctrl);
> >  }
> >
> >  static inline int flexcan_transceiver_enable(const struct
> > flexcan_priv *priv) @@ -377,14 +387,14 @@ static int
> flexcan_chip_enable(struct flexcan_priv *priv)
> >  	unsigned int timeout = FLEXCAN_TIMEOUT_US / 10;
> >  	u32 reg;
> >
> > -	reg = flexcan_read(&regs->mcr);
> > +	reg = priv->read(&regs->mcr);
> >  	reg &= ~FLEXCAN_MCR_MDIS;
> > -	flexcan_write(reg, &regs->mcr);
> > +	priv->write(reg, &regs->mcr);
> >
> > -	while (timeout-- && (flexcan_read(&regs->mcr) &
> FLEXCAN_MCR_LPM_ACK))
> > +	while (timeout-- && (priv->read(&regs->mcr) &
> FLEXCAN_MCR_LPM_ACK))
> >  		udelay(10);
> >
> > -	if (flexcan_read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK)
> > +	if (priv->read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK)
> >  		return -ETIMEDOUT;
> >
> >  	return 0;
> > @@ -396,14 +406,14 @@ static int flexcan_chip_disable(struct flexcan_priv
> *priv)
> >  	unsigned int timeout = FLEXCAN_TIMEOUT_US / 10;
> >  	u32 reg;
> >
> > -	reg = flexcan_read(&regs->mcr);
> > +	reg = priv->read(&regs->mcr);
> >  	reg |= FLEXCAN_MCR_MDIS;
> > -	flexcan_write(reg, &regs->mcr);
> > +	priv->write(reg, &regs->mcr);
> >
> > -	while (timeout-- && !(flexcan_read(&regs->mcr) &
> FLEXCAN_MCR_LPM_ACK))
> > +	while (timeout-- && !(priv->read(&regs->mcr) &
> FLEXCAN_MCR_LPM_ACK))
> >  		udelay(10);
> >
> > -	if (!(flexcan_read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK))
> > +	if (!(priv->read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK))
> >  		return -ETIMEDOUT;
> >
> >  	return 0;
> > @@ -415,14 +425,14 @@ static int flexcan_chip_freeze(struct flexcan_priv
> *priv)
> >  	unsigned int timeout = 1000 * 1000 * 10 / priv->can.bittiming.bitrate;
> >  	u32 reg;
> >
> > -	reg = flexcan_read(&regs->mcr);
> > +	reg = priv->read(&regs->mcr);
> >  	reg |= FLEXCAN_MCR_HALT;
> > -	flexcan_write(reg, &regs->mcr);
> > +	priv->write(reg, &regs->mcr);
> >
> > -	while (timeout-- && !(flexcan_read(&regs->mcr) &
> FLEXCAN_MCR_FRZ_ACK))
> > +	while (timeout-- && !(priv->read(&regs->mcr) &
> FLEXCAN_MCR_FRZ_ACK))
> >  		udelay(100);
> >
> > -	if (!(flexcan_read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK))
> > +	if (!(priv->read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK))
> >  		return -ETIMEDOUT;
> >
> >  	return 0;
> > @@ -434,14 +444,14 @@ static int flexcan_chip_unfreeze(struct
> flexcan_priv *priv)
> >  	unsigned int timeout = FLEXCAN_TIMEOUT_US / 10;
> >  	u32 reg;
> >
> > -	reg = flexcan_read(&regs->mcr);
> > +	reg = priv->read(&regs->mcr);
> >  	reg &= ~FLEXCAN_MCR_HALT;
> > -	flexcan_write(reg, &regs->mcr);
> > +	priv->write(reg, &regs->mcr);
> >
> > -	while (timeout-- && (flexcan_read(&regs->mcr) &
> FLEXCAN_MCR_FRZ_ACK))
> > +	while (timeout-- && (priv->read(&regs->mcr) &
> FLEXCAN_MCR_FRZ_ACK))
> >  		udelay(10);
> >
> > -	if (flexcan_read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK)
> > +	if (priv->read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK)
> >  		return -ETIMEDOUT;
> >
> >  	return 0;
> > @@ -452,11 +462,11 @@ static int flexcan_chip_softreset(struct
> flexcan_priv *priv)
> >  	struct flexcan_regs __iomem *regs = priv->regs;
> >  	unsigned int timeout = FLEXCAN_TIMEOUT_US / 10;
> >
> > -	flexcan_write(FLEXCAN_MCR_SOFTRST, &regs->mcr);
> > -	while (timeout-- && (flexcan_read(&regs->mcr) &
> FLEXCAN_MCR_SOFTRST))
> > +	priv->write(FLEXCAN_MCR_SOFTRST, &regs->mcr);
> > +	while (timeout-- && (priv->read(&regs->mcr) &
> FLEXCAN_MCR_SOFTRST))
> >  		udelay(10);
> >
> > -	if (flexcan_read(&regs->mcr) & FLEXCAN_MCR_SOFTRST)
> > +	if (priv->read(&regs->mcr) & FLEXCAN_MCR_SOFTRST)
> >  		return -ETIMEDOUT;
> >
> >  	return 0;
> > @@ -467,7 +477,7 @@ static int __flexcan_get_berr_counter(const struct
> > net_device *dev,  {
> >  	const struct flexcan_priv *priv = netdev_priv(dev);
> >  	struct flexcan_regs __iomem *regs = priv->regs;
> > -	u32 reg = flexcan_read(&regs->ecr);
> > +	u32 reg = priv->read(&regs->ecr);
> >
> >  	bec->txerr = (reg >> 0) & 0xff;
> >  	bec->rxerr = (reg >> 8) & 0xff;
> > @@ -523,24 +533,24 @@ static int flexcan_start_xmit(struct sk_buff
> > *skb, struct net_device *dev)
> >
> >  	if (cf->can_dlc > 0) {
> >  		data = be32_to_cpup((__be32 *)&cf->data[0]);
> > -		flexcan_write(data, &priv->tx_mb->data[0]);
> > +		priv->write(data, &priv->tx_mb->data[0]);
> >  	}
> >  	if (cf->can_dlc > 3) {
> >  		data = be32_to_cpup((__be32 *)&cf->data[4]);
> > -		flexcan_write(data, &priv->tx_mb->data[1]);
> > +		priv->write(data, &priv->tx_mb->data[1]);
> >  	}
> >
> >  	can_put_echo_skb(skb, dev, 0);
> >
> > -	flexcan_write(can_id, &priv->tx_mb->can_id);
> > -	flexcan_write(ctrl, &priv->tx_mb->can_ctrl);
> > +	priv->write(can_id, &priv->tx_mb->can_id);
> > +	priv->write(ctrl, &priv->tx_mb->can_ctrl);
> >
> >  	/* Errata ERR005829 step8:
> >  	 * Write twice INACTIVE(0x8) code to first MB.
> >  	 */
> > -	flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE,
> > +	priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
> >  		      &priv->tx_mb_reserved->can_ctrl);
> > -	flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE,
> > +	priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
> >  		      &priv->tx_mb_reserved->can_ctrl);
> >
> >  	return NETDEV_TX_OK;
> > @@ -659,7 +669,7 @@ static unsigned int flexcan_mailbox_read(struct
> can_rx_offload *offload,
> >  		u32 code;
> >
> >  		do {
> > -			reg_ctrl = flexcan_read(&mb->can_ctrl);
> > +			reg_ctrl = priv->read(&mb->can_ctrl);
> >  		} while (reg_ctrl & FLEXCAN_MB_CODE_RX_BUSY_BIT);
> >
> >  		/* is this MB empty? */
> > @@ -674,17 +684,17 @@ static unsigned int flexcan_mailbox_read(struct
> can_rx_offload *offload,
> >  			offload->dev->stats.rx_errors++;
> >  		}
> >  	} else {
> > -		reg_iflag1 = flexcan_read(&regs->iflag1);
> > +		reg_iflag1 = priv->read(&regs->iflag1);
> >  		if (!(reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_AVAILABLE))
> >  			return 0;
> >
> > -		reg_ctrl = flexcan_read(&mb->can_ctrl);
> > +		reg_ctrl = priv->read(&mb->can_ctrl);
> >  	}
> >
> >  	/* increase timstamp to full 32 bit */
> >  	*timestamp = reg_ctrl << 16;
> >
> > -	reg_id = flexcan_read(&mb->can_id);
> > +	reg_id = priv->read(&mb->can_id);
> >  	if (reg_ctrl & FLEXCAN_MB_CNT_IDE)
> >  		cf->can_id = ((reg_id >> 0) & CAN_EFF_MASK) |
> CAN_EFF_FLAG;
> >  	else
> > @@ -694,19 +704,19 @@ static unsigned int flexcan_mailbox_read(struct
> can_rx_offload *offload,
> >  		cf->can_id |= CAN_RTR_FLAG;
> >  	cf->can_dlc = get_can_dlc((reg_ctrl >> 16) & 0xf);
> >
> > -	*(__be32 *)(cf->data + 0) = cpu_to_be32(flexcan_read(&mb-
> >data[0]));
> > -	*(__be32 *)(cf->data + 4) = cpu_to_be32(flexcan_read(&mb-
> >data[1]));
> > +	*(__be32 *)(cf->data + 0) = cpu_to_be32(priv->read(&mb->data[0]));
> > +	*(__be32 *)(cf->data + 4) = cpu_to_be32(priv->read(&mb->data[1]));
> >
> >  	/* mark as read */
> >  	if (priv->devtype_data->quirks &
> FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) {
> >  		/* Clear IRQ */
> >  		if (n < 32)
> > -			flexcan_write(BIT(n), &regs->iflag1);
> > +			priv->write(BIT(n), &regs->iflag1);
> >  		else
> > -			flexcan_write(BIT(n - 32), &regs->iflag2);
> > +			priv->write(BIT(n - 32), &regs->iflag2);
> >  	} else {
> > -		flexcan_write(FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, &regs-
> >iflag1);
> > -		flexcan_read(&regs->timer);
> > +		priv->write(FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, &regs-
> >iflag1);
> > +		priv->read(&regs->timer);
> >  	}
> >
> >  	return 1;
> > @@ -718,8 +728,8 @@ static inline u64 flexcan_read_reg_iflag_rx(struct
> flexcan_priv *priv)
> >  	struct flexcan_regs __iomem *regs = priv->regs;
> >  	u32 iflag1, iflag2;
> >
> > -	iflag2 = flexcan_read(&regs->iflag2) & priv->reg_imask2_default;
> > -	iflag1 = flexcan_read(&regs->iflag1) & priv->reg_imask1_default &
> > +	iflag2 = priv->read(&regs->iflag2) & priv->reg_imask2_default;
> > +	iflag1 = priv->read(&regs->iflag1) & priv->reg_imask1_default &
> >  		~FLEXCAN_IFLAG_MB(priv->tx_mb_idx);
> >
> >  	return (u64)iflag2 << 32 | iflag1;
> > @@ -735,7 +745,7 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
> >  	u32 reg_iflag1, reg_esr;
> >  	enum can_state last_state = priv->can.state;
> >
> > -	reg_iflag1 = flexcan_read(&regs->iflag1);
> > +	reg_iflag1 = priv->read(&regs->iflag1);
> >
> >  	/* reception interrupt */
> >  	if (priv->devtype_data->quirks &
> FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) {
> > @@ -758,7 +768,8 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
> >  		/* FIFO overflow interrupt */
> >  		if (reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_OVERFLOW) {
> >  			handled = IRQ_HANDLED;
> > -			flexcan_write(FLEXCAN_IFLAG_RX_FIFO_OVERFLOW,
> &regs->iflag1);
> > +			priv->write(FLEXCAN_IFLAG_RX_FIFO_OVERFLOW,
> > +				    &regs->iflag1);
> >  			dev->stats.rx_over_errors++;
> >  			dev->stats.rx_errors++;
> >  		}
> > @@ -772,18 +783,18 @@ static irqreturn_t flexcan_irq(int irq, void
> *dev_id)
> >  		can_led_event(dev, CAN_LED_EVENT_TX);
> >
> >  		/* after sending a RTR frame MB is in RX mode */
> > -		flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE,
> > -			      &priv->tx_mb->can_ctrl);
> > -		flexcan_write(FLEXCAN_IFLAG_MB(priv->tx_mb_idx), &regs-
> >iflag1);
> > +		priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
> > +			    &priv->tx_mb->can_ctrl);
> > +		priv->write(FLEXCAN_IFLAG_MB(priv->tx_mb_idx), &regs-
> >iflag1);
> >  		netif_wake_queue(dev);
> >  	}
> >
> > -	reg_esr = flexcan_read(&regs->esr);
> > +	reg_esr = priv->read(&regs->esr);
> >
> >  	/* ACK all bus error and state change IRQ sources */
> >  	if (reg_esr & FLEXCAN_ESR_ALL_INT) {
> >  		handled = IRQ_HANDLED;
> > -		flexcan_write(reg_esr & FLEXCAN_ESR_ALL_INT, &regs->esr);
> > +		priv->write(reg_esr & FLEXCAN_ESR_ALL_INT, &regs->esr);
> >  	}
> >
> >  	/* state change interrupt or broken error state quirk fix is enabled
> > */ @@ -845,7 +856,7 @@ static void flexcan_set_bittiming(struct
> net_device *dev)
> >  	struct flexcan_regs __iomem *regs = priv->regs;
> >  	u32 reg;
> >
> > -	reg = flexcan_read(&regs->ctrl);
> > +	reg = priv->read(&regs->ctrl);
> >  	reg &= ~(FLEXCAN_CTRL_PRESDIV(0xff) |
> >  		 FLEXCAN_CTRL_RJW(0x3) |
> >  		 FLEXCAN_CTRL_PSEG1(0x7) |
> > @@ -869,11 +880,11 @@ static void flexcan_set_bittiming(struct
> net_device *dev)
> >  		reg |= FLEXCAN_CTRL_SMP;
> >
> >  	netdev_dbg(dev, "writing ctrl=0x%08x\n", reg);
> > -	flexcan_write(reg, &regs->ctrl);
> > +	priv->write(reg, &regs->ctrl);
> >
> >  	/* print chip status */
> >  	netdev_dbg(dev, "%s: mcr=0x%08x ctrl=0x%08x\n", __func__,
> > -		   flexcan_read(&regs->mcr), flexcan_read(&regs->ctrl));
> > +		   priv->read(&regs->mcr), priv->read(&regs->ctrl));
> >  }
> >
> >  /* flexcan_chip_start
> > @@ -912,7 +923,7 @@ static int flexcan_chip_start(struct net_device *dev)
> >  	 * choose format C
> >  	 * set max mailbox number
> >  	 */
> > -	reg_mcr = flexcan_read(&regs->mcr);
> > +	reg_mcr = priv->read(&regs->mcr);
> >  	reg_mcr &= ~FLEXCAN_MCR_MAXMB(0xff);
> >  	reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT |
> FLEXCAN_MCR_SUPV |
> >  		FLEXCAN_MCR_WRN_EN | FLEXCAN_MCR_SRX_DIS |
> FLEXCAN_MCR_IRMQ | @@
> > -926,7 +937,7 @@ static int flexcan_chip_start(struct net_device *dev)
> >  			FLEXCAN_MCR_MAXMB(priv->tx_mb_idx);
> >  	}
> >  	netdev_dbg(dev, "%s: writing mcr=0x%08x", __func__, reg_mcr);
> > -	flexcan_write(reg_mcr, &regs->mcr);
> > +	priv->write(reg_mcr, &regs->mcr);
> >
> >  	/* CTRL
> >  	 *
> > @@ -939,7 +950,7 @@ static int flexcan_chip_start(struct net_device *dev)
> >  	 * enable bus off interrupt
> >  	 * (== FLEXCAN_CTRL_ERR_STATE)
> >  	 */
> > -	reg_ctrl = flexcan_read(&regs->ctrl);
> > +	reg_ctrl = priv->read(&regs->ctrl);
> >  	reg_ctrl &= ~FLEXCAN_CTRL_TSYN;
> >  	reg_ctrl |= FLEXCAN_CTRL_BOFF_REC | FLEXCAN_CTRL_LBUF |
> >  		FLEXCAN_CTRL_ERR_STATE;
> > @@ -959,45 +970,45 @@ static int flexcan_chip_start(struct net_device
> *dev)
> >  	/* leave interrupts disabled for now */
> >  	reg_ctrl &= ~FLEXCAN_CTRL_ERR_ALL;
> >  	netdev_dbg(dev, "%s: writing ctrl=0x%08x", __func__, reg_ctrl);
> > -	flexcan_write(reg_ctrl, &regs->ctrl);
> > +	priv->write(reg_ctrl, &regs->ctrl);
> >
> >  	if ((priv->devtype_data->quirks &
> FLEXCAN_QUIRK_ENABLE_EACEN_RRS)) {
> > -		reg_ctrl2 = flexcan_read(&regs->ctrl2);
> > +		reg_ctrl2 = priv->read(&regs->ctrl2);
> >  		reg_ctrl2 |= FLEXCAN_CTRL2_EACEN | FLEXCAN_CTRL2_RRS;
> > -		flexcan_write(reg_ctrl2, &regs->ctrl2);
> > +		priv->write(reg_ctrl2, &regs->ctrl2);
> >  	}
> >
> >  	/* clear and invalidate all mailboxes first */
> >  	for (i = priv->tx_mb_idx; i < ARRAY_SIZE(regs->mb); i++) {
> > -		flexcan_write(FLEXCAN_MB_CODE_RX_INACTIVE,
> > -			      &regs->mb[i].can_ctrl);
> > +		priv->write(FLEXCAN_MB_CODE_RX_INACTIVE,
> > +			    &regs->mb[i].can_ctrl);
> >  	}
> >
> >  	if (priv->devtype_data->quirks &
> FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) {
> >  		for (i = priv->offload.mb_first; i <= priv->offload.mb_last; i++)
> > -			flexcan_write(FLEXCAN_MB_CODE_RX_EMPTY,
> > -				      &regs->mb[i].can_ctrl);
> > +			priv->write(FLEXCAN_MB_CODE_RX_EMPTY,
> > +				    &regs->mb[i].can_ctrl);
> >  	}
> >
> >  	/* Errata ERR005829: mark first TX mailbox as INACTIVE */
> > -	flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE,
> > -		      &priv->tx_mb_reserved->can_ctrl);
> > +	priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
> > +		    &priv->tx_mb_reserved->can_ctrl);
> >
> >  	/* mark TX mailbox as INACTIVE */
> > -	flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE,
> > -		      &priv->tx_mb->can_ctrl);
> > +	priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
> > +		    &priv->tx_mb->can_ctrl);
> >
> >  	/* acceptance mask/acceptance code (accept everything) */
> > -	flexcan_write(0x0, &regs->rxgmask);
> > -	flexcan_write(0x0, &regs->rx14mask);
> > -	flexcan_write(0x0, &regs->rx15mask);
> > +	priv->write(0x0, &regs->rxgmask);
> > +	priv->write(0x0, &regs->rx14mask);
> > +	priv->write(0x0, &regs->rx15mask);
> >
> >  	if (priv->devtype_data->quirks & FLEXCAN_QUIRK_DISABLE_RXFG)
> > -		flexcan_write(0x0, &regs->rxfgmask);
> > +		priv->write(0x0, &regs->rxfgmask);
> >
> >  	/* clear acceptance filters */
> >  	for (i = 0; i < ARRAY_SIZE(regs->mb); i++)
> > -		flexcan_write(0, &regs->rximr[i]);
> > +		priv->write(0, &regs->rximr[i]);
> >
> >  	/* On Vybrid, disable memory error detection interrupts
> >  	 * and freeze mode.
> > @@ -1010,16 +1021,16 @@ static int flexcan_chip_start(struct net_device
> *dev)
> >  		 * and Correction of Memory Errors" to write to
> >  		 * MECR register
> >  		 */
> > -		reg_ctrl2 = flexcan_read(&regs->ctrl2);
> > +		reg_ctrl2 = priv->read(&regs->ctrl2);
> >  		reg_ctrl2 |= FLEXCAN_CTRL2_ECRWRE;
> > -		flexcan_write(reg_ctrl2, &regs->ctrl2);
> > +		priv->write(reg_ctrl2, &regs->ctrl2);
> >
> > -		reg_mecr = flexcan_read(&regs->mecr);
> > +		reg_mecr = priv->read(&regs->mecr);
> >  		reg_mecr &= ~FLEXCAN_MECR_ECRWRDIS;
> > -		flexcan_write(reg_mecr, &regs->mecr);
> > +		priv->write(reg_mecr, &regs->mecr);
> >  		reg_mecr &= ~(FLEXCAN_MECR_NCEFAFRZ |
> FLEXCAN_MECR_HANCEI_MSK |
> >  			      FLEXCAN_MECR_FANCEI_MSK);
> > -		flexcan_write(reg_mecr, &regs->mecr);
> > +		priv->write(reg_mecr, &regs->mecr);
> >  	}
> >
> >  	err = flexcan_transceiver_enable(priv); @@ -1035,14 +1046,14 @@
> > static int flexcan_chip_start(struct net_device *dev)
> >
> >  	/* enable interrupts atomically */
> >  	disable_irq(dev->irq);
> > -	flexcan_write(priv->reg_ctrl_default, &regs->ctrl);
> > -	flexcan_write(priv->reg_imask1_default, &regs->imask1);
> > -	flexcan_write(priv->reg_imask2_default, &regs->imask2);
> > +	priv->write(priv->reg_ctrl_default, &regs->ctrl);
> > +	priv->write(priv->reg_imask1_default, &regs->imask1);
> > +	priv->write(priv->reg_imask2_default, &regs->imask2);
> >  	enable_irq(dev->irq);
> >
> >  	/* print chip status */
> >  	netdev_dbg(dev, "%s: reading mcr=0x%08x ctrl=0x%08x\n",
> __func__,
> > -		   flexcan_read(&regs->mcr), flexcan_read(&regs->ctrl));
> > +		   priv->read(&regs->mcr), priv->read(&regs->ctrl));
> >
> >  	return 0;
> >
> > @@ -1067,10 +1078,10 @@ static void flexcan_chip_stop(struct net_device
> *dev)
> >  	flexcan_chip_disable(priv);
> >
> >  	/* Disable all interrupts */
> > -	flexcan_write(0, &regs->imask2);
> > -	flexcan_write(0, &regs->imask1);
> > -	flexcan_write(priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_ALL,
> > -		      &regs->ctrl);
> > +	priv->write(0, &regs->imask2);
> > +	priv->write(0, &regs->imask1);
> > +	priv->write(priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_ALL,
> > +		    &regs->ctrl);
> >
> >  	flexcan_transceiver_disable(priv);
> >  	priv->can.state = CAN_STATE_STOPPED; @@ -1185,26 +1196,26 @@
> static
> > int register_flexcandev(struct net_device *dev)
> >  	err = flexcan_chip_disable(priv);
> >  	if (err)
> >  		goto out_disable_per;
> > -	reg = flexcan_read(&regs->ctrl);
> > +	reg = priv->read(&regs->ctrl);
> >  	reg |= FLEXCAN_CTRL_CLK_SRC;
> > -	flexcan_write(reg, &regs->ctrl);
> > +	priv->write(reg, &regs->ctrl);
> >
> >  	err = flexcan_chip_enable(priv);
> >  	if (err)
> >  		goto out_chip_disable;
> >
> >  	/* set freeze, halt and activate FIFO, restrict register access */
> > -	reg = flexcan_read(&regs->mcr);
> > +	reg = priv->read(&regs->mcr);
> >  	reg |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT |
> >  		FLEXCAN_MCR_FEN | FLEXCAN_MCR_SUPV;
> > -	flexcan_write(reg, &regs->mcr);
> > +	priv->write(reg, &regs->mcr);
> >
> >  	/* Currently we only support newer versions of this core
> >  	 * featuring a RX hardware FIFO (although this driver doesn't
> >  	 * make use of it on some cores). Older cores, found on some
> >  	 * Coldfire derivates are not tested.
> >  	 */
> > -	reg = flexcan_read(&regs->mcr);
> > +	reg = priv->read(&regs->mcr);
> >  	if (!(reg & FLEXCAN_MCR_FEN)) {
> >  		netdev_err(dev, "Could not enable RX FIFO, unsupported
> core\n");
> >  		err = -ENODEV;
> > @@ -1313,6 +1324,21 @@ static int flexcan_probe(struct platform_device
> *pdev)
> >  	dev->flags |= IFF_ECHO;
> >
> >  	priv = netdev_priv(dev);
> > +
> > +	if (of_property_read_bool(pdev->dev.of_node, "big-endian")) {
> > +		priv->read = flexcan_read_be;
> > +		priv->write = flexcan_write_be;
> > +	} else {
> > +		if (of_device_is_compatible(pdev->dev.of_node,
> > +					    "fsl,p1010-flexcan")) {
> > +			priv->read = flexcan_read_be;
> > +			priv->write = flexcan_write_be;
> > +		} else {
> > +			priv->read = flexcan_read_le;
> > +			priv->write = flexcan_write_le;
> > +		}
> > +	}
> > +
> 
> What about this:
> 
> 	/* set defaults */
> 	if (of_device_is_compatible(pdev->dev.of_node,
> 				    "fsl,p1010-flexcan")) {
> 		priv->read = flexcan_read_be;
> 		priv->write = flexcan_write_be;
> 	} else {
> 		priv->read = flexcan_read_le;
> 		priv->write = flexcan_write_le;
> 	}
> 
> 	if (of_device_is_big_endian()) {
> 		priv->read = flexcan_read_be;
> 		priv->write = flexcan_write_be;
> 	} else {
> 		priv->read = flexcan_read_le;
> 		priv->write = flexcan_write_le;
> 	}
> 

native-endian : Use this if the hardware "self-adjusts"
   register endianness based on the CPU's configured endianness.
I don’t see FlexCAN hardware doing that. That is why we should not use 
of_device_is_big_endian, and only check for "big-endian".

> >  	priv->can.clock.freq = clock_freq;
> >  	priv->can.bittiming_const = &flexcan_bittiming_const;
> >  	priv->can.do_set_mode = flexcan_set_mode;
> >
> 
> Marc
> 
> --
> Pengutronix e.K.                  | Marc Kleine-Budde           |
> Industrial Linux Solutions        | Phone: +49-231-2826-924     |
> Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
> Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


^ permalink raw reply	[flat|nested] 52+ messages in thread

* RE: [PATCH v2 2/2] can: flexcan: adding platform specific details for LS1021A
  2017-11-14 12:59     ` Marc Kleine-Budde
@ 2017-11-16  5:34       ` Pankaj Bansal
  2017-11-16  7:05         ` Wolfgang Grandegger
  0 siblings, 1 reply; 52+ messages in thread
From: Pankaj Bansal @ 2017-11-16  5:34 UTC (permalink / raw)
  To: Marc Kleine-Budde, wg, linux-can, Yi.Zhu5
  Cc: Varun Sethi, Poonam Aggrwal, Bhupesh Sharma



> -----Original Message-----
> From: Marc Kleine-Budde [mailto:mkl@pengutronix.de]
> Sent: Tuesday, November 14, 2017 6:29 PM
> To: Pankaj Bansal <pankaj.bansal@nxp.com>; wg@grandegger.com; linux-
> can@vger.kernel.org
> Cc: Varun Sethi <V.Sethi@nxp.com>; Poonam Aggrwal
> <poonam.aggrwal@nxp.com>; Bhupesh Sharma
> <bhupesh.sharma@freescale.com>
> Subject: Re: [PATCH v2 2/2] can: flexcan: adding platform specific details for
> LS1021A
> 
> On 11/14/2017 12:56 PM, Pankaj Bansal wrote:
> > This patch adds platform specific details for NXP SOC LS1021A to the
> > flexcan driver code.
> >
> > Signed-off-by: Pankaj Bansal <pankaj.bansal@nxp.com>
> > Signed-off-by: Bhupesh Sharma <bhupesh.sharma@freescale.com>
> > Reviewed-by: Zhengxiong Jin <Jason.Jin@freescale.com>
> > Reviewed-by: Poonam Aggrwal <poonam.aggrwal@nxp.com>
> > ---
> > Changes in v2:
> >   - No change.
> >
> >  drivers/net/can/flexcan.c | 7 +++++++
> >  1 file changed, 7 insertions(+)
> >
> > diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
> > index 100b451..fa2d4c9 100644
> > --- a/drivers/net/can/flexcan.c
> > +++ b/drivers/net/can/flexcan.c
> > @@ -304,6 +304,11 @@ static const struct flexcan_devtype_data
> fsl_vf610_devtype_data = {
> >  		FLEXCAN_QUIRK_DISABLE_MECR |
> FLEXCAN_QUIRK_USE_OFF_TIMESTAMP,  };
> >
> > +/* LS1021A-Rev2 has functional RX-FIFO mode  */
> 
> How big is the RX-FIFO? If the normal mailboxes can receive RTR messages,
> we definitely want to use FLEXCAN_QUIRK_USE_OFF_TIMESTAMP. As you
> can buffer > 60 CAN frames compared to only 6 in FIFO mode.
> 

The FIFO in LS1021A is 6 frames.
I saw this quirk. Basically we are creating a FIFO in software which is sorted based
on the receive time stamp value. IMO LS1021A should be able to support that.
BUT I have not tested this quirk yet. Right now I won't be able to test this on LS1021A.
If you can accept this platform with FIFO mode now, then later on I can add this quirk after testing.

> Please add your IP core to the "FLEXCAN hardware feature flags" table [1] in
> the driver. Also please test the transition interrupts for changes in the CAN
> error state, see the commits of ZHU Yi
> (ST-FIR/ENG1-Zhu) <Yi.Zhu5@cn.bosch.com> on the driver. [2]
> 

I did not understand this quirk (FLEXCAN_QUIRK_BROKEN_PERR_STATE).
What does this quirk do ? how do I check if my IP supports it or not ?
How do I test this ?

Can you please help me to understand ?

> > +static const struct flexcan_devtype_data fsl_ls1021a_r2_devtype_data = {
> > +	.quirks = FLEXCAN_QUIRK_DISABLE_RXFG |
> FLEXCAN_QUIRK_DISABLE_MECR,
> > +};
> > +
> >  static const struct can_bittiming_const flexcan_bittiming_const = {
> >  	.name = DRV_NAME,
> >  	.tseg1_min = 4,
> > @@ -1245,6 +1250,8 @@ static const struct of_device_id
> flexcan_of_match[] = {
> >  	{ .compatible = "fsl,imx28-flexcan", .data =
> &fsl_imx28_devtype_data, },
> >  	{ .compatible = "fsl,p1010-flexcan", .data =
> &fsl_p1010_devtype_data, },
> >  	{ .compatible = "fsl,vf610-flexcan", .data =
> > &fsl_vf610_devtype_data, },
> > +	{ .compatible = "fsl,ls1021ar2-flexcan",
> > +	  .data = &fsl_ls1021a_r2_devtype_data, },
> 
> Please keep in in one line, even if it's more than 80 chars.
> 
> >  	{ /* sentinel */ },
> >  };
> >  MODULE_DEVICE_TABLE(of, flexcan_of_match);
> >
> 
> Marc
> 
> [1]
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/driver
> s/net/can/flexcan.c#n182
> [2]
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/log/drivers
> /net/can/flexcan.c
> 
> --
> Pengutronix e.K.                  | Marc Kleine-Budde           |
> Industrial Linux Solutions        | Phone: +49-231-2826-924     |
> Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
> Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH v2 2/2] can: flexcan: adding platform specific details for LS1021A
  2017-11-16  5:34       ` Pankaj Bansal
@ 2017-11-16  7:05         ` Wolfgang Grandegger
  2017-11-16  7:23           ` ZHU Yi (ST-FIR/ENG1-Zhu)
  0 siblings, 1 reply; 52+ messages in thread
From: Wolfgang Grandegger @ 2017-11-16  7:05 UTC (permalink / raw)
  To: Pankaj Bansal, Marc Kleine-Budde, linux-can, Yi.Zhu5
  Cc: Varun Sethi, Poonam Aggrwal, Bhupesh Sharma



Am 16.11.2017 um 06:34 schrieb Pankaj Bansal:
> 
> 
>> -----Original Message-----
>> From: Marc Kleine-Budde [mailto:mkl@pengutronix.de]
>> Sent: Tuesday, November 14, 2017 6:29 PM
>> To: Pankaj Bansal <pankaj.bansal@nxp.com>; wg@grandegger.com; linux-
>> can@vger.kernel.org
>> Cc: Varun Sethi <V.Sethi@nxp.com>; Poonam Aggrwal
>> <poonam.aggrwal@nxp.com>; Bhupesh Sharma
>> <bhupesh.sharma@freescale.com>
>> Subject: Re: [PATCH v2 2/2] can: flexcan: adding platform specific details for
>> LS1021A
>>
>> On 11/14/2017 12:56 PM, Pankaj Bansal wrote:
>>> This patch adds platform specific details for NXP SOC LS1021A to the
>>> flexcan driver code.
>>>
>>> Signed-off-by: Pankaj Bansal <pankaj.bansal@nxp.com>
>>> Signed-off-by: Bhupesh Sharma <bhupesh.sharma@freescale.com>
>>> Reviewed-by: Zhengxiong Jin <Jason.Jin@freescale.com>
>>> Reviewed-by: Poonam Aggrwal <poonam.aggrwal@nxp.com>
>>> ---
>>> Changes in v2:
>>>    - No change.
>>>
>>>   drivers/net/can/flexcan.c | 7 +++++++
>>>   1 file changed, 7 insertions(+)
>>>
>>> diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
>>> index 100b451..fa2d4c9 100644
>>> --- a/drivers/net/can/flexcan.c
>>> +++ b/drivers/net/can/flexcan.c
>>> @@ -304,6 +304,11 @@ static const struct flexcan_devtype_data
>> fsl_vf610_devtype_data = {
>>>   		FLEXCAN_QUIRK_DISABLE_MECR |
>> FLEXCAN_QUIRK_USE_OFF_TIMESTAMP,  };
>>>
>>> +/* LS1021A-Rev2 has functional RX-FIFO mode  */
>>
>> How big is the RX-FIFO? If the normal mailboxes can receive RTR messages,
>> we definitely want to use FLEXCAN_QUIRK_USE_OFF_TIMESTAMP. As you
>> can buffer > 60 CAN frames compared to only 6 in FIFO mode.
>>
> 
> The FIFO in LS1021A is 6 frames.
> I saw this quirk. Basically we are creating a FIFO in software which is sorted based
> on the receive time stamp value. IMO LS1021A should be able to support that.
> BUT I have not tested this quirk yet. Right now I won't be able to test this on LS1021A.
> If you can accept this platform with FIFO mode now, then later on I can add this quirk after testing.
> 
>> Please add your IP core to the "FLEXCAN hardware feature flags" table [1] in
>> the driver. Also please test the transition interrupts for changes in the CAN
>> error state, see the commits of ZHU Yi
>> (ST-FIR/ENG1-Zhu) <Yi.Zhu5@cn.bosch.com> on the driver. [2]
>>
> 
> I did not understand this quirk (FLEXCAN_QUIRK_BROKEN_PERR_STATE).
> What does this quirk do ? how do I check if my IP supports it or not ?
> How do I test this ?
> 
> Can you please help me to understand ?

It's about reporting CAN error state changes "error-active" -> "warning" 
-> "error-passive" -> "bus-off" and back. The quirk might be required to 
trigger the state-change to "error-passive".

You can test such state changes by doing:

1. Send messages without CAN cable connected

2. Short-circuit the CAN low and high signals

Then connect the cable and remove the short-circuit and send messages 
using "cansend" or "cangen". Please also use "ip set link can0 ... 
restart-ms 100" to recover from bus-off automatically.

While testing watch the error messages with the command below and report 
the results to the list.

# candump -td -e any,0:0,#FFFFFFFF

Thanks,

Wolfgang.

^ permalink raw reply	[flat|nested] 52+ messages in thread

* RE: [PATCH v2 2/2] can: flexcan: adding platform specific details for LS1021A
  2017-11-16  7:05         ` Wolfgang Grandegger
@ 2017-11-16  7:23           ` ZHU Yi (ST-FIR/ENG1-Zhu)
  2017-11-20 11:11             ` Pankaj Bansal
  0 siblings, 1 reply; 52+ messages in thread
From: ZHU Yi (ST-FIR/ENG1-Zhu) @ 2017-11-16  7:23 UTC (permalink / raw)
  To: Wolfgang Grandegger, Pankaj Bansal, Marc Kleine-Budde, linux-can
  Cc: Varun Sethi, Poonam Aggrwal, Bhupesh Sharma

Hello Pankaj,

>From: Wolfgang Grandegger [mailto:wg@grandegger.com]
>Sent: Thursday, November 16, 2017 3:06 PM
>
>Am 16.11.2017 um 06:34 schrieb Pankaj Bansal:
>> [...]
>>> Please add your IP core to the "FLEXCAN hardware feature flags" table [1] in
>>> the driver. Also please test the transition interrupts for changes in the CAN
>>> error state, see the commits of ZHU Yi
>>> (ST-FIR/ENG1-Zhu) <Yi.Zhu5@cn.bosch.com> on the driver. [2]
>>>
>>
>> I did not understand this quirk (FLEXCAN_QUIRK_BROKEN_PERR_STATE).
>> What does this quirk do ? how do I check if my IP supports it or not ?
>> How do I test this ?
>>
>> Can you please help me to understand ?
>
>It's about reporting CAN error state changes "error-active" -> "warning"
>-> "error-passive" -> "bus-off" and back. The quirk might be required to
>trigger the state-change to "error-passive".

The FLEXCAN_QUIRK_BROKEN_PERR_STATE in conjunction with the
FLEXCAN_QUIRK_BROKEN_WERR_STATE were added for:
1. solve error state transition problems found in some core
2. throttle error interrupt flooding when applicable
due to some core cannot generate state interrupt for error
warning (that's the WERR_STATE stands for) and/or error passive
(that's the PERR_STATE stands for), thus the user space cannot
receive correct state transitions via listening to the SocketCAN socket.

The workaround overcomes the interrupt support shortage by:
1. derive correct state from error counters upon any interrupt.
2. disable/enable error interrupt to minimize the potential
   performance impact caused by error interrupt flooding.

These two quirks need to set according to hardware features, e.g.,
the i.MX28 and i.MX6 set the PERR_STATE quirk because they have the
[TR]WRN_INT connected but no interrupt for error passive. If they
don't have the [TR]WRN_INT too, then both quirks are required.
(PS: As we understand so far, there is no flexcan core lack of error
warning interrupt but have error passive interrupt, so the WERR_STATE
should never been set alone).

>
>You can test such state changes by doing:
>
>1. Send messages without CAN cable connected
>
>2. Short-circuit the CAN low and high signals
>
>Then connect the cable and remove the short-circuit and send messages
>using "cansend" or "cangen". Please also use "ip set link can0 ...
>restart-ms 100" to recover from bus-off automatically.
>
>While testing watch the error messages with the command below and report
>the results to the list.
>
># candump -td -e any,0:0,#FFFFFFFF

The fast way to check whether your IP needs the quirk or not is look
into the reference and find whether it supports the aforementioned
interrupts, if anyone is missing, then the quirk is needed. Please
consult suggestion from Wolfgang about how to test.

Best regards
Yi

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH v2 1/2] can: flexcan: Remodel FlexCAN register r/w APIs for big endian FlexCAN controllers.
  2017-11-16  5:24     ` Pankaj Bansal
@ 2017-11-16 12:04       ` Marc Kleine-Budde
  0 siblings, 0 replies; 52+ messages in thread
From: Marc Kleine-Budde @ 2017-11-16 12:04 UTC (permalink / raw)
  To: Pankaj Bansal, wg, linux-can
  Cc: Varun Sethi, Poonam Aggrwal, Bhupesh Sharma, Sakar Arora


[-- Attachment #1.1: Type: text/plain, Size: 1235 bytes --]

On 11/16/2017 06:24 AM, Pankaj Bansal wrote:
>> What about this:
>>
>> 	/* set defaults */
>> 	if (of_device_is_compatible(pdev->dev.of_node,
>> 				    "fsl,p1010-flexcan")) {
>> 		priv->read = flexcan_read_be;
>> 		priv->write = flexcan_write_be;
>> 	} else {
>> 		priv->read = flexcan_read_le;
>> 		priv->write = flexcan_write_le;
>> 	}
>>
>> 	if (of_device_is_big_endian()) {
>> 		priv->read = flexcan_read_be;
>> 		priv->write = flexcan_write_be;
>> 	} else {
>> 		priv->read = flexcan_read_le;
>> 		priv->write = flexcan_write_le;
>> 	}
>>
> 
> native-endian : Use this if the hardware "self-adjusts"
>    register endianness based on the CPU's configured endianness.

If someone set the wrong endianess, be it native, litte or big, if it's
wrong, it's wrong.

> I don’t see FlexCAN hardware doing that. That is why we should not use 
> of_device_is_big_endian, and only check for "big-endian".

I don't mind.

Marc

-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 52+ messages in thread

* RE: [PATCH v2 2/2] can: flexcan: adding platform specific details for LS1021A
  2017-11-16  7:23           ` ZHU Yi (ST-FIR/ENG1-Zhu)
@ 2017-11-20 11:11             ` Pankaj Bansal
  2017-11-21  2:13               ` ZHU Yi (ST-FIR/ENG1-Zhu)
  0 siblings, 1 reply; 52+ messages in thread
From: Pankaj Bansal @ 2017-11-20 11:11 UTC (permalink / raw)
  To: ZHU Yi (ST-FIR/ENG1-Zhu),
	Wolfgang Grandegger, Marc Kleine-Budde, linux-can
  Cc: Varun Sethi, Poonam Aggrwal, Bhupesh Sharma



> -----Original Message-----
> From: ZHU Yi (ST-FIR/ENG1-Zhu) [mailto:Yi.Zhu5@cn.bosch.com]
> Sent: Thursday, November 16, 2017 12:53 PM
> To: Wolfgang Grandegger <wg@grandegger.com>; Pankaj Bansal
> <pankaj.bansal@nxp.com>; Marc Kleine-Budde <mkl@pengutronix.de>;
> linux-can@vger.kernel.org
> Cc: Varun Sethi <V.Sethi@nxp.com>; Poonam Aggrwal
> <poonam.aggrwal@nxp.com>; Bhupesh Sharma
> <bhupesh.sharma@freescale.com>
> Subject: RE: [PATCH v2 2/2] can: flexcan: adding platform specific details for
> LS1021A
> 
> Hello Pankaj,
> 
> >From: Wolfgang Grandegger [mailto:wg@grandegger.com]
> >Sent: Thursday, November 16, 2017 3:06 PM
> >
> >Am 16.11.2017 um 06:34 schrieb Pankaj Bansal:
> >> [...]
> >>> Please add your IP core to the "FLEXCAN hardware feature flags"
> >>> table [1] in the driver. Also please test the transition interrupts
> >>> for changes in the CAN error state, see the commits of ZHU Yi
> >>> (ST-FIR/ENG1-Zhu) <Yi.Zhu5@cn.bosch.com> on the driver. [2]
> >>>
> >>
> >> I did not understand this quirk (FLEXCAN_QUIRK_BROKEN_PERR_STATE).
> >> What does this quirk do ? how do I check if my IP supports it or not ?
> >> How do I test this ?
> >>
> >> Can you please help me to understand ?
> >
> >It's about reporting CAN error state changes "error-active" -> "warning"
> >-> "error-passive" -> "bus-off" and back. The quirk might be required
> >-> to
> >trigger the state-change to "error-passive".
> 
> The FLEXCAN_QUIRK_BROKEN_PERR_STATE in conjunction with the
> FLEXCAN_QUIRK_BROKEN_WERR_STATE were added for:
> 1. solve error state transition problems found in some core 2. throttle error
> interrupt flooding when applicable due to some core cannot generate state
> interrupt for error warning (that's the WERR_STATE stands for) and/or error
> passive (that's the PERR_STATE stands for), thus the user space cannot
> receive correct state transitions via listening to the SocketCAN socket.
> 
> The workaround overcomes the interrupt support shortage by:
> 1. derive correct state from error counters upon any interrupt.
> 2. disable/enable error interrupt to minimize the potential
>    performance impact caused by error interrupt flooding.
> 
> These two quirks need to set according to hardware features, e.g., the
> i.MX28 and i.MX6 set the PERR_STATE quirk because they have the
> [TR]WRN_INT connected but no interrupt for error passive. If they don't have
> the [TR]WRN_INT too, then both quirks are required.
> (PS: As we understand so far, there is no flexcan core lack of error warning
> interrupt but have error passive interrupt, so the WERR_STATE should never
> been set alone).
> 

Thank you Zhu Yi for this explanation. This helped me in understanding the quirks.
Is there any flexcan core which generates passive state interrupt ?
The reason I ask this is because I see in flexcan doc :

The module has many interrupt sources: interrupts due to message buffers and interrupts
due to the ORed interrupts from MBs, Bus Off, Error, Tx Warning, and Rx Warning.

Also in flexcan.c :
#define FLEXCAN_ESR_ALL_INT \
	(FLEXCAN_ESR_TWRN_INT | FLEXCAN_ESR_RWRN_INT | \
	 FLEXCAN_ESR_BOFF_INT | FLEXCAN_ESR_ERR_INT)

I don't see (in document or in code), if passive state interrupts are even generated ?
I see that we can detect passive state using ESR[FLTCONF]  = 01.
But I think we need to rely on ERROR interrupts to do that (even if the BERR_REPORTING is off).

Please correct me if I am wrong in my understanding.

> >
> >You can test such state changes by doing:
> >
> >1. Send messages without CAN cable connected
> >
> >2. Short-circuit the CAN low and high signals
> >
> >Then connect the cable and remove the short-circuit and send messages
> >using "cansend" or "cangen". Please also use "ip set link can0 ...
> >restart-ms 100" to recover from bus-off automatically.
> >
> >While testing watch the error messages with the command below and
> >report the results to the list.
> >
> ># candump -td -e any,0:0,#FFFFFFFF
> 
> The fast way to check whether your IP needs the quirk or not is look into the
> reference and find whether it supports the aforementioned interrupts, if
> anyone is missing, then the quirk is needed. Please consult suggestion from
> Wolfgang about how to test.
> 

Thank you Wolfgang. With the steps you mentioned and some debug logs I see that LS1021A
supports [TR]WRN_INT.

root@TinyDistro:~# ip link set can0 up type can bitrate 125000 restart-ms 100 berr-reporting off
[  596.117066] IPv6: ADDRCONF(NETDEV_CHANGE): can0: link becomes ready
root@TinyDistro:~# ip link set can1 up type can bitrate 125000 restart-ms 100 berr-reporting off
[  600.724547] IPv6: ADDRCONF(NETDEV_CHANGE): can1: link becomes ready
root@TinyDistro:~# candump -td -e any,0:0,#FFFFFFFF &
[1] 632
root@TinyDistro:~# cansend can0 5A1#123412341234
root@TinyDistro:~# [  647.522941] flexcan_irq 804 reg_esr=0x00062242, reg_ecr=0x00000060, reg_ctrl=0x4a31ac55
 (000.000000)  can0  20000004   [8]  00 08 00 00 00 00 00 00   ERRORFRAME
        controller-problem{tx-error-warning}

> Best regards
> Yi

^ permalink raw reply	[flat|nested] 52+ messages in thread

* RE: [PATCH v2 2/2] can: flexcan: adding platform specific details for LS1021A
  2017-11-20 11:11             ` Pankaj Bansal
@ 2017-11-21  2:13               ` ZHU Yi (ST-FIR/ENG1-Zhu)
  2017-11-21  2:37                 ` Pankaj Bansal
  2017-11-21 12:43                 ` Marc Kleine-Budde
  0 siblings, 2 replies; 52+ messages in thread
From: ZHU Yi (ST-FIR/ENG1-Zhu) @ 2017-11-21  2:13 UTC (permalink / raw)
  To: Pankaj Bansal, Wolfgang Grandegger, Marc Kleine-Budde, linux-can
  Cc: Varun Sethi, Poonam Aggrwal, Bhupesh Sharma

Hello Pankaj,

>From: Pankaj Bansal [mailto:pankaj.bansal@nxp.com]
>Sent: Monday, November 20, 2017 7:11 PM
> [...]
>Thank you Zhu Yi for this explanation. This helped me in understanding the quirks.
>Is there any flexcan core which generates passive state interrupt ?
I'm afraid so far no known flexcan core supports it.

>The reason I ask this is because I see in flexcan doc :
>
>The module has many interrupt sources: interrupts due to message buffers and interrupts
>due to the ORed interrupts from MBs, Bus Off, Error, Tx Warning, and Rx Warning.
>
>Also in flexcan.c :
>#define FLEXCAN_ESR_ALL_INT \
>	(FLEXCAN_ESR_TWRN_INT | FLEXCAN_ESR_RWRN_INT | \
>	 FLEXCAN_ESR_BOFF_INT | FLEXCAN_ESR_ERR_INT)
>
>I don't see (in document or in code), if passive state interrupts are even generated ?
>I see that we can detect passive state using ESR[FLTCONF]  = 01.
>But I think we need to rely on ERROR interrupts to do that (even if the BERR_REPORTING is off).
>
>Please correct me if I am wrong in my understanding.
Yes, you're right. We use the error interrupts to report active -> warning -> passive,
and use the tx/rx interrupts to report passive -> warning -> active.

>
> [...]
>Thank you Wolfgang. With the steps you mentioned and some debug logs I see that LS1021A
>supports [TR]WRN_INT.
>
>root@TinyDistro:~# ip link set can0 up type can bitrate 125000 restart-ms 100 berr-reporting off
>[  596.117066] IPv6: ADDRCONF(NETDEV_CHANGE): can0: link becomes ready
>root@TinyDistro:~# ip link set can1 up type can bitrate 125000 restart-ms 100 berr-reporting off
>[  600.724547] IPv6: ADDRCONF(NETDEV_CHANGE): can1: link becomes ready
>root@TinyDistro:~# candump -td -e any,0:0,#FFFFFFFF &
>[1] 632
>root@TinyDistro:~# cansend can0 5A1#123412341234
>root@TinyDistro:~# [  647.522941] flexcan_irq 804 reg_esr=0x00062242, reg_ecr=0x00000060, reg_ctrl=0x4a31ac55
> (000.000000)  can0  20000004   [8]  00 08 00 00 00 00 00 00   ERRORFRAME
>        controller-problem{tx-error-warning}
Seems it needs the FLEXCAN_QUIRK_BROKEN_PERR_STATE. After that, above
steps should be able to report the correct state - error passive, and
all the scenarios Wolfgang mentioned should also works fine.

Please be aware that you need to send multiple can frames (manually
with cansend or automatically with cangen) to get the state back to
warning and active if removed the error condition on the bus.

Best regards
Yi

^ permalink raw reply	[flat|nested] 52+ messages in thread

* RE: [PATCH v2 2/2] can: flexcan: adding platform specific details for LS1021A
  2017-11-21  2:13               ` ZHU Yi (ST-FIR/ENG1-Zhu)
@ 2017-11-21  2:37                 ` Pankaj Bansal
  2017-11-21  3:31                   ` ZHU Yi (ST-FIR/ENG1-Zhu)
  2017-11-21 12:43                 ` Marc Kleine-Budde
  1 sibling, 1 reply; 52+ messages in thread
From: Pankaj Bansal @ 2017-11-21  2:37 UTC (permalink / raw)
  To: ZHU Yi (ST-FIR/ENG1-Zhu),
	Wolfgang Grandegger, Marc Kleine-Budde, linux-can
  Cc: Varun Sethi, Poonam Aggrwal, Bhupesh Sharma



> -----Original Message-----
> From: ZHU Yi (ST-FIR/ENG1-Zhu) [mailto:Yi.Zhu5@cn.bosch.com]
> Sent: Tuesday, November 21, 2017 7:43 AM
> To: Pankaj Bansal <pankaj.bansal@nxp.com>; Wolfgang Grandegger
> <wg@grandegger.com>; Marc Kleine-Budde <mkl@pengutronix.de>; linux-
> can@vger.kernel.org
> Cc: Varun Sethi <V.Sethi@nxp.com>; Poonam Aggrwal
> <poonam.aggrwal@nxp.com>; Bhupesh Sharma
> <bhupesh.sharma@freescale.com>
> Subject: RE: [PATCH v2 2/2] can: flexcan: adding platform specific details for
> LS1021A
> 
> Hello Pankaj,
> 
> >From: Pankaj Bansal [mailto:pankaj.bansal@nxp.com]
> >Sent: Monday, November 20, 2017 7:11 PM  [...] Thank you Zhu Yi for
> >this explanation. This helped me in understanding the quirks.
> >Is there any flexcan core which generates passive state interrupt ?
> I'm afraid so far no known flexcan core supports it.
> 
> >The reason I ask this is because I see in flexcan doc :
> >
> >The module has many interrupt sources: interrupts due to message
> >buffers and interrupts due to the ORed interrupts from MBs, Bus Off, Error,
> Tx Warning, and Rx Warning.
> >
> >Also in flexcan.c :
> >#define FLEXCAN_ESR_ALL_INT \
> >	(FLEXCAN_ESR_TWRN_INT | FLEXCAN_ESR_RWRN_INT | \
> >	 FLEXCAN_ESR_BOFF_INT | FLEXCAN_ESR_ERR_INT)
> >
> >I don't see (in document or in code), if passive state interrupts are even
> generated ?
> >I see that we can detect passive state using ESR[FLTCONF]  = 01.
> >But I think we need to rely on ERROR interrupts to do that (even if the
> BERR_REPORTING is off).
> >
> >Please correct me if I am wrong in my understanding.
> Yes, you're right. We use the error interrupts to report active -> warning ->
> passive, and use the tx/rx interrupts to report passive -> warning -> active.
>

Thanks Zhu Yi. In that case do we even need to put these changes in a quirk?
Shouldn't this code be generic flexcan code, irrespective of the platform?
 
> >
> > [...]
> >Thank you Wolfgang. With the steps you mentioned and some debug logs I
> >see that LS1021A supports [TR]WRN_INT.
> >
> >root@TinyDistro:~# ip link set can0 up type can bitrate 125000
> >restart-ms 100 berr-reporting off [  596.117066] IPv6:
> >ADDRCONF(NETDEV_CHANGE): can0: link becomes ready
> root@TinyDistro:~# ip
> >link set can1 up type can bitrate 125000 restart-ms 100 berr-reporting
> >off [  600.724547] IPv6: ADDRCONF(NETDEV_CHANGE): can1: link becomes
> >ready root@TinyDistro:~# candump -td -e any,0:0,#FFFFFFFF & [1] 632
> >root@TinyDistro:~# cansend can0 5A1#123412341234 root@TinyDistro:~# [
> >647.522941] flexcan_irq 804 reg_esr=0x00062242, reg_ecr=0x00000060,
> reg_ctrl=0x4a31ac55
> > (000.000000)  can0  20000004   [8]  00 08 00 00 00 00 00 00   ERRORFRAME
> >        controller-problem{tx-error-warning}
> Seems it needs the FLEXCAN_QUIRK_BROKEN_PERR_STATE. After that, above
> steps should be able to report the correct state - error passive, and all the
> scenarios Wolfgang mentioned should also works fine.
> 
> Please be aware that you need to send multiple can frames (manually with
> cansend or automatically with cangen) to get the state back to warning and
> active if removed the error condition on the bus.
> 

I will test this after PERR_STATE quirk. But as I mentioned above, in my opinion
we should remove FLEXCAN_QUIRK_BROKEN_PERR_STATE, and make these changes
common for all platforms.

> Best regards
> Yi

^ permalink raw reply	[flat|nested] 52+ messages in thread

* RE: [PATCH v2 2/2] can: flexcan: adding platform specific details for LS1021A
  2017-11-21  2:37                 ` Pankaj Bansal
@ 2017-11-21  3:31                   ` ZHU Yi (ST-FIR/ENG1-Zhu)
  2017-11-21 10:01                     ` Pankaj Bansal
  0 siblings, 1 reply; 52+ messages in thread
From: ZHU Yi (ST-FIR/ENG1-Zhu) @ 2017-11-21  3:31 UTC (permalink / raw)
  To: Pankaj Bansal, Wolfgang Grandegger, Marc Kleine-Budde, linux-can
  Cc: Varun Sethi, Poonam Aggrwal, Bhupesh Sharma

Hello Pankaj,

>From: Pankaj Bansal [mailto:pankaj.bansal@nxp.com]
>Sent: Tuesday, November 21, 2017 10:38 AM
> [...]
>
>Thanks Zhu Yi. In that case do we even need to put these changes in a quirk?
>Shouldn't this code be generic flexcan code, irrespective of the platform?
If in the future version of flexcan supports the complete set of
state interrupts, then the new core which don't need the workaround
can switch it off easily via not specifying these quirks.

Make it irrespective of the platform will add the unnecessary overhead
to the new core (although the overhead is little).

>
> [...]
>
>I will test this after PERR_STATE quirk. But as I mentioned above, in my opinion
>we should remove FLEXCAN_QUIRK_BROKEN_PERR_STATE, and make these changes
>common for all platforms.
Thanks, I'm looking forward to the test results. As explained above,
we are still in the hope that FLEXCAN might improve in the future. :)

Best regards
Yi

^ permalink raw reply	[flat|nested] 52+ messages in thread

* RE: [PATCH v2 2/2] can: flexcan: adding platform specific details for LS1021A
  2017-11-21  3:31                   ` ZHU Yi (ST-FIR/ENG1-Zhu)
@ 2017-11-21 10:01                     ` Pankaj Bansal
  2017-11-23  7:23                       ` ZHU Yi (ST-FIR/ENG1-Zhu)
  0 siblings, 1 reply; 52+ messages in thread
From: Pankaj Bansal @ 2017-11-21 10:01 UTC (permalink / raw)
  To: ZHU Yi (ST-FIR/ENG1-Zhu),
	Wolfgang Grandegger, Marc Kleine-Budde, linux-can
  Cc: Varun Sethi, Poonam Aggrwal



> -----Original Message-----
> From: ZHU Yi (ST-FIR/ENG1-Zhu) [mailto:Yi.Zhu5@cn.bosch.com]
> Sent: Tuesday, November 21, 2017 9:01 AM
> To: Pankaj Bansal <pankaj.bansal@nxp.com>; Wolfgang Grandegger
> <wg@grandegger.com>; Marc Kleine-Budde <mkl@pengutronix.de>; linux-
> can@vger.kernel.org
> Cc: Varun Sethi <V.Sethi@nxp.com>; Poonam Aggrwal
> <poonam.aggrwal@nxp.com>; Bhupesh Sharma
> <bhupesh.sharma@freescale.com>
> Subject: RE: [PATCH v2 2/2] can: flexcan: adding platform specific details for
> LS1021A
> 
> Hello Pankaj,
> 
> >From: Pankaj Bansal [mailto:pankaj.bansal@nxp.com]
> >Sent: Tuesday, November 21, 2017 10:38 AM  [...]
> >
> >Thanks Zhu Yi. In that case do we even need to put these changes in a
> quirk?
> >Shouldn't this code be generic flexcan code, irrespective of the platform?
> If in the future version of flexcan supports the complete set of state
> interrupts, then the new core which don't need the workaround can switch it
> off easily via not specifying these quirks.
> 
> Make it irrespective of the platform will add the unnecessary overhead to the
> new core (although the overhead is little).

I understand. It's nice that you have thought of future hardware enhancements.

> 
> >
> > [...]
> >
> >I will test this after PERR_STATE quirk. But as I mentioned above, in
> >my opinion we should remove FLEXCAN_QUIRK_BROKEN_PERR_STATE, and
> make
> >these changes common for all platforms.
> Thanks, I'm looking forward to the test results. As explained above, we are
> still in the hope that FLEXCAN might improve in the future. :)
> 

Without PERR_STATE :

root@TinyDistro:~# ip link set can0 up type can bitrate 125000 restart-ms 100 berr-reporting off
[   22.507345] IPv6: ADDRCONF(NETDEV_CHANGE): can0: link becomes ready
root@TinyDistro:~# ip link set can1 up type can bitrate 125000 restart-ms 100 berr-reporting off
[   30.934669] IPv6: ADDRCONF(NETDEV_CHANGE): can1: link becomes ready
root@TinyDistro:~# candump -td -e any,0:0,#FFFFFFFF &
[1] 617
root@TinyDistro:~# cangen can0 -D 11223344DEADBEEF -L 8
[   48.684839] flexcan_irq 804 reg_esr=0x00062242, reg_ecr=0x00000060, reg_ctrl=0x4a31ac55
 (000.000000)  can0  20000004   [8]  00 08 00 00 00 00 00 00   ERRORFRAME
        controller-problem{tx-error-warning}
write: No buffer space available
        **********  Short L and H signals of CAN ************
root@TinyDistro:~# [  228.338038] flexcan_irq 804 reg_esr=0x00006036, reg_ecr=0x00000000, reg_ctrl=0x4a31ac55
 (179.653204)  can0  20000040   [8]  00 00 00 00 00 00 00 00   ERRORFRAME
        bus-off
[  228.438287] IPv6: ADDRCONF(NETDEV_CHANGE): can0: link becomes ready
 (000.092122)  can0  20000100   [8]  00 00 00 00 00 00 00 00   ERRORFRAME
        restarted-after-bus-off

With PERR_STATE :

root@TinyDistro:~# ip link set can0 up type can bitrate 125000 restart-ms 100 berr-reporting off
[   31.997286] IPv6: ADDRCONF(NETDEV_CHANGE): can0: link becomes ready
root@TinyDistro:~# ip link set can1 up type can bitrate 125000 restart-ms 100 berr-reporting off
[   40.934824] IPv6: ADDRCONF(NETDEV_CHANGE): can1: link becomes ready
root@TinyDistro:~# candump -td -e any,0:0,#FFFFFFFF &
[1] 620
root@TinyDistro:~# cangen can0 -D 11223344DEADBEEF -L 8
[   59.314920] flexcan_irq 805 reg_esr=0x00062242, reg_ecr=0x00000060, reg_ctrl=0x4a31ac55
 (000.000000)  [   59.323862] flexcan_irq 805 reg_esr=0x00042252, reg_ecr=0x00000080, reg_ctrl=0x4a31ec55
can0  20000004   [8]  00 08 00 00 00 00 00 00   ERRORFRAME
        controller-problem{tx-error-warning}
 (000.009673)  can0  20000004   [8]  00 20 00 00 00 00 00 00   ERRORFRAME
        controller-problem{tx-error-passive}
write: No buffer space available
        **********  Short L and H signals of CAN ************
root@TinyDistro:~# [   87.995878] flexcan_irq 805 reg_esr=0x00006036, reg_ecr=0x00000000, reg_ctrl=0x4a31ac55
 (028.671291)  can0  20000040   [8]  00 00 00 00 00 00 00 00   ERRORFRAME
        bus-off
 (000.094305)  [   88.098464] IPv6: ADDRCONF(NETDEV_CHANGE): can0: link becomes ready
can0  20000100   [8]  00 00 00 00 00 00 00 00   ERRORFRAME
        restarted-after-bus-off

> Best regards
> Yi

^ permalink raw reply	[flat|nested] 52+ messages in thread

* RE: [PATCH v2 1/2] can: flexcan: Remodel FlexCAN register r/w APIs for big endian FlexCAN controllers.
  2017-11-14 15:24   ` [PATCH v2 1/2] can: flexcan: Remodel FlexCAN register r/w APIs for big endian FlexCAN controllers Marc Kleine-Budde
  2017-11-16  5:24     ` Pankaj Bansal
@ 2017-11-21 12:18     ` Pankaj Bansal
  2017-11-21 12:38       ` Marc Kleine-Budde
  1 sibling, 1 reply; 52+ messages in thread
From: Pankaj Bansal @ 2017-11-21 12:18 UTC (permalink / raw)
  To: Marc Kleine-Budde, wg, linux-can; +Cc: Varun Sethi, Poonam Aggrwal

> -----Original Message-----
> From: Marc Kleine-Budde [mailto:mkl@pengutronix.de]
> Sent: Tuesday, November 14, 2017 8:54 PM
> To: Pankaj Bansal <pankaj.bansal@nxp.com>; wg@grandegger.com; linux-
> can@vger.kernel.org
> Cc: Varun Sethi <V.Sethi@nxp.com>; Poonam Aggrwal
> <poonam.aggrwal@nxp.com>; Bhupesh Sharma
> <bhupesh.sharma@freescale.com>; Sakar Arora
> <Sakar.Arora@freescale.com>
> Subject: Re: [PATCH v2 1/2] can: flexcan: Remodel FlexCAN register r/w APIs
> for big endian FlexCAN controllers.
> 
> On 11/14/2017 12:56 PM, Pankaj Bansal wrote:
> > The FlexCAN driver assumed that FlexCAN controller is big endian for
> > powerpc architecture and little endian for other architectures.
> >
> > But this may not be the case. FlexCAN controller can be little or big
> > endian on any architecture. For e.g. NXP LS1021A ARM based SOC has big
> > endian FlexCAN controller.
> >
> > Therefore, the driver has been modified to add a provision for both
> > types of controllers using an additional device tree property. Big
> > Endian controllers should have "big-endian" set in the device tree.
> >
> > This is the standard practice followed in linux. for more info check:
> > Documentation/devicetree/bindings/common-properties.txt
> 
> Looks better now. Please add note to
> "Documentation/devicetree/bindings/net/can/fsl-flexcan.txt" that we now
> support endianess and state the default endianess.
> 
> What about:
> 
> On a "fsl,p1010-flexcan" device BE is default, on all other devices LE is.
> 
> Please remove the existing "fsl,p1010-flexcan" from "arch/arm/boot/dts"
> and add fsl,imx25-flexcan, fsl,imx35-flexcan and fsl,imx53-flexcan support to
> the driver.
> 

@Marc Kleine-Budde :
Should we keep 
.compatible = "fsl,imx25-flexcan", .data = &fsl_p1010_devtype_data,
or 
.compatible = "fsl,imx25-flexcan", .data = &fsl_imx25_devtype_data,

in flexcan.c ? right now imx25, imx35, imx53 use same dev_data as p1010.
So If any quirk is added to p1010, it's also applicable for other 3 platforms.
Once we remove p1010 compatible from their device-tree, should we keep
The dev_data as p1010 or make it separate too ?

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH v2 1/2] can: flexcan: Remodel FlexCAN register r/w APIs for big endian FlexCAN controllers.
  2017-11-21 12:18     ` Pankaj Bansal
@ 2017-11-21 12:38       ` Marc Kleine-Budde
  0 siblings, 0 replies; 52+ messages in thread
From: Marc Kleine-Budde @ 2017-11-21 12:38 UTC (permalink / raw)
  To: Pankaj Bansal, wg, linux-can; +Cc: Varun Sethi, Poonam Aggrwal


[-- Attachment #1.1: Type: text/plain, Size: 1417 bytes --]

On 11/21/2017 01:18 PM, Pankaj Bansal wrote:
>> Looks better now. Please add note to
>> "Documentation/devicetree/bindings/net/can/fsl-flexcan.txt" that we now
>> support endianess and state the default endianess.
>>
>> What about:
>>
>> On a "fsl,p1010-flexcan" device BE is default, on all other devices LE is.
>>
>> Please remove the existing "fsl,p1010-flexcan" from "arch/arm/boot/dts"
>> and add fsl,imx25-flexcan, fsl,imx35-flexcan and fsl,imx53-flexcan support to
>> the driver.
> 
> @Marc Kleine-Budde :
> Should we keep 
> .compatible = "fsl,imx25-flexcan", .data = &fsl_p1010_devtype_data,
> or 
> .compatible = "fsl,imx25-flexcan", .data = &fsl_imx25_devtype_data,
> 
> in flexcan.c ? right now imx25, imx35, imx53 use same dev_data as p1010.

Yes, keep it this way.

> So If any quirk is added to p1010, it's also applicable for other 3
> platforms.

Probably... I've never had a p1010 in my hands.

> Once we remove p1010 compatible from their device-tree, should we
> keep The dev_data as p1010 or make it separate too ?
Keep it until there is a change makes separating them necessary.

Marc

-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH v2 2/2] can: flexcan: adding platform specific details for LS1021A
  2017-11-21  2:13               ` ZHU Yi (ST-FIR/ENG1-Zhu)
  2017-11-21  2:37                 ` Pankaj Bansal
@ 2017-11-21 12:43                 ` Marc Kleine-Budde
  2017-11-22  2:56                   ` ZHU Yi (ST-FIR/ENG1-Zhu)
  1 sibling, 1 reply; 52+ messages in thread
From: Marc Kleine-Budde @ 2017-11-21 12:43 UTC (permalink / raw)
  To: ZHU Yi (ST-FIR/ENG1-Zhu), Pankaj Bansal, Wolfgang Grandegger, linux-can
  Cc: Varun Sethi, Poonam Aggrwal, Bhupesh Sharma


[-- Attachment #1.1: Type: text/plain, Size: 1784 bytes --]

On 11/21/2017 03:13 AM, ZHU Yi (ST-FIR/ENG1-Zhu) wrote:
> Hello Pankaj,
> 
>> From: Pankaj Bansal [mailto:pankaj.bansal@nxp.com]
>> Sent: Monday, November 20, 2017 7:11 PM
>> [...]
>> Thank you Zhu Yi for this explanation. This helped me in understanding the quirks.
>> Is there any flexcan core which generates passive state interrupt ?

> I'm afraid so far no known flexcan core supports it.

Should we update the table and add a "IRQ Err Passive" no for all cores?

>  * Below is some version info we got:
>  *    SOC   Version   IP-Version  Glitch- [TR]WRN_INT IRQ Err Memory err RTR re-
>  *                                Filter? connected?  Passive detection  ception in MB
>  *   MX25  FlexCAN2  03.00.00.00     no        no         ?       no        no
>  *   MX28  FlexCAN2  03.00.04.00    yes       yes        no       no        no
>  *   MX35  FlexCAN2  03.00.00.00     no        no         ?       no        no
>  *   MX53  FlexCAN2  03.00.00.00    yes        no        no       no        no
>  *   MX6s  FlexCAN3  10.00.12.00    yes       yes        no       no       yes
>  *   VF610 FlexCAN3  ?               no       yes         ?      yes       yes?

And does it make sense to add "FLEXCAN_QUIRK_BROKEN_PERR_STATE" to the
vf610, too?

> static const struct flexcan_devtype_data fsl_vf610_devtype_data = {
> 	.quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_ENABLE_EACEN_RRS |
> 		FLEXCAN_QUIRK_DISABLE_MECR | FLEXCAN_QUIRK_USE_OFF_TIMESTAMP,
> };

Marc

-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 52+ messages in thread

* RE: [PATCH v2 2/2] can: flexcan: adding platform specific details for LS1021A
  2017-11-21 12:43                 ` Marc Kleine-Budde
@ 2017-11-22  2:56                   ` ZHU Yi (ST-FIR/ENG1-Zhu)
  2017-11-22  6:27                     ` Pankaj Bansal
  2017-11-22 11:59                     ` Marc Kleine-Budde
  0 siblings, 2 replies; 52+ messages in thread
From: ZHU Yi (ST-FIR/ENG1-Zhu) @ 2017-11-22  2:56 UTC (permalink / raw)
  To: Marc Kleine-Budde, Pankaj Bansal, Wolfgang Grandegger, linux-can
  Cc: Varun Sethi, Poonam Aggrwal, Bhupesh Sharma

Hello Marc,

>From: Marc Kleine-Budde [mailto:mkl@pengutronix.de]
>Sent: Tuesday, November 21, 2017 8:44 PM
>
> [...]
>> I'm afraid so far no known flexcan core supports it.
>
>Should we update the table and add a "IRQ Err Passive" no for all cores?
By look into the reference manual of MX25[1], MX35[2] and VF610[3],
it turns out that none of them support the error passive interrupt.
So we should update the "IRQ Err Passive" to no for all cores.

Interestingly, seems the new RM of MX25 (Rev.2) and MX35 (Rev.3)
states that both core have the [TR]WRN_INT connected, so I guess the
no in that column were added for the legacy core. However, as the
driver also needs to work with the legacy core, and they share the
same devtype_data as p1010, so I think we should leave it as it is.

>
>>  * Below is some version info we got:
>>  *    SOC   Version   IP-Version  Glitch- [TR]WRN_INT IRQ Err Memory err RTR re-
>>  *                                Filter? connected?  Passive detection  ception in MB
>>  *   MX25  FlexCAN2  03.00.00.00     no        no         ?       no        no
>>  *   MX28  FlexCAN2  03.00.04.00    yes       yes        no       no        no
>>  *   MX35  FlexCAN2  03.00.00.00     no        no         ?       no        no
>>  *   MX53  FlexCAN2  03.00.00.00    yes        no        no       no        no
>>  *   MX6s  FlexCAN3  10.00.12.00    yes       yes        no       no       yes
>>  *   VF610 FlexCAN3  ?               no       yes         ?      yes       yes?
>
>And does it make sense to add "FLEXCAN_QUIRK_BROKEN_PERR_STATE" to the
>vf610, too?
I think vf610 will need this quirk to report correct state transitions.
The reason last time we do not touch this is because neither Wolfgang
nor I had access to vf610, so we can only test with MX28, MX53 and MX6.
We thought someone will speak out if they meet problems with this core,
and then they can help to fix and test it.

@Marc, @Wolfgang,
What do you think? Or shall we fix first and then wait?

@Pankaj, as you are currently working on patch this driver, is it
possible that you can help to create patch for the table and/or the
PERR_STATE quirk fix for vf610 in case required? Thanks!

Best regards
Yi

[1] https://www.nxp.com/docs/en/reference-manual/IMX25RM.pdf
[2] https://www.nxp.com/docs/en/reference-manual/IMX35RM.pdf
[3] https://www.nxp.com/docs/en/reference-manual/VFXXXRM.pdf

^ permalink raw reply	[flat|nested] 52+ messages in thread

* RE: [PATCH v2 2/2] can: flexcan: adding platform specific details for LS1021A
  2017-11-22  2:56                   ` ZHU Yi (ST-FIR/ENG1-Zhu)
@ 2017-11-22  6:27                     ` Pankaj Bansal
  2017-11-22 13:56                       ` Marc Kleine-Budde
  2017-11-22 11:59                     ` Marc Kleine-Budde
  1 sibling, 1 reply; 52+ messages in thread
From: Pankaj Bansal @ 2017-11-22  6:27 UTC (permalink / raw)
  To: ZHU Yi (ST-FIR/ENG1-Zhu),
	Marc Kleine-Budde, Wolfgang Grandegger, linux-can
  Cc: Varun Sethi, Poonam Aggrwal

Hi ZHU Yi,


> From: ZHU Yi (ST-FIR/ENG1-Zhu) [mailto:Yi.Zhu5@cn.bosch.com]
> Sent: Wednesday, November 22, 2017 8:27 AM
> > [...]
> @Pankaj, as you are currently working on patch this driver, is it possible that
> you can help to create patch for the table and/or the PERR_STATE quirk fix
> for vf610 in case required? Thanks!
> 

I am afraid I also do not have access to vf610. I have access to p1010.

Regards,
Pankaj Bansal


^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH v2 2/2] can: flexcan: adding platform specific details for LS1021A
  2017-11-22  2:56                   ` ZHU Yi (ST-FIR/ENG1-Zhu)
  2017-11-22  6:27                     ` Pankaj Bansal
@ 2017-11-22 11:59                     ` Marc Kleine-Budde
  2017-11-23  1:26                       ` ZHU Yi (ST-FIR/ENG1-Zhu)
       [not found]                       ` <CALw8SCUGuCmq+S_9-o-ZDYJuASveuj71WH97jYsEvNZX2N5ZXA@mail.gmail.com>
  1 sibling, 2 replies; 52+ messages in thread
From: Marc Kleine-Budde @ 2017-11-22 11:59 UTC (permalink / raw)
  To: ZHU Yi (ST-FIR/ENG1-Zhu), Pankaj Bansal, Wolfgang Grandegger, linux-can
  Cc: Varun Sethi, Poonam Aggrwal, Stefan Agner


[-- Attachment #1.1: Type: text/plain, Size: 3731 bytes --]

On 11/22/2017 03:56 AM, ZHU Yi (ST-FIR/ENG1-Zhu) wrote:
>>> I'm afraid so far no known flexcan core supports it.
>>
>> Should we update the table and add a "IRQ Err Passive" no for all
>> cores?
> By look into the reference manual of MX25[1], MX35[2] and VF610[3],
> it turns out that none of them support the error passive interrupt.
> So we should update the "IRQ Err Passive" to no for all cores.

I'll create a patch.

> Interestingly, seems the new RM of MX25 (Rev.2) and MX35 (Rev.3)
> states that both core have the [TR]WRN_INT connected, so I guess the
> no in that column were added for the legacy core.

What do you mean by connected exactly?

As fas as I know these IP cores have these interrupts lines, but they
are not properly wired to the IRQ line that leaves the IP core. To quote
Shawn Guo from the discussion back in 2012:

>> From what I can tell, i.MX35, i.MX51 and i.MX53 use the same version,
>> so they should all have the bug.  And for i.MX6Q, since it uses a newer
>> version even than i.MX28, I would believe it's affected by the bug.
>> But I'm copying Dong who should have better knowledge about this to
>> confirm.

Further Dong Aisheng says:

>> Our IC owner double checked the MX35 and MX53 IP and found the
>> RX_WARN & TX_WARN Interrupt source actually are not connected to
>> ARM. That means flexcan will not trigger interrupt to ARM core even
>> RX_WARN or TX_WARN Happens. This may be the root cause that why you
>> cannot see RX_WARN interrupt if not enable bus error interrupt on
>> mx35. He also checked that mx6q has the rx/tx warning interrupt
>> connected to arm. So we guess mx6q does not have this issue. 
>> Anyway, we can test to confirm.

> However, as the driver also needs to work with the legacy core, and
> they share the same devtype_data as p1010, so I think we should leave
> it as it is.

>>>  * Below is some version info we got:
>>>  *    SOC   Version   IP-Version  Glitch- [TR]WRN_INT IRQ Err Memory err RTR re-
>>>  *                                Filter? connected?  Passive detection  ception in MB
>>>  *   MX25  FlexCAN2  03.00.00.00     no        no         ?       no        no
>>>  *   MX28  FlexCAN2  03.00.04.00    yes       yes        no       no        no
>>>  *   MX35  FlexCAN2  03.00.00.00     no        no         ?       no        no
>>>  *   MX53  FlexCAN2  03.00.00.00    yes        no        no       no        no
>>>  *   MX6s  FlexCAN3  10.00.12.00    yes       yes        no       no       yes
>>>  *   VF610 FlexCAN3  ?               no       yes         ?      yes       yes?
>>
>> And does it make sense to add "FLEXCAN_QUIRK_BROKEN_PERR_STATE" to the
>> vf610, too?

> I think vf610 will need this quirk to report correct state transitions.
> The reason last time we do not touch this is because neither Wolfgang
> nor I had access to vf610, so we can only test with MX28, MX53 and MX6.
> We thought someone will speak out if they meet problems with this core,
> and then they can help to fix and test it.

Cc'ed Stefan Agner - maybe he has access to this SoC.

> @Marc, @Wolfgang,
> What do you think? Or shall we fix first and then wait?

Let's wait if Stefan can test, otherwise just fix.

> @Pankaj, as you are currently working on patch this driver, is it
> possible that you can help to create patch for the table and/or the
> PERR_STATE quirk fix for vf610 in case required? Thanks!
Marc

-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH v2 2/2] can: flexcan: adding platform specific details for LS1021A
  2017-11-22  6:27                     ` Pankaj Bansal
@ 2017-11-22 13:56                       ` Marc Kleine-Budde
  0 siblings, 0 replies; 52+ messages in thread
From: Marc Kleine-Budde @ 2017-11-22 13:56 UTC (permalink / raw)
  To: Pankaj Bansal, ZHU Yi (ST-FIR/ENG1-Zhu), Wolfgang Grandegger, linux-can
  Cc: Varun Sethi, Poonam Aggrwal


[-- Attachment #1.1: Type: text/plain, Size: 797 bytes --]

On 11/22/2017 07:27 AM, Pankaj Bansal wrote:
> Hi ZHU Yi,
> 
> 
>> From: ZHU Yi (ST-FIR/ENG1-Zhu) [mailto:Yi.Zhu5@cn.bosch.com]
>> Sent: Wednesday, November 22, 2017 8:27 AM
>>> [...]
>> @Pankaj, as you are currently working on patch this driver, is it possible that
>> you can help to create patch for the table and/or the PERR_STATE quirk fix
>> for vf610 in case required? Thanks!
>>
> 
> I am afraid I also do not have access to vf610. I have access to p1010.

Please go ahead and test there.

Marc

-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 52+ messages in thread

* RE: [PATCH v2 2/2] can: flexcan: adding platform specific details for LS1021A
  2017-11-22 11:59                     ` Marc Kleine-Budde
@ 2017-11-23  1:26                       ` ZHU Yi (ST-FIR/ENG1-Zhu)
       [not found]                       ` <CALw8SCUGuCmq+S_9-o-ZDYJuASveuj71WH97jYsEvNZX2N5ZXA@mail.gmail.com>
  1 sibling, 0 replies; 52+ messages in thread
From: ZHU Yi (ST-FIR/ENG1-Zhu) @ 2017-11-23  1:26 UTC (permalink / raw)
  To: Marc Kleine-Budde, Pankaj Bansal, Wolfgang Grandegger, linux-can
  Cc: Varun Sethi, Poonam Aggrwal, Stefan Agner

Hello Marc,

>From: Marc Kleine-Budde [mailto:mkl@pengutronix.de]
>Sent: Wednesday, November 22, 2017 8:00 PM
>
>On 11/22/2017 03:56 AM, ZHU Yi (ST-FIR/ENG1-Zhu) wrote:
>>>> I'm afraid so far no known flexcan core supports it.
>>>
>>> Should we update the table and add a "IRQ Err Passive" no for all
>>> cores?
>> By look into the reference manual of MX25[1], MX35[2] and VF610[3],
>> it turns out that none of them support the error passive interrupt.
>> So we should update the "IRQ Err Passive" to no for all cores.
>
>I'll create a patch.
Thanks! :)

>
>> Interestingly, seems the new RM of MX25 (Rev.2) and MX35 (Rev.3)
>> states that both core have the [TR]WRN_INT connected, so I guess the
>> no in that column were added for the legacy core.
>
>What do you mean by connected exactly?
>
>As fas as I know these IP cores have these interrupts lines, but they
>are not properly wired to the IRQ line that leaves the IP core. To quote
>Shawn Guo from the discussion back in 2012:
>
>>> From what I can tell, i.MX35, i.MX51 and i.MX53 use the same version,
>>> so they should all have the bug.  And for i.MX6Q, since it uses a newer
>>> version even than i.MX28, I would believe it's affected by the bug.
>>> But I'm copying Dong who should have better knowledge about this to
>>> confirm.
>
>Further Dong Aisheng says:
>
>>> Our IC owner double checked the MX35 and MX53 IP and found the
>>> RX_WARN & TX_WARN Interrupt source actually are not connected to
>>> ARM. That means flexcan will not trigger interrupt to ARM core even
>>> RX_WARN or TX_WARN Happens. This may be the root cause that why you
>>> cannot see RX_WARN interrupt if not enable bus error interrupt on
>>> mx35. He also checked that mx6q has the rx/tx warning interrupt
>>> connected to arm. So we guess mx6q does not have this issue.
>>> Anyway, we can test to confirm.
>
Ah, that's the reason behind, thanks for dig into the history and
sharing the knowledge with us. :)

>> However, as the driver also needs to work with the legacy core, and
>> they share the same devtype_data as p1010, so I think we should leave
>> it as it is.
>
>>>>  * Below is some version info we got:
>>>>  *    SOC   Version   IP-Version  Glitch- [TR]WRN_INT IRQ Err Memory err RTR re-
>>>>  *                                Filter? connected?  Passive detection  ception in MB
>>>>  *   MX25  FlexCAN2  03.00.00.00     no        no         ?       no        no
>>>>  *   MX28  FlexCAN2  03.00.04.00    yes       yes        no       no        no
>>>>  *   MX35  FlexCAN2  03.00.00.00     no        no         ?       no        no
>>>>  *   MX53  FlexCAN2  03.00.00.00    yes        no        no       no        no
>>>>  *   MX6s  FlexCAN3  10.00.12.00    yes       yes        no       no       yes
>>>>  *   VF610 FlexCAN3  ?               no       yes         ?      yes       yes?
>>>
>>> And does it make sense to add "FLEXCAN_QUIRK_BROKEN_PERR_STATE" to the
>>> vf610, too?
>
>> I think vf610 will need this quirk to report correct state transitions.
>> The reason last time we do not touch this is because neither Wolfgang
>> nor I had access to vf610, so we can only test with MX28, MX53 and MX6.
>> We thought someone will speak out if they meet problems with this core,
>> and then they can help to fix and test it.
>
>Cc'ed Stefan Agner - maybe he has access to this SoC.
>
>> @Marc, @Wolfgang,
>> What do you think? Or shall we fix first and then wait?
>
>Let's wait if Stefan can test, otherwise just fix.
OK.

Best regards
Yi

^ permalink raw reply	[flat|nested] 52+ messages in thread

* RE: [PATCH v2 2/2] can: flexcan: adding platform specific details for LS1021A
  2017-11-21 10:01                     ` Pankaj Bansal
@ 2017-11-23  7:23                       ` ZHU Yi (ST-FIR/ENG1-Zhu)
  0 siblings, 0 replies; 52+ messages in thread
From: ZHU Yi (ST-FIR/ENG1-Zhu) @ 2017-11-23  7:23 UTC (permalink / raw)
  To: Pankaj Bansal, Wolfgang Grandegger, Marc Kleine-Budde, linux-can
  Cc: Varun Sethi, Poonam Aggrwal

Hello Pankaj,

>From: Pankaj Bansal [mailto:pankaj.bansal@nxp.com]
>Sent: Tuesday, November 21, 2017 6:02 PM
> [...]
>Without PERR_STATE :
>
>root@TinyDistro:~# ip link set can0 up type can bitrate 125000 restart-ms 100 berr-reporting off
>[   22.507345] IPv6: ADDRCONF(NETDEV_CHANGE): can0: link becomes ready
>root@TinyDistro:~# ip link set can1 up type can bitrate 125000 restart-ms 100 berr-reporting off
>[   30.934669] IPv6: ADDRCONF(NETDEV_CHANGE): can1: link becomes ready
>root@TinyDistro:~# candump -td -e any,0:0,#FFFFFFFF &
>[1] 617
>root@TinyDistro:~# cangen can0 -D 11223344DEADBEEF -L 8
>[   48.684839] flexcan_irq 804 reg_esr=0x00062242, reg_ecr=0x00000060, reg_ctrl=0x4a31ac55
> (000.000000)  can0  20000004   [8]  00 08 00 00 00 00 00 00   ERRORFRAME
>        controller-problem{tx-error-warning}
>write: No buffer space available
>        **********  Short L and H signals of CAN ************
>root@TinyDistro:~# [  228.338038] flexcan_irq 804 reg_esr=0x00006036, reg_ecr=0x00000000, reg_ctrl=0x4a31ac55
> (179.653204)  can0  20000040   [8]  00 00 00 00 00 00 00 00   ERRORFRAME
>        bus-off
>[  228.438287] IPv6: ADDRCONF(NETDEV_CHANGE): can0: link becomes ready
> (000.092122)  can0  20000100   [8]  00 00 00 00 00 00 00 00   ERRORFRAME
>        restarted-after-bus-off
>
>With PERR_STATE :
>
>root@TinyDistro:~# ip link set can0 up type can bitrate 125000 restart-ms 100 berr-reporting off
>[   31.997286] IPv6: ADDRCONF(NETDEV_CHANGE): can0: link becomes ready
>root@TinyDistro:~# ip link set can1 up type can bitrate 125000 restart-ms 100 berr-reporting off
>[   40.934824] IPv6: ADDRCONF(NETDEV_CHANGE): can1: link becomes ready
>root@TinyDistro:~# candump -td -e any,0:0,#FFFFFFFF &
>[1] 620
>root@TinyDistro:~# cangen can0 -D 11223344DEADBEEF -L 8
>[   59.314920] flexcan_irq 805 reg_esr=0x00062242, reg_ecr=0x00000060, reg_ctrl=0x4a31ac55
> (000.000000)  [   59.323862] flexcan_irq 805 reg_esr=0x00042252, reg_ecr=0x00000080, reg_ctrl=0x4a31ec55
>can0  20000004   [8]  00 08 00 00 00 00 00 00   ERRORFRAME
>        controller-problem{tx-error-warning}
> (000.009673)  can0  20000004   [8]  00 20 00 00 00 00 00 00   ERRORFRAME
>        controller-problem{tx-error-passive}
>write: No buffer space available
>        **********  Short L and H signals of CAN ************
>root@TinyDistro:~# [   87.995878] flexcan_irq 805 reg_esr=0x00006036, reg_ecr=0x00000000, reg_ctrl=0x4a31ac55
> (028.671291)  can0  20000040   [8]  00 00 00 00 00 00 00 00   ERRORFRAME
>        bus-off
> (000.094305)  [   88.098464] IPv6: ADDRCONF(NETDEV_CHANGE): can0: link becomes ready
>can0  20000100   [8]  00 00 00 00 00 00 00 00   ERRORFRAME
>        restarted-after-bus-off

Seems the state increase can be reported correctly, and the state
decrease should also works fine, thanks for the test results!

Best regards
Yi



^ permalink raw reply	[flat|nested] 52+ messages in thread

* [PATCH v3 1/2] can: flexcan: Remodel FlexCAN register r/w APIs for big endian FlexCAN controllers.
  2017-11-14 11:56 ` [PATCH v2 " Pankaj Bansal
  2017-11-14 11:56   ` [PATCH v2 2/2] can: flexcan: adding platform specific details for LS1021A Pankaj Bansal
  2017-11-14 15:24   ` [PATCH v2 1/2] can: flexcan: Remodel FlexCAN register r/w APIs for big endian FlexCAN controllers Marc Kleine-Budde
@ 2017-11-23  9:09   ` Pankaj Bansal
  2017-11-23  9:09     ` [PATCH v3 2/2] can: flexcan: adding platform specific details for LS1021A Pankaj Bansal
  2017-11-23  9:18     ` [PATCH v3 1/2] can: flexcan: Remodel FlexCAN register r/w APIs for big endian FlexCAN controllers Marc Kleine-Budde
  2 siblings, 2 replies; 52+ messages in thread
From: Pankaj Bansal @ 2017-11-23  9:09 UTC (permalink / raw)
  To: wg, mkl, linux-can
  Cc: V.Sethi, poonam.aggrwal, Pankaj Bansal, Bhupesh Sharma, Sakar Arora

The FlexCAN driver assumed that FlexCAN controller is big endian for
powerpc architecture and little endian for other architectures.

But this may not be the case. FlexCAN controller can be little or big
endian on any architecture. For e.g. NXP LS1021A ARM based SOC has big
endian FlexCAN controller.

Therefore, the driver has been modified to add a provision for both
types of controllers using an additional device tree property. On a
"fsl,p1010-flexcan" device BE is default, on all other devices LE is.

Big Endian controllers should have "big-endian" set in the device tree.
check "Documentation/devicetree/bindings/net/can/fsl-flexcan.txt" for
usage.

This is the standard practice followed in linux. for more info check:
Documentation/devicetree/bindings/common-properties.txt

Signed-off-by: Pankaj Bansal <pankaj.bansal@nxp.com>
Signed-off-by: Bhupesh Sharma <bhupesh.sharma@freescale.com>
Signed-off-by: Sakar Arora <Sakar.Arora@freescale.com>
Reviewed-by: Zhengxiong Jin <Jason.Jin@freescale.com>
Reviewed-by: Poonam Aggrwal <poonam.aggrwal@nxp.com>
---
Changes in v3:
  - Added fsl,imx25-flexcan, fsl,imx35-flexcan and fsl,imx53-flexcan
    support to the driver.
Changes in v2:
  - Modified patch deciption to include common-properties.txt reference.
  - Reorder the LE/BE read/write APIs for better readability of code
  - Added an exception to force BE API selection, for powerpc based platform
    P1010. This ensures that new linux kernel works with old P1010
    device-tree, while future powerpc platforms that use big endian
    FlexCAN controller need to specify big-endian in device tree in
    FlexCAN node.
  - Tested on P1010 after backporting to freescale sdk 1.4 linux, without
    any change in device-tree.
  - Tested on NXP LS1021A arm based platform.

 drivers/net/can/flexcan.c | 233 ++++++++++++++++++++----------------
 1 file changed, 131 insertions(+), 102 deletions(-)

diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
index a13a489..4c873fb 100644
--- a/drivers/net/can/flexcan.c
+++ b/drivers/net/can/flexcan.c
@@ -279,6 +279,10 @@ struct flexcan_priv {
 	struct clk *clk_per;
 	const struct flexcan_devtype_data *devtype_data;
 	struct regulator *reg_xceiver;
+
+	/* Read and Write APIs */
+	u32 (*read)(void __iomem *addr);
+	void (*write)(u32 val, void __iomem *addr);
 };
 
 static const struct flexcan_devtype_data fsl_p1010_devtype_data = {
@@ -312,39 +316,45 @@ static const struct can_bittiming_const flexcan_bittiming_const = {
 	.brp_inc = 1,
 };
 
-/* Abstract off the read/write for arm versus ppc. This
- * assumes that PPC uses big-endian registers and everything
- * else uses little-endian registers, independent of CPU
- * endianness.
+/* FlexCAN module is essentially modelled as a little-endian IP in most
+ * SoCs, i.e the registers as well as the message buffer areas are
+ * implemented in a little-endian fashion.
+ *
+ * However there are some SoCs (e.g. LS1021A) which implement the FlexCAN
+ * module in a big-endian fashion (i.e the registers as well as the
+ * message buffer areas are implemented in a big-endian way).
+ *
+ * In addition, the FlexCAN module can be found on SoCs having ARM or
+ * PPC cores. So, we need to abstract off the register read/write
+ * functions, ensuring that these cater to all the combinations of module
+ * endianness and underlying CPU endianness.
  */
-#if defined(CONFIG_PPC)
-static inline u32 flexcan_read(void __iomem *addr)
+static inline u32 flexcan_read_be(void __iomem *addr)
 {
-	return in_be32(addr);
+	return ioread32be(addr);
 }
 
-static inline void flexcan_write(u32 val, void __iomem *addr)
+static inline void flexcan_write_be(u32 val, void __iomem *addr)
 {
-	out_be32(addr, val);
+	iowrite32be(val, addr);
 }
-#else
-static inline u32 flexcan_read(void __iomem *addr)
+
+static inline u32 flexcan_read_le(void __iomem *addr)
 {
-	return readl(addr);
+	return ioread32(addr);
 }
 
-static inline void flexcan_write(u32 val, void __iomem *addr)
+static inline void flexcan_write_le(u32 val, void __iomem *addr)
 {
-	writel(val, addr);
+	iowrite32(val, addr);
 }
-#endif
 
 static inline void flexcan_error_irq_enable(const struct flexcan_priv *priv)
 {
 	struct flexcan_regs __iomem *regs = priv->regs;
 	u32 reg_ctrl = (priv->reg_ctrl_default | FLEXCAN_CTRL_ERR_MSK);
 
-	flexcan_write(reg_ctrl, &regs->ctrl);
+	priv->write(reg_ctrl, &regs->ctrl);
 }
 
 static inline void flexcan_error_irq_disable(const struct flexcan_priv *priv)
@@ -352,7 +362,7 @@ static inline void flexcan_error_irq_disable(const struct flexcan_priv *priv)
 	struct flexcan_regs __iomem *regs = priv->regs;
 	u32 reg_ctrl = (priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_MSK);
 
-	flexcan_write(reg_ctrl, &regs->ctrl);
+	priv->write(reg_ctrl, &regs->ctrl);
 }
 
 static inline int flexcan_transceiver_enable(const struct flexcan_priv *priv)
@@ -377,14 +387,14 @@ static int flexcan_chip_enable(struct flexcan_priv *priv)
 	unsigned int timeout = FLEXCAN_TIMEOUT_US / 10;
 	u32 reg;
 
-	reg = flexcan_read(&regs->mcr);
+	reg = priv->read(&regs->mcr);
 	reg &= ~FLEXCAN_MCR_MDIS;
-	flexcan_write(reg, &regs->mcr);
+	priv->write(reg, &regs->mcr);
 
-	while (timeout-- && (flexcan_read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK))
+	while (timeout-- && (priv->read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK))
 		udelay(10);
 
-	if (flexcan_read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK)
+	if (priv->read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK)
 		return -ETIMEDOUT;
 
 	return 0;
@@ -396,14 +406,14 @@ static int flexcan_chip_disable(struct flexcan_priv *priv)
 	unsigned int timeout = FLEXCAN_TIMEOUT_US / 10;
 	u32 reg;
 
-	reg = flexcan_read(&regs->mcr);
+	reg = priv->read(&regs->mcr);
 	reg |= FLEXCAN_MCR_MDIS;
-	flexcan_write(reg, &regs->mcr);
+	priv->write(reg, &regs->mcr);
 
-	while (timeout-- && !(flexcan_read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK))
+	while (timeout-- && !(priv->read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK))
 		udelay(10);
 
-	if (!(flexcan_read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK))
+	if (!(priv->read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK))
 		return -ETIMEDOUT;
 
 	return 0;
@@ -415,14 +425,14 @@ static int flexcan_chip_freeze(struct flexcan_priv *priv)
 	unsigned int timeout = 1000 * 1000 * 10 / priv->can.bittiming.bitrate;
 	u32 reg;
 
-	reg = flexcan_read(&regs->mcr);
+	reg = priv->read(&regs->mcr);
 	reg |= FLEXCAN_MCR_HALT;
-	flexcan_write(reg, &regs->mcr);
+	priv->write(reg, &regs->mcr);
 
-	while (timeout-- && !(flexcan_read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK))
+	while (timeout-- && !(priv->read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK))
 		udelay(100);
 
-	if (!(flexcan_read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK))
+	if (!(priv->read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK))
 		return -ETIMEDOUT;
 
 	return 0;
@@ -434,14 +444,14 @@ static int flexcan_chip_unfreeze(struct flexcan_priv *priv)
 	unsigned int timeout = FLEXCAN_TIMEOUT_US / 10;
 	u32 reg;
 
-	reg = flexcan_read(&regs->mcr);
+	reg = priv->read(&regs->mcr);
 	reg &= ~FLEXCAN_MCR_HALT;
-	flexcan_write(reg, &regs->mcr);
+	priv->write(reg, &regs->mcr);
 
-	while (timeout-- && (flexcan_read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK))
+	while (timeout-- && (priv->read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK))
 		udelay(10);
 
-	if (flexcan_read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK)
+	if (priv->read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK)
 		return -ETIMEDOUT;
 
 	return 0;
@@ -452,11 +462,11 @@ static int flexcan_chip_softreset(struct flexcan_priv *priv)
 	struct flexcan_regs __iomem *regs = priv->regs;
 	unsigned int timeout = FLEXCAN_TIMEOUT_US / 10;
 
-	flexcan_write(FLEXCAN_MCR_SOFTRST, &regs->mcr);
-	while (timeout-- && (flexcan_read(&regs->mcr) & FLEXCAN_MCR_SOFTRST))
+	priv->write(FLEXCAN_MCR_SOFTRST, &regs->mcr);
+	while (timeout-- && (priv->read(&regs->mcr) & FLEXCAN_MCR_SOFTRST))
 		udelay(10);
 
-	if (flexcan_read(&regs->mcr) & FLEXCAN_MCR_SOFTRST)
+	if (priv->read(&regs->mcr) & FLEXCAN_MCR_SOFTRST)
 		return -ETIMEDOUT;
 
 	return 0;
@@ -467,7 +477,7 @@ static int __flexcan_get_berr_counter(const struct net_device *dev,
 {
 	const struct flexcan_priv *priv = netdev_priv(dev);
 	struct flexcan_regs __iomem *regs = priv->regs;
-	u32 reg = flexcan_read(&regs->ecr);
+	u32 reg = priv->read(&regs->ecr);
 
 	bec->txerr = (reg >> 0) & 0xff;
 	bec->rxerr = (reg >> 8) & 0xff;
@@ -523,24 +533,24 @@ static int flexcan_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	if (cf->can_dlc > 0) {
 		data = be32_to_cpup((__be32 *)&cf->data[0]);
-		flexcan_write(data, &priv->tx_mb->data[0]);
+		priv->write(data, &priv->tx_mb->data[0]);
 	}
 	if (cf->can_dlc > 3) {
 		data = be32_to_cpup((__be32 *)&cf->data[4]);
-		flexcan_write(data, &priv->tx_mb->data[1]);
+		priv->write(data, &priv->tx_mb->data[1]);
 	}
 
 	can_put_echo_skb(skb, dev, 0);
 
-	flexcan_write(can_id, &priv->tx_mb->can_id);
-	flexcan_write(ctrl, &priv->tx_mb->can_ctrl);
+	priv->write(can_id, &priv->tx_mb->can_id);
+	priv->write(ctrl, &priv->tx_mb->can_ctrl);
 
 	/* Errata ERR005829 step8:
 	 * Write twice INACTIVE(0x8) code to first MB.
 	 */
-	flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE,
+	priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
 		      &priv->tx_mb_reserved->can_ctrl);
-	flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE,
+	priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
 		      &priv->tx_mb_reserved->can_ctrl);
 
 	return NETDEV_TX_OK;
@@ -659,7 +669,7 @@ static unsigned int flexcan_mailbox_read(struct can_rx_offload *offload,
 		u32 code;
 
 		do {
-			reg_ctrl = flexcan_read(&mb->can_ctrl);
+			reg_ctrl = priv->read(&mb->can_ctrl);
 		} while (reg_ctrl & FLEXCAN_MB_CODE_RX_BUSY_BIT);
 
 		/* is this MB empty? */
@@ -674,17 +684,17 @@ static unsigned int flexcan_mailbox_read(struct can_rx_offload *offload,
 			offload->dev->stats.rx_errors++;
 		}
 	} else {
-		reg_iflag1 = flexcan_read(&regs->iflag1);
+		reg_iflag1 = priv->read(&regs->iflag1);
 		if (!(reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_AVAILABLE))
 			return 0;
 
-		reg_ctrl = flexcan_read(&mb->can_ctrl);
+		reg_ctrl = priv->read(&mb->can_ctrl);
 	}
 
 	/* increase timstamp to full 32 bit */
 	*timestamp = reg_ctrl << 16;
 
-	reg_id = flexcan_read(&mb->can_id);
+	reg_id = priv->read(&mb->can_id);
 	if (reg_ctrl & FLEXCAN_MB_CNT_IDE)
 		cf->can_id = ((reg_id >> 0) & CAN_EFF_MASK) | CAN_EFF_FLAG;
 	else
@@ -694,19 +704,19 @@ static unsigned int flexcan_mailbox_read(struct can_rx_offload *offload,
 		cf->can_id |= CAN_RTR_FLAG;
 	cf->can_dlc = get_can_dlc((reg_ctrl >> 16) & 0xf);
 
-	*(__be32 *)(cf->data + 0) = cpu_to_be32(flexcan_read(&mb->data[0]));
-	*(__be32 *)(cf->data + 4) = cpu_to_be32(flexcan_read(&mb->data[1]));
+	*(__be32 *)(cf->data + 0) = cpu_to_be32(priv->read(&mb->data[0]));
+	*(__be32 *)(cf->data + 4) = cpu_to_be32(priv->read(&mb->data[1]));
 
 	/* mark as read */
 	if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) {
 		/* Clear IRQ */
 		if (n < 32)
-			flexcan_write(BIT(n), &regs->iflag1);
+			priv->write(BIT(n), &regs->iflag1);
 		else
-			flexcan_write(BIT(n - 32), &regs->iflag2);
+			priv->write(BIT(n - 32), &regs->iflag2);
 	} else {
-		flexcan_write(FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, &regs->iflag1);
-		flexcan_read(&regs->timer);
+		priv->write(FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, &regs->iflag1);
+		priv->read(&regs->timer);
 	}
 
 	return 1;
@@ -718,8 +728,8 @@ static inline u64 flexcan_read_reg_iflag_rx(struct flexcan_priv *priv)
 	struct flexcan_regs __iomem *regs = priv->regs;
 	u32 iflag1, iflag2;
 
-	iflag2 = flexcan_read(&regs->iflag2) & priv->reg_imask2_default;
-	iflag1 = flexcan_read(&regs->iflag1) & priv->reg_imask1_default &
+	iflag2 = priv->read(&regs->iflag2) & priv->reg_imask2_default;
+	iflag1 = priv->read(&regs->iflag1) & priv->reg_imask1_default &
 		~FLEXCAN_IFLAG_MB(priv->tx_mb_idx);
 
 	return (u64)iflag2 << 32 | iflag1;
@@ -735,7 +745,7 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
 	u32 reg_iflag1, reg_esr;
 	enum can_state last_state = priv->can.state;
 
-	reg_iflag1 = flexcan_read(&regs->iflag1);
+	reg_iflag1 = priv->read(&regs->iflag1);
 
 	/* reception interrupt */
 	if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) {
@@ -758,7 +768,8 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
 		/* FIFO overflow interrupt */
 		if (reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_OVERFLOW) {
 			handled = IRQ_HANDLED;
-			flexcan_write(FLEXCAN_IFLAG_RX_FIFO_OVERFLOW, &regs->iflag1);
+			priv->write(FLEXCAN_IFLAG_RX_FIFO_OVERFLOW,
+				    &regs->iflag1);
 			dev->stats.rx_over_errors++;
 			dev->stats.rx_errors++;
 		}
@@ -772,18 +783,18 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
 		can_led_event(dev, CAN_LED_EVENT_TX);
 
 		/* after sending a RTR frame MB is in RX mode */
-		flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE,
-			      &priv->tx_mb->can_ctrl);
-		flexcan_write(FLEXCAN_IFLAG_MB(priv->tx_mb_idx), &regs->iflag1);
+		priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
+			    &priv->tx_mb->can_ctrl);
+		priv->write(FLEXCAN_IFLAG_MB(priv->tx_mb_idx), &regs->iflag1);
 		netif_wake_queue(dev);
 	}
 
-	reg_esr = flexcan_read(&regs->esr);
+	reg_esr = priv->read(&regs->esr);
 
 	/* ACK all bus error and state change IRQ sources */
 	if (reg_esr & FLEXCAN_ESR_ALL_INT) {
 		handled = IRQ_HANDLED;
-		flexcan_write(reg_esr & FLEXCAN_ESR_ALL_INT, &regs->esr);
+		priv->write(reg_esr & FLEXCAN_ESR_ALL_INT, &regs->esr);
 	}
 
 	/* state change interrupt or broken error state quirk fix is enabled */
@@ -845,7 +856,7 @@ static void flexcan_set_bittiming(struct net_device *dev)
 	struct flexcan_regs __iomem *regs = priv->regs;
 	u32 reg;
 
-	reg = flexcan_read(&regs->ctrl);
+	reg = priv->read(&regs->ctrl);
 	reg &= ~(FLEXCAN_CTRL_PRESDIV(0xff) |
 		 FLEXCAN_CTRL_RJW(0x3) |
 		 FLEXCAN_CTRL_PSEG1(0x7) |
@@ -869,11 +880,11 @@ static void flexcan_set_bittiming(struct net_device *dev)
 		reg |= FLEXCAN_CTRL_SMP;
 
 	netdev_dbg(dev, "writing ctrl=0x%08x\n", reg);
-	flexcan_write(reg, &regs->ctrl);
+	priv->write(reg, &regs->ctrl);
 
 	/* print chip status */
 	netdev_dbg(dev, "%s: mcr=0x%08x ctrl=0x%08x\n", __func__,
-		   flexcan_read(&regs->mcr), flexcan_read(&regs->ctrl));
+		   priv->read(&regs->mcr), priv->read(&regs->ctrl));
 }
 
 /* flexcan_chip_start
@@ -912,7 +923,7 @@ static int flexcan_chip_start(struct net_device *dev)
 	 * choose format C
 	 * set max mailbox number
 	 */
-	reg_mcr = flexcan_read(&regs->mcr);
+	reg_mcr = priv->read(&regs->mcr);
 	reg_mcr &= ~FLEXCAN_MCR_MAXMB(0xff);
 	reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT | FLEXCAN_MCR_SUPV |
 		FLEXCAN_MCR_WRN_EN | FLEXCAN_MCR_SRX_DIS | FLEXCAN_MCR_IRMQ |
@@ -926,7 +937,7 @@ static int flexcan_chip_start(struct net_device *dev)
 			FLEXCAN_MCR_MAXMB(priv->tx_mb_idx);
 	}
 	netdev_dbg(dev, "%s: writing mcr=0x%08x", __func__, reg_mcr);
-	flexcan_write(reg_mcr, &regs->mcr);
+	priv->write(reg_mcr, &regs->mcr);
 
 	/* CTRL
 	 *
@@ -939,7 +950,7 @@ static int flexcan_chip_start(struct net_device *dev)
 	 * enable bus off interrupt
 	 * (== FLEXCAN_CTRL_ERR_STATE)
 	 */
-	reg_ctrl = flexcan_read(&regs->ctrl);
+	reg_ctrl = priv->read(&regs->ctrl);
 	reg_ctrl &= ~FLEXCAN_CTRL_TSYN;
 	reg_ctrl |= FLEXCAN_CTRL_BOFF_REC | FLEXCAN_CTRL_LBUF |
 		FLEXCAN_CTRL_ERR_STATE;
@@ -959,45 +970,45 @@ static int flexcan_chip_start(struct net_device *dev)
 	/* leave interrupts disabled for now */
 	reg_ctrl &= ~FLEXCAN_CTRL_ERR_ALL;
 	netdev_dbg(dev, "%s: writing ctrl=0x%08x", __func__, reg_ctrl);
-	flexcan_write(reg_ctrl, &regs->ctrl);
+	priv->write(reg_ctrl, &regs->ctrl);
 
 	if ((priv->devtype_data->quirks & FLEXCAN_QUIRK_ENABLE_EACEN_RRS)) {
-		reg_ctrl2 = flexcan_read(&regs->ctrl2);
+		reg_ctrl2 = priv->read(&regs->ctrl2);
 		reg_ctrl2 |= FLEXCAN_CTRL2_EACEN | FLEXCAN_CTRL2_RRS;
-		flexcan_write(reg_ctrl2, &regs->ctrl2);
+		priv->write(reg_ctrl2, &regs->ctrl2);
 	}
 
 	/* clear and invalidate all mailboxes first */
 	for (i = priv->tx_mb_idx; i < ARRAY_SIZE(regs->mb); i++) {
-		flexcan_write(FLEXCAN_MB_CODE_RX_INACTIVE,
-			      &regs->mb[i].can_ctrl);
+		priv->write(FLEXCAN_MB_CODE_RX_INACTIVE,
+			    &regs->mb[i].can_ctrl);
 	}
 
 	if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) {
 		for (i = priv->offload.mb_first; i <= priv->offload.mb_last; i++)
-			flexcan_write(FLEXCAN_MB_CODE_RX_EMPTY,
-				      &regs->mb[i].can_ctrl);
+			priv->write(FLEXCAN_MB_CODE_RX_EMPTY,
+				    &regs->mb[i].can_ctrl);
 	}
 
 	/* Errata ERR005829: mark first TX mailbox as INACTIVE */
-	flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE,
-		      &priv->tx_mb_reserved->can_ctrl);
+	priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
+		    &priv->tx_mb_reserved->can_ctrl);
 
 	/* mark TX mailbox as INACTIVE */
-	flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE,
-		      &priv->tx_mb->can_ctrl);
+	priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
+		    &priv->tx_mb->can_ctrl);
 
 	/* acceptance mask/acceptance code (accept everything) */
-	flexcan_write(0x0, &regs->rxgmask);
-	flexcan_write(0x0, &regs->rx14mask);
-	flexcan_write(0x0, &regs->rx15mask);
+	priv->write(0x0, &regs->rxgmask);
+	priv->write(0x0, &regs->rx14mask);
+	priv->write(0x0, &regs->rx15mask);
 
 	if (priv->devtype_data->quirks & FLEXCAN_QUIRK_DISABLE_RXFG)
-		flexcan_write(0x0, &regs->rxfgmask);
+		priv->write(0x0, &regs->rxfgmask);
 
 	/* clear acceptance filters */
 	for (i = 0; i < ARRAY_SIZE(regs->mb); i++)
-		flexcan_write(0, &regs->rximr[i]);
+		priv->write(0, &regs->rximr[i]);
 
 	/* On Vybrid, disable memory error detection interrupts
 	 * and freeze mode.
@@ -1010,16 +1021,16 @@ static int flexcan_chip_start(struct net_device *dev)
 		 * and Correction of Memory Errors" to write to
 		 * MECR register
 		 */
-		reg_ctrl2 = flexcan_read(&regs->ctrl2);
+		reg_ctrl2 = priv->read(&regs->ctrl2);
 		reg_ctrl2 |= FLEXCAN_CTRL2_ECRWRE;
-		flexcan_write(reg_ctrl2, &regs->ctrl2);
+		priv->write(reg_ctrl2, &regs->ctrl2);
 
-		reg_mecr = flexcan_read(&regs->mecr);
+		reg_mecr = priv->read(&regs->mecr);
 		reg_mecr &= ~FLEXCAN_MECR_ECRWRDIS;
-		flexcan_write(reg_mecr, &regs->mecr);
+		priv->write(reg_mecr, &regs->mecr);
 		reg_mecr &= ~(FLEXCAN_MECR_NCEFAFRZ | FLEXCAN_MECR_HANCEI_MSK |
 			      FLEXCAN_MECR_FANCEI_MSK);
-		flexcan_write(reg_mecr, &regs->mecr);
+		priv->write(reg_mecr, &regs->mecr);
 	}
 
 	err = flexcan_transceiver_enable(priv);
@@ -1035,14 +1046,14 @@ static int flexcan_chip_start(struct net_device *dev)
 
 	/* enable interrupts atomically */
 	disable_irq(dev->irq);
-	flexcan_write(priv->reg_ctrl_default, &regs->ctrl);
-	flexcan_write(priv->reg_imask1_default, &regs->imask1);
-	flexcan_write(priv->reg_imask2_default, &regs->imask2);
+	priv->write(priv->reg_ctrl_default, &regs->ctrl);
+	priv->write(priv->reg_imask1_default, &regs->imask1);
+	priv->write(priv->reg_imask2_default, &regs->imask2);
 	enable_irq(dev->irq);
 
 	/* print chip status */
 	netdev_dbg(dev, "%s: reading mcr=0x%08x ctrl=0x%08x\n", __func__,
-		   flexcan_read(&regs->mcr), flexcan_read(&regs->ctrl));
+		   priv->read(&regs->mcr), priv->read(&regs->ctrl));
 
 	return 0;
 
@@ -1067,10 +1078,10 @@ static void flexcan_chip_stop(struct net_device *dev)
 	flexcan_chip_disable(priv);
 
 	/* Disable all interrupts */
-	flexcan_write(0, &regs->imask2);
-	flexcan_write(0, &regs->imask1);
-	flexcan_write(priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_ALL,
-		      &regs->ctrl);
+	priv->write(0, &regs->imask2);
+	priv->write(0, &regs->imask1);
+	priv->write(priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_ALL,
+		    &regs->ctrl);
 
 	flexcan_transceiver_disable(priv);
 	priv->can.state = CAN_STATE_STOPPED;
@@ -1185,26 +1196,26 @@ static int register_flexcandev(struct net_device *dev)
 	err = flexcan_chip_disable(priv);
 	if (err)
 		goto out_disable_per;
-	reg = flexcan_read(&regs->ctrl);
+	reg = priv->read(&regs->ctrl);
 	reg |= FLEXCAN_CTRL_CLK_SRC;
-	flexcan_write(reg, &regs->ctrl);
+	priv->write(reg, &regs->ctrl);
 
 	err = flexcan_chip_enable(priv);
 	if (err)
 		goto out_chip_disable;
 
 	/* set freeze, halt and activate FIFO, restrict register access */
-	reg = flexcan_read(&regs->mcr);
+	reg = priv->read(&regs->mcr);
 	reg |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT |
 		FLEXCAN_MCR_FEN | FLEXCAN_MCR_SUPV;
-	flexcan_write(reg, &regs->mcr);
+	priv->write(reg, &regs->mcr);
 
 	/* Currently we only support newer versions of this core
 	 * featuring a RX hardware FIFO (although this driver doesn't
 	 * make use of it on some cores). Older cores, found on some
 	 * Coldfire derivates are not tested.
 	 */
-	reg = flexcan_read(&regs->mcr);
+	reg = priv->read(&regs->mcr);
 	if (!(reg & FLEXCAN_MCR_FEN)) {
 		netdev_err(dev, "Could not enable RX FIFO, unsupported core\n");
 		err = -ENODEV;
@@ -1232,6 +1243,9 @@ static void unregister_flexcandev(struct net_device *dev)
 static const struct of_device_id flexcan_of_match[] = {
 	{ .compatible = "fsl,imx6q-flexcan", .data = &fsl_imx6q_devtype_data, },
 	{ .compatible = "fsl,imx28-flexcan", .data = &fsl_imx28_devtype_data, },
+	{ .compatible = "fsl,imx53-flexcan", .data = &fsl_p1010_devtype_data, },
+	{ .compatible = "fsl,imx35-flexcan", .data = &fsl_p1010_devtype_data, },
+	{ .compatible = "fsl,imx25-flexcan", .data = &fsl_p1010_devtype_data, },
 	{ .compatible = "fsl,p1010-flexcan", .data = &fsl_p1010_devtype_data, },
 	{ .compatible = "fsl,vf610-flexcan", .data = &fsl_vf610_devtype_data, },
 	{ /* sentinel */ },
@@ -1313,6 +1327,21 @@ static int flexcan_probe(struct platform_device *pdev)
 	dev->flags |= IFF_ECHO;
 
 	priv = netdev_priv(dev);
+
+	if (of_property_read_bool(pdev->dev.of_node, "big-endian")) {
+		priv->read = flexcan_read_be;
+		priv->write = flexcan_write_be;
+	} else {
+		if (of_device_is_compatible(pdev->dev.of_node,
+					    "fsl,p1010-flexcan")) {
+			priv->read = flexcan_read_be;
+			priv->write = flexcan_write_be;
+		} else {
+			priv->read = flexcan_read_le;
+			priv->write = flexcan_write_le;
+		}
+	}
+
 	priv->can.clock.freq = clock_freq;
 	priv->can.bittiming_const = &flexcan_bittiming_const;
 	priv->can.do_set_mode = flexcan_set_mode;
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [PATCH v3 2/2] can: flexcan: adding platform specific details for LS1021A
  2017-11-23  9:09   ` [PATCH v3 " Pankaj Bansal
@ 2017-11-23  9:09     ` Pankaj Bansal
  2017-11-23  9:16       ` Marc Kleine-Budde
  2017-11-23  9:18     ` [PATCH v3 1/2] can: flexcan: Remodel FlexCAN register r/w APIs for big endian FlexCAN controllers Marc Kleine-Budde
  1 sibling, 1 reply; 52+ messages in thread
From: Pankaj Bansal @ 2017-11-23  9:09 UTC (permalink / raw)
  To: wg, mkl, linux-can; +Cc: V.Sethi, poonam.aggrwal, Pankaj Bansal, Bhupesh Sharma

This patch adds platform specific details for NXP SOC LS1021A to the
flexcan driver code.

Signed-off-by: Pankaj Bansal <pankaj.bansal@nxp.com>
Signed-off-by: Bhupesh Sharma <bhupesh.sharma@freescale.com>
Reviewed-by: Zhengxiong Jin <Jason.Jin@freescale.com>
Reviewed-by: Poonam Aggrwal <poonam.aggrwal@nxp.com>
---
Changes in v3:
  - Add LS1021 in FLEXCAN hardware feature flags table
  - Kept LS1021 compatible in one line, even if it's more than 80
    chars.
  - Add PERR_STATE quirk and USE_OFF_TIMESTAMP quirk and
    ENABLE_EACEN_RRS quirk for LS1021A.
  - Tested on LS1021A using "cangen can0 -D 11223344DEADBEEF -L 8 -R"
    and "cangen can0 -D 11223344DEADBEEF -L 8"
Changes in v2:
  - No change.

 drivers/net/can/flexcan.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
index 4c873fb..21d0dd8 100644
--- a/drivers/net/can/flexcan.c
+++ b/drivers/net/can/flexcan.c
@@ -190,6 +190,7 @@
  *   MX53  FlexCAN2  03.00.00.00    yes        no        no       no        no
  *   MX6s  FlexCAN3  10.00.12.00    yes       yes        no       no       yes
  *   VF610 FlexCAN3  ?               no       yes         ?      yes       yes?
+ * LS1021A FlexCAN2  03.00.04.00     no       yes        no       no       yes
  *
  * Some SOCs do not have the RX_WARN & TX_WARN interrupt line connected.
  */
@@ -304,6 +305,13 @@ static const struct flexcan_devtype_data fsl_vf610_devtype_data = {
 		FLEXCAN_QUIRK_DISABLE_MECR | FLEXCAN_QUIRK_USE_OFF_TIMESTAMP,
 };
 
+/* LS1021A-Rev2 has functional RX-FIFO mode  */
+static const struct flexcan_devtype_data fsl_ls1021a_r2_devtype_data = {
+	.quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_ENABLE_EACEN_RRS |
+		FLEXCAN_QUIRK_DISABLE_MECR | FLEXCAN_QUIRK_BROKEN_PERR_STATE |
+		FLEXCAN_QUIRK_USE_OFF_TIMESTAMP,
+};
+
 static const struct can_bittiming_const flexcan_bittiming_const = {
 	.name = DRV_NAME,
 	.tseg1_min = 4,
@@ -1248,6 +1256,7 @@ static const struct of_device_id flexcan_of_match[] = {
 	{ .compatible = "fsl,imx25-flexcan", .data = &fsl_p1010_devtype_data, },
 	{ .compatible = "fsl,p1010-flexcan", .data = &fsl_p1010_devtype_data, },
 	{ .compatible = "fsl,vf610-flexcan", .data = &fsl_vf610_devtype_data, },
+	{ .compatible = "fsl,ls1021ar2-flexcan", .data = &fsl_ls1021a_r2_devtype_data, },
 	{ /* sentinel */ },
 };
 MODULE_DEVICE_TABLE(of, flexcan_of_match);
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 52+ messages in thread

* Re: [PATCH v3 2/2] can: flexcan: adding platform specific details for LS1021A
  2017-11-23  9:09     ` [PATCH v3 2/2] can: flexcan: adding platform specific details for LS1021A Pankaj Bansal
@ 2017-11-23  9:16       ` Marc Kleine-Budde
  2017-11-23 10:01         ` Pankaj Bansal
  0 siblings, 1 reply; 52+ messages in thread
From: Marc Kleine-Budde @ 2017-11-23  9:16 UTC (permalink / raw)
  To: Pankaj Bansal, wg, linux-can; +Cc: V.Sethi, poonam.aggrwal, Bhupesh Sharma


[-- Attachment #1.1: Type: text/plain, Size: 3076 bytes --]

On 11/23/2017 10:09 AM, Pankaj Bansal wrote:
> This patch adds platform specific details for NXP SOC LS1021A to the
> flexcan driver code.
> 
> Signed-off-by: Pankaj Bansal <pankaj.bansal@nxp.com>
> Signed-off-by: Bhupesh Sharma <bhupesh.sharma@freescale.com>
> Reviewed-by: Zhengxiong Jin <Jason.Jin@freescale.com>
> Reviewed-by: Poonam Aggrwal <poonam.aggrwal@nxp.com>
> ---
> Changes in v3:
>   - Add LS1021 in FLEXCAN hardware feature flags table
>   - Kept LS1021 compatible in one line, even if it's more than 80
>     chars.
>   - Add PERR_STATE quirk and USE_OFF_TIMESTAMP quirk and
>     ENABLE_EACEN_RRS quirk for LS1021A.
>   - Tested on LS1021A using "cangen can0 -D 11223344DEADBEEF -L 8 -R"
>     and "cangen can0 -D 11223344DEADBEEF -L 8"
> Changes in v2:
>   - No change.
> 
>  drivers/net/can/flexcan.c | 9 +++++++++
>  1 file changed, 9 insertions(+)
> 
> diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
> index 4c873fb..21d0dd8 100644
> --- a/drivers/net/can/flexcan.c
> +++ b/drivers/net/can/flexcan.c
> @@ -190,6 +190,7 @@
>   *   MX53  FlexCAN2  03.00.00.00    yes        no        no       no        no
>   *   MX6s  FlexCAN3  10.00.12.00    yes       yes        no       no       yes
>   *   VF610 FlexCAN3  ?               no       yes         ?      yes       yes?
> + * LS1021A FlexCAN2  03.00.04.00     no       yes        no       no       yes

Out of curiosity, where have you got the IP core version from?

>   *
>   * Some SOCs do not have the RX_WARN & TX_WARN interrupt line connected.
>   */
> @@ -304,6 +305,13 @@ static const struct flexcan_devtype_data fsl_vf610_devtype_data = {
>  		FLEXCAN_QUIRK_DISABLE_MECR | FLEXCAN_QUIRK_USE_OFF_TIMESTAMP,
>  };
>  
> +/* LS1021A-Rev2 has functional RX-FIFO mode  */

That comment is obsolete, isn't it? If it's a noteworthy feature, add it
to the overview table above.

> +static const struct flexcan_devtype_data fsl_ls1021a_r2_devtype_data = {
> +	.quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_ENABLE_EACEN_RRS |
> +		FLEXCAN_QUIRK_DISABLE_MECR | FLEXCAN_QUIRK_BROKEN_PERR_STATE |
> +		FLEXCAN_QUIRK_USE_OFF_TIMESTAMP,
> +};
> +
>  static const struct can_bittiming_const flexcan_bittiming_const = {
>  	.name = DRV_NAME,
>  	.tseg1_min = 4,
> @@ -1248,6 +1256,7 @@ static const struct of_device_id flexcan_of_match[] = {
>  	{ .compatible = "fsl,imx25-flexcan", .data = &fsl_p1010_devtype_data, },
>  	{ .compatible = "fsl,p1010-flexcan", .data = &fsl_p1010_devtype_data, },
>  	{ .compatible = "fsl,vf610-flexcan", .data = &fsl_vf610_devtype_data, },
> +	{ .compatible = "fsl,ls1021ar2-flexcan", .data = &fsl_ls1021a_r2_devtype_data, },
>  	{ /* sentinel */ },
>  };
>  MODULE_DEVICE_TABLE(of, flexcan_of_match);
> 

Marc

-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH v3 1/2] can: flexcan: Remodel FlexCAN register r/w APIs for big endian FlexCAN controllers.
  2017-11-23  9:09   ` [PATCH v3 " Pankaj Bansal
  2017-11-23  9:09     ` [PATCH v3 2/2] can: flexcan: adding platform specific details for LS1021A Pankaj Bansal
@ 2017-11-23  9:18     ` Marc Kleine-Budde
  2017-11-23  9:55       ` Pankaj Bansal
  1 sibling, 1 reply; 52+ messages in thread
From: Marc Kleine-Budde @ 2017-11-23  9:18 UTC (permalink / raw)
  To: Pankaj Bansal, wg, linux-can
  Cc: V.Sethi, poonam.aggrwal, Bhupesh Sharma, Sakar Arora


[-- Attachment #1.1: Type: text/plain, Size: 1528 bytes --]

On 11/23/2017 10:09 AM, Pankaj Bansal wrote:
> The FlexCAN driver assumed that FlexCAN controller is big endian for
> powerpc architecture and little endian for other architectures.
> 
> But this may not be the case. FlexCAN controller can be little or big
> endian on any architecture. For e.g. NXP LS1021A ARM based SOC has big
> endian FlexCAN controller.
> 
> Therefore, the driver has been modified to add a provision for both
> types of controllers using an additional device tree property. On a
> "fsl,p1010-flexcan" device BE is default, on all other devices LE is.
> 
> Big Endian controllers should have "big-endian" set in the device tree.
> check "Documentation/devicetree/bindings/net/can/fsl-flexcan.txt" for
> usage.
> 
> This is the standard practice followed in linux. for more info check:
> Documentation/devicetree/bindings/common-properties.txt
> 
> Signed-off-by: Pankaj Bansal <pankaj.bansal@nxp.com>
> Signed-off-by: Bhupesh Sharma <bhupesh.sharma@freescale.com>
> Signed-off-by: Sakar Arora <Sakar.Arora@freescale.com>
> Reviewed-by: Zhengxiong Jin <Jason.Jin@freescale.com>
> Reviewed-by: Poonam Aggrwal <poonam.aggrwal@nxp.com>

I'm missing the update of the fsl-flexcan.txt in this series.

Marc

-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 52+ messages in thread

* RE: [PATCH v3 1/2] can: flexcan: Remodel FlexCAN register r/w APIs for big endian FlexCAN controllers.
  2017-11-23  9:18     ` [PATCH v3 1/2] can: flexcan: Remodel FlexCAN register r/w APIs for big endian FlexCAN controllers Marc Kleine-Budde
@ 2017-11-23  9:55       ` Pankaj Bansal
  0 siblings, 0 replies; 52+ messages in thread
From: Pankaj Bansal @ 2017-11-23  9:55 UTC (permalink / raw)
  To: Marc Kleine-Budde, wg, linux-can
  Cc: Varun Sethi, Poonam Aggrwal, Bhupesh Sharma, Sakar Arora

Hi Marc,

> -----Original Message-----
> From: Marc Kleine-Budde [mailto:mkl@pengutronix.de]
> Sent: Thursday, November 23, 2017 2:48 PM
> To: Pankaj Bansal <pankaj.bansal@nxp.com>; wg@grandegger.com; linux-
> can@vger.kernel.org
> Cc: Varun Sethi <V.Sethi@nxp.com>; Poonam Aggrwal
> <poonam.aggrwal@nxp.com>; Bhupesh Sharma
> <bhupesh.sharma@freescale.com>; Sakar Arora
> <Sakar.Arora@freescale.com>
> Subject: Re: [PATCH v3 1/2] can: flexcan: Remodel FlexCAN register r/w APIs
> for big endian FlexCAN controllers.
> 
> On 11/23/2017 10:09 AM, Pankaj Bansal wrote:
> > The FlexCAN driver assumed that FlexCAN controller is big endian for
> > powerpc architecture and little endian for other architectures.
> >
> > But this may not be the case. FlexCAN controller can be little or big
> > endian on any architecture. For e.g. NXP LS1021A ARM based SOC has big
> > endian FlexCAN controller.
> >
> > Therefore, the driver has been modified to add a provision for both
> > types of controllers using an additional device tree property. On a
> > "fsl,p1010-flexcan" device BE is default, on all other devices LE is.
> >
> > Big Endian controllers should have "big-endian" set in the device tree.
> > check "Documentation/devicetree/bindings/net/can/fsl-flexcan.txt" for
> > usage.
> >
> > This is the standard practice followed in linux. for more info check:
> > Documentation/devicetree/bindings/common-properties.txt
> >
> > Signed-off-by: Pankaj Bansal <pankaj.bansal@nxp.com>
> > Signed-off-by: Bhupesh Sharma <bhupesh.sharma@freescale.com>
> > Signed-off-by: Sakar Arora <Sakar.Arora@freescale.com>
> > Reviewed-by: Zhengxiong Jin <Jason.Jin@freescale.com>
> > Reviewed-by: Poonam Aggrwal <poonam.aggrwal@nxp.com>
> 
> I'm missing the update of the fsl-flexcan.txt in this series.
> 

As fsl-flexcan.txt is a change in device-tree, I have sent this change in another series of patches which are all in device tree.

> Marc
> 
> --
> Pengutronix e.K.                  | Marc Kleine-Budde           |
> Industrial Linux Solutions        | Phone: +49-231-2826-924     |
> Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
> Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


^ permalink raw reply	[flat|nested] 52+ messages in thread

* RE: [PATCH v3 2/2] can: flexcan: adding platform specific details for LS1021A
  2017-11-23  9:16       ` Marc Kleine-Budde
@ 2017-11-23 10:01         ` Pankaj Bansal
  2017-11-23 10:07           ` Marc Kleine-Budde
  0 siblings, 1 reply; 52+ messages in thread
From: Pankaj Bansal @ 2017-11-23 10:01 UTC (permalink / raw)
  To: Marc Kleine-Budde, wg, linux-can
  Cc: Varun Sethi, Poonam Aggrwal, Bhupesh Sharma

Hi Marc,

> -----Original Message-----
> From: Marc Kleine-Budde [mailto:mkl@pengutronix.de]
> Sent: Thursday, November 23, 2017 2:47 PM
> To: Pankaj Bansal <pankaj.bansal@nxp.com>; wg@grandegger.com; linux-
> can@vger.kernel.org
> Cc: Varun Sethi <V.Sethi@nxp.com>; Poonam Aggrwal
> <poonam.aggrwal@nxp.com>; Bhupesh Sharma
> <bhupesh.sharma@freescale.com>
> Subject: Re: [PATCH v3 2/2] can: flexcan: adding platform specific details for
> LS1021A
> 
> On 11/23/2017 10:09 AM, Pankaj Bansal wrote:
> > This patch adds platform specific details for NXP SOC LS1021A to the
> > flexcan driver code.
> >
> > Signed-off-by: Pankaj Bansal <pankaj.bansal@nxp.com>
> > Signed-off-by: Bhupesh Sharma <bhupesh.sharma@freescale.com>
> > Reviewed-by: Zhengxiong Jin <Jason.Jin@freescale.com>
> > Reviewed-by: Poonam Aggrwal <poonam.aggrwal@nxp.com>
> > ---
> > Changes in v3:
> >   - Add LS1021 in FLEXCAN hardware feature flags table
> >   - Kept LS1021 compatible in one line, even if it's more than 80
> >     chars.
> >   - Add PERR_STATE quirk and USE_OFF_TIMESTAMP quirk and
> >     ENABLE_EACEN_RRS quirk for LS1021A.
> >   - Tested on LS1021A using "cangen can0 -D 11223344DEADBEEF -L 8 -R"
> >     and "cangen can0 -D 11223344DEADBEEF -L 8"
> > Changes in v2:
> >   - No change.
> >
> >  drivers/net/can/flexcan.c | 9 +++++++++
> >  1 file changed, 9 insertions(+)
> >
> > diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
> > index 4c873fb..21d0dd8 100644
> > --- a/drivers/net/can/flexcan.c
> > +++ b/drivers/net/can/flexcan.c
> > @@ -190,6 +190,7 @@
> >   *   MX53  FlexCAN2  03.00.00.00    yes        no        no       no        no
> >   *   MX6s  FlexCAN3  10.00.12.00    yes       yes        no       no       yes
> >   *   VF610 FlexCAN3  ?               no       yes         ?      yes       yes?
> > + * LS1021A FlexCAN2  03.00.04.00     no       yes        no       no       yes
> 
> Out of curiosity, where have you got the IP core version from?
> 

I got this version from Bill Of Material details of LS1021A SOC.

> >   *
> >   * Some SOCs do not have the RX_WARN & TX_WARN interrupt line
> connected.
> >   */
> > @@ -304,6 +305,13 @@ static const struct flexcan_devtype_data
> fsl_vf610_devtype_data = {
> >  		FLEXCAN_QUIRK_DISABLE_MECR |
> FLEXCAN_QUIRK_USE_OFF_TIMESTAMP,  };
> >
> > +/* LS1021A-Rev2 has functional RX-FIFO mode  */
> 
> That comment is obsolete, isn't it? If it's a noteworthy feature, add it to the
> overview table above.

Actually in LS1021A Rev1 RX-FIFO mode is broken. Rev1 is initial release, and Rev2
Is final release. Which is why this comment.

> 
> > +static const struct flexcan_devtype_data fsl_ls1021a_r2_devtype_data = {
> > +	.quirks = FLEXCAN_QUIRK_DISABLE_RXFG |
> FLEXCAN_QUIRK_ENABLE_EACEN_RRS |
> > +		FLEXCAN_QUIRK_DISABLE_MECR |
> FLEXCAN_QUIRK_BROKEN_PERR_STATE |
> > +		FLEXCAN_QUIRK_USE_OFF_TIMESTAMP,
> > +};
> > +
> >  static const struct can_bittiming_const flexcan_bittiming_const = {
> >  	.name = DRV_NAME,
> >  	.tseg1_min = 4,
> > @@ -1248,6 +1256,7 @@ static const struct of_device_id
> flexcan_of_match[] = {
> >  	{ .compatible = "fsl,imx25-flexcan", .data =
> &fsl_p1010_devtype_data, },
> >  	{ .compatible = "fsl,p1010-flexcan", .data =
> &fsl_p1010_devtype_data, },
> >  	{ .compatible = "fsl,vf610-flexcan", .data =
> > &fsl_vf610_devtype_data, },
> > +	{ .compatible = "fsl,ls1021ar2-flexcan", .data =
> > +&fsl_ls1021a_r2_devtype_data, },
> >  	{ /* sentinel */ },
> >  };
> >  MODULE_DEVICE_TABLE(of, flexcan_of_match);
> >
> 
> Marc
> 
> --
> Pengutronix e.K.                  | Marc Kleine-Budde           |
> Industrial Linux Solutions        | Phone: +49-231-2826-924     |
> Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
> Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH v3 2/2] can: flexcan: adding platform specific details for LS1021A
  2017-11-23 10:01         ` Pankaj Bansal
@ 2017-11-23 10:07           ` Marc Kleine-Budde
  2017-11-23 12:01             ` Pankaj Bansal
  0 siblings, 1 reply; 52+ messages in thread
From: Marc Kleine-Budde @ 2017-11-23 10:07 UTC (permalink / raw)
  To: Pankaj Bansal, wg, linux-can; +Cc: Varun Sethi, Poonam Aggrwal, Bhupesh Sharma


[-- Attachment #1.1: Type: text/plain, Size: 1979 bytes --]

On 11/23/2017 11:01 AM, Pankaj Bansal wrote:
>>> diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
>>> index 4c873fb..21d0dd8 100644
>>> --- a/drivers/net/can/flexcan.c
>>> +++ b/drivers/net/can/flexcan.c
>>> @@ -190,6 +190,7 @@
>>>   *   MX53  FlexCAN2  03.00.00.00    yes        no        no       no        no
>>>   *   MX6s  FlexCAN3  10.00.12.00    yes       yes        no       no       yes
>>>   *   VF610 FlexCAN3  ?               no       yes         ?      yes       yes?
>>> + * LS1021A FlexCAN2  03.00.04.00     no       yes        no       no       yes
>>
>> Out of curiosity, where have you got the IP core version from?

> I got this version from Bill Of Material details of LS1021A SOC.

Oh, nice. Do you have access to the vf610 list to get the IP core version?


>>>   *
>>>   * Some SOCs do not have the RX_WARN & TX_WARN interrupt line
>> connected.
>>>   */
>>> @@ -304,6 +305,13 @@ static const struct flexcan_devtype_data
>> fsl_vf610_devtype_data = {
>>>  		FLEXCAN_QUIRK_DISABLE_MECR |
>> FLEXCAN_QUIRK_USE_OFF_TIMESTAMP,  };
>>>
>>> +/* LS1021A-Rev2 has functional RX-FIFO mode  */
>>
>> That comment is obsolete, isn't it? If it's a noteworthy feature, add it to the
>> overview table above.
> 
> Actually in LS1021A Rev1 RX-FIFO mode is broken. Rev1 is initial release, and Rev2
> Is final release. Which is why this comment.

Ahh, can you please add this to the table above.

You're not using the mailbox mode anymore, right? This means the driver
should work with the broken r1 silicon, too? Are any of these silicons
out in the wild? Does it make sense to use "fsl,ls1021ar1-flexcan" for
this compatible?

Marc

-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 52+ messages in thread

* RE: [PATCH v3 2/2] can: flexcan: adding platform specific details for LS1021A
  2017-11-23 10:07           ` Marc Kleine-Budde
@ 2017-11-23 12:01             ` Pankaj Bansal
  2017-11-23 12:33               ` Marc Kleine-Budde
  0 siblings, 1 reply; 52+ messages in thread
From: Pankaj Bansal @ 2017-11-23 12:01 UTC (permalink / raw)
  To: Marc Kleine-Budde, wg, linux-can
  Cc: Varun Sethi, Poonam Aggrwal, Bhupesh Sharma

HI Marc,

> -----Original Message-----
> From: Marc Kleine-Budde [mailto:mkl@pengutronix.de]
> Sent: Thursday, November 23, 2017 3:38 PM
> To: Pankaj Bansal <pankaj.bansal@nxp.com>; wg@grandegger.com; linux-
> can@vger.kernel.org
> Cc: Varun Sethi <V.Sethi@nxp.com>; Poonam Aggrwal
> <poonam.aggrwal@nxp.com>; Bhupesh Sharma
> <bhupesh.sharma@freescale.com>
> Subject: Re: [PATCH v3 2/2] can: flexcan: adding platform specific details for
> LS1021A
> 
> On 11/23/2017 11:01 AM, Pankaj Bansal wrote:
> >>> diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
> >>> index 4c873fb..21d0dd8 100644
> >>> --- a/drivers/net/can/flexcan.c
> >>> +++ b/drivers/net/can/flexcan.c
> >>> @@ -190,6 +190,7 @@
> >>>   *   MX53  FlexCAN2  03.00.00.00    yes        no        no       no        no
> >>>   *   MX6s  FlexCAN3  10.00.12.00    yes       yes        no       no       yes
> >>>   *   VF610 FlexCAN3  ?               no       yes         ?      yes       yes?
> >>> + * LS1021A FlexCAN2  03.00.04.00     no       yes        no       no       yes
> >>
> >> Out of curiosity, where have you got the IP core version from?
> 
> > I got this version from Bill Of Material details of LS1021A SOC.
> 
> Oh, nice. Do you have access to the vf610 list to get the IP core version?
> 

I am sorry but I don't have access to vf610 list.

> 
> >>>   *
> >>>   * Some SOCs do not have the RX_WARN & TX_WARN interrupt line
> >> connected.
> >>>   */
> >>> @@ -304,6 +305,13 @@ static const struct flexcan_devtype_data
> >> fsl_vf610_devtype_data = {
> >>>  		FLEXCAN_QUIRK_DISABLE_MECR |
> >> FLEXCAN_QUIRK_USE_OFF_TIMESTAMP,  };
> >>>
> >>> +/* LS1021A-Rev2 has functional RX-FIFO mode  */
> >>
> >> That comment is obsolete, isn't it? If it's a noteworthy feature, add
> >> it to the overview table above.
> >
> > Actually in LS1021A Rev1 RX-FIFO mode is broken. Rev1 is initial
> > release, and Rev2 Is final release. Which is why this comment.
> 
> Ahh, can you please add this to the table above.

I have already added LS1021A in table.

> 
> You're not using the mailbox mode anymore, right? 

No, we are using timestamp based RX fifo.

> This means the driver should work with the broken r1 silicon, too?

I would think so. But as r1 is not officially supported version, I have not checked it.

> Are any of these silicons out in
> the wild? Does it make sense to use "fsl,ls1021ar1-flexcan" for this
> compatible?

No. r1 silicon has not been delivered to any customer. We need not to support
r1 silicon in compatible, as its not official supported version.

> 
> Marc
> 
> --
> Pengutronix e.K.                  | Marc Kleine-Budde           |
> Industrial Linux Solutions        | Phone: +49-231-2826-924     |
> Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
> Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH v3 2/2] can: flexcan: adding platform specific details for LS1021A
  2017-11-23 12:01             ` Pankaj Bansal
@ 2017-11-23 12:33               ` Marc Kleine-Budde
  0 siblings, 0 replies; 52+ messages in thread
From: Marc Kleine-Budde @ 2017-11-23 12:33 UTC (permalink / raw)
  To: Pankaj Bansal, wg, linux-can; +Cc: Varun Sethi, Poonam Aggrwal, Bhupesh Sharma


[-- Attachment #1.1: Type: text/plain, Size: 1571 bytes --]

On 11/23/2017 01:01 PM, Pankaj Bansal wrote:
>>> I got this version from Bill Of Material details of LS1021A SOC.
>>
>> Oh, nice. Do you have access to the vf610 list to get the IP core version?
> 
> I am sorry but I don't have access to vf610 list.

Ok.

>>> Actually in LS1021A Rev1 RX-FIFO mode is broken. Rev1 is initial
>>> release, and Rev2 Is final release. Which is why this comment.
>>
>> Ahh, can you please add this to the table above.
> 
> I have already added LS1021A in table.

Yes, but not the information that the r1 has a broken FIFO.

>> You're not using the mailbox mode anymore, right? 
> 
> No, we are using timestamp based RX fifo.
> 
>> This means the driver should work with the broken r1 silicon, too?
> 
> I would think so. But as r1 is not officially supported version, I
> have not checked it.

Ok - I don't mind if nxp doesn't support it or not...

>> Are any of these silicons out in
>> the wild? Does it make sense to use "fsl,ls1021ar1-flexcan" for this
>> compatible?
> 
> No. r1 silicon has not been delivered to any customer. We need not to support
> r1 silicon in compatible, as its not official supported version.

...but if it's not out in the wild we don't have to add it. And wait
until someone complains :)

Marc

-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH v2 2/2] can: flexcan: adding platform specific details for LS1021A
       [not found]                       ` <CALw8SCUGuCmq+S_9-o-ZDYJuASveuj71WH97jYsEvNZX2N5ZXA@mail.gmail.com>
@ 2017-11-23 20:17                         ` Mirza Krak
  2017-11-23 21:05                           ` Wolfgang Grandegger
  2017-11-27 16:34                           ` Stefan Agner
  0 siblings, 2 replies; 52+ messages in thread
From: Mirza Krak @ 2017-11-23 20:17 UTC (permalink / raw)
  To: Marc Kleine-Budde
  Cc: ZHU Yi (ST-FIR/ENG1-Zhu),
	Pankaj Bansal, Wolfgang Grandegger, linux-can, Varun Sethi,
	Poonam Aggrwal, Stefan Agner

2017-11-23 21:12 GMT+01:00 Mirza Krak <mirza.krak@gmail.com>:
> On Nov 22, 2017 13:00, "Marc Kleine-Budde" <mkl@pengutronix.de> wrote:
>

< snip >

>
> Cc'ed Stefan Agner - maybe he has access to this SoC.
>
>> @Marc, @Wolfgang,
>> What do you think? Or shall we fix first and then wait?
>
> Let's wait if Stefan can test, otherwise just fix.
>
>
> I have access to an vf610 and can test CAN stuff.
>
> What is it more specifically we want to test? I read the thread but not
> completely clear to me.

Sent for my phone client initially which inserted HTML and it was not
delivered to linux-can. Re-send....

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH v2 2/2] can: flexcan: adding platform specific details for LS1021A
  2017-11-23 20:17                         ` Mirza Krak
@ 2017-11-23 21:05                           ` Wolfgang Grandegger
  2017-11-24 16:02                             ` Mirza Krak
  2017-11-27 16:34                           ` Stefan Agner
  1 sibling, 1 reply; 52+ messages in thread
From: Wolfgang Grandegger @ 2017-11-23 21:05 UTC (permalink / raw)
  To: Mirza Krak, Marc Kleine-Budde
  Cc: ZHU Yi (ST-FIR/ENG1-Zhu),
	Pankaj Bansal, linux-can, Varun Sethi, Poonam Aggrwal,
	Stefan Agner

Hello Mirza,

Am 23.11.2017 um 21:17 schrieb Mirza Krak:
> 2017-11-23 21:12 GMT+01:00 Mirza Krak <mirza.krak@gmail.com>:
>> On Nov 22, 2017 13:00, "Marc Kleine-Budde" <mkl@pengutronix.de> wrote:
>>
> 
> < snip >
> 
>>
>> Cc'ed Stefan Agner - maybe he has access to this SoC.
>>
>>> @Marc, @Wolfgang,
>>> What do you think? Or shall we fix first and then wait?
>>
>> Let's wait if Stefan can test, otherwise just fix.
>>
>>
>> I have access to an vf610 and can test CAN stuff.
>>
>> What is it more specifically we want to test? I read the thread but not
>> completely clear to me.

We want to know how the reporting of CAN error state changes 
"error-active" -> "warning" -> "error-passive" -> "bus-off" and back is 
working on that hardware.

You can test such state changes as show below. First setup the interface 
and start a session calling "candump" to report the state changes:

   # ip link set can0 up type can bitrate 500000 restart-ms 100
   # candump -td -e any,0:0,#FFFFFFFF

Then

1. disconnect the cable and send messages with "cangen"

    # cangen -i can0

"candump" should then report the error state changes "error-active" -> 
"warning" -> "error-passive". If you don't see "error-passive", the 
hardware needs the FLEXCAN_QUIRK_BROKEN_PERR_STATE as well. Then 
reconnect the cable and send messages till the "error active" state is 
reached (again with "cangen").

2. The second test is quite similar. Instead of disconnecting the cable, 
short-circuit the CAN low and high lines. The device should then go to 
"bus-off".

Thanks for testing,

Wolfgang.



^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH v2 2/2] can: flexcan: adding platform specific details for LS1021A
  2017-11-23 21:05                           ` Wolfgang Grandegger
@ 2017-11-24 16:02                             ` Mirza Krak
  2017-11-24 19:19                               ` Wolfgang Grandegger
  0 siblings, 1 reply; 52+ messages in thread
From: Mirza Krak @ 2017-11-24 16:02 UTC (permalink / raw)
  To: Wolfgang Grandegger
  Cc: Marc Kleine-Budde, ZHU Yi (ST-FIR/ENG1-Zhu),
	Pankaj Bansal, linux-can, Varun Sethi, Poonam Aggrwal,
	Stefan Agner

2017-11-23 22:05 GMT+01:00 Wolfgang Grandegger <wg@grandegger.com>:
> Hello Mirza,
>
> Am 23.11.2017 um 21:17 schrieb Mirza Krak:
>>
>> 2017-11-23 21:12 GMT+01:00 Mirza Krak <mirza.krak@gmail.com>:
>>>
>>> On Nov 22, 2017 13:00, "Marc Kleine-Budde" <mkl@pengutronix.de> wrote:
>>>
>>
>> < snip >
>>
>>>
>>> Cc'ed Stefan Agner - maybe he has access to this SoC.
>>>
>>>> @Marc, @Wolfgang,
>>>> What do you think? Or shall we fix first and then wait?
>>>
>>>
>>> Let's wait if Stefan can test, otherwise just fix.
>>>
>>>
>>> I have access to an vf610 and can test CAN stuff.
>>>
>>> What is it more specifically we want to test? I read the thread but not
>>> completely clear to me.
>
>
> We want to know how the reporting of CAN error state changes "error-active"
> -> "warning" -> "error-passive" -> "bus-off" and back is working on that
> hardware.
>
> You can test such state changes as show below. First setup the interface and
> start a session calling "candump" to report the state changes:
>
>   # ip link set can0 up type can bitrate 500000 restart-ms 100
>   # candump -td -e any,0:0,#FFFFFFFF
>
> Then
>
> 1. disconnect the cable and send messages with "cangen"
>
>    # cangen -i can0
>
> "candump" should then report the error state changes "error-active" ->
> "warning" -> "error-passive". If you don't see "error-passive", the hardware
> needs the FLEXCAN_QUIRK_BROKEN_PERR_STATE as well. Then reconnect the cable
> and send messages till the "error active" state is reached (again with
> "cangen").

This was the result of this test:

root@colibri-vf:~# ./candump -td -e can0,0:0,#FFFFFFFF
 (000.000000)  can0  0C8   [8]  E7 D5 75 20 1C F8 AA 6D
 (000.200201)  can0  7CD   [8]  58 5F B1 1E D7 AB 3C 15
 (000.200123)  can0  7FD   [8]  EC 43 EF 11 BB 76 50 4F
 (000.200119)  can0  20D   [8]  64 E0 A6 74 A2 A4 22 42
 (000.200115)  can0  226   [7]  CB 4D 12 46 F3 37 F1
 (000.200000)  can0  42F   [0]
 (000.200245)  can0  0F9   [8]  AD 61 16 77 0A 64 50 5C
 (000.199983)  can0  76E   [0]
 (000.200206)  can0  3CB   [6]  53 28 03 34 98 43
 (000.200152)  can0  230   [8]  70 EF 66 38 2D BA 5D 4D
 (000.200106)  can0  568   [8]  E8 30 AE 1C 75 77 4E 5E
 (000.200274)  can0  20000004   [8]  00 04 00 00 00 00 00 00   ERRORFRAME
controller-problem{rx-error-warning}

and the statistics

root@colibri-vf:~# ip -d -s link show can0
2: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state
UNKNOWN mode DEFAULT group default qlen 10
    link/can  promiscuity 0
    can state ERROR-WARNING (berr-counter tx 0 rx 128) restart-ms 100
 bitrate 496240 sample-point 0.857
 tq 143 prop-seg 5 phase-seg1 6 phase-seg2 2 sjw 1
 flexcan: tseg1 4..16 tseg2 2..8 sjw 1..4 brp 1..256 brp-inc 1
 clock 83368421
 re-started bus-errors arbit-lost error-warn error-pass bus-off
 0          0          0          1          0          0         numtxqueues 1
    RX: bytes  packets  errors  dropped overrun mcast
    8          1        0       0       0       0
    TX: bytes  packets  errors  dropped carrier collsns
    69         11       0       0       0       0

I ran out of time as wanted to test a bit more as I was confused that
it is showing RX errors on the first test? I was not able to get it
back to ERROR-ACTIVE from ERROR-WARNING either. But posted result
anyway


> 2. The second test is quite similar. Instead of disconnecting the cable,
> short-circuit the CAN low and high lines. The device should then go to
> "bus-off".

And this one:

root@colibri-vf:~# ./candump -td -e any,0:0,#FFFFFFFF
 (000.000000)  can0  20000004   [8]  00 20 00 00 00 00 00 00   ERRORFRAME
controller-problem{tx-error-passive}
 (000.000809)  can0  20000040   [8]  00 00 00 00 00 00 00 00   ERRORFRAME
bus-off
 (000.109797)  can0  20000100   [8]  00 00 00 00 00 00 00 00   ERRORFRAME
restarted-after-bus-off
 (000.100551)  can0  20000004   [8]  00 20 00 00 00 00 00 00   ERRORFRAME
controller-problem{tx-error-passive}
 (000.000823)  can0  20000040   [8]  00 00 00 00 00 00 00 00   ERRORFRAME
bus-off
 (000.108644)  can0  20000100   [8]  00 00 00 00 00 00 00 00   ERRORFRAME
restarted-after-bus-off
 (000.090692)  can0  20000004   [8]  00 08 00 00 00 00 00 00   ERRORFRAME
controller-problem{tx-error-warning}
 (000.000797)  can0  20000040   [8]  00 00 00 00 00 00 00 00   ERRORFRAME
bus-off

Will try again next week when I am back at the office.

I ran my tests on 4.14 kernel.

Best Regards
Mirza

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH v2 2/2] can: flexcan: adding platform specific details for LS1021A
  2017-11-24 16:02                             ` Mirza Krak
@ 2017-11-24 19:19                               ` Wolfgang Grandegger
  2017-11-26 21:11                                 ` Mirza Krak
  0 siblings, 1 reply; 52+ messages in thread
From: Wolfgang Grandegger @ 2017-11-24 19:19 UTC (permalink / raw)
  To: Mirza Krak
  Cc: Marc Kleine-Budde, ZHU Yi (ST-FIR/ENG1-Zhu),
	Pankaj Bansal, linux-can, Varun Sethi, Poonam Aggrwal,
	Stefan Agner

Hello Mirza,

Am 24.11.2017 um 17:02 schrieb Mirza Krak:
> 2017-11-23 22:05 GMT+01:00 Wolfgang Grandegger <wg@grandegger.com>:
>> Hello Mirza,
>>
>> Am 23.11.2017 um 21:17 schrieb Mirza Krak:
>>>
>>> 2017-11-23 21:12 GMT+01:00 Mirza Krak <mirza.krak@gmail.com>:
>>>>
>>>> On Nov 22, 2017 13:00, "Marc Kleine-Budde" <mkl@pengutronix.de> wrote:
>>>>
>>>
>>> < snip >
>>>
>>>>
>>>> Cc'ed Stefan Agner - maybe he has access to this SoC.
>>>>
>>>>> @Marc, @Wolfgang,
>>>>> What do you think? Or shall we fix first and then wait?
>>>>
>>>>
>>>> Let's wait if Stefan can test, otherwise just fix.
>>>>
>>>>
>>>> I have access to an vf610 and can test CAN stuff.
>>>>
>>>> What is it more specifically we want to test? I read the thread but not
>>>> completely clear to me.
>>
>>
>> We want to know how the reporting of CAN error state changes "error-active"
>> -> "warning" -> "error-passive" -> "bus-off" and back is working on that
>> hardware.
>>
>> You can test such state changes as show below. First setup the interface and
>> start a session calling "candump" to report the state changes:
>>
>>    # ip link set can0 up type can bitrate 500000 restart-ms 100
>>    # candump -td -e any,0:0,#FFFFFFFF
>>
>> Then
>>
>> 1. disconnect the cable and send messages with "cangen"
>>
>>     # cangen -i can0
>>
>> "candump" should then report the error state changes "error-active" ->
>> "warning" -> "error-passive". If you don't see "error-passive", the hardware
>> needs the FLEXCAN_QUIRK_BROKEN_PERR_STATE as well. Then reconnect the cable
>> and send messages till the "error active" state is reached (again with
>> "cangen").
> 
> This was the result of this test:
> 
> root@colibri-vf:~# ./candump -td -e can0,0:0,#FFFFFFFF
>   (000.000000)  can0  0C8   [8]  E7 D5 75 20 1C F8 AA 6D
>   (000.200201)  can0  7CD   [8]  58 5F B1 1E D7 AB 3C 15
>   (000.200123)  can0  7FD   [8]  EC 43 EF 11 BB 76 50 4F
>   (000.200119)  can0  20D   [8]  64 E0 A6 74 A2 A4 22 42
>   (000.200115)  can0  226   [7]  CB 4D 12 46 F3 37 F1
>   (000.200000)  can0  42F   [0]
>   (000.200245)  can0  0F9   [8]  AD 61 16 77 0A 64 50 5C
>   (000.199983)  can0  76E   [0]
>   (000.200206)  can0  3CB   [6]  53 28 03 34 98 43
>   (000.200152)  can0  230   [8]  70 EF 66 38 2D BA 5D 4D
>   (000.200106)  can0  568   [8]  E8 30 AE 1C 75 77 4E 5E
>   (000.200274)  can0  20000004   [8]  00 04 00 00 00 00 00 00   ERRORFRAME
> controller-problem{rx-error-warning}
> 
> and the statistics
> 
> root@colibri-vf:~# ip -d -s link show can0
> 2: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state
> UNKNOWN mode DEFAULT group default qlen 10
>      link/can  promiscuity 0
>      can state ERROR-WARNING (berr-counter tx 0 rx 128) restart-ms 100
>   bitrate 496240 sample-point 0.857
>   tq 143 prop-seg 5 phase-seg1 6 phase-seg2 2 sjw 1
>   flexcan: tseg1 4..16 tseg2 2..8 sjw 1..4 brp 1..256 brp-inc 1
>   clock 83368421
>   re-started bus-errors arbit-lost error-warn error-pass bus-off
>   0          0          0          1          0          0         numtxqueues 1
>      RX: bytes  packets  errors  dropped overrun mcast
>      8          1        0       0       0       0
>      TX: bytes  packets  errors  dropped carrier collsns
>      69         11       0       0       0       0
> 
> I ran out of time as wanted to test a bit more as I was confused that
> it is showing RX errors on the first test? I was not able to get it
> back to ERROR-ACTIVE from ERROR-WARNING either. But posted result
> anyway

The received error messages are counted as well.

>> 2. The second test is quite similar. Instead of disconnecting the cable,
>> short-circuit the CAN low and high lines. The device should then go to
>> "bus-off".
> 
> And this one:
> 
> root@colibri-vf:~# ./candump -td -e any,0:0,#FFFFFFFF
>   (000.000000)  can0  20000004   [8]  00 20 00 00 00 00 00 00   ERRORFRAME
> controller-problem{tx-error-passive}
>   (000.000809)  can0  20000040   [8]  00 00 00 00 00 00 00 00   ERRORFRAME
> bus-off
>   (000.109797)  can0  20000100   [8]  00 00 00 00 00 00 00 00   ERRORFRAME
> restarted-after-bus-off
>   (000.100551)  can0  20000004   [8]  00 20 00 00 00 00 00 00   ERRORFRAME
> controller-problem{tx-error-passive}
>   (000.000823)  can0  20000040   [8]  00 00 00 00 00 00 00 00   ERRORFRAME
> bus-off
>   (000.108644)  can0  20000100   [8]  00 00 00 00 00 00 00 00   ERRORFRAME
> restarted-after-bus-off
>   (000.090692)  can0  20000004   [8]  00 08 00 00 00 00 00 00   ERRORFRAME
> controller-problem{tx-error-warning}
>   (000.000797)  can0  20000040   [8]  00 00 00 00 00 00 00 00   ERRORFRAME
> bus-off
> 
> Will try again next week when I am back at the office.
> 
> I ran my tests on 4.14 kernel.

This Flexcan core needs the FLEXCAN_QUIRK_BROKEN_PERR_STATE as well, 
like all other cores. Adding that quirk for the vf610 will cure the 
problems.

Thanks for testing.

Wolfgang.

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH v2 2/2] can: flexcan: adding platform specific details for LS1021A
  2017-11-24 19:19                               ` Wolfgang Grandegger
@ 2017-11-26 21:11                                 ` Mirza Krak
  2017-11-27 14:00                                   ` Marc Kleine-Budde
  0 siblings, 1 reply; 52+ messages in thread
From: Mirza Krak @ 2017-11-26 21:11 UTC (permalink / raw)
  To: Wolfgang Grandegger
  Cc: Marc Kleine-Budde, ZHU Yi (ST-FIR/ENG1-Zhu),
	Pankaj Bansal, linux-can, Varun Sethi, Poonam Aggrwal,
	Stefan Agner

2017-11-24 20:19 GMT+01:00 Wolfgang Grandegger <wg@grandegger.com>:
> Hello Mirza,
>

< snip >

>>>
>>> You can test such state changes as show below. First setup the interface
>>> and
>>> start a session calling "candump" to report the state changes:
>>>
>>>    # ip link set can0 up type can bitrate 500000 restart-ms 100
>>>    # candump -td -e any,0:0,#FFFFFFFF
>>>
>>> Then
>>>
>>> 1. disconnect the cable and send messages with "cangen"
>>>
>>>     # cangen -i can0
>>>
>>> "candump" should then report the error state changes "error-active" ->
>>> "warning" -> "error-passive". If you don't see "error-passive", the
>>> hardware
>>> needs the FLEXCAN_QUIRK_BROKEN_PERR_STATE as well. Then reconnect the
>>> cable
>>> and send messages till the "error active" state is reached (again with
>>> "cangen").
>>
>>
>> This was the result of this test:
>>
>> root@colibri-vf:~# ./candump -td -e can0,0:0,#FFFFFFFF
>>   (000.000000)  can0  0C8   [8]  E7 D5 75 20 1C F8 AA 6D
>>   (000.200201)  can0  7CD   [8]  58 5F B1 1E D7 AB 3C 15
>>   (000.200123)  can0  7FD   [8]  EC 43 EF 11 BB 76 50 4F
>>   (000.200119)  can0  20D   [8]  64 E0 A6 74 A2 A4 22 42
>>   (000.200115)  can0  226   [7]  CB 4D 12 46 F3 37 F1
>>   (000.200000)  can0  42F   [0]
>>   (000.200245)  can0  0F9   [8]  AD 61 16 77 0A 64 50 5C
>>   (000.199983)  can0  76E   [0]
>>   (000.200206)  can0  3CB   [6]  53 28 03 34 98 43
>>   (000.200152)  can0  230   [8]  70 EF 66 38 2D BA 5D 4D
>>   (000.200106)  can0  568   [8]  E8 30 AE 1C 75 77 4E 5E
>>   (000.200274)  can0  20000004   [8]  00 04 00 00 00 00 00 00   ERRORFRAME
>> controller-problem{rx-error-warning}
>>
>> and the statistics
>>
>> root@colibri-vf:~# ip -d -s link show can0
>> 2: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state
>> UNKNOWN mode DEFAULT group default qlen 10
>>      link/can  promiscuity 0
>>      can state ERROR-WARNING (berr-counter tx 0 rx 128) restart-ms 100
>>   bitrate 496240 sample-point 0.857
>>   tq 143 prop-seg 5 phase-seg1 6 phase-seg2 2 sjw 1
>>   flexcan: tseg1 4..16 tseg2 2..8 sjw 1..4 brp 1..256 brp-inc 1
>>   clock 83368421
>>   re-started bus-errors arbit-lost error-warn error-pass bus-off
>>   0          0          0          1          0          0
>> numtxqueues 1
>>      RX: bytes  packets  errors  dropped overrun mcast
>>      8          1        0       0       0       0
>>      TX: bytes  packets  errors  dropped carrier collsns
>>      69         11       0       0       0       0
>>
>> I ran out of time as wanted to test a bit more as I was confused that
>> it is showing RX errors on the first test? I was not able to get it
>> back to ERROR-ACTIVE from ERROR-WARNING either. But posted result
>> anyway
>
>
> The received error messages are counted as well.
>
>>> 2. The second test is quite similar. Instead of disconnecting the cable,
>>> short-circuit the CAN low and high lines. The device should then go to
>>> "bus-off".
>>
>>
>> And this one:
>>
>> root@colibri-vf:~# ./candump -td -e any,0:0,#FFFFFFFF
>>   (000.000000)  can0  20000004   [8]  00 20 00 00 00 00 00 00   ERRORFRAME
>> controller-problem{tx-error-passive}
>>   (000.000809)  can0  20000040   [8]  00 00 00 00 00 00 00 00   ERRORFRAME
>> bus-off
>>   (000.109797)  can0  20000100   [8]  00 00 00 00 00 00 00 00   ERRORFRAME
>> restarted-after-bus-off
>>   (000.100551)  can0  20000004   [8]  00 20 00 00 00 00 00 00   ERRORFRAME
>> controller-problem{tx-error-passive}
>>   (000.000823)  can0  20000040   [8]  00 00 00 00 00 00 00 00   ERRORFRAME
>> bus-off
>>   (000.108644)  can0  20000100   [8]  00 00 00 00 00 00 00 00   ERRORFRAME
>> restarted-after-bus-off
>>   (000.090692)  can0  20000004   [8]  00 08 00 00 00 00 00 00   ERRORFRAME
>> controller-problem{tx-error-warning}
>>   (000.000797)  can0  20000040   [8]  00 00 00 00 00 00 00 00   ERRORFRAME
>> bus-off
>>
>> Will try again next week when I am back at the office.
>>
>> I ran my tests on 4.14 kernel.
>
>
> This Flexcan core needs the FLEXCAN_QUIRK_BROKEN_PERR_STATE as well, like
> all other cores. Adding that quirk for the vf610 will cure the problems.
>

I will probably get some time during the coming week to test adding
FLEXCAN_QUIRK_BROKEN_PERR_STATE and I can send a patch if it all looks
good.

-- 
Med Vänliga Hälsningar / Best Regards

Mirza Krak

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH v2 2/2] can: flexcan: adding platform specific details for LS1021A
  2017-11-26 21:11                                 ` Mirza Krak
@ 2017-11-27 14:00                                   ` Marc Kleine-Budde
       [not found]                                     ` <CALw8SCVNqN0SM1e=bxXZFMVL0VN0iy0LgFj9Hv4BeRwAbb9Y6A@mail.gmail.com>
  0 siblings, 1 reply; 52+ messages in thread
From: Marc Kleine-Budde @ 2017-11-27 14:00 UTC (permalink / raw)
  To: Mirza Krak, Wolfgang Grandegger
  Cc: ZHU Yi (ST-FIR/ENG1-Zhu),
	Pankaj Bansal, linux-can, Varun Sethi, Poonam Aggrwal,
	Stefan Agner


[-- Attachment #1.1: Type: text/plain, Size: 883 bytes --]

On 11/26/2017 10:11 PM, Mirza Krak wrote:
>>> Will try again next week when I am back at the office.
>>>
>>> I ran my tests on 4.14 kernel.
>>
>> This Flexcan core needs the FLEXCAN_QUIRK_BROKEN_PERR_STATE as well, like
>> all other cores. Adding that quirk for the vf610 will cure the problems.
> 
> I will probably get some time during the coming week to test adding
> FLEXCAN_QUIRK_BROKEN_PERR_STATE and I can send a patch if it all looks
> good.

I've created a patch, waiting for your Tested-by.

https://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can.git/log/?h=testing

Marc

-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH v2 2/2] can: flexcan: adding platform specific details for LS1021A
  2017-11-23 20:17                         ` Mirza Krak
  2017-11-23 21:05                           ` Wolfgang Grandegger
@ 2017-11-27 16:34                           ` Stefan Agner
  1 sibling, 0 replies; 52+ messages in thread
From: Stefan Agner @ 2017-11-27 16:34 UTC (permalink / raw)
  To: Mirza Krak, Marc Kleine-Budde
  Cc: ZHU Yi (ST-FIR/ENG1-Zhu),
	Pankaj Bansal, Wolfgang Grandegger, linux-can, Varun Sethi,
	Poonam Aggrwal

On 2017-11-23 21:17, Mirza Krak wrote:
> 2017-11-23 21:12 GMT+01:00 Mirza Krak <mirza.krak@gmail.com>:
>> On Nov 22, 2017 13:00, "Marc Kleine-Budde" <mkl@pengutronix.de> wrote:
>>
> 
> < snip >
> 
>>
>> Cc'ed Stefan Agner - maybe he has access to this SoC.
>>

Without reading the full thread, I did some testing back when we added
vf610 support:
http://lists.infradead.org/pipermail/linux-arm-kernel/2014-July/275903.html

>>> @Marc, @Wolfgang,
>>> What do you think? Or shall we fix first and then wait?
>>
>> Let's wait if Stefan can test, otherwise just fix.
>>
>>
>> I have access to an vf610 and can test CAN stuff.
>>
>> What is it more specifically we want to test? I read the thread but not
>> completely clear to me.
> 

Thanks Mirza for your testing!

--
Stefan

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH v2 2/2] can: flexcan: adding platform specific details for LS1021A
       [not found]                                     ` <CALw8SCVNqN0SM1e=bxXZFMVL0VN0iy0LgFj9Hv4BeRwAbb9Y6A@mail.gmail.com>
@ 2017-11-28 22:11                                       ` Mirza Krak
  2017-12-01 10:12                                         ` Mirza Krak
  0 siblings, 1 reply; 52+ messages in thread
From: Mirza Krak @ 2017-11-28 22:11 UTC (permalink / raw)
  To: Marc Kleine-Budde
  Cc: Wolfgang Grandegger, ZHU Yi (ST-FIR/ENG1-Zhu),
	Pankaj Bansal, linux-can, Varun Sethi, Poonam Aggrwal,
	Stefan Agner

2017-11-28 23:09 GMT+01:00 Mirza Krak <mirza.krak@gmail.com>:
> 2017-11-27 15:00 GMT+01:00 Marc Kleine-Budde <mkl@pengutronix.de>:
>>
>> On 11/26/2017 10:11 PM, Mirza Krak wrote:
>> >>> Will try again next week when I am back at the office.
>> >>>
>> >>> I ran my tests on 4.14 kernel.
>> >>
>> >> This Flexcan core needs the FLEXCAN_QUIRK_BROKEN_PERR_STATE as well,
>> >> like
>> >> all other cores. Adding that quirk for the vf610 will cure the
>> >> problems.
>> >
>> > I will probably get some time during the coming week to test adding
>> > FLEXCAN_QUIRK_BROKEN_PERR_STATE and I can send a patch if it all looks
>> > good.
>>
>> I've created a patch, waiting for your Tested-by.
>>
>>
>> https://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can.git/log/?h=testing
>
>
> Great thanks. I will not have access to hardware until Friday this week,
> hope you are patient :)

Grrr, stupid email client (last mail went out as HTML), sorry.

Re-send as plain-text for it to reach mailing list as well.

-- 
Med Vänliga Hälsningar / Best Regards

Mirza Krak

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH v2 2/2] can: flexcan: adding platform specific details for LS1021A
  2017-11-28 22:11                                       ` Mirza Krak
@ 2017-12-01 10:12                                         ` Mirza Krak
  2017-12-01 10:32                                           ` Marc Kleine-Budde
  0 siblings, 1 reply; 52+ messages in thread
From: Mirza Krak @ 2017-12-01 10:12 UTC (permalink / raw)
  To: Marc Kleine-Budde
  Cc: Wolfgang Grandegger, ZHU Yi (ST-FIR/ENG1-Zhu),
	Pankaj Bansal, linux-can, Varun Sethi, Poonam Aggrwal,
	Stefan Agner

2017-11-28 23:11 GMT+01:00 Mirza Krak <mirza.krak@gmail.com>:
> 2017-11-28 23:09 GMT+01:00 Mirza Krak <mirza.krak@gmail.com>:
>> 2017-11-27 15:00 GMT+01:00 Marc Kleine-Budde <mkl@pengutronix.de>:
>>>
>>> On 11/26/2017 10:11 PM, Mirza Krak wrote:
>>> >>> Will try again next week when I am back at the office.
>>> >>>
>>> >>> I ran my tests on 4.14 kernel.
>>> >>
>>> >> This Flexcan core needs the FLEXCAN_QUIRK_BROKEN_PERR_STATE as well,
>>> >> like
>>> >> all other cores. Adding that quirk for the vf610 will cure the
>>> >> problems.
>>> >
>>> > I will probably get some time during the coming week to test adding
>>> > FLEXCAN_QUIRK_BROKEN_PERR_STATE and I can send a patch if it all looks
>>> > good.
>>>
>>> I've created a patch, waiting for your Tested-by.
>>>
>>>
>>> https://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can.git/log/?h=testing

Tested-by: Mirza Krak <mirza.krak@gmail.com>


Test results:

1. Not connected and then connected

    root@colibri-vf:~# ./candump -td -e any,0:0,#FFFFFFFF
    (000.000000)  can0  20000004   [8]  00 04 00 00 00 00 00 00   ERRORFRAME
              controller-problem{rx-error-warning}
    (000.000120)  can0  20000004   [8]  00 10 00 00 00 00 00 00   ERRORFRAME
              controller-problem{rx-error-passive}

And I also get the following:

    (000.000011)  can0  20000004   [8]  00 04 00 00 00 00 00 00   ERRORFRAME
              controller-problem{rx-error-warning}

and

(000.000008)  can0  20000004   [8]  00 40 00 00 00 00 00 00   ERRORFRAME
              controller-problem{back-to-error-active}

When I re-connect to the network.

2. Short on CAN_H and CAN_L

    root@colibri-vf:~# ./candump -td -e any,0:0,#FFFFFFFF
    (000.000000)  can0  20000004   [8]  00 08 00 00 00 00 00 00   ERRORFRAME
              controller-problem{tx-error-warning}
    (000.000043)  can0  20000004   [8]  00 20 00 00 00 00 00 00   ERRORFRAME
              controller-problem{tx-error-passive}
    (000.000745)  can0  20000040   [8]  00 00 00 00 00 00 00 00   ERRORFRAME
              bus-off
    (000.100306)  can0  20000100   [8]  00 00 00 00 00 00 00 00   ERRORFRAME
              restarted-after-bus-off
    (000.111280)  can0  20000004   [8]  00 08 00 00 00 00 00 00   ERRORFRAME
              controller-problem{tx-error-warning}
    (000.000034)  can0  20000004   [8]  00 20 00 00 00 00 00 00   ERRORFRAME
              controller-problem{tx-error-passive}
    (000.000759)  can0  20000040   [8]  00 00 00 00 00 00 00 00   ERRORFRAME
              bus-off

-- 
Med Vänliga Hälsningar / Best Regards

Mirza Krak

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [PATCH v2 2/2] can: flexcan: adding platform specific details for LS1021A
  2017-12-01 10:12                                         ` Mirza Krak
@ 2017-12-01 10:32                                           ` Marc Kleine-Budde
  0 siblings, 0 replies; 52+ messages in thread
From: Marc Kleine-Budde @ 2017-12-01 10:32 UTC (permalink / raw)
  To: Mirza Krak
  Cc: Wolfgang Grandegger, ZHU Yi (ST-FIR/ENG1-Zhu),
	Pankaj Bansal, linux-can, Varun Sethi, Poonam Aggrwal,
	Stefan Agner


[-- Attachment #1.1: Type: text/plain, Size: 1277 bytes --]

On 12/01/2017 11:12 AM, Mirza Krak wrote:
> 2017-11-28 23:11 GMT+01:00 Mirza Krak <mirza.krak@gmail.com>:
>> 2017-11-28 23:09 GMT+01:00 Mirza Krak <mirza.krak@gmail.com>:
>>> 2017-11-27 15:00 GMT+01:00 Marc Kleine-Budde <mkl@pengutronix.de>:
>>>>
>>>> On 11/26/2017 10:11 PM, Mirza Krak wrote:
>>>>>>> Will try again next week when I am back at the office.
>>>>>>>
>>>>>>> I ran my tests on 4.14 kernel.
>>>>>>
>>>>>> This Flexcan core needs the FLEXCAN_QUIRK_BROKEN_PERR_STATE as well,
>>>>>> like
>>>>>> all other cores. Adding that quirk for the vf610 will cure the
>>>>>> problems.
>>>>>
>>>>> I will probably get some time during the coming week to test adding
>>>>> FLEXCAN_QUIRK_BROKEN_PERR_STATE and I can send a patch if it all looks
>>>>> good.
>>>>
>>>> I've created a patch, waiting for your Tested-by.
>>>>
>>>>
>>>> https://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can.git/log/?h=testing
> 
> Tested-by: Mirza Krak <mirza.krak@gmail.com>

Tnx,
Marc

-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 52+ messages in thread

end of thread, other threads:[~2017-12-01 10:32 UTC | newest]

Thread overview: 52+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-11-10  9:59 [PATCH 1/2] can: flexcan: Remodel FlexCAN register r/w APIs for big endian FlexCAN controllers Pankaj Bansal
2017-11-10  9:59 ` [PATCH 2/2] can: flexcan: adding platform specific details for LS1021A Pankaj Bansal
2017-11-10 10:06 ` [PATCH 1/2] can: flexcan: Remodel FlexCAN register r/w APIs for big endian FlexCAN controllers Marc Kleine-Budde
2017-11-10 11:06   ` Pankaj Bansal
2017-11-10 11:09     ` Marc Kleine-Budde
2017-11-10 12:35       ` Pankaj Bansal
     [not found]         ` <AM0PR0402MB394051B0FAADBC45AF71439CF1540-mYCQpYF9suc3mfjNbz3WnI3W/0Ik+aLCnBOFsp37pqbUKgpGm//BTAC/G2K4zDHf@public.gmane.org>
2017-11-10 12:49           ` Marc Kleine-Budde
2017-11-10 16:32             ` Pankaj Bansal
     [not found]               ` <AM0PR0402MB3940DE05B2BA456D0FF54498F1540-mYCQpYF9suc3mfjNbz3WnI3W/0Ik+aLCnBOFsp37pqbUKgpGm//BTAC/G2K4zDHf@public.gmane.org>
2017-11-13 15:50                 ` Marc Kleine-Budde
2017-11-10 10:48 ` Marc Kleine-Budde
2017-11-14 11:56 ` [PATCH v2 " Pankaj Bansal
2017-11-14 11:56   ` [PATCH v2 2/2] can: flexcan: adding platform specific details for LS1021A Pankaj Bansal
2017-11-14 12:59     ` Marc Kleine-Budde
2017-11-16  5:34       ` Pankaj Bansal
2017-11-16  7:05         ` Wolfgang Grandegger
2017-11-16  7:23           ` ZHU Yi (ST-FIR/ENG1-Zhu)
2017-11-20 11:11             ` Pankaj Bansal
2017-11-21  2:13               ` ZHU Yi (ST-FIR/ENG1-Zhu)
2017-11-21  2:37                 ` Pankaj Bansal
2017-11-21  3:31                   ` ZHU Yi (ST-FIR/ENG1-Zhu)
2017-11-21 10:01                     ` Pankaj Bansal
2017-11-23  7:23                       ` ZHU Yi (ST-FIR/ENG1-Zhu)
2017-11-21 12:43                 ` Marc Kleine-Budde
2017-11-22  2:56                   ` ZHU Yi (ST-FIR/ENG1-Zhu)
2017-11-22  6:27                     ` Pankaj Bansal
2017-11-22 13:56                       ` Marc Kleine-Budde
2017-11-22 11:59                     ` Marc Kleine-Budde
2017-11-23  1:26                       ` ZHU Yi (ST-FIR/ENG1-Zhu)
     [not found]                       ` <CALw8SCUGuCmq+S_9-o-ZDYJuASveuj71WH97jYsEvNZX2N5ZXA@mail.gmail.com>
2017-11-23 20:17                         ` Mirza Krak
2017-11-23 21:05                           ` Wolfgang Grandegger
2017-11-24 16:02                             ` Mirza Krak
2017-11-24 19:19                               ` Wolfgang Grandegger
2017-11-26 21:11                                 ` Mirza Krak
2017-11-27 14:00                                   ` Marc Kleine-Budde
     [not found]                                     ` <CALw8SCVNqN0SM1e=bxXZFMVL0VN0iy0LgFj9Hv4BeRwAbb9Y6A@mail.gmail.com>
2017-11-28 22:11                                       ` Mirza Krak
2017-12-01 10:12                                         ` Mirza Krak
2017-12-01 10:32                                           ` Marc Kleine-Budde
2017-11-27 16:34                           ` Stefan Agner
2017-11-14 15:24   ` [PATCH v2 1/2] can: flexcan: Remodel FlexCAN register r/w APIs for big endian FlexCAN controllers Marc Kleine-Budde
2017-11-16  5:24     ` Pankaj Bansal
2017-11-16 12:04       ` Marc Kleine-Budde
2017-11-21 12:18     ` Pankaj Bansal
2017-11-21 12:38       ` Marc Kleine-Budde
2017-11-23  9:09   ` [PATCH v3 " Pankaj Bansal
2017-11-23  9:09     ` [PATCH v3 2/2] can: flexcan: adding platform specific details for LS1021A Pankaj Bansal
2017-11-23  9:16       ` Marc Kleine-Budde
2017-11-23 10:01         ` Pankaj Bansal
2017-11-23 10:07           ` Marc Kleine-Budde
2017-11-23 12:01             ` Pankaj Bansal
2017-11-23 12:33               ` Marc Kleine-Budde
2017-11-23  9:18     ` [PATCH v3 1/2] can: flexcan: Remodel FlexCAN register r/w APIs for big endian FlexCAN controllers Marc Kleine-Budde
2017-11-23  9:55       ` Pankaj Bansal

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.