All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 00/10] Add Actions Semi S900 pinctrl and gpio support
@ 2018-03-02  3:50 ` Manivannan Sadhasivam
  0 siblings, 0 replies; 43+ messages in thread
From: Manivannan Sadhasivam @ 2018-03-02  3:50 UTC (permalink / raw)
  To: linus.walleij, robh+dt, afaerber
  Cc: liuwei, mp-cs, 96boards, devicetree, daniel.thompson,
	amit.kucheria, linux-arm-kernel, linux-gpio, linux-kernel,
	hzhang, bdong, manivannanece23, Manivannan Sadhasivam

This patchset adds pinctrl and gpio support for Actions Semi S900 SoC.
Pinctrl and gpio subsystems share the common set of register range but
implemented as individual drivers for making it less complex.

Pinmux functions are only accessible for pin groups while pinconf
parameters are available for both pin groups and individual pins.

gpio-line-names has been added for the Bubblegum-96 board matching the
96Boards CE specification v1.0.

Both pinctrl and gpio drivers are verified using the Bubblegum-96 board.

This patchset depends on the clock driver which is still under review:
https://lkml.org/lkml/2018/2/9/831

There is also S500 pinctrl and gpio driver developed by Andreas Farber
independently to this patchset.
https://github.com/afaerber/linux/commits/bg96-next

If this patchseries seems to be good enough to add base OWL pinctrl and
gpio support. Then, we may decide on adding S500 support on top of this later
by reusing the pinctrl definitions from Andreas.

Thanks,
Mani

Changes in v4:

* Incorporated Andy's review for pinctrl driver
* Used _relaxed functions for pinctrl driver
* Added Andy's Reviewed-by tag for gpio driver
* Added (back) Rob's Reviewed-by tag for pinctrl bindings

Changes in v3:

* Simplified owl_gpio_set_reg() with _relaxed functions
* Added interrupt controller properties to gpio node bindings as suggested
  by Rob
* Minor code cleanups

Changes in v2:

* Implemented each GPIO bank as its own gpio-controller
* Added gpio-ranges property
* Modified pin group to follow pad names instead of register names
* Incorporated review comments from Andy
* Incorporated review comments from Andreas
* Fixed the MODULE_LICENSE with respect to SPDX tag
* Added Reviewed by tag from Rob for pinctrl binding

Manivannan Sadhasivam (10):
  dt-bindings: pinctrl: Add bindings for Actions S900 SoC
  arm64: dts: actions: Add pinctrl node for S900
  arm64: actions: Enable PINCTRL in platforms Kconfig
  pinctrl: actions: Add Actions S900 pinctrl driver
  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 reviewer for ACTIONS platforms
  MAINTAINERS: Add Actions Semi S900 pinctrl and gpio entries

 .../devicetree/bindings/gpio/actions,owl-gpio.txt  |   95 +
 .../bindings/pinctrl/actions,s900-pinctrl.txt      |  178 ++
 MAINTAINERS                                        |    5 +
 arch/arm64/Kconfig.platforms                       |    1 +
 arch/arm64/boot/dts/actions/s900-bubblegum-96.dts  |  201 ++
 arch/arm64/boot/dts/actions/s900.dtsi              |   54 +
 drivers/gpio/Kconfig                               |    8 +
 drivers/gpio/Makefile                              |    1 +
 drivers/gpio/gpio-owl.c                            |  218 ++
 drivers/pinctrl/Kconfig                            |    1 +
 drivers/pinctrl/Makefile                           |    1 +
 drivers/pinctrl/actions/Kconfig                    |   12 +
 drivers/pinctrl/actions/Makefile                   |    2 +
 drivers/pinctrl/actions/pinctrl-owl.c              |  579 +++++
 drivers/pinctrl/actions/pinctrl-owl.h              |  142 ++
 drivers/pinctrl/actions/pinctrl-s900.c             | 2505 ++++++++++++++++++++
 16 files changed, 4003 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/actions,owl-gpio.txt
 create mode 100644 Documentation/devicetree/bindings/pinctrl/actions,s900-pinctrl.txt
 create mode 100644 drivers/gpio/gpio-owl.c
 create mode 100644 drivers/pinctrl/actions/Kconfig
 create mode 100644 drivers/pinctrl/actions/Makefile
 create mode 100644 drivers/pinctrl/actions/pinctrl-owl.c
 create mode 100644 drivers/pinctrl/actions/pinctrl-owl.h
 create mode 100644 drivers/pinctrl/actions/pinctrl-s900.c

-- 
2.14.1

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

* [PATCH v4 00/10] Add Actions Semi S900 pinctrl and gpio support
@ 2018-03-02  3:50 ` Manivannan Sadhasivam
  0 siblings, 0 replies; 43+ messages in thread
From: Manivannan Sadhasivam @ 2018-03-02  3:50 UTC (permalink / raw)
  To: linux-arm-kernel

This patchset adds pinctrl and gpio support for Actions Semi S900 SoC.
Pinctrl and gpio subsystems share the common set of register range but
implemented as individual drivers for making it less complex.

Pinmux functions are only accessible for pin groups while pinconf
parameters are available for both pin groups and individual pins.

gpio-line-names has been added for the Bubblegum-96 board matching the
96Boards CE specification v1.0.

Both pinctrl and gpio drivers are verified using the Bubblegum-96 board.

This patchset depends on the clock driver which is still under review:
https://lkml.org/lkml/2018/2/9/831

There is also S500 pinctrl and gpio driver developed by Andreas Farber
independently to this patchset.
https://github.com/afaerber/linux/commits/bg96-next

If this patchseries seems to be good enough to add base OWL pinctrl and
gpio support. Then, we may decide on adding S500 support on top of this later
by reusing the pinctrl definitions from Andreas.

Thanks,
Mani

Changes in v4:

* Incorporated Andy's review for pinctrl driver
* Used _relaxed functions for pinctrl driver
* Added Andy's Reviewed-by tag for gpio driver
* Added (back) Rob's Reviewed-by tag for pinctrl bindings

Changes in v3:

* Simplified owl_gpio_set_reg() with _relaxed functions
* Added interrupt controller properties to gpio node bindings as suggested
  by Rob
* Minor code cleanups

Changes in v2:

* Implemented each GPIO bank as its own gpio-controller
* Added gpio-ranges property
* Modified pin group to follow pad names instead of register names
* Incorporated review comments from Andy
* Incorporated review comments from Andreas
* Fixed the MODULE_LICENSE with respect to SPDX tag
* Added Reviewed by tag from Rob for pinctrl binding

Manivannan Sadhasivam (10):
  dt-bindings: pinctrl: Add bindings for Actions S900 SoC
  arm64: dts: actions: Add pinctrl node for S900
  arm64: actions: Enable PINCTRL in platforms Kconfig
  pinctrl: actions: Add Actions S900 pinctrl driver
  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 reviewer for ACTIONS platforms
  MAINTAINERS: Add Actions Semi S900 pinctrl and gpio entries

 .../devicetree/bindings/gpio/actions,owl-gpio.txt  |   95 +
 .../bindings/pinctrl/actions,s900-pinctrl.txt      |  178 ++
 MAINTAINERS                                        |    5 +
 arch/arm64/Kconfig.platforms                       |    1 +
 arch/arm64/boot/dts/actions/s900-bubblegum-96.dts  |  201 ++
 arch/arm64/boot/dts/actions/s900.dtsi              |   54 +
 drivers/gpio/Kconfig                               |    8 +
 drivers/gpio/Makefile                              |    1 +
 drivers/gpio/gpio-owl.c                            |  218 ++
 drivers/pinctrl/Kconfig                            |    1 +
 drivers/pinctrl/Makefile                           |    1 +
 drivers/pinctrl/actions/Kconfig                    |   12 +
 drivers/pinctrl/actions/Makefile                   |    2 +
 drivers/pinctrl/actions/pinctrl-owl.c              |  579 +++++
 drivers/pinctrl/actions/pinctrl-owl.h              |  142 ++
 drivers/pinctrl/actions/pinctrl-s900.c             | 2505 ++++++++++++++++++++
 16 files changed, 4003 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/actions,owl-gpio.txt
 create mode 100644 Documentation/devicetree/bindings/pinctrl/actions,s900-pinctrl.txt
 create mode 100644 drivers/gpio/gpio-owl.c
 create mode 100644 drivers/pinctrl/actions/Kconfig
 create mode 100644 drivers/pinctrl/actions/Makefile
 create mode 100644 drivers/pinctrl/actions/pinctrl-owl.c
 create mode 100644 drivers/pinctrl/actions/pinctrl-owl.h
 create mode 100644 drivers/pinctrl/actions/pinctrl-s900.c

-- 
2.14.1

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

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

Add pinctrl bindings for Actions Semi S900 SoC

Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Reviewed-by: Rob Herring <robh@kernel.org>
---
 .../bindings/pinctrl/actions,s900-pinctrl.txt      | 178 +++++++++++++++++++++
 1 file changed, 178 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/actions,s900-pinctrl.txt

diff --git a/Documentation/devicetree/bindings/pinctrl/actions,s900-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/actions,s900-pinctrl.txt
new file mode 100644
index 000000000000..fb87c7d74f2e
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/actions,s900-pinctrl.txt
@@ -0,0 +1,178 @@
+Actions Semi S900 Pin Controller
+
+This binding describes the pin controller found in the S900 SoC.
+
+Required Properties:
+
+- compatible:   Should be "actions,s900-pinctrl"
+- reg:          Should contain the register base address and size of
+                the pin controller.
+- clocks:       phandle of the clock feeding the pin controller
+
+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
+phrase "pin configuration node".
+
+The pin configuration nodes act as a container for an arbitrary number of
+subnodes. Each of these subnodes represents some desired configuration for a
+pin, a group, or a list of pins or groups. This configuration can include the
+mux function to select on those group(s), and various pin configuration
+parameters, such as pull-up, drive strength, etc.
+
+PIN CONFIGURATION NODES:
+
+The name of each subnode is not important; all subnodes should be enumerated
+and processed purely based on their content.
+
+Each subnode only affects those parameters that are explicitly listed. In
+other words, a subnode that lists a mux function but no pin configuration
+parameters implies no information about any pin configuration parameters.
+Similarly, a pin subnode that describes a pullup parameter implies no
+information about e.g. the mux function.
+
+Pinmux functions are available only for the pin groups while pinconf
+parameters are available for both pin groups and individual pins.
+
+The following generic properties as defined in pinctrl-bindings.txt are valid
+to specify in a pin configuration subnode:
+
+Required Properties:
+
+- pins:           An array of strings, each string containing the name of a pin.
+                  These pins are used for selecting the pull control and schmitt
+                  trigger parameters. The following are the list of pins
+                  available:
+
+                  eth_txd0, eth_txd1, eth_txen, eth_rxer, eth_crs_dv,
+                  eth_rxd1, eth_rxd0, eth_ref_clk, eth_mdc, eth_mdio,
+                  sirq0, sirq1, sirq2, i2s_d0, i2s_bclk0, i2s_lrclk0,
+                  i2s_mclk0, i2s_d1, i2s_bclk1, i2s_lrclk1, i2s_mclk1,
+                  pcm1_in, pcm1_clk, pcm1_sync, pcm1_out, eram_a5,
+                  eram_a6, eram_a7, eram_a8, eram_a9, eram_a10, eram_a11,
+                  lvds_oep, lvds_oen, lvds_odp, lvds_odn, lvds_ocp,
+                  lvds_ocn, lvds_obp, lvds_obn, lvds_oap, lvds_oan,
+                  lvds_eep, lvds_een, lvds_edp, lvds_edn, lvds_ecp,
+                  lvds_ecn, lvds_ebp, lvds_ebn, lvds_eap, lvds_ean,
+                  sd0_d0, sd0_d1, sd0_d2, sd0_d3, sd1_d0, sd1_d1,
+                  sd1_d2, sd1_d3, sd0_cmd, sd0_clk, sd1_cmd, sd1_clk,
+                  spi0_sclk, spi0_ss, spi0_miso, spi0_mosi, uart0_rx,
+                  uart0_tx, uart2_rx, uart2_tx, uart2_rtsb, uart2_ctsb,
+                  uart3_rx, uart3_tx, uart3_rtsb, uart3_ctsb, uart4_rx,
+                  uart4_tx, i2c0_sclk, i2c0_sdata, i2c1_sclk, i2c1_sdata,
+                  i2c2_sclk, i2c2_sdata, csi0_dn0, csi0_dp0, csi0_dn1,
+                  csi0_dp1, csi0_cn, csi0_cp, csi0_dn2, csi0_dp2, csi0_dn3,
+                  csi0_dp3, dsi_dp3, dsi_dn3, dsi_dp1, dsi_dn1, dsi_cp,
+                  dsi_cn, dsi_dp0, dsi_dn0, dsi_dp2, dsi_dn2, sensor0_pclk,
+                  csi1_dn0,csi1_dp0,csi1_dn1, csi1_dp1, csi1_cn, csi1_cp,
+                  sensor0_ckout, nand0_d0, nand0_d1, nand0_d2, nand0_d3,
+                  nand0_d4, nand0_d5, nand0_d6, nand0_d7, nand0_dqs,
+                  nand0_dqsn, nand0_ale, nand0_cle, nand0_ceb0, nand0_ceb1,
+                  nand0_ceb2, nand0_ceb3, nand1_d0, nand1_d1, nand1_d2,
+                  nand1_d3, nand1_d4, nand1_d5, nand1_d6, nand1_d7, nand1_dqs,
+                  nand1_dqsn, nand1_ale, nand1_cle, nand1_ceb0, nand1_ceb1,
+                  nand1_ceb2, nand1_ceb3, sgpio0, sgpio1, sgpio2, sgpio3
+
+- groups:         An array of strings, each string containing the name of a pin
+                  group. These pin groups are used for selecting the pinmux
+                  functions.
+
+                  lvds_oxx_uart4_mfp, rmii_mdc_mfp, rmii_mdio_mfp, sirq0_mfp,
+                  sirq1_mfp, rmii_txd0_mfp, rmii_txd1_mfp, rmii_txen_mfp,
+                  rmii_rxer_mfp, rmii_crs_dv_mfp, rmii_rxd1_mfp, rmii_rxd0_mfp,
+                  rmii_ref_clk_mfp, i2s_d0_mfp, i2s_d1_mfp, i2s_lr_m_clk0_mfp,
+                  i2s_bclk0_mfp, i2s_bclk1_mclk1_mfp, pcm1_in_out_mfp,
+                  pcm1_clk_mfp, pcm1_sync_mfp, eram_a5_mfp, eram_a6_mfp,
+                  eram_a7_mfp, eram_a8_mfp, eram_a9_mfp, eram_a10_mfp,
+                  eram_a11_mfp, lvds_oep_odn_mfp, lvds_ocp_obn_mfp,
+                  lvds_oap_oan_mfp, lvds_e_mfp, spi0_sclk_mosi_mfp, spi0_ss_mfp,
+                  spi0_miso_mfp, uart2_rtsb_mfp, uart2_ctsb_mfp, uart3_rtsb_mfp,
+                  uart3_ctsb_mfp, sd0_d0_mfp, sd0_d1_mfp, sd0_d2_d3_mfp,
+                  sd1_d0_d3_mfp, sd0_cmd_mfp, sd0_clk_mfp, sd1_cmd_clk_mfp,
+                  uart0_rx_mfp, nand0_d0_ceb3_mfp, uart0_tx_mfp, i2c0_mfp,
+                  csi0_cn_cp_mfp, csi0_dn0_dp3_mfp, csi1_dn0_cp_mfp,
+                  dsi_dp3_dn1_mfp, dsi_cp_dn0_mfp, dsi_dp2_dn2_mfp,
+                  nand1_d0_ceb1_mfp, nand1_ceb3_mfp, nand1_ceb0_mfp,
+                  csi1_dn0_dp0_mfp, uart4_rx_tx_mfp
+
+
+                  These pin groups are used for selecting the drive strength
+                  parameters.
+
+                  sgpio3_drv, sgpio2_drv, sgpio1_drv, sgpio0_drv,
+                  rmii_tx_d0_d1_drv, rmii_txen_rxer_drv, rmii_crs_dv_drv,
+                  rmii_rx_d1_d0_drv, rmii_ref_clk_drv, rmii_mdc_mdio_drv,
+                  sirq_0_1_drv, sirq2_drv, i2s_d0_d1_drv, i2s_lr_m_clk0_drv,
+                  i2s_blk1_mclk1_drv, pcm1_in_out_drv, lvds_oap_oan_drv,
+                  lvds_oep_odn_drv, lvds_ocp_obn_drv, lvds_e_drv, sd0_d3_d0_drv,
+                  sd1_d3_d0_drv, sd0_sd1_cmd_clk_drv, spi0_sclk_mosi_drv,
+                  spi0_ss_miso_drv, uart0_rx_tx_drv, uart4_rx_tx_drv, uart2_drv,
+                  uart3_drv, i2c0_drv, i2c1_drv, i2c2_drv, sensor0_drv
+
+                  These pin groups are used for selecting the slew rate
+                  parameters.
+
+                  sgpio3_sr, sgpio2_sr, sgpio1_sr, sgpio0_sr, rmii_tx_d0_d1_sr,
+                  rmii_txen_rxer_sr, rmii_crs_dv_sr, rmii_rx_d1_d0_sr,
+                  rmii_ref_clk_sr, rmii_mdc_mdio_sr, sirq_0_1_sr, sirq2_sr,
+                  i2s_do_d1_sr, i2s_lr_m_clk0_sr, i2s_bclk0_mclk1_sr,
+                  pcm1_in_out_sr, sd1_d3_d0_sr, sd0_sd1_clk_cmd_sr,
+                  spi0_sclk_mosi_sr, spi0_ss_miso_sr, uart0_rx_tx_sr,
+                  uart4_rx_tx_sr, uart2_sr, uart3_sr, i2c0_sr, i2c1_sr, i2c2_sr,
+                  sensor0_sr
+
+- function:       An array of strings, each string containing the name of the
+                  pinmux functions. These functions can only be selected by
+                  the corresponding pin groups. The following are the list of
+                  pinmux functions available:
+
+                  eram, eth_rmii, eth_smii, spi0, spi1, spi2, spi3, sens0,
+                  uart0, uart1, uart2, uart3, uart4, uart5, uart6, i2s0, i2s1,
+                  pcm0, pcm1, jtag, pwm0, pwm1, pwm2, pwm3, pwm4, pwm5, sd0,
+                  sd1, sd2, sd3, i2c0, i2c1, i2c2, i2c3, i2c4, i2c5, lvds,
+                  usb30, usb20, gpu, mipi_csi0, mipi_csi1, mipi_dsi, nand0,
+                  nand1, spdif, sirq0, sirq1, sirq2
+
+Optional Properties:
+
+- bias-bus-hold:  No arguments. The specified pins should retain the previous
+                  state value.
+- bias-high-impedance: No arguments. The specified pins should be configured
+                  as high impedance.
+- bias-pull-down: No arguments. The specified pins should be configured as
+                  pull down.
+- bias-pull-up:   No arguments. The specified pins should be configured as
+                  pull up.
+- input-schmitt-enable: No arguments: Enable schmitt trigger for the specified
+                  pins
+- input-schmitt-disable: No arguments: Disable schmitt trigger for the specified
+                  pins
+- slew-rate:      Integer. Sets slew rate for the specified pins.
+                  Valid values are:
+                  <0>  - Slow
+                  <1>  - Fast
+- drive-strength: Integer. Selects the drive strength for the specified
+                  pins in mA.
+                  Valid values are:
+                  <2>
+                  <4>
+                  <8>
+                  <12>
+
+Example:
+
+          pinctrl: pinctrl@e01b0000 {
+                  compatible = "actions,s900-pinctrl";
+                  reg = <0x0 0xe01b0000 0x0 0x1000>;
+                  clocks = <&cmu CLK_GPIO>;
+
+                  uart2-default: uart2-default {
+                          pinmux {
+                                  groups = "lvds_oep_odn_mfp";
+                                  function = "uart2";
+                          };
+                          pinconf {
+                                  groups = "lvds_oep_odn_drv";
+                                  drive-strength = <12>;
+                          };
+                  };
+          };
-- 
2.14.1

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

* [PATCH v4 01/10] dt-bindings: pinctrl: Add bindings for Actions S900 SoC
@ 2018-03-02  3:50   ` Manivannan Sadhasivam
  0 siblings, 0 replies; 43+ messages in thread
From: Manivannan Sadhasivam @ 2018-03-02  3:50 UTC (permalink / raw)
  To: linux-arm-kernel

Add pinctrl bindings for Actions Semi S900 SoC

Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Reviewed-by: Rob Herring <robh@kernel.org>
---
 .../bindings/pinctrl/actions,s900-pinctrl.txt      | 178 +++++++++++++++++++++
 1 file changed, 178 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/actions,s900-pinctrl.txt

diff --git a/Documentation/devicetree/bindings/pinctrl/actions,s900-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/actions,s900-pinctrl.txt
new file mode 100644
index 000000000000..fb87c7d74f2e
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/actions,s900-pinctrl.txt
@@ -0,0 +1,178 @@
+Actions Semi S900 Pin Controller
+
+This binding describes the pin controller found in the S900 SoC.
+
+Required Properties:
+
+- compatible:   Should be "actions,s900-pinctrl"
+- reg:          Should contain the register base address and size of
+                the pin controller.
+- clocks:       phandle of the clock feeding the pin controller
+
+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
+phrase "pin configuration node".
+
+The pin configuration nodes act as a container for an arbitrary number of
+subnodes. Each of these subnodes represents some desired configuration for a
+pin, a group, or a list of pins or groups. This configuration can include the
+mux function to select on those group(s), and various pin configuration
+parameters, such as pull-up, drive strength, etc.
+
+PIN CONFIGURATION NODES:
+
+The name of each subnode is not important; all subnodes should be enumerated
+and processed purely based on their content.
+
+Each subnode only affects those parameters that are explicitly listed. In
+other words, a subnode that lists a mux function but no pin configuration
+parameters implies no information about any pin configuration parameters.
+Similarly, a pin subnode that describes a pullup parameter implies no
+information about e.g. the mux function.
+
+Pinmux functions are available only for the pin groups while pinconf
+parameters are available for both pin groups and individual pins.
+
+The following generic properties as defined in pinctrl-bindings.txt are valid
+to specify in a pin configuration subnode:
+
+Required Properties:
+
+- pins:           An array of strings, each string containing the name of a pin.
+                  These pins are used for selecting the pull control and schmitt
+                  trigger parameters. The following are the list of pins
+                  available:
+
+                  eth_txd0, eth_txd1, eth_txen, eth_rxer, eth_crs_dv,
+                  eth_rxd1, eth_rxd0, eth_ref_clk, eth_mdc, eth_mdio,
+                  sirq0, sirq1, sirq2, i2s_d0, i2s_bclk0, i2s_lrclk0,
+                  i2s_mclk0, i2s_d1, i2s_bclk1, i2s_lrclk1, i2s_mclk1,
+                  pcm1_in, pcm1_clk, pcm1_sync, pcm1_out, eram_a5,
+                  eram_a6, eram_a7, eram_a8, eram_a9, eram_a10, eram_a11,
+                  lvds_oep, lvds_oen, lvds_odp, lvds_odn, lvds_ocp,
+                  lvds_ocn, lvds_obp, lvds_obn, lvds_oap, lvds_oan,
+                  lvds_eep, lvds_een, lvds_edp, lvds_edn, lvds_ecp,
+                  lvds_ecn, lvds_ebp, lvds_ebn, lvds_eap, lvds_ean,
+                  sd0_d0, sd0_d1, sd0_d2, sd0_d3, sd1_d0, sd1_d1,
+                  sd1_d2, sd1_d3, sd0_cmd, sd0_clk, sd1_cmd, sd1_clk,
+                  spi0_sclk, spi0_ss, spi0_miso, spi0_mosi, uart0_rx,
+                  uart0_tx, uart2_rx, uart2_tx, uart2_rtsb, uart2_ctsb,
+                  uart3_rx, uart3_tx, uart3_rtsb, uart3_ctsb, uart4_rx,
+                  uart4_tx, i2c0_sclk, i2c0_sdata, i2c1_sclk, i2c1_sdata,
+                  i2c2_sclk, i2c2_sdata, csi0_dn0, csi0_dp0, csi0_dn1,
+                  csi0_dp1, csi0_cn, csi0_cp, csi0_dn2, csi0_dp2, csi0_dn3,
+                  csi0_dp3, dsi_dp3, dsi_dn3, dsi_dp1, dsi_dn1, dsi_cp,
+                  dsi_cn, dsi_dp0, dsi_dn0, dsi_dp2, dsi_dn2, sensor0_pclk,
+                  csi1_dn0,csi1_dp0,csi1_dn1, csi1_dp1, csi1_cn, csi1_cp,
+                  sensor0_ckout, nand0_d0, nand0_d1, nand0_d2, nand0_d3,
+                  nand0_d4, nand0_d5, nand0_d6, nand0_d7, nand0_dqs,
+                  nand0_dqsn, nand0_ale, nand0_cle, nand0_ceb0, nand0_ceb1,
+                  nand0_ceb2, nand0_ceb3, nand1_d0, nand1_d1, nand1_d2,
+                  nand1_d3, nand1_d4, nand1_d5, nand1_d6, nand1_d7, nand1_dqs,
+                  nand1_dqsn, nand1_ale, nand1_cle, nand1_ceb0, nand1_ceb1,
+                  nand1_ceb2, nand1_ceb3, sgpio0, sgpio1, sgpio2, sgpio3
+
+- groups:         An array of strings, each string containing the name of a pin
+                  group. These pin groups are used for selecting the pinmux
+                  functions.
+
+                  lvds_oxx_uart4_mfp, rmii_mdc_mfp, rmii_mdio_mfp, sirq0_mfp,
+                  sirq1_mfp, rmii_txd0_mfp, rmii_txd1_mfp, rmii_txen_mfp,
+                  rmii_rxer_mfp, rmii_crs_dv_mfp, rmii_rxd1_mfp, rmii_rxd0_mfp,
+                  rmii_ref_clk_mfp, i2s_d0_mfp, i2s_d1_mfp, i2s_lr_m_clk0_mfp,
+                  i2s_bclk0_mfp, i2s_bclk1_mclk1_mfp, pcm1_in_out_mfp,
+                  pcm1_clk_mfp, pcm1_sync_mfp, eram_a5_mfp, eram_a6_mfp,
+                  eram_a7_mfp, eram_a8_mfp, eram_a9_mfp, eram_a10_mfp,
+                  eram_a11_mfp, lvds_oep_odn_mfp, lvds_ocp_obn_mfp,
+                  lvds_oap_oan_mfp, lvds_e_mfp, spi0_sclk_mosi_mfp, spi0_ss_mfp,
+                  spi0_miso_mfp, uart2_rtsb_mfp, uart2_ctsb_mfp, uart3_rtsb_mfp,
+                  uart3_ctsb_mfp, sd0_d0_mfp, sd0_d1_mfp, sd0_d2_d3_mfp,
+                  sd1_d0_d3_mfp, sd0_cmd_mfp, sd0_clk_mfp, sd1_cmd_clk_mfp,
+                  uart0_rx_mfp, nand0_d0_ceb3_mfp, uart0_tx_mfp, i2c0_mfp,
+                  csi0_cn_cp_mfp, csi0_dn0_dp3_mfp, csi1_dn0_cp_mfp,
+                  dsi_dp3_dn1_mfp, dsi_cp_dn0_mfp, dsi_dp2_dn2_mfp,
+                  nand1_d0_ceb1_mfp, nand1_ceb3_mfp, nand1_ceb0_mfp,
+                  csi1_dn0_dp0_mfp, uart4_rx_tx_mfp
+
+
+                  These pin groups are used for selecting the drive strength
+                  parameters.
+
+                  sgpio3_drv, sgpio2_drv, sgpio1_drv, sgpio0_drv,
+                  rmii_tx_d0_d1_drv, rmii_txen_rxer_drv, rmii_crs_dv_drv,
+                  rmii_rx_d1_d0_drv, rmii_ref_clk_drv, rmii_mdc_mdio_drv,
+                  sirq_0_1_drv, sirq2_drv, i2s_d0_d1_drv, i2s_lr_m_clk0_drv,
+                  i2s_blk1_mclk1_drv, pcm1_in_out_drv, lvds_oap_oan_drv,
+                  lvds_oep_odn_drv, lvds_ocp_obn_drv, lvds_e_drv, sd0_d3_d0_drv,
+                  sd1_d3_d0_drv, sd0_sd1_cmd_clk_drv, spi0_sclk_mosi_drv,
+                  spi0_ss_miso_drv, uart0_rx_tx_drv, uart4_rx_tx_drv, uart2_drv,
+                  uart3_drv, i2c0_drv, i2c1_drv, i2c2_drv, sensor0_drv
+
+                  These pin groups are used for selecting the slew rate
+                  parameters.
+
+                  sgpio3_sr, sgpio2_sr, sgpio1_sr, sgpio0_sr, rmii_tx_d0_d1_sr,
+                  rmii_txen_rxer_sr, rmii_crs_dv_sr, rmii_rx_d1_d0_sr,
+                  rmii_ref_clk_sr, rmii_mdc_mdio_sr, sirq_0_1_sr, sirq2_sr,
+                  i2s_do_d1_sr, i2s_lr_m_clk0_sr, i2s_bclk0_mclk1_sr,
+                  pcm1_in_out_sr, sd1_d3_d0_sr, sd0_sd1_clk_cmd_sr,
+                  spi0_sclk_mosi_sr, spi0_ss_miso_sr, uart0_rx_tx_sr,
+                  uart4_rx_tx_sr, uart2_sr, uart3_sr, i2c0_sr, i2c1_sr, i2c2_sr,
+                  sensor0_sr
+
+- function:       An array of strings, each string containing the name of the
+                  pinmux functions. These functions can only be selected by
+                  the corresponding pin groups. The following are the list of
+                  pinmux functions available:
+
+                  eram, eth_rmii, eth_smii, spi0, spi1, spi2, spi3, sens0,
+                  uart0, uart1, uart2, uart3, uart4, uart5, uart6, i2s0, i2s1,
+                  pcm0, pcm1, jtag, pwm0, pwm1, pwm2, pwm3, pwm4, pwm5, sd0,
+                  sd1, sd2, sd3, i2c0, i2c1, i2c2, i2c3, i2c4, i2c5, lvds,
+                  usb30, usb20, gpu, mipi_csi0, mipi_csi1, mipi_dsi, nand0,
+                  nand1, spdif, sirq0, sirq1, sirq2
+
+Optional Properties:
+
+- bias-bus-hold:  No arguments. The specified pins should retain the previous
+                  state value.
+- bias-high-impedance: No arguments. The specified pins should be configured
+                  as high impedance.
+- bias-pull-down: No arguments. The specified pins should be configured as
+                  pull down.
+- bias-pull-up:   No arguments. The specified pins should be configured as
+                  pull up.
+- input-schmitt-enable: No arguments: Enable schmitt trigger for the specified
+                  pins
+- input-schmitt-disable: No arguments: Disable schmitt trigger for the specified
+                  pins
+- slew-rate:      Integer. Sets slew rate for the specified pins.
+                  Valid values are:
+                  <0>  - Slow
+                  <1>  - Fast
+- drive-strength: Integer. Selects the drive strength for the specified
+                  pins in mA.
+                  Valid values are:
+                  <2>
+                  <4>
+                  <8>
+                  <12>
+
+Example:
+
+          pinctrl: pinctrl at e01b0000 {
+                  compatible = "actions,s900-pinctrl";
+                  reg = <0x0 0xe01b0000 0x0 0x1000>;
+                  clocks = <&cmu CLK_GPIO>;
+
+                  uart2-default: uart2-default {
+                          pinmux {
+                                  groups = "lvds_oep_odn_mfp";
+                                  function = "uart2";
+                          };
+                          pinconf {
+                                  groups = "lvds_oep_odn_drv";
+                                  drive-strength = <12>;
+                          };
+                  };
+          };
-- 
2.14.1

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

* [PATCH v4 02/10] arm64: dts: actions: Add pinctrl node for S900
  2018-03-02  3:50 ` Manivannan Sadhasivam
  (?)
@ 2018-03-02  3:50   ` Manivannan Sadhasivam
  -1 siblings, 0 replies; 43+ messages in thread
From: Manivannan Sadhasivam @ 2018-03-02  3:50 UTC (permalink / raw)
  To: linus.walleij, robh+dt, afaerber
  Cc: devicetree, daniel.thompson, manivannanece23, hzhang, bdong,
	liuwei, linux-kernel, amit.kucheria, linux-gpio, mp-cs, 96boards,
	Manivannan Sadhasivam, linux-arm-kernel

Add pinctrl nodes for Actions Semi S900 SoC

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

diff --git a/arch/arm64/boot/dts/actions/s900.dtsi b/arch/arm64/boot/dts/actions/s900.dtsi
index fee0c9557656..0156483f0f4d 100644
--- a/arch/arm64/boot/dts/actions/s900.dtsi
+++ b/arch/arm64/boot/dts/actions/s900.dtsi
@@ -174,6 +174,12 @@
 			#clock-cells = <1>;
 		};
 
+		pinctrl: pinctrl@e01b0000 {
+			compatible = "actions,s900-pinctrl";
+			reg = <0x0 0xe01b0000 0x0 0x1000>;
+			clocks = <&cmu CLK_GPIO>;
+		};
+
 		timer: timer@e0228000 {
 			compatible = "actions,s900-timer";
 			reg = <0x0 0xe0228000 0x0 0x8000>;
-- 
2.14.1

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

* [PATCH v4 02/10] arm64: dts: actions: Add pinctrl node for S900
@ 2018-03-02  3:50   ` Manivannan Sadhasivam
  0 siblings, 0 replies; 43+ messages in thread
From: Manivannan Sadhasivam @ 2018-03-02  3:50 UTC (permalink / raw)
  To: linus.walleij, robh+dt, afaerber
  Cc: liuwei, mp-cs, 96boards, devicetree, daniel.thompson,
	amit.kucheria, linux-arm-kernel, linux-gpio, linux-kernel,
	hzhang, bdong, manivannanece23, Manivannan Sadhasivam

Add pinctrl nodes for Actions Semi S900 SoC

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

diff --git a/arch/arm64/boot/dts/actions/s900.dtsi b/arch/arm64/boot/dts/actions/s900.dtsi
index fee0c9557656..0156483f0f4d 100644
--- a/arch/arm64/boot/dts/actions/s900.dtsi
+++ b/arch/arm64/boot/dts/actions/s900.dtsi
@@ -174,6 +174,12 @@
 			#clock-cells = <1>;
 		};
 
+		pinctrl: pinctrl@e01b0000 {
+			compatible = "actions,s900-pinctrl";
+			reg = <0x0 0xe01b0000 0x0 0x1000>;
+			clocks = <&cmu CLK_GPIO>;
+		};
+
 		timer: timer@e0228000 {
 			compatible = "actions,s900-timer";
 			reg = <0x0 0xe0228000 0x0 0x8000>;
-- 
2.14.1

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

* [PATCH v4 02/10] arm64: dts: actions: Add pinctrl node for S900
@ 2018-03-02  3:50   ` Manivannan Sadhasivam
  0 siblings, 0 replies; 43+ messages in thread
From: Manivannan Sadhasivam @ 2018-03-02  3:50 UTC (permalink / raw)
  To: linux-arm-kernel

Add pinctrl nodes for Actions Semi S900 SoC

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

diff --git a/arch/arm64/boot/dts/actions/s900.dtsi b/arch/arm64/boot/dts/actions/s900.dtsi
index fee0c9557656..0156483f0f4d 100644
--- a/arch/arm64/boot/dts/actions/s900.dtsi
+++ b/arch/arm64/boot/dts/actions/s900.dtsi
@@ -174,6 +174,12 @@
 			#clock-cells = <1>;
 		};
 
+		pinctrl: pinctrl at e01b0000 {
+			compatible = "actions,s900-pinctrl";
+			reg = <0x0 0xe01b0000 0x0 0x1000>;
+			clocks = <&cmu CLK_GPIO>;
+		};
+
 		timer: timer at e0228000 {
 			compatible = "actions,s900-timer";
 			reg = <0x0 0xe0228000 0x0 0x8000>;
-- 
2.14.1

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

* [PATCH v4 03/10] arm64: actions: Enable PINCTRL in platforms Kconfig
  2018-03-02  3:50 ` Manivannan Sadhasivam
  (?)
@ 2018-03-02  3:50   ` Manivannan Sadhasivam
  -1 siblings, 0 replies; 43+ messages in thread
From: Manivannan Sadhasivam @ 2018-03-02  3:50 UTC (permalink / raw)
  To: linus.walleij, robh+dt, afaerber
  Cc: devicetree, daniel.thompson, manivannanece23, hzhang, bdong,
	liuwei, linux-kernel, amit.kucheria, linux-gpio, mp-cs, 96boards,
	Manivannan Sadhasivam, linux-arm-kernel

Select PINCTRL for Actions Semi SoCs

Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
---
 arch/arm64/Kconfig.platforms | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
index fbedbd8f619a..bae1289bdc3f 100644
--- a/arch/arm64/Kconfig.platforms
+++ b/arch/arm64/Kconfig.platforms
@@ -3,6 +3,7 @@ menu "Platform selection"
 config ARCH_ACTIONS
 	bool "Actions Semi Platforms"
 	select OWL_TIMER
+	select PINCTRL
 	help
 	  This enables support for the Actions Semiconductor S900 SoC family.
 
-- 
2.14.1

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

* [PATCH v4 03/10] arm64: actions: Enable PINCTRL in platforms Kconfig
@ 2018-03-02  3:50   ` Manivannan Sadhasivam
  0 siblings, 0 replies; 43+ messages in thread
From: Manivannan Sadhasivam @ 2018-03-02  3:50 UTC (permalink / raw)
  To: linus.walleij, robh+dt, afaerber
  Cc: liuwei, mp-cs, 96boards, devicetree, daniel.thompson,
	amit.kucheria, linux-arm-kernel, linux-gpio, linux-kernel,
	hzhang, bdong, manivannanece23, Manivannan Sadhasivam

Select PINCTRL for Actions Semi SoCs

Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
---
 arch/arm64/Kconfig.platforms | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
index fbedbd8f619a..bae1289bdc3f 100644
--- a/arch/arm64/Kconfig.platforms
+++ b/arch/arm64/Kconfig.platforms
@@ -3,6 +3,7 @@ menu "Platform selection"
 config ARCH_ACTIONS
 	bool "Actions Semi Platforms"
 	select OWL_TIMER
+	select PINCTRL
 	help
 	  This enables support for the Actions Semiconductor S900 SoC family.
 
-- 
2.14.1

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

* [PATCH v4 03/10] arm64: actions: Enable PINCTRL in platforms Kconfig
@ 2018-03-02  3:50   ` Manivannan Sadhasivam
  0 siblings, 0 replies; 43+ messages in thread
From: Manivannan Sadhasivam @ 2018-03-02  3:50 UTC (permalink / raw)
  To: linux-arm-kernel

Select PINCTRL for Actions Semi SoCs

Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
---
 arch/arm64/Kconfig.platforms | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
index fbedbd8f619a..bae1289bdc3f 100644
--- a/arch/arm64/Kconfig.platforms
+++ b/arch/arm64/Kconfig.platforms
@@ -3,6 +3,7 @@ menu "Platform selection"
 config ARCH_ACTIONS
 	bool "Actions Semi Platforms"
 	select OWL_TIMER
+	select PINCTRL
 	help
 	  This enables support for the Actions Semiconductor S900 SoC family.
 
-- 
2.14.1

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

* [PATCH v4 04/10] pinctrl: actions: Add Actions S900 pinctrl driver
  2018-03-02  3:50 ` Manivannan Sadhasivam
@ 2018-03-02  3:50   ` Manivannan Sadhasivam
  -1 siblings, 0 replies; 43+ messages in thread
From: Manivannan Sadhasivam @ 2018-03-02  3:50 UTC (permalink / raw)
  To: linus.walleij, robh+dt, afaerber
  Cc: liuwei, mp-cs, 96boards, devicetree, daniel.thompson,
	amit.kucheria, linux-arm-kernel, linux-gpio, linux-kernel,
	hzhang, bdong, manivannanece23, Manivannan Sadhasivam

Add pinctrl driver for Actions Semi S900 SoC. The driver supports
pinctrl, pinmux and pinconf functionalities through a range of registers
common to both gpio driver and pinctrl driver.

Pinmux functionality is available only for the pin groups while the
pinconf functionality is available for both pin groups and individual
pins.

Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
---
 drivers/pinctrl/Kconfig                |    1 +
 drivers/pinctrl/Makefile               |    1 +
 drivers/pinctrl/actions/Kconfig        |   12 +
 drivers/pinctrl/actions/Makefile       |    2 +
 drivers/pinctrl/actions/pinctrl-owl.c  |  579 ++++++++
 drivers/pinctrl/actions/pinctrl-owl.h  |  142 ++
 drivers/pinctrl/actions/pinctrl-s900.c | 2505 ++++++++++++++++++++++++++++++++
 7 files changed, 3242 insertions(+)
 create mode 100644 drivers/pinctrl/actions/Kconfig
 create mode 100644 drivers/pinctrl/actions/Makefile
 create mode 100644 drivers/pinctrl/actions/pinctrl-owl.c
 create mode 100644 drivers/pinctrl/actions/pinctrl-owl.h
 create mode 100644 drivers/pinctrl/actions/pinctrl-s900.c

diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 0f254b35c378..838c8fff8c24 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -368,6 +368,7 @@ config PINCTRL_OCELOT
 	select GENERIC_PINMUX_FUNCTIONS
 	select REGMAP_MMIO
 
+source "drivers/pinctrl/actions/Kconfig"
 source "drivers/pinctrl/aspeed/Kconfig"
 source "drivers/pinctrl/bcm/Kconfig"
 source "drivers/pinctrl/berlin/Kconfig"
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index d3692633e9ed..fb3497c1a4cb 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -48,6 +48,7 @@ obj-$(CONFIG_PINCTRL_INGENIC)	+= pinctrl-ingenic.o
 obj-$(CONFIG_PINCTRL_RK805)	+= pinctrl-rk805.o
 obj-$(CONFIG_PINCTRL_OCELOT)	+= pinctrl-ocelot.o
 
+obj-y				+= actions/
 obj-$(CONFIG_ARCH_ASPEED)	+= aspeed/
 obj-y				+= bcm/
 obj-$(CONFIG_PINCTRL_BERLIN)	+= berlin/
diff --git a/drivers/pinctrl/actions/Kconfig b/drivers/pinctrl/actions/Kconfig
new file mode 100644
index 000000000000..1c7309c90f0d
--- /dev/null
+++ b/drivers/pinctrl/actions/Kconfig
@@ -0,0 +1,12 @@
+config PINCTRL_OWL
+	bool
+	depends on (ARCH_ACTIONS || COMPILE_TEST) && OF
+	select PINMUX
+	select PINCONF
+	select GENERIC_PINCONF
+
+config PINCTRL_S900
+	bool "Actions Semi S900 pinctrl driver"
+	select PINCTRL_OWL
+	help
+	  Say Y here to enable Actions Semi S900 pinctrl driver
diff --git a/drivers/pinctrl/actions/Makefile b/drivers/pinctrl/actions/Makefile
new file mode 100644
index 000000000000..bd232d28400f
--- /dev/null
+++ b/drivers/pinctrl/actions/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_PINCTRL_OWL)	+= pinctrl-owl.o
+obj-$(CONFIG_PINCTRL_S900) 	+= pinctrl-s900.o
diff --git a/drivers/pinctrl/actions/pinctrl-owl.c b/drivers/pinctrl/actions/pinctrl-owl.c
new file mode 100644
index 000000000000..1a526abebf91
--- /dev/null
+++ b/drivers/pinctrl/actions/pinctrl-owl.c
@@ -0,0 +1,579 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * OWL SoC's Pinctrl driver
+ *
+ * Copyright (c) 2014 Actions Semi Inc.
+ * Author: David Liu <liuwei@actions-semi.com>
+ *
+ * Copyright (c) 2018 Linaro Ltd.
+ * Author: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+ */
+
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pinctrl/machine.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinconf-generic.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+
+#include "../core.h"
+#include "../pinctrl-utils.h"
+#include "pinctrl-owl.h"
+
+/**
+ * struct owl_pinctrl - pinctrl state of the device
+ * @dev: device handle
+ * @pctrldev: pinctrl handle
+ * @lock: spinlock to protect registers
+ * @soc: reference to soc_data
+ * @base: pinctrl register base address
+ */
+struct owl_pinctrl {
+	struct device *dev;
+	struct pinctrl_dev *pctrldev;
+	raw_spinlock_t lock;
+	struct clk *clk;
+	const struct owl_pinctrl_soc_data *soc;
+	void __iomem *base;
+};
+
+static void owl_update_bits(void __iomem *base, u32 mask, u32 val)
+{
+	u32 reg_val;
+
+	reg_val = readl_relaxed(base);
+
+	reg_val &= ~mask;
+	reg_val |= val;
+
+	writel_relaxed(reg_val, base);
+}
+
+static int owl_get_groups_count(struct pinctrl_dev *pctrldev)
+{
+	struct owl_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrldev);
+
+	return pctrl->soc->ngroups;
+}
+
+static const char *owl_get_group_name(struct pinctrl_dev *pctrldev,
+				unsigned int group)
+{
+	struct owl_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrldev);
+
+	return pctrl->soc->groups[group].name;
+}
+
+static int owl_get_group_pins(struct pinctrl_dev *pctrldev,
+				unsigned int group,
+				const unsigned int **pins,
+				unsigned int *num_pins)
+{
+	struct owl_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrldev);
+
+	*pins = pctrl->soc->groups[group].pads;
+	*num_pins = pctrl->soc->groups[group].npads;
+
+	return 0;
+}
+
+static void owl_pin_dbg_show(struct pinctrl_dev *pctrldev,
+				struct seq_file *s,
+				unsigned int offset)
+{
+	struct owl_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrldev);
+
+	seq_printf(s, "%s", dev_name(pctrl->dev));
+}
+
+static struct pinctrl_ops owl_pinctrl_ops = {
+	.get_groups_count = owl_get_groups_count,
+	.get_group_name = owl_get_group_name,
+	.get_group_pins = owl_get_group_pins,
+	.pin_dbg_show = owl_pin_dbg_show,
+	.dt_node_to_map = pinconf_generic_dt_node_to_map_all,
+	.dt_free_map = pinctrl_utils_free_map,
+};
+
+static int owl_get_funcs_count(struct pinctrl_dev *pctrldev)
+{
+	struct owl_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrldev);
+
+	return pctrl->soc->nfunctions;
+}
+
+static const char *owl_get_func_name(struct pinctrl_dev *pctrldev,
+				unsigned int function)
+{
+	struct owl_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrldev);
+
+	return pctrl->soc->functions[function].name;
+}
+
+static int owl_get_func_groups(struct pinctrl_dev *pctrldev,
+				unsigned int function,
+				const char * const **groups,
+				unsigned int * const num_groups)
+{
+	struct owl_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrldev);
+
+	*groups = pctrl->soc->functions[function].groups;
+	*num_groups = pctrl->soc->functions[function].ngroups;
+
+	return 0;
+}
+
+static inline int get_group_mfp_mask_val(const struct owl_pingroup *g,
+				int function,
+				u32 *mask,
+				u32 *val)
+{
+	int id;
+	u32 option_num;
+	u32 option_mask;
+
+	for (id = 0; id < g->nfuncs; id++) {
+		if (g->funcs[id] == function)
+			break;
+	}
+	if (WARN_ON(id == g->nfuncs))
+		return -EINVAL;
+
+	option_num = (1 << g->mfpctl_width);
+	if (id > option_num)
+		id -= option_num;
+
+	option_mask = option_num - 1;
+	*mask = (option_mask  << g->mfpctl_shift);
+	*val = (id << g->mfpctl_shift);
+
+	return 0;
+}
+
+static int owl_set_mux(struct pinctrl_dev *pctrldev,
+				unsigned int function,
+				unsigned int group)
+{
+	struct owl_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrldev);
+	const struct owl_pingroup *g;
+	unsigned long flags;
+	u32 val, mask;
+
+	g = &pctrl->soc->groups[group];
+
+	if (get_group_mfp_mask_val(g, function, &mask, &val))
+		return -EINVAL;
+
+	raw_spin_lock_irqsave(&pctrl->lock, flags);
+
+	owl_update_bits(pctrl->base + g->mfpctl_reg, mask, val);
+
+	raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+
+	return 0;
+}
+
+static struct pinmux_ops owl_pinmux_ops = {
+	.get_functions_count = owl_get_funcs_count,
+	.get_function_name = owl_get_func_name,
+	.get_function_groups = owl_get_func_groups,
+	.set_mux = owl_set_mux,
+};
+
+static int owl_pad_pinconf_reg(const struct owl_padinfo *info,
+				unsigned int param,
+				u32 *reg,
+				u32 *bit,
+				u32 *width)
+{
+	switch (param) {
+	case PIN_CONFIG_BIAS_BUS_HOLD:
+	case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
+	case PIN_CONFIG_BIAS_PULL_DOWN:
+	case PIN_CONFIG_BIAS_PULL_UP:
+		if (!info->pullctl)
+			return -EINVAL;
+		*reg = info->pullctl->reg;
+		*bit = info->pullctl->shift;
+		*width = info->pullctl->width;
+		break;
+	case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
+		if (!info->st)
+			return -EINVAL;
+		*reg = info->st->reg;
+		*bit = info->st->shift;
+		*width = info->st->width;
+		break;
+	default:
+		return -ENOTSUPP;
+	}
+
+	return 0;
+}
+
+static int owl_pad_pinconf_arg2val(const struct owl_padinfo *info,
+				unsigned int param,
+				u32 *arg)
+{
+	switch (param) {
+	case PIN_CONFIG_BIAS_BUS_HOLD:
+		*arg = OWL_PINCONF_PULL_HOLD;
+		break;
+	case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
+		*arg = OWL_PINCONF_PULL_HIZ;
+		break;
+	case PIN_CONFIG_BIAS_PULL_DOWN:
+		*arg = OWL_PINCONF_PULL_DOWN;
+		break;
+	case PIN_CONFIG_BIAS_PULL_UP:
+		*arg = OWL_PINCONF_PULL_UP;
+		break;
+	case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
+		*arg = (*arg >= 1 ? 1 : 0);
+		break;
+	default:
+		return -ENOTSUPP;
+	}
+
+	return 0;
+}
+
+static int owl_pad_pinconf_val2arg(const struct owl_padinfo *padinfo,
+				unsigned int param,
+				u32 *arg)
+{
+	switch (param) {
+	case PIN_CONFIG_BIAS_BUS_HOLD:
+		*arg = *arg == OWL_PINCONF_PULL_HOLD;
+		break;
+	case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
+		*arg = *arg == OWL_PINCONF_PULL_HIZ;
+		break;
+	case PIN_CONFIG_BIAS_PULL_DOWN:
+		*arg = *arg == OWL_PINCONF_PULL_DOWN;
+		break;
+	case PIN_CONFIG_BIAS_PULL_UP:
+		*arg = *arg == OWL_PINCONF_PULL_UP;
+		break;
+	case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
+		*arg = *arg == 1;
+		break;
+	default:
+		return -ENOTSUPP;
+	}
+
+	return 0;
+}
+
+static int owl_pin_config_get(struct pinctrl_dev *pctrldev,
+				unsigned int pin,
+				unsigned long *config)
+{
+	int ret = 0;
+	struct owl_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrldev);
+	const struct owl_padinfo *info;
+	unsigned int param = pinconf_to_config_param(*config);
+	u32 reg, bit, width;
+	u32 tmp, mask;
+	u32 arg = 0;
+
+	info = &pctrl->soc->padinfo[pin];
+
+	ret = owl_pad_pinconf_reg(info, param, &reg, &bit, &width);
+	if (ret)
+		return ret;
+
+	tmp = readl_relaxed(pctrl->base + reg);
+	mask = (1 << width) - 1;
+	arg = (tmp >> bit) & mask;
+
+	ret = owl_pad_pinconf_val2arg(info, param, &arg);
+	if (ret)
+		return ret;
+
+	*config = pinconf_to_config_packed(param, arg);
+
+	return ret;
+}
+
+static int owl_pin_config_set(struct pinctrl_dev *pctrldev,
+				unsigned int pin,
+				unsigned long *configs,
+				unsigned int num_configs)
+{
+	struct owl_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrldev);
+	const struct owl_padinfo *info;
+	unsigned long flags;
+	unsigned int param;
+	u32 reg, bit, width;
+	u32 mask = 0, arg = 0;
+	int ret, i;
+
+	info = &pctrl->soc->padinfo[pin];
+
+	for (i = 0; i < num_configs; i++) {
+		param = pinconf_to_config_param(configs[i]);
+		arg = pinconf_to_config_argument(configs[i]);
+
+		ret = owl_pad_pinconf_reg(info, param, &reg, &bit, &width);
+		if (ret)
+			return ret;
+
+		ret = owl_pad_pinconf_arg2val(info, param, &arg);
+		if (ret)
+			return ret;
+
+		raw_spin_lock_irqsave(&pctrl->lock, flags);
+
+		mask = (1 << width) - 1;
+		mask = mask << bit;
+
+		owl_update_bits(pctrl->base + reg, mask, (arg << bit));
+
+		raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+	}
+
+	return ret;
+}
+
+static int owl_group_pinconf_reg(const struct owl_pingroup *g,
+				unsigned int param,
+				u32 *reg,
+				u32 *bit,
+				u32 *width)
+{
+	switch (param) {
+	case PIN_CONFIG_DRIVE_STRENGTH:
+		if (g->drv_reg < 0)
+			return -EINVAL;
+		*reg = g->drv_reg;
+		*bit = g->drv_shift;
+		*width = g->drv_width;
+		break;
+	case PIN_CONFIG_SLEW_RATE:
+		if (g->sr_reg < 0)
+			return -EINVAL;
+		*reg = g->sr_reg;
+		*bit = g->sr_shift;
+		*width = g->sr_width;
+		break;
+	default:
+		return -ENOTSUPP;
+	}
+
+	return 0;
+}
+
+static int owl_group_pinconf_arg2val(const struct owl_pingroup *g,
+				unsigned int param,
+				u32 *arg)
+{
+	switch (param) {
+	case PIN_CONFIG_DRIVE_STRENGTH:
+		switch (*arg) {
+		case 2:
+			*arg = OWL_PINCONF_DRV_2MA;
+			break;
+		case 4:
+			*arg = OWL_PINCONF_DRV_4MA;
+			break;
+		case 8:
+			*arg = OWL_PINCONF_DRV_8MA;
+			break;
+		case 12:
+			*arg = OWL_PINCONF_DRV_12MA;
+			break;
+		default:
+			return -EINVAL;
+		}
+	case PIN_CONFIG_SLEW_RATE:
+		if (*arg)
+			*arg = OWL_PINCONF_SLEW_FAST;
+		else
+			*arg = OWL_PINCONF_SLEW_SLOW;
+		break;
+	default:
+		return -ENOTSUPP;
+	}
+
+	return 0;
+}
+
+static int owl_group_pinconf_val2arg(const struct owl_pingroup *g,
+				unsigned int param,
+				u32 *arg)
+{
+	switch (param) {
+	case PIN_CONFIG_DRIVE_STRENGTH:
+		switch (*arg) {
+		case OWL_PINCONF_DRV_2MA:
+			*arg = 2;
+			break;
+		case OWL_PINCONF_DRV_4MA:
+			*arg = 4;
+			break;
+		case OWL_PINCONF_DRV_8MA:
+			*arg = 8;
+			break;
+		case OWL_PINCONF_DRV_12MA:
+			*arg = 12;
+			break;
+		default:
+			return -EINVAL;
+		}
+	case PIN_CONFIG_SLEW_RATE:
+		if (*arg)
+			*arg = 1;
+		else
+			*arg = 0;
+		break;
+	default:
+		return -ENOTSUPP;
+	}
+
+	return 0;
+}
+
+static int owl_group_config_get(struct pinctrl_dev *pctrldev,
+				unsigned int group,
+				unsigned long *config)
+{
+	const struct owl_pingroup *g;
+	struct owl_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrldev);
+	unsigned int param = pinconf_to_config_param(*config);
+	u32 reg, bit, width;
+	u32 mask, tmp, arg = 0;
+	int ret;
+
+	g = &pctrl->soc->groups[group];
+
+	ret = owl_group_pinconf_reg(g, param, &reg, &bit, &width);
+	if (ret)
+		return ret;
+
+	tmp = readl_relaxed(pctrl->base + reg);
+	mask = (1 << width) - 1;
+	arg = (tmp >> bit) & mask;
+
+	ret = owl_group_pinconf_val2arg(g, param, &arg);
+	if (ret)
+		return ret;
+
+	*config = pinconf_to_config_packed(param, arg);
+
+	return ret;
+
+}
+
+static int owl_group_config_set(struct pinctrl_dev *pctrldev,
+				unsigned int group,
+				unsigned long *configs,
+				unsigned int num_configs)
+{
+	const struct owl_pingroup *g;
+	struct owl_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrldev);
+	unsigned long flags;
+	unsigned int param;
+	u32 reg, bit, width;
+	u32 mask, arg = 0;
+	int ret, i;
+
+	g = &pctrl->soc->groups[group];
+
+	for (i = 0; i < num_configs; i++) {
+		param = pinconf_to_config_param(configs[i]);
+		arg = pinconf_to_config_argument(configs[i]);
+
+		ret = owl_group_pinconf_reg(g, param, &reg, &bit, &width);
+		if (ret)
+			return ret;
+
+		ret = owl_group_pinconf_arg2val(g, param, &arg);
+		if (ret)
+			return ret;
+
+		/* Update register */
+		raw_spin_lock_irqsave(&pctrl->lock, flags);
+
+		mask = (1 << width) - 1;
+		mask = mask << bit;
+
+		owl_update_bits(pctrl->base + reg, mask, (arg << bit));
+
+		raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+	}
+
+	return 0;
+}
+
+static const struct pinconf_ops owl_pinconf_ops = {
+	.is_generic = true,
+	.pin_config_get = owl_pin_config_get,
+	.pin_config_set = owl_pin_config_set,
+	.pin_config_group_get = owl_group_config_get,
+	.pin_config_group_set = owl_group_config_set
+};
+
+static struct pinctrl_desc owl_pinctrl_desc = {
+	.pctlops = &owl_pinctrl_ops,
+	.pmxops = &owl_pinmux_ops,
+	.confops = &owl_pinconf_ops,
+	.owner = THIS_MODULE
+};
+
+int owl_pinctrl_probe(struct platform_device *pdev,
+				struct owl_pinctrl_soc_data *soc_data)
+{
+	struct resource *res;
+	struct owl_pinctrl *pctrl;
+	int ret;
+
+	pctrl = devm_kzalloc(&pdev->dev, sizeof(*pctrl), GFP_KERNEL);
+	if (!pctrl)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	pctrl->base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(pctrl->base))
+		return PTR_ERR(pctrl->base);
+
+	/* enable GPIO/MFP clock */
+	pctrl->clk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(pctrl->clk)) {
+		dev_err(&pdev->dev, "no clock defined\n");
+		return PTR_ERR(pctrl->clk);
+	}
+
+	ret = clk_prepare_enable(pctrl->clk);
+	if (ret) {
+		dev_err(&pdev->dev, "clk enable failed\n");
+		return ret;
+	}
+
+	raw_spin_lock_init(&pctrl->lock);
+
+	owl_pinctrl_desc.name = dev_name(&pdev->dev);
+	owl_pinctrl_desc.pins = soc_data->pins;
+	owl_pinctrl_desc.npins = soc_data->npins;
+
+	pctrl->soc = soc_data;
+	pctrl->dev = &pdev->dev;
+
+	pctrl->pctrldev = devm_pinctrl_register(&pdev->dev,
+					&owl_pinctrl_desc, pctrl);
+	if (IS_ERR(pctrl->pctrldev)) {
+		dev_err(&pdev->dev, "could not register Actions OWL pinmux driver\n");
+		return PTR_ERR(pctrl->pctrldev);
+	}
+
+	platform_set_drvdata(pdev, pctrl);
+
+	return 0;
+}
diff --git a/drivers/pinctrl/actions/pinctrl-owl.h b/drivers/pinctrl/actions/pinctrl-owl.h
new file mode 100644
index 000000000000..448f81a6db3b
--- /dev/null
+++ b/drivers/pinctrl/actions/pinctrl-owl.h
@@ -0,0 +1,142 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * OWL SoC's Pinctrl definitions
+ *
+ * Copyright (c) 2014 Actions Semi Inc.
+ * Author: David Liu <liuwei@actions-semi.com>
+ *
+ * Copyright (c) 2018 Linaro Ltd.
+ * Author: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+ */
+
+#ifndef __PINCTRL_OWL_H__
+#define __PINCTRL_OWL_H__
+
+#define OWL_PINCONF_SLEW_SLOW 0
+#define OWL_PINCONF_SLEW_FAST 1
+
+enum owl_pinconf_pull {
+	OWL_PINCONF_PULL_HIZ,
+	OWL_PINCONF_PULL_DOWN,
+	OWL_PINCONF_PULL_UP,
+	OWL_PINCONF_PULL_HOLD,
+};
+
+enum owl_pinconf_drv {
+	OWL_PINCONF_DRV_2MA,
+	OWL_PINCONF_DRV_4MA,
+	OWL_PINCONF_DRV_8MA,
+	OWL_PINCONF_DRV_12MA,
+};
+
+/**
+ * struct owl_pullctl - Actions pad pull control register
+ * @reg: offset to the pull control register
+ * @shift: shift value of the register
+ * @width: width of the register
+ */
+struct owl_pullctl {
+	int reg;
+	unsigned int shift;
+	unsigned int width;
+};
+
+/**
+ * struct owl_st - Actions pad schmitt trigger enable register
+ * @reg: offset to the schmitt trigger enable register
+ * @shift: shift value of the register
+ * @width: width of the register
+ */
+struct owl_st {
+	int reg;
+	unsigned int shift;
+	unsigned int width;
+};
+
+/**
+ * struct owl_pingroup - Actions pingroup definition
+ * @name: name of the  pin group
+ * @pads: list of pins assigned to this pingroup
+ * @npads: size of @pads array
+ * @funcs: list of pinmux functions for this pingroup
+ * @nfuncs: size of @funcs array
+ * @mfpctl_reg: multiplexing control register offset
+ * @mfpctl_shift: multiplexing control register bit mask
+ * @mfpctl_width: multiplexing control register width
+ * @drv_reg: drive control register offset
+ * @drv_shift: drive control register bit mask
+ * @drv_width: driver control register width
+ * @sr_reg: slew rate control register offset
+ * @sr_shift: slew rate control register bit mask
+ * @sr_width: slew rate control register width
+ */
+struct owl_pingroup {
+	const char *name;
+	unsigned int *pads;
+	unsigned int npads;
+	unsigned int *funcs;
+	unsigned int nfuncs;
+
+	int mfpctl_reg;
+	unsigned int mfpctl_shift;
+	unsigned int mfpctl_width;
+
+	int drv_reg;
+	unsigned int drv_shift;
+	unsigned int drv_width;
+
+	int sr_reg;
+	unsigned int sr_shift;
+	unsigned int sr_width;
+};
+
+/**
+ * struct owl_padinfo - Actions pinctrl pad info
+ * @pad: pad name of the SoC
+ * @pullctl: pull control register info
+ * @st: schmitt trigger register info
+ */
+struct owl_padinfo {
+	int pad;
+	struct owl_pullctl *pullctl;
+	struct owl_st *st;
+};
+
+/**
+ * struct owl_pinmux_func - Actions pinctrl mux functions
+ * @name: name of the pinmux function.
+ * @groups: array of pin groups that may select this function.
+ * @ngroups: number of entries in @groups.
+ */
+struct owl_pinmux_func {
+	const char *name;
+	const char * const *groups;
+	unsigned int ngroups;
+};
+
+/**
+ * struct owl_pinctrl_soc_data - Actions pin controller driver configuration
+ * @pins: array describing all pins of the pin controller.
+ * @npins: number of entries in @pins.
+ * @functions: array describing all mux functions of this SoC.
+ * @nfunction: number of entries in @functions.
+ * @groups: array describing all pin groups of this SoC.
+ * @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.
+ */
+struct owl_pinctrl_soc_data {
+	const struct pinctrl_pin_desc *pins;
+	unsigned int npins;
+	const struct owl_pinmux_func *functions;
+	unsigned int nfunctions;
+	const struct owl_pingroup *groups;
+	unsigned int ngroups;
+	const struct owl_padinfo *padinfo;
+	unsigned int ngpios;
+};
+
+int owl_pinctrl_probe(struct platform_device *pdev,
+		struct owl_pinctrl_soc_data *soc_data);
+
+#endif /* __PINCTRL_OWL_H__ */
diff --git a/drivers/pinctrl/actions/pinctrl-s900.c b/drivers/pinctrl/actions/pinctrl-s900.c
new file mode 100644
index 000000000000..f320ddaea865
--- /dev/null
+++ b/drivers/pinctrl/actions/pinctrl-s900.c
@@ -0,0 +1,2505 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * OWL S900 Pinctrl driver
+ *
+ * Copyright (c) 2014 Actions Semi Inc.
+ * Author: David Liu <liuwei@actions-semi.com>
+ *
+ * Copyright (c) 2018 Linaro Ltd.
+ * Author: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+ */
+
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pinctrl/pinctrl.h>
+#include "pinctrl-owl.h"
+
+/* Pinctrl registers offset */
+#define MFCTL0			(0x0040)
+#define MFCTL1			(0x0044)
+#define MFCTL2			(0x0048)
+#define MFCTL3			(0x004C)
+#define PAD_PULLCTL0		(0x0060)
+#define PAD_PULLCTL1		(0x0064)
+#define PAD_PULLCTL2		(0x0068)
+#define PAD_ST0			(0x006C)
+#define PAD_ST1			(0x0070)
+#define PAD_CTL			(0x0074)
+#define PAD_DRV0		(0x0080)
+#define PAD_DRV1		(0x0084)
+#define PAD_DRV2		(0x0088)
+#define PAD_SR0			(0x0270)
+#define PAD_SR1			(0x0274)
+#define PAD_SR2			(0x0278)
+
+#define _GPIOA(offset)		(offset)
+#define _GPIOB(offset)		(32 + (offset))
+#define _GPIOC(offset)		(64 + (offset))
+#define _GPIOD(offset)		(76 + (offset))
+#define _GPIOE(offset)		(106 + (offset))
+#define _GPIOF(offset)		(138 + (offset))
+
+#define NUM_GPIOS		(_GPIOF(7) + 1)
+#define _PIN(offset)		(NUM_GPIOS + (offset))
+
+#define ETH_TXD0		_GPIOA(0)
+#define ETH_TXD1		_GPIOA(1)
+#define ETH_TXEN		_GPIOA(2)
+#define ETH_RXER		_GPIOA(3)
+#define ETH_CRS_DV		_GPIOA(4)
+#define ETH_RXD1		_GPIOA(5)
+#define ETH_RXD0		_GPIOA(6)
+#define ETH_REF_CLK		_GPIOA(7)
+#define ETH_MDC			_GPIOA(8)
+#define ETH_MDIO		_GPIOA(9)
+#define SIRQ0			_GPIOA(10)
+#define SIRQ1			_GPIOA(11)
+#define SIRQ2			_GPIOA(12)
+#define I2S_D0			_GPIOA(13)
+#define I2S_BCLK0		_GPIOA(14)
+#define I2S_LRCLK0		_GPIOA(15)
+#define I2S_MCLK0		_GPIOA(16)
+#define I2S_D1			_GPIOA(17)
+#define I2S_BCLK1		_GPIOA(18)
+#define I2S_LRCLK1		_GPIOA(19)
+#define I2S_MCLK1		_GPIOA(20)
+#define ERAM_A5			_GPIOA(21)
+#define ERAM_A6			_GPIOA(22)
+#define ERAM_A7			_GPIOA(23)
+#define ERAM_A8			_GPIOA(24)
+#define ERAM_A9			_GPIOA(25)
+#define ERAM_A10		_GPIOA(26)
+#define ERAM_A11		_GPIOA(27)
+#define SD0_D0			_GPIOA(28)
+#define SD0_D1			_GPIOA(29)
+#define SD0_D2			_GPIOA(30)
+#define SD0_D3			_GPIOA(31)
+
+#define SD1_D0			_GPIOB(0)
+#define SD1_D1			_GPIOB(1)
+#define SD1_D2			_GPIOB(2)
+#define SD1_D3			_GPIOB(3)
+#define SD0_CMD			_GPIOB(4)
+#define SD0_CLK			_GPIOB(5)
+#define SD1_CMD			_GPIOB(6)
+#define SD1_CLK			_GPIOB(7)
+#define SPI0_SCLK		_GPIOB(8)
+#define SPI0_SS			_GPIOB(9)
+#define SPI0_MISO		_GPIOB(10)
+#define SPI0_MOSI		_GPIOB(11)
+#define UART0_RX		_GPIOB(12)
+#define UART0_TX		_GPIOB(13)
+#define UART2_RX		_GPIOB(14)
+#define UART2_TX		_GPIOB(15)
+#define UART2_RTSB		_GPIOB(16)
+#define UART2_CTSB		_GPIOB(17)
+#define UART4_RX		_GPIOB(18)
+#define UART4_TX		_GPIOB(19)
+#define I2C0_SCLK		_GPIOB(20)
+#define I2C0_SDATA		_GPIOB(21)
+#define I2C1_SCLK		_GPIOB(22)
+#define I2C1_SDATA		_GPIOB(23)
+#define I2C2_SCLK		_GPIOB(24)
+#define I2C2_SDATA		_GPIOB(25)
+#define CSI0_DN0		_GPIOB(26)
+#define CSI0_DP0		_GPIOB(27)
+#define CSI0_DN1		_GPIOB(28)
+#define CSI0_DP1		_GPIOB(29)
+#define CSI0_CN			_GPIOB(30)
+#define CSI0_CP			_GPIOB(31)
+
+#define CSI0_DN2		_GPIOC(0)
+#define CSI0_DP2		_GPIOC(1)
+#define CSI0_DN3		_GPIOC(2)
+#define CSI0_DP3		_GPIOC(3)
+#define SENSOR0_PCLK		_GPIOC(4)
+#define CSI1_DN0		_GPIOC(5)
+#define CSI1_DP0		_GPIOC(6)
+#define CSI1_DN1		_GPIOC(7)
+#define CSI1_DP1		_GPIOC(8)
+#define CSI1_CN			_GPIOC(9)
+#define CSI1_CP			_GPIOC(10)
+#define SENSOR0_CKOUT		_GPIOC(11)
+
+#define LVDS_OEP		_GPIOD(0)
+#define LVDS_OEN		_GPIOD(1)
+#define LVDS_ODP		_GPIOD(2)
+#define LVDS_ODN		_GPIOD(3)
+#define LVDS_OCP		_GPIOD(4)
+#define LVDS_OCN		_GPIOD(5)
+#define LVDS_OBP		_GPIOD(6)
+#define LVDS_OBN		_GPIOD(7)
+#define LVDS_OAP		_GPIOD(8)
+#define LVDS_OAN		_GPIOD(9)
+#define LVDS_EEP		_GPIOD(10)
+#define LVDS_EEN		_GPIOD(11)
+#define LVDS_EDP		_GPIOD(12)
+#define LVDS_EDN		_GPIOD(13)
+#define LVDS_ECP		_GPIOD(14)
+#define LVDS_ECN		_GPIOD(15)
+#define LVDS_EBP		_GPIOD(16)
+#define LVDS_EBN		_GPIOD(17)
+#define LVDS_EAP		_GPIOD(18)
+#define LVDS_EAN		_GPIOD(19)
+#define DSI_DP3			_GPIOD(20)
+#define DSI_DN3			_GPIOD(21)
+#define DSI_DP1			_GPIOD(22)
+#define DSI_DN1			_GPIOD(23)
+#define DSI_CP			_GPIOD(24)
+#define DSI_CN			_GPIOD(25)
+#define DSI_DP0			_GPIOD(26)
+#define DSI_DN0			_GPIOD(27)
+#define DSI_DP2			_GPIOD(28)
+#define DSI_DN2			_GPIOD(29)
+
+#define NAND0_D0		_GPIOE(0)
+#define NAND0_D1		_GPIOE(1)
+#define NAND0_D2		_GPIOE(2)
+#define NAND0_D3		_GPIOE(3)
+#define NAND0_D4		_GPIOE(4)
+#define NAND0_D5		_GPIOE(5)
+#define NAND0_D6		_GPIOE(6)
+#define NAND0_D7		_GPIOE(7)
+#define NAND0_DQS		_GPIOE(8)
+#define NAND0_DQSN		_GPIOE(9)
+#define NAND0_ALE		_GPIOE(10)
+#define NAND0_CLE		_GPIOE(11)
+#define NAND0_CEB0		_GPIOE(12)
+#define NAND0_CEB1		_GPIOE(13)
+#define NAND0_CEB2		_GPIOE(14)
+#define NAND0_CEB3		_GPIOE(15)
+#define NAND1_D0		_GPIOE(16)
+#define NAND1_D1		_GPIOE(17)
+#define NAND1_D2		_GPIOE(18)
+#define NAND1_D3		_GPIOE(19)
+#define NAND1_D4		_GPIOE(20)
+#define NAND1_D5		_GPIOE(21)
+#define NAND1_D6		_GPIOE(22)
+#define NAND1_D7		_GPIOE(23)
+#define NAND1_DQS		_GPIOE(24)
+#define NAND1_DQSN		_GPIOE(25)
+#define NAND1_ALE		_GPIOE(26)
+#define NAND1_CLE		_GPIOE(27)
+#define NAND1_CEB0		_GPIOE(28)
+#define NAND1_CEB1		_GPIOE(29)
+#define NAND1_CEB2		_GPIOE(30)
+#define NAND1_CEB3		_GPIOE(31)
+
+#define PCM1_IN			_GPIOF(0)
+#define PCM1_CLK		_GPIOF(1)
+#define PCM1_SYNC		_GPIOF(2)
+#define PCM1_OUT		_GPIOF(3)
+#define UART3_RX		_GPIOF(4)
+#define UART3_TX		_GPIOF(5)
+#define UART3_RTSB		_GPIOF(6)
+#define UART3_CTSB		_GPIOF(7)
+
+/* System */
+#define SGPIO0			_PIN(0)
+#define SGPIO1			_PIN(1)
+#define SGPIO2			_PIN(2)
+#define SGPIO3			_PIN(3)
+
+#define NUM_PADS		(_PIN(3) + 1)
+
+/* Pad names as specified in datasheet */
+const struct pinctrl_pin_desc s900_pads[] = {
+	PINCTRL_PIN(ETH_TXD0, "eth_txd0"),
+	PINCTRL_PIN(ETH_TXD1, "eth_txd1"),
+	PINCTRL_PIN(ETH_TXEN, "eth_txen"),
+	PINCTRL_PIN(ETH_RXER, "eth_rxer"),
+	PINCTRL_PIN(ETH_CRS_DV, "eth_crs_dv"),
+	PINCTRL_PIN(ETH_RXD1, "eth_rxd1"),
+	PINCTRL_PIN(ETH_RXD0, "eth_rxd0"),
+	PINCTRL_PIN(ETH_REF_CLK, "eth_ref_clk"),
+	PINCTRL_PIN(ETH_MDC, "eth_mdc"),
+	PINCTRL_PIN(ETH_MDIO, "eth_mdio"),
+	PINCTRL_PIN(SIRQ0, "sirq0"),
+	PINCTRL_PIN(SIRQ1, "sirq1"),
+	PINCTRL_PIN(SIRQ2, "sirq2"),
+	PINCTRL_PIN(I2S_D0, "i2s_d0"),
+	PINCTRL_PIN(I2S_BCLK0, "i2s_bclk0"),
+	PINCTRL_PIN(I2S_LRCLK0, "i2s_lrclk0"),
+	PINCTRL_PIN(I2S_MCLK0, "i2s_mclk0"),
+	PINCTRL_PIN(I2S_D1, "i2s_d1"),
+	PINCTRL_PIN(I2S_BCLK1, "i2s_bclk1"),
+	PINCTRL_PIN(I2S_LRCLK1, "i2s_lrclk1"),
+	PINCTRL_PIN(I2S_MCLK1, "i2s_mclk1"),
+	PINCTRL_PIN(PCM1_IN, "pcm1_in"),
+	PINCTRL_PIN(PCM1_CLK, "pcm1_clk"),
+	PINCTRL_PIN(PCM1_SYNC, "pcm1_sync"),
+	PINCTRL_PIN(PCM1_OUT, "pcm1_out"),
+	PINCTRL_PIN(ERAM_A5, "eram_a5"),
+	PINCTRL_PIN(ERAM_A6, "eram_a6"),
+	PINCTRL_PIN(ERAM_A7, "eram_a7"),
+	PINCTRL_PIN(ERAM_A8, "eram_a8"),
+	PINCTRL_PIN(ERAM_A9, "eram_a9"),
+	PINCTRL_PIN(ERAM_A10, "eram_a10"),
+	PINCTRL_PIN(ERAM_A11, "eram_a11"),
+	PINCTRL_PIN(LVDS_OEP, "lvds_oep"),
+	PINCTRL_PIN(LVDS_OEN, "lvds_oen"),
+	PINCTRL_PIN(LVDS_ODP, "lvds_odp"),
+	PINCTRL_PIN(LVDS_ODN, "lvds_odn"),
+	PINCTRL_PIN(LVDS_OCP, "lvds_ocp"),
+	PINCTRL_PIN(LVDS_OCN, "lvds_ocn"),
+	PINCTRL_PIN(LVDS_OBP, "lvds_obp"),
+	PINCTRL_PIN(LVDS_OBN, "lvds_obn"),
+	PINCTRL_PIN(LVDS_OAP, "lvds_oap"),
+	PINCTRL_PIN(LVDS_OAN, "lvds_oan"),
+	PINCTRL_PIN(LVDS_EEP, "lvds_eep"),
+	PINCTRL_PIN(LVDS_EEN, "lvds_een"),
+	PINCTRL_PIN(LVDS_EDP, "lvds_edp"),
+	PINCTRL_PIN(LVDS_EDN, "lvds_edn"),
+	PINCTRL_PIN(LVDS_ECP, "lvds_ecp"),
+	PINCTRL_PIN(LVDS_ECN, "lvds_ecn"),
+	PINCTRL_PIN(LVDS_EBP, "lvds_ebp"),
+	PINCTRL_PIN(LVDS_EBN, "lvds_ebn"),
+	PINCTRL_PIN(LVDS_EAP, "lvds_eap"),
+	PINCTRL_PIN(LVDS_EAN, "lvds_ean"),
+	PINCTRL_PIN(SD0_D0, "sd0_d0"),
+	PINCTRL_PIN(SD0_D1, "sd0_d1"),
+	PINCTRL_PIN(SD0_D2, "sd0_d2"),
+	PINCTRL_PIN(SD0_D3, "sd0_d3"),
+	PINCTRL_PIN(SD1_D0, "sd1_d0"),
+	PINCTRL_PIN(SD1_D1, "sd1_d1"),
+	PINCTRL_PIN(SD1_D2, "sd1_d2"),
+	PINCTRL_PIN(SD1_D3, "sd1_d3"),
+	PINCTRL_PIN(SD0_CMD, "sd0_cmd"),
+	PINCTRL_PIN(SD0_CLK, "sd0_clk"),
+	PINCTRL_PIN(SD1_CMD, "sd1_cmd"),
+	PINCTRL_PIN(SD1_CLK, "sd1_clk"),
+	PINCTRL_PIN(SPI0_SCLK, "spi0_sclk"),
+	PINCTRL_PIN(SPI0_SS, "spi0_ss"),
+	PINCTRL_PIN(SPI0_MISO, "spi0_miso"),
+	PINCTRL_PIN(SPI0_MOSI, "spi0_mosi"),
+	PINCTRL_PIN(UART0_RX, "uart0_rx"),
+	PINCTRL_PIN(UART0_TX, "uart0_tx"),
+	PINCTRL_PIN(UART2_RX, "uart2_rx"),
+	PINCTRL_PIN(UART2_TX, "uart2_tx"),
+	PINCTRL_PIN(UART2_RTSB, "uart2_rtsb"),
+	PINCTRL_PIN(UART2_CTSB, "uart2_ctsb"),
+	PINCTRL_PIN(UART3_RX, "uart3_rx"),
+	PINCTRL_PIN(UART3_TX, "uart3_tx"),
+	PINCTRL_PIN(UART3_RTSB, "uart3_rtsb"),
+	PINCTRL_PIN(UART3_CTSB, "uart3_ctsb"),
+	PINCTRL_PIN(UART4_RX, "uart4_rx"),
+	PINCTRL_PIN(UART4_TX, "uart4_tx"),
+	PINCTRL_PIN(I2C0_SCLK, "i2c0_sclk"),
+	PINCTRL_PIN(I2C0_SDATA, "i2c0_sdata"),
+	PINCTRL_PIN(I2C1_SCLK, "i2c1_sclk"),
+	PINCTRL_PIN(I2C1_SDATA, "i2c1_sdata"),
+	PINCTRL_PIN(I2C2_SCLK, "i2c2_sclk"),
+	PINCTRL_PIN(I2C2_SDATA, "i2c2_sdata"),
+	PINCTRL_PIN(CSI0_DN0, "csi0_dn0"),
+	PINCTRL_PIN(CSI0_DP0, "csi0_dp0"),
+	PINCTRL_PIN(CSI0_DN1, "csi0_dn1"),
+	PINCTRL_PIN(CSI0_DP1, "csi0_dp1"),
+	PINCTRL_PIN(CSI0_CN, "csi0_cn"),
+	PINCTRL_PIN(CSI0_CP, "csi0_cp"),
+	PINCTRL_PIN(CSI0_DN2, "csi0_dn2"),
+	PINCTRL_PIN(CSI0_DP2, "csi0_dp2"),
+	PINCTRL_PIN(CSI0_DN3, "csi0_dn3"),
+	PINCTRL_PIN(CSI0_DP3, "csi0_dp3"),
+	PINCTRL_PIN(DSI_DP3, "dsi_dp3"),
+	PINCTRL_PIN(DSI_DN3, "dsi_dn3"),
+	PINCTRL_PIN(DSI_DP1, "dsi_dp1"),
+	PINCTRL_PIN(DSI_DN1, "dsi_dn1"),
+	PINCTRL_PIN(DSI_CP, "dsi_cp"),
+	PINCTRL_PIN(DSI_CN, "dsi_cn"),
+	PINCTRL_PIN(DSI_DP0, "dsi_dp0"),
+	PINCTRL_PIN(DSI_DN0, "dsi_dn0"),
+	PINCTRL_PIN(DSI_DP2, "dsi_dp2"),
+	PINCTRL_PIN(DSI_DN2, "dsi_dn2"),
+	PINCTRL_PIN(SENSOR0_PCLK, "sensor0_pclk"),
+	PINCTRL_PIN(CSI1_DN0, "csi1_dn0"),
+	PINCTRL_PIN(CSI1_DP0, "csi1_dp0"),
+	PINCTRL_PIN(CSI1_DN1, "csi1_dn1"),
+	PINCTRL_PIN(CSI1_DP1, "csi1_dp1"),
+	PINCTRL_PIN(CSI1_CN, "csi1_cn"),
+	PINCTRL_PIN(CSI1_CP, "csi1_cp"),
+	PINCTRL_PIN(SENSOR0_CKOUT, "sensor0_ckout"),
+	PINCTRL_PIN(NAND0_D0, "nand0_d0"),
+	PINCTRL_PIN(NAND0_D1, "nand0_d1"),
+	PINCTRL_PIN(NAND0_D2, "nand0_d2"),
+	PINCTRL_PIN(NAND0_D3, "nand0_d3"),
+	PINCTRL_PIN(NAND0_D4, "nand0_d4"),
+	PINCTRL_PIN(NAND0_D5, "nand0_d5"),
+	PINCTRL_PIN(NAND0_D6, "nand0_d6"),
+	PINCTRL_PIN(NAND0_D7, "nand0_d7"),
+	PINCTRL_PIN(NAND0_DQS, "nand0_dqs"),
+	PINCTRL_PIN(NAND0_DQSN, "nand0_dqsn"),
+	PINCTRL_PIN(NAND0_ALE, "nand0_ale"),
+	PINCTRL_PIN(NAND0_CLE, "nand0_cle"),
+	PINCTRL_PIN(NAND0_CEB0, "nand0_ceb0"),
+	PINCTRL_PIN(NAND0_CEB1, "nand0_ceb1"),
+	PINCTRL_PIN(NAND0_CEB2, "nand0_ceb2"),
+	PINCTRL_PIN(NAND0_CEB3, "nand0_ceb3"),
+	PINCTRL_PIN(NAND1_D0, "nand1_d0"),
+	PINCTRL_PIN(NAND1_D1, "nand1_d1"),
+	PINCTRL_PIN(NAND1_D2, "nand1_d2"),
+	PINCTRL_PIN(NAND1_D3, "nand1_d3"),
+	PINCTRL_PIN(NAND1_D4, "nand1_d4"),
+	PINCTRL_PIN(NAND1_D5, "nand1_d5"),
+	PINCTRL_PIN(NAND1_D6, "nand1_d6"),
+	PINCTRL_PIN(NAND1_D7, "nand1_d7"),
+	PINCTRL_PIN(NAND1_DQS, "nand1_dqs"),
+	PINCTRL_PIN(NAND1_DQSN, "nand1_dqsn"),
+	PINCTRL_PIN(NAND1_ALE, "nand1_ale"),
+	PINCTRL_PIN(NAND1_CLE, "nand1_cle"),
+	PINCTRL_PIN(NAND1_CEB0, "nand1_ceb0"),
+	PINCTRL_PIN(NAND1_CEB1, "nand1_ceb1"),
+	PINCTRL_PIN(NAND1_CEB2, "nand1_ceb2"),
+	PINCTRL_PIN(NAND1_CEB3, "nand1_ceb3"),
+	PINCTRL_PIN(SGPIO0, "sgpio0"),
+	PINCTRL_PIN(SGPIO1, "sgpio1"),
+	PINCTRL_PIN(SGPIO2, "sgpio2"),
+	PINCTRL_PIN(SGPIO3, "sgpio3")
+};
+
+enum s900_pinmux_functions {
+	S900_MUX_ERAM,
+	S900_MUX_ETH_RMII,
+	S900_MUX_ETH_SMII,
+	S900_MUX_SPI0,
+	S900_MUX_SPI1,
+	S900_MUX_SPI2,
+	S900_MUX_SPI3,
+	S900_MUX_SENS0,
+	S900_MUX_UART0,
+	S900_MUX_UART1,
+	S900_MUX_UART2,
+	S900_MUX_UART3,
+	S900_MUX_UART4,
+	S900_MUX_UART5,
+	S900_MUX_UART6,
+	S900_MUX_I2S0,
+	S900_MUX_I2S1,
+	S900_MUX_PCM0,
+	S900_MUX_PCM1,
+	S900_MUX_JTAG,
+	S900_MUX_PWM0,
+	S900_MUX_PWM1,
+	S900_MUX_PWM2,
+	S900_MUX_PWM3,
+	S900_MUX_PWM4,
+	S900_MUX_PWM5,
+	S900_MUX_SD0,
+	S900_MUX_SD1,
+	S900_MUX_SD2,
+	S900_MUX_SD3,
+	S900_MUX_I2C0,
+	S900_MUX_I2C1,
+	S900_MUX_I2C2,
+	S900_MUX_I2C3,
+	S900_MUX_I2C4,
+	S900_MUX_I2C5,
+	S900_MUX_LVDS,
+	S900_MUX_USB20,
+	S900_MUX_USB30,
+	S900_MUX_GPU,
+	S900_MUX_MIPI_CSI0,
+	S900_MUX_MIPI_CSI1,
+	S900_MUX_MIPI_DSI,
+	S900_MUX_NAND0,
+	S900_MUX_NAND1,
+	S900_MUX_SPDIF,
+	S900_MUX_SIRQ0,
+	S900_MUX_SIRQ1,
+	S900_MUX_SIRQ2,
+	S900_MUX_AUX_START,
+	S900_MUX_MAX,
+	S900_MUX_RESERVED
+};
+
+/* mfp0_22 */
+static unsigned int lvds_oxx_uart4_mfp_pads[] = {
+	LVDS_OAP,
+	LVDS_OAN,
+};
+
+static unsigned int lvds_oxx_uart4_mfp_funcs[] = {
+	S900_MUX_ERAM,
+	S900_MUX_UART4,
+};
+
+/* mfp0_21_20 */
+static unsigned int rmii_mdc_mfp_pads[] = {
+	ETH_MDC,
+};
+
+static unsigned int rmii_mdc_mfp_funcs[] = {
+	S900_MUX_ETH_RMII,
+	S900_MUX_PWM2,
+	S900_MUX_UART2,
+	S900_MUX_RESERVED,
+};
+
+static unsigned int rmii_mdio_mfp_pads[] = {
+	ETH_MDIO,
+};
+
+static unsigned int rmii_mdio_mfp_funcs[] = {
+	S900_MUX_ETH_RMII,
+	S900_MUX_PWM3,
+	S900_MUX_UART2,
+	S900_MUX_RESERVED,
+};
+
+/* mfp0_19 */
+static unsigned int sirq0_mfp_pads[] = {
+	SIRQ0,
+};
+
+static unsigned int sirq0_mfp_funcs[] = {
+	S900_MUX_SIRQ0,
+	S900_MUX_PWM0,
+};
+
+static unsigned int sirq1_mfp_pads[] = {
+	SIRQ1,
+};
+
+static unsigned int sirq1_mfp_funcs[] = {
+	S900_MUX_SIRQ1,
+	S900_MUX_PWM1,
+};
+
+/* mfp0_18_16 */
+static unsigned int rmii_txd0_mfp_pads[] = {
+	ETH_TXD0,
+};
+
+static unsigned int rmii_txd0_mfp_funcs[] = {
+	S900_MUX_ETH_RMII,
+	S900_MUX_ETH_SMII,
+	S900_MUX_SPI2,
+	S900_MUX_UART6,
+	S900_MUX_SENS0,
+	S900_MUX_PWM0,
+};
+
+static unsigned int rmii_txd1_mfp_pads[] = {
+	ETH_TXD1,
+};
+
+static unsigned int rmii_txd1_mfp_funcs[] = {
+	S900_MUX_ETH_RMII,
+	S900_MUX_ETH_SMII,
+	S900_MUX_SPI2,
+	S900_MUX_UART6,
+	S900_MUX_SENS0,
+	S900_MUX_PWM1,
+};
+
+/* mfp0_15_13 */
+static unsigned int rmii_txen_mfp_pads[] = {
+	ETH_TXEN,
+};
+
+static unsigned int rmii_txen_mfp_funcs[] = {
+	S900_MUX_ETH_RMII,
+	S900_MUX_UART2,
+	S900_MUX_SPI3,
+	S900_MUX_RESERVED,
+	S900_MUX_RESERVED,
+	S900_MUX_PWM2,
+	S900_MUX_SENS0,
+};
+
+static unsigned int rmii_rxer_mfp_pads[] = {
+	ETH_RXER,
+};
+
+static unsigned int rmii_rxer_mfp_funcs[] = {
+	S900_MUX_ETH_RMII,
+	S900_MUX_UART2,
+	S900_MUX_SPI3,
+	S900_MUX_RESERVED,
+	S900_MUX_RESERVED,
+	S900_MUX_PWM3,
+	S900_MUX_SENS0,
+};
+
+/* mfp0_12_11 */
+static unsigned int rmii_crs_dv_mfp_pads[] = {
+	ETH_CRS_DV,
+};
+
+static unsigned int rmii_crs_dv_mfp_funcs[] = {
+	S900_MUX_ETH_RMII,
+	S900_MUX_ETH_SMII,
+	S900_MUX_SPI2,
+	S900_MUX_UART4,
+};
+
+/* mfp0_10_8 */
+static unsigned int rmii_rxd1_mfp_pads[] = {
+	ETH_RXD1,
+};
+
+static unsigned int rmii_rxd1_mfp_funcs[] = {
+	S900_MUX_ETH_RMII,
+	S900_MUX_UART2,
+	S900_MUX_SPI3,
+	S900_MUX_RESERVED,
+	S900_MUX_UART5,
+	S900_MUX_PWM0,
+	S900_MUX_SENS0,
+};
+
+static unsigned int rmii_rxd0_mfp_pads[] = {
+	ETH_RXD0,
+};
+
+static unsigned int rmii_rxd0_mfp_funcs[] = {
+	S900_MUX_ETH_RMII,
+	S900_MUX_UART2,
+	S900_MUX_SPI3,
+	S900_MUX_RESERVED,
+	S900_MUX_UART5,
+	S900_MUX_PWM1,
+	S900_MUX_SENS0,
+};
+
+/* mfp0_7_6 */
+static unsigned int rmii_ref_clk_mfp_pads[] = {
+	ETH_REF_CLK,
+};
+
+static unsigned int rmii_ref_clk_mfp_funcs[] = {
+	S900_MUX_ETH_RMII,
+	S900_MUX_UART4,
+	S900_MUX_SPI2,
+	S900_MUX_RESERVED,
+};
+
+/* mfp0_5 */
+static unsigned int i2s_d0_mfp_pads[] = {
+	I2S_D0,
+};
+
+static unsigned int i2s_d0_mfp_funcs[] = {
+	S900_MUX_I2S0,
+	S900_MUX_PCM0,
+};
+
+static unsigned int i2s_d1_mfp_pads[] = {
+	I2S_D1,
+};
+
+static unsigned int i2s_d1_mfp_funcs[] = {
+	S900_MUX_I2S1,
+	S900_MUX_PCM0,
+};
+
+/* mfp0_4_3 */
+static unsigned int i2s_lr_m_clk0_mfp_pads[] = {
+	I2S_LRCLK0,
+	I2S_MCLK0,
+};
+
+static unsigned int i2s_lr_m_clk0_mfp_funcs[] = {
+	S900_MUX_I2S0,
+	S900_MUX_PCM0,
+	S900_MUX_PCM1,
+	S900_MUX_RESERVED,
+};
+
+/* mfp0_2 */
+static unsigned int i2s_bclk0_mfp_pads[] = {
+	I2S_BCLK0,
+};
+
+static unsigned int i2s_bclk0_mfp_funcs[] = {
+	S900_MUX_I2S0,
+	S900_MUX_PCM0,
+};
+
+static unsigned int i2s_bclk1_mclk1_mfp_pads[] = {
+	I2S_BCLK1,
+	I2S_LRCLK1,
+	I2S_MCLK1,
+};
+
+static unsigned int i2s_bclk1_mclk1_mfp_funcs[] = {
+	S900_MUX_I2S1,
+	S900_MUX_PCM0,
+};
+
+/* mfp0_1_0 */
+static unsigned int pcm1_in_out_mfp_pads[] = {
+	PCM1_IN,
+	PCM1_OUT,
+};
+
+static unsigned int pcm1_in_out_mfp_funcs[] = {
+	S900_MUX_PCM1,
+	S900_MUX_SPI1,
+	S900_MUX_I2C3,
+	S900_MUX_UART4,
+};
+
+static unsigned int pcm1_clk_mfp_pads[] = {
+	PCM1_CLK,
+};
+
+static unsigned int pcm1_clk_mfp_funcs[] = {
+	S900_MUX_PCM1,
+	S900_MUX_SPI1,
+	S900_MUX_PWM4,
+	S900_MUX_UART4,
+};
+
+static unsigned int pcm1_sync_mfp_pads[] = {
+	PCM1_SYNC,
+};
+
+static unsigned int pcm1_sync_mfp_funcs[] = {
+	S900_MUX_PCM1,
+	S900_MUX_SPI1,
+	S900_MUX_PWM5,
+	S900_MUX_UART4,
+};
+
+/* mfp1_31_29 */
+static unsigned int eram_a5_mfp_pads[] = {
+	ERAM_A5,
+};
+
+static unsigned int eram_a5_mfp_funcs[] = {
+	S900_MUX_UART4,
+	S900_MUX_JTAG,
+	S900_MUX_ERAM,
+	S900_MUX_PWM0,
+	S900_MUX_RESERVED,
+	S900_MUX_SENS0,
+};
+
+static unsigned int eram_a6_mfp_pads[] = {
+	ERAM_A6,
+};
+
+static unsigned int eram_a6_mfp_funcs[] = {
+	S900_MUX_UART4,
+	S900_MUX_JTAG,
+	S900_MUX_ERAM,
+	S900_MUX_PWM1,
+	S900_MUX_RESERVED,
+	S900_MUX_SENS0,
+};
+
+static unsigned int eram_a7_mfp_pads[] = {
+	ERAM_A7,
+};
+
+static unsigned int eram_a7_mfp_funcs[] = {
+	S900_MUX_RESERVED,
+	S900_MUX_JTAG,
+	S900_MUX_ERAM,
+	S900_MUX_RESERVED,
+	S900_MUX_RESERVED,
+	S900_MUX_SENS0,
+};
+
+/* mfp1_28_26 */
+static unsigned int eram_a8_mfp_pads[] = {
+	ERAM_A8,
+};
+
+static unsigned int eram_a8_mfp_funcs[] = {
+	S900_MUX_RESERVED,
+	S900_MUX_JTAG,
+	S900_MUX_ERAM,
+	S900_MUX_PWM1,
+	S900_MUX_RESERVED,
+	S900_MUX_SENS0,
+};
+
+static unsigned int eram_a9_mfp_pads[] = {
+	ERAM_A9,
+};
+
+static unsigned int eram_a9_mfp_funcs[] = {
+	S900_MUX_USB20,
+	S900_MUX_UART5,
+	S900_MUX_ERAM,
+	S900_MUX_PWM2,
+	S900_MUX_RESERVED,
+	S900_MUX_SENS0,
+};
+
+static unsigned int eram_a10_mfp_pads[] = {
+	ERAM_A10,
+};
+
+static unsigned int eram_a10_mfp_funcs[] = {
+	S900_MUX_USB30,
+	S900_MUX_JTAG,
+	S900_MUX_ERAM,
+	S900_MUX_PWM3,
+	S900_MUX_RESERVED,
+	S900_MUX_SENS0,
+	S900_MUX_RESERVED,
+	S900_MUX_RESERVED,
+};
+
+/* mfp1_25_23 */
+static unsigned int eram_a11_mfp_pads[] = {
+	ERAM_A11,
+};
+
+static unsigned int eram_a11_mfp_funcs[] = {
+	S900_MUX_RESERVED,
+	S900_MUX_RESERVED,
+	S900_MUX_ERAM,
+	S900_MUX_PWM2,
+	S900_MUX_UART5,
+	S900_MUX_RESERVED,
+	S900_MUX_SENS0,
+	S900_MUX_RESERVED,
+};
+
+/* mfp1_22 */
+static unsigned int lvds_oep_odn_mfp_pads[] = {
+	LVDS_OEP,
+	LVDS_OEN,
+	LVDS_ODP,
+	LVDS_ODN,
+};
+
+static unsigned int lvds_oep_odn_mfp_funcs[] = {
+	S900_MUX_LVDS,
+	S900_MUX_UART2,
+};
+
+static unsigned int lvds_ocp_obn_mfp_pads[] = {
+	LVDS_OCP,
+	LVDS_OCN,
+	LVDS_OBP,
+	LVDS_OBN,
+};
+
+static unsigned int lvds_ocp_obn_mfp_funcs[] = {
+	S900_MUX_LVDS,
+	S900_MUX_PCM1,
+};
+
+static unsigned int lvds_oap_oan_mfp_pads[] = {
+	LVDS_OAP,
+	LVDS_OAN,
+};
+
+static unsigned int lvds_oap_oan_mfp_funcs[] = {
+	S900_MUX_LVDS,
+	S900_MUX_ERAM,
+};
+
+/* mfp1_21 */
+static unsigned int lvds_e_mfp_pads[] = {
+	LVDS_EEP,
+	LVDS_EEN,
+	LVDS_EDP,
+	LVDS_EDN,
+	LVDS_ECP,
+	LVDS_ECN,
+	LVDS_EBP,
+	LVDS_EBN,
+	LVDS_EAP,
+	LVDS_EAN,
+};
+
+static unsigned int lvds_e_mfp_funcs[] = {
+	S900_MUX_LVDS,
+	S900_MUX_ERAM,
+};
+
+/* mfp1_5_4 */
+static unsigned int spi0_sclk_mosi_mfp_pads[] = {
+	SPI0_SCLK,
+	SPI0_MOSI,
+};
+
+static unsigned int spi0_sclk_mosi_mfp_funcs[] = {
+	S900_MUX_SPI0,
+	S900_MUX_ERAM,
+	S900_MUX_I2C3,
+	S900_MUX_PCM0,
+};
+
+/* mfp1_3_1 */
+static unsigned int spi0_ss_mfp_pads[] = {
+	SPI0_SS,
+};
+
+static unsigned int spi0_ss_mfp_funcs[] = {
+	S900_MUX_SPI0,
+	S900_MUX_ERAM,
+	S900_MUX_I2S1,
+	S900_MUX_PCM1,
+	S900_MUX_PCM0,
+	S900_MUX_PWM4,
+};
+
+static unsigned int spi0_miso_mfp_pads[] = {
+	SPI0_MISO,
+};
+
+static unsigned int spi0_miso_mfp_funcs[] = {
+	S900_MUX_SPI0,
+	S900_MUX_ERAM,
+	S900_MUX_I2S1,
+	S900_MUX_PCM1,
+	S900_MUX_PCM0,
+	S900_MUX_PWM5,
+};
+
+/* mfp2_23 */
+static unsigned int uart2_rtsb_mfp_pads[] = {
+	UART2_RTSB,
+};
+
+static unsigned int uart2_rtsb_mfp_funcs[] = {
+	S900_MUX_UART2,
+	S900_MUX_UART0,
+};
+
+/* mfp2_22 */
+static unsigned int uart2_ctsb_mfp_pads[] = {
+	UART2_CTSB,
+};
+
+static unsigned int uart2_ctsb_mfp_funcs[] = {
+	S900_MUX_UART2,
+	S900_MUX_UART0,
+};
+
+/* mfp2_21 */
+static unsigned int uart3_rtsb_mfp_pads[] = {
+	UART3_RTSB,
+};
+
+static unsigned int uart3_rtsb_mfp_funcs[] = {
+	S900_MUX_UART3,
+	S900_MUX_UART5,
+};
+
+/* mfp2_20 */
+static unsigned int uart3_ctsb_mfp_pads[] = {
+	UART3_CTSB,
+};
+
+static unsigned int uart3_ctsb_mfp_funcs[] = {
+	S900_MUX_UART3,
+	S900_MUX_UART5,
+};
+
+/* mfp2_19_17 */
+static unsigned int sd0_d0_mfp_pads[] = {
+	SD0_D0,
+};
+
+static unsigned int sd0_d0_mfp_funcs[] = {
+	S900_MUX_SD0,
+	S900_MUX_ERAM,
+	S900_MUX_RESERVED,
+	S900_MUX_JTAG,
+	S900_MUX_UART2,
+	S900_MUX_UART5,
+	S900_MUX_GPU,
+};
+
+/* mfp2_16_14 */
+static unsigned int sd0_d1_mfp_pads[] = {
+	SD0_D1,
+};
+
+static unsigned int sd0_d1_mfp_funcs[] = {
+	S900_MUX_SD0,
+	S900_MUX_ERAM,
+	S900_MUX_GPU,
+	S900_MUX_RESERVED,
+	S900_MUX_UART2,
+	S900_MUX_UART5,
+};
+
+/* mfp_13_11 */
+static unsigned int sd0_d2_d3_mfp_pads[] = {
+	SD0_D2,
+	SD0_D3,
+};
+
+static unsigned int sd0_d2_d3_mfp_funcs[] = {
+	S900_MUX_SD0,
+	S900_MUX_ERAM,
+	S900_MUX_RESERVED,
+	S900_MUX_JTAG,
+	S900_MUX_UART2,
+	S900_MUX_UART1,
+	S900_MUX_GPU,
+};
+
+/* mfp2_10_9 */
+static unsigned int sd1_d0_d3_mfp_pads[] = {
+	SD1_D0,
+	SD1_D1,
+	SD1_D2,
+	SD1_D3,
+};
+
+static unsigned int sd1_d0_d3_mfp_funcs[] = {
+	S900_MUX_SD1,
+	S900_MUX_ERAM,
+};
+
+/* mfp2_8_7 */
+static unsigned int sd0_cmd_mfp_pads[] = {
+	SD0_CMD,
+};
+
+static unsigned int sd0_cmd_mfp_funcs[] = {
+	S900_MUX_SD0,
+	S900_MUX_ERAM,
+	S900_MUX_GPU,
+	S900_MUX_JTAG,
+};
+
+/* mfp2_6_5 */
+static unsigned int sd0_clk_mfp_pads[] = {
+	SD0_CLK,
+};
+
+static unsigned int sd0_clk_mfp_funcs[] = {
+	S900_MUX_SD0,
+	S900_MUX_ERAM,
+	S900_MUX_JTAG,
+	S900_MUX_GPU,
+};
+
+/* mfp2_4_3 */
+static unsigned int sd1_cmd_clk_mfp_pads[] = {
+	SD1_CMD,
+	SD1_CLK,
+};
+
+static unsigned int sd1_cmd_clk_mfp_funcs[] = {
+	S900_MUX_SD1,
+	S900_MUX_ERAM,
+};
+
+/* mfp2_2_0 */
+static unsigned int uart0_rx_mfp_pads[] = {
+	UART0_RX,
+};
+
+static unsigned int uart0_rx_mfp_funcs[] = {
+	S900_MUX_UART0,
+	S900_MUX_UART2,
+	S900_MUX_SPI1,
+	S900_MUX_I2C5,
+	S900_MUX_PCM1,
+	S900_MUX_I2S1,
+};
+
+
+/* mfp3_27 */
+static unsigned int nand0_d0_ceb3_mfp_pads[] = {
+	NAND0_D0,
+	NAND0_D1,
+	NAND0_D2,
+	NAND0_D3,
+	NAND0_D4,
+	NAND0_D5,
+	NAND0_D6,
+	NAND0_D7,
+	NAND0_DQSN,
+	NAND0_CEB3,
+};
+
+static unsigned int nand0_d0_ceb3_mfp_funcs[] = {
+	S900_MUX_NAND0,
+	S900_MUX_SD2,
+};
+
+
+/* mfp3_21_19 */
+static unsigned int uart0_tx_mfp_pads[] = {
+	UART0_TX,
+};
+
+static unsigned int uart0_tx_mfp_funcs[] = {
+	S900_MUX_UART0,
+	S900_MUX_UART2,
+	S900_MUX_SPI1,
+	S900_MUX_I2C5,
+	S900_MUX_SPDIF,
+	S900_MUX_PCM1,
+	S900_MUX_I2S1,
+};
+
+/* mfp3_18_16 */
+static unsigned int i2c0_mfp_pads[] = {
+	I2C0_SCLK,
+	I2C0_SDATA,
+};
+
+static unsigned int i2c0_mfp_funcs[] = {
+	S900_MUX_I2C0,
+	S900_MUX_UART2,
+	S900_MUX_I2C1,
+	S900_MUX_UART1,
+	S900_MUX_SPI1,
+};
+
+/* mfp3_15 */
+static unsigned int csi0_cn_cp_mfp_pads[] = {
+	CSI0_CN,
+	CSI0_CP,
+};
+
+static unsigned int csi0_cn_cp_mfp_funcs[] = {
+	S900_MUX_SENS0,
+	S900_MUX_SENS0,
+};
+
+/* mfp3_14 */
+static unsigned int csi0_dn0_dp3_mfp_pads[] = {
+	CSI0_DN0,
+	CSI0_DP0,
+	CSI0_DN1,
+	CSI0_DP1,
+	CSI0_CN,
+	CSI0_CP,
+	CSI0_DP2,
+	CSI0_DN2,
+	CSI0_DN3,
+	CSI0_DP3,
+};
+
+static unsigned int csi0_dn0_dp3_mfp_funcs[] = {
+	S900_MUX_MIPI_CSI0,
+	S900_MUX_SENS0,
+};
+
+/* mfp3_13 */
+static unsigned int csi1_dn0_cp_mfp_pads[] = {
+	CSI1_DN0,
+	CSI1_DP0,
+	CSI1_DN1,
+	CSI1_DP1,
+	CSI1_CN,
+	CSI1_CP,
+};
+
+static unsigned int csi1_dn0_cp_mfp_funcs[] = {
+	S900_MUX_MIPI_CSI1,
+	S900_MUX_SENS0,
+};
+
+
+/* mfp3_12_dsi */
+static unsigned int dsi_dp3_dn1_mfp_pads[] = {
+	DSI_DP3,
+	DSI_DN2,
+	DSI_DP1,
+	DSI_DN1,
+};
+
+static unsigned int dsi_dp3_dn1_mfp_funcs[] = {
+	S900_MUX_MIPI_DSI,
+	S900_MUX_UART2,
+};
+
+static unsigned int dsi_cp_dn0_mfp_pads[] = {
+	DSI_CP,
+	DSI_CN,
+	DSI_DP0,
+	DSI_DN0,
+};
+
+static unsigned int dsi_cp_dn0_mfp_funcs[] = {
+	S900_MUX_MIPI_DSI,
+	S900_MUX_PCM1,
+};
+
+static unsigned int dsi_dp2_dn2_mfp_pads[] = {
+	DSI_DP2,
+	DSI_DN2,
+};
+
+static unsigned int dsi_dp2_dn2_mfp_funcs[] = {
+	S900_MUX_MIPI_DSI,
+	S900_MUX_UART4,
+};
+
+/* mfp3_11 */
+static unsigned int nand1_d0_ceb1_mfp_pads[] = {
+	NAND1_D0,
+	NAND1_D1,
+	NAND1_D2,
+	NAND1_D3,
+	NAND1_D4,
+	NAND1_D5,
+	NAND1_D6,
+	NAND1_D7,
+	NAND1_DQSN,
+	NAND1_CEB1,
+};
+
+static unsigned int nand1_d0_ceb1_mfp_funcs[] = {
+	S900_MUX_NAND1,
+	S900_MUX_SD3,
+};
+
+/* mfp3_10 */
+static unsigned int nand1_ceb3_mfp_pads[] = {
+	NAND1_CEB3,
+};
+
+static unsigned int nand1_ceb3_mfp_funcs[] = {
+	S900_MUX_NAND1,
+	S900_MUX_PWM0,
+};
+
+static unsigned int nand1_ceb0_mfp_pads[] = {
+	NAND1_CEB0,
+};
+
+static unsigned int nand1_ceb0_mfp_funcs[] = {
+	S900_MUX_NAND1,
+	S900_MUX_PWM1,
+};
+
+/* mfp3_9 */
+static unsigned int csi1_dn0_dp0_mfp_pads[] = {
+	CSI1_DN0,
+	CSI1_DP0,
+};
+
+static unsigned int csi1_dn0_dp0_mfp_funcs[] = {
+	S900_MUX_SENS0,
+	S900_MUX_SENS0,
+};
+
+/* mfp3_8 */
+static unsigned int uart4_rx_tx_mfp_pads[] = {
+	UART4_RX,
+	UART4_TX,
+};
+
+static unsigned int uart4_rx_tx_mfp_funcs[] = {
+	S900_MUX_UART4,
+	S900_MUX_I2C4,
+};
+
+
+/* PADDRV group data */
+
+/* drv0 */
+static unsigned int sgpio3_drv_pads[] = {
+	SGPIO3,
+};
+
+static unsigned int sgpio2_drv_pads[] = {
+	SGPIO2,
+};
+
+static unsigned int sgpio1_drv_pads[] = {
+	SGPIO1,
+};
+
+static unsigned int sgpio0_drv_pads[] = {
+	SGPIO0,
+};
+
+static unsigned int rmii_tx_d0_d1_drv_pads[] = {
+	ETH_TXD0,
+	ETH_TXD1,
+};
+
+static unsigned int rmii_txen_rxer_drv_pads[] = {
+	ETH_TXEN,
+	ETH_RXER,
+};
+
+static unsigned int rmii_crs_dv_drv_pads[] = {
+	ETH_CRS_DV,
+};
+
+static unsigned int rmii_rx_d1_d0_drv_pads[] = {
+	ETH_RXD1,
+	ETH_RXD0,
+};
+
+static unsigned int rmii_ref_clk_drv_pads[] = {
+	ETH_REF_CLK,
+};
+
+static unsigned int rmii_mdc_mdio_drv_pads[] = {
+	ETH_MDC,
+	ETH_MDIO,
+};
+
+static unsigned int sirq_0_1_drv_pads[] = {
+	SIRQ0,
+	SIRQ1,
+};
+
+static unsigned int sirq2_drv_pads[] = {
+	SIRQ2,
+};
+
+static unsigned int i2s_d0_d1_drv_pads[] = {
+	I2S_D0,
+	I2S_D1,
+};
+
+static unsigned int i2s_lr_m_clk0_drv_pads[] = {
+	I2S_LRCLK0,
+	I2S_MCLK0,
+};
+
+static unsigned int i2s_blk1_mclk1_drv_pads[] = {
+	I2S_BCLK0,
+	I2S_BCLK1,
+	I2S_LRCLK1,
+	I2S_MCLK1,
+};
+
+static unsigned int pcm1_in_out_drv_pads[] = {
+	PCM1_IN,
+	PCM1_CLK,
+	PCM1_SYNC,
+	PCM1_OUT,
+};
+
+/* drv1 */
+static unsigned int lvds_oap_oan_drv_pads[] = {
+	LVDS_OAP,
+	LVDS_OAN,
+};
+
+static unsigned int lvds_oep_odn_drv_pads[] = {
+	LVDS_OEP,
+	LVDS_OEN,
+	LVDS_ODP,
+	LVDS_ODN,
+};
+
+static unsigned int lvds_ocp_obn_drv_pads[] = {
+	LVDS_OCP,
+	LVDS_OCN,
+	LVDS_OBP,
+	LVDS_OBN,
+};
+
+static unsigned int lvds_e_drv_pads[] = {
+	LVDS_EEP,
+	LVDS_EEN,
+	LVDS_EDP,
+	LVDS_EDN,
+	LVDS_ECP,
+	LVDS_ECN,
+	LVDS_EBP,
+	LVDS_EBN,
+};
+
+static unsigned int sd0_d3_d0_drv_pads[] = {
+	SD0_D3,
+	SD0_D2,
+	SD0_D1,
+	SD0_D0,
+};
+static unsigned int sd1_d3_d0_drv_pads[] = {
+	SD1_D3,
+	SD1_D2,
+	SD1_D1,
+	SD1_D0,
+};
+
+static unsigned int sd0_sd1_cmd_clk_drv_pads[] = {
+	SD0_CLK,
+	SD0_CMD,
+	SD1_CLK,
+	SD1_CMD,
+};
+
+static unsigned int spi0_sclk_mosi_drv_pads[] = {
+	SPI0_SCLK,
+	SPI0_MOSI,
+};
+
+static unsigned int spi0_ss_miso_drv_pads[] = {
+	SPI0_SS,
+	SPI0_MISO,
+};
+
+static unsigned int uart0_rx_tx_drv_pads[] = {
+	UART0_RX,
+	UART0_TX,
+};
+
+static unsigned int uart4_rx_tx_drv_pads[] = {
+	UART4_RX,
+	UART4_TX,
+};
+
+static unsigned int uart2_drv_pads[] = {
+	UART2_RX,
+	UART2_TX,
+	UART2_RTSB,
+	UART2_CTSB,
+};
+
+static unsigned int uart3_drv_pads[] = {
+	UART3_RX,
+	UART3_TX,
+	UART3_RTSB,
+	UART3_CTSB,
+};
+
+/* drv2 */
+static unsigned int i2c0_drv_pads[] = {
+	I2C0_SCLK,
+	I2C0_SDATA,
+};
+
+static unsigned int i2c1_drv_pads[] = {
+	I2C1_SCLK,
+	I2C1_SDATA,
+};
+
+static unsigned int i2c2_drv_pads[] = {
+	I2C2_SCLK,
+	I2C2_SDATA,
+};
+
+static unsigned int sensor0_drv_pads[] = {
+	SENSOR0_PCLK,
+	SENSOR0_CKOUT,
+};
+
+/* SR group data */
+
+/* sr0 */
+static unsigned int sgpio3_sr_pads[] = {
+	SGPIO3,
+};
+
+static unsigned int sgpio2_sr_pads[] = {
+	SGPIO2,
+};
+
+static unsigned int sgpio1_sr_pads[] = {
+	SGPIO1,
+};
+
+static unsigned int sgpio0_sr_pads[] = {
+	SGPIO0,
+};
+
+static unsigned int rmii_tx_d0_d1_sr_pads[] = {
+	ETH_TXD0,
+	ETH_TXD1,
+};
+
+static unsigned int rmii_txen_rxer_sr_pads[] = {
+	ETH_TXEN,
+	ETH_RXER,
+};
+
+static unsigned int rmii_crs_dv_sr_pads[] = {
+	ETH_CRS_DV,
+};
+
+static unsigned int rmii_rx_d1_d0_sr_pads[] = {
+	ETH_RXD1,
+	ETH_RXD0,
+};
+
+static unsigned int rmii_ref_clk_sr_pads[] = {
+	ETH_REF_CLK,
+};
+
+static unsigned int rmii_mdc_mdio_sr_pads[] = {
+	ETH_MDC,
+	ETH_MDIO,
+};
+
+static unsigned int sirq_0_1_sr_pads[] = {
+	SIRQ0,
+	SIRQ1,
+};
+
+static unsigned int sirq2_sr_pads[] = {
+	SIRQ2,
+};
+
+static unsigned int i2s_do_d1_sr_pads[] = {
+	I2S_D0,
+	I2S_D1,
+};
+
+static unsigned int i2s_lr_m_clk0_sr_pads[] = {
+	I2S_LRCLK0,
+	I2S_MCLK0,
+};
+
+static unsigned int i2s_bclk0_mclk1_sr_pads[] = {
+	I2S_BCLK0,
+	I2S_BCLK1,
+	I2S_LRCLK1,
+	I2S_MCLK1,
+};
+
+static unsigned int pcm1_in_out_sr_pads[] = {
+	PCM1_IN,
+	PCM1_CLK,
+	PCM1_SYNC,
+	PCM1_OUT,
+};
+
+/* sr1 */
+static unsigned int sd1_d3_d0_sr_pads[] = {
+	SD1_D3,
+	SD1_D2,
+	SD1_D1,
+	SD1_D0,
+};
+
+static unsigned int sd0_sd1_clk_cmd_sr_pads[] = {
+	SD0_CLK,
+	SD0_CMD,
+	SD1_CLK,
+	SD1_CMD,
+};
+
+static unsigned int spi0_sclk_mosi_sr_pads[] = {
+	SPI0_SCLK,
+	SPI0_MOSI,
+};
+
+static unsigned int spi0_ss_miso_sr_pads[] = {
+	SPI0_SS,
+	SPI0_MISO,
+};
+
+static unsigned int uart0_rx_tx_sr_pads[] = {
+	UART0_RX,
+	UART0_TX,
+};
+
+static unsigned int uart4_rx_tx_sr_pads[] = {
+	UART4_RX,
+	UART4_TX,
+};
+
+static unsigned int uart2_sr_pads[] = {
+	UART2_RX,
+	UART2_TX,
+	UART2_RTSB,
+	UART2_CTSB,
+};
+
+static unsigned int uart3_sr_pads[] = {
+	UART3_RX,
+	UART3_TX,
+	UART3_RTSB,
+	UART3_CTSB,
+};
+
+/* sr2 */
+static unsigned int i2c0_sr_pads[] = {
+	I2C0_SCLK,
+	I2C0_SDATA,
+};
+
+static unsigned int i2c1_sr_pads[] = {
+	I2C1_SCLK,
+	I2C1_SDATA,
+};
+
+static unsigned int i2c2_sr_pads[] = {
+	I2C2_SCLK,
+	I2C2_SDATA,
+};
+
+static unsigned int sensor0_sr_pads[] = {
+	SENSOR0_PCLK,
+	SENSOR0_CKOUT,
+};
+
+#define MUX_PG(group_name, reg, shift, width)				\
+	{								\
+		.name = #group_name,					\
+		.pads = group_name##_pads,				\
+		.npads = ARRAY_SIZE(group_name##_pads),			\
+		.funcs = group_name##_funcs,				\
+		.nfuncs = ARRAY_SIZE(group_name##_funcs),		\
+		.mfpctl_reg  = MFCTL##reg,				\
+		.mfpctl_shift = shift,					\
+		.mfpctl_width = width,					\
+		.drv_reg = -1,						\
+		.drv_shift = -1,					\
+		.drv_width = -1,					\
+		.sr_reg = -1,						\
+		.sr_shift = -1,						\
+		.sr_width = -1,						\
+	}
+
+#define DRV_PG(group_name, reg, shift, width)				\
+	{								\
+		.name = #group_name,					\
+		.pads = group_name##_pads,				\
+		.npads = ARRAY_SIZE(group_name##_pads),			\
+		.mfpctl_reg  = -1,					\
+		.mfpctl_shift = -1,					\
+		.mfpctl_width = -1,					\
+		.drv_reg = PAD_DRV##reg,				\
+		.drv_shift = shift,					\
+		.drv_width = width,					\
+		.sr_reg = -1,						\
+		.sr_shift = -1,						\
+		.sr_width = -1,						\
+	}
+
+#define SR_PG(group_name, reg, shift, width)				\
+	{								\
+		.name = #group_name,					\
+		.pads = group_name##_pads,				\
+		.npads = ARRAY_SIZE(group_name##_pads),			\
+		.mfpctl_reg  = -1,					\
+		.mfpctl_shift = -1,					\
+		.mfpctl_width = -1,					\
+		.drv_reg = -1,						\
+		.drv_shift = -1,					\
+		.drv_width = -1,					\
+		.sr_reg = PAD_SR##reg,					\
+		.sr_shift = shift,					\
+		.sr_width = width,					\
+	}
+
+/* Pinctrl groups */
+static const struct owl_pingroup s900_groups[] = {
+	MUX_PG(lvds_oxx_uart4_mfp, 0, 22, 1),
+	MUX_PG(rmii_mdc_mfp, 0, 20, 2),
+	MUX_PG(rmii_mdio_mfp, 0, 20, 2),
+	MUX_PG(sirq0_mfp, 0, 19, 1),
+	MUX_PG(sirq1_mfp, 0, 19, 1),
+	MUX_PG(rmii_txd0_mfp, 0, 16, 3),
+	MUX_PG(rmii_txd1_mfp, 0, 16, 3),
+	MUX_PG(rmii_txen_mfp, 0, 13, 3),
+	MUX_PG(rmii_rxer_mfp, 0, 13, 3),
+	MUX_PG(rmii_crs_dv_mfp, 0, 11, 2),
+	MUX_PG(rmii_rxd1_mfp, 0, 8, 3),
+	MUX_PG(rmii_rxd0_mfp, 0, 8, 3),
+	MUX_PG(rmii_ref_clk_mfp, 0, 6, 2),
+	MUX_PG(i2s_d0_mfp, 0, 5, 1),
+	MUX_PG(i2s_d1_mfp, 0, 5, 1),
+	MUX_PG(i2s_lr_m_clk0_mfp, 0, 3, 2),
+	MUX_PG(i2s_bclk0_mfp, 0, 2, 1),
+	MUX_PG(i2s_bclk1_mclk1_mfp, 0, 2, 1),
+	MUX_PG(pcm1_in_out_mfp, 0, 0, 2),
+	MUX_PG(pcm1_clk_mfp, 0, 0, 2),
+	MUX_PG(pcm1_sync_mfp, 0, 0, 2),
+	MUX_PG(eram_a5_mfp, 1, 29, 3),
+	MUX_PG(eram_a6_mfp, 1, 29, 3),
+	MUX_PG(eram_a7_mfp, 1, 29, 3),
+	MUX_PG(eram_a8_mfp, 1, 26, 3),
+	MUX_PG(eram_a9_mfp, 1, 26, 3),
+	MUX_PG(eram_a10_mfp, 1, 26, 3),
+	MUX_PG(eram_a11_mfp, 1, 23, 3),
+	MUX_PG(lvds_oep_odn_mfp, 1, 22, 1),
+	MUX_PG(lvds_ocp_obn_mfp, 1, 22, 1),
+	MUX_PG(lvds_oap_oan_mfp, 1, 22, 1),
+	MUX_PG(lvds_e_mfp, 1, 21, 1),
+	MUX_PG(spi0_sclk_mosi_mfp, 1, 4, 2),
+	MUX_PG(spi0_ss_mfp, 1, 1, 3),
+	MUX_PG(spi0_miso_mfp, 1, 1, 3),
+	MUX_PG(uart2_rtsb_mfp, 2, 23, 1),
+	MUX_PG(uart2_ctsb_mfp, 2, 22, 1),
+	MUX_PG(uart3_rtsb_mfp, 2, 21, 1),
+	MUX_PG(uart3_ctsb_mfp, 2, 20, 1),
+	MUX_PG(sd0_d0_mfp, 2, 17, 3),
+	MUX_PG(sd0_d1_mfp, 2, 14, 3),
+	MUX_PG(sd0_d2_d3_mfp, 2, 11, 3),
+	MUX_PG(sd1_d0_d3_mfp, 2, 9, 2),
+	MUX_PG(sd0_cmd_mfp, 2, 7, 2),
+	MUX_PG(sd0_clk_mfp, 2, 5, 2),
+	MUX_PG(sd1_cmd_clk_mfp, 2, 3, 2),
+	MUX_PG(uart0_rx_mfp, 2, 0, 3),
+	MUX_PG(nand0_d0_ceb3_mfp, 3, 27, 1),
+	MUX_PG(uart0_tx_mfp, 3, 19, 3),
+	MUX_PG(i2c0_mfp, 3, 16, 3),
+	MUX_PG(csi0_cn_cp_mfp, 3, 15, 1),
+	MUX_PG(csi0_dn0_dp3_mfp, 3, 14, 1),
+	MUX_PG(csi1_dn0_cp_mfp, 3, 13, 1),
+	MUX_PG(dsi_dp3_dn1_mfp, 3, 12, 1),
+	MUX_PG(dsi_cp_dn0_mfp, 3, 12, 1),
+	MUX_PG(dsi_dp2_dn2_mfp, 3, 12, 1),
+	MUX_PG(nand1_d0_ceb1_mfp, 3, 11, 1),
+	MUX_PG(nand1_ceb3_mfp, 3, 10, 1),
+	MUX_PG(nand1_ceb0_mfp, 3, 10, 1),
+	MUX_PG(csi1_dn0_dp0_mfp, 3, 9, 1),
+	MUX_PG(uart4_rx_tx_mfp, 3, 8, 1),
+
+	DRV_PG(sgpio3_drv, 0, 30, 2),
+	DRV_PG(sgpio2_drv, 0, 28, 2),
+	DRV_PG(sgpio1_drv, 0, 26, 2),
+	DRV_PG(sgpio0_drv, 0, 24, 2),
+	DRV_PG(rmii_tx_d0_d1_drv, 0, 22, 2),
+	DRV_PG(rmii_txen_rxer_drv, 0, 20, 2),
+	DRV_PG(rmii_crs_dv_drv, 0, 18, 2),
+	DRV_PG(rmii_rx_d1_d0_drv, 0, 16, 2),
+	DRV_PG(rmii_ref_clk_drv, 0, 14, 2),
+	DRV_PG(rmii_mdc_mdio_drv, 0, 12, 2),
+	DRV_PG(sirq_0_1_drv, 0, 10, 2),
+	DRV_PG(sirq2_drv, 0, 8, 2),
+	DRV_PG(i2s_d0_d1_drv, 0, 6, 2),
+	DRV_PG(i2s_lr_m_clk0_drv, 0, 4, 2),
+	DRV_PG(i2s_blk1_mclk1_drv, 0, 2, 2),
+	DRV_PG(pcm1_in_out_drv, 0, 0, 2),
+	DRV_PG(lvds_oap_oan_drv, 1, 28, 2),
+	DRV_PG(lvds_oep_odn_drv, 1, 26, 2),
+	DRV_PG(lvds_ocp_obn_drv, 1, 24, 2),
+	DRV_PG(lvds_e_drv, 1, 22, 2),
+	DRV_PG(sd0_d3_d0_drv, 1, 20, 2),
+	DRV_PG(sd1_d3_d0_drv, 1, 18, 2),
+	DRV_PG(sd0_sd1_cmd_clk_drv, 1, 16, 2),
+	DRV_PG(spi0_sclk_mosi_drv, 1, 14, 2),
+	DRV_PG(spi0_ss_miso_drv, 1, 12, 2),
+	DRV_PG(uart0_rx_tx_drv, 1, 10, 2),
+	DRV_PG(uart4_rx_tx_drv, 1, 8, 2),
+	DRV_PG(uart2_drv, 1, 6, 2),
+	DRV_PG(uart3_drv, 1, 4, 2),
+	DRV_PG(i2c0_drv, 2, 30, 2),
+	DRV_PG(i2c1_drv, 2, 28, 2),
+	DRV_PG(i2c2_drv, 2, 26, 2),
+	DRV_PG(sensor0_drv, 2, 20, 2),
+
+	SR_PG(sgpio3_sr, 0, 15, 1),
+	SR_PG(sgpio2_sr, 0, 14, 1),
+	SR_PG(sgpio1_sr, 0, 13, 1),
+	SR_PG(sgpio0_sr, 0, 12, 1),
+	SR_PG(rmii_tx_d0_d1_sr, 0, 11, 1),
+	SR_PG(rmii_txen_rxer_sr, 0, 10, 1),
+	SR_PG(rmii_crs_dv_sr, 0, 9, 1),
+	SR_PG(rmii_rx_d1_d0_sr, 0, 8, 1),
+	SR_PG(rmii_ref_clk_sr, 0, 7, 1),
+	SR_PG(rmii_mdc_mdio_sr, 0, 6, 1),
+	SR_PG(sirq_0_1_sr, 0, 5, 1),
+	SR_PG(sirq2_sr, 0, 4, 1),
+	SR_PG(i2s_do_d1_sr, 0, 3, 1),
+	SR_PG(i2s_lr_m_clk0_sr, 0, 2, 1),
+	SR_PG(i2s_bclk0_mclk1_sr, 0, 1, 1),
+	SR_PG(pcm1_in_out_sr, 0, 0, 1),
+	SR_PG(sd1_d3_d0_sr, 1, 25, 1),
+	SR_PG(sd0_sd1_clk_cmd_sr, 1, 24, 1),
+	SR_PG(spi0_sclk_mosi_sr, 1, 23, 1),
+	SR_PG(spi0_ss_miso_sr, 1, 22, 1),
+	SR_PG(uart0_rx_tx_sr, 1, 21, 1),
+	SR_PG(uart4_rx_tx_sr, 1, 20, 1),
+	SR_PG(uart2_sr, 1, 19, 1),
+	SR_PG(uart3_sr, 1, 18, 1),
+	SR_PG(i2c0_sr, 2, 31, 1),
+	SR_PG(i2c1_sr, 2, 30, 1),
+	SR_PG(i2c2_sr, 2, 29, 1),
+	SR_PG(sensor0_sr, 2, 25, 1)
+};
+
+static const char * const eram_groups[] = {
+	"lvds_oxx_uart4_mfp",
+	"eram_a5_mfp",
+	"eram_a6_mfp",
+	"eram_a7_mfp",
+	"eram_a8_mfp",
+	"eram_a9_mfp",
+	"eram_a10_mfp",
+	"eram_a11_mfp",
+	"lvds_oap_oan_mfp",
+	"lvds_e_mfp",
+	"spi0_sclk_mosi_mfp",
+	"spi0_ss_mfp",
+	"spi0_miso_mfp",
+	"sd0_d0_mfp",
+	"sd0_d1_mfp",
+	"sd0_d2_d3_mfp",
+	"sd1_d0_d3_mfp",
+	"sd0_cmd_mfp",
+	"sd0_clk_mfp",
+	"sd1_cmd_clk_mfp",
+};
+
+static const char * const eth_rmii_groups[] = {
+	"rmii_mdc_mfp",
+	"rmii_mdio_mfp",
+	"rmii_txd0_mfp",
+	"rmii_txd1_mfp",
+	"rmii_txen_mfp",
+	"rmii_rxer_mfp",
+	"rmii_crs_dv_mfp",
+	"rmii_rxd1_mfp",
+	"rmii_rxd0_mfp",
+	"rmii_ref_clk_mfp",
+	"eth_smi_dummy",
+};
+
+static const char * const eth_smii_groups[] = {
+	"rmii_txd0_mfp",
+	"rmii_txd1_mfp",
+	"rmii_crs_dv_mfp",
+	"eth_smi_dummy",
+};
+
+static const char * const spi0_groups[] = {
+	"spi0_sclk_mosi_mfp",
+	"spi0_ss_mfp",
+	"spi0_miso_mfp",
+	"spi0_sclk_mosi_mfp",
+	"spi0_ss_mfp",
+	"spi0_miso_mfp",
+};
+
+static const char * const spi1_groups[] = {
+	"pcm1_in_out_mfp",
+	"pcm1_clk_mfp",
+	"pcm1_sync_mfp",
+	"uart0_rx_mfp",
+	"uart0_tx_mfp",
+	"i2c0_mfp",
+};
+
+static const char * const spi2_groups[] = {
+	"rmii_txd0_mfp",
+	"rmii_txd1_mfp",
+	"rmii_crs_dv_mfp",
+	"rmii_ref_clk_mfp",
+};
+
+static const char * const spi3_groups[] = {
+	"rmii_txen_mfp",
+	"rmii_rxer_mfp",
+};
+
+static const char * const sens0_groups[] = {
+	"rmii_txd0_mfp",
+	"rmii_txd1_mfp",
+	"rmii_txen_mfp",
+	"rmii_rxer_mfp",
+	"rmii_rxd1_mfp",
+	"rmii_rxd0_mfp",
+	"eram_a5_mfp",
+	"eram_a6_mfp",
+	"eram_a7_mfp",
+	"eram_a8_mfp",
+	"eram_a9_mfp",
+	"csi0_cn_cp_mfp",
+	"csi0_dn0_dp3_mfp",
+	"csi1_dn0_cp_mfp",
+	"csi1_dn0_dp0_mfp",
+};
+
+static const char * const uart0_groups[] = {
+	"uart2_rtsb_mfp",
+	"uart2_ctsb_mfp",
+	"uart0_rx_mfp",
+	"uart0_tx_mfp",
+};
+
+static const char * const uart1_groups[] = {
+	"sd0_d2_d3_mfp",
+	"i2c0_mfp",
+};
+
+static const char * const uart2_groups[] = {
+	"rmii_mdc_mfp",
+	"rmii_mdio_mfp",
+	"rmii_txen_mfp",
+	"rmii_rxer_mfp",
+	"rmii_rxd1_mfp",
+	"rmii_rxd0_mfp",
+	"lvds_oep_odn_mfp",
+	"uart2_rtsb_mfp",
+	"uart2_ctsb_mfp",
+	"sd0_d0_mfp",
+	"sd0_d1_mfp",
+	"sd0_d2_d3_mfp",
+	"uart0_rx_mfp",
+	"uart0_tx_mfp_pads",
+	"i2c0_mfp_pads",
+	"dsi_dp3_dn1_mfp",
+	"uart2_dummy"
+};
+
+static const char * const uart3_groups[] = {
+	"uart3_rtsb_mfp",
+	"uart3_ctsb_mfp",
+	"uart3_dummy"
+};
+
+static const char * const uart4_groups[] = {
+	"lvds_oxx_uart4_mfp",
+	"rmii_crs_dv_mfp",
+	"rmii_ref_clk_mfp",
+	"pcm1_in_out_mfp",
+	"pcm1_clk_mfp",
+	"pcm1_sync_mfp",
+	"eram_a5_mfp",
+	"eram_a6_mfp",
+	"dsi_dp2_dn2_mfp",
+	"uart4_rx_tx_mfp_pads",
+	"uart4_dummy"
+};
+
+static const char * const uart5_groups[] = {
+	"rmii_rxd1_mfp",
+	"rmii_rxd0_mfp",
+	"eram_a9_mfp",
+	"eram_a11_mfp",
+	"uart3_rtsb_mfp",
+	"uart3_ctsb_mfp",
+	"sd0_d0_mfp",
+	"sd0_d1_mfp",
+};
+
+static const char * const uart6_groups[] = {
+	"rmii_txd0_mfp",
+	"rmii_txd1_mfp",
+};
+
+static const char * const i2s0_groups[] = {
+	"i2s_d0_mfp",
+	"i2s_lr_m_clk0_mfp",
+	"i2s_bclk0_mfp",
+	"i2s0_dummy",
+};
+
+static const char * const i2s1_groups[] = {
+	"i2s_d1_mfp",
+	"i2s_bclk1_mclk1_mfp",
+	"spi0_ss_mfp",
+	"spi0_miso_mfp",
+	"uart0_rx_mfp",
+	"uart0_tx_mfp",
+	"i2s1_dummy",
+};
+
+static const char * const pcm0_groups[] = {
+	"i2s_d0_mfp",
+	"i2s_d1_mfp",
+	"i2s_lr_m_clk0_mfp",
+	"i2s_bclk0_mfp",
+	"i2s_bclk1_mclk1_mfp",
+	"spi0_sclk_mosi_mfp",
+	"spi0_ss_mfp",
+	"spi0_miso_mfp",
+};
+
+static const char * const pcm1_groups[] = {
+	"i2s_lr_m_clk0_mfp",
+	"pcm1_in_out_mfp",
+	"pcm1_clk_mfp",
+	"pcm1_sync_mfp",
+	"lvds_oep_odn_mfp",
+	"spi0_ss_mfp",
+	"spi0_miso_mfp",
+	"uart0_rx_mfp",
+	"uart0_tx_mfp",
+	"dsi_cp_dn0_mfp",
+	"pcm1_dummy",
+};
+
+static const char * const jtag_groups[] = {
+	"eram_a5_mfp",
+	"eram_a6_mfp",
+	"eram_a7_mfp",
+	"eram_a8_mfp",
+	"eram_a10_mfp",
+	"eram_a10_mfp",
+	"sd0_d2_d3_mfp",
+	"sd0_cmd_mfp",
+	"sd0_clk_mfp",
+};
+
+static const char * const pwm0_groups[] = {
+	"sirq0_mfp",
+	"rmii_txd0_mfp",
+	"rmii_rxd1_mfp",
+	"eram_a5_mfp",
+	"nand1_ceb3_mfp",
+};
+
+static const char * const pwm1_groups[] = {
+	"sirq1_mfp",
+	"rmii_txd1_mfp",
+	"rmii_rxd0_mfp",
+	"eram_a6_mfp",
+	"eram_a8_mfp",
+	"nand1_ceb0_mfp",
+};
+
+static const char * const pwm2_groups[] = {
+	"rmii_mdc_mfp",
+	"rmii_txen_mfp",
+	"eram_a9_mfp",
+	"eram_a11_mfp",
+};
+
+static const char * const pwm3_groups[] = {
+	"rmii_mdio_mfp",
+	"rmii_rxer_mfp",
+	"eram_a10_mfp",
+};
+
+static const char * const pwm4_groups[] = {
+	"pcm1_clk_mfp",
+	"spi0_ss_mfp",
+};
+
+static const char * const pwm5_groups[] = {
+	"pcm1_sync_mfp",
+	"spi0_miso_mfp",
+};
+
+static const char * const sd0_groups[] = {
+	"sd0_d0_mfp",
+	"sd0_d1_mfp",
+	"sd0_d2_d3_mfp",
+	"sd0_cmd_mfp",
+	"sd0_clk_mfp",
+};
+
+static const char * const sd1_groups[] = {
+	"sd1_d0_d3_mfp",
+	"sd1_cmd_clk_mfp",
+	"sd1_dummy",
+};
+
+static const char * const sd2_groups[] = {
+	"nand0_d0_ceb3_mfp",
+};
+
+static const char * const sd3_groups[] = {
+	"nand1_d0_ceb1_mfp",
+};
+
+static const char * const i2c0_groups[] = {
+	"i2c0_mfp",
+};
+
+static const char * const i2c1_groups[] = {
+	"i2c0_mfp",
+	"i2c1_dummy"
+};
+
+static const char * const i2c2_groups[] = {
+	"i2c2_dummy"
+};
+
+static const char * const i2c3_groups[] = {
+	"pcm1_in_out_mfp",
+	"spi0_sclk_mosi_mfp",
+};
+
+static const char * const i2c4_groups[] = {
+	"uart4_rx_tx_mfp",
+};
+
+static const char * const i2c5_groups[] = {
+	"uart0_rx_mfp",
+	"uart0_tx_mfp",
+};
+
+
+static const char * const lvds_groups[] = {
+	"lvds_oep_odn_mfp",
+	"lvds_ocp_obn_mfp",
+	"lvds_oap_oan_mfp",
+	"lvds_e_mfp",
+};
+
+static const char * const usb20_groups[] = {
+	"eram_a9_mfp",
+};
+
+static const char * const usb30_groups[] = {
+	"eram_a10_mfp",
+};
+
+static const char * const gpu_groups[] = {
+	"sd0_d0_mfp",
+	"sd0_d1_mfp",
+	"sd0_d2_d3_mfp",
+	"sd0_cmd_mfp",
+	"sd0_clk_mfp",
+};
+
+static const char * const mipi_csi0_groups[] = {
+	"csi0_dn0_dp3_mfp",
+};
+
+static const char * const mipi_csi1_groups[] = {
+	"csi1_dn0_cp_mfp",
+};
+
+static const char * const mipi_dsi_groups[] = {
+	"dsi_dp3_dn1_mfp",
+	"dsi_cp_dn0_mfp",
+	"dsi_dp2_dn2_mfp",
+	"mipi_dsi_dummy",
+};
+
+static const char * const nand0_groups[] = {
+	"nand0_d0_ceb3_mfp",
+	"nand0_dummy",
+};
+
+static const char * const nand1_groups[] = {
+	"nand1_d0_ceb1_mfp",
+	"nand1_ceb3_mfp",
+	"nand1_ceb0_mfp",
+	"nand1_dummy",
+};
+
+static const char * const spdif_groups[] = {
+	"uart0_tx_mfp",
+};
+
+static const char * const sirq0_groups[] = {
+	"sirq0_mfp",
+	"sirq0_dummy",
+};
+
+static const char * const sirq1_groups[] = {
+	"sirq1_mfp",
+	"sirq1_dummy",
+};
+
+static const char * const sirq2_groups[] = {
+	"sirq2_dummy",
+};
+
+#define FUNCTION(fname)					\
+	{						\
+		.name = #fname,				\
+		.groups = fname##_groups,		\
+		.ngroups = ARRAY_SIZE(fname##_groups),	\
+	}
+
+const struct owl_pinmux_func s900_functions[] = {
+	[S900_MUX_ERAM] = FUNCTION(eram),
+	[S900_MUX_ETH_RMII] = FUNCTION(eth_rmii),
+	[S900_MUX_ETH_SMII] = FUNCTION(eth_smii),
+	[S900_MUX_SPI0] = FUNCTION(spi0),
+	[S900_MUX_SPI1] = FUNCTION(spi1),
+	[S900_MUX_SPI2] = FUNCTION(spi2),
+	[S900_MUX_SPI3] = FUNCTION(spi3),
+	[S900_MUX_SENS0] = FUNCTION(sens0),
+	[S900_MUX_UART0] = FUNCTION(uart0),
+	[S900_MUX_UART1] = FUNCTION(uart1),
+	[S900_MUX_UART2] = FUNCTION(uart2),
+	[S900_MUX_UART3] = FUNCTION(uart3),
+	[S900_MUX_UART4] = FUNCTION(uart4),
+	[S900_MUX_UART5] = FUNCTION(uart5),
+	[S900_MUX_UART6] = FUNCTION(uart6),
+	[S900_MUX_I2S0] = FUNCTION(i2s0),
+	[S900_MUX_I2S1] = FUNCTION(i2s1),
+	[S900_MUX_PCM0] = FUNCTION(pcm0),
+	[S900_MUX_PCM1] = FUNCTION(pcm1),
+	[S900_MUX_JTAG] = FUNCTION(jtag),
+	[S900_MUX_PWM0] = FUNCTION(pwm0),
+	[S900_MUX_PWM1] = FUNCTION(pwm1),
+	[S900_MUX_PWM2] = FUNCTION(pwm2),
+	[S900_MUX_PWM3] = FUNCTION(pwm3),
+	[S900_MUX_PWM4] = FUNCTION(pwm4),
+	[S900_MUX_PWM5] = FUNCTION(pwm5),
+	[S900_MUX_SD0] = FUNCTION(sd0),
+	[S900_MUX_SD1] = FUNCTION(sd1),
+	[S900_MUX_SD2] = FUNCTION(sd2),
+	[S900_MUX_SD3] = FUNCTION(sd3),
+	[S900_MUX_I2C0] = FUNCTION(i2c0),
+	[S900_MUX_I2C1] = FUNCTION(i2c1),
+	[S900_MUX_I2C2] = FUNCTION(i2c2),
+	[S900_MUX_I2C3] = FUNCTION(i2c3),
+	[S900_MUX_I2C4] = FUNCTION(i2c4),
+	[S900_MUX_I2C5] = FUNCTION(i2c5),
+	[S900_MUX_LVDS] = FUNCTION(lvds),
+	[S900_MUX_USB30] = FUNCTION(usb30),
+	[S900_MUX_USB20] = FUNCTION(usb20),
+	[S900_MUX_GPU] = FUNCTION(gpu),
+	[S900_MUX_MIPI_CSI0] = FUNCTION(mipi_csi0),
+	[S900_MUX_MIPI_CSI1] = FUNCTION(mipi_csi1),
+	[S900_MUX_MIPI_DSI] = FUNCTION(mipi_dsi),
+	[S900_MUX_NAND0] = FUNCTION(nand0),
+	[S900_MUX_NAND1] = FUNCTION(nand1),
+	[S900_MUX_SPDIF] = FUNCTION(spdif),
+	[S900_MUX_SIRQ0] = FUNCTION(sirq0),
+	[S900_MUX_SIRQ1] = FUNCTION(sirq1),
+	[S900_MUX_SIRQ2] = FUNCTION(sirq2)
+};
+/* PAD PULL UP/DOWN CONFIGURES */
+#define PULLCTL_CONF(pull_reg, pull_sft, pull_wdt)			\
+	{								\
+		.reg = PAD_PULLCTL##pull_reg,				\
+		.shift = pull_sft,					\
+		.width = pull_wdt,					\
+	}
+
+#define PAD_PULLCTL_CONF(pad_name, pull_reg, pull_sft, pull_wdt)	\
+	struct owl_pullctl pad_name##_pullctl_conf			\
+		= PULLCTL_CONF(pull_reg, pull_sft, pull_wdt)
+
+#define ST_CONF(st_reg, st_sft, st_wdt)					\
+	{								\
+		.reg = PAD_ST##st_reg,					\
+		.shift = st_sft,					\
+		.width = st_wdt,					\
+	}
+
+#define PAD_ST_CONF(pad_name, st_reg, st_sft, st_wdt)			\
+	struct owl_st pad_name##_st_conf				\
+		= ST_CONF(st_reg, st_sft, st_wdt)
+
+/* PAD_PULLCTL0 */
+static PAD_PULLCTL_CONF(ETH_RXER, 0, 18, 2);
+static PAD_PULLCTL_CONF(SIRQ0, 0, 16, 2);
+static PAD_PULLCTL_CONF(SIRQ1, 0, 14, 2);
+static PAD_PULLCTL_CONF(SIRQ2, 0, 12, 2);
+static PAD_PULLCTL_CONF(I2C0_SDATA, 0, 10, 2);
+static PAD_PULLCTL_CONF(I2C0_SCLK, 0, 8, 2);
+static PAD_PULLCTL_CONF(ERAM_A5, 0, 6, 2);
+static PAD_PULLCTL_CONF(ERAM_A6, 0, 4, 2);
+static PAD_PULLCTL_CONF(ERAM_A7, 0, 2, 2);
+static PAD_PULLCTL_CONF(ERAM_A10, 0, 0, 2);
+
+/* PAD_PULLCTL1 */
+static PAD_PULLCTL_CONF(PCM1_IN, 1, 30, 2);
+static PAD_PULLCTL_CONF(PCM1_OUT, 1, 28, 2);
+static PAD_PULLCTL_CONF(SD0_D0, 1, 26, 2);
+static PAD_PULLCTL_CONF(SD0_D1, 1, 24, 2);
+static PAD_PULLCTL_CONF(SD0_D2, 1, 22, 2);
+static PAD_PULLCTL_CONF(SD0_D3, 1, 20, 2);
+static PAD_PULLCTL_CONF(SD0_CMD, 1, 18, 2);
+static PAD_PULLCTL_CONF(SD0_CLK, 1, 16, 2);
+static PAD_PULLCTL_CONF(SD1_CMD, 1, 14, 2);
+static PAD_PULLCTL_CONF(SD1_D0, 1, 12, 2);
+static PAD_PULLCTL_CONF(SD1_D1, 1, 10, 2);
+static PAD_PULLCTL_CONF(SD1_D2, 1, 8, 2);
+static PAD_PULLCTL_CONF(SD1_D3, 1, 6, 2);
+static PAD_PULLCTL_CONF(UART0_RX, 1, 4, 2);
+static PAD_PULLCTL_CONF(UART0_TX, 1, 2, 2);
+
+/* PAD_PULLCTL2 */
+static PAD_PULLCTL_CONF(I2C2_SDATA, 2, 26, 2);
+static PAD_PULLCTL_CONF(I2C2_SCLK, 2, 24, 2);
+static PAD_PULLCTL_CONF(SPI0_SCLK, 2, 22, 2);
+static PAD_PULLCTL_CONF(SPI0_MOSI, 2, 20, 2);
+static PAD_PULLCTL_CONF(I2C1_SDATA, 2, 18, 2);
+static PAD_PULLCTL_CONF(I2C1_SCLK, 2, 16, 2);
+static PAD_PULLCTL_CONF(NAND0_D0, 2, 15, 1);
+static PAD_PULLCTL_CONF(NAND0_D1, 2, 15, 1);
+static PAD_PULLCTL_CONF(NAND0_D2, 2, 15, 1);
+static PAD_PULLCTL_CONF(NAND0_D3, 2, 15, 1);
+static PAD_PULLCTL_CONF(NAND0_D4, 2, 15, 1);
+static PAD_PULLCTL_CONF(NAND0_D5, 2, 15, 1);
+static PAD_PULLCTL_CONF(NAND0_D6, 2, 15, 1);
+static PAD_PULLCTL_CONF(NAND0_D7, 2, 15, 1);
+static PAD_PULLCTL_CONF(NAND0_DQSN, 2, 14, 1);
+static PAD_PULLCTL_CONF(NAND0_DQS, 2, 13, 1);
+static PAD_PULLCTL_CONF(NAND1_D0, 2, 12, 1);
+static PAD_PULLCTL_CONF(NAND1_D1, 2, 12, 1);
+static PAD_PULLCTL_CONF(NAND1_D2, 2, 12, 1);
+static PAD_PULLCTL_CONF(NAND1_D3, 2, 12, 1);
+static PAD_PULLCTL_CONF(NAND1_D4, 2, 12, 1);
+static PAD_PULLCTL_CONF(NAND1_D5, 2, 12, 1);
+static PAD_PULLCTL_CONF(NAND1_D6, 2, 12, 1);
+static PAD_PULLCTL_CONF(NAND1_D7, 2, 12, 1);
+static PAD_PULLCTL_CONF(NAND1_DQSN, 2, 11, 1);
+static PAD_PULLCTL_CONF(NAND1_DQS, 2, 10, 1);
+static PAD_PULLCTL_CONF(SGPIO2, 2, 8, 2);
+static PAD_PULLCTL_CONF(SGPIO3, 2, 6, 2);
+static PAD_PULLCTL_CONF(UART4_RX, 2, 4, 2);
+static PAD_PULLCTL_CONF(UART4_TX, 2, 2, 2);
+
+/* PAD_ST0 */
+static PAD_ST_CONF(I2C0_SDATA, 0, 30, 1);
+static PAD_ST_CONF(UART0_RX, 0, 29, 1);
+static PAD_ST_CONF(ETH_MDC, 0, 28, 1);
+static PAD_ST_CONF(I2S_MCLK1, 0, 23, 1);
+static PAD_ST_CONF(ETH_REF_CLK, 0, 22, 1);
+static PAD_ST_CONF(ETH_TXEN, 0, 21, 1);
+static PAD_ST_CONF(ETH_TXD0, 0, 20, 1);
+static PAD_ST_CONF(I2S_LRCLK1, 0, 19, 1);
+static PAD_ST_CONF(SGPIO2, 0, 18, 1);
+static PAD_ST_CONF(SGPIO3, 0, 17, 1);
+static PAD_ST_CONF(UART4_TX, 0, 16, 1);
+static PAD_ST_CONF(I2S_D1, 0, 15, 1);
+static PAD_ST_CONF(UART0_TX, 0, 14, 1);
+static PAD_ST_CONF(SPI0_SCLK, 0, 13, 1);
+static PAD_ST_CONF(SD0_CLK, 0, 12, 1);
+static PAD_ST_CONF(ERAM_A5, 0, 11, 1);
+static PAD_ST_CONF(I2C0_SCLK, 0, 7, 1);
+static PAD_ST_CONF(ERAM_A9, 0, 6, 1);
+static PAD_ST_CONF(LVDS_OEP, 0, 5, 1);
+static PAD_ST_CONF(LVDS_ODN, 0, 4, 1);
+static PAD_ST_CONF(LVDS_OAP, 0, 3, 1);
+static PAD_ST_CONF(I2S_BCLK1, 0, 2, 1);
+
+/* PAD_ST1 */
+static PAD_ST_CONF(I2S_LRCLK0, 1, 29, 1);
+static PAD_ST_CONF(UART4_RX, 1, 28, 1);
+static PAD_ST_CONF(UART3_CTSB, 1, 27, 1);
+static PAD_ST_CONF(UART3_RTSB, 1, 26, 1);
+static PAD_ST_CONF(UART3_RX, 1, 25, 1);
+static PAD_ST_CONF(UART2_RTSB, 1, 24, 1);
+static PAD_ST_CONF(UART2_CTSB, 1, 23, 1);
+static PAD_ST_CONF(UART2_RX, 1, 22, 1);
+static PAD_ST_CONF(ETH_RXD0, 1, 21, 1);
+static PAD_ST_CONF(ETH_RXD1, 1, 20, 1);
+static PAD_ST_CONF(ETH_CRS_DV, 1, 19, 1);
+static PAD_ST_CONF(ETH_RXER, 1, 18, 1);
+static PAD_ST_CONF(ETH_TXD1, 1, 17, 1);
+static PAD_ST_CONF(LVDS_OCP, 1, 16, 1);
+static PAD_ST_CONF(LVDS_OBP, 1, 15, 1);
+static PAD_ST_CONF(LVDS_OBN, 1, 14, 1);
+static PAD_ST_CONF(PCM1_OUT, 1, 12, 1);
+static PAD_ST_CONF(PCM1_CLK, 1, 11, 1);
+static PAD_ST_CONF(PCM1_IN, 1, 10, 1);
+static PAD_ST_CONF(PCM1_SYNC, 1, 9, 1);
+static PAD_ST_CONF(I2C1_SCLK, 1, 8, 1);
+static PAD_ST_CONF(I2C1_SDATA, 1, 7, 1);
+static PAD_ST_CONF(I2C2_SCLK, 1, 6, 1);
+static PAD_ST_CONF(I2C2_SDATA, 1, 5, 1);
+static PAD_ST_CONF(SPI0_MOSI, 1, 4, 1);
+static PAD_ST_CONF(SPI0_MISO, 1, 3, 1);
+static PAD_ST_CONF(SPI0_SS, 1, 2, 1);
+static PAD_ST_CONF(I2S_BCLK0, 1, 1, 1);
+static PAD_ST_CONF(I2S_MCLK0, 1, 0, 1);
+
+#define PAD_INFO(name)							\
+	{								\
+		.pad = name,						\
+		.pullctl = NULL,					\
+		.st = NULL,						\
+	}
+
+#define PAD_INFO_ST(name)						\
+	{								\
+		.pad = name,						\
+		.pullctl = NULL,					\
+		.st = &name##_st_conf,					\
+	}
+
+#define PAD_INFO_PULLCTL(name)						\
+	{								\
+		.pad = name,						\
+		.pullctl = &name##_pullctl_conf,			\
+		.st = NULL,						\
+	}
+
+#define PAD_INFO_PULLCTL_ST(name)					\
+	{								\
+		.pad = name,						\
+		.pullctl = &name##_pullctl_conf,			\
+		.st = &name##_st_conf,					\
+	}
+
+/* Pad info table */
+struct owl_padinfo s900_padinfo[NUM_PADS] = {
+	[ETH_TXD0] = PAD_INFO_ST(ETH_TXD0),
+	[ETH_TXD1] = PAD_INFO_ST(ETH_TXD1),
+	[ETH_TXEN] = PAD_INFO_ST(ETH_TXEN),
+	[ETH_RXER] = PAD_INFO_PULLCTL_ST(ETH_RXER),
+	[ETH_CRS_DV] = PAD_INFO_ST(ETH_CRS_DV),
+	[ETH_RXD1] = PAD_INFO_ST(ETH_RXD1),
+	[ETH_RXD0] = PAD_INFO_ST(ETH_RXD0),
+	[ETH_REF_CLK] = PAD_INFO_ST(ETH_REF_CLK),
+	[ETH_MDC] = PAD_INFO_ST(ETH_MDC),
+	[ETH_MDIO] = PAD_INFO(ETH_MDIO),
+	[SIRQ0] = PAD_INFO_PULLCTL(SIRQ0),
+	[SIRQ1] = PAD_INFO_PULLCTL(SIRQ1),
+	[SIRQ2] = PAD_INFO_PULLCTL(SIRQ2),
+	[I2S_D0] = PAD_INFO(I2S_D0),
+	[I2S_BCLK0] = PAD_INFO_ST(I2S_BCLK0),
+	[I2S_LRCLK0] = PAD_INFO_ST(I2S_LRCLK0),
+	[I2S_MCLK0] = PAD_INFO_ST(I2S_MCLK0),
+	[I2S_D1] = PAD_INFO_ST(I2S_D1),
+	[I2S_BCLK1] = PAD_INFO_ST(I2S_BCLK1),
+	[I2S_LRCLK1] = PAD_INFO_ST(I2S_LRCLK1),
+	[I2S_MCLK1] = PAD_INFO_ST(I2S_MCLK1),
+	[PCM1_IN] = PAD_INFO_PULLCTL_ST(PCM1_IN),
+	[PCM1_CLK] = PAD_INFO_ST(PCM1_CLK),
+	[PCM1_SYNC] = PAD_INFO_ST(PCM1_SYNC),
+	[PCM1_OUT] = PAD_INFO_PULLCTL_ST(PCM1_OUT),
+	[ERAM_A5] = PAD_INFO_PULLCTL_ST(ERAM_A5),
+	[ERAM_A6] = PAD_INFO_PULLCTL(ERAM_A6),
+	[ERAM_A7] = PAD_INFO_PULLCTL(ERAM_A7),
+	[ERAM_A8] = PAD_INFO(ERAM_A8),
+	[ERAM_A9] = PAD_INFO_ST(ERAM_A9),
+	[ERAM_A10] = PAD_INFO_PULLCTL(ERAM_A10),
+	[ERAM_A11] = PAD_INFO(ERAM_A11),
+	[LVDS_OEP] = PAD_INFO_ST(LVDS_OEP),
+	[LVDS_OEN] = PAD_INFO(LVDS_OEN),
+	[LVDS_ODP] = PAD_INFO(LVDS_ODP),
+	[LVDS_ODN] = PAD_INFO_ST(LVDS_ODN),
+	[LVDS_OCP] = PAD_INFO_ST(LVDS_OCP),
+	[LVDS_OCN] = PAD_INFO(LVDS_OCN),
+	[LVDS_OBP] = PAD_INFO_ST(LVDS_OBP),
+	[LVDS_OBN] = PAD_INFO_ST(LVDS_OBN),
+	[LVDS_OAP] = PAD_INFO_ST(LVDS_OAP),
+	[LVDS_OAN] = PAD_INFO(LVDS_OAN),
+	[LVDS_EEP] = PAD_INFO(LVDS_EEP),
+	[LVDS_EEN] = PAD_INFO(LVDS_EEN),
+	[LVDS_EDP] = PAD_INFO(LVDS_EDP),
+	[LVDS_EDN] = PAD_INFO(LVDS_EDN),
+	[LVDS_ECP] = PAD_INFO(LVDS_ECP),
+	[LVDS_ECN] = PAD_INFO(LVDS_ECN),
+	[LVDS_EBP] = PAD_INFO(LVDS_EBP),
+	[LVDS_EBN] = PAD_INFO(LVDS_EBN),
+	[LVDS_EAP] = PAD_INFO(LVDS_EAP),
+	[LVDS_EAN] = PAD_INFO(LVDS_EAN),
+	[SD0_D0] = PAD_INFO_PULLCTL(SD0_D0),
+	[SD0_D1] = PAD_INFO_PULLCTL(SD0_D1),
+	[SD0_D2] = PAD_INFO_PULLCTL(SD0_D2),
+	[SD0_D3] = PAD_INFO_PULLCTL(SD0_D3),
+	[SD1_D0] = PAD_INFO_PULLCTL(SD1_D0),
+	[SD1_D1] = PAD_INFO_PULLCTL(SD1_D1),
+	[SD1_D2] = PAD_INFO_PULLCTL(SD1_D2),
+	[SD1_D3] = PAD_INFO_PULLCTL(SD1_D3),
+	[SD0_CMD] = PAD_INFO_PULLCTL(SD0_CMD),
+	[SD0_CLK] = PAD_INFO_PULLCTL_ST(SD0_CLK),
+	[SD1_CMD] = PAD_INFO_PULLCTL(SD1_CMD),
+	[SD1_CLK] = PAD_INFO(SD1_CLK),
+	[SPI0_SCLK] = PAD_INFO_PULLCTL_ST(SPI0_SCLK),
+	[SPI0_SS] = PAD_INFO_ST(SPI0_SS),
+	[SPI0_MISO] = PAD_INFO_ST(SPI0_MISO),
+	[SPI0_MOSI] = PAD_INFO_PULLCTL_ST(SPI0_MOSI),
+	[UART0_RX] = PAD_INFO_PULLCTL_ST(UART0_RX),
+	[UART0_TX] = PAD_INFO_PULLCTL_ST(UART0_TX),
+	[UART2_RX] = PAD_INFO_ST(UART2_RX),
+	[UART2_TX] = PAD_INFO(UART2_TX),
+	[UART2_RTSB] = PAD_INFO_ST(UART2_RTSB),
+	[UART2_CTSB] = PAD_INFO_ST(UART2_CTSB),
+	[UART3_RX] = PAD_INFO_ST(UART3_RX),
+	[UART3_TX] = PAD_INFO(UART3_TX),
+	[UART3_RTSB] = PAD_INFO_ST(UART3_RTSB),
+	[UART3_CTSB] = PAD_INFO_ST(UART3_CTSB),
+	[UART4_RX] = PAD_INFO_PULLCTL_ST(UART4_RX),
+	[UART4_TX] = PAD_INFO_PULLCTL_ST(UART4_TX),
+	[I2C0_SCLK] = PAD_INFO_PULLCTL_ST(I2C0_SCLK),
+	[I2C0_SDATA] = PAD_INFO_PULLCTL_ST(I2C0_SDATA),
+	[I2C1_SCLK] = PAD_INFO_PULLCTL_ST(I2C1_SCLK),
+	[I2C1_SDATA] = PAD_INFO_PULLCTL_ST(I2C1_SDATA),
+	[I2C2_SCLK] = PAD_INFO_PULLCTL_ST(I2C2_SCLK),
+	[I2C2_SDATA] = PAD_INFO_PULLCTL_ST(I2C2_SDATA),
+	[CSI0_DN0] = PAD_INFO(CSI0_DN0),
+	[CSI0_DP0] = PAD_INFO(CSI0_DP0),
+	[CSI0_DN1] = PAD_INFO(CSI0_DN1),
+	[CSI0_DP1] = PAD_INFO(CSI0_DP1),
+	[CSI0_CN] = PAD_INFO(CSI0_CN),
+	[CSI0_CP] = PAD_INFO(CSI0_CP),
+	[CSI0_DN2] = PAD_INFO(CSI0_DN2),
+	[CSI0_DP2] = PAD_INFO(CSI0_DP2),
+	[CSI0_DN3] = PAD_INFO(CSI0_DN3),
+	[CSI0_DP3] = PAD_INFO(CSI0_DP3),
+	[DSI_DP3] = PAD_INFO(DSI_DP3),
+	[DSI_DN3] = PAD_INFO(DSI_DN3),
+	[DSI_DP1] = PAD_INFO(DSI_DP1),
+	[DSI_DN1] = PAD_INFO(DSI_DN1),
+	[DSI_CP] = PAD_INFO(DSI_CP),
+	[DSI_CN] = PAD_INFO(DSI_CN),
+	[DSI_DP0] = PAD_INFO(DSI_DP0),
+	[DSI_DN0] = PAD_INFO(DSI_DN0),
+	[DSI_DP2] = PAD_INFO(DSI_DP2),
+	[DSI_DN2] = PAD_INFO(DSI_DN2),
+	[SENSOR0_PCLK] = PAD_INFO(SENSOR0_PCLK),
+	[CSI1_DN0] = PAD_INFO(CSI1_DN0),
+	[CSI1_DP0] = PAD_INFO(CSI1_DP0),
+	[CSI1_DN1] = PAD_INFO(CSI1_DN1),
+	[CSI1_DP1] = PAD_INFO(CSI1_DP1),
+	[CSI1_CN] = PAD_INFO(CSI1_CN),
+	[CSI1_CP] = PAD_INFO(CSI1_CP),
+	[SENSOR0_CKOUT] = PAD_INFO(SENSOR0_CKOUT),
+	[NAND0_D0] = PAD_INFO_PULLCTL(NAND0_D0),
+	[NAND0_D1] = PAD_INFO_PULLCTL(NAND0_D1),
+	[NAND0_D2] = PAD_INFO_PULLCTL(NAND0_D2),
+	[NAND0_D3] = PAD_INFO_PULLCTL(NAND0_D3),
+	[NAND0_D4] = PAD_INFO_PULLCTL(NAND0_D4),
+	[NAND0_D5] = PAD_INFO_PULLCTL(NAND0_D5),
+	[NAND0_D6] = PAD_INFO_PULLCTL(NAND0_D6),
+	[NAND0_D7] = PAD_INFO_PULLCTL(NAND0_D7),
+	[NAND0_DQS] = PAD_INFO_PULLCTL(NAND0_DQS),
+	[NAND0_DQSN] = PAD_INFO_PULLCTL(NAND0_DQSN),
+	[NAND0_ALE] = PAD_INFO(NAND0_ALE),
+	[NAND0_CLE] = PAD_INFO(NAND0_CLE),
+	[NAND0_CEB0] = PAD_INFO(NAND0_CEB0),
+	[NAND0_CEB1] = PAD_INFO(NAND0_CEB1),
+	[NAND0_CEB2] = PAD_INFO(NAND0_CEB2),
+	[NAND0_CEB3] = PAD_INFO(NAND0_CEB3),
+	[NAND1_D0] = PAD_INFO_PULLCTL(NAND1_D0),
+	[NAND1_D1] = PAD_INFO_PULLCTL(NAND1_D1),
+	[NAND1_D2] = PAD_INFO_PULLCTL(NAND1_D2),
+	[NAND1_D3] = PAD_INFO_PULLCTL(NAND1_D3),
+	[NAND1_D4] = PAD_INFO_PULLCTL(NAND1_D4),
+	[NAND1_D5] = PAD_INFO_PULLCTL(NAND1_D5),
+	[NAND1_D6] = PAD_INFO_PULLCTL(NAND1_D6),
+	[NAND1_D7] = PAD_INFO_PULLCTL(NAND1_D7),
+	[NAND1_DQS] = PAD_INFO_PULLCTL(NAND1_DQS),
+	[NAND1_DQSN] = PAD_INFO_PULLCTL(NAND1_DQSN),
+	[NAND1_ALE] = PAD_INFO(NAND1_ALE),
+	[NAND1_CLE] = PAD_INFO(NAND1_CLE),
+	[NAND1_CEB0] = PAD_INFO(NAND1_CEB0),
+	[NAND1_CEB1] = PAD_INFO(NAND1_CEB1),
+	[NAND1_CEB2] = PAD_INFO(NAND1_CEB2),
+	[NAND1_CEB3] = PAD_INFO(NAND1_CEB3),
+	[SGPIO0] = PAD_INFO(SGPIO0),
+	[SGPIO1] = PAD_INFO(SGPIO1),
+	[SGPIO2] = PAD_INFO_PULLCTL_ST(SGPIO2),
+	[SGPIO3] = PAD_INFO_PULLCTL_ST(SGPIO3)
+};
+
+static struct owl_pinctrl_soc_data s900_pinctrl_data = {
+	.padinfo = s900_padinfo,
+	.pins = (const struct pinctrl_pin_desc *)s900_pads,
+	.npins = ARRAY_SIZE(s900_pads),
+	.functions = s900_functions,
+	.nfunctions = ARRAY_SIZE(s900_functions),
+	.groups = s900_groups,
+	.ngroups = ARRAY_SIZE(s900_groups),
+	.ngpios = NUM_GPIOS
+};
+
+static int s900_pinctrl_probe(struct platform_device *pdev)
+{
+	return owl_pinctrl_probe(pdev, &s900_pinctrl_data);
+}
+
+static const struct of_device_id s900_pinctrl_of_match[] = {
+	{ .compatible = "actions,s900-pinctrl", },
+	{ }
+};
+
+static struct platform_driver s900_pinctrl_driver = {
+	.driver = {
+		.name = "pinctrl-s900",
+		.of_match_table = of_match_ptr(s900_pinctrl_of_match),
+	},
+	.probe = s900_pinctrl_probe
+};
+
+static int __init s900_pinctrl_init(void)
+{
+	return platform_driver_register(&s900_pinctrl_driver);
+}
+arch_initcall(s900_pinctrl_init);
+
+static void __exit s900_pinctrl_exit(void)
+{
+	platform_driver_unregister(&s900_pinctrl_driver);
+}
+module_exit(s900_pinctrl_exit);
+
+MODULE_AUTHOR("Actions Semi Inc.");
+MODULE_AUTHOR("Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>");
+MODULE_DESCRIPTION("Actions Semi S900 SoC Pinctrl Driver");
+MODULE_LICENSE("GPL");
-- 
2.14.1

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

* [PATCH v4 04/10] pinctrl: actions: Add Actions S900 pinctrl driver
@ 2018-03-02  3:50   ` Manivannan Sadhasivam
  0 siblings, 0 replies; 43+ messages in thread
From: Manivannan Sadhasivam @ 2018-03-02  3:50 UTC (permalink / raw)
  To: linux-arm-kernel

Add pinctrl driver for Actions Semi S900 SoC. The driver supports
pinctrl, pinmux and pinconf functionalities through a range of registers
common to both gpio driver and pinctrl driver.

Pinmux functionality is available only for the pin groups while the
pinconf functionality is available for both pin groups and individual
pins.

Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
---
 drivers/pinctrl/Kconfig                |    1 +
 drivers/pinctrl/Makefile               |    1 +
 drivers/pinctrl/actions/Kconfig        |   12 +
 drivers/pinctrl/actions/Makefile       |    2 +
 drivers/pinctrl/actions/pinctrl-owl.c  |  579 ++++++++
 drivers/pinctrl/actions/pinctrl-owl.h  |  142 ++
 drivers/pinctrl/actions/pinctrl-s900.c | 2505 ++++++++++++++++++++++++++++++++
 7 files changed, 3242 insertions(+)
 create mode 100644 drivers/pinctrl/actions/Kconfig
 create mode 100644 drivers/pinctrl/actions/Makefile
 create mode 100644 drivers/pinctrl/actions/pinctrl-owl.c
 create mode 100644 drivers/pinctrl/actions/pinctrl-owl.h
 create mode 100644 drivers/pinctrl/actions/pinctrl-s900.c

diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 0f254b35c378..838c8fff8c24 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -368,6 +368,7 @@ config PINCTRL_OCELOT
 	select GENERIC_PINMUX_FUNCTIONS
 	select REGMAP_MMIO
 
+source "drivers/pinctrl/actions/Kconfig"
 source "drivers/pinctrl/aspeed/Kconfig"
 source "drivers/pinctrl/bcm/Kconfig"
 source "drivers/pinctrl/berlin/Kconfig"
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index d3692633e9ed..fb3497c1a4cb 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -48,6 +48,7 @@ obj-$(CONFIG_PINCTRL_INGENIC)	+= pinctrl-ingenic.o
 obj-$(CONFIG_PINCTRL_RK805)	+= pinctrl-rk805.o
 obj-$(CONFIG_PINCTRL_OCELOT)	+= pinctrl-ocelot.o
 
+obj-y				+= actions/
 obj-$(CONFIG_ARCH_ASPEED)	+= aspeed/
 obj-y				+= bcm/
 obj-$(CONFIG_PINCTRL_BERLIN)	+= berlin/
diff --git a/drivers/pinctrl/actions/Kconfig b/drivers/pinctrl/actions/Kconfig
new file mode 100644
index 000000000000..1c7309c90f0d
--- /dev/null
+++ b/drivers/pinctrl/actions/Kconfig
@@ -0,0 +1,12 @@
+config PINCTRL_OWL
+	bool
+	depends on (ARCH_ACTIONS || COMPILE_TEST) && OF
+	select PINMUX
+	select PINCONF
+	select GENERIC_PINCONF
+
+config PINCTRL_S900
+	bool "Actions Semi S900 pinctrl driver"
+	select PINCTRL_OWL
+	help
+	  Say Y here to enable Actions Semi S900 pinctrl driver
diff --git a/drivers/pinctrl/actions/Makefile b/drivers/pinctrl/actions/Makefile
new file mode 100644
index 000000000000..bd232d28400f
--- /dev/null
+++ b/drivers/pinctrl/actions/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_PINCTRL_OWL)	+= pinctrl-owl.o
+obj-$(CONFIG_PINCTRL_S900) 	+= pinctrl-s900.o
diff --git a/drivers/pinctrl/actions/pinctrl-owl.c b/drivers/pinctrl/actions/pinctrl-owl.c
new file mode 100644
index 000000000000..1a526abebf91
--- /dev/null
+++ b/drivers/pinctrl/actions/pinctrl-owl.c
@@ -0,0 +1,579 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * OWL SoC's Pinctrl driver
+ *
+ * Copyright (c) 2014 Actions Semi Inc.
+ * Author: David Liu <liuwei@actions-semi.com>
+ *
+ * Copyright (c) 2018 Linaro Ltd.
+ * Author: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+ */
+
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pinctrl/machine.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinconf-generic.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+
+#include "../core.h"
+#include "../pinctrl-utils.h"
+#include "pinctrl-owl.h"
+
+/**
+ * struct owl_pinctrl - pinctrl state of the device
+ * @dev: device handle
+ * @pctrldev: pinctrl handle
+ * @lock: spinlock to protect registers
+ * @soc: reference to soc_data
+ * @base: pinctrl register base address
+ */
+struct owl_pinctrl {
+	struct device *dev;
+	struct pinctrl_dev *pctrldev;
+	raw_spinlock_t lock;
+	struct clk *clk;
+	const struct owl_pinctrl_soc_data *soc;
+	void __iomem *base;
+};
+
+static void owl_update_bits(void __iomem *base, u32 mask, u32 val)
+{
+	u32 reg_val;
+
+	reg_val = readl_relaxed(base);
+
+	reg_val &= ~mask;
+	reg_val |= val;
+
+	writel_relaxed(reg_val, base);
+}
+
+static int owl_get_groups_count(struct pinctrl_dev *pctrldev)
+{
+	struct owl_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrldev);
+
+	return pctrl->soc->ngroups;
+}
+
+static const char *owl_get_group_name(struct pinctrl_dev *pctrldev,
+				unsigned int group)
+{
+	struct owl_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrldev);
+
+	return pctrl->soc->groups[group].name;
+}
+
+static int owl_get_group_pins(struct pinctrl_dev *pctrldev,
+				unsigned int group,
+				const unsigned int **pins,
+				unsigned int *num_pins)
+{
+	struct owl_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrldev);
+
+	*pins = pctrl->soc->groups[group].pads;
+	*num_pins = pctrl->soc->groups[group].npads;
+
+	return 0;
+}
+
+static void owl_pin_dbg_show(struct pinctrl_dev *pctrldev,
+				struct seq_file *s,
+				unsigned int offset)
+{
+	struct owl_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrldev);
+
+	seq_printf(s, "%s", dev_name(pctrl->dev));
+}
+
+static struct pinctrl_ops owl_pinctrl_ops = {
+	.get_groups_count = owl_get_groups_count,
+	.get_group_name = owl_get_group_name,
+	.get_group_pins = owl_get_group_pins,
+	.pin_dbg_show = owl_pin_dbg_show,
+	.dt_node_to_map = pinconf_generic_dt_node_to_map_all,
+	.dt_free_map = pinctrl_utils_free_map,
+};
+
+static int owl_get_funcs_count(struct pinctrl_dev *pctrldev)
+{
+	struct owl_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrldev);
+
+	return pctrl->soc->nfunctions;
+}
+
+static const char *owl_get_func_name(struct pinctrl_dev *pctrldev,
+				unsigned int function)
+{
+	struct owl_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrldev);
+
+	return pctrl->soc->functions[function].name;
+}
+
+static int owl_get_func_groups(struct pinctrl_dev *pctrldev,
+				unsigned int function,
+				const char * const **groups,
+				unsigned int * const num_groups)
+{
+	struct owl_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrldev);
+
+	*groups = pctrl->soc->functions[function].groups;
+	*num_groups = pctrl->soc->functions[function].ngroups;
+
+	return 0;
+}
+
+static inline int get_group_mfp_mask_val(const struct owl_pingroup *g,
+				int function,
+				u32 *mask,
+				u32 *val)
+{
+	int id;
+	u32 option_num;
+	u32 option_mask;
+
+	for (id = 0; id < g->nfuncs; id++) {
+		if (g->funcs[id] == function)
+			break;
+	}
+	if (WARN_ON(id == g->nfuncs))
+		return -EINVAL;
+
+	option_num = (1 << g->mfpctl_width);
+	if (id > option_num)
+		id -= option_num;
+
+	option_mask = option_num - 1;
+	*mask = (option_mask  << g->mfpctl_shift);
+	*val = (id << g->mfpctl_shift);
+
+	return 0;
+}
+
+static int owl_set_mux(struct pinctrl_dev *pctrldev,
+				unsigned int function,
+				unsigned int group)
+{
+	struct owl_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrldev);
+	const struct owl_pingroup *g;
+	unsigned long flags;
+	u32 val, mask;
+
+	g = &pctrl->soc->groups[group];
+
+	if (get_group_mfp_mask_val(g, function, &mask, &val))
+		return -EINVAL;
+
+	raw_spin_lock_irqsave(&pctrl->lock, flags);
+
+	owl_update_bits(pctrl->base + g->mfpctl_reg, mask, val);
+
+	raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+
+	return 0;
+}
+
+static struct pinmux_ops owl_pinmux_ops = {
+	.get_functions_count = owl_get_funcs_count,
+	.get_function_name = owl_get_func_name,
+	.get_function_groups = owl_get_func_groups,
+	.set_mux = owl_set_mux,
+};
+
+static int owl_pad_pinconf_reg(const struct owl_padinfo *info,
+				unsigned int param,
+				u32 *reg,
+				u32 *bit,
+				u32 *width)
+{
+	switch (param) {
+	case PIN_CONFIG_BIAS_BUS_HOLD:
+	case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
+	case PIN_CONFIG_BIAS_PULL_DOWN:
+	case PIN_CONFIG_BIAS_PULL_UP:
+		if (!info->pullctl)
+			return -EINVAL;
+		*reg = info->pullctl->reg;
+		*bit = info->pullctl->shift;
+		*width = info->pullctl->width;
+		break;
+	case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
+		if (!info->st)
+			return -EINVAL;
+		*reg = info->st->reg;
+		*bit = info->st->shift;
+		*width = info->st->width;
+		break;
+	default:
+		return -ENOTSUPP;
+	}
+
+	return 0;
+}
+
+static int owl_pad_pinconf_arg2val(const struct owl_padinfo *info,
+				unsigned int param,
+				u32 *arg)
+{
+	switch (param) {
+	case PIN_CONFIG_BIAS_BUS_HOLD:
+		*arg = OWL_PINCONF_PULL_HOLD;
+		break;
+	case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
+		*arg = OWL_PINCONF_PULL_HIZ;
+		break;
+	case PIN_CONFIG_BIAS_PULL_DOWN:
+		*arg = OWL_PINCONF_PULL_DOWN;
+		break;
+	case PIN_CONFIG_BIAS_PULL_UP:
+		*arg = OWL_PINCONF_PULL_UP;
+		break;
+	case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
+		*arg = (*arg >= 1 ? 1 : 0);
+		break;
+	default:
+		return -ENOTSUPP;
+	}
+
+	return 0;
+}
+
+static int owl_pad_pinconf_val2arg(const struct owl_padinfo *padinfo,
+				unsigned int param,
+				u32 *arg)
+{
+	switch (param) {
+	case PIN_CONFIG_BIAS_BUS_HOLD:
+		*arg = *arg == OWL_PINCONF_PULL_HOLD;
+		break;
+	case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
+		*arg = *arg == OWL_PINCONF_PULL_HIZ;
+		break;
+	case PIN_CONFIG_BIAS_PULL_DOWN:
+		*arg = *arg == OWL_PINCONF_PULL_DOWN;
+		break;
+	case PIN_CONFIG_BIAS_PULL_UP:
+		*arg = *arg == OWL_PINCONF_PULL_UP;
+		break;
+	case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
+		*arg = *arg == 1;
+		break;
+	default:
+		return -ENOTSUPP;
+	}
+
+	return 0;
+}
+
+static int owl_pin_config_get(struct pinctrl_dev *pctrldev,
+				unsigned int pin,
+				unsigned long *config)
+{
+	int ret = 0;
+	struct owl_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrldev);
+	const struct owl_padinfo *info;
+	unsigned int param = pinconf_to_config_param(*config);
+	u32 reg, bit, width;
+	u32 tmp, mask;
+	u32 arg = 0;
+
+	info = &pctrl->soc->padinfo[pin];
+
+	ret = owl_pad_pinconf_reg(info, param, &reg, &bit, &width);
+	if (ret)
+		return ret;
+
+	tmp = readl_relaxed(pctrl->base + reg);
+	mask = (1 << width) - 1;
+	arg = (tmp >> bit) & mask;
+
+	ret = owl_pad_pinconf_val2arg(info, param, &arg);
+	if (ret)
+		return ret;
+
+	*config = pinconf_to_config_packed(param, arg);
+
+	return ret;
+}
+
+static int owl_pin_config_set(struct pinctrl_dev *pctrldev,
+				unsigned int pin,
+				unsigned long *configs,
+				unsigned int num_configs)
+{
+	struct owl_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrldev);
+	const struct owl_padinfo *info;
+	unsigned long flags;
+	unsigned int param;
+	u32 reg, bit, width;
+	u32 mask = 0, arg = 0;
+	int ret, i;
+
+	info = &pctrl->soc->padinfo[pin];
+
+	for (i = 0; i < num_configs; i++) {
+		param = pinconf_to_config_param(configs[i]);
+		arg = pinconf_to_config_argument(configs[i]);
+
+		ret = owl_pad_pinconf_reg(info, param, &reg, &bit, &width);
+		if (ret)
+			return ret;
+
+		ret = owl_pad_pinconf_arg2val(info, param, &arg);
+		if (ret)
+			return ret;
+
+		raw_spin_lock_irqsave(&pctrl->lock, flags);
+
+		mask = (1 << width) - 1;
+		mask = mask << bit;
+
+		owl_update_bits(pctrl->base + reg, mask, (arg << bit));
+
+		raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+	}
+
+	return ret;
+}
+
+static int owl_group_pinconf_reg(const struct owl_pingroup *g,
+				unsigned int param,
+				u32 *reg,
+				u32 *bit,
+				u32 *width)
+{
+	switch (param) {
+	case PIN_CONFIG_DRIVE_STRENGTH:
+		if (g->drv_reg < 0)
+			return -EINVAL;
+		*reg = g->drv_reg;
+		*bit = g->drv_shift;
+		*width = g->drv_width;
+		break;
+	case PIN_CONFIG_SLEW_RATE:
+		if (g->sr_reg < 0)
+			return -EINVAL;
+		*reg = g->sr_reg;
+		*bit = g->sr_shift;
+		*width = g->sr_width;
+		break;
+	default:
+		return -ENOTSUPP;
+	}
+
+	return 0;
+}
+
+static int owl_group_pinconf_arg2val(const struct owl_pingroup *g,
+				unsigned int param,
+				u32 *arg)
+{
+	switch (param) {
+	case PIN_CONFIG_DRIVE_STRENGTH:
+		switch (*arg) {
+		case 2:
+			*arg = OWL_PINCONF_DRV_2MA;
+			break;
+		case 4:
+			*arg = OWL_PINCONF_DRV_4MA;
+			break;
+		case 8:
+			*arg = OWL_PINCONF_DRV_8MA;
+			break;
+		case 12:
+			*arg = OWL_PINCONF_DRV_12MA;
+			break;
+		default:
+			return -EINVAL;
+		}
+	case PIN_CONFIG_SLEW_RATE:
+		if (*arg)
+			*arg = OWL_PINCONF_SLEW_FAST;
+		else
+			*arg = OWL_PINCONF_SLEW_SLOW;
+		break;
+	default:
+		return -ENOTSUPP;
+	}
+
+	return 0;
+}
+
+static int owl_group_pinconf_val2arg(const struct owl_pingroup *g,
+				unsigned int param,
+				u32 *arg)
+{
+	switch (param) {
+	case PIN_CONFIG_DRIVE_STRENGTH:
+		switch (*arg) {
+		case OWL_PINCONF_DRV_2MA:
+			*arg = 2;
+			break;
+		case OWL_PINCONF_DRV_4MA:
+			*arg = 4;
+			break;
+		case OWL_PINCONF_DRV_8MA:
+			*arg = 8;
+			break;
+		case OWL_PINCONF_DRV_12MA:
+			*arg = 12;
+			break;
+		default:
+			return -EINVAL;
+		}
+	case PIN_CONFIG_SLEW_RATE:
+		if (*arg)
+			*arg = 1;
+		else
+			*arg = 0;
+		break;
+	default:
+		return -ENOTSUPP;
+	}
+
+	return 0;
+}
+
+static int owl_group_config_get(struct pinctrl_dev *pctrldev,
+				unsigned int group,
+				unsigned long *config)
+{
+	const struct owl_pingroup *g;
+	struct owl_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrldev);
+	unsigned int param = pinconf_to_config_param(*config);
+	u32 reg, bit, width;
+	u32 mask, tmp, arg = 0;
+	int ret;
+
+	g = &pctrl->soc->groups[group];
+
+	ret = owl_group_pinconf_reg(g, param, &reg, &bit, &width);
+	if (ret)
+		return ret;
+
+	tmp = readl_relaxed(pctrl->base + reg);
+	mask = (1 << width) - 1;
+	arg = (tmp >> bit) & mask;
+
+	ret = owl_group_pinconf_val2arg(g, param, &arg);
+	if (ret)
+		return ret;
+
+	*config = pinconf_to_config_packed(param, arg);
+
+	return ret;
+
+}
+
+static int owl_group_config_set(struct pinctrl_dev *pctrldev,
+				unsigned int group,
+				unsigned long *configs,
+				unsigned int num_configs)
+{
+	const struct owl_pingroup *g;
+	struct owl_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrldev);
+	unsigned long flags;
+	unsigned int param;
+	u32 reg, bit, width;
+	u32 mask, arg = 0;
+	int ret, i;
+
+	g = &pctrl->soc->groups[group];
+
+	for (i = 0; i < num_configs; i++) {
+		param = pinconf_to_config_param(configs[i]);
+		arg = pinconf_to_config_argument(configs[i]);
+
+		ret = owl_group_pinconf_reg(g, param, &reg, &bit, &width);
+		if (ret)
+			return ret;
+
+		ret = owl_group_pinconf_arg2val(g, param, &arg);
+		if (ret)
+			return ret;
+
+		/* Update register */
+		raw_spin_lock_irqsave(&pctrl->lock, flags);
+
+		mask = (1 << width) - 1;
+		mask = mask << bit;
+
+		owl_update_bits(pctrl->base + reg, mask, (arg << bit));
+
+		raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+	}
+
+	return 0;
+}
+
+static const struct pinconf_ops owl_pinconf_ops = {
+	.is_generic = true,
+	.pin_config_get = owl_pin_config_get,
+	.pin_config_set = owl_pin_config_set,
+	.pin_config_group_get = owl_group_config_get,
+	.pin_config_group_set = owl_group_config_set
+};
+
+static struct pinctrl_desc owl_pinctrl_desc = {
+	.pctlops = &owl_pinctrl_ops,
+	.pmxops = &owl_pinmux_ops,
+	.confops = &owl_pinconf_ops,
+	.owner = THIS_MODULE
+};
+
+int owl_pinctrl_probe(struct platform_device *pdev,
+				struct owl_pinctrl_soc_data *soc_data)
+{
+	struct resource *res;
+	struct owl_pinctrl *pctrl;
+	int ret;
+
+	pctrl = devm_kzalloc(&pdev->dev, sizeof(*pctrl), GFP_KERNEL);
+	if (!pctrl)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	pctrl->base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(pctrl->base))
+		return PTR_ERR(pctrl->base);
+
+	/* enable GPIO/MFP clock */
+	pctrl->clk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(pctrl->clk)) {
+		dev_err(&pdev->dev, "no clock defined\n");
+		return PTR_ERR(pctrl->clk);
+	}
+
+	ret = clk_prepare_enable(pctrl->clk);
+	if (ret) {
+		dev_err(&pdev->dev, "clk enable failed\n");
+		return ret;
+	}
+
+	raw_spin_lock_init(&pctrl->lock);
+
+	owl_pinctrl_desc.name = dev_name(&pdev->dev);
+	owl_pinctrl_desc.pins = soc_data->pins;
+	owl_pinctrl_desc.npins = soc_data->npins;
+
+	pctrl->soc = soc_data;
+	pctrl->dev = &pdev->dev;
+
+	pctrl->pctrldev = devm_pinctrl_register(&pdev->dev,
+					&owl_pinctrl_desc, pctrl);
+	if (IS_ERR(pctrl->pctrldev)) {
+		dev_err(&pdev->dev, "could not register Actions OWL pinmux driver\n");
+		return PTR_ERR(pctrl->pctrldev);
+	}
+
+	platform_set_drvdata(pdev, pctrl);
+
+	return 0;
+}
diff --git a/drivers/pinctrl/actions/pinctrl-owl.h b/drivers/pinctrl/actions/pinctrl-owl.h
new file mode 100644
index 000000000000..448f81a6db3b
--- /dev/null
+++ b/drivers/pinctrl/actions/pinctrl-owl.h
@@ -0,0 +1,142 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * OWL SoC's Pinctrl definitions
+ *
+ * Copyright (c) 2014 Actions Semi Inc.
+ * Author: David Liu <liuwei@actions-semi.com>
+ *
+ * Copyright (c) 2018 Linaro Ltd.
+ * Author: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+ */
+
+#ifndef __PINCTRL_OWL_H__
+#define __PINCTRL_OWL_H__
+
+#define OWL_PINCONF_SLEW_SLOW 0
+#define OWL_PINCONF_SLEW_FAST 1
+
+enum owl_pinconf_pull {
+	OWL_PINCONF_PULL_HIZ,
+	OWL_PINCONF_PULL_DOWN,
+	OWL_PINCONF_PULL_UP,
+	OWL_PINCONF_PULL_HOLD,
+};
+
+enum owl_pinconf_drv {
+	OWL_PINCONF_DRV_2MA,
+	OWL_PINCONF_DRV_4MA,
+	OWL_PINCONF_DRV_8MA,
+	OWL_PINCONF_DRV_12MA,
+};
+
+/**
+ * struct owl_pullctl - Actions pad pull control register
+ * @reg: offset to the pull control register
+ * @shift: shift value of the register
+ * @width: width of the register
+ */
+struct owl_pullctl {
+	int reg;
+	unsigned int shift;
+	unsigned int width;
+};
+
+/**
+ * struct owl_st - Actions pad schmitt trigger enable register
+ * @reg: offset to the schmitt trigger enable register
+ * @shift: shift value of the register
+ * @width: width of the register
+ */
+struct owl_st {
+	int reg;
+	unsigned int shift;
+	unsigned int width;
+};
+
+/**
+ * struct owl_pingroup - Actions pingroup definition
+ * @name: name of the  pin group
+ * @pads: list of pins assigned to this pingroup
+ * @npads: size of @pads array
+ * @funcs: list of pinmux functions for this pingroup
+ * @nfuncs: size of @funcs array
+ * @mfpctl_reg: multiplexing control register offset
+ * @mfpctl_shift: multiplexing control register bit mask
+ * @mfpctl_width: multiplexing control register width
+ * @drv_reg: drive control register offset
+ * @drv_shift: drive control register bit mask
+ * @drv_width: driver control register width
+ * @sr_reg: slew rate control register offset
+ * @sr_shift: slew rate control register bit mask
+ * @sr_width: slew rate control register width
+ */
+struct owl_pingroup {
+	const char *name;
+	unsigned int *pads;
+	unsigned int npads;
+	unsigned int *funcs;
+	unsigned int nfuncs;
+
+	int mfpctl_reg;
+	unsigned int mfpctl_shift;
+	unsigned int mfpctl_width;
+
+	int drv_reg;
+	unsigned int drv_shift;
+	unsigned int drv_width;
+
+	int sr_reg;
+	unsigned int sr_shift;
+	unsigned int sr_width;
+};
+
+/**
+ * struct owl_padinfo - Actions pinctrl pad info
+ * @pad: pad name of the SoC
+ * @pullctl: pull control register info
+ * @st: schmitt trigger register info
+ */
+struct owl_padinfo {
+	int pad;
+	struct owl_pullctl *pullctl;
+	struct owl_st *st;
+};
+
+/**
+ * struct owl_pinmux_func - Actions pinctrl mux functions
+ * @name: name of the pinmux function.
+ * @groups: array of pin groups that may select this function.
+ * @ngroups: number of entries in @groups.
+ */
+struct owl_pinmux_func {
+	const char *name;
+	const char * const *groups;
+	unsigned int ngroups;
+};
+
+/**
+ * struct owl_pinctrl_soc_data - Actions pin controller driver configuration
+ * @pins: array describing all pins of the pin controller.
+ * @npins: number of entries in @pins.
+ * @functions: array describing all mux functions of this SoC.
+ * @nfunction: number of entries in @functions.
+ * @groups: array describing all pin groups of this SoC.
+ * @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.
+ */
+struct owl_pinctrl_soc_data {
+	const struct pinctrl_pin_desc *pins;
+	unsigned int npins;
+	const struct owl_pinmux_func *functions;
+	unsigned int nfunctions;
+	const struct owl_pingroup *groups;
+	unsigned int ngroups;
+	const struct owl_padinfo *padinfo;
+	unsigned int ngpios;
+};
+
+int owl_pinctrl_probe(struct platform_device *pdev,
+		struct owl_pinctrl_soc_data *soc_data);
+
+#endif /* __PINCTRL_OWL_H__ */
diff --git a/drivers/pinctrl/actions/pinctrl-s900.c b/drivers/pinctrl/actions/pinctrl-s900.c
new file mode 100644
index 000000000000..f320ddaea865
--- /dev/null
+++ b/drivers/pinctrl/actions/pinctrl-s900.c
@@ -0,0 +1,2505 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * OWL S900 Pinctrl driver
+ *
+ * Copyright (c) 2014 Actions Semi Inc.
+ * Author: David Liu <liuwei@actions-semi.com>
+ *
+ * Copyright (c) 2018 Linaro Ltd.
+ * Author: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+ */
+
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pinctrl/pinctrl.h>
+#include "pinctrl-owl.h"
+
+/* Pinctrl registers offset */
+#define MFCTL0			(0x0040)
+#define MFCTL1			(0x0044)
+#define MFCTL2			(0x0048)
+#define MFCTL3			(0x004C)
+#define PAD_PULLCTL0		(0x0060)
+#define PAD_PULLCTL1		(0x0064)
+#define PAD_PULLCTL2		(0x0068)
+#define PAD_ST0			(0x006C)
+#define PAD_ST1			(0x0070)
+#define PAD_CTL			(0x0074)
+#define PAD_DRV0		(0x0080)
+#define PAD_DRV1		(0x0084)
+#define PAD_DRV2		(0x0088)
+#define PAD_SR0			(0x0270)
+#define PAD_SR1			(0x0274)
+#define PAD_SR2			(0x0278)
+
+#define _GPIOA(offset)		(offset)
+#define _GPIOB(offset)		(32 + (offset))
+#define _GPIOC(offset)		(64 + (offset))
+#define _GPIOD(offset)		(76 + (offset))
+#define _GPIOE(offset)		(106 + (offset))
+#define _GPIOF(offset)		(138 + (offset))
+
+#define NUM_GPIOS		(_GPIOF(7) + 1)
+#define _PIN(offset)		(NUM_GPIOS + (offset))
+
+#define ETH_TXD0		_GPIOA(0)
+#define ETH_TXD1		_GPIOA(1)
+#define ETH_TXEN		_GPIOA(2)
+#define ETH_RXER		_GPIOA(3)
+#define ETH_CRS_DV		_GPIOA(4)
+#define ETH_RXD1		_GPIOA(5)
+#define ETH_RXD0		_GPIOA(6)
+#define ETH_REF_CLK		_GPIOA(7)
+#define ETH_MDC			_GPIOA(8)
+#define ETH_MDIO		_GPIOA(9)
+#define SIRQ0			_GPIOA(10)
+#define SIRQ1			_GPIOA(11)
+#define SIRQ2			_GPIOA(12)
+#define I2S_D0			_GPIOA(13)
+#define I2S_BCLK0		_GPIOA(14)
+#define I2S_LRCLK0		_GPIOA(15)
+#define I2S_MCLK0		_GPIOA(16)
+#define I2S_D1			_GPIOA(17)
+#define I2S_BCLK1		_GPIOA(18)
+#define I2S_LRCLK1		_GPIOA(19)
+#define I2S_MCLK1		_GPIOA(20)
+#define ERAM_A5			_GPIOA(21)
+#define ERAM_A6			_GPIOA(22)
+#define ERAM_A7			_GPIOA(23)
+#define ERAM_A8			_GPIOA(24)
+#define ERAM_A9			_GPIOA(25)
+#define ERAM_A10		_GPIOA(26)
+#define ERAM_A11		_GPIOA(27)
+#define SD0_D0			_GPIOA(28)
+#define SD0_D1			_GPIOA(29)
+#define SD0_D2			_GPIOA(30)
+#define SD0_D3			_GPIOA(31)
+
+#define SD1_D0			_GPIOB(0)
+#define SD1_D1			_GPIOB(1)
+#define SD1_D2			_GPIOB(2)
+#define SD1_D3			_GPIOB(3)
+#define SD0_CMD			_GPIOB(4)
+#define SD0_CLK			_GPIOB(5)
+#define SD1_CMD			_GPIOB(6)
+#define SD1_CLK			_GPIOB(7)
+#define SPI0_SCLK		_GPIOB(8)
+#define SPI0_SS			_GPIOB(9)
+#define SPI0_MISO		_GPIOB(10)
+#define SPI0_MOSI		_GPIOB(11)
+#define UART0_RX		_GPIOB(12)
+#define UART0_TX		_GPIOB(13)
+#define UART2_RX		_GPIOB(14)
+#define UART2_TX		_GPIOB(15)
+#define UART2_RTSB		_GPIOB(16)
+#define UART2_CTSB		_GPIOB(17)
+#define UART4_RX		_GPIOB(18)
+#define UART4_TX		_GPIOB(19)
+#define I2C0_SCLK		_GPIOB(20)
+#define I2C0_SDATA		_GPIOB(21)
+#define I2C1_SCLK		_GPIOB(22)
+#define I2C1_SDATA		_GPIOB(23)
+#define I2C2_SCLK		_GPIOB(24)
+#define I2C2_SDATA		_GPIOB(25)
+#define CSI0_DN0		_GPIOB(26)
+#define CSI0_DP0		_GPIOB(27)
+#define CSI0_DN1		_GPIOB(28)
+#define CSI0_DP1		_GPIOB(29)
+#define CSI0_CN			_GPIOB(30)
+#define CSI0_CP			_GPIOB(31)
+
+#define CSI0_DN2		_GPIOC(0)
+#define CSI0_DP2		_GPIOC(1)
+#define CSI0_DN3		_GPIOC(2)
+#define CSI0_DP3		_GPIOC(3)
+#define SENSOR0_PCLK		_GPIOC(4)
+#define CSI1_DN0		_GPIOC(5)
+#define CSI1_DP0		_GPIOC(6)
+#define CSI1_DN1		_GPIOC(7)
+#define CSI1_DP1		_GPIOC(8)
+#define CSI1_CN			_GPIOC(9)
+#define CSI1_CP			_GPIOC(10)
+#define SENSOR0_CKOUT		_GPIOC(11)
+
+#define LVDS_OEP		_GPIOD(0)
+#define LVDS_OEN		_GPIOD(1)
+#define LVDS_ODP		_GPIOD(2)
+#define LVDS_ODN		_GPIOD(3)
+#define LVDS_OCP		_GPIOD(4)
+#define LVDS_OCN		_GPIOD(5)
+#define LVDS_OBP		_GPIOD(6)
+#define LVDS_OBN		_GPIOD(7)
+#define LVDS_OAP		_GPIOD(8)
+#define LVDS_OAN		_GPIOD(9)
+#define LVDS_EEP		_GPIOD(10)
+#define LVDS_EEN		_GPIOD(11)
+#define LVDS_EDP		_GPIOD(12)
+#define LVDS_EDN		_GPIOD(13)
+#define LVDS_ECP		_GPIOD(14)
+#define LVDS_ECN		_GPIOD(15)
+#define LVDS_EBP		_GPIOD(16)
+#define LVDS_EBN		_GPIOD(17)
+#define LVDS_EAP		_GPIOD(18)
+#define LVDS_EAN		_GPIOD(19)
+#define DSI_DP3			_GPIOD(20)
+#define DSI_DN3			_GPIOD(21)
+#define DSI_DP1			_GPIOD(22)
+#define DSI_DN1			_GPIOD(23)
+#define DSI_CP			_GPIOD(24)
+#define DSI_CN			_GPIOD(25)
+#define DSI_DP0			_GPIOD(26)
+#define DSI_DN0			_GPIOD(27)
+#define DSI_DP2			_GPIOD(28)
+#define DSI_DN2			_GPIOD(29)
+
+#define NAND0_D0		_GPIOE(0)
+#define NAND0_D1		_GPIOE(1)
+#define NAND0_D2		_GPIOE(2)
+#define NAND0_D3		_GPIOE(3)
+#define NAND0_D4		_GPIOE(4)
+#define NAND0_D5		_GPIOE(5)
+#define NAND0_D6		_GPIOE(6)
+#define NAND0_D7		_GPIOE(7)
+#define NAND0_DQS		_GPIOE(8)
+#define NAND0_DQSN		_GPIOE(9)
+#define NAND0_ALE		_GPIOE(10)
+#define NAND0_CLE		_GPIOE(11)
+#define NAND0_CEB0		_GPIOE(12)
+#define NAND0_CEB1		_GPIOE(13)
+#define NAND0_CEB2		_GPIOE(14)
+#define NAND0_CEB3		_GPIOE(15)
+#define NAND1_D0		_GPIOE(16)
+#define NAND1_D1		_GPIOE(17)
+#define NAND1_D2		_GPIOE(18)
+#define NAND1_D3		_GPIOE(19)
+#define NAND1_D4		_GPIOE(20)
+#define NAND1_D5		_GPIOE(21)
+#define NAND1_D6		_GPIOE(22)
+#define NAND1_D7		_GPIOE(23)
+#define NAND1_DQS		_GPIOE(24)
+#define NAND1_DQSN		_GPIOE(25)
+#define NAND1_ALE		_GPIOE(26)
+#define NAND1_CLE		_GPIOE(27)
+#define NAND1_CEB0		_GPIOE(28)
+#define NAND1_CEB1		_GPIOE(29)
+#define NAND1_CEB2		_GPIOE(30)
+#define NAND1_CEB3		_GPIOE(31)
+
+#define PCM1_IN			_GPIOF(0)
+#define PCM1_CLK		_GPIOF(1)
+#define PCM1_SYNC		_GPIOF(2)
+#define PCM1_OUT		_GPIOF(3)
+#define UART3_RX		_GPIOF(4)
+#define UART3_TX		_GPIOF(5)
+#define UART3_RTSB		_GPIOF(6)
+#define UART3_CTSB		_GPIOF(7)
+
+/* System */
+#define SGPIO0			_PIN(0)
+#define SGPIO1			_PIN(1)
+#define SGPIO2			_PIN(2)
+#define SGPIO3			_PIN(3)
+
+#define NUM_PADS		(_PIN(3) + 1)
+
+/* Pad names as specified in datasheet */
+const struct pinctrl_pin_desc s900_pads[] = {
+	PINCTRL_PIN(ETH_TXD0, "eth_txd0"),
+	PINCTRL_PIN(ETH_TXD1, "eth_txd1"),
+	PINCTRL_PIN(ETH_TXEN, "eth_txen"),
+	PINCTRL_PIN(ETH_RXER, "eth_rxer"),
+	PINCTRL_PIN(ETH_CRS_DV, "eth_crs_dv"),
+	PINCTRL_PIN(ETH_RXD1, "eth_rxd1"),
+	PINCTRL_PIN(ETH_RXD0, "eth_rxd0"),
+	PINCTRL_PIN(ETH_REF_CLK, "eth_ref_clk"),
+	PINCTRL_PIN(ETH_MDC, "eth_mdc"),
+	PINCTRL_PIN(ETH_MDIO, "eth_mdio"),
+	PINCTRL_PIN(SIRQ0, "sirq0"),
+	PINCTRL_PIN(SIRQ1, "sirq1"),
+	PINCTRL_PIN(SIRQ2, "sirq2"),
+	PINCTRL_PIN(I2S_D0, "i2s_d0"),
+	PINCTRL_PIN(I2S_BCLK0, "i2s_bclk0"),
+	PINCTRL_PIN(I2S_LRCLK0, "i2s_lrclk0"),
+	PINCTRL_PIN(I2S_MCLK0, "i2s_mclk0"),
+	PINCTRL_PIN(I2S_D1, "i2s_d1"),
+	PINCTRL_PIN(I2S_BCLK1, "i2s_bclk1"),
+	PINCTRL_PIN(I2S_LRCLK1, "i2s_lrclk1"),
+	PINCTRL_PIN(I2S_MCLK1, "i2s_mclk1"),
+	PINCTRL_PIN(PCM1_IN, "pcm1_in"),
+	PINCTRL_PIN(PCM1_CLK, "pcm1_clk"),
+	PINCTRL_PIN(PCM1_SYNC, "pcm1_sync"),
+	PINCTRL_PIN(PCM1_OUT, "pcm1_out"),
+	PINCTRL_PIN(ERAM_A5, "eram_a5"),
+	PINCTRL_PIN(ERAM_A6, "eram_a6"),
+	PINCTRL_PIN(ERAM_A7, "eram_a7"),
+	PINCTRL_PIN(ERAM_A8, "eram_a8"),
+	PINCTRL_PIN(ERAM_A9, "eram_a9"),
+	PINCTRL_PIN(ERAM_A10, "eram_a10"),
+	PINCTRL_PIN(ERAM_A11, "eram_a11"),
+	PINCTRL_PIN(LVDS_OEP, "lvds_oep"),
+	PINCTRL_PIN(LVDS_OEN, "lvds_oen"),
+	PINCTRL_PIN(LVDS_ODP, "lvds_odp"),
+	PINCTRL_PIN(LVDS_ODN, "lvds_odn"),
+	PINCTRL_PIN(LVDS_OCP, "lvds_ocp"),
+	PINCTRL_PIN(LVDS_OCN, "lvds_ocn"),
+	PINCTRL_PIN(LVDS_OBP, "lvds_obp"),
+	PINCTRL_PIN(LVDS_OBN, "lvds_obn"),
+	PINCTRL_PIN(LVDS_OAP, "lvds_oap"),
+	PINCTRL_PIN(LVDS_OAN, "lvds_oan"),
+	PINCTRL_PIN(LVDS_EEP, "lvds_eep"),
+	PINCTRL_PIN(LVDS_EEN, "lvds_een"),
+	PINCTRL_PIN(LVDS_EDP, "lvds_edp"),
+	PINCTRL_PIN(LVDS_EDN, "lvds_edn"),
+	PINCTRL_PIN(LVDS_ECP, "lvds_ecp"),
+	PINCTRL_PIN(LVDS_ECN, "lvds_ecn"),
+	PINCTRL_PIN(LVDS_EBP, "lvds_ebp"),
+	PINCTRL_PIN(LVDS_EBN, "lvds_ebn"),
+	PINCTRL_PIN(LVDS_EAP, "lvds_eap"),
+	PINCTRL_PIN(LVDS_EAN, "lvds_ean"),
+	PINCTRL_PIN(SD0_D0, "sd0_d0"),
+	PINCTRL_PIN(SD0_D1, "sd0_d1"),
+	PINCTRL_PIN(SD0_D2, "sd0_d2"),
+	PINCTRL_PIN(SD0_D3, "sd0_d3"),
+	PINCTRL_PIN(SD1_D0, "sd1_d0"),
+	PINCTRL_PIN(SD1_D1, "sd1_d1"),
+	PINCTRL_PIN(SD1_D2, "sd1_d2"),
+	PINCTRL_PIN(SD1_D3, "sd1_d3"),
+	PINCTRL_PIN(SD0_CMD, "sd0_cmd"),
+	PINCTRL_PIN(SD0_CLK, "sd0_clk"),
+	PINCTRL_PIN(SD1_CMD, "sd1_cmd"),
+	PINCTRL_PIN(SD1_CLK, "sd1_clk"),
+	PINCTRL_PIN(SPI0_SCLK, "spi0_sclk"),
+	PINCTRL_PIN(SPI0_SS, "spi0_ss"),
+	PINCTRL_PIN(SPI0_MISO, "spi0_miso"),
+	PINCTRL_PIN(SPI0_MOSI, "spi0_mosi"),
+	PINCTRL_PIN(UART0_RX, "uart0_rx"),
+	PINCTRL_PIN(UART0_TX, "uart0_tx"),
+	PINCTRL_PIN(UART2_RX, "uart2_rx"),
+	PINCTRL_PIN(UART2_TX, "uart2_tx"),
+	PINCTRL_PIN(UART2_RTSB, "uart2_rtsb"),
+	PINCTRL_PIN(UART2_CTSB, "uart2_ctsb"),
+	PINCTRL_PIN(UART3_RX, "uart3_rx"),
+	PINCTRL_PIN(UART3_TX, "uart3_tx"),
+	PINCTRL_PIN(UART3_RTSB, "uart3_rtsb"),
+	PINCTRL_PIN(UART3_CTSB, "uart3_ctsb"),
+	PINCTRL_PIN(UART4_RX, "uart4_rx"),
+	PINCTRL_PIN(UART4_TX, "uart4_tx"),
+	PINCTRL_PIN(I2C0_SCLK, "i2c0_sclk"),
+	PINCTRL_PIN(I2C0_SDATA, "i2c0_sdata"),
+	PINCTRL_PIN(I2C1_SCLK, "i2c1_sclk"),
+	PINCTRL_PIN(I2C1_SDATA, "i2c1_sdata"),
+	PINCTRL_PIN(I2C2_SCLK, "i2c2_sclk"),
+	PINCTRL_PIN(I2C2_SDATA, "i2c2_sdata"),
+	PINCTRL_PIN(CSI0_DN0, "csi0_dn0"),
+	PINCTRL_PIN(CSI0_DP0, "csi0_dp0"),
+	PINCTRL_PIN(CSI0_DN1, "csi0_dn1"),
+	PINCTRL_PIN(CSI0_DP1, "csi0_dp1"),
+	PINCTRL_PIN(CSI0_CN, "csi0_cn"),
+	PINCTRL_PIN(CSI0_CP, "csi0_cp"),
+	PINCTRL_PIN(CSI0_DN2, "csi0_dn2"),
+	PINCTRL_PIN(CSI0_DP2, "csi0_dp2"),
+	PINCTRL_PIN(CSI0_DN3, "csi0_dn3"),
+	PINCTRL_PIN(CSI0_DP3, "csi0_dp3"),
+	PINCTRL_PIN(DSI_DP3, "dsi_dp3"),
+	PINCTRL_PIN(DSI_DN3, "dsi_dn3"),
+	PINCTRL_PIN(DSI_DP1, "dsi_dp1"),
+	PINCTRL_PIN(DSI_DN1, "dsi_dn1"),
+	PINCTRL_PIN(DSI_CP, "dsi_cp"),
+	PINCTRL_PIN(DSI_CN, "dsi_cn"),
+	PINCTRL_PIN(DSI_DP0, "dsi_dp0"),
+	PINCTRL_PIN(DSI_DN0, "dsi_dn0"),
+	PINCTRL_PIN(DSI_DP2, "dsi_dp2"),
+	PINCTRL_PIN(DSI_DN2, "dsi_dn2"),
+	PINCTRL_PIN(SENSOR0_PCLK, "sensor0_pclk"),
+	PINCTRL_PIN(CSI1_DN0, "csi1_dn0"),
+	PINCTRL_PIN(CSI1_DP0, "csi1_dp0"),
+	PINCTRL_PIN(CSI1_DN1, "csi1_dn1"),
+	PINCTRL_PIN(CSI1_DP1, "csi1_dp1"),
+	PINCTRL_PIN(CSI1_CN, "csi1_cn"),
+	PINCTRL_PIN(CSI1_CP, "csi1_cp"),
+	PINCTRL_PIN(SENSOR0_CKOUT, "sensor0_ckout"),
+	PINCTRL_PIN(NAND0_D0, "nand0_d0"),
+	PINCTRL_PIN(NAND0_D1, "nand0_d1"),
+	PINCTRL_PIN(NAND0_D2, "nand0_d2"),
+	PINCTRL_PIN(NAND0_D3, "nand0_d3"),
+	PINCTRL_PIN(NAND0_D4, "nand0_d4"),
+	PINCTRL_PIN(NAND0_D5, "nand0_d5"),
+	PINCTRL_PIN(NAND0_D6, "nand0_d6"),
+	PINCTRL_PIN(NAND0_D7, "nand0_d7"),
+	PINCTRL_PIN(NAND0_DQS, "nand0_dqs"),
+	PINCTRL_PIN(NAND0_DQSN, "nand0_dqsn"),
+	PINCTRL_PIN(NAND0_ALE, "nand0_ale"),
+	PINCTRL_PIN(NAND0_CLE, "nand0_cle"),
+	PINCTRL_PIN(NAND0_CEB0, "nand0_ceb0"),
+	PINCTRL_PIN(NAND0_CEB1, "nand0_ceb1"),
+	PINCTRL_PIN(NAND0_CEB2, "nand0_ceb2"),
+	PINCTRL_PIN(NAND0_CEB3, "nand0_ceb3"),
+	PINCTRL_PIN(NAND1_D0, "nand1_d0"),
+	PINCTRL_PIN(NAND1_D1, "nand1_d1"),
+	PINCTRL_PIN(NAND1_D2, "nand1_d2"),
+	PINCTRL_PIN(NAND1_D3, "nand1_d3"),
+	PINCTRL_PIN(NAND1_D4, "nand1_d4"),
+	PINCTRL_PIN(NAND1_D5, "nand1_d5"),
+	PINCTRL_PIN(NAND1_D6, "nand1_d6"),
+	PINCTRL_PIN(NAND1_D7, "nand1_d7"),
+	PINCTRL_PIN(NAND1_DQS, "nand1_dqs"),
+	PINCTRL_PIN(NAND1_DQSN, "nand1_dqsn"),
+	PINCTRL_PIN(NAND1_ALE, "nand1_ale"),
+	PINCTRL_PIN(NAND1_CLE, "nand1_cle"),
+	PINCTRL_PIN(NAND1_CEB0, "nand1_ceb0"),
+	PINCTRL_PIN(NAND1_CEB1, "nand1_ceb1"),
+	PINCTRL_PIN(NAND1_CEB2, "nand1_ceb2"),
+	PINCTRL_PIN(NAND1_CEB3, "nand1_ceb3"),
+	PINCTRL_PIN(SGPIO0, "sgpio0"),
+	PINCTRL_PIN(SGPIO1, "sgpio1"),
+	PINCTRL_PIN(SGPIO2, "sgpio2"),
+	PINCTRL_PIN(SGPIO3, "sgpio3")
+};
+
+enum s900_pinmux_functions {
+	S900_MUX_ERAM,
+	S900_MUX_ETH_RMII,
+	S900_MUX_ETH_SMII,
+	S900_MUX_SPI0,
+	S900_MUX_SPI1,
+	S900_MUX_SPI2,
+	S900_MUX_SPI3,
+	S900_MUX_SENS0,
+	S900_MUX_UART0,
+	S900_MUX_UART1,
+	S900_MUX_UART2,
+	S900_MUX_UART3,
+	S900_MUX_UART4,
+	S900_MUX_UART5,
+	S900_MUX_UART6,
+	S900_MUX_I2S0,
+	S900_MUX_I2S1,
+	S900_MUX_PCM0,
+	S900_MUX_PCM1,
+	S900_MUX_JTAG,
+	S900_MUX_PWM0,
+	S900_MUX_PWM1,
+	S900_MUX_PWM2,
+	S900_MUX_PWM3,
+	S900_MUX_PWM4,
+	S900_MUX_PWM5,
+	S900_MUX_SD0,
+	S900_MUX_SD1,
+	S900_MUX_SD2,
+	S900_MUX_SD3,
+	S900_MUX_I2C0,
+	S900_MUX_I2C1,
+	S900_MUX_I2C2,
+	S900_MUX_I2C3,
+	S900_MUX_I2C4,
+	S900_MUX_I2C5,
+	S900_MUX_LVDS,
+	S900_MUX_USB20,
+	S900_MUX_USB30,
+	S900_MUX_GPU,
+	S900_MUX_MIPI_CSI0,
+	S900_MUX_MIPI_CSI1,
+	S900_MUX_MIPI_DSI,
+	S900_MUX_NAND0,
+	S900_MUX_NAND1,
+	S900_MUX_SPDIF,
+	S900_MUX_SIRQ0,
+	S900_MUX_SIRQ1,
+	S900_MUX_SIRQ2,
+	S900_MUX_AUX_START,
+	S900_MUX_MAX,
+	S900_MUX_RESERVED
+};
+
+/* mfp0_22 */
+static unsigned int lvds_oxx_uart4_mfp_pads[] = {
+	LVDS_OAP,
+	LVDS_OAN,
+};
+
+static unsigned int lvds_oxx_uart4_mfp_funcs[] = {
+	S900_MUX_ERAM,
+	S900_MUX_UART4,
+};
+
+/* mfp0_21_20 */
+static unsigned int rmii_mdc_mfp_pads[] = {
+	ETH_MDC,
+};
+
+static unsigned int rmii_mdc_mfp_funcs[] = {
+	S900_MUX_ETH_RMII,
+	S900_MUX_PWM2,
+	S900_MUX_UART2,
+	S900_MUX_RESERVED,
+};
+
+static unsigned int rmii_mdio_mfp_pads[] = {
+	ETH_MDIO,
+};
+
+static unsigned int rmii_mdio_mfp_funcs[] = {
+	S900_MUX_ETH_RMII,
+	S900_MUX_PWM3,
+	S900_MUX_UART2,
+	S900_MUX_RESERVED,
+};
+
+/* mfp0_19 */
+static unsigned int sirq0_mfp_pads[] = {
+	SIRQ0,
+};
+
+static unsigned int sirq0_mfp_funcs[] = {
+	S900_MUX_SIRQ0,
+	S900_MUX_PWM0,
+};
+
+static unsigned int sirq1_mfp_pads[] = {
+	SIRQ1,
+};
+
+static unsigned int sirq1_mfp_funcs[] = {
+	S900_MUX_SIRQ1,
+	S900_MUX_PWM1,
+};
+
+/* mfp0_18_16 */
+static unsigned int rmii_txd0_mfp_pads[] = {
+	ETH_TXD0,
+};
+
+static unsigned int rmii_txd0_mfp_funcs[] = {
+	S900_MUX_ETH_RMII,
+	S900_MUX_ETH_SMII,
+	S900_MUX_SPI2,
+	S900_MUX_UART6,
+	S900_MUX_SENS0,
+	S900_MUX_PWM0,
+};
+
+static unsigned int rmii_txd1_mfp_pads[] = {
+	ETH_TXD1,
+};
+
+static unsigned int rmii_txd1_mfp_funcs[] = {
+	S900_MUX_ETH_RMII,
+	S900_MUX_ETH_SMII,
+	S900_MUX_SPI2,
+	S900_MUX_UART6,
+	S900_MUX_SENS0,
+	S900_MUX_PWM1,
+};
+
+/* mfp0_15_13 */
+static unsigned int rmii_txen_mfp_pads[] = {
+	ETH_TXEN,
+};
+
+static unsigned int rmii_txen_mfp_funcs[] = {
+	S900_MUX_ETH_RMII,
+	S900_MUX_UART2,
+	S900_MUX_SPI3,
+	S900_MUX_RESERVED,
+	S900_MUX_RESERVED,
+	S900_MUX_PWM2,
+	S900_MUX_SENS0,
+};
+
+static unsigned int rmii_rxer_mfp_pads[] = {
+	ETH_RXER,
+};
+
+static unsigned int rmii_rxer_mfp_funcs[] = {
+	S900_MUX_ETH_RMII,
+	S900_MUX_UART2,
+	S900_MUX_SPI3,
+	S900_MUX_RESERVED,
+	S900_MUX_RESERVED,
+	S900_MUX_PWM3,
+	S900_MUX_SENS0,
+};
+
+/* mfp0_12_11 */
+static unsigned int rmii_crs_dv_mfp_pads[] = {
+	ETH_CRS_DV,
+};
+
+static unsigned int rmii_crs_dv_mfp_funcs[] = {
+	S900_MUX_ETH_RMII,
+	S900_MUX_ETH_SMII,
+	S900_MUX_SPI2,
+	S900_MUX_UART4,
+};
+
+/* mfp0_10_8 */
+static unsigned int rmii_rxd1_mfp_pads[] = {
+	ETH_RXD1,
+};
+
+static unsigned int rmii_rxd1_mfp_funcs[] = {
+	S900_MUX_ETH_RMII,
+	S900_MUX_UART2,
+	S900_MUX_SPI3,
+	S900_MUX_RESERVED,
+	S900_MUX_UART5,
+	S900_MUX_PWM0,
+	S900_MUX_SENS0,
+};
+
+static unsigned int rmii_rxd0_mfp_pads[] = {
+	ETH_RXD0,
+};
+
+static unsigned int rmii_rxd0_mfp_funcs[] = {
+	S900_MUX_ETH_RMII,
+	S900_MUX_UART2,
+	S900_MUX_SPI3,
+	S900_MUX_RESERVED,
+	S900_MUX_UART5,
+	S900_MUX_PWM1,
+	S900_MUX_SENS0,
+};
+
+/* mfp0_7_6 */
+static unsigned int rmii_ref_clk_mfp_pads[] = {
+	ETH_REF_CLK,
+};
+
+static unsigned int rmii_ref_clk_mfp_funcs[] = {
+	S900_MUX_ETH_RMII,
+	S900_MUX_UART4,
+	S900_MUX_SPI2,
+	S900_MUX_RESERVED,
+};
+
+/* mfp0_5 */
+static unsigned int i2s_d0_mfp_pads[] = {
+	I2S_D0,
+};
+
+static unsigned int i2s_d0_mfp_funcs[] = {
+	S900_MUX_I2S0,
+	S900_MUX_PCM0,
+};
+
+static unsigned int i2s_d1_mfp_pads[] = {
+	I2S_D1,
+};
+
+static unsigned int i2s_d1_mfp_funcs[] = {
+	S900_MUX_I2S1,
+	S900_MUX_PCM0,
+};
+
+/* mfp0_4_3 */
+static unsigned int i2s_lr_m_clk0_mfp_pads[] = {
+	I2S_LRCLK0,
+	I2S_MCLK0,
+};
+
+static unsigned int i2s_lr_m_clk0_mfp_funcs[] = {
+	S900_MUX_I2S0,
+	S900_MUX_PCM0,
+	S900_MUX_PCM1,
+	S900_MUX_RESERVED,
+};
+
+/* mfp0_2 */
+static unsigned int i2s_bclk0_mfp_pads[] = {
+	I2S_BCLK0,
+};
+
+static unsigned int i2s_bclk0_mfp_funcs[] = {
+	S900_MUX_I2S0,
+	S900_MUX_PCM0,
+};
+
+static unsigned int i2s_bclk1_mclk1_mfp_pads[] = {
+	I2S_BCLK1,
+	I2S_LRCLK1,
+	I2S_MCLK1,
+};
+
+static unsigned int i2s_bclk1_mclk1_mfp_funcs[] = {
+	S900_MUX_I2S1,
+	S900_MUX_PCM0,
+};
+
+/* mfp0_1_0 */
+static unsigned int pcm1_in_out_mfp_pads[] = {
+	PCM1_IN,
+	PCM1_OUT,
+};
+
+static unsigned int pcm1_in_out_mfp_funcs[] = {
+	S900_MUX_PCM1,
+	S900_MUX_SPI1,
+	S900_MUX_I2C3,
+	S900_MUX_UART4,
+};
+
+static unsigned int pcm1_clk_mfp_pads[] = {
+	PCM1_CLK,
+};
+
+static unsigned int pcm1_clk_mfp_funcs[] = {
+	S900_MUX_PCM1,
+	S900_MUX_SPI1,
+	S900_MUX_PWM4,
+	S900_MUX_UART4,
+};
+
+static unsigned int pcm1_sync_mfp_pads[] = {
+	PCM1_SYNC,
+};
+
+static unsigned int pcm1_sync_mfp_funcs[] = {
+	S900_MUX_PCM1,
+	S900_MUX_SPI1,
+	S900_MUX_PWM5,
+	S900_MUX_UART4,
+};
+
+/* mfp1_31_29 */
+static unsigned int eram_a5_mfp_pads[] = {
+	ERAM_A5,
+};
+
+static unsigned int eram_a5_mfp_funcs[] = {
+	S900_MUX_UART4,
+	S900_MUX_JTAG,
+	S900_MUX_ERAM,
+	S900_MUX_PWM0,
+	S900_MUX_RESERVED,
+	S900_MUX_SENS0,
+};
+
+static unsigned int eram_a6_mfp_pads[] = {
+	ERAM_A6,
+};
+
+static unsigned int eram_a6_mfp_funcs[] = {
+	S900_MUX_UART4,
+	S900_MUX_JTAG,
+	S900_MUX_ERAM,
+	S900_MUX_PWM1,
+	S900_MUX_RESERVED,
+	S900_MUX_SENS0,
+};
+
+static unsigned int eram_a7_mfp_pads[] = {
+	ERAM_A7,
+};
+
+static unsigned int eram_a7_mfp_funcs[] = {
+	S900_MUX_RESERVED,
+	S900_MUX_JTAG,
+	S900_MUX_ERAM,
+	S900_MUX_RESERVED,
+	S900_MUX_RESERVED,
+	S900_MUX_SENS0,
+};
+
+/* mfp1_28_26 */
+static unsigned int eram_a8_mfp_pads[] = {
+	ERAM_A8,
+};
+
+static unsigned int eram_a8_mfp_funcs[] = {
+	S900_MUX_RESERVED,
+	S900_MUX_JTAG,
+	S900_MUX_ERAM,
+	S900_MUX_PWM1,
+	S900_MUX_RESERVED,
+	S900_MUX_SENS0,
+};
+
+static unsigned int eram_a9_mfp_pads[] = {
+	ERAM_A9,
+};
+
+static unsigned int eram_a9_mfp_funcs[] = {
+	S900_MUX_USB20,
+	S900_MUX_UART5,
+	S900_MUX_ERAM,
+	S900_MUX_PWM2,
+	S900_MUX_RESERVED,
+	S900_MUX_SENS0,
+};
+
+static unsigned int eram_a10_mfp_pads[] = {
+	ERAM_A10,
+};
+
+static unsigned int eram_a10_mfp_funcs[] = {
+	S900_MUX_USB30,
+	S900_MUX_JTAG,
+	S900_MUX_ERAM,
+	S900_MUX_PWM3,
+	S900_MUX_RESERVED,
+	S900_MUX_SENS0,
+	S900_MUX_RESERVED,
+	S900_MUX_RESERVED,
+};
+
+/* mfp1_25_23 */
+static unsigned int eram_a11_mfp_pads[] = {
+	ERAM_A11,
+};
+
+static unsigned int eram_a11_mfp_funcs[] = {
+	S900_MUX_RESERVED,
+	S900_MUX_RESERVED,
+	S900_MUX_ERAM,
+	S900_MUX_PWM2,
+	S900_MUX_UART5,
+	S900_MUX_RESERVED,
+	S900_MUX_SENS0,
+	S900_MUX_RESERVED,
+};
+
+/* mfp1_22 */
+static unsigned int lvds_oep_odn_mfp_pads[] = {
+	LVDS_OEP,
+	LVDS_OEN,
+	LVDS_ODP,
+	LVDS_ODN,
+};
+
+static unsigned int lvds_oep_odn_mfp_funcs[] = {
+	S900_MUX_LVDS,
+	S900_MUX_UART2,
+};
+
+static unsigned int lvds_ocp_obn_mfp_pads[] = {
+	LVDS_OCP,
+	LVDS_OCN,
+	LVDS_OBP,
+	LVDS_OBN,
+};
+
+static unsigned int lvds_ocp_obn_mfp_funcs[] = {
+	S900_MUX_LVDS,
+	S900_MUX_PCM1,
+};
+
+static unsigned int lvds_oap_oan_mfp_pads[] = {
+	LVDS_OAP,
+	LVDS_OAN,
+};
+
+static unsigned int lvds_oap_oan_mfp_funcs[] = {
+	S900_MUX_LVDS,
+	S900_MUX_ERAM,
+};
+
+/* mfp1_21 */
+static unsigned int lvds_e_mfp_pads[] = {
+	LVDS_EEP,
+	LVDS_EEN,
+	LVDS_EDP,
+	LVDS_EDN,
+	LVDS_ECP,
+	LVDS_ECN,
+	LVDS_EBP,
+	LVDS_EBN,
+	LVDS_EAP,
+	LVDS_EAN,
+};
+
+static unsigned int lvds_e_mfp_funcs[] = {
+	S900_MUX_LVDS,
+	S900_MUX_ERAM,
+};
+
+/* mfp1_5_4 */
+static unsigned int spi0_sclk_mosi_mfp_pads[] = {
+	SPI0_SCLK,
+	SPI0_MOSI,
+};
+
+static unsigned int spi0_sclk_mosi_mfp_funcs[] = {
+	S900_MUX_SPI0,
+	S900_MUX_ERAM,
+	S900_MUX_I2C3,
+	S900_MUX_PCM0,
+};
+
+/* mfp1_3_1 */
+static unsigned int spi0_ss_mfp_pads[] = {
+	SPI0_SS,
+};
+
+static unsigned int spi0_ss_mfp_funcs[] = {
+	S900_MUX_SPI0,
+	S900_MUX_ERAM,
+	S900_MUX_I2S1,
+	S900_MUX_PCM1,
+	S900_MUX_PCM0,
+	S900_MUX_PWM4,
+};
+
+static unsigned int spi0_miso_mfp_pads[] = {
+	SPI0_MISO,
+};
+
+static unsigned int spi0_miso_mfp_funcs[] = {
+	S900_MUX_SPI0,
+	S900_MUX_ERAM,
+	S900_MUX_I2S1,
+	S900_MUX_PCM1,
+	S900_MUX_PCM0,
+	S900_MUX_PWM5,
+};
+
+/* mfp2_23 */
+static unsigned int uart2_rtsb_mfp_pads[] = {
+	UART2_RTSB,
+};
+
+static unsigned int uart2_rtsb_mfp_funcs[] = {
+	S900_MUX_UART2,
+	S900_MUX_UART0,
+};
+
+/* mfp2_22 */
+static unsigned int uart2_ctsb_mfp_pads[] = {
+	UART2_CTSB,
+};
+
+static unsigned int uart2_ctsb_mfp_funcs[] = {
+	S900_MUX_UART2,
+	S900_MUX_UART0,
+};
+
+/* mfp2_21 */
+static unsigned int uart3_rtsb_mfp_pads[] = {
+	UART3_RTSB,
+};
+
+static unsigned int uart3_rtsb_mfp_funcs[] = {
+	S900_MUX_UART3,
+	S900_MUX_UART5,
+};
+
+/* mfp2_20 */
+static unsigned int uart3_ctsb_mfp_pads[] = {
+	UART3_CTSB,
+};
+
+static unsigned int uart3_ctsb_mfp_funcs[] = {
+	S900_MUX_UART3,
+	S900_MUX_UART5,
+};
+
+/* mfp2_19_17 */
+static unsigned int sd0_d0_mfp_pads[] = {
+	SD0_D0,
+};
+
+static unsigned int sd0_d0_mfp_funcs[] = {
+	S900_MUX_SD0,
+	S900_MUX_ERAM,
+	S900_MUX_RESERVED,
+	S900_MUX_JTAG,
+	S900_MUX_UART2,
+	S900_MUX_UART5,
+	S900_MUX_GPU,
+};
+
+/* mfp2_16_14 */
+static unsigned int sd0_d1_mfp_pads[] = {
+	SD0_D1,
+};
+
+static unsigned int sd0_d1_mfp_funcs[] = {
+	S900_MUX_SD0,
+	S900_MUX_ERAM,
+	S900_MUX_GPU,
+	S900_MUX_RESERVED,
+	S900_MUX_UART2,
+	S900_MUX_UART5,
+};
+
+/* mfp_13_11 */
+static unsigned int sd0_d2_d3_mfp_pads[] = {
+	SD0_D2,
+	SD0_D3,
+};
+
+static unsigned int sd0_d2_d3_mfp_funcs[] = {
+	S900_MUX_SD0,
+	S900_MUX_ERAM,
+	S900_MUX_RESERVED,
+	S900_MUX_JTAG,
+	S900_MUX_UART2,
+	S900_MUX_UART1,
+	S900_MUX_GPU,
+};
+
+/* mfp2_10_9 */
+static unsigned int sd1_d0_d3_mfp_pads[] = {
+	SD1_D0,
+	SD1_D1,
+	SD1_D2,
+	SD1_D3,
+};
+
+static unsigned int sd1_d0_d3_mfp_funcs[] = {
+	S900_MUX_SD1,
+	S900_MUX_ERAM,
+};
+
+/* mfp2_8_7 */
+static unsigned int sd0_cmd_mfp_pads[] = {
+	SD0_CMD,
+};
+
+static unsigned int sd0_cmd_mfp_funcs[] = {
+	S900_MUX_SD0,
+	S900_MUX_ERAM,
+	S900_MUX_GPU,
+	S900_MUX_JTAG,
+};
+
+/* mfp2_6_5 */
+static unsigned int sd0_clk_mfp_pads[] = {
+	SD0_CLK,
+};
+
+static unsigned int sd0_clk_mfp_funcs[] = {
+	S900_MUX_SD0,
+	S900_MUX_ERAM,
+	S900_MUX_JTAG,
+	S900_MUX_GPU,
+};
+
+/* mfp2_4_3 */
+static unsigned int sd1_cmd_clk_mfp_pads[] = {
+	SD1_CMD,
+	SD1_CLK,
+};
+
+static unsigned int sd1_cmd_clk_mfp_funcs[] = {
+	S900_MUX_SD1,
+	S900_MUX_ERAM,
+};
+
+/* mfp2_2_0 */
+static unsigned int uart0_rx_mfp_pads[] = {
+	UART0_RX,
+};
+
+static unsigned int uart0_rx_mfp_funcs[] = {
+	S900_MUX_UART0,
+	S900_MUX_UART2,
+	S900_MUX_SPI1,
+	S900_MUX_I2C5,
+	S900_MUX_PCM1,
+	S900_MUX_I2S1,
+};
+
+
+/* mfp3_27 */
+static unsigned int nand0_d0_ceb3_mfp_pads[] = {
+	NAND0_D0,
+	NAND0_D1,
+	NAND0_D2,
+	NAND0_D3,
+	NAND0_D4,
+	NAND0_D5,
+	NAND0_D6,
+	NAND0_D7,
+	NAND0_DQSN,
+	NAND0_CEB3,
+};
+
+static unsigned int nand0_d0_ceb3_mfp_funcs[] = {
+	S900_MUX_NAND0,
+	S900_MUX_SD2,
+};
+
+
+/* mfp3_21_19 */
+static unsigned int uart0_tx_mfp_pads[] = {
+	UART0_TX,
+};
+
+static unsigned int uart0_tx_mfp_funcs[] = {
+	S900_MUX_UART0,
+	S900_MUX_UART2,
+	S900_MUX_SPI1,
+	S900_MUX_I2C5,
+	S900_MUX_SPDIF,
+	S900_MUX_PCM1,
+	S900_MUX_I2S1,
+};
+
+/* mfp3_18_16 */
+static unsigned int i2c0_mfp_pads[] = {
+	I2C0_SCLK,
+	I2C0_SDATA,
+};
+
+static unsigned int i2c0_mfp_funcs[] = {
+	S900_MUX_I2C0,
+	S900_MUX_UART2,
+	S900_MUX_I2C1,
+	S900_MUX_UART1,
+	S900_MUX_SPI1,
+};
+
+/* mfp3_15 */
+static unsigned int csi0_cn_cp_mfp_pads[] = {
+	CSI0_CN,
+	CSI0_CP,
+};
+
+static unsigned int csi0_cn_cp_mfp_funcs[] = {
+	S900_MUX_SENS0,
+	S900_MUX_SENS0,
+};
+
+/* mfp3_14 */
+static unsigned int csi0_dn0_dp3_mfp_pads[] = {
+	CSI0_DN0,
+	CSI0_DP0,
+	CSI0_DN1,
+	CSI0_DP1,
+	CSI0_CN,
+	CSI0_CP,
+	CSI0_DP2,
+	CSI0_DN2,
+	CSI0_DN3,
+	CSI0_DP3,
+};
+
+static unsigned int csi0_dn0_dp3_mfp_funcs[] = {
+	S900_MUX_MIPI_CSI0,
+	S900_MUX_SENS0,
+};
+
+/* mfp3_13 */
+static unsigned int csi1_dn0_cp_mfp_pads[] = {
+	CSI1_DN0,
+	CSI1_DP0,
+	CSI1_DN1,
+	CSI1_DP1,
+	CSI1_CN,
+	CSI1_CP,
+};
+
+static unsigned int csi1_dn0_cp_mfp_funcs[] = {
+	S900_MUX_MIPI_CSI1,
+	S900_MUX_SENS0,
+};
+
+
+/* mfp3_12_dsi */
+static unsigned int dsi_dp3_dn1_mfp_pads[] = {
+	DSI_DP3,
+	DSI_DN2,
+	DSI_DP1,
+	DSI_DN1,
+};
+
+static unsigned int dsi_dp3_dn1_mfp_funcs[] = {
+	S900_MUX_MIPI_DSI,
+	S900_MUX_UART2,
+};
+
+static unsigned int dsi_cp_dn0_mfp_pads[] = {
+	DSI_CP,
+	DSI_CN,
+	DSI_DP0,
+	DSI_DN0,
+};
+
+static unsigned int dsi_cp_dn0_mfp_funcs[] = {
+	S900_MUX_MIPI_DSI,
+	S900_MUX_PCM1,
+};
+
+static unsigned int dsi_dp2_dn2_mfp_pads[] = {
+	DSI_DP2,
+	DSI_DN2,
+};
+
+static unsigned int dsi_dp2_dn2_mfp_funcs[] = {
+	S900_MUX_MIPI_DSI,
+	S900_MUX_UART4,
+};
+
+/* mfp3_11 */
+static unsigned int nand1_d0_ceb1_mfp_pads[] = {
+	NAND1_D0,
+	NAND1_D1,
+	NAND1_D2,
+	NAND1_D3,
+	NAND1_D4,
+	NAND1_D5,
+	NAND1_D6,
+	NAND1_D7,
+	NAND1_DQSN,
+	NAND1_CEB1,
+};
+
+static unsigned int nand1_d0_ceb1_mfp_funcs[] = {
+	S900_MUX_NAND1,
+	S900_MUX_SD3,
+};
+
+/* mfp3_10 */
+static unsigned int nand1_ceb3_mfp_pads[] = {
+	NAND1_CEB3,
+};
+
+static unsigned int nand1_ceb3_mfp_funcs[] = {
+	S900_MUX_NAND1,
+	S900_MUX_PWM0,
+};
+
+static unsigned int nand1_ceb0_mfp_pads[] = {
+	NAND1_CEB0,
+};
+
+static unsigned int nand1_ceb0_mfp_funcs[] = {
+	S900_MUX_NAND1,
+	S900_MUX_PWM1,
+};
+
+/* mfp3_9 */
+static unsigned int csi1_dn0_dp0_mfp_pads[] = {
+	CSI1_DN0,
+	CSI1_DP0,
+};
+
+static unsigned int csi1_dn0_dp0_mfp_funcs[] = {
+	S900_MUX_SENS0,
+	S900_MUX_SENS0,
+};
+
+/* mfp3_8 */
+static unsigned int uart4_rx_tx_mfp_pads[] = {
+	UART4_RX,
+	UART4_TX,
+};
+
+static unsigned int uart4_rx_tx_mfp_funcs[] = {
+	S900_MUX_UART4,
+	S900_MUX_I2C4,
+};
+
+
+/* PADDRV group data */
+
+/* drv0 */
+static unsigned int sgpio3_drv_pads[] = {
+	SGPIO3,
+};
+
+static unsigned int sgpio2_drv_pads[] = {
+	SGPIO2,
+};
+
+static unsigned int sgpio1_drv_pads[] = {
+	SGPIO1,
+};
+
+static unsigned int sgpio0_drv_pads[] = {
+	SGPIO0,
+};
+
+static unsigned int rmii_tx_d0_d1_drv_pads[] = {
+	ETH_TXD0,
+	ETH_TXD1,
+};
+
+static unsigned int rmii_txen_rxer_drv_pads[] = {
+	ETH_TXEN,
+	ETH_RXER,
+};
+
+static unsigned int rmii_crs_dv_drv_pads[] = {
+	ETH_CRS_DV,
+};
+
+static unsigned int rmii_rx_d1_d0_drv_pads[] = {
+	ETH_RXD1,
+	ETH_RXD0,
+};
+
+static unsigned int rmii_ref_clk_drv_pads[] = {
+	ETH_REF_CLK,
+};
+
+static unsigned int rmii_mdc_mdio_drv_pads[] = {
+	ETH_MDC,
+	ETH_MDIO,
+};
+
+static unsigned int sirq_0_1_drv_pads[] = {
+	SIRQ0,
+	SIRQ1,
+};
+
+static unsigned int sirq2_drv_pads[] = {
+	SIRQ2,
+};
+
+static unsigned int i2s_d0_d1_drv_pads[] = {
+	I2S_D0,
+	I2S_D1,
+};
+
+static unsigned int i2s_lr_m_clk0_drv_pads[] = {
+	I2S_LRCLK0,
+	I2S_MCLK0,
+};
+
+static unsigned int i2s_blk1_mclk1_drv_pads[] = {
+	I2S_BCLK0,
+	I2S_BCLK1,
+	I2S_LRCLK1,
+	I2S_MCLK1,
+};
+
+static unsigned int pcm1_in_out_drv_pads[] = {
+	PCM1_IN,
+	PCM1_CLK,
+	PCM1_SYNC,
+	PCM1_OUT,
+};
+
+/* drv1 */
+static unsigned int lvds_oap_oan_drv_pads[] = {
+	LVDS_OAP,
+	LVDS_OAN,
+};
+
+static unsigned int lvds_oep_odn_drv_pads[] = {
+	LVDS_OEP,
+	LVDS_OEN,
+	LVDS_ODP,
+	LVDS_ODN,
+};
+
+static unsigned int lvds_ocp_obn_drv_pads[] = {
+	LVDS_OCP,
+	LVDS_OCN,
+	LVDS_OBP,
+	LVDS_OBN,
+};
+
+static unsigned int lvds_e_drv_pads[] = {
+	LVDS_EEP,
+	LVDS_EEN,
+	LVDS_EDP,
+	LVDS_EDN,
+	LVDS_ECP,
+	LVDS_ECN,
+	LVDS_EBP,
+	LVDS_EBN,
+};
+
+static unsigned int sd0_d3_d0_drv_pads[] = {
+	SD0_D3,
+	SD0_D2,
+	SD0_D1,
+	SD0_D0,
+};
+static unsigned int sd1_d3_d0_drv_pads[] = {
+	SD1_D3,
+	SD1_D2,
+	SD1_D1,
+	SD1_D0,
+};
+
+static unsigned int sd0_sd1_cmd_clk_drv_pads[] = {
+	SD0_CLK,
+	SD0_CMD,
+	SD1_CLK,
+	SD1_CMD,
+};
+
+static unsigned int spi0_sclk_mosi_drv_pads[] = {
+	SPI0_SCLK,
+	SPI0_MOSI,
+};
+
+static unsigned int spi0_ss_miso_drv_pads[] = {
+	SPI0_SS,
+	SPI0_MISO,
+};
+
+static unsigned int uart0_rx_tx_drv_pads[] = {
+	UART0_RX,
+	UART0_TX,
+};
+
+static unsigned int uart4_rx_tx_drv_pads[] = {
+	UART4_RX,
+	UART4_TX,
+};
+
+static unsigned int uart2_drv_pads[] = {
+	UART2_RX,
+	UART2_TX,
+	UART2_RTSB,
+	UART2_CTSB,
+};
+
+static unsigned int uart3_drv_pads[] = {
+	UART3_RX,
+	UART3_TX,
+	UART3_RTSB,
+	UART3_CTSB,
+};
+
+/* drv2 */
+static unsigned int i2c0_drv_pads[] = {
+	I2C0_SCLK,
+	I2C0_SDATA,
+};
+
+static unsigned int i2c1_drv_pads[] = {
+	I2C1_SCLK,
+	I2C1_SDATA,
+};
+
+static unsigned int i2c2_drv_pads[] = {
+	I2C2_SCLK,
+	I2C2_SDATA,
+};
+
+static unsigned int sensor0_drv_pads[] = {
+	SENSOR0_PCLK,
+	SENSOR0_CKOUT,
+};
+
+/* SR group data */
+
+/* sr0 */
+static unsigned int sgpio3_sr_pads[] = {
+	SGPIO3,
+};
+
+static unsigned int sgpio2_sr_pads[] = {
+	SGPIO2,
+};
+
+static unsigned int sgpio1_sr_pads[] = {
+	SGPIO1,
+};
+
+static unsigned int sgpio0_sr_pads[] = {
+	SGPIO0,
+};
+
+static unsigned int rmii_tx_d0_d1_sr_pads[] = {
+	ETH_TXD0,
+	ETH_TXD1,
+};
+
+static unsigned int rmii_txen_rxer_sr_pads[] = {
+	ETH_TXEN,
+	ETH_RXER,
+};
+
+static unsigned int rmii_crs_dv_sr_pads[] = {
+	ETH_CRS_DV,
+};
+
+static unsigned int rmii_rx_d1_d0_sr_pads[] = {
+	ETH_RXD1,
+	ETH_RXD0,
+};
+
+static unsigned int rmii_ref_clk_sr_pads[] = {
+	ETH_REF_CLK,
+};
+
+static unsigned int rmii_mdc_mdio_sr_pads[] = {
+	ETH_MDC,
+	ETH_MDIO,
+};
+
+static unsigned int sirq_0_1_sr_pads[] = {
+	SIRQ0,
+	SIRQ1,
+};
+
+static unsigned int sirq2_sr_pads[] = {
+	SIRQ2,
+};
+
+static unsigned int i2s_do_d1_sr_pads[] = {
+	I2S_D0,
+	I2S_D1,
+};
+
+static unsigned int i2s_lr_m_clk0_sr_pads[] = {
+	I2S_LRCLK0,
+	I2S_MCLK0,
+};
+
+static unsigned int i2s_bclk0_mclk1_sr_pads[] = {
+	I2S_BCLK0,
+	I2S_BCLK1,
+	I2S_LRCLK1,
+	I2S_MCLK1,
+};
+
+static unsigned int pcm1_in_out_sr_pads[] = {
+	PCM1_IN,
+	PCM1_CLK,
+	PCM1_SYNC,
+	PCM1_OUT,
+};
+
+/* sr1 */
+static unsigned int sd1_d3_d0_sr_pads[] = {
+	SD1_D3,
+	SD1_D2,
+	SD1_D1,
+	SD1_D0,
+};
+
+static unsigned int sd0_sd1_clk_cmd_sr_pads[] = {
+	SD0_CLK,
+	SD0_CMD,
+	SD1_CLK,
+	SD1_CMD,
+};
+
+static unsigned int spi0_sclk_mosi_sr_pads[] = {
+	SPI0_SCLK,
+	SPI0_MOSI,
+};
+
+static unsigned int spi0_ss_miso_sr_pads[] = {
+	SPI0_SS,
+	SPI0_MISO,
+};
+
+static unsigned int uart0_rx_tx_sr_pads[] = {
+	UART0_RX,
+	UART0_TX,
+};
+
+static unsigned int uart4_rx_tx_sr_pads[] = {
+	UART4_RX,
+	UART4_TX,
+};
+
+static unsigned int uart2_sr_pads[] = {
+	UART2_RX,
+	UART2_TX,
+	UART2_RTSB,
+	UART2_CTSB,
+};
+
+static unsigned int uart3_sr_pads[] = {
+	UART3_RX,
+	UART3_TX,
+	UART3_RTSB,
+	UART3_CTSB,
+};
+
+/* sr2 */
+static unsigned int i2c0_sr_pads[] = {
+	I2C0_SCLK,
+	I2C0_SDATA,
+};
+
+static unsigned int i2c1_sr_pads[] = {
+	I2C1_SCLK,
+	I2C1_SDATA,
+};
+
+static unsigned int i2c2_sr_pads[] = {
+	I2C2_SCLK,
+	I2C2_SDATA,
+};
+
+static unsigned int sensor0_sr_pads[] = {
+	SENSOR0_PCLK,
+	SENSOR0_CKOUT,
+};
+
+#define MUX_PG(group_name, reg, shift, width)				\
+	{								\
+		.name = #group_name,					\
+		.pads = group_name##_pads,				\
+		.npads = ARRAY_SIZE(group_name##_pads),			\
+		.funcs = group_name##_funcs,				\
+		.nfuncs = ARRAY_SIZE(group_name##_funcs),		\
+		.mfpctl_reg  = MFCTL##reg,				\
+		.mfpctl_shift = shift,					\
+		.mfpctl_width = width,					\
+		.drv_reg = -1,						\
+		.drv_shift = -1,					\
+		.drv_width = -1,					\
+		.sr_reg = -1,						\
+		.sr_shift = -1,						\
+		.sr_width = -1,						\
+	}
+
+#define DRV_PG(group_name, reg, shift, width)				\
+	{								\
+		.name = #group_name,					\
+		.pads = group_name##_pads,				\
+		.npads = ARRAY_SIZE(group_name##_pads),			\
+		.mfpctl_reg  = -1,					\
+		.mfpctl_shift = -1,					\
+		.mfpctl_width = -1,					\
+		.drv_reg = PAD_DRV##reg,				\
+		.drv_shift = shift,					\
+		.drv_width = width,					\
+		.sr_reg = -1,						\
+		.sr_shift = -1,						\
+		.sr_width = -1,						\
+	}
+
+#define SR_PG(group_name, reg, shift, width)				\
+	{								\
+		.name = #group_name,					\
+		.pads = group_name##_pads,				\
+		.npads = ARRAY_SIZE(group_name##_pads),			\
+		.mfpctl_reg  = -1,					\
+		.mfpctl_shift = -1,					\
+		.mfpctl_width = -1,					\
+		.drv_reg = -1,						\
+		.drv_shift = -1,					\
+		.drv_width = -1,					\
+		.sr_reg = PAD_SR##reg,					\
+		.sr_shift = shift,					\
+		.sr_width = width,					\
+	}
+
+/* Pinctrl groups */
+static const struct owl_pingroup s900_groups[] = {
+	MUX_PG(lvds_oxx_uart4_mfp, 0, 22, 1),
+	MUX_PG(rmii_mdc_mfp, 0, 20, 2),
+	MUX_PG(rmii_mdio_mfp, 0, 20, 2),
+	MUX_PG(sirq0_mfp, 0, 19, 1),
+	MUX_PG(sirq1_mfp, 0, 19, 1),
+	MUX_PG(rmii_txd0_mfp, 0, 16, 3),
+	MUX_PG(rmii_txd1_mfp, 0, 16, 3),
+	MUX_PG(rmii_txen_mfp, 0, 13, 3),
+	MUX_PG(rmii_rxer_mfp, 0, 13, 3),
+	MUX_PG(rmii_crs_dv_mfp, 0, 11, 2),
+	MUX_PG(rmii_rxd1_mfp, 0, 8, 3),
+	MUX_PG(rmii_rxd0_mfp, 0, 8, 3),
+	MUX_PG(rmii_ref_clk_mfp, 0, 6, 2),
+	MUX_PG(i2s_d0_mfp, 0, 5, 1),
+	MUX_PG(i2s_d1_mfp, 0, 5, 1),
+	MUX_PG(i2s_lr_m_clk0_mfp, 0, 3, 2),
+	MUX_PG(i2s_bclk0_mfp, 0, 2, 1),
+	MUX_PG(i2s_bclk1_mclk1_mfp, 0, 2, 1),
+	MUX_PG(pcm1_in_out_mfp, 0, 0, 2),
+	MUX_PG(pcm1_clk_mfp, 0, 0, 2),
+	MUX_PG(pcm1_sync_mfp, 0, 0, 2),
+	MUX_PG(eram_a5_mfp, 1, 29, 3),
+	MUX_PG(eram_a6_mfp, 1, 29, 3),
+	MUX_PG(eram_a7_mfp, 1, 29, 3),
+	MUX_PG(eram_a8_mfp, 1, 26, 3),
+	MUX_PG(eram_a9_mfp, 1, 26, 3),
+	MUX_PG(eram_a10_mfp, 1, 26, 3),
+	MUX_PG(eram_a11_mfp, 1, 23, 3),
+	MUX_PG(lvds_oep_odn_mfp, 1, 22, 1),
+	MUX_PG(lvds_ocp_obn_mfp, 1, 22, 1),
+	MUX_PG(lvds_oap_oan_mfp, 1, 22, 1),
+	MUX_PG(lvds_e_mfp, 1, 21, 1),
+	MUX_PG(spi0_sclk_mosi_mfp, 1, 4, 2),
+	MUX_PG(spi0_ss_mfp, 1, 1, 3),
+	MUX_PG(spi0_miso_mfp, 1, 1, 3),
+	MUX_PG(uart2_rtsb_mfp, 2, 23, 1),
+	MUX_PG(uart2_ctsb_mfp, 2, 22, 1),
+	MUX_PG(uart3_rtsb_mfp, 2, 21, 1),
+	MUX_PG(uart3_ctsb_mfp, 2, 20, 1),
+	MUX_PG(sd0_d0_mfp, 2, 17, 3),
+	MUX_PG(sd0_d1_mfp, 2, 14, 3),
+	MUX_PG(sd0_d2_d3_mfp, 2, 11, 3),
+	MUX_PG(sd1_d0_d3_mfp, 2, 9, 2),
+	MUX_PG(sd0_cmd_mfp, 2, 7, 2),
+	MUX_PG(sd0_clk_mfp, 2, 5, 2),
+	MUX_PG(sd1_cmd_clk_mfp, 2, 3, 2),
+	MUX_PG(uart0_rx_mfp, 2, 0, 3),
+	MUX_PG(nand0_d0_ceb3_mfp, 3, 27, 1),
+	MUX_PG(uart0_tx_mfp, 3, 19, 3),
+	MUX_PG(i2c0_mfp, 3, 16, 3),
+	MUX_PG(csi0_cn_cp_mfp, 3, 15, 1),
+	MUX_PG(csi0_dn0_dp3_mfp, 3, 14, 1),
+	MUX_PG(csi1_dn0_cp_mfp, 3, 13, 1),
+	MUX_PG(dsi_dp3_dn1_mfp, 3, 12, 1),
+	MUX_PG(dsi_cp_dn0_mfp, 3, 12, 1),
+	MUX_PG(dsi_dp2_dn2_mfp, 3, 12, 1),
+	MUX_PG(nand1_d0_ceb1_mfp, 3, 11, 1),
+	MUX_PG(nand1_ceb3_mfp, 3, 10, 1),
+	MUX_PG(nand1_ceb0_mfp, 3, 10, 1),
+	MUX_PG(csi1_dn0_dp0_mfp, 3, 9, 1),
+	MUX_PG(uart4_rx_tx_mfp, 3, 8, 1),
+
+	DRV_PG(sgpio3_drv, 0, 30, 2),
+	DRV_PG(sgpio2_drv, 0, 28, 2),
+	DRV_PG(sgpio1_drv, 0, 26, 2),
+	DRV_PG(sgpio0_drv, 0, 24, 2),
+	DRV_PG(rmii_tx_d0_d1_drv, 0, 22, 2),
+	DRV_PG(rmii_txen_rxer_drv, 0, 20, 2),
+	DRV_PG(rmii_crs_dv_drv, 0, 18, 2),
+	DRV_PG(rmii_rx_d1_d0_drv, 0, 16, 2),
+	DRV_PG(rmii_ref_clk_drv, 0, 14, 2),
+	DRV_PG(rmii_mdc_mdio_drv, 0, 12, 2),
+	DRV_PG(sirq_0_1_drv, 0, 10, 2),
+	DRV_PG(sirq2_drv, 0, 8, 2),
+	DRV_PG(i2s_d0_d1_drv, 0, 6, 2),
+	DRV_PG(i2s_lr_m_clk0_drv, 0, 4, 2),
+	DRV_PG(i2s_blk1_mclk1_drv, 0, 2, 2),
+	DRV_PG(pcm1_in_out_drv, 0, 0, 2),
+	DRV_PG(lvds_oap_oan_drv, 1, 28, 2),
+	DRV_PG(lvds_oep_odn_drv, 1, 26, 2),
+	DRV_PG(lvds_ocp_obn_drv, 1, 24, 2),
+	DRV_PG(lvds_e_drv, 1, 22, 2),
+	DRV_PG(sd0_d3_d0_drv, 1, 20, 2),
+	DRV_PG(sd1_d3_d0_drv, 1, 18, 2),
+	DRV_PG(sd0_sd1_cmd_clk_drv, 1, 16, 2),
+	DRV_PG(spi0_sclk_mosi_drv, 1, 14, 2),
+	DRV_PG(spi0_ss_miso_drv, 1, 12, 2),
+	DRV_PG(uart0_rx_tx_drv, 1, 10, 2),
+	DRV_PG(uart4_rx_tx_drv, 1, 8, 2),
+	DRV_PG(uart2_drv, 1, 6, 2),
+	DRV_PG(uart3_drv, 1, 4, 2),
+	DRV_PG(i2c0_drv, 2, 30, 2),
+	DRV_PG(i2c1_drv, 2, 28, 2),
+	DRV_PG(i2c2_drv, 2, 26, 2),
+	DRV_PG(sensor0_drv, 2, 20, 2),
+
+	SR_PG(sgpio3_sr, 0, 15, 1),
+	SR_PG(sgpio2_sr, 0, 14, 1),
+	SR_PG(sgpio1_sr, 0, 13, 1),
+	SR_PG(sgpio0_sr, 0, 12, 1),
+	SR_PG(rmii_tx_d0_d1_sr, 0, 11, 1),
+	SR_PG(rmii_txen_rxer_sr, 0, 10, 1),
+	SR_PG(rmii_crs_dv_sr, 0, 9, 1),
+	SR_PG(rmii_rx_d1_d0_sr, 0, 8, 1),
+	SR_PG(rmii_ref_clk_sr, 0, 7, 1),
+	SR_PG(rmii_mdc_mdio_sr, 0, 6, 1),
+	SR_PG(sirq_0_1_sr, 0, 5, 1),
+	SR_PG(sirq2_sr, 0, 4, 1),
+	SR_PG(i2s_do_d1_sr, 0, 3, 1),
+	SR_PG(i2s_lr_m_clk0_sr, 0, 2, 1),
+	SR_PG(i2s_bclk0_mclk1_sr, 0, 1, 1),
+	SR_PG(pcm1_in_out_sr, 0, 0, 1),
+	SR_PG(sd1_d3_d0_sr, 1, 25, 1),
+	SR_PG(sd0_sd1_clk_cmd_sr, 1, 24, 1),
+	SR_PG(spi0_sclk_mosi_sr, 1, 23, 1),
+	SR_PG(spi0_ss_miso_sr, 1, 22, 1),
+	SR_PG(uart0_rx_tx_sr, 1, 21, 1),
+	SR_PG(uart4_rx_tx_sr, 1, 20, 1),
+	SR_PG(uart2_sr, 1, 19, 1),
+	SR_PG(uart3_sr, 1, 18, 1),
+	SR_PG(i2c0_sr, 2, 31, 1),
+	SR_PG(i2c1_sr, 2, 30, 1),
+	SR_PG(i2c2_sr, 2, 29, 1),
+	SR_PG(sensor0_sr, 2, 25, 1)
+};
+
+static const char * const eram_groups[] = {
+	"lvds_oxx_uart4_mfp",
+	"eram_a5_mfp",
+	"eram_a6_mfp",
+	"eram_a7_mfp",
+	"eram_a8_mfp",
+	"eram_a9_mfp",
+	"eram_a10_mfp",
+	"eram_a11_mfp",
+	"lvds_oap_oan_mfp",
+	"lvds_e_mfp",
+	"spi0_sclk_mosi_mfp",
+	"spi0_ss_mfp",
+	"spi0_miso_mfp",
+	"sd0_d0_mfp",
+	"sd0_d1_mfp",
+	"sd0_d2_d3_mfp",
+	"sd1_d0_d3_mfp",
+	"sd0_cmd_mfp",
+	"sd0_clk_mfp",
+	"sd1_cmd_clk_mfp",
+};
+
+static const char * const eth_rmii_groups[] = {
+	"rmii_mdc_mfp",
+	"rmii_mdio_mfp",
+	"rmii_txd0_mfp",
+	"rmii_txd1_mfp",
+	"rmii_txen_mfp",
+	"rmii_rxer_mfp",
+	"rmii_crs_dv_mfp",
+	"rmii_rxd1_mfp",
+	"rmii_rxd0_mfp",
+	"rmii_ref_clk_mfp",
+	"eth_smi_dummy",
+};
+
+static const char * const eth_smii_groups[] = {
+	"rmii_txd0_mfp",
+	"rmii_txd1_mfp",
+	"rmii_crs_dv_mfp",
+	"eth_smi_dummy",
+};
+
+static const char * const spi0_groups[] = {
+	"spi0_sclk_mosi_mfp",
+	"spi0_ss_mfp",
+	"spi0_miso_mfp",
+	"spi0_sclk_mosi_mfp",
+	"spi0_ss_mfp",
+	"spi0_miso_mfp",
+};
+
+static const char * const spi1_groups[] = {
+	"pcm1_in_out_mfp",
+	"pcm1_clk_mfp",
+	"pcm1_sync_mfp",
+	"uart0_rx_mfp",
+	"uart0_tx_mfp",
+	"i2c0_mfp",
+};
+
+static const char * const spi2_groups[] = {
+	"rmii_txd0_mfp",
+	"rmii_txd1_mfp",
+	"rmii_crs_dv_mfp",
+	"rmii_ref_clk_mfp",
+};
+
+static const char * const spi3_groups[] = {
+	"rmii_txen_mfp",
+	"rmii_rxer_mfp",
+};
+
+static const char * const sens0_groups[] = {
+	"rmii_txd0_mfp",
+	"rmii_txd1_mfp",
+	"rmii_txen_mfp",
+	"rmii_rxer_mfp",
+	"rmii_rxd1_mfp",
+	"rmii_rxd0_mfp",
+	"eram_a5_mfp",
+	"eram_a6_mfp",
+	"eram_a7_mfp",
+	"eram_a8_mfp",
+	"eram_a9_mfp",
+	"csi0_cn_cp_mfp",
+	"csi0_dn0_dp3_mfp",
+	"csi1_dn0_cp_mfp",
+	"csi1_dn0_dp0_mfp",
+};
+
+static const char * const uart0_groups[] = {
+	"uart2_rtsb_mfp",
+	"uart2_ctsb_mfp",
+	"uart0_rx_mfp",
+	"uart0_tx_mfp",
+};
+
+static const char * const uart1_groups[] = {
+	"sd0_d2_d3_mfp",
+	"i2c0_mfp",
+};
+
+static const char * const uart2_groups[] = {
+	"rmii_mdc_mfp",
+	"rmii_mdio_mfp",
+	"rmii_txen_mfp",
+	"rmii_rxer_mfp",
+	"rmii_rxd1_mfp",
+	"rmii_rxd0_mfp",
+	"lvds_oep_odn_mfp",
+	"uart2_rtsb_mfp",
+	"uart2_ctsb_mfp",
+	"sd0_d0_mfp",
+	"sd0_d1_mfp",
+	"sd0_d2_d3_mfp",
+	"uart0_rx_mfp",
+	"uart0_tx_mfp_pads",
+	"i2c0_mfp_pads",
+	"dsi_dp3_dn1_mfp",
+	"uart2_dummy"
+};
+
+static const char * const uart3_groups[] = {
+	"uart3_rtsb_mfp",
+	"uart3_ctsb_mfp",
+	"uart3_dummy"
+};
+
+static const char * const uart4_groups[] = {
+	"lvds_oxx_uart4_mfp",
+	"rmii_crs_dv_mfp",
+	"rmii_ref_clk_mfp",
+	"pcm1_in_out_mfp",
+	"pcm1_clk_mfp",
+	"pcm1_sync_mfp",
+	"eram_a5_mfp",
+	"eram_a6_mfp",
+	"dsi_dp2_dn2_mfp",
+	"uart4_rx_tx_mfp_pads",
+	"uart4_dummy"
+};
+
+static const char * const uart5_groups[] = {
+	"rmii_rxd1_mfp",
+	"rmii_rxd0_mfp",
+	"eram_a9_mfp",
+	"eram_a11_mfp",
+	"uart3_rtsb_mfp",
+	"uart3_ctsb_mfp",
+	"sd0_d0_mfp",
+	"sd0_d1_mfp",
+};
+
+static const char * const uart6_groups[] = {
+	"rmii_txd0_mfp",
+	"rmii_txd1_mfp",
+};
+
+static const char * const i2s0_groups[] = {
+	"i2s_d0_mfp",
+	"i2s_lr_m_clk0_mfp",
+	"i2s_bclk0_mfp",
+	"i2s0_dummy",
+};
+
+static const char * const i2s1_groups[] = {
+	"i2s_d1_mfp",
+	"i2s_bclk1_mclk1_mfp",
+	"spi0_ss_mfp",
+	"spi0_miso_mfp",
+	"uart0_rx_mfp",
+	"uart0_tx_mfp",
+	"i2s1_dummy",
+};
+
+static const char * const pcm0_groups[] = {
+	"i2s_d0_mfp",
+	"i2s_d1_mfp",
+	"i2s_lr_m_clk0_mfp",
+	"i2s_bclk0_mfp",
+	"i2s_bclk1_mclk1_mfp",
+	"spi0_sclk_mosi_mfp",
+	"spi0_ss_mfp",
+	"spi0_miso_mfp",
+};
+
+static const char * const pcm1_groups[] = {
+	"i2s_lr_m_clk0_mfp",
+	"pcm1_in_out_mfp",
+	"pcm1_clk_mfp",
+	"pcm1_sync_mfp",
+	"lvds_oep_odn_mfp",
+	"spi0_ss_mfp",
+	"spi0_miso_mfp",
+	"uart0_rx_mfp",
+	"uart0_tx_mfp",
+	"dsi_cp_dn0_mfp",
+	"pcm1_dummy",
+};
+
+static const char * const jtag_groups[] = {
+	"eram_a5_mfp",
+	"eram_a6_mfp",
+	"eram_a7_mfp",
+	"eram_a8_mfp",
+	"eram_a10_mfp",
+	"eram_a10_mfp",
+	"sd0_d2_d3_mfp",
+	"sd0_cmd_mfp",
+	"sd0_clk_mfp",
+};
+
+static const char * const pwm0_groups[] = {
+	"sirq0_mfp",
+	"rmii_txd0_mfp",
+	"rmii_rxd1_mfp",
+	"eram_a5_mfp",
+	"nand1_ceb3_mfp",
+};
+
+static const char * const pwm1_groups[] = {
+	"sirq1_mfp",
+	"rmii_txd1_mfp",
+	"rmii_rxd0_mfp",
+	"eram_a6_mfp",
+	"eram_a8_mfp",
+	"nand1_ceb0_mfp",
+};
+
+static const char * const pwm2_groups[] = {
+	"rmii_mdc_mfp",
+	"rmii_txen_mfp",
+	"eram_a9_mfp",
+	"eram_a11_mfp",
+};
+
+static const char * const pwm3_groups[] = {
+	"rmii_mdio_mfp",
+	"rmii_rxer_mfp",
+	"eram_a10_mfp",
+};
+
+static const char * const pwm4_groups[] = {
+	"pcm1_clk_mfp",
+	"spi0_ss_mfp",
+};
+
+static const char * const pwm5_groups[] = {
+	"pcm1_sync_mfp",
+	"spi0_miso_mfp",
+};
+
+static const char * const sd0_groups[] = {
+	"sd0_d0_mfp",
+	"sd0_d1_mfp",
+	"sd0_d2_d3_mfp",
+	"sd0_cmd_mfp",
+	"sd0_clk_mfp",
+};
+
+static const char * const sd1_groups[] = {
+	"sd1_d0_d3_mfp",
+	"sd1_cmd_clk_mfp",
+	"sd1_dummy",
+};
+
+static const char * const sd2_groups[] = {
+	"nand0_d0_ceb3_mfp",
+};
+
+static const char * const sd3_groups[] = {
+	"nand1_d0_ceb1_mfp",
+};
+
+static const char * const i2c0_groups[] = {
+	"i2c0_mfp",
+};
+
+static const char * const i2c1_groups[] = {
+	"i2c0_mfp",
+	"i2c1_dummy"
+};
+
+static const char * const i2c2_groups[] = {
+	"i2c2_dummy"
+};
+
+static const char * const i2c3_groups[] = {
+	"pcm1_in_out_mfp",
+	"spi0_sclk_mosi_mfp",
+};
+
+static const char * const i2c4_groups[] = {
+	"uart4_rx_tx_mfp",
+};
+
+static const char * const i2c5_groups[] = {
+	"uart0_rx_mfp",
+	"uart0_tx_mfp",
+};
+
+
+static const char * const lvds_groups[] = {
+	"lvds_oep_odn_mfp",
+	"lvds_ocp_obn_mfp",
+	"lvds_oap_oan_mfp",
+	"lvds_e_mfp",
+};
+
+static const char * const usb20_groups[] = {
+	"eram_a9_mfp",
+};
+
+static const char * const usb30_groups[] = {
+	"eram_a10_mfp",
+};
+
+static const char * const gpu_groups[] = {
+	"sd0_d0_mfp",
+	"sd0_d1_mfp",
+	"sd0_d2_d3_mfp",
+	"sd0_cmd_mfp",
+	"sd0_clk_mfp",
+};
+
+static const char * const mipi_csi0_groups[] = {
+	"csi0_dn0_dp3_mfp",
+};
+
+static const char * const mipi_csi1_groups[] = {
+	"csi1_dn0_cp_mfp",
+};
+
+static const char * const mipi_dsi_groups[] = {
+	"dsi_dp3_dn1_mfp",
+	"dsi_cp_dn0_mfp",
+	"dsi_dp2_dn2_mfp",
+	"mipi_dsi_dummy",
+};
+
+static const char * const nand0_groups[] = {
+	"nand0_d0_ceb3_mfp",
+	"nand0_dummy",
+};
+
+static const char * const nand1_groups[] = {
+	"nand1_d0_ceb1_mfp",
+	"nand1_ceb3_mfp",
+	"nand1_ceb0_mfp",
+	"nand1_dummy",
+};
+
+static const char * const spdif_groups[] = {
+	"uart0_tx_mfp",
+};
+
+static const char * const sirq0_groups[] = {
+	"sirq0_mfp",
+	"sirq0_dummy",
+};
+
+static const char * const sirq1_groups[] = {
+	"sirq1_mfp",
+	"sirq1_dummy",
+};
+
+static const char * const sirq2_groups[] = {
+	"sirq2_dummy",
+};
+
+#define FUNCTION(fname)					\
+	{						\
+		.name = #fname,				\
+		.groups = fname##_groups,		\
+		.ngroups = ARRAY_SIZE(fname##_groups),	\
+	}
+
+const struct owl_pinmux_func s900_functions[] = {
+	[S900_MUX_ERAM] = FUNCTION(eram),
+	[S900_MUX_ETH_RMII] = FUNCTION(eth_rmii),
+	[S900_MUX_ETH_SMII] = FUNCTION(eth_smii),
+	[S900_MUX_SPI0] = FUNCTION(spi0),
+	[S900_MUX_SPI1] = FUNCTION(spi1),
+	[S900_MUX_SPI2] = FUNCTION(spi2),
+	[S900_MUX_SPI3] = FUNCTION(spi3),
+	[S900_MUX_SENS0] = FUNCTION(sens0),
+	[S900_MUX_UART0] = FUNCTION(uart0),
+	[S900_MUX_UART1] = FUNCTION(uart1),
+	[S900_MUX_UART2] = FUNCTION(uart2),
+	[S900_MUX_UART3] = FUNCTION(uart3),
+	[S900_MUX_UART4] = FUNCTION(uart4),
+	[S900_MUX_UART5] = FUNCTION(uart5),
+	[S900_MUX_UART6] = FUNCTION(uart6),
+	[S900_MUX_I2S0] = FUNCTION(i2s0),
+	[S900_MUX_I2S1] = FUNCTION(i2s1),
+	[S900_MUX_PCM0] = FUNCTION(pcm0),
+	[S900_MUX_PCM1] = FUNCTION(pcm1),
+	[S900_MUX_JTAG] = FUNCTION(jtag),
+	[S900_MUX_PWM0] = FUNCTION(pwm0),
+	[S900_MUX_PWM1] = FUNCTION(pwm1),
+	[S900_MUX_PWM2] = FUNCTION(pwm2),
+	[S900_MUX_PWM3] = FUNCTION(pwm3),
+	[S900_MUX_PWM4] = FUNCTION(pwm4),
+	[S900_MUX_PWM5] = FUNCTION(pwm5),
+	[S900_MUX_SD0] = FUNCTION(sd0),
+	[S900_MUX_SD1] = FUNCTION(sd1),
+	[S900_MUX_SD2] = FUNCTION(sd2),
+	[S900_MUX_SD3] = FUNCTION(sd3),
+	[S900_MUX_I2C0] = FUNCTION(i2c0),
+	[S900_MUX_I2C1] = FUNCTION(i2c1),
+	[S900_MUX_I2C2] = FUNCTION(i2c2),
+	[S900_MUX_I2C3] = FUNCTION(i2c3),
+	[S900_MUX_I2C4] = FUNCTION(i2c4),
+	[S900_MUX_I2C5] = FUNCTION(i2c5),
+	[S900_MUX_LVDS] = FUNCTION(lvds),
+	[S900_MUX_USB30] = FUNCTION(usb30),
+	[S900_MUX_USB20] = FUNCTION(usb20),
+	[S900_MUX_GPU] = FUNCTION(gpu),
+	[S900_MUX_MIPI_CSI0] = FUNCTION(mipi_csi0),
+	[S900_MUX_MIPI_CSI1] = FUNCTION(mipi_csi1),
+	[S900_MUX_MIPI_DSI] = FUNCTION(mipi_dsi),
+	[S900_MUX_NAND0] = FUNCTION(nand0),
+	[S900_MUX_NAND1] = FUNCTION(nand1),
+	[S900_MUX_SPDIF] = FUNCTION(spdif),
+	[S900_MUX_SIRQ0] = FUNCTION(sirq0),
+	[S900_MUX_SIRQ1] = FUNCTION(sirq1),
+	[S900_MUX_SIRQ2] = FUNCTION(sirq2)
+};
+/* PAD PULL UP/DOWN CONFIGURES */
+#define PULLCTL_CONF(pull_reg, pull_sft, pull_wdt)			\
+	{								\
+		.reg = PAD_PULLCTL##pull_reg,				\
+		.shift = pull_sft,					\
+		.width = pull_wdt,					\
+	}
+
+#define PAD_PULLCTL_CONF(pad_name, pull_reg, pull_sft, pull_wdt)	\
+	struct owl_pullctl pad_name##_pullctl_conf			\
+		= PULLCTL_CONF(pull_reg, pull_sft, pull_wdt)
+
+#define ST_CONF(st_reg, st_sft, st_wdt)					\
+	{								\
+		.reg = PAD_ST##st_reg,					\
+		.shift = st_sft,					\
+		.width = st_wdt,					\
+	}
+
+#define PAD_ST_CONF(pad_name, st_reg, st_sft, st_wdt)			\
+	struct owl_st pad_name##_st_conf				\
+		= ST_CONF(st_reg, st_sft, st_wdt)
+
+/* PAD_PULLCTL0 */
+static PAD_PULLCTL_CONF(ETH_RXER, 0, 18, 2);
+static PAD_PULLCTL_CONF(SIRQ0, 0, 16, 2);
+static PAD_PULLCTL_CONF(SIRQ1, 0, 14, 2);
+static PAD_PULLCTL_CONF(SIRQ2, 0, 12, 2);
+static PAD_PULLCTL_CONF(I2C0_SDATA, 0, 10, 2);
+static PAD_PULLCTL_CONF(I2C0_SCLK, 0, 8, 2);
+static PAD_PULLCTL_CONF(ERAM_A5, 0, 6, 2);
+static PAD_PULLCTL_CONF(ERAM_A6, 0, 4, 2);
+static PAD_PULLCTL_CONF(ERAM_A7, 0, 2, 2);
+static PAD_PULLCTL_CONF(ERAM_A10, 0, 0, 2);
+
+/* PAD_PULLCTL1 */
+static PAD_PULLCTL_CONF(PCM1_IN, 1, 30, 2);
+static PAD_PULLCTL_CONF(PCM1_OUT, 1, 28, 2);
+static PAD_PULLCTL_CONF(SD0_D0, 1, 26, 2);
+static PAD_PULLCTL_CONF(SD0_D1, 1, 24, 2);
+static PAD_PULLCTL_CONF(SD0_D2, 1, 22, 2);
+static PAD_PULLCTL_CONF(SD0_D3, 1, 20, 2);
+static PAD_PULLCTL_CONF(SD0_CMD, 1, 18, 2);
+static PAD_PULLCTL_CONF(SD0_CLK, 1, 16, 2);
+static PAD_PULLCTL_CONF(SD1_CMD, 1, 14, 2);
+static PAD_PULLCTL_CONF(SD1_D0, 1, 12, 2);
+static PAD_PULLCTL_CONF(SD1_D1, 1, 10, 2);
+static PAD_PULLCTL_CONF(SD1_D2, 1, 8, 2);
+static PAD_PULLCTL_CONF(SD1_D3, 1, 6, 2);
+static PAD_PULLCTL_CONF(UART0_RX, 1, 4, 2);
+static PAD_PULLCTL_CONF(UART0_TX, 1, 2, 2);
+
+/* PAD_PULLCTL2 */
+static PAD_PULLCTL_CONF(I2C2_SDATA, 2, 26, 2);
+static PAD_PULLCTL_CONF(I2C2_SCLK, 2, 24, 2);
+static PAD_PULLCTL_CONF(SPI0_SCLK, 2, 22, 2);
+static PAD_PULLCTL_CONF(SPI0_MOSI, 2, 20, 2);
+static PAD_PULLCTL_CONF(I2C1_SDATA, 2, 18, 2);
+static PAD_PULLCTL_CONF(I2C1_SCLK, 2, 16, 2);
+static PAD_PULLCTL_CONF(NAND0_D0, 2, 15, 1);
+static PAD_PULLCTL_CONF(NAND0_D1, 2, 15, 1);
+static PAD_PULLCTL_CONF(NAND0_D2, 2, 15, 1);
+static PAD_PULLCTL_CONF(NAND0_D3, 2, 15, 1);
+static PAD_PULLCTL_CONF(NAND0_D4, 2, 15, 1);
+static PAD_PULLCTL_CONF(NAND0_D5, 2, 15, 1);
+static PAD_PULLCTL_CONF(NAND0_D6, 2, 15, 1);
+static PAD_PULLCTL_CONF(NAND0_D7, 2, 15, 1);
+static PAD_PULLCTL_CONF(NAND0_DQSN, 2, 14, 1);
+static PAD_PULLCTL_CONF(NAND0_DQS, 2, 13, 1);
+static PAD_PULLCTL_CONF(NAND1_D0, 2, 12, 1);
+static PAD_PULLCTL_CONF(NAND1_D1, 2, 12, 1);
+static PAD_PULLCTL_CONF(NAND1_D2, 2, 12, 1);
+static PAD_PULLCTL_CONF(NAND1_D3, 2, 12, 1);
+static PAD_PULLCTL_CONF(NAND1_D4, 2, 12, 1);
+static PAD_PULLCTL_CONF(NAND1_D5, 2, 12, 1);
+static PAD_PULLCTL_CONF(NAND1_D6, 2, 12, 1);
+static PAD_PULLCTL_CONF(NAND1_D7, 2, 12, 1);
+static PAD_PULLCTL_CONF(NAND1_DQSN, 2, 11, 1);
+static PAD_PULLCTL_CONF(NAND1_DQS, 2, 10, 1);
+static PAD_PULLCTL_CONF(SGPIO2, 2, 8, 2);
+static PAD_PULLCTL_CONF(SGPIO3, 2, 6, 2);
+static PAD_PULLCTL_CONF(UART4_RX, 2, 4, 2);
+static PAD_PULLCTL_CONF(UART4_TX, 2, 2, 2);
+
+/* PAD_ST0 */
+static PAD_ST_CONF(I2C0_SDATA, 0, 30, 1);
+static PAD_ST_CONF(UART0_RX, 0, 29, 1);
+static PAD_ST_CONF(ETH_MDC, 0, 28, 1);
+static PAD_ST_CONF(I2S_MCLK1, 0, 23, 1);
+static PAD_ST_CONF(ETH_REF_CLK, 0, 22, 1);
+static PAD_ST_CONF(ETH_TXEN, 0, 21, 1);
+static PAD_ST_CONF(ETH_TXD0, 0, 20, 1);
+static PAD_ST_CONF(I2S_LRCLK1, 0, 19, 1);
+static PAD_ST_CONF(SGPIO2, 0, 18, 1);
+static PAD_ST_CONF(SGPIO3, 0, 17, 1);
+static PAD_ST_CONF(UART4_TX, 0, 16, 1);
+static PAD_ST_CONF(I2S_D1, 0, 15, 1);
+static PAD_ST_CONF(UART0_TX, 0, 14, 1);
+static PAD_ST_CONF(SPI0_SCLK, 0, 13, 1);
+static PAD_ST_CONF(SD0_CLK, 0, 12, 1);
+static PAD_ST_CONF(ERAM_A5, 0, 11, 1);
+static PAD_ST_CONF(I2C0_SCLK, 0, 7, 1);
+static PAD_ST_CONF(ERAM_A9, 0, 6, 1);
+static PAD_ST_CONF(LVDS_OEP, 0, 5, 1);
+static PAD_ST_CONF(LVDS_ODN, 0, 4, 1);
+static PAD_ST_CONF(LVDS_OAP, 0, 3, 1);
+static PAD_ST_CONF(I2S_BCLK1, 0, 2, 1);
+
+/* PAD_ST1 */
+static PAD_ST_CONF(I2S_LRCLK0, 1, 29, 1);
+static PAD_ST_CONF(UART4_RX, 1, 28, 1);
+static PAD_ST_CONF(UART3_CTSB, 1, 27, 1);
+static PAD_ST_CONF(UART3_RTSB, 1, 26, 1);
+static PAD_ST_CONF(UART3_RX, 1, 25, 1);
+static PAD_ST_CONF(UART2_RTSB, 1, 24, 1);
+static PAD_ST_CONF(UART2_CTSB, 1, 23, 1);
+static PAD_ST_CONF(UART2_RX, 1, 22, 1);
+static PAD_ST_CONF(ETH_RXD0, 1, 21, 1);
+static PAD_ST_CONF(ETH_RXD1, 1, 20, 1);
+static PAD_ST_CONF(ETH_CRS_DV, 1, 19, 1);
+static PAD_ST_CONF(ETH_RXER, 1, 18, 1);
+static PAD_ST_CONF(ETH_TXD1, 1, 17, 1);
+static PAD_ST_CONF(LVDS_OCP, 1, 16, 1);
+static PAD_ST_CONF(LVDS_OBP, 1, 15, 1);
+static PAD_ST_CONF(LVDS_OBN, 1, 14, 1);
+static PAD_ST_CONF(PCM1_OUT, 1, 12, 1);
+static PAD_ST_CONF(PCM1_CLK, 1, 11, 1);
+static PAD_ST_CONF(PCM1_IN, 1, 10, 1);
+static PAD_ST_CONF(PCM1_SYNC, 1, 9, 1);
+static PAD_ST_CONF(I2C1_SCLK, 1, 8, 1);
+static PAD_ST_CONF(I2C1_SDATA, 1, 7, 1);
+static PAD_ST_CONF(I2C2_SCLK, 1, 6, 1);
+static PAD_ST_CONF(I2C2_SDATA, 1, 5, 1);
+static PAD_ST_CONF(SPI0_MOSI, 1, 4, 1);
+static PAD_ST_CONF(SPI0_MISO, 1, 3, 1);
+static PAD_ST_CONF(SPI0_SS, 1, 2, 1);
+static PAD_ST_CONF(I2S_BCLK0, 1, 1, 1);
+static PAD_ST_CONF(I2S_MCLK0, 1, 0, 1);
+
+#define PAD_INFO(name)							\
+	{								\
+		.pad = name,						\
+		.pullctl = NULL,					\
+		.st = NULL,						\
+	}
+
+#define PAD_INFO_ST(name)						\
+	{								\
+		.pad = name,						\
+		.pullctl = NULL,					\
+		.st = &name##_st_conf,					\
+	}
+
+#define PAD_INFO_PULLCTL(name)						\
+	{								\
+		.pad = name,						\
+		.pullctl = &name##_pullctl_conf,			\
+		.st = NULL,						\
+	}
+
+#define PAD_INFO_PULLCTL_ST(name)					\
+	{								\
+		.pad = name,						\
+		.pullctl = &name##_pullctl_conf,			\
+		.st = &name##_st_conf,					\
+	}
+
+/* Pad info table */
+struct owl_padinfo s900_padinfo[NUM_PADS] = {
+	[ETH_TXD0] = PAD_INFO_ST(ETH_TXD0),
+	[ETH_TXD1] = PAD_INFO_ST(ETH_TXD1),
+	[ETH_TXEN] = PAD_INFO_ST(ETH_TXEN),
+	[ETH_RXER] = PAD_INFO_PULLCTL_ST(ETH_RXER),
+	[ETH_CRS_DV] = PAD_INFO_ST(ETH_CRS_DV),
+	[ETH_RXD1] = PAD_INFO_ST(ETH_RXD1),
+	[ETH_RXD0] = PAD_INFO_ST(ETH_RXD0),
+	[ETH_REF_CLK] = PAD_INFO_ST(ETH_REF_CLK),
+	[ETH_MDC] = PAD_INFO_ST(ETH_MDC),
+	[ETH_MDIO] = PAD_INFO(ETH_MDIO),
+	[SIRQ0] = PAD_INFO_PULLCTL(SIRQ0),
+	[SIRQ1] = PAD_INFO_PULLCTL(SIRQ1),
+	[SIRQ2] = PAD_INFO_PULLCTL(SIRQ2),
+	[I2S_D0] = PAD_INFO(I2S_D0),
+	[I2S_BCLK0] = PAD_INFO_ST(I2S_BCLK0),
+	[I2S_LRCLK0] = PAD_INFO_ST(I2S_LRCLK0),
+	[I2S_MCLK0] = PAD_INFO_ST(I2S_MCLK0),
+	[I2S_D1] = PAD_INFO_ST(I2S_D1),
+	[I2S_BCLK1] = PAD_INFO_ST(I2S_BCLK1),
+	[I2S_LRCLK1] = PAD_INFO_ST(I2S_LRCLK1),
+	[I2S_MCLK1] = PAD_INFO_ST(I2S_MCLK1),
+	[PCM1_IN] = PAD_INFO_PULLCTL_ST(PCM1_IN),
+	[PCM1_CLK] = PAD_INFO_ST(PCM1_CLK),
+	[PCM1_SYNC] = PAD_INFO_ST(PCM1_SYNC),
+	[PCM1_OUT] = PAD_INFO_PULLCTL_ST(PCM1_OUT),
+	[ERAM_A5] = PAD_INFO_PULLCTL_ST(ERAM_A5),
+	[ERAM_A6] = PAD_INFO_PULLCTL(ERAM_A6),
+	[ERAM_A7] = PAD_INFO_PULLCTL(ERAM_A7),
+	[ERAM_A8] = PAD_INFO(ERAM_A8),
+	[ERAM_A9] = PAD_INFO_ST(ERAM_A9),
+	[ERAM_A10] = PAD_INFO_PULLCTL(ERAM_A10),
+	[ERAM_A11] = PAD_INFO(ERAM_A11),
+	[LVDS_OEP] = PAD_INFO_ST(LVDS_OEP),
+	[LVDS_OEN] = PAD_INFO(LVDS_OEN),
+	[LVDS_ODP] = PAD_INFO(LVDS_ODP),
+	[LVDS_ODN] = PAD_INFO_ST(LVDS_ODN),
+	[LVDS_OCP] = PAD_INFO_ST(LVDS_OCP),
+	[LVDS_OCN] = PAD_INFO(LVDS_OCN),
+	[LVDS_OBP] = PAD_INFO_ST(LVDS_OBP),
+	[LVDS_OBN] = PAD_INFO_ST(LVDS_OBN),
+	[LVDS_OAP] = PAD_INFO_ST(LVDS_OAP),
+	[LVDS_OAN] = PAD_INFO(LVDS_OAN),
+	[LVDS_EEP] = PAD_INFO(LVDS_EEP),
+	[LVDS_EEN] = PAD_INFO(LVDS_EEN),
+	[LVDS_EDP] = PAD_INFO(LVDS_EDP),
+	[LVDS_EDN] = PAD_INFO(LVDS_EDN),
+	[LVDS_ECP] = PAD_INFO(LVDS_ECP),
+	[LVDS_ECN] = PAD_INFO(LVDS_ECN),
+	[LVDS_EBP] = PAD_INFO(LVDS_EBP),
+	[LVDS_EBN] = PAD_INFO(LVDS_EBN),
+	[LVDS_EAP] = PAD_INFO(LVDS_EAP),
+	[LVDS_EAN] = PAD_INFO(LVDS_EAN),
+	[SD0_D0] = PAD_INFO_PULLCTL(SD0_D0),
+	[SD0_D1] = PAD_INFO_PULLCTL(SD0_D1),
+	[SD0_D2] = PAD_INFO_PULLCTL(SD0_D2),
+	[SD0_D3] = PAD_INFO_PULLCTL(SD0_D3),
+	[SD1_D0] = PAD_INFO_PULLCTL(SD1_D0),
+	[SD1_D1] = PAD_INFO_PULLCTL(SD1_D1),
+	[SD1_D2] = PAD_INFO_PULLCTL(SD1_D2),
+	[SD1_D3] = PAD_INFO_PULLCTL(SD1_D3),
+	[SD0_CMD] = PAD_INFO_PULLCTL(SD0_CMD),
+	[SD0_CLK] = PAD_INFO_PULLCTL_ST(SD0_CLK),
+	[SD1_CMD] = PAD_INFO_PULLCTL(SD1_CMD),
+	[SD1_CLK] = PAD_INFO(SD1_CLK),
+	[SPI0_SCLK] = PAD_INFO_PULLCTL_ST(SPI0_SCLK),
+	[SPI0_SS] = PAD_INFO_ST(SPI0_SS),
+	[SPI0_MISO] = PAD_INFO_ST(SPI0_MISO),
+	[SPI0_MOSI] = PAD_INFO_PULLCTL_ST(SPI0_MOSI),
+	[UART0_RX] = PAD_INFO_PULLCTL_ST(UART0_RX),
+	[UART0_TX] = PAD_INFO_PULLCTL_ST(UART0_TX),
+	[UART2_RX] = PAD_INFO_ST(UART2_RX),
+	[UART2_TX] = PAD_INFO(UART2_TX),
+	[UART2_RTSB] = PAD_INFO_ST(UART2_RTSB),
+	[UART2_CTSB] = PAD_INFO_ST(UART2_CTSB),
+	[UART3_RX] = PAD_INFO_ST(UART3_RX),
+	[UART3_TX] = PAD_INFO(UART3_TX),
+	[UART3_RTSB] = PAD_INFO_ST(UART3_RTSB),
+	[UART3_CTSB] = PAD_INFO_ST(UART3_CTSB),
+	[UART4_RX] = PAD_INFO_PULLCTL_ST(UART4_RX),
+	[UART4_TX] = PAD_INFO_PULLCTL_ST(UART4_TX),
+	[I2C0_SCLK] = PAD_INFO_PULLCTL_ST(I2C0_SCLK),
+	[I2C0_SDATA] = PAD_INFO_PULLCTL_ST(I2C0_SDATA),
+	[I2C1_SCLK] = PAD_INFO_PULLCTL_ST(I2C1_SCLK),
+	[I2C1_SDATA] = PAD_INFO_PULLCTL_ST(I2C1_SDATA),
+	[I2C2_SCLK] = PAD_INFO_PULLCTL_ST(I2C2_SCLK),
+	[I2C2_SDATA] = PAD_INFO_PULLCTL_ST(I2C2_SDATA),
+	[CSI0_DN0] = PAD_INFO(CSI0_DN0),
+	[CSI0_DP0] = PAD_INFO(CSI0_DP0),
+	[CSI0_DN1] = PAD_INFO(CSI0_DN1),
+	[CSI0_DP1] = PAD_INFO(CSI0_DP1),
+	[CSI0_CN] = PAD_INFO(CSI0_CN),
+	[CSI0_CP] = PAD_INFO(CSI0_CP),
+	[CSI0_DN2] = PAD_INFO(CSI0_DN2),
+	[CSI0_DP2] = PAD_INFO(CSI0_DP2),
+	[CSI0_DN3] = PAD_INFO(CSI0_DN3),
+	[CSI0_DP3] = PAD_INFO(CSI0_DP3),
+	[DSI_DP3] = PAD_INFO(DSI_DP3),
+	[DSI_DN3] = PAD_INFO(DSI_DN3),
+	[DSI_DP1] = PAD_INFO(DSI_DP1),
+	[DSI_DN1] = PAD_INFO(DSI_DN1),
+	[DSI_CP] = PAD_INFO(DSI_CP),
+	[DSI_CN] = PAD_INFO(DSI_CN),
+	[DSI_DP0] = PAD_INFO(DSI_DP0),
+	[DSI_DN0] = PAD_INFO(DSI_DN0),
+	[DSI_DP2] = PAD_INFO(DSI_DP2),
+	[DSI_DN2] = PAD_INFO(DSI_DN2),
+	[SENSOR0_PCLK] = PAD_INFO(SENSOR0_PCLK),
+	[CSI1_DN0] = PAD_INFO(CSI1_DN0),
+	[CSI1_DP0] = PAD_INFO(CSI1_DP0),
+	[CSI1_DN1] = PAD_INFO(CSI1_DN1),
+	[CSI1_DP1] = PAD_INFO(CSI1_DP1),
+	[CSI1_CN] = PAD_INFO(CSI1_CN),
+	[CSI1_CP] = PAD_INFO(CSI1_CP),
+	[SENSOR0_CKOUT] = PAD_INFO(SENSOR0_CKOUT),
+	[NAND0_D0] = PAD_INFO_PULLCTL(NAND0_D0),
+	[NAND0_D1] = PAD_INFO_PULLCTL(NAND0_D1),
+	[NAND0_D2] = PAD_INFO_PULLCTL(NAND0_D2),
+	[NAND0_D3] = PAD_INFO_PULLCTL(NAND0_D3),
+	[NAND0_D4] = PAD_INFO_PULLCTL(NAND0_D4),
+	[NAND0_D5] = PAD_INFO_PULLCTL(NAND0_D5),
+	[NAND0_D6] = PAD_INFO_PULLCTL(NAND0_D6),
+	[NAND0_D7] = PAD_INFO_PULLCTL(NAND0_D7),
+	[NAND0_DQS] = PAD_INFO_PULLCTL(NAND0_DQS),
+	[NAND0_DQSN] = PAD_INFO_PULLCTL(NAND0_DQSN),
+	[NAND0_ALE] = PAD_INFO(NAND0_ALE),
+	[NAND0_CLE] = PAD_INFO(NAND0_CLE),
+	[NAND0_CEB0] = PAD_INFO(NAND0_CEB0),
+	[NAND0_CEB1] = PAD_INFO(NAND0_CEB1),
+	[NAND0_CEB2] = PAD_INFO(NAND0_CEB2),
+	[NAND0_CEB3] = PAD_INFO(NAND0_CEB3),
+	[NAND1_D0] = PAD_INFO_PULLCTL(NAND1_D0),
+	[NAND1_D1] = PAD_INFO_PULLCTL(NAND1_D1),
+	[NAND1_D2] = PAD_INFO_PULLCTL(NAND1_D2),
+	[NAND1_D3] = PAD_INFO_PULLCTL(NAND1_D3),
+	[NAND1_D4] = PAD_INFO_PULLCTL(NAND1_D4),
+	[NAND1_D5] = PAD_INFO_PULLCTL(NAND1_D5),
+	[NAND1_D6] = PAD_INFO_PULLCTL(NAND1_D6),
+	[NAND1_D7] = PAD_INFO_PULLCTL(NAND1_D7),
+	[NAND1_DQS] = PAD_INFO_PULLCTL(NAND1_DQS),
+	[NAND1_DQSN] = PAD_INFO_PULLCTL(NAND1_DQSN),
+	[NAND1_ALE] = PAD_INFO(NAND1_ALE),
+	[NAND1_CLE] = PAD_INFO(NAND1_CLE),
+	[NAND1_CEB0] = PAD_INFO(NAND1_CEB0),
+	[NAND1_CEB1] = PAD_INFO(NAND1_CEB1),
+	[NAND1_CEB2] = PAD_INFO(NAND1_CEB2),
+	[NAND1_CEB3] = PAD_INFO(NAND1_CEB3),
+	[SGPIO0] = PAD_INFO(SGPIO0),
+	[SGPIO1] = PAD_INFO(SGPIO1),
+	[SGPIO2] = PAD_INFO_PULLCTL_ST(SGPIO2),
+	[SGPIO3] = PAD_INFO_PULLCTL_ST(SGPIO3)
+};
+
+static struct owl_pinctrl_soc_data s900_pinctrl_data = {
+	.padinfo = s900_padinfo,
+	.pins = (const struct pinctrl_pin_desc *)s900_pads,
+	.npins = ARRAY_SIZE(s900_pads),
+	.functions = s900_functions,
+	.nfunctions = ARRAY_SIZE(s900_functions),
+	.groups = s900_groups,
+	.ngroups = ARRAY_SIZE(s900_groups),
+	.ngpios = NUM_GPIOS
+};
+
+static int s900_pinctrl_probe(struct platform_device *pdev)
+{
+	return owl_pinctrl_probe(pdev, &s900_pinctrl_data);
+}
+
+static const struct of_device_id s900_pinctrl_of_match[] = {
+	{ .compatible = "actions,s900-pinctrl", },
+	{ }
+};
+
+static struct platform_driver s900_pinctrl_driver = {
+	.driver = {
+		.name = "pinctrl-s900",
+		.of_match_table = of_match_ptr(s900_pinctrl_of_match),
+	},
+	.probe = s900_pinctrl_probe
+};
+
+static int __init s900_pinctrl_init(void)
+{
+	return platform_driver_register(&s900_pinctrl_driver);
+}
+arch_initcall(s900_pinctrl_init);
+
+static void __exit s900_pinctrl_exit(void)
+{
+	platform_driver_unregister(&s900_pinctrl_driver);
+}
+module_exit(s900_pinctrl_exit);
+
+MODULE_AUTHOR("Actions Semi Inc.");
+MODULE_AUTHOR("Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>");
+MODULE_DESCRIPTION("Actions Semi S900 SoC Pinctrl Driver");
+MODULE_LICENSE("GPL");
-- 
2.14.1

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

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

Add gpio nodes for Actions Semi S900 SoC.

Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
---
 .../devicetree/bindings/gpio/actions,owl-gpio.txt  | 95 ++++++++++++++++++++++
 1 file changed, 95 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/actions,owl-gpio.txt

diff --git a/Documentation/devicetree/bindings/gpio/actions,owl-gpio.txt b/Documentation/devicetree/bindings/gpio/actions,owl-gpio.txt
new file mode 100644
index 000000000000..d2939ca6cfaf
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/actions,owl-gpio.txt
@@ -0,0 +1,95 @@
+* Actions Semi OWL GPIO controller bindings
+
+The GPIOs are organized as individual banks/ports with variable number
+of GPIOs. Each bank is represented as an individual GPIO controller.
+
+Required properties:
+- compatible            : Should be "actions,s900-gpio"
+- reg                   : Address and range of the GPIO controller registers.
+- gpio-controller       : Marks the device node as a GPIO controller.
+- #gpio-cells           : Should be <2>. The first cell is the gpio number
+                          and the second cell is used to specify 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
+
+Optional properties:
+- gpio-ranges           : Mapping between GPIO and pinctrl
+
+Note: Each GPIO port should have an alias correctly numbered in "aliases"
+node.
+
+Examples:
+
+aliases {
+        gpio0 = &gpioa;
+        gpio1 = &gpiob;
+        gpio2 = &gpioc;
+        gpio3 = &gpiod;
+        gpio4 = &gpioe;
+        gpio5 = &gpiof;
+};
+
+       gpioa: gpioa@e01b0000 {
+               compatible = "actions,s900-gpio";
+               reg = <0x0 0xe01b0000 0x0 0x1000>;
+               gpio-controller;
+               #gpio-cells = <2>;
+               gpio-ranges = <&pinctrl 0 0 32>;
+               interrupt-controller;
+               #interrupt-cells = <2>;
+       };
+
+       gpiob: gpiob@e01b0000 {
+               compatible = "actions,s900-gpio";
+               reg = <0x0 0xe01b0000 0x0 0x1000>;
+               gpio-controller;
+               #gpio-cells = <2>;
+               gpio-ranges = <&pinctrl 0 32 32>;
+               interrupt-controller;
+               #interrupt-cells = <2>;
+       };
+
+       gpioc: gpioc@e01b0000 {
+               compatible = "actions,s900-gpio";
+               reg = <0x0 0xe01b0000 0x0 0x1000>;
+               gpio-controller;
+               #gpio-cells = <2>;
+               gpio-ranges = <&pinctrl 0 64 12>;
+               interrupt-controller;
+               #interrupt-cells = <2>;
+       };
+
+       gpiod: gpiod@e01b0000 {
+               compatible = "actions,s900-gpio";
+               reg = <0x0 0xe01b0000 0x0 0x1000>;
+               gpio-controller;
+               #gpio-cells = <2>;
+               gpio-ranges = <&pinctrl 0 76 30>;
+               interrupt-controller;
+               #interrupt-cells = <2>;
+       };
+
+       gpioe: gpioe@e01b0000 {
+               compatible = "actions,s900-gpio";
+               reg = <0x0 0xe01b0000 0x0 0x1000>;
+               gpio-controller;
+               #gpio-cells = <2>;
+               gpio-ranges = <&pinctrl 0 106 32>;
+               interrupt-controller;
+               #interrupt-cells = <2>;
+       };
+
+       gpiof: gpiof@e01b0000 {
+               compatible = "actions,s900-gpio";
+               reg = <0x0 0xe01b0000 0x0 0x1000>;
+               gpio-controller;
+               #gpio-cells = <2>;
+               gpio-ranges = <&pinctrl 0 138 8>;
+               interrupt-controller;
+               #interrupt-cells = <2>;
+       };
-- 
2.14.1

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

* [PATCH v4 05/10] dt-bindings: gpio: Add gpio nodes for Actions S900 SoC
@ 2018-03-02  3:50   ` Manivannan Sadhasivam
  0 siblings, 0 replies; 43+ messages in thread
From: Manivannan Sadhasivam @ 2018-03-02  3:50 UTC (permalink / raw)
  To: linux-arm-kernel

Add gpio nodes for Actions Semi S900 SoC.

Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
---
 .../devicetree/bindings/gpio/actions,owl-gpio.txt  | 95 ++++++++++++++++++++++
 1 file changed, 95 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/actions,owl-gpio.txt

diff --git a/Documentation/devicetree/bindings/gpio/actions,owl-gpio.txt b/Documentation/devicetree/bindings/gpio/actions,owl-gpio.txt
new file mode 100644
index 000000000000..d2939ca6cfaf
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/actions,owl-gpio.txt
@@ -0,0 +1,95 @@
+* Actions Semi OWL GPIO controller bindings
+
+The GPIOs are organized as individual banks/ports with variable number
+of GPIOs. Each bank is represented as an individual GPIO controller.
+
+Required properties:
+- compatible            : Should be "actions,s900-gpio"
+- reg                   : Address and range of the GPIO controller registers.
+- gpio-controller       : Marks the device node as a GPIO controller.
+- #gpio-cells           : Should be <2>. The first cell is the gpio number
+                          and the second cell is used to specify 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
+
+Optional properties:
+- gpio-ranges           : Mapping between GPIO and pinctrl
+
+Note: Each GPIO port should have an alias correctly numbered in "aliases"
+node.
+
+Examples:
+
+aliases {
+        gpio0 = &gpioa;
+        gpio1 = &gpiob;
+        gpio2 = &gpioc;
+        gpio3 = &gpiod;
+        gpio4 = &gpioe;
+        gpio5 = &gpiof;
+};
+
+       gpioa: gpioa at e01b0000 {
+               compatible = "actions,s900-gpio";
+               reg = <0x0 0xe01b0000 0x0 0x1000>;
+               gpio-controller;
+               #gpio-cells = <2>;
+               gpio-ranges = <&pinctrl 0 0 32>;
+               interrupt-controller;
+               #interrupt-cells = <2>;
+       };
+
+       gpiob: gpiob at e01b0000 {
+               compatible = "actions,s900-gpio";
+               reg = <0x0 0xe01b0000 0x0 0x1000>;
+               gpio-controller;
+               #gpio-cells = <2>;
+               gpio-ranges = <&pinctrl 0 32 32>;
+               interrupt-controller;
+               #interrupt-cells = <2>;
+       };
+
+       gpioc: gpioc at e01b0000 {
+               compatible = "actions,s900-gpio";
+               reg = <0x0 0xe01b0000 0x0 0x1000>;
+               gpio-controller;
+               #gpio-cells = <2>;
+               gpio-ranges = <&pinctrl 0 64 12>;
+               interrupt-controller;
+               #interrupt-cells = <2>;
+       };
+
+       gpiod: gpiod at e01b0000 {
+               compatible = "actions,s900-gpio";
+               reg = <0x0 0xe01b0000 0x0 0x1000>;
+               gpio-controller;
+               #gpio-cells = <2>;
+               gpio-ranges = <&pinctrl 0 76 30>;
+               interrupt-controller;
+               #interrupt-cells = <2>;
+       };
+
+       gpioe: gpioe at e01b0000 {
+               compatible = "actions,s900-gpio";
+               reg = <0x0 0xe01b0000 0x0 0x1000>;
+               gpio-controller;
+               #gpio-cells = <2>;
+               gpio-ranges = <&pinctrl 0 106 32>;
+               interrupt-controller;
+               #interrupt-cells = <2>;
+       };
+
+       gpiof: gpiof at e01b0000 {
+               compatible = "actions,s900-gpio";
+               reg = <0x0 0xe01b0000 0x0 0x1000>;
+               gpio-controller;
+               #gpio-cells = <2>;
+               gpio-ranges = <&pinctrl 0 138 8>;
+               interrupt-controller;
+               #interrupt-cells = <2>;
+       };
-- 
2.14.1

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

* [PATCH v4 06/10] arm64: dts: actions: Add S900 gpio nodes
  2018-03-02  3:50 ` Manivannan Sadhasivam
@ 2018-03-02  3:50   ` Manivannan Sadhasivam
  -1 siblings, 0 replies; 43+ messages in thread
From: Manivannan Sadhasivam @ 2018-03-02  3:50 UTC (permalink / raw)
  To: linus.walleij, robh+dt, afaerber
  Cc: liuwei, mp-cs, 96boards, devicetree, daniel.thompson,
	amit.kucheria, linux-arm-kernel, linux-gpio, linux-kernel,
	hzhang, bdong, manivannanece23, Manivannan Sadhasivam

Add gpio nodes for Actions Semi S900 SoC.

Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
---
 arch/arm64/boot/dts/actions/s900-bubblegum-96.dts |  6 +++
 arch/arm64/boot/dts/actions/s900.dtsi             | 48 +++++++++++++++++++++++
 2 files changed, 54 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..60ddaf98401b 100644
--- a/arch/arm64/boot/dts/actions/s900-bubblegum-96.dts
+++ b/arch/arm64/boot/dts/actions/s900-bubblegum-96.dts
@@ -14,6 +14,12 @@
 
 	aliases {
 		serial5 = &uart5;
+		gpio0 = &gpioa;
+		gpio1 = &gpiob;
+		gpio2 = &gpioc;
+		gpio3 = &gpiod;
+		gpio4 = &gpioe;
+		gpio5 = &gpiof;
 	};
 
 	chosen {
diff --git a/arch/arm64/boot/dts/actions/s900.dtsi b/arch/arm64/boot/dts/actions/s900.dtsi
index 0156483f0f4d..9c7843045850 100644
--- a/arch/arm64/boot/dts/actions/s900.dtsi
+++ b/arch/arm64/boot/dts/actions/s900.dtsi
@@ -180,6 +180,54 @@
 			clocks = <&cmu CLK_GPIO>;
 		};
 
+		gpioa: gpioa@e01b0000 {
+			compatible = "actions,s900-gpio";
+			reg = <0x0 0xe01b0000 0x0 0x1000>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <&pinctrl 0 0 32>;
+		};
+
+		gpiob: gpiob@e01b0000 {
+			compatible = "actions,s900-gpio";
+			reg = <0x0 0xe01b0000 0x0 0x1000>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <&pinctrl 0 32 32>;
+		};
+
+		gpioc: gpioc@e01b0000 {
+			compatible = "actions,s900-gpio";
+			reg = <0x0 0xe01b0000 0x0 0x1000>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <&pinctrl 0 64 12>;
+		};
+
+		gpiod: gpiod@e01b0000 {
+			compatible = "actions,s900-gpio";
+			reg = <0x0 0xe01b0000 0x0 0x1000>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <&pinctrl 0 76 30>;
+		};
+
+		gpioe: gpioe@e01b0000 {
+			compatible = "actions,s900-gpio";
+			reg = <0x0 0xe01b0000 0x0 0x1000>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <&pinctrl 0 106 32>;
+		};
+
+		gpiof: gpiof@e01b0000 {
+			compatible = "actions,s900-gpio";
+			reg = <0x0 0xe01b0000 0x0 0x1000>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <&pinctrl 0 138 8>;
+		};
+
 		timer: timer@e0228000 {
 			compatible = "actions,s900-timer";
 			reg = <0x0 0xe0228000 0x0 0x8000>;
-- 
2.14.1

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

* [PATCH v4 06/10] arm64: dts: actions: Add S900 gpio nodes
@ 2018-03-02  3:50   ` Manivannan Sadhasivam
  0 siblings, 0 replies; 43+ messages in thread
From: Manivannan Sadhasivam @ 2018-03-02  3:50 UTC (permalink / raw)
  To: linux-arm-kernel

Add gpio nodes for Actions Semi S900 SoC.

Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
---
 arch/arm64/boot/dts/actions/s900-bubblegum-96.dts |  6 +++
 arch/arm64/boot/dts/actions/s900.dtsi             | 48 +++++++++++++++++++++++
 2 files changed, 54 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..60ddaf98401b 100644
--- a/arch/arm64/boot/dts/actions/s900-bubblegum-96.dts
+++ b/arch/arm64/boot/dts/actions/s900-bubblegum-96.dts
@@ -14,6 +14,12 @@
 
 	aliases {
 		serial5 = &uart5;
+		gpio0 = &gpioa;
+		gpio1 = &gpiob;
+		gpio2 = &gpioc;
+		gpio3 = &gpiod;
+		gpio4 = &gpioe;
+		gpio5 = &gpiof;
 	};
 
 	chosen {
diff --git a/arch/arm64/boot/dts/actions/s900.dtsi b/arch/arm64/boot/dts/actions/s900.dtsi
index 0156483f0f4d..9c7843045850 100644
--- a/arch/arm64/boot/dts/actions/s900.dtsi
+++ b/arch/arm64/boot/dts/actions/s900.dtsi
@@ -180,6 +180,54 @@
 			clocks = <&cmu CLK_GPIO>;
 		};
 
+		gpioa: gpioa at e01b0000 {
+			compatible = "actions,s900-gpio";
+			reg = <0x0 0xe01b0000 0x0 0x1000>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <&pinctrl 0 0 32>;
+		};
+
+		gpiob: gpiob at e01b0000 {
+			compatible = "actions,s900-gpio";
+			reg = <0x0 0xe01b0000 0x0 0x1000>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <&pinctrl 0 32 32>;
+		};
+
+		gpioc: gpioc at e01b0000 {
+			compatible = "actions,s900-gpio";
+			reg = <0x0 0xe01b0000 0x0 0x1000>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <&pinctrl 0 64 12>;
+		};
+
+		gpiod: gpiod at e01b0000 {
+			compatible = "actions,s900-gpio";
+			reg = <0x0 0xe01b0000 0x0 0x1000>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <&pinctrl 0 76 30>;
+		};
+
+		gpioe: gpioe at e01b0000 {
+			compatible = "actions,s900-gpio";
+			reg = <0x0 0xe01b0000 0x0 0x1000>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <&pinctrl 0 106 32>;
+		};
+
+		gpiof: gpiof at e01b0000 {
+			compatible = "actions,s900-gpio";
+			reg = <0x0 0xe01b0000 0x0 0x1000>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <&pinctrl 0 138 8>;
+		};
+
 		timer: timer at e0228000 {
 			compatible = "actions,s900-timer";
 			reg = <0x0 0xe0228000 0x0 0x8000>;
-- 
2.14.1

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

* [PATCH v4 07/10] arm64: dts: actions: Add gpio line names to Bubblegum-96 board
  2018-03-02  3:50 ` Manivannan Sadhasivam
@ 2018-03-02  3:50   ` Manivannan Sadhasivam
  -1 siblings, 0 replies; 43+ messages in thread
From: Manivannan Sadhasivam @ 2018-03-02  3:50 UTC (permalink / raw)
  To: linus.walleij, robh+dt, afaerber
  Cc: liuwei, mp-cs, 96boards, devicetree, 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 | 195 ++++++++++++++++++++++
 1 file changed, 195 insertions(+)

diff --git a/arch/arm64/boot/dts/actions/s900-bubblegum-96.dts b/arch/arm64/boot/dts/actions/s900-bubblegum-96.dts
index 60ddaf98401b..05ec8a7e924d 100644
--- a/arch/arm64/boot/dts/actions/s900-bubblegum-96.dts
+++ b/arch/arm64/boot/dts/actions/s900-bubblegum-96.dts
@@ -40,3 +40,198 @@
 	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.
+ */
+
+&gpioa {
+	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 */
+};
+
+&gpiob {
+	gpio-line-names =
+		"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 */
+};
+
+&gpioc {
+	gpio-line-names =
+		"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 */
+};
+
+&gpiod {
+	gpio-line-names =
+		"[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 */
+};
+
+&gpioe {
+	gpio-line-names =
+		"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 */
+};
+
+&gpiof {
+	gpio-line-names =
+		"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] 43+ messages in thread

* [PATCH v4 07/10] arm64: dts: actions: Add gpio line names to Bubblegum-96 board
@ 2018-03-02  3:50   ` Manivannan Sadhasivam
  0 siblings, 0 replies; 43+ messages in thread
From: Manivannan Sadhasivam @ 2018-03-02  3:50 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 | 195 ++++++++++++++++++++++
 1 file changed, 195 insertions(+)

diff --git a/arch/arm64/boot/dts/actions/s900-bubblegum-96.dts b/arch/arm64/boot/dts/actions/s900-bubblegum-96.dts
index 60ddaf98401b..05ec8a7e924d 100644
--- a/arch/arm64/boot/dts/actions/s900-bubblegum-96.dts
+++ b/arch/arm64/boot/dts/actions/s900-bubblegum-96.dts
@@ -40,3 +40,198 @@
 	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.
+ */
+
+&gpioa {
+	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 */
+};
+
+&gpiob {
+	gpio-line-names =
+		"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 */
+};
+
+&gpioc {
+	gpio-line-names =
+		"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 */
+};
+
+&gpiod {
+	gpio-line-names =
+		"[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 */
+};
+
+&gpioe {
+	gpio-line-names =
+		"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 */
+};
+
+&gpiof {
+	gpio-line-names =
+		"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] 43+ messages in thread

* [PATCH v4 08/10] gpio: Add gpio driver for Actions OWL S900 SoC
  2018-03-02  3:50 ` Manivannan Sadhasivam
@ 2018-03-02  3:50   ` Manivannan Sadhasivam
  -1 siblings, 0 replies; 43+ messages in thread
From: Manivannan Sadhasivam @ 2018-03-02  3:50 UTC (permalink / raw)
  To: linus.walleij, robh+dt, afaerber
  Cc: liuwei, mp-cs, 96boards, devicetree, daniel.thompson,
	amit.kucheria, linux-arm-kernel, linux-gpio, linux-kernel,
	hzhang, bdong, manivannanece23, Manivannan Sadhasivam

Add gpio driver for Actions Semi OWL family S900 SoC. Set of registers
controlling the gpio shares the same register range with pinctrl block.

GPIO registers are organized as 6 banks and each bank controls the
maximum of 32 gpios.

Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
---
 drivers/gpio/Kconfig    |   8 ++
 drivers/gpio/Makefile   |   1 +
 drivers/gpio/gpio-owl.c | 218 ++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 227 insertions(+)
 create mode 100644 drivers/gpio/gpio-owl.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 8dbb2280538d..75533f55ad0e 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -364,6 +364,14 @@ config GPIO_OMAP
 	help
 	  Say yes here to enable GPIO support for TI OMAP SoCs.
 
+config GPIO_OWL
+	tristate "Actions Semi OWL GPIO support"
+	default ARCH_ACTIONS
+	depends on ARCH_ACTIONS || COMPILE_TEST
+	depends on OF_GPIO
+	help
+	  Say yes here to enable GPIO support for Actions Semi OWL SoCs.
+
 config GPIO_PL061
 	bool "PrimeCell PL061 GPIO support"
 	depends on ARM_AMBA
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index cccb0d40846c..b2bb11d4675f 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -91,6 +91,7 @@ obj-$(CONFIG_GPIO_MXC)		+= gpio-mxc.o
 obj-$(CONFIG_GPIO_MXS)		+= gpio-mxs.o
 obj-$(CONFIG_GPIO_OCTEON)	+= gpio-octeon.o
 obj-$(CONFIG_GPIO_OMAP)		+= gpio-omap.o
+obj-$(CONFIG_GPIO_OWL)		+= gpio-owl.o
 obj-$(CONFIG_GPIO_PCA953X)	+= gpio-pca953x.o
 obj-$(CONFIG_GPIO_PCF857X)	+= gpio-pcf857x.o
 obj-$(CONFIG_GPIO_PCH)		+= gpio-pch.o
diff --git a/drivers/gpio/gpio-owl.c b/drivers/gpio/gpio-owl.c
new file mode 100644
index 000000000000..88d88cd82d2a
--- /dev/null
+++ b/drivers/gpio/gpio-owl.c
@@ -0,0 +1,218 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * OWL SoC's GPIO driver
+ *
+ * Copyright (c) 2018 Linaro Ltd.
+ * Author: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+ */
+
+#include <linux/bitops.h>
+#include <linux/err.h>
+#include <linux/gpio/driver.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#define GPIO_OUTEN	0x0000
+#define GPIO_INEN	0x0004
+#define GPIO_DAT	0x0008
+
+#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
+
+struct owl_gpio_port {
+	const char *name;
+	unsigned int offset;
+	unsigned int pins;
+};
+
+struct owl_gpio {
+	struct gpio_chip gpio;
+	const struct owl_gpio_port *port;
+	void __iomem *base;
+	int id;
+};
+
+static void owl_gpio_set_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_gpio *gpio = gpiochip_get_data(chip);
+	const struct owl_gpio_port *port = gpio->port;
+	void __iomem *gpio_base = gpio->base + port->offset;
+
+	/*
+	 * GPIOs have higher priority over other modules, so either setting
+	 * them as OUT or IN is sufficient
+	 */
+	owl_gpio_set_reg(gpio_base + GPIO_OUTEN, offset, true);
+
+	return 0;
+}
+
+static void owl_gpio_free(struct gpio_chip *chip, unsigned int offset)
+{
+	struct owl_gpio *gpio = gpiochip_get_data(chip);
+	const struct owl_gpio_port *port = gpio->port;
+	void __iomem *gpio_base = gpio->base + port->offset;
+
+	/* disable gpio output */
+	owl_gpio_set_reg(gpio_base + GPIO_OUTEN, offset, false);
+
+	/* disable gpio input */
+	owl_gpio_set_reg(gpio_base + GPIO_INEN, offset, false);
+}
+
+static int owl_gpio_get(struct gpio_chip *chip, unsigned int offset)
+{
+	struct owl_gpio *gpio = gpiochip_get_data(chip);
+	const struct owl_gpio_port *port = gpio->port;
+	void __iomem *gpio_base = gpio->base + port->offset;
+	u32 val;
+
+	val = readl_relaxed(gpio_base + GPIO_DAT);
+
+	return !!(val & BIT(offset));
+}
+
+static void owl_gpio_set(struct gpio_chip *chip, unsigned int offset, int value)
+{
+	struct owl_gpio *gpio = gpiochip_get_data(chip);
+	const struct owl_gpio_port *port = gpio->port;
+	void __iomem *gpio_base = gpio->base + port->offset;
+	u32 val;
+
+	val = readl_relaxed(gpio_base + GPIO_DAT);
+
+	if (value)
+		val |= BIT(offset);
+	else
+		val &= ~BIT(offset);
+
+	writel_relaxed(val, gpio_base + GPIO_DAT);
+}
+
+static int owl_gpio_direction_input(struct gpio_chip *chip, unsigned int offset)
+{
+	struct owl_gpio *gpio = gpiochip_get_data(chip);
+	const struct owl_gpio_port *port = gpio->port;
+	void __iomem *gpio_base = gpio->base + port->offset;
+
+	owl_gpio_set_reg(gpio_base + GPIO_OUTEN, offset, false);
+	owl_gpio_set_reg(gpio_base + GPIO_INEN, offset, true);
+
+	return 0;
+}
+
+static int owl_gpio_direction_output(struct gpio_chip *chip,
+				unsigned int offset, int value)
+{
+	struct owl_gpio *gpio = gpiochip_get_data(chip);
+	const struct owl_gpio_port *port = gpio->port;
+	void __iomem *gpio_base = gpio->base + port->offset;
+
+	owl_gpio_set_reg(gpio_base + GPIO_INEN, offset, false);
+	owl_gpio_set_reg(gpio_base + GPIO_OUTEN, offset, true);
+	owl_gpio_set(chip, offset, value);
+
+	return 0;
+}
+
+#define OWL_GPIO_PORT(port, base, count)		\
+	[OWL_GPIO_PORT_##port] = {			\
+		.name = #port,				\
+		.offset = base,				\
+		.pins = count,				\
+	}
+
+static const struct owl_gpio_port s900_gpio_ports[] = {
+	OWL_GPIO_PORT(A, 0x0000, 32),
+	OWL_GPIO_PORT(B, 0x000C, 32),
+	OWL_GPIO_PORT(C, 0x0018, 12),
+	OWL_GPIO_PORT(D, 0x0024, 30),
+	OWL_GPIO_PORT(E, 0x0030, 32),
+	OWL_GPIO_PORT(F, 0x00F0, 8)
+};
+
+static int owl_gpio_probe(struct platform_device *pdev)
+{
+	struct owl_gpio *gpio;
+	const struct owl_gpio_port *port;
+	int ret;
+
+	gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL);
+	if (!gpio)
+		return -ENOMEM;
+
+	gpio->base = of_iomap(pdev->dev.of_node, 0);
+	if (IS_ERR(gpio->base))
+		return PTR_ERR(gpio->base);
+
+	gpio->id = of_alias_get_id(pdev->dev.of_node, "gpio");
+	if (gpio->id < 0)
+		return gpio->id;
+
+	port = &s900_gpio_ports[gpio->id];
+
+	gpio->gpio.request = owl_gpio_request;
+	gpio->gpio.free = owl_gpio_free;
+	gpio->gpio.get = owl_gpio_get;
+	gpio->gpio.set = owl_gpio_set;
+	gpio->gpio.direction_input = owl_gpio_direction_input;
+	gpio->gpio.direction_output = owl_gpio_direction_output;
+
+	gpio->gpio.base = -1;
+	gpio->gpio.parent = &pdev->dev;
+	gpio->gpio.label = port->name;
+	gpio->gpio.ngpio = port->pins;
+
+	gpio->port = port;
+
+	platform_set_drvdata(pdev, gpio);
+
+	ret = devm_gpiochip_add_data(&pdev->dev, &gpio->gpio, gpio);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Failed to register gpiochip\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static const struct of_device_id owl_gpio_of_match[] = {
+	{ .compatible = "actions,s900-gpio", },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, owl_gpio_of_match);
+
+static struct platform_driver owl_gpio_driver = {
+	.driver		= {
+		.name	= "owl-gpio",
+		.of_match_table = owl_gpio_of_match,
+	},
+	.probe		= owl_gpio_probe
+};
+module_platform_driver(owl_gpio_driver);
+
+MODULE_AUTHOR("Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>");
+MODULE_DESCRIPTION("Actions Semi OWL SoCs GPIO driver");
+MODULE_LICENSE("GPL");
-- 
2.14.1

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

* [PATCH v4 08/10] gpio: Add gpio driver for Actions OWL S900 SoC
@ 2018-03-02  3:50   ` Manivannan Sadhasivam
  0 siblings, 0 replies; 43+ messages in thread
From: Manivannan Sadhasivam @ 2018-03-02  3:50 UTC (permalink / raw)
  To: linux-arm-kernel

Add gpio driver for Actions Semi OWL family S900 SoC. Set of registers
controlling the gpio shares the same register range with pinctrl block.

GPIO registers are organized as 6 banks and each bank controls the
maximum of 32 gpios.

Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
---
 drivers/gpio/Kconfig    |   8 ++
 drivers/gpio/Makefile   |   1 +
 drivers/gpio/gpio-owl.c | 218 ++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 227 insertions(+)
 create mode 100644 drivers/gpio/gpio-owl.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 8dbb2280538d..75533f55ad0e 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -364,6 +364,14 @@ config GPIO_OMAP
 	help
 	  Say yes here to enable GPIO support for TI OMAP SoCs.
 
+config GPIO_OWL
+	tristate "Actions Semi OWL GPIO support"
+	default ARCH_ACTIONS
+	depends on ARCH_ACTIONS || COMPILE_TEST
+	depends on OF_GPIO
+	help
+	  Say yes here to enable GPIO support for Actions Semi OWL SoCs.
+
 config GPIO_PL061
 	bool "PrimeCell PL061 GPIO support"
 	depends on ARM_AMBA
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index cccb0d40846c..b2bb11d4675f 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -91,6 +91,7 @@ obj-$(CONFIG_GPIO_MXC)		+= gpio-mxc.o
 obj-$(CONFIG_GPIO_MXS)		+= gpio-mxs.o
 obj-$(CONFIG_GPIO_OCTEON)	+= gpio-octeon.o
 obj-$(CONFIG_GPIO_OMAP)		+= gpio-omap.o
+obj-$(CONFIG_GPIO_OWL)		+= gpio-owl.o
 obj-$(CONFIG_GPIO_PCA953X)	+= gpio-pca953x.o
 obj-$(CONFIG_GPIO_PCF857X)	+= gpio-pcf857x.o
 obj-$(CONFIG_GPIO_PCH)		+= gpio-pch.o
diff --git a/drivers/gpio/gpio-owl.c b/drivers/gpio/gpio-owl.c
new file mode 100644
index 000000000000..88d88cd82d2a
--- /dev/null
+++ b/drivers/gpio/gpio-owl.c
@@ -0,0 +1,218 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * OWL SoC's GPIO driver
+ *
+ * Copyright (c) 2018 Linaro Ltd.
+ * Author: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+ */
+
+#include <linux/bitops.h>
+#include <linux/err.h>
+#include <linux/gpio/driver.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#define GPIO_OUTEN	0x0000
+#define GPIO_INEN	0x0004
+#define GPIO_DAT	0x0008
+
+#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
+
+struct owl_gpio_port {
+	const char *name;
+	unsigned int offset;
+	unsigned int pins;
+};
+
+struct owl_gpio {
+	struct gpio_chip gpio;
+	const struct owl_gpio_port *port;
+	void __iomem *base;
+	int id;
+};
+
+static void owl_gpio_set_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_gpio *gpio = gpiochip_get_data(chip);
+	const struct owl_gpio_port *port = gpio->port;
+	void __iomem *gpio_base = gpio->base + port->offset;
+
+	/*
+	 * GPIOs have higher priority over other modules, so either setting
+	 * them as OUT or IN is sufficient
+	 */
+	owl_gpio_set_reg(gpio_base + GPIO_OUTEN, offset, true);
+
+	return 0;
+}
+
+static void owl_gpio_free(struct gpio_chip *chip, unsigned int offset)
+{
+	struct owl_gpio *gpio = gpiochip_get_data(chip);
+	const struct owl_gpio_port *port = gpio->port;
+	void __iomem *gpio_base = gpio->base + port->offset;
+
+	/* disable gpio output */
+	owl_gpio_set_reg(gpio_base + GPIO_OUTEN, offset, false);
+
+	/* disable gpio input */
+	owl_gpio_set_reg(gpio_base + GPIO_INEN, offset, false);
+}
+
+static int owl_gpio_get(struct gpio_chip *chip, unsigned int offset)
+{
+	struct owl_gpio *gpio = gpiochip_get_data(chip);
+	const struct owl_gpio_port *port = gpio->port;
+	void __iomem *gpio_base = gpio->base + port->offset;
+	u32 val;
+
+	val = readl_relaxed(gpio_base + GPIO_DAT);
+
+	return !!(val & BIT(offset));
+}
+
+static void owl_gpio_set(struct gpio_chip *chip, unsigned int offset, int value)
+{
+	struct owl_gpio *gpio = gpiochip_get_data(chip);
+	const struct owl_gpio_port *port = gpio->port;
+	void __iomem *gpio_base = gpio->base + port->offset;
+	u32 val;
+
+	val = readl_relaxed(gpio_base + GPIO_DAT);
+
+	if (value)
+		val |= BIT(offset);
+	else
+		val &= ~BIT(offset);
+
+	writel_relaxed(val, gpio_base + GPIO_DAT);
+}
+
+static int owl_gpio_direction_input(struct gpio_chip *chip, unsigned int offset)
+{
+	struct owl_gpio *gpio = gpiochip_get_data(chip);
+	const struct owl_gpio_port *port = gpio->port;
+	void __iomem *gpio_base = gpio->base + port->offset;
+
+	owl_gpio_set_reg(gpio_base + GPIO_OUTEN, offset, false);
+	owl_gpio_set_reg(gpio_base + GPIO_INEN, offset, true);
+
+	return 0;
+}
+
+static int owl_gpio_direction_output(struct gpio_chip *chip,
+				unsigned int offset, int value)
+{
+	struct owl_gpio *gpio = gpiochip_get_data(chip);
+	const struct owl_gpio_port *port = gpio->port;
+	void __iomem *gpio_base = gpio->base + port->offset;
+
+	owl_gpio_set_reg(gpio_base + GPIO_INEN, offset, false);
+	owl_gpio_set_reg(gpio_base + GPIO_OUTEN, offset, true);
+	owl_gpio_set(chip, offset, value);
+
+	return 0;
+}
+
+#define OWL_GPIO_PORT(port, base, count)		\
+	[OWL_GPIO_PORT_##port] = {			\
+		.name = #port,				\
+		.offset = base,				\
+		.pins = count,				\
+	}
+
+static const struct owl_gpio_port s900_gpio_ports[] = {
+	OWL_GPIO_PORT(A, 0x0000, 32),
+	OWL_GPIO_PORT(B, 0x000C, 32),
+	OWL_GPIO_PORT(C, 0x0018, 12),
+	OWL_GPIO_PORT(D, 0x0024, 30),
+	OWL_GPIO_PORT(E, 0x0030, 32),
+	OWL_GPIO_PORT(F, 0x00F0, 8)
+};
+
+static int owl_gpio_probe(struct platform_device *pdev)
+{
+	struct owl_gpio *gpio;
+	const struct owl_gpio_port *port;
+	int ret;
+
+	gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL);
+	if (!gpio)
+		return -ENOMEM;
+
+	gpio->base = of_iomap(pdev->dev.of_node, 0);
+	if (IS_ERR(gpio->base))
+		return PTR_ERR(gpio->base);
+
+	gpio->id = of_alias_get_id(pdev->dev.of_node, "gpio");
+	if (gpio->id < 0)
+		return gpio->id;
+
+	port = &s900_gpio_ports[gpio->id];
+
+	gpio->gpio.request = owl_gpio_request;
+	gpio->gpio.free = owl_gpio_free;
+	gpio->gpio.get = owl_gpio_get;
+	gpio->gpio.set = owl_gpio_set;
+	gpio->gpio.direction_input = owl_gpio_direction_input;
+	gpio->gpio.direction_output = owl_gpio_direction_output;
+
+	gpio->gpio.base = -1;
+	gpio->gpio.parent = &pdev->dev;
+	gpio->gpio.label = port->name;
+	gpio->gpio.ngpio = port->pins;
+
+	gpio->port = port;
+
+	platform_set_drvdata(pdev, gpio);
+
+	ret = devm_gpiochip_add_data(&pdev->dev, &gpio->gpio, gpio);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Failed to register gpiochip\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static const struct of_device_id owl_gpio_of_match[] = {
+	{ .compatible = "actions,s900-gpio", },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, owl_gpio_of_match);
+
+static struct platform_driver owl_gpio_driver = {
+	.driver		= {
+		.name	= "owl-gpio",
+		.of_match_table = owl_gpio_of_match,
+	},
+	.probe		= owl_gpio_probe
+};
+module_platform_driver(owl_gpio_driver);
+
+MODULE_AUTHOR("Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>");
+MODULE_DESCRIPTION("Actions Semi OWL SoCs GPIO driver");
+MODULE_LICENSE("GPL");
-- 
2.14.1

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

* [PATCH v4 09/10] MAINTAINERS: Add reviewer for ACTIONS platforms
  2018-03-02  3:50 ` Manivannan Sadhasivam
@ 2018-03-02  3:50   ` Manivannan Sadhasivam
  -1 siblings, 0 replies; 43+ messages in thread
From: Manivannan Sadhasivam @ 2018-03-02  3:50 UTC (permalink / raw)
  To: linus.walleij, robh+dt, afaerber
  Cc: liuwei, mp-cs, 96boards, devicetree, daniel.thompson,
	amit.kucheria, linux-arm-kernel, linux-gpio, linux-kernel,
	hzhang, bdong, manivannanece23, Manivannan Sadhasivam

Since I'll be working on improving support for ACTIONS platforms, adding
myself as the reviewer.

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

diff --git a/MAINTAINERS b/MAINTAINERS
index 9a7f76eadae9..640dabc4c311 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1117,6 +1117,7 @@ T:	git git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc.git
 
 ARM/ACTIONS SEMI ARCHITECTURE
 M:	Andreas Färber <afaerber@suse.de>
+R:	Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
 L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:	Maintained
 N:	owl
-- 
2.14.1

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

* [PATCH v4 09/10] MAINTAINERS: Add reviewer for ACTIONS platforms
@ 2018-03-02  3:50   ` Manivannan Sadhasivam
  0 siblings, 0 replies; 43+ messages in thread
From: Manivannan Sadhasivam @ 2018-03-02  3:50 UTC (permalink / raw)
  To: linux-arm-kernel

Since I'll be working on improving support for ACTIONS platforms, adding
myself as the reviewer.

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

diff --git a/MAINTAINERS b/MAINTAINERS
index 9a7f76eadae9..640dabc4c311 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1117,6 +1117,7 @@ T:	git git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc.git
 
 ARM/ACTIONS SEMI ARCHITECTURE
 M:	Andreas F?rber <afaerber@suse.de>
+R:	Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
 L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
 S:	Maintained
 N:	owl
-- 
2.14.1

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

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

Add S900 pinctrl and gpio entries under ARCH_ACTIONS

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

diff --git a/MAINTAINERS b/MAINTAINERS
index 640dabc4c311..d63793ee545e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1125,10 +1125,14 @@ F:	arch/arm/mach-actions/
 F:	arch/arm/boot/dts/owl-*
 F:	arch/arm64/boot/dts/actions/
 F:	drivers/clocksource/owl-*
+F:	drivers/gpio/gpio-owl.c
+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/gpio/actions,owl-gpio.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] 43+ messages in thread

* [PATCH v4 10/10] MAINTAINERS: Add Actions Semi S900 pinctrl and gpio entries
@ 2018-03-02  3:50   ` Manivannan Sadhasivam
  0 siblings, 0 replies; 43+ messages in thread
From: Manivannan Sadhasivam @ 2018-03-02  3:50 UTC (permalink / raw)
  To: linux-arm-kernel

Add S900 pinctrl and gpio entries under ARCH_ACTIONS

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

diff --git a/MAINTAINERS b/MAINTAINERS
index 640dabc4c311..d63793ee545e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1125,10 +1125,14 @@ F:	arch/arm/mach-actions/
 F:	arch/arm/boot/dts/owl-*
 F:	arch/arm64/boot/dts/actions/
 F:	drivers/clocksource/owl-*
+F:	drivers/gpio/gpio-owl.c
+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/gpio/actions,owl-gpio.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] 43+ messages in thread

* Re: [PATCH v4 01/10] dt-bindings: pinctrl: Add bindings for Actions S900 SoC
  2018-03-02  3:50   ` Manivannan Sadhasivam
@ 2018-03-02 13:10     ` Linus Walleij
  -1 siblings, 0 replies; 43+ messages in thread
From: Linus Walleij @ 2018-03-02 13:10 UTC (permalink / raw)
  To: Manivannan Sadhasivam
  Cc: Rob Herring, Andreas Färber, liuwei, mp-cs, 96boards,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Daniel Thompson, Amit Kucheria, Linux ARM,
	open list:GPIO SUBSYSTEM, linux-kernel, hzhang, bdong,
	Mani Sadhasivam

On Fri, Mar 2, 2018 at 4:50 AM, Manivannan Sadhasivam
<manivannan.sadhasivam@linaro.org> wrote:

> Add pinctrl bindings for Actions Semi S900 SoC
>
> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
> Reviewed-by: Rob Herring <robh@kernel.org>

Patch applied.

These bindings are definately good looking and finalized,
so no point in keeping iterating them, good work!

Yours,
Linus Walleij

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

* [PATCH v4 01/10] dt-bindings: pinctrl: Add bindings for Actions S900 SoC
@ 2018-03-02 13:10     ` Linus Walleij
  0 siblings, 0 replies; 43+ messages in thread
From: Linus Walleij @ 2018-03-02 13:10 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Mar 2, 2018 at 4:50 AM, Manivannan Sadhasivam
<manivannan.sadhasivam@linaro.org> wrote:

> Add pinctrl bindings for Actions Semi S900 SoC
>
> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
> Reviewed-by: Rob Herring <robh@kernel.org>

Patch applied.

These bindings are definately good looking and finalized,
so no point in keeping iterating them, good work!

Yours,
Linus Walleij

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

* Re: [PATCH v4 02/10] arm64: dts: actions: Add pinctrl node for S900
  2018-03-02  3:50   ` Manivannan Sadhasivam
@ 2018-03-02 13:11     ` Linus Walleij
  -1 siblings, 0 replies; 43+ messages in thread
From: Linus Walleij @ 2018-03-02 13:11 UTC (permalink / raw)
  To: Manivannan Sadhasivam
  Cc: Rob Herring, Andreas Färber, liuwei, mp-cs, 96boards,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Daniel Thompson, Amit Kucheria, Linux ARM,
	open list:GPIO SUBSYSTEM, linux-kernel, hzhang, bdong,
	Mani Sadhasivam

On Fri, Mar 2, 2018 at 4:50 AM, Manivannan Sadhasivam
<manivannan.sadhasivam@linaro.org> wrote:

> Add pinctrl nodes for Actions Semi S900 SoC
>
> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>

Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

Please funnel this patch through the ARM SoC
tree.

Yours,
Linus Walleij

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

* [PATCH v4 02/10] arm64: dts: actions: Add pinctrl node for S900
@ 2018-03-02 13:11     ` Linus Walleij
  0 siblings, 0 replies; 43+ messages in thread
From: Linus Walleij @ 2018-03-02 13:11 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Mar 2, 2018 at 4:50 AM, Manivannan Sadhasivam
<manivannan.sadhasivam@linaro.org> wrote:

> Add pinctrl nodes for Actions Semi S900 SoC
>
> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>

Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

Please funnel this patch through the ARM SoC
tree.

Yours,
Linus Walleij

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

* Re: [PATCH v4 03/10] arm64: actions: Enable PINCTRL in platforms Kconfig
  2018-03-02  3:50   ` Manivannan Sadhasivam
@ 2018-03-02 13:12     ` Linus Walleij
  -1 siblings, 0 replies; 43+ messages in thread
From: Linus Walleij @ 2018-03-02 13:12 UTC (permalink / raw)
  To: Manivannan Sadhasivam
  Cc: Rob Herring, Andreas Färber, liuwei, mp-cs, 96boards,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Daniel Thompson, Amit Kucheria, Linux ARM,
	open list:GPIO SUBSYSTEM, linux-kernel, hzhang, bdong,
	Mani Sadhasivam

On Fri, Mar 2, 2018 at 4:50 AM, Manivannan Sadhasivam
<manivannan.sadhasivam@linaro.org> wrote:

> Select PINCTRL for Actions Semi SoCs
>
> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>

Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

Please funnel this patch through the ARM SoC tree.

Yours,
Linus Walleij

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

* [PATCH v4 03/10] arm64: actions: Enable PINCTRL in platforms Kconfig
@ 2018-03-02 13:12     ` Linus Walleij
  0 siblings, 0 replies; 43+ messages in thread
From: Linus Walleij @ 2018-03-02 13:12 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Mar 2, 2018 at 4:50 AM, Manivannan Sadhasivam
<manivannan.sadhasivam@linaro.org> wrote:

> Select PINCTRL for Actions Semi SoCs
>
> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>

Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

Please funnel this patch through the ARM SoC tree.

Yours,
Linus Walleij

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

* Re: [PATCH v4 04/10] pinctrl: actions: Add Actions S900 pinctrl driver
  2018-03-02  3:50   ` Manivannan Sadhasivam
@ 2018-03-02 13:21     ` Linus Walleij
  -1 siblings, 0 replies; 43+ messages in thread
From: Linus Walleij @ 2018-03-02 13:21 UTC (permalink / raw)
  To: Manivannan Sadhasivam
  Cc: Rob Herring, Andreas Färber, liuwei, mp-cs, 96boards,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Daniel Thompson, Amit Kucheria, Linux ARM,
	open list:GPIO SUBSYSTEM, linux-kernel, hzhang, bdong,
	Mani Sadhasivam

On Fri, Mar 2, 2018 at 4:50 AM, Manivannan Sadhasivam
<manivannan.sadhasivam@linaro.org> wrote:

> Add pinctrl driver for Actions Semi S900 SoC. The driver supports
> pinctrl, pinmux and pinconf functionalities through a range of registers
> common to both gpio driver and pinctrl driver.
>
> Pinmux functionality is available only for the pin groups while the
> pinconf functionality is available for both pin groups and individual
> pins.
>
> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>

Seems like this is pretty much finished.

Let's see if you can collect some ACKs before we apply it.

Now just minor things remain.

Random chosen example:

> +static unsigned int lvds_e_drv_pads[] = {
> +       LVDS_EEP,
> +       LVDS_EEN,
> +       LVDS_EDP,
> +       LVDS_EDN,
> +       LVDS_ECP,
> +       LVDS_ECN,
> +       LVDS_EBP,
> +       LVDS_EBN,
> +};
> +
> +static unsigned int sd0_d3_d0_drv_pads[] = {
> +       SD0_D3,
> +       SD0_D2,
> +       SD0_D1,
> +       SD0_D0,
> +};

People (e.g. Torvalds) sometimes get upset with files with too many lines
in them. This file has a lot of lines. A lot of pin control drivers try to cut
down the lines with macros, and you do it in some places too,
would you consider to see if you can cut down these tables with
macros?

S900_PADS(LVDS_EEP, LVDS_EEN, LVDS_EDP, LVDS_EDN,
                    LVDS_ECP, LVDS_ECN, LVDS_EBP, LVDS_EBN);
S900_PADS(SD0_D3, SD0_D2, SD0_D1, SD0_D0);

Would be so much more compact.

It's not the biggest problem though.

Yours,
Linus Walleij

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

* [PATCH v4 04/10] pinctrl: actions: Add Actions S900 pinctrl driver
@ 2018-03-02 13:21     ` Linus Walleij
  0 siblings, 0 replies; 43+ messages in thread
From: Linus Walleij @ 2018-03-02 13:21 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Mar 2, 2018 at 4:50 AM, Manivannan Sadhasivam
<manivannan.sadhasivam@linaro.org> wrote:

> Add pinctrl driver for Actions Semi S900 SoC. The driver supports
> pinctrl, pinmux and pinconf functionalities through a range of registers
> common to both gpio driver and pinctrl driver.
>
> Pinmux functionality is available only for the pin groups while the
> pinconf functionality is available for both pin groups and individual
> pins.
>
> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>

Seems like this is pretty much finished.

Let's see if you can collect some ACKs before we apply it.

Now just minor things remain.

Random chosen example:

> +static unsigned int lvds_e_drv_pads[] = {
> +       LVDS_EEP,
> +       LVDS_EEN,
> +       LVDS_EDP,
> +       LVDS_EDN,
> +       LVDS_ECP,
> +       LVDS_ECN,
> +       LVDS_EBP,
> +       LVDS_EBN,
> +};
> +
> +static unsigned int sd0_d3_d0_drv_pads[] = {
> +       SD0_D3,
> +       SD0_D2,
> +       SD0_D1,
> +       SD0_D0,
> +};

People (e.g. Torvalds) sometimes get upset with files with too many lines
in them. This file has a lot of lines. A lot of pin control drivers try to cut
down the lines with macros, and you do it in some places too,
would you consider to see if you can cut down these tables with
macros?

S900_PADS(LVDS_EEP, LVDS_EEN, LVDS_EDP, LVDS_EDN,
                    LVDS_ECP, LVDS_ECN, LVDS_EBP, LVDS_EBN);
S900_PADS(SD0_D3, SD0_D2, SD0_D1, SD0_D0);

Would be so much more compact.

It's not the biggest problem though.

Yours,
Linus Walleij

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

* Re: [PATCH v4 09/10] MAINTAINERS: Add reviewer for ACTIONS platforms
  2018-03-02  3:50   ` Manivannan Sadhasivam
@ 2018-03-02 13:23     ` Linus Walleij
  -1 siblings, 0 replies; 43+ messages in thread
From: Linus Walleij @ 2018-03-02 13:23 UTC (permalink / raw)
  To: Manivannan Sadhasivam, Andreas Färber
  Cc: Rob Herring, liuwei, mp-cs, 96boards,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Daniel Thompson, Amit Kucheria, Linux ARM,
	open list:GPIO SUBSYSTEM, linux-kernel, hzhang, bdong,
	Mani Sadhasivam

On Fri, Mar 2, 2018 at 4:50 AM, Manivannan Sadhasivam
<manivannan.sadhasivam@linaro.org> wrote:

> Since I'll be working on improving support for ACTIONS platforms, adding
> myself as the reviewer.
>
> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>

Andreas it would be great of I can have your ACK on this so I
can merge the new pinctrl drivers and maintainer changes
through the pinctrl tree.

Yours,
Linus Walleij

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

* [PATCH v4 09/10] MAINTAINERS: Add reviewer for ACTIONS platforms
@ 2018-03-02 13:23     ` Linus Walleij
  0 siblings, 0 replies; 43+ messages in thread
From: Linus Walleij @ 2018-03-02 13:23 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Mar 2, 2018 at 4:50 AM, Manivannan Sadhasivam
<manivannan.sadhasivam@linaro.org> wrote:

> Since I'll be working on improving support for ACTIONS platforms, adding
> myself as the reviewer.
>
> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>

Andreas it would be great of I can have your ACK on this so I
can merge the new pinctrl drivers and maintainer changes
through the pinctrl tree.

Yours,
Linus Walleij

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

* Re: [PATCH v4 04/10] pinctrl: actions: Add Actions S900 pinctrl driver
  2018-03-02 13:21     ` Linus Walleij
@ 2018-03-02 17:56       ` Manivannan Sadhasivam
  -1 siblings, 0 replies; 43+ messages in thread
From: Manivannan Sadhasivam @ 2018-03-02 17:56 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Rob Herring, Andreas Färber, liuwei, mp-cs, 96boards,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Daniel Thompson, Amit Kucheria, Linux ARM,
	open list:GPIO SUBSYSTEM, linux-kernel, hzhang, bdong,
	Mani Sadhasivam

Hi Linus,

On Fri, Mar 02, 2018 at 02:21:37PM +0100, Linus Walleij wrote:
> On Fri, Mar 2, 2018 at 4:50 AM, Manivannan Sadhasivam
> <manivannan.sadhasivam@linaro.org> wrote:
> 
> > Add pinctrl driver for Actions Semi S900 SoC. The driver supports
> > pinctrl, pinmux and pinconf functionalities through a range of registers
> > common to both gpio driver and pinctrl driver.
> >
> > Pinmux functionality is available only for the pin groups while the
> > pinconf functionality is available for both pin groups and individual
> > pins.
> >
> > Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
> 
> Seems like this is pretty much finished.
> 
> Let's see if you can collect some ACKs before we apply it.
> 

Andreas is at Embedded World conference. I hope once he is
back, he will have a look at this patchset.

> Now just minor things remain.
> 
> Random chosen example:
> 
> > +static unsigned int lvds_e_drv_pads[] = {
> > +       LVDS_EEP,
> > +       LVDS_EEN,
> > +       LVDS_EDP,
> > +       LVDS_EDN,
> > +       LVDS_ECP,
> > +       LVDS_ECN,
> > +       LVDS_EBP,
> > +       LVDS_EBN,
> > +};
> > +
> > +static unsigned int sd0_d3_d0_drv_pads[] = {
> > +       SD0_D3,
> > +       SD0_D2,
> > +       SD0_D1,
> > +       SD0_D0,
> > +};
> 
> People (e.g. Torvalds) sometimes get upset with files with too many lines
> in them. This file has a lot of lines. A lot of pin control drivers try to cut
> down the lines with macros, and you do it in some places too,
> would you consider to see if you can cut down these tables with
> macros?
> 
> S900_PADS(LVDS_EEP, LVDS_EEN, LVDS_EDP, LVDS_EDN,
>                     LVDS_ECP, LVDS_ECN, LVDS_EBP, LVDS_EBN);
> S900_PADS(SD0_D3, SD0_D2, SD0_D1, SD0_D0);
> 

I don't think it would be efficient to use macros here. However, I can
align the pads and func definitions in a single line. This will also
save a considerable amount of space.

Thanks,
Mani

> Would be so much more compact.
> 
> It's not the biggest problem though.
> 
> Yours,
> Linus Walleij

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

* [PATCH v4 04/10] pinctrl: actions: Add Actions S900 pinctrl driver
@ 2018-03-02 17:56       ` Manivannan Sadhasivam
  0 siblings, 0 replies; 43+ messages in thread
From: Manivannan Sadhasivam @ 2018-03-02 17:56 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Linus,

On Fri, Mar 02, 2018 at 02:21:37PM +0100, Linus Walleij wrote:
> On Fri, Mar 2, 2018 at 4:50 AM, Manivannan Sadhasivam
> <manivannan.sadhasivam@linaro.org> wrote:
> 
> > Add pinctrl driver for Actions Semi S900 SoC. The driver supports
> > pinctrl, pinmux and pinconf functionalities through a range of registers
> > common to both gpio driver and pinctrl driver.
> >
> > Pinmux functionality is available only for the pin groups while the
> > pinconf functionality is available for both pin groups and individual
> > pins.
> >
> > Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
> 
> Seems like this is pretty much finished.
> 
> Let's see if you can collect some ACKs before we apply it.
> 

Andreas is at Embedded World conference. I hope once he is
back, he will have a look at this patchset.

> Now just minor things remain.
> 
> Random chosen example:
> 
> > +static unsigned int lvds_e_drv_pads[] = {
> > +       LVDS_EEP,
> > +       LVDS_EEN,
> > +       LVDS_EDP,
> > +       LVDS_EDN,
> > +       LVDS_ECP,
> > +       LVDS_ECN,
> > +       LVDS_EBP,
> > +       LVDS_EBN,
> > +};
> > +
> > +static unsigned int sd0_d3_d0_drv_pads[] = {
> > +       SD0_D3,
> > +       SD0_D2,
> > +       SD0_D1,
> > +       SD0_D0,
> > +};
> 
> People (e.g. Torvalds) sometimes get upset with files with too many lines
> in them. This file has a lot of lines. A lot of pin control drivers try to cut
> down the lines with macros, and you do it in some places too,
> would you consider to see if you can cut down these tables with
> macros?
> 
> S900_PADS(LVDS_EEP, LVDS_EEN, LVDS_EDP, LVDS_EDN,
>                     LVDS_ECP, LVDS_ECN, LVDS_EBP, LVDS_EBN);
> S900_PADS(SD0_D3, SD0_D2, SD0_D1, SD0_D0);
> 

I don't think it would be efficient to use macros here. However, I can
align the pads and func definitions in a single line. This will also
save a considerable amount of space.

Thanks,
Mani

> Would be so much more compact.
> 
> It's not the biggest problem though.
> 
> Yours,
> Linus Walleij

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

* Re: [PATCH v4 05/10] dt-bindings: gpio: Add gpio nodes for Actions S900 SoC
  2018-03-02  3:50   ` Manivannan Sadhasivam
@ 2018-03-07 19:52     ` Rob Herring
  -1 siblings, 0 replies; 43+ messages in thread
From: Rob Herring @ 2018-03-07 19:52 UTC (permalink / raw)
  To: Manivannan Sadhasivam
  Cc: linus.walleij, afaerber, liuwei, mp-cs, 96boards, devicetree,
	daniel.thompson, amit.kucheria, linux-arm-kernel, linux-gpio,
	linux-kernel, hzhang, bdong, manivannanece23

On Fri, Mar 02, 2018 at 09:20:40AM +0530, Manivannan Sadhasivam wrote:
> Add gpio nodes for Actions Semi S900 SoC.
> 
> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
> ---
>  .../devicetree/bindings/gpio/actions,owl-gpio.txt  | 95 ++++++++++++++++++++++
>  1 file changed, 95 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/gpio/actions,owl-gpio.txt
> 
> diff --git a/Documentation/devicetree/bindings/gpio/actions,owl-gpio.txt b/Documentation/devicetree/bindings/gpio/actions,owl-gpio.txt
> new file mode 100644
> index 000000000000..d2939ca6cfaf
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/gpio/actions,owl-gpio.txt
> @@ -0,0 +1,95 @@
> +* Actions Semi OWL GPIO controller bindings
> +
> +The GPIOs are organized as individual banks/ports with variable number
> +of GPIOs. Each bank is represented as an individual GPIO controller.
> +
> +Required properties:
> +- compatible            : Should be "actions,s900-gpio"
> +- reg                   : Address and range of the GPIO controller registers.
> +- gpio-controller       : Marks the device node as a GPIO controller.
> +- #gpio-cells           : Should be <2>. The first cell is the gpio number
> +                          and the second cell is used to specify 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
> +
> +Optional properties:
> +- gpio-ranges           : Mapping between GPIO and pinctrl
> +
> +Note: Each GPIO port should have an alias correctly numbered in "aliases"
> +node.

Why? Please don't use aliases for gpios.

> +
> +Examples:
> +
> +aliases {
> +        gpio0 = &gpioa;
> +        gpio1 = &gpiob;
> +        gpio2 = &gpioc;
> +        gpio3 = &gpiod;
> +        gpio4 = &gpioe;
> +        gpio5 = &gpiof;
> +};
> +
> +       gpioa: gpioa@e01b0000 {

Use generic node names (gpio).

> +               compatible = "actions,s900-gpio";
> +               reg = <0x0 0xe01b0000 0x0 0x1000>;
> +               gpio-controller;
> +               #gpio-cells = <2>;
> +               gpio-ranges = <&pinctrl 0 0 32>;
> +               interrupt-controller;
> +               #interrupt-cells = <2>;
> +       };
> +
> +       gpiob: gpiob@e01b0000 {

Ah, but your are duplicating addresses here which you shouldn't do 
either. These should be all one node if you can avoid overlapping.

> +               compatible = "actions,s900-gpio";
> +               reg = <0x0 0xe01b0000 0x0 0x1000>;
> +               gpio-controller;
> +               #gpio-cells = <2>;
> +               gpio-ranges = <&pinctrl 0 32 32>;
> +               interrupt-controller;
> +               #interrupt-cells = <2>;
> +       };
> +
> +       gpioc: gpioc@e01b0000 {
> +               compatible = "actions,s900-gpio";
> +               reg = <0x0 0xe01b0000 0x0 0x1000>;
> +               gpio-controller;
> +               #gpio-cells = <2>;
> +               gpio-ranges = <&pinctrl 0 64 12>;
> +               interrupt-controller;
> +               #interrupt-cells = <2>;
> +       };
> +
> +       gpiod: gpiod@e01b0000 {
> +               compatible = "actions,s900-gpio";
> +               reg = <0x0 0xe01b0000 0x0 0x1000>;
> +               gpio-controller;
> +               #gpio-cells = <2>;
> +               gpio-ranges = <&pinctrl 0 76 30>;
> +               interrupt-controller;
> +               #interrupt-cells = <2>;
> +       };
> +
> +       gpioe: gpioe@e01b0000 {
> +               compatible = "actions,s900-gpio";
> +               reg = <0x0 0xe01b0000 0x0 0x1000>;
> +               gpio-controller;
> +               #gpio-cells = <2>;
> +               gpio-ranges = <&pinctrl 0 106 32>;
> +               interrupt-controller;
> +               #interrupt-cells = <2>;
> +       };
> +
> +       gpiof: gpiof@e01b0000 {
> +               compatible = "actions,s900-gpio";
> +               reg = <0x0 0xe01b0000 0x0 0x1000>;
> +               gpio-controller;
> +               #gpio-cells = <2>;
> +               gpio-ranges = <&pinctrl 0 138 8>;
> +               interrupt-controller;
> +               #interrupt-cells = <2>;
> +       };
> -- 
> 2.14.1
> 

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

* [PATCH v4 05/10] dt-bindings: gpio: Add gpio nodes for Actions S900 SoC
@ 2018-03-07 19:52     ` Rob Herring
  0 siblings, 0 replies; 43+ messages in thread
From: Rob Herring @ 2018-03-07 19:52 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Mar 02, 2018 at 09:20:40AM +0530, Manivannan Sadhasivam wrote:
> Add gpio nodes for Actions Semi S900 SoC.
> 
> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
> ---
>  .../devicetree/bindings/gpio/actions,owl-gpio.txt  | 95 ++++++++++++++++++++++
>  1 file changed, 95 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/gpio/actions,owl-gpio.txt
> 
> diff --git a/Documentation/devicetree/bindings/gpio/actions,owl-gpio.txt b/Documentation/devicetree/bindings/gpio/actions,owl-gpio.txt
> new file mode 100644
> index 000000000000..d2939ca6cfaf
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/gpio/actions,owl-gpio.txt
> @@ -0,0 +1,95 @@
> +* Actions Semi OWL GPIO controller bindings
> +
> +The GPIOs are organized as individual banks/ports with variable number
> +of GPIOs. Each bank is represented as an individual GPIO controller.
> +
> +Required properties:
> +- compatible            : Should be "actions,s900-gpio"
> +- reg                   : Address and range of the GPIO controller registers.
> +- gpio-controller       : Marks the device node as a GPIO controller.
> +- #gpio-cells           : Should be <2>. The first cell is the gpio number
> +                          and the second cell is used to specify 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
> +
> +Optional properties:
> +- gpio-ranges           : Mapping between GPIO and pinctrl
> +
> +Note: Each GPIO port should have an alias correctly numbered in "aliases"
> +node.

Why? Please don't use aliases for gpios.

> +
> +Examples:
> +
> +aliases {
> +        gpio0 = &gpioa;
> +        gpio1 = &gpiob;
> +        gpio2 = &gpioc;
> +        gpio3 = &gpiod;
> +        gpio4 = &gpioe;
> +        gpio5 = &gpiof;
> +};
> +
> +       gpioa: gpioa at e01b0000 {

Use generic node names (gpio).

> +               compatible = "actions,s900-gpio";
> +               reg = <0x0 0xe01b0000 0x0 0x1000>;
> +               gpio-controller;
> +               #gpio-cells = <2>;
> +               gpio-ranges = <&pinctrl 0 0 32>;
> +               interrupt-controller;
> +               #interrupt-cells = <2>;
> +       };
> +
> +       gpiob: gpiob at e01b0000 {

Ah, but your are duplicating addresses here which you shouldn't do 
either. These should be all one node if you can avoid overlapping.

> +               compatible = "actions,s900-gpio";
> +               reg = <0x0 0xe01b0000 0x0 0x1000>;
> +               gpio-controller;
> +               #gpio-cells = <2>;
> +               gpio-ranges = <&pinctrl 0 32 32>;
> +               interrupt-controller;
> +               #interrupt-cells = <2>;
> +       };
> +
> +       gpioc: gpioc at e01b0000 {
> +               compatible = "actions,s900-gpio";
> +               reg = <0x0 0xe01b0000 0x0 0x1000>;
> +               gpio-controller;
> +               #gpio-cells = <2>;
> +               gpio-ranges = <&pinctrl 0 64 12>;
> +               interrupt-controller;
> +               #interrupt-cells = <2>;
> +       };
> +
> +       gpiod: gpiod at e01b0000 {
> +               compatible = "actions,s900-gpio";
> +               reg = <0x0 0xe01b0000 0x0 0x1000>;
> +               gpio-controller;
> +               #gpio-cells = <2>;
> +               gpio-ranges = <&pinctrl 0 76 30>;
> +               interrupt-controller;
> +               #interrupt-cells = <2>;
> +       };
> +
> +       gpioe: gpioe at e01b0000 {
> +               compatible = "actions,s900-gpio";
> +               reg = <0x0 0xe01b0000 0x0 0x1000>;
> +               gpio-controller;
> +               #gpio-cells = <2>;
> +               gpio-ranges = <&pinctrl 0 106 32>;
> +               interrupt-controller;
> +               #interrupt-cells = <2>;
> +       };
> +
> +       gpiof: gpiof at e01b0000 {
> +               compatible = "actions,s900-gpio";
> +               reg = <0x0 0xe01b0000 0x0 0x1000>;
> +               gpio-controller;
> +               #gpio-cells = <2>;
> +               gpio-ranges = <&pinctrl 0 138 8>;
> +               interrupt-controller;
> +               #interrupt-cells = <2>;
> +       };
> -- 
> 2.14.1
> 

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

* Re: [PATCH v4 05/10] dt-bindings: gpio: Add gpio nodes for Actions S900 SoC
  2018-03-07 19:52     ` Rob Herring
@ 2018-03-07 20:05       ` Manivannan Sadhasivam
  -1 siblings, 0 replies; 43+ messages in thread
From: Manivannan Sadhasivam @ 2018-03-07 20:05 UTC (permalink / raw)
  To: Rob Herring
  Cc: linus.walleij, afaerber, liuwei, mp-cs, 96boards, devicetree,
	daniel.thompson, amit.kucheria, linux-arm-kernel, linux-gpio,
	linux-kernel, hzhang, bdong, manivannanece23

Hi Rob,

Thanks for the review.

On Wed, Mar 07, 2018 at 01:52:33PM -0600, Rob Herring wrote:
> On Fri, Mar 02, 2018 at 09:20:40AM +0530, Manivannan Sadhasivam wrote:
> > Add gpio nodes for Actions Semi S900 SoC.
> > 
> > Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
> > ---
> >  .../devicetree/bindings/gpio/actions,owl-gpio.txt  | 95 ++++++++++++++++++++++
> >  1 file changed, 95 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/gpio/actions,owl-gpio.txt
> > 
> > diff --git a/Documentation/devicetree/bindings/gpio/actions,owl-gpio.txt b/Documentation/devicetree/bindings/gpio/actions,owl-gpio.txt
> > new file mode 100644
> > index 000000000000..d2939ca6cfaf
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/gpio/actions,owl-gpio.txt
> > @@ -0,0 +1,95 @@
> > +* Actions Semi OWL GPIO controller bindings
> > +
> > +The GPIOs are organized as individual banks/ports with variable number
> > +of GPIOs. Each bank is represented as an individual GPIO controller.
> > +
> > +Required properties:
> > +- compatible            : Should be "actions,s900-gpio"
> > +- reg                   : Address and range of the GPIO controller registers.
> > +- gpio-controller       : Marks the device node as a GPIO controller.
> > +- #gpio-cells           : Should be <2>. The first cell is the gpio number
> > +                          and the second cell is used to specify 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
> > +
> > +Optional properties:
> > +- gpio-ranges           : Mapping between GPIO and pinctrl
> > +
> > +Note: Each GPIO port should have an alias correctly numbered in "aliases"
> > +node.
> 
> Why? Please don't use aliases for gpios.
> 

Okay.

> > +
> > +Examples:
> > +
> > +aliases {
> > +        gpio0 = &gpioa;
> > +        gpio1 = &gpiob;
> > +        gpio2 = &gpioc;
> > +        gpio3 = &gpiod;
> > +        gpio4 = &gpioe;
> > +        gpio5 = &gpiof;
> > +};
> > +
> > +       gpioa: gpioa@e01b0000 {
> 
> Use generic node names (gpio).
>

Okay. But how about the label? Should it be gpioa... or gpio1...
In datasheet, the registers are named from gpioa to gpiof.
 
> > +               compatible = "actions,s900-gpio";
> > +               reg = <0x0 0xe01b0000 0x0 0x1000>;
> > +               gpio-controller;
> > +               #gpio-cells = <2>;
> > +               gpio-ranges = <&pinctrl 0 0 32>;
> > +               interrupt-controller;
> > +               #interrupt-cells = <2>;
> > +       };
> > +
> > +       gpiob: gpiob@e01b0000 {
> 
> Ah, but your are duplicating addresses here which you shouldn't do 
> either. These should be all one node if you can avoid overlapping.
>

Hmmm. Okay. Then I can use the sub address for all nodes. But having a single
node doesn't makes sense here since each bank has its own interrupt
domain and somewhat resembles an individual controller.

Thanks,
Mani

> > +               compatible = "actions,s900-gpio";
> > +               reg = <0x0 0xe01b0000 0x0 0x1000>;
> > +               gpio-controller;
> > +               #gpio-cells = <2>;
> > +               gpio-ranges = <&pinctrl 0 32 32>;
> > +               interrupt-controller;
> > +               #interrupt-cells = <2>;
> > +       };
> > +
> > +       gpioc: gpioc@e01b0000 {
> > +               compatible = "actions,s900-gpio";
> > +               reg = <0x0 0xe01b0000 0x0 0x1000>;
> > +               gpio-controller;
> > +               #gpio-cells = <2>;
> > +               gpio-ranges = <&pinctrl 0 64 12>;
> > +               interrupt-controller;
> > +               #interrupt-cells = <2>;
> > +       };
> > +
> > +       gpiod: gpiod@e01b0000 {
> > +               compatible = "actions,s900-gpio";
> > +               reg = <0x0 0xe01b0000 0x0 0x1000>;
> > +               gpio-controller;
> > +               #gpio-cells = <2>;
> > +               gpio-ranges = <&pinctrl 0 76 30>;
> > +               interrupt-controller;
> > +               #interrupt-cells = <2>;
> > +       };
> > +
> > +       gpioe: gpioe@e01b0000 {
> > +               compatible = "actions,s900-gpio";
> > +               reg = <0x0 0xe01b0000 0x0 0x1000>;
> > +               gpio-controller;
> > +               #gpio-cells = <2>;
> > +               gpio-ranges = <&pinctrl 0 106 32>;
> > +               interrupt-controller;
> > +               #interrupt-cells = <2>;
> > +       };
> > +
> > +       gpiof: gpiof@e01b0000 {
> > +               compatible = "actions,s900-gpio";
> > +               reg = <0x0 0xe01b0000 0x0 0x1000>;
> > +               gpio-controller;
> > +               #gpio-cells = <2>;
> > +               gpio-ranges = <&pinctrl 0 138 8>;
> > +               interrupt-controller;
> > +               #interrupt-cells = <2>;
> > +       };
> > -- 
> > 2.14.1
> > 

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

* [PATCH v4 05/10] dt-bindings: gpio: Add gpio nodes for Actions S900 SoC
@ 2018-03-07 20:05       ` Manivannan Sadhasivam
  0 siblings, 0 replies; 43+ messages in thread
From: Manivannan Sadhasivam @ 2018-03-07 20:05 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Rob,

Thanks for the review.

On Wed, Mar 07, 2018 at 01:52:33PM -0600, Rob Herring wrote:
> On Fri, Mar 02, 2018 at 09:20:40AM +0530, Manivannan Sadhasivam wrote:
> > Add gpio nodes for Actions Semi S900 SoC.
> > 
> > Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
> > ---
> >  .../devicetree/bindings/gpio/actions,owl-gpio.txt  | 95 ++++++++++++++++++++++
> >  1 file changed, 95 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/gpio/actions,owl-gpio.txt
> > 
> > diff --git a/Documentation/devicetree/bindings/gpio/actions,owl-gpio.txt b/Documentation/devicetree/bindings/gpio/actions,owl-gpio.txt
> > new file mode 100644
> > index 000000000000..d2939ca6cfaf
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/gpio/actions,owl-gpio.txt
> > @@ -0,0 +1,95 @@
> > +* Actions Semi OWL GPIO controller bindings
> > +
> > +The GPIOs are organized as individual banks/ports with variable number
> > +of GPIOs. Each bank is represented as an individual GPIO controller.
> > +
> > +Required properties:
> > +- compatible            : Should be "actions,s900-gpio"
> > +- reg                   : Address and range of the GPIO controller registers.
> > +- gpio-controller       : Marks the device node as a GPIO controller.
> > +- #gpio-cells           : Should be <2>. The first cell is the gpio number
> > +                          and the second cell is used to specify 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
> > +
> > +Optional properties:
> > +- gpio-ranges           : Mapping between GPIO and pinctrl
> > +
> > +Note: Each GPIO port should have an alias correctly numbered in "aliases"
> > +node.
> 
> Why? Please don't use aliases for gpios.
> 

Okay.

> > +
> > +Examples:
> > +
> > +aliases {
> > +        gpio0 = &gpioa;
> > +        gpio1 = &gpiob;
> > +        gpio2 = &gpioc;
> > +        gpio3 = &gpiod;
> > +        gpio4 = &gpioe;
> > +        gpio5 = &gpiof;
> > +};
> > +
> > +       gpioa: gpioa at e01b0000 {
> 
> Use generic node names (gpio).
>

Okay. But how about the label? Should it be gpioa... or gpio1...
In datasheet, the registers are named from gpioa to gpiof.
 
> > +               compatible = "actions,s900-gpio";
> > +               reg = <0x0 0xe01b0000 0x0 0x1000>;
> > +               gpio-controller;
> > +               #gpio-cells = <2>;
> > +               gpio-ranges = <&pinctrl 0 0 32>;
> > +               interrupt-controller;
> > +               #interrupt-cells = <2>;
> > +       };
> > +
> > +       gpiob: gpiob at e01b0000 {
> 
> Ah, but your are duplicating addresses here which you shouldn't do 
> either. These should be all one node if you can avoid overlapping.
>

Hmmm. Okay. Then I can use the sub address for all nodes. But having a single
node doesn't makes sense here since each bank has its own interrupt
domain and somewhat resembles an individual controller.

Thanks,
Mani

> > +               compatible = "actions,s900-gpio";
> > +               reg = <0x0 0xe01b0000 0x0 0x1000>;
> > +               gpio-controller;
> > +               #gpio-cells = <2>;
> > +               gpio-ranges = <&pinctrl 0 32 32>;
> > +               interrupt-controller;
> > +               #interrupt-cells = <2>;
> > +       };
> > +
> > +       gpioc: gpioc at e01b0000 {
> > +               compatible = "actions,s900-gpio";
> > +               reg = <0x0 0xe01b0000 0x0 0x1000>;
> > +               gpio-controller;
> > +               #gpio-cells = <2>;
> > +               gpio-ranges = <&pinctrl 0 64 12>;
> > +               interrupt-controller;
> > +               #interrupt-cells = <2>;
> > +       };
> > +
> > +       gpiod: gpiod at e01b0000 {
> > +               compatible = "actions,s900-gpio";
> > +               reg = <0x0 0xe01b0000 0x0 0x1000>;
> > +               gpio-controller;
> > +               #gpio-cells = <2>;
> > +               gpio-ranges = <&pinctrl 0 76 30>;
> > +               interrupt-controller;
> > +               #interrupt-cells = <2>;
> > +       };
> > +
> > +       gpioe: gpioe at e01b0000 {
> > +               compatible = "actions,s900-gpio";
> > +               reg = <0x0 0xe01b0000 0x0 0x1000>;
> > +               gpio-controller;
> > +               #gpio-cells = <2>;
> > +               gpio-ranges = <&pinctrl 0 106 32>;
> > +               interrupt-controller;
> > +               #interrupt-cells = <2>;
> > +       };
> > +
> > +       gpiof: gpiof at e01b0000 {
> > +               compatible = "actions,s900-gpio";
> > +               reg = <0x0 0xe01b0000 0x0 0x1000>;
> > +               gpio-controller;
> > +               #gpio-cells = <2>;
> > +               gpio-ranges = <&pinctrl 0 138 8>;
> > +               interrupt-controller;
> > +               #interrupt-cells = <2>;
> > +       };
> > -- 
> > 2.14.1
> > 

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

* Re: [PATCH v4 07/10] arm64: dts: actions: Add gpio line names to Bubblegum-96 board
  2018-03-02  3:50   ` Manivannan Sadhasivam
  (?)
@ 2018-03-22 15:28     ` Linus Walleij
  -1 siblings, 0 replies; 43+ messages in thread
From: Linus Walleij @ 2018-03-22 15:28 UTC (permalink / raw)
  To: Manivannan Sadhasivam
  Cc: open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Daniel Thompson, Mani Sadhasivam, hzhang, bdong, liuwei,
	linux-kernel, Amit Kucheria, open list:GPIO SUBSYSTEM,
	Rob Herring, mp-cs, 96boards, Andreas Färber, Linux ARM

On Fri, Mar 2, 2018 at 4:50 AM, Manivannan Sadhasivam
<manivannan.sadhasivam@linaro.org> wrote:

> Add gpio line names to Actions Semi S900 based Bubblegum-96 board.
>
> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>

Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij

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

* Re: [PATCH v4 07/10] arm64: dts: actions: Add gpio line names to Bubblegum-96 board
@ 2018-03-22 15:28     ` Linus Walleij
  0 siblings, 0 replies; 43+ messages in thread
From: Linus Walleij @ 2018-03-22 15:28 UTC (permalink / raw)
  To: Manivannan Sadhasivam
  Cc: Rob Herring, Andreas Färber, liuwei, mp-cs, 96boards,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Daniel Thompson, Amit Kucheria, Linux ARM,
	open list:GPIO SUBSYSTEM, linux-kernel, hzhang, bdong,
	Mani Sadhasivam

On Fri, Mar 2, 2018 at 4:50 AM, Manivannan Sadhasivam
<manivannan.sadhasivam@linaro.org> wrote:

> Add gpio line names to Actions Semi S900 based Bubblegum-96 board.
>
> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>

Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij

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

* [PATCH v4 07/10] arm64: dts: actions: Add gpio line names to Bubblegum-96 board
@ 2018-03-22 15:28     ` Linus Walleij
  0 siblings, 0 replies; 43+ messages in thread
From: Linus Walleij @ 2018-03-22 15:28 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Mar 2, 2018 at 4:50 AM, Manivannan Sadhasivam
<manivannan.sadhasivam@linaro.org> wrote:

> Add gpio line names to Actions Semi S900 based Bubblegum-96 board.
>
> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>

Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij

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

end of thread, other threads:[~2018-03-22 15:28 UTC | newest]

Thread overview: 43+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-03-02  3:50 [PATCH v4 00/10] Add Actions Semi S900 pinctrl and gpio support Manivannan Sadhasivam
2018-03-02  3:50 ` Manivannan Sadhasivam
2018-03-02  3:50 ` [PATCH v4 01/10] dt-bindings: pinctrl: Add bindings for Actions S900 SoC Manivannan Sadhasivam
2018-03-02  3:50   ` Manivannan Sadhasivam
2018-03-02 13:10   ` Linus Walleij
2018-03-02 13:10     ` Linus Walleij
2018-03-02  3:50 ` [PATCH v4 02/10] arm64: dts: actions: Add pinctrl node for S900 Manivannan Sadhasivam
2018-03-02  3:50   ` Manivannan Sadhasivam
2018-03-02  3:50   ` Manivannan Sadhasivam
2018-03-02 13:11   ` Linus Walleij
2018-03-02 13:11     ` Linus Walleij
2018-03-02  3:50 ` [PATCH v4 03/10] arm64: actions: Enable PINCTRL in platforms Kconfig Manivannan Sadhasivam
2018-03-02  3:50   ` Manivannan Sadhasivam
2018-03-02  3:50   ` Manivannan Sadhasivam
2018-03-02 13:12   ` Linus Walleij
2018-03-02 13:12     ` Linus Walleij
2018-03-02  3:50 ` [PATCH v4 04/10] pinctrl: actions: Add Actions S900 pinctrl driver Manivannan Sadhasivam
2018-03-02  3:50   ` Manivannan Sadhasivam
2018-03-02 13:21   ` Linus Walleij
2018-03-02 13:21     ` Linus Walleij
2018-03-02 17:56     ` Manivannan Sadhasivam
2018-03-02 17:56       ` Manivannan Sadhasivam
2018-03-02  3:50 ` [PATCH v4 05/10] dt-bindings: gpio: Add gpio nodes for Actions S900 SoC Manivannan Sadhasivam
2018-03-02  3:50   ` Manivannan Sadhasivam
2018-03-07 19:52   ` Rob Herring
2018-03-07 19:52     ` Rob Herring
2018-03-07 20:05     ` Manivannan Sadhasivam
2018-03-07 20:05       ` Manivannan Sadhasivam
2018-03-02  3:50 ` [PATCH v4 06/10] arm64: dts: actions: Add S900 gpio nodes Manivannan Sadhasivam
2018-03-02  3:50   ` Manivannan Sadhasivam
2018-03-02  3:50 ` [PATCH v4 07/10] arm64: dts: actions: Add gpio line names to Bubblegum-96 board Manivannan Sadhasivam
2018-03-02  3:50   ` Manivannan Sadhasivam
2018-03-22 15:28   ` Linus Walleij
2018-03-22 15:28     ` Linus Walleij
2018-03-22 15:28     ` Linus Walleij
2018-03-02  3:50 ` [PATCH v4 08/10] gpio: Add gpio driver for Actions OWL S900 SoC Manivannan Sadhasivam
2018-03-02  3:50   ` Manivannan Sadhasivam
2018-03-02  3:50 ` [PATCH v4 09/10] MAINTAINERS: Add reviewer for ACTIONS platforms Manivannan Sadhasivam
2018-03-02  3:50   ` Manivannan Sadhasivam
2018-03-02 13:23   ` Linus Walleij
2018-03-02 13:23     ` Linus Walleij
2018-03-02  3:50 ` [PATCH v4 10/10] MAINTAINERS: Add Actions Semi S900 pinctrl and gpio entries Manivannan Sadhasivam
2018-03-02  3:50   ` 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.