* [PATCH 3/3] arm/dts: Add nodes for flexcan devices present on LS1021A-Rev2 SoC
From: Pankaj Bansal @ 2017-11-10 10:17 UTC (permalink / raw)
To: wg, mkl, linux-can, robh+dt, mark.rutland, devicetree
Cc: V.Sethi, poonam.aggrwal, Pankaj Bansal, Bhupesh Sharma,
Sakar Arora
In-Reply-To: <1510309043-16777-1-git-send-email-pankaj.bansal@nxp.com>
This patch adds the device nodes for flexcan controller(s) present
on LS1021A-Rev2 SoC.
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>
---
arch/arm/boot/dts/ls1021a-qds.dts | 16 +++++++++++++
arch/arm/boot/dts/ls1021a-twr.dts | 16 +++++++++++++
arch/arm/boot/dts/ls1021a.dtsi | 36 +++++++++++++++++++++++++++++
3 files changed, 68 insertions(+)
diff --git a/arch/arm/boot/dts/ls1021a-qds.dts b/arch/arm/boot/dts/ls1021a-qds.dts
index 9408753..4f211e3 100644
--- a/arch/arm/boot/dts/ls1021a-qds.dts
+++ b/arch/arm/boot/dts/ls1021a-qds.dts
@@ -331,3 +331,19 @@
&uart1 {
status = "okay";
};
+
+&can0 {
+ status = "okay";
+};
+
+&can1 {
+ status = "okay";
+};
+
+&can2 {
+ status = "disabled";
+};
+
+&can3 {
+ status = "disabled";
+};
diff --git a/arch/arm/boot/dts/ls1021a-twr.dts b/arch/arm/boot/dts/ls1021a-twr.dts
index a8b148a..7202d9c 100644
--- a/arch/arm/boot/dts/ls1021a-twr.dts
+++ b/arch/arm/boot/dts/ls1021a-twr.dts
@@ -243,3 +243,19 @@
&uart1 {
status = "okay";
};
+
+&can0 {
+ status = "okay";
+};
+
+&can1 {
+ status = "okay";
+};
+
+&can2 {
+ status = "disabled";
+};
+
+&can3 {
+ status = "disabled";
+};
diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi
index 9319e1f..7789031 100644
--- a/arch/arm/boot/dts/ls1021a.dtsi
+++ b/arch/arm/boot/dts/ls1021a.dtsi
@@ -730,5 +730,41 @@
<0000 0 0 3 &gic GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>,
<0000 0 0 4 &gic GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>;
};
+
+ can0: can@2a70000 {
+ compatible = "fsl,ls1021ar2-flexcan";
+ reg = <0x0 0x2a70000 0x0 0x1000>;
+ interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clockgen 4 1>, <&clockgen 4 1>;
+ clock-names = "ipg", "per";
+ big-endian;
+ };
+
+ can1: can@2a80000 {
+ compatible = "fsl,ls1021ar2-flexcan";
+ reg = <0x0 0x2a80000 0x0 0x1000>;
+ interrupts = <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clockgen 4 1>, <&clockgen 4 1>;
+ clock-names = "ipg", "per";
+ big-endian;
+ };
+
+ can2: can@2a90000 {
+ compatible = "fsl,ls1021ar2-flexcan";
+ reg = <0x0 0x2a90000 0x0 0x1000>;
+ interrupts = <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clockgen 4 1>, <&clockgen 4 1>;
+ clock-names = "ipg", "per";
+ big-endian;
+ };
+
+ can3: can@2aa0000 {
+ compatible = "fsl,ls1021ar2-flexcan";
+ reg = <0x0 0x2aa0000 0x0 0x1000>;
+ interrupts = <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clockgen 4 1>, <&clockgen 4 1>;
+ clock-names = "ipg", "per";
+ big-endian;
+ };
};
};
--
2.7.4
^ permalink raw reply related
* [PATCH] can: ifi: Fix transmitter delay calculation
From: Marek Vasut @ 2017-11-10 10:22 UTC (permalink / raw)
To: linux-can; +Cc: Marek Vasut, Markus Marb, Marc Kleine-Budde
The CANFD transmitter delay calculation formula was updated in the
latest software drop from IFI and improves the behavior of the IFI
CANFD core during bitrate switching. Use the new formula to improve
stability of the CANFD operation.
Signed-off-by: Marek Vasut <marex@denx.de>
Cc: Markus Marb <markus@marb.org>
Cc: Marc Kleine-Budde <mkl@pengutronix.de>
---
drivers/net/can/ifi_canfd/ifi_canfd.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/net/can/ifi_canfd/ifi_canfd.c b/drivers/net/can/ifi_canfd/ifi_canfd.c
index 0e22599dfe4a..6c37f5d4fe7e 100644
--- a/drivers/net/can/ifi_canfd/ifi_canfd.c
+++ b/drivers/net/can/ifi_canfd/ifi_canfd.c
@@ -671,9 +671,9 @@ static void ifi_canfd_set_bittiming(struct net_device *ndev)
priv->base + IFI_CANFD_FTIME);
/* Configure transmitter delay */
- tdc = (dbt->brp * (dbt->phase_seg1 + 1)) & IFI_CANFD_TDELAY_MASK;
- writel(IFI_CANFD_TDELAY_EN | IFI_CANFD_TDELAY_ABS | tdc,
- priv->base + IFI_CANFD_TDELAY);
+ tdc = dbt->brp * (dbt->prop_seg + dbt->phase_seg1);
+ tdc &= IFI_CANFD_TDELAY_MASK;
+ writel(IFI_CANFD_TDELAY_EN | tdc, priv->base + IFI_CANFD_TDELAY);
}
static void ifi_canfd_set_filter(struct net_device *ndev, const u32 id,
--
2.11.0
^ permalink raw reply related
* Re: [PATCH 1/3] Documentation : can : flexcan : Add big-endian property to device tree
From: Marc Kleine-Budde @ 2017-11-10 10:36 UTC (permalink / raw)
To: Pankaj Bansal, wg-5Yr1BZd7O62+XT7JhA+gdA,
linux-can-u79uwXL29TY76Z2rM5mHXA, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
mark.rutland-5wv7dgnIgG8, devicetree-u79uwXL29TY76Z2rM5mHXA
Cc: V.Sethi-3arQi8VN3Tc, poonam.aggrwal-3arQi8VN3Tc
In-Reply-To: <1510309043-16777-1-git-send-email-pankaj.bansal-3arQi8VN3Tc@public.gmane.org>
[-- Attachment #1.1: Type: text/plain, Size: 1868 bytes --]
On 11/10/2017 11:17 AM, Pankaj Bansal wrote:
> The FlexCAN controller can be modelled as little or big endian
> depending on SOC design. This device tree property identifies the
> controller endianness and the driver reads/writes controller registers
> based on that.
>
> This is optional property. i.e. if this property is not present in
> device tree node then controller is assumed to be little endian. if
> this property is present then controller is assumed to be big endian.
>
> Signed-off-by: Pankaj Bansal <pankaj.bansal-3arQi8VN3Tc@public.gmane.org>
> Reviewed-by: Poonam Aggrwal <poonam.aggrwal-3arQi8VN3Tc@public.gmane.org>
NACK, this is not backwards compatible.
See mail on linux-can for better solution.
Marc
> ---
> Documentation/devicetree/bindings/net/can/fsl-flexcan.txt | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/net/can/fsl-flexcan.txt b/Documentation/devicetree/bindings/net/can/fsl-flexcan.txt
> index 56d6cc3..b9693c7 100644
> --- a/Documentation/devicetree/bindings/net/can/fsl-flexcan.txt
> +++ b/Documentation/devicetree/bindings/net/can/fsl-flexcan.txt
> @@ -18,6 +18,8 @@ Optional properties:
>
> - xceiver-supply: Regulator that powers the CAN transceiver
>
> +- big-endian: This means the registers of FlexCAN controller are big endian
> +
> Example:
>
> can@1c000 {
> @@ -26,4 +28,5 @@ Example:
> interrupts = <48 0x2>;
> interrupt-parent = <&mpic>;
> clock-frequency = <200000000>; // filled in by bootloader
> + big-endian;
> };
>
--
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
* Re: [PATCH 1/2] can: flexcan: Remodel FlexCAN register r/w APIs for big endian FlexCAN controllers.
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
In-Reply-To: <1510307990-15418-1-git-send-email-pankaj.bansal@nxp.com>
[-- 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, ®s->ctrl);
> + priv->write(reg_ctrl, ®s->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, ®s->ctrl);
> + priv->write(reg_ctrl, ®s->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(®s->mcr);
> + reg = priv->read(®s->mcr);
> reg &= ~FLEXCAN_MCR_MDIS;
> - flexcan_write(reg, ®s->mcr);
> + priv->write(reg, ®s->mcr);
>
> - while (timeout-- && (flexcan_read(®s->mcr) & FLEXCAN_MCR_LPM_ACK))
> + while (timeout-- && (priv->read(®s->mcr) & FLEXCAN_MCR_LPM_ACK))
> udelay(10);
>
> - if (flexcan_read(®s->mcr) & FLEXCAN_MCR_LPM_ACK)
> + if (priv->read(®s->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(®s->mcr);
> + reg = priv->read(®s->mcr);
> reg |= FLEXCAN_MCR_MDIS;
> - flexcan_write(reg, ®s->mcr);
> + priv->write(reg, ®s->mcr);
>
> - while (timeout-- && !(flexcan_read(®s->mcr) & FLEXCAN_MCR_LPM_ACK))
> + while (timeout-- && !(priv->read(®s->mcr) & FLEXCAN_MCR_LPM_ACK))
> udelay(10);
>
> - if (!(flexcan_read(®s->mcr) & FLEXCAN_MCR_LPM_ACK))
> + if (!(priv->read(®s->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(®s->mcr);
> + reg = priv->read(®s->mcr);
> reg |= FLEXCAN_MCR_HALT;
> - flexcan_write(reg, ®s->mcr);
> + priv->write(reg, ®s->mcr);
>
> - while (timeout-- && !(flexcan_read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK))
> + while (timeout-- && !(priv->read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK))
> udelay(100);
>
> - if (!(flexcan_read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK))
> + if (!(priv->read(®s->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(®s->mcr);
> + reg = priv->read(®s->mcr);
> reg &= ~FLEXCAN_MCR_HALT;
> - flexcan_write(reg, ®s->mcr);
> + priv->write(reg, ®s->mcr);
>
> - while (timeout-- && (flexcan_read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK))
> + while (timeout-- && (priv->read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK))
> udelay(10);
>
> - if (flexcan_read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK)
> + if (priv->read(®s->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, ®s->mcr);
> - while (timeout-- && (flexcan_read(®s->mcr) & FLEXCAN_MCR_SOFTRST))
> + priv->write(FLEXCAN_MCR_SOFTRST, ®s->mcr);
> + while (timeout-- && (priv->read(®s->mcr) & FLEXCAN_MCR_SOFTRST))
> udelay(10);
>
> - if (flexcan_read(®s->mcr) & FLEXCAN_MCR_SOFTRST)
> + if (priv->read(®s->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(®s->ecr);
> + u32 reg = priv->read(®s->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(®s->iflag1);
> + reg_iflag1 = priv->read(®s->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), ®s->iflag1);
> + priv->write(BIT(n), ®s->iflag1);
> else
> - flexcan_write(BIT(n - 32), ®s->iflag2);
> + priv->write(BIT(n - 32), ®s->iflag2);
> } else {
> - flexcan_write(FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, ®s->iflag1);
> - flexcan_read(®s->timer);
> + priv->write(FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, ®s->iflag1);
> + priv->read(®s->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(®s->iflag2) & priv->reg_imask2_default;
> - iflag1 = flexcan_read(®s->iflag1) & priv->reg_imask1_default &
> + iflag2 = priv->read(®s->iflag2) & priv->reg_imask2_default;
> + iflag1 = priv->read(®s->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(®s->iflag1);
> + reg_iflag1 = priv->read(®s->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, ®s->iflag1);
> + priv->write(FLEXCAN_IFLAG_RX_FIFO_OVERFLOW,
> + ®s->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), ®s->iflag1);
> + priv->write(FLEXCAN_IFLAG_MB(priv->tx_mb_idx), ®s->iflag1);
> netif_wake_queue(dev);
> }
>
> - reg_esr = flexcan_read(®s->esr);
> + reg_esr = priv->read(®s->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, ®s->esr);
> + priv->write(reg_esr & FLEXCAN_ESR_ALL_INT, ®s->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(®s->ctrl);
> + reg = priv->read(®s->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, ®s->ctrl);
> + priv->write(reg, ®s->ctrl);
>
> /* print chip status */
> netdev_dbg(dev, "%s: mcr=0x%08x ctrl=0x%08x\n", __func__,
> - flexcan_read(®s->mcr), flexcan_read(®s->ctrl));
> + priv->read(®s->mcr), priv->read(®s->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(®s->mcr);
> + reg_mcr = priv->read(®s->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, ®s->mcr);
> + priv->write(reg_mcr, ®s->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(®s->ctrl);
> + reg_ctrl = priv->read(®s->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, ®s->ctrl);
> + priv->write(reg_ctrl, ®s->ctrl);
>
> if ((priv->devtype_data->quirks & FLEXCAN_QUIRK_ENABLE_EACEN_RRS)) {
> - reg_ctrl2 = flexcan_read(®s->ctrl2);
> + reg_ctrl2 = priv->read(®s->ctrl2);
> reg_ctrl2 |= FLEXCAN_CTRL2_EACEN | FLEXCAN_CTRL2_RRS;
> - flexcan_write(reg_ctrl2, ®s->ctrl2);
> + priv->write(reg_ctrl2, ®s->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,
> ®s->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,
> ®s->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, ®s->rxgmask);
> - flexcan_write(0x0, ®s->rx14mask);
> - flexcan_write(0x0, ®s->rx15mask);
> + priv->write(0x0, ®s->rxgmask);
> + priv->write(0x0, ®s->rx14mask);
> + priv->write(0x0, ®s->rx15mask);
>
> if (priv->devtype_data->quirks & FLEXCAN_QUIRK_DISABLE_RXFG)
> - flexcan_write(0x0, ®s->rxfgmask);
> + priv->write(0x0, ®s->rxfgmask);
>
> /* clear acceptance filters */
> for (i = 0; i < ARRAY_SIZE(regs->mb); i++)
> - flexcan_write(0, ®s->rximr[i]);
> + priv->write(0, ®s->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(®s->ctrl2);
> + reg_ctrl2 = priv->read(®s->ctrl2);
> reg_ctrl2 |= FLEXCAN_CTRL2_ECRWRE;
> - flexcan_write(reg_ctrl2, ®s->ctrl2);
> + priv->write(reg_ctrl2, ®s->ctrl2);
>
> - reg_mecr = flexcan_read(®s->mecr);
> + reg_mecr = priv->read(®s->mecr);
> reg_mecr &= ~FLEXCAN_MECR_ECRWRDIS;
> - flexcan_write(reg_mecr, ®s->mecr);
> + priv->write(reg_mecr, ®s->mecr);
> reg_mecr &= ~(FLEXCAN_MECR_NCEFAFRZ | FLEXCAN_MECR_HANCEI_MSK |
> FLEXCAN_MECR_FANCEI_MSK);
> - flexcan_write(reg_mecr, ®s->mecr);
> + priv->write(reg_mecr, ®s->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, ®s->ctrl);
> - flexcan_write(priv->reg_imask1_default, ®s->imask1);
> - flexcan_write(priv->reg_imask2_default, ®s->imask2);
> + priv->write(priv->reg_ctrl_default, ®s->ctrl);
> + priv->write(priv->reg_imask1_default, ®s->imask1);
> + priv->write(priv->reg_imask2_default, ®s->imask2);
> enable_irq(dev->irq);
>
> /* print chip status */
> netdev_dbg(dev, "%s: reading mcr=0x%08x ctrl=0x%08x\n", __func__,
> - flexcan_read(®s->mcr), flexcan_read(®s->ctrl));
> + priv->read(®s->mcr), priv->read(®s->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, ®s->imask2);
> - flexcan_write(0, ®s->imask1);
> - flexcan_write(priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_ALL,
> + priv->write(0, ®s->imask2);
> + priv->write(0, ®s->imask1);
> + priv->write(priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_ALL,
> ®s->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(®s->ctrl);
> + reg = priv->read(®s->ctrl);
> reg |= FLEXCAN_CTRL_CLK_SRC;
> - flexcan_write(reg, ®s->ctrl);
> + priv->write(reg, ®s->ctrl);
>
> err = flexcan_chip_enable(priv);
> if (err)
> goto out_chip_disable;
>
> /* set freeze, halt and activate FIFO, restrict register access */
> - reg = flexcan_read(®s->mcr);
> + reg = priv->read(®s->mcr);
> reg |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT |
> FLEXCAN_MCR_FEN | FLEXCAN_MCR_SUPV;
> - flexcan_write(reg, ®s->mcr);
> + priv->write(reg, ®s->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(®s->mcr);
> + reg = priv->read(®s->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
* Re: [PATCH 1/2] can: flexcan: Remodel FlexCAN register r/w APIs for big endian FlexCAN controllers.
From: Marc Kleine-Budde @ 2017-11-10 10:48 UTC (permalink / raw)
To: Pankaj Bansal, wg, linux-can; +Cc: V.Sethi, poonam.aggrwal
In-Reply-To: <1510307990-15418-1-git-send-email-pankaj.bansal@nxp.com>
[-- 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
* RE: [PATCH 1/2] can: flexcan: Remodel FlexCAN register r/w APIs for big endian FlexCAN controllers.
From: Pankaj Bansal @ 2017-11-10 11:06 UTC (permalink / raw)
To: Marc Kleine-Budde, wg@grandegger.com, linux-can@vger.kernel.org
Cc: Varun Sethi, Poonam Aggrwal, Bhupesh Sharma, Sakar Arora
In-Reply-To: <a08c34d0-5870-b4b3-f68d-3db33ba3e950@pengutronix.de>
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, ®s->ctrl);
> + priv->write(reg_ctrl, ®s->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, ®s->ctrl);
> + priv->write(reg_ctrl, ®s->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(®s->mcr);
> + reg = priv->read(®s->mcr);
> reg &= ~FLEXCAN_MCR_MDIS;
> - flexcan_write(reg, ®s->mcr);
> + priv->write(reg, ®s->mcr);
>
> - while (timeout-- && (flexcan_read(®s->mcr) & FLEXCAN_MCR_LPM_ACK))
> + while (timeout-- && (priv->read(®s->mcr) & FLEXCAN_MCR_LPM_ACK))
> udelay(10);
>
> - if (flexcan_read(®s->mcr) & FLEXCAN_MCR_LPM_ACK)
> + if (priv->read(®s->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(®s->mcr);
> + reg = priv->read(®s->mcr);
> reg |= FLEXCAN_MCR_MDIS;
> - flexcan_write(reg, ®s->mcr);
> + priv->write(reg, ®s->mcr);
>
> - while (timeout-- && !(flexcan_read(®s->mcr) & FLEXCAN_MCR_LPM_ACK))
> + while (timeout-- && !(priv->read(®s->mcr) & FLEXCAN_MCR_LPM_ACK))
> udelay(10);
>
> - if (!(flexcan_read(®s->mcr) & FLEXCAN_MCR_LPM_ACK))
> + if (!(priv->read(®s->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(®s->mcr);
> + reg = priv->read(®s->mcr);
> reg |= FLEXCAN_MCR_HALT;
> - flexcan_write(reg, ®s->mcr);
> + priv->write(reg, ®s->mcr);
>
> - while (timeout-- && !(flexcan_read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK))
> + while (timeout-- && !(priv->read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK))
> udelay(100);
>
> - if (!(flexcan_read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK))
> + if (!(priv->read(®s->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(®s->mcr);
> + reg = priv->read(®s->mcr);
> reg &= ~FLEXCAN_MCR_HALT;
> - flexcan_write(reg, ®s->mcr);
> + priv->write(reg, ®s->mcr);
>
> - while (timeout-- && (flexcan_read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK))
> + while (timeout-- && (priv->read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK))
> udelay(10);
>
> - if (flexcan_read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK)
> + if (priv->read(®s->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, ®s->mcr);
> - while (timeout-- && (flexcan_read(®s->mcr) & FLEXCAN_MCR_SOFTRST))
> + priv->write(FLEXCAN_MCR_SOFTRST, ®s->mcr);
> + while (timeout-- && (priv->read(®s->mcr) & FLEXCAN_MCR_SOFTRST))
> udelay(10);
>
> - if (flexcan_read(®s->mcr) & FLEXCAN_MCR_SOFTRST)
> + if (priv->read(®s->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(®s->ecr);
> + u32 reg = priv->read(®s->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(®s->iflag1);
> + reg_iflag1 = priv->read(®s->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), ®s->iflag1);
> + priv->write(BIT(n), ®s->iflag1);
> else
> - flexcan_write(BIT(n - 32), ®s->iflag2);
> + priv->write(BIT(n - 32), ®s->iflag2);
> } else {
> - flexcan_write(FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, ®s->iflag1);
> - flexcan_read(®s->timer);
> + priv->write(FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, ®s->iflag1);
> + priv->read(®s->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(®s->iflag2) & priv->reg_imask2_default;
> - iflag1 = flexcan_read(®s->iflag1) & priv->reg_imask1_default &
> + iflag2 = priv->read(®s->iflag2) & priv->reg_imask2_default;
> + iflag1 = priv->read(®s->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(®s->iflag1);
> + reg_iflag1 = priv->read(®s->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, ®s->iflag1);
> + priv->write(FLEXCAN_IFLAG_RX_FIFO_OVERFLOW,
> + ®s->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), ®s->iflag1);
> + priv->write(FLEXCAN_IFLAG_MB(priv->tx_mb_idx), ®s->iflag1);
> netif_wake_queue(dev);
> }
>
> - reg_esr = flexcan_read(®s->esr);
> + reg_esr = priv->read(®s->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, ®s->esr);
> + priv->write(reg_esr & FLEXCAN_ESR_ALL_INT, ®s->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(®s->ctrl);
> + reg = priv->read(®s->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, ®s->ctrl);
> + priv->write(reg, ®s->ctrl);
>
> /* print chip status */
> netdev_dbg(dev, "%s: mcr=0x%08x ctrl=0x%08x\n", __func__,
> - flexcan_read(®s->mcr), flexcan_read(®s->ctrl));
> + priv->read(®s->mcr), priv->read(®s->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(®s->mcr);
> + reg_mcr = priv->read(®s->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, ®s->mcr);
> + priv->write(reg_mcr, ®s->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(®s->ctrl);
> + reg_ctrl = priv->read(®s->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, ®s->ctrl);
> + priv->write(reg_ctrl, ®s->ctrl);
>
> if ((priv->devtype_data->quirks & FLEXCAN_QUIRK_ENABLE_EACEN_RRS)) {
> - reg_ctrl2 = flexcan_read(®s->ctrl2);
> + reg_ctrl2 = priv->read(®s->ctrl2);
> reg_ctrl2 |= FLEXCAN_CTRL2_EACEN | FLEXCAN_CTRL2_RRS;
> - flexcan_write(reg_ctrl2, ®s->ctrl2);
> + priv->write(reg_ctrl2, ®s->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,
> ®s->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,
> ®s->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, ®s->rxgmask);
> - flexcan_write(0x0, ®s->rx14mask);
> - flexcan_write(0x0, ®s->rx15mask);
> + priv->write(0x0, ®s->rxgmask);
> + priv->write(0x0, ®s->rx14mask);
> + priv->write(0x0, ®s->rx15mask);
>
> if (priv->devtype_data->quirks & FLEXCAN_QUIRK_DISABLE_RXFG)
> - flexcan_write(0x0, ®s->rxfgmask);
> + priv->write(0x0, ®s->rxfgmask);
>
> /* clear acceptance filters */
> for (i = 0; i < ARRAY_SIZE(regs->mb); i++)
> - flexcan_write(0, ®s->rximr[i]);
> + priv->write(0, ®s->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(®s->ctrl2);
> + reg_ctrl2 = priv->read(®s->ctrl2);
> reg_ctrl2 |= FLEXCAN_CTRL2_ECRWRE;
> - flexcan_write(reg_ctrl2, ®s->ctrl2);
> + priv->write(reg_ctrl2, ®s->ctrl2);
>
> - reg_mecr = flexcan_read(®s->mecr);
> + reg_mecr = priv->read(®s->mecr);
> reg_mecr &= ~FLEXCAN_MECR_ECRWRDIS;
> - flexcan_write(reg_mecr, ®s->mecr);
> + priv->write(reg_mecr, ®s->mecr);
> reg_mecr &= ~(FLEXCAN_MECR_NCEFAFRZ | FLEXCAN_MECR_HANCEI_MSK |
> FLEXCAN_MECR_FANCEI_MSK);
> - flexcan_write(reg_mecr, ®s->mecr);
> + priv->write(reg_mecr, ®s->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, ®s->ctrl);
> - flexcan_write(priv->reg_imask1_default, ®s->imask1);
> - flexcan_write(priv->reg_imask2_default, ®s->imask2);
> + priv->write(priv->reg_ctrl_default, ®s->ctrl);
> + priv->write(priv->reg_imask1_default, ®s->imask1);
> + priv->write(priv->reg_imask2_default, ®s->imask2);
> enable_irq(dev->irq);
>
> /* print chip status */
> netdev_dbg(dev, "%s: reading mcr=0x%08x ctrl=0x%08x\n", __func__,
> - flexcan_read(®s->mcr), flexcan_read(®s->ctrl));
> + priv->read(®s->mcr), priv->read(®s->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, ®s->imask2);
> - flexcan_write(0, ®s->imask1);
> - flexcan_write(priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_ALL,
> + priv->write(0, ®s->imask2);
> + priv->write(0, ®s->imask1);
> + priv->write(priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_ALL,
> ®s->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(®s->ctrl);
> + reg = priv->read(®s->ctrl);
> reg |= FLEXCAN_CTRL_CLK_SRC;
> - flexcan_write(reg, ®s->ctrl);
> + priv->write(reg, ®s->ctrl);
>
> err = flexcan_chip_enable(priv);
> if (err)
> goto out_chip_disable;
>
> /* set freeze, halt and activate FIFO, restrict register access */
> - reg = flexcan_read(®s->mcr);
> + reg = priv->read(®s->mcr);
> reg |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT |
> FLEXCAN_MCR_FEN | FLEXCAN_MCR_SUPV;
> - flexcan_write(reg, ®s->mcr);
> + priv->write(reg, ®s->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(®s->mcr);
> + reg = priv->read(®s->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
* Re: [PATCH 1/2] can: flexcan: Remodel FlexCAN register r/w APIs for big endian FlexCAN controllers.
From: Marc Kleine-Budde @ 2017-11-10 11:09 UTC (permalink / raw)
To: Pankaj Bansal, wg@grandegger.com, linux-can@vger.kernel.org
Cc: Varun Sethi, Poonam Aggrwal, Bhupesh Sharma, Sakar Arora
In-Reply-To: <AM0PR0402MB3940A39D32C4725DE1B8C426F1540@AM0PR0402MB3940.eurprd04.prod.outlook.com>
[-- 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
* RE: [PATCH 1/2] can: flexcan: Remodel FlexCAN register r/w APIs for big endian FlexCAN controllers.
From: Pankaj Bansal @ 2017-11-10 12:35 UTC (permalink / raw)
To: Marc Kleine-Budde, wg@grandegger.com, linux-can@vger.kernel.org
Cc: Varun Sethi, Poonam Aggrwal, Bhupesh Sharma, Sakar Arora
In-Reply-To: <e87441cc-3848-1125-f4f0-02f1a630c36b@pengutronix.de>
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
* Re: [PATCH 1/2] can: flexcan: Remodel FlexCAN register r/w APIs for big endian FlexCAN controllers.
From: Marc Kleine-Budde @ 2017-11-10 12:49 UTC (permalink / raw)
To: Pankaj Bansal, wg-5Yr1BZd7O62+XT7JhA+gdA@public.gmane.org,
linux-can-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: Varun Sethi, Poonam Aggrwal,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <AM0PR0402MB394051B0FAADBC45AF71439CF1540-mYCQpYF9suc3mfjNbz3WnI3W/0Ik+aLCnBOFsp37pqbUKgpGm//BTAC/G2K4zDHf@public.gmane.org>
[-- 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
* pull-request: can 2017-11-10
From: Marc Kleine-Budde @ 2017-11-10 13:07 UTC (permalink / raw)
To: netdev; +Cc: davem, linux-can, kernel
Hello David,
this is a pull request for net/master.
The first patch by Richard Schütz for the c_can driver removes the false
indication to support triple sampling for d_can. Gerhard Bertelsmann's
patch for the sun4i driver improves the RX overrun handling. The patch
by Stephane Grosjean for the peak_canfd driver adds the PCI ids for
various new PCIe/M2 interfaces. Marek Vasut's patch for the ifi driver
fix transmitter delay calculation.
regards,
Marc
---
The following changes since commit 1cb483a5cc84b497afb51a6c5dfb5a38a0b67086:
rds: ib: Fix NULL pointer dereference in debug code (2017-11-10 14:54:47 +0900)
are available in the Git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can.git tags/linux-can-fixes-for-4.14-20171110
for you to fetch changes up to 4f7116757b4bd99e4ef2636c7d957a6d63035d11:
can: ifi: Fix transmitter delay calculation (2017-11-10 11:35:09 +0100)
----------------------------------------------------------------
linux-can-fixes-for-4.14-20171110
----------------------------------------------------------------
Gerhard Bertelsmann (1):
can: sun4i: handle overrun in RX FIFO
Marek Vasut (1):
can: ifi: Fix transmitter delay calculation
Richard Schütz (1):
can: c_can: don't indicate triple sampling support for D_CAN
Stephane Grosjean (1):
can: peak: Add support for new PCIe/M2 CAN FD interfaces
drivers/net/can/c_can/c_can_pci.c | 1 -
drivers/net/can/c_can/c_can_platform.c | 1 -
drivers/net/can/ifi_canfd/ifi_canfd.c | 6 +++---
drivers/net/can/peak_canfd/peak_pciefd_main.c | 14 ++++++++++++--
drivers/net/can/sun4i_can.c | 12 ++++++++++--
5 files changed, 25 insertions(+), 9 deletions(-)
^ permalink raw reply
* [PATCH 1/4] can: c_can: don't indicate triple sampling support for D_CAN
From: Marc Kleine-Budde @ 2017-11-10 13:07 UTC (permalink / raw)
To: netdev
Cc: davem, linux-can, kernel, Richard Schütz, linux-stable,
Marc Kleine-Budde
In-Reply-To: <20171110130730.6662-1-mkl@pengutronix.de>
From: Richard Schütz <rschuetz@uni-koblenz.de>
The D_CAN controller doesn't provide a triple sampling mode, so don't set
the CAN_CTRLMODE_3_SAMPLES flag in ctrlmode_supported. Currently enabling
triple sampling is a no-op.
Signed-off-by: Richard Schütz <rschuetz@uni-koblenz.de>
Cc: linux-stable <stable@vger.kernel.org> # >= v3.6
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
drivers/net/can/c_can/c_can_pci.c | 1 -
drivers/net/can/c_can/c_can_platform.c | 1 -
2 files changed, 2 deletions(-)
diff --git a/drivers/net/can/c_can/c_can_pci.c b/drivers/net/can/c_can/c_can_pci.c
index cf7c18947189..d065c0e2d18e 100644
--- a/drivers/net/can/c_can/c_can_pci.c
+++ b/drivers/net/can/c_can/c_can_pci.c
@@ -178,7 +178,6 @@ static int c_can_pci_probe(struct pci_dev *pdev,
break;
case BOSCH_D_CAN:
priv->regs = reg_map_d_can;
- priv->can.ctrlmode_supported |= CAN_CTRLMODE_3_SAMPLES;
break;
default:
ret = -EINVAL;
diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c
index 46a746ee80bb..b5145a7f874c 100644
--- a/drivers/net/can/c_can/c_can_platform.c
+++ b/drivers/net/can/c_can/c_can_platform.c
@@ -320,7 +320,6 @@ static int c_can_plat_probe(struct platform_device *pdev)
break;
case BOSCH_D_CAN:
priv->regs = reg_map_d_can;
- priv->can.ctrlmode_supported |= CAN_CTRLMODE_3_SAMPLES;
priv->read_reg = c_can_plat_read_reg_aligned_to_16bit;
priv->write_reg = c_can_plat_write_reg_aligned_to_16bit;
priv->read_reg32 = d_can_plat_read_reg32;
--
2.15.0
^ permalink raw reply related
* [PATCH 2/4] can: sun4i: handle overrun in RX FIFO
From: Marc Kleine-Budde @ 2017-11-10 13:07 UTC (permalink / raw)
To: netdev
Cc: davem, linux-can, kernel, Gerhard Bertelsmann, linux-stable,
Marc Kleine-Budde
In-Reply-To: <20171110130730.6662-1-mkl@pengutronix.de>
From: Gerhard Bertelsmann <info@gerhard-bertelsmann.de>
SUN4Is CAN IP has a 64 byte deep FIFO buffer. If the buffer is not
drained fast enough (overrun) it's getting mangled. Already received
frames are dropped - the data can't be restored.
Signed-off-by: Gerhard Bertelsmann <info@gerhard-bertelsmann.de>
Cc: linux-stable <stable@vger.kernel.org>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
drivers/net/can/sun4i_can.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/drivers/net/can/sun4i_can.c b/drivers/net/can/sun4i_can.c
index b0c80859f746..1ac2090a1721 100644
--- a/drivers/net/can/sun4i_can.c
+++ b/drivers/net/can/sun4i_can.c
@@ -539,6 +539,13 @@ static int sun4i_can_err(struct net_device *dev, u8 isrc, u8 status)
}
stats->rx_over_errors++;
stats->rx_errors++;
+
+ /* reset the CAN IP by entering reset mode
+ * ignoring timeout error
+ */
+ set_reset_mode(dev);
+ set_normal_mode(dev);
+
/* clear bit */
sun4i_can_write_cmdreg(priv, SUN4I_CMD_CLEAR_OR_FLAG);
}
@@ -653,8 +660,9 @@ static irqreturn_t sun4i_can_interrupt(int irq, void *dev_id)
netif_wake_queue(dev);
can_led_event(dev, CAN_LED_EVENT_TX);
}
- if (isrc & SUN4I_INT_RBUF_VLD) {
- /* receive interrupt */
+ if ((isrc & SUN4I_INT_RBUF_VLD) &&
+ !(isrc & SUN4I_INT_DATA_OR)) {
+ /* receive interrupt - don't read if overrun occurred */
while (status & SUN4I_STA_RBUF_RDY) {
/* RX buffer is not empty */
sun4i_can_rx(dev);
--
2.15.0
^ permalink raw reply related
* [PATCH 3/4] can: peak: Add support for new PCIe/M2 CAN FD interfaces
From: Marc Kleine-Budde @ 2017-11-10 13:07 UTC (permalink / raw)
To: netdev
Cc: davem, linux-can, kernel, Stephane Grosjean, linux-stable,
Marc Kleine-Budde
In-Reply-To: <20171110130730.6662-1-mkl@pengutronix.de>
From: Stephane Grosjean <s.grosjean@peak-system.com>
This adds support for the following PEAK-System CAN FD interfaces:
PCAN-cPCIe FD CAN FD Interface for cPCI Serial (2 or 4 channels)
PCAN-PCIe/104-Express CAN FD Interface for PCIe/104-Express (1, 2 or 4 ch.)
PCAN-miniPCIe FD CAN FD Interface for PCIe Mini (1, 2 or 4 channels)
PCAN-PCIe FD OEM CAN FD Interface for PCIe OEM version (1, 2 or 4 ch.)
PCAN-M.2 CAN FD Interface for M.2 (1 or 2 channels)
Like the PCAN-PCIe FD interface, all of these boards run the same IP Core
that is able to handle CAN FD (see also http://www.peak-system.com).
Signed-off-by: Stephane Grosjean <s.grosjean@peak-system.com>
Cc: linux-stable <stable@vger.kernel.org>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
drivers/net/can/peak_canfd/peak_pciefd_main.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/drivers/net/can/peak_canfd/peak_pciefd_main.c b/drivers/net/can/peak_canfd/peak_pciefd_main.c
index 51c2d182a33a..b4efd711f824 100644
--- a/drivers/net/can/peak_canfd/peak_pciefd_main.c
+++ b/drivers/net/can/peak_canfd/peak_pciefd_main.c
@@ -29,14 +29,19 @@
#include "peak_canfd_user.h"
MODULE_AUTHOR("Stephane Grosjean <s.grosjean@peak-system.com>");
-MODULE_DESCRIPTION("Socket-CAN driver for PEAK PCAN PCIe FD family cards");
-MODULE_SUPPORTED_DEVICE("PEAK PCAN PCIe FD CAN cards");
+MODULE_DESCRIPTION("Socket-CAN driver for PEAK PCAN PCIe/M.2 FD family cards");
+MODULE_SUPPORTED_DEVICE("PEAK PCAN PCIe/M.2 FD CAN cards");
MODULE_LICENSE("GPL v2");
#define PCIEFD_DRV_NAME "peak_pciefd"
#define PEAK_PCI_VENDOR_ID 0x001c /* The PCI device and vendor IDs */
#define PEAK_PCIEFD_ID 0x0013 /* for PCIe slot cards */
+#define PCAN_CPCIEFD_ID 0x0014 /* for Compact-PCI Serial slot cards */
+#define PCAN_PCIE104FD_ID 0x0017 /* for PCIe-104 Express slot cards */
+#define PCAN_MINIPCIEFD_ID 0x0018 /* for mini-PCIe slot cards */
+#define PCAN_PCIEFD_OEM_ID 0x0019 /* for PCIe slot OEM cards */
+#define PCAN_M2_ID 0x001a /* for M2 slot cards */
/* PEAK PCIe board access description */
#define PCIEFD_BAR0_SIZE (64 * 1024)
@@ -203,6 +208,11 @@ struct pciefd_board {
/* supported device ids. */
static const struct pci_device_id peak_pciefd_tbl[] = {
{PEAK_PCI_VENDOR_ID, PEAK_PCIEFD_ID, PCI_ANY_ID, PCI_ANY_ID,},
+ {PEAK_PCI_VENDOR_ID, PCAN_CPCIEFD_ID, PCI_ANY_ID, PCI_ANY_ID,},
+ {PEAK_PCI_VENDOR_ID, PCAN_PCIE104FD_ID, PCI_ANY_ID, PCI_ANY_ID,},
+ {PEAK_PCI_VENDOR_ID, PCAN_MINIPCIEFD_ID, PCI_ANY_ID, PCI_ANY_ID,},
+ {PEAK_PCI_VENDOR_ID, PCAN_PCIEFD_OEM_ID, PCI_ANY_ID, PCI_ANY_ID,},
+ {PEAK_PCI_VENDOR_ID, PCAN_M2_ID, PCI_ANY_ID, PCI_ANY_ID,},
{0,}
};
--
2.15.0
^ permalink raw reply related
* [PATCH 4/4] can: ifi: Fix transmitter delay calculation
From: Marc Kleine-Budde @ 2017-11-10 13:07 UTC (permalink / raw)
To: netdev
Cc: davem, linux-can, kernel, Marek Vasut, Markus Marb, linux-stable,
Marc Kleine-Budde
In-Reply-To: <20171110130730.6662-1-mkl@pengutronix.de>
From: Marek Vasut <marex@denx.de>
The CANFD transmitter delay calculation formula was updated in the
latest software drop from IFI and improves the behavior of the IFI
CANFD core during bitrate switching. Use the new formula to improve
stability of the CANFD operation.
Signed-off-by: Marek Vasut <marex@denx.de>
Cc: Markus Marb <markus@marb.org>
Cc: linux-stable <stable@vger.kernel.org>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
drivers/net/can/ifi_canfd/ifi_canfd.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/net/can/ifi_canfd/ifi_canfd.c b/drivers/net/can/ifi_canfd/ifi_canfd.c
index 4d1fe8d95042..2772d05ff11c 100644
--- a/drivers/net/can/ifi_canfd/ifi_canfd.c
+++ b/drivers/net/can/ifi_canfd/ifi_canfd.c
@@ -670,9 +670,9 @@ static void ifi_canfd_set_bittiming(struct net_device *ndev)
priv->base + IFI_CANFD_FTIME);
/* Configure transmitter delay */
- tdc = (dbt->brp * (dbt->phase_seg1 + 1)) & IFI_CANFD_TDELAY_MASK;
- writel(IFI_CANFD_TDELAY_EN | IFI_CANFD_TDELAY_ABS | tdc,
- priv->base + IFI_CANFD_TDELAY);
+ tdc = dbt->brp * (dbt->prop_seg + dbt->phase_seg1);
+ tdc &= IFI_CANFD_TDELAY_MASK;
+ writel(IFI_CANFD_TDELAY_EN | tdc, priv->base + IFI_CANFD_TDELAY);
}
static void ifi_canfd_set_filter(struct net_device *ndev, const u32 id,
--
2.15.0
^ permalink raw reply related
* Re: [PATCH] can: ifi: Fix transmitter delay calculation
From: Marc Kleine-Budde @ 2017-11-10 13:07 UTC (permalink / raw)
To: Marek Vasut, linux-can; +Cc: Markus Marb
In-Reply-To: <20171110102239.6864-1-marex@denx.de>
[-- Attachment #1.1: Type: text/plain, Size: 733 bytes --]
On 11/10/2017 11:22 AM, Marek Vasut wrote:
> The CANFD transmitter delay calculation formula was updated in the
> latest software drop from IFI and improves the behavior of the IFI
> CANFD core during bitrate switching. Use the new formula to improve
> stability of the CANFD operation.
>
> Signed-off-by: Marek Vasut <marex@denx.de>
> Cc: Markus Marb <markus@marb.org>
> Cc: Marc Kleine-Budde <mkl@pengutronix.de>
added to can.
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
* Re: [PATCH] can: peak: Add support for new PCIe/M2 CAN FD interfaces
From: Marc Kleine-Budde @ 2017-11-10 13:08 UTC (permalink / raw)
To: Stephane Grosjean, Oliver Hartkopp; +Cc: linux-can Mailing List
In-Reply-To: <20171109134214.29503-1-s.grosjean@peak-system.com>
[-- Attachment #1.1: Type: text/plain, Size: 1033 bytes --]
On 11/09/2017 02:42 PM, Stephane Grosjean wrote:
> This adds support for the following PEAK-System CAN FD interfaces:
>
> PCAN-cPCIe FD CAN FD Interface for cPCI Serial (2 or 4 channels)
> PCAN-PCIe/104-Express CAN FD Interface for PCIe/104-Express (1, 2 or 4 ch.)
> PCAN-miniPCIe FD CAN FD Interface for PCIe Mini (1, 2 or 4 channels)
> PCAN-PCIe FD OEM CAN FD Interface for PCIe OEM version (1, 2 or 4 ch.)
> PCAN-M.2 CAN FD Interface for M.2 (1 or 2 channels)
>
> Like the PCAN-PCIe FD interface, all of these boards run the same IP Core
> that is able to handle CAN FD (see also http://www.peak-system.com).
>
> Signed-off-by: Stephane Grosjean <s.grosjean@peak-system.com>
Added to can.
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
* RE: [PATCH 1/2] can: flexcan: Remodel FlexCAN register r/w APIs for big endian FlexCAN controllers.
From: Pankaj Bansal @ 2017-11-10 16:32 UTC (permalink / raw)
To: Marc Kleine-Budde, wg@grandegger.com, linux-can@vger.kernel.org
Cc: Varun Sethi, Poonam Aggrwal, devicetree@vger.kernel.org
In-Reply-To: <b27d6e14-c6d7-5c4b-0588-093684cbe57b@pengutronix.de>
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
* Re: [PATCH 1/8] dt-bindings: can: rcar_can: document r8a774[35] can support
From: Rob Herring @ 2017-11-10 21:23 UTC (permalink / raw)
To: Fabrizio Castro
Cc: Wolfgang Grandegger, Marc Kleine-Budde, Mark Rutland,
Simon Horman, Geert Uytterhoeven, linux-can, netdev, devicetree,
linux-renesas-soc, Chris Paterson, Biju Das
In-Reply-To: <1510067449-17017-2-git-send-email-fabrizio.castro@bp.renesas.com>
On Tue, Nov 07, 2017 at 03:10:42PM +0000, Fabrizio Castro wrote:
> Document "renesas,can-r8a7743" and "renesas,can-r8a7745" compatible
> strings. Since the fallback compatible string ("renesas,rcar-gen2-can")
> activates the right code in the driver, no driver change is needed.
>
> Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com>
> Reviewed-by: Biju Das <biju.das@bp.renesas.com>
> ---
> Documentation/devicetree/bindings/net/can/rcar_can.txt | 7 +++++--
> 1 file changed, 5 insertions(+), 2 deletions(-)
Acked-by: Rob Herring <robh@kernel.org>
^ permalink raw reply
* Re: pull-request: can 2017-11-10
From: David Miller @ 2017-11-11 12:52 UTC (permalink / raw)
To: mkl; +Cc: netdev, linux-can, kernel
In-Reply-To: <20171110130730.6662-1-mkl@pengutronix.de>
From: Marc Kleine-Budde <mkl@pengutronix.de>
Date: Fri, 10 Nov 2017 14:07:26 +0100
> this is a pull request for net/master.
>
> The first patch by Richard Schütz for the c_can driver removes the false
> indication to support triple sampling for d_can. Gerhard Bertelsmann's
> patch for the sun4i driver improves the RX overrun handling. The patch
> by Stephane Grosjean for the peak_canfd driver adds the PCI ids for
> various new PCIe/M2 interfaces. Marek Vasut's patch for the ifi driver
> fix transmitter delay calculation.
Pulled, thanks Marc.
^ permalink raw reply
* Re:
From: Amos Kalonzo @ 2017-11-13 14:55 UTC (permalink / raw)
Attn:
I am wondering why You haven't respond to my email for some days now.
reference to my client's contract balance payment of (11.7M,USD)
Kindly get back to me for more details.
Best Regards
Amos Kalonzo
^ permalink raw reply
* Re: [PATCH 1/2] can: flexcan: Remodel FlexCAN register r/w APIs for big endian FlexCAN controllers.
From: Marc Kleine-Budde @ 2017-11-13 15:50 UTC (permalink / raw)
To: Pankaj Bansal, wg-5Yr1BZd7O62+XT7JhA+gdA@public.gmane.org,
linux-can-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: Varun Sethi, Poonam Aggrwal,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <AM0PR0402MB3940DE05B2BA456D0FF54498F1540-mYCQpYF9suc3mfjNbz3WnI3W/0Ik+aLCnBOFsp37pqbUKgpGm//BTAC/G2K4zDHf@public.gmane.org>
[-- 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
* [PATCH v2 1/2] can: flexcan: Remodel FlexCAN register r/w APIs for big endian FlexCAN controllers.
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
In-Reply-To: <1510307990-15418-1-git-send-email-pankaj.bansal@nxp.com>
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, ®s->ctrl);
+ priv->write(reg_ctrl, ®s->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, ®s->ctrl);
+ priv->write(reg_ctrl, ®s->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(®s->mcr);
+ reg = priv->read(®s->mcr);
reg &= ~FLEXCAN_MCR_MDIS;
- flexcan_write(reg, ®s->mcr);
+ priv->write(reg, ®s->mcr);
- while (timeout-- && (flexcan_read(®s->mcr) & FLEXCAN_MCR_LPM_ACK))
+ while (timeout-- && (priv->read(®s->mcr) & FLEXCAN_MCR_LPM_ACK))
udelay(10);
- if (flexcan_read(®s->mcr) & FLEXCAN_MCR_LPM_ACK)
+ if (priv->read(®s->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(®s->mcr);
+ reg = priv->read(®s->mcr);
reg |= FLEXCAN_MCR_MDIS;
- flexcan_write(reg, ®s->mcr);
+ priv->write(reg, ®s->mcr);
- while (timeout-- && !(flexcan_read(®s->mcr) & FLEXCAN_MCR_LPM_ACK))
+ while (timeout-- && !(priv->read(®s->mcr) & FLEXCAN_MCR_LPM_ACK))
udelay(10);
- if (!(flexcan_read(®s->mcr) & FLEXCAN_MCR_LPM_ACK))
+ if (!(priv->read(®s->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(®s->mcr);
+ reg = priv->read(®s->mcr);
reg |= FLEXCAN_MCR_HALT;
- flexcan_write(reg, ®s->mcr);
+ priv->write(reg, ®s->mcr);
- while (timeout-- && !(flexcan_read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK))
+ while (timeout-- && !(priv->read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK))
udelay(100);
- if (!(flexcan_read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK))
+ if (!(priv->read(®s->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(®s->mcr);
+ reg = priv->read(®s->mcr);
reg &= ~FLEXCAN_MCR_HALT;
- flexcan_write(reg, ®s->mcr);
+ priv->write(reg, ®s->mcr);
- while (timeout-- && (flexcan_read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK))
+ while (timeout-- && (priv->read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK))
udelay(10);
- if (flexcan_read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK)
+ if (priv->read(®s->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, ®s->mcr);
- while (timeout-- && (flexcan_read(®s->mcr) & FLEXCAN_MCR_SOFTRST))
+ priv->write(FLEXCAN_MCR_SOFTRST, ®s->mcr);
+ while (timeout-- && (priv->read(®s->mcr) & FLEXCAN_MCR_SOFTRST))
udelay(10);
- if (flexcan_read(®s->mcr) & FLEXCAN_MCR_SOFTRST)
+ if (priv->read(®s->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(®s->ecr);
+ u32 reg = priv->read(®s->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(®s->iflag1);
+ reg_iflag1 = priv->read(®s->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), ®s->iflag1);
+ priv->write(BIT(n), ®s->iflag1);
else
- flexcan_write(BIT(n - 32), ®s->iflag2);
+ priv->write(BIT(n - 32), ®s->iflag2);
} else {
- flexcan_write(FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, ®s->iflag1);
- flexcan_read(®s->timer);
+ priv->write(FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, ®s->iflag1);
+ priv->read(®s->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(®s->iflag2) & priv->reg_imask2_default;
- iflag1 = flexcan_read(®s->iflag1) & priv->reg_imask1_default &
+ iflag2 = priv->read(®s->iflag2) & priv->reg_imask2_default;
+ iflag1 = priv->read(®s->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(®s->iflag1);
+ reg_iflag1 = priv->read(®s->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, ®s->iflag1);
+ priv->write(FLEXCAN_IFLAG_RX_FIFO_OVERFLOW,
+ ®s->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), ®s->iflag1);
+ priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
+ &priv->tx_mb->can_ctrl);
+ priv->write(FLEXCAN_IFLAG_MB(priv->tx_mb_idx), ®s->iflag1);
netif_wake_queue(dev);
}
- reg_esr = flexcan_read(®s->esr);
+ reg_esr = priv->read(®s->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, ®s->esr);
+ priv->write(reg_esr & FLEXCAN_ESR_ALL_INT, ®s->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(®s->ctrl);
+ reg = priv->read(®s->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, ®s->ctrl);
+ priv->write(reg, ®s->ctrl);
/* print chip status */
netdev_dbg(dev, "%s: mcr=0x%08x ctrl=0x%08x\n", __func__,
- flexcan_read(®s->mcr), flexcan_read(®s->ctrl));
+ priv->read(®s->mcr), priv->read(®s->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(®s->mcr);
+ reg_mcr = priv->read(®s->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, ®s->mcr);
+ priv->write(reg_mcr, ®s->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(®s->ctrl);
+ reg_ctrl = priv->read(®s->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, ®s->ctrl);
+ priv->write(reg_ctrl, ®s->ctrl);
if ((priv->devtype_data->quirks & FLEXCAN_QUIRK_ENABLE_EACEN_RRS)) {
- reg_ctrl2 = flexcan_read(®s->ctrl2);
+ reg_ctrl2 = priv->read(®s->ctrl2);
reg_ctrl2 |= FLEXCAN_CTRL2_EACEN | FLEXCAN_CTRL2_RRS;
- flexcan_write(reg_ctrl2, ®s->ctrl2);
+ priv->write(reg_ctrl2, ®s->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,
- ®s->mb[i].can_ctrl);
+ priv->write(FLEXCAN_MB_CODE_RX_INACTIVE,
+ ®s->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,
- ®s->mb[i].can_ctrl);
+ priv->write(FLEXCAN_MB_CODE_RX_EMPTY,
+ ®s->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, ®s->rxgmask);
- flexcan_write(0x0, ®s->rx14mask);
- flexcan_write(0x0, ®s->rx15mask);
+ priv->write(0x0, ®s->rxgmask);
+ priv->write(0x0, ®s->rx14mask);
+ priv->write(0x0, ®s->rx15mask);
if (priv->devtype_data->quirks & FLEXCAN_QUIRK_DISABLE_RXFG)
- flexcan_write(0x0, ®s->rxfgmask);
+ priv->write(0x0, ®s->rxfgmask);
/* clear acceptance filters */
for (i = 0; i < ARRAY_SIZE(regs->mb); i++)
- flexcan_write(0, ®s->rximr[i]);
+ priv->write(0, ®s->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(®s->ctrl2);
+ reg_ctrl2 = priv->read(®s->ctrl2);
reg_ctrl2 |= FLEXCAN_CTRL2_ECRWRE;
- flexcan_write(reg_ctrl2, ®s->ctrl2);
+ priv->write(reg_ctrl2, ®s->ctrl2);
- reg_mecr = flexcan_read(®s->mecr);
+ reg_mecr = priv->read(®s->mecr);
reg_mecr &= ~FLEXCAN_MECR_ECRWRDIS;
- flexcan_write(reg_mecr, ®s->mecr);
+ priv->write(reg_mecr, ®s->mecr);
reg_mecr &= ~(FLEXCAN_MECR_NCEFAFRZ | FLEXCAN_MECR_HANCEI_MSK |
FLEXCAN_MECR_FANCEI_MSK);
- flexcan_write(reg_mecr, ®s->mecr);
+ priv->write(reg_mecr, ®s->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, ®s->ctrl);
- flexcan_write(priv->reg_imask1_default, ®s->imask1);
- flexcan_write(priv->reg_imask2_default, ®s->imask2);
+ priv->write(priv->reg_ctrl_default, ®s->ctrl);
+ priv->write(priv->reg_imask1_default, ®s->imask1);
+ priv->write(priv->reg_imask2_default, ®s->imask2);
enable_irq(dev->irq);
/* print chip status */
netdev_dbg(dev, "%s: reading mcr=0x%08x ctrl=0x%08x\n", __func__,
- flexcan_read(®s->mcr), flexcan_read(®s->ctrl));
+ priv->read(®s->mcr), priv->read(®s->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, ®s->imask2);
- flexcan_write(0, ®s->imask1);
- flexcan_write(priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_ALL,
- ®s->ctrl);
+ priv->write(0, ®s->imask2);
+ priv->write(0, ®s->imask1);
+ priv->write(priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_ALL,
+ ®s->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(®s->ctrl);
+ reg = priv->read(®s->ctrl);
reg |= FLEXCAN_CTRL_CLK_SRC;
- flexcan_write(reg, ®s->ctrl);
+ priv->write(reg, ®s->ctrl);
err = flexcan_chip_enable(priv);
if (err)
goto out_chip_disable;
/* set freeze, halt and activate FIFO, restrict register access */
- reg = flexcan_read(®s->mcr);
+ reg = priv->read(®s->mcr);
reg |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT |
FLEXCAN_MCR_FEN | FLEXCAN_MCR_SUPV;
- flexcan_write(reg, ®s->mcr);
+ priv->write(reg, ®s->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(®s->mcr);
+ reg = priv->read(®s->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
* [PATCH v2 2/2] can: flexcan: adding platform specific details for LS1021A
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
In-Reply-To: <1510660589-16125-1-git-send-email-pankaj.bansal@nxp.com>
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
* Re: [PATCH v2 2/2] can: flexcan: adding platform specific details for LS1021A
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
In-Reply-To: <1510660589-16125-2-git-send-email-pankaj.bansal@nxp.com>
[-- 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
* Re: [PATCH v2 1/2] can: flexcan: Remodel FlexCAN register r/w APIs for big endian FlexCAN controllers.
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
In-Reply-To: <1510660589-16125-1-git-send-email-pankaj.bansal@nxp.com>
[-- 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, ®s->ctrl);
> + priv->write(reg_ctrl, ®s->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, ®s->ctrl);
> + priv->write(reg_ctrl, ®s->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(®s->mcr);
> + reg = priv->read(®s->mcr);
> reg &= ~FLEXCAN_MCR_MDIS;
> - flexcan_write(reg, ®s->mcr);
> + priv->write(reg, ®s->mcr);
>
> - while (timeout-- && (flexcan_read(®s->mcr) & FLEXCAN_MCR_LPM_ACK))
> + while (timeout-- && (priv->read(®s->mcr) & FLEXCAN_MCR_LPM_ACK))
> udelay(10);
>
> - if (flexcan_read(®s->mcr) & FLEXCAN_MCR_LPM_ACK)
> + if (priv->read(®s->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(®s->mcr);
> + reg = priv->read(®s->mcr);
> reg |= FLEXCAN_MCR_MDIS;
> - flexcan_write(reg, ®s->mcr);
> + priv->write(reg, ®s->mcr);
>
> - while (timeout-- && !(flexcan_read(®s->mcr) & FLEXCAN_MCR_LPM_ACK))
> + while (timeout-- && !(priv->read(®s->mcr) & FLEXCAN_MCR_LPM_ACK))
> udelay(10);
>
> - if (!(flexcan_read(®s->mcr) & FLEXCAN_MCR_LPM_ACK))
> + if (!(priv->read(®s->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(®s->mcr);
> + reg = priv->read(®s->mcr);
> reg |= FLEXCAN_MCR_HALT;
> - flexcan_write(reg, ®s->mcr);
> + priv->write(reg, ®s->mcr);
>
> - while (timeout-- && !(flexcan_read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK))
> + while (timeout-- && !(priv->read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK))
> udelay(100);
>
> - if (!(flexcan_read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK))
> + if (!(priv->read(®s->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(®s->mcr);
> + reg = priv->read(®s->mcr);
> reg &= ~FLEXCAN_MCR_HALT;
> - flexcan_write(reg, ®s->mcr);
> + priv->write(reg, ®s->mcr);
>
> - while (timeout-- && (flexcan_read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK))
> + while (timeout-- && (priv->read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK))
> udelay(10);
>
> - if (flexcan_read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK)
> + if (priv->read(®s->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, ®s->mcr);
> - while (timeout-- && (flexcan_read(®s->mcr) & FLEXCAN_MCR_SOFTRST))
> + priv->write(FLEXCAN_MCR_SOFTRST, ®s->mcr);
> + while (timeout-- && (priv->read(®s->mcr) & FLEXCAN_MCR_SOFTRST))
> udelay(10);
>
> - if (flexcan_read(®s->mcr) & FLEXCAN_MCR_SOFTRST)
> + if (priv->read(®s->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(®s->ecr);
> + u32 reg = priv->read(®s->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(®s->iflag1);
> + reg_iflag1 = priv->read(®s->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), ®s->iflag1);
> + priv->write(BIT(n), ®s->iflag1);
> else
> - flexcan_write(BIT(n - 32), ®s->iflag2);
> + priv->write(BIT(n - 32), ®s->iflag2);
> } else {
> - flexcan_write(FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, ®s->iflag1);
> - flexcan_read(®s->timer);
> + priv->write(FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, ®s->iflag1);
> + priv->read(®s->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(®s->iflag2) & priv->reg_imask2_default;
> - iflag1 = flexcan_read(®s->iflag1) & priv->reg_imask1_default &
> + iflag2 = priv->read(®s->iflag2) & priv->reg_imask2_default;
> + iflag1 = priv->read(®s->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(®s->iflag1);
> + reg_iflag1 = priv->read(®s->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, ®s->iflag1);
> + priv->write(FLEXCAN_IFLAG_RX_FIFO_OVERFLOW,
> + ®s->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), ®s->iflag1);
> + priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
> + &priv->tx_mb->can_ctrl);
> + priv->write(FLEXCAN_IFLAG_MB(priv->tx_mb_idx), ®s->iflag1);
> netif_wake_queue(dev);
> }
>
> - reg_esr = flexcan_read(®s->esr);
> + reg_esr = priv->read(®s->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, ®s->esr);
> + priv->write(reg_esr & FLEXCAN_ESR_ALL_INT, ®s->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(®s->ctrl);
> + reg = priv->read(®s->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, ®s->ctrl);
> + priv->write(reg, ®s->ctrl);
>
> /* print chip status */
> netdev_dbg(dev, "%s: mcr=0x%08x ctrl=0x%08x\n", __func__,
> - flexcan_read(®s->mcr), flexcan_read(®s->ctrl));
> + priv->read(®s->mcr), priv->read(®s->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(®s->mcr);
> + reg_mcr = priv->read(®s->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, ®s->mcr);
> + priv->write(reg_mcr, ®s->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(®s->ctrl);
> + reg_ctrl = priv->read(®s->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, ®s->ctrl);
> + priv->write(reg_ctrl, ®s->ctrl);
>
> if ((priv->devtype_data->quirks & FLEXCAN_QUIRK_ENABLE_EACEN_RRS)) {
> - reg_ctrl2 = flexcan_read(®s->ctrl2);
> + reg_ctrl2 = priv->read(®s->ctrl2);
> reg_ctrl2 |= FLEXCAN_CTRL2_EACEN | FLEXCAN_CTRL2_RRS;
> - flexcan_write(reg_ctrl2, ®s->ctrl2);
> + priv->write(reg_ctrl2, ®s->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,
> - ®s->mb[i].can_ctrl);
> + priv->write(FLEXCAN_MB_CODE_RX_INACTIVE,
> + ®s->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,
> - ®s->mb[i].can_ctrl);
> + priv->write(FLEXCAN_MB_CODE_RX_EMPTY,
> + ®s->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, ®s->rxgmask);
> - flexcan_write(0x0, ®s->rx14mask);
> - flexcan_write(0x0, ®s->rx15mask);
> + priv->write(0x0, ®s->rxgmask);
> + priv->write(0x0, ®s->rx14mask);
> + priv->write(0x0, ®s->rx15mask);
>
> if (priv->devtype_data->quirks & FLEXCAN_QUIRK_DISABLE_RXFG)
> - flexcan_write(0x0, ®s->rxfgmask);
> + priv->write(0x0, ®s->rxfgmask);
>
> /* clear acceptance filters */
> for (i = 0; i < ARRAY_SIZE(regs->mb); i++)
> - flexcan_write(0, ®s->rximr[i]);
> + priv->write(0, ®s->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(®s->ctrl2);
> + reg_ctrl2 = priv->read(®s->ctrl2);
> reg_ctrl2 |= FLEXCAN_CTRL2_ECRWRE;
> - flexcan_write(reg_ctrl2, ®s->ctrl2);
> + priv->write(reg_ctrl2, ®s->ctrl2);
>
> - reg_mecr = flexcan_read(®s->mecr);
> + reg_mecr = priv->read(®s->mecr);
> reg_mecr &= ~FLEXCAN_MECR_ECRWRDIS;
> - flexcan_write(reg_mecr, ®s->mecr);
> + priv->write(reg_mecr, ®s->mecr);
> reg_mecr &= ~(FLEXCAN_MECR_NCEFAFRZ | FLEXCAN_MECR_HANCEI_MSK |
> FLEXCAN_MECR_FANCEI_MSK);
> - flexcan_write(reg_mecr, ®s->mecr);
> + priv->write(reg_mecr, ®s->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, ®s->ctrl);
> - flexcan_write(priv->reg_imask1_default, ®s->imask1);
> - flexcan_write(priv->reg_imask2_default, ®s->imask2);
> + priv->write(priv->reg_ctrl_default, ®s->ctrl);
> + priv->write(priv->reg_imask1_default, ®s->imask1);
> + priv->write(priv->reg_imask2_default, ®s->imask2);
> enable_irq(dev->irq);
>
> /* print chip status */
> netdev_dbg(dev, "%s: reading mcr=0x%08x ctrl=0x%08x\n", __func__,
> - flexcan_read(®s->mcr), flexcan_read(®s->ctrl));
> + priv->read(®s->mcr), priv->read(®s->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, ®s->imask2);
> - flexcan_write(0, ®s->imask1);
> - flexcan_write(priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_ALL,
> - ®s->ctrl);
> + priv->write(0, ®s->imask2);
> + priv->write(0, ®s->imask1);
> + priv->write(priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_ALL,
> + ®s->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(®s->ctrl);
> + reg = priv->read(®s->ctrl);
> reg |= FLEXCAN_CTRL_CLK_SRC;
> - flexcan_write(reg, ®s->ctrl);
> + priv->write(reg, ®s->ctrl);
>
> err = flexcan_chip_enable(priv);
> if (err)
> goto out_chip_disable;
>
> /* set freeze, halt and activate FIFO, restrict register access */
> - reg = flexcan_read(®s->mcr);
> + reg = priv->read(®s->mcr);
> reg |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT |
> FLEXCAN_MCR_FEN | FLEXCAN_MCR_SUPV;
> - flexcan_write(reg, ®s->mcr);
> + priv->write(reg, ®s->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(®s->mcr);
> + reg = priv->read(®s->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
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox