Linux CAN drivers development
 help / color / mirror / Atom feed
* RE: PCAN-USB on 3v3 CAN
From: Stéphane Grosjean @ 2017-11-17 14:41 UTC (permalink / raw)
  To: Kurt Van Dijck; +Cc: linux-can@vger.kernel.org
In-Reply-To: <20171117132954.GA7355@airbook.vandijck-laurijssen.be>

Hi,

The 3V3 is not the problem but this weird bitrate is not supported by the PCAN-USB.

Regards,

Stephane

-----Original Message-----
From: linux-can-owner@vger.kernel.org [mailto:linux-can-owner@vger.kernel.org] On Behalf Of Kurt Van Dijck
Sent: vendredi 17 novembre 2017 14:30
To: linux-can@vger.kernel.org
Subject: PCAN-USB on 3v3 CAN

Hello,

I have difficulty connecting my PCAN-USB to a CAN network where all nodes have a 3v3 transceiver, and the obscure bitrate of 923kBit.

Since this is the first time I encountered a '3v3' CAN bus, I was a bit supprised. Will this work with my (I think) 5v PCAN-USB?
Is this transceiver voltage interchangeable?

Kind regards,
Kurt
--
To unsubscribe from this list: send the line "unsubscribe linux-can" in the body of a message to majordomo@vger.kernel.org More majordomo info at  http://vger.kernel.org/majordomo-info.html

--
PEAK-System Technik GmbH
Sitz der Gesellschaft Darmstadt - HRB 9183
Geschaeftsfuehrung: Alexander Gach / Uwe Wilhelm
--

^ permalink raw reply

* PCAN-USB on 3v3 CAN
From: Kurt Van Dijck @ 2017-11-17 13:29 UTC (permalink / raw)
  To: linux-can

Hello,

I have difficulty connecting my PCAN-USB to a CAN network
where all nodes have a 3v3 transceiver,
and the obscure bitrate of 923kBit.

Since this is the first time I encountered a '3v3' CAN bus,
I was a bit supprised. Will this work with my (I think) 5v PCAN-USB?
Is this transceiver voltage interchangeable?

Kind regards,
Kurt

^ permalink raw reply

* Re: [PATCH 2/7] pinctrl: sh-pfc: r8a77995: Add CAN FD support
From: Geert Uytterhoeven @ 2017-11-17 13:31 UTC (permalink / raw)
  To: Ulrich Hecht
  Cc: Linux-Renesas, linux-can, devicetree@vger.kernel.org,
	Wolfram Sang, Simon Horman, Magnus Damm, Chris Paterson,
	Ramesh Shanmugasundaram
In-Reply-To: <1510915289-15059-3-git-send-email-ulrich.hecht+renesas@gmail.com>

On Fri, Nov 17, 2017 at 11:41 AM, Ulrich Hecht
<ulrich.hecht+renesas@gmail.com> wrote:
> This patch adds CAN FD[0-1] pinmux support to the r8a77995 SoC.
>
> Signed-off-by: Ulrich Hecht <ulrich.hecht+renesas@gmail.com>

Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
i.e. will queue in sh-pfc-for-v4.16.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply

* Re: [PATCH 1/7] pinctrl: sh-pfc: r8a77995: Add CAN support
From: Geert Uytterhoeven @ 2017-11-17 13:30 UTC (permalink / raw)
  To: Ulrich Hecht
  Cc: Linux-Renesas, linux-can, devicetree@vger.kernel.org,
	Wolfram Sang, Simon Horman, Magnus Damm, Chris Paterson,
	Ramesh Shanmugasundaram
In-Reply-To: <1510915289-15059-2-git-send-email-ulrich.hecht+renesas@gmail.com>

On Fri, Nov 17, 2017 at 11:41 AM, Ulrich Hecht
<ulrich.hecht+renesas@gmail.com> wrote:
> This patch adds CAN[0-1] pinmux support to the r8a77995 SoC.
>
> Signed-off-by: Ulrich Hecht <ulrich.hecht+renesas@gmail.com>

Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
i.e. will queue in sh-pfc-for-v4.16.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply

* [PATCH 0/7] R-Car D3 (r8a77995) CAN support
From: Ulrich Hecht @ 2017-11-17 10:41 UTC (permalink / raw)
  To: linux-renesas-soc
  Cc: linux-can, devicetree, wsa, horms, geert, magnus.damm,
	chris.paterson2, ramesh.shanmugasundaram, Ulrich Hecht

Hi!

Here's CAN and CAN FD support for the R-Car D3. This is a by-the-datasheet
implementation, with the datasheet missing some bits, namely the pin map.
I filled in the gaps with frog DNA^W^W^Wby deducing the information from
pin numbers already in the PFC driver, so careful scrutiny is advised.

CU
Uli


Ulrich Hecht (7):
  pinctrl: sh-pfc: r8a77995: Add CAN support
  pinctrl: sh-pfc: r8a77995: Add CAN FD support
  arm64: dts: r8a77995: Add CAN external clock support
  arm64: dts: r8a77995: Add CAN support
  arm64: dts: r8a77995: Add CAN FD support
  can: rcar_can: document r8a77995 (R-Car D3) compatibility strings
  can: rcar_canfd: document r8a77995 (R-Car D3) compatibility strings

 .../devicetree/bindings/net/can/rcar_can.txt       | 13 ++--
 .../devicetree/bindings/net/can/rcar_canfd.txt     | 13 ++--
 arch/arm64/boot/dts/renesas/r8a77995.dtsi          | 64 ++++++++++++++++
 drivers/pinctrl/sh-pfc/pfc-r8a77995.c              | 86 ++++++++++++++++++++++
 4 files changed, 164 insertions(+), 12 deletions(-)

-- 
2.7.4


^ permalink raw reply

* [PATCH 7/7] can: rcar_canfd: document r8a77995 (R-Car D3) compatibility strings
From: Ulrich Hecht @ 2017-11-17 10:41 UTC (permalink / raw)
  To: linux-renesas-soc-u79uwXL29TY76Z2rM5mHXA
  Cc: linux-can-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, wsa-z923LK4zBo2bacvFa/9K2g,
	horms-/R6kz+dDXgpPR4JQBCEnsQ, geert-Td1EMuHUCqxL1ZNQvxDV9g,
	magnus.damm-Re5JQEeQqe8AvxtiuMwx3w,
	chris.paterson2-zM6kxYcvzFBBDgjK7y7TUQ,
	ramesh.shanmugasundaram-kTT6dE0pTRh9uiUsa/gSgQ, Ulrich Hecht
In-Reply-To: <1510915289-15059-1-git-send-email-ulrich.hecht+renesas-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

Signed-off-by: Ulrich Hecht <ulrich.hecht+renesas-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 Documentation/devicetree/bindings/net/can/rcar_canfd.txt | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/Documentation/devicetree/bindings/net/can/rcar_canfd.txt b/Documentation/devicetree/bindings/net/can/rcar_canfd.txt
index 93c3a6a..5617892 100644
--- a/Documentation/devicetree/bindings/net/can/rcar_canfd.txt
+++ b/Documentation/devicetree/bindings/net/can/rcar_canfd.txt
@@ -6,6 +6,7 @@ Required properties:
   - "renesas,rcar-gen3-canfd" for R-Car Gen3 compatible controller.
   - "renesas,r8a7795-canfd" for R8A7795 (R-Car H3) compatible controller.
   - "renesas,r8a7796-canfd" for R8A7796 (R-Car M3) compatible controller.
+  - "renesas,r8a77995-canfd" for R8A77995 (R-Car D3) compatible controller.
 
   When compatible with the generic version, nodes must list the
   SoC-specific version corresponding to the platform first, followed by the
@@ -24,12 +25,12 @@ The name of the child nodes are "channel0" and "channel1" respectively. Each
 child node supports the "status" property only, which is used to
 enable/disable the respective channel.
 
-Required properties for "renesas,r8a7795-canfd" and "renesas,r8a7796-canfd"
-compatible:
-In R8A7795 and R8A7796 SoCs, canfd clock is a div6 clock and can be used by both
-CAN and CAN FD controller at the same time. It needs to be scaled to maximum
-frequency if any of these controllers use it. This is done using the below
-properties:
+Required properties for "renesas,r8a7795-canfd", "renesas,r8a7796-canfd" and
+"renesas,r8a77995" compatible:
+In R8A7795, R8A7796 and R8A77995 SoCs, canfd clock is a div6 clock and can
+be used by both CAN and CAN FD controller at the same time. It needs to be
+scaled to maximum frequency if any of these controllers use it. This is
+done using the below properties:
 
 - assigned-clocks: phandle of canfd clock.
 - assigned-clock-rates: maximum frequency of this clock.
-- 
2.7.4

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* [PATCH 6/7] can: rcar_can: document r8a77995 (R-Car D3) compatibility strings
From: Ulrich Hecht @ 2017-11-17 10:41 UTC (permalink / raw)
  To: linux-renesas-soc-u79uwXL29TY76Z2rM5mHXA
  Cc: linux-can-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, wsa-z923LK4zBo2bacvFa/9K2g,
	horms-/R6kz+dDXgpPR4JQBCEnsQ, geert-Td1EMuHUCqxL1ZNQvxDV9g,
	magnus.damm-Re5JQEeQqe8AvxtiuMwx3w,
	chris.paterson2-zM6kxYcvzFBBDgjK7y7TUQ,
	ramesh.shanmugasundaram-kTT6dE0pTRh9uiUsa/gSgQ, Ulrich Hecht
In-Reply-To: <1510915289-15059-1-git-send-email-ulrich.hecht+renesas-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

Signed-off-by: Ulrich Hecht <ulrich.hecht+renesas-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 Documentation/devicetree/bindings/net/can/rcar_can.txt | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/Documentation/devicetree/bindings/net/can/rcar_can.txt b/Documentation/devicetree/bindings/net/can/rcar_can.txt
index 06bb7cc..f7d0358 100644
--- a/Documentation/devicetree/bindings/net/can/rcar_can.txt
+++ b/Documentation/devicetree/bindings/net/can/rcar_can.txt
@@ -11,6 +11,7 @@ Required properties:
 	      "renesas,can-r8a7794" if CAN controller is a part of R8A7794 SoC.
 	      "renesas,can-r8a7795" if CAN controller is a part of R8A7795 SoC.
 	      "renesas,can-r8a7796" if CAN controller is a part of R8A7796 SoC.
+	      "renesas,can-r8a77995" if CAN controller is a part of R8A77995 SoC.
 	      "renesas,rcar-gen1-can" for a generic R-Car Gen1 compatible device.
 	      "renesas,rcar-gen2-can" for a generic R-Car Gen2 compatible device.
 	      "renesas,rcar-gen3-can" for a generic R-Car Gen3 compatible device.
@@ -25,12 +26,12 @@ Required properties:
 - pinctrl-0: pin control group to be used for this controller.
 - pinctrl-names: must be "default".
 
-Required properties for "renesas,can-r8a7795" and "renesas,can-r8a7796"
-compatible:
-In R8A7795 and R8A7796 SoCs, "clkp2" can be CANFD clock. This is a div6 clock
-and can be used by both CAN and CAN FD controller at the same time. It needs to
-be scaled to maximum frequency if any of these controllers use it. This is done
-using the below properties:
+Required properties for "renesas,can-r8a7795", "renesas,can-r8a7796" and
+"renesas,can-r8a77995" compatible:
+In R8A7795, R8A7796 and R8A77995 SoCs, "clkp2" can be CANFD clock. This is a
+div6 clock and can be used by both CAN and CAN FD controller at the same
+time. It needs to be scaled to maximum frequency if any of these
+controllers use it. This is done using the below properties:
 
 - assigned-clocks: phandle of clkp2(CANFD) clock.
 - assigned-clock-rates: maximum frequency of this clock.
-- 
2.7.4

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* [PATCH 5/7] arm64: dts: r8a77995: Add CAN FD support
From: Ulrich Hecht @ 2017-11-17 10:41 UTC (permalink / raw)
  To: linux-renesas-soc
  Cc: linux-can, devicetree, wsa, horms, geert, magnus.damm,
	chris.paterson2, ramesh.shanmugasundaram, Ulrich Hecht
In-Reply-To: <1510915289-15059-1-git-send-email-ulrich.hecht+renesas@gmail.com>

Adds CAN FD controller node for r8a77995.

Based on a patch for r8a7796 by Chris Paterson.

Signed-off-by: Ulrich Hecht <ulrich.hecht+renesas@gmail.com>
---
 arch/arm64/boot/dts/renesas/r8a77995.dtsi | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/arch/arm64/boot/dts/renesas/r8a77995.dtsi b/arch/arm64/boot/dts/renesas/r8a77995.dtsi
index a611324..6648c9b 100644
--- a/arch/arm64/boot/dts/renesas/r8a77995.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a77995.dtsi
@@ -306,6 +306,31 @@
 			status = "disabled";
 		};
 
+		canfd: can@e66c0000 {
+			compatible = "renesas,r8a77995-canfd",
+				     "renesas,rcar-gen3-canfd";
+			reg = <0 0xe66c0000 0 0x8000>;
+			interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>,
+				   <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 914>,
+			       <&cpg CPG_CORE R8A77995_CLK_CANFD>,
+			       <&can_clk>;
+			clock-names = "fck", "canfd", "can_clk";
+			assigned-clocks = <&cpg CPG_CORE R8A77995_CLK_CANFD>;
+			assigned-clock-rates = <40000000>;
+			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+			resets = <&cpg 914>;
+			status = "disabled";
+
+			channel0 {
+				status = "disabled";
+			};
+
+			channel1 {
+				status = "disabled";
+			};
+		};
+
 		avb: ethernet@e6800000 {
 			compatible = "renesas,etheravb-r8a77995",
 				     "renesas,etheravb-rcar-gen3";
-- 
2.7.4

^ permalink raw reply related

* [PATCH 4/7] arm64: dts: r8a77995: Add CAN support
From: Ulrich Hecht @ 2017-11-17 10:41 UTC (permalink / raw)
  To: linux-renesas-soc-u79uwXL29TY76Z2rM5mHXA
  Cc: linux-can-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, wsa-z923LK4zBo2bacvFa/9K2g,
	horms-/R6kz+dDXgpPR4JQBCEnsQ, geert-Td1EMuHUCqxL1ZNQvxDV9g,
	magnus.damm-Re5JQEeQqe8AvxtiuMwx3w,
	chris.paterson2-zM6kxYcvzFBBDgjK7y7TUQ,
	ramesh.shanmugasundaram-kTT6dE0pTRh9uiUsa/gSgQ, Ulrich Hecht
In-Reply-To: <1510915289-15059-1-git-send-email-ulrich.hecht+renesas-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

Adds CAN controller nodes for r8a77995.

Based on a patch for r8a7796 by Chris Paterson.

Signed-off-by: Ulrich Hecht <ulrich.hecht+renesas-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 arch/arm64/boot/dts/renesas/r8a77995.dtsi | 32 +++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/arch/arm64/boot/dts/renesas/r8a77995.dtsi b/arch/arm64/boot/dts/renesas/r8a77995.dtsi
index a8df296..a611324 100644
--- a/arch/arm64/boot/dts/renesas/r8a77995.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a77995.dtsi
@@ -274,6 +274,38 @@
 			resets = <&cpg 906>;
 		};
 
+		can0: can@e6c30000 {
+			compatible = "renesas,can-r8a77995",
+				     "renesas,rcar-gen3-can";
+			reg = <0 0xe6c30000 0 0x1000>;
+			interrupts = <GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 916>,
+			       <&cpg CPG_CORE R8A77995_CLK_CANFD>,
+			       <&can_clk>;
+			clock-names = "clkp1", "clkp2", "can_clk";
+			assigned-clocks = <&cpg CPG_CORE R8A77995_CLK_CANFD>;
+			assigned-clock-rates = <40000000>;
+			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+			resets = <&cpg 916>;
+			status = "disabled";
+		};
+
+		can1: can@e6c38000 {
+			compatible = "renesas,can-r8a77995",
+				     "renesas,rcar-gen3-can";
+			reg = <0 0xe6c38000 0 0x1000>;
+			interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 915>,
+			       <&cpg CPG_CORE R8A77995_CLK_CANFD>,
+			       <&can_clk>;
+			clock-names = "clkp1", "clkp2", "can_clk";
+			assigned-clocks = <&cpg CPG_CORE R8A77995_CLK_CANFD>;
+			assigned-clock-rates = <40000000>;
+			power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+			resets = <&cpg 915>;
+			status = "disabled";
+		};
+
 		avb: ethernet@e6800000 {
 			compatible = "renesas,etheravb-r8a77995",
 				     "renesas,etheravb-rcar-gen3";
-- 
2.7.4

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* [PATCH 3/7] arm64: dts: r8a77995: Add CAN external clock support
From: Ulrich Hecht @ 2017-11-17 10:41 UTC (permalink / raw)
  To: linux-renesas-soc-u79uwXL29TY76Z2rM5mHXA
  Cc: linux-can-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, wsa-z923LK4zBo2bacvFa/9K2g,
	horms-/R6kz+dDXgpPR4JQBCEnsQ, geert-Td1EMuHUCqxL1ZNQvxDV9g,
	magnus.damm-Re5JQEeQqe8AvxtiuMwx3w,
	chris.paterson2-zM6kxYcvzFBBDgjK7y7TUQ,
	ramesh.shanmugasundaram-kTT6dE0pTRh9uiUsa/gSgQ, Ulrich Hecht
In-Reply-To: <1510915289-15059-1-git-send-email-ulrich.hecht+renesas-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

Adds external CAN clock node for r8a77995. This clock can be used as
fCAN clock of CAN and CAN FD controller.

Based on a patch for r8a7796 by Chris Paterson.

Signed-off-by: Ulrich Hecht <ulrich.hecht+renesas-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 arch/arm64/boot/dts/renesas/r8a77995.dtsi | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm64/boot/dts/renesas/r8a77995.dtsi b/arch/arm64/boot/dts/renesas/r8a77995.dtsi
index 788e3af..a8df296 100644
--- a/arch/arm64/boot/dts/renesas/r8a77995.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a77995.dtsi
@@ -51,6 +51,13 @@
 		clock-frequency = <0>;
 	};
 
