All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/5] Add gpio support for Action Semi S900 SoC
@ 2018-05-18  2:30 ` Manivannan Sadhasivam
  0 siblings, 0 replies; 18+ messages in thread
From: Manivannan Sadhasivam @ 2018-05-18  2:30 UTC (permalink / raw)
  To: linus.walleij, robh+dt, afaerber
  Cc: liuwei, mp-cs, 96boards, devicetree, andy.shevchenko,
	daniel.thompson, amit.kucheria, linux-arm-kernel, linux-gpio,
	linux-kernel, hzhang, bdong, manivannanece23,
	Manivannan Sadhasivam

This patchset adds gpio support for Actions Semi S900 SoC by extending
the pinctrl driver. There were previous patches submitted for adding a
standalone gpio driver based on gpiolib. But later on it has been realised
that the gpio functionality is closely tied with pinctrl subsystem for this
OWL family processors. So, having a separate gpio driver will make it hard
to add further functionalities in future. Hence, we decided to drop the
previous patches below adding a standalone gpio support:

dt-bindings: gpio: Add gpio nodes for Actions S900 SoC
arm64: dts: actions: Add S900 gpio nodes
arm64: dts: actions: Add gpio line names to Bubblegum-96 board
gpio: Add gpio driver for Actions OWL S900 SoC
MAINTAINERS: Add Actions Semi S900 pinctrl and gpio entries

This patchset consits of incremental patches which will apply with the
previous pinctrl series: Add Actions Semi S900 pinctrl and gpio support,
excluding the dropped patches mentioned above.

Thanks,
Mani

Manivannan Sadhasivam (5):
  dt-bindings: pinctrl: Add gpio bindings for Actions S900 SoC
  arm64: dts: actions: Add gpio properties to pinctrl node for S900
  arm64: dts: actions: Add gpio line names to Bubblegum-96 board
  pinctrl: actions: Add gpio support for Actions S900 SoC
  MAINTAINERS: Add Actions Semi S900 pinctrl entries

 .../bindings/pinctrl/actions,s900-pinctrl.txt      |  13 ++
 MAINTAINERS                                        |   2 +
 arch/arm64/boot/dts/actions/s900-bubblegum-96.dts  | 175 +++++++++++++++++
 arch/arm64/boot/dts/actions/s900.dtsi              |   2 +
 drivers/pinctrl/actions/Kconfig                    |   1 +
 drivers/pinctrl/actions/pinctrl-owl.c              | 206 +++++++++++++++++++++
 drivers/pinctrl/actions/pinctrl-owl.h              |  20 ++
 drivers/pinctrl/actions/pinctrl-s900.c             |  29 ++-
 8 files changed, 447 insertions(+), 1 deletion(-)

-- 
2.14.1

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

* [PATCH 0/5] Add gpio support for Action Semi S900 SoC
@ 2018-05-18  2:30 ` Manivannan Sadhasivam
  0 siblings, 0 replies; 18+ messages in thread
From: Manivannan Sadhasivam @ 2018-05-18  2:30 UTC (permalink / raw)
  To: linux-arm-kernel

This patchset adds gpio support for Actions Semi S900 SoC by extending
the pinctrl driver. There were previous patches submitted for adding a
standalone gpio driver based on gpiolib. But later on it has been realised
that the gpio functionality is closely tied with pinctrl subsystem for this
OWL family processors. So, having a separate gpio driver will make it hard
to add further functionalities in future. Hence, we decided to drop the
previous patches below adding a standalone gpio support:

dt-bindings: gpio: Add gpio nodes for Actions S900 SoC
arm64: dts: actions: Add S900 gpio nodes
arm64: dts: actions: Add gpio line names to Bubblegum-96 board
gpio: Add gpio driver for Actions OWL S900 SoC
MAINTAINERS: Add Actions Semi S900 pinctrl and gpio entries

This patchset consits of incremental patches which will apply with the
previous pinctrl series: Add Actions Semi S900 pinctrl and gpio support,
excluding the dropped patches mentioned above.

Thanks,
Mani

Manivannan Sadhasivam (5):
  dt-bindings: pinctrl: Add gpio bindings for Actions S900 SoC
  arm64: dts: actions: Add gpio properties to pinctrl node for S900
  arm64: dts: actions: Add gpio line names to Bubblegum-96 board
  pinctrl: actions: Add gpio support for Actions S900 SoC
  MAINTAINERS: Add Actions Semi S900 pinctrl entries

 .../bindings/pinctrl/actions,s900-pinctrl.txt      |  13 ++
 MAINTAINERS                                        |   2 +
 arch/arm64/boot/dts/actions/s900-bubblegum-96.dts  | 175 +++++++++++++++++
 arch/arm64/boot/dts/actions/s900.dtsi              |   2 +
 drivers/pinctrl/actions/Kconfig                    |   1 +
 drivers/pinctrl/actions/pinctrl-owl.c              | 206 +++++++++++++++++++++
 drivers/pinctrl/actions/pinctrl-owl.h              |  20 ++
 drivers/pinctrl/actions/pinctrl-s900.c             |  29 ++-
 8 files changed, 447 insertions(+), 1 deletion(-)

-- 
2.14.1

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

* [PATCH 1/5] dt-bindings: pinctrl: Add gpio bindings for Actions S900 SoC
  2018-05-18  2:30 ` Manivannan Sadhasivam
@ 2018-05-18  2:30   ` Manivannan Sadhasivam
  -1 siblings, 0 replies; 18+ messages in thread
From: Manivannan Sadhasivam @ 2018-05-18  2:30 UTC (permalink / raw)
  To: linus.walleij, robh+dt, afaerber
  Cc: liuwei, mp-cs, 96boards, devicetree, andy.shevchenko,
	daniel.thompson, amit.kucheria, linux-arm-kernel, linux-gpio,
	linux-kernel, hzhang, bdong, manivannanece23,
	Manivannan Sadhasivam

Add gpio bindings for Actions Semi S900 SoC.

Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
---
 .../devicetree/bindings/pinctrl/actions,s900-pinctrl.txt    | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/Documentation/devicetree/bindings/pinctrl/actions,s900-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/actions,s900-pinctrl.txt
index fb87c7d74f2e..300a50783aab 100644
--- a/Documentation/devicetree/bindings/pinctrl/actions,s900-pinctrl.txt
+++ b/Documentation/devicetree/bindings/pinctrl/actions,s900-pinctrl.txt
@@ -8,6 +8,15 @@ Required Properties:
 - reg:          Should contain the register base address and size of
                 the pin controller.
 - clocks:       phandle of the clock feeding the pin controller
+- gpio-controller: Marks the device node as a GPIO controller.
+- #gpio-cells:     Should be two. The first cell is the gpio pin number
+                   and the second cell is used for optional parameters.
+- interrupt-controller: Marks the device node as an interrupt controller.
+- #interrupt-cells:      Specifies the number of cells needed to encode an
+                        interrupt.  Shall be set to 2.  The first cell
+                        defines the interrupt number, the second encodes
+                        the trigger flags described in
+                        bindings/interrupt-controller/interrupts.txt
 
 Please refer to pinctrl-bindings.txt in this directory for details of the
 common pinctrl bindings used by client devices, including the meaning of the
@@ -164,6 +173,10 @@ Example:
                   compatible = "actions,s900-pinctrl";
                   reg = <0x0 0xe01b0000 0x0 0x1000>;
                   clocks = <&cmu CLK_GPIO>;
+                  gpio-controller;
+                  #gpio-cells = <2>;
+                  interrupt-controller;
+                  #interrupt-cells = <2>;
 
                   uart2-default: uart2-default {
                           pinmux {
-- 
2.14.1

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

* [PATCH 1/5] dt-bindings: pinctrl: Add gpio bindings for Actions S900 SoC
@ 2018-05-18  2:30   ` Manivannan Sadhasivam
  0 siblings, 0 replies; 18+ messages in thread
From: Manivannan Sadhasivam @ 2018-05-18  2:30 UTC (permalink / raw)
  To: linux-arm-kernel

Add gpio bindings for Actions Semi S900 SoC.

Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
---
 .../devicetree/bindings/pinctrl/actions,s900-pinctrl.txt    | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/Documentation/devicetree/bindings/pinctrl/actions,s900-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/actions,s900-pinctrl.txt
index fb87c7d74f2e..300a50783aab 100644
--- a/Documentation/devicetree/bindings/pinctrl/actions,s900-pinctrl.txt
+++ b/Documentation/devicetree/bindings/pinctrl/actions,s900-pinctrl.txt
@@ -8,6 +8,15 @@ Required Properties:
 - reg:          Should contain the register base address and size of
                 the pin controller.
 - clocks:       phandle of the clock feeding the pin controller
+- gpio-controller: Marks the device node as a GPIO controller.
+- #gpio-cells:     Should be two. The first cell is the gpio pin number
+                   and the second cell is used for optional parameters.
+- interrupt-controller: Marks the device node as an interrupt controller.
+- #interrupt-cells:      Specifies the number of cells needed to encode an
+                        interrupt.  Shall be set to 2.  The first cell
+                        defines the interrupt number, the second encodes
+                        the trigger flags described in
+                        bindings/interrupt-controller/interrupts.txt
 
 Please refer to pinctrl-bindings.txt in this directory for details of the
 common pinctrl bindings used by client devices, including the meaning of the
@@ -164,6 +173,10 @@ Example:
                   compatible = "actions,s900-pinctrl";
                   reg = <0x0 0xe01b0000 0x0 0x1000>;
                   clocks = <&cmu CLK_GPIO>;
+                  gpio-controller;
+                  #gpio-cells = <2>;
+                  interrupt-controller;
+                  #interrupt-cells = <2>;
 
                   uart2-default: uart2-default {
                           pinmux {
-- 
2.14.1

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

* [PATCH 2/5] arm64: dts: actions: Add gpio properties to pinctrl node for S900
  2018-05-18  2:30 ` Manivannan Sadhasivam
@ 2018-05-18  2:30   ` Manivannan Sadhasivam
  -1 siblings, 0 replies; 18+ messages in thread
From: Manivannan Sadhasivam @ 2018-05-18  2:30 UTC (permalink / raw)
  To: linus.walleij, robh+dt, afaerber
  Cc: liuwei, mp-cs, 96boards, devicetree, andy.shevchenko,
	daniel.thompson, amit.kucheria, linux-arm-kernel, linux-gpio,
	linux-kernel, hzhang, bdong, manivannanece23,
	Manivannan Sadhasivam

Add gpio properties to pinctrl node for Actions Semi S900 SoC.

Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
---
 arch/arm64/boot/dts/actions/s900.dtsi | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/boot/dts/actions/s900.dtsi b/arch/arm64/boot/dts/actions/s900.dtsi
index 0156483f0f4d..05f31a954733 100644
--- a/arch/arm64/boot/dts/actions/s900.dtsi
+++ b/arch/arm64/boot/dts/actions/s900.dtsi
@@ -178,6 +178,8 @@
 			compatible = "actions,s900-pinctrl";
 			reg = <0x0 0xe01b0000 0x0 0x1000>;
 			clocks = <&cmu CLK_GPIO>;
+			gpio-controller;
+			#gpio-cells = <2>;
 		};
 
 		timer: timer@e0228000 {
-- 
2.14.1

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

* [PATCH 2/5] arm64: dts: actions: Add gpio properties to pinctrl node for S900
@ 2018-05-18  2:30   ` Manivannan Sadhasivam
  0 siblings, 0 replies; 18+ messages in thread
From: Manivannan Sadhasivam @ 2018-05-18  2:30 UTC (permalink / raw)
  To: linux-arm-kernel

Add gpio properties to pinctrl node for Actions Semi S900 SoC.

Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
---
 arch/arm64/boot/dts/actions/s900.dtsi | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/boot/dts/actions/s900.dtsi b/arch/arm64/boot/dts/actions/s900.dtsi
index 0156483f0f4d..05f31a954733 100644
--- a/arch/arm64/boot/dts/actions/s900.dtsi
+++ b/arch/arm64/boot/dts/actions/s900.dtsi
@@ -178,6 +178,8 @@
 			compatible = "actions,s900-pinctrl";
 			reg = <0x0 0xe01b0000 0x0 0x1000>;
 			clocks = <&cmu CLK_GPIO>;
+			gpio-controller;
+			#gpio-cells = <2>;
 		};
 
 		timer: timer at e0228000 {
-- 
2.14.1

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

* [PATCH 3/5] arm64: dts: actions: Add gpio line names to Bubblegum-96 board
  2018-05-18  2:30 ` Manivannan Sadhasivam
@ 2018-05-18  2:30   ` Manivannan Sadhasivam
  -1 siblings, 0 replies; 18+ messages in thread
From: Manivannan Sadhasivam @ 2018-05-18  2:30 UTC (permalink / raw)
  To: linus.walleij, robh+dt, afaerber
  Cc: liuwei, mp-cs, 96boards, devicetree, andy.shevchenko,
	daniel.thompson, amit.kucheria, linux-arm-kernel, linux-gpio,
	linux-kernel, hzhang, bdong, manivannanece23,
	Manivannan Sadhasivam

Add gpio line names to Actions Semi S900 based Bubblegum-96 board.

Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
---
 arch/arm64/boot/dts/actions/s900-bubblegum-96.dts | 175 ++++++++++++++++++++++
 1 file changed, 175 insertions(+)

diff --git a/arch/arm64/boot/dts/actions/s900-bubblegum-96.dts b/arch/arm64/boot/dts/actions/s900-bubblegum-96.dts
index ff043c961d75..d0ba35df9015 100644
--- a/arch/arm64/boot/dts/actions/s900-bubblegum-96.dts
+++ b/arch/arm64/boot/dts/actions/s900-bubblegum-96.dts
@@ -34,3 +34,178 @@
 	status = "okay";
 	clocks = <&cmu CLK_UART5>;
 };
+
+/*
+ * GPIO name legend: proper name = the GPIO line is used as GPIO
+ *         NC = not connected (pin out but not routed from the chip to
+ *              anything the board)
+ *         "[PER]" = pin is muxed for [peripheral] (not GPIO)
+ *         LSEC = Low Speed External Connector
+ *         HSEC = High Speed External Connector
+ *
+ * Line names are taken from the schematic "Schematics Bubblegum96"
+ * version v1.0
+ *
+ * For the lines routed to the external connectors the
+ * lines are named after the 96Boards CE Specification 1.0,
+ * Appendix "Expansion Connector Signal Description".
+ *
+ * When the 96Boards naming of a line and the schematic name of
+ * the same line are in conflict, the 96Boards specification
+ * takes precedence, which means that the external UART on the
+ * LSEC is named UART0 while the schematic and SoC names this
+ * UART2. Only exception is the I2C lines for which the schematic
+ * naming has been preferred. This is only for the informational
+ * lines i.e. "[FOO]", the GPIO named lines "GPIO-A" thru "GPIO-L"
+ * are the only ones actually used for GPIO.
+ */
+
+&pinctrl {
+	gpio-line-names =
+		"GPIO-A", /* GPIO_0, LSEC pin 23 */
+		"GPIO-B", /* GPIO_1, LSEC pin 24 */
+		"GPIO-C", /* GPIO_2, LSEC pin 25 */
+		"GPIO-D", /* GPIO_3, LSEC pin 26 */
+		"GPIO-E", /* GPIO_4, LSEC pin 27 */
+		"GPIO-F", /* GPIO_5, LSEC pin 28 */
+		"GPIO-G", /* GPIO_6, LSEC pin 29 */
+		"GPIO-H", /* GPIO_7, LSEC pin 30 */
+		"GPIO-I", /* GPIO_8, LSEC pin 31 */
+		"GPIO-J", /* GPIO_9, LSEC pin 32 */
+		"NC", /* GPIO_10 */
+		"NC", /* GPIO_11 */
+		"SIRQ2_1V8", /* GPIO_12 */
+		"PCM0_OUT", /* GPIO_13 */
+		"WIFI_LED", /* GPIO_14 */
+		"PCM0_SYNC", /* GPIO_15 */
+		"PCM0_CLK", /* GPIO_16 */
+		"PCM0_IN", /* GPIO_17 */
+		"BT_LED", /* GPIO_18 */
+		"LED0", /* GPIO_19 */
+		"LED1", /* GPIO_20 */
+		"JTAG_TCK", /* GPIO_21 */
+		"JTAG_TMS", /* GPIO_22 */
+		"JTAG_TDI", /* GPIO_23 */
+		"JTAG_TDO", /* GPIO_24 */
+		"[UART1_RxD]", /* GPIO_25, LSEC pin 13 */
+		"NC", /* GPIO_26 */
+		"[UART1_TxD]", /* GPIO_27, LSEC pin 11 */
+		"SD0_D0", /* GPIO_28 */
+		"SD0_D1", /* GPIO_29 */
+		"SD0_D2", /* GPIO_30 */
+		"SD0_D3", /* GPIO_31 */
+		"SD1_D0", /* GPIO_32 */
+		"SD1_D1", /* GPIO_33 */
+		"SD1_D2", /* GPIO_34 */
+		"SD1_D3", /* GPIO_35 */
+		"SD0_CMD", /* GPIO_36 */
+		"SD0_CLK", /* GPIO_37 */
+		"SD1_CMD", /* GPIO_38 */
+		"SD1_CLK", /* GPIO_39 */
+		"SPI0_SCLK", /* GPIO_40, LSEC pin 8 */
+		"SPI0_CS", /* GPIO_41, LSEC pin 12 */
+		"SPI0_DIN", /* GPIO_42, LSEC pin 10 */
+		"SPI0_DOUT", /* GPIO_43, LSEC pin 14 */
+		"I2C5_SDATA", /* GPIO_44, HSEC pin 36 */
+		"I2C5_SCLK", /* GPIO_45, HSEC pin 38 */
+		"UART0_RX", /* GPIO_46, LSEC pin 7 */
+		"UART0_TX", /* GPIO_47, LSEC pin 5 */
+		"UART0_RTSB", /* GPIO_48, LSEC pin 9 */
+		"UART0_CTSB", /* GPIO_49, LSEC pin 3 */
+		"I2C4_SCLK", /* GPIO_50, HSEC pin 32 */
+		"I2C4_SDATA", /* GPIO_51, HSEC pin 34 */
+		"I2C0_SCLK", /* GPIO_52 */
+		"I2C0_SDATA", /* GPIO_53 */
+		"I2C1_SCLK", /* GPIO_54, LSEC pin 15 */
+		"I2C1_SDATA", /* GPIO_55, LSEC pin 17 */
+		"I2C2_SCLK", /* GPIO_56, LSEC pin 19 */
+		"I2C2_SDATA", /* GPIO_57, LSEC pin 21 */
+		"CSI0_DN0", /* GPIO_58, HSEC pin 10 */
+		"CSI0_DP0", /* GPIO_59, HSEC pin 8 */
+		"CSI0_DN1", /* GPIO_60, HSEC pin 16 */
+		"CSI0_DP1", /* GPIO_61, HSEC pin 14 */
+		"CSI0_CN", /* GPIO_62, HSEC pin 4 */
+		"CSI0_CP", /* GPIO_63, HSEC pin 2 */
+		"CSI0_DN2", /* GPIO_64, HSEC pin 22 */
+		"CSI0_DP2", /* GPIO_65, HSEC pin 20 */
+		"CSI0_DN3", /* GPIO_66, HSEC pin 28 */
+		"CSI0_DP3", /* GPIO_67, HSEC pin 26 */
+		"[CLK0]", /* GPIO_68, HSEC pin 15 */
+		"CSI1_DN0", /* GPIO_69, HSEC pin 44 */
+		"CSI1_DP0", /* GPIO_70, HSEC pin 42 */
+		"CSI1_DN1", /* GPIO_71, HSEC pin 50 */
+		"CSI1_DP1", /* GPIO_72, HSEC pin 48 */
+		"CSI1_CN", /* GPIO_73, HSEC pin 56 */
+		"CSI1_CP", /* GPIO_74, HSEC pin 54 */
+		"[CLK1]", /* GPIO_75, HSEC pin 17 */
+		"[GPIOD0]", /* GPIO_76 */
+		"[GPIOD1]", /* GPIO_77 */
+		"BT_RST_N", /* GPIO_78 */
+		"EXT_DC_EN", /* GPIO_79 */
+		"[PCM_DI]", /* GPIO_80, LSEC pin 22 */
+		"[PCM_DO]", /* GPIO_81, LSEC pin 20 */
+		"[PCM_CLK]", /* GPIO_82, LSEC pin 18 */
+		"[PCM_FS]", /* GPIO_83, LSEC pin 16 */
+		"WAKE_BT", /* GPIO_84 */
+		"WL_REG_ON", /* GPIO_85 */
+		"NC", /* GPIO_86 */
+		"NC", /* GPIO_87 */
+		"NC", /* GPIO_88 */
+		"NC", /* GPIO_89 */
+		"NC", /* GPIO_90 */
+		"WIFI_WAKE", /* GPIO_91 */
+		"BT_WAKE", /* GPIO_92 */
+		"NC", /* GPIO_93 */
+		"OTG_EN2", /* GPIO_94 */
+		"OTG_EN", /* GPIO_95 */
+		"DSI_DP3", /* GPIO_96, HSEC pin 45 */
+		"DSI_DN3", /* GPIO_97, HSEC pin 47 */
+		"DSI_DP1", /* GPIO_98, HSEC pin 33 */
+		"DSI_DN1", /* GPIO_99, HSEC pin 35 */
+		"DSI_CP", /* GPIO_100, HSEC pin 21 */
+		"DSI_CN", /* GPIO_101, HSEC pin 23 */
+		"DSI_DP0", /* GPIO_102, HSEC pin 27 */
+		"DSI_DN0", /* GPIO_103, HSEC pin 29 */
+		"DSI_DP2", /* GPIO_104, HSEC pin 39 */
+		"DSI_DN2", /* GPIO_105, HSEC pin 41 */
+		"N0_D0", /* GPIO_106 */
+		"N0_D1", /* GPIO_107 */
+		"N0_D2", /* GPIO_108 */
+		"N0_D3", /* GPIO_109 */
+		"N0_D4", /* GPIO_110 */
+		"N0_D5", /* GPIO_111 */
+		"N0_D6", /* GPIO_112 */
+		"N0_D7", /* GPIO_113 */
+		"N0_DQS", /* GPIO_114 */
+		"N0_DQSN", /* GPIO_115 */
+		"NC", /* GPIO_116 */
+		"NC", /* GPIO_117 */
+		"NC", /* GPIO_118 */
+		"N0_CEB1", /* GPIO_119 */
+		"CARD_DT", /* GPIO_120 */
+		"N0_CEB3", /* GPIO_121 */
+		"SD_DAT0", /* GPIO_122, HSEC pin 1 */
+		"SD_DAT1", /* GPIO_123, HSEC pin 3 */
+		"SD_DAT2", /* GPIO_124, HSEC pin 5 */
+		"SD_DAT3", /* GPIO_125, HSEC pin 7 */
+		"NC", /* GPIO_126 */
+		"NC", /* GPIO_127 */
+		"[PWR_BTN_N]", /* GPIO_128, LSEC pin 4 */
+		"[RST_BTN_N]", /* GPIO_129, LSEC pin 6 */
+		"NC", /* GPIO_130 */
+		"SD_CMD", /* GPIO_131 */
+		"GPIO-L", /* GPIO_132, LSEC pin 34 */
+		"GPIO-K", /* GPIO_133, LSEC pin 33 */
+		"NC", /* GPIO_134 */
+		"SD_SCLK", /* GPIO_135 */
+		"NC", /* GPIO_136 */
+		"JTAG_TRST", /* GPIO_137 */
+		"I2C3_SCLK", /* GPIO_138 */
+		"LED2", /* GPIO_139 */
+		"LED3", /* GPIO_140 */
+		"I2C3_SDATA", /* GPIO_141 */
+		"UART3_RX", /* GPIO_142 */
+		"UART3_TX", /* GPIO_143 */
+		"UART3_RTSB", /* GPIO_144 */
+		"UART3_CTSB"; /* GPIO_145 */
+};
-- 
2.14.1

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

* [PATCH 3/5] arm64: dts: actions: Add gpio line names to Bubblegum-96 board
@ 2018-05-18  2:30   ` Manivannan Sadhasivam
  0 siblings, 0 replies; 18+ messages in thread
From: Manivannan Sadhasivam @ 2018-05-18  2:30 UTC (permalink / raw)
  To: linux-arm-kernel

Add gpio line names to Actions Semi S900 based Bubblegum-96 board.

Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
---
 arch/arm64/boot/dts/actions/s900-bubblegum-96.dts | 175 ++++++++++++++++++++++
 1 file changed, 175 insertions(+)

diff --git a/arch/arm64/boot/dts/actions/s900-bubblegum-96.dts b/arch/arm64/boot/dts/actions/s900-bubblegum-96.dts
index ff043c961d75..d0ba35df9015 100644
--- a/arch/arm64/boot/dts/actions/s900-bubblegum-96.dts
+++ b/arch/arm64/boot/dts/actions/s900-bubblegum-96.dts
@@ -34,3 +34,178 @@
 	status = "okay";
 	clocks = <&cmu CLK_UART5>;
 };
+
+/*
+ * GPIO name legend: proper name = the GPIO line is used as GPIO
+ *         NC = not connected (pin out but not routed from the chip to
+ *              anything the board)
+ *         "[PER]" = pin is muxed for [peripheral] (not GPIO)
+ *         LSEC = Low Speed External Connector
+ *         HSEC = High Speed External Connector
+ *
+ * Line names are taken from the schematic "Schematics Bubblegum96"
+ * version v1.0
+ *
+ * For the lines routed to the external connectors the
+ * lines are named after the 96Boards CE Specification 1.0,
+ * Appendix "Expansion Connector Signal Description".
+ *
+ * When the 96Boards naming of a line and the schematic name of
+ * the same line are in conflict, the 96Boards specification
+ * takes precedence, which means that the external UART on the
+ * LSEC is named UART0 while the schematic and SoC names this
+ * UART2. Only exception is the I2C lines for which the schematic
+ * naming has been preferred. This is only for the informational
+ * lines i.e. "[FOO]", the GPIO named lines "GPIO-A" thru "GPIO-L"
+ * are the only ones actually used for GPIO.
+ */
+
+&pinctrl {
+	gpio-line-names =
+		"GPIO-A", /* GPIO_0, LSEC pin 23 */
+		"GPIO-B", /* GPIO_1, LSEC pin 24 */
+		"GPIO-C", /* GPIO_2, LSEC pin 25 */
+		"GPIO-D", /* GPIO_3, LSEC pin 26 */
+		"GPIO-E", /* GPIO_4, LSEC pin 27 */
+		"GPIO-F", /* GPIO_5, LSEC pin 28 */
+		"GPIO-G", /* GPIO_6, LSEC pin 29 */
+		"GPIO-H", /* GPIO_7, LSEC pin 30 */
+		"GPIO-I", /* GPIO_8, LSEC pin 31 */
+		"GPIO-J", /* GPIO_9, LSEC pin 32 */
+		"NC", /* GPIO_10 */
+		"NC", /* GPIO_11 */
+		"SIRQ2_1V8", /* GPIO_12 */
+		"PCM0_OUT", /* GPIO_13 */
+		"WIFI_LED", /* GPIO_14 */
+		"PCM0_SYNC", /* GPIO_15 */
+		"PCM0_CLK", /* GPIO_16 */
+		"PCM0_IN", /* GPIO_17 */
+		"BT_LED", /* GPIO_18 */
+		"LED0", /* GPIO_19 */
+		"LED1", /* GPIO_20 */
+		"JTAG_TCK", /* GPIO_21 */
+		"JTAG_TMS", /* GPIO_22 */
+		"JTAG_TDI", /* GPIO_23 */
+		"JTAG_TDO", /* GPIO_24 */
+		"[UART1_RxD]", /* GPIO_25, LSEC pin 13 */
+		"NC", /* GPIO_26 */
+		"[UART1_TxD]", /* GPIO_27, LSEC pin 11 */
+		"SD0_D0", /* GPIO_28 */
+		"SD0_D1", /* GPIO_29 */
+		"SD0_D2", /* GPIO_30 */
+		"SD0_D3", /* GPIO_31 */
+		"SD1_D0", /* GPIO_32 */
+		"SD1_D1", /* GPIO_33 */
+		"SD1_D2", /* GPIO_34 */
+		"SD1_D3", /* GPIO_35 */
+		"SD0_CMD", /* GPIO_36 */
+		"SD0_CLK", /* GPIO_37 */
+		"SD1_CMD", /* GPIO_38 */
+		"SD1_CLK", /* GPIO_39 */
+		"SPI0_SCLK", /* GPIO_40, LSEC pin 8 */
+		"SPI0_CS", /* GPIO_41, LSEC pin 12 */
+		"SPI0_DIN", /* GPIO_42, LSEC pin 10 */
+		"SPI0_DOUT", /* GPIO_43, LSEC pin 14 */
+		"I2C5_SDATA", /* GPIO_44, HSEC pin 36 */
+		"I2C5_SCLK", /* GPIO_45, HSEC pin 38 */
+		"UART0_RX", /* GPIO_46, LSEC pin 7 */
+		"UART0_TX", /* GPIO_47, LSEC pin 5 */
+		"UART0_RTSB", /* GPIO_48, LSEC pin 9 */
+		"UART0_CTSB", /* GPIO_49, LSEC pin 3 */
+		"I2C4_SCLK", /* GPIO_50, HSEC pin 32 */
+		"I2C4_SDATA", /* GPIO_51, HSEC pin 34 */
+		"I2C0_SCLK", /* GPIO_52 */
+		"I2C0_SDATA", /* GPIO_53 */
+		"I2C1_SCLK", /* GPIO_54, LSEC pin 15 */
+		"I2C1_SDATA", /* GPIO_55, LSEC pin 17 */
+		"I2C2_SCLK", /* GPIO_56, LSEC pin 19 */
+		"I2C2_SDATA", /* GPIO_57, LSEC pin 21 */
+		"CSI0_DN0", /* GPIO_58, HSEC pin 10 */
+		"CSI0_DP0", /* GPIO_59, HSEC pin 8 */
+		"CSI0_DN1", /* GPIO_60, HSEC pin 16 */
+		"CSI0_DP1", /* GPIO_61, HSEC pin 14 */
+		"CSI0_CN", /* GPIO_62, HSEC pin 4 */
+		"CSI0_CP", /* GPIO_63, HSEC pin 2 */
+		"CSI0_DN2", /* GPIO_64, HSEC pin 22 */
+		"CSI0_DP2", /* GPIO_65, HSEC pin 20 */
+		"CSI0_DN3", /* GPIO_66, HSEC pin 28 */
+		"CSI0_DP3", /* GPIO_67, HSEC pin 26 */
+		"[CLK0]", /* GPIO_68, HSEC pin 15 */
+		"CSI1_DN0", /* GPIO_69, HSEC pin 44 */
+		"CSI1_DP0", /* GPIO_70, HSEC pin 42 */
+		"CSI1_DN1", /* GPIO_71, HSEC pin 50 */
+		"CSI1_DP1", /* GPIO_72, HSEC pin 48 */
+		"CSI1_CN", /* GPIO_73, HSEC pin 56 */
+		"CSI1_CP", /* GPIO_74, HSEC pin 54 */
+		"[CLK1]", /* GPIO_75, HSEC pin 17 */
+		"[GPIOD0]", /* GPIO_76 */
+		"[GPIOD1]", /* GPIO_77 */
+		"BT_RST_N", /* GPIO_78 */
+		"EXT_DC_EN", /* GPIO_79 */
+		"[PCM_DI]", /* GPIO_80, LSEC pin 22 */
+		"[PCM_DO]", /* GPIO_81, LSEC pin 20 */
+		"[PCM_CLK]", /* GPIO_82, LSEC pin 18 */
+		"[PCM_FS]", /* GPIO_83, LSEC pin 16 */
+		"WAKE_BT", /* GPIO_84 */
+		"WL_REG_ON", /* GPIO_85 */
+		"NC", /* GPIO_86 */
+		"NC", /* GPIO_87 */
+		"NC", /* GPIO_88 */
+		"NC", /* GPIO_89 */
+		"NC", /* GPIO_90 */
+		"WIFI_WAKE", /* GPIO_91 */
+		"BT_WAKE", /* GPIO_92 */
+		"NC", /* GPIO_93 */
+		"OTG_EN2", /* GPIO_94 */
+		"OTG_EN", /* GPIO_95 */
+		"DSI_DP3", /* GPIO_96, HSEC pin 45 */
+		"DSI_DN3", /* GPIO_97, HSEC pin 47 */
+		"DSI_DP1", /* GPIO_98, HSEC pin 33 */
+		"DSI_DN1", /* GPIO_99, HSEC pin 35 */
+		"DSI_CP", /* GPIO_100, HSEC pin 21 */
+		"DSI_CN", /* GPIO_101, HSEC pin 23 */
+		"DSI_DP0", /* GPIO_102, HSEC pin 27 */
+		"DSI_DN0", /* GPIO_103, HSEC pin 29 */
+		"DSI_DP2", /* GPIO_104, HSEC pin 39 */
+		"DSI_DN2", /* GPIO_105, HSEC pin 41 */
+		"N0_D0", /* GPIO_106 */
+		"N0_D1", /* GPIO_107 */
+		"N0_D2", /* GPIO_108 */
+		"N0_D3", /* GPIO_109 */
+		"N0_D4", /* GPIO_110 */
+		"N0_D5", /* GPIO_111 */
+		"N0_D6", /* GPIO_112 */
+		"N0_D7", /* GPIO_113 */
+		"N0_DQS", /* GPIO_114 */
+		"N0_DQSN", /* GPIO_115 */
+		"NC", /* GPIO_116 */
+		"NC", /* GPIO_117 */
+		"NC", /* GPIO_118 */
+		"N0_CEB1", /* GPIO_119 */
+		"CARD_DT", /* GPIO_120 */
+		"N0_CEB3", /* GPIO_121 */
+		"SD_DAT0", /* GPIO_122, HSEC pin 1 */
+		"SD_DAT1", /* GPIO_123, HSEC pin 3 */
+		"SD_DAT2", /* GPIO_124, HSEC pin 5 */
+		"SD_DAT3", /* GPIO_125, HSEC pin 7 */
+		"NC", /* GPIO_126 */
+		"NC", /* GPIO_127 */
+		"[PWR_BTN_N]", /* GPIO_128, LSEC pin 4 */
+		"[RST_BTN_N]", /* GPIO_129, LSEC pin 6 */
+		"NC", /* GPIO_130 */
+		"SD_CMD", /* GPIO_131 */
+		"GPIO-L", /* GPIO_132, LSEC pin 34 */
+		"GPIO-K", /* GPIO_133, LSEC pin 33 */
+		"NC", /* GPIO_134 */
+		"SD_SCLK", /* GPIO_135 */
+		"NC", /* GPIO_136 */
+		"JTAG_TRST", /* GPIO_137 */
+		"I2C3_SCLK", /* GPIO_138 */
+		"LED2", /* GPIO_139 */
+		"LED3", /* GPIO_140 */
+		"I2C3_SDATA", /* GPIO_141 */
+		"UART3_RX", /* GPIO_142 */
+		"UART3_TX", /* GPIO_143 */
+		"UART3_RTSB", /* GPIO_144 */
+		"UART3_CTSB"; /* GPIO_145 */
+};
-- 
2.14.1

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

* [PATCH 4/5] pinctrl: actions: Add gpio support for Actions S900 SoC
  2018-05-18  2:30 ` Manivannan Sadhasivam
@ 2018-05-18  2:30   ` Manivannan Sadhasivam
  -1 siblings, 0 replies; 18+ messages in thread
From: Manivannan Sadhasivam @ 2018-05-18  2:30 UTC (permalink / raw)
  To: linus.walleij, robh+dt, afaerber
  Cc: liuwei, mp-cs, 96boards, devicetree, andy.shevchenko,
	daniel.thompson, amit.kucheria, linux-arm-kernel, linux-gpio,
	linux-kernel, hzhang, bdong, manivannanece23,
	Manivannan Sadhasivam

Add gpio support to pinctrl driver for Actions Semi S900 SoC.

Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
---
 drivers/pinctrl/actions/Kconfig        |   1 +
 drivers/pinctrl/actions/pinctrl-owl.c  | 206 +++++++++++++++++++++++++++++++++
 drivers/pinctrl/actions/pinctrl-owl.h  |  20 ++++
 drivers/pinctrl/actions/pinctrl-s900.c |  29 ++++-
 4 files changed, 255 insertions(+), 1 deletion(-)

diff --git a/drivers/pinctrl/actions/Kconfig b/drivers/pinctrl/actions/Kconfig
index ede97cdbbc12..490927b4ea76 100644
--- a/drivers/pinctrl/actions/Kconfig
+++ b/drivers/pinctrl/actions/Kconfig
@@ -4,6 +4,7 @@ config PINCTRL_OWL
 	select PINMUX
 	select PINCONF
 	select GENERIC_PINCONF
+	select GPIOLIB
 	help
 	  Say Y here to enable Actions Semi OWL pinctrl driver
 
diff --git a/drivers/pinctrl/actions/pinctrl-owl.c b/drivers/pinctrl/actions/pinctrl-owl.c
index ee090697b1e9..4942e34c8b76 100644
--- a/drivers/pinctrl/actions/pinctrl-owl.c
+++ b/drivers/pinctrl/actions/pinctrl-owl.c
@@ -11,6 +11,7 @@
 
 #include <linux/clk.h>
 #include <linux/err.h>
+#include <linux/gpio/driver.h>
 #include <linux/io.h>
 #include <linux/module.h>
 #include <linux/of.h>
@@ -31,6 +32,7 @@
  * struct owl_pinctrl - pinctrl state of the device
  * @dev: device handle
  * @pctrldev: pinctrl handle
+ * @chip: gpio chip
  * @lock: spinlock to protect registers
  * @soc: reference to soc_data
  * @base: pinctrl register base address
@@ -38,6 +40,7 @@
 struct owl_pinctrl {
 	struct device *dev;
 	struct pinctrl_dev *pctrldev;
+	struct gpio_chip chip;
 	raw_spinlock_t lock;
 	struct clk *clk;
 	const struct owl_pinctrl_soc_data *soc;
@@ -536,6 +539,198 @@ static struct pinctrl_desc owl_pinctrl_desc = {
 	.owner = THIS_MODULE,
 };
 
+static const struct owl_gpio_port *
+owl_gpio_get_port(struct owl_pinctrl *pctrl, unsigned int *pin)
+{
+	unsigned int start = 0, i;
+
+	for (i = 0; i < pctrl->soc->nports; i++) {
+		const struct owl_gpio_port *port = &pctrl->soc->ports[i];
+
+		if (*pin >= start && *pin < start + port->pins) {
+			*pin -= start;
+			return port;
+		}
+
+		start += port->pins;
+	}
+
+	return NULL;
+}
+
+static void owl_gpio_update_reg(void __iomem *base, unsigned int pin, int flag)
+{
+	u32 val;
+
+	val = readl_relaxed(base);
+
+	if (flag)
+		val |= BIT(pin);
+	else
+		val &= ~BIT(pin);
+
+	writel_relaxed(val, base);
+}
+
+static int owl_gpio_request(struct gpio_chip *chip, unsigned int offset)
+{
+	struct owl_pinctrl *pctrl = gpiochip_get_data(chip);
+	const struct owl_gpio_port *port;
+	void __iomem *gpio_base;
+	unsigned long flags;
+
+	port = owl_gpio_get_port(pctrl, &offset);
+	if (WARN_ON(port == NULL))
+		return -ENODEV;
+
+	gpio_base = pctrl->base + port->offset;
+
+	/*
+	 * GPIOs have higher priority over other modules, so either setting
+	 * them as OUT or IN is sufficient
+	 */
+	raw_spin_lock_irqsave(&pctrl->lock, flags);
+	owl_gpio_update_reg(gpio_base + port->outen, offset, true);
+	raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+
+	return 0;
+}
+
+static void owl_gpio_free(struct gpio_chip *chip, unsigned int offset)
+{
+	struct owl_pinctrl *pctrl = gpiochip_get_data(chip);
+	const struct owl_gpio_port *port;
+	void __iomem *gpio_base;
+	unsigned long flags;
+
+	port = owl_gpio_get_port(pctrl, &offset);
+	if (WARN_ON(port == NULL))
+		return;
+
+	gpio_base = pctrl->base + port->offset;
+
+	raw_spin_lock_irqsave(&pctrl->lock, flags);
+	/* disable gpio output */
+	owl_gpio_update_reg(gpio_base + port->outen, offset, false);
+
+	/* disable gpio input */
+	owl_gpio_update_reg(gpio_base + port->inen, offset, false);
+	raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+}
+
+static int owl_gpio_get(struct gpio_chip *chip, unsigned int offset)
+{
+	struct owl_pinctrl *pctrl = gpiochip_get_data(chip);
+	const struct owl_gpio_port *port;
+	void __iomem *gpio_base;
+	unsigned long flags;
+	u32 val;
+
+	port = owl_gpio_get_port(pctrl, &offset);
+	if (WARN_ON(port == NULL))
+		return -ENODEV;
+
+	gpio_base = pctrl->base + port->offset;
+
+	raw_spin_lock_irqsave(&pctrl->lock, flags);
+	val = readl_relaxed(gpio_base + port->dat);
+	raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+
+	return !!(val & BIT(offset));
+}
+
+static void owl_gpio_set(struct gpio_chip *chip, unsigned int offset, int value)
+{
+	struct owl_pinctrl *pctrl = gpiochip_get_data(chip);
+	const struct owl_gpio_port *port;
+	void __iomem *gpio_base;
+	unsigned long flags;
+
+	port = owl_gpio_get_port(pctrl, &offset);
+	if (WARN_ON(port == NULL))
+		return;
+
+	gpio_base = pctrl->base + port->offset;
+
+	raw_spin_lock_irqsave(&pctrl->lock, flags);
+	owl_gpio_update_reg(gpio_base + port->dat, offset, value);
+	raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+}
+
+static int owl_gpio_direction_input(struct gpio_chip *chip, unsigned int offset)
+{
+	struct owl_pinctrl *pctrl = gpiochip_get_data(chip);
+	const struct owl_gpio_port *port;
+	void __iomem *gpio_base;
+	unsigned long flags;
+
+	port = owl_gpio_get_port(pctrl, &offset);
+	if (WARN_ON(port == NULL))
+		return -ENODEV;
+
+	gpio_base = pctrl->base + port->offset;
+
+	raw_spin_lock_irqsave(&pctrl->lock, flags);
+	owl_gpio_update_reg(gpio_base + port->outen, offset, false);
+	owl_gpio_update_reg(gpio_base + port->inen, offset, true);
+	raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+
+	return 0;
+}
+
+static int owl_gpio_direction_output(struct gpio_chip *chip,
+				unsigned int offset, int value)
+{
+	struct owl_pinctrl *pctrl = gpiochip_get_data(chip);
+	const struct owl_gpio_port *port;
+	void __iomem *gpio_base;
+	unsigned long flags;
+
+	port = owl_gpio_get_port(pctrl, &offset);
+	if (WARN_ON(port == NULL))
+		return -ENODEV;
+
+	gpio_base = pctrl->base + port->offset;
+
+	raw_spin_lock_irqsave(&pctrl->lock, flags);
+	owl_gpio_update_reg(gpio_base + port->inen, offset, false);
+	owl_gpio_update_reg(gpio_base + port->outen, offset, true);
+	owl_gpio_update_reg(gpio_base + port->dat, offset, value);
+	raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+
+	return 0;
+}
+
+static int owl_gpio_init(struct owl_pinctrl *pctrl)
+{
+	struct gpio_chip *chip;
+	int ret;
+
+	chip = &pctrl->chip;
+	chip->base = -1;
+	chip->ngpio = pctrl->soc->ngpios;
+	chip->label = dev_name(pctrl->dev);
+	chip->parent = pctrl->dev;
+	chip->owner = THIS_MODULE;
+	chip->of_node = pctrl->dev->of_node;
+
+	ret = gpiochip_add_data(&pctrl->chip, pctrl);
+	if (ret) {
+		dev_err(pctrl->dev, "failed to register gpiochip\n");
+		return ret;
+	}
+
+	ret = gpiochip_add_pin_range(&pctrl->chip, dev_name(pctrl->dev),
+							0, 0, chip->ngpio);
+	if (ret) {
+		dev_err(pctrl->dev, "failed to add pin range\n");
+		gpiochip_remove(&pctrl->chip);
+		return ret;
+	}
+
+	return 0;
+}
+
 int owl_pinctrl_probe(struct platform_device *pdev,
 				struct owl_pinctrl_soc_data *soc_data)
 {
@@ -571,6 +766,13 @@ int owl_pinctrl_probe(struct platform_device *pdev,
 	owl_pinctrl_desc.pins = soc_data->pins;
 	owl_pinctrl_desc.npins = soc_data->npins;
 
+	pctrl->chip.direction_input  = owl_gpio_direction_input;
+	pctrl->chip.direction_output = owl_gpio_direction_output;
+	pctrl->chip.get = owl_gpio_get;
+	pctrl->chip.set = owl_gpio_set;
+	pctrl->chip.request = owl_gpio_request;
+	pctrl->chip.free = owl_gpio_free;
+
 	pctrl->soc = soc_data;
 	pctrl->dev = &pdev->dev;
 
@@ -581,6 +783,10 @@ int owl_pinctrl_probe(struct platform_device *pdev,
 		return PTR_ERR(pctrl->pctrldev);
 	}
 
+	ret = owl_gpio_init(pctrl);
+	if (ret)
+		return ret;
+
 	platform_set_drvdata(pdev, pctrl);
 
 	return 0;
diff --git a/drivers/pinctrl/actions/pinctrl-owl.h b/drivers/pinctrl/actions/pinctrl-owl.h
index 448f81a6db3b..74342378937c 100644
--- a/drivers/pinctrl/actions/pinctrl-owl.h
+++ b/drivers/pinctrl/actions/pinctrl-owl.h
@@ -114,6 +114,22 @@ struct owl_pinmux_func {
 	unsigned int ngroups;
 };
 
+/**
+ * struct owl_gpio_port - Actions GPIO port info
+ * @offset: offset of the GPIO port.
+ * @pins: number of pins belongs to the GPIO port.
+ * @outen: offset of the output enable register.
+ * @inen: offset of the input enable register.
+ * @dat: offset of the data register.
+ */
+struct owl_gpio_port {
+	unsigned int offset;
+	unsigned int pins;
+	unsigned int outen;
+	unsigned int inen;
+	unsigned int dat;
+};
+
 /**
  * struct owl_pinctrl_soc_data - Actions pin controller driver configuration
  * @pins: array describing all pins of the pin controller.
@@ -124,6 +140,8 @@ struct owl_pinmux_func {
  * @ngroups: number of entries in @groups.
  * @padinfo: array describing the pad info of this SoC.
  * @ngpios: number of pingroups the driver should expose as GPIOs.
+ * @port: array describing all GPIO ports of this SoC.
+ * @nports: number of GPIO ports in this SoC.
  */
 struct owl_pinctrl_soc_data {
 	const struct pinctrl_pin_desc *pins;
@@ -134,6 +152,8 @@ struct owl_pinctrl_soc_data {
 	unsigned int ngroups;
 	const struct owl_padinfo *padinfo;
 	unsigned int ngpios;
+	const struct owl_gpio_port *ports;
+	unsigned int nports;
 };
 
 int owl_pinctrl_probe(struct platform_device *pdev,
diff --git a/drivers/pinctrl/actions/pinctrl-s900.c b/drivers/pinctrl/actions/pinctrl-s900.c
index 08d93f8fc086..5503c7945764 100644
--- a/drivers/pinctrl/actions/pinctrl-s900.c
+++ b/drivers/pinctrl/actions/pinctrl-s900.c
@@ -33,6 +33,13 @@
 #define PAD_SR1			(0x0274)
 #define PAD_SR2			(0x0278)
 
+#define OWL_GPIO_PORT_A		0
+#define OWL_GPIO_PORT_B		1
+#define OWL_GPIO_PORT_C		2
+#define OWL_GPIO_PORT_D		3
+#define OWL_GPIO_PORT_E		4
+#define OWL_GPIO_PORT_F		5
+
 #define _GPIOA(offset)		(offset)
 #define _GPIOB(offset)		(32 + (offset))
 #define _GPIOC(offset)		(64 + (offset))
@@ -1814,6 +1821,24 @@ static struct owl_padinfo s900_padinfo[NUM_PADS] = {
 	[SGPIO3] = PAD_INFO_PULLCTL_ST(SGPIO3)
 };
 
+#define OWL_GPIO_PORT(port, base, count, _outen, _inen, _dat)	\
+	[OWL_GPIO_PORT_##port] = {				\
+		.offset = base,					\
+		.pins = count,					\
+		.outen = _outen,				\
+		.inen = _inen,					\
+		.dat = _dat,					\
+	}
+
+static const struct owl_gpio_port s900_gpio_ports[] = {
+	OWL_GPIO_PORT(A, 0x0000, 32, 0x0, 0x4, 0x8),
+	OWL_GPIO_PORT(B, 0x000C, 32, 0x0, 0x4, 0x8),
+	OWL_GPIO_PORT(C, 0x0018, 12, 0x0, 0x4, 0x8),
+	OWL_GPIO_PORT(D, 0x0024, 30, 0x0, 0x4, 0x8),
+	OWL_GPIO_PORT(E, 0x0030, 32, 0x0, 0x4, 0x8),
+	OWL_GPIO_PORT(F, 0x00F0, 8, 0x0, 0x4, 0x8)
+};
+
 static struct owl_pinctrl_soc_data s900_pinctrl_data = {
 	.padinfo = s900_padinfo,
 	.pins = (const struct pinctrl_pin_desc *)s900_pads,
@@ -1822,7 +1847,9 @@ static struct owl_pinctrl_soc_data s900_pinctrl_data = {
 	.nfunctions = ARRAY_SIZE(s900_functions),
 	.groups = s900_groups,
 	.ngroups = ARRAY_SIZE(s900_groups),
-	.ngpios = NUM_GPIOS
+	.ngpios = NUM_GPIOS,
+	.ports = s900_gpio_ports,
+	.nports = ARRAY_SIZE(s900_gpio_ports)
 };
 
 static int s900_pinctrl_probe(struct platform_device *pdev)
-- 
2.14.1

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

* [PATCH 4/5] pinctrl: actions: Add gpio support for Actions S900 SoC
@ 2018-05-18  2:30   ` Manivannan Sadhasivam
  0 siblings, 0 replies; 18+ messages in thread
From: Manivannan Sadhasivam @ 2018-05-18  2:30 UTC (permalink / raw)
  To: linux-arm-kernel

Add gpio support to pinctrl driver for Actions Semi S900 SoC.

Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
---
 drivers/pinctrl/actions/Kconfig        |   1 +
 drivers/pinctrl/actions/pinctrl-owl.c  | 206 +++++++++++++++++++++++++++++++++
 drivers/pinctrl/actions/pinctrl-owl.h  |  20 ++++
 drivers/pinctrl/actions/pinctrl-s900.c |  29 ++++-
 4 files changed, 255 insertions(+), 1 deletion(-)

diff --git a/drivers/pinctrl/actions/Kconfig b/drivers/pinctrl/actions/Kconfig
index ede97cdbbc12..490927b4ea76 100644
--- a/drivers/pinctrl/actions/Kconfig
+++ b/drivers/pinctrl/actions/Kconfig
@@ -4,6 +4,7 @@ config PINCTRL_OWL
 	select PINMUX
 	select PINCONF
 	select GENERIC_PINCONF
+	select GPIOLIB
 	help
 	  Say Y here to enable Actions Semi OWL pinctrl driver
 
diff --git a/drivers/pinctrl/actions/pinctrl-owl.c b/drivers/pinctrl/actions/pinctrl-owl.c
index ee090697b1e9..4942e34c8b76 100644
--- a/drivers/pinctrl/actions/pinctrl-owl.c
+++ b/drivers/pinctrl/actions/pinctrl-owl.c
@@ -11,6 +11,7 @@
 
 #include <linux/clk.h>
 #include <linux/err.h>
+#include <linux/gpio/driver.h>
 #include <linux/io.h>
 #include <linux/module.h>
 #include <linux/of.h>
@@ -31,6 +32,7 @@
  * struct owl_pinctrl - pinctrl state of the device
  * @dev: device handle
  * @pctrldev: pinctrl handle
+ * @chip: gpio chip
  * @lock: spinlock to protect registers
  * @soc: reference to soc_data
  * @base: pinctrl register base address
@@ -38,6 +40,7 @@
 struct owl_pinctrl {
 	struct device *dev;
 	struct pinctrl_dev *pctrldev;
+	struct gpio_chip chip;
 	raw_spinlock_t lock;
 	struct clk *clk;
 	const struct owl_pinctrl_soc_data *soc;
@@ -536,6 +539,198 @@ static struct pinctrl_desc owl_pinctrl_desc = {
 	.owner = THIS_MODULE,
 };
 
+static const struct owl_gpio_port *
+owl_gpio_get_port(struct owl_pinctrl *pctrl, unsigned int *pin)
+{
+	unsigned int start = 0, i;
+
+	for (i = 0; i < pctrl->soc->nports; i++) {
+		const struct owl_gpio_port *port = &pctrl->soc->ports[i];
+
+		if (*pin >= start && *pin < start + port->pins) {
+			*pin -= start;
+			return port;
+		}
+
+		start += port->pins;
+	}
+
+	return NULL;
+}
+
+static void owl_gpio_update_reg(void __iomem *base, unsigned int pin, int flag)
+{
+	u32 val;
+
+	val = readl_relaxed(base);
+
+	if (flag)
+		val |= BIT(pin);
+	else
+		val &= ~BIT(pin);
+
+	writel_relaxed(val, base);
+}
+
+static int owl_gpio_request(struct gpio_chip *chip, unsigned int offset)
+{
+	struct owl_pinctrl *pctrl = gpiochip_get_data(chip);
+	const struct owl_gpio_port *port;
+	void __iomem *gpio_base;
+	unsigned long flags;
+
+	port = owl_gpio_get_port(pctrl, &offset);
+	if (WARN_ON(port == NULL))
+		return -ENODEV;
+
+	gpio_base = pctrl->base + port->offset;
+
+	/*
+	 * GPIOs have higher priority over other modules, so either setting
+	 * them as OUT or IN is sufficient
+	 */
+	raw_spin_lock_irqsave(&pctrl->lock, flags);
+	owl_gpio_update_reg(gpio_base + port->outen, offset, true);
+	raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+
+	return 0;
+}
+
+static void owl_gpio_free(struct gpio_chip *chip, unsigned int offset)
+{
+	struct owl_pinctrl *pctrl = gpiochip_get_data(chip);
+	const struct owl_gpio_port *port;
+	void __iomem *gpio_base;
+	unsigned long flags;
+
+	port = owl_gpio_get_port(pctrl, &offset);
+	if (WARN_ON(port == NULL))
+		return;
+
+	gpio_base = pctrl->base + port->offset;
+
+	raw_spin_lock_irqsave(&pctrl->lock, flags);
+	/* disable gpio output */
+	owl_gpio_update_reg(gpio_base + port->outen, offset, false);
+
+	/* disable gpio input */
+	owl_gpio_update_reg(gpio_base + port->inen, offset, false);
+	raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+}
+
+static int owl_gpio_get(struct gpio_chip *chip, unsigned int offset)
+{
+	struct owl_pinctrl *pctrl = gpiochip_get_data(chip);
+	const struct owl_gpio_port *port;
+	void __iomem *gpio_base;
+	unsigned long flags;
+	u32 val;
+
+	port = owl_gpio_get_port(pctrl, &offset);
+	if (WARN_ON(port == NULL))
+		return -ENODEV;
+
+	gpio_base = pctrl->base + port->offset;
+
+	raw_spin_lock_irqsave(&pctrl->lock, flags);
+	val = readl_relaxed(gpio_base + port->dat);
+	raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+
+	return !!(val & BIT(offset));
+}
+
+static void owl_gpio_set(struct gpio_chip *chip, unsigned int offset, int value)
+{
+	struct owl_pinctrl *pctrl = gpiochip_get_data(chip);
+	const struct owl_gpio_port *port;
+	void __iomem *gpio_base;
+	unsigned long flags;
+
+	port = owl_gpio_get_port(pctrl, &offset);
+	if (WARN_ON(port == NULL))
+		return;
+
+	gpio_base = pctrl->base + port->offset;
+
+	raw_spin_lock_irqsave(&pctrl->lock, flags);
+	owl_gpio_update_reg(gpio_base + port->dat, offset, value);
+	raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+}
+
+static int owl_gpio_direction_input(struct gpio_chip *chip, unsigned int offset)
+{
+	struct owl_pinctrl *pctrl = gpiochip_get_data(chip);
+	const struct owl_gpio_port *port;
+	void __iomem *gpio_base;
+	unsigned long flags;
+
+	port = owl_gpio_get_port(pctrl, &offset);
+	if (WARN_ON(port == NULL))
+		return -ENODEV;
+
+	gpio_base = pctrl->base + port->offset;
+
+	raw_spin_lock_irqsave(&pctrl->lock, flags);
+	owl_gpio_update_reg(gpio_base + port->outen, offset, false);
+	owl_gpio_update_reg(gpio_base + port->inen, offset, true);
+	raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+
+	return 0;
+}
+
+static int owl_gpio_direction_output(struct gpio_chip *chip,
+				unsigned int offset, int value)
+{
+	struct owl_pinctrl *pctrl = gpiochip_get_data(chip);
+	const struct owl_gpio_port *port;
+	void __iomem *gpio_base;
+	unsigned long flags;
+
+	port = owl_gpio_get_port(pctrl, &offset);
+	if (WARN_ON(port == NULL))
+		return -ENODEV;
+
+	gpio_base = pctrl->base + port->offset;
+
+	raw_spin_lock_irqsave(&pctrl->lock, flags);
+	owl_gpio_update_reg(gpio_base + port->inen, offset, false);
+	owl_gpio_update_reg(gpio_base + port->outen, offset, true);
+	owl_gpio_update_reg(gpio_base + port->dat, offset, value);
+	raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+
+	return 0;
+}
+
+static int owl_gpio_init(struct owl_pinctrl *pctrl)
+{
+	struct gpio_chip *chip;
+	int ret;
+
+	chip = &pctrl->chip;
+	chip->base = -1;
+	chip->ngpio = pctrl->soc->ngpios;
+	chip->label = dev_name(pctrl->dev);
+	chip->parent = pctrl->dev;
+	chip->owner = THIS_MODULE;
+	chip->of_node = pctrl->dev->of_node;
+
+	ret = gpiochip_add_data(&pctrl->chip, pctrl);
+	if (ret) {
+		dev_err(pctrl->dev, "failed to register gpiochip\n");
+		return ret;
+	}
+
+	ret = gpiochip_add_pin_range(&pctrl->chip, dev_name(pctrl->dev),
+							0, 0, chip->ngpio);
+	if (ret) {
+		dev_err(pctrl->dev, "failed to add pin range\n");
+		gpiochip_remove(&pctrl->chip);
+		return ret;
+	}
+
+	return 0;
+}
+
 int owl_pinctrl_probe(struct platform_device *pdev,
 				struct owl_pinctrl_soc_data *soc_data)
 {
@@ -571,6 +766,13 @@ int owl_pinctrl_probe(struct platform_device *pdev,
 	owl_pinctrl_desc.pins = soc_data->pins;
 	owl_pinctrl_desc.npins = soc_data->npins;
 
+	pctrl->chip.direction_input  = owl_gpio_direction_input;
+	pctrl->chip.direction_output = owl_gpio_direction_output;
+	pctrl->chip.get = owl_gpio_get;
+	pctrl->chip.set = owl_gpio_set;
+	pctrl->chip.request = owl_gpio_request;
+	pctrl->chip.free = owl_gpio_free;
+
 	pctrl->soc = soc_data;
 	pctrl->dev = &pdev->dev;
 
@@ -581,6 +783,10 @@ int owl_pinctrl_probe(struct platform_device *pdev,
 		return PTR_ERR(pctrl->pctrldev);
 	}
 
+	ret = owl_gpio_init(pctrl);
+	if (ret)
+		return ret;
+
 	platform_set_drvdata(pdev, pctrl);
 
 	return 0;
diff --git a/drivers/pinctrl/actions/pinctrl-owl.h b/drivers/pinctrl/actions/pinctrl-owl.h
index 448f81a6db3b..74342378937c 100644
--- a/drivers/pinctrl/actions/pinctrl-owl.h
+++ b/drivers/pinctrl/actions/pinctrl-owl.h
@@ -114,6 +114,22 @@ struct owl_pinmux_func {
 	unsigned int ngroups;
 };
 
+/**
+ * struct owl_gpio_port - Actions GPIO port info
+ * @offset: offset of the GPIO port.
+ * @pins: number of pins belongs to the GPIO port.
+ * @outen: offset of the output enable register.
+ * @inen: offset of the input enable register.
+ * @dat: offset of the data register.
+ */
+struct owl_gpio_port {
+	unsigned int offset;
+	unsigned int pins;
+	unsigned int outen;
+	unsigned int inen;
+	unsigned int dat;
+};
+
 /**
  * struct owl_pinctrl_soc_data - Actions pin controller driver configuration
  * @pins: array describing all pins of the pin controller.
@@ -124,6 +140,8 @@ struct owl_pinmux_func {
  * @ngroups: number of entries in @groups.
  * @padinfo: array describing the pad info of this SoC.
  * @ngpios: number of pingroups the driver should expose as GPIOs.
+ * @port: array describing all GPIO ports of this SoC.
+ * @nports: number of GPIO ports in this SoC.
  */
 struct owl_pinctrl_soc_data {
 	const struct pinctrl_pin_desc *pins;
@@ -134,6 +152,8 @@ struct owl_pinctrl_soc_data {
 	unsigned int ngroups;
 	const struct owl_padinfo *padinfo;
 	unsigned int ngpios;
+	const struct owl_gpio_port *ports;
+	unsigned int nports;
 };
 
 int owl_pinctrl_probe(struct platform_device *pdev,
diff --git a/drivers/pinctrl/actions/pinctrl-s900.c b/drivers/pinctrl/actions/pinctrl-s900.c
index 08d93f8fc086..5503c7945764 100644
--- a/drivers/pinctrl/actions/pinctrl-s900.c
+++ b/drivers/pinctrl/actions/pinctrl-s900.c
@@ -33,6 +33,13 @@
 #define PAD_SR1			(0x0274)
 #define PAD_SR2			(0x0278)
 
+#define OWL_GPIO_PORT_A		0
+#define OWL_GPIO_PORT_B		1
+#define OWL_GPIO_PORT_C		2
+#define OWL_GPIO_PORT_D		3
+#define OWL_GPIO_PORT_E		4
+#define OWL_GPIO_PORT_F		5
+
 #define _GPIOA(offset)		(offset)
 #define _GPIOB(offset)		(32 + (offset))
 #define _GPIOC(offset)		(64 + (offset))
@@ -1814,6 +1821,24 @@ static struct owl_padinfo s900_padinfo[NUM_PADS] = {
 	[SGPIO3] = PAD_INFO_PULLCTL_ST(SGPIO3)
 };
 
+#define OWL_GPIO_PORT(port, base, count, _outen, _inen, _dat)	\
+	[OWL_GPIO_PORT_##port] = {				\
+		.offset = base,					\
+		.pins = count,					\
+		.outen = _outen,				\
+		.inen = _inen,					\
+		.dat = _dat,					\
+	}
+
+static const struct owl_gpio_port s900_gpio_ports[] = {
+	OWL_GPIO_PORT(A, 0x0000, 32, 0x0, 0x4, 0x8),
+	OWL_GPIO_PORT(B, 0x000C, 32, 0x0, 0x4, 0x8),
+	OWL_GPIO_PORT(C, 0x0018, 12, 0x0, 0x4, 0x8),
+	OWL_GPIO_PORT(D, 0x0024, 30, 0x0, 0x4, 0x8),
+	OWL_GPIO_PORT(E, 0x0030, 32, 0x0, 0x4, 0x8),
+	OWL_GPIO_PORT(F, 0x00F0, 8, 0x0, 0x4, 0x8)
+};
+
 static struct owl_pinctrl_soc_data s900_pinctrl_data = {
 	.padinfo = s900_padinfo,
 	.pins = (const struct pinctrl_pin_desc *)s900_pads,
@@ -1822,7 +1847,9 @@ static struct owl_pinctrl_soc_data s900_pinctrl_data = {
 	.nfunctions = ARRAY_SIZE(s900_functions),
 	.groups = s900_groups,
 	.ngroups = ARRAY_SIZE(s900_groups),
-	.ngpios = NUM_GPIOS
+	.ngpios = NUM_GPIOS,
+	.ports = s900_gpio_ports,
+	.nports = ARRAY_SIZE(s900_gpio_ports)
 };
 
 static int s900_pinctrl_probe(struct platform_device *pdev)
-- 
2.14.1

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

* [PATCH 5/5] MAINTAINERS: Add Actions Semi S900 pinctrl entries
  2018-05-18  2:30 ` Manivannan Sadhasivam
@ 2018-05-18  2:30   ` Manivannan Sadhasivam
  -1 siblings, 0 replies; 18+ messages in thread
From: Manivannan Sadhasivam @ 2018-05-18  2:30 UTC (permalink / raw)
  To: linus.walleij, robh+dt, afaerber
  Cc: liuwei, mp-cs, 96boards, devicetree, andy.shevchenko,
	daniel.thompson, amit.kucheria, linux-arm-kernel, linux-gpio,
	linux-kernel, hzhang, bdong, manivannanece23,
	Manivannan Sadhasivam

Add S900 pinctrl entries under ARCH_ACTIONS

Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
---
 MAINTAINERS | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 640dabc4c311..9e1a17c9b4a7 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1125,10 +1125,12 @@ F:	arch/arm/mach-actions/
 F:	arch/arm/boot/dts/owl-*
 F:	arch/arm64/boot/dts/actions/
 F:	drivers/clocksource/owl-*
+F:	drivers/pinctrl/actions/*
 F:	drivers/soc/actions/
 F:	include/dt-bindings/power/owl-*
 F:	include/linux/soc/actions/
 F:	Documentation/devicetree/bindings/arm/actions.txt
+F:	Documentation/devicetree/bindings/pinctrl/actions,s900-pinctrl.txt
 F:	Documentation/devicetree/bindings/power/actions,owl-sps.txt
 F:	Documentation/devicetree/bindings/timer/actions,owl-timer.txt
 
-- 
2.14.1

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

* [PATCH 5/5] MAINTAINERS: Add Actions Semi S900 pinctrl entries
@ 2018-05-18  2:30   ` Manivannan Sadhasivam
  0 siblings, 0 replies; 18+ messages in thread
From: Manivannan Sadhasivam @ 2018-05-18  2:30 UTC (permalink / raw)
  To: linux-arm-kernel

Add S900 pinctrl entries under ARCH_ACTIONS

Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
---
 MAINTAINERS | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 640dabc4c311..9e1a17c9b4a7 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1125,10 +1125,12 @@ F:	arch/arm/mach-actions/
 F:	arch/arm/boot/dts/owl-*
 F:	arch/arm64/boot/dts/actions/
 F:	drivers/clocksource/owl-*
+F:	drivers/pinctrl/actions/*
 F:	drivers/soc/actions/
 F:	include/dt-bindings/power/owl-*
 F:	include/linux/soc/actions/
 F:	Documentation/devicetree/bindings/arm/actions.txt
+F:	Documentation/devicetree/bindings/pinctrl/actions,s900-pinctrl.txt
 F:	Documentation/devicetree/bindings/power/actions,owl-sps.txt
 F:	Documentation/devicetree/bindings/timer/actions,owl-timer.txt
 
-- 
2.14.1

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

* Re: [PATCH 4/5] pinctrl: actions: Add gpio support for Actions S900 SoC
  2018-05-18  2:30   ` Manivannan Sadhasivam
@ 2018-05-18 21:43     ` Andy Shevchenko
  -1 siblings, 0 replies; 18+ messages in thread
From: Andy Shevchenko @ 2018-05-18 21:43 UTC (permalink / raw)
  To: Manivannan Sadhasivam
  Cc: Linus Walleij, Rob Herring, Andreas Färber, 刘炜,
	mp-cs, 96boards, devicetree, Daniel Thompson, amit.kucheria,
	linux-arm Mailing List, open list:GPIO SUBSYSTEM,
	Linux Kernel Mailing List, hzhang, bdong, Mani Sadhasivam

On Fri, May 18, 2018 at 5:30 AM, Manivannan Sadhasivam
<manivannan.sadhasivam@linaro.org> wrote:
> Add gpio support to pinctrl driver for Actions Semi S900 SoC.
>

LGTM,

Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>

> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
> ---
>  drivers/pinctrl/actions/Kconfig        |   1 +
>  drivers/pinctrl/actions/pinctrl-owl.c  | 206 +++++++++++++++++++++++++++++++++
>  drivers/pinctrl/actions/pinctrl-owl.h  |  20 ++++
>  drivers/pinctrl/actions/pinctrl-s900.c |  29 ++++-
>  4 files changed, 255 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/pinctrl/actions/Kconfig b/drivers/pinctrl/actions/Kconfig
> index ede97cdbbc12..490927b4ea76 100644
> --- a/drivers/pinctrl/actions/Kconfig
> +++ b/drivers/pinctrl/actions/Kconfig
> @@ -4,6 +4,7 @@ config PINCTRL_OWL
>         select PINMUX
>         select PINCONF
>         select GENERIC_PINCONF
> +       select GPIOLIB
>         help
>           Say Y here to enable Actions Semi OWL pinctrl driver
>
> diff --git a/drivers/pinctrl/actions/pinctrl-owl.c b/drivers/pinctrl/actions/pinctrl-owl.c
> index ee090697b1e9..4942e34c8b76 100644
> --- a/drivers/pinctrl/actions/pinctrl-owl.c
> +++ b/drivers/pinctrl/actions/pinctrl-owl.c
> @@ -11,6 +11,7 @@
>
>  #include <linux/clk.h>
>  #include <linux/err.h>
> +#include <linux/gpio/driver.h>
>  #include <linux/io.h>
>  #include <linux/module.h>
>  #include <linux/of.h>
> @@ -31,6 +32,7 @@
>   * struct owl_pinctrl - pinctrl state of the device
>   * @dev: device handle
>   * @pctrldev: pinctrl handle
> + * @chip: gpio chip
>   * @lock: spinlock to protect registers
>   * @soc: reference to soc_data
>   * @base: pinctrl register base address
> @@ -38,6 +40,7 @@
>  struct owl_pinctrl {
>         struct device *dev;
>         struct pinctrl_dev *pctrldev;
> +       struct gpio_chip chip;
>         raw_spinlock_t lock;
>         struct clk *clk;
>         const struct owl_pinctrl_soc_data *soc;
> @@ -536,6 +539,198 @@ static struct pinctrl_desc owl_pinctrl_desc = {
>         .owner = THIS_MODULE,
>  };
>
> +static const struct owl_gpio_port *
> +owl_gpio_get_port(struct owl_pinctrl *pctrl, unsigned int *pin)
> +{
> +       unsigned int start = 0, i;
> +
> +       for (i = 0; i < pctrl->soc->nports; i++) {
> +               const struct owl_gpio_port *port = &pctrl->soc->ports[i];
> +
> +               if (*pin >= start && *pin < start + port->pins) {
> +                       *pin -= start;
> +                       return port;
> +               }
> +
> +               start += port->pins;
> +       }
> +
> +       return NULL;
> +}
> +
> +static void owl_gpio_update_reg(void __iomem *base, unsigned int pin, int flag)
> +{
> +       u32 val;
> +
> +       val = readl_relaxed(base);
> +
> +       if (flag)
> +               val |= BIT(pin);
> +       else
> +               val &= ~BIT(pin);
> +
> +       writel_relaxed(val, base);
> +}
> +
> +static int owl_gpio_request(struct gpio_chip *chip, unsigned int offset)
> +{
> +       struct owl_pinctrl *pctrl = gpiochip_get_data(chip);
> +       const struct owl_gpio_port *port;
> +       void __iomem *gpio_base;
> +       unsigned long flags;
> +
> +       port = owl_gpio_get_port(pctrl, &offset);
> +       if (WARN_ON(port == NULL))
> +               return -ENODEV;
> +
> +       gpio_base = pctrl->base + port->offset;
> +
> +       /*
> +        * GPIOs have higher priority over other modules, so either setting
> +        * them as OUT or IN is sufficient
> +        */
> +       raw_spin_lock_irqsave(&pctrl->lock, flags);
> +       owl_gpio_update_reg(gpio_base + port->outen, offset, true);
> +       raw_spin_unlock_irqrestore(&pctrl->lock, flags);
> +
> +       return 0;
> +}
> +
> +static void owl_gpio_free(struct gpio_chip *chip, unsigned int offset)
> +{
> +       struct owl_pinctrl *pctrl = gpiochip_get_data(chip);
> +       const struct owl_gpio_port *port;
> +       void __iomem *gpio_base;
> +       unsigned long flags;
> +
> +       port = owl_gpio_get_port(pctrl, &offset);
> +       if (WARN_ON(port == NULL))
> +               return;
> +
> +       gpio_base = pctrl->base + port->offset;
> +
> +       raw_spin_lock_irqsave(&pctrl->lock, flags);
> +       /* disable gpio output */
> +       owl_gpio_update_reg(gpio_base + port->outen, offset, false);
> +
> +       /* disable gpio input */
> +       owl_gpio_update_reg(gpio_base + port->inen, offset, false);
> +       raw_spin_unlock_irqrestore(&pctrl->lock, flags);
> +}
> +
> +static int owl_gpio_get(struct gpio_chip *chip, unsigned int offset)
> +{
> +       struct owl_pinctrl *pctrl = gpiochip_get_data(chip);
> +       const struct owl_gpio_port *port;
> +       void __iomem *gpio_base;
> +       unsigned long flags;
> +       u32 val;
> +
> +       port = owl_gpio_get_port(pctrl, &offset);
> +       if (WARN_ON(port == NULL))
> +               return -ENODEV;
> +
> +       gpio_base = pctrl->base + port->offset;
> +
> +       raw_spin_lock_irqsave(&pctrl->lock, flags);
> +       val = readl_relaxed(gpio_base + port->dat);
> +       raw_spin_unlock_irqrestore(&pctrl->lock, flags);
> +
> +       return !!(val & BIT(offset));
> +}
> +
> +static void owl_gpio_set(struct gpio_chip *chip, unsigned int offset, int value)
> +{
> +       struct owl_pinctrl *pctrl = gpiochip_get_data(chip);
> +       const struct owl_gpio_port *port;
> +       void __iomem *gpio_base;
> +       unsigned long flags;
> +
> +       port = owl_gpio_get_port(pctrl, &offset);
> +       if (WARN_ON(port == NULL))
> +               return;
> +
> +       gpio_base = pctrl->base + port->offset;
> +
> +       raw_spin_lock_irqsave(&pctrl->lock, flags);
> +       owl_gpio_update_reg(gpio_base + port->dat, offset, value);
> +       raw_spin_unlock_irqrestore(&pctrl->lock, flags);
> +}
> +
> +static int owl_gpio_direction_input(struct gpio_chip *chip, unsigned int offset)
> +{
> +       struct owl_pinctrl *pctrl = gpiochip_get_data(chip);
> +       const struct owl_gpio_port *port;
> +       void __iomem *gpio_base;
> +       unsigned long flags;
> +
> +       port = owl_gpio_get_port(pctrl, &offset);
> +       if (WARN_ON(port == NULL))
> +               return -ENODEV;
> +
> +       gpio_base = pctrl->base + port->offset;
> +
> +       raw_spin_lock_irqsave(&pctrl->lock, flags);
> +       owl_gpio_update_reg(gpio_base + port->outen, offset, false);
> +       owl_gpio_update_reg(gpio_base + port->inen, offset, true);
> +       raw_spin_unlock_irqrestore(&pctrl->lock, flags);
> +
> +       return 0;
> +}
> +
> +static int owl_gpio_direction_output(struct gpio_chip *chip,
> +                               unsigned int offset, int value)
> +{
> +       struct owl_pinctrl *pctrl = gpiochip_get_data(chip);
> +       const struct owl_gpio_port *port;
> +       void __iomem *gpio_base;
> +       unsigned long flags;
> +
> +       port = owl_gpio_get_port(pctrl, &offset);
> +       if (WARN_ON(port == NULL))
> +               return -ENODEV;
> +
> +       gpio_base = pctrl->base + port->offset;
> +
> +       raw_spin_lock_irqsave(&pctrl->lock, flags);
> +       owl_gpio_update_reg(gpio_base + port->inen, offset, false);
> +       owl_gpio_update_reg(gpio_base + port->outen, offset, true);
> +       owl_gpio_update_reg(gpio_base + port->dat, offset, value);
> +       raw_spin_unlock_irqrestore(&pctrl->lock, flags);
> +
> +       return 0;
> +}
> +
> +static int owl_gpio_init(struct owl_pinctrl *pctrl)
> +{
> +       struct gpio_chip *chip;
> +       int ret;
> +
> +       chip = &pctrl->chip;
> +       chip->base = -1;
> +       chip->ngpio = pctrl->soc->ngpios;
> +       chip->label = dev_name(pctrl->dev);
> +       chip->parent = pctrl->dev;
> +       chip->owner = THIS_MODULE;
> +       chip->of_node = pctrl->dev->of_node;
> +
> +       ret = gpiochip_add_data(&pctrl->chip, pctrl);
> +       if (ret) {
> +               dev_err(pctrl->dev, "failed to register gpiochip\n");
> +               return ret;
> +       }
> +
> +       ret = gpiochip_add_pin_range(&pctrl->chip, dev_name(pctrl->dev),
> +                                                       0, 0, chip->ngpio);
> +       if (ret) {
> +               dev_err(pctrl->dev, "failed to add pin range\n");
> +               gpiochip_remove(&pctrl->chip);
> +               return ret;
> +       }
> +
> +       return 0;
> +}
> +
>  int owl_pinctrl_probe(struct platform_device *pdev,
>                                 struct owl_pinctrl_soc_data *soc_data)
>  {
> @@ -571,6 +766,13 @@ int owl_pinctrl_probe(struct platform_device *pdev,
>         owl_pinctrl_desc.pins = soc_data->pins;
>         owl_pinctrl_desc.npins = soc_data->npins;
>
> +       pctrl->chip.direction_input  = owl_gpio_direction_input;
> +       pctrl->chip.direction_output = owl_gpio_direction_output;
> +       pctrl->chip.get = owl_gpio_get;
> +       pctrl->chip.set = owl_gpio_set;
> +       pctrl->chip.request = owl_gpio_request;
> +       pctrl->chip.free = owl_gpio_free;
> +
>         pctrl->soc = soc_data;
>         pctrl->dev = &pdev->dev;
>
> @@ -581,6 +783,10 @@ int owl_pinctrl_probe(struct platform_device *pdev,
>                 return PTR_ERR(pctrl->pctrldev);
>         }
>
> +       ret = owl_gpio_init(pctrl);
> +       if (ret)
> +               return ret;
> +
>         platform_set_drvdata(pdev, pctrl);
>
>         return 0;
> diff --git a/drivers/pinctrl/actions/pinctrl-owl.h b/drivers/pinctrl/actions/pinctrl-owl.h
> index 448f81a6db3b..74342378937c 100644
> --- a/drivers/pinctrl/actions/pinctrl-owl.h
> +++ b/drivers/pinctrl/actions/pinctrl-owl.h
> @@ -114,6 +114,22 @@ struct owl_pinmux_func {
>         unsigned int ngroups;
>  };
>
> +/**
> + * struct owl_gpio_port - Actions GPIO port info
> + * @offset: offset of the GPIO port.
> + * @pins: number of pins belongs to the GPIO port.
> + * @outen: offset of the output enable register.
> + * @inen: offset of the input enable register.
> + * @dat: offset of the data register.
> + */
> +struct owl_gpio_port {
> +       unsigned int offset;
> +       unsigned int pins;
> +       unsigned int outen;
> +       unsigned int inen;
> +       unsigned int dat;
> +};
> +
>  /**
>   * struct owl_pinctrl_soc_data - Actions pin controller driver configuration
>   * @pins: array describing all pins of the pin controller.
> @@ -124,6 +140,8 @@ struct owl_pinmux_func {
>   * @ngroups: number of entries in @groups.
>   * @padinfo: array describing the pad info of this SoC.
>   * @ngpios: number of pingroups the driver should expose as GPIOs.
> + * @port: array describing all GPIO ports of this SoC.
> + * @nports: number of GPIO ports in this SoC.
>   */
>  struct owl_pinctrl_soc_data {
>         const struct pinctrl_pin_desc *pins;
> @@ -134,6 +152,8 @@ struct owl_pinctrl_soc_data {
>         unsigned int ngroups;
>         const struct owl_padinfo *padinfo;
>         unsigned int ngpios;
> +       const struct owl_gpio_port *ports;
> +       unsigned int nports;
>  };
>
>  int owl_pinctrl_probe(struct platform_device *pdev,
> diff --git a/drivers/pinctrl/actions/pinctrl-s900.c b/drivers/pinctrl/actions/pinctrl-s900.c
> index 08d93f8fc086..5503c7945764 100644
> --- a/drivers/pinctrl/actions/pinctrl-s900.c
> +++ b/drivers/pinctrl/actions/pinctrl-s900.c
> @@ -33,6 +33,13 @@
>  #define PAD_SR1                        (0x0274)
>  #define PAD_SR2                        (0x0278)
>
> +#define OWL_GPIO_PORT_A                0
> +#define OWL_GPIO_PORT_B                1
> +#define OWL_GPIO_PORT_C                2
> +#define OWL_GPIO_PORT_D                3
> +#define OWL_GPIO_PORT_E                4
> +#define OWL_GPIO_PORT_F                5
> +
>  #define _GPIOA(offset)         (offset)
>  #define _GPIOB(offset)         (32 + (offset))
>  #define _GPIOC(offset)         (64 + (offset))
> @@ -1814,6 +1821,24 @@ static struct owl_padinfo s900_padinfo[NUM_PADS] = {
>         [SGPIO3] = PAD_INFO_PULLCTL_ST(SGPIO3)
>  };
>
> +#define OWL_GPIO_PORT(port, base, count, _outen, _inen, _dat)  \
> +       [OWL_GPIO_PORT_##port] = {                              \
> +               .offset = base,                                 \
> +               .pins = count,                                  \
> +               .outen = _outen,                                \
> +               .inen = _inen,                                  \
> +               .dat = _dat,                                    \
> +       }
> +
> +static const struct owl_gpio_port s900_gpio_ports[] = {
> +       OWL_GPIO_PORT(A, 0x0000, 32, 0x0, 0x4, 0x8),
> +       OWL_GPIO_PORT(B, 0x000C, 32, 0x0, 0x4, 0x8),
> +       OWL_GPIO_PORT(C, 0x0018, 12, 0x0, 0x4, 0x8),
> +       OWL_GPIO_PORT(D, 0x0024, 30, 0x0, 0x4, 0x8),
> +       OWL_GPIO_PORT(E, 0x0030, 32, 0x0, 0x4, 0x8),
> +       OWL_GPIO_PORT(F, 0x00F0, 8, 0x0, 0x4, 0x8)
> +};
> +
>  static struct owl_pinctrl_soc_data s900_pinctrl_data = {
>         .padinfo = s900_padinfo,
>         .pins = (const struct pinctrl_pin_desc *)s900_pads,
> @@ -1822,7 +1847,9 @@ static struct owl_pinctrl_soc_data s900_pinctrl_data = {
>         .nfunctions = ARRAY_SIZE(s900_functions),
>         .groups = s900_groups,
>         .ngroups = ARRAY_SIZE(s900_groups),
> -       .ngpios = NUM_GPIOS
> +       .ngpios = NUM_GPIOS,
> +       .ports = s900_gpio_ports,
> +       .nports = ARRAY_SIZE(s900_gpio_ports)
>  };
>
>  static int s900_pinctrl_probe(struct platform_device *pdev)
> --
> 2.14.1
>



-- 
With Best Regards,
Andy Shevchenko

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

* [PATCH 4/5] pinctrl: actions: Add gpio support for Actions S900 SoC
@ 2018-05-18 21:43     ` Andy Shevchenko
  0 siblings, 0 replies; 18+ messages in thread
From: Andy Shevchenko @ 2018-05-18 21:43 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, May 18, 2018 at 5:30 AM, Manivannan Sadhasivam
<manivannan.sadhasivam@linaro.org> wrote:
> Add gpio support to pinctrl driver for Actions Semi S900 SoC.
>

LGTM,

Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>

> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
> ---
>  drivers/pinctrl/actions/Kconfig        |   1 +
>  drivers/pinctrl/actions/pinctrl-owl.c  | 206 +++++++++++++++++++++++++++++++++
>  drivers/pinctrl/actions/pinctrl-owl.h  |  20 ++++
>  drivers/pinctrl/actions/pinctrl-s900.c |  29 ++++-
>  4 files changed, 255 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/pinctrl/actions/Kconfig b/drivers/pinctrl/actions/Kconfig
> index ede97cdbbc12..490927b4ea76 100644
> --- a/drivers/pinctrl/actions/Kconfig
> +++ b/drivers/pinctrl/actions/Kconfig
> @@ -4,6 +4,7 @@ config PINCTRL_OWL
>         select PINMUX
>         select PINCONF
>         select GENERIC_PINCONF
> +       select GPIOLIB
>         help
>           Say Y here to enable Actions Semi OWL pinctrl driver
>
> diff --git a/drivers/pinctrl/actions/pinctrl-owl.c b/drivers/pinctrl/actions/pinctrl-owl.c
> index ee090697b1e9..4942e34c8b76 100644
> --- a/drivers/pinctrl/actions/pinctrl-owl.c
> +++ b/drivers/pinctrl/actions/pinctrl-owl.c
> @@ -11,6 +11,7 @@
>
>  #include <linux/clk.h>
>  #include <linux/err.h>
> +#include <linux/gpio/driver.h>
>  #include <linux/io.h>
>  #include <linux/module.h>
>  #include <linux/of.h>
> @@ -31,6 +32,7 @@
>   * struct owl_pinctrl - pinctrl state of the device
>   * @dev: device handle
>   * @pctrldev: pinctrl handle
> + * @chip: gpio chip
>   * @lock: spinlock to protect registers
>   * @soc: reference to soc_data
>   * @base: pinctrl register base address
> @@ -38,6 +40,7 @@
>  struct owl_pinctrl {
>         struct device *dev;
>         struct pinctrl_dev *pctrldev;
> +       struct gpio_chip chip;
>         raw_spinlock_t lock;
>         struct clk *clk;
>         const struct owl_pinctrl_soc_data *soc;
> @@ -536,6 +539,198 @@ static struct pinctrl_desc owl_pinctrl_desc = {
>         .owner = THIS_MODULE,
>  };
>
> +static const struct owl_gpio_port *
> +owl_gpio_get_port(struct owl_pinctrl *pctrl, unsigned int *pin)
> +{
> +       unsigned int start = 0, i;
> +
> +       for (i = 0; i < pctrl->soc->nports; i++) {
> +               const struct owl_gpio_port *port = &pctrl->soc->ports[i];
> +
> +               if (*pin >= start && *pin < start + port->pins) {
> +                       *pin -= start;
> +                       return port;
> +               }
> +
> +               start += port->pins;
> +       }
> +
> +       return NULL;
> +}
> +
> +static void owl_gpio_update_reg(void __iomem *base, unsigned int pin, int flag)
> +{
> +       u32 val;
> +
> +       val = readl_relaxed(base);
> +
> +       if (flag)
> +               val |= BIT(pin);
> +       else
> +               val &= ~BIT(pin);
> +
> +       writel_relaxed(val, base);
> +}
> +
> +static int owl_gpio_request(struct gpio_chip *chip, unsigned int offset)
> +{
> +       struct owl_pinctrl *pctrl = gpiochip_get_data(chip);
> +       const struct owl_gpio_port *port;
> +       void __iomem *gpio_base;
> +       unsigned long flags;
> +
> +       port = owl_gpio_get_port(pctrl, &offset);
> +       if (WARN_ON(port == NULL))
> +               return -ENODEV;
> +
> +       gpio_base = pctrl->base + port->offset;
> +
> +       /*
> +        * GPIOs have higher priority over other modules, so either setting
> +        * them as OUT or IN is sufficient
> +        */
> +       raw_spin_lock_irqsave(&pctrl->lock, flags);
> +       owl_gpio_update_reg(gpio_base + port->outen, offset, true);
> +       raw_spin_unlock_irqrestore(&pctrl->lock, flags);
> +
> +       return 0;
> +}
> +
> +static void owl_gpio_free(struct gpio_chip *chip, unsigned int offset)
> +{
> +       struct owl_pinctrl *pctrl = gpiochip_get_data(chip);
> +       const struct owl_gpio_port *port;
> +       void __iomem *gpio_base;
> +       unsigned long flags;
> +
> +       port = owl_gpio_get_port(pctrl, &offset);
> +       if (WARN_ON(port == NULL))
> +               return;
> +
> +       gpio_base = pctrl->base + port->offset;
> +
> +       raw_spin_lock_irqsave(&pctrl->lock, flags);
> +       /* disable gpio output */
> +       owl_gpio_update_reg(gpio_base + port->outen, offset, false);
> +
> +       /* disable gpio input */
> +       owl_gpio_update_reg(gpio_base + port->inen, offset, false);
> +       raw_spin_unlock_irqrestore(&pctrl->lock, flags);
> +}
> +
> +static int owl_gpio_get(struct gpio_chip *chip, unsigned int offset)
> +{
> +       struct owl_pinctrl *pctrl = gpiochip_get_data(chip);
> +       const struct owl_gpio_port *port;
> +       void __iomem *gpio_base;
> +       unsigned long flags;
> +       u32 val;
> +
> +       port = owl_gpio_get_port(pctrl, &offset);
> +       if (WARN_ON(port == NULL))
> +               return -ENODEV;
> +
> +       gpio_base = pctrl->base + port->offset;
> +
> +       raw_spin_lock_irqsave(&pctrl->lock, flags);
> +       val = readl_relaxed(gpio_base + port->dat);
> +       raw_spin_unlock_irqrestore(&pctrl->lock, flags);
> +
> +       return !!(val & BIT(offset));
> +}
> +
> +static void owl_gpio_set(struct gpio_chip *chip, unsigned int offset, int value)
> +{
> +       struct owl_pinctrl *pctrl = gpiochip_get_data(chip);
> +       const struct owl_gpio_port *port;
> +       void __iomem *gpio_base;
> +       unsigned long flags;
> +
> +       port = owl_gpio_get_port(pctrl, &offset);
> +       if (WARN_ON(port == NULL))
> +               return;
> +
> +       gpio_base = pctrl->base + port->offset;
> +
> +       raw_spin_lock_irqsave(&pctrl->lock, flags);
> +       owl_gpio_update_reg(gpio_base + port->dat, offset, value);
> +       raw_spin_unlock_irqrestore(&pctrl->lock, flags);
> +}
> +
> +static int owl_gpio_direction_input(struct gpio_chip *chip, unsigned int offset)
> +{
> +       struct owl_pinctrl *pctrl = gpiochip_get_data(chip);
> +       const struct owl_gpio_port *port;
> +       void __iomem *gpio_base;
> +       unsigned long flags;
> +
> +       port = owl_gpio_get_port(pctrl, &offset);
> +       if (WARN_ON(port == NULL))
> +               return -ENODEV;
> +
> +       gpio_base = pctrl->base + port->offset;
> +
> +       raw_spin_lock_irqsave(&pctrl->lock, flags);
> +       owl_gpio_update_reg(gpio_base + port->outen, offset, false);
> +       owl_gpio_update_reg(gpio_base + port->inen, offset, true);
> +       raw_spin_unlock_irqrestore(&pctrl->lock, flags);
> +
> +       return 0;
> +}
> +
> +static int owl_gpio_direction_output(struct gpio_chip *chip,
> +                               unsigned int offset, int value)
> +{
> +       struct owl_pinctrl *pctrl = gpiochip_get_data(chip);
> +       const struct owl_gpio_port *port;
> +       void __iomem *gpio_base;
> +       unsigned long flags;
> +
> +       port = owl_gpio_get_port(pctrl, &offset);
> +       if (WARN_ON(port == NULL))
> +               return -ENODEV;
> +
> +       gpio_base = pctrl->base + port->offset;
> +
> +       raw_spin_lock_irqsave(&pctrl->lock, flags);
> +       owl_gpio_update_reg(gpio_base + port->inen, offset, false);
> +       owl_gpio_update_reg(gpio_base + port->outen, offset, true);
> +       owl_gpio_update_reg(gpio_base + port->dat, offset, value);
> +       raw_spin_unlock_irqrestore(&pctrl->lock, flags);
> +
> +       return 0;
> +}
> +
> +static int owl_gpio_init(struct owl_pinctrl *pctrl)
> +{
> +       struct gpio_chip *chip;
> +       int ret;
> +
> +       chip = &pctrl->chip;
> +       chip->base = -1;
> +       chip->ngpio = pctrl->soc->ngpios;
> +       chip->label = dev_name(pctrl->dev);
> +       chip->parent = pctrl->dev;
> +       chip->owner = THIS_MODULE;
> +       chip->of_node = pctrl->dev->of_node;
> +
> +       ret = gpiochip_add_data(&pctrl->chip, pctrl);
> +       if (ret) {
> +               dev_err(pctrl->dev, "failed to register gpiochip\n");
> +               return ret;
> +       }
> +
> +       ret = gpiochip_add_pin_range(&pctrl->chip, dev_name(pctrl->dev),
> +                                                       0, 0, chip->ngpio);
> +       if (ret) {
> +               dev_err(pctrl->dev, "failed to add pin range\n");
> +               gpiochip_remove(&pctrl->chip);
> +               return ret;
> +       }
> +
> +       return 0;
> +}
> +
>  int owl_pinctrl_probe(struct platform_device *pdev,
>                                 struct owl_pinctrl_soc_data *soc_data)
>  {
> @@ -571,6 +766,13 @@ int owl_pinctrl_probe(struct platform_device *pdev,
>         owl_pinctrl_desc.pins = soc_data->pins;
>         owl_pinctrl_desc.npins = soc_data->npins;
>
> +       pctrl->chip.direction_input  = owl_gpio_direction_input;
> +       pctrl->chip.direction_output = owl_gpio_direction_output;
> +       pctrl->chip.get = owl_gpio_get;
> +       pctrl->chip.set = owl_gpio_set;
> +       pctrl->chip.request = owl_gpio_request;
> +       pctrl->chip.free = owl_gpio_free;
> +
>         pctrl->soc = soc_data;
>         pctrl->dev = &pdev->dev;
>
> @@ -581,6 +783,10 @@ int owl_pinctrl_probe(struct platform_device *pdev,
>                 return PTR_ERR(pctrl->pctrldev);
>         }
>
> +       ret = owl_gpio_init(pctrl);
> +       if (ret)
> +               return ret;
> +
>         platform_set_drvdata(pdev, pctrl);
>
>         return 0;
> diff --git a/drivers/pinctrl/actions/pinctrl-owl.h b/drivers/pinctrl/actions/pinctrl-owl.h
> index 448f81a6db3b..74342378937c 100644
> --- a/drivers/pinctrl/actions/pinctrl-owl.h
> +++ b/drivers/pinctrl/actions/pinctrl-owl.h
> @@ -114,6 +114,22 @@ struct owl_pinmux_func {
>         unsigned int ngroups;
>  };
>
> +/**
> + * struct owl_gpio_port - Actions GPIO port info
> + * @offset: offset of the GPIO port.
> + * @pins: number of pins belongs to the GPIO port.
> + * @outen: offset of the output enable register.
> + * @inen: offset of the input enable register.
> + * @dat: offset of the data register.
> + */
> +struct owl_gpio_port {
> +       unsigned int offset;
> +       unsigned int pins;
> +       unsigned int outen;
> +       unsigned int inen;
> +       unsigned int dat;
> +};
> +
>  /**
>   * struct owl_pinctrl_soc_data - Actions pin controller driver configuration
>   * @pins: array describing all pins of the pin controller.
> @@ -124,6 +140,8 @@ struct owl_pinmux_func {
>   * @ngroups: number of entries in @groups.
>   * @padinfo: array describing the pad info of this SoC.
>   * @ngpios: number of pingroups the driver should expose as GPIOs.
> + * @port: array describing all GPIO ports of this SoC.
> + * @nports: number of GPIO ports in this SoC.
>   */
>  struct owl_pinctrl_soc_data {
>         const struct pinctrl_pin_desc *pins;
> @@ -134,6 +152,8 @@ struct owl_pinctrl_soc_data {
>         unsigned int ngroups;
>         const struct owl_padinfo *padinfo;
>         unsigned int ngpios;
> +       const struct owl_gpio_port *ports;
> +       unsigned int nports;
>  };
>
>  int owl_pinctrl_probe(struct platform_device *pdev,
> diff --git a/drivers/pinctrl/actions/pinctrl-s900.c b/drivers/pinctrl/actions/pinctrl-s900.c
> index 08d93f8fc086..5503c7945764 100644
> --- a/drivers/pinctrl/actions/pinctrl-s900.c
> +++ b/drivers/pinctrl/actions/pinctrl-s900.c
> @@ -33,6 +33,13 @@
>  #define PAD_SR1                        (0x0274)
>  #define PAD_SR2                        (0x0278)
>
> +#define OWL_GPIO_PORT_A                0
> +#define OWL_GPIO_PORT_B                1
> +#define OWL_GPIO_PORT_C                2
> +#define OWL_GPIO_PORT_D                3
> +#define OWL_GPIO_PORT_E                4
> +#define OWL_GPIO_PORT_F                5
> +
>  #define _GPIOA(offset)         (offset)
>  #define _GPIOB(offset)         (32 + (offset))
>  #define _GPIOC(offset)         (64 + (offset))
> @@ -1814,6 +1821,24 @@ static struct owl_padinfo s900_padinfo[NUM_PADS] = {
>         [SGPIO3] = PAD_INFO_PULLCTL_ST(SGPIO3)
>  };
>
> +#define OWL_GPIO_PORT(port, base, count, _outen, _inen, _dat)  \
> +       [OWL_GPIO_PORT_##port] = {                              \
> +               .offset = base,                                 \
> +               .pins = count,                                  \
> +               .outen = _outen,                                \
> +               .inen = _inen,                                  \
> +               .dat = _dat,                                    \
> +       }
> +
> +static const struct owl_gpio_port s900_gpio_ports[] = {
> +       OWL_GPIO_PORT(A, 0x0000, 32, 0x0, 0x4, 0x8),
> +       OWL_GPIO_PORT(B, 0x000C, 32, 0x0, 0x4, 0x8),
> +       OWL_GPIO_PORT(C, 0x0018, 12, 0x0, 0x4, 0x8),
> +       OWL_GPIO_PORT(D, 0x0024, 30, 0x0, 0x4, 0x8),
> +       OWL_GPIO_PORT(E, 0x0030, 32, 0x0, 0x4, 0x8),
> +       OWL_GPIO_PORT(F, 0x00F0, 8, 0x0, 0x4, 0x8)
> +};
> +
>  static struct owl_pinctrl_soc_data s900_pinctrl_data = {
>         .padinfo = s900_padinfo,
>         .pins = (const struct pinctrl_pin_desc *)s900_pads,
> @@ -1822,7 +1847,9 @@ static struct owl_pinctrl_soc_data s900_pinctrl_data = {
>         .nfunctions = ARRAY_SIZE(s900_functions),
>         .groups = s900_groups,
>         .ngroups = ARRAY_SIZE(s900_groups),
> -       .ngpios = NUM_GPIOS
> +       .ngpios = NUM_GPIOS,
> +       .ports = s900_gpio_ports,
> +       .nports = ARRAY_SIZE(s900_gpio_ports)
>  };
>
>  static int s900_pinctrl_probe(struct platform_device *pdev)
> --
> 2.14.1
>



-- 
With Best Regards,
Andy Shevchenko

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

* Re: [PATCH 4/5] pinctrl: actions: Add gpio support for Actions S900 SoC
  2018-05-18  2:30   ` Manivannan Sadhasivam
@ 2018-05-19  9:18     ` Christian Lamparter
  -1 siblings, 0 replies; 18+ messages in thread
From: Christian Lamparter @ 2018-05-19  9:18 UTC (permalink / raw)
  To: Manivannan Sadhasivam
  Cc: linus.walleij, robh+dt, afaerber, liuwei, mp-cs, 96boards,
	devicetree, andy.shevchenko, daniel.thompson, amit.kucheria,
	linux-arm-kernel, linux-gpio, linux-kernel, hzhang, bdong,
	manivannanece23

On Friday, May 18, 2018 4:30:55 AM CEST Manivannan Sadhasivam wrote:
> Add gpio support to pinctrl driver for Actions Semi S900 SoC.
> 
> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
> ---
> [...]
> +static int owl_gpio_init(struct owl_pinctrl *pctrl)
> +{
> +	struct gpio_chip *chip;
> +	int ret;
> +
> +	chip = &pctrl->chip;
> +	chip->base = -1;
> +	chip->ngpio = pctrl->soc->ngpios;
> +	chip->label = dev_name(pctrl->dev);
> +	chip->parent = pctrl->dev;
> +	chip->owner = THIS_MODULE;
> +	chip->of_node = pctrl->dev->of_node;
> +
> +	ret = gpiochip_add_data(&pctrl->chip, pctrl);
> +	if (ret) {
> +		dev_err(pctrl->dev, "failed to register gpiochip\n");
> +		return ret;
> +	}
> +
> +	ret = gpiochip_add_pin_range(&pctrl->chip, dev_name(pctrl->dev),
> +							0, 0, chip->ngpio);
> +	if (ret) {
> +		dev_err(pctrl->dev, "failed to add pin range\n");
> +		gpiochip_remove(&pctrl->chip);
> +		return ret;
> +	}
> +
gpiochip_add_pin_range()? That's not going to work with gpio-hogs. 

But, you can easily test this. Just add a gpio-hog [0] 
( Section 2. gpio-controller nodes) into the Devicetree's
pinctrl node.

something like: (No idea if GPIO1 is already used, but any free
gpio will do)
| 		[...]
|		pinctrl@e01b0000 {
|			compatible = "actions,s900-pinctrl";
|			reg = <0x0 0xe01b0000 0x0 0x1000>;
|			clocks = <&cmu CLK_GPIO>;
|			gpio-controller;
|			#gpio-cells = <2>;
|
|			line_b {
|				gpio-hog;
|				gpios = <1 GPIO_ACTIVE_HIGH>;
|				output-low;
|				line-name = "foo-bar-gpio";
|			};
|		};

The pinctrl probe will fail. You can fix this by
replacing the gpiochip_add_pin_range() and use
the gpio-ranges [0] property to define the range.

[0] <https://www.kernel.org/doc/Documentation/devicetree/bindings/gpio/gpio.txt>

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

* [PATCH 4/5] pinctrl: actions: Add gpio support for Actions S900 SoC
@ 2018-05-19  9:18     ` Christian Lamparter
  0 siblings, 0 replies; 18+ messages in thread
From: Christian Lamparter @ 2018-05-19  9:18 UTC (permalink / raw)
  To: linux-arm-kernel

On Friday, May 18, 2018 4:30:55 AM CEST Manivannan Sadhasivam wrote:
> Add gpio support to pinctrl driver for Actions Semi S900 SoC.
> 
> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
> ---
> [...]
> +static int owl_gpio_init(struct owl_pinctrl *pctrl)
> +{
> +	struct gpio_chip *chip;
> +	int ret;
> +
> +	chip = &pctrl->chip;
> +	chip->base = -1;
> +	chip->ngpio = pctrl->soc->ngpios;
> +	chip->label = dev_name(pctrl->dev);
> +	chip->parent = pctrl->dev;
> +	chip->owner = THIS_MODULE;
> +	chip->of_node = pctrl->dev->of_node;
> +
> +	ret = gpiochip_add_data(&pctrl->chip, pctrl);
> +	if (ret) {
> +		dev_err(pctrl->dev, "failed to register gpiochip\n");
> +		return ret;
> +	}
> +
> +	ret = gpiochip_add_pin_range(&pctrl->chip, dev_name(pctrl->dev),
> +							0, 0, chip->ngpio);
> +	if (ret) {
> +		dev_err(pctrl->dev, "failed to add pin range\n");
> +		gpiochip_remove(&pctrl->chip);
> +		return ret;
> +	}
> +
gpiochip_add_pin_range()? That's not going to work with gpio-hogs. 

But, you can easily test this. Just add a gpio-hog [0] 
( Section 2. gpio-controller nodes) into the Devicetree's
pinctrl node.

something like: (No idea if GPIO1 is already used, but any free
gpio will do)
| 		[...]
|		pinctrl at e01b0000 {
|			compatible = "actions,s900-pinctrl";
|			reg = <0x0 0xe01b0000 0x0 0x1000>;
|			clocks = <&cmu CLK_GPIO>;
|			gpio-controller;
|			#gpio-cells = <2>;
|
|			line_b {
|				gpio-hog;
|				gpios = <1 GPIO_ACTIVE_HIGH>;
|				output-low;
|				line-name = "foo-bar-gpio";
|			};
|		};

The pinctrl probe will fail. You can fix this by
replacing the gpiochip_add_pin_range() and use
the gpio-ranges [0] property to define the range.

[0] <https://www.kernel.org/doc/Documentation/devicetree/bindings/gpio/gpio.txt>

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

* Re: [PATCH 4/5] pinctrl: actions: Add gpio support for Actions S900 SoC
  2018-05-19  9:18     ` Christian Lamparter
@ 2018-05-19 10:11       ` Manivannan Sadhasivam
  -1 siblings, 0 replies; 18+ messages in thread
From: Manivannan Sadhasivam @ 2018-05-19 10:11 UTC (permalink / raw)
  To: Christian Lamparter
  Cc: linus.walleij, robh+dt, afaerber, liuwei, mp-cs, 96boards,
	devicetree, andy.shevchenko, daniel.thompson, amit.kucheria,
	linux-arm-kernel, linux-gpio, linux-kernel, hzhang, bdong,
	manivannanece23

Hi Christian,

On Sat, May 19, 2018 at 11:18:53AM +0200, Christian Lamparter wrote:
> On Friday, May 18, 2018 4:30:55 AM CEST Manivannan Sadhasivam wrote:
> > Add gpio support to pinctrl driver for Actions Semi S900 SoC.
> > 
> > Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
> > ---
> > [...]
> > +static int owl_gpio_init(struct owl_pinctrl *pctrl)
> > +{
> > +	struct gpio_chip *chip;
> > +	int ret;
> > +
> > +	chip = &pctrl->chip;
> > +	chip->base = -1;
> > +	chip->ngpio = pctrl->soc->ngpios;
> > +	chip->label = dev_name(pctrl->dev);
> > +	chip->parent = pctrl->dev;
> > +	chip->owner = THIS_MODULE;
> > +	chip->of_node = pctrl->dev->of_node;
> > +
> > +	ret = gpiochip_add_data(&pctrl->chip, pctrl);
> > +	if (ret) {
> > +		dev_err(pctrl->dev, "failed to register gpiochip\n");
> > +		return ret;
> > +	}
> > +
> > +	ret = gpiochip_add_pin_range(&pctrl->chip, dev_name(pctrl->dev),
> > +							0, 0, chip->ngpio);
> > +	if (ret) {
> > +		dev_err(pctrl->dev, "failed to add pin range\n");
> > +		gpiochip_remove(&pctrl->chip);
> > +		return ret;
> > +	}
> > +
> gpiochip_add_pin_range()? That's not going to work with gpio-hogs. 
> 

Hmmm. Just looked into the gpio-hog mechanism and the patch you have
implemented for MSM driver. I agree with you on replacing
gpiochip_add_pin_range() with gpio-ranges property. But I'm curious
whether we should document it somewhere or not (probably in [1]).

Anyway I will send the v2 incorporating your suggestion.

Thanks,
Mani

[1] Documentation/devicetree/bindings/gpio/gpio.txt

> But, you can easily test this. Just add a gpio-hog [0] 
> ( Section 2. gpio-controller nodes) into the Devicetree's
> pinctrl node.
> 
> something like: (No idea if GPIO1 is already used, but any free
> gpio will do)
> | 		[...]
> |		pinctrl@e01b0000 {
> |			compatible = "actions,s900-pinctrl";
> |			reg = <0x0 0xe01b0000 0x0 0x1000>;
> |			clocks = <&cmu CLK_GPIO>;
> |			gpio-controller;
> |			#gpio-cells = <2>;
> |
> |			line_b {
> |				gpio-hog;
> |				gpios = <1 GPIO_ACTIVE_HIGH>;
> |				output-low;
> |				line-name = "foo-bar-gpio";
> |			};
> |		};
> 
> The pinctrl probe will fail. You can fix this by
> replacing the gpiochip_add_pin_range() and use
> the gpio-ranges [0] property to define the range.
> 
> [0] <https://www.kernel.org/doc/Documentation/devicetree/bindings/gpio/gpio.txt>
> 
> 
> 

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

* [PATCH 4/5] pinctrl: actions: Add gpio support for Actions S900 SoC
@ 2018-05-19 10:11       ` Manivannan Sadhasivam
  0 siblings, 0 replies; 18+ messages in thread
From: Manivannan Sadhasivam @ 2018-05-19 10:11 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Christian,

On Sat, May 19, 2018 at 11:18:53AM +0200, Christian Lamparter wrote:
> On Friday, May 18, 2018 4:30:55 AM CEST Manivannan Sadhasivam wrote:
> > Add gpio support to pinctrl driver for Actions Semi S900 SoC.
> > 
> > Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
> > ---
> > [...]
> > +static int owl_gpio_init(struct owl_pinctrl *pctrl)
> > +{
> > +	struct gpio_chip *chip;
> > +	int ret;
> > +
> > +	chip = &pctrl->chip;
> > +	chip->base = -1;
> > +	chip->ngpio = pctrl->soc->ngpios;
> > +	chip->label = dev_name(pctrl->dev);
> > +	chip->parent = pctrl->dev;
> > +	chip->owner = THIS_MODULE;
> > +	chip->of_node = pctrl->dev->of_node;
> > +
> > +	ret = gpiochip_add_data(&pctrl->chip, pctrl);
> > +	if (ret) {
> > +		dev_err(pctrl->dev, "failed to register gpiochip\n");
> > +		return ret;
> > +	}
> > +
> > +	ret = gpiochip_add_pin_range(&pctrl->chip, dev_name(pctrl->dev),
> > +							0, 0, chip->ngpio);
> > +	if (ret) {
> > +		dev_err(pctrl->dev, "failed to add pin range\n");
> > +		gpiochip_remove(&pctrl->chip);
> > +		return ret;
> > +	}
> > +
> gpiochip_add_pin_range()? That's not going to work with gpio-hogs. 
> 

Hmmm. Just looked into the gpio-hog mechanism and the patch you have
implemented for MSM driver. I agree with you on replacing
gpiochip_add_pin_range() with gpio-ranges property. But I'm curious
whether we should document it somewhere or not (probably in [1]).

Anyway I will send the v2 incorporating your suggestion.

Thanks,
Mani

[1] Documentation/devicetree/bindings/gpio/gpio.txt

> But, you can easily test this. Just add a gpio-hog [0] 
> ( Section 2. gpio-controller nodes) into the Devicetree's
> pinctrl node.
> 
> something like: (No idea if GPIO1 is already used, but any free
> gpio will do)
> | 		[...]
> |		pinctrl at e01b0000 {
> |			compatible = "actions,s900-pinctrl";
> |			reg = <0x0 0xe01b0000 0x0 0x1000>;
> |			clocks = <&cmu CLK_GPIO>;
> |			gpio-controller;
> |			#gpio-cells = <2>;
> |
> |			line_b {
> |				gpio-hog;
> |				gpios = <1 GPIO_ACTIVE_HIGH>;
> |				output-low;
> |				line-name = "foo-bar-gpio";
> |			};
> |		};
> 
> The pinctrl probe will fail. You can fix this by
> replacing the gpiochip_add_pin_range() and use
> the gpio-ranges [0] property to define the range.
> 
> [0] <https://www.kernel.org/doc/Documentation/devicetree/bindings/gpio/gpio.txt>
> 
> 
> 

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

end of thread, other threads:[~2018-05-19 10:11 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-05-18  2:30 [PATCH 0/5] Add gpio support for Action Semi S900 SoC Manivannan Sadhasivam
2018-05-18  2:30 ` Manivannan Sadhasivam
2018-05-18  2:30 ` [PATCH 1/5] dt-bindings: pinctrl: Add gpio bindings for Actions " Manivannan Sadhasivam
2018-05-18  2:30   ` Manivannan Sadhasivam
2018-05-18  2:30 ` [PATCH 2/5] arm64: dts: actions: Add gpio properties to pinctrl node for S900 Manivannan Sadhasivam
2018-05-18  2:30   ` Manivannan Sadhasivam
2018-05-18  2:30 ` [PATCH 3/5] arm64: dts: actions: Add gpio line names to Bubblegum-96 board Manivannan Sadhasivam
2018-05-18  2:30   ` Manivannan Sadhasivam
2018-05-18  2:30 ` [PATCH 4/5] pinctrl: actions: Add gpio support for Actions S900 SoC Manivannan Sadhasivam
2018-05-18  2:30   ` Manivannan Sadhasivam
2018-05-18 21:43   ` Andy Shevchenko
2018-05-18 21:43     ` Andy Shevchenko
2018-05-19  9:18   ` Christian Lamparter
2018-05-19  9:18     ` Christian Lamparter
2018-05-19 10:11     ` Manivannan Sadhasivam
2018-05-19 10:11       ` Manivannan Sadhasivam
2018-05-18  2:30 ` [PATCH 5/5] MAINTAINERS: Add Actions Semi S900 pinctrl entries Manivannan Sadhasivam
2018-05-18  2:30   ` Manivannan Sadhasivam

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