Devicetree
 help / color / mirror / Atom feed
* [PATCH 7/8] ARM: dts: imx7d: Add node for PCIe controller
From: Andrey Smirnov @ 2017-04-13 13:32 UTC (permalink / raw)
  To: Shawn Guo
  Cc: Andrey Smirnov, yurovsky, Sascha Hauer, Fabio Estevam,
	Rob Herring, Mark Rutland, Russell King, devicetree, linux-kernel,
	linux-arm-kernel
In-Reply-To: <20170413133242.5068-1-andrew.smirnov@gmail.com>

Cc: yurovsky@gmail.com
Cc: Sascha Hauer <kernel@pengutronix.de>
Cc: Fabio Estevam <fabio.estevam@nxp.com>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Russell King <linux@armlinux.org.uk>
Cc: devicetree@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-arm-kernel@lists.infradead.org
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
 arch/arm/boot/dts/imx7d.dtsi | 38 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/arch/arm/boot/dts/imx7d.dtsi b/arch/arm/boot/dts/imx7d.dtsi
index f6dee41..bbe23e4 100644
--- a/arch/arm/boot/dts/imx7d.dtsi
+++ b/arch/arm/boot/dts/imx7d.dtsi
@@ -42,6 +42,7 @@
  */
 
 #include "imx7s.dtsi"
+#include <dt-bindings/reset/imx7-reset.h>
 
 / {
 	cpus {
@@ -127,6 +128,43 @@
 		fsl,num-rx-queues=<3>;
 		status = "disabled";
 	};
+
+	pcie: pcie@0x33800000 {
+		compatible = "fsl,imx7d-pcie", "snps,dw-pcie";
+		reg = <0x33800000 0x4000>,
+		      <0x4ff00000 0x80000>;
+		reg-names = "dbi", "config";
+		#address-cells = <3>;
+		#size-cells = <2>;
+		device_type = "pci";
+		bus-range = <0x00 0xff>;
+		ranges = <0x81000000 0 0          0x4ff80000 0 0x00010000   /* downstream I/O */
+			  0x82000000 0 0x40000000 0x40000000 0 0x0ff00000>; /* non-prefetchable memory */
+		num-lanes = <1>;
+		interrupts = <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "msi";
+		#interrupt-cells = <1>;
+		interrupt-map-mask = <0 0 0 0x7>;
+		interrupt-map = <0 0 0 1 &intc GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0 0 2 &intc GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0 0 3 &intc GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0 0 4 &intc GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&clks IMX7D_PCIE_CTRL_ROOT_CLK>,
+			 <&clks IMX7D_PLL_ENET_MAIN_100M_CLK>,
+			 <&clks IMX7D_PCIE_PHY_ROOT_CLK>;
+		clock-names = "pcie", "pcie_bus", "pcie_phy";
+		assigned-clocks = <&clks IMX7D_PCIE_CTRL_ROOT_SRC>,
+				  <&clks IMX7D_PCIE_PHY_ROOT_SRC>;
+		assigned-clock-parents = <&clks IMX7D_PLL_ENET_MAIN_250M_CLK>,
+					 <&clks IMX7D_PLL_ENET_MAIN_100M_CLK>;
+
+		fsl,max-link-speed = <2>;
+		power-domains = <&pgc_pcie_phy>;
+		resets = <&src IMX7_RESET_PCIEPHY>,
+			 <&src IMX7_RESET_PCIE_CTRL_APPS_EN>;
+		reset-names = "pciephy", "apps";
+		status = "disabled";
+	};
 };
 
 &ca_funnel_ports {
-- 
2.9.3

^ permalink raw reply related

* [PATCH 6/8] ARM: dts: imx7d-sdb: Add GPIO expander node
From: Andrey Smirnov @ 2017-04-13 13:32 UTC (permalink / raw)
  To: Shawn Guo
  Cc: Andrey Smirnov, yurovsky, Sascha Hauer, Fabio Estevam,
	Rob Herring, Mark Rutland, Russell King, devicetree, linux-kernel,
	linux-arm-kernel
In-Reply-To: <20170413133242.5068-1-andrew.smirnov@gmail.com>

Add node for U38, a 74LV595PW serial-in shift register that acts as a
GPIO expander on the board.

Cc: yurovsky@gmail.com
Cc: Sascha Hauer <kernel@pengutronix.de>
Cc: Fabio Estevam <fabio.estevam@nxp.com>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Russell King <linux@armlinux.org.uk>
Cc: devicetree@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-arm-kernel@lists.infradead.org
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
 arch/arm/boot/dts/imx7d-sdb.dts | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/arch/arm/boot/dts/imx7d-sdb.dts b/arch/arm/boot/dts/imx7d-sdb.dts
index 5be01a1..e0ff276 100644
--- a/arch/arm/boot/dts/imx7d-sdb.dts
+++ b/arch/arm/boot/dts/imx7d-sdb.dts
@@ -52,6 +52,30 @@
 		reg = <0x80000000 0x80000000>;
 	};
 
+	spi4 {
+		compatible = "spi-gpio";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_spi1>;
+		status = "okay";
+		gpio-sck = <&gpio1 13 0>;
+		gpio-mosi = <&gpio1 9 0>;
+		cs-gpios = <&gpio1 12 0>;
+		num-chipselects = <1>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		gpio_spi: gpio_spi@0 {
+			compatible = "fairchild,74hc595";
+			gpio-controller;
+			#gpio-cells = <2>;
+			reg = <0>;
+			registers-number = <1>;
+			 /* Enable PERI_3V3, SENSOR_RST_B and HDMI_RST*/
+			registers-default = /bits/ 8 <0x74>;
+			spi-max-frequency = <100000>;
+		};
+	};
+
 	regulators {
 		compatible = "simple-bus";
 		#address-cells = <1>;
@@ -642,5 +666,13 @@
 		fsl,pins = <
 			MX7D_PAD_LPSR_GPIO1_IO01__PWM1_OUT		0x110b0
 		>;
+
+		pinctrl_spi1: spi1grp {
+			fsl,pins = <
+				MX7D_PAD_GPIO1_IO09__GPIO1_IO9	0x59
+				MX7D_PAD_GPIO1_IO12__GPIO1_IO12	0x59
+				MX7D_PAD_GPIO1_IO13__GPIO1_IO13	0x59
+			>;
+		};
 	};
 };
-- 
2.9.3

^ permalink raw reply related

* [PATCH 5/8] ARM: dts: imx7s: Mark 'gpr' compatible with i.MX6 variant
From: Andrey Smirnov @ 2017-04-13 13:32 UTC (permalink / raw)
  To: Shawn Guo
  Cc: Andrey Smirnov, yurovsky-Re5JQEeQqe8AvxtiuMwx3w, Sascha Hauer,
	Fabio Estevam, Rob Herring, Mark Rutland, Russell King,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <20170413133242.5068-1-andrew.smirnov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

List GPR block as compatible "fsl,imx6q-iomuxc-gpr" to support drivers
requesting it that way (PCIe driver is one example).

Cc: yurovsky-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org
Cc: Sascha Hauer <kernel-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
Cc: Fabio Estevam <fabio.estevam-3arQi8VN3Tc@public.gmane.org>
Cc: Rob Herring <robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Cc: Mark Rutland <mark.rutland-5wv7dgnIgG8@public.gmane.org>
Cc: Russell King <linux-I+IVW8TIWO2tmTQ+vhA3Yw@public.gmane.org>
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
Signed-off-by: Andrey Smirnov <andrew.smirnov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 arch/arm/boot/dts/imx7s.dtsi | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/imx7s.dtsi b/arch/arm/boot/dts/imx7s.dtsi
index 1a7058f..cc23478 100644
--- a/arch/arm/boot/dts/imx7s.dtsi
+++ b/arch/arm/boot/dts/imx7s.dtsi
@@ -491,7 +491,8 @@
 			};
 
 			gpr: iomuxc-gpr@30340000 {
-				compatible = "fsl,imx7d-iomuxc-gpr", "syscon";
+				compatible = "fsl,imx7d-iomuxc-gpr",
+					"fsl,imx6q-iomuxc-gpr", "syscon";
 				reg = <0x30340000 0x10000>;
 			};
 
-- 
2.9.3

--
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 4/8] ARM: dts: imx7s: Add node for GPC
From: Andrey Smirnov @ 2017-04-13 13:32 UTC (permalink / raw)
  To: Shawn Guo
  Cc: Andrey Smirnov, yurovsky, Sascha Hauer, Fabio Estevam,
	Rob Herring, Mark Rutland, Russell King, devicetree, linux-kernel,
	linux-arm-kernel
In-Reply-To: <20170413133242.5068-1-andrew.smirnov@gmail.com>

Add node for GPC and specify as a parent interrupt controller for SoC bus.

Cc: yurovsky@gmail.com
Cc: Sascha Hauer <kernel@pengutronix.de>
Cc: Fabio Estevam <fabio.estevam@nxp.com>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Russell King <linux@armlinux.org.uk>
Cc: devicetree@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-arm-kernel@lists.infradead.org
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
 arch/arm/boot/dts/imx7s.dtsi | 27 ++++++++++++++++++++++++++-
 1 file changed, 26 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/imx7s.dtsi b/arch/arm/boot/dts/imx7s.dtsi
index 8fee299..1a7058f 100644
--- a/arch/arm/boot/dts/imx7s.dtsi
+++ b/arch/arm/boot/dts/imx7s.dtsi
@@ -42,6 +42,7 @@
  */
 
 #include <dt-bindings/clock/imx7d-clock.h>
+#include <dt-bindings/power/imx7-power.h>
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/input/input.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
@@ -119,7 +120,7 @@
 		#address-cells = <1>;
 		#size-cells = <1>;
 		compatible = "simple-bus";
-		interrupt-parent = <&intc>;
+		interrupt-parent = <&gpc>;
 		ranges;
 
 		funnel@30041000 {
@@ -301,6 +302,7 @@
 			interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
 			#interrupt-cells = <3>;
 			interrupt-controller;
+			interrupt-parent = <&intc>;
 			reg = <0x31001000 0x1000>,
 			      <0x31002000 0x2000>,
 			      <0x31004000 0x2000>,
@@ -309,6 +311,7 @@
 
 		timer {
 			compatible = "arm,armv7-timer";
+			interrupt-parent = <&intc>;
 			interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
 				     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
 				     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
@@ -564,6 +567,28 @@
 				interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
 				#reset-cells = <1>;
 			};
+
+			gpc: gpc@303a0000 {
+				compatible = "fsl,imx7d-gpc";
+				reg = <0x303a0000 0x10000>;
+				interrupt-controller;
+				interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>;
+				#interrupt-cells = <3>;
+				interrupt-parent = <&intc>;
+				#power-domain-cells = <1>;
+
+				pgc {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					pgc_pcie_phy: pgc-pcie-phy-domain {
+						#power-domain-cells = <0>;
+
+						reg = <IMX7_POWER_DOMAIN_PCIE_PHY>;
+						power-supply = <&reg_1p0d>;
+					};
+				};
+			};
 		};
 
 		aips2: aips-bus@30400000 {
-- 
2.9.3

^ permalink raw reply related

* [PATCH 3/8] ARM: dts: imx7s: Adjust anatop-enable-bit for 'reg_1p0d'
From: Andrey Smirnov @ 2017-04-13 13:32 UTC (permalink / raw)
  To: Shawn Guo
  Cc: Andrey Smirnov, yurovsky-Re5JQEeQqe8AvxtiuMwx3w, Sascha Hauer,
	Fabio Estevam, Rob Herring, Mark Rutland, Russell King,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <20170413133242.5068-1-andrew.smirnov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

In PMU_REG_1P0Dn ENABLE_LINREG is bit 0. Bit 31 is called OVERRIDE and
it serves the function of granting permission to GPC IP block to alter
various bit-fields of the register. The reason why this property, that
trickeld here from Freescale BSP, is set to 31 is because in the code
it came from it is used in conjunction with a notifier handler for
REGULATOR_EVENT_PRE_DO_ENABLE and REGULATOR_EVENT_PRE_DO_DISABLE
events (not found in upstream kernel) that triggers GPC to start
manipulating aforementioned other bitfields.

Since:
	a) none of the aforementioned machinery is implemented by
	   upstream
	b) using 'anatop-enable-bit' in that capacity is a bit of a
	   semantic stretch

simplify the situation by setting the value of 'anatop-enable-bit' to
point to ENABLE_LINREG (same as i.MX6).

Cc: yurovsky-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org
Cc: Sascha Hauer <kernel-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
Cc: Fabio Estevam <fabio.estevam-3arQi8VN3Tc@public.gmane.org>
Cc: Rob Herring <robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Cc: Mark Rutland <mark.rutland-5wv7dgnIgG8@public.gmane.org>
Cc: Russell King <linux-I+IVW8TIWO2tmTQ+vhA3Yw@public.gmane.org>
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
Signed-off-by: Andrey Smirnov <andrew.smirnov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 arch/arm/boot/dts/imx7s.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/imx7s.dtsi b/arch/arm/boot/dts/imx7s.dtsi
index 22c9788..8fee299 100644
--- a/arch/arm/boot/dts/imx7s.dtsi
+++ b/arch/arm/boot/dts/imx7s.dtsi
@@ -516,7 +516,7 @@
 					anatop-min-bit-val = <8>;
 					anatop-min-voltage = <800000>;
 					anatop-max-voltage = <1200000>;
-					anatop-enable-bit = <31>;
+					anatop-enable-bit = <0>;
 				};
 			};
 
-- 
2.9.3

--
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/8] ARM: dts: imx6: Specify 'anatop-enable-bit' where appropriate
From: Andrey Smirnov @ 2017-04-13 13:32 UTC (permalink / raw)
  To: Shawn Guo
  Cc: Mark Rutland, devicetree, Andrey Smirnov, Russell King,
	linux-kernel, Rob Herring, Sascha Hauer, Fabio Estevam,
	linux-arm-kernel, yurovsky
In-Reply-To: <20170413133242.5068-1-andrew.smirnov@gmail.com>

ENABLE_LINREG bit is implemented by 3P0, 1P1 and 2P5 regulators on
i.MX6. This property is present in similar code in Fresscale BSP and
made its way upstream in imx6ul.dtsi, so this patch adds this property
to the rest of i.MX6 family for completness.

Cc: yurovsky@gmail.com
Cc: Sascha Hauer <kernel@pengutronix.de>
Cc: Fabio Estevam <fabio.estevam@nxp.com>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Russell King <linux@armlinux.org.uk>
Cc: devicetree@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-arm-kernel@lists.infradead.org
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
 arch/arm/boot/dts/imx6qdl.dtsi | 3 +++
 arch/arm/boot/dts/imx6sl.dtsi  | 3 +++
 arch/arm/boot/dts/imx6sx.dtsi  | 3 +++
 3 files changed, 9 insertions(+)

diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi
index e426faa..0576ef6 100644
--- a/arch/arm/boot/dts/imx6qdl.dtsi
+++ b/arch/arm/boot/dts/imx6qdl.dtsi
@@ -644,6 +644,7 @@
 					anatop-min-bit-val = <4>;
 					anatop-min-voltage = <800000>;
 					anatop-max-voltage = <1375000>;
+					anatop-enable-bit = <0>;
 				};
 
 				regulator-3p0 {
@@ -658,6 +659,7 @@
 					anatop-min-bit-val = <0>;
 					anatop-min-voltage = <2625000>;
 					anatop-max-voltage = <3400000>;
+					anatop-enable-bit = <0>;
 				};
 
 				regulator-2p5 {
@@ -672,6 +674,7 @@
 					anatop-min-bit-val = <0>;
 					anatop-min-voltage = <2100000>;
 					anatop-max-voltage = <2875000>;
+					anatop-enable-bit = <0>;
 				};
 
 				reg_arm: regulator-vddcore {
diff --git a/arch/arm/boot/dts/imx6sl.dtsi b/arch/arm/boot/dts/imx6sl.dtsi
index cc9572e..3243af4 100644
--- a/arch/arm/boot/dts/imx6sl.dtsi
+++ b/arch/arm/boot/dts/imx6sl.dtsi
@@ -530,6 +530,7 @@
 					anatop-min-bit-val = <4>;
 					anatop-min-voltage = <800000>;
 					anatop-max-voltage = <1375000>;
+					anatop-enable-bit = <0>;
 				};
 
 				regulator-3p0 {
@@ -544,6 +545,7 @@
 					anatop-min-bit-val = <0>;
 					anatop-min-voltage = <2625000>;
 					anatop-max-voltage = <3400000>;
+					anatop-enable-bit = <0>;
 				};
 
 				regulator-2p5 {
@@ -558,6 +560,7 @@
 					anatop-min-bit-val = <0>;
 					anatop-min-voltage = <2100000>;
 					anatop-max-voltage = <2850000>;
+					anatop-enable-bit = <0>;
 				};
 
 				reg_arm: regulator-vddcore {
diff --git a/arch/arm/boot/dts/imx6sx.dtsi b/arch/arm/boot/dts/imx6sx.dtsi
index 3f1416b..f16b9df 100644
--- a/arch/arm/boot/dts/imx6sx.dtsi
+++ b/arch/arm/boot/dts/imx6sx.dtsi
@@ -587,6 +587,7 @@
 					anatop-min-bit-val = <4>;
 					anatop-min-voltage = <800000>;
 					anatop-max-voltage = <1375000>;
+					anatop-enable-bit = <0>;
 				};
 
 				regulator-3p0 {
@@ -601,6 +602,7 @@
 					anatop-min-bit-val = <0>;
 					anatop-min-voltage = <2625000>;
 					anatop-max-voltage = <3400000>;
+					anatop-enable-bit = <0>;
 				};
 
 				regulator-2p5 {
@@ -615,6 +617,7 @@
 					anatop-min-bit-val = <0>;
 					anatop-min-voltage = <2100000>;
 					anatop-max-voltage = <2875000>;
+					anatop-enable-bit = <0>;
 				};
 
 				reg_arm: regulator-vddcore {
-- 
2.9.3

^ permalink raw reply related

* [PATCH 1/8] Revert "ARM: dts: imx: Remove unexistant property"
From: Andrey Smirnov @ 2017-04-13 13:32 UTC (permalink / raw)
  To: Shawn Guo
  Cc: Andrey Smirnov, yurovsky-Re5JQEeQqe8AvxtiuMwx3w, Sascha Hauer,
	Fabio Estevam, Rob Herring, Mark Rutland, Russell King,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <20170413133242.5068-1-andrew.smirnov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

Commit ca7734a ("regulator: anatop: Add support for
"anatop-enable-bit"") added code to support this particular binding
and 'anatop-enable-bit' is no longer an unused property.

This reverts commit 27958ccdf29e9971732e02494b48be54b0691269.

Cc: yurovsky-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org
Cc: Sascha Hauer <kernel-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
Cc: Fabio Estevam <fabio.estevam-3arQi8VN3Tc@public.gmane.org>
Cc: Rob Herring <robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Cc: Mark Rutland <mark.rutland-5wv7dgnIgG8@public.gmane.org>
Cc: Russell King <linux-I+IVW8TIWO2tmTQ+vhA3Yw@public.gmane.org>
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
Signed-off-by: Andrey Smirnov <andrew.smirnov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 arch/arm/boot/dts/imx6ul.dtsi | 1 +
 arch/arm/boot/dts/imx7s.dtsi  | 1 +
 2 files changed, 2 insertions(+)

diff --git a/arch/arm/boot/dts/imx6ul.dtsi b/arch/arm/boot/dts/imx6ul.dtsi
index b9d7d2d..6da2b77 100644
--- a/arch/arm/boot/dts/imx6ul.dtsi
+++ b/arch/arm/boot/dts/imx6ul.dtsi
@@ -542,6 +542,7 @@
 					anatop-min-bit-val = <0>;
 					anatop-min-voltage = <2625000>;
 					anatop-max-voltage = <3400000>;
+					anatop-enable-bit = <0>;
 				};
 
 				reg_arm: regulator-vddcore {
diff --git a/arch/arm/boot/dts/imx7s.dtsi b/arch/arm/boot/dts/imx7s.dtsi
index c4f12fd..22c9788 100644
--- a/arch/arm/boot/dts/imx7s.dtsi
+++ b/arch/arm/boot/dts/imx7s.dtsi
@@ -516,6 +516,7 @@
 					anatop-min-bit-val = <8>;
 					anatop-min-voltage = <800000>;
 					anatop-max-voltage = <1200000>;
+					anatop-enable-bit = <31>;
 				};
 			};
 
-- 
2.9.3

--
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 0/8] i.MX7 PCIe related device tree changes
From: Andrey Smirnov @ 2017-04-13 13:32 UTC (permalink / raw)
  To: Shawn Guo
  Cc: Andrey Smirnov, yurovsky, Sascha Hauer, Fabio Estevam,
	Rob Herring, Mark Rutland, Russell King, devicetree, linux-kernel,
	linux-arm-kernel

Shawn, everyone:

This series includes changes made to device-tree in order to support
PCIe on i.MX7 platform. They include:

     - Bringing 'anatop-enable-bit' property of ANATOP regulators back
       and extending it to all of the HW it is applicable to

     - Adding GPCv2 node for i.MX7 (which was missing, despite the
       irqchip driver for it being in the tree for quite some time)

     - Adding a PCIe node for i.MX7

     - Adding GPIO expander used by PCIe and enabling PCIe node from
       above on i.MX7 based Sabre board

As usual, feedback is welcome.

Thanks,
Andrey Smrinov

Andrey Smirnov (8):
  Revert "ARM: dts: imx: Remove unexistant property"
  ARM: dts: imx6: Specify 'anatop-enable-bit' where appropriate
  ARM: dts: imx7s: Adjust anatop-enable-bit for 'reg_1p0d'
  ARM: dts: imx7s: Add node for GPC
  ARM: dts: imx7s: Mark 'gpr' compatible with i.MX6 variant
  ARM: dts: imx7d-sdb: Add GPIO expander node
  ARM: dts: imx7d: Add node for PCIe controller
  ARM: dts: imx7d-sdb: Enable PCIe peripheral

 arch/arm/boot/dts/imx6qdl.dtsi  |  3 +++
 arch/arm/boot/dts/imx6sl.dtsi   |  3 +++
 arch/arm/boot/dts/imx6sx.dtsi   |  3 +++
 arch/arm/boot/dts/imx6ul.dtsi   |  1 +
 arch/arm/boot/dts/imx7d-sdb.dts | 39 +++++++++++++++++++++++++++++++++++++++
 arch/arm/boot/dts/imx7d.dtsi    | 38 ++++++++++++++++++++++++++++++++++++++
 arch/arm/boot/dts/imx7s.dtsi    | 31 +++++++++++++++++++++++++++++--
 7 files changed, 116 insertions(+), 2 deletions(-)

-- 
2.9.3

^ permalink raw reply

* Re: [PATCH 1/2] mfd: arizona: Add GPIO maintain state flag
From: Charles Keepax @ 2017-04-13 13:07 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Richard Fitzgerald, Rob Herring, Lee Jones, Alexandre Courbot,
	Mark Rutland, linux-gpio-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	open list:WOLFSON MICROELECTRONICS DRIVERS
In-Reply-To: <CACRpkdYAgd+ovH5x+GpbqPqGNG8W=t3A_g1rpY6tha2=FPsfOA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>

On Thu, Apr 13, 2017 at 02:48:45PM +0200, Linus Walleij wrote:
> On Thu, Apr 13, 2017 at 2:21 PM, Richard Fitzgerald
> <rf-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org> wrote:
> > On Thu, 2017-04-13 at 14:14 +0200, Linus Walleij wrote:
> >> On Thu, Apr 13, 2017 at 11:15 AM, Charles Keepax
> >> <ckeepax-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org> wrote:
> >> > On Tue, Apr 11, 2017 at 10:34:27AM +0100, Richard Fitzgerald wrote:
> >>
> >> >> 3) The codec only has to be kept awake while any such GPIO is actually
> >> >> in use. See (2)
> >> >
> >> > Yeah option 3 is the primary issue here, we only want to keep the
> >> > CODEC enabled whilst specific GPIOs are in use. As GPIOs can be
> >> > dynamically requested/released by things in the kernel we want to
> >> > know which GPIOs require the CODEC to be kept alive. Also in the
> >> > future one might be tempted to add maintain whilst high and
> >> > maintain whilst low options for lines with pulls on them to
> >> > further optimise power.
> >>
> >> Why does this have to be encoded as information in the device
> >> tree? Isn't it better to use a static table in the driver?
> >>
> >> I don't see what use system integrators and others playing
> >> around with the device tree has of this, it will just be confusing
> >> to them if it is a chip-internal detail.
> >>
> >
> > They are GPIOs for connecting to external hardware, we don't know what
> > people are going to connect them to so they have to tell us how they
> > need them to behave.
> 
> Aha it is a consumer configuration thing, then I see it.
> 
> I think it seems a bit odd that it is assumed that the default is that
> we should *not* preserve the GPIO output value if we go to sleep.
> Should the flag be inverted?
> 

I agree that is a bit odd, my thinking was keeping the behaviour
the same for existing systems. But it only introduces a power
regression perhaps it is ok to require people to update their DT
to avoid that?

> Also, why can't we just use a generic flag for this, it seems very
> very generic.
> 
> Look in:
> include/dt-bindings/gpio/gpio.h
> 
> Is there any reasons why we can't have:
> /* Bit 3 express GPIO suspend/resume persistance in low power mode */
> #define GPIO_MUST_KEEP_VALUE 0
> #define GPIO_MAY_LOOSE_VALUE_DURING_SLEEP 8
> 
> Yeah it's talkative but informative. This way you can mark up lines
> that are OK to loose their value during low-power/sleep using
> just (new) standard bindings that can be reused by others,
> also optionally making it possible for the gpiolib core to take action
> on these properties if need be.
> 

I certainly have no objections to making this a core feature if
you are comfortable with that. I will have a look at what that
would look like.

Thanks,
Charles
--
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

* Re: [PATCH RFC 0/5] *** SPI Slave mode support ***
From: Mark Brown @ 2017-04-13 12:59 UTC (permalink / raw)
  To: jiada_wang-nmGgyN9QBj3QT0dZR+AlfA
  Cc: robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
	shawnguo-DgEjT+Ai2ygdnm+yROfE0A, kernel-bIcnvbaLZ9MEGnE8C9+IrQ,
	fabio.estevam-3arQi8VN3Tc, linux-spi-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Geert Uytterhoeven
In-Reply-To: <1492085644-4195-1-git-send-email-jiada_wang-nmGgyN9QBj3QT0dZR+AlfA@public.gmane.org>

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

On Thu, Apr 13, 2017 at 05:13:59AM -0700, jiada_wang-nmGgyN9QBj3QT0dZR+AlfA@public.gmane.org wrote:
> From: Jiada Wang <jiada_wang-nmGgyN9QBj3QT0dZR+AlfA@public.gmane.org>
> 
> v1:
>   add Slave mode support in SPI core
>   spidev create slave device when SPI controller work in slave mode
>   spi-imx support to work in slave mode

Adding Geert who also had a series doing this in progress that was
getting very near to being merged.

> 
> Jiada Wang (5):
>   spi: core: add support to work in Slave mode
>   spi: spidev: use different name for SPI controller slave mode device
>   spi: imx: add selection for iMX53 and iMX6 controller
>   ARM: dts: imx: change compatiblity for SPI controllers on imx53 later
>     soc
>   spi: imx: Add support for SPI Slave mode for imx53 and imx6 chips
> 
>  Documentation/devicetree/bindings/spi/spi-bus.txt |  27 ++-
>  Documentation/spi/spi-summary                     |  19 +-
>  arch/arm/boot/dts/imx53.dtsi                      |   4 +-
>  arch/arm/boot/dts/imx6q.dtsi                      |   2 +-
>  arch/arm/boot/dts/imx6qdl.dtsi                    |   8 +-
>  arch/arm/boot/dts/imx6sl.dtsi                     |   8 +-
>  arch/arm/boot/dts/imx6sx.dtsi                     |   8 +-
>  arch/arm/boot/dts/imx6ul.dtsi                     |   8 +-
>  drivers/spi/Kconfig                               |  14 +-
>  drivers/spi/spi-imx.c                             | 216 ++++++++++++++++++++--
>  drivers/spi/spi.c                                 |  23 ++-
>  drivers/spi/spidev.c                              |  15 +-
>  include/linux/spi/spi.h                           |  15 ++
>  13 files changed, 310 insertions(+), 57 deletions(-)
> 
> -- 
> 2.7.4
> 
> 

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

^ permalink raw reply

* Re: [PATCH 1/2] mfd: arizona: Add GPIO maintain state flag
From: Linus Walleij @ 2017-04-13 12:48 UTC (permalink / raw)
  To: Richard Fitzgerald
  Cc: Charles Keepax, Rob Herring, Lee Jones, Alexandre Courbot,
	Mark Rutland, linux-gpio@vger.kernel.org,
	devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
	open list:WOLFSON MICROELECTRONICS DRIVERS
In-Reply-To: <1492086093.4826.25.camel@rf-debian.wolfsonmicro.main>

On Thu, Apr 13, 2017 at 2:21 PM, Richard Fitzgerald
<rf@opensource.wolfsonmicro.com> wrote:
> On Thu, 2017-04-13 at 14:14 +0200, Linus Walleij wrote:
>> On Thu, Apr 13, 2017 at 11:15 AM, Charles Keepax
>> <ckeepax@opensource.wolfsonmicro.com> wrote:
>> > On Tue, Apr 11, 2017 at 10:34:27AM +0100, Richard Fitzgerald wrote:
>>
>> >> 3) The codec only has to be kept awake while any such GPIO is actually
>> >> in use. See (2)
>> >
>> > Yeah option 3 is the primary issue here, we only want to keep the
>> > CODEC enabled whilst specific GPIOs are in use. As GPIOs can be
>> > dynamically requested/released by things in the kernel we want to
>> > know which GPIOs require the CODEC to be kept alive. Also in the
>> > future one might be tempted to add maintain whilst high and
>> > maintain whilst low options for lines with pulls on them to
>> > further optimise power.
>>
>> Why does this have to be encoded as information in the device
>> tree? Isn't it better to use a static table in the driver?
>>
>> I don't see what use system integrators and others playing
>> around with the device tree has of this, it will just be confusing
>> to them if it is a chip-internal detail.
>>
>
> They are GPIOs for connecting to external hardware, we don't know what
> people are going to connect them to so they have to tell us how they
> need them to behave.

Aha it is a consumer configuration thing, then I see it.

I think it seems a bit odd that it is assumed that the default is that
we should *not* preserve the GPIO output value if we go to sleep.
Should the flag be inverted?

Also, why can't we just use a generic flag for this, it seems very
very generic.

Look in:
include/dt-bindings/gpio/gpio.h

Is there any reasons why we can't have:
/* Bit 3 express GPIO suspend/resume persistance in low power mode */
#define GPIO_MUST_KEEP_VALUE 0
#define GPIO_MAY_LOOSE_VALUE_DURING_SLEEP 8

Yeah it's talkative but informative. This way you can mark up lines
that are OK to loose their value during low-power/sleep using
just (new) standard bindings that can be reused by others,
also optionally making it possible for the gpiolib core to take action
on these properties if need be.

Yours,
Linus Walleij

^ permalink raw reply

* Re: [PATCH 1/2] mfd: arizona: Add GPIO maintain state flag
From: Richard Fitzgerald @ 2017-04-13 12:21 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Charles Keepax, Rob Herring, Lee Jones, Alexandre Courbot,
	Mark Rutland, linux-gpio-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	open list:WOLFSON MICROELECTRONICS DRIVERS
In-Reply-To: <CACRpkdZ6PBv72BCn1bXsvhcHD2+dsCdh=3F3Vnnm7AWZqyWrig-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>

On Thu, 2017-04-13 at 14:14 +0200, Linus Walleij wrote:
> On Thu, Apr 13, 2017 at 11:15 AM, Charles Keepax
> <ckeepax-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org> wrote:
> > On Tue, Apr 11, 2017 at 10:34:27AM +0100, Richard Fitzgerald wrote:
> 
> >> 3) The codec only has to be kept awake while any such GPIO is actually
> >> in use. See (2)
> >
> > Yeah option 3 is the primary issue here, we only want to keep the
> > CODEC enabled whilst specific GPIOs are in use. As GPIOs can be
> > dynamically requested/released by things in the kernel we want to
> > know which GPIOs require the CODEC to be kept alive. Also in the
> > future one might be tempted to add maintain whilst high and
> > maintain whilst low options for lines with pulls on them to
> > further optimise power.
> 
> Why does this have to be encoded as information in the device
> tree? Isn't it better to use a static table in the driver?
> 
> I don't see what use system integrators and others playing
> around with the device tree has of this, it will just be confusing
> to them if it is a chip-internal detail.
> 

They are GPIOs for connecting to external hardware, we don't know what
people are going to connect them to so they have to tell us how they
need them to behave.

> Yours,
> Linus Walleij


--
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

* Re: [PATCH 1/2] mfd: arizona: Add GPIO maintain state flag
From: Linus Walleij @ 2017-04-13 12:14 UTC (permalink / raw)
  To: Charles Keepax
  Cc: Richard Fitzgerald, Rob Herring, Lee Jones, Alexandre Courbot,
	Mark Rutland, linux-gpio-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	open list:WOLFSON MICROELECTRONICS DRIVERS
In-Reply-To: <20170413091513.GA1878-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>

On Thu, Apr 13, 2017 at 11:15 AM, Charles Keepax
<ckeepax-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org> wrote:
> On Tue, Apr 11, 2017 at 10:34:27AM +0100, Richard Fitzgerald wrote:

>> 3) The codec only has to be kept awake while any such GPIO is actually
>> in use. See (2)
>
> Yeah option 3 is the primary issue here, we only want to keep the
> CODEC enabled whilst specific GPIOs are in use. As GPIOs can be
> dynamically requested/released by things in the kernel we want to
> know which GPIOs require the CODEC to be kept alive. Also in the
> future one might be tempted to add maintain whilst high and
> maintain whilst low options for lines with pulls on them to
> further optimise power.

Why does this have to be encoded as information in the device
tree? Isn't it better to use a static table in the driver?

I don't see what use system integrators and others playing
around with the device tree has of this, it will just be confusing
to them if it is a chip-internal detail.

Yours,
Linus Walleij
--
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

* [PATCH RFC 5/5] spi: imx: Add support for SPI Slave mode for imx53 and imx6 chips
From: jiada_wang @ 2017-04-13 12:14 UTC (permalink / raw)
  To: broonie, robh+dt, mark.rutland, shawnguo, kernel, fabio.estevam
  Cc: linux-spi, devicetree, linux-kernel, linux-arm-kernel, Jiada Wang
In-Reply-To: <1492085644-4195-1-git-send-email-jiada_wang@mentor.com>

From: Jiada Wang <jiada_wang@mentor.com>

Previously i.MX SPI controller only works in Master mode.
This patch adds support to work also in Slave mode.

Currently SPI Slave mode support patch has the following limitations:
1. The stale data in RXFIFO will be dropped when the Slave does any new
   transfer.
2. One transfer can be finished only after all transfer->len data been
   transferred to master device
3. Slave device only accepts transfer->len data. Any data longer than this
   from master device will be dropped. Any data shorter than this from
   master will cause SPI to stuck due to mentioned HW limitation 2.
4. Only PIO transfer is supported in Slave mode.

Following HW limitation applies:
1.  ECSPI has a HW issue when works in Slave mode, after 64
    words written to TXFIFO, even TXFIFO becomes empty,
    ECSPI_TXDATA keeps shift out the last word data,
    so we have to disable ECSPI when in slave mode after the
    transfer completes
2.  Due to Freescale errata ERR003775 "eCSPI: Burst completion by Chip
    Select (SS) signal in Slave mode is not functional" burst size must
    be set exactly to the size of the transfer. This limit SPI transaction
    with maximum 2^12 bits.

Signed-off-by: Jiada Wang <jiada_wang@mentor.com>
---
 drivers/spi/spi-imx.c | 173 ++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 159 insertions(+), 14 deletions(-)

diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c
index b2323b9..f6e1baa 100644
--- a/drivers/spi/spi-imx.c
+++ b/drivers/spi/spi-imx.c
@@ -53,9 +53,13 @@
 /* generic defines to abstract from the different register layouts */
 #define MXC_INT_RR	(1 << 0) /* Receive data ready interrupt */
 #define MXC_INT_TE	(1 << 1) /* Transmit FIFO empty interrupt */
+#define MXC_INT_RDR	BIT(4) /* Receive date threshold interrupt */
 
 /* The maximum  bytes that a sdma BD can transfer.*/
 #define MAX_SDMA_BD_BYTES  (1 << 15)
+/* The maximum bytes that IMX53_ECSPI can transfer in slave mode.*/
+#define MX53_MAX_TRANSFER_BYTES		512
+
 struct spi_imx_config {
 	unsigned int speed_hz;
 	unsigned int bpw;
@@ -79,6 +83,7 @@ struct spi_imx_devtype_data {
 	void (*trigger)(struct spi_imx_data *);
 	int (*rx_available)(struct spi_imx_data *);
 	void (*reset)(struct spi_imx_data *);
+	void (*disable)(struct spi_imx_data *);
 	enum spi_imx_devtype devtype;
 };
 
@@ -104,6 +109,10 @@ struct spi_imx_data {
 	const void *tx_buf;
 	unsigned int txfifo; /* number of words pushed in tx FIFO */
 
+	/* Slave mode */
+	unsigned int slave_mode;
+	unsigned int slave_burst;
+
 	/* DMA */
 	bool usedma;
 	u32 wml;
@@ -156,6 +165,19 @@ static inline bool spi_imx_has_dmamode(struct spi_imx_data *d)
 	}
 }
 
+static bool spi_imx_has_slavemode(struct spi_master *master)
+{
+	struct spi_imx_data *spi_imx = spi_master_get_devdata(master);
+
+	switch (spi_imx->devtype_data->devtype) {
+	case IMX51_ECSPI:
+	case IMX53_ECSPI:
+		return true;
+	default:
+		return false;
+	}
+}
+
 #define MXC_SPI_BUF_RX(type)						\
 static void spi_imx_buf_rx_##type(struct spi_imx_data *spi_imx)		\
 {									\
@@ -285,6 +307,7 @@ static bool spi_imx_can_dma(struct spi_master *master, struct spi_device *spi,
 #define MX51_ECSPI_INT		0x10
 #define MX51_ECSPI_INT_TEEN		(1 <<  0)
 #define MX51_ECSPI_INT_RREN		(1 <<  3)
+#define MX51_ECSPI_INT_RDREN		(1 <<  4)
 
 #define MX51_ECSPI_DMA      0x14
 #define MX51_ECSPI_DMA_TX_WML(wml)	((wml) & 0x3f)
@@ -301,6 +324,51 @@ static bool spi_imx_can_dma(struct spi_master *master, struct spi_device *spi,
 #define MX51_ECSPI_TESTREG	0x20
 #define MX51_ECSPI_TESTREG_LBC	BIT(31)
 
+static void mx53_ecspi_rx_slave(struct spi_imx_data *spi_imx)
+{
+	u32 val = be32_to_cpu(readl(spi_imx->base + MXC_CSPIRXDATA));
+
+	if (spi_imx->rx_buf) {
+		int shift = spi_imx->slave_burst % sizeof(val);
+
+		if (shift) {
+			memcpy(spi_imx->rx_buf,
+			       ((u8 *)&val) + sizeof(val) - shift, shift);
+		} else {
+			*((u32 *)spi_imx->rx_buf) = val;
+			shift = sizeof(val);
+		}
+
+		spi_imx->rx_buf += shift;
+		spi_imx->slave_burst -= shift;
+	}
+}
+
+static void mx53_ecspi_tx_slave(struct spi_imx_data *spi_imx)
+{
+	u32 val = 0;
+	int shift = spi_imx->count % sizeof(val);
+
+	if (spi_imx->tx_buf) {
+		if (shift) {
+			memcpy(((u8 *)&val) + sizeof(val) - shift,
+			       spi_imx->tx_buf, shift);
+		} else {
+			val = *((u32 *)spi_imx->tx_buf);
+			shift = sizeof(val);
+		}
+		val = cpu_to_be32(val);
+		spi_imx->tx_buf += shift;
+	}
+
+	if (!shift)
+		shift = sizeof(val);
+
+	spi_imx->count -= shift;
+
+	writel(val, spi_imx->base + MXC_CSPITXDATA);
+}
+
 /* MX51 eCSPI */
 static unsigned int mx51_ecspi_clkdiv(struct spi_imx_data *spi_imx,
 				      unsigned int fspi, unsigned int *fres)
@@ -350,6 +418,9 @@ static void mx51_ecspi_intctrl(struct spi_imx_data *spi_imx, int enable)
 	if (enable & MXC_INT_RR)
 		val |= MX51_ECSPI_INT_RREN;
 
+	if (enable & MXC_INT_RDR)
+		val |= MX51_ECSPI_INT_RDREN;
+
 	writel(val, spi_imx->base + MX51_ECSPI_INT);
 }
 
@@ -362,6 +433,15 @@ static void mx51_ecspi_trigger(struct spi_imx_data *spi_imx)
 	writel(reg, spi_imx->base + MX51_ECSPI_CTRL);
 }
 
+static void __maybe_unused mx51_ecspi_disable(struct spi_imx_data *spi_imx)
+{
+	u32 ctrl;
+
+	ctrl = readl(spi_imx->base + MX51_ECSPI_CTRL);
+	ctrl &= ~MX51_ECSPI_CTRL_ENABLE;
+	writel(ctrl, spi_imx->base + MX51_ECSPI_CTRL);
+}
+
 static int mx51_ecspi_config(struct spi_device *spi,
 			     struct spi_imx_config *config)
 {
@@ -370,14 +450,13 @@ static int mx51_ecspi_config(struct spi_device *spi,
 	u32 clk = config->speed_hz, delay, reg;
 	u32 cfg = readl(spi_imx->base + MX51_ECSPI_CONFIG);
 
-	/*
-	 * The hardware seems to have a race condition when changing modes. The
-	 * current assumption is that the selection of the channel arrives
-	 * earlier in the hardware than the mode bits when they are written at
-	 * the same time.
-	 * So set master mode for all channels as we do not support slave mode.
-	 */
-	ctrl |= MX51_ECSPI_CTRL_MODE_MASK;
+	writel(0, spi_imx->base + MX51_ECSPI_CTRL);
+
+	/* set Master or Slave mode */
+	if (spi_imx->slave_mode)
+		ctrl &= ~MX51_ECSPI_CTRL_MODE_MASK;
+	else
+		ctrl |= MX51_ECSPI_CTRL_MODE_MASK;
 
 	/* set clock speed */
 	ctrl |= mx51_ecspi_clkdiv(spi_imx, config->speed_hz, &clk);
@@ -386,9 +465,21 @@ static int mx51_ecspi_config(struct spi_device *spi,
 	/* set chip select to use */
 	ctrl |= MX51_ECSPI_CTRL_CS(spi->chip_select);
 
-	ctrl |= (config->bpw - 1) << MX51_ECSPI_CTRL_BL_OFFSET;
+	if (spi_imx->slave_mode && is_imx53_ecspi(spi_imx))
+		ctrl |= (spi_imx->slave_burst * 8 - 1)
+			<< MX51_ECSPI_CTRL_BL_OFFSET;
+	else
+		ctrl |= (config->bpw - 1) << MX51_ECSPI_CTRL_BL_OFFSET;
 
-	cfg |= MX51_ECSPI_CONFIG_SBBCTRL(spi->chip_select);
+	/*
+	 * eCSPI burst completion by Chip Select signal in Slave mode
+	 * is not functional, config SPI burst completed when
+	 * BURST_LENGTH + 1 bits are received
+	 */
+	if (spi_imx->slave_mode && is_imx53_ecspi(spi_imx))
+		cfg &= ~MX51_ECSPI_CONFIG_SBBCTRL(spi->chip_select);
+	else
+		cfg |= MX51_ECSPI_CONFIG_SBBCTRL(spi->chip_select);
 
 	if (spi->mode & SPI_CPHA)
 		cfg |= MX51_ECSPI_CONFIG_SCLKPHA(spi->chip_select);
@@ -767,6 +858,7 @@ static struct spi_imx_devtype_data imx51_ecspi_devtype_data = {
 	.trigger = mx51_ecspi_trigger,
 	.rx_available = mx51_ecspi_rx_available,
 	.reset = mx51_ecspi_reset,
+	.disable = mx51_ecspi_disable,
 	.devtype = IMX51_ECSPI,
 };
 
@@ -776,6 +868,7 @@ static struct spi_imx_devtype_data imx53_ecspi_devtype_data = {
 	.trigger = mx51_ecspi_trigger,
 	.rx_available = mx51_ecspi_rx_available,
 	.reset = mx51_ecspi_reset,
+	.disable = mx51_ecspi_disable,
 	.devtype = IMX53_ECSPI,
 };
 
@@ -838,14 +931,16 @@ static void spi_imx_push(struct spi_imx_data *spi_imx)
 		spi_imx->txfifo++;
 	}
 
-	spi_imx->devtype_data->trigger(spi_imx);
+	if (!spi_imx->slave_mode)
+		spi_imx->devtype_data->trigger(spi_imx);
 }
 
 static irqreturn_t spi_imx_isr(int irq, void *dev_id)
 {
 	struct spi_imx_data *spi_imx = dev_id;
 
-	while (spi_imx->devtype_data->rx_available(spi_imx)) {
+	while (spi_imx->txfifo &&
+	       spi_imx->devtype_data->rx_available(spi_imx)) {
 		spi_imx->rx(spi_imx);
 		spi_imx->txfifo--;
 	}
@@ -927,6 +1022,8 @@ static int spi_imx_setupxfer(struct spi_device *spi,
 	config.bpw = t ? t->bits_per_word : spi->bits_per_word;
 	config.speed_hz  = t ? t->speed_hz : spi->max_speed_hz;
 
+	spi_imx->slave_mode = spi->slave_mode;
+
 	if (!config.speed_hz)
 		config.speed_hz = spi->max_speed_hz;
 	if (!config.bpw)
@@ -944,7 +1041,8 @@ static int spi_imx_setupxfer(struct spi_device *spi,
 		spi_imx->tx = spi_imx_buf_tx_u32;
 	}
 
-	if (spi_imx_can_dma(spi_imx->bitbang.master, spi, t))
+	if (!spi->slave_mode &&
+	    spi_imx_can_dma(spi_imx->bitbang.master, spi, t))
 		spi_imx->usedma = 1;
 	else
 		spi_imx->usedma = 0;
@@ -956,6 +1054,12 @@ static int spi_imx_setupxfer(struct spi_device *spi,
 			return ret;
 	}
 
+	if (is_imx53_ecspi(spi_imx) && spi_imx->slave_mode) {
+		spi_imx->rx = mx53_ecspi_rx_slave;
+		spi_imx->tx = mx53_ecspi_tx_slave;
+		spi_imx->slave_burst = t->len;
+	}
+
 	spi_imx->devtype_data->config(spi, &config);
 
 	return 0;
@@ -1117,16 +1221,46 @@ static int spi_imx_pio_transfer(struct spi_device *spi,
 	struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master);
 	unsigned long transfer_timeout;
 	unsigned long timeout;
+	int ret = transfer->len;
+
+	if (is_imx53_ecspi(spi_imx) && spi_imx->slave_mode &&
+	    transfer->len > MX53_MAX_TRANSFER_BYTES) {
+		pr_err("Transaction too big, max size is %d bytes\n",
+		       MX53_MAX_TRANSFER_BYTES);
+		return -EMSGSIZE;
+	}
 
 	spi_imx->tx_buf = transfer->tx_buf;
 	spi_imx->rx_buf = transfer->rx_buf;
 	spi_imx->count = transfer->len;
 	spi_imx->txfifo = 0;
 
+	if (spi_imx->slave_mode)
+		spi_imx->slave_burst = spi_imx->count;
+
 	reinit_completion(&spi_imx->xfer_done);
 
 	spi_imx_push(spi_imx);
 
+	if (spi_imx->slave_mode) {
+		spi_imx->devtype_data->intctrl(spi_imx, MXC_INT_TE |
+							MXC_INT_RDR);
+
+		if (wait_for_completion_interruptible(&spi_imx->xfer_done) < 0)
+			ret = -EINTR;
+
+		/* ecspi has a HW issue when works in Slave mode,
+		 * after 64 words writtern to TXFIFO, even TXFIFO becomes empty,
+		 * ECSPI_TXDATA keeps shift out the last word data,
+		 * so we have to disable ECSPI when in slave mode after the
+		 * transfer completes
+		 */
+		if (spi_imx->devtype_data->disable)
+			spi_imx->devtype_data->disable(spi_imx);
+
+		goto out;
+	}
+
 	spi_imx->devtype_data->intctrl(spi_imx, MXC_INT_TE);
 
 	transfer_timeout = spi_imx_calculate_timeout(spi_imx, transfer->len);
@@ -1139,7 +1273,8 @@ static int spi_imx_pio_transfer(struct spi_device *spi,
 		return -ETIMEDOUT;
 	}
 
-	return transfer->len;
+out:
+	return ret;
 }
 
 static int spi_imx_transfer(struct spi_device *spi,
@@ -1147,6 +1282,10 @@ static int spi_imx_transfer(struct spi_device *spi,
 {
 	struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master);
 
+	/* flush rxfifo before transfer */
+	while (spi_imx->devtype_data->rx_available(spi_imx))
+		spi_imx->rx(spi_imx);
+
 	if (spi_imx->usedma)
 		return spi_imx_dma_transfer(spi_imx, transfer);
 	else
@@ -1155,6 +1294,11 @@ static int spi_imx_transfer(struct spi_device *spi,
 
 static int spi_imx_setup(struct spi_device *spi)
 {
+	if (spi->slave_mode) {
+		dev_dbg(&spi->dev, "%s: slave mode\n", __func__);
+		return 0;
+	}
+
 	dev_dbg(&spi->dev, "%s: mode %d, %u bpw, %d hz\n", __func__,
 		 spi->mode, spi->bits_per_word, spi->max_speed_hz);
 
@@ -1254,6 +1398,7 @@ static int spi_imx_probe(struct platform_device *pdev)
 	spi_imx->bitbang.master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
 	if (is_imx35_cspi(spi_imx) || is_imx51_ecspi(spi_imx))
 		spi_imx->bitbang.master->mode_bits |= SPI_LOOP;
+	spi_imx->bitbang.master->has_slavemode = spi_imx_has_slavemode;
 
 	init_completion(&spi_imx->xfer_done);
 
-- 
2.7.4

^ permalink raw reply related

* [PATCH RFC 4/5] ARM: dts: imx: change compatiblity for SPI controllers on imx53 later soc
From: jiada_wang @ 2017-04-13 12:14 UTC (permalink / raw)
  To: broonie, robh+dt, mark.rutland, shawnguo, kernel, fabio.estevam
  Cc: linux-spi, devicetree, linux-kernel, linux-arm-kernel, Jiada Wang
In-Reply-To: <1492085644-4195-1-git-send-email-jiada_wang@mentor.com>

From: Jiada Wang <jiada_wang@mentor.com>

for SPI controllers on imx53 and later SoCs, there is HW issue when
work in slave mode, as new device type 'IMX53_ECSPI' has been added
for these SPI controllers which is compatible with 'fsl,imx53-ecspi'.

This patch updates DTS to make imx53 later SPI controller only be
compatibile with 'fsl,imx53-ecspi'.

Signed-off-by: Jiada Wang <jiada_wang@mentor.com>
---
 arch/arm/boot/dts/imx53.dtsi   | 4 ++--
 arch/arm/boot/dts/imx6q.dtsi   | 2 +-
 arch/arm/boot/dts/imx6qdl.dtsi | 8 ++++----
 arch/arm/boot/dts/imx6sl.dtsi  | 8 ++++----
 arch/arm/boot/dts/imx6sx.dtsi  | 8 ++++----
 arch/arm/boot/dts/imx6ul.dtsi  | 8 ++++----
 6 files changed, 19 insertions(+), 19 deletions(-)

diff --git a/arch/arm/boot/dts/imx53.dtsi b/arch/arm/boot/dts/imx53.dtsi
index 2e516f4..9eeafb9 100644
--- a/arch/arm/boot/dts/imx53.dtsi
+++ b/arch/arm/boot/dts/imx53.dtsi
@@ -243,7 +243,7 @@
 				ecspi1: ecspi@50010000 {
 					#address-cells = <1>;
 					#size-cells = <0>;
-					compatible = "fsl,imx53-ecspi", "fsl,imx51-ecspi";
+					compatible = "fsl,imx53-ecspi";
 					reg = <0x50010000 0x4000>;
 					interrupts = <36>;
 					clocks = <&clks IMX5_CLK_ECSPI1_IPG_GATE>,
@@ -662,7 +662,7 @@
 			ecspi2: ecspi@63fac000 {
 				#address-cells = <1>;
 				#size-cells = <0>;
-				compatible = "fsl,imx53-ecspi", "fsl,imx51-ecspi";
+				compatible = "fsl,imx53-ecspi";
 				reg = <0x63fac000 0x4000>;
 				interrupts = <37>;
 				clocks = <&clks IMX5_CLK_ECSPI2_IPG_GATE>,
diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi
index e9a5d0b..7373671 100644
--- a/arch/arm/boot/dts/imx6q.dtsi
+++ b/arch/arm/boot/dts/imx6q.dtsi
@@ -90,7 +90,7 @@
 				ecspi5: ecspi@02018000 {
 					#address-cells = <1>;
 					#size-cells = <0>;
-					compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
+					compatible = "fsl,imx6q-ecspi", "fsl,imx53-ecspi";
 					reg = <0x02018000 0x4000>;
 					interrupts = <0 35 IRQ_TYPE_LEVEL_HIGH>;
 					clocks = <&clks IMX6Q_CLK_ECSPI5>,
diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi
index 6d7bf64..4a4b509 100644
--- a/arch/arm/boot/dts/imx6qdl.dtsi
+++ b/arch/arm/boot/dts/imx6qdl.dtsi
@@ -265,7 +265,7 @@
 				ecspi1: ecspi@02008000 {
 					#address-cells = <1>;
 					#size-cells = <0>;
-					compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
+					compatible = "fsl,imx6q-ecspi", "fsl,imx53-ecspi";
 					reg = <0x02008000 0x4000>;
 					interrupts = <0 31 IRQ_TYPE_LEVEL_HIGH>;
 					clocks = <&clks IMX6QDL_CLK_ECSPI1>,
@@ -279,7 +279,7 @@
 				ecspi2: ecspi@0200c000 {
 					#address-cells = <1>;
 					#size-cells = <0>;
-					compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
+					compatible = "fsl,imx6q-ecspi", "fsl,imx53-ecspi";
 					reg = <0x0200c000 0x4000>;
 					interrupts = <0 32 IRQ_TYPE_LEVEL_HIGH>;
 					clocks = <&clks IMX6QDL_CLK_ECSPI2>,
@@ -293,7 +293,7 @@
 				ecspi3: ecspi@02010000 {
 					#address-cells = <1>;
 					#size-cells = <0>;
-					compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
+					compatible = "fsl,imx6q-ecspi", "fsl,imx53-ecspi";
 					reg = <0x02010000 0x4000>;
 					interrupts = <0 33 IRQ_TYPE_LEVEL_HIGH>;
 					clocks = <&clks IMX6QDL_CLK_ECSPI3>,
@@ -307,7 +307,7 @@
 				ecspi4: ecspi@02014000 {
 					#address-cells = <1>;
 					#size-cells = <0>;
-					compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
+					compatible = "fsl,imx6q-ecspi", "fsl,imx53-ecspi";
 					reg = <0x02014000 0x4000>;
 					interrupts = <0 34 IRQ_TYPE_LEVEL_HIGH>;
 					clocks = <&clks IMX6QDL_CLK_ECSPI4>,
diff --git a/arch/arm/boot/dts/imx6sl.dtsi b/arch/arm/boot/dts/imx6sl.dtsi
index cc9572e..1d1200c 100644
--- a/arch/arm/boot/dts/imx6sl.dtsi
+++ b/arch/arm/boot/dts/imx6sl.dtsi
@@ -168,7 +168,7 @@
 				ecspi1: ecspi@02008000 {
 					#address-cells = <1>;
 					#size-cells = <0>;
-					compatible = "fsl,imx6sl-ecspi", "fsl,imx51-ecspi";
+					compatible = "fsl,imx6sl-ecspi", "fsl,imx53-ecspi";
 					reg = <0x02008000 0x4000>;
 					interrupts = <0 31 IRQ_TYPE_LEVEL_HIGH>;
 					clocks = <&clks IMX6SL_CLK_ECSPI1>,
@@ -180,7 +180,7 @@
 				ecspi2: ecspi@0200c000 {
 					#address-cells = <1>;
 					#size-cells = <0>;
-					compatible = "fsl,imx6sl-ecspi", "fsl,imx51-ecspi";
+					compatible = "fsl,imx6sl-ecspi", "fsl,imx53-ecspi";
 					reg = <0x0200c000 0x4000>;
 					interrupts = <0 32 IRQ_TYPE_LEVEL_HIGH>;
 					clocks = <&clks IMX6SL_CLK_ECSPI2>,
@@ -192,7 +192,7 @@
 				ecspi3: ecspi@02010000 {
 					#address-cells = <1>;
 					#size-cells = <0>;
-					compatible = "fsl,imx6sl-ecspi", "fsl,imx51-ecspi";
+					compatible = "fsl,imx6sl-ecspi", "fsl,imx53-ecspi";
 					reg = <0x02010000 0x4000>;
 					interrupts = <0 33 IRQ_TYPE_LEVEL_HIGH>;
 					clocks = <&clks IMX6SL_CLK_ECSPI3>,
@@ -204,7 +204,7 @@
 				ecspi4: ecspi@02014000 {
 					#address-cells = <1>;
 					#size-cells = <0>;
-					compatible = "fsl,imx6sl-ecspi", "fsl,imx51-ecspi";
+					compatible = "fsl,imx6sl-ecspi", "fsl,imx53-ecspi";
 					reg = <0x02014000 0x4000>;
 					interrupts = <0 34 IRQ_TYPE_LEVEL_HIGH>;
 					clocks = <&clks IMX6SL_CLK_ECSPI4>,
diff --git a/arch/arm/boot/dts/imx6sx.dtsi b/arch/arm/boot/dts/imx6sx.dtsi
index dd4ec85..c115ed3 100644
--- a/arch/arm/boot/dts/imx6sx.dtsi
+++ b/arch/arm/boot/dts/imx6sx.dtsi
@@ -251,7 +251,7 @@
 				ecspi1: ecspi@02008000 {
 					#address-cells = <1>;
 					#size-cells = <0>;
-					compatible = "fsl,imx6sx-ecspi", "fsl,imx51-ecspi";
+					compatible = "fsl,imx6sx-ecspi", "fsl,imx53-ecspi";
 					reg = <0x02008000 0x4000>;
 					interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
 					clocks = <&clks IMX6SX_CLK_ECSPI1>,
@@ -263,7 +263,7 @@
 				ecspi2: ecspi@0200c000 {
 					#address-cells = <1>;
 					#size-cells = <0>;
-					compatible = "fsl,imx6sx-ecspi", "fsl,imx51-ecspi";
+					compatible = "fsl,imx6sx-ecspi", "fsl,imx53-ecspi";
 					reg = <0x0200c000 0x4000>;
 					interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
 					clocks = <&clks IMX6SX_CLK_ECSPI2>,
@@ -275,7 +275,7 @@
 				ecspi3: ecspi@02010000 {
 					#address-cells = <1>;
 					#size-cells = <0>;
-					compatible = "fsl,imx6sx-ecspi", "fsl,imx51-ecspi";
+					compatible = "fsl,imx6sx-ecspi", "fsl,imx53-ecspi";
 					reg = <0x02010000 0x4000>;
 					interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
 					clocks = <&clks IMX6SX_CLK_ECSPI3>,
@@ -287,7 +287,7 @@
 				ecspi4: ecspi@02014000 {
 					#address-cells = <1>;
 					#size-cells = <0>;
-					compatible = "fsl,imx6sx-ecspi", "fsl,imx51-ecspi";
+					compatible = "fsl,imx6sx-ecspi", "fsl,imx53-ecspi";
 					reg = <0x02014000 0x4000>;
 					interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
 					clocks = <&clks IMX6SX_CLK_ECSPI4>,
diff --git a/arch/arm/boot/dts/imx6ul.dtsi b/arch/arm/boot/dts/imx6ul.dtsi
index b9d7d2d..d35ad5b 100644
--- a/arch/arm/boot/dts/imx6ul.dtsi
+++ b/arch/arm/boot/dts/imx6ul.dtsi
@@ -204,7 +204,7 @@
 				ecspi1: ecspi@02008000 {
 					#address-cells = <1>;
 					#size-cells = <0>;
-					compatible = "fsl,imx6ul-ecspi", "fsl,imx51-ecspi";
+					compatible = "fsl,imx6ul-ecspi", "fsl,imx53-ecspi";
 					reg = <0x02008000 0x4000>;
 					interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
 					clocks = <&clks IMX6UL_CLK_ECSPI1>,
@@ -216,7 +216,7 @@
 				ecspi2: ecspi@0200c000 {
 					#address-cells = <1>;
 					#size-cells = <0>;
-					compatible = "fsl,imx6ul-ecspi", "fsl,imx51-ecspi";
+					compatible = "fsl,imx6ul-ecspi", "fsl,imx53-ecspi";
 					reg = <0x0200c000 0x4000>;
 					interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
 					clocks = <&clks IMX6UL_CLK_ECSPI2>,
@@ -228,7 +228,7 @@
 				ecspi3: ecspi@02010000 {
 					#address-cells = <1>;
 					#size-cells = <0>;
-					compatible = "fsl,imx6ul-ecspi", "fsl,imx51-ecspi";
+					compatible = "fsl,imx6ul-ecspi", "fsl,imx53-ecspi";
 					reg = <0x02010000 0x4000>;
 					interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
 					clocks = <&clks IMX6UL_CLK_ECSPI3>,
@@ -240,7 +240,7 @@
 				ecspi4: ecspi@02014000 {
 					#address-cells = <1>;
 					#size-cells = <0>;
-					compatible = "fsl,imx6ul-ecspi", "fsl,imx51-ecspi";
+					compatible = "fsl,imx6ul-ecspi", "fsl,imx53-ecspi";
 					reg = <0x02014000 0x4000>;
 					interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
 					clocks = <&clks IMX6UL_CLK_ECSPI4>,
-- 
2.7.4

^ permalink raw reply related

* [PATCH RFC 3/5] spi: imx: add selection for iMX53 and iMX6 controller
From: jiada_wang @ 2017-04-13 12:14 UTC (permalink / raw)
  To: broonie, robh+dt, mark.rutland, shawnguo, kernel, fabio.estevam
  Cc: linux-spi, devicetree, linux-kernel, linux-arm-kernel, Jiada Wang
In-Reply-To: <1492085644-4195-1-git-send-email-jiada_wang@mentor.com>

From: Jiada Wang <jiada_wang@mentor.com>

ECSPI contorller for iMX53 and iMX6 has few hardware issues
comparing to iMX51.
The change add possibility to detect which controller is used
to apply possible workaround and limitations.

Signed-off-by: Jiada Wang <jiada_wang@mentor.com>
---
 drivers/spi/spi-imx.c | 43 ++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 40 insertions(+), 3 deletions(-)

diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c
index 9a7c62f..b2323b9 100644
--- a/drivers/spi/spi-imx.c
+++ b/drivers/spi/spi-imx.c
@@ -67,7 +67,8 @@ enum spi_imx_devtype {
 	IMX27_CSPI,
 	IMX31_CSPI,
 	IMX35_CSPI,	/* CSPI on all i.mx except above */
-	IMX51_ECSPI,	/* ECSPI on i.mx51 and later */
+	IMX51_ECSPI,	/* ECSPI on i.mx51 */
+	IMX53_ECSPI,	/* ECSPI on i.mx53 and later */
 };
 
 struct spi_imx_data;
@@ -127,9 +128,32 @@ static inline int is_imx51_ecspi(struct spi_imx_data *d)
 	return d->devtype_data->devtype == IMX51_ECSPI;
 }
 
+static inline int is_imx53_ecspi(struct spi_imx_data *d)
+{
+	return d->devtype_data->devtype == IMX53_ECSPI;
+}
+
 static inline unsigned spi_imx_get_fifosize(struct spi_imx_data *d)
 {
-	return is_imx51_ecspi(d) ? 64 : 8;
+	switch (d->devtype_data->devtype) {
+	case IMX51_ECSPI:
+	case IMX53_ECSPI:
+		return 64;
+	default:
+		return 8;
+	}
+}
+
+static inline bool spi_imx_has_dmamode(struct spi_imx_data *d)
+{
+	switch (d->devtype_data->devtype) {
+	case IMX35_CSPI:
+	case IMX51_ECSPI:
+	case IMX53_ECSPI:
+		return true;
+	default:
+		return false;
+	}
 }
 
 #define MXC_SPI_BUF_RX(type)						\
@@ -746,6 +770,15 @@ static struct spi_imx_devtype_data imx51_ecspi_devtype_data = {
 	.devtype = IMX51_ECSPI,
 };
 
+static struct spi_imx_devtype_data imx53_ecspi_devtype_data = {
+	.intctrl = mx51_ecspi_intctrl,
+	.config = mx51_ecspi_config,
+	.trigger = mx51_ecspi_trigger,
+	.rx_available = mx51_ecspi_rx_available,
+	.reset = mx51_ecspi_reset,
+	.devtype = IMX53_ECSPI,
+};
+
 static const struct platform_device_id spi_imx_devtype[] = {
 	{
 		.name = "imx1-cspi",
@@ -766,6 +799,9 @@ static const struct platform_device_id spi_imx_devtype[] = {
 		.name = "imx51-ecspi",
 		.driver_data = (kernel_ulong_t) &imx51_ecspi_devtype_data,
 	}, {
+		.name = "imx53-ecspi",
+		.driver_data = (kernel_ulong_t) &imx53_ecspi_devtype_data,
+	}, {
 		/* sentinel */
 	}
 };
@@ -777,6 +813,7 @@ static const struct of_device_id spi_imx_dt_ids[] = {
 	{ .compatible = "fsl,imx31-cspi", .data = &imx31_cspi_devtype_data, },
 	{ .compatible = "fsl,imx35-cspi", .data = &imx35_cspi_devtype_data, },
 	{ .compatible = "fsl,imx51-ecspi", .data = &imx51_ecspi_devtype_data, },
+	{ .compatible = "fsl,imx53-ecspi", .data = &imx53_ecspi_devtype_data, },
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, spi_imx_dt_ids);
@@ -1266,7 +1303,7 @@ static int spi_imx_probe(struct platform_device *pdev)
 	 * Only validated on i.mx35 and i.mx6 now, can remove the constraint
 	 * if validated on other chips.
 	 */
-	if (is_imx35_cspi(spi_imx) || is_imx51_ecspi(spi_imx)) {
+	if (spi_imx_has_dmamode(spi_imx)) {
 		ret = spi_imx_sdma_init(&pdev->dev, spi_imx, master);
 		if (ret == -EPROBE_DEFER)
 			goto out_clk_put;
-- 
2.7.4

^ permalink raw reply related

* [PATCH RFC 2/5] spi: spidev: use different name for SPI controller slave mode device
From: jiada_wang @ 2017-04-13 12:14 UTC (permalink / raw)
  To: broonie, robh+dt, mark.rutland, shawnguo, kernel, fabio.estevam
  Cc: Jiada Wang, devicetree, linux-kernel, linux-arm-kernel, linux-spi
In-Reply-To: <1492085644-4195-1-git-send-email-jiada_wang@mentor.com>

From: Jiada Wang <jiada_wang@mentor.com>

SPI bus controller has started to support to work in slave mode,
for device SPI controller itself works in slave mode, use name
'spidev[bus]-slv' as its name to differentiate from other
SPI devices

Signed-off-by: Jiada Wang <jiada_wang@mentor.com>
---
 drivers/spi/spidev.c | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c
index 9e2e099..e2996fb 100644
--- a/drivers/spi/spidev.c
+++ b/drivers/spi/spidev.c
@@ -781,9 +781,18 @@ static int spidev_probe(struct spi_device *spi)
 		struct device *dev;
 
 		spidev->devt = MKDEV(SPIDEV_MAJOR, minor);
-		dev = device_create(spidev_class, &spi->dev, spidev->devt,
-				    spidev, "spidev%d.%d",
-				    spi->master->bus_num, spi->chip_select);
+		if (spi->slave_mode)
+			dev = device_create(spidev_class, &spi->dev,
+					    spidev->devt, spidev,
+					    "spidev%d-slv",
+					    spi->master->bus_num);
+		else
+			dev = device_create(spidev_class, &spi->dev,
+					    spidev->devt, spidev,
+					    "spidev%d.%d",
+					    spi->master->bus_num,
+					    spi->chip_select);
+
 		status = PTR_ERR_OR_ZERO(dev);
 	} else {
 		dev_dbg(&spi->dev, "no minor number available!\n");
-- 
2.7.4

^ permalink raw reply related

* [PATCH RFC 1/5] spi: core: add support to work in Slave mode
From: jiada_wang-nmGgyN9QBj3QT0dZR+AlfA @ 2017-04-13 12:14 UTC (permalink / raw)
  To: broonie-DgEjT+Ai2ygdnm+yROfE0A, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	mark.rutland-5wv7dgnIgG8, shawnguo-DgEjT+Ai2ygdnm+yROfE0A,
	kernel-bIcnvbaLZ9MEGnE8C9+IrQ, fabio.estevam-3arQi8VN3Tc
  Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Jiada Wang
In-Reply-To: <1492085644-4195-1-git-send-email-jiada_wang-nmGgyN9QBj3QT0dZR+AlfA@public.gmane.org>

From: Jiada Wang <jiada_wang-nmGgyN9QBj3QT0dZR+AlfA@public.gmane.org>

Add support for SPI bus controller to work in slave mode using
the existing SPI master framework.
- SPI device on SPI bus controller with 'spi-slave' property
  declared in DT node represents SPI controller itself to work
  as a slave device and listening to external SPI master devices
- when SPI bus controller works in slave mode, 'chip_select' and
  'max_speed_hz' are not required.
- SPI slave mode continue to use 'struct spi_master'

Signed-off-by: Jiada Wang <jiada_wang-nmGgyN9QBj3QT0dZR+AlfA@public.gmane.org>
---
 Documentation/devicetree/bindings/spi/spi-bus.txt | 27 ++++++++++++++---------
 Documentation/spi/spi-summary                     | 19 +++++++++++-----
 drivers/spi/Kconfig                               | 14 +++++++++++-
 drivers/spi/spi.c                                 | 23 ++++++++++++++++++-
 include/linux/spi/spi.h                           | 15 +++++++++++++
 5 files changed, 80 insertions(+), 18 deletions(-)

diff --git a/Documentation/devicetree/bindings/spi/spi-bus.txt b/Documentation/devicetree/bindings/spi/spi-bus.txt
index 4b1d6e7..96e93ba 100644
--- a/Documentation/devicetree/bindings/spi/spi-bus.txt
+++ b/Documentation/devicetree/bindings/spi/spi-bus.txt
@@ -1,17 +1,20 @@
 SPI (Serial Peripheral Interface) busses
 
-SPI busses can be described with a node for the SPI master device
-and a set of child nodes for each SPI slave on the bus.  For this
-discussion, it is assumed that the system's SPI controller is in
-SPI master mode.  This binding does not describe SPI controllers
-in slave mode.
+SPI busses can be described with a node for the SPI controller device
+and a set of child nodes for each SPI slave on the bus.  The system's SPI
+controller can work either in master mode or in slave mode, based on the
+child node on it.
 
-The SPI master node requires the following properties:
+The SPI controller node requires the following properties:
+- compatible      - name of SPI bus controller following generic names
+		recommended practice.
+
+In master mode, the SPI controller node requires the following additional
+properties:
 - #address-cells  - number of cells required to define a chip select
 		address on the SPI bus.
 - #size-cells     - should be zero.
-- compatible      - name of SPI bus controller following generic names
-		recommended practice.
+
 No other properties are required in the SPI bus node.  It is assumed
 that a driver for an SPI bus device will understand that it is an SPI bus.
 However, the binding does not attempt to define the specific method for
@@ -43,10 +46,11 @@ cs3 : &gpio1 2 0
 
 SPI slave nodes must be children of the SPI master node and can
 contain the following properties.
-- reg             - (required) chip select address of device.
+- reg             - (required, master mode only) chip select address of device.
 - compatible      - (required) name of SPI device following generic names
 		recommended practice.
-- spi-max-frequency - (required) Maximum SPI clocking speed of device in Hz.
+- spi-max-frequency - (required, master mode only) Maximum SPI clocking speed of
+		device in Hz.
 - spi-cpol        - (optional) Empty property indicating device requires
 		inverse clock polarity (CPOL) mode.
 - spi-cpha        - (optional) Empty property indicating device requires
@@ -63,6 +67,9 @@ contain the following properties.
                       used for MISO. Defaults to 1 if not present.
 - spi-rx-delay-us  - (optional) Microsecond delay after a read transfer.
 - spi-tx-delay-us  - (optional) Microsecond delay after a write transfer.
+- spi-slave        - (optional) Empty property indicating SPI bus controller
+		itself works in slave mode to interface with external master
+		devices.
 
 Some SPI controllers and devices support Dual and Quad SPI transfer mode.
 It allows data in the SPI system to be transferred using 2 wires (DUAL) or 4
diff --git a/Documentation/spi/spi-summary b/Documentation/spi/spi-summary
index d1824b3..4c2ceaa 100644
--- a/Documentation/spi/spi-summary
+++ b/Documentation/spi/spi-summary
@@ -62,9 +62,8 @@ chips described as using "three wire" signaling: SCK, data, nCSx.
 (That data line is sometimes called MOMI or SISO.)
 
 Microcontrollers often support both master and slave sides of the SPI
-protocol.  This document (and Linux) currently only supports the master
-side of SPI interactions.
-
+protocol.  This document (and Linux) supports both the master and slave
+sides of SPI interactions.
 
 Who uses it?  On what kinds of systems?
 ---------------------------------------
@@ -154,9 +153,8 @@ control audio interfaces, present touchscreen sensors as input interfaces,
 or monitor temperature and voltage levels during industrial processing.
 And those might all be sharing the same controller driver.
 
-A "struct spi_device" encapsulates the master-side interface between
-those two types of driver.  At this writing, Linux has no slave side
-programming interface.
+A "struct spi_device" encapsulates the controller-side interface between
+those two types of drivers.
 
 There is a minimal core of SPI programming interfaces, focussing on
 using the driver model to connect controller and protocol drivers using
@@ -168,12 +166,21 @@ shows up in sysfs in several locations:
    /sys/devices/.../CTLR/spiB.C ... spi_device on bus "B",
 	chipselect C, accessed through CTLR.
 
+   /sys/devices/.../CTLR/spiB-slv ... SPI bus "B" controller itself as a
+	spi_device works in slave mode, accessed through CTRL.
+
    /sys/bus/spi/devices/spiB.C ... symlink to that physical
    	.../CTLR/spiB.C device
 
+   /sys/bus/spi/devices/spiB-slv ... symlink to that physical
+	.../CTLR/spiB-slv device
+
    /sys/devices/.../CTLR/spiB.C/modalias ... identifies the driver
 	that should be used with this device (for hotplug/coldplug)
 
+   /sys/devices/.../CTLR/spiB-slv/modalias ... identifies the driver
+	that should be used with this device (for hotplug/coldplug)
+
    /sys/bus/spi/drivers/D ... driver for one or more spi*.* devices
 
    /sys/class/spi_master/spiB ... symlink (or actual device node) to
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 25ae7f2e..1096c7d 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -784,6 +784,18 @@ config SPI_TLE62X0
 
 endif # SPI_MASTER
 
-# (slave support would go here)
+#
+# SLAVE side ... listening to other SPI masters
+#
+
+config SPI_SLAVE
+	bool "SPI slave protocol handlers"
+	help
+	  If your system has a slave-capable SPI controller, you can enable
+	  slave protocol handlers.
+
+if SPI_SLAVE
+
+endif # SPI_SLAVE
 
 endif # SPI
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 90b5b2e..3af26e2 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -475,6 +475,12 @@ static void spi_dev_set_name(struct spi_device *spi)
 		return;
 	}
 
+	if (spi->slave_mode) {
+		dev_set_name(&spi->dev, "%s-slv",
+			     dev_name(&spi->master->dev));
+		return;
+	}
+
 	dev_set_name(&spi->dev, "%s.%u", dev_name(&spi->master->dev),
 		     spi->chip_select);
 }
@@ -484,6 +490,9 @@ static int spi_dev_check(struct device *dev, void *data)
 	struct spi_device *spi = to_spi_device(dev);
 	struct spi_device *new_spi = data;
 
+	if (spi->slave_mode)
+		return 0;
+
 	if (spi->master == new_spi->master &&
 	    spi->chip_select == new_spi->chip_select)
 		return -EBUSY;
@@ -523,6 +532,9 @@ int spi_add_device(struct spi_device *spi)
 	 */
 	mutex_lock(&spi_add_lock);
 
+	if (spi->slave_mode)
+		goto setup_spi;
+
 	status = bus_for_each_dev(&spi_bus_type, NULL, spi, spi_dev_check);
 	if (status) {
 		dev_err(dev, "chipselect %d already in use\n",
@@ -533,6 +545,7 @@ int spi_add_device(struct spi_device *spi)
 	if (master->cs_gpios)
 		spi->cs_gpio = master->cs_gpios[spi->chip_select];
 
+setup_spi:
 	/* Drivers may modify this initial i/o setup, but will
 	 * normally rely on the device being setup.  Devices
 	 * using SPI_CS_HIGH can't coexist well otherwise...
@@ -1511,6 +1524,14 @@ static int of_spi_parse_dt(struct spi_master *master, struct spi_device *spi,
 	u32 value;
 	int rc;
 
+	if (of_find_property(nc, "spi-slave", NULL)) {
+		if (!spi_controller_has_slavemode(master))
+			return -EINVAL;
+
+		spi->slave_mode = 1;
+		return 0;
+	}
+
 	/* Device address */
 	rc = of_property_read_u32(nc, "reg", &value);
 	if (rc) {
@@ -1961,7 +1982,7 @@ int spi_register_master(struct spi_master *master)
 	status = device_add(&master->dev);
 	if (status < 0)
 		goto done;
-	dev_dbg(dev, "registered master %s%s\n", dev_name(&master->dev),
+	dev_dbg(dev, "registered controller %s%s\n", dev_name(&master->dev),
 			dynamic ? " (dynamic)" : "");
 
 	/* If we're using a queued driver, start the queue */
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index 75c6bd0..bb81425 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -115,6 +115,8 @@ void spi_statistics_add_transfer_stats(struct spi_statistics *stats,
  *	This may be changed by the device's driver, or left at the
  *	default (0) indicating protocol words are eight bit bytes.
  *	The spi_transfer.bits_per_word can override this for each transfer.
+ * @slave_mode: indicates whether SPI controller works in master mode
+ *	or slave mode to transfer data with external spi devices.
  * @irq: Negative, or the number passed to request_irq() to receive
  *	interrupts from this device.
  * @controller_state: Controller's runtime state
@@ -144,6 +146,7 @@ struct spi_device {
 	u8			chip_select;
 	u8			bits_per_word;
 	u16			mode;
+	u8			slave_mode;
 #define	SPI_CPHA	0x01			/* clock phase */
 #define	SPI_CPOL	0x02			/* clock polarity */
 #define	SPI_MODE_0	(0|0)			/* (original MicroWire) */
@@ -372,6 +375,7 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv)
  *                    transfer_one callback.
  * @handle_err: the subsystem calls the driver to handle an error that occurs
  *		in the generic implementation of transfer_one_message().
+ * @has_slavemode: checks whether SPI Controller supports slave mode or not.
  * @unprepare_message: undo any work done by prepare_message().
  * @spi_flash_read: to support spi-controller hardwares that provide
  *                  accelerated interface to read from flash devices.
@@ -549,6 +553,7 @@ struct spi_master {
 			    struct spi_transfer *transfer);
 	void (*handle_err)(struct spi_master *master,
 			   struct spi_message *message);
+	bool (*has_slavemode)(struct spi_master *master);
 
 	/* gpio chip select */
 	int			*cs_gpios;
@@ -590,6 +595,16 @@ static inline void spi_master_put(struct spi_master *master)
 		put_device(&master->dev);
 }
 
+
+static inline bool spi_controller_has_slavemode(struct spi_master *master)
+{
+#ifdef CONFIG_SPI_SLAVE
+	if (master->has_slavemode)
+		return master->has_slavemode(master);
+#endif
+	return false;
+}
+
 /* PM calls that need to be issued by the driver */
 extern int spi_master_suspend(struct spi_master *master);
 extern int spi_master_resume(struct spi_master *master);
-- 
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 RFC 0/5] *** SPI Slave mode support ***
From: jiada_wang @ 2017-04-13 12:13 UTC (permalink / raw)
  To: broonie, robh+dt, mark.rutland, shawnguo, kernel, fabio.estevam
  Cc: Jiada Wang, devicetree, linux-kernel, linux-arm-kernel, linux-spi

From: Jiada Wang <jiada_wang@mentor.com>

v1:
  add Slave mode support in SPI core
  spidev create slave device when SPI controller work in slave mode
  spi-imx support to work in slave mode

Jiada Wang (5):
  spi: core: add support to work in Slave mode
  spi: spidev: use different name for SPI controller slave mode device
  spi: imx: add selection for iMX53 and iMX6 controller
  ARM: dts: imx: change compatiblity for SPI controllers on imx53 later
    soc
  spi: imx: Add support for SPI Slave mode for imx53 and imx6 chips

 Documentation/devicetree/bindings/spi/spi-bus.txt |  27 ++-
 Documentation/spi/spi-summary                     |  19 +-
 arch/arm/boot/dts/imx53.dtsi                      |   4 +-
 arch/arm/boot/dts/imx6q.dtsi                      |   2 +-
 arch/arm/boot/dts/imx6qdl.dtsi                    |   8 +-
 arch/arm/boot/dts/imx6sl.dtsi                     |   8 +-
 arch/arm/boot/dts/imx6sx.dtsi                     |   8 +-
 arch/arm/boot/dts/imx6ul.dtsi                     |   8 +-
 drivers/spi/Kconfig                               |  14 +-
 drivers/spi/spi-imx.c                             | 216 ++++++++++++++++++++--
 drivers/spi/spi.c                                 |  23 ++-
 drivers/spi/spidev.c                              |  15 +-
 include/linux/spi/spi.h                           |  15 ++
 13 files changed, 310 insertions(+), 57 deletions(-)

-- 
2.7.4

^ permalink raw reply

* Re: [RFC PATCH] of: Fix DMA configuration for non-DT masters
From: Oza Oza @ 2017-04-13 11:41 UTC (permalink / raw)
  To: Robin Murphy
  Cc: Linux IOMMU, devicetree-u79uwXL29TY76Z2rM5mHXA,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <b02ace9b-f8f3-269d-6db4-3c1b1ea1e816-5wv7dgnIgG8@public.gmane.org>

On Wed, Mar 29, 2017 at 11:12 PM, Robin Murphy <robin.murphy-5wv7dgnIgG8@public.gmane.org> wrote:
> On 29/03/17 06:46, Oza Oza wrote:
>> On Wed, Mar 29, 2017 at 10:23 AM, Oza Oza <oza.oza-dY08KVG/lbpWk0Htik3J/w@public.gmane.org> wrote:
>>> On Wed, Mar 29, 2017 at 12:27 AM, Robin Murphy <robin.murphy-5wv7dgnIgG8@public.gmane.org> wrote:
>>>> For PCI masters not represented in DT, we pass the OF node of their
>>>> associated host bridge to of_dma_configure(), such that they can inherit
>>>> the appropriate DMA configuration from whatever is described there.
>>>> Unfortunately, whilst this has worked for the "dma-coherent" property,
>>>> it turns out to miss the case where the host bridge node has a non-empty
>>>> "dma-ranges", since nobody is expecting the 'device' to be a bus itself.
>>>>
>>>> It transpires, though, that the de-facto interface since the prototype
>>>> change in 1f5c69aa51f9 ("of: Move of_dma_configure() to device.c to help
>>>> re-use") is very clear-cut: either the master_np argument is redundant
>>>> with dev->of_node, or dev->of_node is NULL and master_np is the relevant
>>>> parent bus. Let's ratify that behaviour, then teach the whole
>>>> of_dma_configure() pipeline to cope with both cases properly.
>>>>
>>>> Signed-off-by: Robin Murphy <robin.murphy-5wv7dgnIgG8@public.gmane.org>
>
> [...]
>
>>>
>>> pci and memory mapped device world is different.
>
> ???
>
> No they aren't. There is nothing magic about PCI. PCI *is* a
> memory-mapped bus.
>
> The only PCI-specific aspect here is the Linux code path which passes a
> host controller node into of_dma_configure() where the latter expects a
> node for the actual endpoint device. It managed to work for
> "dma-coherent", because that may appear either directly on a device node
> or on any of its parent buses, but "dma-ranges" is *only* valid for DT
> nodes representing buses, thus reveals that using a parent bus to stand
> in for a device isn't actually correct. I only posted that horrible hack
> patch to prove the point that having a child node to represent the
> actual device is indeed sufficient to make of_dma_configure() work
> correctly for PCI masters as-is (modulo the other issues).
>
>> of course if you talk
>>> from iommu perspective, all the master are same for IOMMU
>
> I don't understand what you mean by that. There's nothing about IOMMUs
> here, it's purely about parsing DT properties correctly.
>
>>> but the original intention of the patch is to try to solve 2 problems.
>>> please refer to https://lkml.org/lkml/2017/3/29/10
>
> One patch should not solve two separate problems anyway. Taking a step
> back, there are at least 3 things that this discussion has brought up:
>
> 1) The way in which we call of_dma_configure() for PCI devices causes
> the "dma-ranges" property on PCI host controllers to be ignored.
>
> 2) of_dma_get_range() only considers the first entry in any "dma-ranges"
> property.
>
> 3) When of_dma_configure() does set a DMA mask, there is nothing on
> arm64 and other architectures to prevent drivers overriding that with a
> wider mask later.
>
> Those are 3 separate problems, to solve with 3 or more separate patches,
> and I have deliberately put the second and third to one side for the
> moment. This patch fixes problem 1.
>
>>> 1) expose generic API for pci world clients to configure their
>>> dma-ranges. right now there is none.
>>> 2) same API can be used by IOMMU to derive dma_mask.
>>>
>>> while the current patch posted to handle dma-ranges for both memory
>>> mapped and pci devices, which I think is overdoing.
>
> No, of_dma_configure() handles the "dma-ranges" property as it is
> defined in the DT spec to describe the mapping between a child bus
> address space and a parent bus address space. Whether those
> memory-mapped parent and child buses are PCI, ISA, AMBA, HyperTransport,
> or anything else is irrelevant other than for the encoding of the
> address specifiers. All this patch does is sort out the cases where we
> have a real device node to start at, from the cases where we don't and
> so start directly at the device's parent bus node instead.
>
>>> besides we have different configuration of dma-ranges based on iommu
>>> is enabled or not enabled.
>
> That doesn't sound right, unless you mean the firmware actually programs
> the host controller's AXI bridge differently for system configurations
> where the IOMMU is expected to be used or not? (and even then, I don't
> really see why it would be necessary to do that...)
>
>>>  #define PCIE_DMA_RANGES dma-ranges = <0x43000000 0x00 0x80000000 0x00
>>> 0x80000000 0x00 0x80000000 \
>>>                                       0x43000000 0x08 0x00000000 0x08
>>> 0x00000000 0x08 0x00000000 \
>>>                                       0x43000000 0x80 0x00000000 0x80
>>> 0x00000000 0x40 0x00000000>;
>>> Not sure if this patch will consider above dma-ranges.
>>>
>>> my suggestion is to leave existing of_dma_get_range as is, and have
>>> new function for pci world as discussed in
>>> please refer to https://lkml.org/lkml/2017/3/29/10
>
> And then we keep adding new functions to do the exact same thing for
> every other discoverable bus type whose bridge is be described in DT? I
> fail to see how that is in any way better than simply fixing the
> existing code to work as it was intended to.
>
> of_dma_get_ranges() uses of_translate_dma_address() just the same way as
> existing PowerPC PCI code does, which further disproves your assertion
> that parsing PCI addresses is somehow special - it's really only a
> matter of getting the right number of address cells in order to to read
> a child address to give to of_translate_dma_address() in the first
> place. Incidentally, I now notice that the proposed
> of_pci_get_dma_ranges() is incomplete as it doesn't use
> of_translate_dma_address() or otherwise traverse upwards through the
> dma-ranges of any further parent buses.
>
>>>
>>> Regards,
>>> Oza.
>>
>> also I see that, in case of multiple ranges of_dma_get_range doesnt handle that.
>> and also it is not meant to handle.
>
> Yes, the existing code doesn't handle multiple dma-ranges entries,
> because nobody's had the need to implement that so far, and this patch
> does not change that because it's fixing a separate problem.
>
> Now, of course of_dma_get_range() *should* be capable of handling
> multiple entries regardless of this patch, and I'm going to write *that*
> patch right now (it's going to be a case of adding a handful of lines
> which probably won't even conflict with this one at all). If we had a
> bunch of different range parsing functions, we'd then have to duplicate
> the equivalent logic across all of them, which is clearly undesirable
> when it can easily be avoided altogether.
>
> Robin.
>
>> so with this patch will return wrong size and hence wrong dma_mask.
>> having said, I think it is better to separate pci world dma-ranges
>> function on of_pci.c
>>
>> for which my discussion with Rob already, (same thread)
>> https://lkml.org/lkml/2017/3/29/10
>> Waiting for Rob's viewpoint on this.
>>
>>
>> Regards,
>> Oza.
>>
>

first of all the patch

https://lkml.org/lkml/2017/3/30/304

is not only to address the original problem of dma_mask but also to
provide generic APIs
to PCI RC drivers such as pcie-iproc.c or even rcar to get their dma-ranges.

this API not only provides basis to retrieve the ranges but also it
should have capability to handle
inbound memory flags.

having said that the PCI dma-ranges do differ slightly from
traditional memory ranges.
because it has got flags.

now those flags could be IORESOURCE_CACHEABLE or anything else.
our SOC will be having use of these flags in near future (although can
not discuss details as of now).
but in short we will need these flags to be taken care which were
passed form DT.

so PCIe iproc driver calls this function to get all teh information
about dma-ranges.

now if such function exists, other framework could also make use of it
to get resources and figure out dma_mask.
and in that case you really need not change of_dma_get_range.

not only of_dma_get_range can hdnle PCI flags property but also it can
not handle multiple ranges because finally it has only
single *dma_addr, *paddr, *size  out parameters.
so the burdon will be on API to fix the behavior as what to return
rather than having Caller to choose what to do with the ranges.

coming back to my current patch
currently it does not do flag handling, but in near future I will have
to add, but for that, this patch
https://lkml.org/lkml/2017/3/30/304
needs to bring under consideration to be ACKed.

hope this explains the need of API.

Regards,
Oza.
--
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

* Re: [PATCH 2/2] hwrng: mtk: Add driver for hardware random generator on MT7623 SoC
From: Corentin Labbe @ 2017-04-13 11:06 UTC (permalink / raw)
  To: sean.wang-NuS5LvNUpcJWk0Htik3J/w
  Cc: herbert-lOAM2aK0SrRLBo1qDEOMRrpzq4S04n8Q,
	mpm-VDJrAJ4Gl5ZBDgjK7y7TUQ, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	mark.rutland-5wv7dgnIgG8, prasannatsmkumar-Re5JQEeQqe8AvxtiuMwx3w,
	romain.perier-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	shannon.nelson-QHcLZuEGTsvQT0dZR+AlfA,
	weiyongjun1-hv44wF8Li93QT0dZR+AlfA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-crypto-u79uwXL29TY76Z2rM5mHXA,
	linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	keyhaede-Re5JQEeQqe8AvxtiuMwx3w
In-Reply-To: <1492067108-14748-3-git-send-email-sean.wang-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>

Hello

I have some minor comment below:

On Thu, Apr 13, 2017 at 03:05:08PM +0800, sean.wang-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org wrote:
> From: Sean Wang <sean.wang-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
> 
> This patch adds support for hardware random generator on MT7623 SoC
> and should also work on other similar Mediatek SoCs. Currently,
> the driver is already tested successfully with rng-tools.
> 
> Signed-off-by: Sean Wang <sean.wang-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
> ---
>  drivers/char/hw_random/Kconfig   |  16 +++-
>  drivers/char/hw_random/Makefile  |   2 +-
>  drivers/char/hw_random/mtk-rng.c | 174 +++++++++++++++++++++++++++++++++++++++
>  3 files changed, 190 insertions(+), 2 deletions(-)
>  create mode 100644 drivers/char/hw_random/mtk-rng.c
> 
> diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig
> index 0cafe08..af782ce 100644
> --- a/drivers/char/hw_random/Kconfig
> +++ b/drivers/char/hw_random/Kconfig
> @@ -419,10 +419,24 @@ config HW_RANDOM_CAVIUM
>           Generator hardware found on Cavium SoCs.
>  
>           To compile this driver as a module, choose M here: the
> -         module will be called cavium_rng.
> +         module will be called mtk-rng.

Unwanted change

>  
>           If unsure, say Y.
>  
> +config HW_RANDOM_MTK
> +	tristate "Mediatek Random Number Generator support"
> +	depends on HW_RANDOM
> +	depends on ARCH_MEDIATEK || COMPILE_TEST
> +	default y
> +	---help---
> +	  This driver provides kernel-side support for the Random Number
> +	  Generator hardware found on Mediatek SoCs.
> +
> +	  To compile this driver as a module, choose M here. the
> +	  module will be called mtk-rng.
> +
> +	  If unsure, say Y.
> +
>  endif # HW_RANDOM
>  
>  config UML_RANDOM
> diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile
> index 5f52b1e..68be716 100644
> --- a/drivers/char/hw_random/Makefile
> +++ b/drivers/char/hw_random/Makefile
> @@ -1,7 +1,6 @@
>  #
>  # Makefile for HW Random Number Generator (RNG) device drivers.
>  #
> -

Another unwanted change

>  obj-$(CONFIG_HW_RANDOM) += rng-core.o
>  rng-core-y := core.o
>  obj-$(CONFIG_HW_RANDOM_TIMERIOMEM) += timeriomem-rng.o
> @@ -36,3 +35,4 @@ obj-$(CONFIG_HW_RANDOM_STM32) += stm32-rng.o
>  obj-$(CONFIG_HW_RANDOM_PIC32) += pic32-rng.o
>  obj-$(CONFIG_HW_RANDOM_MESON) += meson-rng.o
>  obj-$(CONFIG_HW_RANDOM_CAVIUM) += cavium-rng.o cavium-rng-vf.o
> +obj-$(CONFIG_HW_RANDOM_MTK)	+= mtk-rng.o
> diff --git a/drivers/char/hw_random/mtk-rng.c b/drivers/char/hw_random/mtk-rng.c
> new file mode 100644
> index 0000000..6561ee0
> --- /dev/null
> +++ b/drivers/char/hw_random/mtk-rng.c
> @@ -0,0 +1,174 @@
> +/*
> + * Driver for Mediatek Hardware Random Number Generator
> + *
> + * Copyright (C) 2017 Sean Wang <sean.wang-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + */
> +#define MTK_RNG_DEV KBUILD_MODNAME
> +
> +#include <linux/clk.h>
> +#include <linux/delay.h>
> +#include <linux/err.h>
> +#include <linux/hw_random.h>
> +#include <linux/io.h>
> +#include <linux/iopoll.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +
> +#define USEC_POLL			2
> +#define TIMEOUT_POLL			20
> +
> +#define RNG_CTRL			0x00
> +#define  RNG_EN				BIT(0)
> +#define  RNG_READY			BIT(31)

Keep only one space between define and name

> +
> +#define RNG_DATA			0x08
> +
> +#define to_mtk_rng(p)	container_of(p, struct mtk_rng, rng)
> +
> +struct mtk_rng {
> +	struct device	*dev;
> +	void __iomem *base;
> +	struct clk *clk;
> +	struct hwrng rng;
> +};
> +
> +static int mtk_rng_init(struct hwrng *rng)
> +{
> +	struct mtk_rng *priv = to_mtk_rng(rng);
> +	u32 val;
> +	int err;
> +
> +	err = clk_prepare_enable(priv->clk);
> +	if (err)
> +		return err;
> +
> +	val = readl(priv->base + RNG_CTRL);
> +	val |= RNG_EN;
> +	writel(val, priv->base + RNG_CTRL);
> +
> +	return 0;
> +}
> +
> +static void mtk_rng_cleanup(struct hwrng *rng)
> +{
> +	struct mtk_rng *priv = to_mtk_rng(rng);
> +	u32 val;
> +
> +	val = readl(priv->base + RNG_CTRL);
> +	val &= ~RNG_EN;
> +	writel(val, priv->base + RNG_CTRL);
> +
> +	clk_disable_unprepare(priv->clk);
> +}
> +
> +static bool mtk_rng_wait_ready(struct hwrng *rng, bool wait)
> +{
> +	struct mtk_rng *priv = to_mtk_rng(rng);
> +	int ready;
> +
> +	ready = readl(priv->base + RNG_CTRL) & RNG_READY;
> +	if (!ready && wait)
> +		readl_poll_timeout_atomic(priv->base + RNG_CTRL, ready,
> +					  ready & RNG_READY, USEC_POLL,
> +					  TIMEOUT_POLL);
> +	return !!ready;
> +}
> +
> +static int mtk_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait)
> +{
> +	struct mtk_rng *priv = to_mtk_rng(rng);
> +	int retval = 0;
> +
> +	while (max >= sizeof(u32)) {
> +		if (!mtk_rng_wait_ready(rng, wait))
> +			break;
> +
> +		*(u32 *)buf = readl(priv->base + RNG_DATA);
> +		retval += sizeof(u32);
> +		buf += sizeof(u32);
> +		max -= sizeof(u32);
> +	}
> +
> +	if (unlikely(wait && max))
> +		dev_warn(priv->dev, "timeout might be not properly set\n");
> +
> +	return retval || !wait ? retval : -EIO;
> +}
> +
> +static int mtk_rng_probe(struct platform_device *pdev)
> +{
> +	struct resource *res;
> +	int ret;
> +	struct mtk_rng *priv;
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	if (!res) {
> +		dev_err(&pdev->dev, "no iomem resource\n");
> +		return -ENXIO;
> +	}
> +
> +	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
> +	if (!priv)
> +		return -ENOMEM;
> +
> +	priv->dev = &pdev->dev;
> +	priv->rng.name = pdev->name;
> +	priv->rng.init = mtk_rng_init;
> +	priv->rng.cleanup = mtk_rng_cleanup;
> +	priv->rng.read = mtk_rng_read;
> +
> +	priv->clk = devm_clk_get(&pdev->dev, "rng");
> +	if (IS_ERR(priv->clk)) {
> +		ret = PTR_ERR(priv->clk);
> +		dev_err(&pdev->dev, "no clock for device: %d\n", ret);
> +		return ret;
> +	}
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);

You get that resource twice

Regards
Corentin Labbe
--
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

* [PATCH v2 4/4] Add XRA1403 support to MAINTAINERS file
From: Nandor Han @ 2017-04-13 10:27 UTC (permalink / raw)
  To: gregkh, davem, geert, mchehab, daniel.vetter, linus.walleij,
	gnurou, robh+dt, mark.rutland, linux-gpio, devicetree,
	linux-kernel
  Cc: Nandor Han
In-Reply-To: <cover.1492077070.git.nandor.han@ge.com>

Add XRA1403 support to MAINTAINERS list.

Signed-off-by: Nandor Han <nandor.han@ge.com>
---
 MAINTAINERS | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 892e958..0c5b984 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14013,6 +14013,14 @@ L:	linux-kernel@vger.kernel.org
 S:	Supported
 F:	drivers/char/xillybus/
 
+XRA1403 GPIO EXPANDER
+M:	Nandor Han <nandor.han@ge.com>
+M:	Semi Malinen <semi.malinen@ge.com>
+L:	linux-gpio@vger.kernel.org
+S:	Maintained
+F:	drivers/gpio/gpio-xra1403.c
+F:	Documentation/devicetree/bindings/gpio/gpio-xra1403.txt
+
 XTENSA XTFPGA PLATFORM SUPPORT
 M:	Max Filippov <jcmvbkbc@gmail.com>
 L:	linux-xtensa@linux-xtensa.org
-- 
2.10.1

^ permalink raw reply related

* [PATCH v2 3/4] doc,dts - add XRA1403 DTS binding documentation
From: Nandor Han @ 2017-04-13 10:27 UTC (permalink / raw)
  To: gregkh, davem, geert, mchehab, daniel.vetter, linus.walleij,
	gnurou, robh+dt, mark.rutland, linux-gpio, devicetree,
	linux-kernel
  Cc: Nandor Han
In-Reply-To: <cover.1492077070.git.nandor.han@ge.com>

Add the XRA1403 DTS binding documentation.

Signed-off-by: Nandor Han <nandor.han@ge.com>
---
 .../devicetree/bindings/gpio/gpio-xra1403.txt      | 46 ++++++++++++++++++++++
 1 file changed, 46 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/gpio-xra1403.txt

diff --git a/Documentation/devicetree/bindings/gpio/gpio-xra1403.txt b/Documentation/devicetree/bindings/gpio/gpio-xra1403.txt
new file mode 100644
index 0000000..e13cc39
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/gpio-xra1403.txt
@@ -0,0 +1,46 @@
+GPIO Driver for XRA1403 16-BIT GPIO Expander With Reset Input from EXAR
+
+The XRA1403 is an 16-bit GPIO expander with an SPI interface. Features available:
+	- Individually programmable inputs:
+		- Internal pull-up resistors
+		- Polarity inversion
+		- Individual interrupt enable
+		- Rising edge and/or Falling edge interrupt
+		- Input filter
+	- Individually programmable outputs
+		- Output Level Control
+		- Output Three-State Control
+
+Properties
+----------
+Check documentation for SPI and GPIO controllers regarding properties needed to configure the node.
+
+	- compatible = "exar,xra1403".
+	- reg - SPI id of the device.
+	- gpio-controller - marks the node as gpio.
+	- #gpio-cells - should be two where the first cell is the pin number
+		and the second one is used for optional parameters.
+
+Optional properties:
+-------------------
+	- reset-gpios: in case available used to control the device reset line.
+	- interrupt-controller - marks the node as interrupt controller.
+	- #interrupt-cells - should be two and represents the number of cells
+		needed to encode interrupt source.
+
+Example
+--------
+
+	gpioxra0: gpio@2 {
+		compatible = "exar,xra1403";
+		reg = <2>;
+
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+
+		reset-gpios = <&gpio3 6 GPIO_ACTIVE_LOW>;
+		spi-max-frequency = <1000000>;
+	};
-- 
2.10.1


^ permalink raw reply related

* [PATCH v2 2/4] gpio - Add EXAR XRA1403 SPI GPIO expander driver
From: Nandor Han @ 2017-04-13 10:27 UTC (permalink / raw)
  To: gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
	davem-fT/PcQaiUtIeIZ0/mPfg9Q, geert-Td1EMuHUCqxL1ZNQvxDV9g,
	mchehab-DgEjT+Ai2ygdnm+yROfE0A, daniel.vetter-/w4YWyX8dFk,
	linus.walleij-QSEj5FYQhm4dnm+yROfE0A,
	gnurou-Re5JQEeQqe8AvxtiuMwx3w, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	mark.rutland-5wv7dgnIgG8, linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA
  Cc: Nandor Han, Semi Malinen
In-Reply-To: <cover.1492077070.git.nandor.han-JJi787mZWgc@public.gmane.org>

This is a simple driver that provides a /sys/class/gpio
interface for controlling and configuring the GPIO lines.
It does not provide support for chip select or interrupts.

Signed-off-by: Nandor Han <nandor.han-JJi787mZWgc@public.gmane.org>
Signed-off-by: Semi Malinen <semi.malinen-JJi787mZWgc@public.gmane.org>
---
 drivers/gpio/Kconfig        |   5 +
 drivers/gpio/Makefile       |   1 +
 drivers/gpio/gpio-xra1403.c | 236 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 242 insertions(+)
 create mode 100644 drivers/gpio/gpio-xra1403.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 63ceed2..53cbe9b 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -1214,6 +1214,11 @@ config GPIO_PISOSR
 	  GPIO driver for SPI compatible parallel-in/serial-out shift
 	  registers. These are input only devices.
 
+config GPIO_XRA1403
+	tristate "EXAR XRA1403 16-bit GPIO expander"
+	help
+	  GPIO driver for EXAR XRA1403 16-bit SPI-based GPIO expander.
+
 endmenu
 
 menu "SPI or I2C GPIO expanders"
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 095598e..76dc3d7 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -140,6 +140,7 @@ obj-$(CONFIG_GPIO_XGENE)	+= gpio-xgene.o
 obj-$(CONFIG_GPIO_XGENE_SB)	+= gpio-xgene-sb.o
 obj-$(CONFIG_GPIO_XILINX)	+= gpio-xilinx.o
 obj-$(CONFIG_GPIO_XLP)		+= gpio-xlp.o
+obj-$(CONFIG_GPIO_XRA1403)	+= gpio-xra1403.o
 obj-$(CONFIG_GPIO_XTENSA)	+= gpio-xtensa.o
 obj-$(CONFIG_GPIO_ZEVIO)	+= gpio-zevio.o
 obj-$(CONFIG_GPIO_ZYNQ)		+= gpio-zynq.o
diff --git a/drivers/gpio/gpio-xra1403.c b/drivers/gpio/gpio-xra1403.c
new file mode 100644
index 0000000..e6966d9
--- /dev/null
+++ b/drivers/gpio/gpio-xra1403.c
@@ -0,0 +1,236 @@
+/*
+ * GPIO driver for EXAR XRA1403 16-bit GPIO expander
+ *
+ * Copyright (c) 2017, General Electric Company
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/bitops.h>
+#include <linux/gpio/driver.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
+#include <linux/spi/spi.h>
+#include <linux/regmap.h>
+
+/* XRA1403 registers */
+#define XRA_GSR   0x00 /* GPIO State */
+#define XRA_OCR   0x02 /* Output Control */
+#define XRA_PIR   0x04 /* Input Polarity Inversion */
+#define XRA_GCR   0x06 /* GPIO Configuration */
+#define XRA_PUR   0x08 /* Input Internal Pull-up Resistor Enable/Disable */
+#define XRA_IER   0x0A /* Input Interrupt Enable */
+#define XRA_TSCR  0x0C /* Output Three-State Control */
+#define XRA_ISR   0x0E /* Input Interrupt Status */
+#define XRA_REIR  0x10 /* Input Rising Edge Interrupt Enable */
+#define XRA_FEIR  0x12 /* Input Falling Edge Interrupt Enable */
+#define XRA_IFR   0x14 /* Input Filter Enable/Disable */
+
+struct xra1403 {
+	struct gpio_chip  chip;
+	struct regmap     *regmap;
+};
+
+static const struct regmap_config xra1403_regmap_cfg = {
+		.reg_bits = 7,
+		.pad_bits = 1,
+		.val_bits = 8,
+
+		.max_register = XRA_IFR | 0x01,
+};
+
+static unsigned int to_reg(unsigned int reg, unsigned int offset)
+{
+	return reg + (offset > 7);
+}
+
+static int xra1403_direction_input(struct gpio_chip *chip, unsigned int offset)
+{
+	struct xra1403 *xra = gpiochip_get_data(chip);
+
+	return regmap_update_bits(xra->regmap, to_reg(XRA_GCR, offset),
+			BIT(offset % 8), BIT(offset % 8));
+}
+
+static int xra1403_direction_output(struct gpio_chip *chip, unsigned int offset,
+				    int value)
+{
+	int ret;
+	struct xra1403 *xra = gpiochip_get_data(chip);
+
+	ret = regmap_update_bits(xra->regmap, to_reg(XRA_GCR, offset),
+			BIT(offset % 8), 0);
+	if (ret)
+		return ret;
+
+	ret = regmap_update_bits(xra->regmap, to_reg(XRA_OCR, offset),
+			BIT(offset % 8), value ? BIT(offset % 8) : 0);
+
+	return ret;
+}
+
+static int xra1403_get_direction(struct gpio_chip *chip, unsigned int offset)
+{
+	int ret;
+	unsigned int val;
+	struct xra1403 *xra = gpiochip_get_data(chip);
+
+	ret = regmap_read(xra->regmap, to_reg(XRA_GCR, offset), &val);
+	if (ret)
+		return ret;
+
+	return !!(val & BIT(offset % 8));
+}
+
+static int xra1403_get(struct gpio_chip *chip, unsigned int offset)
+{
+	int ret;
+	unsigned int val;
+	struct xra1403 *xra = gpiochip_get_data(chip);
+
+	ret = regmap_read(xra->regmap, to_reg(XRA_GSR, offset), &val);
+	if (ret)
+		return ret;
+
+	return !!(val & BIT(offset % 8));
+}
+
+static void xra1403_set(struct gpio_chip *chip, unsigned int offset, int value)
+{
+	int ret;
+	struct xra1403 *xra = gpiochip_get_data(chip);
+
+	ret = regmap_update_bits(xra->regmap, to_reg(XRA_OCR, offset),
+			BIT(offset % 8), value ? BIT(offset % 8) : 0);
+	if (ret)
+		dev_err(chip->parent, "Failed to set pin: %d, ret: %d\n",
+				offset, ret);
+}
+
+#ifdef CONFIG_DEBUG_FS
+static void xra1403_dbg_show(struct seq_file *s, struct gpio_chip *chip)
+{
+	int reg;
+	struct xra1403 *xra = gpiochip_get_data(chip);
+	int value[xra1403_regmap_cfg.max_register];
+	int i;
+	unsigned int gcr;
+	unsigned int gsr;
+
+	seq_puts(s, "xra reg:");
+	for (reg = 0; reg <= xra1403_regmap_cfg.max_register; reg++)
+		seq_printf(s, " %2.2x", reg);
+	seq_puts(s, "\n  value:");
+	for (reg = 0; reg < xra1403_regmap_cfg.max_register; reg++) {
+		regmap_read(xra->regmap, reg, &value[reg]);
+		seq_printf(s, " %2.2x", value[reg]);
+	}
+	seq_puts(s, "\n");
+
+	gcr = value[XRA_GCR + 1] << 8 | value[XRA_GCR];
+	gsr = value[XRA_GSR + 1] << 8 | value[XRA_GSR];
+	for (i = 0; i < chip->ngpio; i++) {
+		const char *label = gpiochip_is_requested(chip, i);
+
+		if (!label)
+			continue;
+
+		seq_printf(s, " gpio-%-3d (%-12s) %s %s\n",
+			   chip->base + i, label,
+			   (gcr & BIT(i)) ? "in" : "out",
+			   (gsr & BIT(i)) ? "hi" : "lo");
+	}
+}
+#else
+#define xra1403_dbg_show NULL
+#endif
+
+static int xra1403_probe(struct spi_device *spi)
+{
+	struct xra1403 *xra;
+	struct gpio_desc *reset_gpio;
+	int ret;
+
+	xra = devm_kzalloc(&spi->dev, sizeof(*xra), GFP_KERNEL);
+	if (!xra)
+		return -ENOMEM;
+
+	/* bring the chip out of reset if reset pin is provided*/
+	reset_gpio = devm_gpiod_get_optional(&spi->dev, "reset", GPIOD_OUT_LOW);
+	if (IS_ERR(reset_gpio))
+		dev_warn(&spi->dev, "Could not get reset-gpios\n");
+
+	xra->chip.direction_input = xra1403_direction_input;
+	xra->chip.direction_output = xra1403_direction_output;
+	xra->chip.get_direction = xra1403_get_direction;
+	xra->chip.get = xra1403_get;
+	xra->chip.set = xra1403_set;
+
+	xra->chip.dbg_show = xra1403_dbg_show;
+
+	xra->chip.ngpio = 16;
+	xra->chip.label = "xra1403";
+
+	xra->chip.base = -1;
+	xra->chip.can_sleep = true;
+	xra->chip.parent = &spi->dev;
+	xra->chip.owner = THIS_MODULE;
+
+	xra->regmap = devm_regmap_init_spi(spi, &xra1403_regmap_cfg);
+	if (IS_ERR(xra->regmap)) {
+		ret = PTR_ERR(xra->regmap);
+		dev_err(&spi->dev, "Failed to allocate regmap: %d\n", ret);
+		return ret;
+	}
+
+	ret = devm_gpiochip_add_data(&spi->dev, &xra->chip, xra);
+	if (ret < 0) {
+		dev_err(&spi->dev, "Unable to register gpiochip\n");
+		return ret;
+	}
+
+	spi_set_drvdata(spi, xra);
+
+	return 0;
+}
+
+static const struct spi_device_id xra1403_ids[] = {
+	{ "xra1403" },
+	{},
+};
+MODULE_DEVICE_TABLE(spi, xra1403_ids);
+
+static const struct of_device_id xra1403_spi_of_match[] = {
+	{ .compatible = "exar,xra1403" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, xra1403_spi_of_match);
+
+static struct spi_driver xra1403_driver = {
+	.probe    = xra1403_probe,
+	.id_table = xra1403_ids,
+	.driver   = {
+		.name           = "xra1403",
+		.of_match_table = of_match_ptr(xra1403_spi_of_match),
+	},
+};
+
+module_spi_driver(xra1403_driver);
+
+MODULE_AUTHOR("Nandor Han <nandor.han-JJi787mZWgc@public.gmane.org>");
+MODULE_AUTHOR("Semi Malinen <semi.malinen-JJi787mZWgc@public.gmane.org>");
+MODULE_DESCRIPTION("GPIO expander driver for EXAR XRA1403");
+MODULE_LICENSE("GPL v2");
-- 
2.10.1

--
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 v2 1/4] dt-bindings: gpio - add exar to vendor prefixes list
From: Nandor Han @ 2017-04-13 10:27 UTC (permalink / raw)
  To: gregkh, davem, geert, mchehab, daniel.vetter, linus.walleij,
	gnurou, robh+dt, mark.rutland, linux-gpio, devicetree,
	linux-kernel
  Cc: Nandor Han
In-Reply-To: <cover.1492077070.git.nandor.han@ge.com>

Add Exar Corporation to vendors list.

Signed-off-by: Nandor Han <nandor.han@ge.com>
---
 Documentation/devicetree/bindings/vendor-prefixes.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index c7d1b72..ba9058c 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -104,6 +104,7 @@ ettus	NI Ettus Research
 eukrea  Eukréa Electromatique
 everest	Everest Semiconductor Co. Ltd.
 everspin	Everspin Technologies, Inc.
+exar	Exar Corporation
 excito	Excito
 ezchip	EZchip Semiconductor
 faraday	Faraday Technology Corporation
-- 
2.10.1


^ permalink raw reply related


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