+	/* External CAN clock - to be overridden by boards that provide it */
+	can_clk: can {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <0>;
+	};
+
 	scif_clk: scif {
 		compatible = "fixed-clock";
 		#clock-cells = <0>;
-- 
2.7.4

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* [PATCH 2/7] pinctrl: sh-pfc: r8a77995: Add CAN FD support
From: Ulrich Hecht @ 2017-11-17 10:41 UTC (permalink / raw)
  To: linux-renesas-soc-u79uwXL29TY76Z2rM5mHXA
  Cc: linux-can-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, wsa-z923LK4zBo2bacvFa/9K2g,
	horms-/R6kz+dDXgpPR4JQBCEnsQ, geert-Td1EMuHUCqxL1ZNQvxDV9g,
	magnus.damm-Re5JQEeQqe8AvxtiuMwx3w,
	chris.paterson2-zM6kxYcvzFBBDgjK7y7TUQ,
	ramesh.shanmugasundaram-kTT6dE0pTRh9uiUsa/gSgQ, Ulrich Hecht
In-Reply-To: <1510915289-15059-1-git-send-email-ulrich.hecht+renesas-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

This patch adds CAN FD[0-1] pinmux support to the r8a77995 SoC.

Signed-off-by: Ulrich Hecht <ulrich.hecht+renesas-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 drivers/pinctrl/sh-pfc/pfc-r8a77995.c | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a77995.c b/drivers/pinctrl/sh-pfc/pfc-r8a77995.c
index 616854d..e7849a4 100644
--- a/drivers/pinctrl/sh-pfc/pfc-r8a77995.c
+++ b/drivers/pinctrl/sh-pfc/pfc-r8a77995.c
@@ -1096,6 +1096,22 @@ static const unsigned int can_clk_mux[] = {
 	CAN_CLK_MARK,
 };
 
+/* - CAN FD ----------------------------------------------------------------- */
+static const unsigned int canfd0_data_pins[] = {
+	/* TX, RX */
+	RCAR_GP_PIN(4, 28), RCAR_GP_PIN(4, 31),
+};
+static const unsigned int canfd0_data_mux[] = {
+	CANFD0_TX_MARK, CANFD0_RX_MARK,
+};
+static const unsigned int canfd1_data_pins[] = {
+	/* TX, RX */
+	RCAR_GP_PIN(4, 30), RCAR_GP_PIN(4, 29),
+};
+static const unsigned int canfd1_data_mux[] = {
+	CANFD1_TX_MARK, CANFD1_RX_MARK,
+};
+
 /* - I2C -------------------------------------------------------------------- */
 static const unsigned int i2c0_pins[] = {
 	/* SCL, SDA */
@@ -1548,6 +1564,8 @@ static const struct sh_pfc_pin_group pinmux_groups[] = {
 	SH_PFC_PIN_GROUP(can1_data_a),
 	SH_PFC_PIN_GROUP(can1_data_b),
 	SH_PFC_PIN_GROUP(can_clk),
+	SH_PFC_PIN_GROUP(canfd0_data),
+	SH_PFC_PIN_GROUP(canfd1_data),
 	SH_PFC_PIN_GROUP(i2c0),
 	SH_PFC_PIN_GROUP(i2c1),
 	SH_PFC_PIN_GROUP(i2c2_a),
@@ -1637,6 +1655,13 @@ static const char * const can_clk_groups[] = {
 	"can_clk",
 };
 
+static const char * const canfd0_groups[] = {
+	"canfd0_data",
+};
+static const char * const canfd1_groups[] = {
+	"canfd1_data",
+};
+
 static const char * const i2c0_groups[] = {
 	"i2c0",
 };
@@ -1750,6 +1775,8 @@ static const struct sh_pfc_function pinmux_functions[] = {
 	SH_PFC_FUNCTION(can0),
 	SH_PFC_FUNCTION(can1),
 	SH_PFC_FUNCTION(can_clk),
+	SH_PFC_FUNCTION(canfd0),
+	SH_PFC_FUNCTION(canfd1),
 	SH_PFC_FUNCTION(i2c0),
 	SH_PFC_FUNCTION(i2c1),
 	SH_PFC_FUNCTION(i2c2),
-- 
2.7.4

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* [PATCH 1/7] pinctrl: sh-pfc: r8a77995: Add CAN support
From: Ulrich Hecht @ 2017-11-17 10:41 UTC (permalink / raw)
  To: linux-renesas-soc
  Cc: linux-can, devicetree, wsa, horms, geert, magnus.damm,
	chris.paterson2, ramesh.shanmugasundaram, Ulrich Hecht
In-Reply-To: <1510915289-15059-1-git-send-email-ulrich.hecht+renesas@gmail.com>

This patch adds CAN[0-1] pinmux support to the r8a77995 SoC.

Signed-off-by: Ulrich Hecht <ulrich.hecht+renesas@gmail.com>
---
 drivers/pinctrl/sh-pfc/pfc-r8a77995.c | 59 +++++++++++++++++++++++++++++++++++
 1 file changed, 59 insertions(+)

diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a77995.c b/drivers/pinctrl/sh-pfc/pfc-r8a77995.c
index 89b7541..616854d 100644
--- a/drivers/pinctrl/sh-pfc/pfc-r8a77995.c
+++ b/drivers/pinctrl/sh-pfc/pfc-r8a77995.c
@@ -1057,6 +1057,45 @@ static const unsigned int avb0_avtp_capture_b_mux[] = {
 	AVB0_AVTP_CAPTURE_B_MARK,
 };
 
+/* - CAN ------------------------------------------------------------------ */
+static const unsigned int can0_data_a_pins[] = {
+	/* TX, RX */
+	RCAR_GP_PIN(4, 28), RCAR_GP_PIN(4, 31),
+};
+static const unsigned int can0_data_a_mux[] = {
+	CAN0_TX_A_MARK, CAN0_RX_A_MARK,
+};
+static const unsigned int can0_data_b_pins[] = {
+	/* TX, RX */
+	RCAR_GP_PIN(4, 22), RCAR_GP_PIN(4, 5),
+};
+static const unsigned int can0_data_b_mux[] = {
+	CAN0_TX_B_MARK, CAN0_RX_B_MARK,
+};
+static const unsigned int can1_data_a_pins[] = {
+	/* TX, RX */
+	RCAR_GP_PIN(4, 30), RCAR_GP_PIN(4, 29),
+};
+static const unsigned int can1_data_a_mux[] = {
+	CAN1_TX_A_MARK, CAN1_RX_A_MARK,
+};
+static const unsigned int can1_data_b_pins[] = {
+	/* TX, RX */
+	RCAR_GP_PIN(4, 7), RCAR_GP_PIN(4, 6),
+};
+static const unsigned int can1_data_b_mux[] = {
+	CAN1_TX_B_MARK, CAN1_RX_B_MARK,
+};
+
+/* - CAN Clock -------------------------------------------------------------- */
+static const unsigned int can_clk_pins[] = {
+	/* CLK */
+	RCAR_GP_PIN(5, 2),
+};
+static const unsigned int can_clk_mux[] = {
+	CAN_CLK_MARK,
+};
+
 /* - I2C -------------------------------------------------------------------- */
 static const unsigned int i2c0_pins[] = {
 	/* SCL, SDA */
@@ -1504,6 +1543,11 @@ static const struct sh_pfc_pin_group pinmux_groups[] = {
 	SH_PFC_PIN_GROUP(avb0_avtp_pps_b),
 	SH_PFC_PIN_GROUP(avb0_avtp_match_b),
 	SH_PFC_PIN_GROUP(avb0_avtp_capture_b),
+	SH_PFC_PIN_GROUP(can0_data_a),
+	SH_PFC_PIN_GROUP(can0_data_b),
+	SH_PFC_PIN_GROUP(can1_data_a),
+	SH_PFC_PIN_GROUP(can1_data_b),
+	SH_PFC_PIN_GROUP(can_clk),
 	SH_PFC_PIN_GROUP(i2c0),
 	SH_PFC_PIN_GROUP(i2c1),
 	SH_PFC_PIN_GROUP(i2c2_a),
@@ -1581,6 +1625,18 @@ static const char * const avb0_groups[] = {
 	"avb0_avtp_capture_b",
 };
 
+static const char * const can0_groups[] = {
+	"can0_data_a",
+	"can0_data_b",
+};
+static const char * const can1_groups[] = {
+	"can1_data_a",
+	"can1_data_b",
+};
+static const char * const can_clk_groups[] = {
+	"can_clk",
+};
+
 static const char * const i2c0_groups[] = {
 	"i2c0",
 };
@@ -1691,6 +1747,9 @@ static const char * const usb0_groups[] = {
 static const struct sh_pfc_function pinmux_functions[] = {
 	SH_PFC_FUNCTION(audio_clk),
 	SH_PFC_FUNCTION(avb0),
+	SH_PFC_FUNCTION(can0),
+	SH_PFC_FUNCTION(can1),
+	SH_PFC_FUNCTION(can_clk),
 	SH_PFC_FUNCTION(i2c0),
 	SH_PFC_FUNCTION(i2c1),
 	SH_PFC_FUNCTION(i2c2),
-- 
2.7.4

^ permalink raw reply related

* Re: [PATCH v2 1/2] can: flexcan: Remodel FlexCAN register r/w APIs for big endian FlexCAN controllers.
From: Marc Kleine-Budde @ 2017-11-16 12:04 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: <AM0PR0402MB3940B601B1AB23500B2B49D0F12E0@AM0PR0402MB3940.eurprd04.prod.outlook.com>


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

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

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

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

I don't mind.

Marc

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


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

^ permalink raw reply

* RE: [PATCH v2 2/2] can: flexcan: adding platform specific details for LS1021A
From: ZHU Yi (ST-FIR/ENG1-Zhu) @ 2017-11-16  7:23 UTC (permalink / raw)
  To: Wolfgang Grandegger, Pankaj Bansal, Marc Kleine-Budde,
	linux-can@vger.kernel.org
  Cc: Varun Sethi, Poonam Aggrwal, Bhupesh Sharma
In-Reply-To: <343d8c69-a01a-5ff7-75a2-99523391f97c@grandegger.com>

Hello Pankaj,

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

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

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

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

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

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

Best regards
Yi

^ permalink raw reply

* Re: [PATCH v2 2/2] can: flexcan: adding platform specific details for LS1021A
From: Wolfgang Grandegger @ 2017-11-16  7:05 UTC (permalink / raw)
  To: Pankaj Bansal, Marc Kleine-Budde, linux-can@vger.kernel.org,
	Yi.Zhu5@cn.bosch.com
  Cc: Varun Sethi, Poonam Aggrwal, Bhupesh Sharma
In-Reply-To: <AM0PR0402MB3940A4B29C67BAD85F461331F12E0@AM0PR0402MB3940.eurprd04.prod.outlook.com>



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

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

You can test such state changes by doing:

1. Send messages without CAN cable connected

2. Short-circuit the CAN low and high signals

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

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

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

Thanks,

Wolfgang.

^ permalink raw reply

* RE: [PATCH v2 2/2] can: flexcan: adding platform specific details for LS1021A
From: Pankaj Bansal @ 2017-11-16  5:34 UTC (permalink / raw)
  To: Marc Kleine-Budde, wg@grandegger.com, linux-can@vger.kernel.org,
	Yi.Zhu5@cn.bosch.com
  Cc: Varun Sethi, Poonam Aggrwal, Bhupesh Sharma
In-Reply-To: <828fba89-66dc-a2c5-e095-8554b9dce5d5@pengutronix.de>



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

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

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

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

Can you please help me to understand ?

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


^ permalink raw reply

* RE: [PATCH v2 1/2] can: flexcan: Remodel FlexCAN register r/w APIs for big endian FlexCAN controllers.
From: Pankaj Bansal @ 2017-11-16  5:24 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: <26cf5587-3100-e681-b477-0f87ed58b872@pengutronix.de>



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

Ok, will do.

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

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

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


^ permalink raw reply

* Re: MCP251x SPI CAN controller on Cavium ThunderX
From: Mark Brown @ 2017-11-15 15:39 UTC (permalink / raw)
  To: Jan Glauber
  Cc: Marc Kleine-Budde, Tim Harvey, linux-spi,
	linux-kernel@vger.kernel.org, Wolfgang Grandegger, linux-can
In-Reply-To: <20171115120754.GC3011@hc>

[-- Attachment #1: Type: text/plain, Size: 461 bytes --]

On Wed, Nov 15, 2017 at 01:07:54PM +0100, Jan Glauber wrote:

> To support this full duplex transfer the Cavium SPI controller needs
> to know the receive lenght before setting up the transaction.

> spi_transfer only includes the total length, so I don't see how this
> should work.

For a full duplex transfer the recieve length *is* the total length of
the transfer.  If there is a mix of tx, rx and full duplex then you need
multiple xfers in the transfer.

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

^ permalink raw reply

* Re: MCP251x SPI CAN controller on Cavium ThunderX
From: Jan Glauber @ 2017-11-15 14:24 UTC (permalink / raw)
  To: Marc Kleine-Budde
  Cc: Mark Brown, Tim Harvey, linux-spi, linux-kernel@vger.kernel.org,
	Wolfgang Grandegger, linux-can, David Daney
In-Reply-To: <1feffea6-00de-6e73-309a-bd9619c19666@pengutronix.de>

On Wed, Nov 15, 2017 at 02:31:45PM +0100, Marc Kleine-Budde wrote:
> On 11/15/2017 01:40 PM, Marc Kleine-Budde wrote:
> > mcp251x_spi_trans() is called with len=3,
> > priv->spi_tx_buf and priv->spi_rx_buf point to previously allocared memory
> > 
> > priv->spi_tx_buf has been filled before calling mcp251x_spi_trans().
> 
> > #define OCTEON_SPI_MAX_BYTES 9
> 
> > static int octeon_spi_do_transfer(struct octeon_spi *p,
> > 				  struct spi_message *msg,
> > 				  struct spi_transfer *xfer,
> > 				  bool last_xfer)
> > {
> > 	struct spi_device *spi = msg->spi;
> > 	union cvmx_mpi_cfg mpi_cfg;
> > 	union cvmx_mpi_tx mpi_tx;
> > 	unsigned int clkdiv;
> > 	int mode;
> > 	bool cpha, cpol;
> > 	const u8 *tx_buf;
> > 	u8 *rx_buf;
> > 	int len;
> > 	int i;
> > 
> > 	mode = spi->mode;
> > 	cpha = mode & SPI_CPHA;
> > 	cpol = mode & SPI_CPOL;
> > 
> > 	clkdiv = p->sys_freq / (2 * xfer->speed_hz);
> > 
> > 	mpi_cfg.u64 = 0;
> > 
> > 	mpi_cfg.s.clkdiv = clkdiv;
> > 	mpi_cfg.s.cshi = (mode & SPI_CS_HIGH) ? 1 : 0;
> > 	mpi_cfg.s.lsbfirst = (mode & SPI_LSB_FIRST) ? 1 : 0;
> > 	mpi_cfg.s.wireor = (mode & SPI_3WIRE) ? 1 : 0;
> > 	mpi_cfg.s.idlelo = cpha != cpol;
> > 	mpi_cfg.s.cslate = cpha ? 1 : 0;
> > 	mpi_cfg.s.enable = 1;
> > 
> > 	if (spi->chip_select < 4)
> > 		p->cs_enax |= 1ull << (12 + spi->chip_select);
> > 	mpi_cfg.u64 |= p->cs_enax;
> > 
> > 	if (mpi_cfg.u64 != p->last_cfg) {
> > 		p->last_cfg = mpi_cfg.u64;
> > 		writeq(mpi_cfg.u64, p->register_base + OCTEON_SPI_CFG(p));
> > 	}
> > 	tx_buf = xfer->tx_buf;
> > 	rx_buf = xfer->rx_buf;
> > 	len = xfer->len;
> > 	while (len > OCTEON_SPI_MAX_BYTES) {
> > 		for (i = 0; i < OCTEON_SPI_MAX_BYTES; i++) {
> > 			u8 d;
> > 			if (tx_buf)
> > 				d = *tx_buf++;
> > 			else
> > 				d = 0;
> > 			writeq(d, p->register_base + OCTEON_SPI_DAT0(p) + (8 * i));
> > 		}
> > 		mpi_tx.u64 = 0;
> > 		mpi_tx.s.csid = spi->chip_select;
> > 		mpi_tx.s.leavecs = 1;
> > 		mpi_tx.s.txnum = tx_buf ? OCTEON_SPI_MAX_BYTES : 0;
> 
> This looks fishy, OCTEON_SPI_MAX_BYTES is 9....

Because there are 9 registers in MPI_DAT(0..8).

> > 		mpi_tx.s.totnum = OCTEON_SPI_MAX_BYTES;
> > 		writeq(mpi_tx.u64, p->register_base + OCTEON_SPI_TX(p));
> > 
> > 		octeon_spi_wait_ready(p);
> > 		if (rx_buf)
> > 			for (i = 0; i < OCTEON_SPI_MAX_BYTES; i++) {
> > 				u64 v = readq(p->register_base + OCTEON_SPI_DAT0(p) + (8 * i));
> > 				*rx_buf++ = (u8)v;
> > 			}
> > 		len -= OCTEON_SPI_MAX_BYTES;
> > 	}
> > 
> > 	for (i = 0; i < len; i++) {
> > 		u8 d;
> > 		if (tx_buf)
> > 			d = *tx_buf++;
> > 		else
> > 			d = 0;
> > 		writeq(d, p->register_base + OCTEON_SPI_DAT0(p) + (8 * i));
> > 	}
> > 
> > 	mpi_tx.u64 = 0;
> > 	mpi_tx.s.csid = spi->chip_select;
> > 	if (last_xfer)
> > 		mpi_tx.s.leavecs = xfer->cs_change;
> > 	else
> > 		mpi_tx.s.leavecs = !xfer->cs_change;
> > 	mpi_tx.s.txnum = tx_buf ? len : 0;
> > 	mpi_tx.s.totnum = len;
> > 	writeq(mpi_tx.u64, p->register_base + OCTEON_SPI_TX(p));
> > 
> > 	octeon_spi_wait_ready(p);
> > 	if (rx_buf)
> > 		for (i = 0; i < len; i++) {
> > 			u64 v = readq(p->register_base + OCTEON_SPI_DAT0(p) + (8 * i));
> > 			*rx_buf++ = (u8)v;
> > 		}
> 
> Personally I'd fold this into the while loop, as there's quite some code
> duplication. Of course your have to improve the "if (last_xfer)" a bit.

I've not written that code, just split it for shared arm64 & mips usage
and avoided re-writing it completely on purpose :) If it turns out that
we need to change this code I might consider making changes like this.

Adding David who might know more about this driver.

--Jan

^ permalink raw reply

* Re: MCP251x SPI CAN controller on Cavium ThunderX
From: Marc Kleine-Budde @ 2017-11-15 13:31 UTC (permalink / raw)
  To: Jan Glauber
  Cc: Mark Brown, Tim Harvey, linux-spi, linux-kernel@vger.kernel.org,
	Wolfgang Grandegger, linux-can
In-Reply-To: <36b04940-83a6-93a7-f7e1-d0acc8c135d9@pengutronix.de>


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

On 11/15/2017 01:40 PM, Marc Kleine-Budde wrote:
> mcp251x_spi_trans() is called with len=3,
> priv->spi_tx_buf and priv->spi_rx_buf point to previously allocared memory
> 
> priv->spi_tx_buf has been filled before calling mcp251x_spi_trans().

> #define OCTEON_SPI_MAX_BYTES 9

> static int octeon_spi_do_transfer(struct octeon_spi *p,
> 				  struct spi_message *msg,
> 				  struct spi_transfer *xfer,
> 				  bool last_xfer)
> {
> 	struct spi_device *spi = msg->spi;
> 	union cvmx_mpi_cfg mpi_cfg;
> 	union cvmx_mpi_tx mpi_tx;
> 	unsigned int clkdiv;
> 	int mode;
> 	bool cpha, cpol;
> 	const u8 *tx_buf;
> 	u8 *rx_buf;
> 	int len;
> 	int i;
> 
> 	mode = spi->mode;
> 	cpha = mode & SPI_CPHA;
> 	cpol = mode & SPI_CPOL;
> 
> 	clkdiv = p->sys_freq / (2 * xfer->speed_hz);
> 
> 	mpi_cfg.u64 = 0;
> 
> 	mpi_cfg.s.clkdiv = clkdiv;
> 	mpi_cfg.s.cshi = (mode & SPI_CS_HIGH) ? 1 : 0;
> 	mpi_cfg.s.lsbfirst = (mode & SPI_LSB_FIRST) ? 1 : 0;
> 	mpi_cfg.s.wireor = (mode & SPI_3WIRE) ? 1 : 0;
> 	mpi_cfg.s.idlelo = cpha != cpol;
> 	mpi_cfg.s.cslate = cpha ? 1 : 0;
> 	mpi_cfg.s.enable = 1;
> 
> 	if (spi->chip_select < 4)
> 		p->cs_enax |= 1ull << (12 + spi->chip_select);
> 	mpi_cfg.u64 |= p->cs_enax;
> 
> 	if (mpi_cfg.u64 != p->last_cfg) {
> 		p->last_cfg = mpi_cfg.u64;
> 		writeq(mpi_cfg.u64, p->register_base + OCTEON_SPI_CFG(p));
> 	}
> 	tx_buf = xfer->tx_buf;
> 	rx_buf = xfer->rx_buf;
> 	len = xfer->len;
> 	while (len > OCTEON_SPI_MAX_BYTES) {
> 		for (i = 0; i < OCTEON_SPI_MAX_BYTES; i++) {
> 			u8 d;
> 			if (tx_buf)
> 				d = *tx_buf++;
> 			else
> 				d = 0;
> 			writeq(d, p->register_base + OCTEON_SPI_DAT0(p) + (8 * i));
> 		}
> 		mpi_tx.u64 = 0;
> 		mpi_tx.s.csid = spi->chip_select;
> 		mpi_tx.s.leavecs = 1;
> 		mpi_tx.s.txnum = tx_buf ? OCTEON_SPI_MAX_BYTES : 0;

This looks fishy, OCTEON_SPI_MAX_BYTES is 9....

> 		mpi_tx.s.totnum = OCTEON_SPI_MAX_BYTES;
> 		writeq(mpi_tx.u64, p->register_base + OCTEON_SPI_TX(p));
> 
> 		octeon_spi_wait_ready(p);
> 		if (rx_buf)
> 			for (i = 0; i < OCTEON_SPI_MAX_BYTES; i++) {
> 				u64 v = readq(p->register_base + OCTEON_SPI_DAT0(p) + (8 * i));
> 				*rx_buf++ = (u8)v;
> 			}
> 		len -= OCTEON_SPI_MAX_BYTES;
> 	}
> 
> 	for (i = 0; i < len; i++) {
> 		u8 d;
> 		if (tx_buf)
> 			d = *tx_buf++;
> 		else
> 			d = 0;
> 		writeq(d, p->register_base + OCTEON_SPI_DAT0(p) + (8 * i));
> 	}
> 
> 	mpi_tx.u64 = 0;
> 	mpi_tx.s.csid = spi->chip_select;
> 	if (last_xfer)
> 		mpi_tx.s.leavecs = xfer->cs_change;
> 	else
> 		mpi_tx.s.leavecs = !xfer->cs_change;
> 	mpi_tx.s.txnum = tx_buf ? len : 0;
> 	mpi_tx.s.totnum = len;
> 	writeq(mpi_tx.u64, p->register_base + OCTEON_SPI_TX(p));
> 
> 	octeon_spi_wait_ready(p);
> 	if (rx_buf)
> 		for (i = 0; i < len; i++) {
> 			u64 v = readq(p->register_base + OCTEON_SPI_DAT0(p) + (8 * i));
> 			*rx_buf++ = (u8)v;
> 		}

Personally I'd fold this into the while loop, as there's quite some code
duplication. Of course your have to improve the "if (last_xfer)" a bit.

> 
> 	if (xfer->delay_usecs)
> 		udelay(xfer->delay_usecs);
> 
> 	return xfer->len;
> }

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: MCP251x SPI CAN controller on Cavium ThunderX
From: Marc Kleine-Budde @ 2017-11-15 12:40 UTC (permalink / raw)
  To: Jan Glauber
  Cc: Mark Brown, Tim Harvey, linux-spi, linux-kernel@vger.kernel.org,
	Wolfgang Grandegger, linux-can
In-Reply-To: <20171115120754.GC3011@hc>


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

On 11/15/2017 01:07 PM, Jan Glauber wrote:
> On Wed, Nov 15, 2017 at 11:54:20AM +0100, Marc Kleine-Budde wrote:
>> On 11/14/2017 01:02 PM, Mark Brown wrote:
>>> On Mon, Nov 13, 2017 at 01:17:42PM -0800, Tim Harvey wrote:
>>>
>>>> When a register is read from the mcp251x driver the
>>>> octeon_spi_do_transfer() gets a spi_message with a single spi_xfer of
>>>> len=3, a tx_buf, and an rx_buf which I believe is supposed to shift
>>>> out 3 bytes out MOSI and shift in 3 bytes from MISO where the last
>>>> byte shifted in would be the response.
>>>
>>> No, that will simultaneously transmit and recieve three bytes.
>>
>> That's what the driver supposed to do.
>>
>>> If you want to transmit two bytes and then recieve one byte you need
>>> two xfers, one with a len of 2 and a tx_buf, the other with a len of
>>> 1 and a rx_buf.
>> To read a register (mcp251x_read_reg()) the mcp251x does a 3 byte full
>> duplex transfer. The first byte send is the command (read register) the
>> second byte the register number the third byte is a dummy. The first 2
>> bytes received are ignored the 3rd byte is the register contents.
> 
> To support this full duplex transfer the Cavium SPI controller needs
> to know the receive lenght before setting up the transaction.
> 
> spi_transfer only includes the total length, so I don't see how this
> should work.

It's a standard 3 byte full duplex transfer. Three bytes are send while
three bytes are received.

> static int mcp251x_spi_trans(struct spi_device *spi, int len)
> {
> 	struct mcp251x_priv *priv = spi_get_drvdata(spi);
> 	struct spi_transfer t = {
> 		.tx_buf = priv->spi_tx_buf,
> 		.rx_buf = priv->spi_rx_buf,
> 		.len = len,
> 		.cs_change = 0,
> 	};
> 	struct spi_message m;
> 	int ret;
> 
> 	spi_message_init(&m);
> 
> 	if (mcp251x_enable_dma) {
> 		t.tx_dma = priv->spi_tx_dma;
> 		t.rx_dma = priv->spi_rx_dma;
> 		m.is_dma_mapped = 1;
> 	}
> 
> 	spi_message_add_tail(&t, &m);
> 
> 	ret = spi_sync(spi, &m);
> 	if (ret)
> 		dev_err(&spi->dev, "spi transfer failed: ret = %d\n", ret);
> 	return ret;
> }

mcp251x_spi_trans() is called with len=3,
priv->spi_tx_buf and priv->spi_rx_buf point to previously allocared memory

priv->spi_tx_buf has been filled before calling mcp251x_spi_trans().

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: MCP251x SPI CAN controller on Cavium ThunderX
From: Jan Glauber @ 2017-11-15 12:07 UTC (permalink / raw)
  To: Marc Kleine-Budde
  Cc: Mark Brown, Tim Harvey, linux-spi-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	Wolfgang Grandegger, linux-can
In-Reply-To: <bfa971bb-1217-ed86-d1d8-e353ecc506aa-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>

On Wed, Nov 15, 2017 at 11:54:20AM +0100, Marc Kleine-Budde wrote:
> On 11/14/2017 01:02 PM, Mark Brown wrote:
> > On Mon, Nov 13, 2017 at 01:17:42PM -0800, Tim Harvey wrote:
> > 
> >> When a register is read from the mcp251x driver the
> >> octeon_spi_do_transfer() gets a spi_message with a single spi_xfer of
> >> len=3, a tx_buf, and an rx_buf which I believe is supposed to shift
> >> out 3 bytes out MOSI and shift in 3 bytes from MISO where the last
> >> byte shifted in would be the response.
> > 
> > No, that will simultaneously transmit and recieve three bytes.
> 
> That's what the driver supposed to do.
> 
> > If you want to transmit two bytes and then recieve one byte you need
> > two xfers, one with a len of 2 and a tx_buf, the other with a len of
> > 1 and a rx_buf.
> To read a register (mcp251x_read_reg()) the mcp251x does a 3 byte full
> duplex transfer. The first byte send is the command (read register) the
> second byte the register number the third byte is a dummy. The first 2
> bytes received are ignored the 3rd byte is the register contents.

To support this full duplex transfer the Cavium SPI controller needs
to know the receive lenght before setting up the transaction.

spi_transfer only includes the total length, so I don't see how this
should work.

--Jan
--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Hello Dear...
From:  M,Shakour Rosarita @ 2017-11-15 11:33 UTC (permalink / raw)


Hello Dear...

I know that this message will come to you as a surprise. I hoped that
you will not expose or betray this trust and confident that I am about
to repose on you, my name is M, Shakour Rosarita. I am 19 years old
Girl, female, from Tartu Syria, (never married) 61 kg, white in
complexion, and I am currently living in the refugee camp here in
Abidjan Ivory Coast, My late beloved father M,Shakour Hassin was a
renowned businessman and owner of Natour Petrol Station in Syria, he
was killed in a stampede riot in Tartu, Syria.
When I got the news about my parents. I fled to a nearby country
Jordan before I joined a ferry to Africa and came to Abidjan capital
city Ivory Coast West Africa find safety here.
I came in 2015 to Abidjan and I now live in refugee camps here as
refugees are allowed freely to enter here without, My late father
deposited (US$6.200.000.00m) My late father kept the money at the bank
of Africa, I want you to help me transfer the money to your hand so
that you will help me bring me into your country for my continue
education.

I sent my pictures here for you to see. Who I am seriously looking for
a good-person in my life, so I want to hear from you soon and learn
more about you.

I am an open-minded and friendly girl to share a good time with you
and have fun and enjoy on the go, bird watching, the rest of our
lives. My Hobbies, tourism books, dance, music, soccer, tennis,
swimming and cinema.
I would just think about you, including your dose and doesn’t .I
believe we will do well together, and live like one family.
Thank you and God bless you, for you in your promise to help me here,
looking forward to your reply by the grace of God and have a good day.
I hope you send me your photos as well? I await your next reply in
faith please reply through my private email at
(mshakourrosarita22@gmail.com):
Thanks.
Ms Rosarita

^ permalink raw reply

* Re: MCP251x SPI CAN controller on Cavium ThunderX
From: Marc Kleine-Budde @ 2017-11-15 10:54 UTC (permalink / raw)
  To: Mark Brown, Tim Harvey
  Cc: Jan Glauber, linux-spi, linux-kernel@vger.kernel.org,
	Wolfgang Grandegger, linux-can
In-Reply-To: <20171114120207.xbee2cgsai4qka46@sirena.org.uk>


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

On 11/14/2017 01:02 PM, Mark Brown wrote:
> On Mon, Nov 13, 2017 at 01:17:42PM -0800, Tim Harvey wrote:
> 
>> When a register is read from the mcp251x driver the
>> octeon_spi_do_transfer() gets a spi_message with a single spi_xfer of
>> len=3, a tx_buf, and an rx_buf which I believe is supposed to shift
>> out 3 bytes out MOSI and shift in 3 bytes from MISO where the last
>> byte shifted in would be the response.
> 
> No, that will simultaneously transmit and recieve three bytes.

That's what the driver supposed to do.

> If you want to transmit two bytes and then recieve one byte you need
> two xfers, one with a len of 2 and a tx_buf, the other with a len of
> 1 and a rx_buf.
To read a register (mcp251x_read_reg()) the mcp251x does a 3 byte full
duplex transfer. The first byte send is the command (read register) the
second byte the register number the third byte is a dummy. The first 2
bytes received are ignored the 3rd byte is the register contents.

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

What about this:

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

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

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

Marc

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


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

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox