Merge tag 'sh-pfc-for-v4.20-tag1' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Walleij <linus.walleij@linaro.org>
Fri, 31 Aug 2018 13:42:33 +0000 (15:42 +0200)
committerLinus Walleij <linus.walleij@linaro.org>
Fri, 31 Aug 2018 13:42:33 +0000 (15:42 +0200)
pinctrl: sh-pfc: Updates for v4.20

  - Add SATA and audio pin groups on R-Car M3-N,
  - Add EtherAVB pin groups on RZ/G1C,
  - Add PWM and display (DU) pin groups on R-Car E3,
  - Add support for the new RZ/G2M (r8a774a1) SoC.

50 files changed:
Documentation/devicetree/bindings/gpio/ingenic,gpio.txt [deleted file]
Documentation/devicetree/bindings/pinctrl/ingenic,pinctrl.txt
Documentation/devicetree/bindings/pinctrl/meson,pinctrl.txt
Documentation/devicetree/bindings/pinctrl/nuvoton,npcm7xx-pinctrl.txt [new file with mode: 0644]
drivers/gpio/Kconfig
drivers/gpio/Makefile
drivers/gpio/gpio-ingenic.c [deleted file]
drivers/pinctrl/Kconfig
drivers/pinctrl/Makefile
drivers/pinctrl/aspeed/pinctrl-aspeed.c
drivers/pinctrl/berlin/berlin.c
drivers/pinctrl/cirrus/pinctrl-madera-core.c
drivers/pinctrl/freescale/pinctrl-imx.c
drivers/pinctrl/freescale/pinctrl-imx1-core.c
drivers/pinctrl/intel/pinctrl-baytrail.c
drivers/pinctrl/intel/pinctrl-broxton.c
drivers/pinctrl/intel/pinctrl-cannonlake.c
drivers/pinctrl/intel/pinctrl-cedarfork.c
drivers/pinctrl/intel/pinctrl-denverton.c
drivers/pinctrl/intel/pinctrl-geminilake.c
drivers/pinctrl/intel/pinctrl-icelake.c
drivers/pinctrl/intel/pinctrl-intel.c
drivers/pinctrl/intel/pinctrl-intel.h
drivers/pinctrl/intel/pinctrl-lewisburg.c
drivers/pinctrl/intel/pinctrl-sunrisepoint.c
drivers/pinctrl/mediatek/pinctrl-mtk-common.c
drivers/pinctrl/meson/Kconfig
drivers/pinctrl/meson/Makefile
drivers/pinctrl/meson/pinctrl-meson-g12a.c [new file with mode: 0644]
drivers/pinctrl/meson/pinctrl-meson.c
drivers/pinctrl/mvebu/pinctrl-mvebu.c
drivers/pinctrl/nomadik/pinctrl-nomadik.c
drivers/pinctrl/nuvoton/Kconfig [new file with mode: 0644]
drivers/pinctrl/nuvoton/Makefile [new file with mode: 0644]
drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c [new file with mode: 0644]
drivers/pinctrl/pinctrl-at91.c
drivers/pinctrl/pinctrl-ingenic.c
drivers/pinctrl/pinctrl-lantiq.c
drivers/pinctrl/pinctrl-lpc18xx.c
drivers/pinctrl/pinctrl-rockchip.c
drivers/pinctrl/pinctrl-rza1.c
drivers/pinctrl/pinctrl-single.c
drivers/pinctrl/pinctrl-st.c
drivers/pinctrl/qcom/pinctrl-msm.c
drivers/pinctrl/sirf/pinctrl-atlas7.c
drivers/pinctrl/stm32/pinctrl-stm32.c
drivers/pinctrl/sunxi/pinctrl-sunxi.c
drivers/pinctrl/ti/pinctrl-ti-iodelay.c
drivers/pinctrl/uniphier/pinctrl-uniphier-pro4.c
include/dt-bindings/gpio/meson-g12a-gpio.h [new file with mode: 0644]

diff --git a/Documentation/devicetree/bindings/gpio/ingenic,gpio.txt b/Documentation/devicetree/bindings/gpio/ingenic,gpio.txt
deleted file mode 100644 (file)
index 7988aeb..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-Ingenic jz47xx GPIO controller
-
-That the Ingenic GPIO driver node must be a sub-node of the Ingenic pinctrl
-driver node.
-
-Required properties:
---------------------
-
- - compatible: Must contain one of:
-    - "ingenic,jz4740-gpio"
-    - "ingenic,jz4770-gpio"
-    - "ingenic,jz4780-gpio"
- - reg: The GPIO bank number.
- - interrupt-controller: Marks the device node as an interrupt controller.
- - interrupts: Interrupt specifier for the controllers interrupt.
- - #interrupt-cells: Should be 2. Refer to
-   ../interrupt-controller/interrupts.txt for more details.
- - 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 specifies GPIO flags, as defined in <dt-bindings/gpio/gpio.h>. Only the
-    GPIO_ACTIVE_HIGH and GPIO_ACTIVE_LOW flags are supported.
- - gpio-ranges: Range of pins managed by the GPIO controller. Refer to
-   'gpio.txt' in this directory for more details.
-
-Example:
---------
-
-&pinctrl {
-       #address-cells = <1>;
-       #size-cells = <0>;
-
-       gpa: gpio@0 {
-               compatible = "ingenic,jz4740-gpio";
-               reg = <0>;
-
-               gpio-controller;
-               gpio-ranges = <&pinctrl 0 0 32>;
-               #gpio-cells = <2>;
-
-               interrupt-controller;
-               #interrupt-cells = <2>;
-
-               interrupt-parent = <&intc>;
-               interrupts = <28>;
-       };
-};
index ca313a7..af20b0e 100644 (file)
@@ -20,16 +20,30 @@ Required properties:
 
  - compatible: One of:
     - "ingenic,jz4740-pinctrl"
+    - "ingenic,jz4725b-pinctrl"
     - "ingenic,jz4770-pinctrl"
     - "ingenic,jz4780-pinctrl"
  - reg: Address range of the pinctrl registers.
 
 
-GPIO sub-nodes
---------------
+Required properties for sub-nodes (GPIO chips):
+-----------------------------------------------
 
-The pinctrl node can have optional sub-nodes for the Ingenic GPIO driver;
-please refer to ../gpio/ingenic,gpio.txt.
+ - compatible: Must contain one of:
+    - "ingenic,jz4740-gpio"
+    - "ingenic,jz4770-gpio"
+    - "ingenic,jz4780-gpio"
+ - reg: The GPIO bank number.
+ - interrupt-controller: Marks the device node as an interrupt controller.
+ - interrupts: Interrupt specifier for the controllers interrupt.
+ - #interrupt-cells: Should be 2. Refer to
+   ../interrupt-controller/interrupts.txt for more details.
+ - 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 specifies GPIO flags, as defined in <dt-bindings/gpio/gpio.h>. Only the
+    GPIO_ACTIVE_HIGH and GPIO_ACTIVE_LOW flags are supported.
+ - gpio-ranges: Range of pins managed by the GPIO controller. Refer to
+   ../gpio/gpio.txt for more details.
 
 
 Example:
@@ -38,4 +52,21 @@ Example:
 pinctrl: pin-controller@10010000 {
        compatible = "ingenic,jz4740-pinctrl";
        reg = <0x10010000 0x400>;
+       #address-cells = <1>;
+       #size-cells = <0>;
+
+       gpa: gpio@0 {
+               compatible = "ingenic,jz4740-gpio";
+               reg = <0>;
+
+               gpio-controller;
+               gpio-ranges = <&pinctrl 0 0 32>;
+               #gpio-cells = <2>;
+
+               interrupt-controller;
+               #interrupt-cells = <2>;
+
+               interrupt-parent = <&intc>;
+               interrupts = <28>;
+       };
 };
index 54ecb8a..82ead40 100644 (file)
@@ -13,6 +13,8 @@ Required properties for the root node:
                      "amlogic,meson-gxl-aobus-pinctrl"
                      "amlogic,meson-axg-periphs-pinctrl"
                      "amlogic,meson-axg-aobus-pinctrl"
+                     "amlogic,meson-g12a-periphs-pinctrl"
+                     "amlogic,meson-g12a-aobus-pinctrl"
  - reg: address and size of registers controlling irq functionality
 
 === GPIO sub-nodes ===
diff --git a/Documentation/devicetree/bindings/pinctrl/nuvoton,npcm7xx-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/nuvoton,npcm7xx-pinctrl.txt
new file mode 100644 (file)
index 0000000..83f4bba
--- /dev/null
@@ -0,0 +1,216 @@
+Nuvoton NPCM7XX Pin Controllers
+
+The Nuvoton BMC NPCM7XX Pin Controller multi-function routed through
+the multiplexing block, Each pin supports GPIO functionality (GPIOx)
+and multiple functions that directly connect the pin to different
+hardware blocks.
+
+Required properties:
+- #address-cells : should be 1.
+- #size-cells   : should be 1.
+- compatible    : "nuvoton,npcm750-pinctrl" for Poleg NPCM7XX.
+- ranges        : defines mapping ranges between pin controller node (parent)
+                       to GPIO bank node (children).
+
+=== GPIO Bank Subnode ===
+
+The NPCM7XX has 8 GPIO Banks each GPIO bank supports 32 GPIO.
+
+Required GPIO Bank subnode-properties:
+- reg                  : specifies physical base address and size of the GPIO
+                               bank registers.
+- gpio-controller      : Marks the device node as a GPIO controller.
+- #gpio-cells          : Must be <2>. The first cell is the gpio pin number
+                               and the second cell is used for optional parameters.
+- interrupts           : contain the GPIO bank interrupt with flags for falling edge.
+- gpio-ranges          : defines the range of pins managed by the GPIO bank controller.
+
+For example, GPIO bank subnodes like the following:
+       gpio0: gpio@f0010000 {
+               gpio-controller;
+               #gpio-cells = <2>;
+               reg = <0x0 0x80>;
+               interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
+               gpio-ranges = <&pinctrl 0 0 32>;
+       };
+
+=== Pin Mux Subnode ===
+
+- pin: A string containing the name of the pin
+       An array of strings, each string containing the name of a pin.
+       These pin are used for selecting pin configuration.
+
+The following are the list of pins available:
+       "GPIO0/IOX1DI", "GPIO1/IOX1LD", "GPIO2/IOX1CK", "GPIO3/IOX1D0",
+       "GPIO4/IOX2DI/SMB1DSDA", "GPIO5/IOX2LD/SMB1DSCL", "GPIO6/IOX2CK/SMB2DSDA",
+       "GPIO7/IOX2D0/SMB2DSCL", "GPIO8/LKGPO1", "GPIO9/LKGPO2", "GPIO10/IOXHLD",
+       "GPIO11/IOXHCK", "GPIO12/GSPICK/SMB5BSCL", "GPIO13/GSPIDO/SMB5BSDA",
+       "GPIO14/GSPIDI/SMB5CSCL", "GPIO15/GSPICS/SMB5CSDA", "GPIO16/LKGPO0",
+       "GPIO17/PSPI2DI/SMB4DEN","GPIO18/PSPI2D0/SMB4BSDA", "GPIO19/PSPI2CK/SMB4BSCL",
+       "GPIO20/SMB4CSDA/SMB15SDA", "GPIO21/SMB4CSCL/SMB15SCL", "GPIO22/SMB4DSDA/SMB14SDA",
+       "GPIO23/SMB4DSCL/SMB14SCL", "GPIO24/IOXHDO", "GPIO25/IOXHDI", "GPIO26/SMB5SDA",
+       "GPIO27/SMB5SCL", "GPIO28/SMB4SDA", "GPIO29/SMB4SCL", "GPIO30/SMB3SDA",
+       "GPIO31/SMB3SCL", "GPIO32/nSPI0CS1","SPI0D2", "SPI0D3", "GPIO37/SMB3CSDA",
+       "GPIO38/SMB3CSCL", "GPIO39/SMB3BSDA", "GPIO40/SMB3BSCL", "GPIO41/BSPRXD",
+       "GPO42/BSPTXD/STRAP11", "GPIO43/RXD1/JTMS2/BU1RXD", "GPIO44/nCTS1/JTDI2/BU1CTS",
+       "GPIO45/nDCD1/JTDO2", "GPIO46/nDSR1/JTCK2", "GPIO47/nRI1/JCP_RDY2",
+       "GPIO48/TXD2/BSPTXD", "GPIO49/RXD2/BSPRXD", "GPIO50/nCTS2", "GPO51/nRTS2/STRAP2",
+       "GPIO52/nDCD2", "GPO53/nDTR2_BOUT2/STRAP1", "GPIO54/nDSR2", "GPIO55/nRI2",
+       "GPIO56/R1RXERR", "GPIO57/R1MDC", "GPIO58/R1MDIO", "GPIO59/SMB3DSDA",
+       "GPIO60/SMB3DSCL", "GPO61/nDTR1_BOUT1/STRAP6", "GPO62/nRTST1/STRAP5",
+       "GPO63/TXD1/STRAP4", "GPIO64/FANIN0", "GPIO65/FANIN1", "GPIO66/FANIN2",
+       "GPIO67/FANIN3", "GPIO68/FANIN4", "GPIO69/FANIN5", "GPIO70/FANIN6", "GPIO71/FANIN7",
+       "GPIO72/FANIN8", "GPIO73/FANIN9", "GPIO74/FANIN10", "GPIO75/FANIN11",
+       "GPIO76/FANIN12", "GPIO77/FANIN13","GPIO78/FANIN14", "GPIO79/FANIN15",
+       "GPIO80/PWM0", "GPIO81/PWM1", "GPIO82/PWM2", "GPIO83/PWM3", "GPIO84/R2TXD0",
+       "GPIO85/R2TXD1", "GPIO86/R2TXEN", "GPIO87/R2RXD0", "GPIO88/R2RXD1", "GPIO89/R2CRSDV",
+       "GPIO90/R2RXERR", "GPIO91/R2MDC", "GPIO92/R2MDIO", "GPIO93/GA20/SMB5DSCL",
+       "GPIO94/nKBRST/SMB5DSDA", "GPIO95/nLRESET/nESPIRST", "GPIO96/RG1TXD0",
+       "GPIO97/RG1TXD1", "GPIO98/RG1TXD2", "GPIO99/RG1TXD3","GPIO100/RG1TXC",
+       "GPIO101/RG1TXCTL", "GPIO102/RG1RXD0", "GPIO103/RG1RXD1", "GPIO104/RG1RXD2",
+       "GPIO105/RG1RXD3", "GPIO106/RG1RXC", "GPIO107/RG1RXCTL", "GPIO108/RG1MDC",
+       "GPIO109/RG1MDIO", "GPIO110/RG2TXD0/DDRV0", "GPIO111/RG2TXD1/DDRV1",
+       "GPIO112/RG2TXD2/DDRV2", "GPIO113/RG2TXD3/DDRV3", "GPIO114/SMB0SCL",
+       "GPIO115/SMB0SDA", "GPIO116/SMB1SCL", "GPIO117/SMB1SDA", "GPIO118/SMB2SCL",
+       "GPIO119/SMB2SDA", "GPIO120/SMB2CSDA", "GPIO121/SMB2CSCL", "GPIO122/SMB2BSDA",
+       "GPIO123/SMB2BSCL", "GPIO124/SMB1CSDA", "GPIO125/SMB1CSCL","GPIO126/SMB1BSDA",
+       "GPIO127/SMB1BSCL", "GPIO128/SMB8SCL", "GPIO129/SMB8SDA", "GPIO130/SMB9SCL",
+       "GPIO131/SMB9SDA", "GPIO132/SMB10SCL", "GPIO133/SMB10SDA","GPIO134/SMB11SCL",
+       "GPIO135/SMB11SDA", "GPIO136/SD1DT0", "GPIO137/SD1DT1", "GPIO138/SD1DT2",
+       "GPIO139/SD1DT3", "GPIO140/SD1CLK", "GPIO141/SD1WP", "GPIO142/SD1CMD",
+       "GPIO143/SD1CD/SD1PWR", "GPIO144/PWM4", "GPIO145/PWM5", "GPIO146/PWM6",
+       "GPIO147/PWM7", "GPIO148/MMCDT4", "GPIO149/MMCDT5", "GPIO150/MMCDT6",
+       "GPIO151/MMCDT7", "GPIO152/MMCCLK", "GPIO153/MMCWP", "GPIO154/MMCCMD",
+       "GPIO155/nMMCCD/nMMCRST", "GPIO156/MMCDT0", "GPIO157/MMCDT1", "GPIO158/MMCDT2",
+       "GPIO159/MMCDT3", "GPIO160/CLKOUT/RNGOSCOUT", "GPIO161/nLFRAME/nESPICS",
+       "GPIO162/SERIRQ", "GPIO163/LCLK/ESPICLK", "GPIO164/LAD0/ESPI_IO0",
+       "GPIO165/LAD1/ESPI_IO1", "GPIO166/LAD2/ESPI_IO2", "GPIO167/LAD3/ESPI_IO3",
+       "GPIO168/nCLKRUN/nESPIALERT", "GPIO169/nSCIPME", "GPIO170/nSMI", "GPIO171/SMB6SCL",
+       "GPIO172/SMB6SDA", "GPIO173/SMB7SCL", "GPIO174/SMB7SDA", "GPIO175/PSPI1CK/FANIN19",
+       "GPIO176/PSPI1DO/FANIN18", "GPIO177/PSPI1DI/FANIN17", "GPIO178/R1TXD0",
+       "GPIO179/R1TXD1", "GPIO180/R1TXEN", "GPIO181/R1RXD0", "GPIO182/R1RXD1",
+       "GPIO183/SPI3CK", "GPO184/SPI3D0/STRAP9", "GPO185/SPI3D1/STRAP10",
+       "GPIO186/nSPI3CS0", "GPIO187/nSPI3CS1", "GPIO188/SPI3D2/nSPI3CS2",
+       "GPIO189/SPI3D3/nSPI3CS3", "GPIO190/nPRD_SMI", "GPIO191", "GPIO192", "GPIO193/R1CRSDV",
+       "GPIO194/SMB0BSCL", "GPIO195/SMB0BSDA", "GPIO196/SMB0CSCL", "GPIO197/SMB0DEN",
+       "GPIO198/SMB0DSDA", "GPIO199/SMB0DSCL", "GPIO200/R2CK", "GPIO201/R1CK",
+       "GPIO202/SMB0CSDA", "GPIO203/FANIN16", "GPIO204/DDC2SCL", "GPIO205/DDC2SDA",
+       "GPIO206/HSYNC2", "GPIO207/VSYNC2", "GPIO208/RG2TXC/DVCK", "GPIO209/RG2TXCTL/DDRV4",
+       "GPIO210/RG2RXD0/DDRV5", "GPIO211/RG2RXD1/DDRV6", "GPIO212/RG2RXD2/DDRV7",
+       "GPIO213/RG2RXD3/DDRV8", "GPIO214/RG2RXC/DDRV9", "GPIO215/RG2RXCTL/DDRV10",
+       "GPIO216/RG2MDC/DDRV11", "GPIO217/RG2MDIO/DVHSYNC", "GPIO218/nWDO1",
+       "GPIO219/nWDO2", "GPIO220/SMB12SCL", "GPIO221/SMB12SDA", "GPIO222/SMB13SCL",
+       "GPIO223/SMB13SDA", "GPIO224/SPIXCK", "GPO225/SPIXD0/STRAP12", "GPO226/SPIXD1/STRAP13",
+       "GPIO227/nSPIXCS0", "GPIO228/nSPIXCS1", "GPO229/SPIXD2/STRAP3", "GPIO230/SPIXD3",
+       "GPIO231/nCLKREQ", "GPI255/DACOSEL"
+
+Optional Properties:
+ bias-disable, bias-pull-down, bias-pull-up, input-enable,
+ input-disable, output-high, output-low, drive-push-pull,
+ drive-open-drain, input-debounce, slew-rate, drive-strength
+
+ slew-rate valid arguments are:
+                               <0> - slow
+                               <1> - fast
+ drive-strength valid arguments are:
+                               <2> - 2mA
+                               <4> - 4mA
+                               <8> - 8mA
+                               <12> - 12mA
+                               <16> - 16mA
+                               <24> - 24mA
+
+For example, pinctrl might have pinmux subnodes like the following:
+
+       gpio0_iox1d1_pin: gpio0-iox1d1-pin {
+               pins = "GPIO0/IOX1DI";
+               output-high;
+       };
+       gpio0_iox1ck_pin: gpio0-iox1ck-pin {
+               pins = "GPIO2/IOX1CK";
+               output_high;
+       };
+
+=== Pin Group Subnode ===
+
+Required pin group subnode-properties:
+- groups : A string containing the name of the group to mux.
+- function: A string containing the name of the function to mux to the
+  group.
+
+The following are the list of the available groups and functions :
+       smb0, smb0b, smb0c, smb0d, smb0den, smb1, smb1b, smb1c, smb1d,
+       smb2, smb2b, smb2c, smb2d, smb3, smb3b, smb3c, smb3d, smb4, smb4b,
+       smb4c, smb4d, smb4den, smb5, smb5b, smb5c, smb5d, ga20kbc, smb6,
+       smb7, smb8, smb9, smb10, smb11, smb12, smb13, smb14, smb15, fanin0,
+       fanin1, fanin2, fanin3, fanin4, fanin5, fanin6, fanin7, fanin8,
+       fanin9, fanin10, fanin11 fanin12 fanin13, fanin14, fanin15, faninx,
+       pwm0, pwm1, pwm2, pwm3, pwm4, pwm5, pwm6, pwm7, rg1, rg1mdio, rg2,
+       rg2mdio, ddr, uart1, uart2, bmcuart0a, bmcuart0b, bmcuart1, iox1,
+       iox2, ioxh, gspi, mmc, mmcwp, mmccd, mmcrst, mmc8, r1, r1err, r1md,
+       r2, r2err, r2md, sd1, sd1pwr, wdog1, wdog2, scipme, sci, serirq,
+       jtag2, spix, spixcs1, pspi1, pspi2, ddc, clkreq, clkout, spi3, spi3cs1,
+       spi3quad, spi3cs2, spi3cs3, spi0cs1, lpc, lpcclk, espi, lkgpo0, lkgpo1,
+       lkgpo2, nprd_smi
+
+For example, pinctrl might have group subnodes like the following:
+       r1err_pins: r1err-pins {
+               groups = "r1err";
+               function = "r1err";
+       };
+       r1md_pins: r1md-pins {
+               groups = "r1md";
+               function = "r1md";
+       };
+       r1_pins: r1-pins {
+               groups = "r1";
+               function = "r1";
+       };
+
+Examples
+========
+pinctrl: pinctrl@f0800000 {
+       #address-cells = <1>;
+       #size-cells = <1>;
+       compatible = "nuvoton,npcm750-pinctrl";
+       ranges = <0 0xf0010000 0x8000>;
+
+       gpio0: gpio@f0010000 {
+               gpio-controller;
+               #gpio-cells = <2>;
+               reg = <0x0 0x80>;
+               interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
+               gpio-ranges = <&pinctrl 0 0 32>;
+       };
+
+       ....
+
+       gpio7: gpio@f0017000 {
+               gpio-controller;
+               #gpio-cells = <2>;
+               reg = <0x7000 0x80>;
+               interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
+               gpio-ranges = <&pinctrl 0 224 32>;
+       };
+
+       gpio0_iox1d1_pin: gpio0-iox1d1-pin {
+               pins = "GPIO0/IOX1DI";
+               output-high;
+       };
+
+       iox1_pins: iox1-pins {
+               groups = "iox1";
+               function = "iox1";
+       };
+       iox2_pins: iox2-pins {
+               groups = "iox2";
+               function = "iox2";
+       };
+
+       ....
+
+       clkreq_pins: clkreq-pins {
+               groups = "clkreq";
+               function = "clkreq";
+       };
+};
\ No newline at end of file
index 4f52c3a..052dd59 100644 (file)
@@ -267,17 +267,6 @@ config GPIO_ICH
 
          If unsure, say N.
 
-config GPIO_INGENIC
-       tristate "Ingenic JZ47xx SoCs GPIO support"
-       depends on OF
-       depends on MACH_INGENIC || COMPILE_TEST
-       select GPIOLIB_IRQCHIP
-       help
-         Say yes here to support the GPIO functionality present on the
-         JZ4740 and JZ4780 SoCs from Ingenic.
-
-         If unsure, say N.
-
 config GPIO_IOP
        tristate "Intel IOP GPIO"
        depends on ARCH_IOP32X || ARCH_IOP33X || COMPILE_TEST
index c256aff..80d58c2 100644 (file)
@@ -57,7 +57,6 @@ obj-$(CONFIG_GPIO_GRGPIO)     += gpio-grgpio.o
 obj-$(CONFIG_GPIO_HLWD)                += gpio-hlwd.o
 obj-$(CONFIG_HTC_EGPIO)                += gpio-htc-egpio.o
 obj-$(CONFIG_GPIO_ICH)         += gpio-ich.o
-obj-$(CONFIG_GPIO_INGENIC)     += gpio-ingenic.o
 obj-$(CONFIG_GPIO_IOP)         += gpio-iop.o
 obj-$(CONFIG_GPIO_IT87)                += gpio-it87.o
 obj-$(CONFIG_GPIO_JANZ_TTL)    += gpio-janz-ttl.o
diff --git a/drivers/gpio/gpio-ingenic.c b/drivers/gpio/gpio-ingenic.c
deleted file mode 100644 (file)
index e738e38..0000000
+++ /dev/null
@@ -1,392 +0,0 @@
-/*
- * Ingenic JZ47xx GPIO driver
- *
- * Copyright (c) 2017 Paul Cercueil <paul@crapouillou.net>
- *
- * License terms: GNU General Public License (GPL) version 2
- */
-
-#include <linux/gpio/driver.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/module.h>
-#include <linux/of_address.h>
-#include <linux/of_device.h>
-#include <linux/of_irq.h>
-#include <linux/pinctrl/consumer.h>
-#include <linux/regmap.h>
-
-#define GPIO_PIN       0x00
-#define GPIO_MSK       0x20
-
-#define JZ4740_GPIO_DATA       0x10
-#define JZ4740_GPIO_SELECT     0x50
-#define JZ4740_GPIO_DIR                0x60
-#define JZ4740_GPIO_TRIG       0x70
-#define JZ4740_GPIO_FLAG       0x80
-
-#define JZ4770_GPIO_INT                0x10
-#define JZ4770_GPIO_PAT1       0x30
-#define JZ4770_GPIO_PAT0       0x40
-#define JZ4770_GPIO_FLAG       0x50
-
-#define REG_SET(x) ((x) + 0x4)
-#define REG_CLEAR(x) ((x) + 0x8)
-
-enum jz_version {
-       ID_JZ4740,
-       ID_JZ4770,
-       ID_JZ4780,
-};
-
-struct ingenic_gpio_chip {
-       struct regmap *map;
-       struct gpio_chip gc;
-       struct irq_chip irq_chip;
-       unsigned int irq, reg_base;
-       enum jz_version version;
-};
-
-static u32 gpio_ingenic_read_reg(struct ingenic_gpio_chip *jzgc, u8 reg)
-{
-       unsigned int val;
-
-       regmap_read(jzgc->map, jzgc->reg_base + reg, &val);
-
-       return (u32) val;
-}
-
-static void gpio_ingenic_set_bit(struct ingenic_gpio_chip *jzgc,
-               u8 reg, u8 offset, bool set)
-{
-       if (set)
-               reg = REG_SET(reg);
-       else
-               reg = REG_CLEAR(reg);
-
-       regmap_write(jzgc->map, jzgc->reg_base + reg, BIT(offset));
-}
-
-static inline bool gpio_get_value(struct ingenic_gpio_chip *jzgc, u8 offset)
-{
-       unsigned int val = gpio_ingenic_read_reg(jzgc, GPIO_PIN);
-
-       return !!(val & BIT(offset));
-}
-
-static void gpio_set_value(struct ingenic_gpio_chip *jzgc, u8 offset, int value)
-{
-       if (jzgc->version >= ID_JZ4770)
-               gpio_ingenic_set_bit(jzgc, JZ4770_GPIO_PAT0, offset, !!value);
-       else
-               gpio_ingenic_set_bit(jzgc, JZ4740_GPIO_DATA, offset, !!value);
-}
-
-static void irq_set_type(struct ingenic_gpio_chip *jzgc,
-               u8 offset, unsigned int type)
-{
-       u8 reg1, reg2;
-
-       if (jzgc->version >= ID_JZ4770) {
-               reg1 = JZ4770_GPIO_PAT1;
-               reg2 = JZ4770_GPIO_PAT0;
-       } else {
-               reg1 = JZ4740_GPIO_TRIG;
-               reg2 = JZ4740_GPIO_DIR;
-       }
-
-       switch (type) {
-       case IRQ_TYPE_EDGE_RISING:
-               gpio_ingenic_set_bit(jzgc, reg2, offset, true);
-               gpio_ingenic_set_bit(jzgc, reg1, offset, true);
-               break;
-       case IRQ_TYPE_EDGE_FALLING:
-               gpio_ingenic_set_bit(jzgc, reg2, offset, false);
-               gpio_ingenic_set_bit(jzgc, reg1, offset, true);
-               break;
-       case IRQ_TYPE_LEVEL_HIGH:
-               gpio_ingenic_set_bit(jzgc, reg2, offset, true);
-               gpio_ingenic_set_bit(jzgc, reg1, offset, false);
-               break;
-       case IRQ_TYPE_LEVEL_LOW:
-       default:
-               gpio_ingenic_set_bit(jzgc, reg2, offset, false);
-               gpio_ingenic_set_bit(jzgc, reg1, offset, false);
-               break;
-       }
-}
-
-static void ingenic_gpio_irq_mask(struct irq_data *irqd)
-{
-       struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
-       struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
-
-       gpio_ingenic_set_bit(jzgc, GPIO_MSK, irqd->hwirq, true);
-}
-
-static void ingenic_gpio_irq_unmask(struct irq_data *irqd)
-{
-       struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
-       struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
-
-       gpio_ingenic_set_bit(jzgc, GPIO_MSK, irqd->hwirq, false);
-}
-
-static void ingenic_gpio_irq_enable(struct irq_data *irqd)
-{
-       struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
-       struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
-       int irq = irqd->hwirq;
-
-       if (jzgc->version >= ID_JZ4770)
-               gpio_ingenic_set_bit(jzgc, JZ4770_GPIO_INT, irq, true);
-       else
-               gpio_ingenic_set_bit(jzgc, JZ4740_GPIO_SELECT, irq, true);
-
-       ingenic_gpio_irq_unmask(irqd);
-}
-
-static void ingenic_gpio_irq_disable(struct irq_data *irqd)
-{
-       struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
-       struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
-       int irq = irqd->hwirq;
-
-       ingenic_gpio_irq_mask(irqd);
-
-       if (jzgc->version >= ID_JZ4770)
-               gpio_ingenic_set_bit(jzgc, JZ4770_GPIO_INT, irq, false);
-       else
-               gpio_ingenic_set_bit(jzgc, JZ4740_GPIO_SELECT, irq, false);
-}
-
-static void ingenic_gpio_irq_ack(struct irq_data *irqd)
-{
-       struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
-       struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
-       int irq = irqd->hwirq;
-       bool high;
-
-       if (irqd_get_trigger_type(irqd) == IRQ_TYPE_EDGE_BOTH) {
-               /*
-                * Switch to an interrupt for the opposite edge to the one that
-                * triggered the interrupt being ACKed.
-                */
-               high = gpio_get_value(jzgc, irq);
-               if (high)
-                       irq_set_type(jzgc, irq, IRQ_TYPE_EDGE_FALLING);
-               else
-                       irq_set_type(jzgc, irq, IRQ_TYPE_EDGE_RISING);
-       }
-
-       if (jzgc->version >= ID_JZ4770)
-               gpio_ingenic_set_bit(jzgc, JZ4770_GPIO_FLAG, irq, false);
-       else
-               gpio_ingenic_set_bit(jzgc, JZ4740_GPIO_DATA, irq, true);
-}
-
-static int ingenic_gpio_irq_set_type(struct irq_data *irqd, unsigned int type)
-{
-       struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
-       struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
-
-       switch (type) {
-       case IRQ_TYPE_EDGE_BOTH:
-       case IRQ_TYPE_EDGE_RISING:
-       case IRQ_TYPE_EDGE_FALLING:
-               irq_set_handler_locked(irqd, handle_edge_irq);
-               break;
-       case IRQ_TYPE_LEVEL_HIGH:
-       case IRQ_TYPE_LEVEL_LOW:
-               irq_set_handler_locked(irqd, handle_level_irq);
-               break;
-       default:
-               irq_set_handler_locked(irqd, handle_bad_irq);
-       }
-
-       if (type == IRQ_TYPE_EDGE_BOTH) {
-               /*
-                * The hardware does not support interrupts on both edges. The
-                * best we can do is to set up a single-edge interrupt and then
-                * switch to the opposing edge when ACKing the interrupt.
-                */
-               bool high = gpio_get_value(jzgc, irqd->hwirq);
-
-               type = high ? IRQ_TYPE_EDGE_FALLING : IRQ_TYPE_EDGE_RISING;
-       }
-
-       irq_set_type(jzgc, irqd->hwirq, type);
-       return 0;
-}
-
-static int ingenic_gpio_irq_set_wake(struct irq_data *irqd, unsigned int on)
-{
-       struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
-       struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
-
-       return irq_set_irq_wake(jzgc->irq, on);
-}
-
-static void ingenic_gpio_irq_handler(struct irq_desc *desc)
-{
-       struct gpio_chip *gc = irq_desc_get_handler_data(desc);
-       struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
-       struct irq_chip *irq_chip = irq_data_get_irq_chip(&desc->irq_data);
-       unsigned long flag, i;
-
-       chained_irq_enter(irq_chip, desc);
-
-       if (jzgc->version >= ID_JZ4770)
-               flag = gpio_ingenic_read_reg(jzgc, JZ4770_GPIO_FLAG);
-       else
-               flag = gpio_ingenic_read_reg(jzgc, JZ4740_GPIO_FLAG);
-
-       for_each_set_bit(i, &flag, 32)
-               generic_handle_irq(irq_linear_revmap(gc->irq.domain, i));
-       chained_irq_exit(irq_chip, desc);
-}
-
-static void ingenic_gpio_set(struct gpio_chip *gc,
-               unsigned int offset, int value)
-{
-       struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
-
-       gpio_set_value(jzgc, offset, value);
-}
-
-static int ingenic_gpio_get(struct gpio_chip *gc, unsigned int offset)
-{
-       struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
-
-       return (int) gpio_get_value(jzgc, offset);
-}
-
-static int ingenic_gpio_direction_input(struct gpio_chip *gc,
-               unsigned int offset)
-{
-       return pinctrl_gpio_direction_input(gc->base + offset);
-}
-
-static int ingenic_gpio_direction_output(struct gpio_chip *gc,
-               unsigned int offset, int value)
-{
-       ingenic_gpio_set(gc, offset, value);
-       return pinctrl_gpio_direction_output(gc->base + offset);
-}
-
-static const struct of_device_id ingenic_gpio_of_match[] = {
-       { .compatible = "ingenic,jz4740-gpio", .data = (void *)ID_JZ4740 },
-       { .compatible = "ingenic,jz4770-gpio", .data = (void *)ID_JZ4770 },
-       { .compatible = "ingenic,jz4780-gpio", .data = (void *)ID_JZ4780 },
-       {},
-};
-MODULE_DEVICE_TABLE(of, ingenic_gpio_of_match);
-
-static int ingenic_gpio_probe(struct platform_device *pdev)
-{
-       struct device *dev = &pdev->dev;
-       struct ingenic_gpio_chip *jzgc;
-       u32 bank;
-       int err;
-
-       jzgc = devm_kzalloc(dev, sizeof(*jzgc), GFP_KERNEL);
-       if (!jzgc)
-               return -ENOMEM;
-
-       jzgc->map = dev_get_drvdata(dev->parent);
-       if (!jzgc->map) {
-               dev_err(dev, "Cannot get parent regmap\n");
-               return -ENXIO;
-       }
-
-       err = of_property_read_u32(dev->of_node, "reg", &bank);
-       if (err) {
-               dev_err(dev, "Cannot read \"reg\" property: %i\n", err);
-               return err;
-       }
-
-       jzgc->reg_base = bank * 0x100;
-
-       jzgc->gc.label = devm_kasprintf(dev, GFP_KERNEL, "GPIO%c", 'A' + bank);
-       if (!jzgc->gc.label)
-               return -ENOMEM;
-
-       /* DO NOT EXPAND THIS: FOR BACKWARD GPIO NUMBERSPACE COMPATIBIBILITY
-        * ONLY: WORK TO TRANSITION CONSUMERS TO USE THE GPIO DESCRIPTOR API IN
-        * <linux/gpio/consumer.h> INSTEAD.
-        */
-       jzgc->gc.base = bank * 32;
-
-       jzgc->gc.ngpio = 32;
-       jzgc->gc.parent = dev;
-       jzgc->gc.of_node = dev->of_node;
-       jzgc->gc.owner = THIS_MODULE;
-       jzgc->version = (enum jz_version)of_device_get_match_data(dev);
-
-       jzgc->gc.set = ingenic_gpio_set;
-       jzgc->gc.get = ingenic_gpio_get;
-       jzgc->gc.direction_input = ingenic_gpio_direction_input;
-       jzgc->gc.direction_output = ingenic_gpio_direction_output;
-
-       if (of_property_read_bool(dev->of_node, "gpio-ranges")) {
-               jzgc->gc.request = gpiochip_generic_request;
-               jzgc->gc.free = gpiochip_generic_free;
-       }
-
-       err = devm_gpiochip_add_data(dev, &jzgc->gc, jzgc);
-       if (err)
-               return err;
-
-       jzgc->irq = irq_of_parse_and_map(dev->of_node, 0);
-       if (!jzgc->irq)
-               return -EINVAL;
-
-       jzgc->irq_chip.name = jzgc->gc.label;
-       jzgc->irq_chip.irq_enable = ingenic_gpio_irq_enable;
-       jzgc->irq_chip.irq_disable = ingenic_gpio_irq_disable;
-       jzgc->irq_chip.irq_unmask = ingenic_gpio_irq_unmask;
-       jzgc->irq_chip.irq_mask = ingenic_gpio_irq_mask;
-       jzgc->irq_chip.irq_ack = ingenic_gpio_irq_ack;
-       jzgc->irq_chip.irq_set_type = ingenic_gpio_irq_set_type;
-       jzgc->irq_chip.irq_set_wake = ingenic_gpio_irq_set_wake;
-       jzgc->irq_chip.flags = IRQCHIP_MASK_ON_SUSPEND;
-
-       err = gpiochip_irqchip_add(&jzgc->gc, &jzgc->irq_chip, 0,
-                       handle_level_irq, IRQ_TYPE_NONE);
-       if (err)
-               return err;
-
-       gpiochip_set_chained_irqchip(&jzgc->gc, &jzgc->irq_chip,
-                       jzgc->irq, ingenic_gpio_irq_handler);
-       return 0;
-}
-
-static int ingenic_gpio_remove(struct platform_device *pdev)
-{
-       return 0;
-}
-
-static struct platform_driver ingenic_gpio_driver = {
-       .driver = {
-               .name = "gpio-ingenic",
-               .of_match_table = of_match_ptr(ingenic_gpio_of_match),
-       },
-       .probe = ingenic_gpio_probe,
-       .remove = ingenic_gpio_remove,
-};
-
-static int __init ingenic_gpio_drv_register(void)
-{
-       return platform_driver_register(&ingenic_gpio_driver);
-}
-subsys_initcall(ingenic_gpio_drv_register);
-
-static void __exit ingenic_gpio_drv_unregister(void)
-{
-       platform_driver_unregister(&ingenic_gpio_driver);
-}
-module_exit(ingenic_gpio_drv_unregister);
-
-MODULE_AUTHOR("Paul Cercueil <paul@crapouillou.net>");
-MODULE_DESCRIPTION("Ingenic JZ47xx GPIO driver");
-MODULE_LICENSE("GPL");
index e86752b..978b2ed 100644 (file)
@@ -309,12 +309,14 @@ config PINCTRL_ZYNQ
 
 config PINCTRL_INGENIC
        bool "Pinctrl driver for the Ingenic JZ47xx SoCs"
-       default y
+       default MACH_INGENIC
        depends on OF
-       depends on MACH_INGENIC || COMPILE_TEST
+       depends on MIPS || COMPILE_TEST
        select GENERIC_PINCONF
        select GENERIC_PINCTRL_GROUPS
        select GENERIC_PINMUX_FUNCTIONS
+       select GPIOLIB
+       select GPIOLIB_IRQCHIP
        select REGMAP_MMIO
 
 config PINCTRL_RK805
@@ -346,6 +348,7 @@ source "drivers/pinctrl/freescale/Kconfig"
 source "drivers/pinctrl/intel/Kconfig"
 source "drivers/pinctrl/mvebu/Kconfig"
 source "drivers/pinctrl/nomadik/Kconfig"
+source "drivers/pinctrl/nuvoton/Kconfig"
 source "drivers/pinctrl/pxa/Kconfig"
 source "drivers/pinctrl/qcom/Kconfig"
 source "drivers/pinctrl/samsung/Kconfig"
index 46ef9bd..8e127bd 100644 (file)
@@ -51,6 +51,7 @@ obj-y                         += freescale/
 obj-$(CONFIG_X86)              += intel/
 obj-y                          += mvebu/
 obj-y                          += nomadik/
+obj-$(CONFIG_ARCH_NPCM7XX)     += nuvoton/
 obj-$(CONFIG_PINCTRL_PXA)      += pxa/
 obj-$(CONFIG_ARCH_QCOM)                += qcom/
 obj-$(CONFIG_PINCTRL_SAMSUNG)  += samsung/
index aefe3c3..eb87ab7 100644 (file)
@@ -715,7 +715,7 @@ int aspeed_pin_config_set(struct pinctrl_dev *pctldev, unsigned int offset,
 
                pmap = find_pinconf_map(param, MAP_TYPE_ARG, arg);
 
-               if (unlikely(WARN_ON(!pmap)))
+               if (WARN_ON(!pmap))
                        return -EINVAL;
 
                val = pmap->val << pconf->bit;
index b5903ff..b17a03c 100644 (file)
@@ -64,16 +64,14 @@ static int berlin_pinctrl_dt_node_to_map(struct pinctrl_dev *pctrl_dev,
        ret = of_property_read_string(node, "function", &function_name);
        if (ret) {
                dev_err(pctrl->dev,
-                       "missing function property in node %s\n",
-                       node->name);
+                       "missing function property in node %pOFn\n", node);
                return -EINVAL;
        }
 
        ngroups = of_property_count_strings(node, "groups");
        if (ngroups < 0) {
                dev_err(pctrl->dev,
-                       "missing groups property in node %s\n",
-                       node->name);
+                       "missing groups property in node %pOFn\n", node);
                return -EINVAL;
        }
 
index ece41fb..979df10 100644 (file)
@@ -550,7 +550,7 @@ static void __maybe_unused madera_pin_dbg_show(struct pinctrl_dev *pctldev,
        seq_printf(s, " DRV=%umA", madera_pin_unmake_drv_str(priv, conf[1]));
 
        if (conf[0] & MADERA_GP1_IP_CFG_MASK)
-               seq_puts(s, "SCHMITT");
+               seq_puts(s, " SCHMITT");
 }
 
 
@@ -801,7 +801,7 @@ static int madera_pin_conf_get(struct pinctrl_dev *pctldev, unsigned int pin,
                        result = 1;
                break;
        default:
-               break;
+               return -ENOTSUPP;
        }
 
        *config = pinconf_to_config_packed(param, result);
@@ -905,7 +905,7 @@ static int madera_pin_conf_set(struct pinctrl_dev *pctldev, unsigned int pin,
                        conf[1] &= ~MADERA_GP1_DIR;
                        break;
                default:
-                       break;
+                       return -ENOTSUPP;
                }
 
                ++configs;
@@ -971,10 +971,10 @@ static int madera_pin_conf_group_set(struct pinctrl_dev *pctldev,
 }
 
 static const struct pinconf_ops madera_pin_conf_ops = {
+       .is_generic = true,
        .pin_config_get = madera_pin_conf_get,
        .pin_config_set = madera_pin_conf_set,
        .pin_config_group_set = madera_pin_conf_group_set,
-
 };
 
 static struct pinctrl_desc madera_pin_desc = {
index b04edc2..4e8cf0e 100644 (file)
@@ -69,8 +69,7 @@ static int imx_dt_node_to_map(struct pinctrl_dev *pctldev,
         */
        grp = imx_pinctrl_find_group_by_name(pctldev, np->name);
        if (!grp) {
-               dev_err(ipctl->dev, "unable to find group for node %s\n",
-                       np->name);
+               dev_err(ipctl->dev, "unable to find group for node %pOFn\n", np);
                return -EINVAL;
        }
 
@@ -434,7 +433,7 @@ static int imx_pinctrl_parse_groups(struct device_node *np,
        int i;
        u32 config;
 
-       dev_dbg(ipctl->dev, "group(%d): %s\n", index, np->name);
+       dev_dbg(ipctl->dev, "group(%d): %pOFn\n", index, np);
 
        if (info->flags & SHARE_MUX_CONF_REG)
                pin_size = FSL_PIN_SHARE_SIZE;
@@ -544,7 +543,7 @@ static int imx_pinctrl_parse_functions(struct device_node *np,
        struct group_desc *grp;
        u32 i = 0;
 
-       dev_dbg(pctl->dev, "parse function(%d): %s\n", index, np->name);
+       dev_dbg(pctl->dev, "parse function(%d): %pOFn\n", index, np);
 
        func = pinmux_generic_get_function(pctl, index);
        if (!func)
index deb7870..7e29e3f 100644 (file)
@@ -233,8 +233,8 @@ static int imx1_dt_node_to_map(struct pinctrl_dev *pctldev,
         */
        grp = imx1_pinctrl_find_group_by_name(info, np->name);
        if (!grp) {
-               dev_err(info->dev, "unable to find group for node %s\n",
-                       np->name);
+               dev_err(info->dev, "unable to find group for node %pOFn\n",
+                       np);
                return -EINVAL;
        }
 
@@ -466,7 +466,7 @@ static int imx1_pinctrl_parse_groups(struct device_node *np,
        const __be32 *list;
        int i;
 
-       dev_dbg(info->dev, "group(%d): %s\n", index, np->name);
+       dev_dbg(info->dev, "group(%d): %pOFn\n", index, np);
 
        /* Initialise group */
        grp->name = np->name;
@@ -477,8 +477,8 @@ static int imx1_pinctrl_parse_groups(struct device_node *np,
        list = of_get_property(np, "fsl,pins", &size);
        /* we do not check return since it's safe node passed down */
        if (!size || size % 12) {
-               dev_notice(info->dev, "Not a valid fsl,pins property (%s)\n",
-                               np->name);
+               dev_notice(info->dev, "Not a valid fsl,pins property (%pOFn)\n",
+                               np);
                return -EINVAL;
        }
 
@@ -513,7 +513,7 @@ static int imx1_pinctrl_parse_functions(struct device_node *np,
        static u32 grp_index;
        u32 i = 0;
 
-       dev_dbg(info->dev, "parse function(%d): %s\n", index, np->name);
+       dev_dbg(info->dev, "parse function(%d): %pOFn\n", index, np);
 
        func = &info->functions[index];
 
index f38d596..8aa03d1 100644 (file)
@@ -18,6 +18,8 @@
 #include <linux/seq_file.h>
 #include <linux/io.h>
 #include <linux/pm_runtime.h>
+#include <linux/property.h>
+
 #include <linux/pinctrl/pinctrl.h>
 #include <linux/pinctrl/pinmux.h>
 #include <linux/pinctrl/pinconf.h>
@@ -1781,7 +1783,6 @@ static int byt_pinctrl_probe(struct platform_device *pdev)
 {
        const struct byt_pinctrl_soc_data *soc_data = NULL;
        const struct byt_pinctrl_soc_data **soc_table;
-       const struct acpi_device_id *acpi_id;
        struct acpi_device *acpi_dev;
        struct byt_gpio *vg;
        int i, ret;
@@ -1790,11 +1791,7 @@ static int byt_pinctrl_probe(struct platform_device *pdev)
        if (!acpi_dev)
                return -ENODEV;
 
-       acpi_id = acpi_match_device(byt_gpio_acpi_match, &pdev->dev);
-       if (!acpi_id)
-               return -ENODEV;
-
-       soc_table = (const struct byt_pinctrl_soc_data **)acpi_id->driver_data;
+       soc_table = (const struct byt_pinctrl_soc_data **)device_get_match_data(&pdev->dev);
 
        for (i = 0; soc_table[i]; i++) {
                if (!strcmp(acpi_dev->pnp.unique_id, soc_table[i]->uid)) {
index 8b1c7b5..629d640 100644 (file)
@@ -6,7 +6,7 @@
  * Author: Mika Westerberg <mika.westerberg@linux.intel.com>
  */
 
-#include <linux/acpi.h>
+#include <linux/mod_devicetable.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/pm.h>
@@ -1008,50 +1008,10 @@ static const struct platform_device_id bxt_pinctrl_platform_ids[] = {
 
 static int bxt_pinctrl_probe(struct platform_device *pdev)
 {
-       const struct intel_pinctrl_soc_data *soc_data = NULL;
-       const struct intel_pinctrl_soc_data **soc_table;
-       struct acpi_device *adev;
-       int i;
-
-       adev = ACPI_COMPANION(&pdev->dev);
-       if (adev) {
-               const struct acpi_device_id *id;
-
-               id = acpi_match_device(bxt_pinctrl_acpi_match, &pdev->dev);
-               if (!id)
-                       return -ENODEV;
-
-               soc_table = (const struct intel_pinctrl_soc_data **)
-                       id->driver_data;
-
-               for (i = 0; soc_table[i]; i++) {
-                       if (!strcmp(adev->pnp.unique_id, soc_table[i]->uid)) {
-                               soc_data = soc_table[i];
-                               break;
-                       }
-               }
-       } else {
-               const struct platform_device_id *pid;
-
-               pid = platform_get_device_id(pdev);
-               if (!pid)
-                       return -ENODEV;
-
-               soc_table = (const struct intel_pinctrl_soc_data **)
-                       pid->driver_data;
-               soc_data = soc_table[pdev->id];
-       }
-
-       if (!soc_data)
-               return -ENODEV;
-
-       return intel_pinctrl_probe(pdev, soc_data);
+       return intel_pinctrl_probe_by_uid(pdev);
 }
 
-static const struct dev_pm_ops bxt_pinctrl_pm_ops = {
-       SET_LATE_SYSTEM_SLEEP_PM_OPS(intel_pinctrl_suspend,
-                                    intel_pinctrl_resume)
-};
+static INTEL_PINCTRL_PM_OPS(bxt_pinctrl_pm_ops);
 
 static struct platform_driver bxt_pinctrl_driver = {
        .probe = bxt_pinctrl_probe,
index fb1afe5..88ff675 100644 (file)
@@ -7,10 +7,11 @@
  *          Mika Westerberg <mika.westerberg@linux.intel.com>
  */
 
-#include <linux/acpi.h>
+#include <linux/mod_devicetable.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/pm.h>
+
 #include <linux/pinctrl/pinctrl.h>
 
 #include "pinctrl-intel.h"
@@ -828,21 +829,10 @@ MODULE_DEVICE_TABLE(acpi, cnl_pinctrl_acpi_match);
 
 static int cnl_pinctrl_probe(struct platform_device *pdev)
 {
-       const struct intel_pinctrl_soc_data *soc_data;
-       const struct acpi_device_id *id;
-
-       id = acpi_match_device(cnl_pinctrl_acpi_match, &pdev->dev);
-       if (!id || !id->driver_data)
-               return -ENODEV;
-
-       soc_data = (const struct intel_pinctrl_soc_data *)id->driver_data;
-       return intel_pinctrl_probe(pdev, soc_data);
+       return intel_pinctrl_probe_by_hid(pdev);
 }
 
-static const struct dev_pm_ops cnl_pinctrl_pm_ops = {
-       SET_LATE_SYSTEM_SLEEP_PM_OPS(intel_pinctrl_suspend,
-                                    intel_pinctrl_resume)
-};
+static INTEL_PINCTRL_PM_OPS(cnl_pinctrl_pm_ops);
 
 static struct platform_driver cnl_pinctrl_driver = {
        .probe = cnl_pinctrl_probe,
index c788e37..d675c9b 100644 (file)
@@ -335,10 +335,7 @@ static int cdf_pinctrl_probe(struct platform_device *pdev)
        return intel_pinctrl_probe(pdev, &cdf_soc_data);
 }
 
-static const struct dev_pm_ops cdf_pinctrl_pm_ops = {
-       SET_LATE_SYSTEM_SLEEP_PM_OPS(intel_pinctrl_suspend,
-                                    intel_pinctrl_resume)
-};
+static INTEL_PINCTRL_PM_OPS(cdf_pinctrl_pm_ops);
 
 static const struct acpi_device_id cdf_pinctrl_acpi_match[] = {
        { "INTC3001" },
index f321ab0..2017250 100644 (file)
@@ -262,10 +262,7 @@ static int dnv_pinctrl_probe(struct platform_device *pdev)
        return intel_pinctrl_probe(pdev, &dnv_soc_data);
 }
 
-static const struct dev_pm_ops dnv_pinctrl_pm_ops = {
-       SET_LATE_SYSTEM_SLEEP_PM_OPS(intel_pinctrl_suspend,
-                                    intel_pinctrl_resume)
-};
+static INTEL_PINCTRL_PM_OPS(dnv_pinctrl_pm_ops);
 
 static const struct acpi_device_id dnv_pinctrl_acpi_match[] = {
        { "INTC3000" },
index 5c4c967..3e7a2a1 100644 (file)
@@ -6,7 +6,7 @@
  * Author: Mika Westerberg <mika.westerberg@linux.intel.com>
  */
 
-#include <linux/acpi.h>
+#include <linux/mod_devicetable.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/pm.h>
@@ -449,39 +449,17 @@ static const struct intel_pinctrl_soc_data *glk_pinctrl_soc_data[] = {
 };
 
 static const struct acpi_device_id glk_pinctrl_acpi_match[] = {
-       { "INT3453" },
+       { "INT3453", (kernel_ulong_t)glk_pinctrl_soc_data },
        { }
 };
 MODULE_DEVICE_TABLE(acpi, glk_pinctrl_acpi_match);
 
 static int glk_pinctrl_probe(struct platform_device *pdev)
 {
-       const struct intel_pinctrl_soc_data *soc_data = NULL;
-       struct acpi_device *adev;
-       int i;
-
-       adev = ACPI_COMPANION(&pdev->dev);
-       if (!adev)
-               return -ENODEV;
-
-       for (i = 0; glk_pinctrl_soc_data[i]; i++) {
-               if (!strcmp(adev->pnp.unique_id,
-                           glk_pinctrl_soc_data[i]->uid)) {
-                       soc_data = glk_pinctrl_soc_data[i];
-                       break;
-               }
-       }
-
-       if (!soc_data)
-               return -ENODEV;
-
-       return intel_pinctrl_probe(pdev, soc_data);
+       return intel_pinctrl_probe_by_uid(pdev);
 }
 
-static const struct dev_pm_ops glk_pinctrl_pm_ops = {
-       SET_LATE_SYSTEM_SLEEP_PM_OPS(intel_pinctrl_suspend,
-                                    intel_pinctrl_resume)
-};
+static INTEL_PINCTRL_PM_OPS(glk_pinctrl_pm_ops);
 
 static struct platform_driver glk_pinctrl_driver = {
        .probe = glk_pinctrl_probe,
index 630b966..7c0972c 100644 (file)
@@ -408,10 +408,7 @@ static int icl_pinctrl_probe(struct platform_device *pdev)
        return intel_pinctrl_probe(pdev, &icllp_soc_data);
 }
 
-static const struct dev_pm_ops icl_pinctrl_pm_ops = {
-       SET_LATE_SYSTEM_SLEEP_PM_OPS(intel_pinctrl_suspend,
-                                    intel_pinctrl_resume)
-};
+static INTEL_PINCTRL_PM_OPS(icl_pinctrl_pm_ops);
 
 static const struct acpi_device_id icl_pinctrl_acpi_match[] = {
        { "INT3455" },
index 62b009b..9a75acc 100644 (file)
@@ -7,11 +7,14 @@
  *          Mika Westerberg <mika.westerberg@linux.intel.com>
  */
 
+#include <linux/acpi.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/gpio/driver.h>
 #include <linux/log2.h>
 #include <linux/platform_device.h>
+#include <linux/property.h>
+
 #include <linux/pinctrl/pinctrl.h>
 #include <linux/pinctrl/pinmux.h>
 #include <linux/pinctrl/pinconf.h>
@@ -831,7 +834,7 @@ static const struct gpio_chip intel_gpio_chip = {
  * intel_gpio_to_pin() - Translate from GPIO offset to pin number
  * @pctrl: Pinctrl structure
  * @offset: GPIO offset from gpiolib
- * @commmunity: Community is filled here if not %NULL
+ * @community: Community is filled here if not %NULL
  * @padgrp: Pad group is filled here if not %NULL
  *
  * When coming through gpiolib irqchip, the GPIO offset is not
@@ -1415,6 +1418,50 @@ int intel_pinctrl_probe(struct platform_device *pdev,
 }
 EXPORT_SYMBOL_GPL(intel_pinctrl_probe);
 
+int intel_pinctrl_probe_by_hid(struct platform_device *pdev)
+{
+       const struct intel_pinctrl_soc_data *data;
+
+       data = device_get_match_data(&pdev->dev);
+       return intel_pinctrl_probe(pdev, data);
+}
+EXPORT_SYMBOL_GPL(intel_pinctrl_probe_by_hid);
+
+int intel_pinctrl_probe_by_uid(struct platform_device *pdev)
+{
+       const struct intel_pinctrl_soc_data *data = NULL;
+       const struct intel_pinctrl_soc_data **table;
+       struct acpi_device *adev;
+       unsigned int i;
+
+       adev = ACPI_COMPANION(&pdev->dev);
+       if (adev) {
+               const void *match = device_get_match_data(&pdev->dev);
+
+               table = (const struct intel_pinctrl_soc_data **)match;
+               for (i = 0; table[i]; i++) {
+                       if (!strcmp(adev->pnp.unique_id, table[i]->uid)) {
+                               data = table[i];
+                               break;
+                       }
+               }
+       } else {
+               const struct platform_device_id *id;
+
+               id = platform_get_device_id(pdev);
+               if (!id)
+                       return -ENODEV;
+
+               table = (const struct intel_pinctrl_soc_data **)id->driver_data;
+               data = table[pdev->id];
+       }
+       if (!data)
+               return -ENODEV;
+
+       return intel_pinctrl_probe(pdev, data);
+}
+EXPORT_SYMBOL_GPL(intel_pinctrl_probe_by_uid);
+
 #ifdef CONFIG_PM_SLEEP
 static bool intel_pinctrl_should_save(struct intel_pinctrl *pctrl, unsigned pin)
 {
index 1785abf..acb723b 100644 (file)
@@ -173,9 +173,17 @@ struct intel_pinctrl_soc_data {
 
 int intel_pinctrl_probe(struct platform_device *pdev,
                        const struct intel_pinctrl_soc_data *soc_data);
+int intel_pinctrl_probe_by_hid(struct platform_device *pdev);
+int intel_pinctrl_probe_by_uid(struct platform_device *pdev);
+
 #ifdef CONFIG_PM_SLEEP
 int intel_pinctrl_suspend(struct device *dev);
 int intel_pinctrl_resume(struct device *dev);
 #endif
 
+#define INTEL_PINCTRL_PM_OPS(_name)                                              \
+const struct dev_pm_ops _name = {                                                \
+       SET_LATE_SYSTEM_SLEEP_PM_OPS(intel_pinctrl_suspend, intel_pinctrl_resume) \
+}
+
 #endif /* PINCTRL_INTEL_H */
index 9989464..804b86e 100644 (file)
@@ -313,10 +313,7 @@ static int lbg_pinctrl_probe(struct platform_device *pdev)
        return intel_pinctrl_probe(pdev, &lbg_soc_data);
 }
 
-static const struct dev_pm_ops lbg_pinctrl_pm_ops = {
-       SET_LATE_SYSTEM_SLEEP_PM_OPS(intel_pinctrl_suspend,
-                                    intel_pinctrl_resume)
-};
+static INTEL_PINCTRL_PM_OPS(lbg_pinctrl_pm_ops);
 
 static const struct acpi_device_id lbg_pinctrl_acpi_match[] = {
        { "INT3536" },
index 7984392..53ebcea 100644 (file)
@@ -7,10 +7,11 @@
  *          Mika Westerberg <mika.westerberg@linux.intel.com>
  */
 
-#include <linux/acpi.h>
+#include <linux/mod_devicetable.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/pm.h>
+
 #include <linux/pinctrl/pinctrl.h>
 
 #include "pinctrl-intel.h"
@@ -593,21 +594,10 @@ MODULE_DEVICE_TABLE(acpi, spt_pinctrl_acpi_match);
 
 static int spt_pinctrl_probe(struct platform_device *pdev)
 {
-       const struct intel_pinctrl_soc_data *soc_data;
-       const struct acpi_device_id *id;
-
-       id = acpi_match_device(spt_pinctrl_acpi_match, &pdev->dev);
-       if (!id || !id->driver_data)
-               return -ENODEV;
-
-       soc_data = (const struct intel_pinctrl_soc_data *)id->driver_data;
-       return intel_pinctrl_probe(pdev, soc_data);
+       return intel_pinctrl_probe_by_hid(pdev);
 }
 
-static const struct dev_pm_ops spt_pinctrl_pm_ops = {
-       SET_LATE_SYSTEM_SLEEP_PM_OPS(intel_pinctrl_suspend,
-                                    intel_pinctrl_resume)
-};
+static INTEL_PINCTRL_PM_OPS(spt_pinctrl_pm_ops);
 
 static struct platform_driver spt_pinctrl_driver = {
        .probe = spt_pinctrl_probe,
index 16ff56f..0716238 100644 (file)
@@ -514,8 +514,8 @@ static int mtk_pctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
 
        pins = of_find_property(node, "pinmux", NULL);
        if (!pins) {
-               dev_err(pctl->dev, "missing pins property in node %s .\n",
-                               node->name);
+               dev_err(pctl->dev, "missing pins property in node %pOFn .\n",
+                               node);
                return -EINVAL;
        }
 
index c80951d..9ab537e 100644 (file)
@@ -47,4 +47,10 @@ config PINCTRL_MESON_AXG
 config PINCTRL_MESON_AXG_PMX
        bool
 
+config PINCTRL_MESON_G12A
+       bool "Meson g12a Soc pinctrl driver"
+       depends on ARM64
+       select PINCTRL_MESON_AXG_PMX
+       default y
+
 endif
index 3c6580c..cf283f4 100644 (file)
@@ -6,3 +6,4 @@ obj-$(CONFIG_PINCTRL_MESON_GXBB) += pinctrl-meson-gxbb.o
 obj-$(CONFIG_PINCTRL_MESON_GXL) += pinctrl-meson-gxl.o
 obj-$(CONFIG_PINCTRL_MESON_AXG_PMX) += pinctrl-meson-axg-pmx.o
 obj-$(CONFIG_PINCTRL_MESON_AXG) += pinctrl-meson-axg.o
+obj-$(CONFIG_PINCTRL_MESON_G12A) += pinctrl-meson-g12a.o
diff --git a/drivers/pinctrl/meson/pinctrl-meson-g12a.c b/drivers/pinctrl/meson/pinctrl-meson-g12a.c
new file mode 100644 (file)
index 0000000..d494492
--- /dev/null
@@ -0,0 +1,1404 @@
+// SPDX-License-Identifier: (GPL-2.0+ or MIT)
+/*
+ * Pin controller and GPIO driver for Amlogic Meson G12A SoC.
+ *
+ * Copyright (c) 2018 Amlogic, Inc. All rights reserved.
+ * Author: Xingyu Chen <xingyu.chen@amlogic.com>
+ * Author: Yixun Lan <yixun.lan@amlogic.com>
+ */
+
+#include <dt-bindings/gpio/meson-g12a-gpio.h>
+#include "pinctrl-meson.h"
+#include "pinctrl-meson-axg-pmx.h"
+
+static const struct pinctrl_pin_desc meson_g12a_periphs_pins[] = {
+       MESON_PIN(GPIOZ_0),
+       MESON_PIN(GPIOZ_1),
+       MESON_PIN(GPIOZ_2),
+       MESON_PIN(GPIOZ_3),
+       MESON_PIN(GPIOZ_4),
+       MESON_PIN(GPIOZ_5),
+       MESON_PIN(GPIOZ_6),
+       MESON_PIN(GPIOZ_7),
+       MESON_PIN(GPIOZ_8),
+       MESON_PIN(GPIOZ_9),
+       MESON_PIN(GPIOZ_10),
+       MESON_PIN(GPIOZ_11),
+       MESON_PIN(GPIOZ_12),
+       MESON_PIN(GPIOZ_13),
+       MESON_PIN(GPIOZ_14),
+       MESON_PIN(GPIOZ_15),
+       MESON_PIN(GPIOH_0),
+       MESON_PIN(GPIOH_1),
+       MESON_PIN(GPIOH_2),
+       MESON_PIN(GPIOH_3),
+       MESON_PIN(GPIOH_4),
+       MESON_PIN(GPIOH_5),
+       MESON_PIN(GPIOH_6),
+       MESON_PIN(GPIOH_7),
+       MESON_PIN(GPIOH_8),
+       MESON_PIN(BOOT_0),
+       MESON_PIN(BOOT_1),
+       MESON_PIN(BOOT_2),
+       MESON_PIN(BOOT_3),
+       MESON_PIN(BOOT_4),
+       MESON_PIN(BOOT_5),
+       MESON_PIN(BOOT_6),
+       MESON_PIN(BOOT_7),
+       MESON_PIN(BOOT_8),
+       MESON_PIN(BOOT_9),
+       MESON_PIN(BOOT_10),
+       MESON_PIN(BOOT_11),
+       MESON_PIN(BOOT_12),
+       MESON_PIN(BOOT_13),
+       MESON_PIN(BOOT_14),
+       MESON_PIN(BOOT_15),
+       MESON_PIN(GPIOC_0),
+       MESON_PIN(GPIOC_1),
+       MESON_PIN(GPIOC_2),
+       MESON_PIN(GPIOC_3),
+       MESON_PIN(GPIOC_4),
+       MESON_PIN(GPIOC_5),
+       MESON_PIN(GPIOC_6),
+       MESON_PIN(GPIOC_7),
+       MESON_PIN(GPIOA_0),
+       MESON_PIN(GPIOA_1),
+       MESON_PIN(GPIOA_2),
+       MESON_PIN(GPIOA_3),
+       MESON_PIN(GPIOA_4),
+       MESON_PIN(GPIOA_5),
+       MESON_PIN(GPIOA_6),
+       MESON_PIN(GPIOA_7),
+       MESON_PIN(GPIOA_8),
+       MESON_PIN(GPIOA_9),
+       MESON_PIN(GPIOA_10),
+       MESON_PIN(GPIOA_11),
+       MESON_PIN(GPIOA_12),
+       MESON_PIN(GPIOA_13),
+       MESON_PIN(GPIOA_14),
+       MESON_PIN(GPIOA_15),
+       MESON_PIN(GPIOX_0),
+       MESON_PIN(GPIOX_1),
+       MESON_PIN(GPIOX_2),
+       MESON_PIN(GPIOX_3),
+       MESON_PIN(GPIOX_4),
+       MESON_PIN(GPIOX_5),
+       MESON_PIN(GPIOX_6),
+       MESON_PIN(GPIOX_7),
+       MESON_PIN(GPIOX_8),
+       MESON_PIN(GPIOX_9),
+       MESON_PIN(GPIOX_10),
+       MESON_PIN(GPIOX_11),
+       MESON_PIN(GPIOX_12),
+       MESON_PIN(GPIOX_13),
+       MESON_PIN(GPIOX_14),
+       MESON_PIN(GPIOX_15),
+       MESON_PIN(GPIOX_16),
+       MESON_PIN(GPIOX_17),
+       MESON_PIN(GPIOX_18),
+       MESON_PIN(GPIOX_19),
+};
+
+static const struct pinctrl_pin_desc meson_g12a_aobus_pins[] = {
+       MESON_PIN(GPIOAO_0),
+       MESON_PIN(GPIOAO_1),
+       MESON_PIN(GPIOAO_2),
+       MESON_PIN(GPIOAO_3),
+       MESON_PIN(GPIOAO_4),
+       MESON_PIN(GPIOAO_5),
+       MESON_PIN(GPIOAO_6),
+       MESON_PIN(GPIOAO_7),
+       MESON_PIN(GPIOAO_8),
+       MESON_PIN(GPIOAO_9),
+       MESON_PIN(GPIOAO_10),
+       MESON_PIN(GPIOAO_11),
+       MESON_PIN(GPIOE_0),
+       MESON_PIN(GPIOE_1),
+       MESON_PIN(GPIOE_2),
+};
+
+/* emmc */
+static const unsigned int emmc_nand_d0_pins[]          = { BOOT_0 };
+static const unsigned int emmc_nand_d1_pins[]          = { BOOT_1 };
+static const unsigned int emmc_nand_d2_pins[]          = { BOOT_2 };
+static const unsigned int emmc_nand_d3_pins[]          = { BOOT_3 };
+static const unsigned int emmc_nand_d4_pins[]          = { BOOT_4 };
+static const unsigned int emmc_nand_d5_pins[]          = { BOOT_5 };
+static const unsigned int emmc_nand_d6_pins[]          = { BOOT_6 };
+static const unsigned int emmc_nand_d7_pins[]          = { BOOT_7 };
+static const unsigned int emmc_clk_pins[]              = { BOOT_8 };
+static const unsigned int emmc_cmd_pins[]              = { BOOT_10 };
+static const unsigned int emmc_nand_ds_pins[]          = { BOOT_13 };
+
+/* nand */
+static const unsigned int nand_wen_clk_pins[]          = { BOOT_8 };
+static const unsigned int nand_ale_pins[]              = { BOOT_9 };
+static const unsigned int nand_cle_pins[]              = { BOOT_10 };
+static const unsigned int nand_ce0_pins[]              = { BOOT_11 };
+static const unsigned int nand_ren_wr_pins[]           = { BOOT_12 };
+static const unsigned int nand_rb0_pins[]              = { BOOT_14 };
+static const unsigned int nand_ce1_pins[]              = { BOOT_15 };
+
+/* nor */
+static const unsigned int nor_hold_pins[]              = { BOOT_3 };
+static const unsigned int nor_d_pins[]                 = { BOOT_4 };
+static const unsigned int nor_q_pins[]                 = { BOOT_5 };
+static const unsigned int nor_c_pins[]                 = { BOOT_6 };
+static const unsigned int nor_wp_pins[]                        = { BOOT_7 };
+static const unsigned int nor_cs_pins[]                        = { BOOT_14 };
+
+/* sdio */
+static const unsigned int sdio_d0_pins[]               = { GPIOX_0 };
+static const unsigned int sdio_d1_pins[]               = { GPIOX_1 };
+static const unsigned int sdio_d2_pins[]               = { GPIOX_2 };
+static const unsigned int sdio_d3_pins[]               = { GPIOX_3 };
+static const unsigned int sdio_clk_pins[]              = { GPIOX_4 };
+static const unsigned int sdio_cmd_pins[]              = { GPIOX_5 };
+
+/* sdcard */
+static const unsigned int sdcard_d0_c_pins[]           = { GPIOC_0 };
+static const unsigned int sdcard_d1_c_pins[]           = { GPIOC_1 };
+static const unsigned int sdcard_d2_c_pins[]           = { GPIOC_2 };
+static const unsigned int sdcard_d3_c_pins[]           = { GPIOC_3 };
+static const unsigned int sdcard_clk_c_pins[]          = { GPIOC_4 };
+static const unsigned int sdcard_cmd_c_pins[]          = { GPIOC_5 };
+
+static const unsigned int sdcard_d0_z_pins[]           = { GPIOZ_2 };
+static const unsigned int sdcard_d1_z_pins[]           = { GPIOZ_3 };
+static const unsigned int sdcard_d2_z_pins[]           = { GPIOZ_4 };
+static const unsigned int sdcard_d3_z_pins[]           = { GPIOZ_5 };
+static const unsigned int sdcard_clk_z_pins[]          = { GPIOZ_6 };
+static const unsigned int sdcard_cmd_z_pins[]          = { GPIOZ_7 };
+
+/* spi0 */
+static const unsigned int spi0_mosi_c_pins[]           = { GPIOC_0 };
+static const unsigned int spi0_miso_c_pins[]           = { GPIOC_1 };
+static const unsigned int spi0_ss0_c_pins[]            = { GPIOC_2 };
+static const unsigned int spi0_clk_c_pins[]            = { GPIOC_3 };
+
+static const unsigned int spi0_mosi_x_pins[]           = { GPIOX_8 };
+static const unsigned int spi0_miso_x_pins[]           = { GPIOX_9 };
+static const unsigned int spi0_ss0_x_pins[]            = { GPIOX_10 };
+static const unsigned int spi0_clk_x_pins[]            = { GPIOX_11 };
+
+/* spi1 */
+static const unsigned int spi1_mosi_pins[]             = { GPIOH_4 };
+static const unsigned int spi1_miso_pins[]             = { GPIOH_5 };
+static const unsigned int spi1_ss0_pins[]              = { GPIOH_6 };
+static const unsigned int spi1_clk_pins[]              = { GPIOH_7 };
+
+/* i2c0 */
+static const unsigned int i2c0_sda_c_pins[]            = { GPIOC_5 };
+static const unsigned int i2c0_sck_c_pins[]            = { GPIOC_6 };
+static const unsigned int i2c0_sda_z0_pins[]           = { GPIOZ_0 };
+static const unsigned int i2c0_sck_z1_pins[]           = { GPIOZ_1 };
+static const unsigned int i2c0_sda_z7_pins[]           = { GPIOZ_7 };
+static const unsigned int i2c0_sck_z8_pins[]           = { GPIOZ_8 };
+
+/* i2c1 */
+static const unsigned int i2c1_sda_x_pins[]            = { GPIOX_10 };
+static const unsigned int i2c1_sck_x_pins[]            = { GPIOX_11 };
+static const unsigned int i2c1_sda_h2_pins[]           = { GPIOH_2 };
+static const unsigned int i2c1_sck_h3_pins[]           = { GPIOH_3 };
+static const unsigned int i2c1_sda_h6_pins[]           = { GPIOH_6 };
+static const unsigned int i2c1_sck_h7_pins[]           = { GPIOH_7 };
+
+/* i2c2 */
+static const unsigned int i2c2_sda_x_pins[]            = { GPIOX_17 };
+static const unsigned int i2c2_sck_x_pins[]            = { GPIOX_18 };
+static const unsigned int i2c2_sda_z_pins[]            = { GPIOZ_14 };
+static const unsigned int i2c2_sck_z_pins[]            = { GPIOZ_15 };
+
+/* i2c3 */
+static const unsigned int i2c3_sda_h_pins[]            = { GPIOH_0 };
+static const unsigned int i2c3_sck_h_pins[]            = { GPIOH_1 };
+static const unsigned int i2c3_sda_a_pins[]            = { GPIOA_14 };
+static const unsigned int i2c3_sck_a_pins[]            = { GPIOA_15 };
+
+/* uart_a */
+static const unsigned int uart_a_tx_pins[]             = { GPIOX_12 };
+static const unsigned int uart_a_rx_pins[]             = { GPIOX_13 };
+static const unsigned int uart_a_cts_pins[]            = { GPIOX_14 };
+static const unsigned int uart_a_rts_pins[]            = { GPIOX_15 };
+
+/* uart_b */
+static const unsigned int uart_b_tx_pins[]             = { GPIOX_6 };
+static const unsigned int uart_b_rx_pins[]             = { GPIOX_7 };
+
+/* uart_c */
+static const unsigned int uart_c_rts_pins[]            = { GPIOH_4 };
+static const unsigned int uart_c_cts_pins[]            = { GPIOH_5 };
+static const unsigned int uart_c_rx_pins[]             = { GPIOH_6 };
+static const unsigned int uart_c_tx_pins[]             = { GPIOH_7 };
+
+/* uart_ao_a_c */
+static const unsigned int uart_ao_a_rx_c_pins[]                = { GPIOC_2 };
+static const unsigned int uart_ao_a_tx_c_pins[]                = { GPIOC_3 };
+
+/* iso7816 */
+static const unsigned int iso7816_clk_c_pins[]         = { GPIOC_5 };
+static const unsigned int iso7816_data_c_pins[]                = { GPIOC_6 };
+static const unsigned int iso7816_clk_x_pins[]         = { GPIOX_8 };
+static const unsigned int iso7816_data_x_pins[]                = { GPIOX_9 };
+static const unsigned int iso7816_clk_h_pins[]         = { GPIOH_6 };
+static const unsigned int iso7816_data_h_pins[]                = { GPIOH_7 };
+static const unsigned int iso7816_clk_z_pins[]         = { GPIOZ_0 };
+static const unsigned int iso7816_data_z_pins[]                = { GPIOZ_1 };
+
+/* eth */
+static const unsigned int eth_mdio_pins[]              = { GPIOZ_0 };
+static const unsigned int eth_mdc_pins[]               = { GPIOZ_1 };
+static const unsigned int eth_rgmii_rx_clk_pins[]      = { GPIOZ_2 };
+static const unsigned int eth_rx_dv_pins[]             = { GPIOZ_3 };
+static const unsigned int eth_rxd0_pins[]              = { GPIOZ_4 };
+static const unsigned int eth_rxd1_pins[]              = { GPIOZ_5 };
+static const unsigned int eth_rxd2_rgmii_pins[]                = { GPIOZ_6 };
+static const unsigned int eth_rxd3_rgmii_pins[]                = { GPIOZ_7 };
+static const unsigned int eth_rgmii_tx_clk_pins[]      = { GPIOZ_8 };
+static const unsigned int eth_txen_pins[]              = { GPIOZ_9 };
+static const unsigned int eth_txd0_pins[]              = { GPIOZ_10 };
+static const unsigned int eth_txd1_pins[]              = { GPIOZ_11 };
+static const unsigned int eth_txd2_rgmii_pins[]                = { GPIOZ_12 };
+static const unsigned int eth_txd3_rgmii_pins[]                = { GPIOZ_13 };
+static const unsigned int eth_link_led_pins[]          = { GPIOZ_14 };
+static const unsigned int eth_act_led_pins[]           = { GPIOZ_15 };
+
+/* pwm_a */
+static const unsigned int pwm_a_pins[]                 = { GPIOX_6 };
+
+/* pwm_b */
+static const unsigned int pwm_b_x7_pins[]              = { GPIOX_7 };
+static const unsigned int pwm_b_x19_pins[]             = { GPIOX_19 };
+
+/* pwm_c */
+static const unsigned int pwm_c_c_pins[]               = { GPIOC_4 };
+static const unsigned int pwm_c_x5_pins[]              = { GPIOX_5 };
+static const unsigned int pwm_c_x8_pins[]              = { GPIOX_8 };
+
+/* pwm_d */
+static const unsigned int pwm_d_x3_pins[]              = { GPIOX_3 };
+static const unsigned int pwm_d_x6_pins[]              = { GPIOX_6 };
+
+/* pwm_e */
+static const unsigned int pwm_e_pins[]                 = { GPIOX_16 };
+
+/* pwm_f */
+static const unsigned int pwm_f_x_pins[]               = { GPIOX_7 };
+static const unsigned int pwm_f_h_pins[]               = { GPIOH_5 };
+
+/* cec_ao */
+static const unsigned int cec_ao_a_h_pins[]            = { GPIOH_3 };
+static const unsigned int cec_ao_b_h_pins[]            = { GPIOH_3 };
+
+/* jtag_b */
+static const unsigned int jtag_b_tdo_pins[]            = { GPIOC_0 };
+static const unsigned int jtag_b_tdi_pins[]            = { GPIOC_1 };
+static const unsigned int jtag_b_clk_pins[]            = { GPIOC_4 };
+static const unsigned int jtag_b_tms_pins[]            = { GPIOC_5 };
+
+/* bt565_a */
+static const unsigned int bt565_a_vs_pins[]            = { GPIOZ_0 };
+static const unsigned int bt565_a_hs_pins[]            = { GPIOZ_1 };
+static const unsigned int bt565_a_clk_pins[]           = { GPIOZ_3 };
+static const unsigned int bt565_a_din0_pins[]          = { GPIOZ_4 };
+static const unsigned int bt565_a_din1_pins[]          = { GPIOZ_5 };
+static const unsigned int bt565_a_din2_pins[]          = { GPIOZ_6 };
+static const unsigned int bt565_a_din3_pins[]          = { GPIOZ_7 };
+static const unsigned int bt565_a_din4_pins[]          = { GPIOZ_8 };
+static const unsigned int bt565_a_din5_pins[]          = { GPIOZ_9 };
+static const unsigned int bt565_a_din6_pins[]          = { GPIOZ_10 };
+static const unsigned int bt565_a_din7_pins[]          = { GPIOZ_11 };
+
+/* tsin_a */
+static const unsigned int tsin_a_valid_pins[]          = { GPIOX_2 };
+static const unsigned int tsin_a_sop_pins[]            = { GPIOX_1 };
+static const unsigned int tsin_a_din0_pins[]           = { GPIOX_0 };
+static const unsigned int tsin_a_clk_pins[]            = { GPIOX_3 };
+
+/* tsin_b */
+static const unsigned int tsin_b_valid_x_pins[]                = { GPIOX_9 };
+static const unsigned int tsin_b_sop_x_pins[]          = { GPIOX_8 };
+static const unsigned int tsin_b_din0_x_pins[]         = { GPIOX_10 };
+static const unsigned int tsin_b_clk_x_pins[]          = { GPIOX_11 };
+
+static const unsigned int tsin_b_valid_z_pins[]                = { GPIOZ_2 };
+static const unsigned int tsin_b_sop_z_pins[]          = { GPIOZ_3 };
+static const unsigned int tsin_b_din0_z_pins[]         = { GPIOZ_4 };
+static const unsigned int tsin_b_clk_z_pins[]          = { GPIOZ_5 };
+
+static const unsigned int tsin_b_fail_pins[]           = { GPIOZ_6 };
+static const unsigned int tsin_b_din1_pins[]           = { GPIOZ_7 };
+static const unsigned int tsin_b_din2_pins[]           = { GPIOZ_8 };
+static const unsigned int tsin_b_din3_pins[]           = { GPIOZ_9 };
+static const unsigned int tsin_b_din4_pins[]           = { GPIOZ_10 };
+static const unsigned int tsin_b_din5_pins[]           = { GPIOZ_11 };
+static const unsigned int tsin_b_din6_pins[]           = { GPIOZ_12 };
+static const unsigned int tsin_b_din7_pins[]           = { GPIOZ_13 };
+
+/* hdmitx */
+static const unsigned int hdmitx_sda_pins[]            = { GPIOH_0 };
+static const unsigned int hdmitx_sck_pins[]            = { GPIOH_1 };
+static const unsigned int hdmitx_hpd_in_pins[]         = { GPIOH_2 };
+
+/* pdm */
+static const unsigned int pdm_din0_c_pins[]            = { GPIOC_0 };
+static const unsigned int pdm_din1_c_pins[]            = { GPIOC_1 };
+static const unsigned int pdm_din2_c_pins[]            = { GPIOC_2 };
+static const unsigned int pdm_din3_c_pins[]            = { GPIOC_3 };
+static const unsigned int pdm_dclk_c_pins[]            = { GPIOC_4 };
+
+static const unsigned int pdm_din0_x_pins[]            = { GPIOX_0 };
+static const unsigned int pdm_din1_x_pins[]            = { GPIOX_1 };
+static const unsigned int pdm_din2_x_pins[]            = { GPIOX_2 };
+static const unsigned int pdm_din3_x_pins[]            = { GPIOX_3 };
+static const unsigned int pdm_dclk_x_pins[]            = { GPIOX_4 };
+
+static const unsigned int pdm_din0_z_pins[]            = { GPIOZ_2 };
+static const unsigned int pdm_din1_z_pins[]            = { GPIOZ_3 };
+static const unsigned int pdm_din2_z_pins[]            = { GPIOZ_4 };
+static const unsigned int pdm_din3_z_pins[]            = { GPIOZ_5 };
+static const unsigned int pdm_dclk_z_pins[]            = { GPIOZ_6 };
+
+static const unsigned int pdm_din0_a_pins[]            = { GPIOA_8 };
+static const unsigned int pdm_din1_a_pins[]            = { GPIOA_9 };
+static const unsigned int pdm_din2_a_pins[]            = { GPIOA_6 };
+static const unsigned int pdm_din3_a_pins[]            = { GPIOA_5 };
+static const unsigned int pdm_dclk_a_pins[]            = { GPIOA_7 };
+
+/* spdif_in */
+static const unsigned int spdif_in_h_pins[]            = { GPIOH_5 };
+static const unsigned int spdif_in_a10_pins[]          = { GPIOA_10 };
+static const unsigned int spdif_in_a12_pins[]          = { GPIOA_12 };
+
+/* spdif_out */
+static const unsigned int spdif_out_h_pins[]           = { GPIOH_4 };
+static const unsigned int spdif_out_a11_pins[]         = { GPIOA_11 };
+static const unsigned int spdif_out_a13_pins[]         = { GPIOA_13 };
+
+/* mclk0 */
+static const unsigned int mclk0_a_pins[]               = { GPIOA_0 };
+
+/* mclk1 */
+static const unsigned int mclk1_x_pins[]               = { GPIOX_5 };
+static const unsigned int mclk1_z_pins[]               = { GPIOZ_8 };
+static const unsigned int mclk1_a_pins[]               = { GPIOA_11 };
+
+/* tdm */
+static const unsigned int tdm_a_slv_sclk_pins[]                = { GPIOX_11 };
+static const unsigned int tdm_a_slv_fs_pins[]          = { GPIOX_10 };
+static const unsigned int tdm_a_sclk_pins[]            = { GPIOX_11 };
+static const unsigned int tdm_a_fs_pins[]              = { GPIOX_10 };
+static const unsigned int tdm_a_din0_pins[]            = { GPIOX_9 };
+static const unsigned int tdm_a_din1_pins[]            = { GPIOX_8 };
+static const unsigned int tdm_a_dout0_pins[]           = { GPIOX_9 };
+static const unsigned int tdm_a_dout1_pins[]           = { GPIOX_8 };
+
+static const unsigned int tdm_b_slv_sclk_pins[]                = { GPIOA_1 };
+static const unsigned int tdm_b_slv_fs_pins[]          = { GPIOA_2 };
+static const unsigned int tdm_b_sclk_pins[]            = { GPIOA_1 };
+static const unsigned int tdm_b_fs_pins[]              = { GPIOA_2 };
+static const unsigned int tdm_b_din0_pins[]            = { GPIOA_3 };
+static const unsigned int tdm_b_din1_pins[]            = { GPIOA_4 };
+static const unsigned int tdm_b_din2_pins[]            = { GPIOA_5 };
+static const unsigned int tdm_b_din3_a_pins[]          = { GPIOA_6 };
+static const unsigned int tdm_b_din3_h_pins[]          = { GPIOH_5 };
+static const unsigned int tdm_b_dout0_pins[]           = { GPIOA_3 };
+static const unsigned int tdm_b_dout1_pins[]           = { GPIOA_4 };
+static const unsigned int tdm_b_dout2_pins[]           = { GPIOA_5 };
+static const unsigned int tdm_b_dout3_a_pins[]         = { GPIOA_6 };
+static const unsigned int tdm_b_dout3_h_pins[]         = { GPIOH_5 };
+
+static const unsigned int tdm_c_slv_sclk_a_pins[]      = { GPIOA_12 };
+static const unsigned int tdm_c_slv_fs_a_pins[]                = { GPIOA_13 };
+static const unsigned int tdm_c_slv_sclk_z_pins[]      = { GPIOZ_7 };
+static const unsigned int tdm_c_slv_fs_z_pins[]                = { GPIOZ_6 };
+static const unsigned int tdm_c_sclk_a_pins[]          = { GPIOA_12 };
+static const unsigned int tdm_c_fs_a_pins[]            = { GPIOA_13 };
+static const unsigned int tdm_c_sclk_z_pins[]          = { GPIOZ_7 };
+static const unsigned int tdm_c_fs_z_pins[]            = { GPIOZ_6 };
+static const unsigned int tdm_c_din0_a_pins[]          = { GPIOA_10 };
+static const unsigned int tdm_c_din1_a_pins[]          = { GPIOA_9 };
+static const unsigned int tdm_c_din2_a_pins[]          = { GPIOA_8 };
+static const unsigned int tdm_c_din3_a_pins[]          = { GPIOA_7 };
+static const unsigned int tdm_c_din0_z_pins[]          = { GPIOZ_2 };
+static const unsigned int tdm_c_din1_z_pins[]          = { GPIOZ_3 };
+static const unsigned int tdm_c_din2_z_pins[]          = { GPIOZ_4 };
+static const unsigned int tdm_c_din3_z_pins[]          = { GPIOZ_5 };
+static const unsigned int tdm_c_dout0_a_pins[]         = { GPIOA_10 };
+static const unsigned int tdm_c_dout1_a_pins[]         = { GPIOA_9 };
+static const unsigned int tdm_c_dout2_a_pins[]         = { GPIOA_8 };
+static const unsigned int tdm_c_dout3_a_pins[]         = { GPIOA_7 };
+static const unsigned int tdm_c_dout0_z_pins[]         = { GPIOZ_2 };
+static const unsigned int tdm_c_dout1_z_pins[]         = { GPIOZ_3 };
+static const unsigned int tdm_c_dout2_z_pins[]         = { GPIOZ_4 };
+static const unsigned int tdm_c_dout3_z_pins[]         = { GPIOZ_5 };
+
+static struct meson_pmx_group meson_g12a_periphs_groups[] = {
+       GPIO_GROUP(GPIOZ_0),
+       GPIO_GROUP(GPIOZ_1),
+       GPIO_GROUP(GPIOZ_2),
+       GPIO_GROUP(GPIOZ_3),
+       GPIO_GROUP(GPIOZ_4),
+       GPIO_GROUP(GPIOZ_5),
+       GPIO_GROUP(GPIOZ_6),
+       GPIO_GROUP(GPIOZ_7),
+       GPIO_GROUP(GPIOZ_8),
+       GPIO_GROUP(GPIOZ_9),
+       GPIO_GROUP(GPIOZ_10),
+       GPIO_GROUP(GPIOZ_11),
+       GPIO_GROUP(GPIOZ_12),
+       GPIO_GROUP(GPIOZ_13),
+       GPIO_GROUP(GPIOZ_14),
+       GPIO_GROUP(GPIOZ_15),
+       GPIO_GROUP(GPIOH_0),
+       GPIO_GROUP(GPIOH_1),
+       GPIO_GROUP(GPIOH_2),
+       GPIO_GROUP(GPIOH_3),
+       GPIO_GROUP(GPIOH_4),
+       GPIO_GROUP(GPIOH_5),
+       GPIO_GROUP(GPIOH_6),
+       GPIO_GROUP(GPIOH_7),
+       GPIO_GROUP(GPIOH_8),
+       GPIO_GROUP(BOOT_0),
+       GPIO_GROUP(BOOT_1),
+       GPIO_GROUP(BOOT_2),
+       GPIO_GROUP(BOOT_3),
+       GPIO_GROUP(BOOT_4),
+       GPIO_GROUP(BOOT_5),
+       GPIO_GROUP(BOOT_6),
+       GPIO_GROUP(BOOT_7),
+       GPIO_GROUP(BOOT_8),
+       GPIO_GROUP(BOOT_9),
+       GPIO_GROUP(BOOT_10),
+       GPIO_GROUP(BOOT_11),
+       GPIO_GROUP(BOOT_12),
+       GPIO_GROUP(BOOT_13),
+       GPIO_GROUP(BOOT_14),
+       GPIO_GROUP(BOOT_15),
+       GPIO_GROUP(GPIOC_0),
+       GPIO_GROUP(GPIOC_1),
+       GPIO_GROUP(GPIOC_2),
+       GPIO_GROUP(GPIOC_3),
+       GPIO_GROUP(GPIOC_4),
+       GPIO_GROUP(GPIOC_5),
+       GPIO_GROUP(GPIOC_6),
+       GPIO_GROUP(GPIOC_7),
+       GPIO_GROUP(GPIOA_0),
+       GPIO_GROUP(GPIOA_1),
+       GPIO_GROUP(GPIOA_2),
+       GPIO_GROUP(GPIOA_3),
+       GPIO_GROUP(GPIOA_4),
+       GPIO_GROUP(GPIOA_5),
+       GPIO_GROUP(GPIOA_6),
+       GPIO_GROUP(GPIOA_7),
+       GPIO_GROUP(GPIOA_8),
+       GPIO_GROUP(GPIOA_9),
+       GPIO_GROUP(GPIOA_10),
+       GPIO_GROUP(GPIOA_11),
+       GPIO_GROUP(GPIOA_12),
+       GPIO_GROUP(GPIOA_13),
+       GPIO_GROUP(GPIOA_14),
+       GPIO_GROUP(GPIOA_15),
+       GPIO_GROUP(GPIOX_0),
+       GPIO_GROUP(GPIOX_1),
+       GPIO_GROUP(GPIOX_2),
+       GPIO_GROUP(GPIOX_3),
+       GPIO_GROUP(GPIOX_4),
+       GPIO_GROUP(GPIOX_5),
+       GPIO_GROUP(GPIOX_6),
+       GPIO_GROUP(GPIOX_7),
+       GPIO_GROUP(GPIOX_8),
+       GPIO_GROUP(GPIOX_9),
+       GPIO_GROUP(GPIOX_10),
+       GPIO_GROUP(GPIOX_11),
+       GPIO_GROUP(GPIOX_12),
+       GPIO_GROUP(GPIOX_13),
+       GPIO_GROUP(GPIOX_14),
+       GPIO_GROUP(GPIOX_15),
+       GPIO_GROUP(GPIOX_16),
+       GPIO_GROUP(GPIOX_17),
+       GPIO_GROUP(GPIOX_18),
+       GPIO_GROUP(GPIOX_19),
+
+       /* bank BOOT */
+       GROUP(emmc_nand_d0,             1),
+       GROUP(emmc_nand_d1,             1),
+       GROUP(emmc_nand_d2,             1),
+       GROUP(emmc_nand_d3,             1),
+       GROUP(emmc_nand_d4,             1),
+       GROUP(emmc_nand_d5,             1),
+       GROUP(emmc_nand_d6,             1),
+       GROUP(emmc_nand_d7,             1),
+       GROUP(emmc_clk,                 1),
+       GROUP(emmc_cmd,                 1),
+       GROUP(emmc_nand_ds,             1),
+       GROUP(nand_ce0,                 2),
+       GROUP(nand_ale,                 2),
+       GROUP(nand_cle,                 2),
+       GROUP(nand_wen_clk,             2),
+       GROUP(nand_ren_wr,              2),
+       GROUP(nand_rb0,                 2),
+       GROUP(nand_ce1,                 2),
+       GROUP(nor_hold,                 3),
+       GROUP(nor_d,                    3),
+       GROUP(nor_q,                    3),
+       GROUP(nor_c,                    3),
+       GROUP(nor_wp,                   3),
+       GROUP(nor_cs,                   3),
+
+       /* bank GPIOZ */
+       GROUP(sdcard_d0_z,              5),
+       GROUP(sdcard_d1_z,              5),
+       GROUP(sdcard_d2_z,              5),
+       GROUP(sdcard_d3_z,              5),
+       GROUP(sdcard_clk_z,             5),
+       GROUP(sdcard_cmd_z,             5),
+       GROUP(i2c0_sda_z0,              4),
+       GROUP(i2c0_sck_z1,              4),
+       GROUP(i2c0_sda_z7,              7),
+       GROUP(i2c0_sck_z8,              7),
+       GROUP(i2c2_sda_z,               3),
+       GROUP(i2c2_sck_z,               3),
+       GROUP(iso7816_clk_z,            3),
+       GROUP(iso7816_data_z,           3),
+       GROUP(eth_mdio,                 1),
+       GROUP(eth_mdc,                  1),
+       GROUP(eth_rgmii_rx_clk,         1),
+       GROUP(eth_rx_dv,                1),
+       GROUP(eth_rxd0,                 1),
+       GROUP(eth_rxd1,                 1),
+       GROUP(eth_rxd2_rgmii,           1),
+       GROUP(eth_rxd3_rgmii,           1),
+       GROUP(eth_rgmii_tx_clk,         1),
+       GROUP(eth_txen,                 1),
+       GROUP(eth_txd0,                 1),
+       GROUP(eth_txd1,                 1),
+       GROUP(eth_txd2_rgmii,           1),
+       GROUP(eth_txd3_rgmii,           1),
+       GROUP(eth_link_led,             1),
+       GROUP(eth_act_led,              1),
+       GROUP(bt565_a_vs,               2),
+       GROUP(bt565_a_hs,               2),
+       GROUP(bt565_a_clk,              2),
+       GROUP(bt565_a_din0,             2),
+       GROUP(bt565_a_din1,             2),
+       GROUP(bt565_a_din2,             2),
+       GROUP(bt565_a_din3,             2),
+       GROUP(bt565_a_din4,             2),
+       GROUP(bt565_a_din5,             2),
+       GROUP(bt565_a_din6,             2),
+       GROUP(bt565_a_din7,             2),
+       GROUP(tsin_b_valid_z,           3),
+       GROUP(tsin_b_sop_z,             3),
+       GROUP(tsin_b_din0_z,            3),
+       GROUP(tsin_b_clk_z,             3),
+       GROUP(tsin_b_fail,              3),
+       GROUP(tsin_b_din1,              3),
+       GROUP(tsin_b_din2,              3),
+       GROUP(tsin_b_din3,              3),
+       GROUP(tsin_b_din4,              3),
+       GROUP(tsin_b_din5,              3),
+       GROUP(tsin_b_din6,              3),
+       GROUP(tsin_b_din7,              3),
+       GROUP(pdm_din0_z,               7),
+       GROUP(pdm_din1_z,               7),
+       GROUP(pdm_din2_z,               7),
+       GROUP(pdm_din3_z,               7),
+       GROUP(pdm_dclk_z,               7),
+       GROUP(tdm_c_slv_sclk_z,         6),
+       GROUP(tdm_c_slv_fs_z,           6),
+       GROUP(tdm_c_din0_z,             6),
+       GROUP(tdm_c_din1_z,             6),
+       GROUP(tdm_c_din2_z,             6),
+       GROUP(tdm_c_din3_z,             6),
+       GROUP(tdm_c_sclk_z,             4),
+       GROUP(tdm_c_fs_z,               4),
+       GROUP(tdm_c_dout0_z,            4),
+       GROUP(tdm_c_dout1_z,            4),
+       GROUP(tdm_c_dout2_z,            4),
+       GROUP(tdm_c_dout3_z,            4),
+       GROUP(mclk1_z,                  4),
+
+       /* bank GPIOX */
+       GROUP(sdio_d0,                  1),
+       GROUP(sdio_d1,                  1),
+       GROUP(sdio_d2,                  1),
+       GROUP(sdio_d3,                  1),
+       GROUP(sdio_clk,                 1),
+       GROUP(sdio_cmd,                 1),
+       GROUP(spi0_mosi_x,              4),
+       GROUP(spi0_miso_x,              4),
+       GROUP(spi0_ss0_x,               4),
+       GROUP(spi0_clk_x,               4),
+       GROUP(i2c1_sda_x,               5),
+       GROUP(i2c1_sck_x,               5),
+       GROUP(i2c2_sda_x,               1),
+       GROUP(i2c2_sck_x,               1),
+       GROUP(uart_a_tx,                1),
+       GROUP(uart_a_rx,                1),
+       GROUP(uart_a_cts,               1),
+       GROUP(uart_a_rts,               1),
+       GROUP(uart_b_tx,                2),
+       GROUP(uart_b_rx,                2),
+       GROUP(iso7816_clk_x,            6),
+       GROUP(iso7816_data_x,           6),
+       GROUP(pwm_a,                    1),
+       GROUP(pwm_b_x7,                 4),
+       GROUP(pwm_b_x19,                1),
+       GROUP(pwm_c_x5,                 4),
+       GROUP(pwm_c_x8,                 5),
+       GROUP(pwm_d_x3,                 4),
+       GROUP(pwm_d_x6,                 4),
+       GROUP(pwm_e,                    1),
+       GROUP(pwm_f_x,                  1),
+       GROUP(tsin_a_valid,             3),
+       GROUP(tsin_a_sop,               3),
+       GROUP(tsin_a_din0,              3),
+       GROUP(tsin_a_clk,               3),
+       GROUP(tsin_b_valid_x,           3),
+       GROUP(tsin_b_sop_x,             3),
+       GROUP(tsin_b_din0_x,            3),
+       GROUP(tsin_b_clk_x,             3),
+       GROUP(pdm_din0_x,               2),
+       GROUP(pdm_din1_x,               2),
+       GROUP(pdm_din2_x,               2),
+       GROUP(pdm_din3_x,               2),
+       GROUP(pdm_dclk_x,               2),
+       GROUP(tdm_a_slv_sclk,           2),
+       GROUP(tdm_a_slv_fs,             2),
+       GROUP(tdm_a_din0,               2),
+       GROUP(tdm_a_din1,               2),
+       GROUP(tdm_a_sclk,               1),
+       GROUP(tdm_a_fs,                 1),
+       GROUP(tdm_a_dout0,              1),
+       GROUP(tdm_a_dout1,              1),
+       GROUP(mclk1_x,                  2),
+
+       /* bank GPIOC */
+       GROUP(sdcard_d0_c,              1),
+       GROUP(sdcard_d1_c,              1),
+       GROUP(sdcard_d2_c,              1),
+       GROUP(sdcard_d3_c,              1),
+       GROUP(sdcard_clk_c,             1),
+       GROUP(sdcard_cmd_c,             1),
+       GROUP(spi0_mosi_c,              5),
+       GROUP(spi0_miso_c,              5),
+       GROUP(spi0_ss0_c,               5),
+       GROUP(spi0_clk_c,               5),
+       GROUP(i2c0_sda_c,               3),
+       GROUP(i2c0_sck_c,               3),
+       GROUP(uart_ao_a_rx_c,           2),
+       GROUP(uart_ao_a_tx_c,           2),
+       GROUP(iso7816_clk_c,            5),
+       GROUP(iso7816_data_c,           5),
+       GROUP(pwm_c_c,                  5),
+       GROUP(jtag_b_tdo,               2),
+       GROUP(jtag_b_tdi,               2),
+       GROUP(jtag_b_clk,               2),
+       GROUP(jtag_b_tms,               2),
+       GROUP(pdm_din0_c,               4),
+       GROUP(pdm_din1_c,               4),
+       GROUP(pdm_din2_c,               4),
+       GROUP(pdm_din3_c,               4),
+       GROUP(pdm_dclk_c,               4),
+
+       /* bank GPIOH */
+       GROUP(spi1_mosi,                3),
+       GROUP(spi1_miso,                3),
+       GROUP(spi1_ss0,                 3),
+       GROUP(spi1_clk,                 3),
+       GROUP(i2c1_sda_h2,              2),
+       GROUP(i2c1_sck_h3,              2),
+       GROUP(i2c1_sda_h6,              4),
+       GROUP(i2c1_sck_h7,              4),
+       GROUP(i2c3_sda_h,               2),
+       GROUP(i2c3_sck_h,               2),
+       GROUP(uart_c_tx,                2),
+       GROUP(uart_c_rx,                2),
+       GROUP(uart_c_cts,               2),
+       GROUP(uart_c_rts,               2),
+       GROUP(iso7816_clk_h,            1),
+       GROUP(iso7816_data_h,           1),
+       GROUP(pwm_f_h,                  4),
+       GROUP(cec_ao_a_h,               4),
+       GROUP(cec_ao_b_h,               5),
+       GROUP(hdmitx_sda,               1),
+       GROUP(hdmitx_sck,               1),
+       GROUP(hdmitx_hpd_in,            1),
+       GROUP(spdif_out_h,              1),
+       GROUP(spdif_in_h,               1),
+       GROUP(tdm_b_din3_h,             6),
+       GROUP(tdm_b_dout3_h,            5),
+
+       /* bank GPIOA */
+       GROUP(i2c3_sda_a,               2),
+       GROUP(i2c3_sck_a,               2),
+       GROUP(pdm_din0_a,               1),
+       GROUP(pdm_din1_a,               1),
+       GROUP(pdm_din2_a,               1),
+       GROUP(pdm_din3_a,               1),
+       GROUP(pdm_dclk_a,               1),
+       GROUP(spdif_in_a10,             1),
+       GROUP(spdif_in_a12,             1),
+       GROUP(spdif_out_a11,            1),
+       GROUP(spdif_out_a13,            1),
+       GROUP(tdm_b_slv_sclk,           2),
+       GROUP(tdm_b_slv_fs,             2),
+       GROUP(tdm_b_din0,               2),
+       GROUP(tdm_b_din1,               2),
+       GROUP(tdm_b_din2,               2),
+       GROUP(tdm_b_din3_a,             2),
+       GROUP(tdm_b_sclk,               1),
+       GROUP(tdm_b_fs,                 1),
+       GROUP(tdm_b_dout0,              1),
+       GROUP(tdm_b_dout1,              1),
+       GROUP(tdm_b_dout2,              3),
+       GROUP(tdm_b_dout3_a,            3),
+       GROUP(tdm_c_slv_sclk_a,         3),
+       GROUP(tdm_c_slv_fs_a,           3),
+       GROUP(tdm_c_din0_a,             3),
+       GROUP(tdm_c_din1_a,             3),
+       GROUP(tdm_c_din2_a,             3),
+       GROUP(tdm_c_din3_a,             3),
+       GROUP(tdm_c_sclk_a,             2),
+       GROUP(tdm_c_fs_a,               2),
+       GROUP(tdm_c_dout0_a,            2),
+       GROUP(tdm_c_dout1_a,            2),
+       GROUP(tdm_c_dout2_a,            2),
+       GROUP(tdm_c_dout3_a,            2),
+       GROUP(mclk0_a,                  1),
+       GROUP(mclk1_a,                  2),
+};
+
+/* uart_ao_a */
+static const unsigned int uart_ao_a_tx_pins[]          = { GPIOAO_0 };
+static const unsigned int uart_ao_a_rx_pins[]          = { GPIOAO_1 };
+static const unsigned int uart_ao_a_cts_pins[]         = { GPIOE_0 };
+static const unsigned int uart_ao_a_rts_pins[]         = { GPIOE_1 };
+
+/* uart_ao_b */
+static const unsigned int uart_ao_b_tx_2_pins[]                = { GPIOAO_2 };
+static const unsigned int uart_ao_b_rx_3_pins[]                = { GPIOAO_3 };
+static const unsigned int uart_ao_b_tx_8_pins[]                = { GPIOAO_8 };
+static const unsigned int uart_ao_b_rx_9_pins[]                = { GPIOAO_9 };
+static const unsigned int uart_ao_b_cts_pins[]         = { GPIOE_0 };
+static const unsigned int uart_ao_b_rts_pins[]         = { GPIOE_1 };
+
+/* i2c_ao */
+static const unsigned int i2c_ao_sck_pins[]            = { GPIOAO_2 };
+static const unsigned int i2c_ao_sda_pins[]            = { GPIOAO_3 };
+
+static const unsigned int i2c_ao_sck_e_pins[]          = { GPIOE_0 };
+static const unsigned int i2c_ao_sda_e_pins[]          = { GPIOE_1 };
+
+/* i2c_ao_slave */
+static const unsigned int i2c_ao_slave_sck_pins[]      = { GPIOAO_2 };
+static const unsigned int i2c_ao_slave_sda_pins[]      = { GPIOAO_3 };
+
+/* ir_in */
+static const unsigned int remote_ao_input_pins[]       = { GPIOAO_5 };
+
+/* ir_out */
+static const unsigned int remote_ao_out_pins[]         = { GPIOAO_4 };
+
+/* pwm_ao_a */
+static const unsigned int pwm_ao_a_pins[]              = { GPIOAO_11 };
+static const unsigned int pwm_ao_a_hiz_pins[]          = { GPIOAO_11 };
+
+/* pwm_ao_b */
+static const unsigned int pwm_ao_b_pins[]              = { GPIOE_0 };
+
+/* pwm_ao_c */
+static const unsigned int pwm_ao_c_4_pins[]            = { GPIOAO_4 };
+static const unsigned int pwm_ao_c_hiz_pins[]          = { GPIOAO_4 };
+static const unsigned int pwm_ao_c_6_pins[]            = { GPIOAO_6 };
+
+/* pwm_ao_d */
+static const unsigned int pwm_ao_d_5_pins[]            = { GPIOAO_5 };
+static const unsigned int pwm_ao_d_10_pins[]           = { GPIOAO_10 };
+static const unsigned int pwm_ao_d_e_pins[]            = { GPIOE_1 };
+
+/* jtag_a */
+static const unsigned int jtag_a_tdi_pins[]            = { GPIOAO_8 };
+static const unsigned int jtag_a_tdo_pins[]            = { GPIOAO_9 };
+static const unsigned int jtag_a_clk_pins[]            = { GPIOAO_6 };
+static const unsigned int jtag_a_tms_pins[]            = { GPIOAO_7 };
+
+/* cec_ao */
+static const unsigned int cec_ao_a_pins[]              = { GPIOAO_10 };
+static const unsigned int cec_ao_b_pins[]              = { GPIOAO_10 };
+
+/* tsin_ao_a */
+static const unsigned int tsin_ao_asop_pins[]          = { GPIOAO_6 };
+static const unsigned int tsin_ao_adin0_pins[]         = { GPIOAO_7 };
+static const unsigned int tsin_ao_aclk_pins[]          = { GPIOAO_8 };
+static const unsigned int tsin_ao_a_valid_pins[]       = { GPIOAO_9 };
+
+/* spdif_ao_out */
+static const unsigned int spdif_ao_out_pins[]          = { GPIOAO_10 };
+
+/* tdm_ao_b */
+static const unsigned int tdm_ao_b_slv_fs_pins[]       = { GPIOAO_7 };
+static const unsigned int tdm_ao_b_slv_sclk_pins[]     = { GPIOAO_8 };
+static const unsigned int tdm_ao_b_fs_pins[]           = { GPIOAO_7 };
+static const unsigned int tdm_ao_b_sclk_pins[]         = { GPIOAO_8 };
+static const unsigned int tdm_ao_b_din0_pins[]         = { GPIOAO_4 };
+static const unsigned int tdm_ao_b_din1_pins[]         = { GPIOAO_10 };
+static const unsigned int tdm_ao_b_din2_pins[]         = { GPIOAO_6 };
+static const unsigned int tdm_ao_b_dout0_pins[]                = { GPIOAO_4 };
+static const unsigned int tdm_ao_b_dout1_pins[]                = { GPIOAO_10 };
+static const unsigned int tdm_ao_b_dout2_pins[]                = { GPIOAO_6 };
+
+/* mclk0_ao */
+static const unsigned int mclk0_ao_pins[]              = { GPIOAO_9 };
+
+static struct meson_pmx_group meson_g12a_aobus_groups[] = {
+       GPIO_GROUP(GPIOAO_0),
+       GPIO_GROUP(GPIOAO_1),
+       GPIO_GROUP(GPIOAO_2),
+       GPIO_GROUP(GPIOAO_3),
+       GPIO_GROUP(GPIOAO_4),
+       GPIO_GROUP(GPIOAO_5),
+       GPIO_GROUP(GPIOAO_6),
+       GPIO_GROUP(GPIOAO_7),
+       GPIO_GROUP(GPIOAO_8),
+       GPIO_GROUP(GPIOAO_9),
+       GPIO_GROUP(GPIOAO_10),
+       GPIO_GROUP(GPIOAO_11),
+       GPIO_GROUP(GPIOE_0),
+       GPIO_GROUP(GPIOE_1),
+       GPIO_GROUP(GPIOE_2),
+
+       /* bank AO */
+       GROUP(uart_ao_a_tx,             1),
+       GROUP(uart_ao_a_rx,             1),
+       GROUP(uart_ao_a_cts,            1),
+       GROUP(uart_ao_a_rts,            1),
+       GROUP(uart_ao_b_tx_2,           2),
+       GROUP(uart_ao_b_rx_3,           2),
+       GROUP(uart_ao_b_tx_8,           3),
+       GROUP(uart_ao_b_rx_9,           3),
+       GROUP(uart_ao_b_cts,            2),
+       GROUP(uart_ao_b_rts,            2),
+       GROUP(i2c_ao_sck,               1),
+       GROUP(i2c_ao_sda,               1),
+       GROUP(i2c_ao_sck_e,             4),
+       GROUP(i2c_ao_sda_e,             4),
+       GROUP(i2c_ao_slave_sck,         3),
+       GROUP(i2c_ao_slave_sda,         3),
+       GROUP(remote_ao_input,          1),
+       GROUP(remote_ao_out,            1),
+       GROUP(pwm_ao_a,                 3),
+       GROUP(pwm_ao_a_hiz,             2),
+       GROUP(pwm_ao_b,                 3),
+       GROUP(pwm_ao_c_4,               3),
+       GROUP(pwm_ao_c_hiz,             4),
+       GROUP(pwm_ao_c_6,               3),
+       GROUP(pwm_ao_d_5,               3),
+       GROUP(pwm_ao_d_10,              3),
+       GROUP(pwm_ao_d_e,               3),
+       GROUP(jtag_a_tdi,               1),
+       GROUP(jtag_a_tdo,               1),
+       GROUP(jtag_a_clk,               1),
+       GROUP(jtag_a_tms,               1),
+       GROUP(cec_ao_a,                 1),
+       GROUP(cec_ao_b,                 2),
+       GROUP(tsin_ao_asop,             4),
+       GROUP(tsin_ao_adin0,            4),
+       GROUP(tsin_ao_aclk,             4),
+       GROUP(tsin_ao_a_valid,          4),
+       GROUP(spdif_ao_out,             4),
+       GROUP(tdm_ao_b_dout0,           5),
+       GROUP(tdm_ao_b_dout1,           5),
+       GROUP(tdm_ao_b_dout2,           5),
+       GROUP(tdm_ao_b_fs,              5),
+       GROUP(tdm_ao_b_sclk,            5),
+       GROUP(tdm_ao_b_din0,            6),
+       GROUP(tdm_ao_b_din1,            6),
+       GROUP(tdm_ao_b_din2,            6),
+       GROUP(tdm_ao_b_slv_fs,          6),
+       GROUP(tdm_ao_b_slv_sclk,        6),
+       GROUP(mclk0_ao,                 5),
+};
+
+static const char * const gpio_periphs_groups[] = {
+       "GPIOZ_0", "GPIOZ_1", "GPIOZ_2", "GPIOZ_3", "GPIOZ_4",
+       "GPIOZ_5", "GPIOZ_6", "GPIOZ_7", "GPIOZ_8", "GPIOZ_9",
+       "GPIOZ_10", "GPIOZ_11", "GPIOZ_12", "GPIOZ_13", "GPIOZ_14",
+       "GPIOZ_15",
+
+       "GPIOH_0", "GPIOH_1", "GPIOH_2", "GPIOH_3", "GPIOH_4",
+       "GPIOH_5", "GPIOH_6", "GPIOH_7", "GPIOH_8",
+
+       "BOOT_0", "BOOT_1", "BOOT_2", "BOOT_3", "BOOT_4",
+       "BOOT_5", "BOOT_6", "BOOT_7", "BOOT_8", "BOOT_9",
+       "BOOT_10", "BOOT_11", "BOOT_12", "BOOT_13", "BOOT_14",
+       "BOOT_15",
+
+       "GPIOC_0", "GPIOC_1", "GPIOC_2", "GPIOC_3", "GPIOC_4",
+       "GPIOC_5", "GPIOC_6", "GPIOC_7",
+
+       "GPIOA_0", "GPIOA_1", "GPIOA_2", "GPIOA_3", "GPIOA_4",
+       "GPIOA_5", "GPIOA_6", "GPIOA_7", "GPIOA_8", "GPIOA_9",
+       "GPIOA_10", "GPIOA_11", "GPIOA_12", "GPIOA_13", "GPIOA_14",
+       "GPIOA_15",
+
+       "GPIOX_0", "GPIOX_1", "GPIOX_2", "GPIOX_3", "GPIOX_4",
+       "GPIOX_5", "GPIOX_6", "GPIOX_7", "GPIOX_8", "GPIOX_9",
+       "GPIOX_10", "GPIOX_11", "GPIOX_12", "GPIOX_13", "GPIOX_14",
+       "GPIOX_15", "GPIOX_16", "GPIOX_17", "GPIOX_18", "GPIOX_19",
+};
+
+static const char * const emmc_groups[] = {
+       "emmc_nand_d0", "emmc_nand_d1", "emmc_nand_d2",
+       "emmc_nand_d3", "emmc_nand_d4", "emmc_nand_d5",
+       "emmc_nand_d6", "emmc_nand_d7",
+       "emmc_clk", "emmc_cmd", "emmc_nand_ds",
+};
+
+static const char * const nand_groups[] = {
+       "emmc_nand_d0", "emmc_nand_d1", "emmc_nand_d2",
+       "emmc_nand_d3", "emmc_nand_d4", "emmc_nand_d5",
+       "emmc_nand_d6", "emmc_nand_d7",
+       "nand_ce0", "nand_ale", "nand_cle",
+       "nand_wen_clk", "nand_ren_wr", "nand_rb0",
+       "emmc_nand_ds", "nand_ce1",
+};
+
+static const char * const nor_groups[] = {
+       "nor_d", "nor_q", "nor_c", "nor_cs",
+       "nor_hold", "nor_wp",
+};
+
+static const char * const sdio_groups[] = {
+       "sdio_d0", "sdio_d1", "sdio_d2", "sdio_d3",
+       "sdio_cmd", "sdio_clk", "sdio_dummy",
+};
+
+static const char * const sdcard_groups[] = {
+       "sdcard_d0_c", "sdcard_d1_c", "sdcard_d2_c", "sdcard_d3_c",
+       "sdcard_clk_c", "sdcard_cmd_c",
+       "sdcard_d0_z", "sdcard_d1_z", "sdcard_d2_z", "sdcard_d3_z",
+       "sdcard_clk_z", "sdcard_cmd_z",
+};
+
+static const char * const spi0_groups[] = {
+       "spi0_mosi_c", "spi0_miso_c", "spi0_ss0_c", "spi0_clk_c",
+       "spi0_mosi_x", "spi0_miso_x", "spi0_ss0_x", "spi0_clk_x",
+};
+
+static const char * const spi1_groups[] = {
+       "spi1_mosi", "spi1_miso", "spi1_ss0", "spi1_clk",
+};
+
+static const char * const i2c0_groups[] = {
+       "i2c0_sda_c", "i2c0_sck_c",
+       "i2c0_sda_z0", "i2c0_sck_z1",
+       "i2c0_sda_z7", "i2c0_sck_z8",
+};
+
+static const char * const i2c1_groups[] = {
+       "i2c1_sda_x", "i2c1_sck_x",
+       "i2c1_sda_h2", "i2c1_sck_h3",
+       "i2c1_sda_h6", "i2c1_sck_h7",
+};
+
+static const char * const i2c2_groups[] = {
+       "i2c2_sda_x", "i2c2_sck_x",
+       "i2c2_sda_z", "i2c2_sck_z",
+};
+
+static const char * const i2c3_groups[] = {
+       "i2c3_sda_h", "i2c3_sck_h",
+       "i2c3_sda_a", "i2c3_sck_a",
+};
+
+static const char * const uart_a_groups[] = {
+       "uart_a_tx", "uart_a_rx", "uart_a_cts", "uart_a_rts",
+};
+
+static const char * const uart_b_groups[] = {
+       "uart_b_tx", "uart_b_rx",
+};
+
+static const char * const uart_c_groups[] = {
+       "uart_c_tx", "uart_c_rx", "uart_c_cts", "uart_c_rts",
+};
+
+static const char * const uart_ao_a_c_groups[] = {
+       "uart_ao_a_rx_c", "uart_ao_a_tx_c",
+};
+
+static const char * const iso7816_groups[] = {
+       "iso7816_clk_c", "iso7816_data_c",
+       "iso7816_clk_x", "iso7816_data_x",
+       "iso7816_clk_h", "iso7816_data_h",
+       "iso7816_clk_z", "iso7816_data_z",
+};
+
+static const char * const eth_groups[] = {
+       "eth_rxd2_rgmii", "eth_rxd3_rgmii", "eth_rgmii_tx_clk",
+       "eth_txd2_rgmii", "eth_txd3_rgmii", "eth_rgmii_rx_clk",
+       "eth_txd0", "eth_txd1", "eth_txen", "eth_mdc",
+       "eth_rxd0", "eth_rxd1", "eth_rx_dv", "eth_mdio",
+       "eth_link_led", "eth_act_led",
+};
+
+static const char * const pwm_a_groups[] = {
+       "pwm_a",
+};
+
+static const char * const pwm_b_groups[] = {
+       "pwm_b_x7", "pwm_b_x19",
+};
+
+static const char * const pwm_c_groups[] = {
+       "pwm_c_c", "pwm_c_x5", "pwm_c_x8",
+};
+
+static const char * const pwm_d_groups[] = {
+       "pwm_d_x3", "pwm_d_x6",
+};
+
+static const char * const pwm_e_groups[] = {
+       "pwm_e",
+};
+
+static const char * const pwm_f_groups[] = {
+       "pwm_f_x", "pwm_f_h",
+};
+
+static const char * const cec_ao_a_h_groups[] = {
+       "cec_ao_a_h",
+};
+
+static const char * const cec_ao_b_h_groups[] = {
+       "cec_ao_b_h",
+};
+
+static const char * const jtag_b_groups[] = {
+       "jtag_b_tdi", "jtag_b_tdo", "jtag_b_clk", "jtag_b_tms",
+};
+
+static const char * const bt565_a_groups[] = {
+       "bt565_a_vs", "bt565_a_hs", "bt565_a_clk",
+       "bt565_a_din0", "bt565_a_din1", "bt565_a_din2",
+       "bt565_a_din3", "bt565_a_din4", "bt565_a_din5",
+       "bt565_a_din6", "bt565_a_din7",
+};
+
+static const char * const tsin_a_groups[] = {
+       "tsin_a_valid", "tsin_a_sop", "tsin_a_din0",
+       "tsin_a_clk",
+};
+
+static const char * const tsin_b_groups[] = {
+       "tsin_b_valid_x", "tsin_b_sop_x", "tsin_b_din0_x", "tsin_b_clk_x",
+       "tsin_b_valid_z", "tsin_b_sop_z", "tsin_b_din0_z", "tsin_b_clk_z",
+       "tsin_b_fail", "tsin_b_din1", "tsin_b_din2", "tsin_b_din3",
+       "tsin_b_din4", "tsin_b_din5", "tsin_b_din6", "tsin_b_din7",
+};
+
+static const char * const hdmitx_groups[] = {
+       "hdmitx_sda", "hdmitx_sck", "hdmitx_hpd_in",
+};
+
+static const char * const pdm_groups[] = {
+       "pdm_din0_c", "pdm_din1_c", "pdm_din2_c", "pdm_din3_c",
+       "pdm_dclk_c",
+       "pdm_din0_x", "pdm_din1_x", "pdm_din2_x", "pdm_din3_x",
+       "pdm_dclk_x",
+       "pdm_din0_z", "pdm_din1_z", "pdm_din2_z", "pdm_din3_z",
+       "pdm_dclk_z",
+       "pdm_din0_a", "pdm_din1_a", "pdm_din2_a", "pdm_din3_a",
+       "pdm_dclk_a",
+};
+
+static const char * const spdif_in_groups[] = {
+       "spdif_in_h", "spdif_in_a10", "spdif_in_a12",
+};
+
+static const char * const spdif_out_groups[] = {
+       "spdif_out_h", "spdif_out_a11", "spdif_out_a13",
+};
+
+static const char * const mclk0_groups[] = {
+       "mclk0_a",
+};
+
+static const char * const mclk1_groups[] = {
+       "mclk1_x", "mclk1_z", "mclk1_a",
+};
+
+static const char * const tdm_a_groups[] = {
+       "tdm_a_slv_sclk", "tdm_a_slv_fs", "tdm_a_sclk", "tdm_a_fs",
+       "tdm_a_din0", "tdm_a_din1", "tdm_a_dout0", "tdm_a_dout1",
+};
+
+static const char * const tdm_b_groups[] = {
+       "tdm_b_slv_sclk", "tdm_b_slv_fs", "tdm_b_sclk", "tdm_b_fs",
+       "tdm_b_din0", "tdm_b_din1", "tdm_b_din2",
+       "tdm_b_din3_a", "tdm_b_din3_h",
+       "tdm_b_dout0", "tdm_b_dout1", "tdm_b_dout2",
+       "tdm_b_dout3_a", "tdm_b_dout3_h",
+};
+
+static const char * const tdm_c_groups[] = {
+       "tdm_c_slv_sclk_a", "tdm_c_slv_fs_a",
+       "tdm_c_slv_sclk_z", "tdm_c_slv_fs_z",
+       "tdm_c_sclk_a", "tdm_c_fs_a",
+       "tdm_c_sclk_z", "tdm_c_fs_z",
+       "tdm_c_din0_a", "tdm_c_din1_a",
+       "tdm_c_din2_a", "tdm_c_din3_a",
+       "tdm_c_din0_z", "tdm_c_din1_z",
+       "tdm_c_din2_z", "tdm_c_din3_z",
+       "tdm_c_dout0_a", "tdm_c_dout1_a",
+       "tdm_c_dout2_a", "tdm_c_dout3_a",
+       "tdm_c_dout0_z", "tdm_c_dout1_z",
+       "tdm_c_dout2_z", "tdm_c_dout3_z",
+};
+
+static const char * const gpio_aobus_groups[] = {
+       "GPIOAO_0", "GPIOAO_1", "GPIOAO_2", "GPIOAO_3", "GPIOAO_4",
+       "GPIOAO_5", "GPIOAO_6", "GPIOAO_7", "GPIOAO_8", "GPIOAO_9",
+       "GPIOAO_10", "GPIOAO_11", "GPIOE_0", "GPIOE_1", "GPIOE_2",
+};
+
+static const char * const uart_ao_a_groups[] = {
+       "uart_ao_a_tx", "uart_ao_a_rx",
+       "uart_ao_a_cts", "uart_ao_a_rts",
+};
+
+static const char * const uart_ao_b_groups[] = {
+       "uart_ao_b_tx_2", "uart_ao_b_rx_3",
+       "uart_ao_b_tx_8", "uart_ao_b_rx_9",
+       "uart_ao_b_cts", "uart_ao_b_rts",
+};
+
+static const char * const i2c_ao_groups[] = {
+       "i2c_ao_sck", "i2c_ao_sda",
+       "i2c_ao_sck_e", "i2c_ao_sda_e",
+};
+
+static const char * const i2c_ao_slave_groups[] = {
+       "i2c_ao_slave_sck", "i2c_ao_slave_sda",
+};
+
+static const char * const remote_ao_input_groups[] = {
+       "remote_ao_input",
+};
+
+static const char * const remote_ao_out_groups[] = {
+       "remote_ao_out",
+};
+
+static const char * const pwm_ao_a_groups[] = {
+       "pwm_ao_a", "pwm_ao_a_hiz",
+};
+
+static const char * const pwm_ao_b_groups[] = {
+       "pwm_ao_b",
+};
+
+static const char * const pwm_ao_c_groups[] = {
+       "pwm_ao_c_4", "pwm_ao_c_hiz",
+       "pwm_ao_c_6",
+};
+
+static const char * const pwm_ao_d_groups[] = {
+       "pwm_ao_d_5", "pwm_ao_d_10", "pwm_ao_d_e",
+};
+
+static const char * const jtag_a_groups[] = {
+       "jtag_a_tdi", "jtag_a_tdo", "jtag_a_clk", "jtag_a_tms",
+};
+
+static const char * const cec_ao_a_groups[] = {
+       "cec_ao_a",
+};
+
+static const char * const cec_ao_b_groups[] = {
+       "cec_ao_b",
+};
+
+static const char * const tsin_ao_a_groups[] = {
+       "tsin_ao_asop", "tsin_ao_adin0", "tsin_ao_aclk", "tsin_ao_a_valid",
+};
+
+static const char * const spdif_ao_out_groups[] = {
+       "spdif_ao_out",
+};
+
+static const char * const tdm_ao_b_groups[] = {
+       "tdm_ao_b_dout0", "tdm_ao_b_dout1", "tdm_ao_b_dout2",
+       "tdm_ao_b_fs", "tdm_ao_b_sclk",
+       "tdm_ao_b_din0", "tdm_ao_b_din1", "tdm_ao_b_din2",
+       "tdm_ao_b_slv_fs", "tdm_ao_b_slv_sclk",
+};
+
+static const char * const mclk0_ao_groups[] = {
+       "mclk0_ao",
+};
+
+static struct meson_pmx_func meson_g12a_periphs_functions[] = {
+       FUNCTION(gpio_periphs),
+       FUNCTION(emmc),
+       FUNCTION(nor),
+       FUNCTION(spi0),
+       FUNCTION(spi1),
+       FUNCTION(sdio),
+       FUNCTION(nand),
+       FUNCTION(sdcard),
+       FUNCTION(i2c0),
+       FUNCTION(i2c1),
+       FUNCTION(i2c2),
+       FUNCTION(i2c3),
+       FUNCTION(uart_a),
+       FUNCTION(uart_b),
+       FUNCTION(uart_c),
+       FUNCTION(uart_ao_a_c),
+       FUNCTION(iso7816),
+       FUNCTION(eth),
+       FUNCTION(pwm_a),
+       FUNCTION(pwm_b),
+       FUNCTION(pwm_c),
+       FUNCTION(pwm_d),
+       FUNCTION(pwm_e),
+       FUNCTION(pwm_f),
+       FUNCTION(cec_ao_a_h),
+       FUNCTION(cec_ao_b_h),
+       FUNCTION(jtag_b),
+       FUNCTION(bt565_a),
+       FUNCTION(tsin_a),
+       FUNCTION(tsin_b),
+       FUNCTION(hdmitx),
+       FUNCTION(pdm),
+       FUNCTION(spdif_out),
+       FUNCTION(spdif_in),
+       FUNCTION(mclk0),
+       FUNCTION(mclk1),
+       FUNCTION(tdm_a),
+       FUNCTION(tdm_b),
+       FUNCTION(tdm_c),
+};
+
+static struct meson_pmx_func meson_g12a_aobus_functions[] = {
+       FUNCTION(gpio_aobus),
+       FUNCTION(uart_ao_a),
+       FUNCTION(uart_ao_b),
+       FUNCTION(i2c_ao),
+       FUNCTION(i2c_ao_slave),
+       FUNCTION(remote_ao_input),
+       FUNCTION(remote_ao_out),
+       FUNCTION(pwm_ao_a),
+       FUNCTION(pwm_ao_b),
+       FUNCTION(pwm_ao_c),
+       FUNCTION(pwm_ao_d),
+       FUNCTION(jtag_a),
+       FUNCTION(cec_ao_a),
+       FUNCTION(cec_ao_b),
+       FUNCTION(tsin_ao_a),
+       FUNCTION(spdif_ao_out),
+       FUNCTION(tdm_ao_b),
+       FUNCTION(mclk0_ao),
+};
+
+static struct meson_bank meson_g12a_periphs_banks[] = {
+       /* name  first  last  irq  pullen  pull  dir  out  in */
+       BANK("Z",    GPIOZ_0,    GPIOZ_15, 12, 27,
+            4,  0,  4,  0,  12,  0,  13, 0,  14, 0),
+       BANK("H",    GPIOH_0,    GPIOH_8, 28, 36,
+            3,  0,  3,  0,  9,  0,  10,  0,  11,  0),
+       BANK("BOOT", BOOT_0,     BOOT_15,  37, 52,
+            0,  0,  0,  0,  0, 0,  1, 0,  2, 0),
+       BANK("C",    GPIOC_0,    GPIOC_7,  53, 60,
+            1,  0,  1,  0,  3, 0,  4, 0,  5, 0),
+       BANK("A",    GPIOA_0,    GPIOA_15,  61, 76,
+            5,  0,  5,  0,  16,  0,  17,  0,  18,  0),
+       BANK("X",    GPIOX_0,    GPIOX_19,   77, 96,
+            2,  0,  2,  0,  6,  0,  7,  0,  8,  0),
+};
+
+static struct meson_bank meson_g12a_aobus_banks[] = {
+       /* name  first  last  irq  pullen  pull  dir  out  in  */
+       BANK("AO",   GPIOAO_0,  GPIOAO_11,  0, 11,
+            3,  0,  2, 0,  0,  0,  4, 0,  1,  0),
+       /* GPIOE actually located in the AO bank */
+       BANK("E",   GPIOE_0,  GPIOE_2,   97, 99,
+            3,  16,  2, 16,  0,  16,  4, 16,  1,  16),
+};
+
+static struct meson_pmx_bank meson_g12a_periphs_pmx_banks[] = {
+       /*       name    first          lask       reg  offset  */
+       BANK_PMX("Z",    GPIOZ_0, GPIOZ_15, 0x6, 0),
+       BANK_PMX("H",    GPIOH_0, GPIOH_8,  0xb, 0),
+       BANK_PMX("BOOT", BOOT_0,  BOOT_15,  0x0, 0),
+       BANK_PMX("C",    GPIOC_0, GPIOC_7,  0x9, 0),
+       BANK_PMX("A",    GPIOA_0, GPIOA_15, 0xd, 0),
+       BANK_PMX("X",    GPIOX_0, GPIOX_19, 0x3, 0),
+};
+
+static struct meson_axg_pmx_data meson_g12a_periphs_pmx_banks_data = {
+       .pmx_banks      = meson_g12a_periphs_pmx_banks,
+       .num_pmx_banks  = ARRAY_SIZE(meson_g12a_periphs_pmx_banks),
+};
+
+static struct meson_pmx_bank meson_g12a_aobus_pmx_banks[] = {
+       BANK_PMX("AO",  GPIOAO_0, GPIOAO_11, 0x0, 0),
+       BANK_PMX("E",   GPIOE_0,  GPIOE_2,   0x1, 16),
+};
+
+static struct meson_axg_pmx_data meson_g12a_aobus_pmx_banks_data = {
+       .pmx_banks      = meson_g12a_aobus_pmx_banks,
+       .num_pmx_banks  = ARRAY_SIZE(meson_g12a_aobus_pmx_banks),
+};
+
+static struct meson_pinctrl_data meson_g12a_periphs_pinctrl_data = {
+       .name           = "periphs-banks",
+       .pins           = meson_g12a_periphs_pins,
+       .groups         = meson_g12a_periphs_groups,
+       .funcs          = meson_g12a_periphs_functions,
+       .banks          = meson_g12a_periphs_banks,
+       .num_pins       = ARRAY_SIZE(meson_g12a_periphs_pins),
+       .num_groups     = ARRAY_SIZE(meson_g12a_periphs_groups),
+       .num_funcs      = ARRAY_SIZE(meson_g12a_periphs_functions),
+       .num_banks      = ARRAY_SIZE(meson_g12a_periphs_banks),
+       .pmx_ops        = &meson_axg_pmx_ops,
+       .pmx_data       = &meson_g12a_periphs_pmx_banks_data,
+};
+
+static struct meson_pinctrl_data meson_g12a_aobus_pinctrl_data = {
+       .name           = "aobus-banks",
+       .pins           = meson_g12a_aobus_pins,
+       .groups         = meson_g12a_aobus_groups,
+       .funcs          = meson_g12a_aobus_functions,
+       .banks          = meson_g12a_aobus_banks,
+       .num_pins       = ARRAY_SIZE(meson_g12a_aobus_pins),
+       .num_groups     = ARRAY_SIZE(meson_g12a_aobus_groups),
+       .num_funcs      = ARRAY_SIZE(meson_g12a_aobus_functions),
+       .num_banks      = ARRAY_SIZE(meson_g12a_aobus_banks),
+       .pmx_ops        = &meson_axg_pmx_ops,
+       .pmx_data       = &meson_g12a_aobus_pmx_banks_data,
+};
+
+static const struct of_device_id meson_g12a_pinctrl_dt_match[] = {
+       {
+               .compatible = "amlogic,meson-g12a-periphs-pinctrl",
+               .data = &meson_g12a_periphs_pinctrl_data,
+       },
+       {
+               .compatible = "amlogic,meson-g12a-aobus-pinctrl",
+               .data = &meson_g12a_aobus_pinctrl_data,
+       },
+       { },
+};
+
+static struct platform_driver meson_g12a_pinctrl_driver = {
+       .probe  = meson_pinctrl_probe,
+       .driver = {
+               .name   = "meson-g12a-pinctrl",
+               .of_match_table = meson_g12a_pinctrl_dt_match,
+       },
+};
+
+builtin_platform_driver(meson_g12a_pinctrl_driver);
index 29a458d..9cb81ae 100644 (file)
@@ -451,7 +451,7 @@ static struct regmap *meson_map_resource(struct meson_pinctrl *pc,
 
        meson_regmap_config.max_register = resource_size(&res) - 4;
        meson_regmap_config.name = devm_kasprintf(pc->dev, GFP_KERNEL,
-                                                 "%s-%s", node->name,
+                                                 "%pOFn-%s", node,
                                                  name);
        if (!meson_regmap_config.name)
                return ERR_PTR(-ENOMEM);
index d7ec711..7ee5f79 100644 (file)
@@ -413,14 +413,14 @@ static int mvebu_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
        ret = of_property_read_string(np, "marvell,function", &function);
        if (ret) {
                dev_err(pctl->dev,
-                       "missing marvell,function in node %s\n", np->name);
+                       "missing marvell,function in node %pOFn\n", np);
                return 0;
        }
 
        nmaps = of_property_count_strings(np, "marvell,pins");
        if (nmaps < 0) {
                dev_err(pctl->dev,
-                       "missing marvell,pins in node %s\n", np->name);
+                       "missing marvell,pins in node %pOFn\n", np);
                return 0;
        }
 
index f0e7a8c..866db27 100644 (file)
@@ -1051,7 +1051,7 @@ static struct nmk_gpio_chip *nmk_gpio_populate_chip(struct device_node *np,
 
        gpio_pdev = of_find_device_by_node(np);
        if (!gpio_pdev) {
-               pr_err("populate \"%s\": device not found\n", np->name);
+               pr_err("populate \"%pOFn\": device not found\n", np);
                return ERR_PTR(-ENODEV);
        }
        if (of_property_read_u32(np, "gpio-bank", &id)) {
@@ -1904,8 +1904,8 @@ static int nmk_pinctrl_probe(struct platform_device *pdev)
                gpio_np = of_parse_phandle(np, "nomadik-gpio-chips", i);
                if (gpio_np) {
                        dev_info(&pdev->dev,
-                                "populate NMK GPIO %d \"%s\"\n",
-                                i, gpio_np->name);
+                                "populate NMK GPIO %d \"%pOFn\"\n",
+                                i, gpio_np);
                        nmk_chip = nmk_gpio_populate_chip(gpio_np, pdev);
                        if (IS_ERR(nmk_chip))
                                dev_err(&pdev->dev,
diff --git a/drivers/pinctrl/nuvoton/Kconfig b/drivers/pinctrl/nuvoton/Kconfig
new file mode 100644 (file)
index 0000000..6056841
--- /dev/null
@@ -0,0 +1,12 @@
+config PINCTRL_NPCM7XX
+       bool "Pinctrl and GPIO driver for Nuvoton NPCM7XX"
+       depends on (ARCH_NPCM7XX || COMPILE_TEST) && OF
+       select PINMUX
+       select PINCONF
+       select GENERIC_PINCONF
+       select GPIOLIB
+       select GPIO_GENERIC
+       select GPIOLIB_IRQCHIP
+       help
+         Say Y here to enable pin controller and GPIO support
+         for Nuvoton NPCM750/730/715/705 SoCs.
diff --git a/drivers/pinctrl/nuvoton/Makefile b/drivers/pinctrl/nuvoton/Makefile
new file mode 100644 (file)
index 0000000..886d007
--- /dev/null
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
+# Nuvoton pinctrl support
+
+obj-$(CONFIG_PINCTRL_NPCM7XX)  += pinctrl-npcm7xx.o
diff --git a/drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c b/drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c
new file mode 100644 (file)
index 0000000..7ad50d9
--- /dev/null
@@ -0,0 +1,2072 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2016-2018 Nuvoton Technology corporation.
+// Copyright (c) 2016, Dell Inc
+
+#include <linux/device.h>
+#include <linux/gpio/driver.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/pinctrl/machine.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinconf-generic.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+/* GCR registers */
+#define NPCM7XX_GCR_PDID       0x00
+#define NPCM7XX_GCR_MFSEL1     0x0C
+#define NPCM7XX_GCR_MFSEL2     0x10
+#define NPCM7XX_GCR_MFSEL3     0x64
+#define NPCM7XX_GCR_MFSEL4     0xb0
+#define NPCM7XX_GCR_CPCTL      0xD0
+#define NPCM7XX_GCR_CP2BST     0xD4
+#define NPCM7XX_GCR_B2CPNT     0xD8
+#define NPCM7XX_GCR_I2CSEGSEL  0xE0
+#define NPCM7XX_GCR_I2CSEGCTL  0xE4
+#define NPCM7XX_GCR_SRCNT      0x68
+#define NPCM7XX_GCR_FLOCKR1    0x74
+#define NPCM7XX_GCR_DSCNT      0x78
+
+#define SRCNT_ESPI             BIT(3)
+
+/* GPIO registers */
+#define NPCM7XX_GP_N_TLOCK1    0x00
+#define NPCM7XX_GP_N_DIN       0x04 /* Data IN */
+#define NPCM7XX_GP_N_POL       0x08 /* Polarity */
+#define NPCM7XX_GP_N_DOUT      0x0c /* Data OUT */
+#define NPCM7XX_GP_N_OE                0x10 /* Output Enable */
+#define NPCM7XX_GP_N_OTYP      0x14
+#define NPCM7XX_GP_N_MP                0x18
+#define NPCM7XX_GP_N_PU                0x1c /* Pull-up */
+#define NPCM7XX_GP_N_PD                0x20 /* Pull-down */
+#define NPCM7XX_GP_N_DBNC      0x24 /* Debounce */
+#define NPCM7XX_GP_N_EVTYP     0x28 /* Event Type */
+#define NPCM7XX_GP_N_EVBE      0x2c /* Event Both Edge */
+#define NPCM7XX_GP_N_OBL0      0x30
+#define NPCM7XX_GP_N_OBL1      0x34
+#define NPCM7XX_GP_N_OBL2      0x38
+#define NPCM7XX_GP_N_OBL3      0x3c
+#define NPCM7XX_GP_N_EVEN      0x40 /* Event Enable */
+#define NPCM7XX_GP_N_EVENS     0x44 /* Event Set (enable) */
+#define NPCM7XX_GP_N_EVENC     0x48 /* Event Clear (disable) */
+#define NPCM7XX_GP_N_EVST      0x4c /* Event Status */
+#define NPCM7XX_GP_N_SPLCK     0x50
+#define NPCM7XX_GP_N_MPLCK     0x54
+#define NPCM7XX_GP_N_IEM       0x58 /* Input Enable */
+#define NPCM7XX_GP_N_OSRC      0x5c
+#define NPCM7XX_GP_N_ODSC      0x60
+#define NPCM7XX_GP_N_DOS       0x68 /* Data OUT Set */
+#define NPCM7XX_GP_N_DOC       0x6c /* Data OUT Clear */
+#define NPCM7XX_GP_N_OES       0x70 /* Output Enable Set */
+#define NPCM7XX_GP_N_OEC       0x74 /* Output Enable Clear */
+#define NPCM7XX_GP_N_TLOCK2    0x7c
+
+#define NPCM7XX_GPIO_PER_BANK  32
+#define NPCM7XX_GPIO_BANK_NUM  8
+#define NPCM7XX_GCR_NONE       0
+
+/* Structure for register banks */
+struct npcm7xx_gpio {
+       void __iomem            *base;
+       struct gpio_chip        gc;
+       int                     irqbase;
+       int                     irq;
+       void                    *priv;
+       struct irq_chip         irq_chip;
+       u32                     pinctrl_id;
+       int (*direction_input)(struct gpio_chip *chip, unsigned offset);
+       int (*direction_output)(struct gpio_chip *chip, unsigned offset,
+                               int value);
+       int (*request)(struct gpio_chip *chip, unsigned offset);
+       void (*free)(struct gpio_chip *chip, unsigned offset);
+};
+
+struct npcm7xx_pinctrl {
+       struct pinctrl_dev      *pctldev;
+       struct device           *dev;
+       struct npcm7xx_gpio     gpio_bank[NPCM7XX_GPIO_BANK_NUM];
+       struct irq_domain       *domain;
+       struct regmap           *gcr_regmap;
+       void __iomem            *regs;
+       u32                     bank_num;
+};
+
+/* GPIO handling in the pinctrl driver */
+static void npcm_gpio_set(struct gpio_chip *gc, void __iomem *reg,
+                         unsigned int pinmask)
+{
+       unsigned long flags;
+       unsigned long val;
+
+       spin_lock_irqsave(&gc->bgpio_lock, flags);
+
+       val = ioread32(reg) | pinmask;
+       iowrite32(val, reg);
+
+       spin_unlock_irqrestore(&gc->bgpio_lock, flags);
+}
+
+static void npcm_gpio_clr(struct gpio_chip *gc, void __iomem *reg,
+                         unsigned int pinmask)
+{
+       unsigned long flags;
+       unsigned long val;
+
+       spin_lock_irqsave(&gc->bgpio_lock, flags);
+
+       val = ioread32(reg) & ~pinmask;
+       iowrite32(val, reg);
+
+       spin_unlock_irqrestore(&gc->bgpio_lock, flags);
+}
+
+static void npcmgpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
+{
+       struct npcm7xx_gpio *bank = gpiochip_get_data(chip);
+
+       seq_printf(s, "-- module %d [gpio%d - %d]\n",
+                  bank->gc.base / bank->gc.ngpio,
+                  bank->gc.base,
+                  bank->gc.base + bank->gc.ngpio);
+       seq_printf(s, "DIN :%.8x DOUT:%.8x IE  :%.8x OE  :%.8x\n",
+                  ioread32(bank->base + NPCM7XX_GP_N_DIN),
+                  ioread32(bank->base + NPCM7XX_GP_N_DOUT),
+                  ioread32(bank->base + NPCM7XX_GP_N_IEM),
+                  ioread32(bank->base + NPCM7XX_GP_N_OE));
+       seq_printf(s, "PU  :%.8x PD  :%.8x DB  :%.8x POL :%.8x\n",
+                  ioread32(bank->base + NPCM7XX_GP_N_PU),
+                  ioread32(bank->base + NPCM7XX_GP_N_PD),
+                  ioread32(bank->base + NPCM7XX_GP_N_DBNC),
+                  ioread32(bank->base + NPCM7XX_GP_N_POL));
+       seq_printf(s, "ETYP:%.8x EVBE:%.8x EVEN:%.8x EVST:%.8x\n",
+                  ioread32(bank->base + NPCM7XX_GP_N_EVTYP),
+                  ioread32(bank->base + NPCM7XX_GP_N_EVBE),
+                  ioread32(bank->base + NPCM7XX_GP_N_EVEN),
+                  ioread32(bank->base + NPCM7XX_GP_N_EVST));
+       seq_printf(s, "OTYP:%.8x OSRC:%.8x ODSC:%.8x\n",
+                  ioread32(bank->base + NPCM7XX_GP_N_OTYP),
+                  ioread32(bank->base + NPCM7XX_GP_N_OSRC),
+                  ioread32(bank->base + NPCM7XX_GP_N_ODSC));
+       seq_printf(s, "OBL0:%.8x OBL1:%.8x OBL2:%.8x OBL3:%.8x\n",
+                  ioread32(bank->base + NPCM7XX_GP_N_OBL0),
+                  ioread32(bank->base + NPCM7XX_GP_N_OBL1),
+                  ioread32(bank->base + NPCM7XX_GP_N_OBL2),
+                  ioread32(bank->base + NPCM7XX_GP_N_OBL3));
+       seq_printf(s, "SLCK:%.8x MLCK:%.8x\n",
+                  ioread32(bank->base + NPCM7XX_GP_N_SPLCK),
+                  ioread32(bank->base + NPCM7XX_GP_N_MPLCK));
+}
+
+static int npcmgpio_direction_input(struct gpio_chip *chip, unsigned int offset)
+{
+       struct npcm7xx_gpio *bank = gpiochip_get_data(chip);
+       int ret;
+
+       ret = pinctrl_gpio_direction_input(offset + chip->base);
+       if (ret)
+               return ret;
+
+       return bank->direction_input(chip, offset);
+}
+
+/* Set GPIO to Output with initial value */
+static int npcmgpio_direction_output(struct gpio_chip *chip,
+                                    unsigned int offset, int value)
+{
+       struct npcm7xx_gpio *bank = gpiochip_get_data(chip);
+       int ret;
+
+       dev_dbg(chip->parent, "gpio_direction_output: offset%d = %x\n", offset,
+               value);
+
+       ret = pinctrl_gpio_direction_output(offset + chip->base);
+       if (ret)
+               return ret;
+
+       return bank->direction_output(chip, offset, value);
+}
+
+static int npcmgpio_gpio_request(struct gpio_chip *chip, unsigned int offset)
+{
+       struct npcm7xx_gpio *bank = gpiochip_get_data(chip);
+       int ret;
+
+       dev_dbg(chip->parent, "gpio_request: offset%d\n", offset);
+       ret = pinctrl_gpio_request(offset + chip->base);
+       if (ret)
+               return ret;
+
+       return bank->request(chip, offset);
+}
+
+static void npcmgpio_gpio_free(struct gpio_chip *chip, unsigned int offset)
+{
+       dev_dbg(chip->parent, "gpio_free: offset%d\n", offset);
+       pinctrl_gpio_free(offset + chip->base);
+}
+
+static void npcmgpio_irq_handler(struct irq_desc *desc)
+{
+       struct gpio_chip *gc;
+       struct irq_chip *chip;
+       struct npcm7xx_gpio *bank;
+       u32 sts, en, bit;
+
+       gc = irq_desc_get_handler_data(desc);
+       bank = gpiochip_get_data(gc);
+       chip = irq_desc_get_chip(desc);
+
+       chained_irq_enter(chip, desc);
+       sts = ioread32(bank->base + NPCM7XX_GP_N_EVST);
+       en  = ioread32(bank->base + NPCM7XX_GP_N_EVEN);
+       dev_dbg(chip->parent_device, "==> got irq sts %.8x %.8x\n", sts,
+               en);
+
+       sts &= en;
+       for_each_set_bit(bit, (const void *)&sts, NPCM7XX_GPIO_PER_BANK)
+               generic_handle_irq(irq_linear_revmap(gc->irq.domain, bit));
+       chained_irq_exit(chip, desc);
+}
+
+static int npcmgpio_set_irq_type(struct irq_data *d, unsigned int type)
+{
+       struct npcm7xx_gpio *bank =
+               gpiochip_get_data(irq_data_get_irq_chip_data(d));
+       unsigned int gpio = BIT(d->hwirq);
+
+       dev_dbg(d->chip->parent_device, "setirqtype: %u.%u = %u\n", gpio,
+               d->irq, type);
+       switch (type) {
+       case IRQ_TYPE_EDGE_RISING:
+               dev_dbg(d->chip->parent_device, "edge.rising\n");
+               npcm_gpio_clr(&bank->gc, bank->base + NPCM7XX_GP_N_EVBE, gpio);
+               npcm_gpio_clr(&bank->gc, bank->base + NPCM7XX_GP_N_POL, gpio);
+               break;
+       case IRQ_TYPE_EDGE_FALLING:
+               dev_dbg(d->chip->parent_device, "edge.falling\n");
+               npcm_gpio_clr(&bank->gc, bank->base + NPCM7XX_GP_N_EVBE, gpio);
+               npcm_gpio_set(&bank->gc, bank->base + NPCM7XX_GP_N_POL, gpio);
+               break;
+       case IRQ_TYPE_EDGE_BOTH:
+               dev_dbg(d->chip->parent_device, "edge.both\n");
+               npcm_gpio_set(&bank->gc, bank->base + NPCM7XX_GP_N_EVBE, gpio);
+               break;
+       case IRQ_TYPE_LEVEL_LOW:
+               dev_dbg(d->chip->parent_device, "level.low\n");
+               npcm_gpio_set(&bank->gc, bank->base + NPCM7XX_GP_N_POL, gpio);
+               break;
+       case IRQ_TYPE_LEVEL_HIGH:
+               dev_dbg(d->chip->parent_device, "level.high\n");
+               npcm_gpio_clr(&bank->gc, bank->base + NPCM7XX_GP_N_POL, gpio);
+               break;
+       default:
+               dev_dbg(d->chip->parent_device, "invalid irq type\n");
+               return -EINVAL;
+       }
+
+       if (type & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) {
+               npcm_gpio_clr(&bank->gc, bank->base + NPCM7XX_GP_N_EVTYP, gpio);
+               irq_set_handler_locked(d, handle_level_irq);
+       } else if (type & (IRQ_TYPE_EDGE_BOTH | IRQ_TYPE_EDGE_RISING
+                          | IRQ_TYPE_EDGE_FALLING)) {
+               npcm_gpio_set(&bank->gc, bank->base + NPCM7XX_GP_N_EVTYP, gpio);
+               irq_set_handler_locked(d, handle_edge_irq);
+       }
+
+       return 0;
+}
+
+static void npcmgpio_irq_ack(struct irq_data *d)
+{
+       struct npcm7xx_gpio *bank =
+               gpiochip_get_data(irq_data_get_irq_chip_data(d));
+       unsigned int gpio = d->hwirq;
+
+       dev_dbg(d->chip->parent_device, "irq_ack: %u.%u\n", gpio, d->irq);
+       iowrite32(BIT(gpio), bank->base + NPCM7XX_GP_N_EVST);
+}
+
+/* Disable GPIO interrupt */
+static void npcmgpio_irq_mask(struct irq_data *d)
+{
+       struct npcm7xx_gpio *bank =
+               gpiochip_get_data(irq_data_get_irq_chip_data(d));
+       unsigned int gpio = d->hwirq;
+
+       /* Clear events */
+       dev_dbg(d->chip->parent_device, "irq_mask: %u.%u\n", gpio, d->irq);
+       iowrite32(BIT(gpio), bank->base + NPCM7XX_GP_N_EVENC);
+}
+
+/* Enable GPIO interrupt */
+static void npcmgpio_irq_unmask(struct irq_data *d)
+{
+       struct npcm7xx_gpio *bank =
+               gpiochip_get_data(irq_data_get_irq_chip_data(d));
+       unsigned int gpio = d->hwirq;
+
+       /* Enable events */
+       dev_dbg(d->chip->parent_device, "irq_unmask: %u.%u\n", gpio, d->irq);
+       iowrite32(BIT(gpio), bank->base + NPCM7XX_GP_N_EVENS);
+}
+
+static unsigned int npcmgpio_irq_startup(struct irq_data *d)
+{
+       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+       unsigned int gpio = d->hwirq;
+
+       /* active-high, input, clear interrupt, enable interrupt */
+       dev_dbg(d->chip->parent_device, "startup: %u.%u\n", gpio, d->irq);
+       npcmgpio_direction_input(gc, gpio);
+       npcmgpio_irq_ack(d);
+       npcmgpio_irq_unmask(d);
+
+       return 0;
+}
+
+static struct irq_chip npcmgpio_irqchip = {
+       .name = "NPCM7XX-GPIO-IRQ",
+       .irq_ack = npcmgpio_irq_ack,
+       .irq_unmask = npcmgpio_irq_unmask,
+       .irq_mask = npcmgpio_irq_mask,
+       .irq_set_type = npcmgpio_set_irq_type,
+       .irq_startup = npcmgpio_irq_startup,
+};
+
+/* pinmux handing in the pinctrl driver*/
+static const int smb0_pins[]  = { 115, 114 };
+static const int smb0b_pins[] = { 195, 194 };
+static const int smb0c_pins[] = { 202, 196 };
+static const int smb0d_pins[] = { 198, 199 };
+static const int smb0den_pins[] = { 197 };
+
+static const int smb1_pins[]  = { 117, 116 };
+static const int smb1b_pins[] = { 126, 127 };
+static const int smb1c_pins[] = { 124, 125 };
+static const int smb1d_pins[] = { 4, 5 };
+
+static const int smb2_pins[]  = { 119, 118 };
+static const int smb2b_pins[] = { 122, 123 };
+static const int smb2c_pins[] = { 120, 121 };
+static const int smb2d_pins[] = { 6, 7 };
+
+static const int smb3_pins[]  = { 30, 31 };
+static const int smb3b_pins[] = { 39, 40 };
+static const int smb3c_pins[] = { 37, 38 };
+static const int smb3d_pins[] = { 59, 60 };
+
+static const int smb4_pins[]  = { 28, 29 };
+static const int smb4b_pins[] = { 18, 19 };
+static const int smb4c_pins[] = { 20, 21 };
+static const int smb4d_pins[] = { 22, 23 };
+static const int smb4den_pins[] = { 17 };
+
+static const int smb5_pins[]  = { 26, 27 };
+static const int smb5b_pins[] = { 13, 12 };
+static const int smb5c_pins[] = { 15, 14 };
+static const int smb5d_pins[] = { 94, 93 };
+static const int ga20kbc_pins[] = { 94, 93 };
+
+static const int smb6_pins[]  = { 172, 171 };
+static const int smb7_pins[]  = { 174, 173 };
+static const int smb8_pins[]  = { 129, 128 };
+static const int smb9_pins[]  = { 131, 130 };
+static const int smb10_pins[] = { 133, 132 };
+static const int smb11_pins[] = { 135, 134 };
+static const int smb12_pins[] = { 221, 220 };
+static const int smb13_pins[] = { 223, 222 };
+static const int smb14_pins[] = { 22, 23 };
+static const int smb15_pins[] = { 20, 21 };
+
+static const int fanin0_pins[] = { 64 };
+static const int fanin1_pins[] = { 65 };
+static const int fanin2_pins[] = { 66 };
+static const int fanin3_pins[] = { 67 };
+static const int fanin4_pins[] = { 68 };
+static const int fanin5_pins[] = { 69 };
+static const int fanin6_pins[] = { 70 };
+static const int fanin7_pins[] = { 71 };
+static const int fanin8_pins[] = { 72 };
+static const int fanin9_pins[] = { 73 };
+static const int fanin10_pins[] = { 74 };
+static const int fanin11_pins[] = { 75 };
+static const int fanin12_pins[] = { 76 };
+static const int fanin13_pins[] = { 77 };
+static const int fanin14_pins[] = { 78 };
+static const int fanin15_pins[] = { 79 };
+static const int faninx_pins[] = { 175, 176, 177, 203 };
+
+static const int pwm0_pins[] = { 80 };
+static const int pwm1_pins[] = { 81 };
+static const int pwm2_pins[] = { 82 };
+static const int pwm3_pins[] = { 83 };
+static const int pwm4_pins[] = { 144 };
+static const int pwm5_pins[] = { 145 };
+static const int pwm6_pins[] = { 146 };
+static const int pwm7_pins[] = { 147 };
+
+static const int uart1_pins[] = { 43, 44, 45, 46, 47, 61, 62, 63 };
+static const int uart2_pins[] = { 48, 49, 50, 51, 52, 53, 54, 55 };
+
+/* RGMII 1 pin group */
+static const int rg1_pins[] = { 96, 97, 98, 99, 100, 101, 102, 103, 104, 105,
+       106, 107 };
+/* RGMII 1 MD interface pin group */
+static const int rg1mdio_pins[] = { 108, 109 };
+
+/* RGMII 2 pin group */
+static const int rg2_pins[] = { 110, 111, 112, 113, 208, 209, 210, 211, 212,
+       213, 214, 215 };
+/* RGMII 2 MD interface pin group */
+static const int rg2mdio_pins[] = { 216, 217 };
+
+static const int ddr_pins[] = { 110, 111, 112, 113, 208, 209, 210, 211, 212,
+       213, 214, 215, 216, 217 };
+/* Serial I/O Expander 1 */
+static const int iox1_pins[] = { 0, 1, 2, 3 };
+/* Serial I/O Expander 2 */
+static const int iox2_pins[] = { 4, 5, 6, 7 };
+/* Host Serial I/O Expander 2 */
+static const int ioxh_pins[] = { 10, 11, 24, 25 };
+
+static const int mmc_pins[] = { 152, 154, 156, 157, 158, 159 };
+static const int mmcwp_pins[] = { 153 };
+static const int mmccd_pins[] = { 155 };
+static const int mmcrst_pins[] = { 155 };
+static const int mmc8_pins[] = { 148, 149, 150, 151 };
+
+/* RMII 1 pin groups */
+static const int r1_pins[] = { 178, 179, 180, 181, 182, 193, 201 };
+static const int r1err_pins[] = { 56 };
+static const int r1md_pins[] = { 57, 58 };
+
+/* RMII 2 pin groups */
+static const int r2_pins[] = { 84, 85, 86, 87, 88, 89, 200 };
+static const int r2err_pins[] = { 90 };
+static const int r2md_pins[] = { 91, 92 };
+
+static const int sd1_pins[] = { 136, 137, 138, 139, 140, 141, 142, 143 };
+static const int sd1pwr_pins[] = { 143 };
+
+static const int wdog1_pins[] = { 218 };
+static const int wdog2_pins[] = { 219 };
+
+/* BMC serial port 0 */
+static const int bmcuart0a_pins[] = { 41, 42 };
+static const int bmcuart0b_pins[] = { 48, 49 };
+
+static const int bmcuart1_pins[] = { 43, 44, 62, 63 };
+
+/* System Control Interrupt and Power Management Event pin group */
+static const int scipme_pins[] = { 169 };
+/* System Management Interrupt pin group */
+static const int sci_pins[] = { 170 };
+/* Serial Interrupt Line pin group */
+static const int serirq_pins[] = { 162 };
+
+static const int clkout_pins[] = { 160 };
+static const int clkreq_pins[] = { 231 };
+
+static const int jtag2_pins[] = { 43, 44, 45, 46, 47 };
+/* Graphics SPI Clock pin group */
+static const int gspi_pins[] = { 12, 13, 14, 15 };
+
+static const int spix_pins[] = { 224, 225, 226, 227, 229, 230 };
+static const int spixcs1_pins[] = { 228 };
+
+static const int pspi1_pins[] = { 175, 176, 177 };
+static const int pspi2_pins[] = { 17, 18, 19 };
+
+static const int spi0cs1_pins[] = { 32 };
+
+static const int spi3_pins[] = { 183, 184, 185, 186 };
+static const int spi3cs1_pins[] = { 187 };
+static const int spi3quad_pins[] = { 188, 189 };
+static const int spi3cs2_pins[] = { 188 };
+static const int spi3cs3_pins[] = { 189 };
+
+static const int ddc_pins[] = { 204, 205, 206, 207 };
+
+static const int lpc_pins[] = { 95, 161, 163, 164, 165, 166, 167 };
+static const int lpcclk_pins[] = { 168 };
+static const int espi_pins[] = { 95, 161, 163, 164, 165, 166, 167, 168 };
+
+static const int lkgpo0_pins[] = { 16 };
+static const int lkgpo1_pins[] = { 8 };
+static const int lkgpo2_pins[] = { 9 };
+
+static const int nprd_smi_pins[] = { 190 };
+
+/*
+ * pin:             name, number
+ * group:    name, npins,   pins
+ * function: name, ngroups, groups
+ */
+struct npcm7xx_group {
+       const char *name;
+       const unsigned int *pins;
+       int npins;
+};
+
+#define NPCM7XX_GRPS \
+       NPCM7XX_GRP(smb0), \
+       NPCM7XX_GRP(smb0b), \
+       NPCM7XX_GRP(smb0c), \
+       NPCM7XX_GRP(smb0d), \
+       NPCM7XX_GRP(smb0den), \
+       NPCM7XX_GRP(smb1), \
+       NPCM7XX_GRP(smb1b), \
+       NPCM7XX_GRP(smb1c), \
+       NPCM7XX_GRP(smb1d), \
+       NPCM7XX_GRP(smb2), \
+       NPCM7XX_GRP(smb2b), \
+       NPCM7XX_GRP(smb2c), \
+       NPCM7XX_GRP(smb2d), \
+       NPCM7XX_GRP(smb3), \
+       NPCM7XX_GRP(smb3b), \
+       NPCM7XX_GRP(smb3c), \
+       NPCM7XX_GRP(smb3d), \
+       NPCM7XX_GRP(smb4), \
+       NPCM7XX_GRP(smb4b), \
+       NPCM7XX_GRP(smb4c), \
+       NPCM7XX_GRP(smb4d), \
+       NPCM7XX_GRP(smb4den), \
+       NPCM7XX_GRP(smb5), \
+       NPCM7XX_GRP(smb5b), \
+       NPCM7XX_GRP(smb5c), \
+       NPCM7XX_GRP(smb5d), \
+       NPCM7XX_GRP(ga20kbc), \
+       NPCM7XX_GRP(smb6), \
+       NPCM7XX_GRP(smb7), \
+       NPCM7XX_GRP(smb8), \
+       NPCM7XX_GRP(smb9), \
+       NPCM7XX_GRP(smb10), \
+       NPCM7XX_GRP(smb11), \
+       NPCM7XX_GRP(smb12), \
+       NPCM7XX_GRP(smb13), \
+       NPCM7XX_GRP(smb14), \
+       NPCM7XX_GRP(smb15), \
+       NPCM7XX_GRP(fanin0), \
+       NPCM7XX_GRP(fanin1), \
+       NPCM7XX_GRP(fanin2), \
+       NPCM7XX_GRP(fanin3), \
+       NPCM7XX_GRP(fanin4), \
+       NPCM7XX_GRP(fanin5), \
+       NPCM7XX_GRP(fanin6), \
+       NPCM7XX_GRP(fanin7), \
+       NPCM7XX_GRP(fanin8), \
+       NPCM7XX_GRP(fanin9), \
+       NPCM7XX_GRP(fanin10), \
+       NPCM7XX_GRP(fanin11), \
+       NPCM7XX_GRP(fanin12), \
+       NPCM7XX_GRP(fanin13), \
+       NPCM7XX_GRP(fanin14), \
+       NPCM7XX_GRP(fanin15), \
+       NPCM7XX_GRP(faninx), \
+       NPCM7XX_GRP(pwm0), \
+       NPCM7XX_GRP(pwm1), \
+       NPCM7XX_GRP(pwm2), \
+       NPCM7XX_GRP(pwm3), \
+       NPCM7XX_GRP(pwm4), \
+       NPCM7XX_GRP(pwm5), \
+       NPCM7XX_GRP(pwm6), \
+       NPCM7XX_GRP(pwm7), \
+       NPCM7XX_GRP(rg1), \
+       NPCM7XX_GRP(rg1mdio), \
+       NPCM7XX_GRP(rg2), \
+       NPCM7XX_GRP(rg2mdio), \
+       NPCM7XX_GRP(ddr), \
+       NPCM7XX_GRP(uart1), \
+       NPCM7XX_GRP(uart2), \
+       NPCM7XX_GRP(bmcuart0a), \
+       NPCM7XX_GRP(bmcuart0b), \
+       NPCM7XX_GRP(bmcuart1), \
+       NPCM7XX_GRP(iox1), \
+       NPCM7XX_GRP(iox2), \
+       NPCM7XX_GRP(ioxh), \
+       NPCM7XX_GRP(gspi), \
+       NPCM7XX_GRP(mmc), \
+       NPCM7XX_GRP(mmcwp), \
+       NPCM7XX_GRP(mmccd), \
+       NPCM7XX_GRP(mmcrst), \
+       NPCM7XX_GRP(mmc8), \
+       NPCM7XX_GRP(r1), \
+       NPCM7XX_GRP(r1err), \
+       NPCM7XX_GRP(r1md), \
+       NPCM7XX_GRP(r2), \
+       NPCM7XX_GRP(r2err), \
+       NPCM7XX_GRP(r2md), \
+       NPCM7XX_GRP(sd1), \
+       NPCM7XX_GRP(sd1pwr), \
+       NPCM7XX_GRP(wdog1), \
+       NPCM7XX_GRP(wdog2), \
+       NPCM7XX_GRP(scipme), \
+       NPCM7XX_GRP(sci), \
+       NPCM7XX_GRP(serirq), \
+       NPCM7XX_GRP(jtag2), \
+       NPCM7XX_GRP(spix), \
+       NPCM7XX_GRP(spixcs1), \
+       NPCM7XX_GRP(pspi1), \
+       NPCM7XX_GRP(pspi2), \
+       NPCM7XX_GRP(ddc), \
+       NPCM7XX_GRP(clkreq), \
+       NPCM7XX_GRP(clkout), \
+       NPCM7XX_GRP(spi3), \
+       NPCM7XX_GRP(spi3cs1), \
+       NPCM7XX_GRP(spi3quad), \
+       NPCM7XX_GRP(spi3cs2), \
+       NPCM7XX_GRP(spi3cs3), \
+       NPCM7XX_GRP(spi0cs1), \
+       NPCM7XX_GRP(lpc), \
+       NPCM7XX_GRP(lpcclk), \
+       NPCM7XX_GRP(espi), \
+       NPCM7XX_GRP(lkgpo0), \
+       NPCM7XX_GRP(lkgpo1), \
+       NPCM7XX_GRP(lkgpo2), \
+       NPCM7XX_GRP(nprd_smi), \
+       \
+
+enum {
+#define NPCM7XX_GRP(x) fn_ ## x
+       NPCM7XX_GRPS
+       /* add placeholder for none/gpio */
+       NPCM7XX_GRP(none),
+       NPCM7XX_GRP(gpio),
+#undef NPCM7XX_GRP
+};
+
+static struct npcm7xx_group npcm7xx_groups[] = {
+#define NPCM7XX_GRP(x) { .name = #x, .pins = x ## _pins, \
+                       .npins = ARRAY_SIZE(x ## _pins) }
+       NPCM7XX_GRPS
+#undef NPCM7XX_GRP
+};
+
+#define NPCM7XX_SFUNC(a) NPCM7XX_FUNC(a, #a)
+#define NPCM7XX_FUNC(a, b...) static const char *a ## _grp[] = { b }
+#define NPCM7XX_MKFUNC(nm) { .name = #nm, .ngroups = ARRAY_SIZE(nm ## _grp), \
+                       .groups = nm ## _grp }
+struct npcm7xx_func {
+       const char *name;
+       const unsigned int ngroups;
+       const char *const *groups;
+};
+
+NPCM7XX_SFUNC(smb0);
+NPCM7XX_SFUNC(smb0b);
+NPCM7XX_SFUNC(smb0c);
+NPCM7XX_SFUNC(smb0d);
+NPCM7XX_SFUNC(smb0den);
+NPCM7XX_SFUNC(smb1);
+NPCM7XX_SFUNC(smb1b);
+NPCM7XX_SFUNC(smb1c);
+NPCM7XX_SFUNC(smb1d);
+NPCM7XX_SFUNC(smb2);
+NPCM7XX_SFUNC(smb2b);
+NPCM7XX_SFUNC(smb2c);
+NPCM7XX_SFUNC(smb2d);
+NPCM7XX_SFUNC(smb3);
+NPCM7XX_SFUNC(smb3b);
+NPCM7XX_SFUNC(smb3c);
+NPCM7XX_SFUNC(smb3d);
+NPCM7XX_SFUNC(smb4);
+NPCM7XX_SFUNC(smb4b);
+NPCM7XX_SFUNC(smb4c);
+NPCM7XX_SFUNC(smb4d);
+NPCM7XX_SFUNC(smb4den);
+NPCM7XX_SFUNC(smb5);
+NPCM7XX_SFUNC(smb5b);
+NPCM7XX_SFUNC(smb5c);
+NPCM7XX_SFUNC(smb5d);
+NPCM7XX_SFUNC(ga20kbc);
+NPCM7XX_SFUNC(smb6);
+NPCM7XX_SFUNC(smb7);
+NPCM7XX_SFUNC(smb8);
+NPCM7XX_SFUNC(smb9);
+NPCM7XX_SFUNC(smb10);
+NPCM7XX_SFUNC(smb11);
+NPCM7XX_SFUNC(smb12);
+NPCM7XX_SFUNC(smb13);
+NPCM7XX_SFUNC(smb14);
+NPCM7XX_SFUNC(smb15);
+NPCM7XX_SFUNC(fanin0);
+NPCM7XX_SFUNC(fanin1);
+NPCM7XX_SFUNC(fanin2);
+NPCM7XX_SFUNC(fanin3);
+NPCM7XX_SFUNC(fanin4);
+NPCM7XX_SFUNC(fanin5);
+NPCM7XX_SFUNC(fanin6);
+NPCM7XX_SFUNC(fanin7);
+NPCM7XX_SFUNC(fanin8);
+NPCM7XX_SFUNC(fanin9);
+NPCM7XX_SFUNC(fanin10);
+NPCM7XX_SFUNC(fanin11);
+NPCM7XX_SFUNC(fanin12);
+NPCM7XX_SFUNC(fanin13);
+NPCM7XX_SFUNC(fanin14);
+NPCM7XX_SFUNC(fanin15);
+NPCM7XX_SFUNC(faninx);
+NPCM7XX_SFUNC(pwm0);
+NPCM7XX_SFUNC(pwm1);
+NPCM7XX_SFUNC(pwm2);
+NPCM7XX_SFUNC(pwm3);
+NPCM7XX_SFUNC(pwm4);
+NPCM7XX_SFUNC(pwm5);
+NPCM7XX_SFUNC(pwm6);
+NPCM7XX_SFUNC(pwm7);
+NPCM7XX_SFUNC(rg1);
+NPCM7XX_SFUNC(rg1mdio);
+NPCM7XX_SFUNC(rg2);
+NPCM7XX_SFUNC(rg2mdio);
+NPCM7XX_SFUNC(ddr);
+NPCM7XX_SFUNC(uart1);
+NPCM7XX_SFUNC(uart2);
+NPCM7XX_SFUNC(bmcuart0a);
+NPCM7XX_SFUNC(bmcuart0b);
+NPCM7XX_SFUNC(bmcuart1);
+NPCM7XX_SFUNC(iox1);
+NPCM7XX_SFUNC(iox2);
+NPCM7XX_SFUNC(ioxh);
+NPCM7XX_SFUNC(gspi);
+NPCM7XX_SFUNC(mmc);
+NPCM7XX_SFUNC(mmcwp);
+NPCM7XX_SFUNC(mmccd);
+NPCM7XX_SFUNC(mmcrst);
+NPCM7XX_SFUNC(mmc8);
+NPCM7XX_SFUNC(r1);
+NPCM7XX_SFUNC(r1err);
+NPCM7XX_SFUNC(r1md);
+NPCM7XX_SFUNC(r2);
+NPCM7XX_SFUNC(r2err);
+NPCM7XX_SFUNC(r2md);
+NPCM7XX_SFUNC(sd1);
+NPCM7XX_SFUNC(sd1pwr);
+NPCM7XX_SFUNC(wdog1);
+NPCM7XX_SFUNC(wdog2);
+NPCM7XX_SFUNC(scipme);
+NPCM7XX_SFUNC(sci);
+NPCM7XX_SFUNC(serirq);
+NPCM7XX_SFUNC(jtag2);
+NPCM7XX_SFUNC(spix);
+NPCM7XX_SFUNC(spixcs1);
+NPCM7XX_SFUNC(pspi1);
+NPCM7XX_SFUNC(pspi2);
+NPCM7XX_SFUNC(ddc);
+NPCM7XX_SFUNC(clkreq);
+NPCM7XX_SFUNC(clkout);
+NPCM7XX_SFUNC(spi3);
+NPCM7XX_SFUNC(spi3cs1);
+NPCM7XX_SFUNC(spi3quad);
+NPCM7XX_SFUNC(spi3cs2);
+NPCM7XX_SFUNC(spi3cs3);
+NPCM7XX_SFUNC(spi0cs1);
+NPCM7XX_SFUNC(lpc);
+NPCM7XX_SFUNC(lpcclk);
+NPCM7XX_SFUNC(espi);
+NPCM7XX_SFUNC(lkgpo0);
+NPCM7XX_SFUNC(lkgpo1);
+NPCM7XX_SFUNC(lkgpo2);
+NPCM7XX_SFUNC(nprd_smi);
+
+/* Function names */
+static struct npcm7xx_func npcm7xx_funcs[] = {
+       NPCM7XX_MKFUNC(smb0),
+       NPCM7XX_MKFUNC(smb0b),
+       NPCM7XX_MKFUNC(smb0c),
+       NPCM7XX_MKFUNC(smb0d),
+       NPCM7XX_MKFUNC(smb0den),
+       NPCM7XX_MKFUNC(smb1),
+       NPCM7XX_MKFUNC(smb1b),
+       NPCM7XX_MKFUNC(smb1c),
+       NPCM7XX_MKFUNC(smb1d),
+       NPCM7XX_MKFUNC(smb2),
+       NPCM7XX_MKFUNC(smb2b),
+       NPCM7XX_MKFUNC(smb2c),
+       NPCM7XX_MKFUNC(smb2d),
+       NPCM7XX_MKFUNC(smb3),
+       NPCM7XX_MKFUNC(smb3b),
+       NPCM7XX_MKFUNC(smb3c),
+       NPCM7XX_MKFUNC(smb3d),
+       NPCM7XX_MKFUNC(smb4),
+       NPCM7XX_MKFUNC(smb4b),
+       NPCM7XX_MKFUNC(smb4c),
+       NPCM7XX_MKFUNC(smb4d),
+       NPCM7XX_MKFUNC(smb4den),
+       NPCM7XX_MKFUNC(smb5),
+       NPCM7XX_MKFUNC(smb5b),
+       NPCM7XX_MKFUNC(smb5c),
+       NPCM7XX_MKFUNC(smb5d),
+       NPCM7XX_MKFUNC(ga20kbc),
+       NPCM7XX_MKFUNC(smb6),
+       NPCM7XX_MKFUNC(smb7),
+       NPCM7XX_MKFUNC(smb8),
+       NPCM7XX_MKFUNC(smb9),
+       NPCM7XX_MKFUNC(smb10),
+       NPCM7XX_MKFUNC(smb11),
+       NPCM7XX_MKFUNC(smb12),
+       NPCM7XX_MKFUNC(smb13),
+       NPCM7XX_MKFUNC(smb14),
+       NPCM7XX_MKFUNC(smb15),
+       NPCM7XX_MKFUNC(fanin0),
+       NPCM7XX_MKFUNC(fanin1),
+       NPCM7XX_MKFUNC(fanin2),
+       NPCM7XX_MKFUNC(fanin3),
+       NPCM7XX_MKFUNC(fanin4),
+       NPCM7XX_MKFUNC(fanin5),
+       NPCM7XX_MKFUNC(fanin6),
+       NPCM7XX_MKFUNC(fanin7),
+       NPCM7XX_MKFUNC(fanin8),
+       NPCM7XX_MKFUNC(fanin9),
+       NPCM7XX_MKFUNC(fanin10),
+       NPCM7XX_MKFUNC(fanin11),
+       NPCM7XX_MKFUNC(fanin12),
+       NPCM7XX_MKFUNC(fanin13),
+       NPCM7XX_MKFUNC(fanin14),
+       NPCM7XX_MKFUNC(fanin15),
+       NPCM7XX_MKFUNC(faninx),
+       NPCM7XX_MKFUNC(pwm0),
+       NPCM7XX_MKFUNC(pwm1),
+       NPCM7XX_MKFUNC(pwm2),
+       NPCM7XX_MKFUNC(pwm3),
+       NPCM7XX_MKFUNC(pwm4),
+       NPCM7XX_MKFUNC(pwm5),
+       NPCM7XX_MKFUNC(pwm6),
+       NPCM7XX_MKFUNC(pwm7),
+       NPCM7XX_MKFUNC(rg1),
+       NPCM7XX_MKFUNC(rg1mdio),
+       NPCM7XX_MKFUNC(rg2),
+       NPCM7XX_MKFUNC(rg2mdio),
+       NPCM7XX_MKFUNC(ddr),
+       NPCM7XX_MKFUNC(uart1),
+       NPCM7XX_MKFUNC(uart2),
+       NPCM7XX_MKFUNC(bmcuart0a),
+       NPCM7XX_MKFUNC(bmcuart0b),
+       NPCM7XX_MKFUNC(bmcuart1),
+       NPCM7XX_MKFUNC(iox1),
+       NPCM7XX_MKFUNC(iox2),
+       NPCM7XX_MKFUNC(ioxh),
+       NPCM7XX_MKFUNC(gspi),
+       NPCM7XX_MKFUNC(mmc),
+       NPCM7XX_MKFUNC(mmcwp),
+       NPCM7XX_MKFUNC(mmccd),
+       NPCM7XX_MKFUNC(mmcrst),
+       NPCM7XX_MKFUNC(mmc8),
+       NPCM7XX_MKFUNC(r1),
+       NPCM7XX_MKFUNC(r1err),
+       NPCM7XX_MKFUNC(r1md),
+       NPCM7XX_MKFUNC(r2),
+       NPCM7XX_MKFUNC(r2err),
+       NPCM7XX_MKFUNC(r2md),
+       NPCM7XX_MKFUNC(sd1),
+       NPCM7XX_MKFUNC(sd1pwr),
+       NPCM7XX_MKFUNC(wdog1),
+       NPCM7XX_MKFUNC(wdog2),
+       NPCM7XX_MKFUNC(scipme),
+       NPCM7XX_MKFUNC(sci),
+       NPCM7XX_MKFUNC(serirq),
+       NPCM7XX_MKFUNC(jtag2),
+       NPCM7XX_MKFUNC(spix),
+       NPCM7XX_MKFUNC(spixcs1),
+       NPCM7XX_MKFUNC(pspi1),
+       NPCM7XX_MKFUNC(pspi2),
+       NPCM7XX_MKFUNC(ddc),
+       NPCM7XX_MKFUNC(clkreq),
+       NPCM7XX_MKFUNC(clkout),
+       NPCM7XX_MKFUNC(spi3),
+       NPCM7XX_MKFUNC(spi3cs1),
+       NPCM7XX_MKFUNC(spi3quad),
+       NPCM7XX_MKFUNC(spi3cs2),
+       NPCM7XX_MKFUNC(spi3cs3),
+       NPCM7XX_MKFUNC(spi0cs1),
+       NPCM7XX_MKFUNC(lpc),
+       NPCM7XX_MKFUNC(lpcclk),
+       NPCM7XX_MKFUNC(espi),
+       NPCM7XX_MKFUNC(lkgpo0),
+       NPCM7XX_MKFUNC(lkgpo1),
+       NPCM7XX_MKFUNC(lkgpo2),
+       NPCM7XX_MKFUNC(nprd_smi),
+};
+
+#define NPCM7XX_PINCFG(a, b, c, d, e, f, g, h, i, j, k) \
+       [a] { .fn0 = fn_ ## b, .reg0 = NPCM7XX_GCR_ ## c, .bit0 = d, \
+                       .fn1 = fn_ ## e, .reg1 = NPCM7XX_GCR_ ## f, .bit1 = g, \
+                       .fn2 = fn_ ## h, .reg2 = NPCM7XX_GCR_ ## i, .bit2 = j, \
+                       .flag = k }
+
+/* Drive strength controlled by NPCM7XX_GP_N_ODSC */
+#define DRIVE_STRENGTH_LO_SHIFT                8
+#define DRIVE_STRENGTH_HI_SHIFT                12
+#define DRIVE_STRENGTH_MASK            0x0000FF00
+
+#define DS(lo, hi)     (((lo) << DRIVE_STRENGTH_LO_SHIFT) | \
+                        ((hi) << DRIVE_STRENGTH_HI_SHIFT))
+#define DSLO(x)                (((x) >> DRIVE_STRENGTH_LO_SHIFT) & 0xF)
+#define DSHI(x)                (((x) >> DRIVE_STRENGTH_HI_SHIFT) & 0xF)
+
+#define GPI            0x1 /* Not GPO */
+#define GPO            0x2 /* Not GPI */
+#define SLEW           0x4 /* Has Slew Control, NPCM7XX_GP_N_OSRC */
+#define SLEWLPC                0x8 /* Has Slew Control, SRCNT.3 */
+
+struct npcm7xx_pincfg {
+       int flag;
+       int fn0, reg0, bit0;
+       int fn1, reg1, bit1;
+       int fn2, reg2, bit2;
+};
+
+static const struct npcm7xx_pincfg pincfg[] = {
+       /*      PIN       FUNCTION 1               FUNCTION 2             FUNCTION 3        FLAGS */
+       NPCM7XX_PINCFG(0,        iox1, MFSEL1, 30,        none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(1,        iox1, MFSEL1, 30,        none, NONE, 0,        none, NONE, 0,       DS(8, 12)),
+       NPCM7XX_PINCFG(2,        iox1, MFSEL1, 30,        none, NONE, 0,        none, NONE, 0,       DS(8, 12)),
+       NPCM7XX_PINCFG(3,        iox1, MFSEL1, 30,        none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(4,        iox2, MFSEL3, 14,       smb1d, I2CSEGSEL, 7,   none, NONE, 0,       SLEW),
+       NPCM7XX_PINCFG(5,        iox2, MFSEL3, 14,       smb1d, I2CSEGSEL, 7,   none, NONE, 0,       SLEW),
+       NPCM7XX_PINCFG(6,        iox2, MFSEL3, 14,       smb2d, I2CSEGSEL, 10,  none, NONE, 0,       SLEW),
+       NPCM7XX_PINCFG(7,        iox2, MFSEL3, 14,       smb2d, I2CSEGSEL, 10,  none, NONE, 0,       SLEW),
+       NPCM7XX_PINCFG(8,      lkgpo1, FLOCKR1, 4,        none, NONE, 0,        none, NONE, 0,       DS(8, 12)),
+       NPCM7XX_PINCFG(9,      lkgpo2, FLOCKR1, 8,        none, NONE, 0,        none, NONE, 0,       DS(8, 12)),
+       NPCM7XX_PINCFG(10,       ioxh, MFSEL3, 18,        none, NONE, 0,        none, NONE, 0,       DS(8, 12)),
+       NPCM7XX_PINCFG(11,       ioxh, MFSEL3, 18,        none, NONE, 0,        none, NONE, 0,       DS(8, 12)),
+       NPCM7XX_PINCFG(12,       gspi, MFSEL1, 24,       smb5b, I2CSEGSEL, 19,  none, NONE, 0,       SLEW),
+       NPCM7XX_PINCFG(13,       gspi, MFSEL1, 24,       smb5b, I2CSEGSEL, 19,  none, NONE, 0,       SLEW),
+       NPCM7XX_PINCFG(14,       gspi, MFSEL1, 24,       smb5c, I2CSEGSEL, 20,  none, NONE, 0,       SLEW),
+       NPCM7XX_PINCFG(15,       gspi, MFSEL1, 24,       smb5c, I2CSEGSEL, 20,  none, NONE, 0,       SLEW),
+       NPCM7XX_PINCFG(16,     lkgpo0, FLOCKR1, 0,        none, NONE, 0,        none, NONE, 0,       DS(8, 12)),
+       NPCM7XX_PINCFG(17,      pspi2, MFSEL3, 13,     smb4den, I2CSEGSEL, 23,  none, NONE, 0,       DS(8, 12)),
+       NPCM7XX_PINCFG(18,      pspi2, MFSEL3, 13,       smb4b, I2CSEGSEL, 14,  none, NONE, 0,       DS(8, 12)),
+       NPCM7XX_PINCFG(19,      pspi2, MFSEL3, 13,       smb4b, I2CSEGSEL, 14,  none, NONE, 0,       DS(8, 12)),
+       NPCM7XX_PINCFG(20,      smb4c, I2CSEGSEL, 15,    smb15, MFSEL3, 8,      none, NONE, 0,       0),
+       NPCM7XX_PINCFG(21,      smb4c, I2CSEGSEL, 15,    smb15, MFSEL3, 8,      none, NONE, 0,       0),
+       NPCM7XX_PINCFG(22,      smb4d, I2CSEGSEL, 16,    smb14, MFSEL3, 7,      none, NONE, 0,       0),
+       NPCM7XX_PINCFG(23,      smb4d, I2CSEGSEL, 16,    smb14, MFSEL3, 7,      none, NONE, 0,       0),
+       NPCM7XX_PINCFG(24,       ioxh, MFSEL3, 18,        none, NONE, 0,        none, NONE, 0,       DS(8, 12)),
+       NPCM7XX_PINCFG(25,       ioxh, MFSEL3, 18,        none, NONE, 0,        none, NONE, 0,       DS(8, 12)),
+       NPCM7XX_PINCFG(26,       smb5, MFSEL1, 2,         none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(27,       smb5, MFSEL1, 2,         none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(28,       smb4, MFSEL1, 1,         none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(29,       smb4, MFSEL1, 1,         none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(30,       smb3, MFSEL1, 0,         none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(31,       smb3, MFSEL1, 0,         none, NONE, 0,        none, NONE, 0,       0),
+
+       NPCM7XX_PINCFG(32,    spi0cs1, MFSEL1, 3,         none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(33,   none, NONE, 0,     none, NONE, 0,  none, NONE, 0,       SLEW),
+       NPCM7XX_PINCFG(34,   none, NONE, 0,     none, NONE, 0,  none, NONE, 0,       SLEW),
+       NPCM7XX_PINCFG(37,      smb3c, I2CSEGSEL, 12,     none, NONE, 0,        none, NONE, 0,       SLEW),
+       NPCM7XX_PINCFG(38,      smb3c, I2CSEGSEL, 12,     none, NONE, 0,        none, NONE, 0,       SLEW),
+       NPCM7XX_PINCFG(39,      smb3b, I2CSEGSEL, 11,     none, NONE, 0,        none, NONE, 0,       SLEW),
+       NPCM7XX_PINCFG(40,      smb3b, I2CSEGSEL, 11,     none, NONE, 0,        none, NONE, 0,       SLEW),
+       NPCM7XX_PINCFG(41,  bmcuart0a, MFSEL1, 9,         none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(42,  bmcuart0a, MFSEL1, 9,         none, NONE, 0,        none, NONE, 0,       DS(2, 4) | GPO),
+       NPCM7XX_PINCFG(43,      uart1, MFSEL1, 10,       jtag2, MFSEL4, 0,  bmcuart1, MFSEL3, 24,    0),
+       NPCM7XX_PINCFG(44,      uart1, MFSEL1, 10,       jtag2, MFSEL4, 0,  bmcuart1, MFSEL3, 24,    0),
+       NPCM7XX_PINCFG(45,      uart1, MFSEL1, 10,       jtag2, MFSEL4, 0,      none, NONE, 0,       0),
+       NPCM7XX_PINCFG(46,      uart1, MFSEL1, 10,       jtag2, MFSEL4, 0,      none, NONE, 0,       DS(2, 8)),
+       NPCM7XX_PINCFG(47,      uart1, MFSEL1, 10,       jtag2, MFSEL4, 0,      none, NONE, 0,       DS(2, 8)),
+       NPCM7XX_PINCFG(48,      uart2, MFSEL1, 11,   bmcuart0b, MFSEL4, 1,      none, NONE, 0,       GPO),
+       NPCM7XX_PINCFG(49,      uart2, MFSEL1, 11,   bmcuart0b, MFSEL4, 1,      none, NONE, 0,       0),
+       NPCM7XX_PINCFG(50,      uart2, MFSEL1, 11,        none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(51,      uart2, MFSEL1, 11,        none, NONE, 0,        none, NONE, 0,       GPO),
+       NPCM7XX_PINCFG(52,      uart2, MFSEL1, 11,        none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(53,      uart2, MFSEL1, 11,        none, NONE, 0,        none, NONE, 0,       GPO),
+       NPCM7XX_PINCFG(54,      uart2, MFSEL1, 11,        none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(55,      uart2, MFSEL1, 11,        none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(56,      r1err, MFSEL1, 12,        none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(57,       r1md, MFSEL1, 13,        none, NONE, 0,        none, NONE, 0,       DS(2, 4)),
+       NPCM7XX_PINCFG(58,       r1md, MFSEL1, 13,        none, NONE, 0,        none, NONE, 0,       DS(2, 4)),
+       NPCM7XX_PINCFG(59,      smb3d, I2CSEGSEL, 13,     none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(60,      smb3d, I2CSEGSEL, 13,     none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(61,      uart1, MFSEL1, 10,        none, NONE, 0,        none, NONE, 0,     GPO),
+       NPCM7XX_PINCFG(62,      uart1, MFSEL1, 10,    bmcuart1, MFSEL3, 24,     none, NONE, 0,     GPO),
+       NPCM7XX_PINCFG(63,      uart1, MFSEL1, 10,    bmcuart1, MFSEL3, 24,     none, NONE, 0,     GPO),
+
+       NPCM7XX_PINCFG(64,    fanin0, MFSEL2, 0,          none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(65,    fanin1, MFSEL2, 1,          none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(66,    fanin2, MFSEL2, 2,          none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(67,    fanin3, MFSEL2, 3,          none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(68,    fanin4, MFSEL2, 4,          none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(69,    fanin5, MFSEL2, 5,          none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(70,    fanin6, MFSEL2, 6,          none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(71,    fanin7, MFSEL2, 7,          none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(72,    fanin8, MFSEL2, 8,          none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(73,    fanin9, MFSEL2, 9,          none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(74,    fanin10, MFSEL2, 10,        none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(75,    fanin11, MFSEL2, 11,        none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(76,    fanin12, MFSEL2, 12,        none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(77,    fanin13, MFSEL2, 13,        none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(78,    fanin14, MFSEL2, 14,        none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(79,    fanin15, MFSEL2, 15,        none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(80,       pwm0, MFSEL2, 16,        none, NONE, 0,        none, NONE, 0,       DS(4, 8)),
+       NPCM7XX_PINCFG(81,       pwm1, MFSEL2, 17,        none, NONE, 0,        none, NONE, 0,       DS(4, 8)),
+       NPCM7XX_PINCFG(82,       pwm2, MFSEL2, 18,        none, NONE, 0,        none, NONE, 0,       DS(4, 8)),
+       NPCM7XX_PINCFG(83,       pwm3, MFSEL2, 19,        none, NONE, 0,        none, NONE, 0,       DS(4, 8)),
+       NPCM7XX_PINCFG(84,         r2, MFSEL1, 14,        none, NONE, 0,        none, NONE, 0,       DS(8, 12) | SLEW),
+       NPCM7XX_PINCFG(85,         r2, MFSEL1, 14,        none, NONE, 0,        none, NONE, 0,       DS(8, 12) | SLEW),
+       NPCM7XX_PINCFG(86,         r2, MFSEL1, 14,        none, NONE, 0,        none, NONE, 0,       DS(8, 12) | SLEW),
+       NPCM7XX_PINCFG(87,         r2, MFSEL1, 14,        none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(88,         r2, MFSEL1, 14,        none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(89,         r2, MFSEL1, 14,        none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(90,      r2err, MFSEL1, 15,        none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(91,       r2md, MFSEL1, 16,        none, NONE, 0,        none, NONE, 0,       DS(2, 4)),
+       NPCM7XX_PINCFG(92,       r2md, MFSEL1, 16,        none, NONE, 0,        none, NONE, 0,       DS(2, 4)),
+       NPCM7XX_PINCFG(93,    ga20kbc, MFSEL1, 17,       smb5d, I2CSEGSEL, 21,  none, NONE, 0,       0),
+       NPCM7XX_PINCFG(94,    ga20kbc, MFSEL1, 17,       smb5d, I2CSEGSEL, 21,  none, NONE, 0,       0),
+       NPCM7XX_PINCFG(95,        lpc, NONE, 0,           espi, MFSEL4, 8,      gpio, MFSEL1, 26,    0),
+
+       NPCM7XX_PINCFG(96,        rg1, MFSEL4, 22,        none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(97,        rg1, MFSEL4, 22,        none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(98,        rg1, MFSEL4, 22,        none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(99,        rg1, MFSEL4, 22,        none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(100,       rg1, MFSEL4, 22,        none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(101,       rg1, MFSEL4, 22,        none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(102,       rg1, MFSEL4, 22,        none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(103,       rg1, MFSEL4, 22,        none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(104,       rg1, MFSEL4, 22,        none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(105,       rg1, MFSEL4, 22,        none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(106,       rg1, MFSEL4, 22,        none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(107,       rg1, MFSEL4, 22,        none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(108,   rg1mdio, MFSEL4, 21,        none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(109,   rg1mdio, MFSEL4, 21,        none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(110,       rg2, MFSEL4, 24,         ddr, MFSEL3, 26,     none, NONE, 0,       0),
+       NPCM7XX_PINCFG(111,       rg2, MFSEL4, 24,         ddr, MFSEL3, 26,     none, NONE, 0,       0),
+       NPCM7XX_PINCFG(112,       rg2, MFSEL4, 24,         ddr, MFSEL3, 26,     none, NONE, 0,       0),
+       NPCM7XX_PINCFG(113,       rg2, MFSEL4, 24,         ddr, MFSEL3, 26,     none, NONE, 0,       0),
+       NPCM7XX_PINCFG(114,      smb0, MFSEL1, 6,         none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(115,      smb0, MFSEL1, 6,         none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(116,      smb1, MFSEL1, 7,         none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(117,      smb1, MFSEL1, 7,         none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(118,      smb2, MFSEL1, 8,         none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(119,      smb2, MFSEL1, 8,         none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(120,     smb2c, I2CSEGSEL, 9,      none, NONE, 0,        none, NONE, 0,       SLEW),
+       NPCM7XX_PINCFG(121,     smb2c, I2CSEGSEL, 9,      none, NONE, 0,        none, NONE, 0,       SLEW),
+       NPCM7XX_PINCFG(122,     smb2b, I2CSEGSEL, 8,      none, NONE, 0,        none, NONE, 0,       SLEW),
+       NPCM7XX_PINCFG(123,     smb2b, I2CSEGSEL, 8,      none, NONE, 0,        none, NONE, 0,       SLEW),
+       NPCM7XX_PINCFG(124,     smb1c, I2CSEGSEL, 6,      none, NONE, 0,        none, NONE, 0,       SLEW),
+       NPCM7XX_PINCFG(125,     smb1c, I2CSEGSEL, 6,      none, NONE, 0,        none, NONE, 0,       SLEW),
+       NPCM7XX_PINCFG(126,     smb1b, I2CSEGSEL, 5,      none, NONE, 0,        none, NONE, 0,       SLEW),
+       NPCM7XX_PINCFG(127,     smb1b, I2CSEGSEL, 5,      none, NONE, 0,        none, NONE, 0,       SLEW),
+
+       NPCM7XX_PINCFG(128,      smb8, MFSEL4, 11,        none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(129,      smb8, MFSEL4, 11,        none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(130,      smb9, MFSEL4, 12,        none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(131,      smb9, MFSEL4, 12,        none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(132,     smb10, MFSEL4, 13,        none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(133,     smb10, MFSEL4, 13,        none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(134,     smb11, MFSEL4, 14,        none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(135,     smb11, MFSEL4, 14,        none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(136,       sd1, MFSEL3, 12,        none, NONE, 0,        none, NONE, 0,       DS(8, 12) | SLEW),
+       NPCM7XX_PINCFG(137,       sd1, MFSEL3, 12,        none, NONE, 0,        none, NONE, 0,       DS(8, 12) | SLEW),
+       NPCM7XX_PINCFG(138,       sd1, MFSEL3, 12,        none, NONE, 0,        none, NONE, 0,       DS(8, 12) | SLEW),
+       NPCM7XX_PINCFG(139,       sd1, MFSEL3, 12,        none, NONE, 0,        none, NONE, 0,       DS(8, 12) | SLEW),
+       NPCM7XX_PINCFG(140,       sd1, MFSEL3, 12,        none, NONE, 0,        none, NONE, 0,       DS(8, 12) | SLEW),
+       NPCM7XX_PINCFG(141,       sd1, MFSEL3, 12,        none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(142,       sd1, MFSEL3, 12,        none, NONE, 0,        none, NONE, 0,       DS(8, 12) | SLEW),
+       NPCM7XX_PINCFG(143,       sd1, MFSEL3, 12,      sd1pwr, MFSEL4, 5,      none, NONE, 0,       0),
+       NPCM7XX_PINCFG(144,      pwm4, MFSEL2, 20,        none, NONE, 0,        none, NONE, 0,       DS(4, 8)),
+       NPCM7XX_PINCFG(145,      pwm5, MFSEL2, 21,        none, NONE, 0,        none, NONE, 0,       DS(4, 8)),
+       NPCM7XX_PINCFG(146,      pwm6, MFSEL2, 22,        none, NONE, 0,        none, NONE, 0,       DS(4, 8)),
+       NPCM7XX_PINCFG(147,      pwm7, MFSEL2, 23,        none, NONE, 0,        none, NONE, 0,       DS(4, 8)),
+       NPCM7XX_PINCFG(148,      mmc8, MFSEL3, 11,        none, NONE, 0,        none, NONE, 0,       DS(8, 12) | SLEW),
+       NPCM7XX_PINCFG(149,      mmc8, MFSEL3, 11,        none, NONE, 0,        none, NONE, 0,       DS(8, 12) | SLEW),
+       NPCM7XX_PINCFG(150,      mmc8, MFSEL3, 11,        none, NONE, 0,        none, NONE, 0,       DS(8, 12) | SLEW),
+       NPCM7XX_PINCFG(151,      mmc8, MFSEL3, 11,        none, NONE, 0,        none, NONE, 0,       DS(8, 12) | SLEW),
+       NPCM7XX_PINCFG(152,       mmc, MFSEL3, 10,        none, NONE, 0,        none, NONE, 0,       DS(8, 12) | SLEW),
+       NPCM7XX_PINCFG(153,     mmcwp, FLOCKR1, 24,       none, NONE, 0,        none, NONE, 0,       0),  /* Z1/A1 */
+       NPCM7XX_PINCFG(154,       mmc, MFSEL3, 10,        none, NONE, 0,        none, NONE, 0,       DS(8, 12) | SLEW),
+       NPCM7XX_PINCFG(155,     mmccd, MFSEL3, 25,      mmcrst, MFSEL4, 6,      none, NONE, 0,       0),  /* Z1/A1 */
+       NPCM7XX_PINCFG(156,       mmc, MFSEL3, 10,        none, NONE, 0,        none, NONE, 0,       DS(8, 12) | SLEW),
+       NPCM7XX_PINCFG(157,       mmc, MFSEL3, 10,        none, NONE, 0,        none, NONE, 0,       DS(8, 12) | SLEW),
+       NPCM7XX_PINCFG(158,       mmc, MFSEL3, 10,        none, NONE, 0,        none, NONE, 0,       DS(8, 12) | SLEW),
+       NPCM7XX_PINCFG(159,       mmc, MFSEL3, 10,        none, NONE, 0,        none, NONE, 0,       DS(8, 12) | SLEW),
+
+       NPCM7XX_PINCFG(160,    clkout, MFSEL1, 21,        none, NONE, 0,        none, NONE, 0,       DS(8, 12) | SLEW),
+       NPCM7XX_PINCFG(161,       lpc, NONE, 0,           espi, MFSEL4, 8,      gpio, MFSEL1, 26,    DS(8, 12)),
+       NPCM7XX_PINCFG(162,    serirq, NONE, 0,           gpio, MFSEL1, 31,     none, NONE, 0,       DS(8, 12)),
+       NPCM7XX_PINCFG(163,       lpc, NONE, 0,           espi, MFSEL4, 8,      gpio, MFSEL1, 26,    0),
+       NPCM7XX_PINCFG(164,       lpc, NONE, 0,           espi, MFSEL4, 8,      gpio, MFSEL1, 26,    SLEWLPC),
+       NPCM7XX_PINCFG(165,       lpc, NONE, 0,           espi, MFSEL4, 8,      gpio, MFSEL1, 26,    SLEWLPC),
+       NPCM7XX_PINCFG(166,       lpc, NONE, 0,           espi, MFSEL4, 8,      gpio, MFSEL1, 26,    SLEWLPC),
+       NPCM7XX_PINCFG(167,       lpc, NONE, 0,           espi, MFSEL4, 8,      gpio, MFSEL1, 26,    SLEWLPC),
+       NPCM7XX_PINCFG(168,    lpcclk, NONE, 0,           espi, MFSEL4, 8,      gpio, MFSEL3, 16,    0),
+       NPCM7XX_PINCFG(169,    scipme, MFSEL3, 0,         none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(170,       sci, MFSEL1, 22,        none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(171,      smb6, MFSEL3, 1,         none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(172,      smb6, MFSEL3, 1,         none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(173,      smb7, MFSEL3, 2,         none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(174,      smb7, MFSEL3, 2,         none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(175,     pspi1, MFSEL3, 4,       faninx, MFSEL3, 3,      none, NONE, 0,       DS(8, 12)),
+       NPCM7XX_PINCFG(176,     pspi1, MFSEL3, 4,       faninx, MFSEL3, 3,      none, NONE, 0,       DS(8, 12)),
+       NPCM7XX_PINCFG(177,     pspi1, MFSEL3, 4,       faninx, MFSEL3, 3,      none, NONE, 0,       DS(8, 12)),
+       NPCM7XX_PINCFG(178,        r1, MFSEL3, 9,         none, NONE, 0,        none, NONE, 0,       DS(8, 12) | SLEW),
+       NPCM7XX_PINCFG(179,        r1, MFSEL3, 9,         none, NONE, 0,        none, NONE, 0,       DS(8, 12) | SLEW),
+       NPCM7XX_PINCFG(180,        r1, MFSEL3, 9,         none, NONE, 0,        none, NONE, 0,       DS(8, 12) | SLEW),
+       NPCM7XX_PINCFG(181,        r1, MFSEL3, 9,         none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(182,        r1, MFSEL3, 9,         none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(183,     spi3, MFSEL4, 16,         none, NONE, 0,        none, NONE, 0,       DS(8, 12) | SLEW),
+       NPCM7XX_PINCFG(184,     spi3, MFSEL4, 16,         none, NONE, 0,        none, NONE, 0,       DS(8, 12) | SLEW | GPO),
+       NPCM7XX_PINCFG(185,     spi3, MFSEL4, 16,         none, NONE, 0,        none, NONE, 0,       DS(8, 12) | SLEW | GPO),
+       NPCM7XX_PINCFG(186,     spi3, MFSEL4, 16,         none, NONE, 0,        none, NONE, 0,       DS(8, 12)),
+       NPCM7XX_PINCFG(187,   spi3cs1, MFSEL4, 17,        none, NONE, 0,        none, NONE, 0,       DS(8, 12)),
+       NPCM7XX_PINCFG(188,  spi3quad, MFSEL4, 20,     spi3cs2, MFSEL4, 18,     none, NONE, 0,    DS(8, 12) | SLEW),
+       NPCM7XX_PINCFG(189,  spi3quad, MFSEL4, 20,     spi3cs3, MFSEL4, 19,     none, NONE, 0,    DS(8, 12) | SLEW),
+       NPCM7XX_PINCFG(190,      gpio, FLOCKR1, 20,   nprd_smi, NONE, 0,        none, NONE, 0,       DS(2, 4)),
+       NPCM7XX_PINCFG(191,      none, NONE, 0,           none, NONE, 0,        none, NONE, 0,       DS(8, 12)),  /* XX */
+
+       NPCM7XX_PINCFG(192,      none, NONE, 0,           none, NONE, 0,        none, NONE, 0,       DS(8, 12)),  /* XX */
+       NPCM7XX_PINCFG(193,        r1, MFSEL3, 9,         none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(194,     smb0b, I2CSEGSEL, 0,      none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(195,     smb0b, I2CSEGSEL, 0,      none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(196,     smb0c, I2CSEGSEL, 1,      none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(197,   smb0den, I2CSEGSEL, 22,     none, NONE, 0,        none, NONE, 0,       SLEW),
+       NPCM7XX_PINCFG(198,     smb0d, I2CSEGSEL, 2,      none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(199,     smb0d, I2CSEGSEL, 2,      none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(200,        r2, MFSEL1, 14,        none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(201,        r1, MFSEL3, 9,         none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(202,     smb0c, I2CSEGSEL, 1,      none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(203,    faninx, MFSEL3, 3,         none, NONE, 0,        none, NONE, 0,       DS(8, 12)),
+       NPCM7XX_PINCFG(204,       ddc, NONE, 0,           gpio, MFSEL3, 22,     none, NONE, 0,       SLEW),
+       NPCM7XX_PINCFG(205,       ddc, NONE, 0,           gpio, MFSEL3, 22,     none, NONE, 0,       SLEW),
+       NPCM7XX_PINCFG(206,       ddc, NONE, 0,           gpio, MFSEL3, 22,     none, NONE, 0,       DS(4, 8)),
+       NPCM7XX_PINCFG(207,       ddc, NONE, 0,           gpio, MFSEL3, 22,     none, NONE, 0,       DS(4, 8)),
+       NPCM7XX_PINCFG(208,       rg2, MFSEL4, 24,         ddr, MFSEL3, 26,     none, NONE, 0,       0),
+       NPCM7XX_PINCFG(209,       rg2, MFSEL4, 24,         ddr, MFSEL3, 26,     none, NONE, 0,       0),
+       NPCM7XX_PINCFG(210,       rg2, MFSEL4, 24,         ddr, MFSEL3, 26,     none, NONE, 0,       0),
+       NPCM7XX_PINCFG(211,       rg2, MFSEL4, 24,         ddr, MFSEL3, 26,     none, NONE, 0,       0),
+       NPCM7XX_PINCFG(212,       rg2, MFSEL4, 24,         ddr, MFSEL3, 26,     none, NONE, 0,       0),
+       NPCM7XX_PINCFG(213,       rg2, MFSEL4, 24,         ddr, MFSEL3, 26,     none, NONE, 0,       0),
+       NPCM7XX_PINCFG(214,       rg2, MFSEL4, 24,         ddr, MFSEL3, 26,     none, NONE, 0,       0),
+       NPCM7XX_PINCFG(215,       rg2, MFSEL4, 24,         ddr, MFSEL3, 26,     none, NONE, 0,       0),
+       NPCM7XX_PINCFG(216,   rg2mdio, MFSEL4, 23,         ddr, MFSEL3, 26,     none, NONE, 0,       0),
+       NPCM7XX_PINCFG(217,   rg2mdio, MFSEL4, 23,         ddr, MFSEL3, 26,     none, NONE, 0,       0),
+       NPCM7XX_PINCFG(218,     wdog1, MFSEL3, 19,        none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(219,     wdog2, MFSEL3, 20,        none, NONE, 0,        none, NONE, 0,       DS(4, 8)),
+       NPCM7XX_PINCFG(220,     smb12, MFSEL3, 5,         none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(221,     smb12, MFSEL3, 5,         none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(222,     smb13, MFSEL3, 6,         none, NONE, 0,        none, NONE, 0,       0),
+       NPCM7XX_PINCFG(223,     smb13, MFSEL3, 6,         none, NONE, 0,        none, NONE, 0,       0),
+
+       NPCM7XX_PINCFG(224,      spix, MFSEL4, 27,        none, NONE, 0,        none, NONE, 0,       SLEW),
+       NPCM7XX_PINCFG(225,      spix, MFSEL4, 27,        none, NONE, 0,        none, NONE, 0,       DS(8, 12) | SLEW | GPO),
+       NPCM7XX_PINCFG(226,      spix, MFSEL4, 27,        none, NONE, 0,        none, NONE, 0,       DS(8, 12) | SLEW | GPO),
+       NPCM7XX_PINCFG(227,      spix, MFSEL4, 27,        none, NONE, 0,        none, NONE, 0,       DS(8, 12) | SLEW),
+       NPCM7XX_PINCFG(228,   spixcs1, MFSEL4, 28,        none, NONE, 0,        none, NONE, 0,       DS(8, 12) | SLEW),
+       NPCM7XX_PINCFG(229,      spix, MFSEL4, 27,        none, NONE, 0,        none, NONE, 0,       DS(8, 12) | SLEW),
+       NPCM7XX_PINCFG(230,      spix, MFSEL4, 27,        none, NONE, 0,        none, NONE, 0,       DS(8, 12) | SLEW),
+       NPCM7XX_PINCFG(231,    clkreq, MFSEL4, 9,         none, NONE, 0,        none, NONE, 0,       DS(8, 12)),
+       NPCM7XX_PINCFG(253,      none, NONE, 0,           none, NONE, 0,        none, NONE, 0,       GPI), /* SDHC1 power */
+       NPCM7XX_PINCFG(254,      none, NONE, 0,           none, NONE, 0,        none, NONE, 0,       GPI), /* SDHC2 power */
+       NPCM7XX_PINCFG(255,      none, NONE, 0,           none, NONE, 0,        none, NONE, 0,       GPI), /* DACOSEL */
+};
+
+/* number, name, drv_data */
+static const struct pinctrl_pin_desc npcm7xx_pins[] = {
+       PINCTRL_PIN(0,  "GPIO0/IOX1DI"),
+       PINCTRL_PIN(1,  "GPIO1/IOX1LD"),
+       PINCTRL_PIN(2,  "GPIO2/IOX1CK"),
+       PINCTRL_PIN(3,  "GPIO3/IOX1D0"),
+       PINCTRL_PIN(4,  "GPIO4/IOX2DI/SMB1DSDA"),
+       PINCTRL_PIN(5,  "GPIO5/IOX2LD/SMB1DSCL"),
+       PINCTRL_PIN(6,  "GPIO6/IOX2CK/SMB2DSDA"),
+       PINCTRL_PIN(7,  "GPIO7/IOX2D0/SMB2DSCL"),
+       PINCTRL_PIN(8,  "GPIO8/LKGPO1"),
+       PINCTRL_PIN(9,  "GPIO9/LKGPO2"),
+       PINCTRL_PIN(10, "GPIO10/IOXHLD"),
+       PINCTRL_PIN(11, "GPIO11/IOXHCK"),
+       PINCTRL_PIN(12, "GPIO12/GSPICK/SMB5BSCL"),
+       PINCTRL_PIN(13, "GPIO13/GSPIDO/SMB5BSDA"),
+       PINCTRL_PIN(14, "GPIO14/GSPIDI/SMB5CSCL"),
+       PINCTRL_PIN(15, "GPIO15/GSPICS/SMB5CSDA"),
+       PINCTRL_PIN(16, "GPIO16/LKGPO0"),
+       PINCTRL_PIN(17, "GPIO17/PSPI2DI/SMB4DEN"),
+       PINCTRL_PIN(18, "GPIO18/PSPI2D0/SMB4BSDA"),
+       PINCTRL_PIN(19, "GPIO19/PSPI2CK/SMB4BSCL"),
+       PINCTRL_PIN(20, "GPIO20/SMB4CSDA/SMB15SDA"),
+       PINCTRL_PIN(21, "GPIO21/SMB4CSCL/SMB15SCL"),
+       PINCTRL_PIN(22, "GPIO22/SMB4DSDA/SMB14SDA"),
+       PINCTRL_PIN(23, "GPIO23/SMB4DSCL/SMB14SCL"),
+       PINCTRL_PIN(24, "GPIO24/IOXHDO"),
+       PINCTRL_PIN(25, "GPIO25/IOXHDI"),
+       PINCTRL_PIN(26, "GPIO26/SMB5SDA"),
+       PINCTRL_PIN(27, "GPIO27/SMB5SCL"),
+       PINCTRL_PIN(28, "GPIO28/SMB4SDA"),
+       PINCTRL_PIN(29, "GPIO29/SMB4SCL"),
+       PINCTRL_PIN(30, "GPIO30/SMB3SDA"),
+       PINCTRL_PIN(31, "GPIO31/SMB3SCL"),
+
+       PINCTRL_PIN(32, "GPIO32/nSPI0CS1"),
+       PINCTRL_PIN(33, "SPI0D2"),
+       PINCTRL_PIN(34, "SPI0D3"),
+       PINCTRL_PIN(37, "GPIO37/SMB3CSDA"),
+       PINCTRL_PIN(38, "GPIO38/SMB3CSCL"),
+       PINCTRL_PIN(39, "GPIO39/SMB3BSDA"),
+       PINCTRL_PIN(40, "GPIO40/SMB3BSCL"),
+       PINCTRL_PIN(41, "GPIO41/BSPRXD"),
+       PINCTRL_PIN(42, "GPO42/BSPTXD/STRAP11"),
+       PINCTRL_PIN(43, "GPIO43/RXD1/JTMS2/BU1RXD"),
+       PINCTRL_PIN(44, "GPIO44/nCTS1/JTDI2/BU1CTS"),
+       PINCTRL_PIN(45, "GPIO45/nDCD1/JTDO2"),
+       PINCTRL_PIN(46, "GPIO46/nDSR1/JTCK2"),
+       PINCTRL_PIN(47, "GPIO47/nRI1/JCP_RDY2"),
+       PINCTRL_PIN(48, "GPIO48/TXD2/BSPTXD"),
+       PINCTRL_PIN(49, "GPIO49/RXD2/BSPRXD"),
+       PINCTRL_PIN(50, "GPIO50/nCTS2"),
+       PINCTRL_PIN(51, "GPO51/nRTS2/STRAP2"),
+       PINCTRL_PIN(52, "GPIO52/nDCD2"),
+       PINCTRL_PIN(53, "GPO53/nDTR2_BOUT2/STRAP1"),
+       PINCTRL_PIN(54, "GPIO54/nDSR2"),
+       PINCTRL_PIN(55, "GPIO55/nRI2"),
+       PINCTRL_PIN(56, "GPIO56/R1RXERR"),
+       PINCTRL_PIN(57, "GPIO57/R1MDC"),
+       PINCTRL_PIN(58, "GPIO58/R1MDIO"),
+       PINCTRL_PIN(59, "GPIO59/SMB3DSDA"),
+       PINCTRL_PIN(60, "GPIO60/SMB3DSCL"),
+       PINCTRL_PIN(61, "GPO61/nDTR1_BOUT1/STRAP6"),
+       PINCTRL_PIN(62, "GPO62/nRTST1/STRAP5"),
+       PINCTRL_PIN(63, "GPO63/TXD1/STRAP4"),
+
+       PINCTRL_PIN(64, "GPIO64/FANIN0"),
+       PINCTRL_PIN(65, "GPIO65/FANIN1"),
+       PINCTRL_PIN(66, "GPIO66/FANIN2"),
+       PINCTRL_PIN(67, "GPIO67/FANIN3"),
+       PINCTRL_PIN(68, "GPIO68/FANIN4"),
+       PINCTRL_PIN(69, "GPIO69/FANIN5"),
+       PINCTRL_PIN(70, "GPIO70/FANIN6"),
+       PINCTRL_PIN(71, "GPIO71/FANIN7"),
+       PINCTRL_PIN(72, "GPIO72/FANIN8"),
+       PINCTRL_PIN(73, "GPIO73/FANIN9"),
+       PINCTRL_PIN(74, "GPIO74/FANIN10"),
+       PINCTRL_PIN(75, "GPIO75/FANIN11"),
+       PINCTRL_PIN(76, "GPIO76/FANIN12"),
+       PINCTRL_PIN(77, "GPIO77/FANIN13"),
+       PINCTRL_PIN(78, "GPIO78/FANIN14"),
+       PINCTRL_PIN(79, "GPIO79/FANIN15"),
+       PINCTRL_PIN(80, "GPIO80/PWM0"),
+       PINCTRL_PIN(81, "GPIO81/PWM1"),
+       PINCTRL_PIN(82, "GPIO82/PWM2"),
+       PINCTRL_PIN(83, "GPIO83/PWM3"),
+       PINCTRL_PIN(84, "GPIO84/R2TXD0"),
+       PINCTRL_PIN(85, "GPIO85/R2TXD1"),
+       PINCTRL_PIN(86, "GPIO86/R2TXEN"),
+       PINCTRL_PIN(87, "GPIO87/R2RXD0"),
+       PINCTRL_PIN(88, "GPIO88/R2RXD1"),
+       PINCTRL_PIN(89, "GPIO89/R2CRSDV"),
+       PINCTRL_PIN(90, "GPIO90/R2RXERR"),
+       PINCTRL_PIN(91, "GPIO91/R2MDC"),
+       PINCTRL_PIN(92, "GPIO92/R2MDIO"),
+       PINCTRL_PIN(93, "GPIO93/GA20/SMB5DSCL"),
+       PINCTRL_PIN(94, "GPIO94/nKBRST/SMB5DSDA"),
+       PINCTRL_PIN(95, "GPIO95/nLRESET/nESPIRST"),
+
+       PINCTRL_PIN(96, "GPIO96/RG1TXD0"),
+       PINCTRL_PIN(97, "GPIO97/RG1TXD1"),
+       PINCTRL_PIN(98, "GPIO98/RG1TXD2"),
+       PINCTRL_PIN(99, "GPIO99/RG1TXD3"),
+       PINCTRL_PIN(100, "GPIO100/RG1TXC"),
+       PINCTRL_PIN(101, "GPIO101/RG1TXCTL"),
+       PINCTRL_PIN(102, "GPIO102/RG1RXD0"),
+       PINCTRL_PIN(103, "GPIO103/RG1RXD1"),
+       PINCTRL_PIN(104, "GPIO104/RG1RXD2"),
+       PINCTRL_PIN(105, "GPIO105/RG1RXD3"),
+       PINCTRL_PIN(106, "GPIO106/RG1RXC"),
+       PINCTRL_PIN(107, "GPIO107/RG1RXCTL"),
+       PINCTRL_PIN(108, "GPIO108/RG1MDC"),
+       PINCTRL_PIN(109, "GPIO109/RG1MDIO"),
+       PINCTRL_PIN(110, "GPIO110/RG2TXD0/DDRV0"),
+       PINCTRL_PIN(111, "GPIO111/RG2TXD1/DDRV1"),
+       PINCTRL_PIN(112, "GPIO112/RG2TXD2/DDRV2"),
+       PINCTRL_PIN(113, "GPIO113/RG2TXD3/DDRV3"),
+       PINCTRL_PIN(114, "GPIO114/SMB0SCL"),
+       PINCTRL_PIN(115, "GPIO115/SMB0SDA"),
+       PINCTRL_PIN(116, "GPIO116/SMB1SCL"),
+       PINCTRL_PIN(117, "GPIO117/SMB1SDA"),
+       PINCTRL_PIN(118, "GPIO118/SMB2SCL"),
+       PINCTRL_PIN(119, "GPIO119/SMB2SDA"),
+       PINCTRL_PIN(120, "GPIO120/SMB2CSDA"),
+       PINCTRL_PIN(121, "GPIO121/SMB2CSCL"),
+       PINCTRL_PIN(122, "GPIO122/SMB2BSDA"),
+       PINCTRL_PIN(123, "GPIO123/SMB2BSCL"),
+       PINCTRL_PIN(124, "GPIO124/SMB1CSDA"),
+       PINCTRL_PIN(125, "GPIO125/SMB1CSCL"),
+       PINCTRL_PIN(126, "GPIO126/SMB1BSDA"),
+       PINCTRL_PIN(127, "GPIO127/SMB1BSCL"),
+
+       PINCTRL_PIN(128, "GPIO128/SMB8SCL"),
+       PINCTRL_PIN(129, "GPIO129/SMB8SDA"),
+       PINCTRL_PIN(130, "GPIO130/SMB9SCL"),
+       PINCTRL_PIN(131, "GPIO131/SMB9SDA"),
+       PINCTRL_PIN(132, "GPIO132/SMB10SCL"),
+       PINCTRL_PIN(133, "GPIO133/SMB10SDA"),
+       PINCTRL_PIN(134, "GPIO134/SMB11SCL"),
+       PINCTRL_PIN(135, "GPIO135/SMB11SDA"),
+       PINCTRL_PIN(136, "GPIO136/SD1DT0"),
+       PINCTRL_PIN(137, "GPIO137/SD1DT1"),
+       PINCTRL_PIN(138, "GPIO138/SD1DT2"),
+       PINCTRL_PIN(139, "GPIO139/SD1DT3"),
+       PINCTRL_PIN(140, "GPIO140/SD1CLK"),
+       PINCTRL_PIN(141, "GPIO141/SD1WP"),
+       PINCTRL_PIN(142, "GPIO142/SD1CMD"),
+       PINCTRL_PIN(143, "GPIO143/SD1CD/SD1PWR"),
+       PINCTRL_PIN(144, "GPIO144/PWM4"),
+       PINCTRL_PIN(145, "GPIO145/PWM5"),
+       PINCTRL_PIN(146, "GPIO146/PWM6"),
+       PINCTRL_PIN(147, "GPIO147/PWM7"),
+       PINCTRL_PIN(148, "GPIO148/MMCDT4"),
+       PINCTRL_PIN(149, "GPIO149/MMCDT5"),
+       PINCTRL_PIN(150, "GPIO150/MMCDT6"),
+       PINCTRL_PIN(151, "GPIO151/MMCDT7"),
+       PINCTRL_PIN(152, "GPIO152/MMCCLK"),
+       PINCTRL_PIN(153, "GPIO153/MMCWP"),
+       PINCTRL_PIN(154, "GPIO154/MMCCMD"),
+       PINCTRL_PIN(155, "GPIO155/nMMCCD/nMMCRST"),
+       PINCTRL_PIN(156, "GPIO156/MMCDT0"),
+       PINCTRL_PIN(157, "GPIO157/MMCDT1"),
+       PINCTRL_PIN(158, "GPIO158/MMCDT2"),
+       PINCTRL_PIN(159, "GPIO159/MMCDT3"),
+
+       PINCTRL_PIN(160, "GPIO160/CLKOUT/RNGOSCOUT"),
+       PINCTRL_PIN(161, "GPIO161/nLFRAME/nESPICS"),
+       PINCTRL_PIN(162, "GPIO162/SERIRQ"),
+       PINCTRL_PIN(163, "GPIO163/LCLK/ESPICLK"),
+       PINCTRL_PIN(164, "GPIO164/LAD0/ESPI_IO0"/*dscnt6*/),
+       PINCTRL_PIN(165, "GPIO165/LAD1/ESPI_IO1"/*dscnt6*/),
+       PINCTRL_PIN(166, "GPIO166/LAD2/ESPI_IO2"/*dscnt6*/),
+       PINCTRL_PIN(167, "GPIO167/LAD3/ESPI_IO3"/*dscnt6*/),
+       PINCTRL_PIN(168, "GPIO168/nCLKRUN/nESPIALERT"),
+       PINCTRL_PIN(169, "GPIO169/nSCIPME"),
+       PINCTRL_PIN(170, "GPIO170/nSMI"),
+       PINCTRL_PIN(171, "GPIO171/SMB6SCL"),
+       PINCTRL_PIN(172, "GPIO172/SMB6SDA"),
+       PINCTRL_PIN(173, "GPIO173/SMB7SCL"),
+       PINCTRL_PIN(174, "GPIO174/SMB7SDA"),
+       PINCTRL_PIN(175, "GPIO175/PSPI1CK/FANIN19"),
+       PINCTRL_PIN(176, "GPIO176/PSPI1DO/FANIN18"),
+       PINCTRL_PIN(177, "GPIO177/PSPI1DI/FANIN17"),
+       PINCTRL_PIN(178, "GPIO178/R1TXD0"),
+       PINCTRL_PIN(179, "GPIO179/R1TXD1"),
+       PINCTRL_PIN(180, "GPIO180/R1TXEN"),
+       PINCTRL_PIN(181, "GPIO181/R1RXD0"),
+       PINCTRL_PIN(182, "GPIO182/R1RXD1"),
+       PINCTRL_PIN(183, "GPIO183/SPI3CK"),
+       PINCTRL_PIN(184, "GPO184/SPI3D0/STRAP9"),
+       PINCTRL_PIN(185, "GPO185/SPI3D1/STRAP10"),
+       PINCTRL_PIN(186, "GPIO186/nSPI3CS0"),
+       PINCTRL_PIN(187, "GPIO187/nSPI3CS1"),
+       PINCTRL_PIN(188, "GPIO188/SPI3D2/nSPI3CS2"),
+       PINCTRL_PIN(189, "GPIO189/SPI3D3/nSPI3CS3"),
+       PINCTRL_PIN(190, "GPIO190/nPRD_SMI"),
+       PINCTRL_PIN(191, "GPIO191"),
+
+       PINCTRL_PIN(192, "GPIO192"),
+       PINCTRL_PIN(193, "GPIO193/R1CRSDV"),
+       PINCTRL_PIN(194, "GPIO194/SMB0BSCL"),
+       PINCTRL_PIN(195, "GPIO195/SMB0BSDA"),
+       PINCTRL_PIN(196, "GPIO196/SMB0CSCL"),
+       PINCTRL_PIN(197, "GPIO197/SMB0DEN"),
+       PINCTRL_PIN(198, "GPIO198/SMB0DSDA"),
+       PINCTRL_PIN(199, "GPIO199/SMB0DSCL"),
+       PINCTRL_PIN(200, "GPIO200/R2CK"),
+       PINCTRL_PIN(201, "GPIO201/R1CK"),
+       PINCTRL_PIN(202, "GPIO202/SMB0CSDA"),
+       PINCTRL_PIN(203, "GPIO203/FANIN16"),
+       PINCTRL_PIN(204, "GPIO204/DDC2SCL"),
+       PINCTRL_PIN(205, "GPIO205/DDC2SDA"),
+       PINCTRL_PIN(206, "GPIO206/HSYNC2"),
+       PINCTRL_PIN(207, "GPIO207/VSYNC2"),
+       PINCTRL_PIN(208, "GPIO208/RG2TXC/DVCK"),
+       PINCTRL_PIN(209, "GPIO209/RG2TXCTL/DDRV4"),
+       PINCTRL_PIN(210, "GPIO210/RG2RXD0/DDRV5"),
+       PINCTRL_PIN(211, "GPIO211/RG2RXD1/DDRV6"),
+       PINCTRL_PIN(212, "GPIO212/RG2RXD2/DDRV7"),
+       PINCTRL_PIN(213, "GPIO213/RG2RXD3/DDRV8"),
+       PINCTRL_PIN(214, "GPIO214/RG2RXC/DDRV9"),
+       PINCTRL_PIN(215, "GPIO215/RG2RXCTL/DDRV10"),
+       PINCTRL_PIN(216, "GPIO216/RG2MDC/DDRV11"),
+       PINCTRL_PIN(217, "GPIO217/RG2MDIO/DVHSYNC"),
+       PINCTRL_PIN(218, "GPIO218/nWDO1"),
+       PINCTRL_PIN(219, "GPIO219/nWDO2"),
+       PINCTRL_PIN(220, "GPIO220/SMB12SCL"),
+       PINCTRL_PIN(221, "GPIO221/SMB12SDA"),
+       PINCTRL_PIN(222, "GPIO222/SMB13SCL"),
+       PINCTRL_PIN(223, "GPIO223/SMB13SDA"),
+
+       PINCTRL_PIN(224, "GPIO224/SPIXCK"),
+       PINCTRL_PIN(225, "GPO225/SPIXD0/STRAP12"),
+       PINCTRL_PIN(226, "GPO226/SPIXD1/STRAP13"),
+       PINCTRL_PIN(227, "GPIO227/nSPIXCS0"),
+       PINCTRL_PIN(228, "GPIO228/nSPIXCS1"),
+       PINCTRL_PIN(229, "GPO229/SPIXD2/STRAP3"),
+       PINCTRL_PIN(230, "GPIO230/SPIXD3"),
+       PINCTRL_PIN(231, "GPIO231/nCLKREQ"),
+       PINCTRL_PIN(255, "GPI255/DACOSEL"),
+};
+
+/* Enable mode in pin group */
+static void npcm7xx_setfunc(struct regmap *gcr_regmap, const unsigned int *pin,
+                           int pin_number, int mode)
+{
+       const struct npcm7xx_pincfg *cfg;
+       int i;
+
+       for (i = 0 ; i < pin_number ; i++) {
+               cfg = &pincfg[pin[i]];
+               if (mode == fn_gpio || cfg->fn0 == mode || cfg->fn1 == mode || cfg->fn2 == mode) {
+                       if (cfg->reg0)
+                               regmap_update_bits(gcr_regmap, cfg->reg0,
+                                                  BIT(cfg->bit0),
+                                                  !!(cfg->fn0 == mode) ?
+                                                  BIT(cfg->bit0) : 0);
+                       if (cfg->reg1)
+                               regmap_update_bits(gcr_regmap, cfg->reg1,
+                                                  BIT(cfg->bit1),
+                                                  !!(cfg->fn1 == mode) ?
+                                                  BIT(cfg->bit1) : 0);
+                       if (cfg->reg2)
+                               regmap_update_bits(gcr_regmap, cfg->reg2,
+                                                  BIT(cfg->bit2),
+                                                  !!(cfg->fn2 == mode) ?
+                                                  BIT(cfg->bit2) : 0);
+               }
+       }
+}
+
+/* Get slew rate of pin (high/low) */
+static int npcm7xx_get_slew_rate(struct npcm7xx_gpio *bank,
+                                struct regmap *gcr_regmap, unsigned int pin)
+{
+       u32 val;
+       int gpio = (pin % bank->gc.ngpio);
+       unsigned long pinmask = BIT(gpio);
+
+       if (pincfg[pin].flag & SLEW)
+               return ioread32(bank->base + NPCM7XX_GP_N_OSRC)
+               & pinmask;
+       /* LPC Slew rate in SRCNT register */
+       if (pincfg[pin].flag & SLEWLPC) {
+               regmap_read(gcr_regmap, NPCM7XX_GCR_SRCNT, &val);
+               return !!(val & SRCNT_ESPI);
+       }
+
+       return -EINVAL;
+}
+
+/* Set slew rate of pin (high/low) */
+static int npcm7xx_set_slew_rate(struct npcm7xx_gpio *bank,
+                                struct regmap *gcr_regmap, unsigned int pin,
+                                int arg)
+{
+       int gpio = BIT(pin % bank->gc.ngpio);
+
+       if (pincfg[pin].flag & SLEW) {
+               switch (arg) {
+               case 0:
+                       npcm_gpio_clr(&bank->gc, bank->base + NPCM7XX_GP_N_OSRC,
+                                     gpio);
+                       return 0;
+               case 1:
+                       npcm_gpio_set(&bank->gc, bank->base + NPCM7XX_GP_N_OSRC,
+                                     gpio);
+                       return 0;
+               default:
+                       return -EINVAL;
+               }
+       }
+       /* LPC Slew rate in SRCNT register */
+       if (pincfg[pin].flag & SLEWLPC) {
+               switch (arg) {
+               case 0:
+                       regmap_update_bits(gcr_regmap, NPCM7XX_GCR_SRCNT,
+                                          SRCNT_ESPI, 0);
+                       return 0;
+               case 1:
+                       regmap_update_bits(gcr_regmap, NPCM7XX_GCR_SRCNT,
+                                          SRCNT_ESPI, SRCNT_ESPI);
+                       return 0;
+               default:
+                       return -EINVAL;
+               }
+       }
+
+       return -EINVAL;
+}
+
+/* Get drive strength for a pin, if supported */
+static int npcm7xx_get_drive_strength(struct pinctrl_dev *pctldev,
+                                     unsigned int pin)
+{
+       struct npcm7xx_pinctrl *npcm = pinctrl_dev_get_drvdata(pctldev);
+       struct npcm7xx_gpio *bank =
+               &npcm->gpio_bank[pin / NPCM7XX_GPIO_PER_BANK];
+       int gpio = (pin % bank->gc.ngpio);
+       unsigned long pinmask = BIT(gpio);
+       u32 ds = 0;
+       int flg, val;
+
+       flg = pincfg[pin].flag;
+       if (flg & DRIVE_STRENGTH_MASK) {
+               /* Get standard reading */
+               val = ioread32(bank->base + NPCM7XX_GP_N_ODSC)
+               & pinmask;
+               ds = val ? DSHI(flg) : DSLO(flg);
+               dev_dbg(bank->gc.parent,
+                       "pin %d strength %d = %d\n", pin, val, ds);
+               return ds;
+       }
+
+       return -EINVAL;
+}
+
+/* Set drive strength for a pin, if supported */
+static int npcm7xx_set_drive_strength(struct npcm7xx_pinctrl *npcm,
+                                     unsigned int pin, int nval)
+{
+       int v;
+       struct npcm7xx_gpio *bank =
+               &npcm->gpio_bank[pin / NPCM7XX_GPIO_PER_BANK];
+       int gpio = BIT(pin % bank->gc.ngpio);
+
+       v = (pincfg[pin].flag & DRIVE_STRENGTH_MASK);
+       if (!nval || !v)
+               return -ENOTSUPP;
+       if (DSLO(v) == nval) {
+               dev_dbg(bank->gc.parent,
+                       "setting pin %d to low strength [%d]\n", pin, nval);
+               npcm_gpio_clr(&bank->gc, bank->base + NPCM7XX_GP_N_ODSC, gpio);
+               return 0;
+       } else if (DSHI(v) == nval) {
+               dev_dbg(bank->gc.parent,
+                       "setting pin %d to high strength [%d]\n", pin, nval);
+               npcm_gpio_set(&bank->gc, bank->base + NPCM7XX_GP_N_ODSC, gpio);
+               return 0;
+       }
+
+       return -ENOTSUPP;
+}
+
+/* pinctrl_ops */
+static void npcm7xx_pin_dbg_show(struct pinctrl_dev *pctldev,
+                                struct seq_file *s, unsigned int offset)
+{
+       seq_printf(s, "pinctrl_ops.dbg: %d", offset);
+}
+
+static int npcm7xx_get_groups_count(struct pinctrl_dev *pctldev)
+{
+       struct npcm7xx_pinctrl *npcm = pinctrl_dev_get_drvdata(pctldev);
+
+       dev_dbg(npcm->dev, "group size: %d\n", ARRAY_SIZE(npcm7xx_groups));
+       return ARRAY_SIZE(npcm7xx_groups);
+}
+
+static const char *npcm7xx_get_group_name(struct pinctrl_dev *pctldev,
+                                         unsigned int selector)
+{
+       return npcm7xx_groups[selector].name;
+}
+
+static int npcm7xx_get_group_pins(struct pinctrl_dev *pctldev,
+                                 unsigned int selector,
+                                 const unsigned int **pins,
+                                 unsigned int *npins)
+{
+       *npins = npcm7xx_groups[selector].npins;
+       *pins  = npcm7xx_groups[selector].pins;
+
+       return 0;
+}
+
+static int npcm7xx_dt_node_to_map(struct pinctrl_dev *pctldev,
+                                 struct device_node *np_config,
+                                 struct pinctrl_map **map,
+                                 u32 *num_maps)
+{
+       struct npcm7xx_pinctrl *npcm = pinctrl_dev_get_drvdata(pctldev);
+
+       dev_dbg(npcm->dev, "dt_node_to_map: %s\n", np_config->name);
+       return pinconf_generic_dt_node_to_map(pctldev, np_config,
+                                             map, num_maps,
+                                             PIN_MAP_TYPE_INVALID);
+}
+
+static void npcm7xx_dt_free_map(struct pinctrl_dev *pctldev,
+                               struct pinctrl_map *map, u32 num_maps)
+{
+       kfree(map);
+}
+
+static struct pinctrl_ops npcm7xx_pinctrl_ops = {
+       .get_groups_count = npcm7xx_get_groups_count,
+       .get_group_name = npcm7xx_get_group_name,
+       .get_group_pins = npcm7xx_get_group_pins,
+       .pin_dbg_show = npcm7xx_pin_dbg_show,
+       .dt_node_to_map = npcm7xx_dt_node_to_map,
+       .dt_free_map = npcm7xx_dt_free_map,
+};
+
+/* pinmux_ops  */
+static int npcm7xx_get_functions_count(struct pinctrl_dev *pctldev)
+{
+       return ARRAY_SIZE(npcm7xx_funcs);
+}
+
+static const char *npcm7xx_get_function_name(struct pinctrl_dev *pctldev,
+                                            unsigned int function)
+{
+       return npcm7xx_funcs[function].name;
+}
+
+static int npcm7xx_get_function_groups(struct pinctrl_dev *pctldev,
+                                      unsigned int function,
+                                      const char * const **groups,
+                                      unsigned int * const ngroups)
+{
+       *ngroups = npcm7xx_funcs[function].ngroups;
+       *groups  = npcm7xx_funcs[function].groups;
+
+       return 0;
+}
+
+static int npcm7xx_pinmux_set_mux(struct pinctrl_dev *pctldev,
+                                 unsigned int function,
+                                 unsigned int group)
+{
+       struct npcm7xx_pinctrl *npcm = pinctrl_dev_get_drvdata(pctldev);
+
+       dev_dbg(npcm->dev, "set_mux: %d, %d[%s]\n", function, group,
+               npcm7xx_groups[group].name);
+
+       npcm7xx_setfunc(npcm->gcr_regmap, npcm7xx_groups[group].pins,
+                       npcm7xx_groups[group].npins, group);
+
+       return 0;
+}
+
+static int npcm7xx_gpio_request_enable(struct pinctrl_dev *pctldev,
+                                      struct pinctrl_gpio_range *range,
+                                      unsigned int offset)
+{
+       struct npcm7xx_pinctrl *npcm = pinctrl_dev_get_drvdata(pctldev);
+
+       if (!range) {
+               dev_err(npcm->dev, "invalid range\n");
+               return -EINVAL;
+       }
+       if (!range->gc) {
+               dev_err(npcm->dev, "invalid gpiochip\n");
+               return -EINVAL;
+       }
+
+       npcm7xx_setfunc(npcm->gcr_regmap, &offset, 1, fn_gpio);
+
+       return 0;
+}
+
+/* Release GPIO back to pinctrl mode */
+static void npcm7xx_gpio_request_free(struct pinctrl_dev *pctldev,
+                                     struct pinctrl_gpio_range *range,
+                                     unsigned int offset)
+{
+       struct npcm7xx_pinctrl *npcm = pinctrl_dev_get_drvdata(pctldev);
+       int virq;
+
+       virq = irq_find_mapping(npcm->domain, offset);
+       if (virq)
+               irq_dispose_mapping(virq);
+}
+
+/* Set GPIO direction */
+static int npcm_gpio_set_direction(struct pinctrl_dev *pctldev,
+                                  struct pinctrl_gpio_range *range,
+                                  unsigned int offset, bool input)
+{
+       struct npcm7xx_pinctrl *npcm = pinctrl_dev_get_drvdata(pctldev);
+       struct npcm7xx_gpio *bank =
+               &npcm->gpio_bank[offset / NPCM7XX_GPIO_PER_BANK];
+       int gpio = BIT(offset % bank->gc.ngpio);
+
+       dev_dbg(bank->gc.parent, "GPIO Set Direction: %d = %d\n", offset,
+               input);
+       if (input)
+               iowrite32(gpio, bank->base + NPCM7XX_GP_N_OEC);
+       else
+               iowrite32(gpio, bank->base + NPCM7XX_GP_N_OES);
+
+       return 0;
+}
+
+static struct pinmux_ops npcm7xx_pinmux_ops = {
+       .get_functions_count = npcm7xx_get_functions_count,
+       .get_function_name = npcm7xx_get_function_name,
+       .get_function_groups = npcm7xx_get_function_groups,
+       .set_mux = npcm7xx_pinmux_set_mux,
+       .gpio_request_enable = npcm7xx_gpio_request_enable,
+       .gpio_disable_free = npcm7xx_gpio_request_free,
+       .gpio_set_direction = npcm_gpio_set_direction,
+};
+
+/* pinconf_ops */
+static int npcm7xx_config_get(struct pinctrl_dev *pctldev, unsigned int pin,
+                             unsigned long *config)
+{
+       enum pin_config_param param = pinconf_to_config_param(*config);
+       struct npcm7xx_pinctrl *npcm = pinctrl_dev_get_drvdata(pctldev);
+       struct npcm7xx_gpio *bank =
+               &npcm->gpio_bank[pin / NPCM7XX_GPIO_PER_BANK];
+       int gpio = (pin % bank->gc.ngpio);
+       unsigned long pinmask = BIT(gpio);
+       u32 ie, oe, pu, pd;
+       int rc = 0;
+
+       switch (param) {
+       case PIN_CONFIG_BIAS_DISABLE:
+       case PIN_CONFIG_BIAS_PULL_UP:
+       case PIN_CONFIG_BIAS_PULL_DOWN:
+               pu = ioread32(bank->base + NPCM7XX_GP_N_PU) & pinmask;
+               pd = ioread32(bank->base + NPCM7XX_GP_N_PD) & pinmask;
+               if (param == PIN_CONFIG_BIAS_DISABLE)
+                       rc = (!pu && !pd);
+               else if (param == PIN_CONFIG_BIAS_PULL_UP)
+                       rc = (pu && !pd);
+               else if (param == PIN_CONFIG_BIAS_PULL_DOWN)
+                       rc = (!pu && pd);
+               break;
+       case PIN_CONFIG_OUTPUT:
+       case PIN_CONFIG_INPUT_ENABLE:
+               ie = ioread32(bank->base + NPCM7XX_GP_N_IEM) & pinmask;
+               oe = ioread32(bank->base + NPCM7XX_GP_N_OE) & pinmask;
+               if (param == PIN_CONFIG_INPUT_ENABLE)
+                       rc = (ie && !oe);
+               else if (param == PIN_CONFIG_OUTPUT)
+                       rc = (!ie && oe);
+               break;
+       case PIN_CONFIG_DRIVE_PUSH_PULL:
+               rc = !(ioread32(bank->base + NPCM7XX_GP_N_OTYP) & pinmask);
+               break;
+       case PIN_CONFIG_DRIVE_OPEN_DRAIN:
+               rc = ioread32(bank->base + NPCM7XX_GP_N_OTYP) & pinmask;
+               break;
+       case PIN_CONFIG_INPUT_DEBOUNCE:
+               rc = ioread32(bank->base + NPCM7XX_GP_N_DBNC) & pinmask;
+               break;
+       case PIN_CONFIG_DRIVE_STRENGTH:
+               rc = npcm7xx_get_drive_strength(pctldev, pin);
+               if (rc)
+                       *config = pinconf_to_config_packed(param, rc);
+               break;
+       case PIN_CONFIG_SLEW_RATE:
+               rc = npcm7xx_get_slew_rate(bank, npcm->gcr_regmap, pin);
+               if (rc >= 0)
+                       *config = pinconf_to_config_packed(param, rc);
+               break;
+       default:
+               return -ENOTSUPP;
+       }
+
+       if (!rc)
+               return -EINVAL;
+
+       return 0;
+}
+
+static int npcm7xx_config_set_one(struct npcm7xx_pinctrl *npcm,
+                                 unsigned int pin, unsigned long config)
+{
+       enum pin_config_param param = pinconf_to_config_param(config);
+       u16 arg = pinconf_to_config_argument(config);
+       struct npcm7xx_gpio *bank =
+               &npcm->gpio_bank[pin / NPCM7XX_GPIO_PER_BANK];
+       int gpio = BIT(pin % bank->gc.ngpio);
+
+       dev_dbg(bank->gc.parent, "param=%d %d[GPIO]\n", param, pin);
+       switch (param) {
+       case PIN_CONFIG_BIAS_DISABLE:
+               npcm_gpio_clr(&bank->gc, bank->base + NPCM7XX_GP_N_PU, gpio);
+               npcm_gpio_clr(&bank->gc, bank->base + NPCM7XX_GP_N_PD, gpio);
+               break;
+       case PIN_CONFIG_BIAS_PULL_DOWN:
+               npcm_gpio_clr(&bank->gc, bank->base + NPCM7XX_GP_N_PU, gpio);
+               npcm_gpio_set(&bank->gc, bank->base + NPCM7XX_GP_N_PD, gpio);
+               break;
+       case PIN_CONFIG_BIAS_PULL_UP:
+               npcm_gpio_clr(&bank->gc, bank->base + NPCM7XX_GP_N_PD, gpio);
+               npcm_gpio_set(&bank->gc, bank->base + NPCM7XX_GP_N_PU, gpio);
+               break;
+       case PIN_CONFIG_INPUT_ENABLE:
+               if (arg) {
+                       iowrite32(gpio, bank->base + NPCM7XX_GP_N_OEC);
+                       npcm_gpio_set(&bank->gc, bank->base + NPCM7XX_GP_N_IEM,
+                                     gpio);
+               } else
+                       npcm_gpio_clr(&bank->gc, bank->base + NPCM7XX_GP_N_IEM,
+                                     gpio);
+               break;
+       case PIN_CONFIG_OUTPUT:
+               npcm_gpio_clr(&bank->gc, bank->base + NPCM7XX_GP_N_IEM, gpio);
+               iowrite32(gpio, arg ? bank->base + NPCM7XX_GP_N_DOS :
+                         bank->base + NPCM7XX_GP_N_DOC);
+               iowrite32(gpio, bank->base + NPCM7XX_GP_N_OES);
+               break;
+       case PIN_CONFIG_DRIVE_PUSH_PULL:
+               npcm_gpio_clr(&bank->gc, bank->base + NPCM7XX_GP_N_OTYP, gpio);
+               break;
+       case PIN_CONFIG_DRIVE_OPEN_DRAIN:
+               npcm_gpio_set(&bank->gc, bank->base + NPCM7XX_GP_N_OTYP, gpio);
+               break;
+       case PIN_CONFIG_INPUT_DEBOUNCE:
+               npcm_gpio_set(&bank->gc, bank->base + NPCM7XX_GP_N_DBNC, gpio);
+               break;
+       case PIN_CONFIG_SLEW_RATE:
+               return npcm7xx_set_slew_rate(bank, npcm->gcr_regmap, pin, arg);
+       case PIN_CONFIG_DRIVE_STRENGTH:
+               return npcm7xx_set_drive_strength(npcm, pin, arg);
+       default:
+               return -ENOTSUPP;
+       }
+
+       return 0;
+}
+
+/* Set multiple configuration settings for a pin */
+static int npcm7xx_config_set(struct pinctrl_dev *pctldev, unsigned int pin,
+                             unsigned long *configs, unsigned int num_configs)
+{
+       struct npcm7xx_pinctrl *npcm = pinctrl_dev_get_drvdata(pctldev);
+       int rc;
+
+       while (num_configs--) {
+               rc = npcm7xx_config_set_one(npcm, pin, *configs++);
+               if (rc)
+                       return rc;
+       }
+
+       return 0;
+}
+
+static struct pinconf_ops npcm7xx_pinconf_ops = {
+       .is_generic = true,
+       .pin_config_get = npcm7xx_config_get,
+       .pin_config_set = npcm7xx_config_set,
+};
+
+/* pinctrl_desc */
+static struct pinctrl_desc npcm7xx_pinctrl_desc = {
+       .name = "npcm7xx-pinctrl",
+       .pins = npcm7xx_pins,
+       .npins = ARRAY_SIZE(npcm7xx_pins),
+       .pctlops = &npcm7xx_pinctrl_ops,
+       .pmxops = &npcm7xx_pinmux_ops,
+       .confops = &npcm7xx_pinconf_ops,
+       .owner = THIS_MODULE,
+};
+
+static int npcm7xx_gpio_of(struct npcm7xx_pinctrl *pctrl)
+{
+       int ret = -ENXIO;
+       struct resource res;
+       int id = 0, irq;
+       struct device_node *np;
+       struct of_phandle_args pinspec;
+
+       for_each_available_child_of_node(pctrl->dev->of_node, np)
+               if (of_find_property(np, "gpio-controller", NULL)) {
+                       ret = of_address_to_resource(np, 0, &res);
+                       if (ret < 0) {
+                               dev_err(pctrl->dev,
+                                       "Resource fail for GPIO bank %u\n", id);
+                               return ret;
+                       }
+
+                       pctrl->gpio_bank[id].base =
+                               ioremap(res.start, resource_size(&res));
+
+                       irq = irq_of_parse_and_map(np, 0);
+                       if (irq < 0) {
+                               dev_err(pctrl->dev,
+                                       "No IRQ for GPIO bank %u\n", id);
+                               ret = irq;
+                               return ret;
+                       }
+
+                       ret = bgpio_init(&pctrl->gpio_bank[id].gc,
+                                        pctrl->dev, 4,
+                                        pctrl->gpio_bank[id].base +
+                                        NPCM7XX_GP_N_DIN,
+                                        pctrl->gpio_bank[id].base +
+                                        NPCM7XX_GP_N_DOUT,
+                                        NULL,
+                                        NULL,
+                                        pctrl->gpio_bank[id].base +
+                                        NPCM7XX_GP_N_IEM,
+                                        BGPIOF_READ_OUTPUT_REG_SET);
+                       if (ret) {
+                               dev_err(pctrl->dev, "bgpio_init() failed\n");
+                               return ret;
+                       }
+
+                       ret = of_parse_phandle_with_fixed_args(np,
+                                                              "gpio-ranges", 3,
+                                                              0, &pinspec);
+                       if (ret < 0) {
+                               dev_err(pctrl->dev,
+                                       "gpio-ranges fail for GPIO bank %u\n",
+                                       id);
+                               return ret;
+                       }
+
+                       pctrl->gpio_bank[id].irq = irq;
+                       pctrl->gpio_bank[id].irq_chip = npcmgpio_irqchip;
+                       pctrl->gpio_bank[id].gc.parent = pctrl->dev;
+                       pctrl->gpio_bank[id].irqbase =
+                               id * NPCM7XX_GPIO_PER_BANK;
+                       pctrl->gpio_bank[id].pinctrl_id = pinspec.args[0];
+                       pctrl->gpio_bank[id].gc.base = pinspec.args[1];
+                       pctrl->gpio_bank[id].gc.ngpio = pinspec.args[2];
+                       pctrl->gpio_bank[id].gc.owner = THIS_MODULE;
+                       pctrl->gpio_bank[id].gc.label =
+                               devm_kasprintf(pctrl->dev, GFP_KERNEL, "%pOF",
+                                              np);
+                       pctrl->gpio_bank[id].gc.dbg_show = npcmgpio_dbg_show;
+                       pctrl->gpio_bank[id].direction_input =
+                               pctrl->gpio_bank[id].gc.direction_input;
+                       pctrl->gpio_bank[id].gc.direction_input =
+                               npcmgpio_direction_input;
+                       pctrl->gpio_bank[id].direction_output =
+                               pctrl->gpio_bank[id].gc.direction_output;
+                       pctrl->gpio_bank[id].gc.direction_output =
+                               npcmgpio_direction_output;
+                       pctrl->gpio_bank[id].request =
+                               pctrl->gpio_bank[id].gc.request;
+                       pctrl->gpio_bank[id].gc.request = npcmgpio_gpio_request;
+                       pctrl->gpio_bank[id].gc.free = npcmgpio_gpio_free;
+                       pctrl->gpio_bank[id].gc.of_node = np;
+                       id++;
+               }
+
+       pctrl->bank_num = id;
+       return ret;
+}
+
+static int npcm7xx_gpio_register(struct npcm7xx_pinctrl *pctrl)
+{
+       int ret, id;
+
+       for (id = 0 ; id < pctrl->bank_num ; id++) {
+               ret = devm_gpiochip_add_data(pctrl->dev,
+                                            &pctrl->gpio_bank[id].gc,
+                                            &pctrl->gpio_bank[id]);
+               if (ret) {
+                       dev_err(pctrl->dev, "Failed to add GPIO chip %u\n", id);
+                       goto err_register;
+               }
+
+               ret = gpiochip_add_pin_range(&pctrl->gpio_bank[id].gc,
+                                            dev_name(pctrl->dev),
+                                            pctrl->gpio_bank[id].pinctrl_id,
+                                            pctrl->gpio_bank[id].gc.base,
+                                            pctrl->gpio_bank[id].gc.ngpio);
+               if (ret < 0) {
+                       dev_err(pctrl->dev, "Failed to add GPIO bank %u\n", id);
+                       gpiochip_remove(&pctrl->gpio_bank[id].gc);
+                       goto err_register;
+               }
+
+               ret = gpiochip_irqchip_add(&pctrl->gpio_bank[id].gc,
+                                          &pctrl->gpio_bank[id].irq_chip,
+                                          0, handle_level_irq,
+                                          IRQ_TYPE_NONE);
+               if (ret < 0) {
+                       dev_err(pctrl->dev,
+                               "Failed to add IRQ chip %u\n", id);
+                       gpiochip_remove(&pctrl->gpio_bank[id].gc);
+                       goto err_register;
+               }
+
+               gpiochip_set_chained_irqchip(&pctrl->gpio_bank[id].gc,
+                                            &pctrl->gpio_bank[id].irq_chip,
+                                            pctrl->gpio_bank[id].irq,
+                                            npcmgpio_irq_handler);
+       }
+
+       return 0;
+
+err_register:
+       for (; id > 0; id--)
+               gpiochip_remove(&pctrl->gpio_bank[id - 1].gc);
+
+       return ret;
+}
+
+static int npcm7xx_pinctrl_probe(struct platform_device *pdev)
+{
+       struct npcm7xx_pinctrl *pctrl;
+       int ret;
+
+       pctrl = devm_kzalloc(&pdev->dev, sizeof(*pctrl), GFP_KERNEL);
+       if (!pctrl)
+               return -ENOMEM;
+
+       pctrl->dev = &pdev->dev;
+       dev_set_drvdata(&pdev->dev, pctrl);
+
+       pctrl->gcr_regmap =
+               syscon_regmap_lookup_by_compatible("nuvoton,npcm750-gcr");
+       if (IS_ERR(pctrl->gcr_regmap)) {
+               dev_err(pctrl->dev, "didn't find nuvoton,npcm750-gcr\n");
+               return PTR_ERR(pctrl->gcr_regmap);
+       }
+
+       ret = npcm7xx_gpio_of(pctrl);
+       if (ret < 0) {
+               dev_err(pctrl->dev, "Failed to gpio dt-binding %u\n", ret);
+               return ret;
+       }
+
+       pctrl->pctldev = devm_pinctrl_register(&pdev->dev,
+                                              &npcm7xx_pinctrl_desc, pctrl);
+       if (IS_ERR(pctrl->pctldev)) {
+               dev_err(&pdev->dev, "Failed to register pinctrl device\n");
+               return PTR_ERR(pctrl->pctldev);
+       }
+
+       ret = npcm7xx_gpio_register(pctrl);
+       if (ret < 0) {
+               dev_err(pctrl->dev, "Failed to register gpio %u\n", ret);
+               return ret;
+       }
+
+       pr_info("NPCM7xx Pinctrl driver probed\n");
+       return 0;
+}
+
+static const struct of_device_id npcm7xx_pinctrl_match[] = {
+       { .compatible = "nuvoton,npcm750-pinctrl" },
+       { },
+};
+MODULE_DEVICE_TABLE(of, npcm7xx_pinctrl_match);
+
+static struct platform_driver npcm7xx_pinctrl_driver = {
+       .probe = npcm7xx_pinctrl_probe,
+       .driver = {
+               .name = "npcm7xx-pinctrl",
+               .of_match_table = npcm7xx_pinctrl_match,
+               .suppress_bind_attrs = true,
+       },
+};
+
+static int __init npcm7xx_pinctrl_register(void)
+{
+       return platform_driver_register(&npcm7xx_pinctrl_driver);
+}
+arch_initcall(npcm7xx_pinctrl_register);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("jordan_hargrave@dell.com");
+MODULE_AUTHOR("tomer.maimon@nuvoton.com");
+MODULE_DESCRIPTION("Nuvoton NPCM7XX Pinctrl and GPIO driver");
index 50f0ec4..cfd8239 100644 (file)
@@ -263,8 +263,8 @@ static int at91_dt_node_to_map(struct pinctrl_dev *pctldev,
         */
        grp = at91_pinctrl_find_group_by_name(info, np->name);
        if (!grp) {
-               dev_err(info->dev, "unable to find group for node %s\n",
-                       np->name);
+               dev_err(info->dev, "unable to find group for node %pOFn\n",
+                       np);
                return -EINVAL;
        }
 
@@ -1071,7 +1071,7 @@ static int at91_pinctrl_parse_groups(struct device_node *np,
        const __be32 *list;
        int i, j;
 
-       dev_dbg(info->dev, "group(%d): %s\n", index, np->name);
+       dev_dbg(info->dev, "group(%d): %pOFn\n", index, np);
 
        /* Initialise group */
        grp->name = np->name;
@@ -1122,7 +1122,7 @@ static int at91_pinctrl_parse_functions(struct device_node *np,
        static u32 grp_index;
        u32 i = 0;
 
-       dev_dbg(info->dev, "parse function(%d): %s\n", index, np->name);
+       dev_dbg(info->dev, "parse function(%d): %pOFn\n", index, np);
 
        func = &info->functions[index];
 
index 6a1b605..9782151 100644 (file)
@@ -7,10 +7,11 @@
  */
 
 #include <linux/compiler.h>
-#include <linux/gpio.h>
+#include <linux/gpio/driver.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/of_device.h>
+#include <linux/of_irq.h>
 #include <linux/of_platform.h>
 #include <linux/pinctrl/pinctrl.h>
 #include <linux/pinctrl/pinmux.h>
@@ -24,6 +25,9 @@
 #include "pinconf.h"
 #include "pinmux.h"
 
+#define GPIO_PIN       0x00
+#define GPIO_MSK       0x20
+
 #define JZ4740_GPIO_DATA       0x10
 #define JZ4740_GPIO_PULL_DIS   0x30
 #define JZ4740_GPIO_FUNC       0x40
@@ -33,7 +37,6 @@
 #define JZ4740_GPIO_FLAG       0x80
 
 #define JZ4770_GPIO_INT                0x10
-#define JZ4770_GPIO_MSK                0x20
 #define JZ4770_GPIO_PAT1       0x30
 #define JZ4770_GPIO_PAT0       0x40
 #define JZ4770_GPIO_FLAG       0x50
@@ -46,6 +49,7 @@
 
 enum jz_version {
        ID_JZ4740,
+       ID_JZ4725B,
        ID_JZ4770,
        ID_JZ4780,
 };
@@ -72,6 +76,13 @@ struct ingenic_pinctrl {
        const struct ingenic_chip_info *info;
 };
 
+struct ingenic_gpio_chip {
+       struct ingenic_pinctrl *jzpc;
+       struct gpio_chip gc;
+       struct irq_chip irq_chip;
+       unsigned int irq, reg_base;
+};
+
 static const u32 jz4740_pull_ups[4] = {
        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
 };
@@ -205,6 +216,99 @@ static const struct ingenic_chip_info jz4740_chip_info = {
        .pull_downs = jz4740_pull_downs,
 };
 
+static int jz4725b_mmc0_1bit_pins[] = { 0x48, 0x49, 0x5c, };
+static int jz4725b_mmc0_4bit_pins[] = { 0x5d, 0x5b, 0x56, };
+static int jz4725b_mmc1_1bit_pins[] = { 0x7a, 0x7b, 0x7c, };
+static int jz4725b_mmc1_4bit_pins[] = { 0x7d, 0x7e, 0x7f, };
+static int jz4725b_uart_data_pins[] = { 0x4c, 0x4d, };
+static int jz4725b_nand_cs1_pins[] = { 0x55, };
+static int jz4725b_nand_cs2_pins[] = { 0x56, };
+static int jz4725b_nand_cs3_pins[] = { 0x57, };
+static int jz4725b_nand_cs4_pins[] = { 0x58, };
+static int jz4725b_nand_cle_ale_pins[] = { 0x48, 0x49 };
+static int jz4725b_nand_fre_fwe_pins[] = { 0x5c, 0x5d };
+static int jz4725b_pwm_pwm0_pins[] = { 0x4a, };
+static int jz4725b_pwm_pwm1_pins[] = { 0x4b, };
+static int jz4725b_pwm_pwm2_pins[] = { 0x4c, };
+static int jz4725b_pwm_pwm3_pins[] = { 0x4d, };
+static int jz4725b_pwm_pwm4_pins[] = { 0x4e, };
+static int jz4725b_pwm_pwm5_pins[] = { 0x4f, };
+
+static int jz4725b_mmc0_1bit_funcs[] = { 1, 1, 1, };
+static int jz4725b_mmc0_4bit_funcs[] = { 1, 0, 1, };
+static int jz4725b_mmc1_1bit_funcs[] = { 0, 0, 0, };
+static int jz4725b_mmc1_4bit_funcs[] = { 0, 0, 0, };
+static int jz4725b_uart_data_funcs[] = { 1, 1, };
+static int jz4725b_nand_cs1_funcs[] = { 0, };
+static int jz4725b_nand_cs2_funcs[] = { 0, };
+static int jz4725b_nand_cs3_funcs[] = { 0, };
+static int jz4725b_nand_cs4_funcs[] = { 0, };
+static int jz4725b_nand_cle_ale_funcs[] = { 0, 0, };
+static int jz4725b_nand_fre_fwe_funcs[] = { 0, 0, };
+static int jz4725b_pwm_pwm0_funcs[] = { 0, };
+static int jz4725b_pwm_pwm1_funcs[] = { 0, };
+static int jz4725b_pwm_pwm2_funcs[] = { 0, };
+static int jz4725b_pwm_pwm3_funcs[] = { 0, };
+static int jz4725b_pwm_pwm4_funcs[] = { 0, };
+static int jz4725b_pwm_pwm5_funcs[] = { 0, };
+
+static const struct group_desc jz4725b_groups[] = {
+       INGENIC_PIN_GROUP("mmc0-1bit", jz4725b_mmc0_1bit),
+       INGENIC_PIN_GROUP("mmc0-4bit", jz4725b_mmc0_4bit),
+       INGENIC_PIN_GROUP("mmc1-1bit", jz4725b_mmc1_1bit),
+       INGENIC_PIN_GROUP("mmc1-4bit", jz4725b_mmc1_4bit),
+       INGENIC_PIN_GROUP("uart-data", jz4725b_uart_data),
+       INGENIC_PIN_GROUP("nand-cs1", jz4725b_nand_cs1),
+       INGENIC_PIN_GROUP("nand-cs2", jz4725b_nand_cs2),
+       INGENIC_PIN_GROUP("nand-cs3", jz4725b_nand_cs3),
+       INGENIC_PIN_GROUP("nand-cs4", jz4725b_nand_cs4),
+       INGENIC_PIN_GROUP("nand-cle-ale", jz4725b_nand_cle_ale),
+       INGENIC_PIN_GROUP("nand-fre-fwe", jz4725b_nand_fre_fwe),
+       INGENIC_PIN_GROUP("pwm0", jz4725b_pwm_pwm0),
+       INGENIC_PIN_GROUP("pwm1", jz4725b_pwm_pwm1),
+       INGENIC_PIN_GROUP("pwm2", jz4725b_pwm_pwm2),
+       INGENIC_PIN_GROUP("pwm3", jz4725b_pwm_pwm3),
+       INGENIC_PIN_GROUP("pwm4", jz4725b_pwm_pwm4),
+       INGENIC_PIN_GROUP("pwm5", jz4725b_pwm_pwm5),
+};
+
+static const char *jz4725b_mmc0_groups[] = { "mmc0-1bit", "mmc0-4bit", };
+static const char *jz4725b_mmc1_groups[] = { "mmc1-1bit", "mmc1-4bit", };
+static const char *jz4725b_uart_groups[] = { "uart-data", };
+static const char *jz4725b_nand_groups[] = {
+       "nand-cs1", "nand-cs2", "nand-cs3", "nand-cs4",
+       "nand-cle-ale", "nand-fre-fwe",
+};
+static const char *jz4725b_pwm0_groups[] = { "pwm0", };
+static const char *jz4725b_pwm1_groups[] = { "pwm1", };
+static const char *jz4725b_pwm2_groups[] = { "pwm2", };
+static const char *jz4725b_pwm3_groups[] = { "pwm3", };
+static const char *jz4725b_pwm4_groups[] = { "pwm4", };
+static const char *jz4725b_pwm5_groups[] = { "pwm5", };
+
+static const struct function_desc jz4725b_functions[] = {
+       { "mmc0", jz4725b_mmc0_groups, ARRAY_SIZE(jz4725b_mmc0_groups), },
+       { "mmc1", jz4725b_mmc1_groups, ARRAY_SIZE(jz4725b_mmc1_groups), },
+       { "uart", jz4725b_uart_groups, ARRAY_SIZE(jz4725b_uart_groups), },
+       { "nand", jz4725b_nand_groups, ARRAY_SIZE(jz4725b_nand_groups), },
+       { "pwm0", jz4725b_pwm0_groups, ARRAY_SIZE(jz4725b_pwm0_groups), },
+       { "pwm1", jz4725b_pwm1_groups, ARRAY_SIZE(jz4725b_pwm1_groups), },
+       { "pwm2", jz4725b_pwm2_groups, ARRAY_SIZE(jz4725b_pwm2_groups), },
+       { "pwm3", jz4725b_pwm3_groups, ARRAY_SIZE(jz4725b_pwm3_groups), },
+       { "pwm4", jz4725b_pwm4_groups, ARRAY_SIZE(jz4725b_pwm4_groups), },
+       { "pwm5", jz4725b_pwm5_groups, ARRAY_SIZE(jz4725b_pwm5_groups), },
+};
+
+static const struct ingenic_chip_info jz4725b_chip_info = {
+       .num_chips = 4,
+       .groups = jz4725b_groups,
+       .num_groups = ARRAY_SIZE(jz4725b_groups),
+       .functions = jz4725b_functions,
+       .num_functions = ARRAY_SIZE(jz4725b_functions),
+       .pull_ups = jz4740_pull_ups,
+       .pull_downs = jz4740_pull_downs,
+};
+
 static const u32 jz4770_pull_ups[6] = {
        0x3fffffff, 0xfff0030c, 0xffffffff, 0xffff4fff, 0xfffffb7c, 0xffa7f00f,
 };
@@ -438,6 +542,235 @@ static const struct ingenic_chip_info jz4770_chip_info = {
        .pull_downs = jz4770_pull_downs,
 };
 
+static u32 gpio_ingenic_read_reg(struct ingenic_gpio_chip *jzgc, u8 reg)
+{
+       unsigned int val;
+
+       regmap_read(jzgc->jzpc->map, jzgc->reg_base + reg, &val);
+
+       return (u32) val;
+}
+
+static void gpio_ingenic_set_bit(struct ingenic_gpio_chip *jzgc,
+               u8 reg, u8 offset, bool set)
+{
+       if (set)
+               reg = REG_SET(reg);
+       else
+               reg = REG_CLEAR(reg);
+
+       regmap_write(jzgc->jzpc->map, jzgc->reg_base + reg, BIT(offset));
+}
+
+static inline bool ingenic_gpio_get_value(struct ingenic_gpio_chip *jzgc,
+                                         u8 offset)
+{
+       unsigned int val = gpio_ingenic_read_reg(jzgc, GPIO_PIN);
+
+       return !!(val & BIT(offset));
+}
+
+static void ingenic_gpio_set_value(struct ingenic_gpio_chip *jzgc,
+                                  u8 offset, int value)
+{
+       if (jzgc->jzpc->version >= ID_JZ4770)
+               gpio_ingenic_set_bit(jzgc, JZ4770_GPIO_PAT0, offset, !!value);
+       else
+               gpio_ingenic_set_bit(jzgc, JZ4740_GPIO_DATA, offset, !!value);
+}
+
+static void irq_set_type(struct ingenic_gpio_chip *jzgc,
+               u8 offset, unsigned int type)
+{
+       u8 reg1, reg2;
+
+       if (jzgc->jzpc->version >= ID_JZ4770) {
+               reg1 = JZ4770_GPIO_PAT1;
+               reg2 = JZ4770_GPIO_PAT0;
+       } else {
+               reg1 = JZ4740_GPIO_TRIG;
+               reg2 = JZ4740_GPIO_DIR;
+       }
+
+       switch (type) {
+       case IRQ_TYPE_EDGE_RISING:
+               gpio_ingenic_set_bit(jzgc, reg2, offset, true);
+               gpio_ingenic_set_bit(jzgc, reg1, offset, true);
+               break;
+       case IRQ_TYPE_EDGE_FALLING:
+               gpio_ingenic_set_bit(jzgc, reg2, offset, false);
+               gpio_ingenic_set_bit(jzgc, reg1, offset, true);
+               break;
+       case IRQ_TYPE_LEVEL_HIGH:
+               gpio_ingenic_set_bit(jzgc, reg2, offset, true);
+               gpio_ingenic_set_bit(jzgc, reg1, offset, false);
+               break;
+       case IRQ_TYPE_LEVEL_LOW:
+       default:
+               gpio_ingenic_set_bit(jzgc, reg2, offset, false);
+               gpio_ingenic_set_bit(jzgc, reg1, offset, false);
+               break;
+       }
+}
+
+static void ingenic_gpio_irq_mask(struct irq_data *irqd)
+{
+       struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
+       struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
+
+       gpio_ingenic_set_bit(jzgc, GPIO_MSK, irqd->hwirq, true);
+}
+
+static void ingenic_gpio_irq_unmask(struct irq_data *irqd)
+{
+       struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
+       struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
+
+       gpio_ingenic_set_bit(jzgc, GPIO_MSK, irqd->hwirq, false);
+}
+
+static void ingenic_gpio_irq_enable(struct irq_data *irqd)
+{
+       struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
+       struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
+       int irq = irqd->hwirq;
+
+       if (jzgc->jzpc->version >= ID_JZ4770)
+               gpio_ingenic_set_bit(jzgc, JZ4770_GPIO_INT, irq, true);
+       else
+               gpio_ingenic_set_bit(jzgc, JZ4740_GPIO_SELECT, irq, true);
+
+       ingenic_gpio_irq_unmask(irqd);
+}
+
+static void ingenic_gpio_irq_disable(struct irq_data *irqd)
+{
+       struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
+       struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
+       int irq = irqd->hwirq;
+
+       ingenic_gpio_irq_mask(irqd);
+
+       if (jzgc->jzpc->version >= ID_JZ4770)
+               gpio_ingenic_set_bit(jzgc, JZ4770_GPIO_INT, irq, false);
+       else
+               gpio_ingenic_set_bit(jzgc, JZ4740_GPIO_SELECT, irq, false);
+}
+
+static void ingenic_gpio_irq_ack(struct irq_data *irqd)
+{
+       struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
+       struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
+       int irq = irqd->hwirq;
+       bool high;
+
+       if (irqd_get_trigger_type(irqd) == IRQ_TYPE_EDGE_BOTH) {
+               /*
+                * Switch to an interrupt for the opposite edge to the one that
+                * triggered the interrupt being ACKed.
+                */
+               high = ingenic_gpio_get_value(jzgc, irq);
+               if (high)
+                       irq_set_type(jzgc, irq, IRQ_TYPE_EDGE_FALLING);
+               else
+                       irq_set_type(jzgc, irq, IRQ_TYPE_EDGE_RISING);
+       }
+
+       if (jzgc->jzpc->version >= ID_JZ4770)
+               gpio_ingenic_set_bit(jzgc, JZ4770_GPIO_FLAG, irq, false);
+       else
+               gpio_ingenic_set_bit(jzgc, JZ4740_GPIO_DATA, irq, true);
+}
+
+static int ingenic_gpio_irq_set_type(struct irq_data *irqd, unsigned int type)
+{
+       struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
+       struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
+
+       switch (type) {
+       case IRQ_TYPE_EDGE_BOTH:
+       case IRQ_TYPE_EDGE_RISING:
+       case IRQ_TYPE_EDGE_FALLING:
+               irq_set_handler_locked(irqd, handle_edge_irq);
+               break;
+       case IRQ_TYPE_LEVEL_HIGH:
+       case IRQ_TYPE_LEVEL_LOW:
+               irq_set_handler_locked(irqd, handle_level_irq);
+               break;
+       default:
+               irq_set_handler_locked(irqd, handle_bad_irq);
+       }
+
+       if (type == IRQ_TYPE_EDGE_BOTH) {
+               /*
+                * The hardware does not support interrupts on both edges. The
+                * best we can do is to set up a single-edge interrupt and then
+                * switch to the opposing edge when ACKing the interrupt.
+                */
+               bool high = ingenic_gpio_get_value(jzgc, irqd->hwirq);
+
+               type = high ? IRQ_TYPE_EDGE_FALLING : IRQ_TYPE_EDGE_RISING;
+       }
+
+       irq_set_type(jzgc, irqd->hwirq, type);
+       return 0;
+}
+
+static int ingenic_gpio_irq_set_wake(struct irq_data *irqd, unsigned int on)
+{
+       struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
+       struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
+
+       return irq_set_irq_wake(jzgc->irq, on);
+}
+
+static void ingenic_gpio_irq_handler(struct irq_desc *desc)
+{
+       struct gpio_chip *gc = irq_desc_get_handler_data(desc);
+       struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
+       struct irq_chip *irq_chip = irq_data_get_irq_chip(&desc->irq_data);
+       unsigned long flag, i;
+
+       chained_irq_enter(irq_chip, desc);
+
+       if (jzgc->jzpc->version >= ID_JZ4770)
+               flag = gpio_ingenic_read_reg(jzgc, JZ4770_GPIO_FLAG);
+       else
+               flag = gpio_ingenic_read_reg(jzgc, JZ4740_GPIO_FLAG);
+
+       for_each_set_bit(i, &flag, 32)
+               generic_handle_irq(irq_linear_revmap(gc->irq.domain, i));
+       chained_irq_exit(irq_chip, desc);
+}
+
+static void ingenic_gpio_set(struct gpio_chip *gc,
+               unsigned int offset, int value)
+{
+       struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
+
+       ingenic_gpio_set_value(jzgc, offset, value);
+}
+
+static int ingenic_gpio_get(struct gpio_chip *gc, unsigned int offset)
+{
+       struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
+
+       return (int) ingenic_gpio_get_value(jzgc, offset);
+}
+
+static int ingenic_gpio_direction_input(struct gpio_chip *gc,
+               unsigned int offset)
+{
+       return pinctrl_gpio_direction_input(gc->base + offset);
+}
+
+static int ingenic_gpio_direction_output(struct gpio_chip *gc,
+               unsigned int offset, int value)
+{
+       ingenic_gpio_set(gc, offset, value);
+       return pinctrl_gpio_direction_output(gc->base + offset);
+}
+
 static inline void ingenic_config_pin(struct ingenic_pinctrl *jzpc,
                unsigned int pin, u8 reg, bool set)
 {
@@ -460,6 +793,21 @@ static inline bool ingenic_get_pin_config(struct ingenic_pinctrl *jzpc,
        return val & BIT(idx);
 }
 
+static int ingenic_gpio_get_direction(struct gpio_chip *gc, unsigned int offset)
+{
+       struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
+       struct ingenic_pinctrl *jzpc = jzgc->jzpc;
+       unsigned int pin = gc->base + offset;
+
+       if (jzpc->version >= ID_JZ4770)
+               return ingenic_get_pin_config(jzpc, pin, JZ4770_GPIO_PAT1);
+
+       if (ingenic_get_pin_config(jzpc, pin, JZ4740_GPIO_SELECT))
+               return true;
+
+       return !ingenic_get_pin_config(jzpc, pin, JZ4740_GPIO_DIR);
+}
+
 static const struct pinctrl_ops ingenic_pctlops = {
        .get_groups_count = pinctrl_generic_get_group_count,
        .get_group_name = pinctrl_generic_get_group_name,
@@ -479,7 +827,7 @@ static int ingenic_pinmux_set_pin_fn(struct ingenic_pinctrl *jzpc,
 
        if (jzpc->version >= ID_JZ4770) {
                ingenic_config_pin(jzpc, pin, JZ4770_GPIO_INT, false);
-               ingenic_config_pin(jzpc, pin, JZ4770_GPIO_MSK, false);
+               ingenic_config_pin(jzpc, pin, GPIO_MSK, false);
                ingenic_config_pin(jzpc, pin, JZ4770_GPIO_PAT1, func & 0x2);
                ingenic_config_pin(jzpc, pin, JZ4770_GPIO_PAT0, func & 0x1);
        } else {
@@ -532,7 +880,7 @@ static int ingenic_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev,
 
        if (jzpc->version >= ID_JZ4770) {
                ingenic_config_pin(jzpc, pin, JZ4770_GPIO_INT, false);
-               ingenic_config_pin(jzpc, pin, JZ4770_GPIO_MSK, true);
+               ingenic_config_pin(jzpc, pin, GPIO_MSK, true);
                ingenic_config_pin(jzpc, pin, JZ4770_GPIO_PAT1, input);
        } else {
                ingenic_config_pin(jzpc, pin, JZ4740_GPIO_SELECT, false);
@@ -712,12 +1060,95 @@ static const struct regmap_config ingenic_pinctrl_regmap_config = {
 
 static const struct of_device_id ingenic_pinctrl_of_match[] = {
        { .compatible = "ingenic,jz4740-pinctrl", .data = (void *) ID_JZ4740 },
+       { .compatible = "ingenic,jz4725b-pinctrl", .data = (void *)ID_JZ4725B },
        { .compatible = "ingenic,jz4770-pinctrl", .data = (void *) ID_JZ4770 },
        { .compatible = "ingenic,jz4780-pinctrl", .data = (void *) ID_JZ4780 },
        {},
 };
 
-static int ingenic_pinctrl_probe(struct platform_device *pdev)
+static const struct of_device_id ingenic_gpio_of_match[] __initconst = {
+       { .compatible = "ingenic,jz4740-gpio", },
+       { .compatible = "ingenic,jz4770-gpio", },
+       { .compatible = "ingenic,jz4780-gpio", },
+       {},
+};
+
+static int __init ingenic_gpio_probe(struct ingenic_pinctrl *jzpc,
+                                    struct device_node *node)
+{
+       struct ingenic_gpio_chip *jzgc;
+       struct device *dev = jzpc->dev;
+       unsigned int bank;
+       int err;
+
+       err = of_property_read_u32(node, "reg", &bank);
+       if (err) {
+               dev_err(dev, "Cannot read \"reg\" property: %i\n", err);
+               return err;
+       }
+
+       jzgc = devm_kzalloc(dev, sizeof(*jzgc), GFP_KERNEL);
+       if (!jzgc)
+               return -ENOMEM;
+
+       jzgc->jzpc = jzpc;
+       jzgc->reg_base = bank * 0x100;
+
+       jzgc->gc.label = devm_kasprintf(dev, GFP_KERNEL, "GPIO%c", 'A' + bank);
+       if (!jzgc->gc.label)
+               return -ENOMEM;
+
+       /* DO NOT EXPAND THIS: FOR BACKWARD GPIO NUMBERSPACE COMPATIBIBILITY
+        * ONLY: WORK TO TRANSITION CONSUMERS TO USE THE GPIO DESCRIPTOR API IN
+        * <linux/gpio/consumer.h> INSTEAD.
+        */
+       jzgc->gc.base = bank * 32;
+
+       jzgc->gc.ngpio = 32;
+       jzgc->gc.parent = dev;
+       jzgc->gc.of_node = node;
+       jzgc->gc.owner = THIS_MODULE;
+
+       jzgc->gc.set = ingenic_gpio_set;
+       jzgc->gc.get = ingenic_gpio_get;
+       jzgc->gc.direction_input = ingenic_gpio_direction_input;
+       jzgc->gc.direction_output = ingenic_gpio_direction_output;
+       jzgc->gc.get_direction = ingenic_gpio_get_direction;
+
+       if (of_property_read_bool(node, "gpio-ranges")) {
+               jzgc->gc.request = gpiochip_generic_request;
+               jzgc->gc.free = gpiochip_generic_free;
+       }
+
+       err = devm_gpiochip_add_data(dev, &jzgc->gc, jzgc);
+       if (err)
+               return err;
+
+       jzgc->irq = irq_of_parse_and_map(node, 0);
+       if (!jzgc->irq)
+               return -EINVAL;
+
+       jzgc->irq_chip.name = jzgc->gc.label;
+       jzgc->irq_chip.irq_enable = ingenic_gpio_irq_enable;
+       jzgc->irq_chip.irq_disable = ingenic_gpio_irq_disable;
+       jzgc->irq_chip.irq_unmask = ingenic_gpio_irq_unmask;
+       jzgc->irq_chip.irq_mask = ingenic_gpio_irq_mask;
+       jzgc->irq_chip.irq_ack = ingenic_gpio_irq_ack;
+       jzgc->irq_chip.irq_set_type = ingenic_gpio_irq_set_type;
+       jzgc->irq_chip.irq_set_wake = ingenic_gpio_irq_set_wake;
+       jzgc->irq_chip.flags = IRQCHIP_MASK_ON_SUSPEND;
+
+       err = gpiochip_irqchip_add(&jzgc->gc, &jzgc->irq_chip, 0,
+                       handle_level_irq, IRQ_TYPE_NONE);
+       if (err)
+               return err;
+
+       gpiochip_set_chained_irqchip(&jzgc->gc, &jzgc->irq_chip,
+                       jzgc->irq, ingenic_gpio_irq_handler);
+       return 0;
+}
+
+static int __init ingenic_pinctrl_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
        struct ingenic_pinctrl *jzpc;
@@ -727,6 +1158,7 @@ static int ingenic_pinctrl_probe(struct platform_device *pdev)
        const struct of_device_id *of_id = of_match_device(
                        ingenic_pinctrl_of_match, dev);
        const struct ingenic_chip_info *chip_info;
+       struct device_node *node;
        unsigned int i;
        int err;
 
@@ -755,6 +1187,8 @@ static int ingenic_pinctrl_probe(struct platform_device *pdev)
 
        if (jzpc->version >= ID_JZ4770)
                chip_info = &jz4770_chip_info;
+       else if (jzpc->version >= ID_JZ4725B)
+               chip_info = &jz4725b_chip_info;
        else
                chip_info = &jz4740_chip_info;
        jzpc->info = chip_info;
@@ -815,11 +1249,11 @@ static int ingenic_pinctrl_probe(struct platform_device *pdev)
 
        dev_set_drvdata(dev, jzpc->map);
 
-       if (dev->of_node) {
-               err = of_platform_populate(dev->of_node, NULL, NULL, dev);
-               if (err) {
-                       dev_err(dev, "Failed to probe GPIO devices\n");
-                       return err;
+       for_each_child_of_node(dev->of_node, node) {
+               if (of_match_node(ingenic_gpio_of_match, node)) {
+                       err = ingenic_gpio_probe(jzpc, node);
+                       if (err)
+                               return err;
                }
        }
 
@@ -828,6 +1262,7 @@ static int ingenic_pinctrl_probe(struct platform_device *pdev)
 
 static const struct platform_device_id ingenic_pinctrl_ids[] = {
        { "jz4740-pinctrl", ID_JZ4740 },
+       { "jz4725b-pinctrl", ID_JZ4725B },
        { "jz4770-pinctrl", ID_JZ4770 },
        { "jz4780-pinctrl", ID_JZ4780 },
        {},
@@ -837,14 +1272,13 @@ static struct platform_driver ingenic_pinctrl_driver = {
        .driver = {
                .name = "pinctrl-ingenic",
                .of_match_table = of_match_ptr(ingenic_pinctrl_of_match),
-               .suppress_bind_attrs = true,
        },
-       .probe = ingenic_pinctrl_probe,
        .id_table = ingenic_pinctrl_ids,
 };
 
 static int __init ingenic_pinctrl_drv_register(void)
 {
-       return platform_driver_register(&ingenic_pinctrl_driver);
+       return platform_driver_probe(&ingenic_pinctrl_driver,
+                                    ingenic_pinctrl_probe);
 }
-postcore_initcall(ingenic_pinctrl_drv_register);
+subsys_initcall(ingenic_pinctrl_drv_register);
index 81632af..22e8061 100644 (file)
@@ -80,14 +80,14 @@ static void ltq_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
        int ret, i;
 
        if (!pins && !groups) {
-               dev_err(pctldev->dev, "%s defines neither pins nor groups\n",
-                       np->name);
+               dev_err(pctldev->dev, "%pOFn defines neither pins nor groups\n",
+                       np);
                return;
        }
 
        if (pins && groups) {
-               dev_err(pctldev->dev, "%s defines both pins and groups\n",
-                       np->name);
+               dev_err(pctldev->dev, "%pOFn defines both pins and groups\n",
+                       np);
                return;
        }
 
index 190f17e..a14bc5e 100644 (file)
@@ -844,8 +844,11 @@ static int lpc18xx_pconf_get_pin(struct pinctrl_dev *pctldev, unsigned param,
                *arg = (reg & LPC18XX_SCU_PIN_EHD_MASK) >> LPC18XX_SCU_PIN_EHD_POS;
                switch (*arg) {
                case 3: *arg += 5;
+                       /* fall through */
                case 2: *arg += 5;
+                       /* fall through */
                case 1: *arg += 3;
+                       /* fall through */
                case 0: *arg += 4;
                }
                break;
@@ -1060,8 +1063,11 @@ static int lpc18xx_pconf_set_pin(struct pinctrl_dev *pctldev, unsigned param,
 
                switch (param_val) {
                case 20: param_val -= 5;
+                        /* fall through */
                case 14: param_val -= 5;
+                        /* fall through */
                case  8: param_val -= 3;
+                        /* fall through */
                case  4: param_val -= 4;
                         break;
                default:
index f4a6142..1fe72af 100644 (file)
@@ -501,8 +501,8 @@ static int rockchip_dt_node_to_map(struct pinctrl_dev *pctldev,
         */
        grp = pinctrl_name_to_group(info, np->name);
        if (!grp) {
-               dev_err(info->dev, "unable to find group for node %s\n",
-                       np->name);
+               dev_err(info->dev, "unable to find group for node %pOFn\n",
+                       np);
                return -EINVAL;
        }
 
@@ -2454,7 +2454,7 @@ static int rockchip_pinctrl_parse_groups(struct device_node *np,
        int i, j;
        int ret;
 
-       dev_dbg(info->dev, "group(%d): %s\n", index, np->name);
+       dev_dbg(info->dev, "group(%d): %pOFn\n", index, np);
 
        /* Initialise group */
        grp->name = np->name;
@@ -2519,7 +2519,7 @@ static int rockchip_pinctrl_parse_functions(struct device_node *np,
        static u32 grp_index;
        u32 i = 0;
 
-       dev_dbg(info->dev, "parse function(%d): %s\n", index, np->name);
+       dev_dbg(info->dev, "parse function(%d): %pOFn\n", index, np);
 
        func = &info->functions[index];
 
index f76edf6..042ede3 100644 (file)
@@ -930,8 +930,8 @@ static int rza1_parse_pinmux_node(struct rza1_pinctrl *rza1_pctl,
                                              &npin_configs);
        if (ret) {
                dev_err(rza1_pctl->dev,
-                       "Unable to parse pin configuration options for %s\n",
-                       np->name);
+                       "Unable to parse pin configuration options for %pOFn\n",
+                       np);
                return ret;
        }
 
@@ -1226,8 +1226,8 @@ static int rza1_parse_gpiochip(struct rza1_pinctrl *rza1_pctl,
 
        *chip           = rza1_gpiochip_template;
        chip->base      = -1;
-       chip->label     = devm_kasprintf(rza1_pctl->dev, GFP_KERNEL, "%s",
-                                        np->name);
+       chip->label     = devm_kasprintf(rza1_pctl->dev, GFP_KERNEL, "%pOFn",
+                                        np);
        chip->ngpio     = of_args.args[2];
        chip->of_node   = np;
        chip->parent    = rza1_pctl->dev;
index 7ec72ff..1e0614d 100644 (file)
@@ -1022,14 +1022,14 @@ static int pcs_parse_one_pinctrl_entry(struct pcs_device *pcs,
                vals[found].reg = pcs->base + offset;
                vals[found].val = pinctrl_spec.args[1];
 
-               dev_dbg(pcs->dev, "%s index: 0x%x value: 0x%x\n",
-                       pinctrl_spec.np->name, offset, pinctrl_spec.args[1]);
+               dev_dbg(pcs->dev, "%pOFn index: 0x%x value: 0x%x\n",
+                       pinctrl_spec.np, offset, pinctrl_spec.args[1]);
 
                pin = pcs_get_pin_by_offset(pcs, offset);
                if (pin < 0) {
                        dev_err(pcs->dev,
-                               "could not add functions for %s %ux\n",
-                               np->name, offset);
+                               "could not add functions for %pOFn %ux\n",
+                               np, offset);
                        break;
                }
                pins[found++] = pin;
@@ -1135,8 +1135,8 @@ static int pcs_parse_bits_in_pinctrl_entry(struct pcs_device *pcs,
                val = pinctrl_spec.args[1];
                mask = pinctrl_spec.args[2];
 
-               dev_dbg(pcs->dev, "%s index: 0x%x value: 0x%x mask: 0x%x\n",
-                       pinctrl_spec.np->name, offset, val, mask);
+               dev_dbg(pcs->dev, "%pOFn index: 0x%x value: 0x%x mask: 0x%x\n",
+                       pinctrl_spec.np, offset, val, mask);
 
                /* Parse pins in each row from LSB */
                while (mask) {
@@ -1148,8 +1148,8 @@ static int pcs_parse_bits_in_pinctrl_entry(struct pcs_device *pcs,
 
                        if ((mask & mask_pos) == 0) {
                                dev_err(pcs->dev,
-                                       "Invalid mask for %s at 0x%x\n",
-                                       np->name, offset);
+                                       "Invalid mask for %pOFn at 0x%x\n",
+                                       np, offset);
                                break;
                        }
 
@@ -1157,8 +1157,8 @@ static int pcs_parse_bits_in_pinctrl_entry(struct pcs_device *pcs,
 
                        if (submask != mask_pos) {
                                dev_warn(pcs->dev,
-                                               "Invalid submask 0x%x for %s at 0x%x\n",
-                                               submask, np->name, offset);
+                                               "Invalid submask 0x%x for %pOFn at 0x%x\n",
+                                               submask, np, offset);
                                continue;
                        }
 
@@ -1169,8 +1169,8 @@ static int pcs_parse_bits_in_pinctrl_entry(struct pcs_device *pcs,
                        pin = pcs_get_pin_by_offset(pcs, offset);
                        if (pin < 0) {
                                dev_err(pcs->dev,
-                                       "could not add functions for %s %ux\n",
-                                       np->name, offset);
+                                       "could not add functions for %pOFn %ux\n",
+                                       np, offset);
                                break;
                        }
                        pins[found++] = pin + pin_num_from_lsb;
@@ -1254,16 +1254,16 @@ static int pcs_dt_node_to_map(struct pinctrl_dev *pctldev,
                ret = pcs_parse_bits_in_pinctrl_entry(pcs, np_config, map,
                                num_maps, pgnames);
                if (ret < 0) {
-                       dev_err(pcs->dev, "no pins entries for %s\n",
-                               np_config->name);
+                       dev_err(pcs->dev, "no pins entries for %pOFn\n",
+                               np_config);
                        goto free_pgnames;
                }
        } else {
                ret = pcs_parse_one_pinctrl_entry(pcs, np_config, map,
                                num_maps, pgnames);
                if (ret < 0) {
-                       dev_err(pcs->dev, "no pins entries for %s\n",
-                               np_config->name);
+                       dev_err(pcs->dev, "no pins entries for %pOFn\n",
+                               np_config);
                        goto free_pgnames;
                }
        }
index 0966bb0..e66af93 100644 (file)
@@ -817,8 +817,8 @@ static int st_pctl_dt_node_to_map(struct pinctrl_dev *pctldev,
 
        grp = st_pctl_find_group_by_name(info, np->name);
        if (!grp) {
-               dev_err(info->dev, "unable to find group for node %s\n",
-                       np->name);
+               dev_err(info->dev, "unable to find group for node %pOFn\n",
+                       np);
                return -EINVAL;
        }
 
@@ -1184,7 +1184,7 @@ static int st_pctl_dt_parse_groups(struct device_node *np,
                if (pp->length / sizeof(__be32) >= OF_GPIO_ARGS_MIN) {
                        npins++;
                } else {
-                       pr_warn("Invalid st,pins in %s node\n", np->name);
+                       pr_warn("Invalid st,pins in %pOFn node\n", np);
                        return -EINVAL;
                }
        }
index 2155a30..cad7409 100644 (file)
@@ -176,11 +176,27 @@ static int msm_pinmux_set_mux(struct pinctrl_dev *pctldev,
        return 0;
 }
 
+static int msm_pinmux_request_gpio(struct pinctrl_dev *pctldev,
+                                  struct pinctrl_gpio_range *range,
+                                  unsigned offset)
+{
+       struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+       const struct msm_pingroup *g = &pctrl->soc->groups[offset];
+
+       /* No funcs? Probably ACPI so can't do anything here */
+       if (!g->nfuncs)
+               return 0;
+
+       /* For now assume function 0 is GPIO because it always is */
+       return msm_pinmux_set_mux(pctldev, 0, offset);
+}
+
 static const struct pinmux_ops msm_pinmux_ops = {
        .request                = msm_pinmux_request,
        .get_functions_count    = msm_get_functions_count,
        .get_function_name      = msm_get_function_name,
        .get_function_groups    = msm_get_function_groups,
+       .gpio_request_enable    = msm_pinmux_request_gpio,
        .set_mux                = msm_pinmux_set_mux,
 };
 
@@ -797,6 +813,41 @@ static int msm_gpio_irq_set_wake(struct irq_data *d, unsigned int on)
        return 0;
 }
 
+static int msm_gpio_irq_reqres(struct irq_data *d)
+{
+       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+       struct msm_pinctrl *pctrl = gpiochip_get_data(gc);
+       int ret;
+
+       if (!try_module_get(gc->owner))
+               return -ENODEV;
+
+       ret = msm_pinmux_request_gpio(pctrl->pctrl, NULL, d->hwirq);
+       if (ret)
+               goto out;
+       msm_gpio_direction_input(gc, d->hwirq);
+
+       if (gpiochip_lock_as_irq(gc, d->hwirq)) {
+               dev_err(gc->parent,
+                       "unable to lock HW IRQ %lu for IRQ\n",
+                       d->hwirq);
+               ret = -EINVAL;
+               goto out;
+       }
+       return 0;
+out:
+       module_put(gc->owner);
+       return ret;
+}
+
+static void msm_gpio_irq_relres(struct irq_data *d)
+{
+       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+
+       gpiochip_unlock_as_irq(gc, d->hwirq);
+       module_put(gc->owner);
+}
+
 static void msm_gpio_irq_handler(struct irq_desc *desc)
 {
        struct gpio_chip *gc = irq_desc_get_handler_data(desc);
@@ -895,6 +946,8 @@ static int msm_gpio_init(struct msm_pinctrl *pctrl)
        pctrl->irq_chip.irq_ack = msm_gpio_irq_ack;
        pctrl->irq_chip.irq_set_type = msm_gpio_irq_set_type;
        pctrl->irq_chip.irq_set_wake = msm_gpio_irq_set_wake;
+       pctrl->irq_chip.irq_request_resources = msm_gpio_irq_reqres;
+       pctrl->irq_chip.irq_release_resources = msm_gpio_irq_relres;
 
        ret = gpiochip_add_data(&pctrl->chip, pctrl);
        if (ret) {
index 3abb028..1d16df1 100644 (file)
@@ -6058,8 +6058,8 @@ static int atlas7_gpio_probe(struct platform_device *pdev)
        ret = gpiochip_add_data(chip, a7gc);
        if (ret) {
                dev_err(&pdev->dev,
-                       "%s: error in probe function with status %d\n",
-                       np->name, ret);
+                       "%pOF: error in probe function with status %d\n",
+                       np, ret);
                goto failed;
        }
 
index a9bec6e..0fbfcc9 100644 (file)
@@ -416,8 +416,8 @@ static int stm32_pctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
 
        pins = of_find_property(node, "pinmux", NULL);
        if (!pins) {
-               dev_err(pctl->dev, "missing pins property in node %s .\n",
-                               node->name);
+               dev_err(pctl->dev, "missing pins property in node %pOFn .\n",
+                               node);
                return -EINVAL;
        }
 
index 4d9bf9b..3ccbe22 100644 (file)
@@ -332,15 +332,15 @@ static int sunxi_pctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
 
        function = sunxi_pctrl_parse_function_prop(node);
        if (!function) {
-               dev_err(pctl->dev, "missing function property in node %s\n",
-                       node->name);
+               dev_err(pctl->dev, "missing function property in node %pOFn\n",
+                       node);
                return -EINVAL;
        }
 
        pin_prop = sunxi_pctrl_find_pins_prop(node, &npins);
        if (!pin_prop) {
-               dev_err(pctl->dev, "missing pins property in node %s\n",
-                       node->name);
+               dev_err(pctl->dev, "missing pins property in node %pOFn\n",
+                       node);
                return -EINVAL;
        }
 
index 8782c34..a4bc506 100644 (file)
@@ -452,8 +452,8 @@ static int ti_iodelay_node_iterator(struct pinctrl_dev *pctldev,
 
        pin = ti_iodelay_offset_to_pin(iod, cfg[pin_index].offset);
        if (pin < 0) {
-               dev_err(iod->dev, "could not add functions for %s %ux\n",
-                       np->name, cfg[pin_index].offset);
+               dev_err(iod->dev, "could not add functions for %pOFn %ux\n",
+                       np, cfg[pin_index].offset);
                return -ENODEV;
        }
        pins[pin_index] = pin;
@@ -461,8 +461,8 @@ static int ti_iodelay_node_iterator(struct pinctrl_dev *pctldev,
        pd = &iod->pa[pin];
        pd->drv_data = &cfg[pin_index];
 
-       dev_dbg(iod->dev, "%s offset=%x a_delay = %d g_delay = %d\n",
-               np->name, cfg[pin_index].offset, cfg[pin_index].a_delay,
+       dev_dbg(iod->dev, "%pOFn offset=%x a_delay = %d g_delay = %d\n",
+               np, cfg[pin_index].offset, cfg[pin_index].a_delay,
                cfg[pin_index].g_delay);
 
        return 0;
index 6072289..4326f5c 100644 (file)
@@ -1048,9 +1048,8 @@ static const unsigned nand_cs1_pins[] = {131, 132};
 static const int nand_cs1_muxvals[] = {1, 1};
 static const unsigned sd_pins[] = {150, 151, 152, 153, 154, 155, 156, 157, 158};
 static const int sd_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
-static const unsigned sd1_pins[] = {319, 320, 321, 322, 323, 324, 325, 326,
-                                   327};
-static const int sd1_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
+static const unsigned int sd1_pins[] = {319, 320, 321, 322, 323, 324, 325, 326};
+static const int sd1_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0};
 static const unsigned spi0_pins[] = {199, 200, 201, 202};
 static const int spi0_muxvals[] = {11, 11, 11, 11};
 static const unsigned spi1_pins[] = {195, 196, 197, 198, 235, 238, 239};
diff --git a/include/dt-bindings/gpio/meson-g12a-gpio.h b/include/dt-bindings/gpio/meson-g12a-gpio.h
new file mode 100644 (file)
index 0000000..f7bd693
--- /dev/null
@@ -0,0 +1,114 @@
+/* SPDX-License-Identifier: (GPL-2.0+ or MIT) */
+/*
+ * Copyright (c) 2018 Amlogic, Inc. All rights reserved.
+ * Author: Xingyu Chen <xingyu.chen@amlogic.com>
+ */
+
+#ifndef _DT_BINDINGS_MESON_G12A_GPIO_H
+#define _DT_BINDINGS_MESON_G12A_GPIO_H
+
+/* First GPIO chip */
+#define GPIOAO_0       0
+#define GPIOAO_1       1
+#define GPIOAO_2       2
+#define GPIOAO_3       3
+#define GPIOAO_4       4
+#define GPIOAO_5       5
+#define GPIOAO_6       6
+#define GPIOAO_7       7
+#define GPIOAO_8       8
+#define GPIOAO_9       9
+#define GPIOAO_10      10
+#define GPIOAO_11      11
+#define GPIOE_0                12
+#define GPIOE_1                13
+#define GPIOE_2                14
+
+/* Second GPIO chip */
+#define GPIOZ_0                0
+#define GPIOZ_1                1
+#define GPIOZ_2                2
+#define GPIOZ_3                3
+#define GPIOZ_4                4
+#define GPIOZ_5                5
+#define GPIOZ_6                6
+#define GPIOZ_7                7
+#define GPIOZ_8                8
+#define GPIOZ_9                9
+#define GPIOZ_10       10
+#define GPIOZ_11       11
+#define GPIOZ_12       12
+#define GPIOZ_13       13
+#define GPIOZ_14       14
+#define GPIOZ_15       15
+#define GPIOH_0                16
+#define GPIOH_1                17
+#define GPIOH_2                18
+#define GPIOH_3                19
+#define GPIOH_4                20
+#define GPIOH_5                21
+#define GPIOH_6                22
+#define GPIOH_7                23
+#define GPIOH_8                24
+#define BOOT_0         25
+#define BOOT_1         26
+#define BOOT_2         27
+#define BOOT_3         28
+#define BOOT_4         29
+#define BOOT_5         30
+#define BOOT_6         31
+#define BOOT_7         32
+#define BOOT_8         33
+#define BOOT_9         34
+#define BOOT_10                35
+#define BOOT_11                36
+#define BOOT_12                37
+#define BOOT_13                38
+#define BOOT_14                39
+#define BOOT_15                40
+#define GPIOC_0                41
+#define GPIOC_1                42
+#define GPIOC_2                43
+#define GPIOC_3                44
+#define GPIOC_4                45
+#define GPIOC_5                46
+#define GPIOC_6                47
+#define GPIOC_7                48
+#define GPIOA_0                49
+#define GPIOA_1                50
+#define GPIOA_2                51
+#define GPIOA_3                52
+#define GPIOA_4                53
+#define GPIOA_5                54
+#define GPIOA_6                55
+#define GPIOA_7                56
+#define GPIOA_8                57
+#define GPIOA_9                58
+#define GPIOA_10       59
+#define GPIOA_11       60
+#define GPIOA_12       61
+#define GPIOA_13       62
+#define GPIOA_14       63
+#define GPIOA_15       64
+#define GPIOX_0                65
+#define GPIOX_1                66
+#define GPIOX_2                67
+#define GPIOX_3                68
+#define GPIOX_4                69
+#define GPIOX_5                70
+#define GPIOX_6                71
+#define GPIOX_7                72
+#define GPIOX_8                73
+#define GPIOX_9                74
+#define GPIOX_10       75
+#define GPIOX_11       76
+#define GPIOX_12       77
+#define GPIOX_13       78
+#define GPIOX_14       79
+#define GPIOX_15       80
+#define GPIOX_16       81
+#define GPIOX_17       82
+#define GPIOX_18       83
+#define GPIOX_19       84
+
+#endif /* _DT_BINDINGS_MESON_G12A_GPIO_H */