Merge tag 'pinctrl-v3.17-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 8 Aug 2014 00:20:53 +0000 (17:20 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 8 Aug 2014 00:20:53 +0000 (17:20 -0700)
Pull pinctrl updates from Linus Walleij:
 "This is the bulk pin control changes for the v3.17 merge development
  cycle:

   - get rid of the .disable() callback from the driver callback vtable.

     This callback was abused and counterintuitive since a pin or group
     of pins can be said to always be in some setting, and never really
     disabled.  We now only enable a certain muxing, and move between
     some certain muxings, we never "disable" a mux setting

   - some janitorial moving the MSM, Samsung and Nomadik and drivers to
     their own subdirectories for a clearer view in the subsystem.  This
     will continue

   - kill off the use of the return value from gpiochip_remove(), this
     will be done in parallel in the GPIO subsystem and hopefully not
     trigger too many unchecked return value warnings before we get rid
     of this altogether

   - a huge set of changes and improvements to the Allwinner sunxi
     drivers especially for their latest A23 and A31 SoCs, and some
     ground work for the new sun8i platform family

   - a large set of Rockchip driver improvements adding support for the
     RK3288 SoC

   - advances in migration of older Freescale platforms to pin control,
     especially i.MX1

   - Samsung and Exynos improvements

   - support for the Qualcomm MSM8960 SoC

   - use the gpiolib irqchip helpers for the ST SPEAr and Intel Baytrail
     drivers

   - a bunch of nice janitorial work done with cppcheck"

* tag 'pinctrl-v3.17-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl: (61 commits)
  pinctrl: baytrail: Convert to use gpiolib irqchip
  pinctrl: sunxi: number gpio ranges starting from 0
  pinctrl: sunxi: use gpiolib API to mark a GPIO used as an IRQ
  pinctrl: rockchip: add drive-strength control for rk3288
  pinctrl: rockchip: add separate type for rk3288
  pinctrl: rockchip: set is_generic in pinconf_ops
  pinctrl: msm: drop negativity check on unsigned value
  pinctrl: remove all usage of gpio_remove ret val in driver/pinctl
  pinctrl: qcom: Make muxing of gpio function explicit
  pinctrl: nomadik: move all Nomadik drivers to subdir
  pinctrl: samsung: Group all drivers in a sub-dir
  sh-pfc: sh73a0: Introduce the use of devm_regulator_register
  sh-pfc: Add renesas,pfc-r8a7791 to binding documentation
  pinctrl: msm: move all qualcomm drivers to subdir
  pinctrl: msm: Add msm8960 definitions
  pinctrl: samsung: Allow pin value to be initialized using pinfunc
  pinctrl: samsung: Allow grouping multiple pinmux/pinconf nodes
  pinctrl: exynos: Consolidate irq_chips of GPIO and WKUP EINTs
  pinctrl: samsung: Handle GPIO request and free using pinctrl helpers
  pinctrl: samsung: Decouple direction setting from pinctrl
  ...

108 files changed:
Documentation/devicetree/bindings/pinctrl/allwinner,sunxi-pinctrl.txt
Documentation/devicetree/bindings/pinctrl/qcom,apq8064-pinctrl.txt
Documentation/devicetree/bindings/pinctrl/qcom,ipq8064-pinctrl.txt
Documentation/devicetree/bindings/pinctrl/qcom,msm8960-pinctrl.txt [new file with mode: 0644]
Documentation/devicetree/bindings/pinctrl/qcom,msm8974-pinctrl.txt
Documentation/devicetree/bindings/pinctrl/renesas,pfc-pinctrl.txt
Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.txt
Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
arch/arm/boot/dts/imx27-pinfunc.h
arch/arm/mach-sunxi/Kconfig
drivers/pinctrl/Kconfig
drivers/pinctrl/Makefile
drivers/pinctrl/core.c
drivers/pinctrl/nomadik/Kconfig [new file with mode: 0644]
drivers/pinctrl/nomadik/Makefile [new file with mode: 0644]
drivers/pinctrl/nomadik/pinctrl-ab8500.c [new file with mode: 0644]
drivers/pinctrl/nomadik/pinctrl-ab8505.c [new file with mode: 0644]
drivers/pinctrl/nomadik/pinctrl-ab8540.c [new file with mode: 0644]
drivers/pinctrl/nomadik/pinctrl-ab9540.c [new file with mode: 0644]
drivers/pinctrl/nomadik/pinctrl-abx500.c [new file with mode: 0644]
drivers/pinctrl/nomadik/pinctrl-abx500.h [new file with mode: 0644]
drivers/pinctrl/nomadik/pinctrl-nomadik-db8500.c [new file with mode: 0644]
drivers/pinctrl/nomadik/pinctrl-nomadik-db8540.c [new file with mode: 0644]
drivers/pinctrl/nomadik/pinctrl-nomadik-stn8815.c [new file with mode: 0644]
drivers/pinctrl/nomadik/pinctrl-nomadik.c [new file with mode: 0644]
drivers/pinctrl/nomadik/pinctrl-nomadik.h [new file with mode: 0644]
drivers/pinctrl/pinctrl-ab8500.c [deleted file]
drivers/pinctrl/pinctrl-ab8505.c [deleted file]
drivers/pinctrl/pinctrl-ab8540.c [deleted file]
drivers/pinctrl/pinctrl-ab9540.c [deleted file]
drivers/pinctrl/pinctrl-abx500.c [deleted file]
drivers/pinctrl/pinctrl-abx500.h [deleted file]
drivers/pinctrl/pinctrl-adi2.c
drivers/pinctrl/pinctrl-apq8064.c [deleted file]
drivers/pinctrl/pinctrl-as3722.c
drivers/pinctrl/pinctrl-at91.c
drivers/pinctrl/pinctrl-baytrail.c
drivers/pinctrl/pinctrl-bcm281xx.c
drivers/pinctrl/pinctrl-bcm2835.c
drivers/pinctrl/pinctrl-coh901.c
drivers/pinctrl/pinctrl-exynos.c [deleted file]
drivers/pinctrl/pinctrl-exynos.h [deleted file]
drivers/pinctrl/pinctrl-exynos5440.c [deleted file]
drivers/pinctrl/pinctrl-imx.c
drivers/pinctrl/pinctrl-imx1-core.c
drivers/pinctrl/pinctrl-imx1.c [new file with mode: 0644]
drivers/pinctrl/pinctrl-imx27.c
drivers/pinctrl/pinctrl-ipq8064.c [deleted file]
drivers/pinctrl/pinctrl-msm.c [deleted file]
drivers/pinctrl/pinctrl-msm.h [deleted file]
drivers/pinctrl/pinctrl-msm8x74.c [deleted file]
drivers/pinctrl/pinctrl-nomadik-db8500.c [deleted file]
drivers/pinctrl/pinctrl-nomadik-db8540.c [deleted file]
drivers/pinctrl/pinctrl-nomadik-stn8815.c [deleted file]
drivers/pinctrl/pinctrl-nomadik.c [deleted file]
drivers/pinctrl/pinctrl-nomadik.h [deleted file]
drivers/pinctrl/pinctrl-rockchip.c
drivers/pinctrl/pinctrl-s3c24xx.c [deleted file]
drivers/pinctrl/pinctrl-s3c64xx.c [deleted file]
drivers/pinctrl/pinctrl-samsung.c [deleted file]
drivers/pinctrl/pinctrl-samsung.h [deleted file]
drivers/pinctrl/pinctrl-single.c
drivers/pinctrl/pinctrl-st.c
drivers/pinctrl/pinctrl-tb10x.c
drivers/pinctrl/pinctrl-tegra.c
drivers/pinctrl/pinctrl-tz1090-pdc.c
drivers/pinctrl/pinctrl-tz1090.c
drivers/pinctrl/pinctrl-u300.c
drivers/pinctrl/pinmux.c
drivers/pinctrl/qcom/Kconfig [new file with mode: 0644]
drivers/pinctrl/qcom/Makefile [new file with mode: 0644]
drivers/pinctrl/qcom/pinctrl-apq8064.c [new file with mode: 0644]
drivers/pinctrl/qcom/pinctrl-ipq8064.c [new file with mode: 0644]
drivers/pinctrl/qcom/pinctrl-msm.c [new file with mode: 0644]
drivers/pinctrl/qcom/pinctrl-msm.h [new file with mode: 0644]
drivers/pinctrl/qcom/pinctrl-msm8960.c [new file with mode: 0644]
drivers/pinctrl/qcom/pinctrl-msm8x74.c [new file with mode: 0644]
drivers/pinctrl/samsung/Kconfig [new file with mode: 0644]
drivers/pinctrl/samsung/Makefile [new file with mode: 0644]
drivers/pinctrl/samsung/pinctrl-exynos.c [new file with mode: 0644]
drivers/pinctrl/samsung/pinctrl-exynos.h [new file with mode: 0644]
drivers/pinctrl/samsung/pinctrl-exynos5440.c [new file with mode: 0644]
drivers/pinctrl/samsung/pinctrl-s3c24xx.c [new file with mode: 0644]
drivers/pinctrl/samsung/pinctrl-s3c64xx.c [new file with mode: 0644]
drivers/pinctrl/samsung/pinctrl-samsung.c [new file with mode: 0644]
drivers/pinctrl/samsung/pinctrl-samsung.h [new file with mode: 0644]
drivers/pinctrl/sh-pfc/gpio.c
drivers/pinctrl/sh-pfc/pfc-r8a7791.c
drivers/pinctrl/sh-pfc/pfc-sh73a0.c
drivers/pinctrl/sh-pfc/pinctrl.c
drivers/pinctrl/sirf/pinctrl-sirf.c
drivers/pinctrl/spear/Kconfig
drivers/pinctrl/spear/pinctrl-plgpio.c
drivers/pinctrl/spear/pinctrl-spear.c
drivers/pinctrl/sunxi/Kconfig
drivers/pinctrl/sunxi/Makefile
drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c
drivers/pinctrl/sunxi/pinctrl-sun5i-a10s.c
drivers/pinctrl/sunxi/pinctrl-sun5i-a13.c
drivers/pinctrl/sunxi/pinctrl-sun6i-a31-r.c
drivers/pinctrl/sunxi/pinctrl-sun6i-a31.c
drivers/pinctrl/sunxi/pinctrl-sun7i-a20.c
drivers/pinctrl/sunxi/pinctrl-sun8i-a23-r.c [new file with mode: 0644]
drivers/pinctrl/sunxi/pinctrl-sun8i-a23.c [new file with mode: 0644]
drivers/pinctrl/sunxi/pinctrl-sunxi.c
drivers/pinctrl/sunxi/pinctrl-sunxi.h
drivers/pinctrl/vt8500/pinctrl-wmt.c
include/linux/pinctrl/pinmux.h

index d8d065608ec0a7de0aae5d5f8f094a9d5ed1cb40..93ce12eb422a6877de66d4a2ab29dd86f003ecb8 100644 (file)
@@ -13,6 +13,8 @@ Required properties:
   "allwinner,sun6i-a31-pinctrl"
   "allwinner,sun6i-a31-r-pinctrl"
   "allwinner,sun7i-a20-pinctrl"
+  "allwinner,sun8i-a23-pinctrl"
+  "allwinner,sun8i-a23-r-pinctrl"
 - reg: Should contain the register physical address and length for the
   pin controller.
 
index 7181f925acaaa8c82a16fb22393d0c70ae193089..0211c6d8a5229e17866eb90f751a015ffaf609a0 100644 (file)
@@ -46,7 +46,7 @@ Valid values for pins are:
   gpio0-gpio89
 
 Valid values for function are:
-  cam_mclk, codec_mic_i2s, codec_spkr_i2s, gsbi1, gsbi2, gsbi3, gsbi4,
+  cam_mclk, codec_mic_i2s, codec_spkr_i2s, gpio, gsbi1, gsbi2, gsbi3, gsbi4,
   gsbi4_cam_i2c, gsbi5, gsbi5_spi_cs1, gsbi5_spi_cs2, gsbi5_spi_cs3, gsbi6,
   gsbi6_spi_cs1, gsbi6_spi_cs2, gsbi6_spi_cs3, gsbi7, gsbi7_spi_cs1,
   gsbi7_spi_cs2, gsbi7_spi_cs3, gsbi_cam_i2c, hdmi, mi2s, riva_bt, riva_fm,
index e0d35a40981be7deafba5d6da370be4b6c68d685..e33e4dcdce79bdfb51e17b4ab1bbb5602db569b0 100644 (file)
@@ -51,7 +51,7 @@ Valid values for qcom,pins are:
 
 
 Valid values for function are:
-  mdio, mi2s, pdm, ssbi, spmi, audio_pcm, gsbi1, gsbi2, gsbi4, gsbi5,
+  mdio, mi2s, pdm, ssbi, spmi, audio_pcm, gpio, gsbi1, gsbi2, gsbi4, gsbi5,
   gsbi5_spi_cs1, gsbi5_spi_cs2, gsbi5_spi_cs3, gsbi6, gsbi7, nss_spi, sdc1,
   spdif, nand, tsif1, tsif2, usb_fs_n, usb_fs, usb2_hsic, rgmii2, sata,
   pcie1_rst, pcie1_prsnt, pcie1_pwren_n, pcie1_pwren, pcie1_pwrflt,
diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,msm8960-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/qcom,msm8960-pinctrl.txt
new file mode 100644 (file)
index 0000000..93b7de9
--- /dev/null
@@ -0,0 +1,181 @@
+Qualcomm MSM8960 TLMM block
+
+This binding describes the Top Level Mode Multiplexer block found in the
+MSM8960 platform.
+
+- compatible:
+       Usage: required
+       Value type: <string>
+       Definition: must be "qcom,msm8960-pinctrl"
+
+- reg:
+       Usage: required
+       Value type: <prop-encoded-array>
+       Definition: the base address and size of the TLMM register space.
+
+- interrupts:
+       Usage: required
+       Value type: <prop-encoded-array>
+       Definition: should specify the TLMM summary IRQ.
+
+- interrupt-controller:
+       Usage: required
+       Value type: <none>
+       Definition: identifies this node as an interrupt controller
+
+- #interrupt-cells:
+       Usage: required
+       Value type: <u32>
+       Definition: must be 2. Specifying the pin number and flags, as defined
+                   in <dt-bindings/interrupt-controller/irq.h>
+
+- gpio-controller:
+       Usage: required
+       Value type: <none>
+       Definition: identifies this node as a gpio controller
+
+- #gpio-cells:
+       Usage: required
+       Value type: <u32>
+       Definition: must be 2. Specifying the pin number and flags, as defined
+                   in <dt-bindings/gpio/gpio.h>
+
+Please refer to ../gpio/gpio.txt and ../interrupt-controller/interrupts.txt for
+a general description of GPIO and interrupt bindings.
+
+Please refer to pinctrl-bindings.txt in this directory for details of the
+common pinctrl bindings used by client devices, including the meaning of the
+phrase "pin configuration node".
+
+The pin configuration nodes act as a container for an abitrary number of
+subnodes. Each of these subnodes represents some desired configuration for a
+pin, a group, or a list of pins or groups. This configuration can include the
+mux function to select on those pin(s)/group(s), and various pin configuration
+parameters, such as pull-up, drive strength, etc.
+
+
+PIN CONFIGURATION NODES:
+
+The name of each subnode is not important; all subnodes should be enumerated
+and processed purely based on their content.
+
+Each subnode only affects those parameters that are explicitly listed. In
+other words, a subnode that lists a mux function but no pin configuration
+parameters implies no information about any pin configuration parameters.
+Similarly, a pin subnode that describes a pullup parameter implies no
+information about e.g. the mux function.
+
+
+The following generic properties as defined in pinctrl-bindings.txt are valid
+to specify in a pin configuration subnode:
+
+- pins:
+       Usage: required
+       Value type: <string-array>
+       Definition: List of gpio pins affected by the properties specified in
+                   this subnode.  Valid pins are:
+                   gpio0-gpio151,
+                   sdc1_clk,
+                   sdc1_cmd,
+                   sdc1_data
+                   sdc3_clk,
+                   sdc3_cmd,
+                   sdc3_data
+
+- function:
+       Usage: required
+       Value type: <string>
+       Definition: Specify the alternative function to be configured for the
+                   specified pins. Functions are only valid for gpio pins.
+                   Valid values are:
+                   audio_pcm, bt, cam_mclk0, cam_mclk1, cam_mclk2,
+                   codec_mic_i2s, codec_spkr_i2s, ext_gps, fm, gps_blanking,
+                   gps_pps_in, gps_pps_out, gp_clk_0a, gp_clk_0b, gp_clk_1a,
+                   gp_clk_1b, gp_clk_2a, gp_clk_2b, gp_mn, gp_pdm_0a,
+                   gp_pdm_0b, gp_pdm_1a, gp_pdm_1b, gp_pdm_2a, gp_pdm_2b, gpio,
+                   gsbi1, gsbi1_spi_cs1_n, gsbi1_spi_cs2a_n, gsbi1_spi_cs2b_n,
+                   gsbi1_spi_cs3_n, gsbi2, gsbi2_spi_cs1_n, gsbi2_spi_cs2_n,
+                   gsbi2_spi_cs3_n, gsbi3, gsbi4, gsbi4_3d_cam_i2c_l,
+                   gsbi4_3d_cam_i2c_r, gsbi5, gsbi5_3d_cam_i2c_l,
+                   gsbi5_3d_cam_i2c_r, gsbi6, gsbi7, gsbi8, gsbi9, gsbi10,
+                   gsbi11, gsbi11_spi_cs1a_n, gsbi11_spi_cs1b_n,
+                   gsbi11_spi_cs2a_n, gsbi11_spi_cs2b_n, gsbi11_spi_cs3_n,
+                   gsbi12, hdmi_cec, hdmi_ddc_clock, hdmi_ddc_data,
+                   hdmi_hot_plug_detect, hsic, mdp_vsync, mi2s, mic_i2s,
+                   pmb_clk, pmb_ext_ctrl, ps_hold, rpm_wdog, sdc2, sdc4, sdc5,
+                   slimbus1, slimbus2, spkr_i2s, ssbi1, ssbi2, ssbi_ext_gps,
+                   ssbi_pmic2, ssbi_qpa1, ssbi_ts, tsif1, tsif2, ts_eoc,
+                   usb_fs1, usb_fs1_oe, usb_fs1_oe_n, usb_fs2, usb_fs2_oe,
+                   usb_fs2_oe_n, vfe_camif_timer1_a, vfe_camif_timer1_b,
+                   vfe_camif_timer2, vfe_camif_timer3_a, vfe_camif_timer3_b,
+                   vfe_camif_timer4_a, vfe_camif_timer4_b, vfe_camif_timer4_c,
+                   vfe_camif_timer5_a, vfe_camif_timer5_b, vfe_camif_timer6_a,
+                   vfe_camif_timer6_b, vfe_camif_timer6_c, vfe_camif_timer7_a,
+                   vfe_camif_timer7_b, vfe_camif_timer7_c, wlan
+
+- bias-disable:
+       Usage: optional
+       Value type: <none>
+       Definition: The specified pins should be configued as no pull.
+
+- bias-pull-down:
+       Usage: optional
+       Value type: <none>
+       Definition: The specified pins should be configued as pull down.
+
+- bias-pull-up:
+       Usage: optional
+       Value type: <none>
+       Definition: The specified pins should be configued as pull up.
+
+- output-high:
+       Usage: optional
+       Value type: <none>
+       Definition: The specified pins are configured in output mode, driven
+                   high.
+                   Not valid for sdc pins.
+
+- output-low:
+       Usage: optional
+       Value type: <none>
+       Definition: The specified pins are configured in output mode, driven
+                   low.
+                   Not valid for sdc pins.
+
+- drive-strength:
+       Usage: optional
+       Value type: <u32>
+       Definition: Selects the drive strength for the specified pins, in mA.
+                   Valid values are: 2, 4, 6, 8, 10, 12, 14 and 16
+
+Example:
+
+       msmgpio: pinctrl@800000 {
+               compatible = "qcom,msm8960-pinctrl";
+               reg = <0x800000 0x4000>;
+
+               gpio-controller;
+               #gpio-cells = <2>;
+               interrupt-controller;
+               #interrupt-cells = <2>;
+               interrupts = <0 16 0x4>;
+
+               gsbi8_uart: gsbi8-uart {
+                       mux {
+                               pins = "gpio34", "gpio35";
+                               function = "gsbi8";
+                       };
+
+                       tx {
+                               pins = "gpio34";
+                               drive-strength = <4>;
+                               bias-disable;
+                       };
+
+                       rx {
+                               pins = "gpio35";
+                               drive-strength = <2>;
+                               bias-pull-up;
+                       };
+               };
+       };
index 73262b575dfc2481b8cf1925a7652dc9020f656d..d2ea80dc43ebca126558ed3f97d8a395f1b63c7c 100644 (file)
@@ -70,7 +70,7 @@ Valid values for function are:
   cam_mckl0, cam_mclk1, cam_mclk2, cam_mclk3, mdp_vsync, hdmi_cec, hdmi_ddc,
   hdmi_hpd, edp_hpd, gp_pdm0, gp_pdm1, gp_pdm2, gp_pdm3, gp0_clk, gp1_clk,
   gp_mn, tsif1, tsif2, hsic, grfc, audio_ref_clk, qua_mi2s, pri_mi2s, spkr_mi2s,
-  ter_mi2s, sec_mi2s, bt, fm, wlan, slimbus
+  ter_mi2s, sec_mi2s, bt, fm, wlan, slimbus, gpio
 
   (Note that this is not yet the complete list of functions)
 
index 35d2e1f186f0c99ebdab2a66e3c35ce43f4cccc3..daef6fad6a5fb94007a4a0af2d0e4eceb13a47d9 100644 (file)
@@ -15,6 +15,7 @@ Required Properties:
     - "renesas,pfc-r8a7778": for R8A7778 (R-Mobile M1) compatible pin-controller.
     - "renesas,pfc-r8a7779": for R8A7779 (R-Car H1) compatible pin-controller.
     - "renesas,pfc-r8a7790": for R8A7790 (R-Car H2) compatible pin-controller.
+    - "renesas,pfc-r8a7791": for R8A7791 (R-Car M2) compatible pin-controller.
     - "renesas,pfc-sh7372": for SH7372 (SH-Mobile AP4) compatible pin-controller.
     - "renesas,pfc-sh73a0": for SH73A0 (SH-Mobile AG5) compatible pin-controller.
 
index cefef741a40b4e795eee20ae6375a86083427c6d..4658b69d4f4dd3a5876e5967e35edbed6d486eb7 100644 (file)
@@ -21,6 +21,7 @@ defined as gpio sub-nodes of the pinmux controller.
 Required properties for iomux controller:
   - compatible: one of "rockchip,rk2928-pinctrl", "rockchip,rk3066a-pinctrl"
                       "rockchip,rk3066b-pinctrl", "rockchip,rk3188-pinctrl"
+                      "rockchip,rk3288-pinctrl"
   - rockchip,grf: phandle referencing a syscon providing the
         "general register files"
 
@@ -36,7 +37,7 @@ Deprecated properties for iomux controller:
         Use rockchip,grf and rockchip,pmu described above instead.
 
 Required properties for gpio sub nodes:
-  - compatible: "rockchip,gpio-bank", "rockchip,rk3188-gpio-bank0"
+  - compatible: "rockchip,gpio-bank"
   - reg: register of the gpio bank (different than the iomux registerset)
   - interrupts: base interrupt of the gpio bank in the interrupt controller
   - clocks: clock that drives this bank
@@ -50,6 +51,7 @@ Required properties for gpio sub nodes:
     bindings/interrupt-controller/interrupts.txt
 
 Deprecated properties for gpio sub nodes:
+  - compatible: "rockchip,rk3188-gpio-bank0"
   - reg: second element: separate pull register for rk3188 bank0, use
         rockchip,pmu described above instead
 
index 2b32783ba8210dda7fd78b231c512a9e672d694a..e82aaf4925176758437552d0becae0aa530387b7 100644 (file)
@@ -44,7 +44,11 @@ Required Properties:
 - Pin mux/config groups as child nodes: The pin mux (selecting pin function
   mode) and pin config (pull up/down, driver strength) settings are represented
   as child nodes of the pin-controller node. There should be atleast one
-  child node and there is no limit on the count of these child nodes.
+  child node and there is no limit on the count of these child nodes. It is
+  also possible for a child node to consist of several further child nodes
+  to allow grouping multiple pinctrl groups into one. The format of second
+  level child nodes is exactly the same as for first level ones and is
+  described below.
 
   The child node should contain a list of pin(s) on which a particular pin
   function selection or pin configuration (or both) have to applied. This
@@ -71,6 +75,7 @@ Required Properties:
   "samsung,pins" property of the child node. The following pin configuration
   properties are supported.
 
+  - samsung,pin-val: Initial value of pin output buffer.
   - samsung,pin-pud: Pull up/down configuration.
   - samsung,pin-drv: Drive strength configuration.
   - samsung,pin-pud-pdn: Pull up/down configuration in power down mode.
@@ -249,6 +254,23 @@ Example 1: A pin-controller node with pin groups.
                        samsung,pin-pud = <3>;
                        samsung,pin-drv = <0>;
                };
+
+               sd4_bus8: sd4-bus-width8 {
+                       part-1 {
+                               samsung,pins = "gpk0-3", "gpk0-4",
+                                               "gpk0-5", "gpk0-6";
+                               samsung,pin-function = <3>;
+                               samsung,pin-pud = <3>;
+                               samsung,pin-drv = <3>;
+                       };
+                       part-2 {
+                               samsung,pins = "gpk1-3", "gpk1-4",
+                                               "gpk1-5", "gpk1-6";
+                               samsung,pin-function = <4>;
+                               samsung,pin-pud = <4>;
+                               samsung,pin-drv = <3>;
+                       };
+               };
        };
 
 Example 2: A pin-controller node with external wakeup interrupt controller node.
index f5387b4de577ba1b0c73cb85ebeaa6177d685504..597bb5f74dcc5ecccaa664274f672d8608297dac 100644 (file)
 #define MX27_PAD_CONTRAST__GPIO1_30                        0x1e 0x032
 #define MX27_PAD_OE_ACD__OE_ACD                            0x1f 0x004
 #define MX27_PAD_OE_ACD__GPIO1_31                          0x1f 0x032
-#define MX27_PAD_UNUSED0__UNUSED0                          0x20 0x004
-#define MX27_PAD_UNUSED0__GPIO2_0                          0x20 0x032
-#define MX27_PAD_UNUSED1__UNUSED1                          0x21 0x004
-#define MX27_PAD_UNUSED1__GPIO2_1                          0x21 0x032
-#define MX27_PAD_UNUSED2__UNUSED2                          0x22 0x004
-#define MX27_PAD_UNUSED2__GPIO2_2                          0x22 0x032
-#define MX27_PAD_UNUSED3__UNUSED3                          0x23 0x004
-#define MX27_PAD_UNUSED3__GPIO2_3                          0x23 0x032
 #define MX27_PAD_SD2_D0__SD2_D0                            0x24 0x004
 #define MX27_PAD_SD2_D0__MSHC_DATA0                        0x24 0x005
 #define MX27_PAD_SD2_D0__GPIO2_4                           0x24 0x032
 #define MX27_PAD_USBH1_RXDP__USBH1_RXDP                    0x3f 0x004
 #define MX27_PAD_USBH1_RXDP__UART4_RXD                     0x3f 0x001
 #define MX27_PAD_USBH1_RXDP__GPIO2_31                      0x3f 0x032
-#define MX27_PAD_UNUSED4__UNUSED4                          0x40 0x004
-#define MX27_PAD_UNUSED4__GPIO3_0                          0x40 0x032
-#define MX27_PAD_UNUSED5__UNUSED5                          0x41 0x004
-#define MX27_PAD_UNUSED5__GPIO3_1                          0x41 0x032
-#define MX27_PAD_UNUSED6__UNUSED6                          0x42 0x004
-#define MX27_PAD_UNUSED6__GPIO3_2                          0x42 0x032
-#define MX27_PAD_UNUSED7__UNUSED7                          0x43 0x004
-#define MX27_PAD_UNUSED7__GPIO3_3                          0x43 0x032
-#define MX27_PAD_UNUSED8__UNUSED8                          0x44 0x004
-#define MX27_PAD_UNUSED8__GPIO3_4                          0x44 0x032
 #define MX27_PAD_I2C2_SDA__I2C2_SDA                        0x45 0x004
 #define MX27_PAD_I2C2_SDA__GPIO3_5                         0x45 0x032
 #define MX27_PAD_I2C2_SCL__I2C2_SCL                        0x46 0x004
 #define MX27_PAD_USBOTG_CLK__GPIO5_24                      0x98 0x032
 #define MX27_PAD_USBOTG_DATA7__USBOTG_DATA7                0x99 0x004
 #define MX27_PAD_USBOTG_DATA7__GPIO5_25                    0x99 0x032
-#define MX27_PAD_UNUSED9__UNUSED9                          0x9a 0x004
-#define MX27_PAD_UNUSED9__GPIO5_26                         0x9a 0x032
-#define MX27_PAD_UNUSED10__UNUSED10                        0x9b 0x004
-#define MX27_PAD_UNUSED10__GPIO5_27                        0x9b 0x032
-#define MX27_PAD_UNUSED11__UNUSED11                        0x9c 0x004
-#define MX27_PAD_UNUSED11__GPIO5_28                        0x9c 0x032
-#define MX27_PAD_UNUSED12__UNUSED12                        0x9d 0x004
-#define MX27_PAD_UNUSED12__GPIO5_29                        0x9d 0x032
-#define MX27_PAD_UNUSED13__UNUSED13                        0x9e 0x004
-#define MX27_PAD_UNUSED13__GPIO5_30                        0x9e 0x032
-#define MX27_PAD_UNUSED14__UNUSED14                        0x9f 0x004
-#define MX27_PAD_UNUSED14__GPIO5_31                        0x9f 0x032
 #define MX27_PAD_NFRB__NFRB                                0xa0 0x000
 #define MX27_PAD_NFRB__ETMTRACEPKT3                        0xa0 0x005
 #define MX27_PAD_NFRB__GPIO6_0                             0xa0 0x032
 #define MX27_PAD_ATA_DATA15__ETMTRACEPKT4                  0xb7 0x005
 #define MX27_PAD_ATA_DATA15__FEC_TX_EN                     0xb7 0x006
 #define MX27_PAD_ATA_DATA15__GPIO6_23                      0xb7 0x032
-#define MX27_PAD_UNUSED15__UNUSED15                        0xb8 0x004
-#define MX27_PAD_UNUSED15__GPIO6_24                        0xb8 0x032
-#define MX27_PAD_UNUSED16__UNUSED16                        0xb9 0x004
-#define MX27_PAD_UNUSED16__GPIO6_25                        0xb9 0x032
-#define MX27_PAD_UNUSED17__UNUSED17                        0xba 0x004
-#define MX27_PAD_UNUSED17__GPIO6_26                        0xba 0x032
-#define MX27_PAD_UNUSED18__UNUSED18                        0xbb 0x004
-#define MX27_PAD_UNUSED18__GPIO6_27                        0xbb 0x032
-#define MX27_PAD_UNUSED19__UNUSED19                        0xbc 0x004
-#define MX27_PAD_UNUSED19__GPIO6_28                        0xbc 0x032
-#define MX27_PAD_UNUSED20__UNUSED20                        0xbd 0x004
-#define MX27_PAD_UNUSED20__GPIO6_29                        0xbd 0x032
-#define MX27_PAD_UNUSED21__UNUSED21                        0xbe 0x004
-#define MX27_PAD_UNUSED21__GPIO6_30                        0xbe 0x032
-#define MX27_PAD_UNUSED22__UNUSED22                        0xbf 0x004
-#define MX27_PAD_UNUSED22__GPIO6_31                        0xbf 0x032
 
 #endif /* __DTS_IMX27_PINFUNC_H */
index 0fbd4f156bfa9035ff2eb5a9aa8056c72781e35a..d46b9495cd558daead43ba07b476956da42cd241 100644 (file)
@@ -4,7 +4,6 @@ menuconfig ARCH_SUNXI
        select CLKSRC_MMIO
        select GENERIC_IRQ_CHIP
        select PINCTRL
-       select PINCTRL_SUNXI
        select SUN4I_TIMER
 
 if ARCH_SUNXI
index 0042ccb46b9a1277fa2824845e2affb9844505a4..4e3231ad03cde1b0327933c0b0036de3e41e9bb6 100644 (file)
@@ -11,10 +11,10 @@ menu "Pin controllers"
        depends on PINCTRL
 
 config PINMUX
-       bool "Support pin multiplexing controllers"
+       bool "Support pin multiplexing controllers" if COMPILE_TEST
 
 config PINCONF
-       bool "Support pin configuration controllers"
+       bool "Support pin configuration controllers" if COMPILE_TEST
 
 config GENERIC_PINCONF
        bool
@@ -26,29 +26,6 @@ config DEBUG_PINCTRL
        help
          Say Y here to add some extra checks and diagnostics to PINCTRL calls.
 
-config PINCTRL_ABX500
-       bool "ST-Ericsson ABx500 family Mixed Signal Circuit gpio functions"
-       depends on AB8500_CORE
-       select GENERIC_PINCONF
-       help
-         Select this to enable the ABx500 family IC GPIO driver
-
-config PINCTRL_AB8500
-       bool "AB8500 pin controller driver"
-       depends on PINCTRL_ABX500 && ARCH_U8500
-
-config PINCTRL_AB8540
-       bool "AB8540 pin controller driver"
-       depends on PINCTRL_ABX500 && ARCH_U8500
-
-config PINCTRL_AB9540
-       bool "AB9540 pin controller driver"
-       depends on PINCTRL_ABX500 && ARCH_U8500
-
-config PINCTRL_AB8505
-       bool "AB8505 pin controller driver"
-       depends on PINCTRL_ABX500 && ARCH_U8500
-
 config PINCTRL_ADI2
        bool "ADI pin controller driver"
        depends on BLACKFIN
@@ -93,7 +70,7 @@ config PINCTRL_AT91
 config PINCTRL_BAYTRAIL
        bool "Intel Baytrail GPIO pin control"
        depends on GPIOLIB && ACPI && X86
-       select IRQ_DOMAIN
+       select GPIOLIB_IRQCHIP
        help
          driver for memory mapped GPIO functionality on Intel Baytrail
          platforms. Supports 3 banks with 102, 28 and 44 gpios.
@@ -130,6 +107,13 @@ config PINCTRL_IMX1_CORE
        select PINMUX
        select PINCONF
 
+config PINCTRL_IMX1
+       bool "IMX1 pinctrl driver"
+       depends on SOC_IMX1
+       select PINCTRL_IMX1_CORE
+       help
+         Say Y here to enable the imx1 pinctrl driver
+
 config PINCTRL_IMX27
        bool "IMX27 pinctrl driver"
        depends on SOC_IMX27
@@ -226,58 +210,6 @@ config PINCTRL_IMX28
        bool
        select PINCTRL_MXS
 
-config PINCTRL_MSM
-       bool
-       select PINMUX
-       select PINCONF
-       select GENERIC_PINCONF
-       select GPIOLIB_IRQCHIP
-
-config PINCTRL_APQ8064
-       tristate "Qualcomm APQ8064 pin controller driver"
-       depends on GPIOLIB && OF
-       select PINCTRL_MSM
-       help
-         This is the pinctrl, pinmux, pinconf and gpiolib driver for the
-         Qualcomm TLMM block found in the Qualcomm APQ8064 platform.
-
-config PINCTRL_IPQ8064
-       tristate "Qualcomm IPQ8064 pin controller driver"
-       depends on GPIOLIB && OF
-       select PINCTRL_MSM
-       help
-         This is the pinctrl, pinmux, pinconf and gpiolib driver for the
-         Qualcomm TLMM block found in the Qualcomm IPQ8064 platform.
-
-config PINCTRL_MSM8X74
-       tristate "Qualcomm 8x74 pin controller driver"
-       depends on GPIOLIB && OF && (ARCH_QCOM || COMPILE_TEST)
-       select PINCTRL_MSM
-       help
-         This is the pinctrl, pinmux, pinconf and gpiolib driver for the
-         Qualcomm TLMM block found in the Qualcomm 8974 platform.
-
-config PINCTRL_NOMADIK
-       bool "Nomadik pin controller driver"
-       depends on ARCH_U8500 || ARCH_NOMADIK
-       select PINMUX
-       select PINCONF
-       select GPIOLIB
-       select OF_GPIO
-       select GPIOLIB_IRQCHIP
-
-config PINCTRL_STN8815
-       bool "STN8815 pin controller driver"
-       depends on PINCTRL_NOMADIK && ARCH_NOMADIK
-
-config PINCTRL_DB8500
-       bool "DB8500 pin controller driver"
-       depends on PINCTRL_NOMADIK && ARCH_U8500
-
-config PINCTRL_DB8540
-       bool "DB8540 pin controller driver"
-       depends on PINCTRL_NOMADIK && ARCH_U8500
-
 config PINCTRL_ROCKCHIP
        bool
        select PINMUX
@@ -356,22 +288,6 @@ config PINCTRL_COH901
          COH 901 335 and COH 901 571/3. They contain 3, 5 or 7
          ports of 8 GPIO pins each.
 
-config PINCTRL_SAMSUNG
-       bool
-       select PINMUX
-       select PINCONF
-
-config PINCTRL_EXYNOS
-       bool "Pinctrl driver data for Samsung EXYNOS SoCs other than 5440"
-       depends on OF && GPIOLIB && (ARCH_EXYNOS || ARCH_S5PV210)
-       select PINCTRL_SAMSUNG
-
-config PINCTRL_EXYNOS5440
-       bool "Samsung EXYNOS5440 SoC pinctrl driver"
-       depends on SOC_EXYNOS5440
-       select PINMUX
-       select PINCONF
-
 config PINCTRL_PALMAS
        bool "Pinctrl driver for the PALMAS Series MFD devices"
        depends on OF && MFD_PALMAS
@@ -383,18 +299,11 @@ config PINCTRL_PALMAS
          open drain configuration for the Palmas series devices like
          TPS65913, TPS80036 etc.
 
-config PINCTRL_S3C24XX
-       bool "Samsung S3C24XX SoC pinctrl driver"
-       depends on ARCH_S3C24XX
-       select PINCTRL_SAMSUNG
-
-config PINCTRL_S3C64XX
-       bool "Samsung S3C64XX SoC pinctrl driver"
-       depends on ARCH_S3C64XX
-       select PINCTRL_SAMSUNG
-
 source "drivers/pinctrl/berlin/Kconfig"
 source "drivers/pinctrl/mvebu/Kconfig"
+source "drivers/pinctrl/nomadik/Kconfig"
+source "drivers/pinctrl/qcom/Kconfig"
+source "drivers/pinctrl/samsung/Kconfig"
 source "drivers/pinctrl/sh-pfc/Kconfig"
 source "drivers/pinctrl/spear/Kconfig"
 source "drivers/pinctrl/sunxi/Kconfig"
index c4b5d405b8f58d55628d4a80e544bb762efdf430..e90817c1f58425f6d36633e0d89fdae99712b3f6 100644 (file)
@@ -9,11 +9,6 @@ ifeq ($(CONFIG_OF),y)
 obj-$(CONFIG_PINCTRL)          += devicetree.o
 endif
 obj-$(CONFIG_GENERIC_PINCONF)  += pinconf-generic.o
-obj-$(CONFIG_PINCTRL_ABX500)   += pinctrl-abx500.o
-obj-$(CONFIG_PINCTRL_AB8500)   += pinctrl-ab8500.o
-obj-$(CONFIG_PINCTRL_AB8540)   += pinctrl-ab8540.o
-obj-$(CONFIG_PINCTRL_AB9540)   += pinctrl-ab9540.o
-obj-$(CONFIG_PINCTRL_AB8505)   += pinctrl-ab8505.o
 obj-$(CONFIG_PINCTRL_ADI2)     += pinctrl-adi2.o
 obj-$(CONFIG_PINCTRL_AS3722)   += pinctrl-as3722.o
 obj-$(CONFIG_PINCTRL_BF54x)    += pinctrl-adi2-bf54x.o
@@ -24,6 +19,7 @@ obj-$(CONFIG_PINCTRL_BAYTRAIL)        += pinctrl-baytrail.o
 obj-$(CONFIG_PINCTRL_BCM281XX) += pinctrl-bcm281xx.o
 obj-$(CONFIG_PINCTRL_IMX)      += pinctrl-imx.o
 obj-$(CONFIG_PINCTRL_IMX1_CORE)        += pinctrl-imx1-core.o
+obj-$(CONFIG_PINCTRL_IMX1)     += pinctrl-imx1.o
 obj-$(CONFIG_PINCTRL_IMX27)    += pinctrl-imx27.o
 obj-$(CONFIG_PINCTRL_IMX35)    += pinctrl-imx35.o
 obj-$(CONFIG_PINCTRL_IMX50)    += pinctrl-imx50.o
@@ -38,14 +34,6 @@ obj-$(CONFIG_PINCTRL_MXS)    += pinctrl-mxs.o
 obj-$(CONFIG_PINCTRL_IMX23)    += pinctrl-imx23.o
 obj-$(CONFIG_PINCTRL_IMX25)    += pinctrl-imx25.o
 obj-$(CONFIG_PINCTRL_IMX28)    += pinctrl-imx28.o
-obj-$(CONFIG_PINCTRL_MSM)      += pinctrl-msm.o
-obj-$(CONFIG_PINCTRL_APQ8064)  += pinctrl-apq8064.o
-obj-$(CONFIG_PINCTRL_IPQ8064)  += pinctrl-ipq8064.o
-obj-$(CONFIG_PINCTRL_MSM8X74)  += pinctrl-msm8x74.o
-obj-$(CONFIG_PINCTRL_NOMADIK)  += pinctrl-nomadik.o
-obj-$(CONFIG_PINCTRL_STN8815)  += pinctrl-nomadik-stn8815.o
-obj-$(CONFIG_PINCTRL_DB8500)   += pinctrl-nomadik-db8500.o
-obj-$(CONFIG_PINCTRL_DB8540)   += pinctrl-nomadik-db8540.o
 obj-$(CONFIG_PINCTRL_PALMAS)   += pinctrl-palmas.o
 obj-$(CONFIG_PINCTRL_ROCKCHIP) += pinctrl-rockchip.o
 obj-$(CONFIG_PINCTRL_SINGLE)   += pinctrl-single.o
@@ -59,11 +47,6 @@ obj-$(CONFIG_PINCTRL_TZ1090) += pinctrl-tz1090.o
 obj-$(CONFIG_PINCTRL_TZ1090_PDC)       += pinctrl-tz1090-pdc.o
 obj-$(CONFIG_PINCTRL_U300)     += pinctrl-u300.o
 obj-$(CONFIG_PINCTRL_COH901)   += pinctrl-coh901.o
-obj-$(CONFIG_PINCTRL_SAMSUNG)  += pinctrl-samsung.o
-obj-$(CONFIG_PINCTRL_EXYNOS)   += pinctrl-exynos.o
-obj-$(CONFIG_PINCTRL_EXYNOS5440)       += pinctrl-exynos5440.o
-obj-$(CONFIG_PINCTRL_S3C24XX)  += pinctrl-s3c24xx.o
-obj-$(CONFIG_PINCTRL_S3C64XX)  += pinctrl-s3c64xx.o
 obj-$(CONFIG_PINCTRL_XWAY)     += pinctrl-xway.o
 obj-$(CONFIG_PINCTRL_LANTIQ)   += pinctrl-lantiq.o
 obj-$(CONFIG_PINCTRL_TB10X)    += pinctrl-tb10x.o
@@ -72,8 +55,11 @@ obj-$(CONFIG_PINCTRL_VF610)  += pinctrl-vf610.o
 
 obj-$(CONFIG_ARCH_BERLIN)      += berlin/
 obj-$(CONFIG_PLAT_ORION)        += mvebu/
+obj-y                          += nomadik/
+obj-$(CONFIG_ARCH_QCOM)                += qcom/
+obj-$(CONFIG_PLAT_SAMSUNG)     += samsung/
 obj-$(CONFIG_ARCH_SHMOBILE)    += sh-pfc/
 obj-$(CONFIG_SUPERH)           += sh-pfc/
 obj-$(CONFIG_PLAT_SPEAR)       += spear/
-obj-$(CONFIG_ARCH_VT8500)      += vt8500/
 obj-$(CONFIG_ARCH_SUNXI)       += sunxi/
+obj-$(CONFIG_ARCH_VT8500)      += vt8500/
index e09474ecde2346bd900d8f9d05ba3c26c63f9aa9..e4f65510c87e8928666e195b6b76e52cae9252b5 100644 (file)
@@ -992,29 +992,15 @@ int pinctrl_select_state(struct pinctrl *p, struct pinctrl_state *state)
 
        if (p->state) {
                /*
-                * The set of groups with a mux configuration in the old state
-                * may not be identical to the set of groups with a mux setting
-                * in the new state. While this might be unusual, it's entirely
-                * possible for the "user"-supplied mapping table to be written
-                * that way. For each group that was configured in the old state
-                * but not in the new state, this code puts that group into a
-                * safe/disabled state.
+                * For each pinmux setting in the old state, forget SW's record
+                * of mux owner for that pingroup. Any pingroups which are
+                * still owned by the new state will be re-acquired by the call
+                * to pinmux_enable_setting() in the loop below.
                 */
                list_for_each_entry(setting, &p->state->settings, node) {
-                       bool found = false;
                        if (setting->type != PIN_MAP_TYPE_MUX_GROUP)
                                continue;
-                       list_for_each_entry(setting2, &state->settings, node) {
-                               if (setting2->type != PIN_MAP_TYPE_MUX_GROUP)
-                                       continue;
-                               if (setting2->data.mux.group ==
-                                               setting->data.mux.group) {
-                                       found = true;
-                                       break;
-                               }
-                       }
-                       if (!found)
-                               pinmux_disable_setting(setting);
+                       pinmux_disable_setting(setting);
                }
        }
 
diff --git a/drivers/pinctrl/nomadik/Kconfig b/drivers/pinctrl/nomadik/Kconfig
new file mode 100644 (file)
index 0000000..d48a5aa
--- /dev/null
@@ -0,0 +1,51 @@
+if ARCH_U8500
+
+config PINCTRL_ABX500
+       bool "ST-Ericsson ABx500 family Mixed Signal Circuit gpio functions"
+       depends on AB8500_CORE
+       select GENERIC_PINCONF
+       help
+         Select this to enable the ABx500 family IC GPIO driver
+
+config PINCTRL_AB8500
+       bool "AB8500 pin controller driver"
+       depends on PINCTRL_ABX500 && ARCH_U8500
+
+config PINCTRL_AB8540
+       bool "AB8540 pin controller driver"
+       depends on PINCTRL_ABX500 && ARCH_U8500
+
+config PINCTRL_AB9540
+       bool "AB9540 pin controller driver"
+       depends on PINCTRL_ABX500 && ARCH_U8500
+
+config PINCTRL_AB8505
+       bool "AB8505 pin controller driver"
+       depends on PINCTRL_ABX500 && ARCH_U8500
+
+endif
+
+if (ARCH_U8500 || ARCH_NOMADIK)
+
+config PINCTRL_NOMADIK
+       bool "Nomadik pin controller driver"
+       depends on ARCH_U8500 || ARCH_NOMADIK
+       select PINMUX
+       select PINCONF
+       select GPIOLIB
+       select OF_GPIO
+       select GPIOLIB_IRQCHIP
+
+config PINCTRL_STN8815
+       bool "STN8815 pin controller driver"
+       depends on PINCTRL_NOMADIK && ARCH_NOMADIK
+
+config PINCTRL_DB8500
+       bool "DB8500 pin controller driver"
+       depends on PINCTRL_NOMADIK && ARCH_U8500
+
+config PINCTRL_DB8540
+       bool "DB8540 pin controller driver"
+       depends on PINCTRL_NOMADIK && ARCH_U8500
+
+endif
diff --git a/drivers/pinctrl/nomadik/Makefile b/drivers/pinctrl/nomadik/Makefile
new file mode 100644 (file)
index 0000000..30b27f1
--- /dev/null
@@ -0,0 +1,10 @@
+# Nomadik family pin control drivers
+obj-$(CONFIG_PINCTRL_ABX500)   += pinctrl-abx500.o
+obj-$(CONFIG_PINCTRL_AB8500)   += pinctrl-ab8500.o
+obj-$(CONFIG_PINCTRL_AB8540)   += pinctrl-ab8540.o
+obj-$(CONFIG_PINCTRL_AB9540)   += pinctrl-ab9540.o
+obj-$(CONFIG_PINCTRL_AB8505)   += pinctrl-ab8505.o
+obj-$(CONFIG_PINCTRL_NOMADIK)  += pinctrl-nomadik.o
+obj-$(CONFIG_PINCTRL_STN8815)  += pinctrl-nomadik-stn8815.o
+obj-$(CONFIG_PINCTRL_DB8500)   += pinctrl-nomadik-db8500.o
+obj-$(CONFIG_PINCTRL_DB8540)   += pinctrl-nomadik-db8540.o
diff --git a/drivers/pinctrl/nomadik/pinctrl-ab8500.c b/drivers/pinctrl/nomadik/pinctrl-ab8500.c
new file mode 100644 (file)
index 0000000..2ac2d0a
--- /dev/null
@@ -0,0 +1,485 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2012
+ *
+ * Author: Patrice Chotard <patrice.chotard@stericsson.com> for ST-Ericsson.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/mfd/abx500/ab8500.h>
+#include "pinctrl-abx500.h"
+
+/* All the pins that can be used for GPIO and some other functions */
+#define ABX500_GPIO(offset)            (offset)
+
+#define AB8500_PIN_T10         ABX500_GPIO(1)
+#define AB8500_PIN_T9          ABX500_GPIO(2)
+#define AB8500_PIN_U9          ABX500_GPIO(3)
+#define AB8500_PIN_W2          ABX500_GPIO(4)
+/* hole */
+#define AB8500_PIN_Y18         ABX500_GPIO(6)
+#define AB8500_PIN_AA20                ABX500_GPIO(7)
+#define AB8500_PIN_W18         ABX500_GPIO(8)
+#define AB8500_PIN_AA19                ABX500_GPIO(9)
+#define AB8500_PIN_U17         ABX500_GPIO(10)
+#define AB8500_PIN_AA18                ABX500_GPIO(11)
+#define AB8500_PIN_U16         ABX500_GPIO(12)
+#define AB8500_PIN_W17         ABX500_GPIO(13)
+#define AB8500_PIN_F14         ABX500_GPIO(14)
+#define AB8500_PIN_B17         ABX500_GPIO(15)
+#define AB8500_PIN_F15         ABX500_GPIO(16)
+#define AB8500_PIN_P5          ABX500_GPIO(17)
+#define AB8500_PIN_R5          ABX500_GPIO(18)
+#define AB8500_PIN_U5          ABX500_GPIO(19)
+#define AB8500_PIN_T5          ABX500_GPIO(20)
+#define AB8500_PIN_H19         ABX500_GPIO(21)
+#define AB8500_PIN_G20         ABX500_GPIO(22)
+#define AB8500_PIN_G19         ABX500_GPIO(23)
+#define AB8500_PIN_T14         ABX500_GPIO(24)
+#define AB8500_PIN_R16         ABX500_GPIO(25)
+#define AB8500_PIN_M16         ABX500_GPIO(26)
+#define AB8500_PIN_J6          ABX500_GPIO(27)
+#define AB8500_PIN_K6          ABX500_GPIO(28)
+#define AB8500_PIN_G6          ABX500_GPIO(29)
+#define AB8500_PIN_H6          ABX500_GPIO(30)
+#define AB8500_PIN_F5          ABX500_GPIO(31)
+#define AB8500_PIN_G5          ABX500_GPIO(32)
+/* hole */
+#define AB8500_PIN_R17         ABX500_GPIO(34)
+#define AB8500_PIN_W15         ABX500_GPIO(35)
+#define AB8500_PIN_A17         ABX500_GPIO(36)
+#define AB8500_PIN_E15         ABX500_GPIO(37)
+#define AB8500_PIN_C17         ABX500_GPIO(38)
+#define AB8500_PIN_E16         ABX500_GPIO(39)
+#define AB8500_PIN_T19         ABX500_GPIO(40)
+#define AB8500_PIN_U19         ABX500_GPIO(41)
+#define AB8500_PIN_U2          ABX500_GPIO(42)
+
+/* indicates the highest GPIO number */
+#define AB8500_GPIO_MAX_NUMBER 42
+
+/*
+ * The names of the pins are denoted by GPIO number and ball name, even
+ * though they can be used for other things than GPIO, this is the first
+ * column in the table of the data sheet and often used on schematics and
+ * such.
+ */
+static const struct pinctrl_pin_desc ab8500_pins[] = {
+       PINCTRL_PIN(AB8500_PIN_T10, "GPIO1_T10"),
+       PINCTRL_PIN(AB8500_PIN_T9, "GPIO2_T9"),
+       PINCTRL_PIN(AB8500_PIN_U9, "GPIO3_U9"),
+       PINCTRL_PIN(AB8500_PIN_W2, "GPIO4_W2"),
+       /* hole */
+       PINCTRL_PIN(AB8500_PIN_Y18, "GPIO6_Y18"),
+       PINCTRL_PIN(AB8500_PIN_AA20, "GPIO7_AA20"),
+       PINCTRL_PIN(AB8500_PIN_W18, "GPIO8_W18"),
+       PINCTRL_PIN(AB8500_PIN_AA19, "GPIO9_AA19"),
+       PINCTRL_PIN(AB8500_PIN_U17, "GPIO10_U17"),
+       PINCTRL_PIN(AB8500_PIN_AA18, "GPIO11_AA18"),
+       PINCTRL_PIN(AB8500_PIN_U16, "GPIO12_U16"),
+       PINCTRL_PIN(AB8500_PIN_W17, "GPIO13_W17"),
+       PINCTRL_PIN(AB8500_PIN_F14, "GPIO14_F14"),
+       PINCTRL_PIN(AB8500_PIN_B17, "GPIO15_B17"),
+       PINCTRL_PIN(AB8500_PIN_F15, "GPIO16_F15"),
+       PINCTRL_PIN(AB8500_PIN_P5, "GPIO17_P5"),
+       PINCTRL_PIN(AB8500_PIN_R5, "GPIO18_R5"),
+       PINCTRL_PIN(AB8500_PIN_U5, "GPIO19_U5"),
+       PINCTRL_PIN(AB8500_PIN_T5, "GPIO20_T5"),
+       PINCTRL_PIN(AB8500_PIN_H19, "GPIO21_H19"),
+       PINCTRL_PIN(AB8500_PIN_G20, "GPIO22_G20"),
+       PINCTRL_PIN(AB8500_PIN_G19, "GPIO23_G19"),
+       PINCTRL_PIN(AB8500_PIN_T14, "GPIO24_T14"),
+       PINCTRL_PIN(AB8500_PIN_R16, "GPIO25_R16"),
+       PINCTRL_PIN(AB8500_PIN_M16, "GPIO26_M16"),
+       PINCTRL_PIN(AB8500_PIN_J6, "GPIO27_J6"),
+       PINCTRL_PIN(AB8500_PIN_K6, "GPIO28_K6"),
+       PINCTRL_PIN(AB8500_PIN_G6, "GPIO29_G6"),
+       PINCTRL_PIN(AB8500_PIN_H6, "GPIO30_H6"),
+       PINCTRL_PIN(AB8500_PIN_F5, "GPIO31_F5"),
+       PINCTRL_PIN(AB8500_PIN_G5, "GPIO32_G5"),
+       /* hole */
+       PINCTRL_PIN(AB8500_PIN_R17, "GPIO34_R17"),
+       PINCTRL_PIN(AB8500_PIN_W15, "GPIO35_W15"),
+       PINCTRL_PIN(AB8500_PIN_A17, "GPIO36_A17"),
+       PINCTRL_PIN(AB8500_PIN_E15, "GPIO37_E15"),
+       PINCTRL_PIN(AB8500_PIN_C17, "GPIO38_C17"),
+       PINCTRL_PIN(AB8500_PIN_E16, "GPIO39_E16"),
+       PINCTRL_PIN(AB8500_PIN_T19, "GPIO40_T19"),
+       PINCTRL_PIN(AB8500_PIN_U19, "GPIO41_U19"),
+       PINCTRL_PIN(AB8500_PIN_U2, "GPIO42_U2"),
+};
+
+/*
+ * Maps local GPIO offsets to local pin numbers
+ */
+static const struct abx500_pinrange ab8500_pinranges[] = {
+       ABX500_PINRANGE(1, 4, ABX500_ALT_A),
+       ABX500_PINRANGE(6, 4, ABX500_ALT_A),
+       ABX500_PINRANGE(10, 4, ABX500_DEFAULT),
+       ABX500_PINRANGE(14, 12, ABX500_ALT_A),
+       ABX500_PINRANGE(26, 1, ABX500_DEFAULT),
+       ABX500_PINRANGE(27, 6, ABX500_ALT_A),
+       ABX500_PINRANGE(34, 1, ABX500_ALT_A),
+       ABX500_PINRANGE(35, 1, ABX500_DEFAULT),
+       ABX500_PINRANGE(36, 7, ABX500_ALT_A),
+};
+
+/*
+ * Read the pin group names like this:
+ * sysclkreq2_d_1 = first groups of pins for sysclkreq2 on default function
+ *
+ * The groups are arranged as sets per altfunction column, so we can
+ * mux in one group at a time by selecting the same altfunction for them
+ * all. When functions require pins on different altfunctions, you need
+ * to combine several groups.
+ */
+
+/* default column */
+static const unsigned sysclkreq2_d_1_pins[] = { AB8500_PIN_T10 };
+static const unsigned sysclkreq3_d_1_pins[] = { AB8500_PIN_T9 };
+static const unsigned sysclkreq4_d_1_pins[] = { AB8500_PIN_U9 };
+static const unsigned sysclkreq6_d_1_pins[] = { AB8500_PIN_W2 };
+static const unsigned ycbcr0123_d_1_pins[] = { AB8500_PIN_Y18, AB8500_PIN_AA20,
+                                       AB8500_PIN_W18, AB8500_PIN_AA19};
+static const unsigned gpio10_d_1_pins[] = { AB8500_PIN_U17 };
+static const unsigned gpio11_d_1_pins[] = { AB8500_PIN_AA18 };
+static const unsigned gpio12_d_1_pins[] = { AB8500_PIN_U16 };
+static const unsigned gpio13_d_1_pins[] = { AB8500_PIN_W17 };
+static const unsigned pwmout1_d_1_pins[] = { AB8500_PIN_F14 };
+static const unsigned pwmout2_d_1_pins[] = { AB8500_PIN_B17 };
+static const unsigned pwmout3_d_1_pins[] = { AB8500_PIN_F15 };
+
+/* audio data interface 1*/
+static const unsigned adi1_d_1_pins[] = { AB8500_PIN_P5, AB8500_PIN_R5,
+                                       AB8500_PIN_U5, AB8500_PIN_T5 };
+/* USBUICC */
+static const unsigned usbuicc_d_1_pins[] = { AB8500_PIN_H19, AB8500_PIN_G20,
+                                       AB8500_PIN_G19 };
+static const unsigned sysclkreq7_d_1_pins[] = { AB8500_PIN_T14 };
+static const unsigned sysclkreq8_d_1_pins[] = { AB8500_PIN_R16 };
+static const unsigned gpio26_d_1_pins[] = { AB8500_PIN_M16 };
+/* Digital microphone 1 and 2 */
+static const unsigned dmic12_d_1_pins[] = { AB8500_PIN_J6, AB8500_PIN_K6 };
+/* Digital microphone 3 and 4 */
+static const unsigned dmic34_d_1_pins[] = { AB8500_PIN_G6, AB8500_PIN_H6 };
+/* Digital microphone 5 and 6 */
+static const unsigned dmic56_d_1_pins[] = { AB8500_PIN_F5, AB8500_PIN_G5 };
+static const unsigned extcpena_d_1_pins[] = { AB8500_PIN_R17 };
+static const unsigned gpio35_d_1_pins[] = { AB8500_PIN_W15 };
+/* APE SPI */
+static const unsigned apespi_d_1_pins[] = { AB8500_PIN_A17, AB8500_PIN_E15,
+                                       AB8500_PIN_C17, AB8500_PIN_E16};
+/* modem SDA/SCL */
+static const unsigned modsclsda_d_1_pins[] = { AB8500_PIN_T19, AB8500_PIN_U19 };
+static const unsigned sysclkreq5_d_1_pins[] = { AB8500_PIN_U2 };
+
+/* Altfunction A column */
+static const unsigned gpio1_a_1_pins[] = { AB8500_PIN_T10 };
+static const unsigned gpio2_a_1_pins[] = { AB8500_PIN_T9 };
+static const unsigned gpio3_a_1_pins[] = { AB8500_PIN_U9 };
+static const unsigned gpio4_a_1_pins[] = { AB8500_PIN_W2 };
+static const unsigned gpio6_a_1_pins[] = { AB8500_PIN_Y18 };
+static const unsigned gpio7_a_1_pins[] = { AB8500_PIN_AA20 };
+static const unsigned gpio8_a_1_pins[] = { AB8500_PIN_W18 };
+static const unsigned gpio9_a_1_pins[] = { AB8500_PIN_AA19 };
+/* YCbCr4 YCbCr5 YCbCr6 YCbCr7*/
+static const unsigned ycbcr4567_a_1_pins[] = { AB8500_PIN_U17, AB8500_PIN_AA18,
+                                       AB8500_PIN_U16, AB8500_PIN_W17};
+static const unsigned gpio14_a_1_pins[] = { AB8500_PIN_F14 };
+static const unsigned gpio15_a_1_pins[] = { AB8500_PIN_B17 };
+static const unsigned gpio16_a_1_pins[] = { AB8500_PIN_F15 };
+static const unsigned gpio17_a_1_pins[] = { AB8500_PIN_P5 };
+static const unsigned gpio18_a_1_pins[] = { AB8500_PIN_R5 };
+static const unsigned gpio19_a_1_pins[] = { AB8500_PIN_U5 };
+static const unsigned gpio20_a_1_pins[] = { AB8500_PIN_T5 };
+static const unsigned gpio21_a_1_pins[] = { AB8500_PIN_H19 };
+static const unsigned gpio22_a_1_pins[] = { AB8500_PIN_G20 };
+static const unsigned gpio23_a_1_pins[] = { AB8500_PIN_G19 };
+static const unsigned gpio24_a_1_pins[] = { AB8500_PIN_T14 };
+static const unsigned gpio25_a_1_pins[] = { AB8500_PIN_R16 };
+static const unsigned gpio27_a_1_pins[] = { AB8500_PIN_J6 };
+static const unsigned gpio28_a_1_pins[] = { AB8500_PIN_K6 };
+static const unsigned gpio29_a_1_pins[] = { AB8500_PIN_G6 };
+static const unsigned gpio30_a_1_pins[] = { AB8500_PIN_H6 };
+static const unsigned gpio31_a_1_pins[] = { AB8500_PIN_F5 };
+static const unsigned gpio32_a_1_pins[] = { AB8500_PIN_G5 };
+static const unsigned gpio34_a_1_pins[] = { AB8500_PIN_R17 };
+static const unsigned gpio36_a_1_pins[] = { AB8500_PIN_A17 };
+static const unsigned gpio37_a_1_pins[] = { AB8500_PIN_E15 };
+static const unsigned gpio38_a_1_pins[] = { AB8500_PIN_C17 };
+static const unsigned gpio39_a_1_pins[] = { AB8500_PIN_E16 };
+static const unsigned gpio40_a_1_pins[] = { AB8500_PIN_T19 };
+static const unsigned gpio41_a_1_pins[] = { AB8500_PIN_U19 };
+static const unsigned gpio42_a_1_pins[] = { AB8500_PIN_U2 };
+
+/* Altfunction B colum */
+static const unsigned hiqclkena_b_1_pins[] = { AB8500_PIN_U17 };
+static const unsigned usbuiccpd_b_1_pins[] = { AB8500_PIN_AA18 };
+static const unsigned i2ctrig1_b_1_pins[] = { AB8500_PIN_U16 };
+static const unsigned i2ctrig2_b_1_pins[] = { AB8500_PIN_W17 };
+
+/* Altfunction C column */
+static const unsigned usbvdat_c_1_pins[] = { AB8500_PIN_W17 };
+
+
+#define AB8500_PIN_GROUP(a, b) { .name = #a, .pins = a##_pins,         \
+                       .npins = ARRAY_SIZE(a##_pins), .altsetting = b }
+
+static const struct abx500_pingroup ab8500_groups[] = {
+       /* default column */
+       AB8500_PIN_GROUP(sysclkreq2_d_1, ABX500_DEFAULT),
+       AB8500_PIN_GROUP(sysclkreq3_d_1, ABX500_DEFAULT),
+       AB8500_PIN_GROUP(sysclkreq4_d_1, ABX500_DEFAULT),
+       AB8500_PIN_GROUP(sysclkreq6_d_1, ABX500_DEFAULT),
+       AB8500_PIN_GROUP(ycbcr0123_d_1, ABX500_DEFAULT),
+       AB8500_PIN_GROUP(gpio10_d_1, ABX500_DEFAULT),
+       AB8500_PIN_GROUP(gpio11_d_1, ABX500_DEFAULT),
+       AB8500_PIN_GROUP(gpio12_d_1, ABX500_DEFAULT),
+       AB8500_PIN_GROUP(gpio13_d_1, ABX500_DEFAULT),
+       AB8500_PIN_GROUP(pwmout1_d_1, ABX500_DEFAULT),
+       AB8500_PIN_GROUP(pwmout2_d_1, ABX500_DEFAULT),
+       AB8500_PIN_GROUP(pwmout3_d_1, ABX500_DEFAULT),
+       AB8500_PIN_GROUP(adi1_d_1, ABX500_DEFAULT),
+       AB8500_PIN_GROUP(usbuicc_d_1, ABX500_DEFAULT),
+       AB8500_PIN_GROUP(sysclkreq7_d_1, ABX500_DEFAULT),
+       AB8500_PIN_GROUP(sysclkreq8_d_1, ABX500_DEFAULT),
+       AB8500_PIN_GROUP(gpio26_d_1, ABX500_DEFAULT),
+       AB8500_PIN_GROUP(dmic12_d_1, ABX500_DEFAULT),
+       AB8500_PIN_GROUP(dmic34_d_1, ABX500_DEFAULT),
+       AB8500_PIN_GROUP(dmic56_d_1, ABX500_DEFAULT),
+       AB8500_PIN_GROUP(extcpena_d_1, ABX500_DEFAULT),
+       AB8500_PIN_GROUP(gpio35_d_1, ABX500_DEFAULT),
+       AB8500_PIN_GROUP(apespi_d_1, ABX500_DEFAULT),
+       AB8500_PIN_GROUP(modsclsda_d_1, ABX500_DEFAULT),
+       AB8500_PIN_GROUP(sysclkreq5_d_1, ABX500_DEFAULT),
+       /* Altfunction A column */
+       AB8500_PIN_GROUP(gpio1_a_1, ABX500_ALT_A),
+       AB8500_PIN_GROUP(gpio2_a_1, ABX500_ALT_A),
+       AB8500_PIN_GROUP(gpio3_a_1, ABX500_ALT_A),
+       AB8500_PIN_GROUP(gpio4_a_1, ABX500_ALT_A),
+       AB8500_PIN_GROUP(gpio6_a_1, ABX500_ALT_A),
+       AB8500_PIN_GROUP(gpio7_a_1, ABX500_ALT_A),
+       AB8500_PIN_GROUP(gpio8_a_1, ABX500_ALT_A),
+       AB8500_PIN_GROUP(gpio9_a_1, ABX500_ALT_A),
+       AB8500_PIN_GROUP(ycbcr4567_a_1, ABX500_ALT_A),
+       AB8500_PIN_GROUP(gpio14_a_1, ABX500_ALT_A),
+       AB8500_PIN_GROUP(gpio15_a_1, ABX500_ALT_A),
+       AB8500_PIN_GROUP(gpio16_a_1, ABX500_ALT_A),
+       AB8500_PIN_GROUP(gpio17_a_1, ABX500_ALT_A),
+       AB8500_PIN_GROUP(gpio18_a_1, ABX500_ALT_A),
+       AB8500_PIN_GROUP(gpio19_a_1, ABX500_ALT_A),
+       AB8500_PIN_GROUP(gpio20_a_1, ABX500_ALT_A),
+       AB8500_PIN_GROUP(gpio21_a_1, ABX500_ALT_A),
+       AB8500_PIN_GROUP(gpio22_a_1, ABX500_ALT_A),
+       AB8500_PIN_GROUP(gpio23_a_1, ABX500_ALT_A),
+       AB8500_PIN_GROUP(gpio24_a_1, ABX500_ALT_A),
+       AB8500_PIN_GROUP(gpio25_a_1, ABX500_ALT_A),
+       AB8500_PIN_GROUP(gpio27_a_1, ABX500_ALT_A),
+       AB8500_PIN_GROUP(gpio28_a_1, ABX500_ALT_A),
+       AB8500_PIN_GROUP(gpio29_a_1, ABX500_ALT_A),
+       AB8500_PIN_GROUP(gpio30_a_1, ABX500_ALT_A),
+       AB8500_PIN_GROUP(gpio31_a_1, ABX500_ALT_A),
+       AB8500_PIN_GROUP(gpio32_a_1, ABX500_ALT_A),
+       AB8500_PIN_GROUP(gpio34_a_1, ABX500_ALT_A),
+       AB8500_PIN_GROUP(gpio36_a_1, ABX500_ALT_A),
+       AB8500_PIN_GROUP(gpio37_a_1, ABX500_ALT_A),
+       AB8500_PIN_GROUP(gpio38_a_1, ABX500_ALT_A),
+       AB8500_PIN_GROUP(gpio39_a_1, ABX500_ALT_A),
+       AB8500_PIN_GROUP(gpio40_a_1, ABX500_ALT_A),
+       AB8500_PIN_GROUP(gpio41_a_1, ABX500_ALT_A),
+       AB8500_PIN_GROUP(gpio42_a_1, ABX500_ALT_A),
+       /* Altfunction B column */
+       AB8500_PIN_GROUP(hiqclkena_b_1, ABX500_ALT_B),
+       AB8500_PIN_GROUP(usbuiccpd_b_1, ABX500_ALT_B),
+       AB8500_PIN_GROUP(i2ctrig1_b_1, ABX500_ALT_B),
+       AB8500_PIN_GROUP(i2ctrig2_b_1, ABX500_ALT_B),
+       /* Altfunction C column */
+       AB8500_PIN_GROUP(usbvdat_c_1, ABX500_ALT_C),
+};
+
+/* We use this macro to define the groups applicable to a function */
+#define AB8500_FUNC_GROUPS(a, b...)       \
+static const char * const a##_groups[] = { b };
+
+AB8500_FUNC_GROUPS(sysclkreq, "sysclkreq2_d_1", "sysclkreq3_d_1",
+               "sysclkreq4_d_1", "sysclkreq5_d_1", "sysclkreq6_d_1",
+               "sysclkreq7_d_1", "sysclkreq8_d_1");
+AB8500_FUNC_GROUPS(ycbcr, "ycbcr0123_d_1", "ycbcr4567_a_1");
+AB8500_FUNC_GROUPS(gpio, "gpio1_a_1", "gpio2_a_1", "gpio3_a_1", "gpio4_a_1",
+               "gpio6_a_1", "gpio7_a_1", "gpio8_a_1", "gpio9_a_1",
+               "gpio10_d_1", "gpio11_d_1", "gpio12_d_1", "gpio13_d_1",
+               "gpio14_a_1", "gpio15_a_1", "gpio16_a_1", "gpio17_a_1",
+               "gpio18_a_1", "gpio19_a_1", "gpio20_a_1", "gpio21_a_1",
+               "gpio22_a_1", "gpio23_a_1", "gpio24_a_1", "gpio25_a_1",
+               "gpio26_d_1", "gpio27_a_1", "gpio28_a_1", "gpio29_a_1",
+               "gpio30_a_1", "gpio31_a_1", "gpio32_a_1", "gpio34_a_1",
+               "gpio35_d_1", "gpio36_a_1", "gpio37_a_1", "gpio38_a_1",
+               "gpio39_a_1", "gpio40_a_1", "gpio41_a_1", "gpio42_a_1");
+AB8500_FUNC_GROUPS(pwmout, "pwmout1_d_1", "pwmout2_d_1", "pwmout3_d_1");
+AB8500_FUNC_GROUPS(adi1, "adi1_d_1");
+AB8500_FUNC_GROUPS(usbuicc, "usbuicc_d_1", "usbuiccpd_b_1");
+AB8500_FUNC_GROUPS(dmic, "dmic12_d_1", "dmic34_d_1", "dmic56_d_1");
+AB8500_FUNC_GROUPS(extcpena, "extcpena_d_1");
+AB8500_FUNC_GROUPS(apespi, "apespi_d_1");
+AB8500_FUNC_GROUPS(modsclsda, "modsclsda_d_1");
+AB8500_FUNC_GROUPS(hiqclkena, "hiqclkena_b_1");
+AB8500_FUNC_GROUPS(i2ctrig, "i2ctrig1_b_1", "i2ctrig2_b_1");
+AB8500_FUNC_GROUPS(usbvdat, "usbvdat_c_1");
+
+#define FUNCTION(fname)                                        \
+       {                                               \
+               .name = #fname,                         \
+               .groups = fname##_groups,               \
+               .ngroups = ARRAY_SIZE(fname##_groups),  \
+       }
+
+static const struct abx500_function ab8500_functions[] = {
+       FUNCTION(sysclkreq),
+       FUNCTION(ycbcr),
+       FUNCTION(gpio),
+       FUNCTION(pwmout),
+       FUNCTION(adi1),
+       FUNCTION(usbuicc),
+       FUNCTION(dmic),
+       FUNCTION(extcpena),
+       FUNCTION(apespi),
+       FUNCTION(modsclsda),
+       FUNCTION(hiqclkena),
+       FUNCTION(i2ctrig),
+       FUNCTION(usbvdat),
+};
+
+/*
+ * this table translates what's is in the AB8500 specification regarding the
+ * balls alternate functions (as for DB, default, ALT_A, ALT_B and ALT_C).
+ * ALTERNATE_FUNCTIONS(GPIO_NUMBER, GPIOSEL bit, ALTERNATFUNC bit1,
+ * ALTERNATEFUNC bit2, ALTA val, ALTB val, ALTC val),
+ *
+ * example :
+ *
+ *     ALTERNATE_FUNCTIONS(13,     4,      3,      4, 0, 1 ,2),
+ *     means that pin AB8500_PIN_W17 (pin 13) supports 4 mux (default/ALT_A,
+ *     ALT_B and ALT_C), so GPIOSEL and ALTERNATFUNC registers are used to
+ *     select the mux.  ALTA, ALTB and ALTC val indicates values to write in
+ *     ALTERNATFUNC register. We need to specifies these values as SOC
+ *     designers didn't apply the same logic on how to select mux in the
+ *     ABx500 family.
+ *
+ *     As this pins supports at least ALT_B mux, default mux is
+ *     selected by writing 1 in GPIOSEL bit :
+ *
+ *             | GPIOSEL bit=4 | alternatfunc bit2=4 | alternatfunc bit1=3
+ *     default |       1       |          0          |          0
+ *     alt_A   |       0       |          0          |          0
+ *     alt_B   |       0       |          0          |          1
+ *     alt_C   |       0       |          1          |          0
+ *
+ *     ALTERNATE_FUNCTIONS(8,      7, UNUSED, UNUSED),
+ *     means that pin AB8500_PIN_W18 (pin 8) supports 2 mux, so only GPIOSEL
+ *     register is used to select the mux. As this pins doesn't support at
+ *     least ALT_B mux, default mux is by writing 0 in GPIOSEL bit :
+ *
+ *             | GPIOSEL bit=7 | alternatfunc bit2=  | alternatfunc bit1=
+ *     default |       0       |          0          |          0
+ *     alt_A   |       1       |          0          |          0
+ */
+
+static struct
+alternate_functions ab8500_alternate_functions[AB8500_GPIO_MAX_NUMBER + 1] = {
+       ALTERNATE_FUNCTIONS(0, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO0 */
+       ALTERNATE_FUNCTIONS(1,      0, UNUSED, UNUSED, 0, 0, 0), /* GPIO1, altA controlled by bit 0 */
+       ALTERNATE_FUNCTIONS(2,      1, UNUSED, UNUSED, 0, 0, 0), /* GPIO2, altA controlled by bit 1 */
+       ALTERNATE_FUNCTIONS(3,      2, UNUSED, UNUSED, 0, 0, 0), /* GPIO3, altA controlled by bit 2*/
+       ALTERNATE_FUNCTIONS(4,      3, UNUSED, UNUSED, 0, 0, 0), /* GPIO4, altA controlled by bit 3*/
+       /* bit 4 reserved */
+       ALTERNATE_FUNCTIONS(5, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO5 */
+       ALTERNATE_FUNCTIONS(6,      5, UNUSED, UNUSED, 0, 0, 0), /* GPIO6, altA controlled by bit 5*/
+       ALTERNATE_FUNCTIONS(7,      6, UNUSED, UNUSED, 0, 0, 0), /* GPIO7, altA controlled by bit 6*/
+       ALTERNATE_FUNCTIONS(8,      7, UNUSED, UNUSED, 0, 0, 0), /* GPIO8, altA controlled by bit 7*/
+
+       ALTERNATE_FUNCTIONS(9,      0, UNUSED, UNUSED, 0, 0, 0), /* GPIO9, altA controlled by bit 0*/
+       ALTERNATE_FUNCTIONS(10,     1,      0, UNUSED, 0, 1, 0), /* GPIO10, altA and altB controlled by bit 0 */
+       ALTERNATE_FUNCTIONS(11,     2,      1, UNUSED, 0, 1, 0), /* GPIO11, altA and altB controlled by bit 1 */
+       ALTERNATE_FUNCTIONS(12,     3,      2, UNUSED, 0, 1, 0), /* GPIO12, altA and altB controlled by bit 2 */
+       ALTERNATE_FUNCTIONS(13,     4,      3,      4, 0, 1, 2), /* GPIO13, altA altB and altC controlled by bit 3 and 4 */
+       ALTERNATE_FUNCTIONS(14,     5, UNUSED, UNUSED, 0, 0, 0), /* GPIO14, altA controlled by bit 5 */
+       ALTERNATE_FUNCTIONS(15,     6, UNUSED, UNUSED, 0, 0, 0), /* GPIO15, altA controlled by bit 6 */
+       ALTERNATE_FUNCTIONS(16,     7, UNUSED, UNUSED, 0, 0, 0), /* GPIO16, altA controlled by bit 7 */
+       /*
+        * pins 17 to 20 are special case, only bit 0 is used to select
+        * alternate function for these 4 pins.
+        * bits 1 to 3 are reserved
+        */
+       ALTERNATE_FUNCTIONS(17,      0, UNUSED, UNUSED, 0, 0, 0), /* GPIO17, altA controlled by bit 0 */
+       ALTERNATE_FUNCTIONS(18,      0, UNUSED, UNUSED, 0, 0, 0), /* GPIO18, altA controlled by bit 0 */
+       ALTERNATE_FUNCTIONS(19,      0, UNUSED, UNUSED, 0, 0, 0), /* GPIO19, altA controlled by bit 0 */
+       ALTERNATE_FUNCTIONS(20,      0, UNUSED, UNUSED, 0, 0, 0), /* GPIO20, altA controlled by bit 0 */
+       ALTERNATE_FUNCTIONS(21,      4, UNUSED, UNUSED, 0, 0, 0), /* GPIO21, altA controlled by bit 4 */
+       ALTERNATE_FUNCTIONS(22,      5, UNUSED, UNUSED, 0, 0, 0), /* GPIO22, altA controlled by bit 5 */
+       ALTERNATE_FUNCTIONS(23,      6, UNUSED, UNUSED, 0, 0, 0), /* GPIO23, altA controlled by bit 6 */
+       ALTERNATE_FUNCTIONS(24,      7, UNUSED, UNUSED, 0, 0, 0), /* GPIO24, altA controlled by bit 7 */
+
+       ALTERNATE_FUNCTIONS(25,      0, UNUSED, UNUSED, 0, 0, 0), /* GPIO25, altA controlled by bit 0 */
+       /* pin 26 special case, no alternate function, bit 1 reserved */
+       ALTERNATE_FUNCTIONS(26, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* GPIO26 */
+       ALTERNATE_FUNCTIONS(27,      2, UNUSED, UNUSED, 0, 0, 0), /* GPIO27, altA controlled by bit 2 */
+       ALTERNATE_FUNCTIONS(28,      3, UNUSED, UNUSED, 0, 0, 0), /* GPIO28, altA controlled by bit 3 */
+       ALTERNATE_FUNCTIONS(29,      4, UNUSED, UNUSED, 0, 0, 0), /* GPIO29, altA controlled by bit 4 */
+       ALTERNATE_FUNCTIONS(30,      5, UNUSED, UNUSED, 0, 0, 0), /* GPIO30, altA controlled by bit 5 */
+       ALTERNATE_FUNCTIONS(31,      6, UNUSED, UNUSED, 0, 0, 0), /* GPIO31, altA controlled by bit 6 */
+       ALTERNATE_FUNCTIONS(32,      7, UNUSED, UNUSED, 0, 0, 0), /* GPIO32, altA controlled by bit 7 */
+
+       ALTERNATE_FUNCTIONS(33, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO33 */
+       ALTERNATE_FUNCTIONS(34,      1, UNUSED, UNUSED, 0, 0, 0), /* GPIO34, altA controlled by bit 1 */
+       /* pin 35 special case, no alternate function, bit 2 reserved */
+       ALTERNATE_FUNCTIONS(35, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* GPIO35 */
+       ALTERNATE_FUNCTIONS(36,      3, UNUSED, UNUSED, 0, 0, 0), /* GPIO36, altA controlled by bit 3 */
+       ALTERNATE_FUNCTIONS(37,      4, UNUSED, UNUSED, 0, 0, 0), /* GPIO37, altA controlled by bit 4 */
+       ALTERNATE_FUNCTIONS(38,      5, UNUSED, UNUSED, 0, 0, 0), /* GPIO38, altA controlled by bit 5 */
+       ALTERNATE_FUNCTIONS(39,      6, UNUSED, UNUSED, 0, 0, 0), /* GPIO39, altA controlled by bit 6 */
+       ALTERNATE_FUNCTIONS(40,      7, UNUSED, UNUSED, 0, 0, 0), /* GPIO40, altA controlled by bit 7 */
+
+       ALTERNATE_FUNCTIONS(41,      0, UNUSED, UNUSED, 0, 0, 0), /* GPIO41, altA controlled by bit 0 */
+       ALTERNATE_FUNCTIONS(42,      1, UNUSED, UNUSED, 0, 0, 0), /* GPIO42, altA controlled by bit 1 */
+};
+
+/*
+ * Only some GPIOs are interrupt capable, and they are
+ * organized in discontiguous clusters:
+ *
+ *     GPIO6 to GPIO13
+ *     GPIO24 and GPIO25
+ *     GPIO36 to GPIO41
+ */
+static struct abx500_gpio_irq_cluster ab8500_gpio_irq_cluster[] = {
+       GPIO_IRQ_CLUSTER(6,  13, AB8500_INT_GPIO6R),
+       GPIO_IRQ_CLUSTER(24, 25, AB8500_INT_GPIO24R),
+       GPIO_IRQ_CLUSTER(36, 41, AB8500_INT_GPIO36R),
+};
+
+static struct abx500_pinctrl_soc_data ab8500_soc = {
+       .gpio_ranges = ab8500_pinranges,
+       .gpio_num_ranges = ARRAY_SIZE(ab8500_pinranges),
+       .pins = ab8500_pins,
+       .npins = ARRAY_SIZE(ab8500_pins),
+       .functions = ab8500_functions,
+       .nfunctions = ARRAY_SIZE(ab8500_functions),
+       .groups = ab8500_groups,
+       .ngroups = ARRAY_SIZE(ab8500_groups),
+       .alternate_functions = ab8500_alternate_functions,
+       .gpio_irq_cluster = ab8500_gpio_irq_cluster,
+       .ngpio_irq_cluster = ARRAY_SIZE(ab8500_gpio_irq_cluster),
+       .irq_gpio_rising_offset = AB8500_INT_GPIO6R,
+       .irq_gpio_falling_offset = AB8500_INT_GPIO6F,
+       .irq_gpio_factor = 1,
+};
+
+void abx500_pinctrl_ab8500_init(struct abx500_pinctrl_soc_data **soc)
+{
+       *soc = &ab8500_soc;
+}
diff --git a/drivers/pinctrl/nomadik/pinctrl-ab8505.c b/drivers/pinctrl/nomadik/pinctrl-ab8505.c
new file mode 100644 (file)
index 0000000..bf0ef4a
--- /dev/null
@@ -0,0 +1,381 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2012
+ *
+ * Author: Patrice Chotard <patrice.chotard@stericsson.com> for ST-Ericsson.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/mfd/abx500/ab8500.h>
+#include "pinctrl-abx500.h"
+
+/* All the pins that can be used for GPIO and some other functions */
+#define ABX500_GPIO(offset)    (offset)
+
+#define AB8505_PIN_N4          ABX500_GPIO(1)
+#define AB8505_PIN_R5          ABX500_GPIO(2)
+#define AB8505_PIN_P5          ABX500_GPIO(3)
+/* hole */
+#define AB8505_PIN_B16         ABX500_GPIO(10)
+#define AB8505_PIN_B17         ABX500_GPIO(11)
+/* hole */
+#define AB8505_PIN_D17         ABX500_GPIO(13)
+#define AB8505_PIN_C16         ABX500_GPIO(14)
+/* hole */
+#define AB8505_PIN_P2          ABX500_GPIO(17)
+#define AB8505_PIN_N3          ABX500_GPIO(18)
+#define AB8505_PIN_T1          ABX500_GPIO(19)
+#define AB8505_PIN_P3          ABX500_GPIO(20)
+/* hole */
+#define AB8505_PIN_H14         ABX500_GPIO(34)
+/* hole */
+#define AB8505_PIN_J15         ABX500_GPIO(40)
+#define AB8505_PIN_J14         ABX500_GPIO(41)
+/* hole */
+#define AB8505_PIN_L4          ABX500_GPIO(50)
+/* hole */
+#define AB8505_PIN_D16         ABX500_GPIO(52)
+#define AB8505_PIN_D15         ABX500_GPIO(53)
+
+/* indicates the higher GPIO number */
+#define AB8505_GPIO_MAX_NUMBER 53
+
+/*
+ * The names of the pins are denoted by GPIO number and ball name, even
+ * though they can be used for other things than GPIO, this is the first
+ * column in the table of the data sheet and often used on schematics and
+ * such.
+ */
+static const struct pinctrl_pin_desc ab8505_pins[] = {
+       PINCTRL_PIN(AB8505_PIN_N4, "GPIO1_N4"),
+       PINCTRL_PIN(AB8505_PIN_R5, "GPIO2_R5"),
+       PINCTRL_PIN(AB8505_PIN_P5, "GPIO3_P5"),
+/* hole */
+       PINCTRL_PIN(AB8505_PIN_B16, "GPIO10_B16"),
+       PINCTRL_PIN(AB8505_PIN_B17, "GPIO11_B17"),
+/* hole */
+       PINCTRL_PIN(AB8505_PIN_D17, "GPIO13_D17"),
+       PINCTRL_PIN(AB8505_PIN_C16, "GPIO14_C16"),
+/* hole */
+       PINCTRL_PIN(AB8505_PIN_P2, "GPIO17_P2"),
+       PINCTRL_PIN(AB8505_PIN_N3, "GPIO18_N3"),
+       PINCTRL_PIN(AB8505_PIN_T1, "GPIO19_T1"),
+       PINCTRL_PIN(AB8505_PIN_P3, "GPIO20_P3"),
+/* hole */
+       PINCTRL_PIN(AB8505_PIN_H14, "GPIO34_H14"),
+/* hole */
+       PINCTRL_PIN(AB8505_PIN_J15, "GPIO40_J15"),
+       PINCTRL_PIN(AB8505_PIN_J14, "GPIO41_J14"),
+/* hole */
+       PINCTRL_PIN(AB8505_PIN_L4, "GPIO50_L4"),
+/* hole */
+       PINCTRL_PIN(AB8505_PIN_D16, "GPIO52_D16"),
+       PINCTRL_PIN(AB8505_PIN_D15, "GPIO53_D15"),
+};
+
+/*
+ * Maps local GPIO offsets to local pin numbers
+ */
+static const struct abx500_pinrange ab8505_pinranges[] = {
+       ABX500_PINRANGE(1, 3, ABX500_ALT_A),
+       ABX500_PINRANGE(10, 2, ABX500_DEFAULT),
+       ABX500_PINRANGE(13, 1, ABX500_DEFAULT),
+       ABX500_PINRANGE(14, 1, ABX500_ALT_A),
+       ABX500_PINRANGE(17, 4, ABX500_ALT_A),
+       ABX500_PINRANGE(34, 1, ABX500_ALT_A),
+       ABX500_PINRANGE(40, 2, ABX500_ALT_A),
+       ABX500_PINRANGE(50, 1, ABX500_DEFAULT),
+       ABX500_PINRANGE(52, 2, ABX500_ALT_A),
+};
+
+/*
+ * Read the pin group names like this:
+ * sysclkreq2_d_1 = first groups of pins for sysclkreq2 on default function
+ *
+ * The groups are arranged as sets per altfunction column, so we can
+ * mux in one group at a time by selecting the same altfunction for them
+ * all. When functions require pins on different altfunctions, you need
+ * to combine several groups.
+ */
+
+/* default column */
+static const unsigned sysclkreq2_d_1_pins[] = { AB8505_PIN_N4 };
+static const unsigned sysclkreq3_d_1_pins[] = { AB8505_PIN_R5 };
+static const unsigned sysclkreq4_d_1_pins[] = { AB8505_PIN_P5 };
+static const unsigned gpio10_d_1_pins[] = { AB8505_PIN_B16 };
+static const unsigned gpio11_d_1_pins[] = { AB8505_PIN_B17 };
+static const unsigned gpio13_d_1_pins[] = { AB8505_PIN_D17 };
+static const unsigned pwmout1_d_1_pins[] = { AB8505_PIN_C16 };
+/* audio data interface 2*/
+static const unsigned adi2_d_1_pins[] = { AB8505_PIN_P2, AB8505_PIN_N3,
+                                       AB8505_PIN_T1, AB8505_PIN_P3 };
+static const unsigned extcpena_d_1_pins[] = { AB8505_PIN_H14 };
+/* modem SDA/SCL */
+static const unsigned modsclsda_d_1_pins[] = { AB8505_PIN_J15, AB8505_PIN_J14 };
+static const unsigned gpio50_d_1_pins[] = { AB8505_PIN_L4 };
+static const unsigned resethw_d_1_pins[] = { AB8505_PIN_D16 };
+static const unsigned service_d_1_pins[] = { AB8505_PIN_D15 };
+
+/* Altfunction A column */
+static const unsigned gpio1_a_1_pins[] = { AB8505_PIN_N4 };
+static const unsigned gpio2_a_1_pins[] = { AB8505_PIN_R5 };
+static const unsigned gpio3_a_1_pins[] = { AB8505_PIN_P5 };
+static const unsigned hiqclkena_a_1_pins[] = { AB8505_PIN_B16 };
+static const unsigned pdmclk_a_1_pins[] = { AB8505_PIN_B17 };
+static const unsigned uarttxdata_a_1_pins[] = { AB8505_PIN_D17 };
+static const unsigned gpio14_a_1_pins[] = { AB8505_PIN_C16 };
+static const unsigned gpio17_a_1_pins[] = { AB8505_PIN_P2 };
+static const unsigned gpio18_a_1_pins[] = { AB8505_PIN_N3 };
+static const unsigned gpio19_a_1_pins[] = { AB8505_PIN_T1 };
+static const unsigned gpio20_a_1_pins[] = { AB8505_PIN_P3 };
+static const unsigned gpio34_a_1_pins[] = { AB8505_PIN_H14 };
+static const unsigned gpio40_a_1_pins[] = { AB8505_PIN_J15 };
+static const unsigned gpio41_a_1_pins[] = { AB8505_PIN_J14 };
+static const unsigned uartrxdata_a_1_pins[] = { AB8505_PIN_J14 };
+static const unsigned gpio50_a_1_pins[] = { AB8505_PIN_L4 };
+static const unsigned gpio52_a_1_pins[] = { AB8505_PIN_D16 };
+static const unsigned gpio53_a_1_pins[] = { AB8505_PIN_D15 };
+
+/* Altfunction B colum */
+static const unsigned pdmdata_b_1_pins[] = { AB8505_PIN_B16 };
+static const unsigned extvibrapwm1_b_1_pins[] = { AB8505_PIN_D17 };
+static const unsigned extvibrapwm2_b_1_pins[] = { AB8505_PIN_L4 };
+
+/* Altfunction C column */
+static const unsigned usbvdat_c_1_pins[] = { AB8505_PIN_D17 };
+
+#define AB8505_PIN_GROUP(a, b) { .name = #a, .pins = a##_pins,         \
+                       .npins = ARRAY_SIZE(a##_pins), .altsetting = b }
+
+static const struct abx500_pingroup ab8505_groups[] = {
+       AB8505_PIN_GROUP(sysclkreq2_d_1, ABX500_DEFAULT),
+       AB8505_PIN_GROUP(sysclkreq3_d_1, ABX500_DEFAULT),
+       AB8505_PIN_GROUP(sysclkreq4_d_1, ABX500_DEFAULT),
+       AB8505_PIN_GROUP(gpio10_d_1, ABX500_DEFAULT),
+       AB8505_PIN_GROUP(gpio11_d_1, ABX500_DEFAULT),
+       AB8505_PIN_GROUP(gpio13_d_1, ABX500_DEFAULT),
+       AB8505_PIN_GROUP(pwmout1_d_1, ABX500_DEFAULT),
+       AB8505_PIN_GROUP(adi2_d_1, ABX500_DEFAULT),
+       AB8505_PIN_GROUP(extcpena_d_1, ABX500_DEFAULT),
+       AB8505_PIN_GROUP(modsclsda_d_1, ABX500_DEFAULT),
+       AB8505_PIN_GROUP(gpio50_d_1, ABX500_DEFAULT),
+       AB8505_PIN_GROUP(resethw_d_1, ABX500_DEFAULT),
+       AB8505_PIN_GROUP(service_d_1, ABX500_DEFAULT),
+       AB8505_PIN_GROUP(gpio1_a_1, ABX500_ALT_A),
+       AB8505_PIN_GROUP(gpio2_a_1, ABX500_ALT_A),
+       AB8505_PIN_GROUP(gpio3_a_1, ABX500_ALT_A),
+       AB8505_PIN_GROUP(hiqclkena_a_1, ABX500_ALT_A),
+       AB8505_PIN_GROUP(pdmclk_a_1, ABX500_ALT_A),
+       AB8505_PIN_GROUP(uarttxdata_a_1, ABX500_ALT_A),
+       AB8505_PIN_GROUP(gpio14_a_1, ABX500_ALT_A),
+       AB8505_PIN_GROUP(gpio17_a_1, ABX500_ALT_A),
+       AB8505_PIN_GROUP(gpio18_a_1, ABX500_ALT_A),
+       AB8505_PIN_GROUP(gpio19_a_1, ABX500_ALT_A),
+       AB8505_PIN_GROUP(gpio20_a_1, ABX500_ALT_A),
+       AB8505_PIN_GROUP(gpio34_a_1, ABX500_ALT_A),
+       AB8505_PIN_GROUP(gpio40_a_1, ABX500_ALT_A),
+       AB8505_PIN_GROUP(gpio41_a_1, ABX500_ALT_A),
+       AB8505_PIN_GROUP(uartrxdata_a_1, ABX500_ALT_A),
+       AB8505_PIN_GROUP(gpio52_a_1, ABX500_ALT_A),
+       AB8505_PIN_GROUP(gpio53_a_1, ABX500_ALT_A),
+       AB8505_PIN_GROUP(pdmdata_b_1, ABX500_ALT_B),
+       AB8505_PIN_GROUP(extvibrapwm1_b_1, ABX500_ALT_B),
+       AB8505_PIN_GROUP(extvibrapwm2_b_1, ABX500_ALT_B),
+       AB8505_PIN_GROUP(usbvdat_c_1, ABX500_ALT_C),
+};
+
+/* We use this macro to define the groups applicable to a function */
+#define AB8505_FUNC_GROUPS(a, b...)       \
+static const char * const a##_groups[] = { b };
+
+AB8505_FUNC_GROUPS(sysclkreq, "sysclkreq2_d_1", "sysclkreq3_d_1",
+               "sysclkreq4_d_1");
+AB8505_FUNC_GROUPS(gpio, "gpio1_a_1", "gpio2_a_1", "gpio3_a_1",
+               "gpio10_d_1", "gpio11_d_1", "gpio13_d_1", "gpio14_a_1",
+               "gpio17_a_1", "gpio18_a_1", "gpio19_a_1", "gpio20_a_1",
+               "gpio34_a_1", "gpio40_a_1", "gpio41_a_1", "gpio50_d_1",
+               "gpio52_a_1", "gpio53_a_1");
+AB8505_FUNC_GROUPS(pwmout, "pwmout1_d_1");
+AB8505_FUNC_GROUPS(adi2, "adi2_d_1");
+AB8505_FUNC_GROUPS(extcpena, "extcpena_d_1");
+AB8505_FUNC_GROUPS(modsclsda, "modsclsda_d_1");
+AB8505_FUNC_GROUPS(resethw, "resethw_d_1");
+AB8505_FUNC_GROUPS(service, "service_d_1");
+AB8505_FUNC_GROUPS(hiqclkena, "hiqclkena_a_1");
+AB8505_FUNC_GROUPS(pdm, "pdmclk_a_1", "pdmdata_b_1");
+AB8505_FUNC_GROUPS(uartdata, "uarttxdata_a_1", "uartrxdata_a_1");
+AB8505_FUNC_GROUPS(extvibra, "extvibrapwm1_b_1", "extvibrapwm2_b_1");
+AB8505_FUNC_GROUPS(usbvdat, "usbvdat_c_1");
+
+#define FUNCTION(fname)                                        \
+       {                                               \
+               .name = #fname,                         \
+               .groups = fname##_groups,               \
+               .ngroups = ARRAY_SIZE(fname##_groups),  \
+       }
+
+static const struct abx500_function ab8505_functions[] = {
+       FUNCTION(sysclkreq),
+       FUNCTION(gpio),
+       FUNCTION(pwmout),
+       FUNCTION(adi2),
+       FUNCTION(extcpena),
+       FUNCTION(modsclsda),
+       FUNCTION(resethw),
+       FUNCTION(service),
+       FUNCTION(hiqclkena),
+       FUNCTION(pdm),
+       FUNCTION(uartdata),
+       FUNCTION(extvibra),
+       FUNCTION(extvibra),
+       FUNCTION(usbvdat),
+};
+
+/*
+ * this table translates what's is in the AB8505 specification regarding the
+ * balls alternate functions (as for DB, default, ALT_A, ALT_B and ALT_C).
+ * ALTERNATE_FUNCTIONS(GPIO_NUMBER, GPIOSEL bit, ALTERNATFUNC bit1,
+ * ALTERNATEFUNC bit2, ALTA val, ALTB val, ALTC val),
+ *
+ * example :
+ *
+ *     ALTERNATE_FUNCTIONS(13,     4,      3,      4, 1, 0, 2),
+ *     means that pin AB8505_PIN_D18 (pin 13) supports 4 mux (default/ALT_A,
+ *     ALT_B and ALT_C), so GPIOSEL and ALTERNATFUNC registers are used to
+ *     select the mux. ALTA, ALTB and ALTC val indicates values to write in
+ *     ALTERNATFUNC register. We need to specifies these values as SOC
+ *     designers didn't apply the same logic on how to select mux in the
+ *     ABx500 family.
+ *
+ *     As this pins supports at least ALT_B mux, default mux is
+ *     selected by writing 1 in GPIOSEL bit :
+ *
+ *             | GPIOSEL bit=4 | alternatfunc bit2=4 | alternatfunc bit1=3
+ *     default |       1       |          0          |          0
+ *     alt_A   |       0       |          0          |          1
+ *     alt_B   |       0       |          0          |          0
+ *     alt_C   |       0       |          1          |          0
+ *
+ *     ALTERNATE_FUNCTIONS(1,      0, UNUSED, UNUSED),
+ *     means that pin AB9540_PIN_R4 (pin 1) supports 2 mux, so only GPIOSEL
+ *     register is used to select the mux. As this pins doesn't support at
+ *     least ALT_B mux, default mux is by writing 0 in GPIOSEL bit :
+ *
+ *             | GPIOSEL bit=0 | alternatfunc bit2=  | alternatfunc bit1=
+ *     default |       0       |          0          |          0
+ *     alt_A   |       1       |          0          |          0
+ */
+
+static struct
+alternate_functions ab8505_alternate_functions[AB8505_GPIO_MAX_NUMBER + 1] = {
+       ALTERNATE_FUNCTIONS(0, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO0 */
+       ALTERNATE_FUNCTIONS(1,      0, UNUSED, UNUSED, 0, 0, 0), /* GPIO1, altA controlled by bit 0 */
+       ALTERNATE_FUNCTIONS(2,      1, UNUSED, UNUSED, 0, 0, 0), /* GPIO2, altA controlled by bit 1 */
+       ALTERNATE_FUNCTIONS(3,      2, UNUSED, UNUSED, 0, 0, 0), /* GPIO3, altA controlled by bit 2*/
+       ALTERNATE_FUNCTIONS(4, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO4, bit 3 reserved */
+       ALTERNATE_FUNCTIONS(5, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO5, bit 4 reserved */
+       ALTERNATE_FUNCTIONS(6, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO6, bit 5 reserved */
+       ALTERNATE_FUNCTIONS(7, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO7, bit 6 reserved */
+       ALTERNATE_FUNCTIONS(8, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO8, bit 7 reserved */
+
+       ALTERNATE_FUNCTIONS(9, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO9, bit 0 reserved */
+       ALTERNATE_FUNCTIONS(10,      1,      0, UNUSED, 1, 0, 0), /* GPIO10, altA and altB controlled by bit 0 */
+       ALTERNATE_FUNCTIONS(11,      2,      1, UNUSED, 0, 0, 0), /* GPIO11, altA controlled by bit 2 */
+       ALTERNATE_FUNCTIONS(12, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO12, bit3 reseved */
+       ALTERNATE_FUNCTIONS(13,      4,      3,      4, 1, 0, 2), /* GPIO13, altA altB and altC controlled by bit 3 and 4 */
+       ALTERNATE_FUNCTIONS(14,      5, UNUSED, UNUSED, 0, 0, 0), /* GPIO14, altA controlled by bit 5 */
+       ALTERNATE_FUNCTIONS(15, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO15, bit 6 reserved */
+       ALTERNATE_FUNCTIONS(16, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO15, bit 7 reserved  */
+       /*
+        * pins 17 to 20 are special case, only bit 0 is used to select
+        * alternate function for these 4 pins.
+        * bits 1 to 3 are reserved
+        */
+       ALTERNATE_FUNCTIONS(17,      0, UNUSED, UNUSED, 0, 0, 0), /* GPIO17, altA controlled by bit 0 */
+       ALTERNATE_FUNCTIONS(18,      0, UNUSED, UNUSED, 0, 0, 0), /* GPIO18, altA controlled by bit 0 */
+       ALTERNATE_FUNCTIONS(19,      0, UNUSED, UNUSED, 0, 0, 0), /* GPIO19, altA controlled by bit 0 */
+       ALTERNATE_FUNCTIONS(20,      0, UNUSED, UNUSED, 0, 0, 0), /* GPIO20, altA controlled by bit 0 */
+       ALTERNATE_FUNCTIONS(21, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO21, bit 4 reserved */
+       ALTERNATE_FUNCTIONS(22, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO22, bit 5 reserved */
+       ALTERNATE_FUNCTIONS(23, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO23, bit 6 reserved */
+       ALTERNATE_FUNCTIONS(24, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO24, bit 7 reserved */
+
+       ALTERNATE_FUNCTIONS(25, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO25, bit 0 reserved */
+       ALTERNATE_FUNCTIONS(26, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO26, bit 1 reserved */
+       ALTERNATE_FUNCTIONS(27, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO27, bit 2 reserved */
+       ALTERNATE_FUNCTIONS(28, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO28, bit 3 reserved */
+       ALTERNATE_FUNCTIONS(29, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO29, bit 4 reserved */
+       ALTERNATE_FUNCTIONS(30, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO30, bit 5 reserved */
+       ALTERNATE_FUNCTIONS(31, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO31, bit 6 reserved */
+       ALTERNATE_FUNCTIONS(32, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO32, bit 7 reserved */
+
+       ALTERNATE_FUNCTIONS(33, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO33, bit 0 reserved */
+       ALTERNATE_FUNCTIONS(34,      1, UNUSED, UNUSED, 0, 0, 0), /* GPIO34, altA controlled by bit 1 */
+       ALTERNATE_FUNCTIONS(35, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO35, bit 2 reserved */
+       ALTERNATE_FUNCTIONS(36, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO36, bit 2 reserved */
+       ALTERNATE_FUNCTIONS(37, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO37, bit 2 reserved */
+       ALTERNATE_FUNCTIONS(38, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO38, bit 2 reserved */
+       ALTERNATE_FUNCTIONS(39, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO39, bit 2 reserved */
+       ALTERNATE_FUNCTIONS(40,      7, UNUSED, UNUSED, 0, 0, 0), /* GPIO40, altA controlled by bit 7*/
+
+       ALTERNATE_FUNCTIONS(41,      0, UNUSED, UNUSED, 0, 0, 0), /* GPIO41, altA controlled by bit 0 */
+       ALTERNATE_FUNCTIONS(42, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO42, bit 1 reserved */
+       ALTERNATE_FUNCTIONS(43, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO43, bit 2 reserved */
+       ALTERNATE_FUNCTIONS(44, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO44, bit 3 reserved */
+       ALTERNATE_FUNCTIONS(45, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO45, bit 4 reserved */
+       ALTERNATE_FUNCTIONS(46, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO46, bit 5 reserved */
+       ALTERNATE_FUNCTIONS(47, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO47, bit 6 reserved */
+       ALTERNATE_FUNCTIONS(48, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO48, bit 7 reserved */
+
+       ALTERNATE_FUNCTIONS(49, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO49, bit 0 reserved */
+       ALTERNATE_FUNCTIONS(50,      1,      2, UNUSED, 1, 0, 0), /* GPIO50, altA controlled by bit 1 */
+       ALTERNATE_FUNCTIONS(51, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO49, bit 0 reserved */
+       ALTERNATE_FUNCTIONS(52,      3, UNUSED, UNUSED, 0, 0, 0), /* GPIO52, altA controlled by bit 3 */
+       ALTERNATE_FUNCTIONS(53,      4, UNUSED, UNUSED, 0, 0, 0), /* GPIO53, altA controlled by bit 4 */
+};
+
+/*
+ * For AB8505 Only some GPIOs are interrupt capable, and they are
+ * organized in discontiguous clusters:
+ *
+ *     GPIO10 to GPIO11
+ *     GPIO13
+ *     GPIO40 and GPIO41
+ *     GPIO50
+ *     GPIO52 to GPIO53
+ */
+static struct abx500_gpio_irq_cluster ab8505_gpio_irq_cluster[] = {
+       GPIO_IRQ_CLUSTER(10, 11, AB8500_INT_GPIO10R),
+       GPIO_IRQ_CLUSTER(13, 13, AB8500_INT_GPIO13R),
+       GPIO_IRQ_CLUSTER(40, 41, AB8500_INT_GPIO40R),
+       GPIO_IRQ_CLUSTER(50, 50, AB9540_INT_GPIO50R),
+       GPIO_IRQ_CLUSTER(52, 53, AB9540_INT_GPIO52R),
+};
+
+static struct abx500_pinctrl_soc_data ab8505_soc = {
+       .gpio_ranges = ab8505_pinranges,
+       .gpio_num_ranges = ARRAY_SIZE(ab8505_pinranges),
+       .pins = ab8505_pins,
+       .npins = ARRAY_SIZE(ab8505_pins),
+       .functions = ab8505_functions,
+       .nfunctions = ARRAY_SIZE(ab8505_functions),
+       .groups = ab8505_groups,
+       .ngroups = ARRAY_SIZE(ab8505_groups),
+       .alternate_functions = ab8505_alternate_functions,
+       .gpio_irq_cluster = ab8505_gpio_irq_cluster,
+       .ngpio_irq_cluster = ARRAY_SIZE(ab8505_gpio_irq_cluster),
+       .irq_gpio_rising_offset = AB8500_INT_GPIO6R,
+       .irq_gpio_falling_offset = AB8500_INT_GPIO6F,
+       .irq_gpio_factor = 1,
+};
+
+void
+abx500_pinctrl_ab8505_init(struct abx500_pinctrl_soc_data **soc)
+{
+       *soc = &ab8505_soc;
+}
diff --git a/drivers/pinctrl/nomadik/pinctrl-ab8540.c b/drivers/pinctrl/nomadik/pinctrl-ab8540.c
new file mode 100644 (file)
index 0000000..9867535
--- /dev/null
@@ -0,0 +1,408 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2012
+ *
+ * Author: Patrice Chotard <patrice.chotard@stericsson.com> for ST-Ericsson.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/mfd/abx500/ab8500.h>
+#include "pinctrl-abx500.h"
+
+/* All the pins that can be used for GPIO and some other functions */
+#define ABX500_GPIO(offset)            (offset)
+
+#define AB8540_PIN_J16         ABX500_GPIO(1)
+#define AB8540_PIN_D17         ABX500_GPIO(2)
+#define AB8540_PIN_C12         ABX500_GPIO(3)
+#define AB8540_PIN_G12         ABX500_GPIO(4)
+/* hole */
+#define AB8540_PIN_D16         ABX500_GPIO(14)
+#define AB8540_PIN_F15         ABX500_GPIO(15)
+#define AB8540_PIN_J8          ABX500_GPIO(16)
+#define AB8540_PIN_K16         ABX500_GPIO(17)
+#define AB8540_PIN_G15         ABX500_GPIO(18)
+#define AB8540_PIN_F17         ABX500_GPIO(19)
+#define AB8540_PIN_E17         ABX500_GPIO(20)
+/* hole */
+#define AB8540_PIN_AA16                ABX500_GPIO(27)
+#define AB8540_PIN_W18         ABX500_GPIO(28)
+#define AB8540_PIN_Y15         ABX500_GPIO(29)
+#define AB8540_PIN_W16         ABX500_GPIO(30)
+#define AB8540_PIN_V15         ABX500_GPIO(31)
+#define AB8540_PIN_W17         ABX500_GPIO(32)
+/* hole */
+#define AB8540_PIN_D12         ABX500_GPIO(42)
+#define AB8540_PIN_P4          ABX500_GPIO(43)
+#define AB8540_PIN_AB1         ABX500_GPIO(44)
+#define AB8540_PIN_K7          ABX500_GPIO(45)
+#define AB8540_PIN_L7          ABX500_GPIO(46)
+#define AB8540_PIN_G10         ABX500_GPIO(47)
+#define AB8540_PIN_K12         ABX500_GPIO(48)
+/* hole */
+#define AB8540_PIN_N8          ABX500_GPIO(51)
+#define AB8540_PIN_P12         ABX500_GPIO(52)
+#define AB8540_PIN_K8          ABX500_GPIO(53)
+#define AB8540_PIN_J11         ABX500_GPIO(54)
+#define AB8540_PIN_AC2         ABX500_GPIO(55)
+#define AB8540_PIN_AB2         ABX500_GPIO(56)
+
+/* indicates the highest GPIO number */
+#define AB8540_GPIO_MAX_NUMBER 56
+
+/*
+ * The names of the pins are denoted by GPIO number and ball name, even
+ * though they can be used for other things than GPIO, this is the first
+ * column in the table of the data sheet and often used on schematics and
+ * such.
+ */
+static const struct pinctrl_pin_desc ab8540_pins[] = {
+       PINCTRL_PIN(AB8540_PIN_J16, "GPIO1_J16"),
+       PINCTRL_PIN(AB8540_PIN_D17, "GPIO2_D17"),
+       PINCTRL_PIN(AB8540_PIN_C12, "GPIO3_C12"),
+       PINCTRL_PIN(AB8540_PIN_G12, "GPIO4_G12"),
+       /* hole */
+       PINCTRL_PIN(AB8540_PIN_D16, "GPIO14_D16"),
+       PINCTRL_PIN(AB8540_PIN_F15, "GPIO15_F15"),
+       PINCTRL_PIN(AB8540_PIN_J8, "GPIO16_J8"),
+       PINCTRL_PIN(AB8540_PIN_K16, "GPIO17_K16"),
+       PINCTRL_PIN(AB8540_PIN_G15, "GPIO18_G15"),
+       PINCTRL_PIN(AB8540_PIN_F17, "GPIO19_F17"),
+       PINCTRL_PIN(AB8540_PIN_E17, "GPIO20_E17"),
+       /* hole */
+       PINCTRL_PIN(AB8540_PIN_AA16, "GPIO27_AA16"),
+       PINCTRL_PIN(AB8540_PIN_W18, "GPIO28_W18"),
+       PINCTRL_PIN(AB8540_PIN_Y15, "GPIO29_Y15"),
+       PINCTRL_PIN(AB8540_PIN_W16, "GPIO30_W16"),
+       PINCTRL_PIN(AB8540_PIN_V15, "GPIO31_V15"),
+       PINCTRL_PIN(AB8540_PIN_W17, "GPIO32_W17"),
+       /* hole */
+       PINCTRL_PIN(AB8540_PIN_D12, "GPIO42_D12"),
+       PINCTRL_PIN(AB8540_PIN_P4, "GPIO43_P4"),
+       PINCTRL_PIN(AB8540_PIN_AB1, "GPIO44_AB1"),
+       PINCTRL_PIN(AB8540_PIN_K7, "GPIO45_K7"),
+       PINCTRL_PIN(AB8540_PIN_L7, "GPIO46_L7"),
+       PINCTRL_PIN(AB8540_PIN_G10, "GPIO47_G10"),
+       PINCTRL_PIN(AB8540_PIN_K12, "GPIO48_K12"),
+       /* hole */
+       PINCTRL_PIN(AB8540_PIN_N8, "GPIO51_N8"),
+       PINCTRL_PIN(AB8540_PIN_P12, "GPIO52_P12"),
+       PINCTRL_PIN(AB8540_PIN_K8, "GPIO53_K8"),
+       PINCTRL_PIN(AB8540_PIN_J11, "GPIO54_J11"),
+       PINCTRL_PIN(AB8540_PIN_AC2, "GPIO55_AC2"),
+       PINCTRL_PIN(AB8540_PIN_AB2, "GPIO56_AB2"),
+};
+
+/*
+ * Maps local GPIO offsets to local pin numbers
+ */
+static const struct abx500_pinrange ab8540_pinranges[] = {
+       ABX500_PINRANGE(1, 4, ABX500_ALT_A),
+       ABX500_PINRANGE(14, 7, ABX500_ALT_A),
+       ABX500_PINRANGE(27, 6, ABX500_ALT_A),
+       ABX500_PINRANGE(42, 7, ABX500_ALT_A),
+       ABX500_PINRANGE(51, 6, ABX500_ALT_A),
+};
+
+/*
+ * Read the pin group names like this:
+ * sysclkreq2_d_1 = first groups of pins for sysclkreq2 on default function
+ *
+ * The groups are arranged as sets per altfunction column, so we can
+ * mux in one group at a time by selecting the same altfunction for them
+ * all. When functions require pins on different altfunctions, you need
+ * to combine several groups.
+ */
+
+/* default column */
+static const unsigned sysclkreq2_d_1_pins[] = { AB8540_PIN_J16 };
+static const unsigned sysclkreq3_d_1_pins[] = { AB8540_PIN_D17 };
+static const unsigned sysclkreq4_d_1_pins[] = { AB8540_PIN_C12 };
+static const unsigned sysclkreq6_d_1_pins[] = { AB8540_PIN_G12 };
+static const unsigned pwmout1_d_1_pins[] = { AB8540_PIN_D16 };
+static const unsigned pwmout2_d_1_pins[] = { AB8540_PIN_F15 };
+static const unsigned pwmout3_d_1_pins[] = { AB8540_PIN_J8 };
+
+/* audio data interface 1*/
+static const unsigned adi1_d_1_pins[] = { AB8540_PIN_K16, AB8540_PIN_G15,
+                                       AB8540_PIN_F17, AB8540_PIN_E17 };
+/* Digital microphone 1 and 2 */
+static const unsigned dmic12_d_1_pins[] = { AB8540_PIN_AA16, AB8540_PIN_W18 };
+/* Digital microphone 3 and 4 */
+static const unsigned dmic34_d_1_pins[] = { AB8540_PIN_Y15, AB8540_PIN_W16 };
+/* Digital microphone 5 and 6 */
+static const unsigned dmic56_d_1_pins[] = { AB8540_PIN_V15, AB8540_PIN_W17 };
+static const unsigned sysclkreq5_d_1_pins[] = { AB8540_PIN_D12 };
+static const unsigned batremn_d_1_pins[] = { AB8540_PIN_P4 };
+static const unsigned service_d_1_pins[] = { AB8540_PIN_AB1 };
+static const unsigned pwrctrl0_d_1_pins[] = { AB8540_PIN_K7 };
+static const unsigned pwrctrl1_d_1_pins[] = { AB8540_PIN_L7 };
+static const unsigned pwmextvibra1_d_1_pins[] = { AB8540_PIN_G10 };
+static const unsigned pwmextvibra2_d_1_pins[] = { AB8540_PIN_K12 };
+static const unsigned gpio1_vbat_d_1_pins[] = { AB8540_PIN_N8 };
+static const unsigned gpio2_vbat_d_1_pins[] = { AB8540_PIN_P12 };
+static const unsigned gpio3_vbat_d_1_pins[] = { AB8540_PIN_K8 };
+static const unsigned gpio4_vbat_d_1_pins[] = { AB8540_PIN_J11 };
+static const unsigned pdmclkdat_d_1_pins[] = { AB8540_PIN_AC2, AB8540_PIN_AB2 };
+
+/* Altfunction A column */
+static const unsigned gpio1_a_1_pins[] = { AB8540_PIN_J16 };
+static const unsigned gpio2_a_1_pins[] = { AB8540_PIN_D17 };
+static const unsigned gpio3_a_1_pins[] = { AB8540_PIN_C12 };
+static const unsigned gpio4_a_1_pins[] = { AB8540_PIN_G12 };
+static const unsigned gpio14_a_1_pins[] = { AB8540_PIN_D16 };
+static const unsigned gpio15_a_1_pins[] = { AB8540_PIN_F15 };
+static const unsigned gpio16_a_1_pins[] = { AB8540_PIN_J8 };
+static const unsigned gpio17_a_1_pins[] = { AB8540_PIN_K16 };
+static const unsigned gpio18_a_1_pins[] = { AB8540_PIN_G15 };
+static const unsigned gpio19_a_1_pins[] = { AB8540_PIN_F17 };
+static const unsigned gpio20_a_1_pins[] = { AB8540_PIN_E17 };
+static const unsigned gpio27_a_1_pins[] = { AB8540_PIN_AA16 };
+static const unsigned gpio28_a_1_pins[] = { AB8540_PIN_W18 };
+static const unsigned gpio29_a_1_pins[] = { AB8540_PIN_Y15 };
+static const unsigned gpio30_a_1_pins[] = { AB8540_PIN_W16 };
+static const unsigned gpio31_a_1_pins[] = { AB8540_PIN_V15 };
+static const unsigned gpio32_a_1_pins[] = { AB8540_PIN_W17 };
+static const unsigned gpio42_a_1_pins[] = { AB8540_PIN_D12 };
+static const unsigned gpio43_a_1_pins[] = { AB8540_PIN_P4 };
+static const unsigned gpio44_a_1_pins[] = { AB8540_PIN_AB1 };
+static const unsigned gpio45_a_1_pins[] = { AB8540_PIN_K7 };
+static const unsigned gpio46_a_1_pins[] = { AB8540_PIN_L7 };
+static const unsigned gpio47_a_1_pins[] = { AB8540_PIN_G10 };
+static const unsigned gpio48_a_1_pins[] = { AB8540_PIN_K12 };
+static const unsigned gpio51_a_1_pins[] = { AB8540_PIN_N8 };
+static const unsigned gpio52_a_1_pins[] = { AB8540_PIN_P12 };
+static const unsigned gpio53_a_1_pins[] = { AB8540_PIN_K8 };
+static const unsigned gpio54_a_1_pins[] = { AB8540_PIN_J11 };
+static const unsigned gpio55_a_1_pins[] = { AB8540_PIN_AC2 };
+static const unsigned gpio56_a_1_pins[] = { AB8540_PIN_AB2 };
+
+#define AB8540_PIN_GROUP(a, b) { .name = #a, .pins = a##_pins,         \
+                       .npins = ARRAY_SIZE(a##_pins), .altsetting = b }
+
+static const struct abx500_pingroup ab8540_groups[] = {
+       /* default column */
+       AB8540_PIN_GROUP(sysclkreq2_d_1, ABX500_DEFAULT),
+       AB8540_PIN_GROUP(sysclkreq3_d_1, ABX500_DEFAULT),
+       AB8540_PIN_GROUP(sysclkreq4_d_1, ABX500_DEFAULT),
+       AB8540_PIN_GROUP(sysclkreq6_d_1, ABX500_DEFAULT),
+       AB8540_PIN_GROUP(pwmout1_d_1, ABX500_DEFAULT),
+       AB8540_PIN_GROUP(pwmout2_d_1, ABX500_DEFAULT),
+       AB8540_PIN_GROUP(pwmout3_d_1, ABX500_DEFAULT),
+       AB8540_PIN_GROUP(adi1_d_1, ABX500_DEFAULT),
+       AB8540_PIN_GROUP(dmic12_d_1, ABX500_DEFAULT),
+       AB8540_PIN_GROUP(dmic34_d_1, ABX500_DEFAULT),
+       AB8540_PIN_GROUP(dmic56_d_1, ABX500_DEFAULT),
+       AB8540_PIN_GROUP(sysclkreq5_d_1, ABX500_DEFAULT),
+       AB8540_PIN_GROUP(batremn_d_1, ABX500_DEFAULT),
+       AB8540_PIN_GROUP(service_d_1, ABX500_DEFAULT),
+       AB8540_PIN_GROUP(pwrctrl0_d_1, ABX500_DEFAULT),
+       AB8540_PIN_GROUP(pwrctrl1_d_1, ABX500_DEFAULT),
+       AB8540_PIN_GROUP(pwmextvibra1_d_1, ABX500_DEFAULT),
+       AB8540_PIN_GROUP(pwmextvibra2_d_1, ABX500_DEFAULT),
+       AB8540_PIN_GROUP(gpio1_vbat_d_1, ABX500_DEFAULT),
+       AB8540_PIN_GROUP(gpio2_vbat_d_1, ABX500_DEFAULT),
+       AB8540_PIN_GROUP(gpio3_vbat_d_1, ABX500_DEFAULT),
+       AB8540_PIN_GROUP(gpio4_vbat_d_1, ABX500_DEFAULT),
+       AB8540_PIN_GROUP(pdmclkdat_d_1, ABX500_DEFAULT),
+       /* Altfunction A column */
+       AB8540_PIN_GROUP(gpio1_a_1, ABX500_ALT_A),
+       AB8540_PIN_GROUP(gpio2_a_1, ABX500_ALT_A),
+       AB8540_PIN_GROUP(gpio3_a_1, ABX500_ALT_A),
+       AB8540_PIN_GROUP(gpio4_a_1, ABX500_ALT_A),
+       AB8540_PIN_GROUP(gpio14_a_1, ABX500_ALT_A),
+       AB8540_PIN_GROUP(gpio15_a_1, ABX500_ALT_A),
+       AB8540_PIN_GROUP(gpio16_a_1, ABX500_ALT_A),
+       AB8540_PIN_GROUP(gpio17_a_1, ABX500_ALT_A),
+       AB8540_PIN_GROUP(gpio18_a_1, ABX500_ALT_A),
+       AB8540_PIN_GROUP(gpio19_a_1, ABX500_ALT_A),
+       AB8540_PIN_GROUP(gpio20_a_1, ABX500_ALT_A),
+       AB8540_PIN_GROUP(gpio27_a_1, ABX500_ALT_A),
+       AB8540_PIN_GROUP(gpio28_a_1, ABX500_ALT_A),
+       AB8540_PIN_GROUP(gpio29_a_1, ABX500_ALT_A),
+       AB8540_PIN_GROUP(gpio30_a_1, ABX500_ALT_A),
+       AB8540_PIN_GROUP(gpio31_a_1, ABX500_ALT_A),
+       AB8540_PIN_GROUP(gpio32_a_1, ABX500_ALT_A),
+       AB8540_PIN_GROUP(gpio42_a_1, ABX500_ALT_A),
+       AB8540_PIN_GROUP(gpio43_a_1, ABX500_ALT_A),
+       AB8540_PIN_GROUP(gpio44_a_1, ABX500_ALT_A),
+       AB8540_PIN_GROUP(gpio45_a_1, ABX500_ALT_A),
+       AB8540_PIN_GROUP(gpio46_a_1, ABX500_ALT_A),
+       AB8540_PIN_GROUP(gpio47_a_1, ABX500_ALT_A),
+       AB8540_PIN_GROUP(gpio48_a_1, ABX500_ALT_A),
+       AB8540_PIN_GROUP(gpio51_a_1, ABX500_ALT_A),
+       AB8540_PIN_GROUP(gpio52_a_1, ABX500_ALT_A),
+       AB8540_PIN_GROUP(gpio53_a_1, ABX500_ALT_A),
+       AB8540_PIN_GROUP(gpio54_a_1, ABX500_ALT_A),
+       AB8540_PIN_GROUP(gpio55_a_1, ABX500_ALT_A),
+       AB8540_PIN_GROUP(gpio56_a_1, ABX500_ALT_A),
+};
+
+/* We use this macro to define the groups applicable to a function */
+#define AB8540_FUNC_GROUPS(a, b...)       \
+static const char * const a##_groups[] = { b };
+
+AB8540_FUNC_GROUPS(sysclkreq, "sysclkreq2_d_1", "sysclkreq3_d_1",
+               "sysclkreq4_d_1", "sysclkreq5_d_1", "sysclkreq6_d_1");
+AB8540_FUNC_GROUPS(gpio, "gpio1_a_1", "gpio2_a_1", "gpio3_a_1", "gpio4_a_1",
+               "gpio14_a_1", "gpio15_a_1", "gpio16_a_1", "gpio17_a_1",
+               "gpio18_a_1", "gpio19_a_1", "gpio20_a_1", "gpio27_a_1",
+               "gpio28_a_1", "gpio29_a_1", "gpio30_a_1", "gpio31_a_1",
+               "gpio32_a_1", "gpio42_a_1", "gpio43_a_1", "gpio44_a_1",
+               "gpio45_a_1", "gpio46_a_1", "gpio47_a_1", "gpio48_a_1",
+               "gpio51_a_1", "gpio52_a_1", "gpio53_a_1", "gpio54_a_1",
+               "gpio55_a_1", "gpio56_a_1");
+AB8540_FUNC_GROUPS(pwmout, "pwmout1_d_1", "pwmout2_d_1", "pwmout3_d_1");
+AB8540_FUNC_GROUPS(adi1, "adi1_d_1");
+AB8540_FUNC_GROUPS(dmic, "dmic12_d_1", "dmic34_d_1", "dmic56_d_1");
+AB8540_FUNC_GROUPS(batremn, "batremn_d_1");
+AB8540_FUNC_GROUPS(service, "service_d_1");
+AB8540_FUNC_GROUPS(pwrctrl, "pwrctrl0_d_1", "pwrctrl1_d_1");
+AB8540_FUNC_GROUPS(pwmextvibra, "pwmextvibra1_d_1", "pwmextvibra2_d_1");
+AB8540_FUNC_GROUPS(gpio_vbat, "gpio1_vbat_d_1", "gpio2_vbat_d_1",
+               "gpio3_vbat_d_1", "gpio4_vbat_d_1");
+AB8540_FUNC_GROUPS(pdm, "pdmclkdat_d_1");
+
+#define FUNCTION(fname)                                        \
+       {                                               \
+               .name = #fname,                         \
+               .groups = fname##_groups,               \
+               .ngroups = ARRAY_SIZE(fname##_groups),  \
+       }
+
+static const struct abx500_function ab8540_functions[] = {
+       FUNCTION(sysclkreq),
+       FUNCTION(gpio),
+       FUNCTION(pwmout),
+       FUNCTION(adi1),
+       FUNCTION(dmic),
+       FUNCTION(batremn),
+       FUNCTION(service),
+       FUNCTION(pwrctrl),
+       FUNCTION(pwmextvibra),
+       FUNCTION(gpio_vbat),
+       FUNCTION(pdm),
+};
+
+/*
+ * this table translates what's is in the AB8540 specification regarding the
+ * balls alternate functions (as for DB, default, ALT_A, ALT_B and ALT_C).
+ * ALTERNATE_FUNCTIONS(GPIO_NUMBER, GPIOSEL bit, ALTERNATFUNC bit1,
+ * ALTERNATEFUNC bit2, ALTA val, ALTB val, ALTC val),
+ * AB8540 only supports DEFAULT and ALTA functions, so ALTERNATFUNC
+ * registers is not used
+ *
+ */
+
+static struct
+alternate_functions ab8540_alternate_functions[AB8540_GPIO_MAX_NUMBER + 1] = {
+       /* GPIOSEL1 - bit 4-7 reserved */
+       ALTERNATE_FUNCTIONS(0, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO0 */
+       ALTERNATE_FUNCTIONS(1,      0, UNUSED, UNUSED, 0, 0, 0), /* GPIO1, altA controlled by bit 0 */
+       ALTERNATE_FUNCTIONS(2,      1, UNUSED, UNUSED, 0, 0, 0), /* GPIO2, altA controlled by bit 1 */
+       ALTERNATE_FUNCTIONS(3,      2, UNUSED, UNUSED, 0, 0, 0), /* GPIO3, altA controlled by bit 2*/
+       ALTERNATE_FUNCTIONS(4,      3, UNUSED, UNUSED, 0, 0, 0), /* GPIO4, altA controlled by bit 3*/
+       ALTERNATE_FUNCTIONS(5, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO5 */
+       ALTERNATE_FUNCTIONS(6, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO6 */
+       ALTERNATE_FUNCTIONS(7, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO7 */
+       ALTERNATE_FUNCTIONS(8, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO8 */
+       /* GPIOSEL2 - bit 0-4 reserved */
+       ALTERNATE_FUNCTIONS(9,  UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO9 */
+       ALTERNATE_FUNCTIONS(10, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO10 */
+       ALTERNATE_FUNCTIONS(11, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO11 */
+       ALTERNATE_FUNCTIONS(12, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO12 */
+       ALTERNATE_FUNCTIONS(13, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO13 */
+       ALTERNATE_FUNCTIONS(14,      5, UNUSED, UNUSED, 0, 0, 0), /* GPIO14, altA controlled by bit 5 */
+       ALTERNATE_FUNCTIONS(15,      6, UNUSED, UNUSED, 0, 0, 0), /* GPIO15, altA controlled by bit 6 */
+       ALTERNATE_FUNCTIONS(16,      7, UNUSED, UNUSED, 0, 0, 0), /* GPIO16, altA controlled by bit 7 */
+       /* GPIOSEL3 - bit 4-7 reserved */
+       ALTERNATE_FUNCTIONS(17,      0, UNUSED, UNUSED, 0, 0, 0), /* GPIO17, altA controlled by bit 0 */
+       ALTERNATE_FUNCTIONS(18,      1, UNUSED, UNUSED, 0, 0, 0), /* GPIO18, altA controlled by bit 1 */
+       ALTERNATE_FUNCTIONS(19,      2, UNUSED, UNUSED, 0, 0, 0), /* GPIO19, altA controlled by bit 2 */
+       ALTERNATE_FUNCTIONS(20,      3, UNUSED, UNUSED, 0, 0, 0), /* GPIO20, altA controlled by bit 3 */
+       ALTERNATE_FUNCTIONS(21, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO21 */
+       ALTERNATE_FUNCTIONS(22, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO22 */
+       ALTERNATE_FUNCTIONS(23, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO23 */
+       ALTERNATE_FUNCTIONS(24, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO24 */
+       /* GPIOSEL4 - bit 0-1 reserved */
+       ALTERNATE_FUNCTIONS(25, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO25 */
+       ALTERNATE_FUNCTIONS(26, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO26 */
+       ALTERNATE_FUNCTIONS(27,      2, UNUSED, UNUSED, 0, 0, 0), /* GPIO27, altA controlled by bit 2 */
+       ALTERNATE_FUNCTIONS(28,      3, UNUSED, UNUSED, 0, 0, 0), /* GPIO28, altA controlled by bit 3 */
+       ALTERNATE_FUNCTIONS(29,      4, UNUSED, UNUSED, 0, 0, 0), /* GPIO29, altA controlled by bit 4 */
+       ALTERNATE_FUNCTIONS(30,      5, UNUSED, UNUSED, 0, 0, 0), /* GPIO30, altA controlled by bit 5 */
+       ALTERNATE_FUNCTIONS(31,      6, UNUSED, UNUSED, 0, 0, 0), /* GPIO31, altA controlled by bit 6 */
+       ALTERNATE_FUNCTIONS(32,      7, UNUSED, UNUSED, 0, 0, 0), /* GPIO32, altA controlled by bit 7 */
+       /* GPIOSEL5 - bit 0-7 reserved */
+       ALTERNATE_FUNCTIONS(33, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO33 */
+       ALTERNATE_FUNCTIONS(34, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO34 */
+       ALTERNATE_FUNCTIONS(35, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO35 */
+       ALTERNATE_FUNCTIONS(36, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO36 */
+       ALTERNATE_FUNCTIONS(37, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO37 */
+       ALTERNATE_FUNCTIONS(38, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO38 */
+       ALTERNATE_FUNCTIONS(39, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO39 */
+       ALTERNATE_FUNCTIONS(40, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO40 */
+       /* GPIOSEL6 - bit 0 reserved */
+       ALTERNATE_FUNCTIONS(41, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO41 */
+       ALTERNATE_FUNCTIONS(42,      1, UNUSED, UNUSED, 0, 0, 0), /* GPIO42, altA controlled by bit 1 */
+       ALTERNATE_FUNCTIONS(43,      2, UNUSED, UNUSED, 0, 0, 0), /* GPIO43, altA controlled by bit 2 */
+       ALTERNATE_FUNCTIONS(44,      3, UNUSED, UNUSED, 0, 0, 0), /* GPIO44, altA controlled by bit 3 */
+       ALTERNATE_FUNCTIONS(45,      4, UNUSED, UNUSED, 0, 0, 0), /* GPIO45, altA controlled by bit 4 */
+       ALTERNATE_FUNCTIONS(46,      5, UNUSED, UNUSED, 0, 0, 0), /* GPIO46, altA controlled by bit 5 */
+       ALTERNATE_FUNCTIONS(47,      6, UNUSED, UNUSED, 0, 0, 0), /* GPIO47, altA controlled by bit 6 */
+       ALTERNATE_FUNCTIONS(48,      7, UNUSED, UNUSED, 0, 0, 0), /* GPIO48, altA controlled by bit 7 */
+       /* GPIOSEL7 - bit 0-1 reserved */
+       ALTERNATE_FUNCTIONS(49, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO49 */
+       ALTERNATE_FUNCTIONS(50, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO50 */
+       ALTERNATE_FUNCTIONS(51,      2, UNUSED, UNUSED, 0, 0, 0), /* GPIO51, altA controlled by bit 2 */
+       ALTERNATE_FUNCTIONS(52,      3, UNUSED, UNUSED, 0, 0, 0), /* GPIO52, altA controlled by bit 3 */
+       ALTERNATE_FUNCTIONS(53,      4, UNUSED, UNUSED, 0, 0, 0), /* GPIO53, altA controlled by bit 4 */
+       ALTERNATE_FUNCTIONS(54,      5, UNUSED, UNUSED, 0, 0, 0), /* GPIO54, altA controlled by bit 5 */
+       ALTERNATE_FUNCTIONS(55,      6, UNUSED, UNUSED, 0, 0, 0), /* GPIO55, altA controlled by bit 6 */
+       ALTERNATE_FUNCTIONS(56,      7, UNUSED, UNUSED, 0, 0, 0), /* GPIO56, altA controlled by bit 7 */
+};
+
+static struct pullud ab8540_pullud = {
+       .first_pin = 51,        /* GPIO1_VBAT */
+       .last_pin = 54,         /* GPIO4_VBAT */
+};
+
+/*
+ * For AB8540 Only some GPIOs are interrupt capable:
+ *     GPIO43 to GPIO44
+ *     GPIO51 to GPIO54
+ */
+static struct abx500_gpio_irq_cluster ab8540_gpio_irq_cluster[] = {
+       GPIO_IRQ_CLUSTER(43, 43, AB8540_INT_GPIO43F),
+       GPIO_IRQ_CLUSTER(44, 44, AB8540_INT_GPIO44F),
+       GPIO_IRQ_CLUSTER(51, 54, AB9540_INT_GPIO51R),
+};
+
+static struct abx500_pinctrl_soc_data ab8540_soc = {
+       .gpio_ranges = ab8540_pinranges,
+       .gpio_num_ranges = ARRAY_SIZE(ab8540_pinranges),
+       .pins = ab8540_pins,
+       .npins = ARRAY_SIZE(ab8540_pins),
+       .functions = ab8540_functions,
+       .nfunctions = ARRAY_SIZE(ab8540_functions),
+       .groups = ab8540_groups,
+       .ngroups = ARRAY_SIZE(ab8540_groups),
+       .alternate_functions = ab8540_alternate_functions,
+       .pullud = &ab8540_pullud,
+       .gpio_irq_cluster = ab8540_gpio_irq_cluster,
+       .ngpio_irq_cluster = ARRAY_SIZE(ab8540_gpio_irq_cluster),
+       .irq_gpio_rising_offset = AB8540_INT_GPIO43R,
+       .irq_gpio_falling_offset = AB8540_INT_GPIO43F,
+       .irq_gpio_factor = 2,
+};
+
+void
+abx500_pinctrl_ab8540_init(struct abx500_pinctrl_soc_data **soc)
+{
+       *soc = &ab8540_soc;
+}
diff --git a/drivers/pinctrl/nomadik/pinctrl-ab9540.c b/drivers/pinctrl/nomadik/pinctrl-ab9540.c
new file mode 100644 (file)
index 0000000..1a281ca
--- /dev/null
@@ -0,0 +1,486 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2012
+ *
+ * Author: Patrice Chotard <patrice.chotard@stericsson.com> for ST-Ericsson.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/mfd/abx500/ab8500.h>
+#include "pinctrl-abx500.h"
+
+/* All the pins that can be used for GPIO and some other functions */
+#define ABX500_GPIO(offset)            (offset)
+
+#define AB9540_PIN_R4          ABX500_GPIO(1)
+#define AB9540_PIN_V3          ABX500_GPIO(2)
+#define AB9540_PIN_T4          ABX500_GPIO(3)
+#define AB9540_PIN_T5          ABX500_GPIO(4)
+/* hole */
+#define AB9540_PIN_B18         ABX500_GPIO(10)
+#define AB9540_PIN_C18         ABX500_GPIO(11)
+/* hole */
+#define AB9540_PIN_D18         ABX500_GPIO(13)
+#define AB9540_PIN_B19         ABX500_GPIO(14)
+#define AB9540_PIN_C19         ABX500_GPIO(15)
+#define AB9540_PIN_D19         ABX500_GPIO(16)
+#define AB9540_PIN_R3          ABX500_GPIO(17)
+#define AB9540_PIN_T2          ABX500_GPIO(18)
+#define AB9540_PIN_U2          ABX500_GPIO(19)
+#define AB9540_PIN_V2          ABX500_GPIO(20)
+#define AB9540_PIN_N17         ABX500_GPIO(21)
+#define AB9540_PIN_N16         ABX500_GPIO(22)
+#define AB9540_PIN_M19         ABX500_GPIO(23)
+#define AB9540_PIN_T3          ABX500_GPIO(24)
+#define AB9540_PIN_W2          ABX500_GPIO(25)
+/* hole */
+#define AB9540_PIN_H4          ABX500_GPIO(27)
+#define AB9540_PIN_F1          ABX500_GPIO(28)
+#define AB9540_PIN_F4          ABX500_GPIO(29)
+#define AB9540_PIN_F2          ABX500_GPIO(30)
+#define AB9540_PIN_E4          ABX500_GPIO(31)
+#define AB9540_PIN_F3          ABX500_GPIO(32)
+/* hole */
+#define AB9540_PIN_J13         ABX500_GPIO(34)
+/* hole */
+#define AB9540_PIN_L17         ABX500_GPIO(40)
+#define AB9540_PIN_L16         ABX500_GPIO(41)
+#define AB9540_PIN_W3          ABX500_GPIO(42)
+#define AB9540_PIN_N4          ABX500_GPIO(50)
+#define AB9540_PIN_G12         ABX500_GPIO(51)
+#define AB9540_PIN_E17         ABX500_GPIO(52)
+#define AB9540_PIN_D11         ABX500_GPIO(53)
+#define AB9540_PIN_M18         ABX500_GPIO(54)
+
+/* indicates the highest GPIO number */
+#define AB9540_GPIO_MAX_NUMBER 54
+
+/*
+ * The names of the pins are denoted by GPIO number and ball name, even
+ * though they can be used for other things than GPIO, this is the first
+ * column in the table of the data sheet and often used on schematics and
+ * such.
+ */
+static const struct pinctrl_pin_desc ab9540_pins[] = {
+       PINCTRL_PIN(AB9540_PIN_R4, "GPIO1_R4"),
+       PINCTRL_PIN(AB9540_PIN_V3, "GPIO2_V3"),
+       PINCTRL_PIN(AB9540_PIN_T4, "GPIO3_T4"),
+       PINCTRL_PIN(AB9540_PIN_T5, "GPIO4_T5"),
+       /* hole */
+       PINCTRL_PIN(AB9540_PIN_B18, "GPIO10_B18"),
+       PINCTRL_PIN(AB9540_PIN_C18, "GPIO11_C18"),
+       /* hole */
+       PINCTRL_PIN(AB9540_PIN_D18, "GPIO13_D18"),
+       PINCTRL_PIN(AB9540_PIN_B19, "GPIO14_B19"),
+       PINCTRL_PIN(AB9540_PIN_C19, "GPIO15_C19"),
+       PINCTRL_PIN(AB9540_PIN_D19, "GPIO16_D19"),
+       PINCTRL_PIN(AB9540_PIN_R3, "GPIO17_R3"),
+       PINCTRL_PIN(AB9540_PIN_T2, "GPIO18_T2"),
+       PINCTRL_PIN(AB9540_PIN_U2, "GPIO19_U2"),
+       PINCTRL_PIN(AB9540_PIN_V2, "GPIO20_V2"),
+       PINCTRL_PIN(AB9540_PIN_N17, "GPIO21_N17"),
+       PINCTRL_PIN(AB9540_PIN_N16, "GPIO22_N16"),
+       PINCTRL_PIN(AB9540_PIN_M19, "GPIO23_M19"),
+       PINCTRL_PIN(AB9540_PIN_T3, "GPIO24_T3"),
+       PINCTRL_PIN(AB9540_PIN_W2, "GPIO25_W2"),
+       /* hole */
+       PINCTRL_PIN(AB9540_PIN_H4, "GPIO27_H4"),
+       PINCTRL_PIN(AB9540_PIN_F1, "GPIO28_F1"),
+       PINCTRL_PIN(AB9540_PIN_F4, "GPIO29_F4"),
+       PINCTRL_PIN(AB9540_PIN_F2, "GPIO30_F2"),
+       PINCTRL_PIN(AB9540_PIN_E4, "GPIO31_E4"),
+       PINCTRL_PIN(AB9540_PIN_F3, "GPIO32_F3"),
+       /* hole */
+       PINCTRL_PIN(AB9540_PIN_J13, "GPIO34_J13"),
+       /* hole */
+       PINCTRL_PIN(AB9540_PIN_L17, "GPIO40_L17"),
+       PINCTRL_PIN(AB9540_PIN_L16, "GPIO41_L16"),
+       PINCTRL_PIN(AB9540_PIN_W3, "GPIO42_W3"),
+       PINCTRL_PIN(AB9540_PIN_N4, "GPIO50_N4"),
+       PINCTRL_PIN(AB9540_PIN_G12, "GPIO51_G12"),
+       PINCTRL_PIN(AB9540_PIN_E17, "GPIO52_E17"),
+       PINCTRL_PIN(AB9540_PIN_D11, "GPIO53_D11"),
+       PINCTRL_PIN(AB9540_PIN_M18, "GPIO60_M18"),
+};
+
+/*
+ * Maps local GPIO offsets to local pin numbers
+ */
+static const struct abx500_pinrange ab9540_pinranges[] = {
+       ABX500_PINRANGE(1, 4, ABX500_ALT_A),
+       ABX500_PINRANGE(10, 2, ABX500_DEFAULT),
+       ABX500_PINRANGE(13, 1, ABX500_DEFAULT),
+       ABX500_PINRANGE(14, 12, ABX500_ALT_A),
+       ABX500_PINRANGE(27, 6, ABX500_ALT_A),
+       ABX500_PINRANGE(34, 1, ABX500_ALT_A),
+       ABX500_PINRANGE(40, 3, ABX500_ALT_A),
+       ABX500_PINRANGE(50, 1, ABX500_DEFAULT),
+       ABX500_PINRANGE(51, 3, ABX500_ALT_A),
+       ABX500_PINRANGE(54, 1, ABX500_DEFAULT),
+};
+
+/*
+ * Read the pin group names like this:
+ * sysclkreq2_d_1 = first groups of pins for sysclkreq2 on default function
+ *
+ * The groups are arranged as sets per altfunction column, so we can
+ * mux in one group at a time by selecting the same altfunction for them
+ * all. When functions require pins on different altfunctions, you need
+ * to combine several groups.
+ */
+
+/* default column */
+static const unsigned sysclkreq2_d_1_pins[] = { AB9540_PIN_R4 };
+static const unsigned sysclkreq3_d_1_pins[] = { AB9540_PIN_V3 };
+static const unsigned sysclkreq4_d_1_pins[] = { AB9540_PIN_T4 };
+static const unsigned sysclkreq6_d_1_pins[] = { AB9540_PIN_T5 };
+static const unsigned gpio10_d_1_pins[] = { AB9540_PIN_B18 };
+static const unsigned gpio11_d_1_pins[] = { AB9540_PIN_C18 };
+static const unsigned gpio13_d_1_pins[] = { AB9540_PIN_D18 };
+static const unsigned pwmout1_d_1_pins[] = { AB9540_PIN_B19 };
+static const unsigned pwmout2_d_1_pins[] = { AB9540_PIN_C19 };
+static const unsigned pwmout3_d_1_pins[] = { AB9540_PIN_D19 };
+/* audio data interface 1*/
+static const unsigned adi1_d_1_pins[] = { AB9540_PIN_R3, AB9540_PIN_T2,
+                                       AB9540_PIN_U2, AB9540_PIN_V2 };
+/* USBUICC */
+static const unsigned usbuicc_d_1_pins[] = { AB9540_PIN_N17, AB9540_PIN_N16,
+                                       AB9540_PIN_M19 };
+static const unsigned sysclkreq7_d_1_pins[] = { AB9540_PIN_T3 };
+static const unsigned sysclkreq8_d_1_pins[] = { AB9540_PIN_W2 };
+/* Digital microphone 1 and 2 */
+static const unsigned dmic12_d_1_pins[] = { AB9540_PIN_H4, AB9540_PIN_F1 };
+/* Digital microphone 3 and 4 */
+static const unsigned dmic34_d_1_pins[] = { AB9540_PIN_F4, AB9540_PIN_F2 };
+/* Digital microphone 5 and 6 */
+static const unsigned dmic56_d_1_pins[] = { AB9540_PIN_E4, AB9540_PIN_F3 };
+static const unsigned extcpena_d_1_pins[] = { AB9540_PIN_J13 };
+/* modem SDA/SCL */
+static const unsigned modsclsda_d_1_pins[] = { AB9540_PIN_L17, AB9540_PIN_L16 };
+static const unsigned sysclkreq5_d_1_pins[] = { AB9540_PIN_W3 };
+static const unsigned gpio50_d_1_pins[] = { AB9540_PIN_N4 };
+static const unsigned batremn_d_1_pins[] = { AB9540_PIN_G12 };
+static const unsigned resethw_d_1_pins[] = { AB9540_PIN_E17 };
+static const unsigned service_d_1_pins[] = { AB9540_PIN_D11 };
+static const unsigned gpio60_d_1_pins[] = { AB9540_PIN_M18 };
+
+/* Altfunction A column */
+static const unsigned gpio1_a_1_pins[] = { AB9540_PIN_R4 };
+static const unsigned gpio2_a_1_pins[] = { AB9540_PIN_V3 };
+static const unsigned gpio3_a_1_pins[] = { AB9540_PIN_T4 };
+static const unsigned gpio4_a_1_pins[] = { AB9540_PIN_T5 };
+static const unsigned hiqclkena_a_1_pins[] = { AB9540_PIN_B18 };
+static const unsigned pdmclk_a_1_pins[] = { AB9540_PIN_C18 };
+static const unsigned uartdata_a_1_pins[] = { AB9540_PIN_D18, AB9540_PIN_N4 };
+static const unsigned gpio14_a_1_pins[] = { AB9540_PIN_B19 };
+static const unsigned gpio15_a_1_pins[] = { AB9540_PIN_C19 };
+static const unsigned gpio16_a_1_pins[] = { AB9540_PIN_D19 };
+static const unsigned gpio17_a_1_pins[] = { AB9540_PIN_R3 };
+static const unsigned gpio18_a_1_pins[] = { AB9540_PIN_T2 };
+static const unsigned gpio19_a_1_pins[] = { AB9540_PIN_U2 };
+static const unsigned gpio20_a_1_pins[] = { AB9540_PIN_V2 };
+static const unsigned gpio21_a_1_pins[] = { AB9540_PIN_N17 };
+static const unsigned gpio22_a_1_pins[] = { AB9540_PIN_N16 };
+static const unsigned gpio23_a_1_pins[] = { AB9540_PIN_M19 };
+static const unsigned gpio24_a_1_pins[] = { AB9540_PIN_T3 };
+static const unsigned gpio25_a_1_pins[] = { AB9540_PIN_W2 };
+static const unsigned gpio27_a_1_pins[] = { AB9540_PIN_H4 };
+static const unsigned gpio28_a_1_pins[] = { AB9540_PIN_F1 };
+static const unsigned gpio29_a_1_pins[] = { AB9540_PIN_F4 };
+static const unsigned gpio30_a_1_pins[] = { AB9540_PIN_F2 };
+static const unsigned gpio31_a_1_pins[] = { AB9540_PIN_E4 };
+static const unsigned gpio32_a_1_pins[] = { AB9540_PIN_F3 };
+static const unsigned gpio34_a_1_pins[] = { AB9540_PIN_J13 };
+static const unsigned gpio40_a_1_pins[] = { AB9540_PIN_L17 };
+static const unsigned gpio41_a_1_pins[] = { AB9540_PIN_L16 };
+static const unsigned gpio42_a_1_pins[] = { AB9540_PIN_W3 };
+static const unsigned gpio51_a_1_pins[] = { AB9540_PIN_G12 };
+static const unsigned gpio52_a_1_pins[] = { AB9540_PIN_E17 };
+static const unsigned gpio53_a_1_pins[] = { AB9540_PIN_D11 };
+static const unsigned usbuiccpd_a_1_pins[] = { AB9540_PIN_M18 };
+
+/* Altfunction B colum */
+static const unsigned pdmdata_b_1_pins[] = { AB9540_PIN_B18 };
+static const unsigned pwmextvibra1_b_1_pins[] = { AB9540_PIN_D18 };
+static const unsigned pwmextvibra2_b_1_pins[] = { AB9540_PIN_N4 };
+
+/* Altfunction C column */
+static const unsigned usbvdat_c_1_pins[] = { AB9540_PIN_D18 };
+
+#define AB9540_PIN_GROUP(a, b) { .name = #a, .pins = a##_pins,         \
+                       .npins = ARRAY_SIZE(a##_pins), .altsetting = b }
+
+static const struct abx500_pingroup ab9540_groups[] = {
+       /* default column */
+       AB9540_PIN_GROUP(sysclkreq2_d_1, ABX500_DEFAULT),
+       AB9540_PIN_GROUP(sysclkreq3_d_1, ABX500_DEFAULT),
+       AB9540_PIN_GROUP(sysclkreq4_d_1, ABX500_DEFAULT),
+       AB9540_PIN_GROUP(sysclkreq6_d_1, ABX500_DEFAULT),
+       AB9540_PIN_GROUP(gpio10_d_1, ABX500_DEFAULT),
+       AB9540_PIN_GROUP(gpio11_d_1, ABX500_DEFAULT),
+       AB9540_PIN_GROUP(gpio13_d_1, ABX500_DEFAULT),
+       AB9540_PIN_GROUP(pwmout1_d_1, ABX500_DEFAULT),
+       AB9540_PIN_GROUP(pwmout2_d_1, ABX500_DEFAULT),
+       AB9540_PIN_GROUP(pwmout3_d_1, ABX500_DEFAULT),
+       AB9540_PIN_GROUP(adi1_d_1, ABX500_DEFAULT),
+       AB9540_PIN_GROUP(usbuicc_d_1, ABX500_DEFAULT),
+       AB9540_PIN_GROUP(sysclkreq7_d_1, ABX500_DEFAULT),
+       AB9540_PIN_GROUP(sysclkreq8_d_1, ABX500_DEFAULT),
+       AB9540_PIN_GROUP(dmic12_d_1, ABX500_DEFAULT),
+       AB9540_PIN_GROUP(dmic34_d_1, ABX500_DEFAULT),
+       AB9540_PIN_GROUP(dmic56_d_1, ABX500_DEFAULT),
+       AB9540_PIN_GROUP(extcpena_d_1, ABX500_DEFAULT),
+       AB9540_PIN_GROUP(modsclsda_d_1, ABX500_DEFAULT),
+       AB9540_PIN_GROUP(sysclkreq5_d_1, ABX500_DEFAULT),
+       AB9540_PIN_GROUP(gpio50_d_1, ABX500_DEFAULT),
+       AB9540_PIN_GROUP(batremn_d_1, ABX500_DEFAULT),
+       AB9540_PIN_GROUP(resethw_d_1, ABX500_DEFAULT),
+       AB9540_PIN_GROUP(service_d_1, ABX500_DEFAULT),
+       AB9540_PIN_GROUP(gpio60_d_1, ABX500_DEFAULT),
+
+       /* Altfunction A column */
+       AB9540_PIN_GROUP(gpio1_a_1, ABX500_ALT_A),
+       AB9540_PIN_GROUP(gpio2_a_1, ABX500_ALT_A),
+       AB9540_PIN_GROUP(gpio3_a_1, ABX500_ALT_A),
+       AB9540_PIN_GROUP(gpio4_a_1, ABX500_ALT_A),
+       AB9540_PIN_GROUP(hiqclkena_a_1, ABX500_ALT_A),
+       AB9540_PIN_GROUP(pdmclk_a_1, ABX500_ALT_A),
+       AB9540_PIN_GROUP(uartdata_a_1, ABX500_ALT_A),
+       AB9540_PIN_GROUP(gpio14_a_1, ABX500_ALT_A),
+       AB9540_PIN_GROUP(gpio15_a_1, ABX500_ALT_A),
+       AB9540_PIN_GROUP(gpio16_a_1, ABX500_ALT_A),
+       AB9540_PIN_GROUP(gpio17_a_1, ABX500_ALT_A),
+       AB9540_PIN_GROUP(gpio18_a_1, ABX500_ALT_A),
+       AB9540_PIN_GROUP(gpio19_a_1, ABX500_ALT_A),
+       AB9540_PIN_GROUP(gpio20_a_1, ABX500_ALT_A),
+       AB9540_PIN_GROUP(gpio21_a_1, ABX500_ALT_A),
+       AB9540_PIN_GROUP(gpio22_a_1, ABX500_ALT_A),
+       AB9540_PIN_GROUP(gpio23_a_1, ABX500_ALT_A),
+       AB9540_PIN_GROUP(gpio24_a_1, ABX500_ALT_A),
+       AB9540_PIN_GROUP(gpio25_a_1, ABX500_ALT_A),
+       AB9540_PIN_GROUP(gpio27_a_1, ABX500_ALT_A),
+       AB9540_PIN_GROUP(gpio28_a_1, ABX500_ALT_A),
+       AB9540_PIN_GROUP(gpio29_a_1, ABX500_ALT_A),
+       AB9540_PIN_GROUP(gpio30_a_1, ABX500_ALT_A),
+       AB9540_PIN_GROUP(gpio31_a_1, ABX500_ALT_A),
+       AB9540_PIN_GROUP(gpio32_a_1, ABX500_ALT_A),
+       AB9540_PIN_GROUP(gpio34_a_1, ABX500_ALT_A),
+       AB9540_PIN_GROUP(gpio40_a_1, ABX500_ALT_A),
+       AB9540_PIN_GROUP(gpio41_a_1, ABX500_ALT_A),
+       AB9540_PIN_GROUP(gpio42_a_1, ABX500_ALT_A),
+       AB9540_PIN_GROUP(gpio51_a_1, ABX500_ALT_A),
+       AB9540_PIN_GROUP(gpio52_a_1, ABX500_ALT_A),
+       AB9540_PIN_GROUP(gpio53_a_1, ABX500_ALT_A),
+       AB9540_PIN_GROUP(usbuiccpd_a_1, ABX500_ALT_A),
+
+       /* Altfunction B column */
+       AB9540_PIN_GROUP(pdmdata_b_1, ABX500_ALT_B),
+       AB9540_PIN_GROUP(pwmextvibra1_b_1, ABX500_ALT_B),
+       AB9540_PIN_GROUP(pwmextvibra2_b_1, ABX500_ALT_B),
+
+       /* Altfunction C column */
+       AB9540_PIN_GROUP(usbvdat_c_1, ABX500_ALT_C),
+};
+
+/* We use this macro to define the groups applicable to a function */
+#define AB9540_FUNC_GROUPS(a, b...)       \
+static const char * const a##_groups[] = { b };
+
+AB9540_FUNC_GROUPS(sysclkreq, "sysclkreq2_d_1", "sysclkreq3_d_1",
+               "sysclkreq4_d_1", "sysclkreq5_d_1", "sysclkreq6_d_1",
+               "sysclkreq7_d_1", "sysclkreq8_d_1");
+AB9540_FUNC_GROUPS(gpio, "gpio1_a_1", "gpio2_a_1", "gpio3_a_1", "gpio4_a_1",
+               "gpio10_d_1", "gpio11_d_1", "gpio13_d_1", "gpio14_a_1",
+               "gpio15_a_1", "gpio16_a_1", "gpio17_a_1", "gpio18_a_1",
+               "gpio19_a_1", "gpio20_a_1", "gpio21_a_1", "gpio22_a_1",
+               "gpio23_a_1", "gpio24_a_1", "gpio25_a_1", "gpio27_a_1",
+               "gpio28_a_1", "gpio29_a_1", "gpio30_a_1", "gpio31_a_1",
+               "gpio32_a_1", "gpio34_a_1", "gpio40_a_1", "gpio41_a_1",
+               "gpio42_a_1", "gpio50_d_1", "gpio51_a_1", "gpio52_a_1",
+               "gpio53_a_1", "gpio60_d_1");
+AB9540_FUNC_GROUPS(pwmout, "pwmout1_d_1", "pwmout2_d_1", "pwmout3_d_1");
+AB9540_FUNC_GROUPS(adi1, "adi1_d_1");
+AB9540_FUNC_GROUPS(usbuicc, "usbuicc_d_1", "usbuiccpd_a_1");
+AB9540_FUNC_GROUPS(dmic, "dmic12_d_1", "dmic34_d_1", "dmic56_d_1");
+AB9540_FUNC_GROUPS(extcpena, "extcpena_d_1");
+AB9540_FUNC_GROUPS(modsclsda, "modsclsda_d_1");
+AB9540_FUNC_GROUPS(batremn, "batremn_d_1");
+AB9540_FUNC_GROUPS(resethw, "resethw_d_1");
+AB9540_FUNC_GROUPS(service, "service_d_1");
+AB9540_FUNC_GROUPS(hiqclkena, "hiqclkena_a_1");
+AB9540_FUNC_GROUPS(pdm, "pdmdata_b_1", "pdmclk_a_1");
+AB9540_FUNC_GROUPS(uartdata, "uartdata_a_1");
+AB9540_FUNC_GROUPS(pwmextvibra, "pwmextvibra1_b_1", "pwmextvibra2_b_1");
+AB9540_FUNC_GROUPS(usbvdat, "usbvdat_c_1");
+
+#define FUNCTION(fname)                                        \
+       {                                               \
+               .name = #fname,                         \
+               .groups = fname##_groups,               \
+               .ngroups = ARRAY_SIZE(fname##_groups),  \
+       }
+
+static const struct abx500_function ab9540_functions[] = {
+       FUNCTION(sysclkreq),
+       FUNCTION(gpio),
+       FUNCTION(pwmout),
+       FUNCTION(adi1),
+       FUNCTION(usbuicc),
+       FUNCTION(dmic),
+       FUNCTION(extcpena),
+       FUNCTION(modsclsda),
+       FUNCTION(batremn),
+       FUNCTION(resethw),
+       FUNCTION(service),
+       FUNCTION(hiqclkena),
+       FUNCTION(pdm),
+       FUNCTION(uartdata),
+       FUNCTION(pwmextvibra),
+       FUNCTION(usbvdat),
+};
+
+/*
+ * this table translates what's is in the AB9540 specification regarding the
+ * balls alternate functions (as for DB, default, ALT_A, ALT_B and ALT_C).
+ * ALTERNATE_FUNCTIONS(GPIO_NUMBER, GPIOSEL bit, ALTERNATFUNC bit1,
+ * ALTERNATEFUNC bit2, ALTA val, ALTB val, ALTC val),
+ *
+ * example :
+ *
+ *     ALTERNATE_FUNCTIONS(13,     4,      3,      4, 1, 0, 2),
+ *     means that pin AB9540_PIN_D18 (pin 13) supports 4 mux (default/ALT_A,
+ *     ALT_B and ALT_C), so GPIOSEL and ALTERNATFUNC registers are used to
+ *     select the mux. ALTA, ALTB and ALTC val indicates values to write in
+ *     ALTERNATFUNC register. We need to specifies these values as SOC
+ *     designers didn't apply the same logic on how to select mux in the
+ *     ABx500 family.
+ *
+ *     As this pins supports at least ALT_B mux, default mux is
+ *     selected by writing 1 in GPIOSEL bit :
+ *
+ *             | GPIOSEL bit=4 | alternatfunc bit2=4 | alternatfunc bit1=3
+ *     default |       1       |          0          |          0
+ *     alt_A   |       0       |          0          |          1
+ *     alt_B   |       0       |          0          |          0
+ *     alt_C   |       0       |          1          |          0
+ *
+ *     ALTERNATE_FUNCTIONS(1,      0, UNUSED, UNUSED),
+ *     means that pin AB9540_PIN_R4 (pin 1) supports 2 mux, so only GPIOSEL
+ *     register is used to select the mux. As this pins doesn't support at
+ *     least ALT_B mux, default mux is by writing 0 in GPIOSEL bit :
+ *
+ *             | GPIOSEL bit=0 | alternatfunc bit2=  | alternatfunc bit1=
+ *     default |       0       |          0          |          0
+ *     alt_A   |       1       |          0          |          0
+ */
+
+static struct
+alternate_functions ab9540alternate_functions[AB9540_GPIO_MAX_NUMBER + 1] = {
+       /* GPIOSEL1 - bits 4-7 are reserved */
+       ALTERNATE_FUNCTIONS(0, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO0 */
+       ALTERNATE_FUNCTIONS(1,      0, UNUSED, UNUSED, 0, 0, 0), /* GPIO1, altA controlled by bit 0 */
+       ALTERNATE_FUNCTIONS(2,      1, UNUSED, UNUSED, 0, 0, 0), /* GPIO2, altA controlled by bit 1 */
+       ALTERNATE_FUNCTIONS(3,      2, UNUSED, UNUSED, 0, 0, 0), /* GPIO3, altA controlled by bit 2*/
+       ALTERNATE_FUNCTIONS(4,      3, UNUSED, UNUSED, 0, 0, 0), /* GPIO4, altA controlled by bit 3*/
+       ALTERNATE_FUNCTIONS(5, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO5 */
+       ALTERNATE_FUNCTIONS(6, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO6 */
+       ALTERNATE_FUNCTIONS(7, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO7 */
+       ALTERNATE_FUNCTIONS(8, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO8 */
+       /* GPIOSEL2 - bits 0 and 3 are reserved */
+       ALTERNATE_FUNCTIONS(9, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO9 */
+       ALTERNATE_FUNCTIONS(10,      1,      0, UNUSED, 1, 0, 0), /* GPIO10, altA and altB controlled by bit 0 */
+       ALTERNATE_FUNCTIONS(11,      2,      1, UNUSED, 0, 0, 0), /* GPIO11, altA controlled by bit 1 */
+       ALTERNATE_FUNCTIONS(12, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO12 */
+       ALTERNATE_FUNCTIONS(13,      4,      3,      4, 1, 0, 2), /* GPIO13, altA altB and altC controlled by bit 3 and 4 */
+       ALTERNATE_FUNCTIONS(14,      5, UNUSED, UNUSED, 0, 0, 0), /* GPIO14, altA controlled by bit 5 */
+       ALTERNATE_FUNCTIONS(15,      6, UNUSED, UNUSED, 0, 0, 0), /* GPIO15, altA controlled by bit 6 */
+       ALTERNATE_FUNCTIONS(16,      7, UNUSED, UNUSED, 0, 0, 0), /* GPIO16, altA controlled by bit 7 */
+       /* GPIOSEL3 - bit 1-3 reserved
+        * pins 17 to 20 are special case, only bit 0 is used to select
+        * alternate function for these 4 pins.
+        * bits 1 to 3 are reserved
+        */
+       ALTERNATE_FUNCTIONS(17,      0, UNUSED, UNUSED, 0, 0, 0), /* GPIO17, altA controlled by bit 0 */
+       ALTERNATE_FUNCTIONS(18,      0, UNUSED, UNUSED, 0, 0, 0), /* GPIO18, altA controlled by bit 0 */
+       ALTERNATE_FUNCTIONS(19,      0, UNUSED, UNUSED, 0, 0, 0), /* GPIO19, altA controlled by bit 0 */
+       ALTERNATE_FUNCTIONS(20,      0, UNUSED, UNUSED, 0, 0, 0), /* GPIO20, altA controlled by bit 0 */
+       ALTERNATE_FUNCTIONS(21,      4, UNUSED, UNUSED, 0, 0, 0), /* GPIO21, altA controlled by bit 4 */
+       ALTERNATE_FUNCTIONS(22,      5, UNUSED, UNUSED, 0, 0, 0), /* GPIO22, altA controlled by bit 5 */
+       ALTERNATE_FUNCTIONS(23,      6, UNUSED, UNUSED, 0, 0, 0), /* GPIO23, altA controlled by bit 6 */
+       ALTERNATE_FUNCTIONS(24,      7, UNUSED, UNUSED, 0, 0, 0), /* GPIO24, altA controlled by bit 7 */
+       /* GPIOSEL4 - bit 1 reserved */
+       ALTERNATE_FUNCTIONS(25,      0, UNUSED, UNUSED, 0, 0, 0), /* GPIO25, altA controlled by bit 0 */
+       ALTERNATE_FUNCTIONS(26, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO26 */
+       ALTERNATE_FUNCTIONS(27,      2, UNUSED, UNUSED, 0, 0, 0), /* GPIO27, altA controlled by bit 2 */
+       ALTERNATE_FUNCTIONS(28,      3, UNUSED, UNUSED, 0, 0, 0), /* GPIO28, altA controlled by bit 3 */
+       ALTERNATE_FUNCTIONS(29,      4, UNUSED, UNUSED, 0, 0, 0), /* GPIO29, altA controlled by bit 4 */
+       ALTERNATE_FUNCTIONS(30,      5, UNUSED, UNUSED, 0, 0, 0), /* GPIO30, altA controlled by bit 5 */
+       ALTERNATE_FUNCTIONS(31,      6, UNUSED, UNUSED, 0, 0, 0), /* GPIO31, altA controlled by bit 6 */
+       ALTERNATE_FUNCTIONS(32,      7, UNUSED, UNUSED, 0, 0, 0), /* GPIO32, altA controlled by bit 7 */
+       /* GPIOSEL5 - bit 0, 2-6 are reserved */
+       ALTERNATE_FUNCTIONS(33, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO33 */
+       ALTERNATE_FUNCTIONS(34,      1, UNUSED, UNUSED, 0, 0, 0), /* GPIO34, altA controlled by bit 1 */
+       ALTERNATE_FUNCTIONS(35, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO35 */
+       ALTERNATE_FUNCTIONS(36, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO36 */
+       ALTERNATE_FUNCTIONS(37, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO37 */
+       ALTERNATE_FUNCTIONS(38, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO38 */
+       ALTERNATE_FUNCTIONS(39, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO39 */
+       ALTERNATE_FUNCTIONS(40,      7, UNUSED, UNUSED, 0, 0, 0), /* GPIO40, altA controlled by bit 7 */
+       /* GPIOSEL6 - bit 2-7 are reserved */
+       ALTERNATE_FUNCTIONS(41,      0, UNUSED, UNUSED, 0, 0, 0), /* GPIO41, altA controlled by bit 0 */
+       ALTERNATE_FUNCTIONS(42,      1, UNUSED, UNUSED, 0, 0, 0), /* GPIO42, altA controlled by bit 1 */
+       ALTERNATE_FUNCTIONS(43, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO43 */
+       ALTERNATE_FUNCTIONS(44, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO44 */
+       ALTERNATE_FUNCTIONS(45, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO45 */
+       ALTERNATE_FUNCTIONS(46, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO46 */
+       ALTERNATE_FUNCTIONS(47, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO47 */
+       ALTERNATE_FUNCTIONS(48, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO48 */
+       /*
+        * GPIOSEL7 - bit 0 and 6-7 are reserved
+        * special case with GPIO60, wich is located at offset 5 of gpiosel7
+        * don't know why it has been called GPIO60 in AB9540 datasheet,
+        * GPIO54 would be logical..., so at SOC point of view we consider
+        * GPIO60 = GPIO54
+        */
+       ALTERNATE_FUNCTIONS(49,      0, UNUSED, UNUSED, 0, 0, 0), /* no GPIO49 */
+       ALTERNATE_FUNCTIONS(50,      1,      2, UNUSED, 1, 0, 0), /* GPIO50, altA and altB controlled by bit 1 */
+       ALTERNATE_FUNCTIONS(51,      2, UNUSED, UNUSED, 0, 0, 0), /* GPIO51, altA controlled by bit 2 */
+       ALTERNATE_FUNCTIONS(52,      3, UNUSED, UNUSED, 0, 0, 0), /* GPIO52, altA controlled by bit 3 */
+       ALTERNATE_FUNCTIONS(53,      4, UNUSED, UNUSED, 0, 0, 0), /* GPIO53, altA controlled by bit 4 */
+       ALTERNATE_FUNCTIONS(54,      5, UNUSED, UNUSED, 0, 0, 0), /* GPIO54 = GPIO60, altA controlled by bit 5 */
+};
+
+static struct abx500_gpio_irq_cluster ab9540_gpio_irq_cluster[] = {
+       GPIO_IRQ_CLUSTER(10, 13, AB8500_INT_GPIO10R),
+       GPIO_IRQ_CLUSTER(24, 25, AB8500_INT_GPIO24R),
+       GPIO_IRQ_CLUSTER(40, 41, AB8500_INT_GPIO40R),
+       GPIO_IRQ_CLUSTER(50, 54, AB9540_INT_GPIO50R),
+};
+
+static struct abx500_pinctrl_soc_data ab9540_soc = {
+       .gpio_ranges = ab9540_pinranges,
+       .gpio_num_ranges = ARRAY_SIZE(ab9540_pinranges),
+       .pins = ab9540_pins,
+       .npins = ARRAY_SIZE(ab9540_pins),
+       .functions = ab9540_functions,
+       .nfunctions = ARRAY_SIZE(ab9540_functions),
+       .groups = ab9540_groups,
+       .ngroups = ARRAY_SIZE(ab9540_groups),
+       .alternate_functions = ab9540alternate_functions,
+       .gpio_irq_cluster = ab9540_gpio_irq_cluster,
+       .ngpio_irq_cluster = ARRAY_SIZE(ab9540_gpio_irq_cluster),
+       .irq_gpio_rising_offset = AB8500_INT_GPIO6R,
+       .irq_gpio_falling_offset = AB8500_INT_GPIO6F,
+       .irq_gpio_factor = 1,
+};
+
+void
+abx500_pinctrl_ab9540_init(struct abx500_pinctrl_soc_data **soc)
+{
+       *soc = &ab9540_soc;
+}
diff --git a/drivers/pinctrl/nomadik/pinctrl-abx500.c b/drivers/pinctrl/nomadik/pinctrl-abx500.c
new file mode 100644 (file)
index 0000000..a53a689
--- /dev/null
@@ -0,0 +1,1346 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2013
+ *
+ * Author: Patrice Chotard <patrice.chotard@st.com>
+ * License terms: GNU General Public License (GPL) version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/interrupt.h>
+#include <linux/bitops.h>
+#include <linux/mfd/abx500.h>
+#include <linux/mfd/abx500/ab8500.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinconf-generic.h>
+#include <linux/pinctrl/machine.h>
+
+#include "pinctrl-abx500.h"
+#include "../core.h"
+#include "../pinconf.h"
+
+/*
+ * The AB9540 and AB8540 GPIO support are extended versions
+ * of the AB8500 GPIO support.
+ * The AB9540 supports an additional (7th) register so that
+ * more GPIO may be configured and used.
+ * The AB8540 supports 4 new gpios (GPIOx_VBAT) that have
+ * internal pull-up and pull-down capabilities.
+ */
+
+/*
+ * GPIO registers offset
+ * Bank: 0x10
+ */
+#define AB8500_GPIO_SEL1_REG   0x00
+#define AB8500_GPIO_SEL2_REG   0x01
+#define AB8500_GPIO_SEL3_REG   0x02
+#define AB8500_GPIO_SEL4_REG   0x03
+#define AB8500_GPIO_SEL5_REG   0x04
+#define AB8500_GPIO_SEL6_REG   0x05
+#define AB9540_GPIO_SEL7_REG   0x06
+
+#define AB8500_GPIO_DIR1_REG   0x10
+#define AB8500_GPIO_DIR2_REG   0x11
+#define AB8500_GPIO_DIR3_REG   0x12
+#define AB8500_GPIO_DIR4_REG   0x13
+#define AB8500_GPIO_DIR5_REG   0x14
+#define AB8500_GPIO_DIR6_REG   0x15
+#define AB9540_GPIO_DIR7_REG   0x16
+
+#define AB8500_GPIO_OUT1_REG   0x20
+#define AB8500_GPIO_OUT2_REG   0x21
+#define AB8500_GPIO_OUT3_REG   0x22
+#define AB8500_GPIO_OUT4_REG   0x23
+#define AB8500_GPIO_OUT5_REG   0x24
+#define AB8500_GPIO_OUT6_REG   0x25
+#define AB9540_GPIO_OUT7_REG   0x26
+
+#define AB8500_GPIO_PUD1_REG   0x30
+#define AB8500_GPIO_PUD2_REG   0x31
+#define AB8500_GPIO_PUD3_REG   0x32
+#define AB8500_GPIO_PUD4_REG   0x33
+#define AB8500_GPIO_PUD5_REG   0x34
+#define AB8500_GPIO_PUD6_REG   0x35
+#define AB9540_GPIO_PUD7_REG   0x36
+
+#define AB8500_GPIO_IN1_REG    0x40
+#define AB8500_GPIO_IN2_REG    0x41
+#define AB8500_GPIO_IN3_REG    0x42
+#define AB8500_GPIO_IN4_REG    0x43
+#define AB8500_GPIO_IN5_REG    0x44
+#define AB8500_GPIO_IN6_REG    0x45
+#define AB9540_GPIO_IN7_REG    0x46
+#define AB8540_GPIO_VINSEL_REG 0x47
+#define AB8540_GPIO_PULL_UPDOWN_REG    0x48
+#define AB8500_GPIO_ALTFUN_REG 0x50
+#define AB8540_GPIO_PULL_UPDOWN_MASK   0x03
+#define AB8540_GPIO_VINSEL_MASK        0x03
+#define AB8540_GPIOX_VBAT_START        51
+#define AB8540_GPIOX_VBAT_END  54
+
+#define ABX500_GPIO_INPUT      0
+#define ABX500_GPIO_OUTPUT     1
+
+struct abx500_pinctrl {
+       struct device *dev;
+       struct pinctrl_dev *pctldev;
+       struct abx500_pinctrl_soc_data *soc;
+       struct gpio_chip chip;
+       struct ab8500 *parent;
+       struct abx500_gpio_irq_cluster *irq_cluster;
+       int irq_cluster_size;
+};
+
+/**
+ * to_abx500_pinctrl() - get the pointer to abx500_pinctrl
+ * @chip:      Member of the structure abx500_pinctrl
+ */
+static inline struct abx500_pinctrl *to_abx500_pinctrl(struct gpio_chip *chip)
+{
+       return container_of(chip, struct abx500_pinctrl, chip);
+}
+
+static int abx500_gpio_get_bit(struct gpio_chip *chip, u8 reg,
+                              unsigned offset, bool *bit)
+{
+       struct abx500_pinctrl *pct = to_abx500_pinctrl(chip);
+       u8 pos = offset % 8;
+       u8 val;
+       int ret;
+
+       reg += offset / 8;
+       ret = abx500_get_register_interruptible(pct->dev,
+                                               AB8500_MISC, reg, &val);
+
+       *bit = !!(val & BIT(pos));
+
+       if (ret < 0)
+               dev_err(pct->dev,
+                       "%s read reg =%x, offset=%x failed (%d)\n",
+                       __func__, reg, offset, ret);
+
+       return ret;
+}
+
+static int abx500_gpio_set_bits(struct gpio_chip *chip, u8 reg,
+                               unsigned offset, int val)
+{
+       struct abx500_pinctrl *pct = to_abx500_pinctrl(chip);
+       u8 pos = offset % 8;
+       int ret;
+
+       reg += offset / 8;
+       ret = abx500_mask_and_set_register_interruptible(pct->dev,
+                               AB8500_MISC, reg, BIT(pos), val << pos);
+       if (ret < 0)
+               dev_err(pct->dev, "%s write reg, %x offset %x failed (%d)\n",
+                               __func__, reg, offset, ret);
+
+       return ret;
+}
+
+/**
+ * abx500_gpio_get() - Get the particular GPIO value
+ * @chip:      Gpio device
+ * @offset:    GPIO number to read
+ */
+static int abx500_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+       struct abx500_pinctrl *pct = to_abx500_pinctrl(chip);
+       bool bit;
+       bool is_out;
+       u8 gpio_offset = offset - 1;
+       int ret;
+
+       ret = abx500_gpio_get_bit(chip, AB8500_GPIO_DIR1_REG,
+                       gpio_offset, &is_out);
+       if (ret < 0)
+               goto out;
+
+       if (is_out)
+               ret = abx500_gpio_get_bit(chip, AB8500_GPIO_OUT1_REG,
+                               gpio_offset, &bit);
+       else
+               ret = abx500_gpio_get_bit(chip, AB8500_GPIO_IN1_REG,
+                               gpio_offset, &bit);
+out:
+       if (ret < 0) {
+               dev_err(pct->dev, "%s failed (%d)\n", __func__, ret);
+               return ret;
+       }
+
+       return bit;
+}
+
+static void abx500_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
+{
+       struct abx500_pinctrl *pct = to_abx500_pinctrl(chip);
+       int ret;
+
+       ret = abx500_gpio_set_bits(chip, AB8500_GPIO_OUT1_REG, offset, val);
+       if (ret < 0)
+               dev_err(pct->dev, "%s write failed (%d)\n", __func__, ret);
+}
+
+static int abx500_get_pull_updown(struct abx500_pinctrl *pct, int offset,
+                                 enum abx500_gpio_pull_updown *pull_updown)
+{
+       u8 pos;
+       u8 val;
+       int ret;
+       struct pullud *pullud;
+
+       if (!pct->soc->pullud) {
+               dev_err(pct->dev, "%s AB chip doesn't support pull up/down feature",
+                               __func__);
+               ret = -EPERM;
+               goto out;
+       }
+
+       pullud = pct->soc->pullud;
+
+       if ((offset < pullud->first_pin)
+               || (offset > pullud->last_pin)) {
+               ret = -EINVAL;
+               goto out;
+       }
+
+       ret = abx500_get_register_interruptible(pct->dev,
+                       AB8500_MISC, AB8540_GPIO_PULL_UPDOWN_REG, &val);
+
+       pos = (offset - pullud->first_pin) << 1;
+       *pull_updown = (val >> pos) & AB8540_GPIO_PULL_UPDOWN_MASK;
+
+out:
+       if (ret < 0)
+               dev_err(pct->dev, "%s failed (%d)\n", __func__, ret);
+
+       return ret;
+}
+
+static int abx500_set_pull_updown(struct abx500_pinctrl *pct,
+                                 int offset, enum abx500_gpio_pull_updown val)
+{
+       u8 pos;
+       int ret;
+       struct pullud *pullud;
+
+       if (!pct->soc->pullud) {
+               dev_err(pct->dev, "%s AB chip doesn't support pull up/down feature",
+                               __func__);
+               ret = -EPERM;
+               goto out;
+       }
+
+       pullud = pct->soc->pullud;
+
+       if ((offset < pullud->first_pin)
+               || (offset > pullud->last_pin)) {
+               ret = -EINVAL;
+               goto out;
+       }
+       pos = (offset - pullud->first_pin) << 1;
+
+       ret = abx500_mask_and_set_register_interruptible(pct->dev,
+                       AB8500_MISC, AB8540_GPIO_PULL_UPDOWN_REG,
+                       AB8540_GPIO_PULL_UPDOWN_MASK << pos, val << pos);
+
+out:
+       if (ret < 0)
+               dev_err(pct->dev, "%s failed (%d)\n", __func__, ret);
+
+       return ret;
+}
+
+static bool abx500_pullud_supported(struct gpio_chip *chip, unsigned gpio)
+{
+       struct abx500_pinctrl *pct = to_abx500_pinctrl(chip);
+       struct pullud *pullud = pct->soc->pullud;
+
+       return (pullud &&
+               gpio >= pullud->first_pin &&
+               gpio <= pullud->last_pin);
+}
+
+static int abx500_gpio_direction_output(struct gpio_chip *chip,
+                                       unsigned offset,
+                                       int val)
+{
+       struct abx500_pinctrl *pct = to_abx500_pinctrl(chip);
+       unsigned gpio;
+       int ret;
+
+       /* set direction as output */
+       ret = abx500_gpio_set_bits(chip,
+                               AB8500_GPIO_DIR1_REG,
+                               offset,
+                               ABX500_GPIO_OUTPUT);
+       if (ret < 0)
+               goto out;
+
+       /* disable pull down */
+       ret = abx500_gpio_set_bits(chip,
+                               AB8500_GPIO_PUD1_REG,
+                               offset,
+                               ABX500_GPIO_PULL_NONE);
+       if (ret < 0)
+               goto out;
+
+       /* if supported, disable both pull down and pull up */
+       gpio = offset + 1;
+       if (abx500_pullud_supported(chip, gpio)) {
+               ret = abx500_set_pull_updown(pct,
+                               gpio,
+                               ABX500_GPIO_PULL_NONE);
+       }
+out:
+       if (ret < 0) {
+               dev_err(pct->dev, "%s failed (%d)\n", __func__, ret);
+               return ret;
+       }
+
+       /* set the output as 1 or 0 */
+       return abx500_gpio_set_bits(chip, AB8500_GPIO_OUT1_REG, offset, val);
+}
+
+static int abx500_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+       /* set the register as input */
+       return abx500_gpio_set_bits(chip,
+                               AB8500_GPIO_DIR1_REG,
+                               offset,
+                               ABX500_GPIO_INPUT);
+}
+
+static int abx500_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+       struct abx500_pinctrl *pct = to_abx500_pinctrl(chip);
+       /* The AB8500 GPIO numbers are off by one */
+       int gpio = offset + 1;
+       int hwirq;
+       int i;
+
+       for (i = 0; i < pct->irq_cluster_size; i++) {
+               struct abx500_gpio_irq_cluster *cluster =
+                       &pct->irq_cluster[i];
+
+               if (gpio >= cluster->start && gpio <= cluster->end) {
+                       /*
+                        * The ABx500 GPIO's associated IRQs are clustered together
+                        * throughout the interrupt numbers at irregular intervals.
+                        * To solve this quandry, we have placed the read-in values
+                        * into the cluster information table.
+                        */
+                       hwirq = gpio - cluster->start + cluster->to_irq;
+                       return irq_create_mapping(pct->parent->domain, hwirq);
+               }
+       }
+
+       return -EINVAL;
+}
+
+static int abx500_set_mode(struct pinctrl_dev *pctldev, struct gpio_chip *chip,
+                          unsigned gpio, int alt_setting)
+{
+       struct abx500_pinctrl *pct = pinctrl_dev_get_drvdata(pctldev);
+       struct alternate_functions af = pct->soc->alternate_functions[gpio];
+       int ret;
+       int val;
+       unsigned offset;
+
+       const char *modes[] = {
+               [ABX500_DEFAULT]        = "default",
+               [ABX500_ALT_A]          = "altA",
+               [ABX500_ALT_B]          = "altB",
+               [ABX500_ALT_C]          = "altC",
+       };
+
+       /* sanity check */
+       if (((alt_setting == ABX500_ALT_A) && (af.gpiosel_bit == UNUSED)) ||
+           ((alt_setting == ABX500_ALT_B) && (af.alt_bit1 == UNUSED)) ||
+           ((alt_setting == ABX500_ALT_C) && (af.alt_bit2 == UNUSED))) {
+               dev_dbg(pct->dev, "pin %d doesn't support %s mode\n", gpio,
+                               modes[alt_setting]);
+               return -EINVAL;
+       }
+
+       /* on ABx5xx, there is no GPIO0, so adjust the offset */
+       offset = gpio - 1;
+
+       switch (alt_setting) {
+       case ABX500_DEFAULT:
+               /*
+                * for ABx5xx family, default mode is always selected by
+                * writing 0 to GPIOSELx register, except for pins which
+                * support at least ALT_B mode, default mode is selected
+                * by writing 1 to GPIOSELx register
+                */
+               val = 0;
+               if (af.alt_bit1 != UNUSED)
+                       val++;
+
+               ret = abx500_gpio_set_bits(chip, AB8500_GPIO_SEL1_REG,
+                                          offset, val);
+               break;
+
+       case ABX500_ALT_A:
+               /*
+                * for ABx5xx family, alt_a mode is always selected by
+                * writing 1 to GPIOSELx register, except for pins which
+                * support at least ALT_B mode, alt_a mode is selected
+                * by writing 0 to GPIOSELx register and 0 in ALTFUNC
+                * register
+                */
+               if (af.alt_bit1 != UNUSED) {
+                       ret = abx500_gpio_set_bits(chip, AB8500_GPIO_SEL1_REG,
+                                       offset, 0);
+                       if (ret < 0)
+                               goto out;
+
+                       ret = abx500_gpio_set_bits(chip,
+                                       AB8500_GPIO_ALTFUN_REG,
+                                       af.alt_bit1,
+                                       !!(af.alta_val & BIT(0)));
+                       if (ret < 0)
+                               goto out;
+
+                       if (af.alt_bit2 != UNUSED)
+                               ret = abx500_gpio_set_bits(chip,
+                                       AB8500_GPIO_ALTFUN_REG,
+                                       af.alt_bit2,
+                                       !!(af.alta_val & BIT(1)));
+               } else
+                       ret = abx500_gpio_set_bits(chip, AB8500_GPIO_SEL1_REG,
+                                       offset, 1);
+               break;
+
+       case ABX500_ALT_B:
+               ret = abx500_gpio_set_bits(chip, AB8500_GPIO_SEL1_REG,
+                               offset, 0);
+               if (ret < 0)
+                       goto out;
+
+               ret = abx500_gpio_set_bits(chip, AB8500_GPIO_ALTFUN_REG,
+                               af.alt_bit1, !!(af.altb_val & BIT(0)));
+               if (ret < 0)
+                       goto out;
+
+               if (af.alt_bit2 != UNUSED)
+                       ret = abx500_gpio_set_bits(chip,
+                                       AB8500_GPIO_ALTFUN_REG,
+                                       af.alt_bit2,
+                                       !!(af.altb_val & BIT(1)));
+               break;
+
+       case ABX500_ALT_C:
+               ret = abx500_gpio_set_bits(chip, AB8500_GPIO_SEL1_REG,
+                               offset, 0);
+               if (ret < 0)
+                       goto out;
+
+               ret = abx500_gpio_set_bits(chip, AB8500_GPIO_ALTFUN_REG,
+                               af.alt_bit2, !!(af.altc_val & BIT(0)));
+               if (ret < 0)
+                       goto out;
+
+               ret = abx500_gpio_set_bits(chip, AB8500_GPIO_ALTFUN_REG,
+                               af.alt_bit2, !!(af.altc_val & BIT(1)));
+               break;
+
+       default:
+               dev_dbg(pct->dev, "unknow alt_setting %d\n", alt_setting);
+
+               return -EINVAL;
+       }
+out:
+       if (ret < 0)
+               dev_err(pct->dev, "%s failed (%d)\n", __func__, ret);
+
+       return ret;
+}
+
+static int abx500_get_mode(struct pinctrl_dev *pctldev, struct gpio_chip *chip,
+                         unsigned gpio)
+{
+       u8 mode;
+       bool bit_mode;
+       bool alt_bit1;
+       bool alt_bit2;
+       struct abx500_pinctrl *pct = pinctrl_dev_get_drvdata(pctldev);
+       struct alternate_functions af = pct->soc->alternate_functions[gpio];
+       /* on ABx5xx, there is no GPIO0, so adjust the offset */
+       unsigned offset = gpio - 1;
+       int ret;
+
+       /*
+        * if gpiosel_bit is set to unused,
+        * it means no GPIO or special case
+        */
+       if (af.gpiosel_bit == UNUSED)
+               return ABX500_DEFAULT;
+
+       /* read GpioSelx register */
+       ret = abx500_gpio_get_bit(chip, AB8500_GPIO_SEL1_REG + (offset / 8),
+                       af.gpiosel_bit, &bit_mode);
+       if (ret < 0)
+               goto out;
+
+       mode = bit_mode;
+
+       /* sanity check */
+       if ((af.alt_bit1 < UNUSED) || (af.alt_bit1 > 7) ||
+           (af.alt_bit2 < UNUSED) || (af.alt_bit2 > 7)) {
+               dev_err(pct->dev,
+                       "alt_bitX value not in correct range (-1 to 7)\n");
+               return -EINVAL;
+       }
+
+       /* if alt_bit2 is used, alt_bit1 must be used too */
+       if ((af.alt_bit2 != UNUSED) && (af.alt_bit1 == UNUSED)) {
+               dev_err(pct->dev,
+                       "if alt_bit2 is used, alt_bit1 can't be unused\n");
+               return -EINVAL;
+       }
+
+       /* check if pin use AlternateFunction register */
+       if ((af.alt_bit1 == UNUSED) && (af.alt_bit2 == UNUSED))
+               return mode;
+       /*
+        * if pin GPIOSEL bit is set and pin supports alternate function,
+        * it means DEFAULT mode
+        */
+       if (mode)
+               return ABX500_DEFAULT;
+
+       /*
+        * pin use the AlternatFunction register
+        * read alt_bit1 value
+        */
+       ret = abx500_gpio_get_bit(chip, AB8500_GPIO_ALTFUN_REG,
+                           af.alt_bit1, &alt_bit1);
+       if (ret < 0)
+               goto out;
+
+       if (af.alt_bit2 != UNUSED) {
+               /* read alt_bit2 value */
+               ret = abx500_gpio_get_bit(chip, AB8500_GPIO_ALTFUN_REG,
+                               af.alt_bit2,
+                               &alt_bit2);
+               if (ret < 0)
+                       goto out;
+       } else
+               alt_bit2 = 0;
+
+       mode = (alt_bit2 << 1) + alt_bit1;
+       if (mode == af.alta_val)
+               return ABX500_ALT_A;
+       else if (mode == af.altb_val)
+               return ABX500_ALT_B;
+       else
+               return ABX500_ALT_C;
+
+out:
+       dev_err(pct->dev, "%s failed (%d)\n", __func__, ret);
+       return ret;
+}
+
+#ifdef CONFIG_DEBUG_FS
+
+#include <linux/seq_file.h>
+
+static void abx500_gpio_dbg_show_one(struct seq_file *s,
+                                    struct pinctrl_dev *pctldev,
+                                    struct gpio_chip *chip,
+                                    unsigned offset, unsigned gpio)
+{
+       struct abx500_pinctrl *pct = pinctrl_dev_get_drvdata(pctldev);
+       const char *label = gpiochip_is_requested(chip, offset - 1);
+       u8 gpio_offset = offset - 1;
+       int mode = -1;
+       bool is_out;
+       bool pd;
+       enum abx500_gpio_pull_updown pud = 0;
+       int ret;
+
+       const char *modes[] = {
+               [ABX500_DEFAULT]        = "default",
+               [ABX500_ALT_A]          = "altA",
+               [ABX500_ALT_B]          = "altB",
+               [ABX500_ALT_C]          = "altC",
+       };
+
+       const char *pull_up_down[] = {
+               [ABX500_GPIO_PULL_DOWN]         = "pull down",
+               [ABX500_GPIO_PULL_NONE]         = "pull none",
+               [ABX500_GPIO_PULL_NONE + 1]     = "pull none",
+               [ABX500_GPIO_PULL_UP]           = "pull up",
+       };
+
+       ret = abx500_gpio_get_bit(chip, AB8500_GPIO_DIR1_REG,
+                       gpio_offset, &is_out);
+       if (ret < 0)
+               goto out;
+
+       seq_printf(s, " gpio-%-3d (%-20.20s) %-3s",
+                  gpio, label ?: "(none)",
+                  is_out ? "out" : "in ");
+
+       if (!is_out) {
+               if (abx500_pullud_supported(chip, offset)) {
+                       ret = abx500_get_pull_updown(pct, offset, &pud);
+                       if (ret < 0)
+                               goto out;
+
+                       seq_printf(s, " %-9s", pull_up_down[pud]);
+               } else {
+                       ret = abx500_gpio_get_bit(chip, AB8500_GPIO_PUD1_REG,
+                                       gpio_offset, &pd);
+                       if (ret < 0)
+                               goto out;
+
+                       seq_printf(s, " %-9s", pull_up_down[pd]);
+               }
+       } else
+               seq_printf(s, " %-9s", chip->get(chip, offset) ? "hi" : "lo");
+
+       if (pctldev)
+               mode = abx500_get_mode(pctldev, chip, offset);
+
+       seq_printf(s, " %s", (mode < 0) ? "unknown" : modes[mode]);
+
+out:
+       if (ret < 0)
+               dev_err(pct->dev, "%s failed (%d)\n", __func__, ret);
+}
+
+static void abx500_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
+{
+       unsigned i;
+       unsigned gpio = chip->base;
+       struct abx500_pinctrl *pct = to_abx500_pinctrl(chip);
+       struct pinctrl_dev *pctldev = pct->pctldev;
+
+       for (i = 0; i < chip->ngpio; i++, gpio++) {
+               /* On AB8500, there is no GPIO0, the first is the GPIO 1 */
+               abx500_gpio_dbg_show_one(s, pctldev, chip, i + 1, gpio);
+               seq_printf(s, "\n");
+       }
+}
+
+#else
+static inline void abx500_gpio_dbg_show_one(struct seq_file *s,
+                                           struct pinctrl_dev *pctldev,
+                                           struct gpio_chip *chip,
+                                           unsigned offset, unsigned gpio)
+{
+}
+#define abx500_gpio_dbg_show   NULL
+#endif
+
+static int abx500_gpio_request(struct gpio_chip *chip, unsigned offset)
+{
+       int gpio = chip->base + offset;
+
+       return pinctrl_request_gpio(gpio);
+}
+
+static void abx500_gpio_free(struct gpio_chip *chip, unsigned offset)
+{
+       int gpio = chip->base + offset;
+
+       pinctrl_free_gpio(gpio);
+}
+
+static struct gpio_chip abx500gpio_chip = {
+       .label                  = "abx500-gpio",
+       .owner                  = THIS_MODULE,
+       .request                = abx500_gpio_request,
+       .free                   = abx500_gpio_free,
+       .direction_input        = abx500_gpio_direction_input,
+       .get                    = abx500_gpio_get,
+       .direction_output       = abx500_gpio_direction_output,
+       .set                    = abx500_gpio_set,
+       .to_irq                 = abx500_gpio_to_irq,
+       .dbg_show               = abx500_gpio_dbg_show,
+};
+
+static int abx500_pmx_get_funcs_cnt(struct pinctrl_dev *pctldev)
+{
+       struct abx500_pinctrl *pct = pinctrl_dev_get_drvdata(pctldev);
+
+       return pct->soc->nfunctions;
+}
+
+static const char *abx500_pmx_get_func_name(struct pinctrl_dev *pctldev,
+                                        unsigned function)
+{
+       struct abx500_pinctrl *pct = pinctrl_dev_get_drvdata(pctldev);
+
+       return pct->soc->functions[function].name;
+}
+
+static int abx500_pmx_get_func_groups(struct pinctrl_dev *pctldev,
+                                     unsigned function,
+                                     const char * const **groups,
+                                     unsigned * const num_groups)
+{
+       struct abx500_pinctrl *pct = pinctrl_dev_get_drvdata(pctldev);
+
+       *groups = pct->soc->functions[function].groups;
+       *num_groups = pct->soc->functions[function].ngroups;
+
+       return 0;
+}
+
+static int abx500_pmx_enable(struct pinctrl_dev *pctldev, unsigned function,
+                            unsigned group)
+{
+       struct abx500_pinctrl *pct = pinctrl_dev_get_drvdata(pctldev);
+       struct gpio_chip *chip = &pct->chip;
+       const struct abx500_pingroup *g;
+       int i;
+       int ret = 0;
+
+       g = &pct->soc->groups[group];
+       if (g->altsetting < 0)
+               return -EINVAL;
+
+       dev_dbg(pct->dev, "enable group %s, %u pins\n", g->name, g->npins);
+
+       for (i = 0; i < g->npins; i++) {
+               dev_dbg(pct->dev, "setting pin %d to altsetting %d\n",
+                       g->pins[i], g->altsetting);
+
+               ret = abx500_set_mode(pctldev, chip, g->pins[i], g->altsetting);
+       }
+
+       if (ret < 0)
+               dev_err(pct->dev, "%s failed (%d)\n", __func__, ret);
+
+       return ret;
+}
+
+static int abx500_gpio_request_enable(struct pinctrl_dev *pctldev,
+                              struct pinctrl_gpio_range *range,
+                              unsigned offset)
+{
+       struct abx500_pinctrl *pct = pinctrl_dev_get_drvdata(pctldev);
+       const struct abx500_pinrange *p;
+       int ret;
+       int i;
+
+       /*
+        * Different ranges have different ways to enable GPIO function on a
+        * pin, so refer back to our local range type, where we handily define
+        * what altfunc enables GPIO for a certain pin.
+        */
+       for (i = 0; i < pct->soc->gpio_num_ranges; i++) {
+               p = &pct->soc->gpio_ranges[i];
+               if ((offset >= p->offset) &&
+                   (offset < (p->offset + p->npins)))
+                 break;
+       }
+
+       if (i == pct->soc->gpio_num_ranges) {
+               dev_err(pct->dev, "%s failed to locate range\n", __func__);
+               return -ENODEV;
+       }
+
+       dev_dbg(pct->dev, "enable GPIO by altfunc %d at gpio %d\n",
+               p->altfunc, offset);
+
+       ret = abx500_set_mode(pct->pctldev, &pct->chip,
+                             offset, p->altfunc);
+       if (ret < 0)
+               dev_err(pct->dev, "%s setting altfunc failed\n", __func__);
+
+       return ret;
+}
+
+static void abx500_gpio_disable_free(struct pinctrl_dev *pctldev,
+                                    struct pinctrl_gpio_range *range,
+                                    unsigned offset)
+{
+}
+
+static const struct pinmux_ops abx500_pinmux_ops = {
+       .get_functions_count = abx500_pmx_get_funcs_cnt,
+       .get_function_name = abx500_pmx_get_func_name,
+       .get_function_groups = abx500_pmx_get_func_groups,
+       .enable = abx500_pmx_enable,
+       .gpio_request_enable = abx500_gpio_request_enable,
+       .gpio_disable_free = abx500_gpio_disable_free,
+};
+
+static int abx500_get_groups_cnt(struct pinctrl_dev *pctldev)
+{
+       struct abx500_pinctrl *pct = pinctrl_dev_get_drvdata(pctldev);
+
+       return pct->soc->ngroups;
+}
+
+static const char *abx500_get_group_name(struct pinctrl_dev *pctldev,
+                                        unsigned selector)
+{
+       struct abx500_pinctrl *pct = pinctrl_dev_get_drvdata(pctldev);
+
+       return pct->soc->groups[selector].name;
+}
+
+static int abx500_get_group_pins(struct pinctrl_dev *pctldev,
+                                unsigned selector,
+                                const unsigned **pins,
+                                unsigned *num_pins)
+{
+       struct abx500_pinctrl *pct = pinctrl_dev_get_drvdata(pctldev);
+
+       *pins = pct->soc->groups[selector].pins;
+       *num_pins = pct->soc->groups[selector].npins;
+
+       return 0;
+}
+
+static void abx500_pin_dbg_show(struct pinctrl_dev *pctldev,
+                               struct seq_file *s, unsigned offset)
+{
+       struct abx500_pinctrl *pct = pinctrl_dev_get_drvdata(pctldev);
+       struct gpio_chip *chip = &pct->chip;
+
+       abx500_gpio_dbg_show_one(s, pctldev, chip, offset,
+                                chip->base + offset - 1);
+}
+
+static void abx500_dt_free_map(struct pinctrl_dev *pctldev,
+               struct pinctrl_map *map, unsigned num_maps)
+{
+       int i;
+
+       for (i = 0; i < num_maps; i++)
+               if (map[i].type == PIN_MAP_TYPE_CONFIGS_PIN)
+                       kfree(map[i].data.configs.configs);
+       kfree(map);
+}
+
+static int abx500_dt_reserve_map(struct pinctrl_map **map,
+               unsigned *reserved_maps,
+               unsigned *num_maps,
+               unsigned reserve)
+{
+       unsigned old_num = *reserved_maps;
+       unsigned new_num = *num_maps + reserve;
+       struct pinctrl_map *new_map;
+
+       if (old_num >= new_num)
+               return 0;
+
+       new_map = krealloc(*map, sizeof(*new_map) * new_num, GFP_KERNEL);
+       if (!new_map)
+               return -ENOMEM;
+
+       memset(new_map + old_num, 0, (new_num - old_num) * sizeof(*new_map));
+
+       *map = new_map;
+       *reserved_maps = new_num;
+
+       return 0;
+}
+
+static int abx500_dt_add_map_mux(struct pinctrl_map **map,
+               unsigned *reserved_maps,
+               unsigned *num_maps, const char *group,
+               const char *function)
+{
+       if (*num_maps == *reserved_maps)
+               return -ENOSPC;
+
+       (*map)[*num_maps].type = PIN_MAP_TYPE_MUX_GROUP;
+       (*map)[*num_maps].data.mux.group = group;
+       (*map)[*num_maps].data.mux.function = function;
+       (*num_maps)++;
+
+       return 0;
+}
+
+static int abx500_dt_add_map_configs(struct pinctrl_map **map,
+               unsigned *reserved_maps,
+               unsigned *num_maps, const char *group,
+               unsigned long *configs, unsigned num_configs)
+{
+       unsigned long *dup_configs;
+
+       if (*num_maps == *reserved_maps)
+               return -ENOSPC;
+
+       dup_configs = kmemdup(configs, num_configs * sizeof(*dup_configs),
+                             GFP_KERNEL);
+       if (!dup_configs)
+               return -ENOMEM;
+
+       (*map)[*num_maps].type = PIN_MAP_TYPE_CONFIGS_PIN;
+
+       (*map)[*num_maps].data.configs.group_or_pin = group;
+       (*map)[*num_maps].data.configs.configs = dup_configs;
+       (*map)[*num_maps].data.configs.num_configs = num_configs;
+       (*num_maps)++;
+
+       return 0;
+}
+
+static const char *abx500_find_pin_name(struct pinctrl_dev *pctldev,
+                                       const char *pin_name)
+{
+       int i, pin_number;
+       struct abx500_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
+
+       if (sscanf((char *)pin_name, "GPIO%d", &pin_number) == 1)
+               for (i = 0; i < npct->soc->npins; i++)
+                       if (npct->soc->pins[i].number == pin_number)
+                               return npct->soc->pins[i].name;
+       return NULL;
+}
+
+static int abx500_dt_subnode_to_map(struct pinctrl_dev *pctldev,
+               struct device_node *np,
+               struct pinctrl_map **map,
+               unsigned *reserved_maps,
+               unsigned *num_maps)
+{
+       int ret;
+       const char *function = NULL;
+       unsigned long *configs;
+       unsigned int nconfigs = 0;
+       bool has_config = 0;
+       unsigned reserve = 0;
+       struct property *prop;
+       const char *group, *gpio_name;
+       struct device_node *np_config;
+
+       ret = of_property_read_string(np, "ste,function", &function);
+       if (ret >= 0)
+               reserve = 1;
+
+       ret = pinconf_generic_parse_dt_config(np, &configs, &nconfigs);
+       if (nconfigs)
+               has_config = 1;
+
+       np_config = of_parse_phandle(np, "ste,config", 0);
+       if (np_config) {
+               ret = pinconf_generic_parse_dt_config(np_config, &configs,
+                               &nconfigs);
+               if (ret)
+                       goto exit;
+               has_config |= nconfigs;
+       }
+
+       ret = of_property_count_strings(np, "ste,pins");
+       if (ret < 0)
+               goto exit;
+
+       if (has_config)
+               reserve++;
+
+       reserve *= ret;
+
+       ret = abx500_dt_reserve_map(map, reserved_maps, num_maps, reserve);
+       if (ret < 0)
+               goto exit;
+
+       of_property_for_each_string(np, "ste,pins", prop, group) {
+               if (function) {
+                       ret = abx500_dt_add_map_mux(map, reserved_maps,
+                                       num_maps, group, function);
+                       if (ret < 0)
+                               goto exit;
+               }
+               if (has_config) {
+                       gpio_name = abx500_find_pin_name(pctldev, group);
+
+                       ret = abx500_dt_add_map_configs(map, reserved_maps,
+                                       num_maps, gpio_name, configs, 1);
+                       if (ret < 0)
+                               goto exit;
+               }
+
+       }
+exit:
+       return ret;
+}
+
+static int abx500_dt_node_to_map(struct pinctrl_dev *pctldev,
+                                struct device_node *np_config,
+                                struct pinctrl_map **map, unsigned *num_maps)
+{
+       unsigned reserved_maps;
+       struct device_node *np;
+       int ret;
+
+       reserved_maps = 0;
+       *map = NULL;
+       *num_maps = 0;
+
+       for_each_child_of_node(np_config, np) {
+               ret = abx500_dt_subnode_to_map(pctldev, np, map,
+                               &reserved_maps, num_maps);
+               if (ret < 0) {
+                       abx500_dt_free_map(pctldev, *map, *num_maps);
+                       return ret;
+               }
+       }
+
+       return 0;
+}
+
+static const struct pinctrl_ops abx500_pinctrl_ops = {
+       .get_groups_count = abx500_get_groups_cnt,
+       .get_group_name = abx500_get_group_name,
+       .get_group_pins = abx500_get_group_pins,
+       .pin_dbg_show = abx500_pin_dbg_show,
+       .dt_node_to_map = abx500_dt_node_to_map,
+       .dt_free_map = abx500_dt_free_map,
+};
+
+static int abx500_pin_config_get(struct pinctrl_dev *pctldev,
+                         unsigned pin,
+                         unsigned long *config)
+{
+       return -ENOSYS;
+}
+
+static int abx500_pin_config_set(struct pinctrl_dev *pctldev,
+                         unsigned pin,
+                         unsigned long *configs,
+                         unsigned num_configs)
+{
+       struct abx500_pinctrl *pct = pinctrl_dev_get_drvdata(pctldev);
+       struct gpio_chip *chip = &pct->chip;
+       unsigned offset;
+       int ret = -EINVAL;
+       int i;
+       enum pin_config_param param;
+       enum pin_config_param argument;
+
+       for (i = 0; i < num_configs; i++) {
+               param = pinconf_to_config_param(configs[i]);
+               argument = pinconf_to_config_argument(configs[i]);
+
+               dev_dbg(chip->dev, "pin %d [%#lx]: %s %s\n",
+                       pin, configs[i],
+                       (param == PIN_CONFIG_OUTPUT) ? "output " : "input",
+                       (param == PIN_CONFIG_OUTPUT) ?
+                       (argument ? "high" : "low") :
+                       (argument ? "pull up" : "pull down"));
+
+               /* on ABx500, there is no GPIO0, so adjust the offset */
+               offset = pin - 1;
+
+               switch (param) {
+               case PIN_CONFIG_BIAS_DISABLE:
+                       ret = abx500_gpio_direction_input(chip, offset);
+                       if (ret < 0)
+                               goto out;
+                       /*
+                        * Some chips only support pull down, while some
+                        * actually support both pull up and pull down. Such
+                        * chips have a "pullud" range specified for the pins
+                        * that support both features. If the pin is not
+                        * within that range, we fall back to the old bit set
+                        * that only support pull down.
+                        */
+                       if (abx500_pullud_supported(chip, pin))
+                               ret = abx500_set_pull_updown(pct,
+                                       pin,
+                                       ABX500_GPIO_PULL_NONE);
+                       else
+                               /* Chip only supports pull down */
+                               ret = abx500_gpio_set_bits(chip,
+                                       AB8500_GPIO_PUD1_REG, offset,
+                                       ABX500_GPIO_PULL_NONE);
+                       break;
+
+               case PIN_CONFIG_BIAS_PULL_DOWN:
+                       ret = abx500_gpio_direction_input(chip, offset);
+                       if (ret < 0)
+                               goto out;
+                       /*
+                        * if argument = 1 set the pull down
+                        * else clear the pull down
+                        * Some chips only support pull down, while some
+                        * actually support both pull up and pull down. Such
+                        * chips have a "pullud" range specified for the pins
+                        * that support both features. If the pin is not
+                        * within that range, we fall back to the old bit set
+                        * that only support pull down.
+                        */
+                       if (abx500_pullud_supported(chip, pin))
+                               ret = abx500_set_pull_updown(pct,
+                                       pin,
+                                       argument ? ABX500_GPIO_PULL_DOWN :
+                                       ABX500_GPIO_PULL_NONE);
+                       else
+                               /* Chip only supports pull down */
+                               ret = abx500_gpio_set_bits(chip,
+                               AB8500_GPIO_PUD1_REG,
+                                       offset,
+                                       argument ? ABX500_GPIO_PULL_DOWN :
+                                       ABX500_GPIO_PULL_NONE);
+                       break;
+
+               case PIN_CONFIG_BIAS_PULL_UP:
+                       ret = abx500_gpio_direction_input(chip, offset);
+                       if (ret < 0)
+                               goto out;
+                       /*
+                        * if argument = 1 set the pull up
+                        * else clear the pull up
+                        */
+                       ret = abx500_gpio_direction_input(chip, offset);
+                       /*
+                        * Some chips only support pull down, while some
+                        * actually support both pull up and pull down. Such
+                        * chips have a "pullud" range specified for the pins
+                        * that support both features. If the pin is not
+                        * within that range, do nothing
+                        */
+                       if (abx500_pullud_supported(chip, pin))
+                               ret = abx500_set_pull_updown(pct,
+                                       pin,
+                                       argument ? ABX500_GPIO_PULL_UP :
+                                       ABX500_GPIO_PULL_NONE);
+                       break;
+
+               case PIN_CONFIG_OUTPUT:
+                       ret = abx500_gpio_direction_output(chip, offset,
+                               argument);
+                       break;
+
+               default:
+                       dev_err(chip->dev, "illegal configuration requested\n");
+               }
+       } /* for each config */
+out:
+       if (ret < 0)
+               dev_err(pct->dev, "%s failed (%d)\n", __func__, ret);
+
+       return ret;
+}
+
+static const struct pinconf_ops abx500_pinconf_ops = {
+       .pin_config_get = abx500_pin_config_get,
+       .pin_config_set = abx500_pin_config_set,
+};
+
+static struct pinctrl_desc abx500_pinctrl_desc = {
+       .name = "pinctrl-abx500",
+       .pctlops = &abx500_pinctrl_ops,
+       .pmxops = &abx500_pinmux_ops,
+       .confops = &abx500_pinconf_ops,
+       .owner = THIS_MODULE,
+};
+
+static int abx500_get_gpio_num(struct abx500_pinctrl_soc_data *soc)
+{
+       unsigned int lowest = 0;
+       unsigned int highest = 0;
+       unsigned int npins = 0;
+       int i;
+
+       /*
+        * Compute number of GPIOs from the last SoC gpio range descriptors
+        * These ranges may include "holes" but the GPIO number space shall
+        * still be homogeneous, so we need to detect and account for any
+        * such holes so that these are included in the number of GPIO pins.
+        */
+       for (i = 0; i < soc->gpio_num_ranges; i++) {
+               unsigned gstart;
+               unsigned gend;
+               const struct abx500_pinrange *p;
+
+               p = &soc->gpio_ranges[i];
+               gstart = p->offset;
+               gend = p->offset + p->npins - 1;
+
+               if (i == 0) {
+                       /* First iteration, set start values */
+                       lowest = gstart;
+                       highest = gend;
+               } else {
+                       if (gstart < lowest)
+                               lowest = gstart;
+                       if (gend > highest)
+                               highest = gend;
+               }
+       }
+       /* this gives the absolute number of pins */
+       npins = highest - lowest + 1;
+       return npins;
+}
+
+static const struct of_device_id abx500_gpio_match[] = {
+       { .compatible = "stericsson,ab8500-gpio", .data = (void *)PINCTRL_AB8500, },
+       { .compatible = "stericsson,ab8505-gpio", .data = (void *)PINCTRL_AB8505, },
+       { .compatible = "stericsson,ab8540-gpio", .data = (void *)PINCTRL_AB8540, },
+       { .compatible = "stericsson,ab9540-gpio", .data = (void *)PINCTRL_AB9540, },
+       { }
+};
+
+static int abx500_gpio_probe(struct platform_device *pdev)
+{
+       struct device_node *np = pdev->dev.of_node;
+       const struct of_device_id *match;
+       struct abx500_pinctrl *pct;
+       unsigned int id = -1;
+       int ret, err;
+       int i;
+
+       if (!np) {
+               dev_err(&pdev->dev, "gpio dt node missing\n");
+               return -ENODEV;
+       }
+
+       pct = devm_kzalloc(&pdev->dev, sizeof(struct abx500_pinctrl),
+                                  GFP_KERNEL);
+       if (pct == NULL) {
+               dev_err(&pdev->dev,
+                       "failed to allocate memory for pct\n");
+               return -ENOMEM;
+       }
+
+       pct->dev = &pdev->dev;
+       pct->parent = dev_get_drvdata(pdev->dev.parent);
+       pct->chip = abx500gpio_chip;
+       pct->chip.dev = &pdev->dev;
+       pct->chip.base = -1; /* Dynamic allocation */
+
+       match = of_match_device(abx500_gpio_match, &pdev->dev);
+       if (!match) {
+               dev_err(&pdev->dev, "gpio dt not matching\n");
+               return -ENODEV;
+       }
+       id = (unsigned long)match->data;
+
+       /* Poke in other ASIC variants here */
+       switch (id) {
+       case PINCTRL_AB8500:
+               abx500_pinctrl_ab8500_init(&pct->soc);
+               break;
+       case PINCTRL_AB8540:
+               abx500_pinctrl_ab8540_init(&pct->soc);
+               break;
+       case PINCTRL_AB9540:
+               abx500_pinctrl_ab9540_init(&pct->soc);
+               break;
+       case PINCTRL_AB8505:
+               abx500_pinctrl_ab8505_init(&pct->soc);
+               break;
+       default:
+               dev_err(&pdev->dev, "Unsupported pinctrl sub driver (%d)\n", id);
+               return -EINVAL;
+       }
+
+       if (!pct->soc) {
+               dev_err(&pdev->dev, "Invalid SOC data\n");
+               return -EINVAL;
+       }
+
+       pct->chip.ngpio = abx500_get_gpio_num(pct->soc);
+       pct->irq_cluster = pct->soc->gpio_irq_cluster;
+       pct->irq_cluster_size = pct->soc->ngpio_irq_cluster;
+
+       ret = gpiochip_add(&pct->chip);
+       if (ret) {
+               dev_err(&pdev->dev, "unable to add gpiochip: %d\n", ret);
+               return ret;
+       }
+       dev_info(&pdev->dev, "added gpiochip\n");
+
+       abx500_pinctrl_desc.pins = pct->soc->pins;
+       abx500_pinctrl_desc.npins = pct->soc->npins;
+       pct->pctldev = pinctrl_register(&abx500_pinctrl_desc, &pdev->dev, pct);
+       if (!pct->pctldev) {
+               dev_err(&pdev->dev,
+                       "could not register abx500 pinctrl driver\n");
+               ret = -EINVAL;
+               goto out_rem_chip;
+       }
+       dev_info(&pdev->dev, "registered pin controller\n");
+
+       /* We will handle a range of GPIO pins */
+       for (i = 0; i < pct->soc->gpio_num_ranges; i++) {
+               const struct abx500_pinrange *p = &pct->soc->gpio_ranges[i];
+
+               ret = gpiochip_add_pin_range(&pct->chip,
+                                       dev_name(&pdev->dev),
+                                       p->offset - 1, p->offset, p->npins);
+               if (ret < 0)
+                       goto out_rem_chip;
+       }
+
+       platform_set_drvdata(pdev, pct);
+       dev_info(&pdev->dev, "initialized abx500 pinctrl driver\n");
+
+       return 0;
+
+out_rem_chip:
+       err = gpiochip_remove(&pct->chip);
+       if (err)
+               dev_info(&pdev->dev, "failed to remove gpiochip\n");
+
+       return ret;
+}
+
+/**
+ * abx500_gpio_remove() - remove Ab8500-gpio driver
+ * @pdev:      Platform device registered
+ */
+static int abx500_gpio_remove(struct platform_device *pdev)
+{
+       struct abx500_pinctrl *pct = platform_get_drvdata(pdev);
+       int ret;
+
+       ret = gpiochip_remove(&pct->chip);
+       if (ret < 0) {
+               dev_err(pct->dev, "unable to remove gpiochip: %d\n",
+                       ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+static struct platform_driver abx500_gpio_driver = {
+       .driver = {
+               .name = "abx500-gpio",
+               .owner = THIS_MODULE,
+               .of_match_table = abx500_gpio_match,
+       },
+       .probe = abx500_gpio_probe,
+       .remove = abx500_gpio_remove,
+};
+
+static int __init abx500_gpio_init(void)
+{
+       return platform_driver_register(&abx500_gpio_driver);
+}
+core_initcall(abx500_gpio_init);
+
+MODULE_AUTHOR("Patrice Chotard <patrice.chotard@st.com>");
+MODULE_DESCRIPTION("Driver allows to use AxB5xx unused pins to be used as GPIO");
+MODULE_ALIAS("platform:abx500-gpio");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/pinctrl/nomadik/pinctrl-abx500.h b/drivers/pinctrl/nomadik/pinctrl-abx500.h
new file mode 100644 (file)
index 0000000..2beef3b
--- /dev/null
@@ -0,0 +1,246 @@
+#ifndef PINCTRL_PINCTRL_ABx500_H
+#define PINCTRL_PINCTRL_ABx500_H
+
+/* Package definitions */
+#define PINCTRL_AB8500 0
+#define PINCTRL_AB8540 1
+#define PINCTRL_AB9540 2
+#define PINCTRL_AB8505 3
+
+/* pins alternate function */
+enum abx500_pin_func {
+       ABX500_DEFAULT,
+       ABX500_ALT_A,
+       ABX500_ALT_B,
+       ABX500_ALT_C,
+};
+
+enum abx500_gpio_pull_updown {
+       ABX500_GPIO_PULL_DOWN = 0x0,
+       ABX500_GPIO_PULL_NONE = 0x1,
+       ABX500_GPIO_PULL_UP = 0x3,
+};
+
+enum abx500_gpio_vinsel {
+       ABX500_GPIO_VINSEL_VBAT = 0x0,
+       ABX500_GPIO_VINSEL_VIN_1V8 = 0x1,
+       ABX500_GPIO_VINSEL_VDD_BIF = 0x2,
+};
+
+/**
+ * struct abx500_function - ABx500 pinctrl mux function
+ * @name: The name of the function, exported to pinctrl core.
+ * @groups: An array of pin groups that may select this function.
+ * @ngroups: The number of entries in @groups.
+ */
+struct abx500_function {
+       const char *name;
+       const char * const *groups;
+       unsigned ngroups;
+};
+
+/**
+ * struct abx500_pingroup - describes a ABx500 pin group
+ * @name: the name of this specific pin group
+ * @pins: an array of discrete physical pins used in this group, taken
+ *     from the driver-local pin enumeration space
+ * @num_pins: the number of pins in this group array, i.e. the number of
+ *     elements in .pins so we can iterate over that array
+ * @altsetting: the altsetting to apply to all pins in this group to
+ *     configure them to be used by a function
+ */
+struct abx500_pingroup {
+       const char *name;
+       const unsigned int *pins;
+       const unsigned npins;
+       int altsetting;
+};
+
+#define ALTERNATE_FUNCTIONS(pin, sel_bit, alt1, alt2, alta, altb, altc)        \
+{                                                                      \
+       .pin_number = pin,                                              \
+       .gpiosel_bit = sel_bit,                                         \
+       .alt_bit1 = alt1,                                               \
+       .alt_bit2 = alt2,                                               \
+       .alta_val = alta,                                               \
+       .altb_val = altb,                                               \
+       .altc_val = altc,                                               \
+}
+
+#define UNUSED -1
+/**
+ * struct alternate_functions
+ * @pin_number:                The pin number
+ * @gpiosel_bit:       Control bit in GPIOSEL register,
+ * @alt_bit1:          First AlternateFunction bit used to select the
+ *                     alternate function
+ * @alt_bit2:          Second AlternateFunction bit used to select the
+ *                     alternate function
+ *
+ *                     these 3 following fields are necessary due to none
+ *                     coherency on how to select the altA, altB and altC
+ *                     function between the ABx500 SOC family when using
+ *                     alternatfunc register.
+ * @alta_val:          value to write in alternatfunc to select altA function
+ * @altb_val:          value to write in alternatfunc to select altB function
+ * @altc_val:          value to write in alternatfunc to select altC function
+ */
+struct alternate_functions {
+       unsigned pin_number;
+       s8 gpiosel_bit;
+       s8 alt_bit1;
+       s8 alt_bit2;
+       u8 alta_val;
+       u8 altb_val;
+       u8 altc_val;
+};
+
+/**
+ * struct pullud - specific pull up/down feature
+ * @first_pin:         The pin number of the first pins which support
+ *                     specific pull up/down
+ * @last_pin:          The pin number of the last pins
+ */
+struct pullud {
+       unsigned first_pin;
+       unsigned last_pin;
+};
+
+#define GPIO_IRQ_CLUSTER(a, b, c)      \
+{                                      \
+       .start = a,                     \
+       .end = b,                       \
+       .to_irq = c,                    \
+}
+
+/**
+ * struct abx500_gpio_irq_cluster - indicates GPIOs which are interrupt
+ *                     capable
+ * @start:             The pin number of the first pin interrupt capable
+ * @end:               The pin number of the last pin interrupt capable
+ * @to_irq:            The ABx500 GPIO's associated IRQs are clustered
+ *                      together throughout the interrupt numbers at irregular
+ *                      intervals. To solve this quandary, we will place the
+ *                      read-in values into the cluster information table
+ */
+
+struct abx500_gpio_irq_cluster {
+       int start;
+       int end;
+       int to_irq;
+};
+
+/**
+ * struct abx500_pinrange - map pin numbers to GPIO offsets
+ * @offset:            offset into the GPIO local numberspace, incidentally
+ *                     identical to the offset into the local pin numberspace
+ * @npins:             number of pins to map from both offsets
+ * @altfunc:           altfunc setting to be used to enable GPIO on a pin in
+ *                     this range (may vary)
+ */
+struct abx500_pinrange {
+       unsigned int offset;
+       unsigned int npins;
+       int altfunc;
+};
+
+#define ABX500_PINRANGE(a, b, c) { .offset = a, .npins = b, .altfunc = c }
+
+/**
+ * struct abx500_pinctrl_soc_data - ABx500 pin controller per-SoC configuration
+ * @gpio_ranges:       An array of GPIO ranges for this SoC
+ * @gpio_num_ranges:   The number of GPIO ranges for this SoC
+ * @pins:              An array describing all pins the pin controller affects.
+ *                     All pins which are also GPIOs must be listed first within the
+ *                     array, and be numbered identically to the GPIO controller's
+ *                     numbering.
+ * @npins:             The number of entries in @pins.
+ * @functions:         The functions supported on this SoC.
+ * @nfunction:         The number of entries in @functions.
+ * @groups:            An array describing all pin groups the pin SoC supports.
+ * @ngroups:           The number of entries in @groups.
+ * @alternate_functions: array describing pins which supports alternate and
+ *                     how to set it.
+ * @pullud:            array describing pins which supports pull up/down
+ *                     specific registers.
+ * @gpio_irq_cluster:  An array of GPIO interrupt capable for this SoC
+ * @ngpio_irq_cluster: The number of GPIO inetrrupt capable for this SoC
+ * @irq_gpio_rising_offset: Interrupt offset used as base to compute specific
+ *                     setting strategy of the rising interrupt line
+ * @irq_gpio_falling_offset: Interrupt offset used as base to compute specific
+ *                     setting strategy of the falling interrupt line
+ * @irq_gpio_factor:   Factor used to compute specific setting strategy of
+ *                     the interrupt line
+ */
+
+struct abx500_pinctrl_soc_data {
+       const struct abx500_pinrange *gpio_ranges;
+       unsigned gpio_num_ranges;
+       const struct pinctrl_pin_desc *pins;
+       unsigned npins;
+       const struct abx500_function *functions;
+       unsigned nfunctions;
+       const struct abx500_pingroup *groups;
+       unsigned ngroups;
+       struct alternate_functions *alternate_functions;
+       struct pullud *pullud;
+       struct abx500_gpio_irq_cluster *gpio_irq_cluster;
+       unsigned ngpio_irq_cluster;
+       int irq_gpio_rising_offset;
+       int irq_gpio_falling_offset;
+       int irq_gpio_factor;
+};
+
+#ifdef CONFIG_PINCTRL_AB8500
+
+void abx500_pinctrl_ab8500_init(struct abx500_pinctrl_soc_data **soc);
+
+#else
+
+static inline void
+abx500_pinctrl_ab8500_init(struct abx500_pinctrl_soc_data **soc)
+{
+}
+
+#endif
+
+#ifdef CONFIG_PINCTRL_AB8540
+
+void abx500_pinctrl_ab8540_init(struct abx500_pinctrl_soc_data **soc);
+
+#else
+
+static inline void
+abx500_pinctrl_ab8540_init(struct abx500_pinctrl_soc_data **soc)
+{
+}
+
+#endif
+
+#ifdef CONFIG_PINCTRL_AB9540
+
+void abx500_pinctrl_ab9540_init(struct abx500_pinctrl_soc_data **soc);
+
+#else
+
+static inline void
+abx500_pinctrl_ab9540_init(struct abx500_pinctrl_soc_data **soc)
+{
+}
+
+#endif
+
+#ifdef CONFIG_PINCTRL_AB8505
+
+void abx500_pinctrl_ab8505_init(struct abx500_pinctrl_soc_data **soc);
+
+#else
+
+static inline void
+abx500_pinctrl_ab8505_init(struct abx500_pinctrl_soc_data **soc)
+{
+}
+
+#endif
+
+#endif /* PINCTRL_PINCTRL_ABx500_H */
diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik-db8500.c b/drivers/pinctrl/nomadik/pinctrl-nomadik-db8500.c
new file mode 100644 (file)
index 0000000..c748407
--- /dev/null
@@ -0,0 +1,1257 @@
+#include <linux/kernel.h>
+#include <linux/pinctrl/pinctrl.h>
+#include "pinctrl-nomadik.h"
+
+/* All the pins that can be used for GPIO and some other functions */
+#define _GPIO(offset)          (offset)
+
+#define DB8500_PIN_AJ5         _GPIO(0)
+#define DB8500_PIN_AJ3         _GPIO(1)
+#define DB8500_PIN_AH4         _GPIO(2)
+#define DB8500_PIN_AH3         _GPIO(3)
+#define DB8500_PIN_AH6         _GPIO(4)
+#define DB8500_PIN_AG6         _GPIO(5)
+#define DB8500_PIN_AF6         _GPIO(6)
+#define DB8500_PIN_AG5         _GPIO(7)
+#define DB8500_PIN_AD5         _GPIO(8)
+#define DB8500_PIN_AE4         _GPIO(9)
+#define DB8500_PIN_AF5         _GPIO(10)
+#define DB8500_PIN_AG4         _GPIO(11)
+#define DB8500_PIN_AC4         _GPIO(12)
+#define DB8500_PIN_AF3         _GPIO(13)
+#define DB8500_PIN_AE3         _GPIO(14)
+#define DB8500_PIN_AC3         _GPIO(15)
+#define DB8500_PIN_AD3         _GPIO(16)
+#define DB8500_PIN_AD4         _GPIO(17)
+#define DB8500_PIN_AC2         _GPIO(18)
+#define DB8500_PIN_AC1         _GPIO(19)
+#define DB8500_PIN_AB4         _GPIO(20)
+#define DB8500_PIN_AB3         _GPIO(21)
+#define DB8500_PIN_AA3         _GPIO(22)
+#define DB8500_PIN_AA4         _GPIO(23)
+#define DB8500_PIN_AB2         _GPIO(24)
+#define DB8500_PIN_Y4          _GPIO(25)
+#define DB8500_PIN_Y2          _GPIO(26)
+#define DB8500_PIN_AA2         _GPIO(27)
+#define DB8500_PIN_AA1         _GPIO(28)
+#define DB8500_PIN_W2          _GPIO(29)
+#define DB8500_PIN_W3          _GPIO(30)
+#define DB8500_PIN_V3          _GPIO(31)
+#define DB8500_PIN_V2          _GPIO(32)
+#define DB8500_PIN_AF2         _GPIO(33)
+#define DB8500_PIN_AE1         _GPIO(34)
+#define DB8500_PIN_AE2         _GPIO(35)
+#define DB8500_PIN_AG2         _GPIO(36)
+/* Hole */
+#define DB8500_PIN_F3          _GPIO(64)
+#define DB8500_PIN_F1          _GPIO(65)
+#define DB8500_PIN_G3          _GPIO(66)
+#define DB8500_PIN_G2          _GPIO(67)
+#define DB8500_PIN_E1          _GPIO(68)
+#define DB8500_PIN_E2          _GPIO(69)
+#define DB8500_PIN_G5          _GPIO(70)
+#define DB8500_PIN_G4          _GPIO(71)
+#define DB8500_PIN_H4          _GPIO(72)
+#define DB8500_PIN_H3          _GPIO(73)
+#define DB8500_PIN_J3          _GPIO(74)
+#define DB8500_PIN_H2          _GPIO(75)
+#define DB8500_PIN_J2          _GPIO(76)
+#define DB8500_PIN_H1          _GPIO(77)
+#define DB8500_PIN_F4          _GPIO(78)
+#define DB8500_PIN_E3          _GPIO(79)
+#define DB8500_PIN_E4          _GPIO(80)
+#define DB8500_PIN_D2          _GPIO(81)
+#define DB8500_PIN_C1          _GPIO(82)
+#define DB8500_PIN_D3          _GPIO(83)
+#define DB8500_PIN_C2          _GPIO(84)
+#define DB8500_PIN_D5          _GPIO(85)
+#define DB8500_PIN_C6          _GPIO(86)
+#define DB8500_PIN_B3          _GPIO(87)
+#define DB8500_PIN_C4          _GPIO(88)
+#define DB8500_PIN_E6          _GPIO(89)
+#define DB8500_PIN_A3          _GPIO(90)
+#define DB8500_PIN_B6          _GPIO(91)
+#define DB8500_PIN_D6          _GPIO(92)
+#define DB8500_PIN_B7          _GPIO(93)
+#define DB8500_PIN_D7          _GPIO(94)
+#define DB8500_PIN_E8          _GPIO(95)
+#define DB8500_PIN_D8          _GPIO(96)
+#define DB8500_PIN_D9          _GPIO(97)
+/* Hole */
+#define DB8500_PIN_A5          _GPIO(128)
+#define DB8500_PIN_B4          _GPIO(129)
+#define DB8500_PIN_C8          _GPIO(130)
+#define DB8500_PIN_A12         _GPIO(131)
+#define DB8500_PIN_C10         _GPIO(132)
+#define DB8500_PIN_B10         _GPIO(133)
+#define DB8500_PIN_B9          _GPIO(134)
+#define DB8500_PIN_A9          _GPIO(135)
+#define DB8500_PIN_C7          _GPIO(136)
+#define DB8500_PIN_A7          _GPIO(137)
+#define DB8500_PIN_C5          _GPIO(138)
+#define DB8500_PIN_C9          _GPIO(139)
+#define DB8500_PIN_B11         _GPIO(140)
+#define DB8500_PIN_C12         _GPIO(141)
+#define DB8500_PIN_C11         _GPIO(142)
+#define DB8500_PIN_D12         _GPIO(143)
+#define DB8500_PIN_B13         _GPIO(144)
+#define DB8500_PIN_C13         _GPIO(145)
+#define DB8500_PIN_D13         _GPIO(146)
+#define DB8500_PIN_C15         _GPIO(147)
+#define DB8500_PIN_B16         _GPIO(148)
+#define DB8500_PIN_B14         _GPIO(149)
+#define DB8500_PIN_C14         _GPIO(150)
+#define DB8500_PIN_D17         _GPIO(151)
+#define DB8500_PIN_D16         _GPIO(152)
+#define DB8500_PIN_B17         _GPIO(153)
+#define DB8500_PIN_C16         _GPIO(154)
+#define DB8500_PIN_C19         _GPIO(155)
+#define DB8500_PIN_C17         _GPIO(156)
+#define DB8500_PIN_A18         _GPIO(157)
+#define DB8500_PIN_C18         _GPIO(158)
+#define DB8500_PIN_B19         _GPIO(159)
+#define DB8500_PIN_B20         _GPIO(160)
+#define DB8500_PIN_D21         _GPIO(161)
+#define DB8500_PIN_D20         _GPIO(162)
+#define DB8500_PIN_C20         _GPIO(163)
+#define DB8500_PIN_B21         _GPIO(164)
+#define DB8500_PIN_C21         _GPIO(165)
+#define DB8500_PIN_A22         _GPIO(166)
+#define DB8500_PIN_B24         _GPIO(167)
+#define DB8500_PIN_C22         _GPIO(168)
+#define DB8500_PIN_D22         _GPIO(169)
+#define DB8500_PIN_C23         _GPIO(170)
+#define DB8500_PIN_D23         _GPIO(171)
+/* Hole */
+#define DB8500_PIN_AJ27                _GPIO(192)
+#define DB8500_PIN_AH27                _GPIO(193)
+#define DB8500_PIN_AF27                _GPIO(194)
+#define DB8500_PIN_AG28                _GPIO(195)
+#define DB8500_PIN_AG26                _GPIO(196)
+#define DB8500_PIN_AH24                _GPIO(197)
+#define DB8500_PIN_AG25                _GPIO(198)
+#define DB8500_PIN_AH23                _GPIO(199)
+#define DB8500_PIN_AH26                _GPIO(200)
+#define DB8500_PIN_AF24                _GPIO(201)
+#define DB8500_PIN_AF25                _GPIO(202)
+#define DB8500_PIN_AE23                _GPIO(203)
+#define DB8500_PIN_AF23                _GPIO(204)
+#define DB8500_PIN_AG23                _GPIO(205)
+#define DB8500_PIN_AG24                _GPIO(206)
+#define DB8500_PIN_AJ23                _GPIO(207)
+#define DB8500_PIN_AH16                _GPIO(208)
+#define DB8500_PIN_AG15                _GPIO(209)
+#define DB8500_PIN_AJ15                _GPIO(210)
+#define DB8500_PIN_AG14                _GPIO(211)
+#define DB8500_PIN_AF13                _GPIO(212)
+#define DB8500_PIN_AG13                _GPIO(213)
+#define DB8500_PIN_AH15                _GPIO(214)
+#define DB8500_PIN_AH13                _GPIO(215)
+#define DB8500_PIN_AG12                _GPIO(216)
+#define DB8500_PIN_AH12                _GPIO(217)
+#define DB8500_PIN_AH11                _GPIO(218)
+#define DB8500_PIN_AG10                _GPIO(219)
+#define DB8500_PIN_AH10                _GPIO(220)
+#define DB8500_PIN_AJ11                _GPIO(221)
+#define DB8500_PIN_AJ9         _GPIO(222)
+#define DB8500_PIN_AH9         _GPIO(223)
+#define DB8500_PIN_AG9         _GPIO(224)
+#define DB8500_PIN_AG8         _GPIO(225)
+#define DB8500_PIN_AF8         _GPIO(226)
+#define DB8500_PIN_AH7         _GPIO(227)
+#define DB8500_PIN_AJ6         _GPIO(228)
+#define DB8500_PIN_AG7         _GPIO(229)
+#define DB8500_PIN_AF7         _GPIO(230)
+/* Hole */
+#define DB8500_PIN_AF28                _GPIO(256)
+#define DB8500_PIN_AE29                _GPIO(257)
+#define DB8500_PIN_AD29                _GPIO(258)
+#define DB8500_PIN_AC29                _GPIO(259)
+#define DB8500_PIN_AD28                _GPIO(260)
+#define DB8500_PIN_AD26                _GPIO(261)
+#define DB8500_PIN_AE26                _GPIO(262)
+#define DB8500_PIN_AG29                _GPIO(263)
+#define DB8500_PIN_AE27                _GPIO(264)
+#define DB8500_PIN_AD27                _GPIO(265)
+#define DB8500_PIN_AC28                _GPIO(266)
+#define DB8500_PIN_AC27                _GPIO(267)
+
+/*
+ * The names of the pins are denoted by GPIO number and ball name, even
+ * though they can be used for other things than GPIO, this is the first
+ * column in the table of the data sheet and often used on schematics and
+ * such.
+ */
+static const struct pinctrl_pin_desc nmk_db8500_pins[] = {
+       PINCTRL_PIN(DB8500_PIN_AJ5, "GPIO0_AJ5"),
+       PINCTRL_PIN(DB8500_PIN_AJ3, "GPIO1_AJ3"),
+       PINCTRL_PIN(DB8500_PIN_AH4, "GPIO2_AH4"),
+       PINCTRL_PIN(DB8500_PIN_AH3, "GPIO3_AH3"),
+       PINCTRL_PIN(DB8500_PIN_AH6, "GPIO4_AH6"),
+       PINCTRL_PIN(DB8500_PIN_AG6, "GPIO5_AG6"),
+       PINCTRL_PIN(DB8500_PIN_AF6, "GPIO6_AF6"),
+       PINCTRL_PIN(DB8500_PIN_AG5, "GPIO7_AG5"),
+       PINCTRL_PIN(DB8500_PIN_AD5, "GPIO8_AD5"),
+       PINCTRL_PIN(DB8500_PIN_AE4, "GPIO9_AE4"),
+       PINCTRL_PIN(DB8500_PIN_AF5, "GPIO10_AF5"),
+       PINCTRL_PIN(DB8500_PIN_AG4, "GPIO11_AG4"),
+       PINCTRL_PIN(DB8500_PIN_AC4, "GPIO12_AC4"),
+       PINCTRL_PIN(DB8500_PIN_AF3, "GPIO13_AF3"),
+       PINCTRL_PIN(DB8500_PIN_AE3, "GPIO14_AE3"),
+       PINCTRL_PIN(DB8500_PIN_AC3, "GPIO15_AC3"),
+       PINCTRL_PIN(DB8500_PIN_AD3, "GPIO16_AD3"),
+       PINCTRL_PIN(DB8500_PIN_AD4, "GPIO17_AD4"),
+       PINCTRL_PIN(DB8500_PIN_AC2, "GPIO18_AC2"),
+       PINCTRL_PIN(DB8500_PIN_AC1, "GPIO19_AC1"),
+       PINCTRL_PIN(DB8500_PIN_AB4, "GPIO20_AB4"),
+       PINCTRL_PIN(DB8500_PIN_AB3, "GPIO21_AB3"),
+       PINCTRL_PIN(DB8500_PIN_AA3, "GPIO22_AA3"),
+       PINCTRL_PIN(DB8500_PIN_AA4, "GPIO23_AA4"),
+       PINCTRL_PIN(DB8500_PIN_AB2, "GPIO24_AB2"),
+       PINCTRL_PIN(DB8500_PIN_Y4, "GPIO25_Y4"),
+       PINCTRL_PIN(DB8500_PIN_Y2, "GPIO26_Y2"),
+       PINCTRL_PIN(DB8500_PIN_AA2, "GPIO27_AA2"),
+       PINCTRL_PIN(DB8500_PIN_AA1, "GPIO28_AA1"),
+       PINCTRL_PIN(DB8500_PIN_W2, "GPIO29_W2"),
+       PINCTRL_PIN(DB8500_PIN_W3, "GPIO30_W3"),
+       PINCTRL_PIN(DB8500_PIN_V3, "GPIO31_V3"),
+       PINCTRL_PIN(DB8500_PIN_V2, "GPIO32_V2"),
+       PINCTRL_PIN(DB8500_PIN_AF2, "GPIO33_AF2"),
+       PINCTRL_PIN(DB8500_PIN_AE1, "GPIO34_AE1"),
+       PINCTRL_PIN(DB8500_PIN_AE2, "GPIO35_AE2"),
+       PINCTRL_PIN(DB8500_PIN_AG2, "GPIO36_AG2"),
+       /* Hole */
+       PINCTRL_PIN(DB8500_PIN_F3, "GPIO64_F3"),
+       PINCTRL_PIN(DB8500_PIN_F1, "GPIO65_F1"),
+       PINCTRL_PIN(DB8500_PIN_G3, "GPIO66_G3"),
+       PINCTRL_PIN(DB8500_PIN_G2, "GPIO67_G2"),
+       PINCTRL_PIN(DB8500_PIN_E1, "GPIO68_E1"),
+       PINCTRL_PIN(DB8500_PIN_E2, "GPIO69_E2"),
+       PINCTRL_PIN(DB8500_PIN_G5, "GPIO70_G5"),
+       PINCTRL_PIN(DB8500_PIN_G4, "GPIO71_G4"),
+       PINCTRL_PIN(DB8500_PIN_H4, "GPIO72_H4"),
+       PINCTRL_PIN(DB8500_PIN_H3, "GPIO73_H3"),
+       PINCTRL_PIN(DB8500_PIN_J3, "GPIO74_J3"),
+       PINCTRL_PIN(DB8500_PIN_H2, "GPIO75_H2"),
+       PINCTRL_PIN(DB8500_PIN_J2, "GPIO76_J2"),
+       PINCTRL_PIN(DB8500_PIN_H1, "GPIO77_H1"),
+       PINCTRL_PIN(DB8500_PIN_F4, "GPIO78_F4"),
+       PINCTRL_PIN(DB8500_PIN_E3, "GPIO79_E3"),
+       PINCTRL_PIN(DB8500_PIN_E4, "GPIO80_E4"),
+       PINCTRL_PIN(DB8500_PIN_D2, "GPIO81_D2"),
+       PINCTRL_PIN(DB8500_PIN_C1, "GPIO82_C1"),
+       PINCTRL_PIN(DB8500_PIN_D3, "GPIO83_D3"),
+       PINCTRL_PIN(DB8500_PIN_C2, "GPIO84_C2"),
+       PINCTRL_PIN(DB8500_PIN_D5, "GPIO85_D5"),
+       PINCTRL_PIN(DB8500_PIN_C6, "GPIO86_C6"),
+       PINCTRL_PIN(DB8500_PIN_B3, "GPIO87_B3"),
+       PINCTRL_PIN(DB8500_PIN_C4, "GPIO88_C4"),
+       PINCTRL_PIN(DB8500_PIN_E6, "GPIO89_E6"),
+       PINCTRL_PIN(DB8500_PIN_A3, "GPIO90_A3"),
+       PINCTRL_PIN(DB8500_PIN_B6, "GPIO91_B6"),
+       PINCTRL_PIN(DB8500_PIN_D6, "GPIO92_D6"),
+       PINCTRL_PIN(DB8500_PIN_B7, "GPIO93_B7"),
+       PINCTRL_PIN(DB8500_PIN_D7, "GPIO94_D7"),
+       PINCTRL_PIN(DB8500_PIN_E8, "GPIO95_E8"),
+       PINCTRL_PIN(DB8500_PIN_D8, "GPIO96_D8"),
+       PINCTRL_PIN(DB8500_PIN_D9, "GPIO97_D9"),
+       /* Hole */
+       PINCTRL_PIN(DB8500_PIN_A5, "GPIO128_A5"),
+       PINCTRL_PIN(DB8500_PIN_B4, "GPIO129_B4"),
+       PINCTRL_PIN(DB8500_PIN_C8, "GPIO130_C8"),
+       PINCTRL_PIN(DB8500_PIN_A12, "GPIO131_A12"),
+       PINCTRL_PIN(DB8500_PIN_C10, "GPIO132_C10"),
+       PINCTRL_PIN(DB8500_PIN_B10, "GPIO133_B10"),
+       PINCTRL_PIN(DB8500_PIN_B9, "GPIO134_B9"),
+       PINCTRL_PIN(DB8500_PIN_A9, "GPIO135_A9"),
+       PINCTRL_PIN(DB8500_PIN_C7, "GPIO136_C7"),
+       PINCTRL_PIN(DB8500_PIN_A7, "GPIO137_A7"),
+       PINCTRL_PIN(DB8500_PIN_C5, "GPIO138_C5"),
+       PINCTRL_PIN(DB8500_PIN_C9, "GPIO139_C9"),
+       PINCTRL_PIN(DB8500_PIN_B11, "GPIO140_B11"),
+       PINCTRL_PIN(DB8500_PIN_C12, "GPIO141_C12"),
+       PINCTRL_PIN(DB8500_PIN_C11, "GPIO142_C11"),
+       PINCTRL_PIN(DB8500_PIN_D12, "GPIO143_D12"),
+       PINCTRL_PIN(DB8500_PIN_B13, "GPIO144_B13"),
+       PINCTRL_PIN(DB8500_PIN_C13, "GPIO145_C13"),
+       PINCTRL_PIN(DB8500_PIN_D13, "GPIO146_D13"),
+       PINCTRL_PIN(DB8500_PIN_C15, "GPIO147_C15"),
+       PINCTRL_PIN(DB8500_PIN_B16, "GPIO148_B16"),
+       PINCTRL_PIN(DB8500_PIN_B14, "GPIO149_B14"),
+       PINCTRL_PIN(DB8500_PIN_C14, "GPIO150_C14"),
+       PINCTRL_PIN(DB8500_PIN_D17, "GPIO151_D17"),
+       PINCTRL_PIN(DB8500_PIN_D16, "GPIO152_D16"),
+       PINCTRL_PIN(DB8500_PIN_B17, "GPIO153_B17"),
+       PINCTRL_PIN(DB8500_PIN_C16, "GPIO154_C16"),
+       PINCTRL_PIN(DB8500_PIN_C19, "GPIO155_C19"),
+       PINCTRL_PIN(DB8500_PIN_C17, "GPIO156_C17"),
+       PINCTRL_PIN(DB8500_PIN_A18, "GPIO157_A18"),
+       PINCTRL_PIN(DB8500_PIN_C18, "GPIO158_C18"),
+       PINCTRL_PIN(DB8500_PIN_B19, "GPIO159_B19"),
+       PINCTRL_PIN(DB8500_PIN_B20, "GPIO160_B20"),
+       PINCTRL_PIN(DB8500_PIN_D21, "GPIO161_D21"),
+       PINCTRL_PIN(DB8500_PIN_D20, "GPIO162_D20"),
+       PINCTRL_PIN(DB8500_PIN_C20, "GPIO163_C20"),
+       PINCTRL_PIN(DB8500_PIN_B21, "GPIO164_B21"),
+       PINCTRL_PIN(DB8500_PIN_C21, "GPIO165_C21"),
+       PINCTRL_PIN(DB8500_PIN_A22, "GPIO166_A22"),
+       PINCTRL_PIN(DB8500_PIN_B24, "GPIO167_B24"),
+       PINCTRL_PIN(DB8500_PIN_C22, "GPIO168_C22"),
+       PINCTRL_PIN(DB8500_PIN_D22, "GPIO169_D22"),
+       PINCTRL_PIN(DB8500_PIN_C23, "GPIO170_C23"),
+       PINCTRL_PIN(DB8500_PIN_D23, "GPIO171_D23"),
+       /* Hole */
+       PINCTRL_PIN(DB8500_PIN_AJ27, "GPIO192_AJ27"),
+       PINCTRL_PIN(DB8500_PIN_AH27, "GPIO193_AH27"),
+       PINCTRL_PIN(DB8500_PIN_AF27, "GPIO194_AF27"),
+       PINCTRL_PIN(DB8500_PIN_AG28, "GPIO195_AG28"),
+       PINCTRL_PIN(DB8500_PIN_AG26, "GPIO196_AG26"),
+       PINCTRL_PIN(DB8500_PIN_AH24, "GPIO197_AH24"),
+       PINCTRL_PIN(DB8500_PIN_AG25, "GPIO198_AG25"),
+       PINCTRL_PIN(DB8500_PIN_AH23, "GPIO199_AH23"),
+       PINCTRL_PIN(DB8500_PIN_AH26, "GPIO200_AH26"),
+       PINCTRL_PIN(DB8500_PIN_AF24, "GPIO201_AF24"),
+       PINCTRL_PIN(DB8500_PIN_AF25, "GPIO202_AF25"),
+       PINCTRL_PIN(DB8500_PIN_AE23, "GPIO203_AE23"),
+       PINCTRL_PIN(DB8500_PIN_AF23, "GPIO204_AF23"),
+       PINCTRL_PIN(DB8500_PIN_AG23, "GPIO205_AG23"),
+       PINCTRL_PIN(DB8500_PIN_AG24, "GPIO206_AG24"),
+       PINCTRL_PIN(DB8500_PIN_AJ23, "GPIO207_AJ23"),
+       PINCTRL_PIN(DB8500_PIN_AH16, "GPIO208_AH16"),
+       PINCTRL_PIN(DB8500_PIN_AG15, "GPIO209_AG15"),
+       PINCTRL_PIN(DB8500_PIN_AJ15, "GPIO210_AJ15"),
+       PINCTRL_PIN(DB8500_PIN_AG14, "GPIO211_AG14"),
+       PINCTRL_PIN(DB8500_PIN_AF13, "GPIO212_AF13"),
+       PINCTRL_PIN(DB8500_PIN_AG13, "GPIO213_AG13"),
+       PINCTRL_PIN(DB8500_PIN_AH15, "GPIO214_AH15"),
+       PINCTRL_PIN(DB8500_PIN_AH13, "GPIO215_AH13"),
+       PINCTRL_PIN(DB8500_PIN_AG12, "GPIO216_AG12"),
+       PINCTRL_PIN(DB8500_PIN_AH12, "GPIO217_AH12"),
+       PINCTRL_PIN(DB8500_PIN_AH11, "GPIO218_AH11"),
+       PINCTRL_PIN(DB8500_PIN_AG10, "GPIO219_AG10"),
+       PINCTRL_PIN(DB8500_PIN_AH10, "GPIO220_AH10"),
+       PINCTRL_PIN(DB8500_PIN_AJ11, "GPIO221_AJ11"),
+       PINCTRL_PIN(DB8500_PIN_AJ9, "GPIO222_AJ9"),
+       PINCTRL_PIN(DB8500_PIN_AH9, "GPIO223_AH9"),
+       PINCTRL_PIN(DB8500_PIN_AG9, "GPIO224_AG9"),
+       PINCTRL_PIN(DB8500_PIN_AG8, "GPIO225_AG8"),
+       PINCTRL_PIN(DB8500_PIN_AF8, "GPIO226_AF8"),
+       PINCTRL_PIN(DB8500_PIN_AH7, "GPIO227_AH7"),
+       PINCTRL_PIN(DB8500_PIN_AJ6, "GPIO228_AJ6"),
+       PINCTRL_PIN(DB8500_PIN_AG7, "GPIO229_AG7"),
+       PINCTRL_PIN(DB8500_PIN_AF7, "GPIO230_AF7"),
+       /* Hole */
+       PINCTRL_PIN(DB8500_PIN_AF28, "GPIO256_AF28"),
+       PINCTRL_PIN(DB8500_PIN_AE29, "GPIO257_AE29"),
+       PINCTRL_PIN(DB8500_PIN_AD29, "GPIO258_AD29"),
+       PINCTRL_PIN(DB8500_PIN_AC29, "GPIO259_AC29"),
+       PINCTRL_PIN(DB8500_PIN_AD28, "GPIO260_AD28"),
+       PINCTRL_PIN(DB8500_PIN_AD26, "GPIO261_AD26"),
+       PINCTRL_PIN(DB8500_PIN_AE26, "GPIO262_AE26"),
+       PINCTRL_PIN(DB8500_PIN_AG29, "GPIO263_AG29"),
+       PINCTRL_PIN(DB8500_PIN_AE27, "GPIO264_AE27"),
+       PINCTRL_PIN(DB8500_PIN_AD27, "GPIO265_AD27"),
+       PINCTRL_PIN(DB8500_PIN_AC28, "GPIO266_AC28"),
+       PINCTRL_PIN(DB8500_PIN_AC27, "GPIO267_AC27"),
+};
+
+#define DB8500_GPIO_RANGE(a, b, c) { .name = "DB8500", .id = a, .base = b, \
+                       .pin_base = b, .npins = c }
+
+/*
+ * This matches the 32-pin gpio chips registered by the GPIO portion. This
+ * cannot be const since we assign the struct gpio_chip * pointer at runtime.
+ */
+static struct pinctrl_gpio_range nmk_db8500_ranges[] = {
+       DB8500_GPIO_RANGE(0, 0, 32),
+       DB8500_GPIO_RANGE(1, 32, 5),
+       DB8500_GPIO_RANGE(2, 64, 32),
+       DB8500_GPIO_RANGE(3, 96, 2),
+       DB8500_GPIO_RANGE(4, 128, 32),
+       DB8500_GPIO_RANGE(5, 160, 12),
+       DB8500_GPIO_RANGE(6, 192, 32),
+       DB8500_GPIO_RANGE(7, 224, 7),
+       DB8500_GPIO_RANGE(8, 256, 12),
+};
+
+/*
+ * Read the pin group names like this:
+ * u0_a_1    = first groups of pins for uart0 on alt function a
+ * i2c2_b_2  = second group of pins for i2c2 on alt function b
+ *
+ * The groups are arranged as sets per altfunction column, so we can
+ * mux in one group at a time by selecting the same altfunction for them
+ * all. When functions require pins on different altfunctions, you need
+ * to combine several groups.
+ */
+
+/* Altfunction A column */
+static const unsigned u0_a_1_pins[] = { DB8500_PIN_AJ5, DB8500_PIN_AJ3,
+                                       DB8500_PIN_AH4, DB8500_PIN_AH3 };
+static const unsigned u1rxtx_a_1_pins[] = { DB8500_PIN_AH6, DB8500_PIN_AG6 };
+static const unsigned u1ctsrts_a_1_pins[] = { DB8500_PIN_AF6, DB8500_PIN_AG5 };
+/* Image processor I2C line, this is driven by image processor firmware */
+static const unsigned ipi2c_a_1_pins[] = { DB8500_PIN_AD5, DB8500_PIN_AE4 };
+static const unsigned ipi2c_a_2_pins[] = { DB8500_PIN_AF5, DB8500_PIN_AG4 };
+/* MSP0 can only be on these pins, but TXD and RXD can be flipped */
+static const unsigned msp0txrx_a_1_pins[] = { DB8500_PIN_AC4, DB8500_PIN_AC3 };
+static const unsigned msp0tfstck_a_1_pins[] = { DB8500_PIN_AF3, DB8500_PIN_AE3 };
+static const unsigned msp0rfsrck_a_1_pins[] = { DB8500_PIN_AD3, DB8500_PIN_AD4 };
+/* Basic pins of the MMC/SD card 0 interface */
+static const unsigned mc0_a_1_pins[] = { DB8500_PIN_AC2, DB8500_PIN_AC1,
+       DB8500_PIN_AB4, DB8500_PIN_AA3, DB8500_PIN_AA4, DB8500_PIN_AB2,
+       DB8500_PIN_Y4, DB8500_PIN_Y2, DB8500_PIN_AA2, DB8500_PIN_AA1 };
+/* Often only 4 bits are used, then these are not needed (only used for MMC) */
+static const unsigned mc0_dat47_a_1_pins[] = { DB8500_PIN_W2, DB8500_PIN_W3,
+       DB8500_PIN_V3, DB8500_PIN_V2};
+static const unsigned mc0dat31dir_a_1_pins[] = { DB8500_PIN_AB3 };
+/* MSP1 can only be on these pins, but TXD and RXD can be flipped */
+static const unsigned msp1txrx_a_1_pins[] = { DB8500_PIN_AF2, DB8500_PIN_AG2 };
+static const unsigned msp1_a_1_pins[] = { DB8500_PIN_AE1, DB8500_PIN_AE2 };
+/* LCD interface */
+static const unsigned lcdb_a_1_pins[] = { DB8500_PIN_F3, DB8500_PIN_F1,
+                                         DB8500_PIN_G3, DB8500_PIN_G2 };
+static const unsigned lcdvsi0_a_1_pins[] = { DB8500_PIN_E1 };
+static const unsigned lcdvsi1_a_1_pins[] = { DB8500_PIN_E2 };
+static const unsigned lcd_d0_d7_a_1_pins[] = {
+       DB8500_PIN_G5, DB8500_PIN_G4, DB8500_PIN_H4, DB8500_PIN_H3,
+       DB8500_PIN_J3, DB8500_PIN_H2, DB8500_PIN_J2, DB8500_PIN_H1 };
+/* D8 thru D11 often used as TVOUT lines */
+static const unsigned lcd_d8_d11_a_1_pins[] = { DB8500_PIN_F4,
+       DB8500_PIN_E3, DB8500_PIN_E4, DB8500_PIN_D2 };
+static const unsigned lcd_d12_d23_a_1_pins[] = {
+       DB8500_PIN_C1, DB8500_PIN_D3, DB8500_PIN_C2, DB8500_PIN_D5,
+       DB8500_PIN_C6, DB8500_PIN_B3, DB8500_PIN_C4, DB8500_PIN_E6,
+       DB8500_PIN_A3, DB8500_PIN_B6, DB8500_PIN_D6, DB8500_PIN_B7 };
+static const unsigned kp_a_1_pins[] = { DB8500_PIN_D7, DB8500_PIN_E8,
+       DB8500_PIN_D8, DB8500_PIN_D9 };
+static const unsigned kpskaskb_a_1_pins[] = { DB8500_PIN_D17, DB8500_PIN_D16 };
+static const unsigned kp_a_2_pins[] = {
+       DB8500_PIN_B17, DB8500_PIN_C16, DB8500_PIN_C19, DB8500_PIN_C17,
+       DB8500_PIN_A18, DB8500_PIN_C18, DB8500_PIN_B19, DB8500_PIN_B20,
+       DB8500_PIN_D21, DB8500_PIN_D20, DB8500_PIN_C20, DB8500_PIN_B21,
+       DB8500_PIN_C21, DB8500_PIN_A22, DB8500_PIN_B24, DB8500_PIN_C22 };
+/* MC2 has 8 data lines and no direction control, so only for (e)MMC */
+static const unsigned mc2_a_1_pins[] = { DB8500_PIN_A5, DB8500_PIN_B4,
+       DB8500_PIN_C8, DB8500_PIN_A12, DB8500_PIN_C10, DB8500_PIN_B10,
+       DB8500_PIN_B9, DB8500_PIN_A9, DB8500_PIN_C7, DB8500_PIN_A7,
+       DB8500_PIN_C5 };
+static const unsigned ssp1_a_1_pins[] = { DB8500_PIN_C9, DB8500_PIN_B11,
+                                         DB8500_PIN_C12, DB8500_PIN_C11 };
+static const unsigned ssp0_a_1_pins[] = { DB8500_PIN_D12, DB8500_PIN_B13,
+                                         DB8500_PIN_C13, DB8500_PIN_D13 };
+static const unsigned i2c0_a_1_pins[] = { DB8500_PIN_C15, DB8500_PIN_B16 };
+/*
+ * Image processor GPIO pins are named "ipgpio" and have their own
+ * numberspace
+ */
+static const unsigned ipgpio0_a_1_pins[] = { DB8500_PIN_B14 };
+static const unsigned ipgpio1_a_1_pins[] = { DB8500_PIN_C14 };
+/* Three modem pins named RF_PURn, MODEM_STATE and MODEM_PWREN */
+static const unsigned modem_a_1_pins[] = { DB8500_PIN_D22, DB8500_PIN_C23,
+                                          DB8500_PIN_D23 };
+/*
+ * This MSP cannot switch RX and TX, SCK in a separate group since this
+ * seems to be optional.
+ */
+static const unsigned msp2sck_a_1_pins[] = { DB8500_PIN_AJ27 };
+static const unsigned msp2_a_1_pins[] = { DB8500_PIN_AH27, DB8500_PIN_AF27,
+                                         DB8500_PIN_AG28, DB8500_PIN_AG26 };
+static const unsigned mc4_a_1_pins[] = { DB8500_PIN_AH24, DB8500_PIN_AG25,
+       DB8500_PIN_AH23, DB8500_PIN_AH26, DB8500_PIN_AF24, DB8500_PIN_AF25,
+       DB8500_PIN_AE23, DB8500_PIN_AF23, DB8500_PIN_AG23, DB8500_PIN_AG24,
+       DB8500_PIN_AJ23 };
+/* MC1 has only 4 data pins, designed for SD or SDIO exclusively */
+static const unsigned mc1_a_1_pins[] = { DB8500_PIN_AH16, DB8500_PIN_AG15,
+       DB8500_PIN_AJ15, DB8500_PIN_AG14, DB8500_PIN_AF13, DB8500_PIN_AG13,
+       DB8500_PIN_AH15 };
+static const unsigned mc1_a_2_pins[] = { DB8500_PIN_AH16, DB8500_PIN_AJ15,
+       DB8500_PIN_AG14, DB8500_PIN_AF13, DB8500_PIN_AG13, DB8500_PIN_AH15 };
+static const unsigned mc1dir_a_1_pins[] = { DB8500_PIN_AH13, DB8500_PIN_AG12,
+       DB8500_PIN_AH12, DB8500_PIN_AH11 };
+static const unsigned hsir_a_1_pins[] = { DB8500_PIN_AG10, DB8500_PIN_AH10,
+       DB8500_PIN_AJ11 };
+static const unsigned hsit_a_1_pins[] = { DB8500_PIN_AJ9, DB8500_PIN_AH9,
+       DB8500_PIN_AG9, DB8500_PIN_AG8, DB8500_PIN_AF8 };
+static const unsigned hsit_a_2_pins[] = { DB8500_PIN_AJ9, DB8500_PIN_AH9,
+       DB8500_PIN_AG9, DB8500_PIN_AG8 };
+static const unsigned clkout1_a_1_pins[] = { DB8500_PIN_AH7 };
+static const unsigned clkout1_a_2_pins[] = { DB8500_PIN_AG7 };
+static const unsigned clkout2_a_1_pins[] = { DB8500_PIN_AJ6 };
+static const unsigned clkout2_a_2_pins[] = { DB8500_PIN_AF7 };
+static const unsigned usb_a_1_pins[] = { DB8500_PIN_AF28, DB8500_PIN_AE29,
+       DB8500_PIN_AD29, DB8500_PIN_AC29, DB8500_PIN_AD28, DB8500_PIN_AD26,
+       DB8500_PIN_AE26, DB8500_PIN_AG29, DB8500_PIN_AE27, DB8500_PIN_AD27,
+       DB8500_PIN_AC28, DB8500_PIN_AC27 };
+
+/* Altfunction B column */
+static const unsigned trig_b_1_pins[] = { DB8500_PIN_AJ5, DB8500_PIN_AJ3 };
+static const unsigned i2c4_b_1_pins[] = { DB8500_PIN_AH6, DB8500_PIN_AG6 };
+static const unsigned i2c1_b_1_pins[] = { DB8500_PIN_AF6, DB8500_PIN_AG5 };
+static const unsigned i2c2_b_1_pins[] = { DB8500_PIN_AD5, DB8500_PIN_AE4 };
+static const unsigned i2c2_b_2_pins[] = { DB8500_PIN_AF5, DB8500_PIN_AG4 };
+static const unsigned msp0txrx_b_1_pins[] = { DB8500_PIN_AC4, DB8500_PIN_AC3 };
+static const unsigned i2c1_b_2_pins[] = { DB8500_PIN_AD3, DB8500_PIN_AD4 };
+/* Just RX and TX for UART2 */
+static const unsigned u2rxtx_b_1_pins[] = { DB8500_PIN_AC2, DB8500_PIN_AC1 };
+static const unsigned uartmodtx_b_1_pins[] = { DB8500_PIN_AB4 };
+static const unsigned msp0sck_b_1_pins[] = { DB8500_PIN_AB3 };
+static const unsigned uartmodrx_b_1_pins[] = { DB8500_PIN_AA3 };
+static const unsigned stmmod_b_1_pins[] = { DB8500_PIN_AA4, DB8500_PIN_Y4,
+       DB8500_PIN_Y2, DB8500_PIN_AA2, DB8500_PIN_AA1 };
+static const unsigned uartmodrx_b_2_pins[] = { DB8500_PIN_AB2 };
+static const unsigned spi3_b_1_pins[] = { DB8500_PIN_W2, DB8500_PIN_W3,
+                                         DB8500_PIN_V3, DB8500_PIN_V2 };
+static const unsigned msp1txrx_b_1_pins[] = { DB8500_PIN_AF2, DB8500_PIN_AG2 };
+static const unsigned kp_b_1_pins[] = { DB8500_PIN_F3, DB8500_PIN_F1,
+       DB8500_PIN_G3, DB8500_PIN_G2, DB8500_PIN_E1, DB8500_PIN_E2,
+       DB8500_PIN_G5, DB8500_PIN_G4, DB8500_PIN_H4, DB8500_PIN_H3,
+       DB8500_PIN_J3, DB8500_PIN_H2, DB8500_PIN_J2, DB8500_PIN_H1,
+       DB8500_PIN_F4, DB8500_PIN_E3, DB8500_PIN_E4, DB8500_PIN_D2,
+       DB8500_PIN_C1, DB8500_PIN_D3, DB8500_PIN_C2, DB8500_PIN_D5 };
+static const unsigned kp_b_2_pins[] = { DB8500_PIN_F3, DB8500_PIN_F1,
+       DB8500_PIN_G3, DB8500_PIN_G2, DB8500_PIN_F4, DB8500_PIN_E3};
+static const unsigned sm_b_1_pins[] = { DB8500_PIN_C6, DB8500_PIN_B3,
+       DB8500_PIN_C4, DB8500_PIN_E6, DB8500_PIN_A3, DB8500_PIN_B6,
+       DB8500_PIN_D6, DB8500_PIN_B7, DB8500_PIN_D7, DB8500_PIN_D8,
+       DB8500_PIN_D9, DB8500_PIN_A5, DB8500_PIN_B4, DB8500_PIN_C8,
+       DB8500_PIN_A12, DB8500_PIN_C10, DB8500_PIN_B10, DB8500_PIN_B9,
+       DB8500_PIN_A9, DB8500_PIN_C7, DB8500_PIN_A7, DB8500_PIN_C5,
+       DB8500_PIN_C9 };
+/* This chip select pin can be "ps0" in alt C so have it separately */
+static const unsigned smcs0_b_1_pins[] = { DB8500_PIN_E8 };
+/* This chip select pin can be "ps1" in alt C so have it separately */
+static const unsigned smcs1_b_1_pins[] = { DB8500_PIN_B14 };
+static const unsigned ipgpio7_b_1_pins[] = { DB8500_PIN_B11 };
+static const unsigned ipgpio2_b_1_pins[] = { DB8500_PIN_C12 };
+static const unsigned ipgpio3_b_1_pins[] = { DB8500_PIN_C11 };
+static const unsigned lcdaclk_b_1_pins[] = { DB8500_PIN_C14 };
+static const unsigned lcda_b_1_pins[] = { DB8500_PIN_D22,
+       DB8500_PIN_C23, DB8500_PIN_D23 };
+static const unsigned lcd_b_1_pins[] = { DB8500_PIN_D17, DB8500_PIN_D16,
+       DB8500_PIN_B17, DB8500_PIN_C16, DB8500_PIN_C19, DB8500_PIN_C17,
+       DB8500_PIN_A18, DB8500_PIN_C18, DB8500_PIN_B19, DB8500_PIN_B20,
+       DB8500_PIN_D21, DB8500_PIN_D20, DB8500_PIN_C20, DB8500_PIN_B21,
+       DB8500_PIN_C21, DB8500_PIN_A22, DB8500_PIN_B24, DB8500_PIN_C22 };
+static const unsigned ddrtrig_b_1_pins[] = { DB8500_PIN_AJ27 };
+static const unsigned pwl_b_1_pins[] = { DB8500_PIN_AF25 };
+static const unsigned spi1_b_1_pins[] = { DB8500_PIN_AG15, DB8500_PIN_AF13,
+                                         DB8500_PIN_AG13, DB8500_PIN_AH15 };
+static const unsigned mc3_b_1_pins[] = { DB8500_PIN_AH13, DB8500_PIN_AG12,
+       DB8500_PIN_AH12, DB8500_PIN_AH11, DB8500_PIN_AG10, DB8500_PIN_AH10,
+       DB8500_PIN_AJ11, DB8500_PIN_AJ9, DB8500_PIN_AH9, DB8500_PIN_AG9,
+       DB8500_PIN_AG8 };
+static const unsigned pwl_b_2_pins[] = { DB8500_PIN_AF8 };
+static const unsigned pwl_b_3_pins[] = { DB8500_PIN_AG7 };
+static const unsigned pwl_b_4_pins[] = { DB8500_PIN_AF7 };
+
+/* Altfunction C column */
+static const unsigned ipjtag_c_1_pins[] = { DB8500_PIN_AJ5, DB8500_PIN_AJ3,
+       DB8500_PIN_AH4, DB8500_PIN_AH3, DB8500_PIN_AH6 };
+static const unsigned ipgpio6_c_1_pins[] = { DB8500_PIN_AG6 };
+static const unsigned ipgpio0_c_1_pins[] = { DB8500_PIN_AF6 };
+static const unsigned ipgpio1_c_1_pins[] = { DB8500_PIN_AG5 };
+static const unsigned ipgpio3_c_1_pins[] = { DB8500_PIN_AF5 };
+static const unsigned ipgpio2_c_1_pins[] = { DB8500_PIN_AG4 };
+static const unsigned slim0_c_1_pins[] = { DB8500_PIN_AD3, DB8500_PIN_AD4 };
+/* Optional 4-bit Memory Stick interface */
+static const unsigned ms_c_1_pins[] = { DB8500_PIN_AC2, DB8500_PIN_AC1,
+       DB8500_PIN_AB3, DB8500_PIN_AA3, DB8500_PIN_AA4, DB8500_PIN_AB2,
+       DB8500_PIN_Y4, DB8500_PIN_Y2, DB8500_PIN_AA2, DB8500_PIN_AA1 };
+static const unsigned iptrigout_c_1_pins[] = { DB8500_PIN_AB4 };
+static const unsigned u2rxtx_c_1_pins[] = { DB8500_PIN_W2, DB8500_PIN_W3 };
+static const unsigned u2ctsrts_c_1_pins[] = { DB8500_PIN_V3, DB8500_PIN_V2 };
+static const unsigned u0_c_1_pins[] = { DB8500_PIN_AF2, DB8500_PIN_AE1,
+                                       DB8500_PIN_AE2, DB8500_PIN_AG2 };
+static const unsigned ipgpio4_c_1_pins[] = { DB8500_PIN_F3 };
+static const unsigned ipgpio5_c_1_pins[] = { DB8500_PIN_F1 };
+static const unsigned ipgpio6_c_2_pins[] = { DB8500_PIN_G3 };
+static const unsigned ipgpio7_c_1_pins[] = { DB8500_PIN_G2 };
+static const unsigned smcleale_c_1_pins[] = { DB8500_PIN_E1, DB8500_PIN_E2 };
+static const unsigned stmape_c_1_pins[] = { DB8500_PIN_G5, DB8500_PIN_G4,
+       DB8500_PIN_H4, DB8500_PIN_H3, DB8500_PIN_J3 };
+static const unsigned u2rxtx_c_2_pins[] = { DB8500_PIN_H2, DB8500_PIN_J2 };
+static const unsigned ipgpio2_c_2_pins[] = { DB8500_PIN_F4 };
+static const unsigned ipgpio3_c_2_pins[] = { DB8500_PIN_E3 };
+static const unsigned ipgpio4_c_2_pins[] = { DB8500_PIN_E4 };
+static const unsigned ipgpio5_c_2_pins[] = { DB8500_PIN_D2 };
+static const unsigned mc5_c_1_pins[] = { DB8500_PIN_C6, DB8500_PIN_B3,
+       DB8500_PIN_C4, DB8500_PIN_E6, DB8500_PIN_A3, DB8500_PIN_B6,
+       DB8500_PIN_D6, DB8500_PIN_B7, DB8500_PIN_D7, DB8500_PIN_D8,
+       DB8500_PIN_D9 };
+static const unsigned mc2rstn_c_1_pins[] = { DB8500_PIN_C8 };
+static const unsigned kp_c_1_pins[] = { DB8500_PIN_C9, DB8500_PIN_B11,
+       DB8500_PIN_C12, DB8500_PIN_C11, DB8500_PIN_D17, DB8500_PIN_D16,
+       DB8500_PIN_C23, DB8500_PIN_D23 };
+static const unsigned smps0_c_1_pins[] = { DB8500_PIN_E8 };
+static const unsigned smps1_c_1_pins[] = { DB8500_PIN_B14 };
+static const unsigned u2rxtx_c_3_pins[] = { DB8500_PIN_B17, DB8500_PIN_C16 };
+static const unsigned stmape_c_2_pins[] = { DB8500_PIN_C19, DB8500_PIN_C17,
+       DB8500_PIN_A18, DB8500_PIN_C18, DB8500_PIN_B19 };
+static const unsigned uartmodrx_c_1_pins[] = { DB8500_PIN_D21 };
+static const unsigned uartmodtx_c_1_pins[] = { DB8500_PIN_D20 };
+static const unsigned stmmod_c_1_pins[] = { DB8500_PIN_C20, DB8500_PIN_B21,
+       DB8500_PIN_C21, DB8500_PIN_A22, DB8500_PIN_B24 };
+static const unsigned usbsim_c_1_pins[] = { DB8500_PIN_D22 };
+static const unsigned mc4rstn_c_1_pins[] = { DB8500_PIN_AF25 };
+static const unsigned clkout1_c_1_pins[] = { DB8500_PIN_AH13 };
+static const unsigned clkout2_c_1_pins[] = { DB8500_PIN_AH12 };
+static const unsigned i2c3_c_1_pins[] = { DB8500_PIN_AG12, DB8500_PIN_AH11 };
+static const unsigned spi0_c_1_pins[] = { DB8500_PIN_AH10, DB8500_PIN_AH9,
+                                         DB8500_PIN_AG9, DB8500_PIN_AG8 };
+static const unsigned usbsim_c_2_pins[] = { DB8500_PIN_AF8 };
+static const unsigned i2c3_c_2_pins[] = { DB8500_PIN_AG7, DB8500_PIN_AF7 };
+
+/* Other C1 column */
+static const unsigned u2rx_oc1_1_pins[] = { DB8500_PIN_AB2 };
+static const unsigned stmape_oc1_1_pins[] = { DB8500_PIN_AA4, DB8500_PIN_Y4,
+       DB8500_PIN_Y2, DB8500_PIN_AA2, DB8500_PIN_AA1 };
+static const unsigned remap0_oc1_1_pins[] = { DB8500_PIN_E1 };
+static const unsigned remap1_oc1_1_pins[] = { DB8500_PIN_E2 };
+static const unsigned ptma9_oc1_1_pins[] = { DB8500_PIN_G5, DB8500_PIN_G4,
+       DB8500_PIN_H4, DB8500_PIN_H3, DB8500_PIN_J3, DB8500_PIN_H2,
+       DB8500_PIN_J2, DB8500_PIN_H1 };
+static const unsigned kp_oc1_1_pins[] = { DB8500_PIN_C6, DB8500_PIN_B3,
+       DB8500_PIN_C4, DB8500_PIN_E6, DB8500_PIN_A3, DB8500_PIN_B6,
+       DB8500_PIN_D6, DB8500_PIN_B7 };
+static const unsigned rf_oc1_1_pins[] = { DB8500_PIN_D8, DB8500_PIN_D9 };
+static const unsigned hxclk_oc1_1_pins[] = { DB8500_PIN_D16 };
+static const unsigned uartmodrx_oc1_1_pins[] = { DB8500_PIN_B17 };
+static const unsigned uartmodtx_oc1_1_pins[] = { DB8500_PIN_C16 };
+static const unsigned stmmod_oc1_1_pins[] = { DB8500_PIN_C19, DB8500_PIN_C17,
+       DB8500_PIN_A18, DB8500_PIN_C18, DB8500_PIN_B19 };
+static const unsigned hxgpio_oc1_1_pins[] = { DB8500_PIN_D21, DB8500_PIN_D20,
+       DB8500_PIN_C20, DB8500_PIN_B21, DB8500_PIN_C21, DB8500_PIN_A22,
+       DB8500_PIN_B24, DB8500_PIN_C22 };
+static const unsigned rf_oc1_2_pins[] = { DB8500_PIN_C23, DB8500_PIN_D23 };
+static const unsigned spi2_oc1_1_pins[] = { DB8500_PIN_AH13, DB8500_PIN_AG12,
+       DB8500_PIN_AH12, DB8500_PIN_AH11 };
+static const unsigned spi2_oc1_2_pins[] = { DB8500_PIN_AH13, DB8500_PIN_AH12,
+       DB8500_PIN_AH11 };
+
+/* Other C2 column */
+static const unsigned sbag_oc2_1_pins[] = { DB8500_PIN_AA4, DB8500_PIN_AB2,
+       DB8500_PIN_Y4, DB8500_PIN_Y2, DB8500_PIN_AA2, DB8500_PIN_AA1 };
+static const unsigned etmr4_oc2_1_pins[] = { DB8500_PIN_G5, DB8500_PIN_G4,
+       DB8500_PIN_H4, DB8500_PIN_H3, DB8500_PIN_J3, DB8500_PIN_H2,
+       DB8500_PIN_J2, DB8500_PIN_H1 };
+static const unsigned ptma9_oc2_1_pins[] = { DB8500_PIN_D17, DB8500_PIN_D16,
+       DB8500_PIN_B17, DB8500_PIN_C16, DB8500_PIN_C19, DB8500_PIN_C17,
+       DB8500_PIN_A18, DB8500_PIN_C18, DB8500_PIN_B19, DB8500_PIN_B20,
+       DB8500_PIN_D21, DB8500_PIN_D20, DB8500_PIN_C20, DB8500_PIN_B21,
+       DB8500_PIN_C21, DB8500_PIN_A22, DB8500_PIN_B24, DB8500_PIN_C22 };
+
+/* Other C3 column */
+static const unsigned stmmod_oc3_1_pins[] = { DB8500_PIN_AB2, DB8500_PIN_W2,
+       DB8500_PIN_W3, DB8500_PIN_V3, DB8500_PIN_V2 };
+static const unsigned stmmod_oc3_2_pins[] = { DB8500_PIN_G5, DB8500_PIN_G4,
+       DB8500_PIN_H4, DB8500_PIN_H3, DB8500_PIN_J3 };
+static const unsigned uartmodrx_oc3_1_pins[] = { DB8500_PIN_H2 };
+static const unsigned uartmodtx_oc3_1_pins[] = { DB8500_PIN_J2 };
+static const unsigned etmr4_oc3_1_pins[] = { DB8500_PIN_D17, DB8500_PIN_D16,
+       DB8500_PIN_B17, DB8500_PIN_C16, DB8500_PIN_C19, DB8500_PIN_C17,
+       DB8500_PIN_A18, DB8500_PIN_C18, DB8500_PIN_B19, DB8500_PIN_B20,
+       DB8500_PIN_D21, DB8500_PIN_D20, DB8500_PIN_C20, DB8500_PIN_B21,
+       DB8500_PIN_C21, DB8500_PIN_A22, DB8500_PIN_B24, DB8500_PIN_C22 };
+
+/* Other C4 column */
+static const unsigned sbag_oc4_1_pins[] = { DB8500_PIN_G5, DB8500_PIN_G4,
+       DB8500_PIN_H4, DB8500_PIN_H3, DB8500_PIN_J3, DB8500_PIN_H1 };
+static const unsigned hwobs_oc4_1_pins[] = { DB8500_PIN_D17, DB8500_PIN_D16,
+       DB8500_PIN_B17, DB8500_PIN_C16, DB8500_PIN_C19, DB8500_PIN_C17,
+       DB8500_PIN_A18, DB8500_PIN_C18, DB8500_PIN_B19, DB8500_PIN_B20,
+       DB8500_PIN_D21, DB8500_PIN_D20, DB8500_PIN_C20, DB8500_PIN_B21,
+       DB8500_PIN_C21, DB8500_PIN_A22, DB8500_PIN_B24, DB8500_PIN_C22 };
+
+#define DB8500_PIN_GROUP(a, b) { .name = #a, .pins = a##_pins,         \
+                       .npins = ARRAY_SIZE(a##_pins), .altsetting = b }
+
+static const struct nmk_pingroup nmk_db8500_groups[] = {
+       /* Altfunction A column */
+       DB8500_PIN_GROUP(u0_a_1, NMK_GPIO_ALT_A),
+       DB8500_PIN_GROUP(u1rxtx_a_1, NMK_GPIO_ALT_A),
+       DB8500_PIN_GROUP(u1ctsrts_a_1, NMK_GPIO_ALT_A),
+       DB8500_PIN_GROUP(ipi2c_a_1, NMK_GPIO_ALT_A),
+       DB8500_PIN_GROUP(ipi2c_a_2, NMK_GPIO_ALT_A),
+       DB8500_PIN_GROUP(msp0txrx_a_1, NMK_GPIO_ALT_A),
+       DB8500_PIN_GROUP(msp0tfstck_a_1, NMK_GPIO_ALT_A),
+       DB8500_PIN_GROUP(msp0rfsrck_a_1, NMK_GPIO_ALT_A),
+       DB8500_PIN_GROUP(mc0_a_1, NMK_GPIO_ALT_A),
+       DB8500_PIN_GROUP(mc0_dat47_a_1, NMK_GPIO_ALT_A),
+       DB8500_PIN_GROUP(mc0dat31dir_a_1, NMK_GPIO_ALT_A),
+       DB8500_PIN_GROUP(msp1txrx_a_1, NMK_GPIO_ALT_A),
+       DB8500_PIN_GROUP(msp1_a_1, NMK_GPIO_ALT_A),
+       DB8500_PIN_GROUP(lcdb_a_1, NMK_GPIO_ALT_A),
+       DB8500_PIN_GROUP(lcdvsi0_a_1, NMK_GPIO_ALT_A),
+       DB8500_PIN_GROUP(lcdvsi1_a_1, NMK_GPIO_ALT_A),
+       DB8500_PIN_GROUP(lcd_d0_d7_a_1, NMK_GPIO_ALT_A),
+       DB8500_PIN_GROUP(lcd_d8_d11_a_1, NMK_GPIO_ALT_A),
+       DB8500_PIN_GROUP(lcd_d12_d23_a_1, NMK_GPIO_ALT_A),
+       DB8500_PIN_GROUP(kp_a_1, NMK_GPIO_ALT_A),
+       DB8500_PIN_GROUP(mc2_a_1, NMK_GPIO_ALT_A),
+       DB8500_PIN_GROUP(ssp1_a_1, NMK_GPIO_ALT_A),
+       DB8500_PIN_GROUP(ssp0_a_1, NMK_GPIO_ALT_A),
+       DB8500_PIN_GROUP(i2c0_a_1, NMK_GPIO_ALT_A),
+       DB8500_PIN_GROUP(ipgpio0_a_1, NMK_GPIO_ALT_A),
+       DB8500_PIN_GROUP(ipgpio1_a_1, NMK_GPIO_ALT_A),
+       DB8500_PIN_GROUP(kp_a_2, NMK_GPIO_ALT_A),
+       DB8500_PIN_GROUP(msp2sck_a_1, NMK_GPIO_ALT_A),
+       DB8500_PIN_GROUP(msp2_a_1, NMK_GPIO_ALT_A),
+       DB8500_PIN_GROUP(mc4_a_1, NMK_GPIO_ALT_A),
+       DB8500_PIN_GROUP(mc1_a_1, NMK_GPIO_ALT_A),
+       DB8500_PIN_GROUP(mc1_a_2, NMK_GPIO_ALT_A),
+       DB8500_PIN_GROUP(hsir_a_1, NMK_GPIO_ALT_A),
+       DB8500_PIN_GROUP(hsit_a_1, NMK_GPIO_ALT_A),
+       DB8500_PIN_GROUP(hsit_a_2, NMK_GPIO_ALT_A),
+       DB8500_PIN_GROUP(clkout1_a_1, NMK_GPIO_ALT_A),
+       DB8500_PIN_GROUP(clkout1_a_2, NMK_GPIO_ALT_A),
+       DB8500_PIN_GROUP(clkout2_a_1, NMK_GPIO_ALT_A),
+       DB8500_PIN_GROUP(clkout2_a_2, NMK_GPIO_ALT_A),
+       DB8500_PIN_GROUP(usb_a_1, NMK_GPIO_ALT_A),
+       /* Altfunction B column */
+       DB8500_PIN_GROUP(trig_b_1, NMK_GPIO_ALT_B),
+       DB8500_PIN_GROUP(i2c4_b_1, NMK_GPIO_ALT_B),
+       DB8500_PIN_GROUP(i2c1_b_1, NMK_GPIO_ALT_B),
+       DB8500_PIN_GROUP(i2c2_b_1, NMK_GPIO_ALT_B),
+       DB8500_PIN_GROUP(i2c2_b_2, NMK_GPIO_ALT_B),
+       DB8500_PIN_GROUP(msp0txrx_b_1, NMK_GPIO_ALT_B),
+       DB8500_PIN_GROUP(i2c1_b_2, NMK_GPIO_ALT_B),
+       DB8500_PIN_GROUP(u2rxtx_b_1, NMK_GPIO_ALT_B),
+       DB8500_PIN_GROUP(uartmodtx_b_1, NMK_GPIO_ALT_B),
+       DB8500_PIN_GROUP(msp0sck_b_1, NMK_GPIO_ALT_B),
+       DB8500_PIN_GROUP(uartmodrx_b_1, NMK_GPIO_ALT_B),
+       DB8500_PIN_GROUP(stmmod_b_1, NMK_GPIO_ALT_B),
+       DB8500_PIN_GROUP(uartmodrx_b_2, NMK_GPIO_ALT_B),
+       DB8500_PIN_GROUP(spi3_b_1, NMK_GPIO_ALT_B),
+       DB8500_PIN_GROUP(msp1txrx_b_1, NMK_GPIO_ALT_B),
+       DB8500_PIN_GROUP(kp_b_1, NMK_GPIO_ALT_B),
+       DB8500_PIN_GROUP(kp_b_2, NMK_GPIO_ALT_B),
+       DB8500_PIN_GROUP(sm_b_1, NMK_GPIO_ALT_B),
+       DB8500_PIN_GROUP(smcs0_b_1, NMK_GPIO_ALT_B),
+       DB8500_PIN_GROUP(smcs1_b_1, NMK_GPIO_ALT_B),
+       DB8500_PIN_GROUP(ipgpio7_b_1, NMK_GPIO_ALT_B),
+       DB8500_PIN_GROUP(ipgpio2_b_1, NMK_GPIO_ALT_B),
+       DB8500_PIN_GROUP(ipgpio3_b_1, NMK_GPIO_ALT_B),
+       DB8500_PIN_GROUP(lcdaclk_b_1, NMK_GPIO_ALT_B),
+       DB8500_PIN_GROUP(lcda_b_1, NMK_GPIO_ALT_B),
+       DB8500_PIN_GROUP(lcd_b_1, NMK_GPIO_ALT_B),
+       DB8500_PIN_GROUP(ddrtrig_b_1, NMK_GPIO_ALT_B),
+       DB8500_PIN_GROUP(pwl_b_1, NMK_GPIO_ALT_B),
+       DB8500_PIN_GROUP(spi1_b_1, NMK_GPIO_ALT_B),
+       DB8500_PIN_GROUP(mc3_b_1, NMK_GPIO_ALT_B),
+       DB8500_PIN_GROUP(pwl_b_2, NMK_GPIO_ALT_B),
+       DB8500_PIN_GROUP(pwl_b_3, NMK_GPIO_ALT_B),
+       DB8500_PIN_GROUP(pwl_b_4, NMK_GPIO_ALT_B),
+       /* Altfunction C column */
+       DB8500_PIN_GROUP(ipjtag_c_1, NMK_GPIO_ALT_C),
+       DB8500_PIN_GROUP(ipgpio6_c_1, NMK_GPIO_ALT_C),
+       DB8500_PIN_GROUP(ipgpio0_c_1, NMK_GPIO_ALT_C),
+       DB8500_PIN_GROUP(ipgpio1_c_1, NMK_GPIO_ALT_C),
+       DB8500_PIN_GROUP(ipgpio3_c_1, NMK_GPIO_ALT_C),
+       DB8500_PIN_GROUP(ipgpio2_c_1, NMK_GPIO_ALT_C),
+       DB8500_PIN_GROUP(slim0_c_1, NMK_GPIO_ALT_C),
+       DB8500_PIN_GROUP(ms_c_1, NMK_GPIO_ALT_C),
+       DB8500_PIN_GROUP(iptrigout_c_1, NMK_GPIO_ALT_C),
+       DB8500_PIN_GROUP(u2rxtx_c_1, NMK_GPIO_ALT_C),
+       DB8500_PIN_GROUP(u2ctsrts_c_1, NMK_GPIO_ALT_C),
+       DB8500_PIN_GROUP(u0_c_1, NMK_GPIO_ALT_C),
+       DB8500_PIN_GROUP(ipgpio4_c_1, NMK_GPIO_ALT_C),
+       DB8500_PIN_GROUP(ipgpio5_c_1, NMK_GPIO_ALT_C),
+       DB8500_PIN_GROUP(ipgpio6_c_1, NMK_GPIO_ALT_C),
+       DB8500_PIN_GROUP(ipgpio7_c_1, NMK_GPIO_ALT_C),
+       DB8500_PIN_GROUP(smcleale_c_1, NMK_GPIO_ALT_C),
+       DB8500_PIN_GROUP(stmape_c_1, NMK_GPIO_ALT_C),
+       DB8500_PIN_GROUP(u2rxtx_c_2, NMK_GPIO_ALT_C),
+       DB8500_PIN_GROUP(ipgpio2_c_2, NMK_GPIO_ALT_C),
+       DB8500_PIN_GROUP(ipgpio3_c_2, NMK_GPIO_ALT_C),
+       DB8500_PIN_GROUP(ipgpio4_c_2, NMK_GPIO_ALT_C),
+       DB8500_PIN_GROUP(ipgpio5_c_2, NMK_GPIO_ALT_C),
+       DB8500_PIN_GROUP(mc5_c_1, NMK_GPIO_ALT_C),
+       DB8500_PIN_GROUP(mc2rstn_c_1, NMK_GPIO_ALT_C),
+       DB8500_PIN_GROUP(kp_c_1, NMK_GPIO_ALT_C),
+       DB8500_PIN_GROUP(smps0_c_1, NMK_GPIO_ALT_C),
+       DB8500_PIN_GROUP(smps1_c_1, NMK_GPIO_ALT_C),
+       DB8500_PIN_GROUP(u2rxtx_c_3, NMK_GPIO_ALT_C),
+       DB8500_PIN_GROUP(stmape_c_2, NMK_GPIO_ALT_C),
+       DB8500_PIN_GROUP(uartmodrx_c_1, NMK_GPIO_ALT_C),
+       DB8500_PIN_GROUP(uartmodtx_c_1, NMK_GPIO_ALT_C),
+       DB8500_PIN_GROUP(stmmod_c_1, NMK_GPIO_ALT_C),
+       DB8500_PIN_GROUP(usbsim_c_1, NMK_GPIO_ALT_C),
+       DB8500_PIN_GROUP(mc4rstn_c_1, NMK_GPIO_ALT_C),
+       DB8500_PIN_GROUP(clkout1_c_1, NMK_GPIO_ALT_C),
+       DB8500_PIN_GROUP(clkout2_c_1, NMK_GPIO_ALT_C),
+       DB8500_PIN_GROUP(i2c3_c_1, NMK_GPIO_ALT_C),
+       DB8500_PIN_GROUP(spi0_c_1, NMK_GPIO_ALT_C),
+       DB8500_PIN_GROUP(usbsim_c_2, NMK_GPIO_ALT_C),
+       DB8500_PIN_GROUP(i2c3_c_2, NMK_GPIO_ALT_C),
+       /* Other alt C1 column */
+       DB8500_PIN_GROUP(u2rx_oc1_1, NMK_GPIO_ALT_C1),
+       DB8500_PIN_GROUP(stmape_oc1_1, NMK_GPIO_ALT_C1),
+       DB8500_PIN_GROUP(remap0_oc1_1, NMK_GPIO_ALT_C1),
+       DB8500_PIN_GROUP(remap1_oc1_1, NMK_GPIO_ALT_C1),
+       DB8500_PIN_GROUP(ptma9_oc1_1, NMK_GPIO_ALT_C1),
+       DB8500_PIN_GROUP(kp_oc1_1, NMK_GPIO_ALT_C1),
+       DB8500_PIN_GROUP(rf_oc1_1, NMK_GPIO_ALT_C1),
+       DB8500_PIN_GROUP(hxclk_oc1_1, NMK_GPIO_ALT_C1),
+       DB8500_PIN_GROUP(uartmodrx_oc1_1, NMK_GPIO_ALT_C1),
+       DB8500_PIN_GROUP(uartmodtx_oc1_1, NMK_GPIO_ALT_C1),
+       DB8500_PIN_GROUP(stmmod_oc1_1, NMK_GPIO_ALT_C1),
+       DB8500_PIN_GROUP(hxgpio_oc1_1, NMK_GPIO_ALT_C1),
+       DB8500_PIN_GROUP(rf_oc1_2, NMK_GPIO_ALT_C1),
+       DB8500_PIN_GROUP(spi2_oc1_1, NMK_GPIO_ALT_C1),
+       DB8500_PIN_GROUP(spi2_oc1_2, NMK_GPIO_ALT_C1),
+       /* Other alt C2 column */
+       DB8500_PIN_GROUP(sbag_oc2_1, NMK_GPIO_ALT_C2),
+       DB8500_PIN_GROUP(etmr4_oc2_1, NMK_GPIO_ALT_C2),
+       DB8500_PIN_GROUP(ptma9_oc2_1, NMK_GPIO_ALT_C2),
+       /* Other alt C3 column */
+       DB8500_PIN_GROUP(stmmod_oc3_1, NMK_GPIO_ALT_C3),
+       DB8500_PIN_GROUP(stmmod_oc3_2, NMK_GPIO_ALT_C3),
+       DB8500_PIN_GROUP(uartmodrx_oc3_1, NMK_GPIO_ALT_C3),
+       DB8500_PIN_GROUP(uartmodtx_oc3_1, NMK_GPIO_ALT_C3),
+       DB8500_PIN_GROUP(etmr4_oc3_1, NMK_GPIO_ALT_C3),
+       /* Other alt C4 column */
+       DB8500_PIN_GROUP(sbag_oc4_1, NMK_GPIO_ALT_C4),
+       DB8500_PIN_GROUP(hwobs_oc4_1, NMK_GPIO_ALT_C4),
+};
+
+/* We use this macro to define the groups applicable to a function */
+#define DB8500_FUNC_GROUPS(a, b...)       \
+static const char * const a##_groups[] = { b };
+
+DB8500_FUNC_GROUPS(u0, "u0_a_1", "u0_c_1");
+DB8500_FUNC_GROUPS(u1, "u1rxtx_a_1", "u1ctsrts_a_1");
+/*
+ * UART2 can be muxed out with just RX/TX in four places, CTS+RTS is however
+ * only available on two pins in alternative function C
+ */
+DB8500_FUNC_GROUPS(u2, "u2rxtx_b_1", "u2rxtx_c_1", "u2ctsrts_c_1",
+                  "u2rxtx_c_2", "u2rxtx_c_3", "u2rx_oc1_1");
+DB8500_FUNC_GROUPS(ipi2c, "ipi2c_a_1", "ipi2c_a_2");
+/*
+ * MSP0 can only be on a certain set of pins, but the TX/RX pins can be
+ * switched around by selecting the altfunction A or B. The SCK pin is
+ * only available on the altfunction B.
+ */
+DB8500_FUNC_GROUPS(msp0, "msp0txrx_a_1", "msp0tfstck_a_1", "msp0rfstck_a_1",
+                  "msp0txrx_b_1", "msp0sck_b_1");
+DB8500_FUNC_GROUPS(mc0, "mc0_a_1", "mc0_dat47_a_1", "mc0dat31dir_a_1");
+/* MSP0 can swap RX/TX like MSP0 but has no SCK pin available */
+DB8500_FUNC_GROUPS(msp1, "msp1txrx_a_1", "msp1_a_1", "msp1txrx_b_1");
+DB8500_FUNC_GROUPS(lcdb, "lcdb_a_1");
+DB8500_FUNC_GROUPS(lcd, "lcdvsi0_a_1", "lcdvsi1_a_1", "lcd_d0_d7_a_1",
+       "lcd_d8_d11_a_1", "lcd_d12_d23_a_1", "lcd_b_1");
+DB8500_FUNC_GROUPS(kp, "kp_a_1", "kp_a_2", "kp_b_1", "kp_b_2", "kp_c_1", "kp_oc1_1");
+DB8500_FUNC_GROUPS(mc2, "mc2_a_1", "mc2rstn_c_1");
+DB8500_FUNC_GROUPS(ssp1, "ssp1_a_1");
+DB8500_FUNC_GROUPS(ssp0, "ssp0_a_1");
+DB8500_FUNC_GROUPS(i2c0, "i2c0_a_1");
+/* The image processor has 8 GPIO pins that can be muxed out */
+DB8500_FUNC_GROUPS(ipgpio, "ipgpio0_a_1", "ipgpio1_a_1", "ipgpio7_b_1",
+       "ipgpio2_b_1", "ipgpio3_b_1", "ipgpio6_c_1", "ipgpio0_c_1",
+       "ipgpio1_c_1", "ipgpio3_c_1", "ipgpio2_c_1", "ipgpio4_c_1",
+       "ipgpio5_c_1", "ipgpio6_c_2", "ipgpio7_c_1", "ipgpio2_c_2",
+       "ipgpio3_c_2", "ipgpio4_c_2", "ipgpio5_c_2");
+/* MSP2 can not invert the RX/TX pins but has the optional SCK pin */
+DB8500_FUNC_GROUPS(msp2, "msp2sck_a_1", "msp2_a_1");
+DB8500_FUNC_GROUPS(mc4, "mc4_a_1", "mc4rstn_c_1");
+DB8500_FUNC_GROUPS(mc1, "mc1_a_1", "mc1_a_2", "mc1dir_a_1");
+DB8500_FUNC_GROUPS(hsi, "hsir_a_1", "hsit_a_1", "hsit_a_2");
+DB8500_FUNC_GROUPS(clkout, "clkout1_a_1", "clkout1_a_2", "clkout1_c_1",
+               "clkout2_a_1", "clkout2_a_2", "clkout2_c_1");
+DB8500_FUNC_GROUPS(usb, "usb_a_1");
+DB8500_FUNC_GROUPS(trig, "trig_b_1");
+DB8500_FUNC_GROUPS(i2c4, "i2c4_b_1");
+DB8500_FUNC_GROUPS(i2c1, "i2c1_b_1", "i2c1_b_2");
+DB8500_FUNC_GROUPS(i2c2, "i2c2_b_1", "i2c2_b_2");
+/*
+ * The modem UART can output its RX and TX pins in some different places,
+ * so select one of each.
+ */
+DB8500_FUNC_GROUPS(uartmod, "uartmodtx_b_1", "uartmodrx_b_1", "uartmodrx_b_2",
+               "uartmodrx_c_1", "uartmod_tx_c_1", "uartmodrx_oc1_1",
+               "uartmodtx_oc1_1", "uartmodrx_oc3_1", "uartmodtx_oc3_1");
+DB8500_FUNC_GROUPS(stmmod, "stmmod_b_1", "stmmod_c_1", "stmmod_oc1_1",
+               "stmmod_oc3_1", "stmmod_oc3_2");
+DB8500_FUNC_GROUPS(spi3, "spi3_b_1");
+/* Select between CS0 on alt B or PS1 on alt C */
+DB8500_FUNC_GROUPS(sm, "sm_b_1", "smcs0_b_1", "smcs1_b_1", "smcleale_c_1",
+                  "smps0_c_1", "smps1_c_1");
+DB8500_FUNC_GROUPS(lcda, "lcdaclk_b_1", "lcda_b_1");
+DB8500_FUNC_GROUPS(ddrtrig, "ddrtrig_b_1");
+DB8500_FUNC_GROUPS(pwl, "pwl_b_1", "pwl_b_2", "pwl_b_3", "pwl_b_4");
+DB8500_FUNC_GROUPS(spi1, "spi1_b_1");
+DB8500_FUNC_GROUPS(mc3, "mc3_b_1");
+DB8500_FUNC_GROUPS(ipjtag, "ipjtag_c_1");
+DB8500_FUNC_GROUPS(slim0, "slim0_c_1");
+DB8500_FUNC_GROUPS(ms, "ms_c_1");
+DB8500_FUNC_GROUPS(iptrigout, "iptrigout_c_1");
+DB8500_FUNC_GROUPS(stmape, "stmape_c_1", "stmape_c_2", "stmape_oc1_1");
+DB8500_FUNC_GROUPS(mc5, "mc5_c_1");
+DB8500_FUNC_GROUPS(usbsim, "usbsim_c_1", "usbsim_c_2");
+DB8500_FUNC_GROUPS(i2c3, "i2c3_c_1", "i2c3_c_2");
+DB8500_FUNC_GROUPS(spi0, "spi0_c_1");
+DB8500_FUNC_GROUPS(spi2, "spi2_oc1_1", "spi2_oc1_2");
+DB8500_FUNC_GROUPS(remap, "remap0_oc1_1", "remap1_oc1_1");
+DB8500_FUNC_GROUPS(sbag, "sbag_oc2_1", "sbag_oc4_1");
+DB8500_FUNC_GROUPS(ptm, "ptma9_oc1_1", "ptma9_oc2_1");
+DB8500_FUNC_GROUPS(rf, "rf_oc1_1", "rf_oc1_2");
+DB8500_FUNC_GROUPS(hx, "hxclk_oc1_1", "hxgpio_oc1_1");
+DB8500_FUNC_GROUPS(etm, "etmr4_oc2_1", "etmr4_oc3_1");
+DB8500_FUNC_GROUPS(hwobs, "hwobs_oc4_1");
+#define FUNCTION(fname)                                        \
+       {                                               \
+               .name = #fname,                         \
+               .groups = fname##_groups,               \
+               .ngroups = ARRAY_SIZE(fname##_groups),  \
+       }
+
+static const struct nmk_function nmk_db8500_functions[] = {
+       FUNCTION(u0),
+       FUNCTION(u1),
+       FUNCTION(u2),
+       FUNCTION(ipi2c),
+       FUNCTION(msp0),
+       FUNCTION(mc0),
+       FUNCTION(msp1),
+       FUNCTION(lcdb),
+       FUNCTION(lcd),
+       FUNCTION(kp),
+       FUNCTION(mc2),
+       FUNCTION(ssp1),
+       FUNCTION(ssp0),
+       FUNCTION(i2c0),
+       FUNCTION(ipgpio),
+       FUNCTION(msp2),
+       FUNCTION(mc4),
+       FUNCTION(mc1),
+       FUNCTION(hsi),
+       FUNCTION(clkout),
+       FUNCTION(usb),
+       FUNCTION(trig),
+       FUNCTION(i2c4),
+       FUNCTION(i2c1),
+       FUNCTION(i2c2),
+       FUNCTION(uartmod),
+       FUNCTION(stmmod),
+       FUNCTION(spi3),
+       FUNCTION(sm),
+       FUNCTION(lcda),
+       FUNCTION(ddrtrig),
+       FUNCTION(pwl),
+       FUNCTION(spi1),
+       FUNCTION(mc3),
+       FUNCTION(ipjtag),
+       FUNCTION(slim0),
+       FUNCTION(ms),
+       FUNCTION(iptrigout),
+       FUNCTION(stmape),
+       FUNCTION(mc5),
+       FUNCTION(usbsim),
+       FUNCTION(i2c3),
+       FUNCTION(spi0),
+       FUNCTION(spi2),
+       FUNCTION(remap),
+       FUNCTION(ptm),
+       FUNCTION(rf),
+       FUNCTION(hx),
+       FUNCTION(etm),
+       FUNCTION(hwobs),
+};
+
+static const struct prcm_gpiocr_altcx_pin_desc db8500_altcx_pins[] = {
+       PRCM_GPIOCR_ALTCX(23,   true, PRCM_IDX_GPIOCR1, 9,      /* STMAPE_CLK_a */
+                               true, PRCM_IDX_GPIOCR1, 7,      /* SBAG_CLK_a */
+                               false, 0, 0,
+                               false, 0, 0
+       ),
+       PRCM_GPIOCR_ALTCX(24,   true, PRCM_IDX_GPIOCR1, 9,      /* STMAPE or U2_RXD ??? */
+                               true, PRCM_IDX_GPIOCR1, 7,      /* SBAG_VAL_a */
+                               true, PRCM_IDX_GPIOCR1, 10,     /* STM_MOD_CMD0 */
+                               false, 0, 0
+       ),
+       PRCM_GPIOCR_ALTCX(25,   true, PRCM_IDX_GPIOCR1, 9,      /* STMAPE_DAT_a[0] */
+                               true, PRCM_IDX_GPIOCR1, 7,      /* SBAG_D_a[0] */
+                               false, 0, 0,
+                               false, 0, 0
+       ),
+       PRCM_GPIOCR_ALTCX(26,   true, PRCM_IDX_GPIOCR1, 9,      /* STMAPE_DAT_a[1] */
+                               true, PRCM_IDX_GPIOCR1, 7,      /* SBAG_D_a[1] */
+                               false, 0, 0,
+                               false, 0, 0
+       ),
+       PRCM_GPIOCR_ALTCX(27,   true, PRCM_IDX_GPIOCR1, 9,      /* STMAPE_DAT_a[2] */
+                               true, PRCM_IDX_GPIOCR1, 7,      /* SBAG_D_a[2] */
+                               false, 0, 0,
+                               false, 0, 0
+       ),
+       PRCM_GPIOCR_ALTCX(28,   true, PRCM_IDX_GPIOCR1, 9,      /* STMAPE_DAT_a[3] */
+                               true, PRCM_IDX_GPIOCR1, 7,      /* SBAG_D_a[3] */
+                               false, 0, 0,
+                               false, 0, 0
+       ),
+       PRCM_GPIOCR_ALTCX(29,   false, 0, 0,
+                               false, 0, 0,
+                               true, PRCM_IDX_GPIOCR1, 10,     /* STM_MOD_CMD0 */
+                               false, 0, 0
+       ),
+       PRCM_GPIOCR_ALTCX(30,   false, 0, 0,
+                               false, 0, 0,
+                               true, PRCM_IDX_GPIOCR1, 10,     /* STM_MOD_CMD0 */
+                               false, 0, 0
+       ),
+       PRCM_GPIOCR_ALTCX(31,   false, 0, 0,
+                               false, 0, 0,
+                               true, PRCM_IDX_GPIOCR1, 10,     /* STM_MOD_CMD0 */
+                               false, 0, 0
+       ),
+       PRCM_GPIOCR_ALTCX(32,   false, 0, 0,
+                               false, 0, 0,
+                               true, PRCM_IDX_GPIOCR1, 10,     /* STM_MOD_CMD0 */
+                               false, 0, 0
+       ),
+       PRCM_GPIOCR_ALTCX(68,   true, PRCM_IDX_GPIOCR1, 18,     /* REMAP_SELECT_ON */
+                               false, 0, 0,
+                               false, 0, 0,
+                               false, 0, 0
+       ),
+       PRCM_GPIOCR_ALTCX(69,   true, PRCM_IDX_GPIOCR1, 18,     /* REMAP_SELECT_ON */
+                               false, 0, 0,
+                               false, 0, 0,
+                               false, 0, 0
+       ),
+       PRCM_GPIOCR_ALTCX(70,   true, PRCM_IDX_GPIOCR1, 5,      /* PTM_A9_D23 */
+                               true, PRCM_IDX_GPIOCR2, 2,      /* DBG_ETM_R4_CMD0 */
+                               true, PRCM_IDX_GPIOCR1, 11,     /* STM_MOD_CMD1 */
+                               true, PRCM_IDX_GPIOCR1, 8       /* SBAG_CLK */
+       ),
+       PRCM_GPIOCR_ALTCX(71,   true, PRCM_IDX_GPIOCR1, 5,      /* PTM_A9_D22 */
+                               true, PRCM_IDX_GPIOCR2, 2,      /* DBG_ETM_R4_CMD0 */
+                               true, PRCM_IDX_GPIOCR1, 11,     /* STM_MOD_CMD1 */
+                               true, PRCM_IDX_GPIOCR1, 8       /* SBAG_D3 */
+       ),
+       PRCM_GPIOCR_ALTCX(72,   true, PRCM_IDX_GPIOCR1, 5,      /* PTM_A9_D21 */
+                               true, PRCM_IDX_GPIOCR2, 2,      /* DBG_ETM_R4_CMD0 */
+                               true, PRCM_IDX_GPIOCR1, 11,     /* STM_MOD_CMD1 */
+                               true, PRCM_IDX_GPIOCR1, 8       /* SBAG_D2 */
+       ),
+       PRCM_GPIOCR_ALTCX(73,   true, PRCM_IDX_GPIOCR1, 5,      /* PTM_A9_D20 */
+                               true, PRCM_IDX_GPIOCR2, 2,      /* DBG_ETM_R4_CMD0 */
+                               true, PRCM_IDX_GPIOCR1, 11,     /* STM_MOD_CMD1 */
+                               true, PRCM_IDX_GPIOCR1, 8       /* SBAG_D1 */
+       ),
+       PRCM_GPIOCR_ALTCX(74,   true, PRCM_IDX_GPIOCR1, 5,      /* PTM_A9_D19 */
+                               true, PRCM_IDX_GPIOCR2, 2,      /* DBG_ETM_R4_CMD0 */
+                               true, PRCM_IDX_GPIOCR1, 11,     /* STM_MOD_CMD1 */
+                               true, PRCM_IDX_GPIOCR1, 8       /* SBAG_D0 */
+       ),
+       PRCM_GPIOCR_ALTCX(75,   true, PRCM_IDX_GPIOCR1, 5,      /* PTM_A9_D18 */
+                               true, PRCM_IDX_GPIOCR2, 2,      /* DBG_ETM_R4_CMD0 */
+                               true, PRCM_IDX_GPIOCR1, 0,      /* DBG_UARTMOD_CMD0 */
+                               false, 0, 0
+       ),
+       PRCM_GPIOCR_ALTCX(76,   true, PRCM_IDX_GPIOCR1, 5,      /* PTM_A9_D17 */
+                               true, PRCM_IDX_GPIOCR2, 2,      /* DBG_ETM_R4_CMD0 */
+                               true, PRCM_IDX_GPIOCR1, 0,      /* DBG_UARTMOD_CMD0 */
+                               false, 0, 0
+       ),
+       PRCM_GPIOCR_ALTCX(77,   true, PRCM_IDX_GPIOCR1, 5,      /* PTM_A9_D16 */
+                               true, PRCM_IDX_GPIOCR2, 2,      /* DBG_ETM_R4_CMD0 */
+                               false, 0, 0,
+                               true, PRCM_IDX_GPIOCR1, 8       /* SBAG_VAL */
+       ),
+       PRCM_GPIOCR_ALTCX(86,   true, PRCM_IDX_GPIOCR1, 12,     /* KP_O3 */
+                               false, 0, 0,
+                               false, 0, 0,
+                               false, 0, 0
+       ),
+       PRCM_GPIOCR_ALTCX(87,   true, PRCM_IDX_GPIOCR1, 12,     /* KP_O2 */
+                               false, 0, 0,
+                               false, 0, 0,
+                               false, 0, 0
+       ),
+       PRCM_GPIOCR_ALTCX(88,   true, PRCM_IDX_GPIOCR1, 12,     /* KP_I3 */
+                               false, 0, 0,
+                               false, 0, 0,
+                               false, 0, 0
+       ),
+       PRCM_GPIOCR_ALTCX(89,   true, PRCM_IDX_GPIOCR1, 12,     /* KP_I2 */
+                               false, 0, 0,
+                               false, 0, 0,
+                               false, 0, 0
+       ),
+       PRCM_GPIOCR_ALTCX(90,   true, PRCM_IDX_GPIOCR1, 12,     /* KP_O1 */
+                               false, 0, 0,
+                               false, 0, 0,
+                               false, 0, 0
+       ),
+       PRCM_GPIOCR_ALTCX(91,   true, PRCM_IDX_GPIOCR1, 12,     /* KP_O0 */
+                               false, 0, 0,
+                               false, 0, 0,
+                               false, 0, 0
+       ),
+       PRCM_GPIOCR_ALTCX(92,   true, PRCM_IDX_GPIOCR1, 12,     /* KP_I1 */
+                               false, 0, 0,
+                               false, 0, 0,
+                               false, 0, 0
+       ),
+       PRCM_GPIOCR_ALTCX(93,   true, PRCM_IDX_GPIOCR1, 12,     /* KP_I0 */
+                               false, 0, 0,
+                               false, 0, 0,
+                               false, 0, 0
+       ),
+       PRCM_GPIOCR_ALTCX(96,   true, PRCM_IDX_GPIOCR2, 3,      /* RF_INT */
+                               false, 0, 0,
+                               false, 0, 0,
+                               false, 0, 0
+       ),
+       PRCM_GPIOCR_ALTCX(97,   true, PRCM_IDX_GPIOCR2, 1,      /* RF_CTRL */
+                               false, 0, 0,
+                               false, 0, 0,
+                               false, 0, 0
+       ),
+       PRCM_GPIOCR_ALTCX(151,  false, 0, 0,
+                               true, PRCM_IDX_GPIOCR1, 6,      /* PTM_A9_CTL */
+                               true, PRCM_IDX_GPIOCR1, 15,     /* DBG_ETM_R4_CMD1*/
+                               true, PRCM_IDX_GPIOCR1, 25      /* HW_OBS17 */
+       ),
+       PRCM_GPIOCR_ALTCX(152,  true, PRCM_IDX_GPIOCR1, 4,      /* Hx_CLK */
+                               true, PRCM_IDX_GPIOCR1, 6,      /* PTM_A9_CLK */
+                               true, PRCM_IDX_GPIOCR1, 15,     /* DBG_ETM_R4_CMD1*/
+                               true, PRCM_IDX_GPIOCR1, 25      /* HW_OBS16 */
+       ),
+       PRCM_GPIOCR_ALTCX(153,  true, PRCM_IDX_GPIOCR1, 1,      /* UARTMOD_CMD1 */
+                               true, PRCM_IDX_GPIOCR1, 14,     /* PTM_A9_D15 */
+                               true, PRCM_IDX_GPIOCR1, 19,     /* DBG_ETM_R4_CMD2 */
+                               true, PRCM_IDX_GPIOCR1, 25      /* HW_OBS15 */
+       ),
+       PRCM_GPIOCR_ALTCX(154,  true, PRCM_IDX_GPIOCR1, 1,      /* UARTMOD_CMD1 */
+                               true, PRCM_IDX_GPIOCR1, 14,     /* PTM_A9_D14 */
+                               true, PRCM_IDX_GPIOCR1, 19,     /* DBG_ETM_R4_CMD2 */
+                               true, PRCM_IDX_GPIOCR1, 25      /* HW_OBS14 */
+       ),
+       PRCM_GPIOCR_ALTCX(155,  true, PRCM_IDX_GPIOCR1, 13,     /* STM_MOD_CMD2 */
+                               true, PRCM_IDX_GPIOCR1, 14,     /* PTM_A9_D13 */
+                               true, PRCM_IDX_GPIOCR1, 19,     /* DBG_ETM_R4_CMD2 */
+                               true, PRCM_IDX_GPIOCR1, 25      /* HW_OBS13 */
+       ),
+       PRCM_GPIOCR_ALTCX(156,  true, PRCM_IDX_GPIOCR1, 13,     /* STM_MOD_CMD2 */
+                               true, PRCM_IDX_GPIOCR1, 14,     /* PTM_A9_D12 */
+                               true, PRCM_IDX_GPIOCR1, 19,     /* DBG_ETM_R4_CMD2 */
+                               true, PRCM_IDX_GPIOCR1, 25      /* HW_OBS12 */
+       ),
+       PRCM_GPIOCR_ALTCX(157,  true, PRCM_IDX_GPIOCR1, 13,     /* STM_MOD_CMD2 */
+                               true, PRCM_IDX_GPIOCR1, 14,     /* PTM_A9_D11 */
+                               true, PRCM_IDX_GPIOCR1, 19,     /* DBG_ETM_R4_CMD2 */
+                               true, PRCM_IDX_GPIOCR1, 25      /* HW_OBS11 */
+       ),
+       PRCM_GPIOCR_ALTCX(158,  true, PRCM_IDX_GPIOCR1, 13,     /* STM_MOD_CMD2 */
+                               true, PRCM_IDX_GPIOCR1, 14,     /* PTM_A9_D10 */
+                               true, PRCM_IDX_GPIOCR1, 19,     /* DBG_ETM_R4_CMD2 */
+                               true, PRCM_IDX_GPIOCR1, 25      /* HW_OBS10 */
+       ),
+       PRCM_GPIOCR_ALTCX(159,  true, PRCM_IDX_GPIOCR1, 13,     /* STM_MOD_CMD2 */
+                               true, PRCM_IDX_GPIOCR1, 14,     /* PTM_A9_D9 */
+                               true, PRCM_IDX_GPIOCR1, 19,     /* DBG_ETM_R4_CMD2 */
+                               true, PRCM_IDX_GPIOCR1, 25      /* HW_OBS9 */
+       ),
+       PRCM_GPIOCR_ALTCX(160,  false, 0, 0,
+                               true, PRCM_IDX_GPIOCR1, 14,     /* PTM_A9_D8 */
+                               true, PRCM_IDX_GPIOCR1, 19,     /* DBG_ETM_R4_CMD2 */
+                               true, PRCM_IDX_GPIOCR1, 25      /* HW_OBS8 */
+       ),
+       PRCM_GPIOCR_ALTCX(161,  true, PRCM_IDX_GPIOCR1, 4,      /* Hx_GPIO7 */
+                               true, PRCM_IDX_GPIOCR1, 6,      /* PTM_A9_D7 */
+                               true, PRCM_IDX_GPIOCR1, 15,     /* DBG_ETM_R4_CMD1*/
+                               true, PRCM_IDX_GPIOCR1, 24      /* HW_OBS7 */
+       ),
+       PRCM_GPIOCR_ALTCX(162,  true, PRCM_IDX_GPIOCR1, 4,      /* Hx_GPIO6 */
+                               true, PRCM_IDX_GPIOCR1, 6,      /* PTM_A9_D6 */
+                               true, PRCM_IDX_GPIOCR1, 15,     /* DBG_ETM_R4_CMD1*/
+                               true, PRCM_IDX_GPIOCR1, 24      /* HW_OBS6 */
+       ),
+       PRCM_GPIOCR_ALTCX(163,  true, PRCM_IDX_GPIOCR1, 4,      /* Hx_GPIO5 */
+                               true, PRCM_IDX_GPIOCR1, 6,      /* PTM_A9_D5 */
+                               true, PRCM_IDX_GPIOCR1, 15,     /* DBG_ETM_R4_CMD1*/
+                               true, PRCM_IDX_GPIOCR1, 24      /* HW_OBS5 */
+       ),
+       PRCM_GPIOCR_ALTCX(164,  true, PRCM_IDX_GPIOCR1, 4,      /* Hx_GPIO4 */
+                               true, PRCM_IDX_GPIOCR1, 6,      /* PTM_A9_D4 */
+                               true, PRCM_IDX_GPIOCR1, 15,     /* DBG_ETM_R4_CMD1*/
+                               true, PRCM_IDX_GPIOCR1, 24      /* HW_OBS4 */
+       ),
+       PRCM_GPIOCR_ALTCX(165,  true, PRCM_IDX_GPIOCR1, 4,      /* Hx_GPIO3 */
+                               true, PRCM_IDX_GPIOCR1, 6,      /* PTM_A9_D3 */
+                               true, PRCM_IDX_GPIOCR1, 15,     /* DBG_ETM_R4_CMD1*/
+                               true, PRCM_IDX_GPIOCR1, 24      /* HW_OBS3 */
+       ),
+       PRCM_GPIOCR_ALTCX(166,  true, PRCM_IDX_GPIOCR1, 4,      /* Hx_GPIO2 */
+                               true, PRCM_IDX_GPIOCR1, 6,      /* PTM_A9_D2 */
+                               true, PRCM_IDX_GPIOCR1, 15,     /* DBG_ETM_R4_CMD1*/
+                               true, PRCM_IDX_GPIOCR1, 24      /* HW_OBS2 */
+       ),
+       PRCM_GPIOCR_ALTCX(167,  true, PRCM_IDX_GPIOCR1, 4,      /* Hx_GPIO1 */
+                               true, PRCM_IDX_GPIOCR1, 6,      /* PTM_A9_D1 */
+                               true, PRCM_IDX_GPIOCR1, 15,     /* DBG_ETM_R4_CMD1*/
+                               true, PRCM_IDX_GPIOCR1, 24      /* HW_OBS1 */
+       ),
+       PRCM_GPIOCR_ALTCX(168,  true, PRCM_IDX_GPIOCR1, 4,      /* Hx_GPIO0 */
+                               true, PRCM_IDX_GPIOCR1, 6,      /* PTM_A9_D0 */
+                               true, PRCM_IDX_GPIOCR1, 15,     /* DBG_ETM_R4_CMD1*/
+                               true, PRCM_IDX_GPIOCR1, 24      /* HW_OBS0 */
+       ),
+       PRCM_GPIOCR_ALTCX(170,  true, PRCM_IDX_GPIOCR2, 2,      /* RF_INT */
+                               false, 0, 0,
+                               false, 0, 0,
+                               false, 0, 0
+       ),
+       PRCM_GPIOCR_ALTCX(171,  true, PRCM_IDX_GPIOCR2, 0,      /* RF_CTRL */
+                               false, 0, 0,
+                               false, 0, 0,
+                               false, 0, 0
+       ),
+       PRCM_GPIOCR_ALTCX(215,  true, PRCM_IDX_GPIOCR1, 23,     /* SPI2_TXD */
+                               false, 0, 0,
+                               false, 0, 0,
+                               false, 0, 0
+       ),
+       PRCM_GPIOCR_ALTCX(216,  true, PRCM_IDX_GPIOCR1, 23,     /* SPI2_FRM */
+                               false, 0, 0,
+                               false, 0, 0,
+                               false, 0, 0
+       ),
+       PRCM_GPIOCR_ALTCX(217,  true, PRCM_IDX_GPIOCR1, 23,     /* SPI2_CLK */
+                               false, 0, 0,
+                               false, 0, 0,
+                               false, 0, 0
+       ),
+       PRCM_GPIOCR_ALTCX(218,  true, PRCM_IDX_GPIOCR1, 23,     /* SPI2_RXD */
+                               false, 0, 0,
+                               false, 0, 0,
+                               false, 0, 0
+       ),
+};
+
+static const u16 db8500_prcm_gpiocr_regs[] = {
+       [PRCM_IDX_GPIOCR1] = 0x138,
+       [PRCM_IDX_GPIOCR2] = 0x574,
+};
+
+static const struct nmk_pinctrl_soc_data nmk_db8500_soc = {
+       .gpio_ranges = nmk_db8500_ranges,
+       .gpio_num_ranges = ARRAY_SIZE(nmk_db8500_ranges),
+       .pins = nmk_db8500_pins,
+       .npins = ARRAY_SIZE(nmk_db8500_pins),
+       .functions = nmk_db8500_functions,
+       .nfunctions = ARRAY_SIZE(nmk_db8500_functions),
+       .groups = nmk_db8500_groups,
+       .ngroups = ARRAY_SIZE(nmk_db8500_groups),
+       .altcx_pins = db8500_altcx_pins,
+       .npins_altcx = ARRAY_SIZE(db8500_altcx_pins),
+       .prcm_gpiocr_registers = db8500_prcm_gpiocr_regs,
+};
+
+void nmk_pinctrl_db8500_init(const struct nmk_pinctrl_soc_data **soc)
+{
+       *soc = &nmk_db8500_soc;
+}
diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik-db8540.c b/drivers/pinctrl/nomadik/pinctrl-nomadik-db8540.c
new file mode 100644 (file)
index 0000000..d7ba544
--- /dev/null
@@ -0,0 +1,1266 @@
+#include <linux/kernel.h>
+#include <linux/pinctrl/pinctrl.h>
+#include "pinctrl-nomadik.h"
+
+/* All the pins that can be used for GPIO and some other functions */
+#define _GPIO(offset)          (offset)
+
+#define DB8540_PIN_AH6         _GPIO(0)
+#define DB8540_PIN_AG7         _GPIO(1)
+#define DB8540_PIN_AF2         _GPIO(2)
+#define DB8540_PIN_AD3         _GPIO(3)
+#define DB8540_PIN_AF6         _GPIO(4)
+#define DB8540_PIN_AG6         _GPIO(5)
+#define DB8540_PIN_AD5         _GPIO(6)
+#define DB8540_PIN_AF7         _GPIO(7)
+#define DB8540_PIN_AG5         _GPIO(8)
+#define DB8540_PIN_AH5         _GPIO(9)
+#define DB8540_PIN_AE4         _GPIO(10)
+#define DB8540_PIN_AD1         _GPIO(11)
+#define DB8540_PIN_AD2         _GPIO(12)
+#define DB8540_PIN_AC2         _GPIO(13)
+#define DB8540_PIN_AC4         _GPIO(14)
+#define DB8540_PIN_AC3         _GPIO(15)
+#define DB8540_PIN_AH7         _GPIO(16)
+#define DB8540_PIN_AE7         _GPIO(17)
+/* Hole */
+#define DB8540_PIN_AF8         _GPIO(22)
+#define DB8540_PIN_AH11                _GPIO(23)
+#define DB8540_PIN_AG11                _GPIO(24)
+#define DB8540_PIN_AF11                _GPIO(25)
+#define DB8540_PIN_AH10                _GPIO(26)
+#define DB8540_PIN_AG10                _GPIO(27)
+#define DB8540_PIN_AF10                _GPIO(28)
+/* Hole */
+#define DB8540_PIN_AD4         _GPIO(33)
+#define DB8540_PIN_AF3         _GPIO(34)
+#define DB8540_PIN_AF5         _GPIO(35)
+#define DB8540_PIN_AG4         _GPIO(36)
+#define DB8540_PIN_AF9         _GPIO(37)
+#define DB8540_PIN_AE8         _GPIO(38)
+/* Hole */
+#define DB8540_PIN_M26         _GPIO(64)
+#define DB8540_PIN_M25         _GPIO(65)
+#define DB8540_PIN_M27         _GPIO(66)
+#define DB8540_PIN_N25         _GPIO(67)
+/* Hole */
+#define DB8540_PIN_M28         _GPIO(70)
+#define DB8540_PIN_N26         _GPIO(71)
+#define DB8540_PIN_M22         _GPIO(72)
+#define DB8540_PIN_N22         _GPIO(73)
+#define DB8540_PIN_N27         _GPIO(74)
+#define DB8540_PIN_N28         _GPIO(75)
+#define DB8540_PIN_P22         _GPIO(76)
+#define DB8540_PIN_P28         _GPIO(77)
+#define DB8540_PIN_P26         _GPIO(78)
+#define DB8540_PIN_T22         _GPIO(79)
+#define DB8540_PIN_R27         _GPIO(80)
+#define DB8540_PIN_P27         _GPIO(81)
+#define DB8540_PIN_R26         _GPIO(82)
+#define DB8540_PIN_R25         _GPIO(83)
+#define DB8540_PIN_U22         _GPIO(84)
+#define DB8540_PIN_T27         _GPIO(85)
+#define DB8540_PIN_T25         _GPIO(86)
+#define DB8540_PIN_T26         _GPIO(87)
+/* Hole */
+#define DB8540_PIN_AF20                _GPIO(116)
+#define DB8540_PIN_AG21                _GPIO(117)
+#define DB8540_PIN_AH19                _GPIO(118)
+#define DB8540_PIN_AE19                _GPIO(119)
+#define DB8540_PIN_AG18                _GPIO(120)
+#define DB8540_PIN_AH17                _GPIO(121)
+#define DB8540_PIN_AF19                _GPIO(122)
+#define DB8540_PIN_AF18                _GPIO(123)
+#define DB8540_PIN_AE18                _GPIO(124)
+#define DB8540_PIN_AG17                _GPIO(125)
+#define DB8540_PIN_AF17                _GPIO(126)
+#define DB8540_PIN_AE17                _GPIO(127)
+#define DB8540_PIN_AC27                _GPIO(128)
+#define DB8540_PIN_AD27                _GPIO(129)
+#define DB8540_PIN_AE28                _GPIO(130)
+#define DB8540_PIN_AG26                _GPIO(131)
+#define DB8540_PIN_AF25                _GPIO(132)
+#define DB8540_PIN_AE27                _GPIO(133)
+#define DB8540_PIN_AF27                _GPIO(134)
+#define DB8540_PIN_AG28                _GPIO(135)
+#define DB8540_PIN_AF28                _GPIO(136)
+#define DB8540_PIN_AG25                _GPIO(137)
+#define DB8540_PIN_AG24                _GPIO(138)
+#define DB8540_PIN_AD25                _GPIO(139)
+#define DB8540_PIN_AH25                _GPIO(140)
+#define DB8540_PIN_AF26                _GPIO(141)
+#define DB8540_PIN_AF23                _GPIO(142)
+#define DB8540_PIN_AG23                _GPIO(143)
+#define DB8540_PIN_AE25                _GPIO(144)
+#define DB8540_PIN_AH24                _GPIO(145)
+#define DB8540_PIN_AJ25                _GPIO(146)
+#define DB8540_PIN_AG27                _GPIO(147)
+#define DB8540_PIN_AH23                _GPIO(148)
+#define DB8540_PIN_AE26                _GPIO(149)
+#define DB8540_PIN_AE24                _GPIO(150)
+#define DB8540_PIN_AJ24                _GPIO(151)
+#define DB8540_PIN_AE21                _GPIO(152)
+#define DB8540_PIN_AG22                _GPIO(153)
+#define DB8540_PIN_AF21                _GPIO(154)
+#define DB8540_PIN_AF24                _GPIO(155)
+#define DB8540_PIN_AH22                _GPIO(156)
+#define DB8540_PIN_AJ23                _GPIO(157)
+#define DB8540_PIN_AH21                _GPIO(158)
+#define DB8540_PIN_AG20                _GPIO(159)
+#define DB8540_PIN_AE23                _GPIO(160)
+#define DB8540_PIN_AH20                _GPIO(161)
+#define DB8540_PIN_AG19                _GPIO(162)
+#define DB8540_PIN_AF22                _GPIO(163)
+#define DB8540_PIN_AJ21                _GPIO(164)
+#define DB8540_PIN_AD26                _GPIO(165)
+#define DB8540_PIN_AD28                _GPIO(166)
+#define DB8540_PIN_AC28                _GPIO(167)
+#define DB8540_PIN_AC26                _GPIO(168)
+/* Hole */
+#define DB8540_PIN_J3          _GPIO(192)
+#define DB8540_PIN_H1          _GPIO(193)
+#define DB8540_PIN_J2          _GPIO(194)
+#define DB8540_PIN_H2          _GPIO(195)
+#define DB8540_PIN_H3          _GPIO(196)
+#define DB8540_PIN_H4          _GPIO(197)
+#define DB8540_PIN_G2          _GPIO(198)
+#define DB8540_PIN_G3          _GPIO(199)
+#define DB8540_PIN_G4          _GPIO(200)
+#define DB8540_PIN_F2          _GPIO(201)
+#define DB8540_PIN_C6          _GPIO(202)
+#define DB8540_PIN_B6          _GPIO(203)
+#define DB8540_PIN_B7          _GPIO(204)
+#define DB8540_PIN_A7          _GPIO(205)
+#define DB8540_PIN_D7          _GPIO(206)
+#define DB8540_PIN_D8          _GPIO(207)
+#define DB8540_PIN_F3          _GPIO(208)
+#define DB8540_PIN_E2          _GPIO(209)
+#define DB8540_PIN_C7          _GPIO(210)
+#define DB8540_PIN_B8          _GPIO(211)
+#define DB8540_PIN_C10         _GPIO(212)
+#define DB8540_PIN_C8          _GPIO(213)
+#define DB8540_PIN_C9          _GPIO(214)
+/* Hole */
+#define DB8540_PIN_B9          _GPIO(219)
+#define DB8540_PIN_A10         _GPIO(220)
+#define DB8540_PIN_D9          _GPIO(221)
+#define DB8540_PIN_B11         _GPIO(222)
+#define DB8540_PIN_B10         _GPIO(223)
+#define DB8540_PIN_E10         _GPIO(224)
+#define DB8540_PIN_B12         _GPIO(225)
+#define DB8540_PIN_D10         _GPIO(226)
+#define DB8540_PIN_D11         _GPIO(227)
+#define DB8540_PIN_AJ6         _GPIO(228)
+#define DB8540_PIN_B13         _GPIO(229)
+#define DB8540_PIN_C12         _GPIO(230)
+#define DB8540_PIN_B14         _GPIO(231)
+#define DB8540_PIN_E11         _GPIO(232)
+/* Hole */
+#define DB8540_PIN_D12         _GPIO(256)
+#define DB8540_PIN_D15         _GPIO(257)
+#define DB8540_PIN_C13         _GPIO(258)
+#define DB8540_PIN_C14         _GPIO(259)
+#define DB8540_PIN_C18         _GPIO(260)
+#define DB8540_PIN_C16         _GPIO(261)
+#define DB8540_PIN_B16         _GPIO(262)
+#define DB8540_PIN_D18         _GPIO(263)
+#define DB8540_PIN_C15         _GPIO(264)
+#define DB8540_PIN_C17         _GPIO(265)
+#define DB8540_PIN_B17         _GPIO(266)
+#define DB8540_PIN_D17         _GPIO(267)
+
+/*
+ * The names of the pins are denoted by GPIO number and ball name, even
+ * though they can be used for other things than GPIO, this is the first
+ * column in the table of the data sheet and often used on schematics and
+ * such.
+ */
+static const struct pinctrl_pin_desc nmk_db8540_pins[] = {
+       PINCTRL_PIN(DB8540_PIN_AH6, "GPIO0_AH6"),
+       PINCTRL_PIN(DB8540_PIN_AG7, "GPIO1_AG7"),
+       PINCTRL_PIN(DB8540_PIN_AF2, "GPIO2_AF2"),
+       PINCTRL_PIN(DB8540_PIN_AD3, "GPIO3_AD3"),
+       PINCTRL_PIN(DB8540_PIN_AF6, "GPIO4_AF6"),
+       PINCTRL_PIN(DB8540_PIN_AG6, "GPIO5_AG6"),
+       PINCTRL_PIN(DB8540_PIN_AD5, "GPIO6_AD5"),
+       PINCTRL_PIN(DB8540_PIN_AF7, "GPIO7_AF7"),
+       PINCTRL_PIN(DB8540_PIN_AG5, "GPIO8_AG5"),
+       PINCTRL_PIN(DB8540_PIN_AH5, "GPIO9_AH5"),
+       PINCTRL_PIN(DB8540_PIN_AE4, "GPIO10_AE4"),
+       PINCTRL_PIN(DB8540_PIN_AD1, "GPIO11_AD1"),
+       PINCTRL_PIN(DB8540_PIN_AD2, "GPIO12_AD2"),
+       PINCTRL_PIN(DB8540_PIN_AC2, "GPIO13_AC2"),
+       PINCTRL_PIN(DB8540_PIN_AC4, "GPIO14_AC4"),
+       PINCTRL_PIN(DB8540_PIN_AC3, "GPIO15_AC3"),
+       PINCTRL_PIN(DB8540_PIN_AH7, "GPIO16_AH7"),
+       PINCTRL_PIN(DB8540_PIN_AE7, "GPIO17_AE7"),
+       /* Hole */
+       PINCTRL_PIN(DB8540_PIN_AF8, "GPIO22_AF8"),
+       PINCTRL_PIN(DB8540_PIN_AH11, "GPIO23_AH11"),
+       PINCTRL_PIN(DB8540_PIN_AG11, "GPIO24_AG11"),
+       PINCTRL_PIN(DB8540_PIN_AF11, "GPIO25_AF11"),
+       PINCTRL_PIN(DB8540_PIN_AH10, "GPIO26_AH10"),
+       PINCTRL_PIN(DB8540_PIN_AG10, "GPIO27_AG10"),
+       PINCTRL_PIN(DB8540_PIN_AF10, "GPIO28_AF10"),
+       /* Hole */
+       PINCTRL_PIN(DB8540_PIN_AD4, "GPIO33_AD4"),
+       PINCTRL_PIN(DB8540_PIN_AF3, "GPIO34_AF3"),
+       PINCTRL_PIN(DB8540_PIN_AF5, "GPIO35_AF5"),
+       PINCTRL_PIN(DB8540_PIN_AG4, "GPIO36_AG4"),
+       PINCTRL_PIN(DB8540_PIN_AF9, "GPIO37_AF9"),
+       PINCTRL_PIN(DB8540_PIN_AE8, "GPIO38_AE8"),
+       /* Hole */
+       PINCTRL_PIN(DB8540_PIN_M26, "GPIO64_M26"),
+       PINCTRL_PIN(DB8540_PIN_M25, "GPIO65_M25"),
+       PINCTRL_PIN(DB8540_PIN_M27, "GPIO66_M27"),
+       PINCTRL_PIN(DB8540_PIN_N25, "GPIO67_N25"),
+       /* Hole */
+       PINCTRL_PIN(DB8540_PIN_M28, "GPIO70_M28"),
+       PINCTRL_PIN(DB8540_PIN_N26, "GPIO71_N26"),
+       PINCTRL_PIN(DB8540_PIN_M22, "GPIO72_M22"),
+       PINCTRL_PIN(DB8540_PIN_N22, "GPIO73_N22"),
+       PINCTRL_PIN(DB8540_PIN_N27, "GPIO74_N27"),
+       PINCTRL_PIN(DB8540_PIN_N28, "GPIO75_N28"),
+       PINCTRL_PIN(DB8540_PIN_P22, "GPIO76_P22"),
+       PINCTRL_PIN(DB8540_PIN_P28, "GPIO77_P28"),
+       PINCTRL_PIN(DB8540_PIN_P26, "GPIO78_P26"),
+       PINCTRL_PIN(DB8540_PIN_T22, "GPIO79_T22"),
+       PINCTRL_PIN(DB8540_PIN_R27, "GPIO80_R27"),
+       PINCTRL_PIN(DB8540_PIN_P27, "GPIO81_P27"),
+       PINCTRL_PIN(DB8540_PIN_R26, "GPIO82_R26"),
+       PINCTRL_PIN(DB8540_PIN_R25, "GPIO83_R25"),
+       PINCTRL_PIN(DB8540_PIN_U22, "GPIO84_U22"),
+       PINCTRL_PIN(DB8540_PIN_T27, "GPIO85_T27"),
+       PINCTRL_PIN(DB8540_PIN_T25, "GPIO86_T25"),
+       PINCTRL_PIN(DB8540_PIN_T26, "GPIO87_T26"),
+       /* Hole */
+       PINCTRL_PIN(DB8540_PIN_AF20, "GPIO116_AF20"),
+       PINCTRL_PIN(DB8540_PIN_AG21, "GPIO117_AG21"),
+       PINCTRL_PIN(DB8540_PIN_AH19, "GPIO118_AH19"),
+       PINCTRL_PIN(DB8540_PIN_AE19, "GPIO119_AE19"),
+       PINCTRL_PIN(DB8540_PIN_AG18, "GPIO120_AG18"),
+       PINCTRL_PIN(DB8540_PIN_AH17, "GPIO121_AH17"),
+       PINCTRL_PIN(DB8540_PIN_AF19, "GPIO122_AF19"),
+       PINCTRL_PIN(DB8540_PIN_AF18, "GPIO123_AF18"),
+       PINCTRL_PIN(DB8540_PIN_AE18, "GPIO124_AE18"),
+       PINCTRL_PIN(DB8540_PIN_AG17, "GPIO125_AG17"),
+       PINCTRL_PIN(DB8540_PIN_AF17, "GPIO126_AF17"),
+       PINCTRL_PIN(DB8540_PIN_AE17, "GPIO127_AE17"),
+       PINCTRL_PIN(DB8540_PIN_AC27, "GPIO128_AC27"),
+       PINCTRL_PIN(DB8540_PIN_AD27, "GPIO129_AD27"),
+       PINCTRL_PIN(DB8540_PIN_AE28, "GPIO130_AE28"),
+       PINCTRL_PIN(DB8540_PIN_AG26, "GPIO131_AG26"),
+       PINCTRL_PIN(DB8540_PIN_AF25, "GPIO132_AF25"),
+       PINCTRL_PIN(DB8540_PIN_AE27, "GPIO133_AE27"),
+       PINCTRL_PIN(DB8540_PIN_AF27, "GPIO134_AF27"),
+       PINCTRL_PIN(DB8540_PIN_AG28, "GPIO135_AG28"),
+       PINCTRL_PIN(DB8540_PIN_AF28, "GPIO136_AF28"),
+       PINCTRL_PIN(DB8540_PIN_AG25, "GPIO137_AG25"),
+       PINCTRL_PIN(DB8540_PIN_AG24, "GPIO138_AG24"),
+       PINCTRL_PIN(DB8540_PIN_AD25, "GPIO139_AD25"),
+       PINCTRL_PIN(DB8540_PIN_AH25, "GPIO140_AH25"),
+       PINCTRL_PIN(DB8540_PIN_AF26, "GPIO141_AF26"),
+       PINCTRL_PIN(DB8540_PIN_AF23, "GPIO142_AF23"),
+       PINCTRL_PIN(DB8540_PIN_AG23, "GPIO143_AG23"),
+       PINCTRL_PIN(DB8540_PIN_AE25, "GPIO144_AE25"),
+       PINCTRL_PIN(DB8540_PIN_AH24, "GPIO145_AH24"),
+       PINCTRL_PIN(DB8540_PIN_AJ25, "GPIO146_AJ25"),
+       PINCTRL_PIN(DB8540_PIN_AG27, "GPIO147_AG27"),
+       PINCTRL_PIN(DB8540_PIN_AH23, "GPIO148_AH23"),
+       PINCTRL_PIN(DB8540_PIN_AE26, "GPIO149_AE26"),
+       PINCTRL_PIN(DB8540_PIN_AE24, "GPIO150_AE24"),
+       PINCTRL_PIN(DB8540_PIN_AJ24, "GPIO151_AJ24"),
+       PINCTRL_PIN(DB8540_PIN_AE21, "GPIO152_AE21"),
+       PINCTRL_PIN(DB8540_PIN_AG22, "GPIO153_AG22"),
+       PINCTRL_PIN(DB8540_PIN_AF21, "GPIO154_AF21"),
+       PINCTRL_PIN(DB8540_PIN_AF24, "GPIO155_AF24"),
+       PINCTRL_PIN(DB8540_PIN_AH22, "GPIO156_AH22"),
+       PINCTRL_PIN(DB8540_PIN_AJ23, "GPIO157_AJ23"),
+       PINCTRL_PIN(DB8540_PIN_AH21, "GPIO158_AH21"),
+       PINCTRL_PIN(DB8540_PIN_AG20, "GPIO159_AG20"),
+       PINCTRL_PIN(DB8540_PIN_AE23, "GPIO160_AE23"),
+       PINCTRL_PIN(DB8540_PIN_AH20, "GPIO161_AH20"),
+       PINCTRL_PIN(DB8540_PIN_AG19, "GPIO162_AG19"),
+       PINCTRL_PIN(DB8540_PIN_AF22, "GPIO163_AF22"),
+       PINCTRL_PIN(DB8540_PIN_AJ21, "GPIO164_AJ21"),
+       PINCTRL_PIN(DB8540_PIN_AD26, "GPIO165_AD26"),
+       PINCTRL_PIN(DB8540_PIN_AD28, "GPIO166_AD28"),
+       PINCTRL_PIN(DB8540_PIN_AC28, "GPIO167_AC28"),
+       PINCTRL_PIN(DB8540_PIN_AC26, "GPIO168_AC26"),
+       /* Hole */
+       PINCTRL_PIN(DB8540_PIN_J3, "GPIO192_J3"),
+       PINCTRL_PIN(DB8540_PIN_H1, "GPIO193_H1"),
+       PINCTRL_PIN(DB8540_PIN_J2, "GPIO194_J2"),
+       PINCTRL_PIN(DB8540_PIN_H2, "GPIO195_H2"),
+       PINCTRL_PIN(DB8540_PIN_H3, "GPIO196_H3"),
+       PINCTRL_PIN(DB8540_PIN_H4, "GPIO197_H4"),
+       PINCTRL_PIN(DB8540_PIN_G2, "GPIO198_G2"),
+       PINCTRL_PIN(DB8540_PIN_G3, "GPIO199_G3"),
+       PINCTRL_PIN(DB8540_PIN_G4, "GPIO200_G4"),
+       PINCTRL_PIN(DB8540_PIN_F2, "GPIO201_F2"),
+       PINCTRL_PIN(DB8540_PIN_C6, "GPIO202_C6"),
+       PINCTRL_PIN(DB8540_PIN_B6, "GPIO203_B6"),
+       PINCTRL_PIN(DB8540_PIN_B7, "GPIO204_B7"),
+       PINCTRL_PIN(DB8540_PIN_A7, "GPIO205_A7"),
+       PINCTRL_PIN(DB8540_PIN_D7, "GPIO206_D7"),
+       PINCTRL_PIN(DB8540_PIN_D8, "GPIO207_D8"),
+       PINCTRL_PIN(DB8540_PIN_F3, "GPIO208_F3"),
+       PINCTRL_PIN(DB8540_PIN_E2, "GPIO209_E2"),
+       PINCTRL_PIN(DB8540_PIN_C7, "GPIO210_C7"),
+       PINCTRL_PIN(DB8540_PIN_B8, "GPIO211_B8"),
+       PINCTRL_PIN(DB8540_PIN_C10, "GPIO212_C10"),
+       PINCTRL_PIN(DB8540_PIN_C8, "GPIO213_C8"),
+       PINCTRL_PIN(DB8540_PIN_C9, "GPIO214_C9"),
+       /* Hole */
+       PINCTRL_PIN(DB8540_PIN_B9, "GPIO219_B9"),
+       PINCTRL_PIN(DB8540_PIN_A10, "GPIO220_A10"),
+       PINCTRL_PIN(DB8540_PIN_D9, "GPIO221_D9"),
+       PINCTRL_PIN(DB8540_PIN_B11, "GPIO222_B11"),
+       PINCTRL_PIN(DB8540_PIN_B10, "GPIO223_B10"),
+       PINCTRL_PIN(DB8540_PIN_E10, "GPIO224_E10"),
+       PINCTRL_PIN(DB8540_PIN_B12, "GPIO225_B12"),
+       PINCTRL_PIN(DB8540_PIN_D10, "GPIO226_D10"),
+       PINCTRL_PIN(DB8540_PIN_D11, "GPIO227_D11"),
+       PINCTRL_PIN(DB8540_PIN_AJ6, "GPIO228_AJ6"),
+       PINCTRL_PIN(DB8540_PIN_B13, "GPIO229_B13"),
+       PINCTRL_PIN(DB8540_PIN_C12, "GPIO230_C12"),
+       PINCTRL_PIN(DB8540_PIN_B14, "GPIO231_B14"),
+       PINCTRL_PIN(DB8540_PIN_E11, "GPIO232_E11"),
+       /* Hole */
+       PINCTRL_PIN(DB8540_PIN_D12, "GPIO256_D12"),
+       PINCTRL_PIN(DB8540_PIN_D15, "GPIO257_D15"),
+       PINCTRL_PIN(DB8540_PIN_C13, "GPIO258_C13"),
+       PINCTRL_PIN(DB8540_PIN_C14, "GPIO259_C14"),
+       PINCTRL_PIN(DB8540_PIN_C18, "GPIO260_C18"),
+       PINCTRL_PIN(DB8540_PIN_C16, "GPIO261_C16"),
+       PINCTRL_PIN(DB8540_PIN_B16, "GPIO262_B16"),
+       PINCTRL_PIN(DB8540_PIN_D18, "GPIO263_D18"),
+       PINCTRL_PIN(DB8540_PIN_C15, "GPIO264_C15"),
+       PINCTRL_PIN(DB8540_PIN_C17, "GPIO265_C17"),
+       PINCTRL_PIN(DB8540_PIN_B17, "GPIO266_B17"),
+       PINCTRL_PIN(DB8540_PIN_D17, "GPIO267_D17"),
+};
+
+#define DB8540_GPIO_RANGE(a, b, c) { .name = "db8540", .id = a, .base = b, \
+                       .pin_base = b, .npins = c }
+
+/*
+ * This matches the 32-pin gpio chips registered by the GPIO portion. This
+ * cannot be const since we assign the struct gpio_chip * pointer at runtime.
+ */
+static struct pinctrl_gpio_range nmk_db8540_ranges[] = {
+       DB8540_GPIO_RANGE(0, 0, 18),
+       DB8540_GPIO_RANGE(0, 22, 7),
+       DB8540_GPIO_RANGE(1, 33, 6),
+       DB8540_GPIO_RANGE(2, 64, 4),
+       DB8540_GPIO_RANGE(2, 70, 18),
+       DB8540_GPIO_RANGE(3, 116, 12),
+       DB8540_GPIO_RANGE(4, 128, 32),
+       DB8540_GPIO_RANGE(5, 160, 9),
+       DB8540_GPIO_RANGE(6, 192, 23),
+       DB8540_GPIO_RANGE(6, 219, 5),
+       DB8540_GPIO_RANGE(7, 224, 9),
+       DB8540_GPIO_RANGE(8, 256, 12),
+};
+
+/*
+ * Read the pin group names like this:
+ * u0_a_1    = first groups of pins for uart0 on alt function a
+ * i2c2_b_2  = second group of pins for i2c2 on alt function b
+ *
+ * The groups are arranged as sets per altfunction column, so we can
+ * mux in one group at a time by selecting the same altfunction for them
+ * all. When functions require pins on different altfunctions, you need
+ * to combine several groups.
+ */
+
+/* Altfunction A column */
+static const unsigned u0_a_1_pins[] = { DB8540_PIN_AH6, DB8540_PIN_AG7,
+                                       DB8540_PIN_AF2, DB8540_PIN_AD3 };
+static const unsigned u1rxtx_a_1_pins[] = { DB8540_PIN_AF6, DB8540_PIN_AG6 };
+static const unsigned u1ctsrts_a_1_pins[] = { DB8540_PIN_AD5, DB8540_PIN_AF7 };
+/* Image processor I2C line, this is driven by image processor firmware */
+static const unsigned ipi2c_a_1_pins[] = { DB8540_PIN_AG5, DB8540_PIN_AH5 };
+static const unsigned ipi2c_a_2_pins[] = { DB8540_PIN_AE4, DB8540_PIN_AD1 };
+/* MSP0 can only be on these pins, but TXD and RXD can be flipped */
+static const unsigned msp0txrx_a_1_pins[] = { DB8540_PIN_AD2, DB8540_PIN_AC3 };
+static const unsigned msp0tfstck_a_1_pins[] = { DB8540_PIN_AC2,
+       DB8540_PIN_AC4 };
+static const unsigned msp0rfsrck_a_1_pins[] = { DB8540_PIN_AH7,
+       DB8540_PIN_AE7 };
+/* Basic pins of the MMC/SD card 0 interface */
+static const unsigned mc0_a_1_pins[] = { DB8540_PIN_AH11, DB8540_PIN_AG11,
+       DB8540_PIN_AF11, DB8540_PIN_AH10, DB8540_PIN_AG10, DB8540_PIN_AF10};
+/* MSP1 can only be on these pins, but TXD and RXD can be flipped */
+static const unsigned msp1txrx_a_1_pins[] = { DB8540_PIN_AD4, DB8540_PIN_AG4 };
+static const unsigned msp1_a_1_pins[] = { DB8540_PIN_AF3, DB8540_PIN_AF5 };
+
+static const unsigned modobsclk_a_1_pins[] = { DB8540_PIN_AF9 };
+static const unsigned clkoutreq_a_1_pins[] = { DB8540_PIN_AE8 };
+/* LCD interface */
+static const unsigned lcdb_a_1_pins[] = { DB8540_PIN_M26, DB8540_PIN_M25,
+       DB8540_PIN_M27, DB8540_PIN_N25 };
+static const unsigned lcdvsi0_a_1_pins[] = { DB8540_PIN_AJ24 };
+static const unsigned lcdvsi1_a_1_pins[] = { DB8540_PIN_AE21 };
+static const unsigned lcd_d0_d7_a_1_pins[] = { DB8540_PIN_M28, DB8540_PIN_N26,
+       DB8540_PIN_M22, DB8540_PIN_N22, DB8540_PIN_N27, DB8540_PIN_N28,
+       DB8540_PIN_P22, DB8540_PIN_P28 };
+/* D8 thru D11 often used as TVOUT lines */
+static const unsigned lcd_d8_d11_a_1_pins[] = { DB8540_PIN_P26, DB8540_PIN_T22,
+       DB8540_PIN_R27, DB8540_PIN_P27 };
+static const unsigned lcd_d12_d23_a_1_pins[] = { DB8540_PIN_R26, DB8540_PIN_R25,
+       DB8540_PIN_U22, DB8540_PIN_T27, DB8540_PIN_AG22, DB8540_PIN_AF21,
+       DB8540_PIN_AF24, DB8540_PIN_AH22, DB8540_PIN_AJ23, DB8540_PIN_AH21,
+       DB8540_PIN_AG20, DB8540_PIN_AE23 };
+static const unsigned kp_a_1_pins[] = { DB8540_PIN_AH20, DB8540_PIN_AG19,
+       DB8540_PIN_AF22, DB8540_PIN_AJ21, DB8540_PIN_T25, DB8540_PIN_T26 };
+/* MC2 has 8 data lines and no direction control, so only for (e)MMC */
+static const unsigned mc2_a_1_pins[] = { DB8540_PIN_AC27, DB8540_PIN_AD27,
+       DB8540_PIN_AE28, DB8540_PIN_AG26, DB8540_PIN_AF25, DB8540_PIN_AE27,
+       DB8540_PIN_AF27, DB8540_PIN_AG28, DB8540_PIN_AF28, DB8540_PIN_AG25,
+       DB8540_PIN_AG24 };
+static const unsigned ssp1_a_1_pins[] = {  DB8540_PIN_AD25, DB8540_PIN_AH25,
+       DB8540_PIN_AF26, DB8540_PIN_AF23 };
+static const unsigned ssp0_a_1_pins[] = { DB8540_PIN_AG23, DB8540_PIN_AE25,
+       DB8540_PIN_AH24, DB8540_PIN_AJ25 };
+static const unsigned i2c0_a_1_pins[] = { DB8540_PIN_AG27, DB8540_PIN_AH23 };
+/*
+ * Image processor GPIO pins are named "ipgpio" and have their own
+ * numberspace
+ */
+static const unsigned ipgpio0_a_1_pins[] = { DB8540_PIN_AE26 };
+static const unsigned ipgpio1_a_1_pins[] = { DB8540_PIN_AE24 };
+/* modem i2s interface */
+static const unsigned modi2s_a_1_pins[] = { DB8540_PIN_AD26, DB8540_PIN_AD28,
+       DB8540_PIN_AC28, DB8540_PIN_AC26 };
+static const unsigned spi2_a_1_pins[] = { DB8540_PIN_AF20, DB8540_PIN_AG21,
+       DB8540_PIN_AH19, DB8540_PIN_AE19 };
+static const unsigned u2txrx_a_1_pins[] = { DB8540_PIN_AG18, DB8540_PIN_AH17 };
+static const unsigned u2ctsrts_a_1_pins[] = { DB8540_PIN_AF19,
+       DB8540_PIN_AF18 };
+static const unsigned modsmb_a_1_pins[] = { DB8540_PIN_AF17, DB8540_PIN_AE17 };
+static const unsigned msp2sck_a_1_pins[] = { DB8540_PIN_J3 };
+static const unsigned msp2txdtcktfs_a_1_pins[] = { DB8540_PIN_H1, DB8540_PIN_J2,
+       DB8540_PIN_H2 };
+static const unsigned msp2rxd_a_1_pins[] = { DB8540_PIN_H3 };
+static const unsigned mc4_a_1_pins[] = { DB8540_PIN_H4, DB8540_PIN_G2,
+       DB8540_PIN_G3, DB8540_PIN_G4, DB8540_PIN_F2, DB8540_PIN_C6,
+       DB8540_PIN_B6, DB8540_PIN_B7, DB8540_PIN_A7, DB8540_PIN_D7,
+       DB8540_PIN_D8 };
+static const unsigned mc1_a_1_pins[] = { DB8540_PIN_F3, DB8540_PIN_E2,
+       DB8540_PIN_C7, DB8540_PIN_B8, DB8540_PIN_C10, DB8540_PIN_C8,
+       DB8540_PIN_C9 };
+/* mc1_a_2_pins exclude MC1_FBCLK */
+static const unsigned mc1_a_2_pins[] = { DB8540_PIN_F3,        DB8540_PIN_C7,
+       DB8540_PIN_B8, DB8540_PIN_C10, DB8540_PIN_C8,
+       DB8540_PIN_C9 };
+static const unsigned hsir_a_1_pins[] = { DB8540_PIN_B9, DB8540_PIN_A10,
+       DB8540_PIN_D9 };
+static const unsigned hsit_a_1_pins[] = { DB8540_PIN_B11, DB8540_PIN_B10,
+       DB8540_PIN_E10, DB8540_PIN_B12, DB8540_PIN_D10 };
+static const unsigned hsit_a_2_pins[] = { DB8540_PIN_B11, DB8540_PIN_B10,
+       DB8540_PIN_E10, DB8540_PIN_B12 };
+static const unsigned clkout1_a_1_pins[] = { DB8540_PIN_D11 };
+static const unsigned clkout1_a_2_pins[] = { DB8540_PIN_B13 };
+static const unsigned clkout2_a_1_pins[] = { DB8540_PIN_AJ6 };
+static const unsigned clkout2_a_2_pins[] = { DB8540_PIN_C12 };
+static const unsigned msp4_a_1_pins[] = { DB8540_PIN_B14, DB8540_PIN_E11 };
+static const unsigned usb_a_1_pins[] = { DB8540_PIN_D12, DB8540_PIN_D15,
+       DB8540_PIN_C13, DB8540_PIN_C14, DB8540_PIN_C18, DB8540_PIN_C16,
+       DB8540_PIN_B16, DB8540_PIN_D18, DB8540_PIN_C15, DB8540_PIN_C17,
+       DB8540_PIN_B17, DB8540_PIN_D17 };
+/* Altfunction B colum */
+static const unsigned apetrig_b_1_pins[] = { DB8540_PIN_AH6, DB8540_PIN_AG7 };
+static const unsigned modtrig_b_1_pins[] = { DB8540_PIN_AF2, DB8540_PIN_AD3 };
+static const unsigned i2c4_b_1_pins[] = { DB8540_PIN_AF6, DB8540_PIN_AG6 };
+static const unsigned i2c1_b_1_pins[] = { DB8540_PIN_AD5, DB8540_PIN_AF7 };
+static const unsigned i2c2_b_1_pins[] = { DB8540_PIN_AG5, DB8540_PIN_AH5 };
+static const unsigned i2c2_b_2_pins[] = { DB8540_PIN_AE4, DB8540_PIN_AD1 };
+static const unsigned msp0txrx_b_1_pins[] = { DB8540_PIN_AD2, DB8540_PIN_AC3 };
+static const unsigned i2c1_b_2_pins[] = { DB8540_PIN_AH7, DB8540_PIN_AE7 };
+static const unsigned stmmod_b_1_pins[] = { DB8540_PIN_AH11, DB8540_PIN_AF11,
+       DB8540_PIN_AH10, DB8540_PIN_AG10, DB8540_PIN_AF10 };
+static const unsigned moduartstmmux_b_1_pins[] = { DB8540_PIN_AG11 };
+static const unsigned msp1txrx_b_1_pins[] = { DB8540_PIN_AD4, DB8540_PIN_AG4 };
+static const unsigned kp_b_1_pins[] = { DB8540_PIN_AJ24, DB8540_PIN_AE21,
+       DB8540_PIN_M26, DB8540_PIN_M25, DB8540_PIN_M27, DB8540_PIN_N25,
+       DB8540_PIN_M28, DB8540_PIN_N26, DB8540_PIN_M22, DB8540_PIN_N22,
+       DB8540_PIN_N27, DB8540_PIN_N28, DB8540_PIN_P22, DB8540_PIN_P28,
+       DB8540_PIN_P26, DB8540_PIN_T22, DB8540_PIN_R27, DB8540_PIN_P27,
+       DB8540_PIN_R26, DB8540_PIN_R25 };
+static const unsigned u2txrx_b_1_pins[] = { DB8540_PIN_U22, DB8540_PIN_T27 };
+static const unsigned sm_b_1_pins[] = { DB8540_PIN_AG22, DB8540_PIN_AF21,
+       DB8540_PIN_AF24, DB8540_PIN_AH22, DB8540_PIN_AJ23, DB8540_PIN_AH21,
+       DB8540_PIN_AG20, DB8540_PIN_AE23, DB8540_PIN_AH20, DB8540_PIN_AF22,
+       DB8540_PIN_AJ21, DB8540_PIN_AC27, DB8540_PIN_AD27, DB8540_PIN_AE28,
+       DB8540_PIN_AG26, DB8540_PIN_AF25, DB8540_PIN_AE27, DB8540_PIN_AF27,
+       DB8540_PIN_AG28, DB8540_PIN_AF28, DB8540_PIN_AG25, DB8540_PIN_AG24,
+       DB8540_PIN_AD25 };
+static const unsigned smcs0_b_1_pins[] = { DB8540_PIN_AG19 };
+static const unsigned smcs1_b_1_pins[] = { DB8540_PIN_AE26 };
+static const unsigned ipgpio7_b_1_pins[] = { DB8540_PIN_AH25 };
+static const unsigned ipgpio2_b_1_pins[] = { DB8540_PIN_AF26 };
+static const unsigned ipgpio3_b_1_pins[] = { DB8540_PIN_AF23 };
+static const unsigned i2c6_b_1_pins[] = { DB8540_PIN_AG23, DB8540_PIN_AE25 };
+static const unsigned i2c5_b_1_pins[] = { DB8540_PIN_AH24, DB8540_PIN_AJ25 };
+static const unsigned u3txrx_b_1_pins[] = { DB8540_PIN_AF20, DB8540_PIN_AG21 };
+static const unsigned u3ctsrts_b_1_pins[] = { DB8540_PIN_AH19,
+       DB8540_PIN_AE19 };
+static const unsigned i2c5_b_2_pins[] = { DB8540_PIN_AG18, DB8540_PIN_AH17 };
+static const unsigned i2c4_b_2_pins[] = { DB8540_PIN_AF19, DB8540_PIN_AF18 };
+static const unsigned u4txrx_b_1_pins[] = { DB8540_PIN_AE18, DB8540_PIN_AG17 };
+static const unsigned u4ctsrts_b_1_pins[] = { DB8540_PIN_AF17,
+       DB8540_PIN_AE17 };
+static const unsigned ddrtrig_b_1_pins[] = { DB8540_PIN_J3 };
+static const unsigned msp4_b_1_pins[] = { DB8540_PIN_H3 };
+static const unsigned pwl_b_1_pins[] = { DB8540_PIN_C6 };
+static const unsigned spi1_b_1_pins[] = { DB8540_PIN_E2, DB8540_PIN_C10,
+       DB8540_PIN_C8, DB8540_PIN_C9 };
+static const unsigned mc3_b_1_pins[] = { DB8540_PIN_B9, DB8540_PIN_A10,
+       DB8540_PIN_D9, DB8540_PIN_B11, DB8540_PIN_B10, DB8540_PIN_E10,
+       DB8540_PIN_B12 };
+static const unsigned pwl_b_2_pins[] = { DB8540_PIN_D10 };
+static const unsigned pwl_b_3_pins[] = { DB8540_PIN_B13 };
+static const unsigned pwl_b_4_pins[] = { DB8540_PIN_C12 };
+static const unsigned u2txrx_b_2_pins[] = { DB8540_PIN_B17, DB8540_PIN_D17 };
+
+/* Altfunction C column */
+static const unsigned ipgpio6_c_1_pins[] = { DB8540_PIN_AG6 };
+static const unsigned ipgpio0_c_1_pins[] = { DB8540_PIN_AD5 };
+static const unsigned ipgpio1_c_1_pins[] = { DB8540_PIN_AF7 };
+static const unsigned ipgpio3_c_1_pins[] = { DB8540_PIN_AE4 };
+static const unsigned ipgpio2_c_1_pins[] = { DB8540_PIN_AD1 };
+static const unsigned u0_c_1_pins[] = { DB8540_PIN_AD4, DB8540_PIN_AF3,
+       DB8540_PIN_AF5, DB8540_PIN_AG4 };
+static const unsigned smcleale_c_1_pins[] = { DB8540_PIN_AJ24,
+       DB8540_PIN_AE21 };
+static const unsigned ipgpio4_c_1_pins[] = { DB8540_PIN_M26 };
+static const unsigned ipgpio5_c_1_pins[] = { DB8540_PIN_M25 };
+static const unsigned ipgpio6_c_2_pins[] = { DB8540_PIN_M27 };
+static const unsigned ipgpio7_c_1_pins[] = { DB8540_PIN_N25 };
+static const unsigned stmape_c_1_pins[] = { DB8540_PIN_M28, DB8540_PIN_N26,
+       DB8540_PIN_M22, DB8540_PIN_N22, DB8540_PIN_N27 };
+static const unsigned u2rxtx_c_1_pins[] = { DB8540_PIN_N28, DB8540_PIN_P22 };
+static const unsigned modobsresout_c_1_pins[] = { DB8540_PIN_P28 };
+static const unsigned ipgpio2_c_2_pins[] = { DB8540_PIN_P26 };
+static const unsigned ipgpio3_c_2_pins[] = { DB8540_PIN_T22 };
+static const unsigned ipgpio4_c_2_pins[] = { DB8540_PIN_R27 };
+static const unsigned ipgpio5_c_2_pins[] = { DB8540_PIN_P27 };
+static const unsigned modaccgpo_c_1_pins[] = { DB8540_PIN_R26, DB8540_PIN_R25,
+       DB8540_PIN_U22 };
+static const unsigned modobspwrrst_c_1_pins[] = { DB8540_PIN_T27 };
+static const unsigned mc5_c_1_pins[] = { DB8540_PIN_AG22, DB8540_PIN_AF21,
+       DB8540_PIN_AF24, DB8540_PIN_AH22, DB8540_PIN_AJ23, DB8540_PIN_AH21,
+       DB8540_PIN_AG20, DB8540_PIN_AE23, DB8540_PIN_AH20, DB8540_PIN_AF22,
+       DB8540_PIN_AJ21};
+static const unsigned smps0_c_1_pins[] = { DB8540_PIN_AG19 };
+static const unsigned moduart1_c_1_pins[] = { DB8540_PIN_T25, DB8540_PIN_T26 };
+static const unsigned mc2rstn_c_1_pins[] = { DB8540_PIN_AE28 };
+static const unsigned i2c5_c_1_pins[] = { DB8540_PIN_AG28, DB8540_PIN_AF28 };
+static const unsigned ipgpio0_c_2_pins[] = { DB8540_PIN_AG25 };
+static const unsigned ipgpio1_c_2_pins[] = { DB8540_PIN_AG24 };
+static const unsigned kp_c_1_pins[] = { DB8540_PIN_AD25, DB8540_PIN_AH25,
+       DB8540_PIN_AF26, DB8540_PIN_AF23 };
+static const unsigned modrf_c_1_pins[] = { DB8540_PIN_AG23, DB8540_PIN_AE25,
+       DB8540_PIN_AH24 };
+static const unsigned smps1_c_1_pins[] = { DB8540_PIN_AE26 };
+static const unsigned i2c5_c_2_pins[] = { DB8540_PIN_AH19, DB8540_PIN_AE19 };
+static const unsigned u4ctsrts_c_1_pins[] = { DB8540_PIN_AG18,
+       DB8540_PIN_AH17 };
+static const unsigned u3rxtx_c_1_pins[] = { DB8540_PIN_AF19, DB8540_PIN_AF18 };
+static const unsigned msp4_c_1_pins[] = { DB8540_PIN_J3 };
+static const unsigned mc4rstn_c_1_pins[] = { DB8540_PIN_C6 };
+static const unsigned spi0_c_1_pins[] = { DB8540_PIN_A10, DB8540_PIN_B10,
+       DB8540_PIN_E10, DB8540_PIN_B12 };
+static const unsigned i2c3_c_1_pins[] = { DB8540_PIN_B13, DB8540_PIN_C12 };
+
+/* Other alt C1 column */
+static const unsigned spi3_oc1_1_pins[] = { DB8540_PIN_AG5, DB8540_PIN_AH5,
+       DB8540_PIN_AE4, DB8540_PIN_AD1 };
+static const unsigned stmape_oc1_1_pins[] = { DB8540_PIN_AH11, DB8540_PIN_AF11,
+       DB8540_PIN_AH10, DB8540_PIN_AG10, DB8540_PIN_AF10 };
+static const unsigned u2_oc1_1_pins[] = { DB8540_PIN_AG11 };
+static const unsigned remap0_oc1_1_pins[] = { DB8540_PIN_AJ24 };
+static const unsigned remap1_oc1_1_pins[] = { DB8540_PIN_AE21 };
+static const unsigned modobsrefclk_oc1_1_pins[] = { DB8540_PIN_M26 };
+static const unsigned modobspwrctrl_oc1_1_pins[] = { DB8540_PIN_M25 };
+static const unsigned modobsclkout_oc1_1_pins[] = { DB8540_PIN_M27 };
+static const unsigned moduart1_oc1_1_pins[] = { DB8540_PIN_N25 };
+static const unsigned modprcmudbg_oc1_1_pins[] = { DB8540_PIN_M28,
+       DB8540_PIN_N26, DB8540_PIN_M22, DB8540_PIN_N22, DB8540_PIN_N27,
+       DB8540_PIN_P22, DB8540_PIN_P28, DB8540_PIN_P26, DB8540_PIN_T22,
+       DB8540_PIN_R26, DB8540_PIN_R25, DB8540_PIN_U22, DB8540_PIN_T27,
+       DB8540_PIN_AH20, DB8540_PIN_AG19, DB8540_PIN_AF22, DB8540_PIN_AJ21,
+       DB8540_PIN_T25};
+static const unsigned modobsresout_oc1_1_pins[] = { DB8540_PIN_N28 };
+static const unsigned modaccgpo_oc1_1_pins[] = { DB8540_PIN_R27, DB8540_PIN_P27,
+       DB8540_PIN_T26 };
+static const unsigned kp_oc1_1_pins[] = { DB8540_PIN_AG22, DB8540_PIN_AF21,
+       DB8540_PIN_AF24, DB8540_PIN_AH22, DB8540_PIN_AJ23, DB8540_PIN_AH21,
+       DB8540_PIN_AG20, DB8540_PIN_AE23 };
+static const unsigned modxmip_oc1_1_pins[] = { DB8540_PIN_AD25, DB8540_PIN_AH25,
+       DB8540_PIN_AG23, DB8540_PIN_AE25 };
+static const unsigned i2c6_oc1_1_pins[] = { DB8540_PIN_AE26, DB8540_PIN_AE24 };
+static const unsigned u2txrx_oc1_1_pins[] = { DB8540_PIN_B7, DB8540_PIN_A7 };
+static const unsigned u2ctsrts_oc1_1_pins[] = { DB8540_PIN_D7, DB8540_PIN_D8 };
+
+/* Other alt C2 column */
+static const unsigned sbag_oc2_1_pins[] = { DB8540_PIN_AH11, DB8540_PIN_AG11,
+       DB8540_PIN_AF11, DB8540_PIN_AH10, DB8540_PIN_AG10, DB8540_PIN_AF10 };
+static const unsigned hxclk_oc2_1_pins[] = { DB8540_PIN_M25 };
+static const unsigned modaccuart_oc2_1_pins[] = { DB8540_PIN_N25 };
+static const unsigned stmmod_oc2_1_pins[] = { DB8540_PIN_M28, DB8540_PIN_N26,
+       DB8540_PIN_M22, DB8540_PIN_N22, DB8540_PIN_N27 };
+static const unsigned moduartstmmux_oc2_1_pins[] = { DB8540_PIN_N28 };
+static const unsigned hxgpio_oc2_1_pins[] = { DB8540_PIN_P22, DB8540_PIN_P28,
+       DB8540_PIN_P26, DB8540_PIN_T22, DB8540_PIN_R27, DB8540_PIN_P27,
+       DB8540_PIN_R26, DB8540_PIN_R25 };
+static const unsigned sbag_oc2_2_pins[] = { DB8540_PIN_U22, DB8540_PIN_T27,
+       DB8540_PIN_AG22, DB8540_PIN_AF21, DB8540_PIN_AF24, DB8540_PIN_AH22 };
+static const unsigned modobsservice_oc2_1_pins[] = { DB8540_PIN_AJ23 };
+static const unsigned moduart0_oc2_1_pins[] = { DB8540_PIN_AG20,
+       DB8540_PIN_AE23 };
+static const unsigned stmape_oc2_1_pins[] = { DB8540_PIN_AH20, DB8540_PIN_AG19,
+       DB8540_PIN_AF22, DB8540_PIN_AJ21, DB8540_PIN_T25 };
+static const unsigned u2_oc2_1_pins[] = { DB8540_PIN_T26, DB8540_PIN_AH21 };
+static const unsigned modxmip_oc2_1_pins[] = { DB8540_PIN_AE26,
+       DB8540_PIN_AE24 };
+
+/* Other alt C3 column */
+static const unsigned modaccgpo_oc3_1_pins[] = { DB8540_PIN_AG11 };
+static const unsigned tpui_oc3_1_pins[] = { DB8540_PIN_M26, DB8540_PIN_M25,
+       DB8540_PIN_M27, DB8540_PIN_N25, DB8540_PIN_M28, DB8540_PIN_N26,
+       DB8540_PIN_M22, DB8540_PIN_N22, DB8540_PIN_N27, DB8540_PIN_N28,
+       DB8540_PIN_P22, DB8540_PIN_P28, DB8540_PIN_P26, DB8540_PIN_T22,
+       DB8540_PIN_R27, DB8540_PIN_P27, DB8540_PIN_R26, DB8540_PIN_R25,
+       DB8540_PIN_U22, DB8540_PIN_T27, DB8540_PIN_AG22, DB8540_PIN_AF21,
+       DB8540_PIN_AF24, DB8540_PIN_AH22, DB8540_PIN_AJ23, DB8540_PIN_AH21,
+       DB8540_PIN_AG20, DB8540_PIN_AE23, DB8540_PIN_AH20, DB8540_PIN_AG19,
+       DB8540_PIN_AF22, DB8540_PIN_AJ21, DB8540_PIN_T25, DB8540_PIN_T26 };
+
+/* Other alt C4 column */
+static const unsigned hwobs_oc4_1_pins[] = { DB8540_PIN_M26, DB8540_PIN_M25,
+       DB8540_PIN_M27, DB8540_PIN_N25, DB8540_PIN_M28, DB8540_PIN_N26,
+       DB8540_PIN_M22, DB8540_PIN_N22, DB8540_PIN_N27, DB8540_PIN_N28,
+       DB8540_PIN_P22, DB8540_PIN_P28, DB8540_PIN_P26, DB8540_PIN_T22,
+       DB8540_PIN_R27, DB8540_PIN_P27, DB8540_PIN_R26, DB8540_PIN_R25 };
+static const unsigned moduart1txrx_oc4_1_pins[] = { DB8540_PIN_U22,
+       DB8540_PIN_T27 };
+static const unsigned moduart1rtscts_oc4_1_pins[] = { DB8540_PIN_AG22,
+       DB8540_PIN_AF21 };
+static const unsigned modaccuarttxrx_oc4_1_pins[] = { DB8540_PIN_AF24,
+       DB8540_PIN_AH22 };
+static const unsigned modaccuartrtscts_oc4_1_pins[] = { DB8540_PIN_AJ23,
+       DB8540_PIN_AH21 };
+static const unsigned stmmod_oc4_1_pins[] = { DB8540_PIN_AH20, DB8540_PIN_AG19,
+       DB8540_PIN_AF22, DB8540_PIN_AJ21, DB8540_PIN_T25 };
+static const unsigned moduartstmmux_oc4_1_pins[] = { DB8540_PIN_T26 };
+
+#define DB8540_PIN_GROUP(a, b) { .name = #a, .pins = a##_pins,         \
+                       .npins = ARRAY_SIZE(a##_pins), .altsetting = b }
+
+static const struct nmk_pingroup nmk_db8540_groups[] = {
+       /* Altfunction A column */
+       DB8540_PIN_GROUP(u0_a_1, NMK_GPIO_ALT_A),
+       DB8540_PIN_GROUP(u1rxtx_a_1, NMK_GPIO_ALT_A),
+       DB8540_PIN_GROUP(u1ctsrts_a_1, NMK_GPIO_ALT_A),
+       DB8540_PIN_GROUP(ipi2c_a_1, NMK_GPIO_ALT_A),
+       DB8540_PIN_GROUP(ipi2c_a_2, NMK_GPIO_ALT_A),
+       DB8540_PIN_GROUP(msp0txrx_a_1, NMK_GPIO_ALT_A),
+       DB8540_PIN_GROUP(msp0tfstck_a_1, NMK_GPIO_ALT_A),
+       DB8540_PIN_GROUP(msp0rfsrck_a_1, NMK_GPIO_ALT_A),
+       DB8540_PIN_GROUP(mc0_a_1, NMK_GPIO_ALT_A),
+       DB8540_PIN_GROUP(msp1txrx_a_1, NMK_GPIO_ALT_A),
+       DB8540_PIN_GROUP(msp1_a_1, NMK_GPIO_ALT_A),
+       DB8540_PIN_GROUP(modobsclk_a_1, NMK_GPIO_ALT_A),
+       DB8540_PIN_GROUP(clkoutreq_a_1, NMK_GPIO_ALT_A),
+       DB8540_PIN_GROUP(lcdb_a_1, NMK_GPIO_ALT_A),
+       DB8540_PIN_GROUP(lcdvsi0_a_1, NMK_GPIO_ALT_A),
+       DB8540_PIN_GROUP(lcdvsi1_a_1, NMK_GPIO_ALT_A),
+       DB8540_PIN_GROUP(lcd_d0_d7_a_1, NMK_GPIO_ALT_A),
+       DB8540_PIN_GROUP(lcd_d8_d11_a_1, NMK_GPIO_ALT_A),
+       DB8540_PIN_GROUP(lcd_d12_d23_a_1, NMK_GPIO_ALT_A),
+       DB8540_PIN_GROUP(kp_a_1, NMK_GPIO_ALT_A),
+       DB8540_PIN_GROUP(mc2_a_1, NMK_GPIO_ALT_A),
+       DB8540_PIN_GROUP(ssp1_a_1, NMK_GPIO_ALT_A),
+       DB8540_PIN_GROUP(ssp0_a_1, NMK_GPIO_ALT_A),
+       DB8540_PIN_GROUP(i2c0_a_1, NMK_GPIO_ALT_A),
+       DB8540_PIN_GROUP(ipgpio0_a_1, NMK_GPIO_ALT_A),
+       DB8540_PIN_GROUP(ipgpio1_a_1, NMK_GPIO_ALT_A),
+       DB8540_PIN_GROUP(modi2s_a_1, NMK_GPIO_ALT_A),
+       DB8540_PIN_GROUP(spi2_a_1, NMK_GPIO_ALT_A),
+       DB8540_PIN_GROUP(u2txrx_a_1, NMK_GPIO_ALT_A),
+       DB8540_PIN_GROUP(u2ctsrts_a_1, NMK_GPIO_ALT_A),
+       DB8540_PIN_GROUP(modsmb_a_1, NMK_GPIO_ALT_A),
+       DB8540_PIN_GROUP(msp2sck_a_1, NMK_GPIO_ALT_A),
+       DB8540_PIN_GROUP(msp2txdtcktfs_a_1, NMK_GPIO_ALT_A),
+       DB8540_PIN_GROUP(msp2rxd_a_1, NMK_GPIO_ALT_A),
+       DB8540_PIN_GROUP(mc4_a_1, NMK_GPIO_ALT_A),
+       DB8540_PIN_GROUP(mc1_a_1, NMK_GPIO_ALT_A),
+       DB8540_PIN_GROUP(hsir_a_1, NMK_GPIO_ALT_A),
+       DB8540_PIN_GROUP(hsit_a_1, NMK_GPIO_ALT_A),
+       DB8540_PIN_GROUP(hsit_a_2, NMK_GPIO_ALT_A),
+       DB8540_PIN_GROUP(clkout1_a_1, NMK_GPIO_ALT_A),
+       DB8540_PIN_GROUP(clkout1_a_2, NMK_GPIO_ALT_A),
+       DB8540_PIN_GROUP(clkout2_a_1, NMK_GPIO_ALT_A),
+       DB8540_PIN_GROUP(clkout2_a_2, NMK_GPIO_ALT_A),
+       DB8540_PIN_GROUP(msp4_a_1, NMK_GPIO_ALT_A),
+       DB8540_PIN_GROUP(usb_a_1, NMK_GPIO_ALT_A),
+       /* Altfunction B column */
+       DB8540_PIN_GROUP(apetrig_b_1, NMK_GPIO_ALT_B),
+       DB8540_PIN_GROUP(modtrig_b_1, NMK_GPIO_ALT_B),
+       DB8540_PIN_GROUP(i2c4_b_1, NMK_GPIO_ALT_B),
+       DB8540_PIN_GROUP(i2c1_b_1, NMK_GPIO_ALT_B),
+       DB8540_PIN_GROUP(i2c2_b_1, NMK_GPIO_ALT_B),
+       DB8540_PIN_GROUP(i2c2_b_2, NMK_GPIO_ALT_B),
+       DB8540_PIN_GROUP(msp0txrx_b_1, NMK_GPIO_ALT_B),
+       DB8540_PIN_GROUP(i2c1_b_2, NMK_GPIO_ALT_B),
+       DB8540_PIN_GROUP(stmmod_b_1, NMK_GPIO_ALT_B),
+       DB8540_PIN_GROUP(moduartstmmux_b_1, NMK_GPIO_ALT_B),
+       DB8540_PIN_GROUP(msp1txrx_b_1, NMK_GPIO_ALT_B),
+       DB8540_PIN_GROUP(kp_b_1, NMK_GPIO_ALT_B),
+       DB8540_PIN_GROUP(u2txrx_b_1, NMK_GPIO_ALT_B),
+       DB8540_PIN_GROUP(sm_b_1, NMK_GPIO_ALT_B),
+       DB8540_PIN_GROUP(smcs0_b_1, NMK_GPIO_ALT_B),
+       DB8540_PIN_GROUP(smcs1_b_1, NMK_GPIO_ALT_B),
+       DB8540_PIN_GROUP(ipgpio7_b_1, NMK_GPIO_ALT_B),
+       DB8540_PIN_GROUP(ipgpio2_b_1, NMK_GPIO_ALT_B),
+       DB8540_PIN_GROUP(ipgpio3_b_1, NMK_GPIO_ALT_B),
+       DB8540_PIN_GROUP(i2c6_b_1, NMK_GPIO_ALT_B),
+       DB8540_PIN_GROUP(i2c5_b_1, NMK_GPIO_ALT_B),
+       DB8540_PIN_GROUP(u3txrx_b_1, NMK_GPIO_ALT_B),
+       DB8540_PIN_GROUP(u3ctsrts_b_1, NMK_GPIO_ALT_B),
+       DB8540_PIN_GROUP(i2c5_b_2, NMK_GPIO_ALT_B),
+       DB8540_PIN_GROUP(i2c4_b_2, NMK_GPIO_ALT_B),
+       DB8540_PIN_GROUP(u4txrx_b_1, NMK_GPIO_ALT_B),
+       DB8540_PIN_GROUP(u4ctsrts_b_1, NMK_GPIO_ALT_B),
+       DB8540_PIN_GROUP(ddrtrig_b_1, NMK_GPIO_ALT_B),
+       DB8540_PIN_GROUP(msp4_b_1, NMK_GPIO_ALT_B),
+       DB8540_PIN_GROUP(pwl_b_1, NMK_GPIO_ALT_B),
+       DB8540_PIN_GROUP(spi1_b_1, NMK_GPIO_ALT_B),
+       DB8540_PIN_GROUP(mc3_b_1, NMK_GPIO_ALT_B),
+       DB8540_PIN_GROUP(pwl_b_2, NMK_GPIO_ALT_B),
+       DB8540_PIN_GROUP(pwl_b_3, NMK_GPIO_ALT_B),
+       DB8540_PIN_GROUP(pwl_b_4, NMK_GPIO_ALT_B),
+       DB8540_PIN_GROUP(u2txrx_b_2, NMK_GPIO_ALT_B),
+       /* Altfunction C column */
+       DB8540_PIN_GROUP(ipgpio6_c_1, NMK_GPIO_ALT_C),
+       DB8540_PIN_GROUP(ipgpio0_c_1, NMK_GPIO_ALT_C),
+       DB8540_PIN_GROUP(ipgpio1_c_1, NMK_GPIO_ALT_C),
+       DB8540_PIN_GROUP(ipgpio3_c_1, NMK_GPIO_ALT_C),
+       DB8540_PIN_GROUP(ipgpio2_c_1, NMK_GPIO_ALT_C),
+       DB8540_PIN_GROUP(u0_c_1, NMK_GPIO_ALT_C),
+       DB8540_PIN_GROUP(smcleale_c_1, NMK_GPIO_ALT_C),
+       DB8540_PIN_GROUP(ipgpio4_c_1, NMK_GPIO_ALT_C),
+       DB8540_PIN_GROUP(ipgpio5_c_1, NMK_GPIO_ALT_C),
+       DB8540_PIN_GROUP(ipgpio6_c_2, NMK_GPIO_ALT_C),
+       DB8540_PIN_GROUP(ipgpio7_c_1, NMK_GPIO_ALT_C),
+       DB8540_PIN_GROUP(stmape_c_1, NMK_GPIO_ALT_C),
+       DB8540_PIN_GROUP(u2rxtx_c_1, NMK_GPIO_ALT_C),
+       DB8540_PIN_GROUP(modobsresout_c_1, NMK_GPIO_ALT_C),
+       DB8540_PIN_GROUP(ipgpio2_c_2, NMK_GPIO_ALT_C),
+       DB8540_PIN_GROUP(ipgpio3_c_2, NMK_GPIO_ALT_C),
+       DB8540_PIN_GROUP(ipgpio4_c_2, NMK_GPIO_ALT_C),
+       DB8540_PIN_GROUP(ipgpio5_c_2, NMK_GPIO_ALT_C),
+       DB8540_PIN_GROUP(modaccgpo_c_1, NMK_GPIO_ALT_C),
+       DB8540_PIN_GROUP(modobspwrrst_c_1, NMK_GPIO_ALT_C),
+       DB8540_PIN_GROUP(mc5_c_1, NMK_GPIO_ALT_C),
+       DB8540_PIN_GROUP(smps0_c_1, NMK_GPIO_ALT_C),
+       DB8540_PIN_GROUP(moduart1_c_1, NMK_GPIO_ALT_C),
+       DB8540_PIN_GROUP(mc2rstn_c_1, NMK_GPIO_ALT_C),
+       DB8540_PIN_GROUP(i2c5_c_1, NMK_GPIO_ALT_C),
+       DB8540_PIN_GROUP(ipgpio0_c_2, NMK_GPIO_ALT_C),
+       DB8540_PIN_GROUP(ipgpio1_c_2, NMK_GPIO_ALT_C),
+       DB8540_PIN_GROUP(kp_c_1, NMK_GPIO_ALT_C),
+       DB8540_PIN_GROUP(modrf_c_1, NMK_GPIO_ALT_C),
+       DB8540_PIN_GROUP(smps1_c_1, NMK_GPIO_ALT_C),
+       DB8540_PIN_GROUP(i2c5_c_2, NMK_GPIO_ALT_C),
+       DB8540_PIN_GROUP(u4ctsrts_c_1, NMK_GPIO_ALT_C),
+       DB8540_PIN_GROUP(u3rxtx_c_1, NMK_GPIO_ALT_C),
+       DB8540_PIN_GROUP(msp4_c_1, NMK_GPIO_ALT_C),
+       DB8540_PIN_GROUP(mc4rstn_c_1, NMK_GPIO_ALT_C),
+       DB8540_PIN_GROUP(spi0_c_1, NMK_GPIO_ALT_C),
+       DB8540_PIN_GROUP(i2c3_c_1, NMK_GPIO_ALT_C),
+
+       /* Other alt C1 column */
+       DB8540_PIN_GROUP(spi3_oc1_1, NMK_GPIO_ALT_C1),
+       DB8540_PIN_GROUP(stmape_oc1_1, NMK_GPIO_ALT_C1),
+       DB8540_PIN_GROUP(u2_oc1_1, NMK_GPIO_ALT_C1),
+       DB8540_PIN_GROUP(remap0_oc1_1, NMK_GPIO_ALT_C1),
+       DB8540_PIN_GROUP(remap1_oc1_1, NMK_GPIO_ALT_C1),
+       DB8540_PIN_GROUP(modobsrefclk_oc1_1, NMK_GPIO_ALT_C1),
+       DB8540_PIN_GROUP(modobspwrctrl_oc1_1, NMK_GPIO_ALT_C1),
+       DB8540_PIN_GROUP(modobsclkout_oc1_1, NMK_GPIO_ALT_C1),
+       DB8540_PIN_GROUP(moduart1_oc1_1, NMK_GPIO_ALT_C1),
+       DB8540_PIN_GROUP(modprcmudbg_oc1_1, NMK_GPIO_ALT_C1),
+       DB8540_PIN_GROUP(modobsresout_oc1_1, NMK_GPIO_ALT_C1),
+       DB8540_PIN_GROUP(modaccgpo_oc1_1, NMK_GPIO_ALT_C1),
+       DB8540_PIN_GROUP(kp_oc1_1, NMK_GPIO_ALT_C1),
+       DB8540_PIN_GROUP(modxmip_oc1_1, NMK_GPIO_ALT_C1),
+       DB8540_PIN_GROUP(i2c6_oc1_1, NMK_GPIO_ALT_C1),
+       DB8540_PIN_GROUP(u2txrx_oc1_1, NMK_GPIO_ALT_C1),
+       DB8540_PIN_GROUP(u2ctsrts_oc1_1, NMK_GPIO_ALT_C1),
+
+       /* Other alt C2 column */
+       DB8540_PIN_GROUP(sbag_oc2_1, NMK_GPIO_ALT_C2),
+       DB8540_PIN_GROUP(hxclk_oc2_1, NMK_GPIO_ALT_C2),
+       DB8540_PIN_GROUP(modaccuart_oc2_1, NMK_GPIO_ALT_C2),
+       DB8540_PIN_GROUP(stmmod_oc2_1, NMK_GPIO_ALT_C2),
+       DB8540_PIN_GROUP(moduartstmmux_oc2_1, NMK_GPIO_ALT_C2),
+       DB8540_PIN_GROUP(hxgpio_oc2_1, NMK_GPIO_ALT_C2),
+       DB8540_PIN_GROUP(sbag_oc2_2, NMK_GPIO_ALT_C2),
+       DB8540_PIN_GROUP(modobsservice_oc2_1, NMK_GPIO_ALT_C2),
+       DB8540_PIN_GROUP(moduart0_oc2_1, NMK_GPIO_ALT_C2),
+       DB8540_PIN_GROUP(stmape_oc2_1, NMK_GPIO_ALT_C2),
+       DB8540_PIN_GROUP(u2_oc2_1, NMK_GPIO_ALT_C2),
+       DB8540_PIN_GROUP(modxmip_oc2_1, NMK_GPIO_ALT_C2),
+
+       /* Other alt C3 column */
+       DB8540_PIN_GROUP(modaccgpo_oc3_1, NMK_GPIO_ALT_C3),
+       DB8540_PIN_GROUP(tpui_oc3_1, NMK_GPIO_ALT_C3),
+
+       /* Other alt C4 column */
+       DB8540_PIN_GROUP(hwobs_oc4_1, NMK_GPIO_ALT_C4),
+       DB8540_PIN_GROUP(moduart1txrx_oc4_1, NMK_GPIO_ALT_C4),
+       DB8540_PIN_GROUP(moduart1rtscts_oc4_1, NMK_GPIO_ALT_C4),
+       DB8540_PIN_GROUP(modaccuarttxrx_oc4_1, NMK_GPIO_ALT_C4),
+       DB8540_PIN_GROUP(modaccuartrtscts_oc4_1, NMK_GPIO_ALT_C4),
+       DB8540_PIN_GROUP(stmmod_oc4_1, NMK_GPIO_ALT_C4),
+       DB8540_PIN_GROUP(moduartstmmux_oc4_1, NMK_GPIO_ALT_C4),
+
+};
+
+/* We use this macro to define the groups applicable to a function */
+#define DB8540_FUNC_GROUPS(a, b...)       \
+static const char * const a##_groups[] = { b };
+
+DB8540_FUNC_GROUPS(apetrig, "apetrig_b_1");
+DB8540_FUNC_GROUPS(clkout, "clkoutreq_a_1", "clkout1_a_1", "clkout1_a_2",
+               "clkout2_a_1", "clkout2_a_2");
+DB8540_FUNC_GROUPS(ddrtrig, "ddrtrig_b_1");
+DB8540_FUNC_GROUPS(hsi, "hsir_a_1", "hsit_a_1", "hsit_a_2");
+DB8540_FUNC_GROUPS(hwobs, "hwobs_oc4_1");
+DB8540_FUNC_GROUPS(hx, "hxclk_oc2_1", "hxgpio_oc2_1");
+DB8540_FUNC_GROUPS(i2c0, "i2c0_a_1");
+DB8540_FUNC_GROUPS(i2c1, "i2c1_b_1", "i2c1_b_2");
+DB8540_FUNC_GROUPS(i2c2, "i2c2_b_1", "i2c2_b_2");
+DB8540_FUNC_GROUPS(i2c3, "i2c3_c_1", "i2c4_b_1");
+DB8540_FUNC_GROUPS(i2c4, "i2c4_b_2");
+DB8540_FUNC_GROUPS(i2c5, "i2c5_b_1", "i2c5_b_2", "i2c5_c_1", "i2c5_c_2");
+DB8540_FUNC_GROUPS(i2c6, "i2c6_b_1", "i2c6_oc1_1");
+/* The image processor has 8 GPIO pins that can be muxed out */
+DB8540_FUNC_GROUPS(ipgpio, "ipgpio0_a_1", "ipgpio0_c_1", "ipgpio0_c_2",
+               "ipgpio1_a_1", "ipgpio1_c_1", "ipgpio1_c_2",
+               "ipgpio2_b_1", "ipgpio2_c_1", "ipgpio2_c_2",
+               "ipgpio3_b_1", "ipgpio3_c_1", "ipgpio3_c_2",
+               "ipgpio4_c_1", "ipgpio4_c_2",
+               "ipgpio5_c_1", "ipgpio5_c_2",
+               "ipgpio6_c_1", "ipgpio6_c_2",
+               "ipgpio7_b_1", "ipgpio7_c_1");
+DB8540_FUNC_GROUPS(ipi2c, "ipi2c_a_1", "ipi2c_a_2");
+DB8540_FUNC_GROUPS(kp, "kp_a_1", "kp_b_1", "kp_c_1", "kp_oc1_1");
+DB8540_FUNC_GROUPS(lcd, "lcd_d0_d7_a_1", "lcd_d12_d23_a_1", "lcd_d8_d11_a_1",
+               "lcdvsi0_a_1", "lcdvsi1_a_1");
+DB8540_FUNC_GROUPS(lcdb, "lcdb_a_1");
+DB8540_FUNC_GROUPS(mc0, "mc0_a_1");
+DB8540_FUNC_GROUPS(mc1, "mc1_a_1", "mc1_a_2");
+DB8540_FUNC_GROUPS(mc2, "mc2_a_1", "mc2rstn_c_1");
+DB8540_FUNC_GROUPS(mc3, "mc3_b_1");
+DB8540_FUNC_GROUPS(mc4, "mc4_a_1", "mc4rstn_c_1");
+DB8540_FUNC_GROUPS(mc5, "mc5_c_1");
+DB8540_FUNC_GROUPS(modaccgpo, "modaccgpo_c_1", "modaccgpo_oc1_1",
+               "modaccgpo_oc3_1");
+DB8540_FUNC_GROUPS(modaccuart, "modaccuart_oc2_1", "modaccuarttxrx_oc4_1",
+               "modaccuartrtccts_oc4_1");
+DB8540_FUNC_GROUPS(modi2s, "modi2s_a_1");
+DB8540_FUNC_GROUPS(modobs, "modobsclk_a_1", "modobsclkout_oc1_1",
+               "modobspwrctrl_oc1_1", "modobspwrrst_c_1",
+               "modobsrefclk_oc1_1", "modobsresout_c_1",
+               "modobsresout_oc1_1", "modobsservice_oc2_1");
+DB8540_FUNC_GROUPS(modprcmudbg, "modprcmudbg_oc1_1");
+DB8540_FUNC_GROUPS(modrf, "modrf_c_1");
+DB8540_FUNC_GROUPS(modsmb, "modsmb_a_1");
+DB8540_FUNC_GROUPS(modtrig, "modtrig_b_1");
+DB8540_FUNC_GROUPS(moduart, "moduart1_c_1", "moduart1_oc1_1",
+               "moduart1txrx_oc4_1", "moduart1rtscts_oc4_1", "moduart0_oc2_1");
+DB8540_FUNC_GROUPS(moduartstmmux, "moduartstmmux_b_1", "moduartstmmux_oc2_1",
+               "moduartstmmux_oc4_1");
+DB8540_FUNC_GROUPS(modxmip, "modxmip_oc1_1", "modxmip_oc2_1");
+/*
+ * MSP0 can only be on a certain set of pins, but the TX/RX pins can be
+ * switched around by selecting the altfunction A or B.
+ */
+DB8540_FUNC_GROUPS(msp0, "msp0rfsrck_a_1", "msp0tfstck_a_1", "msp0txrx_a_1",
+               "msp0txrx_b_1");
+DB8540_FUNC_GROUPS(msp1, "msp1_a_1", "msp1txrx_a_1", "msp1txrx_b_1");
+DB8540_FUNC_GROUPS(msp2, "msp2sck_a_1", "msp2txdtcktfs_a_1", "msp2rxd_a_1");
+DB8540_FUNC_GROUPS(msp4, "msp4_a_1", "msp4_b_1", "msp4_c_1");
+DB8540_FUNC_GROUPS(pwl, "pwl_b_1", "pwl_b_2", "pwl_b_3", "pwl_b_4");
+DB8540_FUNC_GROUPS(remap, "remap0_oc1_1", "remap1_oc1_1");
+DB8540_FUNC_GROUPS(sbag, "sbag_oc2_1", "sbag_oc2_2");
+/* Select between CS0 on alt B or PS1 on alt C */
+DB8540_FUNC_GROUPS(sm, "sm_b_1", "smcleale_c_1", "smcs0_b_1", "smcs1_b_1",
+               "smps0_c_1", "smps1_c_1");
+DB8540_FUNC_GROUPS(spi0, "spi0_c_1");
+DB8540_FUNC_GROUPS(spi1, "spi1_b_1");
+DB8540_FUNC_GROUPS(spi2, "spi2_a_1");
+DB8540_FUNC_GROUPS(spi3, "spi3_oc1_1");
+DB8540_FUNC_GROUPS(ssp0, "ssp0_a_1");
+DB8540_FUNC_GROUPS(ssp1, "ssp1_a_1");
+DB8540_FUNC_GROUPS(stmape, "stmape_c_1", "stmape_oc1_1", "stmape_oc2_1");
+DB8540_FUNC_GROUPS(stmmod, "stmmod_b_1", "stmmod_oc2_1", "stmmod_oc4_1");
+DB8540_FUNC_GROUPS(tpui, "tpui_oc3_1");
+DB8540_FUNC_GROUPS(u0, "u0_a_1", "u0_c_1");
+DB8540_FUNC_GROUPS(u1, "u1ctsrts_a_1", "u1rxtx_a_1");
+DB8540_FUNC_GROUPS(u2, "u2_oc1_1", "u2_oc2_1", "u2ctsrts_a_1", "u2ctsrts_oc1_1",
+               "u2rxtx_c_1", "u2txrx_a_1", "u2txrx_b_1", "u2txrx_b_2",
+               "u2txrx_oc1_1");
+DB8540_FUNC_GROUPS(u3, "u3ctsrts_b_1", "u3rxtx_c_1", "u3txrxa_b_1");
+DB8540_FUNC_GROUPS(u4, "u4ctsrts_b_1", "u4ctsrts_c_1", "u4txrx_b_1");
+DB8540_FUNC_GROUPS(usb, "usb_a_1");
+
+
+#define FUNCTION(fname)                                        \
+       {                                               \
+               .name = #fname,                         \
+               .groups = fname##_groups,               \
+               .ngroups = ARRAY_SIZE(fname##_groups),  \
+       }
+
+static const struct nmk_function nmk_db8540_functions[] = {
+       FUNCTION(apetrig),
+       FUNCTION(clkout),
+       FUNCTION(ddrtrig),
+       FUNCTION(hsi),
+       FUNCTION(hwobs),
+       FUNCTION(hx),
+       FUNCTION(i2c0),
+       FUNCTION(i2c1),
+       FUNCTION(i2c2),
+       FUNCTION(i2c3),
+       FUNCTION(i2c4),
+       FUNCTION(i2c5),
+       FUNCTION(i2c6),
+       FUNCTION(ipgpio),
+       FUNCTION(ipi2c),
+       FUNCTION(kp),
+       FUNCTION(lcd),
+       FUNCTION(lcdb),
+       FUNCTION(mc0),
+       FUNCTION(mc1),
+       FUNCTION(mc2),
+       FUNCTION(mc3),
+       FUNCTION(mc4),
+       FUNCTION(mc5),
+       FUNCTION(modaccgpo),
+       FUNCTION(modaccuart),
+       FUNCTION(modi2s),
+       FUNCTION(modobs),
+       FUNCTION(modprcmudbg),
+       FUNCTION(modrf),
+       FUNCTION(modsmb),
+       FUNCTION(modtrig),
+       FUNCTION(moduart),
+       FUNCTION(modxmip),
+       FUNCTION(msp0),
+       FUNCTION(msp1),
+       FUNCTION(msp2),
+       FUNCTION(msp4),
+       FUNCTION(pwl),
+       FUNCTION(remap),
+       FUNCTION(sbag),
+       FUNCTION(sm),
+       FUNCTION(spi0),
+       FUNCTION(spi1),
+       FUNCTION(spi2),
+       FUNCTION(spi3),
+       FUNCTION(ssp0),
+       FUNCTION(ssp1),
+       FUNCTION(stmape),
+       FUNCTION(stmmod),
+       FUNCTION(tpui),
+       FUNCTION(u0),
+       FUNCTION(u1),
+       FUNCTION(u2),
+       FUNCTION(u3),
+       FUNCTION(u4),
+       FUNCTION(usb)
+};
+
+static const struct prcm_gpiocr_altcx_pin_desc db8540_altcx_pins[] = {
+       PRCM_GPIOCR_ALTCX(8,    true, PRCM_IDX_GPIOCR1, 20,     /* SPI3_CLK */
+                               false, 0, 0,
+                               false, 0, 0,
+                               false, 0, 0
+       ),
+       PRCM_GPIOCR_ALTCX(9,    true, PRCM_IDX_GPIOCR1, 20,     /* SPI3_RXD */
+                               false, 0, 0,
+                               false, 0, 0,
+                               false, 0, 0
+       ),
+       PRCM_GPIOCR_ALTCX(10,   true, PRCM_IDX_GPIOCR1, 20,     /* SPI3_FRM */
+                               false, 0, 0,
+                               false, 0, 0,
+                               false, 0, 0
+       ),
+       PRCM_GPIOCR_ALTCX(11,   true, PRCM_IDX_GPIOCR1, 20,     /* SPI3_TXD */
+                               false, 0, 0,
+                               false, 0, 0,
+                               false, 0, 0
+       ),
+       PRCM_GPIOCR_ALTCX(23,   true, PRCM_IDX_GPIOCR1, 9,      /* STMAPE_CLK_a */
+                               true, PRCM_IDX_GPIOCR2, 10,     /* SBAG_CLK_a */
+                               false, 0, 0,
+                               false, 0, 0
+       ),
+       PRCM_GPIOCR_ALTCX(24,   true, PRCM_IDX_GPIOCR3, 30,     /* U2_RXD_g */
+                               true, PRCM_IDX_GPIOCR2, 10,     /* SBAG_VAL_a */
+                               false, 0, 0,
+                               false, 0, 0
+       ),
+       PRCM_GPIOCR_ALTCX(25,   true, PRCM_IDX_GPIOCR1, 9,      /* STMAPE_DAT_a[0] */
+                               true, PRCM_IDX_GPIOCR2, 10,     /* SBAG_D_a[0] */
+                               false, 0, 0,
+                               false, 0, 0
+       ),
+       PRCM_GPIOCR_ALTCX(26,   true, PRCM_IDX_GPIOCR1, 9,      /* STMAPE_DAT_a[1] */
+                               true, PRCM_IDX_GPIOCR2, 10,     /* SBAG_D_a[1] */
+                               false, 0, 0,
+                               false, 0, 0
+       ),
+       PRCM_GPIOCR_ALTCX(27,   true, PRCM_IDX_GPIOCR1, 9,      /* STMAPE_DAT_a[2] */
+                               true, PRCM_IDX_GPIOCR2, 10,     /* SBAG_D_a[2] */
+                               false, 0, 0,
+                               false, 0, 0
+       ),
+       PRCM_GPIOCR_ALTCX(28,   true, PRCM_IDX_GPIOCR1, 9,      /* STMAPE_DAT_a[3] */
+                               true, PRCM_IDX_GPIOCR2, 10,     /* SBAG_D_a[3] */
+                               false, 0, 0,
+                               false, 0, 0
+       ),
+       PRCM_GPIOCR_ALTCX(64,   true, PRCM_IDX_GPIOCR1, 15,     /* MODOBS_REFCLK_REQ */
+                               false, 0, 0,
+                               true, PRCM_IDX_GPIOCR1, 2,      /* TPIU_CTL */
+                               true, PRCM_IDX_GPIOCR2, 23      /* HW_OBS_APE_PRCMU[17] */
+       ),
+       PRCM_GPIOCR_ALTCX(65,   true, PRCM_IDX_GPIOCR1, 19,     /* MODOBS_PWRCTRL0 */
+                               true, PRCM_IDX_GPIOCR1, 24,     /* Hx_CLK */
+                               true, PRCM_IDX_GPIOCR1, 2,      /* TPIU_CLK */
+                               true, PRCM_IDX_GPIOCR2, 24      /* HW_OBS_APE_PRCMU[16] */
+       ),
+       PRCM_GPIOCR_ALTCX(66,   true, PRCM_IDX_GPIOCR1, 15,     /* MODOBS_CLKOUT1 */
+                               false, 0, 0,
+                               true, PRCM_IDX_GPIOCR1, 2,      /* TPIU_D[15] */
+                               true, PRCM_IDX_GPIOCR2, 25      /* HW_OBS_APE_PRCMU[15] */
+       ),
+       PRCM_GPIOCR_ALTCX(67,   true, PRCM_IDX_GPIOCR1, 1,      /* MODUART1_TXD_a */
+                               true, PRCM_IDX_GPIOCR1, 6,      /* MODACCUART_TXD_a */
+                               true, PRCM_IDX_GPIOCR1, 2,      /* TPIU_D[14] */
+                               true, PRCM_IDX_GPIOCR2, 26      /* HW_OBS_APE_PRCMU[14] */
+       ),
+       PRCM_GPIOCR_ALTCX(70,   true, PRCM_IDX_GPIOCR3, 6,      /* MOD_PRCMU_DEBUG[17] */
+                               true, PRCM_IDX_GPIOCR1, 10,     /* STMMOD_CLK_b */
+                               true, PRCM_IDX_GPIOCR1, 2,      /* TPIU_D[13] */
+                               true, PRCM_IDX_GPIOCR2, 27      /* HW_OBS_APE_PRCMU[13] */
+       ),
+       PRCM_GPIOCR_ALTCX(71,   true, PRCM_IDX_GPIOCR3, 6,      /* MOD_PRCMU_DEBUG[16] */
+                               true, PRCM_IDX_GPIOCR1, 10,     /* STMMOD_DAT_b[3] */
+                               true, PRCM_IDX_GPIOCR1, 2,      /* TPIU_D[12] */
+                               true, PRCM_IDX_GPIOCR2, 27      /* HW_OBS_APE_PRCMU[12] */
+       ),
+       PRCM_GPIOCR_ALTCX(72,   true, PRCM_IDX_GPIOCR3, 6,      /* MOD_PRCMU_DEBUG[15] */
+                               true, PRCM_IDX_GPIOCR1, 10,     /* STMMOD_DAT_b[2] */
+                               true, PRCM_IDX_GPIOCR1, 2,      /* TPIU_D[11] */
+                               true, PRCM_IDX_GPIOCR2, 27      /* HW_OBS_APE_PRCMU[11] */
+       ),
+       PRCM_GPIOCR_ALTCX(73,   true, PRCM_IDX_GPIOCR3, 6,      /* MOD_PRCMU_DEBUG[14] */
+                               true, PRCM_IDX_GPIOCR1, 10,     /* STMMOD_DAT_b[1] */
+                               true, PRCM_IDX_GPIOCR1, 2,      /* TPIU_D[10] */
+                               true, PRCM_IDX_GPIOCR2, 27      /* HW_OBS_APE_PRCMU[10] */
+       ),
+       PRCM_GPIOCR_ALTCX(74,   true, PRCM_IDX_GPIOCR3, 6,      /* MOD_PRCMU_DEBUG[13] */
+                               true, PRCM_IDX_GPIOCR1, 10,     /* STMMOD_DAT_b[0] */
+                               true, PRCM_IDX_GPIOCR1, 2,      /* TPIU_D[9] */
+                               true, PRCM_IDX_GPIOCR2, 27      /* HW_OBS_APE_PRCMU[9] */
+       ),
+       PRCM_GPIOCR_ALTCX(75,   true, PRCM_IDX_GPIOCR1, 12,     /* MODOBS_RESOUT0_N */
+                               true, PRCM_IDX_GPIOCR2, 1,      /* MODUART_STMMUX_RXD_b */
+                               true, PRCM_IDX_GPIOCR1, 2,      /* TPIU_D[8] */
+                               true, PRCM_IDX_GPIOCR2, 28      /* HW_OBS_APE_PRCMU[8] */
+       ),
+       PRCM_GPIOCR_ALTCX(76,   true, PRCM_IDX_GPIOCR3, 7,      /* MOD_PRCMU_DEBUG[12] */
+                               true, PRCM_IDX_GPIOCR1, 25,     /* Hx_GPIO[7] */
+                               true, PRCM_IDX_GPIOCR1, 2,      /* TPIU_D[7] */
+                               true, PRCM_IDX_GPIOCR2, 29      /* HW_OBS_APE_PRCMU[7] */
+       ),
+       PRCM_GPIOCR_ALTCX(77,   true, PRCM_IDX_GPIOCR3, 7,      /* MOD_PRCMU_DEBUG[11] */
+                               true, PRCM_IDX_GPIOCR1, 25,     /* Hx_GPIO[6] */
+                               true, PRCM_IDX_GPIOCR1, 2,      /* TPIU_D[6] */
+                               true, PRCM_IDX_GPIOCR2, 29      /* HW_OBS_APE_PRCMU[6] */
+       ),
+       PRCM_GPIOCR_ALTCX(78,   true, PRCM_IDX_GPIOCR3, 7,      /* MOD_PRCMU_DEBUG[10] */
+                               true, PRCM_IDX_GPIOCR1, 25,     /* Hx_GPIO[5] */
+                               true, PRCM_IDX_GPIOCR1, 2,      /* TPIU_D[5] */
+                               true, PRCM_IDX_GPIOCR2, 29      /* HW_OBS_APE_PRCMU[5] */
+       ),
+       PRCM_GPIOCR_ALTCX(79,   true, PRCM_IDX_GPIOCR3, 7,      /* MOD_PRCMU_DEBUG[9] */
+                               true, PRCM_IDX_GPIOCR1, 25,     /* Hx_GPIO[4] */
+                               true, PRCM_IDX_GPIOCR1, 2,      /* TPIU_D[4] */
+                               true, PRCM_IDX_GPIOCR2, 29      /* HW_OBS_APE_PRCMU[4] */
+       ),
+       PRCM_GPIOCR_ALTCX(80,   true, PRCM_IDX_GPIOCR1, 26,     /* MODACC_GPO[0] */
+                               true, PRCM_IDX_GPIOCR1, 25,     /* Hx_GPIO[3] */
+                               true, PRCM_IDX_GPIOCR1, 2,      /* TPIU_D[3] */
+                               true, PRCM_IDX_GPIOCR2, 30      /* HW_OBS_APE_PRCMU[3] */
+       ),
+       PRCM_GPIOCR_ALTCX(81,   true, PRCM_IDX_GPIOCR2, 17,     /* MODACC_GPO[1] */
+                               true, PRCM_IDX_GPIOCR1, 25,     /* Hx_GPIO[2] */
+                               true, PRCM_IDX_GPIOCR1, 2,      /* TPIU_D[2] */
+                               true, PRCM_IDX_GPIOCR2, 30      /* HW_OBS_APE_PRCMU[2] */
+       ),
+       PRCM_GPIOCR_ALTCX(82,   true, PRCM_IDX_GPIOCR3, 8,      /* MOD_PRCMU_DEBUG[8] */
+                               true, PRCM_IDX_GPIOCR1, 25,     /* Hx_GPIO[1] */
+                               true, PRCM_IDX_GPIOCR1, 2,      /* TPIU_D[1] */
+                               true, PRCM_IDX_GPIOCR2, 31      /* HW_OBS_APE_PRCMU[1] */
+       ),
+       PRCM_GPIOCR_ALTCX(83,   true, PRCM_IDX_GPIOCR3, 8,      /* MOD_PRCMU_DEBUG[7] */
+                               true, PRCM_IDX_GPIOCR1, 25,     /* Hx_GPIO[0] */
+                               true, PRCM_IDX_GPIOCR1, 2,      /* TPIU_D[0] */
+                               true, PRCM_IDX_GPIOCR2, 31      /* HW_OBS_APE_PRCMU[0] */
+       ),
+       PRCM_GPIOCR_ALTCX(84,   true, PRCM_IDX_GPIOCR3, 9,      /* MOD_PRCMU_DEBUG[6] */
+                               true, PRCM_IDX_GPIOCR1, 8,      /* SBAG_CLK_b */
+                               true, PRCM_IDX_GPIOCR1, 3,      /* TPIU_D[23] */
+                               true, PRCM_IDX_GPIOCR1, 16      /* MODUART1_RXD_b */
+       ),
+       PRCM_GPIOCR_ALTCX(85,   true, PRCM_IDX_GPIOCR3, 9,      /* MOD_PRCMU_DEBUG[5] */
+                               true, PRCM_IDX_GPIOCR1, 8,      /* SBAG_D_b[3] */
+                               true, PRCM_IDX_GPIOCR1, 3,      /* TPIU_D[22] */
+                               true, PRCM_IDX_GPIOCR1, 16      /* MODUART1_TXD_b */
+       ),
+       PRCM_GPIOCR_ALTCX(86,   true, PRCM_IDX_GPIOCR3, 9,      /* MOD_PRCMU_DEBUG[0] */
+                               true, PRCM_IDX_GPIOCR2, 18,     /* STMAPE_DAT_b[0] */
+                               true, PRCM_IDX_GPIOCR1, 14,     /* TPIU_D[25] */
+                               true, PRCM_IDX_GPIOCR1, 11      /* STMMOD_DAT_c[0] */
+       ),
+       PRCM_GPIOCR_ALTCX(87,   true, PRCM_IDX_GPIOCR3, 0,      /* MODACC_GPO_a[5] */
+                               true, PRCM_IDX_GPIOCR2, 3,      /* U2_RXD_c */
+                               true, PRCM_IDX_GPIOCR1, 4,      /* TPIU_D[24] */
+                               true, PRCM_IDX_GPIOCR1, 21      /* MODUART_STMMUX_RXD_c */
+       ),
+       PRCM_GPIOCR_ALTCX(151,  true, PRCM_IDX_GPIOCR1, 18,     /* REMAP0 */
+                               false, 0, 0,
+                               false, 0, 0,
+                               false, 0, 0
+       ),
+       PRCM_GPIOCR_ALTCX(152,  true, PRCM_IDX_GPIOCR1, 18,     /* REMAP1 */
+                               false, 0, 0,
+                               false, 0, 0,
+                               false, 0, 0
+       ),
+       PRCM_GPIOCR_ALTCX(153,  true, PRCM_IDX_GPIOCR3, 2,      /* KP_O_b[6] */
+                               true, PRCM_IDX_GPIOCR1, 8,      /* SBAG_D_b[2] */
+                               true, PRCM_IDX_GPIOCR1, 3,      /* TPIU_D[21] */
+                               true, PRCM_IDX_GPIOCR1, 0       /* MODUART1_RTS */
+       ),
+       PRCM_GPIOCR_ALTCX(154,  true, PRCM_IDX_GPIOCR3, 2,      /* KP_I_b[6] */
+                               true, PRCM_IDX_GPIOCR1, 8,      /* SBAG_D_b[1] */
+                               true, PRCM_IDX_GPIOCR1, 3,      /* TPIU_D[20] */
+                               true, PRCM_IDX_GPIOCR1, 0       /* MODUART1_CTS */
+       ),
+       PRCM_GPIOCR_ALTCX(155,  true, PRCM_IDX_GPIOCR3, 3,      /* KP_O_b[5] */
+                               true, PRCM_IDX_GPIOCR1, 8,      /* SBAG_D_b[0] */
+                               true, PRCM_IDX_GPIOCR1, 3,      /* TPIU_D[19] */
+                               true, PRCM_IDX_GPIOCR1, 5       /* MODACCUART_RXD_c */
+       ),
+       PRCM_GPIOCR_ALTCX(156,  true, PRCM_IDX_GPIOCR3, 3,      /* KP_O_b[4] */
+                               true, PRCM_IDX_GPIOCR1, 8,      /* SBAG_VAL_b */
+                               true, PRCM_IDX_GPIOCR1, 3,      /* TPIU_D[18] */
+                               true, PRCM_IDX_GPIOCR1, 5       /* MODACCUART_TXD_b */
+       ),
+       PRCM_GPIOCR_ALTCX(157,  true, PRCM_IDX_GPIOCR3, 4,      /* KP_I_b[5] */
+                               true, PRCM_IDX_GPIOCR1, 23,     /* MODOBS_SERVICE_N */
+                               true, PRCM_IDX_GPIOCR1, 3,      /* TPIU_D[17] */
+                               true, PRCM_IDX_GPIOCR1, 14      /* MODACCUART_RTS */
+       ),
+       PRCM_GPIOCR_ALTCX(158,  true, PRCM_IDX_GPIOCR3, 4,      /* KP_I_b[4] */
+                               true, PRCM_IDX_GPIOCR2, 0,      /* U2_TXD_c */
+                               true, PRCM_IDX_GPIOCR1, 3,      /* TPIU_D[16] */
+                               true, PRCM_IDX_GPIOCR1, 14      /* MODACCUART_CTS */
+       ),
+       PRCM_GPIOCR_ALTCX(159,  true, PRCM_IDX_GPIOCR3, 5,      /* KP_O_b[3] */
+                               true, PRCM_IDX_GPIOCR3, 10,     /* MODUART0_RXD */
+                               true, PRCM_IDX_GPIOCR1, 4,      /* TPIU_D[31] */
+                               false, 0, 0
+       ),
+       PRCM_GPIOCR_ALTCX(160,  true, PRCM_IDX_GPIOCR3, 5,      /* KP_I_b[3] */
+                               true, PRCM_IDX_GPIOCR3, 10,     /* MODUART0_TXD */
+                               true, PRCM_IDX_GPIOCR1, 4,      /* TPIU_D[30] */
+                               false, 0, 0
+       ),
+       PRCM_GPIOCR_ALTCX(161,  true, PRCM_IDX_GPIOCR3, 9,      /* MOD_PRCMU_DEBUG[4] */
+                               true, PRCM_IDX_GPIOCR2, 18,     /* STMAPE_CLK_b */
+                               true, PRCM_IDX_GPIOCR1, 4,      /* TPIU_D[29] */
+                               true, PRCM_IDX_GPIOCR1, 11      /* STMMOD_CLK_c */
+       ),
+       PRCM_GPIOCR_ALTCX(162,  true, PRCM_IDX_GPIOCR3, 9,      /* MOD_PRCMU_DEBUG[3] */
+                               true, PRCM_IDX_GPIOCR2, 18,     /* STMAPE_DAT_b[3] */
+                               true, PRCM_IDX_GPIOCR1, 4,      /* TPIU_D[28] */
+                               true, PRCM_IDX_GPIOCR1, 11      /* STMMOD_DAT_c[3] */
+       ),
+       PRCM_GPIOCR_ALTCX(163,  true, PRCM_IDX_GPIOCR3, 9,      /* MOD_PRCMU_DEBUG[2] */
+                               true, PRCM_IDX_GPIOCR2, 18,     /* STMAPE_DAT_b[2] */
+                               true, PRCM_IDX_GPIOCR1, 4,      /* TPIU_D[27] */
+                               true, PRCM_IDX_GPIOCR1, 11      /* STMMOD_DAT_c[2] */
+       ),
+       PRCM_GPIOCR_ALTCX(164,  true, PRCM_IDX_GPIOCR3, 9,      /* MOD_PRCMU_DEBUG[1] */
+                               true, PRCM_IDX_GPIOCR2, 18,     /* STMAPE_DAT_b[1] */
+                               true, PRCM_IDX_GPIOCR1, 4,      /* TPIU_D[26] */
+                               true, PRCM_IDX_GPIOCR1, 11      /* STMMOD_DAT_c[1] */
+       ),
+       PRCM_GPIOCR_ALTCX(204,  true, PRCM_IDX_GPIOCR2, 2,      /* U2_RXD_f */
+                               false, 0, 0,
+                               false, 0, 0,
+                               false, 0, 0
+       ),
+       PRCM_GPIOCR_ALTCX(205,  true, PRCM_IDX_GPIOCR2, 2,      /* U2_TXD_f */
+                               false, 0, 0,
+                               false, 0, 0,
+                               false, 0, 0
+       ),
+       PRCM_GPIOCR_ALTCX(206,  true, PRCM_IDX_GPIOCR2, 2,      /* U2_CTSn_b */
+                               false, 0, 0,
+                               false, 0, 0,
+                               false, 0, 0
+       ),
+       PRCM_GPIOCR_ALTCX(207,  true, PRCM_IDX_GPIOCR2, 2,      /* U2_RTSn_b */
+                               false, 0, 0,
+                               false, 0, 0,
+                               false, 0, 0
+       ),
+};
+
+static const u16 db8540_prcm_gpiocr_regs[] = {
+       [PRCM_IDX_GPIOCR1] = 0x138,
+       [PRCM_IDX_GPIOCR2] = 0x574,
+       [PRCM_IDX_GPIOCR3] = 0x2bc,
+};
+
+static const struct nmk_pinctrl_soc_data nmk_db8540_soc = {
+       .gpio_ranges = nmk_db8540_ranges,
+       .gpio_num_ranges = ARRAY_SIZE(nmk_db8540_ranges),
+       .pins = nmk_db8540_pins,
+       .npins = ARRAY_SIZE(nmk_db8540_pins),
+       .functions = nmk_db8540_functions,
+       .nfunctions = ARRAY_SIZE(nmk_db8540_functions),
+       .groups = nmk_db8540_groups,
+       .ngroups = ARRAY_SIZE(nmk_db8540_groups),
+       .altcx_pins = db8540_altcx_pins,
+       .npins_altcx = ARRAY_SIZE(db8540_altcx_pins),
+       .prcm_gpiocr_registers = db8540_prcm_gpiocr_regs,
+};
+
+void nmk_pinctrl_db8540_init(const struct nmk_pinctrl_soc_data **soc)
+{
+       *soc = &nmk_db8540_soc;
+}
diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik-stn8815.c b/drivers/pinctrl/nomadik/pinctrl-nomadik-stn8815.c
new file mode 100644 (file)
index 0000000..ed39dca
--- /dev/null
@@ -0,0 +1,356 @@
+#include <linux/kernel.h>
+#include <linux/pinctrl/pinctrl.h>
+#include "pinctrl-nomadik.h"
+
+/* All the pins that can be used for GPIO and some other functions */
+#define _GPIO(offset)          (offset)
+
+#define STN8815_PIN_B4         _GPIO(0)
+#define STN8815_PIN_D5         _GPIO(1)
+#define STN8815_PIN_C5         _GPIO(2)
+#define STN8815_PIN_A4         _GPIO(3)
+#define STN8815_PIN_B5         _GPIO(4)
+#define STN8815_PIN_D6         _GPIO(5)
+#define STN8815_PIN_C6         _GPIO(6)
+#define STN8815_PIN_B6         _GPIO(7)
+#define STN8815_PIN_B10                _GPIO(8)
+#define STN8815_PIN_A10                _GPIO(9)
+#define STN8815_PIN_C11                _GPIO(10)
+#define STN8815_PIN_B11                _GPIO(11)
+#define STN8815_PIN_A11                _GPIO(12)
+#define STN8815_PIN_C12                _GPIO(13)
+#define STN8815_PIN_B12                _GPIO(14)
+#define STN8815_PIN_A12                _GPIO(15)
+#define STN8815_PIN_C13                _GPIO(16)
+#define STN8815_PIN_B13                _GPIO(17)
+#define STN8815_PIN_A13                _GPIO(18)
+#define STN8815_PIN_D13                _GPIO(19)
+#define STN8815_PIN_C14                _GPIO(20)
+#define STN8815_PIN_B14                _GPIO(21)
+#define STN8815_PIN_A14                _GPIO(22)
+#define STN8815_PIN_D15                _GPIO(23)
+#define STN8815_PIN_C15                _GPIO(24)
+#define STN8815_PIN_B15                _GPIO(25)
+#define STN8815_PIN_A15                _GPIO(26)
+#define STN8815_PIN_C16                _GPIO(27)
+#define STN8815_PIN_B16                _GPIO(28)
+#define STN8815_PIN_A16                _GPIO(29)
+#define STN8815_PIN_D17                _GPIO(30)
+#define STN8815_PIN_C17                _GPIO(31)
+#define STN8815_PIN_AB6                _GPIO(32)
+#define STN8815_PIN_AA6                _GPIO(33)
+#define STN8815_PIN_Y6         _GPIO(34)
+#define STN8815_PIN_Y5         _GPIO(35)
+#define STN8815_PIN_AA5                _GPIO(36)
+#define STN8815_PIN_AB5                _GPIO(37)
+#define STN8815_PIN_AB4                _GPIO(38)
+#define STN8815_PIN_Y4         _GPIO(39)
+#define STN8815_PIN_R1         _GPIO(40)
+#define STN8815_PIN_R2         _GPIO(41)
+#define STN8815_PIN_R3         _GPIO(42)
+#define STN8815_PIN_P1         _GPIO(43)
+#define STN8815_PIN_P2         _GPIO(44)
+#define STN8815_PIN_P3         _GPIO(45)
+#define STN8815_PIN_N1         _GPIO(46)
+#define STN8815_PIN_N2         _GPIO(47)
+#define STN8815_PIN_N3         _GPIO(48)
+#define STN8815_PIN_M1         _GPIO(49)
+#define STN8815_PIN_M3         _GPIO(50)
+#define STN8815_PIN_M2         _GPIO(51)
+#define STN8815_PIN_L1         _GPIO(52)
+#define STN8815_PIN_L4         _GPIO(53)
+#define STN8815_PIN_L3         _GPIO(54)
+#define STN8815_PIN_L2         _GPIO(55)
+#define STN8815_PIN_F3         _GPIO(56)
+#define STN8815_PIN_F2         _GPIO(57)
+#define STN8815_PIN_E1         _GPIO(58)
+#define STN8815_PIN_E3         _GPIO(59)
+#define STN8815_PIN_E2         _GPIO(60)
+#define STN8815_PIN_E4         _GPIO(61)
+#define STN8815_PIN_D3         _GPIO(62)
+#define STN8815_PIN_D2         _GPIO(63)
+#define STN8815_PIN_F21                _GPIO(64)
+#define STN8815_PIN_F20                _GPIO(65)
+#define STN8815_PIN_E22                _GPIO(66)
+#define STN8815_PIN_D22                _GPIO(67)
+#define STN8815_PIN_E21                _GPIO(68)
+#define STN8815_PIN_E20                _GPIO(69)
+#define STN8815_PIN_C22                _GPIO(70)
+#define STN8815_PIN_D21                _GPIO(71)
+#define STN8815_PIN_D20                _GPIO(72)
+#define STN8815_PIN_C21                _GPIO(73)
+#define STN8815_PIN_C20                _GPIO(74)
+#define STN8815_PIN_C19                _GPIO(75)
+#define STN8815_PIN_B20                _GPIO(76)
+#define STN8815_PIN_B8         _GPIO(77)
+#define STN8815_PIN_A8         _GPIO(78)
+#define STN8815_PIN_C9         _GPIO(79)
+#define STN8815_PIN_B9         _GPIO(80)
+#define STN8815_PIN_A9         _GPIO(81)
+#define STN8815_PIN_C10                _GPIO(82)
+#define STN8815_PIN_K1         _GPIO(83)
+#define STN8815_PIN_K3         _GPIO(84)
+#define STN8815_PIN_K2         _GPIO(85)
+#define STN8815_PIN_J1         _GPIO(86)
+#define STN8815_PIN_J3         _GPIO(87)
+#define STN8815_PIN_J2         _GPIO(88)
+#define STN8815_PIN_H1         _GPIO(89)
+#define STN8815_PIN_H3         _GPIO(90)
+#define STN8815_PIN_H2         _GPIO(91)
+#define STN8815_PIN_G1         _GPIO(92)
+#define STN8815_PIN_G3         _GPIO(93)
+#define STN8815_PIN_G2         _GPIO(94)
+#define STN8815_PIN_F1         _GPIO(95)
+#define STN8815_PIN_T20                _GPIO(96)
+#define STN8815_PIN_R21                _GPIO(97)
+#define STN8815_PIN_R20                _GPIO(98)
+#define STN8815_PIN_U22                _GPIO(99)
+#define STN8815_PIN_N21                _GPIO(100)
+#define STN8815_PIN_N20                _GPIO(101)
+#define STN8815_PIN_P22                _GPIO(102)
+#define STN8815_PIN_N22                _GPIO(103)
+#define STN8815_PIN_V22                _GPIO(104)
+#define STN8815_PIN_V21                _GPIO(105)
+#define STN8815_PIN_K22                _GPIO(106)
+#define STN8815_PIN_K21                _GPIO(107)
+#define STN8815_PIN_H20                _GPIO(108)
+#define STN8815_PIN_G20                _GPIO(109)
+#define STN8815_PIN_L21                _GPIO(110)
+#define STN8815_PIN_H21                _GPIO(111)
+#define STN8815_PIN_J21                _GPIO(112)
+#define STN8815_PIN_H22                _GPIO(113)
+#define STN8815_PIN_K20                _GPIO(114)
+#define STN8815_PIN_L22                _GPIO(115)
+#define STN8815_PIN_G21                _GPIO(116)
+#define STN8815_PIN_J20                _GPIO(117)
+#define STN8815_PIN_G22                _GPIO(118)
+#define STN8815_PIN_U19                _GPIO(119)
+#define STN8815_PIN_G19                _GPIO(120)
+#define STN8815_PIN_M22                _GPIO(121)
+#define STN8815_PIN_M19                _GPIO(122)
+#define STN8815_PIN_J22                _GPIO(123)
+/* GPIOs 124-127 not routed to pins */
+
+/*
+ * The names of the pins are denoted by GPIO number and ball name, even
+ * though they can be used for other things than GPIO, this is the first
+ * column in the table of the data sheet and often used on schematics and
+ * such.
+ */
+static const struct pinctrl_pin_desc nmk_stn8815_pins[] = {
+       PINCTRL_PIN(STN8815_PIN_B4, "GPIO0_B4"),
+       PINCTRL_PIN(STN8815_PIN_D5, "GPIO1_D5"),
+       PINCTRL_PIN(STN8815_PIN_C5, "GPIO2_C5"),
+       PINCTRL_PIN(STN8815_PIN_A4, "GPIO3_A4"),
+       PINCTRL_PIN(STN8815_PIN_B5, "GPIO4_B5"),
+       PINCTRL_PIN(STN8815_PIN_D6, "GPIO5_D6"),
+       PINCTRL_PIN(STN8815_PIN_C6, "GPIO6_C6"),
+       PINCTRL_PIN(STN8815_PIN_B6, "GPIO7_B6"),
+       PINCTRL_PIN(STN8815_PIN_B10, "GPIO8_B10"),
+       PINCTRL_PIN(STN8815_PIN_A10, "GPIO9_A10"),
+       PINCTRL_PIN(STN8815_PIN_C11, "GPIO10_C11"),
+       PINCTRL_PIN(STN8815_PIN_B11, "GPIO11_B11"),
+       PINCTRL_PIN(STN8815_PIN_A11, "GPIO12_A11"),
+       PINCTRL_PIN(STN8815_PIN_C12, "GPIO13_C12"),
+       PINCTRL_PIN(STN8815_PIN_B12, "GPIO14_B12"),
+       PINCTRL_PIN(STN8815_PIN_A12, "GPIO15_A12"),
+       PINCTRL_PIN(STN8815_PIN_C13, "GPIO16_C13"),
+       PINCTRL_PIN(STN8815_PIN_B13, "GPIO17_B13"),
+       PINCTRL_PIN(STN8815_PIN_A13, "GPIO18_A13"),
+       PINCTRL_PIN(STN8815_PIN_D13, "GPIO19_D13"),
+       PINCTRL_PIN(STN8815_PIN_C14, "GPIO20_C14"),
+       PINCTRL_PIN(STN8815_PIN_B14, "GPIO21_B14"),
+       PINCTRL_PIN(STN8815_PIN_A14, "GPIO22_A14"),
+       PINCTRL_PIN(STN8815_PIN_D15, "GPIO23_D15"),
+       PINCTRL_PIN(STN8815_PIN_C15, "GPIO24_C15"),
+       PINCTRL_PIN(STN8815_PIN_B15, "GPIO25_B15"),
+       PINCTRL_PIN(STN8815_PIN_A15, "GPIO26_A15"),
+       PINCTRL_PIN(STN8815_PIN_C16, "GPIO27_C16"),
+       PINCTRL_PIN(STN8815_PIN_B16, "GPIO28_B16"),
+       PINCTRL_PIN(STN8815_PIN_A16, "GPIO29_A16"),
+       PINCTRL_PIN(STN8815_PIN_D17, "GPIO30_D17"),
+       PINCTRL_PIN(STN8815_PIN_C17, "GPIO31_C17"),
+       PINCTRL_PIN(STN8815_PIN_AB6, "GPIO32_AB6"),
+       PINCTRL_PIN(STN8815_PIN_AA6, "GPIO33_AA6"),
+       PINCTRL_PIN(STN8815_PIN_Y6, "GPIO34_Y6"),
+       PINCTRL_PIN(STN8815_PIN_Y5, "GPIO35_Y5"),
+       PINCTRL_PIN(STN8815_PIN_AA5, "GPIO36_AA5"),
+       PINCTRL_PIN(STN8815_PIN_AB5, "GPIO37_AB5"),
+       PINCTRL_PIN(STN8815_PIN_AB4, "GPIO38_AB4"),
+       PINCTRL_PIN(STN8815_PIN_Y4, "GPIO39_Y4"),
+       PINCTRL_PIN(STN8815_PIN_R1, "GPIO40_R1"),
+       PINCTRL_PIN(STN8815_PIN_R2, "GPIO41_R2"),
+       PINCTRL_PIN(STN8815_PIN_R3, "GPIO42_R3"),
+       PINCTRL_PIN(STN8815_PIN_P1, "GPIO43_P1"),
+       PINCTRL_PIN(STN8815_PIN_P2, "GPIO44_P2"),
+       PINCTRL_PIN(STN8815_PIN_P3, "GPIO45_P3"),
+       PINCTRL_PIN(STN8815_PIN_N1, "GPIO46_N1"),
+       PINCTRL_PIN(STN8815_PIN_N2, "GPIO47_N2"),
+       PINCTRL_PIN(STN8815_PIN_N3, "GPIO48_N3"),
+       PINCTRL_PIN(STN8815_PIN_M1, "GPIO49_M1"),
+       PINCTRL_PIN(STN8815_PIN_M3, "GPIO50_M3"),
+       PINCTRL_PIN(STN8815_PIN_M2, "GPIO51_M2"),
+       PINCTRL_PIN(STN8815_PIN_L1, "GPIO52_L1"),
+       PINCTRL_PIN(STN8815_PIN_L4, "GPIO53_L4"),
+       PINCTRL_PIN(STN8815_PIN_L3, "GPIO54_L3"),
+       PINCTRL_PIN(STN8815_PIN_L2, "GPIO55_L2"),
+       PINCTRL_PIN(STN8815_PIN_F3, "GPIO56_F3"),
+       PINCTRL_PIN(STN8815_PIN_F2, "GPIO57_F2"),
+       PINCTRL_PIN(STN8815_PIN_E1, "GPIO58_E1"),
+       PINCTRL_PIN(STN8815_PIN_E3, "GPIO59_E3"),
+       PINCTRL_PIN(STN8815_PIN_E2, "GPIO60_E2"),
+       PINCTRL_PIN(STN8815_PIN_E4, "GPIO61_E4"),
+       PINCTRL_PIN(STN8815_PIN_D3, "GPIO62_D3"),
+       PINCTRL_PIN(STN8815_PIN_D2, "GPIO63_D2"),
+       PINCTRL_PIN(STN8815_PIN_F21, "GPIO64_F21"),
+       PINCTRL_PIN(STN8815_PIN_F20, "GPIO65_F20"),
+       PINCTRL_PIN(STN8815_PIN_E22, "GPIO66_E22"),
+       PINCTRL_PIN(STN8815_PIN_D22, "GPIO67_D22"),
+       PINCTRL_PIN(STN8815_PIN_E21, "GPIO68_E21"),
+       PINCTRL_PIN(STN8815_PIN_E20, "GPIO69_E20"),
+       PINCTRL_PIN(STN8815_PIN_C22, "GPIO70_C22"),
+       PINCTRL_PIN(STN8815_PIN_D21, "GPIO71_D21"),
+       PINCTRL_PIN(STN8815_PIN_D20, "GPIO72_D20"),
+       PINCTRL_PIN(STN8815_PIN_C21, "GPIO73_C21"),
+       PINCTRL_PIN(STN8815_PIN_C20, "GPIO74_C20"),
+       PINCTRL_PIN(STN8815_PIN_C19, "GPIO75_C19"),
+       PINCTRL_PIN(STN8815_PIN_B20, "GPIO76_B20"),
+       PINCTRL_PIN(STN8815_PIN_B8, "GPIO77_B8"),
+       PINCTRL_PIN(STN8815_PIN_A8, "GPIO78_A8"),
+       PINCTRL_PIN(STN8815_PIN_C9, "GPIO79_C9"),
+       PINCTRL_PIN(STN8815_PIN_B9, "GPIO80_B9"),
+       PINCTRL_PIN(STN8815_PIN_A9, "GPIO81_A9"),
+       PINCTRL_PIN(STN8815_PIN_C10, "GPIO82_C10"),
+       PINCTRL_PIN(STN8815_PIN_K1, "GPIO83_K1"),
+       PINCTRL_PIN(STN8815_PIN_K3, "GPIO84_K3"),
+       PINCTRL_PIN(STN8815_PIN_K2, "GPIO85_K2"),
+       PINCTRL_PIN(STN8815_PIN_J1, "GPIO86_J1"),
+       PINCTRL_PIN(STN8815_PIN_J3, "GPIO87_J3"),
+       PINCTRL_PIN(STN8815_PIN_J2, "GPIO88_J2"),
+       PINCTRL_PIN(STN8815_PIN_H1, "GPIO89_H1"),
+       PINCTRL_PIN(STN8815_PIN_H3, "GPIO90_H3"),
+       PINCTRL_PIN(STN8815_PIN_H2, "GPIO91_H2"),
+       PINCTRL_PIN(STN8815_PIN_G1, "GPIO92_G1"),
+       PINCTRL_PIN(STN8815_PIN_G3, "GPIO93_G3"),
+       PINCTRL_PIN(STN8815_PIN_G2, "GPIO94_G2"),
+       PINCTRL_PIN(STN8815_PIN_F1, "GPIO95_F1"),
+       PINCTRL_PIN(STN8815_PIN_T20, "GPIO96_T20"),
+       PINCTRL_PIN(STN8815_PIN_R21, "GPIO97_R21"),
+       PINCTRL_PIN(STN8815_PIN_R20, "GPIO98_R20"),
+       PINCTRL_PIN(STN8815_PIN_U22, "GPIO99_U22"),
+       PINCTRL_PIN(STN8815_PIN_N21, "GPIO100_N21"),
+       PINCTRL_PIN(STN8815_PIN_N20, "GPIO101_N20"),
+       PINCTRL_PIN(STN8815_PIN_P22, "GPIO102_P22"),
+       PINCTRL_PIN(STN8815_PIN_N22, "GPIO103_N22"),
+       PINCTRL_PIN(STN8815_PIN_V22, "GPIO104_V22"),
+       PINCTRL_PIN(STN8815_PIN_V21, "GPIO105_V21"),
+       PINCTRL_PIN(STN8815_PIN_K22, "GPIO106_K22"),
+       PINCTRL_PIN(STN8815_PIN_K21, "GPIO107_K21"),
+       PINCTRL_PIN(STN8815_PIN_H20, "GPIO108_H20"),
+       PINCTRL_PIN(STN8815_PIN_G20, "GPIO109_G20"),
+       PINCTRL_PIN(STN8815_PIN_L21, "GPIO110_L21"),
+       PINCTRL_PIN(STN8815_PIN_H21, "GPIO111_H21"),
+       PINCTRL_PIN(STN8815_PIN_J21, "GPIO112_J21"),
+       PINCTRL_PIN(STN8815_PIN_H22, "GPIO113_H22"),
+       PINCTRL_PIN(STN8815_PIN_K20, "GPIO114_K20"),
+       PINCTRL_PIN(STN8815_PIN_L22, "GPIO115_L22"),
+       PINCTRL_PIN(STN8815_PIN_G21, "GPIO116_G21"),
+       PINCTRL_PIN(STN8815_PIN_J20, "GPIO117_J20"),
+       PINCTRL_PIN(STN8815_PIN_G22, "GPIO118_G22"),
+       PINCTRL_PIN(STN8815_PIN_U19, "GPIO119_U19"),
+       PINCTRL_PIN(STN8815_PIN_G19, "GPIO120_G19"),
+       PINCTRL_PIN(STN8815_PIN_M22, "GPIO121_M22"),
+       PINCTRL_PIN(STN8815_PIN_M19, "GPIO122_M19"),
+       PINCTRL_PIN(STN8815_PIN_J22, "GPIO123_J22"),
+};
+
+#define STN8815_GPIO_RANGE(a, b, c) { .name = "STN8815", .id = a, .base = b, \
+                       .pin_base = b, .npins = c }
+
+/*
+ * This matches the 32-pin gpio chips registered by the GPIO portion. This
+ * cannot be const since we assign the struct gpio_chip * pointer at runtime.
+ */
+static struct pinctrl_gpio_range nmk_stn8815_ranges[] = {
+       STN8815_GPIO_RANGE(0, 0, 32),
+       STN8815_GPIO_RANGE(1, 32, 32),
+       STN8815_GPIO_RANGE(2, 64, 32),
+       STN8815_GPIO_RANGE(3, 96, 28),
+};
+
+/*
+ * Read the pin group names like this:
+ * u0_a_1    = first groups of pins for uart0 on alt function a
+ * i2c2_b_2  = second group of pins for i2c2 on alt function b
+ */
+
+/* Altfunction A */
+static const unsigned u0_a_1_pins[] = { STN8815_PIN_B4, STN8815_PIN_D5,
+       STN8815_PIN_C5, STN8815_PIN_A4, STN8815_PIN_B5, STN8815_PIN_D6,
+       STN8815_PIN_C6, STN8815_PIN_B6 };
+static const unsigned mmcsd_a_1_pins[] = { STN8815_PIN_B10, STN8815_PIN_A10,
+       STN8815_PIN_C11, STN8815_PIN_B11, STN8815_PIN_A11, STN8815_PIN_C12,
+       STN8815_PIN_B12, STN8815_PIN_A12, STN8815_PIN_C13, STN8815_PIN_C15 };
+static const unsigned u1_a_1_pins[] = { STN8815_PIN_M2, STN8815_PIN_L1,
+                                       STN8815_PIN_F3, STN8815_PIN_F2 };
+static const unsigned i2c1_a_1_pins[] = { STN8815_PIN_L4, STN8815_PIN_L3 };
+static const unsigned i2c0_a_1_pins[] = { STN8815_PIN_D3, STN8815_PIN_D2 };
+/* Altfunction B */
+static const unsigned u1_b_1_pins[] = { STN8815_PIN_B16, STN8815_PIN_A16 };
+static const unsigned i2cusb_b_1_pins[] = { STN8815_PIN_C21, STN8815_PIN_C20 };
+
+#define STN8815_PIN_GROUP(a, b) { .name = #a, .pins = a##_pins,                \
+                       .npins = ARRAY_SIZE(a##_pins), .altsetting = b }
+
+static const struct nmk_pingroup nmk_stn8815_groups[] = {
+       STN8815_PIN_GROUP(u0_a_1, NMK_GPIO_ALT_A),
+       STN8815_PIN_GROUP(mmcsd_a_1, NMK_GPIO_ALT_A),
+       STN8815_PIN_GROUP(u1_a_1, NMK_GPIO_ALT_A),
+       STN8815_PIN_GROUP(i2c1_a_1, NMK_GPIO_ALT_A),
+       STN8815_PIN_GROUP(i2c0_a_1, NMK_GPIO_ALT_A),
+       STN8815_PIN_GROUP(u1_b_1, NMK_GPIO_ALT_B),
+       STN8815_PIN_GROUP(i2cusb_b_1, NMK_GPIO_ALT_B),
+};
+
+/* We use this macro to define the groups applicable to a function */
+#define STN8815_FUNC_GROUPS(a, b...)      \
+static const char * const a##_groups[] = { b };
+
+STN8815_FUNC_GROUPS(u0, "u0_a_1");
+STN8815_FUNC_GROUPS(mmcsd, "mmcsd_a_1");
+STN8815_FUNC_GROUPS(u1, "u1_a_1", "u1_b_1");
+STN8815_FUNC_GROUPS(i2c1, "i2c1_a_1");
+STN8815_FUNC_GROUPS(i2c0, "i2c0_a_1");
+STN8815_FUNC_GROUPS(i2cusb, "i2cusb_b_1");
+
+#define FUNCTION(fname)                                        \
+       {                                               \
+               .name = #fname,                         \
+               .groups = fname##_groups,               \
+               .ngroups = ARRAY_SIZE(fname##_groups),  \
+       }
+
+static const struct nmk_function nmk_stn8815_functions[] = {
+       FUNCTION(u0),
+       FUNCTION(mmcsd),
+       FUNCTION(u1),
+       FUNCTION(i2c1),
+       FUNCTION(i2c0),
+       FUNCTION(i2cusb),
+};
+
+static const struct nmk_pinctrl_soc_data nmk_stn8815_soc = {
+       .gpio_ranges = nmk_stn8815_ranges,
+       .gpio_num_ranges = ARRAY_SIZE(nmk_stn8815_ranges),
+       .pins = nmk_stn8815_pins,
+       .npins = ARRAY_SIZE(nmk_stn8815_pins),
+       .functions = nmk_stn8815_functions,
+       .nfunctions = ARRAY_SIZE(nmk_stn8815_functions),
+       .groups = nmk_stn8815_groups,
+       .ngroups = ARRAY_SIZE(nmk_stn8815_groups),
+};
+
+void nmk_pinctrl_stn8815_init(const struct nmk_pinctrl_soc_data **soc)
+{
+       *soc = &nmk_stn8815_soc;
+}
diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik.c b/drivers/pinctrl/nomadik/pinctrl-nomadik.c
new file mode 100644 (file)
index 0000000..e7cab07
--- /dev/null
@@ -0,0 +1,2099 @@
+/*
+ * Generic GPIO driver for logic cells found in the Nomadik SoC
+ *
+ * Copyright (C) 2008,2009 STMicroelectronics
+ * Copyright (C) 2009 Alessandro Rubini <rubini@unipv.it>
+ *   Rewritten based on work by Prafulla WADASKAR <prafulla.wadaskar@st.com>
+ * Copyright (C) 2011-2013 Linus Walleij <linus.walleij@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/pinctrl/machine.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/pinctrl/pinconf.h>
+/* Since we request GPIOs from ourself */
+#include <linux/pinctrl/consumer.h>
+#include "pinctrl-nomadik.h"
+#include "../core.h"
+
+/*
+ * The GPIO module in the Nomadik family of Systems-on-Chip is an
+ * AMBA device, managing 32 pins and alternate functions.  The logic block
+ * is currently used in the Nomadik and ux500.
+ *
+ * Symbols in this file are called "nmk_gpio" for "nomadik gpio"
+ */
+
+/*
+ * pin configurations are represented by 32-bit integers:
+ *
+ *     bit  0.. 8 - Pin Number (512 Pins Maximum)
+ *     bit  9..10 - Alternate Function Selection
+ *     bit 11..12 - Pull up/down state
+ *     bit     13 - Sleep mode behaviour
+ *     bit     14 - Direction
+ *     bit     15 - Value (if output)
+ *     bit 16..18 - SLPM pull up/down state
+ *     bit 19..20 - SLPM direction
+ *     bit 21..22 - SLPM Value (if output)
+ *     bit 23..25 - PDIS value (if input)
+ *     bit     26 - Gpio mode
+ *     bit     27 - Sleep mode
+ *
+ * to facilitate the definition, the following macros are provided
+ *
+ * PIN_CFG_DEFAULT - default config (0):
+ *                  pull up/down = disabled
+ *                  sleep mode = input/wakeup
+ *                  direction = input
+ *                  value = low
+ *                  SLPM direction = same as normal
+ *                  SLPM pull = same as normal
+ *                  SLPM value = same as normal
+ *
+ * PIN_CFG        - default config with alternate function
+ */
+
+typedef unsigned long pin_cfg_t;
+
+#define PIN_NUM_MASK           0x1ff
+#define PIN_NUM(x)             ((x) & PIN_NUM_MASK)
+
+#define PIN_ALT_SHIFT          9
+#define PIN_ALT_MASK           (0x3 << PIN_ALT_SHIFT)
+#define PIN_ALT(x)             (((x) & PIN_ALT_MASK) >> PIN_ALT_SHIFT)
+#define PIN_GPIO               (NMK_GPIO_ALT_GPIO << PIN_ALT_SHIFT)
+#define PIN_ALT_A              (NMK_GPIO_ALT_A << PIN_ALT_SHIFT)
+#define PIN_ALT_B              (NMK_GPIO_ALT_B << PIN_ALT_SHIFT)
+#define PIN_ALT_C              (NMK_GPIO_ALT_C << PIN_ALT_SHIFT)
+
+#define PIN_PULL_SHIFT         11
+#define PIN_PULL_MASK          (0x3 << PIN_PULL_SHIFT)
+#define PIN_PULL(x)            (((x) & PIN_PULL_MASK) >> PIN_PULL_SHIFT)
+#define PIN_PULL_NONE          (NMK_GPIO_PULL_NONE << PIN_PULL_SHIFT)
+#define PIN_PULL_UP            (NMK_GPIO_PULL_UP << PIN_PULL_SHIFT)
+#define PIN_PULL_DOWN          (NMK_GPIO_PULL_DOWN << PIN_PULL_SHIFT)
+
+#define PIN_SLPM_SHIFT         13
+#define PIN_SLPM_MASK          (0x1 << PIN_SLPM_SHIFT)
+#define PIN_SLPM(x)            (((x) & PIN_SLPM_MASK) >> PIN_SLPM_SHIFT)
+#define PIN_SLPM_MAKE_INPUT    (NMK_GPIO_SLPM_INPUT << PIN_SLPM_SHIFT)
+#define PIN_SLPM_NOCHANGE      (NMK_GPIO_SLPM_NOCHANGE << PIN_SLPM_SHIFT)
+/* These two replace the above in DB8500v2+ */
+#define PIN_SLPM_WAKEUP_ENABLE (NMK_GPIO_SLPM_WAKEUP_ENABLE << PIN_SLPM_SHIFT)
+#define PIN_SLPM_WAKEUP_DISABLE        (NMK_GPIO_SLPM_WAKEUP_DISABLE << PIN_SLPM_SHIFT)
+#define PIN_SLPM_USE_MUX_SETTINGS_IN_SLEEP PIN_SLPM_WAKEUP_DISABLE
+
+#define PIN_SLPM_GPIO  PIN_SLPM_WAKEUP_ENABLE /* In SLPM, pin is a gpio */
+#define PIN_SLPM_ALTFUNC PIN_SLPM_WAKEUP_DISABLE /* In SLPM, pin is altfunc */
+
+#define PIN_DIR_SHIFT          14
+#define PIN_DIR_MASK           (0x1 << PIN_DIR_SHIFT)
+#define PIN_DIR(x)             (((x) & PIN_DIR_MASK) >> PIN_DIR_SHIFT)
+#define PIN_DIR_INPUT          (0 << PIN_DIR_SHIFT)
+#define PIN_DIR_OUTPUT         (1 << PIN_DIR_SHIFT)
+
+#define PIN_VAL_SHIFT          15
+#define PIN_VAL_MASK           (0x1 << PIN_VAL_SHIFT)
+#define PIN_VAL(x)             (((x) & PIN_VAL_MASK) >> PIN_VAL_SHIFT)
+#define PIN_VAL_LOW            (0 << PIN_VAL_SHIFT)
+#define PIN_VAL_HIGH           (1 << PIN_VAL_SHIFT)
+
+#define PIN_SLPM_PULL_SHIFT    16
+#define PIN_SLPM_PULL_MASK     (0x7 << PIN_SLPM_PULL_SHIFT)
+#define PIN_SLPM_PULL(x)       \
+       (((x) & PIN_SLPM_PULL_MASK) >> PIN_SLPM_PULL_SHIFT)
+#define PIN_SLPM_PULL_NONE     \
+       ((1 + NMK_GPIO_PULL_NONE) << PIN_SLPM_PULL_SHIFT)
+#define PIN_SLPM_PULL_UP       \
+       ((1 + NMK_GPIO_PULL_UP) << PIN_SLPM_PULL_SHIFT)
+#define PIN_SLPM_PULL_DOWN     \
+       ((1 + NMK_GPIO_PULL_DOWN) << PIN_SLPM_PULL_SHIFT)
+
+#define PIN_SLPM_DIR_SHIFT     19
+#define PIN_SLPM_DIR_MASK      (0x3 << PIN_SLPM_DIR_SHIFT)
+#define PIN_SLPM_DIR(x)                \
+       (((x) & PIN_SLPM_DIR_MASK) >> PIN_SLPM_DIR_SHIFT)
+#define PIN_SLPM_DIR_INPUT     ((1 + 0) << PIN_SLPM_DIR_SHIFT)
+#define PIN_SLPM_DIR_OUTPUT    ((1 + 1) << PIN_SLPM_DIR_SHIFT)
+
+#define PIN_SLPM_VAL_SHIFT     21
+#define PIN_SLPM_VAL_MASK      (0x3 << PIN_SLPM_VAL_SHIFT)
+#define PIN_SLPM_VAL(x)                \
+       (((x) & PIN_SLPM_VAL_MASK) >> PIN_SLPM_VAL_SHIFT)
+#define PIN_SLPM_VAL_LOW       ((1 + 0) << PIN_SLPM_VAL_SHIFT)
+#define PIN_SLPM_VAL_HIGH      ((1 + 1) << PIN_SLPM_VAL_SHIFT)
+
+#define PIN_SLPM_PDIS_SHIFT            23
+#define PIN_SLPM_PDIS_MASK             (0x3 << PIN_SLPM_PDIS_SHIFT)
+#define PIN_SLPM_PDIS(x)       \
+       (((x) & PIN_SLPM_PDIS_MASK) >> PIN_SLPM_PDIS_SHIFT)
+#define PIN_SLPM_PDIS_NO_CHANGE                (0 << PIN_SLPM_PDIS_SHIFT)
+#define PIN_SLPM_PDIS_DISABLED         (1 << PIN_SLPM_PDIS_SHIFT)
+#define PIN_SLPM_PDIS_ENABLED          (2 << PIN_SLPM_PDIS_SHIFT)
+
+#define PIN_LOWEMI_SHIFT       25
+#define PIN_LOWEMI_MASK                (0x1 << PIN_LOWEMI_SHIFT)
+#define PIN_LOWEMI(x)          (((x) & PIN_LOWEMI_MASK) >> PIN_LOWEMI_SHIFT)
+#define PIN_LOWEMI_DISABLED    (0 << PIN_LOWEMI_SHIFT)
+#define PIN_LOWEMI_ENABLED     (1 << PIN_LOWEMI_SHIFT)
+
+#define PIN_GPIOMODE_SHIFT     26
+#define PIN_GPIOMODE_MASK      (0x1 << PIN_GPIOMODE_SHIFT)
+#define PIN_GPIOMODE(x)                (((x) & PIN_GPIOMODE_MASK) >> PIN_GPIOMODE_SHIFT)
+#define PIN_GPIOMODE_DISABLED  (0 << PIN_GPIOMODE_SHIFT)
+#define PIN_GPIOMODE_ENABLED   (1 << PIN_GPIOMODE_SHIFT)
+
+#define PIN_SLEEPMODE_SHIFT    27
+#define PIN_SLEEPMODE_MASK     (0x1 << PIN_SLEEPMODE_SHIFT)
+#define PIN_SLEEPMODE(x)       (((x) & PIN_SLEEPMODE_MASK) >> PIN_SLEEPMODE_SHIFT)
+#define PIN_SLEEPMODE_DISABLED (0 << PIN_SLEEPMODE_SHIFT)
+#define PIN_SLEEPMODE_ENABLED  (1 << PIN_SLEEPMODE_SHIFT)
+
+
+/* Shortcuts.  Use these instead of separate DIR, PULL, and VAL.  */
+#define PIN_INPUT_PULLDOWN     (PIN_DIR_INPUT | PIN_PULL_DOWN)
+#define PIN_INPUT_PULLUP       (PIN_DIR_INPUT | PIN_PULL_UP)
+#define PIN_INPUT_NOPULL       (PIN_DIR_INPUT | PIN_PULL_NONE)
+#define PIN_OUTPUT_LOW         (PIN_DIR_OUTPUT | PIN_VAL_LOW)
+#define PIN_OUTPUT_HIGH                (PIN_DIR_OUTPUT | PIN_VAL_HIGH)
+
+#define PIN_SLPM_INPUT_PULLDOWN        (PIN_SLPM_DIR_INPUT | PIN_SLPM_PULL_DOWN)
+#define PIN_SLPM_INPUT_PULLUP  (PIN_SLPM_DIR_INPUT | PIN_SLPM_PULL_UP)
+#define PIN_SLPM_INPUT_NOPULL  (PIN_SLPM_DIR_INPUT | PIN_SLPM_PULL_NONE)
+#define PIN_SLPM_OUTPUT_LOW    (PIN_SLPM_DIR_OUTPUT | PIN_SLPM_VAL_LOW)
+#define PIN_SLPM_OUTPUT_HIGH   (PIN_SLPM_DIR_OUTPUT | PIN_SLPM_VAL_HIGH)
+
+#define PIN_CFG_DEFAULT                (0)
+
+#define PIN_CFG(num, alt)              \
+       (PIN_CFG_DEFAULT |\
+        (PIN_NUM(num) | PIN_##alt))
+
+#define PIN_CFG_INPUT(num, alt, pull)          \
+       (PIN_CFG_DEFAULT |\
+        (PIN_NUM(num) | PIN_##alt | PIN_INPUT_##pull))
+
+#define PIN_CFG_OUTPUT(num, alt, val)          \
+       (PIN_CFG_DEFAULT |\
+        (PIN_NUM(num) | PIN_##alt | PIN_OUTPUT_##val))
+
+/*
+ * "nmk_gpio" and "NMK_GPIO" stand for "Nomadik GPIO", leaving
+ * the "gpio" namespace for generic and cross-machine functions
+ */
+
+#define GPIO_BLOCK_SHIFT 5
+#define NMK_GPIO_PER_CHIP (1 << GPIO_BLOCK_SHIFT)
+
+/* Register in the logic block */
+#define NMK_GPIO_DAT   0x00
+#define NMK_GPIO_DATS  0x04
+#define NMK_GPIO_DATC  0x08
+#define NMK_GPIO_PDIS  0x0c
+#define NMK_GPIO_DIR   0x10
+#define NMK_GPIO_DIRS  0x14
+#define NMK_GPIO_DIRC  0x18
+#define NMK_GPIO_SLPC  0x1c
+#define NMK_GPIO_AFSLA 0x20
+#define NMK_GPIO_AFSLB 0x24
+#define NMK_GPIO_LOWEMI        0x28
+
+#define NMK_GPIO_RIMSC 0x40
+#define NMK_GPIO_FIMSC 0x44
+#define NMK_GPIO_IS    0x48
+#define NMK_GPIO_IC    0x4c
+#define NMK_GPIO_RWIMSC        0x50
+#define NMK_GPIO_FWIMSC        0x54
+#define NMK_GPIO_WKS   0x58
+/* These appear in DB8540 and later ASICs */
+#define NMK_GPIO_EDGELEVEL 0x5C
+#define NMK_GPIO_LEVEL 0x60
+
+
+/* Pull up/down values */
+enum nmk_gpio_pull {
+       NMK_GPIO_PULL_NONE,
+       NMK_GPIO_PULL_UP,
+       NMK_GPIO_PULL_DOWN,
+};
+
+/* Sleep mode */
+enum nmk_gpio_slpm {
+       NMK_GPIO_SLPM_INPUT,
+       NMK_GPIO_SLPM_WAKEUP_ENABLE = NMK_GPIO_SLPM_INPUT,
+       NMK_GPIO_SLPM_NOCHANGE,
+       NMK_GPIO_SLPM_WAKEUP_DISABLE = NMK_GPIO_SLPM_NOCHANGE,
+};
+
+struct nmk_gpio_chip {
+       struct gpio_chip chip;
+       void __iomem *addr;
+       struct clk *clk;
+       unsigned int bank;
+       unsigned int parent_irq;
+       int latent_parent_irq;
+       u32 (*get_latent_status)(unsigned int bank);
+       void (*set_ioforce)(bool enable);
+       spinlock_t lock;
+       bool sleepmode;
+       /* Keep track of configured edges */
+       u32 edge_rising;
+       u32 edge_falling;
+       u32 real_wake;
+       u32 rwimsc;
+       u32 fwimsc;
+       u32 rimsc;
+       u32 fimsc;
+       u32 pull_up;
+       u32 lowemi;
+};
+
+/**
+ * struct nmk_pinctrl - state container for the Nomadik pin controller
+ * @dev: containing device pointer
+ * @pctl: corresponding pin controller device
+ * @soc: SoC data for this specific chip
+ * @prcm_base: PRCM register range virtual base
+ */
+struct nmk_pinctrl {
+       struct device *dev;
+       struct pinctrl_dev *pctl;
+       const struct nmk_pinctrl_soc_data *soc;
+       void __iomem *prcm_base;
+};
+
+static struct nmk_gpio_chip *
+nmk_gpio_chips[DIV_ROUND_UP(ARCH_NR_GPIOS, NMK_GPIO_PER_CHIP)];
+
+static DEFINE_SPINLOCK(nmk_gpio_slpm_lock);
+
+#define NUM_BANKS ARRAY_SIZE(nmk_gpio_chips)
+
+static void __nmk_gpio_set_mode(struct nmk_gpio_chip *nmk_chip,
+                               unsigned offset, int gpio_mode)
+{
+       u32 bit = 1 << offset;
+       u32 afunc, bfunc;
+
+       afunc = readl(nmk_chip->addr + NMK_GPIO_AFSLA) & ~bit;
+       bfunc = readl(nmk_chip->addr + NMK_GPIO_AFSLB) & ~bit;
+       if (gpio_mode & NMK_GPIO_ALT_A)
+               afunc |= bit;
+       if (gpio_mode & NMK_GPIO_ALT_B)
+               bfunc |= bit;
+       writel(afunc, nmk_chip->addr + NMK_GPIO_AFSLA);
+       writel(bfunc, nmk_chip->addr + NMK_GPIO_AFSLB);
+}
+
+static void __nmk_gpio_set_slpm(struct nmk_gpio_chip *nmk_chip,
+                               unsigned offset, enum nmk_gpio_slpm mode)
+{
+       u32 bit = 1 << offset;
+       u32 slpm;
+
+       slpm = readl(nmk_chip->addr + NMK_GPIO_SLPC);
+       if (mode == NMK_GPIO_SLPM_NOCHANGE)
+               slpm |= bit;
+       else
+               slpm &= ~bit;
+       writel(slpm, nmk_chip->addr + NMK_GPIO_SLPC);
+}
+
+static void __nmk_gpio_set_pull(struct nmk_gpio_chip *nmk_chip,
+                               unsigned offset, enum nmk_gpio_pull pull)
+{
+       u32 bit = 1 << offset;
+       u32 pdis;
+
+       pdis = readl(nmk_chip->addr + NMK_GPIO_PDIS);
+       if (pull == NMK_GPIO_PULL_NONE) {
+               pdis |= bit;
+               nmk_chip->pull_up &= ~bit;
+       } else {
+               pdis &= ~bit;
+       }
+
+       writel(pdis, nmk_chip->addr + NMK_GPIO_PDIS);
+
+       if (pull == NMK_GPIO_PULL_UP) {
+               nmk_chip->pull_up |= bit;
+               writel(bit, nmk_chip->addr + NMK_GPIO_DATS);
+       } else if (pull == NMK_GPIO_PULL_DOWN) {
+               nmk_chip->pull_up &= ~bit;
+               writel(bit, nmk_chip->addr + NMK_GPIO_DATC);
+       }
+}
+
+static void __nmk_gpio_set_lowemi(struct nmk_gpio_chip *nmk_chip,
+                                 unsigned offset, bool lowemi)
+{
+       u32 bit = BIT(offset);
+       bool enabled = nmk_chip->lowemi & bit;
+
+       if (lowemi == enabled)
+               return;
+
+       if (lowemi)
+               nmk_chip->lowemi |= bit;
+       else
+               nmk_chip->lowemi &= ~bit;
+
+       writel_relaxed(nmk_chip->lowemi,
+                      nmk_chip->addr + NMK_GPIO_LOWEMI);
+}
+
+static void __nmk_gpio_make_input(struct nmk_gpio_chip *nmk_chip,
+                                 unsigned offset)
+{
+       writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRC);
+}
+
+static void __nmk_gpio_set_output(struct nmk_gpio_chip *nmk_chip,
+                                 unsigned offset, int val)
+{
+       if (val)
+               writel(1 << offset, nmk_chip->addr + NMK_GPIO_DATS);
+       else
+               writel(1 << offset, nmk_chip->addr + NMK_GPIO_DATC);
+}
+
+static void __nmk_gpio_make_output(struct nmk_gpio_chip *nmk_chip,
+                                 unsigned offset, int val)
+{
+       writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRS);
+       __nmk_gpio_set_output(nmk_chip, offset, val);
+}
+
+static void __nmk_gpio_set_mode_safe(struct nmk_gpio_chip *nmk_chip,
+                                    unsigned offset, int gpio_mode,
+                                    bool glitch)
+{
+       u32 rwimsc = nmk_chip->rwimsc;
+       u32 fwimsc = nmk_chip->fwimsc;
+
+       if (glitch && nmk_chip->set_ioforce) {
+               u32 bit = BIT(offset);
+
+               /* Prevent spurious wakeups */
+               writel(rwimsc & ~bit, nmk_chip->addr + NMK_GPIO_RWIMSC);
+               writel(fwimsc & ~bit, nmk_chip->addr + NMK_GPIO_FWIMSC);
+
+               nmk_chip->set_ioforce(true);
+       }
+
+       __nmk_gpio_set_mode(nmk_chip, offset, gpio_mode);
+
+       if (glitch && nmk_chip->set_ioforce) {
+               nmk_chip->set_ioforce(false);
+
+               writel(rwimsc, nmk_chip->addr + NMK_GPIO_RWIMSC);
+               writel(fwimsc, nmk_chip->addr + NMK_GPIO_FWIMSC);
+       }
+}
+
+static void
+nmk_gpio_disable_lazy_irq(struct nmk_gpio_chip *nmk_chip, unsigned offset)
+{
+       u32 falling = nmk_chip->fimsc & BIT(offset);
+       u32 rising = nmk_chip->rimsc & BIT(offset);
+       int gpio = nmk_chip->chip.base + offset;
+       int irq = irq_find_mapping(nmk_chip->chip.irqdomain, offset);
+       struct irq_data *d = irq_get_irq_data(irq);
+
+       if (!rising && !falling)
+               return;
+
+       if (!d || !irqd_irq_disabled(d))
+               return;
+
+       if (rising) {
+               nmk_chip->rimsc &= ~BIT(offset);
+               writel_relaxed(nmk_chip->rimsc,
+                              nmk_chip->addr + NMK_GPIO_RIMSC);
+       }
+
+       if (falling) {
+               nmk_chip->fimsc &= ~BIT(offset);
+               writel_relaxed(nmk_chip->fimsc,
+                              nmk_chip->addr + NMK_GPIO_FIMSC);
+       }
+
+       dev_dbg(nmk_chip->chip.dev, "%d: clearing interrupt mask\n", gpio);
+}
+
+static void nmk_write_masked(void __iomem *reg, u32 mask, u32 value)
+{
+       u32 val;
+
+       val = readl(reg);
+       val = ((val & ~mask) | (value & mask));
+       writel(val, reg);
+}
+
+static void nmk_prcm_altcx_set_mode(struct nmk_pinctrl *npct,
+       unsigned offset, unsigned alt_num)
+{
+       int i;
+       u16 reg;
+       u8 bit;
+       u8 alt_index;
+       const struct prcm_gpiocr_altcx_pin_desc *pin_desc;
+       const u16 *gpiocr_regs;
+
+       if (!npct->prcm_base)
+               return;
+
+       if (alt_num > PRCM_IDX_GPIOCR_ALTC_MAX) {
+               dev_err(npct->dev, "PRCM GPIOCR: alternate-C%i is invalid\n",
+                       alt_num);
+               return;
+       }
+
+       for (i = 0 ; i < npct->soc->npins_altcx ; i++) {
+               if (npct->soc->altcx_pins[i].pin == offset)
+                       break;
+       }
+       if (i == npct->soc->npins_altcx) {
+               dev_dbg(npct->dev, "PRCM GPIOCR: pin %i is not found\n",
+                       offset);
+               return;
+       }
+
+       pin_desc = npct->soc->altcx_pins + i;
+       gpiocr_regs = npct->soc->prcm_gpiocr_registers;
+
+       /*
+        * If alt_num is NULL, just clear current ALTCx selection
+        * to make sure we come back to a pure ALTC selection
+        */
+       if (!alt_num) {
+               for (i = 0 ; i < PRCM_IDX_GPIOCR_ALTC_MAX ; i++) {
+                       if (pin_desc->altcx[i].used == true) {
+                               reg = gpiocr_regs[pin_desc->altcx[i].reg_index];
+                               bit = pin_desc->altcx[i].control_bit;
+                               if (readl(npct->prcm_base + reg) & BIT(bit)) {
+                                       nmk_write_masked(npct->prcm_base + reg, BIT(bit), 0);
+                                       dev_dbg(npct->dev,
+                                               "PRCM GPIOCR: pin %i: alternate-C%i has been disabled\n",
+                                               offset, i+1);
+                               }
+                       }
+               }
+               return;
+       }
+
+       alt_index = alt_num - 1;
+       if (pin_desc->altcx[alt_index].used == false) {
+               dev_warn(npct->dev,
+                       "PRCM GPIOCR: pin %i: alternate-C%i does not exist\n",
+                       offset, alt_num);
+               return;
+       }
+
+       /*
+        * Check if any other ALTCx functions are activated on this pin
+        * and disable it first.
+        */
+       for (i = 0 ; i < PRCM_IDX_GPIOCR_ALTC_MAX ; i++) {
+               if (i == alt_index)
+                       continue;
+               if (pin_desc->altcx[i].used == true) {
+                       reg = gpiocr_regs[pin_desc->altcx[i].reg_index];
+                       bit = pin_desc->altcx[i].control_bit;
+                       if (readl(npct->prcm_base + reg) & BIT(bit)) {
+                               nmk_write_masked(npct->prcm_base + reg, BIT(bit), 0);
+                               dev_dbg(npct->dev,
+                                       "PRCM GPIOCR: pin %i: alternate-C%i has been disabled\n",
+                                       offset, i+1);
+                       }
+               }
+       }
+
+       reg = gpiocr_regs[pin_desc->altcx[alt_index].reg_index];
+       bit = pin_desc->altcx[alt_index].control_bit;
+       dev_dbg(npct->dev, "PRCM GPIOCR: pin %i: alternate-C%i has been selected\n",
+               offset, alt_index+1);
+       nmk_write_masked(npct->prcm_base + reg, BIT(bit), BIT(bit));
+}
+
+/*
+ * Safe sequence used to switch IOs between GPIO and Alternate-C mode:
+ *  - Save SLPM registers
+ *  - Set SLPM=0 for the IOs you want to switch and others to 1
+ *  - Configure the GPIO registers for the IOs that are being switched
+ *  - Set IOFORCE=1
+ *  - Modify the AFLSA/B registers for the IOs that are being switched
+ *  - Set IOFORCE=0
+ *  - Restore SLPM registers
+ *  - Any spurious wake up event during switch sequence to be ignored and
+ *    cleared
+ */
+static void nmk_gpio_glitch_slpm_init(unsigned int *slpm)
+{
+       int i;
+
+       for (i = 0; i < NUM_BANKS; i++) {
+               struct nmk_gpio_chip *chip = nmk_gpio_chips[i];
+               unsigned int temp = slpm[i];
+
+               if (!chip)
+                       break;
+
+               clk_enable(chip->clk);
+
+               slpm[i] = readl(chip->addr + NMK_GPIO_SLPC);
+               writel(temp, chip->addr + NMK_GPIO_SLPC);
+       }
+}
+
+static void nmk_gpio_glitch_slpm_restore(unsigned int *slpm)
+{
+       int i;
+
+       for (i = 0; i < NUM_BANKS; i++) {
+               struct nmk_gpio_chip *chip = nmk_gpio_chips[i];
+
+               if (!chip)
+                       break;
+
+               writel(slpm[i], chip->addr + NMK_GPIO_SLPC);
+
+               clk_disable(chip->clk);
+       }
+}
+
+static int __maybe_unused nmk_prcm_gpiocr_get_mode(struct pinctrl_dev *pctldev, int gpio)
+{
+       int i;
+       u16 reg;
+       u8 bit;
+       struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
+       const struct prcm_gpiocr_altcx_pin_desc *pin_desc;
+       const u16 *gpiocr_regs;
+
+       if (!npct->prcm_base)
+               return NMK_GPIO_ALT_C;
+
+       for (i = 0; i < npct->soc->npins_altcx; i++) {
+               if (npct->soc->altcx_pins[i].pin == gpio)
+                       break;
+       }
+       if (i == npct->soc->npins_altcx)
+               return NMK_GPIO_ALT_C;
+
+       pin_desc = npct->soc->altcx_pins + i;
+       gpiocr_regs = npct->soc->prcm_gpiocr_registers;
+       for (i = 0; i < PRCM_IDX_GPIOCR_ALTC_MAX; i++) {
+               if (pin_desc->altcx[i].used == true) {
+                       reg = gpiocr_regs[pin_desc->altcx[i].reg_index];
+                       bit = pin_desc->altcx[i].control_bit;
+                       if (readl(npct->prcm_base + reg) & BIT(bit))
+                               return NMK_GPIO_ALT_C+i+1;
+               }
+       }
+       return NMK_GPIO_ALT_C;
+}
+
+int nmk_gpio_get_mode(int gpio)
+{
+       struct nmk_gpio_chip *nmk_chip;
+       u32 afunc, bfunc, bit;
+
+       nmk_chip = nmk_gpio_chips[gpio / NMK_GPIO_PER_CHIP];
+       if (!nmk_chip)
+               return -EINVAL;
+
+       bit = 1 << (gpio % NMK_GPIO_PER_CHIP);
+
+       clk_enable(nmk_chip->clk);
+
+       afunc = readl(nmk_chip->addr + NMK_GPIO_AFSLA) & bit;
+       bfunc = readl(nmk_chip->addr + NMK_GPIO_AFSLB) & bit;
+
+       clk_disable(nmk_chip->clk);
+
+       return (afunc ? NMK_GPIO_ALT_A : 0) | (bfunc ? NMK_GPIO_ALT_B : 0);
+}
+EXPORT_SYMBOL(nmk_gpio_get_mode);
+
+
+/* IRQ functions */
+static inline int nmk_gpio_get_bitmask(int gpio)
+{
+       return 1 << (gpio % NMK_GPIO_PER_CHIP);
+}
+
+static void nmk_gpio_irq_ack(struct irq_data *d)
+{
+       struct gpio_chip *chip = irq_data_get_irq_chip_data(d);
+       struct nmk_gpio_chip *nmk_chip = container_of(chip, struct nmk_gpio_chip, chip);
+
+       clk_enable(nmk_chip->clk);
+       writel(nmk_gpio_get_bitmask(d->hwirq), nmk_chip->addr + NMK_GPIO_IC);
+       clk_disable(nmk_chip->clk);
+}
+
+enum nmk_gpio_irq_type {
+       NORMAL,
+       WAKE,
+};
+
+static void __nmk_gpio_irq_modify(struct nmk_gpio_chip *nmk_chip,
+                                 int gpio, enum nmk_gpio_irq_type which,
+                                 bool enable)
+{
+       u32 bitmask = nmk_gpio_get_bitmask(gpio);
+       u32 *rimscval;
+       u32 *fimscval;
+       u32 rimscreg;
+       u32 fimscreg;
+
+       if (which == NORMAL) {
+               rimscreg = NMK_GPIO_RIMSC;
+               fimscreg = NMK_GPIO_FIMSC;
+               rimscval = &nmk_chip->rimsc;
+               fimscval = &nmk_chip->fimsc;
+       } else  {
+               rimscreg = NMK_GPIO_RWIMSC;
+               fimscreg = NMK_GPIO_FWIMSC;
+               rimscval = &nmk_chip->rwimsc;
+               fimscval = &nmk_chip->fwimsc;
+       }
+
+       /* we must individually set/clear the two edges */
+       if (nmk_chip->edge_rising & bitmask) {
+               if (enable)
+                       *rimscval |= bitmask;
+               else
+                       *rimscval &= ~bitmask;
+               writel(*rimscval, nmk_chip->addr + rimscreg);
+       }
+       if (nmk_chip->edge_falling & bitmask) {
+               if (enable)
+                       *fimscval |= bitmask;
+               else
+                       *fimscval &= ~bitmask;
+               writel(*fimscval, nmk_chip->addr + fimscreg);
+       }
+}
+
+static void __nmk_gpio_set_wake(struct nmk_gpio_chip *nmk_chip,
+                               int gpio, bool on)
+{
+       /*
+        * Ensure WAKEUP_ENABLE is on.  No need to disable it if wakeup is
+        * disabled, since setting SLPM to 1 increases power consumption, and
+        * wakeup is anyhow controlled by the RIMSC and FIMSC registers.
+        */
+       if (nmk_chip->sleepmode && on) {
+               __nmk_gpio_set_slpm(nmk_chip, gpio % NMK_GPIO_PER_CHIP,
+                                   NMK_GPIO_SLPM_WAKEUP_ENABLE);
+       }
+
+       __nmk_gpio_irq_modify(nmk_chip, gpio, WAKE, on);
+}
+
+static int nmk_gpio_irq_maskunmask(struct irq_data *d, bool enable)
+{
+       struct nmk_gpio_chip *nmk_chip;
+       unsigned long flags;
+       u32 bitmask;
+
+       nmk_chip = irq_data_get_irq_chip_data(d);
+       bitmask = nmk_gpio_get_bitmask(d->hwirq);
+       if (!nmk_chip)
+               return -EINVAL;
+
+       clk_enable(nmk_chip->clk);
+       spin_lock_irqsave(&nmk_gpio_slpm_lock, flags);
+       spin_lock(&nmk_chip->lock);
+
+       __nmk_gpio_irq_modify(nmk_chip, d->hwirq, NORMAL, enable);
+
+       if (!(nmk_chip->real_wake & bitmask))
+               __nmk_gpio_set_wake(nmk_chip, d->hwirq, enable);
+
+       spin_unlock(&nmk_chip->lock);
+       spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags);
+       clk_disable(nmk_chip->clk);
+
+       return 0;
+}
+
+static void nmk_gpio_irq_mask(struct irq_data *d)
+{
+       nmk_gpio_irq_maskunmask(d, false);
+}
+
+static void nmk_gpio_irq_unmask(struct irq_data *d)
+{
+       nmk_gpio_irq_maskunmask(d, true);
+}
+
+static int nmk_gpio_irq_set_wake(struct irq_data *d, unsigned int on)
+{
+       struct nmk_gpio_chip *nmk_chip;
+       unsigned long flags;
+       u32 bitmask;
+
+       nmk_chip = irq_data_get_irq_chip_data(d);
+       if (!nmk_chip)
+               return -EINVAL;
+       bitmask = nmk_gpio_get_bitmask(d->hwirq);
+
+       clk_enable(nmk_chip->clk);
+       spin_lock_irqsave(&nmk_gpio_slpm_lock, flags);
+       spin_lock(&nmk_chip->lock);
+
+       if (irqd_irq_disabled(d))
+               __nmk_gpio_set_wake(nmk_chip, d->hwirq, on);
+
+       if (on)
+               nmk_chip->real_wake |= bitmask;
+       else
+               nmk_chip->real_wake &= ~bitmask;
+
+       spin_unlock(&nmk_chip->lock);
+       spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags);
+       clk_disable(nmk_chip->clk);
+
+       return 0;
+}
+
+static int nmk_gpio_irq_set_type(struct irq_data *d, unsigned int type)
+{
+       bool enabled = !irqd_irq_disabled(d);
+       bool wake = irqd_is_wakeup_set(d);
+       struct nmk_gpio_chip *nmk_chip;
+       unsigned long flags;
+       u32 bitmask;
+
+       nmk_chip = irq_data_get_irq_chip_data(d);
+       bitmask = nmk_gpio_get_bitmask(d->hwirq);
+       if (!nmk_chip)
+               return -EINVAL;
+       if (type & IRQ_TYPE_LEVEL_HIGH)
+               return -EINVAL;
+       if (type & IRQ_TYPE_LEVEL_LOW)
+               return -EINVAL;
+
+       clk_enable(nmk_chip->clk);
+       spin_lock_irqsave(&nmk_chip->lock, flags);
+
+       if (enabled)
+               __nmk_gpio_irq_modify(nmk_chip, d->hwirq, NORMAL, false);
+
+       if (enabled || wake)
+               __nmk_gpio_irq_modify(nmk_chip, d->hwirq, WAKE, false);
+
+       nmk_chip->edge_rising &= ~bitmask;
+       if (type & IRQ_TYPE_EDGE_RISING)
+               nmk_chip->edge_rising |= bitmask;
+
+       nmk_chip->edge_falling &= ~bitmask;
+       if (type & IRQ_TYPE_EDGE_FALLING)
+               nmk_chip->edge_falling |= bitmask;
+
+       if (enabled)
+               __nmk_gpio_irq_modify(nmk_chip, d->hwirq, NORMAL, true);
+
+       if (enabled || wake)
+               __nmk_gpio_irq_modify(nmk_chip, d->hwirq, WAKE, true);
+
+       spin_unlock_irqrestore(&nmk_chip->lock, flags);
+       clk_disable(nmk_chip->clk);
+
+       return 0;
+}
+
+static unsigned int nmk_gpio_irq_startup(struct irq_data *d)
+{
+       struct nmk_gpio_chip *nmk_chip = irq_data_get_irq_chip_data(d);
+
+       clk_enable(nmk_chip->clk);
+       nmk_gpio_irq_unmask(d);
+       return 0;
+}
+
+static void nmk_gpio_irq_shutdown(struct irq_data *d)
+{
+       struct nmk_gpio_chip *nmk_chip = irq_data_get_irq_chip_data(d);
+
+       nmk_gpio_irq_mask(d);
+       clk_disable(nmk_chip->clk);
+}
+
+static struct irq_chip nmk_gpio_irq_chip = {
+       .name           = "Nomadik-GPIO",
+       .irq_ack        = nmk_gpio_irq_ack,
+       .irq_mask       = nmk_gpio_irq_mask,
+       .irq_unmask     = nmk_gpio_irq_unmask,
+       .irq_set_type   = nmk_gpio_irq_set_type,
+       .irq_set_wake   = nmk_gpio_irq_set_wake,
+       .irq_startup    = nmk_gpio_irq_startup,
+       .irq_shutdown   = nmk_gpio_irq_shutdown,
+       .flags          = IRQCHIP_MASK_ON_SUSPEND,
+};
+
+static void __nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc,
+                                  u32 status)
+{
+       struct irq_chip *host_chip = irq_get_chip(irq);
+       struct gpio_chip *chip = irq_desc_get_handler_data(desc);
+
+       chained_irq_enter(host_chip, desc);
+
+       while (status) {
+               int bit = __ffs(status);
+
+               generic_handle_irq(irq_find_mapping(chip->irqdomain, bit));
+               status &= ~BIT(bit);
+       }
+
+       chained_irq_exit(host_chip, desc);
+}
+
+static void nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+       struct gpio_chip *chip = irq_desc_get_handler_data(desc);
+       struct nmk_gpio_chip *nmk_chip = container_of(chip, struct nmk_gpio_chip, chip);
+       u32 status;
+
+       clk_enable(nmk_chip->clk);
+       status = readl(nmk_chip->addr + NMK_GPIO_IS);
+       clk_disable(nmk_chip->clk);
+
+       __nmk_gpio_irq_handler(irq, desc, status);
+}
+
+static void nmk_gpio_latent_irq_handler(unsigned int irq,
+                                          struct irq_desc *desc)
+{
+       struct gpio_chip *chip = irq_desc_get_handler_data(desc);
+       struct nmk_gpio_chip *nmk_chip = container_of(chip, struct nmk_gpio_chip, chip);
+       u32 status = nmk_chip->get_latent_status(nmk_chip->bank);
+
+       __nmk_gpio_irq_handler(irq, desc, status);
+}
+
+/* I/O Functions */
+
+static int nmk_gpio_request(struct gpio_chip *chip, unsigned offset)
+{
+       /*
+        * Map back to global GPIO space and request muxing, the direction
+        * parameter does not matter for this controller.
+        */
+       int gpio = chip->base + offset;
+
+       return pinctrl_request_gpio(gpio);
+}
+
+static void nmk_gpio_free(struct gpio_chip *chip, unsigned offset)
+{
+       int gpio = chip->base + offset;
+
+       pinctrl_free_gpio(gpio);
+}
+
+static int nmk_gpio_make_input(struct gpio_chip *chip, unsigned offset)
+{
+       struct nmk_gpio_chip *nmk_chip =
+               container_of(chip, struct nmk_gpio_chip, chip);
+
+       clk_enable(nmk_chip->clk);
+
+       writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRC);
+
+       clk_disable(nmk_chip->clk);
+
+       return 0;
+}
+
+static int nmk_gpio_get_input(struct gpio_chip *chip, unsigned offset)
+{
+       struct nmk_gpio_chip *nmk_chip =
+               container_of(chip, struct nmk_gpio_chip, chip);
+       u32 bit = 1 << offset;
+       int value;
+
+       clk_enable(nmk_chip->clk);
+
+       value = (readl(nmk_chip->addr + NMK_GPIO_DAT) & bit) != 0;
+
+       clk_disable(nmk_chip->clk);
+
+       return value;
+}
+
+static void nmk_gpio_set_output(struct gpio_chip *chip, unsigned offset,
+                               int val)
+{
+       struct nmk_gpio_chip *nmk_chip =
+               container_of(chip, struct nmk_gpio_chip, chip);
+
+       clk_enable(nmk_chip->clk);
+
+       __nmk_gpio_set_output(nmk_chip, offset, val);
+
+       clk_disable(nmk_chip->clk);
+}
+
+static int nmk_gpio_make_output(struct gpio_chip *chip, unsigned offset,
+                               int val)
+{
+       struct nmk_gpio_chip *nmk_chip =
+               container_of(chip, struct nmk_gpio_chip, chip);
+
+       clk_enable(nmk_chip->clk);
+
+       __nmk_gpio_make_output(nmk_chip, offset, val);
+
+       clk_disable(nmk_chip->clk);
+
+       return 0;
+}
+
+#ifdef CONFIG_DEBUG_FS
+
+#include <linux/seq_file.h>
+
+static void nmk_gpio_dbg_show_one(struct seq_file *s,
+       struct pinctrl_dev *pctldev, struct gpio_chip *chip,
+       unsigned offset, unsigned gpio)
+{
+       const char *label = gpiochip_is_requested(chip, offset);
+       struct nmk_gpio_chip *nmk_chip =
+               container_of(chip, struct nmk_gpio_chip, chip);
+       int mode;
+       bool is_out;
+       bool pull;
+       u32 bit = 1 << offset;
+       const char *modes[] = {
+               [NMK_GPIO_ALT_GPIO]     = "gpio",
+               [NMK_GPIO_ALT_A]        = "altA",
+               [NMK_GPIO_ALT_B]        = "altB",
+               [NMK_GPIO_ALT_C]        = "altC",
+               [NMK_GPIO_ALT_C+1]      = "altC1",
+               [NMK_GPIO_ALT_C+2]      = "altC2",
+               [NMK_GPIO_ALT_C+3]      = "altC3",
+               [NMK_GPIO_ALT_C+4]      = "altC4",
+       };
+
+       clk_enable(nmk_chip->clk);
+       is_out = !!(readl(nmk_chip->addr + NMK_GPIO_DIR) & bit);
+       pull = !(readl(nmk_chip->addr + NMK_GPIO_PDIS) & bit);
+       mode = nmk_gpio_get_mode(gpio);
+       if ((mode == NMK_GPIO_ALT_C) && pctldev)
+               mode = nmk_prcm_gpiocr_get_mode(pctldev, gpio);
+
+       seq_printf(s, " gpio-%-3d (%-20.20s) %s %s %s %s",
+                  gpio, label ?: "(none)",
+                  is_out ? "out" : "in ",
+                  chip->get
+                  ? (chip->get(chip, offset) ? "hi" : "lo")
+                  : "?  ",
+                  (mode < 0) ? "unknown" : modes[mode],
+                  pull ? "pull" : "none");
+
+       if (!is_out) {
+               int irq = gpio_to_irq(gpio);
+               struct irq_desc *desc = irq_to_desc(irq);
+
+               /* This races with request_irq(), set_irq_type(),
+                * and set_irq_wake() ... but those are "rare".
+                */
+               if (irq > 0 && desc && desc->action) {
+                       char *trigger;
+                       u32 bitmask = nmk_gpio_get_bitmask(gpio);
+
+                       if (nmk_chip->edge_rising & bitmask)
+                               trigger = "edge-rising";
+                       else if (nmk_chip->edge_falling & bitmask)
+                               trigger = "edge-falling";
+                       else
+                               trigger = "edge-undefined";
+
+                       seq_printf(s, " irq-%d %s%s",
+                                  irq, trigger,
+                                  irqd_is_wakeup_set(&desc->irq_data)
+                                  ? " wakeup" : "");
+               }
+       }
+       clk_disable(nmk_chip->clk);
+}
+
+static void nmk_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
+{
+       unsigned                i;
+       unsigned                gpio = chip->base;
+
+       for (i = 0; i < chip->ngpio; i++, gpio++) {
+               nmk_gpio_dbg_show_one(s, NULL, chip, i, gpio);
+               seq_printf(s, "\n");
+       }
+}
+
+#else
+static inline void nmk_gpio_dbg_show_one(struct seq_file *s,
+                                        struct pinctrl_dev *pctldev,
+                                        struct gpio_chip *chip,
+                                        unsigned offset, unsigned gpio)
+{
+}
+#define nmk_gpio_dbg_show      NULL
+#endif
+
+/* This structure is replicated for each GPIO block allocated at probe time */
+static struct gpio_chip nmk_gpio_template = {
+       .request                = nmk_gpio_request,
+       .free                   = nmk_gpio_free,
+       .direction_input        = nmk_gpio_make_input,
+       .get                    = nmk_gpio_get_input,
+       .direction_output       = nmk_gpio_make_output,
+       .set                    = nmk_gpio_set_output,
+       .dbg_show               = nmk_gpio_dbg_show,
+       .can_sleep              = false,
+};
+
+void nmk_gpio_clocks_enable(void)
+{
+       int i;
+
+       for (i = 0; i < NUM_BANKS; i++) {
+               struct nmk_gpio_chip *chip = nmk_gpio_chips[i];
+
+               if (!chip)
+                       continue;
+
+               clk_enable(chip->clk);
+       }
+}
+
+void nmk_gpio_clocks_disable(void)
+{
+       int i;
+
+       for (i = 0; i < NUM_BANKS; i++) {
+               struct nmk_gpio_chip *chip = nmk_gpio_chips[i];
+
+               if (!chip)
+                       continue;
+
+               clk_disable(chip->clk);
+       }
+}
+
+/*
+ * Called from the suspend/resume path to only keep the real wakeup interrupts
+ * (those that have had set_irq_wake() called on them) as wakeup interrupts,
+ * and not the rest of the interrupts which we needed to have as wakeups for
+ * cpuidle.
+ *
+ * PM ops are not used since this needs to be done at the end, after all the
+ * other drivers are done with their suspend callbacks.
+ */
+void nmk_gpio_wakeups_suspend(void)
+{
+       int i;
+
+       for (i = 0; i < NUM_BANKS; i++) {
+               struct nmk_gpio_chip *chip = nmk_gpio_chips[i];
+
+               if (!chip)
+                       break;
+
+               clk_enable(chip->clk);
+
+               writel(chip->rwimsc & chip->real_wake,
+                      chip->addr + NMK_GPIO_RWIMSC);
+               writel(chip->fwimsc & chip->real_wake,
+                      chip->addr + NMK_GPIO_FWIMSC);
+
+               clk_disable(chip->clk);
+       }
+}
+
+void nmk_gpio_wakeups_resume(void)
+{
+       int i;
+
+       for (i = 0; i < NUM_BANKS; i++) {
+               struct nmk_gpio_chip *chip = nmk_gpio_chips[i];
+
+               if (!chip)
+                       break;
+
+               clk_enable(chip->clk);
+
+               writel(chip->rwimsc, chip->addr + NMK_GPIO_RWIMSC);
+               writel(chip->fwimsc, chip->addr + NMK_GPIO_FWIMSC);
+
+               clk_disable(chip->clk);
+       }
+}
+
+/*
+ * Read the pull up/pull down status.
+ * A bit set in 'pull_up' means that pull up
+ * is selected if pull is enabled in PDIS register.
+ * Note: only pull up/down set via this driver can
+ * be detected due to HW limitations.
+ */
+void nmk_gpio_read_pull(int gpio_bank, u32 *pull_up)
+{
+       if (gpio_bank < NUM_BANKS) {
+               struct nmk_gpio_chip *chip = nmk_gpio_chips[gpio_bank];
+
+               if (!chip)
+                       return;
+
+               *pull_up = chip->pull_up;
+       }
+}
+
+static int nmk_gpio_probe(struct platform_device *dev)
+{
+       struct device_node *np = dev->dev.of_node;
+       struct nmk_gpio_chip *nmk_chip;
+       struct gpio_chip *chip;
+       struct resource *res;
+       struct clk *clk;
+       int latent_irq;
+       bool supports_sleepmode;
+       void __iomem *base;
+       int irq;
+       int ret;
+
+       if (of_get_property(np, "st,supports-sleepmode", NULL))
+               supports_sleepmode = true;
+       else
+               supports_sleepmode = false;
+
+       if (of_property_read_u32(np, "gpio-bank", &dev->id)) {
+               dev_err(&dev->dev, "gpio-bank property not found\n");
+               return -EINVAL;
+       }
+
+       irq = platform_get_irq(dev, 0);
+       if (irq < 0)
+               return irq;
+
+       /* It's OK for this IRQ not to be present */
+       latent_irq = platform_get_irq(dev, 1);
+
+       res = platform_get_resource(dev, IORESOURCE_MEM, 0);
+       base = devm_ioremap_resource(&dev->dev, res);
+       if (IS_ERR(base))
+               return PTR_ERR(base);
+
+       clk = devm_clk_get(&dev->dev, NULL);
+       if (IS_ERR(clk))
+               return PTR_ERR(clk);
+       clk_prepare(clk);
+
+       nmk_chip = devm_kzalloc(&dev->dev, sizeof(*nmk_chip), GFP_KERNEL);
+       if (!nmk_chip)
+               return -ENOMEM;
+
+       /*
+        * The virt address in nmk_chip->addr is in the nomadik register space,
+        * so we can simply convert the resource address, without remapping
+        */
+       nmk_chip->bank = dev->id;
+       nmk_chip->clk = clk;
+       nmk_chip->addr = base;
+       nmk_chip->chip = nmk_gpio_template;
+       nmk_chip->parent_irq = irq;
+       nmk_chip->latent_parent_irq = latent_irq;
+       nmk_chip->sleepmode = supports_sleepmode;
+       spin_lock_init(&nmk_chip->lock);
+
+       chip = &nmk_chip->chip;
+       chip->base = dev->id * NMK_GPIO_PER_CHIP;
+       chip->ngpio = NMK_GPIO_PER_CHIP;
+       chip->label = dev_name(&dev->dev);
+       chip->dev = &dev->dev;
+       chip->owner = THIS_MODULE;
+
+       clk_enable(nmk_chip->clk);
+       nmk_chip->lowemi = readl_relaxed(nmk_chip->addr + NMK_GPIO_LOWEMI);
+       clk_disable(nmk_chip->clk);
+       chip->of_node = np;
+
+       ret = gpiochip_add(&nmk_chip->chip);
+       if (ret)
+               return ret;
+
+       BUG_ON(nmk_chip->bank >= ARRAY_SIZE(nmk_gpio_chips));
+
+       nmk_gpio_chips[nmk_chip->bank] = nmk_chip;
+
+       platform_set_drvdata(dev, nmk_chip);
+
+       /*
+        * Let the generic code handle this edge IRQ, the the chained
+        * handler will perform the actual work of handling the parent
+        * interrupt.
+        */
+       ret = gpiochip_irqchip_add(&nmk_chip->chip,
+                                  &nmk_gpio_irq_chip,
+                                  0,
+                                  handle_edge_irq,
+                                  IRQ_TYPE_EDGE_FALLING);
+       if (ret) {
+               dev_err(&dev->dev, "could not add irqchip\n");
+               ret = gpiochip_remove(&nmk_chip->chip);
+               return -ENODEV;
+       }
+       /* Then register the chain on the parent IRQ */
+       gpiochip_set_chained_irqchip(&nmk_chip->chip,
+                                    &nmk_gpio_irq_chip,
+                                    nmk_chip->parent_irq,
+                                    nmk_gpio_irq_handler);
+       if (nmk_chip->latent_parent_irq > 0)
+               gpiochip_set_chained_irqchip(&nmk_chip->chip,
+                                            &nmk_gpio_irq_chip,
+                                            nmk_chip->latent_parent_irq,
+                                            nmk_gpio_latent_irq_handler);
+
+       dev_info(&dev->dev, "at address %p\n", nmk_chip->addr);
+
+       return 0;
+}
+
+static int nmk_get_groups_cnt(struct pinctrl_dev *pctldev)
+{
+       struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
+
+       return npct->soc->ngroups;
+}
+
+static const char *nmk_get_group_name(struct pinctrl_dev *pctldev,
+                                      unsigned selector)
+{
+       struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
+
+       return npct->soc->groups[selector].name;
+}
+
+static int nmk_get_group_pins(struct pinctrl_dev *pctldev, unsigned selector,
+                             const unsigned **pins,
+                             unsigned *num_pins)
+{
+       struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
+
+       *pins = npct->soc->groups[selector].pins;
+       *num_pins = npct->soc->groups[selector].npins;
+       return 0;
+}
+
+static struct pinctrl_gpio_range *
+nmk_match_gpio_range(struct pinctrl_dev *pctldev, unsigned offset)
+{
+       struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
+       int i;
+
+       for (i = 0; i < npct->soc->gpio_num_ranges; i++) {
+               struct pinctrl_gpio_range *range;
+
+               range = &npct->soc->gpio_ranges[i];
+               if (offset >= range->pin_base &&
+                   offset <= (range->pin_base + range->npins - 1))
+                       return range;
+       }
+       return NULL;
+}
+
+static void nmk_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
+                  unsigned offset)
+{
+       struct pinctrl_gpio_range *range;
+       struct gpio_chip *chip;
+
+       range = nmk_match_gpio_range(pctldev, offset);
+       if (!range || !range->gc) {
+               seq_printf(s, "invalid pin offset");
+               return;
+       }
+       chip = range->gc;
+       nmk_gpio_dbg_show_one(s, pctldev, chip, offset - chip->base, offset);
+}
+
+static void nmk_pinctrl_dt_free_map(struct pinctrl_dev *pctldev,
+               struct pinctrl_map *map, unsigned num_maps)
+{
+       int i;
+
+       for (i = 0; i < num_maps; i++)
+               if (map[i].type == PIN_MAP_TYPE_CONFIGS_PIN)
+                       kfree(map[i].data.configs.configs);
+       kfree(map);
+}
+
+static int nmk_dt_reserve_map(struct pinctrl_map **map, unsigned *reserved_maps,
+               unsigned *num_maps, unsigned reserve)
+{
+       unsigned old_num = *reserved_maps;
+       unsigned new_num = *num_maps + reserve;
+       struct pinctrl_map *new_map;
+
+       if (old_num >= new_num)
+               return 0;
+
+       new_map = krealloc(*map, sizeof(*new_map) * new_num, GFP_KERNEL);
+       if (!new_map)
+               return -ENOMEM;
+
+       memset(new_map + old_num, 0, (new_num - old_num) * sizeof(*new_map));
+
+       *map = new_map;
+       *reserved_maps = new_num;
+
+       return 0;
+}
+
+static int nmk_dt_add_map_mux(struct pinctrl_map **map, unsigned *reserved_maps,
+               unsigned *num_maps, const char *group,
+               const char *function)
+{
+       if (*num_maps == *reserved_maps)
+               return -ENOSPC;
+
+       (*map)[*num_maps].type = PIN_MAP_TYPE_MUX_GROUP;
+       (*map)[*num_maps].data.mux.group = group;
+       (*map)[*num_maps].data.mux.function = function;
+       (*num_maps)++;
+
+       return 0;
+}
+
+static int nmk_dt_add_map_configs(struct pinctrl_map **map,
+               unsigned *reserved_maps,
+               unsigned *num_maps, const char *group,
+               unsigned long *configs, unsigned num_configs)
+{
+       unsigned long *dup_configs;
+
+       if (*num_maps == *reserved_maps)
+               return -ENOSPC;
+
+       dup_configs = kmemdup(configs, num_configs * sizeof(*dup_configs),
+                             GFP_KERNEL);
+       if (!dup_configs)
+               return -ENOMEM;
+
+       (*map)[*num_maps].type = PIN_MAP_TYPE_CONFIGS_PIN;
+
+       (*map)[*num_maps].data.configs.group_or_pin = group;
+       (*map)[*num_maps].data.configs.configs = dup_configs;
+       (*map)[*num_maps].data.configs.num_configs = num_configs;
+       (*num_maps)++;
+
+       return 0;
+}
+
+#define NMK_CONFIG_PIN(x, y) { .property = x, .config = y, }
+#define NMK_CONFIG_PIN_ARRAY(x, y) { .property = x, .choice = y, \
+       .size = ARRAY_SIZE(y), }
+
+static const unsigned long nmk_pin_input_modes[] = {
+       PIN_INPUT_NOPULL,
+       PIN_INPUT_PULLUP,
+       PIN_INPUT_PULLDOWN,
+};
+
+static const unsigned long nmk_pin_output_modes[] = {
+       PIN_OUTPUT_LOW,
+       PIN_OUTPUT_HIGH,
+       PIN_DIR_OUTPUT,
+};
+
+static const unsigned long nmk_pin_sleep_modes[] = {
+       PIN_SLEEPMODE_DISABLED,
+       PIN_SLEEPMODE_ENABLED,
+};
+
+static const unsigned long nmk_pin_sleep_input_modes[] = {
+       PIN_SLPM_INPUT_NOPULL,
+       PIN_SLPM_INPUT_PULLUP,
+       PIN_SLPM_INPUT_PULLDOWN,
+       PIN_SLPM_DIR_INPUT,
+};
+
+static const unsigned long nmk_pin_sleep_output_modes[] = {
+       PIN_SLPM_OUTPUT_LOW,
+       PIN_SLPM_OUTPUT_HIGH,
+       PIN_SLPM_DIR_OUTPUT,
+};
+
+static const unsigned long nmk_pin_sleep_wakeup_modes[] = {
+       PIN_SLPM_WAKEUP_DISABLE,
+       PIN_SLPM_WAKEUP_ENABLE,
+};
+
+static const unsigned long nmk_pin_gpio_modes[] = {
+       PIN_GPIOMODE_DISABLED,
+       PIN_GPIOMODE_ENABLED,
+};
+
+static const unsigned long nmk_pin_sleep_pdis_modes[] = {
+       PIN_SLPM_PDIS_DISABLED,
+       PIN_SLPM_PDIS_ENABLED,
+};
+
+struct nmk_cfg_param {
+       const char *property;
+       unsigned long config;
+       const unsigned long *choice;
+       int size;
+};
+
+static const struct nmk_cfg_param nmk_cfg_params[] = {
+       NMK_CONFIG_PIN_ARRAY("ste,input",               nmk_pin_input_modes),
+       NMK_CONFIG_PIN_ARRAY("ste,output",              nmk_pin_output_modes),
+       NMK_CONFIG_PIN_ARRAY("ste,sleep",               nmk_pin_sleep_modes),
+       NMK_CONFIG_PIN_ARRAY("ste,sleep-input",         nmk_pin_sleep_input_modes),
+       NMK_CONFIG_PIN_ARRAY("ste,sleep-output",        nmk_pin_sleep_output_modes),
+       NMK_CONFIG_PIN_ARRAY("ste,sleep-wakeup",        nmk_pin_sleep_wakeup_modes),
+       NMK_CONFIG_PIN_ARRAY("ste,gpio",                nmk_pin_gpio_modes),
+       NMK_CONFIG_PIN_ARRAY("ste,sleep-pull-disable",  nmk_pin_sleep_pdis_modes),
+};
+
+static int nmk_dt_pin_config(int index, int val, unsigned long *config)
+{
+       int ret = 0;
+
+       if (nmk_cfg_params[index].choice == NULL)
+               *config = nmk_cfg_params[index].config;
+       else {
+               /* test if out of range */
+               if  (val < nmk_cfg_params[index].size) {
+                       *config = nmk_cfg_params[index].config |
+                               nmk_cfg_params[index].choice[val];
+               }
+       }
+       return ret;
+}
+
+static const char *nmk_find_pin_name(struct pinctrl_dev *pctldev, const char *pin_name)
+{
+       int i, pin_number;
+       struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
+
+       if (sscanf((char *)pin_name, "GPIO%d", &pin_number) == 1)
+               for (i = 0; i < npct->soc->npins; i++)
+                       if (npct->soc->pins[i].number == pin_number)
+                               return npct->soc->pins[i].name;
+       return NULL;
+}
+
+static bool nmk_pinctrl_dt_get_config(struct device_node *np,
+               unsigned long *configs)
+{
+       bool has_config = 0;
+       unsigned long cfg = 0;
+       int i, val, ret;
+
+       for (i = 0; i < ARRAY_SIZE(nmk_cfg_params); i++) {
+               ret = of_property_read_u32(np,
+                               nmk_cfg_params[i].property, &val);
+               if (ret != -EINVAL) {
+                       if (nmk_dt_pin_config(i, val, &cfg) == 0) {
+                               *configs |= cfg;
+                               has_config = 1;
+                       }
+               }
+       }
+
+       return has_config;
+}
+
+static int nmk_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
+               struct device_node *np,
+               struct pinctrl_map **map,
+               unsigned *reserved_maps,
+               unsigned *num_maps)
+{
+       int ret;
+       const char *function = NULL;
+       unsigned long configs = 0;
+       bool has_config = 0;
+       unsigned reserve = 0;
+       struct property *prop;
+       const char *group, *gpio_name;
+       struct device_node *np_config;
+
+       ret = of_property_read_string(np, "ste,function", &function);
+       if (ret >= 0)
+               reserve = 1;
+
+       has_config = nmk_pinctrl_dt_get_config(np, &configs);
+
+       np_config = of_parse_phandle(np, "ste,config", 0);
+       if (np_config)
+               has_config |= nmk_pinctrl_dt_get_config(np_config, &configs);
+
+       ret = of_property_count_strings(np, "ste,pins");
+       if (ret < 0)
+               goto exit;
+
+       if (has_config)
+               reserve++;
+
+       reserve *= ret;
+
+       ret = nmk_dt_reserve_map(map, reserved_maps, num_maps, reserve);
+       if (ret < 0)
+               goto exit;
+
+       of_property_for_each_string(np, "ste,pins", prop, group) {
+               if (function) {
+                       ret = nmk_dt_add_map_mux(map, reserved_maps, num_maps,
+                                         group, function);
+                       if (ret < 0)
+                               goto exit;
+               }
+               if (has_config) {
+                       gpio_name = nmk_find_pin_name(pctldev, group);
+
+                       ret = nmk_dt_add_map_configs(map, reserved_maps, num_maps,
+                                             gpio_name, &configs, 1);
+                       if (ret < 0)
+                               goto exit;
+               }
+
+       }
+exit:
+       return ret;
+}
+
+static int nmk_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
+                                struct device_node *np_config,
+                                struct pinctrl_map **map, unsigned *num_maps)
+{
+       unsigned reserved_maps;
+       struct device_node *np;
+       int ret;
+
+       reserved_maps = 0;
+       *map = NULL;
+       *num_maps = 0;
+
+       for_each_child_of_node(np_config, np) {
+               ret = nmk_pinctrl_dt_subnode_to_map(pctldev, np, map,
+                               &reserved_maps, num_maps);
+               if (ret < 0) {
+                       nmk_pinctrl_dt_free_map(pctldev, *map, *num_maps);
+                       return ret;
+               }
+       }
+
+       return 0;
+}
+
+static const struct pinctrl_ops nmk_pinctrl_ops = {
+       .get_groups_count = nmk_get_groups_cnt,
+       .get_group_name = nmk_get_group_name,
+       .get_group_pins = nmk_get_group_pins,
+       .pin_dbg_show = nmk_pin_dbg_show,
+       .dt_node_to_map = nmk_pinctrl_dt_node_to_map,
+       .dt_free_map = nmk_pinctrl_dt_free_map,
+};
+
+static int nmk_pmx_get_funcs_cnt(struct pinctrl_dev *pctldev)
+{
+       struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
+
+       return npct->soc->nfunctions;
+}
+
+static const char *nmk_pmx_get_func_name(struct pinctrl_dev *pctldev,
+                                        unsigned function)
+{
+       struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
+
+       return npct->soc->functions[function].name;
+}
+
+static int nmk_pmx_get_func_groups(struct pinctrl_dev *pctldev,
+                                  unsigned function,
+                                  const char * const **groups,
+                                  unsigned * const num_groups)
+{
+       struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
+
+       *groups = npct->soc->functions[function].groups;
+       *num_groups = npct->soc->functions[function].ngroups;
+
+       return 0;
+}
+
+static int nmk_pmx_enable(struct pinctrl_dev *pctldev, unsigned function,
+                         unsigned group)
+{
+       struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
+       const struct nmk_pingroup *g;
+       static unsigned int slpm[NUM_BANKS];
+       unsigned long flags = 0;
+       bool glitch;
+       int ret = -EINVAL;
+       int i;
+
+       g = &npct->soc->groups[group];
+
+       if (g->altsetting < 0)
+               return -EINVAL;
+
+       dev_dbg(npct->dev, "enable group %s, %u pins\n", g->name, g->npins);
+
+       /*
+        * If we're setting altfunc C by setting both AFSLA and AFSLB to 1,
+        * we may pass through an undesired state. In this case we take
+        * some extra care.
+        *
+        * Safe sequence used to switch IOs between GPIO and Alternate-C mode:
+        *  - Save SLPM registers (since we have a shadow register in the
+        *    nmk_chip we're using that as backup)
+        *  - Set SLPM=0 for the IOs you want to switch and others to 1
+        *  - Configure the GPIO registers for the IOs that are being switched
+        *  - Set IOFORCE=1
+        *  - Modify the AFLSA/B registers for the IOs that are being switched
+        *  - Set IOFORCE=0
+        *  - Restore SLPM registers
+        *  - Any spurious wake up event during switch sequence to be ignored
+        *    and cleared
+        *
+        * We REALLY need to save ALL slpm registers, because the external
+        * IOFORCE will switch *all* ports to their sleepmode setting to as
+        * to avoid glitches. (Not just one port!)
+        */
+       glitch = ((g->altsetting & NMK_GPIO_ALT_C) == NMK_GPIO_ALT_C);
+
+       if (glitch) {
+               spin_lock_irqsave(&nmk_gpio_slpm_lock, flags);
+
+               /* Initially don't put any pins to sleep when switching */
+               memset(slpm, 0xff, sizeof(slpm));
+
+               /*
+                * Then mask the pins that need to be sleeping now when we're
+                * switching to the ALT C function.
+                */
+               for (i = 0; i < g->npins; i++)
+                       slpm[g->pins[i] / NMK_GPIO_PER_CHIP] &= ~BIT(g->pins[i]);
+               nmk_gpio_glitch_slpm_init(slpm);
+       }
+
+       for (i = 0; i < g->npins; i++) {
+               struct pinctrl_gpio_range *range;
+               struct nmk_gpio_chip *nmk_chip;
+               struct gpio_chip *chip;
+               unsigned bit;
+
+               range = nmk_match_gpio_range(pctldev, g->pins[i]);
+               if (!range) {
+                       dev_err(npct->dev,
+                               "invalid pin offset %d in group %s at index %d\n",
+                               g->pins[i], g->name, i);
+                       goto out_glitch;
+               }
+               if (!range->gc) {
+                       dev_err(npct->dev, "GPIO chip missing in range for pin offset %d in group %s at index %d\n",
+                               g->pins[i], g->name, i);
+                       goto out_glitch;
+               }
+               chip = range->gc;
+               nmk_chip = container_of(chip, struct nmk_gpio_chip, chip);
+               dev_dbg(npct->dev, "setting pin %d to altsetting %d\n", g->pins[i], g->altsetting);
+
+               clk_enable(nmk_chip->clk);
+               bit = g->pins[i] % NMK_GPIO_PER_CHIP;
+               /*
+                * If the pin is switching to altfunc, and there was an
+                * interrupt installed on it which has been lazy disabled,
+                * actually mask the interrupt to prevent spurious interrupts
+                * that would occur while the pin is under control of the
+                * peripheral. Only SKE does this.
+                */
+               nmk_gpio_disable_lazy_irq(nmk_chip, bit);
+
+               __nmk_gpio_set_mode_safe(nmk_chip, bit,
+                       (g->altsetting & NMK_GPIO_ALT_C), glitch);
+               clk_disable(nmk_chip->clk);
+
+               /*
+                * Call PRCM GPIOCR config function in case ALTC
+                * has been selected:
+                * - If selection is a ALTCx, some bits in PRCM GPIOCR registers
+                *   must be set.
+                * - If selection is pure ALTC and previous selection was ALTCx,
+                *   then some bits in PRCM GPIOCR registers must be cleared.
+                */
+               if ((g->altsetting & NMK_GPIO_ALT_C) == NMK_GPIO_ALT_C)
+                       nmk_prcm_altcx_set_mode(npct, g->pins[i],
+                               g->altsetting >> NMK_GPIO_ALT_CX_SHIFT);
+       }
+
+       /* When all pins are successfully reconfigured we get here */
+       ret = 0;
+
+out_glitch:
+       if (glitch) {
+               nmk_gpio_glitch_slpm_restore(slpm);
+               spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags);
+       }
+
+       return ret;
+}
+
+static int nmk_gpio_request_enable(struct pinctrl_dev *pctldev,
+                                  struct pinctrl_gpio_range *range,
+                                  unsigned offset)
+{
+       struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
+       struct nmk_gpio_chip *nmk_chip;
+       struct gpio_chip *chip;
+       unsigned bit;
+
+       if (!range) {
+               dev_err(npct->dev, "invalid range\n");
+               return -EINVAL;
+       }
+       if (!range->gc) {
+               dev_err(npct->dev, "missing GPIO chip in range\n");
+               return -EINVAL;
+       }
+       chip = range->gc;
+       nmk_chip = container_of(chip, struct nmk_gpio_chip, chip);
+
+       dev_dbg(npct->dev, "enable pin %u as GPIO\n", offset);
+
+       clk_enable(nmk_chip->clk);
+       bit = offset % NMK_GPIO_PER_CHIP;
+       /* There is no glitch when converting any pin to GPIO */
+       __nmk_gpio_set_mode(nmk_chip, bit, NMK_GPIO_ALT_GPIO);
+       clk_disable(nmk_chip->clk);
+
+       return 0;
+}
+
+static void nmk_gpio_disable_free(struct pinctrl_dev *pctldev,
+                                 struct pinctrl_gpio_range *range,
+                                 unsigned offset)
+{
+       struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
+
+       dev_dbg(npct->dev, "disable pin %u as GPIO\n", offset);
+       /* Set the pin to some default state, GPIO is usually default */
+}
+
+static const struct pinmux_ops nmk_pinmux_ops = {
+       .get_functions_count = nmk_pmx_get_funcs_cnt,
+       .get_function_name = nmk_pmx_get_func_name,
+       .get_function_groups = nmk_pmx_get_func_groups,
+       .enable = nmk_pmx_enable,
+       .gpio_request_enable = nmk_gpio_request_enable,
+       .gpio_disable_free = nmk_gpio_disable_free,
+};
+
+static int nmk_pin_config_get(struct pinctrl_dev *pctldev, unsigned pin,
+                             unsigned long *config)
+{
+       /* Not implemented */
+       return -EINVAL;
+}
+
+static int nmk_pin_config_set(struct pinctrl_dev *pctldev, unsigned pin,
+                             unsigned long *configs, unsigned num_configs)
+{
+       static const char *pullnames[] = {
+               [NMK_GPIO_PULL_NONE]    = "none",
+               [NMK_GPIO_PULL_UP]      = "up",
+               [NMK_GPIO_PULL_DOWN]    = "down",
+               [3] /* illegal */       = "??"
+       };
+       static const char *slpmnames[] = {
+               [NMK_GPIO_SLPM_INPUT]           = "input/wakeup",
+               [NMK_GPIO_SLPM_NOCHANGE]        = "no-change/no-wakeup",
+       };
+       struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
+       struct nmk_gpio_chip *nmk_chip;
+       struct pinctrl_gpio_range *range;
+       struct gpio_chip *chip;
+       unsigned bit;
+       pin_cfg_t cfg;
+       int pull, slpm, output, val, i;
+       bool lowemi, gpiomode, sleep;
+
+       range = nmk_match_gpio_range(pctldev, pin);
+       if (!range) {
+               dev_err(npct->dev, "invalid pin offset %d\n", pin);
+               return -EINVAL;
+       }
+       if (!range->gc) {
+               dev_err(npct->dev, "GPIO chip missing in range for pin %d\n",
+                       pin);
+               return -EINVAL;
+       }
+       chip = range->gc;
+       nmk_chip = container_of(chip, struct nmk_gpio_chip, chip);
+
+       for (i = 0; i < num_configs; i++) {
+               /*
+                * The pin config contains pin number and altfunction fields,
+                * here we just ignore that part. It's being handled by the
+                * framework and pinmux callback respectively.
+                */
+               cfg = (pin_cfg_t) configs[i];
+               pull = PIN_PULL(cfg);
+               slpm = PIN_SLPM(cfg);
+               output = PIN_DIR(cfg);
+               val = PIN_VAL(cfg);
+               lowemi = PIN_LOWEMI(cfg);
+               gpiomode = PIN_GPIOMODE(cfg);
+               sleep = PIN_SLEEPMODE(cfg);
+
+               if (sleep) {
+                       int slpm_pull = PIN_SLPM_PULL(cfg);
+                       int slpm_output = PIN_SLPM_DIR(cfg);
+                       int slpm_val = PIN_SLPM_VAL(cfg);
+
+                       /* All pins go into GPIO mode at sleep */
+                       gpiomode = true;
+
+                       /*
+                        * The SLPM_* values are normal values + 1 to allow zero
+                        * to mean "same as normal".
+                        */
+                       if (slpm_pull)
+                               pull = slpm_pull - 1;
+                       if (slpm_output)
+                               output = slpm_output - 1;
+                       if (slpm_val)
+                               val = slpm_val - 1;
+
+                       dev_dbg(nmk_chip->chip.dev,
+                               "pin %d: sleep pull %s, dir %s, val %s\n",
+                               pin,
+                               slpm_pull ? pullnames[pull] : "same",
+                               slpm_output ? (output ? "output" : "input")
+                               : "same",
+                               slpm_val ? (val ? "high" : "low") : "same");
+               }
+
+               dev_dbg(nmk_chip->chip.dev,
+                       "pin %d [%#lx]: pull %s, slpm %s (%s%s), lowemi %s\n",
+                       pin, cfg, pullnames[pull], slpmnames[slpm],
+                       output ? "output " : "input",
+                       output ? (val ? "high" : "low") : "",
+                       lowemi ? "on" : "off");
+
+               clk_enable(nmk_chip->clk);
+               bit = pin % NMK_GPIO_PER_CHIP;
+               if (gpiomode)
+                       /* No glitch when going to GPIO mode */
+                       __nmk_gpio_set_mode(nmk_chip, bit, NMK_GPIO_ALT_GPIO);
+               if (output)
+                       __nmk_gpio_make_output(nmk_chip, bit, val);
+               else {
+                       __nmk_gpio_make_input(nmk_chip, bit);
+                       __nmk_gpio_set_pull(nmk_chip, bit, pull);
+               }
+               /* TODO: isn't this only applicable on output pins? */
+               __nmk_gpio_set_lowemi(nmk_chip, bit, lowemi);
+
+               __nmk_gpio_set_slpm(nmk_chip, bit, slpm);
+               clk_disable(nmk_chip->clk);
+       } /* for each config */
+
+       return 0;
+}
+
+static const struct pinconf_ops nmk_pinconf_ops = {
+       .pin_config_get = nmk_pin_config_get,
+       .pin_config_set = nmk_pin_config_set,
+};
+
+static struct pinctrl_desc nmk_pinctrl_desc = {
+       .name = "pinctrl-nomadik",
+       .pctlops = &nmk_pinctrl_ops,
+       .pmxops = &nmk_pinmux_ops,
+       .confops = &nmk_pinconf_ops,
+       .owner = THIS_MODULE,
+};
+
+static const struct of_device_id nmk_pinctrl_match[] = {
+       {
+               .compatible = "stericsson,stn8815-pinctrl",
+               .data = (void *)PINCTRL_NMK_STN8815,
+       },
+       {
+               .compatible = "stericsson,db8500-pinctrl",
+               .data = (void *)PINCTRL_NMK_DB8500,
+       },
+       {
+               .compatible = "stericsson,db8540-pinctrl",
+               .data = (void *)PINCTRL_NMK_DB8540,
+       },
+       {},
+};
+
+#ifdef CONFIG_PM_SLEEP
+static int nmk_pinctrl_suspend(struct device *dev)
+{
+       struct nmk_pinctrl *npct;
+
+       npct = dev_get_drvdata(dev);
+       if (!npct)
+               return -EINVAL;
+
+       return pinctrl_force_sleep(npct->pctl);
+}
+
+static int nmk_pinctrl_resume(struct device *dev)
+{
+       struct nmk_pinctrl *npct;
+
+       npct = dev_get_drvdata(dev);
+       if (!npct)
+               return -EINVAL;
+
+       return pinctrl_force_default(npct->pctl);
+}
+#endif
+
+static int nmk_pinctrl_probe(struct platform_device *pdev)
+{
+       const struct of_device_id *match;
+       struct device_node *np = pdev->dev.of_node;
+       struct device_node *prcm_np;
+       struct nmk_pinctrl *npct;
+       unsigned int version = 0;
+       int i;
+
+       npct = devm_kzalloc(&pdev->dev, sizeof(*npct), GFP_KERNEL);
+       if (!npct)
+               return -ENOMEM;
+
+       match = of_match_device(nmk_pinctrl_match, &pdev->dev);
+       if (!match)
+               return -ENODEV;
+       version = (unsigned int) match->data;
+
+       /* Poke in other ASIC variants here */
+       if (version == PINCTRL_NMK_STN8815)
+               nmk_pinctrl_stn8815_init(&npct->soc);
+       if (version == PINCTRL_NMK_DB8500)
+               nmk_pinctrl_db8500_init(&npct->soc);
+       if (version == PINCTRL_NMK_DB8540)
+               nmk_pinctrl_db8540_init(&npct->soc);
+
+       prcm_np = of_parse_phandle(np, "prcm", 0);
+       if (prcm_np)
+               npct->prcm_base = of_iomap(prcm_np, 0);
+       if (!npct->prcm_base) {
+               if (version == PINCTRL_NMK_STN8815) {
+                       dev_info(&pdev->dev,
+                                "No PRCM base, "
+                                "assuming no ALT-Cx control is available\n");
+               } else {
+                       dev_err(&pdev->dev, "missing PRCM base address\n");
+                       return -EINVAL;
+               }
+       }
+
+       /*
+        * We need all the GPIO drivers to probe FIRST, or we will not be able
+        * to obtain references to the struct gpio_chip * for them, and we
+        * need this to proceed.
+        */
+       for (i = 0; i < npct->soc->gpio_num_ranges; i++) {
+               if (!nmk_gpio_chips[npct->soc->gpio_ranges[i].id]) {
+                       dev_warn(&pdev->dev, "GPIO chip %d not registered yet\n", i);
+                       return -EPROBE_DEFER;
+               }
+               npct->soc->gpio_ranges[i].gc = &nmk_gpio_chips[npct->soc->gpio_ranges[i].id]->chip;
+       }
+
+       nmk_pinctrl_desc.pins = npct->soc->pins;
+       nmk_pinctrl_desc.npins = npct->soc->npins;
+       npct->dev = &pdev->dev;
+
+       npct->pctl = pinctrl_register(&nmk_pinctrl_desc, &pdev->dev, npct);
+       if (!npct->pctl) {
+               dev_err(&pdev->dev, "could not register Nomadik pinctrl driver\n");
+               return -EINVAL;
+       }
+
+       /* We will handle a range of GPIO pins */
+       for (i = 0; i < npct->soc->gpio_num_ranges; i++)
+               pinctrl_add_gpio_range(npct->pctl, &npct->soc->gpio_ranges[i]);
+
+       platform_set_drvdata(pdev, npct);
+       dev_info(&pdev->dev, "initialized Nomadik pin control driver\n");
+
+       return 0;
+}
+
+static const struct of_device_id nmk_gpio_match[] = {
+       { .compatible = "st,nomadik-gpio", },
+       {}
+};
+
+static struct platform_driver nmk_gpio_driver = {
+       .driver = {
+               .owner = THIS_MODULE,
+               .name = "gpio",
+               .of_match_table = nmk_gpio_match,
+       },
+       .probe = nmk_gpio_probe,
+};
+
+static SIMPLE_DEV_PM_OPS(nmk_pinctrl_pm_ops,
+                       nmk_pinctrl_suspend,
+                       nmk_pinctrl_resume);
+
+static struct platform_driver nmk_pinctrl_driver = {
+       .driver = {
+               .owner = THIS_MODULE,
+               .name = "pinctrl-nomadik",
+               .of_match_table = nmk_pinctrl_match,
+               .pm = &nmk_pinctrl_pm_ops,
+       },
+       .probe = nmk_pinctrl_probe,
+};
+
+static int __init nmk_gpio_init(void)
+{
+       int ret;
+
+       ret = platform_driver_register(&nmk_gpio_driver);
+       if (ret)
+               return ret;
+       return platform_driver_register(&nmk_pinctrl_driver);
+}
+
+core_initcall(nmk_gpio_init);
+
+MODULE_AUTHOR("Prafulla WADASKAR and Alessandro Rubini");
+MODULE_DESCRIPTION("Nomadik GPIO Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik.h b/drivers/pinctrl/nomadik/pinctrl-nomadik.h
new file mode 100644 (file)
index 0000000..d8215f1
--- /dev/null
@@ -0,0 +1,192 @@
+#ifndef PINCTRL_PINCTRL_NOMADIK_H
+#define PINCTRL_PINCTRL_NOMADIK_H
+
+/* Package definitions */
+#define PINCTRL_NMK_STN8815    0
+#define PINCTRL_NMK_DB8500     1
+#define PINCTRL_NMK_DB8540     2
+
+/* Alternate functions: function C is set in hw by setting both A and B */
+#define NMK_GPIO_ALT_GPIO      0
+#define NMK_GPIO_ALT_A 1
+#define NMK_GPIO_ALT_B 2
+#define NMK_GPIO_ALT_C (NMK_GPIO_ALT_A | NMK_GPIO_ALT_B)
+
+#define NMK_GPIO_ALT_CX_SHIFT 2
+#define NMK_GPIO_ALT_C1        ((1<<NMK_GPIO_ALT_CX_SHIFT) | NMK_GPIO_ALT_C)
+#define NMK_GPIO_ALT_C2        ((2<<NMK_GPIO_ALT_CX_SHIFT) | NMK_GPIO_ALT_C)
+#define NMK_GPIO_ALT_C3        ((3<<NMK_GPIO_ALT_CX_SHIFT) | NMK_GPIO_ALT_C)
+#define NMK_GPIO_ALT_C4        ((4<<NMK_GPIO_ALT_CX_SHIFT) | NMK_GPIO_ALT_C)
+
+#define PRCM_GPIOCR_ALTCX(pin_num,\
+       altc1_used, altc1_ri, altc1_cb,\
+       altc2_used, altc2_ri, altc2_cb,\
+       altc3_used, altc3_ri, altc3_cb,\
+       altc4_used, altc4_ri, altc4_cb)\
+{\
+       .pin = pin_num,\
+       .altcx[PRCM_IDX_GPIOCR_ALTC1] = {\
+               .used = altc1_used,\
+               .reg_index = altc1_ri,\
+               .control_bit = altc1_cb\
+       },\
+       .altcx[PRCM_IDX_GPIOCR_ALTC2] = {\
+               .used = altc2_used,\
+               .reg_index = altc2_ri,\
+               .control_bit = altc2_cb\
+       },\
+       .altcx[PRCM_IDX_GPIOCR_ALTC3] = {\
+               .used = altc3_used,\
+               .reg_index = altc3_ri,\
+               .control_bit = altc3_cb\
+       },\
+       .altcx[PRCM_IDX_GPIOCR_ALTC4] = {\
+               .used = altc4_used,\
+               .reg_index = altc4_ri,\
+               .control_bit = altc4_cb\
+       },\
+}
+
+/**
+ * enum prcm_gpiocr_reg_index
+ * Used to reference an PRCM GPIOCR register address.
+ */
+enum prcm_gpiocr_reg_index {
+       PRCM_IDX_GPIOCR1,
+       PRCM_IDX_GPIOCR2,
+       PRCM_IDX_GPIOCR3
+};
+/**
+ * enum prcm_gpiocr_altcx_index
+ * Used to reference an Other alternate-C function.
+ */
+enum prcm_gpiocr_altcx_index {
+       PRCM_IDX_GPIOCR_ALTC1,
+       PRCM_IDX_GPIOCR_ALTC2,
+       PRCM_IDX_GPIOCR_ALTC3,
+       PRCM_IDX_GPIOCR_ALTC4,
+       PRCM_IDX_GPIOCR_ALTC_MAX,
+};
+
+/**
+ * struct prcm_gpio_altcx - Other alternate-C function
+ * @used: other alternate-C function availability
+ * @reg_index: PRCM GPIOCR register index used to control the function
+ * @control_bit: PRCM GPIOCR bit used to control the function
+ */
+struct prcm_gpiocr_altcx {
+       bool used:1;
+       u8 reg_index:2;
+       u8 control_bit:5;
+} __packed;
+
+/**
+ * struct prcm_gpio_altcx_pin_desc - Other alternate-C pin
+ * @pin: The pin number
+ * @altcx: array of other alternate-C[1-4] functions
+ */
+struct prcm_gpiocr_altcx_pin_desc {
+       unsigned short pin;
+       struct prcm_gpiocr_altcx altcx[PRCM_IDX_GPIOCR_ALTC_MAX];
+};
+
+/**
+ * struct nmk_function - Nomadik pinctrl mux function
+ * @name: The name of the function, exported to pinctrl core.
+ * @groups: An array of pin groups that may select this function.
+ * @ngroups: The number of entries in @groups.
+ */
+struct nmk_function {
+       const char *name;
+       const char * const *groups;
+       unsigned ngroups;
+};
+
+/**
+ * struct nmk_pingroup - describes a Nomadik pin group
+ * @name: the name of this specific pin group
+ * @pins: an array of discrete physical pins used in this group, taken
+ *     from the driver-local pin enumeration space
+ * @num_pins: the number of pins in this group array, i.e. the number of
+ *     elements in .pins so we can iterate over that array
+ * @altsetting: the altsetting to apply to all pins in this group to
+ *     configure them to be used by a function
+ */
+struct nmk_pingroup {
+       const char *name;
+       const unsigned int *pins;
+       const unsigned npins;
+       int altsetting;
+};
+
+/**
+ * struct nmk_pinctrl_soc_data - Nomadik pin controller per-SoC configuration
+ * @gpio_ranges: An array of GPIO ranges for this SoC
+ * @gpio_num_ranges: The number of GPIO ranges for this SoC
+ * @pins:      An array describing all pins the pin controller affects.
+ *             All pins which are also GPIOs must be listed first within the
+ *             array, and be numbered identically to the GPIO controller's
+ *             numbering.
+ * @npins:     The number of entries in @pins.
+ * @functions: The functions supported on this SoC.
+ * @nfunction: The number of entries in @functions.
+ * @groups:    An array describing all pin groups the pin SoC supports.
+ * @ngroups:   The number of entries in @groups.
+ * @altcx_pins:        The pins that support Other alternate-C function on this SoC
+ * @npins_altcx: The number of Other alternate-C pins
+ * @prcm_gpiocr_registers: The array of PRCM GPIOCR registers on this SoC
+ */
+struct nmk_pinctrl_soc_data {
+       struct pinctrl_gpio_range *gpio_ranges;
+       unsigned gpio_num_ranges;
+       const struct pinctrl_pin_desc *pins;
+       unsigned npins;
+       const struct nmk_function *functions;
+       unsigned nfunctions;
+       const struct nmk_pingroup *groups;
+       unsigned ngroups;
+       const struct prcm_gpiocr_altcx_pin_desc *altcx_pins;
+       unsigned npins_altcx;
+       const u16 *prcm_gpiocr_registers;
+};
+
+#ifdef CONFIG_PINCTRL_STN8815
+
+void nmk_pinctrl_stn8815_init(const struct nmk_pinctrl_soc_data **soc);
+
+#else
+
+static inline void
+nmk_pinctrl_stn8815_init(const struct nmk_pinctrl_soc_data **soc)
+{
+}
+
+#endif
+
+#ifdef CONFIG_PINCTRL_DB8500
+
+void nmk_pinctrl_db8500_init(const struct nmk_pinctrl_soc_data **soc);
+
+#else
+
+static inline void
+nmk_pinctrl_db8500_init(const struct nmk_pinctrl_soc_data **soc)
+{
+}
+
+#endif
+
+#ifdef CONFIG_PINCTRL_DB8540
+
+void nmk_pinctrl_db8540_init(const struct nmk_pinctrl_soc_data **soc);
+
+#else
+
+static inline void
+nmk_pinctrl_db8540_init(const struct nmk_pinctrl_soc_data **soc)
+{
+}
+
+#endif
+
+#endif /* PINCTRL_PINCTRL_NOMADIK_H */
diff --git a/drivers/pinctrl/pinctrl-ab8500.c b/drivers/pinctrl/pinctrl-ab8500.c
deleted file mode 100644 (file)
index 2ac2d0a..0000000
+++ /dev/null
@@ -1,485 +0,0 @@
-/*
- * Copyright (C) ST-Ericsson SA 2012
- *
- * Author: Patrice Chotard <patrice.chotard@stericsson.com> for ST-Ericsson.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/gpio.h>
-#include <linux/pinctrl/pinctrl.h>
-#include <linux/mfd/abx500/ab8500.h>
-#include "pinctrl-abx500.h"
-
-/* All the pins that can be used for GPIO and some other functions */
-#define ABX500_GPIO(offset)            (offset)
-
-#define AB8500_PIN_T10         ABX500_GPIO(1)
-#define AB8500_PIN_T9          ABX500_GPIO(2)
-#define AB8500_PIN_U9          ABX500_GPIO(3)
-#define AB8500_PIN_W2          ABX500_GPIO(4)
-/* hole */
-#define AB8500_PIN_Y18         ABX500_GPIO(6)
-#define AB8500_PIN_AA20                ABX500_GPIO(7)
-#define AB8500_PIN_W18         ABX500_GPIO(8)
-#define AB8500_PIN_AA19                ABX500_GPIO(9)
-#define AB8500_PIN_U17         ABX500_GPIO(10)
-#define AB8500_PIN_AA18                ABX500_GPIO(11)
-#define AB8500_PIN_U16         ABX500_GPIO(12)
-#define AB8500_PIN_W17         ABX500_GPIO(13)
-#define AB8500_PIN_F14         ABX500_GPIO(14)
-#define AB8500_PIN_B17         ABX500_GPIO(15)
-#define AB8500_PIN_F15         ABX500_GPIO(16)
-#define AB8500_PIN_P5          ABX500_GPIO(17)
-#define AB8500_PIN_R5          ABX500_GPIO(18)
-#define AB8500_PIN_U5          ABX500_GPIO(19)
-#define AB8500_PIN_T5          ABX500_GPIO(20)
-#define AB8500_PIN_H19         ABX500_GPIO(21)
-#define AB8500_PIN_G20         ABX500_GPIO(22)
-#define AB8500_PIN_G19         ABX500_GPIO(23)
-#define AB8500_PIN_T14         ABX500_GPIO(24)
-#define AB8500_PIN_R16         ABX500_GPIO(25)
-#define AB8500_PIN_M16         ABX500_GPIO(26)
-#define AB8500_PIN_J6          ABX500_GPIO(27)
-#define AB8500_PIN_K6          ABX500_GPIO(28)
-#define AB8500_PIN_G6          ABX500_GPIO(29)
-#define AB8500_PIN_H6          ABX500_GPIO(30)
-#define AB8500_PIN_F5          ABX500_GPIO(31)
-#define AB8500_PIN_G5          ABX500_GPIO(32)
-/* hole */
-#define AB8500_PIN_R17         ABX500_GPIO(34)
-#define AB8500_PIN_W15         ABX500_GPIO(35)
-#define AB8500_PIN_A17         ABX500_GPIO(36)
-#define AB8500_PIN_E15         ABX500_GPIO(37)
-#define AB8500_PIN_C17         ABX500_GPIO(38)
-#define AB8500_PIN_E16         ABX500_GPIO(39)
-#define AB8500_PIN_T19         ABX500_GPIO(40)
-#define AB8500_PIN_U19         ABX500_GPIO(41)
-#define AB8500_PIN_U2          ABX500_GPIO(42)
-
-/* indicates the highest GPIO number */
-#define AB8500_GPIO_MAX_NUMBER 42
-
-/*
- * The names of the pins are denoted by GPIO number and ball name, even
- * though they can be used for other things than GPIO, this is the first
- * column in the table of the data sheet and often used on schematics and
- * such.
- */
-static const struct pinctrl_pin_desc ab8500_pins[] = {
-       PINCTRL_PIN(AB8500_PIN_T10, "GPIO1_T10"),
-       PINCTRL_PIN(AB8500_PIN_T9, "GPIO2_T9"),
-       PINCTRL_PIN(AB8500_PIN_U9, "GPIO3_U9"),
-       PINCTRL_PIN(AB8500_PIN_W2, "GPIO4_W2"),
-       /* hole */
-       PINCTRL_PIN(AB8500_PIN_Y18, "GPIO6_Y18"),
-       PINCTRL_PIN(AB8500_PIN_AA20, "GPIO7_AA20"),
-       PINCTRL_PIN(AB8500_PIN_W18, "GPIO8_W18"),
-       PINCTRL_PIN(AB8500_PIN_AA19, "GPIO9_AA19"),
-       PINCTRL_PIN(AB8500_PIN_U17, "GPIO10_U17"),
-       PINCTRL_PIN(AB8500_PIN_AA18, "GPIO11_AA18"),
-       PINCTRL_PIN(AB8500_PIN_U16, "GPIO12_U16"),
-       PINCTRL_PIN(AB8500_PIN_W17, "GPIO13_W17"),
-       PINCTRL_PIN(AB8500_PIN_F14, "GPIO14_F14"),
-       PINCTRL_PIN(AB8500_PIN_B17, "GPIO15_B17"),
-       PINCTRL_PIN(AB8500_PIN_F15, "GPIO16_F15"),
-       PINCTRL_PIN(AB8500_PIN_P5, "GPIO17_P5"),
-       PINCTRL_PIN(AB8500_PIN_R5, "GPIO18_R5"),
-       PINCTRL_PIN(AB8500_PIN_U5, "GPIO19_U5"),
-       PINCTRL_PIN(AB8500_PIN_T5, "GPIO20_T5"),
-       PINCTRL_PIN(AB8500_PIN_H19, "GPIO21_H19"),
-       PINCTRL_PIN(AB8500_PIN_G20, "GPIO22_G20"),
-       PINCTRL_PIN(AB8500_PIN_G19, "GPIO23_G19"),
-       PINCTRL_PIN(AB8500_PIN_T14, "GPIO24_T14"),
-       PINCTRL_PIN(AB8500_PIN_R16, "GPIO25_R16"),
-       PINCTRL_PIN(AB8500_PIN_M16, "GPIO26_M16"),
-       PINCTRL_PIN(AB8500_PIN_J6, "GPIO27_J6"),
-       PINCTRL_PIN(AB8500_PIN_K6, "GPIO28_K6"),
-       PINCTRL_PIN(AB8500_PIN_G6, "GPIO29_G6"),
-       PINCTRL_PIN(AB8500_PIN_H6, "GPIO30_H6"),
-       PINCTRL_PIN(AB8500_PIN_F5, "GPIO31_F5"),
-       PINCTRL_PIN(AB8500_PIN_G5, "GPIO32_G5"),
-       /* hole */
-       PINCTRL_PIN(AB8500_PIN_R17, "GPIO34_R17"),
-       PINCTRL_PIN(AB8500_PIN_W15, "GPIO35_W15"),
-       PINCTRL_PIN(AB8500_PIN_A17, "GPIO36_A17"),
-       PINCTRL_PIN(AB8500_PIN_E15, "GPIO37_E15"),
-       PINCTRL_PIN(AB8500_PIN_C17, "GPIO38_C17"),
-       PINCTRL_PIN(AB8500_PIN_E16, "GPIO39_E16"),
-       PINCTRL_PIN(AB8500_PIN_T19, "GPIO40_T19"),
-       PINCTRL_PIN(AB8500_PIN_U19, "GPIO41_U19"),
-       PINCTRL_PIN(AB8500_PIN_U2, "GPIO42_U2"),
-};
-
-/*
- * Maps local GPIO offsets to local pin numbers
- */
-static const struct abx500_pinrange ab8500_pinranges[] = {
-       ABX500_PINRANGE(1, 4, ABX500_ALT_A),
-       ABX500_PINRANGE(6, 4, ABX500_ALT_A),
-       ABX500_PINRANGE(10, 4, ABX500_DEFAULT),
-       ABX500_PINRANGE(14, 12, ABX500_ALT_A),
-       ABX500_PINRANGE(26, 1, ABX500_DEFAULT),
-       ABX500_PINRANGE(27, 6, ABX500_ALT_A),
-       ABX500_PINRANGE(34, 1, ABX500_ALT_A),
-       ABX500_PINRANGE(35, 1, ABX500_DEFAULT),
-       ABX500_PINRANGE(36, 7, ABX500_ALT_A),
-};
-
-/*
- * Read the pin group names like this:
- * sysclkreq2_d_1 = first groups of pins for sysclkreq2 on default function
- *
- * The groups are arranged as sets per altfunction column, so we can
- * mux in one group at a time by selecting the same altfunction for them
- * all. When functions require pins on different altfunctions, you need
- * to combine several groups.
- */
-
-/* default column */
-static const unsigned sysclkreq2_d_1_pins[] = { AB8500_PIN_T10 };
-static const unsigned sysclkreq3_d_1_pins[] = { AB8500_PIN_T9 };
-static const unsigned sysclkreq4_d_1_pins[] = { AB8500_PIN_U9 };
-static const unsigned sysclkreq6_d_1_pins[] = { AB8500_PIN_W2 };
-static const unsigned ycbcr0123_d_1_pins[] = { AB8500_PIN_Y18, AB8500_PIN_AA20,
-                                       AB8500_PIN_W18, AB8500_PIN_AA19};
-static const unsigned gpio10_d_1_pins[] = { AB8500_PIN_U17 };
-static const unsigned gpio11_d_1_pins[] = { AB8500_PIN_AA18 };
-static const unsigned gpio12_d_1_pins[] = { AB8500_PIN_U16 };
-static const unsigned gpio13_d_1_pins[] = { AB8500_PIN_W17 };
-static const unsigned pwmout1_d_1_pins[] = { AB8500_PIN_F14 };
-static const unsigned pwmout2_d_1_pins[] = { AB8500_PIN_B17 };
-static const unsigned pwmout3_d_1_pins[] = { AB8500_PIN_F15 };
-
-/* audio data interface 1*/
-static const unsigned adi1_d_1_pins[] = { AB8500_PIN_P5, AB8500_PIN_R5,
-                                       AB8500_PIN_U5, AB8500_PIN_T5 };
-/* USBUICC */
-static const unsigned usbuicc_d_1_pins[] = { AB8500_PIN_H19, AB8500_PIN_G20,
-                                       AB8500_PIN_G19 };
-static const unsigned sysclkreq7_d_1_pins[] = { AB8500_PIN_T14 };
-static const unsigned sysclkreq8_d_1_pins[] = { AB8500_PIN_R16 };
-static const unsigned gpio26_d_1_pins[] = { AB8500_PIN_M16 };
-/* Digital microphone 1 and 2 */
-static const unsigned dmic12_d_1_pins[] = { AB8500_PIN_J6, AB8500_PIN_K6 };
-/* Digital microphone 3 and 4 */
-static const unsigned dmic34_d_1_pins[] = { AB8500_PIN_G6, AB8500_PIN_H6 };
-/* Digital microphone 5 and 6 */
-static const unsigned dmic56_d_1_pins[] = { AB8500_PIN_F5, AB8500_PIN_G5 };
-static const unsigned extcpena_d_1_pins[] = { AB8500_PIN_R17 };
-static const unsigned gpio35_d_1_pins[] = { AB8500_PIN_W15 };
-/* APE SPI */
-static const unsigned apespi_d_1_pins[] = { AB8500_PIN_A17, AB8500_PIN_E15,
-                                       AB8500_PIN_C17, AB8500_PIN_E16};
-/* modem SDA/SCL */
-static const unsigned modsclsda_d_1_pins[] = { AB8500_PIN_T19, AB8500_PIN_U19 };
-static const unsigned sysclkreq5_d_1_pins[] = { AB8500_PIN_U2 };
-
-/* Altfunction A column */
-static const unsigned gpio1_a_1_pins[] = { AB8500_PIN_T10 };
-static const unsigned gpio2_a_1_pins[] = { AB8500_PIN_T9 };
-static const unsigned gpio3_a_1_pins[] = { AB8500_PIN_U9 };
-static const unsigned gpio4_a_1_pins[] = { AB8500_PIN_W2 };
-static const unsigned gpio6_a_1_pins[] = { AB8500_PIN_Y18 };
-static const unsigned gpio7_a_1_pins[] = { AB8500_PIN_AA20 };
-static const unsigned gpio8_a_1_pins[] = { AB8500_PIN_W18 };
-static const unsigned gpio9_a_1_pins[] = { AB8500_PIN_AA19 };
-/* YCbCr4 YCbCr5 YCbCr6 YCbCr7*/
-static const unsigned ycbcr4567_a_1_pins[] = { AB8500_PIN_U17, AB8500_PIN_AA18,
-                                       AB8500_PIN_U16, AB8500_PIN_W17};
-static const unsigned gpio14_a_1_pins[] = { AB8500_PIN_F14 };
-static const unsigned gpio15_a_1_pins[] = { AB8500_PIN_B17 };
-static const unsigned gpio16_a_1_pins[] = { AB8500_PIN_F15 };
-static const unsigned gpio17_a_1_pins[] = { AB8500_PIN_P5 };
-static const unsigned gpio18_a_1_pins[] = { AB8500_PIN_R5 };
-static const unsigned gpio19_a_1_pins[] = { AB8500_PIN_U5 };
-static const unsigned gpio20_a_1_pins[] = { AB8500_PIN_T5 };
-static const unsigned gpio21_a_1_pins[] = { AB8500_PIN_H19 };
-static const unsigned gpio22_a_1_pins[] = { AB8500_PIN_G20 };
-static const unsigned gpio23_a_1_pins[] = { AB8500_PIN_G19 };
-static const unsigned gpio24_a_1_pins[] = { AB8500_PIN_T14 };
-static const unsigned gpio25_a_1_pins[] = { AB8500_PIN_R16 };
-static const unsigned gpio27_a_1_pins[] = { AB8500_PIN_J6 };
-static const unsigned gpio28_a_1_pins[] = { AB8500_PIN_K6 };
-static const unsigned gpio29_a_1_pins[] = { AB8500_PIN_G6 };
-static const unsigned gpio30_a_1_pins[] = { AB8500_PIN_H6 };
-static const unsigned gpio31_a_1_pins[] = { AB8500_PIN_F5 };
-static const unsigned gpio32_a_1_pins[] = { AB8500_PIN_G5 };
-static const unsigned gpio34_a_1_pins[] = { AB8500_PIN_R17 };
-static const unsigned gpio36_a_1_pins[] = { AB8500_PIN_A17 };
-static const unsigned gpio37_a_1_pins[] = { AB8500_PIN_E15 };
-static const unsigned gpio38_a_1_pins[] = { AB8500_PIN_C17 };
-static const unsigned gpio39_a_1_pins[] = { AB8500_PIN_E16 };
-static const unsigned gpio40_a_1_pins[] = { AB8500_PIN_T19 };
-static const unsigned gpio41_a_1_pins[] = { AB8500_PIN_U19 };
-static const unsigned gpio42_a_1_pins[] = { AB8500_PIN_U2 };
-
-/* Altfunction B colum */
-static const unsigned hiqclkena_b_1_pins[] = { AB8500_PIN_U17 };
-static const unsigned usbuiccpd_b_1_pins[] = { AB8500_PIN_AA18 };
-static const unsigned i2ctrig1_b_1_pins[] = { AB8500_PIN_U16 };
-static const unsigned i2ctrig2_b_1_pins[] = { AB8500_PIN_W17 };
-
-/* Altfunction C column */
-static const unsigned usbvdat_c_1_pins[] = { AB8500_PIN_W17 };
-
-
-#define AB8500_PIN_GROUP(a, b) { .name = #a, .pins = a##_pins,         \
-                       .npins = ARRAY_SIZE(a##_pins), .altsetting = b }
-
-static const struct abx500_pingroup ab8500_groups[] = {
-       /* default column */
-       AB8500_PIN_GROUP(sysclkreq2_d_1, ABX500_DEFAULT),
-       AB8500_PIN_GROUP(sysclkreq3_d_1, ABX500_DEFAULT),
-       AB8500_PIN_GROUP(sysclkreq4_d_1, ABX500_DEFAULT),
-       AB8500_PIN_GROUP(sysclkreq6_d_1, ABX500_DEFAULT),
-       AB8500_PIN_GROUP(ycbcr0123_d_1, ABX500_DEFAULT),
-       AB8500_PIN_GROUP(gpio10_d_1, ABX500_DEFAULT),
-       AB8500_PIN_GROUP(gpio11_d_1, ABX500_DEFAULT),
-       AB8500_PIN_GROUP(gpio12_d_1, ABX500_DEFAULT),
-       AB8500_PIN_GROUP(gpio13_d_1, ABX500_DEFAULT),
-       AB8500_PIN_GROUP(pwmout1_d_1, ABX500_DEFAULT),
-       AB8500_PIN_GROUP(pwmout2_d_1, ABX500_DEFAULT),
-       AB8500_PIN_GROUP(pwmout3_d_1, ABX500_DEFAULT),
-       AB8500_PIN_GROUP(adi1_d_1, ABX500_DEFAULT),
-       AB8500_PIN_GROUP(usbuicc_d_1, ABX500_DEFAULT),
-       AB8500_PIN_GROUP(sysclkreq7_d_1, ABX500_DEFAULT),
-       AB8500_PIN_GROUP(sysclkreq8_d_1, ABX500_DEFAULT),
-       AB8500_PIN_GROUP(gpio26_d_1, ABX500_DEFAULT),
-       AB8500_PIN_GROUP(dmic12_d_1, ABX500_DEFAULT),
-       AB8500_PIN_GROUP(dmic34_d_1, ABX500_DEFAULT),
-       AB8500_PIN_GROUP(dmic56_d_1, ABX500_DEFAULT),
-       AB8500_PIN_GROUP(extcpena_d_1, ABX500_DEFAULT),
-       AB8500_PIN_GROUP(gpio35_d_1, ABX500_DEFAULT),
-       AB8500_PIN_GROUP(apespi_d_1, ABX500_DEFAULT),
-       AB8500_PIN_GROUP(modsclsda_d_1, ABX500_DEFAULT),
-       AB8500_PIN_GROUP(sysclkreq5_d_1, ABX500_DEFAULT),
-       /* Altfunction A column */
-       AB8500_PIN_GROUP(gpio1_a_1, ABX500_ALT_A),
-       AB8500_PIN_GROUP(gpio2_a_1, ABX500_ALT_A),
-       AB8500_PIN_GROUP(gpio3_a_1, ABX500_ALT_A),
-       AB8500_PIN_GROUP(gpio4_a_1, ABX500_ALT_A),
-       AB8500_PIN_GROUP(gpio6_a_1, ABX500_ALT_A),
-       AB8500_PIN_GROUP(gpio7_a_1, ABX500_ALT_A),
-       AB8500_PIN_GROUP(gpio8_a_1, ABX500_ALT_A),
-       AB8500_PIN_GROUP(gpio9_a_1, ABX500_ALT_A),
-       AB8500_PIN_GROUP(ycbcr4567_a_1, ABX500_ALT_A),
-       AB8500_PIN_GROUP(gpio14_a_1, ABX500_ALT_A),
-       AB8500_PIN_GROUP(gpio15_a_1, ABX500_ALT_A),
-       AB8500_PIN_GROUP(gpio16_a_1, ABX500_ALT_A),
-       AB8500_PIN_GROUP(gpio17_a_1, ABX500_ALT_A),
-       AB8500_PIN_GROUP(gpio18_a_1, ABX500_ALT_A),
-       AB8500_PIN_GROUP(gpio19_a_1, ABX500_ALT_A),
-       AB8500_PIN_GROUP(gpio20_a_1, ABX500_ALT_A),
-       AB8500_PIN_GROUP(gpio21_a_1, ABX500_ALT_A),
-       AB8500_PIN_GROUP(gpio22_a_1, ABX500_ALT_A),
-       AB8500_PIN_GROUP(gpio23_a_1, ABX500_ALT_A),
-       AB8500_PIN_GROUP(gpio24_a_1, ABX500_ALT_A),
-       AB8500_PIN_GROUP(gpio25_a_1, ABX500_ALT_A),
-       AB8500_PIN_GROUP(gpio27_a_1, ABX500_ALT_A),
-       AB8500_PIN_GROUP(gpio28_a_1, ABX500_ALT_A),
-       AB8500_PIN_GROUP(gpio29_a_1, ABX500_ALT_A),
-       AB8500_PIN_GROUP(gpio30_a_1, ABX500_ALT_A),
-       AB8500_PIN_GROUP(gpio31_a_1, ABX500_ALT_A),
-       AB8500_PIN_GROUP(gpio32_a_1, ABX500_ALT_A),
-       AB8500_PIN_GROUP(gpio34_a_1, ABX500_ALT_A),
-       AB8500_PIN_GROUP(gpio36_a_1, ABX500_ALT_A),
-       AB8500_PIN_GROUP(gpio37_a_1, ABX500_ALT_A),
-       AB8500_PIN_GROUP(gpio38_a_1, ABX500_ALT_A),
-       AB8500_PIN_GROUP(gpio39_a_1, ABX500_ALT_A),
-       AB8500_PIN_GROUP(gpio40_a_1, ABX500_ALT_A),
-       AB8500_PIN_GROUP(gpio41_a_1, ABX500_ALT_A),
-       AB8500_PIN_GROUP(gpio42_a_1, ABX500_ALT_A),
-       /* Altfunction B column */
-       AB8500_PIN_GROUP(hiqclkena_b_1, ABX500_ALT_B),
-       AB8500_PIN_GROUP(usbuiccpd_b_1, ABX500_ALT_B),
-       AB8500_PIN_GROUP(i2ctrig1_b_1, ABX500_ALT_B),
-       AB8500_PIN_GROUP(i2ctrig2_b_1, ABX500_ALT_B),
-       /* Altfunction C column */
-       AB8500_PIN_GROUP(usbvdat_c_1, ABX500_ALT_C),
-};
-
-/* We use this macro to define the groups applicable to a function */
-#define AB8500_FUNC_GROUPS(a, b...)       \
-static const char * const a##_groups[] = { b };
-
-AB8500_FUNC_GROUPS(sysclkreq, "sysclkreq2_d_1", "sysclkreq3_d_1",
-               "sysclkreq4_d_1", "sysclkreq5_d_1", "sysclkreq6_d_1",
-               "sysclkreq7_d_1", "sysclkreq8_d_1");
-AB8500_FUNC_GROUPS(ycbcr, "ycbcr0123_d_1", "ycbcr4567_a_1");
-AB8500_FUNC_GROUPS(gpio, "gpio1_a_1", "gpio2_a_1", "gpio3_a_1", "gpio4_a_1",
-               "gpio6_a_1", "gpio7_a_1", "gpio8_a_1", "gpio9_a_1",
-               "gpio10_d_1", "gpio11_d_1", "gpio12_d_1", "gpio13_d_1",
-               "gpio14_a_1", "gpio15_a_1", "gpio16_a_1", "gpio17_a_1",
-               "gpio18_a_1", "gpio19_a_1", "gpio20_a_1", "gpio21_a_1",
-               "gpio22_a_1", "gpio23_a_1", "gpio24_a_1", "gpio25_a_1",
-               "gpio26_d_1", "gpio27_a_1", "gpio28_a_1", "gpio29_a_1",
-               "gpio30_a_1", "gpio31_a_1", "gpio32_a_1", "gpio34_a_1",
-               "gpio35_d_1", "gpio36_a_1", "gpio37_a_1", "gpio38_a_1",
-               "gpio39_a_1", "gpio40_a_1", "gpio41_a_1", "gpio42_a_1");
-AB8500_FUNC_GROUPS(pwmout, "pwmout1_d_1", "pwmout2_d_1", "pwmout3_d_1");
-AB8500_FUNC_GROUPS(adi1, "adi1_d_1");
-AB8500_FUNC_GROUPS(usbuicc, "usbuicc_d_1", "usbuiccpd_b_1");
-AB8500_FUNC_GROUPS(dmic, "dmic12_d_1", "dmic34_d_1", "dmic56_d_1");
-AB8500_FUNC_GROUPS(extcpena, "extcpena_d_1");
-AB8500_FUNC_GROUPS(apespi, "apespi_d_1");
-AB8500_FUNC_GROUPS(modsclsda, "modsclsda_d_1");
-AB8500_FUNC_GROUPS(hiqclkena, "hiqclkena_b_1");
-AB8500_FUNC_GROUPS(i2ctrig, "i2ctrig1_b_1", "i2ctrig2_b_1");
-AB8500_FUNC_GROUPS(usbvdat, "usbvdat_c_1");
-
-#define FUNCTION(fname)                                        \
-       {                                               \
-               .name = #fname,                         \
-               .groups = fname##_groups,               \
-               .ngroups = ARRAY_SIZE(fname##_groups),  \
-       }
-
-static const struct abx500_function ab8500_functions[] = {
-       FUNCTION(sysclkreq),
-       FUNCTION(ycbcr),
-       FUNCTION(gpio),
-       FUNCTION(pwmout),
-       FUNCTION(adi1),
-       FUNCTION(usbuicc),
-       FUNCTION(dmic),
-       FUNCTION(extcpena),
-       FUNCTION(apespi),
-       FUNCTION(modsclsda),
-       FUNCTION(hiqclkena),
-       FUNCTION(i2ctrig),
-       FUNCTION(usbvdat),
-};
-
-/*
- * this table translates what's is in the AB8500 specification regarding the
- * balls alternate functions (as for DB, default, ALT_A, ALT_B and ALT_C).
- * ALTERNATE_FUNCTIONS(GPIO_NUMBER, GPIOSEL bit, ALTERNATFUNC bit1,
- * ALTERNATEFUNC bit2, ALTA val, ALTB val, ALTC val),
- *
- * example :
- *
- *     ALTERNATE_FUNCTIONS(13,     4,      3,      4, 0, 1 ,2),
- *     means that pin AB8500_PIN_W17 (pin 13) supports 4 mux (default/ALT_A,
- *     ALT_B and ALT_C), so GPIOSEL and ALTERNATFUNC registers are used to
- *     select the mux.  ALTA, ALTB and ALTC val indicates values to write in
- *     ALTERNATFUNC register. We need to specifies these values as SOC
- *     designers didn't apply the same logic on how to select mux in the
- *     ABx500 family.
- *
- *     As this pins supports at least ALT_B mux, default mux is
- *     selected by writing 1 in GPIOSEL bit :
- *
- *             | GPIOSEL bit=4 | alternatfunc bit2=4 | alternatfunc bit1=3
- *     default |       1       |          0          |          0
- *     alt_A   |       0       |          0          |          0
- *     alt_B   |       0       |          0          |          1
- *     alt_C   |       0       |          1          |          0
- *
- *     ALTERNATE_FUNCTIONS(8,      7, UNUSED, UNUSED),
- *     means that pin AB8500_PIN_W18 (pin 8) supports 2 mux, so only GPIOSEL
- *     register is used to select the mux. As this pins doesn't support at
- *     least ALT_B mux, default mux is by writing 0 in GPIOSEL bit :
- *
- *             | GPIOSEL bit=7 | alternatfunc bit2=  | alternatfunc bit1=
- *     default |       0       |          0          |          0
- *     alt_A   |       1       |          0          |          0
- */
-
-static struct
-alternate_functions ab8500_alternate_functions[AB8500_GPIO_MAX_NUMBER + 1] = {
-       ALTERNATE_FUNCTIONS(0, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO0 */
-       ALTERNATE_FUNCTIONS(1,      0, UNUSED, UNUSED, 0, 0, 0), /* GPIO1, altA controlled by bit 0 */
-       ALTERNATE_FUNCTIONS(2,      1, UNUSED, UNUSED, 0, 0, 0), /* GPIO2, altA controlled by bit 1 */
-       ALTERNATE_FUNCTIONS(3,      2, UNUSED, UNUSED, 0, 0, 0), /* GPIO3, altA controlled by bit 2*/
-       ALTERNATE_FUNCTIONS(4,      3, UNUSED, UNUSED, 0, 0, 0), /* GPIO4, altA controlled by bit 3*/
-       /* bit 4 reserved */
-       ALTERNATE_FUNCTIONS(5, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO5 */
-       ALTERNATE_FUNCTIONS(6,      5, UNUSED, UNUSED, 0, 0, 0), /* GPIO6, altA controlled by bit 5*/
-       ALTERNATE_FUNCTIONS(7,      6, UNUSED, UNUSED, 0, 0, 0), /* GPIO7, altA controlled by bit 6*/
-       ALTERNATE_FUNCTIONS(8,      7, UNUSED, UNUSED, 0, 0, 0), /* GPIO8, altA controlled by bit 7*/
-
-       ALTERNATE_FUNCTIONS(9,      0, UNUSED, UNUSED, 0, 0, 0), /* GPIO9, altA controlled by bit 0*/
-       ALTERNATE_FUNCTIONS(10,     1,      0, UNUSED, 0, 1, 0), /* GPIO10, altA and altB controlled by bit 0 */
-       ALTERNATE_FUNCTIONS(11,     2,      1, UNUSED, 0, 1, 0), /* GPIO11, altA and altB controlled by bit 1 */
-       ALTERNATE_FUNCTIONS(12,     3,      2, UNUSED, 0, 1, 0), /* GPIO12, altA and altB controlled by bit 2 */
-       ALTERNATE_FUNCTIONS(13,     4,      3,      4, 0, 1, 2), /* GPIO13, altA altB and altC controlled by bit 3 and 4 */
-       ALTERNATE_FUNCTIONS(14,     5, UNUSED, UNUSED, 0, 0, 0), /* GPIO14, altA controlled by bit 5 */
-       ALTERNATE_FUNCTIONS(15,     6, UNUSED, UNUSED, 0, 0, 0), /* GPIO15, altA controlled by bit 6 */
-       ALTERNATE_FUNCTIONS(16,     7, UNUSED, UNUSED, 0, 0, 0), /* GPIO16, altA controlled by bit 7 */
-       /*
-        * pins 17 to 20 are special case, only bit 0 is used to select
-        * alternate function for these 4 pins.
-        * bits 1 to 3 are reserved
-        */
-       ALTERNATE_FUNCTIONS(17,      0, UNUSED, UNUSED, 0, 0, 0), /* GPIO17, altA controlled by bit 0 */
-       ALTERNATE_FUNCTIONS(18,      0, UNUSED, UNUSED, 0, 0, 0), /* GPIO18, altA controlled by bit 0 */
-       ALTERNATE_FUNCTIONS(19,      0, UNUSED, UNUSED, 0, 0, 0), /* GPIO19, altA controlled by bit 0 */
-       ALTERNATE_FUNCTIONS(20,      0, UNUSED, UNUSED, 0, 0, 0), /* GPIO20, altA controlled by bit 0 */
-       ALTERNATE_FUNCTIONS(21,      4, UNUSED, UNUSED, 0, 0, 0), /* GPIO21, altA controlled by bit 4 */
-       ALTERNATE_FUNCTIONS(22,      5, UNUSED, UNUSED, 0, 0, 0), /* GPIO22, altA controlled by bit 5 */
-       ALTERNATE_FUNCTIONS(23,      6, UNUSED, UNUSED, 0, 0, 0), /* GPIO23, altA controlled by bit 6 */
-       ALTERNATE_FUNCTIONS(24,      7, UNUSED, UNUSED, 0, 0, 0), /* GPIO24, altA controlled by bit 7 */
-
-       ALTERNATE_FUNCTIONS(25,      0, UNUSED, UNUSED, 0, 0, 0), /* GPIO25, altA controlled by bit 0 */
-       /* pin 26 special case, no alternate function, bit 1 reserved */
-       ALTERNATE_FUNCTIONS(26, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* GPIO26 */
-       ALTERNATE_FUNCTIONS(27,      2, UNUSED, UNUSED, 0, 0, 0), /* GPIO27, altA controlled by bit 2 */
-       ALTERNATE_FUNCTIONS(28,      3, UNUSED, UNUSED, 0, 0, 0), /* GPIO28, altA controlled by bit 3 */
-       ALTERNATE_FUNCTIONS(29,      4, UNUSED, UNUSED, 0, 0, 0), /* GPIO29, altA controlled by bit 4 */
-       ALTERNATE_FUNCTIONS(30,      5, UNUSED, UNUSED, 0, 0, 0), /* GPIO30, altA controlled by bit 5 */
-       ALTERNATE_FUNCTIONS(31,      6, UNUSED, UNUSED, 0, 0, 0), /* GPIO31, altA controlled by bit 6 */
-       ALTERNATE_FUNCTIONS(32,      7, UNUSED, UNUSED, 0, 0, 0), /* GPIO32, altA controlled by bit 7 */
-
-       ALTERNATE_FUNCTIONS(33, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO33 */
-       ALTERNATE_FUNCTIONS(34,      1, UNUSED, UNUSED, 0, 0, 0), /* GPIO34, altA controlled by bit 1 */
-       /* pin 35 special case, no alternate function, bit 2 reserved */
-       ALTERNATE_FUNCTIONS(35, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* GPIO35 */
-       ALTERNATE_FUNCTIONS(36,      3, UNUSED, UNUSED, 0, 0, 0), /* GPIO36, altA controlled by bit 3 */
-       ALTERNATE_FUNCTIONS(37,      4, UNUSED, UNUSED, 0, 0, 0), /* GPIO37, altA controlled by bit 4 */
-       ALTERNATE_FUNCTIONS(38,      5, UNUSED, UNUSED, 0, 0, 0), /* GPIO38, altA controlled by bit 5 */
-       ALTERNATE_FUNCTIONS(39,      6, UNUSED, UNUSED, 0, 0, 0), /* GPIO39, altA controlled by bit 6 */
-       ALTERNATE_FUNCTIONS(40,      7, UNUSED, UNUSED, 0, 0, 0), /* GPIO40, altA controlled by bit 7 */
-
-       ALTERNATE_FUNCTIONS(41,      0, UNUSED, UNUSED, 0, 0, 0), /* GPIO41, altA controlled by bit 0 */
-       ALTERNATE_FUNCTIONS(42,      1, UNUSED, UNUSED, 0, 0, 0), /* GPIO42, altA controlled by bit 1 */
-};
-
-/*
- * Only some GPIOs are interrupt capable, and they are
- * organized in discontiguous clusters:
- *
- *     GPIO6 to GPIO13
- *     GPIO24 and GPIO25
- *     GPIO36 to GPIO41
- */
-static struct abx500_gpio_irq_cluster ab8500_gpio_irq_cluster[] = {
-       GPIO_IRQ_CLUSTER(6,  13, AB8500_INT_GPIO6R),
-       GPIO_IRQ_CLUSTER(24, 25, AB8500_INT_GPIO24R),
-       GPIO_IRQ_CLUSTER(36, 41, AB8500_INT_GPIO36R),
-};
-
-static struct abx500_pinctrl_soc_data ab8500_soc = {
-       .gpio_ranges = ab8500_pinranges,
-       .gpio_num_ranges = ARRAY_SIZE(ab8500_pinranges),
-       .pins = ab8500_pins,
-       .npins = ARRAY_SIZE(ab8500_pins),
-       .functions = ab8500_functions,
-       .nfunctions = ARRAY_SIZE(ab8500_functions),
-       .groups = ab8500_groups,
-       .ngroups = ARRAY_SIZE(ab8500_groups),
-       .alternate_functions = ab8500_alternate_functions,
-       .gpio_irq_cluster = ab8500_gpio_irq_cluster,
-       .ngpio_irq_cluster = ARRAY_SIZE(ab8500_gpio_irq_cluster),
-       .irq_gpio_rising_offset = AB8500_INT_GPIO6R,
-       .irq_gpio_falling_offset = AB8500_INT_GPIO6F,
-       .irq_gpio_factor = 1,
-};
-
-void abx500_pinctrl_ab8500_init(struct abx500_pinctrl_soc_data **soc)
-{
-       *soc = &ab8500_soc;
-}
diff --git a/drivers/pinctrl/pinctrl-ab8505.c b/drivers/pinctrl/pinctrl-ab8505.c
deleted file mode 100644 (file)
index bf0ef4a..0000000
+++ /dev/null
@@ -1,381 +0,0 @@
-/*
- * Copyright (C) ST-Ericsson SA 2012
- *
- * Author: Patrice Chotard <patrice.chotard@stericsson.com> for ST-Ericsson.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/gpio.h>
-#include <linux/pinctrl/pinctrl.h>
-#include <linux/mfd/abx500/ab8500.h>
-#include "pinctrl-abx500.h"
-
-/* All the pins that can be used for GPIO and some other functions */
-#define ABX500_GPIO(offset)    (offset)
-
-#define AB8505_PIN_N4          ABX500_GPIO(1)
-#define AB8505_PIN_R5          ABX500_GPIO(2)
-#define AB8505_PIN_P5          ABX500_GPIO(3)
-/* hole */
-#define AB8505_PIN_B16         ABX500_GPIO(10)
-#define AB8505_PIN_B17         ABX500_GPIO(11)
-/* hole */
-#define AB8505_PIN_D17         ABX500_GPIO(13)
-#define AB8505_PIN_C16         ABX500_GPIO(14)
-/* hole */
-#define AB8505_PIN_P2          ABX500_GPIO(17)
-#define AB8505_PIN_N3          ABX500_GPIO(18)
-#define AB8505_PIN_T1          ABX500_GPIO(19)
-#define AB8505_PIN_P3          ABX500_GPIO(20)
-/* hole */
-#define AB8505_PIN_H14         ABX500_GPIO(34)
-/* hole */
-#define AB8505_PIN_J15         ABX500_GPIO(40)
-#define AB8505_PIN_J14         ABX500_GPIO(41)
-/* hole */
-#define AB8505_PIN_L4          ABX500_GPIO(50)
-/* hole */
-#define AB8505_PIN_D16         ABX500_GPIO(52)
-#define AB8505_PIN_D15         ABX500_GPIO(53)
-
-/* indicates the higher GPIO number */
-#define AB8505_GPIO_MAX_NUMBER 53
-
-/*
- * The names of the pins are denoted by GPIO number and ball name, even
- * though they can be used for other things than GPIO, this is the first
- * column in the table of the data sheet and often used on schematics and
- * such.
- */
-static const struct pinctrl_pin_desc ab8505_pins[] = {
-       PINCTRL_PIN(AB8505_PIN_N4, "GPIO1_N4"),
-       PINCTRL_PIN(AB8505_PIN_R5, "GPIO2_R5"),
-       PINCTRL_PIN(AB8505_PIN_P5, "GPIO3_P5"),
-/* hole */
-       PINCTRL_PIN(AB8505_PIN_B16, "GPIO10_B16"),
-       PINCTRL_PIN(AB8505_PIN_B17, "GPIO11_B17"),
-/* hole */
-       PINCTRL_PIN(AB8505_PIN_D17, "GPIO13_D17"),
-       PINCTRL_PIN(AB8505_PIN_C16, "GPIO14_C16"),
-/* hole */
-       PINCTRL_PIN(AB8505_PIN_P2, "GPIO17_P2"),
-       PINCTRL_PIN(AB8505_PIN_N3, "GPIO18_N3"),
-       PINCTRL_PIN(AB8505_PIN_T1, "GPIO19_T1"),
-       PINCTRL_PIN(AB8505_PIN_P3, "GPIO20_P3"),
-/* hole */
-       PINCTRL_PIN(AB8505_PIN_H14, "GPIO34_H14"),
-/* hole */
-       PINCTRL_PIN(AB8505_PIN_J15, "GPIO40_J15"),
-       PINCTRL_PIN(AB8505_PIN_J14, "GPIO41_J14"),
-/* hole */
-       PINCTRL_PIN(AB8505_PIN_L4, "GPIO50_L4"),
-/* hole */
-       PINCTRL_PIN(AB8505_PIN_D16, "GPIO52_D16"),
-       PINCTRL_PIN(AB8505_PIN_D15, "GPIO53_D15"),
-};
-
-/*
- * Maps local GPIO offsets to local pin numbers
- */
-static const struct abx500_pinrange ab8505_pinranges[] = {
-       ABX500_PINRANGE(1, 3, ABX500_ALT_A),
-       ABX500_PINRANGE(10, 2, ABX500_DEFAULT),
-       ABX500_PINRANGE(13, 1, ABX500_DEFAULT),
-       ABX500_PINRANGE(14, 1, ABX500_ALT_A),
-       ABX500_PINRANGE(17, 4, ABX500_ALT_A),
-       ABX500_PINRANGE(34, 1, ABX500_ALT_A),
-       ABX500_PINRANGE(40, 2, ABX500_ALT_A),
-       ABX500_PINRANGE(50, 1, ABX500_DEFAULT),
-       ABX500_PINRANGE(52, 2, ABX500_ALT_A),
-};
-
-/*
- * Read the pin group names like this:
- * sysclkreq2_d_1 = first groups of pins for sysclkreq2 on default function
- *
- * The groups are arranged as sets per altfunction column, so we can
- * mux in one group at a time by selecting the same altfunction for them
- * all. When functions require pins on different altfunctions, you need
- * to combine several groups.
- */
-
-/* default column */
-static const unsigned sysclkreq2_d_1_pins[] = { AB8505_PIN_N4 };
-static const unsigned sysclkreq3_d_1_pins[] = { AB8505_PIN_R5 };
-static const unsigned sysclkreq4_d_1_pins[] = { AB8505_PIN_P5 };
-static const unsigned gpio10_d_1_pins[] = { AB8505_PIN_B16 };
-static const unsigned gpio11_d_1_pins[] = { AB8505_PIN_B17 };
-static const unsigned gpio13_d_1_pins[] = { AB8505_PIN_D17 };
-static const unsigned pwmout1_d_1_pins[] = { AB8505_PIN_C16 };
-/* audio data interface 2*/
-static const unsigned adi2_d_1_pins[] = { AB8505_PIN_P2, AB8505_PIN_N3,
-                                       AB8505_PIN_T1, AB8505_PIN_P3 };
-static const unsigned extcpena_d_1_pins[] = { AB8505_PIN_H14 };
-/* modem SDA/SCL */
-static const unsigned modsclsda_d_1_pins[] = { AB8505_PIN_J15, AB8505_PIN_J14 };
-static const unsigned gpio50_d_1_pins[] = { AB8505_PIN_L4 };
-static const unsigned resethw_d_1_pins[] = { AB8505_PIN_D16 };
-static const unsigned service_d_1_pins[] = { AB8505_PIN_D15 };
-
-/* Altfunction A column */
-static const unsigned gpio1_a_1_pins[] = { AB8505_PIN_N4 };
-static const unsigned gpio2_a_1_pins[] = { AB8505_PIN_R5 };
-static const unsigned gpio3_a_1_pins[] = { AB8505_PIN_P5 };
-static const unsigned hiqclkena_a_1_pins[] = { AB8505_PIN_B16 };
-static const unsigned pdmclk_a_1_pins[] = { AB8505_PIN_B17 };
-static const unsigned uarttxdata_a_1_pins[] = { AB8505_PIN_D17 };
-static const unsigned gpio14_a_1_pins[] = { AB8505_PIN_C16 };
-static const unsigned gpio17_a_1_pins[] = { AB8505_PIN_P2 };
-static const unsigned gpio18_a_1_pins[] = { AB8505_PIN_N3 };
-static const unsigned gpio19_a_1_pins[] = { AB8505_PIN_T1 };
-static const unsigned gpio20_a_1_pins[] = { AB8505_PIN_P3 };
-static const unsigned gpio34_a_1_pins[] = { AB8505_PIN_H14 };
-static const unsigned gpio40_a_1_pins[] = { AB8505_PIN_J15 };
-static const unsigned gpio41_a_1_pins[] = { AB8505_PIN_J14 };
-static const unsigned uartrxdata_a_1_pins[] = { AB8505_PIN_J14 };
-static const unsigned gpio50_a_1_pins[] = { AB8505_PIN_L4 };
-static const unsigned gpio52_a_1_pins[] = { AB8505_PIN_D16 };
-static const unsigned gpio53_a_1_pins[] = { AB8505_PIN_D15 };
-
-/* Altfunction B colum */
-static const unsigned pdmdata_b_1_pins[] = { AB8505_PIN_B16 };
-static const unsigned extvibrapwm1_b_1_pins[] = { AB8505_PIN_D17 };
-static const unsigned extvibrapwm2_b_1_pins[] = { AB8505_PIN_L4 };
-
-/* Altfunction C column */
-static const unsigned usbvdat_c_1_pins[] = { AB8505_PIN_D17 };
-
-#define AB8505_PIN_GROUP(a, b) { .name = #a, .pins = a##_pins,         \
-                       .npins = ARRAY_SIZE(a##_pins), .altsetting = b }
-
-static const struct abx500_pingroup ab8505_groups[] = {
-       AB8505_PIN_GROUP(sysclkreq2_d_1, ABX500_DEFAULT),
-       AB8505_PIN_GROUP(sysclkreq3_d_1, ABX500_DEFAULT),
-       AB8505_PIN_GROUP(sysclkreq4_d_1, ABX500_DEFAULT),
-       AB8505_PIN_GROUP(gpio10_d_1, ABX500_DEFAULT),
-       AB8505_PIN_GROUP(gpio11_d_1, ABX500_DEFAULT),
-       AB8505_PIN_GROUP(gpio13_d_1, ABX500_DEFAULT),
-       AB8505_PIN_GROUP(pwmout1_d_1, ABX500_DEFAULT),
-       AB8505_PIN_GROUP(adi2_d_1, ABX500_DEFAULT),
-       AB8505_PIN_GROUP(extcpena_d_1, ABX500_DEFAULT),
-       AB8505_PIN_GROUP(modsclsda_d_1, ABX500_DEFAULT),
-       AB8505_PIN_GROUP(gpio50_d_1, ABX500_DEFAULT),
-       AB8505_PIN_GROUP(resethw_d_1, ABX500_DEFAULT),
-       AB8505_PIN_GROUP(service_d_1, ABX500_DEFAULT),
-       AB8505_PIN_GROUP(gpio1_a_1, ABX500_ALT_A),
-       AB8505_PIN_GROUP(gpio2_a_1, ABX500_ALT_A),
-       AB8505_PIN_GROUP(gpio3_a_1, ABX500_ALT_A),
-       AB8505_PIN_GROUP(hiqclkena_a_1, ABX500_ALT_A),
-       AB8505_PIN_GROUP(pdmclk_a_1, ABX500_ALT_A),
-       AB8505_PIN_GROUP(uarttxdata_a_1, ABX500_ALT_A),
-       AB8505_PIN_GROUP(gpio14_a_1, ABX500_ALT_A),
-       AB8505_PIN_GROUP(gpio17_a_1, ABX500_ALT_A),
-       AB8505_PIN_GROUP(gpio18_a_1, ABX500_ALT_A),
-       AB8505_PIN_GROUP(gpio19_a_1, ABX500_ALT_A),
-       AB8505_PIN_GROUP(gpio20_a_1, ABX500_ALT_A),
-       AB8505_PIN_GROUP(gpio34_a_1, ABX500_ALT_A),
-       AB8505_PIN_GROUP(gpio40_a_1, ABX500_ALT_A),
-       AB8505_PIN_GROUP(gpio41_a_1, ABX500_ALT_A),
-       AB8505_PIN_GROUP(uartrxdata_a_1, ABX500_ALT_A),
-       AB8505_PIN_GROUP(gpio52_a_1, ABX500_ALT_A),
-       AB8505_PIN_GROUP(gpio53_a_1, ABX500_ALT_A),
-       AB8505_PIN_GROUP(pdmdata_b_1, ABX500_ALT_B),
-       AB8505_PIN_GROUP(extvibrapwm1_b_1, ABX500_ALT_B),
-       AB8505_PIN_GROUP(extvibrapwm2_b_1, ABX500_ALT_B),
-       AB8505_PIN_GROUP(usbvdat_c_1, ABX500_ALT_C),
-};
-
-/* We use this macro to define the groups applicable to a function */
-#define AB8505_FUNC_GROUPS(a, b...)       \
-static const char * const a##_groups[] = { b };
-
-AB8505_FUNC_GROUPS(sysclkreq, "sysclkreq2_d_1", "sysclkreq3_d_1",
-               "sysclkreq4_d_1");
-AB8505_FUNC_GROUPS(gpio, "gpio1_a_1", "gpio2_a_1", "gpio3_a_1",
-               "gpio10_d_1", "gpio11_d_1", "gpio13_d_1", "gpio14_a_1",
-               "gpio17_a_1", "gpio18_a_1", "gpio19_a_1", "gpio20_a_1",
-               "gpio34_a_1", "gpio40_a_1", "gpio41_a_1", "gpio50_d_1",
-               "gpio52_a_1", "gpio53_a_1");
-AB8505_FUNC_GROUPS(pwmout, "pwmout1_d_1");
-AB8505_FUNC_GROUPS(adi2, "adi2_d_1");
-AB8505_FUNC_GROUPS(extcpena, "extcpena_d_1");
-AB8505_FUNC_GROUPS(modsclsda, "modsclsda_d_1");
-AB8505_FUNC_GROUPS(resethw, "resethw_d_1");
-AB8505_FUNC_GROUPS(service, "service_d_1");
-AB8505_FUNC_GROUPS(hiqclkena, "hiqclkena_a_1");
-AB8505_FUNC_GROUPS(pdm, "pdmclk_a_1", "pdmdata_b_1");
-AB8505_FUNC_GROUPS(uartdata, "uarttxdata_a_1", "uartrxdata_a_1");
-AB8505_FUNC_GROUPS(extvibra, "extvibrapwm1_b_1", "extvibrapwm2_b_1");
-AB8505_FUNC_GROUPS(usbvdat, "usbvdat_c_1");
-
-#define FUNCTION(fname)                                        \
-       {                                               \
-               .name = #fname,                         \
-               .groups = fname##_groups,               \
-               .ngroups = ARRAY_SIZE(fname##_groups),  \
-       }
-
-static const struct abx500_function ab8505_functions[] = {
-       FUNCTION(sysclkreq),
-       FUNCTION(gpio),
-       FUNCTION(pwmout),
-       FUNCTION(adi2),
-       FUNCTION(extcpena),
-       FUNCTION(modsclsda),
-       FUNCTION(resethw),
-       FUNCTION(service),
-       FUNCTION(hiqclkena),
-       FUNCTION(pdm),
-       FUNCTION(uartdata),
-       FUNCTION(extvibra),
-       FUNCTION(extvibra),
-       FUNCTION(usbvdat),
-};
-
-/*
- * this table translates what's is in the AB8505 specification regarding the
- * balls alternate functions (as for DB, default, ALT_A, ALT_B and ALT_C).
- * ALTERNATE_FUNCTIONS(GPIO_NUMBER, GPIOSEL bit, ALTERNATFUNC bit1,
- * ALTERNATEFUNC bit2, ALTA val, ALTB val, ALTC val),
- *
- * example :
- *
- *     ALTERNATE_FUNCTIONS(13,     4,      3,      4, 1, 0, 2),
- *     means that pin AB8505_PIN_D18 (pin 13) supports 4 mux (default/ALT_A,
- *     ALT_B and ALT_C), so GPIOSEL and ALTERNATFUNC registers are used to
- *     select the mux. ALTA, ALTB and ALTC val indicates values to write in
- *     ALTERNATFUNC register. We need to specifies these values as SOC
- *     designers didn't apply the same logic on how to select mux in the
- *     ABx500 family.
- *
- *     As this pins supports at least ALT_B mux, default mux is
- *     selected by writing 1 in GPIOSEL bit :
- *
- *             | GPIOSEL bit=4 | alternatfunc bit2=4 | alternatfunc bit1=3
- *     default |       1       |          0          |          0
- *     alt_A   |       0       |          0          |          1
- *     alt_B   |       0       |          0          |          0
- *     alt_C   |       0       |          1          |          0
- *
- *     ALTERNATE_FUNCTIONS(1,      0, UNUSED, UNUSED),
- *     means that pin AB9540_PIN_R4 (pin 1) supports 2 mux, so only GPIOSEL
- *     register is used to select the mux. As this pins doesn't support at
- *     least ALT_B mux, default mux is by writing 0 in GPIOSEL bit :
- *
- *             | GPIOSEL bit=0 | alternatfunc bit2=  | alternatfunc bit1=
- *     default |       0       |          0          |          0
- *     alt_A   |       1       |          0          |          0
- */
-
-static struct
-alternate_functions ab8505_alternate_functions[AB8505_GPIO_MAX_NUMBER + 1] = {
-       ALTERNATE_FUNCTIONS(0, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO0 */
-       ALTERNATE_FUNCTIONS(1,      0, UNUSED, UNUSED, 0, 0, 0), /* GPIO1, altA controlled by bit 0 */
-       ALTERNATE_FUNCTIONS(2,      1, UNUSED, UNUSED, 0, 0, 0), /* GPIO2, altA controlled by bit 1 */
-       ALTERNATE_FUNCTIONS(3,      2, UNUSED, UNUSED, 0, 0, 0), /* GPIO3, altA controlled by bit 2*/
-       ALTERNATE_FUNCTIONS(4, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO4, bit 3 reserved */
-       ALTERNATE_FUNCTIONS(5, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO5, bit 4 reserved */
-       ALTERNATE_FUNCTIONS(6, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO6, bit 5 reserved */
-       ALTERNATE_FUNCTIONS(7, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO7, bit 6 reserved */
-       ALTERNATE_FUNCTIONS(8, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO8, bit 7 reserved */
-
-       ALTERNATE_FUNCTIONS(9, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO9, bit 0 reserved */
-       ALTERNATE_FUNCTIONS(10,      1,      0, UNUSED, 1, 0, 0), /* GPIO10, altA and altB controlled by bit 0 */
-       ALTERNATE_FUNCTIONS(11,      2,      1, UNUSED, 0, 0, 0), /* GPIO11, altA controlled by bit 2 */
-       ALTERNATE_FUNCTIONS(12, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO12, bit3 reseved */
-       ALTERNATE_FUNCTIONS(13,      4,      3,      4, 1, 0, 2), /* GPIO13, altA altB and altC controlled by bit 3 and 4 */
-       ALTERNATE_FUNCTIONS(14,      5, UNUSED, UNUSED, 0, 0, 0), /* GPIO14, altA controlled by bit 5 */
-       ALTERNATE_FUNCTIONS(15, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO15, bit 6 reserved */
-       ALTERNATE_FUNCTIONS(16, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO15, bit 7 reserved  */
-       /*
-        * pins 17 to 20 are special case, only bit 0 is used to select
-        * alternate function for these 4 pins.
-        * bits 1 to 3 are reserved
-        */
-       ALTERNATE_FUNCTIONS(17,      0, UNUSED, UNUSED, 0, 0, 0), /* GPIO17, altA controlled by bit 0 */
-       ALTERNATE_FUNCTIONS(18,      0, UNUSED, UNUSED, 0, 0, 0), /* GPIO18, altA controlled by bit 0 */
-       ALTERNATE_FUNCTIONS(19,      0, UNUSED, UNUSED, 0, 0, 0), /* GPIO19, altA controlled by bit 0 */
-       ALTERNATE_FUNCTIONS(20,      0, UNUSED, UNUSED, 0, 0, 0), /* GPIO20, altA controlled by bit 0 */
-       ALTERNATE_FUNCTIONS(21, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO21, bit 4 reserved */
-       ALTERNATE_FUNCTIONS(22, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO22, bit 5 reserved */
-       ALTERNATE_FUNCTIONS(23, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO23, bit 6 reserved */
-       ALTERNATE_FUNCTIONS(24, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO24, bit 7 reserved */
-
-       ALTERNATE_FUNCTIONS(25, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO25, bit 0 reserved */
-       ALTERNATE_FUNCTIONS(26, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO26, bit 1 reserved */
-       ALTERNATE_FUNCTIONS(27, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO27, bit 2 reserved */
-       ALTERNATE_FUNCTIONS(28, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO28, bit 3 reserved */
-       ALTERNATE_FUNCTIONS(29, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO29, bit 4 reserved */
-       ALTERNATE_FUNCTIONS(30, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO30, bit 5 reserved */
-       ALTERNATE_FUNCTIONS(31, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO31, bit 6 reserved */
-       ALTERNATE_FUNCTIONS(32, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO32, bit 7 reserved */
-
-       ALTERNATE_FUNCTIONS(33, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO33, bit 0 reserved */
-       ALTERNATE_FUNCTIONS(34,      1, UNUSED, UNUSED, 0, 0, 0), /* GPIO34, altA controlled by bit 1 */
-       ALTERNATE_FUNCTIONS(35, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO35, bit 2 reserved */
-       ALTERNATE_FUNCTIONS(36, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO36, bit 2 reserved */
-       ALTERNATE_FUNCTIONS(37, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO37, bit 2 reserved */
-       ALTERNATE_FUNCTIONS(38, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO38, bit 2 reserved */
-       ALTERNATE_FUNCTIONS(39, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO39, bit 2 reserved */
-       ALTERNATE_FUNCTIONS(40,      7, UNUSED, UNUSED, 0, 0, 0), /* GPIO40, altA controlled by bit 7*/
-
-       ALTERNATE_FUNCTIONS(41,      0, UNUSED, UNUSED, 0, 0, 0), /* GPIO41, altA controlled by bit 0 */
-       ALTERNATE_FUNCTIONS(42, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO42, bit 1 reserved */
-       ALTERNATE_FUNCTIONS(43, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO43, bit 2 reserved */
-       ALTERNATE_FUNCTIONS(44, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO44, bit 3 reserved */
-       ALTERNATE_FUNCTIONS(45, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO45, bit 4 reserved */
-       ALTERNATE_FUNCTIONS(46, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO46, bit 5 reserved */
-       ALTERNATE_FUNCTIONS(47, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO47, bit 6 reserved */
-       ALTERNATE_FUNCTIONS(48, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO48, bit 7 reserved */
-
-       ALTERNATE_FUNCTIONS(49, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO49, bit 0 reserved */
-       ALTERNATE_FUNCTIONS(50,      1,      2, UNUSED, 1, 0, 0), /* GPIO50, altA controlled by bit 1 */
-       ALTERNATE_FUNCTIONS(51, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO49, bit 0 reserved */
-       ALTERNATE_FUNCTIONS(52,      3, UNUSED, UNUSED, 0, 0, 0), /* GPIO52, altA controlled by bit 3 */
-       ALTERNATE_FUNCTIONS(53,      4, UNUSED, UNUSED, 0, 0, 0), /* GPIO53, altA controlled by bit 4 */
-};
-
-/*
- * For AB8505 Only some GPIOs are interrupt capable, and they are
- * organized in discontiguous clusters:
- *
- *     GPIO10 to GPIO11
- *     GPIO13
- *     GPIO40 and GPIO41
- *     GPIO50
- *     GPIO52 to GPIO53
- */
-static struct abx500_gpio_irq_cluster ab8505_gpio_irq_cluster[] = {
-       GPIO_IRQ_CLUSTER(10, 11, AB8500_INT_GPIO10R),
-       GPIO_IRQ_CLUSTER(13, 13, AB8500_INT_GPIO13R),
-       GPIO_IRQ_CLUSTER(40, 41, AB8500_INT_GPIO40R),
-       GPIO_IRQ_CLUSTER(50, 50, AB9540_INT_GPIO50R),
-       GPIO_IRQ_CLUSTER(52, 53, AB9540_INT_GPIO52R),
-};
-
-static struct abx500_pinctrl_soc_data ab8505_soc = {
-       .gpio_ranges = ab8505_pinranges,
-       .gpio_num_ranges = ARRAY_SIZE(ab8505_pinranges),
-       .pins = ab8505_pins,
-       .npins = ARRAY_SIZE(ab8505_pins),
-       .functions = ab8505_functions,
-       .nfunctions = ARRAY_SIZE(ab8505_functions),
-       .groups = ab8505_groups,
-       .ngroups = ARRAY_SIZE(ab8505_groups),
-       .alternate_functions = ab8505_alternate_functions,
-       .gpio_irq_cluster = ab8505_gpio_irq_cluster,
-       .ngpio_irq_cluster = ARRAY_SIZE(ab8505_gpio_irq_cluster),
-       .irq_gpio_rising_offset = AB8500_INT_GPIO6R,
-       .irq_gpio_falling_offset = AB8500_INT_GPIO6F,
-       .irq_gpio_factor = 1,
-};
-
-void
-abx500_pinctrl_ab8505_init(struct abx500_pinctrl_soc_data **soc)
-{
-       *soc = &ab8505_soc;
-}
diff --git a/drivers/pinctrl/pinctrl-ab8540.c b/drivers/pinctrl/pinctrl-ab8540.c
deleted file mode 100644 (file)
index 9867535..0000000
+++ /dev/null
@@ -1,408 +0,0 @@
-/*
- * Copyright (C) ST-Ericsson SA 2012
- *
- * Author: Patrice Chotard <patrice.chotard@stericsson.com> for ST-Ericsson.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/gpio.h>
-#include <linux/pinctrl/pinctrl.h>
-#include <linux/mfd/abx500/ab8500.h>
-#include "pinctrl-abx500.h"
-
-/* All the pins that can be used for GPIO and some other functions */
-#define ABX500_GPIO(offset)            (offset)
-
-#define AB8540_PIN_J16         ABX500_GPIO(1)
-#define AB8540_PIN_D17         ABX500_GPIO(2)
-#define AB8540_PIN_C12         ABX500_GPIO(3)
-#define AB8540_PIN_G12         ABX500_GPIO(4)
-/* hole */
-#define AB8540_PIN_D16         ABX500_GPIO(14)
-#define AB8540_PIN_F15         ABX500_GPIO(15)
-#define AB8540_PIN_J8          ABX500_GPIO(16)
-#define AB8540_PIN_K16         ABX500_GPIO(17)
-#define AB8540_PIN_G15         ABX500_GPIO(18)
-#define AB8540_PIN_F17         ABX500_GPIO(19)
-#define AB8540_PIN_E17         ABX500_GPIO(20)
-/* hole */
-#define AB8540_PIN_AA16                ABX500_GPIO(27)
-#define AB8540_PIN_W18         ABX500_GPIO(28)
-#define AB8540_PIN_Y15         ABX500_GPIO(29)
-#define AB8540_PIN_W16         ABX500_GPIO(30)
-#define AB8540_PIN_V15         ABX500_GPIO(31)
-#define AB8540_PIN_W17         ABX500_GPIO(32)
-/* hole */
-#define AB8540_PIN_D12         ABX500_GPIO(42)
-#define AB8540_PIN_P4          ABX500_GPIO(43)
-#define AB8540_PIN_AB1         ABX500_GPIO(44)
-#define AB8540_PIN_K7          ABX500_GPIO(45)
-#define AB8540_PIN_L7          ABX500_GPIO(46)
-#define AB8540_PIN_G10         ABX500_GPIO(47)
-#define AB8540_PIN_K12         ABX500_GPIO(48)
-/* hole */
-#define AB8540_PIN_N8          ABX500_GPIO(51)
-#define AB8540_PIN_P12         ABX500_GPIO(52)
-#define AB8540_PIN_K8          ABX500_GPIO(53)
-#define AB8540_PIN_J11         ABX500_GPIO(54)
-#define AB8540_PIN_AC2         ABX500_GPIO(55)
-#define AB8540_PIN_AB2         ABX500_GPIO(56)
-
-/* indicates the highest GPIO number */
-#define AB8540_GPIO_MAX_NUMBER 56
-
-/*
- * The names of the pins are denoted by GPIO number and ball name, even
- * though they can be used for other things than GPIO, this is the first
- * column in the table of the data sheet and often used on schematics and
- * such.
- */
-static const struct pinctrl_pin_desc ab8540_pins[] = {
-       PINCTRL_PIN(AB8540_PIN_J16, "GPIO1_J16"),
-       PINCTRL_PIN(AB8540_PIN_D17, "GPIO2_D17"),
-       PINCTRL_PIN(AB8540_PIN_C12, "GPIO3_C12"),
-       PINCTRL_PIN(AB8540_PIN_G12, "GPIO4_G12"),
-       /* hole */
-       PINCTRL_PIN(AB8540_PIN_D16, "GPIO14_D16"),
-       PINCTRL_PIN(AB8540_PIN_F15, "GPIO15_F15"),
-       PINCTRL_PIN(AB8540_PIN_J8, "GPIO16_J8"),
-       PINCTRL_PIN(AB8540_PIN_K16, "GPIO17_K16"),
-       PINCTRL_PIN(AB8540_PIN_G15, "GPIO18_G15"),
-       PINCTRL_PIN(AB8540_PIN_F17, "GPIO19_F17"),
-       PINCTRL_PIN(AB8540_PIN_E17, "GPIO20_E17"),
-       /* hole */
-       PINCTRL_PIN(AB8540_PIN_AA16, "GPIO27_AA16"),
-       PINCTRL_PIN(AB8540_PIN_W18, "GPIO28_W18"),
-       PINCTRL_PIN(AB8540_PIN_Y15, "GPIO29_Y15"),
-       PINCTRL_PIN(AB8540_PIN_W16, "GPIO30_W16"),
-       PINCTRL_PIN(AB8540_PIN_V15, "GPIO31_V15"),
-       PINCTRL_PIN(AB8540_PIN_W17, "GPIO32_W17"),
-       /* hole */
-       PINCTRL_PIN(AB8540_PIN_D12, "GPIO42_D12"),
-       PINCTRL_PIN(AB8540_PIN_P4, "GPIO43_P4"),
-       PINCTRL_PIN(AB8540_PIN_AB1, "GPIO44_AB1"),
-       PINCTRL_PIN(AB8540_PIN_K7, "GPIO45_K7"),
-       PINCTRL_PIN(AB8540_PIN_L7, "GPIO46_L7"),
-       PINCTRL_PIN(AB8540_PIN_G10, "GPIO47_G10"),
-       PINCTRL_PIN(AB8540_PIN_K12, "GPIO48_K12"),
-       /* hole */
-       PINCTRL_PIN(AB8540_PIN_N8, "GPIO51_N8"),
-       PINCTRL_PIN(AB8540_PIN_P12, "GPIO52_P12"),
-       PINCTRL_PIN(AB8540_PIN_K8, "GPIO53_K8"),
-       PINCTRL_PIN(AB8540_PIN_J11, "GPIO54_J11"),
-       PINCTRL_PIN(AB8540_PIN_AC2, "GPIO55_AC2"),
-       PINCTRL_PIN(AB8540_PIN_AB2, "GPIO56_AB2"),
-};
-
-/*
- * Maps local GPIO offsets to local pin numbers
- */
-static const struct abx500_pinrange ab8540_pinranges[] = {
-       ABX500_PINRANGE(1, 4, ABX500_ALT_A),
-       ABX500_PINRANGE(14, 7, ABX500_ALT_A),
-       ABX500_PINRANGE(27, 6, ABX500_ALT_A),
-       ABX500_PINRANGE(42, 7, ABX500_ALT_A),
-       ABX500_PINRANGE(51, 6, ABX500_ALT_A),
-};
-
-/*
- * Read the pin group names like this:
- * sysclkreq2_d_1 = first groups of pins for sysclkreq2 on default function
- *
- * The groups are arranged as sets per altfunction column, so we can
- * mux in one group at a time by selecting the same altfunction for them
- * all. When functions require pins on different altfunctions, you need
- * to combine several groups.
- */
-
-/* default column */
-static const unsigned sysclkreq2_d_1_pins[] = { AB8540_PIN_J16 };
-static const unsigned sysclkreq3_d_1_pins[] = { AB8540_PIN_D17 };
-static const unsigned sysclkreq4_d_1_pins[] = { AB8540_PIN_C12 };
-static const unsigned sysclkreq6_d_1_pins[] = { AB8540_PIN_G12 };
-static const unsigned pwmout1_d_1_pins[] = { AB8540_PIN_D16 };
-static const unsigned pwmout2_d_1_pins[] = { AB8540_PIN_F15 };
-static const unsigned pwmout3_d_1_pins[] = { AB8540_PIN_J8 };
-
-/* audio data interface 1*/
-static const unsigned adi1_d_1_pins[] = { AB8540_PIN_K16, AB8540_PIN_G15,
-                                       AB8540_PIN_F17, AB8540_PIN_E17 };
-/* Digital microphone 1 and 2 */
-static const unsigned dmic12_d_1_pins[] = { AB8540_PIN_AA16, AB8540_PIN_W18 };
-/* Digital microphone 3 and 4 */
-static const unsigned dmic34_d_1_pins[] = { AB8540_PIN_Y15, AB8540_PIN_W16 };
-/* Digital microphone 5 and 6 */
-static const unsigned dmic56_d_1_pins[] = { AB8540_PIN_V15, AB8540_PIN_W17 };
-static const unsigned sysclkreq5_d_1_pins[] = { AB8540_PIN_D12 };
-static const unsigned batremn_d_1_pins[] = { AB8540_PIN_P4 };
-static const unsigned service_d_1_pins[] = { AB8540_PIN_AB1 };
-static const unsigned pwrctrl0_d_1_pins[] = { AB8540_PIN_K7 };
-static const unsigned pwrctrl1_d_1_pins[] = { AB8540_PIN_L7 };
-static const unsigned pwmextvibra1_d_1_pins[] = { AB8540_PIN_G10 };
-static const unsigned pwmextvibra2_d_1_pins[] = { AB8540_PIN_K12 };
-static const unsigned gpio1_vbat_d_1_pins[] = { AB8540_PIN_N8 };
-static const unsigned gpio2_vbat_d_1_pins[] = { AB8540_PIN_P12 };
-static const unsigned gpio3_vbat_d_1_pins[] = { AB8540_PIN_K8 };
-static const unsigned gpio4_vbat_d_1_pins[] = { AB8540_PIN_J11 };
-static const unsigned pdmclkdat_d_1_pins[] = { AB8540_PIN_AC2, AB8540_PIN_AB2 };
-
-/* Altfunction A column */
-static const unsigned gpio1_a_1_pins[] = { AB8540_PIN_J16 };
-static const unsigned gpio2_a_1_pins[] = { AB8540_PIN_D17 };
-static const unsigned gpio3_a_1_pins[] = { AB8540_PIN_C12 };
-static const unsigned gpio4_a_1_pins[] = { AB8540_PIN_G12 };
-static const unsigned gpio14_a_1_pins[] = { AB8540_PIN_D16 };
-static const unsigned gpio15_a_1_pins[] = { AB8540_PIN_F15 };
-static const unsigned gpio16_a_1_pins[] = { AB8540_PIN_J8 };
-static const unsigned gpio17_a_1_pins[] = { AB8540_PIN_K16 };
-static const unsigned gpio18_a_1_pins[] = { AB8540_PIN_G15 };
-static const unsigned gpio19_a_1_pins[] = { AB8540_PIN_F17 };
-static const unsigned gpio20_a_1_pins[] = { AB8540_PIN_E17 };
-static const unsigned gpio27_a_1_pins[] = { AB8540_PIN_AA16 };
-static const unsigned gpio28_a_1_pins[] = { AB8540_PIN_W18 };
-static const unsigned gpio29_a_1_pins[] = { AB8540_PIN_Y15 };
-static const unsigned gpio30_a_1_pins[] = { AB8540_PIN_W16 };
-static const unsigned gpio31_a_1_pins[] = { AB8540_PIN_V15 };
-static const unsigned gpio32_a_1_pins[] = { AB8540_PIN_W17 };
-static const unsigned gpio42_a_1_pins[] = { AB8540_PIN_D12 };
-static const unsigned gpio43_a_1_pins[] = { AB8540_PIN_P4 };
-static const unsigned gpio44_a_1_pins[] = { AB8540_PIN_AB1 };
-static const unsigned gpio45_a_1_pins[] = { AB8540_PIN_K7 };
-static const unsigned gpio46_a_1_pins[] = { AB8540_PIN_L7 };
-static const unsigned gpio47_a_1_pins[] = { AB8540_PIN_G10 };
-static const unsigned gpio48_a_1_pins[] = { AB8540_PIN_K12 };
-static const unsigned gpio51_a_1_pins[] = { AB8540_PIN_N8 };
-static const unsigned gpio52_a_1_pins[] = { AB8540_PIN_P12 };
-static const unsigned gpio53_a_1_pins[] = { AB8540_PIN_K8 };
-static const unsigned gpio54_a_1_pins[] = { AB8540_PIN_J11 };
-static const unsigned gpio55_a_1_pins[] = { AB8540_PIN_AC2 };
-static const unsigned gpio56_a_1_pins[] = { AB8540_PIN_AB2 };
-
-#define AB8540_PIN_GROUP(a, b) { .name = #a, .pins = a##_pins,         \
-                       .npins = ARRAY_SIZE(a##_pins), .altsetting = b }
-
-static const struct abx500_pingroup ab8540_groups[] = {
-       /* default column */
-       AB8540_PIN_GROUP(sysclkreq2_d_1, ABX500_DEFAULT),
-       AB8540_PIN_GROUP(sysclkreq3_d_1, ABX500_DEFAULT),
-       AB8540_PIN_GROUP(sysclkreq4_d_1, ABX500_DEFAULT),
-       AB8540_PIN_GROUP(sysclkreq6_d_1, ABX500_DEFAULT),
-       AB8540_PIN_GROUP(pwmout1_d_1, ABX500_DEFAULT),
-       AB8540_PIN_GROUP(pwmout2_d_1, ABX500_DEFAULT),
-       AB8540_PIN_GROUP(pwmout3_d_1, ABX500_DEFAULT),
-       AB8540_PIN_GROUP(adi1_d_1, ABX500_DEFAULT),
-       AB8540_PIN_GROUP(dmic12_d_1, ABX500_DEFAULT),
-       AB8540_PIN_GROUP(dmic34_d_1, ABX500_DEFAULT),
-       AB8540_PIN_GROUP(dmic56_d_1, ABX500_DEFAULT),
-       AB8540_PIN_GROUP(sysclkreq5_d_1, ABX500_DEFAULT),
-       AB8540_PIN_GROUP(batremn_d_1, ABX500_DEFAULT),
-       AB8540_PIN_GROUP(service_d_1, ABX500_DEFAULT),
-       AB8540_PIN_GROUP(pwrctrl0_d_1, ABX500_DEFAULT),
-       AB8540_PIN_GROUP(pwrctrl1_d_1, ABX500_DEFAULT),
-       AB8540_PIN_GROUP(pwmextvibra1_d_1, ABX500_DEFAULT),
-       AB8540_PIN_GROUP(pwmextvibra2_d_1, ABX500_DEFAULT),
-       AB8540_PIN_GROUP(gpio1_vbat_d_1, ABX500_DEFAULT),
-       AB8540_PIN_GROUP(gpio2_vbat_d_1, ABX500_DEFAULT),
-       AB8540_PIN_GROUP(gpio3_vbat_d_1, ABX500_DEFAULT),
-       AB8540_PIN_GROUP(gpio4_vbat_d_1, ABX500_DEFAULT),
-       AB8540_PIN_GROUP(pdmclkdat_d_1, ABX500_DEFAULT),
-       /* Altfunction A column */
-       AB8540_PIN_GROUP(gpio1_a_1, ABX500_ALT_A),
-       AB8540_PIN_GROUP(gpio2_a_1, ABX500_ALT_A),
-       AB8540_PIN_GROUP(gpio3_a_1, ABX500_ALT_A),
-       AB8540_PIN_GROUP(gpio4_a_1, ABX500_ALT_A),
-       AB8540_PIN_GROUP(gpio14_a_1, ABX500_ALT_A),
-       AB8540_PIN_GROUP(gpio15_a_1, ABX500_ALT_A),
-       AB8540_PIN_GROUP(gpio16_a_1, ABX500_ALT_A),
-       AB8540_PIN_GROUP(gpio17_a_1, ABX500_ALT_A),
-       AB8540_PIN_GROUP(gpio18_a_1, ABX500_ALT_A),
-       AB8540_PIN_GROUP(gpio19_a_1, ABX500_ALT_A),
-       AB8540_PIN_GROUP(gpio20_a_1, ABX500_ALT_A),
-       AB8540_PIN_GROUP(gpio27_a_1, ABX500_ALT_A),
-       AB8540_PIN_GROUP(gpio28_a_1, ABX500_ALT_A),
-       AB8540_PIN_GROUP(gpio29_a_1, ABX500_ALT_A),
-       AB8540_PIN_GROUP(gpio30_a_1, ABX500_ALT_A),
-       AB8540_PIN_GROUP(gpio31_a_1, ABX500_ALT_A),
-       AB8540_PIN_GROUP(gpio32_a_1, ABX500_ALT_A),
-       AB8540_PIN_GROUP(gpio42_a_1, ABX500_ALT_A),
-       AB8540_PIN_GROUP(gpio43_a_1, ABX500_ALT_A),
-       AB8540_PIN_GROUP(gpio44_a_1, ABX500_ALT_A),
-       AB8540_PIN_GROUP(gpio45_a_1, ABX500_ALT_A),
-       AB8540_PIN_GROUP(gpio46_a_1, ABX500_ALT_A),
-       AB8540_PIN_GROUP(gpio47_a_1, ABX500_ALT_A),
-       AB8540_PIN_GROUP(gpio48_a_1, ABX500_ALT_A),
-       AB8540_PIN_GROUP(gpio51_a_1, ABX500_ALT_A),
-       AB8540_PIN_GROUP(gpio52_a_1, ABX500_ALT_A),
-       AB8540_PIN_GROUP(gpio53_a_1, ABX500_ALT_A),
-       AB8540_PIN_GROUP(gpio54_a_1, ABX500_ALT_A),
-       AB8540_PIN_GROUP(gpio55_a_1, ABX500_ALT_A),
-       AB8540_PIN_GROUP(gpio56_a_1, ABX500_ALT_A),
-};
-
-/* We use this macro to define the groups applicable to a function */
-#define AB8540_FUNC_GROUPS(a, b...)       \
-static const char * const a##_groups[] = { b };
-
-AB8540_FUNC_GROUPS(sysclkreq, "sysclkreq2_d_1", "sysclkreq3_d_1",
-               "sysclkreq4_d_1", "sysclkreq5_d_1", "sysclkreq6_d_1");
-AB8540_FUNC_GROUPS(gpio, "gpio1_a_1", "gpio2_a_1", "gpio3_a_1", "gpio4_a_1",
-               "gpio14_a_1", "gpio15_a_1", "gpio16_a_1", "gpio17_a_1",
-               "gpio18_a_1", "gpio19_a_1", "gpio20_a_1", "gpio27_a_1",
-               "gpio28_a_1", "gpio29_a_1", "gpio30_a_1", "gpio31_a_1",
-               "gpio32_a_1", "gpio42_a_1", "gpio43_a_1", "gpio44_a_1",
-               "gpio45_a_1", "gpio46_a_1", "gpio47_a_1", "gpio48_a_1",
-               "gpio51_a_1", "gpio52_a_1", "gpio53_a_1", "gpio54_a_1",
-               "gpio55_a_1", "gpio56_a_1");
-AB8540_FUNC_GROUPS(pwmout, "pwmout1_d_1", "pwmout2_d_1", "pwmout3_d_1");
-AB8540_FUNC_GROUPS(adi1, "adi1_d_1");
-AB8540_FUNC_GROUPS(dmic, "dmic12_d_1", "dmic34_d_1", "dmic56_d_1");
-AB8540_FUNC_GROUPS(batremn, "batremn_d_1");
-AB8540_FUNC_GROUPS(service, "service_d_1");
-AB8540_FUNC_GROUPS(pwrctrl, "pwrctrl0_d_1", "pwrctrl1_d_1");
-AB8540_FUNC_GROUPS(pwmextvibra, "pwmextvibra1_d_1", "pwmextvibra2_d_1");
-AB8540_FUNC_GROUPS(gpio_vbat, "gpio1_vbat_d_1", "gpio2_vbat_d_1",
-               "gpio3_vbat_d_1", "gpio4_vbat_d_1");
-AB8540_FUNC_GROUPS(pdm, "pdmclkdat_d_1");
-
-#define FUNCTION(fname)                                        \
-       {                                               \
-               .name = #fname,                         \
-               .groups = fname##_groups,               \
-               .ngroups = ARRAY_SIZE(fname##_groups),  \
-       }
-
-static const struct abx500_function ab8540_functions[] = {
-       FUNCTION(sysclkreq),
-       FUNCTION(gpio),
-       FUNCTION(pwmout),
-       FUNCTION(adi1),
-       FUNCTION(dmic),
-       FUNCTION(batremn),
-       FUNCTION(service),
-       FUNCTION(pwrctrl),
-       FUNCTION(pwmextvibra),
-       FUNCTION(gpio_vbat),
-       FUNCTION(pdm),
-};
-
-/*
- * this table translates what's is in the AB8540 specification regarding the
- * balls alternate functions (as for DB, default, ALT_A, ALT_B and ALT_C).
- * ALTERNATE_FUNCTIONS(GPIO_NUMBER, GPIOSEL bit, ALTERNATFUNC bit1,
- * ALTERNATEFUNC bit2, ALTA val, ALTB val, ALTC val),
- * AB8540 only supports DEFAULT and ALTA functions, so ALTERNATFUNC
- * registers is not used
- *
- */
-
-static struct
-alternate_functions ab8540_alternate_functions[AB8540_GPIO_MAX_NUMBER + 1] = {
-       /* GPIOSEL1 - bit 4-7 reserved */
-       ALTERNATE_FUNCTIONS(0, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO0 */
-       ALTERNATE_FUNCTIONS(1,      0, UNUSED, UNUSED, 0, 0, 0), /* GPIO1, altA controlled by bit 0 */
-       ALTERNATE_FUNCTIONS(2,      1, UNUSED, UNUSED, 0, 0, 0), /* GPIO2, altA controlled by bit 1 */
-       ALTERNATE_FUNCTIONS(3,      2, UNUSED, UNUSED, 0, 0, 0), /* GPIO3, altA controlled by bit 2*/
-       ALTERNATE_FUNCTIONS(4,      3, UNUSED, UNUSED, 0, 0, 0), /* GPIO4, altA controlled by bit 3*/
-       ALTERNATE_FUNCTIONS(5, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO5 */
-       ALTERNATE_FUNCTIONS(6, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO6 */
-       ALTERNATE_FUNCTIONS(7, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO7 */
-       ALTERNATE_FUNCTIONS(8, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO8 */
-       /* GPIOSEL2 - bit 0-4 reserved */
-       ALTERNATE_FUNCTIONS(9,  UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO9 */
-       ALTERNATE_FUNCTIONS(10, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO10 */
-       ALTERNATE_FUNCTIONS(11, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO11 */
-       ALTERNATE_FUNCTIONS(12, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO12 */
-       ALTERNATE_FUNCTIONS(13, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO13 */
-       ALTERNATE_FUNCTIONS(14,      5, UNUSED, UNUSED, 0, 0, 0), /* GPIO14, altA controlled by bit 5 */
-       ALTERNATE_FUNCTIONS(15,      6, UNUSED, UNUSED, 0, 0, 0), /* GPIO15, altA controlled by bit 6 */
-       ALTERNATE_FUNCTIONS(16,      7, UNUSED, UNUSED, 0, 0, 0), /* GPIO16, altA controlled by bit 7 */
-       /* GPIOSEL3 - bit 4-7 reserved */
-       ALTERNATE_FUNCTIONS(17,      0, UNUSED, UNUSED, 0, 0, 0), /* GPIO17, altA controlled by bit 0 */
-       ALTERNATE_FUNCTIONS(18,      1, UNUSED, UNUSED, 0, 0, 0), /* GPIO18, altA controlled by bit 1 */
-       ALTERNATE_FUNCTIONS(19,      2, UNUSED, UNUSED, 0, 0, 0), /* GPIO19, altA controlled by bit 2 */
-       ALTERNATE_FUNCTIONS(20,      3, UNUSED, UNUSED, 0, 0, 0), /* GPIO20, altA controlled by bit 3 */
-       ALTERNATE_FUNCTIONS(21, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO21 */
-       ALTERNATE_FUNCTIONS(22, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO22 */
-       ALTERNATE_FUNCTIONS(23, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO23 */
-       ALTERNATE_FUNCTIONS(24, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO24 */
-       /* GPIOSEL4 - bit 0-1 reserved */
-       ALTERNATE_FUNCTIONS(25, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO25 */
-       ALTERNATE_FUNCTIONS(26, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO26 */
-       ALTERNATE_FUNCTIONS(27,      2, UNUSED, UNUSED, 0, 0, 0), /* GPIO27, altA controlled by bit 2 */
-       ALTERNATE_FUNCTIONS(28,      3, UNUSED, UNUSED, 0, 0, 0), /* GPIO28, altA controlled by bit 3 */
-       ALTERNATE_FUNCTIONS(29,      4, UNUSED, UNUSED, 0, 0, 0), /* GPIO29, altA controlled by bit 4 */
-       ALTERNATE_FUNCTIONS(30,      5, UNUSED, UNUSED, 0, 0, 0), /* GPIO30, altA controlled by bit 5 */
-       ALTERNATE_FUNCTIONS(31,      6, UNUSED, UNUSED, 0, 0, 0), /* GPIO31, altA controlled by bit 6 */
-       ALTERNATE_FUNCTIONS(32,      7, UNUSED, UNUSED, 0, 0, 0), /* GPIO32, altA controlled by bit 7 */
-       /* GPIOSEL5 - bit 0-7 reserved */
-       ALTERNATE_FUNCTIONS(33, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO33 */
-       ALTERNATE_FUNCTIONS(34, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO34 */
-       ALTERNATE_FUNCTIONS(35, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO35 */
-       ALTERNATE_FUNCTIONS(36, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO36 */
-       ALTERNATE_FUNCTIONS(37, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO37 */
-       ALTERNATE_FUNCTIONS(38, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO38 */
-       ALTERNATE_FUNCTIONS(39, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO39 */
-       ALTERNATE_FUNCTIONS(40, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO40 */
-       /* GPIOSEL6 - bit 0 reserved */
-       ALTERNATE_FUNCTIONS(41, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO41 */
-       ALTERNATE_FUNCTIONS(42,      1, UNUSED, UNUSED, 0, 0, 0), /* GPIO42, altA controlled by bit 1 */
-       ALTERNATE_FUNCTIONS(43,      2, UNUSED, UNUSED, 0, 0, 0), /* GPIO43, altA controlled by bit 2 */
-       ALTERNATE_FUNCTIONS(44,      3, UNUSED, UNUSED, 0, 0, 0), /* GPIO44, altA controlled by bit 3 */
-       ALTERNATE_FUNCTIONS(45,      4, UNUSED, UNUSED, 0, 0, 0), /* GPIO45, altA controlled by bit 4 */
-       ALTERNATE_FUNCTIONS(46,      5, UNUSED, UNUSED, 0, 0, 0), /* GPIO46, altA controlled by bit 5 */
-       ALTERNATE_FUNCTIONS(47,      6, UNUSED, UNUSED, 0, 0, 0), /* GPIO47, altA controlled by bit 6 */
-       ALTERNATE_FUNCTIONS(48,      7, UNUSED, UNUSED, 0, 0, 0), /* GPIO48, altA controlled by bit 7 */
-       /* GPIOSEL7 - bit 0-1 reserved */
-       ALTERNATE_FUNCTIONS(49, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO49 */
-       ALTERNATE_FUNCTIONS(50, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO50 */
-       ALTERNATE_FUNCTIONS(51,      2, UNUSED, UNUSED, 0, 0, 0), /* GPIO51, altA controlled by bit 2 */
-       ALTERNATE_FUNCTIONS(52,      3, UNUSED, UNUSED, 0, 0, 0), /* GPIO52, altA controlled by bit 3 */
-       ALTERNATE_FUNCTIONS(53,      4, UNUSED, UNUSED, 0, 0, 0), /* GPIO53, altA controlled by bit 4 */
-       ALTERNATE_FUNCTIONS(54,      5, UNUSED, UNUSED, 0, 0, 0), /* GPIO54, altA controlled by bit 5 */
-       ALTERNATE_FUNCTIONS(55,      6, UNUSED, UNUSED, 0, 0, 0), /* GPIO55, altA controlled by bit 6 */
-       ALTERNATE_FUNCTIONS(56,      7, UNUSED, UNUSED, 0, 0, 0), /* GPIO56, altA controlled by bit 7 */
-};
-
-static struct pullud ab8540_pullud = {
-       .first_pin = 51,        /* GPIO1_VBAT */
-       .last_pin = 54,         /* GPIO4_VBAT */
-};
-
-/*
- * For AB8540 Only some GPIOs are interrupt capable:
- *     GPIO43 to GPIO44
- *     GPIO51 to GPIO54
- */
-static struct abx500_gpio_irq_cluster ab8540_gpio_irq_cluster[] = {
-       GPIO_IRQ_CLUSTER(43, 43, AB8540_INT_GPIO43F),
-       GPIO_IRQ_CLUSTER(44, 44, AB8540_INT_GPIO44F),
-       GPIO_IRQ_CLUSTER(51, 54, AB9540_INT_GPIO51R),
-};
-
-static struct abx500_pinctrl_soc_data ab8540_soc = {
-       .gpio_ranges = ab8540_pinranges,
-       .gpio_num_ranges = ARRAY_SIZE(ab8540_pinranges),
-       .pins = ab8540_pins,
-       .npins = ARRAY_SIZE(ab8540_pins),
-       .functions = ab8540_functions,
-       .nfunctions = ARRAY_SIZE(ab8540_functions),
-       .groups = ab8540_groups,
-       .ngroups = ARRAY_SIZE(ab8540_groups),
-       .alternate_functions = ab8540_alternate_functions,
-       .pullud = &ab8540_pullud,
-       .gpio_irq_cluster = ab8540_gpio_irq_cluster,
-       .ngpio_irq_cluster = ARRAY_SIZE(ab8540_gpio_irq_cluster),
-       .irq_gpio_rising_offset = AB8540_INT_GPIO43R,
-       .irq_gpio_falling_offset = AB8540_INT_GPIO43F,
-       .irq_gpio_factor = 2,
-};
-
-void
-abx500_pinctrl_ab8540_init(struct abx500_pinctrl_soc_data **soc)
-{
-       *soc = &ab8540_soc;
-}
diff --git a/drivers/pinctrl/pinctrl-ab9540.c b/drivers/pinctrl/pinctrl-ab9540.c
deleted file mode 100644 (file)
index 1a281ca..0000000
+++ /dev/null
@@ -1,486 +0,0 @@
-/*
- * Copyright (C) ST-Ericsson SA 2012
- *
- * Author: Patrice Chotard <patrice.chotard@stericsson.com> for ST-Ericsson.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/gpio.h>
-#include <linux/pinctrl/pinctrl.h>
-#include <linux/mfd/abx500/ab8500.h>
-#include "pinctrl-abx500.h"
-
-/* All the pins that can be used for GPIO and some other functions */
-#define ABX500_GPIO(offset)            (offset)
-
-#define AB9540_PIN_R4          ABX500_GPIO(1)
-#define AB9540_PIN_V3          ABX500_GPIO(2)
-#define AB9540_PIN_T4          ABX500_GPIO(3)
-#define AB9540_PIN_T5          ABX500_GPIO(4)
-/* hole */
-#define AB9540_PIN_B18         ABX500_GPIO(10)
-#define AB9540_PIN_C18         ABX500_GPIO(11)
-/* hole */
-#define AB9540_PIN_D18         ABX500_GPIO(13)
-#define AB9540_PIN_B19         ABX500_GPIO(14)
-#define AB9540_PIN_C19         ABX500_GPIO(15)
-#define AB9540_PIN_D19         ABX500_GPIO(16)
-#define AB9540_PIN_R3          ABX500_GPIO(17)
-#define AB9540_PIN_T2          ABX500_GPIO(18)
-#define AB9540_PIN_U2          ABX500_GPIO(19)
-#define AB9540_PIN_V2          ABX500_GPIO(20)
-#define AB9540_PIN_N17         ABX500_GPIO(21)
-#define AB9540_PIN_N16         ABX500_GPIO(22)
-#define AB9540_PIN_M19         ABX500_GPIO(23)
-#define AB9540_PIN_T3          ABX500_GPIO(24)
-#define AB9540_PIN_W2          ABX500_GPIO(25)
-/* hole */
-#define AB9540_PIN_H4          ABX500_GPIO(27)
-#define AB9540_PIN_F1          ABX500_GPIO(28)
-#define AB9540_PIN_F4          ABX500_GPIO(29)
-#define AB9540_PIN_F2          ABX500_GPIO(30)
-#define AB9540_PIN_E4          ABX500_GPIO(31)
-#define AB9540_PIN_F3          ABX500_GPIO(32)
-/* hole */
-#define AB9540_PIN_J13         ABX500_GPIO(34)
-/* hole */
-#define AB9540_PIN_L17         ABX500_GPIO(40)
-#define AB9540_PIN_L16         ABX500_GPIO(41)
-#define AB9540_PIN_W3          ABX500_GPIO(42)
-#define AB9540_PIN_N4          ABX500_GPIO(50)
-#define AB9540_PIN_G12         ABX500_GPIO(51)
-#define AB9540_PIN_E17         ABX500_GPIO(52)
-#define AB9540_PIN_D11         ABX500_GPIO(53)
-#define AB9540_PIN_M18         ABX500_GPIO(54)
-
-/* indicates the highest GPIO number */
-#define AB9540_GPIO_MAX_NUMBER 54
-
-/*
- * The names of the pins are denoted by GPIO number and ball name, even
- * though they can be used for other things than GPIO, this is the first
- * column in the table of the data sheet and often used on schematics and
- * such.
- */
-static const struct pinctrl_pin_desc ab9540_pins[] = {
-       PINCTRL_PIN(AB9540_PIN_R4, "GPIO1_R4"),
-       PINCTRL_PIN(AB9540_PIN_V3, "GPIO2_V3"),
-       PINCTRL_PIN(AB9540_PIN_T4, "GPIO3_T4"),
-       PINCTRL_PIN(AB9540_PIN_T5, "GPIO4_T5"),
-       /* hole */
-       PINCTRL_PIN(AB9540_PIN_B18, "GPIO10_B18"),
-       PINCTRL_PIN(AB9540_PIN_C18, "GPIO11_C18"),
-       /* hole */
-       PINCTRL_PIN(AB9540_PIN_D18, "GPIO13_D18"),
-       PINCTRL_PIN(AB9540_PIN_B19, "GPIO14_B19"),
-       PINCTRL_PIN(AB9540_PIN_C19, "GPIO15_C19"),
-       PINCTRL_PIN(AB9540_PIN_D19, "GPIO16_D19"),
-       PINCTRL_PIN(AB9540_PIN_R3, "GPIO17_R3"),
-       PINCTRL_PIN(AB9540_PIN_T2, "GPIO18_T2"),
-       PINCTRL_PIN(AB9540_PIN_U2, "GPIO19_U2"),
-       PINCTRL_PIN(AB9540_PIN_V2, "GPIO20_V2"),
-       PINCTRL_PIN(AB9540_PIN_N17, "GPIO21_N17"),
-       PINCTRL_PIN(AB9540_PIN_N16, "GPIO22_N16"),
-       PINCTRL_PIN(AB9540_PIN_M19, "GPIO23_M19"),
-       PINCTRL_PIN(AB9540_PIN_T3, "GPIO24_T3"),
-       PINCTRL_PIN(AB9540_PIN_W2, "GPIO25_W2"),
-       /* hole */
-       PINCTRL_PIN(AB9540_PIN_H4, "GPIO27_H4"),
-       PINCTRL_PIN(AB9540_PIN_F1, "GPIO28_F1"),
-       PINCTRL_PIN(AB9540_PIN_F4, "GPIO29_F4"),
-       PINCTRL_PIN(AB9540_PIN_F2, "GPIO30_F2"),
-       PINCTRL_PIN(AB9540_PIN_E4, "GPIO31_E4"),
-       PINCTRL_PIN(AB9540_PIN_F3, "GPIO32_F3"),
-       /* hole */
-       PINCTRL_PIN(AB9540_PIN_J13, "GPIO34_J13"),
-       /* hole */
-       PINCTRL_PIN(AB9540_PIN_L17, "GPIO40_L17"),
-       PINCTRL_PIN(AB9540_PIN_L16, "GPIO41_L16"),
-       PINCTRL_PIN(AB9540_PIN_W3, "GPIO42_W3"),
-       PINCTRL_PIN(AB9540_PIN_N4, "GPIO50_N4"),
-       PINCTRL_PIN(AB9540_PIN_G12, "GPIO51_G12"),
-       PINCTRL_PIN(AB9540_PIN_E17, "GPIO52_E17"),
-       PINCTRL_PIN(AB9540_PIN_D11, "GPIO53_D11"),
-       PINCTRL_PIN(AB9540_PIN_M18, "GPIO60_M18"),
-};
-
-/*
- * Maps local GPIO offsets to local pin numbers
- */
-static const struct abx500_pinrange ab9540_pinranges[] = {
-       ABX500_PINRANGE(1, 4, ABX500_ALT_A),
-       ABX500_PINRANGE(10, 2, ABX500_DEFAULT),
-       ABX500_PINRANGE(13, 1, ABX500_DEFAULT),
-       ABX500_PINRANGE(14, 12, ABX500_ALT_A),
-       ABX500_PINRANGE(27, 6, ABX500_ALT_A),
-       ABX500_PINRANGE(34, 1, ABX500_ALT_A),
-       ABX500_PINRANGE(40, 3, ABX500_ALT_A),
-       ABX500_PINRANGE(50, 1, ABX500_DEFAULT),
-       ABX500_PINRANGE(51, 3, ABX500_ALT_A),
-       ABX500_PINRANGE(54, 1, ABX500_DEFAULT),
-};
-
-/*
- * Read the pin group names like this:
- * sysclkreq2_d_1 = first groups of pins for sysclkreq2 on default function
- *
- * The groups are arranged as sets per altfunction column, so we can
- * mux in one group at a time by selecting the same altfunction for them
- * all. When functions require pins on different altfunctions, you need
- * to combine several groups.
- */
-
-/* default column */
-static const unsigned sysclkreq2_d_1_pins[] = { AB9540_PIN_R4 };
-static const unsigned sysclkreq3_d_1_pins[] = { AB9540_PIN_V3 };
-static const unsigned sysclkreq4_d_1_pins[] = { AB9540_PIN_T4 };
-static const unsigned sysclkreq6_d_1_pins[] = { AB9540_PIN_T5 };
-static const unsigned gpio10_d_1_pins[] = { AB9540_PIN_B18 };
-static const unsigned gpio11_d_1_pins[] = { AB9540_PIN_C18 };
-static const unsigned gpio13_d_1_pins[] = { AB9540_PIN_D18 };
-static const unsigned pwmout1_d_1_pins[] = { AB9540_PIN_B19 };
-static const unsigned pwmout2_d_1_pins[] = { AB9540_PIN_C19 };
-static const unsigned pwmout3_d_1_pins[] = { AB9540_PIN_D19 };
-/* audio data interface 1*/
-static const unsigned adi1_d_1_pins[] = { AB9540_PIN_R3, AB9540_PIN_T2,
-                                       AB9540_PIN_U2, AB9540_PIN_V2 };
-/* USBUICC */
-static const unsigned usbuicc_d_1_pins[] = { AB9540_PIN_N17, AB9540_PIN_N16,
-                                       AB9540_PIN_M19 };
-static const unsigned sysclkreq7_d_1_pins[] = { AB9540_PIN_T3 };
-static const unsigned sysclkreq8_d_1_pins[] = { AB9540_PIN_W2 };
-/* Digital microphone 1 and 2 */
-static const unsigned dmic12_d_1_pins[] = { AB9540_PIN_H4, AB9540_PIN_F1 };
-/* Digital microphone 3 and 4 */
-static const unsigned dmic34_d_1_pins[] = { AB9540_PIN_F4, AB9540_PIN_F2 };
-/* Digital microphone 5 and 6 */
-static const unsigned dmic56_d_1_pins[] = { AB9540_PIN_E4, AB9540_PIN_F3 };
-static const unsigned extcpena_d_1_pins[] = { AB9540_PIN_J13 };
-/* modem SDA/SCL */
-static const unsigned modsclsda_d_1_pins[] = { AB9540_PIN_L17, AB9540_PIN_L16 };
-static const unsigned sysclkreq5_d_1_pins[] = { AB9540_PIN_W3 };
-static const unsigned gpio50_d_1_pins[] = { AB9540_PIN_N4 };
-static const unsigned batremn_d_1_pins[] = { AB9540_PIN_G12 };
-static const unsigned resethw_d_1_pins[] = { AB9540_PIN_E17 };
-static const unsigned service_d_1_pins[] = { AB9540_PIN_D11 };
-static const unsigned gpio60_d_1_pins[] = { AB9540_PIN_M18 };
-
-/* Altfunction A column */
-static const unsigned gpio1_a_1_pins[] = { AB9540_PIN_R4 };
-static const unsigned gpio2_a_1_pins[] = { AB9540_PIN_V3 };
-static const unsigned gpio3_a_1_pins[] = { AB9540_PIN_T4 };
-static const unsigned gpio4_a_1_pins[] = { AB9540_PIN_T5 };
-static const unsigned hiqclkena_a_1_pins[] = { AB9540_PIN_B18 };
-static const unsigned pdmclk_a_1_pins[] = { AB9540_PIN_C18 };
-static const unsigned uartdata_a_1_pins[] = { AB9540_PIN_D18, AB9540_PIN_N4 };
-static const unsigned gpio14_a_1_pins[] = { AB9540_PIN_B19 };
-static const unsigned gpio15_a_1_pins[] = { AB9540_PIN_C19 };
-static const unsigned gpio16_a_1_pins[] = { AB9540_PIN_D19 };
-static const unsigned gpio17_a_1_pins[] = { AB9540_PIN_R3 };
-static const unsigned gpio18_a_1_pins[] = { AB9540_PIN_T2 };
-static const unsigned gpio19_a_1_pins[] = { AB9540_PIN_U2 };
-static const unsigned gpio20_a_1_pins[] = { AB9540_PIN_V2 };
-static const unsigned gpio21_a_1_pins[] = { AB9540_PIN_N17 };
-static const unsigned gpio22_a_1_pins[] = { AB9540_PIN_N16 };
-static const unsigned gpio23_a_1_pins[] = { AB9540_PIN_M19 };
-static const unsigned gpio24_a_1_pins[] = { AB9540_PIN_T3 };
-static const unsigned gpio25_a_1_pins[] = { AB9540_PIN_W2 };
-static const unsigned gpio27_a_1_pins[] = { AB9540_PIN_H4 };
-static const unsigned gpio28_a_1_pins[] = { AB9540_PIN_F1 };
-static const unsigned gpio29_a_1_pins[] = { AB9540_PIN_F4 };
-static const unsigned gpio30_a_1_pins[] = { AB9540_PIN_F2 };
-static const unsigned gpio31_a_1_pins[] = { AB9540_PIN_E4 };
-static const unsigned gpio32_a_1_pins[] = { AB9540_PIN_F3 };
-static const unsigned gpio34_a_1_pins[] = { AB9540_PIN_J13 };
-static const unsigned gpio40_a_1_pins[] = { AB9540_PIN_L17 };
-static const unsigned gpio41_a_1_pins[] = { AB9540_PIN_L16 };
-static const unsigned gpio42_a_1_pins[] = { AB9540_PIN_W3 };
-static const unsigned gpio51_a_1_pins[] = { AB9540_PIN_G12 };
-static const unsigned gpio52_a_1_pins[] = { AB9540_PIN_E17 };
-static const unsigned gpio53_a_1_pins[] = { AB9540_PIN_D11 };
-static const unsigned usbuiccpd_a_1_pins[] = { AB9540_PIN_M18 };
-
-/* Altfunction B colum */
-static const unsigned pdmdata_b_1_pins[] = { AB9540_PIN_B18 };
-static const unsigned pwmextvibra1_b_1_pins[] = { AB9540_PIN_D18 };
-static const unsigned pwmextvibra2_b_1_pins[] = { AB9540_PIN_N4 };
-
-/* Altfunction C column */
-static const unsigned usbvdat_c_1_pins[] = { AB9540_PIN_D18 };
-
-#define AB9540_PIN_GROUP(a, b) { .name = #a, .pins = a##_pins,         \
-                       .npins = ARRAY_SIZE(a##_pins), .altsetting = b }
-
-static const struct abx500_pingroup ab9540_groups[] = {
-       /* default column */
-       AB9540_PIN_GROUP(sysclkreq2_d_1, ABX500_DEFAULT),
-       AB9540_PIN_GROUP(sysclkreq3_d_1, ABX500_DEFAULT),
-       AB9540_PIN_GROUP(sysclkreq4_d_1, ABX500_DEFAULT),
-       AB9540_PIN_GROUP(sysclkreq6_d_1, ABX500_DEFAULT),
-       AB9540_PIN_GROUP(gpio10_d_1, ABX500_DEFAULT),
-       AB9540_PIN_GROUP(gpio11_d_1, ABX500_DEFAULT),
-       AB9540_PIN_GROUP(gpio13_d_1, ABX500_DEFAULT),
-       AB9540_PIN_GROUP(pwmout1_d_1, ABX500_DEFAULT),
-       AB9540_PIN_GROUP(pwmout2_d_1, ABX500_DEFAULT),
-       AB9540_PIN_GROUP(pwmout3_d_1, ABX500_DEFAULT),
-       AB9540_PIN_GROUP(adi1_d_1, ABX500_DEFAULT),
-       AB9540_PIN_GROUP(usbuicc_d_1, ABX500_DEFAULT),
-       AB9540_PIN_GROUP(sysclkreq7_d_1, ABX500_DEFAULT),
-       AB9540_PIN_GROUP(sysclkreq8_d_1, ABX500_DEFAULT),
-       AB9540_PIN_GROUP(dmic12_d_1, ABX500_DEFAULT),
-       AB9540_PIN_GROUP(dmic34_d_1, ABX500_DEFAULT),
-       AB9540_PIN_GROUP(dmic56_d_1, ABX500_DEFAULT),
-       AB9540_PIN_GROUP(extcpena_d_1, ABX500_DEFAULT),
-       AB9540_PIN_GROUP(modsclsda_d_1, ABX500_DEFAULT),
-       AB9540_PIN_GROUP(sysclkreq5_d_1, ABX500_DEFAULT),
-       AB9540_PIN_GROUP(gpio50_d_1, ABX500_DEFAULT),
-       AB9540_PIN_GROUP(batremn_d_1, ABX500_DEFAULT),
-       AB9540_PIN_GROUP(resethw_d_1, ABX500_DEFAULT),
-       AB9540_PIN_GROUP(service_d_1, ABX500_DEFAULT),
-       AB9540_PIN_GROUP(gpio60_d_1, ABX500_DEFAULT),
-
-       /* Altfunction A column */
-       AB9540_PIN_GROUP(gpio1_a_1, ABX500_ALT_A),
-       AB9540_PIN_GROUP(gpio2_a_1, ABX500_ALT_A),
-       AB9540_PIN_GROUP(gpio3_a_1, ABX500_ALT_A),
-       AB9540_PIN_GROUP(gpio4_a_1, ABX500_ALT_A),
-       AB9540_PIN_GROUP(hiqclkena_a_1, ABX500_ALT_A),
-       AB9540_PIN_GROUP(pdmclk_a_1, ABX500_ALT_A),
-       AB9540_PIN_GROUP(uartdata_a_1, ABX500_ALT_A),
-       AB9540_PIN_GROUP(gpio14_a_1, ABX500_ALT_A),
-       AB9540_PIN_GROUP(gpio15_a_1, ABX500_ALT_A),
-       AB9540_PIN_GROUP(gpio16_a_1, ABX500_ALT_A),
-       AB9540_PIN_GROUP(gpio17_a_1, ABX500_ALT_A),
-       AB9540_PIN_GROUP(gpio18_a_1, ABX500_ALT_A),
-       AB9540_PIN_GROUP(gpio19_a_1, ABX500_ALT_A),
-       AB9540_PIN_GROUP(gpio20_a_1, ABX500_ALT_A),
-       AB9540_PIN_GROUP(gpio21_a_1, ABX500_ALT_A),
-       AB9540_PIN_GROUP(gpio22_a_1, ABX500_ALT_A),
-       AB9540_PIN_GROUP(gpio23_a_1, ABX500_ALT_A),
-       AB9540_PIN_GROUP(gpio24_a_1, ABX500_ALT_A),
-       AB9540_PIN_GROUP(gpio25_a_1, ABX500_ALT_A),
-       AB9540_PIN_GROUP(gpio27_a_1, ABX500_ALT_A),
-       AB9540_PIN_GROUP(gpio28_a_1, ABX500_ALT_A),
-       AB9540_PIN_GROUP(gpio29_a_1, ABX500_ALT_A),
-       AB9540_PIN_GROUP(gpio30_a_1, ABX500_ALT_A),
-       AB9540_PIN_GROUP(gpio31_a_1, ABX500_ALT_A),
-       AB9540_PIN_GROUP(gpio32_a_1, ABX500_ALT_A),
-       AB9540_PIN_GROUP(gpio34_a_1, ABX500_ALT_A),
-       AB9540_PIN_GROUP(gpio40_a_1, ABX500_ALT_A),
-       AB9540_PIN_GROUP(gpio41_a_1, ABX500_ALT_A),
-       AB9540_PIN_GROUP(gpio42_a_1, ABX500_ALT_A),
-       AB9540_PIN_GROUP(gpio51_a_1, ABX500_ALT_A),
-       AB9540_PIN_GROUP(gpio52_a_1, ABX500_ALT_A),
-       AB9540_PIN_GROUP(gpio53_a_1, ABX500_ALT_A),
-       AB9540_PIN_GROUP(usbuiccpd_a_1, ABX500_ALT_A),
-
-       /* Altfunction B column */
-       AB9540_PIN_GROUP(pdmdata_b_1, ABX500_ALT_B),
-       AB9540_PIN_GROUP(pwmextvibra1_b_1, ABX500_ALT_B),
-       AB9540_PIN_GROUP(pwmextvibra2_b_1, ABX500_ALT_B),
-
-       /* Altfunction C column */
-       AB9540_PIN_GROUP(usbvdat_c_1, ABX500_ALT_C),
-};
-
-/* We use this macro to define the groups applicable to a function */
-#define AB9540_FUNC_GROUPS(a, b...)       \
-static const char * const a##_groups[] = { b };
-
-AB9540_FUNC_GROUPS(sysclkreq, "sysclkreq2_d_1", "sysclkreq3_d_1",
-               "sysclkreq4_d_1", "sysclkreq5_d_1", "sysclkreq6_d_1",
-               "sysclkreq7_d_1", "sysclkreq8_d_1");
-AB9540_FUNC_GROUPS(gpio, "gpio1_a_1", "gpio2_a_1", "gpio3_a_1", "gpio4_a_1",
-               "gpio10_d_1", "gpio11_d_1", "gpio13_d_1", "gpio14_a_1",
-               "gpio15_a_1", "gpio16_a_1", "gpio17_a_1", "gpio18_a_1",
-               "gpio19_a_1", "gpio20_a_1", "gpio21_a_1", "gpio22_a_1",
-               "gpio23_a_1", "gpio24_a_1", "gpio25_a_1", "gpio27_a_1",
-               "gpio28_a_1", "gpio29_a_1", "gpio30_a_1", "gpio31_a_1",
-               "gpio32_a_1", "gpio34_a_1", "gpio40_a_1", "gpio41_a_1",
-               "gpio42_a_1", "gpio50_d_1", "gpio51_a_1", "gpio52_a_1",
-               "gpio53_a_1", "gpio60_d_1");
-AB9540_FUNC_GROUPS(pwmout, "pwmout1_d_1", "pwmout2_d_1", "pwmout3_d_1");
-AB9540_FUNC_GROUPS(adi1, "adi1_d_1");
-AB9540_FUNC_GROUPS(usbuicc, "usbuicc_d_1", "usbuiccpd_a_1");
-AB9540_FUNC_GROUPS(dmic, "dmic12_d_1", "dmic34_d_1", "dmic56_d_1");
-AB9540_FUNC_GROUPS(extcpena, "extcpena_d_1");
-AB9540_FUNC_GROUPS(modsclsda, "modsclsda_d_1");
-AB9540_FUNC_GROUPS(batremn, "batremn_d_1");
-AB9540_FUNC_GROUPS(resethw, "resethw_d_1");
-AB9540_FUNC_GROUPS(service, "service_d_1");
-AB9540_FUNC_GROUPS(hiqclkena, "hiqclkena_a_1");
-AB9540_FUNC_GROUPS(pdm, "pdmdata_b_1", "pdmclk_a_1");
-AB9540_FUNC_GROUPS(uartdata, "uartdata_a_1");
-AB9540_FUNC_GROUPS(pwmextvibra, "pwmextvibra1_b_1", "pwmextvibra2_b_1");
-AB9540_FUNC_GROUPS(usbvdat, "usbvdat_c_1");
-
-#define FUNCTION(fname)                                        \
-       {                                               \
-               .name = #fname,                         \
-               .groups = fname##_groups,               \
-               .ngroups = ARRAY_SIZE(fname##_groups),  \
-       }
-
-static const struct abx500_function ab9540_functions[] = {
-       FUNCTION(sysclkreq),
-       FUNCTION(gpio),
-       FUNCTION(pwmout),
-       FUNCTION(adi1),
-       FUNCTION(usbuicc),
-       FUNCTION(dmic),
-       FUNCTION(extcpena),
-       FUNCTION(modsclsda),
-       FUNCTION(batremn),
-       FUNCTION(resethw),
-       FUNCTION(service),
-       FUNCTION(hiqclkena),
-       FUNCTION(pdm),
-       FUNCTION(uartdata),
-       FUNCTION(pwmextvibra),
-       FUNCTION(usbvdat),
-};
-
-/*
- * this table translates what's is in the AB9540 specification regarding the
- * balls alternate functions (as for DB, default, ALT_A, ALT_B and ALT_C).
- * ALTERNATE_FUNCTIONS(GPIO_NUMBER, GPIOSEL bit, ALTERNATFUNC bit1,
- * ALTERNATEFUNC bit2, ALTA val, ALTB val, ALTC val),
- *
- * example :
- *
- *     ALTERNATE_FUNCTIONS(13,     4,      3,      4, 1, 0, 2),
- *     means that pin AB9540_PIN_D18 (pin 13) supports 4 mux (default/ALT_A,
- *     ALT_B and ALT_C), so GPIOSEL and ALTERNATFUNC registers are used to
- *     select the mux. ALTA, ALTB and ALTC val indicates values to write in
- *     ALTERNATFUNC register. We need to specifies these values as SOC
- *     designers didn't apply the same logic on how to select mux in the
- *     ABx500 family.
- *
- *     As this pins supports at least ALT_B mux, default mux is
- *     selected by writing 1 in GPIOSEL bit :
- *
- *             | GPIOSEL bit=4 | alternatfunc bit2=4 | alternatfunc bit1=3
- *     default |       1       |          0          |          0
- *     alt_A   |       0       |          0          |          1
- *     alt_B   |       0       |          0          |          0
- *     alt_C   |       0       |          1          |          0
- *
- *     ALTERNATE_FUNCTIONS(1,      0, UNUSED, UNUSED),
- *     means that pin AB9540_PIN_R4 (pin 1) supports 2 mux, so only GPIOSEL
- *     register is used to select the mux. As this pins doesn't support at
- *     least ALT_B mux, default mux is by writing 0 in GPIOSEL bit :
- *
- *             | GPIOSEL bit=0 | alternatfunc bit2=  | alternatfunc bit1=
- *     default |       0       |          0          |          0
- *     alt_A   |       1       |          0          |          0
- */
-
-static struct
-alternate_functions ab9540alternate_functions[AB9540_GPIO_MAX_NUMBER + 1] = {
-       /* GPIOSEL1 - bits 4-7 are reserved */
-       ALTERNATE_FUNCTIONS(0, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO0 */
-       ALTERNATE_FUNCTIONS(1,      0, UNUSED, UNUSED, 0, 0, 0), /* GPIO1, altA controlled by bit 0 */
-       ALTERNATE_FUNCTIONS(2,      1, UNUSED, UNUSED, 0, 0, 0), /* GPIO2, altA controlled by bit 1 */
-       ALTERNATE_FUNCTIONS(3,      2, UNUSED, UNUSED, 0, 0, 0), /* GPIO3, altA controlled by bit 2*/
-       ALTERNATE_FUNCTIONS(4,      3, UNUSED, UNUSED, 0, 0, 0), /* GPIO4, altA controlled by bit 3*/
-       ALTERNATE_FUNCTIONS(5, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO5 */
-       ALTERNATE_FUNCTIONS(6, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO6 */
-       ALTERNATE_FUNCTIONS(7, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO7 */
-       ALTERNATE_FUNCTIONS(8, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO8 */
-       /* GPIOSEL2 - bits 0 and 3 are reserved */
-       ALTERNATE_FUNCTIONS(9, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO9 */
-       ALTERNATE_FUNCTIONS(10,      1,      0, UNUSED, 1, 0, 0), /* GPIO10, altA and altB controlled by bit 0 */
-       ALTERNATE_FUNCTIONS(11,      2,      1, UNUSED, 0, 0, 0), /* GPIO11, altA controlled by bit 1 */
-       ALTERNATE_FUNCTIONS(12, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO12 */
-       ALTERNATE_FUNCTIONS(13,      4,      3,      4, 1, 0, 2), /* GPIO13, altA altB and altC controlled by bit 3 and 4 */
-       ALTERNATE_FUNCTIONS(14,      5, UNUSED, UNUSED, 0, 0, 0), /* GPIO14, altA controlled by bit 5 */
-       ALTERNATE_FUNCTIONS(15,      6, UNUSED, UNUSED, 0, 0, 0), /* GPIO15, altA controlled by bit 6 */
-       ALTERNATE_FUNCTIONS(16,      7, UNUSED, UNUSED, 0, 0, 0), /* GPIO16, altA controlled by bit 7 */
-       /* GPIOSEL3 - bit 1-3 reserved
-        * pins 17 to 20 are special case, only bit 0 is used to select
-        * alternate function for these 4 pins.
-        * bits 1 to 3 are reserved
-        */
-       ALTERNATE_FUNCTIONS(17,      0, UNUSED, UNUSED, 0, 0, 0), /* GPIO17, altA controlled by bit 0 */
-       ALTERNATE_FUNCTIONS(18,      0, UNUSED, UNUSED, 0, 0, 0), /* GPIO18, altA controlled by bit 0 */
-       ALTERNATE_FUNCTIONS(19,      0, UNUSED, UNUSED, 0, 0, 0), /* GPIO19, altA controlled by bit 0 */
-       ALTERNATE_FUNCTIONS(20,      0, UNUSED, UNUSED, 0, 0, 0), /* GPIO20, altA controlled by bit 0 */
-       ALTERNATE_FUNCTIONS(21,      4, UNUSED, UNUSED, 0, 0, 0), /* GPIO21, altA controlled by bit 4 */
-       ALTERNATE_FUNCTIONS(22,      5, UNUSED, UNUSED, 0, 0, 0), /* GPIO22, altA controlled by bit 5 */
-       ALTERNATE_FUNCTIONS(23,      6, UNUSED, UNUSED, 0, 0, 0), /* GPIO23, altA controlled by bit 6 */
-       ALTERNATE_FUNCTIONS(24,      7, UNUSED, UNUSED, 0, 0, 0), /* GPIO24, altA controlled by bit 7 */
-       /* GPIOSEL4 - bit 1 reserved */
-       ALTERNATE_FUNCTIONS(25,      0, UNUSED, UNUSED, 0, 0, 0), /* GPIO25, altA controlled by bit 0 */
-       ALTERNATE_FUNCTIONS(26, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO26 */
-       ALTERNATE_FUNCTIONS(27,      2, UNUSED, UNUSED, 0, 0, 0), /* GPIO27, altA controlled by bit 2 */
-       ALTERNATE_FUNCTIONS(28,      3, UNUSED, UNUSED, 0, 0, 0), /* GPIO28, altA controlled by bit 3 */
-       ALTERNATE_FUNCTIONS(29,      4, UNUSED, UNUSED, 0, 0, 0), /* GPIO29, altA controlled by bit 4 */
-       ALTERNATE_FUNCTIONS(30,      5, UNUSED, UNUSED, 0, 0, 0), /* GPIO30, altA controlled by bit 5 */
-       ALTERNATE_FUNCTIONS(31,      6, UNUSED, UNUSED, 0, 0, 0), /* GPIO31, altA controlled by bit 6 */
-       ALTERNATE_FUNCTIONS(32,      7, UNUSED, UNUSED, 0, 0, 0), /* GPIO32, altA controlled by bit 7 */
-       /* GPIOSEL5 - bit 0, 2-6 are reserved */
-       ALTERNATE_FUNCTIONS(33, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO33 */
-       ALTERNATE_FUNCTIONS(34,      1, UNUSED, UNUSED, 0, 0, 0), /* GPIO34, altA controlled by bit 1 */
-       ALTERNATE_FUNCTIONS(35, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO35 */
-       ALTERNATE_FUNCTIONS(36, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO36 */
-       ALTERNATE_FUNCTIONS(37, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO37 */
-       ALTERNATE_FUNCTIONS(38, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO38 */
-       ALTERNATE_FUNCTIONS(39, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO39 */
-       ALTERNATE_FUNCTIONS(40,      7, UNUSED, UNUSED, 0, 0, 0), /* GPIO40, altA controlled by bit 7 */
-       /* GPIOSEL6 - bit 2-7 are reserved */
-       ALTERNATE_FUNCTIONS(41,      0, UNUSED, UNUSED, 0, 0, 0), /* GPIO41, altA controlled by bit 0 */
-       ALTERNATE_FUNCTIONS(42,      1, UNUSED, UNUSED, 0, 0, 0), /* GPIO42, altA controlled by bit 1 */
-       ALTERNATE_FUNCTIONS(43, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO43 */
-       ALTERNATE_FUNCTIONS(44, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO44 */
-       ALTERNATE_FUNCTIONS(45, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO45 */
-       ALTERNATE_FUNCTIONS(46, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO46 */
-       ALTERNATE_FUNCTIONS(47, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO47 */
-       ALTERNATE_FUNCTIONS(48, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO48 */
-       /*
-        * GPIOSEL7 - bit 0 and 6-7 are reserved
-        * special case with GPIO60, wich is located at offset 5 of gpiosel7
-        * don't know why it has been called GPIO60 in AB9540 datasheet,
-        * GPIO54 would be logical..., so at SOC point of view we consider
-        * GPIO60 = GPIO54
-        */
-       ALTERNATE_FUNCTIONS(49,      0, UNUSED, UNUSED, 0, 0, 0), /* no GPIO49 */
-       ALTERNATE_FUNCTIONS(50,      1,      2, UNUSED, 1, 0, 0), /* GPIO50, altA and altB controlled by bit 1 */
-       ALTERNATE_FUNCTIONS(51,      2, UNUSED, UNUSED, 0, 0, 0), /* GPIO51, altA controlled by bit 2 */
-       ALTERNATE_FUNCTIONS(52,      3, UNUSED, UNUSED, 0, 0, 0), /* GPIO52, altA controlled by bit 3 */
-       ALTERNATE_FUNCTIONS(53,      4, UNUSED, UNUSED, 0, 0, 0), /* GPIO53, altA controlled by bit 4 */
-       ALTERNATE_FUNCTIONS(54,      5, UNUSED, UNUSED, 0, 0, 0), /* GPIO54 = GPIO60, altA controlled by bit 5 */
-};
-
-static struct abx500_gpio_irq_cluster ab9540_gpio_irq_cluster[] = {
-       GPIO_IRQ_CLUSTER(10, 13, AB8500_INT_GPIO10R),
-       GPIO_IRQ_CLUSTER(24, 25, AB8500_INT_GPIO24R),
-       GPIO_IRQ_CLUSTER(40, 41, AB8500_INT_GPIO40R),
-       GPIO_IRQ_CLUSTER(50, 54, AB9540_INT_GPIO50R),
-};
-
-static struct abx500_pinctrl_soc_data ab9540_soc = {
-       .gpio_ranges = ab9540_pinranges,
-       .gpio_num_ranges = ARRAY_SIZE(ab9540_pinranges),
-       .pins = ab9540_pins,
-       .npins = ARRAY_SIZE(ab9540_pins),
-       .functions = ab9540_functions,
-       .nfunctions = ARRAY_SIZE(ab9540_functions),
-       .groups = ab9540_groups,
-       .ngroups = ARRAY_SIZE(ab9540_groups),
-       .alternate_functions = ab9540alternate_functions,
-       .gpio_irq_cluster = ab9540_gpio_irq_cluster,
-       .ngpio_irq_cluster = ARRAY_SIZE(ab9540_gpio_irq_cluster),
-       .irq_gpio_rising_offset = AB8500_INT_GPIO6R,
-       .irq_gpio_falling_offset = AB8500_INT_GPIO6F,
-       .irq_gpio_factor = 1,
-};
-
-void
-abx500_pinctrl_ab9540_init(struct abx500_pinctrl_soc_data **soc)
-{
-       *soc = &ab9540_soc;
-}
diff --git a/drivers/pinctrl/pinctrl-abx500.c b/drivers/pinctrl/pinctrl-abx500.c
deleted file mode 100644 (file)
index 163da9c..0000000
+++ /dev/null
@@ -1,1361 +0,0 @@
-/*
- * Copyright (C) ST-Ericsson SA 2013
- *
- * Author: Patrice Chotard <patrice.chotard@st.com>
- * License terms: GNU General Public License (GPL) version 2
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/err.h>
-#include <linux/of.h>
-#include <linux/of_device.h>
-#include <linux/platform_device.h>
-#include <linux/gpio.h>
-#include <linux/irq.h>
-#include <linux/irqdomain.h>
-#include <linux/interrupt.h>
-#include <linux/bitops.h>
-#include <linux/mfd/abx500.h>
-#include <linux/mfd/abx500/ab8500.h>
-#include <linux/pinctrl/pinctrl.h>
-#include <linux/pinctrl/consumer.h>
-#include <linux/pinctrl/pinmux.h>
-#include <linux/pinctrl/pinconf.h>
-#include <linux/pinctrl/pinconf-generic.h>
-#include <linux/pinctrl/machine.h>
-
-#include "pinctrl-abx500.h"
-#include "core.h"
-#include "pinconf.h"
-
-/*
- * The AB9540 and AB8540 GPIO support are extended versions
- * of the AB8500 GPIO support.
- * The AB9540 supports an additional (7th) register so that
- * more GPIO may be configured and used.
- * The AB8540 supports 4 new gpios (GPIOx_VBAT) that have
- * internal pull-up and pull-down capabilities.
- */
-
-/*
- * GPIO registers offset
- * Bank: 0x10
- */
-#define AB8500_GPIO_SEL1_REG   0x00
-#define AB8500_GPIO_SEL2_REG   0x01
-#define AB8500_GPIO_SEL3_REG   0x02
-#define AB8500_GPIO_SEL4_REG   0x03
-#define AB8500_GPIO_SEL5_REG   0x04
-#define AB8500_GPIO_SEL6_REG   0x05
-#define AB9540_GPIO_SEL7_REG   0x06
-
-#define AB8500_GPIO_DIR1_REG   0x10
-#define AB8500_GPIO_DIR2_REG   0x11
-#define AB8500_GPIO_DIR3_REG   0x12
-#define AB8500_GPIO_DIR4_REG   0x13
-#define AB8500_GPIO_DIR5_REG   0x14
-#define AB8500_GPIO_DIR6_REG   0x15
-#define AB9540_GPIO_DIR7_REG   0x16
-
-#define AB8500_GPIO_OUT1_REG   0x20
-#define AB8500_GPIO_OUT2_REG   0x21
-#define AB8500_GPIO_OUT3_REG   0x22
-#define AB8500_GPIO_OUT4_REG   0x23
-#define AB8500_GPIO_OUT5_REG   0x24
-#define AB8500_GPIO_OUT6_REG   0x25
-#define AB9540_GPIO_OUT7_REG   0x26
-
-#define AB8500_GPIO_PUD1_REG   0x30
-#define AB8500_GPIO_PUD2_REG   0x31
-#define AB8500_GPIO_PUD3_REG   0x32
-#define AB8500_GPIO_PUD4_REG   0x33
-#define AB8500_GPIO_PUD5_REG   0x34
-#define AB8500_GPIO_PUD6_REG   0x35
-#define AB9540_GPIO_PUD7_REG   0x36
-
-#define AB8500_GPIO_IN1_REG    0x40
-#define AB8500_GPIO_IN2_REG    0x41
-#define AB8500_GPIO_IN3_REG    0x42
-#define AB8500_GPIO_IN4_REG    0x43
-#define AB8500_GPIO_IN5_REG    0x44
-#define AB8500_GPIO_IN6_REG    0x45
-#define AB9540_GPIO_IN7_REG    0x46
-#define AB8540_GPIO_VINSEL_REG 0x47
-#define AB8540_GPIO_PULL_UPDOWN_REG    0x48
-#define AB8500_GPIO_ALTFUN_REG 0x50
-#define AB8540_GPIO_PULL_UPDOWN_MASK   0x03
-#define AB8540_GPIO_VINSEL_MASK        0x03
-#define AB8540_GPIOX_VBAT_START        51
-#define AB8540_GPIOX_VBAT_END  54
-
-#define ABX500_GPIO_INPUT      0
-#define ABX500_GPIO_OUTPUT     1
-
-struct abx500_pinctrl {
-       struct device *dev;
-       struct pinctrl_dev *pctldev;
-       struct abx500_pinctrl_soc_data *soc;
-       struct gpio_chip chip;
-       struct ab8500 *parent;
-       struct abx500_gpio_irq_cluster *irq_cluster;
-       int irq_cluster_size;
-};
-
-/**
- * to_abx500_pinctrl() - get the pointer to abx500_pinctrl
- * @chip:      Member of the structure abx500_pinctrl
- */
-static inline struct abx500_pinctrl *to_abx500_pinctrl(struct gpio_chip *chip)
-{
-       return container_of(chip, struct abx500_pinctrl, chip);
-}
-
-static int abx500_gpio_get_bit(struct gpio_chip *chip, u8 reg,
-                              unsigned offset, bool *bit)
-{
-       struct abx500_pinctrl *pct = to_abx500_pinctrl(chip);
-       u8 pos = offset % 8;
-       u8 val;
-       int ret;
-
-       reg += offset / 8;
-       ret = abx500_get_register_interruptible(pct->dev,
-                                               AB8500_MISC, reg, &val);
-
-       *bit = !!(val & BIT(pos));
-
-       if (ret < 0)
-               dev_err(pct->dev,
-                       "%s read reg =%x, offset=%x failed (%d)\n",
-                       __func__, reg, offset, ret);
-
-       return ret;
-}
-
-static int abx500_gpio_set_bits(struct gpio_chip *chip, u8 reg,
-                               unsigned offset, int val)
-{
-       struct abx500_pinctrl *pct = to_abx500_pinctrl(chip);
-       u8 pos = offset % 8;
-       int ret;
-
-       reg += offset / 8;
-       ret = abx500_mask_and_set_register_interruptible(pct->dev,
-                               AB8500_MISC, reg, BIT(pos), val << pos);
-       if (ret < 0)
-               dev_err(pct->dev, "%s write reg, %x offset %x failed (%d)\n",
-                               __func__, reg, offset, ret);
-
-       return ret;
-}
-
-/**
- * abx500_gpio_get() - Get the particular GPIO value
- * @chip:      Gpio device
- * @offset:    GPIO number to read
- */
-static int abx500_gpio_get(struct gpio_chip *chip, unsigned offset)
-{
-       struct abx500_pinctrl *pct = to_abx500_pinctrl(chip);
-       bool bit;
-       bool is_out;
-       u8 gpio_offset = offset - 1;
-       int ret;
-
-       ret = abx500_gpio_get_bit(chip, AB8500_GPIO_DIR1_REG,
-                       gpio_offset, &is_out);
-       if (ret < 0)
-               goto out;
-
-       if (is_out)
-               ret = abx500_gpio_get_bit(chip, AB8500_GPIO_OUT1_REG,
-                               gpio_offset, &bit);
-       else
-               ret = abx500_gpio_get_bit(chip, AB8500_GPIO_IN1_REG,
-                               gpio_offset, &bit);
-out:
-       if (ret < 0) {
-               dev_err(pct->dev, "%s failed (%d)\n", __func__, ret);
-               return ret;
-       }
-
-       return bit;
-}
-
-static void abx500_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
-{
-       struct abx500_pinctrl *pct = to_abx500_pinctrl(chip);
-       int ret;
-
-       ret = abx500_gpio_set_bits(chip, AB8500_GPIO_OUT1_REG, offset, val);
-       if (ret < 0)
-               dev_err(pct->dev, "%s write failed (%d)\n", __func__, ret);
-}
-
-static int abx500_get_pull_updown(struct abx500_pinctrl *pct, int offset,
-                                 enum abx500_gpio_pull_updown *pull_updown)
-{
-       u8 pos;
-       u8 val;
-       int ret;
-       struct pullud *pullud;
-
-       if (!pct->soc->pullud) {
-               dev_err(pct->dev, "%s AB chip doesn't support pull up/down feature",
-                               __func__);
-               ret = -EPERM;
-               goto out;
-       }
-
-       pullud = pct->soc->pullud;
-
-       if ((offset < pullud->first_pin)
-               || (offset > pullud->last_pin)) {
-               ret = -EINVAL;
-               goto out;
-       }
-
-       ret = abx500_get_register_interruptible(pct->dev,
-                       AB8500_MISC, AB8540_GPIO_PULL_UPDOWN_REG, &val);
-
-       pos = (offset - pullud->first_pin) << 1;
-       *pull_updown = (val >> pos) & AB8540_GPIO_PULL_UPDOWN_MASK;
-
-out:
-       if (ret < 0)
-               dev_err(pct->dev, "%s failed (%d)\n", __func__, ret);
-
-       return ret;
-}
-
-static int abx500_set_pull_updown(struct abx500_pinctrl *pct,
-                                 int offset, enum abx500_gpio_pull_updown val)
-{
-       u8 pos;
-       int ret;
-       struct pullud *pullud;
-
-       if (!pct->soc->pullud) {
-               dev_err(pct->dev, "%s AB chip doesn't support pull up/down feature",
-                               __func__);
-               ret = -EPERM;
-               goto out;
-       }
-
-       pullud = pct->soc->pullud;
-
-       if ((offset < pullud->first_pin)
-               || (offset > pullud->last_pin)) {
-               ret = -EINVAL;
-               goto out;
-       }
-       pos = (offset - pullud->first_pin) << 1;
-
-       ret = abx500_mask_and_set_register_interruptible(pct->dev,
-                       AB8500_MISC, AB8540_GPIO_PULL_UPDOWN_REG,
-                       AB8540_GPIO_PULL_UPDOWN_MASK << pos, val << pos);
-
-out:
-       if (ret < 0)
-               dev_err(pct->dev, "%s failed (%d)\n", __func__, ret);
-
-       return ret;
-}
-
-static bool abx500_pullud_supported(struct gpio_chip *chip, unsigned gpio)
-{
-       struct abx500_pinctrl *pct = to_abx500_pinctrl(chip);
-       struct pullud *pullud = pct->soc->pullud;
-
-       return (pullud &&
-               gpio >= pullud->first_pin &&
-               gpio <= pullud->last_pin);
-}
-
-static int abx500_gpio_direction_output(struct gpio_chip *chip,
-                                       unsigned offset,
-                                       int val)
-{
-       struct abx500_pinctrl *pct = to_abx500_pinctrl(chip);
-       unsigned gpio;
-       int ret;
-
-       /* set direction as output */
-       ret = abx500_gpio_set_bits(chip,
-                               AB8500_GPIO_DIR1_REG,
-                               offset,
-                               ABX500_GPIO_OUTPUT);
-       if (ret < 0)
-               goto out;
-
-       /* disable pull down */
-       ret = abx500_gpio_set_bits(chip,
-                               AB8500_GPIO_PUD1_REG,
-                               offset,
-                               ABX500_GPIO_PULL_NONE);
-       if (ret < 0)
-               goto out;
-
-       /* if supported, disable both pull down and pull up */
-       gpio = offset + 1;
-       if (abx500_pullud_supported(chip, gpio)) {
-               ret = abx500_set_pull_updown(pct,
-                               gpio,
-                               ABX500_GPIO_PULL_NONE);
-       }
-out:
-       if (ret < 0) {
-               dev_err(pct->dev, "%s failed (%d)\n", __func__, ret);
-               return ret;
-       }
-
-       /* set the output as 1 or 0 */
-       return abx500_gpio_set_bits(chip, AB8500_GPIO_OUT1_REG, offset, val);
-}
-
-static int abx500_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
-{
-       /* set the register as input */
-       return abx500_gpio_set_bits(chip,
-                               AB8500_GPIO_DIR1_REG,
-                               offset,
-                               ABX500_GPIO_INPUT);
-}
-
-static int abx500_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
-{
-       struct abx500_pinctrl *pct = to_abx500_pinctrl(chip);
-       /* The AB8500 GPIO numbers are off by one */
-       int gpio = offset + 1;
-       int hwirq;
-       int i;
-
-       for (i = 0; i < pct->irq_cluster_size; i++) {
-               struct abx500_gpio_irq_cluster *cluster =
-                       &pct->irq_cluster[i];
-
-               if (gpio >= cluster->start && gpio <= cluster->end) {
-                       /*
-                        * The ABx500 GPIO's associated IRQs are clustered together
-                        * throughout the interrupt numbers at irregular intervals.
-                        * To solve this quandry, we have placed the read-in values
-                        * into the cluster information table.
-                        */
-                       hwirq = gpio - cluster->start + cluster->to_irq;
-                       return irq_create_mapping(pct->parent->domain, hwirq);
-               }
-       }
-
-       return -EINVAL;
-}
-
-static int abx500_set_mode(struct pinctrl_dev *pctldev, struct gpio_chip *chip,
-                          unsigned gpio, int alt_setting)
-{
-       struct abx500_pinctrl *pct = pinctrl_dev_get_drvdata(pctldev);
-       struct alternate_functions af = pct->soc->alternate_functions[gpio];
-       int ret;
-       int val;
-       unsigned offset;
-
-       const char *modes[] = {
-               [ABX500_DEFAULT]        = "default",
-               [ABX500_ALT_A]          = "altA",
-               [ABX500_ALT_B]          = "altB",
-               [ABX500_ALT_C]          = "altC",
-       };
-
-       /* sanity check */
-       if (((alt_setting == ABX500_ALT_A) && (af.gpiosel_bit == UNUSED)) ||
-           ((alt_setting == ABX500_ALT_B) && (af.alt_bit1 == UNUSED)) ||
-           ((alt_setting == ABX500_ALT_C) && (af.alt_bit2 == UNUSED))) {
-               dev_dbg(pct->dev, "pin %d doesn't support %s mode\n", gpio,
-                               modes[alt_setting]);
-               return -EINVAL;
-       }
-
-       /* on ABx5xx, there is no GPIO0, so adjust the offset */
-       offset = gpio - 1;
-
-       switch (alt_setting) {
-       case ABX500_DEFAULT:
-               /*
-                * for ABx5xx family, default mode is always selected by
-                * writing 0 to GPIOSELx register, except for pins which
-                * support at least ALT_B mode, default mode is selected
-                * by writing 1 to GPIOSELx register
-                */
-               val = 0;
-               if (af.alt_bit1 != UNUSED)
-                       val++;
-
-               ret = abx500_gpio_set_bits(chip, AB8500_GPIO_SEL1_REG,
-                                          offset, val);
-               break;
-
-       case ABX500_ALT_A:
-               /*
-                * for ABx5xx family, alt_a mode is always selected by
-                * writing 1 to GPIOSELx register, except for pins which
-                * support at least ALT_B mode, alt_a mode is selected
-                * by writing 0 to GPIOSELx register and 0 in ALTFUNC
-                * register
-                */
-               if (af.alt_bit1 != UNUSED) {
-                       ret = abx500_gpio_set_bits(chip, AB8500_GPIO_SEL1_REG,
-                                       offset, 0);
-                       if (ret < 0)
-                               goto out;
-
-                       ret = abx500_gpio_set_bits(chip,
-                                       AB8500_GPIO_ALTFUN_REG,
-                                       af.alt_bit1,
-                                       !!(af.alta_val & BIT(0)));
-                       if (ret < 0)
-                               goto out;
-
-                       if (af.alt_bit2 != UNUSED)
-                               ret = abx500_gpio_set_bits(chip,
-                                       AB8500_GPIO_ALTFUN_REG,
-                                       af.alt_bit2,
-                                       !!(af.alta_val & BIT(1)));
-               } else
-                       ret = abx500_gpio_set_bits(chip, AB8500_GPIO_SEL1_REG,
-                                       offset, 1);
-               break;
-
-       case ABX500_ALT_B:
-               ret = abx500_gpio_set_bits(chip, AB8500_GPIO_SEL1_REG,
-                               offset, 0);
-               if (ret < 0)
-                       goto out;
-
-               ret = abx500_gpio_set_bits(chip, AB8500_GPIO_ALTFUN_REG,
-                               af.alt_bit1, !!(af.altb_val & BIT(0)));
-               if (ret < 0)
-                       goto out;
-
-               if (af.alt_bit2 != UNUSED)
-                       ret = abx500_gpio_set_bits(chip,
-                                       AB8500_GPIO_ALTFUN_REG,
-                                       af.alt_bit2,
-                                       !!(af.altb_val & BIT(1)));
-               break;
-
-       case ABX500_ALT_C:
-               ret = abx500_gpio_set_bits(chip, AB8500_GPIO_SEL1_REG,
-                               offset, 0);
-               if (ret < 0)
-                       goto out;
-
-               ret = abx500_gpio_set_bits(chip, AB8500_GPIO_ALTFUN_REG,
-                               af.alt_bit2, !!(af.altc_val & BIT(0)));
-               if (ret < 0)
-                       goto out;
-
-               ret = abx500_gpio_set_bits(chip, AB8500_GPIO_ALTFUN_REG,
-                               af.alt_bit2, !!(af.altc_val & BIT(1)));
-               break;
-
-       default:
-               dev_dbg(pct->dev, "unknow alt_setting %d\n", alt_setting);
-
-               return -EINVAL;
-       }
-out:
-       if (ret < 0)
-               dev_err(pct->dev, "%s failed (%d)\n", __func__, ret);
-
-       return ret;
-}
-
-static int abx500_get_mode(struct pinctrl_dev *pctldev, struct gpio_chip *chip,
-                         unsigned gpio)
-{
-       u8 mode;
-       bool bit_mode;
-       bool alt_bit1;
-       bool alt_bit2;
-       struct abx500_pinctrl *pct = pinctrl_dev_get_drvdata(pctldev);
-       struct alternate_functions af = pct->soc->alternate_functions[gpio];
-       /* on ABx5xx, there is no GPIO0, so adjust the offset */
-       unsigned offset = gpio - 1;
-       int ret;
-
-       /*
-        * if gpiosel_bit is set to unused,
-        * it means no GPIO or special case
-        */
-       if (af.gpiosel_bit == UNUSED)
-               return ABX500_DEFAULT;
-
-       /* read GpioSelx register */
-       ret = abx500_gpio_get_bit(chip, AB8500_GPIO_SEL1_REG + (offset / 8),
-                       af.gpiosel_bit, &bit_mode);
-       if (ret < 0)
-               goto out;
-
-       mode = bit_mode;
-
-       /* sanity check */
-       if ((af.alt_bit1 < UNUSED) || (af.alt_bit1 > 7) ||
-           (af.alt_bit2 < UNUSED) || (af.alt_bit2 > 7)) {
-               dev_err(pct->dev,
-                       "alt_bitX value not in correct range (-1 to 7)\n");
-               return -EINVAL;
-       }
-
-       /* if alt_bit2 is used, alt_bit1 must be used too */
-       if ((af.alt_bit2 != UNUSED) && (af.alt_bit1 == UNUSED)) {
-               dev_err(pct->dev,
-                       "if alt_bit2 is used, alt_bit1 can't be unused\n");
-               return -EINVAL;
-       }
-
-       /* check if pin use AlternateFunction register */
-       if ((af.alt_bit1 == UNUSED) && (af.alt_bit2 == UNUSED))
-               return mode;
-       /*
-        * if pin GPIOSEL bit is set and pin supports alternate function,
-        * it means DEFAULT mode
-        */
-       if (mode)
-               return ABX500_DEFAULT;
-
-       /*
-        * pin use the AlternatFunction register
-        * read alt_bit1 value
-        */
-       ret = abx500_gpio_get_bit(chip, AB8500_GPIO_ALTFUN_REG,
-                           af.alt_bit1, &alt_bit1);
-       if (ret < 0)
-               goto out;
-
-       if (af.alt_bit2 != UNUSED) {
-               /* read alt_bit2 value */
-               ret = abx500_gpio_get_bit(chip, AB8500_GPIO_ALTFUN_REG,
-                               af.alt_bit2,
-                               &alt_bit2);
-               if (ret < 0)
-                       goto out;
-       } else
-               alt_bit2 = 0;
-
-       mode = (alt_bit2 << 1) + alt_bit1;
-       if (mode == af.alta_val)
-               return ABX500_ALT_A;
-       else if (mode == af.altb_val)
-               return ABX500_ALT_B;
-       else
-               return ABX500_ALT_C;
-
-out:
-       dev_err(pct->dev, "%s failed (%d)\n", __func__, ret);
-       return ret;
-}
-
-#ifdef CONFIG_DEBUG_FS
-
-#include <linux/seq_file.h>
-
-static void abx500_gpio_dbg_show_one(struct seq_file *s,
-                                    struct pinctrl_dev *pctldev,
-                                    struct gpio_chip *chip,
-                                    unsigned offset, unsigned gpio)
-{
-       struct abx500_pinctrl *pct = pinctrl_dev_get_drvdata(pctldev);
-       const char *label = gpiochip_is_requested(chip, offset - 1);
-       u8 gpio_offset = offset - 1;
-       int mode = -1;
-       bool is_out;
-       bool pd;
-       enum abx500_gpio_pull_updown pud = 0;
-       int ret;
-
-       const char *modes[] = {
-               [ABX500_DEFAULT]        = "default",
-               [ABX500_ALT_A]          = "altA",
-               [ABX500_ALT_B]          = "altB",
-               [ABX500_ALT_C]          = "altC",
-       };
-
-       const char *pull_up_down[] = {
-               [ABX500_GPIO_PULL_DOWN]         = "pull down",
-               [ABX500_GPIO_PULL_NONE]         = "pull none",
-               [ABX500_GPIO_PULL_NONE + 1]     = "pull none",
-               [ABX500_GPIO_PULL_UP]           = "pull up",
-       };
-
-       ret = abx500_gpio_get_bit(chip, AB8500_GPIO_DIR1_REG,
-                       gpio_offset, &is_out);
-       if (ret < 0)
-               goto out;
-
-       seq_printf(s, " gpio-%-3d (%-20.20s) %-3s",
-                  gpio, label ?: "(none)",
-                  is_out ? "out" : "in ");
-
-       if (!is_out) {
-               if (abx500_pullud_supported(chip, offset)) {
-                       ret = abx500_get_pull_updown(pct, offset, &pud);
-                       if (ret < 0)
-                               goto out;
-
-                       seq_printf(s, " %-9s", pull_up_down[pud]);
-               } else {
-                       ret = abx500_gpio_get_bit(chip, AB8500_GPIO_PUD1_REG,
-                                       gpio_offset, &pd);
-                       if (ret < 0)
-                               goto out;
-
-                       seq_printf(s, " %-9s", pull_up_down[pd]);
-               }
-       } else
-               seq_printf(s, " %-9s", chip->get(chip, offset) ? "hi" : "lo");
-
-       if (pctldev)
-               mode = abx500_get_mode(pctldev, chip, offset);
-
-       seq_printf(s, " %s", (mode < 0) ? "unknown" : modes[mode]);
-
-out:
-       if (ret < 0)
-               dev_err(pct->dev, "%s failed (%d)\n", __func__, ret);
-}
-
-static void abx500_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
-{
-       unsigned i;
-       unsigned gpio = chip->base;
-       struct abx500_pinctrl *pct = to_abx500_pinctrl(chip);
-       struct pinctrl_dev *pctldev = pct->pctldev;
-
-       for (i = 0; i < chip->ngpio; i++, gpio++) {
-               /* On AB8500, there is no GPIO0, the first is the GPIO 1 */
-               abx500_gpio_dbg_show_one(s, pctldev, chip, i + 1, gpio);
-               seq_printf(s, "\n");
-       }
-}
-
-#else
-static inline void abx500_gpio_dbg_show_one(struct seq_file *s,
-                                           struct pinctrl_dev *pctldev,
-                                           struct gpio_chip *chip,
-                                           unsigned offset, unsigned gpio)
-{
-}
-#define abx500_gpio_dbg_show   NULL
-#endif
-
-static int abx500_gpio_request(struct gpio_chip *chip, unsigned offset)
-{
-       int gpio = chip->base + offset;
-
-       return pinctrl_request_gpio(gpio);
-}
-
-static void abx500_gpio_free(struct gpio_chip *chip, unsigned offset)
-{
-       int gpio = chip->base + offset;
-
-       pinctrl_free_gpio(gpio);
-}
-
-static struct gpio_chip abx500gpio_chip = {
-       .label                  = "abx500-gpio",
-       .owner                  = THIS_MODULE,
-       .request                = abx500_gpio_request,
-       .free                   = abx500_gpio_free,
-       .direction_input        = abx500_gpio_direction_input,
-       .get                    = abx500_gpio_get,
-       .direction_output       = abx500_gpio_direction_output,
-       .set                    = abx500_gpio_set,
-       .to_irq                 = abx500_gpio_to_irq,
-       .dbg_show               = abx500_gpio_dbg_show,
-};
-
-static int abx500_pmx_get_funcs_cnt(struct pinctrl_dev *pctldev)
-{
-       struct abx500_pinctrl *pct = pinctrl_dev_get_drvdata(pctldev);
-
-       return pct->soc->nfunctions;
-}
-
-static const char *abx500_pmx_get_func_name(struct pinctrl_dev *pctldev,
-                                        unsigned function)
-{
-       struct abx500_pinctrl *pct = pinctrl_dev_get_drvdata(pctldev);
-
-       return pct->soc->functions[function].name;
-}
-
-static int abx500_pmx_get_func_groups(struct pinctrl_dev *pctldev,
-                                     unsigned function,
-                                     const char * const **groups,
-                                     unsigned * const num_groups)
-{
-       struct abx500_pinctrl *pct = pinctrl_dev_get_drvdata(pctldev);
-
-       *groups = pct->soc->functions[function].groups;
-       *num_groups = pct->soc->functions[function].ngroups;
-
-       return 0;
-}
-
-static int abx500_pmx_enable(struct pinctrl_dev *pctldev, unsigned function,
-                            unsigned group)
-{
-       struct abx500_pinctrl *pct = pinctrl_dev_get_drvdata(pctldev);
-       struct gpio_chip *chip = &pct->chip;
-       const struct abx500_pingroup *g;
-       int i;
-       int ret = 0;
-
-       g = &pct->soc->groups[group];
-       if (g->altsetting < 0)
-               return -EINVAL;
-
-       dev_dbg(pct->dev, "enable group %s, %u pins\n", g->name, g->npins);
-
-       for (i = 0; i < g->npins; i++) {
-               dev_dbg(pct->dev, "setting pin %d to altsetting %d\n",
-                       g->pins[i], g->altsetting);
-
-               ret = abx500_set_mode(pctldev, chip, g->pins[i], g->altsetting);
-       }
-
-       if (ret < 0)
-               dev_err(pct->dev, "%s failed (%d)\n", __func__, ret);
-
-       return ret;
-}
-
-static void abx500_pmx_disable(struct pinctrl_dev *pctldev,
-                              unsigned function, unsigned group)
-{
-       struct abx500_pinctrl *pct = pinctrl_dev_get_drvdata(pctldev);
-       const struct abx500_pingroup *g;
-
-       g = &pct->soc->groups[group];
-       if (g->altsetting < 0)
-               return;
-
-       /* FIXME: poke out the mux, set the pin to some default state? */
-       dev_dbg(pct->dev, "disable group %s, %u pins\n", g->name, g->npins);
-}
-
-static int abx500_gpio_request_enable(struct pinctrl_dev *pctldev,
-                              struct pinctrl_gpio_range *range,
-                              unsigned offset)
-{
-       struct abx500_pinctrl *pct = pinctrl_dev_get_drvdata(pctldev);
-       const struct abx500_pinrange *p;
-       int ret;
-       int i;
-
-       /*
-        * Different ranges have different ways to enable GPIO function on a
-        * pin, so refer back to our local range type, where we handily define
-        * what altfunc enables GPIO for a certain pin.
-        */
-       for (i = 0; i < pct->soc->gpio_num_ranges; i++) {
-               p = &pct->soc->gpio_ranges[i];
-               if ((offset >= p->offset) &&
-                   (offset < (p->offset + p->npins)))
-                 break;
-       }
-
-       if (i == pct->soc->gpio_num_ranges) {
-               dev_err(pct->dev, "%s failed to locate range\n", __func__);
-               return -ENODEV;
-       }
-
-       dev_dbg(pct->dev, "enable GPIO by altfunc %d at gpio %d\n",
-               p->altfunc, offset);
-
-       ret = abx500_set_mode(pct->pctldev, &pct->chip,
-                             offset, p->altfunc);
-       if (ret < 0)
-               dev_err(pct->dev, "%s setting altfunc failed\n", __func__);
-
-       return ret;
-}
-
-static void abx500_gpio_disable_free(struct pinctrl_dev *pctldev,
-                                    struct pinctrl_gpio_range *range,
-                                    unsigned offset)
-{
-}
-
-static const struct pinmux_ops abx500_pinmux_ops = {
-       .get_functions_count = abx500_pmx_get_funcs_cnt,
-       .get_function_name = abx500_pmx_get_func_name,
-       .get_function_groups = abx500_pmx_get_func_groups,
-       .enable = abx500_pmx_enable,
-       .disable = abx500_pmx_disable,
-       .gpio_request_enable = abx500_gpio_request_enable,
-       .gpio_disable_free = abx500_gpio_disable_free,
-};
-
-static int abx500_get_groups_cnt(struct pinctrl_dev *pctldev)
-{
-       struct abx500_pinctrl *pct = pinctrl_dev_get_drvdata(pctldev);
-
-       return pct->soc->ngroups;
-}
-
-static const char *abx500_get_group_name(struct pinctrl_dev *pctldev,
-                                        unsigned selector)
-{
-       struct abx500_pinctrl *pct = pinctrl_dev_get_drvdata(pctldev);
-
-       return pct->soc->groups[selector].name;
-}
-
-static int abx500_get_group_pins(struct pinctrl_dev *pctldev,
-                                unsigned selector,
-                                const unsigned **pins,
-                                unsigned *num_pins)
-{
-       struct abx500_pinctrl *pct = pinctrl_dev_get_drvdata(pctldev);
-
-       *pins = pct->soc->groups[selector].pins;
-       *num_pins = pct->soc->groups[selector].npins;
-
-       return 0;
-}
-
-static void abx500_pin_dbg_show(struct pinctrl_dev *pctldev,
-                               struct seq_file *s, unsigned offset)
-{
-       struct abx500_pinctrl *pct = pinctrl_dev_get_drvdata(pctldev);
-       struct gpio_chip *chip = &pct->chip;
-
-       abx500_gpio_dbg_show_one(s, pctldev, chip, offset,
-                                chip->base + offset - 1);
-}
-
-static void abx500_dt_free_map(struct pinctrl_dev *pctldev,
-               struct pinctrl_map *map, unsigned num_maps)
-{
-       int i;
-
-       for (i = 0; i < num_maps; i++)
-               if (map[i].type == PIN_MAP_TYPE_CONFIGS_PIN)
-                       kfree(map[i].data.configs.configs);
-       kfree(map);
-}
-
-static int abx500_dt_reserve_map(struct pinctrl_map **map,
-               unsigned *reserved_maps,
-               unsigned *num_maps,
-               unsigned reserve)
-{
-       unsigned old_num = *reserved_maps;
-       unsigned new_num = *num_maps + reserve;
-       struct pinctrl_map *new_map;
-
-       if (old_num >= new_num)
-               return 0;
-
-       new_map = krealloc(*map, sizeof(*new_map) * new_num, GFP_KERNEL);
-       if (!new_map)
-               return -ENOMEM;
-
-       memset(new_map + old_num, 0, (new_num - old_num) * sizeof(*new_map));
-
-       *map = new_map;
-       *reserved_maps = new_num;
-
-       return 0;
-}
-
-static int abx500_dt_add_map_mux(struct pinctrl_map **map,
-               unsigned *reserved_maps,
-               unsigned *num_maps, const char *group,
-               const char *function)
-{
-       if (*num_maps == *reserved_maps)
-               return -ENOSPC;
-
-       (*map)[*num_maps].type = PIN_MAP_TYPE_MUX_GROUP;
-       (*map)[*num_maps].data.mux.group = group;
-       (*map)[*num_maps].data.mux.function = function;
-       (*num_maps)++;
-
-       return 0;
-}
-
-static int abx500_dt_add_map_configs(struct pinctrl_map **map,
-               unsigned *reserved_maps,
-               unsigned *num_maps, const char *group,
-               unsigned long *configs, unsigned num_configs)
-{
-       unsigned long *dup_configs;
-
-       if (*num_maps == *reserved_maps)
-               return -ENOSPC;
-
-       dup_configs = kmemdup(configs, num_configs * sizeof(*dup_configs),
-                             GFP_KERNEL);
-       if (!dup_configs)
-               return -ENOMEM;
-
-       (*map)[*num_maps].type = PIN_MAP_TYPE_CONFIGS_PIN;
-
-       (*map)[*num_maps].data.configs.group_or_pin = group;
-       (*map)[*num_maps].data.configs.configs = dup_configs;
-       (*map)[*num_maps].data.configs.num_configs = num_configs;
-       (*num_maps)++;
-
-       return 0;
-}
-
-static const char *abx500_find_pin_name(struct pinctrl_dev *pctldev,
-                                       const char *pin_name)
-{
-       int i, pin_number;
-       struct abx500_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
-
-       if (sscanf((char *)pin_name, "GPIO%d", &pin_number) == 1)
-               for (i = 0; i < npct->soc->npins; i++)
-                       if (npct->soc->pins[i].number == pin_number)
-                               return npct->soc->pins[i].name;
-       return NULL;
-}
-
-static int abx500_dt_subnode_to_map(struct pinctrl_dev *pctldev,
-               struct device_node *np,
-               struct pinctrl_map **map,
-               unsigned *reserved_maps,
-               unsigned *num_maps)
-{
-       int ret;
-       const char *function = NULL;
-       unsigned long *configs;
-       unsigned int nconfigs = 0;
-       bool has_config = 0;
-       unsigned reserve = 0;
-       struct property *prop;
-       const char *group, *gpio_name;
-       struct device_node *np_config;
-
-       ret = of_property_read_string(np, "ste,function", &function);
-       if (ret >= 0)
-               reserve = 1;
-
-       ret = pinconf_generic_parse_dt_config(np, &configs, &nconfigs);
-       if (nconfigs)
-               has_config = 1;
-
-       np_config = of_parse_phandle(np, "ste,config", 0);
-       if (np_config) {
-               ret = pinconf_generic_parse_dt_config(np_config, &configs,
-                               &nconfigs);
-               if (ret)
-                       goto exit;
-               has_config |= nconfigs;
-       }
-
-       ret = of_property_count_strings(np, "ste,pins");
-       if (ret < 0)
-               goto exit;
-
-       if (has_config)
-               reserve++;
-
-       reserve *= ret;
-
-       ret = abx500_dt_reserve_map(map, reserved_maps, num_maps, reserve);
-       if (ret < 0)
-               goto exit;
-
-       of_property_for_each_string(np, "ste,pins", prop, group) {
-               if (function) {
-                       ret = abx500_dt_add_map_mux(map, reserved_maps,
-                                       num_maps, group, function);
-                       if (ret < 0)
-                               goto exit;
-               }
-               if (has_config) {
-                       gpio_name = abx500_find_pin_name(pctldev, group);
-
-                       ret = abx500_dt_add_map_configs(map, reserved_maps,
-                                       num_maps, gpio_name, configs, 1);
-                       if (ret < 0)
-                               goto exit;
-               }
-
-       }
-exit:
-       return ret;
-}
-
-static int abx500_dt_node_to_map(struct pinctrl_dev *pctldev,
-                                struct device_node *np_config,
-                                struct pinctrl_map **map, unsigned *num_maps)
-{
-       unsigned reserved_maps;
-       struct device_node *np;
-       int ret;
-
-       reserved_maps = 0;
-       *map = NULL;
-       *num_maps = 0;
-
-       for_each_child_of_node(np_config, np) {
-               ret = abx500_dt_subnode_to_map(pctldev, np, map,
-                               &reserved_maps, num_maps);
-               if (ret < 0) {
-                       abx500_dt_free_map(pctldev, *map, *num_maps);
-                       return ret;
-               }
-       }
-
-       return 0;
-}
-
-static const struct pinctrl_ops abx500_pinctrl_ops = {
-       .get_groups_count = abx500_get_groups_cnt,
-       .get_group_name = abx500_get_group_name,
-       .get_group_pins = abx500_get_group_pins,
-       .pin_dbg_show = abx500_pin_dbg_show,
-       .dt_node_to_map = abx500_dt_node_to_map,
-       .dt_free_map = abx500_dt_free_map,
-};
-
-static int abx500_pin_config_get(struct pinctrl_dev *pctldev,
-                         unsigned pin,
-                         unsigned long *config)
-{
-       return -ENOSYS;
-}
-
-static int abx500_pin_config_set(struct pinctrl_dev *pctldev,
-                         unsigned pin,
-                         unsigned long *configs,
-                         unsigned num_configs)
-{
-       struct abx500_pinctrl *pct = pinctrl_dev_get_drvdata(pctldev);
-       struct gpio_chip *chip = &pct->chip;
-       unsigned offset;
-       int ret = -EINVAL;
-       int i;
-       enum pin_config_param param;
-       enum pin_config_param argument;
-
-       for (i = 0; i < num_configs; i++) {
-               param = pinconf_to_config_param(configs[i]);
-               argument = pinconf_to_config_argument(configs[i]);
-
-               dev_dbg(chip->dev, "pin %d [%#lx]: %s %s\n",
-                       pin, configs[i],
-                       (param == PIN_CONFIG_OUTPUT) ? "output " : "input",
-                       (param == PIN_CONFIG_OUTPUT) ?
-                       (argument ? "high" : "low") :
-                       (argument ? "pull up" : "pull down"));
-
-               /* on ABx500, there is no GPIO0, so adjust the offset */
-               offset = pin - 1;
-
-               switch (param) {
-               case PIN_CONFIG_BIAS_DISABLE:
-                       ret = abx500_gpio_direction_input(chip, offset);
-                       if (ret < 0)
-                               goto out;
-                       /*
-                        * Some chips only support pull down, while some
-                        * actually support both pull up and pull down. Such
-                        * chips have a "pullud" range specified for the pins
-                        * that support both features. If the pin is not
-                        * within that range, we fall back to the old bit set
-                        * that only support pull down.
-                        */
-                       if (abx500_pullud_supported(chip, pin))
-                               ret = abx500_set_pull_updown(pct,
-                                       pin,
-                                       ABX500_GPIO_PULL_NONE);
-                       else
-                               /* Chip only supports pull down */
-                               ret = abx500_gpio_set_bits(chip,
-                                       AB8500_GPIO_PUD1_REG, offset,
-                                       ABX500_GPIO_PULL_NONE);
-                       break;
-
-               case PIN_CONFIG_BIAS_PULL_DOWN:
-                       ret = abx500_gpio_direction_input(chip, offset);
-                       if (ret < 0)
-                               goto out;
-                       /*
-                        * if argument = 1 set the pull down
-                        * else clear the pull down
-                        * Some chips only support pull down, while some
-                        * actually support both pull up and pull down. Such
-                        * chips have a "pullud" range specified for the pins
-                        * that support both features. If the pin is not
-                        * within that range, we fall back to the old bit set
-                        * that only support pull down.
-                        */
-                       if (abx500_pullud_supported(chip, pin))
-                               ret = abx500_set_pull_updown(pct,
-                                       pin,
-                                       argument ? ABX500_GPIO_PULL_DOWN :
-                                       ABX500_GPIO_PULL_NONE);
-                       else
-                               /* Chip only supports pull down */
-                               ret = abx500_gpio_set_bits(chip,
-                               AB8500_GPIO_PUD1_REG,
-                                       offset,
-                                       argument ? ABX500_GPIO_PULL_DOWN :
-                                       ABX500_GPIO_PULL_NONE);
-                       break;
-
-               case PIN_CONFIG_BIAS_PULL_UP:
-                       ret = abx500_gpio_direction_input(chip, offset);
-                       if (ret < 0)
-                               goto out;
-                       /*
-                        * if argument = 1 set the pull up
-                        * else clear the pull up
-                        */
-                       ret = abx500_gpio_direction_input(chip, offset);
-                       /*
-                        * Some chips only support pull down, while some
-                        * actually support both pull up and pull down. Such
-                        * chips have a "pullud" range specified for the pins
-                        * that support both features. If the pin is not
-                        * within that range, do nothing
-                        */
-                       if (abx500_pullud_supported(chip, pin))
-                               ret = abx500_set_pull_updown(pct,
-                                       pin,
-                                       argument ? ABX500_GPIO_PULL_UP :
-                                       ABX500_GPIO_PULL_NONE);
-                       break;
-
-               case PIN_CONFIG_OUTPUT:
-                       ret = abx500_gpio_direction_output(chip, offset,
-                               argument);
-                       break;
-
-               default:
-                       dev_err(chip->dev, "illegal configuration requested\n");
-               }
-       } /* for each config */
-out:
-       if (ret < 0)
-               dev_err(pct->dev, "%s failed (%d)\n", __func__, ret);
-
-       return ret;
-}
-
-static const struct pinconf_ops abx500_pinconf_ops = {
-       .pin_config_get = abx500_pin_config_get,
-       .pin_config_set = abx500_pin_config_set,
-};
-
-static struct pinctrl_desc abx500_pinctrl_desc = {
-       .name = "pinctrl-abx500",
-       .pctlops = &abx500_pinctrl_ops,
-       .pmxops = &abx500_pinmux_ops,
-       .confops = &abx500_pinconf_ops,
-       .owner = THIS_MODULE,
-};
-
-static int abx500_get_gpio_num(struct abx500_pinctrl_soc_data *soc)
-{
-       unsigned int lowest = 0;
-       unsigned int highest = 0;
-       unsigned int npins = 0;
-       int i;
-
-       /*
-        * Compute number of GPIOs from the last SoC gpio range descriptors
-        * These ranges may include "holes" but the GPIO number space shall
-        * still be homogeneous, so we need to detect and account for any
-        * such holes so that these are included in the number of GPIO pins.
-        */
-       for (i = 0; i < soc->gpio_num_ranges; i++) {
-               unsigned gstart;
-               unsigned gend;
-               const struct abx500_pinrange *p;
-
-               p = &soc->gpio_ranges[i];
-               gstart = p->offset;
-               gend = p->offset + p->npins - 1;
-
-               if (i == 0) {
-                       /* First iteration, set start values */
-                       lowest = gstart;
-                       highest = gend;
-               } else {
-                       if (gstart < lowest)
-                               lowest = gstart;
-                       if (gend > highest)
-                               highest = gend;
-               }
-       }
-       /* this gives the absolute number of pins */
-       npins = highest - lowest + 1;
-       return npins;
-}
-
-static const struct of_device_id abx500_gpio_match[] = {
-       { .compatible = "stericsson,ab8500-gpio", .data = (void *)PINCTRL_AB8500, },
-       { .compatible = "stericsson,ab8505-gpio", .data = (void *)PINCTRL_AB8505, },
-       { .compatible = "stericsson,ab8540-gpio", .data = (void *)PINCTRL_AB8540, },
-       { .compatible = "stericsson,ab9540-gpio", .data = (void *)PINCTRL_AB9540, },
-       { }
-};
-
-static int abx500_gpio_probe(struct platform_device *pdev)
-{
-       struct device_node *np = pdev->dev.of_node;
-       const struct of_device_id *match;
-       struct abx500_pinctrl *pct;
-       unsigned int id = -1;
-       int ret, err;
-       int i;
-
-       if (!np) {
-               dev_err(&pdev->dev, "gpio dt node missing\n");
-               return -ENODEV;
-       }
-
-       pct = devm_kzalloc(&pdev->dev, sizeof(struct abx500_pinctrl),
-                                  GFP_KERNEL);
-       if (pct == NULL) {
-               dev_err(&pdev->dev,
-                       "failed to allocate memory for pct\n");
-               return -ENOMEM;
-       }
-
-       pct->dev = &pdev->dev;
-       pct->parent = dev_get_drvdata(pdev->dev.parent);
-       pct->chip = abx500gpio_chip;
-       pct->chip.dev = &pdev->dev;
-       pct->chip.base = -1; /* Dynamic allocation */
-
-       match = of_match_device(abx500_gpio_match, &pdev->dev);
-       if (!match) {
-               dev_err(&pdev->dev, "gpio dt not matching\n");
-               return -ENODEV;
-       }
-       id = (unsigned long)match->data;
-
-       /* Poke in other ASIC variants here */
-       switch (id) {
-       case PINCTRL_AB8500:
-               abx500_pinctrl_ab8500_init(&pct->soc);
-               break;
-       case PINCTRL_AB8540:
-               abx500_pinctrl_ab8540_init(&pct->soc);
-               break;
-       case PINCTRL_AB9540:
-               abx500_pinctrl_ab9540_init(&pct->soc);
-               break;
-       case PINCTRL_AB8505:
-               abx500_pinctrl_ab8505_init(&pct->soc);
-               break;
-       default:
-               dev_err(&pdev->dev, "Unsupported pinctrl sub driver (%d)\n", id);
-               return -EINVAL;
-       }
-
-       if (!pct->soc) {
-               dev_err(&pdev->dev, "Invalid SOC data\n");
-               return -EINVAL;
-       }
-
-       pct->chip.ngpio = abx500_get_gpio_num(pct->soc);
-       pct->irq_cluster = pct->soc->gpio_irq_cluster;
-       pct->irq_cluster_size = pct->soc->ngpio_irq_cluster;
-
-       ret = gpiochip_add(&pct->chip);
-       if (ret) {
-               dev_err(&pdev->dev, "unable to add gpiochip: %d\n", ret);
-               return ret;
-       }
-       dev_info(&pdev->dev, "added gpiochip\n");
-
-       abx500_pinctrl_desc.pins = pct->soc->pins;
-       abx500_pinctrl_desc.npins = pct->soc->npins;
-       pct->pctldev = pinctrl_register(&abx500_pinctrl_desc, &pdev->dev, pct);
-       if (!pct->pctldev) {
-               dev_err(&pdev->dev,
-                       "could not register abx500 pinctrl driver\n");
-               ret = -EINVAL;
-               goto out_rem_chip;
-       }
-       dev_info(&pdev->dev, "registered pin controller\n");
-
-       /* We will handle a range of GPIO pins */
-       for (i = 0; i < pct->soc->gpio_num_ranges; i++) {
-               const struct abx500_pinrange *p = &pct->soc->gpio_ranges[i];
-
-               ret = gpiochip_add_pin_range(&pct->chip,
-                                       dev_name(&pdev->dev),
-                                       p->offset - 1, p->offset, p->npins);
-               if (ret < 0)
-                       goto out_rem_chip;
-       }
-
-       platform_set_drvdata(pdev, pct);
-       dev_info(&pdev->dev, "initialized abx500 pinctrl driver\n");
-
-       return 0;
-
-out_rem_chip:
-       err = gpiochip_remove(&pct->chip);
-       if (err)
-               dev_info(&pdev->dev, "failed to remove gpiochip\n");
-
-       return ret;
-}
-
-/**
- * abx500_gpio_remove() - remove Ab8500-gpio driver
- * @pdev:      Platform device registered
- */
-static int abx500_gpio_remove(struct platform_device *pdev)
-{
-       struct abx500_pinctrl *pct = platform_get_drvdata(pdev);
-       int ret;
-
-       ret = gpiochip_remove(&pct->chip);
-       if (ret < 0) {
-               dev_err(pct->dev, "unable to remove gpiochip: %d\n",
-                       ret);
-               return ret;
-       }
-
-       return 0;
-}
-
-static struct platform_driver abx500_gpio_driver = {
-       .driver = {
-               .name = "abx500-gpio",
-               .owner = THIS_MODULE,
-               .of_match_table = abx500_gpio_match,
-       },
-       .probe = abx500_gpio_probe,
-       .remove = abx500_gpio_remove,
-};
-
-static int __init abx500_gpio_init(void)
-{
-       return platform_driver_register(&abx500_gpio_driver);
-}
-core_initcall(abx500_gpio_init);
-
-MODULE_AUTHOR("Patrice Chotard <patrice.chotard@st.com>");
-MODULE_DESCRIPTION("Driver allows to use AxB5xx unused pins to be used as GPIO");
-MODULE_ALIAS("platform:abx500-gpio");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/pinctrl/pinctrl-abx500.h b/drivers/pinctrl/pinctrl-abx500.h
deleted file mode 100644 (file)
index 2beef3b..0000000
+++ /dev/null
@@ -1,246 +0,0 @@
-#ifndef PINCTRL_PINCTRL_ABx500_H
-#define PINCTRL_PINCTRL_ABx500_H
-
-/* Package definitions */
-#define PINCTRL_AB8500 0
-#define PINCTRL_AB8540 1
-#define PINCTRL_AB9540 2
-#define PINCTRL_AB8505 3
-
-/* pins alternate function */
-enum abx500_pin_func {
-       ABX500_DEFAULT,
-       ABX500_ALT_A,
-       ABX500_ALT_B,
-       ABX500_ALT_C,
-};
-
-enum abx500_gpio_pull_updown {
-       ABX500_GPIO_PULL_DOWN = 0x0,
-       ABX500_GPIO_PULL_NONE = 0x1,
-       ABX500_GPIO_PULL_UP = 0x3,
-};
-
-enum abx500_gpio_vinsel {
-       ABX500_GPIO_VINSEL_VBAT = 0x0,
-       ABX500_GPIO_VINSEL_VIN_1V8 = 0x1,
-       ABX500_GPIO_VINSEL_VDD_BIF = 0x2,
-};
-
-/**
- * struct abx500_function - ABx500 pinctrl mux function
- * @name: The name of the function, exported to pinctrl core.
- * @groups: An array of pin groups that may select this function.
- * @ngroups: The number of entries in @groups.
- */
-struct abx500_function {
-       const char *name;
-       const char * const *groups;
-       unsigned ngroups;
-};
-
-/**
- * struct abx500_pingroup - describes a ABx500 pin group
- * @name: the name of this specific pin group
- * @pins: an array of discrete physical pins used in this group, taken
- *     from the driver-local pin enumeration space
- * @num_pins: the number of pins in this group array, i.e. the number of
- *     elements in .pins so we can iterate over that array
- * @altsetting: the altsetting to apply to all pins in this group to
- *     configure them to be used by a function
- */
-struct abx500_pingroup {
-       const char *name;
-       const unsigned int *pins;
-       const unsigned npins;
-       int altsetting;
-};
-
-#define ALTERNATE_FUNCTIONS(pin, sel_bit, alt1, alt2, alta, altb, altc)        \
-{                                                                      \
-       .pin_number = pin,                                              \
-       .gpiosel_bit = sel_bit,                                         \
-       .alt_bit1 = alt1,                                               \
-       .alt_bit2 = alt2,                                               \
-       .alta_val = alta,                                               \
-       .altb_val = altb,                                               \
-       .altc_val = altc,                                               \
-}
-
-#define UNUSED -1
-/**
- * struct alternate_functions
- * @pin_number:                The pin number
- * @gpiosel_bit:       Control bit in GPIOSEL register,
- * @alt_bit1:          First AlternateFunction bit used to select the
- *                     alternate function
- * @alt_bit2:          Second AlternateFunction bit used to select the
- *                     alternate function
- *
- *                     these 3 following fields are necessary due to none
- *                     coherency on how to select the altA, altB and altC
- *                     function between the ABx500 SOC family when using
- *                     alternatfunc register.
- * @alta_val:          value to write in alternatfunc to select altA function
- * @altb_val:          value to write in alternatfunc to select altB function
- * @altc_val:          value to write in alternatfunc to select altC function
- */
-struct alternate_functions {
-       unsigned pin_number;
-       s8 gpiosel_bit;
-       s8 alt_bit1;
-       s8 alt_bit2;
-       u8 alta_val;
-       u8 altb_val;
-       u8 altc_val;
-};
-
-/**
- * struct pullud - specific pull up/down feature
- * @first_pin:         The pin number of the first pins which support
- *                     specific pull up/down
- * @last_pin:          The pin number of the last pins
- */
-struct pullud {
-       unsigned first_pin;
-       unsigned last_pin;
-};
-
-#define GPIO_IRQ_CLUSTER(a, b, c)      \
-{                                      \
-       .start = a,                     \
-       .end = b,                       \
-       .to_irq = c,                    \
-}
-
-/**
- * struct abx500_gpio_irq_cluster - indicates GPIOs which are interrupt
- *                     capable
- * @start:             The pin number of the first pin interrupt capable
- * @end:               The pin number of the last pin interrupt capable
- * @to_irq:            The ABx500 GPIO's associated IRQs are clustered
- *                      together throughout the interrupt numbers at irregular
- *                      intervals. To solve this quandary, we will place the
- *                      read-in values into the cluster information table
- */
-
-struct abx500_gpio_irq_cluster {
-       int start;
-       int end;
-       int to_irq;
-};
-
-/**
- * struct abx500_pinrange - map pin numbers to GPIO offsets
- * @offset:            offset into the GPIO local numberspace, incidentally
- *                     identical to the offset into the local pin numberspace
- * @npins:             number of pins to map from both offsets
- * @altfunc:           altfunc setting to be used to enable GPIO on a pin in
- *                     this range (may vary)
- */
-struct abx500_pinrange {
-       unsigned int offset;
-       unsigned int npins;
-       int altfunc;
-};
-
-#define ABX500_PINRANGE(a, b, c) { .offset = a, .npins = b, .altfunc = c }
-
-/**
- * struct abx500_pinctrl_soc_data - ABx500 pin controller per-SoC configuration
- * @gpio_ranges:       An array of GPIO ranges for this SoC
- * @gpio_num_ranges:   The number of GPIO ranges for this SoC
- * @pins:              An array describing all pins the pin controller affects.
- *                     All pins which are also GPIOs must be listed first within the
- *                     array, and be numbered identically to the GPIO controller's
- *                     numbering.
- * @npins:             The number of entries in @pins.
- * @functions:         The functions supported on this SoC.
- * @nfunction:         The number of entries in @functions.
- * @groups:            An array describing all pin groups the pin SoC supports.
- * @ngroups:           The number of entries in @groups.
- * @alternate_functions: array describing pins which supports alternate and
- *                     how to set it.
- * @pullud:            array describing pins which supports pull up/down
- *                     specific registers.
- * @gpio_irq_cluster:  An array of GPIO interrupt capable for this SoC
- * @ngpio_irq_cluster: The number of GPIO inetrrupt capable for this SoC
- * @irq_gpio_rising_offset: Interrupt offset used as base to compute specific
- *                     setting strategy of the rising interrupt line
- * @irq_gpio_falling_offset: Interrupt offset used as base to compute specific
- *                     setting strategy of the falling interrupt line
- * @irq_gpio_factor:   Factor used to compute specific setting strategy of
- *                     the interrupt line
- */
-
-struct abx500_pinctrl_soc_data {
-       const struct abx500_pinrange *gpio_ranges;
-       unsigned gpio_num_ranges;
-       const struct pinctrl_pin_desc *pins;
-       unsigned npins;
-       const struct abx500_function *functions;
-       unsigned nfunctions;
-       const struct abx500_pingroup *groups;
-       unsigned ngroups;
-       struct alternate_functions *alternate_functions;
-       struct pullud *pullud;
-       struct abx500_gpio_irq_cluster *gpio_irq_cluster;
-       unsigned ngpio_irq_cluster;
-       int irq_gpio_rising_offset;
-       int irq_gpio_falling_offset;
-       int irq_gpio_factor;
-};
-
-#ifdef CONFIG_PINCTRL_AB8500
-
-void abx500_pinctrl_ab8500_init(struct abx500_pinctrl_soc_data **soc);
-
-#else
-
-static inline void
-abx500_pinctrl_ab8500_init(struct abx500_pinctrl_soc_data **soc)
-{
-}
-
-#endif
-
-#ifdef CONFIG_PINCTRL_AB8540
-
-void abx500_pinctrl_ab8540_init(struct abx500_pinctrl_soc_data **soc);
-
-#else
-
-static inline void
-abx500_pinctrl_ab8540_init(struct abx500_pinctrl_soc_data **soc)
-{
-}
-
-#endif
-
-#ifdef CONFIG_PINCTRL_AB9540
-
-void abx500_pinctrl_ab9540_init(struct abx500_pinctrl_soc_data **soc);
-
-#else
-
-static inline void
-abx500_pinctrl_ab9540_init(struct abx500_pinctrl_soc_data **soc)
-{
-}
-
-#endif
-
-#ifdef CONFIG_PINCTRL_AB8505
-
-void abx500_pinctrl_ab8505_init(struct abx500_pinctrl_soc_data **soc);
-
-#else
-
-static inline void
-abx500_pinctrl_ab8505_init(struct abx500_pinctrl_soc_data **soc)
-{
-}
-
-#endif
-
-#endif /* PINCTRL_PINCTRL_ABx500_H */
index 5c44feb54ebb4771566dcce454bd7f81a9bc34fe..b092b93c67a1dcbbd1d364609fe47a7c22ee24d6 100644 (file)
@@ -401,7 +401,7 @@ static int adi_gpio_irq_type(struct irq_data *d, unsigned int type)
 
        if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING |
                    IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) {
-               snprintf(buf, 16, "gpio-irq%d", irq);
+               snprintf(buf, 16, "gpio-irq%u", irq);
                port_setup(port, d->hwirq, true);
        } else
                goto out;
@@ -652,35 +652,6 @@ static int adi_pinmux_enable(struct pinctrl_dev *pctldev, unsigned func_id,
        return 0;
 }
 
-static void adi_pinmux_disable(struct pinctrl_dev *pctldev, unsigned func_id,
-       unsigned group_id)
-{
-       struct adi_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctldev);
-       struct gpio_port *port;
-       struct pinctrl_gpio_range *range;
-       unsigned long flags;
-       unsigned short *mux, pin;
-
-       mux = (unsigned short *)pinctrl->soc->groups[group_id].mux;
-
-       while (*mux) {
-               pin = P_IDENT(*mux);
-
-               range = pinctrl_find_gpio_range_from_pin(pctldev, pin);
-               if (range == NULL) /* should not happen */
-                       return;
-
-               port = container_of(range->gc, struct gpio_port, chip);
-
-               spin_lock_irqsave(&port->lock, flags);
-
-               port_setup(port, pin_to_offset(range, pin), true);
-               mux++;
-
-               spin_unlock_irqrestore(&port->lock, flags);
-       }
-}
-
 static int adi_pinmux_get_funcs_count(struct pinctrl_dev *pctldev)
 {
        struct adi_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctldev);
@@ -728,7 +699,6 @@ static int adi_pinmux_request_gpio(struct pinctrl_dev *pctldev,
 
 static struct pinmux_ops adi_pinmux_ops = {
        .enable = adi_pinmux_enable,
-       .disable = adi_pinmux_disable,
        .get_functions_count = adi_pinmux_get_funcs_count,
        .get_function_name = adi_pinmux_get_func_name,
        .get_function_groups = adi_pinmux_get_groups,
@@ -979,7 +949,7 @@ static int adi_gpio_probe(struct platform_device *pdev)
        struct gpio_port *port;
        char pinctrl_devname[DEVNAME_SIZE];
        static int gpio;
-       int ret = 0, ret1;
+       int ret = 0;
 
        pdata = dev->platform_data;
        if (!pdata)
@@ -1057,7 +1027,7 @@ static int adi_gpio_probe(struct platform_device *pdev)
        return 0;
 
 out_remove_gpiochip:
-       ret1 = gpiochip_remove(&port->chip);
+       gpiochip_remove(&port->chip);
 out_remove_domain:
        if (port->pint)
                irq_domain_remove(port->domain);
@@ -1068,12 +1038,11 @@ out_remove_domain:
 static int adi_gpio_remove(struct platform_device *pdev)
 {
        struct gpio_port *port = platform_get_drvdata(pdev);
-       int ret;
        u8 offset;
 
        list_del(&port->node);
        gpiochip_remove_pin_ranges(&port->chip);
-       ret = gpiochip_remove(&port->chip);
+       gpiochip_remove(&port->chip);
        if (port->pint) {
                for (offset = 0; offset < port->width; offset++)
                        irq_dispose_mapping(irq_find_mapping(port->domain,
@@ -1081,7 +1050,7 @@ static int adi_gpio_remove(struct platform_device *pdev)
                irq_domain_remove(port->domain);
        }
 
-       return ret;
+       return 0;
 }
 
 static int adi_pinctrl_probe(struct platform_device *pdev)
diff --git a/drivers/pinctrl/pinctrl-apq8064.c b/drivers/pinctrl/pinctrl-apq8064.c
deleted file mode 100644 (file)
index 519f788..0000000
+++ /dev/null
@@ -1,613 +0,0 @@
-/*
- * Copyright (c) 2014, Sony Mobile Communications AB.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#include <linux/module.h>
-#include <linux/of.h>
-#include <linux/platform_device.h>
-#include <linux/pinctrl/pinctrl.h>
-
-#include "pinctrl-msm.h"
-
-static const struct pinctrl_pin_desc apq8064_pins[] = {
-       PINCTRL_PIN(0, "GPIO_0"),
-       PINCTRL_PIN(1, "GPIO_1"),
-       PINCTRL_PIN(2, "GPIO_2"),
-       PINCTRL_PIN(3, "GPIO_3"),
-       PINCTRL_PIN(4, "GPIO_4"),
-       PINCTRL_PIN(5, "GPIO_5"),
-       PINCTRL_PIN(6, "GPIO_6"),
-       PINCTRL_PIN(7, "GPIO_7"),
-       PINCTRL_PIN(8, "GPIO_8"),
-       PINCTRL_PIN(9, "GPIO_9"),
-       PINCTRL_PIN(10, "GPIO_10"),
-       PINCTRL_PIN(11, "GPIO_11"),
-       PINCTRL_PIN(12, "GPIO_12"),
-       PINCTRL_PIN(13, "GPIO_13"),
-       PINCTRL_PIN(14, "GPIO_14"),
-       PINCTRL_PIN(15, "GPIO_15"),
-       PINCTRL_PIN(16, "GPIO_16"),
-       PINCTRL_PIN(17, "GPIO_17"),
-       PINCTRL_PIN(18, "GPIO_18"),
-       PINCTRL_PIN(19, "GPIO_19"),
-       PINCTRL_PIN(20, "GPIO_20"),
-       PINCTRL_PIN(21, "GPIO_21"),
-       PINCTRL_PIN(22, "GPIO_22"),
-       PINCTRL_PIN(23, "GPIO_23"),
-       PINCTRL_PIN(24, "GPIO_24"),
-       PINCTRL_PIN(25, "GPIO_25"),
-       PINCTRL_PIN(26, "GPIO_26"),
-       PINCTRL_PIN(27, "GPIO_27"),
-       PINCTRL_PIN(28, "GPIO_28"),
-       PINCTRL_PIN(29, "GPIO_29"),
-       PINCTRL_PIN(30, "GPIO_30"),
-       PINCTRL_PIN(31, "GPIO_31"),
-       PINCTRL_PIN(32, "GPIO_32"),
-       PINCTRL_PIN(33, "GPIO_33"),
-       PINCTRL_PIN(34, "GPIO_34"),
-       PINCTRL_PIN(35, "GPIO_35"),
-       PINCTRL_PIN(36, "GPIO_36"),
-       PINCTRL_PIN(37, "GPIO_37"),
-       PINCTRL_PIN(38, "GPIO_38"),
-       PINCTRL_PIN(39, "GPIO_39"),
-       PINCTRL_PIN(40, "GPIO_40"),
-       PINCTRL_PIN(41, "GPIO_41"),
-       PINCTRL_PIN(42, "GPIO_42"),
-       PINCTRL_PIN(43, "GPIO_43"),
-       PINCTRL_PIN(44, "GPIO_44"),
-       PINCTRL_PIN(45, "GPIO_45"),
-       PINCTRL_PIN(46, "GPIO_46"),
-       PINCTRL_PIN(47, "GPIO_47"),
-       PINCTRL_PIN(48, "GPIO_48"),
-       PINCTRL_PIN(49, "GPIO_49"),
-       PINCTRL_PIN(50, "GPIO_50"),
-       PINCTRL_PIN(51, "GPIO_51"),
-       PINCTRL_PIN(52, "GPIO_52"),
-       PINCTRL_PIN(53, "GPIO_53"),
-       PINCTRL_PIN(54, "GPIO_54"),
-       PINCTRL_PIN(55, "GPIO_55"),
-       PINCTRL_PIN(56, "GPIO_56"),
-       PINCTRL_PIN(57, "GPIO_57"),
-       PINCTRL_PIN(58, "GPIO_58"),
-       PINCTRL_PIN(59, "GPIO_59"),
-       PINCTRL_PIN(60, "GPIO_60"),
-       PINCTRL_PIN(61, "GPIO_61"),
-       PINCTRL_PIN(62, "GPIO_62"),
-       PINCTRL_PIN(63, "GPIO_63"),
-       PINCTRL_PIN(64, "GPIO_64"),
-       PINCTRL_PIN(65, "GPIO_65"),
-       PINCTRL_PIN(66, "GPIO_66"),
-       PINCTRL_PIN(67, "GPIO_67"),
-       PINCTRL_PIN(68, "GPIO_68"),
-       PINCTRL_PIN(69, "GPIO_69"),
-       PINCTRL_PIN(70, "GPIO_70"),
-       PINCTRL_PIN(71, "GPIO_71"),
-       PINCTRL_PIN(72, "GPIO_72"),
-       PINCTRL_PIN(73, "GPIO_73"),
-       PINCTRL_PIN(74, "GPIO_74"),
-       PINCTRL_PIN(75, "GPIO_75"),
-       PINCTRL_PIN(76, "GPIO_76"),
-       PINCTRL_PIN(77, "GPIO_77"),
-       PINCTRL_PIN(78, "GPIO_78"),
-       PINCTRL_PIN(79, "GPIO_79"),
-       PINCTRL_PIN(80, "GPIO_80"),
-       PINCTRL_PIN(81, "GPIO_81"),
-       PINCTRL_PIN(82, "GPIO_82"),
-       PINCTRL_PIN(83, "GPIO_83"),
-       PINCTRL_PIN(84, "GPIO_84"),
-       PINCTRL_PIN(85, "GPIO_85"),
-       PINCTRL_PIN(86, "GPIO_86"),
-       PINCTRL_PIN(87, "GPIO_87"),
-       PINCTRL_PIN(88, "GPIO_88"),
-       PINCTRL_PIN(89, "GPIO_89"),
-
-       PINCTRL_PIN(90, "SDC1_CLK"),
-       PINCTRL_PIN(91, "SDC1_CMD"),
-       PINCTRL_PIN(92, "SDC1_DATA"),
-       PINCTRL_PIN(93, "SDC3_CLK"),
-       PINCTRL_PIN(94, "SDC3_CMD"),
-       PINCTRL_PIN(95, "SDC3_DATA"),
-};
-
-#define DECLARE_APQ_GPIO_PINS(pin) static const unsigned int gpio##pin##_pins[] = { pin }
-DECLARE_APQ_GPIO_PINS(0);
-DECLARE_APQ_GPIO_PINS(1);
-DECLARE_APQ_GPIO_PINS(2);
-DECLARE_APQ_GPIO_PINS(3);
-DECLARE_APQ_GPIO_PINS(4);
-DECLARE_APQ_GPIO_PINS(5);
-DECLARE_APQ_GPIO_PINS(6);
-DECLARE_APQ_GPIO_PINS(7);
-DECLARE_APQ_GPIO_PINS(8);
-DECLARE_APQ_GPIO_PINS(9);
-DECLARE_APQ_GPIO_PINS(10);
-DECLARE_APQ_GPIO_PINS(11);
-DECLARE_APQ_GPIO_PINS(12);
-DECLARE_APQ_GPIO_PINS(13);
-DECLARE_APQ_GPIO_PINS(14);
-DECLARE_APQ_GPIO_PINS(15);
-DECLARE_APQ_GPIO_PINS(16);
-DECLARE_APQ_GPIO_PINS(17);
-DECLARE_APQ_GPIO_PINS(18);
-DECLARE_APQ_GPIO_PINS(19);
-DECLARE_APQ_GPIO_PINS(20);
-DECLARE_APQ_GPIO_PINS(21);
-DECLARE_APQ_GPIO_PINS(22);
-DECLARE_APQ_GPIO_PINS(23);
-DECLARE_APQ_GPIO_PINS(24);
-DECLARE_APQ_GPIO_PINS(25);
-DECLARE_APQ_GPIO_PINS(26);
-DECLARE_APQ_GPIO_PINS(27);
-DECLARE_APQ_GPIO_PINS(28);
-DECLARE_APQ_GPIO_PINS(29);
-DECLARE_APQ_GPIO_PINS(30);
-DECLARE_APQ_GPIO_PINS(31);
-DECLARE_APQ_GPIO_PINS(32);
-DECLARE_APQ_GPIO_PINS(33);
-DECLARE_APQ_GPIO_PINS(34);
-DECLARE_APQ_GPIO_PINS(35);
-DECLARE_APQ_GPIO_PINS(36);
-DECLARE_APQ_GPIO_PINS(37);
-DECLARE_APQ_GPIO_PINS(38);
-DECLARE_APQ_GPIO_PINS(39);
-DECLARE_APQ_GPIO_PINS(40);
-DECLARE_APQ_GPIO_PINS(41);
-DECLARE_APQ_GPIO_PINS(42);
-DECLARE_APQ_GPIO_PINS(43);
-DECLARE_APQ_GPIO_PINS(44);
-DECLARE_APQ_GPIO_PINS(45);
-DECLARE_APQ_GPIO_PINS(46);
-DECLARE_APQ_GPIO_PINS(47);
-DECLARE_APQ_GPIO_PINS(48);
-DECLARE_APQ_GPIO_PINS(49);
-DECLARE_APQ_GPIO_PINS(50);
-DECLARE_APQ_GPIO_PINS(51);
-DECLARE_APQ_GPIO_PINS(52);
-DECLARE_APQ_GPIO_PINS(53);
-DECLARE_APQ_GPIO_PINS(54);
-DECLARE_APQ_GPIO_PINS(55);
-DECLARE_APQ_GPIO_PINS(56);
-DECLARE_APQ_GPIO_PINS(57);
-DECLARE_APQ_GPIO_PINS(58);
-DECLARE_APQ_GPIO_PINS(59);
-DECLARE_APQ_GPIO_PINS(60);
-DECLARE_APQ_GPIO_PINS(61);
-DECLARE_APQ_GPIO_PINS(62);
-DECLARE_APQ_GPIO_PINS(63);
-DECLARE_APQ_GPIO_PINS(64);
-DECLARE_APQ_GPIO_PINS(65);
-DECLARE_APQ_GPIO_PINS(66);
-DECLARE_APQ_GPIO_PINS(67);
-DECLARE_APQ_GPIO_PINS(68);
-DECLARE_APQ_GPIO_PINS(69);
-DECLARE_APQ_GPIO_PINS(70);
-DECLARE_APQ_GPIO_PINS(71);
-DECLARE_APQ_GPIO_PINS(72);
-DECLARE_APQ_GPIO_PINS(73);
-DECLARE_APQ_GPIO_PINS(74);
-DECLARE_APQ_GPIO_PINS(75);
-DECLARE_APQ_GPIO_PINS(76);
-DECLARE_APQ_GPIO_PINS(77);
-DECLARE_APQ_GPIO_PINS(78);
-DECLARE_APQ_GPIO_PINS(79);
-DECLARE_APQ_GPIO_PINS(80);
-DECLARE_APQ_GPIO_PINS(81);
-DECLARE_APQ_GPIO_PINS(82);
-DECLARE_APQ_GPIO_PINS(83);
-DECLARE_APQ_GPIO_PINS(84);
-DECLARE_APQ_GPIO_PINS(85);
-DECLARE_APQ_GPIO_PINS(86);
-DECLARE_APQ_GPIO_PINS(87);
-DECLARE_APQ_GPIO_PINS(88);
-DECLARE_APQ_GPIO_PINS(89);
-
-static const unsigned int sdc1_clk_pins[] = { 90 };
-static const unsigned int sdc1_cmd_pins[] = { 91 };
-static const unsigned int sdc1_data_pins[] = { 92 };
-static const unsigned int sdc3_clk_pins[] = { 93 };
-static const unsigned int sdc3_cmd_pins[] = { 94 };
-static const unsigned int sdc3_data_pins[] = { 95 };
-
-#define FUNCTION(fname)                                        \
-       [APQ_MUX_##fname] = {                           \
-               .name = #fname,                         \
-               .groups = fname##_groups,               \
-               .ngroups = ARRAY_SIZE(fname##_groups),  \
-       }
-
-#define PINGROUP(id, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10) \
-       {                                               \
-               .name = "gpio" #id,                     \
-               .pins = gpio##id##_pins,                \
-               .npins = ARRAY_SIZE(gpio##id##_pins),   \
-               .funcs = (int[]){                       \
-                       APQ_MUX_NA, /* gpio mode */     \
-                       APQ_MUX_##f1,                   \
-                       APQ_MUX_##f2,                   \
-                       APQ_MUX_##f3,                   \
-                       APQ_MUX_##f4,                   \
-                       APQ_MUX_##f5,                   \
-                       APQ_MUX_##f6,                   \
-                       APQ_MUX_##f7,                   \
-                       APQ_MUX_##f8,                   \
-                       APQ_MUX_##f9,                   \
-                       APQ_MUX_##f10,                  \
-               },                                      \
-               .nfuncs = 11,                           \
-               .ctl_reg = 0x1000 + 0x10 * id,          \
-               .io_reg = 0x1004 + 0x10 * id,           \
-               .intr_cfg_reg = 0x1008 + 0x10 * id,     \
-               .intr_status_reg = 0x100c + 0x10 * id,  \
-               .intr_target_reg = 0x400 + 0x4 * id,    \
-               .mux_bit = 2,                           \
-               .pull_bit = 0,                          \
-               .drv_bit = 6,                           \
-               .oe_bit = 9,                            \
-               .in_bit = 0,                            \
-               .out_bit = 1,                           \
-               .intr_enable_bit = 0,                   \
-               .intr_status_bit = 0,                   \
-               .intr_ack_high = 1,                     \
-               .intr_target_bit = 0,                   \
-               .intr_raw_status_bit = 3,               \
-               .intr_polarity_bit = 1,                 \
-               .intr_detection_bit = 2,                \
-               .intr_detection_width = 1,              \
-       }
-
-#define SDC_PINGROUP(pg_name, ctl, pull, drv)          \
-       {                                               \
-               .name = #pg_name,                       \
-               .pins = pg_name##_pins,                 \
-               .npins = ARRAY_SIZE(pg_name##_pins),    \
-               .ctl_reg = ctl,                         \
-               .io_reg = 0,                            \
-               .intr_cfg_reg = 0,                      \
-               .intr_status_reg = 0,                   \
-               .intr_target_reg = 0,                   \
-               .mux_bit = -1,                          \
-               .pull_bit = pull,                       \
-               .drv_bit = drv,                         \
-               .oe_bit = -1,                           \
-               .in_bit = -1,                           \
-               .out_bit = -1,                          \
-               .intr_enable_bit = -1,                  \
-               .intr_status_bit = -1,                  \
-               .intr_target_bit = -1,                  \
-               .intr_raw_status_bit = -1,              \
-               .intr_polarity_bit = -1,                \
-               .intr_detection_bit = -1,               \
-               .intr_detection_width = -1,             \
-       }
-
-enum apq8064_functions {
-       APQ_MUX_cam_mclk,
-       APQ_MUX_codec_mic_i2s,
-       APQ_MUX_codec_spkr_i2s,
-       APQ_MUX_gsbi1,
-       APQ_MUX_gsbi2,
-       APQ_MUX_gsbi3,
-       APQ_MUX_gsbi4,
-       APQ_MUX_gsbi4_cam_i2c,
-       APQ_MUX_gsbi5,
-       APQ_MUX_gsbi5_spi_cs1,
-       APQ_MUX_gsbi5_spi_cs2,
-       APQ_MUX_gsbi5_spi_cs3,
-       APQ_MUX_gsbi6,
-       APQ_MUX_gsbi6_spi_cs1,
-       APQ_MUX_gsbi6_spi_cs2,
-       APQ_MUX_gsbi6_spi_cs3,
-       APQ_MUX_gsbi7,
-       APQ_MUX_gsbi7_spi_cs1,
-       APQ_MUX_gsbi7_spi_cs2,
-       APQ_MUX_gsbi7_spi_cs3,
-       APQ_MUX_gsbi_cam_i2c,
-       APQ_MUX_hdmi,
-       APQ_MUX_mi2s,
-       APQ_MUX_riva_bt,
-       APQ_MUX_riva_fm,
-       APQ_MUX_riva_wlan,
-       APQ_MUX_sdc2,
-       APQ_MUX_sdc4,
-       APQ_MUX_slimbus,
-       APQ_MUX_spkr_i2s,
-       APQ_MUX_tsif1,
-       APQ_MUX_tsif2,
-       APQ_MUX_usb2_hsic,
-       APQ_MUX_NA,
-};
-
-static const char * const cam_mclk_groups[] = {
-       "gpio4" "gpio5"
-};
-static const char * const codec_mic_i2s_groups[] = {
-       "gpio34", "gpio35", "gpio36", "gpio37", "gpio38"
-};
-static const char * const codec_spkr_i2s_groups[] = {
-       "gpio39", "gpio40", "gpio41", "gpio42"
-};
-static const char * const gsbi1_groups[] = {
-       "gpio18", "gpio19", "gpio20", "gpio21"
-};
-static const char * const gsbi2_groups[] = {
-       "gpio22", "gpio23", "gpio24", "gpio25"
-};
-static const char * const gsbi3_groups[] = {
-       "gpio6", "gpio7", "gpio8", "gpio9"
-};
-static const char * const gsbi4_groups[] = {
-       "gpio10", "gpio11", "gpio12", "gpio13"
-};
-static const char * const gsbi4_cam_i2c_groups[] = {
-       "gpio10", "gpio11", "gpio12", "gpio13"
-};
-static const char * const gsbi5_groups[] = {
-       "gpio51", "gpio52", "gpio53", "gpio54"
-};
-static const char * const gsbi5_spi_cs1_groups[] = {
-       "gpio47"
-};
-static const char * const gsbi5_spi_cs2_groups[] = {
-       "gpio31"
-};
-static const char * const gsbi5_spi_cs3_groups[] = {
-       "gpio32"
-};
-static const char * const gsbi6_groups[] = {
-       "gpio14", "gpio15", "gpio16", "gpio17"
-};
-static const char * const gsbi6_spi_cs1_groups[] = {
-       "gpio47"
-};
-static const char * const gsbi6_spi_cs2_groups[] = {
-       "gpio31"
-};
-static const char * const gsbi6_spi_cs3_groups[] = {
-       "gpio32"
-};
-static const char * const gsbi7_groups[] = {
-       "gpio82", "gpio83", "gpio84", "gpio85"
-};
-static const char * const gsbi7_spi_cs1_groups[] = {
-       "gpio47"
-};
-static const char * const gsbi7_spi_cs2_groups[] = {
-       "gpio31"
-};
-static const char * const gsbi7_spi_cs3_groups[] = {
-       "gpio32"
-};
-static const char * const gsbi_cam_i2c_groups[] = {
-       "gpio10", "gpio11", "gpio12", "gpio13"
-};
-static const char * const hdmi_groups[] = {
-       "gpio69", "gpio70", "gpio71", "gpio72"
-};
-static const char * const mi2s_groups[] = {
-       "gpio27", "gpio28", "gpio29", "gpio30", "gpio31", "gpio32", "gpio33"
-};
-static const char * const riva_bt_groups[] = {
-       "gpio16", "gpio17"
-};
-static const char * const riva_fm_groups[] = {
-       "gpio14", "gpio15"
-};
-static const char * const riva_wlan_groups[] = {
-       "gpio64", "gpio65", "gpio66", "gpio67", "gpio68"
-};
-static const char * const sdc2_groups[] = {
-       "gpio57", "gpio58", "gpio59", "gpio60", "gpio61", "gpio62"
-};
-static const char * const sdc4_groups[] = {
-       "gpio63", "gpio64", "gpio65", "gpio66", "gpio67", "gpio68"
-};
-static const char * const slimbus_groups[] = {
-       "gpio40", "gpio41"
-};
-static const char * const spkr_i2s_groups[] = {
-       "gpio47", "gpio48", "gpio49", "gpio50"
-};
-static const char * const tsif1_groups[] = {
-       "gpio55", "gpio56", "gpio57"
-};
-static const char * const tsif2_groups[] = {
-       "gpio58", "gpio59", "gpio60"
-};
-static const char * const usb2_hsic_groups[] = {
-       "gpio88", "gpio89"
-};
-
-static const struct msm_function apq8064_functions[] = {
-       FUNCTION(cam_mclk),
-       FUNCTION(codec_mic_i2s),
-       FUNCTION(codec_spkr_i2s),
-       FUNCTION(gsbi1),
-       FUNCTION(gsbi2),
-       FUNCTION(gsbi3),
-       FUNCTION(gsbi4),
-       FUNCTION(gsbi4_cam_i2c),
-       FUNCTION(gsbi5),
-       FUNCTION(gsbi5_spi_cs1),
-       FUNCTION(gsbi5_spi_cs2),
-       FUNCTION(gsbi5_spi_cs3),
-       FUNCTION(gsbi6),
-       FUNCTION(gsbi6_spi_cs1),
-       FUNCTION(gsbi6_spi_cs2),
-       FUNCTION(gsbi6_spi_cs3),
-       FUNCTION(gsbi7),
-       FUNCTION(gsbi7_spi_cs1),
-       FUNCTION(gsbi7_spi_cs2),
-       FUNCTION(gsbi7_spi_cs3),
-       FUNCTION(gsbi_cam_i2c),
-       FUNCTION(hdmi),
-       FUNCTION(mi2s),
-       FUNCTION(riva_bt),
-       FUNCTION(riva_fm),
-       FUNCTION(riva_wlan),
-       FUNCTION(sdc2),
-       FUNCTION(sdc4),
-       FUNCTION(slimbus),
-       FUNCTION(spkr_i2s),
-       FUNCTION(tsif1),
-       FUNCTION(tsif2),
-       FUNCTION(usb2_hsic),
-};
-
-static const struct msm_pingroup apq8064_groups[] = {
-       PINGROUP(0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(2, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(3, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(4, NA, NA, cam_mclk, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(5, NA, cam_mclk, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(6, gsbi3, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(7, gsbi3, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(8, gsbi3, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(9, gsbi3, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(10, gsbi4, NA, NA, NA, NA, NA, NA, NA, gsbi4_cam_i2c, NA),
-       PINGROUP(11, gsbi4, NA, NA, NA, NA, NA, NA, NA, NA, gsbi4_cam_i2c),
-       PINGROUP(12, gsbi4, NA, NA, NA, NA, gsbi4_cam_i2c, NA, NA, NA, NA),
-       PINGROUP(13, gsbi4, NA, NA, NA, NA, gsbi4_cam_i2c, NA, NA, NA, NA),
-       PINGROUP(14, riva_fm, gsbi6, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(15, riva_fm, gsbi6, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(16, riva_bt, gsbi6, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(17, riva_bt, gsbi6, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(18, gsbi1, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(19, gsbi1, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(20, gsbi1, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(21, gsbi1, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(22, gsbi2, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(23, gsbi2, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(24, gsbi2, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(25, gsbi2, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(26, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(27, mi2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(28, mi2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(29, mi2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(30, mi2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(31, mi2s, NA, gsbi5_spi_cs2, gsbi6_spi_cs2, gsbi7_spi_cs2, NA, NA, NA, NA, NA),
-       PINGROUP(32, mi2s, NA, NA, NA, NA, gsbi5_spi_cs3, gsbi6_spi_cs3, gsbi7_spi_cs3, NA, NA),
-       PINGROUP(33, mi2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(34, codec_mic_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(35, codec_mic_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(36, codec_mic_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(37, codec_mic_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(38, codec_mic_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(39, codec_spkr_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(40, slimbus, codec_spkr_i2s, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(41, slimbus, codec_spkr_i2s, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(42, codec_spkr_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(43, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(44, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(45, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(46, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(47, spkr_i2s, gsbi5_spi_cs1, gsbi6_spi_cs1, gsbi7_spi_cs1, NA, NA, NA, NA, NA, NA),
-       PINGROUP(48, spkr_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(49, spkr_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(50, spkr_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(51, NA, gsbi5, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(52, NA, gsbi5, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(53, NA, gsbi5, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(54, NA, gsbi5, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(55, tsif1, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(56, tsif1, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(57, tsif1, sdc2, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(58, tsif2, sdc2, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(59, tsif2, sdc2, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(60, tsif2, sdc2, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(61, NA, sdc2, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(62, NA, sdc2, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(63, NA, sdc4, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(64, riva_wlan, sdc4, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(65, riva_wlan, sdc4, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(66, riva_wlan, sdc4, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(67, riva_wlan, sdc4, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(68, riva_wlan, sdc4, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(69, hdmi, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(70, hdmi, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(71, hdmi, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(72, hdmi, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(73, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(74, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(75, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(76, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(77, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(78, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(79, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(80, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(81, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(82, NA, gsbi7, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(83, gsbi7, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(84, NA, gsbi7, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(85, NA, NA, gsbi7, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(86, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(87, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(88, usb2_hsic, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(89, usb2_hsic, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-
-       SDC_PINGROUP(sdc1_clk, 0x20a0, 13, 6),
-       SDC_PINGROUP(sdc1_cmd, 0x20a0, 11, 3),
-       SDC_PINGROUP(sdc1_data, 0x20a0, 9, 0),
-
-       SDC_PINGROUP(sdc3_clk, 0x20a4, 14, 6),
-       SDC_PINGROUP(sdc3_cmd, 0x20a4, 11, 3),
-       SDC_PINGROUP(sdc3_data, 0x20a4, 9, 0),
-};
-
-#define NUM_GPIO_PINGROUPS 90
-
-static const struct msm_pinctrl_soc_data apq8064_pinctrl = {
-       .pins = apq8064_pins,
-       .npins = ARRAY_SIZE(apq8064_pins),
-       .functions = apq8064_functions,
-       .nfunctions = ARRAY_SIZE(apq8064_functions),
-       .groups = apq8064_groups,
-       .ngroups = ARRAY_SIZE(apq8064_groups),
-       .ngpios = NUM_GPIO_PINGROUPS,
-};
-
-static int apq8064_pinctrl_probe(struct platform_device *pdev)
-{
-       return msm_pinctrl_probe(pdev, &apq8064_pinctrl);
-}
-
-static const struct of_device_id apq8064_pinctrl_of_match[] = {
-       { .compatible = "qcom,apq8064-pinctrl", },
-       { },
-};
-
-static struct platform_driver apq8064_pinctrl_driver = {
-       .driver = {
-               .name = "apq8064-pinctrl",
-               .owner = THIS_MODULE,
-               .of_match_table = apq8064_pinctrl_of_match,
-       },
-       .probe = apq8064_pinctrl_probe,
-       .remove = msm_pinctrl_remove,
-};
-
-static int __init apq8064_pinctrl_init(void)
-{
-       return platform_driver_register(&apq8064_pinctrl_driver);
-}
-arch_initcall(apq8064_pinctrl_init);
-
-static void __exit apq8064_pinctrl_exit(void)
-{
-       platform_driver_unregister(&apq8064_pinctrl_driver);
-}
-module_exit(apq8064_pinctrl_exit);
-
-MODULE_AUTHOR("Bjorn Andersson <bjorn.andersson@sonymobile.com>");
-MODULE_DESCRIPTION("Qualcomm APQ8064 pinctrl driver");
-MODULE_LICENSE("GPL v2");
-MODULE_DEVICE_TABLE(of, apq8064_pinctrl_of_match);
index c862f9c0e9ce4cb356222b496c40ca1ac26b0699..0e4ec91f4d491693cd23e10186a59412f8a9edff 100644 (file)
@@ -565,7 +565,6 @@ static int as3722_pinctrl_probe(struct platform_device *pdev)
 {
        struct as3722_pctrl_info *as_pci;
        int ret;
-       int tret;
 
        as_pci = devm_kzalloc(&pdev->dev, sizeof(*as_pci), GFP_KERNEL);
        if (!as_pci)
@@ -611,10 +610,7 @@ static int as3722_pinctrl_probe(struct platform_device *pdev)
        return 0;
 
 fail_range_add:
-       tret = gpiochip_remove(&as_pci->gpio_chip);
-       if (tret < 0)
-               dev_warn(&pdev->dev, "Couldn't remove gpio chip, %d\n", tret);
-
+       gpiochip_remove(&as_pci->gpio_chip);
 fail_chip_add:
        pinctrl_unregister(as_pci->pctl);
        return ret;
@@ -623,11 +619,8 @@ fail_chip_add:
 static int as3722_pinctrl_remove(struct platform_device *pdev)
 {
        struct as3722_pctrl_info *as_pci = platform_get_drvdata(pdev);
-       int ret;
 
-       ret = gpiochip_remove(&as_pci->gpio_chip);
-       if (ret < 0)
-               return ret;
+       gpiochip_remove(&as_pci->gpio_chip);
        pinctrl_unregister(as_pci->pctl);
        return 0;
 }
index 421493cb490c52a9f434df0ffd041c91c31536b9..af1ba4fc150dd4e10509b8e53ccab89458d7d09a 100644 (file)
@@ -611,26 +611,6 @@ static int at91_pmx_enable(struct pinctrl_dev *pctldev, unsigned selector,
        return 0;
 }
 
-static void at91_pmx_disable(struct pinctrl_dev *pctldev, unsigned selector,
-                          unsigned group)
-{
-       struct at91_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
-       const struct at91_pmx_pin *pins_conf = info->groups[group].pins_conf;
-       const struct at91_pmx_pin *pin;
-       uint32_t npins = info->groups[group].npins;
-       int i;
-       unsigned mask;
-       void __iomem *pio;
-
-       for (i = 0; i < npins; i++) {
-               pin = &pins_conf[i];
-               at91_pin_dbg(info->dev, pin);
-               pio = pin_to_controller(info, pin->bank);
-               mask = pin_to_mask(pin->pin);
-               at91_mux_gpio_enable(pio, mask, 1);
-       }
-}
-
 static int at91_pmx_get_funcs_count(struct pinctrl_dev *pctldev)
 {
        struct at91_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
@@ -705,7 +685,6 @@ static const struct pinmux_ops at91_pmx_ops = {
        .get_function_name      = at91_pmx_get_func_name,
        .get_function_groups    = at91_pmx_get_groups,
        .enable                 = at91_pmx_enable,
-       .disable                = at91_pmx_disable,
        .gpio_request_enable    = at91_gpio_request_enable,
        .gpio_disable_free      = at91_gpio_disable_free,
 };
@@ -793,9 +772,9 @@ static void at91_pinconf_dbg_show(struct pinctrl_dev *pctldev,
                                   struct seq_file *s, unsigned pin_id)
 {
        unsigned long config;
-       int ret, val, num_conf = 0;
+       int val, num_conf = 0;
 
-       ret = at91_pinconf_get(pctldev, pin_id, &config);
+       at91_pinconf_get(pctldev, pin_id, &config);
 
        DBG_SHOW_FLAG(MULTI_DRIVE);
        DBG_SHOW_FLAG(PULL_UP);
@@ -945,7 +924,7 @@ static int at91_pinctrl_parse_functions(struct device_node *np,
        /* Initialise function */
        func->name = np->name;
        func->ngroups = of_get_child_count(np);
-       if (func->ngroups <= 0) {
+       if (func->ngroups == 0) {
                dev_err(info->dev, "no groups defined\n");
                return -EINVAL;
        }
index 975572e2f260442a4ecd7baf54728664ca81e0f0..9ca59a01874316585a190093b0265401e17975a3 100644 (file)
@@ -25,9 +25,7 @@
 #include <linux/types.h>
 #include <linux/bitops.h>
 #include <linux/interrupt.h>
-#include <linux/irq.h>
 #include <linux/gpio.h>
-#include <linux/irqdomain.h>
 #include <linux/acpi.h>
 #include <linux/platform_device.h>
 #include <linux/seq_file.h>
@@ -44,6 +42,7 @@
 
 /* BYT_CONF0_REG register bits */
 #define BYT_IODEN              BIT(31)
+#define BYT_DIRECT_IRQ_EN      BIT(27)
 #define BYT_TRIG_NEG           BIT(26)
 #define BYT_TRIG_POS           BIT(25)
 #define BYT_TRIG_LVL           BIT(24)
@@ -137,7 +136,6 @@ static struct pinctrl_gpio_range byt_ranges[] = {
 
 struct byt_gpio {
        struct gpio_chip                chip;
-       struct irq_domain               *domain;
        struct platform_device          *pdev;
        spinlock_t                      lock;
        void __iomem                    *reg_base;
@@ -217,7 +215,7 @@ static void byt_gpio_free(struct gpio_chip *chip, unsigned offset)
 
 static int byt_irq_type(struct irq_data *d, unsigned type)
 {
-       struct byt_gpio *vg = irq_data_get_irq_chip_data(d);
+       struct byt_gpio *vg = to_byt_gpio(irq_data_get_irq_chip_data(d));
        u32 offset = irqd_to_hwirq(d);
        u32 value;
        unsigned long flags;
@@ -303,12 +301,22 @@ static int byt_gpio_direction_output(struct gpio_chip *chip,
                                     unsigned gpio, int value)
 {
        struct byt_gpio *vg = to_byt_gpio(chip);
+       void __iomem *conf_reg = byt_gpio_reg(chip, gpio, BYT_CONF0_REG);
        void __iomem *reg = byt_gpio_reg(chip, gpio, BYT_VAL_REG);
        unsigned long flags;
        u32 reg_val;
 
        spin_lock_irqsave(&vg->lock, flags);
 
+       /*
+        * Before making any direction modifications, do a check if gpio
+        * is set for direct IRQ.  On baytrail, setting GPIO to output does
+        * not make sense, so let's at least warn the caller before they shoot
+        * themselves in the foot.
+        */
+       WARN(readl(conf_reg) & BYT_DIRECT_IRQ_EN,
+               "Potential Error: Setting GPIO with direct_irq_en to output");
+
        reg_val = readl(reg) | BYT_DIR_MASK;
        reg_val &= ~BYT_OUTPUT_EN;
 
@@ -393,16 +401,10 @@ static void byt_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
        spin_unlock_irqrestore(&vg->lock, flags);
 }
 
-static int byt_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
-{
-       struct byt_gpio *vg = to_byt_gpio(chip);
-       return irq_create_mapping(vg->domain, offset);
-}
-
 static void byt_gpio_irq_handler(unsigned irq, struct irq_desc *desc)
 {
        struct irq_data *data = irq_desc_get_irq_data(desc);
-       struct byt_gpio *vg = irq_data_get_irq_handler_data(data);
+       struct byt_gpio *vg = to_byt_gpio(irq_desc_get_handler_data(desc));
        struct irq_chip *chip = irq_data_get_irq_chip(data);
        u32 base, pin, mask;
        void __iomem *reg;
@@ -421,7 +423,7 @@ static void byt_gpio_irq_handler(unsigned irq, struct irq_desc *desc)
                        /* Clear before handling so we can't lose an edge */
                        writel(mask, reg);
 
-                       virq = irq_find_mapping(vg->domain, base + pin);
+                       virq = irq_find_mapping(vg->chip.irqdomain, base + pin);
                        generic_handle_irq(virq);
 
                        /* In case bios or user sets triggering incorretly a pin
@@ -454,33 +456,11 @@ static void byt_irq_mask(struct irq_data *d)
 {
 }
 
-static int byt_irq_reqres(struct irq_data *d)
-{
-       struct byt_gpio *vg = irq_data_get_irq_chip_data(d);
-
-       if (gpio_lock_as_irq(&vg->chip, irqd_to_hwirq(d))) {
-               dev_err(vg->chip.dev,
-                       "unable to lock HW IRQ %lu for IRQ\n",
-                       irqd_to_hwirq(d));
-               return -EINVAL;
-       }
-       return 0;
-}
-
-static void byt_irq_relres(struct irq_data *d)
-{
-       struct byt_gpio *vg = irq_data_get_irq_chip_data(d);
-
-       gpio_unlock_as_irq(&vg->chip, irqd_to_hwirq(d));
-}
-
 static struct irq_chip byt_irqchip = {
        .name = "BYT-GPIO",
        .irq_mask = byt_irq_mask,
        .irq_unmask = byt_irq_unmask,
        .irq_set_type = byt_irq_type,
-       .irq_request_resources = byt_irq_reqres,
-       .irq_release_resources = byt_irq_relres,
 };
 
 static void byt_gpio_irq_init_hw(struct byt_gpio *vg)
@@ -501,23 +481,6 @@ static void byt_gpio_irq_init_hw(struct byt_gpio *vg)
        }
 }
 
-static int byt_gpio_irq_map(struct irq_domain *d, unsigned int virq,
-                           irq_hw_number_t hw)
-{
-       struct byt_gpio *vg = d->host_data;
-
-       irq_set_chip_and_handler_name(virq, &byt_irqchip, handle_simple_irq,
-                                     "demux");
-       irq_set_chip_data(virq, vg);
-       irq_set_irq_type(virq, IRQ_TYPE_NONE);
-
-       return 0;
-}
-
-static const struct irq_domain_ops byt_gpio_irq_ops = {
-       .map = byt_gpio_irq_map,
-};
-
 static int byt_gpio_probe(struct platform_device *pdev)
 {
        struct byt_gpio *vg;
@@ -527,7 +490,6 @@ static int byt_gpio_probe(struct platform_device *pdev)
        struct acpi_device *acpi_dev;
        struct pinctrl_gpio_range *range;
        acpi_handle handle = ACPI_HANDLE(dev);
-       unsigned hwirq;
        int ret;
 
        if (acpi_bus_get_device(handle, &acpi_dev))
@@ -574,27 +536,27 @@ static int byt_gpio_probe(struct platform_device *pdev)
        gc->can_sleep = false;
        gc->dev = dev;
 
+       ret = gpiochip_add(gc);
+       if (ret) {
+               dev_err(&pdev->dev, "failed adding byt-gpio chip\n");
+               return ret;
+       }
+
        /* set up interrupts  */
        irq_rc = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
        if (irq_rc && irq_rc->start) {
-               hwirq = irq_rc->start;
-               gc->to_irq = byt_gpio_to_irq;
-
-               vg->domain = irq_domain_add_linear(NULL, gc->ngpio,
-                                                  &byt_gpio_irq_ops, vg);
-               if (!vg->domain)
-                       return -ENXIO;
-
                byt_gpio_irq_init_hw(vg);
+               ret = gpiochip_irqchip_add(gc, &byt_irqchip, 0,
+                                          handle_simple_irq, IRQ_TYPE_NONE);
+               if (ret) {
+                       dev_err(dev, "failed to add irqchip\n");
+                       gpiochip_remove(gc);
+                       return ret;
+               }
 
-               irq_set_handler_data(hwirq, vg);
-               irq_set_chained_handler(hwirq, byt_gpio_irq_handler);
-       }
-
-       ret = gpiochip_add(gc);
-       if (ret) {
-               dev_err(&pdev->dev, "failed adding byt-gpio chip\n");
-               return ret;
+               gpiochip_set_chained_irqchip(gc, &byt_irqchip,
+                                            (unsigned)irq_rc->start,
+                                            byt_gpio_irq_handler);
        }
 
        pm_runtime_enable(dev);
@@ -627,12 +589,9 @@ MODULE_DEVICE_TABLE(acpi, byt_gpio_acpi_match);
 static int byt_gpio_remove(struct platform_device *pdev)
 {
        struct byt_gpio *vg = platform_get_drvdata(pdev);
-       int err;
 
        pm_runtime_disable(&pdev->dev);
-       err = gpiochip_remove(&vg->chip);
-       if (err)
-               dev_warn(&pdev->dev, "failed to remove gpio_chip.\n");
+       gpiochip_remove(&vg->chip);
 
        return 0;
 }
index 3bed792b2c03b03da1ca0721548f19a04fb16619..c5ca9e633fffbb76aeb1dd176859bcacccd32725 100644 (file)
@@ -1396,7 +1396,7 @@ static struct pinctrl_desc bcm281xx_pinctrl_desc = {
        .owner = THIS_MODULE,
 };
 
-int __init bcm281xx_pinctrl_probe(struct platform_device *pdev)
+static int __init bcm281xx_pinctrl_probe(struct platform_device *pdev)
 {
        struct bcm281xx_pinctrl_data *pdata = &bcm281xx_pinctrl;
        struct resource *res;
index 3d907de9bc91501cc7a83ccd7cfab487bbcab265..5bcfd7ace0cd207eeddfa310663df8c5494ff6a2 100644 (file)
@@ -841,16 +841,6 @@ static int bcm2835_pmx_enable(struct pinctrl_dev *pctldev,
        return 0;
 }
 
-static void bcm2835_pmx_disable(struct pinctrl_dev *pctldev,
-               unsigned func_selector,
-               unsigned group_selector)
-{
-       struct bcm2835_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
-
-       /* disable by setting to GPIO_IN */
-       bcm2835_pinctrl_fsel_set(pc, group_selector, BCM2835_FSEL_GPIO_IN);
-}
-
 static void bcm2835_pmx_gpio_disable_free(struct pinctrl_dev *pctldev,
                struct pinctrl_gpio_range *range,
                unsigned offset)
@@ -880,7 +870,6 @@ static const struct pinmux_ops bcm2835_pmx_ops = {
        .get_function_name = bcm2835_pmx_get_function_name,
        .get_function_groups = bcm2835_pmx_get_function_groups,
        .enable = bcm2835_pmx_enable,
-       .disable = bcm2835_pmx_disable,
        .gpio_disable_free = bcm2835_pmx_gpio_disable_free,
        .gpio_set_direction = bcm2835_pmx_gpio_set_direction,
 };
index d182fdd2e7158c17003b4f3dd187aa65f7a59027..29cbbab8c3a673cecb6225e45c7bb8343700c2a6 100644 (file)
@@ -756,8 +756,7 @@ static int __init u300_gpio_probe(struct platform_device *pdev)
 
 err_no_range:
 err_no_irqchip:
-       if (gpiochip_remove(&gpio->chip))
-               dev_err(&pdev->dev, "failed to remove gpio chip\n");
+       gpiochip_remove(&gpio->chip);
 err_no_chip:
        clk_disable_unprepare(gpio->clk);
        dev_err(&pdev->dev, "module ERROR:%d\n", err);
@@ -767,16 +766,11 @@ err_no_chip:
 static int __exit u300_gpio_remove(struct platform_device *pdev)
 {
        struct u300_gpio *gpio = platform_get_drvdata(pdev);
-       int err;
 
        /* Turn off the GPIO block */
        writel(0x00000000U, gpio->base + U300_GPIO_CR);
 
-       err = gpiochip_remove(&gpio->chip);
-       if (err < 0) {
-               dev_err(gpio->dev, "unable to remove gpiochip: %d\n", err);
-               return err;
-       }
+       gpiochip_remove(&gpio->chip);
        clk_disable_unprepare(gpio->clk);
        return 0;
 }
diff --git a/drivers/pinctrl/pinctrl-exynos.c b/drivers/pinctrl/pinctrl-exynos.c
deleted file mode 100644 (file)
index 9609c23..0000000
+++ /dev/null
@@ -1,1310 +0,0 @@
-/*
- * Exynos specific support for Samsung pinctrl/gpiolib driver with eint support.
- *
- * Copyright (c) 2012 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- * Copyright (c) 2012 Linaro Ltd
- *             http://www.linaro.org
- *
- * Author: Thomas Abraham <thomas.ab@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This file contains the Samsung Exynos specific information required by the
- * the Samsung pinctrl/gpiolib driver. It also includes the implementation of
- * external gpio and wakeup interrupt support.
- */
-
-#include <linux/module.h>
-#include <linux/device.h>
-#include <linux/interrupt.h>
-#include <linux/irqdomain.h>
-#include <linux/irq.h>
-#include <linux/irqchip/chained_irq.h>
-#include <linux/of_irq.h>
-#include <linux/io.h>
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/err.h>
-
-#include "pinctrl-samsung.h"
-#include "pinctrl-exynos.h"
-
-
-static struct samsung_pin_bank_type bank_type_off = {
-       .fld_width = { 4, 1, 2, 2, 2, 2, },
-       .reg_offset = { 0x00, 0x04, 0x08, 0x0c, 0x10, 0x14, },
-};
-
-static struct samsung_pin_bank_type bank_type_alive = {
-       .fld_width = { 4, 1, 2, 2, },
-       .reg_offset = { 0x00, 0x04, 0x08, 0x0c, },
-};
-
-/* list of external wakeup controllers supported */
-static const struct of_device_id exynos_wkup_irq_ids[] = {
-       { .compatible = "samsung,exynos4210-wakeup-eint", },
-       { }
-};
-
-static void exynos_gpio_irq_mask(struct irq_data *irqd)
-{
-       struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
-       struct samsung_pinctrl_drv_data *d = bank->drvdata;
-       unsigned long reg_mask = d->ctrl->geint_mask + bank->eint_offset;
-       unsigned long mask;
-       unsigned long flags;
-
-       spin_lock_irqsave(&bank->slock, flags);
-
-       mask = readl(d->virt_base + reg_mask);
-       mask |= 1 << irqd->hwirq;
-       writel(mask, d->virt_base + reg_mask);
-
-       spin_unlock_irqrestore(&bank->slock, flags);
-}
-
-static void exynos_gpio_irq_ack(struct irq_data *irqd)
-{
-       struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
-       struct samsung_pinctrl_drv_data *d = bank->drvdata;
-       unsigned long reg_pend = d->ctrl->geint_pend + bank->eint_offset;
-
-       writel(1 << irqd->hwirq, d->virt_base + reg_pend);
-}
-
-static void exynos_gpio_irq_unmask(struct irq_data *irqd)
-{
-       struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
-       struct samsung_pinctrl_drv_data *d = bank->drvdata;
-       unsigned long reg_mask = d->ctrl->geint_mask + bank->eint_offset;
-       unsigned long mask;
-       unsigned long flags;
-
-       /*
-        * Ack level interrupts right before unmask
-        *
-        * If we don't do this we'll get a double-interrupt.  Level triggered
-        * interrupts must not fire an interrupt if the level is not
-        * _currently_ active, even if it was active while the interrupt was
-        * masked.
-        */
-       if (irqd_get_trigger_type(irqd) & IRQ_TYPE_LEVEL_MASK)
-               exynos_gpio_irq_ack(irqd);
-
-       spin_lock_irqsave(&bank->slock, flags);
-
-       mask = readl(d->virt_base + reg_mask);
-       mask &= ~(1 << irqd->hwirq);
-       writel(mask, d->virt_base + reg_mask);
-
-       spin_unlock_irqrestore(&bank->slock, flags);
-}
-
-static int exynos_gpio_irq_set_type(struct irq_data *irqd, unsigned int type)
-{
-       struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
-       struct samsung_pin_bank_type *bank_type = bank->type;
-       struct samsung_pinctrl_drv_data *d = bank->drvdata;
-       struct samsung_pin_ctrl *ctrl = d->ctrl;
-       unsigned int pin = irqd->hwirq;
-       unsigned int shift = EXYNOS_EINT_CON_LEN * pin;
-       unsigned int con, trig_type;
-       unsigned long reg_con = ctrl->geint_con + bank->eint_offset;
-       unsigned long flags;
-       unsigned int mask;
-
-       switch (type) {
-       case IRQ_TYPE_EDGE_RISING:
-               trig_type = EXYNOS_EINT_EDGE_RISING;
-               break;
-       case IRQ_TYPE_EDGE_FALLING:
-               trig_type = EXYNOS_EINT_EDGE_FALLING;
-               break;
-       case IRQ_TYPE_EDGE_BOTH:
-               trig_type = EXYNOS_EINT_EDGE_BOTH;
-               break;
-       case IRQ_TYPE_LEVEL_HIGH:
-               trig_type = EXYNOS_EINT_LEVEL_HIGH;
-               break;
-       case IRQ_TYPE_LEVEL_LOW:
-               trig_type = EXYNOS_EINT_LEVEL_LOW;
-               break;
-       default:
-               pr_err("unsupported external interrupt type\n");
-               return -EINVAL;
-       }
-
-       if (type & IRQ_TYPE_EDGE_BOTH)
-               __irq_set_handler_locked(irqd->irq, handle_edge_irq);
-       else
-               __irq_set_handler_locked(irqd->irq, handle_level_irq);
-
-       con = readl(d->virt_base + reg_con);
-       con &= ~(EXYNOS_EINT_CON_MASK << shift);
-       con |= trig_type << shift;
-       writel(con, d->virt_base + reg_con);
-
-       reg_con = bank->pctl_offset + bank_type->reg_offset[PINCFG_TYPE_FUNC];
-       shift = pin * bank_type->fld_width[PINCFG_TYPE_FUNC];
-       mask = (1 << bank_type->fld_width[PINCFG_TYPE_FUNC]) - 1;
-
-       spin_lock_irqsave(&bank->slock, flags);
-
-       con = readl(d->virt_base + reg_con);
-       con &= ~(mask << shift);
-       con |= EXYNOS_EINT_FUNC << shift;
-       writel(con, d->virt_base + reg_con);
-
-       spin_unlock_irqrestore(&bank->slock, flags);
-
-       return 0;
-}
-
-/*
- * irq_chip for gpio interrupts.
- */
-static struct irq_chip exynos_gpio_irq_chip = {
-       .name           = "exynos_gpio_irq_chip",
-       .irq_unmask     = exynos_gpio_irq_unmask,
-       .irq_mask       = exynos_gpio_irq_mask,
-       .irq_ack                = exynos_gpio_irq_ack,
-       .irq_set_type   = exynos_gpio_irq_set_type,
-};
-
-static int exynos_gpio_irq_map(struct irq_domain *h, unsigned int virq,
-                                       irq_hw_number_t hw)
-{
-       struct samsung_pin_bank *b = h->host_data;
-
-       irq_set_chip_data(virq, b);
-       irq_set_chip_and_handler(virq, &exynos_gpio_irq_chip,
-                                       handle_level_irq);
-       set_irq_flags(virq, IRQF_VALID);
-       return 0;
-}
-
-/*
- * irq domain callbacks for external gpio interrupt controller.
- */
-static const struct irq_domain_ops exynos_gpio_irqd_ops = {
-       .map    = exynos_gpio_irq_map,
-       .xlate  = irq_domain_xlate_twocell,
-};
-
-static irqreturn_t exynos_eint_gpio_irq(int irq, void *data)
-{
-       struct samsung_pinctrl_drv_data *d = data;
-       struct samsung_pin_ctrl *ctrl = d->ctrl;
-       struct samsung_pin_bank *bank = ctrl->pin_banks;
-       unsigned int svc, group, pin, virq;
-
-       svc = readl(d->virt_base + ctrl->svc);
-       group = EXYNOS_SVC_GROUP(svc);
-       pin = svc & EXYNOS_SVC_NUM_MASK;
-
-       if (!group)
-               return IRQ_HANDLED;
-       bank += (group - 1);
-
-       virq = irq_linear_revmap(bank->irq_domain, pin);
-       if (!virq)
-               return IRQ_NONE;
-       generic_handle_irq(virq);
-       return IRQ_HANDLED;
-}
-
-struct exynos_eint_gpio_save {
-       u32 eint_con;
-       u32 eint_fltcon0;
-       u32 eint_fltcon1;
-};
-
-/*
- * exynos_eint_gpio_init() - setup handling of external gpio interrupts.
- * @d: driver data of samsung pinctrl driver.
- */
-static int exynos_eint_gpio_init(struct samsung_pinctrl_drv_data *d)
-{
-       struct samsung_pin_bank *bank;
-       struct device *dev = d->dev;
-       int ret;
-       int i;
-
-       if (!d->irq) {
-               dev_err(dev, "irq number not available\n");
-               return -EINVAL;
-       }
-
-       ret = devm_request_irq(dev, d->irq, exynos_eint_gpio_irq,
-                                       0, dev_name(dev), d);
-       if (ret) {
-               dev_err(dev, "irq request failed\n");
-               return -ENXIO;
-       }
-
-       bank = d->ctrl->pin_banks;
-       for (i = 0; i < d->ctrl->nr_banks; ++i, ++bank) {
-               if (bank->eint_type != EINT_TYPE_GPIO)
-                       continue;
-               bank->irq_domain = irq_domain_add_linear(bank->of_node,
-                               bank->nr_pins, &exynos_gpio_irqd_ops, bank);
-               if (!bank->irq_domain) {
-                       dev_err(dev, "gpio irq domain add failed\n");
-                       ret = -ENXIO;
-                       goto err_domains;
-               }
-
-               bank->soc_priv = devm_kzalloc(d->dev,
-                       sizeof(struct exynos_eint_gpio_save), GFP_KERNEL);
-               if (!bank->soc_priv) {
-                       irq_domain_remove(bank->irq_domain);
-                       ret = -ENOMEM;
-                       goto err_domains;
-               }
-       }
-
-       return 0;
-
-err_domains:
-       for (--i, --bank; i >= 0; --i, --bank) {
-               if (bank->eint_type != EINT_TYPE_GPIO)
-                       continue;
-               irq_domain_remove(bank->irq_domain);
-       }
-
-       return ret;
-}
-
-static void exynos_wkup_irq_mask(struct irq_data *irqd)
-{
-       struct samsung_pin_bank *b = irq_data_get_irq_chip_data(irqd);
-       struct samsung_pinctrl_drv_data *d = b->drvdata;
-       unsigned long reg_mask = d->ctrl->weint_mask + b->eint_offset;
-       unsigned long mask;
-       unsigned long flags;
-
-       spin_lock_irqsave(&b->slock, flags);
-
-       mask = readl(d->virt_base + reg_mask);
-       mask |= 1 << irqd->hwirq;
-       writel(mask, d->virt_base + reg_mask);
-
-       spin_unlock_irqrestore(&b->slock, flags);
-}
-
-static void exynos_wkup_irq_ack(struct irq_data *irqd)
-{
-       struct samsung_pin_bank *b = irq_data_get_irq_chip_data(irqd);
-       struct samsung_pinctrl_drv_data *d = b->drvdata;
-       unsigned long pend = d->ctrl->weint_pend + b->eint_offset;
-
-       writel(1 << irqd->hwirq, d->virt_base + pend);
-}
-
-static void exynos_wkup_irq_unmask(struct irq_data *irqd)
-{
-       struct samsung_pin_bank *b = irq_data_get_irq_chip_data(irqd);
-       struct samsung_pinctrl_drv_data *d = b->drvdata;
-       unsigned long reg_mask = d->ctrl->weint_mask + b->eint_offset;
-       unsigned long mask;
-       unsigned long flags;
-
-       /*
-        * Ack level interrupts right before unmask
-        *
-        * If we don't do this we'll get a double-interrupt.  Level triggered
-        * interrupts must not fire an interrupt if the level is not
-        * _currently_ active, even if it was active while the interrupt was
-        * masked.
-        */
-       if (irqd_get_trigger_type(irqd) & IRQ_TYPE_LEVEL_MASK)
-               exynos_wkup_irq_ack(irqd);
-
-       spin_lock_irqsave(&b->slock, flags);
-
-       mask = readl(d->virt_base + reg_mask);
-       mask &= ~(1 << irqd->hwirq);
-       writel(mask, d->virt_base + reg_mask);
-
-       spin_unlock_irqrestore(&b->slock, flags);
-}
-
-static int exynos_wkup_irq_set_type(struct irq_data *irqd, unsigned int type)
-{
-       struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
-       struct samsung_pin_bank_type *bank_type = bank->type;
-       struct samsung_pinctrl_drv_data *d = bank->drvdata;
-       unsigned int pin = irqd->hwirq;
-       unsigned long reg_con = d->ctrl->weint_con + bank->eint_offset;
-       unsigned long shift = EXYNOS_EINT_CON_LEN * pin;
-       unsigned long con, trig_type;
-       unsigned long flags;
-       unsigned int mask;
-
-       switch (type) {
-       case IRQ_TYPE_EDGE_RISING:
-               trig_type = EXYNOS_EINT_EDGE_RISING;
-               break;
-       case IRQ_TYPE_EDGE_FALLING:
-               trig_type = EXYNOS_EINT_EDGE_FALLING;
-               break;
-       case IRQ_TYPE_EDGE_BOTH:
-               trig_type = EXYNOS_EINT_EDGE_BOTH;
-               break;
-       case IRQ_TYPE_LEVEL_HIGH:
-               trig_type = EXYNOS_EINT_LEVEL_HIGH;
-               break;
-       case IRQ_TYPE_LEVEL_LOW:
-               trig_type = EXYNOS_EINT_LEVEL_LOW;
-               break;
-       default:
-               pr_err("unsupported external interrupt type\n");
-               return -EINVAL;
-       }
-
-       if (type & IRQ_TYPE_EDGE_BOTH)
-               __irq_set_handler_locked(irqd->irq, handle_edge_irq);
-       else
-               __irq_set_handler_locked(irqd->irq, handle_level_irq);
-
-       con = readl(d->virt_base + reg_con);
-       con &= ~(EXYNOS_EINT_CON_MASK << shift);
-       con |= trig_type << shift;
-       writel(con, d->virt_base + reg_con);
-
-       reg_con = bank->pctl_offset + bank_type->reg_offset[PINCFG_TYPE_FUNC];
-       shift = pin * bank_type->fld_width[PINCFG_TYPE_FUNC];
-       mask = (1 << bank_type->fld_width[PINCFG_TYPE_FUNC]) - 1;
-
-       spin_lock_irqsave(&bank->slock, flags);
-
-       con = readl(d->virt_base + reg_con);
-       con &= ~(mask << shift);
-       con |= EXYNOS_EINT_FUNC << shift;
-       writel(con, d->virt_base + reg_con);
-
-       spin_unlock_irqrestore(&bank->slock, flags);
-
-       return 0;
-}
-
-static u32 exynos_eint_wake_mask = 0xffffffff;
-
-u32 exynos_get_eint_wake_mask(void)
-{
-       return exynos_eint_wake_mask;
-}
-
-static int exynos_wkup_irq_set_wake(struct irq_data *irqd, unsigned int on)
-{
-       struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
-       unsigned long bit = 1UL << (2 * bank->eint_offset + irqd->hwirq);
-
-       pr_info("wake %s for irq %d\n", on ? "enabled" : "disabled", irqd->irq);
-
-       if (!on)
-               exynos_eint_wake_mask |= bit;
-       else
-               exynos_eint_wake_mask &= ~bit;
-
-       return 0;
-}
-
-/*
- * irq_chip for wakeup interrupts
- */
-static struct irq_chip exynos_wkup_irq_chip = {
-       .name   = "exynos_wkup_irq_chip",
-       .irq_unmask     = exynos_wkup_irq_unmask,
-       .irq_mask       = exynos_wkup_irq_mask,
-       .irq_ack        = exynos_wkup_irq_ack,
-       .irq_set_type   = exynos_wkup_irq_set_type,
-       .irq_set_wake   = exynos_wkup_irq_set_wake,
-};
-
-/* interrupt handler for wakeup interrupts 0..15 */
-static void exynos_irq_eint0_15(unsigned int irq, struct irq_desc *desc)
-{
-       struct exynos_weint_data *eintd = irq_get_handler_data(irq);
-       struct samsung_pin_bank *bank = eintd->bank;
-       struct irq_chip *chip = irq_get_chip(irq);
-       int eint_irq;
-
-       chained_irq_enter(chip, desc);
-       chip->irq_mask(&desc->irq_data);
-
-       if (chip->irq_ack)
-               chip->irq_ack(&desc->irq_data);
-
-       eint_irq = irq_linear_revmap(bank->irq_domain, eintd->irq);
-       generic_handle_irq(eint_irq);
-       chip->irq_unmask(&desc->irq_data);
-       chained_irq_exit(chip, desc);
-}
-
-static inline void exynos_irq_demux_eint(unsigned long pend,
-                                               struct irq_domain *domain)
-{
-       unsigned int irq;
-
-       while (pend) {
-               irq = fls(pend) - 1;
-               generic_handle_irq(irq_find_mapping(domain, irq));
-               pend &= ~(1 << irq);
-       }
-}
-
-/* interrupt handler for wakeup interrupt 16 */
-static void exynos_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc)
-{
-       struct irq_chip *chip = irq_get_chip(irq);
-       struct exynos_muxed_weint_data *eintd = irq_get_handler_data(irq);
-       struct samsung_pinctrl_drv_data *d = eintd->banks[0]->drvdata;
-       struct samsung_pin_ctrl *ctrl = d->ctrl;
-       unsigned long pend;
-       unsigned long mask;
-       int i;
-
-       chained_irq_enter(chip, desc);
-
-       for (i = 0; i < eintd->nr_banks; ++i) {
-               struct samsung_pin_bank *b = eintd->banks[i];
-               pend = readl(d->virt_base + ctrl->weint_pend + b->eint_offset);
-               mask = readl(d->virt_base + ctrl->weint_mask + b->eint_offset);
-               exynos_irq_demux_eint(pend & ~mask, b->irq_domain);
-       }
-
-       chained_irq_exit(chip, desc);
-}
-
-static int exynos_wkup_irq_map(struct irq_domain *h, unsigned int virq,
-                                       irq_hw_number_t hw)
-{
-       irq_set_chip_and_handler(virq, &exynos_wkup_irq_chip, handle_level_irq);
-       irq_set_chip_data(virq, h->host_data);
-       set_irq_flags(virq, IRQF_VALID);
-       return 0;
-}
-
-/*
- * irq domain callbacks for external wakeup interrupt controller.
- */
-static const struct irq_domain_ops exynos_wkup_irqd_ops = {
-       .map    = exynos_wkup_irq_map,
-       .xlate  = irq_domain_xlate_twocell,
-};
-
-/*
- * exynos_eint_wkup_init() - setup handling of external wakeup interrupts.
- * @d: driver data of samsung pinctrl driver.
- */
-static int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d)
-{
-       struct device *dev = d->dev;
-       struct device_node *wkup_np = NULL;
-       struct device_node *np;
-       struct samsung_pin_bank *bank;
-       struct exynos_weint_data *weint_data;
-       struct exynos_muxed_weint_data *muxed_data;
-       unsigned int muxed_banks = 0;
-       unsigned int i;
-       int idx, irq;
-
-       for_each_child_of_node(dev->of_node, np) {
-               if (of_match_node(exynos_wkup_irq_ids, np)) {
-                       wkup_np = np;
-                       break;
-               }
-       }
-       if (!wkup_np)
-               return -ENODEV;
-
-       bank = d->ctrl->pin_banks;
-       for (i = 0; i < d->ctrl->nr_banks; ++i, ++bank) {
-               if (bank->eint_type != EINT_TYPE_WKUP)
-                       continue;
-
-               bank->irq_domain = irq_domain_add_linear(bank->of_node,
-                               bank->nr_pins, &exynos_wkup_irqd_ops, bank);
-               if (!bank->irq_domain) {
-                       dev_err(dev, "wkup irq domain add failed\n");
-                       return -ENXIO;
-               }
-
-               if (!of_find_property(bank->of_node, "interrupts", NULL)) {
-                       bank->eint_type = EINT_TYPE_WKUP_MUX;
-                       ++muxed_banks;
-                       continue;
-               }
-
-               weint_data = devm_kzalloc(dev, bank->nr_pins
-                                       * sizeof(*weint_data), GFP_KERNEL);
-               if (!weint_data) {
-                       dev_err(dev, "could not allocate memory for weint_data\n");
-                       return -ENOMEM;
-               }
-
-               for (idx = 0; idx < bank->nr_pins; ++idx) {
-                       irq = irq_of_parse_and_map(bank->of_node, idx);
-                       if (!irq) {
-                               dev_err(dev, "irq number for eint-%s-%d not found\n",
-                                                       bank->name, idx);
-                               continue;
-                       }
-                       weint_data[idx].irq = idx;
-                       weint_data[idx].bank = bank;
-                       irq_set_handler_data(irq, &weint_data[idx]);
-                       irq_set_chained_handler(irq, exynos_irq_eint0_15);
-               }
-       }
-
-       if (!muxed_banks)
-               return 0;
-
-       irq = irq_of_parse_and_map(wkup_np, 0);
-       if (!irq) {
-               dev_err(dev, "irq number for muxed EINTs not found\n");
-               return 0;
-       }
-
-       muxed_data = devm_kzalloc(dev, sizeof(*muxed_data)
-               + muxed_banks*sizeof(struct samsung_pin_bank *), GFP_KERNEL);
-       if (!muxed_data) {
-               dev_err(dev, "could not allocate memory for muxed_data\n");
-               return -ENOMEM;
-       }
-
-       irq_set_chained_handler(irq, exynos_irq_demux_eint16_31);
-       irq_set_handler_data(irq, muxed_data);
-
-       bank = d->ctrl->pin_banks;
-       idx = 0;
-       for (i = 0; i < d->ctrl->nr_banks; ++i, ++bank) {
-               if (bank->eint_type != EINT_TYPE_WKUP_MUX)
-                       continue;
-
-               muxed_data->banks[idx++] = bank;
-       }
-       muxed_data->nr_banks = muxed_banks;
-
-       return 0;
-}
-
-static void exynos_pinctrl_suspend_bank(
-                               struct samsung_pinctrl_drv_data *drvdata,
-                               struct samsung_pin_bank *bank)
-{
-       struct exynos_eint_gpio_save *save = bank->soc_priv;
-       void __iomem *regs = drvdata->virt_base;
-
-       save->eint_con = readl(regs + EXYNOS_GPIO_ECON_OFFSET
-                                               + bank->eint_offset);
-       save->eint_fltcon0 = readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET
-                                               + 2 * bank->eint_offset);
-       save->eint_fltcon1 = readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET
-                                               + 2 * bank->eint_offset + 4);
-
-       pr_debug("%s: save     con %#010x\n", bank->name, save->eint_con);
-       pr_debug("%s: save fltcon0 %#010x\n", bank->name, save->eint_fltcon0);
-       pr_debug("%s: save fltcon1 %#010x\n", bank->name, save->eint_fltcon1);
-}
-
-static void exynos_pinctrl_suspend(struct samsung_pinctrl_drv_data *drvdata)
-{
-       struct samsung_pin_ctrl *ctrl = drvdata->ctrl;
-       struct samsung_pin_bank *bank = ctrl->pin_banks;
-       int i;
-
-       for (i = 0; i < ctrl->nr_banks; ++i, ++bank)
-               if (bank->eint_type == EINT_TYPE_GPIO)
-                       exynos_pinctrl_suspend_bank(drvdata, bank);
-}
-
-static void exynos_pinctrl_resume_bank(
-                               struct samsung_pinctrl_drv_data *drvdata,
-                               struct samsung_pin_bank *bank)
-{
-       struct exynos_eint_gpio_save *save = bank->soc_priv;
-       void __iomem *regs = drvdata->virt_base;
-
-       pr_debug("%s:     con %#010x => %#010x\n", bank->name,
-                       readl(regs + EXYNOS_GPIO_ECON_OFFSET
-                       + bank->eint_offset), save->eint_con);
-       pr_debug("%s: fltcon0 %#010x => %#010x\n", bank->name,
-                       readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET
-                       + 2 * bank->eint_offset), save->eint_fltcon0);
-       pr_debug("%s: fltcon1 %#010x => %#010x\n", bank->name,
-                       readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET
-                       + 2 * bank->eint_offset + 4), save->eint_fltcon1);
-
-       writel(save->eint_con, regs + EXYNOS_GPIO_ECON_OFFSET
-                                               + bank->eint_offset);
-       writel(save->eint_fltcon0, regs + EXYNOS_GPIO_EFLTCON_OFFSET
-                                               + 2 * bank->eint_offset);
-       writel(save->eint_fltcon1, regs + EXYNOS_GPIO_EFLTCON_OFFSET
-                                               + 2 * bank->eint_offset + 4);
-}
-
-static void exynos_pinctrl_resume(struct samsung_pinctrl_drv_data *drvdata)
-{
-       struct samsung_pin_ctrl *ctrl = drvdata->ctrl;
-       struct samsung_pin_bank *bank = ctrl->pin_banks;
-       int i;
-
-       for (i = 0; i < ctrl->nr_banks; ++i, ++bank)
-               if (bank->eint_type == EINT_TYPE_GPIO)
-                       exynos_pinctrl_resume_bank(drvdata, bank);
-}
-
-/* pin banks of s5pv210 pin-controller */
-static struct samsung_pin_bank s5pv210_pin_bank[] = {
-       EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00),
-       EXYNOS_PIN_BANK_EINTG(4, 0x020, "gpa1", 0x04),
-       EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpb", 0x08),
-       EXYNOS_PIN_BANK_EINTG(5, 0x060, "gpc0", 0x0c),
-       EXYNOS_PIN_BANK_EINTG(5, 0x080, "gpc1", 0x10),
-       EXYNOS_PIN_BANK_EINTG(4, 0x0a0, "gpd0", 0x14),
-       EXYNOS_PIN_BANK_EINTG(6, 0x0c0, "gpd1", 0x18),
-       EXYNOS_PIN_BANK_EINTG(8, 0x0e0, "gpe0", 0x1c),
-       EXYNOS_PIN_BANK_EINTG(5, 0x100, "gpe1", 0x20),
-       EXYNOS_PIN_BANK_EINTG(8, 0x120, "gpf0", 0x24),
-       EXYNOS_PIN_BANK_EINTG(8, 0x140, "gpf1", 0x28),
-       EXYNOS_PIN_BANK_EINTG(8, 0x160, "gpf2", 0x2c),
-       EXYNOS_PIN_BANK_EINTG(6, 0x180, "gpf3", 0x30),
-       EXYNOS_PIN_BANK_EINTG(7, 0x1a0, "gpg0", 0x34),
-       EXYNOS_PIN_BANK_EINTG(7, 0x1c0, "gpg1", 0x38),
-       EXYNOS_PIN_BANK_EINTG(7, 0x1e0, "gpg2", 0x3c),
-       EXYNOS_PIN_BANK_EINTG(7, 0x200, "gpg3", 0x40),
-       EXYNOS_PIN_BANK_EINTN(7, 0x220, "gpi"),
-       EXYNOS_PIN_BANK_EINTG(8, 0x240, "gpj0", 0x44),
-       EXYNOS_PIN_BANK_EINTG(6, 0x260, "gpj1", 0x48),
-       EXYNOS_PIN_BANK_EINTG(8, 0x280, "gpj2", 0x4c),
-       EXYNOS_PIN_BANK_EINTG(8, 0x2a0, "gpj3", 0x50),
-       EXYNOS_PIN_BANK_EINTG(5, 0x2c0, "gpj4", 0x54),
-       EXYNOS_PIN_BANK_EINTN(8, 0x2e0, "mp01"),
-       EXYNOS_PIN_BANK_EINTN(4, 0x300, "mp02"),
-       EXYNOS_PIN_BANK_EINTN(8, 0x320, "mp03"),
-       EXYNOS_PIN_BANK_EINTN(8, 0x340, "mp04"),
-       EXYNOS_PIN_BANK_EINTN(8, 0x360, "mp05"),
-       EXYNOS_PIN_BANK_EINTN(8, 0x380, "mp06"),
-       EXYNOS_PIN_BANK_EINTN(8, 0x3a0, "mp07"),
-       EXYNOS_PIN_BANK_EINTW(8, 0xc00, "gph0", 0x00),
-       EXYNOS_PIN_BANK_EINTW(8, 0xc20, "gph1", 0x04),
-       EXYNOS_PIN_BANK_EINTW(8, 0xc40, "gph2", 0x08),
-       EXYNOS_PIN_BANK_EINTW(8, 0xc60, "gph3", 0x0c),
-};
-
-struct samsung_pin_ctrl s5pv210_pin_ctrl[] = {
-       {
-               /* pin-controller instance 0 data */
-               .pin_banks      = s5pv210_pin_bank,
-               .nr_banks       = ARRAY_SIZE(s5pv210_pin_bank),
-               .geint_con      = EXYNOS_GPIO_ECON_OFFSET,
-               .geint_mask     = EXYNOS_GPIO_EMASK_OFFSET,
-               .geint_pend     = EXYNOS_GPIO_EPEND_OFFSET,
-               .weint_con      = EXYNOS_WKUP_ECON_OFFSET,
-               .weint_mask     = EXYNOS_WKUP_EMASK_OFFSET,
-               .weint_pend     = EXYNOS_WKUP_EPEND_OFFSET,
-               .svc            = EXYNOS_SVC_OFFSET,
-               .eint_gpio_init = exynos_eint_gpio_init,
-               .eint_wkup_init = exynos_eint_wkup_init,
-               .suspend        = exynos_pinctrl_suspend,
-               .resume         = exynos_pinctrl_resume,
-               .label          = "s5pv210-gpio-ctrl0",
-       },
-};
-
-/* pin banks of exynos3250 pin-controller 0 */
-static struct samsung_pin_bank exynos3250_pin_banks0[] = {
-       EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00),
-       EXYNOS_PIN_BANK_EINTG(6, 0x020, "gpa1", 0x04),
-       EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpb",  0x08),
-       EXYNOS_PIN_BANK_EINTG(5, 0x060, "gpc0", 0x0c),
-       EXYNOS_PIN_BANK_EINTG(5, 0x080, "gpc1", 0x10),
-       EXYNOS_PIN_BANK_EINTG(4, 0x0a0, "gpd0", 0x14),
-       EXYNOS_PIN_BANK_EINTG(4, 0x0c0, "gpd1", 0x18),
-};
-
-/* pin banks of exynos3250 pin-controller 1 */
-static struct samsung_pin_bank exynos3250_pin_banks1[] = {
-       EXYNOS_PIN_BANK_EINTN(8, 0x120, "gpe0"),
-       EXYNOS_PIN_BANK_EINTN(8, 0x140, "gpe1"),
-       EXYNOS_PIN_BANK_EINTN(3, 0x180, "gpe2"),
-       EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpk0", 0x08),
-       EXYNOS_PIN_BANK_EINTG(7, 0x060, "gpk1", 0x0c),
-       EXYNOS_PIN_BANK_EINTG(7, 0x080, "gpk2", 0x10),
-       EXYNOS_PIN_BANK_EINTG(4, 0x0c0, "gpl0", 0x18),
-       EXYNOS_PIN_BANK_EINTG(8, 0x260, "gpm0", 0x24),
-       EXYNOS_PIN_BANK_EINTG(7, 0x280, "gpm1", 0x28),
-       EXYNOS_PIN_BANK_EINTG(5, 0x2a0, "gpm2", 0x2c),
-       EXYNOS_PIN_BANK_EINTG(8, 0x2c0, "gpm3", 0x30),
-       EXYNOS_PIN_BANK_EINTG(8, 0x2e0, "gpm4", 0x34),
-       EXYNOS_PIN_BANK_EINTW(8, 0xc00, "gpx0", 0x00),
-       EXYNOS_PIN_BANK_EINTW(8, 0xc20, "gpx1", 0x04),
-       EXYNOS_PIN_BANK_EINTW(8, 0xc40, "gpx2", 0x08),
-       EXYNOS_PIN_BANK_EINTW(8, 0xc60, "gpx3", 0x0c),
-};
-
-/*
- * Samsung pinctrl driver data for Exynos3250 SoC. Exynos3250 SoC includes
- * two gpio/pin-mux/pinconfig controllers.
- */
-struct samsung_pin_ctrl exynos3250_pin_ctrl[] = {
-       {
-               /* pin-controller instance 0 data */
-               .pin_banks      = exynos3250_pin_banks0,
-               .nr_banks       = ARRAY_SIZE(exynos3250_pin_banks0),
-               .geint_con      = EXYNOS_GPIO_ECON_OFFSET,
-               .geint_mask     = EXYNOS_GPIO_EMASK_OFFSET,
-               .geint_pend     = EXYNOS_GPIO_EPEND_OFFSET,
-               .svc            = EXYNOS_SVC_OFFSET,
-               .eint_gpio_init = exynos_eint_gpio_init,
-               .suspend        = exynos_pinctrl_suspend,
-               .resume         = exynos_pinctrl_resume,
-               .label          = "exynos3250-gpio-ctrl0",
-       }, {
-               /* pin-controller instance 1 data */
-               .pin_banks      = exynos3250_pin_banks1,
-               .nr_banks       = ARRAY_SIZE(exynos3250_pin_banks1),
-               .geint_con      = EXYNOS_GPIO_ECON_OFFSET,
-               .geint_mask     = EXYNOS_GPIO_EMASK_OFFSET,
-               .geint_pend     = EXYNOS_GPIO_EPEND_OFFSET,
-               .weint_con      = EXYNOS_WKUP_ECON_OFFSET,
-               .weint_mask     = EXYNOS_WKUP_EMASK_OFFSET,
-               .weint_pend     = EXYNOS_WKUP_EPEND_OFFSET,
-               .svc            = EXYNOS_SVC_OFFSET,
-               .eint_gpio_init = exynos_eint_gpio_init,
-               .eint_wkup_init = exynos_eint_wkup_init,
-               .suspend        = exynos_pinctrl_suspend,
-               .resume         = exynos_pinctrl_resume,
-               .label          = "exynos3250-gpio-ctrl1",
-       },
-};
-
-/* pin banks of exynos4210 pin-controller 0 */
-static struct samsung_pin_bank exynos4210_pin_banks0[] = {
-       EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00),
-       EXYNOS_PIN_BANK_EINTG(6, 0x020, "gpa1", 0x04),
-       EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpb", 0x08),
-       EXYNOS_PIN_BANK_EINTG(5, 0x060, "gpc0", 0x0c),
-       EXYNOS_PIN_BANK_EINTG(5, 0x080, "gpc1", 0x10),
-       EXYNOS_PIN_BANK_EINTG(4, 0x0A0, "gpd0", 0x14),
-       EXYNOS_PIN_BANK_EINTG(4, 0x0C0, "gpd1", 0x18),
-       EXYNOS_PIN_BANK_EINTG(5, 0x0E0, "gpe0", 0x1c),
-       EXYNOS_PIN_BANK_EINTG(8, 0x100, "gpe1", 0x20),
-       EXYNOS_PIN_BANK_EINTG(6, 0x120, "gpe2", 0x24),
-       EXYNOS_PIN_BANK_EINTG(8, 0x140, "gpe3", 0x28),
-       EXYNOS_PIN_BANK_EINTG(8, 0x160, "gpe4", 0x2c),
-       EXYNOS_PIN_BANK_EINTG(8, 0x180, "gpf0", 0x30),
-       EXYNOS_PIN_BANK_EINTG(8, 0x1A0, "gpf1", 0x34),
-       EXYNOS_PIN_BANK_EINTG(8, 0x1C0, "gpf2", 0x38),
-       EXYNOS_PIN_BANK_EINTG(6, 0x1E0, "gpf3", 0x3c),
-};
-
-/* pin banks of exynos4210 pin-controller 1 */
-static struct samsung_pin_bank exynos4210_pin_banks1[] = {
-       EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpj0", 0x00),
-       EXYNOS_PIN_BANK_EINTG(5, 0x020, "gpj1", 0x04),
-       EXYNOS_PIN_BANK_EINTG(7, 0x040, "gpk0", 0x08),
-       EXYNOS_PIN_BANK_EINTG(7, 0x060, "gpk1", 0x0c),
-       EXYNOS_PIN_BANK_EINTG(7, 0x080, "gpk2", 0x10),
-       EXYNOS_PIN_BANK_EINTG(7, 0x0A0, "gpk3", 0x14),
-       EXYNOS_PIN_BANK_EINTG(8, 0x0C0, "gpl0", 0x18),
-       EXYNOS_PIN_BANK_EINTG(3, 0x0E0, "gpl1", 0x1c),
-       EXYNOS_PIN_BANK_EINTG(8, 0x100, "gpl2", 0x20),
-       EXYNOS_PIN_BANK_EINTN(6, 0x120, "gpy0"),
-       EXYNOS_PIN_BANK_EINTN(4, 0x140, "gpy1"),
-       EXYNOS_PIN_BANK_EINTN(6, 0x160, "gpy2"),
-       EXYNOS_PIN_BANK_EINTN(8, 0x180, "gpy3"),
-       EXYNOS_PIN_BANK_EINTN(8, 0x1A0, "gpy4"),
-       EXYNOS_PIN_BANK_EINTN(8, 0x1C0, "gpy5"),
-       EXYNOS_PIN_BANK_EINTN(8, 0x1E0, "gpy6"),
-       EXYNOS_PIN_BANK_EINTW(8, 0xC00, "gpx0", 0x00),
-       EXYNOS_PIN_BANK_EINTW(8, 0xC20, "gpx1", 0x04),
-       EXYNOS_PIN_BANK_EINTW(8, 0xC40, "gpx2", 0x08),
-       EXYNOS_PIN_BANK_EINTW(8, 0xC60, "gpx3", 0x0c),
-};
-
-/* pin banks of exynos4210 pin-controller 2 */
-static struct samsung_pin_bank exynos4210_pin_banks2[] = {
-       EXYNOS_PIN_BANK_EINTN(7, 0x000, "gpz"),
-};
-
-/*
- * Samsung pinctrl driver data for Exynos4210 SoC. Exynos4210 SoC includes
- * three gpio/pin-mux/pinconfig controllers.
- */
-struct samsung_pin_ctrl exynos4210_pin_ctrl[] = {
-       {
-               /* pin-controller instance 0 data */
-               .pin_banks      = exynos4210_pin_banks0,
-               .nr_banks       = ARRAY_SIZE(exynos4210_pin_banks0),
-               .geint_con      = EXYNOS_GPIO_ECON_OFFSET,
-               .geint_mask     = EXYNOS_GPIO_EMASK_OFFSET,
-               .geint_pend     = EXYNOS_GPIO_EPEND_OFFSET,
-               .svc            = EXYNOS_SVC_OFFSET,
-               .eint_gpio_init = exynos_eint_gpio_init,
-               .suspend        = exynos_pinctrl_suspend,
-               .resume         = exynos_pinctrl_resume,
-               .label          = "exynos4210-gpio-ctrl0",
-       }, {
-               /* pin-controller instance 1 data */
-               .pin_banks      = exynos4210_pin_banks1,
-               .nr_banks       = ARRAY_SIZE(exynos4210_pin_banks1),
-               .geint_con      = EXYNOS_GPIO_ECON_OFFSET,
-               .geint_mask     = EXYNOS_GPIO_EMASK_OFFSET,
-               .geint_pend     = EXYNOS_GPIO_EPEND_OFFSET,
-               .weint_con      = EXYNOS_WKUP_ECON_OFFSET,
-               .weint_mask     = EXYNOS_WKUP_EMASK_OFFSET,
-               .weint_pend     = EXYNOS_WKUP_EPEND_OFFSET,
-               .svc            = EXYNOS_SVC_OFFSET,
-               .eint_gpio_init = exynos_eint_gpio_init,
-               .eint_wkup_init = exynos_eint_wkup_init,
-               .suspend        = exynos_pinctrl_suspend,
-               .resume         = exynos_pinctrl_resume,
-               .label          = "exynos4210-gpio-ctrl1",
-       }, {
-               /* pin-controller instance 2 data */
-               .pin_banks      = exynos4210_pin_banks2,
-               .nr_banks       = ARRAY_SIZE(exynos4210_pin_banks2),
-               .label          = "exynos4210-gpio-ctrl2",
-       },
-};
-
-/* pin banks of exynos4x12 pin-controller 0 */
-static struct samsung_pin_bank exynos4x12_pin_banks0[] = {
-       EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00),
-       EXYNOS_PIN_BANK_EINTG(6, 0x020, "gpa1", 0x04),
-       EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpb", 0x08),
-       EXYNOS_PIN_BANK_EINTG(5, 0x060, "gpc0", 0x0c),
-       EXYNOS_PIN_BANK_EINTG(5, 0x080, "gpc1", 0x10),
-       EXYNOS_PIN_BANK_EINTG(4, 0x0A0, "gpd0", 0x14),
-       EXYNOS_PIN_BANK_EINTG(4, 0x0C0, "gpd1", 0x18),
-       EXYNOS_PIN_BANK_EINTG(8, 0x180, "gpf0", 0x30),
-       EXYNOS_PIN_BANK_EINTG(8, 0x1A0, "gpf1", 0x34),
-       EXYNOS_PIN_BANK_EINTG(8, 0x1C0, "gpf2", 0x38),
-       EXYNOS_PIN_BANK_EINTG(6, 0x1E0, "gpf3", 0x3c),
-       EXYNOS_PIN_BANK_EINTG(8, 0x240, "gpj0", 0x40),
-       EXYNOS_PIN_BANK_EINTG(5, 0x260, "gpj1", 0x44),
-};
-
-/* pin banks of exynos4x12 pin-controller 1 */
-static struct samsung_pin_bank exynos4x12_pin_banks1[] = {
-       EXYNOS_PIN_BANK_EINTG(7, 0x040, "gpk0", 0x08),
-       EXYNOS_PIN_BANK_EINTG(7, 0x060, "gpk1", 0x0c),
-       EXYNOS_PIN_BANK_EINTG(7, 0x080, "gpk2", 0x10),
-       EXYNOS_PIN_BANK_EINTG(7, 0x0A0, "gpk3", 0x14),
-       EXYNOS_PIN_BANK_EINTG(7, 0x0C0, "gpl0", 0x18),
-       EXYNOS_PIN_BANK_EINTG(2, 0x0E0, "gpl1", 0x1c),
-       EXYNOS_PIN_BANK_EINTG(8, 0x100, "gpl2", 0x20),
-       EXYNOS_PIN_BANK_EINTG(8, 0x260, "gpm0", 0x24),
-       EXYNOS_PIN_BANK_EINTG(7, 0x280, "gpm1", 0x28),
-       EXYNOS_PIN_BANK_EINTG(5, 0x2A0, "gpm2", 0x2c),
-       EXYNOS_PIN_BANK_EINTG(8, 0x2C0, "gpm3", 0x30),
-       EXYNOS_PIN_BANK_EINTG(8, 0x2E0, "gpm4", 0x34),
-       EXYNOS_PIN_BANK_EINTN(6, 0x120, "gpy0"),
-       EXYNOS_PIN_BANK_EINTN(4, 0x140, "gpy1"),
-       EXYNOS_PIN_BANK_EINTN(6, 0x160, "gpy2"),
-       EXYNOS_PIN_BANK_EINTN(8, 0x180, "gpy3"),
-       EXYNOS_PIN_BANK_EINTN(8, 0x1A0, "gpy4"),
-       EXYNOS_PIN_BANK_EINTN(8, 0x1C0, "gpy5"),
-       EXYNOS_PIN_BANK_EINTN(8, 0x1E0, "gpy6"),
-       EXYNOS_PIN_BANK_EINTW(8, 0xC00, "gpx0", 0x00),
-       EXYNOS_PIN_BANK_EINTW(8, 0xC20, "gpx1", 0x04),
-       EXYNOS_PIN_BANK_EINTW(8, 0xC40, "gpx2", 0x08),
-       EXYNOS_PIN_BANK_EINTW(8, 0xC60, "gpx3", 0x0c),
-};
-
-/* pin banks of exynos4x12 pin-controller 2 */
-static struct samsung_pin_bank exynos4x12_pin_banks2[] = {
-       EXYNOS_PIN_BANK_EINTG(7, 0x000, "gpz", 0x00),
-};
-
-/* pin banks of exynos4x12 pin-controller 3 */
-static struct samsung_pin_bank exynos4x12_pin_banks3[] = {
-       EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpv0", 0x00),
-       EXYNOS_PIN_BANK_EINTG(8, 0x020, "gpv1", 0x04),
-       EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpv2", 0x08),
-       EXYNOS_PIN_BANK_EINTG(8, 0x060, "gpv3", 0x0c),
-       EXYNOS_PIN_BANK_EINTG(2, 0x080, "gpv4", 0x10),
-};
-
-/*
- * Samsung pinctrl driver data for Exynos4x12 SoC. Exynos4x12 SoC includes
- * four gpio/pin-mux/pinconfig controllers.
- */
-struct samsung_pin_ctrl exynos4x12_pin_ctrl[] = {
-       {
-               /* pin-controller instance 0 data */
-               .pin_banks      = exynos4x12_pin_banks0,
-               .nr_banks       = ARRAY_SIZE(exynos4x12_pin_banks0),
-               .geint_con      = EXYNOS_GPIO_ECON_OFFSET,
-               .geint_mask     = EXYNOS_GPIO_EMASK_OFFSET,
-               .geint_pend     = EXYNOS_GPIO_EPEND_OFFSET,
-               .svc            = EXYNOS_SVC_OFFSET,
-               .eint_gpio_init = exynos_eint_gpio_init,
-               .suspend        = exynos_pinctrl_suspend,
-               .resume         = exynos_pinctrl_resume,
-               .label          = "exynos4x12-gpio-ctrl0",
-       }, {
-               /* pin-controller instance 1 data */
-               .pin_banks      = exynos4x12_pin_banks1,
-               .nr_banks       = ARRAY_SIZE(exynos4x12_pin_banks1),
-               .geint_con      = EXYNOS_GPIO_ECON_OFFSET,
-               .geint_mask     = EXYNOS_GPIO_EMASK_OFFSET,
-               .geint_pend     = EXYNOS_GPIO_EPEND_OFFSET,
-               .weint_con      = EXYNOS_WKUP_ECON_OFFSET,
-               .weint_mask     = EXYNOS_WKUP_EMASK_OFFSET,
-               .weint_pend     = EXYNOS_WKUP_EPEND_OFFSET,
-               .svc            = EXYNOS_SVC_OFFSET,
-               .eint_gpio_init = exynos_eint_gpio_init,
-               .eint_wkup_init = exynos_eint_wkup_init,
-               .suspend        = exynos_pinctrl_suspend,
-               .resume         = exynos_pinctrl_resume,
-               .label          = "exynos4x12-gpio-ctrl1",
-       }, {
-               /* pin-controller instance 2 data */
-               .pin_banks      = exynos4x12_pin_banks2,
-               .nr_banks       = ARRAY_SIZE(exynos4x12_pin_banks2),
-               .geint_con      = EXYNOS_GPIO_ECON_OFFSET,
-               .geint_mask     = EXYNOS_GPIO_EMASK_OFFSET,
-               .geint_pend     = EXYNOS_GPIO_EPEND_OFFSET,
-               .svc            = EXYNOS_SVC_OFFSET,
-               .eint_gpio_init = exynos_eint_gpio_init,
-               .suspend        = exynos_pinctrl_suspend,
-               .resume         = exynos_pinctrl_resume,
-               .label          = "exynos4x12-gpio-ctrl2",
-       }, {
-               /* pin-controller instance 3 data */
-               .pin_banks      = exynos4x12_pin_banks3,
-               .nr_banks       = ARRAY_SIZE(exynos4x12_pin_banks3),
-               .geint_con      = EXYNOS_GPIO_ECON_OFFSET,
-               .geint_mask     = EXYNOS_GPIO_EMASK_OFFSET,
-               .geint_pend     = EXYNOS_GPIO_EPEND_OFFSET,
-               .svc            = EXYNOS_SVC_OFFSET,
-               .eint_gpio_init = exynos_eint_gpio_init,
-               .suspend        = exynos_pinctrl_suspend,
-               .resume         = exynos_pinctrl_resume,
-               .label          = "exynos4x12-gpio-ctrl3",
-       },
-};
-
-/* pin banks of exynos5250 pin-controller 0 */
-static struct samsung_pin_bank exynos5250_pin_banks0[] = {
-       EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00),
-       EXYNOS_PIN_BANK_EINTG(6, 0x020, "gpa1", 0x04),
-       EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpa2", 0x08),
-       EXYNOS_PIN_BANK_EINTG(5, 0x060, "gpb0", 0x0c),
-       EXYNOS_PIN_BANK_EINTG(5, 0x080, "gpb1", 0x10),
-       EXYNOS_PIN_BANK_EINTG(4, 0x0A0, "gpb2", 0x14),
-       EXYNOS_PIN_BANK_EINTG(4, 0x0C0, "gpb3", 0x18),
-       EXYNOS_PIN_BANK_EINTG(7, 0x0E0, "gpc0", 0x1c),
-       EXYNOS_PIN_BANK_EINTG(4, 0x100, "gpc1", 0x20),
-       EXYNOS_PIN_BANK_EINTG(7, 0x120, "gpc2", 0x24),
-       EXYNOS_PIN_BANK_EINTG(7, 0x140, "gpc3", 0x28),
-       EXYNOS_PIN_BANK_EINTG(4, 0x160, "gpd0", 0x2c),
-       EXYNOS_PIN_BANK_EINTG(8, 0x180, "gpd1", 0x30),
-       EXYNOS_PIN_BANK_EINTG(7, 0x2E0, "gpc4", 0x34),
-       EXYNOS_PIN_BANK_EINTN(6, 0x1A0, "gpy0"),
-       EXYNOS_PIN_BANK_EINTN(4, 0x1C0, "gpy1"),
-       EXYNOS_PIN_BANK_EINTN(6, 0x1E0, "gpy2"),
-       EXYNOS_PIN_BANK_EINTN(8, 0x200, "gpy3"),
-       EXYNOS_PIN_BANK_EINTN(8, 0x220, "gpy4"),
-       EXYNOS_PIN_BANK_EINTN(8, 0x240, "gpy5"),
-       EXYNOS_PIN_BANK_EINTN(8, 0x260, "gpy6"),
-       EXYNOS_PIN_BANK_EINTW(8, 0xC00, "gpx0", 0x00),
-       EXYNOS_PIN_BANK_EINTW(8, 0xC20, "gpx1", 0x04),
-       EXYNOS_PIN_BANK_EINTW(8, 0xC40, "gpx2", 0x08),
-       EXYNOS_PIN_BANK_EINTW(8, 0xC60, "gpx3", 0x0c),
-};
-
-/* pin banks of exynos5250 pin-controller 1 */
-static struct samsung_pin_bank exynos5250_pin_banks1[] = {
-       EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpe0", 0x00),
-       EXYNOS_PIN_BANK_EINTG(2, 0x020, "gpe1", 0x04),
-       EXYNOS_PIN_BANK_EINTG(4, 0x040, "gpf0", 0x08),
-       EXYNOS_PIN_BANK_EINTG(4, 0x060, "gpf1", 0x0c),
-       EXYNOS_PIN_BANK_EINTG(8, 0x080, "gpg0", 0x10),
-       EXYNOS_PIN_BANK_EINTG(8, 0x0A0, "gpg1", 0x14),
-       EXYNOS_PIN_BANK_EINTG(2, 0x0C0, "gpg2", 0x18),
-       EXYNOS_PIN_BANK_EINTG(4, 0x0E0, "gph0", 0x1c),
-       EXYNOS_PIN_BANK_EINTG(8, 0x100, "gph1", 0x20),
-};
-
-/* pin banks of exynos5250 pin-controller 2 */
-static struct samsung_pin_bank exynos5250_pin_banks2[] = {
-       EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpv0", 0x00),
-       EXYNOS_PIN_BANK_EINTG(8, 0x020, "gpv1", 0x04),
-       EXYNOS_PIN_BANK_EINTG(8, 0x060, "gpv2", 0x08),
-       EXYNOS_PIN_BANK_EINTG(8, 0x080, "gpv3", 0x0c),
-       EXYNOS_PIN_BANK_EINTG(2, 0x0C0, "gpv4", 0x10),
-};
-
-/* pin banks of exynos5250 pin-controller 3 */
-static struct samsung_pin_bank exynos5250_pin_banks3[] = {
-       EXYNOS_PIN_BANK_EINTG(7, 0x000, "gpz", 0x00),
-};
-
-/*
- * Samsung pinctrl driver data for Exynos5250 SoC. Exynos5250 SoC includes
- * four gpio/pin-mux/pinconfig controllers.
- */
-struct samsung_pin_ctrl exynos5250_pin_ctrl[] = {
-       {
-               /* pin-controller instance 0 data */
-               .pin_banks      = exynos5250_pin_banks0,
-               .nr_banks       = ARRAY_SIZE(exynos5250_pin_banks0),
-               .geint_con      = EXYNOS_GPIO_ECON_OFFSET,
-               .geint_mask     = EXYNOS_GPIO_EMASK_OFFSET,
-               .geint_pend     = EXYNOS_GPIO_EPEND_OFFSET,
-               .weint_con      = EXYNOS_WKUP_ECON_OFFSET,
-               .weint_mask     = EXYNOS_WKUP_EMASK_OFFSET,
-               .weint_pend     = EXYNOS_WKUP_EPEND_OFFSET,
-               .svc            = EXYNOS_SVC_OFFSET,
-               .eint_gpio_init = exynos_eint_gpio_init,
-               .eint_wkup_init = exynos_eint_wkup_init,
-               .suspend        = exynos_pinctrl_suspend,
-               .resume         = exynos_pinctrl_resume,
-               .label          = "exynos5250-gpio-ctrl0",
-       }, {
-               /* pin-controller instance 1 data */
-               .pin_banks      = exynos5250_pin_banks1,
-               .nr_banks       = ARRAY_SIZE(exynos5250_pin_banks1),
-               .geint_con      = EXYNOS_GPIO_ECON_OFFSET,
-               .geint_mask     = EXYNOS_GPIO_EMASK_OFFSET,
-               .geint_pend     = EXYNOS_GPIO_EPEND_OFFSET,
-               .svc            = EXYNOS_SVC_OFFSET,
-               .eint_gpio_init = exynos_eint_gpio_init,
-               .suspend        = exynos_pinctrl_suspend,
-               .resume         = exynos_pinctrl_resume,
-               .label          = "exynos5250-gpio-ctrl1",
-       }, {
-               /* pin-controller instance 2 data */
-               .pin_banks      = exynos5250_pin_banks2,
-               .nr_banks       = ARRAY_SIZE(exynos5250_pin_banks2),
-               .geint_con      = EXYNOS_GPIO_ECON_OFFSET,
-               .geint_mask     = EXYNOS_GPIO_EMASK_OFFSET,
-               .geint_pend     = EXYNOS_GPIO_EPEND_OFFSET,
-               .svc            = EXYNOS_SVC_OFFSET,
-               .eint_gpio_init = exynos_eint_gpio_init,
-               .suspend        = exynos_pinctrl_suspend,
-               .resume         = exynos_pinctrl_resume,
-               .label          = "exynos5250-gpio-ctrl2",
-       }, {
-               /* pin-controller instance 3 data */
-               .pin_banks      = exynos5250_pin_banks3,
-               .nr_banks       = ARRAY_SIZE(exynos5250_pin_banks3),
-               .geint_con      = EXYNOS_GPIO_ECON_OFFSET,
-               .geint_mask     = EXYNOS_GPIO_EMASK_OFFSET,
-               .geint_pend     = EXYNOS_GPIO_EPEND_OFFSET,
-               .svc            = EXYNOS_SVC_OFFSET,
-               .eint_gpio_init = exynos_eint_gpio_init,
-               .suspend        = exynos_pinctrl_suspend,
-               .resume         = exynos_pinctrl_resume,
-               .label          = "exynos5250-gpio-ctrl3",
-       },
-};
-
-/* pin banks of exynos5260 pin-controller 0 */
-static struct samsung_pin_bank exynos5260_pin_banks0[] = {
-       EXYNOS_PIN_BANK_EINTG(4, 0x000, "gpa0", 0x00),
-       EXYNOS_PIN_BANK_EINTG(7, 0x020, "gpa1", 0x04),
-       EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpa2", 0x08),
-       EXYNOS_PIN_BANK_EINTG(5, 0x060, "gpb0", 0x0c),
-       EXYNOS_PIN_BANK_EINTG(4, 0x080, "gpb1", 0x10),
-       EXYNOS_PIN_BANK_EINTG(5, 0x0a0, "gpb2", 0x14),
-       EXYNOS_PIN_BANK_EINTG(8, 0x0c0, "gpb3", 0x18),
-       EXYNOS_PIN_BANK_EINTG(8, 0x0e0, "gpb4", 0x1c),
-       EXYNOS_PIN_BANK_EINTG(8, 0x100, "gpb5", 0x20),
-       EXYNOS_PIN_BANK_EINTG(8, 0x120, "gpd0", 0x24),
-       EXYNOS_PIN_BANK_EINTG(7, 0x140, "gpd1", 0x28),
-       EXYNOS_PIN_BANK_EINTG(5, 0x160, "gpd2", 0x2c),
-       EXYNOS_PIN_BANK_EINTG(8, 0x180, "gpe0", 0x30),
-       EXYNOS_PIN_BANK_EINTG(5, 0x1a0, "gpe1", 0x34),
-       EXYNOS_PIN_BANK_EINTG(4, 0x1c0, "gpf0", 0x38),
-       EXYNOS_PIN_BANK_EINTG(8, 0x1e0, "gpf1", 0x3c),
-       EXYNOS_PIN_BANK_EINTG(2, 0x200, "gpk0", 0x40),
-       EXYNOS_PIN_BANK_EINTW(8, 0xc00, "gpx0", 0x00),
-       EXYNOS_PIN_BANK_EINTW(8, 0xc20, "gpx1", 0x04),
-       EXYNOS_PIN_BANK_EINTW(8, 0xc40, "gpx2", 0x08),
-       EXYNOS_PIN_BANK_EINTW(8, 0xc60, "gpx3", 0x0c),
-};
-
-/* pin banks of exynos5260 pin-controller 1 */
-static struct samsung_pin_bank exynos5260_pin_banks1[] = {
-       EXYNOS_PIN_BANK_EINTG(7, 0x000, "gpc0", 0x00),
-       EXYNOS_PIN_BANK_EINTG(6, 0x020, "gpc1", 0x04),
-       EXYNOS_PIN_BANK_EINTG(7, 0x040, "gpc2", 0x08),
-       EXYNOS_PIN_BANK_EINTG(4, 0x060, "gpc3", 0x0c),
-       EXYNOS_PIN_BANK_EINTG(4, 0x080, "gpc4", 0x10),
-};
-
-/* pin banks of exynos5260 pin-controller 2 */
-static struct samsung_pin_bank exynos5260_pin_banks2[] = {
-       EXYNOS_PIN_BANK_EINTG(7, 0x000, "gpz0", 0x00),
-       EXYNOS_PIN_BANK_EINTG(4, 0x020, "gpz1", 0x04),
-};
-
-/*
- * Samsung pinctrl driver data for Exynos5260 SoC. Exynos5260 SoC includes
- * three gpio/pin-mux/pinconfig controllers.
- */
-struct samsung_pin_ctrl exynos5260_pin_ctrl[] = {
-       {
-               /* pin-controller instance 0 data */
-               .pin_banks      = exynos5260_pin_banks0,
-               .nr_banks       = ARRAY_SIZE(exynos5260_pin_banks0),
-               .geint_con      = EXYNOS_GPIO_ECON_OFFSET,
-               .geint_mask     = EXYNOS_GPIO_EMASK_OFFSET,
-               .geint_pend     = EXYNOS_GPIO_EPEND_OFFSET,
-               .weint_con      = EXYNOS_WKUP_ECON_OFFSET,
-               .weint_mask     = EXYNOS_WKUP_EMASK_OFFSET,
-               .weint_pend     = EXYNOS_WKUP_EPEND_OFFSET,
-               .svc            = EXYNOS_SVC_OFFSET,
-               .eint_gpio_init = exynos_eint_gpio_init,
-               .eint_wkup_init = exynos_eint_wkup_init,
-               .label          = "exynos5260-gpio-ctrl0",
-       }, {
-               /* pin-controller instance 1 data */
-               .pin_banks      = exynos5260_pin_banks1,
-               .nr_banks       = ARRAY_SIZE(exynos5260_pin_banks1),
-               .geint_con      = EXYNOS_GPIO_ECON_OFFSET,
-               .geint_mask     = EXYNOS_GPIO_EMASK_OFFSET,
-               .geint_pend     = EXYNOS_GPIO_EPEND_OFFSET,
-               .svc            = EXYNOS_SVC_OFFSET,
-               .eint_gpio_init = exynos_eint_gpio_init,
-               .label          = "exynos5260-gpio-ctrl1",
-       }, {
-               /* pin-controller instance 2 data */
-               .pin_banks      = exynos5260_pin_banks2,
-               .nr_banks       = ARRAY_SIZE(exynos5260_pin_banks2),
-               .geint_con      = EXYNOS_GPIO_ECON_OFFSET,
-               .geint_mask     = EXYNOS_GPIO_EMASK_OFFSET,
-               .geint_pend     = EXYNOS_GPIO_EPEND_OFFSET,
-               .svc            = EXYNOS_SVC_OFFSET,
-               .eint_gpio_init = exynos_eint_gpio_init,
-               .label          = "exynos5260-gpio-ctrl2",
-       },
-};
-
-/* pin banks of exynos5420 pin-controller 0 */
-static struct samsung_pin_bank exynos5420_pin_banks0[] = {
-       EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpy7", 0x00),
-       EXYNOS_PIN_BANK_EINTW(8, 0xC00, "gpx0", 0x00),
-       EXYNOS_PIN_BANK_EINTW(8, 0xC20, "gpx1", 0x04),
-       EXYNOS_PIN_BANK_EINTW(8, 0xC40, "gpx2", 0x08),
-       EXYNOS_PIN_BANK_EINTW(8, 0xC60, "gpx3", 0x0c),
-};
-
-/* pin banks of exynos5420 pin-controller 1 */
-static struct samsung_pin_bank exynos5420_pin_banks1[] = {
-       EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpc0", 0x00),
-       EXYNOS_PIN_BANK_EINTG(8, 0x020, "gpc1", 0x04),
-       EXYNOS_PIN_BANK_EINTG(7, 0x040, "gpc2", 0x08),
-       EXYNOS_PIN_BANK_EINTG(4, 0x060, "gpc3", 0x0c),
-       EXYNOS_PIN_BANK_EINTG(2, 0x080, "gpc4", 0x10),
-       EXYNOS_PIN_BANK_EINTG(8, 0x0A0, "gpd1", 0x14),
-       EXYNOS_PIN_BANK_EINTN(6, 0x0C0, "gpy0"),
-       EXYNOS_PIN_BANK_EINTN(4, 0x0E0, "gpy1"),
-       EXYNOS_PIN_BANK_EINTN(6, 0x100, "gpy2"),
-       EXYNOS_PIN_BANK_EINTN(8, 0x120, "gpy3"),
-       EXYNOS_PIN_BANK_EINTN(8, 0x140, "gpy4"),
-       EXYNOS_PIN_BANK_EINTN(8, 0x160, "gpy5"),
-       EXYNOS_PIN_BANK_EINTN(8, 0x180, "gpy6"),
-};
-
-/* pin banks of exynos5420 pin-controller 2 */
-static struct samsung_pin_bank exynos5420_pin_banks2[] = {
-       EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpe0", 0x00),
-       EXYNOS_PIN_BANK_EINTG(2, 0x020, "gpe1", 0x04),
-       EXYNOS_PIN_BANK_EINTG(6, 0x040, "gpf0", 0x08),
-       EXYNOS_PIN_BANK_EINTG(8, 0x060, "gpf1", 0x0c),
-       EXYNOS_PIN_BANK_EINTG(8, 0x080, "gpg0", 0x10),
-       EXYNOS_PIN_BANK_EINTG(8, 0x0A0, "gpg1", 0x14),
-       EXYNOS_PIN_BANK_EINTG(2, 0x0C0, "gpg2", 0x18),
-       EXYNOS_PIN_BANK_EINTG(4, 0x0E0, "gpj4", 0x1c),
-};
-
-/* pin banks of exynos5420 pin-controller 3 */
-static struct samsung_pin_bank exynos5420_pin_banks3[] = {
-       EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00),
-       EXYNOS_PIN_BANK_EINTG(6, 0x020, "gpa1", 0x04),
-       EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpa2", 0x08),
-       EXYNOS_PIN_BANK_EINTG(5, 0x060, "gpb0", 0x0c),
-       EXYNOS_PIN_BANK_EINTG(5, 0x080, "gpb1", 0x10),
-       EXYNOS_PIN_BANK_EINTG(4, 0x0A0, "gpb2", 0x14),
-       EXYNOS_PIN_BANK_EINTG(8, 0x0C0, "gpb3", 0x18),
-       EXYNOS_PIN_BANK_EINTG(2, 0x0E0, "gpb4", 0x1c),
-       EXYNOS_PIN_BANK_EINTG(8, 0x100, "gph0", 0x20),
-};
-
-/* pin banks of exynos5420 pin-controller 4 */
-static struct samsung_pin_bank exynos5420_pin_banks4[] = {
-       EXYNOS_PIN_BANK_EINTG(7, 0x000, "gpz", 0x00),
-};
-
-/*
- * Samsung pinctrl driver data for Exynos5420 SoC. Exynos5420 SoC includes
- * four gpio/pin-mux/pinconfig controllers.
- */
-struct samsung_pin_ctrl exynos5420_pin_ctrl[] = {
-       {
-               /* pin-controller instance 0 data */
-               .pin_banks      = exynos5420_pin_banks0,
-               .nr_banks       = ARRAY_SIZE(exynos5420_pin_banks0),
-               .geint_con      = EXYNOS_GPIO_ECON_OFFSET,
-               .geint_mask     = EXYNOS_GPIO_EMASK_OFFSET,
-               .geint_pend     = EXYNOS_GPIO_EPEND_OFFSET,
-               .weint_con      = EXYNOS_WKUP_ECON_OFFSET,
-               .weint_mask     = EXYNOS_WKUP_EMASK_OFFSET,
-               .weint_pend     = EXYNOS_WKUP_EPEND_OFFSET,
-               .svc            = EXYNOS_SVC_OFFSET,
-               .eint_gpio_init = exynos_eint_gpio_init,
-               .eint_wkup_init = exynos_eint_wkup_init,
-               .label          = "exynos5420-gpio-ctrl0",
-       }, {
-               /* pin-controller instance 1 data */
-               .pin_banks      = exynos5420_pin_banks1,
-               .nr_banks       = ARRAY_SIZE(exynos5420_pin_banks1),
-               .geint_con      = EXYNOS_GPIO_ECON_OFFSET,
-               .geint_mask     = EXYNOS_GPIO_EMASK_OFFSET,
-               .geint_pend     = EXYNOS_GPIO_EPEND_OFFSET,
-               .svc            = EXYNOS_SVC_OFFSET,
-               .eint_gpio_init = exynos_eint_gpio_init,
-               .label          = "exynos5420-gpio-ctrl1",
-       }, {
-               /* pin-controller instance 2 data */
-               .pin_banks      = exynos5420_pin_banks2,
-               .nr_banks       = ARRAY_SIZE(exynos5420_pin_banks2),
-               .geint_con      = EXYNOS_GPIO_ECON_OFFSET,
-               .geint_mask     = EXYNOS_GPIO_EMASK_OFFSET,
-               .geint_pend     = EXYNOS_GPIO_EPEND_OFFSET,
-               .svc            = EXYNOS_SVC_OFFSET,
-               .eint_gpio_init = exynos_eint_gpio_init,
-               .label          = "exynos5420-gpio-ctrl2",
-       }, {
-               /* pin-controller instance 3 data */
-               .pin_banks      = exynos5420_pin_banks3,
-               .nr_banks       = ARRAY_SIZE(exynos5420_pin_banks3),
-               .geint_con      = EXYNOS_GPIO_ECON_OFFSET,
-               .geint_mask     = EXYNOS_GPIO_EMASK_OFFSET,
-               .geint_pend     = EXYNOS_GPIO_EPEND_OFFSET,
-               .svc            = EXYNOS_SVC_OFFSET,
-               .eint_gpio_init = exynos_eint_gpio_init,
-               .label          = "exynos5420-gpio-ctrl3",
-       }, {
-               /* pin-controller instance 4 data */
-               .pin_banks      = exynos5420_pin_banks4,
-               .nr_banks       = ARRAY_SIZE(exynos5420_pin_banks4),
-               .geint_con      = EXYNOS_GPIO_ECON_OFFSET,
-               .geint_mask     = EXYNOS_GPIO_EMASK_OFFSET,
-               .geint_pend     = EXYNOS_GPIO_EPEND_OFFSET,
-               .svc            = EXYNOS_SVC_OFFSET,
-               .eint_gpio_init = exynos_eint_gpio_init,
-               .label          = "exynos5420-gpio-ctrl4",
-       },
-};
diff --git a/drivers/pinctrl/pinctrl-exynos.h b/drivers/pinctrl/pinctrl-exynos.h
deleted file mode 100644 (file)
index 3c91c35..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Exynos specific definitions for Samsung pinctrl and gpiolib driver.
- *
- * Copyright (c) 2012 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- * Copyright (c) 2012 Linaro Ltd
- *             http://www.linaro.org
- *
- * This file contains the Exynos specific definitions for the Samsung
- * pinctrl/gpiolib interface drivers.
- *
- * Author: Thomas Abraham <thomas.ab@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-/* External GPIO and wakeup interrupt related definitions */
-#define EXYNOS_GPIO_ECON_OFFSET                0x700
-#define EXYNOS_GPIO_EFLTCON_OFFSET     0x800
-#define EXYNOS_GPIO_EMASK_OFFSET       0x900
-#define EXYNOS_GPIO_EPEND_OFFSET       0xA00
-#define EXYNOS_WKUP_ECON_OFFSET                0xE00
-#define EXYNOS_WKUP_EMASK_OFFSET       0xF00
-#define EXYNOS_WKUP_EPEND_OFFSET       0xF40
-#define EXYNOS_SVC_OFFSET              0xB08
-#define EXYNOS_EINT_FUNC               0xF
-
-/* helpers to access interrupt service register */
-#define EXYNOS_SVC_GROUP_SHIFT         3
-#define EXYNOS_SVC_GROUP_MASK          0x1f
-#define EXYNOS_SVC_NUM_MASK            7
-#define EXYNOS_SVC_GROUP(x)            ((x >> EXYNOS_SVC_GROUP_SHIFT) & \
-                                               EXYNOS_SVC_GROUP_MASK)
-
-/* Exynos specific external interrupt trigger types */
-#define EXYNOS_EINT_LEVEL_LOW          0
-#define EXYNOS_EINT_LEVEL_HIGH         1
-#define EXYNOS_EINT_EDGE_FALLING       2
-#define EXYNOS_EINT_EDGE_RISING                3
-#define EXYNOS_EINT_EDGE_BOTH          4
-#define EXYNOS_EINT_CON_MASK           0xF
-#define EXYNOS_EINT_CON_LEN            4
-
-#define EXYNOS_EINT_MAX_PER_BANK       8
-#define EXYNOS_EINT_NR_WKUP_EINT
-
-#define EXYNOS_PIN_BANK_EINTN(pins, reg, id)           \
-       {                                               \
-               .type           = &bank_type_off,       \
-               .pctl_offset    = reg,                  \
-               .nr_pins        = pins,                 \
-               .eint_type      = EINT_TYPE_NONE,       \
-               .name           = id                    \
-       }
-
-#define EXYNOS_PIN_BANK_EINTG(pins, reg, id, offs)     \
-       {                                               \
-               .type           = &bank_type_off,       \
-               .pctl_offset    = reg,                  \
-               .nr_pins        = pins,                 \
-               .eint_type      = EINT_TYPE_GPIO,       \
-               .eint_offset    = offs,                 \
-               .name           = id                    \
-       }
-
-#define EXYNOS_PIN_BANK_EINTW(pins, reg, id, offs)     \
-       {                                               \
-               .type           = &bank_type_alive,     \
-               .pctl_offset    = reg,                  \
-               .nr_pins        = pins,                 \
-               .eint_type      = EINT_TYPE_WKUP,       \
-               .eint_offset    = offs,                 \
-               .name           = id                    \
-       }
-
-/**
- * struct exynos_weint_data: irq specific data for all the wakeup interrupts
- * generated by the external wakeup interrupt controller.
- * @irq: interrupt number within the domain.
- * @bank: bank responsible for this interrupt
- */
-struct exynos_weint_data {
-       unsigned int irq;
-       struct samsung_pin_bank *bank;
-};
-
-/**
- * struct exynos_muxed_weint_data: irq specific data for muxed wakeup interrupts
- * generated by the external wakeup interrupt controller.
- * @nr_banks: count of banks being part of the mux
- * @banks: array of banks being part of the mux
- */
-struct exynos_muxed_weint_data {
-       unsigned int nr_banks;
-       struct samsung_pin_bank *banks[];
-};
diff --git a/drivers/pinctrl/pinctrl-exynos5440.c b/drivers/pinctrl/pinctrl-exynos5440.c
deleted file mode 100644 (file)
index 8fe2ab0..0000000
+++ /dev/null
@@ -1,1069 +0,0 @@
-/*
- * pin-controller/pin-mux/pin-config/gpio-driver for Samsung's EXYNOS5440 SoC.
- *
- * Copyright (c) 2012 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-#include <linux/slab.h>
-#include <linux/err.h>
-#include <linux/gpio.h>
-#include <linux/device.h>
-#include <linux/pinctrl/pinctrl.h>
-#include <linux/pinctrl/pinmux.h>
-#include <linux/pinctrl/pinconf.h>
-#include <linux/interrupt.h>
-#include <linux/irqdomain.h>
-#include <linux/of_irq.h>
-#include "core.h"
-
-/* EXYNOS5440 GPIO and Pinctrl register offsets */
-#define GPIO_MUX               0x00
-#define GPIO_IE                        0x04
-#define GPIO_INT               0x08
-#define GPIO_TYPE              0x0C
-#define GPIO_VAL               0x10
-#define GPIO_OE                        0x14
-#define GPIO_IN                        0x18
-#define GPIO_PE                        0x1C
-#define GPIO_PS                        0x20
-#define GPIO_SR                        0x24
-#define GPIO_DS0               0x28
-#define GPIO_DS1               0x2C
-
-#define EXYNOS5440_MAX_PINS            23
-#define EXYNOS5440_MAX_GPIO_INT        8
-#define PIN_NAME_LENGTH                10
-
-#define GROUP_SUFFIX           "-grp"
-#define GSUFFIX_LEN            sizeof(GROUP_SUFFIX)
-#define FUNCTION_SUFFIX                "-mux"
-#define FSUFFIX_LEN            sizeof(FUNCTION_SUFFIX)
-
-/*
- * pin configuration type and its value are packed together into a 16-bits.
- * The upper 8-bits represent the configuration type and the lower 8-bits
- * hold the value of the configuration type.
- */
-#define PINCFG_TYPE_MASK               0xFF
-#define PINCFG_VALUE_SHIFT             8
-#define PINCFG_VALUE_MASK              (0xFF << PINCFG_VALUE_SHIFT)
-#define PINCFG_PACK(type, value)       (((value) << PINCFG_VALUE_SHIFT) | type)
-#define PINCFG_UNPACK_TYPE(cfg)                ((cfg) & PINCFG_TYPE_MASK)
-#define PINCFG_UNPACK_VALUE(cfg)       (((cfg) & PINCFG_VALUE_MASK) >> \
-                                               PINCFG_VALUE_SHIFT)
-
-/**
- * enum pincfg_type - possible pin configuration types supported.
- * @PINCFG_TYPE_PUD: Pull up/down configuration.
- * @PINCFG_TYPE_DRV: Drive strength configuration.
- * @PINCFG_TYPE_SKEW_RATE: Skew rate configuration.
- * @PINCFG_TYPE_INPUT_TYPE: Pin input type configuration.
- */
-enum pincfg_type {
-       PINCFG_TYPE_PUD,
-       PINCFG_TYPE_DRV,
-       PINCFG_TYPE_SKEW_RATE,
-       PINCFG_TYPE_INPUT_TYPE
-};
-
-/**
- * struct exynos5440_pin_group: represent group of pins for pincfg setting.
- * @name: name of the pin group, used to lookup the group.
- * @pins: the pins included in this group.
- * @num_pins: number of pins included in this group.
- */
-struct exynos5440_pin_group {
-       const char              *name;
-       const unsigned int      *pins;
-       u8                      num_pins;
-};
-
-/**
- * struct exynos5440_pmx_func: represent a pin function.
- * @name: name of the pin function, used to lookup the function.
- * @groups: one or more names of pin groups that provide this function.
- * @num_groups: number of groups included in @groups.
- * @function: the function number to be programmed when selected.
- */
-struct exynos5440_pmx_func {
-       const char              *name;
-       const char              **groups;
-       u8                      num_groups;
-       unsigned long           function;
-};
-
-/**
- * struct exynos5440_pinctrl_priv_data: driver's private runtime data.
- * @reg_base: ioremapped based address of the register space.
- * @gc: gpio chip registered with gpiolib.
- * @pin_groups: list of pin groups parsed from device tree.
- * @nr_groups: number of pin groups available.
- * @pmx_functions: list of pin functions parsed from device tree.
- * @nr_functions: number of pin functions available.
- */
-struct exynos5440_pinctrl_priv_data {
-       void __iomem                    *reg_base;
-       struct gpio_chip                *gc;
-       struct irq_domain               *irq_domain;
-
-       const struct exynos5440_pin_group       *pin_groups;
-       unsigned int                    nr_groups;
-       const struct exynos5440_pmx_func        *pmx_functions;
-       unsigned int                    nr_functions;
-};
-
-/**
- * struct exynos5440_gpio_intr_data: private data for gpio interrupts.
- * @priv: driver's private runtime data.
- * @gpio_int: gpio interrupt number.
- */
-struct exynos5440_gpio_intr_data {
-       struct exynos5440_pinctrl_priv_data     *priv;
-       unsigned int                            gpio_int;
-};
-
-/* list of all possible config options supported */
-static struct pin_config {
-       char            *prop_cfg;
-       unsigned int    cfg_type;
-} pcfgs[] = {
-       { "samsung,exynos5440-pin-pud", PINCFG_TYPE_PUD },
-       { "samsung,exynos5440-pin-drv", PINCFG_TYPE_DRV },
-       { "samsung,exynos5440-pin-skew-rate", PINCFG_TYPE_SKEW_RATE },
-       { "samsung,exynos5440-pin-input-type", PINCFG_TYPE_INPUT_TYPE },
-};
-
-/* check if the selector is a valid pin group selector */
-static int exynos5440_get_group_count(struct pinctrl_dev *pctldev)
-{
-       struct exynos5440_pinctrl_priv_data *priv;
-
-       priv = pinctrl_dev_get_drvdata(pctldev);
-       return priv->nr_groups;
-}
-
-/* return the name of the group selected by the group selector */
-static const char *exynos5440_get_group_name(struct pinctrl_dev *pctldev,
-                                               unsigned selector)
-{
-       struct exynos5440_pinctrl_priv_data *priv;
-
-       priv = pinctrl_dev_get_drvdata(pctldev);
-       return priv->pin_groups[selector].name;
-}
-
-/* return the pin numbers associated with the specified group */
-static int exynos5440_get_group_pins(struct pinctrl_dev *pctldev,
-               unsigned selector, const unsigned **pins, unsigned *num_pins)
-{
-       struct exynos5440_pinctrl_priv_data *priv;
-
-       priv = pinctrl_dev_get_drvdata(pctldev);
-       *pins = priv->pin_groups[selector].pins;
-       *num_pins = priv->pin_groups[selector].num_pins;
-       return 0;
-}
-
-/* create pinctrl_map entries by parsing device tree nodes */
-static int exynos5440_dt_node_to_map(struct pinctrl_dev *pctldev,
-                       struct device_node *np, struct pinctrl_map **maps,
-                       unsigned *nmaps)
-{
-       struct device *dev = pctldev->dev;
-       struct pinctrl_map *map;
-       unsigned long *cfg = NULL;
-       char *gname, *fname;
-       int cfg_cnt = 0, map_cnt = 0, idx = 0;
-
-       /* count the number of config options specfied in the node */
-       for (idx = 0; idx < ARRAY_SIZE(pcfgs); idx++)
-               if (of_find_property(np, pcfgs[idx].prop_cfg, NULL))
-                       cfg_cnt++;
-
-       /*
-        * Find out the number of map entries to create. All the config options
-        * can be accomadated into a single config map entry.
-        */
-       if (cfg_cnt)
-               map_cnt = 1;
-       if (of_find_property(np, "samsung,exynos5440-pin-function", NULL))
-               map_cnt++;
-       if (!map_cnt) {
-               dev_err(dev, "node %s does not have either config or function "
-                               "configurations\n", np->name);
-               return -EINVAL;
-       }
-
-       /* Allocate memory for pin-map entries */
-       map = kzalloc(sizeof(*map) * map_cnt, GFP_KERNEL);
-       if (!map) {
-               dev_err(dev, "could not alloc memory for pin-maps\n");
-               return -ENOMEM;
-       }
-       *nmaps = 0;
-
-       /*
-        * Allocate memory for pin group name. The pin group name is derived
-        * from the node name from which these map entries are be created.
-        */
-       gname = kzalloc(strlen(np->name) + GSUFFIX_LEN, GFP_KERNEL);
-       if (!gname) {
-               dev_err(dev, "failed to alloc memory for group name\n");
-               goto free_map;
-       }
-       snprintf(gname, strlen(np->name) + 4, "%s%s", np->name, GROUP_SUFFIX);
-
-       /*
-        * don't have config options? then skip over to creating function
-        * map entries.
-        */
-       if (!cfg_cnt)
-               goto skip_cfgs;
-
-       /* Allocate memory for config entries */
-       cfg = kzalloc(sizeof(*cfg) * cfg_cnt, GFP_KERNEL);
-       if (!cfg) {
-               dev_err(dev, "failed to alloc memory for configs\n");
-               goto free_gname;
-       }
-
-       /* Prepare a list of config settings */
-       for (idx = 0, cfg_cnt = 0; idx < ARRAY_SIZE(pcfgs); idx++) {
-               u32 value;
-               if (!of_property_read_u32(np, pcfgs[idx].prop_cfg, &value))
-                       cfg[cfg_cnt++] =
-                               PINCFG_PACK(pcfgs[idx].cfg_type, value);
-       }
-
-       /* create the config map entry */
-       map[*nmaps].data.configs.group_or_pin = gname;
-       map[*nmaps].data.configs.configs = cfg;
-       map[*nmaps].data.configs.num_configs = cfg_cnt;
-       map[*nmaps].type = PIN_MAP_TYPE_CONFIGS_GROUP;
-       *nmaps += 1;
-
-skip_cfgs:
-       /* create the function map entry */
-       if (of_find_property(np, "samsung,exynos5440-pin-function", NULL)) {
-               fname = kzalloc(strlen(np->name) + FSUFFIX_LEN, GFP_KERNEL);
-               if (!fname) {
-                       dev_err(dev, "failed to alloc memory for func name\n");
-                       goto free_cfg;
-               }
-               snprintf(fname, strlen(np->name) + 4, "%s%s", np->name,
-                        FUNCTION_SUFFIX);
-
-               map[*nmaps].data.mux.group = gname;
-               map[*nmaps].data.mux.function = fname;
-               map[*nmaps].type = PIN_MAP_TYPE_MUX_GROUP;
-               *nmaps += 1;
-       }
-
-       *maps = map;
-       return 0;
-
-free_cfg:
-       kfree(cfg);
-free_gname:
-       kfree(gname);
-free_map:
-       kfree(map);
-       return -ENOMEM;
-}
-
-/* free the memory allocated to hold the pin-map table */
-static void exynos5440_dt_free_map(struct pinctrl_dev *pctldev,
-                            struct pinctrl_map *map, unsigned num_maps)
-{
-       int idx;
-
-       for (idx = 0; idx < num_maps; idx++) {
-               if (map[idx].type == PIN_MAP_TYPE_MUX_GROUP) {
-                       kfree(map[idx].data.mux.function);
-                       if (!idx)
-                               kfree(map[idx].data.mux.group);
-               } else if (map->type == PIN_MAP_TYPE_CONFIGS_GROUP) {
-                       kfree(map[idx].data.configs.configs);
-                       if (!idx)
-                               kfree(map[idx].data.configs.group_or_pin);
-               }
-       };
-
-       kfree(map);
-}
-
-/* list of pinctrl callbacks for the pinctrl core */
-static const struct pinctrl_ops exynos5440_pctrl_ops = {
-       .get_groups_count       = exynos5440_get_group_count,
-       .get_group_name         = exynos5440_get_group_name,
-       .get_group_pins         = exynos5440_get_group_pins,
-       .dt_node_to_map         = exynos5440_dt_node_to_map,
-       .dt_free_map            = exynos5440_dt_free_map,
-};
-
-/* check if the selector is a valid pin function selector */
-static int exynos5440_get_functions_count(struct pinctrl_dev *pctldev)
-{
-       struct exynos5440_pinctrl_priv_data *priv;
-
-       priv = pinctrl_dev_get_drvdata(pctldev);
-       return priv->nr_functions;
-}
-
-/* return the name of the pin function specified */
-static const char *exynos5440_pinmux_get_fname(struct pinctrl_dev *pctldev,
-                                               unsigned selector)
-{
-       struct exynos5440_pinctrl_priv_data *priv;
-
-       priv = pinctrl_dev_get_drvdata(pctldev);
-       return priv->pmx_functions[selector].name;
-}
-
-/* return the groups associated for the specified function selector */
-static int exynos5440_pinmux_get_groups(struct pinctrl_dev *pctldev,
-               unsigned selector, const char * const **groups,
-               unsigned * const num_groups)
-{
-       struct exynos5440_pinctrl_priv_data *priv;
-
-       priv = pinctrl_dev_get_drvdata(pctldev);
-       *groups = priv->pmx_functions[selector].groups;
-       *num_groups = priv->pmx_functions[selector].num_groups;
-       return 0;
-}
-
-/* enable or disable a pinmux function */
-static void exynos5440_pinmux_setup(struct pinctrl_dev *pctldev, unsigned selector,
-                                       unsigned group, bool enable)
-{
-       struct exynos5440_pinctrl_priv_data *priv;
-       void __iomem *base;
-       u32 function;
-       u32 data;
-
-       priv = pinctrl_dev_get_drvdata(pctldev);
-       base = priv->reg_base;
-       function = priv->pmx_functions[selector].function;
-
-       data = readl(base + GPIO_MUX);
-       if (enable)
-               data |= (1 << function);
-       else
-               data &= ~(1 << function);
-       writel(data, base + GPIO_MUX);
-}
-
-/* enable a specified pinmux by writing to registers */
-static int exynos5440_pinmux_enable(struct pinctrl_dev *pctldev, unsigned selector,
-                                       unsigned group)
-{
-       exynos5440_pinmux_setup(pctldev, selector, group, true);
-       return 0;
-}
-
-/* disable a specified pinmux by writing to registers */
-static void exynos5440_pinmux_disable(struct pinctrl_dev *pctldev,
-                                       unsigned selector, unsigned group)
-{
-       exynos5440_pinmux_setup(pctldev, selector, group, false);
-}
-
-/*
- * The calls to gpio_direction_output() and gpio_direction_input()
- * leads to this function call (via the pinctrl_gpio_direction_{input|output}()
- * function called from the gpiolib interface).
- */
-static int exynos5440_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev,
-               struct pinctrl_gpio_range *range, unsigned offset, bool input)
-{
-       return 0;
-}
-
-/* list of pinmux callbacks for the pinmux vertical in pinctrl core */
-static const struct pinmux_ops exynos5440_pinmux_ops = {
-       .get_functions_count    = exynos5440_get_functions_count,
-       .get_function_name      = exynos5440_pinmux_get_fname,
-       .get_function_groups    = exynos5440_pinmux_get_groups,
-       .enable                 = exynos5440_pinmux_enable,
-       .disable                = exynos5440_pinmux_disable,
-       .gpio_set_direction     = exynos5440_pinmux_gpio_set_direction,
-};
-
-/* set the pin config settings for a specified pin */
-static int exynos5440_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
-                               unsigned long *configs,
-                               unsigned num_configs)
-{
-       struct exynos5440_pinctrl_priv_data *priv;
-       void __iomem *base;
-       enum pincfg_type cfg_type;
-       u32 cfg_value;
-       u32 data;
-       int i;
-
-       priv = pinctrl_dev_get_drvdata(pctldev);
-       base = priv->reg_base;
-
-       for (i = 0; i < num_configs; i++) {
-               cfg_type = PINCFG_UNPACK_TYPE(configs[i]);
-               cfg_value = PINCFG_UNPACK_VALUE(configs[i]);
-
-               switch (cfg_type) {
-               case PINCFG_TYPE_PUD:
-                       /* first set pull enable/disable bit */
-                       data = readl(base + GPIO_PE);
-                       data &= ~(1 << pin);
-                       if (cfg_value)
-                               data |= (1 << pin);
-                       writel(data, base + GPIO_PE);
-
-                       /* then set pull up/down bit */
-                       data = readl(base + GPIO_PS);
-                       data &= ~(1 << pin);
-                       if (cfg_value == 2)
-                               data |= (1 << pin);
-                       writel(data, base + GPIO_PS);
-                       break;
-
-               case PINCFG_TYPE_DRV:
-                       /* set the first bit of the drive strength */
-                       data = readl(base + GPIO_DS0);
-                       data &= ~(1 << pin);
-                       data |= ((cfg_value & 1) << pin);
-                       writel(data, base + GPIO_DS0);
-                       cfg_value >>= 1;
-
-                       /* set the second bit of the driver strength */
-                       data = readl(base + GPIO_DS1);
-                       data &= ~(1 << pin);
-                       data |= ((cfg_value & 1) << pin);
-                       writel(data, base + GPIO_DS1);
-                       break;
-               case PINCFG_TYPE_SKEW_RATE:
-                       data = readl(base + GPIO_SR);
-                       data &= ~(1 << pin);
-                       data |= ((cfg_value & 1) << pin);
-                       writel(data, base + GPIO_SR);
-                       break;
-               case PINCFG_TYPE_INPUT_TYPE:
-                       data = readl(base + GPIO_TYPE);
-                       data &= ~(1 << pin);
-                       data |= ((cfg_value & 1) << pin);
-                       writel(data, base + GPIO_TYPE);
-                       break;
-               default:
-                       WARN_ON(1);
-                       return -EINVAL;
-               }
-       } /* for each config */
-
-       return 0;
-}
-
-/* get the pin config settings for a specified pin */
-static int exynos5440_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
-                                       unsigned long *config)
-{
-       struct exynos5440_pinctrl_priv_data *priv;
-       void __iomem *base;
-       enum pincfg_type cfg_type = PINCFG_UNPACK_TYPE(*config);
-       u32 data;
-
-       priv = pinctrl_dev_get_drvdata(pctldev);
-       base = priv->reg_base;
-
-       switch (cfg_type) {
-       case PINCFG_TYPE_PUD:
-               data = readl(base + GPIO_PE);
-               data = (data >> pin) & 1;
-               if (!data)
-                       *config = 0;
-               else
-                       *config = ((readl(base + GPIO_PS) >> pin) & 1) + 1;
-               break;
-       case PINCFG_TYPE_DRV:
-               data = readl(base + GPIO_DS0);
-               data = (data >> pin) & 1;
-               *config = data;
-               data = readl(base + GPIO_DS1);
-               data = (data >> pin) & 1;
-               *config |= (data << 1);
-               break;
-       case PINCFG_TYPE_SKEW_RATE:
-               data = readl(base + GPIO_SR);
-               *config = (data >> pin) & 1;
-               break;
-       case PINCFG_TYPE_INPUT_TYPE:
-               data = readl(base + GPIO_TYPE);
-               *config = (data >> pin) & 1;
-               break;
-       default:
-               WARN_ON(1);
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-/* set the pin config settings for a specified pin group */
-static int exynos5440_pinconf_group_set(struct pinctrl_dev *pctldev,
-                       unsigned group, unsigned long *configs,
-                       unsigned num_configs)
-{
-       struct exynos5440_pinctrl_priv_data *priv;
-       const unsigned int *pins;
-       unsigned int cnt;
-
-       priv = pinctrl_dev_get_drvdata(pctldev);
-       pins = priv->pin_groups[group].pins;
-
-       for (cnt = 0; cnt < priv->pin_groups[group].num_pins; cnt++)
-               exynos5440_pinconf_set(pctldev, pins[cnt], configs,
-                                      num_configs);
-
-       return 0;
-}
-
-/* get the pin config settings for a specified pin group */
-static int exynos5440_pinconf_group_get(struct pinctrl_dev *pctldev,
-                               unsigned int group, unsigned long *config)
-{
-       struct exynos5440_pinctrl_priv_data *priv;
-       const unsigned int *pins;
-
-       priv = pinctrl_dev_get_drvdata(pctldev);
-       pins = priv->pin_groups[group].pins;
-       exynos5440_pinconf_get(pctldev, pins[0], config);
-       return 0;
-}
-
-/* list of pinconfig callbacks for pinconfig vertical in the pinctrl code */
-static const struct pinconf_ops exynos5440_pinconf_ops = {
-       .pin_config_get         = exynos5440_pinconf_get,
-       .pin_config_set         = exynos5440_pinconf_set,
-       .pin_config_group_get   = exynos5440_pinconf_group_get,
-       .pin_config_group_set   = exynos5440_pinconf_group_set,
-};
-
-/* gpiolib gpio_set callback function */
-static void exynos5440_gpio_set(struct gpio_chip *gc, unsigned offset, int value)
-{
-       struct exynos5440_pinctrl_priv_data *priv = dev_get_drvdata(gc->dev);
-       void __iomem *base = priv->reg_base;
-       u32 data;
-
-       data = readl(base + GPIO_VAL);
-       data &= ~(1 << offset);
-       if (value)
-               data |= 1 << offset;
-       writel(data, base + GPIO_VAL);
-}
-
-/* gpiolib gpio_get callback function */
-static int exynos5440_gpio_get(struct gpio_chip *gc, unsigned offset)
-{
-       struct exynos5440_pinctrl_priv_data *priv = dev_get_drvdata(gc->dev);
-       void __iomem *base = priv->reg_base;
-       u32 data;
-
-       data = readl(base + GPIO_IN);
-       data >>= offset;
-       data &= 1;
-       return data;
-}
-
-/* gpiolib gpio_direction_input callback function */
-static int exynos5440_gpio_direction_input(struct gpio_chip *gc, unsigned offset)
-{
-       struct exynos5440_pinctrl_priv_data *priv = dev_get_drvdata(gc->dev);
-       void __iomem *base = priv->reg_base;
-       u32 data;
-
-       /* first disable the data output enable on this pin */
-       data = readl(base + GPIO_OE);
-       data &= ~(1 << offset);
-       writel(data, base + GPIO_OE);
-
-       /* now enable input on this pin */
-       data =  readl(base + GPIO_IE);
-       data |= 1 << offset;
-       writel(data, base + GPIO_IE);
-       return 0;
-}
-
-/* gpiolib gpio_direction_output callback function */
-static int exynos5440_gpio_direction_output(struct gpio_chip *gc, unsigned offset,
-                                                       int value)
-{
-       struct exynos5440_pinctrl_priv_data *priv = dev_get_drvdata(gc->dev);
-       void __iomem *base = priv->reg_base;
-       u32 data;
-
-       exynos5440_gpio_set(gc, offset, value);
-
-       /* first disable the data input enable on this pin */
-       data = readl(base + GPIO_IE);
-       data &= ~(1 << offset);
-       writel(data, base + GPIO_IE);
-
-       /* now enable output on this pin */
-       data =  readl(base + GPIO_OE);
-       data |= 1 << offset;
-       writel(data, base + GPIO_OE);
-       return 0;
-}
-
-/* gpiolib gpio_to_irq callback function */
-static int exynos5440_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
-{
-       struct exynos5440_pinctrl_priv_data *priv = dev_get_drvdata(gc->dev);
-       unsigned int virq;
-
-       if (offset < 16 || offset > 23)
-               return -ENXIO;
-
-       if (!priv->irq_domain)
-               return -ENXIO;
-
-       virq = irq_create_mapping(priv->irq_domain, offset - 16);
-       return virq ? : -ENXIO;
-}
-
-/* parse the pin numbers listed in the 'samsung,exynos5440-pins' property */
-static int exynos5440_pinctrl_parse_dt_pins(struct platform_device *pdev,
-                       struct device_node *cfg_np, unsigned int **pin_list,
-                       unsigned int *npins)
-{
-       struct device *dev = &pdev->dev;
-       struct property *prop;
-
-       prop = of_find_property(cfg_np, "samsung,exynos5440-pins", NULL);
-       if (!prop)
-               return -ENOENT;
-
-       *npins = prop->length / sizeof(unsigned long);
-       if (!*npins) {
-               dev_err(dev, "invalid pin list in %s node", cfg_np->name);
-               return -EINVAL;
-       }
-
-       *pin_list = devm_kzalloc(dev, *npins * sizeof(**pin_list), GFP_KERNEL);
-       if (!*pin_list) {
-               dev_err(dev, "failed to allocate memory for pin list\n");
-               return -ENOMEM;
-       }
-
-       return of_property_read_u32_array(cfg_np, "samsung,exynos5440-pins",
-                       *pin_list, *npins);
-}
-
-/*
- * Parse the information about all the available pin groups and pin functions
- * from device node of the pin-controller.
- */
-static int exynos5440_pinctrl_parse_dt(struct platform_device *pdev,
-                               struct exynos5440_pinctrl_priv_data *priv)
-{
-       struct device *dev = &pdev->dev;
-       struct device_node *dev_np = dev->of_node;
-       struct device_node *cfg_np;
-       struct exynos5440_pin_group *groups, *grp;
-       struct exynos5440_pmx_func *functions, *func;
-       unsigned *pin_list;
-       unsigned int npins, grp_cnt, func_idx = 0;
-       char *gname, *fname;
-       int ret;
-
-       grp_cnt = of_get_child_count(dev_np);
-       if (!grp_cnt)
-               return -EINVAL;
-
-       groups = devm_kzalloc(dev, grp_cnt * sizeof(*groups), GFP_KERNEL);
-       if (!groups) {
-               dev_err(dev, "failed allocate memory for ping group list\n");
-               return -EINVAL;
-       }
-       grp = groups;
-
-       functions = devm_kzalloc(dev, grp_cnt * sizeof(*functions), GFP_KERNEL);
-       if (!functions) {
-               dev_err(dev, "failed to allocate memory for function list\n");
-               return -EINVAL;
-       }
-       func = functions;
-
-       /*
-        * Iterate over all the child nodes of the pin controller node
-        * and create pin groups and pin function lists.
-        */
-       for_each_child_of_node(dev_np, cfg_np) {
-               u32 function;
-
-               ret = exynos5440_pinctrl_parse_dt_pins(pdev, cfg_np,
-                                       &pin_list, &npins);
-               if (ret) {
-                       gname = NULL;
-                       goto skip_to_pin_function;
-               }
-
-               /* derive pin group name from the node name */
-               gname = devm_kzalloc(dev, strlen(cfg_np->name) + GSUFFIX_LEN,
-                                       GFP_KERNEL);
-               if (!gname) {
-                       dev_err(dev, "failed to alloc memory for group name\n");
-                       return -ENOMEM;
-               }
-               snprintf(gname, strlen(cfg_np->name) + 4, "%s%s", cfg_np->name,
-                        GROUP_SUFFIX);
-
-               grp->name = gname;
-               grp->pins = pin_list;
-               grp->num_pins = npins;
-               grp++;
-
-skip_to_pin_function:
-               ret = of_property_read_u32(cfg_np, "samsung,exynos5440-pin-function",
-                                               &function);
-               if (ret)
-                       continue;
-
-               /* derive function name from the node name */
-               fname = devm_kzalloc(dev, strlen(cfg_np->name) + FSUFFIX_LEN,
-                                       GFP_KERNEL);
-               if (!fname) {
-                       dev_err(dev, "failed to alloc memory for func name\n");
-                       return -ENOMEM;
-               }
-               snprintf(fname, strlen(cfg_np->name) + 4, "%s%s", cfg_np->name,
-                        FUNCTION_SUFFIX);
-
-               func->name = fname;
-               func->groups = devm_kzalloc(dev, sizeof(char *), GFP_KERNEL);
-               if (!func->groups) {
-                       dev_err(dev, "failed to alloc memory for group list "
-                                       "in pin function");
-                       return -ENOMEM;
-               }
-               func->groups[0] = gname;
-               func->num_groups = gname ? 1 : 0;
-               func->function = function;
-               func++;
-               func_idx++;
-       }
-
-       priv->pin_groups = groups;
-       priv->nr_groups = grp_cnt;
-       priv->pmx_functions = functions;
-       priv->nr_functions = func_idx;
-       return 0;
-}
-
-/* register the pinctrl interface with the pinctrl subsystem */
-static int exynos5440_pinctrl_register(struct platform_device *pdev,
-                               struct exynos5440_pinctrl_priv_data *priv)
-{
-       struct device *dev = &pdev->dev;
-       struct pinctrl_desc *ctrldesc;
-       struct pinctrl_dev *pctl_dev;
-       struct pinctrl_pin_desc *pindesc, *pdesc;
-       struct pinctrl_gpio_range grange;
-       char *pin_names;
-       int pin, ret;
-
-       ctrldesc = devm_kzalloc(dev, sizeof(*ctrldesc), GFP_KERNEL);
-       if (!ctrldesc) {
-               dev_err(dev, "could not allocate memory for pinctrl desc\n");
-               return -ENOMEM;
-       }
-
-       ctrldesc->name = "exynos5440-pinctrl";
-       ctrldesc->owner = THIS_MODULE;
-       ctrldesc->pctlops = &exynos5440_pctrl_ops;
-       ctrldesc->pmxops = &exynos5440_pinmux_ops;
-       ctrldesc->confops = &exynos5440_pinconf_ops;
-
-       pindesc = devm_kzalloc(&pdev->dev, sizeof(*pindesc) *
-                               EXYNOS5440_MAX_PINS, GFP_KERNEL);
-       if (!pindesc) {
-               dev_err(&pdev->dev, "mem alloc for pin descriptors failed\n");
-               return -ENOMEM;
-       }
-       ctrldesc->pins = pindesc;
-       ctrldesc->npins = EXYNOS5440_MAX_PINS;
-
-       /* dynamically populate the pin number and pin name for pindesc */
-       for (pin = 0, pdesc = pindesc; pin < ctrldesc->npins; pin++, pdesc++)
-               pdesc->number = pin;
-
-       /*
-        * allocate space for storing the dynamically generated names for all
-        * the pins which belong to this pin-controller.
-        */
-       pin_names = devm_kzalloc(&pdev->dev, sizeof(char) * PIN_NAME_LENGTH *
-                                       ctrldesc->npins, GFP_KERNEL);
-       if (!pin_names) {
-               dev_err(&pdev->dev, "mem alloc for pin names failed\n");
-               return -ENOMEM;
-       }
-
-       /* for each pin, set the name of the pin */
-       for (pin = 0; pin < ctrldesc->npins; pin++) {
-               snprintf(pin_names, 6, "gpio%02d", pin);
-               pdesc = pindesc + pin;
-               pdesc->name = pin_names;
-               pin_names += PIN_NAME_LENGTH;
-       }
-
-       ret = exynos5440_pinctrl_parse_dt(pdev, priv);
-       if (ret)
-               return ret;
-
-       pctl_dev = pinctrl_register(ctrldesc, &pdev->dev, priv);
-       if (!pctl_dev) {
-               dev_err(&pdev->dev, "could not register pinctrl driver\n");
-               return -EINVAL;
-       }
-
-       grange.name = "exynos5440-pctrl-gpio-range";
-       grange.id = 0;
-       grange.base = 0;
-       grange.npins = EXYNOS5440_MAX_PINS;
-       grange.gc = priv->gc;
-       pinctrl_add_gpio_range(pctl_dev, &grange);
-       return 0;
-}
-
-/* register the gpiolib interface with the gpiolib subsystem */
-static int exynos5440_gpiolib_register(struct platform_device *pdev,
-                               struct exynos5440_pinctrl_priv_data *priv)
-{
-       struct gpio_chip *gc;
-       int ret;
-
-       gc = devm_kzalloc(&pdev->dev, sizeof(*gc), GFP_KERNEL);
-       if (!gc) {
-               dev_err(&pdev->dev, "mem alloc for gpio_chip failed\n");
-               return -ENOMEM;
-       }
-
-       priv->gc = gc;
-       gc->base = 0;
-       gc->ngpio = EXYNOS5440_MAX_PINS;
-       gc->dev = &pdev->dev;
-       gc->set = exynos5440_gpio_set;
-       gc->get = exynos5440_gpio_get;
-       gc->direction_input = exynos5440_gpio_direction_input;
-       gc->direction_output = exynos5440_gpio_direction_output;
-       gc->to_irq = exynos5440_gpio_to_irq;
-       gc->label = "gpiolib-exynos5440";
-       gc->owner = THIS_MODULE;
-       ret = gpiochip_add(gc);
-       if (ret) {
-               dev_err(&pdev->dev, "failed to register gpio_chip %s, error "
-                                       "code: %d\n", gc->label, ret);
-               return ret;
-       }
-
-       return 0;
-}
-
-/* unregister the gpiolib interface with the gpiolib subsystem */
-static int exynos5440_gpiolib_unregister(struct platform_device *pdev,
-                               struct exynos5440_pinctrl_priv_data *priv)
-{
-       int ret = gpiochip_remove(priv->gc);
-       if (ret) {
-               dev_err(&pdev->dev, "gpio chip remove failed\n");
-               return ret;
-       }
-       return 0;
-}
-
-static void exynos5440_gpio_irq_unmask(struct irq_data *irqd)
-{
-       struct exynos5440_pinctrl_priv_data *d;
-       unsigned long gpio_int;
-
-       d = irq_data_get_irq_chip_data(irqd);
-       gpio_int = readl(d->reg_base + GPIO_INT);
-       gpio_int |= 1 << irqd->hwirq;
-       writel(gpio_int, d->reg_base + GPIO_INT);
-}
-
-static void exynos5440_gpio_irq_mask(struct irq_data *irqd)
-{
-       struct exynos5440_pinctrl_priv_data *d;
-       unsigned long gpio_int;
-
-       d = irq_data_get_irq_chip_data(irqd);
-       gpio_int = readl(d->reg_base + GPIO_INT);
-       gpio_int &= ~(1 << irqd->hwirq);
-       writel(gpio_int, d->reg_base + GPIO_INT);
-}
-
-/* irq_chip for gpio interrupts */
-static struct irq_chip exynos5440_gpio_irq_chip = {
-       .name           = "exynos5440_gpio_irq_chip",
-       .irq_unmask     = exynos5440_gpio_irq_unmask,
-       .irq_mask       = exynos5440_gpio_irq_mask,
-};
-
-/* interrupt handler for GPIO interrupts 0..7 */
-static irqreturn_t exynos5440_gpio_irq(int irq, void *data)
-{
-       struct exynos5440_gpio_intr_data *intd = data;
-       struct exynos5440_pinctrl_priv_data *d = intd->priv;
-       int virq;
-
-       virq = irq_linear_revmap(d->irq_domain, intd->gpio_int);
-       if (!virq)
-               return IRQ_NONE;
-       generic_handle_irq(virq);
-       return IRQ_HANDLED;
-}
-
-static int exynos5440_gpio_irq_map(struct irq_domain *h, unsigned int virq,
-                                       irq_hw_number_t hw)
-{
-       struct exynos5440_pinctrl_priv_data *d = h->host_data;
-
-       irq_set_chip_data(virq, d);
-       irq_set_chip_and_handler(virq, &exynos5440_gpio_irq_chip,
-                                       handle_level_irq);
-       set_irq_flags(virq, IRQF_VALID);
-       return 0;
-}
-
-/* irq domain callbacks for gpio interrupt controller */
-static const struct irq_domain_ops exynos5440_gpio_irqd_ops = {
-       .map    = exynos5440_gpio_irq_map,
-       .xlate  = irq_domain_xlate_twocell,
-};
-
-/* setup handling of gpio interrupts */
-static int exynos5440_gpio_irq_init(struct platform_device *pdev,
-                               struct exynos5440_pinctrl_priv_data *priv)
-{
-       struct device *dev = &pdev->dev;
-       struct exynos5440_gpio_intr_data *intd;
-       int i, irq, ret;
-
-       intd = devm_kzalloc(dev, sizeof(*intd) * EXYNOS5440_MAX_GPIO_INT,
-                                       GFP_KERNEL);
-       if (!intd) {
-               dev_err(dev, "failed to allocate memory for gpio intr data\n");
-               return -ENOMEM;
-       }
-
-       for (i = 0; i < EXYNOS5440_MAX_GPIO_INT; i++) {
-               irq = irq_of_parse_and_map(dev->of_node, i);
-               if (irq <= 0) {
-                       dev_err(dev, "irq parsing failed\n");
-                       return -EINVAL;
-               }
-
-               intd->gpio_int = i;
-               intd->priv = priv;
-               ret = devm_request_irq(dev, irq, exynos5440_gpio_irq,
-                                       0, dev_name(dev), intd++);
-               if (ret) {
-                       dev_err(dev, "irq request failed\n");
-                       return -ENXIO;
-               }
-       }
-
-       priv->irq_domain = irq_domain_add_linear(dev->of_node,
-                               EXYNOS5440_MAX_GPIO_INT,
-                               &exynos5440_gpio_irqd_ops, priv);
-       if (!priv->irq_domain) {
-               dev_err(dev, "failed to create irq domain\n");
-               return -ENXIO;
-       }
-
-       return 0;
-}
-
-static int exynos5440_pinctrl_probe(struct platform_device *pdev)
-{
-       struct device *dev = &pdev->dev;
-       struct exynos5440_pinctrl_priv_data *priv;
-       struct resource *res;
-       int ret;
-
-       if (!dev->of_node) {
-               dev_err(dev, "device tree node not found\n");
-               return -ENODEV;
-       }
-
-       priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
-       if (!priv) {
-               dev_err(dev, "could not allocate memory for private data\n");
-               return -ENOMEM;
-       }
-
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       priv->reg_base = devm_ioremap_resource(&pdev->dev, res);
-       if (IS_ERR(priv->reg_base))
-               return PTR_ERR(priv->reg_base);
-
-       ret = exynos5440_gpiolib_register(pdev, priv);
-       if (ret)
-               return ret;
-
-       ret = exynos5440_pinctrl_register(pdev, priv);
-       if (ret) {
-               exynos5440_gpiolib_unregister(pdev, priv);
-               return ret;
-       }
-
-       ret = exynos5440_gpio_irq_init(pdev, priv);
-       if (ret) {
-               dev_err(dev, "failed to setup gpio interrupts\n");
-               return ret;
-       }
-
-       platform_set_drvdata(pdev, priv);
-       dev_info(dev, "EXYNOS5440 pinctrl driver registered\n");
-       return 0;
-}
-
-static const struct of_device_id exynos5440_pinctrl_dt_match[] = {
-       { .compatible = "samsung,exynos5440-pinctrl" },
-       {},
-};
-MODULE_DEVICE_TABLE(of, exynos5440_pinctrl_dt_match);
-
-static struct platform_driver exynos5440_pinctrl_driver = {
-       .probe          = exynos5440_pinctrl_probe,
-       .driver = {
-               .name   = "exynos5440-pinctrl",
-               .owner  = THIS_MODULE,
-               .of_match_table = exynos5440_pinctrl_dt_match,
-       },
-};
-
-static int __init exynos5440_pinctrl_drv_register(void)
-{
-       return platform_driver_register(&exynos5440_pinctrl_driver);
-}
-postcore_initcall(exynos5440_pinctrl_drv_register);
-
-static void __exit exynos5440_pinctrl_drv_unregister(void)
-{
-       platform_driver_unregister(&exynos5440_pinctrl_driver);
-}
-module_exit(exynos5440_pinctrl_drv_unregister);
-
-MODULE_AUTHOR("Thomas Abraham <thomas.ab@samsung.com>");
-MODULE_DESCRIPTION("Samsung EXYNOS5440 SoC pinctrl driver");
-MODULE_LICENSE("GPL v2");
index a24448e5d3996ee81a490710545626be8c83f0a2..946d594a64dddc929884d7306055afcdd63e8efc 100644 (file)
@@ -515,7 +515,7 @@ static int imx_pinctrl_parse_functions(struct device_node *np,
        /* Initialise function */
        func->name = np->name;
        func->num_groups = of_get_child_count(np);
-       if (func->num_groups <= 0) {
+       if (func->num_groups == 0) {
                dev_err(info->dev, "no groups defined in %s\n", np->full_name);
                return -EINVAL;
        }
index 815384b377b5fc192a4cdab6eba6c413e62c53fd..483420757c9fa811049cb3fd4669448b688e1805 100644 (file)
@@ -526,7 +526,7 @@ static int imx1_pinctrl_parse_functions(struct device_node *np,
        /* Initialise function */
        func->name = np->name;
        func->num_groups = of_get_child_count(np);
-       if (func->num_groups <= 0)
+       if (func->num_groups == 0)
                return -EINVAL;
 
        func->groups = devm_kzalloc(info->dev,
diff --git a/drivers/pinctrl/pinctrl-imx1.c b/drivers/pinctrl/pinctrl-imx1.c
new file mode 100644 (file)
index 0000000..533a6e5
--- /dev/null
@@ -0,0 +1,279 @@
+/*
+ * i.MX1 pinctrl driver based on imx pinmux core
+ *
+ * Copyright (C) 2014 Alexander Shiyan <shc_work@mail.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pinctrl/pinctrl.h>
+
+#include "pinctrl-imx1.h"
+
+#define PAD_ID(port, pin)      ((port) * 32 + (pin))
+#define PA     0
+#define PB     1
+#define PC     2
+#define PD     3
+
+enum imx1_pads {
+       MX1_PAD_A24             = PAD_ID(PA, 0),
+       MX1_PAD_TIN             = PAD_ID(PA, 1),
+       MX1_PAD_PWMO            = PAD_ID(PA, 2),
+       MX1_PAD_CSI_MCLK        = PAD_ID(PA, 3),
+       MX1_PAD_CSI_D0          = PAD_ID(PA, 4),
+       MX1_PAD_CSI_D1          = PAD_ID(PA, 5),
+       MX1_PAD_CSI_D2          = PAD_ID(PA, 6),
+       MX1_PAD_CSI_D3          = PAD_ID(PA, 7),
+       MX1_PAD_CSI_D4          = PAD_ID(PA, 8),
+       MX1_PAD_CSI_D5          = PAD_ID(PA, 9),
+       MX1_PAD_CSI_D6          = PAD_ID(PA, 10),
+       MX1_PAD_CSI_D7          = PAD_ID(PA, 11),
+       MX1_PAD_CSI_VSYNC       = PAD_ID(PA, 12),
+       MX1_PAD_CSI_HSYNC       = PAD_ID(PA, 13),
+       MX1_PAD_CSI_PIXCLK      = PAD_ID(PA, 14),
+       MX1_PAD_I2C_SDA         = PAD_ID(PA, 15),
+       MX1_PAD_I2C_SCL         = PAD_ID(PA, 16),
+       MX1_PAD_DTACK           = PAD_ID(PA, 17),
+       MX1_PAD_BCLK            = PAD_ID(PA, 18),
+       MX1_PAD_LBA             = PAD_ID(PA, 19),
+       MX1_PAD_ECB             = PAD_ID(PA, 20),
+       MX1_PAD_A0              = PAD_ID(PA, 21),
+       MX1_PAD_CS4             = PAD_ID(PA, 22),
+       MX1_PAD_CS5             = PAD_ID(PA, 23),
+       MX1_PAD_A16             = PAD_ID(PA, 24),
+       MX1_PAD_A17             = PAD_ID(PA, 25),
+       MX1_PAD_A18             = PAD_ID(PA, 26),
+       MX1_PAD_A19             = PAD_ID(PA, 27),
+       MX1_PAD_A20             = PAD_ID(PA, 28),
+       MX1_PAD_A21             = PAD_ID(PA, 29),
+       MX1_PAD_A22             = PAD_ID(PA, 30),
+       MX1_PAD_A23             = PAD_ID(PA, 31),
+       MX1_PAD_SD_DAT0         = PAD_ID(PB, 8),
+       MX1_PAD_SD_DAT1         = PAD_ID(PB, 9),
+       MX1_PAD_SD_DAT2         = PAD_ID(PB, 10),
+       MX1_PAD_SD_DAT3         = PAD_ID(PB, 11),
+       MX1_PAD_SD_SCLK         = PAD_ID(PB, 12),
+       MX1_PAD_SD_CMD          = PAD_ID(PB, 13),
+       MX1_PAD_SIM_SVEN        = PAD_ID(PB, 14),
+       MX1_PAD_SIM_PD          = PAD_ID(PB, 15),
+       MX1_PAD_SIM_TX          = PAD_ID(PB, 16),
+       MX1_PAD_SIM_RX          = PAD_ID(PB, 17),
+       MX1_PAD_SIM_RST         = PAD_ID(PB, 18),
+       MX1_PAD_SIM_CLK         = PAD_ID(PB, 19),
+       MX1_PAD_USBD_AFE        = PAD_ID(PB, 20),
+       MX1_PAD_USBD_OE         = PAD_ID(PB, 21),
+       MX1_PAD_USBD_RCV        = PAD_ID(PB, 22),
+       MX1_PAD_USBD_SUSPND     = PAD_ID(PB, 23),
+       MX1_PAD_USBD_VP         = PAD_ID(PB, 24),
+       MX1_PAD_USBD_VM         = PAD_ID(PB, 25),
+       MX1_PAD_USBD_VPO        = PAD_ID(PB, 26),
+       MX1_PAD_USBD_VMO        = PAD_ID(PB, 27),
+       MX1_PAD_UART2_CTS       = PAD_ID(PB, 28),
+       MX1_PAD_UART2_RTS       = PAD_ID(PB, 29),
+       MX1_PAD_UART2_TXD       = PAD_ID(PB, 30),
+       MX1_PAD_UART2_RXD       = PAD_ID(PB, 31),
+       MX1_PAD_SSI_RXFS        = PAD_ID(PC, 3),
+       MX1_PAD_SSI_RXCLK       = PAD_ID(PC, 4),
+       MX1_PAD_SSI_RXDAT       = PAD_ID(PC, 5),
+       MX1_PAD_SSI_TXDAT       = PAD_ID(PC, 6),
+       MX1_PAD_SSI_TXFS        = PAD_ID(PC, 7),
+       MX1_PAD_SSI_TXCLK       = PAD_ID(PC, 8),
+       MX1_PAD_UART1_CTS       = PAD_ID(PC, 9),
+       MX1_PAD_UART1_RTS       = PAD_ID(PC, 10),
+       MX1_PAD_UART1_TXD       = PAD_ID(PC, 11),
+       MX1_PAD_UART1_RXD       = PAD_ID(PC, 12),
+       MX1_PAD_SPI1_RDY        = PAD_ID(PC, 13),
+       MX1_PAD_SPI1_SCLK       = PAD_ID(PC, 14),
+       MX1_PAD_SPI1_SS         = PAD_ID(PC, 15),
+       MX1_PAD_SPI1_MISO       = PAD_ID(PC, 16),
+       MX1_PAD_SPI1_MOSI       = PAD_ID(PC, 17),
+       MX1_PAD_BT13            = PAD_ID(PC, 19),
+       MX1_PAD_BT12            = PAD_ID(PC, 20),
+       MX1_PAD_BT11            = PAD_ID(PC, 21),
+       MX1_PAD_BT10            = PAD_ID(PC, 22),
+       MX1_PAD_BT9             = PAD_ID(PC, 23),
+       MX1_PAD_BT8             = PAD_ID(PC, 24),
+       MX1_PAD_BT7             = PAD_ID(PC, 25),
+       MX1_PAD_BT6             = PAD_ID(PC, 26),
+       MX1_PAD_BT5             = PAD_ID(PC, 27),
+       MX1_PAD_BT4             = PAD_ID(PC, 28),
+       MX1_PAD_BT3             = PAD_ID(PC, 29),
+       MX1_PAD_BT2             = PAD_ID(PC, 30),
+       MX1_PAD_BT1             = PAD_ID(PC, 31),
+       MX1_PAD_LSCLK           = PAD_ID(PD, 6),
+       MX1_PAD_REV             = PAD_ID(PD, 7),
+       MX1_PAD_CLS             = PAD_ID(PD, 8),
+       MX1_PAD_PS              = PAD_ID(PD, 9),
+       MX1_PAD_SPL_SPR         = PAD_ID(PD, 10),
+       MX1_PAD_CONTRAST        = PAD_ID(PD, 11),
+       MX1_PAD_ACD_OE          = PAD_ID(PD, 12),
+       MX1_PAD_LP_HSYNC        = PAD_ID(PD, 13),
+       MX1_PAD_FLM_VSYNC       = PAD_ID(PD, 14),
+       MX1_PAD_LD0             = PAD_ID(PD, 15),
+       MX1_PAD_LD1             = PAD_ID(PD, 16),
+       MX1_PAD_LD2             = PAD_ID(PD, 17),
+       MX1_PAD_LD3             = PAD_ID(PD, 18),
+       MX1_PAD_LD4             = PAD_ID(PD, 19),
+       MX1_PAD_LD5             = PAD_ID(PD, 20),
+       MX1_PAD_LD6             = PAD_ID(PD, 21),
+       MX1_PAD_LD7             = PAD_ID(PD, 22),
+       MX1_PAD_LD8             = PAD_ID(PD, 23),
+       MX1_PAD_LD9             = PAD_ID(PD, 24),
+       MX1_PAD_LD10            = PAD_ID(PD, 25),
+       MX1_PAD_LD11            = PAD_ID(PD, 26),
+       MX1_PAD_LD12            = PAD_ID(PD, 27),
+       MX1_PAD_LD13            = PAD_ID(PD, 28),
+       MX1_PAD_LD14            = PAD_ID(PD, 29),
+       MX1_PAD_LD15            = PAD_ID(PD, 30),
+       MX1_PAD_TMR2OUT         = PAD_ID(PD, 31),
+};
+
+/* Pad names for the pinmux subsystem */
+static const struct pinctrl_pin_desc imx1_pinctrl_pads[] = {
+       IMX_PINCTRL_PIN(MX1_PAD_A24),
+       IMX_PINCTRL_PIN(MX1_PAD_TIN),
+       IMX_PINCTRL_PIN(MX1_PAD_PWMO),
+       IMX_PINCTRL_PIN(MX1_PAD_CSI_MCLK),
+       IMX_PINCTRL_PIN(MX1_PAD_CSI_D0),
+       IMX_PINCTRL_PIN(MX1_PAD_CSI_D1),
+       IMX_PINCTRL_PIN(MX1_PAD_CSI_D2),
+       IMX_PINCTRL_PIN(MX1_PAD_CSI_D3),
+       IMX_PINCTRL_PIN(MX1_PAD_CSI_D4),
+       IMX_PINCTRL_PIN(MX1_PAD_CSI_D5),
+       IMX_PINCTRL_PIN(MX1_PAD_CSI_D6),
+       IMX_PINCTRL_PIN(MX1_PAD_CSI_D7),
+       IMX_PINCTRL_PIN(MX1_PAD_CSI_VSYNC),
+       IMX_PINCTRL_PIN(MX1_PAD_CSI_HSYNC),
+       IMX_PINCTRL_PIN(MX1_PAD_CSI_PIXCLK),
+       IMX_PINCTRL_PIN(MX1_PAD_I2C_SDA),
+       IMX_PINCTRL_PIN(MX1_PAD_I2C_SCL),
+       IMX_PINCTRL_PIN(MX1_PAD_DTACK),
+       IMX_PINCTRL_PIN(MX1_PAD_BCLK),
+       IMX_PINCTRL_PIN(MX1_PAD_LBA),
+       IMX_PINCTRL_PIN(MX1_PAD_ECB),
+       IMX_PINCTRL_PIN(MX1_PAD_A0),
+       IMX_PINCTRL_PIN(MX1_PAD_CS4),
+       IMX_PINCTRL_PIN(MX1_PAD_CS5),
+       IMX_PINCTRL_PIN(MX1_PAD_A16),
+       IMX_PINCTRL_PIN(MX1_PAD_A17),
+       IMX_PINCTRL_PIN(MX1_PAD_A18),
+       IMX_PINCTRL_PIN(MX1_PAD_A19),
+       IMX_PINCTRL_PIN(MX1_PAD_A20),
+       IMX_PINCTRL_PIN(MX1_PAD_A21),
+       IMX_PINCTRL_PIN(MX1_PAD_A22),
+       IMX_PINCTRL_PIN(MX1_PAD_A23),
+       IMX_PINCTRL_PIN(MX1_PAD_SD_DAT0),
+       IMX_PINCTRL_PIN(MX1_PAD_SD_DAT1),
+       IMX_PINCTRL_PIN(MX1_PAD_SD_DAT2),
+       IMX_PINCTRL_PIN(MX1_PAD_SD_DAT3),
+       IMX_PINCTRL_PIN(MX1_PAD_SD_SCLK),
+       IMX_PINCTRL_PIN(MX1_PAD_SD_CMD),
+       IMX_PINCTRL_PIN(MX1_PAD_SIM_SVEN),
+       IMX_PINCTRL_PIN(MX1_PAD_SIM_PD),
+       IMX_PINCTRL_PIN(MX1_PAD_SIM_TX),
+       IMX_PINCTRL_PIN(MX1_PAD_SIM_RX),
+       IMX_PINCTRL_PIN(MX1_PAD_SIM_CLK),
+       IMX_PINCTRL_PIN(MX1_PAD_USBD_AFE),
+       IMX_PINCTRL_PIN(MX1_PAD_USBD_OE),
+       IMX_PINCTRL_PIN(MX1_PAD_USBD_RCV),
+       IMX_PINCTRL_PIN(MX1_PAD_USBD_SUSPND),
+       IMX_PINCTRL_PIN(MX1_PAD_USBD_VP),
+       IMX_PINCTRL_PIN(MX1_PAD_USBD_VM),
+       IMX_PINCTRL_PIN(MX1_PAD_USBD_VPO),
+       IMX_PINCTRL_PIN(MX1_PAD_USBD_VMO),
+       IMX_PINCTRL_PIN(MX1_PAD_UART2_CTS),
+       IMX_PINCTRL_PIN(MX1_PAD_UART2_RTS),
+       IMX_PINCTRL_PIN(MX1_PAD_UART2_TXD),
+       IMX_PINCTRL_PIN(MX1_PAD_UART2_RXD),
+       IMX_PINCTRL_PIN(MX1_PAD_SSI_RXFS),
+       IMX_PINCTRL_PIN(MX1_PAD_SSI_RXCLK),
+       IMX_PINCTRL_PIN(MX1_PAD_SSI_RXDAT),
+       IMX_PINCTRL_PIN(MX1_PAD_SSI_TXDAT),
+       IMX_PINCTRL_PIN(MX1_PAD_SSI_TXFS),
+       IMX_PINCTRL_PIN(MX1_PAD_SSI_TXCLK),
+       IMX_PINCTRL_PIN(MX1_PAD_UART1_CTS),
+       IMX_PINCTRL_PIN(MX1_PAD_UART1_RTS),
+       IMX_PINCTRL_PIN(MX1_PAD_UART1_TXD),
+       IMX_PINCTRL_PIN(MX1_PAD_UART1_RXD),
+       IMX_PINCTRL_PIN(MX1_PAD_SPI1_RDY),
+       IMX_PINCTRL_PIN(MX1_PAD_SPI1_SCLK),
+       IMX_PINCTRL_PIN(MX1_PAD_SPI1_SS),
+       IMX_PINCTRL_PIN(MX1_PAD_SPI1_MISO),
+       IMX_PINCTRL_PIN(MX1_PAD_SPI1_MOSI),
+       IMX_PINCTRL_PIN(MX1_PAD_BT13),
+       IMX_PINCTRL_PIN(MX1_PAD_BT12),
+       IMX_PINCTRL_PIN(MX1_PAD_BT11),
+       IMX_PINCTRL_PIN(MX1_PAD_BT10),
+       IMX_PINCTRL_PIN(MX1_PAD_BT9),
+       IMX_PINCTRL_PIN(MX1_PAD_BT8),
+       IMX_PINCTRL_PIN(MX1_PAD_BT7),
+       IMX_PINCTRL_PIN(MX1_PAD_BT6),
+       IMX_PINCTRL_PIN(MX1_PAD_BT5),
+       IMX_PINCTRL_PIN(MX1_PAD_BT4),
+       IMX_PINCTRL_PIN(MX1_PAD_BT3),
+       IMX_PINCTRL_PIN(MX1_PAD_BT2),
+       IMX_PINCTRL_PIN(MX1_PAD_BT1),
+       IMX_PINCTRL_PIN(MX1_PAD_LSCLK),
+       IMX_PINCTRL_PIN(MX1_PAD_REV),
+       IMX_PINCTRL_PIN(MX1_PAD_CLS),
+       IMX_PINCTRL_PIN(MX1_PAD_PS),
+       IMX_PINCTRL_PIN(MX1_PAD_SPL_SPR),
+       IMX_PINCTRL_PIN(MX1_PAD_CONTRAST),
+       IMX_PINCTRL_PIN(MX1_PAD_ACD_OE),
+       IMX_PINCTRL_PIN(MX1_PAD_LP_HSYNC),
+       IMX_PINCTRL_PIN(MX1_PAD_FLM_VSYNC),
+       IMX_PINCTRL_PIN(MX1_PAD_LD0),
+       IMX_PINCTRL_PIN(MX1_PAD_LD1),
+       IMX_PINCTRL_PIN(MX1_PAD_LD2),
+       IMX_PINCTRL_PIN(MX1_PAD_LD3),
+       IMX_PINCTRL_PIN(MX1_PAD_LD4),
+       IMX_PINCTRL_PIN(MX1_PAD_LD5),
+       IMX_PINCTRL_PIN(MX1_PAD_LD6),
+       IMX_PINCTRL_PIN(MX1_PAD_LD7),
+       IMX_PINCTRL_PIN(MX1_PAD_LD8),
+       IMX_PINCTRL_PIN(MX1_PAD_LD9),
+       IMX_PINCTRL_PIN(MX1_PAD_LD10),
+       IMX_PINCTRL_PIN(MX1_PAD_LD11),
+       IMX_PINCTRL_PIN(MX1_PAD_LD12),
+       IMX_PINCTRL_PIN(MX1_PAD_LD13),
+       IMX_PINCTRL_PIN(MX1_PAD_LD14),
+       IMX_PINCTRL_PIN(MX1_PAD_LD15),
+       IMX_PINCTRL_PIN(MX1_PAD_TMR2OUT),
+};
+
+static struct imx1_pinctrl_soc_info imx1_pinctrl_info = {
+       .pins   = imx1_pinctrl_pads,
+       .npins  = ARRAY_SIZE(imx1_pinctrl_pads),
+};
+
+static int __init imx1_pinctrl_probe(struct platform_device *pdev)
+{
+       return imx1_pinctrl_core_probe(pdev, &imx1_pinctrl_info);
+}
+
+static const struct of_device_id imx1_pinctrl_of_match[] = {
+       { .compatible = "fsl,imx1-iomuxc", },
+       { }
+};
+MODULE_DEVICE_TABLE(of, imx1_pinctrl_of_match);
+
+static struct platform_driver imx1_pinctrl_driver = {
+       .driver = {
+               .name           = "imx1-pinctrl",
+               .owner          = THIS_MODULE,
+               .of_match_table = imx1_pinctrl_of_match,
+       },
+       .remove = imx1_pinctrl_core_remove,
+};
+module_platform_driver_probe(imx1_pinctrl_driver, imx1_pinctrl_probe);
+
+MODULE_AUTHOR("Alexander Shiyan <shc_work@mail.ru>");
+MODULE_DESCRIPTION("Freescale i.MX1 pinctrl driver");
+MODULE_LICENSE("GPL");
index 417c99205bc25acc2388009b154011df74824a04..f8dfefb6996818bfc82635bfd18130c650c4d498 100644 (file)
@@ -63,10 +63,6 @@ enum imx27_pads {
        MX27_PAD_CONTRAST = PAD_ID(PA, 30),
        MX27_PAD_OE_ACD = PAD_ID(PA, 31),
 
-       MX27_PAD_UNUSED0 = PAD_ID(PB, 0),
-       MX27_PAD_UNUSED1 = PAD_ID(PB, 1),
-       MX27_PAD_UNUSED2 = PAD_ID(PB, 2),
-       MX27_PAD_UNUSED3 = PAD_ID(PB, 3),
        MX27_PAD_SD2_D0 = PAD_ID(PB, 4),
        MX27_PAD_SD2_D1 = PAD_ID(PB, 5),
        MX27_PAD_SD2_D2 = PAD_ID(PB, 6),
@@ -96,11 +92,6 @@ enum imx27_pads {
        MX27_PAD_USBH1_RXDM = PAD_ID(PB, 30),
        MX27_PAD_USBH1_RXDP = PAD_ID(PB, 31),
 
-       MX27_PAD_UNUSED4 = PAD_ID(PC, 0),
-       MX27_PAD_UNUSED5 = PAD_ID(PC, 1),
-       MX27_PAD_UNUSED6 = PAD_ID(PC, 2),
-       MX27_PAD_UNUSED7 = PAD_ID(PC, 3),
-       MX27_PAD_UNUSED8 = PAD_ID(PC, 4),
        MX27_PAD_I2C2_SDA = PAD_ID(PC, 5),
        MX27_PAD_I2C2_SCL = PAD_ID(PC, 6),
        MX27_PAD_USBOTG_DATA5 = PAD_ID(PC, 7),
@@ -188,12 +179,6 @@ enum imx27_pads {
        MX27_PAD_SD1_CLK = PAD_ID(PE, 23),
        MX27_PAD_USBOTG_CLK = PAD_ID(PE, 24),
        MX27_PAD_USBOTG_DATA7 = PAD_ID(PE, 25),
-       MX27_PAD_UNUSED9 = PAD_ID(PE, 26),
-       MX27_PAD_UNUSED10 = PAD_ID(PE, 27),
-       MX27_PAD_UNUSED11 = PAD_ID(PE, 28),
-       MX27_PAD_UNUSED12 = PAD_ID(PE, 29),
-       MX27_PAD_UNUSED13 = PAD_ID(PE, 30),
-       MX27_PAD_UNUSED14 = PAD_ID(PE, 31),
 
        MX27_PAD_NFRB = PAD_ID(PF, 0),
        MX27_PAD_NFCLE = PAD_ID(PF, 1),
@@ -219,14 +204,6 @@ enum imx27_pads {
        MX27_PAD_CS4_B = PAD_ID(PF, 21),
        MX27_PAD_CS5_B = PAD_ID(PF, 22),
        MX27_PAD_ATA_DATA15 = PAD_ID(PF, 23),
-       MX27_PAD_UNUSED15 = PAD_ID(PF, 24),
-       MX27_PAD_UNUSED16 = PAD_ID(PF, 25),
-       MX27_PAD_UNUSED17 = PAD_ID(PF, 26),
-       MX27_PAD_UNUSED18 = PAD_ID(PF, 27),
-       MX27_PAD_UNUSED19 = PAD_ID(PF, 28),
-       MX27_PAD_UNUSED20 = PAD_ID(PF, 29),
-       MX27_PAD_UNUSED21 = PAD_ID(PF, 30),
-       MX27_PAD_UNUSED22 = PAD_ID(PF, 31),
 };
 
 /* Pad names for the pinmux subsystem */
@@ -264,10 +241,6 @@ static const struct pinctrl_pin_desc imx27_pinctrl_pads[] = {
        IMX_PINCTRL_PIN(MX27_PAD_CONTRAST),
        IMX_PINCTRL_PIN(MX27_PAD_OE_ACD),
 
-       IMX_PINCTRL_PIN(MX27_PAD_UNUSED0),
-       IMX_PINCTRL_PIN(MX27_PAD_UNUSED1),
-       IMX_PINCTRL_PIN(MX27_PAD_UNUSED2),
-       IMX_PINCTRL_PIN(MX27_PAD_UNUSED3),
        IMX_PINCTRL_PIN(MX27_PAD_SD2_D0),
        IMX_PINCTRL_PIN(MX27_PAD_SD2_D1),
        IMX_PINCTRL_PIN(MX27_PAD_SD2_D2),
@@ -297,11 +270,6 @@ static const struct pinctrl_pin_desc imx27_pinctrl_pads[] = {
        IMX_PINCTRL_PIN(MX27_PAD_USBH1_RXDM),
        IMX_PINCTRL_PIN(MX27_PAD_USBH1_RXDP),
 
-       IMX_PINCTRL_PIN(MX27_PAD_UNUSED4),
-       IMX_PINCTRL_PIN(MX27_PAD_UNUSED5),
-       IMX_PINCTRL_PIN(MX27_PAD_UNUSED6),
-       IMX_PINCTRL_PIN(MX27_PAD_UNUSED7),
-       IMX_PINCTRL_PIN(MX27_PAD_UNUSED8),
        IMX_PINCTRL_PIN(MX27_PAD_I2C2_SDA),
        IMX_PINCTRL_PIN(MX27_PAD_I2C2_SCL),
        IMX_PINCTRL_PIN(MX27_PAD_USBOTG_DATA5),
@@ -389,12 +357,6 @@ static const struct pinctrl_pin_desc imx27_pinctrl_pads[] = {
        IMX_PINCTRL_PIN(MX27_PAD_SD1_CLK),
        IMX_PINCTRL_PIN(MX27_PAD_USBOTG_CLK),
        IMX_PINCTRL_PIN(MX27_PAD_USBOTG_DATA7),
-       IMX_PINCTRL_PIN(MX27_PAD_UNUSED9),
-       IMX_PINCTRL_PIN(MX27_PAD_UNUSED10),
-       IMX_PINCTRL_PIN(MX27_PAD_UNUSED11),
-       IMX_PINCTRL_PIN(MX27_PAD_UNUSED12),
-       IMX_PINCTRL_PIN(MX27_PAD_UNUSED13),
-       IMX_PINCTRL_PIN(MX27_PAD_UNUSED14),
 
        IMX_PINCTRL_PIN(MX27_PAD_NFRB),
        IMX_PINCTRL_PIN(MX27_PAD_NFCLE),
@@ -420,14 +382,6 @@ static const struct pinctrl_pin_desc imx27_pinctrl_pads[] = {
        IMX_PINCTRL_PIN(MX27_PAD_CS4_B),
        IMX_PINCTRL_PIN(MX27_PAD_CS5_B),
        IMX_PINCTRL_PIN(MX27_PAD_ATA_DATA15),
-       IMX_PINCTRL_PIN(MX27_PAD_UNUSED15),
-       IMX_PINCTRL_PIN(MX27_PAD_UNUSED16),
-       IMX_PINCTRL_PIN(MX27_PAD_UNUSED17),
-       IMX_PINCTRL_PIN(MX27_PAD_UNUSED18),
-       IMX_PINCTRL_PIN(MX27_PAD_UNUSED19),
-       IMX_PINCTRL_PIN(MX27_PAD_UNUSED20),
-       IMX_PINCTRL_PIN(MX27_PAD_UNUSED21),
-       IMX_PINCTRL_PIN(MX27_PAD_UNUSED22),
 };
 
 static struct imx1_pinctrl_soc_info imx27_pinctrl_info = {
@@ -440,12 +394,6 @@ static struct of_device_id imx27_pinctrl_of_match[] = {
        { /* sentinel */ }
 };
 
-struct imx27_pinctrl_private {
-       int num_gpio_childs;
-       struct platform_device **gpio_dev;
-       struct mxc_gpio_platform_data *gpio_pdata;
-};
-
 static int imx27_pinctrl_probe(struct platform_device *pdev)
 {
        return imx1_pinctrl_core_probe(pdev, &imx27_pinctrl_info);
diff --git a/drivers/pinctrl/pinctrl-ipq8064.c b/drivers/pinctrl/pinctrl-ipq8064.c
deleted file mode 100644 (file)
index acafea4..0000000
+++ /dev/null
@@ -1,653 +0,0 @@
-/*
- * Copyright (c) 2014, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- */
-
-#include <linux/module.h>
-#include <linux/of.h>
-#include <linux/platform_device.h>
-#include <linux/pinctrl/pinctrl.h>
-
-#include "pinctrl-msm.h"
-
-static const struct pinctrl_pin_desc ipq8064_pins[] = {
-       PINCTRL_PIN(0, "GPIO_0"),
-       PINCTRL_PIN(1, "GPIO_1"),
-       PINCTRL_PIN(2, "GPIO_2"),
-       PINCTRL_PIN(3, "GPIO_3"),
-       PINCTRL_PIN(4, "GPIO_4"),
-       PINCTRL_PIN(5, "GPIO_5"),
-       PINCTRL_PIN(6, "GPIO_6"),
-       PINCTRL_PIN(7, "GPIO_7"),
-       PINCTRL_PIN(8, "GPIO_8"),
-       PINCTRL_PIN(9, "GPIO_9"),
-       PINCTRL_PIN(10, "GPIO_10"),
-       PINCTRL_PIN(11, "GPIO_11"),
-       PINCTRL_PIN(12, "GPIO_12"),
-       PINCTRL_PIN(13, "GPIO_13"),
-       PINCTRL_PIN(14, "GPIO_14"),
-       PINCTRL_PIN(15, "GPIO_15"),
-       PINCTRL_PIN(16, "GPIO_16"),
-       PINCTRL_PIN(17, "GPIO_17"),
-       PINCTRL_PIN(18, "GPIO_18"),
-       PINCTRL_PIN(19, "GPIO_19"),
-       PINCTRL_PIN(20, "GPIO_20"),
-       PINCTRL_PIN(21, "GPIO_21"),
-       PINCTRL_PIN(22, "GPIO_22"),
-       PINCTRL_PIN(23, "GPIO_23"),
-       PINCTRL_PIN(24, "GPIO_24"),
-       PINCTRL_PIN(25, "GPIO_25"),
-       PINCTRL_PIN(26, "GPIO_26"),
-       PINCTRL_PIN(27, "GPIO_27"),
-       PINCTRL_PIN(28, "GPIO_28"),
-       PINCTRL_PIN(29, "GPIO_29"),
-       PINCTRL_PIN(30, "GPIO_30"),
-       PINCTRL_PIN(31, "GPIO_31"),
-       PINCTRL_PIN(32, "GPIO_32"),
-       PINCTRL_PIN(33, "GPIO_33"),
-       PINCTRL_PIN(34, "GPIO_34"),
-       PINCTRL_PIN(35, "GPIO_35"),
-       PINCTRL_PIN(36, "GPIO_36"),
-       PINCTRL_PIN(37, "GPIO_37"),
-       PINCTRL_PIN(38, "GPIO_38"),
-       PINCTRL_PIN(39, "GPIO_39"),
-       PINCTRL_PIN(40, "GPIO_40"),
-       PINCTRL_PIN(41, "GPIO_41"),
-       PINCTRL_PIN(42, "GPIO_42"),
-       PINCTRL_PIN(43, "GPIO_43"),
-       PINCTRL_PIN(44, "GPIO_44"),
-       PINCTRL_PIN(45, "GPIO_45"),
-       PINCTRL_PIN(46, "GPIO_46"),
-       PINCTRL_PIN(47, "GPIO_47"),
-       PINCTRL_PIN(48, "GPIO_48"),
-       PINCTRL_PIN(49, "GPIO_49"),
-       PINCTRL_PIN(50, "GPIO_50"),
-       PINCTRL_PIN(51, "GPIO_51"),
-       PINCTRL_PIN(52, "GPIO_52"),
-       PINCTRL_PIN(53, "GPIO_53"),
-       PINCTRL_PIN(54, "GPIO_54"),
-       PINCTRL_PIN(55, "GPIO_55"),
-       PINCTRL_PIN(56, "GPIO_56"),
-       PINCTRL_PIN(57, "GPIO_57"),
-       PINCTRL_PIN(58, "GPIO_58"),
-       PINCTRL_PIN(59, "GPIO_59"),
-       PINCTRL_PIN(60, "GPIO_60"),
-       PINCTRL_PIN(61, "GPIO_61"),
-       PINCTRL_PIN(62, "GPIO_62"),
-       PINCTRL_PIN(63, "GPIO_63"),
-       PINCTRL_PIN(64, "GPIO_64"),
-       PINCTRL_PIN(65, "GPIO_65"),
-       PINCTRL_PIN(66, "GPIO_66"),
-       PINCTRL_PIN(67, "GPIO_67"),
-       PINCTRL_PIN(68, "GPIO_68"),
-
-       PINCTRL_PIN(69, "SDC3_CLK"),
-       PINCTRL_PIN(70, "SDC3_CMD"),
-       PINCTRL_PIN(71, "SDC3_DATA"),
-};
-
-#define DECLARE_IPQ_GPIO_PINS(pin) static const unsigned int gpio##pin##_pins[] = { pin }
-DECLARE_IPQ_GPIO_PINS(0);
-DECLARE_IPQ_GPIO_PINS(1);
-DECLARE_IPQ_GPIO_PINS(2);
-DECLARE_IPQ_GPIO_PINS(3);
-DECLARE_IPQ_GPIO_PINS(4);
-DECLARE_IPQ_GPIO_PINS(5);
-DECLARE_IPQ_GPIO_PINS(6);
-DECLARE_IPQ_GPIO_PINS(7);
-DECLARE_IPQ_GPIO_PINS(8);
-DECLARE_IPQ_GPIO_PINS(9);
-DECLARE_IPQ_GPIO_PINS(10);
-DECLARE_IPQ_GPIO_PINS(11);
-DECLARE_IPQ_GPIO_PINS(12);
-DECLARE_IPQ_GPIO_PINS(13);
-DECLARE_IPQ_GPIO_PINS(14);
-DECLARE_IPQ_GPIO_PINS(15);
-DECLARE_IPQ_GPIO_PINS(16);
-DECLARE_IPQ_GPIO_PINS(17);
-DECLARE_IPQ_GPIO_PINS(18);
-DECLARE_IPQ_GPIO_PINS(19);
-DECLARE_IPQ_GPIO_PINS(20);
-DECLARE_IPQ_GPIO_PINS(21);
-DECLARE_IPQ_GPIO_PINS(22);
-DECLARE_IPQ_GPIO_PINS(23);
-DECLARE_IPQ_GPIO_PINS(24);
-DECLARE_IPQ_GPIO_PINS(25);
-DECLARE_IPQ_GPIO_PINS(26);
-DECLARE_IPQ_GPIO_PINS(27);
-DECLARE_IPQ_GPIO_PINS(28);
-DECLARE_IPQ_GPIO_PINS(29);
-DECLARE_IPQ_GPIO_PINS(30);
-DECLARE_IPQ_GPIO_PINS(31);
-DECLARE_IPQ_GPIO_PINS(32);
-DECLARE_IPQ_GPIO_PINS(33);
-DECLARE_IPQ_GPIO_PINS(34);
-DECLARE_IPQ_GPIO_PINS(35);
-DECLARE_IPQ_GPIO_PINS(36);
-DECLARE_IPQ_GPIO_PINS(37);
-DECLARE_IPQ_GPIO_PINS(38);
-DECLARE_IPQ_GPIO_PINS(39);
-DECLARE_IPQ_GPIO_PINS(40);
-DECLARE_IPQ_GPIO_PINS(41);
-DECLARE_IPQ_GPIO_PINS(42);
-DECLARE_IPQ_GPIO_PINS(43);
-DECLARE_IPQ_GPIO_PINS(44);
-DECLARE_IPQ_GPIO_PINS(45);
-DECLARE_IPQ_GPIO_PINS(46);
-DECLARE_IPQ_GPIO_PINS(47);
-DECLARE_IPQ_GPIO_PINS(48);
-DECLARE_IPQ_GPIO_PINS(49);
-DECLARE_IPQ_GPIO_PINS(50);
-DECLARE_IPQ_GPIO_PINS(51);
-DECLARE_IPQ_GPIO_PINS(52);
-DECLARE_IPQ_GPIO_PINS(53);
-DECLARE_IPQ_GPIO_PINS(54);
-DECLARE_IPQ_GPIO_PINS(55);
-DECLARE_IPQ_GPIO_PINS(56);
-DECLARE_IPQ_GPIO_PINS(57);
-DECLARE_IPQ_GPIO_PINS(58);
-DECLARE_IPQ_GPIO_PINS(59);
-DECLARE_IPQ_GPIO_PINS(60);
-DECLARE_IPQ_GPIO_PINS(61);
-DECLARE_IPQ_GPIO_PINS(62);
-DECLARE_IPQ_GPIO_PINS(63);
-DECLARE_IPQ_GPIO_PINS(64);
-DECLARE_IPQ_GPIO_PINS(65);
-DECLARE_IPQ_GPIO_PINS(66);
-DECLARE_IPQ_GPIO_PINS(67);
-DECLARE_IPQ_GPIO_PINS(68);
-
-static const unsigned int sdc3_clk_pins[] = { 69 };
-static const unsigned int sdc3_cmd_pins[] = { 70 };
-static const unsigned int sdc3_data_pins[] = { 71 };
-
-#define FUNCTION(fname)                                        \
-       [IPQ_MUX_##fname] = {                           \
-               .name = #fname,                         \
-               .groups = fname##_groups,               \
-               .ngroups = ARRAY_SIZE(fname##_groups),  \
-       }
-
-#define PINGROUP(id, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10) \
-       {                                               \
-               .name = "gpio" #id,                     \
-               .pins = gpio##id##_pins,                \
-               .npins = ARRAY_SIZE(gpio##id##_pins),   \
-               .funcs = (int[]){                       \
-                       IPQ_MUX_NA, /* gpio mode */     \
-                       IPQ_MUX_##f1,                   \
-                       IPQ_MUX_##f2,                   \
-                       IPQ_MUX_##f3,                   \
-                       IPQ_MUX_##f4,                   \
-                       IPQ_MUX_##f5,                   \
-                       IPQ_MUX_##f6,                   \
-                       IPQ_MUX_##f7,                   \
-                       IPQ_MUX_##f8,                   \
-                       IPQ_MUX_##f9,                   \
-                       IPQ_MUX_##f10,                  \
-               },                                      \
-               .nfuncs = 11,                           \
-               .ctl_reg = 0x1000 + 0x10 * id,          \
-               .io_reg = 0x1004 + 0x10 * id,           \
-               .intr_cfg_reg = 0x1008 + 0x10 * id,     \
-               .intr_status_reg = 0x100c + 0x10 * id,  \
-               .intr_target_reg = 0x400 + 0x4 * id,    \
-               .mux_bit = 2,                           \
-               .pull_bit = 0,                          \
-               .drv_bit = 6,                           \
-               .oe_bit = 9,                            \
-               .in_bit = 0,                            \
-               .out_bit = 1,                           \
-               .intr_enable_bit = 0,                   \
-               .intr_status_bit = 0,                   \
-               .intr_ack_high = 1,                     \
-               .intr_target_bit = 0,                   \
-               .intr_raw_status_bit = 3,               \
-               .intr_polarity_bit = 1,                 \
-               .intr_detection_bit = 2,                \
-               .intr_detection_width = 1,              \
-       }
-
-#define SDC_PINGROUP(pg_name, ctl, pull, drv)          \
-       {                                               \
-               .name = #pg_name,                       \
-               .pins = pg_name##_pins,                 \
-               .npins = ARRAY_SIZE(pg_name##_pins),    \
-               .ctl_reg = ctl,                         \
-               .io_reg = 0,                            \
-               .intr_cfg_reg = 0,                      \
-               .intr_status_reg = 0,                   \
-               .intr_target_reg = 0,                   \
-               .mux_bit = -1,                          \
-               .pull_bit = pull,                       \
-               .drv_bit = drv,                         \
-               .oe_bit = -1,                           \
-               .in_bit = -1,                           \
-               .out_bit = -1,                          \
-               .intr_enable_bit = -1,                  \
-               .intr_status_bit = -1,                  \
-               .intr_target_bit = -1,                  \
-               .intr_raw_status_bit = -1,              \
-               .intr_polarity_bit = -1,                \
-               .intr_detection_bit = -1,               \
-               .intr_detection_width = -1,             \
-       }
-
-enum ipq8064_functions {
-       IPQ_MUX_mdio,
-       IPQ_MUX_mi2s,
-       IPQ_MUX_pdm,
-       IPQ_MUX_ssbi,
-       IPQ_MUX_spmi,
-       IPQ_MUX_audio_pcm,
-       IPQ_MUX_gsbi1,
-       IPQ_MUX_gsbi2,
-       IPQ_MUX_gsbi4,
-       IPQ_MUX_gsbi5,
-       IPQ_MUX_gsbi5_spi_cs1,
-       IPQ_MUX_gsbi5_spi_cs2,
-       IPQ_MUX_gsbi5_spi_cs3,
-       IPQ_MUX_gsbi6,
-       IPQ_MUX_gsbi7,
-       IPQ_MUX_nss_spi,
-       IPQ_MUX_sdc1,
-       IPQ_MUX_spdif,
-       IPQ_MUX_nand,
-       IPQ_MUX_tsif1,
-       IPQ_MUX_tsif2,
-       IPQ_MUX_usb_fs_n,
-       IPQ_MUX_usb_fs,
-       IPQ_MUX_usb2_hsic,
-       IPQ_MUX_rgmii2,
-       IPQ_MUX_sata,
-       IPQ_MUX_pcie1_rst,
-       IPQ_MUX_pcie1_prsnt,
-       IPQ_MUX_pcie1_pwrflt,
-       IPQ_MUX_pcie1_pwren_n,
-       IPQ_MUX_pcie1_pwren,
-       IPQ_MUX_pcie1_clk_req,
-       IPQ_MUX_pcie2_rst,
-       IPQ_MUX_pcie2_prsnt,
-       IPQ_MUX_pcie2_pwrflt,
-       IPQ_MUX_pcie2_pwren_n,
-       IPQ_MUX_pcie2_pwren,
-       IPQ_MUX_pcie2_clk_req,
-       IPQ_MUX_pcie3_rst,
-       IPQ_MUX_pcie3_prsnt,
-       IPQ_MUX_pcie3_pwrflt,
-       IPQ_MUX_pcie3_pwren_n,
-       IPQ_MUX_pcie3_pwren,
-       IPQ_MUX_pcie3_clk_req,
-       IPQ_MUX_ps_hold,
-       IPQ_MUX_NA,
-};
-
-static const char * const mdio_groups[] = {
-       "gpio0", "gpio1", "gpio10", "gpio11",
-};
-
-static const char * const mi2s_groups[] = {
-       "gpio27", "gpio28", "gpio29", "gpio30", "gpio31", "gpio32",
-       "gpio33", "gpio55", "gpio56", "gpio57", "gpio58",
-};
-
-static const char * const pdm_groups[] = {
-       "gpio3", "gpio16", "gpio17", "gpio22", "gpio30", "gpio31",
-       "gpio34", "gpio35", "gpio52", "gpio55", "gpio56", "gpio58",
-       "gpio59",
-};
-
-static const char * const ssbi_groups[] = {
-       "gpio10", "gpio11",
-};
-
-static const char * const spmi_groups[] = {
-       "gpio10", "gpio11",
-};
-
-static const char * const audio_pcm_groups[] = {
-       "gpio14", "gpio15", "gpio16", "gpio17",
-};
-
-static const char * const gsbi1_groups[] = {
-       "gpio51", "gpio52", "gpio53", "gpio54",
-};
-
-static const char * const gsbi2_groups[] = {
-       "gpio22", "gpio23", "gpio24", "gpio25",
-};
-
-static const char * const gsbi4_groups[] = {
-       "gpio10", "gpio11", "gpio12", "gpio13",
-};
-
-static const char * const gsbi5_groups[] = {
-       "gpio18", "gpio19", "gpio20", "gpio21",
-};
-
-static const char * const gsbi5_spi_cs1_groups[] = {
-       "gpio6", "gpio61",
-};
-
-static const char * const gsbi5_spi_cs2_groups[] = {
-       "gpio7", "gpio62",
-};
-
-static const char * const gsbi5_spi_cs3_groups[] = {
-       "gpio2",
-};
-
-static const char * const gsbi6_groups[] = {
-       "gpio27", "gpio28", "gpio29", "gpio30", "gpio55", "gpio56",
-       "gpio57", "gpio58",
-};
-
-static const char * const gsbi7_groups[] = {
-       "gpio6", "gpio7", "gpio8", "gpio9",
-};
-
-static const char * const nss_spi_groups[] = {
-       "gpio14", "gpio15", "gpio16", "gpio17", "gpio55", "gpio56",
-       "gpio57", "gpio58",
-};
-
-static const char * const sdc1_groups[] = {
-       "gpio38", "gpio39", "gpio40", "gpio41", "gpio42", "gpio43",
-       "gpio44", "gpio45", "gpio46", "gpio47",
-};
-
-static const char * const spdif_groups[] = {
-       "gpio10", "gpio48",
-};
-
-static const char * const nand_groups[] = {
-       "gpio34", "gpio35", "gpio36", "gpio37", "gpio38", "gpio39",
-       "gpio40", "gpio41", "gpio42", "gpio43", "gpio44", "gpio45",
-       "gpio46", "gpio47",
-};
-
-static const char * const tsif1_groups[] = {
-       "gpio55", "gpio56", "gpio57", "gpio58",
-};
-
-static const char * const tsif2_groups[] = {
-       "gpio59", "gpio60", "gpio61", "gpio62",
-};
-
-static const char * const usb_fs_n_groups[] = {
-       "gpio6",
-};
-
-static const char * const usb_fs_groups[] = {
-       "gpio6", "gpio7", "gpio8",
-};
-
-static const char * const usb2_hsic_groups[] = {
-       "gpio67", "gpio68",
-};
-
-static const char * const rgmii2_groups[] = {
-       "gpio27", "gpio28", "gpio29", "gpio30", "gpio31", "gpio32",
-       "gpio51", "gpio52", "gpio59", "gpio60", "gpio61", "gpio62",
-};
-
-static const char * const sata_groups[] = {
-       "gpio10",
-};
-
-static const char * const pcie1_rst_groups[] = {
-       "gpio3",
-};
-
-static const char * const pcie1_prsnt_groups[] = {
-       "gpio3", "gpio11",
-};
-
-static const char * const pcie1_pwren_n_groups[] = {
-       "gpio4", "gpio12",
-};
-
-static const char * const pcie1_pwren_groups[] = {
-       "gpio4", "gpio12",
-};
-
-static const char * const pcie1_pwrflt_groups[] = {
-       "gpio5", "gpio13",
-};
-
-static const char * const pcie1_clk_req_groups[] = {
-       "gpio5",
-};
-
-static const char * const pcie2_rst_groups[] = {
-       "gpio48",
-};
-
-static const char * const pcie2_prsnt_groups[] = {
-       "gpio11", "gpio48",
-};
-
-static const char * const pcie2_pwren_n_groups[] = {
-       "gpio12", "gpio49",
-};
-
-static const char * const pcie2_pwren_groups[] = {
-       "gpio12", "gpio49",
-};
-
-static const char * const pcie2_pwrflt_groups[] = {
-       "gpio13", "gpio50",
-};
-
-static const char * const pcie2_clk_req_groups[] = {
-       "gpio50",
-};
-
-static const char * const pcie3_rst_groups[] = {
-       "gpio63",
-};
-
-static const char * const pcie3_prsnt_groups[] = {
-       "gpio11",
-};
-
-static const char * const pcie3_pwren_n_groups[] = {
-       "gpio12",
-};
-
-static const char * const pcie3_pwren_groups[] = {
-       "gpio12",
-};
-
-static const char * const pcie3_pwrflt_groups[] = {
-       "gpio13",
-};
-
-static const char * const pcie3_clk_req_groups[] = {
-       "gpio65",
-};
-
-static const char * const ps_hold_groups[] = {
-       "gpio26",
-};
-
-static const struct msm_function ipq8064_functions[] = {
-       FUNCTION(mdio),
-       FUNCTION(ssbi),
-       FUNCTION(spmi),
-       FUNCTION(mi2s),
-       FUNCTION(pdm),
-       FUNCTION(audio_pcm),
-       FUNCTION(gsbi1),
-       FUNCTION(gsbi2),
-       FUNCTION(gsbi4),
-       FUNCTION(gsbi5),
-       FUNCTION(gsbi5_spi_cs1),
-       FUNCTION(gsbi5_spi_cs2),
-       FUNCTION(gsbi5_spi_cs3),
-       FUNCTION(gsbi6),
-       FUNCTION(gsbi7),
-       FUNCTION(nss_spi),
-       FUNCTION(sdc1),
-       FUNCTION(spdif),
-       FUNCTION(nand),
-       FUNCTION(tsif1),
-       FUNCTION(tsif2),
-       FUNCTION(usb_fs_n),
-       FUNCTION(usb_fs),
-       FUNCTION(usb2_hsic),
-       FUNCTION(rgmii2),
-       FUNCTION(sata),
-       FUNCTION(pcie1_rst),
-       FUNCTION(pcie1_prsnt),
-       FUNCTION(pcie1_pwren_n),
-       FUNCTION(pcie1_pwren),
-       FUNCTION(pcie1_pwrflt),
-       FUNCTION(pcie1_clk_req),
-       FUNCTION(pcie2_rst),
-       FUNCTION(pcie2_prsnt),
-       FUNCTION(pcie2_pwren_n),
-       FUNCTION(pcie2_pwren),
-       FUNCTION(pcie2_pwrflt),
-       FUNCTION(pcie2_clk_req),
-       FUNCTION(pcie3_rst),
-       FUNCTION(pcie3_prsnt),
-       FUNCTION(pcie3_pwren_n),
-       FUNCTION(pcie3_pwren),
-       FUNCTION(pcie3_pwrflt),
-       FUNCTION(pcie3_clk_req),
-       FUNCTION(ps_hold),
-};
-
-static const struct msm_pingroup ipq8064_groups[] = {
-       PINGROUP(0, mdio, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(1, mdio, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(2, gsbi5_spi_cs3, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(3, pcie1_rst, pcie1_prsnt, pdm, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(4, pcie1_pwren_n, pcie1_pwren, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(5, pcie1_clk_req, pcie1_pwrflt, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(6, gsbi7, usb_fs, gsbi5_spi_cs1, usb_fs_n, NA, NA, NA, NA, NA, NA),
-       PINGROUP(7, gsbi7, usb_fs, gsbi5_spi_cs2, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(8, gsbi7, usb_fs, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(9, gsbi7, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(10, gsbi4, spdif, sata, ssbi, mdio, spmi, NA, NA, NA, NA),
-       PINGROUP(11, gsbi4, pcie2_prsnt, pcie1_prsnt, pcie3_prsnt, ssbi, mdio, spmi, NA, NA, NA),
-       PINGROUP(12, gsbi4, pcie2_pwren_n, pcie1_pwren_n, pcie3_pwren_n, pcie2_pwren, pcie1_pwren, pcie3_pwren, NA, NA, NA),
-       PINGROUP(13, gsbi4, pcie2_pwrflt, pcie1_pwrflt, pcie3_pwrflt, NA, NA, NA, NA, NA, NA),
-       PINGROUP(14, audio_pcm, nss_spi, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(15, audio_pcm, nss_spi, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(16, audio_pcm, nss_spi, pdm, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(17, audio_pcm, nss_spi, pdm, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(18, gsbi5, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(19, gsbi5, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(20, gsbi5, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(21, gsbi5, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(22, gsbi2, pdm, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(23, gsbi2, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(24, gsbi2, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(25, gsbi2, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(26, ps_hold, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(27, mi2s, rgmii2, gsbi6, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(28, mi2s, rgmii2, gsbi6, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(29, mi2s, rgmii2, gsbi6, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(30, mi2s, rgmii2, gsbi6, pdm, NA, NA, NA, NA, NA, NA),
-       PINGROUP(31, mi2s, rgmii2, pdm, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(32, mi2s, rgmii2, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(33, mi2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(34, nand, pdm, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(35, nand, pdm, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(36, nand, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(37, nand, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(38, nand, sdc1, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(39, nand, sdc1, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(40, nand, sdc1, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(41, nand, sdc1, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(42, nand, sdc1, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(43, nand, sdc1, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(44, nand, sdc1, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(45, nand, sdc1, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(46, nand, sdc1, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(47, nand, sdc1, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(48, pcie2_rst, spdif, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(49, pcie2_pwren_n, pcie2_pwren, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(50, pcie2_clk_req, pcie2_pwrflt, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(51, gsbi1, rgmii2, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(52, gsbi1, rgmii2, pdm, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(53, gsbi1, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(54, gsbi1, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(55, tsif1, mi2s, gsbi6, pdm, nss_spi, NA, NA, NA, NA, NA),
-       PINGROUP(56, tsif1, mi2s, gsbi6, pdm, nss_spi, NA, NA, NA, NA, NA),
-       PINGROUP(57, tsif1, mi2s, gsbi6, nss_spi, NA, NA, NA, NA, NA, NA),
-       PINGROUP(58, tsif1, mi2s, gsbi6, pdm, nss_spi, NA, NA, NA, NA, NA),
-       PINGROUP(59, tsif2, rgmii2, pdm, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(60, tsif2, rgmii2, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(61, tsif2, rgmii2, gsbi5_spi_cs1, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(62, tsif2, rgmii2, gsbi5_spi_cs2, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(63, pcie3_rst, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(64, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(65, pcie3_clk_req, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(66, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(67, usb2_hsic, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(68, usb2_hsic, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-       SDC_PINGROUP(sdc3_clk, 0x204a, 14, 6),
-       SDC_PINGROUP(sdc3_cmd, 0x204a, 11, 3),
-       SDC_PINGROUP(sdc3_data, 0x204a, 9, 0),
-};
-
-#define NUM_GPIO_PINGROUPS 69
-
-static const struct msm_pinctrl_soc_data ipq8064_pinctrl = {
-       .pins = ipq8064_pins,
-       .npins = ARRAY_SIZE(ipq8064_pins),
-       .functions = ipq8064_functions,
-       .nfunctions = ARRAY_SIZE(ipq8064_functions),
-       .groups = ipq8064_groups,
-       .ngroups = ARRAY_SIZE(ipq8064_groups),
-       .ngpios = NUM_GPIO_PINGROUPS,
-};
-
-static int ipq8064_pinctrl_probe(struct platform_device *pdev)
-{
-       return msm_pinctrl_probe(pdev, &ipq8064_pinctrl);
-}
-
-static const struct of_device_id ipq8064_pinctrl_of_match[] = {
-       { .compatible = "qcom,ipq8064-pinctrl", },
-       { },
-};
-
-static struct platform_driver ipq8064_pinctrl_driver = {
-       .driver = {
-               .name = "ipq8064-pinctrl",
-               .owner = THIS_MODULE,
-               .of_match_table = ipq8064_pinctrl_of_match,
-       },
-       .probe = ipq8064_pinctrl_probe,
-       .remove = msm_pinctrl_remove,
-};
-
-static int __init ipq8064_pinctrl_init(void)
-{
-       return platform_driver_register(&ipq8064_pinctrl_driver);
-}
-arch_initcall(ipq8064_pinctrl_init);
-
-static void __exit ipq8064_pinctrl_exit(void)
-{
-       platform_driver_unregister(&ipq8064_pinctrl_driver);
-}
-module_exit(ipq8064_pinctrl_exit);
-
-MODULE_AUTHOR("Andy Gross <agross@codeaurora.org>");
-MODULE_DESCRIPTION("Qualcomm IPQ8064 pinctrl driver");
-MODULE_LICENSE("GPL v2");
-MODULE_DEVICE_TABLE(of, ipq8064_pinctrl_of_match);
diff --git a/drivers/pinctrl/pinctrl-msm.c b/drivers/pinctrl/pinctrl-msm.c
deleted file mode 100644 (file)
index df6dda4..0000000
+++ /dev/null
@@ -1,939 +0,0 @@
-/*
- * Copyright (c) 2013, Sony Mobile Communications AB.
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#include <linux/err.h>
-#include <linux/io.h>
-#include <linux/module.h>
-#include <linux/of.h>
-#include <linux/platform_device.h>
-#include <linux/pinctrl/machine.h>
-#include <linux/pinctrl/pinctrl.h>
-#include <linux/pinctrl/pinmux.h>
-#include <linux/pinctrl/pinconf.h>
-#include <linux/pinctrl/pinconf-generic.h>
-#include <linux/slab.h>
-#include <linux/gpio.h>
-#include <linux/interrupt.h>
-#include <linux/spinlock.h>
-
-#include "core.h"
-#include "pinconf.h"
-#include "pinctrl-msm.h"
-#include "pinctrl-utils.h"
-
-#define MAX_NR_GPIO 300
-
-/**
- * struct msm_pinctrl - state for a pinctrl-msm device
- * @dev:            device handle.
- * @pctrl:          pinctrl handle.
- * @chip:           gpiochip handle.
- * @irq:            parent irq for the TLMM irq_chip.
- * @lock:           Spinlock to protect register resources as well
- *                  as msm_pinctrl data structures.
- * @enabled_irqs:   Bitmap of currently enabled irqs.
- * @dual_edge_irqs: Bitmap of irqs that need sw emulated dual edge
- *                  detection.
- * @soc;            Reference to soc_data of platform specific data.
- * @regs:           Base address for the TLMM register map.
- */
-struct msm_pinctrl {
-       struct device *dev;
-       struct pinctrl_dev *pctrl;
-       struct gpio_chip chip;
-       int irq;
-
-       spinlock_t lock;
-
-       DECLARE_BITMAP(dual_edge_irqs, MAX_NR_GPIO);
-       DECLARE_BITMAP(enabled_irqs, MAX_NR_GPIO);
-
-       const struct msm_pinctrl_soc_data *soc;
-       void __iomem *regs;
-};
-
-static inline struct msm_pinctrl *to_msm_pinctrl(struct gpio_chip *gc)
-{
-       return container_of(gc, struct msm_pinctrl, chip);
-}
-
-static int msm_get_groups_count(struct pinctrl_dev *pctldev)
-{
-       struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
-
-       return pctrl->soc->ngroups;
-}
-
-static const char *msm_get_group_name(struct pinctrl_dev *pctldev,
-                                     unsigned group)
-{
-       struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
-
-       return pctrl->soc->groups[group].name;
-}
-
-static int msm_get_group_pins(struct pinctrl_dev *pctldev,
-                             unsigned group,
-                             const unsigned **pins,
-                             unsigned *num_pins)
-{
-       struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
-
-       *pins = pctrl->soc->groups[group].pins;
-       *num_pins = pctrl->soc->groups[group].npins;
-       return 0;
-}
-
-static const struct pinctrl_ops msm_pinctrl_ops = {
-       .get_groups_count       = msm_get_groups_count,
-       .get_group_name         = msm_get_group_name,
-       .get_group_pins         = msm_get_group_pins,
-       .dt_node_to_map         = pinconf_generic_dt_node_to_map_group,
-       .dt_free_map            = pinctrl_utils_dt_free_map,
-};
-
-static int msm_get_functions_count(struct pinctrl_dev *pctldev)
-{
-       struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
-
-       return pctrl->soc->nfunctions;
-}
-
-static const char *msm_get_function_name(struct pinctrl_dev *pctldev,
-                                        unsigned function)
-{
-       struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
-
-       return pctrl->soc->functions[function].name;
-}
-
-static int msm_get_function_groups(struct pinctrl_dev *pctldev,
-                                  unsigned function,
-                                  const char * const **groups,
-                                  unsigned * const num_groups)
-{
-       struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
-
-       *groups = pctrl->soc->functions[function].groups;
-       *num_groups = pctrl->soc->functions[function].ngroups;
-       return 0;
-}
-
-static int msm_pinmux_enable(struct pinctrl_dev *pctldev,
-                            unsigned function,
-                            unsigned group)
-{
-       struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
-       const struct msm_pingroup *g;
-       unsigned long flags;
-       u32 val;
-       int i;
-
-       g = &pctrl->soc->groups[group];
-
-       if (WARN_ON(g->mux_bit < 0))
-               return -EINVAL;
-
-       for (i = 0; i < g->nfuncs; i++) {
-               if (g->funcs[i] == function)
-                       break;
-       }
-
-       if (WARN_ON(i == g->nfuncs))
-               return -EINVAL;
-
-       spin_lock_irqsave(&pctrl->lock, flags);
-
-       val = readl(pctrl->regs + g->ctl_reg);
-       val &= ~(0x7 << g->mux_bit);
-       val |= i << g->mux_bit;
-       writel(val, pctrl->regs + g->ctl_reg);
-
-       spin_unlock_irqrestore(&pctrl->lock, flags);
-
-       return 0;
-}
-
-static void msm_pinmux_disable(struct pinctrl_dev *pctldev,
-                              unsigned function,
-                              unsigned group)
-{
-       struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
-       const struct msm_pingroup *g;
-       unsigned long flags;
-       u32 val;
-
-       g = &pctrl->soc->groups[group];
-
-       if (WARN_ON(g->mux_bit < 0))
-               return;
-
-       spin_lock_irqsave(&pctrl->lock, flags);
-
-       /* Clear the mux bits to select gpio mode */
-       val = readl(pctrl->regs + g->ctl_reg);
-       val &= ~(0x7 << g->mux_bit);
-       writel(val, pctrl->regs + g->ctl_reg);
-
-       spin_unlock_irqrestore(&pctrl->lock, flags);
-}
-
-static const struct pinmux_ops msm_pinmux_ops = {
-       .get_functions_count    = msm_get_functions_count,
-       .get_function_name      = msm_get_function_name,
-       .get_function_groups    = msm_get_function_groups,
-       .enable                 = msm_pinmux_enable,
-       .disable                = msm_pinmux_disable,
-};
-
-static int msm_config_reg(struct msm_pinctrl *pctrl,
-                         const struct msm_pingroup *g,
-                         unsigned param,
-                         unsigned *mask,
-                         unsigned *bit)
-{
-       switch (param) {
-       case PIN_CONFIG_BIAS_DISABLE:
-       case PIN_CONFIG_BIAS_PULL_DOWN:
-       case PIN_CONFIG_BIAS_PULL_UP:
-               *bit = g->pull_bit;
-               *mask = 3;
-               break;
-       case PIN_CONFIG_DRIVE_STRENGTH:
-               *bit = g->drv_bit;
-               *mask = 7;
-               break;
-       case PIN_CONFIG_OUTPUT:
-               *bit = g->oe_bit;
-               *mask = 1;
-               break;
-       default:
-               dev_err(pctrl->dev, "Invalid config param %04x\n", param);
-               return -ENOTSUPP;
-       }
-
-       return 0;
-}
-
-static int msm_config_get(struct pinctrl_dev *pctldev,
-                         unsigned int pin,
-                         unsigned long *config)
-{
-       dev_err(pctldev->dev, "pin_config_set op not supported\n");
-       return -ENOTSUPP;
-}
-
-static int msm_config_set(struct pinctrl_dev *pctldev, unsigned int pin,
-                               unsigned long *configs, unsigned num_configs)
-{
-       dev_err(pctldev->dev, "pin_config_set op not supported\n");
-       return -ENOTSUPP;
-}
-
-#define MSM_NO_PULL    0
-#define MSM_PULL_DOWN  1
-#define MSM_PULL_UP    3
-
-static unsigned msm_regval_to_drive(u32 val)
-{
-       return (val + 1) * 2;
-}
-
-static int msm_config_group_get(struct pinctrl_dev *pctldev,
-                               unsigned int group,
-                               unsigned long *config)
-{
-       const struct msm_pingroup *g;
-       struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
-       unsigned param = pinconf_to_config_param(*config);
-       unsigned mask;
-       unsigned arg;
-       unsigned bit;
-       int ret;
-       u32 val;
-
-       g = &pctrl->soc->groups[group];
-
-       ret = msm_config_reg(pctrl, g, param, &mask, &bit);
-       if (ret < 0)
-               return ret;
-
-       val = readl(pctrl->regs + g->ctl_reg);
-       arg = (val >> bit) & mask;
-
-       /* Convert register value to pinconf value */
-       switch (param) {
-       case PIN_CONFIG_BIAS_DISABLE:
-               arg = arg == MSM_NO_PULL;
-               break;
-       case PIN_CONFIG_BIAS_PULL_DOWN:
-               arg = arg == MSM_PULL_DOWN;
-               break;
-       case PIN_CONFIG_BIAS_PULL_UP:
-               arg = arg == MSM_PULL_UP;
-               break;
-       case PIN_CONFIG_DRIVE_STRENGTH:
-               arg = msm_regval_to_drive(arg);
-               break;
-       case PIN_CONFIG_OUTPUT:
-               /* Pin is not output */
-               if (!arg)
-                       return -EINVAL;
-
-               val = readl(pctrl->regs + g->io_reg);
-               arg = !!(val & BIT(g->in_bit));
-               break;
-       default:
-               dev_err(pctrl->dev, "Unsupported config parameter: %x\n",
-                       param);
-               return -EINVAL;
-       }
-
-       *config = pinconf_to_config_packed(param, arg);
-
-       return 0;
-}
-
-static int msm_config_group_set(struct pinctrl_dev *pctldev,
-                               unsigned group,
-                               unsigned long *configs,
-                               unsigned num_configs)
-{
-       const struct msm_pingroup *g;
-       struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
-       unsigned long flags;
-       unsigned param;
-       unsigned mask;
-       unsigned arg;
-       unsigned bit;
-       int ret;
-       u32 val;
-       int i;
-
-       g = &pctrl->soc->groups[group];
-
-       for (i = 0; i < num_configs; i++) {
-               param = pinconf_to_config_param(configs[i]);
-               arg = pinconf_to_config_argument(configs[i]);
-
-               ret = msm_config_reg(pctrl, g, param, &mask, &bit);
-               if (ret < 0)
-                       return ret;
-
-               /* Convert pinconf values to register values */
-               switch (param) {
-               case PIN_CONFIG_BIAS_DISABLE:
-                       arg = MSM_NO_PULL;
-                       break;
-               case PIN_CONFIG_BIAS_PULL_DOWN:
-                       arg = MSM_PULL_DOWN;
-                       break;
-               case PIN_CONFIG_BIAS_PULL_UP:
-                       arg = MSM_PULL_UP;
-                       break;
-               case PIN_CONFIG_DRIVE_STRENGTH:
-                       /* Check for invalid values */
-                       if (arg > 16 || arg < 2 || (arg % 2) != 0)
-                               arg = -1;
-                       else
-                               arg = (arg / 2) - 1;
-                       break;
-               case PIN_CONFIG_OUTPUT:
-                       /* set output value */
-                       spin_lock_irqsave(&pctrl->lock, flags);
-                       val = readl(pctrl->regs + g->io_reg);
-                       if (arg)
-                               val |= BIT(g->out_bit);
-                       else
-                               val &= ~BIT(g->out_bit);
-                       writel(val, pctrl->regs + g->io_reg);
-                       spin_unlock_irqrestore(&pctrl->lock, flags);
-
-                       /* enable output */
-                       arg = 1;
-                       break;
-               default:
-                       dev_err(pctrl->dev, "Unsupported config parameter: %x\n",
-                               param);
-                       return -EINVAL;
-               }
-
-               /* Range-check user-supplied value */
-               if (arg & ~mask) {
-                       dev_err(pctrl->dev, "config %x: %x is invalid\n", param, arg);
-                       return -EINVAL;
-               }
-
-               spin_lock_irqsave(&pctrl->lock, flags);
-               val = readl(pctrl->regs + g->ctl_reg);
-               val &= ~(mask << bit);
-               val |= arg << bit;
-               writel(val, pctrl->regs + g->ctl_reg);
-               spin_unlock_irqrestore(&pctrl->lock, flags);
-       }
-
-       return 0;
-}
-
-static const struct pinconf_ops msm_pinconf_ops = {
-       .pin_config_get         = msm_config_get,
-       .pin_config_set         = msm_config_set,
-       .pin_config_group_get   = msm_config_group_get,
-       .pin_config_group_set   = msm_config_group_set,
-};
-
-static struct pinctrl_desc msm_pinctrl_desc = {
-       .pctlops = &msm_pinctrl_ops,
-       .pmxops = &msm_pinmux_ops,
-       .confops = &msm_pinconf_ops,
-       .owner = THIS_MODULE,
-};
-
-static int msm_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
-{
-       const struct msm_pingroup *g;
-       struct msm_pinctrl *pctrl = container_of(chip, struct msm_pinctrl, chip);
-       unsigned long flags;
-       u32 val;
-
-       g = &pctrl->soc->groups[offset];
-
-       spin_lock_irqsave(&pctrl->lock, flags);
-
-       val = readl(pctrl->regs + g->ctl_reg);
-       val &= ~BIT(g->oe_bit);
-       writel(val, pctrl->regs + g->ctl_reg);
-
-       spin_unlock_irqrestore(&pctrl->lock, flags);
-
-       return 0;
-}
-
-static int msm_gpio_direction_output(struct gpio_chip *chip, unsigned offset, int value)
-{
-       const struct msm_pingroup *g;
-       struct msm_pinctrl *pctrl = container_of(chip, struct msm_pinctrl, chip);
-       unsigned long flags;
-       u32 val;
-
-       g = &pctrl->soc->groups[offset];
-
-       spin_lock_irqsave(&pctrl->lock, flags);
-
-       val = readl(pctrl->regs + g->io_reg);
-       if (value)
-               val |= BIT(g->out_bit);
-       else
-               val &= ~BIT(g->out_bit);
-       writel(val, pctrl->regs + g->io_reg);
-
-       val = readl(pctrl->regs + g->ctl_reg);
-       val |= BIT(g->oe_bit);
-       writel(val, pctrl->regs + g->ctl_reg);
-
-       spin_unlock_irqrestore(&pctrl->lock, flags);
-
-       return 0;
-}
-
-static int msm_gpio_get(struct gpio_chip *chip, unsigned offset)
-{
-       const struct msm_pingroup *g;
-       struct msm_pinctrl *pctrl = container_of(chip, struct msm_pinctrl, chip);
-       u32 val;
-
-       g = &pctrl->soc->groups[offset];
-
-       val = readl(pctrl->regs + g->io_reg);
-       return !!(val & BIT(g->in_bit));
-}
-
-static void msm_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
-{
-       const struct msm_pingroup *g;
-       struct msm_pinctrl *pctrl = container_of(chip, struct msm_pinctrl, chip);
-       unsigned long flags;
-       u32 val;
-
-       g = &pctrl->soc->groups[offset];
-
-       spin_lock_irqsave(&pctrl->lock, flags);
-
-       val = readl(pctrl->regs + g->io_reg);
-       if (value)
-               val |= BIT(g->out_bit);
-       else
-               val &= ~BIT(g->out_bit);
-       writel(val, pctrl->regs + g->io_reg);
-
-       spin_unlock_irqrestore(&pctrl->lock, flags);
-}
-
-static int msm_gpio_request(struct gpio_chip *chip, unsigned offset)
-{
-       int gpio = chip->base + offset;
-       return pinctrl_request_gpio(gpio);
-}
-
-static void msm_gpio_free(struct gpio_chip *chip, unsigned offset)
-{
-       int gpio = chip->base + offset;
-       return pinctrl_free_gpio(gpio);
-}
-
-#ifdef CONFIG_DEBUG_FS
-#include <linux/seq_file.h>
-
-static void msm_gpio_dbg_show_one(struct seq_file *s,
-                                 struct pinctrl_dev *pctldev,
-                                 struct gpio_chip *chip,
-                                 unsigned offset,
-                                 unsigned gpio)
-{
-       const struct msm_pingroup *g;
-       struct msm_pinctrl *pctrl = container_of(chip, struct msm_pinctrl, chip);
-       unsigned func;
-       int is_out;
-       int drive;
-       int pull;
-       u32 ctl_reg;
-
-       static const char * const pulls[] = {
-               "no pull",
-               "pull down",
-               "keeper",
-               "pull up"
-       };
-
-       g = &pctrl->soc->groups[offset];
-       ctl_reg = readl(pctrl->regs + g->ctl_reg);
-
-       is_out = !!(ctl_reg & BIT(g->oe_bit));
-       func = (ctl_reg >> g->mux_bit) & 7;
-       drive = (ctl_reg >> g->drv_bit) & 7;
-       pull = (ctl_reg >> g->pull_bit) & 3;
-
-       seq_printf(s, " %-8s: %-3s %d", g->name, is_out ? "out" : "in", func);
-       seq_printf(s, " %dmA", msm_regval_to_drive(drive));
-       seq_printf(s, " %s", pulls[pull]);
-}
-
-static void msm_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
-{
-       unsigned gpio = chip->base;
-       unsigned i;
-
-       for (i = 0; i < chip->ngpio; i++, gpio++) {
-               msm_gpio_dbg_show_one(s, NULL, chip, i, gpio);
-               seq_puts(s, "\n");
-       }
-}
-
-#else
-#define msm_gpio_dbg_show NULL
-#endif
-
-static struct gpio_chip msm_gpio_template = {
-       .direction_input  = msm_gpio_direction_input,
-       .direction_output = msm_gpio_direction_output,
-       .get              = msm_gpio_get,
-       .set              = msm_gpio_set,
-       .request          = msm_gpio_request,
-       .free             = msm_gpio_free,
-       .dbg_show         = msm_gpio_dbg_show,
-};
-
-/* For dual-edge interrupts in software, since some hardware has no
- * such support:
- *
- * At appropriate moments, this function may be called to flip the polarity
- * settings of both-edge irq lines to try and catch the next edge.
- *
- * The attempt is considered successful if:
- * - the status bit goes high, indicating that an edge was caught, or
- * - the input value of the gpio doesn't change during the attempt.
- * If the value changes twice during the process, that would cause the first
- * test to fail but would force the second, as two opposite
- * transitions would cause a detection no matter the polarity setting.
- *
- * The do-loop tries to sledge-hammer closed the timing hole between
- * the initial value-read and the polarity-write - if the line value changes
- * during that window, an interrupt is lost, the new polarity setting is
- * incorrect, and the first success test will fail, causing a retry.
- *
- * Algorithm comes from Google's msmgpio driver.
- */
-static void msm_gpio_update_dual_edge_pos(struct msm_pinctrl *pctrl,
-                                         const struct msm_pingroup *g,
-                                         struct irq_data *d)
-{
-       int loop_limit = 100;
-       unsigned val, val2, intstat;
-       unsigned pol;
-
-       do {
-               val = readl(pctrl->regs + g->io_reg) & BIT(g->in_bit);
-
-               pol = readl(pctrl->regs + g->intr_cfg_reg);
-               pol ^= BIT(g->intr_polarity_bit);
-               writel(pol, pctrl->regs + g->intr_cfg_reg);
-
-               val2 = readl(pctrl->regs + g->io_reg) & BIT(g->in_bit);
-               intstat = readl(pctrl->regs + g->intr_status_reg);
-               if (intstat || (val == val2))
-                       return;
-       } while (loop_limit-- > 0);
-       dev_err(pctrl->dev, "dual-edge irq failed to stabilize, %#08x != %#08x\n",
-               val, val2);
-}
-
-static void msm_gpio_irq_mask(struct irq_data *d)
-{
-       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
-       struct msm_pinctrl *pctrl = to_msm_pinctrl(gc);
-       const struct msm_pingroup *g;
-       unsigned long flags;
-       u32 val;
-
-       g = &pctrl->soc->groups[d->hwirq];
-
-       spin_lock_irqsave(&pctrl->lock, flags);
-
-       val = readl(pctrl->regs + g->intr_cfg_reg);
-       val &= ~BIT(g->intr_enable_bit);
-       writel(val, pctrl->regs + g->intr_cfg_reg);
-
-       clear_bit(d->hwirq, pctrl->enabled_irqs);
-
-       spin_unlock_irqrestore(&pctrl->lock, flags);
-}
-
-static void msm_gpio_irq_unmask(struct irq_data *d)
-{
-       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
-       struct msm_pinctrl *pctrl = to_msm_pinctrl(gc);
-       const struct msm_pingroup *g;
-       unsigned long flags;
-       u32 val;
-
-       g = &pctrl->soc->groups[d->hwirq];
-
-       spin_lock_irqsave(&pctrl->lock, flags);
-
-       val = readl(pctrl->regs + g->intr_status_reg);
-       val &= ~BIT(g->intr_status_bit);
-       writel(val, pctrl->regs + g->intr_status_reg);
-
-       val = readl(pctrl->regs + g->intr_cfg_reg);
-       val |= BIT(g->intr_enable_bit);
-       writel(val, pctrl->regs + g->intr_cfg_reg);
-
-       set_bit(d->hwirq, pctrl->enabled_irqs);
-
-       spin_unlock_irqrestore(&pctrl->lock, flags);
-}
-
-static void msm_gpio_irq_ack(struct irq_data *d)
-{
-       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
-       struct msm_pinctrl *pctrl = to_msm_pinctrl(gc);
-       const struct msm_pingroup *g;
-       unsigned long flags;
-       u32 val;
-
-       g = &pctrl->soc->groups[d->hwirq];
-
-       spin_lock_irqsave(&pctrl->lock, flags);
-
-       val = readl(pctrl->regs + g->intr_status_reg);
-       if (g->intr_ack_high)
-               val |= BIT(g->intr_status_bit);
-       else
-               val &= ~BIT(g->intr_status_bit);
-       writel(val, pctrl->regs + g->intr_status_reg);
-
-       if (test_bit(d->hwirq, pctrl->dual_edge_irqs))
-               msm_gpio_update_dual_edge_pos(pctrl, g, d);
-
-       spin_unlock_irqrestore(&pctrl->lock, flags);
-}
-
-#define INTR_TARGET_PROC_APPS    4
-
-static int msm_gpio_irq_set_type(struct irq_data *d, unsigned int type)
-{
-       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
-       struct msm_pinctrl *pctrl = to_msm_pinctrl(gc);
-       const struct msm_pingroup *g;
-       unsigned long flags;
-       u32 val;
-
-       g = &pctrl->soc->groups[d->hwirq];
-
-       spin_lock_irqsave(&pctrl->lock, flags);
-
-       /*
-        * For hw without possibility of detecting both edges
-        */
-       if (g->intr_detection_width == 1 && type == IRQ_TYPE_EDGE_BOTH)
-               set_bit(d->hwirq, pctrl->dual_edge_irqs);
-       else
-               clear_bit(d->hwirq, pctrl->dual_edge_irqs);
-
-       /* Route interrupts to application cpu */
-       val = readl(pctrl->regs + g->intr_target_reg);
-       val &= ~(7 << g->intr_target_bit);
-       val |= INTR_TARGET_PROC_APPS << g->intr_target_bit;
-       writel(val, pctrl->regs + g->intr_target_reg);
-
-       /* Update configuration for gpio.
-        * RAW_STATUS_EN is left on for all gpio irqs. Due to the
-        * internal circuitry of TLMM, toggling the RAW_STATUS
-        * could cause the INTR_STATUS to be set for EDGE interrupts.
-        */
-       val = readl(pctrl->regs + g->intr_cfg_reg);
-       val |= BIT(g->intr_raw_status_bit);
-       if (g->intr_detection_width == 2) {
-               val &= ~(3 << g->intr_detection_bit);
-               val &= ~(1 << g->intr_polarity_bit);
-               switch (type) {
-               case IRQ_TYPE_EDGE_RISING:
-                       val |= 1 << g->intr_detection_bit;
-                       val |= BIT(g->intr_polarity_bit);
-                       break;
-               case IRQ_TYPE_EDGE_FALLING:
-                       val |= 2 << g->intr_detection_bit;
-                       val |= BIT(g->intr_polarity_bit);
-                       break;
-               case IRQ_TYPE_EDGE_BOTH:
-                       val |= 3 << g->intr_detection_bit;
-                       val |= BIT(g->intr_polarity_bit);
-                       break;
-               case IRQ_TYPE_LEVEL_LOW:
-                       break;
-               case IRQ_TYPE_LEVEL_HIGH:
-                       val |= BIT(g->intr_polarity_bit);
-                       break;
-               }
-       } else if (g->intr_detection_width == 1) {
-               val &= ~(1 << g->intr_detection_bit);
-               val &= ~(1 << g->intr_polarity_bit);
-               switch (type) {
-               case IRQ_TYPE_EDGE_RISING:
-                       val |= BIT(g->intr_detection_bit);
-                       val |= BIT(g->intr_polarity_bit);
-                       break;
-               case IRQ_TYPE_EDGE_FALLING:
-                       val |= BIT(g->intr_detection_bit);
-                       break;
-               case IRQ_TYPE_EDGE_BOTH:
-                       val |= BIT(g->intr_detection_bit);
-                       val |= BIT(g->intr_polarity_bit);
-                       break;
-               case IRQ_TYPE_LEVEL_LOW:
-                       break;
-               case IRQ_TYPE_LEVEL_HIGH:
-                       val |= BIT(g->intr_polarity_bit);
-                       break;
-               }
-       } else {
-               BUG();
-       }
-       writel(val, pctrl->regs + g->intr_cfg_reg);
-
-       if (test_bit(d->hwirq, pctrl->dual_edge_irqs))
-               msm_gpio_update_dual_edge_pos(pctrl, g, d);
-
-       spin_unlock_irqrestore(&pctrl->lock, flags);
-
-       if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH))
-               __irq_set_handler_locked(d->irq, handle_level_irq);
-       else if (type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
-               __irq_set_handler_locked(d->irq, handle_edge_irq);
-
-       return 0;
-}
-
-static int msm_gpio_irq_set_wake(struct irq_data *d, unsigned int on)
-{
-       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
-       struct msm_pinctrl *pctrl = to_msm_pinctrl(gc);
-       unsigned long flags;
-
-       spin_lock_irqsave(&pctrl->lock, flags);
-
-       irq_set_irq_wake(pctrl->irq, on);
-
-       spin_unlock_irqrestore(&pctrl->lock, flags);
-
-       return 0;
-}
-
-static struct irq_chip msm_gpio_irq_chip = {
-       .name           = "msmgpio",
-       .irq_mask       = msm_gpio_irq_mask,
-       .irq_unmask     = msm_gpio_irq_unmask,
-       .irq_ack        = msm_gpio_irq_ack,
-       .irq_set_type   = msm_gpio_irq_set_type,
-       .irq_set_wake   = msm_gpio_irq_set_wake,
-};
-
-static void msm_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
-{
-       struct gpio_chip *gc = irq_desc_get_handler_data(desc);
-       const struct msm_pingroup *g;
-       struct msm_pinctrl *pctrl = to_msm_pinctrl(gc);
-       struct irq_chip *chip = irq_get_chip(irq);
-       int irq_pin;
-       int handled = 0;
-       u32 val;
-       int i;
-
-       chained_irq_enter(chip, desc);
-
-       /*
-        * Each pin has it's own IRQ status register, so use
-        * enabled_irq bitmap to limit the number of reads.
-        */
-       for_each_set_bit(i, pctrl->enabled_irqs, pctrl->chip.ngpio) {
-               g = &pctrl->soc->groups[i];
-               val = readl(pctrl->regs + g->intr_status_reg);
-               if (val & BIT(g->intr_status_bit)) {
-                       irq_pin = irq_find_mapping(gc->irqdomain, i);
-                       generic_handle_irq(irq_pin);
-                       handled++;
-               }
-       }
-
-       /* No interrupts were flagged */
-       if (handled == 0)
-               handle_bad_irq(irq, desc);
-
-       chained_irq_exit(chip, desc);
-}
-
-static int msm_gpio_init(struct msm_pinctrl *pctrl)
-{
-       struct gpio_chip *chip;
-       int ret;
-       unsigned ngpio = pctrl->soc->ngpios;
-
-       if (WARN_ON(ngpio > MAX_NR_GPIO))
-               return -EINVAL;
-
-       chip = &pctrl->chip;
-       chip->base = 0;
-       chip->ngpio = ngpio;
-       chip->label = dev_name(pctrl->dev);
-       chip->dev = pctrl->dev;
-       chip->owner = THIS_MODULE;
-       chip->of_node = pctrl->dev->of_node;
-
-       ret = gpiochip_add(&pctrl->chip);
-       if (ret) {
-               dev_err(pctrl->dev, "Failed register gpiochip\n");
-               return ret;
-       }
-
-       ret = gpiochip_add_pin_range(&pctrl->chip, dev_name(pctrl->dev), 0, 0, chip->ngpio);
-       if (ret) {
-               dev_err(pctrl->dev, "Failed to add pin range\n");
-               return ret;
-       }
-
-       ret = gpiochip_irqchip_add(chip,
-                                  &msm_gpio_irq_chip,
-                                  0,
-                                  handle_edge_irq,
-                                  IRQ_TYPE_NONE);
-       if (ret) {
-               dev_err(pctrl->dev, "Failed to add irqchip to gpiochip\n");
-               return -ENOSYS;
-       }
-
-       gpiochip_set_chained_irqchip(chip, &msm_gpio_irq_chip, pctrl->irq,
-                                    msm_gpio_irq_handler);
-
-       return 0;
-}
-
-int msm_pinctrl_probe(struct platform_device *pdev,
-                     const struct msm_pinctrl_soc_data *soc_data)
-{
-       struct msm_pinctrl *pctrl;
-       struct resource *res;
-       int ret;
-
-       pctrl = devm_kzalloc(&pdev->dev, sizeof(*pctrl), GFP_KERNEL);
-       if (!pctrl) {
-               dev_err(&pdev->dev, "Can't allocate msm_pinctrl\n");
-               return -ENOMEM;
-       }
-       pctrl->dev = &pdev->dev;
-       pctrl->soc = soc_data;
-       pctrl->chip = msm_gpio_template;
-
-       spin_lock_init(&pctrl->lock);
-
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       pctrl->regs = devm_ioremap_resource(&pdev->dev, res);
-       if (IS_ERR(pctrl->regs))
-               return PTR_ERR(pctrl->regs);
-
-       pctrl->irq = platform_get_irq(pdev, 0);
-       if (pctrl->irq < 0) {
-               dev_err(&pdev->dev, "No interrupt defined for msmgpio\n");
-               return pctrl->irq;
-       }
-
-       msm_pinctrl_desc.name = dev_name(&pdev->dev);
-       msm_pinctrl_desc.pins = pctrl->soc->pins;
-       msm_pinctrl_desc.npins = pctrl->soc->npins;
-       pctrl->pctrl = pinctrl_register(&msm_pinctrl_desc, &pdev->dev, pctrl);
-       if (!pctrl->pctrl) {
-               dev_err(&pdev->dev, "Couldn't register pinctrl driver\n");
-               return -ENODEV;
-       }
-
-       ret = msm_gpio_init(pctrl);
-       if (ret) {
-               pinctrl_unregister(pctrl->pctrl);
-               return ret;
-       }
-
-       platform_set_drvdata(pdev, pctrl);
-
-       dev_dbg(&pdev->dev, "Probed Qualcomm pinctrl driver\n");
-
-       return 0;
-}
-EXPORT_SYMBOL(msm_pinctrl_probe);
-
-int msm_pinctrl_remove(struct platform_device *pdev)
-{
-       struct msm_pinctrl *pctrl = platform_get_drvdata(pdev);
-       int ret;
-
-       ret = gpiochip_remove(&pctrl->chip);
-       if (ret) {
-               dev_err(&pdev->dev, "Failed to remove gpiochip\n");
-               return ret;
-       }
-
-       pinctrl_unregister(pctrl->pctrl);
-
-       return 0;
-}
-EXPORT_SYMBOL(msm_pinctrl_remove);
-
diff --git a/drivers/pinctrl/pinctrl-msm.h b/drivers/pinctrl/pinctrl-msm.h
deleted file mode 100644 (file)
index 7b2a227..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (c) 2013, Sony Mobile Communications AB.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-#ifndef __PINCTRL_MSM_H__
-#define __PINCTRL_MSM_H__
-
-struct pinctrl_pin_desc;
-
-/**
- * struct msm_function - a pinmux function
- * @name:    Name of the pinmux function.
- * @groups:  List of pingroups for this function.
- * @ngroups: Number of entries in @groups.
- */
-struct msm_function {
-       const char *name;
-       const char * const *groups;
-       unsigned ngroups;
-};
-
-/**
- * struct msm_pingroup - Qualcomm pingroup definition
- * @name:                 Name of the pingroup.
- * @pins:                A list of pins assigned to this pingroup.
- * @npins:               Number of entries in @pins.
- * @funcs:                A list of pinmux functions that can be selected for
- *                        this group. The index of the selected function is used
- *                        for programming the function selector.
- *                        Entries should be indices into the groups list of the
- *                        struct msm_pinctrl_soc_data.
- * @ctl_reg:              Offset of the register holding control bits for this group.
- * @io_reg:               Offset of the register holding input/output bits for this group.
- * @intr_cfg_reg:         Offset of the register holding interrupt configuration bits.
- * @intr_status_reg:      Offset of the register holding the status bits for this group.
- * @intr_target_reg:      Offset of the register specifying routing of the interrupts
- *                        from this group.
- * @mux_bit:              Offset in @ctl_reg for the pinmux function selection.
- * @pull_bit:             Offset in @ctl_reg for the bias configuration.
- * @drv_bit:              Offset in @ctl_reg for the drive strength configuration.
- * @oe_bit:               Offset in @ctl_reg for controlling output enable.
- * @in_bit:               Offset in @io_reg for the input bit value.
- * @out_bit:              Offset in @io_reg for the output bit value.
- * @intr_enable_bit:      Offset in @intr_cfg_reg for enabling the interrupt for this group.
- * @intr_status_bit:      Offset in @intr_status_reg for reading and acking the interrupt
- *                        status.
- * @intr_target_bit:      Offset in @intr_target_reg for configuring the interrupt routing.
- * @intr_raw_status_bit:  Offset in @intr_cfg_reg for the raw status bit.
- * @intr_polarity_bit:    Offset in @intr_cfg_reg for specifying polarity of the interrupt.
- * @intr_detection_bit:   Offset in @intr_cfg_reg for specifying interrupt type.
- * @intr_detection_width: Number of bits used for specifying interrupt type,
- *                        Should be 2 for SoCs that can detect both edges in hardware,
- *                        otherwise 1.
- */
-struct msm_pingroup {
-       const char *name;
-       const unsigned *pins;
-       unsigned npins;
-
-       unsigned *funcs;
-       unsigned nfuncs;
-
-       s16 ctl_reg;
-       s16 io_reg;
-       s16 intr_cfg_reg;
-       s16 intr_status_reg;
-       s16 intr_target_reg;
-
-       unsigned mux_bit:5;
-
-       unsigned pull_bit:5;
-       unsigned drv_bit:5;
-
-       unsigned oe_bit:5;
-       unsigned in_bit:5;
-       unsigned out_bit:5;
-
-       unsigned intr_enable_bit:5;
-       unsigned intr_status_bit:5;
-       unsigned intr_ack_high:1;
-
-       unsigned intr_target_bit:5;
-       unsigned intr_raw_status_bit:5;
-       unsigned intr_polarity_bit:5;
-       unsigned intr_detection_bit:5;
-       unsigned intr_detection_width:5;
-};
-
-/**
- * struct msm_pinctrl_soc_data - Qualcomm pin controller driver configuration
- * @pins:       An array describing all pins the pin controller affects.
- * @npins:      The number of entries in @pins.
- * @functions:  An array describing all mux functions the SoC supports.
- * @nfunctions: The number of entries in @functions.
- * @groups:     An array describing all pin groups the pin SoC supports.
- * @ngroups:    The numbmer of entries in @groups.
- * @ngpio:      The number of pingroups the driver should expose as GPIOs.
- */
-struct msm_pinctrl_soc_data {
-       const struct pinctrl_pin_desc *pins;
-       unsigned npins;
-       const struct msm_function *functions;
-       unsigned nfunctions;
-       const struct msm_pingroup *groups;
-       unsigned ngroups;
-       unsigned ngpios;
-};
-
-int msm_pinctrl_probe(struct platform_device *pdev,
-                     const struct msm_pinctrl_soc_data *soc_data);
-int msm_pinctrl_remove(struct platform_device *pdev);
-
-#endif
diff --git a/drivers/pinctrl/pinctrl-msm8x74.c b/drivers/pinctrl/pinctrl-msm8x74.c
deleted file mode 100644 (file)
index 4183069..0000000
+++ /dev/null
@@ -1,1040 +0,0 @@
-/*
- * Copyright (c) 2013, Sony Mobile Communications AB.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#include <linux/module.h>
-#include <linux/of.h>
-#include <linux/platform_device.h>
-#include <linux/pinctrl/pinctrl.h>
-
-#include "pinctrl-msm.h"
-
-static const struct pinctrl_pin_desc msm8x74_pins[] = {
-       PINCTRL_PIN(0, "GPIO_0"),
-       PINCTRL_PIN(1, "GPIO_1"),
-       PINCTRL_PIN(2, "GPIO_2"),
-       PINCTRL_PIN(3, "GPIO_3"),
-       PINCTRL_PIN(4, "GPIO_4"),
-       PINCTRL_PIN(5, "GPIO_5"),
-       PINCTRL_PIN(6, "GPIO_6"),
-       PINCTRL_PIN(7, "GPIO_7"),
-       PINCTRL_PIN(8, "GPIO_8"),
-       PINCTRL_PIN(9, "GPIO_9"),
-       PINCTRL_PIN(10, "GPIO_10"),
-       PINCTRL_PIN(11, "GPIO_11"),
-       PINCTRL_PIN(12, "GPIO_12"),
-       PINCTRL_PIN(13, "GPIO_13"),
-       PINCTRL_PIN(14, "GPIO_14"),
-       PINCTRL_PIN(15, "GPIO_15"),
-       PINCTRL_PIN(16, "GPIO_16"),
-       PINCTRL_PIN(17, "GPIO_17"),
-       PINCTRL_PIN(18, "GPIO_18"),
-       PINCTRL_PIN(19, "GPIO_19"),
-       PINCTRL_PIN(20, "GPIO_20"),
-       PINCTRL_PIN(21, "GPIO_21"),
-       PINCTRL_PIN(22, "GPIO_22"),
-       PINCTRL_PIN(23, "GPIO_23"),
-       PINCTRL_PIN(24, "GPIO_24"),
-       PINCTRL_PIN(25, "GPIO_25"),
-       PINCTRL_PIN(26, "GPIO_26"),
-       PINCTRL_PIN(27, "GPIO_27"),
-       PINCTRL_PIN(28, "GPIO_28"),
-       PINCTRL_PIN(29, "GPIO_29"),
-       PINCTRL_PIN(30, "GPIO_30"),
-       PINCTRL_PIN(31, "GPIO_31"),
-       PINCTRL_PIN(32, "GPIO_32"),
-       PINCTRL_PIN(33, "GPIO_33"),
-       PINCTRL_PIN(34, "GPIO_34"),
-       PINCTRL_PIN(35, "GPIO_35"),
-       PINCTRL_PIN(36, "GPIO_36"),
-       PINCTRL_PIN(37, "GPIO_37"),
-       PINCTRL_PIN(38, "GPIO_38"),
-       PINCTRL_PIN(39, "GPIO_39"),
-       PINCTRL_PIN(40, "GPIO_40"),
-       PINCTRL_PIN(41, "GPIO_41"),
-       PINCTRL_PIN(42, "GPIO_42"),
-       PINCTRL_PIN(43, "GPIO_43"),
-       PINCTRL_PIN(44, "GPIO_44"),
-       PINCTRL_PIN(45, "GPIO_45"),
-       PINCTRL_PIN(46, "GPIO_46"),
-       PINCTRL_PIN(47, "GPIO_47"),
-       PINCTRL_PIN(48, "GPIO_48"),
-       PINCTRL_PIN(49, "GPIO_49"),
-       PINCTRL_PIN(50, "GPIO_50"),
-       PINCTRL_PIN(51, "GPIO_51"),
-       PINCTRL_PIN(52, "GPIO_52"),
-       PINCTRL_PIN(53, "GPIO_53"),
-       PINCTRL_PIN(54, "GPIO_54"),
-       PINCTRL_PIN(55, "GPIO_55"),
-       PINCTRL_PIN(56, "GPIO_56"),
-       PINCTRL_PIN(57, "GPIO_57"),
-       PINCTRL_PIN(58, "GPIO_58"),
-       PINCTRL_PIN(59, "GPIO_59"),
-       PINCTRL_PIN(60, "GPIO_60"),
-       PINCTRL_PIN(61, "GPIO_61"),
-       PINCTRL_PIN(62, "GPIO_62"),
-       PINCTRL_PIN(63, "GPIO_63"),
-       PINCTRL_PIN(64, "GPIO_64"),
-       PINCTRL_PIN(65, "GPIO_65"),
-       PINCTRL_PIN(66, "GPIO_66"),
-       PINCTRL_PIN(67, "GPIO_67"),
-       PINCTRL_PIN(68, "GPIO_68"),
-       PINCTRL_PIN(69, "GPIO_69"),
-       PINCTRL_PIN(70, "GPIO_70"),
-       PINCTRL_PIN(71, "GPIO_71"),
-       PINCTRL_PIN(72, "GPIO_72"),
-       PINCTRL_PIN(73, "GPIO_73"),
-       PINCTRL_PIN(74, "GPIO_74"),
-       PINCTRL_PIN(75, "GPIO_75"),
-       PINCTRL_PIN(76, "GPIO_76"),
-       PINCTRL_PIN(77, "GPIO_77"),
-       PINCTRL_PIN(78, "GPIO_78"),
-       PINCTRL_PIN(79, "GPIO_79"),
-       PINCTRL_PIN(80, "GPIO_80"),
-       PINCTRL_PIN(81, "GPIO_81"),
-       PINCTRL_PIN(82, "GPIO_82"),
-       PINCTRL_PIN(83, "GPIO_83"),
-       PINCTRL_PIN(84, "GPIO_84"),
-       PINCTRL_PIN(85, "GPIO_85"),
-       PINCTRL_PIN(86, "GPIO_86"),
-       PINCTRL_PIN(87, "GPIO_87"),
-       PINCTRL_PIN(88, "GPIO_88"),
-       PINCTRL_PIN(89, "GPIO_89"),
-       PINCTRL_PIN(90, "GPIO_90"),
-       PINCTRL_PIN(91, "GPIO_91"),
-       PINCTRL_PIN(92, "GPIO_92"),
-       PINCTRL_PIN(93, "GPIO_93"),
-       PINCTRL_PIN(94, "GPIO_94"),
-       PINCTRL_PIN(95, "GPIO_95"),
-       PINCTRL_PIN(96, "GPIO_96"),
-       PINCTRL_PIN(97, "GPIO_97"),
-       PINCTRL_PIN(98, "GPIO_98"),
-       PINCTRL_PIN(99, "GPIO_99"),
-       PINCTRL_PIN(100, "GPIO_100"),
-       PINCTRL_PIN(101, "GPIO_101"),
-       PINCTRL_PIN(102, "GPIO_102"),
-       PINCTRL_PIN(103, "GPIO_103"),
-       PINCTRL_PIN(104, "GPIO_104"),
-       PINCTRL_PIN(105, "GPIO_105"),
-       PINCTRL_PIN(106, "GPIO_106"),
-       PINCTRL_PIN(107, "GPIO_107"),
-       PINCTRL_PIN(108, "GPIO_108"),
-       PINCTRL_PIN(109, "GPIO_109"),
-       PINCTRL_PIN(110, "GPIO_110"),
-       PINCTRL_PIN(111, "GPIO_111"),
-       PINCTRL_PIN(112, "GPIO_112"),
-       PINCTRL_PIN(113, "GPIO_113"),
-       PINCTRL_PIN(114, "GPIO_114"),
-       PINCTRL_PIN(115, "GPIO_115"),
-       PINCTRL_PIN(116, "GPIO_116"),
-       PINCTRL_PIN(117, "GPIO_117"),
-       PINCTRL_PIN(118, "GPIO_118"),
-       PINCTRL_PIN(119, "GPIO_119"),
-       PINCTRL_PIN(120, "GPIO_120"),
-       PINCTRL_PIN(121, "GPIO_121"),
-       PINCTRL_PIN(122, "GPIO_122"),
-       PINCTRL_PIN(123, "GPIO_123"),
-       PINCTRL_PIN(124, "GPIO_124"),
-       PINCTRL_PIN(125, "GPIO_125"),
-       PINCTRL_PIN(126, "GPIO_126"),
-       PINCTRL_PIN(127, "GPIO_127"),
-       PINCTRL_PIN(128, "GPIO_128"),
-       PINCTRL_PIN(129, "GPIO_129"),
-       PINCTRL_PIN(130, "GPIO_130"),
-       PINCTRL_PIN(131, "GPIO_131"),
-       PINCTRL_PIN(132, "GPIO_132"),
-       PINCTRL_PIN(133, "GPIO_133"),
-       PINCTRL_PIN(134, "GPIO_134"),
-       PINCTRL_PIN(135, "GPIO_135"),
-       PINCTRL_PIN(136, "GPIO_136"),
-       PINCTRL_PIN(137, "GPIO_137"),
-       PINCTRL_PIN(138, "GPIO_138"),
-       PINCTRL_PIN(139, "GPIO_139"),
-       PINCTRL_PIN(140, "GPIO_140"),
-       PINCTRL_PIN(141, "GPIO_141"),
-       PINCTRL_PIN(142, "GPIO_142"),
-       PINCTRL_PIN(143, "GPIO_143"),
-       PINCTRL_PIN(144, "GPIO_144"),
-       PINCTRL_PIN(145, "GPIO_145"),
-
-       PINCTRL_PIN(146, "SDC1_CLK"),
-       PINCTRL_PIN(147, "SDC1_CMD"),
-       PINCTRL_PIN(148, "SDC1_DATA"),
-       PINCTRL_PIN(149, "SDC2_CLK"),
-       PINCTRL_PIN(150, "SDC2_CMD"),
-       PINCTRL_PIN(151, "SDC2_DATA"),
-};
-
-#define DECLARE_MSM_GPIO_PINS(pin) static const unsigned int gpio##pin##_pins[] = { pin }
-DECLARE_MSM_GPIO_PINS(0);
-DECLARE_MSM_GPIO_PINS(1);
-DECLARE_MSM_GPIO_PINS(2);
-DECLARE_MSM_GPIO_PINS(3);
-DECLARE_MSM_GPIO_PINS(4);
-DECLARE_MSM_GPIO_PINS(5);
-DECLARE_MSM_GPIO_PINS(6);
-DECLARE_MSM_GPIO_PINS(7);
-DECLARE_MSM_GPIO_PINS(8);
-DECLARE_MSM_GPIO_PINS(9);
-DECLARE_MSM_GPIO_PINS(10);
-DECLARE_MSM_GPIO_PINS(11);
-DECLARE_MSM_GPIO_PINS(12);
-DECLARE_MSM_GPIO_PINS(13);
-DECLARE_MSM_GPIO_PINS(14);
-DECLARE_MSM_GPIO_PINS(15);
-DECLARE_MSM_GPIO_PINS(16);
-DECLARE_MSM_GPIO_PINS(17);
-DECLARE_MSM_GPIO_PINS(18);
-DECLARE_MSM_GPIO_PINS(19);
-DECLARE_MSM_GPIO_PINS(20);
-DECLARE_MSM_GPIO_PINS(21);
-DECLARE_MSM_GPIO_PINS(22);
-DECLARE_MSM_GPIO_PINS(23);
-DECLARE_MSM_GPIO_PINS(24);
-DECLARE_MSM_GPIO_PINS(25);
-DECLARE_MSM_GPIO_PINS(26);
-DECLARE_MSM_GPIO_PINS(27);
-DECLARE_MSM_GPIO_PINS(28);
-DECLARE_MSM_GPIO_PINS(29);
-DECLARE_MSM_GPIO_PINS(30);
-DECLARE_MSM_GPIO_PINS(31);
-DECLARE_MSM_GPIO_PINS(32);
-DECLARE_MSM_GPIO_PINS(33);
-DECLARE_MSM_GPIO_PINS(34);
-DECLARE_MSM_GPIO_PINS(35);
-DECLARE_MSM_GPIO_PINS(36);
-DECLARE_MSM_GPIO_PINS(37);
-DECLARE_MSM_GPIO_PINS(38);
-DECLARE_MSM_GPIO_PINS(39);
-DECLARE_MSM_GPIO_PINS(40);
-DECLARE_MSM_GPIO_PINS(41);
-DECLARE_MSM_GPIO_PINS(42);
-DECLARE_MSM_GPIO_PINS(43);
-DECLARE_MSM_GPIO_PINS(44);
-DECLARE_MSM_GPIO_PINS(45);
-DECLARE_MSM_GPIO_PINS(46);
-DECLARE_MSM_GPIO_PINS(47);
-DECLARE_MSM_GPIO_PINS(48);
-DECLARE_MSM_GPIO_PINS(49);
-DECLARE_MSM_GPIO_PINS(50);
-DECLARE_MSM_GPIO_PINS(51);
-DECLARE_MSM_GPIO_PINS(52);
-DECLARE_MSM_GPIO_PINS(53);
-DECLARE_MSM_GPIO_PINS(54);
-DECLARE_MSM_GPIO_PINS(55);
-DECLARE_MSM_GPIO_PINS(56);
-DECLARE_MSM_GPIO_PINS(57);
-DECLARE_MSM_GPIO_PINS(58);
-DECLARE_MSM_GPIO_PINS(59);
-DECLARE_MSM_GPIO_PINS(60);
-DECLARE_MSM_GPIO_PINS(61);
-DECLARE_MSM_GPIO_PINS(62);
-DECLARE_MSM_GPIO_PINS(63);
-DECLARE_MSM_GPIO_PINS(64);
-DECLARE_MSM_GPIO_PINS(65);
-DECLARE_MSM_GPIO_PINS(66);
-DECLARE_MSM_GPIO_PINS(67);
-DECLARE_MSM_GPIO_PINS(68);
-DECLARE_MSM_GPIO_PINS(69);
-DECLARE_MSM_GPIO_PINS(70);
-DECLARE_MSM_GPIO_PINS(71);
-DECLARE_MSM_GPIO_PINS(72);
-DECLARE_MSM_GPIO_PINS(73);
-DECLARE_MSM_GPIO_PINS(74);
-DECLARE_MSM_GPIO_PINS(75);
-DECLARE_MSM_GPIO_PINS(76);
-DECLARE_MSM_GPIO_PINS(77);
-DECLARE_MSM_GPIO_PINS(78);
-DECLARE_MSM_GPIO_PINS(79);
-DECLARE_MSM_GPIO_PINS(80);
-DECLARE_MSM_GPIO_PINS(81);
-DECLARE_MSM_GPIO_PINS(82);
-DECLARE_MSM_GPIO_PINS(83);
-DECLARE_MSM_GPIO_PINS(84);
-DECLARE_MSM_GPIO_PINS(85);
-DECLARE_MSM_GPIO_PINS(86);
-DECLARE_MSM_GPIO_PINS(87);
-DECLARE_MSM_GPIO_PINS(88);
-DECLARE_MSM_GPIO_PINS(89);
-DECLARE_MSM_GPIO_PINS(90);
-DECLARE_MSM_GPIO_PINS(91);
-DECLARE_MSM_GPIO_PINS(92);
-DECLARE_MSM_GPIO_PINS(93);
-DECLARE_MSM_GPIO_PINS(94);
-DECLARE_MSM_GPIO_PINS(95);
-DECLARE_MSM_GPIO_PINS(96);
-DECLARE_MSM_GPIO_PINS(97);
-DECLARE_MSM_GPIO_PINS(98);
-DECLARE_MSM_GPIO_PINS(99);
-DECLARE_MSM_GPIO_PINS(100);
-DECLARE_MSM_GPIO_PINS(101);
-DECLARE_MSM_GPIO_PINS(102);
-DECLARE_MSM_GPIO_PINS(103);
-DECLARE_MSM_GPIO_PINS(104);
-DECLARE_MSM_GPIO_PINS(105);
-DECLARE_MSM_GPIO_PINS(106);
-DECLARE_MSM_GPIO_PINS(107);
-DECLARE_MSM_GPIO_PINS(108);
-DECLARE_MSM_GPIO_PINS(109);
-DECLARE_MSM_GPIO_PINS(110);
-DECLARE_MSM_GPIO_PINS(111);
-DECLARE_MSM_GPIO_PINS(112);
-DECLARE_MSM_GPIO_PINS(113);
-DECLARE_MSM_GPIO_PINS(114);
-DECLARE_MSM_GPIO_PINS(115);
-DECLARE_MSM_GPIO_PINS(116);
-DECLARE_MSM_GPIO_PINS(117);
-DECLARE_MSM_GPIO_PINS(118);
-DECLARE_MSM_GPIO_PINS(119);
-DECLARE_MSM_GPIO_PINS(120);
-DECLARE_MSM_GPIO_PINS(121);
-DECLARE_MSM_GPIO_PINS(122);
-DECLARE_MSM_GPIO_PINS(123);
-DECLARE_MSM_GPIO_PINS(124);
-DECLARE_MSM_GPIO_PINS(125);
-DECLARE_MSM_GPIO_PINS(126);
-DECLARE_MSM_GPIO_PINS(127);
-DECLARE_MSM_GPIO_PINS(128);
-DECLARE_MSM_GPIO_PINS(129);
-DECLARE_MSM_GPIO_PINS(130);
-DECLARE_MSM_GPIO_PINS(131);
-DECLARE_MSM_GPIO_PINS(132);
-DECLARE_MSM_GPIO_PINS(133);
-DECLARE_MSM_GPIO_PINS(134);
-DECLARE_MSM_GPIO_PINS(135);
-DECLARE_MSM_GPIO_PINS(136);
-DECLARE_MSM_GPIO_PINS(137);
-DECLARE_MSM_GPIO_PINS(138);
-DECLARE_MSM_GPIO_PINS(139);
-DECLARE_MSM_GPIO_PINS(140);
-DECLARE_MSM_GPIO_PINS(141);
-DECLARE_MSM_GPIO_PINS(142);
-DECLARE_MSM_GPIO_PINS(143);
-DECLARE_MSM_GPIO_PINS(144);
-DECLARE_MSM_GPIO_PINS(145);
-
-static const unsigned int sdc1_clk_pins[] = { 146 };
-static const unsigned int sdc1_cmd_pins[] = { 147 };
-static const unsigned int sdc1_data_pins[] = { 148 };
-static const unsigned int sdc2_clk_pins[] = { 149 };
-static const unsigned int sdc2_cmd_pins[] = { 150 };
-static const unsigned int sdc2_data_pins[] = { 151 };
-
-#define FUNCTION(fname)                                        \
-       [MSM_MUX_##fname] = {                           \
-               .name = #fname,                         \
-               .groups = fname##_groups,               \
-               .ngroups = ARRAY_SIZE(fname##_groups),  \
-       }
-
-#define PINGROUP(id, f1, f2, f3, f4, f5, f6, f7)       \
-       {                                               \
-               .name = "gpio" #id,                     \
-               .pins = gpio##id##_pins,                \
-               .npins = ARRAY_SIZE(gpio##id##_pins),   \
-               .funcs = (int[]){                       \
-                       MSM_MUX_NA, /* gpio mode */     \
-                       MSM_MUX_##f1,                   \
-                       MSM_MUX_##f2,                   \
-                       MSM_MUX_##f3,                   \
-                       MSM_MUX_##f4,                   \
-                       MSM_MUX_##f5,                   \
-                       MSM_MUX_##f6,                   \
-                       MSM_MUX_##f7                    \
-               },                                      \
-               .nfuncs = 8,                            \
-               .ctl_reg = 0x1000 + 0x10 * id,          \
-               .io_reg = 0x1004 + 0x10 * id,           \
-               .intr_cfg_reg = 0x1008 + 0x10 * id,     \
-               .intr_status_reg = 0x100c + 0x10 * id,  \
-               .intr_target_reg = 0x1008 + 0x10 * id,  \
-               .mux_bit = 2,                           \
-               .pull_bit = 0,                          \
-               .drv_bit = 6,                           \
-               .oe_bit = 9,                            \
-               .in_bit = 0,                            \
-               .out_bit = 1,                           \
-               .intr_enable_bit = 0,                   \
-               .intr_status_bit = 0,                   \
-               .intr_target_bit = 5,                   \
-               .intr_raw_status_bit = 4,               \
-               .intr_polarity_bit = 1,                 \
-               .intr_detection_bit = 2,                \
-               .intr_detection_width = 2,              \
-       }
-
-#define SDC_PINGROUP(pg_name, ctl, pull, drv)          \
-       {                                               \
-               .name = #pg_name,                       \
-               .pins = pg_name##_pins,                 \
-               .npins = ARRAY_SIZE(pg_name##_pins),    \
-               .ctl_reg = ctl,                         \
-               .io_reg = 0,                            \
-               .intr_cfg_reg = 0,                      \
-               .intr_status_reg = 0,                   \
-               .intr_target_reg = 0,                   \
-               .mux_bit = -1,                          \
-               .pull_bit = pull,                       \
-               .drv_bit = drv,                         \
-               .oe_bit = -1,                           \
-               .in_bit = -1,                           \
-               .out_bit = -1,                          \
-               .intr_enable_bit = -1,                  \
-               .intr_status_bit = -1,                  \
-               .intr_target_bit = -1,                  \
-               .intr_raw_status_bit = -1,              \
-               .intr_polarity_bit = -1,                \
-               .intr_detection_bit = -1,               \
-               .intr_detection_width = -1,             \
-       }
-
-/*
- * TODO: Add the rest of the possible functions and fill out
- * the pingroup table below.
- */
-enum msm8x74_functions {
-       MSM_MUX_cci_i2c0,
-       MSM_MUX_cci_i2c1,
-       MSM_MUX_blsp_i2c1,
-       MSM_MUX_blsp_i2c2,
-       MSM_MUX_blsp_i2c3,
-       MSM_MUX_blsp_i2c4,
-       MSM_MUX_blsp_i2c5,
-       MSM_MUX_blsp_i2c6,
-       MSM_MUX_blsp_i2c7,
-       MSM_MUX_blsp_i2c8,
-       MSM_MUX_blsp_i2c9,
-       MSM_MUX_blsp_i2c10,
-       MSM_MUX_blsp_i2c11,
-       MSM_MUX_blsp_i2c12,
-       MSM_MUX_blsp_spi1,
-       MSM_MUX_blsp_spi1_cs1,
-       MSM_MUX_blsp_spi1_cs2,
-       MSM_MUX_blsp_spi1_cs3,
-       MSM_MUX_blsp_spi2,
-       MSM_MUX_blsp_spi2_cs1,
-       MSM_MUX_blsp_spi2_cs2,
-       MSM_MUX_blsp_spi2_cs3,
-       MSM_MUX_blsp_spi3,
-       MSM_MUX_blsp_spi4,
-       MSM_MUX_blsp_spi5,
-       MSM_MUX_blsp_spi6,
-       MSM_MUX_blsp_spi7,
-       MSM_MUX_blsp_spi8,
-       MSM_MUX_blsp_spi9,
-       MSM_MUX_blsp_spi10,
-       MSM_MUX_blsp_spi10_cs1,
-       MSM_MUX_blsp_spi10_cs2,
-       MSM_MUX_blsp_spi10_cs3,
-       MSM_MUX_blsp_spi11,
-       MSM_MUX_blsp_spi12,
-       MSM_MUX_blsp_uart1,
-       MSM_MUX_blsp_uart2,
-       MSM_MUX_blsp_uart3,
-       MSM_MUX_blsp_uart4,
-       MSM_MUX_blsp_uart5,
-       MSM_MUX_blsp_uart6,
-       MSM_MUX_blsp_uart7,
-       MSM_MUX_blsp_uart8,
-       MSM_MUX_blsp_uart9,
-       MSM_MUX_blsp_uart10,
-       MSM_MUX_blsp_uart11,
-       MSM_MUX_blsp_uart12,
-       MSM_MUX_blsp_uim1,
-       MSM_MUX_blsp_uim2,
-       MSM_MUX_blsp_uim3,
-       MSM_MUX_blsp_uim4,
-       MSM_MUX_blsp_uim5,
-       MSM_MUX_blsp_uim6,
-       MSM_MUX_blsp_uim7,
-       MSM_MUX_blsp_uim8,
-       MSM_MUX_blsp_uim9,
-       MSM_MUX_blsp_uim10,
-       MSM_MUX_blsp_uim11,
-       MSM_MUX_blsp_uim12,
-       MSM_MUX_uim1,
-       MSM_MUX_uim2,
-       MSM_MUX_uim_batt_alarm,
-       MSM_MUX_sdc3,
-       MSM_MUX_sdc4,
-       MSM_MUX_gcc_gp_clk1,
-       MSM_MUX_gcc_gp_clk2,
-       MSM_MUX_gcc_gp_clk3,
-       MSM_MUX_qua_mi2s,
-       MSM_MUX_pri_mi2s,
-       MSM_MUX_spkr_mi2s,
-       MSM_MUX_ter_mi2s,
-       MSM_MUX_sec_mi2s,
-       MSM_MUX_hdmi_cec,
-       MSM_MUX_hdmi_ddc,
-       MSM_MUX_hdmi_hpd,
-       MSM_MUX_edp_hpd,
-       MSM_MUX_mdp_vsync,
-       MSM_MUX_cam_mclk0,
-       MSM_MUX_cam_mclk1,
-       MSM_MUX_cam_mclk2,
-       MSM_MUX_cam_mclk3,
-       MSM_MUX_cci_timer0,
-       MSM_MUX_cci_timer1,
-       MSM_MUX_cci_timer2,
-       MSM_MUX_cci_timer3,
-       MSM_MUX_cci_timer4,
-       MSM_MUX_cci_async_in0,
-       MSM_MUX_cci_async_in1,
-       MSM_MUX_cci_async_in2,
-       MSM_MUX_gp_pdm0,
-       MSM_MUX_gp_pdm1,
-       MSM_MUX_gp_pdm2,
-       MSM_MUX_gp0_clk,
-       MSM_MUX_gp1_clk,
-       MSM_MUX_gp_mn,
-       MSM_MUX_tsif1,
-       MSM_MUX_tsif2,
-       MSM_MUX_hsic,
-       MSM_MUX_grfc,
-       MSM_MUX_audio_ref_clk,
-       MSM_MUX_bt,
-       MSM_MUX_fm,
-       MSM_MUX_wlan,
-       MSM_MUX_slimbus,
-       MSM_MUX_NA,
-};
-
-static const char * const blsp_uart1_groups[] = {
-       "gpio0", "gpio1", "gpio2", "gpio3"
-};
-static const char * const blsp_uim1_groups[] = { "gpio0", "gpio1" };
-static const char * const blsp_i2c1_groups[] = { "gpio2", "gpio3" };
-static const char * const blsp_spi1_groups[] = {
-       "gpio0", "gpio1", "gpio2", "gpio3"
-};
-static const char * const blsp_spi1_cs1_groups[] = { "gpio8" };
-static const char * const blsp_spi1_cs2_groups[] = { "gpio9", "gpio11" };
-static const char * const blsp_spi1_cs3_groups[] = { "gpio10" };
-
-static const char * const blsp_uart2_groups[] = {
-       "gpio4", "gpio5", "gpio6", "gpio7"
-};
-static const char * const blsp_uim2_groups[] = { "gpio4", "gpio5" };
-static const char * const blsp_i2c2_groups[] = { "gpio6", "gpio7" };
-static const char * const blsp_spi2_groups[] = {
-       "gpio4", "gpio5", "gpio6", "gpio7"
-};
-static const char * const blsp_spi2_cs1_groups[] = { "gpio53", "gpio62" };
-static const char * const blsp_spi2_cs2_groups[] = { "gpio54", "gpio63" };
-static const char * const blsp_spi2_cs3_groups[] = { "gpio66" };
-
-static const char * const blsp_uart3_groups[] = {
-       "gpio8", "gpio9", "gpio10", "gpio11"
-};
-static const char * const blsp_uim3_groups[] = { "gpio8", "gpio9" };
-static const char * const blsp_i2c3_groups[] = { "gpio10", "gpio11" };
-static const char * const blsp_spi3_groups[] = {
-       "gpio8", "gpio9", "gpio10", "gpio11"
-};
-
-static const char * const cci_i2c0_groups[] = { "gpio19", "gpio20" };
-static const char * const cci_i2c1_groups[] = { "gpio21", "gpio22" };
-
-static const char * const blsp_uart4_groups[] = {
-       "gpio19", "gpio20", "gpio21", "gpio22"
-};
-static const char * const blsp_uim4_groups[] = { "gpio19", "gpio20" };
-static const char * const blsp_i2c4_groups[] = { "gpio21", "gpio22" };
-static const char * const blsp_spi4_groups[] = {
-       "gpio19", "gpio20", "gpio21", "gpio22"
-};
-
-static const char * const blsp_uart5_groups[] = {
-       "gpio23", "gpio24", "gpio25", "gpio26"
-};
-static const char * const blsp_uim5_groups[] = { "gpio23", "gpio24" };
-static const char * const blsp_i2c5_groups[] = { "gpio25", "gpio26" };
-static const char * const blsp_spi5_groups[] = {
-       "gpio23", "gpio24", "gpio25", "gpio26"
-};
-
-static const char * const blsp_uart6_groups[] = {
-       "gpio27", "gpio28", "gpio29", "gpio30"
-};
-static const char * const blsp_uim6_groups[] = { "gpio27", "gpio28" };
-static const char * const blsp_i2c6_groups[] = { "gpio29", "gpio30" };
-static const char * const blsp_spi6_groups[] = {
-       "gpio27", "gpio28", "gpio29", "gpio30"
-};
-
-static const char * const blsp_uart7_groups[] = {
-       "gpio41", "gpio42", "gpio43", "gpio44"
-};
-static const char * const blsp_uim7_groups[] = { "gpio41", "gpio42" };
-static const char * const blsp_i2c7_groups[] = { "gpio43", "gpio44" };
-static const char * const blsp_spi7_groups[] = {
-       "gpio41", "gpio42", "gpio43", "gpio44"
-};
-
-static const char * const blsp_uart8_groups[] = {
-       "gpio45", "gpio46", "gpio47", "gpio48"
-};
-static const char * const blsp_uim8_groups[] = { "gpio45", "gpio46" };
-static const char * const blsp_i2c8_groups[] = { "gpio47", "gpio48" };
-static const char * const blsp_spi8_groups[] = {
-       "gpio45", "gpio46", "gpio47", "gpio48"
-};
-
-static const char * const blsp_uart9_groups[] = {
-       "gpio49", "gpio50", "gpio51", "gpio52"
-};
-static const char * const blsp_uim9_groups[] = { "gpio49", "gpio50" };
-static const char * const blsp_i2c9_groups[] = { "gpio51", "gpio52" };
-static const char * const blsp_spi9_groups[] = {
-       "gpio49", "gpio50", "gpio51", "gpio52"
-};
-
-static const char * const blsp_uart10_groups[] = {
-       "gpio53", "gpio54", "gpio55", "gpio56"
-};
-static const char * const blsp_uim10_groups[] = { "gpio53", "gpio54" };
-static const char * const blsp_i2c10_groups[] = { "gpio55", "gpio56" };
-static const char * const blsp_spi10_groups[] = {
-       "gpio53", "gpio54", "gpio55", "gpio56"
-};
-static const char * const blsp_spi10_cs1_groups[] = { "gpio47", "gpio67" };
-static const char * const blsp_spi10_cs2_groups[] = { "gpio48", "gpio68" };
-static const char * const blsp_spi10_cs3_groups[] = { "gpio90" };
-
-static const char * const blsp_uart11_groups[] = {
-       "gpio81", "gpio82", "gpio83", "gpio84"
-};
-static const char * const blsp_uim11_groups[] = { "gpio81", "gpio82" };
-static const char * const blsp_i2c11_groups[] = { "gpio83", "gpio84" };
-static const char * const blsp_spi11_groups[] = {
-       "gpio81", "gpio82", "gpio83", "gpio84"
-};
-
-static const char * const blsp_uart12_groups[] = {
-       "gpio85", "gpio86", "gpio87", "gpio88"
-};
-static const char * const blsp_uim12_groups[] = { "gpio85", "gpio86" };
-static const char * const blsp_i2c12_groups[] = { "gpio87", "gpio88" };
-static const char * const blsp_spi12_groups[] = {
-       "gpio85", "gpio86", "gpio87", "gpio88"
-};
-
-static const char * const uim1_groups[] = {
-       "gpio97", "gpio98", "gpio99", "gpio100"
-};
-
-static const char * const uim2_groups[] = {
-       "gpio49", "gpio50", "gpio51", "gpio52"
-};
-
-static const char * const uim_batt_alarm_groups[] = { "gpio101" };
-
-static const char * const sdc3_groups[] = {
-       "gpio35", "gpio36", "gpio37", "gpio38", "gpio39", "gpio40"
-};
-
-static const char * const sdc4_groups[] = {
-       "gpio91", "gpio92", "gpio93", "gpio94", "gpio95", "gpio96"
-};
-
-static const char * const gp0_clk_groups[] = { "gpio26" };
-static const char * const gp1_clk_groups[] = { "gpio27", "gpio57", "gpio78" };
-static const char * const gp_mn_groups[] = { "gpio29" };
-static const char * const gcc_gp_clk1_groups[] = { "gpio57", "gpio78" };
-static const char * const gcc_gp_clk2_groups[] = { "gpio58", "gpio81" };
-static const char * const gcc_gp_clk3_groups[] = { "gpio59", "gpio82" };
-
-static const char * const qua_mi2s_groups[] = {
-       "gpio57", "gpio58", "gpio59", "gpio60", "gpio61", "gpio62", "gpio63",
-};
-
-static const char * const pri_mi2s_groups[] = {
-       "gpio64", "gpio65", "gpio66", "gpio67", "gpio68"
-};
-
-static const char * const spkr_mi2s_groups[] = {
-       "gpio69", "gpio70", "gpio71", "gpio72"
-};
-
-static const char * const ter_mi2s_groups[] = {
-       "gpio73", "gpio74", "gpio75", "gpio76", "gpio77"
-};
-
-static const char * const sec_mi2s_groups[] = {
-       "gpio78", "gpio79", "gpio80", "gpio81", "gpio82"
-};
-
-static const char * const hdmi_cec_groups[] = { "gpio31" };
-static const char * const hdmi_ddc_groups[] = { "gpio32", "gpio33" };
-static const char * const hdmi_hpd_groups[] = { "gpio34" };
-static const char * const edp_hpd_groups[] = { "gpio102" };
-
-static const char * const mdp_vsync_groups[] = { "gpio12", "gpio13", "gpio14" };
-static const char * const cam_mclk0_groups[] = { "gpio15" };
-static const char * const cam_mclk1_groups[] = { "gpio16" };
-static const char * const cam_mclk2_groups[] = { "gpio17" };
-static const char * const cam_mclk3_groups[] = { "gpio18" };
-
-static const char * const cci_timer0_groups[] = { "gpio23" };
-static const char * const cci_timer1_groups[] = { "gpio24" };
-static const char * const cci_timer2_groups[] = { "gpio25" };
-static const char * const cci_timer3_groups[] = { "gpio26" };
-static const char * const cci_timer4_groups[] = { "gpio27" };
-static const char * const cci_async_in0_groups[] = { "gpio28" };
-static const char * const cci_async_in1_groups[] = { "gpio26" };
-static const char * const cci_async_in2_groups[] = { "gpio27" };
-
-static const char * const gp_pdm0_groups[] = { "gpio54", "gpio68" };
-static const char * const gp_pdm1_groups[] = { "gpio74", "gpio86" };
-static const char * const gp_pdm2_groups[] = { "gpio63", "gpio79" };
-
-static const char * const tsif1_groups[] = {
-       "gpio89", "gpio90", "gpio91", "gpio92"
-};
-
-static const char * const tsif2_groups[] = {
-       "gpio93", "gpio94", "gpio95", "gpio96"
-};
-
-static const char * const hsic_groups[] = { "gpio144", "gpio145" };
-static const char * const grfc_groups[] = {
-       "gpio104", "gpio105", "gpio106", "gpio107", "gpio108", "gpio109",
-       "gpio110", "gpio111", "gpio112", "gpio113", "gpio114", "gpio115",
-       "gpio116", "gpio117", "gpio118", "gpio119", "gpio120", "gpio121",
-       "gpio122", "gpio123", "gpio124", "gpio125", "gpio126", "gpio127",
-       "gpio128", "gpio136", "gpio137", "gpio141", "gpio143"
-};
-
-static const char * const audio_ref_clk_groups[] = { "gpio69" };
-
-static const char * const bt_groups[] = { "gpio35", "gpio43", "gpio44" };
-
-static const char * const fm_groups[] = { "gpio41", "gpio42" };
-
-static const char * const wlan_groups[] = {
-       "gpio36", "gpio37", "gpio38", "gpio39", "gpio40"
-};
-
-static const char * const slimbus_groups[] = { "gpio70", "gpio71" };
-
-static const struct msm_function msm8x74_functions[] = {
-       FUNCTION(cci_i2c0),
-       FUNCTION(cci_i2c1),
-       FUNCTION(uim1),
-       FUNCTION(uim2),
-       FUNCTION(uim_batt_alarm),
-       FUNCTION(blsp_uim1),
-       FUNCTION(blsp_uim2),
-       FUNCTION(blsp_uim3),
-       FUNCTION(blsp_uim4),
-       FUNCTION(blsp_uim5),
-       FUNCTION(blsp_uim6),
-       FUNCTION(blsp_uim7),
-       FUNCTION(blsp_uim8),
-       FUNCTION(blsp_uim9),
-       FUNCTION(blsp_uim10),
-       FUNCTION(blsp_uim11),
-       FUNCTION(blsp_uim12),
-       FUNCTION(blsp_i2c1),
-       FUNCTION(blsp_i2c2),
-       FUNCTION(blsp_i2c3),
-       FUNCTION(blsp_i2c4),
-       FUNCTION(blsp_i2c5),
-       FUNCTION(blsp_i2c6),
-       FUNCTION(blsp_i2c7),
-       FUNCTION(blsp_i2c8),
-       FUNCTION(blsp_i2c9),
-       FUNCTION(blsp_i2c10),
-       FUNCTION(blsp_i2c11),
-       FUNCTION(blsp_i2c12),
-       FUNCTION(blsp_spi1),
-       FUNCTION(blsp_spi1_cs1),
-       FUNCTION(blsp_spi1_cs2),
-       FUNCTION(blsp_spi1_cs3),
-       FUNCTION(blsp_spi2),
-       FUNCTION(blsp_spi2_cs1),
-       FUNCTION(blsp_spi2_cs2),
-       FUNCTION(blsp_spi2_cs3),
-       FUNCTION(blsp_spi3),
-       FUNCTION(blsp_spi4),
-       FUNCTION(blsp_spi5),
-       FUNCTION(blsp_spi6),
-       FUNCTION(blsp_spi7),
-       FUNCTION(blsp_spi8),
-       FUNCTION(blsp_spi9),
-       FUNCTION(blsp_spi10),
-       FUNCTION(blsp_spi10_cs1),
-       FUNCTION(blsp_spi10_cs2),
-       FUNCTION(blsp_spi10_cs3),
-       FUNCTION(blsp_spi11),
-       FUNCTION(blsp_spi12),
-       FUNCTION(blsp_uart1),
-       FUNCTION(blsp_uart2),
-       FUNCTION(blsp_uart3),
-       FUNCTION(blsp_uart4),
-       FUNCTION(blsp_uart5),
-       FUNCTION(blsp_uart6),
-       FUNCTION(blsp_uart7),
-       FUNCTION(blsp_uart8),
-       FUNCTION(blsp_uart9),
-       FUNCTION(blsp_uart10),
-       FUNCTION(blsp_uart11),
-       FUNCTION(blsp_uart12),
-       FUNCTION(sdc3),
-       FUNCTION(sdc4),
-       FUNCTION(gcc_gp_clk1),
-       FUNCTION(gcc_gp_clk2),
-       FUNCTION(gcc_gp_clk3),
-       FUNCTION(qua_mi2s),
-       FUNCTION(pri_mi2s),
-       FUNCTION(spkr_mi2s),
-       FUNCTION(ter_mi2s),
-       FUNCTION(sec_mi2s),
-       FUNCTION(mdp_vsync),
-       FUNCTION(cam_mclk0),
-       FUNCTION(cam_mclk1),
-       FUNCTION(cam_mclk2),
-       FUNCTION(cam_mclk3),
-       FUNCTION(cci_timer0),
-       FUNCTION(cci_timer1),
-       FUNCTION(cci_timer2),
-       FUNCTION(cci_timer3),
-       FUNCTION(cci_timer4),
-       FUNCTION(cci_async_in0),
-       FUNCTION(cci_async_in1),
-       FUNCTION(cci_async_in2),
-       FUNCTION(hdmi_cec),
-       FUNCTION(hdmi_ddc),
-       FUNCTION(hdmi_hpd),
-       FUNCTION(edp_hpd),
-       FUNCTION(gp_pdm0),
-       FUNCTION(gp_pdm1),
-       FUNCTION(gp_pdm2),
-       FUNCTION(gp0_clk),
-       FUNCTION(gp1_clk),
-       FUNCTION(gp_mn),
-       FUNCTION(tsif1),
-       FUNCTION(tsif2),
-       FUNCTION(hsic),
-       FUNCTION(grfc),
-       FUNCTION(audio_ref_clk),
-       FUNCTION(bt),
-       FUNCTION(fm),
-       FUNCTION(wlan),
-       FUNCTION(slimbus),
-};
-
-static const struct msm_pingroup msm8x74_groups[] = {
-       PINGROUP(0,   blsp_spi1, blsp_uart1, blsp_uim1, NA, NA, NA, NA),
-       PINGROUP(1,   blsp_spi1, blsp_uart1, blsp_uim1, NA, NA, NA, NA),
-       PINGROUP(2,   blsp_spi1, blsp_uart1, blsp_i2c1, NA, NA, NA, NA),
-       PINGROUP(3,   blsp_spi1, blsp_uart1, blsp_i2c1, NA, NA, NA, NA),
-       PINGROUP(4,   blsp_spi2, blsp_uart2, blsp_uim2, NA, NA, NA, NA),
-       PINGROUP(5,   blsp_spi2, blsp_uart2, blsp_uim2, NA, NA, NA, NA),
-       PINGROUP(6,   blsp_spi2, blsp_uart2, blsp_i2c2, NA, NA, NA, NA),
-       PINGROUP(7,   blsp_spi2, blsp_uart2, blsp_i2c2, NA, NA, NA, NA),
-       PINGROUP(8,   blsp_spi3, blsp_uart3, blsp_uim3, blsp_spi1_cs1, NA, NA, NA),
-       PINGROUP(9,   blsp_spi3, blsp_uart3, blsp_uim3, blsp_spi1_cs2, NA, NA, NA),
-       PINGROUP(10,  blsp_spi3, blsp_uart3, blsp_i2c3, blsp_spi1_cs3, NA, NA, NA),
-       PINGROUP(11,  blsp_spi3, blsp_uart3, blsp_i2c3, blsp_spi1_cs2, NA, NA, NA),
-       PINGROUP(12,  mdp_vsync, NA, NA, NA, NA, NA, NA),
-       PINGROUP(13,  mdp_vsync, NA, NA, NA, NA, NA, NA),
-       PINGROUP(14,  mdp_vsync, NA, NA, NA, NA, NA, NA),
-       PINGROUP(15,  cam_mclk0, NA, NA, NA, NA, NA, NA),
-       PINGROUP(16,  cam_mclk1, NA, NA, NA, NA, NA, NA),
-       PINGROUP(17,  cam_mclk2, NA, NA, NA, NA, NA, NA),
-       PINGROUP(18,  cam_mclk3, NA, NA, NA, NA, NA, NA),
-       PINGROUP(19,  cci_i2c0, blsp_spi4, blsp_uart4, blsp_uim4, NA, NA, NA),
-       PINGROUP(20,  cci_i2c0, blsp_spi4, blsp_uart4, blsp_uim4, NA, NA, NA),
-       PINGROUP(21,  cci_i2c1, blsp_spi4, blsp_uart4, blsp_i2c4, NA, NA, NA),
-       PINGROUP(22,  cci_i2c1, blsp_spi4, blsp_uart4, blsp_i2c4, NA, NA, NA),
-       PINGROUP(23,  cci_timer0, blsp_spi5, blsp_uart5, blsp_uim5, NA, NA, NA),
-       PINGROUP(24,  cci_timer1, blsp_spi5, blsp_uart5, blsp_uim5, NA, NA, NA),
-       PINGROUP(25,  cci_timer2, blsp_spi5, blsp_uart5, blsp_i2c5, NA, NA, NA),
-       PINGROUP(26,  cci_timer3, cci_async_in1, blsp_spi5, blsp_uart5, blsp_i2c5, gp0_clk, NA),
-       PINGROUP(27,  cci_timer4, cci_async_in2, blsp_spi6, blsp_uart6, blsp_i2c6, gp1_clk, NA),
-       PINGROUP(28,  cci_async_in0, blsp_spi6, blsp_uart6, blsp_uim6, NA, NA, NA),
-       PINGROUP(29,  blsp_spi6, blsp_uart6, blsp_i2c6, gp_mn, NA, NA, NA),
-       PINGROUP(30,  blsp_spi6, blsp_uart6, blsp_i2c6, NA, NA, NA, NA),
-       PINGROUP(31,  hdmi_cec, NA, NA, NA, NA, NA, NA),
-       PINGROUP(32,  hdmi_ddc, NA, NA, NA, NA, NA, NA),
-       PINGROUP(33,  hdmi_ddc, NA, NA, NA, NA, NA, NA),
-       PINGROUP(34,  hdmi_hpd, NA, NA, NA, NA, NA, NA),
-       PINGROUP(35,  bt, sdc3, NA, NA, NA, NA, NA),
-       PINGROUP(36,  wlan, sdc3, NA, NA, NA, NA, NA),
-       PINGROUP(37,  wlan, sdc3, NA, NA, NA, NA, NA),
-       PINGROUP(38,  wlan, sdc3, NA, NA, NA, NA, NA),
-       PINGROUP(39,  wlan, sdc3, NA, NA, NA, NA, NA),
-       PINGROUP(40,  wlan, sdc3, NA, NA, NA, NA, NA),
-       PINGROUP(41,  fm, blsp_spi7, blsp_uart7, blsp_uim7, NA, NA, NA),
-       PINGROUP(42,  fm, blsp_spi7, blsp_uart7, blsp_uim7, NA, NA, NA),
-       PINGROUP(43,  bt, blsp_spi7, blsp_uart7, blsp_i2c7, NA, NA, NA),
-       PINGROUP(44,  bt, blsp_spi7, blsp_uart7, blsp_i2c7, NA, NA, NA),
-       PINGROUP(45,  blsp_spi8, blsp_uart8, blsp_uim8, NA, NA, NA, NA),
-       PINGROUP(46,  blsp_spi8, blsp_uart8, blsp_uim8, NA, NA, NA, NA),
-       PINGROUP(47,  blsp_spi8, blsp_uart8, blsp_i2c8, blsp_spi10_cs1, NA, NA, NA),
-       PINGROUP(48,  blsp_spi8, blsp_uart8, blsp_i2c8, blsp_spi10_cs2, NA, NA, NA),
-       PINGROUP(49,  uim2, blsp_spi9, blsp_uart9, blsp_uim9, NA, NA, NA),
-       PINGROUP(50,  uim2, blsp_spi9, blsp_uart9, blsp_uim9, NA, NA, NA),
-       PINGROUP(51,  uim2, blsp_spi9, blsp_uart9, blsp_i2c9, NA, NA, NA),
-       PINGROUP(52,  uim2, blsp_spi9, blsp_uart9, blsp_i2c9, NA, NA, NA),
-       PINGROUP(53,  blsp_spi10, blsp_uart10, blsp_uim10, blsp_spi2_cs1, NA, NA, NA),
-       PINGROUP(54,  blsp_spi10, blsp_uart10, blsp_uim10, blsp_spi2_cs2, gp_pdm0, NA, NA),
-       PINGROUP(55,  blsp_spi10, blsp_uart10, blsp_i2c10, NA, NA, NA, NA),
-       PINGROUP(56,  blsp_spi10, blsp_uart10, blsp_i2c10, NA, NA, NA, NA),
-       PINGROUP(57,  qua_mi2s, gcc_gp_clk1, NA, NA, NA, NA, NA),
-       PINGROUP(58,  qua_mi2s, gcc_gp_clk2, NA, NA, NA, NA, NA),
-       PINGROUP(59,  qua_mi2s, gcc_gp_clk3, NA, NA, NA, NA, NA),
-       PINGROUP(60,  qua_mi2s, NA, NA, NA, NA, NA, NA),
-       PINGROUP(61,  qua_mi2s, NA, NA, NA, NA, NA, NA),
-       PINGROUP(62,  qua_mi2s, blsp_spi2_cs1, NA, NA, NA, NA, NA),
-       PINGROUP(63,  qua_mi2s, blsp_spi2_cs2, gp_pdm2, NA, NA, NA, NA),
-       PINGROUP(64,  pri_mi2s, NA, NA, NA, NA, NA, NA),
-       PINGROUP(65,  pri_mi2s, NA, NA, NA, NA, NA, NA),
-       PINGROUP(66,  pri_mi2s, blsp_spi2_cs3, NA, NA, NA, NA, NA),
-       PINGROUP(67,  pri_mi2s, blsp_spi10_cs1, NA, NA, NA, NA, NA),
-       PINGROUP(68,  pri_mi2s, blsp_spi10_cs2, gp_pdm0, NA, NA, NA, NA),
-       PINGROUP(69,  spkr_mi2s, audio_ref_clk, NA, NA, NA, NA, NA),
-       PINGROUP(70,  slimbus, spkr_mi2s, NA, NA, NA, NA, NA),
-       PINGROUP(71,  slimbus, spkr_mi2s, NA, NA, NA, NA, NA),
-       PINGROUP(72,  spkr_mi2s, NA, NA, NA, NA, NA, NA),
-       PINGROUP(73,  ter_mi2s, NA, NA, NA, NA, NA, NA),
-       PINGROUP(74,  ter_mi2s, gp_pdm1, NA, NA, NA, NA, NA),
-       PINGROUP(75,  ter_mi2s, NA, NA, NA, NA, NA, NA),
-       PINGROUP(76,  ter_mi2s, NA, NA, NA, NA, NA, NA),
-       PINGROUP(77,  ter_mi2s, NA, NA, NA, NA, NA, NA),
-       PINGROUP(78,  sec_mi2s, gcc_gp_clk1, NA, NA, NA, NA, NA),
-       PINGROUP(79,  sec_mi2s, gp_pdm2, NA, NA, NA, NA, NA),
-       PINGROUP(80,  sec_mi2s, NA, NA, NA, NA, NA, NA),
-       PINGROUP(81,  sec_mi2s, blsp_spi11, blsp_uart11, blsp_uim11, gcc_gp_clk2, NA, NA),
-       PINGROUP(82,  sec_mi2s, blsp_spi11, blsp_uart11, blsp_uim11, gcc_gp_clk3, NA, NA),
-       PINGROUP(83,  blsp_spi11, blsp_uart11, blsp_i2c11, NA, NA, NA, NA),
-       PINGROUP(84,  blsp_spi11, blsp_uart11, blsp_i2c11, NA, NA, NA, NA),
-       PINGROUP(85,  blsp_spi12, blsp_uart12, blsp_uim12, NA, NA, NA, NA),
-       PINGROUP(86,  blsp_spi12, blsp_uart12, blsp_uim12, gp_pdm1, NA, NA, NA),
-       PINGROUP(87,  blsp_spi12, blsp_uart12, blsp_i2c12, NA, NA, NA, NA),
-       PINGROUP(88,  blsp_spi12, blsp_uart12, blsp_i2c12, NA, NA, NA, NA),
-       PINGROUP(89,  tsif1, NA, NA, NA, NA, NA, NA),
-       PINGROUP(90,  tsif1, blsp_spi10_cs3, NA, NA, NA, NA, NA),
-       PINGROUP(91,  tsif1, sdc4, NA, NA, NA, NA, NA),
-       PINGROUP(92,  tsif1, sdc4, NA, NA, NA, NA, NA),
-       PINGROUP(93,  tsif2, sdc4, NA, NA, NA, NA, NA),
-       PINGROUP(94,  tsif2, sdc4, NA, NA, NA, NA, NA),
-       PINGROUP(95,  tsif2, sdc4, NA, NA, NA, NA, NA),
-       PINGROUP(96,  tsif2, sdc4, NA, NA, NA, NA, NA),
-       PINGROUP(97,  uim1, NA, NA, NA, NA, NA, NA),
-       PINGROUP(98,  uim1, NA, NA, NA, NA, NA, NA),
-       PINGROUP(99,  uim1, NA, NA, NA, NA, NA, NA),
-       PINGROUP(100, uim1, NA, NA, NA, NA, NA, NA),
-       PINGROUP(101, uim_batt_alarm, NA, NA, NA, NA, NA, NA),
-       PINGROUP(102, edp_hpd, NA, NA, NA, NA, NA, NA),
-       PINGROUP(103, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(104, grfc, NA, NA, NA, NA, NA, NA),
-       PINGROUP(105, grfc, NA, NA, NA, NA, NA, NA),
-       PINGROUP(106, grfc, NA, NA, NA, NA, NA, NA),
-       PINGROUP(107, grfc, NA, NA, NA, NA, NA, NA),
-       PINGROUP(108, grfc, NA, NA, NA, NA, NA, NA),
-       PINGROUP(109, grfc, NA, NA, NA, NA, NA, NA),
-       PINGROUP(110, grfc, NA, NA, NA, NA, NA, NA),
-       PINGROUP(111, grfc, NA, NA, NA, NA, NA, NA),
-       PINGROUP(112, grfc, NA, NA, NA, NA, NA, NA),
-       PINGROUP(113, grfc, NA, NA, NA, NA, NA, NA),
-       PINGROUP(114, grfc, NA, NA, NA, NA, NA, NA),
-       PINGROUP(115, grfc, NA, NA, NA, NA, NA, NA),
-       PINGROUP(116, grfc, NA, NA, NA, NA, NA, NA),
-       PINGROUP(117, grfc, NA, NA, NA, NA, NA, NA),
-       PINGROUP(118, grfc, NA, NA, NA, NA, NA, NA),
-       PINGROUP(119, grfc, NA, NA, NA, NA, NA, NA),
-       PINGROUP(120, grfc, NA, NA, NA, NA, NA, NA),
-       PINGROUP(121, grfc, NA, NA, NA, NA, NA, NA),
-       PINGROUP(122, grfc, NA, NA, NA, NA, NA, NA),
-       PINGROUP(123, grfc, NA, NA, NA, NA, NA, NA),
-       PINGROUP(124, grfc, NA, NA, NA, NA, NA, NA),
-       PINGROUP(125, grfc, NA, NA, NA, NA, NA, NA),
-       PINGROUP(126, grfc, NA, NA, NA, NA, NA, NA),
-       PINGROUP(127, grfc, NA, NA, NA, NA, NA, NA),
-       PINGROUP(128, NA, grfc, NA, NA, NA, NA, NA),
-       PINGROUP(129, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(130, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(131, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(132, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(133, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(134, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(135, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(136, NA, grfc, NA, NA, NA, NA, NA),
-       PINGROUP(137, NA, grfc, NA, NA, NA, NA, NA),
-       PINGROUP(138, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(139, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(140, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(141, NA, grfc, NA, NA, NA, NA, NA),
-       PINGROUP(142, NA, NA, NA, NA, NA, NA, NA),
-       PINGROUP(143, NA, grfc, NA, NA, NA, NA, NA),
-       PINGROUP(144, hsic, NA, NA, NA, NA, NA, NA),
-       PINGROUP(145, hsic, NA, NA, NA, NA, NA, NA),
-       SDC_PINGROUP(sdc1_clk, 0x2044, 13, 6),
-       SDC_PINGROUP(sdc1_cmd, 0x2044, 11, 3),
-       SDC_PINGROUP(sdc1_data, 0x2044, 9, 0),
-       SDC_PINGROUP(sdc2_clk, 0x2048, 14, 6),
-       SDC_PINGROUP(sdc2_cmd, 0x2048, 11, 3),
-       SDC_PINGROUP(sdc2_data, 0x2048, 9, 0),
-};
-
-#define NUM_GPIO_PINGROUPS 146
-
-static const struct msm_pinctrl_soc_data msm8x74_pinctrl = {
-       .pins = msm8x74_pins,
-       .npins = ARRAY_SIZE(msm8x74_pins),
-       .functions = msm8x74_functions,
-       .nfunctions = ARRAY_SIZE(msm8x74_functions),
-       .groups = msm8x74_groups,
-       .ngroups = ARRAY_SIZE(msm8x74_groups),
-       .ngpios = NUM_GPIO_PINGROUPS,
-};
-
-static int msm8x74_pinctrl_probe(struct platform_device *pdev)
-{
-       return msm_pinctrl_probe(pdev, &msm8x74_pinctrl);
-}
-
-static const struct of_device_id msm8x74_pinctrl_of_match[] = {
-       { .compatible = "qcom,msm8974-pinctrl", },
-       { },
-};
-
-static struct platform_driver msm8x74_pinctrl_driver = {
-       .driver = {
-               .name = "msm8x74-pinctrl",
-               .owner = THIS_MODULE,
-               .of_match_table = msm8x74_pinctrl_of_match,
-       },
-       .probe = msm8x74_pinctrl_probe,
-       .remove = msm_pinctrl_remove,
-};
-
-static int __init msm8x74_pinctrl_init(void)
-{
-       return platform_driver_register(&msm8x74_pinctrl_driver);
-}
-arch_initcall(msm8x74_pinctrl_init);
-
-static void __exit msm8x74_pinctrl_exit(void)
-{
-       platform_driver_unregister(&msm8x74_pinctrl_driver);
-}
-module_exit(msm8x74_pinctrl_exit);
-
-MODULE_AUTHOR("Bjorn Andersson <bjorn.andersson@sonymobile.com>");
-MODULE_DESCRIPTION("Qualcomm MSM8x74 pinctrl driver");
-MODULE_LICENSE("GPL v2");
-MODULE_DEVICE_TABLE(of, msm8x74_pinctrl_of_match);
-
diff --git a/drivers/pinctrl/pinctrl-nomadik-db8500.c b/drivers/pinctrl/pinctrl-nomadik-db8500.c
deleted file mode 100644 (file)
index c748407..0000000
+++ /dev/null
@@ -1,1257 +0,0 @@
-#include <linux/kernel.h>
-#include <linux/pinctrl/pinctrl.h>
-#include "pinctrl-nomadik.h"
-
-/* All the pins that can be used for GPIO and some other functions */
-#define _GPIO(offset)          (offset)
-
-#define DB8500_PIN_AJ5         _GPIO(0)
-#define DB8500_PIN_AJ3         _GPIO(1)
-#define DB8500_PIN_AH4         _GPIO(2)
-#define DB8500_PIN_AH3         _GPIO(3)
-#define DB8500_PIN_AH6         _GPIO(4)
-#define DB8500_PIN_AG6         _GPIO(5)
-#define DB8500_PIN_AF6         _GPIO(6)
-#define DB8500_PIN_AG5         _GPIO(7)
-#define DB8500_PIN_AD5         _GPIO(8)
-#define DB8500_PIN_AE4         _GPIO(9)
-#define DB8500_PIN_AF5         _GPIO(10)
-#define DB8500_PIN_AG4         _GPIO(11)
-#define DB8500_PIN_AC4         _GPIO(12)
-#define DB8500_PIN_AF3         _GPIO(13)
-#define DB8500_PIN_AE3         _GPIO(14)
-#define DB8500_PIN_AC3         _GPIO(15)
-#define DB8500_PIN_AD3         _GPIO(16)
-#define DB8500_PIN_AD4         _GPIO(17)
-#define DB8500_PIN_AC2         _GPIO(18)
-#define DB8500_PIN_AC1         _GPIO(19)
-#define DB8500_PIN_AB4         _GPIO(20)
-#define DB8500_PIN_AB3         _GPIO(21)
-#define DB8500_PIN_AA3         _GPIO(22)
-#define DB8500_PIN_AA4         _GPIO(23)
-#define DB8500_PIN_AB2         _GPIO(24)
-#define DB8500_PIN_Y4          _GPIO(25)
-#define DB8500_PIN_Y2          _GPIO(26)
-#define DB8500_PIN_AA2         _GPIO(27)
-#define DB8500_PIN_AA1         _GPIO(28)
-#define DB8500_PIN_W2          _GPIO(29)
-#define DB8500_PIN_W3          _GPIO(30)
-#define DB8500_PIN_V3          _GPIO(31)
-#define DB8500_PIN_V2          _GPIO(32)
-#define DB8500_PIN_AF2         _GPIO(33)
-#define DB8500_PIN_AE1         _GPIO(34)
-#define DB8500_PIN_AE2         _GPIO(35)
-#define DB8500_PIN_AG2         _GPIO(36)
-/* Hole */
-#define DB8500_PIN_F3          _GPIO(64)
-#define DB8500_PIN_F1          _GPIO(65)
-#define DB8500_PIN_G3          _GPIO(66)
-#define DB8500_PIN_G2          _GPIO(67)
-#define DB8500_PIN_E1          _GPIO(68)
-#define DB8500_PIN_E2          _GPIO(69)
-#define DB8500_PIN_G5          _GPIO(70)
-#define DB8500_PIN_G4          _GPIO(71)
-#define DB8500_PIN_H4          _GPIO(72)
-#define DB8500_PIN_H3          _GPIO(73)
-#define DB8500_PIN_J3          _GPIO(74)
-#define DB8500_PIN_H2          _GPIO(75)
-#define DB8500_PIN_J2          _GPIO(76)
-#define DB8500_PIN_H1          _GPIO(77)
-#define DB8500_PIN_F4          _GPIO(78)
-#define DB8500_PIN_E3          _GPIO(79)
-#define DB8500_PIN_E4          _GPIO(80)
-#define DB8500_PIN_D2          _GPIO(81)
-#define DB8500_PIN_C1          _GPIO(82)
-#define DB8500_PIN_D3          _GPIO(83)
-#define DB8500_PIN_C2          _GPIO(84)
-#define DB8500_PIN_D5          _GPIO(85)
-#define DB8500_PIN_C6          _GPIO(86)
-#define DB8500_PIN_B3          _GPIO(87)
-#define DB8500_PIN_C4          _GPIO(88)
-#define DB8500_PIN_E6          _GPIO(89)
-#define DB8500_PIN_A3          _GPIO(90)
-#define DB8500_PIN_B6          _GPIO(91)
-#define DB8500_PIN_D6          _GPIO(92)
-#define DB8500_PIN_B7          _GPIO(93)
-#define DB8500_PIN_D7          _GPIO(94)
-#define DB8500_PIN_E8          _GPIO(95)
-#define DB8500_PIN_D8          _GPIO(96)
-#define DB8500_PIN_D9          _GPIO(97)
-/* Hole */
-#define DB8500_PIN_A5          _GPIO(128)
-#define DB8500_PIN_B4          _GPIO(129)
-#define DB8500_PIN_C8          _GPIO(130)
-#define DB8500_PIN_A12         _GPIO(131)
-#define DB8500_PIN_C10         _GPIO(132)
-#define DB8500_PIN_B10         _GPIO(133)
-#define DB8500_PIN_B9          _GPIO(134)
-#define DB8500_PIN_A9          _GPIO(135)
-#define DB8500_PIN_C7          _GPIO(136)
-#define DB8500_PIN_A7          _GPIO(137)
-#define DB8500_PIN_C5          _GPIO(138)
-#define DB8500_PIN_C9          _GPIO(139)
-#define DB8500_PIN_B11         _GPIO(140)
-#define DB8500_PIN_C12         _GPIO(141)
-#define DB8500_PIN_C11         _GPIO(142)
-#define DB8500_PIN_D12         _GPIO(143)
-#define DB8500_PIN_B13         _GPIO(144)
-#define DB8500_PIN_C13         _GPIO(145)
-#define DB8500_PIN_D13         _GPIO(146)
-#define DB8500_PIN_C15         _GPIO(147)
-#define DB8500_PIN_B16         _GPIO(148)
-#define DB8500_PIN_B14         _GPIO(149)
-#define DB8500_PIN_C14         _GPIO(150)
-#define DB8500_PIN_D17         _GPIO(151)
-#define DB8500_PIN_D16         _GPIO(152)
-#define DB8500_PIN_B17         _GPIO(153)
-#define DB8500_PIN_C16         _GPIO(154)
-#define DB8500_PIN_C19         _GPIO(155)
-#define DB8500_PIN_C17         _GPIO(156)
-#define DB8500_PIN_A18         _GPIO(157)
-#define DB8500_PIN_C18         _GPIO(158)
-#define DB8500_PIN_B19         _GPIO(159)
-#define DB8500_PIN_B20         _GPIO(160)
-#define DB8500_PIN_D21         _GPIO(161)
-#define DB8500_PIN_D20         _GPIO(162)
-#define DB8500_PIN_C20         _GPIO(163)
-#define DB8500_PIN_B21         _GPIO(164)
-#define DB8500_PIN_C21         _GPIO(165)
-#define DB8500_PIN_A22         _GPIO(166)
-#define DB8500_PIN_B24         _GPIO(167)
-#define DB8500_PIN_C22         _GPIO(168)
-#define DB8500_PIN_D22         _GPIO(169)
-#define DB8500_PIN_C23         _GPIO(170)
-#define DB8500_PIN_D23         _GPIO(171)
-/* Hole */
-#define DB8500_PIN_AJ27                _GPIO(192)
-#define DB8500_PIN_AH27                _GPIO(193)
-#define DB8500_PIN_AF27                _GPIO(194)
-#define DB8500_PIN_AG28                _GPIO(195)
-#define DB8500_PIN_AG26                _GPIO(196)
-#define DB8500_PIN_AH24                _GPIO(197)
-#define DB8500_PIN_AG25                _GPIO(198)
-#define DB8500_PIN_AH23                _GPIO(199)
-#define DB8500_PIN_AH26                _GPIO(200)
-#define DB8500_PIN_AF24                _GPIO(201)
-#define DB8500_PIN_AF25                _GPIO(202)
-#define DB8500_PIN_AE23                _GPIO(203)
-#define DB8500_PIN_AF23                _GPIO(204)
-#define DB8500_PIN_AG23                _GPIO(205)
-#define DB8500_PIN_AG24                _GPIO(206)
-#define DB8500_PIN_AJ23                _GPIO(207)
-#define DB8500_PIN_AH16                _GPIO(208)
-#define DB8500_PIN_AG15                _GPIO(209)
-#define DB8500_PIN_AJ15                _GPIO(210)
-#define DB8500_PIN_AG14                _GPIO(211)
-#define DB8500_PIN_AF13                _GPIO(212)
-#define DB8500_PIN_AG13                _GPIO(213)
-#define DB8500_PIN_AH15                _GPIO(214)
-#define DB8500_PIN_AH13                _GPIO(215)
-#define DB8500_PIN_AG12                _GPIO(216)
-#define DB8500_PIN_AH12                _GPIO(217)
-#define DB8500_PIN_AH11                _GPIO(218)
-#define DB8500_PIN_AG10                _GPIO(219)
-#define DB8500_PIN_AH10                _GPIO(220)
-#define DB8500_PIN_AJ11                _GPIO(221)
-#define DB8500_PIN_AJ9         _GPIO(222)
-#define DB8500_PIN_AH9         _GPIO(223)
-#define DB8500_PIN_AG9         _GPIO(224)
-#define DB8500_PIN_AG8         _GPIO(225)
-#define DB8500_PIN_AF8         _GPIO(226)
-#define DB8500_PIN_AH7         _GPIO(227)
-#define DB8500_PIN_AJ6         _GPIO(228)
-#define DB8500_PIN_AG7         _GPIO(229)
-#define DB8500_PIN_AF7         _GPIO(230)
-/* Hole */
-#define DB8500_PIN_AF28                _GPIO(256)
-#define DB8500_PIN_AE29                _GPIO(257)
-#define DB8500_PIN_AD29                _GPIO(258)
-#define DB8500_PIN_AC29                _GPIO(259)
-#define DB8500_PIN_AD28                _GPIO(260)
-#define DB8500_PIN_AD26                _GPIO(261)
-#define DB8500_PIN_AE26                _GPIO(262)
-#define DB8500_PIN_AG29                _GPIO(263)
-#define DB8500_PIN_AE27                _GPIO(264)
-#define DB8500_PIN_AD27                _GPIO(265)
-#define DB8500_PIN_AC28                _GPIO(266)
-#define DB8500_PIN_AC27                _GPIO(267)
-
-/*
- * The names of the pins are denoted by GPIO number and ball name, even
- * though they can be used for other things than GPIO, this is the first
- * column in the table of the data sheet and often used on schematics and
- * such.
- */
-static const struct pinctrl_pin_desc nmk_db8500_pins[] = {
-       PINCTRL_PIN(DB8500_PIN_AJ5, "GPIO0_AJ5"),
-       PINCTRL_PIN(DB8500_PIN_AJ3, "GPIO1_AJ3"),
-       PINCTRL_PIN(DB8500_PIN_AH4, "GPIO2_AH4"),
-       PINCTRL_PIN(DB8500_PIN_AH3, "GPIO3_AH3"),
-       PINCTRL_PIN(DB8500_PIN_AH6, "GPIO4_AH6"),
-       PINCTRL_PIN(DB8500_PIN_AG6, "GPIO5_AG6"),
-       PINCTRL_PIN(DB8500_PIN_AF6, "GPIO6_AF6"),
-       PINCTRL_PIN(DB8500_PIN_AG5, "GPIO7_AG5"),
-       PINCTRL_PIN(DB8500_PIN_AD5, "GPIO8_AD5"),
-       PINCTRL_PIN(DB8500_PIN_AE4, "GPIO9_AE4"),
-       PINCTRL_PIN(DB8500_PIN_AF5, "GPIO10_AF5"),
-       PINCTRL_PIN(DB8500_PIN_AG4, "GPIO11_AG4"),
-       PINCTRL_PIN(DB8500_PIN_AC4, "GPIO12_AC4"),
-       PINCTRL_PIN(DB8500_PIN_AF3, "GPIO13_AF3"),
-       PINCTRL_PIN(DB8500_PIN_AE3, "GPIO14_AE3"),
-       PINCTRL_PIN(DB8500_PIN_AC3, "GPIO15_AC3"),
-       PINCTRL_PIN(DB8500_PIN_AD3, "GPIO16_AD3"),
-       PINCTRL_PIN(DB8500_PIN_AD4, "GPIO17_AD4"),
-       PINCTRL_PIN(DB8500_PIN_AC2, "GPIO18_AC2"),
-       PINCTRL_PIN(DB8500_PIN_AC1, "GPIO19_AC1"),
-       PINCTRL_PIN(DB8500_PIN_AB4, "GPIO20_AB4"),
-       PINCTRL_PIN(DB8500_PIN_AB3, "GPIO21_AB3"),
-       PINCTRL_PIN(DB8500_PIN_AA3, "GPIO22_AA3"),
-       PINCTRL_PIN(DB8500_PIN_AA4, "GPIO23_AA4"),
-       PINCTRL_PIN(DB8500_PIN_AB2, "GPIO24_AB2"),
-       PINCTRL_PIN(DB8500_PIN_Y4, "GPIO25_Y4"),
-       PINCTRL_PIN(DB8500_PIN_Y2, "GPIO26_Y2"),
-       PINCTRL_PIN(DB8500_PIN_AA2, "GPIO27_AA2"),
-       PINCTRL_PIN(DB8500_PIN_AA1, "GPIO28_AA1"),
-       PINCTRL_PIN(DB8500_PIN_W2, "GPIO29_W2"),
-       PINCTRL_PIN(DB8500_PIN_W3, "GPIO30_W3"),
-       PINCTRL_PIN(DB8500_PIN_V3, "GPIO31_V3"),
-       PINCTRL_PIN(DB8500_PIN_V2, "GPIO32_V2"),
-       PINCTRL_PIN(DB8500_PIN_AF2, "GPIO33_AF2"),
-       PINCTRL_PIN(DB8500_PIN_AE1, "GPIO34_AE1"),
-       PINCTRL_PIN(DB8500_PIN_AE2, "GPIO35_AE2"),
-       PINCTRL_PIN(DB8500_PIN_AG2, "GPIO36_AG2"),
-       /* Hole */
-       PINCTRL_PIN(DB8500_PIN_F3, "GPIO64_F3"),
-       PINCTRL_PIN(DB8500_PIN_F1, "GPIO65_F1"),
-       PINCTRL_PIN(DB8500_PIN_G3, "GPIO66_G3"),
-       PINCTRL_PIN(DB8500_PIN_G2, "GPIO67_G2"),
-       PINCTRL_PIN(DB8500_PIN_E1, "GPIO68_E1"),
-       PINCTRL_PIN(DB8500_PIN_E2, "GPIO69_E2"),
-       PINCTRL_PIN(DB8500_PIN_G5, "GPIO70_G5"),
-       PINCTRL_PIN(DB8500_PIN_G4, "GPIO71_G4"),
-       PINCTRL_PIN(DB8500_PIN_H4, "GPIO72_H4"),
-       PINCTRL_PIN(DB8500_PIN_H3, "GPIO73_H3"),
-       PINCTRL_PIN(DB8500_PIN_J3, "GPIO74_J3"),
-       PINCTRL_PIN(DB8500_PIN_H2, "GPIO75_H2"),
-       PINCTRL_PIN(DB8500_PIN_J2, "GPIO76_J2"),
-       PINCTRL_PIN(DB8500_PIN_H1, "GPIO77_H1"),
-       PINCTRL_PIN(DB8500_PIN_F4, "GPIO78_F4"),
-       PINCTRL_PIN(DB8500_PIN_E3, "GPIO79_E3"),
-       PINCTRL_PIN(DB8500_PIN_E4, "GPIO80_E4"),
-       PINCTRL_PIN(DB8500_PIN_D2, "GPIO81_D2"),
-       PINCTRL_PIN(DB8500_PIN_C1, "GPIO82_C1"),
-       PINCTRL_PIN(DB8500_PIN_D3, "GPIO83_D3"),
-       PINCTRL_PIN(DB8500_PIN_C2, "GPIO84_C2"),
-       PINCTRL_PIN(DB8500_PIN_D5, "GPIO85_D5"),
-       PINCTRL_PIN(DB8500_PIN_C6, "GPIO86_C6"),
-       PINCTRL_PIN(DB8500_PIN_B3, "GPIO87_B3"),
-       PINCTRL_PIN(DB8500_PIN_C4, "GPIO88_C4"),
-       PINCTRL_PIN(DB8500_PIN_E6, "GPIO89_E6"),
-       PINCTRL_PIN(DB8500_PIN_A3, "GPIO90_A3"),
-       PINCTRL_PIN(DB8500_PIN_B6, "GPIO91_B6"),
-       PINCTRL_PIN(DB8500_PIN_D6, "GPIO92_D6"),
-       PINCTRL_PIN(DB8500_PIN_B7, "GPIO93_B7"),
-       PINCTRL_PIN(DB8500_PIN_D7, "GPIO94_D7"),
-       PINCTRL_PIN(DB8500_PIN_E8, "GPIO95_E8"),
-       PINCTRL_PIN(DB8500_PIN_D8, "GPIO96_D8"),
-       PINCTRL_PIN(DB8500_PIN_D9, "GPIO97_D9"),
-       /* Hole */
-       PINCTRL_PIN(DB8500_PIN_A5, "GPIO128_A5"),
-       PINCTRL_PIN(DB8500_PIN_B4, "GPIO129_B4"),
-       PINCTRL_PIN(DB8500_PIN_C8, "GPIO130_C8"),
-       PINCTRL_PIN(DB8500_PIN_A12, "GPIO131_A12"),
-       PINCTRL_PIN(DB8500_PIN_C10, "GPIO132_C10"),
-       PINCTRL_PIN(DB8500_PIN_B10, "GPIO133_B10"),
-       PINCTRL_PIN(DB8500_PIN_B9, "GPIO134_B9"),
-       PINCTRL_PIN(DB8500_PIN_A9, "GPIO135_A9"),
-       PINCTRL_PIN(DB8500_PIN_C7, "GPIO136_C7"),
-       PINCTRL_PIN(DB8500_PIN_A7, "GPIO137_A7"),
-       PINCTRL_PIN(DB8500_PIN_C5, "GPIO138_C5"),
-       PINCTRL_PIN(DB8500_PIN_C9, "GPIO139_C9"),
-       PINCTRL_PIN(DB8500_PIN_B11, "GPIO140_B11"),
-       PINCTRL_PIN(DB8500_PIN_C12, "GPIO141_C12"),
-       PINCTRL_PIN(DB8500_PIN_C11, "GPIO142_C11"),
-       PINCTRL_PIN(DB8500_PIN_D12, "GPIO143_D12"),
-       PINCTRL_PIN(DB8500_PIN_B13, "GPIO144_B13"),
-       PINCTRL_PIN(DB8500_PIN_C13, "GPIO145_C13"),
-       PINCTRL_PIN(DB8500_PIN_D13, "GPIO146_D13"),
-       PINCTRL_PIN(DB8500_PIN_C15, "GPIO147_C15"),
-       PINCTRL_PIN(DB8500_PIN_B16, "GPIO148_B16"),
-       PINCTRL_PIN(DB8500_PIN_B14, "GPIO149_B14"),
-       PINCTRL_PIN(DB8500_PIN_C14, "GPIO150_C14"),
-       PINCTRL_PIN(DB8500_PIN_D17, "GPIO151_D17"),
-       PINCTRL_PIN(DB8500_PIN_D16, "GPIO152_D16"),
-       PINCTRL_PIN(DB8500_PIN_B17, "GPIO153_B17"),
-       PINCTRL_PIN(DB8500_PIN_C16, "GPIO154_C16"),
-       PINCTRL_PIN(DB8500_PIN_C19, "GPIO155_C19"),
-       PINCTRL_PIN(DB8500_PIN_C17, "GPIO156_C17"),
-       PINCTRL_PIN(DB8500_PIN_A18, "GPIO157_A18"),
-       PINCTRL_PIN(DB8500_PIN_C18, "GPIO158_C18"),
-       PINCTRL_PIN(DB8500_PIN_B19, "GPIO159_B19"),
-       PINCTRL_PIN(DB8500_PIN_B20, "GPIO160_B20"),
-       PINCTRL_PIN(DB8500_PIN_D21, "GPIO161_D21"),
-       PINCTRL_PIN(DB8500_PIN_D20, "GPIO162_D20"),
-       PINCTRL_PIN(DB8500_PIN_C20, "GPIO163_C20"),
-       PINCTRL_PIN(DB8500_PIN_B21, "GPIO164_B21"),
-       PINCTRL_PIN(DB8500_PIN_C21, "GPIO165_C21"),
-       PINCTRL_PIN(DB8500_PIN_A22, "GPIO166_A22"),
-       PINCTRL_PIN(DB8500_PIN_B24, "GPIO167_B24"),
-       PINCTRL_PIN(DB8500_PIN_C22, "GPIO168_C22"),
-       PINCTRL_PIN(DB8500_PIN_D22, "GPIO169_D22"),
-       PINCTRL_PIN(DB8500_PIN_C23, "GPIO170_C23"),
-       PINCTRL_PIN(DB8500_PIN_D23, "GPIO171_D23"),
-       /* Hole */
-       PINCTRL_PIN(DB8500_PIN_AJ27, "GPIO192_AJ27"),
-       PINCTRL_PIN(DB8500_PIN_AH27, "GPIO193_AH27"),
-       PINCTRL_PIN(DB8500_PIN_AF27, "GPIO194_AF27"),
-       PINCTRL_PIN(DB8500_PIN_AG28, "GPIO195_AG28"),
-       PINCTRL_PIN(DB8500_PIN_AG26, "GPIO196_AG26"),
-       PINCTRL_PIN(DB8500_PIN_AH24, "GPIO197_AH24"),
-       PINCTRL_PIN(DB8500_PIN_AG25, "GPIO198_AG25"),
-       PINCTRL_PIN(DB8500_PIN_AH23, "GPIO199_AH23"),
-       PINCTRL_PIN(DB8500_PIN_AH26, "GPIO200_AH26"),
-       PINCTRL_PIN(DB8500_PIN_AF24, "GPIO201_AF24"),
-       PINCTRL_PIN(DB8500_PIN_AF25, "GPIO202_AF25"),
-       PINCTRL_PIN(DB8500_PIN_AE23, "GPIO203_AE23"),
-       PINCTRL_PIN(DB8500_PIN_AF23, "GPIO204_AF23"),
-       PINCTRL_PIN(DB8500_PIN_AG23, "GPIO205_AG23"),
-       PINCTRL_PIN(DB8500_PIN_AG24, "GPIO206_AG24"),
-       PINCTRL_PIN(DB8500_PIN_AJ23, "GPIO207_AJ23"),
-       PINCTRL_PIN(DB8500_PIN_AH16, "GPIO208_AH16"),
-       PINCTRL_PIN(DB8500_PIN_AG15, "GPIO209_AG15"),
-       PINCTRL_PIN(DB8500_PIN_AJ15, "GPIO210_AJ15"),
-       PINCTRL_PIN(DB8500_PIN_AG14, "GPIO211_AG14"),
-       PINCTRL_PIN(DB8500_PIN_AF13, "GPIO212_AF13"),
-       PINCTRL_PIN(DB8500_PIN_AG13, "GPIO213_AG13"),
-       PINCTRL_PIN(DB8500_PIN_AH15, "GPIO214_AH15"),
-       PINCTRL_PIN(DB8500_PIN_AH13, "GPIO215_AH13"),
-       PINCTRL_PIN(DB8500_PIN_AG12, "GPIO216_AG12"),
-       PINCTRL_PIN(DB8500_PIN_AH12, "GPIO217_AH12"),
-       PINCTRL_PIN(DB8500_PIN_AH11, "GPIO218_AH11"),
-       PINCTRL_PIN(DB8500_PIN_AG10, "GPIO219_AG10"),
-       PINCTRL_PIN(DB8500_PIN_AH10, "GPIO220_AH10"),
-       PINCTRL_PIN(DB8500_PIN_AJ11, "GPIO221_AJ11"),
-       PINCTRL_PIN(DB8500_PIN_AJ9, "GPIO222_AJ9"),
-       PINCTRL_PIN(DB8500_PIN_AH9, "GPIO223_AH9"),
-       PINCTRL_PIN(DB8500_PIN_AG9, "GPIO224_AG9"),
-       PINCTRL_PIN(DB8500_PIN_AG8, "GPIO225_AG8"),
-       PINCTRL_PIN(DB8500_PIN_AF8, "GPIO226_AF8"),
-       PINCTRL_PIN(DB8500_PIN_AH7, "GPIO227_AH7"),
-       PINCTRL_PIN(DB8500_PIN_AJ6, "GPIO228_AJ6"),
-       PINCTRL_PIN(DB8500_PIN_AG7, "GPIO229_AG7"),
-       PINCTRL_PIN(DB8500_PIN_AF7, "GPIO230_AF7"),
-       /* Hole */
-       PINCTRL_PIN(DB8500_PIN_AF28, "GPIO256_AF28"),
-       PINCTRL_PIN(DB8500_PIN_AE29, "GPIO257_AE29"),
-       PINCTRL_PIN(DB8500_PIN_AD29, "GPIO258_AD29"),
-       PINCTRL_PIN(DB8500_PIN_AC29, "GPIO259_AC29"),
-       PINCTRL_PIN(DB8500_PIN_AD28, "GPIO260_AD28"),
-       PINCTRL_PIN(DB8500_PIN_AD26, "GPIO261_AD26"),
-       PINCTRL_PIN(DB8500_PIN_AE26, "GPIO262_AE26"),
-       PINCTRL_PIN(DB8500_PIN_AG29, "GPIO263_AG29"),
-       PINCTRL_PIN(DB8500_PIN_AE27, "GPIO264_AE27"),
-       PINCTRL_PIN(DB8500_PIN_AD27, "GPIO265_AD27"),
-       PINCTRL_PIN(DB8500_PIN_AC28, "GPIO266_AC28"),
-       PINCTRL_PIN(DB8500_PIN_AC27, "GPIO267_AC27"),
-};
-
-#define DB8500_GPIO_RANGE(a, b, c) { .name = "DB8500", .id = a, .base = b, \
-                       .pin_base = b, .npins = c }
-
-/*
- * This matches the 32-pin gpio chips registered by the GPIO portion. This
- * cannot be const since we assign the struct gpio_chip * pointer at runtime.
- */
-static struct pinctrl_gpio_range nmk_db8500_ranges[] = {
-       DB8500_GPIO_RANGE(0, 0, 32),
-       DB8500_GPIO_RANGE(1, 32, 5),
-       DB8500_GPIO_RANGE(2, 64, 32),
-       DB8500_GPIO_RANGE(3, 96, 2),
-       DB8500_GPIO_RANGE(4, 128, 32),
-       DB8500_GPIO_RANGE(5, 160, 12),
-       DB8500_GPIO_RANGE(6, 192, 32),
-       DB8500_GPIO_RANGE(7, 224, 7),
-       DB8500_GPIO_RANGE(8, 256, 12),
-};
-
-/*
- * Read the pin group names like this:
- * u0_a_1    = first groups of pins for uart0 on alt function a
- * i2c2_b_2  = second group of pins for i2c2 on alt function b
- *
- * The groups are arranged as sets per altfunction column, so we can
- * mux in one group at a time by selecting the same altfunction for them
- * all. When functions require pins on different altfunctions, you need
- * to combine several groups.
- */
-
-/* Altfunction A column */
-static const unsigned u0_a_1_pins[] = { DB8500_PIN_AJ5, DB8500_PIN_AJ3,
-                                       DB8500_PIN_AH4, DB8500_PIN_AH3 };
-static const unsigned u1rxtx_a_1_pins[] = { DB8500_PIN_AH6, DB8500_PIN_AG6 };
-static const unsigned u1ctsrts_a_1_pins[] = { DB8500_PIN_AF6, DB8500_PIN_AG5 };
-/* Image processor I2C line, this is driven by image processor firmware */
-static const unsigned ipi2c_a_1_pins[] = { DB8500_PIN_AD5, DB8500_PIN_AE4 };
-static const unsigned ipi2c_a_2_pins[] = { DB8500_PIN_AF5, DB8500_PIN_AG4 };
-/* MSP0 can only be on these pins, but TXD and RXD can be flipped */
-static const unsigned msp0txrx_a_1_pins[] = { DB8500_PIN_AC4, DB8500_PIN_AC3 };
-static const unsigned msp0tfstck_a_1_pins[] = { DB8500_PIN_AF3, DB8500_PIN_AE3 };
-static const unsigned msp0rfsrck_a_1_pins[] = { DB8500_PIN_AD3, DB8500_PIN_AD4 };
-/* Basic pins of the MMC/SD card 0 interface */
-static const unsigned mc0_a_1_pins[] = { DB8500_PIN_AC2, DB8500_PIN_AC1,
-       DB8500_PIN_AB4, DB8500_PIN_AA3, DB8500_PIN_AA4, DB8500_PIN_AB2,
-       DB8500_PIN_Y4, DB8500_PIN_Y2, DB8500_PIN_AA2, DB8500_PIN_AA1 };
-/* Often only 4 bits are used, then these are not needed (only used for MMC) */
-static const unsigned mc0_dat47_a_1_pins[] = { DB8500_PIN_W2, DB8500_PIN_W3,
-       DB8500_PIN_V3, DB8500_PIN_V2};
-static const unsigned mc0dat31dir_a_1_pins[] = { DB8500_PIN_AB3 };
-/* MSP1 can only be on these pins, but TXD and RXD can be flipped */
-static const unsigned msp1txrx_a_1_pins[] = { DB8500_PIN_AF2, DB8500_PIN_AG2 };
-static const unsigned msp1_a_1_pins[] = { DB8500_PIN_AE1, DB8500_PIN_AE2 };
-/* LCD interface */
-static const unsigned lcdb_a_1_pins[] = { DB8500_PIN_F3, DB8500_PIN_F1,
-                                         DB8500_PIN_G3, DB8500_PIN_G2 };
-static const unsigned lcdvsi0_a_1_pins[] = { DB8500_PIN_E1 };
-static const unsigned lcdvsi1_a_1_pins[] = { DB8500_PIN_E2 };
-static const unsigned lcd_d0_d7_a_1_pins[] = {
-       DB8500_PIN_G5, DB8500_PIN_G4, DB8500_PIN_H4, DB8500_PIN_H3,
-       DB8500_PIN_J3, DB8500_PIN_H2, DB8500_PIN_J2, DB8500_PIN_H1 };
-/* D8 thru D11 often used as TVOUT lines */
-static const unsigned lcd_d8_d11_a_1_pins[] = { DB8500_PIN_F4,
-       DB8500_PIN_E3, DB8500_PIN_E4, DB8500_PIN_D2 };
-static const unsigned lcd_d12_d23_a_1_pins[] = {
-       DB8500_PIN_C1, DB8500_PIN_D3, DB8500_PIN_C2, DB8500_PIN_D5,
-       DB8500_PIN_C6, DB8500_PIN_B3, DB8500_PIN_C4, DB8500_PIN_E6,
-       DB8500_PIN_A3, DB8500_PIN_B6, DB8500_PIN_D6, DB8500_PIN_B7 };
-static const unsigned kp_a_1_pins[] = { DB8500_PIN_D7, DB8500_PIN_E8,
-       DB8500_PIN_D8, DB8500_PIN_D9 };
-static const unsigned kpskaskb_a_1_pins[] = { DB8500_PIN_D17, DB8500_PIN_D16 };
-static const unsigned kp_a_2_pins[] = {
-       DB8500_PIN_B17, DB8500_PIN_C16, DB8500_PIN_C19, DB8500_PIN_C17,
-       DB8500_PIN_A18, DB8500_PIN_C18, DB8500_PIN_B19, DB8500_PIN_B20,
-       DB8500_PIN_D21, DB8500_PIN_D20, DB8500_PIN_C20, DB8500_PIN_B21,
-       DB8500_PIN_C21, DB8500_PIN_A22, DB8500_PIN_B24, DB8500_PIN_C22 };
-/* MC2 has 8 data lines and no direction control, so only for (e)MMC */
-static const unsigned mc2_a_1_pins[] = { DB8500_PIN_A5, DB8500_PIN_B4,
-       DB8500_PIN_C8, DB8500_PIN_A12, DB8500_PIN_C10, DB8500_PIN_B10,
-       DB8500_PIN_B9, DB8500_PIN_A9, DB8500_PIN_C7, DB8500_PIN_A7,
-       DB8500_PIN_C5 };
-static const unsigned ssp1_a_1_pins[] = { DB8500_PIN_C9, DB8500_PIN_B11,
-                                         DB8500_PIN_C12, DB8500_PIN_C11 };
-static const unsigned ssp0_a_1_pins[] = { DB8500_PIN_D12, DB8500_PIN_B13,
-                                         DB8500_PIN_C13, DB8500_PIN_D13 };
-static const unsigned i2c0_a_1_pins[] = { DB8500_PIN_C15, DB8500_PIN_B16 };
-/*
- * Image processor GPIO pins are named "ipgpio" and have their own
- * numberspace
- */
-static const unsigned ipgpio0_a_1_pins[] = { DB8500_PIN_B14 };
-static const unsigned ipgpio1_a_1_pins[] = { DB8500_PIN_C14 };
-/* Three modem pins named RF_PURn, MODEM_STATE and MODEM_PWREN */
-static const unsigned modem_a_1_pins[] = { DB8500_PIN_D22, DB8500_PIN_C23,
-                                          DB8500_PIN_D23 };
-/*
- * This MSP cannot switch RX and TX, SCK in a separate group since this
- * seems to be optional.
- */
-static const unsigned msp2sck_a_1_pins[] = { DB8500_PIN_AJ27 };
-static const unsigned msp2_a_1_pins[] = { DB8500_PIN_AH27, DB8500_PIN_AF27,
-                                         DB8500_PIN_AG28, DB8500_PIN_AG26 };
-static const unsigned mc4_a_1_pins[] = { DB8500_PIN_AH24, DB8500_PIN_AG25,
-       DB8500_PIN_AH23, DB8500_PIN_AH26, DB8500_PIN_AF24, DB8500_PIN_AF25,
-       DB8500_PIN_AE23, DB8500_PIN_AF23, DB8500_PIN_AG23, DB8500_PIN_AG24,
-       DB8500_PIN_AJ23 };
-/* MC1 has only 4 data pins, designed for SD or SDIO exclusively */
-static const unsigned mc1_a_1_pins[] = { DB8500_PIN_AH16, DB8500_PIN_AG15,
-       DB8500_PIN_AJ15, DB8500_PIN_AG14, DB8500_PIN_AF13, DB8500_PIN_AG13,
-       DB8500_PIN_AH15 };
-static const unsigned mc1_a_2_pins[] = { DB8500_PIN_AH16, DB8500_PIN_AJ15,
-       DB8500_PIN_AG14, DB8500_PIN_AF13, DB8500_PIN_AG13, DB8500_PIN_AH15 };
-static const unsigned mc1dir_a_1_pins[] = { DB8500_PIN_AH13, DB8500_PIN_AG12,
-       DB8500_PIN_AH12, DB8500_PIN_AH11 };
-static const unsigned hsir_a_1_pins[] = { DB8500_PIN_AG10, DB8500_PIN_AH10,
-       DB8500_PIN_AJ11 };
-static const unsigned hsit_a_1_pins[] = { DB8500_PIN_AJ9, DB8500_PIN_AH9,
-       DB8500_PIN_AG9, DB8500_PIN_AG8, DB8500_PIN_AF8 };
-static const unsigned hsit_a_2_pins[] = { DB8500_PIN_AJ9, DB8500_PIN_AH9,
-       DB8500_PIN_AG9, DB8500_PIN_AG8 };
-static const unsigned clkout1_a_1_pins[] = { DB8500_PIN_AH7 };
-static const unsigned clkout1_a_2_pins[] = { DB8500_PIN_AG7 };
-static const unsigned clkout2_a_1_pins[] = { DB8500_PIN_AJ6 };
-static const unsigned clkout2_a_2_pins[] = { DB8500_PIN_AF7 };
-static const unsigned usb_a_1_pins[] = { DB8500_PIN_AF28, DB8500_PIN_AE29,
-       DB8500_PIN_AD29, DB8500_PIN_AC29, DB8500_PIN_AD28, DB8500_PIN_AD26,
-       DB8500_PIN_AE26, DB8500_PIN_AG29, DB8500_PIN_AE27, DB8500_PIN_AD27,
-       DB8500_PIN_AC28, DB8500_PIN_AC27 };
-
-/* Altfunction B column */
-static const unsigned trig_b_1_pins[] = { DB8500_PIN_AJ5, DB8500_PIN_AJ3 };
-static const unsigned i2c4_b_1_pins[] = { DB8500_PIN_AH6, DB8500_PIN_AG6 };
-static const unsigned i2c1_b_1_pins[] = { DB8500_PIN_AF6, DB8500_PIN_AG5 };
-static const unsigned i2c2_b_1_pins[] = { DB8500_PIN_AD5, DB8500_PIN_AE4 };
-static const unsigned i2c2_b_2_pins[] = { DB8500_PIN_AF5, DB8500_PIN_AG4 };
-static const unsigned msp0txrx_b_1_pins[] = { DB8500_PIN_AC4, DB8500_PIN_AC3 };
-static const unsigned i2c1_b_2_pins[] = { DB8500_PIN_AD3, DB8500_PIN_AD4 };
-/* Just RX and TX for UART2 */
-static const unsigned u2rxtx_b_1_pins[] = { DB8500_PIN_AC2, DB8500_PIN_AC1 };
-static const unsigned uartmodtx_b_1_pins[] = { DB8500_PIN_AB4 };
-static const unsigned msp0sck_b_1_pins[] = { DB8500_PIN_AB3 };
-static const unsigned uartmodrx_b_1_pins[] = { DB8500_PIN_AA3 };
-static const unsigned stmmod_b_1_pins[] = { DB8500_PIN_AA4, DB8500_PIN_Y4,
-       DB8500_PIN_Y2, DB8500_PIN_AA2, DB8500_PIN_AA1 };
-static const unsigned uartmodrx_b_2_pins[] = { DB8500_PIN_AB2 };
-static const unsigned spi3_b_1_pins[] = { DB8500_PIN_W2, DB8500_PIN_W3,
-                                         DB8500_PIN_V3, DB8500_PIN_V2 };
-static const unsigned msp1txrx_b_1_pins[] = { DB8500_PIN_AF2, DB8500_PIN_AG2 };
-static const unsigned kp_b_1_pins[] = { DB8500_PIN_F3, DB8500_PIN_F1,
-       DB8500_PIN_G3, DB8500_PIN_G2, DB8500_PIN_E1, DB8500_PIN_E2,
-       DB8500_PIN_G5, DB8500_PIN_G4, DB8500_PIN_H4, DB8500_PIN_H3,
-       DB8500_PIN_J3, DB8500_PIN_H2, DB8500_PIN_J2, DB8500_PIN_H1,
-       DB8500_PIN_F4, DB8500_PIN_E3, DB8500_PIN_E4, DB8500_PIN_D2,
-       DB8500_PIN_C1, DB8500_PIN_D3, DB8500_PIN_C2, DB8500_PIN_D5 };
-static const unsigned kp_b_2_pins[] = { DB8500_PIN_F3, DB8500_PIN_F1,
-       DB8500_PIN_G3, DB8500_PIN_G2, DB8500_PIN_F4, DB8500_PIN_E3};
-static const unsigned sm_b_1_pins[] = { DB8500_PIN_C6, DB8500_PIN_B3,
-       DB8500_PIN_C4, DB8500_PIN_E6, DB8500_PIN_A3, DB8500_PIN_B6,
-       DB8500_PIN_D6, DB8500_PIN_B7, DB8500_PIN_D7, DB8500_PIN_D8,
-       DB8500_PIN_D9, DB8500_PIN_A5, DB8500_PIN_B4, DB8500_PIN_C8,
-       DB8500_PIN_A12, DB8500_PIN_C10, DB8500_PIN_B10, DB8500_PIN_B9,
-       DB8500_PIN_A9, DB8500_PIN_C7, DB8500_PIN_A7, DB8500_PIN_C5,
-       DB8500_PIN_C9 };
-/* This chip select pin can be "ps0" in alt C so have it separately */
-static const unsigned smcs0_b_1_pins[] = { DB8500_PIN_E8 };
-/* This chip select pin can be "ps1" in alt C so have it separately */
-static const unsigned smcs1_b_1_pins[] = { DB8500_PIN_B14 };
-static const unsigned ipgpio7_b_1_pins[] = { DB8500_PIN_B11 };
-static const unsigned ipgpio2_b_1_pins[] = { DB8500_PIN_C12 };
-static const unsigned ipgpio3_b_1_pins[] = { DB8500_PIN_C11 };
-static const unsigned lcdaclk_b_1_pins[] = { DB8500_PIN_C14 };
-static const unsigned lcda_b_1_pins[] = { DB8500_PIN_D22,
-       DB8500_PIN_C23, DB8500_PIN_D23 };
-static const unsigned lcd_b_1_pins[] = { DB8500_PIN_D17, DB8500_PIN_D16,
-       DB8500_PIN_B17, DB8500_PIN_C16, DB8500_PIN_C19, DB8500_PIN_C17,
-       DB8500_PIN_A18, DB8500_PIN_C18, DB8500_PIN_B19, DB8500_PIN_B20,
-       DB8500_PIN_D21, DB8500_PIN_D20, DB8500_PIN_C20, DB8500_PIN_B21,
-       DB8500_PIN_C21, DB8500_PIN_A22, DB8500_PIN_B24, DB8500_PIN_C22 };
-static const unsigned ddrtrig_b_1_pins[] = { DB8500_PIN_AJ27 };
-static const unsigned pwl_b_1_pins[] = { DB8500_PIN_AF25 };
-static const unsigned spi1_b_1_pins[] = { DB8500_PIN_AG15, DB8500_PIN_AF13,
-                                         DB8500_PIN_AG13, DB8500_PIN_AH15 };
-static const unsigned mc3_b_1_pins[] = { DB8500_PIN_AH13, DB8500_PIN_AG12,
-       DB8500_PIN_AH12, DB8500_PIN_AH11, DB8500_PIN_AG10, DB8500_PIN_AH10,
-       DB8500_PIN_AJ11, DB8500_PIN_AJ9, DB8500_PIN_AH9, DB8500_PIN_AG9,
-       DB8500_PIN_AG8 };
-static const unsigned pwl_b_2_pins[] = { DB8500_PIN_AF8 };
-static const unsigned pwl_b_3_pins[] = { DB8500_PIN_AG7 };
-static const unsigned pwl_b_4_pins[] = { DB8500_PIN_AF7 };
-
-/* Altfunction C column */
-static const unsigned ipjtag_c_1_pins[] = { DB8500_PIN_AJ5, DB8500_PIN_AJ3,
-       DB8500_PIN_AH4, DB8500_PIN_AH3, DB8500_PIN_AH6 };
-static const unsigned ipgpio6_c_1_pins[] = { DB8500_PIN_AG6 };
-static const unsigned ipgpio0_c_1_pins[] = { DB8500_PIN_AF6 };
-static const unsigned ipgpio1_c_1_pins[] = { DB8500_PIN_AG5 };
-static const unsigned ipgpio3_c_1_pins[] = { DB8500_PIN_AF5 };
-static const unsigned ipgpio2_c_1_pins[] = { DB8500_PIN_AG4 };
-static const unsigned slim0_c_1_pins[] = { DB8500_PIN_AD3, DB8500_PIN_AD4 };
-/* Optional 4-bit Memory Stick interface */
-static const unsigned ms_c_1_pins[] = { DB8500_PIN_AC2, DB8500_PIN_AC1,
-       DB8500_PIN_AB3, DB8500_PIN_AA3, DB8500_PIN_AA4, DB8500_PIN_AB2,
-       DB8500_PIN_Y4, DB8500_PIN_Y2, DB8500_PIN_AA2, DB8500_PIN_AA1 };
-static const unsigned iptrigout_c_1_pins[] = { DB8500_PIN_AB4 };
-static const unsigned u2rxtx_c_1_pins[] = { DB8500_PIN_W2, DB8500_PIN_W3 };
-static const unsigned u2ctsrts_c_1_pins[] = { DB8500_PIN_V3, DB8500_PIN_V2 };
-static const unsigned u0_c_1_pins[] = { DB8500_PIN_AF2, DB8500_PIN_AE1,
-                                       DB8500_PIN_AE2, DB8500_PIN_AG2 };
-static const unsigned ipgpio4_c_1_pins[] = { DB8500_PIN_F3 };
-static const unsigned ipgpio5_c_1_pins[] = { DB8500_PIN_F1 };
-static const unsigned ipgpio6_c_2_pins[] = { DB8500_PIN_G3 };
-static const unsigned ipgpio7_c_1_pins[] = { DB8500_PIN_G2 };
-static const unsigned smcleale_c_1_pins[] = { DB8500_PIN_E1, DB8500_PIN_E2 };
-static const unsigned stmape_c_1_pins[] = { DB8500_PIN_G5, DB8500_PIN_G4,
-       DB8500_PIN_H4, DB8500_PIN_H3, DB8500_PIN_J3 };
-static const unsigned u2rxtx_c_2_pins[] = { DB8500_PIN_H2, DB8500_PIN_J2 };
-static const unsigned ipgpio2_c_2_pins[] = { DB8500_PIN_F4 };
-static const unsigned ipgpio3_c_2_pins[] = { DB8500_PIN_E3 };
-static const unsigned ipgpio4_c_2_pins[] = { DB8500_PIN_E4 };
-static const unsigned ipgpio5_c_2_pins[] = { DB8500_PIN_D2 };
-static const unsigned mc5_c_1_pins[] = { DB8500_PIN_C6, DB8500_PIN_B3,
-       DB8500_PIN_C4, DB8500_PIN_E6, DB8500_PIN_A3, DB8500_PIN_B6,
-       DB8500_PIN_D6, DB8500_PIN_B7, DB8500_PIN_D7, DB8500_PIN_D8,
-       DB8500_PIN_D9 };
-static const unsigned mc2rstn_c_1_pins[] = { DB8500_PIN_C8 };
-static const unsigned kp_c_1_pins[] = { DB8500_PIN_C9, DB8500_PIN_B11,
-       DB8500_PIN_C12, DB8500_PIN_C11, DB8500_PIN_D17, DB8500_PIN_D16,
-       DB8500_PIN_C23, DB8500_PIN_D23 };
-static const unsigned smps0_c_1_pins[] = { DB8500_PIN_E8 };
-static const unsigned smps1_c_1_pins[] = { DB8500_PIN_B14 };
-static const unsigned u2rxtx_c_3_pins[] = { DB8500_PIN_B17, DB8500_PIN_C16 };
-static const unsigned stmape_c_2_pins[] = { DB8500_PIN_C19, DB8500_PIN_C17,
-       DB8500_PIN_A18, DB8500_PIN_C18, DB8500_PIN_B19 };
-static const unsigned uartmodrx_c_1_pins[] = { DB8500_PIN_D21 };
-static const unsigned uartmodtx_c_1_pins[] = { DB8500_PIN_D20 };
-static const unsigned stmmod_c_1_pins[] = { DB8500_PIN_C20, DB8500_PIN_B21,
-       DB8500_PIN_C21, DB8500_PIN_A22, DB8500_PIN_B24 };
-static const unsigned usbsim_c_1_pins[] = { DB8500_PIN_D22 };
-static const unsigned mc4rstn_c_1_pins[] = { DB8500_PIN_AF25 };
-static const unsigned clkout1_c_1_pins[] = { DB8500_PIN_AH13 };
-static const unsigned clkout2_c_1_pins[] = { DB8500_PIN_AH12 };
-static const unsigned i2c3_c_1_pins[] = { DB8500_PIN_AG12, DB8500_PIN_AH11 };
-static const unsigned spi0_c_1_pins[] = { DB8500_PIN_AH10, DB8500_PIN_AH9,
-                                         DB8500_PIN_AG9, DB8500_PIN_AG8 };
-static const unsigned usbsim_c_2_pins[] = { DB8500_PIN_AF8 };
-static const unsigned i2c3_c_2_pins[] = { DB8500_PIN_AG7, DB8500_PIN_AF7 };
-
-/* Other C1 column */
-static const unsigned u2rx_oc1_1_pins[] = { DB8500_PIN_AB2 };
-static const unsigned stmape_oc1_1_pins[] = { DB8500_PIN_AA4, DB8500_PIN_Y4,
-       DB8500_PIN_Y2, DB8500_PIN_AA2, DB8500_PIN_AA1 };
-static const unsigned remap0_oc1_1_pins[] = { DB8500_PIN_E1 };
-static const unsigned remap1_oc1_1_pins[] = { DB8500_PIN_E2 };
-static const unsigned ptma9_oc1_1_pins[] = { DB8500_PIN_G5, DB8500_PIN_G4,
-       DB8500_PIN_H4, DB8500_PIN_H3, DB8500_PIN_J3, DB8500_PIN_H2,
-       DB8500_PIN_J2, DB8500_PIN_H1 };
-static const unsigned kp_oc1_1_pins[] = { DB8500_PIN_C6, DB8500_PIN_B3,
-       DB8500_PIN_C4, DB8500_PIN_E6, DB8500_PIN_A3, DB8500_PIN_B6,
-       DB8500_PIN_D6, DB8500_PIN_B7 };
-static const unsigned rf_oc1_1_pins[] = { DB8500_PIN_D8, DB8500_PIN_D9 };
-static const unsigned hxclk_oc1_1_pins[] = { DB8500_PIN_D16 };
-static const unsigned uartmodrx_oc1_1_pins[] = { DB8500_PIN_B17 };
-static const unsigned uartmodtx_oc1_1_pins[] = { DB8500_PIN_C16 };
-static const unsigned stmmod_oc1_1_pins[] = { DB8500_PIN_C19, DB8500_PIN_C17,
-       DB8500_PIN_A18, DB8500_PIN_C18, DB8500_PIN_B19 };
-static const unsigned hxgpio_oc1_1_pins[] = { DB8500_PIN_D21, DB8500_PIN_D20,
-       DB8500_PIN_C20, DB8500_PIN_B21, DB8500_PIN_C21, DB8500_PIN_A22,
-       DB8500_PIN_B24, DB8500_PIN_C22 };
-static const unsigned rf_oc1_2_pins[] = { DB8500_PIN_C23, DB8500_PIN_D23 };
-static const unsigned spi2_oc1_1_pins[] = { DB8500_PIN_AH13, DB8500_PIN_AG12,
-       DB8500_PIN_AH12, DB8500_PIN_AH11 };
-static const unsigned spi2_oc1_2_pins[] = { DB8500_PIN_AH13, DB8500_PIN_AH12,
-       DB8500_PIN_AH11 };
-
-/* Other C2 column */
-static const unsigned sbag_oc2_1_pins[] = { DB8500_PIN_AA4, DB8500_PIN_AB2,
-       DB8500_PIN_Y4, DB8500_PIN_Y2, DB8500_PIN_AA2, DB8500_PIN_AA1 };
-static const unsigned etmr4_oc2_1_pins[] = { DB8500_PIN_G5, DB8500_PIN_G4,
-       DB8500_PIN_H4, DB8500_PIN_H3, DB8500_PIN_J3, DB8500_PIN_H2,
-       DB8500_PIN_J2, DB8500_PIN_H1 };
-static const unsigned ptma9_oc2_1_pins[] = { DB8500_PIN_D17, DB8500_PIN_D16,
-       DB8500_PIN_B17, DB8500_PIN_C16, DB8500_PIN_C19, DB8500_PIN_C17,
-       DB8500_PIN_A18, DB8500_PIN_C18, DB8500_PIN_B19, DB8500_PIN_B20,
-       DB8500_PIN_D21, DB8500_PIN_D20, DB8500_PIN_C20, DB8500_PIN_B21,
-       DB8500_PIN_C21, DB8500_PIN_A22, DB8500_PIN_B24, DB8500_PIN_C22 };
-
-/* Other C3 column */
-static const unsigned stmmod_oc3_1_pins[] = { DB8500_PIN_AB2, DB8500_PIN_W2,
-       DB8500_PIN_W3, DB8500_PIN_V3, DB8500_PIN_V2 };
-static const unsigned stmmod_oc3_2_pins[] = { DB8500_PIN_G5, DB8500_PIN_G4,
-       DB8500_PIN_H4, DB8500_PIN_H3, DB8500_PIN_J3 };
-static const unsigned uartmodrx_oc3_1_pins[] = { DB8500_PIN_H2 };
-static const unsigned uartmodtx_oc3_1_pins[] = { DB8500_PIN_J2 };
-static const unsigned etmr4_oc3_1_pins[] = { DB8500_PIN_D17, DB8500_PIN_D16,
-       DB8500_PIN_B17, DB8500_PIN_C16, DB8500_PIN_C19, DB8500_PIN_C17,
-       DB8500_PIN_A18, DB8500_PIN_C18, DB8500_PIN_B19, DB8500_PIN_B20,
-       DB8500_PIN_D21, DB8500_PIN_D20, DB8500_PIN_C20, DB8500_PIN_B21,
-       DB8500_PIN_C21, DB8500_PIN_A22, DB8500_PIN_B24, DB8500_PIN_C22 };
-
-/* Other C4 column */
-static const unsigned sbag_oc4_1_pins[] = { DB8500_PIN_G5, DB8500_PIN_G4,
-       DB8500_PIN_H4, DB8500_PIN_H3, DB8500_PIN_J3, DB8500_PIN_H1 };
-static const unsigned hwobs_oc4_1_pins[] = { DB8500_PIN_D17, DB8500_PIN_D16,
-       DB8500_PIN_B17, DB8500_PIN_C16, DB8500_PIN_C19, DB8500_PIN_C17,
-       DB8500_PIN_A18, DB8500_PIN_C18, DB8500_PIN_B19, DB8500_PIN_B20,
-       DB8500_PIN_D21, DB8500_PIN_D20, DB8500_PIN_C20, DB8500_PIN_B21,
-       DB8500_PIN_C21, DB8500_PIN_A22, DB8500_PIN_B24, DB8500_PIN_C22 };
-
-#define DB8500_PIN_GROUP(a, b) { .name = #a, .pins = a##_pins,         \
-                       .npins = ARRAY_SIZE(a##_pins), .altsetting = b }
-
-static const struct nmk_pingroup nmk_db8500_groups[] = {
-       /* Altfunction A column */
-       DB8500_PIN_GROUP(u0_a_1, NMK_GPIO_ALT_A),
-       DB8500_PIN_GROUP(u1rxtx_a_1, NMK_GPIO_ALT_A),
-       DB8500_PIN_GROUP(u1ctsrts_a_1, NMK_GPIO_ALT_A),
-       DB8500_PIN_GROUP(ipi2c_a_1, NMK_GPIO_ALT_A),
-       DB8500_PIN_GROUP(ipi2c_a_2, NMK_GPIO_ALT_A),
-       DB8500_PIN_GROUP(msp0txrx_a_1, NMK_GPIO_ALT_A),
-       DB8500_PIN_GROUP(msp0tfstck_a_1, NMK_GPIO_ALT_A),
-       DB8500_PIN_GROUP(msp0rfsrck_a_1, NMK_GPIO_ALT_A),
-       DB8500_PIN_GROUP(mc0_a_1, NMK_GPIO_ALT_A),
-       DB8500_PIN_GROUP(mc0_dat47_a_1, NMK_GPIO_ALT_A),
-       DB8500_PIN_GROUP(mc0dat31dir_a_1, NMK_GPIO_ALT_A),
-       DB8500_PIN_GROUP(msp1txrx_a_1, NMK_GPIO_ALT_A),
-       DB8500_PIN_GROUP(msp1_a_1, NMK_GPIO_ALT_A),
-       DB8500_PIN_GROUP(lcdb_a_1, NMK_GPIO_ALT_A),
-       DB8500_PIN_GROUP(lcdvsi0_a_1, NMK_GPIO_ALT_A),
-       DB8500_PIN_GROUP(lcdvsi1_a_1, NMK_GPIO_ALT_A),
-       DB8500_PIN_GROUP(lcd_d0_d7_a_1, NMK_GPIO_ALT_A),
-       DB8500_PIN_GROUP(lcd_d8_d11_a_1, NMK_GPIO_ALT_A),
-       DB8500_PIN_GROUP(lcd_d12_d23_a_1, NMK_GPIO_ALT_A),
-       DB8500_PIN_GROUP(kp_a_1, NMK_GPIO_ALT_A),
-       DB8500_PIN_GROUP(mc2_a_1, NMK_GPIO_ALT_A),
-       DB8500_PIN_GROUP(ssp1_a_1, NMK_GPIO_ALT_A),
-       DB8500_PIN_GROUP(ssp0_a_1, NMK_GPIO_ALT_A),
-       DB8500_PIN_GROUP(i2c0_a_1, NMK_GPIO_ALT_A),
-       DB8500_PIN_GROUP(ipgpio0_a_1, NMK_GPIO_ALT_A),
-       DB8500_PIN_GROUP(ipgpio1_a_1, NMK_GPIO_ALT_A),
-       DB8500_PIN_GROUP(kp_a_2, NMK_GPIO_ALT_A),
-       DB8500_PIN_GROUP(msp2sck_a_1, NMK_GPIO_ALT_A),
-       DB8500_PIN_GROUP(msp2_a_1, NMK_GPIO_ALT_A),
-       DB8500_PIN_GROUP(mc4_a_1, NMK_GPIO_ALT_A),
-       DB8500_PIN_GROUP(mc1_a_1, NMK_GPIO_ALT_A),
-       DB8500_PIN_GROUP(mc1_a_2, NMK_GPIO_ALT_A),
-       DB8500_PIN_GROUP(hsir_a_1, NMK_GPIO_ALT_A),
-       DB8500_PIN_GROUP(hsit_a_1, NMK_GPIO_ALT_A),
-       DB8500_PIN_GROUP(hsit_a_2, NMK_GPIO_ALT_A),
-       DB8500_PIN_GROUP(clkout1_a_1, NMK_GPIO_ALT_A),
-       DB8500_PIN_GROUP(clkout1_a_2, NMK_GPIO_ALT_A),
-       DB8500_PIN_GROUP(clkout2_a_1, NMK_GPIO_ALT_A),
-       DB8500_PIN_GROUP(clkout2_a_2, NMK_GPIO_ALT_A),
-       DB8500_PIN_GROUP(usb_a_1, NMK_GPIO_ALT_A),
-       /* Altfunction B column */
-       DB8500_PIN_GROUP(trig_b_1, NMK_GPIO_ALT_B),
-       DB8500_PIN_GROUP(i2c4_b_1, NMK_GPIO_ALT_B),
-       DB8500_PIN_GROUP(i2c1_b_1, NMK_GPIO_ALT_B),
-       DB8500_PIN_GROUP(i2c2_b_1, NMK_GPIO_ALT_B),
-       DB8500_PIN_GROUP(i2c2_b_2, NMK_GPIO_ALT_B),
-       DB8500_PIN_GROUP(msp0txrx_b_1, NMK_GPIO_ALT_B),
-       DB8500_PIN_GROUP(i2c1_b_2, NMK_GPIO_ALT_B),
-       DB8500_PIN_GROUP(u2rxtx_b_1, NMK_GPIO_ALT_B),
-       DB8500_PIN_GROUP(uartmodtx_b_1, NMK_GPIO_ALT_B),
-       DB8500_PIN_GROUP(msp0sck_b_1, NMK_GPIO_ALT_B),
-       DB8500_PIN_GROUP(uartmodrx_b_1, NMK_GPIO_ALT_B),
-       DB8500_PIN_GROUP(stmmod_b_1, NMK_GPIO_ALT_B),
-       DB8500_PIN_GROUP(uartmodrx_b_2, NMK_GPIO_ALT_B),
-       DB8500_PIN_GROUP(spi3_b_1, NMK_GPIO_ALT_B),
-       DB8500_PIN_GROUP(msp1txrx_b_1, NMK_GPIO_ALT_B),
-       DB8500_PIN_GROUP(kp_b_1, NMK_GPIO_ALT_B),
-       DB8500_PIN_GROUP(kp_b_2, NMK_GPIO_ALT_B),
-       DB8500_PIN_GROUP(sm_b_1, NMK_GPIO_ALT_B),
-       DB8500_PIN_GROUP(smcs0_b_1, NMK_GPIO_ALT_B),
-       DB8500_PIN_GROUP(smcs1_b_1, NMK_GPIO_ALT_B),
-       DB8500_PIN_GROUP(ipgpio7_b_1, NMK_GPIO_ALT_B),
-       DB8500_PIN_GROUP(ipgpio2_b_1, NMK_GPIO_ALT_B),
-       DB8500_PIN_GROUP(ipgpio3_b_1, NMK_GPIO_ALT_B),
-       DB8500_PIN_GROUP(lcdaclk_b_1, NMK_GPIO_ALT_B),
-       DB8500_PIN_GROUP(lcda_b_1, NMK_GPIO_ALT_B),
-       DB8500_PIN_GROUP(lcd_b_1, NMK_GPIO_ALT_B),
-       DB8500_PIN_GROUP(ddrtrig_b_1, NMK_GPIO_ALT_B),
-       DB8500_PIN_GROUP(pwl_b_1, NMK_GPIO_ALT_B),
-       DB8500_PIN_GROUP(spi1_b_1, NMK_GPIO_ALT_B),
-       DB8500_PIN_GROUP(mc3_b_1, NMK_GPIO_ALT_B),
-       DB8500_PIN_GROUP(pwl_b_2, NMK_GPIO_ALT_B),
-       DB8500_PIN_GROUP(pwl_b_3, NMK_GPIO_ALT_B),
-       DB8500_PIN_GROUP(pwl_b_4, NMK_GPIO_ALT_B),
-       /* Altfunction C column */
-       DB8500_PIN_GROUP(ipjtag_c_1, NMK_GPIO_ALT_C),
-       DB8500_PIN_GROUP(ipgpio6_c_1, NMK_GPIO_ALT_C),
-       DB8500_PIN_GROUP(ipgpio0_c_1, NMK_GPIO_ALT_C),
-       DB8500_PIN_GROUP(ipgpio1_c_1, NMK_GPIO_ALT_C),
-       DB8500_PIN_GROUP(ipgpio3_c_1, NMK_GPIO_ALT_C),
-       DB8500_PIN_GROUP(ipgpio2_c_1, NMK_GPIO_ALT_C),
-       DB8500_PIN_GROUP(slim0_c_1, NMK_GPIO_ALT_C),
-       DB8500_PIN_GROUP(ms_c_1, NMK_GPIO_ALT_C),
-       DB8500_PIN_GROUP(iptrigout_c_1, NMK_GPIO_ALT_C),
-       DB8500_PIN_GROUP(u2rxtx_c_1, NMK_GPIO_ALT_C),
-       DB8500_PIN_GROUP(u2ctsrts_c_1, NMK_GPIO_ALT_C),
-       DB8500_PIN_GROUP(u0_c_1, NMK_GPIO_ALT_C),
-       DB8500_PIN_GROUP(ipgpio4_c_1, NMK_GPIO_ALT_C),
-       DB8500_PIN_GROUP(ipgpio5_c_1, NMK_GPIO_ALT_C),
-       DB8500_PIN_GROUP(ipgpio6_c_1, NMK_GPIO_ALT_C),
-       DB8500_PIN_GROUP(ipgpio7_c_1, NMK_GPIO_ALT_C),
-       DB8500_PIN_GROUP(smcleale_c_1, NMK_GPIO_ALT_C),
-       DB8500_PIN_GROUP(stmape_c_1, NMK_GPIO_ALT_C),
-       DB8500_PIN_GROUP(u2rxtx_c_2, NMK_GPIO_ALT_C),
-       DB8500_PIN_GROUP(ipgpio2_c_2, NMK_GPIO_ALT_C),
-       DB8500_PIN_GROUP(ipgpio3_c_2, NMK_GPIO_ALT_C),
-       DB8500_PIN_GROUP(ipgpio4_c_2, NMK_GPIO_ALT_C),
-       DB8500_PIN_GROUP(ipgpio5_c_2, NMK_GPIO_ALT_C),
-       DB8500_PIN_GROUP(mc5_c_1, NMK_GPIO_ALT_C),
-       DB8500_PIN_GROUP(mc2rstn_c_1, NMK_GPIO_ALT_C),
-       DB8500_PIN_GROUP(kp_c_1, NMK_GPIO_ALT_C),
-       DB8500_PIN_GROUP(smps0_c_1, NMK_GPIO_ALT_C),
-       DB8500_PIN_GROUP(smps1_c_1, NMK_GPIO_ALT_C),
-       DB8500_PIN_GROUP(u2rxtx_c_3, NMK_GPIO_ALT_C),
-       DB8500_PIN_GROUP(stmape_c_2, NMK_GPIO_ALT_C),
-       DB8500_PIN_GROUP(uartmodrx_c_1, NMK_GPIO_ALT_C),
-       DB8500_PIN_GROUP(uartmodtx_c_1, NMK_GPIO_ALT_C),
-       DB8500_PIN_GROUP(stmmod_c_1, NMK_GPIO_ALT_C),
-       DB8500_PIN_GROUP(usbsim_c_1, NMK_GPIO_ALT_C),
-       DB8500_PIN_GROUP(mc4rstn_c_1, NMK_GPIO_ALT_C),
-       DB8500_PIN_GROUP(clkout1_c_1, NMK_GPIO_ALT_C),
-       DB8500_PIN_GROUP(clkout2_c_1, NMK_GPIO_ALT_C),
-       DB8500_PIN_GROUP(i2c3_c_1, NMK_GPIO_ALT_C),
-       DB8500_PIN_GROUP(spi0_c_1, NMK_GPIO_ALT_C),
-       DB8500_PIN_GROUP(usbsim_c_2, NMK_GPIO_ALT_C),
-       DB8500_PIN_GROUP(i2c3_c_2, NMK_GPIO_ALT_C),
-       /* Other alt C1 column */
-       DB8500_PIN_GROUP(u2rx_oc1_1, NMK_GPIO_ALT_C1),
-       DB8500_PIN_GROUP(stmape_oc1_1, NMK_GPIO_ALT_C1),
-       DB8500_PIN_GROUP(remap0_oc1_1, NMK_GPIO_ALT_C1),
-       DB8500_PIN_GROUP(remap1_oc1_1, NMK_GPIO_ALT_C1),
-       DB8500_PIN_GROUP(ptma9_oc1_1, NMK_GPIO_ALT_C1),
-       DB8500_PIN_GROUP(kp_oc1_1, NMK_GPIO_ALT_C1),
-       DB8500_PIN_GROUP(rf_oc1_1, NMK_GPIO_ALT_C1),
-       DB8500_PIN_GROUP(hxclk_oc1_1, NMK_GPIO_ALT_C1),
-       DB8500_PIN_GROUP(uartmodrx_oc1_1, NMK_GPIO_ALT_C1),
-       DB8500_PIN_GROUP(uartmodtx_oc1_1, NMK_GPIO_ALT_C1),
-       DB8500_PIN_GROUP(stmmod_oc1_1, NMK_GPIO_ALT_C1),
-       DB8500_PIN_GROUP(hxgpio_oc1_1, NMK_GPIO_ALT_C1),
-       DB8500_PIN_GROUP(rf_oc1_2, NMK_GPIO_ALT_C1),
-       DB8500_PIN_GROUP(spi2_oc1_1, NMK_GPIO_ALT_C1),
-       DB8500_PIN_GROUP(spi2_oc1_2, NMK_GPIO_ALT_C1),
-       /* Other alt C2 column */
-       DB8500_PIN_GROUP(sbag_oc2_1, NMK_GPIO_ALT_C2),
-       DB8500_PIN_GROUP(etmr4_oc2_1, NMK_GPIO_ALT_C2),
-       DB8500_PIN_GROUP(ptma9_oc2_1, NMK_GPIO_ALT_C2),
-       /* Other alt C3 column */
-       DB8500_PIN_GROUP(stmmod_oc3_1, NMK_GPIO_ALT_C3),
-       DB8500_PIN_GROUP(stmmod_oc3_2, NMK_GPIO_ALT_C3),
-       DB8500_PIN_GROUP(uartmodrx_oc3_1, NMK_GPIO_ALT_C3),
-       DB8500_PIN_GROUP(uartmodtx_oc3_1, NMK_GPIO_ALT_C3),
-       DB8500_PIN_GROUP(etmr4_oc3_1, NMK_GPIO_ALT_C3),
-       /* Other alt C4 column */
-       DB8500_PIN_GROUP(sbag_oc4_1, NMK_GPIO_ALT_C4),
-       DB8500_PIN_GROUP(hwobs_oc4_1, NMK_GPIO_ALT_C4),
-};
-
-/* We use this macro to define the groups applicable to a function */
-#define DB8500_FUNC_GROUPS(a, b...)       \
-static const char * const a##_groups[] = { b };
-
-DB8500_FUNC_GROUPS(u0, "u0_a_1", "u0_c_1");
-DB8500_FUNC_GROUPS(u1, "u1rxtx_a_1", "u1ctsrts_a_1");
-/*
- * UART2 can be muxed out with just RX/TX in four places, CTS+RTS is however
- * only available on two pins in alternative function C
- */
-DB8500_FUNC_GROUPS(u2, "u2rxtx_b_1", "u2rxtx_c_1", "u2ctsrts_c_1",
-                  "u2rxtx_c_2", "u2rxtx_c_3", "u2rx_oc1_1");
-DB8500_FUNC_GROUPS(ipi2c, "ipi2c_a_1", "ipi2c_a_2");
-/*
- * MSP0 can only be on a certain set of pins, but the TX/RX pins can be
- * switched around by selecting the altfunction A or B. The SCK pin is
- * only available on the altfunction B.
- */
-DB8500_FUNC_GROUPS(msp0, "msp0txrx_a_1", "msp0tfstck_a_1", "msp0rfstck_a_1",
-                  "msp0txrx_b_1", "msp0sck_b_1");
-DB8500_FUNC_GROUPS(mc0, "mc0_a_1", "mc0_dat47_a_1", "mc0dat31dir_a_1");
-/* MSP0 can swap RX/TX like MSP0 but has no SCK pin available */
-DB8500_FUNC_GROUPS(msp1, "msp1txrx_a_1", "msp1_a_1", "msp1txrx_b_1");
-DB8500_FUNC_GROUPS(lcdb, "lcdb_a_1");
-DB8500_FUNC_GROUPS(lcd, "lcdvsi0_a_1", "lcdvsi1_a_1", "lcd_d0_d7_a_1",
-       "lcd_d8_d11_a_1", "lcd_d12_d23_a_1", "lcd_b_1");
-DB8500_FUNC_GROUPS(kp, "kp_a_1", "kp_a_2", "kp_b_1", "kp_b_2", "kp_c_1", "kp_oc1_1");
-DB8500_FUNC_GROUPS(mc2, "mc2_a_1", "mc2rstn_c_1");
-DB8500_FUNC_GROUPS(ssp1, "ssp1_a_1");
-DB8500_FUNC_GROUPS(ssp0, "ssp0_a_1");
-DB8500_FUNC_GROUPS(i2c0, "i2c0_a_1");
-/* The image processor has 8 GPIO pins that can be muxed out */
-DB8500_FUNC_GROUPS(ipgpio, "ipgpio0_a_1", "ipgpio1_a_1", "ipgpio7_b_1",
-       "ipgpio2_b_1", "ipgpio3_b_1", "ipgpio6_c_1", "ipgpio0_c_1",
-       "ipgpio1_c_1", "ipgpio3_c_1", "ipgpio2_c_1", "ipgpio4_c_1",
-       "ipgpio5_c_1", "ipgpio6_c_2", "ipgpio7_c_1", "ipgpio2_c_2",
-       "ipgpio3_c_2", "ipgpio4_c_2", "ipgpio5_c_2");
-/* MSP2 can not invert the RX/TX pins but has the optional SCK pin */
-DB8500_FUNC_GROUPS(msp2, "msp2sck_a_1", "msp2_a_1");
-DB8500_FUNC_GROUPS(mc4, "mc4_a_1", "mc4rstn_c_1");
-DB8500_FUNC_GROUPS(mc1, "mc1_a_1", "mc1_a_2", "mc1dir_a_1");
-DB8500_FUNC_GROUPS(hsi, "hsir_a_1", "hsit_a_1", "hsit_a_2");
-DB8500_FUNC_GROUPS(clkout, "clkout1_a_1", "clkout1_a_2", "clkout1_c_1",
-               "clkout2_a_1", "clkout2_a_2", "clkout2_c_1");
-DB8500_FUNC_GROUPS(usb, "usb_a_1");
-DB8500_FUNC_GROUPS(trig, "trig_b_1");
-DB8500_FUNC_GROUPS(i2c4, "i2c4_b_1");
-DB8500_FUNC_GROUPS(i2c1, "i2c1_b_1", "i2c1_b_2");
-DB8500_FUNC_GROUPS(i2c2, "i2c2_b_1", "i2c2_b_2");
-/*
- * The modem UART can output its RX and TX pins in some different places,
- * so select one of each.
- */
-DB8500_FUNC_GROUPS(uartmod, "uartmodtx_b_1", "uartmodrx_b_1", "uartmodrx_b_2",
-               "uartmodrx_c_1", "uartmod_tx_c_1", "uartmodrx_oc1_1",
-               "uartmodtx_oc1_1", "uartmodrx_oc3_1", "uartmodtx_oc3_1");
-DB8500_FUNC_GROUPS(stmmod, "stmmod_b_1", "stmmod_c_1", "stmmod_oc1_1",
-               "stmmod_oc3_1", "stmmod_oc3_2");
-DB8500_FUNC_GROUPS(spi3, "spi3_b_1");
-/* Select between CS0 on alt B or PS1 on alt C */
-DB8500_FUNC_GROUPS(sm, "sm_b_1", "smcs0_b_1", "smcs1_b_1", "smcleale_c_1",
-                  "smps0_c_1", "smps1_c_1");
-DB8500_FUNC_GROUPS(lcda, "lcdaclk_b_1", "lcda_b_1");
-DB8500_FUNC_GROUPS(ddrtrig, "ddrtrig_b_1");
-DB8500_FUNC_GROUPS(pwl, "pwl_b_1", "pwl_b_2", "pwl_b_3", "pwl_b_4");
-DB8500_FUNC_GROUPS(spi1, "spi1_b_1");
-DB8500_FUNC_GROUPS(mc3, "mc3_b_1");
-DB8500_FUNC_GROUPS(ipjtag, "ipjtag_c_1");
-DB8500_FUNC_GROUPS(slim0, "slim0_c_1");
-DB8500_FUNC_GROUPS(ms, "ms_c_1");
-DB8500_FUNC_GROUPS(iptrigout, "iptrigout_c_1");
-DB8500_FUNC_GROUPS(stmape, "stmape_c_1", "stmape_c_2", "stmape_oc1_1");
-DB8500_FUNC_GROUPS(mc5, "mc5_c_1");
-DB8500_FUNC_GROUPS(usbsim, "usbsim_c_1", "usbsim_c_2");
-DB8500_FUNC_GROUPS(i2c3, "i2c3_c_1", "i2c3_c_2");
-DB8500_FUNC_GROUPS(spi0, "spi0_c_1");
-DB8500_FUNC_GROUPS(spi2, "spi2_oc1_1", "spi2_oc1_2");
-DB8500_FUNC_GROUPS(remap, "remap0_oc1_1", "remap1_oc1_1");
-DB8500_FUNC_GROUPS(sbag, "sbag_oc2_1", "sbag_oc4_1");
-DB8500_FUNC_GROUPS(ptm, "ptma9_oc1_1", "ptma9_oc2_1");
-DB8500_FUNC_GROUPS(rf, "rf_oc1_1", "rf_oc1_2");
-DB8500_FUNC_GROUPS(hx, "hxclk_oc1_1", "hxgpio_oc1_1");
-DB8500_FUNC_GROUPS(etm, "etmr4_oc2_1", "etmr4_oc3_1");
-DB8500_FUNC_GROUPS(hwobs, "hwobs_oc4_1");
-#define FUNCTION(fname)                                        \
-       {                                               \
-               .name = #fname,                         \
-               .groups = fname##_groups,               \
-               .ngroups = ARRAY_SIZE(fname##_groups),  \
-       }
-
-static const struct nmk_function nmk_db8500_functions[] = {
-       FUNCTION(u0),
-       FUNCTION(u1),
-       FUNCTION(u2),
-       FUNCTION(ipi2c),
-       FUNCTION(msp0),
-       FUNCTION(mc0),
-       FUNCTION(msp1),
-       FUNCTION(lcdb),
-       FUNCTION(lcd),
-       FUNCTION(kp),
-       FUNCTION(mc2),
-       FUNCTION(ssp1),
-       FUNCTION(ssp0),
-       FUNCTION(i2c0),
-       FUNCTION(ipgpio),
-       FUNCTION(msp2),
-       FUNCTION(mc4),
-       FUNCTION(mc1),
-       FUNCTION(hsi),
-       FUNCTION(clkout),
-       FUNCTION(usb),
-       FUNCTION(trig),
-       FUNCTION(i2c4),
-       FUNCTION(i2c1),
-       FUNCTION(i2c2),
-       FUNCTION(uartmod),
-       FUNCTION(stmmod),
-       FUNCTION(spi3),
-       FUNCTION(sm),
-       FUNCTION(lcda),
-       FUNCTION(ddrtrig),
-       FUNCTION(pwl),
-       FUNCTION(spi1),
-       FUNCTION(mc3),
-       FUNCTION(ipjtag),
-       FUNCTION(slim0),
-       FUNCTION(ms),
-       FUNCTION(iptrigout),
-       FUNCTION(stmape),
-       FUNCTION(mc5),
-       FUNCTION(usbsim),
-       FUNCTION(i2c3),
-       FUNCTION(spi0),
-       FUNCTION(spi2),
-       FUNCTION(remap),
-       FUNCTION(ptm),
-       FUNCTION(rf),
-       FUNCTION(hx),
-       FUNCTION(etm),
-       FUNCTION(hwobs),
-};
-
-static const struct prcm_gpiocr_altcx_pin_desc db8500_altcx_pins[] = {
-       PRCM_GPIOCR_ALTCX(23,   true, PRCM_IDX_GPIOCR1, 9,      /* STMAPE_CLK_a */
-                               true, PRCM_IDX_GPIOCR1, 7,      /* SBAG_CLK_a */
-                               false, 0, 0,
-                               false, 0, 0
-       ),
-       PRCM_GPIOCR_ALTCX(24,   true, PRCM_IDX_GPIOCR1, 9,      /* STMAPE or U2_RXD ??? */
-                               true, PRCM_IDX_GPIOCR1, 7,      /* SBAG_VAL_a */
-                               true, PRCM_IDX_GPIOCR1, 10,     /* STM_MOD_CMD0 */
-                               false, 0, 0
-       ),
-       PRCM_GPIOCR_ALTCX(25,   true, PRCM_IDX_GPIOCR1, 9,      /* STMAPE_DAT_a[0] */
-                               true, PRCM_IDX_GPIOCR1, 7,      /* SBAG_D_a[0] */
-                               false, 0, 0,
-                               false, 0, 0
-       ),
-       PRCM_GPIOCR_ALTCX(26,   true, PRCM_IDX_GPIOCR1, 9,      /* STMAPE_DAT_a[1] */
-                               true, PRCM_IDX_GPIOCR1, 7,      /* SBAG_D_a[1] */
-                               false, 0, 0,
-                               false, 0, 0
-       ),
-       PRCM_GPIOCR_ALTCX(27,   true, PRCM_IDX_GPIOCR1, 9,      /* STMAPE_DAT_a[2] */
-                               true, PRCM_IDX_GPIOCR1, 7,      /* SBAG_D_a[2] */
-                               false, 0, 0,
-                               false, 0, 0
-       ),
-       PRCM_GPIOCR_ALTCX(28,   true, PRCM_IDX_GPIOCR1, 9,      /* STMAPE_DAT_a[3] */
-                               true, PRCM_IDX_GPIOCR1, 7,      /* SBAG_D_a[3] */
-                               false, 0, 0,
-                               false, 0, 0
-       ),
-       PRCM_GPIOCR_ALTCX(29,   false, 0, 0,
-                               false, 0, 0,
-                               true, PRCM_IDX_GPIOCR1, 10,     /* STM_MOD_CMD0 */
-                               false, 0, 0
-       ),
-       PRCM_GPIOCR_ALTCX(30,   false, 0, 0,
-                               false, 0, 0,
-                               true, PRCM_IDX_GPIOCR1, 10,     /* STM_MOD_CMD0 */
-                               false, 0, 0
-       ),
-       PRCM_GPIOCR_ALTCX(31,   false, 0, 0,
-                               false, 0, 0,
-                               true, PRCM_IDX_GPIOCR1, 10,     /* STM_MOD_CMD0 */
-                               false, 0, 0
-       ),
-       PRCM_GPIOCR_ALTCX(32,   false, 0, 0,
-                               false, 0, 0,
-                               true, PRCM_IDX_GPIOCR1, 10,     /* STM_MOD_CMD0 */
-                               false, 0, 0
-       ),
-       PRCM_GPIOCR_ALTCX(68,   true, PRCM_IDX_GPIOCR1, 18,     /* REMAP_SELECT_ON */
-                               false, 0, 0,
-                               false, 0, 0,
-                               false, 0, 0
-       ),
-       PRCM_GPIOCR_ALTCX(69,   true, PRCM_IDX_GPIOCR1, 18,     /* REMAP_SELECT_ON */
-                               false, 0, 0,
-                               false, 0, 0,
-                               false, 0, 0
-       ),
-       PRCM_GPIOCR_ALTCX(70,   true, PRCM_IDX_GPIOCR1, 5,      /* PTM_A9_D23 */
-                               true, PRCM_IDX_GPIOCR2, 2,      /* DBG_ETM_R4_CMD0 */
-                               true, PRCM_IDX_GPIOCR1, 11,     /* STM_MOD_CMD1 */
-                               true, PRCM_IDX_GPIOCR1, 8       /* SBAG_CLK */
-       ),
-       PRCM_GPIOCR_ALTCX(71,   true, PRCM_IDX_GPIOCR1, 5,      /* PTM_A9_D22 */
-                               true, PRCM_IDX_GPIOCR2, 2,      /* DBG_ETM_R4_CMD0 */
-                               true, PRCM_IDX_GPIOCR1, 11,     /* STM_MOD_CMD1 */
-                               true, PRCM_IDX_GPIOCR1, 8       /* SBAG_D3 */
-       ),
-       PRCM_GPIOCR_ALTCX(72,   true, PRCM_IDX_GPIOCR1, 5,      /* PTM_A9_D21 */
-                               true, PRCM_IDX_GPIOCR2, 2,      /* DBG_ETM_R4_CMD0 */
-                               true, PRCM_IDX_GPIOCR1, 11,     /* STM_MOD_CMD1 */
-                               true, PRCM_IDX_GPIOCR1, 8       /* SBAG_D2 */
-       ),
-       PRCM_GPIOCR_ALTCX(73,   true, PRCM_IDX_GPIOCR1, 5,      /* PTM_A9_D20 */
-                               true, PRCM_IDX_GPIOCR2, 2,      /* DBG_ETM_R4_CMD0 */
-                               true, PRCM_IDX_GPIOCR1, 11,     /* STM_MOD_CMD1 */
-                               true, PRCM_IDX_GPIOCR1, 8       /* SBAG_D1 */
-       ),
-       PRCM_GPIOCR_ALTCX(74,   true, PRCM_IDX_GPIOCR1, 5,      /* PTM_A9_D19 */
-                               true, PRCM_IDX_GPIOCR2, 2,      /* DBG_ETM_R4_CMD0 */
-                               true, PRCM_IDX_GPIOCR1, 11,     /* STM_MOD_CMD1 */
-                               true, PRCM_IDX_GPIOCR1, 8       /* SBAG_D0 */
-       ),
-       PRCM_GPIOCR_ALTCX(75,   true, PRCM_IDX_GPIOCR1, 5,      /* PTM_A9_D18 */
-                               true, PRCM_IDX_GPIOCR2, 2,      /* DBG_ETM_R4_CMD0 */
-                               true, PRCM_IDX_GPIOCR1, 0,      /* DBG_UARTMOD_CMD0 */
-                               false, 0, 0
-       ),
-       PRCM_GPIOCR_ALTCX(76,   true, PRCM_IDX_GPIOCR1, 5,      /* PTM_A9_D17 */
-                               true, PRCM_IDX_GPIOCR2, 2,      /* DBG_ETM_R4_CMD0 */
-                               true, PRCM_IDX_GPIOCR1, 0,      /* DBG_UARTMOD_CMD0 */
-                               false, 0, 0
-       ),
-       PRCM_GPIOCR_ALTCX(77,   true, PRCM_IDX_GPIOCR1, 5,      /* PTM_A9_D16 */
-                               true, PRCM_IDX_GPIOCR2, 2,      /* DBG_ETM_R4_CMD0 */
-                               false, 0, 0,
-                               true, PRCM_IDX_GPIOCR1, 8       /* SBAG_VAL */
-       ),
-       PRCM_GPIOCR_ALTCX(86,   true, PRCM_IDX_GPIOCR1, 12,     /* KP_O3 */
-                               false, 0, 0,
-                               false, 0, 0,
-                               false, 0, 0
-       ),
-       PRCM_GPIOCR_ALTCX(87,   true, PRCM_IDX_GPIOCR1, 12,     /* KP_O2 */
-                               false, 0, 0,
-                               false, 0, 0,
-                               false, 0, 0
-       ),
-       PRCM_GPIOCR_ALTCX(88,   true, PRCM_IDX_GPIOCR1, 12,     /* KP_I3 */
-                               false, 0, 0,
-                               false, 0, 0,
-                               false, 0, 0
-       ),
-       PRCM_GPIOCR_ALTCX(89,   true, PRCM_IDX_GPIOCR1, 12,     /* KP_I2 */
-                               false, 0, 0,
-                               false, 0, 0,
-                               false, 0, 0
-       ),
-       PRCM_GPIOCR_ALTCX(90,   true, PRCM_IDX_GPIOCR1, 12,     /* KP_O1 */
-                               false, 0, 0,
-                               false, 0, 0,
-                               false, 0, 0
-       ),
-       PRCM_GPIOCR_ALTCX(91,   true, PRCM_IDX_GPIOCR1, 12,     /* KP_O0 */
-                               false, 0, 0,
-                               false, 0, 0,
-                               false, 0, 0
-       ),
-       PRCM_GPIOCR_ALTCX(92,   true, PRCM_IDX_GPIOCR1, 12,     /* KP_I1 */
-                               false, 0, 0,
-                               false, 0, 0,
-                               false, 0, 0
-       ),
-       PRCM_GPIOCR_ALTCX(93,   true, PRCM_IDX_GPIOCR1, 12,     /* KP_I0 */
-                               false, 0, 0,
-                               false, 0, 0,
-                               false, 0, 0
-       ),
-       PRCM_GPIOCR_ALTCX(96,   true, PRCM_IDX_GPIOCR2, 3,      /* RF_INT */
-                               false, 0, 0,
-                               false, 0, 0,
-                               false, 0, 0
-       ),
-       PRCM_GPIOCR_ALTCX(97,   true, PRCM_IDX_GPIOCR2, 1,      /* RF_CTRL */
-                               false, 0, 0,
-                               false, 0, 0,
-                               false, 0, 0
-       ),
-       PRCM_GPIOCR_ALTCX(151,  false, 0, 0,
-                               true, PRCM_IDX_GPIOCR1, 6,      /* PTM_A9_CTL */
-                               true, PRCM_IDX_GPIOCR1, 15,     /* DBG_ETM_R4_CMD1*/
-                               true, PRCM_IDX_GPIOCR1, 25      /* HW_OBS17 */
-       ),
-       PRCM_GPIOCR_ALTCX(152,  true, PRCM_IDX_GPIOCR1, 4,      /* Hx_CLK */
-                               true, PRCM_IDX_GPIOCR1, 6,      /* PTM_A9_CLK */
-                               true, PRCM_IDX_GPIOCR1, 15,     /* DBG_ETM_R4_CMD1*/
-                               true, PRCM_IDX_GPIOCR1, 25      /* HW_OBS16 */
-       ),
-       PRCM_GPIOCR_ALTCX(153,  true, PRCM_IDX_GPIOCR1, 1,      /* UARTMOD_CMD1 */
-                               true, PRCM_IDX_GPIOCR1, 14,     /* PTM_A9_D15 */
-                               true, PRCM_IDX_GPIOCR1, 19,     /* DBG_ETM_R4_CMD2 */
-                               true, PRCM_IDX_GPIOCR1, 25      /* HW_OBS15 */
-       ),
-       PRCM_GPIOCR_ALTCX(154,  true, PRCM_IDX_GPIOCR1, 1,      /* UARTMOD_CMD1 */
-                               true, PRCM_IDX_GPIOCR1, 14,     /* PTM_A9_D14 */
-                               true, PRCM_IDX_GPIOCR1, 19,     /* DBG_ETM_R4_CMD2 */
-                               true, PRCM_IDX_GPIOCR1, 25      /* HW_OBS14 */
-       ),
-       PRCM_GPIOCR_ALTCX(155,  true, PRCM_IDX_GPIOCR1, 13,     /* STM_MOD_CMD2 */
-                               true, PRCM_IDX_GPIOCR1, 14,     /* PTM_A9_D13 */
-                               true, PRCM_IDX_GPIOCR1, 19,     /* DBG_ETM_R4_CMD2 */
-                               true, PRCM_IDX_GPIOCR1, 25      /* HW_OBS13 */
-       ),
-       PRCM_GPIOCR_ALTCX(156,  true, PRCM_IDX_GPIOCR1, 13,     /* STM_MOD_CMD2 */
-                               true, PRCM_IDX_GPIOCR1, 14,     /* PTM_A9_D12 */
-                               true, PRCM_IDX_GPIOCR1, 19,     /* DBG_ETM_R4_CMD2 */
-                               true, PRCM_IDX_GPIOCR1, 25      /* HW_OBS12 */
-       ),
-       PRCM_GPIOCR_ALTCX(157,  true, PRCM_IDX_GPIOCR1, 13,     /* STM_MOD_CMD2 */
-                               true, PRCM_IDX_GPIOCR1, 14,     /* PTM_A9_D11 */
-                               true, PRCM_IDX_GPIOCR1, 19,     /* DBG_ETM_R4_CMD2 */
-                               true, PRCM_IDX_GPIOCR1, 25      /* HW_OBS11 */
-       ),
-       PRCM_GPIOCR_ALTCX(158,  true, PRCM_IDX_GPIOCR1, 13,     /* STM_MOD_CMD2 */
-                               true, PRCM_IDX_GPIOCR1, 14,     /* PTM_A9_D10 */
-                               true, PRCM_IDX_GPIOCR1, 19,     /* DBG_ETM_R4_CMD2 */
-                               true, PRCM_IDX_GPIOCR1, 25      /* HW_OBS10 */
-       ),
-       PRCM_GPIOCR_ALTCX(159,  true, PRCM_IDX_GPIOCR1, 13,     /* STM_MOD_CMD2 */
-                               true, PRCM_IDX_GPIOCR1, 14,     /* PTM_A9_D9 */
-                               true, PRCM_IDX_GPIOCR1, 19,     /* DBG_ETM_R4_CMD2 */
-                               true, PRCM_IDX_GPIOCR1, 25      /* HW_OBS9 */
-       ),
-       PRCM_GPIOCR_ALTCX(160,  false, 0, 0,
-                               true, PRCM_IDX_GPIOCR1, 14,     /* PTM_A9_D8 */
-                               true, PRCM_IDX_GPIOCR1, 19,     /* DBG_ETM_R4_CMD2 */
-                               true, PRCM_IDX_GPIOCR1, 25      /* HW_OBS8 */
-       ),
-       PRCM_GPIOCR_ALTCX(161,  true, PRCM_IDX_GPIOCR1, 4,      /* Hx_GPIO7 */
-                               true, PRCM_IDX_GPIOCR1, 6,      /* PTM_A9_D7 */
-                               true, PRCM_IDX_GPIOCR1, 15,     /* DBG_ETM_R4_CMD1*/
-                               true, PRCM_IDX_GPIOCR1, 24      /* HW_OBS7 */
-       ),
-       PRCM_GPIOCR_ALTCX(162,  true, PRCM_IDX_GPIOCR1, 4,      /* Hx_GPIO6 */
-                               true, PRCM_IDX_GPIOCR1, 6,      /* PTM_A9_D6 */
-                               true, PRCM_IDX_GPIOCR1, 15,     /* DBG_ETM_R4_CMD1*/
-                               true, PRCM_IDX_GPIOCR1, 24      /* HW_OBS6 */
-       ),
-       PRCM_GPIOCR_ALTCX(163,  true, PRCM_IDX_GPIOCR1, 4,      /* Hx_GPIO5 */
-                               true, PRCM_IDX_GPIOCR1, 6,      /* PTM_A9_D5 */
-                               true, PRCM_IDX_GPIOCR1, 15,     /* DBG_ETM_R4_CMD1*/
-                               true, PRCM_IDX_GPIOCR1, 24      /* HW_OBS5 */
-       ),
-       PRCM_GPIOCR_ALTCX(164,  true, PRCM_IDX_GPIOCR1, 4,      /* Hx_GPIO4 */
-                               true, PRCM_IDX_GPIOCR1, 6,      /* PTM_A9_D4 */
-                               true, PRCM_IDX_GPIOCR1, 15,     /* DBG_ETM_R4_CMD1*/
-                               true, PRCM_IDX_GPIOCR1, 24      /* HW_OBS4 */
-       ),
-       PRCM_GPIOCR_ALTCX(165,  true, PRCM_IDX_GPIOCR1, 4,      /* Hx_GPIO3 */
-                               true, PRCM_IDX_GPIOCR1, 6,      /* PTM_A9_D3 */
-                               true, PRCM_IDX_GPIOCR1, 15,     /* DBG_ETM_R4_CMD1*/
-                               true, PRCM_IDX_GPIOCR1, 24      /* HW_OBS3 */
-       ),
-       PRCM_GPIOCR_ALTCX(166,  true, PRCM_IDX_GPIOCR1, 4,      /* Hx_GPIO2 */
-                               true, PRCM_IDX_GPIOCR1, 6,      /* PTM_A9_D2 */
-                               true, PRCM_IDX_GPIOCR1, 15,     /* DBG_ETM_R4_CMD1*/
-                               true, PRCM_IDX_GPIOCR1, 24      /* HW_OBS2 */
-       ),
-       PRCM_GPIOCR_ALTCX(167,  true, PRCM_IDX_GPIOCR1, 4,      /* Hx_GPIO1 */
-                               true, PRCM_IDX_GPIOCR1, 6,      /* PTM_A9_D1 */
-                               true, PRCM_IDX_GPIOCR1, 15,     /* DBG_ETM_R4_CMD1*/
-                               true, PRCM_IDX_GPIOCR1, 24      /* HW_OBS1 */
-       ),
-       PRCM_GPIOCR_ALTCX(168,  true, PRCM_IDX_GPIOCR1, 4,      /* Hx_GPIO0 */
-                               true, PRCM_IDX_GPIOCR1, 6,      /* PTM_A9_D0 */
-                               true, PRCM_IDX_GPIOCR1, 15,     /* DBG_ETM_R4_CMD1*/
-                               true, PRCM_IDX_GPIOCR1, 24      /* HW_OBS0 */
-       ),
-       PRCM_GPIOCR_ALTCX(170,  true, PRCM_IDX_GPIOCR2, 2,      /* RF_INT */
-                               false, 0, 0,
-                               false, 0, 0,
-                               false, 0, 0
-       ),
-       PRCM_GPIOCR_ALTCX(171,  true, PRCM_IDX_GPIOCR2, 0,      /* RF_CTRL */
-                               false, 0, 0,
-                               false, 0, 0,
-                               false, 0, 0
-       ),
-       PRCM_GPIOCR_ALTCX(215,  true, PRCM_IDX_GPIOCR1, 23,     /* SPI2_TXD */
-                               false, 0, 0,
-                               false, 0, 0,
-                               false, 0, 0
-       ),
-       PRCM_GPIOCR_ALTCX(216,  true, PRCM_IDX_GPIOCR1, 23,     /* SPI2_FRM */
-                               false, 0, 0,
-                               false, 0, 0,
-                               false, 0, 0
-       ),
-       PRCM_GPIOCR_ALTCX(217,  true, PRCM_IDX_GPIOCR1, 23,     /* SPI2_CLK */
-                               false, 0, 0,
-                               false, 0, 0,
-                               false, 0, 0
-       ),
-       PRCM_GPIOCR_ALTCX(218,  true, PRCM_IDX_GPIOCR1, 23,     /* SPI2_RXD */
-                               false, 0, 0,
-                               false, 0, 0,
-                               false, 0, 0
-       ),
-};
-
-static const u16 db8500_prcm_gpiocr_regs[] = {
-       [PRCM_IDX_GPIOCR1] = 0x138,
-       [PRCM_IDX_GPIOCR2] = 0x574,
-};
-
-static const struct nmk_pinctrl_soc_data nmk_db8500_soc = {
-       .gpio_ranges = nmk_db8500_ranges,
-       .gpio_num_ranges = ARRAY_SIZE(nmk_db8500_ranges),
-       .pins = nmk_db8500_pins,
-       .npins = ARRAY_SIZE(nmk_db8500_pins),
-       .functions = nmk_db8500_functions,
-       .nfunctions = ARRAY_SIZE(nmk_db8500_functions),
-       .groups = nmk_db8500_groups,
-       .ngroups = ARRAY_SIZE(nmk_db8500_groups),
-       .altcx_pins = db8500_altcx_pins,
-       .npins_altcx = ARRAY_SIZE(db8500_altcx_pins),
-       .prcm_gpiocr_registers = db8500_prcm_gpiocr_regs,
-};
-
-void nmk_pinctrl_db8500_init(const struct nmk_pinctrl_soc_data **soc)
-{
-       *soc = &nmk_db8500_soc;
-}
diff --git a/drivers/pinctrl/pinctrl-nomadik-db8540.c b/drivers/pinctrl/pinctrl-nomadik-db8540.c
deleted file mode 100644 (file)
index d7ba544..0000000
+++ /dev/null
@@ -1,1266 +0,0 @@
-#include <linux/kernel.h>
-#include <linux/pinctrl/pinctrl.h>
-#include "pinctrl-nomadik.h"
-
-/* All the pins that can be used for GPIO and some other functions */
-#define _GPIO(offset)          (offset)
-
-#define DB8540_PIN_AH6         _GPIO(0)
-#define DB8540_PIN_AG7         _GPIO(1)
-#define DB8540_PIN_AF2         _GPIO(2)
-#define DB8540_PIN_AD3         _GPIO(3)
-#define DB8540_PIN_AF6         _GPIO(4)
-#define DB8540_PIN_AG6         _GPIO(5)
-#define DB8540_PIN_AD5         _GPIO(6)
-#define DB8540_PIN_AF7         _GPIO(7)
-#define DB8540_PIN_AG5         _GPIO(8)
-#define DB8540_PIN_AH5         _GPIO(9)
-#define DB8540_PIN_AE4         _GPIO(10)
-#define DB8540_PIN_AD1         _GPIO(11)
-#define DB8540_PIN_AD2         _GPIO(12)
-#define DB8540_PIN_AC2         _GPIO(13)
-#define DB8540_PIN_AC4         _GPIO(14)
-#define DB8540_PIN_AC3         _GPIO(15)
-#define DB8540_PIN_AH7         _GPIO(16)
-#define DB8540_PIN_AE7         _GPIO(17)
-/* Hole */
-#define DB8540_PIN_AF8         _GPIO(22)
-#define DB8540_PIN_AH11                _GPIO(23)
-#define DB8540_PIN_AG11                _GPIO(24)
-#define DB8540_PIN_AF11                _GPIO(25)
-#define DB8540_PIN_AH10                _GPIO(26)
-#define DB8540_PIN_AG10                _GPIO(27)
-#define DB8540_PIN_AF10                _GPIO(28)
-/* Hole */
-#define DB8540_PIN_AD4         _GPIO(33)
-#define DB8540_PIN_AF3         _GPIO(34)
-#define DB8540_PIN_AF5         _GPIO(35)
-#define DB8540_PIN_AG4         _GPIO(36)
-#define DB8540_PIN_AF9         _GPIO(37)
-#define DB8540_PIN_AE8         _GPIO(38)
-/* Hole */
-#define DB8540_PIN_M26         _GPIO(64)
-#define DB8540_PIN_M25         _GPIO(65)
-#define DB8540_PIN_M27         _GPIO(66)
-#define DB8540_PIN_N25         _GPIO(67)
-/* Hole */
-#define DB8540_PIN_M28         _GPIO(70)
-#define DB8540_PIN_N26         _GPIO(71)
-#define DB8540_PIN_M22         _GPIO(72)
-#define DB8540_PIN_N22         _GPIO(73)
-#define DB8540_PIN_N27         _GPIO(74)
-#define DB8540_PIN_N28         _GPIO(75)
-#define DB8540_PIN_P22         _GPIO(76)
-#define DB8540_PIN_P28         _GPIO(77)
-#define DB8540_PIN_P26         _GPIO(78)
-#define DB8540_PIN_T22         _GPIO(79)
-#define DB8540_PIN_R27         _GPIO(80)
-#define DB8540_PIN_P27         _GPIO(81)
-#define DB8540_PIN_R26         _GPIO(82)
-#define DB8540_PIN_R25         _GPIO(83)
-#define DB8540_PIN_U22         _GPIO(84)
-#define DB8540_PIN_T27         _GPIO(85)
-#define DB8540_PIN_T25         _GPIO(86)
-#define DB8540_PIN_T26         _GPIO(87)
-/* Hole */
-#define DB8540_PIN_AF20                _GPIO(116)
-#define DB8540_PIN_AG21                _GPIO(117)
-#define DB8540_PIN_AH19                _GPIO(118)
-#define DB8540_PIN_AE19                _GPIO(119)
-#define DB8540_PIN_AG18                _GPIO(120)
-#define DB8540_PIN_AH17                _GPIO(121)
-#define DB8540_PIN_AF19                _GPIO(122)
-#define DB8540_PIN_AF18                _GPIO(123)
-#define DB8540_PIN_AE18                _GPIO(124)
-#define DB8540_PIN_AG17                _GPIO(125)
-#define DB8540_PIN_AF17                _GPIO(126)
-#define DB8540_PIN_AE17                _GPIO(127)
-#define DB8540_PIN_AC27                _GPIO(128)
-#define DB8540_PIN_AD27                _GPIO(129)
-#define DB8540_PIN_AE28                _GPIO(130)
-#define DB8540_PIN_AG26                _GPIO(131)
-#define DB8540_PIN_AF25                _GPIO(132)
-#define DB8540_PIN_AE27                _GPIO(133)
-#define DB8540_PIN_AF27                _GPIO(134)
-#define DB8540_PIN_AG28                _GPIO(135)
-#define DB8540_PIN_AF28                _GPIO(136)
-#define DB8540_PIN_AG25                _GPIO(137)
-#define DB8540_PIN_AG24                _GPIO(138)
-#define DB8540_PIN_AD25                _GPIO(139)
-#define DB8540_PIN_AH25                _GPIO(140)
-#define DB8540_PIN_AF26                _GPIO(141)
-#define DB8540_PIN_AF23                _GPIO(142)
-#define DB8540_PIN_AG23                _GPIO(143)
-#define DB8540_PIN_AE25                _GPIO(144)
-#define DB8540_PIN_AH24                _GPIO(145)
-#define DB8540_PIN_AJ25                _GPIO(146)
-#define DB8540_PIN_AG27                _GPIO(147)
-#define DB8540_PIN_AH23                _GPIO(148)
-#define DB8540_PIN_AE26                _GPIO(149)
-#define DB8540_PIN_AE24                _GPIO(150)
-#define DB8540_PIN_AJ24                _GPIO(151)
-#define DB8540_PIN_AE21                _GPIO(152)
-#define DB8540_PIN_AG22                _GPIO(153)
-#define DB8540_PIN_AF21                _GPIO(154)
-#define DB8540_PIN_AF24                _GPIO(155)
-#define DB8540_PIN_AH22                _GPIO(156)
-#define DB8540_PIN_AJ23                _GPIO(157)
-#define DB8540_PIN_AH21                _GPIO(158)
-#define DB8540_PIN_AG20                _GPIO(159)
-#define DB8540_PIN_AE23                _GPIO(160)
-#define DB8540_PIN_AH20                _GPIO(161)
-#define DB8540_PIN_AG19                _GPIO(162)
-#define DB8540_PIN_AF22                _GPIO(163)
-#define DB8540_PIN_AJ21                _GPIO(164)
-#define DB8540_PIN_AD26                _GPIO(165)
-#define DB8540_PIN_AD28                _GPIO(166)
-#define DB8540_PIN_AC28                _GPIO(167)
-#define DB8540_PIN_AC26                _GPIO(168)
-/* Hole */
-#define DB8540_PIN_J3          _GPIO(192)
-#define DB8540_PIN_H1          _GPIO(193)
-#define DB8540_PIN_J2          _GPIO(194)
-#define DB8540_PIN_H2          _GPIO(195)
-#define DB8540_PIN_H3          _GPIO(196)
-#define DB8540_PIN_H4          _GPIO(197)
-#define DB8540_PIN_G2          _GPIO(198)
-#define DB8540_PIN_G3          _GPIO(199)
-#define DB8540_PIN_G4          _GPIO(200)
-#define DB8540_PIN_F2          _GPIO(201)
-#define DB8540_PIN_C6          _GPIO(202)
-#define DB8540_PIN_B6          _GPIO(203)
-#define DB8540_PIN_B7          _GPIO(204)
-#define DB8540_PIN_A7          _GPIO(205)
-#define DB8540_PIN_D7          _GPIO(206)
-#define DB8540_PIN_D8          _GPIO(207)
-#define DB8540_PIN_F3          _GPIO(208)
-#define DB8540_PIN_E2          _GPIO(209)
-#define DB8540_PIN_C7          _GPIO(210)
-#define DB8540_PIN_B8          _GPIO(211)
-#define DB8540_PIN_C10         _GPIO(212)
-#define DB8540_PIN_C8          _GPIO(213)
-#define DB8540_PIN_C9          _GPIO(214)
-/* Hole */
-#define DB8540_PIN_B9          _GPIO(219)
-#define DB8540_PIN_A10         _GPIO(220)
-#define DB8540_PIN_D9          _GPIO(221)
-#define DB8540_PIN_B11         _GPIO(222)
-#define DB8540_PIN_B10         _GPIO(223)
-#define DB8540_PIN_E10         _GPIO(224)
-#define DB8540_PIN_B12         _GPIO(225)
-#define DB8540_PIN_D10         _GPIO(226)
-#define DB8540_PIN_D11         _GPIO(227)
-#define DB8540_PIN_AJ6         _GPIO(228)
-#define DB8540_PIN_B13         _GPIO(229)
-#define DB8540_PIN_C12         _GPIO(230)
-#define DB8540_PIN_B14         _GPIO(231)
-#define DB8540_PIN_E11         _GPIO(232)
-/* Hole */
-#define DB8540_PIN_D12         _GPIO(256)
-#define DB8540_PIN_D15         _GPIO(257)
-#define DB8540_PIN_C13         _GPIO(258)
-#define DB8540_PIN_C14         _GPIO(259)
-#define DB8540_PIN_C18         _GPIO(260)
-#define DB8540_PIN_C16         _GPIO(261)
-#define DB8540_PIN_B16         _GPIO(262)
-#define DB8540_PIN_D18         _GPIO(263)
-#define DB8540_PIN_C15         _GPIO(264)
-#define DB8540_PIN_C17         _GPIO(265)
-#define DB8540_PIN_B17         _GPIO(266)
-#define DB8540_PIN_D17         _GPIO(267)
-
-/*
- * The names of the pins are denoted by GPIO number and ball name, even
- * though they can be used for other things than GPIO, this is the first
- * column in the table of the data sheet and often used on schematics and
- * such.
- */
-static const struct pinctrl_pin_desc nmk_db8540_pins[] = {
-       PINCTRL_PIN(DB8540_PIN_AH6, "GPIO0_AH6"),
-       PINCTRL_PIN(DB8540_PIN_AG7, "GPIO1_AG7"),
-       PINCTRL_PIN(DB8540_PIN_AF2, "GPIO2_AF2"),
-       PINCTRL_PIN(DB8540_PIN_AD3, "GPIO3_AD3"),
-       PINCTRL_PIN(DB8540_PIN_AF6, "GPIO4_AF6"),
-       PINCTRL_PIN(DB8540_PIN_AG6, "GPIO5_AG6"),
-       PINCTRL_PIN(DB8540_PIN_AD5, "GPIO6_AD5"),
-       PINCTRL_PIN(DB8540_PIN_AF7, "GPIO7_AF7"),
-       PINCTRL_PIN(DB8540_PIN_AG5, "GPIO8_AG5"),
-       PINCTRL_PIN(DB8540_PIN_AH5, "GPIO9_AH5"),
-       PINCTRL_PIN(DB8540_PIN_AE4, "GPIO10_AE4"),
-       PINCTRL_PIN(DB8540_PIN_AD1, "GPIO11_AD1"),
-       PINCTRL_PIN(DB8540_PIN_AD2, "GPIO12_AD2"),
-       PINCTRL_PIN(DB8540_PIN_AC2, "GPIO13_AC2"),
-       PINCTRL_PIN(DB8540_PIN_AC4, "GPIO14_AC4"),
-       PINCTRL_PIN(DB8540_PIN_AC3, "GPIO15_AC3"),
-       PINCTRL_PIN(DB8540_PIN_AH7, "GPIO16_AH7"),
-       PINCTRL_PIN(DB8540_PIN_AE7, "GPIO17_AE7"),
-       /* Hole */
-       PINCTRL_PIN(DB8540_PIN_AF8, "GPIO22_AF8"),
-       PINCTRL_PIN(DB8540_PIN_AH11, "GPIO23_AH11"),
-       PINCTRL_PIN(DB8540_PIN_AG11, "GPIO24_AG11"),
-       PINCTRL_PIN(DB8540_PIN_AF11, "GPIO25_AF11"),
-       PINCTRL_PIN(DB8540_PIN_AH10, "GPIO26_AH10"),
-       PINCTRL_PIN(DB8540_PIN_AG10, "GPIO27_AG10"),
-       PINCTRL_PIN(DB8540_PIN_AF10, "GPIO28_AF10"),
-       /* Hole */
-       PINCTRL_PIN(DB8540_PIN_AD4, "GPIO33_AD4"),
-       PINCTRL_PIN(DB8540_PIN_AF3, "GPIO34_AF3"),
-       PINCTRL_PIN(DB8540_PIN_AF5, "GPIO35_AF5"),
-       PINCTRL_PIN(DB8540_PIN_AG4, "GPIO36_AG4"),
-       PINCTRL_PIN(DB8540_PIN_AF9, "GPIO37_AF9"),
-       PINCTRL_PIN(DB8540_PIN_AE8, "GPIO38_AE8"),
-       /* Hole */
-       PINCTRL_PIN(DB8540_PIN_M26, "GPIO64_M26"),
-       PINCTRL_PIN(DB8540_PIN_M25, "GPIO65_M25"),
-       PINCTRL_PIN(DB8540_PIN_M27, "GPIO66_M27"),
-       PINCTRL_PIN(DB8540_PIN_N25, "GPIO67_N25"),
-       /* Hole */
-       PINCTRL_PIN(DB8540_PIN_M28, "GPIO70_M28"),
-       PINCTRL_PIN(DB8540_PIN_N26, "GPIO71_N26"),
-       PINCTRL_PIN(DB8540_PIN_M22, "GPIO72_M22"),
-       PINCTRL_PIN(DB8540_PIN_N22, "GPIO73_N22"),
-       PINCTRL_PIN(DB8540_PIN_N27, "GPIO74_N27"),
-       PINCTRL_PIN(DB8540_PIN_N28, "GPIO75_N28"),
-       PINCTRL_PIN(DB8540_PIN_P22, "GPIO76_P22"),
-       PINCTRL_PIN(DB8540_PIN_P28, "GPIO77_P28"),
-       PINCTRL_PIN(DB8540_PIN_P26, "GPIO78_P26"),
-       PINCTRL_PIN(DB8540_PIN_T22, "GPIO79_T22"),
-       PINCTRL_PIN(DB8540_PIN_R27, "GPIO80_R27"),
-       PINCTRL_PIN(DB8540_PIN_P27, "GPIO81_P27"),
-       PINCTRL_PIN(DB8540_PIN_R26, "GPIO82_R26"),
-       PINCTRL_PIN(DB8540_PIN_R25, "GPIO83_R25"),
-       PINCTRL_PIN(DB8540_PIN_U22, "GPIO84_U22"),
-       PINCTRL_PIN(DB8540_PIN_T27, "GPIO85_T27"),
-       PINCTRL_PIN(DB8540_PIN_T25, "GPIO86_T25"),
-       PINCTRL_PIN(DB8540_PIN_T26, "GPIO87_T26"),
-       /* Hole */
-       PINCTRL_PIN(DB8540_PIN_AF20, "GPIO116_AF20"),
-       PINCTRL_PIN(DB8540_PIN_AG21, "GPIO117_AG21"),
-       PINCTRL_PIN(DB8540_PIN_AH19, "GPIO118_AH19"),
-       PINCTRL_PIN(DB8540_PIN_AE19, "GPIO119_AE19"),
-       PINCTRL_PIN(DB8540_PIN_AG18, "GPIO120_AG18"),
-       PINCTRL_PIN(DB8540_PIN_AH17, "GPIO121_AH17"),
-       PINCTRL_PIN(DB8540_PIN_AF19, "GPIO122_AF19"),
-       PINCTRL_PIN(DB8540_PIN_AF18, "GPIO123_AF18"),
-       PINCTRL_PIN(DB8540_PIN_AE18, "GPIO124_AE18"),
-       PINCTRL_PIN(DB8540_PIN_AG17, "GPIO125_AG17"),
-       PINCTRL_PIN(DB8540_PIN_AF17, "GPIO126_AF17"),
-       PINCTRL_PIN(DB8540_PIN_AE17, "GPIO127_AE17"),
-       PINCTRL_PIN(DB8540_PIN_AC27, "GPIO128_AC27"),
-       PINCTRL_PIN(DB8540_PIN_AD27, "GPIO129_AD27"),
-       PINCTRL_PIN(DB8540_PIN_AE28, "GPIO130_AE28"),
-       PINCTRL_PIN(DB8540_PIN_AG26, "GPIO131_AG26"),
-       PINCTRL_PIN(DB8540_PIN_AF25, "GPIO132_AF25"),
-       PINCTRL_PIN(DB8540_PIN_AE27, "GPIO133_AE27"),
-       PINCTRL_PIN(DB8540_PIN_AF27, "GPIO134_AF27"),
-       PINCTRL_PIN(DB8540_PIN_AG28, "GPIO135_AG28"),
-       PINCTRL_PIN(DB8540_PIN_AF28, "GPIO136_AF28"),
-       PINCTRL_PIN(DB8540_PIN_AG25, "GPIO137_AG25"),
-       PINCTRL_PIN(DB8540_PIN_AG24, "GPIO138_AG24"),
-       PINCTRL_PIN(DB8540_PIN_AD25, "GPIO139_AD25"),
-       PINCTRL_PIN(DB8540_PIN_AH25, "GPIO140_AH25"),
-       PINCTRL_PIN(DB8540_PIN_AF26, "GPIO141_AF26"),
-       PINCTRL_PIN(DB8540_PIN_AF23, "GPIO142_AF23"),
-       PINCTRL_PIN(DB8540_PIN_AG23, "GPIO143_AG23"),
-       PINCTRL_PIN(DB8540_PIN_AE25, "GPIO144_AE25"),
-       PINCTRL_PIN(DB8540_PIN_AH24, "GPIO145_AH24"),
-       PINCTRL_PIN(DB8540_PIN_AJ25, "GPIO146_AJ25"),
-       PINCTRL_PIN(DB8540_PIN_AG27, "GPIO147_AG27"),
-       PINCTRL_PIN(DB8540_PIN_AH23, "GPIO148_AH23"),
-       PINCTRL_PIN(DB8540_PIN_AE26, "GPIO149_AE26"),
-       PINCTRL_PIN(DB8540_PIN_AE24, "GPIO150_AE24"),
-       PINCTRL_PIN(DB8540_PIN_AJ24, "GPIO151_AJ24"),
-       PINCTRL_PIN(DB8540_PIN_AE21, "GPIO152_AE21"),
-       PINCTRL_PIN(DB8540_PIN_AG22, "GPIO153_AG22"),
-       PINCTRL_PIN(DB8540_PIN_AF21, "GPIO154_AF21"),
-       PINCTRL_PIN(DB8540_PIN_AF24, "GPIO155_AF24"),
-       PINCTRL_PIN(DB8540_PIN_AH22, "GPIO156_AH22"),
-       PINCTRL_PIN(DB8540_PIN_AJ23, "GPIO157_AJ23"),
-       PINCTRL_PIN(DB8540_PIN_AH21, "GPIO158_AH21"),
-       PINCTRL_PIN(DB8540_PIN_AG20, "GPIO159_AG20"),
-       PINCTRL_PIN(DB8540_PIN_AE23, "GPIO160_AE23"),
-       PINCTRL_PIN(DB8540_PIN_AH20, "GPIO161_AH20"),
-       PINCTRL_PIN(DB8540_PIN_AG19, "GPIO162_AG19"),
-       PINCTRL_PIN(DB8540_PIN_AF22, "GPIO163_AF22"),
-       PINCTRL_PIN(DB8540_PIN_AJ21, "GPIO164_AJ21"),
-       PINCTRL_PIN(DB8540_PIN_AD26, "GPIO165_AD26"),
-       PINCTRL_PIN(DB8540_PIN_AD28, "GPIO166_AD28"),
-       PINCTRL_PIN(DB8540_PIN_AC28, "GPIO167_AC28"),
-       PINCTRL_PIN(DB8540_PIN_AC26, "GPIO168_AC26"),
-       /* Hole */
-       PINCTRL_PIN(DB8540_PIN_J3, "GPIO192_J3"),
-       PINCTRL_PIN(DB8540_PIN_H1, "GPIO193_H1"),
-       PINCTRL_PIN(DB8540_PIN_J2, "GPIO194_J2"),
-       PINCTRL_PIN(DB8540_PIN_H2, "GPIO195_H2"),
-       PINCTRL_PIN(DB8540_PIN_H3, "GPIO196_H3"),
-       PINCTRL_PIN(DB8540_PIN_H4, "GPIO197_H4"),
-       PINCTRL_PIN(DB8540_PIN_G2, "GPIO198_G2"),
-       PINCTRL_PIN(DB8540_PIN_G3, "GPIO199_G3"),
-       PINCTRL_PIN(DB8540_PIN_G4, "GPIO200_G4"),
-       PINCTRL_PIN(DB8540_PIN_F2, "GPIO201_F2"),
-       PINCTRL_PIN(DB8540_PIN_C6, "GPIO202_C6"),
-       PINCTRL_PIN(DB8540_PIN_B6, "GPIO203_B6"),
-       PINCTRL_PIN(DB8540_PIN_B7, "GPIO204_B7"),
-       PINCTRL_PIN(DB8540_PIN_A7, "GPIO205_A7"),
-       PINCTRL_PIN(DB8540_PIN_D7, "GPIO206_D7"),
-       PINCTRL_PIN(DB8540_PIN_D8, "GPIO207_D8"),
-       PINCTRL_PIN(DB8540_PIN_F3, "GPIO208_F3"),
-       PINCTRL_PIN(DB8540_PIN_E2, "GPIO209_E2"),
-       PINCTRL_PIN(DB8540_PIN_C7, "GPIO210_C7"),
-       PINCTRL_PIN(DB8540_PIN_B8, "GPIO211_B8"),
-       PINCTRL_PIN(DB8540_PIN_C10, "GPIO212_C10"),
-       PINCTRL_PIN(DB8540_PIN_C8, "GPIO213_C8"),
-       PINCTRL_PIN(DB8540_PIN_C9, "GPIO214_C9"),
-       /* Hole */
-       PINCTRL_PIN(DB8540_PIN_B9, "GPIO219_B9"),
-       PINCTRL_PIN(DB8540_PIN_A10, "GPIO220_A10"),
-       PINCTRL_PIN(DB8540_PIN_D9, "GPIO221_D9"),
-       PINCTRL_PIN(DB8540_PIN_B11, "GPIO222_B11"),
-       PINCTRL_PIN(DB8540_PIN_B10, "GPIO223_B10"),
-       PINCTRL_PIN(DB8540_PIN_E10, "GPIO224_E10"),
-       PINCTRL_PIN(DB8540_PIN_B12, "GPIO225_B12"),
-       PINCTRL_PIN(DB8540_PIN_D10, "GPIO226_D10"),
-       PINCTRL_PIN(DB8540_PIN_D11, "GPIO227_D11"),
-       PINCTRL_PIN(DB8540_PIN_AJ6, "GPIO228_AJ6"),
-       PINCTRL_PIN(DB8540_PIN_B13, "GPIO229_B13"),
-       PINCTRL_PIN(DB8540_PIN_C12, "GPIO230_C12"),
-       PINCTRL_PIN(DB8540_PIN_B14, "GPIO231_B14"),
-       PINCTRL_PIN(DB8540_PIN_E11, "GPIO232_E11"),
-       /* Hole */
-       PINCTRL_PIN(DB8540_PIN_D12, "GPIO256_D12"),
-       PINCTRL_PIN(DB8540_PIN_D15, "GPIO257_D15"),
-       PINCTRL_PIN(DB8540_PIN_C13, "GPIO258_C13"),
-       PINCTRL_PIN(DB8540_PIN_C14, "GPIO259_C14"),
-       PINCTRL_PIN(DB8540_PIN_C18, "GPIO260_C18"),
-       PINCTRL_PIN(DB8540_PIN_C16, "GPIO261_C16"),
-       PINCTRL_PIN(DB8540_PIN_B16, "GPIO262_B16"),
-       PINCTRL_PIN(DB8540_PIN_D18, "GPIO263_D18"),
-       PINCTRL_PIN(DB8540_PIN_C15, "GPIO264_C15"),
-       PINCTRL_PIN(DB8540_PIN_C17, "GPIO265_C17"),
-       PINCTRL_PIN(DB8540_PIN_B17, "GPIO266_B17"),
-       PINCTRL_PIN(DB8540_PIN_D17, "GPIO267_D17"),
-};
-
-#define DB8540_GPIO_RANGE(a, b, c) { .name = "db8540", .id = a, .base = b, \
-                       .pin_base = b, .npins = c }
-
-/*
- * This matches the 32-pin gpio chips registered by the GPIO portion. This
- * cannot be const since we assign the struct gpio_chip * pointer at runtime.
- */
-static struct pinctrl_gpio_range nmk_db8540_ranges[] = {
-       DB8540_GPIO_RANGE(0, 0, 18),
-       DB8540_GPIO_RANGE(0, 22, 7),
-       DB8540_GPIO_RANGE(1, 33, 6),
-       DB8540_GPIO_RANGE(2, 64, 4),
-       DB8540_GPIO_RANGE(2, 70, 18),
-       DB8540_GPIO_RANGE(3, 116, 12),
-       DB8540_GPIO_RANGE(4, 128, 32),
-       DB8540_GPIO_RANGE(5, 160, 9),
-       DB8540_GPIO_RANGE(6, 192, 23),
-       DB8540_GPIO_RANGE(6, 219, 5),
-       DB8540_GPIO_RANGE(7, 224, 9),
-       DB8540_GPIO_RANGE(8, 256, 12),
-};
-
-/*
- * Read the pin group names like this:
- * u0_a_1    = first groups of pins for uart0 on alt function a
- * i2c2_b_2  = second group of pins for i2c2 on alt function b
- *
- * The groups are arranged as sets per altfunction column, so we can
- * mux in one group at a time by selecting the same altfunction for them
- * all. When functions require pins on different altfunctions, you need
- * to combine several groups.
- */
-
-/* Altfunction A column */
-static const unsigned u0_a_1_pins[] = { DB8540_PIN_AH6, DB8540_PIN_AG7,
-                                       DB8540_PIN_AF2, DB8540_PIN_AD3 };
-static const unsigned u1rxtx_a_1_pins[] = { DB8540_PIN_AF6, DB8540_PIN_AG6 };
-static const unsigned u1ctsrts_a_1_pins[] = { DB8540_PIN_AD5, DB8540_PIN_AF7 };
-/* Image processor I2C line, this is driven by image processor firmware */
-static const unsigned ipi2c_a_1_pins[] = { DB8540_PIN_AG5, DB8540_PIN_AH5 };
-static const unsigned ipi2c_a_2_pins[] = { DB8540_PIN_AE4, DB8540_PIN_AD1 };
-/* MSP0 can only be on these pins, but TXD and RXD can be flipped */
-static const unsigned msp0txrx_a_1_pins[] = { DB8540_PIN_AD2, DB8540_PIN_AC3 };
-static const unsigned msp0tfstck_a_1_pins[] = { DB8540_PIN_AC2,
-       DB8540_PIN_AC4 };
-static const unsigned msp0rfsrck_a_1_pins[] = { DB8540_PIN_AH7,
-       DB8540_PIN_AE7 };
-/* Basic pins of the MMC/SD card 0 interface */
-static const unsigned mc0_a_1_pins[] = { DB8540_PIN_AH11, DB8540_PIN_AG11,
-       DB8540_PIN_AF11, DB8540_PIN_AH10, DB8540_PIN_AG10, DB8540_PIN_AF10};
-/* MSP1 can only be on these pins, but TXD and RXD can be flipped */
-static const unsigned msp1txrx_a_1_pins[] = { DB8540_PIN_AD4, DB8540_PIN_AG4 };
-static const unsigned msp1_a_1_pins[] = { DB8540_PIN_AF3, DB8540_PIN_AF5 };
-
-static const unsigned modobsclk_a_1_pins[] = { DB8540_PIN_AF9 };
-static const unsigned clkoutreq_a_1_pins[] = { DB8540_PIN_AE8 };
-/* LCD interface */
-static const unsigned lcdb_a_1_pins[] = { DB8540_PIN_M26, DB8540_PIN_M25,
-       DB8540_PIN_M27, DB8540_PIN_N25 };
-static const unsigned lcdvsi0_a_1_pins[] = { DB8540_PIN_AJ24 };
-static const unsigned lcdvsi1_a_1_pins[] = { DB8540_PIN_AE21 };
-static const unsigned lcd_d0_d7_a_1_pins[] = { DB8540_PIN_M28, DB8540_PIN_N26,
-       DB8540_PIN_M22, DB8540_PIN_N22, DB8540_PIN_N27, DB8540_PIN_N28,
-       DB8540_PIN_P22, DB8540_PIN_P28 };
-/* D8 thru D11 often used as TVOUT lines */
-static const unsigned lcd_d8_d11_a_1_pins[] = { DB8540_PIN_P26, DB8540_PIN_T22,
-       DB8540_PIN_R27, DB8540_PIN_P27 };
-static const unsigned lcd_d12_d23_a_1_pins[] = { DB8540_PIN_R26, DB8540_PIN_R25,
-       DB8540_PIN_U22, DB8540_PIN_T27, DB8540_PIN_AG22, DB8540_PIN_AF21,
-       DB8540_PIN_AF24, DB8540_PIN_AH22, DB8540_PIN_AJ23, DB8540_PIN_AH21,
-       DB8540_PIN_AG20, DB8540_PIN_AE23 };
-static const unsigned kp_a_1_pins[] = { DB8540_PIN_AH20, DB8540_PIN_AG19,
-       DB8540_PIN_AF22, DB8540_PIN_AJ21, DB8540_PIN_T25, DB8540_PIN_T26 };
-/* MC2 has 8 data lines and no direction control, so only for (e)MMC */
-static const unsigned mc2_a_1_pins[] = { DB8540_PIN_AC27, DB8540_PIN_AD27,
-       DB8540_PIN_AE28, DB8540_PIN_AG26, DB8540_PIN_AF25, DB8540_PIN_AE27,
-       DB8540_PIN_AF27, DB8540_PIN_AG28, DB8540_PIN_AF28, DB8540_PIN_AG25,
-       DB8540_PIN_AG24 };
-static const unsigned ssp1_a_1_pins[] = {  DB8540_PIN_AD25, DB8540_PIN_AH25,
-       DB8540_PIN_AF26, DB8540_PIN_AF23 };
-static const unsigned ssp0_a_1_pins[] = { DB8540_PIN_AG23, DB8540_PIN_AE25,
-       DB8540_PIN_AH24, DB8540_PIN_AJ25 };
-static const unsigned i2c0_a_1_pins[] = { DB8540_PIN_AG27, DB8540_PIN_AH23 };
-/*
- * Image processor GPIO pins are named "ipgpio" and have their own
- * numberspace
- */
-static const unsigned ipgpio0_a_1_pins[] = { DB8540_PIN_AE26 };
-static const unsigned ipgpio1_a_1_pins[] = { DB8540_PIN_AE24 };
-/* modem i2s interface */
-static const unsigned modi2s_a_1_pins[] = { DB8540_PIN_AD26, DB8540_PIN_AD28,
-       DB8540_PIN_AC28, DB8540_PIN_AC26 };
-static const unsigned spi2_a_1_pins[] = { DB8540_PIN_AF20, DB8540_PIN_AG21,
-       DB8540_PIN_AH19, DB8540_PIN_AE19 };
-static const unsigned u2txrx_a_1_pins[] = { DB8540_PIN_AG18, DB8540_PIN_AH17 };
-static const unsigned u2ctsrts_a_1_pins[] = { DB8540_PIN_AF19,
-       DB8540_PIN_AF18 };
-static const unsigned modsmb_a_1_pins[] = { DB8540_PIN_AF17, DB8540_PIN_AE17 };
-static const unsigned msp2sck_a_1_pins[] = { DB8540_PIN_J3 };
-static const unsigned msp2txdtcktfs_a_1_pins[] = { DB8540_PIN_H1, DB8540_PIN_J2,
-       DB8540_PIN_H2 };
-static const unsigned msp2rxd_a_1_pins[] = { DB8540_PIN_H3 };
-static const unsigned mc4_a_1_pins[] = { DB8540_PIN_H4, DB8540_PIN_G2,
-       DB8540_PIN_G3, DB8540_PIN_G4, DB8540_PIN_F2, DB8540_PIN_C6,
-       DB8540_PIN_B6, DB8540_PIN_B7, DB8540_PIN_A7, DB8540_PIN_D7,
-       DB8540_PIN_D8 };
-static const unsigned mc1_a_1_pins[] = { DB8540_PIN_F3, DB8540_PIN_E2,
-       DB8540_PIN_C7, DB8540_PIN_B8, DB8540_PIN_C10, DB8540_PIN_C8,
-       DB8540_PIN_C9 };
-/* mc1_a_2_pins exclude MC1_FBCLK */
-static const unsigned mc1_a_2_pins[] = { DB8540_PIN_F3,        DB8540_PIN_C7,
-       DB8540_PIN_B8, DB8540_PIN_C10, DB8540_PIN_C8,
-       DB8540_PIN_C9 };
-static const unsigned hsir_a_1_pins[] = { DB8540_PIN_B9, DB8540_PIN_A10,
-       DB8540_PIN_D9 };
-static const unsigned hsit_a_1_pins[] = { DB8540_PIN_B11, DB8540_PIN_B10,
-       DB8540_PIN_E10, DB8540_PIN_B12, DB8540_PIN_D10 };
-static const unsigned hsit_a_2_pins[] = { DB8540_PIN_B11, DB8540_PIN_B10,
-       DB8540_PIN_E10, DB8540_PIN_B12 };
-static const unsigned clkout1_a_1_pins[] = { DB8540_PIN_D11 };
-static const unsigned clkout1_a_2_pins[] = { DB8540_PIN_B13 };
-static const unsigned clkout2_a_1_pins[] = { DB8540_PIN_AJ6 };
-static const unsigned clkout2_a_2_pins[] = { DB8540_PIN_C12 };
-static const unsigned msp4_a_1_pins[] = { DB8540_PIN_B14, DB8540_PIN_E11 };
-static const unsigned usb_a_1_pins[] = { DB8540_PIN_D12, DB8540_PIN_D15,
-       DB8540_PIN_C13, DB8540_PIN_C14, DB8540_PIN_C18, DB8540_PIN_C16,
-       DB8540_PIN_B16, DB8540_PIN_D18, DB8540_PIN_C15, DB8540_PIN_C17,
-       DB8540_PIN_B17, DB8540_PIN_D17 };
-/* Altfunction B colum */
-static const unsigned apetrig_b_1_pins[] = { DB8540_PIN_AH6, DB8540_PIN_AG7 };
-static const unsigned modtrig_b_1_pins[] = { DB8540_PIN_AF2, DB8540_PIN_AD3 };
-static const unsigned i2c4_b_1_pins[] = { DB8540_PIN_AF6, DB8540_PIN_AG6 };
-static const unsigned i2c1_b_1_pins[] = { DB8540_PIN_AD5, DB8540_PIN_AF7 };
-static const unsigned i2c2_b_1_pins[] = { DB8540_PIN_AG5, DB8540_PIN_AH5 };
-static const unsigned i2c2_b_2_pins[] = { DB8540_PIN_AE4, DB8540_PIN_AD1 };
-static const unsigned msp0txrx_b_1_pins[] = { DB8540_PIN_AD2, DB8540_PIN_AC3 };
-static const unsigned i2c1_b_2_pins[] = { DB8540_PIN_AH7, DB8540_PIN_AE7 };
-static const unsigned stmmod_b_1_pins[] = { DB8540_PIN_AH11, DB8540_PIN_AF11,
-       DB8540_PIN_AH10, DB8540_PIN_AG10, DB8540_PIN_AF10 };
-static const unsigned moduartstmmux_b_1_pins[] = { DB8540_PIN_AG11 };
-static const unsigned msp1txrx_b_1_pins[] = { DB8540_PIN_AD4, DB8540_PIN_AG4 };
-static const unsigned kp_b_1_pins[] = { DB8540_PIN_AJ24, DB8540_PIN_AE21,
-       DB8540_PIN_M26, DB8540_PIN_M25, DB8540_PIN_M27, DB8540_PIN_N25,
-       DB8540_PIN_M28, DB8540_PIN_N26, DB8540_PIN_M22, DB8540_PIN_N22,
-       DB8540_PIN_N27, DB8540_PIN_N28, DB8540_PIN_P22, DB8540_PIN_P28,
-       DB8540_PIN_P26, DB8540_PIN_T22, DB8540_PIN_R27, DB8540_PIN_P27,
-       DB8540_PIN_R26, DB8540_PIN_R25 };
-static const unsigned u2txrx_b_1_pins[] = { DB8540_PIN_U22, DB8540_PIN_T27 };
-static const unsigned sm_b_1_pins[] = { DB8540_PIN_AG22, DB8540_PIN_AF21,
-       DB8540_PIN_AF24, DB8540_PIN_AH22, DB8540_PIN_AJ23, DB8540_PIN_AH21,
-       DB8540_PIN_AG20, DB8540_PIN_AE23, DB8540_PIN_AH20, DB8540_PIN_AF22,
-       DB8540_PIN_AJ21, DB8540_PIN_AC27, DB8540_PIN_AD27, DB8540_PIN_AE28,
-       DB8540_PIN_AG26, DB8540_PIN_AF25, DB8540_PIN_AE27, DB8540_PIN_AF27,
-       DB8540_PIN_AG28, DB8540_PIN_AF28, DB8540_PIN_AG25, DB8540_PIN_AG24,
-       DB8540_PIN_AD25 };
-static const unsigned smcs0_b_1_pins[] = { DB8540_PIN_AG19 };
-static const unsigned smcs1_b_1_pins[] = { DB8540_PIN_AE26 };
-static const unsigned ipgpio7_b_1_pins[] = { DB8540_PIN_AH25 };
-static const unsigned ipgpio2_b_1_pins[] = { DB8540_PIN_AF26 };
-static const unsigned ipgpio3_b_1_pins[] = { DB8540_PIN_AF23 };
-static const unsigned i2c6_b_1_pins[] = { DB8540_PIN_AG23, DB8540_PIN_AE25 };
-static const unsigned i2c5_b_1_pins[] = { DB8540_PIN_AH24, DB8540_PIN_AJ25 };
-static const unsigned u3txrx_b_1_pins[] = { DB8540_PIN_AF20, DB8540_PIN_AG21 };
-static const unsigned u3ctsrts_b_1_pins[] = { DB8540_PIN_AH19,
-       DB8540_PIN_AE19 };
-static const unsigned i2c5_b_2_pins[] = { DB8540_PIN_AG18, DB8540_PIN_AH17 };
-static const unsigned i2c4_b_2_pins[] = { DB8540_PIN_AF19, DB8540_PIN_AF18 };
-static const unsigned u4txrx_b_1_pins[] = { DB8540_PIN_AE18, DB8540_PIN_AG17 };
-static const unsigned u4ctsrts_b_1_pins[] = { DB8540_PIN_AF17,
-       DB8540_PIN_AE17 };
-static const unsigned ddrtrig_b_1_pins[] = { DB8540_PIN_J3 };
-static const unsigned msp4_b_1_pins[] = { DB8540_PIN_H3 };
-static const unsigned pwl_b_1_pins[] = { DB8540_PIN_C6 };
-static const unsigned spi1_b_1_pins[] = { DB8540_PIN_E2, DB8540_PIN_C10,
-       DB8540_PIN_C8, DB8540_PIN_C9 };
-static const unsigned mc3_b_1_pins[] = { DB8540_PIN_B9, DB8540_PIN_A10,
-       DB8540_PIN_D9, DB8540_PIN_B11, DB8540_PIN_B10, DB8540_PIN_E10,
-       DB8540_PIN_B12 };
-static const unsigned pwl_b_2_pins[] = { DB8540_PIN_D10 };
-static const unsigned pwl_b_3_pins[] = { DB8540_PIN_B13 };
-static const unsigned pwl_b_4_pins[] = { DB8540_PIN_C12 };
-static const unsigned u2txrx_b_2_pins[] = { DB8540_PIN_B17, DB8540_PIN_D17 };
-
-/* Altfunction C column */
-static const unsigned ipgpio6_c_1_pins[] = { DB8540_PIN_AG6 };
-static const unsigned ipgpio0_c_1_pins[] = { DB8540_PIN_AD5 };
-static const unsigned ipgpio1_c_1_pins[] = { DB8540_PIN_AF7 };
-static const unsigned ipgpio3_c_1_pins[] = { DB8540_PIN_AE4 };
-static const unsigned ipgpio2_c_1_pins[] = { DB8540_PIN_AD1 };
-static const unsigned u0_c_1_pins[] = { DB8540_PIN_AD4, DB8540_PIN_AF3,
-       DB8540_PIN_AF5, DB8540_PIN_AG4 };
-static const unsigned smcleale_c_1_pins[] = { DB8540_PIN_AJ24,
-       DB8540_PIN_AE21 };
-static const unsigned ipgpio4_c_1_pins[] = { DB8540_PIN_M26 };
-static const unsigned ipgpio5_c_1_pins[] = { DB8540_PIN_M25 };
-static const unsigned ipgpio6_c_2_pins[] = { DB8540_PIN_M27 };
-static const unsigned ipgpio7_c_1_pins[] = { DB8540_PIN_N25 };
-static const unsigned stmape_c_1_pins[] = { DB8540_PIN_M28, DB8540_PIN_N26,
-       DB8540_PIN_M22, DB8540_PIN_N22, DB8540_PIN_N27 };
-static const unsigned u2rxtx_c_1_pins[] = { DB8540_PIN_N28, DB8540_PIN_P22 };
-static const unsigned modobsresout_c_1_pins[] = { DB8540_PIN_P28 };
-static const unsigned ipgpio2_c_2_pins[] = { DB8540_PIN_P26 };
-static const unsigned ipgpio3_c_2_pins[] = { DB8540_PIN_T22 };
-static const unsigned ipgpio4_c_2_pins[] = { DB8540_PIN_R27 };
-static const unsigned ipgpio5_c_2_pins[] = { DB8540_PIN_P27 };
-static const unsigned modaccgpo_c_1_pins[] = { DB8540_PIN_R26, DB8540_PIN_R25,
-       DB8540_PIN_U22 };
-static const unsigned modobspwrrst_c_1_pins[] = { DB8540_PIN_T27 };
-static const unsigned mc5_c_1_pins[] = { DB8540_PIN_AG22, DB8540_PIN_AF21,
-       DB8540_PIN_AF24, DB8540_PIN_AH22, DB8540_PIN_AJ23, DB8540_PIN_AH21,
-       DB8540_PIN_AG20, DB8540_PIN_AE23, DB8540_PIN_AH20, DB8540_PIN_AF22,
-       DB8540_PIN_AJ21};
-static const unsigned smps0_c_1_pins[] = { DB8540_PIN_AG19 };
-static const unsigned moduart1_c_1_pins[] = { DB8540_PIN_T25, DB8540_PIN_T26 };
-static const unsigned mc2rstn_c_1_pins[] = { DB8540_PIN_AE28 };
-static const unsigned i2c5_c_1_pins[] = { DB8540_PIN_AG28, DB8540_PIN_AF28 };
-static const unsigned ipgpio0_c_2_pins[] = { DB8540_PIN_AG25 };
-static const unsigned ipgpio1_c_2_pins[] = { DB8540_PIN_AG24 };
-static const unsigned kp_c_1_pins[] = { DB8540_PIN_AD25, DB8540_PIN_AH25,
-       DB8540_PIN_AF26, DB8540_PIN_AF23 };
-static const unsigned modrf_c_1_pins[] = { DB8540_PIN_AG23, DB8540_PIN_AE25,
-       DB8540_PIN_AH24 };
-static const unsigned smps1_c_1_pins[] = { DB8540_PIN_AE26 };
-static const unsigned i2c5_c_2_pins[] = { DB8540_PIN_AH19, DB8540_PIN_AE19 };
-static const unsigned u4ctsrts_c_1_pins[] = { DB8540_PIN_AG18,
-       DB8540_PIN_AH17 };
-static const unsigned u3rxtx_c_1_pins[] = { DB8540_PIN_AF19, DB8540_PIN_AF18 };
-static const unsigned msp4_c_1_pins[] = { DB8540_PIN_J3 };
-static const unsigned mc4rstn_c_1_pins[] = { DB8540_PIN_C6 };
-static const unsigned spi0_c_1_pins[] = { DB8540_PIN_A10, DB8540_PIN_B10,
-       DB8540_PIN_E10, DB8540_PIN_B12 };
-static const unsigned i2c3_c_1_pins[] = { DB8540_PIN_B13, DB8540_PIN_C12 };
-
-/* Other alt C1 column */
-static const unsigned spi3_oc1_1_pins[] = { DB8540_PIN_AG5, DB8540_PIN_AH5,
-       DB8540_PIN_AE4, DB8540_PIN_AD1 };
-static const unsigned stmape_oc1_1_pins[] = { DB8540_PIN_AH11, DB8540_PIN_AF11,
-       DB8540_PIN_AH10, DB8540_PIN_AG10, DB8540_PIN_AF10 };
-static const unsigned u2_oc1_1_pins[] = { DB8540_PIN_AG11 };
-static const unsigned remap0_oc1_1_pins[] = { DB8540_PIN_AJ24 };
-static const unsigned remap1_oc1_1_pins[] = { DB8540_PIN_AE21 };
-static const unsigned modobsrefclk_oc1_1_pins[] = { DB8540_PIN_M26 };
-static const unsigned modobspwrctrl_oc1_1_pins[] = { DB8540_PIN_M25 };
-static const unsigned modobsclkout_oc1_1_pins[] = { DB8540_PIN_M27 };
-static const unsigned moduart1_oc1_1_pins[] = { DB8540_PIN_N25 };
-static const unsigned modprcmudbg_oc1_1_pins[] = { DB8540_PIN_M28,
-       DB8540_PIN_N26, DB8540_PIN_M22, DB8540_PIN_N22, DB8540_PIN_N27,
-       DB8540_PIN_P22, DB8540_PIN_P28, DB8540_PIN_P26, DB8540_PIN_T22,
-       DB8540_PIN_R26, DB8540_PIN_R25, DB8540_PIN_U22, DB8540_PIN_T27,
-       DB8540_PIN_AH20, DB8540_PIN_AG19, DB8540_PIN_AF22, DB8540_PIN_AJ21,
-       DB8540_PIN_T25};
-static const unsigned modobsresout_oc1_1_pins[] = { DB8540_PIN_N28 };
-static const unsigned modaccgpo_oc1_1_pins[] = { DB8540_PIN_R27, DB8540_PIN_P27,
-       DB8540_PIN_T26 };
-static const unsigned kp_oc1_1_pins[] = { DB8540_PIN_AG22, DB8540_PIN_AF21,
-       DB8540_PIN_AF24, DB8540_PIN_AH22, DB8540_PIN_AJ23, DB8540_PIN_AH21,
-       DB8540_PIN_AG20, DB8540_PIN_AE23 };
-static const unsigned modxmip_oc1_1_pins[] = { DB8540_PIN_AD25, DB8540_PIN_AH25,
-       DB8540_PIN_AG23, DB8540_PIN_AE25 };
-static const unsigned i2c6_oc1_1_pins[] = { DB8540_PIN_AE26, DB8540_PIN_AE24 };
-static const unsigned u2txrx_oc1_1_pins[] = { DB8540_PIN_B7, DB8540_PIN_A7 };
-static const unsigned u2ctsrts_oc1_1_pins[] = { DB8540_PIN_D7, DB8540_PIN_D8 };
-
-/* Other alt C2 column */
-static const unsigned sbag_oc2_1_pins[] = { DB8540_PIN_AH11, DB8540_PIN_AG11,
-       DB8540_PIN_AF11, DB8540_PIN_AH10, DB8540_PIN_AG10, DB8540_PIN_AF10 };
-static const unsigned hxclk_oc2_1_pins[] = { DB8540_PIN_M25 };
-static const unsigned modaccuart_oc2_1_pins[] = { DB8540_PIN_N25 };
-static const unsigned stmmod_oc2_1_pins[] = { DB8540_PIN_M28, DB8540_PIN_N26,
-       DB8540_PIN_M22, DB8540_PIN_N22, DB8540_PIN_N27 };
-static const unsigned moduartstmmux_oc2_1_pins[] = { DB8540_PIN_N28 };
-static const unsigned hxgpio_oc2_1_pins[] = { DB8540_PIN_P22, DB8540_PIN_P28,
-       DB8540_PIN_P26, DB8540_PIN_T22, DB8540_PIN_R27, DB8540_PIN_P27,
-       DB8540_PIN_R26, DB8540_PIN_R25 };
-static const unsigned sbag_oc2_2_pins[] = { DB8540_PIN_U22, DB8540_PIN_T27,
-       DB8540_PIN_AG22, DB8540_PIN_AF21, DB8540_PIN_AF24, DB8540_PIN_AH22 };
-static const unsigned modobsservice_oc2_1_pins[] = { DB8540_PIN_AJ23 };
-static const unsigned moduart0_oc2_1_pins[] = { DB8540_PIN_AG20,
-       DB8540_PIN_AE23 };
-static const unsigned stmape_oc2_1_pins[] = { DB8540_PIN_AH20, DB8540_PIN_AG19,
-       DB8540_PIN_AF22, DB8540_PIN_AJ21, DB8540_PIN_T25 };
-static const unsigned u2_oc2_1_pins[] = { DB8540_PIN_T26, DB8540_PIN_AH21 };
-static const unsigned modxmip_oc2_1_pins[] = { DB8540_PIN_AE26,
-       DB8540_PIN_AE24 };
-
-/* Other alt C3 column */
-static const unsigned modaccgpo_oc3_1_pins[] = { DB8540_PIN_AG11 };
-static const unsigned tpui_oc3_1_pins[] = { DB8540_PIN_M26, DB8540_PIN_M25,
-       DB8540_PIN_M27, DB8540_PIN_N25, DB8540_PIN_M28, DB8540_PIN_N26,
-       DB8540_PIN_M22, DB8540_PIN_N22, DB8540_PIN_N27, DB8540_PIN_N28,
-       DB8540_PIN_P22, DB8540_PIN_P28, DB8540_PIN_P26, DB8540_PIN_T22,
-       DB8540_PIN_R27, DB8540_PIN_P27, DB8540_PIN_R26, DB8540_PIN_R25,
-       DB8540_PIN_U22, DB8540_PIN_T27, DB8540_PIN_AG22, DB8540_PIN_AF21,
-       DB8540_PIN_AF24, DB8540_PIN_AH22, DB8540_PIN_AJ23, DB8540_PIN_AH21,
-       DB8540_PIN_AG20, DB8540_PIN_AE23, DB8540_PIN_AH20, DB8540_PIN_AG19,
-       DB8540_PIN_AF22, DB8540_PIN_AJ21, DB8540_PIN_T25, DB8540_PIN_T26 };
-
-/* Other alt C4 column */
-static const unsigned hwobs_oc4_1_pins[] = { DB8540_PIN_M26, DB8540_PIN_M25,
-       DB8540_PIN_M27, DB8540_PIN_N25, DB8540_PIN_M28, DB8540_PIN_N26,
-       DB8540_PIN_M22, DB8540_PIN_N22, DB8540_PIN_N27, DB8540_PIN_N28,
-       DB8540_PIN_P22, DB8540_PIN_P28, DB8540_PIN_P26, DB8540_PIN_T22,
-       DB8540_PIN_R27, DB8540_PIN_P27, DB8540_PIN_R26, DB8540_PIN_R25 };
-static const unsigned moduart1txrx_oc4_1_pins[] = { DB8540_PIN_U22,
-       DB8540_PIN_T27 };
-static const unsigned moduart1rtscts_oc4_1_pins[] = { DB8540_PIN_AG22,
-       DB8540_PIN_AF21 };
-static const unsigned modaccuarttxrx_oc4_1_pins[] = { DB8540_PIN_AF24,
-       DB8540_PIN_AH22 };
-static const unsigned modaccuartrtscts_oc4_1_pins[] = { DB8540_PIN_AJ23,
-       DB8540_PIN_AH21 };
-static const unsigned stmmod_oc4_1_pins[] = { DB8540_PIN_AH20, DB8540_PIN_AG19,
-       DB8540_PIN_AF22, DB8540_PIN_AJ21, DB8540_PIN_T25 };
-static const unsigned moduartstmmux_oc4_1_pins[] = { DB8540_PIN_T26 };
-
-#define DB8540_PIN_GROUP(a, b) { .name = #a, .pins = a##_pins,         \
-                       .npins = ARRAY_SIZE(a##_pins), .altsetting = b }
-
-static const struct nmk_pingroup nmk_db8540_groups[] = {
-       /* Altfunction A column */
-       DB8540_PIN_GROUP(u0_a_1, NMK_GPIO_ALT_A),
-       DB8540_PIN_GROUP(u1rxtx_a_1, NMK_GPIO_ALT_A),
-       DB8540_PIN_GROUP(u1ctsrts_a_1, NMK_GPIO_ALT_A),
-       DB8540_PIN_GROUP(ipi2c_a_1, NMK_GPIO_ALT_A),
-       DB8540_PIN_GROUP(ipi2c_a_2, NMK_GPIO_ALT_A),
-       DB8540_PIN_GROUP(msp0txrx_a_1, NMK_GPIO_ALT_A),
-       DB8540_PIN_GROUP(msp0tfstck_a_1, NMK_GPIO_ALT_A),
-       DB8540_PIN_GROUP(msp0rfsrck_a_1, NMK_GPIO_ALT_A),
-       DB8540_PIN_GROUP(mc0_a_1, NMK_GPIO_ALT_A),
-       DB8540_PIN_GROUP(msp1txrx_a_1, NMK_GPIO_ALT_A),
-       DB8540_PIN_GROUP(msp1_a_1, NMK_GPIO_ALT_A),
-       DB8540_PIN_GROUP(modobsclk_a_1, NMK_GPIO_ALT_A),
-       DB8540_PIN_GROUP(clkoutreq_a_1, NMK_GPIO_ALT_A),
-       DB8540_PIN_GROUP(lcdb_a_1, NMK_GPIO_ALT_A),
-       DB8540_PIN_GROUP(lcdvsi0_a_1, NMK_GPIO_ALT_A),
-       DB8540_PIN_GROUP(lcdvsi1_a_1, NMK_GPIO_ALT_A),
-       DB8540_PIN_GROUP(lcd_d0_d7_a_1, NMK_GPIO_ALT_A),
-       DB8540_PIN_GROUP(lcd_d8_d11_a_1, NMK_GPIO_ALT_A),
-       DB8540_PIN_GROUP(lcd_d12_d23_a_1, NMK_GPIO_ALT_A),
-       DB8540_PIN_GROUP(kp_a_1, NMK_GPIO_ALT_A),
-       DB8540_PIN_GROUP(mc2_a_1, NMK_GPIO_ALT_A),
-       DB8540_PIN_GROUP(ssp1_a_1, NMK_GPIO_ALT_A),
-       DB8540_PIN_GROUP(ssp0_a_1, NMK_GPIO_ALT_A),
-       DB8540_PIN_GROUP(i2c0_a_1, NMK_GPIO_ALT_A),
-       DB8540_PIN_GROUP(ipgpio0_a_1, NMK_GPIO_ALT_A),
-       DB8540_PIN_GROUP(ipgpio1_a_1, NMK_GPIO_ALT_A),
-       DB8540_PIN_GROUP(modi2s_a_1, NMK_GPIO_ALT_A),
-       DB8540_PIN_GROUP(spi2_a_1, NMK_GPIO_ALT_A),
-       DB8540_PIN_GROUP(u2txrx_a_1, NMK_GPIO_ALT_A),
-       DB8540_PIN_GROUP(u2ctsrts_a_1, NMK_GPIO_ALT_A),
-       DB8540_PIN_GROUP(modsmb_a_1, NMK_GPIO_ALT_A),
-       DB8540_PIN_GROUP(msp2sck_a_1, NMK_GPIO_ALT_A),
-       DB8540_PIN_GROUP(msp2txdtcktfs_a_1, NMK_GPIO_ALT_A),
-       DB8540_PIN_GROUP(msp2rxd_a_1, NMK_GPIO_ALT_A),
-       DB8540_PIN_GROUP(mc4_a_1, NMK_GPIO_ALT_A),
-       DB8540_PIN_GROUP(mc1_a_1, NMK_GPIO_ALT_A),
-       DB8540_PIN_GROUP(hsir_a_1, NMK_GPIO_ALT_A),
-       DB8540_PIN_GROUP(hsit_a_1, NMK_GPIO_ALT_A),
-       DB8540_PIN_GROUP(hsit_a_2, NMK_GPIO_ALT_A),
-       DB8540_PIN_GROUP(clkout1_a_1, NMK_GPIO_ALT_A),
-       DB8540_PIN_GROUP(clkout1_a_2, NMK_GPIO_ALT_A),
-       DB8540_PIN_GROUP(clkout2_a_1, NMK_GPIO_ALT_A),
-       DB8540_PIN_GROUP(clkout2_a_2, NMK_GPIO_ALT_A),
-       DB8540_PIN_GROUP(msp4_a_1, NMK_GPIO_ALT_A),
-       DB8540_PIN_GROUP(usb_a_1, NMK_GPIO_ALT_A),
-       /* Altfunction B column */
-       DB8540_PIN_GROUP(apetrig_b_1, NMK_GPIO_ALT_B),
-       DB8540_PIN_GROUP(modtrig_b_1, NMK_GPIO_ALT_B),
-       DB8540_PIN_GROUP(i2c4_b_1, NMK_GPIO_ALT_B),
-       DB8540_PIN_GROUP(i2c1_b_1, NMK_GPIO_ALT_B),
-       DB8540_PIN_GROUP(i2c2_b_1, NMK_GPIO_ALT_B),
-       DB8540_PIN_GROUP(i2c2_b_2, NMK_GPIO_ALT_B),
-       DB8540_PIN_GROUP(msp0txrx_b_1, NMK_GPIO_ALT_B),
-       DB8540_PIN_GROUP(i2c1_b_2, NMK_GPIO_ALT_B),
-       DB8540_PIN_GROUP(stmmod_b_1, NMK_GPIO_ALT_B),
-       DB8540_PIN_GROUP(moduartstmmux_b_1, NMK_GPIO_ALT_B),
-       DB8540_PIN_GROUP(msp1txrx_b_1, NMK_GPIO_ALT_B),
-       DB8540_PIN_GROUP(kp_b_1, NMK_GPIO_ALT_B),
-       DB8540_PIN_GROUP(u2txrx_b_1, NMK_GPIO_ALT_B),
-       DB8540_PIN_GROUP(sm_b_1, NMK_GPIO_ALT_B),
-       DB8540_PIN_GROUP(smcs0_b_1, NMK_GPIO_ALT_B),
-       DB8540_PIN_GROUP(smcs1_b_1, NMK_GPIO_ALT_B),
-       DB8540_PIN_GROUP(ipgpio7_b_1, NMK_GPIO_ALT_B),
-       DB8540_PIN_GROUP(ipgpio2_b_1, NMK_GPIO_ALT_B),
-       DB8540_PIN_GROUP(ipgpio3_b_1, NMK_GPIO_ALT_B),
-       DB8540_PIN_GROUP(i2c6_b_1, NMK_GPIO_ALT_B),
-       DB8540_PIN_GROUP(i2c5_b_1, NMK_GPIO_ALT_B),
-       DB8540_PIN_GROUP(u3txrx_b_1, NMK_GPIO_ALT_B),
-       DB8540_PIN_GROUP(u3ctsrts_b_1, NMK_GPIO_ALT_B),
-       DB8540_PIN_GROUP(i2c5_b_2, NMK_GPIO_ALT_B),
-       DB8540_PIN_GROUP(i2c4_b_2, NMK_GPIO_ALT_B),
-       DB8540_PIN_GROUP(u4txrx_b_1, NMK_GPIO_ALT_B),
-       DB8540_PIN_GROUP(u4ctsrts_b_1, NMK_GPIO_ALT_B),
-       DB8540_PIN_GROUP(ddrtrig_b_1, NMK_GPIO_ALT_B),
-       DB8540_PIN_GROUP(msp4_b_1, NMK_GPIO_ALT_B),
-       DB8540_PIN_GROUP(pwl_b_1, NMK_GPIO_ALT_B),
-       DB8540_PIN_GROUP(spi1_b_1, NMK_GPIO_ALT_B),
-       DB8540_PIN_GROUP(mc3_b_1, NMK_GPIO_ALT_B),
-       DB8540_PIN_GROUP(pwl_b_2, NMK_GPIO_ALT_B),
-       DB8540_PIN_GROUP(pwl_b_3, NMK_GPIO_ALT_B),
-       DB8540_PIN_GROUP(pwl_b_4, NMK_GPIO_ALT_B),
-       DB8540_PIN_GROUP(u2txrx_b_2, NMK_GPIO_ALT_B),
-       /* Altfunction C column */
-       DB8540_PIN_GROUP(ipgpio6_c_1, NMK_GPIO_ALT_C),
-       DB8540_PIN_GROUP(ipgpio0_c_1, NMK_GPIO_ALT_C),
-       DB8540_PIN_GROUP(ipgpio1_c_1, NMK_GPIO_ALT_C),
-       DB8540_PIN_GROUP(ipgpio3_c_1, NMK_GPIO_ALT_C),
-       DB8540_PIN_GROUP(ipgpio2_c_1, NMK_GPIO_ALT_C),
-       DB8540_PIN_GROUP(u0_c_1, NMK_GPIO_ALT_C),
-       DB8540_PIN_GROUP(smcleale_c_1, NMK_GPIO_ALT_C),
-       DB8540_PIN_GROUP(ipgpio4_c_1, NMK_GPIO_ALT_C),
-       DB8540_PIN_GROUP(ipgpio5_c_1, NMK_GPIO_ALT_C),
-       DB8540_PIN_GROUP(ipgpio6_c_2, NMK_GPIO_ALT_C),
-       DB8540_PIN_GROUP(ipgpio7_c_1, NMK_GPIO_ALT_C),
-       DB8540_PIN_GROUP(stmape_c_1, NMK_GPIO_ALT_C),
-       DB8540_PIN_GROUP(u2rxtx_c_1, NMK_GPIO_ALT_C),
-       DB8540_PIN_GROUP(modobsresout_c_1, NMK_GPIO_ALT_C),
-       DB8540_PIN_GROUP(ipgpio2_c_2, NMK_GPIO_ALT_C),
-       DB8540_PIN_GROUP(ipgpio3_c_2, NMK_GPIO_ALT_C),
-       DB8540_PIN_GROUP(ipgpio4_c_2, NMK_GPIO_ALT_C),
-       DB8540_PIN_GROUP(ipgpio5_c_2, NMK_GPIO_ALT_C),
-       DB8540_PIN_GROUP(modaccgpo_c_1, NMK_GPIO_ALT_C),
-       DB8540_PIN_GROUP(modobspwrrst_c_1, NMK_GPIO_ALT_C),
-       DB8540_PIN_GROUP(mc5_c_1, NMK_GPIO_ALT_C),
-       DB8540_PIN_GROUP(smps0_c_1, NMK_GPIO_ALT_C),
-       DB8540_PIN_GROUP(moduart1_c_1, NMK_GPIO_ALT_C),
-       DB8540_PIN_GROUP(mc2rstn_c_1, NMK_GPIO_ALT_C),
-       DB8540_PIN_GROUP(i2c5_c_1, NMK_GPIO_ALT_C),
-       DB8540_PIN_GROUP(ipgpio0_c_2, NMK_GPIO_ALT_C),
-       DB8540_PIN_GROUP(ipgpio1_c_2, NMK_GPIO_ALT_C),
-       DB8540_PIN_GROUP(kp_c_1, NMK_GPIO_ALT_C),
-       DB8540_PIN_GROUP(modrf_c_1, NMK_GPIO_ALT_C),
-       DB8540_PIN_GROUP(smps1_c_1, NMK_GPIO_ALT_C),
-       DB8540_PIN_GROUP(i2c5_c_2, NMK_GPIO_ALT_C),
-       DB8540_PIN_GROUP(u4ctsrts_c_1, NMK_GPIO_ALT_C),
-       DB8540_PIN_GROUP(u3rxtx_c_1, NMK_GPIO_ALT_C),
-       DB8540_PIN_GROUP(msp4_c_1, NMK_GPIO_ALT_C),
-       DB8540_PIN_GROUP(mc4rstn_c_1, NMK_GPIO_ALT_C),
-       DB8540_PIN_GROUP(spi0_c_1, NMK_GPIO_ALT_C),
-       DB8540_PIN_GROUP(i2c3_c_1, NMK_GPIO_ALT_C),
-
-       /* Other alt C1 column */
-       DB8540_PIN_GROUP(spi3_oc1_1, NMK_GPIO_ALT_C1),
-       DB8540_PIN_GROUP(stmape_oc1_1, NMK_GPIO_ALT_C1),
-       DB8540_PIN_GROUP(u2_oc1_1, NMK_GPIO_ALT_C1),
-       DB8540_PIN_GROUP(remap0_oc1_1, NMK_GPIO_ALT_C1),
-       DB8540_PIN_GROUP(remap1_oc1_1, NMK_GPIO_ALT_C1),
-       DB8540_PIN_GROUP(modobsrefclk_oc1_1, NMK_GPIO_ALT_C1),
-       DB8540_PIN_GROUP(modobspwrctrl_oc1_1, NMK_GPIO_ALT_C1),
-       DB8540_PIN_GROUP(modobsclkout_oc1_1, NMK_GPIO_ALT_C1),
-       DB8540_PIN_GROUP(moduart1_oc1_1, NMK_GPIO_ALT_C1),
-       DB8540_PIN_GROUP(modprcmudbg_oc1_1, NMK_GPIO_ALT_C1),
-       DB8540_PIN_GROUP(modobsresout_oc1_1, NMK_GPIO_ALT_C1),
-       DB8540_PIN_GROUP(modaccgpo_oc1_1, NMK_GPIO_ALT_C1),
-       DB8540_PIN_GROUP(kp_oc1_1, NMK_GPIO_ALT_C1),
-       DB8540_PIN_GROUP(modxmip_oc1_1, NMK_GPIO_ALT_C1),
-       DB8540_PIN_GROUP(i2c6_oc1_1, NMK_GPIO_ALT_C1),
-       DB8540_PIN_GROUP(u2txrx_oc1_1, NMK_GPIO_ALT_C1),
-       DB8540_PIN_GROUP(u2ctsrts_oc1_1, NMK_GPIO_ALT_C1),
-
-       /* Other alt C2 column */
-       DB8540_PIN_GROUP(sbag_oc2_1, NMK_GPIO_ALT_C2),
-       DB8540_PIN_GROUP(hxclk_oc2_1, NMK_GPIO_ALT_C2),
-       DB8540_PIN_GROUP(modaccuart_oc2_1, NMK_GPIO_ALT_C2),
-       DB8540_PIN_GROUP(stmmod_oc2_1, NMK_GPIO_ALT_C2),
-       DB8540_PIN_GROUP(moduartstmmux_oc2_1, NMK_GPIO_ALT_C2),
-       DB8540_PIN_GROUP(hxgpio_oc2_1, NMK_GPIO_ALT_C2),
-       DB8540_PIN_GROUP(sbag_oc2_2, NMK_GPIO_ALT_C2),
-       DB8540_PIN_GROUP(modobsservice_oc2_1, NMK_GPIO_ALT_C2),
-       DB8540_PIN_GROUP(moduart0_oc2_1, NMK_GPIO_ALT_C2),
-       DB8540_PIN_GROUP(stmape_oc2_1, NMK_GPIO_ALT_C2),
-       DB8540_PIN_GROUP(u2_oc2_1, NMK_GPIO_ALT_C2),
-       DB8540_PIN_GROUP(modxmip_oc2_1, NMK_GPIO_ALT_C2),
-
-       /* Other alt C3 column */
-       DB8540_PIN_GROUP(modaccgpo_oc3_1, NMK_GPIO_ALT_C3),
-       DB8540_PIN_GROUP(tpui_oc3_1, NMK_GPIO_ALT_C3),
-
-       /* Other alt C4 column */
-       DB8540_PIN_GROUP(hwobs_oc4_1, NMK_GPIO_ALT_C4),
-       DB8540_PIN_GROUP(moduart1txrx_oc4_1, NMK_GPIO_ALT_C4),
-       DB8540_PIN_GROUP(moduart1rtscts_oc4_1, NMK_GPIO_ALT_C4),
-       DB8540_PIN_GROUP(modaccuarttxrx_oc4_1, NMK_GPIO_ALT_C4),
-       DB8540_PIN_GROUP(modaccuartrtscts_oc4_1, NMK_GPIO_ALT_C4),
-       DB8540_PIN_GROUP(stmmod_oc4_1, NMK_GPIO_ALT_C4),
-       DB8540_PIN_GROUP(moduartstmmux_oc4_1, NMK_GPIO_ALT_C4),
-
-};
-
-/* We use this macro to define the groups applicable to a function */
-#define DB8540_FUNC_GROUPS(a, b...)       \
-static const char * const a##_groups[] = { b };
-
-DB8540_FUNC_GROUPS(apetrig, "apetrig_b_1");
-DB8540_FUNC_GROUPS(clkout, "clkoutreq_a_1", "clkout1_a_1", "clkout1_a_2",
-               "clkout2_a_1", "clkout2_a_2");
-DB8540_FUNC_GROUPS(ddrtrig, "ddrtrig_b_1");
-DB8540_FUNC_GROUPS(hsi, "hsir_a_1", "hsit_a_1", "hsit_a_2");
-DB8540_FUNC_GROUPS(hwobs, "hwobs_oc4_1");
-DB8540_FUNC_GROUPS(hx, "hxclk_oc2_1", "hxgpio_oc2_1");
-DB8540_FUNC_GROUPS(i2c0, "i2c0_a_1");
-DB8540_FUNC_GROUPS(i2c1, "i2c1_b_1", "i2c1_b_2");
-DB8540_FUNC_GROUPS(i2c2, "i2c2_b_1", "i2c2_b_2");
-DB8540_FUNC_GROUPS(i2c3, "i2c3_c_1", "i2c4_b_1");
-DB8540_FUNC_GROUPS(i2c4, "i2c4_b_2");
-DB8540_FUNC_GROUPS(i2c5, "i2c5_b_1", "i2c5_b_2", "i2c5_c_1", "i2c5_c_2");
-DB8540_FUNC_GROUPS(i2c6, "i2c6_b_1", "i2c6_oc1_1");
-/* The image processor has 8 GPIO pins that can be muxed out */
-DB8540_FUNC_GROUPS(ipgpio, "ipgpio0_a_1", "ipgpio0_c_1", "ipgpio0_c_2",
-               "ipgpio1_a_1", "ipgpio1_c_1", "ipgpio1_c_2",
-               "ipgpio2_b_1", "ipgpio2_c_1", "ipgpio2_c_2",
-               "ipgpio3_b_1", "ipgpio3_c_1", "ipgpio3_c_2",
-               "ipgpio4_c_1", "ipgpio4_c_2",
-               "ipgpio5_c_1", "ipgpio5_c_2",
-               "ipgpio6_c_1", "ipgpio6_c_2",
-               "ipgpio7_b_1", "ipgpio7_c_1");
-DB8540_FUNC_GROUPS(ipi2c, "ipi2c_a_1", "ipi2c_a_2");
-DB8540_FUNC_GROUPS(kp, "kp_a_1", "kp_b_1", "kp_c_1", "kp_oc1_1");
-DB8540_FUNC_GROUPS(lcd, "lcd_d0_d7_a_1", "lcd_d12_d23_a_1", "lcd_d8_d11_a_1",
-               "lcdvsi0_a_1", "lcdvsi1_a_1");
-DB8540_FUNC_GROUPS(lcdb, "lcdb_a_1");
-DB8540_FUNC_GROUPS(mc0, "mc0_a_1");
-DB8540_FUNC_GROUPS(mc1, "mc1_a_1", "mc1_a_2");
-DB8540_FUNC_GROUPS(mc2, "mc2_a_1", "mc2rstn_c_1");
-DB8540_FUNC_GROUPS(mc3, "mc3_b_1");
-DB8540_FUNC_GROUPS(mc4, "mc4_a_1", "mc4rstn_c_1");
-DB8540_FUNC_GROUPS(mc5, "mc5_c_1");
-DB8540_FUNC_GROUPS(modaccgpo, "modaccgpo_c_1", "modaccgpo_oc1_1",
-               "modaccgpo_oc3_1");
-DB8540_FUNC_GROUPS(modaccuart, "modaccuart_oc2_1", "modaccuarttxrx_oc4_1",
-               "modaccuartrtccts_oc4_1");
-DB8540_FUNC_GROUPS(modi2s, "modi2s_a_1");
-DB8540_FUNC_GROUPS(modobs, "modobsclk_a_1", "modobsclkout_oc1_1",
-               "modobspwrctrl_oc1_1", "modobspwrrst_c_1",
-               "modobsrefclk_oc1_1", "modobsresout_c_1",
-               "modobsresout_oc1_1", "modobsservice_oc2_1");
-DB8540_FUNC_GROUPS(modprcmudbg, "modprcmudbg_oc1_1");
-DB8540_FUNC_GROUPS(modrf, "modrf_c_1");
-DB8540_FUNC_GROUPS(modsmb, "modsmb_a_1");
-DB8540_FUNC_GROUPS(modtrig, "modtrig_b_1");
-DB8540_FUNC_GROUPS(moduart, "moduart1_c_1", "moduart1_oc1_1",
-               "moduart1txrx_oc4_1", "moduart1rtscts_oc4_1", "moduart0_oc2_1");
-DB8540_FUNC_GROUPS(moduartstmmux, "moduartstmmux_b_1", "moduartstmmux_oc2_1",
-               "moduartstmmux_oc4_1");
-DB8540_FUNC_GROUPS(modxmip, "modxmip_oc1_1", "modxmip_oc2_1");
-/*
- * MSP0 can only be on a certain set of pins, but the TX/RX pins can be
- * switched around by selecting the altfunction A or B.
- */
-DB8540_FUNC_GROUPS(msp0, "msp0rfsrck_a_1", "msp0tfstck_a_1", "msp0txrx_a_1",
-               "msp0txrx_b_1");
-DB8540_FUNC_GROUPS(msp1, "msp1_a_1", "msp1txrx_a_1", "msp1txrx_b_1");
-DB8540_FUNC_GROUPS(msp2, "msp2sck_a_1", "msp2txdtcktfs_a_1", "msp2rxd_a_1");
-DB8540_FUNC_GROUPS(msp4, "msp4_a_1", "msp4_b_1", "msp4_c_1");
-DB8540_FUNC_GROUPS(pwl, "pwl_b_1", "pwl_b_2", "pwl_b_3", "pwl_b_4");
-DB8540_FUNC_GROUPS(remap, "remap0_oc1_1", "remap1_oc1_1");
-DB8540_FUNC_GROUPS(sbag, "sbag_oc2_1", "sbag_oc2_2");
-/* Select between CS0 on alt B or PS1 on alt C */
-DB8540_FUNC_GROUPS(sm, "sm_b_1", "smcleale_c_1", "smcs0_b_1", "smcs1_b_1",
-               "smps0_c_1", "smps1_c_1");
-DB8540_FUNC_GROUPS(spi0, "spi0_c_1");
-DB8540_FUNC_GROUPS(spi1, "spi1_b_1");
-DB8540_FUNC_GROUPS(spi2, "spi2_a_1");
-DB8540_FUNC_GROUPS(spi3, "spi3_oc1_1");
-DB8540_FUNC_GROUPS(ssp0, "ssp0_a_1");
-DB8540_FUNC_GROUPS(ssp1, "ssp1_a_1");
-DB8540_FUNC_GROUPS(stmape, "stmape_c_1", "stmape_oc1_1", "stmape_oc2_1");
-DB8540_FUNC_GROUPS(stmmod, "stmmod_b_1", "stmmod_oc2_1", "stmmod_oc4_1");
-DB8540_FUNC_GROUPS(tpui, "tpui_oc3_1");
-DB8540_FUNC_GROUPS(u0, "u0_a_1", "u0_c_1");
-DB8540_FUNC_GROUPS(u1, "u1ctsrts_a_1", "u1rxtx_a_1");
-DB8540_FUNC_GROUPS(u2, "u2_oc1_1", "u2_oc2_1", "u2ctsrts_a_1", "u2ctsrts_oc1_1",
-               "u2rxtx_c_1", "u2txrx_a_1", "u2txrx_b_1", "u2txrx_b_2",
-               "u2txrx_oc1_1");
-DB8540_FUNC_GROUPS(u3, "u3ctsrts_b_1", "u3rxtx_c_1", "u3txrxa_b_1");
-DB8540_FUNC_GROUPS(u4, "u4ctsrts_b_1", "u4ctsrts_c_1", "u4txrx_b_1");
-DB8540_FUNC_GROUPS(usb, "usb_a_1");
-
-
-#define FUNCTION(fname)                                        \
-       {                                               \
-               .name = #fname,                         \
-               .groups = fname##_groups,               \
-               .ngroups = ARRAY_SIZE(fname##_groups),  \
-       }
-
-static const struct nmk_function nmk_db8540_functions[] = {
-       FUNCTION(apetrig),
-       FUNCTION(clkout),
-       FUNCTION(ddrtrig),
-       FUNCTION(hsi),
-       FUNCTION(hwobs),
-       FUNCTION(hx),
-       FUNCTION(i2c0),
-       FUNCTION(i2c1),
-       FUNCTION(i2c2),
-       FUNCTION(i2c3),
-       FUNCTION(i2c4),
-       FUNCTION(i2c5),
-       FUNCTION(i2c6),
-       FUNCTION(ipgpio),
-       FUNCTION(ipi2c),
-       FUNCTION(kp),
-       FUNCTION(lcd),
-       FUNCTION(lcdb),
-       FUNCTION(mc0),
-       FUNCTION(mc1),
-       FUNCTION(mc2),
-       FUNCTION(mc3),
-       FUNCTION(mc4),
-       FUNCTION(mc5),
-       FUNCTION(modaccgpo),
-       FUNCTION(modaccuart),
-       FUNCTION(modi2s),
-       FUNCTION(modobs),
-       FUNCTION(modprcmudbg),
-       FUNCTION(modrf),
-       FUNCTION(modsmb),
-       FUNCTION(modtrig),
-       FUNCTION(moduart),
-       FUNCTION(modxmip),
-       FUNCTION(msp0),
-       FUNCTION(msp1),
-       FUNCTION(msp2),
-       FUNCTION(msp4),
-       FUNCTION(pwl),
-       FUNCTION(remap),
-       FUNCTION(sbag),
-       FUNCTION(sm),
-       FUNCTION(spi0),
-       FUNCTION(spi1),
-       FUNCTION(spi2),
-       FUNCTION(spi3),
-       FUNCTION(ssp0),
-       FUNCTION(ssp1),
-       FUNCTION(stmape),
-       FUNCTION(stmmod),
-       FUNCTION(tpui),
-       FUNCTION(u0),
-       FUNCTION(u1),
-       FUNCTION(u2),
-       FUNCTION(u3),
-       FUNCTION(u4),
-       FUNCTION(usb)
-};
-
-static const struct prcm_gpiocr_altcx_pin_desc db8540_altcx_pins[] = {
-       PRCM_GPIOCR_ALTCX(8,    true, PRCM_IDX_GPIOCR1, 20,     /* SPI3_CLK */
-                               false, 0, 0,
-                               false, 0, 0,
-                               false, 0, 0
-       ),
-       PRCM_GPIOCR_ALTCX(9,    true, PRCM_IDX_GPIOCR1, 20,     /* SPI3_RXD */
-                               false, 0, 0,
-                               false, 0, 0,
-                               false, 0, 0
-       ),
-       PRCM_GPIOCR_ALTCX(10,   true, PRCM_IDX_GPIOCR1, 20,     /* SPI3_FRM */
-                               false, 0, 0,
-                               false, 0, 0,
-                               false, 0, 0
-       ),
-       PRCM_GPIOCR_ALTCX(11,   true, PRCM_IDX_GPIOCR1, 20,     /* SPI3_TXD */
-                               false, 0, 0,
-                               false, 0, 0,
-                               false, 0, 0
-       ),
-       PRCM_GPIOCR_ALTCX(23,   true, PRCM_IDX_GPIOCR1, 9,      /* STMAPE_CLK_a */
-                               true, PRCM_IDX_GPIOCR2, 10,     /* SBAG_CLK_a */
-                               false, 0, 0,
-                               false, 0, 0
-       ),
-       PRCM_GPIOCR_ALTCX(24,   true, PRCM_IDX_GPIOCR3, 30,     /* U2_RXD_g */
-                               true, PRCM_IDX_GPIOCR2, 10,     /* SBAG_VAL_a */
-                               false, 0, 0,
-                               false, 0, 0
-       ),
-       PRCM_GPIOCR_ALTCX(25,   true, PRCM_IDX_GPIOCR1, 9,      /* STMAPE_DAT_a[0] */
-                               true, PRCM_IDX_GPIOCR2, 10,     /* SBAG_D_a[0] */
-                               false, 0, 0,
-                               false, 0, 0
-       ),
-       PRCM_GPIOCR_ALTCX(26,   true, PRCM_IDX_GPIOCR1, 9,      /* STMAPE_DAT_a[1] */
-                               true, PRCM_IDX_GPIOCR2, 10,     /* SBAG_D_a[1] */
-                               false, 0, 0,
-                               false, 0, 0
-       ),
-       PRCM_GPIOCR_ALTCX(27,   true, PRCM_IDX_GPIOCR1, 9,      /* STMAPE_DAT_a[2] */
-                               true, PRCM_IDX_GPIOCR2, 10,     /* SBAG_D_a[2] */
-                               false, 0, 0,
-                               false, 0, 0
-       ),
-       PRCM_GPIOCR_ALTCX(28,   true, PRCM_IDX_GPIOCR1, 9,      /* STMAPE_DAT_a[3] */
-                               true, PRCM_IDX_GPIOCR2, 10,     /* SBAG_D_a[3] */
-                               false, 0, 0,
-                               false, 0, 0
-       ),
-       PRCM_GPIOCR_ALTCX(64,   true, PRCM_IDX_GPIOCR1, 15,     /* MODOBS_REFCLK_REQ */
-                               false, 0, 0,
-                               true, PRCM_IDX_GPIOCR1, 2,      /* TPIU_CTL */
-                               true, PRCM_IDX_GPIOCR2, 23      /* HW_OBS_APE_PRCMU[17] */
-       ),
-       PRCM_GPIOCR_ALTCX(65,   true, PRCM_IDX_GPIOCR1, 19,     /* MODOBS_PWRCTRL0 */
-                               true, PRCM_IDX_GPIOCR1, 24,     /* Hx_CLK */
-                               true, PRCM_IDX_GPIOCR1, 2,      /* TPIU_CLK */
-                               true, PRCM_IDX_GPIOCR2, 24      /* HW_OBS_APE_PRCMU[16] */
-       ),
-       PRCM_GPIOCR_ALTCX(66,   true, PRCM_IDX_GPIOCR1, 15,     /* MODOBS_CLKOUT1 */
-                               false, 0, 0,
-                               true, PRCM_IDX_GPIOCR1, 2,      /* TPIU_D[15] */
-                               true, PRCM_IDX_GPIOCR2, 25      /* HW_OBS_APE_PRCMU[15] */
-       ),
-       PRCM_GPIOCR_ALTCX(67,   true, PRCM_IDX_GPIOCR1, 1,      /* MODUART1_TXD_a */
-                               true, PRCM_IDX_GPIOCR1, 6,      /* MODACCUART_TXD_a */
-                               true, PRCM_IDX_GPIOCR1, 2,      /* TPIU_D[14] */
-                               true, PRCM_IDX_GPIOCR2, 26      /* HW_OBS_APE_PRCMU[14] */
-       ),
-       PRCM_GPIOCR_ALTCX(70,   true, PRCM_IDX_GPIOCR3, 6,      /* MOD_PRCMU_DEBUG[17] */
-                               true, PRCM_IDX_GPIOCR1, 10,     /* STMMOD_CLK_b */
-                               true, PRCM_IDX_GPIOCR1, 2,      /* TPIU_D[13] */
-                               true, PRCM_IDX_GPIOCR2, 27      /* HW_OBS_APE_PRCMU[13] */
-       ),
-       PRCM_GPIOCR_ALTCX(71,   true, PRCM_IDX_GPIOCR3, 6,      /* MOD_PRCMU_DEBUG[16] */
-                               true, PRCM_IDX_GPIOCR1, 10,     /* STMMOD_DAT_b[3] */
-                               true, PRCM_IDX_GPIOCR1, 2,      /* TPIU_D[12] */
-                               true, PRCM_IDX_GPIOCR2, 27      /* HW_OBS_APE_PRCMU[12] */
-       ),
-       PRCM_GPIOCR_ALTCX(72,   true, PRCM_IDX_GPIOCR3, 6,      /* MOD_PRCMU_DEBUG[15] */
-                               true, PRCM_IDX_GPIOCR1, 10,     /* STMMOD_DAT_b[2] */
-                               true, PRCM_IDX_GPIOCR1, 2,      /* TPIU_D[11] */
-                               true, PRCM_IDX_GPIOCR2, 27      /* HW_OBS_APE_PRCMU[11] */
-       ),
-       PRCM_GPIOCR_ALTCX(73,   true, PRCM_IDX_GPIOCR3, 6,      /* MOD_PRCMU_DEBUG[14] */
-                               true, PRCM_IDX_GPIOCR1, 10,     /* STMMOD_DAT_b[1] */
-                               true, PRCM_IDX_GPIOCR1, 2,      /* TPIU_D[10] */
-                               true, PRCM_IDX_GPIOCR2, 27      /* HW_OBS_APE_PRCMU[10] */
-       ),
-       PRCM_GPIOCR_ALTCX(74,   true, PRCM_IDX_GPIOCR3, 6,      /* MOD_PRCMU_DEBUG[13] */
-                               true, PRCM_IDX_GPIOCR1, 10,     /* STMMOD_DAT_b[0] */
-                               true, PRCM_IDX_GPIOCR1, 2,      /* TPIU_D[9] */
-                               true, PRCM_IDX_GPIOCR2, 27      /* HW_OBS_APE_PRCMU[9] */
-       ),
-       PRCM_GPIOCR_ALTCX(75,   true, PRCM_IDX_GPIOCR1, 12,     /* MODOBS_RESOUT0_N */
-                               true, PRCM_IDX_GPIOCR2, 1,      /* MODUART_STMMUX_RXD_b */
-                               true, PRCM_IDX_GPIOCR1, 2,      /* TPIU_D[8] */
-                               true, PRCM_IDX_GPIOCR2, 28      /* HW_OBS_APE_PRCMU[8] */
-       ),
-       PRCM_GPIOCR_ALTCX(76,   true, PRCM_IDX_GPIOCR3, 7,      /* MOD_PRCMU_DEBUG[12] */
-                               true, PRCM_IDX_GPIOCR1, 25,     /* Hx_GPIO[7] */
-                               true, PRCM_IDX_GPIOCR1, 2,      /* TPIU_D[7] */
-                               true, PRCM_IDX_GPIOCR2, 29      /* HW_OBS_APE_PRCMU[7] */
-       ),
-       PRCM_GPIOCR_ALTCX(77,   true, PRCM_IDX_GPIOCR3, 7,      /* MOD_PRCMU_DEBUG[11] */
-                               true, PRCM_IDX_GPIOCR1, 25,     /* Hx_GPIO[6] */
-                               true, PRCM_IDX_GPIOCR1, 2,      /* TPIU_D[6] */
-                               true, PRCM_IDX_GPIOCR2, 29      /* HW_OBS_APE_PRCMU[6] */
-       ),
-       PRCM_GPIOCR_ALTCX(78,   true, PRCM_IDX_GPIOCR3, 7,      /* MOD_PRCMU_DEBUG[10] */
-                               true, PRCM_IDX_GPIOCR1, 25,     /* Hx_GPIO[5] */
-                               true, PRCM_IDX_GPIOCR1, 2,      /* TPIU_D[5] */
-                               true, PRCM_IDX_GPIOCR2, 29      /* HW_OBS_APE_PRCMU[5] */
-       ),
-       PRCM_GPIOCR_ALTCX(79,   true, PRCM_IDX_GPIOCR3, 7,      /* MOD_PRCMU_DEBUG[9] */
-                               true, PRCM_IDX_GPIOCR1, 25,     /* Hx_GPIO[4] */
-                               true, PRCM_IDX_GPIOCR1, 2,      /* TPIU_D[4] */
-                               true, PRCM_IDX_GPIOCR2, 29      /* HW_OBS_APE_PRCMU[4] */
-       ),
-       PRCM_GPIOCR_ALTCX(80,   true, PRCM_IDX_GPIOCR1, 26,     /* MODACC_GPO[0] */
-                               true, PRCM_IDX_GPIOCR1, 25,     /* Hx_GPIO[3] */
-                               true, PRCM_IDX_GPIOCR1, 2,      /* TPIU_D[3] */
-                               true, PRCM_IDX_GPIOCR2, 30      /* HW_OBS_APE_PRCMU[3] */
-       ),
-       PRCM_GPIOCR_ALTCX(81,   true, PRCM_IDX_GPIOCR2, 17,     /* MODACC_GPO[1] */
-                               true, PRCM_IDX_GPIOCR1, 25,     /* Hx_GPIO[2] */
-                               true, PRCM_IDX_GPIOCR1, 2,      /* TPIU_D[2] */
-                               true, PRCM_IDX_GPIOCR2, 30      /* HW_OBS_APE_PRCMU[2] */
-       ),
-       PRCM_GPIOCR_ALTCX(82,   true, PRCM_IDX_GPIOCR3, 8,      /* MOD_PRCMU_DEBUG[8] */
-                               true, PRCM_IDX_GPIOCR1, 25,     /* Hx_GPIO[1] */
-                               true, PRCM_IDX_GPIOCR1, 2,      /* TPIU_D[1] */
-                               true, PRCM_IDX_GPIOCR2, 31      /* HW_OBS_APE_PRCMU[1] */
-       ),
-       PRCM_GPIOCR_ALTCX(83,   true, PRCM_IDX_GPIOCR3, 8,      /* MOD_PRCMU_DEBUG[7] */
-                               true, PRCM_IDX_GPIOCR1, 25,     /* Hx_GPIO[0] */
-                               true, PRCM_IDX_GPIOCR1, 2,      /* TPIU_D[0] */
-                               true, PRCM_IDX_GPIOCR2, 31      /* HW_OBS_APE_PRCMU[0] */
-       ),
-       PRCM_GPIOCR_ALTCX(84,   true, PRCM_IDX_GPIOCR3, 9,      /* MOD_PRCMU_DEBUG[6] */
-                               true, PRCM_IDX_GPIOCR1, 8,      /* SBAG_CLK_b */
-                               true, PRCM_IDX_GPIOCR1, 3,      /* TPIU_D[23] */
-                               true, PRCM_IDX_GPIOCR1, 16      /* MODUART1_RXD_b */
-       ),
-       PRCM_GPIOCR_ALTCX(85,   true, PRCM_IDX_GPIOCR3, 9,      /* MOD_PRCMU_DEBUG[5] */
-                               true, PRCM_IDX_GPIOCR1, 8,      /* SBAG_D_b[3] */
-                               true, PRCM_IDX_GPIOCR1, 3,      /* TPIU_D[22] */
-                               true, PRCM_IDX_GPIOCR1, 16      /* MODUART1_TXD_b */
-       ),
-       PRCM_GPIOCR_ALTCX(86,   true, PRCM_IDX_GPIOCR3, 9,      /* MOD_PRCMU_DEBUG[0] */
-                               true, PRCM_IDX_GPIOCR2, 18,     /* STMAPE_DAT_b[0] */
-                               true, PRCM_IDX_GPIOCR1, 14,     /* TPIU_D[25] */
-                               true, PRCM_IDX_GPIOCR1, 11      /* STMMOD_DAT_c[0] */
-       ),
-       PRCM_GPIOCR_ALTCX(87,   true, PRCM_IDX_GPIOCR3, 0,      /* MODACC_GPO_a[5] */
-                               true, PRCM_IDX_GPIOCR2, 3,      /* U2_RXD_c */
-                               true, PRCM_IDX_GPIOCR1, 4,      /* TPIU_D[24] */
-                               true, PRCM_IDX_GPIOCR1, 21      /* MODUART_STMMUX_RXD_c */
-       ),
-       PRCM_GPIOCR_ALTCX(151,  true, PRCM_IDX_GPIOCR1, 18,     /* REMAP0 */
-                               false, 0, 0,
-                               false, 0, 0,
-                               false, 0, 0
-       ),
-       PRCM_GPIOCR_ALTCX(152,  true, PRCM_IDX_GPIOCR1, 18,     /* REMAP1 */
-                               false, 0, 0,
-                               false, 0, 0,
-                               false, 0, 0
-       ),
-       PRCM_GPIOCR_ALTCX(153,  true, PRCM_IDX_GPIOCR3, 2,      /* KP_O_b[6] */
-                               true, PRCM_IDX_GPIOCR1, 8,      /* SBAG_D_b[2] */
-                               true, PRCM_IDX_GPIOCR1, 3,      /* TPIU_D[21] */
-                               true, PRCM_IDX_GPIOCR1, 0       /* MODUART1_RTS */
-       ),
-       PRCM_GPIOCR_ALTCX(154,  true, PRCM_IDX_GPIOCR3, 2,      /* KP_I_b[6] */
-                               true, PRCM_IDX_GPIOCR1, 8,      /* SBAG_D_b[1] */
-                               true, PRCM_IDX_GPIOCR1, 3,      /* TPIU_D[20] */
-                               true, PRCM_IDX_GPIOCR1, 0       /* MODUART1_CTS */
-       ),
-       PRCM_GPIOCR_ALTCX(155,  true, PRCM_IDX_GPIOCR3, 3,      /* KP_O_b[5] */
-                               true, PRCM_IDX_GPIOCR1, 8,      /* SBAG_D_b[0] */
-                               true, PRCM_IDX_GPIOCR1, 3,      /* TPIU_D[19] */
-                               true, PRCM_IDX_GPIOCR1, 5       /* MODACCUART_RXD_c */
-       ),
-       PRCM_GPIOCR_ALTCX(156,  true, PRCM_IDX_GPIOCR3, 3,      /* KP_O_b[4] */
-                               true, PRCM_IDX_GPIOCR1, 8,      /* SBAG_VAL_b */
-                               true, PRCM_IDX_GPIOCR1, 3,      /* TPIU_D[18] */
-                               true, PRCM_IDX_GPIOCR1, 5       /* MODACCUART_TXD_b */
-       ),
-       PRCM_GPIOCR_ALTCX(157,  true, PRCM_IDX_GPIOCR3, 4,      /* KP_I_b[5] */
-                               true, PRCM_IDX_GPIOCR1, 23,     /* MODOBS_SERVICE_N */
-                               true, PRCM_IDX_GPIOCR1, 3,      /* TPIU_D[17] */
-                               true, PRCM_IDX_GPIOCR1, 14      /* MODACCUART_RTS */
-       ),
-       PRCM_GPIOCR_ALTCX(158,  true, PRCM_IDX_GPIOCR3, 4,      /* KP_I_b[4] */
-                               true, PRCM_IDX_GPIOCR2, 0,      /* U2_TXD_c */
-                               true, PRCM_IDX_GPIOCR1, 3,      /* TPIU_D[16] */
-                               true, PRCM_IDX_GPIOCR1, 14      /* MODACCUART_CTS */
-       ),
-       PRCM_GPIOCR_ALTCX(159,  true, PRCM_IDX_GPIOCR3, 5,      /* KP_O_b[3] */
-                               true, PRCM_IDX_GPIOCR3, 10,     /* MODUART0_RXD */
-                               true, PRCM_IDX_GPIOCR1, 4,      /* TPIU_D[31] */
-                               false, 0, 0
-       ),
-       PRCM_GPIOCR_ALTCX(160,  true, PRCM_IDX_GPIOCR3, 5,      /* KP_I_b[3] */
-                               true, PRCM_IDX_GPIOCR3, 10,     /* MODUART0_TXD */
-                               true, PRCM_IDX_GPIOCR1, 4,      /* TPIU_D[30] */
-                               false, 0, 0
-       ),
-       PRCM_GPIOCR_ALTCX(161,  true, PRCM_IDX_GPIOCR3, 9,      /* MOD_PRCMU_DEBUG[4] */
-                               true, PRCM_IDX_GPIOCR2, 18,     /* STMAPE_CLK_b */
-                               true, PRCM_IDX_GPIOCR1, 4,      /* TPIU_D[29] */
-                               true, PRCM_IDX_GPIOCR1, 11      /* STMMOD_CLK_c */
-       ),
-       PRCM_GPIOCR_ALTCX(162,  true, PRCM_IDX_GPIOCR3, 9,      /* MOD_PRCMU_DEBUG[3] */
-                               true, PRCM_IDX_GPIOCR2, 18,     /* STMAPE_DAT_b[3] */
-                               true, PRCM_IDX_GPIOCR1, 4,      /* TPIU_D[28] */
-                               true, PRCM_IDX_GPIOCR1, 11      /* STMMOD_DAT_c[3] */
-       ),
-       PRCM_GPIOCR_ALTCX(163,  true, PRCM_IDX_GPIOCR3, 9,      /* MOD_PRCMU_DEBUG[2] */
-                               true, PRCM_IDX_GPIOCR2, 18,     /* STMAPE_DAT_b[2] */
-                               true, PRCM_IDX_GPIOCR1, 4,      /* TPIU_D[27] */
-                               true, PRCM_IDX_GPIOCR1, 11      /* STMMOD_DAT_c[2] */
-       ),
-       PRCM_GPIOCR_ALTCX(164,  true, PRCM_IDX_GPIOCR3, 9,      /* MOD_PRCMU_DEBUG[1] */
-                               true, PRCM_IDX_GPIOCR2, 18,     /* STMAPE_DAT_b[1] */
-                               true, PRCM_IDX_GPIOCR1, 4,      /* TPIU_D[26] */
-                               true, PRCM_IDX_GPIOCR1, 11      /* STMMOD_DAT_c[1] */
-       ),
-       PRCM_GPIOCR_ALTCX(204,  true, PRCM_IDX_GPIOCR2, 2,      /* U2_RXD_f */
-                               false, 0, 0,
-                               false, 0, 0,
-                               false, 0, 0
-       ),
-       PRCM_GPIOCR_ALTCX(205,  true, PRCM_IDX_GPIOCR2, 2,      /* U2_TXD_f */
-                               false, 0, 0,
-                               false, 0, 0,
-                               false, 0, 0
-       ),
-       PRCM_GPIOCR_ALTCX(206,  true, PRCM_IDX_GPIOCR2, 2,      /* U2_CTSn_b */
-                               false, 0, 0,
-                               false, 0, 0,
-                               false, 0, 0
-       ),
-       PRCM_GPIOCR_ALTCX(207,  true, PRCM_IDX_GPIOCR2, 2,      /* U2_RTSn_b */
-                               false, 0, 0,
-                               false, 0, 0,
-                               false, 0, 0
-       ),
-};
-
-static const u16 db8540_prcm_gpiocr_regs[] = {
-       [PRCM_IDX_GPIOCR1] = 0x138,
-       [PRCM_IDX_GPIOCR2] = 0x574,
-       [PRCM_IDX_GPIOCR3] = 0x2bc,
-};
-
-static const struct nmk_pinctrl_soc_data nmk_db8540_soc = {
-       .gpio_ranges = nmk_db8540_ranges,
-       .gpio_num_ranges = ARRAY_SIZE(nmk_db8540_ranges),
-       .pins = nmk_db8540_pins,
-       .npins = ARRAY_SIZE(nmk_db8540_pins),
-       .functions = nmk_db8540_functions,
-       .nfunctions = ARRAY_SIZE(nmk_db8540_functions),
-       .groups = nmk_db8540_groups,
-       .ngroups = ARRAY_SIZE(nmk_db8540_groups),
-       .altcx_pins = db8540_altcx_pins,
-       .npins_altcx = ARRAY_SIZE(db8540_altcx_pins),
-       .prcm_gpiocr_registers = db8540_prcm_gpiocr_regs,
-};
-
-void nmk_pinctrl_db8540_init(const struct nmk_pinctrl_soc_data **soc)
-{
-       *soc = &nmk_db8540_soc;
-}
diff --git a/drivers/pinctrl/pinctrl-nomadik-stn8815.c b/drivers/pinctrl/pinctrl-nomadik-stn8815.c
deleted file mode 100644 (file)
index ed39dca..0000000
+++ /dev/null
@@ -1,356 +0,0 @@
-#include <linux/kernel.h>
-#include <linux/pinctrl/pinctrl.h>
-#include "pinctrl-nomadik.h"
-
-/* All the pins that can be used for GPIO and some other functions */
-#define _GPIO(offset)          (offset)
-
-#define STN8815_PIN_B4         _GPIO(0)
-#define STN8815_PIN_D5         _GPIO(1)
-#define STN8815_PIN_C5         _GPIO(2)
-#define STN8815_PIN_A4         _GPIO(3)
-#define STN8815_PIN_B5         _GPIO(4)
-#define STN8815_PIN_D6         _GPIO(5)
-#define STN8815_PIN_C6         _GPIO(6)
-#define STN8815_PIN_B6         _GPIO(7)
-#define STN8815_PIN_B10                _GPIO(8)
-#define STN8815_PIN_A10                _GPIO(9)
-#define STN8815_PIN_C11                _GPIO(10)
-#define STN8815_PIN_B11                _GPIO(11)
-#define STN8815_PIN_A11                _GPIO(12)
-#define STN8815_PIN_C12                _GPIO(13)
-#define STN8815_PIN_B12                _GPIO(14)
-#define STN8815_PIN_A12                _GPIO(15)
-#define STN8815_PIN_C13                _GPIO(16)
-#define STN8815_PIN_B13                _GPIO(17)
-#define STN8815_PIN_A13                _GPIO(18)
-#define STN8815_PIN_D13                _GPIO(19)
-#define STN8815_PIN_C14                _GPIO(20)
-#define STN8815_PIN_B14                _GPIO(21)
-#define STN8815_PIN_A14                _GPIO(22)
-#define STN8815_PIN_D15                _GPIO(23)
-#define STN8815_PIN_C15                _GPIO(24)
-#define STN8815_PIN_B15                _GPIO(25)
-#define STN8815_PIN_A15                _GPIO(26)
-#define STN8815_PIN_C16                _GPIO(27)
-#define STN8815_PIN_B16                _GPIO(28)
-#define STN8815_PIN_A16                _GPIO(29)
-#define STN8815_PIN_D17                _GPIO(30)
-#define STN8815_PIN_C17                _GPIO(31)
-#define STN8815_PIN_AB6                _GPIO(32)
-#define STN8815_PIN_AA6                _GPIO(33)
-#define STN8815_PIN_Y6         _GPIO(34)
-#define STN8815_PIN_Y5         _GPIO(35)
-#define STN8815_PIN_AA5                _GPIO(36)
-#define STN8815_PIN_AB5                _GPIO(37)
-#define STN8815_PIN_AB4                _GPIO(38)
-#define STN8815_PIN_Y4         _GPIO(39)
-#define STN8815_PIN_R1         _GPIO(40)
-#define STN8815_PIN_R2         _GPIO(41)
-#define STN8815_PIN_R3         _GPIO(42)
-#define STN8815_PIN_P1         _GPIO(43)
-#define STN8815_PIN_P2         _GPIO(44)
-#define STN8815_PIN_P3         _GPIO(45)
-#define STN8815_PIN_N1         _GPIO(46)
-#define STN8815_PIN_N2         _GPIO(47)
-#define STN8815_PIN_N3         _GPIO(48)
-#define STN8815_PIN_M1         _GPIO(49)
-#define STN8815_PIN_M3         _GPIO(50)
-#define STN8815_PIN_M2         _GPIO(51)
-#define STN8815_PIN_L1         _GPIO(52)
-#define STN8815_PIN_L4         _GPIO(53)
-#define STN8815_PIN_L3         _GPIO(54)
-#define STN8815_PIN_L2         _GPIO(55)
-#define STN8815_PIN_F3         _GPIO(56)
-#define STN8815_PIN_F2         _GPIO(57)
-#define STN8815_PIN_E1         _GPIO(58)
-#define STN8815_PIN_E3         _GPIO(59)
-#define STN8815_PIN_E2         _GPIO(60)
-#define STN8815_PIN_E4         _GPIO(61)
-#define STN8815_PIN_D3         _GPIO(62)
-#define STN8815_PIN_D2         _GPIO(63)
-#define STN8815_PIN_F21                _GPIO(64)
-#define STN8815_PIN_F20                _GPIO(65)
-#define STN8815_PIN_E22                _GPIO(66)
-#define STN8815_PIN_D22                _GPIO(67)
-#define STN8815_PIN_E21                _GPIO(68)
-#define STN8815_PIN_E20                _GPIO(69)
-#define STN8815_PIN_C22                _GPIO(70)
-#define STN8815_PIN_D21                _GPIO(71)
-#define STN8815_PIN_D20                _GPIO(72)
-#define STN8815_PIN_C21                _GPIO(73)
-#define STN8815_PIN_C20                _GPIO(74)
-#define STN8815_PIN_C19                _GPIO(75)
-#define STN8815_PIN_B20                _GPIO(76)
-#define STN8815_PIN_B8         _GPIO(77)
-#define STN8815_PIN_A8         _GPIO(78)
-#define STN8815_PIN_C9         _GPIO(79)
-#define STN8815_PIN_B9         _GPIO(80)
-#define STN8815_PIN_A9         _GPIO(81)
-#define STN8815_PIN_C10                _GPIO(82)
-#define STN8815_PIN_K1         _GPIO(83)
-#define STN8815_PIN_K3         _GPIO(84)
-#define STN8815_PIN_K2         _GPIO(85)
-#define STN8815_PIN_J1         _GPIO(86)
-#define STN8815_PIN_J3         _GPIO(87)
-#define STN8815_PIN_J2         _GPIO(88)
-#define STN8815_PIN_H1         _GPIO(89)
-#define STN8815_PIN_H3         _GPIO(90)
-#define STN8815_PIN_H2         _GPIO(91)
-#define STN8815_PIN_G1         _GPIO(92)
-#define STN8815_PIN_G3         _GPIO(93)
-#define STN8815_PIN_G2         _GPIO(94)
-#define STN8815_PIN_F1         _GPIO(95)
-#define STN8815_PIN_T20                _GPIO(96)
-#define STN8815_PIN_R21                _GPIO(97)
-#define STN8815_PIN_R20                _GPIO(98)
-#define STN8815_PIN_U22                _GPIO(99)
-#define STN8815_PIN_N21                _GPIO(100)
-#define STN8815_PIN_N20                _GPIO(101)
-#define STN8815_PIN_P22                _GPIO(102)
-#define STN8815_PIN_N22                _GPIO(103)
-#define STN8815_PIN_V22                _GPIO(104)
-#define STN8815_PIN_V21                _GPIO(105)
-#define STN8815_PIN_K22                _GPIO(106)
-#define STN8815_PIN_K21                _GPIO(107)
-#define STN8815_PIN_H20                _GPIO(108)
-#define STN8815_PIN_G20                _GPIO(109)
-#define STN8815_PIN_L21                _GPIO(110)
-#define STN8815_PIN_H21                _GPIO(111)
-#define STN8815_PIN_J21                _GPIO(112)
-#define STN8815_PIN_H22                _GPIO(113)
-#define STN8815_PIN_K20                _GPIO(114)
-#define STN8815_PIN_L22                _GPIO(115)
-#define STN8815_PIN_G21                _GPIO(116)
-#define STN8815_PIN_J20                _GPIO(117)
-#define STN8815_PIN_G22                _GPIO(118)
-#define STN8815_PIN_U19                _GPIO(119)
-#define STN8815_PIN_G19                _GPIO(120)
-#define STN8815_PIN_M22                _GPIO(121)
-#define STN8815_PIN_M19                _GPIO(122)
-#define STN8815_PIN_J22                _GPIO(123)
-/* GPIOs 124-127 not routed to pins */
-
-/*
- * The names of the pins are denoted by GPIO number and ball name, even
- * though they can be used for other things than GPIO, this is the first
- * column in the table of the data sheet and often used on schematics and
- * such.
- */
-static const struct pinctrl_pin_desc nmk_stn8815_pins[] = {
-       PINCTRL_PIN(STN8815_PIN_B4, "GPIO0_B4"),
-       PINCTRL_PIN(STN8815_PIN_D5, "GPIO1_D5"),
-       PINCTRL_PIN(STN8815_PIN_C5, "GPIO2_C5"),
-       PINCTRL_PIN(STN8815_PIN_A4, "GPIO3_A4"),
-       PINCTRL_PIN(STN8815_PIN_B5, "GPIO4_B5"),
-       PINCTRL_PIN(STN8815_PIN_D6, "GPIO5_D6"),
-       PINCTRL_PIN(STN8815_PIN_C6, "GPIO6_C6"),
-       PINCTRL_PIN(STN8815_PIN_B6, "GPIO7_B6"),
-       PINCTRL_PIN(STN8815_PIN_B10, "GPIO8_B10"),
-       PINCTRL_PIN(STN8815_PIN_A10, "GPIO9_A10"),
-       PINCTRL_PIN(STN8815_PIN_C11, "GPIO10_C11"),
-       PINCTRL_PIN(STN8815_PIN_B11, "GPIO11_B11"),
-       PINCTRL_PIN(STN8815_PIN_A11, "GPIO12_A11"),
-       PINCTRL_PIN(STN8815_PIN_C12, "GPIO13_C12"),
-       PINCTRL_PIN(STN8815_PIN_B12, "GPIO14_B12"),
-       PINCTRL_PIN(STN8815_PIN_A12, "GPIO15_A12"),
-       PINCTRL_PIN(STN8815_PIN_C13, "GPIO16_C13"),
-       PINCTRL_PIN(STN8815_PIN_B13, "GPIO17_B13"),
-       PINCTRL_PIN(STN8815_PIN_A13, "GPIO18_A13"),
-       PINCTRL_PIN(STN8815_PIN_D13, "GPIO19_D13"),
-       PINCTRL_PIN(STN8815_PIN_C14, "GPIO20_C14"),
-       PINCTRL_PIN(STN8815_PIN_B14, "GPIO21_B14"),
-       PINCTRL_PIN(STN8815_PIN_A14, "GPIO22_A14"),
-       PINCTRL_PIN(STN8815_PIN_D15, "GPIO23_D15"),
-       PINCTRL_PIN(STN8815_PIN_C15, "GPIO24_C15"),
-       PINCTRL_PIN(STN8815_PIN_B15, "GPIO25_B15"),
-       PINCTRL_PIN(STN8815_PIN_A15, "GPIO26_A15"),
-       PINCTRL_PIN(STN8815_PIN_C16, "GPIO27_C16"),
-       PINCTRL_PIN(STN8815_PIN_B16, "GPIO28_B16"),
-       PINCTRL_PIN(STN8815_PIN_A16, "GPIO29_A16"),
-       PINCTRL_PIN(STN8815_PIN_D17, "GPIO30_D17"),
-       PINCTRL_PIN(STN8815_PIN_C17, "GPIO31_C17"),
-       PINCTRL_PIN(STN8815_PIN_AB6, "GPIO32_AB6"),
-       PINCTRL_PIN(STN8815_PIN_AA6, "GPIO33_AA6"),
-       PINCTRL_PIN(STN8815_PIN_Y6, "GPIO34_Y6"),
-       PINCTRL_PIN(STN8815_PIN_Y5, "GPIO35_Y5"),
-       PINCTRL_PIN(STN8815_PIN_AA5, "GPIO36_AA5"),
-       PINCTRL_PIN(STN8815_PIN_AB5, "GPIO37_AB5"),
-       PINCTRL_PIN(STN8815_PIN_AB4, "GPIO38_AB4"),
-       PINCTRL_PIN(STN8815_PIN_Y4, "GPIO39_Y4"),
-       PINCTRL_PIN(STN8815_PIN_R1, "GPIO40_R1"),
-       PINCTRL_PIN(STN8815_PIN_R2, "GPIO41_R2"),
-       PINCTRL_PIN(STN8815_PIN_R3, "GPIO42_R3"),
-       PINCTRL_PIN(STN8815_PIN_P1, "GPIO43_P1"),
-       PINCTRL_PIN(STN8815_PIN_P2, "GPIO44_P2"),
-       PINCTRL_PIN(STN8815_PIN_P3, "GPIO45_P3"),
-       PINCTRL_PIN(STN8815_PIN_N1, "GPIO46_N1"),
-       PINCTRL_PIN(STN8815_PIN_N2, "GPIO47_N2"),
-       PINCTRL_PIN(STN8815_PIN_N3, "GPIO48_N3"),
-       PINCTRL_PIN(STN8815_PIN_M1, "GPIO49_M1"),
-       PINCTRL_PIN(STN8815_PIN_M3, "GPIO50_M3"),
-       PINCTRL_PIN(STN8815_PIN_M2, "GPIO51_M2"),
-       PINCTRL_PIN(STN8815_PIN_L1, "GPIO52_L1"),
-       PINCTRL_PIN(STN8815_PIN_L4, "GPIO53_L4"),
-       PINCTRL_PIN(STN8815_PIN_L3, "GPIO54_L3"),
-       PINCTRL_PIN(STN8815_PIN_L2, "GPIO55_L2"),
-       PINCTRL_PIN(STN8815_PIN_F3, "GPIO56_F3"),
-       PINCTRL_PIN(STN8815_PIN_F2, "GPIO57_F2"),
-       PINCTRL_PIN(STN8815_PIN_E1, "GPIO58_E1"),
-       PINCTRL_PIN(STN8815_PIN_E3, "GPIO59_E3"),
-       PINCTRL_PIN(STN8815_PIN_E2, "GPIO60_E2"),
-       PINCTRL_PIN(STN8815_PIN_E4, "GPIO61_E4"),
-       PINCTRL_PIN(STN8815_PIN_D3, "GPIO62_D3"),
-       PINCTRL_PIN(STN8815_PIN_D2, "GPIO63_D2"),
-       PINCTRL_PIN(STN8815_PIN_F21, "GPIO64_F21"),
-       PINCTRL_PIN(STN8815_PIN_F20, "GPIO65_F20"),
-       PINCTRL_PIN(STN8815_PIN_E22, "GPIO66_E22"),
-       PINCTRL_PIN(STN8815_PIN_D22, "GPIO67_D22"),
-       PINCTRL_PIN(STN8815_PIN_E21, "GPIO68_E21"),
-       PINCTRL_PIN(STN8815_PIN_E20, "GPIO69_E20"),
-       PINCTRL_PIN(STN8815_PIN_C22, "GPIO70_C22"),
-       PINCTRL_PIN(STN8815_PIN_D21, "GPIO71_D21"),
-       PINCTRL_PIN(STN8815_PIN_D20, "GPIO72_D20"),
-       PINCTRL_PIN(STN8815_PIN_C21, "GPIO73_C21"),
-       PINCTRL_PIN(STN8815_PIN_C20, "GPIO74_C20"),
-       PINCTRL_PIN(STN8815_PIN_C19, "GPIO75_C19"),
-       PINCTRL_PIN(STN8815_PIN_B20, "GPIO76_B20"),
-       PINCTRL_PIN(STN8815_PIN_B8, "GPIO77_B8"),
-       PINCTRL_PIN(STN8815_PIN_A8, "GPIO78_A8"),
-       PINCTRL_PIN(STN8815_PIN_C9, "GPIO79_C9"),
-       PINCTRL_PIN(STN8815_PIN_B9, "GPIO80_B9"),
-       PINCTRL_PIN(STN8815_PIN_A9, "GPIO81_A9"),
-       PINCTRL_PIN(STN8815_PIN_C10, "GPIO82_C10"),
-       PINCTRL_PIN(STN8815_PIN_K1, "GPIO83_K1"),
-       PINCTRL_PIN(STN8815_PIN_K3, "GPIO84_K3"),
-       PINCTRL_PIN(STN8815_PIN_K2, "GPIO85_K2"),
-       PINCTRL_PIN(STN8815_PIN_J1, "GPIO86_J1"),
-       PINCTRL_PIN(STN8815_PIN_J3, "GPIO87_J3"),
-       PINCTRL_PIN(STN8815_PIN_J2, "GPIO88_J2"),
-       PINCTRL_PIN(STN8815_PIN_H1, "GPIO89_H1"),
-       PINCTRL_PIN(STN8815_PIN_H3, "GPIO90_H3"),
-       PINCTRL_PIN(STN8815_PIN_H2, "GPIO91_H2"),
-       PINCTRL_PIN(STN8815_PIN_G1, "GPIO92_G1"),
-       PINCTRL_PIN(STN8815_PIN_G3, "GPIO93_G3"),
-       PINCTRL_PIN(STN8815_PIN_G2, "GPIO94_G2"),
-       PINCTRL_PIN(STN8815_PIN_F1, "GPIO95_F1"),
-       PINCTRL_PIN(STN8815_PIN_T20, "GPIO96_T20"),
-       PINCTRL_PIN(STN8815_PIN_R21, "GPIO97_R21"),
-       PINCTRL_PIN(STN8815_PIN_R20, "GPIO98_R20"),
-       PINCTRL_PIN(STN8815_PIN_U22, "GPIO99_U22"),
-       PINCTRL_PIN(STN8815_PIN_N21, "GPIO100_N21"),
-       PINCTRL_PIN(STN8815_PIN_N20, "GPIO101_N20"),
-       PINCTRL_PIN(STN8815_PIN_P22, "GPIO102_P22"),
-       PINCTRL_PIN(STN8815_PIN_N22, "GPIO103_N22"),
-       PINCTRL_PIN(STN8815_PIN_V22, "GPIO104_V22"),
-       PINCTRL_PIN(STN8815_PIN_V21, "GPIO105_V21"),
-       PINCTRL_PIN(STN8815_PIN_K22, "GPIO106_K22"),
-       PINCTRL_PIN(STN8815_PIN_K21, "GPIO107_K21"),
-       PINCTRL_PIN(STN8815_PIN_H20, "GPIO108_H20"),
-       PINCTRL_PIN(STN8815_PIN_G20, "GPIO109_G20"),
-       PINCTRL_PIN(STN8815_PIN_L21, "GPIO110_L21"),
-       PINCTRL_PIN(STN8815_PIN_H21, "GPIO111_H21"),
-       PINCTRL_PIN(STN8815_PIN_J21, "GPIO112_J21"),
-       PINCTRL_PIN(STN8815_PIN_H22, "GPIO113_H22"),
-       PINCTRL_PIN(STN8815_PIN_K20, "GPIO114_K20"),
-       PINCTRL_PIN(STN8815_PIN_L22, "GPIO115_L22"),
-       PINCTRL_PIN(STN8815_PIN_G21, "GPIO116_G21"),
-       PINCTRL_PIN(STN8815_PIN_J20, "GPIO117_J20"),
-       PINCTRL_PIN(STN8815_PIN_G22, "GPIO118_G22"),
-       PINCTRL_PIN(STN8815_PIN_U19, "GPIO119_U19"),
-       PINCTRL_PIN(STN8815_PIN_G19, "GPIO120_G19"),
-       PINCTRL_PIN(STN8815_PIN_M22, "GPIO121_M22"),
-       PINCTRL_PIN(STN8815_PIN_M19, "GPIO122_M19"),
-       PINCTRL_PIN(STN8815_PIN_J22, "GPIO123_J22"),
-};
-
-#define STN8815_GPIO_RANGE(a, b, c) { .name = "STN8815", .id = a, .base = b, \
-                       .pin_base = b, .npins = c }
-
-/*
- * This matches the 32-pin gpio chips registered by the GPIO portion. This
- * cannot be const since we assign the struct gpio_chip * pointer at runtime.
- */
-static struct pinctrl_gpio_range nmk_stn8815_ranges[] = {
-       STN8815_GPIO_RANGE(0, 0, 32),
-       STN8815_GPIO_RANGE(1, 32, 32),
-       STN8815_GPIO_RANGE(2, 64, 32),
-       STN8815_GPIO_RANGE(3, 96, 28),
-};
-
-/*
- * Read the pin group names like this:
- * u0_a_1    = first groups of pins for uart0 on alt function a
- * i2c2_b_2  = second group of pins for i2c2 on alt function b
- */
-
-/* Altfunction A */
-static const unsigned u0_a_1_pins[] = { STN8815_PIN_B4, STN8815_PIN_D5,
-       STN8815_PIN_C5, STN8815_PIN_A4, STN8815_PIN_B5, STN8815_PIN_D6,
-       STN8815_PIN_C6, STN8815_PIN_B6 };
-static const unsigned mmcsd_a_1_pins[] = { STN8815_PIN_B10, STN8815_PIN_A10,
-       STN8815_PIN_C11, STN8815_PIN_B11, STN8815_PIN_A11, STN8815_PIN_C12,
-       STN8815_PIN_B12, STN8815_PIN_A12, STN8815_PIN_C13, STN8815_PIN_C15 };
-static const unsigned u1_a_1_pins[] = { STN8815_PIN_M2, STN8815_PIN_L1,
-                                       STN8815_PIN_F3, STN8815_PIN_F2 };
-static const unsigned i2c1_a_1_pins[] = { STN8815_PIN_L4, STN8815_PIN_L3 };
-static const unsigned i2c0_a_1_pins[] = { STN8815_PIN_D3, STN8815_PIN_D2 };
-/* Altfunction B */
-static const unsigned u1_b_1_pins[] = { STN8815_PIN_B16, STN8815_PIN_A16 };
-static const unsigned i2cusb_b_1_pins[] = { STN8815_PIN_C21, STN8815_PIN_C20 };
-
-#define STN8815_PIN_GROUP(a, b) { .name = #a, .pins = a##_pins,                \
-                       .npins = ARRAY_SIZE(a##_pins), .altsetting = b }
-
-static const struct nmk_pingroup nmk_stn8815_groups[] = {
-       STN8815_PIN_GROUP(u0_a_1, NMK_GPIO_ALT_A),
-       STN8815_PIN_GROUP(mmcsd_a_1, NMK_GPIO_ALT_A),
-       STN8815_PIN_GROUP(u1_a_1, NMK_GPIO_ALT_A),
-       STN8815_PIN_GROUP(i2c1_a_1, NMK_GPIO_ALT_A),
-       STN8815_PIN_GROUP(i2c0_a_1, NMK_GPIO_ALT_A),
-       STN8815_PIN_GROUP(u1_b_1, NMK_GPIO_ALT_B),
-       STN8815_PIN_GROUP(i2cusb_b_1, NMK_GPIO_ALT_B),
-};
-
-/* We use this macro to define the groups applicable to a function */
-#define STN8815_FUNC_GROUPS(a, b...)      \
-static const char * const a##_groups[] = { b };
-
-STN8815_FUNC_GROUPS(u0, "u0_a_1");
-STN8815_FUNC_GROUPS(mmcsd, "mmcsd_a_1");
-STN8815_FUNC_GROUPS(u1, "u1_a_1", "u1_b_1");
-STN8815_FUNC_GROUPS(i2c1, "i2c1_a_1");
-STN8815_FUNC_GROUPS(i2c0, "i2c0_a_1");
-STN8815_FUNC_GROUPS(i2cusb, "i2cusb_b_1");
-
-#define FUNCTION(fname)                                        \
-       {                                               \
-               .name = #fname,                         \
-               .groups = fname##_groups,               \
-               .ngroups = ARRAY_SIZE(fname##_groups),  \
-       }
-
-static const struct nmk_function nmk_stn8815_functions[] = {
-       FUNCTION(u0),
-       FUNCTION(mmcsd),
-       FUNCTION(u1),
-       FUNCTION(i2c1),
-       FUNCTION(i2c0),
-       FUNCTION(i2cusb),
-};
-
-static const struct nmk_pinctrl_soc_data nmk_stn8815_soc = {
-       .gpio_ranges = nmk_stn8815_ranges,
-       .gpio_num_ranges = ARRAY_SIZE(nmk_stn8815_ranges),
-       .pins = nmk_stn8815_pins,
-       .npins = ARRAY_SIZE(nmk_stn8815_pins),
-       .functions = nmk_stn8815_functions,
-       .nfunctions = ARRAY_SIZE(nmk_stn8815_functions),
-       .groups = nmk_stn8815_groups,
-       .ngroups = ARRAY_SIZE(nmk_stn8815_groups),
-};
-
-void nmk_pinctrl_stn8815_init(const struct nmk_pinctrl_soc_data **soc)
-{
-       *soc = &nmk_stn8815_soc;
-}
diff --git a/drivers/pinctrl/pinctrl-nomadik.c b/drivers/pinctrl/pinctrl-nomadik.c
deleted file mode 100644 (file)
index 8f6f16e..0000000
+++ /dev/null
@@ -1,2115 +0,0 @@
-/*
- * Generic GPIO driver for logic cells found in the Nomadik SoC
- *
- * Copyright (C) 2008,2009 STMicroelectronics
- * Copyright (C) 2009 Alessandro Rubini <rubini@unipv.it>
- *   Rewritten based on work by Prafulla WADASKAR <prafulla.wadaskar@st.com>
- * Copyright (C) 2011-2013 Linus Walleij <linus.walleij@linaro.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/gpio.h>
-#include <linux/spinlock.h>
-#include <linux/interrupt.h>
-#include <linux/slab.h>
-#include <linux/of_device.h>
-#include <linux/of_address.h>
-#include <linux/pinctrl/machine.h>
-#include <linux/pinctrl/pinctrl.h>
-#include <linux/pinctrl/pinmux.h>
-#include <linux/pinctrl/pinconf.h>
-/* Since we request GPIOs from ourself */
-#include <linux/pinctrl/consumer.h>
-#include "pinctrl-nomadik.h"
-#include "core.h"
-
-/*
- * The GPIO module in the Nomadik family of Systems-on-Chip is an
- * AMBA device, managing 32 pins and alternate functions.  The logic block
- * is currently used in the Nomadik and ux500.
- *
- * Symbols in this file are called "nmk_gpio" for "nomadik gpio"
- */
-
-/*
- * pin configurations are represented by 32-bit integers:
- *
- *     bit  0.. 8 - Pin Number (512 Pins Maximum)
- *     bit  9..10 - Alternate Function Selection
- *     bit 11..12 - Pull up/down state
- *     bit     13 - Sleep mode behaviour
- *     bit     14 - Direction
- *     bit     15 - Value (if output)
- *     bit 16..18 - SLPM pull up/down state
- *     bit 19..20 - SLPM direction
- *     bit 21..22 - SLPM Value (if output)
- *     bit 23..25 - PDIS value (if input)
- *     bit     26 - Gpio mode
- *     bit     27 - Sleep mode
- *
- * to facilitate the definition, the following macros are provided
- *
- * PIN_CFG_DEFAULT - default config (0):
- *                  pull up/down = disabled
- *                  sleep mode = input/wakeup
- *                  direction = input
- *                  value = low
- *                  SLPM direction = same as normal
- *                  SLPM pull = same as normal
- *                  SLPM value = same as normal
- *
- * PIN_CFG        - default config with alternate function
- */
-
-typedef unsigned long pin_cfg_t;
-
-#define PIN_NUM_MASK           0x1ff
-#define PIN_NUM(x)             ((x) & PIN_NUM_MASK)
-
-#define PIN_ALT_SHIFT          9
-#define PIN_ALT_MASK           (0x3 << PIN_ALT_SHIFT)
-#define PIN_ALT(x)             (((x) & PIN_ALT_MASK) >> PIN_ALT_SHIFT)
-#define PIN_GPIO               (NMK_GPIO_ALT_GPIO << PIN_ALT_SHIFT)
-#define PIN_ALT_A              (NMK_GPIO_ALT_A << PIN_ALT_SHIFT)
-#define PIN_ALT_B              (NMK_GPIO_ALT_B << PIN_ALT_SHIFT)
-#define PIN_ALT_C              (NMK_GPIO_ALT_C << PIN_ALT_SHIFT)
-
-#define PIN_PULL_SHIFT         11
-#define PIN_PULL_MASK          (0x3 << PIN_PULL_SHIFT)
-#define PIN_PULL(x)            (((x) & PIN_PULL_MASK) >> PIN_PULL_SHIFT)
-#define PIN_PULL_NONE          (NMK_GPIO_PULL_NONE << PIN_PULL_SHIFT)
-#define PIN_PULL_UP            (NMK_GPIO_PULL_UP << PIN_PULL_SHIFT)
-#define PIN_PULL_DOWN          (NMK_GPIO_PULL_DOWN << PIN_PULL_SHIFT)
-
-#define PIN_SLPM_SHIFT         13
-#define PIN_SLPM_MASK          (0x1 << PIN_SLPM_SHIFT)
-#define PIN_SLPM(x)            (((x) & PIN_SLPM_MASK) >> PIN_SLPM_SHIFT)
-#define PIN_SLPM_MAKE_INPUT    (NMK_GPIO_SLPM_INPUT << PIN_SLPM_SHIFT)
-#define PIN_SLPM_NOCHANGE      (NMK_GPIO_SLPM_NOCHANGE << PIN_SLPM_SHIFT)
-/* These two replace the above in DB8500v2+ */
-#define PIN_SLPM_WAKEUP_ENABLE (NMK_GPIO_SLPM_WAKEUP_ENABLE << PIN_SLPM_SHIFT)
-#define PIN_SLPM_WAKEUP_DISABLE        (NMK_GPIO_SLPM_WAKEUP_DISABLE << PIN_SLPM_SHIFT)
-#define PIN_SLPM_USE_MUX_SETTINGS_IN_SLEEP PIN_SLPM_WAKEUP_DISABLE
-
-#define PIN_SLPM_GPIO  PIN_SLPM_WAKEUP_ENABLE /* In SLPM, pin is a gpio */
-#define PIN_SLPM_ALTFUNC PIN_SLPM_WAKEUP_DISABLE /* In SLPM, pin is altfunc */
-
-#define PIN_DIR_SHIFT          14
-#define PIN_DIR_MASK           (0x1 << PIN_DIR_SHIFT)
-#define PIN_DIR(x)             (((x) & PIN_DIR_MASK) >> PIN_DIR_SHIFT)
-#define PIN_DIR_INPUT          (0 << PIN_DIR_SHIFT)
-#define PIN_DIR_OUTPUT         (1 << PIN_DIR_SHIFT)
-
-#define PIN_VAL_SHIFT          15
-#define PIN_VAL_MASK           (0x1 << PIN_VAL_SHIFT)
-#define PIN_VAL(x)             (((x) & PIN_VAL_MASK) >> PIN_VAL_SHIFT)
-#define PIN_VAL_LOW            (0 << PIN_VAL_SHIFT)
-#define PIN_VAL_HIGH           (1 << PIN_VAL_SHIFT)
-
-#define PIN_SLPM_PULL_SHIFT    16
-#define PIN_SLPM_PULL_MASK     (0x7 << PIN_SLPM_PULL_SHIFT)
-#define PIN_SLPM_PULL(x)       \
-       (((x) & PIN_SLPM_PULL_MASK) >> PIN_SLPM_PULL_SHIFT)
-#define PIN_SLPM_PULL_NONE     \
-       ((1 + NMK_GPIO_PULL_NONE) << PIN_SLPM_PULL_SHIFT)
-#define PIN_SLPM_PULL_UP       \
-       ((1 + NMK_GPIO_PULL_UP) << PIN_SLPM_PULL_SHIFT)
-#define PIN_SLPM_PULL_DOWN     \
-       ((1 + NMK_GPIO_PULL_DOWN) << PIN_SLPM_PULL_SHIFT)
-
-#define PIN_SLPM_DIR_SHIFT     19
-#define PIN_SLPM_DIR_MASK      (0x3 << PIN_SLPM_DIR_SHIFT)
-#define PIN_SLPM_DIR(x)                \
-       (((x) & PIN_SLPM_DIR_MASK) >> PIN_SLPM_DIR_SHIFT)
-#define PIN_SLPM_DIR_INPUT     ((1 + 0) << PIN_SLPM_DIR_SHIFT)
-#define PIN_SLPM_DIR_OUTPUT    ((1 + 1) << PIN_SLPM_DIR_SHIFT)
-
-#define PIN_SLPM_VAL_SHIFT     21
-#define PIN_SLPM_VAL_MASK      (0x3 << PIN_SLPM_VAL_SHIFT)
-#define PIN_SLPM_VAL(x)                \
-       (((x) & PIN_SLPM_VAL_MASK) >> PIN_SLPM_VAL_SHIFT)
-#define PIN_SLPM_VAL_LOW       ((1 + 0) << PIN_SLPM_VAL_SHIFT)
-#define PIN_SLPM_VAL_HIGH      ((1 + 1) << PIN_SLPM_VAL_SHIFT)
-
-#define PIN_SLPM_PDIS_SHIFT            23
-#define PIN_SLPM_PDIS_MASK             (0x3 << PIN_SLPM_PDIS_SHIFT)
-#define PIN_SLPM_PDIS(x)       \
-       (((x) & PIN_SLPM_PDIS_MASK) >> PIN_SLPM_PDIS_SHIFT)
-#define PIN_SLPM_PDIS_NO_CHANGE                (0 << PIN_SLPM_PDIS_SHIFT)
-#define PIN_SLPM_PDIS_DISABLED         (1 << PIN_SLPM_PDIS_SHIFT)
-#define PIN_SLPM_PDIS_ENABLED          (2 << PIN_SLPM_PDIS_SHIFT)
-
-#define PIN_LOWEMI_SHIFT       25
-#define PIN_LOWEMI_MASK                (0x1 << PIN_LOWEMI_SHIFT)
-#define PIN_LOWEMI(x)          (((x) & PIN_LOWEMI_MASK) >> PIN_LOWEMI_SHIFT)
-#define PIN_LOWEMI_DISABLED    (0 << PIN_LOWEMI_SHIFT)
-#define PIN_LOWEMI_ENABLED     (1 << PIN_LOWEMI_SHIFT)
-
-#define PIN_GPIOMODE_SHIFT     26
-#define PIN_GPIOMODE_MASK      (0x1 << PIN_GPIOMODE_SHIFT)
-#define PIN_GPIOMODE(x)                (((x) & PIN_GPIOMODE_MASK) >> PIN_GPIOMODE_SHIFT)
-#define PIN_GPIOMODE_DISABLED  (0 << PIN_GPIOMODE_SHIFT)
-#define PIN_GPIOMODE_ENABLED   (1 << PIN_GPIOMODE_SHIFT)
-
-#define PIN_SLEEPMODE_SHIFT    27
-#define PIN_SLEEPMODE_MASK     (0x1 << PIN_SLEEPMODE_SHIFT)
-#define PIN_SLEEPMODE(x)       (((x) & PIN_SLEEPMODE_MASK) >> PIN_SLEEPMODE_SHIFT)
-#define PIN_SLEEPMODE_DISABLED (0 << PIN_SLEEPMODE_SHIFT)
-#define PIN_SLEEPMODE_ENABLED  (1 << PIN_SLEEPMODE_SHIFT)
-
-
-/* Shortcuts.  Use these instead of separate DIR, PULL, and VAL.  */
-#define PIN_INPUT_PULLDOWN     (PIN_DIR_INPUT | PIN_PULL_DOWN)
-#define PIN_INPUT_PULLUP       (PIN_DIR_INPUT | PIN_PULL_UP)
-#define PIN_INPUT_NOPULL       (PIN_DIR_INPUT | PIN_PULL_NONE)
-#define PIN_OUTPUT_LOW         (PIN_DIR_OUTPUT | PIN_VAL_LOW)
-#define PIN_OUTPUT_HIGH                (PIN_DIR_OUTPUT | PIN_VAL_HIGH)
-
-#define PIN_SLPM_INPUT_PULLDOWN        (PIN_SLPM_DIR_INPUT | PIN_SLPM_PULL_DOWN)
-#define PIN_SLPM_INPUT_PULLUP  (PIN_SLPM_DIR_INPUT | PIN_SLPM_PULL_UP)
-#define PIN_SLPM_INPUT_NOPULL  (PIN_SLPM_DIR_INPUT | PIN_SLPM_PULL_NONE)
-#define PIN_SLPM_OUTPUT_LOW    (PIN_SLPM_DIR_OUTPUT | PIN_SLPM_VAL_LOW)
-#define PIN_SLPM_OUTPUT_HIGH   (PIN_SLPM_DIR_OUTPUT | PIN_SLPM_VAL_HIGH)
-
-#define PIN_CFG_DEFAULT                (0)
-
-#define PIN_CFG(num, alt)              \
-       (PIN_CFG_DEFAULT |\
-        (PIN_NUM(num) | PIN_##alt))
-
-#define PIN_CFG_INPUT(num, alt, pull)          \
-       (PIN_CFG_DEFAULT |\
-        (PIN_NUM(num) | PIN_##alt | PIN_INPUT_##pull))
-
-#define PIN_CFG_OUTPUT(num, alt, val)          \
-       (PIN_CFG_DEFAULT |\
-        (PIN_NUM(num) | PIN_##alt | PIN_OUTPUT_##val))
-
-/*
- * "nmk_gpio" and "NMK_GPIO" stand for "Nomadik GPIO", leaving
- * the "gpio" namespace for generic and cross-machine functions
- */
-
-#define GPIO_BLOCK_SHIFT 5
-#define NMK_GPIO_PER_CHIP (1 << GPIO_BLOCK_SHIFT)
-
-/* Register in the logic block */
-#define NMK_GPIO_DAT   0x00
-#define NMK_GPIO_DATS  0x04
-#define NMK_GPIO_DATC  0x08
-#define NMK_GPIO_PDIS  0x0c
-#define NMK_GPIO_DIR   0x10
-#define NMK_GPIO_DIRS  0x14
-#define NMK_GPIO_DIRC  0x18
-#define NMK_GPIO_SLPC  0x1c
-#define NMK_GPIO_AFSLA 0x20
-#define NMK_GPIO_AFSLB 0x24
-#define NMK_GPIO_LOWEMI        0x28
-
-#define NMK_GPIO_RIMSC 0x40
-#define NMK_GPIO_FIMSC 0x44
-#define NMK_GPIO_IS    0x48
-#define NMK_GPIO_IC    0x4c
-#define NMK_GPIO_RWIMSC        0x50
-#define NMK_GPIO_FWIMSC        0x54
-#define NMK_GPIO_WKS   0x58
-/* These appear in DB8540 and later ASICs */
-#define NMK_GPIO_EDGELEVEL 0x5C
-#define NMK_GPIO_LEVEL 0x60
-
-
-/* Pull up/down values */
-enum nmk_gpio_pull {
-       NMK_GPIO_PULL_NONE,
-       NMK_GPIO_PULL_UP,
-       NMK_GPIO_PULL_DOWN,
-};
-
-/* Sleep mode */
-enum nmk_gpio_slpm {
-       NMK_GPIO_SLPM_INPUT,
-       NMK_GPIO_SLPM_WAKEUP_ENABLE = NMK_GPIO_SLPM_INPUT,
-       NMK_GPIO_SLPM_NOCHANGE,
-       NMK_GPIO_SLPM_WAKEUP_DISABLE = NMK_GPIO_SLPM_NOCHANGE,
-};
-
-struct nmk_gpio_chip {
-       struct gpio_chip chip;
-       void __iomem *addr;
-       struct clk *clk;
-       unsigned int bank;
-       unsigned int parent_irq;
-       int latent_parent_irq;
-       u32 (*get_latent_status)(unsigned int bank);
-       void (*set_ioforce)(bool enable);
-       spinlock_t lock;
-       bool sleepmode;
-       /* Keep track of configured edges */
-       u32 edge_rising;
-       u32 edge_falling;
-       u32 real_wake;
-       u32 rwimsc;
-       u32 fwimsc;
-       u32 rimsc;
-       u32 fimsc;
-       u32 pull_up;
-       u32 lowemi;
-};
-
-/**
- * struct nmk_pinctrl - state container for the Nomadik pin controller
- * @dev: containing device pointer
- * @pctl: corresponding pin controller device
- * @soc: SoC data for this specific chip
- * @prcm_base: PRCM register range virtual base
- */
-struct nmk_pinctrl {
-       struct device *dev;
-       struct pinctrl_dev *pctl;
-       const struct nmk_pinctrl_soc_data *soc;
-       void __iomem *prcm_base;
-};
-
-static struct nmk_gpio_chip *
-nmk_gpio_chips[DIV_ROUND_UP(ARCH_NR_GPIOS, NMK_GPIO_PER_CHIP)];
-
-static DEFINE_SPINLOCK(nmk_gpio_slpm_lock);
-
-#define NUM_BANKS ARRAY_SIZE(nmk_gpio_chips)
-
-static void __nmk_gpio_set_mode(struct nmk_gpio_chip *nmk_chip,
-                               unsigned offset, int gpio_mode)
-{
-       u32 bit = 1 << offset;
-       u32 afunc, bfunc;
-
-       afunc = readl(nmk_chip->addr + NMK_GPIO_AFSLA) & ~bit;
-       bfunc = readl(nmk_chip->addr + NMK_GPIO_AFSLB) & ~bit;
-       if (gpio_mode & NMK_GPIO_ALT_A)
-               afunc |= bit;
-       if (gpio_mode & NMK_GPIO_ALT_B)
-               bfunc |= bit;
-       writel(afunc, nmk_chip->addr + NMK_GPIO_AFSLA);
-       writel(bfunc, nmk_chip->addr + NMK_GPIO_AFSLB);
-}
-
-static void __nmk_gpio_set_slpm(struct nmk_gpio_chip *nmk_chip,
-                               unsigned offset, enum nmk_gpio_slpm mode)
-{
-       u32 bit = 1 << offset;
-       u32 slpm;
-
-       slpm = readl(nmk_chip->addr + NMK_GPIO_SLPC);
-       if (mode == NMK_GPIO_SLPM_NOCHANGE)
-               slpm |= bit;
-       else
-               slpm &= ~bit;
-       writel(slpm, nmk_chip->addr + NMK_GPIO_SLPC);
-}
-
-static void __nmk_gpio_set_pull(struct nmk_gpio_chip *nmk_chip,
-                               unsigned offset, enum nmk_gpio_pull pull)
-{
-       u32 bit = 1 << offset;
-       u32 pdis;
-
-       pdis = readl(nmk_chip->addr + NMK_GPIO_PDIS);
-       if (pull == NMK_GPIO_PULL_NONE) {
-               pdis |= bit;
-               nmk_chip->pull_up &= ~bit;
-       } else {
-               pdis &= ~bit;
-       }
-
-       writel(pdis, nmk_chip->addr + NMK_GPIO_PDIS);
-
-       if (pull == NMK_GPIO_PULL_UP) {
-               nmk_chip->pull_up |= bit;
-               writel(bit, nmk_chip->addr + NMK_GPIO_DATS);
-       } else if (pull == NMK_GPIO_PULL_DOWN) {
-               nmk_chip->pull_up &= ~bit;
-               writel(bit, nmk_chip->addr + NMK_GPIO_DATC);
-       }
-}
-
-static void __nmk_gpio_set_lowemi(struct nmk_gpio_chip *nmk_chip,
-                                 unsigned offset, bool lowemi)
-{
-       u32 bit = BIT(offset);
-       bool enabled = nmk_chip->lowemi & bit;
-
-       if (lowemi == enabled)
-               return;
-
-       if (lowemi)
-               nmk_chip->lowemi |= bit;
-       else
-               nmk_chip->lowemi &= ~bit;
-
-       writel_relaxed(nmk_chip->lowemi,
-                      nmk_chip->addr + NMK_GPIO_LOWEMI);
-}
-
-static void __nmk_gpio_make_input(struct nmk_gpio_chip *nmk_chip,
-                                 unsigned offset)
-{
-       writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRC);
-}
-
-static void __nmk_gpio_set_output(struct nmk_gpio_chip *nmk_chip,
-                                 unsigned offset, int val)
-{
-       if (val)
-               writel(1 << offset, nmk_chip->addr + NMK_GPIO_DATS);
-       else
-               writel(1 << offset, nmk_chip->addr + NMK_GPIO_DATC);
-}
-
-static void __nmk_gpio_make_output(struct nmk_gpio_chip *nmk_chip,
-                                 unsigned offset, int val)
-{
-       writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRS);
-       __nmk_gpio_set_output(nmk_chip, offset, val);
-}
-
-static void __nmk_gpio_set_mode_safe(struct nmk_gpio_chip *nmk_chip,
-                                    unsigned offset, int gpio_mode,
-                                    bool glitch)
-{
-       u32 rwimsc = nmk_chip->rwimsc;
-       u32 fwimsc = nmk_chip->fwimsc;
-
-       if (glitch && nmk_chip->set_ioforce) {
-               u32 bit = BIT(offset);
-
-               /* Prevent spurious wakeups */
-               writel(rwimsc & ~bit, nmk_chip->addr + NMK_GPIO_RWIMSC);
-               writel(fwimsc & ~bit, nmk_chip->addr + NMK_GPIO_FWIMSC);
-
-               nmk_chip->set_ioforce(true);
-       }
-
-       __nmk_gpio_set_mode(nmk_chip, offset, gpio_mode);
-
-       if (glitch && nmk_chip->set_ioforce) {
-               nmk_chip->set_ioforce(false);
-
-               writel(rwimsc, nmk_chip->addr + NMK_GPIO_RWIMSC);
-               writel(fwimsc, nmk_chip->addr + NMK_GPIO_FWIMSC);
-       }
-}
-
-static void
-nmk_gpio_disable_lazy_irq(struct nmk_gpio_chip *nmk_chip, unsigned offset)
-{
-       u32 falling = nmk_chip->fimsc & BIT(offset);
-       u32 rising = nmk_chip->rimsc & BIT(offset);
-       int gpio = nmk_chip->chip.base + offset;
-       int irq = irq_find_mapping(nmk_chip->chip.irqdomain, offset);
-       struct irq_data *d = irq_get_irq_data(irq);
-
-       if (!rising && !falling)
-               return;
-
-       if (!d || !irqd_irq_disabled(d))
-               return;
-
-       if (rising) {
-               nmk_chip->rimsc &= ~BIT(offset);
-               writel_relaxed(nmk_chip->rimsc,
-                              nmk_chip->addr + NMK_GPIO_RIMSC);
-       }
-
-       if (falling) {
-               nmk_chip->fimsc &= ~BIT(offset);
-               writel_relaxed(nmk_chip->fimsc,
-                              nmk_chip->addr + NMK_GPIO_FIMSC);
-       }
-
-       dev_dbg(nmk_chip->chip.dev, "%d: clearing interrupt mask\n", gpio);
-}
-
-static void nmk_write_masked(void __iomem *reg, u32 mask, u32 value)
-{
-       u32 val;
-
-       val = readl(reg);
-       val = ((val & ~mask) | (value & mask));
-       writel(val, reg);
-}
-
-static void nmk_prcm_altcx_set_mode(struct nmk_pinctrl *npct,
-       unsigned offset, unsigned alt_num)
-{
-       int i;
-       u16 reg;
-       u8 bit;
-       u8 alt_index;
-       const struct prcm_gpiocr_altcx_pin_desc *pin_desc;
-       const u16 *gpiocr_regs;
-
-       if (!npct->prcm_base)
-               return;
-
-       if (alt_num > PRCM_IDX_GPIOCR_ALTC_MAX) {
-               dev_err(npct->dev, "PRCM GPIOCR: alternate-C%i is invalid\n",
-                       alt_num);
-               return;
-       }
-
-       for (i = 0 ; i < npct->soc->npins_altcx ; i++) {
-               if (npct->soc->altcx_pins[i].pin == offset)
-                       break;
-       }
-       if (i == npct->soc->npins_altcx) {
-               dev_dbg(npct->dev, "PRCM GPIOCR: pin %i is not found\n",
-                       offset);
-               return;
-       }
-
-       pin_desc = npct->soc->altcx_pins + i;
-       gpiocr_regs = npct->soc->prcm_gpiocr_registers;
-
-       /*
-        * If alt_num is NULL, just clear current ALTCx selection
-        * to make sure we come back to a pure ALTC selection
-        */
-       if (!alt_num) {
-               for (i = 0 ; i < PRCM_IDX_GPIOCR_ALTC_MAX ; i++) {
-                       if (pin_desc->altcx[i].used == true) {
-                               reg = gpiocr_regs[pin_desc->altcx[i].reg_index];
-                               bit = pin_desc->altcx[i].control_bit;
-                               if (readl(npct->prcm_base + reg) & BIT(bit)) {
-                                       nmk_write_masked(npct->prcm_base + reg, BIT(bit), 0);
-                                       dev_dbg(npct->dev,
-                                               "PRCM GPIOCR: pin %i: alternate-C%i has been disabled\n",
-                                               offset, i+1);
-                               }
-                       }
-               }
-               return;
-       }
-
-       alt_index = alt_num - 1;
-       if (pin_desc->altcx[alt_index].used == false) {
-               dev_warn(npct->dev,
-                       "PRCM GPIOCR: pin %i: alternate-C%i does not exist\n",
-                       offset, alt_num);
-               return;
-       }
-
-       /*
-        * Check if any other ALTCx functions are activated on this pin
-        * and disable it first.
-        */
-       for (i = 0 ; i < PRCM_IDX_GPIOCR_ALTC_MAX ; i++) {
-               if (i == alt_index)
-                       continue;
-               if (pin_desc->altcx[i].used == true) {
-                       reg = gpiocr_regs[pin_desc->altcx[i].reg_index];
-                       bit = pin_desc->altcx[i].control_bit;
-                       if (readl(npct->prcm_base + reg) & BIT(bit)) {
-                               nmk_write_masked(npct->prcm_base + reg, BIT(bit), 0);
-                               dev_dbg(npct->dev,
-                                       "PRCM GPIOCR: pin %i: alternate-C%i has been disabled\n",
-                                       offset, i+1);
-                       }
-               }
-       }
-
-       reg = gpiocr_regs[pin_desc->altcx[alt_index].reg_index];
-       bit = pin_desc->altcx[alt_index].control_bit;
-       dev_dbg(npct->dev, "PRCM GPIOCR: pin %i: alternate-C%i has been selected\n",
-               offset, alt_index+1);
-       nmk_write_masked(npct->prcm_base + reg, BIT(bit), BIT(bit));
-}
-
-/*
- * Safe sequence used to switch IOs between GPIO and Alternate-C mode:
- *  - Save SLPM registers
- *  - Set SLPM=0 for the IOs you want to switch and others to 1
- *  - Configure the GPIO registers for the IOs that are being switched
- *  - Set IOFORCE=1
- *  - Modify the AFLSA/B registers for the IOs that are being switched
- *  - Set IOFORCE=0
- *  - Restore SLPM registers
- *  - Any spurious wake up event during switch sequence to be ignored and
- *    cleared
- */
-static void nmk_gpio_glitch_slpm_init(unsigned int *slpm)
-{
-       int i;
-
-       for (i = 0; i < NUM_BANKS; i++) {
-               struct nmk_gpio_chip *chip = nmk_gpio_chips[i];
-               unsigned int temp = slpm[i];
-
-               if (!chip)
-                       break;
-
-               clk_enable(chip->clk);
-
-               slpm[i] = readl(chip->addr + NMK_GPIO_SLPC);
-               writel(temp, chip->addr + NMK_GPIO_SLPC);
-       }
-}
-
-static void nmk_gpio_glitch_slpm_restore(unsigned int *slpm)
-{
-       int i;
-
-       for (i = 0; i < NUM_BANKS; i++) {
-               struct nmk_gpio_chip *chip = nmk_gpio_chips[i];
-
-               if (!chip)
-                       break;
-
-               writel(slpm[i], chip->addr + NMK_GPIO_SLPC);
-
-               clk_disable(chip->clk);
-       }
-}
-
-static int __maybe_unused nmk_prcm_gpiocr_get_mode(struct pinctrl_dev *pctldev, int gpio)
-{
-       int i;
-       u16 reg;
-       u8 bit;
-       struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
-       const struct prcm_gpiocr_altcx_pin_desc *pin_desc;
-       const u16 *gpiocr_regs;
-
-       if (!npct->prcm_base)
-               return NMK_GPIO_ALT_C;
-
-       for (i = 0; i < npct->soc->npins_altcx; i++) {
-               if (npct->soc->altcx_pins[i].pin == gpio)
-                       break;
-       }
-       if (i == npct->soc->npins_altcx)
-               return NMK_GPIO_ALT_C;
-
-       pin_desc = npct->soc->altcx_pins + i;
-       gpiocr_regs = npct->soc->prcm_gpiocr_registers;
-       for (i = 0; i < PRCM_IDX_GPIOCR_ALTC_MAX; i++) {
-               if (pin_desc->altcx[i].used == true) {
-                       reg = gpiocr_regs[pin_desc->altcx[i].reg_index];
-                       bit = pin_desc->altcx[i].control_bit;
-                       if (readl(npct->prcm_base + reg) & BIT(bit))
-                               return NMK_GPIO_ALT_C+i+1;
-               }
-       }
-       return NMK_GPIO_ALT_C;
-}
-
-int nmk_gpio_get_mode(int gpio)
-{
-       struct nmk_gpio_chip *nmk_chip;
-       u32 afunc, bfunc, bit;
-
-       nmk_chip = nmk_gpio_chips[gpio / NMK_GPIO_PER_CHIP];
-       if (!nmk_chip)
-               return -EINVAL;
-
-       bit = 1 << (gpio % NMK_GPIO_PER_CHIP);
-
-       clk_enable(nmk_chip->clk);
-
-       afunc = readl(nmk_chip->addr + NMK_GPIO_AFSLA) & bit;
-       bfunc = readl(nmk_chip->addr + NMK_GPIO_AFSLB) & bit;
-
-       clk_disable(nmk_chip->clk);
-
-       return (afunc ? NMK_GPIO_ALT_A : 0) | (bfunc ? NMK_GPIO_ALT_B : 0);
-}
-EXPORT_SYMBOL(nmk_gpio_get_mode);
-
-
-/* IRQ functions */
-static inline int nmk_gpio_get_bitmask(int gpio)
-{
-       return 1 << (gpio % NMK_GPIO_PER_CHIP);
-}
-
-static void nmk_gpio_irq_ack(struct irq_data *d)
-{
-       struct gpio_chip *chip = irq_data_get_irq_chip_data(d);
-       struct nmk_gpio_chip *nmk_chip = container_of(chip, struct nmk_gpio_chip, chip);
-
-       clk_enable(nmk_chip->clk);
-       writel(nmk_gpio_get_bitmask(d->hwirq), nmk_chip->addr + NMK_GPIO_IC);
-       clk_disable(nmk_chip->clk);
-}
-
-enum nmk_gpio_irq_type {
-       NORMAL,
-       WAKE,
-};
-
-static void __nmk_gpio_irq_modify(struct nmk_gpio_chip *nmk_chip,
-                                 int gpio, enum nmk_gpio_irq_type which,
-                                 bool enable)
-{
-       u32 bitmask = nmk_gpio_get_bitmask(gpio);
-       u32 *rimscval;
-       u32 *fimscval;
-       u32 rimscreg;
-       u32 fimscreg;
-
-       if (which == NORMAL) {
-               rimscreg = NMK_GPIO_RIMSC;
-               fimscreg = NMK_GPIO_FIMSC;
-               rimscval = &nmk_chip->rimsc;
-               fimscval = &nmk_chip->fimsc;
-       } else  {
-               rimscreg = NMK_GPIO_RWIMSC;
-               fimscreg = NMK_GPIO_FWIMSC;
-               rimscval = &nmk_chip->rwimsc;
-               fimscval = &nmk_chip->fwimsc;
-       }
-
-       /* we must individually set/clear the two edges */
-       if (nmk_chip->edge_rising & bitmask) {
-               if (enable)
-                       *rimscval |= bitmask;
-               else
-                       *rimscval &= ~bitmask;
-               writel(*rimscval, nmk_chip->addr + rimscreg);
-       }
-       if (nmk_chip->edge_falling & bitmask) {
-               if (enable)
-                       *fimscval |= bitmask;
-               else
-                       *fimscval &= ~bitmask;
-               writel(*fimscval, nmk_chip->addr + fimscreg);
-       }
-}
-
-static void __nmk_gpio_set_wake(struct nmk_gpio_chip *nmk_chip,
-                               int gpio, bool on)
-{
-       /*
-        * Ensure WAKEUP_ENABLE is on.  No need to disable it if wakeup is
-        * disabled, since setting SLPM to 1 increases power consumption, and
-        * wakeup is anyhow controlled by the RIMSC and FIMSC registers.
-        */
-       if (nmk_chip->sleepmode && on) {
-               __nmk_gpio_set_slpm(nmk_chip, gpio % NMK_GPIO_PER_CHIP,
-                                   NMK_GPIO_SLPM_WAKEUP_ENABLE);
-       }
-
-       __nmk_gpio_irq_modify(nmk_chip, gpio, WAKE, on);
-}
-
-static int nmk_gpio_irq_maskunmask(struct irq_data *d, bool enable)
-{
-       struct nmk_gpio_chip *nmk_chip;
-       unsigned long flags;
-       u32 bitmask;
-
-       nmk_chip = irq_data_get_irq_chip_data(d);
-       bitmask = nmk_gpio_get_bitmask(d->hwirq);
-       if (!nmk_chip)
-               return -EINVAL;
-
-       clk_enable(nmk_chip->clk);
-       spin_lock_irqsave(&nmk_gpio_slpm_lock, flags);
-       spin_lock(&nmk_chip->lock);
-
-       __nmk_gpio_irq_modify(nmk_chip, d->hwirq, NORMAL, enable);
-
-       if (!(nmk_chip->real_wake & bitmask))
-               __nmk_gpio_set_wake(nmk_chip, d->hwirq, enable);
-
-       spin_unlock(&nmk_chip->lock);
-       spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags);
-       clk_disable(nmk_chip->clk);
-
-       return 0;
-}
-
-static void nmk_gpio_irq_mask(struct irq_data *d)
-{
-       nmk_gpio_irq_maskunmask(d, false);
-}
-
-static void nmk_gpio_irq_unmask(struct irq_data *d)
-{
-       nmk_gpio_irq_maskunmask(d, true);
-}
-
-static int nmk_gpio_irq_set_wake(struct irq_data *d, unsigned int on)
-{
-       struct nmk_gpio_chip *nmk_chip;
-       unsigned long flags;
-       u32 bitmask;
-
-       nmk_chip = irq_data_get_irq_chip_data(d);
-       if (!nmk_chip)
-               return -EINVAL;
-       bitmask = nmk_gpio_get_bitmask(d->hwirq);
-
-       clk_enable(nmk_chip->clk);
-       spin_lock_irqsave(&nmk_gpio_slpm_lock, flags);
-       spin_lock(&nmk_chip->lock);
-
-       if (irqd_irq_disabled(d))
-               __nmk_gpio_set_wake(nmk_chip, d->hwirq, on);
-
-       if (on)
-               nmk_chip->real_wake |= bitmask;
-       else
-               nmk_chip->real_wake &= ~bitmask;
-
-       spin_unlock(&nmk_chip->lock);
-       spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags);
-       clk_disable(nmk_chip->clk);
-
-       return 0;
-}
-
-static int nmk_gpio_irq_set_type(struct irq_data *d, unsigned int type)
-{
-       bool enabled = !irqd_irq_disabled(d);
-       bool wake = irqd_is_wakeup_set(d);
-       struct nmk_gpio_chip *nmk_chip;
-       unsigned long flags;
-       u32 bitmask;
-
-       nmk_chip = irq_data_get_irq_chip_data(d);
-       bitmask = nmk_gpio_get_bitmask(d->hwirq);
-       if (!nmk_chip)
-               return -EINVAL;
-       if (type & IRQ_TYPE_LEVEL_HIGH)
-               return -EINVAL;
-       if (type & IRQ_TYPE_LEVEL_LOW)
-               return -EINVAL;
-
-       clk_enable(nmk_chip->clk);
-       spin_lock_irqsave(&nmk_chip->lock, flags);
-
-       if (enabled)
-               __nmk_gpio_irq_modify(nmk_chip, d->hwirq, NORMAL, false);
-
-       if (enabled || wake)
-               __nmk_gpio_irq_modify(nmk_chip, d->hwirq, WAKE, false);
-
-       nmk_chip->edge_rising &= ~bitmask;
-       if (type & IRQ_TYPE_EDGE_RISING)
-               nmk_chip->edge_rising |= bitmask;
-
-       nmk_chip->edge_falling &= ~bitmask;
-       if (type & IRQ_TYPE_EDGE_FALLING)
-               nmk_chip->edge_falling |= bitmask;
-
-       if (enabled)
-               __nmk_gpio_irq_modify(nmk_chip, d->hwirq, NORMAL, true);
-
-       if (enabled || wake)
-               __nmk_gpio_irq_modify(nmk_chip, d->hwirq, WAKE, true);
-
-       spin_unlock_irqrestore(&nmk_chip->lock, flags);
-       clk_disable(nmk_chip->clk);
-
-       return 0;
-}
-
-static unsigned int nmk_gpio_irq_startup(struct irq_data *d)
-{
-       struct nmk_gpio_chip *nmk_chip = irq_data_get_irq_chip_data(d);
-
-       clk_enable(nmk_chip->clk);
-       nmk_gpio_irq_unmask(d);
-       return 0;
-}
-
-static void nmk_gpio_irq_shutdown(struct irq_data *d)
-{
-       struct nmk_gpio_chip *nmk_chip = irq_data_get_irq_chip_data(d);
-
-       nmk_gpio_irq_mask(d);
-       clk_disable(nmk_chip->clk);
-}
-
-static struct irq_chip nmk_gpio_irq_chip = {
-       .name           = "Nomadik-GPIO",
-       .irq_ack        = nmk_gpio_irq_ack,
-       .irq_mask       = nmk_gpio_irq_mask,
-       .irq_unmask     = nmk_gpio_irq_unmask,
-       .irq_set_type   = nmk_gpio_irq_set_type,
-       .irq_set_wake   = nmk_gpio_irq_set_wake,
-       .irq_startup    = nmk_gpio_irq_startup,
-       .irq_shutdown   = nmk_gpio_irq_shutdown,
-       .flags          = IRQCHIP_MASK_ON_SUSPEND,
-};
-
-static void __nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc,
-                                  u32 status)
-{
-       struct irq_chip *host_chip = irq_get_chip(irq);
-       struct gpio_chip *chip = irq_desc_get_handler_data(desc);
-
-       chained_irq_enter(host_chip, desc);
-
-       while (status) {
-               int bit = __ffs(status);
-
-               generic_handle_irq(irq_find_mapping(chip->irqdomain, bit));
-               status &= ~BIT(bit);
-       }
-
-       chained_irq_exit(host_chip, desc);
-}
-
-static void nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
-{
-       struct gpio_chip *chip = irq_desc_get_handler_data(desc);
-       struct nmk_gpio_chip *nmk_chip = container_of(chip, struct nmk_gpio_chip, chip);
-       u32 status;
-
-       clk_enable(nmk_chip->clk);
-       status = readl(nmk_chip->addr + NMK_GPIO_IS);
-       clk_disable(nmk_chip->clk);
-
-       __nmk_gpio_irq_handler(irq, desc, status);
-}
-
-static void nmk_gpio_latent_irq_handler(unsigned int irq,
-                                          struct irq_desc *desc)
-{
-       struct gpio_chip *chip = irq_desc_get_handler_data(desc);
-       struct nmk_gpio_chip *nmk_chip = container_of(chip, struct nmk_gpio_chip, chip);
-       u32 status = nmk_chip->get_latent_status(nmk_chip->bank);
-
-       __nmk_gpio_irq_handler(irq, desc, status);
-}
-
-/* I/O Functions */
-
-static int nmk_gpio_request(struct gpio_chip *chip, unsigned offset)
-{
-       /*
-        * Map back to global GPIO space and request muxing, the direction
-        * parameter does not matter for this controller.
-        */
-       int gpio = chip->base + offset;
-
-       return pinctrl_request_gpio(gpio);
-}
-
-static void nmk_gpio_free(struct gpio_chip *chip, unsigned offset)
-{
-       int gpio = chip->base + offset;
-
-       pinctrl_free_gpio(gpio);
-}
-
-static int nmk_gpio_make_input(struct gpio_chip *chip, unsigned offset)
-{
-       struct nmk_gpio_chip *nmk_chip =
-               container_of(chip, struct nmk_gpio_chip, chip);
-
-       clk_enable(nmk_chip->clk);
-
-       writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRC);
-
-       clk_disable(nmk_chip->clk);
-
-       return 0;
-}
-
-static int nmk_gpio_get_input(struct gpio_chip *chip, unsigned offset)
-{
-       struct nmk_gpio_chip *nmk_chip =
-               container_of(chip, struct nmk_gpio_chip, chip);
-       u32 bit = 1 << offset;
-       int value;
-
-       clk_enable(nmk_chip->clk);
-
-       value = (readl(nmk_chip->addr + NMK_GPIO_DAT) & bit) != 0;
-
-       clk_disable(nmk_chip->clk);
-
-       return value;
-}
-
-static void nmk_gpio_set_output(struct gpio_chip *chip, unsigned offset,
-                               int val)
-{
-       struct nmk_gpio_chip *nmk_chip =
-               container_of(chip, struct nmk_gpio_chip, chip);
-
-       clk_enable(nmk_chip->clk);
-
-       __nmk_gpio_set_output(nmk_chip, offset, val);
-
-       clk_disable(nmk_chip->clk);
-}
-
-static int nmk_gpio_make_output(struct gpio_chip *chip, unsigned offset,
-                               int val)
-{
-       struct nmk_gpio_chip *nmk_chip =
-               container_of(chip, struct nmk_gpio_chip, chip);
-
-       clk_enable(nmk_chip->clk);
-
-       __nmk_gpio_make_output(nmk_chip, offset, val);
-
-       clk_disable(nmk_chip->clk);
-
-       return 0;
-}
-
-#ifdef CONFIG_DEBUG_FS
-
-#include <linux/seq_file.h>
-
-static void nmk_gpio_dbg_show_one(struct seq_file *s,
-       struct pinctrl_dev *pctldev, struct gpio_chip *chip,
-       unsigned offset, unsigned gpio)
-{
-       const char *label = gpiochip_is_requested(chip, offset);
-       struct nmk_gpio_chip *nmk_chip =
-               container_of(chip, struct nmk_gpio_chip, chip);
-       int mode;
-       bool is_out;
-       bool pull;
-       u32 bit = 1 << offset;
-       const char *modes[] = {
-               [NMK_GPIO_ALT_GPIO]     = "gpio",
-               [NMK_GPIO_ALT_A]        = "altA",
-               [NMK_GPIO_ALT_B]        = "altB",
-               [NMK_GPIO_ALT_C]        = "altC",
-               [NMK_GPIO_ALT_C+1]      = "altC1",
-               [NMK_GPIO_ALT_C+2]      = "altC2",
-               [NMK_GPIO_ALT_C+3]      = "altC3",
-               [NMK_GPIO_ALT_C+4]      = "altC4",
-       };
-
-       clk_enable(nmk_chip->clk);
-       is_out = !!(readl(nmk_chip->addr + NMK_GPIO_DIR) & bit);
-       pull = !(readl(nmk_chip->addr + NMK_GPIO_PDIS) & bit);
-       mode = nmk_gpio_get_mode(gpio);
-       if ((mode == NMK_GPIO_ALT_C) && pctldev)
-               mode = nmk_prcm_gpiocr_get_mode(pctldev, gpio);
-
-       seq_printf(s, " gpio-%-3d (%-20.20s) %s %s %s %s",
-                  gpio, label ?: "(none)",
-                  is_out ? "out" : "in ",
-                  chip->get
-                  ? (chip->get(chip, offset) ? "hi" : "lo")
-                  : "?  ",
-                  (mode < 0) ? "unknown" : modes[mode],
-                  pull ? "pull" : "none");
-
-       if (!is_out) {
-               int irq = gpio_to_irq(gpio);
-               struct irq_desc *desc = irq_to_desc(irq);
-
-               /* This races with request_irq(), set_irq_type(),
-                * and set_irq_wake() ... but those are "rare".
-                */
-               if (irq > 0 && desc && desc->action) {
-                       char *trigger;
-                       u32 bitmask = nmk_gpio_get_bitmask(gpio);
-
-                       if (nmk_chip->edge_rising & bitmask)
-                               trigger = "edge-rising";
-                       else if (nmk_chip->edge_falling & bitmask)
-                               trigger = "edge-falling";
-                       else
-                               trigger = "edge-undefined";
-
-                       seq_printf(s, " irq-%d %s%s",
-                                  irq, trigger,
-                                  irqd_is_wakeup_set(&desc->irq_data)
-                                  ? " wakeup" : "");
-               }
-       }
-       clk_disable(nmk_chip->clk);
-}
-
-static void nmk_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
-{
-       unsigned                i;
-       unsigned                gpio = chip->base;
-
-       for (i = 0; i < chip->ngpio; i++, gpio++) {
-               nmk_gpio_dbg_show_one(s, NULL, chip, i, gpio);
-               seq_printf(s, "\n");
-       }
-}
-
-#else
-static inline void nmk_gpio_dbg_show_one(struct seq_file *s,
-                                        struct pinctrl_dev *pctldev,
-                                        struct gpio_chip *chip,
-                                        unsigned offset, unsigned gpio)
-{
-}
-#define nmk_gpio_dbg_show      NULL
-#endif
-
-/* This structure is replicated for each GPIO block allocated at probe time */
-static struct gpio_chip nmk_gpio_template = {
-       .request                = nmk_gpio_request,
-       .free                   = nmk_gpio_free,
-       .direction_input        = nmk_gpio_make_input,
-       .get                    = nmk_gpio_get_input,
-       .direction_output       = nmk_gpio_make_output,
-       .set                    = nmk_gpio_set_output,
-       .dbg_show               = nmk_gpio_dbg_show,
-       .can_sleep              = false,
-};
-
-void nmk_gpio_clocks_enable(void)
-{
-       int i;
-
-       for (i = 0; i < NUM_BANKS; i++) {
-               struct nmk_gpio_chip *chip = nmk_gpio_chips[i];
-
-               if (!chip)
-                       continue;
-
-               clk_enable(chip->clk);
-       }
-}
-
-void nmk_gpio_clocks_disable(void)
-{
-       int i;
-
-       for (i = 0; i < NUM_BANKS; i++) {
-               struct nmk_gpio_chip *chip = nmk_gpio_chips[i];
-
-               if (!chip)
-                       continue;
-
-               clk_disable(chip->clk);
-       }
-}
-
-/*
- * Called from the suspend/resume path to only keep the real wakeup interrupts
- * (those that have had set_irq_wake() called on them) as wakeup interrupts,
- * and not the rest of the interrupts which we needed to have as wakeups for
- * cpuidle.
- *
- * PM ops are not used since this needs to be done at the end, after all the
- * other drivers are done with their suspend callbacks.
- */
-void nmk_gpio_wakeups_suspend(void)
-{
-       int i;
-
-       for (i = 0; i < NUM_BANKS; i++) {
-               struct nmk_gpio_chip *chip = nmk_gpio_chips[i];
-
-               if (!chip)
-                       break;
-
-               clk_enable(chip->clk);
-
-               writel(chip->rwimsc & chip->real_wake,
-                      chip->addr + NMK_GPIO_RWIMSC);
-               writel(chip->fwimsc & chip->real_wake,
-                      chip->addr + NMK_GPIO_FWIMSC);
-
-               clk_disable(chip->clk);
-       }
-}
-
-void nmk_gpio_wakeups_resume(void)
-{
-       int i;
-
-       for (i = 0; i < NUM_BANKS; i++) {
-               struct nmk_gpio_chip *chip = nmk_gpio_chips[i];
-
-               if (!chip)
-                       break;
-
-               clk_enable(chip->clk);
-
-               writel(chip->rwimsc, chip->addr + NMK_GPIO_RWIMSC);
-               writel(chip->fwimsc, chip->addr + NMK_GPIO_FWIMSC);
-
-               clk_disable(chip->clk);
-       }
-}
-
-/*
- * Read the pull up/pull down status.
- * A bit set in 'pull_up' means that pull up
- * is selected if pull is enabled in PDIS register.
- * Note: only pull up/down set via this driver can
- * be detected due to HW limitations.
- */
-void nmk_gpio_read_pull(int gpio_bank, u32 *pull_up)
-{
-       if (gpio_bank < NUM_BANKS) {
-               struct nmk_gpio_chip *chip = nmk_gpio_chips[gpio_bank];
-
-               if (!chip)
-                       return;
-
-               *pull_up = chip->pull_up;
-       }
-}
-
-static int nmk_gpio_probe(struct platform_device *dev)
-{
-       struct device_node *np = dev->dev.of_node;
-       struct nmk_gpio_chip *nmk_chip;
-       struct gpio_chip *chip;
-       struct resource *res;
-       struct clk *clk;
-       int latent_irq;
-       bool supports_sleepmode;
-       void __iomem *base;
-       int irq;
-       int ret;
-
-       if (of_get_property(np, "st,supports-sleepmode", NULL))
-               supports_sleepmode = true;
-       else
-               supports_sleepmode = false;
-
-       if (of_property_read_u32(np, "gpio-bank", &dev->id)) {
-               dev_err(&dev->dev, "gpio-bank property not found\n");
-               return -EINVAL;
-       }
-
-       irq = platform_get_irq(dev, 0);
-       if (irq < 0)
-               return irq;
-
-       /* It's OK for this IRQ not to be present */
-       latent_irq = platform_get_irq(dev, 1);
-
-       res = platform_get_resource(dev, IORESOURCE_MEM, 0);
-       base = devm_ioremap_resource(&dev->dev, res);
-       if (IS_ERR(base))
-               return PTR_ERR(base);
-
-       clk = devm_clk_get(&dev->dev, NULL);
-       if (IS_ERR(clk))
-               return PTR_ERR(clk);
-       clk_prepare(clk);
-
-       nmk_chip = devm_kzalloc(&dev->dev, sizeof(*nmk_chip), GFP_KERNEL);
-       if (!nmk_chip)
-               return -ENOMEM;
-
-       /*
-        * The virt address in nmk_chip->addr is in the nomadik register space,
-        * so we can simply convert the resource address, without remapping
-        */
-       nmk_chip->bank = dev->id;
-       nmk_chip->clk = clk;
-       nmk_chip->addr = base;
-       nmk_chip->chip = nmk_gpio_template;
-       nmk_chip->parent_irq = irq;
-       nmk_chip->latent_parent_irq = latent_irq;
-       nmk_chip->sleepmode = supports_sleepmode;
-       spin_lock_init(&nmk_chip->lock);
-
-       chip = &nmk_chip->chip;
-       chip->base = dev->id * NMK_GPIO_PER_CHIP;
-       chip->ngpio = NMK_GPIO_PER_CHIP;
-       chip->label = dev_name(&dev->dev);
-       chip->dev = &dev->dev;
-       chip->owner = THIS_MODULE;
-
-       clk_enable(nmk_chip->clk);
-       nmk_chip->lowemi = readl_relaxed(nmk_chip->addr + NMK_GPIO_LOWEMI);
-       clk_disable(nmk_chip->clk);
-       chip->of_node = np;
-
-       ret = gpiochip_add(&nmk_chip->chip);
-       if (ret)
-               return ret;
-
-       BUG_ON(nmk_chip->bank >= ARRAY_SIZE(nmk_gpio_chips));
-
-       nmk_gpio_chips[nmk_chip->bank] = nmk_chip;
-
-       platform_set_drvdata(dev, nmk_chip);
-
-       /*
-        * Let the generic code handle this edge IRQ, the the chained
-        * handler will perform the actual work of handling the parent
-        * interrupt.
-        */
-       ret = gpiochip_irqchip_add(&nmk_chip->chip,
-                                  &nmk_gpio_irq_chip,
-                                  0,
-                                  handle_edge_irq,
-                                  IRQ_TYPE_EDGE_FALLING);
-       if (ret) {
-               dev_err(&dev->dev, "could not add irqchip\n");
-               ret = gpiochip_remove(&nmk_chip->chip);
-               return -ENODEV;
-       }
-       /* Then register the chain on the parent IRQ */
-       gpiochip_set_chained_irqchip(&nmk_chip->chip,
-                                    &nmk_gpio_irq_chip,
-                                    nmk_chip->parent_irq,
-                                    nmk_gpio_irq_handler);
-       if (nmk_chip->latent_parent_irq > 0)
-               gpiochip_set_chained_irqchip(&nmk_chip->chip,
-                                            &nmk_gpio_irq_chip,
-                                            nmk_chip->latent_parent_irq,
-                                            nmk_gpio_latent_irq_handler);
-
-       dev_info(&dev->dev, "at address %p\n", nmk_chip->addr);
-
-       return 0;
-}
-
-static int nmk_get_groups_cnt(struct pinctrl_dev *pctldev)
-{
-       struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
-
-       return npct->soc->ngroups;
-}
-
-static const char *nmk_get_group_name(struct pinctrl_dev *pctldev,
-                                      unsigned selector)
-{
-       struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
-
-       return npct->soc->groups[selector].name;
-}
-
-static int nmk_get_group_pins(struct pinctrl_dev *pctldev, unsigned selector,
-                             const unsigned **pins,
-                             unsigned *num_pins)
-{
-       struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
-
-       *pins = npct->soc->groups[selector].pins;
-       *num_pins = npct->soc->groups[selector].npins;
-       return 0;
-}
-
-static struct pinctrl_gpio_range *
-nmk_match_gpio_range(struct pinctrl_dev *pctldev, unsigned offset)
-{
-       struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
-       int i;
-
-       for (i = 0; i < npct->soc->gpio_num_ranges; i++) {
-               struct pinctrl_gpio_range *range;
-
-               range = &npct->soc->gpio_ranges[i];
-               if (offset >= range->pin_base &&
-                   offset <= (range->pin_base + range->npins - 1))
-                       return range;
-       }
-       return NULL;
-}
-
-static void nmk_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
-                  unsigned offset)
-{
-       struct pinctrl_gpio_range *range;
-       struct gpio_chip *chip;
-
-       range = nmk_match_gpio_range(pctldev, offset);
-       if (!range || !range->gc) {
-               seq_printf(s, "invalid pin offset");
-               return;
-       }
-       chip = range->gc;
-       nmk_gpio_dbg_show_one(s, pctldev, chip, offset - chip->base, offset);
-}
-
-static void nmk_pinctrl_dt_free_map(struct pinctrl_dev *pctldev,
-               struct pinctrl_map *map, unsigned num_maps)
-{
-       int i;
-
-       for (i = 0; i < num_maps; i++)
-               if (map[i].type == PIN_MAP_TYPE_CONFIGS_PIN)
-                       kfree(map[i].data.configs.configs);
-       kfree(map);
-}
-
-static int nmk_dt_reserve_map(struct pinctrl_map **map, unsigned *reserved_maps,
-               unsigned *num_maps, unsigned reserve)
-{
-       unsigned old_num = *reserved_maps;
-       unsigned new_num = *num_maps + reserve;
-       struct pinctrl_map *new_map;
-
-       if (old_num >= new_num)
-               return 0;
-
-       new_map = krealloc(*map, sizeof(*new_map) * new_num, GFP_KERNEL);
-       if (!new_map)
-               return -ENOMEM;
-
-       memset(new_map + old_num, 0, (new_num - old_num) * sizeof(*new_map));
-
-       *map = new_map;
-       *reserved_maps = new_num;
-
-       return 0;
-}
-
-static int nmk_dt_add_map_mux(struct pinctrl_map **map, unsigned *reserved_maps,
-               unsigned *num_maps, const char *group,
-               const char *function)
-{
-       if (*num_maps == *reserved_maps)
-               return -ENOSPC;
-
-       (*map)[*num_maps].type = PIN_MAP_TYPE_MUX_GROUP;
-       (*map)[*num_maps].data.mux.group = group;
-       (*map)[*num_maps].data.mux.function = function;
-       (*num_maps)++;
-
-       return 0;
-}
-
-static int nmk_dt_add_map_configs(struct pinctrl_map **map,
-               unsigned *reserved_maps,
-               unsigned *num_maps, const char *group,
-               unsigned long *configs, unsigned num_configs)
-{
-       unsigned long *dup_configs;
-
-       if (*num_maps == *reserved_maps)
-               return -ENOSPC;
-
-       dup_configs = kmemdup(configs, num_configs * sizeof(*dup_configs),
-                             GFP_KERNEL);
-       if (!dup_configs)
-               return -ENOMEM;
-
-       (*map)[*num_maps].type = PIN_MAP_TYPE_CONFIGS_PIN;
-
-       (*map)[*num_maps].data.configs.group_or_pin = group;
-       (*map)[*num_maps].data.configs.configs = dup_configs;
-       (*map)[*num_maps].data.configs.num_configs = num_configs;
-       (*num_maps)++;
-
-       return 0;
-}
-
-#define NMK_CONFIG_PIN(x, y) { .property = x, .config = y, }
-#define NMK_CONFIG_PIN_ARRAY(x, y) { .property = x, .choice = y, \
-       .size = ARRAY_SIZE(y), }
-
-static const unsigned long nmk_pin_input_modes[] = {
-       PIN_INPUT_NOPULL,
-       PIN_INPUT_PULLUP,
-       PIN_INPUT_PULLDOWN,
-};
-
-static const unsigned long nmk_pin_output_modes[] = {
-       PIN_OUTPUT_LOW,
-       PIN_OUTPUT_HIGH,
-       PIN_DIR_OUTPUT,
-};
-
-static const unsigned long nmk_pin_sleep_modes[] = {
-       PIN_SLEEPMODE_DISABLED,
-       PIN_SLEEPMODE_ENABLED,
-};
-
-static const unsigned long nmk_pin_sleep_input_modes[] = {
-       PIN_SLPM_INPUT_NOPULL,
-       PIN_SLPM_INPUT_PULLUP,
-       PIN_SLPM_INPUT_PULLDOWN,
-       PIN_SLPM_DIR_INPUT,
-};
-
-static const unsigned long nmk_pin_sleep_output_modes[] = {
-       PIN_SLPM_OUTPUT_LOW,
-       PIN_SLPM_OUTPUT_HIGH,
-       PIN_SLPM_DIR_OUTPUT,
-};
-
-static const unsigned long nmk_pin_sleep_wakeup_modes[] = {
-       PIN_SLPM_WAKEUP_DISABLE,
-       PIN_SLPM_WAKEUP_ENABLE,
-};
-
-static const unsigned long nmk_pin_gpio_modes[] = {
-       PIN_GPIOMODE_DISABLED,
-       PIN_GPIOMODE_ENABLED,
-};
-
-static const unsigned long nmk_pin_sleep_pdis_modes[] = {
-       PIN_SLPM_PDIS_DISABLED,
-       PIN_SLPM_PDIS_ENABLED,
-};
-
-struct nmk_cfg_param {
-       const char *property;
-       unsigned long config;
-       const unsigned long *choice;
-       int size;
-};
-
-static const struct nmk_cfg_param nmk_cfg_params[] = {
-       NMK_CONFIG_PIN_ARRAY("ste,input",               nmk_pin_input_modes),
-       NMK_CONFIG_PIN_ARRAY("ste,output",              nmk_pin_output_modes),
-       NMK_CONFIG_PIN_ARRAY("ste,sleep",               nmk_pin_sleep_modes),
-       NMK_CONFIG_PIN_ARRAY("ste,sleep-input",         nmk_pin_sleep_input_modes),
-       NMK_CONFIG_PIN_ARRAY("ste,sleep-output",        nmk_pin_sleep_output_modes),
-       NMK_CONFIG_PIN_ARRAY("ste,sleep-wakeup",        nmk_pin_sleep_wakeup_modes),
-       NMK_CONFIG_PIN_ARRAY("ste,gpio",                nmk_pin_gpio_modes),
-       NMK_CONFIG_PIN_ARRAY("ste,sleep-pull-disable",  nmk_pin_sleep_pdis_modes),
-};
-
-static int nmk_dt_pin_config(int index, int val, unsigned long *config)
-{
-       int ret = 0;
-
-       if (nmk_cfg_params[index].choice == NULL)
-               *config = nmk_cfg_params[index].config;
-       else {
-               /* test if out of range */
-               if  (val < nmk_cfg_params[index].size) {
-                       *config = nmk_cfg_params[index].config |
-                               nmk_cfg_params[index].choice[val];
-               }
-       }
-       return ret;
-}
-
-static const char *nmk_find_pin_name(struct pinctrl_dev *pctldev, const char *pin_name)
-{
-       int i, pin_number;
-       struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
-
-       if (sscanf((char *)pin_name, "GPIO%d", &pin_number) == 1)
-               for (i = 0; i < npct->soc->npins; i++)
-                       if (npct->soc->pins[i].number == pin_number)
-                               return npct->soc->pins[i].name;
-       return NULL;
-}
-
-static bool nmk_pinctrl_dt_get_config(struct device_node *np,
-               unsigned long *configs)
-{
-       bool has_config = 0;
-       unsigned long cfg = 0;
-       int i, val, ret;
-
-       for (i = 0; i < ARRAY_SIZE(nmk_cfg_params); i++) {
-               ret = of_property_read_u32(np,
-                               nmk_cfg_params[i].property, &val);
-               if (ret != -EINVAL) {
-                       if (nmk_dt_pin_config(i, val, &cfg) == 0) {
-                               *configs |= cfg;
-                               has_config = 1;
-                       }
-               }
-       }
-
-       return has_config;
-}
-
-static int nmk_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
-               struct device_node *np,
-               struct pinctrl_map **map,
-               unsigned *reserved_maps,
-               unsigned *num_maps)
-{
-       int ret;
-       const char *function = NULL;
-       unsigned long configs = 0;
-       bool has_config = 0;
-       unsigned reserve = 0;
-       struct property *prop;
-       const char *group, *gpio_name;
-       struct device_node *np_config;
-
-       ret = of_property_read_string(np, "ste,function", &function);
-       if (ret >= 0)
-               reserve = 1;
-
-       has_config = nmk_pinctrl_dt_get_config(np, &configs);
-
-       np_config = of_parse_phandle(np, "ste,config", 0);
-       if (np_config)
-               has_config |= nmk_pinctrl_dt_get_config(np_config, &configs);
-
-       ret = of_property_count_strings(np, "ste,pins");
-       if (ret < 0)
-               goto exit;
-
-       if (has_config)
-               reserve++;
-
-       reserve *= ret;
-
-       ret = nmk_dt_reserve_map(map, reserved_maps, num_maps, reserve);
-       if (ret < 0)
-               goto exit;
-
-       of_property_for_each_string(np, "ste,pins", prop, group) {
-               if (function) {
-                       ret = nmk_dt_add_map_mux(map, reserved_maps, num_maps,
-                                         group, function);
-                       if (ret < 0)
-                               goto exit;
-               }
-               if (has_config) {
-                       gpio_name = nmk_find_pin_name(pctldev, group);
-
-                       ret = nmk_dt_add_map_configs(map, reserved_maps, num_maps,
-                                             gpio_name, &configs, 1);
-                       if (ret < 0)
-                               goto exit;
-               }
-
-       }
-exit:
-       return ret;
-}
-
-static int nmk_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
-                                struct device_node *np_config,
-                                struct pinctrl_map **map, unsigned *num_maps)
-{
-       unsigned reserved_maps;
-       struct device_node *np;
-       int ret;
-
-       reserved_maps = 0;
-       *map = NULL;
-       *num_maps = 0;
-
-       for_each_child_of_node(np_config, np) {
-               ret = nmk_pinctrl_dt_subnode_to_map(pctldev, np, map,
-                               &reserved_maps, num_maps);
-               if (ret < 0) {
-                       nmk_pinctrl_dt_free_map(pctldev, *map, *num_maps);
-                       return ret;
-               }
-       }
-
-       return 0;
-}
-
-static const struct pinctrl_ops nmk_pinctrl_ops = {
-       .get_groups_count = nmk_get_groups_cnt,
-       .get_group_name = nmk_get_group_name,
-       .get_group_pins = nmk_get_group_pins,
-       .pin_dbg_show = nmk_pin_dbg_show,
-       .dt_node_to_map = nmk_pinctrl_dt_node_to_map,
-       .dt_free_map = nmk_pinctrl_dt_free_map,
-};
-
-static int nmk_pmx_get_funcs_cnt(struct pinctrl_dev *pctldev)
-{
-       struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
-
-       return npct->soc->nfunctions;
-}
-
-static const char *nmk_pmx_get_func_name(struct pinctrl_dev *pctldev,
-                                        unsigned function)
-{
-       struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
-
-       return npct->soc->functions[function].name;
-}
-
-static int nmk_pmx_get_func_groups(struct pinctrl_dev *pctldev,
-                                  unsigned function,
-                                  const char * const **groups,
-                                  unsigned * const num_groups)
-{
-       struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
-
-       *groups = npct->soc->functions[function].groups;
-       *num_groups = npct->soc->functions[function].ngroups;
-
-       return 0;
-}
-
-static int nmk_pmx_enable(struct pinctrl_dev *pctldev, unsigned function,
-                         unsigned group)
-{
-       struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
-       const struct nmk_pingroup *g;
-       static unsigned int slpm[NUM_BANKS];
-       unsigned long flags = 0;
-       bool glitch;
-       int ret = -EINVAL;
-       int i;
-
-       g = &npct->soc->groups[group];
-
-       if (g->altsetting < 0)
-               return -EINVAL;
-
-       dev_dbg(npct->dev, "enable group %s, %u pins\n", g->name, g->npins);
-
-       /*
-        * If we're setting altfunc C by setting both AFSLA and AFSLB to 1,
-        * we may pass through an undesired state. In this case we take
-        * some extra care.
-        *
-        * Safe sequence used to switch IOs between GPIO and Alternate-C mode:
-        *  - Save SLPM registers (since we have a shadow register in the
-        *    nmk_chip we're using that as backup)
-        *  - Set SLPM=0 for the IOs you want to switch and others to 1
-        *  - Configure the GPIO registers for the IOs that are being switched
-        *  - Set IOFORCE=1
-        *  - Modify the AFLSA/B registers for the IOs that are being switched
-        *  - Set IOFORCE=0
-        *  - Restore SLPM registers
-        *  - Any spurious wake up event during switch sequence to be ignored
-        *    and cleared
-        *
-        * We REALLY need to save ALL slpm registers, because the external
-        * IOFORCE will switch *all* ports to their sleepmode setting to as
-        * to avoid glitches. (Not just one port!)
-        */
-       glitch = ((g->altsetting & NMK_GPIO_ALT_C) == NMK_GPIO_ALT_C);
-
-       if (glitch) {
-               spin_lock_irqsave(&nmk_gpio_slpm_lock, flags);
-
-               /* Initially don't put any pins to sleep when switching */
-               memset(slpm, 0xff, sizeof(slpm));
-
-               /*
-                * Then mask the pins that need to be sleeping now when we're
-                * switching to the ALT C function.
-                */
-               for (i = 0; i < g->npins; i++)
-                       slpm[g->pins[i] / NMK_GPIO_PER_CHIP] &= ~BIT(g->pins[i]);
-               nmk_gpio_glitch_slpm_init(slpm);
-       }
-
-       for (i = 0; i < g->npins; i++) {
-               struct pinctrl_gpio_range *range;
-               struct nmk_gpio_chip *nmk_chip;
-               struct gpio_chip *chip;
-               unsigned bit;
-
-               range = nmk_match_gpio_range(pctldev, g->pins[i]);
-               if (!range) {
-                       dev_err(npct->dev,
-                               "invalid pin offset %d in group %s at index %d\n",
-                               g->pins[i], g->name, i);
-                       goto out_glitch;
-               }
-               if (!range->gc) {
-                       dev_err(npct->dev, "GPIO chip missing in range for pin offset %d in group %s at index %d\n",
-                               g->pins[i], g->name, i);
-                       goto out_glitch;
-               }
-               chip = range->gc;
-               nmk_chip = container_of(chip, struct nmk_gpio_chip, chip);
-               dev_dbg(npct->dev, "setting pin %d to altsetting %d\n", g->pins[i], g->altsetting);
-
-               clk_enable(nmk_chip->clk);
-               bit = g->pins[i] % NMK_GPIO_PER_CHIP;
-               /*
-                * If the pin is switching to altfunc, and there was an
-                * interrupt installed on it which has been lazy disabled,
-                * actually mask the interrupt to prevent spurious interrupts
-                * that would occur while the pin is under control of the
-                * peripheral. Only SKE does this.
-                */
-               nmk_gpio_disable_lazy_irq(nmk_chip, bit);
-
-               __nmk_gpio_set_mode_safe(nmk_chip, bit,
-                       (g->altsetting & NMK_GPIO_ALT_C), glitch);
-               clk_disable(nmk_chip->clk);
-
-               /*
-                * Call PRCM GPIOCR config function in case ALTC
-                * has been selected:
-                * - If selection is a ALTCx, some bits in PRCM GPIOCR registers
-                *   must be set.
-                * - If selection is pure ALTC and previous selection was ALTCx,
-                *   then some bits in PRCM GPIOCR registers must be cleared.
-                */
-               if ((g->altsetting & NMK_GPIO_ALT_C) == NMK_GPIO_ALT_C)
-                       nmk_prcm_altcx_set_mode(npct, g->pins[i],
-                               g->altsetting >> NMK_GPIO_ALT_CX_SHIFT);
-       }
-
-       /* When all pins are successfully reconfigured we get here */
-       ret = 0;
-
-out_glitch:
-       if (glitch) {
-               nmk_gpio_glitch_slpm_restore(slpm);
-               spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags);
-       }
-
-       return ret;
-}
-
-static void nmk_pmx_disable(struct pinctrl_dev *pctldev,
-                           unsigned function, unsigned group)
-{
-       struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
-       const struct nmk_pingroup *g;
-
-       g = &npct->soc->groups[group];
-
-       if (g->altsetting < 0)
-               return;
-
-       /* Poke out the mux, set the pin to some default state? */
-       dev_dbg(npct->dev, "disable group %s, %u pins\n", g->name, g->npins);
-}
-
-static int nmk_gpio_request_enable(struct pinctrl_dev *pctldev,
-                                  struct pinctrl_gpio_range *range,
-                                  unsigned offset)
-{
-       struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
-       struct nmk_gpio_chip *nmk_chip;
-       struct gpio_chip *chip;
-       unsigned bit;
-
-       if (!range) {
-               dev_err(npct->dev, "invalid range\n");
-               return -EINVAL;
-       }
-       if (!range->gc) {
-               dev_err(npct->dev, "missing GPIO chip in range\n");
-               return -EINVAL;
-       }
-       chip = range->gc;
-       nmk_chip = container_of(chip, struct nmk_gpio_chip, chip);
-
-       dev_dbg(npct->dev, "enable pin %u as GPIO\n", offset);
-
-       clk_enable(nmk_chip->clk);
-       bit = offset % NMK_GPIO_PER_CHIP;
-       /* There is no glitch when converting any pin to GPIO */
-       __nmk_gpio_set_mode(nmk_chip, bit, NMK_GPIO_ALT_GPIO);
-       clk_disable(nmk_chip->clk);
-
-       return 0;
-}
-
-static void nmk_gpio_disable_free(struct pinctrl_dev *pctldev,
-                                 struct pinctrl_gpio_range *range,
-                                 unsigned offset)
-{
-       struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
-
-       dev_dbg(npct->dev, "disable pin %u as GPIO\n", offset);
-       /* Set the pin to some default state, GPIO is usually default */
-}
-
-static const struct pinmux_ops nmk_pinmux_ops = {
-       .get_functions_count = nmk_pmx_get_funcs_cnt,
-       .get_function_name = nmk_pmx_get_func_name,
-       .get_function_groups = nmk_pmx_get_func_groups,
-       .enable = nmk_pmx_enable,
-       .disable = nmk_pmx_disable,
-       .gpio_request_enable = nmk_gpio_request_enable,
-       .gpio_disable_free = nmk_gpio_disable_free,
-};
-
-static int nmk_pin_config_get(struct pinctrl_dev *pctldev, unsigned pin,
-                             unsigned long *config)
-{
-       /* Not implemented */
-       return -EINVAL;
-}
-
-static int nmk_pin_config_set(struct pinctrl_dev *pctldev, unsigned pin,
-                             unsigned long *configs, unsigned num_configs)
-{
-       static const char *pullnames[] = {
-               [NMK_GPIO_PULL_NONE]    = "none",
-               [NMK_GPIO_PULL_UP]      = "up",
-               [NMK_GPIO_PULL_DOWN]    = "down",
-               [3] /* illegal */       = "??"
-       };
-       static const char *slpmnames[] = {
-               [NMK_GPIO_SLPM_INPUT]           = "input/wakeup",
-               [NMK_GPIO_SLPM_NOCHANGE]        = "no-change/no-wakeup",
-       };
-       struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
-       struct nmk_gpio_chip *nmk_chip;
-       struct pinctrl_gpio_range *range;
-       struct gpio_chip *chip;
-       unsigned bit;
-       pin_cfg_t cfg;
-       int pull, slpm, output, val, i;
-       bool lowemi, gpiomode, sleep;
-
-       range = nmk_match_gpio_range(pctldev, pin);
-       if (!range) {
-               dev_err(npct->dev, "invalid pin offset %d\n", pin);
-               return -EINVAL;
-       }
-       if (!range->gc) {
-               dev_err(npct->dev, "GPIO chip missing in range for pin %d\n",
-                       pin);
-               return -EINVAL;
-       }
-       chip = range->gc;
-       nmk_chip = container_of(chip, struct nmk_gpio_chip, chip);
-
-       for (i = 0; i < num_configs; i++) {
-               /*
-                * The pin config contains pin number and altfunction fields,
-                * here we just ignore that part. It's being handled by the
-                * framework and pinmux callback respectively.
-                */
-               cfg = (pin_cfg_t) configs[i];
-               pull = PIN_PULL(cfg);
-               slpm = PIN_SLPM(cfg);
-               output = PIN_DIR(cfg);
-               val = PIN_VAL(cfg);
-               lowemi = PIN_LOWEMI(cfg);
-               gpiomode = PIN_GPIOMODE(cfg);
-               sleep = PIN_SLEEPMODE(cfg);
-
-               if (sleep) {
-                       int slpm_pull = PIN_SLPM_PULL(cfg);
-                       int slpm_output = PIN_SLPM_DIR(cfg);
-                       int slpm_val = PIN_SLPM_VAL(cfg);
-
-                       /* All pins go into GPIO mode at sleep */
-                       gpiomode = true;
-
-                       /*
-                        * The SLPM_* values are normal values + 1 to allow zero
-                        * to mean "same as normal".
-                        */
-                       if (slpm_pull)
-                               pull = slpm_pull - 1;
-                       if (slpm_output)
-                               output = slpm_output - 1;
-                       if (slpm_val)
-                               val = slpm_val - 1;
-
-                       dev_dbg(nmk_chip->chip.dev,
-                               "pin %d: sleep pull %s, dir %s, val %s\n",
-                               pin,
-                               slpm_pull ? pullnames[pull] : "same",
-                               slpm_output ? (output ? "output" : "input")
-                               : "same",
-                               slpm_val ? (val ? "high" : "low") : "same");
-               }
-
-               dev_dbg(nmk_chip->chip.dev,
-                       "pin %d [%#lx]: pull %s, slpm %s (%s%s), lowemi %s\n",
-                       pin, cfg, pullnames[pull], slpmnames[slpm],
-                       output ? "output " : "input",
-                       output ? (val ? "high" : "low") : "",
-                       lowemi ? "on" : "off");
-
-               clk_enable(nmk_chip->clk);
-               bit = pin % NMK_GPIO_PER_CHIP;
-               if (gpiomode)
-                       /* No glitch when going to GPIO mode */
-                       __nmk_gpio_set_mode(nmk_chip, bit, NMK_GPIO_ALT_GPIO);
-               if (output)
-                       __nmk_gpio_make_output(nmk_chip, bit, val);
-               else {
-                       __nmk_gpio_make_input(nmk_chip, bit);
-                       __nmk_gpio_set_pull(nmk_chip, bit, pull);
-               }
-               /* TODO: isn't this only applicable on output pins? */
-               __nmk_gpio_set_lowemi(nmk_chip, bit, lowemi);
-
-               __nmk_gpio_set_slpm(nmk_chip, bit, slpm);
-               clk_disable(nmk_chip->clk);
-       } /* for each config */
-
-       return 0;
-}
-
-static const struct pinconf_ops nmk_pinconf_ops = {
-       .pin_config_get = nmk_pin_config_get,
-       .pin_config_set = nmk_pin_config_set,
-};
-
-static struct pinctrl_desc nmk_pinctrl_desc = {
-       .name = "pinctrl-nomadik",
-       .pctlops = &nmk_pinctrl_ops,
-       .pmxops = &nmk_pinmux_ops,
-       .confops = &nmk_pinconf_ops,
-       .owner = THIS_MODULE,
-};
-
-static const struct of_device_id nmk_pinctrl_match[] = {
-       {
-               .compatible = "stericsson,stn8815-pinctrl",
-               .data = (void *)PINCTRL_NMK_STN8815,
-       },
-       {
-               .compatible = "stericsson,db8500-pinctrl",
-               .data = (void *)PINCTRL_NMK_DB8500,
-       },
-       {
-               .compatible = "stericsson,db8540-pinctrl",
-               .data = (void *)PINCTRL_NMK_DB8540,
-       },
-       {},
-};
-
-#ifdef CONFIG_PM_SLEEP
-static int nmk_pinctrl_suspend(struct device *dev)
-{
-       struct nmk_pinctrl *npct;
-
-       npct = dev_get_drvdata(dev);
-       if (!npct)
-               return -EINVAL;
-
-       return pinctrl_force_sleep(npct->pctl);
-}
-
-static int nmk_pinctrl_resume(struct device *dev)
-{
-       struct nmk_pinctrl *npct;
-
-       npct = dev_get_drvdata(dev);
-       if (!npct)
-               return -EINVAL;
-
-       return pinctrl_force_default(npct->pctl);
-}
-#endif
-
-static int nmk_pinctrl_probe(struct platform_device *pdev)
-{
-       const struct of_device_id *match;
-       struct device_node *np = pdev->dev.of_node;
-       struct device_node *prcm_np;
-       struct nmk_pinctrl *npct;
-       unsigned int version = 0;
-       int i;
-
-       npct = devm_kzalloc(&pdev->dev, sizeof(*npct), GFP_KERNEL);
-       if (!npct)
-               return -ENOMEM;
-
-       match = of_match_device(nmk_pinctrl_match, &pdev->dev);
-       if (!match)
-               return -ENODEV;
-       version = (unsigned int) match->data;
-
-       /* Poke in other ASIC variants here */
-       if (version == PINCTRL_NMK_STN8815)
-               nmk_pinctrl_stn8815_init(&npct->soc);
-       if (version == PINCTRL_NMK_DB8500)
-               nmk_pinctrl_db8500_init(&npct->soc);
-       if (version == PINCTRL_NMK_DB8540)
-               nmk_pinctrl_db8540_init(&npct->soc);
-
-       prcm_np = of_parse_phandle(np, "prcm", 0);
-       if (prcm_np)
-               npct->prcm_base = of_iomap(prcm_np, 0);
-       if (!npct->prcm_base) {
-               if (version == PINCTRL_NMK_STN8815) {
-                       dev_info(&pdev->dev,
-                                "No PRCM base, "
-                                "assuming no ALT-Cx control is available\n");
-               } else {
-                       dev_err(&pdev->dev, "missing PRCM base address\n");
-                       return -EINVAL;
-               }
-       }
-
-       /*
-        * We need all the GPIO drivers to probe FIRST, or we will not be able
-        * to obtain references to the struct gpio_chip * for them, and we
-        * need this to proceed.
-        */
-       for (i = 0; i < npct->soc->gpio_num_ranges; i++) {
-               if (!nmk_gpio_chips[npct->soc->gpio_ranges[i].id]) {
-                       dev_warn(&pdev->dev, "GPIO chip %d not registered yet\n", i);
-                       return -EPROBE_DEFER;
-               }
-               npct->soc->gpio_ranges[i].gc = &nmk_gpio_chips[npct->soc->gpio_ranges[i].id]->chip;
-       }
-
-       nmk_pinctrl_desc.pins = npct->soc->pins;
-       nmk_pinctrl_desc.npins = npct->soc->npins;
-       npct->dev = &pdev->dev;
-
-       npct->pctl = pinctrl_register(&nmk_pinctrl_desc, &pdev->dev, npct);
-       if (!npct->pctl) {
-               dev_err(&pdev->dev, "could not register Nomadik pinctrl driver\n");
-               return -EINVAL;
-       }
-
-       /* We will handle a range of GPIO pins */
-       for (i = 0; i < npct->soc->gpio_num_ranges; i++)
-               pinctrl_add_gpio_range(npct->pctl, &npct->soc->gpio_ranges[i]);
-
-       platform_set_drvdata(pdev, npct);
-       dev_info(&pdev->dev, "initialized Nomadik pin control driver\n");
-
-       return 0;
-}
-
-static const struct of_device_id nmk_gpio_match[] = {
-       { .compatible = "st,nomadik-gpio", },
-       {}
-};
-
-static struct platform_driver nmk_gpio_driver = {
-       .driver = {
-               .owner = THIS_MODULE,
-               .name = "gpio",
-               .of_match_table = nmk_gpio_match,
-       },
-       .probe = nmk_gpio_probe,
-};
-
-static SIMPLE_DEV_PM_OPS(nmk_pinctrl_pm_ops,
-                       nmk_pinctrl_suspend,
-                       nmk_pinctrl_resume);
-
-static struct platform_driver nmk_pinctrl_driver = {
-       .driver = {
-               .owner = THIS_MODULE,
-               .name = "pinctrl-nomadik",
-               .of_match_table = nmk_pinctrl_match,
-               .pm = &nmk_pinctrl_pm_ops,
-       },
-       .probe = nmk_pinctrl_probe,
-};
-
-static int __init nmk_gpio_init(void)
-{
-       int ret;
-
-       ret = platform_driver_register(&nmk_gpio_driver);
-       if (ret)
-               return ret;
-       return platform_driver_register(&nmk_pinctrl_driver);
-}
-
-core_initcall(nmk_gpio_init);
-
-MODULE_AUTHOR("Prafulla WADASKAR and Alessandro Rubini");
-MODULE_DESCRIPTION("Nomadik GPIO Driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/pinctrl/pinctrl-nomadik.h b/drivers/pinctrl/pinctrl-nomadik.h
deleted file mode 100644 (file)
index d8215f1..0000000
+++ /dev/null
@@ -1,192 +0,0 @@
-#ifndef PINCTRL_PINCTRL_NOMADIK_H
-#define PINCTRL_PINCTRL_NOMADIK_H
-
-/* Package definitions */
-#define PINCTRL_NMK_STN8815    0
-#define PINCTRL_NMK_DB8500     1
-#define PINCTRL_NMK_DB8540     2
-
-/* Alternate functions: function C is set in hw by setting both A and B */
-#define NMK_GPIO_ALT_GPIO      0
-#define NMK_GPIO_ALT_A 1
-#define NMK_GPIO_ALT_B 2
-#define NMK_GPIO_ALT_C (NMK_GPIO_ALT_A | NMK_GPIO_ALT_B)
-
-#define NMK_GPIO_ALT_CX_SHIFT 2
-#define NMK_GPIO_ALT_C1        ((1<<NMK_GPIO_ALT_CX_SHIFT) | NMK_GPIO_ALT_C)
-#define NMK_GPIO_ALT_C2        ((2<<NMK_GPIO_ALT_CX_SHIFT) | NMK_GPIO_ALT_C)
-#define NMK_GPIO_ALT_C3        ((3<<NMK_GPIO_ALT_CX_SHIFT) | NMK_GPIO_ALT_C)
-#define NMK_GPIO_ALT_C4        ((4<<NMK_GPIO_ALT_CX_SHIFT) | NMK_GPIO_ALT_C)
-
-#define PRCM_GPIOCR_ALTCX(pin_num,\
-       altc1_used, altc1_ri, altc1_cb,\
-       altc2_used, altc2_ri, altc2_cb,\
-       altc3_used, altc3_ri, altc3_cb,\
-       altc4_used, altc4_ri, altc4_cb)\
-{\
-       .pin = pin_num,\
-       .altcx[PRCM_IDX_GPIOCR_ALTC1] = {\
-               .used = altc1_used,\
-               .reg_index = altc1_ri,\
-               .control_bit = altc1_cb\
-       },\
-       .altcx[PRCM_IDX_GPIOCR_ALTC2] = {\
-               .used = altc2_used,\
-               .reg_index = altc2_ri,\
-               .control_bit = altc2_cb\
-       },\
-       .altcx[PRCM_IDX_GPIOCR_ALTC3] = {\
-               .used = altc3_used,\
-               .reg_index = altc3_ri,\
-               .control_bit = altc3_cb\
-       },\
-       .altcx[PRCM_IDX_GPIOCR_ALTC4] = {\
-               .used = altc4_used,\
-               .reg_index = altc4_ri,\
-               .control_bit = altc4_cb\
-       },\
-}
-
-/**
- * enum prcm_gpiocr_reg_index
- * Used to reference an PRCM GPIOCR register address.
- */
-enum prcm_gpiocr_reg_index {
-       PRCM_IDX_GPIOCR1,
-       PRCM_IDX_GPIOCR2,
-       PRCM_IDX_GPIOCR3
-};
-/**
- * enum prcm_gpiocr_altcx_index
- * Used to reference an Other alternate-C function.
- */
-enum prcm_gpiocr_altcx_index {
-       PRCM_IDX_GPIOCR_ALTC1,
-       PRCM_IDX_GPIOCR_ALTC2,
-       PRCM_IDX_GPIOCR_ALTC3,
-       PRCM_IDX_GPIOCR_ALTC4,
-       PRCM_IDX_GPIOCR_ALTC_MAX,
-};
-
-/**
- * struct prcm_gpio_altcx - Other alternate-C function
- * @used: other alternate-C function availability
- * @reg_index: PRCM GPIOCR register index used to control the function
- * @control_bit: PRCM GPIOCR bit used to control the function
- */
-struct prcm_gpiocr_altcx {
-       bool used:1;
-       u8 reg_index:2;
-       u8 control_bit:5;
-} __packed;
-
-/**
- * struct prcm_gpio_altcx_pin_desc - Other alternate-C pin
- * @pin: The pin number
- * @altcx: array of other alternate-C[1-4] functions
- */
-struct prcm_gpiocr_altcx_pin_desc {
-       unsigned short pin;
-       struct prcm_gpiocr_altcx altcx[PRCM_IDX_GPIOCR_ALTC_MAX];
-};
-
-/**
- * struct nmk_function - Nomadik pinctrl mux function
- * @name: The name of the function, exported to pinctrl core.
- * @groups: An array of pin groups that may select this function.
- * @ngroups: The number of entries in @groups.
- */
-struct nmk_function {
-       const char *name;
-       const char * const *groups;
-       unsigned ngroups;
-};
-
-/**
- * struct nmk_pingroup - describes a Nomadik pin group
- * @name: the name of this specific pin group
- * @pins: an array of discrete physical pins used in this group, taken
- *     from the driver-local pin enumeration space
- * @num_pins: the number of pins in this group array, i.e. the number of
- *     elements in .pins so we can iterate over that array
- * @altsetting: the altsetting to apply to all pins in this group to
- *     configure them to be used by a function
- */
-struct nmk_pingroup {
-       const char *name;
-       const unsigned int *pins;
-       const unsigned npins;
-       int altsetting;
-};
-
-/**
- * struct nmk_pinctrl_soc_data - Nomadik pin controller per-SoC configuration
- * @gpio_ranges: An array of GPIO ranges for this SoC
- * @gpio_num_ranges: The number of GPIO ranges for this SoC
- * @pins:      An array describing all pins the pin controller affects.
- *             All pins which are also GPIOs must be listed first within the
- *             array, and be numbered identically to the GPIO controller's
- *             numbering.
- * @npins:     The number of entries in @pins.
- * @functions: The functions supported on this SoC.
- * @nfunction: The number of entries in @functions.
- * @groups:    An array describing all pin groups the pin SoC supports.
- * @ngroups:   The number of entries in @groups.
- * @altcx_pins:        The pins that support Other alternate-C function on this SoC
- * @npins_altcx: The number of Other alternate-C pins
- * @prcm_gpiocr_registers: The array of PRCM GPIOCR registers on this SoC
- */
-struct nmk_pinctrl_soc_data {
-       struct pinctrl_gpio_range *gpio_ranges;
-       unsigned gpio_num_ranges;
-       const struct pinctrl_pin_desc *pins;
-       unsigned npins;
-       const struct nmk_function *functions;
-       unsigned nfunctions;
-       const struct nmk_pingroup *groups;
-       unsigned ngroups;
-       const struct prcm_gpiocr_altcx_pin_desc *altcx_pins;
-       unsigned npins_altcx;
-       const u16 *prcm_gpiocr_registers;
-};
-
-#ifdef CONFIG_PINCTRL_STN8815
-
-void nmk_pinctrl_stn8815_init(const struct nmk_pinctrl_soc_data **soc);
-
-#else
-
-static inline void
-nmk_pinctrl_stn8815_init(const struct nmk_pinctrl_soc_data **soc)
-{
-}
-
-#endif
-
-#ifdef CONFIG_PINCTRL_DB8500
-
-void nmk_pinctrl_db8500_init(const struct nmk_pinctrl_soc_data **soc);
-
-#else
-
-static inline void
-nmk_pinctrl_db8500_init(const struct nmk_pinctrl_soc_data **soc)
-{
-}
-
-#endif
-
-#ifdef CONFIG_PINCTRL_DB8540
-
-void nmk_pinctrl_db8540_init(const struct nmk_pinctrl_soc_data **soc);
-
-#else
-
-static inline void
-nmk_pinctrl_db8540_init(const struct nmk_pinctrl_soc_data **soc)
-{
-}
-
-#endif
-
-#endif /* PINCTRL_PINCTRL_NOMADIK_H */
index bb805d5e9ff066a37275fb3e758d7dbae8ab87c9..5e8b2e04cd7a322e6aefa85adbd3996ad04cc19e 100644 (file)
@@ -62,11 +62,26 @@ enum rockchip_pinctrl_type {
        RK2928,
        RK3066B,
        RK3188,
+       RK3288,
 };
 
-enum rockchip_pin_bank_type {
-       COMMON_BANK,
-       RK3188_BANK0,
+/**
+ * Encode variants of iomux registers into a type variable
+ */
+#define IOMUX_GPIO_ONLY                BIT(0)
+#define IOMUX_WIDTH_4BIT       BIT(1)
+#define IOMUX_SOURCE_PMU       BIT(2)
+#define IOMUX_UNROUTED         BIT(3)
+
+/**
+ * @type: iomux variant using IOMUX_* constants
+ * @offset: if initialized to -1 it will be autocalculated, by specifying
+ *         an initial offset value the relevant source offset can be reset
+ *         to a new value for autocalculating the following iomux registers.
+ */
+struct rockchip_iomux {
+       int                             type;
+       int                             offset;
 };
 
 /**
@@ -78,6 +93,7 @@ enum rockchip_pin_bank_type {
  * @nr_pins: number of pins in this bank
  * @name: name of the bank
  * @bank_num: number of the bank, to account for holes
+ * @iomux: array describing the 4 iomux sources of the bank
  * @valid: are all necessary informations present
  * @of_node: dt node of this bank
  * @drvdata: common pinctrl basedata
@@ -95,7 +111,7 @@ struct rockchip_pin_bank {
        u8                              nr_pins;
        char                            *name;
        u8                              bank_num;
-       enum rockchip_pin_bank_type     bank_type;
+       struct rockchip_iomux           iomux[4];
        bool                            valid;
        struct device_node              *of_node;
        struct rockchip_pinctrl         *drvdata;
@@ -111,6 +127,25 @@ struct rockchip_pin_bank {
                .bank_num       = id,                   \
                .nr_pins        = pins,                 \
                .name           = label,                \
+               .iomux          = {                     \
+                       { .offset = -1 },               \
+                       { .offset = -1 },               \
+                       { .offset = -1 },               \
+                       { .offset = -1 },               \
+               },                                      \
+       }
+
+#define PIN_BANK_IOMUX_FLAGS(id, pins, label, iom0, iom1, iom2, iom3)  \
+       {                                                               \
+               .bank_num       = id,                                   \
+               .nr_pins        = pins,                                 \
+               .name           = label,                                \
+               .iomux          = {                                     \
+                       { .type = iom0, .offset = -1 },                 \
+                       { .type = iom1, .offset = -1 },                 \
+                       { .type = iom2, .offset = -1 },                 \
+                       { .type = iom3, .offset = -1 },                 \
+               },                                                      \
        }
 
 /**
@@ -121,7 +156,8 @@ struct rockchip_pin_ctrl {
        u32                             nr_pins;
        char                            *label;
        enum rockchip_pinctrl_type      type;
-       int                             mux_offset;
+       int                             grf_mux_offset;
+       int                             pmu_mux_offset;
        void    (*pull_calc_reg)(struct rockchip_pin_bank *bank,
                                    int pin_num, struct regmap **regmap,
                                    int *reg, u8 *bit);
@@ -343,24 +379,42 @@ static const struct pinctrl_ops rockchip_pctrl_ops = {
 static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin)
 {
        struct rockchip_pinctrl *info = bank->drvdata;
+       int iomux_num = (pin / 8);
+       struct regmap *regmap;
        unsigned int val;
-       int reg, ret;
+       int reg, ret, mask;
        u8 bit;
 
-       if (bank->bank_type == RK3188_BANK0 && pin < 16)
+       if (iomux_num > 3)
+               return -EINVAL;
+
+       if (bank->iomux[iomux_num].type & IOMUX_UNROUTED) {
+               dev_err(info->dev, "pin %d is unrouted\n", pin);
+               return -EINVAL;
+       }
+
+       if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY)
                return RK_FUNC_GPIO;
 
+       regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
+                               ? info->regmap_pmu : info->regmap_base;
+
        /* get basic quadrupel of mux registers and the correct reg inside */
-       reg = info->ctrl->mux_offset;
-       reg += bank->bank_num * 0x10;
-       reg += (pin / 8) * 4;
-       bit = (pin % 8) * 2;
+       mask = (bank->iomux[iomux_num].type & IOMUX_WIDTH_4BIT) ? 0xf : 0x3;
+       reg = bank->iomux[iomux_num].offset;
+       if (bank->iomux[iomux_num].type & IOMUX_WIDTH_4BIT) {
+               if ((pin % 8) >= 4)
+                       reg += 0x4;
+               bit = (pin % 4) * 4;
+       } else {
+               bit = (pin % 8) * 2;
+       }
 
-       ret = regmap_read(info->regmap_base, reg, &val);
+       ret = regmap_read(regmap, reg, &val);
        if (ret)
                return ret;
 
-       return ((val >> bit) & 3);
+       return ((val >> bit) & mask);
 }
 
 /*
@@ -379,16 +433,22 @@ static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin)
 static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
 {
        struct rockchip_pinctrl *info = bank->drvdata;
-       int reg, ret;
+       int iomux_num = (pin / 8);
+       struct regmap *regmap;
+       int reg, ret, mask;
        unsigned long flags;
        u8 bit;
        u32 data;
 
-       /*
-        * The first 16 pins of rk3188_bank0 are always gpios and do not have
-        * a mux register at all.
-        */
-       if (bank->bank_type == RK3188_BANK0 && pin < 16) {
+       if (iomux_num > 3)
+               return -EINVAL;
+
+       if (bank->iomux[iomux_num].type & IOMUX_UNROUTED) {
+               dev_err(info->dev, "pin %d is unrouted\n", pin);
+               return -EINVAL;
+       }
+
+       if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY) {
                if (mux != RK_FUNC_GPIO) {
                        dev_err(info->dev,
                                "pin %d only supports a gpio mux\n", pin);
@@ -401,17 +461,25 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
        dev_dbg(info->dev, "setting mux of GPIO%d-%d to %d\n",
                                                bank->bank_num, pin, mux);
 
+       regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
+                               ? info->regmap_pmu : info->regmap_base;
+
        /* get basic quadrupel of mux registers and the correct reg inside */
-       reg = info->ctrl->mux_offset;
-       reg += bank->bank_num * 0x10;
-       reg += (pin / 8) * 4;
-       bit = (pin % 8) * 2;
+       mask = (bank->iomux[iomux_num].type & IOMUX_WIDTH_4BIT) ? 0xf : 0x3;
+       reg = bank->iomux[iomux_num].offset;
+       if (bank->iomux[iomux_num].type & IOMUX_WIDTH_4BIT) {
+               if ((pin % 8) >= 4)
+                       reg += 0x4;
+               bit = (pin % 4) * 4;
+       } else {
+               bit = (pin % 8) * 2;
+       }
 
        spin_lock_irqsave(&bank->slock, flags);
 
-       data = (3 << (bit + 16));
-       data |= (mux & 3) << bit;
-       ret = regmap_write(info->regmap_base, reg, data);
+       data = (mask << (bit + 16));
+       data |= (mux & mask) << bit;
+       ret = regmap_write(regmap, reg, data);
 
        spin_unlock_irqrestore(&bank->slock, flags);
 
@@ -449,7 +517,7 @@ static void rk3188_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
        struct rockchip_pinctrl *info = bank->drvdata;
 
        /* The first 12 pins of the first bank are located elsewhere */
-       if (bank->bank_type == RK3188_BANK0 && pin_num < 12) {
+       if (bank->bank_num == 0 && pin_num < 12) {
                *regmap = info->regmap_pmu ? info->regmap_pmu
                                           : bank->regmap_pull;
                *reg = info->regmap_pmu ? RK3188_PULL_PMU_OFFSET : 0;
@@ -476,6 +544,127 @@ static void rk3188_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
        }
 }
 
+#define RK3288_PULL_OFFSET             0x140
+static void rk3288_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
+                                   int pin_num, struct regmap **regmap,
+                                   int *reg, u8 *bit)
+{
+       struct rockchip_pinctrl *info = bank->drvdata;
+
+       /* The first 24 pins of the first bank are located in PMU */
+       if (bank->bank_num == 0) {
+               *regmap = info->regmap_pmu;
+               *reg = RK3188_PULL_PMU_OFFSET;
+
+               *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4);
+               *bit = pin_num % RK3188_PULL_PINS_PER_REG;
+               *bit *= RK3188_PULL_BITS_PER_PIN;
+       } else {
+               *regmap = info->regmap_base;
+               *reg = RK3288_PULL_OFFSET;
+
+               /* correct the offset, as we're starting with the 2nd bank */
+               *reg -= 0x10;
+               *reg += bank->bank_num * RK3188_PULL_BANK_STRIDE;
+               *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4);
+
+               *bit = (pin_num % RK3188_PULL_PINS_PER_REG);
+               *bit *= RK3188_PULL_BITS_PER_PIN;
+       }
+}
+
+#define RK3288_DRV_PMU_OFFSET          0x70
+#define RK3288_DRV_GRF_OFFSET          0x1c0
+#define RK3288_DRV_BITS_PER_PIN                2
+#define RK3288_DRV_PINS_PER_REG                8
+#define RK3288_DRV_BANK_STRIDE         16
+static int rk3288_drv_list[] = { 2, 4, 8, 12 };
+
+static void rk3288_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
+                                   int pin_num, struct regmap **regmap,
+                                   int *reg, u8 *bit)
+{
+       struct rockchip_pinctrl *info = bank->drvdata;
+
+       /* The first 24 pins of the first bank are located in PMU */
+       if (bank->bank_num == 0) {
+               *regmap = info->regmap_pmu;
+               *reg = RK3288_DRV_PMU_OFFSET;
+
+               *reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4);
+               *bit = pin_num % RK3288_DRV_PINS_PER_REG;
+               *bit *= RK3288_DRV_BITS_PER_PIN;
+       } else {
+               *regmap = info->regmap_base;
+               *reg = RK3288_DRV_GRF_OFFSET;
+
+               /* correct the offset, as we're starting with the 2nd bank */
+               *reg -= 0x10;
+               *reg += bank->bank_num * RK3288_DRV_BANK_STRIDE;
+               *reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4);
+
+               *bit = (pin_num % RK3288_DRV_PINS_PER_REG);
+               *bit *= RK3288_DRV_BITS_PER_PIN;
+       }
+}
+
+static int rk3288_get_drive(struct rockchip_pin_bank *bank, int pin_num)
+{
+       struct regmap *regmap;
+       int reg, ret;
+       u32 data;
+       u8 bit;
+
+       rk3288_calc_drv_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
+
+       ret = regmap_read(regmap, reg, &data);
+       if (ret)
+               return ret;
+
+       data >>= bit;
+       data &= (1 << RK3288_DRV_BITS_PER_PIN) - 1;
+
+       return rk3288_drv_list[data];
+}
+
+static int rk3288_set_drive(struct rockchip_pin_bank *bank, int pin_num,
+                           int strength)
+{
+       struct rockchip_pinctrl *info = bank->drvdata;
+       struct regmap *regmap;
+       unsigned long flags;
+       int reg, ret, i;
+       u32 data;
+       u8 bit;
+
+       rk3288_calc_drv_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
+
+       ret = -EINVAL;
+       for (i = 0; i < ARRAY_SIZE(rk3288_drv_list); i++) {
+               if (rk3288_drv_list[i] == strength) {
+                       ret = i;
+                       break;
+               }
+       }
+
+       if (ret < 0) {
+               dev_err(info->dev, "unsupported driver strength %d\n",
+                       strength);
+               return ret;
+       }
+
+       spin_lock_irqsave(&bank->slock, flags);
+
+       /* enable the write to the equivalent lower bits */
+       data = ((1 << RK3288_DRV_BITS_PER_PIN) - 1) << (bit + 16);
+       data |= (ret << bit);
+
+       ret = regmap_write(regmap, reg, data);
+       spin_unlock_irqrestore(&bank->slock, flags);
+
+       return ret;
+}
+
 static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num)
 {
        struct rockchip_pinctrl *info = bank->drvdata;
@@ -501,6 +690,7 @@ static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num)
                                ? PIN_CONFIG_BIAS_PULL_PIN_DEFAULT
                                : PIN_CONFIG_BIAS_DISABLE;
        case RK3188:
+       case RK3288:
                data >>= bit;
                data &= (1 << RK3188_PULL_BITS_PER_PIN) - 1;
 
@@ -555,6 +745,7 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank,
                spin_unlock_irqrestore(&bank->slock, flags);
                break;
        case RK3188:
+       case RK3288:
                spin_lock_irqsave(&bank->slock, flags);
 
                /* enable the write to the equivalent lower bits */
@@ -657,23 +848,6 @@ static int rockchip_pmx_enable(struct pinctrl_dev *pctldev, unsigned selector,
        return 0;
 }
 
-static void rockchip_pmx_disable(struct pinctrl_dev *pctldev,
-                                       unsigned selector, unsigned group)
-{
-       struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
-       const unsigned int *pins = info->groups[group].pins;
-       struct rockchip_pin_bank *bank;
-       int cnt;
-
-       dev_dbg(info->dev, "disable function %s group %s\n",
-               info->functions[selector].name, info->groups[group].name);
-
-       for (cnt = 0; cnt < info->groups[group].npins; cnt++) {
-               bank = pin_to_bank(info, pins[cnt]);
-               rockchip_set_mux(bank, pins[cnt] - bank->pin_base, 0);
-       }
-}
-
 /*
  * The calls to gpio_direction_output() and gpio_direction_input()
  * leads to this function call (via the pinctrl_gpio_direction_{input|output}()
@@ -716,7 +890,6 @@ static const struct pinmux_ops rockchip_pmx_ops = {
        .get_function_name      = rockchip_pmx_get_func_name,
        .get_function_groups    = rockchip_pmx_get_groups,
        .enable                 = rockchip_pmx_enable,
-       .disable                = rockchip_pmx_disable,
        .gpio_set_direction     = rockchip_pmx_gpio_set_direction,
 };
 
@@ -734,6 +907,7 @@ static bool rockchip_pinconf_pull_valid(struct rockchip_pin_ctrl *ctrl,
        case RK3066B:
                return pull ? false : true;
        case RK3188:
+       case RK3288:
                return (pull != PIN_CONFIG_BIAS_PULL_PIN_DEFAULT);
        }
 
@@ -788,6 +962,15 @@ static int rockchip_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
                        if (rc)
                                return rc;
                        break;
+               case PIN_CONFIG_DRIVE_STRENGTH:
+                       /* rk3288 is the first with per-pin drive-strength */
+                       if (info->ctrl->type != RK3288)
+                               return -ENOTSUPP;
+
+                       rc = rk3288_set_drive(bank, pin - bank->pin_base, arg);
+                       if (rc < 0)
+                               return rc;
+                       break;
                default:
                        return -ENOTSUPP;
                        break;
@@ -837,6 +1020,17 @@ static int rockchip_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
 
                arg = rc ? 1 : 0;
                break;
+       case PIN_CONFIG_DRIVE_STRENGTH:
+               /* rk3288 is the first with per-pin drive-strength */
+               if (info->ctrl->type != RK3288)
+                       return -ENOTSUPP;
+
+               rc = rk3288_get_drive(bank, pin - bank->pin_base);
+               if (rc < 0)
+                       return rc;
+
+               arg = rc;
+               break;
        default:
                return -ENOTSUPP;
                break;
@@ -850,6 +1044,7 @@ static int rockchip_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
 static const struct pinconf_ops rockchip_pinconf_ops = {
        .pin_config_get                 = rockchip_pinconf_get,
        .pin_config_set                 = rockchip_pinconf_set,
+       .is_generic                     = true,
 };
 
 static const struct of_device_id rockchip_bank_match[] = {
@@ -1414,10 +1609,7 @@ fail:
        for (--i, --bank; i >= 0; --i, --bank) {
                if (!bank->valid)
                        continue;
-
-               if (gpiochip_remove(&bank->gpio_chip))
-                       dev_err(&pdev->dev, "gpio chip %s remove failed\n",
-                                                       bank->gpio_chip.label);
+               gpiochip_remove(&bank->gpio_chip);
        }
        return ret;
 }
@@ -1427,20 +1619,15 @@ static int rockchip_gpiolib_unregister(struct platform_device *pdev,
 {
        struct rockchip_pin_ctrl *ctrl = info->ctrl;
        struct rockchip_pin_bank *bank = ctrl->pin_banks;
-       int ret = 0;
        int i;
 
-       for (i = 0; !ret && i < ctrl->nr_banks; ++i, ++bank) {
+       for (i = 0; i < ctrl->nr_banks; ++i, ++bank) {
                if (!bank->valid)
                        continue;
-
-               ret = gpiochip_remove(&bank->gpio_chip);
+               gpiochip_remove(&bank->gpio_chip);
        }
 
-       if (ret)
-               dev_err(&pdev->dev, "gpio chip remove failed\n");
-
-       return ret;
+       return 0;
 }
 
 static int rockchip_get_bank_data(struct rockchip_pin_bank *bank,
@@ -1466,8 +1653,6 @@ static int rockchip_get_bank_data(struct rockchip_pin_bank *bank,
                                    "rockchip,rk3188-gpio-bank0")) {
                struct device_node *node;
 
-               bank->bank_type = RK3188_BANK0;
-
                node = of_parse_phandle(bank->of_node->parent,
                                        "rockchip,pmu", 0);
                if (!node) {
@@ -1487,9 +1672,6 @@ static int rockchip_get_bank_data(struct rockchip_pin_bank *bank,
                                                    base,
                                                    &rockchip_regmap_config);
                }
-
-       } else {
-               bank->bank_type = COMMON_BANK;
        }
 
        bank->irq = irq_of_parse_and_map(bank->of_node, 0);
@@ -1513,7 +1695,7 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(
        struct device_node *np;
        struct rockchip_pin_ctrl *ctrl;
        struct rockchip_pin_bank *bank;
-       int i;
+       int grf_offs, pmu_offs, i, j;
 
        match = of_match_node(rockchip_pinctrl_dt_match, node);
        ctrl = (struct rockchip_pin_ctrl *)match->data;
@@ -1535,12 +1717,51 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(
                }
        }
 
+       grf_offs = ctrl->grf_mux_offset;
+       pmu_offs = ctrl->pmu_mux_offset;
        bank = ctrl->pin_banks;
        for (i = 0; i < ctrl->nr_banks; ++i, ++bank) {
+               int bank_pins = 0;
+
                spin_lock_init(&bank->slock);
                bank->drvdata = d;
                bank->pin_base = ctrl->nr_pins;
                ctrl->nr_pins += bank->nr_pins;
+
+               /* calculate iomux offsets */
+               for (j = 0; j < 4; j++) {
+                       struct rockchip_iomux *iom = &bank->iomux[j];
+                       int inc;
+
+                       if (bank_pins >= bank->nr_pins)
+                               break;
+
+                       /* preset offset value, set new start value */
+                       if (iom->offset >= 0) {
+                               if (iom->type & IOMUX_SOURCE_PMU)
+                                       pmu_offs = iom->offset;
+                               else
+                                       grf_offs = iom->offset;
+                       } else { /* set current offset */
+                               iom->offset = (iom->type & IOMUX_SOURCE_PMU) ?
+                                                       pmu_offs : grf_offs;
+                       }
+
+                       dev_dbg(d->dev, "bank %d, iomux %d has offset 0x%x\n",
+                                i, j, iom->offset);
+
+                       /*
+                        * Increase offset according to iomux width.
+                        * 4bit iomux'es are spread over two registers.
+                        */
+                       inc = (iom->type & IOMUX_WIDTH_4BIT) ? 8 : 4;
+                       if (iom->type & IOMUX_SOURCE_PMU)
+                               pmu_offs += inc;
+                       else
+                               grf_offs += inc;
+
+                       bank_pins += 8;
+               }
        }
 
        return ctrl;
@@ -1644,7 +1865,7 @@ static struct rockchip_pin_ctrl rk2928_pin_ctrl = {
                .nr_banks               = ARRAY_SIZE(rk2928_pin_banks),
                .label                  = "RK2928-GPIO",
                .type                   = RK2928,
-               .mux_offset             = 0xa8,
+               .grf_mux_offset         = 0xa8,
                .pull_calc_reg          = rk2928_calc_pull_reg_and_bit,
 };
 
@@ -1662,7 +1883,7 @@ static struct rockchip_pin_ctrl rk3066a_pin_ctrl = {
                .nr_banks               = ARRAY_SIZE(rk3066a_pin_banks),
                .label                  = "RK3066a-GPIO",
                .type                   = RK2928,
-               .mux_offset             = 0xa8,
+               .grf_mux_offset         = 0xa8,
                .pull_calc_reg          = rk2928_calc_pull_reg_and_bit,
 };
 
@@ -1678,11 +1899,11 @@ static struct rockchip_pin_ctrl rk3066b_pin_ctrl = {
                .nr_banks       = ARRAY_SIZE(rk3066b_pin_banks),
                .label          = "RK3066b-GPIO",
                .type           = RK3066B,
-               .mux_offset     = 0x60,
+               .grf_mux_offset = 0x60,
 };
 
 static struct rockchip_pin_bank rk3188_pin_banks[] = {
-       PIN_BANK(0, 32, "gpio0"),
+       PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_GPIO_ONLY, 0, 0, 0),
        PIN_BANK(1, 32, "gpio1"),
        PIN_BANK(2, 32, "gpio2"),
        PIN_BANK(3, 32, "gpio3"),
@@ -1693,10 +1914,52 @@ static struct rockchip_pin_ctrl rk3188_pin_ctrl = {
                .nr_banks               = ARRAY_SIZE(rk3188_pin_banks),
                .label                  = "RK3188-GPIO",
                .type                   = RK3188,
-               .mux_offset             = 0x60,
+               .grf_mux_offset         = 0x60,
                .pull_calc_reg          = rk3188_calc_pull_reg_and_bit,
 };
 
+static struct rockchip_pin_bank rk3288_pin_banks[] = {
+       PIN_BANK_IOMUX_FLAGS(0, 24, "gpio0", IOMUX_SOURCE_PMU,
+                                            IOMUX_SOURCE_PMU,
+                                            IOMUX_SOURCE_PMU,
+                                            IOMUX_UNROUTED
+                           ),
+       PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_UNROUTED,
+                                            IOMUX_UNROUTED,
+                                            IOMUX_UNROUTED,
+                                            0
+                           ),
+       PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", 0, 0, 0, IOMUX_UNROUTED),
+       PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", 0, 0, 0, IOMUX_WIDTH_4BIT),
+       PIN_BANK_IOMUX_FLAGS(4, 32, "gpio4", IOMUX_WIDTH_4BIT,
+                                            IOMUX_WIDTH_4BIT,
+                                            0,
+                                            0
+                           ),
+       PIN_BANK_IOMUX_FLAGS(5, 32, "gpio5", IOMUX_UNROUTED,
+                                            0,
+                                            0,
+                                            IOMUX_UNROUTED
+                           ),
+       PIN_BANK_IOMUX_FLAGS(6, 32, "gpio6", 0, 0, 0, IOMUX_UNROUTED),
+       PIN_BANK_IOMUX_FLAGS(7, 32, "gpio7", 0,
+                                            0,
+                                            IOMUX_WIDTH_4BIT,
+                                            IOMUX_UNROUTED
+                           ),
+       PIN_BANK(8, 16, "gpio8"),
+};
+
+static struct rockchip_pin_ctrl rk3288_pin_ctrl = {
+               .pin_banks              = rk3288_pin_banks,
+               .nr_banks               = ARRAY_SIZE(rk3288_pin_banks),
+               .label                  = "RK3288-GPIO",
+               .type                   = RK3288,
+               .grf_mux_offset         = 0x0,
+               .pmu_mux_offset         = 0x84,
+               .pull_calc_reg          = rk3288_calc_pull_reg_and_bit,
+};
+
 static const struct of_device_id rockchip_pinctrl_dt_match[] = {
        { .compatible = "rockchip,rk2928-pinctrl",
                .data = (void *)&rk2928_pin_ctrl },
@@ -1706,6 +1969,8 @@ static const struct of_device_id rockchip_pinctrl_dt_match[] = {
                .data = (void *)&rk3066b_pin_ctrl },
        { .compatible = "rockchip,rk3188-pinctrl",
                .data = (void *)&rk3188_pin_ctrl },
+       { .compatible = "rockchip,rk3288-pinctrl",
+               .data = (void *)&rk3288_pin_ctrl },
        {},
 };
 MODULE_DEVICE_TABLE(of, rockchip_pinctrl_dt_match);
diff --git a/drivers/pinctrl/pinctrl-s3c24xx.c b/drivers/pinctrl/pinctrl-s3c24xx.c
deleted file mode 100644 (file)
index ad3eaad..0000000
+++ /dev/null
@@ -1,651 +0,0 @@
-/*
- * S3C24XX specific support for Samsung pinctrl/gpiolib driver.
- *
- * Copyright (c) 2013 Heiko Stuebner <heiko@sntech.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This file contains the SamsungS3C24XX specific information required by the
- * Samsung pinctrl/gpiolib driver. It also includes the implementation of
- * external gpio and wakeup interrupt support.
- */
-
-#include <linux/module.h>
-#include <linux/device.h>
-#include <linux/interrupt.h>
-#include <linux/irqdomain.h>
-#include <linux/irq.h>
-#include <linux/of_irq.h>
-#include <linux/irqchip/chained_irq.h>
-#include <linux/io.h>
-#include <linux/slab.h>
-#include <linux/err.h>
-
-#include "pinctrl-samsung.h"
-
-#define NUM_EINT       24
-#define NUM_EINT_IRQ   6
-#define EINT_MAX_PER_GROUP     8
-
-#define EINTPEND_REG   0xa8
-#define EINTMASK_REG   0xa4
-
-#define EINT_GROUP(i)          ((int)((i) / EINT_MAX_PER_GROUP))
-#define EINT_REG(i)            ((EINT_GROUP(i) * 4) + 0x88)
-#define EINT_OFFS(i)           ((i) % EINT_MAX_PER_GROUP * 4)
-
-#define EINT_LEVEL_LOW         0
-#define EINT_LEVEL_HIGH                1
-#define EINT_EDGE_FALLING      2
-#define EINT_EDGE_RISING       4
-#define EINT_EDGE_BOTH         6
-#define EINT_MASK              0xf
-
-static struct samsung_pin_bank_type bank_type_1bit = {
-       .fld_width = { 1, 1, },
-       .reg_offset = { 0x00, 0x04, },
-};
-
-static struct samsung_pin_bank_type bank_type_2bit = {
-       .fld_width = { 2, 1, 2, },
-       .reg_offset = { 0x00, 0x04, 0x08, },
-};
-
-#define PIN_BANK_A(pins, reg, id)              \
-       {                                               \
-               .type           = &bank_type_1bit,      \
-               .pctl_offset    = reg,                  \
-               .nr_pins        = pins,                 \
-               .eint_type      = EINT_TYPE_NONE,       \
-               .name           = id                    \
-       }
-
-#define PIN_BANK_2BIT(pins, reg, id)           \
-       {                                               \
-               .type           = &bank_type_2bit,      \
-               .pctl_offset    = reg,                  \
-               .nr_pins        = pins,                 \
-               .eint_type      = EINT_TYPE_NONE,       \
-               .name           = id                    \
-       }
-
-#define PIN_BANK_2BIT_EINTW(pins, reg, id, eoffs, emask)\
-       {                                               \
-               .type           = &bank_type_2bit,      \
-               .pctl_offset    = reg,                  \
-               .nr_pins        = pins,                 \
-               .eint_type      = EINT_TYPE_WKUP,       \
-               .eint_func      = 2,                    \
-               .eint_mask      = emask,                \
-               .eint_offset    = eoffs,                \
-               .name           = id                    \
-       }
-
-/**
- * struct s3c24xx_eint_data: EINT common data
- * @drvdata: pin controller driver data
- * @domains: IRQ domains of particular EINT interrupts
- * @parents: mapped parent irqs in the main interrupt controller
- */
-struct s3c24xx_eint_data {
-       struct samsung_pinctrl_drv_data *drvdata;
-       struct irq_domain *domains[NUM_EINT];
-       int parents[NUM_EINT_IRQ];
-};
-
-/**
- * struct s3c24xx_eint_domain_data: per irq-domain data
- * @bank: pin bank related to the domain
- * @eint_data: common data
- * eint0_3_parent_only: live eints 0-3 only in the main intc
- */
-struct s3c24xx_eint_domain_data {
-       struct samsung_pin_bank *bank;
-       struct s3c24xx_eint_data *eint_data;
-       bool eint0_3_parent_only;
-};
-
-static int s3c24xx_eint_get_trigger(unsigned int type)
-{
-       switch (type) {
-       case IRQ_TYPE_EDGE_RISING:
-               return EINT_EDGE_RISING;
-               break;
-       case IRQ_TYPE_EDGE_FALLING:
-               return EINT_EDGE_FALLING;
-               break;
-       case IRQ_TYPE_EDGE_BOTH:
-               return EINT_EDGE_BOTH;
-               break;
-       case IRQ_TYPE_LEVEL_HIGH:
-               return EINT_LEVEL_HIGH;
-               break;
-       case IRQ_TYPE_LEVEL_LOW:
-               return EINT_LEVEL_LOW;
-               break;
-       default:
-               return -EINVAL;
-       }
-}
-
-static void s3c24xx_eint_set_handler(unsigned int irq, unsigned int type)
-{
-       /* Edge- and level-triggered interrupts need different handlers */
-       if (type & IRQ_TYPE_EDGE_BOTH)
-               __irq_set_handler_locked(irq, handle_edge_irq);
-       else
-               __irq_set_handler_locked(irq, handle_level_irq);
-}
-
-static void s3c24xx_eint_set_function(struct samsung_pinctrl_drv_data *d,
-                                       struct samsung_pin_bank *bank, int pin)
-{
-       struct samsung_pin_bank_type *bank_type = bank->type;
-       unsigned long flags;
-       void __iomem *reg;
-       u8 shift;
-       u32 mask;
-       u32 val;
-
-       /* Make sure that pin is configured as interrupt */
-       reg = d->virt_base + bank->pctl_offset;
-       shift = pin * bank_type->fld_width[PINCFG_TYPE_FUNC];
-       mask = (1 << bank_type->fld_width[PINCFG_TYPE_FUNC]) - 1;
-
-       spin_lock_irqsave(&bank->slock, flags);
-
-       val = readl(reg);
-       val &= ~(mask << shift);
-       val |= bank->eint_func << shift;
-       writel(val, reg);
-
-       spin_unlock_irqrestore(&bank->slock, flags);
-}
-
-static int s3c24xx_eint_type(struct irq_data *data, unsigned int type)
-{
-       struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
-       struct samsung_pinctrl_drv_data *d = bank->drvdata;
-       int index = bank->eint_offset + data->hwirq;
-       void __iomem *reg;
-       int trigger;
-       u8 shift;
-       u32 val;
-
-       trigger = s3c24xx_eint_get_trigger(type);
-       if (trigger < 0) {
-               dev_err(d->dev, "unsupported external interrupt type\n");
-               return -EINVAL;
-       }
-
-       s3c24xx_eint_set_handler(data->irq, type);
-
-       /* Set up interrupt trigger */
-       reg = d->virt_base + EINT_REG(index);
-       shift = EINT_OFFS(index);
-
-       val = readl(reg);
-       val &= ~(EINT_MASK << shift);
-       val |= trigger << shift;
-       writel(val, reg);
-
-       s3c24xx_eint_set_function(d, bank, data->hwirq);
-
-       return 0;
-}
-
-/* Handling of EINTs 0-3 on all except S3C2412 and S3C2413 */
-
-static void s3c2410_eint0_3_ack(struct irq_data *data)
-{
-       struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
-       struct s3c24xx_eint_domain_data *ddata = bank->irq_domain->host_data;
-       struct s3c24xx_eint_data *eint_data = ddata->eint_data;
-       int parent_irq = eint_data->parents[data->hwirq];
-       struct irq_chip *parent_chip = irq_get_chip(parent_irq);
-
-       parent_chip->irq_ack(irq_get_irq_data(parent_irq));
-}
-
-static void s3c2410_eint0_3_mask(struct irq_data *data)
-{
-       struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
-       struct s3c24xx_eint_domain_data *ddata = bank->irq_domain->host_data;
-       struct s3c24xx_eint_data *eint_data = ddata->eint_data;
-       int parent_irq = eint_data->parents[data->hwirq];
-       struct irq_chip *parent_chip = irq_get_chip(parent_irq);
-
-       parent_chip->irq_mask(irq_get_irq_data(parent_irq));
-}
-
-static void s3c2410_eint0_3_unmask(struct irq_data *data)
-{
-       struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
-       struct s3c24xx_eint_domain_data *ddata = bank->irq_domain->host_data;
-       struct s3c24xx_eint_data *eint_data = ddata->eint_data;
-       int parent_irq = eint_data->parents[data->hwirq];
-       struct irq_chip *parent_chip = irq_get_chip(parent_irq);
-
-       parent_chip->irq_unmask(irq_get_irq_data(parent_irq));
-}
-
-static struct irq_chip s3c2410_eint0_3_chip = {
-       .name           = "s3c2410-eint0_3",
-       .irq_ack        = s3c2410_eint0_3_ack,
-       .irq_mask       = s3c2410_eint0_3_mask,
-       .irq_unmask     = s3c2410_eint0_3_unmask,
-       .irq_set_type   = s3c24xx_eint_type,
-};
-
-static void s3c2410_demux_eint0_3(unsigned int irq, struct irq_desc *desc)
-{
-       struct irq_data *data = irq_desc_get_irq_data(desc);
-       struct s3c24xx_eint_data *eint_data = irq_get_handler_data(irq);
-       unsigned int virq;
-
-       /* the first 4 eints have a simple 1 to 1 mapping */
-       virq = irq_linear_revmap(eint_data->domains[data->hwirq], data->hwirq);
-       /* Something must be really wrong if an unmapped EINT is unmasked */
-       BUG_ON(!virq);
-
-       generic_handle_irq(virq);
-}
-
-/* Handling of EINTs 0-3 on S3C2412 and S3C2413 */
-
-static void s3c2412_eint0_3_ack(struct irq_data *data)
-{
-       struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
-       struct samsung_pinctrl_drv_data *d = bank->drvdata;
-
-       unsigned long bitval = 1UL << data->hwirq;
-       writel(bitval, d->virt_base + EINTPEND_REG);
-}
-
-static void s3c2412_eint0_3_mask(struct irq_data *data)
-{
-       struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
-       struct samsung_pinctrl_drv_data *d = bank->drvdata;
-       unsigned long mask;
-
-       mask = readl(d->virt_base + EINTMASK_REG);
-       mask |= (1UL << data->hwirq);
-       writel(mask, d->virt_base + EINTMASK_REG);
-}
-
-static void s3c2412_eint0_3_unmask(struct irq_data *data)
-{
-       struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
-       struct samsung_pinctrl_drv_data *d = bank->drvdata;
-       unsigned long mask;
-
-       mask = readl(d->virt_base + EINTMASK_REG);
-       mask &= ~(1UL << data->hwirq);
-       writel(mask, d->virt_base + EINTMASK_REG);
-}
-
-static struct irq_chip s3c2412_eint0_3_chip = {
-       .name           = "s3c2412-eint0_3",
-       .irq_ack        = s3c2412_eint0_3_ack,
-       .irq_mask       = s3c2412_eint0_3_mask,
-       .irq_unmask     = s3c2412_eint0_3_unmask,
-       .irq_set_type   = s3c24xx_eint_type,
-};
-
-static void s3c2412_demux_eint0_3(unsigned int irq, struct irq_desc *desc)
-{
-       struct irq_chip *chip = irq_get_chip(irq);
-       struct irq_data *data = irq_desc_get_irq_data(desc);
-       struct s3c24xx_eint_data *eint_data = irq_get_handler_data(irq);
-       unsigned int virq;
-
-       chained_irq_enter(chip, desc);
-
-       /* the first 4 eints have a simple 1 to 1 mapping */
-       virq = irq_linear_revmap(eint_data->domains[data->hwirq], data->hwirq);
-       /* Something must be really wrong if an unmapped EINT is unmasked */
-       BUG_ON(!virq);
-
-       generic_handle_irq(virq);
-
-       chained_irq_exit(chip, desc);
-}
-
-/* Handling of all other eints */
-
-static void s3c24xx_eint_ack(struct irq_data *data)
-{
-       struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
-       struct samsung_pinctrl_drv_data *d = bank->drvdata;
-       unsigned char index = bank->eint_offset + data->hwirq;
-
-       writel(1UL << index, d->virt_base + EINTPEND_REG);
-}
-
-static void s3c24xx_eint_mask(struct irq_data *data)
-{
-       struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
-       struct samsung_pinctrl_drv_data *d = bank->drvdata;
-       unsigned char index = bank->eint_offset + data->hwirq;
-       unsigned long mask;
-
-       mask = readl(d->virt_base + EINTMASK_REG);
-       mask |= (1UL << index);
-       writel(mask, d->virt_base + EINTMASK_REG);
-}
-
-static void s3c24xx_eint_unmask(struct irq_data *data)
-{
-       struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
-       struct samsung_pinctrl_drv_data *d = bank->drvdata;
-       unsigned char index = bank->eint_offset + data->hwirq;
-       unsigned long mask;
-
-       mask = readl(d->virt_base + EINTMASK_REG);
-       mask &= ~(1UL << index);
-       writel(mask, d->virt_base + EINTMASK_REG);
-}
-
-static struct irq_chip s3c24xx_eint_chip = {
-       .name           = "s3c-eint",
-       .irq_ack        = s3c24xx_eint_ack,
-       .irq_mask       = s3c24xx_eint_mask,
-       .irq_unmask     = s3c24xx_eint_unmask,
-       .irq_set_type   = s3c24xx_eint_type,
-};
-
-static inline void s3c24xx_demux_eint(unsigned int irq, struct irq_desc *desc,
-                                     u32 offset, u32 range)
-{
-       struct irq_chip *chip = irq_get_chip(irq);
-       struct s3c24xx_eint_data *data = irq_get_handler_data(irq);
-       struct samsung_pinctrl_drv_data *d = data->drvdata;
-       unsigned int pend, mask;
-
-       chained_irq_enter(chip, desc);
-
-       pend = readl(d->virt_base + EINTPEND_REG);
-       mask = readl(d->virt_base + EINTMASK_REG);
-
-       pend &= ~mask;
-       pend &= range;
-
-       while (pend) {
-               unsigned int virq;
-
-               irq = __ffs(pend);
-               pend &= ~(1 << irq);
-               virq = irq_linear_revmap(data->domains[irq], irq - offset);
-               /* Something is really wrong if an unmapped EINT is unmasked */
-               BUG_ON(!virq);
-
-               generic_handle_irq(virq);
-       }
-
-       chained_irq_exit(chip, desc);
-}
-
-static void s3c24xx_demux_eint4_7(unsigned int irq, struct irq_desc *desc)
-{
-       s3c24xx_demux_eint(irq, desc, 0, 0xf0);
-}
-
-static void s3c24xx_demux_eint8_23(unsigned int irq, struct irq_desc *desc)
-{
-       s3c24xx_demux_eint(irq, desc, 8, 0xffff00);
-}
-
-static irq_flow_handler_t s3c2410_eint_handlers[NUM_EINT_IRQ] = {
-       s3c2410_demux_eint0_3,
-       s3c2410_demux_eint0_3,
-       s3c2410_demux_eint0_3,
-       s3c2410_demux_eint0_3,
-       s3c24xx_demux_eint4_7,
-       s3c24xx_demux_eint8_23,
-};
-
-static irq_flow_handler_t s3c2412_eint_handlers[NUM_EINT_IRQ] = {
-       s3c2412_demux_eint0_3,
-       s3c2412_demux_eint0_3,
-       s3c2412_demux_eint0_3,
-       s3c2412_demux_eint0_3,
-       s3c24xx_demux_eint4_7,
-       s3c24xx_demux_eint8_23,
-};
-
-static int s3c24xx_gpf_irq_map(struct irq_domain *h, unsigned int virq,
-                                       irq_hw_number_t hw)
-{
-       struct s3c24xx_eint_domain_data *ddata = h->host_data;
-       struct samsung_pin_bank *bank = ddata->bank;
-
-       if (!(bank->eint_mask & (1 << (bank->eint_offset + hw))))
-               return -EINVAL;
-
-       if (hw <= 3) {
-               if (ddata->eint0_3_parent_only)
-                       irq_set_chip_and_handler(virq, &s3c2410_eint0_3_chip,
-                                                handle_edge_irq);
-               else
-                       irq_set_chip_and_handler(virq, &s3c2412_eint0_3_chip,
-                                                handle_edge_irq);
-       } else {
-               irq_set_chip_and_handler(virq, &s3c24xx_eint_chip,
-                                        handle_edge_irq);
-       }
-       irq_set_chip_data(virq, bank);
-       set_irq_flags(virq, IRQF_VALID);
-       return 0;
-}
-
-static const struct irq_domain_ops s3c24xx_gpf_irq_ops = {
-       .map    = s3c24xx_gpf_irq_map,
-       .xlate  = irq_domain_xlate_twocell,
-};
-
-static int s3c24xx_gpg_irq_map(struct irq_domain *h, unsigned int virq,
-                                       irq_hw_number_t hw)
-{
-       struct s3c24xx_eint_domain_data *ddata = h->host_data;
-       struct samsung_pin_bank *bank = ddata->bank;
-
-       if (!(bank->eint_mask & (1 << (bank->eint_offset + hw))))
-               return -EINVAL;
-
-       irq_set_chip_and_handler(virq, &s3c24xx_eint_chip, handle_edge_irq);
-       irq_set_chip_data(virq, bank);
-       set_irq_flags(virq, IRQF_VALID);
-       return 0;
-}
-
-static const struct irq_domain_ops s3c24xx_gpg_irq_ops = {
-       .map    = s3c24xx_gpg_irq_map,
-       .xlate  = irq_domain_xlate_twocell,
-};
-
-static const struct of_device_id s3c24xx_eint_irq_ids[] = {
-       { .compatible = "samsung,s3c2410-wakeup-eint", .data = (void *)1 },
-       { .compatible = "samsung,s3c2412-wakeup-eint", .data = (void *)0 },
-       { }
-};
-
-static int s3c24xx_eint_init(struct samsung_pinctrl_drv_data *d)
-{
-       struct device *dev = d->dev;
-       const struct of_device_id *match;
-       struct device_node *eint_np = NULL;
-       struct device_node *np;
-       struct samsung_pin_bank *bank;
-       struct s3c24xx_eint_data *eint_data;
-       const struct irq_domain_ops *ops;
-       unsigned int i;
-       bool eint0_3_parent_only;
-       irq_flow_handler_t *handlers;
-
-       for_each_child_of_node(dev->of_node, np) {
-               match = of_match_node(s3c24xx_eint_irq_ids, np);
-               if (match) {
-                       eint_np = np;
-                       eint0_3_parent_only = (bool)match->data;
-                       break;
-               }
-       }
-       if (!eint_np)
-               return -ENODEV;
-
-       eint_data = devm_kzalloc(dev, sizeof(*eint_data), GFP_KERNEL);
-       if (!eint_data)
-               return -ENOMEM;
-
-       eint_data->drvdata = d;
-
-       handlers = eint0_3_parent_only ? s3c2410_eint_handlers
-                                      : s3c2412_eint_handlers;
-       for (i = 0; i < NUM_EINT_IRQ; ++i) {
-               unsigned int irq;
-
-               irq = irq_of_parse_and_map(eint_np, i);
-               if (!irq) {
-                       dev_err(dev, "failed to get wakeup EINT IRQ %d\n", i);
-                       return -ENXIO;
-               }
-
-               eint_data->parents[i] = irq;
-               irq_set_chained_handler(irq, handlers[i]);
-               irq_set_handler_data(irq, eint_data);
-       }
-
-       bank = d->ctrl->pin_banks;
-       for (i = 0; i < d->ctrl->nr_banks; ++i, ++bank) {
-               struct s3c24xx_eint_domain_data *ddata;
-               unsigned int mask;
-               unsigned int irq;
-               unsigned int pin;
-
-               if (bank->eint_type != EINT_TYPE_WKUP)
-                       continue;
-
-               ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL);
-               if (!ddata)
-                       return -ENOMEM;
-
-               ddata->bank = bank;
-               ddata->eint_data = eint_data;
-               ddata->eint0_3_parent_only = eint0_3_parent_only;
-
-               ops = (bank->eint_offset == 0) ? &s3c24xx_gpf_irq_ops
-                                              : &s3c24xx_gpg_irq_ops;
-
-               bank->irq_domain = irq_domain_add_linear(bank->of_node,
-                               bank->nr_pins, ops, ddata);
-               if (!bank->irq_domain) {
-                       dev_err(dev, "wkup irq domain add failed\n");
-                       return -ENXIO;
-               }
-
-               irq = bank->eint_offset;
-               mask = bank->eint_mask;
-               for (pin = 0; mask; ++pin, mask >>= 1) {
-                       if (irq >= NUM_EINT)
-                               break;
-                       if (!(mask & 1))
-                               continue;
-                       eint_data->domains[irq] = bank->irq_domain;
-                       ++irq;
-               }
-       }
-
-       return 0;
-}
-
-static struct samsung_pin_bank s3c2412_pin_banks[] = {
-       PIN_BANK_A(23, 0x000, "gpa"),
-       PIN_BANK_2BIT(11, 0x010, "gpb"),
-       PIN_BANK_2BIT(16, 0x020, "gpc"),
-       PIN_BANK_2BIT(16, 0x030, "gpd"),
-       PIN_BANK_2BIT(16, 0x040, "gpe"),
-       PIN_BANK_2BIT_EINTW(8, 0x050, "gpf", 0, 0xff),
-       PIN_BANK_2BIT_EINTW(16, 0x060, "gpg", 8, 0xffff00),
-       PIN_BANK_2BIT(11, 0x070, "gph"),
-       PIN_BANK_2BIT(13, 0x080, "gpj"),
-};
-
-struct samsung_pin_ctrl s3c2412_pin_ctrl[] = {
-       {
-               .pin_banks      = s3c2412_pin_banks,
-               .nr_banks       = ARRAY_SIZE(s3c2412_pin_banks),
-               .eint_wkup_init = s3c24xx_eint_init,
-               .label          = "S3C2412-GPIO",
-       },
-};
-
-static struct samsung_pin_bank s3c2416_pin_banks[] = {
-       PIN_BANK_A(27, 0x000, "gpa"),
-       PIN_BANK_2BIT(11, 0x010, "gpb"),
-       PIN_BANK_2BIT(16, 0x020, "gpc"),
-       PIN_BANK_2BIT(16, 0x030, "gpd"),
-       PIN_BANK_2BIT(16, 0x040, "gpe"),
-       PIN_BANK_2BIT_EINTW(8, 0x050, "gpf", 0, 0xff),
-       PIN_BANK_2BIT_EINTW(8, 0x060, "gpg", 8, 0xff00),
-       PIN_BANK_2BIT(15, 0x070, "gph"),
-       PIN_BANK_2BIT(16, 0x0e0, "gpk"),
-       PIN_BANK_2BIT(14, 0x0f0, "gpl"),
-       PIN_BANK_2BIT(2, 0x100, "gpm"),
-};
-
-struct samsung_pin_ctrl s3c2416_pin_ctrl[] = {
-       {
-               .pin_banks      = s3c2416_pin_banks,
-               .nr_banks       = ARRAY_SIZE(s3c2416_pin_banks),
-               .eint_wkup_init = s3c24xx_eint_init,
-               .label          = "S3C2416-GPIO",
-       },
-};
-
-static struct samsung_pin_bank s3c2440_pin_banks[] = {
-       PIN_BANK_A(25, 0x000, "gpa"),
-       PIN_BANK_2BIT(11, 0x010, "gpb"),
-       PIN_BANK_2BIT(16, 0x020, "gpc"),
-       PIN_BANK_2BIT(16, 0x030, "gpd"),
-       PIN_BANK_2BIT(16, 0x040, "gpe"),
-       PIN_BANK_2BIT_EINTW(8, 0x050, "gpf", 0, 0xff),
-       PIN_BANK_2BIT_EINTW(16, 0x060, "gpg", 8, 0xffff00),
-       PIN_BANK_2BIT(11, 0x070, "gph"),
-       PIN_BANK_2BIT(13, 0x0d0, "gpj"),
-};
-
-struct samsung_pin_ctrl s3c2440_pin_ctrl[] = {
-       {
-               .pin_banks      = s3c2440_pin_banks,
-               .nr_banks       = ARRAY_SIZE(s3c2440_pin_banks),
-               .eint_wkup_init = s3c24xx_eint_init,
-               .label          = "S3C2440-GPIO",
-       },
-};
-
-static struct samsung_pin_bank s3c2450_pin_banks[] = {
-       PIN_BANK_A(28, 0x000, "gpa"),
-       PIN_BANK_2BIT(11, 0x010, "gpb"),
-       PIN_BANK_2BIT(16, 0x020, "gpc"),
-       PIN_BANK_2BIT(16, 0x030, "gpd"),
-       PIN_BANK_2BIT(16, 0x040, "gpe"),
-       PIN_BANK_2BIT_EINTW(8, 0x050, "gpf", 0, 0xff),
-       PIN_BANK_2BIT_EINTW(16, 0x060, "gpg", 8, 0xffff00),
-       PIN_BANK_2BIT(15, 0x070, "gph"),
-       PIN_BANK_2BIT(16, 0x0d0, "gpj"),
-       PIN_BANK_2BIT(16, 0x0e0, "gpk"),
-       PIN_BANK_2BIT(15, 0x0f0, "gpl"),
-       PIN_BANK_2BIT(2, 0x100, "gpm"),
-};
-
-struct samsung_pin_ctrl s3c2450_pin_ctrl[] = {
-       {
-               .pin_banks      = s3c2450_pin_banks,
-               .nr_banks       = ARRAY_SIZE(s3c2450_pin_banks),
-               .eint_wkup_init = s3c24xx_eint_init,
-               .label          = "S3C2450-GPIO",
-       },
-};
diff --git a/drivers/pinctrl/pinctrl-s3c64xx.c b/drivers/pinctrl/pinctrl-s3c64xx.c
deleted file mode 100644 (file)
index 89143c9..0000000
+++ /dev/null
@@ -1,816 +0,0 @@
-/*
- * S3C64xx specific support for pinctrl-samsung driver.
- *
- * Copyright (c) 2013 Tomasz Figa <tomasz.figa@gmail.com>
- *
- * Based on pinctrl-exynos.c, please see the file for original copyrights.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This file contains the Samsung S3C64xx specific information required by the
- * the Samsung pinctrl/gpiolib driver. It also includes the implementation of
- * external gpio and wakeup interrupt support.
- */
-
-#include <linux/module.h>
-#include <linux/device.h>
-#include <linux/interrupt.h>
-#include <linux/irqdomain.h>
-#include <linux/irq.h>
-#include <linux/of_irq.h>
-#include <linux/io.h>
-#include <linux/irqchip/chained_irq.h>
-#include <linux/slab.h>
-#include <linux/err.h>
-
-#include "pinctrl-samsung.h"
-
-#define NUM_EINT0              28
-#define NUM_EINT0_IRQ          4
-#define EINT_MAX_PER_REG       16
-#define EINT_MAX_PER_GROUP     16
-
-/* External GPIO and wakeup interrupt related definitions */
-#define SVC_GROUP_SHIFT                4
-#define SVC_GROUP_MASK         0xf
-#define SVC_NUM_MASK           0xf
-#define SVC_GROUP(x)           ((x >> SVC_GROUP_SHIFT) & \
-                                               SVC_GROUP_MASK)
-
-#define EINT12CON_REG          0x200
-#define EINT12MASK_REG         0x240
-#define EINT12PEND_REG         0x260
-
-#define EINT_OFFS(i)           ((i) % (2 * EINT_MAX_PER_GROUP))
-#define EINT_GROUP(i)          ((i) / EINT_MAX_PER_GROUP)
-#define EINT_REG(g)            (4 * ((g) / 2))
-
-#define EINTCON_REG(i)         (EINT12CON_REG + EINT_REG(EINT_GROUP(i)))
-#define EINTMASK_REG(i)                (EINT12MASK_REG + EINT_REG(EINT_GROUP(i)))
-#define EINTPEND_REG(i)                (EINT12PEND_REG + EINT_REG(EINT_GROUP(i)))
-
-#define SERVICE_REG            0x284
-#define SERVICEPEND_REG                0x288
-
-#define EINT0CON0_REG          0x900
-#define EINT0MASK_REG          0x920
-#define EINT0PEND_REG          0x924
-
-/* S3C64xx specific external interrupt trigger types */
-#define EINT_LEVEL_LOW         0
-#define EINT_LEVEL_HIGH                1
-#define EINT_EDGE_FALLING      2
-#define EINT_EDGE_RISING       4
-#define EINT_EDGE_BOTH         6
-#define EINT_CON_MASK          0xF
-#define EINT_CON_LEN           4
-
-static struct samsung_pin_bank_type bank_type_4bit_off = {
-       .fld_width = { 4, 1, 2, 0, 2, 2, },
-       .reg_offset = { 0x00, 0x04, 0x08, 0, 0x0c, 0x10, },
-};
-
-static struct samsung_pin_bank_type bank_type_4bit_alive = {
-       .fld_width = { 4, 1, 2, },
-       .reg_offset = { 0x00, 0x04, 0x08, },
-};
-
-static struct samsung_pin_bank_type bank_type_4bit2_off = {
-       .fld_width = { 4, 1, 2, 0, 2, 2, },
-       .reg_offset = { 0x00, 0x08, 0x0c, 0, 0x10, 0x14, },
-};
-
-static struct samsung_pin_bank_type bank_type_4bit2_alive = {
-       .fld_width = { 4, 1, 2, },
-       .reg_offset = { 0x00, 0x08, 0x0c, },
-};
-
-static struct samsung_pin_bank_type bank_type_2bit_off = {
-       .fld_width = { 2, 1, 2, 0, 2, 2, },
-       .reg_offset = { 0x00, 0x04, 0x08, 0, 0x0c, 0x10, },
-};
-
-static struct samsung_pin_bank_type bank_type_2bit_alive = {
-       .fld_width = { 2, 1, 2, },
-       .reg_offset = { 0x00, 0x04, 0x08, },
-};
-
-#define PIN_BANK_4BIT(pins, reg, id)                   \
-       {                                               \
-               .type           = &bank_type_4bit_off,  \
-               .pctl_offset    = reg,                  \
-               .nr_pins        = pins,                 \
-               .eint_type      = EINT_TYPE_NONE,       \
-               .name           = id                    \
-       }
-
-#define PIN_BANK_4BIT_EINTG(pins, reg, id, eoffs)      \
-       {                                               \
-               .type           = &bank_type_4bit_off,  \
-               .pctl_offset    = reg,                  \
-               .nr_pins        = pins,                 \
-               .eint_type      = EINT_TYPE_GPIO,       \
-               .eint_func      = 7,                    \
-               .eint_mask      = (1 << (pins)) - 1,    \
-               .eint_offset    = eoffs,                \
-               .name           = id                    \
-       }
-
-#define PIN_BANK_4BIT_EINTW(pins, reg, id, eoffs, emask) \
-       {                                               \
-               .type           = &bank_type_4bit_alive,\
-               .pctl_offset    = reg,                  \
-               .nr_pins        = pins,                 \
-               .eint_type      = EINT_TYPE_WKUP,       \
-               .eint_func      = 3,                    \
-               .eint_mask      = emask,                \
-               .eint_offset    = eoffs,                \
-               .name           = id                    \
-       }
-
-#define PIN_BANK_4BIT2_EINTG(pins, reg, id, eoffs)     \
-       {                                               \
-               .type           = &bank_type_4bit2_off, \
-               .pctl_offset    = reg,                  \
-               .nr_pins        = pins,                 \
-               .eint_type      = EINT_TYPE_GPIO,       \
-               .eint_func      = 7,                    \
-               .eint_mask      = (1 << (pins)) - 1,    \
-               .eint_offset    = eoffs,                \
-               .name           = id                    \
-       }
-
-#define PIN_BANK_4BIT2_EINTW(pins, reg, id, eoffs, emask) \
-       {                                               \
-               .type           = &bank_type_4bit2_alive,\
-               .pctl_offset    = reg,                  \
-               .nr_pins        = pins,                 \
-               .eint_type      = EINT_TYPE_WKUP,       \
-               .eint_func      = 3,                    \
-               .eint_mask      = emask,                \
-               .eint_offset    = eoffs,                \
-               .name           = id                    \
-       }
-
-#define PIN_BANK_4BIT2_ALIVE(pins, reg, id)            \
-       {                                               \
-               .type           = &bank_type_4bit2_alive,\
-               .pctl_offset    = reg,                  \
-               .nr_pins        = pins,                 \
-               .eint_type      = EINT_TYPE_NONE,       \
-               .name           = id                    \
-       }
-
-#define PIN_BANK_2BIT(pins, reg, id)                   \
-       {                                               \
-               .type           = &bank_type_2bit_off,  \
-               .pctl_offset    = reg,                  \
-               .nr_pins        = pins,                 \
-               .eint_type      = EINT_TYPE_NONE,       \
-               .name           = id                    \
-       }
-
-#define PIN_BANK_2BIT_EINTG(pins, reg, id, eoffs, emask) \
-       {                                               \
-               .type           = &bank_type_2bit_off,  \
-               .pctl_offset    = reg,                  \
-               .nr_pins        = pins,                 \
-               .eint_type      = EINT_TYPE_GPIO,       \
-               .eint_func      = 3,                    \
-               .eint_mask      = emask,                \
-               .eint_offset    = eoffs,                \
-               .name           = id                    \
-       }
-
-#define PIN_BANK_2BIT_EINTW(pins, reg, id, eoffs)      \
-       {                                               \
-               .type           = &bank_type_2bit_alive,\
-               .pctl_offset    = reg,                  \
-               .nr_pins        = pins,                 \
-               .eint_type      = EINT_TYPE_WKUP,       \
-               .eint_func      = 2,                    \
-               .eint_mask      = (1 << (pins)) - 1,    \
-               .eint_offset    = eoffs,                \
-               .name           = id                    \
-       }
-
-/**
- * struct s3c64xx_eint0_data: EINT0 common data
- * @drvdata: pin controller driver data
- * @domains: IRQ domains of particular EINT0 interrupts
- * @pins: pin offsets inside of banks of particular EINT0 interrupts
- */
-struct s3c64xx_eint0_data {
-       struct samsung_pinctrl_drv_data *drvdata;
-       struct irq_domain *domains[NUM_EINT0];
-       u8 pins[NUM_EINT0];
-};
-
-/**
- * struct s3c64xx_eint0_domain_data: EINT0 per-domain data
- * @bank: pin bank related to the domain
- * @eints: EINT0 interrupts related to the domain
- */
-struct s3c64xx_eint0_domain_data {
-       struct samsung_pin_bank *bank;
-       u8 eints[];
-};
-
-/**
- * struct s3c64xx_eint_gpio_data: GPIO EINT data
- * @drvdata: pin controller driver data
- * @domains: array of domains related to EINT interrupt groups
- */
-struct s3c64xx_eint_gpio_data {
-       struct samsung_pinctrl_drv_data *drvdata;
-       struct irq_domain *domains[];
-};
-
-/*
- * Common functions for S3C64xx EINT configuration
- */
-
-static int s3c64xx_irq_get_trigger(unsigned int type)
-{
-       int trigger;
-
-       switch (type) {
-       case IRQ_TYPE_EDGE_RISING:
-               trigger = EINT_EDGE_RISING;
-               break;
-       case IRQ_TYPE_EDGE_FALLING:
-               trigger = EINT_EDGE_FALLING;
-               break;
-       case IRQ_TYPE_EDGE_BOTH:
-               trigger = EINT_EDGE_BOTH;
-               break;
-       case IRQ_TYPE_LEVEL_HIGH:
-               trigger = EINT_LEVEL_HIGH;
-               break;
-       case IRQ_TYPE_LEVEL_LOW:
-               trigger = EINT_LEVEL_LOW;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       return trigger;
-}
-
-static void s3c64xx_irq_set_handler(unsigned int irq, unsigned int type)
-{
-       /* Edge- and level-triggered interrupts need different handlers */
-       if (type & IRQ_TYPE_EDGE_BOTH)
-               __irq_set_handler_locked(irq, handle_edge_irq);
-       else
-               __irq_set_handler_locked(irq, handle_level_irq);
-}
-
-static void s3c64xx_irq_set_function(struct samsung_pinctrl_drv_data *d,
-                                       struct samsung_pin_bank *bank, int pin)
-{
-       struct samsung_pin_bank_type *bank_type = bank->type;
-       unsigned long flags;
-       void __iomem *reg;
-       u8 shift;
-       u32 mask;
-       u32 val;
-
-       /* Make sure that pin is configured as interrupt */
-       reg = d->virt_base + bank->pctl_offset;
-       shift = pin;
-       if (bank_type->fld_width[PINCFG_TYPE_FUNC] * shift >= 32) {
-               /* 4-bit bank type with 2 con regs */
-               reg += 4;
-               shift -= 8;
-       }
-
-       shift = shift * bank_type->fld_width[PINCFG_TYPE_FUNC];
-       mask = (1 << bank_type->fld_width[PINCFG_TYPE_FUNC]) - 1;
-
-       spin_lock_irqsave(&bank->slock, flags);
-
-       val = readl(reg);
-       val &= ~(mask << shift);
-       val |= bank->eint_func << shift;
-       writel(val, reg);
-
-       spin_unlock_irqrestore(&bank->slock, flags);
-}
-
-/*
- * Functions for EINT GPIO configuration (EINT groups 1-9)
- */
-
-static inline void s3c64xx_gpio_irq_set_mask(struct irq_data *irqd, bool mask)
-{
-       struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
-       struct samsung_pinctrl_drv_data *d = bank->drvdata;
-       unsigned char index = EINT_OFFS(bank->eint_offset) + irqd->hwirq;
-       void __iomem *reg = d->virt_base + EINTMASK_REG(bank->eint_offset);
-       u32 val;
-
-       val = readl(reg);
-       if (mask)
-               val |= 1 << index;
-       else
-               val &= ~(1 << index);
-       writel(val, reg);
-}
-
-static void s3c64xx_gpio_irq_unmask(struct irq_data *irqd)
-{
-       s3c64xx_gpio_irq_set_mask(irqd, false);
-}
-
-static void s3c64xx_gpio_irq_mask(struct irq_data *irqd)
-{
-       s3c64xx_gpio_irq_set_mask(irqd, true);
-}
-
-static void s3c64xx_gpio_irq_ack(struct irq_data *irqd)
-{
-       struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
-       struct samsung_pinctrl_drv_data *d = bank->drvdata;
-       unsigned char index = EINT_OFFS(bank->eint_offset) + irqd->hwirq;
-       void __iomem *reg = d->virt_base + EINTPEND_REG(bank->eint_offset);
-
-       writel(1 << index, reg);
-}
-
-static int s3c64xx_gpio_irq_set_type(struct irq_data *irqd, unsigned int type)
-{
-       struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
-       struct samsung_pinctrl_drv_data *d = bank->drvdata;
-       void __iomem *reg;
-       int trigger;
-       u8 shift;
-       u32 val;
-
-       trigger = s3c64xx_irq_get_trigger(type);
-       if (trigger < 0) {
-               pr_err("unsupported external interrupt type\n");
-               return -EINVAL;
-       }
-
-       s3c64xx_irq_set_handler(irqd->irq, type);
-
-       /* Set up interrupt trigger */
-       reg = d->virt_base + EINTCON_REG(bank->eint_offset);
-       shift = EINT_OFFS(bank->eint_offset) + irqd->hwirq;
-       shift = 4 * (shift / 4); /* 4 EINTs per trigger selector */
-
-       val = readl(reg);
-       val &= ~(EINT_CON_MASK << shift);
-       val |= trigger << shift;
-       writel(val, reg);
-
-       s3c64xx_irq_set_function(d, bank, irqd->hwirq);
-
-       return 0;
-}
-
-/*
- * irq_chip for gpio interrupts.
- */
-static struct irq_chip s3c64xx_gpio_irq_chip = {
-       .name           = "GPIO",
-       .irq_unmask     = s3c64xx_gpio_irq_unmask,
-       .irq_mask       = s3c64xx_gpio_irq_mask,
-       .irq_ack        = s3c64xx_gpio_irq_ack,
-       .irq_set_type   = s3c64xx_gpio_irq_set_type,
-};
-
-static int s3c64xx_gpio_irq_map(struct irq_domain *h, unsigned int virq,
-                                       irq_hw_number_t hw)
-{
-       struct samsung_pin_bank *bank = h->host_data;
-
-       if (!(bank->eint_mask & (1 << hw)))
-               return -EINVAL;
-
-       irq_set_chip_and_handler(virq,
-                               &s3c64xx_gpio_irq_chip, handle_level_irq);
-       irq_set_chip_data(virq, bank);
-       set_irq_flags(virq, IRQF_VALID);
-
-       return 0;
-}
-
-/*
- * irq domain callbacks for external gpio interrupt controller.
- */
-static const struct irq_domain_ops s3c64xx_gpio_irqd_ops = {
-       .map    = s3c64xx_gpio_irq_map,
-       .xlate  = irq_domain_xlate_twocell,
-};
-
-static void s3c64xx_eint_gpio_irq(unsigned int irq, struct irq_desc *desc)
-{
-       struct irq_chip *chip = irq_get_chip(irq);
-       struct s3c64xx_eint_gpio_data *data = irq_get_handler_data(irq);
-       struct samsung_pinctrl_drv_data *drvdata = data->drvdata;
-
-       chained_irq_enter(chip, desc);
-
-       do {
-               unsigned int svc;
-               unsigned int group;
-               unsigned int pin;
-               unsigned int virq;
-
-               svc = readl(drvdata->virt_base + SERVICE_REG);
-               group = SVC_GROUP(svc);
-               pin = svc & SVC_NUM_MASK;
-
-               if (!group)
-                       break;
-
-               /* Group 1 is used for two pin banks */
-               if (group == 1) {
-                       if (pin < 8)
-                               group = 0;
-                       else
-                               pin -= 8;
-               }
-
-               virq = irq_linear_revmap(data->domains[group], pin);
-               /*
-                * Something must be really wrong if an unmapped EINT
-                * was unmasked...
-                */
-               BUG_ON(!virq);
-
-               generic_handle_irq(virq);
-       } while (1);
-
-       chained_irq_exit(chip, desc);
-}
-
-/**
- * s3c64xx_eint_gpio_init() - setup handling of external gpio interrupts.
- * @d: driver data of samsung pinctrl driver.
- */
-static int s3c64xx_eint_gpio_init(struct samsung_pinctrl_drv_data *d)
-{
-       struct s3c64xx_eint_gpio_data *data;
-       struct samsung_pin_bank *bank;
-       struct device *dev = d->dev;
-       unsigned int nr_domains;
-       unsigned int i;
-
-       if (!d->irq) {
-               dev_err(dev, "irq number not available\n");
-               return -EINVAL;
-       }
-
-       nr_domains = 0;
-       bank = d->ctrl->pin_banks;
-       for (i = 0; i < d->ctrl->nr_banks; ++i, ++bank) {
-               unsigned int nr_eints;
-               unsigned int mask;
-
-               if (bank->eint_type != EINT_TYPE_GPIO)
-                       continue;
-
-               mask = bank->eint_mask;
-               nr_eints = fls(mask);
-
-               bank->irq_domain = irq_domain_add_linear(bank->of_node,
-                                       nr_eints, &s3c64xx_gpio_irqd_ops, bank);
-               if (!bank->irq_domain) {
-                       dev_err(dev, "gpio irq domain add failed\n");
-                       return -ENXIO;
-               }
-
-               ++nr_domains;
-       }
-
-       data = devm_kzalloc(dev, sizeof(*data)
-                       + nr_domains * sizeof(*data->domains), GFP_KERNEL);
-       if (!data) {
-               dev_err(dev, "failed to allocate handler data\n");
-               return -ENOMEM;
-       }
-       data->drvdata = d;
-
-       bank = d->ctrl->pin_banks;
-       nr_domains = 0;
-       for (i = 0; i < d->ctrl->nr_banks; ++i, ++bank) {
-               if (bank->eint_type != EINT_TYPE_GPIO)
-                       continue;
-
-               data->domains[nr_domains++] = bank->irq_domain;
-       }
-
-       irq_set_chained_handler(d->irq, s3c64xx_eint_gpio_irq);
-       irq_set_handler_data(d->irq, data);
-
-       return 0;
-}
-
-/*
- * Functions for configuration of EINT0 wake-up interrupts
- */
-
-static inline void s3c64xx_eint0_irq_set_mask(struct irq_data *irqd, bool mask)
-{
-       struct s3c64xx_eint0_domain_data *ddata =
-                                       irq_data_get_irq_chip_data(irqd);
-       struct samsung_pinctrl_drv_data *d = ddata->bank->drvdata;
-       u32 val;
-
-       val = readl(d->virt_base + EINT0MASK_REG);
-       if (mask)
-               val |= 1 << ddata->eints[irqd->hwirq];
-       else
-               val &= ~(1 << ddata->eints[irqd->hwirq]);
-       writel(val, d->virt_base + EINT0MASK_REG);
-}
-
-static void s3c64xx_eint0_irq_unmask(struct irq_data *irqd)
-{
-       s3c64xx_eint0_irq_set_mask(irqd, false);
-}
-
-static void s3c64xx_eint0_irq_mask(struct irq_data *irqd)
-{
-       s3c64xx_eint0_irq_set_mask(irqd, true);
-}
-
-static void s3c64xx_eint0_irq_ack(struct irq_data *irqd)
-{
-       struct s3c64xx_eint0_domain_data *ddata =
-                                       irq_data_get_irq_chip_data(irqd);
-       struct samsung_pinctrl_drv_data *d = ddata->bank->drvdata;
-
-       writel(1 << ddata->eints[irqd->hwirq],
-                                       d->virt_base + EINT0PEND_REG);
-}
-
-static int s3c64xx_eint0_irq_set_type(struct irq_data *irqd, unsigned int type)
-{
-       struct s3c64xx_eint0_domain_data *ddata =
-                                       irq_data_get_irq_chip_data(irqd);
-       struct samsung_pin_bank *bank = ddata->bank;
-       struct samsung_pinctrl_drv_data *d = bank->drvdata;
-       void __iomem *reg;
-       int trigger;
-       u8 shift;
-       u32 val;
-
-       trigger = s3c64xx_irq_get_trigger(type);
-       if (trigger < 0) {
-               pr_err("unsupported external interrupt type\n");
-               return -EINVAL;
-       }
-
-       s3c64xx_irq_set_handler(irqd->irq, type);
-
-       /* Set up interrupt trigger */
-       reg = d->virt_base + EINT0CON0_REG;
-       shift = ddata->eints[irqd->hwirq];
-       if (shift >= EINT_MAX_PER_REG) {
-               reg += 4;
-               shift -= EINT_MAX_PER_REG;
-       }
-       shift = EINT_CON_LEN * (shift / 2);
-
-       val = readl(reg);
-       val &= ~(EINT_CON_MASK << shift);
-       val |= trigger << shift;
-       writel(val, reg);
-
-       s3c64xx_irq_set_function(d, bank, irqd->hwirq);
-
-       return 0;
-}
-
-/*
- * irq_chip for wakeup interrupts
- */
-static struct irq_chip s3c64xx_eint0_irq_chip = {
-       .name           = "EINT0",
-       .irq_unmask     = s3c64xx_eint0_irq_unmask,
-       .irq_mask       = s3c64xx_eint0_irq_mask,
-       .irq_ack        = s3c64xx_eint0_irq_ack,
-       .irq_set_type   = s3c64xx_eint0_irq_set_type,
-};
-
-static inline void s3c64xx_irq_demux_eint(unsigned int irq,
-                                       struct irq_desc *desc, u32 range)
-{
-       struct irq_chip *chip = irq_get_chip(irq);
-       struct s3c64xx_eint0_data *data = irq_get_handler_data(irq);
-       struct samsung_pinctrl_drv_data *drvdata = data->drvdata;
-       unsigned int pend, mask;
-
-       chained_irq_enter(chip, desc);
-
-       pend = readl(drvdata->virt_base + EINT0PEND_REG);
-       mask = readl(drvdata->virt_base + EINT0MASK_REG);
-
-       pend = pend & range & ~mask;
-       pend &= range;
-
-       while (pend) {
-               unsigned int virq;
-
-               irq = fls(pend) - 1;
-               pend &= ~(1 << irq);
-
-               virq = irq_linear_revmap(data->domains[irq], data->pins[irq]);
-               /*
-                * Something must be really wrong if an unmapped EINT
-                * was unmasked...
-                */
-               BUG_ON(!virq);
-
-               generic_handle_irq(virq);
-       }
-
-       chained_irq_exit(chip, desc);
-}
-
-static void s3c64xx_demux_eint0_3(unsigned int irq, struct irq_desc *desc)
-{
-       s3c64xx_irq_demux_eint(irq, desc, 0xf);
-}
-
-static void s3c64xx_demux_eint4_11(unsigned int irq, struct irq_desc *desc)
-{
-       s3c64xx_irq_demux_eint(irq, desc, 0xff0);
-}
-
-static void s3c64xx_demux_eint12_19(unsigned int irq, struct irq_desc *desc)
-{
-       s3c64xx_irq_demux_eint(irq, desc, 0xff000);
-}
-
-static void s3c64xx_demux_eint20_27(unsigned int irq, struct irq_desc *desc)
-{
-       s3c64xx_irq_demux_eint(irq, desc, 0xff00000);
-}
-
-static irq_flow_handler_t s3c64xx_eint0_handlers[NUM_EINT0_IRQ] = {
-       s3c64xx_demux_eint0_3,
-       s3c64xx_demux_eint4_11,
-       s3c64xx_demux_eint12_19,
-       s3c64xx_demux_eint20_27,
-};
-
-static int s3c64xx_eint0_irq_map(struct irq_domain *h, unsigned int virq,
-                                       irq_hw_number_t hw)
-{
-       struct s3c64xx_eint0_domain_data *ddata = h->host_data;
-       struct samsung_pin_bank *bank = ddata->bank;
-
-       if (!(bank->eint_mask & (1 << hw)))
-               return -EINVAL;
-
-       irq_set_chip_and_handler(virq,
-                               &s3c64xx_eint0_irq_chip, handle_level_irq);
-       irq_set_chip_data(virq, ddata);
-       set_irq_flags(virq, IRQF_VALID);
-
-       return 0;
-}
-
-/*
- * irq domain callbacks for external wakeup interrupt controller.
- */
-static const struct irq_domain_ops s3c64xx_eint0_irqd_ops = {
-       .map    = s3c64xx_eint0_irq_map,
-       .xlate  = irq_domain_xlate_twocell,
-};
-
-/* list of external wakeup controllers supported */
-static const struct of_device_id s3c64xx_eint0_irq_ids[] = {
-       { .compatible = "samsung,s3c64xx-wakeup-eint", },
-       { }
-};
-
-/**
- * s3c64xx_eint_eint0_init() - setup handling of external wakeup interrupts.
- * @d: driver data of samsung pinctrl driver.
- */
-static int s3c64xx_eint_eint0_init(struct samsung_pinctrl_drv_data *d)
-{
-       struct device *dev = d->dev;
-       struct device_node *eint0_np = NULL;
-       struct device_node *np;
-       struct samsung_pin_bank *bank;
-       struct s3c64xx_eint0_data *data;
-       unsigned int i;
-
-       for_each_child_of_node(dev->of_node, np) {
-               if (of_match_node(s3c64xx_eint0_irq_ids, np)) {
-                       eint0_np = np;
-                       break;
-               }
-       }
-       if (!eint0_np)
-               return -ENODEV;
-
-       data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
-       if (!data) {
-               dev_err(dev, "could not allocate memory for wkup eint data\n");
-               return -ENOMEM;
-       }
-       data->drvdata = d;
-
-       for (i = 0; i < NUM_EINT0_IRQ; ++i) {
-               unsigned int irq;
-
-               irq = irq_of_parse_and_map(eint0_np, i);
-               if (!irq) {
-                       dev_err(dev, "failed to get wakeup EINT IRQ %d\n", i);
-                       return -ENXIO;
-               }
-
-               irq_set_chained_handler(irq, s3c64xx_eint0_handlers[i]);
-               irq_set_handler_data(irq, data);
-       }
-
-       bank = d->ctrl->pin_banks;
-       for (i = 0; i < d->ctrl->nr_banks; ++i, ++bank) {
-               struct s3c64xx_eint0_domain_data *ddata;
-               unsigned int nr_eints;
-               unsigned int mask;
-               unsigned int irq;
-               unsigned int pin;
-
-               if (bank->eint_type != EINT_TYPE_WKUP)
-                       continue;
-
-               mask = bank->eint_mask;
-               nr_eints = fls(mask);
-
-               ddata = devm_kzalloc(dev,
-                               sizeof(*ddata) + nr_eints, GFP_KERNEL);
-               if (!ddata) {
-                       dev_err(dev, "failed to allocate domain data\n");
-                       return -ENOMEM;
-               }
-               ddata->bank = bank;
-
-               bank->irq_domain = irq_domain_add_linear(bank->of_node,
-                               nr_eints, &s3c64xx_eint0_irqd_ops, ddata);
-               if (!bank->irq_domain) {
-                       dev_err(dev, "wkup irq domain add failed\n");
-                       return -ENXIO;
-               }
-
-               irq = bank->eint_offset;
-               mask = bank->eint_mask;
-               for (pin = 0; mask; ++pin, mask >>= 1) {
-                       if (!(mask & 1))
-                               continue;
-                       data->domains[irq] = bank->irq_domain;
-                       data->pins[irq] = pin;
-                       ddata->eints[pin] = irq;
-                       ++irq;
-               }
-       }
-
-       return 0;
-}
-
-/* pin banks of s3c64xx pin-controller 0 */
-static struct samsung_pin_bank s3c64xx_pin_banks0[] = {
-       PIN_BANK_4BIT_EINTG(8, 0x000, "gpa", 0),
-       PIN_BANK_4BIT_EINTG(7, 0x020, "gpb", 8),
-       PIN_BANK_4BIT_EINTG(8, 0x040, "gpc", 16),
-       PIN_BANK_4BIT_EINTG(5, 0x060, "gpd", 32),
-       PIN_BANK_4BIT(5, 0x080, "gpe"),
-       PIN_BANK_2BIT_EINTG(16, 0x0a0, "gpf", 48, 0x3fff),
-       PIN_BANK_4BIT_EINTG(7, 0x0c0, "gpg", 64),
-       PIN_BANK_4BIT2_EINTG(10, 0x0e0, "gph", 80),
-       PIN_BANK_2BIT(16, 0x100, "gpi"),
-       PIN_BANK_2BIT(12, 0x120, "gpj"),
-       PIN_BANK_4BIT2_ALIVE(16, 0x800, "gpk"),
-       PIN_BANK_4BIT2_EINTW(15, 0x810, "gpl", 16, 0x7f00),
-       PIN_BANK_4BIT_EINTW(6, 0x820, "gpm", 23, 0x1f),
-       PIN_BANK_2BIT_EINTW(16, 0x830, "gpn", 0),
-       PIN_BANK_2BIT_EINTG(16, 0x140, "gpo", 96, 0xffff),
-       PIN_BANK_2BIT_EINTG(15, 0x160, "gpp", 112, 0x7fff),
-       PIN_BANK_2BIT_EINTG(9, 0x180, "gpq", 128, 0x1ff),
-};
-
-/*
- * Samsung pinctrl driver data for S3C64xx SoC. S3C64xx SoC includes
- * one gpio/pin-mux/pinconfig controller.
- */
-struct samsung_pin_ctrl s3c64xx_pin_ctrl[] = {
-       {
-               /* pin-controller instance 1 data */
-               .pin_banks      = s3c64xx_pin_banks0,
-               .nr_banks       = ARRAY_SIZE(s3c64xx_pin_banks0),
-               .eint_gpio_init = s3c64xx_eint_gpio_init,
-               .eint_wkup_init = s3c64xx_eint_eint0_init,
-               .label          = "S3C64xx-GPIO",
-       },
-};
diff --git a/drivers/pinctrl/pinctrl-samsung.c b/drivers/pinctrl/pinctrl-samsung.c
deleted file mode 100644 (file)
index 3e61d0f..0000000
+++ /dev/null
@@ -1,1181 +0,0 @@
-/*
- * pin-controller/pin-mux/pin-config/gpio-driver for Samsung's SoC's.
- *
- * Copyright (c) 2012 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- * Copyright (c) 2012 Linaro Ltd
- *             http://www.linaro.org
- *
- * Author: Thomas Abraham <thomas.ab@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This driver implements the Samsung pinctrl driver. It supports setting up of
- * pinmux and pinconf configurations. The gpiolib interface is also included.
- * External interrupt (gpio and wakeup) support are not included in this driver
- * but provides extensions to which platform specific implementation of the gpio
- * and wakeup interrupts can be hooked to.
- */
-
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-#include <linux/slab.h>
-#include <linux/err.h>
-#include <linux/gpio.h>
-#include <linux/irqdomain.h>
-#include <linux/spinlock.h>
-#include <linux/syscore_ops.h>
-
-#include "core.h"
-#include "pinctrl-samsung.h"
-
-#define GROUP_SUFFIX           "-grp"
-#define GSUFFIX_LEN            sizeof(GROUP_SUFFIX)
-#define FUNCTION_SUFFIX                "-mux"
-#define FSUFFIX_LEN            sizeof(FUNCTION_SUFFIX)
-
-/* list of all possible config options supported */
-static struct pin_config {
-       char            *prop_cfg;
-       unsigned int    cfg_type;
-} pcfgs[] = {
-       { "samsung,pin-pud", PINCFG_TYPE_PUD },
-       { "samsung,pin-drv", PINCFG_TYPE_DRV },
-       { "samsung,pin-con-pdn", PINCFG_TYPE_CON_PDN },
-       { "samsung,pin-pud-pdn", PINCFG_TYPE_PUD_PDN },
-};
-
-/* Global list of devices (struct samsung_pinctrl_drv_data) */
-static LIST_HEAD(drvdata_list);
-
-static unsigned int pin_base;
-
-static inline struct samsung_pin_bank *gc_to_pin_bank(struct gpio_chip *gc)
-{
-       return container_of(gc, struct samsung_pin_bank, gpio_chip);
-}
-
-/* check if the selector is a valid pin group selector */
-static int samsung_get_group_count(struct pinctrl_dev *pctldev)
-{
-       struct samsung_pinctrl_drv_data *drvdata;
-
-       drvdata = pinctrl_dev_get_drvdata(pctldev);
-       return drvdata->nr_groups;
-}
-
-/* return the name of the group selected by the group selector */
-static const char *samsung_get_group_name(struct pinctrl_dev *pctldev,
-                                               unsigned selector)
-{
-       struct samsung_pinctrl_drv_data *drvdata;
-
-       drvdata = pinctrl_dev_get_drvdata(pctldev);
-       return drvdata->pin_groups[selector].name;
-}
-
-/* return the pin numbers associated with the specified group */
-static int samsung_get_group_pins(struct pinctrl_dev *pctldev,
-               unsigned selector, const unsigned **pins, unsigned *num_pins)
-{
-       struct samsung_pinctrl_drv_data *drvdata;
-
-       drvdata = pinctrl_dev_get_drvdata(pctldev);
-       *pins = drvdata->pin_groups[selector].pins;
-       *num_pins = drvdata->pin_groups[selector].num_pins;
-       return 0;
-}
-
-/* create pinctrl_map entries by parsing device tree nodes */
-static int samsung_dt_node_to_map(struct pinctrl_dev *pctldev,
-                       struct device_node *np, struct pinctrl_map **maps,
-                       unsigned *nmaps)
-{
-       struct device *dev = pctldev->dev;
-       struct pinctrl_map *map;
-       unsigned long *cfg = NULL;
-       char *gname, *fname;
-       int cfg_cnt = 0, map_cnt = 0, idx = 0;
-
-       /* count the number of config options specfied in the node */
-       for (idx = 0; idx < ARRAY_SIZE(pcfgs); idx++) {
-               if (of_find_property(np, pcfgs[idx].prop_cfg, NULL))
-                       cfg_cnt++;
-       }
-
-       /*
-        * Find out the number of map entries to create. All the config options
-        * can be accomadated into a single config map entry.
-        */
-       if (cfg_cnt)
-               map_cnt = 1;
-       if (of_find_property(np, "samsung,pin-function", NULL))
-               map_cnt++;
-       if (!map_cnt) {
-               dev_err(dev, "node %s does not have either config or function "
-                               "configurations\n", np->name);
-               return -EINVAL;
-       }
-
-       /* Allocate memory for pin-map entries */
-       map = kzalloc(sizeof(*map) * map_cnt, GFP_KERNEL);
-       if (!map) {
-               dev_err(dev, "could not alloc memory for pin-maps\n");
-               return -ENOMEM;
-       }
-       *nmaps = 0;
-
-       /*
-        * Allocate memory for pin group name. The pin group name is derived
-        * from the node name from which these map entries are be created.
-        */
-       gname = kzalloc(strlen(np->name) + GSUFFIX_LEN, GFP_KERNEL);
-       if (!gname) {
-               dev_err(dev, "failed to alloc memory for group name\n");
-               goto free_map;
-       }
-       sprintf(gname, "%s%s", np->name, GROUP_SUFFIX);
-
-       /*
-        * don't have config options? then skip over to creating function
-        * map entries.
-        */
-       if (!cfg_cnt)
-               goto skip_cfgs;
-
-       /* Allocate memory for config entries */
-       cfg = kzalloc(sizeof(*cfg) * cfg_cnt, GFP_KERNEL);
-       if (!cfg) {
-               dev_err(dev, "failed to alloc memory for configs\n");
-               goto free_gname;
-       }
-
-       /* Prepare a list of config settings */
-       for (idx = 0, cfg_cnt = 0; idx < ARRAY_SIZE(pcfgs); idx++) {
-               u32 value;
-               if (!of_property_read_u32(np, pcfgs[idx].prop_cfg, &value))
-                       cfg[cfg_cnt++] =
-                               PINCFG_PACK(pcfgs[idx].cfg_type, value);
-       }
-
-       /* create the config map entry */
-       map[*nmaps].data.configs.group_or_pin = gname;
-       map[*nmaps].data.configs.configs = cfg;
-       map[*nmaps].data.configs.num_configs = cfg_cnt;
-       map[*nmaps].type = PIN_MAP_TYPE_CONFIGS_GROUP;
-       *nmaps += 1;
-
-skip_cfgs:
-       /* create the function map entry */
-       if (of_find_property(np, "samsung,pin-function", NULL)) {
-               fname = kzalloc(strlen(np->name) + FSUFFIX_LEN, GFP_KERNEL);
-               if (!fname) {
-                       dev_err(dev, "failed to alloc memory for func name\n");
-                       goto free_cfg;
-               }
-               sprintf(fname, "%s%s", np->name, FUNCTION_SUFFIX);
-
-               map[*nmaps].data.mux.group = gname;
-               map[*nmaps].data.mux.function = fname;
-               map[*nmaps].type = PIN_MAP_TYPE_MUX_GROUP;
-               *nmaps += 1;
-       }
-
-       *maps = map;
-       return 0;
-
-free_cfg:
-       kfree(cfg);
-free_gname:
-       kfree(gname);
-free_map:
-       kfree(map);
-       return -ENOMEM;
-}
-
-/* free the memory allocated to hold the pin-map table */
-static void samsung_dt_free_map(struct pinctrl_dev *pctldev,
-                            struct pinctrl_map *map, unsigned num_maps)
-{
-       int idx;
-
-       for (idx = 0; idx < num_maps; idx++) {
-               if (map[idx].type == PIN_MAP_TYPE_MUX_GROUP) {
-                       kfree(map[idx].data.mux.function);
-                       if (!idx)
-                               kfree(map[idx].data.mux.group);
-               } else if (map->type == PIN_MAP_TYPE_CONFIGS_GROUP) {
-                       kfree(map[idx].data.configs.configs);
-                       if (!idx)
-                               kfree(map[idx].data.configs.group_or_pin);
-               }
-       };
-
-       kfree(map);
-}
-
-/* list of pinctrl callbacks for the pinctrl core */
-static const struct pinctrl_ops samsung_pctrl_ops = {
-       .get_groups_count       = samsung_get_group_count,
-       .get_group_name         = samsung_get_group_name,
-       .get_group_pins         = samsung_get_group_pins,
-       .dt_node_to_map         = samsung_dt_node_to_map,
-       .dt_free_map            = samsung_dt_free_map,
-};
-
-/* check if the selector is a valid pin function selector */
-static int samsung_get_functions_count(struct pinctrl_dev *pctldev)
-{
-       struct samsung_pinctrl_drv_data *drvdata;
-
-       drvdata = pinctrl_dev_get_drvdata(pctldev);
-       return drvdata->nr_functions;
-}
-
-/* return the name of the pin function specified */
-static const char *samsung_pinmux_get_fname(struct pinctrl_dev *pctldev,
-                                               unsigned selector)
-{
-       struct samsung_pinctrl_drv_data *drvdata;
-
-       drvdata = pinctrl_dev_get_drvdata(pctldev);
-       return drvdata->pmx_functions[selector].name;
-}
-
-/* return the groups associated for the specified function selector */
-static int samsung_pinmux_get_groups(struct pinctrl_dev *pctldev,
-               unsigned selector, const char * const **groups,
-               unsigned * const num_groups)
-{
-       struct samsung_pinctrl_drv_data *drvdata;
-
-       drvdata = pinctrl_dev_get_drvdata(pctldev);
-       *groups = drvdata->pmx_functions[selector].groups;
-       *num_groups = drvdata->pmx_functions[selector].num_groups;
-       return 0;
-}
-
-/*
- * given a pin number that is local to a pin controller, find out the pin bank
- * and the register base of the pin bank.
- */
-static void pin_to_reg_bank(struct samsung_pinctrl_drv_data *drvdata,
-                       unsigned pin, void __iomem **reg, u32 *offset,
-                       struct samsung_pin_bank **bank)
-{
-       struct samsung_pin_bank *b;
-
-       b = drvdata->ctrl->pin_banks;
-
-       while ((pin >= b->pin_base) &&
-                       ((b->pin_base + b->nr_pins - 1) < pin))
-               b++;
-
-       *reg = drvdata->virt_base + b->pctl_offset;
-       *offset = pin - b->pin_base;
-       if (bank)
-               *bank = b;
-}
-
-/* enable or disable a pinmux function */
-static void samsung_pinmux_setup(struct pinctrl_dev *pctldev, unsigned selector,
-                                       unsigned group, bool enable)
-{
-       struct samsung_pinctrl_drv_data *drvdata;
-       const unsigned int *pins;
-       struct samsung_pin_bank *bank;
-       void __iomem *reg;
-       u32 mask, shift, data, pin_offset, cnt;
-       unsigned long flags;
-
-       drvdata = pinctrl_dev_get_drvdata(pctldev);
-       pins = drvdata->pin_groups[group].pins;
-
-       /*
-        * for each pin in the pin group selected, program the correspoding pin
-        * pin function number in the config register.
-        */
-       for (cnt = 0; cnt < drvdata->pin_groups[group].num_pins; cnt++) {
-               struct samsung_pin_bank_type *type;
-
-               pin_to_reg_bank(drvdata, pins[cnt] - drvdata->ctrl->base,
-                               &reg, &pin_offset, &bank);
-               type = bank->type;
-               mask = (1 << type->fld_width[PINCFG_TYPE_FUNC]) - 1;
-               shift = pin_offset * type->fld_width[PINCFG_TYPE_FUNC];
-               if (shift >= 32) {
-                       /* Some banks have two config registers */
-                       shift -= 32;
-                       reg += 4;
-               }
-
-               spin_lock_irqsave(&bank->slock, flags);
-
-               data = readl(reg + type->reg_offset[PINCFG_TYPE_FUNC]);
-               data &= ~(mask << shift);
-               if (enable)
-                       data |= drvdata->pin_groups[group].func << shift;
-               writel(data, reg + type->reg_offset[PINCFG_TYPE_FUNC]);
-
-               spin_unlock_irqrestore(&bank->slock, flags);
-       }
-}
-
-/* enable a specified pinmux by writing to registers */
-static int samsung_pinmux_enable(struct pinctrl_dev *pctldev, unsigned selector,
-                                       unsigned group)
-{
-       samsung_pinmux_setup(pctldev, selector, group, true);
-       return 0;
-}
-
-/* disable a specified pinmux by writing to registers */
-static void samsung_pinmux_disable(struct pinctrl_dev *pctldev,
-                                       unsigned selector, unsigned group)
-{
-       samsung_pinmux_setup(pctldev, selector, group, false);
-}
-
-/*
- * The calls to gpio_direction_output() and gpio_direction_input()
- * leads to this function call (via the pinctrl_gpio_direction_{input|output}()
- * function called from the gpiolib interface).
- */
-static int samsung_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev,
-               struct pinctrl_gpio_range *range, unsigned offset, bool input)
-{
-       struct samsung_pin_bank_type *type;
-       struct samsung_pin_bank *bank;
-       struct samsung_pinctrl_drv_data *drvdata;
-       void __iomem *reg;
-       u32 data, pin_offset, mask, shift;
-       unsigned long flags;
-
-       bank = gc_to_pin_bank(range->gc);
-       type = bank->type;
-       drvdata = pinctrl_dev_get_drvdata(pctldev);
-
-       pin_offset = offset - bank->pin_base;
-       reg = drvdata->virt_base + bank->pctl_offset +
-                                       type->reg_offset[PINCFG_TYPE_FUNC];
-
-       mask = (1 << type->fld_width[PINCFG_TYPE_FUNC]) - 1;
-       shift = pin_offset * type->fld_width[PINCFG_TYPE_FUNC];
-       if (shift >= 32) {
-               /* Some banks have two config registers */
-               shift -= 32;
-               reg += 4;
-       }
-
-       spin_lock_irqsave(&bank->slock, flags);
-
-       data = readl(reg);
-       data &= ~(mask << shift);
-       if (!input)
-               data |= FUNC_OUTPUT << shift;
-       writel(data, reg);
-
-       spin_unlock_irqrestore(&bank->slock, flags);
-
-       return 0;
-}
-
-/* list of pinmux callbacks for the pinmux vertical in pinctrl core */
-static const struct pinmux_ops samsung_pinmux_ops = {
-       .get_functions_count    = samsung_get_functions_count,
-       .get_function_name      = samsung_pinmux_get_fname,
-       .get_function_groups    = samsung_pinmux_get_groups,
-       .enable                 = samsung_pinmux_enable,
-       .disable                = samsung_pinmux_disable,
-       .gpio_set_direction     = samsung_pinmux_gpio_set_direction,
-};
-
-/* set or get the pin config settings for a specified pin */
-static int samsung_pinconf_rw(struct pinctrl_dev *pctldev, unsigned int pin,
-                               unsigned long *config, bool set)
-{
-       struct samsung_pinctrl_drv_data *drvdata;
-       struct samsung_pin_bank_type *type;
-       struct samsung_pin_bank *bank;
-       void __iomem *reg_base;
-       enum pincfg_type cfg_type = PINCFG_UNPACK_TYPE(*config);
-       u32 data, width, pin_offset, mask, shift;
-       u32 cfg_value, cfg_reg;
-       unsigned long flags;
-
-       drvdata = pinctrl_dev_get_drvdata(pctldev);
-       pin_to_reg_bank(drvdata, pin - drvdata->ctrl->base, &reg_base,
-                                       &pin_offset, &bank);
-       type = bank->type;
-
-       if (cfg_type >= PINCFG_TYPE_NUM || !type->fld_width[cfg_type])
-               return -EINVAL;
-
-       width = type->fld_width[cfg_type];
-       cfg_reg = type->reg_offset[cfg_type];
-
-       spin_lock_irqsave(&bank->slock, flags);
-
-       mask = (1 << width) - 1;
-       shift = pin_offset * width;
-       data = readl(reg_base + cfg_reg);
-
-       if (set) {
-               cfg_value = PINCFG_UNPACK_VALUE(*config);
-               data &= ~(mask << shift);
-               data |= (cfg_value << shift);
-               writel(data, reg_base + cfg_reg);
-       } else {
-               data >>= shift;
-               data &= mask;
-               *config = PINCFG_PACK(cfg_type, data);
-       }
-
-       spin_unlock_irqrestore(&bank->slock, flags);
-
-       return 0;
-}
-
-/* set the pin config settings for a specified pin */
-static int samsung_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
-                               unsigned long *configs, unsigned num_configs)
-{
-       int i, ret;
-
-       for (i = 0; i < num_configs; i++) {
-               ret = samsung_pinconf_rw(pctldev, pin, &configs[i], true);
-               if (ret < 0)
-                       return ret;
-       } /* for each config */
-
-       return 0;
-}
-
-/* get the pin config settings for a specified pin */
-static int samsung_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
-                                       unsigned long *config)
-{
-       return samsung_pinconf_rw(pctldev, pin, config, false);
-}
-
-/* set the pin config settings for a specified pin group */
-static int samsung_pinconf_group_set(struct pinctrl_dev *pctldev,
-                       unsigned group, unsigned long *configs,
-                       unsigned num_configs)
-{
-       struct samsung_pinctrl_drv_data *drvdata;
-       const unsigned int *pins;
-       unsigned int cnt;
-
-       drvdata = pinctrl_dev_get_drvdata(pctldev);
-       pins = drvdata->pin_groups[group].pins;
-
-       for (cnt = 0; cnt < drvdata->pin_groups[group].num_pins; cnt++)
-               samsung_pinconf_set(pctldev, pins[cnt], configs, num_configs);
-
-       return 0;
-}
-
-/* get the pin config settings for a specified pin group */
-static int samsung_pinconf_group_get(struct pinctrl_dev *pctldev,
-                               unsigned int group, unsigned long *config)
-{
-       struct samsung_pinctrl_drv_data *drvdata;
-       const unsigned int *pins;
-
-       drvdata = pinctrl_dev_get_drvdata(pctldev);
-       pins = drvdata->pin_groups[group].pins;
-       samsung_pinconf_get(pctldev, pins[0], config);
-       return 0;
-}
-
-/* list of pinconfig callbacks for pinconfig vertical in the pinctrl code */
-static const struct pinconf_ops samsung_pinconf_ops = {
-       .pin_config_get         = samsung_pinconf_get,
-       .pin_config_set         = samsung_pinconf_set,
-       .pin_config_group_get   = samsung_pinconf_group_get,
-       .pin_config_group_set   = samsung_pinconf_group_set,
-};
-
-/* gpiolib gpio_set callback function */
-static void samsung_gpio_set(struct gpio_chip *gc, unsigned offset, int value)
-{
-       struct samsung_pin_bank *bank = gc_to_pin_bank(gc);
-       struct samsung_pin_bank_type *type = bank->type;
-       unsigned long flags;
-       void __iomem *reg;
-       u32 data;
-
-       reg = bank->drvdata->virt_base + bank->pctl_offset;
-
-       spin_lock_irqsave(&bank->slock, flags);
-
-       data = readl(reg + type->reg_offset[PINCFG_TYPE_DAT]);
-       data &= ~(1 << offset);
-       if (value)
-               data |= 1 << offset;
-       writel(data, reg + type->reg_offset[PINCFG_TYPE_DAT]);
-
-       spin_unlock_irqrestore(&bank->slock, flags);
-}
-
-/* gpiolib gpio_get callback function */
-static int samsung_gpio_get(struct gpio_chip *gc, unsigned offset)
-{
-       void __iomem *reg;
-       u32 data;
-       struct samsung_pin_bank *bank = gc_to_pin_bank(gc);
-       struct samsung_pin_bank_type *type = bank->type;
-
-       reg = bank->drvdata->virt_base + bank->pctl_offset;
-
-       data = readl(reg + type->reg_offset[PINCFG_TYPE_DAT]);
-       data >>= offset;
-       data &= 1;
-       return data;
-}
-
-/*
- * gpiolib gpio_direction_input callback function. The setting of the pin
- * mux function as 'gpio input' will be handled by the pinctrl susbsystem
- * interface.
- */
-static int samsung_gpio_direction_input(struct gpio_chip *gc, unsigned offset)
-{
-       return pinctrl_gpio_direction_input(gc->base + offset);
-}
-
-/*
- * gpiolib gpio_direction_output callback function. The setting of the pin
- * mux function as 'gpio output' will be handled by the pinctrl susbsystem
- * interface.
- */
-static int samsung_gpio_direction_output(struct gpio_chip *gc, unsigned offset,
-                                                       int value)
-{
-       samsung_gpio_set(gc, offset, value);
-       return pinctrl_gpio_direction_output(gc->base + offset);
-}
-
-/*
- * gpiolib gpio_to_irq callback function. Creates a mapping between a GPIO pin
- * and a virtual IRQ, if not already present.
- */
-static int samsung_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
-{
-       struct samsung_pin_bank *bank = gc_to_pin_bank(gc);
-       unsigned int virq;
-
-       if (!bank->irq_domain)
-               return -ENXIO;
-
-       virq = irq_create_mapping(bank->irq_domain, offset);
-
-       return (virq) ? : -ENXIO;
-}
-
-/*
- * Parse the pin names listed in the 'samsung,pins' property and convert it
- * into a list of gpio numbers are create a pin group from it.
- */
-static int samsung_pinctrl_parse_dt_pins(struct platform_device *pdev,
-                                        struct device_node *cfg_np,
-                                        struct pinctrl_desc *pctl,
-                                        unsigned int **pin_list,
-                                        unsigned int *npins)
-{
-       struct device *dev = &pdev->dev;
-       struct property *prop;
-       struct pinctrl_pin_desc const *pdesc = pctl->pins;
-       unsigned int idx = 0, cnt;
-       const char *pin_name;
-
-       *npins = of_property_count_strings(cfg_np, "samsung,pins");
-       if (IS_ERR_VALUE(*npins)) {
-               dev_err(dev, "invalid pin list in %s node", cfg_np->name);
-               return -EINVAL;
-       }
-
-       *pin_list = devm_kzalloc(dev, *npins * sizeof(**pin_list), GFP_KERNEL);
-       if (!*pin_list) {
-               dev_err(dev, "failed to allocate memory for pin list\n");
-               return -ENOMEM;
-       }
-
-       of_property_for_each_string(cfg_np, "samsung,pins", prop, pin_name) {
-               for (cnt = 0; cnt < pctl->npins; cnt++) {
-                       if (pdesc[cnt].name) {
-                               if (!strcmp(pin_name, pdesc[cnt].name)) {
-                                       (*pin_list)[idx++] = pdesc[cnt].number;
-                                       break;
-                               }
-                       }
-               }
-               if (cnt == pctl->npins) {
-                       dev_err(dev, "pin %s not valid in %s node\n",
-                                       pin_name, cfg_np->name);
-                       devm_kfree(dev, *pin_list);
-                       return -EINVAL;
-               }
-       }
-
-       return 0;
-}
-
-/*
- * Parse the information about all the available pin groups and pin functions
- * from device node of the pin-controller. A pin group is formed with all
- * the pins listed in the "samsung,pins" property.
- */
-static int samsung_pinctrl_parse_dt(struct platform_device *pdev,
-                                   struct samsung_pinctrl_drv_data *drvdata)
-{
-       struct device *dev = &pdev->dev;
-       struct device_node *dev_np = dev->of_node;
-       struct device_node *cfg_np;
-       struct samsung_pin_group *groups, *grp;
-       struct samsung_pmx_func *functions, *func;
-       unsigned *pin_list;
-       unsigned int npins, grp_cnt, func_idx = 0;
-       char *gname, *fname;
-       int ret;
-
-       grp_cnt = of_get_child_count(dev_np);
-       if (!grp_cnt)
-               return -EINVAL;
-
-       groups = devm_kzalloc(dev, grp_cnt * sizeof(*groups), GFP_KERNEL);
-       if (!groups) {
-               dev_err(dev, "failed allocate memory for ping group list\n");
-               return -EINVAL;
-       }
-       grp = groups;
-
-       functions = devm_kzalloc(dev, grp_cnt * sizeof(*functions), GFP_KERNEL);
-       if (!functions) {
-               dev_err(dev, "failed to allocate memory for function list\n");
-               return -EINVAL;
-       }
-       func = functions;
-
-       /*
-        * Iterate over all the child nodes of the pin controller node
-        * and create pin groups and pin function lists.
-        */
-       for_each_child_of_node(dev_np, cfg_np) {
-               u32 function;
-               if (!of_find_property(cfg_np, "samsung,pins", NULL))
-                       continue;
-
-               ret = samsung_pinctrl_parse_dt_pins(pdev, cfg_np,
-                                       &drvdata->pctl, &pin_list, &npins);
-               if (ret)
-                       return ret;
-
-               /* derive pin group name from the node name */
-               gname = devm_kzalloc(dev, strlen(cfg_np->name) + GSUFFIX_LEN,
-                                       GFP_KERNEL);
-               if (!gname) {
-                       dev_err(dev, "failed to alloc memory for group name\n");
-                       return -ENOMEM;
-               }
-               sprintf(gname, "%s%s", cfg_np->name, GROUP_SUFFIX);
-
-               grp->name = gname;
-               grp->pins = pin_list;
-               grp->num_pins = npins;
-               of_property_read_u32(cfg_np, "samsung,pin-function", &function);
-               grp->func = function;
-               grp++;
-
-               if (!of_find_property(cfg_np, "samsung,pin-function", NULL))
-                       continue;
-
-               /* derive function name from the node name */
-               fname = devm_kzalloc(dev, strlen(cfg_np->name) + FSUFFIX_LEN,
-                                       GFP_KERNEL);
-               if (!fname) {
-                       dev_err(dev, "failed to alloc memory for func name\n");
-                       return -ENOMEM;
-               }
-               sprintf(fname, "%s%s", cfg_np->name, FUNCTION_SUFFIX);
-
-               func->name = fname;
-               func->groups = devm_kzalloc(dev, sizeof(char *), GFP_KERNEL);
-               if (!func->groups) {
-                       dev_err(dev, "failed to alloc memory for group list "
-                                       "in pin function");
-                       return -ENOMEM;
-               }
-               func->groups[0] = gname;
-               func->num_groups = 1;
-               func++;
-               func_idx++;
-       }
-
-       drvdata->pin_groups = groups;
-       drvdata->nr_groups = grp_cnt;
-       drvdata->pmx_functions = functions;
-       drvdata->nr_functions = func_idx;
-
-       return 0;
-}
-
-/* register the pinctrl interface with the pinctrl subsystem */
-static int samsung_pinctrl_register(struct platform_device *pdev,
-                                   struct samsung_pinctrl_drv_data *drvdata)
-{
-       struct pinctrl_desc *ctrldesc = &drvdata->pctl;
-       struct pinctrl_pin_desc *pindesc, *pdesc;
-       struct samsung_pin_bank *pin_bank;
-       char *pin_names;
-       int pin, bank, ret;
-
-       ctrldesc->name = "samsung-pinctrl";
-       ctrldesc->owner = THIS_MODULE;
-       ctrldesc->pctlops = &samsung_pctrl_ops;
-       ctrldesc->pmxops = &samsung_pinmux_ops;
-       ctrldesc->confops = &samsung_pinconf_ops;
-
-       pindesc = devm_kzalloc(&pdev->dev, sizeof(*pindesc) *
-                       drvdata->ctrl->nr_pins, GFP_KERNEL);
-       if (!pindesc) {
-               dev_err(&pdev->dev, "mem alloc for pin descriptors failed\n");
-               return -ENOMEM;
-       }
-       ctrldesc->pins = pindesc;
-       ctrldesc->npins = drvdata->ctrl->nr_pins;
-
-       /* dynamically populate the pin number and pin name for pindesc */
-       for (pin = 0, pdesc = pindesc; pin < ctrldesc->npins; pin++, pdesc++)
-               pdesc->number = pin + drvdata->ctrl->base;
-
-       /*
-        * allocate space for storing the dynamically generated names for all
-        * the pins which belong to this pin-controller.
-        */
-       pin_names = devm_kzalloc(&pdev->dev, sizeof(char) * PIN_NAME_LENGTH *
-                                       drvdata->ctrl->nr_pins, GFP_KERNEL);
-       if (!pin_names) {
-               dev_err(&pdev->dev, "mem alloc for pin names failed\n");
-               return -ENOMEM;
-       }
-
-       /* for each pin, the name of the pin is pin-bank name + pin number */
-       for (bank = 0; bank < drvdata->ctrl->nr_banks; bank++) {
-               pin_bank = &drvdata->ctrl->pin_banks[bank];
-               for (pin = 0; pin < pin_bank->nr_pins; pin++) {
-                       sprintf(pin_names, "%s-%d", pin_bank->name, pin);
-                       pdesc = pindesc + pin_bank->pin_base + pin;
-                       pdesc->name = pin_names;
-                       pin_names += PIN_NAME_LENGTH;
-               }
-       }
-
-       ret = samsung_pinctrl_parse_dt(pdev, drvdata);
-       if (ret)
-               return ret;
-
-       drvdata->pctl_dev = pinctrl_register(ctrldesc, &pdev->dev, drvdata);
-       if (!drvdata->pctl_dev) {
-               dev_err(&pdev->dev, "could not register pinctrl driver\n");
-               return -EINVAL;
-       }
-
-       for (bank = 0; bank < drvdata->ctrl->nr_banks; ++bank) {
-               pin_bank = &drvdata->ctrl->pin_banks[bank];
-               pin_bank->grange.name = pin_bank->name;
-               pin_bank->grange.id = bank;
-               pin_bank->grange.pin_base = pin_bank->pin_base;
-               pin_bank->grange.base = pin_bank->gpio_chip.base;
-               pin_bank->grange.npins = pin_bank->gpio_chip.ngpio;
-               pin_bank->grange.gc = &pin_bank->gpio_chip;
-               pinctrl_add_gpio_range(drvdata->pctl_dev, &pin_bank->grange);
-       }
-
-       return 0;
-}
-
-static const struct gpio_chip samsung_gpiolib_chip = {
-       .set = samsung_gpio_set,
-       .get = samsung_gpio_get,
-       .direction_input = samsung_gpio_direction_input,
-       .direction_output = samsung_gpio_direction_output,
-       .to_irq = samsung_gpio_to_irq,
-       .owner = THIS_MODULE,
-};
-
-/* register the gpiolib interface with the gpiolib subsystem */
-static int samsung_gpiolib_register(struct platform_device *pdev,
-                                   struct samsung_pinctrl_drv_data *drvdata)
-{
-       struct samsung_pin_ctrl *ctrl = drvdata->ctrl;
-       struct samsung_pin_bank *bank = ctrl->pin_banks;
-       struct gpio_chip *gc;
-       int ret;
-       int i;
-
-       for (i = 0; i < ctrl->nr_banks; ++i, ++bank) {
-               bank->gpio_chip = samsung_gpiolib_chip;
-
-               gc = &bank->gpio_chip;
-               gc->base = ctrl->base + bank->pin_base;
-               gc->ngpio = bank->nr_pins;
-               gc->dev = &pdev->dev;
-               gc->of_node = bank->of_node;
-               gc->label = bank->name;
-
-               ret = gpiochip_add(gc);
-               if (ret) {
-                       dev_err(&pdev->dev, "failed to register gpio_chip %s, error code: %d\n",
-                                                       gc->label, ret);
-                       goto fail;
-               }
-       }
-
-       return 0;
-
-fail:
-       for (--i, --bank; i >= 0; --i, --bank)
-               if (gpiochip_remove(&bank->gpio_chip))
-                       dev_err(&pdev->dev, "gpio chip %s remove failed\n",
-                                                       bank->gpio_chip.label);
-       return ret;
-}
-
-/* unregister the gpiolib interface with the gpiolib subsystem */
-static int samsung_gpiolib_unregister(struct platform_device *pdev,
-                                     struct samsung_pinctrl_drv_data *drvdata)
-{
-       struct samsung_pin_ctrl *ctrl = drvdata->ctrl;
-       struct samsung_pin_bank *bank = ctrl->pin_banks;
-       int ret = 0;
-       int i;
-
-       for (i = 0; !ret && i < ctrl->nr_banks; ++i, ++bank)
-               ret = gpiochip_remove(&bank->gpio_chip);
-
-       if (ret)
-               dev_err(&pdev->dev, "gpio chip remove failed\n");
-
-       return ret;
-}
-
-static const struct of_device_id samsung_pinctrl_dt_match[];
-
-/* retrieve the soc specific data */
-static struct samsung_pin_ctrl *samsung_pinctrl_get_soc_data(
-                               struct samsung_pinctrl_drv_data *d,
-                               struct platform_device *pdev)
-{
-       int id;
-       const struct of_device_id *match;
-       struct device_node *node = pdev->dev.of_node;
-       struct device_node *np;
-       struct samsung_pin_ctrl *ctrl;
-       struct samsung_pin_bank *bank;
-       int i;
-
-       id = of_alias_get_id(node, "pinctrl");
-       if (id < 0) {
-               dev_err(&pdev->dev, "failed to get alias id\n");
-               return NULL;
-       }
-       match = of_match_node(samsung_pinctrl_dt_match, node);
-       ctrl = (struct samsung_pin_ctrl *)match->data + id;
-
-       bank = ctrl->pin_banks;
-       for (i = 0; i < ctrl->nr_banks; ++i, ++bank) {
-               spin_lock_init(&bank->slock);
-               bank->drvdata = d;
-               bank->pin_base = ctrl->nr_pins;
-               ctrl->nr_pins += bank->nr_pins;
-       }
-
-       for_each_child_of_node(node, np) {
-               if (!of_find_property(np, "gpio-controller", NULL))
-                       continue;
-               bank = ctrl->pin_banks;
-               for (i = 0; i < ctrl->nr_banks; ++i, ++bank) {
-                       if (!strcmp(bank->name, np->name)) {
-                               bank->of_node = np;
-                               break;
-                       }
-               }
-       }
-
-       ctrl->base = pin_base;
-       pin_base += ctrl->nr_pins;
-
-       return ctrl;
-}
-
-static int samsung_pinctrl_probe(struct platform_device *pdev)
-{
-       struct samsung_pinctrl_drv_data *drvdata;
-       struct device *dev = &pdev->dev;
-       struct samsung_pin_ctrl *ctrl;
-       struct resource *res;
-       int ret;
-
-       if (!dev->of_node) {
-               dev_err(dev, "device tree node not found\n");
-               return -ENODEV;
-       }
-
-       drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
-       if (!drvdata) {
-               dev_err(dev, "failed to allocate memory for driver's "
-                               "private data\n");
-               return -ENOMEM;
-       }
-
-       ctrl = samsung_pinctrl_get_soc_data(drvdata, pdev);
-       if (!ctrl) {
-               dev_err(&pdev->dev, "driver data not available\n");
-               return -EINVAL;
-       }
-       drvdata->ctrl = ctrl;
-       drvdata->dev = dev;
-
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       drvdata->virt_base = devm_ioremap_resource(&pdev->dev, res);
-       if (IS_ERR(drvdata->virt_base))
-               return PTR_ERR(drvdata->virt_base);
-
-       res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-       if (res)
-               drvdata->irq = res->start;
-
-       ret = samsung_gpiolib_register(pdev, drvdata);
-       if (ret)
-               return ret;
-
-       ret = samsung_pinctrl_register(pdev, drvdata);
-       if (ret) {
-               samsung_gpiolib_unregister(pdev, drvdata);
-               return ret;
-       }
-
-       if (ctrl->eint_gpio_init)
-               ctrl->eint_gpio_init(drvdata);
-       if (ctrl->eint_wkup_init)
-               ctrl->eint_wkup_init(drvdata);
-
-       platform_set_drvdata(pdev, drvdata);
-
-       /* Add to the global list */
-       list_add_tail(&drvdata->node, &drvdata_list);
-
-       return 0;
-}
-
-#ifdef CONFIG_PM
-
-/**
- * samsung_pinctrl_suspend_dev - save pinctrl state for suspend for a device
- *
- * Save data for all banks handled by this device.
- */
-static void samsung_pinctrl_suspend_dev(
-       struct samsung_pinctrl_drv_data *drvdata)
-{
-       struct samsung_pin_ctrl *ctrl = drvdata->ctrl;
-       void __iomem *virt_base = drvdata->virt_base;
-       int i;
-
-       for (i = 0; i < ctrl->nr_banks; i++) {
-               struct samsung_pin_bank *bank = &ctrl->pin_banks[i];
-               void __iomem *reg = virt_base + bank->pctl_offset;
-
-               u8 *offs = bank->type->reg_offset;
-               u8 *widths = bank->type->fld_width;
-               enum pincfg_type type;
-
-               /* Registers without a powerdown config aren't lost */
-               if (!widths[PINCFG_TYPE_CON_PDN])
-                       continue;
-
-               for (type = 0; type < PINCFG_TYPE_NUM; type++)
-                       if (widths[type])
-                               bank->pm_save[type] = readl(reg + offs[type]);
-
-               if (widths[PINCFG_TYPE_FUNC] * bank->nr_pins > 32) {
-                       /* Some banks have two config registers */
-                       bank->pm_save[PINCFG_TYPE_NUM] =
-                               readl(reg + offs[PINCFG_TYPE_FUNC] + 4);
-                       pr_debug("Save %s @ %p (con %#010x %08x)\n",
-                                bank->name, reg,
-                                bank->pm_save[PINCFG_TYPE_FUNC],
-                                bank->pm_save[PINCFG_TYPE_NUM]);
-               } else {
-                       pr_debug("Save %s @ %p (con %#010x)\n", bank->name,
-                                reg, bank->pm_save[PINCFG_TYPE_FUNC]);
-               }
-       }
-
-       if (ctrl->suspend)
-               ctrl->suspend(drvdata);
-}
-
-/**
- * samsung_pinctrl_resume_dev - restore pinctrl state from suspend for a device
- *
- * Restore one of the banks that was saved during suspend.
- *
- * We don't bother doing anything complicated to avoid glitching lines since
- * we're called before pad retention is turned off.
- */
-static void samsung_pinctrl_resume_dev(struct samsung_pinctrl_drv_data *drvdata)
-{
-       struct samsung_pin_ctrl *ctrl = drvdata->ctrl;
-       void __iomem *virt_base = drvdata->virt_base;
-       int i;
-
-       if (ctrl->resume)
-               ctrl->resume(drvdata);
-
-       for (i = 0; i < ctrl->nr_banks; i++) {
-               struct samsung_pin_bank *bank = &ctrl->pin_banks[i];
-               void __iomem *reg = virt_base + bank->pctl_offset;
-
-               u8 *offs = bank->type->reg_offset;
-               u8 *widths = bank->type->fld_width;
-               enum pincfg_type type;
-
-               /* Registers without a powerdown config aren't lost */
-               if (!widths[PINCFG_TYPE_CON_PDN])
-                       continue;
-
-               if (widths[PINCFG_TYPE_FUNC] * bank->nr_pins > 32) {
-                       /* Some banks have two config registers */
-                       pr_debug("%s @ %p (con %#010x %08x => %#010x %08x)\n",
-                                bank->name, reg,
-                                readl(reg + offs[PINCFG_TYPE_FUNC]),
-                                readl(reg + offs[PINCFG_TYPE_FUNC] + 4),
-                                bank->pm_save[PINCFG_TYPE_FUNC],
-                                bank->pm_save[PINCFG_TYPE_NUM]);
-                       writel(bank->pm_save[PINCFG_TYPE_NUM],
-                              reg + offs[PINCFG_TYPE_FUNC] + 4);
-               } else {
-                       pr_debug("%s @ %p (con %#010x => %#010x)\n", bank->name,
-                                reg, readl(reg + offs[PINCFG_TYPE_FUNC]),
-                                bank->pm_save[PINCFG_TYPE_FUNC]);
-               }
-               for (type = 0; type < PINCFG_TYPE_NUM; type++)
-                       if (widths[type])
-                               writel(bank->pm_save[type], reg + offs[type]);
-       }
-}
-
-/**
- * samsung_pinctrl_suspend - save pinctrl state for suspend
- *
- * Save data for all banks across all devices.
- */
-static int samsung_pinctrl_suspend(void)
-{
-       struct samsung_pinctrl_drv_data *drvdata;
-
-       list_for_each_entry(drvdata, &drvdata_list, node) {
-               samsung_pinctrl_suspend_dev(drvdata);
-       }
-
-       return 0;
-}
-
-/**
- * samsung_pinctrl_resume - restore pinctrl state for suspend
- *
- * Restore data for all banks across all devices.
- */
-static void samsung_pinctrl_resume(void)
-{
-       struct samsung_pinctrl_drv_data *drvdata;
-
-       list_for_each_entry_reverse(drvdata, &drvdata_list, node) {
-               samsung_pinctrl_resume_dev(drvdata);
-       }
-}
-
-#else
-#define samsung_pinctrl_suspend                NULL
-#define samsung_pinctrl_resume         NULL
-#endif
-
-static struct syscore_ops samsung_pinctrl_syscore_ops = {
-       .suspend        = samsung_pinctrl_suspend,
-       .resume         = samsung_pinctrl_resume,
-};
-
-static const struct of_device_id samsung_pinctrl_dt_match[] = {
-#ifdef CONFIG_PINCTRL_EXYNOS
-       { .compatible = "samsung,exynos3250-pinctrl",
-               .data = (void *)exynos3250_pin_ctrl },
-       { .compatible = "samsung,exynos4210-pinctrl",
-               .data = (void *)exynos4210_pin_ctrl },
-       { .compatible = "samsung,exynos4x12-pinctrl",
-               .data = (void *)exynos4x12_pin_ctrl },
-       { .compatible = "samsung,exynos5250-pinctrl",
-               .data = (void *)exynos5250_pin_ctrl },
-       { .compatible = "samsung,exynos5260-pinctrl",
-               .data = (void *)exynos5260_pin_ctrl },
-       { .compatible = "samsung,exynos5420-pinctrl",
-               .data = (void *)exynos5420_pin_ctrl },
-       { .compatible = "samsung,s5pv210-pinctrl",
-               .data = (void *)s5pv210_pin_ctrl },
-#endif
-#ifdef CONFIG_PINCTRL_S3C64XX
-       { .compatible = "samsung,s3c64xx-pinctrl",
-               .data = s3c64xx_pin_ctrl },
-#endif
-#ifdef CONFIG_PINCTRL_S3C24XX
-       { .compatible = "samsung,s3c2412-pinctrl",
-               .data = s3c2412_pin_ctrl },
-       { .compatible = "samsung,s3c2416-pinctrl",
-               .data = s3c2416_pin_ctrl },
-       { .compatible = "samsung,s3c2440-pinctrl",
-               .data = s3c2440_pin_ctrl },
-       { .compatible = "samsung,s3c2450-pinctrl",
-               .data = s3c2450_pin_ctrl },
-#endif
-       {},
-};
-MODULE_DEVICE_TABLE(of, samsung_pinctrl_dt_match);
-
-static struct platform_driver samsung_pinctrl_driver = {
-       .probe          = samsung_pinctrl_probe,
-       .driver = {
-               .name   = "samsung-pinctrl",
-               .owner  = THIS_MODULE,
-               .of_match_table = samsung_pinctrl_dt_match,
-       },
-};
-
-static int __init samsung_pinctrl_drv_register(void)
-{
-       /*
-        * Register syscore ops for save/restore of registers across suspend.
-        * It's important to ensure that this driver is running at an earlier
-        * initcall level than any arch-specific init calls that install syscore
-        * ops that turn off pad retention (like exynos_pm_resume).
-        */
-       register_syscore_ops(&samsung_pinctrl_syscore_ops);
-
-       return platform_driver_register(&samsung_pinctrl_driver);
-}
-postcore_initcall(samsung_pinctrl_drv_register);
-
-static void __exit samsung_pinctrl_drv_unregister(void)
-{
-       platform_driver_unregister(&samsung_pinctrl_driver);
-}
-module_exit(samsung_pinctrl_drv_unregister);
-
-MODULE_AUTHOR("Thomas Abraham <thomas.ab@samsung.com>");
-MODULE_DESCRIPTION("Samsung pinctrl driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/pinctrl/pinctrl-samsung.h b/drivers/pinctrl/pinctrl-samsung.h
deleted file mode 100644 (file)
index b3e41fa..0000000
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * pin-controller/pin-mux/pin-config/gpio-driver for Samsung's SoC's.
- *
- * Copyright (c) 2012 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- * Copyright (c) 2012 Linaro Ltd
- *             http://www.linaro.org
- *
- * Author: Thomas Abraham <thomas.ab@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#ifndef __PINCTRL_SAMSUNG_H
-#define __PINCTRL_SAMSUNG_H
-
-#include <linux/pinctrl/pinctrl.h>
-#include <linux/pinctrl/pinmux.h>
-#include <linux/pinctrl/pinconf.h>
-#include <linux/pinctrl/consumer.h>
-#include <linux/pinctrl/machine.h>
-
-#include <linux/gpio.h>
-
-/* pinmux function number for pin as gpio output line */
-#define FUNC_OUTPUT    0x1
-
-/**
- * enum pincfg_type - possible pin configuration types supported.
- * @PINCFG_TYPE_FUNC: Function configuration.
- * @PINCFG_TYPE_DAT: Pin value configuration.
- * @PINCFG_TYPE_PUD: Pull up/down configuration.
- * @PINCFG_TYPE_DRV: Drive strength configuration.
- * @PINCFG_TYPE_CON_PDN: Pin function in power down mode.
- * @PINCFG_TYPE_PUD_PDN: Pull up/down configuration in power down mode.
- */
-enum pincfg_type {
-       PINCFG_TYPE_FUNC,
-       PINCFG_TYPE_DAT,
-       PINCFG_TYPE_PUD,
-       PINCFG_TYPE_DRV,
-       PINCFG_TYPE_CON_PDN,
-       PINCFG_TYPE_PUD_PDN,
-
-       PINCFG_TYPE_NUM
-};
-
-/*
- * pin configuration (pull up/down and drive strength) type and its value are
- * packed together into a 16-bits. The upper 8-bits represent the configuration
- * type and the lower 8-bits hold the value of the configuration type.
- */
-#define PINCFG_TYPE_MASK               0xFF
-#define PINCFG_VALUE_SHIFT             8
-#define PINCFG_VALUE_MASK              (0xFF << PINCFG_VALUE_SHIFT)
-#define PINCFG_PACK(type, value)       (((value) << PINCFG_VALUE_SHIFT) | type)
-#define PINCFG_UNPACK_TYPE(cfg)                ((cfg) & PINCFG_TYPE_MASK)
-#define PINCFG_UNPACK_VALUE(cfg)       (((cfg) & PINCFG_VALUE_MASK) >> \
-                                               PINCFG_VALUE_SHIFT)
-/**
- * enum eint_type - possible external interrupt types.
- * @EINT_TYPE_NONE: bank does not support external interrupts
- * @EINT_TYPE_GPIO: bank supportes external gpio interrupts
- * @EINT_TYPE_WKUP: bank supportes external wakeup interrupts
- * @EINT_TYPE_WKUP_MUX: bank supports multiplexed external wakeup interrupts
- *
- * Samsung GPIO controller groups all the available pins into banks. The pins
- * in a pin bank can support external gpio interrupts or external wakeup
- * interrupts or no interrupts at all. From a software perspective, the only
- * difference between external gpio and external wakeup interrupts is that
- * the wakeup interrupts can additionally wakeup the system if it is in
- * suspended state.
- */
-enum eint_type {
-       EINT_TYPE_NONE,
-       EINT_TYPE_GPIO,
-       EINT_TYPE_WKUP,
-       EINT_TYPE_WKUP_MUX,
-};
-
-/* maximum length of a pin in pin descriptor (example: "gpa0-0") */
-#define PIN_NAME_LENGTH        10
-
-#define PIN_GROUP(n, p, f)                             \
-       {                                               \
-               .name           = n,                    \
-               .pins           = p,                    \
-               .num_pins       = ARRAY_SIZE(p),        \
-               .func           = f                     \
-       }
-
-#define PMX_FUNC(n, g)                                 \
-       {                                               \
-               .name           = n,                    \
-               .groups         = g,                    \
-               .num_groups     = ARRAY_SIZE(g),        \
-       }
-
-struct samsung_pinctrl_drv_data;
-
-/**
- * struct samsung_pin_bank_type: pin bank type description
- * @fld_width: widths of configuration bitfields (0 if unavailable)
- * @reg_offset: offsets of configuration registers (don't care of width is 0)
- */
-struct samsung_pin_bank_type {
-       u8 fld_width[PINCFG_TYPE_NUM];
-       u8 reg_offset[PINCFG_TYPE_NUM];
-};
-
-/**
- * struct samsung_pin_bank: represent a controller pin-bank.
- * @type: type of the bank (register offsets and bitfield widths)
- * @pctl_offset: starting offset of the pin-bank registers.
- * @pin_base: starting pin number of the bank.
- * @nr_pins: number of pins included in this bank.
- * @eint_func: function to set in CON register to configure pin as EINT.
- * @eint_type: type of the external interrupt supported by the bank.
- * @eint_mask: bit mask of pins which support EINT function.
- * @name: name to be prefixed for each pin in this pin bank.
- * @of_node: OF node of the bank.
- * @drvdata: link to controller driver data
- * @irq_domain: IRQ domain of the bank.
- * @gpio_chip: GPIO chip of the bank.
- * @grange: linux gpio pin range supported by this bank.
- * @slock: spinlock protecting bank registers
- * @pm_save: saved register values during suspend
- */
-struct samsung_pin_bank {
-       struct samsung_pin_bank_type *type;
-       u32             pctl_offset;
-       u32             pin_base;
-       u8              nr_pins;
-       u8              eint_func;
-       enum eint_type  eint_type;
-       u32             eint_mask;
-       u32             eint_offset;
-       char            *name;
-       void            *soc_priv;
-       struct device_node *of_node;
-       struct samsung_pinctrl_drv_data *drvdata;
-       struct irq_domain *irq_domain;
-       struct gpio_chip gpio_chip;
-       struct pinctrl_gpio_range grange;
-       spinlock_t slock;
-
-       u32 pm_save[PINCFG_TYPE_NUM + 1]; /* +1 to handle double CON registers*/
-};
-
-/**
- * struct samsung_pin_ctrl: represent a pin controller.
- * @pin_banks: list of pin banks included in this controller.
- * @nr_banks: number of pin banks.
- * @base: starting system wide pin number.
- * @nr_pins: number of pins supported by the controller.
- * @geint_con: offset of the ext-gpio controller registers.
- * @geint_mask: offset of the ext-gpio interrupt mask registers.
- * @geint_pend: offset of the ext-gpio interrupt pending registers.
- * @weint_con: offset of the ext-wakeup controller registers.
- * @weint_mask: offset of the ext-wakeup interrupt mask registers.
- * @weint_pend: offset of the ext-wakeup interrupt pending registers.
- * @svc: offset of the interrupt service register.
- * @eint_gpio_init: platform specific callback to setup the external gpio
- *     interrupts for the controller.
- * @eint_wkup_init: platform specific callback to setup the external wakeup
- *     interrupts for the controller.
- * @label: for debug information.
- */
-struct samsung_pin_ctrl {
-       struct samsung_pin_bank *pin_banks;
-       u32             nr_banks;
-
-       u32             base;
-       u32             nr_pins;
-
-       u32             geint_con;
-       u32             geint_mask;
-       u32             geint_pend;
-
-       u32             weint_con;
-       u32             weint_mask;
-       u32             weint_pend;
-
-       u32             svc;
-
-       int             (*eint_gpio_init)(struct samsung_pinctrl_drv_data *);
-       int             (*eint_wkup_init)(struct samsung_pinctrl_drv_data *);
-       void            (*suspend)(struct samsung_pinctrl_drv_data *);
-       void            (*resume)(struct samsung_pinctrl_drv_data *);
-
-       char            *label;
-};
-
-/**
- * struct samsung_pinctrl_drv_data: wrapper for holding driver data together.
- * @node: global list node
- * @virt_base: register base address of the controller.
- * @dev: device instance representing the controller.
- * @irq: interrpt number used by the controller to notify gpio interrupts.
- * @ctrl: pin controller instance managed by the driver.
- * @pctl: pin controller descriptor registered with the pinctrl subsystem.
- * @pctl_dev: cookie representing pinctrl device instance.
- * @pin_groups: list of pin groups available to the driver.
- * @nr_groups: number of such pin groups.
- * @pmx_functions: list of pin functions available to the driver.
- * @nr_function: number of such pin functions.
- */
-struct samsung_pinctrl_drv_data {
-       struct list_head                node;
-       void __iomem                    *virt_base;
-       struct device                   *dev;
-       int                             irq;
-
-       struct samsung_pin_ctrl         *ctrl;
-       struct pinctrl_desc             pctl;
-       struct pinctrl_dev              *pctl_dev;
-
-       const struct samsung_pin_group  *pin_groups;
-       unsigned int                    nr_groups;
-       const struct samsung_pmx_func   *pmx_functions;
-       unsigned int                    nr_functions;
-};
-
-/**
- * struct samsung_pin_group: represent group of pins of a pinmux function.
- * @name: name of the pin group, used to lookup the group.
- * @pins: the pins included in this group.
- * @num_pins: number of pins included in this group.
- * @func: the function number to be programmed when selected.
- */
-struct samsung_pin_group {
-       const char              *name;
-       const unsigned int      *pins;
-       u8                      num_pins;
-       u8                      func;
-};
-
-/**
- * struct samsung_pmx_func: represent a pin function.
- * @name: name of the pin function, used to lookup the function.
- * @groups: one or more names of pin groups that provide this function.
- * @num_groups: number of groups included in @groups.
- */
-struct samsung_pmx_func {
-       const char              *name;
-       const char              **groups;
-       u8                      num_groups;
-};
-
-/* list of all exported SoC specific data */
-extern struct samsung_pin_ctrl exynos3250_pin_ctrl[];
-extern struct samsung_pin_ctrl exynos4210_pin_ctrl[];
-extern struct samsung_pin_ctrl exynos4x12_pin_ctrl[];
-extern struct samsung_pin_ctrl exynos5250_pin_ctrl[];
-extern struct samsung_pin_ctrl exynos5260_pin_ctrl[];
-extern struct samsung_pin_ctrl exynos5420_pin_ctrl[];
-extern struct samsung_pin_ctrl s3c64xx_pin_ctrl[];
-extern struct samsung_pin_ctrl s3c2412_pin_ctrl[];
-extern struct samsung_pin_ctrl s3c2416_pin_ctrl[];
-extern struct samsung_pin_ctrl s3c2440_pin_ctrl[];
-extern struct samsung_pin_ctrl s3c2450_pin_ctrl[];
-extern struct samsung_pin_ctrl s5pv210_pin_ctrl[];
-
-#endif /* __PINCTRL_SAMSUNG_H */
index 2960557bfed95c6d79f316c020ec98c426f38f83..95dd9cf55cb36ab2d5af88b21a437b89adba8656 100644 (file)
@@ -488,61 +488,6 @@ static int pcs_enable(struct pinctrl_dev *pctldev, unsigned fselector,
        return 0;
 }
 
-static void pcs_disable(struct pinctrl_dev *pctldev, unsigned fselector,
-                                       unsigned group)
-{
-       struct pcs_device *pcs;
-       struct pcs_function *func;
-       int i;
-
-       pcs = pinctrl_dev_get_drvdata(pctldev);
-       /* If function mask is null, needn't disable it. */
-       if (!pcs->fmask)
-               return;
-
-       func = radix_tree_lookup(&pcs->ftree, fselector);
-       if (!func) {
-               dev_err(pcs->dev, "%s could not find function%i\n",
-                       __func__, fselector);
-               return;
-       }
-
-       /*
-        * Ignore disable if function-off is not specified. Some hardware
-        * does not have clearly defined disable function. For pin specific
-        * off modes, you can use alternate named states as described in
-        * pinctrl-bindings.txt.
-        */
-       if (pcs->foff == PCS_OFF_DISABLED) {
-               dev_dbg(pcs->dev, "ignoring disable for %s function%i\n",
-                       func->name, fselector);
-               return;
-       }
-
-       dev_dbg(pcs->dev, "disabling function%i %s\n",
-               fselector, func->name);
-
-       for (i = 0; i < func->nvals; i++) {
-               struct pcs_func_vals *vals;
-               unsigned long flags;
-               unsigned val, mask;
-
-               vals = &func->vals[i];
-               raw_spin_lock_irqsave(&pcs->lock, flags);
-               val = pcs->read(vals->reg);
-
-               if (pcs->bits_per_mux)
-                       mask = vals->mask;
-               else
-                       mask = pcs->fmask;
-
-               val &= ~mask;
-               val |= pcs->foff << pcs->fshift;
-               pcs->write(val, vals->reg);
-               raw_spin_unlock_irqrestore(&pcs->lock, flags);
-       }
-}
-
 static int pcs_request_gpio(struct pinctrl_dev *pctldev,
                            struct pinctrl_gpio_range *range, unsigned pin)
 {
@@ -575,7 +520,6 @@ static const struct pinmux_ops pcs_pinmux_ops = {
        .get_function_name = pcs_get_function_name,
        .get_function_groups = pcs_get_function_groups,
        .enable = pcs_enable,
-       .disable = pcs_disable,
        .gpio_request_enable = pcs_request_gpio,
 };
 
@@ -836,7 +780,7 @@ static int pcs_add_pin(struct pcs_device *pcs, unsigned offset,
 
        pin = &pcs->pins.pa[i];
        pn = &pcs->names[i];
-       sprintf(pn->name, "%lx.%d",
+       sprintf(pn->name, "%lx.%u",
                (unsigned long)pcs->res->start + offset, pin_pos);
        pin->name = pn->name;
        pin->number = i;
@@ -1739,11 +1683,10 @@ static void pcs_irq_chain_handler(unsigned int irq, struct irq_desc *desc)
 {
        struct pcs_soc_data *pcs_soc = irq_desc_get_handler_data(desc);
        struct irq_chip *chip;
-       int res;
 
        chip = irq_get_chip(irq);
        chained_irq_enter(chip, desc);
-       res = pcs_irq_handle(pcs_soc);
+       pcs_irq_handle(pcs_soc);
        /* REVISIT: export and add handle_bad_irq(irq, desc)? */
        chained_irq_exit(chip, desc);
 
index 9f43916637ca251372fb57efc32bdd82dde4eef1..5475374d803fd69bf43c44ad2f8087ad858d92e8 100644 (file)
@@ -930,11 +930,6 @@ static int st_pmx_enable(struct pinctrl_dev *pctldev, unsigned fselector,
        return 0;
 }
 
-static void st_pmx_disable(struct pinctrl_dev *pctldev, unsigned selector,
-               unsigned group)
-{
-}
-
 static int st_pmx_set_gpio_direction(struct pinctrl_dev *pctldev,
                        struct pinctrl_gpio_range *range, unsigned gpio,
                        bool input)
@@ -957,7 +952,6 @@ static struct pinmux_ops st_pmxops = {
        .get_function_name      = st_pmx_get_fname,
        .get_function_groups    = st_pmx_get_groups,
        .enable                 = st_pmx_enable,
-       .disable                = st_pmx_disable,
        .gpio_set_direction     = st_pmx_set_gpio_direction,
 };
 
@@ -1178,9 +1172,7 @@ static int st_pctl_dt_parse_groups(struct device_node *np,
        const __be32 *list;
        struct property *pp;
        struct st_pinconf *conf;
-       phandle phandle;
        struct device_node *pins;
-       u32 pin;
        int i = 0, npins = 0, nr_props;
 
        pins = of_get_child_by_name(np, "st,pins");
@@ -1218,8 +1210,8 @@ static int st_pctl_dt_parse_groups(struct device_node *np,
                conf = &grp->pin_conf[i];
 
                /* bank & offset */
-               phandle = be32_to_cpup(list++);
-               pin = be32_to_cpup(list++);
+               be32_to_cpup(list++);
+               be32_to_cpup(list++);
                conf->pin = of_get_named_gpio(pins, pp->name, 0);
                conf->name = pp->name;
                grp->pins[i] = conf->pin;
@@ -1256,7 +1248,7 @@ static int st_pctl_parse_functions(struct device_node *np,
        func = &info->functions[index];
        func->name = np->name;
        func->ngroups = of_get_child_count(np);
-       if (func->ngroups <= 0) {
+       if (func->ngroups == 0) {
                dev_err(info->dev, "No groups defined\n");
                return -EINVAL;
        }
@@ -1454,6 +1446,7 @@ static struct irq_chip st_gpio_irqchip = {
        .irq_mask       = st_gpio_irq_mask,
        .irq_unmask     = st_gpio_irq_unmask,
        .irq_set_type   = st_gpio_irq_set_type,
+       .flags          = IRQCHIP_SKIP_SET_WAKE,
 };
 
 static int st_gpiolib_register_bank(struct st_pinctrl *info,
index 26ca6855f478d3018f79ab8aab87550e1eb52610..71c5d4f0c538ebbb192f963e3c6085b8bd4129cb 100644 (file)
@@ -738,22 +738,6 @@ static int tb10x_pctl_enable(struct pinctrl_dev *pctl,
        return 0;
 }
 
-static void tb10x_pctl_disable(struct pinctrl_dev *pctl,
-                       unsigned func_selector, unsigned group_selector)
-{
-       struct tb10x_pinctrl *state = pinctrl_dev_get_drvdata(pctl);
-       const struct tb10x_pinfuncgrp *grp = &state->pingroups[group_selector];
-
-       if (grp->port < 0)
-               return;
-
-       mutex_lock(&state->mutex);
-
-       state->ports[grp->port].count--;
-
-       mutex_unlock(&state->mutex);
-}
-
 static struct pinmux_ops tb10x_pinmux_ops = {
        .get_functions_count = tb10x_get_functions_count,
        .get_function_name = tb10x_get_function_name,
@@ -761,7 +745,6 @@ static struct pinmux_ops tb10x_pinmux_ops = {
        .gpio_request_enable = tb10x_gpio_request_enable,
        .gpio_disable_free = tb10x_gpio_disable_free,
        .enable = tb10x_pctl_enable,
-       .disable = tb10x_pctl_disable,
 };
 
 static struct pinctrl_desc tb10x_pindesc = {
index 2d43bff74f59bd98d33cb61f4d456849b6718f1c..150af5503c093015dd4d425ca81d64780fc3358a 100644 (file)
@@ -290,24 +290,11 @@ static int tegra_pinctrl_enable(struct pinctrl_dev *pctldev, unsigned function,
        return 0;
 }
 
-static void tegra_pinctrl_disable(struct pinctrl_dev *pctldev,
-                                 unsigned function, unsigned group)
-{
-       struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
-       const struct tegra_pingroup *g;
-
-       g = &pmx->soc->groups[group];
-
-       if (WARN_ON(g->mux_reg < 0))
-               return;
-}
-
 static const struct pinmux_ops tegra_pinmux_ops = {
        .get_functions_count = tegra_pinctrl_get_funcs_count,
        .get_function_name = tegra_pinctrl_get_func_name,
        .get_function_groups = tegra_pinctrl_get_func_groups,
        .enable = tegra_pinctrl_enable,
-       .disable = tegra_pinctrl_disable,
 };
 
 static int tegra_pinconf_reg(struct tegra_pmx *pmx,
index 5bf01c28925ea4e8d0725a43c06a480e0ed0e946..41e81a35cabb07b43a8372210f0bfe6f29be2aa5 100644 (file)
@@ -574,33 +574,6 @@ static int tz1090_pdc_pinctrl_enable(struct pinctrl_dev *pctldev,
        return 0;
 }
 
-static void tz1090_pdc_pinctrl_disable(struct pinctrl_dev *pctldev,
-                                      unsigned int function,
-                                      unsigned int group)
-{
-       struct tz1090_pdc_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
-       const struct tz1090_pdc_pingroup *grp = &tz1090_pdc_groups[group];
-
-       dev_dbg(pctldev->dev, "%s(func=%u (%s), group=%u (%s))\n",
-               __func__,
-               function, tz1090_pdc_functions[function].name,
-               group, tz1090_pdc_groups[group].name);
-
-       /* is it even a mux? */
-       if (grp->drv)
-               return;
-
-       /* does this group even control the function? */
-       if (function != grp->func)
-               return;
-
-       /* record the pin being unmuxed and update mux bit */
-       spin_lock(&pmx->lock);
-       pmx->mux_en &= ~BIT(grp->pins[0]);
-       tz1090_pdc_pinctrl_mux(pmx, grp);
-       spin_unlock(&pmx->lock);
-}
-
 static const struct tz1090_pdc_pingroup *find_mux_group(
                                                struct tz1090_pdc_pmx *pmx,
                                                unsigned int pin)
@@ -662,7 +635,6 @@ static struct pinmux_ops tz1090_pdc_pinmux_ops = {
        .get_function_name      = tz1090_pdc_pinctrl_get_func_name,
        .get_function_groups    = tz1090_pdc_pinctrl_get_func_groups,
        .enable                 = tz1090_pdc_pinctrl_enable,
-       .disable                = tz1090_pdc_pinctrl_disable,
        .gpio_request_enable    = tz1090_pdc_pinctrl_gpio_request_enable,
        .gpio_disable_free      = tz1090_pdc_pinctrl_gpio_disable_free,
 };
index bc9cd7a7602ea30d930d099519b8dfbb3590742a..24082216842e5e69379dd575a7e0350ecbeab9d0 100644 (file)
@@ -1478,63 +1478,6 @@ mux_pins:
        return 0;
 }
 
-/**
- * tz1090_pinctrl_disable() - Disable a function on a pin group.
- * @pctldev:           Pin control data
- * @function:          Function index to disable
- * @group:             Group index to disable
- *
- * Disable a particular function on a group of pins. The per GPIO pin pseudo pin
- * groups can be used (in which case the pin will be taken out of peripheral
- * mode. Some convenience pin groups can also be used in which case the effect
- * is the same as enabling the function on each individual pin in the group.
- */
-static void tz1090_pinctrl_disable(struct pinctrl_dev *pctldev,
-                                  unsigned int function, unsigned int group)
-{
-       struct tz1090_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
-       struct tz1090_pingroup *grp;
-       unsigned int pin_num, mux_group, i, npins;
-       const unsigned int *pins;
-
-       /* group of pins? */
-       if (group < ARRAY_SIZE(tz1090_groups)) {
-               grp = &tz1090_groups[group];
-               npins = grp->npins;
-               pins = grp->pins;
-               /*
-                * All pins in the group must belong to the same mux group,
-                * which allows us to just use the mux group of the first pin.
-                * By explicitly listing permitted pingroups for each function
-                * the pinmux core should ensure this is always the case.
-                */
-       } else {
-               pin_num = group - ARRAY_SIZE(tz1090_groups);
-               npins = 1;
-               pins = &pin_num;
-       }
-       mux_group = tz1090_mux_pins[*pins];
-
-       /* no mux group, but can still be individually muxed to peripheral */
-       if (mux_group >= TZ1090_MUX_GROUP_MAX) {
-               if (function == TZ1090_MUX_PERIP)
-                       goto unmux_pins;
-               return;
-       }
-
-       /* mux group already set to a different function? */
-       grp = &tz1090_mux_groups[mux_group];
-       dev_dbg(pctldev->dev, "%s: unmuxing %u pin(s) in '%s' from '%s'\n",
-               __func__, npins, grp->name, tz1090_functions[function].name);
-
-       /* subtract pins from ref count and unmux individually */
-       WARN_ON(grp->func_count < npins);
-       grp->func_count -= npins;
-unmux_pins:
-       for (i = 0; i < npins; ++i)
-               tz1090_pinctrl_perip_select(pmx, pins[i], false);
-}
-
 /**
  * tz1090_pinctrl_gpio_request_enable() - Put pin in GPIO mode.
  * @pctldev:           Pin control data
@@ -1575,7 +1518,6 @@ static struct pinmux_ops tz1090_pinmux_ops = {
        .get_function_name      = tz1090_pinctrl_get_func_name,
        .get_function_groups    = tz1090_pinctrl_get_func_groups,
        .enable                 = tz1090_pinctrl_enable,
-       .disable                = tz1090_pinctrl_disable,
        .gpio_request_enable    = tz1090_pinctrl_gpio_request_enable,
        .gpio_disable_free      = tz1090_pinctrl_gpio_disable_free,
 };
index 209a01b8bd3b84d9cbe2071a8007ef1caf7b3f0f..0959bb36450f79c09b7446e474aeedfac8014536 100644 (file)
@@ -970,19 +970,6 @@ static int u300_pmx_enable(struct pinctrl_dev *pctldev, unsigned selector,
        return 0;
 }
 
-static void u300_pmx_disable(struct pinctrl_dev *pctldev, unsigned selector,
-                            unsigned group)
-{
-       struct u300_pmx *upmx;
-
-       /* There is nothing to do with the power pins */
-       if (selector == 0)
-               return;
-
-       upmx = pinctrl_dev_get_drvdata(pctldev);
-       u300_pmx_endisable(upmx, selector, false);
-}
-
 static int u300_pmx_get_funcs_count(struct pinctrl_dev *pctldev)
 {
        return ARRAY_SIZE(u300_pmx_functions);
@@ -1008,7 +995,6 @@ static const struct pinmux_ops u300_pmx_ops = {
        .get_function_name = u300_pmx_get_func_name,
        .get_function_groups = u300_pmx_get_groups,
        .enable = u300_pmx_enable,
-       .disable = u300_pmx_disable,
 };
 
 static int u300_pin_config_get(struct pinctrl_dev *pctldev, unsigned pin,
index 051e8592990e9c9824563f8af789af05b1a5fdbf..c055daf9a80f0507e3e1004d648aa0e5131da8d4 100644 (file)
@@ -471,7 +471,6 @@ void pinmux_disable_setting(struct pinctrl_setting const *setting)
 {
        struct pinctrl_dev *pctldev = setting->pctldev;
        const struct pinctrl_ops *pctlops = pctldev->desc->pctlops;
-       const struct pinmux_ops *ops = pctldev->desc->pmxops;
        int ret = 0;
        const unsigned *pins = NULL;
        unsigned num_pins = 0;
@@ -518,9 +517,6 @@ void pinmux_disable_setting(struct pinctrl_setting const *setting)
                                 pins[i], desc->name, gname);
                }
        }
-
-       if (ops->disable)
-               ops->disable(pctldev, setting->data.mux.func, setting->data.mux.group);
 }
 
 #ifdef CONFIG_DEBUG_FS
diff --git a/drivers/pinctrl/qcom/Kconfig b/drivers/pinctrl/qcom/Kconfig
new file mode 100644 (file)
index 0000000..d160a71
--- /dev/null
@@ -0,0 +1,42 @@
+if (ARCH_QCOM || COMPILE_TEST)
+
+config PINCTRL_MSM
+       bool
+       select PINMUX
+       select PINCONF
+       select GENERIC_PINCONF
+       select GPIOLIB_IRQCHIP
+
+config PINCTRL_APQ8064
+       tristate "Qualcomm APQ8064 pin controller driver"
+       depends on GPIOLIB && OF
+       select PINCTRL_MSM
+       help
+         This is the pinctrl, pinmux, pinconf and gpiolib driver for the
+         Qualcomm TLMM block found in the Qualcomm APQ8064 platform.
+
+config PINCTRL_IPQ8064
+       tristate "Qualcomm IPQ8064 pin controller driver"
+       depends on GPIOLIB && OF
+       select PINCTRL_MSM
+       help
+         This is the pinctrl, pinmux, pinconf and gpiolib driver for the
+         Qualcomm TLMM block found in the Qualcomm IPQ8064 platform.
+
+config PINCTRL_MSM8960
+       tristate "Qualcomm 8960 pin controller driver"
+       depends on GPIOLIB && OF
+       select PINCTRL_MSM
+       help
+         This is the pinctrl, pinmux, pinconf and gpiolib driver for the
+         Qualcomm TLMM block found in the Qualcomm 8960 platform.
+
+config PINCTRL_MSM8X74
+       tristate "Qualcomm 8x74 pin controller driver"
+       depends on GPIOLIB && OF
+       select PINCTRL_MSM
+       help
+         This is the pinctrl, pinmux, pinconf and gpiolib driver for the
+         Qualcomm TLMM block found in the Qualcomm 8974 platform.
+
+endif
diff --git a/drivers/pinctrl/qcom/Makefile b/drivers/pinctrl/qcom/Makefile
new file mode 100644 (file)
index 0000000..2a02602
--- /dev/null
@@ -0,0 +1,6 @@
+# Qualcomm pin control drivers
+obj-$(CONFIG_PINCTRL_MSM)      += pinctrl-msm.o
+obj-$(CONFIG_PINCTRL_APQ8064)  += pinctrl-apq8064.o
+obj-$(CONFIG_PINCTRL_IPQ8064)  += pinctrl-ipq8064.o
+obj-$(CONFIG_PINCTRL_MSM8960)  += pinctrl-msm8960.o
+obj-$(CONFIG_PINCTRL_MSM8X74)  += pinctrl-msm8x74.o
diff --git a/drivers/pinctrl/qcom/pinctrl-apq8064.c b/drivers/pinctrl/qcom/pinctrl-apq8064.c
new file mode 100644 (file)
index 0000000..feb6f15
--- /dev/null
@@ -0,0 +1,630 @@
+/*
+ * Copyright (c) 2014, Sony Mobile Communications AB.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pinctrl/pinctrl.h>
+
+#include "pinctrl-msm.h"
+
+static const struct pinctrl_pin_desc apq8064_pins[] = {
+       PINCTRL_PIN(0, "GPIO_0"),
+       PINCTRL_PIN(1, "GPIO_1"),
+       PINCTRL_PIN(2, "GPIO_2"),
+       PINCTRL_PIN(3, "GPIO_3"),
+       PINCTRL_PIN(4, "GPIO_4"),
+       PINCTRL_PIN(5, "GPIO_5"),
+       PINCTRL_PIN(6, "GPIO_6"),
+       PINCTRL_PIN(7, "GPIO_7"),
+       PINCTRL_PIN(8, "GPIO_8"),
+       PINCTRL_PIN(9, "GPIO_9"),
+       PINCTRL_PIN(10, "GPIO_10"),
+       PINCTRL_PIN(11, "GPIO_11"),
+       PINCTRL_PIN(12, "GPIO_12"),
+       PINCTRL_PIN(13, "GPIO_13"),
+       PINCTRL_PIN(14, "GPIO_14"),
+       PINCTRL_PIN(15, "GPIO_15"),
+       PINCTRL_PIN(16, "GPIO_16"),
+       PINCTRL_PIN(17, "GPIO_17"),
+       PINCTRL_PIN(18, "GPIO_18"),
+       PINCTRL_PIN(19, "GPIO_19"),
+       PINCTRL_PIN(20, "GPIO_20"),
+       PINCTRL_PIN(21, "GPIO_21"),
+       PINCTRL_PIN(22, "GPIO_22"),
+       PINCTRL_PIN(23, "GPIO_23"),
+       PINCTRL_PIN(24, "GPIO_24"),
+       PINCTRL_PIN(25, "GPIO_25"),
+       PINCTRL_PIN(26, "GPIO_26"),
+       PINCTRL_PIN(27, "GPIO_27"),
+       PINCTRL_PIN(28, "GPIO_28"),
+       PINCTRL_PIN(29, "GPIO_29"),
+       PINCTRL_PIN(30, "GPIO_30"),
+       PINCTRL_PIN(31, "GPIO_31"),
+       PINCTRL_PIN(32, "GPIO_32"),
+       PINCTRL_PIN(33, "GPIO_33"),
+       PINCTRL_PIN(34, "GPIO_34"),
+       PINCTRL_PIN(35, "GPIO_35"),
+       PINCTRL_PIN(36, "GPIO_36"),
+       PINCTRL_PIN(37, "GPIO_37"),
+       PINCTRL_PIN(38, "GPIO_38"),
+       PINCTRL_PIN(39, "GPIO_39"),
+       PINCTRL_PIN(40, "GPIO_40"),
+       PINCTRL_PIN(41, "GPIO_41"),
+       PINCTRL_PIN(42, "GPIO_42"),
+       PINCTRL_PIN(43, "GPIO_43"),
+       PINCTRL_PIN(44, "GPIO_44"),
+       PINCTRL_PIN(45, "GPIO_45"),
+       PINCTRL_PIN(46, "GPIO_46"),
+       PINCTRL_PIN(47, "GPIO_47"),
+       PINCTRL_PIN(48, "GPIO_48"),
+       PINCTRL_PIN(49, "GPIO_49"),
+       PINCTRL_PIN(50, "GPIO_50"),
+       PINCTRL_PIN(51, "GPIO_51"),
+       PINCTRL_PIN(52, "GPIO_52"),
+       PINCTRL_PIN(53, "GPIO_53"),
+       PINCTRL_PIN(54, "GPIO_54"),
+       PINCTRL_PIN(55, "GPIO_55"),
+       PINCTRL_PIN(56, "GPIO_56"),
+       PINCTRL_PIN(57, "GPIO_57"),
+       PINCTRL_PIN(58, "GPIO_58"),
+       PINCTRL_PIN(59, "GPIO_59"),
+       PINCTRL_PIN(60, "GPIO_60"),
+       PINCTRL_PIN(61, "GPIO_61"),
+       PINCTRL_PIN(62, "GPIO_62"),
+       PINCTRL_PIN(63, "GPIO_63"),
+       PINCTRL_PIN(64, "GPIO_64"),
+       PINCTRL_PIN(65, "GPIO_65"),
+       PINCTRL_PIN(66, "GPIO_66"),
+       PINCTRL_PIN(67, "GPIO_67"),
+       PINCTRL_PIN(68, "GPIO_68"),
+       PINCTRL_PIN(69, "GPIO_69"),
+       PINCTRL_PIN(70, "GPIO_70"),
+       PINCTRL_PIN(71, "GPIO_71"),
+       PINCTRL_PIN(72, "GPIO_72"),
+       PINCTRL_PIN(73, "GPIO_73"),
+       PINCTRL_PIN(74, "GPIO_74"),
+       PINCTRL_PIN(75, "GPIO_75"),
+       PINCTRL_PIN(76, "GPIO_76"),
+       PINCTRL_PIN(77, "GPIO_77"),
+       PINCTRL_PIN(78, "GPIO_78"),
+       PINCTRL_PIN(79, "GPIO_79"),
+       PINCTRL_PIN(80, "GPIO_80"),
+       PINCTRL_PIN(81, "GPIO_81"),
+       PINCTRL_PIN(82, "GPIO_82"),
+       PINCTRL_PIN(83, "GPIO_83"),
+       PINCTRL_PIN(84, "GPIO_84"),
+       PINCTRL_PIN(85, "GPIO_85"),
+       PINCTRL_PIN(86, "GPIO_86"),
+       PINCTRL_PIN(87, "GPIO_87"),
+       PINCTRL_PIN(88, "GPIO_88"),
+       PINCTRL_PIN(89, "GPIO_89"),
+
+       PINCTRL_PIN(90, "SDC1_CLK"),
+       PINCTRL_PIN(91, "SDC1_CMD"),
+       PINCTRL_PIN(92, "SDC1_DATA"),
+       PINCTRL_PIN(93, "SDC3_CLK"),
+       PINCTRL_PIN(94, "SDC3_CMD"),
+       PINCTRL_PIN(95, "SDC3_DATA"),
+};
+
+#define DECLARE_APQ_GPIO_PINS(pin) static const unsigned int gpio##pin##_pins[] = { pin }
+DECLARE_APQ_GPIO_PINS(0);
+DECLARE_APQ_GPIO_PINS(1);
+DECLARE_APQ_GPIO_PINS(2);
+DECLARE_APQ_GPIO_PINS(3);
+DECLARE_APQ_GPIO_PINS(4);
+DECLARE_APQ_GPIO_PINS(5);
+DECLARE_APQ_GPIO_PINS(6);
+DECLARE_APQ_GPIO_PINS(7);
+DECLARE_APQ_GPIO_PINS(8);
+DECLARE_APQ_GPIO_PINS(9);
+DECLARE_APQ_GPIO_PINS(10);
+DECLARE_APQ_GPIO_PINS(11);
+DECLARE_APQ_GPIO_PINS(12);
+DECLARE_APQ_GPIO_PINS(13);
+DECLARE_APQ_GPIO_PINS(14);
+DECLARE_APQ_GPIO_PINS(15);
+DECLARE_APQ_GPIO_PINS(16);
+DECLARE_APQ_GPIO_PINS(17);
+DECLARE_APQ_GPIO_PINS(18);
+DECLARE_APQ_GPIO_PINS(19);
+DECLARE_APQ_GPIO_PINS(20);
+DECLARE_APQ_GPIO_PINS(21);
+DECLARE_APQ_GPIO_PINS(22);
+DECLARE_APQ_GPIO_PINS(23);
+DECLARE_APQ_GPIO_PINS(24);
+DECLARE_APQ_GPIO_PINS(25);
+DECLARE_APQ_GPIO_PINS(26);
+DECLARE_APQ_GPIO_PINS(27);
+DECLARE_APQ_GPIO_PINS(28);
+DECLARE_APQ_GPIO_PINS(29);
+DECLARE_APQ_GPIO_PINS(30);
+DECLARE_APQ_GPIO_PINS(31);
+DECLARE_APQ_GPIO_PINS(32);
+DECLARE_APQ_GPIO_PINS(33);
+DECLARE_APQ_GPIO_PINS(34);
+DECLARE_APQ_GPIO_PINS(35);
+DECLARE_APQ_GPIO_PINS(36);
+DECLARE_APQ_GPIO_PINS(37);
+DECLARE_APQ_GPIO_PINS(38);
+DECLARE_APQ_GPIO_PINS(39);
+DECLARE_APQ_GPIO_PINS(40);
+DECLARE_APQ_GPIO_PINS(41);
+DECLARE_APQ_GPIO_PINS(42);
+DECLARE_APQ_GPIO_PINS(43);
+DECLARE_APQ_GPIO_PINS(44);
+DECLARE_APQ_GPIO_PINS(45);
+DECLARE_APQ_GPIO_PINS(46);
+DECLARE_APQ_GPIO_PINS(47);
+DECLARE_APQ_GPIO_PINS(48);
+DECLARE_APQ_GPIO_PINS(49);
+DECLARE_APQ_GPIO_PINS(50);
+DECLARE_APQ_GPIO_PINS(51);
+DECLARE_APQ_GPIO_PINS(52);
+DECLARE_APQ_GPIO_PINS(53);
+DECLARE_APQ_GPIO_PINS(54);
+DECLARE_APQ_GPIO_PINS(55);
+DECLARE_APQ_GPIO_PINS(56);
+DECLARE_APQ_GPIO_PINS(57);
+DECLARE_APQ_GPIO_PINS(58);
+DECLARE_APQ_GPIO_PINS(59);
+DECLARE_APQ_GPIO_PINS(60);
+DECLARE_APQ_GPIO_PINS(61);
+DECLARE_APQ_GPIO_PINS(62);
+DECLARE_APQ_GPIO_PINS(63);
+DECLARE_APQ_GPIO_PINS(64);
+DECLARE_APQ_GPIO_PINS(65);
+DECLARE_APQ_GPIO_PINS(66);
+DECLARE_APQ_GPIO_PINS(67);
+DECLARE_APQ_GPIO_PINS(68);
+DECLARE_APQ_GPIO_PINS(69);
+DECLARE_APQ_GPIO_PINS(70);
+DECLARE_APQ_GPIO_PINS(71);
+DECLARE_APQ_GPIO_PINS(72);
+DECLARE_APQ_GPIO_PINS(73);
+DECLARE_APQ_GPIO_PINS(74);
+DECLARE_APQ_GPIO_PINS(75);
+DECLARE_APQ_GPIO_PINS(76);
+DECLARE_APQ_GPIO_PINS(77);
+DECLARE_APQ_GPIO_PINS(78);
+DECLARE_APQ_GPIO_PINS(79);
+DECLARE_APQ_GPIO_PINS(80);
+DECLARE_APQ_GPIO_PINS(81);
+DECLARE_APQ_GPIO_PINS(82);
+DECLARE_APQ_GPIO_PINS(83);
+DECLARE_APQ_GPIO_PINS(84);
+DECLARE_APQ_GPIO_PINS(85);
+DECLARE_APQ_GPIO_PINS(86);
+DECLARE_APQ_GPIO_PINS(87);
+DECLARE_APQ_GPIO_PINS(88);
+DECLARE_APQ_GPIO_PINS(89);
+
+static const unsigned int sdc1_clk_pins[] = { 90 };
+static const unsigned int sdc1_cmd_pins[] = { 91 };
+static const unsigned int sdc1_data_pins[] = { 92 };
+static const unsigned int sdc3_clk_pins[] = { 93 };
+static const unsigned int sdc3_cmd_pins[] = { 94 };
+static const unsigned int sdc3_data_pins[] = { 95 };
+
+#define FUNCTION(fname)                                        \
+       [APQ_MUX_##fname] = {                           \
+               .name = #fname,                         \
+               .groups = fname##_groups,               \
+               .ngroups = ARRAY_SIZE(fname##_groups),  \
+       }
+
+#define PINGROUP(id, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10) \
+       {                                               \
+               .name = "gpio" #id,                     \
+               .pins = gpio##id##_pins,                \
+               .npins = ARRAY_SIZE(gpio##id##_pins),   \
+               .funcs = (int[]){                       \
+                       APQ_MUX_gpio,                   \
+                       APQ_MUX_##f1,                   \
+                       APQ_MUX_##f2,                   \
+                       APQ_MUX_##f3,                   \
+                       APQ_MUX_##f4,                   \
+                       APQ_MUX_##f5,                   \
+                       APQ_MUX_##f6,                   \
+                       APQ_MUX_##f7,                   \
+                       APQ_MUX_##f8,                   \
+                       APQ_MUX_##f9,                   \
+                       APQ_MUX_##f10,                  \
+               },                                      \
+               .nfuncs = 11,                           \
+               .ctl_reg = 0x1000 + 0x10 * id,          \
+               .io_reg = 0x1004 + 0x10 * id,           \
+               .intr_cfg_reg = 0x1008 + 0x10 * id,     \
+               .intr_status_reg = 0x100c + 0x10 * id,  \
+               .intr_target_reg = 0x400 + 0x4 * id,    \
+               .mux_bit = 2,                           \
+               .pull_bit = 0,                          \
+               .drv_bit = 6,                           \
+               .oe_bit = 9,                            \
+               .in_bit = 0,                            \
+               .out_bit = 1,                           \
+               .intr_enable_bit = 0,                   \
+               .intr_status_bit = 0,                   \
+               .intr_ack_high = 1,                     \
+               .intr_target_bit = 0,                   \
+               .intr_raw_status_bit = 3,               \
+               .intr_polarity_bit = 1,                 \
+               .intr_detection_bit = 2,                \
+               .intr_detection_width = 1,              \
+       }
+
+#define SDC_PINGROUP(pg_name, ctl, pull, drv)          \
+       {                                               \
+               .name = #pg_name,                       \
+               .pins = pg_name##_pins,                 \
+               .npins = ARRAY_SIZE(pg_name##_pins),    \
+               .ctl_reg = ctl,                         \
+               .io_reg = 0,                            \
+               .intr_cfg_reg = 0,                      \
+               .intr_status_reg = 0,                   \
+               .intr_target_reg = 0,                   \
+               .mux_bit = -1,                          \
+               .pull_bit = pull,                       \
+               .drv_bit = drv,                         \
+               .oe_bit = -1,                           \
+               .in_bit = -1,                           \
+               .out_bit = -1,                          \
+               .intr_enable_bit = -1,                  \
+               .intr_status_bit = -1,                  \
+               .intr_target_bit = -1,                  \
+               .intr_raw_status_bit = -1,              \
+               .intr_polarity_bit = -1,                \
+               .intr_detection_bit = -1,               \
+               .intr_detection_width = -1,             \
+       }
+
+enum apq8064_functions {
+       APQ_MUX_cam_mclk,
+       APQ_MUX_codec_mic_i2s,
+       APQ_MUX_codec_spkr_i2s,
+       APQ_MUX_gpio,
+       APQ_MUX_gsbi1,
+       APQ_MUX_gsbi2,
+       APQ_MUX_gsbi3,
+       APQ_MUX_gsbi4,
+       APQ_MUX_gsbi4_cam_i2c,
+       APQ_MUX_gsbi5,
+       APQ_MUX_gsbi5_spi_cs1,
+       APQ_MUX_gsbi5_spi_cs2,
+       APQ_MUX_gsbi5_spi_cs3,
+       APQ_MUX_gsbi6,
+       APQ_MUX_gsbi6_spi_cs1,
+       APQ_MUX_gsbi6_spi_cs2,
+       APQ_MUX_gsbi6_spi_cs3,
+       APQ_MUX_gsbi7,
+       APQ_MUX_gsbi7_spi_cs1,
+       APQ_MUX_gsbi7_spi_cs2,
+       APQ_MUX_gsbi7_spi_cs3,
+       APQ_MUX_gsbi_cam_i2c,
+       APQ_MUX_hdmi,
+       APQ_MUX_mi2s,
+       APQ_MUX_riva_bt,
+       APQ_MUX_riva_fm,
+       APQ_MUX_riva_wlan,
+       APQ_MUX_sdc2,
+       APQ_MUX_sdc4,
+       APQ_MUX_slimbus,
+       APQ_MUX_spkr_i2s,
+       APQ_MUX_tsif1,
+       APQ_MUX_tsif2,
+       APQ_MUX_usb2_hsic,
+       APQ_MUX_NA,
+};
+
+static const char * const cam_mclk_groups[] = {
+       "gpio4" "gpio5"
+};
+static const char * const codec_mic_i2s_groups[] = {
+       "gpio34", "gpio35", "gpio36", "gpio37", "gpio38"
+};
+static const char * const codec_spkr_i2s_groups[] = {
+       "gpio39", "gpio40", "gpio41", "gpio42"
+};
+static const char * const gpio_groups[] = {
+       "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5", "gpio6", "gpio7",
+       "gpio8", "gpio9", "gpio10", "gpio11", "gpio12", "gpio13", "gpio14",
+       "gpio15", "gpio16", "gpio17", "gpio18", "gpio19", "gpio20", "gpio21",
+       "gpio22", "gpio23", "gpio24", "gpio25", "gpio26", "gpio27", "gpio28",
+       "gpio29", "gpio30", "gpio31", "gpio32", "gpio33", "gpio34", "gpio35",
+       "gpio36", "gpio37", "gpio38", "gpio39", "gpio40", "gpio41", "gpio42",
+       "gpio43", "gpio44", "gpio45", "gpio46", "gpio47", "gpio48", "gpio49",
+       "gpio50", "gpio51", "gpio52", "gpio53", "gpio54", "gpio55", "gpio56",
+       "gpio57", "gpio58", "gpio59", "gpio60", "gpio61", "gpio62", "gpio63",
+       "gpio64", "gpio65", "gpio66", "gpio67", "gpio68", "gpio69", "gpio70",
+       "gpio71", "gpio72", "gpio73", "gpio74", "gpio75", "gpio76", "gpio77",
+       "gpio78", "gpio79", "gpio80", "gpio81", "gpio82", "gpio83", "gpio84",
+       "gpio85", "gpio86", "gpio87", "gpio88", "gpio89"
+};
+static const char * const gsbi1_groups[] = {
+       "gpio18", "gpio19", "gpio20", "gpio21"
+};
+static const char * const gsbi2_groups[] = {
+       "gpio22", "gpio23", "gpio24", "gpio25"
+};
+static const char * const gsbi3_groups[] = {
+       "gpio6", "gpio7", "gpio8", "gpio9"
+};
+static const char * const gsbi4_groups[] = {
+       "gpio10", "gpio11", "gpio12", "gpio13"
+};
+static const char * const gsbi4_cam_i2c_groups[] = {
+       "gpio10", "gpio11", "gpio12", "gpio13"
+};
+static const char * const gsbi5_groups[] = {
+       "gpio51", "gpio52", "gpio53", "gpio54"
+};
+static const char * const gsbi5_spi_cs1_groups[] = {
+       "gpio47"
+};
+static const char * const gsbi5_spi_cs2_groups[] = {
+       "gpio31"
+};
+static const char * const gsbi5_spi_cs3_groups[] = {
+       "gpio32"
+};
+static const char * const gsbi6_groups[] = {
+       "gpio14", "gpio15", "gpio16", "gpio17"
+};
+static const char * const gsbi6_spi_cs1_groups[] = {
+       "gpio47"
+};
+static const char * const gsbi6_spi_cs2_groups[] = {
+       "gpio31"
+};
+static const char * const gsbi6_spi_cs3_groups[] = {
+       "gpio32"
+};
+static const char * const gsbi7_groups[] = {
+       "gpio82", "gpio83", "gpio84", "gpio85"
+};
+static const char * const gsbi7_spi_cs1_groups[] = {
+       "gpio47"
+};
+static const char * const gsbi7_spi_cs2_groups[] = {
+       "gpio31"
+};
+static const char * const gsbi7_spi_cs3_groups[] = {
+       "gpio32"
+};
+static const char * const gsbi_cam_i2c_groups[] = {
+       "gpio10", "gpio11", "gpio12", "gpio13"
+};
+static const char * const hdmi_groups[] = {
+       "gpio69", "gpio70", "gpio71", "gpio72"
+};
+static const char * const mi2s_groups[] = {
+       "gpio27", "gpio28", "gpio29", "gpio30", "gpio31", "gpio32", "gpio33"
+};
+static const char * const riva_bt_groups[] = {
+       "gpio16", "gpio17"
+};
+static const char * const riva_fm_groups[] = {
+       "gpio14", "gpio15"
+};
+static const char * const riva_wlan_groups[] = {
+       "gpio64", "gpio65", "gpio66", "gpio67", "gpio68"
+};
+static const char * const sdc2_groups[] = {
+       "gpio57", "gpio58", "gpio59", "gpio60", "gpio61", "gpio62"
+};
+static const char * const sdc4_groups[] = {
+       "gpio63", "gpio64", "gpio65", "gpio66", "gpio67", "gpio68"
+};
+static const char * const slimbus_groups[] = {
+       "gpio40", "gpio41"
+};
+static const char * const spkr_i2s_groups[] = {
+       "gpio47", "gpio48", "gpio49", "gpio50"
+};
+static const char * const tsif1_groups[] = {
+       "gpio55", "gpio56", "gpio57"
+};
+static const char * const tsif2_groups[] = {
+       "gpio58", "gpio59", "gpio60"
+};
+static const char * const usb2_hsic_groups[] = {
+       "gpio88", "gpio89"
+};
+
+static const struct msm_function apq8064_functions[] = {
+       FUNCTION(cam_mclk),
+       FUNCTION(codec_mic_i2s),
+       FUNCTION(codec_spkr_i2s),
+       FUNCTION(gpio),
+       FUNCTION(gsbi1),
+       FUNCTION(gsbi2),
+       FUNCTION(gsbi3),
+       FUNCTION(gsbi4),
+       FUNCTION(gsbi4_cam_i2c),
+       FUNCTION(gsbi5),
+       FUNCTION(gsbi5_spi_cs1),
+       FUNCTION(gsbi5_spi_cs2),
+       FUNCTION(gsbi5_spi_cs3),
+       FUNCTION(gsbi6),
+       FUNCTION(gsbi6_spi_cs1),
+       FUNCTION(gsbi6_spi_cs2),
+       FUNCTION(gsbi6_spi_cs3),
+       FUNCTION(gsbi7),
+       FUNCTION(gsbi7_spi_cs1),
+       FUNCTION(gsbi7_spi_cs2),
+       FUNCTION(gsbi7_spi_cs3),
+       FUNCTION(gsbi_cam_i2c),
+       FUNCTION(hdmi),
+       FUNCTION(mi2s),
+       FUNCTION(riva_bt),
+       FUNCTION(riva_fm),
+       FUNCTION(riva_wlan),
+       FUNCTION(sdc2),
+       FUNCTION(sdc4),
+       FUNCTION(slimbus),
+       FUNCTION(spkr_i2s),
+       FUNCTION(tsif1),
+       FUNCTION(tsif2),
+       FUNCTION(usb2_hsic),
+};
+
+static const struct msm_pingroup apq8064_groups[] = {
+       PINGROUP(0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(2, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(3, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(4, NA, NA, cam_mclk, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(5, NA, cam_mclk, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(6, gsbi3, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(7, gsbi3, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(8, gsbi3, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(9, gsbi3, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(10, gsbi4, NA, NA, NA, NA, NA, NA, NA, gsbi4_cam_i2c, NA),
+       PINGROUP(11, gsbi4, NA, NA, NA, NA, NA, NA, NA, NA, gsbi4_cam_i2c),
+       PINGROUP(12, gsbi4, NA, NA, NA, NA, gsbi4_cam_i2c, NA, NA, NA, NA),
+       PINGROUP(13, gsbi4, NA, NA, NA, NA, gsbi4_cam_i2c, NA, NA, NA, NA),
+       PINGROUP(14, riva_fm, gsbi6, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(15, riva_fm, gsbi6, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(16, riva_bt, gsbi6, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(17, riva_bt, gsbi6, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(18, gsbi1, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(19, gsbi1, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(20, gsbi1, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(21, gsbi1, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(22, gsbi2, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(23, gsbi2, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(24, gsbi2, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(25, gsbi2, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(26, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(27, mi2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(28, mi2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(29, mi2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(30, mi2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(31, mi2s, NA, gsbi5_spi_cs2, gsbi6_spi_cs2, gsbi7_spi_cs2, NA, NA, NA, NA, NA),
+       PINGROUP(32, mi2s, NA, NA, NA, NA, gsbi5_spi_cs3, gsbi6_spi_cs3, gsbi7_spi_cs3, NA, NA),
+       PINGROUP(33, mi2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(34, codec_mic_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(35, codec_mic_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(36, codec_mic_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(37, codec_mic_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(38, codec_mic_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(39, codec_spkr_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(40, slimbus, codec_spkr_i2s, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(41, slimbus, codec_spkr_i2s, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(42, codec_spkr_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(43, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(44, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(45, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(46, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(47, spkr_i2s, gsbi5_spi_cs1, gsbi6_spi_cs1, gsbi7_spi_cs1, NA, NA, NA, NA, NA, NA),
+       PINGROUP(48, spkr_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(49, spkr_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(50, spkr_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(51, NA, gsbi5, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(52, NA, gsbi5, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(53, NA, gsbi5, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(54, NA, gsbi5, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(55, tsif1, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(56, tsif1, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(57, tsif1, sdc2, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(58, tsif2, sdc2, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(59, tsif2, sdc2, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(60, tsif2, sdc2, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(61, NA, sdc2, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(62, NA, sdc2, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(63, NA, sdc4, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(64, riva_wlan, sdc4, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(65, riva_wlan, sdc4, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(66, riva_wlan, sdc4, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(67, riva_wlan, sdc4, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(68, riva_wlan, sdc4, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(69, hdmi, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(70, hdmi, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(71, hdmi, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(72, hdmi, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(73, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(74, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(75, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(76, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(77, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(78, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(79, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(80, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(81, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(82, NA, gsbi7, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(83, gsbi7, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(84, NA, gsbi7, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(85, NA, NA, gsbi7, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(86, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(87, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(88, usb2_hsic, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(89, usb2_hsic, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+
+       SDC_PINGROUP(sdc1_clk, 0x20a0, 13, 6),
+       SDC_PINGROUP(sdc1_cmd, 0x20a0, 11, 3),
+       SDC_PINGROUP(sdc1_data, 0x20a0, 9, 0),
+
+       SDC_PINGROUP(sdc3_clk, 0x20a4, 14, 6),
+       SDC_PINGROUP(sdc3_cmd, 0x20a4, 11, 3),
+       SDC_PINGROUP(sdc3_data, 0x20a4, 9, 0),
+};
+
+#define NUM_GPIO_PINGROUPS 90
+
+static const struct msm_pinctrl_soc_data apq8064_pinctrl = {
+       .pins = apq8064_pins,
+       .npins = ARRAY_SIZE(apq8064_pins),
+       .functions = apq8064_functions,
+       .nfunctions = ARRAY_SIZE(apq8064_functions),
+       .groups = apq8064_groups,
+       .ngroups = ARRAY_SIZE(apq8064_groups),
+       .ngpios = NUM_GPIO_PINGROUPS,
+};
+
+static int apq8064_pinctrl_probe(struct platform_device *pdev)
+{
+       return msm_pinctrl_probe(pdev, &apq8064_pinctrl);
+}
+
+static const struct of_device_id apq8064_pinctrl_of_match[] = {
+       { .compatible = "qcom,apq8064-pinctrl", },
+       { },
+};
+
+static struct platform_driver apq8064_pinctrl_driver = {
+       .driver = {
+               .name = "apq8064-pinctrl",
+               .owner = THIS_MODULE,
+               .of_match_table = apq8064_pinctrl_of_match,
+       },
+       .probe = apq8064_pinctrl_probe,
+       .remove = msm_pinctrl_remove,
+};
+
+static int __init apq8064_pinctrl_init(void)
+{
+       return platform_driver_register(&apq8064_pinctrl_driver);
+}
+arch_initcall(apq8064_pinctrl_init);
+
+static void __exit apq8064_pinctrl_exit(void)
+{
+       platform_driver_unregister(&apq8064_pinctrl_driver);
+}
+module_exit(apq8064_pinctrl_exit);
+
+MODULE_AUTHOR("Bjorn Andersson <bjorn.andersson@sonymobile.com>");
+MODULE_DESCRIPTION("Qualcomm APQ8064 pinctrl driver");
+MODULE_LICENSE("GPL v2");
+MODULE_DEVICE_TABLE(of, apq8064_pinctrl_of_match);
diff --git a/drivers/pinctrl/qcom/pinctrl-ipq8064.c b/drivers/pinctrl/qcom/pinctrl-ipq8064.c
new file mode 100644 (file)
index 0000000..767cf11
--- /dev/null
@@ -0,0 +1,668 @@
+/*
+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pinctrl/pinctrl.h>
+
+#include "pinctrl-msm.h"
+
+static const struct pinctrl_pin_desc ipq8064_pins[] = {
+       PINCTRL_PIN(0, "GPIO_0"),
+       PINCTRL_PIN(1, "GPIO_1"),
+       PINCTRL_PIN(2, "GPIO_2"),
+       PINCTRL_PIN(3, "GPIO_3"),
+       PINCTRL_PIN(4, "GPIO_4"),
+       PINCTRL_PIN(5, "GPIO_5"),
+       PINCTRL_PIN(6, "GPIO_6"),
+       PINCTRL_PIN(7, "GPIO_7"),
+       PINCTRL_PIN(8, "GPIO_8"),
+       PINCTRL_PIN(9, "GPIO_9"),
+       PINCTRL_PIN(10, "GPIO_10"),
+       PINCTRL_PIN(11, "GPIO_11"),
+       PINCTRL_PIN(12, "GPIO_12"),
+       PINCTRL_PIN(13, "GPIO_13"),
+       PINCTRL_PIN(14, "GPIO_14"),
+       PINCTRL_PIN(15, "GPIO_15"),
+       PINCTRL_PIN(16, "GPIO_16"),
+       PINCTRL_PIN(17, "GPIO_17"),
+       PINCTRL_PIN(18, "GPIO_18"),
+       PINCTRL_PIN(19, "GPIO_19"),
+       PINCTRL_PIN(20, "GPIO_20"),
+       PINCTRL_PIN(21, "GPIO_21"),
+       PINCTRL_PIN(22, "GPIO_22"),
+       PINCTRL_PIN(23, "GPIO_23"),
+       PINCTRL_PIN(24, "GPIO_24"),
+       PINCTRL_PIN(25, "GPIO_25"),
+       PINCTRL_PIN(26, "GPIO_26"),
+       PINCTRL_PIN(27, "GPIO_27"),
+       PINCTRL_PIN(28, "GPIO_28"),
+       PINCTRL_PIN(29, "GPIO_29"),
+       PINCTRL_PIN(30, "GPIO_30"),
+       PINCTRL_PIN(31, "GPIO_31"),
+       PINCTRL_PIN(32, "GPIO_32"),
+       PINCTRL_PIN(33, "GPIO_33"),
+       PINCTRL_PIN(34, "GPIO_34"),
+       PINCTRL_PIN(35, "GPIO_35"),
+       PINCTRL_PIN(36, "GPIO_36"),
+       PINCTRL_PIN(37, "GPIO_37"),
+       PINCTRL_PIN(38, "GPIO_38"),
+       PINCTRL_PIN(39, "GPIO_39"),
+       PINCTRL_PIN(40, "GPIO_40"),
+       PINCTRL_PIN(41, "GPIO_41"),
+       PINCTRL_PIN(42, "GPIO_42"),
+       PINCTRL_PIN(43, "GPIO_43"),
+       PINCTRL_PIN(44, "GPIO_44"),
+       PINCTRL_PIN(45, "GPIO_45"),
+       PINCTRL_PIN(46, "GPIO_46"),
+       PINCTRL_PIN(47, "GPIO_47"),
+       PINCTRL_PIN(48, "GPIO_48"),
+       PINCTRL_PIN(49, "GPIO_49"),
+       PINCTRL_PIN(50, "GPIO_50"),
+       PINCTRL_PIN(51, "GPIO_51"),
+       PINCTRL_PIN(52, "GPIO_52"),
+       PINCTRL_PIN(53, "GPIO_53"),
+       PINCTRL_PIN(54, "GPIO_54"),
+       PINCTRL_PIN(55, "GPIO_55"),
+       PINCTRL_PIN(56, "GPIO_56"),
+       PINCTRL_PIN(57, "GPIO_57"),
+       PINCTRL_PIN(58, "GPIO_58"),
+       PINCTRL_PIN(59, "GPIO_59"),
+       PINCTRL_PIN(60, "GPIO_60"),
+       PINCTRL_PIN(61, "GPIO_61"),
+       PINCTRL_PIN(62, "GPIO_62"),
+       PINCTRL_PIN(63, "GPIO_63"),
+       PINCTRL_PIN(64, "GPIO_64"),
+       PINCTRL_PIN(65, "GPIO_65"),
+       PINCTRL_PIN(66, "GPIO_66"),
+       PINCTRL_PIN(67, "GPIO_67"),
+       PINCTRL_PIN(68, "GPIO_68"),
+
+       PINCTRL_PIN(69, "SDC3_CLK"),
+       PINCTRL_PIN(70, "SDC3_CMD"),
+       PINCTRL_PIN(71, "SDC3_DATA"),
+};
+
+#define DECLARE_IPQ_GPIO_PINS(pin) static const unsigned int gpio##pin##_pins[] = { pin }
+DECLARE_IPQ_GPIO_PINS(0);
+DECLARE_IPQ_GPIO_PINS(1);
+DECLARE_IPQ_GPIO_PINS(2);
+DECLARE_IPQ_GPIO_PINS(3);
+DECLARE_IPQ_GPIO_PINS(4);
+DECLARE_IPQ_GPIO_PINS(5);
+DECLARE_IPQ_GPIO_PINS(6);
+DECLARE_IPQ_GPIO_PINS(7);
+DECLARE_IPQ_GPIO_PINS(8);
+DECLARE_IPQ_GPIO_PINS(9);
+DECLARE_IPQ_GPIO_PINS(10);
+DECLARE_IPQ_GPIO_PINS(11);
+DECLARE_IPQ_GPIO_PINS(12);
+DECLARE_IPQ_GPIO_PINS(13);
+DECLARE_IPQ_GPIO_PINS(14);
+DECLARE_IPQ_GPIO_PINS(15);
+DECLARE_IPQ_GPIO_PINS(16);
+DECLARE_IPQ_GPIO_PINS(17);
+DECLARE_IPQ_GPIO_PINS(18);
+DECLARE_IPQ_GPIO_PINS(19);
+DECLARE_IPQ_GPIO_PINS(20);
+DECLARE_IPQ_GPIO_PINS(21);
+DECLARE_IPQ_GPIO_PINS(22);
+DECLARE_IPQ_GPIO_PINS(23);
+DECLARE_IPQ_GPIO_PINS(24);
+DECLARE_IPQ_GPIO_PINS(25);
+DECLARE_IPQ_GPIO_PINS(26);
+DECLARE_IPQ_GPIO_PINS(27);
+DECLARE_IPQ_GPIO_PINS(28);
+DECLARE_IPQ_GPIO_PINS(29);
+DECLARE_IPQ_GPIO_PINS(30);
+DECLARE_IPQ_GPIO_PINS(31);
+DECLARE_IPQ_GPIO_PINS(32);
+DECLARE_IPQ_GPIO_PINS(33);
+DECLARE_IPQ_GPIO_PINS(34);
+DECLARE_IPQ_GPIO_PINS(35);
+DECLARE_IPQ_GPIO_PINS(36);
+DECLARE_IPQ_GPIO_PINS(37);
+DECLARE_IPQ_GPIO_PINS(38);
+DECLARE_IPQ_GPIO_PINS(39);
+DECLARE_IPQ_GPIO_PINS(40);
+DECLARE_IPQ_GPIO_PINS(41);
+DECLARE_IPQ_GPIO_PINS(42);
+DECLARE_IPQ_GPIO_PINS(43);
+DECLARE_IPQ_GPIO_PINS(44);
+DECLARE_IPQ_GPIO_PINS(45);
+DECLARE_IPQ_GPIO_PINS(46);
+DECLARE_IPQ_GPIO_PINS(47);
+DECLARE_IPQ_GPIO_PINS(48);
+DECLARE_IPQ_GPIO_PINS(49);
+DECLARE_IPQ_GPIO_PINS(50);
+DECLARE_IPQ_GPIO_PINS(51);
+DECLARE_IPQ_GPIO_PINS(52);
+DECLARE_IPQ_GPIO_PINS(53);
+DECLARE_IPQ_GPIO_PINS(54);
+DECLARE_IPQ_GPIO_PINS(55);
+DECLARE_IPQ_GPIO_PINS(56);
+DECLARE_IPQ_GPIO_PINS(57);
+DECLARE_IPQ_GPIO_PINS(58);
+DECLARE_IPQ_GPIO_PINS(59);
+DECLARE_IPQ_GPIO_PINS(60);
+DECLARE_IPQ_GPIO_PINS(61);
+DECLARE_IPQ_GPIO_PINS(62);
+DECLARE_IPQ_GPIO_PINS(63);
+DECLARE_IPQ_GPIO_PINS(64);
+DECLARE_IPQ_GPIO_PINS(65);
+DECLARE_IPQ_GPIO_PINS(66);
+DECLARE_IPQ_GPIO_PINS(67);
+DECLARE_IPQ_GPIO_PINS(68);
+
+static const unsigned int sdc3_clk_pins[] = { 69 };
+static const unsigned int sdc3_cmd_pins[] = { 70 };
+static const unsigned int sdc3_data_pins[] = { 71 };
+
+#define FUNCTION(fname)                                        \
+       [IPQ_MUX_##fname] = {                           \
+               .name = #fname,                         \
+               .groups = fname##_groups,               \
+               .ngroups = ARRAY_SIZE(fname##_groups),  \
+       }
+
+#define PINGROUP(id, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10) \
+       {                                               \
+               .name = "gpio" #id,                     \
+               .pins = gpio##id##_pins,                \
+               .npins = ARRAY_SIZE(gpio##id##_pins),   \
+               .funcs = (int[]){                       \
+                       IPQ_MUX_gpio,                   \
+                       IPQ_MUX_##f1,                   \
+                       IPQ_MUX_##f2,                   \
+                       IPQ_MUX_##f3,                   \
+                       IPQ_MUX_##f4,                   \
+                       IPQ_MUX_##f5,                   \
+                       IPQ_MUX_##f6,                   \
+                       IPQ_MUX_##f7,                   \
+                       IPQ_MUX_##f8,                   \
+                       IPQ_MUX_##f9,                   \
+                       IPQ_MUX_##f10,                  \
+               },                                      \
+               .nfuncs = 11,                           \
+               .ctl_reg = 0x1000 + 0x10 * id,          \
+               .io_reg = 0x1004 + 0x10 * id,           \
+               .intr_cfg_reg = 0x1008 + 0x10 * id,     \
+               .intr_status_reg = 0x100c + 0x10 * id,  \
+               .intr_target_reg = 0x400 + 0x4 * id,    \
+               .mux_bit = 2,                           \
+               .pull_bit = 0,                          \
+               .drv_bit = 6,                           \
+               .oe_bit = 9,                            \
+               .in_bit = 0,                            \
+               .out_bit = 1,                           \
+               .intr_enable_bit = 0,                   \
+               .intr_status_bit = 0,                   \
+               .intr_ack_high = 1,                     \
+               .intr_target_bit = 0,                   \
+               .intr_raw_status_bit = 3,               \
+               .intr_polarity_bit = 1,                 \
+               .intr_detection_bit = 2,                \
+               .intr_detection_width = 1,              \
+       }
+
+#define SDC_PINGROUP(pg_name, ctl, pull, drv)          \
+       {                                               \
+               .name = #pg_name,                       \
+               .pins = pg_name##_pins,                 \
+               .npins = ARRAY_SIZE(pg_name##_pins),    \
+               .ctl_reg = ctl,                         \
+               .io_reg = 0,                            \
+               .intr_cfg_reg = 0,                      \
+               .intr_status_reg = 0,                   \
+               .intr_target_reg = 0,                   \
+               .mux_bit = -1,                          \
+               .pull_bit = pull,                       \
+               .drv_bit = drv,                         \
+               .oe_bit = -1,                           \
+               .in_bit = -1,                           \
+               .out_bit = -1,                          \
+               .intr_enable_bit = -1,                  \
+               .intr_status_bit = -1,                  \
+               .intr_target_bit = -1,                  \
+               .intr_raw_status_bit = -1,              \
+               .intr_polarity_bit = -1,                \
+               .intr_detection_bit = -1,               \
+               .intr_detection_width = -1,             \
+       }
+
+enum ipq8064_functions {
+       IPQ_MUX_gpio,
+       IPQ_MUX_mdio,
+       IPQ_MUX_mi2s,
+       IPQ_MUX_pdm,
+       IPQ_MUX_ssbi,
+       IPQ_MUX_spmi,
+       IPQ_MUX_audio_pcm,
+       IPQ_MUX_gsbi1,
+       IPQ_MUX_gsbi2,
+       IPQ_MUX_gsbi4,
+       IPQ_MUX_gsbi5,
+       IPQ_MUX_gsbi5_spi_cs1,
+       IPQ_MUX_gsbi5_spi_cs2,
+       IPQ_MUX_gsbi5_spi_cs3,
+       IPQ_MUX_gsbi6,
+       IPQ_MUX_gsbi7,
+       IPQ_MUX_nss_spi,
+       IPQ_MUX_sdc1,
+       IPQ_MUX_spdif,
+       IPQ_MUX_nand,
+       IPQ_MUX_tsif1,
+       IPQ_MUX_tsif2,
+       IPQ_MUX_usb_fs_n,
+       IPQ_MUX_usb_fs,
+       IPQ_MUX_usb2_hsic,
+       IPQ_MUX_rgmii2,
+       IPQ_MUX_sata,
+       IPQ_MUX_pcie1_rst,
+       IPQ_MUX_pcie1_prsnt,
+       IPQ_MUX_pcie1_pwrflt,
+       IPQ_MUX_pcie1_pwren_n,
+       IPQ_MUX_pcie1_pwren,
+       IPQ_MUX_pcie1_clk_req,
+       IPQ_MUX_pcie2_rst,
+       IPQ_MUX_pcie2_prsnt,
+       IPQ_MUX_pcie2_pwrflt,
+       IPQ_MUX_pcie2_pwren_n,
+       IPQ_MUX_pcie2_pwren,
+       IPQ_MUX_pcie2_clk_req,
+       IPQ_MUX_pcie3_rst,
+       IPQ_MUX_pcie3_prsnt,
+       IPQ_MUX_pcie3_pwrflt,
+       IPQ_MUX_pcie3_pwren_n,
+       IPQ_MUX_pcie3_pwren,
+       IPQ_MUX_pcie3_clk_req,
+       IPQ_MUX_ps_hold,
+       IPQ_MUX_NA,
+};
+
+static const char * const gpio_groups[] = {
+       "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5", "gpio6", "gpio7",
+       "gpio8", "gpio9", "gpio10", "gpio11", "gpio12", "gpio13", "gpio14",
+       "gpio15", "gpio16", "gpio17", "gpio18", "gpio19", "gpio20", "gpio21",
+       "gpio22", "gpio23", "gpio24", "gpio25", "gpio26", "gpio27", "gpio28",
+       "gpio29", "gpio30", "gpio31", "gpio32", "gpio33", "gpio34", "gpio35",
+       "gpio36", "gpio37", "gpio38", "gpio39", "gpio40", "gpio41", "gpio42",
+       "gpio43", "gpio44", "gpio45", "gpio46", "gpio47", "gpio48", "gpio49",
+       "gpio50", "gpio51", "gpio52", "gpio53", "gpio54", "gpio55", "gpio56",
+       "gpio57", "gpio58", "gpio59", "gpio60", "gpio61", "gpio62", "gpio63",
+       "gpio64", "gpio65", "gpio66", "gpio67", "gpio68"
+};
+
+static const char * const mdio_groups[] = {
+       "gpio0", "gpio1", "gpio10", "gpio11",
+};
+
+static const char * const mi2s_groups[] = {
+       "gpio27", "gpio28", "gpio29", "gpio30", "gpio31", "gpio32",
+       "gpio33", "gpio55", "gpio56", "gpio57", "gpio58",
+};
+
+static const char * const pdm_groups[] = {
+       "gpio3", "gpio16", "gpio17", "gpio22", "gpio30", "gpio31",
+       "gpio34", "gpio35", "gpio52", "gpio55", "gpio56", "gpio58",
+       "gpio59",
+};
+
+static const char * const ssbi_groups[] = {
+       "gpio10", "gpio11",
+};
+
+static const char * const spmi_groups[] = {
+       "gpio10", "gpio11",
+};
+
+static const char * const audio_pcm_groups[] = {
+       "gpio14", "gpio15", "gpio16", "gpio17",
+};
+
+static const char * const gsbi1_groups[] = {
+       "gpio51", "gpio52", "gpio53", "gpio54",
+};
+
+static const char * const gsbi2_groups[] = {
+       "gpio22", "gpio23", "gpio24", "gpio25",
+};
+
+static const char * const gsbi4_groups[] = {
+       "gpio10", "gpio11", "gpio12", "gpio13",
+};
+
+static const char * const gsbi5_groups[] = {
+       "gpio18", "gpio19", "gpio20", "gpio21",
+};
+
+static const char * const gsbi5_spi_cs1_groups[] = {
+       "gpio6", "gpio61",
+};
+
+static const char * const gsbi5_spi_cs2_groups[] = {
+       "gpio7", "gpio62",
+};
+
+static const char * const gsbi5_spi_cs3_groups[] = {
+       "gpio2",
+};
+
+static const char * const gsbi6_groups[] = {
+       "gpio27", "gpio28", "gpio29", "gpio30", "gpio55", "gpio56",
+       "gpio57", "gpio58",
+};
+
+static const char * const gsbi7_groups[] = {
+       "gpio6", "gpio7", "gpio8", "gpio9",
+};
+
+static const char * const nss_spi_groups[] = {
+       "gpio14", "gpio15", "gpio16", "gpio17", "gpio55", "gpio56",
+       "gpio57", "gpio58",
+};
+
+static const char * const sdc1_groups[] = {
+       "gpio38", "gpio39", "gpio40", "gpio41", "gpio42", "gpio43",
+       "gpio44", "gpio45", "gpio46", "gpio47",
+};
+
+static const char * const spdif_groups[] = {
+       "gpio10", "gpio48",
+};
+
+static const char * const nand_groups[] = {
+       "gpio34", "gpio35", "gpio36", "gpio37", "gpio38", "gpio39",
+       "gpio40", "gpio41", "gpio42", "gpio43", "gpio44", "gpio45",
+       "gpio46", "gpio47",
+};
+
+static const char * const tsif1_groups[] = {
+       "gpio55", "gpio56", "gpio57", "gpio58",
+};
+
+static const char * const tsif2_groups[] = {
+       "gpio59", "gpio60", "gpio61", "gpio62",
+};
+
+static const char * const usb_fs_n_groups[] = {
+       "gpio6",
+};
+
+static const char * const usb_fs_groups[] = {
+       "gpio6", "gpio7", "gpio8",
+};
+
+static const char * const usb2_hsic_groups[] = {
+       "gpio67", "gpio68",
+};
+
+static const char * const rgmii2_groups[] = {
+       "gpio27", "gpio28", "gpio29", "gpio30", "gpio31", "gpio32",
+       "gpio51", "gpio52", "gpio59", "gpio60", "gpio61", "gpio62",
+};
+
+static const char * const sata_groups[] = {
+       "gpio10",
+};
+
+static const char * const pcie1_rst_groups[] = {
+       "gpio3",
+};
+
+static const char * const pcie1_prsnt_groups[] = {
+       "gpio3", "gpio11",
+};
+
+static const char * const pcie1_pwren_n_groups[] = {
+       "gpio4", "gpio12",
+};
+
+static const char * const pcie1_pwren_groups[] = {
+       "gpio4", "gpio12",
+};
+
+static const char * const pcie1_pwrflt_groups[] = {
+       "gpio5", "gpio13",
+};
+
+static const char * const pcie1_clk_req_groups[] = {
+       "gpio5",
+};
+
+static const char * const pcie2_rst_groups[] = {
+       "gpio48",
+};
+
+static const char * const pcie2_prsnt_groups[] = {
+       "gpio11", "gpio48",
+};
+
+static const char * const pcie2_pwren_n_groups[] = {
+       "gpio12", "gpio49",
+};
+
+static const char * const pcie2_pwren_groups[] = {
+       "gpio12", "gpio49",
+};
+
+static const char * const pcie2_pwrflt_groups[] = {
+       "gpio13", "gpio50",
+};
+
+static const char * const pcie2_clk_req_groups[] = {
+       "gpio50",
+};
+
+static const char * const pcie3_rst_groups[] = {
+       "gpio63",
+};
+
+static const char * const pcie3_prsnt_groups[] = {
+       "gpio11",
+};
+
+static const char * const pcie3_pwren_n_groups[] = {
+       "gpio12",
+};
+
+static const char * const pcie3_pwren_groups[] = {
+       "gpio12",
+};
+
+static const char * const pcie3_pwrflt_groups[] = {
+       "gpio13",
+};
+
+static const char * const pcie3_clk_req_groups[] = {
+       "gpio65",
+};
+
+static const char * const ps_hold_groups[] = {
+       "gpio26",
+};
+
+static const struct msm_function ipq8064_functions[] = {
+       FUNCTION(gpio),
+       FUNCTION(mdio),
+       FUNCTION(ssbi),
+       FUNCTION(spmi),
+       FUNCTION(mi2s),
+       FUNCTION(pdm),
+       FUNCTION(audio_pcm),
+       FUNCTION(gsbi1),
+       FUNCTION(gsbi2),
+       FUNCTION(gsbi4),
+       FUNCTION(gsbi5),
+       FUNCTION(gsbi5_spi_cs1),
+       FUNCTION(gsbi5_spi_cs2),
+       FUNCTION(gsbi5_spi_cs3),
+       FUNCTION(gsbi6),
+       FUNCTION(gsbi7),
+       FUNCTION(nss_spi),
+       FUNCTION(sdc1),
+       FUNCTION(spdif),
+       FUNCTION(nand),
+       FUNCTION(tsif1),
+       FUNCTION(tsif2),
+       FUNCTION(usb_fs_n),
+       FUNCTION(usb_fs),
+       FUNCTION(usb2_hsic),
+       FUNCTION(rgmii2),
+       FUNCTION(sata),
+       FUNCTION(pcie1_rst),
+       FUNCTION(pcie1_prsnt),
+       FUNCTION(pcie1_pwren_n),
+       FUNCTION(pcie1_pwren),
+       FUNCTION(pcie1_pwrflt),
+       FUNCTION(pcie1_clk_req),
+       FUNCTION(pcie2_rst),
+       FUNCTION(pcie2_prsnt),
+       FUNCTION(pcie2_pwren_n),
+       FUNCTION(pcie2_pwren),
+       FUNCTION(pcie2_pwrflt),
+       FUNCTION(pcie2_clk_req),
+       FUNCTION(pcie3_rst),
+       FUNCTION(pcie3_prsnt),
+       FUNCTION(pcie3_pwren_n),
+       FUNCTION(pcie3_pwren),
+       FUNCTION(pcie3_pwrflt),
+       FUNCTION(pcie3_clk_req),
+       FUNCTION(ps_hold),
+};
+
+static const struct msm_pingroup ipq8064_groups[] = {
+       PINGROUP(0, mdio, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(1, mdio, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(2, gsbi5_spi_cs3, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(3, pcie1_rst, pcie1_prsnt, pdm, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(4, pcie1_pwren_n, pcie1_pwren, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(5, pcie1_clk_req, pcie1_pwrflt, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(6, gsbi7, usb_fs, gsbi5_spi_cs1, usb_fs_n, NA, NA, NA, NA, NA, NA),
+       PINGROUP(7, gsbi7, usb_fs, gsbi5_spi_cs2, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(8, gsbi7, usb_fs, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(9, gsbi7, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(10, gsbi4, spdif, sata, ssbi, mdio, spmi, NA, NA, NA, NA),
+       PINGROUP(11, gsbi4, pcie2_prsnt, pcie1_prsnt, pcie3_prsnt, ssbi, mdio, spmi, NA, NA, NA),
+       PINGROUP(12, gsbi4, pcie2_pwren_n, pcie1_pwren_n, pcie3_pwren_n, pcie2_pwren, pcie1_pwren, pcie3_pwren, NA, NA, NA),
+       PINGROUP(13, gsbi4, pcie2_pwrflt, pcie1_pwrflt, pcie3_pwrflt, NA, NA, NA, NA, NA, NA),
+       PINGROUP(14, audio_pcm, nss_spi, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(15, audio_pcm, nss_spi, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(16, audio_pcm, nss_spi, pdm, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(17, audio_pcm, nss_spi, pdm, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(18, gsbi5, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(19, gsbi5, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(20, gsbi5, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(21, gsbi5, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(22, gsbi2, pdm, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(23, gsbi2, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(24, gsbi2, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(25, gsbi2, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(26, ps_hold, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(27, mi2s, rgmii2, gsbi6, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(28, mi2s, rgmii2, gsbi6, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(29, mi2s, rgmii2, gsbi6, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(30, mi2s, rgmii2, gsbi6, pdm, NA, NA, NA, NA, NA, NA),
+       PINGROUP(31, mi2s, rgmii2, pdm, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(32, mi2s, rgmii2, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(33, mi2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(34, nand, pdm, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(35, nand, pdm, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(36, nand, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(37, nand, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(38, nand, sdc1, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(39, nand, sdc1, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(40, nand, sdc1, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(41, nand, sdc1, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(42, nand, sdc1, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(43, nand, sdc1, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(44, nand, sdc1, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(45, nand, sdc1, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(46, nand, sdc1, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(47, nand, sdc1, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(48, pcie2_rst, spdif, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(49, pcie2_pwren_n, pcie2_pwren, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(50, pcie2_clk_req, pcie2_pwrflt, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(51, gsbi1, rgmii2, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(52, gsbi1, rgmii2, pdm, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(53, gsbi1, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(54, gsbi1, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(55, tsif1, mi2s, gsbi6, pdm, nss_spi, NA, NA, NA, NA, NA),
+       PINGROUP(56, tsif1, mi2s, gsbi6, pdm, nss_spi, NA, NA, NA, NA, NA),
+       PINGROUP(57, tsif1, mi2s, gsbi6, nss_spi, NA, NA, NA, NA, NA, NA),
+       PINGROUP(58, tsif1, mi2s, gsbi6, pdm, nss_spi, NA, NA, NA, NA, NA),
+       PINGROUP(59, tsif2, rgmii2, pdm, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(60, tsif2, rgmii2, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(61, tsif2, rgmii2, gsbi5_spi_cs1, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(62, tsif2, rgmii2, gsbi5_spi_cs2, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(63, pcie3_rst, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(64, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(65, pcie3_clk_req, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(66, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(67, usb2_hsic, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(68, usb2_hsic, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       SDC_PINGROUP(sdc3_clk, 0x204a, 14, 6),
+       SDC_PINGROUP(sdc3_cmd, 0x204a, 11, 3),
+       SDC_PINGROUP(sdc3_data, 0x204a, 9, 0),
+};
+
+#define NUM_GPIO_PINGROUPS 69
+
+static const struct msm_pinctrl_soc_data ipq8064_pinctrl = {
+       .pins = ipq8064_pins,
+       .npins = ARRAY_SIZE(ipq8064_pins),
+       .functions = ipq8064_functions,
+       .nfunctions = ARRAY_SIZE(ipq8064_functions),
+       .groups = ipq8064_groups,
+       .ngroups = ARRAY_SIZE(ipq8064_groups),
+       .ngpios = NUM_GPIO_PINGROUPS,
+};
+
+static int ipq8064_pinctrl_probe(struct platform_device *pdev)
+{
+       return msm_pinctrl_probe(pdev, &ipq8064_pinctrl);
+}
+
+static const struct of_device_id ipq8064_pinctrl_of_match[] = {
+       { .compatible = "qcom,ipq8064-pinctrl", },
+       { },
+};
+
+static struct platform_driver ipq8064_pinctrl_driver = {
+       .driver = {
+               .name = "ipq8064-pinctrl",
+               .owner = THIS_MODULE,
+               .of_match_table = ipq8064_pinctrl_of_match,
+       },
+       .probe = ipq8064_pinctrl_probe,
+       .remove = msm_pinctrl_remove,
+};
+
+static int __init ipq8064_pinctrl_init(void)
+{
+       return platform_driver_register(&ipq8064_pinctrl_driver);
+}
+arch_initcall(ipq8064_pinctrl_init);
+
+static void __exit ipq8064_pinctrl_exit(void)
+{
+       platform_driver_unregister(&ipq8064_pinctrl_driver);
+}
+module_exit(ipq8064_pinctrl_exit);
+
+MODULE_AUTHOR("Andy Gross <agross@codeaurora.org>");
+MODULE_DESCRIPTION("Qualcomm IPQ8064 pinctrl driver");
+MODULE_LICENSE("GPL v2");
+MODULE_DEVICE_TABLE(of, ipq8064_pinctrl_of_match);
diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c
new file mode 100644 (file)
index 0000000..2738108
--- /dev/null
@@ -0,0 +1,919 @@
+/*
+ * Copyright (c) 2013, Sony Mobile Communications AB.
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pinctrl/machine.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinconf-generic.h>
+#include <linux/slab.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+
+#include "../core.h"
+#include "../pinconf.h"
+#include "pinctrl-msm.h"
+#include "../pinctrl-utils.h"
+
+#define MAX_NR_GPIO 300
+
+/**
+ * struct msm_pinctrl - state for a pinctrl-msm device
+ * @dev:            device handle.
+ * @pctrl:          pinctrl handle.
+ * @chip:           gpiochip handle.
+ * @irq:            parent irq for the TLMM irq_chip.
+ * @lock:           Spinlock to protect register resources as well
+ *                  as msm_pinctrl data structures.
+ * @enabled_irqs:   Bitmap of currently enabled irqs.
+ * @dual_edge_irqs: Bitmap of irqs that need sw emulated dual edge
+ *                  detection.
+ * @soc;            Reference to soc_data of platform specific data.
+ * @regs:           Base address for the TLMM register map.
+ */
+struct msm_pinctrl {
+       struct device *dev;
+       struct pinctrl_dev *pctrl;
+       struct gpio_chip chip;
+       int irq;
+
+       spinlock_t lock;
+
+       DECLARE_BITMAP(dual_edge_irqs, MAX_NR_GPIO);
+       DECLARE_BITMAP(enabled_irqs, MAX_NR_GPIO);
+
+       const struct msm_pinctrl_soc_data *soc;
+       void __iomem *regs;
+};
+
+static inline struct msm_pinctrl *to_msm_pinctrl(struct gpio_chip *gc)
+{
+       return container_of(gc, struct msm_pinctrl, chip);
+}
+
+static int msm_get_groups_count(struct pinctrl_dev *pctldev)
+{
+       struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+
+       return pctrl->soc->ngroups;
+}
+
+static const char *msm_get_group_name(struct pinctrl_dev *pctldev,
+                                     unsigned group)
+{
+       struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+
+       return pctrl->soc->groups[group].name;
+}
+
+static int msm_get_group_pins(struct pinctrl_dev *pctldev,
+                             unsigned group,
+                             const unsigned **pins,
+                             unsigned *num_pins)
+{
+       struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+
+       *pins = pctrl->soc->groups[group].pins;
+       *num_pins = pctrl->soc->groups[group].npins;
+       return 0;
+}
+
+static const struct pinctrl_ops msm_pinctrl_ops = {
+       .get_groups_count       = msm_get_groups_count,
+       .get_group_name         = msm_get_group_name,
+       .get_group_pins         = msm_get_group_pins,
+       .dt_node_to_map         = pinconf_generic_dt_node_to_map_group,
+       .dt_free_map            = pinctrl_utils_dt_free_map,
+};
+
+static int msm_get_functions_count(struct pinctrl_dev *pctldev)
+{
+       struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+
+       return pctrl->soc->nfunctions;
+}
+
+static const char *msm_get_function_name(struct pinctrl_dev *pctldev,
+                                        unsigned function)
+{
+       struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+
+       return pctrl->soc->functions[function].name;
+}
+
+static int msm_get_function_groups(struct pinctrl_dev *pctldev,
+                                  unsigned function,
+                                  const char * const **groups,
+                                  unsigned * const num_groups)
+{
+       struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+
+       *groups = pctrl->soc->functions[function].groups;
+       *num_groups = pctrl->soc->functions[function].ngroups;
+       return 0;
+}
+
+static int msm_pinmux_enable(struct pinctrl_dev *pctldev,
+                            unsigned function,
+                            unsigned group)
+{
+       struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+       const struct msm_pingroup *g;
+       unsigned long flags;
+       u32 val;
+       int i;
+
+       g = &pctrl->soc->groups[group];
+
+       for (i = 0; i < g->nfuncs; i++) {
+               if (g->funcs[i] == function)
+                       break;
+       }
+
+       if (WARN_ON(i == g->nfuncs))
+               return -EINVAL;
+
+       spin_lock_irqsave(&pctrl->lock, flags);
+
+       val = readl(pctrl->regs + g->ctl_reg);
+       val &= ~(0x7 << g->mux_bit);
+       val |= i << g->mux_bit;
+       writel(val, pctrl->regs + g->ctl_reg);
+
+       spin_unlock_irqrestore(&pctrl->lock, flags);
+
+       return 0;
+}
+
+static const struct pinmux_ops msm_pinmux_ops = {
+       .get_functions_count    = msm_get_functions_count,
+       .get_function_name      = msm_get_function_name,
+       .get_function_groups    = msm_get_function_groups,
+       .enable                 = msm_pinmux_enable,
+};
+
+static int msm_config_reg(struct msm_pinctrl *pctrl,
+                         const struct msm_pingroup *g,
+                         unsigned param,
+                         unsigned *mask,
+                         unsigned *bit)
+{
+       switch (param) {
+       case PIN_CONFIG_BIAS_DISABLE:
+       case PIN_CONFIG_BIAS_PULL_DOWN:
+       case PIN_CONFIG_BIAS_BUS_HOLD:
+       case PIN_CONFIG_BIAS_PULL_UP:
+               *bit = g->pull_bit;
+               *mask = 3;
+               break;
+       case PIN_CONFIG_DRIVE_STRENGTH:
+               *bit = g->drv_bit;
+               *mask = 7;
+               break;
+       case PIN_CONFIG_OUTPUT:
+               *bit = g->oe_bit;
+               *mask = 1;
+               break;
+       default:
+               dev_err(pctrl->dev, "Invalid config param %04x\n", param);
+               return -ENOTSUPP;
+       }
+
+       return 0;
+}
+
+static int msm_config_get(struct pinctrl_dev *pctldev,
+                         unsigned int pin,
+                         unsigned long *config)
+{
+       dev_err(pctldev->dev, "pin_config_set op not supported\n");
+       return -ENOTSUPP;
+}
+
+static int msm_config_set(struct pinctrl_dev *pctldev, unsigned int pin,
+                               unsigned long *configs, unsigned num_configs)
+{
+       dev_err(pctldev->dev, "pin_config_set op not supported\n");
+       return -ENOTSUPP;
+}
+
+#define MSM_NO_PULL    0
+#define MSM_PULL_DOWN  1
+#define MSM_KEEPER     2
+#define MSM_PULL_UP    3
+
+static unsigned msm_regval_to_drive(u32 val)
+{
+       return (val + 1) * 2;
+}
+
+static int msm_config_group_get(struct pinctrl_dev *pctldev,
+                               unsigned int group,
+                               unsigned long *config)
+{
+       const struct msm_pingroup *g;
+       struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+       unsigned param = pinconf_to_config_param(*config);
+       unsigned mask;
+       unsigned arg;
+       unsigned bit;
+       int ret;
+       u32 val;
+
+       g = &pctrl->soc->groups[group];
+
+       ret = msm_config_reg(pctrl, g, param, &mask, &bit);
+       if (ret < 0)
+               return ret;
+
+       val = readl(pctrl->regs + g->ctl_reg);
+       arg = (val >> bit) & mask;
+
+       /* Convert register value to pinconf value */
+       switch (param) {
+       case PIN_CONFIG_BIAS_DISABLE:
+               arg = arg == MSM_NO_PULL;
+               break;
+       case PIN_CONFIG_BIAS_PULL_DOWN:
+               arg = arg == MSM_PULL_DOWN;
+               break;
+       case PIN_CONFIG_BIAS_BUS_HOLD:
+               arg = arg == MSM_KEEPER;
+               break;
+       case PIN_CONFIG_BIAS_PULL_UP:
+               arg = arg == MSM_PULL_UP;
+               break;
+       case PIN_CONFIG_DRIVE_STRENGTH:
+               arg = msm_regval_to_drive(arg);
+               break;
+       case PIN_CONFIG_OUTPUT:
+               /* Pin is not output */
+               if (!arg)
+                       return -EINVAL;
+
+               val = readl(pctrl->regs + g->io_reg);
+               arg = !!(val & BIT(g->in_bit));
+               break;
+       default:
+               dev_err(pctrl->dev, "Unsupported config parameter: %x\n",
+                       param);
+               return -EINVAL;
+       }
+
+       *config = pinconf_to_config_packed(param, arg);
+
+       return 0;
+}
+
+static int msm_config_group_set(struct pinctrl_dev *pctldev,
+                               unsigned group,
+                               unsigned long *configs,
+                               unsigned num_configs)
+{
+       const struct msm_pingroup *g;
+       struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+       unsigned long flags;
+       unsigned param;
+       unsigned mask;
+       unsigned arg;
+       unsigned bit;
+       int ret;
+       u32 val;
+       int i;
+
+       g = &pctrl->soc->groups[group];
+
+       for (i = 0; i < num_configs; i++) {
+               param = pinconf_to_config_param(configs[i]);
+               arg = pinconf_to_config_argument(configs[i]);
+
+               ret = msm_config_reg(pctrl, g, param, &mask, &bit);
+               if (ret < 0)
+                       return ret;
+
+               /* Convert pinconf values to register values */
+               switch (param) {
+               case PIN_CONFIG_BIAS_DISABLE:
+                       arg = MSM_NO_PULL;
+                       break;
+               case PIN_CONFIG_BIAS_PULL_DOWN:
+                       arg = MSM_PULL_DOWN;
+                       break;
+               case PIN_CONFIG_BIAS_BUS_HOLD:
+                       arg = MSM_KEEPER;
+                       break;
+               case PIN_CONFIG_BIAS_PULL_UP:
+                       arg = MSM_PULL_UP;
+                       break;
+               case PIN_CONFIG_DRIVE_STRENGTH:
+                       /* Check for invalid values */
+                       if (arg > 16 || arg < 2 || (arg % 2) != 0)
+                               arg = -1;
+                       else
+                               arg = (arg / 2) - 1;
+                       break;
+               case PIN_CONFIG_OUTPUT:
+                       /* set output value */
+                       spin_lock_irqsave(&pctrl->lock, flags);
+                       val = readl(pctrl->regs + g->io_reg);
+                       if (arg)
+                               val |= BIT(g->out_bit);
+                       else
+                               val &= ~BIT(g->out_bit);
+                       writel(val, pctrl->regs + g->io_reg);
+                       spin_unlock_irqrestore(&pctrl->lock, flags);
+
+                       /* enable output */
+                       arg = 1;
+                       break;
+               default:
+                       dev_err(pctrl->dev, "Unsupported config parameter: %x\n",
+                               param);
+                       return -EINVAL;
+               }
+
+               /* Range-check user-supplied value */
+               if (arg & ~mask) {
+                       dev_err(pctrl->dev, "config %x: %x is invalid\n", param, arg);
+                       return -EINVAL;
+               }
+
+               spin_lock_irqsave(&pctrl->lock, flags);
+               val = readl(pctrl->regs + g->ctl_reg);
+               val &= ~(mask << bit);
+               val |= arg << bit;
+               writel(val, pctrl->regs + g->ctl_reg);
+               spin_unlock_irqrestore(&pctrl->lock, flags);
+       }
+
+       return 0;
+}
+
+static const struct pinconf_ops msm_pinconf_ops = {
+       .pin_config_get         = msm_config_get,
+       .pin_config_set         = msm_config_set,
+       .pin_config_group_get   = msm_config_group_get,
+       .pin_config_group_set   = msm_config_group_set,
+};
+
+static struct pinctrl_desc msm_pinctrl_desc = {
+       .pctlops = &msm_pinctrl_ops,
+       .pmxops = &msm_pinmux_ops,
+       .confops = &msm_pinconf_ops,
+       .owner = THIS_MODULE,
+};
+
+static int msm_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+       const struct msm_pingroup *g;
+       struct msm_pinctrl *pctrl = container_of(chip, struct msm_pinctrl, chip);
+       unsigned long flags;
+       u32 val;
+
+       g = &pctrl->soc->groups[offset];
+
+       spin_lock_irqsave(&pctrl->lock, flags);
+
+       val = readl(pctrl->regs + g->ctl_reg);
+       val &= ~BIT(g->oe_bit);
+       writel(val, pctrl->regs + g->ctl_reg);
+
+       spin_unlock_irqrestore(&pctrl->lock, flags);
+
+       return 0;
+}
+
+static int msm_gpio_direction_output(struct gpio_chip *chip, unsigned offset, int value)
+{
+       const struct msm_pingroup *g;
+       struct msm_pinctrl *pctrl = container_of(chip, struct msm_pinctrl, chip);
+       unsigned long flags;
+       u32 val;
+
+       g = &pctrl->soc->groups[offset];
+
+       spin_lock_irqsave(&pctrl->lock, flags);
+
+       val = readl(pctrl->regs + g->io_reg);
+       if (value)
+               val |= BIT(g->out_bit);
+       else
+               val &= ~BIT(g->out_bit);
+       writel(val, pctrl->regs + g->io_reg);
+
+       val = readl(pctrl->regs + g->ctl_reg);
+       val |= BIT(g->oe_bit);
+       writel(val, pctrl->regs + g->ctl_reg);
+
+       spin_unlock_irqrestore(&pctrl->lock, flags);
+
+       return 0;
+}
+
+static int msm_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+       const struct msm_pingroup *g;
+       struct msm_pinctrl *pctrl = container_of(chip, struct msm_pinctrl, chip);
+       u32 val;
+
+       g = &pctrl->soc->groups[offset];
+
+       val = readl(pctrl->regs + g->io_reg);
+       return !!(val & BIT(g->in_bit));
+}
+
+static void msm_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+       const struct msm_pingroup *g;
+       struct msm_pinctrl *pctrl = container_of(chip, struct msm_pinctrl, chip);
+       unsigned long flags;
+       u32 val;
+
+       g = &pctrl->soc->groups[offset];
+
+       spin_lock_irqsave(&pctrl->lock, flags);
+
+       val = readl(pctrl->regs + g->io_reg);
+       if (value)
+               val |= BIT(g->out_bit);
+       else
+               val &= ~BIT(g->out_bit);
+       writel(val, pctrl->regs + g->io_reg);
+
+       spin_unlock_irqrestore(&pctrl->lock, flags);
+}
+
+static int msm_gpio_request(struct gpio_chip *chip, unsigned offset)
+{
+       int gpio = chip->base + offset;
+       return pinctrl_request_gpio(gpio);
+}
+
+static void msm_gpio_free(struct gpio_chip *chip, unsigned offset)
+{
+       int gpio = chip->base + offset;
+       return pinctrl_free_gpio(gpio);
+}
+
+#ifdef CONFIG_DEBUG_FS
+#include <linux/seq_file.h>
+
+static void msm_gpio_dbg_show_one(struct seq_file *s,
+                                 struct pinctrl_dev *pctldev,
+                                 struct gpio_chip *chip,
+                                 unsigned offset,
+                                 unsigned gpio)
+{
+       const struct msm_pingroup *g;
+       struct msm_pinctrl *pctrl = container_of(chip, struct msm_pinctrl, chip);
+       unsigned func;
+       int is_out;
+       int drive;
+       int pull;
+       u32 ctl_reg;
+
+       static const char * const pulls[] = {
+               "no pull",
+               "pull down",
+               "keeper",
+               "pull up"
+       };
+
+       g = &pctrl->soc->groups[offset];
+       ctl_reg = readl(pctrl->regs + g->ctl_reg);
+
+       is_out = !!(ctl_reg & BIT(g->oe_bit));
+       func = (ctl_reg >> g->mux_bit) & 7;
+       drive = (ctl_reg >> g->drv_bit) & 7;
+       pull = (ctl_reg >> g->pull_bit) & 3;
+
+       seq_printf(s, " %-8s: %-3s %d", g->name, is_out ? "out" : "in", func);
+       seq_printf(s, " %dmA", msm_regval_to_drive(drive));
+       seq_printf(s, " %s", pulls[pull]);
+}
+
+static void msm_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
+{
+       unsigned gpio = chip->base;
+       unsigned i;
+
+       for (i = 0; i < chip->ngpio; i++, gpio++) {
+               msm_gpio_dbg_show_one(s, NULL, chip, i, gpio);
+               seq_puts(s, "\n");
+       }
+}
+
+#else
+#define msm_gpio_dbg_show NULL
+#endif
+
+static struct gpio_chip msm_gpio_template = {
+       .direction_input  = msm_gpio_direction_input,
+       .direction_output = msm_gpio_direction_output,
+       .get              = msm_gpio_get,
+       .set              = msm_gpio_set,
+       .request          = msm_gpio_request,
+       .free             = msm_gpio_free,
+       .dbg_show         = msm_gpio_dbg_show,
+};
+
+/* For dual-edge interrupts in software, since some hardware has no
+ * such support:
+ *
+ * At appropriate moments, this function may be called to flip the polarity
+ * settings of both-edge irq lines to try and catch the next edge.
+ *
+ * The attempt is considered successful if:
+ * - the status bit goes high, indicating that an edge was caught, or
+ * - the input value of the gpio doesn't change during the attempt.
+ * If the value changes twice during the process, that would cause the first
+ * test to fail but would force the second, as two opposite
+ * transitions would cause a detection no matter the polarity setting.
+ *
+ * The do-loop tries to sledge-hammer closed the timing hole between
+ * the initial value-read and the polarity-write - if the line value changes
+ * during that window, an interrupt is lost, the new polarity setting is
+ * incorrect, and the first success test will fail, causing a retry.
+ *
+ * Algorithm comes from Google's msmgpio driver.
+ */
+static void msm_gpio_update_dual_edge_pos(struct msm_pinctrl *pctrl,
+                                         const struct msm_pingroup *g,
+                                         struct irq_data *d)
+{
+       int loop_limit = 100;
+       unsigned val, val2, intstat;
+       unsigned pol;
+
+       do {
+               val = readl(pctrl->regs + g->io_reg) & BIT(g->in_bit);
+
+               pol = readl(pctrl->regs + g->intr_cfg_reg);
+               pol ^= BIT(g->intr_polarity_bit);
+               writel(pol, pctrl->regs + g->intr_cfg_reg);
+
+               val2 = readl(pctrl->regs + g->io_reg) & BIT(g->in_bit);
+               intstat = readl(pctrl->regs + g->intr_status_reg);
+               if (intstat || (val == val2))
+                       return;
+       } while (loop_limit-- > 0);
+       dev_err(pctrl->dev, "dual-edge irq failed to stabilize, %#08x != %#08x\n",
+               val, val2);
+}
+
+static void msm_gpio_irq_mask(struct irq_data *d)
+{
+       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+       struct msm_pinctrl *pctrl = to_msm_pinctrl(gc);
+       const struct msm_pingroup *g;
+       unsigned long flags;
+       u32 val;
+
+       g = &pctrl->soc->groups[d->hwirq];
+
+       spin_lock_irqsave(&pctrl->lock, flags);
+
+       val = readl(pctrl->regs + g->intr_cfg_reg);
+       val &= ~BIT(g->intr_enable_bit);
+       writel(val, pctrl->regs + g->intr_cfg_reg);
+
+       clear_bit(d->hwirq, pctrl->enabled_irqs);
+
+       spin_unlock_irqrestore(&pctrl->lock, flags);
+}
+
+static void msm_gpio_irq_unmask(struct irq_data *d)
+{
+       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+       struct msm_pinctrl *pctrl = to_msm_pinctrl(gc);
+       const struct msm_pingroup *g;
+       unsigned long flags;
+       u32 val;
+
+       g = &pctrl->soc->groups[d->hwirq];
+
+       spin_lock_irqsave(&pctrl->lock, flags);
+
+       val = readl(pctrl->regs + g->intr_status_reg);
+       val &= ~BIT(g->intr_status_bit);
+       writel(val, pctrl->regs + g->intr_status_reg);
+
+       val = readl(pctrl->regs + g->intr_cfg_reg);
+       val |= BIT(g->intr_enable_bit);
+       writel(val, pctrl->regs + g->intr_cfg_reg);
+
+       set_bit(d->hwirq, pctrl->enabled_irqs);
+
+       spin_unlock_irqrestore(&pctrl->lock, flags);
+}
+
+static void msm_gpio_irq_ack(struct irq_data *d)
+{
+       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+       struct msm_pinctrl *pctrl = to_msm_pinctrl(gc);
+       const struct msm_pingroup *g;
+       unsigned long flags;
+       u32 val;
+
+       g = &pctrl->soc->groups[d->hwirq];
+
+       spin_lock_irqsave(&pctrl->lock, flags);
+
+       val = readl(pctrl->regs + g->intr_status_reg);
+       if (g->intr_ack_high)
+               val |= BIT(g->intr_status_bit);
+       else
+               val &= ~BIT(g->intr_status_bit);
+       writel(val, pctrl->regs + g->intr_status_reg);
+
+       if (test_bit(d->hwirq, pctrl->dual_edge_irqs))
+               msm_gpio_update_dual_edge_pos(pctrl, g, d);
+
+       spin_unlock_irqrestore(&pctrl->lock, flags);
+}
+
+#define INTR_TARGET_PROC_APPS    4
+
+static int msm_gpio_irq_set_type(struct irq_data *d, unsigned int type)
+{
+       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+       struct msm_pinctrl *pctrl = to_msm_pinctrl(gc);
+       const struct msm_pingroup *g;
+       unsigned long flags;
+       u32 val;
+
+       g = &pctrl->soc->groups[d->hwirq];
+
+       spin_lock_irqsave(&pctrl->lock, flags);
+
+       /*
+        * For hw without possibility of detecting both edges
+        */
+       if (g->intr_detection_width == 1 && type == IRQ_TYPE_EDGE_BOTH)
+               set_bit(d->hwirq, pctrl->dual_edge_irqs);
+       else
+               clear_bit(d->hwirq, pctrl->dual_edge_irqs);
+
+       /* Route interrupts to application cpu */
+       val = readl(pctrl->regs + g->intr_target_reg);
+       val &= ~(7 << g->intr_target_bit);
+       val |= INTR_TARGET_PROC_APPS << g->intr_target_bit;
+       writel(val, pctrl->regs + g->intr_target_reg);
+
+       /* Update configuration for gpio.
+        * RAW_STATUS_EN is left on for all gpio irqs. Due to the
+        * internal circuitry of TLMM, toggling the RAW_STATUS
+        * could cause the INTR_STATUS to be set for EDGE interrupts.
+        */
+       val = readl(pctrl->regs + g->intr_cfg_reg);
+       val |= BIT(g->intr_raw_status_bit);
+       if (g->intr_detection_width == 2) {
+               val &= ~(3 << g->intr_detection_bit);
+               val &= ~(1 << g->intr_polarity_bit);
+               switch (type) {
+               case IRQ_TYPE_EDGE_RISING:
+                       val |= 1 << g->intr_detection_bit;
+                       val |= BIT(g->intr_polarity_bit);
+                       break;
+               case IRQ_TYPE_EDGE_FALLING:
+                       val |= 2 << g->intr_detection_bit;
+                       val |= BIT(g->intr_polarity_bit);
+                       break;
+               case IRQ_TYPE_EDGE_BOTH:
+                       val |= 3 << g->intr_detection_bit;
+                       val |= BIT(g->intr_polarity_bit);
+                       break;
+               case IRQ_TYPE_LEVEL_LOW:
+                       break;
+               case IRQ_TYPE_LEVEL_HIGH:
+                       val |= BIT(g->intr_polarity_bit);
+                       break;
+               }
+       } else if (g->intr_detection_width == 1) {
+               val &= ~(1 << g->intr_detection_bit);
+               val &= ~(1 << g->intr_polarity_bit);
+               switch (type) {
+               case IRQ_TYPE_EDGE_RISING:
+                       val |= BIT(g->intr_detection_bit);
+                       val |= BIT(g->intr_polarity_bit);
+                       break;
+               case IRQ_TYPE_EDGE_FALLING:
+                       val |= BIT(g->intr_detection_bit);
+                       break;
+               case IRQ_TYPE_EDGE_BOTH:
+                       val |= BIT(g->intr_detection_bit);
+                       val |= BIT(g->intr_polarity_bit);
+                       break;
+               case IRQ_TYPE_LEVEL_LOW:
+                       break;
+               case IRQ_TYPE_LEVEL_HIGH:
+                       val |= BIT(g->intr_polarity_bit);
+                       break;
+               }
+       } else {
+               BUG();
+       }
+       writel(val, pctrl->regs + g->intr_cfg_reg);
+
+       if (test_bit(d->hwirq, pctrl->dual_edge_irqs))
+               msm_gpio_update_dual_edge_pos(pctrl, g, d);
+
+       spin_unlock_irqrestore(&pctrl->lock, flags);
+
+       if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH))
+               __irq_set_handler_locked(d->irq, handle_level_irq);
+       else if (type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
+               __irq_set_handler_locked(d->irq, handle_edge_irq);
+
+       return 0;
+}
+
+static int msm_gpio_irq_set_wake(struct irq_data *d, unsigned int on)
+{
+       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+       struct msm_pinctrl *pctrl = to_msm_pinctrl(gc);
+       unsigned long flags;
+
+       spin_lock_irqsave(&pctrl->lock, flags);
+
+       irq_set_irq_wake(pctrl->irq, on);
+
+       spin_unlock_irqrestore(&pctrl->lock, flags);
+
+       return 0;
+}
+
+static struct irq_chip msm_gpio_irq_chip = {
+       .name           = "msmgpio",
+       .irq_mask       = msm_gpio_irq_mask,
+       .irq_unmask     = msm_gpio_irq_unmask,
+       .irq_ack        = msm_gpio_irq_ack,
+       .irq_set_type   = msm_gpio_irq_set_type,
+       .irq_set_wake   = msm_gpio_irq_set_wake,
+};
+
+static void msm_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+       struct gpio_chip *gc = irq_desc_get_handler_data(desc);
+       const struct msm_pingroup *g;
+       struct msm_pinctrl *pctrl = to_msm_pinctrl(gc);
+       struct irq_chip *chip = irq_get_chip(irq);
+       int irq_pin;
+       int handled = 0;
+       u32 val;
+       int i;
+
+       chained_irq_enter(chip, desc);
+
+       /*
+        * Each pin has it's own IRQ status register, so use
+        * enabled_irq bitmap to limit the number of reads.
+        */
+       for_each_set_bit(i, pctrl->enabled_irqs, pctrl->chip.ngpio) {
+               g = &pctrl->soc->groups[i];
+               val = readl(pctrl->regs + g->intr_status_reg);
+               if (val & BIT(g->intr_status_bit)) {
+                       irq_pin = irq_find_mapping(gc->irqdomain, i);
+                       generic_handle_irq(irq_pin);
+                       handled++;
+               }
+       }
+
+       /* No interrupts were flagged */
+       if (handled == 0)
+               handle_bad_irq(irq, desc);
+
+       chained_irq_exit(chip, desc);
+}
+
+static int msm_gpio_init(struct msm_pinctrl *pctrl)
+{
+       struct gpio_chip *chip;
+       int ret;
+       unsigned ngpio = pctrl->soc->ngpios;
+
+       if (WARN_ON(ngpio > MAX_NR_GPIO))
+               return -EINVAL;
+
+       chip = &pctrl->chip;
+       chip->base = 0;
+       chip->ngpio = ngpio;
+       chip->label = dev_name(pctrl->dev);
+       chip->dev = pctrl->dev;
+       chip->owner = THIS_MODULE;
+       chip->of_node = pctrl->dev->of_node;
+
+       ret = gpiochip_add(&pctrl->chip);
+       if (ret) {
+               dev_err(pctrl->dev, "Failed register gpiochip\n");
+               return ret;
+       }
+
+       ret = gpiochip_add_pin_range(&pctrl->chip, dev_name(pctrl->dev), 0, 0, chip->ngpio);
+       if (ret) {
+               dev_err(pctrl->dev, "Failed to add pin range\n");
+               return ret;
+       }
+
+       ret = gpiochip_irqchip_add(chip,
+                                  &msm_gpio_irq_chip,
+                                  0,
+                                  handle_edge_irq,
+                                  IRQ_TYPE_NONE);
+       if (ret) {
+               dev_err(pctrl->dev, "Failed to add irqchip to gpiochip\n");
+               return -ENOSYS;
+       }
+
+       gpiochip_set_chained_irqchip(chip, &msm_gpio_irq_chip, pctrl->irq,
+                                    msm_gpio_irq_handler);
+
+       return 0;
+}
+
+int msm_pinctrl_probe(struct platform_device *pdev,
+                     const struct msm_pinctrl_soc_data *soc_data)
+{
+       struct msm_pinctrl *pctrl;
+       struct resource *res;
+       int ret;
+
+       pctrl = devm_kzalloc(&pdev->dev, sizeof(*pctrl), GFP_KERNEL);
+       if (!pctrl) {
+               dev_err(&pdev->dev, "Can't allocate msm_pinctrl\n");
+               return -ENOMEM;
+       }
+       pctrl->dev = &pdev->dev;
+       pctrl->soc = soc_data;
+       pctrl->chip = msm_gpio_template;
+
+       spin_lock_init(&pctrl->lock);
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       pctrl->regs = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(pctrl->regs))
+               return PTR_ERR(pctrl->regs);
+
+       pctrl->irq = platform_get_irq(pdev, 0);
+       if (pctrl->irq < 0) {
+               dev_err(&pdev->dev, "No interrupt defined for msmgpio\n");
+               return pctrl->irq;
+       }
+
+       msm_pinctrl_desc.name = dev_name(&pdev->dev);
+       msm_pinctrl_desc.pins = pctrl->soc->pins;
+       msm_pinctrl_desc.npins = pctrl->soc->npins;
+       pctrl->pctrl = pinctrl_register(&msm_pinctrl_desc, &pdev->dev, pctrl);
+       if (!pctrl->pctrl) {
+               dev_err(&pdev->dev, "Couldn't register pinctrl driver\n");
+               return -ENODEV;
+       }
+
+       ret = msm_gpio_init(pctrl);
+       if (ret) {
+               pinctrl_unregister(pctrl->pctrl);
+               return ret;
+       }
+
+       platform_set_drvdata(pdev, pctrl);
+
+       dev_dbg(&pdev->dev, "Probed Qualcomm pinctrl driver\n");
+
+       return 0;
+}
+EXPORT_SYMBOL(msm_pinctrl_probe);
+
+int msm_pinctrl_remove(struct platform_device *pdev)
+{
+       struct msm_pinctrl *pctrl = platform_get_drvdata(pdev);
+       int ret;
+
+       ret = gpiochip_remove(&pctrl->chip);
+       if (ret) {
+               dev_err(&pdev->dev, "Failed to remove gpiochip\n");
+               return ret;
+       }
+
+       pinctrl_unregister(pctrl->pctrl);
+
+       return 0;
+}
+EXPORT_SYMBOL(msm_pinctrl_remove);
+
diff --git a/drivers/pinctrl/qcom/pinctrl-msm.h b/drivers/pinctrl/qcom/pinctrl-msm.h
new file mode 100644 (file)
index 0000000..7b2a227
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2013, Sony Mobile Communications AB.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#ifndef __PINCTRL_MSM_H__
+#define __PINCTRL_MSM_H__
+
+struct pinctrl_pin_desc;
+
+/**
+ * struct msm_function - a pinmux function
+ * @name:    Name of the pinmux function.
+ * @groups:  List of pingroups for this function.
+ * @ngroups: Number of entries in @groups.
+ */
+struct msm_function {
+       const char *name;
+       const char * const *groups;
+       unsigned ngroups;
+};
+
+/**
+ * struct msm_pingroup - Qualcomm pingroup definition
+ * @name:                 Name of the pingroup.
+ * @pins:                A list of pins assigned to this pingroup.
+ * @npins:               Number of entries in @pins.
+ * @funcs:                A list of pinmux functions that can be selected for
+ *                        this group. The index of the selected function is used
+ *                        for programming the function selector.
+ *                        Entries should be indices into the groups list of the
+ *                        struct msm_pinctrl_soc_data.
+ * @ctl_reg:              Offset of the register holding control bits for this group.
+ * @io_reg:               Offset of the register holding input/output bits for this group.
+ * @intr_cfg_reg:         Offset of the register holding interrupt configuration bits.
+ * @intr_status_reg:      Offset of the register holding the status bits for this group.
+ * @intr_target_reg:      Offset of the register specifying routing of the interrupts
+ *                        from this group.
+ * @mux_bit:              Offset in @ctl_reg for the pinmux function selection.
+ * @pull_bit:             Offset in @ctl_reg for the bias configuration.
+ * @drv_bit:              Offset in @ctl_reg for the drive strength configuration.
+ * @oe_bit:               Offset in @ctl_reg for controlling output enable.
+ * @in_bit:               Offset in @io_reg for the input bit value.
+ * @out_bit:              Offset in @io_reg for the output bit value.
+ * @intr_enable_bit:      Offset in @intr_cfg_reg for enabling the interrupt for this group.
+ * @intr_status_bit:      Offset in @intr_status_reg for reading and acking the interrupt
+ *                        status.
+ * @intr_target_bit:      Offset in @intr_target_reg for configuring the interrupt routing.
+ * @intr_raw_status_bit:  Offset in @intr_cfg_reg for the raw status bit.
+ * @intr_polarity_bit:    Offset in @intr_cfg_reg for specifying polarity of the interrupt.
+ * @intr_detection_bit:   Offset in @intr_cfg_reg for specifying interrupt type.
+ * @intr_detection_width: Number of bits used for specifying interrupt type,
+ *                        Should be 2 for SoCs that can detect both edges in hardware,
+ *                        otherwise 1.
+ */
+struct msm_pingroup {
+       const char *name;
+       const unsigned *pins;
+       unsigned npins;
+
+       unsigned *funcs;
+       unsigned nfuncs;
+
+       s16 ctl_reg;
+       s16 io_reg;
+       s16 intr_cfg_reg;
+       s16 intr_status_reg;
+       s16 intr_target_reg;
+
+       unsigned mux_bit:5;
+
+       unsigned pull_bit:5;
+       unsigned drv_bit:5;
+
+       unsigned oe_bit:5;
+       unsigned in_bit:5;
+       unsigned out_bit:5;
+
+       unsigned intr_enable_bit:5;
+       unsigned intr_status_bit:5;
+       unsigned intr_ack_high:1;
+
+       unsigned intr_target_bit:5;
+       unsigned intr_raw_status_bit:5;
+       unsigned intr_polarity_bit:5;
+       unsigned intr_detection_bit:5;
+       unsigned intr_detection_width:5;
+};
+
+/**
+ * struct msm_pinctrl_soc_data - Qualcomm pin controller driver configuration
+ * @pins:       An array describing all pins the pin controller affects.
+ * @npins:      The number of entries in @pins.
+ * @functions:  An array describing all mux functions the SoC supports.
+ * @nfunctions: The number of entries in @functions.
+ * @groups:     An array describing all pin groups the pin SoC supports.
+ * @ngroups:    The numbmer of entries in @groups.
+ * @ngpio:      The number of pingroups the driver should expose as GPIOs.
+ */
+struct msm_pinctrl_soc_data {
+       const struct pinctrl_pin_desc *pins;
+       unsigned npins;
+       const struct msm_function *functions;
+       unsigned nfunctions;
+       const struct msm_pingroup *groups;
+       unsigned ngroups;
+       unsigned ngpios;
+};
+
+int msm_pinctrl_probe(struct platform_device *pdev,
+                     const struct msm_pinctrl_soc_data *soc_data);
+int msm_pinctrl_remove(struct platform_device *pdev);
+
+#endif
diff --git a/drivers/pinctrl/qcom/pinctrl-msm8960.c b/drivers/pinctrl/qcom/pinctrl-msm8960.c
new file mode 100644 (file)
index 0000000..3504703
--- /dev/null
@@ -0,0 +1,1282 @@
+/*
+ * Copyright (c) 2014, Sony Mobile Communications AB.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+
+#include "pinctrl-msm.h"
+
+static const struct pinctrl_pin_desc msm8960_pins[] = {
+       PINCTRL_PIN(0, "GPIO_0"),
+       PINCTRL_PIN(1, "GPIO_1"),
+       PINCTRL_PIN(2, "GPIO_2"),
+       PINCTRL_PIN(3, "GPIO_3"),
+       PINCTRL_PIN(4, "GPIO_4"),
+       PINCTRL_PIN(5, "GPIO_5"),
+       PINCTRL_PIN(6, "GPIO_6"),
+       PINCTRL_PIN(7, "GPIO_7"),
+       PINCTRL_PIN(8, "GPIO_8"),
+       PINCTRL_PIN(9, "GPIO_9"),
+       PINCTRL_PIN(10, "GPIO_10"),
+       PINCTRL_PIN(11, "GPIO_11"),
+       PINCTRL_PIN(12, "GPIO_12"),
+       PINCTRL_PIN(13, "GPIO_13"),
+       PINCTRL_PIN(14, "GPIO_14"),
+       PINCTRL_PIN(15, "GPIO_15"),
+       PINCTRL_PIN(16, "GPIO_16"),
+       PINCTRL_PIN(17, "GPIO_17"),
+       PINCTRL_PIN(18, "GPIO_18"),
+       PINCTRL_PIN(19, "GPIO_19"),
+       PINCTRL_PIN(20, "GPIO_20"),
+       PINCTRL_PIN(21, "GPIO_21"),
+       PINCTRL_PIN(22, "GPIO_22"),
+       PINCTRL_PIN(23, "GPIO_23"),
+       PINCTRL_PIN(24, "GPIO_24"),
+       PINCTRL_PIN(25, "GPIO_25"),
+       PINCTRL_PIN(26, "GPIO_26"),
+       PINCTRL_PIN(27, "GPIO_27"),
+       PINCTRL_PIN(28, "GPIO_28"),
+       PINCTRL_PIN(29, "GPIO_29"),
+       PINCTRL_PIN(30, "GPIO_30"),
+       PINCTRL_PIN(31, "GPIO_31"),
+       PINCTRL_PIN(32, "GPIO_32"),
+       PINCTRL_PIN(33, "GPIO_33"),
+       PINCTRL_PIN(34, "GPIO_34"),
+       PINCTRL_PIN(35, "GPIO_35"),
+       PINCTRL_PIN(36, "GPIO_36"),
+       PINCTRL_PIN(37, "GPIO_37"),
+       PINCTRL_PIN(38, "GPIO_38"),
+       PINCTRL_PIN(39, "GPIO_39"),
+       PINCTRL_PIN(40, "GPIO_40"),
+       PINCTRL_PIN(41, "GPIO_41"),
+       PINCTRL_PIN(42, "GPIO_42"),
+       PINCTRL_PIN(43, "GPIO_43"),
+       PINCTRL_PIN(44, "GPIO_44"),
+       PINCTRL_PIN(45, "GPIO_45"),
+       PINCTRL_PIN(46, "GPIO_46"),
+       PINCTRL_PIN(47, "GPIO_47"),
+       PINCTRL_PIN(48, "GPIO_48"),
+       PINCTRL_PIN(49, "GPIO_49"),
+       PINCTRL_PIN(50, "GPIO_50"),
+       PINCTRL_PIN(51, "GPIO_51"),
+       PINCTRL_PIN(52, "GPIO_52"),
+       PINCTRL_PIN(53, "GPIO_53"),
+       PINCTRL_PIN(54, "GPIO_54"),
+       PINCTRL_PIN(55, "GPIO_55"),
+       PINCTRL_PIN(56, "GPIO_56"),
+       PINCTRL_PIN(57, "GPIO_57"),
+       PINCTRL_PIN(58, "GPIO_58"),
+       PINCTRL_PIN(59, "GPIO_59"),
+       PINCTRL_PIN(60, "GPIO_60"),
+       PINCTRL_PIN(61, "GPIO_61"),
+       PINCTRL_PIN(62, "GPIO_62"),
+       PINCTRL_PIN(63, "GPIO_63"),
+       PINCTRL_PIN(64, "GPIO_64"),
+       PINCTRL_PIN(65, "GPIO_65"),
+       PINCTRL_PIN(66, "GPIO_66"),
+       PINCTRL_PIN(67, "GPIO_67"),
+       PINCTRL_PIN(68, "GPIO_68"),
+       PINCTRL_PIN(69, "GPIO_69"),
+       PINCTRL_PIN(70, "GPIO_70"),
+       PINCTRL_PIN(71, "GPIO_71"),
+       PINCTRL_PIN(72, "GPIO_72"),
+       PINCTRL_PIN(73, "GPIO_73"),
+       PINCTRL_PIN(74, "GPIO_74"),
+       PINCTRL_PIN(75, "GPIO_75"),
+       PINCTRL_PIN(76, "GPIO_76"),
+       PINCTRL_PIN(77, "GPIO_77"),
+       PINCTRL_PIN(78, "GPIO_78"),
+       PINCTRL_PIN(79, "GPIO_79"),
+       PINCTRL_PIN(80, "GPIO_80"),
+       PINCTRL_PIN(81, "GPIO_81"),
+       PINCTRL_PIN(82, "GPIO_82"),
+       PINCTRL_PIN(83, "GPIO_83"),
+       PINCTRL_PIN(84, "GPIO_84"),
+       PINCTRL_PIN(85, "GPIO_85"),
+       PINCTRL_PIN(86, "GPIO_86"),
+       PINCTRL_PIN(87, "GPIO_87"),
+       PINCTRL_PIN(88, "GPIO_88"),
+       PINCTRL_PIN(89, "GPIO_89"),
+       PINCTRL_PIN(90, "GPIO_90"),
+       PINCTRL_PIN(91, "GPIO_91"),
+       PINCTRL_PIN(92, "GPIO_92"),
+       PINCTRL_PIN(93, "GPIO_93"),
+       PINCTRL_PIN(94, "GPIO_94"),
+       PINCTRL_PIN(95, "GPIO_95"),
+       PINCTRL_PIN(96, "GPIO_96"),
+       PINCTRL_PIN(97, "GPIO_97"),
+       PINCTRL_PIN(98, "GPIO_98"),
+       PINCTRL_PIN(99, "GPIO_99"),
+       PINCTRL_PIN(100, "GPIO_100"),
+       PINCTRL_PIN(101, "GPIO_101"),
+       PINCTRL_PIN(102, "GPIO_102"),
+       PINCTRL_PIN(103, "GPIO_103"),
+       PINCTRL_PIN(104, "GPIO_104"),
+       PINCTRL_PIN(105, "GPIO_105"),
+       PINCTRL_PIN(106, "GPIO_106"),
+       PINCTRL_PIN(107, "GPIO_107"),
+       PINCTRL_PIN(108, "GPIO_108"),
+       PINCTRL_PIN(109, "GPIO_109"),
+       PINCTRL_PIN(110, "GPIO_110"),
+       PINCTRL_PIN(111, "GPIO_111"),
+       PINCTRL_PIN(112, "GPIO_112"),
+       PINCTRL_PIN(113, "GPIO_113"),
+       PINCTRL_PIN(114, "GPIO_114"),
+       PINCTRL_PIN(115, "GPIO_115"),
+       PINCTRL_PIN(116, "GPIO_116"),
+       PINCTRL_PIN(117, "GPIO_117"),
+       PINCTRL_PIN(118, "GPIO_118"),
+       PINCTRL_PIN(119, "GPIO_119"),
+       PINCTRL_PIN(120, "GPIO_120"),
+       PINCTRL_PIN(121, "GPIO_121"),
+       PINCTRL_PIN(122, "GPIO_122"),
+       PINCTRL_PIN(123, "GPIO_123"),
+       PINCTRL_PIN(124, "GPIO_124"),
+       PINCTRL_PIN(125, "GPIO_125"),
+       PINCTRL_PIN(126, "GPIO_126"),
+       PINCTRL_PIN(127, "GPIO_127"),
+       PINCTRL_PIN(128, "GPIO_128"),
+       PINCTRL_PIN(129, "GPIO_129"),
+       PINCTRL_PIN(130, "GPIO_130"),
+       PINCTRL_PIN(131, "GPIO_131"),
+       PINCTRL_PIN(132, "GPIO_132"),
+       PINCTRL_PIN(133, "GPIO_133"),
+       PINCTRL_PIN(134, "GPIO_134"),
+       PINCTRL_PIN(135, "GPIO_135"),
+       PINCTRL_PIN(136, "GPIO_136"),
+       PINCTRL_PIN(137, "GPIO_137"),
+       PINCTRL_PIN(138, "GPIO_138"),
+       PINCTRL_PIN(139, "GPIO_139"),
+       PINCTRL_PIN(140, "GPIO_140"),
+       PINCTRL_PIN(141, "GPIO_141"),
+       PINCTRL_PIN(142, "GPIO_142"),
+       PINCTRL_PIN(143, "GPIO_143"),
+       PINCTRL_PIN(144, "GPIO_144"),
+       PINCTRL_PIN(145, "GPIO_145"),
+       PINCTRL_PIN(146, "GPIO_146"),
+       PINCTRL_PIN(147, "GPIO_147"),
+       PINCTRL_PIN(148, "GPIO_148"),
+       PINCTRL_PIN(149, "GPIO_149"),
+       PINCTRL_PIN(150, "GPIO_150"),
+       PINCTRL_PIN(151, "GPIO_151"),
+
+       PINCTRL_PIN(152, "SDC1_CLK"),
+       PINCTRL_PIN(153, "SDC1_CMD"),
+       PINCTRL_PIN(154, "SDC1_DATA"),
+       PINCTRL_PIN(155, "SDC3_CLK"),
+       PINCTRL_PIN(156, "SDC3_CMD"),
+       PINCTRL_PIN(157, "SDC3_DATA"),
+};
+
+#define DECLARE_MSM_GPIO_PINS(pin) static const unsigned int gpio##pin##_pins[] = { pin }
+DECLARE_MSM_GPIO_PINS(0);
+DECLARE_MSM_GPIO_PINS(1);
+DECLARE_MSM_GPIO_PINS(2);
+DECLARE_MSM_GPIO_PINS(3);
+DECLARE_MSM_GPIO_PINS(4);
+DECLARE_MSM_GPIO_PINS(5);
+DECLARE_MSM_GPIO_PINS(6);
+DECLARE_MSM_GPIO_PINS(7);
+DECLARE_MSM_GPIO_PINS(8);
+DECLARE_MSM_GPIO_PINS(9);
+DECLARE_MSM_GPIO_PINS(10);
+DECLARE_MSM_GPIO_PINS(11);
+DECLARE_MSM_GPIO_PINS(12);
+DECLARE_MSM_GPIO_PINS(13);
+DECLARE_MSM_GPIO_PINS(14);
+DECLARE_MSM_GPIO_PINS(15);
+DECLARE_MSM_GPIO_PINS(16);
+DECLARE_MSM_GPIO_PINS(17);
+DECLARE_MSM_GPIO_PINS(18);
+DECLARE_MSM_GPIO_PINS(19);
+DECLARE_MSM_GPIO_PINS(20);
+DECLARE_MSM_GPIO_PINS(21);
+DECLARE_MSM_GPIO_PINS(22);
+DECLARE_MSM_GPIO_PINS(23);
+DECLARE_MSM_GPIO_PINS(24);
+DECLARE_MSM_GPIO_PINS(25);
+DECLARE_MSM_GPIO_PINS(26);
+DECLARE_MSM_GPIO_PINS(27);
+DECLARE_MSM_GPIO_PINS(28);
+DECLARE_MSM_GPIO_PINS(29);
+DECLARE_MSM_GPIO_PINS(30);
+DECLARE_MSM_GPIO_PINS(31);
+DECLARE_MSM_GPIO_PINS(32);
+DECLARE_MSM_GPIO_PINS(33);
+DECLARE_MSM_GPIO_PINS(34);
+DECLARE_MSM_GPIO_PINS(35);
+DECLARE_MSM_GPIO_PINS(36);
+DECLARE_MSM_GPIO_PINS(37);
+DECLARE_MSM_GPIO_PINS(38);
+DECLARE_MSM_GPIO_PINS(39);
+DECLARE_MSM_GPIO_PINS(40);
+DECLARE_MSM_GPIO_PINS(41);
+DECLARE_MSM_GPIO_PINS(42);
+DECLARE_MSM_GPIO_PINS(43);
+DECLARE_MSM_GPIO_PINS(44);
+DECLARE_MSM_GPIO_PINS(45);
+DECLARE_MSM_GPIO_PINS(46);
+DECLARE_MSM_GPIO_PINS(47);
+DECLARE_MSM_GPIO_PINS(48);
+DECLARE_MSM_GPIO_PINS(49);
+DECLARE_MSM_GPIO_PINS(50);
+DECLARE_MSM_GPIO_PINS(51);
+DECLARE_MSM_GPIO_PINS(52);
+DECLARE_MSM_GPIO_PINS(53);
+DECLARE_MSM_GPIO_PINS(54);
+DECLARE_MSM_GPIO_PINS(55);
+DECLARE_MSM_GPIO_PINS(56);
+DECLARE_MSM_GPIO_PINS(57);
+DECLARE_MSM_GPIO_PINS(58);
+DECLARE_MSM_GPIO_PINS(59);
+DECLARE_MSM_GPIO_PINS(60);
+DECLARE_MSM_GPIO_PINS(61);
+DECLARE_MSM_GPIO_PINS(62);
+DECLARE_MSM_GPIO_PINS(63);
+DECLARE_MSM_GPIO_PINS(64);
+DECLARE_MSM_GPIO_PINS(65);
+DECLARE_MSM_GPIO_PINS(66);
+DECLARE_MSM_GPIO_PINS(67);
+DECLARE_MSM_GPIO_PINS(68);
+DECLARE_MSM_GPIO_PINS(69);
+DECLARE_MSM_GPIO_PINS(70);
+DECLARE_MSM_GPIO_PINS(71);
+DECLARE_MSM_GPIO_PINS(72);
+DECLARE_MSM_GPIO_PINS(73);
+DECLARE_MSM_GPIO_PINS(74);
+DECLARE_MSM_GPIO_PINS(75);
+DECLARE_MSM_GPIO_PINS(76);
+DECLARE_MSM_GPIO_PINS(77);
+DECLARE_MSM_GPIO_PINS(78);
+DECLARE_MSM_GPIO_PINS(79);
+DECLARE_MSM_GPIO_PINS(80);
+DECLARE_MSM_GPIO_PINS(81);
+DECLARE_MSM_GPIO_PINS(82);
+DECLARE_MSM_GPIO_PINS(83);
+DECLARE_MSM_GPIO_PINS(84);
+DECLARE_MSM_GPIO_PINS(85);
+DECLARE_MSM_GPIO_PINS(86);
+DECLARE_MSM_GPIO_PINS(87);
+DECLARE_MSM_GPIO_PINS(88);
+DECLARE_MSM_GPIO_PINS(89);
+DECLARE_MSM_GPIO_PINS(90);
+DECLARE_MSM_GPIO_PINS(91);
+DECLARE_MSM_GPIO_PINS(92);
+DECLARE_MSM_GPIO_PINS(93);
+DECLARE_MSM_GPIO_PINS(94);
+DECLARE_MSM_GPIO_PINS(95);
+DECLARE_MSM_GPIO_PINS(96);
+DECLARE_MSM_GPIO_PINS(97);
+DECLARE_MSM_GPIO_PINS(98);
+DECLARE_MSM_GPIO_PINS(99);
+DECLARE_MSM_GPIO_PINS(100);
+DECLARE_MSM_GPIO_PINS(101);
+DECLARE_MSM_GPIO_PINS(102);
+DECLARE_MSM_GPIO_PINS(103);
+DECLARE_MSM_GPIO_PINS(104);
+DECLARE_MSM_GPIO_PINS(105);
+DECLARE_MSM_GPIO_PINS(106);
+DECLARE_MSM_GPIO_PINS(107);
+DECLARE_MSM_GPIO_PINS(108);
+DECLARE_MSM_GPIO_PINS(109);
+DECLARE_MSM_GPIO_PINS(110);
+DECLARE_MSM_GPIO_PINS(111);
+DECLARE_MSM_GPIO_PINS(112);
+DECLARE_MSM_GPIO_PINS(113);
+DECLARE_MSM_GPIO_PINS(114);
+DECLARE_MSM_GPIO_PINS(115);
+DECLARE_MSM_GPIO_PINS(116);
+DECLARE_MSM_GPIO_PINS(117);
+DECLARE_MSM_GPIO_PINS(118);
+DECLARE_MSM_GPIO_PINS(119);
+DECLARE_MSM_GPIO_PINS(120);
+DECLARE_MSM_GPIO_PINS(121);
+DECLARE_MSM_GPIO_PINS(122);
+DECLARE_MSM_GPIO_PINS(123);
+DECLARE_MSM_GPIO_PINS(124);
+DECLARE_MSM_GPIO_PINS(125);
+DECLARE_MSM_GPIO_PINS(126);
+DECLARE_MSM_GPIO_PINS(127);
+DECLARE_MSM_GPIO_PINS(128);
+DECLARE_MSM_GPIO_PINS(129);
+DECLARE_MSM_GPIO_PINS(130);
+DECLARE_MSM_GPIO_PINS(131);
+DECLARE_MSM_GPIO_PINS(132);
+DECLARE_MSM_GPIO_PINS(133);
+DECLARE_MSM_GPIO_PINS(134);
+DECLARE_MSM_GPIO_PINS(135);
+DECLARE_MSM_GPIO_PINS(136);
+DECLARE_MSM_GPIO_PINS(137);
+DECLARE_MSM_GPIO_PINS(138);
+DECLARE_MSM_GPIO_PINS(139);
+DECLARE_MSM_GPIO_PINS(140);
+DECLARE_MSM_GPIO_PINS(141);
+DECLARE_MSM_GPIO_PINS(142);
+DECLARE_MSM_GPIO_PINS(143);
+DECLARE_MSM_GPIO_PINS(144);
+DECLARE_MSM_GPIO_PINS(145);
+DECLARE_MSM_GPIO_PINS(146);
+DECLARE_MSM_GPIO_PINS(147);
+DECLARE_MSM_GPIO_PINS(148);
+DECLARE_MSM_GPIO_PINS(149);
+DECLARE_MSM_GPIO_PINS(150);
+DECLARE_MSM_GPIO_PINS(151);
+
+static const unsigned int sdc1_clk_pins[] = { 152 };
+static const unsigned int sdc1_cmd_pins[] = { 153 };
+static const unsigned int sdc1_data_pins[] = { 154 };
+static const unsigned int sdc3_clk_pins[] = { 155 };
+static const unsigned int sdc3_cmd_pins[] = { 156 };
+static const unsigned int sdc3_data_pins[] = { 157 };
+
+#define FUNCTION(fname)                                        \
+       [MSM_MUX_##fname] = {                           \
+               .name = #fname,                         \
+               .groups = fname##_groups,               \
+               .ngroups = ARRAY_SIZE(fname##_groups),  \
+       }
+
+#define PINGROUP(id, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11) \
+       {                                               \
+               .name = "gpio" #id,                     \
+               .pins = gpio##id##_pins,                \
+               .npins = ARRAY_SIZE(gpio##id##_pins),   \
+               .funcs = (int[]){                       \
+                       MSM_MUX_gpio,                   \
+                       MSM_MUX_##f1,                   \
+                       MSM_MUX_##f2,                   \
+                       MSM_MUX_##f3,                   \
+                       MSM_MUX_##f4,                   \
+                       MSM_MUX_##f5,                   \
+                       MSM_MUX_##f6,                   \
+                       MSM_MUX_##f7,                   \
+                       MSM_MUX_##f8,                   \
+                       MSM_MUX_##f9,                   \
+                       MSM_MUX_##f10,                  \
+                       MSM_MUX_##f11                   \
+               },                                      \
+               .nfuncs = 12,                           \
+               .ctl_reg = 0x1000 + 0x10 * id,          \
+               .io_reg = 0x1004 + 0x10 * id,           \
+               .intr_cfg_reg = 0x1008 + 0x10 * id,     \
+               .intr_status_reg = 0x100c + 0x10 * id,  \
+               .intr_target_reg = 0x400 + 0x4 * id,    \
+               .mux_bit = 2,                           \
+               .pull_bit = 0,                          \
+               .drv_bit = 6,                           \
+               .oe_bit = 9,                            \
+               .in_bit = 0,                            \
+               .out_bit = 1,                           \
+               .intr_enable_bit = 0,                   \
+               .intr_status_bit = 0,                   \
+               .intr_ack_high = 1,                     \
+               .intr_target_bit = 0,                   \
+               .intr_raw_status_bit = 3,               \
+               .intr_polarity_bit = 1,                 \
+               .intr_detection_bit = 2,                \
+               .intr_detection_width = 1,              \
+       }
+
+#define SDC_PINGROUP(pg_name, ctl, pull, drv)          \
+       {                                               \
+               .name = #pg_name,                       \
+               .pins = pg_name##_pins,                 \
+               .npins = ARRAY_SIZE(pg_name##_pins),    \
+               .ctl_reg = ctl,                         \
+               .io_reg = 0,                            \
+               .intr_cfg_reg = 0,                      \
+               .intr_status_reg = 0,                   \
+               .intr_target_reg = 0,                   \
+               .mux_bit = -1,                          \
+               .pull_bit = pull,                       \
+               .drv_bit = drv,                         \
+               .oe_bit = -1,                           \
+               .in_bit = -1,                           \
+               .out_bit = -1,                          \
+               .intr_enable_bit = -1,                  \
+               .intr_status_bit = -1,                  \
+               .intr_target_bit = -1,                  \
+               .intr_raw_status_bit = -1,              \
+               .intr_polarity_bit = -1,                \
+               .intr_detection_bit = -1,               \
+               .intr_detection_width = -1,             \
+       }
+
+enum msm8960_functions {
+       MSM_MUX_audio_pcm,
+       MSM_MUX_bt,
+       MSM_MUX_cam_mclk0,
+       MSM_MUX_cam_mclk1,
+       MSM_MUX_cam_mclk2,
+       MSM_MUX_codec_mic_i2s,
+       MSM_MUX_codec_spkr_i2s,
+       MSM_MUX_ext_gps,
+       MSM_MUX_fm,
+       MSM_MUX_gps_blanking,
+       MSM_MUX_gps_pps_in,
+       MSM_MUX_gps_pps_out,
+       MSM_MUX_gp_clk_0a,
+       MSM_MUX_gp_clk_0b,
+       MSM_MUX_gp_clk_1a,
+       MSM_MUX_gp_clk_1b,
+       MSM_MUX_gp_clk_2a,
+       MSM_MUX_gp_clk_2b,
+       MSM_MUX_gp_mn,
+       MSM_MUX_gp_pdm_0a,
+       MSM_MUX_gp_pdm_0b,
+       MSM_MUX_gp_pdm_1a,
+       MSM_MUX_gp_pdm_1b,
+       MSM_MUX_gp_pdm_2a,
+       MSM_MUX_gp_pdm_2b,
+       MSM_MUX_gpio,
+       MSM_MUX_gsbi1,
+       MSM_MUX_gsbi1_spi_cs1_n,
+       MSM_MUX_gsbi1_spi_cs2a_n,
+       MSM_MUX_gsbi1_spi_cs2b_n,
+       MSM_MUX_gsbi1_spi_cs3_n,
+       MSM_MUX_gsbi2,
+       MSM_MUX_gsbi2_spi_cs1_n,
+       MSM_MUX_gsbi2_spi_cs2_n,
+       MSM_MUX_gsbi2_spi_cs3_n,
+       MSM_MUX_gsbi3,
+       MSM_MUX_gsbi4,
+       MSM_MUX_gsbi4_3d_cam_i2c_l,
+       MSM_MUX_gsbi4_3d_cam_i2c_r,
+       MSM_MUX_gsbi5,
+       MSM_MUX_gsbi5_3d_cam_i2c_l,
+       MSM_MUX_gsbi5_3d_cam_i2c_r,
+       MSM_MUX_gsbi6,
+       MSM_MUX_gsbi7,
+       MSM_MUX_gsbi8,
+       MSM_MUX_gsbi9,
+       MSM_MUX_gsbi10,
+       MSM_MUX_gsbi11,
+       MSM_MUX_gsbi11_spi_cs1a_n,
+       MSM_MUX_gsbi11_spi_cs1b_n,
+       MSM_MUX_gsbi11_spi_cs2a_n,
+       MSM_MUX_gsbi11_spi_cs2b_n,
+       MSM_MUX_gsbi11_spi_cs3_n,
+       MSM_MUX_gsbi12,
+       MSM_MUX_hdmi_cec,
+       MSM_MUX_hdmi_ddc_clock,
+       MSM_MUX_hdmi_ddc_data,
+       MSM_MUX_hdmi_hot_plug_detect,
+       MSM_MUX_hsic,
+       MSM_MUX_mdp_vsync,
+       MSM_MUX_mi2s,
+       MSM_MUX_mic_i2s,
+       MSM_MUX_pmb_clk,
+       MSM_MUX_pmb_ext_ctrl,
+       MSM_MUX_ps_hold,
+       MSM_MUX_rpm_wdog,
+       MSM_MUX_sdc2,
+       MSM_MUX_sdc4,
+       MSM_MUX_sdc5,
+       MSM_MUX_slimbus1,
+       MSM_MUX_slimbus2,
+       MSM_MUX_spkr_i2s,
+       MSM_MUX_ssbi1,
+       MSM_MUX_ssbi2,
+       MSM_MUX_ssbi_ext_gps,
+       MSM_MUX_ssbi_pmic2,
+       MSM_MUX_ssbi_qpa1,
+       MSM_MUX_ssbi_ts,
+       MSM_MUX_tsif1,
+       MSM_MUX_tsif2,
+       MSM_MUX_ts_eoc,
+       MSM_MUX_usb_fs1,
+       MSM_MUX_usb_fs1_oe,
+       MSM_MUX_usb_fs1_oe_n,
+       MSM_MUX_usb_fs2,
+       MSM_MUX_usb_fs2_oe,
+       MSM_MUX_usb_fs2_oe_n,
+       MSM_MUX_vfe_camif_timer1_a,
+       MSM_MUX_vfe_camif_timer1_b,
+       MSM_MUX_vfe_camif_timer2,
+       MSM_MUX_vfe_camif_timer3_a,
+       MSM_MUX_vfe_camif_timer3_b,
+       MSM_MUX_vfe_camif_timer4_a,
+       MSM_MUX_vfe_camif_timer4_b,
+       MSM_MUX_vfe_camif_timer4_c,
+       MSM_MUX_vfe_camif_timer5_a,
+       MSM_MUX_vfe_camif_timer5_b,
+       MSM_MUX_vfe_camif_timer6_a,
+       MSM_MUX_vfe_camif_timer6_b,
+       MSM_MUX_vfe_camif_timer6_c,
+       MSM_MUX_vfe_camif_timer7_a,
+       MSM_MUX_vfe_camif_timer7_b,
+       MSM_MUX_vfe_camif_timer7_c,
+       MSM_MUX_wlan,
+       MSM_MUX_NA,
+};
+
+static const char * const audio_pcm_groups[] = {
+       "gpio63", "gpio64", "gpio65", "gpio66"
+};
+
+static const char * const bt_groups[] = {
+       "gpio28", "gpio29", "gpio83"
+};
+
+static const char * const cam_mclk0_groups[] = {
+       "gpio5"
+};
+
+static const char * const cam_mclk1_groups[] = {
+       "gpio4"
+};
+
+static const char * const cam_mclk2_groups[] = {
+       "gpio2"
+};
+
+static const char * const codec_mic_i2s_groups[] = {
+       "gpio54", "gpio55", "gpio56", "gpio57", "gpio58"
+};
+
+static const char * const codec_spkr_i2s_groups[] = {
+       "gpio59", "gpio60", "gpio61", "gpio62"
+};
+
+static const char * const ext_gps_groups[] = {
+       "gpio22", "gpio23", "gpio24", "gpio25"
+};
+
+static const char * const fm_groups[] = {
+       "gpio26", "gpio27"
+};
+
+static const char * const gps_blanking_groups[] = {
+       "gpio137"
+};
+
+static const char * const gps_pps_in_groups[] = {
+       "gpio37"
+};
+
+static const char * const gps_pps_out_groups[] = {
+       "gpio37"
+};
+
+static const char * const gp_clk_0a_groups[] = {
+       "gpio3"
+};
+
+static const char * const gp_clk_0b_groups[] = {
+       "gpio54"
+};
+
+static const char * const gp_clk_1a_groups[] = {
+       "gpio4"
+};
+
+static const char * const gp_clk_1b_groups[] = {
+       "gpio70"
+};
+
+static const char * const gp_clk_2a_groups[] = {
+       "gpio52"
+};
+
+static const char * const gp_clk_2b_groups[] = {
+       "gpio37"
+};
+
+static const char * const gp_mn_groups[] = {
+       "gpio2"
+};
+
+static const char * const gp_pdm_0a_groups[] = {
+       "gpio58"
+};
+
+static const char * const gp_pdm_0b_groups[] = {
+       "gpio39"
+};
+
+static const char * const gp_pdm_1a_groups[] = {
+       "gpio94"
+};
+
+static const char * const gp_pdm_1b_groups[] = {
+       "gpio64"
+};
+
+static const char * const gp_pdm_2a_groups[] = {
+       "gpio69"
+};
+
+static const char * const gp_pdm_2b_groups[] = {
+       "gpio53"
+};
+
+static const char * const gpio_groups[] = {
+       "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5", "gpio6", "gpio7",
+       "gpio8", "gpio9", "gpio10", "gpio11", "gpio12", "gpio13", "gpio14",
+       "gpio15", "gpio16", "gpio17", "gpio18", "gpio19", "gpio20", "gpio21",
+       "gpio22", "gpio23", "gpio24", "gpio25", "gpio26", "gpio27", "gpio28",
+       "gpio29", "gpio30", "gpio31", "gpio32", "gpio33", "gpio34", "gpio35",
+       "gpio36", "gpio37", "gpio38", "gpio39", "gpio40", "gpio41", "gpio42",
+       "gpio43", "gpio44", "gpio45", "gpio46", "gpio47", "gpio48", "gpio49",
+       "gpio50", "gpio51", "gpio52", "gpio53", "gpio54", "gpio55", "gpio56",
+       "gpio57", "gpio58", "gpio59", "gpio60", "gpio61", "gpio62", "gpio63",
+       "gpio64", "gpio65", "gpio66", "gpio67", "gpio68", "gpio69", "gpio70",
+       "gpio71", "gpio72", "gpio73", "gpio74", "gpio75", "gpio76", "gpio77",
+       "gpio78", "gpio79", "gpio80", "gpio81", "gpio82", "gpio83", "gpio84",
+       "gpio85", "gpio86", "gpio87", "gpio88", "gpio89", "gpio90", "gpio91",
+       "gpio92", "gpio93", "gpio94", "gpio95", "gpio96", "gpio97", "gpio98",
+       "gpio99", "gpio100", "gpio101", "gpio102", "gpio103", "gpio104",
+       "gpio105", "gpio106", "gpio107", "gpio108", "gpio109", "gpio110",
+       "gpio111", "gpio112", "gpio113", "gpio114", "gpio115", "gpio116",
+       "gpio117", "gpio118", "gpio119", "gpio120", "gpio121", "gpio122",
+       "gpio123", "gpio124", "gpio125", "gpio126", "gpio127", "gpio128",
+       "gpio129", "gpio130", "gpio131", "gpio132", "gpio133", "gpio134",
+       "gpio135", "gpio136", "gpio137", "gpio138", "gpio139", "gpio140",
+       "gpio141", "gpio142", "gpio143", "gpio144", "gpio145", "gpio146",
+       "gpio147", "gpio148", "gpio149", "gpio150", "gpio151"
+};
+
+static const char * const gsbi1_groups[] = {
+       "gpio6", "gpio7", "gpio8", "gpio9"
+};
+
+static const char * const gsbi1_spi_cs1_n_groups[] = {
+       "gpio14"
+};
+
+static const char * const gsbi1_spi_cs2a_n_groups[] = {
+       "gpio15"
+};
+
+static const char * const gsbi1_spi_cs2b_n_groups[] = {
+       "gpio17"
+};
+
+static const char * const gsbi1_spi_cs3_n_groups[] = {
+       "gpio16"
+};
+
+static const char * const gsbi2_groups[] = {
+       "gpio10", "gpio11", "gpio12", "gpio13"
+};
+
+static const char * const gsbi2_spi_cs1_n_groups[] = {
+       "gpio52"
+};
+
+static const char * const gsbi2_spi_cs2_n_groups[] = {
+       "gpio68"
+};
+
+static const char * const gsbi2_spi_cs3_n_groups[] = {
+       "gpio56"
+};
+
+static const char * const gsbi3_groups[] = {
+       "gpio14", "gpio15", "gpio16", "gpio17"
+};
+
+static const char * const gsbi4_groups[] = {
+       "gpio18", "gpio19", "gpio20", "gpio21"
+};
+
+static const char * const gsbi4_3d_cam_i2c_l_groups[] = {
+       "gpio18", "gpio19"
+};
+
+static const char * const gsbi4_3d_cam_i2c_r_groups[] = {
+       "gpio20", "gpio21"
+};
+
+static const char * const gsbi5_groups[] = {
+       "gpio22", "gpio23", "gpio24", "gpio25"
+};
+
+static const char * const gsbi5_3d_cam_i2c_l_groups[] = {
+       "gpio22", "gpio23"
+};
+
+static const char * const gsbi5_3d_cam_i2c_r_groups[] = {
+       "gpio24", "gpio25"
+};
+
+static const char * const gsbi6_groups[] = {
+       "gpio26", "gpio27", "gpio28", "gpio29"
+};
+
+static const char * const gsbi7_groups[] = {
+       "gpio30", "gpio31", "gpio32", "gpio33"
+};
+
+static const char * const gsbi8_groups[] = {
+       "gpio34", "gpio35", "gpio36", "gpio37"
+};
+
+static const char * const gsbi9_groups[] = {
+       "gpio93", "gpio94", "gpio95", "gpio96"
+};
+
+static const char * const gsbi10_groups[] = {
+       "gpio71", "gpio72", "gpio73", "gpio74"
+};
+
+static const char * const gsbi11_groups[] = {
+       "gpio38", "gpio39", "gpio40", "gpio41"
+};
+
+static const char * const gsbi11_spi_cs1a_n_groups[] = {
+       "gpio36"
+};
+
+static const char * const gsbi11_spi_cs1b_n_groups[] = {
+       "gpio18"
+};
+
+static const char * const gsbi11_spi_cs2a_n_groups[] = {
+       "gpio37"
+};
+
+static const char * const gsbi11_spi_cs2b_n_groups[] = {
+       "gpio19"
+};
+
+static const char * const gsbi11_spi_cs3_n_groups[] = {
+       "gpio76"
+};
+
+static const char * const gsbi12_groups[] = {
+       "gpio42", "gpio43", "gpio44", "gpio45"
+};
+
+static const char * const hdmi_cec_groups[] = {
+       "gpio99"
+};
+
+static const char * const hdmi_ddc_clock_groups[] = {
+       "gpio100"
+};
+
+static const char * const hdmi_ddc_data_groups[] = {
+       "gpio101"
+};
+
+static const char * const hdmi_hot_plug_detect_groups[] = {
+       "gpio102"
+};
+
+static const char * const hsic_groups[] = {
+       "gpio150", "gpio151"
+};
+
+static const char * const mdp_vsync_groups[] = {
+       "gpio0", "gpio1", "gpio19"
+};
+
+static const char * const mi2s_groups[] = {
+       "gpio47", "gpio48", "gpio49", "gpio50", "gpio51", "gpio52", "gpio53"
+};
+
+static const char * const mic_i2s_groups[] = {
+       "gpio71", "gpio72", "gpio73", "gpio74"
+};
+
+static const char * const pmb_clk_groups[] = {
+       "gpio21", "gpio86", "gpio112"
+};
+
+static const char * const pmb_ext_ctrl_groups[] = {
+       "gpio4", "gpio5"
+};
+
+static const char * const ps_hold_groups[] = {
+       "gpio108"
+};
+
+static const char * const rpm_wdog_groups[] = {
+       "gpio12"
+};
+
+static const char * const sdc2_groups[] = {
+       "gpio89", "gpio90", "gpio91", "gpio92", "gpio93", "gpio94", "gpio95",
+       "gpio96", "gpio97", "gpio98"
+};
+
+static const char * const sdc4_groups[] = {
+       "gpio83", "gpio84", "gpio85", "gpio86", "gpio87", "gpio88"
+};
+
+static const char * const sdc5_groups[] = {
+       "gpio77", "gpio78", "gpio79", "gpio80", "gpio81", "gpio82"
+};
+
+static const char * const slimbus1_groups[] = {
+       "gpio50", "gpio51", "gpio60", "gpio61"
+};
+
+static const char * const slimbus2_groups[] = {
+       "gpio42", "gpio43"
+};
+
+static const char * const spkr_i2s_groups[] = {
+       "gpio67", "gpio68", "gpio69", "gpio70"
+};
+
+static const char * const ssbi1_groups[] = {
+       "gpio141", "gpio143"
+};
+
+static const char * const ssbi2_groups[] = {
+       "gpio140", "gpio142"
+};
+
+static const char * const ssbi_ext_gps_groups[] = {
+       "gpio23"
+};
+
+static const char * const ssbi_pmic2_groups[] = {
+       "gpio149"
+};
+
+static const char * const ssbi_qpa1_groups[] = {
+       "gpio131"
+};
+
+static const char * const ssbi_ts_groups[] = {
+       "gpio10"
+};
+
+static const char * const tsif1_groups[] = {
+       "gpio75", "gpio76", "gpio77", "gpio82"
+};
+
+static const char * const tsif2_groups[] = {
+       "gpio78", "gpio79", "gpio80", "gpio81"
+};
+
+static const char * const ts_eoc_groups[] = {
+       "gpio11"
+};
+
+static const char * const usb_fs1_groups[] = {
+       "gpio32", "gpio33"
+};
+
+static const char * const usb_fs1_oe_groups[] = {
+       "gpio31"
+};
+
+static const char * const usb_fs1_oe_n_groups[] = {
+       "gpio31"
+};
+
+static const char * const usb_fs2_groups[] = {
+       "gpio34", "gpio35"
+};
+
+static const char * const usb_fs2_oe_groups[] = {
+       "gpio36"
+};
+
+static const char * const usb_fs2_oe_n_groups[] = {
+       "gpio36"
+};
+
+static const char * const vfe_camif_timer1_a_groups[] = {
+       "gpio2"
+};
+
+static const char * const vfe_camif_timer1_b_groups[] = {
+       "gpio38"
+};
+
+static const char * const vfe_camif_timer2_groups[] = {
+       "gpio3"
+};
+
+static const char * const vfe_camif_timer3_a_groups[] = {
+       "gpio4"
+};
+
+static const char * const vfe_camif_timer3_b_groups[] = {
+       "gpio151"
+};
+
+static const char * const vfe_camif_timer4_a_groups[] = {
+       "gpio65"
+};
+
+static const char * const vfe_camif_timer4_b_groups[] = {
+       "gpio150"
+};
+
+static const char * const vfe_camif_timer4_c_groups[] = {
+       "gpio10"
+};
+
+static const char * const vfe_camif_timer5_a_groups[] = {
+       "gpio66"
+};
+
+static const char * const vfe_camif_timer5_b_groups[] = {
+       "gpio39"
+};
+
+static const char * const vfe_camif_timer6_a_groups[] = {
+       "gpio71"
+};
+
+static const char * const vfe_camif_timer6_b_groups[] = {
+       "gpio0"
+};
+
+static const char * const vfe_camif_timer6_c_groups[] = {
+       "gpio18"
+};
+
+static const char * const vfe_camif_timer7_a_groups[] = {
+       "gpio67"
+};
+
+static const char * const vfe_camif_timer7_b_groups[] = {
+       "gpio1"
+};
+
+static const char * const vfe_camif_timer7_c_groups[] = {
+       "gpio19"
+};
+
+static const char * const wlan_groups[] = {
+       "gpio84", "gpio85", "gpio86", "gpio87", "gpio88"
+};
+
+static const struct msm_function msm8960_functions[] = {
+       FUNCTION(audio_pcm),
+       FUNCTION(bt),
+       FUNCTION(cam_mclk0),
+       FUNCTION(cam_mclk1),
+       FUNCTION(cam_mclk2),
+       FUNCTION(codec_mic_i2s),
+       FUNCTION(codec_spkr_i2s),
+       FUNCTION(ext_gps),
+       FUNCTION(fm),
+       FUNCTION(gps_blanking),
+       FUNCTION(gps_pps_in),
+       FUNCTION(gps_pps_out),
+       FUNCTION(gp_clk_0a),
+       FUNCTION(gp_clk_0b),
+       FUNCTION(gp_clk_1a),
+       FUNCTION(gp_clk_1b),
+       FUNCTION(gp_clk_2a),
+       FUNCTION(gp_clk_2b),
+       FUNCTION(gp_mn),
+       FUNCTION(gp_pdm_0a),
+       FUNCTION(gp_pdm_0b),
+       FUNCTION(gp_pdm_1a),
+       FUNCTION(gp_pdm_1b),
+       FUNCTION(gp_pdm_2a),
+       FUNCTION(gp_pdm_2b),
+       FUNCTION(gpio),
+       FUNCTION(gsbi1),
+       FUNCTION(gsbi1_spi_cs1_n),
+       FUNCTION(gsbi1_spi_cs2a_n),
+       FUNCTION(gsbi1_spi_cs2b_n),
+       FUNCTION(gsbi1_spi_cs3_n),
+       FUNCTION(gsbi2),
+       FUNCTION(gsbi2_spi_cs1_n),
+       FUNCTION(gsbi2_spi_cs2_n),
+       FUNCTION(gsbi2_spi_cs3_n),
+       FUNCTION(gsbi3),
+       FUNCTION(gsbi4),
+       FUNCTION(gsbi4_3d_cam_i2c_l),
+       FUNCTION(gsbi4_3d_cam_i2c_r),
+       FUNCTION(gsbi5),
+       FUNCTION(gsbi5_3d_cam_i2c_l),
+       FUNCTION(gsbi5_3d_cam_i2c_r),
+       FUNCTION(gsbi6),
+       FUNCTION(gsbi7),
+       FUNCTION(gsbi8),
+       FUNCTION(gsbi9),
+       FUNCTION(gsbi10),
+       FUNCTION(gsbi11),
+       FUNCTION(gsbi11_spi_cs1a_n),
+       FUNCTION(gsbi11_spi_cs1b_n),
+       FUNCTION(gsbi11_spi_cs2a_n),
+       FUNCTION(gsbi11_spi_cs2b_n),
+       FUNCTION(gsbi11_spi_cs3_n),
+       FUNCTION(gsbi12),
+       FUNCTION(hdmi_cec),
+       FUNCTION(hdmi_ddc_clock),
+       FUNCTION(hdmi_ddc_data),
+       FUNCTION(hdmi_hot_plug_detect),
+       FUNCTION(hsic),
+       FUNCTION(mdp_vsync),
+       FUNCTION(mi2s),
+       FUNCTION(mic_i2s),
+       FUNCTION(pmb_clk),
+       FUNCTION(pmb_ext_ctrl),
+       FUNCTION(ps_hold),
+       FUNCTION(rpm_wdog),
+       FUNCTION(sdc2),
+       FUNCTION(sdc4),
+       FUNCTION(sdc5),
+       FUNCTION(slimbus1),
+       FUNCTION(slimbus2),
+       FUNCTION(spkr_i2s),
+       FUNCTION(ssbi1),
+       FUNCTION(ssbi2),
+       FUNCTION(ssbi_ext_gps),
+       FUNCTION(ssbi_pmic2),
+       FUNCTION(ssbi_qpa1),
+       FUNCTION(ssbi_ts),
+       FUNCTION(tsif1),
+       FUNCTION(tsif2),
+       FUNCTION(ts_eoc),
+       FUNCTION(usb_fs1),
+       FUNCTION(usb_fs1_oe),
+       FUNCTION(usb_fs1_oe_n),
+       FUNCTION(usb_fs2),
+       FUNCTION(usb_fs2_oe),
+       FUNCTION(usb_fs2_oe_n),
+       FUNCTION(vfe_camif_timer1_a),
+       FUNCTION(vfe_camif_timer1_b),
+       FUNCTION(vfe_camif_timer2),
+       FUNCTION(vfe_camif_timer3_a),
+       FUNCTION(vfe_camif_timer3_b),
+       FUNCTION(vfe_camif_timer4_a),
+       FUNCTION(vfe_camif_timer4_b),
+       FUNCTION(vfe_camif_timer4_c),
+       FUNCTION(vfe_camif_timer5_a),
+       FUNCTION(vfe_camif_timer5_b),
+       FUNCTION(vfe_camif_timer6_a),
+       FUNCTION(vfe_camif_timer6_b),
+       FUNCTION(vfe_camif_timer6_c),
+       FUNCTION(vfe_camif_timer7_a),
+       FUNCTION(vfe_camif_timer7_b),
+       FUNCTION(vfe_camif_timer7_c),
+       FUNCTION(wlan),
+};
+
+static const struct msm_pingroup msm8960_groups[] = {
+       PINGROUP(0, mdp_vsync, vfe_camif_timer6_b, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(1, mdp_vsync, vfe_camif_timer7_b, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(2, vfe_camif_timer1_a, gp_mn, NA, cam_mclk2, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(3, vfe_camif_timer2, gp_clk_0a, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(4, vfe_camif_timer3_a, cam_mclk1, gp_clk_1a, pmb_ext_ctrl, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(5, cam_mclk0, pmb_ext_ctrl, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(6, gsbi1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(7, gsbi1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(8, gsbi1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(9, gsbi1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(10, gsbi2, ssbi_ts, NA, vfe_camif_timer4_c, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(11, gsbi2, ts_eoc, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(12, gsbi2, rpm_wdog, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(13, gsbi2, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(14, gsbi3, gsbi1_spi_cs1_n, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(15, gsbi3, gsbi1_spi_cs2a_n, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(16, gsbi3, gsbi1_spi_cs3_n, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(17, gsbi3, gsbi1_spi_cs2b_n, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(18, gsbi4, gsbi11_spi_cs1b_n, NA, NA, gsbi4_3d_cam_i2c_l, vfe_camif_timer6_c, NA, NA, NA, NA, NA),
+       PINGROUP(19, gsbi4, gsbi11_spi_cs2b_n, NA, mdp_vsync, NA, gsbi4_3d_cam_i2c_l, vfe_camif_timer7_c, NA, NA, NA, NA),
+       PINGROUP(20, gsbi4, gsbi4_3d_cam_i2c_r, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(21, gsbi4, pmb_clk, gsbi4_3d_cam_i2c_r, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(22, gsbi5, ext_gps, NA, NA, NA, NA, NA, NA, NA, gsbi5_3d_cam_i2c_l, NA),
+       PINGROUP(23, gsbi5, ssbi_ext_gps, NA, NA, NA, NA, NA, NA, NA, gsbi5_3d_cam_i2c_l, NA),
+       PINGROUP(24, gsbi5, ext_gps, NA, NA, NA, NA, NA, NA, NA, gsbi5_3d_cam_i2c_r, NA),
+       PINGROUP(25, gsbi5, ext_gps, NA, NA, NA, NA, NA, NA, NA, gsbi5_3d_cam_i2c_r, NA),
+       PINGROUP(26, fm, gsbi6, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(27, fm, gsbi6, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(28, bt, gsbi6, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(29, bt, gsbi6, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(30, gsbi7, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(31, gsbi7, usb_fs1_oe, usb_fs1_oe_n, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(32, gsbi7, usb_fs1, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(33, gsbi7, usb_fs1, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(34, gsbi8, usb_fs2, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(35, gsbi8, usb_fs2, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(36, gsbi8, usb_fs2_oe, usb_fs2_oe_n, gsbi11_spi_cs1a_n, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(37, gsbi8, gps_pps_out, gps_pps_in, gsbi11_spi_cs2a_n, gp_clk_2b, NA, NA, NA, NA, NA, NA),
+       PINGROUP(38, gsbi11, NA, NA, NA, NA, NA, NA, NA, NA, vfe_camif_timer1_b, NA),
+       PINGROUP(39, gsbi11, gp_pdm_0b, NA, NA, NA, NA, NA, NA, NA, NA, vfe_camif_timer5_b),
+       PINGROUP(40, gsbi11, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(41, gsbi11, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(42, gsbi12, slimbus2, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(43, gsbi12, slimbus2, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(44, gsbi12, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(45, gsbi12, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(46, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(47, mi2s, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(48, mi2s, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(49, mi2s, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(50, mi2s, slimbus1, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(51, mi2s, slimbus1, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(52, mi2s, gp_clk_2a, gsbi2_spi_cs1_n, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(53, mi2s, gp_pdm_2b, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(54, codec_mic_i2s, gp_clk_0b, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(55, codec_mic_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(56, codec_mic_i2s, gsbi2_spi_cs3_n, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(57, codec_mic_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(58, codec_mic_i2s, gp_pdm_0a, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(59, codec_spkr_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(60, slimbus1, codec_spkr_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(61, slimbus1, codec_spkr_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(62, codec_spkr_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(63, audio_pcm, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(64, audio_pcm, gp_pdm_1b, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(65, audio_pcm, vfe_camif_timer4_a, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(66, audio_pcm, vfe_camif_timer5_a, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(67, spkr_i2s, vfe_camif_timer7_a, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(68, spkr_i2s, gsbi2_spi_cs2_n, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(69, spkr_i2s, gp_pdm_2a, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(70, spkr_i2s, gp_clk_1b, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(71, mic_i2s, gsbi10, vfe_camif_timer6_a, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(72, mic_i2s, gsbi10, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(73, mic_i2s, gsbi10, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(74, mic_i2s, gsbi10, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(75, tsif1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(76, tsif1, gsbi11_spi_cs3_n, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(77, tsif1, sdc5, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(78, tsif2, sdc5, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(79, tsif2, sdc5, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(80, tsif2, sdc5, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(81, tsif2, sdc5, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(82, tsif1, sdc5, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(83, bt, sdc4, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(84, wlan, sdc4, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(85, wlan, sdc4, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(86, wlan, sdc4, pmb_clk, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(87, wlan, sdc4, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(88, wlan, sdc4, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(89, sdc2, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(90, sdc2, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(91, sdc2, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(92, sdc2, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(93, sdc2, gsbi9, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(94, sdc2, gsbi9, gp_pdm_1a, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(95, sdc2, gsbi9, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(96, sdc2, gsbi9, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(97, sdc2, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(98, sdc2, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(99, hdmi_cec, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(100, hdmi_ddc_clock, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(101, hdmi_ddc_data, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(102, hdmi_hot_plug_detect, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(103, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(104, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(105, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(106, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(107, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(108, ps_hold, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(109, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(110, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(111, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(112, NA, pmb_clk, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(113, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(114, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(115, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(116, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(117, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(118, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(119, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(120, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(121, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(122, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(123, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(124, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(125, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(126, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(127, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(128, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(129, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(130, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(131, NA, ssbi_qpa1, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(132, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(133, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(134, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(135, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(136, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(137, gps_blanking, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(138, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(139, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(140, ssbi2, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(141, ssbi1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(142, ssbi2, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(143, ssbi1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(144, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(145, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(146, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(147, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(148, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(149, ssbi_pmic2, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(150, hsic, NA, vfe_camif_timer4_b, NA, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(151, hsic, NA, vfe_camif_timer3_b, NA, NA, NA, NA, NA, NA, NA, NA),
+
+       SDC_PINGROUP(sdc1_clk, 0x20a0, 13, 6),
+       SDC_PINGROUP(sdc1_cmd, 0x20a0, 11, 3),
+       SDC_PINGROUP(sdc1_data, 0x20a0, 9, 0),
+
+       SDC_PINGROUP(sdc3_clk, 0x20a4, 14, 6),
+       SDC_PINGROUP(sdc3_cmd, 0x20a4, 11, 3),
+       SDC_PINGROUP(sdc3_data, 0x20a4, 9, 0),
+};
+
+#define NUM_GPIO_PINGROUPS 152
+
+static const struct msm_pinctrl_soc_data msm8960_pinctrl = {
+       .pins = msm8960_pins,
+       .npins = ARRAY_SIZE(msm8960_pins),
+       .functions = msm8960_functions,
+       .nfunctions = ARRAY_SIZE(msm8960_functions),
+       .groups = msm8960_groups,
+       .ngroups = ARRAY_SIZE(msm8960_groups),
+       .ngpios = NUM_GPIO_PINGROUPS,
+};
+
+static int msm8960_pinctrl_probe(struct platform_device *pdev)
+{
+       return msm_pinctrl_probe(pdev, &msm8960_pinctrl);
+}
+
+static const struct of_device_id msm8960_pinctrl_of_match[] = {
+       { .compatible = "qcom,msm8960-pinctrl", },
+       { },
+};
+
+static struct platform_driver msm8960_pinctrl_driver = {
+       .driver = {
+               .name = "msm8960-pinctrl",
+               .owner = THIS_MODULE,
+               .of_match_table = msm8960_pinctrl_of_match,
+       },
+       .probe = msm8960_pinctrl_probe,
+       .remove = msm_pinctrl_remove,
+};
+
+static int __init msm8960_pinctrl_init(void)
+{
+       return platform_driver_register(&msm8960_pinctrl_driver);
+}
+arch_initcall(msm8960_pinctrl_init);
+
+static void __exit msm8960_pinctrl_exit(void)
+{
+       platform_driver_unregister(&msm8960_pinctrl_driver);
+}
+module_exit(msm8960_pinctrl_exit);
+
+MODULE_AUTHOR("Bjorn Andersson <bjorn.andersson@sonymobile.com>");
+MODULE_DESCRIPTION("Qualcomm MSM8960 pinctrl driver");
+MODULE_LICENSE("GPL v2");
+MODULE_DEVICE_TABLE(of, msm8960_pinctrl_of_match);
diff --git a/drivers/pinctrl/qcom/pinctrl-msm8x74.c b/drivers/pinctrl/qcom/pinctrl-msm8x74.c
new file mode 100644 (file)
index 0000000..8c97201
--- /dev/null
@@ -0,0 +1,1067 @@
+/*
+ * Copyright (c) 2013, Sony Mobile Communications AB.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pinctrl/pinctrl.h>
+
+#include "pinctrl-msm.h"
+
+static const struct pinctrl_pin_desc msm8x74_pins[] = {
+       PINCTRL_PIN(0, "GPIO_0"),
+       PINCTRL_PIN(1, "GPIO_1"),
+       PINCTRL_PIN(2, "GPIO_2"),
+       PINCTRL_PIN(3, "GPIO_3"),
+       PINCTRL_PIN(4, "GPIO_4"),
+       PINCTRL_PIN(5, "GPIO_5"),
+       PINCTRL_PIN(6, "GPIO_6"),
+       PINCTRL_PIN(7, "GPIO_7"),
+       PINCTRL_PIN(8, "GPIO_8"),
+       PINCTRL_PIN(9, "GPIO_9"),
+       PINCTRL_PIN(10, "GPIO_10"),
+       PINCTRL_PIN(11, "GPIO_11"),
+       PINCTRL_PIN(12, "GPIO_12"),
+       PINCTRL_PIN(13, "GPIO_13"),
+       PINCTRL_PIN(14, "GPIO_14"),
+       PINCTRL_PIN(15, "GPIO_15"),
+       PINCTRL_PIN(16, "GPIO_16"),
+       PINCTRL_PIN(17, "GPIO_17"),
+       PINCTRL_PIN(18, "GPIO_18"),
+       PINCTRL_PIN(19, "GPIO_19"),
+       PINCTRL_PIN(20, "GPIO_20"),
+       PINCTRL_PIN(21, "GPIO_21"),
+       PINCTRL_PIN(22, "GPIO_22"),
+       PINCTRL_PIN(23, "GPIO_23"),
+       PINCTRL_PIN(24, "GPIO_24"),
+       PINCTRL_PIN(25, "GPIO_25"),
+       PINCTRL_PIN(26, "GPIO_26"),
+       PINCTRL_PIN(27, "GPIO_27"),
+       PINCTRL_PIN(28, "GPIO_28"),
+       PINCTRL_PIN(29, "GPIO_29"),
+       PINCTRL_PIN(30, "GPIO_30"),
+       PINCTRL_PIN(31, "GPIO_31"),
+       PINCTRL_PIN(32, "GPIO_32"),
+       PINCTRL_PIN(33, "GPIO_33"),
+       PINCTRL_PIN(34, "GPIO_34"),
+       PINCTRL_PIN(35, "GPIO_35"),
+       PINCTRL_PIN(36, "GPIO_36"),
+       PINCTRL_PIN(37, "GPIO_37"),
+       PINCTRL_PIN(38, "GPIO_38"),
+       PINCTRL_PIN(39, "GPIO_39"),
+       PINCTRL_PIN(40, "GPIO_40"),
+       PINCTRL_PIN(41, "GPIO_41"),
+       PINCTRL_PIN(42, "GPIO_42"),
+       PINCTRL_PIN(43, "GPIO_43"),
+       PINCTRL_PIN(44, "GPIO_44"),
+       PINCTRL_PIN(45, "GPIO_45"),
+       PINCTRL_PIN(46, "GPIO_46"),
+       PINCTRL_PIN(47, "GPIO_47"),
+       PINCTRL_PIN(48, "GPIO_48"),
+       PINCTRL_PIN(49, "GPIO_49"),
+       PINCTRL_PIN(50, "GPIO_50"),
+       PINCTRL_PIN(51, "GPIO_51"),
+       PINCTRL_PIN(52, "GPIO_52"),
+       PINCTRL_PIN(53, "GPIO_53"),
+       PINCTRL_PIN(54, "GPIO_54"),
+       PINCTRL_PIN(55, "GPIO_55"),
+       PINCTRL_PIN(56, "GPIO_56"),
+       PINCTRL_PIN(57, "GPIO_57"),
+       PINCTRL_PIN(58, "GPIO_58"),
+       PINCTRL_PIN(59, "GPIO_59"),
+       PINCTRL_PIN(60, "GPIO_60"),
+       PINCTRL_PIN(61, "GPIO_61"),
+       PINCTRL_PIN(62, "GPIO_62"),
+       PINCTRL_PIN(63, "GPIO_63"),
+       PINCTRL_PIN(64, "GPIO_64"),
+       PINCTRL_PIN(65, "GPIO_65"),
+       PINCTRL_PIN(66, "GPIO_66"),
+       PINCTRL_PIN(67, "GPIO_67"),
+       PINCTRL_PIN(68, "GPIO_68"),
+       PINCTRL_PIN(69, "GPIO_69"),
+       PINCTRL_PIN(70, "GPIO_70"),
+       PINCTRL_PIN(71, "GPIO_71"),
+       PINCTRL_PIN(72, "GPIO_72"),
+       PINCTRL_PIN(73, "GPIO_73"),
+       PINCTRL_PIN(74, "GPIO_74"),
+       PINCTRL_PIN(75, "GPIO_75"),
+       PINCTRL_PIN(76, "GPIO_76"),
+       PINCTRL_PIN(77, "GPIO_77"),
+       PINCTRL_PIN(78, "GPIO_78"),
+       PINCTRL_PIN(79, "GPIO_79"),
+       PINCTRL_PIN(80, "GPIO_80"),
+       PINCTRL_PIN(81, "GPIO_81"),
+       PINCTRL_PIN(82, "GPIO_82"),
+       PINCTRL_PIN(83, "GPIO_83"),
+       PINCTRL_PIN(84, "GPIO_84"),
+       PINCTRL_PIN(85, "GPIO_85"),
+       PINCTRL_PIN(86, "GPIO_86"),
+       PINCTRL_PIN(87, "GPIO_87"),
+       PINCTRL_PIN(88, "GPIO_88"),
+       PINCTRL_PIN(89, "GPIO_89"),
+       PINCTRL_PIN(90, "GPIO_90"),
+       PINCTRL_PIN(91, "GPIO_91"),
+       PINCTRL_PIN(92, "GPIO_92"),
+       PINCTRL_PIN(93, "GPIO_93"),
+       PINCTRL_PIN(94, "GPIO_94"),
+       PINCTRL_PIN(95, "GPIO_95"),
+       PINCTRL_PIN(96, "GPIO_96"),
+       PINCTRL_PIN(97, "GPIO_97"),
+       PINCTRL_PIN(98, "GPIO_98"),
+       PINCTRL_PIN(99, "GPIO_99"),
+       PINCTRL_PIN(100, "GPIO_100"),
+       PINCTRL_PIN(101, "GPIO_101"),
+       PINCTRL_PIN(102, "GPIO_102"),
+       PINCTRL_PIN(103, "GPIO_103"),
+       PINCTRL_PIN(104, "GPIO_104"),
+       PINCTRL_PIN(105, "GPIO_105"),
+       PINCTRL_PIN(106, "GPIO_106"),
+       PINCTRL_PIN(107, "GPIO_107"),
+       PINCTRL_PIN(108, "GPIO_108"),
+       PINCTRL_PIN(109, "GPIO_109"),
+       PINCTRL_PIN(110, "GPIO_110"),
+       PINCTRL_PIN(111, "GPIO_111"),
+       PINCTRL_PIN(112, "GPIO_112"),
+       PINCTRL_PIN(113, "GPIO_113"),
+       PINCTRL_PIN(114, "GPIO_114"),
+       PINCTRL_PIN(115, "GPIO_115"),
+       PINCTRL_PIN(116, "GPIO_116"),
+       PINCTRL_PIN(117, "GPIO_117"),
+       PINCTRL_PIN(118, "GPIO_118"),
+       PINCTRL_PIN(119, "GPIO_119"),
+       PINCTRL_PIN(120, "GPIO_120"),
+       PINCTRL_PIN(121, "GPIO_121"),
+       PINCTRL_PIN(122, "GPIO_122"),
+       PINCTRL_PIN(123, "GPIO_123"),
+       PINCTRL_PIN(124, "GPIO_124"),
+       PINCTRL_PIN(125, "GPIO_125"),
+       PINCTRL_PIN(126, "GPIO_126"),
+       PINCTRL_PIN(127, "GPIO_127"),
+       PINCTRL_PIN(128, "GPIO_128"),
+       PINCTRL_PIN(129, "GPIO_129"),
+       PINCTRL_PIN(130, "GPIO_130"),
+       PINCTRL_PIN(131, "GPIO_131"),
+       PINCTRL_PIN(132, "GPIO_132"),
+       PINCTRL_PIN(133, "GPIO_133"),
+       PINCTRL_PIN(134, "GPIO_134"),
+       PINCTRL_PIN(135, "GPIO_135"),
+       PINCTRL_PIN(136, "GPIO_136"),
+       PINCTRL_PIN(137, "GPIO_137"),
+       PINCTRL_PIN(138, "GPIO_138"),
+       PINCTRL_PIN(139, "GPIO_139"),
+       PINCTRL_PIN(140, "GPIO_140"),
+       PINCTRL_PIN(141, "GPIO_141"),
+       PINCTRL_PIN(142, "GPIO_142"),
+       PINCTRL_PIN(143, "GPIO_143"),
+       PINCTRL_PIN(144, "GPIO_144"),
+       PINCTRL_PIN(145, "GPIO_145"),
+
+       PINCTRL_PIN(146, "SDC1_CLK"),
+       PINCTRL_PIN(147, "SDC1_CMD"),
+       PINCTRL_PIN(148, "SDC1_DATA"),
+       PINCTRL_PIN(149, "SDC2_CLK"),
+       PINCTRL_PIN(150, "SDC2_CMD"),
+       PINCTRL_PIN(151, "SDC2_DATA"),
+};
+
+#define DECLARE_MSM_GPIO_PINS(pin) static const unsigned int gpio##pin##_pins[] = { pin }
+DECLARE_MSM_GPIO_PINS(0);
+DECLARE_MSM_GPIO_PINS(1);
+DECLARE_MSM_GPIO_PINS(2);
+DECLARE_MSM_GPIO_PINS(3);
+DECLARE_MSM_GPIO_PINS(4);
+DECLARE_MSM_GPIO_PINS(5);
+DECLARE_MSM_GPIO_PINS(6);
+DECLARE_MSM_GPIO_PINS(7);
+DECLARE_MSM_GPIO_PINS(8);
+DECLARE_MSM_GPIO_PINS(9);
+DECLARE_MSM_GPIO_PINS(10);
+DECLARE_MSM_GPIO_PINS(11);
+DECLARE_MSM_GPIO_PINS(12);
+DECLARE_MSM_GPIO_PINS(13);
+DECLARE_MSM_GPIO_PINS(14);
+DECLARE_MSM_GPIO_PINS(15);
+DECLARE_MSM_GPIO_PINS(16);
+DECLARE_MSM_GPIO_PINS(17);
+DECLARE_MSM_GPIO_PINS(18);
+DECLARE_MSM_GPIO_PINS(19);
+DECLARE_MSM_GPIO_PINS(20);
+DECLARE_MSM_GPIO_PINS(21);
+DECLARE_MSM_GPIO_PINS(22);
+DECLARE_MSM_GPIO_PINS(23);
+DECLARE_MSM_GPIO_PINS(24);
+DECLARE_MSM_GPIO_PINS(25);
+DECLARE_MSM_GPIO_PINS(26);
+DECLARE_MSM_GPIO_PINS(27);
+DECLARE_MSM_GPIO_PINS(28);
+DECLARE_MSM_GPIO_PINS(29);
+DECLARE_MSM_GPIO_PINS(30);
+DECLARE_MSM_GPIO_PINS(31);
+DECLARE_MSM_GPIO_PINS(32);
+DECLARE_MSM_GPIO_PINS(33);
+DECLARE_MSM_GPIO_PINS(34);
+DECLARE_MSM_GPIO_PINS(35);
+DECLARE_MSM_GPIO_PINS(36);
+DECLARE_MSM_GPIO_PINS(37);
+DECLARE_MSM_GPIO_PINS(38);
+DECLARE_MSM_GPIO_PINS(39);
+DECLARE_MSM_GPIO_PINS(40);
+DECLARE_MSM_GPIO_PINS(41);
+DECLARE_MSM_GPIO_PINS(42);
+DECLARE_MSM_GPIO_PINS(43);
+DECLARE_MSM_GPIO_PINS(44);
+DECLARE_MSM_GPIO_PINS(45);
+DECLARE_MSM_GPIO_PINS(46);
+DECLARE_MSM_GPIO_PINS(47);
+DECLARE_MSM_GPIO_PINS(48);
+DECLARE_MSM_GPIO_PINS(49);
+DECLARE_MSM_GPIO_PINS(50);
+DECLARE_MSM_GPIO_PINS(51);
+DECLARE_MSM_GPIO_PINS(52);
+DECLARE_MSM_GPIO_PINS(53);
+DECLARE_MSM_GPIO_PINS(54);
+DECLARE_MSM_GPIO_PINS(55);
+DECLARE_MSM_GPIO_PINS(56);
+DECLARE_MSM_GPIO_PINS(57);
+DECLARE_MSM_GPIO_PINS(58);
+DECLARE_MSM_GPIO_PINS(59);
+DECLARE_MSM_GPIO_PINS(60);
+DECLARE_MSM_GPIO_PINS(61);
+DECLARE_MSM_GPIO_PINS(62);
+DECLARE_MSM_GPIO_PINS(63);
+DECLARE_MSM_GPIO_PINS(64);
+DECLARE_MSM_GPIO_PINS(65);
+DECLARE_MSM_GPIO_PINS(66);
+DECLARE_MSM_GPIO_PINS(67);
+DECLARE_MSM_GPIO_PINS(68);
+DECLARE_MSM_GPIO_PINS(69);
+DECLARE_MSM_GPIO_PINS(70);
+DECLARE_MSM_GPIO_PINS(71);
+DECLARE_MSM_GPIO_PINS(72);
+DECLARE_MSM_GPIO_PINS(73);
+DECLARE_MSM_GPIO_PINS(74);
+DECLARE_MSM_GPIO_PINS(75);
+DECLARE_MSM_GPIO_PINS(76);
+DECLARE_MSM_GPIO_PINS(77);
+DECLARE_MSM_GPIO_PINS(78);
+DECLARE_MSM_GPIO_PINS(79);
+DECLARE_MSM_GPIO_PINS(80);
+DECLARE_MSM_GPIO_PINS(81);
+DECLARE_MSM_GPIO_PINS(82);
+DECLARE_MSM_GPIO_PINS(83);
+DECLARE_MSM_GPIO_PINS(84);
+DECLARE_MSM_GPIO_PINS(85);
+DECLARE_MSM_GPIO_PINS(86);
+DECLARE_MSM_GPIO_PINS(87);
+DECLARE_MSM_GPIO_PINS(88);
+DECLARE_MSM_GPIO_PINS(89);
+DECLARE_MSM_GPIO_PINS(90);
+DECLARE_MSM_GPIO_PINS(91);
+DECLARE_MSM_GPIO_PINS(92);
+DECLARE_MSM_GPIO_PINS(93);
+DECLARE_MSM_GPIO_PINS(94);
+DECLARE_MSM_GPIO_PINS(95);
+DECLARE_MSM_GPIO_PINS(96);
+DECLARE_MSM_GPIO_PINS(97);
+DECLARE_MSM_GPIO_PINS(98);
+DECLARE_MSM_GPIO_PINS(99);
+DECLARE_MSM_GPIO_PINS(100);
+DECLARE_MSM_GPIO_PINS(101);
+DECLARE_MSM_GPIO_PINS(102);
+DECLARE_MSM_GPIO_PINS(103);
+DECLARE_MSM_GPIO_PINS(104);
+DECLARE_MSM_GPIO_PINS(105);
+DECLARE_MSM_GPIO_PINS(106);
+DECLARE_MSM_GPIO_PINS(107);
+DECLARE_MSM_GPIO_PINS(108);
+DECLARE_MSM_GPIO_PINS(109);
+DECLARE_MSM_GPIO_PINS(110);
+DECLARE_MSM_GPIO_PINS(111);
+DECLARE_MSM_GPIO_PINS(112);
+DECLARE_MSM_GPIO_PINS(113);
+DECLARE_MSM_GPIO_PINS(114);
+DECLARE_MSM_GPIO_PINS(115);
+DECLARE_MSM_GPIO_PINS(116);
+DECLARE_MSM_GPIO_PINS(117);
+DECLARE_MSM_GPIO_PINS(118);
+DECLARE_MSM_GPIO_PINS(119);
+DECLARE_MSM_GPIO_PINS(120);
+DECLARE_MSM_GPIO_PINS(121);
+DECLARE_MSM_GPIO_PINS(122);
+DECLARE_MSM_GPIO_PINS(123);
+DECLARE_MSM_GPIO_PINS(124);
+DECLARE_MSM_GPIO_PINS(125);
+DECLARE_MSM_GPIO_PINS(126);
+DECLARE_MSM_GPIO_PINS(127);
+DECLARE_MSM_GPIO_PINS(128);
+DECLARE_MSM_GPIO_PINS(129);
+DECLARE_MSM_GPIO_PINS(130);
+DECLARE_MSM_GPIO_PINS(131);
+DECLARE_MSM_GPIO_PINS(132);
+DECLARE_MSM_GPIO_PINS(133);
+DECLARE_MSM_GPIO_PINS(134);
+DECLARE_MSM_GPIO_PINS(135);
+DECLARE_MSM_GPIO_PINS(136);
+DECLARE_MSM_GPIO_PINS(137);
+DECLARE_MSM_GPIO_PINS(138);
+DECLARE_MSM_GPIO_PINS(139);
+DECLARE_MSM_GPIO_PINS(140);
+DECLARE_MSM_GPIO_PINS(141);
+DECLARE_MSM_GPIO_PINS(142);
+DECLARE_MSM_GPIO_PINS(143);
+DECLARE_MSM_GPIO_PINS(144);
+DECLARE_MSM_GPIO_PINS(145);
+
+static const unsigned int sdc1_clk_pins[] = { 146 };
+static const unsigned int sdc1_cmd_pins[] = { 147 };
+static const unsigned int sdc1_data_pins[] = { 148 };
+static const unsigned int sdc2_clk_pins[] = { 149 };
+static const unsigned int sdc2_cmd_pins[] = { 150 };
+static const unsigned int sdc2_data_pins[] = { 151 };
+
+#define FUNCTION(fname)                                        \
+       [MSM_MUX_##fname] = {                           \
+               .name = #fname,                         \
+               .groups = fname##_groups,               \
+               .ngroups = ARRAY_SIZE(fname##_groups),  \
+       }
+
+#define PINGROUP(id, f1, f2, f3, f4, f5, f6, f7)       \
+       {                                               \
+               .name = "gpio" #id,                     \
+               .pins = gpio##id##_pins,                \
+               .npins = ARRAY_SIZE(gpio##id##_pins),   \
+               .funcs = (int[]){                       \
+                       MSM_MUX_gpio,                   \
+                       MSM_MUX_##f1,                   \
+                       MSM_MUX_##f2,                   \
+                       MSM_MUX_##f3,                   \
+                       MSM_MUX_##f4,                   \
+                       MSM_MUX_##f5,                   \
+                       MSM_MUX_##f6,                   \
+                       MSM_MUX_##f7                    \
+               },                                      \
+               .nfuncs = 8,                            \
+               .ctl_reg = 0x1000 + 0x10 * id,          \
+               .io_reg = 0x1004 + 0x10 * id,           \
+               .intr_cfg_reg = 0x1008 + 0x10 * id,     \
+               .intr_status_reg = 0x100c + 0x10 * id,  \
+               .intr_target_reg = 0x1008 + 0x10 * id,  \
+               .mux_bit = 2,                           \
+               .pull_bit = 0,                          \
+               .drv_bit = 6,                           \
+               .oe_bit = 9,                            \
+               .in_bit = 0,                            \
+               .out_bit = 1,                           \
+               .intr_enable_bit = 0,                   \
+               .intr_status_bit = 0,                   \
+               .intr_target_bit = 5,                   \
+               .intr_raw_status_bit = 4,               \
+               .intr_polarity_bit = 1,                 \
+               .intr_detection_bit = 2,                \
+               .intr_detection_width = 2,              \
+       }
+
+#define SDC_PINGROUP(pg_name, ctl, pull, drv)          \
+       {                                               \
+               .name = #pg_name,                       \
+               .pins = pg_name##_pins,                 \
+               .npins = ARRAY_SIZE(pg_name##_pins),    \
+               .ctl_reg = ctl,                         \
+               .io_reg = 0,                            \
+               .intr_cfg_reg = 0,                      \
+               .intr_status_reg = 0,                   \
+               .intr_target_reg = 0,                   \
+               .mux_bit = -1,                          \
+               .pull_bit = pull,                       \
+               .drv_bit = drv,                         \
+               .oe_bit = -1,                           \
+               .in_bit = -1,                           \
+               .out_bit = -1,                          \
+               .intr_enable_bit = -1,                  \
+               .intr_status_bit = -1,                  \
+               .intr_target_bit = -1,                  \
+               .intr_raw_status_bit = -1,              \
+               .intr_polarity_bit = -1,                \
+               .intr_detection_bit = -1,               \
+               .intr_detection_width = -1,             \
+       }
+
+/*
+ * TODO: Add the rest of the possible functions and fill out
+ * the pingroup table below.
+ */
+enum msm8x74_functions {
+       MSM_MUX_gpio,
+       MSM_MUX_cci_i2c0,
+       MSM_MUX_cci_i2c1,
+       MSM_MUX_blsp_i2c1,
+       MSM_MUX_blsp_i2c2,
+       MSM_MUX_blsp_i2c3,
+       MSM_MUX_blsp_i2c4,
+       MSM_MUX_blsp_i2c5,
+       MSM_MUX_blsp_i2c6,
+       MSM_MUX_blsp_i2c7,
+       MSM_MUX_blsp_i2c8,
+       MSM_MUX_blsp_i2c9,
+       MSM_MUX_blsp_i2c10,
+       MSM_MUX_blsp_i2c11,
+       MSM_MUX_blsp_i2c12,
+       MSM_MUX_blsp_spi1,
+       MSM_MUX_blsp_spi1_cs1,
+       MSM_MUX_blsp_spi1_cs2,
+       MSM_MUX_blsp_spi1_cs3,
+       MSM_MUX_blsp_spi2,
+       MSM_MUX_blsp_spi2_cs1,
+       MSM_MUX_blsp_spi2_cs2,
+       MSM_MUX_blsp_spi2_cs3,
+       MSM_MUX_blsp_spi3,
+       MSM_MUX_blsp_spi4,
+       MSM_MUX_blsp_spi5,
+       MSM_MUX_blsp_spi6,
+       MSM_MUX_blsp_spi7,
+       MSM_MUX_blsp_spi8,
+       MSM_MUX_blsp_spi9,
+       MSM_MUX_blsp_spi10,
+       MSM_MUX_blsp_spi10_cs1,
+       MSM_MUX_blsp_spi10_cs2,
+       MSM_MUX_blsp_spi10_cs3,
+       MSM_MUX_blsp_spi11,
+       MSM_MUX_blsp_spi12,
+       MSM_MUX_blsp_uart1,
+       MSM_MUX_blsp_uart2,
+       MSM_MUX_blsp_uart3,
+       MSM_MUX_blsp_uart4,
+       MSM_MUX_blsp_uart5,
+       MSM_MUX_blsp_uart6,
+       MSM_MUX_blsp_uart7,
+       MSM_MUX_blsp_uart8,
+       MSM_MUX_blsp_uart9,
+       MSM_MUX_blsp_uart10,
+       MSM_MUX_blsp_uart11,
+       MSM_MUX_blsp_uart12,
+       MSM_MUX_blsp_uim1,
+       MSM_MUX_blsp_uim2,
+       MSM_MUX_blsp_uim3,
+       MSM_MUX_blsp_uim4,
+       MSM_MUX_blsp_uim5,
+       MSM_MUX_blsp_uim6,
+       MSM_MUX_blsp_uim7,
+       MSM_MUX_blsp_uim8,
+       MSM_MUX_blsp_uim9,
+       MSM_MUX_blsp_uim10,
+       MSM_MUX_blsp_uim11,
+       MSM_MUX_blsp_uim12,
+       MSM_MUX_uim1,
+       MSM_MUX_uim2,
+       MSM_MUX_uim_batt_alarm,
+       MSM_MUX_sdc3,
+       MSM_MUX_sdc4,
+       MSM_MUX_gcc_gp_clk1,
+       MSM_MUX_gcc_gp_clk2,
+       MSM_MUX_gcc_gp_clk3,
+       MSM_MUX_qua_mi2s,
+       MSM_MUX_pri_mi2s,
+       MSM_MUX_spkr_mi2s,
+       MSM_MUX_ter_mi2s,
+       MSM_MUX_sec_mi2s,
+       MSM_MUX_hdmi_cec,
+       MSM_MUX_hdmi_ddc,
+       MSM_MUX_hdmi_hpd,
+       MSM_MUX_edp_hpd,
+       MSM_MUX_mdp_vsync,
+       MSM_MUX_cam_mclk0,
+       MSM_MUX_cam_mclk1,
+       MSM_MUX_cam_mclk2,
+       MSM_MUX_cam_mclk3,
+       MSM_MUX_cci_timer0,
+       MSM_MUX_cci_timer1,
+       MSM_MUX_cci_timer2,
+       MSM_MUX_cci_timer3,
+       MSM_MUX_cci_timer4,
+       MSM_MUX_cci_async_in0,
+       MSM_MUX_cci_async_in1,
+       MSM_MUX_cci_async_in2,
+       MSM_MUX_gp_pdm0,
+       MSM_MUX_gp_pdm1,
+       MSM_MUX_gp_pdm2,
+       MSM_MUX_gp0_clk,
+       MSM_MUX_gp1_clk,
+       MSM_MUX_gp_mn,
+       MSM_MUX_tsif1,
+       MSM_MUX_tsif2,
+       MSM_MUX_hsic,
+       MSM_MUX_grfc,
+       MSM_MUX_audio_ref_clk,
+       MSM_MUX_bt,
+       MSM_MUX_fm,
+       MSM_MUX_wlan,
+       MSM_MUX_slimbus,
+       MSM_MUX_NA,
+};
+
+static const char * const gpio_groups[] = {
+       "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5", "gpio6", "gpio7",
+       "gpio8", "gpio9", "gpio10", "gpio11", "gpio12", "gpio13", "gpio14",
+       "gpio15", "gpio16", "gpio17", "gpio18", "gpio19", "gpio20", "gpio21",
+       "gpio22", "gpio23", "gpio24", "gpio25", "gpio26", "gpio27", "gpio28",
+       "gpio29", "gpio30", "gpio31", "gpio32", "gpio33", "gpio34", "gpio35",
+       "gpio36", "gpio37", "gpio38", "gpio39", "gpio40", "gpio41", "gpio42",
+       "gpio43", "gpio44", "gpio45", "gpio46", "gpio47", "gpio48", "gpio49",
+       "gpio50", "gpio51", "gpio52", "gpio53", "gpio54", "gpio55", "gpio56",
+       "gpio57", "gpio58", "gpio59", "gpio60", "gpio61", "gpio62", "gpio63",
+       "gpio64", "gpio65", "gpio66", "gpio67", "gpio68", "gpio69", "gpio70",
+       "gpio71", "gpio72", "gpio73", "gpio74", "gpio75", "gpio76", "gpio77",
+       "gpio78", "gpio79", "gpio80", "gpio81", "gpio82", "gpio83", "gpio84",
+       "gpio85", "gpio86", "gpio87", "gpio88", "gpio89", "gpio90", "gpio91",
+       "gpio92", "gpio93", "gpio94", "gpio95", "gpio96", "gpio97", "gpio98",
+       "gpio99", "gpio100", "gpio101", "gpio102", "gpio103", "gpio104",
+       "gpio105", "gpio106", "gpio107", "gpio108", "gpio109", "gpio110",
+       "gpio111", "gpio112", "gpio113", "gpio114", "gpio115", "gpio116",
+       "gpio117", "gpio118", "gpio119", "gpio120", "gpio121", "gpio122",
+       "gpio123", "gpio124", "gpio125", "gpio126", "gpio127", "gpio128",
+       "gpio129", "gpio130", "gpio131", "gpio132", "gpio133", "gpio134",
+       "gpio135", "gpio136", "gpio137", "gpio138", "gpio139", "gpio140",
+       "gpio141", "gpio142", "gpio143", "gpio144", "gpio145"
+};
+
+static const char * const blsp_uart1_groups[] = {
+       "gpio0", "gpio1", "gpio2", "gpio3"
+};
+static const char * const blsp_uim1_groups[] = { "gpio0", "gpio1" };
+static const char * const blsp_i2c1_groups[] = { "gpio2", "gpio3" };
+static const char * const blsp_spi1_groups[] = {
+       "gpio0", "gpio1", "gpio2", "gpio3"
+};
+static const char * const blsp_spi1_cs1_groups[] = { "gpio8" };
+static const char * const blsp_spi1_cs2_groups[] = { "gpio9", "gpio11" };
+static const char * const blsp_spi1_cs3_groups[] = { "gpio10" };
+
+static const char * const blsp_uart2_groups[] = {
+       "gpio4", "gpio5", "gpio6", "gpio7"
+};
+static const char * const blsp_uim2_groups[] = { "gpio4", "gpio5" };
+static const char * const blsp_i2c2_groups[] = { "gpio6", "gpio7" };
+static const char * const blsp_spi2_groups[] = {
+       "gpio4", "gpio5", "gpio6", "gpio7"
+};
+static const char * const blsp_spi2_cs1_groups[] = { "gpio53", "gpio62" };
+static const char * const blsp_spi2_cs2_groups[] = { "gpio54", "gpio63" };
+static const char * const blsp_spi2_cs3_groups[] = { "gpio66" };
+
+static const char * const blsp_uart3_groups[] = {
+       "gpio8", "gpio9", "gpio10", "gpio11"
+};
+static const char * const blsp_uim3_groups[] = { "gpio8", "gpio9" };
+static const char * const blsp_i2c3_groups[] = { "gpio10", "gpio11" };
+static const char * const blsp_spi3_groups[] = {
+       "gpio8", "gpio9", "gpio10", "gpio11"
+};
+
+static const char * const cci_i2c0_groups[] = { "gpio19", "gpio20" };
+static const char * const cci_i2c1_groups[] = { "gpio21", "gpio22" };
+
+static const char * const blsp_uart4_groups[] = {
+       "gpio19", "gpio20", "gpio21", "gpio22"
+};
+static const char * const blsp_uim4_groups[] = { "gpio19", "gpio20" };
+static const char * const blsp_i2c4_groups[] = { "gpio21", "gpio22" };
+static const char * const blsp_spi4_groups[] = {
+       "gpio19", "gpio20", "gpio21", "gpio22"
+};
+
+static const char * const blsp_uart5_groups[] = {
+       "gpio23", "gpio24", "gpio25", "gpio26"
+};
+static const char * const blsp_uim5_groups[] = { "gpio23", "gpio24" };
+static const char * const blsp_i2c5_groups[] = { "gpio25", "gpio26" };
+static const char * const blsp_spi5_groups[] = {
+       "gpio23", "gpio24", "gpio25", "gpio26"
+};
+
+static const char * const blsp_uart6_groups[] = {
+       "gpio27", "gpio28", "gpio29", "gpio30"
+};
+static const char * const blsp_uim6_groups[] = { "gpio27", "gpio28" };
+static const char * const blsp_i2c6_groups[] = { "gpio29", "gpio30" };
+static const char * const blsp_spi6_groups[] = {
+       "gpio27", "gpio28", "gpio29", "gpio30"
+};
+
+static const char * const blsp_uart7_groups[] = {
+       "gpio41", "gpio42", "gpio43", "gpio44"
+};
+static const char * const blsp_uim7_groups[] = { "gpio41", "gpio42" };
+static const char * const blsp_i2c7_groups[] = { "gpio43", "gpio44" };
+static const char * const blsp_spi7_groups[] = {
+       "gpio41", "gpio42", "gpio43", "gpio44"
+};
+
+static const char * const blsp_uart8_groups[] = {
+       "gpio45", "gpio46", "gpio47", "gpio48"
+};
+static const char * const blsp_uim8_groups[] = { "gpio45", "gpio46" };
+static const char * const blsp_i2c8_groups[] = { "gpio47", "gpio48" };
+static const char * const blsp_spi8_groups[] = {
+       "gpio45", "gpio46", "gpio47", "gpio48"
+};
+
+static const char * const blsp_uart9_groups[] = {
+       "gpio49", "gpio50", "gpio51", "gpio52"
+};
+static const char * const blsp_uim9_groups[] = { "gpio49", "gpio50" };
+static const char * const blsp_i2c9_groups[] = { "gpio51", "gpio52" };
+static const char * const blsp_spi9_groups[] = {
+       "gpio49", "gpio50", "gpio51", "gpio52"
+};
+
+static const char * const blsp_uart10_groups[] = {
+       "gpio53", "gpio54", "gpio55", "gpio56"
+};
+static const char * const blsp_uim10_groups[] = { "gpio53", "gpio54" };
+static const char * const blsp_i2c10_groups[] = { "gpio55", "gpio56" };
+static const char * const blsp_spi10_groups[] = {
+       "gpio53", "gpio54", "gpio55", "gpio56"
+};
+static const char * const blsp_spi10_cs1_groups[] = { "gpio47", "gpio67" };
+static const char * const blsp_spi10_cs2_groups[] = { "gpio48", "gpio68" };
+static const char * const blsp_spi10_cs3_groups[] = { "gpio90" };
+
+static const char * const blsp_uart11_groups[] = {
+       "gpio81", "gpio82", "gpio83", "gpio84"
+};
+static const char * const blsp_uim11_groups[] = { "gpio81", "gpio82" };
+static const char * const blsp_i2c11_groups[] = { "gpio83", "gpio84" };
+static const char * const blsp_spi11_groups[] = {
+       "gpio81", "gpio82", "gpio83", "gpio84"
+};
+
+static const char * const blsp_uart12_groups[] = {
+       "gpio85", "gpio86", "gpio87", "gpio88"
+};
+static const char * const blsp_uim12_groups[] = { "gpio85", "gpio86" };
+static const char * const blsp_i2c12_groups[] = { "gpio87", "gpio88" };
+static const char * const blsp_spi12_groups[] = {
+       "gpio85", "gpio86", "gpio87", "gpio88"
+};
+
+static const char * const uim1_groups[] = {
+       "gpio97", "gpio98", "gpio99", "gpio100"
+};
+
+static const char * const uim2_groups[] = {
+       "gpio49", "gpio50", "gpio51", "gpio52"
+};
+
+static const char * const uim_batt_alarm_groups[] = { "gpio101" };
+
+static const char * const sdc3_groups[] = {
+       "gpio35", "gpio36", "gpio37", "gpio38", "gpio39", "gpio40"
+};
+
+static const char * const sdc4_groups[] = {
+       "gpio91", "gpio92", "gpio93", "gpio94", "gpio95", "gpio96"
+};
+
+static const char * const gp0_clk_groups[] = { "gpio26" };
+static const char * const gp1_clk_groups[] = { "gpio27", "gpio57", "gpio78" };
+static const char * const gp_mn_groups[] = { "gpio29" };
+static const char * const gcc_gp_clk1_groups[] = { "gpio57", "gpio78" };
+static const char * const gcc_gp_clk2_groups[] = { "gpio58", "gpio81" };
+static const char * const gcc_gp_clk3_groups[] = { "gpio59", "gpio82" };
+
+static const char * const qua_mi2s_groups[] = {
+       "gpio57", "gpio58", "gpio59", "gpio60", "gpio61", "gpio62", "gpio63",
+};
+
+static const char * const pri_mi2s_groups[] = {
+       "gpio64", "gpio65", "gpio66", "gpio67", "gpio68"
+};
+
+static const char * const spkr_mi2s_groups[] = {
+       "gpio69", "gpio70", "gpio71", "gpio72"
+};
+
+static const char * const ter_mi2s_groups[] = {
+       "gpio73", "gpio74", "gpio75", "gpio76", "gpio77"
+};
+
+static const char * const sec_mi2s_groups[] = {
+       "gpio78", "gpio79", "gpio80", "gpio81", "gpio82"
+};
+
+static const char * const hdmi_cec_groups[] = { "gpio31" };
+static const char * const hdmi_ddc_groups[] = { "gpio32", "gpio33" };
+static const char * const hdmi_hpd_groups[] = { "gpio34" };
+static const char * const edp_hpd_groups[] = { "gpio102" };
+
+static const char * const mdp_vsync_groups[] = { "gpio12", "gpio13", "gpio14" };
+static const char * const cam_mclk0_groups[] = { "gpio15" };
+static const char * const cam_mclk1_groups[] = { "gpio16" };
+static const char * const cam_mclk2_groups[] = { "gpio17" };
+static const char * const cam_mclk3_groups[] = { "gpio18" };
+
+static const char * const cci_timer0_groups[] = { "gpio23" };
+static const char * const cci_timer1_groups[] = { "gpio24" };
+static const char * const cci_timer2_groups[] = { "gpio25" };
+static const char * const cci_timer3_groups[] = { "gpio26" };
+static const char * const cci_timer4_groups[] = { "gpio27" };
+static const char * const cci_async_in0_groups[] = { "gpio28" };
+static const char * const cci_async_in1_groups[] = { "gpio26" };
+static const char * const cci_async_in2_groups[] = { "gpio27" };
+
+static const char * const gp_pdm0_groups[] = { "gpio54", "gpio68" };
+static const char * const gp_pdm1_groups[] = { "gpio74", "gpio86" };
+static const char * const gp_pdm2_groups[] = { "gpio63", "gpio79" };
+
+static const char * const tsif1_groups[] = {
+       "gpio89", "gpio90", "gpio91", "gpio92"
+};
+
+static const char * const tsif2_groups[] = {
+       "gpio93", "gpio94", "gpio95", "gpio96"
+};
+
+static const char * const hsic_groups[] = { "gpio144", "gpio145" };
+static const char * const grfc_groups[] = {
+       "gpio104", "gpio105", "gpio106", "gpio107", "gpio108", "gpio109",
+       "gpio110", "gpio111", "gpio112", "gpio113", "gpio114", "gpio115",
+       "gpio116", "gpio117", "gpio118", "gpio119", "gpio120", "gpio121",
+       "gpio122", "gpio123", "gpio124", "gpio125", "gpio126", "gpio127",
+       "gpio128", "gpio136", "gpio137", "gpio141", "gpio143"
+};
+
+static const char * const audio_ref_clk_groups[] = { "gpio69" };
+
+static const char * const bt_groups[] = { "gpio35", "gpio43", "gpio44" };
+
+static const char * const fm_groups[] = { "gpio41", "gpio42" };
+
+static const char * const wlan_groups[] = {
+       "gpio36", "gpio37", "gpio38", "gpio39", "gpio40"
+};
+
+static const char * const slimbus_groups[] = { "gpio70", "gpio71" };
+
+static const struct msm_function msm8x74_functions[] = {
+       FUNCTION(gpio),
+       FUNCTION(cci_i2c0),
+       FUNCTION(cci_i2c1),
+       FUNCTION(uim1),
+       FUNCTION(uim2),
+       FUNCTION(uim_batt_alarm),
+       FUNCTION(blsp_uim1),
+       FUNCTION(blsp_uim2),
+       FUNCTION(blsp_uim3),
+       FUNCTION(blsp_uim4),
+       FUNCTION(blsp_uim5),
+       FUNCTION(blsp_uim6),
+       FUNCTION(blsp_uim7),
+       FUNCTION(blsp_uim8),
+       FUNCTION(blsp_uim9),
+       FUNCTION(blsp_uim10),
+       FUNCTION(blsp_uim11),
+       FUNCTION(blsp_uim12),
+       FUNCTION(blsp_i2c1),
+       FUNCTION(blsp_i2c2),
+       FUNCTION(blsp_i2c3),
+       FUNCTION(blsp_i2c4),
+       FUNCTION(blsp_i2c5),
+       FUNCTION(blsp_i2c6),
+       FUNCTION(blsp_i2c7),
+       FUNCTION(blsp_i2c8),
+       FUNCTION(blsp_i2c9),
+       FUNCTION(blsp_i2c10),
+       FUNCTION(blsp_i2c11),
+       FUNCTION(blsp_i2c12),
+       FUNCTION(blsp_spi1),
+       FUNCTION(blsp_spi1_cs1),
+       FUNCTION(blsp_spi1_cs2),
+       FUNCTION(blsp_spi1_cs3),
+       FUNCTION(blsp_spi2),
+       FUNCTION(blsp_spi2_cs1),
+       FUNCTION(blsp_spi2_cs2),
+       FUNCTION(blsp_spi2_cs3),
+       FUNCTION(blsp_spi3),
+       FUNCTION(blsp_spi4),
+       FUNCTION(blsp_spi5),
+       FUNCTION(blsp_spi6),
+       FUNCTION(blsp_spi7),
+       FUNCTION(blsp_spi8),
+       FUNCTION(blsp_spi9),
+       FUNCTION(blsp_spi10),
+       FUNCTION(blsp_spi10_cs1),
+       FUNCTION(blsp_spi10_cs2),
+       FUNCTION(blsp_spi10_cs3),
+       FUNCTION(blsp_spi11),
+       FUNCTION(blsp_spi12),
+       FUNCTION(blsp_uart1),
+       FUNCTION(blsp_uart2),
+       FUNCTION(blsp_uart3),
+       FUNCTION(blsp_uart4),
+       FUNCTION(blsp_uart5),
+       FUNCTION(blsp_uart6),
+       FUNCTION(blsp_uart7),
+       FUNCTION(blsp_uart8),
+       FUNCTION(blsp_uart9),
+       FUNCTION(blsp_uart10),
+       FUNCTION(blsp_uart11),
+       FUNCTION(blsp_uart12),
+       FUNCTION(sdc3),
+       FUNCTION(sdc4),
+       FUNCTION(gcc_gp_clk1),
+       FUNCTION(gcc_gp_clk2),
+       FUNCTION(gcc_gp_clk3),
+       FUNCTION(qua_mi2s),
+       FUNCTION(pri_mi2s),
+       FUNCTION(spkr_mi2s),
+       FUNCTION(ter_mi2s),
+       FUNCTION(sec_mi2s),
+       FUNCTION(mdp_vsync),
+       FUNCTION(cam_mclk0),
+       FUNCTION(cam_mclk1),
+       FUNCTION(cam_mclk2),
+       FUNCTION(cam_mclk3),
+       FUNCTION(cci_timer0),
+       FUNCTION(cci_timer1),
+       FUNCTION(cci_timer2),
+       FUNCTION(cci_timer3),
+       FUNCTION(cci_timer4),
+       FUNCTION(cci_async_in0),
+       FUNCTION(cci_async_in1),
+       FUNCTION(cci_async_in2),
+       FUNCTION(hdmi_cec),
+       FUNCTION(hdmi_ddc),
+       FUNCTION(hdmi_hpd),
+       FUNCTION(edp_hpd),
+       FUNCTION(gp_pdm0),
+       FUNCTION(gp_pdm1),
+       FUNCTION(gp_pdm2),
+       FUNCTION(gp0_clk),
+       FUNCTION(gp1_clk),
+       FUNCTION(gp_mn),
+       FUNCTION(tsif1),
+       FUNCTION(tsif2),
+       FUNCTION(hsic),
+       FUNCTION(grfc),
+       FUNCTION(audio_ref_clk),
+       FUNCTION(bt),
+       FUNCTION(fm),
+       FUNCTION(wlan),
+       FUNCTION(slimbus),
+};
+
+static const struct msm_pingroup msm8x74_groups[] = {
+       PINGROUP(0,   blsp_spi1, blsp_uart1, blsp_uim1, NA, NA, NA, NA),
+       PINGROUP(1,   blsp_spi1, blsp_uart1, blsp_uim1, NA, NA, NA, NA),
+       PINGROUP(2,   blsp_spi1, blsp_uart1, blsp_i2c1, NA, NA, NA, NA),
+       PINGROUP(3,   blsp_spi1, blsp_uart1, blsp_i2c1, NA, NA, NA, NA),
+       PINGROUP(4,   blsp_spi2, blsp_uart2, blsp_uim2, NA, NA, NA, NA),
+       PINGROUP(5,   blsp_spi2, blsp_uart2, blsp_uim2, NA, NA, NA, NA),
+       PINGROUP(6,   blsp_spi2, blsp_uart2, blsp_i2c2, NA, NA, NA, NA),
+       PINGROUP(7,   blsp_spi2, blsp_uart2, blsp_i2c2, NA, NA, NA, NA),
+       PINGROUP(8,   blsp_spi3, blsp_uart3, blsp_uim3, blsp_spi1_cs1, NA, NA, NA),
+       PINGROUP(9,   blsp_spi3, blsp_uart3, blsp_uim3, blsp_spi1_cs2, NA, NA, NA),
+       PINGROUP(10,  blsp_spi3, blsp_uart3, blsp_i2c3, blsp_spi1_cs3, NA, NA, NA),
+       PINGROUP(11,  blsp_spi3, blsp_uart3, blsp_i2c3, blsp_spi1_cs2, NA, NA, NA),
+       PINGROUP(12,  mdp_vsync, NA, NA, NA, NA, NA, NA),
+       PINGROUP(13,  mdp_vsync, NA, NA, NA, NA, NA, NA),
+       PINGROUP(14,  mdp_vsync, NA, NA, NA, NA, NA, NA),
+       PINGROUP(15,  cam_mclk0, NA, NA, NA, NA, NA, NA),
+       PINGROUP(16,  cam_mclk1, NA, NA, NA, NA, NA, NA),
+       PINGROUP(17,  cam_mclk2, NA, NA, NA, NA, NA, NA),
+       PINGROUP(18,  cam_mclk3, NA, NA, NA, NA, NA, NA),
+       PINGROUP(19,  cci_i2c0, blsp_spi4, blsp_uart4, blsp_uim4, NA, NA, NA),
+       PINGROUP(20,  cci_i2c0, blsp_spi4, blsp_uart4, blsp_uim4, NA, NA, NA),
+       PINGROUP(21,  cci_i2c1, blsp_spi4, blsp_uart4, blsp_i2c4, NA, NA, NA),
+       PINGROUP(22,  cci_i2c1, blsp_spi4, blsp_uart4, blsp_i2c4, NA, NA, NA),
+       PINGROUP(23,  cci_timer0, blsp_spi5, blsp_uart5, blsp_uim5, NA, NA, NA),
+       PINGROUP(24,  cci_timer1, blsp_spi5, blsp_uart5, blsp_uim5, NA, NA, NA),
+       PINGROUP(25,  cci_timer2, blsp_spi5, blsp_uart5, blsp_i2c5, NA, NA, NA),
+       PINGROUP(26,  cci_timer3, cci_async_in1, blsp_spi5, blsp_uart5, blsp_i2c5, gp0_clk, NA),
+       PINGROUP(27,  cci_timer4, cci_async_in2, blsp_spi6, blsp_uart6, blsp_i2c6, gp1_clk, NA),
+       PINGROUP(28,  cci_async_in0, blsp_spi6, blsp_uart6, blsp_uim6, NA, NA, NA),
+       PINGROUP(29,  blsp_spi6, blsp_uart6, blsp_i2c6, gp_mn, NA, NA, NA),
+       PINGROUP(30,  blsp_spi6, blsp_uart6, blsp_i2c6, NA, NA, NA, NA),
+       PINGROUP(31,  hdmi_cec, NA, NA, NA, NA, NA, NA),
+       PINGROUP(32,  hdmi_ddc, NA, NA, NA, NA, NA, NA),
+       PINGROUP(33,  hdmi_ddc, NA, NA, NA, NA, NA, NA),
+       PINGROUP(34,  hdmi_hpd, NA, NA, NA, NA, NA, NA),
+       PINGROUP(35,  bt, sdc3, NA, NA, NA, NA, NA),
+       PINGROUP(36,  wlan, sdc3, NA, NA, NA, NA, NA),
+       PINGROUP(37,  wlan, sdc3, NA, NA, NA, NA, NA),
+       PINGROUP(38,  wlan, sdc3, NA, NA, NA, NA, NA),
+       PINGROUP(39,  wlan, sdc3, NA, NA, NA, NA, NA),
+       PINGROUP(40,  wlan, sdc3, NA, NA, NA, NA, NA),
+       PINGROUP(41,  fm, blsp_spi7, blsp_uart7, blsp_uim7, NA, NA, NA),
+       PINGROUP(42,  fm, blsp_spi7, blsp_uart7, blsp_uim7, NA, NA, NA),
+       PINGROUP(43,  bt, blsp_spi7, blsp_uart7, blsp_i2c7, NA, NA, NA),
+       PINGROUP(44,  bt, blsp_spi7, blsp_uart7, blsp_i2c7, NA, NA, NA),
+       PINGROUP(45,  blsp_spi8, blsp_uart8, blsp_uim8, NA, NA, NA, NA),
+       PINGROUP(46,  blsp_spi8, blsp_uart8, blsp_uim8, NA, NA, NA, NA),
+       PINGROUP(47,  blsp_spi8, blsp_uart8, blsp_i2c8, blsp_spi10_cs1, NA, NA, NA),
+       PINGROUP(48,  blsp_spi8, blsp_uart8, blsp_i2c8, blsp_spi10_cs2, NA, NA, NA),
+       PINGROUP(49,  uim2, blsp_spi9, blsp_uart9, blsp_uim9, NA, NA, NA),
+       PINGROUP(50,  uim2, blsp_spi9, blsp_uart9, blsp_uim9, NA, NA, NA),
+       PINGROUP(51,  uim2, blsp_spi9, blsp_uart9, blsp_i2c9, NA, NA, NA),
+       PINGROUP(52,  uim2, blsp_spi9, blsp_uart9, blsp_i2c9, NA, NA, NA),
+       PINGROUP(53,  blsp_spi10, blsp_uart10, blsp_uim10, blsp_spi2_cs1, NA, NA, NA),
+       PINGROUP(54,  blsp_spi10, blsp_uart10, blsp_uim10, blsp_spi2_cs2, gp_pdm0, NA, NA),
+       PINGROUP(55,  blsp_spi10, blsp_uart10, blsp_i2c10, NA, NA, NA, NA),
+       PINGROUP(56,  blsp_spi10, blsp_uart10, blsp_i2c10, NA, NA, NA, NA),
+       PINGROUP(57,  qua_mi2s, gcc_gp_clk1, NA, NA, NA, NA, NA),
+       PINGROUP(58,  qua_mi2s, gcc_gp_clk2, NA, NA, NA, NA, NA),
+       PINGROUP(59,  qua_mi2s, gcc_gp_clk3, NA, NA, NA, NA, NA),
+       PINGROUP(60,  qua_mi2s, NA, NA, NA, NA, NA, NA),
+       PINGROUP(61,  qua_mi2s, NA, NA, NA, NA, NA, NA),
+       PINGROUP(62,  qua_mi2s, blsp_spi2_cs1, NA, NA, NA, NA, NA),
+       PINGROUP(63,  qua_mi2s, blsp_spi2_cs2, gp_pdm2, NA, NA, NA, NA),
+       PINGROUP(64,  pri_mi2s, NA, NA, NA, NA, NA, NA),
+       PINGROUP(65,  pri_mi2s, NA, NA, NA, NA, NA, NA),
+       PINGROUP(66,  pri_mi2s, blsp_spi2_cs3, NA, NA, NA, NA, NA),
+       PINGROUP(67,  pri_mi2s, blsp_spi10_cs1, NA, NA, NA, NA, NA),
+       PINGROUP(68,  pri_mi2s, blsp_spi10_cs2, gp_pdm0, NA, NA, NA, NA),
+       PINGROUP(69,  spkr_mi2s, audio_ref_clk, NA, NA, NA, NA, NA),
+       PINGROUP(70,  slimbus, spkr_mi2s, NA, NA, NA, NA, NA),
+       PINGROUP(71,  slimbus, spkr_mi2s, NA, NA, NA, NA, NA),
+       PINGROUP(72,  spkr_mi2s, NA, NA, NA, NA, NA, NA),
+       PINGROUP(73,  ter_mi2s, NA, NA, NA, NA, NA, NA),
+       PINGROUP(74,  ter_mi2s, gp_pdm1, NA, NA, NA, NA, NA),
+       PINGROUP(75,  ter_mi2s, NA, NA, NA, NA, NA, NA),
+       PINGROUP(76,  ter_mi2s, NA, NA, NA, NA, NA, NA),
+       PINGROUP(77,  ter_mi2s, NA, NA, NA, NA, NA, NA),
+       PINGROUP(78,  sec_mi2s, gcc_gp_clk1, NA, NA, NA, NA, NA),
+       PINGROUP(79,  sec_mi2s, gp_pdm2, NA, NA, NA, NA, NA),
+       PINGROUP(80,  sec_mi2s, NA, NA, NA, NA, NA, NA),
+       PINGROUP(81,  sec_mi2s, blsp_spi11, blsp_uart11, blsp_uim11, gcc_gp_clk2, NA, NA),
+       PINGROUP(82,  sec_mi2s, blsp_spi11, blsp_uart11, blsp_uim11, gcc_gp_clk3, NA, NA),
+       PINGROUP(83,  blsp_spi11, blsp_uart11, blsp_i2c11, NA, NA, NA, NA),
+       PINGROUP(84,  blsp_spi11, blsp_uart11, blsp_i2c11, NA, NA, NA, NA),
+       PINGROUP(85,  blsp_spi12, blsp_uart12, blsp_uim12, NA, NA, NA, NA),
+       PINGROUP(86,  blsp_spi12, blsp_uart12, blsp_uim12, gp_pdm1, NA, NA, NA),
+       PINGROUP(87,  blsp_spi12, blsp_uart12, blsp_i2c12, NA, NA, NA, NA),
+       PINGROUP(88,  blsp_spi12, blsp_uart12, blsp_i2c12, NA, NA, NA, NA),
+       PINGROUP(89,  tsif1, NA, NA, NA, NA, NA, NA),
+       PINGROUP(90,  tsif1, blsp_spi10_cs3, NA, NA, NA, NA, NA),
+       PINGROUP(91,  tsif1, sdc4, NA, NA, NA, NA, NA),
+       PINGROUP(92,  tsif1, sdc4, NA, NA, NA, NA, NA),
+       PINGROUP(93,  tsif2, sdc4, NA, NA, NA, NA, NA),
+       PINGROUP(94,  tsif2, sdc4, NA, NA, NA, NA, NA),
+       PINGROUP(95,  tsif2, sdc4, NA, NA, NA, NA, NA),
+       PINGROUP(96,  tsif2, sdc4, NA, NA, NA, NA, NA),
+       PINGROUP(97,  uim1, NA, NA, NA, NA, NA, NA),
+       PINGROUP(98,  uim1, NA, NA, NA, NA, NA, NA),
+       PINGROUP(99,  uim1, NA, NA, NA, NA, NA, NA),
+       PINGROUP(100, uim1, NA, NA, NA, NA, NA, NA),
+       PINGROUP(101, uim_batt_alarm, NA, NA, NA, NA, NA, NA),
+       PINGROUP(102, edp_hpd, NA, NA, NA, NA, NA, NA),
+       PINGROUP(103, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(104, grfc, NA, NA, NA, NA, NA, NA),
+       PINGROUP(105, grfc, NA, NA, NA, NA, NA, NA),
+       PINGROUP(106, grfc, NA, NA, NA, NA, NA, NA),
+       PINGROUP(107, grfc, NA, NA, NA, NA, NA, NA),
+       PINGROUP(108, grfc, NA, NA, NA, NA, NA, NA),
+       PINGROUP(109, grfc, NA, NA, NA, NA, NA, NA),
+       PINGROUP(110, grfc, NA, NA, NA, NA, NA, NA),
+       PINGROUP(111, grfc, NA, NA, NA, NA, NA, NA),
+       PINGROUP(112, grfc, NA, NA, NA, NA, NA, NA),
+       PINGROUP(113, grfc, NA, NA, NA, NA, NA, NA),
+       PINGROUP(114, grfc, NA, NA, NA, NA, NA, NA),
+       PINGROUP(115, grfc, NA, NA, NA, NA, NA, NA),
+       PINGROUP(116, grfc, NA, NA, NA, NA, NA, NA),
+       PINGROUP(117, grfc, NA, NA, NA, NA, NA, NA),
+       PINGROUP(118, grfc, NA, NA, NA, NA, NA, NA),
+       PINGROUP(119, grfc, NA, NA, NA, NA, NA, NA),
+       PINGROUP(120, grfc, NA, NA, NA, NA, NA, NA),
+       PINGROUP(121, grfc, NA, NA, NA, NA, NA, NA),
+       PINGROUP(122, grfc, NA, NA, NA, NA, NA, NA),
+       PINGROUP(123, grfc, NA, NA, NA, NA, NA, NA),
+       PINGROUP(124, grfc, NA, NA, NA, NA, NA, NA),
+       PINGROUP(125, grfc, NA, NA, NA, NA, NA, NA),
+       PINGROUP(126, grfc, NA, NA, NA, NA, NA, NA),
+       PINGROUP(127, grfc, NA, NA, NA, NA, NA, NA),
+       PINGROUP(128, NA, grfc, NA, NA, NA, NA, NA),
+       PINGROUP(129, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(130, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(131, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(132, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(133, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(134, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(135, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(136, NA, grfc, NA, NA, NA, NA, NA),
+       PINGROUP(137, NA, grfc, NA, NA, NA, NA, NA),
+       PINGROUP(138, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(139, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(140, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(141, NA, grfc, NA, NA, NA, NA, NA),
+       PINGROUP(142, NA, NA, NA, NA, NA, NA, NA),
+       PINGROUP(143, NA, grfc, NA, NA, NA, NA, NA),
+       PINGROUP(144, hsic, NA, NA, NA, NA, NA, NA),
+       PINGROUP(145, hsic, NA, NA, NA, NA, NA, NA),
+       SDC_PINGROUP(sdc1_clk, 0x2044, 13, 6),
+       SDC_PINGROUP(sdc1_cmd, 0x2044, 11, 3),
+       SDC_PINGROUP(sdc1_data, 0x2044, 9, 0),
+       SDC_PINGROUP(sdc2_clk, 0x2048, 14, 6),
+       SDC_PINGROUP(sdc2_cmd, 0x2048, 11, 3),
+       SDC_PINGROUP(sdc2_data, 0x2048, 9, 0),
+};
+
+#define NUM_GPIO_PINGROUPS 146
+
+static const struct msm_pinctrl_soc_data msm8x74_pinctrl = {
+       .pins = msm8x74_pins,
+       .npins = ARRAY_SIZE(msm8x74_pins),
+       .functions = msm8x74_functions,
+       .nfunctions = ARRAY_SIZE(msm8x74_functions),
+       .groups = msm8x74_groups,
+       .ngroups = ARRAY_SIZE(msm8x74_groups),
+       .ngpios = NUM_GPIO_PINGROUPS,
+};
+
+static int msm8x74_pinctrl_probe(struct platform_device *pdev)
+{
+       return msm_pinctrl_probe(pdev, &msm8x74_pinctrl);
+}
+
+static const struct of_device_id msm8x74_pinctrl_of_match[] = {
+       { .compatible = "qcom,msm8974-pinctrl", },
+       { },
+};
+
+static struct platform_driver msm8x74_pinctrl_driver = {
+       .driver = {
+               .name = "msm8x74-pinctrl",
+               .owner = THIS_MODULE,
+               .of_match_table = msm8x74_pinctrl_of_match,
+       },
+       .probe = msm8x74_pinctrl_probe,
+       .remove = msm_pinctrl_remove,
+};
+
+static int __init msm8x74_pinctrl_init(void)
+{
+       return platform_driver_register(&msm8x74_pinctrl_driver);
+}
+arch_initcall(msm8x74_pinctrl_init);
+
+static void __exit msm8x74_pinctrl_exit(void)
+{
+       platform_driver_unregister(&msm8x74_pinctrl_driver);
+}
+module_exit(msm8x74_pinctrl_exit);
+
+MODULE_AUTHOR("Bjorn Andersson <bjorn.andersson@sonymobile.com>");
+MODULE_DESCRIPTION("Qualcomm MSM8x74 pinctrl driver");
+MODULE_LICENSE("GPL v2");
+MODULE_DEVICE_TABLE(of, msm8x74_pinctrl_of_match);
+
diff --git a/drivers/pinctrl/samsung/Kconfig b/drivers/pinctrl/samsung/Kconfig
new file mode 100644 (file)
index 0000000..d0461cd
--- /dev/null
@@ -0,0 +1,28 @@
+#
+# Samsung Pin control drivers
+#
+config PINCTRL_SAMSUNG
+       bool
+       select PINMUX
+       select PINCONF
+
+config PINCTRL_EXYNOS
+       bool "Pinctrl driver data for Samsung EXYNOS SoCs other than 5440"
+       depends on OF && GPIOLIB && (ARCH_EXYNOS || ARCH_S5PV210)
+       select PINCTRL_SAMSUNG
+
+config PINCTRL_EXYNOS5440
+       bool "Samsung EXYNOS5440 SoC pinctrl driver"
+       depends on SOC_EXYNOS5440
+       select PINMUX
+       select PINCONF
+
+config PINCTRL_S3C24XX
+       bool "Samsung S3C24XX SoC pinctrl driver"
+       depends on ARCH_S3C24XX
+       select PINCTRL_SAMSUNG
+
+config PINCTRL_S3C64XX
+       bool "Samsung S3C64XX SoC pinctrl driver"
+       depends on ARCH_S3C64XX
+       select PINCTRL_SAMSUNG
diff --git a/drivers/pinctrl/samsung/Makefile b/drivers/pinctrl/samsung/Makefile
new file mode 100644 (file)
index 0000000..70160c0
--- /dev/null
@@ -0,0 +1,7 @@
+# Samsung pin control drivers
+
+obj-$(CONFIG_PINCTRL_SAMSUNG)  += pinctrl-samsung.o
+obj-$(CONFIG_PINCTRL_EXYNOS)   += pinctrl-exynos.o
+obj-$(CONFIG_PINCTRL_EXYNOS5440)       += pinctrl-exynos5440.o
+obj-$(CONFIG_PINCTRL_S3C24XX)  += pinctrl-s3c24xx.o
+obj-$(CONFIG_PINCTRL_S3C64XX)  += pinctrl-s3c64xx.o
diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.c b/drivers/pinctrl/samsung/pinctrl-exynos.c
new file mode 100644 (file)
index 0000000..003bfd8
--- /dev/null
@@ -0,0 +1,1123 @@
+/*
+ * Exynos specific support for Samsung pinctrl/gpiolib driver with eint support.
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ * Copyright (c) 2012 Linaro Ltd
+ *             http://www.linaro.org
+ *
+ * Author: Thomas Abraham <thomas.ab@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This file contains the Samsung Exynos specific information required by the
+ * the Samsung pinctrl/gpiolib driver. It also includes the implementation of
+ * external gpio and wakeup interrupt support.
+ */
+
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/irqdomain.h>
+#include <linux/irq.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/of_irq.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/err.h>
+
+#include "pinctrl-samsung.h"
+#include "pinctrl-exynos.h"
+
+struct exynos_irq_chip {
+       struct irq_chip chip;
+
+       u32 eint_con;
+       u32 eint_mask;
+       u32 eint_pend;
+};
+
+static inline struct exynos_irq_chip *to_exynos_irq_chip(struct irq_chip *chip)
+{
+       return container_of(chip, struct exynos_irq_chip, chip);
+}
+
+static struct samsung_pin_bank_type bank_type_off = {
+       .fld_width = { 4, 1, 2, 2, 2, 2, },
+       .reg_offset = { 0x00, 0x04, 0x08, 0x0c, 0x10, 0x14, },
+};
+
+static struct samsung_pin_bank_type bank_type_alive = {
+       .fld_width = { 4, 1, 2, 2, },
+       .reg_offset = { 0x00, 0x04, 0x08, 0x0c, },
+};
+
+/* list of external wakeup controllers supported */
+static const struct of_device_id exynos_wkup_irq_ids[] = {
+       { .compatible = "samsung,exynos4210-wakeup-eint", },
+       { }
+};
+
+static void exynos_irq_mask(struct irq_data *irqd)
+{
+       struct irq_chip *chip = irq_data_get_irq_chip(irqd);
+       struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip);
+       struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
+       struct samsung_pinctrl_drv_data *d = bank->drvdata;
+       unsigned long reg_mask = our_chip->eint_mask + bank->eint_offset;
+       unsigned long mask;
+       unsigned long flags;
+
+       spin_lock_irqsave(&bank->slock, flags);
+
+       mask = readl(d->virt_base + reg_mask);
+       mask |= 1 << irqd->hwirq;
+       writel(mask, d->virt_base + reg_mask);
+
+       spin_unlock_irqrestore(&bank->slock, flags);
+}
+
+static void exynos_irq_ack(struct irq_data *irqd)
+{
+       struct irq_chip *chip = irq_data_get_irq_chip(irqd);
+       struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip);
+       struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
+       struct samsung_pinctrl_drv_data *d = bank->drvdata;
+       unsigned long reg_pend = our_chip->eint_pend + bank->eint_offset;
+
+       writel(1 << irqd->hwirq, d->virt_base + reg_pend);
+}
+
+static void exynos_irq_unmask(struct irq_data *irqd)
+{
+       struct irq_chip *chip = irq_data_get_irq_chip(irqd);
+       struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip);
+       struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
+       struct samsung_pinctrl_drv_data *d = bank->drvdata;
+       unsigned long reg_mask = our_chip->eint_mask + bank->eint_offset;
+       unsigned long mask;
+       unsigned long flags;
+
+       /*
+        * Ack level interrupts right before unmask
+        *
+        * If we don't do this we'll get a double-interrupt.  Level triggered
+        * interrupts must not fire an interrupt if the level is not
+        * _currently_ active, even if it was active while the interrupt was
+        * masked.
+        */
+       if (irqd_get_trigger_type(irqd) & IRQ_TYPE_LEVEL_MASK)
+               exynos_irq_ack(irqd);
+
+       spin_lock_irqsave(&bank->slock, flags);
+
+       mask = readl(d->virt_base + reg_mask);
+       mask &= ~(1 << irqd->hwirq);
+       writel(mask, d->virt_base + reg_mask);
+
+       spin_unlock_irqrestore(&bank->slock, flags);
+}
+
+static int exynos_irq_set_type(struct irq_data *irqd, unsigned int type)
+{
+       struct irq_chip *chip = irq_data_get_irq_chip(irqd);
+       struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip);
+       struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
+       struct samsung_pin_bank_type *bank_type = bank->type;
+       struct samsung_pinctrl_drv_data *d = bank->drvdata;
+       unsigned int pin = irqd->hwirq;
+       unsigned int shift = EXYNOS_EINT_CON_LEN * pin;
+       unsigned int con, trig_type;
+       unsigned long reg_con = our_chip->eint_con + bank->eint_offset;
+       unsigned long flags;
+       unsigned int mask;
+
+       switch (type) {
+       case IRQ_TYPE_EDGE_RISING:
+               trig_type = EXYNOS_EINT_EDGE_RISING;
+               break;
+       case IRQ_TYPE_EDGE_FALLING:
+               trig_type = EXYNOS_EINT_EDGE_FALLING;
+               break;
+       case IRQ_TYPE_EDGE_BOTH:
+               trig_type = EXYNOS_EINT_EDGE_BOTH;
+               break;
+       case IRQ_TYPE_LEVEL_HIGH:
+               trig_type = EXYNOS_EINT_LEVEL_HIGH;
+               break;
+       case IRQ_TYPE_LEVEL_LOW:
+               trig_type = EXYNOS_EINT_LEVEL_LOW;
+               break;
+       default:
+               pr_err("unsupported external interrupt type\n");
+               return -EINVAL;
+       }
+
+       if (type & IRQ_TYPE_EDGE_BOTH)
+               __irq_set_handler_locked(irqd->irq, handle_edge_irq);
+       else
+               __irq_set_handler_locked(irqd->irq, handle_level_irq);
+
+       con = readl(d->virt_base + reg_con);
+       con &= ~(EXYNOS_EINT_CON_MASK << shift);
+       con |= trig_type << shift;
+       writel(con, d->virt_base + reg_con);
+
+       reg_con = bank->pctl_offset + bank_type->reg_offset[PINCFG_TYPE_FUNC];
+       shift = pin * bank_type->fld_width[PINCFG_TYPE_FUNC];
+       mask = (1 << bank_type->fld_width[PINCFG_TYPE_FUNC]) - 1;
+
+       spin_lock_irqsave(&bank->slock, flags);
+
+       con = readl(d->virt_base + reg_con);
+       con &= ~(mask << shift);
+       con |= EXYNOS_EINT_FUNC << shift;
+       writel(con, d->virt_base + reg_con);
+
+       spin_unlock_irqrestore(&bank->slock, flags);
+
+       return 0;
+}
+
+/*
+ * irq_chip for gpio interrupts.
+ */
+static struct exynos_irq_chip exynos_gpio_irq_chip = {
+       .chip = {
+               .name = "exynos_gpio_irq_chip",
+               .irq_unmask = exynos_irq_unmask,
+               .irq_mask = exynos_irq_mask,
+               .irq_ack = exynos_irq_ack,
+               .irq_set_type = exynos_irq_set_type,
+       },
+       .eint_con = EXYNOS_GPIO_ECON_OFFSET,
+       .eint_mask = EXYNOS_GPIO_EMASK_OFFSET,
+       .eint_pend = EXYNOS_GPIO_EPEND_OFFSET,
+};
+
+static int exynos_gpio_irq_map(struct irq_domain *h, unsigned int virq,
+                                       irq_hw_number_t hw)
+{
+       struct samsung_pin_bank *b = h->host_data;
+
+       irq_set_chip_data(virq, b);
+       irq_set_chip_and_handler(virq, &exynos_gpio_irq_chip.chip,
+                                       handle_level_irq);
+       set_irq_flags(virq, IRQF_VALID);
+       return 0;
+}
+
+/*
+ * irq domain callbacks for external gpio interrupt controller.
+ */
+static const struct irq_domain_ops exynos_gpio_irqd_ops = {
+       .map    = exynos_gpio_irq_map,
+       .xlate  = irq_domain_xlate_twocell,
+};
+
+static irqreturn_t exynos_eint_gpio_irq(int irq, void *data)
+{
+       struct samsung_pinctrl_drv_data *d = data;
+       struct samsung_pin_ctrl *ctrl = d->ctrl;
+       struct samsung_pin_bank *bank = ctrl->pin_banks;
+       unsigned int svc, group, pin, virq;
+
+       svc = readl(d->virt_base + EXYNOS_SVC_OFFSET);
+       group = EXYNOS_SVC_GROUP(svc);
+       pin = svc & EXYNOS_SVC_NUM_MASK;
+
+       if (!group)
+               return IRQ_HANDLED;
+       bank += (group - 1);
+
+       virq = irq_linear_revmap(bank->irq_domain, pin);
+       if (!virq)
+               return IRQ_NONE;
+       generic_handle_irq(virq);
+       return IRQ_HANDLED;
+}
+
+struct exynos_eint_gpio_save {
+       u32 eint_con;
+       u32 eint_fltcon0;
+       u32 eint_fltcon1;
+};
+
+/*
+ * exynos_eint_gpio_init() - setup handling of external gpio interrupts.
+ * @d: driver data of samsung pinctrl driver.
+ */
+static int exynos_eint_gpio_init(struct samsung_pinctrl_drv_data *d)
+{
+       struct samsung_pin_bank *bank;
+       struct device *dev = d->dev;
+       int ret;
+       int i;
+
+       if (!d->irq) {
+               dev_err(dev, "irq number not available\n");
+               return -EINVAL;
+       }
+
+       ret = devm_request_irq(dev, d->irq, exynos_eint_gpio_irq,
+                                       0, dev_name(dev), d);
+       if (ret) {
+               dev_err(dev, "irq request failed\n");
+               return -ENXIO;
+       }
+
+       bank = d->ctrl->pin_banks;
+       for (i = 0; i < d->ctrl->nr_banks; ++i, ++bank) {
+               if (bank->eint_type != EINT_TYPE_GPIO)
+                       continue;
+               bank->irq_domain = irq_domain_add_linear(bank->of_node,
+                               bank->nr_pins, &exynos_gpio_irqd_ops, bank);
+               if (!bank->irq_domain) {
+                       dev_err(dev, "gpio irq domain add failed\n");
+                       ret = -ENXIO;
+                       goto err_domains;
+               }
+
+               bank->soc_priv = devm_kzalloc(d->dev,
+                       sizeof(struct exynos_eint_gpio_save), GFP_KERNEL);
+               if (!bank->soc_priv) {
+                       irq_domain_remove(bank->irq_domain);
+                       ret = -ENOMEM;
+                       goto err_domains;
+               }
+       }
+
+       return 0;
+
+err_domains:
+       for (--i, --bank; i >= 0; --i, --bank) {
+               if (bank->eint_type != EINT_TYPE_GPIO)
+                       continue;
+               irq_domain_remove(bank->irq_domain);
+       }
+
+       return ret;
+}
+
+static u32 exynos_eint_wake_mask = 0xffffffff;
+
+u32 exynos_get_eint_wake_mask(void)
+{
+       return exynos_eint_wake_mask;
+}
+
+static int exynos_wkup_irq_set_wake(struct irq_data *irqd, unsigned int on)
+{
+       struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
+       unsigned long bit = 1UL << (2 * bank->eint_offset + irqd->hwirq);
+
+       pr_info("wake %s for irq %d\n", on ? "enabled" : "disabled", irqd->irq);
+
+       if (!on)
+               exynos_eint_wake_mask |= bit;
+       else
+               exynos_eint_wake_mask &= ~bit;
+
+       return 0;
+}
+
+/*
+ * irq_chip for wakeup interrupts
+ */
+static struct exynos_irq_chip exynos_wkup_irq_chip = {
+       .chip = {
+               .name = "exynos_wkup_irq_chip",
+               .irq_unmask = exynos_irq_unmask,
+               .irq_mask = exynos_irq_mask,
+               .irq_ack = exynos_irq_ack,
+               .irq_set_type = exynos_irq_set_type,
+               .irq_set_wake = exynos_wkup_irq_set_wake,
+       },
+       .eint_con = EXYNOS_WKUP_ECON_OFFSET,
+       .eint_mask = EXYNOS_WKUP_EMASK_OFFSET,
+       .eint_pend = EXYNOS_WKUP_EPEND_OFFSET,
+};
+
+/* interrupt handler for wakeup interrupts 0..15 */
+static void exynos_irq_eint0_15(unsigned int irq, struct irq_desc *desc)
+{
+       struct exynos_weint_data *eintd = irq_get_handler_data(irq);
+       struct samsung_pin_bank *bank = eintd->bank;
+       struct irq_chip *chip = irq_get_chip(irq);
+       int eint_irq;
+
+       chained_irq_enter(chip, desc);
+       chip->irq_mask(&desc->irq_data);
+
+       if (chip->irq_ack)
+               chip->irq_ack(&desc->irq_data);
+
+       eint_irq = irq_linear_revmap(bank->irq_domain, eintd->irq);
+       generic_handle_irq(eint_irq);
+       chip->irq_unmask(&desc->irq_data);
+       chained_irq_exit(chip, desc);
+}
+
+static inline void exynos_irq_demux_eint(unsigned long pend,
+                                               struct irq_domain *domain)
+{
+       unsigned int irq;
+
+       while (pend) {
+               irq = fls(pend) - 1;
+               generic_handle_irq(irq_find_mapping(domain, irq));
+               pend &= ~(1 << irq);
+       }
+}
+
+/* interrupt handler for wakeup interrupt 16 */
+static void exynos_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc)
+{
+       struct irq_chip *chip = irq_get_chip(irq);
+       struct exynos_muxed_weint_data *eintd = irq_get_handler_data(irq);
+       struct samsung_pinctrl_drv_data *d = eintd->banks[0]->drvdata;
+       unsigned long pend;
+       unsigned long mask;
+       int i;
+
+       chained_irq_enter(chip, desc);
+
+       for (i = 0; i < eintd->nr_banks; ++i) {
+               struct samsung_pin_bank *b = eintd->banks[i];
+               pend = readl(d->virt_base + EXYNOS_WKUP_EPEND_OFFSET
+                               + b->eint_offset);
+               mask = readl(d->virt_base + EXYNOS_WKUP_EMASK_OFFSET
+                               + b->eint_offset);
+               exynos_irq_demux_eint(pend & ~mask, b->irq_domain);
+       }
+
+       chained_irq_exit(chip, desc);
+}
+
+static int exynos_wkup_irq_map(struct irq_domain *h, unsigned int virq,
+                                       irq_hw_number_t hw)
+{
+       irq_set_chip_and_handler(virq, &exynos_wkup_irq_chip.chip,
+                                       handle_level_irq);
+       irq_set_chip_data(virq, h->host_data);
+       set_irq_flags(virq, IRQF_VALID);
+       return 0;
+}
+
+/*
+ * irq domain callbacks for external wakeup interrupt controller.
+ */
+static const struct irq_domain_ops exynos_wkup_irqd_ops = {
+       .map    = exynos_wkup_irq_map,
+       .xlate  = irq_domain_xlate_twocell,
+};
+
+/*
+ * exynos_eint_wkup_init() - setup handling of external wakeup interrupts.
+ * @d: driver data of samsung pinctrl driver.
+ */
+static int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d)
+{
+       struct device *dev = d->dev;
+       struct device_node *wkup_np = NULL;
+       struct device_node *np;
+       struct samsung_pin_bank *bank;
+       struct exynos_weint_data *weint_data;
+       struct exynos_muxed_weint_data *muxed_data;
+       unsigned int muxed_banks = 0;
+       unsigned int i;
+       int idx, irq;
+
+       for_each_child_of_node(dev->of_node, np) {
+               if (of_match_node(exynos_wkup_irq_ids, np)) {
+                       wkup_np = np;
+                       break;
+               }
+       }
+       if (!wkup_np)
+               return -ENODEV;
+
+       bank = d->ctrl->pin_banks;
+       for (i = 0; i < d->ctrl->nr_banks; ++i, ++bank) {
+               if (bank->eint_type != EINT_TYPE_WKUP)
+                       continue;
+
+               bank->irq_domain = irq_domain_add_linear(bank->of_node,
+                               bank->nr_pins, &exynos_wkup_irqd_ops, bank);
+               if (!bank->irq_domain) {
+                       dev_err(dev, "wkup irq domain add failed\n");
+                       return -ENXIO;
+               }
+
+               if (!of_find_property(bank->of_node, "interrupts", NULL)) {
+                       bank->eint_type = EINT_TYPE_WKUP_MUX;
+                       ++muxed_banks;
+                       continue;
+               }
+
+               weint_data = devm_kzalloc(dev, bank->nr_pins
+                                       * sizeof(*weint_data), GFP_KERNEL);
+               if (!weint_data) {
+                       dev_err(dev, "could not allocate memory for weint_data\n");
+                       return -ENOMEM;
+               }
+
+               for (idx = 0; idx < bank->nr_pins; ++idx) {
+                       irq = irq_of_parse_and_map(bank->of_node, idx);
+                       if (!irq) {
+                               dev_err(dev, "irq number for eint-%s-%d not found\n",
+                                                       bank->name, idx);
+                               continue;
+                       }
+                       weint_data[idx].irq = idx;
+                       weint_data[idx].bank = bank;
+                       irq_set_handler_data(irq, &weint_data[idx]);
+                       irq_set_chained_handler(irq, exynos_irq_eint0_15);
+               }
+       }
+
+       if (!muxed_banks)
+               return 0;
+
+       irq = irq_of_parse_and_map(wkup_np, 0);
+       if (!irq) {
+               dev_err(dev, "irq number for muxed EINTs not found\n");
+               return 0;
+       }
+
+       muxed_data = devm_kzalloc(dev, sizeof(*muxed_data)
+               + muxed_banks*sizeof(struct samsung_pin_bank *), GFP_KERNEL);
+       if (!muxed_data) {
+               dev_err(dev, "could not allocate memory for muxed_data\n");
+               return -ENOMEM;
+       }
+
+       irq_set_chained_handler(irq, exynos_irq_demux_eint16_31);
+       irq_set_handler_data(irq, muxed_data);
+
+       bank = d->ctrl->pin_banks;
+       idx = 0;
+       for (i = 0; i < d->ctrl->nr_banks; ++i, ++bank) {
+               if (bank->eint_type != EINT_TYPE_WKUP_MUX)
+                       continue;
+
+               muxed_data->banks[idx++] = bank;
+       }
+       muxed_data->nr_banks = muxed_banks;
+
+       return 0;
+}
+
+static void exynos_pinctrl_suspend_bank(
+                               struct samsung_pinctrl_drv_data *drvdata,
+                               struct samsung_pin_bank *bank)
+{
+       struct exynos_eint_gpio_save *save = bank->soc_priv;
+       void __iomem *regs = drvdata->virt_base;
+
+       save->eint_con = readl(regs + EXYNOS_GPIO_ECON_OFFSET
+                                               + bank->eint_offset);
+       save->eint_fltcon0 = readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET
+                                               + 2 * bank->eint_offset);
+       save->eint_fltcon1 = readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET
+                                               + 2 * bank->eint_offset + 4);
+
+       pr_debug("%s: save     con %#010x\n", bank->name, save->eint_con);
+       pr_debug("%s: save fltcon0 %#010x\n", bank->name, save->eint_fltcon0);
+       pr_debug("%s: save fltcon1 %#010x\n", bank->name, save->eint_fltcon1);
+}
+
+static void exynos_pinctrl_suspend(struct samsung_pinctrl_drv_data *drvdata)
+{
+       struct samsung_pin_ctrl *ctrl = drvdata->ctrl;
+       struct samsung_pin_bank *bank = ctrl->pin_banks;
+       int i;
+
+       for (i = 0; i < ctrl->nr_banks; ++i, ++bank)
+               if (bank->eint_type == EINT_TYPE_GPIO)
+                       exynos_pinctrl_suspend_bank(drvdata, bank);
+}
+
+static void exynos_pinctrl_resume_bank(
+                               struct samsung_pinctrl_drv_data *drvdata,
+                               struct samsung_pin_bank *bank)
+{
+       struct exynos_eint_gpio_save *save = bank->soc_priv;
+       void __iomem *regs = drvdata->virt_base;
+
+       pr_debug("%s:     con %#010x => %#010x\n", bank->name,
+                       readl(regs + EXYNOS_GPIO_ECON_OFFSET
+                       + bank->eint_offset), save->eint_con);
+       pr_debug("%s: fltcon0 %#010x => %#010x\n", bank->name,
+                       readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET
+                       + 2 * bank->eint_offset), save->eint_fltcon0);
+       pr_debug("%s: fltcon1 %#010x => %#010x\n", bank->name,
+                       readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET
+                       + 2 * bank->eint_offset + 4), save->eint_fltcon1);
+
+       writel(save->eint_con, regs + EXYNOS_GPIO_ECON_OFFSET
+                                               + bank->eint_offset);
+       writel(save->eint_fltcon0, regs + EXYNOS_GPIO_EFLTCON_OFFSET
+                                               + 2 * bank->eint_offset);
+       writel(save->eint_fltcon1, regs + EXYNOS_GPIO_EFLTCON_OFFSET
+                                               + 2 * bank->eint_offset + 4);
+}
+
+static void exynos_pinctrl_resume(struct samsung_pinctrl_drv_data *drvdata)
+{
+       struct samsung_pin_ctrl *ctrl = drvdata->ctrl;
+       struct samsung_pin_bank *bank = ctrl->pin_banks;
+       int i;
+
+       for (i = 0; i < ctrl->nr_banks; ++i, ++bank)
+               if (bank->eint_type == EINT_TYPE_GPIO)
+                       exynos_pinctrl_resume_bank(drvdata, bank);
+}
+
+/* pin banks of s5pv210 pin-controller */
+static struct samsung_pin_bank s5pv210_pin_bank[] = {
+       EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00),
+       EXYNOS_PIN_BANK_EINTG(4, 0x020, "gpa1", 0x04),
+       EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpb", 0x08),
+       EXYNOS_PIN_BANK_EINTG(5, 0x060, "gpc0", 0x0c),
+       EXYNOS_PIN_BANK_EINTG(5, 0x080, "gpc1", 0x10),
+       EXYNOS_PIN_BANK_EINTG(4, 0x0a0, "gpd0", 0x14),
+       EXYNOS_PIN_BANK_EINTG(6, 0x0c0, "gpd1", 0x18),
+       EXYNOS_PIN_BANK_EINTG(8, 0x0e0, "gpe0", 0x1c),
+       EXYNOS_PIN_BANK_EINTG(5, 0x100, "gpe1", 0x20),
+       EXYNOS_PIN_BANK_EINTG(8, 0x120, "gpf0", 0x24),
+       EXYNOS_PIN_BANK_EINTG(8, 0x140, "gpf1", 0x28),
+       EXYNOS_PIN_BANK_EINTG(8, 0x160, "gpf2", 0x2c),
+       EXYNOS_PIN_BANK_EINTG(6, 0x180, "gpf3", 0x30),
+       EXYNOS_PIN_BANK_EINTG(7, 0x1a0, "gpg0", 0x34),
+       EXYNOS_PIN_BANK_EINTG(7, 0x1c0, "gpg1", 0x38),
+       EXYNOS_PIN_BANK_EINTG(7, 0x1e0, "gpg2", 0x3c),
+       EXYNOS_PIN_BANK_EINTG(7, 0x200, "gpg3", 0x40),
+       EXYNOS_PIN_BANK_EINTN(7, 0x220, "gpi"),
+       EXYNOS_PIN_BANK_EINTG(8, 0x240, "gpj0", 0x44),
+       EXYNOS_PIN_BANK_EINTG(6, 0x260, "gpj1", 0x48),
+       EXYNOS_PIN_BANK_EINTG(8, 0x280, "gpj2", 0x4c),
+       EXYNOS_PIN_BANK_EINTG(8, 0x2a0, "gpj3", 0x50),
+       EXYNOS_PIN_BANK_EINTG(5, 0x2c0, "gpj4", 0x54),
+       EXYNOS_PIN_BANK_EINTN(8, 0x2e0, "mp01"),
+       EXYNOS_PIN_BANK_EINTN(4, 0x300, "mp02"),
+       EXYNOS_PIN_BANK_EINTN(8, 0x320, "mp03"),
+       EXYNOS_PIN_BANK_EINTN(8, 0x340, "mp04"),
+       EXYNOS_PIN_BANK_EINTN(8, 0x360, "mp05"),
+       EXYNOS_PIN_BANK_EINTN(8, 0x380, "mp06"),
+       EXYNOS_PIN_BANK_EINTN(8, 0x3a0, "mp07"),
+       EXYNOS_PIN_BANK_EINTW(8, 0xc00, "gph0", 0x00),
+       EXYNOS_PIN_BANK_EINTW(8, 0xc20, "gph1", 0x04),
+       EXYNOS_PIN_BANK_EINTW(8, 0xc40, "gph2", 0x08),
+       EXYNOS_PIN_BANK_EINTW(8, 0xc60, "gph3", 0x0c),
+};
+
+struct samsung_pin_ctrl s5pv210_pin_ctrl[] = {
+       {
+               /* pin-controller instance 0 data */
+               .pin_banks      = s5pv210_pin_bank,
+               .nr_banks       = ARRAY_SIZE(s5pv210_pin_bank),
+               .eint_gpio_init = exynos_eint_gpio_init,
+               .eint_wkup_init = exynos_eint_wkup_init,
+               .suspend        = exynos_pinctrl_suspend,
+               .resume         = exynos_pinctrl_resume,
+               .label          = "s5pv210-gpio-ctrl0",
+       },
+};
+
+/* pin banks of exynos3250 pin-controller 0 */
+static struct samsung_pin_bank exynos3250_pin_banks0[] = {
+       EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00),
+       EXYNOS_PIN_BANK_EINTG(6, 0x020, "gpa1", 0x04),
+       EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpb",  0x08),
+       EXYNOS_PIN_BANK_EINTG(5, 0x060, "gpc0", 0x0c),
+       EXYNOS_PIN_BANK_EINTG(5, 0x080, "gpc1", 0x10),
+       EXYNOS_PIN_BANK_EINTG(4, 0x0a0, "gpd0", 0x14),
+       EXYNOS_PIN_BANK_EINTG(4, 0x0c0, "gpd1", 0x18),
+};
+
+/* pin banks of exynos3250 pin-controller 1 */
+static struct samsung_pin_bank exynos3250_pin_banks1[] = {
+       EXYNOS_PIN_BANK_EINTN(8, 0x120, "gpe0"),
+       EXYNOS_PIN_BANK_EINTN(8, 0x140, "gpe1"),
+       EXYNOS_PIN_BANK_EINTN(3, 0x180, "gpe2"),
+       EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpk0", 0x08),
+       EXYNOS_PIN_BANK_EINTG(7, 0x060, "gpk1", 0x0c),
+       EXYNOS_PIN_BANK_EINTG(7, 0x080, "gpk2", 0x10),
+       EXYNOS_PIN_BANK_EINTG(4, 0x0c0, "gpl0", 0x18),
+       EXYNOS_PIN_BANK_EINTG(8, 0x260, "gpm0", 0x24),
+       EXYNOS_PIN_BANK_EINTG(7, 0x280, "gpm1", 0x28),
+       EXYNOS_PIN_BANK_EINTG(5, 0x2a0, "gpm2", 0x2c),
+       EXYNOS_PIN_BANK_EINTG(8, 0x2c0, "gpm3", 0x30),
+       EXYNOS_PIN_BANK_EINTG(8, 0x2e0, "gpm4", 0x34),
+       EXYNOS_PIN_BANK_EINTW(8, 0xc00, "gpx0", 0x00),
+       EXYNOS_PIN_BANK_EINTW(8, 0xc20, "gpx1", 0x04),
+       EXYNOS_PIN_BANK_EINTW(8, 0xc40, "gpx2", 0x08),
+       EXYNOS_PIN_BANK_EINTW(8, 0xc60, "gpx3", 0x0c),
+};
+
+/*
+ * Samsung pinctrl driver data for Exynos3250 SoC. Exynos3250 SoC includes
+ * two gpio/pin-mux/pinconfig controllers.
+ */
+struct samsung_pin_ctrl exynos3250_pin_ctrl[] = {
+       {
+               /* pin-controller instance 0 data */
+               .pin_banks      = exynos3250_pin_banks0,
+               .nr_banks       = ARRAY_SIZE(exynos3250_pin_banks0),
+               .eint_gpio_init = exynos_eint_gpio_init,
+               .suspend        = exynos_pinctrl_suspend,
+               .resume         = exynos_pinctrl_resume,
+               .label          = "exynos3250-gpio-ctrl0",
+       }, {
+               /* pin-controller instance 1 data */
+               .pin_banks      = exynos3250_pin_banks1,
+               .nr_banks       = ARRAY_SIZE(exynos3250_pin_banks1),
+               .eint_gpio_init = exynos_eint_gpio_init,
+               .eint_wkup_init = exynos_eint_wkup_init,
+               .suspend        = exynos_pinctrl_suspend,
+               .resume         = exynos_pinctrl_resume,
+               .label          = "exynos3250-gpio-ctrl1",
+       },
+};
+
+/* pin banks of exynos4210 pin-controller 0 */
+static struct samsung_pin_bank exynos4210_pin_banks0[] = {
+       EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00),
+       EXYNOS_PIN_BANK_EINTG(6, 0x020, "gpa1", 0x04),
+       EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpb", 0x08),
+       EXYNOS_PIN_BANK_EINTG(5, 0x060, "gpc0", 0x0c),
+       EXYNOS_PIN_BANK_EINTG(5, 0x080, "gpc1", 0x10),
+       EXYNOS_PIN_BANK_EINTG(4, 0x0A0, "gpd0", 0x14),
+       EXYNOS_PIN_BANK_EINTG(4, 0x0C0, "gpd1", 0x18),
+       EXYNOS_PIN_BANK_EINTG(5, 0x0E0, "gpe0", 0x1c),
+       EXYNOS_PIN_BANK_EINTG(8, 0x100, "gpe1", 0x20),
+       EXYNOS_PIN_BANK_EINTG(6, 0x120, "gpe2", 0x24),
+       EXYNOS_PIN_BANK_EINTG(8, 0x140, "gpe3", 0x28),
+       EXYNOS_PIN_BANK_EINTG(8, 0x160, "gpe4", 0x2c),
+       EXYNOS_PIN_BANK_EINTG(8, 0x180, "gpf0", 0x30),
+       EXYNOS_PIN_BANK_EINTG(8, 0x1A0, "gpf1", 0x34),
+       EXYNOS_PIN_BANK_EINTG(8, 0x1C0, "gpf2", 0x38),
+       EXYNOS_PIN_BANK_EINTG(6, 0x1E0, "gpf3", 0x3c),
+};
+
+/* pin banks of exynos4210 pin-controller 1 */
+static struct samsung_pin_bank exynos4210_pin_banks1[] = {
+       EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpj0", 0x00),
+       EXYNOS_PIN_BANK_EINTG(5, 0x020, "gpj1", 0x04),
+       EXYNOS_PIN_BANK_EINTG(7, 0x040, "gpk0", 0x08),
+       EXYNOS_PIN_BANK_EINTG(7, 0x060, "gpk1", 0x0c),
+       EXYNOS_PIN_BANK_EINTG(7, 0x080, "gpk2", 0x10),
+       EXYNOS_PIN_BANK_EINTG(7, 0x0A0, "gpk3", 0x14),
+       EXYNOS_PIN_BANK_EINTG(8, 0x0C0, "gpl0", 0x18),
+       EXYNOS_PIN_BANK_EINTG(3, 0x0E0, "gpl1", 0x1c),
+       EXYNOS_PIN_BANK_EINTG(8, 0x100, "gpl2", 0x20),
+       EXYNOS_PIN_BANK_EINTN(6, 0x120, "gpy0"),
+       EXYNOS_PIN_BANK_EINTN(4, 0x140, "gpy1"),
+       EXYNOS_PIN_BANK_EINTN(6, 0x160, "gpy2"),
+       EXYNOS_PIN_BANK_EINTN(8, 0x180, "gpy3"),
+       EXYNOS_PIN_BANK_EINTN(8, 0x1A0, "gpy4"),
+       EXYNOS_PIN_BANK_EINTN(8, 0x1C0, "gpy5"),
+       EXYNOS_PIN_BANK_EINTN(8, 0x1E0, "gpy6"),
+       EXYNOS_PIN_BANK_EINTW(8, 0xC00, "gpx0", 0x00),
+       EXYNOS_PIN_BANK_EINTW(8, 0xC20, "gpx1", 0x04),
+       EXYNOS_PIN_BANK_EINTW(8, 0xC40, "gpx2", 0x08),
+       EXYNOS_PIN_BANK_EINTW(8, 0xC60, "gpx3", 0x0c),
+};
+
+/* pin banks of exynos4210 pin-controller 2 */
+static struct samsung_pin_bank exynos4210_pin_banks2[] = {
+       EXYNOS_PIN_BANK_EINTN(7, 0x000, "gpz"),
+};
+
+/*
+ * Samsung pinctrl driver data for Exynos4210 SoC. Exynos4210 SoC includes
+ * three gpio/pin-mux/pinconfig controllers.
+ */
+struct samsung_pin_ctrl exynos4210_pin_ctrl[] = {
+       {
+               /* pin-controller instance 0 data */
+               .pin_banks      = exynos4210_pin_banks0,
+               .nr_banks       = ARRAY_SIZE(exynos4210_pin_banks0),
+               .eint_gpio_init = exynos_eint_gpio_init,
+               .suspend        = exynos_pinctrl_suspend,
+               .resume         = exynos_pinctrl_resume,
+               .label          = "exynos4210-gpio-ctrl0",
+       }, {
+               /* pin-controller instance 1 data */
+               .pin_banks      = exynos4210_pin_banks1,
+               .nr_banks       = ARRAY_SIZE(exynos4210_pin_banks1),
+               .eint_gpio_init = exynos_eint_gpio_init,
+               .eint_wkup_init = exynos_eint_wkup_init,
+               .suspend        = exynos_pinctrl_suspend,
+               .resume         = exynos_pinctrl_resume,
+               .label          = "exynos4210-gpio-ctrl1",
+       }, {
+               /* pin-controller instance 2 data */
+               .pin_banks      = exynos4210_pin_banks2,
+               .nr_banks       = ARRAY_SIZE(exynos4210_pin_banks2),
+               .label          = "exynos4210-gpio-ctrl2",
+       },
+};
+
+/* pin banks of exynos4x12 pin-controller 0 */
+static struct samsung_pin_bank exynos4x12_pin_banks0[] = {
+       EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00),
+       EXYNOS_PIN_BANK_EINTG(6, 0x020, "gpa1", 0x04),
+       EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpb", 0x08),
+       EXYNOS_PIN_BANK_EINTG(5, 0x060, "gpc0", 0x0c),
+       EXYNOS_PIN_BANK_EINTG(5, 0x080, "gpc1", 0x10),
+       EXYNOS_PIN_BANK_EINTG(4, 0x0A0, "gpd0", 0x14),
+       EXYNOS_PIN_BANK_EINTG(4, 0x0C0, "gpd1", 0x18),
+       EXYNOS_PIN_BANK_EINTG(8, 0x180, "gpf0", 0x30),
+       EXYNOS_PIN_BANK_EINTG(8, 0x1A0, "gpf1", 0x34),
+       EXYNOS_PIN_BANK_EINTG(8, 0x1C0, "gpf2", 0x38),
+       EXYNOS_PIN_BANK_EINTG(6, 0x1E0, "gpf3", 0x3c),
+       EXYNOS_PIN_BANK_EINTG(8, 0x240, "gpj0", 0x40),
+       EXYNOS_PIN_BANK_EINTG(5, 0x260, "gpj1", 0x44),
+};
+
+/* pin banks of exynos4x12 pin-controller 1 */
+static struct samsung_pin_bank exynos4x12_pin_banks1[] = {
+       EXYNOS_PIN_BANK_EINTG(7, 0x040, "gpk0", 0x08),
+       EXYNOS_PIN_BANK_EINTG(7, 0x060, "gpk1", 0x0c),
+       EXYNOS_PIN_BANK_EINTG(7, 0x080, "gpk2", 0x10),
+       EXYNOS_PIN_BANK_EINTG(7, 0x0A0, "gpk3", 0x14),
+       EXYNOS_PIN_BANK_EINTG(7, 0x0C0, "gpl0", 0x18),
+       EXYNOS_PIN_BANK_EINTG(2, 0x0E0, "gpl1", 0x1c),
+       EXYNOS_PIN_BANK_EINTG(8, 0x100, "gpl2", 0x20),
+       EXYNOS_PIN_BANK_EINTG(8, 0x260, "gpm0", 0x24),
+       EXYNOS_PIN_BANK_EINTG(7, 0x280, "gpm1", 0x28),
+       EXYNOS_PIN_BANK_EINTG(5, 0x2A0, "gpm2", 0x2c),
+       EXYNOS_PIN_BANK_EINTG(8, 0x2C0, "gpm3", 0x30),
+       EXYNOS_PIN_BANK_EINTG(8, 0x2E0, "gpm4", 0x34),
+       EXYNOS_PIN_BANK_EINTN(6, 0x120, "gpy0"),
+       EXYNOS_PIN_BANK_EINTN(4, 0x140, "gpy1"),
+       EXYNOS_PIN_BANK_EINTN(6, 0x160, "gpy2"),
+       EXYNOS_PIN_BANK_EINTN(8, 0x180, "gpy3"),
+       EXYNOS_PIN_BANK_EINTN(8, 0x1A0, "gpy4"),
+       EXYNOS_PIN_BANK_EINTN(8, 0x1C0, "gpy5"),
+       EXYNOS_PIN_BANK_EINTN(8, 0x1E0, "gpy6"),
+       EXYNOS_PIN_BANK_EINTW(8, 0xC00, "gpx0", 0x00),
+       EXYNOS_PIN_BANK_EINTW(8, 0xC20, "gpx1", 0x04),
+       EXYNOS_PIN_BANK_EINTW(8, 0xC40, "gpx2", 0x08),
+       EXYNOS_PIN_BANK_EINTW(8, 0xC60, "gpx3", 0x0c),
+};
+
+/* pin banks of exynos4x12 pin-controller 2 */
+static struct samsung_pin_bank exynos4x12_pin_banks2[] = {
+       EXYNOS_PIN_BANK_EINTG(7, 0x000, "gpz", 0x00),
+};
+
+/* pin banks of exynos4x12 pin-controller 3 */
+static struct samsung_pin_bank exynos4x12_pin_banks3[] = {
+       EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpv0", 0x00),
+       EXYNOS_PIN_BANK_EINTG(8, 0x020, "gpv1", 0x04),
+       EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpv2", 0x08),
+       EXYNOS_PIN_BANK_EINTG(8, 0x060, "gpv3", 0x0c),
+       EXYNOS_PIN_BANK_EINTG(2, 0x080, "gpv4", 0x10),
+};
+
+/*
+ * Samsung pinctrl driver data for Exynos4x12 SoC. Exynos4x12 SoC includes
+ * four gpio/pin-mux/pinconfig controllers.
+ */
+struct samsung_pin_ctrl exynos4x12_pin_ctrl[] = {
+       {
+               /* pin-controller instance 0 data */
+               .pin_banks      = exynos4x12_pin_banks0,
+               .nr_banks       = ARRAY_SIZE(exynos4x12_pin_banks0),
+               .eint_gpio_init = exynos_eint_gpio_init,
+               .suspend        = exynos_pinctrl_suspend,
+               .resume         = exynos_pinctrl_resume,
+               .label          = "exynos4x12-gpio-ctrl0",
+       }, {
+               /* pin-controller instance 1 data */
+               .pin_banks      = exynos4x12_pin_banks1,
+               .nr_banks       = ARRAY_SIZE(exynos4x12_pin_banks1),
+               .eint_gpio_init = exynos_eint_gpio_init,
+               .eint_wkup_init = exynos_eint_wkup_init,
+               .suspend        = exynos_pinctrl_suspend,
+               .resume         = exynos_pinctrl_resume,
+               .label          = "exynos4x12-gpio-ctrl1",
+       }, {
+               /* pin-controller instance 2 data */
+               .pin_banks      = exynos4x12_pin_banks2,
+               .nr_banks       = ARRAY_SIZE(exynos4x12_pin_banks2),
+               .eint_gpio_init = exynos_eint_gpio_init,
+               .suspend        = exynos_pinctrl_suspend,
+               .resume         = exynos_pinctrl_resume,
+               .label          = "exynos4x12-gpio-ctrl2",
+       }, {
+               /* pin-controller instance 3 data */
+               .pin_banks      = exynos4x12_pin_banks3,
+               .nr_banks       = ARRAY_SIZE(exynos4x12_pin_banks3),
+               .eint_gpio_init = exynos_eint_gpio_init,
+               .suspend        = exynos_pinctrl_suspend,
+               .resume         = exynos_pinctrl_resume,
+               .label          = "exynos4x12-gpio-ctrl3",
+       },
+};
+
+/* pin banks of exynos5250 pin-controller 0 */
+static struct samsung_pin_bank exynos5250_pin_banks0[] = {
+       EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00),
+       EXYNOS_PIN_BANK_EINTG(6, 0x020, "gpa1", 0x04),
+       EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpa2", 0x08),
+       EXYNOS_PIN_BANK_EINTG(5, 0x060, "gpb0", 0x0c),
+       EXYNOS_PIN_BANK_EINTG(5, 0x080, "gpb1", 0x10),
+       EXYNOS_PIN_BANK_EINTG(4, 0x0A0, "gpb2", 0x14),
+       EXYNOS_PIN_BANK_EINTG(4, 0x0C0, "gpb3", 0x18),
+       EXYNOS_PIN_BANK_EINTG(7, 0x0E0, "gpc0", 0x1c),
+       EXYNOS_PIN_BANK_EINTG(4, 0x100, "gpc1", 0x20),
+       EXYNOS_PIN_BANK_EINTG(7, 0x120, "gpc2", 0x24),
+       EXYNOS_PIN_BANK_EINTG(7, 0x140, "gpc3", 0x28),
+       EXYNOS_PIN_BANK_EINTG(4, 0x160, "gpd0", 0x2c),
+       EXYNOS_PIN_BANK_EINTG(8, 0x180, "gpd1", 0x30),
+       EXYNOS_PIN_BANK_EINTG(7, 0x2E0, "gpc4", 0x34),
+       EXYNOS_PIN_BANK_EINTN(6, 0x1A0, "gpy0"),
+       EXYNOS_PIN_BANK_EINTN(4, 0x1C0, "gpy1"),
+       EXYNOS_PIN_BANK_EINTN(6, 0x1E0, "gpy2"),
+       EXYNOS_PIN_BANK_EINTN(8, 0x200, "gpy3"),
+       EXYNOS_PIN_BANK_EINTN(8, 0x220, "gpy4"),
+       EXYNOS_PIN_BANK_EINTN(8, 0x240, "gpy5"),
+       EXYNOS_PIN_BANK_EINTN(8, 0x260, "gpy6"),
+       EXYNOS_PIN_BANK_EINTW(8, 0xC00, "gpx0", 0x00),
+       EXYNOS_PIN_BANK_EINTW(8, 0xC20, "gpx1", 0x04),
+       EXYNOS_PIN_BANK_EINTW(8, 0xC40, "gpx2", 0x08),
+       EXYNOS_PIN_BANK_EINTW(8, 0xC60, "gpx3", 0x0c),
+};
+
+/* pin banks of exynos5250 pin-controller 1 */
+static struct samsung_pin_bank exynos5250_pin_banks1[] = {
+       EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpe0", 0x00),
+       EXYNOS_PIN_BANK_EINTG(2, 0x020, "gpe1", 0x04),
+       EXYNOS_PIN_BANK_EINTG(4, 0x040, "gpf0", 0x08),
+       EXYNOS_PIN_BANK_EINTG(4, 0x060, "gpf1", 0x0c),
+       EXYNOS_PIN_BANK_EINTG(8, 0x080, "gpg0", 0x10),
+       EXYNOS_PIN_BANK_EINTG(8, 0x0A0, "gpg1", 0x14),
+       EXYNOS_PIN_BANK_EINTG(2, 0x0C0, "gpg2", 0x18),
+       EXYNOS_PIN_BANK_EINTG(4, 0x0E0, "gph0", 0x1c),
+       EXYNOS_PIN_BANK_EINTG(8, 0x100, "gph1", 0x20),
+};
+
+/* pin banks of exynos5250 pin-controller 2 */
+static struct samsung_pin_bank exynos5250_pin_banks2[] = {
+       EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpv0", 0x00),
+       EXYNOS_PIN_BANK_EINTG(8, 0x020, "gpv1", 0x04),
+       EXYNOS_PIN_BANK_EINTG(8, 0x060, "gpv2", 0x08),
+       EXYNOS_PIN_BANK_EINTG(8, 0x080, "gpv3", 0x0c),
+       EXYNOS_PIN_BANK_EINTG(2, 0x0C0, "gpv4", 0x10),
+};
+
+/* pin banks of exynos5250 pin-controller 3 */
+static struct samsung_pin_bank exynos5250_pin_banks3[] = {
+       EXYNOS_PIN_BANK_EINTG(7, 0x000, "gpz", 0x00),
+};
+
+/*
+ * Samsung pinctrl driver data for Exynos5250 SoC. Exynos5250 SoC includes
+ * four gpio/pin-mux/pinconfig controllers.
+ */
+struct samsung_pin_ctrl exynos5250_pin_ctrl[] = {
+       {
+               /* pin-controller instance 0 data */
+               .pin_banks      = exynos5250_pin_banks0,
+               .nr_banks       = ARRAY_SIZE(exynos5250_pin_banks0),
+               .eint_gpio_init = exynos_eint_gpio_init,
+               .eint_wkup_init = exynos_eint_wkup_init,
+               .suspend        = exynos_pinctrl_suspend,
+               .resume         = exynos_pinctrl_resume,
+               .label          = "exynos5250-gpio-ctrl0",
+       }, {
+               /* pin-controller instance 1 data */
+               .pin_banks      = exynos5250_pin_banks1,
+               .nr_banks       = ARRAY_SIZE(exynos5250_pin_banks1),
+               .eint_gpio_init = exynos_eint_gpio_init,
+               .suspend        = exynos_pinctrl_suspend,
+               .resume         = exynos_pinctrl_resume,
+               .label          = "exynos5250-gpio-ctrl1",
+       }, {
+               /* pin-controller instance 2 data */
+               .pin_banks      = exynos5250_pin_banks2,
+               .nr_banks       = ARRAY_SIZE(exynos5250_pin_banks2),
+               .eint_gpio_init = exynos_eint_gpio_init,
+               .suspend        = exynos_pinctrl_suspend,
+               .resume         = exynos_pinctrl_resume,
+               .label          = "exynos5250-gpio-ctrl2",
+       }, {
+               /* pin-controller instance 3 data */
+               .pin_banks      = exynos5250_pin_banks3,
+               .nr_banks       = ARRAY_SIZE(exynos5250_pin_banks3),
+               .eint_gpio_init = exynos_eint_gpio_init,
+               .suspend        = exynos_pinctrl_suspend,
+               .resume         = exynos_pinctrl_resume,
+               .label          = "exynos5250-gpio-ctrl3",
+       },
+};
+
+/* pin banks of exynos5260 pin-controller 0 */
+static struct samsung_pin_bank exynos5260_pin_banks0[] = {
+       EXYNOS_PIN_BANK_EINTG(4, 0x000, "gpa0", 0x00),
+       EXYNOS_PIN_BANK_EINTG(7, 0x020, "gpa1", 0x04),
+       EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpa2", 0x08),
+       EXYNOS_PIN_BANK_EINTG(5, 0x060, "gpb0", 0x0c),
+       EXYNOS_PIN_BANK_EINTG(4, 0x080, "gpb1", 0x10),
+       EXYNOS_PIN_BANK_EINTG(5, 0x0a0, "gpb2", 0x14),
+       EXYNOS_PIN_BANK_EINTG(8, 0x0c0, "gpb3", 0x18),
+       EXYNOS_PIN_BANK_EINTG(8, 0x0e0, "gpb4", 0x1c),
+       EXYNOS_PIN_BANK_EINTG(8, 0x100, "gpb5", 0x20),
+       EXYNOS_PIN_BANK_EINTG(8, 0x120, "gpd0", 0x24),
+       EXYNOS_PIN_BANK_EINTG(7, 0x140, "gpd1", 0x28),
+       EXYNOS_PIN_BANK_EINTG(5, 0x160, "gpd2", 0x2c),
+       EXYNOS_PIN_BANK_EINTG(8, 0x180, "gpe0", 0x30),
+       EXYNOS_PIN_BANK_EINTG(5, 0x1a0, "gpe1", 0x34),
+       EXYNOS_PIN_BANK_EINTG(4, 0x1c0, "gpf0", 0x38),
+       EXYNOS_PIN_BANK_EINTG(8, 0x1e0, "gpf1", 0x3c),
+       EXYNOS_PIN_BANK_EINTG(2, 0x200, "gpk0", 0x40),
+       EXYNOS_PIN_BANK_EINTW(8, 0xc00, "gpx0", 0x00),
+       EXYNOS_PIN_BANK_EINTW(8, 0xc20, "gpx1", 0x04),
+       EXYNOS_PIN_BANK_EINTW(8, 0xc40, "gpx2", 0x08),
+       EXYNOS_PIN_BANK_EINTW(8, 0xc60, "gpx3", 0x0c),
+};
+
+/* pin banks of exynos5260 pin-controller 1 */
+static struct samsung_pin_bank exynos5260_pin_banks1[] = {
+       EXYNOS_PIN_BANK_EINTG(7, 0x000, "gpc0", 0x00),
+       EXYNOS_PIN_BANK_EINTG(6, 0x020, "gpc1", 0x04),
+       EXYNOS_PIN_BANK_EINTG(7, 0x040, "gpc2", 0x08),
+       EXYNOS_PIN_BANK_EINTG(4, 0x060, "gpc3", 0x0c),
+       EXYNOS_PIN_BANK_EINTG(4, 0x080, "gpc4", 0x10),
+};
+
+/* pin banks of exynos5260 pin-controller 2 */
+static struct samsung_pin_bank exynos5260_pin_banks2[] = {
+       EXYNOS_PIN_BANK_EINTG(7, 0x000, "gpz0", 0x00),
+       EXYNOS_PIN_BANK_EINTG(4, 0x020, "gpz1", 0x04),
+};
+
+/*
+ * Samsung pinctrl driver data for Exynos5260 SoC. Exynos5260 SoC includes
+ * three gpio/pin-mux/pinconfig controllers.
+ */
+struct samsung_pin_ctrl exynos5260_pin_ctrl[] = {
+       {
+               /* pin-controller instance 0 data */
+               .pin_banks      = exynos5260_pin_banks0,
+               .nr_banks       = ARRAY_SIZE(exynos5260_pin_banks0),
+               .eint_gpio_init = exynos_eint_gpio_init,
+               .eint_wkup_init = exynos_eint_wkup_init,
+               .label          = "exynos5260-gpio-ctrl0",
+       }, {
+               /* pin-controller instance 1 data */
+               .pin_banks      = exynos5260_pin_banks1,
+               .nr_banks       = ARRAY_SIZE(exynos5260_pin_banks1),
+               .eint_gpio_init = exynos_eint_gpio_init,
+               .label          = "exynos5260-gpio-ctrl1",
+       }, {
+               /* pin-controller instance 2 data */
+               .pin_banks      = exynos5260_pin_banks2,
+               .nr_banks       = ARRAY_SIZE(exynos5260_pin_banks2),
+               .eint_gpio_init = exynos_eint_gpio_init,
+               .label          = "exynos5260-gpio-ctrl2",
+       },
+};
+
+/* pin banks of exynos5420 pin-controller 0 */
+static struct samsung_pin_bank exynos5420_pin_banks0[] = {
+       EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpy7", 0x00),
+       EXYNOS_PIN_BANK_EINTW(8, 0xC00, "gpx0", 0x00),
+       EXYNOS_PIN_BANK_EINTW(8, 0xC20, "gpx1", 0x04),
+       EXYNOS_PIN_BANK_EINTW(8, 0xC40, "gpx2", 0x08),
+       EXYNOS_PIN_BANK_EINTW(8, 0xC60, "gpx3", 0x0c),
+};
+
+/* pin banks of exynos5420 pin-controller 1 */
+static struct samsung_pin_bank exynos5420_pin_banks1[] = {
+       EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpc0", 0x00),
+       EXYNOS_PIN_BANK_EINTG(8, 0x020, "gpc1", 0x04),
+       EXYNOS_PIN_BANK_EINTG(7, 0x040, "gpc2", 0x08),
+       EXYNOS_PIN_BANK_EINTG(4, 0x060, "gpc3", 0x0c),
+       EXYNOS_PIN_BANK_EINTG(2, 0x080, "gpc4", 0x10),
+       EXYNOS_PIN_BANK_EINTG(8, 0x0A0, "gpd1", 0x14),
+       EXYNOS_PIN_BANK_EINTN(6, 0x0C0, "gpy0"),
+       EXYNOS_PIN_BANK_EINTN(4, 0x0E0, "gpy1"),
+       EXYNOS_PIN_BANK_EINTN(6, 0x100, "gpy2"),
+       EXYNOS_PIN_BANK_EINTN(8, 0x120, "gpy3"),
+       EXYNOS_PIN_BANK_EINTN(8, 0x140, "gpy4"),
+       EXYNOS_PIN_BANK_EINTN(8, 0x160, "gpy5"),
+       EXYNOS_PIN_BANK_EINTN(8, 0x180, "gpy6"),
+};
+
+/* pin banks of exynos5420 pin-controller 2 */
+static struct samsung_pin_bank exynos5420_pin_banks2[] = {
+       EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpe0", 0x00),
+       EXYNOS_PIN_BANK_EINTG(2, 0x020, "gpe1", 0x04),
+       EXYNOS_PIN_BANK_EINTG(6, 0x040, "gpf0", 0x08),
+       EXYNOS_PIN_BANK_EINTG(8, 0x060, "gpf1", 0x0c),
+       EXYNOS_PIN_BANK_EINTG(8, 0x080, "gpg0", 0x10),
+       EXYNOS_PIN_BANK_EINTG(8, 0x0A0, "gpg1", 0x14),
+       EXYNOS_PIN_BANK_EINTG(2, 0x0C0, "gpg2", 0x18),
+       EXYNOS_PIN_BANK_EINTG(4, 0x0E0, "gpj4", 0x1c),
+};
+
+/* pin banks of exynos5420 pin-controller 3 */
+static struct samsung_pin_bank exynos5420_pin_banks3[] = {
+       EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00),
+       EXYNOS_PIN_BANK_EINTG(6, 0x020, "gpa1", 0x04),
+       EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpa2", 0x08),
+       EXYNOS_PIN_BANK_EINTG(5, 0x060, "gpb0", 0x0c),
+       EXYNOS_PIN_BANK_EINTG(5, 0x080, "gpb1", 0x10),
+       EXYNOS_PIN_BANK_EINTG(4, 0x0A0, "gpb2", 0x14),
+       EXYNOS_PIN_BANK_EINTG(8, 0x0C0, "gpb3", 0x18),
+       EXYNOS_PIN_BANK_EINTG(2, 0x0E0, "gpb4", 0x1c),
+       EXYNOS_PIN_BANK_EINTG(8, 0x100, "gph0", 0x20),
+};
+
+/* pin banks of exynos5420 pin-controller 4 */
+static struct samsung_pin_bank exynos5420_pin_banks4[] = {
+       EXYNOS_PIN_BANK_EINTG(7, 0x000, "gpz", 0x00),
+};
+
+/*
+ * Samsung pinctrl driver data for Exynos5420 SoC. Exynos5420 SoC includes
+ * four gpio/pin-mux/pinconfig controllers.
+ */
+struct samsung_pin_ctrl exynos5420_pin_ctrl[] = {
+       {
+               /* pin-controller instance 0 data */
+               .pin_banks      = exynos5420_pin_banks0,
+               .nr_banks       = ARRAY_SIZE(exynos5420_pin_banks0),
+               .eint_gpio_init = exynos_eint_gpio_init,
+               .eint_wkup_init = exynos_eint_wkup_init,
+               .label          = "exynos5420-gpio-ctrl0",
+       }, {
+               /* pin-controller instance 1 data */
+               .pin_banks      = exynos5420_pin_banks1,
+               .nr_banks       = ARRAY_SIZE(exynos5420_pin_banks1),
+               .eint_gpio_init = exynos_eint_gpio_init,
+               .label          = "exynos5420-gpio-ctrl1",
+       }, {
+               /* pin-controller instance 2 data */
+               .pin_banks      = exynos5420_pin_banks2,
+               .nr_banks       = ARRAY_SIZE(exynos5420_pin_banks2),
+               .eint_gpio_init = exynos_eint_gpio_init,
+               .label          = "exynos5420-gpio-ctrl2",
+       }, {
+               /* pin-controller instance 3 data */
+               .pin_banks      = exynos5420_pin_banks3,
+               .nr_banks       = ARRAY_SIZE(exynos5420_pin_banks3),
+               .eint_gpio_init = exynos_eint_gpio_init,
+               .label          = "exynos5420-gpio-ctrl3",
+       }, {
+               /* pin-controller instance 4 data */
+               .pin_banks      = exynos5420_pin_banks4,
+               .nr_banks       = ARRAY_SIZE(exynos5420_pin_banks4),
+               .eint_gpio_init = exynos_eint_gpio_init,
+               .label          = "exynos5420-gpio-ctrl4",
+       },
+};
diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.h b/drivers/pinctrl/samsung/pinctrl-exynos.h
new file mode 100644 (file)
index 0000000..3c91c35
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * Exynos specific definitions for Samsung pinctrl and gpiolib driver.
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ * Copyright (c) 2012 Linaro Ltd
+ *             http://www.linaro.org
+ *
+ * This file contains the Exynos specific definitions for the Samsung
+ * pinctrl/gpiolib interface drivers.
+ *
+ * Author: Thomas Abraham <thomas.ab@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+/* External GPIO and wakeup interrupt related definitions */
+#define EXYNOS_GPIO_ECON_OFFSET                0x700
+#define EXYNOS_GPIO_EFLTCON_OFFSET     0x800
+#define EXYNOS_GPIO_EMASK_OFFSET       0x900
+#define EXYNOS_GPIO_EPEND_OFFSET       0xA00
+#define EXYNOS_WKUP_ECON_OFFSET                0xE00
+#define EXYNOS_WKUP_EMASK_OFFSET       0xF00
+#define EXYNOS_WKUP_EPEND_OFFSET       0xF40
+#define EXYNOS_SVC_OFFSET              0xB08
+#define EXYNOS_EINT_FUNC               0xF
+
+/* helpers to access interrupt service register */
+#define EXYNOS_SVC_GROUP_SHIFT         3
+#define EXYNOS_SVC_GROUP_MASK          0x1f
+#define EXYNOS_SVC_NUM_MASK            7
+#define EXYNOS_SVC_GROUP(x)            ((x >> EXYNOS_SVC_GROUP_SHIFT) & \
+                                               EXYNOS_SVC_GROUP_MASK)
+
+/* Exynos specific external interrupt trigger types */
+#define EXYNOS_EINT_LEVEL_LOW          0
+#define EXYNOS_EINT_LEVEL_HIGH         1
+#define EXYNOS_EINT_EDGE_FALLING       2
+#define EXYNOS_EINT_EDGE_RISING                3
+#define EXYNOS_EINT_EDGE_BOTH          4
+#define EXYNOS_EINT_CON_MASK           0xF
+#define EXYNOS_EINT_CON_LEN            4
+
+#define EXYNOS_EINT_MAX_PER_BANK       8
+#define EXYNOS_EINT_NR_WKUP_EINT
+
+#define EXYNOS_PIN_BANK_EINTN(pins, reg, id)           \
+       {                                               \
+               .type           = &bank_type_off,       \
+               .pctl_offset    = reg,                  \
+               .nr_pins        = pins,                 \
+               .eint_type      = EINT_TYPE_NONE,       \
+               .name           = id                    \
+       }
+
+#define EXYNOS_PIN_BANK_EINTG(pins, reg, id, offs)     \
+       {                                               \
+               .type           = &bank_type_off,       \
+               .pctl_offset    = reg,                  \
+               .nr_pins        = pins,                 \
+               .eint_type      = EINT_TYPE_GPIO,       \
+               .eint_offset    = offs,                 \
+               .name           = id                    \
+       }
+
+#define EXYNOS_PIN_BANK_EINTW(pins, reg, id, offs)     \
+       {                                               \
+               .type           = &bank_type_alive,     \
+               .pctl_offset    = reg,                  \
+               .nr_pins        = pins,                 \
+               .eint_type      = EINT_TYPE_WKUP,       \
+               .eint_offset    = offs,                 \
+               .name           = id                    \
+       }
+
+/**
+ * struct exynos_weint_data: irq specific data for all the wakeup interrupts
+ * generated by the external wakeup interrupt controller.
+ * @irq: interrupt number within the domain.
+ * @bank: bank responsible for this interrupt
+ */
+struct exynos_weint_data {
+       unsigned int irq;
+       struct samsung_pin_bank *bank;
+};
+
+/**
+ * struct exynos_muxed_weint_data: irq specific data for muxed wakeup interrupts
+ * generated by the external wakeup interrupt controller.
+ * @nr_banks: count of banks being part of the mux
+ * @banks: array of banks being part of the mux
+ */
+struct exynos_muxed_weint_data {
+       unsigned int nr_banks;
+       struct samsung_pin_bank *banks[];
+};
diff --git a/drivers/pinctrl/samsung/pinctrl-exynos5440.c b/drivers/pinctrl/samsung/pinctrl-exynos5440.c
new file mode 100644 (file)
index 0000000..603da2f
--- /dev/null
@@ -0,0 +1,1061 @@
+/*
+ * pin-controller/pin-mux/pin-config/gpio-driver for Samsung's EXYNOS5440 SoC.
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/device.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/interrupt.h>
+#include <linux/irqdomain.h>
+#include <linux/of_irq.h>
+#include "../core.h"
+
+/* EXYNOS5440 GPIO and Pinctrl register offsets */
+#define GPIO_MUX               0x00
+#define GPIO_IE                        0x04
+#define GPIO_INT               0x08
+#define GPIO_TYPE              0x0C
+#define GPIO_VAL               0x10
+#define GPIO_OE                        0x14
+#define GPIO_IN                        0x18
+#define GPIO_PE                        0x1C
+#define GPIO_PS                        0x20
+#define GPIO_SR                        0x24
+#define GPIO_DS0               0x28
+#define GPIO_DS1               0x2C
+
+#define EXYNOS5440_MAX_PINS            23
+#define EXYNOS5440_MAX_GPIO_INT        8
+#define PIN_NAME_LENGTH                10
+
+#define GROUP_SUFFIX           "-grp"
+#define GSUFFIX_LEN            sizeof(GROUP_SUFFIX)
+#define FUNCTION_SUFFIX                "-mux"
+#define FSUFFIX_LEN            sizeof(FUNCTION_SUFFIX)
+
+/*
+ * pin configuration type and its value are packed together into a 16-bits.
+ * The upper 8-bits represent the configuration type and the lower 8-bits
+ * hold the value of the configuration type.
+ */
+#define PINCFG_TYPE_MASK               0xFF
+#define PINCFG_VALUE_SHIFT             8
+#define PINCFG_VALUE_MASK              (0xFF << PINCFG_VALUE_SHIFT)
+#define PINCFG_PACK(type, value)       (((value) << PINCFG_VALUE_SHIFT) | type)
+#define PINCFG_UNPACK_TYPE(cfg)                ((cfg) & PINCFG_TYPE_MASK)
+#define PINCFG_UNPACK_VALUE(cfg)       (((cfg) & PINCFG_VALUE_MASK) >> \
+                                               PINCFG_VALUE_SHIFT)
+
+/**
+ * enum pincfg_type - possible pin configuration types supported.
+ * @PINCFG_TYPE_PUD: Pull up/down configuration.
+ * @PINCFG_TYPE_DRV: Drive strength configuration.
+ * @PINCFG_TYPE_SKEW_RATE: Skew rate configuration.
+ * @PINCFG_TYPE_INPUT_TYPE: Pin input type configuration.
+ */
+enum pincfg_type {
+       PINCFG_TYPE_PUD,
+       PINCFG_TYPE_DRV,
+       PINCFG_TYPE_SKEW_RATE,
+       PINCFG_TYPE_INPUT_TYPE
+};
+
+/**
+ * struct exynos5440_pin_group: represent group of pins for pincfg setting.
+ * @name: name of the pin group, used to lookup the group.
+ * @pins: the pins included in this group.
+ * @num_pins: number of pins included in this group.
+ */
+struct exynos5440_pin_group {
+       const char              *name;
+       const unsigned int      *pins;
+       u8                      num_pins;
+};
+
+/**
+ * struct exynos5440_pmx_func: represent a pin function.
+ * @name: name of the pin function, used to lookup the function.
+ * @groups: one or more names of pin groups that provide this function.
+ * @num_groups: number of groups included in @groups.
+ * @function: the function number to be programmed when selected.
+ */
+struct exynos5440_pmx_func {
+       const char              *name;
+       const char              **groups;
+       u8                      num_groups;
+       unsigned long           function;
+};
+
+/**
+ * struct exynos5440_pinctrl_priv_data: driver's private runtime data.
+ * @reg_base: ioremapped based address of the register space.
+ * @gc: gpio chip registered with gpiolib.
+ * @pin_groups: list of pin groups parsed from device tree.
+ * @nr_groups: number of pin groups available.
+ * @pmx_functions: list of pin functions parsed from device tree.
+ * @nr_functions: number of pin functions available.
+ */
+struct exynos5440_pinctrl_priv_data {
+       void __iomem                    *reg_base;
+       struct gpio_chip                *gc;
+       struct irq_domain               *irq_domain;
+
+       const struct exynos5440_pin_group       *pin_groups;
+       unsigned int                    nr_groups;
+       const struct exynos5440_pmx_func        *pmx_functions;
+       unsigned int                    nr_functions;
+};
+
+/**
+ * struct exynos5440_gpio_intr_data: private data for gpio interrupts.
+ * @priv: driver's private runtime data.
+ * @gpio_int: gpio interrupt number.
+ */
+struct exynos5440_gpio_intr_data {
+       struct exynos5440_pinctrl_priv_data     *priv;
+       unsigned int                            gpio_int;
+};
+
+/* list of all possible config options supported */
+static struct pin_config {
+       char            *prop_cfg;
+       unsigned int    cfg_type;
+} pcfgs[] = {
+       { "samsung,exynos5440-pin-pud", PINCFG_TYPE_PUD },
+       { "samsung,exynos5440-pin-drv", PINCFG_TYPE_DRV },
+       { "samsung,exynos5440-pin-skew-rate", PINCFG_TYPE_SKEW_RATE },
+       { "samsung,exynos5440-pin-input-type", PINCFG_TYPE_INPUT_TYPE },
+};
+
+/* check if the selector is a valid pin group selector */
+static int exynos5440_get_group_count(struct pinctrl_dev *pctldev)
+{
+       struct exynos5440_pinctrl_priv_data *priv;
+
+       priv = pinctrl_dev_get_drvdata(pctldev);
+       return priv->nr_groups;
+}
+
+/* return the name of the group selected by the group selector */
+static const char *exynos5440_get_group_name(struct pinctrl_dev *pctldev,
+                                               unsigned selector)
+{
+       struct exynos5440_pinctrl_priv_data *priv;
+
+       priv = pinctrl_dev_get_drvdata(pctldev);
+       return priv->pin_groups[selector].name;
+}
+
+/* return the pin numbers associated with the specified group */
+static int exynos5440_get_group_pins(struct pinctrl_dev *pctldev,
+               unsigned selector, const unsigned **pins, unsigned *num_pins)
+{
+       struct exynos5440_pinctrl_priv_data *priv;
+
+       priv = pinctrl_dev_get_drvdata(pctldev);
+       *pins = priv->pin_groups[selector].pins;
+       *num_pins = priv->pin_groups[selector].num_pins;
+       return 0;
+}
+
+/* create pinctrl_map entries by parsing device tree nodes */
+static int exynos5440_dt_node_to_map(struct pinctrl_dev *pctldev,
+                       struct device_node *np, struct pinctrl_map **maps,
+                       unsigned *nmaps)
+{
+       struct device *dev = pctldev->dev;
+       struct pinctrl_map *map;
+       unsigned long *cfg = NULL;
+       char *gname, *fname;
+       int cfg_cnt = 0, map_cnt = 0, idx = 0;
+
+       /* count the number of config options specfied in the node */
+       for (idx = 0; idx < ARRAY_SIZE(pcfgs); idx++)
+               if (of_find_property(np, pcfgs[idx].prop_cfg, NULL))
+                       cfg_cnt++;
+
+       /*
+        * Find out the number of map entries to create. All the config options
+        * can be accomadated into a single config map entry.
+        */
+       if (cfg_cnt)
+               map_cnt = 1;
+       if (of_find_property(np, "samsung,exynos5440-pin-function", NULL))
+               map_cnt++;
+       if (!map_cnt) {
+               dev_err(dev, "node %s does not have either config or function "
+                               "configurations\n", np->name);
+               return -EINVAL;
+       }
+
+       /* Allocate memory for pin-map entries */
+       map = kzalloc(sizeof(*map) * map_cnt, GFP_KERNEL);
+       if (!map) {
+               dev_err(dev, "could not alloc memory for pin-maps\n");
+               return -ENOMEM;
+       }
+       *nmaps = 0;
+
+       /*
+        * Allocate memory for pin group name. The pin group name is derived
+        * from the node name from which these map entries are be created.
+        */
+       gname = kzalloc(strlen(np->name) + GSUFFIX_LEN, GFP_KERNEL);
+       if (!gname) {
+               dev_err(dev, "failed to alloc memory for group name\n");
+               goto free_map;
+       }
+       snprintf(gname, strlen(np->name) + 4, "%s%s", np->name, GROUP_SUFFIX);
+
+       /*
+        * don't have config options? then skip over to creating function
+        * map entries.
+        */
+       if (!cfg_cnt)
+               goto skip_cfgs;
+
+       /* Allocate memory for config entries */
+       cfg = kzalloc(sizeof(*cfg) * cfg_cnt, GFP_KERNEL);
+       if (!cfg) {
+               dev_err(dev, "failed to alloc memory for configs\n");
+               goto free_gname;
+       }
+
+       /* Prepare a list of config settings */
+       for (idx = 0, cfg_cnt = 0; idx < ARRAY_SIZE(pcfgs); idx++) {
+               u32 value;
+               if (!of_property_read_u32(np, pcfgs[idx].prop_cfg, &value))
+                       cfg[cfg_cnt++] =
+                               PINCFG_PACK(pcfgs[idx].cfg_type, value);
+       }
+
+       /* create the config map entry */
+       map[*nmaps].data.configs.group_or_pin = gname;
+       map[*nmaps].data.configs.configs = cfg;
+       map[*nmaps].data.configs.num_configs = cfg_cnt;
+       map[*nmaps].type = PIN_MAP_TYPE_CONFIGS_GROUP;
+       *nmaps += 1;
+
+skip_cfgs:
+       /* create the function map entry */
+       if (of_find_property(np, "samsung,exynos5440-pin-function", NULL)) {
+               fname = kzalloc(strlen(np->name) + FSUFFIX_LEN, GFP_KERNEL);
+               if (!fname) {
+                       dev_err(dev, "failed to alloc memory for func name\n");
+                       goto free_cfg;
+               }
+               snprintf(fname, strlen(np->name) + 4, "%s%s", np->name,
+                        FUNCTION_SUFFIX);
+
+               map[*nmaps].data.mux.group = gname;
+               map[*nmaps].data.mux.function = fname;
+               map[*nmaps].type = PIN_MAP_TYPE_MUX_GROUP;
+               *nmaps += 1;
+       }
+
+       *maps = map;
+       return 0;
+
+free_cfg:
+       kfree(cfg);
+free_gname:
+       kfree(gname);
+free_map:
+       kfree(map);
+       return -ENOMEM;
+}
+
+/* free the memory allocated to hold the pin-map table */
+static void exynos5440_dt_free_map(struct pinctrl_dev *pctldev,
+                            struct pinctrl_map *map, unsigned num_maps)
+{
+       int idx;
+
+       for (idx = 0; idx < num_maps; idx++) {
+               if (map[idx].type == PIN_MAP_TYPE_MUX_GROUP) {
+                       kfree(map[idx].data.mux.function);
+                       if (!idx)
+                               kfree(map[idx].data.mux.group);
+               } else if (map->type == PIN_MAP_TYPE_CONFIGS_GROUP) {
+                       kfree(map[idx].data.configs.configs);
+                       if (!idx)
+                               kfree(map[idx].data.configs.group_or_pin);
+               }
+       };
+
+       kfree(map);
+}
+
+/* list of pinctrl callbacks for the pinctrl core */
+static const struct pinctrl_ops exynos5440_pctrl_ops = {
+       .get_groups_count       = exynos5440_get_group_count,
+       .get_group_name         = exynos5440_get_group_name,
+       .get_group_pins         = exynos5440_get_group_pins,
+       .dt_node_to_map         = exynos5440_dt_node_to_map,
+       .dt_free_map            = exynos5440_dt_free_map,
+};
+
+/* check if the selector is a valid pin function selector */
+static int exynos5440_get_functions_count(struct pinctrl_dev *pctldev)
+{
+       struct exynos5440_pinctrl_priv_data *priv;
+
+       priv = pinctrl_dev_get_drvdata(pctldev);
+       return priv->nr_functions;
+}
+
+/* return the name of the pin function specified */
+static const char *exynos5440_pinmux_get_fname(struct pinctrl_dev *pctldev,
+                                               unsigned selector)
+{
+       struct exynos5440_pinctrl_priv_data *priv;
+
+       priv = pinctrl_dev_get_drvdata(pctldev);
+       return priv->pmx_functions[selector].name;
+}
+
+/* return the groups associated for the specified function selector */
+static int exynos5440_pinmux_get_groups(struct pinctrl_dev *pctldev,
+               unsigned selector, const char * const **groups,
+               unsigned * const num_groups)
+{
+       struct exynos5440_pinctrl_priv_data *priv;
+
+       priv = pinctrl_dev_get_drvdata(pctldev);
+       *groups = priv->pmx_functions[selector].groups;
+       *num_groups = priv->pmx_functions[selector].num_groups;
+       return 0;
+}
+
+/* enable or disable a pinmux function */
+static void exynos5440_pinmux_setup(struct pinctrl_dev *pctldev, unsigned selector,
+                                       unsigned group, bool enable)
+{
+       struct exynos5440_pinctrl_priv_data *priv;
+       void __iomem *base;
+       u32 function;
+       u32 data;
+
+       priv = pinctrl_dev_get_drvdata(pctldev);
+       base = priv->reg_base;
+       function = priv->pmx_functions[selector].function;
+
+       data = readl(base + GPIO_MUX);
+       if (enable)
+               data |= (1 << function);
+       else
+               data &= ~(1 << function);
+       writel(data, base + GPIO_MUX);
+}
+
+/* enable a specified pinmux by writing to registers */
+static int exynos5440_pinmux_enable(struct pinctrl_dev *pctldev, unsigned selector,
+                                       unsigned group)
+{
+       exynos5440_pinmux_setup(pctldev, selector, group, true);
+       return 0;
+}
+
+/*
+ * The calls to gpio_direction_output() and gpio_direction_input()
+ * leads to this function call (via the pinctrl_gpio_direction_{input|output}()
+ * function called from the gpiolib interface).
+ */
+static int exynos5440_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev,
+               struct pinctrl_gpio_range *range, unsigned offset, bool input)
+{
+       return 0;
+}
+
+/* list of pinmux callbacks for the pinmux vertical in pinctrl core */
+static const struct pinmux_ops exynos5440_pinmux_ops = {
+       .get_functions_count    = exynos5440_get_functions_count,
+       .get_function_name      = exynos5440_pinmux_get_fname,
+       .get_function_groups    = exynos5440_pinmux_get_groups,
+       .enable                 = exynos5440_pinmux_enable,
+       .gpio_set_direction     = exynos5440_pinmux_gpio_set_direction,
+};
+
+/* set the pin config settings for a specified pin */
+static int exynos5440_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
+                               unsigned long *configs,
+                               unsigned num_configs)
+{
+       struct exynos5440_pinctrl_priv_data *priv;
+       void __iomem *base;
+       enum pincfg_type cfg_type;
+       u32 cfg_value;
+       u32 data;
+       int i;
+
+       priv = pinctrl_dev_get_drvdata(pctldev);
+       base = priv->reg_base;
+
+       for (i = 0; i < num_configs; i++) {
+               cfg_type = PINCFG_UNPACK_TYPE(configs[i]);
+               cfg_value = PINCFG_UNPACK_VALUE(configs[i]);
+
+               switch (cfg_type) {
+               case PINCFG_TYPE_PUD:
+                       /* first set pull enable/disable bit */
+                       data = readl(base + GPIO_PE);
+                       data &= ~(1 << pin);
+                       if (cfg_value)
+                               data |= (1 << pin);
+                       writel(data, base + GPIO_PE);
+
+                       /* then set pull up/down bit */
+                       data = readl(base + GPIO_PS);
+                       data &= ~(1 << pin);
+                       if (cfg_value == 2)
+                               data |= (1 << pin);
+                       writel(data, base + GPIO_PS);
+                       break;
+
+               case PINCFG_TYPE_DRV:
+                       /* set the first bit of the drive strength */
+                       data = readl(base + GPIO_DS0);
+                       data &= ~(1 << pin);
+                       data |= ((cfg_value & 1) << pin);
+                       writel(data, base + GPIO_DS0);
+                       cfg_value >>= 1;
+
+                       /* set the second bit of the driver strength */
+                       data = readl(base + GPIO_DS1);
+                       data &= ~(1 << pin);
+                       data |= ((cfg_value & 1) << pin);
+                       writel(data, base + GPIO_DS1);
+                       break;
+               case PINCFG_TYPE_SKEW_RATE:
+                       data = readl(base + GPIO_SR);
+                       data &= ~(1 << pin);
+                       data |= ((cfg_value & 1) << pin);
+                       writel(data, base + GPIO_SR);
+                       break;
+               case PINCFG_TYPE_INPUT_TYPE:
+                       data = readl(base + GPIO_TYPE);
+                       data &= ~(1 << pin);
+                       data |= ((cfg_value & 1) << pin);
+                       writel(data, base + GPIO_TYPE);
+                       break;
+               default:
+                       WARN_ON(1);
+                       return -EINVAL;
+               }
+       } /* for each config */
+
+       return 0;
+}
+
+/* get the pin config settings for a specified pin */
+static int exynos5440_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
+                                       unsigned long *config)
+{
+       struct exynos5440_pinctrl_priv_data *priv;
+       void __iomem *base;
+       enum pincfg_type cfg_type = PINCFG_UNPACK_TYPE(*config);
+       u32 data;
+
+       priv = pinctrl_dev_get_drvdata(pctldev);
+       base = priv->reg_base;
+
+       switch (cfg_type) {
+       case PINCFG_TYPE_PUD:
+               data = readl(base + GPIO_PE);
+               data = (data >> pin) & 1;
+               if (!data)
+                       *config = 0;
+               else
+                       *config = ((readl(base + GPIO_PS) >> pin) & 1) + 1;
+               break;
+       case PINCFG_TYPE_DRV:
+               data = readl(base + GPIO_DS0);
+               data = (data >> pin) & 1;
+               *config = data;
+               data = readl(base + GPIO_DS1);
+               data = (data >> pin) & 1;
+               *config |= (data << 1);
+               break;
+       case PINCFG_TYPE_SKEW_RATE:
+               data = readl(base + GPIO_SR);
+               *config = (data >> pin) & 1;
+               break;
+       case PINCFG_TYPE_INPUT_TYPE:
+               data = readl(base + GPIO_TYPE);
+               *config = (data >> pin) & 1;
+               break;
+       default:
+               WARN_ON(1);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+/* set the pin config settings for a specified pin group */
+static int exynos5440_pinconf_group_set(struct pinctrl_dev *pctldev,
+                       unsigned group, unsigned long *configs,
+                       unsigned num_configs)
+{
+       struct exynos5440_pinctrl_priv_data *priv;
+       const unsigned int *pins;
+       unsigned int cnt;
+
+       priv = pinctrl_dev_get_drvdata(pctldev);
+       pins = priv->pin_groups[group].pins;
+
+       for (cnt = 0; cnt < priv->pin_groups[group].num_pins; cnt++)
+               exynos5440_pinconf_set(pctldev, pins[cnt], configs,
+                                      num_configs);
+
+       return 0;
+}
+
+/* get the pin config settings for a specified pin group */
+static int exynos5440_pinconf_group_get(struct pinctrl_dev *pctldev,
+                               unsigned int group, unsigned long *config)
+{
+       struct exynos5440_pinctrl_priv_data *priv;
+       const unsigned int *pins;
+
+       priv = pinctrl_dev_get_drvdata(pctldev);
+       pins = priv->pin_groups[group].pins;
+       exynos5440_pinconf_get(pctldev, pins[0], config);
+       return 0;
+}
+
+/* list of pinconfig callbacks for pinconfig vertical in the pinctrl code */
+static const struct pinconf_ops exynos5440_pinconf_ops = {
+       .pin_config_get         = exynos5440_pinconf_get,
+       .pin_config_set         = exynos5440_pinconf_set,
+       .pin_config_group_get   = exynos5440_pinconf_group_get,
+       .pin_config_group_set   = exynos5440_pinconf_group_set,
+};
+
+/* gpiolib gpio_set callback function */
+static void exynos5440_gpio_set(struct gpio_chip *gc, unsigned offset, int value)
+{
+       struct exynos5440_pinctrl_priv_data *priv = dev_get_drvdata(gc->dev);
+       void __iomem *base = priv->reg_base;
+       u32 data;
+
+       data = readl(base + GPIO_VAL);
+       data &= ~(1 << offset);
+       if (value)
+               data |= 1 << offset;
+       writel(data, base + GPIO_VAL);
+}
+
+/* gpiolib gpio_get callback function */
+static int exynos5440_gpio_get(struct gpio_chip *gc, unsigned offset)
+{
+       struct exynos5440_pinctrl_priv_data *priv = dev_get_drvdata(gc->dev);
+       void __iomem *base = priv->reg_base;
+       u32 data;
+
+       data = readl(base + GPIO_IN);
+       data >>= offset;
+       data &= 1;
+       return data;
+}
+
+/* gpiolib gpio_direction_input callback function */
+static int exynos5440_gpio_direction_input(struct gpio_chip *gc, unsigned offset)
+{
+       struct exynos5440_pinctrl_priv_data *priv = dev_get_drvdata(gc->dev);
+       void __iomem *base = priv->reg_base;
+       u32 data;
+
+       /* first disable the data output enable on this pin */
+       data = readl(base + GPIO_OE);
+       data &= ~(1 << offset);
+       writel(data, base + GPIO_OE);
+
+       /* now enable input on this pin */
+       data =  readl(base + GPIO_IE);
+       data |= 1 << offset;
+       writel(data, base + GPIO_IE);
+       return 0;
+}
+
+/* gpiolib gpio_direction_output callback function */
+static int exynos5440_gpio_direction_output(struct gpio_chip *gc, unsigned offset,
+                                                       int value)
+{
+       struct exynos5440_pinctrl_priv_data *priv = dev_get_drvdata(gc->dev);
+       void __iomem *base = priv->reg_base;
+       u32 data;
+
+       exynos5440_gpio_set(gc, offset, value);
+
+       /* first disable the data input enable on this pin */
+       data = readl(base + GPIO_IE);
+       data &= ~(1 << offset);
+       writel(data, base + GPIO_IE);
+
+       /* now enable output on this pin */
+       data =  readl(base + GPIO_OE);
+       data |= 1 << offset;
+       writel(data, base + GPIO_OE);
+       return 0;
+}
+
+/* gpiolib gpio_to_irq callback function */
+static int exynos5440_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
+{
+       struct exynos5440_pinctrl_priv_data *priv = dev_get_drvdata(gc->dev);
+       unsigned int virq;
+
+       if (offset < 16 || offset > 23)
+               return -ENXIO;
+
+       if (!priv->irq_domain)
+               return -ENXIO;
+
+       virq = irq_create_mapping(priv->irq_domain, offset - 16);
+       return virq ? : -ENXIO;
+}
+
+/* parse the pin numbers listed in the 'samsung,exynos5440-pins' property */
+static int exynos5440_pinctrl_parse_dt_pins(struct platform_device *pdev,
+                       struct device_node *cfg_np, unsigned int **pin_list,
+                       unsigned int *npins)
+{
+       struct device *dev = &pdev->dev;
+       struct property *prop;
+
+       prop = of_find_property(cfg_np, "samsung,exynos5440-pins", NULL);
+       if (!prop)
+               return -ENOENT;
+
+       *npins = prop->length / sizeof(unsigned long);
+       if (!*npins) {
+               dev_err(dev, "invalid pin list in %s node", cfg_np->name);
+               return -EINVAL;
+       }
+
+       *pin_list = devm_kzalloc(dev, *npins * sizeof(**pin_list), GFP_KERNEL);
+       if (!*pin_list) {
+               dev_err(dev, "failed to allocate memory for pin list\n");
+               return -ENOMEM;
+       }
+
+       return of_property_read_u32_array(cfg_np, "samsung,exynos5440-pins",
+                       *pin_list, *npins);
+}
+
+/*
+ * Parse the information about all the available pin groups and pin functions
+ * from device node of the pin-controller.
+ */
+static int exynos5440_pinctrl_parse_dt(struct platform_device *pdev,
+                               struct exynos5440_pinctrl_priv_data *priv)
+{
+       struct device *dev = &pdev->dev;
+       struct device_node *dev_np = dev->of_node;
+       struct device_node *cfg_np;
+       struct exynos5440_pin_group *groups, *grp;
+       struct exynos5440_pmx_func *functions, *func;
+       unsigned *pin_list;
+       unsigned int npins, grp_cnt, func_idx = 0;
+       char *gname, *fname;
+       int ret;
+
+       grp_cnt = of_get_child_count(dev_np);
+       if (!grp_cnt)
+               return -EINVAL;
+
+       groups = devm_kzalloc(dev, grp_cnt * sizeof(*groups), GFP_KERNEL);
+       if (!groups) {
+               dev_err(dev, "failed allocate memory for ping group list\n");
+               return -EINVAL;
+       }
+       grp = groups;
+
+       functions = devm_kzalloc(dev, grp_cnt * sizeof(*functions), GFP_KERNEL);
+       if (!functions) {
+               dev_err(dev, "failed to allocate memory for function list\n");
+               return -EINVAL;
+       }
+       func = functions;
+
+       /*
+        * Iterate over all the child nodes of the pin controller node
+        * and create pin groups and pin function lists.
+        */
+       for_each_child_of_node(dev_np, cfg_np) {
+               u32 function;
+
+               ret = exynos5440_pinctrl_parse_dt_pins(pdev, cfg_np,
+                                       &pin_list, &npins);
+               if (ret) {
+                       gname = NULL;
+                       goto skip_to_pin_function;
+               }
+
+               /* derive pin group name from the node name */
+               gname = devm_kzalloc(dev, strlen(cfg_np->name) + GSUFFIX_LEN,
+                                       GFP_KERNEL);
+               if (!gname) {
+                       dev_err(dev, "failed to alloc memory for group name\n");
+                       return -ENOMEM;
+               }
+               snprintf(gname, strlen(cfg_np->name) + 4, "%s%s", cfg_np->name,
+                        GROUP_SUFFIX);
+
+               grp->name = gname;
+               grp->pins = pin_list;
+               grp->num_pins = npins;
+               grp++;
+
+skip_to_pin_function:
+               ret = of_property_read_u32(cfg_np, "samsung,exynos5440-pin-function",
+                                               &function);
+               if (ret)
+                       continue;
+
+               /* derive function name from the node name */
+               fname = devm_kzalloc(dev, strlen(cfg_np->name) + FSUFFIX_LEN,
+                                       GFP_KERNEL);
+               if (!fname) {
+                       dev_err(dev, "failed to alloc memory for func name\n");
+                       return -ENOMEM;
+               }
+               snprintf(fname, strlen(cfg_np->name) + 4, "%s%s", cfg_np->name,
+                        FUNCTION_SUFFIX);
+
+               func->name = fname;
+               func->groups = devm_kzalloc(dev, sizeof(char *), GFP_KERNEL);
+               if (!func->groups) {
+                       dev_err(dev, "failed to alloc memory for group list "
+                                       "in pin function");
+                       return -ENOMEM;
+               }
+               func->groups[0] = gname;
+               func->num_groups = gname ? 1 : 0;
+               func->function = function;
+               func++;
+               func_idx++;
+       }
+
+       priv->pin_groups = groups;
+       priv->nr_groups = grp_cnt;
+       priv->pmx_functions = functions;
+       priv->nr_functions = func_idx;
+       return 0;
+}
+
+/* register the pinctrl interface with the pinctrl subsystem */
+static int exynos5440_pinctrl_register(struct platform_device *pdev,
+                               struct exynos5440_pinctrl_priv_data *priv)
+{
+       struct device *dev = &pdev->dev;
+       struct pinctrl_desc *ctrldesc;
+       struct pinctrl_dev *pctl_dev;
+       struct pinctrl_pin_desc *pindesc, *pdesc;
+       struct pinctrl_gpio_range grange;
+       char *pin_names;
+       int pin, ret;
+
+       ctrldesc = devm_kzalloc(dev, sizeof(*ctrldesc), GFP_KERNEL);
+       if (!ctrldesc) {
+               dev_err(dev, "could not allocate memory for pinctrl desc\n");
+               return -ENOMEM;
+       }
+
+       ctrldesc->name = "exynos5440-pinctrl";
+       ctrldesc->owner = THIS_MODULE;
+       ctrldesc->pctlops = &exynos5440_pctrl_ops;
+       ctrldesc->pmxops = &exynos5440_pinmux_ops;
+       ctrldesc->confops = &exynos5440_pinconf_ops;
+
+       pindesc = devm_kzalloc(&pdev->dev, sizeof(*pindesc) *
+                               EXYNOS5440_MAX_PINS, GFP_KERNEL);
+       if (!pindesc) {
+               dev_err(&pdev->dev, "mem alloc for pin descriptors failed\n");
+               return -ENOMEM;
+       }
+       ctrldesc->pins = pindesc;
+       ctrldesc->npins = EXYNOS5440_MAX_PINS;
+
+       /* dynamically populate the pin number and pin name for pindesc */
+       for (pin = 0, pdesc = pindesc; pin < ctrldesc->npins; pin++, pdesc++)
+               pdesc->number = pin;
+
+       /*
+        * allocate space for storing the dynamically generated names for all
+        * the pins which belong to this pin-controller.
+        */
+       pin_names = devm_kzalloc(&pdev->dev, sizeof(char) * PIN_NAME_LENGTH *
+                                       ctrldesc->npins, GFP_KERNEL);
+       if (!pin_names) {
+               dev_err(&pdev->dev, "mem alloc for pin names failed\n");
+               return -ENOMEM;
+       }
+
+       /* for each pin, set the name of the pin */
+       for (pin = 0; pin < ctrldesc->npins; pin++) {
+               snprintf(pin_names, 6, "gpio%02d", pin);
+               pdesc = pindesc + pin;
+               pdesc->name = pin_names;
+               pin_names += PIN_NAME_LENGTH;
+       }
+
+       ret = exynos5440_pinctrl_parse_dt(pdev, priv);
+       if (ret)
+               return ret;
+
+       pctl_dev = pinctrl_register(ctrldesc, &pdev->dev, priv);
+       if (!pctl_dev) {
+               dev_err(&pdev->dev, "could not register pinctrl driver\n");
+               return -EINVAL;
+       }
+
+       grange.name = "exynos5440-pctrl-gpio-range";
+       grange.id = 0;
+       grange.base = 0;
+       grange.npins = EXYNOS5440_MAX_PINS;
+       grange.gc = priv->gc;
+       pinctrl_add_gpio_range(pctl_dev, &grange);
+       return 0;
+}
+
+/* register the gpiolib interface with the gpiolib subsystem */
+static int exynos5440_gpiolib_register(struct platform_device *pdev,
+                               struct exynos5440_pinctrl_priv_data *priv)
+{
+       struct gpio_chip *gc;
+       int ret;
+
+       gc = devm_kzalloc(&pdev->dev, sizeof(*gc), GFP_KERNEL);
+       if (!gc) {
+               dev_err(&pdev->dev, "mem alloc for gpio_chip failed\n");
+               return -ENOMEM;
+       }
+
+       priv->gc = gc;
+       gc->base = 0;
+       gc->ngpio = EXYNOS5440_MAX_PINS;
+       gc->dev = &pdev->dev;
+       gc->set = exynos5440_gpio_set;
+       gc->get = exynos5440_gpio_get;
+       gc->direction_input = exynos5440_gpio_direction_input;
+       gc->direction_output = exynos5440_gpio_direction_output;
+       gc->to_irq = exynos5440_gpio_to_irq;
+       gc->label = "gpiolib-exynos5440";
+       gc->owner = THIS_MODULE;
+       ret = gpiochip_add(gc);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to register gpio_chip %s, error "
+                                       "code: %d\n", gc->label, ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+/* unregister the gpiolib interface with the gpiolib subsystem */
+static int exynos5440_gpiolib_unregister(struct platform_device *pdev,
+                               struct exynos5440_pinctrl_priv_data *priv)
+{
+       int ret = gpiochip_remove(priv->gc);
+       if (ret) {
+               dev_err(&pdev->dev, "gpio chip remove failed\n");
+               return ret;
+       }
+       return 0;
+}
+
+static void exynos5440_gpio_irq_unmask(struct irq_data *irqd)
+{
+       struct exynos5440_pinctrl_priv_data *d;
+       unsigned long gpio_int;
+
+       d = irq_data_get_irq_chip_data(irqd);
+       gpio_int = readl(d->reg_base + GPIO_INT);
+       gpio_int |= 1 << irqd->hwirq;
+       writel(gpio_int, d->reg_base + GPIO_INT);
+}
+
+static void exynos5440_gpio_irq_mask(struct irq_data *irqd)
+{
+       struct exynos5440_pinctrl_priv_data *d;
+       unsigned long gpio_int;
+
+       d = irq_data_get_irq_chip_data(irqd);
+       gpio_int = readl(d->reg_base + GPIO_INT);
+       gpio_int &= ~(1 << irqd->hwirq);
+       writel(gpio_int, d->reg_base + GPIO_INT);
+}
+
+/* irq_chip for gpio interrupts */
+static struct irq_chip exynos5440_gpio_irq_chip = {
+       .name           = "exynos5440_gpio_irq_chip",
+       .irq_unmask     = exynos5440_gpio_irq_unmask,
+       .irq_mask       = exynos5440_gpio_irq_mask,
+};
+
+/* interrupt handler for GPIO interrupts 0..7 */
+static irqreturn_t exynos5440_gpio_irq(int irq, void *data)
+{
+       struct exynos5440_gpio_intr_data *intd = data;
+       struct exynos5440_pinctrl_priv_data *d = intd->priv;
+       int virq;
+
+       virq = irq_linear_revmap(d->irq_domain, intd->gpio_int);
+       if (!virq)
+               return IRQ_NONE;
+       generic_handle_irq(virq);
+       return IRQ_HANDLED;
+}
+
+static int exynos5440_gpio_irq_map(struct irq_domain *h, unsigned int virq,
+                                       irq_hw_number_t hw)
+{
+       struct exynos5440_pinctrl_priv_data *d = h->host_data;
+
+       irq_set_chip_data(virq, d);
+       irq_set_chip_and_handler(virq, &exynos5440_gpio_irq_chip,
+                                       handle_level_irq);
+       set_irq_flags(virq, IRQF_VALID);
+       return 0;
+}
+
+/* irq domain callbacks for gpio interrupt controller */
+static const struct irq_domain_ops exynos5440_gpio_irqd_ops = {
+       .map    = exynos5440_gpio_irq_map,
+       .xlate  = irq_domain_xlate_twocell,
+};
+
+/* setup handling of gpio interrupts */
+static int exynos5440_gpio_irq_init(struct platform_device *pdev,
+                               struct exynos5440_pinctrl_priv_data *priv)
+{
+       struct device *dev = &pdev->dev;
+       struct exynos5440_gpio_intr_data *intd;
+       int i, irq, ret;
+
+       intd = devm_kzalloc(dev, sizeof(*intd) * EXYNOS5440_MAX_GPIO_INT,
+                                       GFP_KERNEL);
+       if (!intd) {
+               dev_err(dev, "failed to allocate memory for gpio intr data\n");
+               return -ENOMEM;
+       }
+
+       for (i = 0; i < EXYNOS5440_MAX_GPIO_INT; i++) {
+               irq = irq_of_parse_and_map(dev->of_node, i);
+               if (irq <= 0) {
+                       dev_err(dev, "irq parsing failed\n");
+                       return -EINVAL;
+               }
+
+               intd->gpio_int = i;
+               intd->priv = priv;
+               ret = devm_request_irq(dev, irq, exynos5440_gpio_irq,
+                                       0, dev_name(dev), intd++);
+               if (ret) {
+                       dev_err(dev, "irq request failed\n");
+                       return -ENXIO;
+               }
+       }
+
+       priv->irq_domain = irq_domain_add_linear(dev->of_node,
+                               EXYNOS5440_MAX_GPIO_INT,
+                               &exynos5440_gpio_irqd_ops, priv);
+       if (!priv->irq_domain) {
+               dev_err(dev, "failed to create irq domain\n");
+               return -ENXIO;
+       }
+
+       return 0;
+}
+
+static int exynos5440_pinctrl_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct exynos5440_pinctrl_priv_data *priv;
+       struct resource *res;
+       int ret;
+
+       if (!dev->of_node) {
+               dev_err(dev, "device tree node not found\n");
+               return -ENODEV;
+       }
+
+       priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+       if (!priv) {
+               dev_err(dev, "could not allocate memory for private data\n");
+               return -ENOMEM;
+       }
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       priv->reg_base = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(priv->reg_base))
+               return PTR_ERR(priv->reg_base);
+
+       ret = exynos5440_gpiolib_register(pdev, priv);
+       if (ret)
+               return ret;
+
+       ret = exynos5440_pinctrl_register(pdev, priv);
+       if (ret) {
+               exynos5440_gpiolib_unregister(pdev, priv);
+               return ret;
+       }
+
+       ret = exynos5440_gpio_irq_init(pdev, priv);
+       if (ret) {
+               dev_err(dev, "failed to setup gpio interrupts\n");
+               return ret;
+       }
+
+       platform_set_drvdata(pdev, priv);
+       dev_info(dev, "EXYNOS5440 pinctrl driver registered\n");
+       return 0;
+}
+
+static const struct of_device_id exynos5440_pinctrl_dt_match[] = {
+       { .compatible = "samsung,exynos5440-pinctrl" },
+       {},
+};
+MODULE_DEVICE_TABLE(of, exynos5440_pinctrl_dt_match);
+
+static struct platform_driver exynos5440_pinctrl_driver = {
+       .probe          = exynos5440_pinctrl_probe,
+       .driver = {
+               .name   = "exynos5440-pinctrl",
+               .owner  = THIS_MODULE,
+               .of_match_table = exynos5440_pinctrl_dt_match,
+       },
+};
+
+static int __init exynos5440_pinctrl_drv_register(void)
+{
+       return platform_driver_register(&exynos5440_pinctrl_driver);
+}
+postcore_initcall(exynos5440_pinctrl_drv_register);
+
+static void __exit exynos5440_pinctrl_drv_unregister(void)
+{
+       platform_driver_unregister(&exynos5440_pinctrl_driver);
+}
+module_exit(exynos5440_pinctrl_drv_unregister);
+
+MODULE_AUTHOR("Thomas Abraham <thomas.ab@samsung.com>");
+MODULE_DESCRIPTION("Samsung EXYNOS5440 SoC pinctrl driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/pinctrl/samsung/pinctrl-s3c24xx.c b/drivers/pinctrl/samsung/pinctrl-s3c24xx.c
new file mode 100644 (file)
index 0000000..ad3eaad
--- /dev/null
@@ -0,0 +1,651 @@
+/*
+ * S3C24XX specific support for Samsung pinctrl/gpiolib driver.
+ *
+ * Copyright (c) 2013 Heiko Stuebner <heiko@sntech.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This file contains the SamsungS3C24XX specific information required by the
+ * Samsung pinctrl/gpiolib driver. It also includes the implementation of
+ * external gpio and wakeup interrupt support.
+ */
+
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/irqdomain.h>
+#include <linux/irq.h>
+#include <linux/of_irq.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+
+#include "pinctrl-samsung.h"
+
+#define NUM_EINT       24
+#define NUM_EINT_IRQ   6
+#define EINT_MAX_PER_GROUP     8
+
+#define EINTPEND_REG   0xa8
+#define EINTMASK_REG   0xa4
+
+#define EINT_GROUP(i)          ((int)((i) / EINT_MAX_PER_GROUP))
+#define EINT_REG(i)            ((EINT_GROUP(i) * 4) + 0x88)
+#define EINT_OFFS(i)           ((i) % EINT_MAX_PER_GROUP * 4)
+
+#define EINT_LEVEL_LOW         0
+#define EINT_LEVEL_HIGH                1
+#define EINT_EDGE_FALLING      2
+#define EINT_EDGE_RISING       4
+#define EINT_EDGE_BOTH         6
+#define EINT_MASK              0xf
+
+static struct samsung_pin_bank_type bank_type_1bit = {
+       .fld_width = { 1, 1, },
+       .reg_offset = { 0x00, 0x04, },
+};
+
+static struct samsung_pin_bank_type bank_type_2bit = {
+       .fld_width = { 2, 1, 2, },
+       .reg_offset = { 0x00, 0x04, 0x08, },
+};
+
+#define PIN_BANK_A(pins, reg, id)              \
+       {                                               \
+               .type           = &bank_type_1bit,      \
+               .pctl_offset    = reg,                  \
+               .nr_pins        = pins,                 \
+               .eint_type      = EINT_TYPE_NONE,       \
+               .name           = id                    \
+       }
+
+#define PIN_BANK_2BIT(pins, reg, id)           \
+       {                                               \
+               .type           = &bank_type_2bit,      \
+               .pctl_offset    = reg,                  \
+               .nr_pins        = pins,                 \
+               .eint_type      = EINT_TYPE_NONE,       \
+               .name           = id                    \
+       }
+
+#define PIN_BANK_2BIT_EINTW(pins, reg, id, eoffs, emask)\
+       {                                               \
+               .type           = &bank_type_2bit,      \
+               .pctl_offset    = reg,                  \
+               .nr_pins        = pins,                 \
+               .eint_type      = EINT_TYPE_WKUP,       \
+               .eint_func      = 2,                    \
+               .eint_mask      = emask,                \
+               .eint_offset    = eoffs,                \
+               .name           = id                    \
+       }
+
+/**
+ * struct s3c24xx_eint_data: EINT common data
+ * @drvdata: pin controller driver data
+ * @domains: IRQ domains of particular EINT interrupts
+ * @parents: mapped parent irqs in the main interrupt controller
+ */
+struct s3c24xx_eint_data {
+       struct samsung_pinctrl_drv_data *drvdata;
+       struct irq_domain *domains[NUM_EINT];
+       int parents[NUM_EINT_IRQ];
+};
+
+/**
+ * struct s3c24xx_eint_domain_data: per irq-domain data
+ * @bank: pin bank related to the domain
+ * @eint_data: common data
+ * eint0_3_parent_only: live eints 0-3 only in the main intc
+ */
+struct s3c24xx_eint_domain_data {
+       struct samsung_pin_bank *bank;
+       struct s3c24xx_eint_data *eint_data;
+       bool eint0_3_parent_only;
+};
+
+static int s3c24xx_eint_get_trigger(unsigned int type)
+{
+       switch (type) {
+       case IRQ_TYPE_EDGE_RISING:
+               return EINT_EDGE_RISING;
+               break;
+       case IRQ_TYPE_EDGE_FALLING:
+               return EINT_EDGE_FALLING;
+               break;
+       case IRQ_TYPE_EDGE_BOTH:
+               return EINT_EDGE_BOTH;
+               break;
+       case IRQ_TYPE_LEVEL_HIGH:
+               return EINT_LEVEL_HIGH;
+               break;
+       case IRQ_TYPE_LEVEL_LOW:
+               return EINT_LEVEL_LOW;
+               break;
+       default:
+               return -EINVAL;
+       }
+}
+
+static void s3c24xx_eint_set_handler(unsigned int irq, unsigned int type)
+{
+       /* Edge- and level-triggered interrupts need different handlers */
+       if (type & IRQ_TYPE_EDGE_BOTH)
+               __irq_set_handler_locked(irq, handle_edge_irq);
+       else
+               __irq_set_handler_locked(irq, handle_level_irq);
+}
+
+static void s3c24xx_eint_set_function(struct samsung_pinctrl_drv_data *d,
+                                       struct samsung_pin_bank *bank, int pin)
+{
+       struct samsung_pin_bank_type *bank_type = bank->type;
+       unsigned long flags;
+       void __iomem *reg;
+       u8 shift;
+       u32 mask;
+       u32 val;
+
+       /* Make sure that pin is configured as interrupt */
+       reg = d->virt_base + bank->pctl_offset;
+       shift = pin * bank_type->fld_width[PINCFG_TYPE_FUNC];
+       mask = (1 << bank_type->fld_width[PINCFG_TYPE_FUNC]) - 1;
+
+       spin_lock_irqsave(&bank->slock, flags);
+
+       val = readl(reg);
+       val &= ~(mask << shift);
+       val |= bank->eint_func << shift;
+       writel(val, reg);
+
+       spin_unlock_irqrestore(&bank->slock, flags);
+}
+
+static int s3c24xx_eint_type(struct irq_data *data, unsigned int type)
+{
+       struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
+       struct samsung_pinctrl_drv_data *d = bank->drvdata;
+       int index = bank->eint_offset + data->hwirq;
+       void __iomem *reg;
+       int trigger;
+       u8 shift;
+       u32 val;
+
+       trigger = s3c24xx_eint_get_trigger(type);
+       if (trigger < 0) {
+               dev_err(d->dev, "unsupported external interrupt type\n");
+               return -EINVAL;
+       }
+
+       s3c24xx_eint_set_handler(data->irq, type);
+
+       /* Set up interrupt trigger */
+       reg = d->virt_base + EINT_REG(index);
+       shift = EINT_OFFS(index);
+
+       val = readl(reg);
+       val &= ~(EINT_MASK << shift);
+       val |= trigger << shift;
+       writel(val, reg);
+
+       s3c24xx_eint_set_function(d, bank, data->hwirq);
+
+       return 0;
+}
+
+/* Handling of EINTs 0-3 on all except S3C2412 and S3C2413 */
+
+static void s3c2410_eint0_3_ack(struct irq_data *data)
+{
+       struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
+       struct s3c24xx_eint_domain_data *ddata = bank->irq_domain->host_data;
+       struct s3c24xx_eint_data *eint_data = ddata->eint_data;
+       int parent_irq = eint_data->parents[data->hwirq];
+       struct irq_chip *parent_chip = irq_get_chip(parent_irq);
+
+       parent_chip->irq_ack(irq_get_irq_data(parent_irq));
+}
+
+static void s3c2410_eint0_3_mask(struct irq_data *data)
+{
+       struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
+       struct s3c24xx_eint_domain_data *ddata = bank->irq_domain->host_data;
+       struct s3c24xx_eint_data *eint_data = ddata->eint_data;
+       int parent_irq = eint_data->parents[data->hwirq];
+       struct irq_chip *parent_chip = irq_get_chip(parent_irq);
+
+       parent_chip->irq_mask(irq_get_irq_data(parent_irq));
+}
+
+static void s3c2410_eint0_3_unmask(struct irq_data *data)
+{
+       struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
+       struct s3c24xx_eint_domain_data *ddata = bank->irq_domain->host_data;
+       struct s3c24xx_eint_data *eint_data = ddata->eint_data;
+       int parent_irq = eint_data->parents[data->hwirq];
+       struct irq_chip *parent_chip = irq_get_chip(parent_irq);
+
+       parent_chip->irq_unmask(irq_get_irq_data(parent_irq));
+}
+
+static struct irq_chip s3c2410_eint0_3_chip = {
+       .name           = "s3c2410-eint0_3",
+       .irq_ack        = s3c2410_eint0_3_ack,
+       .irq_mask       = s3c2410_eint0_3_mask,
+       .irq_unmask     = s3c2410_eint0_3_unmask,
+       .irq_set_type   = s3c24xx_eint_type,
+};
+
+static void s3c2410_demux_eint0_3(unsigned int irq, struct irq_desc *desc)
+{
+       struct irq_data *data = irq_desc_get_irq_data(desc);
+       struct s3c24xx_eint_data *eint_data = irq_get_handler_data(irq);
+       unsigned int virq;
+
+       /* the first 4 eints have a simple 1 to 1 mapping */
+       virq = irq_linear_revmap(eint_data->domains[data->hwirq], data->hwirq);
+       /* Something must be really wrong if an unmapped EINT is unmasked */
+       BUG_ON(!virq);
+
+       generic_handle_irq(virq);
+}
+
+/* Handling of EINTs 0-3 on S3C2412 and S3C2413 */
+
+static void s3c2412_eint0_3_ack(struct irq_data *data)
+{
+       struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
+       struct samsung_pinctrl_drv_data *d = bank->drvdata;
+
+       unsigned long bitval = 1UL << data->hwirq;
+       writel(bitval, d->virt_base + EINTPEND_REG);
+}
+
+static void s3c2412_eint0_3_mask(struct irq_data *data)
+{
+       struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
+       struct samsung_pinctrl_drv_data *d = bank->drvdata;
+       unsigned long mask;
+
+       mask = readl(d->virt_base + EINTMASK_REG);
+       mask |= (1UL << data->hwirq);
+       writel(mask, d->virt_base + EINTMASK_REG);
+}
+
+static void s3c2412_eint0_3_unmask(struct irq_data *data)
+{
+       struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
+       struct samsung_pinctrl_drv_data *d = bank->drvdata;
+       unsigned long mask;
+
+       mask = readl(d->virt_base + EINTMASK_REG);
+       mask &= ~(1UL << data->hwirq);
+       writel(mask, d->virt_base + EINTMASK_REG);
+}
+
+static struct irq_chip s3c2412_eint0_3_chip = {
+       .name           = "s3c2412-eint0_3",
+       .irq_ack        = s3c2412_eint0_3_ack,
+       .irq_mask       = s3c2412_eint0_3_mask,
+       .irq_unmask     = s3c2412_eint0_3_unmask,
+       .irq_set_type   = s3c24xx_eint_type,
+};
+
+static void s3c2412_demux_eint0_3(unsigned int irq, struct irq_desc *desc)
+{
+       struct irq_chip *chip = irq_get_chip(irq);
+       struct irq_data *data = irq_desc_get_irq_data(desc);
+       struct s3c24xx_eint_data *eint_data = irq_get_handler_data(irq);
+       unsigned int virq;
+
+       chained_irq_enter(chip, desc);
+
+       /* the first 4 eints have a simple 1 to 1 mapping */
+       virq = irq_linear_revmap(eint_data->domains[data->hwirq], data->hwirq);
+       /* Something must be really wrong if an unmapped EINT is unmasked */
+       BUG_ON(!virq);
+
+       generic_handle_irq(virq);
+
+       chained_irq_exit(chip, desc);
+}
+
+/* Handling of all other eints */
+
+static void s3c24xx_eint_ack(struct irq_data *data)
+{
+       struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
+       struct samsung_pinctrl_drv_data *d = bank->drvdata;
+       unsigned char index = bank->eint_offset + data->hwirq;
+
+       writel(1UL << index, d->virt_base + EINTPEND_REG);
+}
+
+static void s3c24xx_eint_mask(struct irq_data *data)
+{
+       struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
+       struct samsung_pinctrl_drv_data *d = bank->drvdata;
+       unsigned char index = bank->eint_offset + data->hwirq;
+       unsigned long mask;
+
+       mask = readl(d->virt_base + EINTMASK_REG);
+       mask |= (1UL << index);
+       writel(mask, d->virt_base + EINTMASK_REG);
+}
+
+static void s3c24xx_eint_unmask(struct irq_data *data)
+{
+       struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
+       struct samsung_pinctrl_drv_data *d = bank->drvdata;
+       unsigned char index = bank->eint_offset + data->hwirq;
+       unsigned long mask;
+
+       mask = readl(d->virt_base + EINTMASK_REG);
+       mask &= ~(1UL << index);
+       writel(mask, d->virt_base + EINTMASK_REG);
+}
+
+static struct irq_chip s3c24xx_eint_chip = {
+       .name           = "s3c-eint",
+       .irq_ack        = s3c24xx_eint_ack,
+       .irq_mask       = s3c24xx_eint_mask,
+       .irq_unmask     = s3c24xx_eint_unmask,
+       .irq_set_type   = s3c24xx_eint_type,
+};
+
+static inline void s3c24xx_demux_eint(unsigned int irq, struct irq_desc *desc,
+                                     u32 offset, u32 range)
+{
+       struct irq_chip *chip = irq_get_chip(irq);
+       struct s3c24xx_eint_data *data = irq_get_handler_data(irq);
+       struct samsung_pinctrl_drv_data *d = data->drvdata;
+       unsigned int pend, mask;
+
+       chained_irq_enter(chip, desc);
+
+       pend = readl(d->virt_base + EINTPEND_REG);
+       mask = readl(d->virt_base + EINTMASK_REG);
+
+       pend &= ~mask;
+       pend &= range;
+
+       while (pend) {
+               unsigned int virq;
+
+               irq = __ffs(pend);
+               pend &= ~(1 << irq);
+               virq = irq_linear_revmap(data->domains[irq], irq - offset);
+               /* Something is really wrong if an unmapped EINT is unmasked */
+               BUG_ON(!virq);
+
+               generic_handle_irq(virq);
+       }
+
+       chained_irq_exit(chip, desc);
+}
+
+static void s3c24xx_demux_eint4_7(unsigned int irq, struct irq_desc *desc)
+{
+       s3c24xx_demux_eint(irq, desc, 0, 0xf0);
+}
+
+static void s3c24xx_demux_eint8_23(unsigned int irq, struct irq_desc *desc)
+{
+       s3c24xx_demux_eint(irq, desc, 8, 0xffff00);
+}
+
+static irq_flow_handler_t s3c2410_eint_handlers[NUM_EINT_IRQ] = {
+       s3c2410_demux_eint0_3,
+       s3c2410_demux_eint0_3,
+       s3c2410_demux_eint0_3,
+       s3c2410_demux_eint0_3,
+       s3c24xx_demux_eint4_7,
+       s3c24xx_demux_eint8_23,
+};
+
+static irq_flow_handler_t s3c2412_eint_handlers[NUM_EINT_IRQ] = {
+       s3c2412_demux_eint0_3,
+       s3c2412_demux_eint0_3,
+       s3c2412_demux_eint0_3,
+       s3c2412_demux_eint0_3,
+       s3c24xx_demux_eint4_7,
+       s3c24xx_demux_eint8_23,
+};
+
+static int s3c24xx_gpf_irq_map(struct irq_domain *h, unsigned int virq,
+                                       irq_hw_number_t hw)
+{
+       struct s3c24xx_eint_domain_data *ddata = h->host_data;
+       struct samsung_pin_bank *bank = ddata->bank;
+
+       if (!(bank->eint_mask & (1 << (bank->eint_offset + hw))))
+               return -EINVAL;
+
+       if (hw <= 3) {
+               if (ddata->eint0_3_parent_only)
+                       irq_set_chip_and_handler(virq, &s3c2410_eint0_3_chip,
+                                                handle_edge_irq);
+               else
+                       irq_set_chip_and_handler(virq, &s3c2412_eint0_3_chip,
+                                                handle_edge_irq);
+       } else {
+               irq_set_chip_and_handler(virq, &s3c24xx_eint_chip,
+                                        handle_edge_irq);
+       }
+       irq_set_chip_data(virq, bank);
+       set_irq_flags(virq, IRQF_VALID);
+       return 0;
+}
+
+static const struct irq_domain_ops s3c24xx_gpf_irq_ops = {
+       .map    = s3c24xx_gpf_irq_map,
+       .xlate  = irq_domain_xlate_twocell,
+};
+
+static int s3c24xx_gpg_irq_map(struct irq_domain *h, unsigned int virq,
+                                       irq_hw_number_t hw)
+{
+       struct s3c24xx_eint_domain_data *ddata = h->host_data;
+       struct samsung_pin_bank *bank = ddata->bank;
+
+       if (!(bank->eint_mask & (1 << (bank->eint_offset + hw))))
+               return -EINVAL;
+
+       irq_set_chip_and_handler(virq, &s3c24xx_eint_chip, handle_edge_irq);
+       irq_set_chip_data(virq, bank);
+       set_irq_flags(virq, IRQF_VALID);
+       return 0;
+}
+
+static const struct irq_domain_ops s3c24xx_gpg_irq_ops = {
+       .map    = s3c24xx_gpg_irq_map,
+       .xlate  = irq_domain_xlate_twocell,
+};
+
+static const struct of_device_id s3c24xx_eint_irq_ids[] = {
+       { .compatible = "samsung,s3c2410-wakeup-eint", .data = (void *)1 },
+       { .compatible = "samsung,s3c2412-wakeup-eint", .data = (void *)0 },
+       { }
+};
+
+static int s3c24xx_eint_init(struct samsung_pinctrl_drv_data *d)
+{
+       struct device *dev = d->dev;
+       const struct of_device_id *match;
+       struct device_node *eint_np = NULL;
+       struct device_node *np;
+       struct samsung_pin_bank *bank;
+       struct s3c24xx_eint_data *eint_data;
+       const struct irq_domain_ops *ops;
+       unsigned int i;
+       bool eint0_3_parent_only;
+       irq_flow_handler_t *handlers;
+
+       for_each_child_of_node(dev->of_node, np) {
+               match = of_match_node(s3c24xx_eint_irq_ids, np);
+               if (match) {
+                       eint_np = np;
+                       eint0_3_parent_only = (bool)match->data;
+                       break;
+               }
+       }
+       if (!eint_np)
+               return -ENODEV;
+
+       eint_data = devm_kzalloc(dev, sizeof(*eint_data), GFP_KERNEL);
+       if (!eint_data)
+               return -ENOMEM;
+
+       eint_data->drvdata = d;
+
+       handlers = eint0_3_parent_only ? s3c2410_eint_handlers
+                                      : s3c2412_eint_handlers;
+       for (i = 0; i < NUM_EINT_IRQ; ++i) {
+               unsigned int irq;
+
+               irq = irq_of_parse_and_map(eint_np, i);
+               if (!irq) {
+                       dev_err(dev, "failed to get wakeup EINT IRQ %d\n", i);
+                       return -ENXIO;
+               }
+
+               eint_data->parents[i] = irq;
+               irq_set_chained_handler(irq, handlers[i]);
+               irq_set_handler_data(irq, eint_data);
+       }
+
+       bank = d->ctrl->pin_banks;
+       for (i = 0; i < d->ctrl->nr_banks; ++i, ++bank) {
+               struct s3c24xx_eint_domain_data *ddata;
+               unsigned int mask;
+               unsigned int irq;
+               unsigned int pin;
+
+               if (bank->eint_type != EINT_TYPE_WKUP)
+                       continue;
+
+               ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL);
+               if (!ddata)
+                       return -ENOMEM;
+
+               ddata->bank = bank;
+               ddata->eint_data = eint_data;
+               ddata->eint0_3_parent_only = eint0_3_parent_only;
+
+               ops = (bank->eint_offset == 0) ? &s3c24xx_gpf_irq_ops
+                                              : &s3c24xx_gpg_irq_ops;
+
+               bank->irq_domain = irq_domain_add_linear(bank->of_node,
+                               bank->nr_pins, ops, ddata);
+               if (!bank->irq_domain) {
+                       dev_err(dev, "wkup irq domain add failed\n");
+                       return -ENXIO;
+               }
+
+               irq = bank->eint_offset;
+               mask = bank->eint_mask;
+               for (pin = 0; mask; ++pin, mask >>= 1) {
+                       if (irq >= NUM_EINT)
+                               break;
+                       if (!(mask & 1))
+                               continue;
+                       eint_data->domains[irq] = bank->irq_domain;
+                       ++irq;
+               }
+       }
+
+       return 0;
+}
+
+static struct samsung_pin_bank s3c2412_pin_banks[] = {
+       PIN_BANK_A(23, 0x000, "gpa"),
+       PIN_BANK_2BIT(11, 0x010, "gpb"),
+       PIN_BANK_2BIT(16, 0x020, "gpc"),
+       PIN_BANK_2BIT(16, 0x030, "gpd"),
+       PIN_BANK_2BIT(16, 0x040, "gpe"),
+       PIN_BANK_2BIT_EINTW(8, 0x050, "gpf", 0, 0xff),
+       PIN_BANK_2BIT_EINTW(16, 0x060, "gpg", 8, 0xffff00),
+       PIN_BANK_2BIT(11, 0x070, "gph"),
+       PIN_BANK_2BIT(13, 0x080, "gpj"),
+};
+
+struct samsung_pin_ctrl s3c2412_pin_ctrl[] = {
+       {
+               .pin_banks      = s3c2412_pin_banks,
+               .nr_banks       = ARRAY_SIZE(s3c2412_pin_banks),
+               .eint_wkup_init = s3c24xx_eint_init,
+               .label          = "S3C2412-GPIO",
+       },
+};
+
+static struct samsung_pin_bank s3c2416_pin_banks[] = {
+       PIN_BANK_A(27, 0x000, "gpa"),
+       PIN_BANK_2BIT(11, 0x010, "gpb"),
+       PIN_BANK_2BIT(16, 0x020, "gpc"),
+       PIN_BANK_2BIT(16, 0x030, "gpd"),
+       PIN_BANK_2BIT(16, 0x040, "gpe"),
+       PIN_BANK_2BIT_EINTW(8, 0x050, "gpf", 0, 0xff),
+       PIN_BANK_2BIT_EINTW(8, 0x060, "gpg", 8, 0xff00),
+       PIN_BANK_2BIT(15, 0x070, "gph"),
+       PIN_BANK_2BIT(16, 0x0e0, "gpk"),
+       PIN_BANK_2BIT(14, 0x0f0, "gpl"),
+       PIN_BANK_2BIT(2, 0x100, "gpm"),
+};
+
+struct samsung_pin_ctrl s3c2416_pin_ctrl[] = {
+       {
+               .pin_banks      = s3c2416_pin_banks,
+               .nr_banks       = ARRAY_SIZE(s3c2416_pin_banks),
+               .eint_wkup_init = s3c24xx_eint_init,
+               .label          = "S3C2416-GPIO",
+       },
+};
+
+static struct samsung_pin_bank s3c2440_pin_banks[] = {
+       PIN_BANK_A(25, 0x000, "gpa"),
+       PIN_BANK_2BIT(11, 0x010, "gpb"),
+       PIN_BANK_2BIT(16, 0x020, "gpc"),
+       PIN_BANK_2BIT(16, 0x030, "gpd"),
+       PIN_BANK_2BIT(16, 0x040, "gpe"),
+       PIN_BANK_2BIT_EINTW(8, 0x050, "gpf", 0, 0xff),
+       PIN_BANK_2BIT_EINTW(16, 0x060, "gpg", 8, 0xffff00),
+       PIN_BANK_2BIT(11, 0x070, "gph"),
+       PIN_BANK_2BIT(13, 0x0d0, "gpj"),
+};
+
+struct samsung_pin_ctrl s3c2440_pin_ctrl[] = {
+       {
+               .pin_banks      = s3c2440_pin_banks,
+               .nr_banks       = ARRAY_SIZE(s3c2440_pin_banks),
+               .eint_wkup_init = s3c24xx_eint_init,
+               .label          = "S3C2440-GPIO",
+       },
+};
+
+static struct samsung_pin_bank s3c2450_pin_banks[] = {
+       PIN_BANK_A(28, 0x000, "gpa"),
+       PIN_BANK_2BIT(11, 0x010, "gpb"),
+       PIN_BANK_2BIT(16, 0x020, "gpc"),
+       PIN_BANK_2BIT(16, 0x030, "gpd"),
+       PIN_BANK_2BIT(16, 0x040, "gpe"),
+       PIN_BANK_2BIT_EINTW(8, 0x050, "gpf", 0, 0xff),
+       PIN_BANK_2BIT_EINTW(16, 0x060, "gpg", 8, 0xffff00),
+       PIN_BANK_2BIT(15, 0x070, "gph"),
+       PIN_BANK_2BIT(16, 0x0d0, "gpj"),
+       PIN_BANK_2BIT(16, 0x0e0, "gpk"),
+       PIN_BANK_2BIT(15, 0x0f0, "gpl"),
+       PIN_BANK_2BIT(2, 0x100, "gpm"),
+};
+
+struct samsung_pin_ctrl s3c2450_pin_ctrl[] = {
+       {
+               .pin_banks      = s3c2450_pin_banks,
+               .nr_banks       = ARRAY_SIZE(s3c2450_pin_banks),
+               .eint_wkup_init = s3c24xx_eint_init,
+               .label          = "S3C2450-GPIO",
+       },
+};
diff --git a/drivers/pinctrl/samsung/pinctrl-s3c64xx.c b/drivers/pinctrl/samsung/pinctrl-s3c64xx.c
new file mode 100644 (file)
index 0000000..89143c9
--- /dev/null
@@ -0,0 +1,816 @@
+/*
+ * S3C64xx specific support for pinctrl-samsung driver.
+ *
+ * Copyright (c) 2013 Tomasz Figa <tomasz.figa@gmail.com>
+ *
+ * Based on pinctrl-exynos.c, please see the file for original copyrights.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This file contains the Samsung S3C64xx specific information required by the
+ * the Samsung pinctrl/gpiolib driver. It also includes the implementation of
+ * external gpio and wakeup interrupt support.
+ */
+
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/irqdomain.h>
+#include <linux/irq.h>
+#include <linux/of_irq.h>
+#include <linux/io.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+
+#include "pinctrl-samsung.h"
+
+#define NUM_EINT0              28
+#define NUM_EINT0_IRQ          4
+#define EINT_MAX_PER_REG       16
+#define EINT_MAX_PER_GROUP     16
+
+/* External GPIO and wakeup interrupt related definitions */
+#define SVC_GROUP_SHIFT                4
+#define SVC_GROUP_MASK         0xf
+#define SVC_NUM_MASK           0xf
+#define SVC_GROUP(x)           ((x >> SVC_GROUP_SHIFT) & \
+                                               SVC_GROUP_MASK)
+
+#define EINT12CON_REG          0x200
+#define EINT12MASK_REG         0x240
+#define EINT12PEND_REG         0x260
+
+#define EINT_OFFS(i)           ((i) % (2 * EINT_MAX_PER_GROUP))
+#define EINT_GROUP(i)          ((i) / EINT_MAX_PER_GROUP)
+#define EINT_REG(g)            (4 * ((g) / 2))
+
+#define EINTCON_REG(i)         (EINT12CON_REG + EINT_REG(EINT_GROUP(i)))
+#define EINTMASK_REG(i)                (EINT12MASK_REG + EINT_REG(EINT_GROUP(i)))
+#define EINTPEND_REG(i)                (EINT12PEND_REG + EINT_REG(EINT_GROUP(i)))
+
+#define SERVICE_REG            0x284
+#define SERVICEPEND_REG                0x288
+
+#define EINT0CON0_REG          0x900
+#define EINT0MASK_REG          0x920
+#define EINT0PEND_REG          0x924
+
+/* S3C64xx specific external interrupt trigger types */
+#define EINT_LEVEL_LOW         0
+#define EINT_LEVEL_HIGH                1
+#define EINT_EDGE_FALLING      2
+#define EINT_EDGE_RISING       4
+#define EINT_EDGE_BOTH         6
+#define EINT_CON_MASK          0xF
+#define EINT_CON_LEN           4
+
+static struct samsung_pin_bank_type bank_type_4bit_off = {
+       .fld_width = { 4, 1, 2, 0, 2, 2, },
+       .reg_offset = { 0x00, 0x04, 0x08, 0, 0x0c, 0x10, },
+};
+
+static struct samsung_pin_bank_type bank_type_4bit_alive = {
+       .fld_width = { 4, 1, 2, },
+       .reg_offset = { 0x00, 0x04, 0x08, },
+};
+
+static struct samsung_pin_bank_type bank_type_4bit2_off = {
+       .fld_width = { 4, 1, 2, 0, 2, 2, },
+       .reg_offset = { 0x00, 0x08, 0x0c, 0, 0x10, 0x14, },
+};
+
+static struct samsung_pin_bank_type bank_type_4bit2_alive = {
+       .fld_width = { 4, 1, 2, },
+       .reg_offset = { 0x00, 0x08, 0x0c, },
+};
+
+static struct samsung_pin_bank_type bank_type_2bit_off = {
+       .fld_width = { 2, 1, 2, 0, 2, 2, },
+       .reg_offset = { 0x00, 0x04, 0x08, 0, 0x0c, 0x10, },
+};
+
+static struct samsung_pin_bank_type bank_type_2bit_alive = {
+       .fld_width = { 2, 1, 2, },
+       .reg_offset = { 0x00, 0x04, 0x08, },
+};
+
+#define PIN_BANK_4BIT(pins, reg, id)                   \
+       {                                               \
+               .type           = &bank_type_4bit_off,  \
+               .pctl_offset    = reg,                  \
+               .nr_pins        = pins,                 \
+               .eint_type      = EINT_TYPE_NONE,       \
+               .name           = id                    \
+       }
+
+#define PIN_BANK_4BIT_EINTG(pins, reg, id, eoffs)      \
+       {                                               \
+               .type           = &bank_type_4bit_off,  \
+               .pctl_offset    = reg,                  \
+               .nr_pins        = pins,                 \
+               .eint_type      = EINT_TYPE_GPIO,       \
+               .eint_func      = 7,                    \
+               .eint_mask      = (1 << (pins)) - 1,    \
+               .eint_offset    = eoffs,                \
+               .name           = id                    \
+       }
+
+#define PIN_BANK_4BIT_EINTW(pins, reg, id, eoffs, emask) \
+       {                                               \
+               .type           = &bank_type_4bit_alive,\
+               .pctl_offset    = reg,                  \
+               .nr_pins        = pins,                 \
+               .eint_type      = EINT_TYPE_WKUP,       \
+               .eint_func      = 3,                    \
+               .eint_mask      = emask,                \
+               .eint_offset    = eoffs,                \
+               .name           = id                    \
+       }
+
+#define PIN_BANK_4BIT2_EINTG(pins, reg, id, eoffs)     \
+       {                                               \
+               .type           = &bank_type_4bit2_off, \
+               .pctl_offset    = reg,                  \
+               .nr_pins        = pins,                 \
+               .eint_type      = EINT_TYPE_GPIO,       \
+               .eint_func      = 7,                    \
+               .eint_mask      = (1 << (pins)) - 1,    \
+               .eint_offset    = eoffs,                \
+               .name           = id                    \
+       }
+
+#define PIN_BANK_4BIT2_EINTW(pins, reg, id, eoffs, emask) \
+       {                                               \
+               .type           = &bank_type_4bit2_alive,\
+               .pctl_offset    = reg,                  \
+               .nr_pins        = pins,                 \
+               .eint_type      = EINT_TYPE_WKUP,       \
+               .eint_func      = 3,                    \
+               .eint_mask      = emask,                \
+               .eint_offset    = eoffs,                \
+               .name           = id                    \
+       }
+
+#define PIN_BANK_4BIT2_ALIVE(pins, reg, id)            \
+       {                                               \
+               .type           = &bank_type_4bit2_alive,\
+               .pctl_offset    = reg,                  \
+               .nr_pins        = pins,                 \
+               .eint_type      = EINT_TYPE_NONE,       \
+               .name           = id                    \
+       }
+
+#define PIN_BANK_2BIT(pins, reg, id)                   \
+       {                                               \
+               .type           = &bank_type_2bit_off,  \
+               .pctl_offset    = reg,                  \
+               .nr_pins        = pins,                 \
+               .eint_type      = EINT_TYPE_NONE,       \
+               .name           = id                    \
+       }
+
+#define PIN_BANK_2BIT_EINTG(pins, reg, id, eoffs, emask) \
+       {                                               \
+               .type           = &bank_type_2bit_off,  \
+               .pctl_offset    = reg,                  \
+               .nr_pins        = pins,                 \
+               .eint_type      = EINT_TYPE_GPIO,       \
+               .eint_func      = 3,                    \
+               .eint_mask      = emask,                \
+               .eint_offset    = eoffs,                \
+               .name           = id                    \
+       }
+
+#define PIN_BANK_2BIT_EINTW(pins, reg, id, eoffs)      \
+       {                                               \
+               .type           = &bank_type_2bit_alive,\
+               .pctl_offset    = reg,                  \
+               .nr_pins        = pins,                 \
+               .eint_type      = EINT_TYPE_WKUP,       \
+               .eint_func      = 2,                    \
+               .eint_mask      = (1 << (pins)) - 1,    \
+               .eint_offset    = eoffs,                \
+               .name           = id                    \
+       }
+
+/**
+ * struct s3c64xx_eint0_data: EINT0 common data
+ * @drvdata: pin controller driver data
+ * @domains: IRQ domains of particular EINT0 interrupts
+ * @pins: pin offsets inside of banks of particular EINT0 interrupts
+ */
+struct s3c64xx_eint0_data {
+       struct samsung_pinctrl_drv_data *drvdata;
+       struct irq_domain *domains[NUM_EINT0];
+       u8 pins[NUM_EINT0];
+};
+
+/**
+ * struct s3c64xx_eint0_domain_data: EINT0 per-domain data
+ * @bank: pin bank related to the domain
+ * @eints: EINT0 interrupts related to the domain
+ */
+struct s3c64xx_eint0_domain_data {
+       struct samsung_pin_bank *bank;
+       u8 eints[];
+};
+
+/**
+ * struct s3c64xx_eint_gpio_data: GPIO EINT data
+ * @drvdata: pin controller driver data
+ * @domains: array of domains related to EINT interrupt groups
+ */
+struct s3c64xx_eint_gpio_data {
+       struct samsung_pinctrl_drv_data *drvdata;
+       struct irq_domain *domains[];
+};
+
+/*
+ * Common functions for S3C64xx EINT configuration
+ */
+
+static int s3c64xx_irq_get_trigger(unsigned int type)
+{
+       int trigger;
+
+       switch (type) {
+       case IRQ_TYPE_EDGE_RISING:
+               trigger = EINT_EDGE_RISING;
+               break;
+       case IRQ_TYPE_EDGE_FALLING:
+               trigger = EINT_EDGE_FALLING;
+               break;
+       case IRQ_TYPE_EDGE_BOTH:
+               trigger = EINT_EDGE_BOTH;
+               break;
+       case IRQ_TYPE_LEVEL_HIGH:
+               trigger = EINT_LEVEL_HIGH;
+               break;
+       case IRQ_TYPE_LEVEL_LOW:
+               trigger = EINT_LEVEL_LOW;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return trigger;
+}
+
+static void s3c64xx_irq_set_handler(unsigned int irq, unsigned int type)
+{
+       /* Edge- and level-triggered interrupts need different handlers */
+       if (type & IRQ_TYPE_EDGE_BOTH)
+               __irq_set_handler_locked(irq, handle_edge_irq);
+       else
+               __irq_set_handler_locked(irq, handle_level_irq);
+}
+
+static void s3c64xx_irq_set_function(struct samsung_pinctrl_drv_data *d,
+                                       struct samsung_pin_bank *bank, int pin)
+{
+       struct samsung_pin_bank_type *bank_type = bank->type;
+       unsigned long flags;
+       void __iomem *reg;
+       u8 shift;
+       u32 mask;
+       u32 val;
+
+       /* Make sure that pin is configured as interrupt */
+       reg = d->virt_base + bank->pctl_offset;
+       shift = pin;
+       if (bank_type->fld_width[PINCFG_TYPE_FUNC] * shift >= 32) {
+               /* 4-bit bank type with 2 con regs */
+               reg += 4;
+               shift -= 8;
+       }
+
+       shift = shift * bank_type->fld_width[PINCFG_TYPE_FUNC];
+       mask = (1 << bank_type->fld_width[PINCFG_TYPE_FUNC]) - 1;
+
+       spin_lock_irqsave(&bank->slock, flags);
+
+       val = readl(reg);
+       val &= ~(mask << shift);
+       val |= bank->eint_func << shift;
+       writel(val, reg);
+
+       spin_unlock_irqrestore(&bank->slock, flags);
+}
+
+/*
+ * Functions for EINT GPIO configuration (EINT groups 1-9)
+ */
+
+static inline void s3c64xx_gpio_irq_set_mask(struct irq_data *irqd, bool mask)
+{
+       struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
+       struct samsung_pinctrl_drv_data *d = bank->drvdata;
+       unsigned char index = EINT_OFFS(bank->eint_offset) + irqd->hwirq;
+       void __iomem *reg = d->virt_base + EINTMASK_REG(bank->eint_offset);
+       u32 val;
+
+       val = readl(reg);
+       if (mask)
+               val |= 1 << index;
+       else
+               val &= ~(1 << index);
+       writel(val, reg);
+}
+
+static void s3c64xx_gpio_irq_unmask(struct irq_data *irqd)
+{
+       s3c64xx_gpio_irq_set_mask(irqd, false);
+}
+
+static void s3c64xx_gpio_irq_mask(struct irq_data *irqd)
+{
+       s3c64xx_gpio_irq_set_mask(irqd, true);
+}
+
+static void s3c64xx_gpio_irq_ack(struct irq_data *irqd)
+{
+       struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
+       struct samsung_pinctrl_drv_data *d = bank->drvdata;
+       unsigned char index = EINT_OFFS(bank->eint_offset) + irqd->hwirq;
+       void __iomem *reg = d->virt_base + EINTPEND_REG(bank->eint_offset);
+
+       writel(1 << index, reg);
+}
+
+static int s3c64xx_gpio_irq_set_type(struct irq_data *irqd, unsigned int type)
+{
+       struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
+       struct samsung_pinctrl_drv_data *d = bank->drvdata;
+       void __iomem *reg;
+       int trigger;
+       u8 shift;
+       u32 val;
+
+       trigger = s3c64xx_irq_get_trigger(type);
+       if (trigger < 0) {
+               pr_err("unsupported external interrupt type\n");
+               return -EINVAL;
+       }
+
+       s3c64xx_irq_set_handler(irqd->irq, type);
+
+       /* Set up interrupt trigger */
+       reg = d->virt_base + EINTCON_REG(bank->eint_offset);
+       shift = EINT_OFFS(bank->eint_offset) + irqd->hwirq;
+       shift = 4 * (shift / 4); /* 4 EINTs per trigger selector */
+
+       val = readl(reg);
+       val &= ~(EINT_CON_MASK << shift);
+       val |= trigger << shift;
+       writel(val, reg);
+
+       s3c64xx_irq_set_function(d, bank, irqd->hwirq);
+
+       return 0;
+}
+
+/*
+ * irq_chip for gpio interrupts.
+ */
+static struct irq_chip s3c64xx_gpio_irq_chip = {
+       .name           = "GPIO",
+       .irq_unmask     = s3c64xx_gpio_irq_unmask,
+       .irq_mask       = s3c64xx_gpio_irq_mask,
+       .irq_ack        = s3c64xx_gpio_irq_ack,
+       .irq_set_type   = s3c64xx_gpio_irq_set_type,
+};
+
+static int s3c64xx_gpio_irq_map(struct irq_domain *h, unsigned int virq,
+                                       irq_hw_number_t hw)
+{
+       struct samsung_pin_bank *bank = h->host_data;
+
+       if (!(bank->eint_mask & (1 << hw)))
+               return -EINVAL;
+
+       irq_set_chip_and_handler(virq,
+                               &s3c64xx_gpio_irq_chip, handle_level_irq);
+       irq_set_chip_data(virq, bank);
+       set_irq_flags(virq, IRQF_VALID);
+
+       return 0;
+}
+
+/*
+ * irq domain callbacks for external gpio interrupt controller.
+ */
+static const struct irq_domain_ops s3c64xx_gpio_irqd_ops = {
+       .map    = s3c64xx_gpio_irq_map,
+       .xlate  = irq_domain_xlate_twocell,
+};
+
+static void s3c64xx_eint_gpio_irq(unsigned int irq, struct irq_desc *desc)
+{
+       struct irq_chip *chip = irq_get_chip(irq);
+       struct s3c64xx_eint_gpio_data *data = irq_get_handler_data(irq);
+       struct samsung_pinctrl_drv_data *drvdata = data->drvdata;
+
+       chained_irq_enter(chip, desc);
+
+       do {
+               unsigned int svc;
+               unsigned int group;
+               unsigned int pin;
+               unsigned int virq;
+
+               svc = readl(drvdata->virt_base + SERVICE_REG);
+               group = SVC_GROUP(svc);
+               pin = svc & SVC_NUM_MASK;
+
+               if (!group)
+                       break;
+
+               /* Group 1 is used for two pin banks */
+               if (group == 1) {
+                       if (pin < 8)
+                               group = 0;
+                       else
+                               pin -= 8;
+               }
+
+               virq = irq_linear_revmap(data->domains[group], pin);
+               /*
+                * Something must be really wrong if an unmapped EINT
+                * was unmasked...
+                */
+               BUG_ON(!virq);
+
+               generic_handle_irq(virq);
+       } while (1);
+
+       chained_irq_exit(chip, desc);
+}
+
+/**
+ * s3c64xx_eint_gpio_init() - setup handling of external gpio interrupts.
+ * @d: driver data of samsung pinctrl driver.
+ */
+static int s3c64xx_eint_gpio_init(struct samsung_pinctrl_drv_data *d)
+{
+       struct s3c64xx_eint_gpio_data *data;
+       struct samsung_pin_bank *bank;
+       struct device *dev = d->dev;
+       unsigned int nr_domains;
+       unsigned int i;
+
+       if (!d->irq) {
+               dev_err(dev, "irq number not available\n");
+               return -EINVAL;
+       }
+
+       nr_domains = 0;
+       bank = d->ctrl->pin_banks;
+       for (i = 0; i < d->ctrl->nr_banks; ++i, ++bank) {
+               unsigned int nr_eints;
+               unsigned int mask;
+
+               if (bank->eint_type != EINT_TYPE_GPIO)
+                       continue;
+
+               mask = bank->eint_mask;
+               nr_eints = fls(mask);
+
+               bank->irq_domain = irq_domain_add_linear(bank->of_node,
+                                       nr_eints, &s3c64xx_gpio_irqd_ops, bank);
+               if (!bank->irq_domain) {
+                       dev_err(dev, "gpio irq domain add failed\n");
+                       return -ENXIO;
+               }
+
+               ++nr_domains;
+       }
+
+       data = devm_kzalloc(dev, sizeof(*data)
+                       + nr_domains * sizeof(*data->domains), GFP_KERNEL);
+       if (!data) {
+               dev_err(dev, "failed to allocate handler data\n");
+               return -ENOMEM;
+       }
+       data->drvdata = d;
+
+       bank = d->ctrl->pin_banks;
+       nr_domains = 0;
+       for (i = 0; i < d->ctrl->nr_banks; ++i, ++bank) {
+               if (bank->eint_type != EINT_TYPE_GPIO)
+                       continue;
+
+               data->domains[nr_domains++] = bank->irq_domain;
+       }
+
+       irq_set_chained_handler(d->irq, s3c64xx_eint_gpio_irq);
+       irq_set_handler_data(d->irq, data);
+
+       return 0;
+}
+
+/*
+ * Functions for configuration of EINT0 wake-up interrupts
+ */
+
+static inline void s3c64xx_eint0_irq_set_mask(struct irq_data *irqd, bool mask)
+{
+       struct s3c64xx_eint0_domain_data *ddata =
+                                       irq_data_get_irq_chip_data(irqd);
+       struct samsung_pinctrl_drv_data *d = ddata->bank->drvdata;
+       u32 val;
+
+       val = readl(d->virt_base + EINT0MASK_REG);
+       if (mask)
+               val |= 1 << ddata->eints[irqd->hwirq];
+       else
+               val &= ~(1 << ddata->eints[irqd->hwirq]);
+       writel(val, d->virt_base + EINT0MASK_REG);
+}
+
+static void s3c64xx_eint0_irq_unmask(struct irq_data *irqd)
+{
+       s3c64xx_eint0_irq_set_mask(irqd, false);
+}
+
+static void s3c64xx_eint0_irq_mask(struct irq_data *irqd)
+{
+       s3c64xx_eint0_irq_set_mask(irqd, true);
+}
+
+static void s3c64xx_eint0_irq_ack(struct irq_data *irqd)
+{
+       struct s3c64xx_eint0_domain_data *ddata =
+                                       irq_data_get_irq_chip_data(irqd);
+       struct samsung_pinctrl_drv_data *d = ddata->bank->drvdata;
+
+       writel(1 << ddata->eints[irqd->hwirq],
+                                       d->virt_base + EINT0PEND_REG);
+}
+
+static int s3c64xx_eint0_irq_set_type(struct irq_data *irqd, unsigned int type)
+{
+       struct s3c64xx_eint0_domain_data *ddata =
+                                       irq_data_get_irq_chip_data(irqd);
+       struct samsung_pin_bank *bank = ddata->bank;
+       struct samsung_pinctrl_drv_data *d = bank->drvdata;
+       void __iomem *reg;
+       int trigger;
+       u8 shift;
+       u32 val;
+
+       trigger = s3c64xx_irq_get_trigger(type);
+       if (trigger < 0) {
+               pr_err("unsupported external interrupt type\n");
+               return -EINVAL;
+       }
+
+       s3c64xx_irq_set_handler(irqd->irq, type);
+
+       /* Set up interrupt trigger */
+       reg = d->virt_base + EINT0CON0_REG;
+       shift = ddata->eints[irqd->hwirq];
+       if (shift >= EINT_MAX_PER_REG) {
+               reg += 4;
+               shift -= EINT_MAX_PER_REG;
+       }
+       shift = EINT_CON_LEN * (shift / 2);
+
+       val = readl(reg);
+       val &= ~(EINT_CON_MASK << shift);
+       val |= trigger << shift;
+       writel(val, reg);
+
+       s3c64xx_irq_set_function(d, bank, irqd->hwirq);
+
+       return 0;
+}
+
+/*
+ * irq_chip for wakeup interrupts
+ */
+static struct irq_chip s3c64xx_eint0_irq_chip = {
+       .name           = "EINT0",
+       .irq_unmask     = s3c64xx_eint0_irq_unmask,
+       .irq_mask       = s3c64xx_eint0_irq_mask,
+       .irq_ack        = s3c64xx_eint0_irq_ack,
+       .irq_set_type   = s3c64xx_eint0_irq_set_type,
+};
+
+static inline void s3c64xx_irq_demux_eint(unsigned int irq,
+                                       struct irq_desc *desc, u32 range)
+{
+       struct irq_chip *chip = irq_get_chip(irq);
+       struct s3c64xx_eint0_data *data = irq_get_handler_data(irq);
+       struct samsung_pinctrl_drv_data *drvdata = data->drvdata;
+       unsigned int pend, mask;
+
+       chained_irq_enter(chip, desc);
+
+       pend = readl(drvdata->virt_base + EINT0PEND_REG);
+       mask = readl(drvdata->virt_base + EINT0MASK_REG);
+
+       pend = pend & range & ~mask;
+       pend &= range;
+
+       while (pend) {
+               unsigned int virq;
+
+               irq = fls(pend) - 1;
+               pend &= ~(1 << irq);
+
+               virq = irq_linear_revmap(data->domains[irq], data->pins[irq]);
+               /*
+                * Something must be really wrong if an unmapped EINT
+                * was unmasked...
+                */
+               BUG_ON(!virq);
+
+               generic_handle_irq(virq);
+       }
+
+       chained_irq_exit(chip, desc);
+}
+
+static void s3c64xx_demux_eint0_3(unsigned int irq, struct irq_desc *desc)
+{
+       s3c64xx_irq_demux_eint(irq, desc, 0xf);
+}
+
+static void s3c64xx_demux_eint4_11(unsigned int irq, struct irq_desc *desc)
+{
+       s3c64xx_irq_demux_eint(irq, desc, 0xff0);
+}
+
+static void s3c64xx_demux_eint12_19(unsigned int irq, struct irq_desc *desc)
+{
+       s3c64xx_irq_demux_eint(irq, desc, 0xff000);
+}
+
+static void s3c64xx_demux_eint20_27(unsigned int irq, struct irq_desc *desc)
+{
+       s3c64xx_irq_demux_eint(irq, desc, 0xff00000);
+}
+
+static irq_flow_handler_t s3c64xx_eint0_handlers[NUM_EINT0_IRQ] = {
+       s3c64xx_demux_eint0_3,
+       s3c64xx_demux_eint4_11,
+       s3c64xx_demux_eint12_19,
+       s3c64xx_demux_eint20_27,
+};
+
+static int s3c64xx_eint0_irq_map(struct irq_domain *h, unsigned int virq,
+                                       irq_hw_number_t hw)
+{
+       struct s3c64xx_eint0_domain_data *ddata = h->host_data;
+       struct samsung_pin_bank *bank = ddata->bank;
+
+       if (!(bank->eint_mask & (1 << hw)))
+               return -EINVAL;
+
+       irq_set_chip_and_handler(virq,
+                               &s3c64xx_eint0_irq_chip, handle_level_irq);
+       irq_set_chip_data(virq, ddata);
+       set_irq_flags(virq, IRQF_VALID);
+
+       return 0;
+}
+
+/*
+ * irq domain callbacks for external wakeup interrupt controller.
+ */
+static const struct irq_domain_ops s3c64xx_eint0_irqd_ops = {
+       .map    = s3c64xx_eint0_irq_map,
+       .xlate  = irq_domain_xlate_twocell,
+};
+
+/* list of external wakeup controllers supported */
+static const struct of_device_id s3c64xx_eint0_irq_ids[] = {
+       { .compatible = "samsung,s3c64xx-wakeup-eint", },
+       { }
+};
+
+/**
+ * s3c64xx_eint_eint0_init() - setup handling of external wakeup interrupts.
+ * @d: driver data of samsung pinctrl driver.
+ */
+static int s3c64xx_eint_eint0_init(struct samsung_pinctrl_drv_data *d)
+{
+       struct device *dev = d->dev;
+       struct device_node *eint0_np = NULL;
+       struct device_node *np;
+       struct samsung_pin_bank *bank;
+       struct s3c64xx_eint0_data *data;
+       unsigned int i;
+
+       for_each_child_of_node(dev->of_node, np) {
+               if (of_match_node(s3c64xx_eint0_irq_ids, np)) {
+                       eint0_np = np;
+                       break;
+               }
+       }
+       if (!eint0_np)
+               return -ENODEV;
+
+       data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
+       if (!data) {
+               dev_err(dev, "could not allocate memory for wkup eint data\n");
+               return -ENOMEM;
+       }
+       data->drvdata = d;
+
+       for (i = 0; i < NUM_EINT0_IRQ; ++i) {
+               unsigned int irq;
+
+               irq = irq_of_parse_and_map(eint0_np, i);
+               if (!irq) {
+                       dev_err(dev, "failed to get wakeup EINT IRQ %d\n", i);
+                       return -ENXIO;
+               }
+
+               irq_set_chained_handler(irq, s3c64xx_eint0_handlers[i]);
+               irq_set_handler_data(irq, data);
+       }
+
+       bank = d->ctrl->pin_banks;
+       for (i = 0; i < d->ctrl->nr_banks; ++i, ++bank) {
+               struct s3c64xx_eint0_domain_data *ddata;
+               unsigned int nr_eints;
+               unsigned int mask;
+               unsigned int irq;
+               unsigned int pin;
+
+               if (bank->eint_type != EINT_TYPE_WKUP)
+                       continue;
+
+               mask = bank->eint_mask;
+               nr_eints = fls(mask);
+
+               ddata = devm_kzalloc(dev,
+                               sizeof(*ddata) + nr_eints, GFP_KERNEL);
+               if (!ddata) {
+                       dev_err(dev, "failed to allocate domain data\n");
+                       return -ENOMEM;
+               }
+               ddata->bank = bank;
+
+               bank->irq_domain = irq_domain_add_linear(bank->of_node,
+                               nr_eints, &s3c64xx_eint0_irqd_ops, ddata);
+               if (!bank->irq_domain) {
+                       dev_err(dev, "wkup irq domain add failed\n");
+                       return -ENXIO;
+               }
+
+               irq = bank->eint_offset;
+               mask = bank->eint_mask;
+               for (pin = 0; mask; ++pin, mask >>= 1) {
+                       if (!(mask & 1))
+                               continue;
+                       data->domains[irq] = bank->irq_domain;
+                       data->pins[irq] = pin;
+                       ddata->eints[pin] = irq;
+                       ++irq;
+               }
+       }
+
+       return 0;
+}
+
+/* pin banks of s3c64xx pin-controller 0 */
+static struct samsung_pin_bank s3c64xx_pin_banks0[] = {
+       PIN_BANK_4BIT_EINTG(8, 0x000, "gpa", 0),
+       PIN_BANK_4BIT_EINTG(7, 0x020, "gpb", 8),
+       PIN_BANK_4BIT_EINTG(8, 0x040, "gpc", 16),
+       PIN_BANK_4BIT_EINTG(5, 0x060, "gpd", 32),
+       PIN_BANK_4BIT(5, 0x080, "gpe"),
+       PIN_BANK_2BIT_EINTG(16, 0x0a0, "gpf", 48, 0x3fff),
+       PIN_BANK_4BIT_EINTG(7, 0x0c0, "gpg", 64),
+       PIN_BANK_4BIT2_EINTG(10, 0x0e0, "gph", 80),
+       PIN_BANK_2BIT(16, 0x100, "gpi"),
+       PIN_BANK_2BIT(12, 0x120, "gpj"),
+       PIN_BANK_4BIT2_ALIVE(16, 0x800, "gpk"),
+       PIN_BANK_4BIT2_EINTW(15, 0x810, "gpl", 16, 0x7f00),
+       PIN_BANK_4BIT_EINTW(6, 0x820, "gpm", 23, 0x1f),
+       PIN_BANK_2BIT_EINTW(16, 0x830, "gpn", 0),
+       PIN_BANK_2BIT_EINTG(16, 0x140, "gpo", 96, 0xffff),
+       PIN_BANK_2BIT_EINTG(15, 0x160, "gpp", 112, 0x7fff),
+       PIN_BANK_2BIT_EINTG(9, 0x180, "gpq", 128, 0x1ff),
+};
+
+/*
+ * Samsung pinctrl driver data for S3C64xx SoC. S3C64xx SoC includes
+ * one gpio/pin-mux/pinconfig controller.
+ */
+struct samsung_pin_ctrl s3c64xx_pin_ctrl[] = {
+       {
+               /* pin-controller instance 1 data */
+               .pin_banks      = s3c64xx_pin_banks0,
+               .nr_banks       = ARRAY_SIZE(s3c64xx_pin_banks0),
+               .eint_gpio_init = s3c64xx_eint_gpio_init,
+               .eint_wkup_init = s3c64xx_eint_eint0_init,
+               .label          = "S3C64xx-GPIO",
+       },
+};
diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.c b/drivers/pinctrl/samsung/pinctrl-samsung.c
new file mode 100644 (file)
index 0000000..b07406d
--- /dev/null
@@ -0,0 +1,1285 @@
+/*
+ * pin-controller/pin-mux/pin-config/gpio-driver for Samsung's SoC's.
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ * Copyright (c) 2012 Linaro Ltd
+ *             http://www.linaro.org
+ *
+ * Author: Thomas Abraham <thomas.ab@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This driver implements the Samsung pinctrl driver. It supports setting up of
+ * pinmux and pinconf configurations. The gpiolib interface is also included.
+ * External interrupt (gpio and wakeup) support are not included in this driver
+ * but provides extensions to which platform specific implementation of the gpio
+ * and wakeup interrupts can be hooked to.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/irqdomain.h>
+#include <linux/spinlock.h>
+#include <linux/syscore_ops.h>
+
+#include "../core.h"
+#include "pinctrl-samsung.h"
+
+#define GROUP_SUFFIX           "-grp"
+#define GSUFFIX_LEN            sizeof(GROUP_SUFFIX)
+#define FUNCTION_SUFFIX                "-mux"
+#define FSUFFIX_LEN            sizeof(FUNCTION_SUFFIX)
+
+/* list of all possible config options supported */
+static struct pin_config {
+       const char *property;
+       enum pincfg_type param;
+} cfg_params[] = {
+       { "samsung,pin-pud", PINCFG_TYPE_PUD },
+       { "samsung,pin-drv", PINCFG_TYPE_DRV },
+       { "samsung,pin-con-pdn", PINCFG_TYPE_CON_PDN },
+       { "samsung,pin-pud-pdn", PINCFG_TYPE_PUD_PDN },
+       { "samsung,pin-val", PINCFG_TYPE_DAT },
+};
+
+/* Global list of devices (struct samsung_pinctrl_drv_data) */
+static LIST_HEAD(drvdata_list);
+
+static unsigned int pin_base;
+
+static inline struct samsung_pin_bank *gc_to_pin_bank(struct gpio_chip *gc)
+{
+       return container_of(gc, struct samsung_pin_bank, gpio_chip);
+}
+
+static int samsung_get_group_count(struct pinctrl_dev *pctldev)
+{
+       struct samsung_pinctrl_drv_data *pmx = pinctrl_dev_get_drvdata(pctldev);
+
+       return pmx->nr_groups;
+}
+
+static const char *samsung_get_group_name(struct pinctrl_dev *pctldev,
+                                               unsigned group)
+{
+       struct samsung_pinctrl_drv_data *pmx = pinctrl_dev_get_drvdata(pctldev);
+
+       return pmx->pin_groups[group].name;
+}
+
+static int samsung_get_group_pins(struct pinctrl_dev *pctldev,
+                                       unsigned group,
+                                       const unsigned **pins,
+                                       unsigned *num_pins)
+{
+       struct samsung_pinctrl_drv_data *pmx = pinctrl_dev_get_drvdata(pctldev);
+
+       *pins = pmx->pin_groups[group].pins;
+       *num_pins = pmx->pin_groups[group].num_pins;
+
+       return 0;
+}
+
+static int reserve_map(struct device *dev, struct pinctrl_map **map,
+                      unsigned *reserved_maps, unsigned *num_maps,
+                      unsigned reserve)
+{
+       unsigned old_num = *reserved_maps;
+       unsigned new_num = *num_maps + reserve;
+       struct pinctrl_map *new_map;
+
+       if (old_num >= new_num)
+               return 0;
+
+       new_map = krealloc(*map, sizeof(*new_map) * new_num, GFP_KERNEL);
+       if (!new_map) {
+               dev_err(dev, "krealloc(map) failed\n");
+               return -ENOMEM;
+       }
+
+       memset(new_map + old_num, 0, (new_num - old_num) * sizeof(*new_map));
+
+       *map = new_map;
+       *reserved_maps = new_num;
+
+       return 0;
+}
+
+static int add_map_mux(struct pinctrl_map **map, unsigned *reserved_maps,
+                      unsigned *num_maps, const char *group,
+                      const char *function)
+{
+       if (WARN_ON(*num_maps == *reserved_maps))
+               return -ENOSPC;
+
+       (*map)[*num_maps].type = PIN_MAP_TYPE_MUX_GROUP;
+       (*map)[*num_maps].data.mux.group = group;
+       (*map)[*num_maps].data.mux.function = function;
+       (*num_maps)++;
+
+       return 0;
+}
+
+static int add_map_configs(struct device *dev, struct pinctrl_map **map,
+                          unsigned *reserved_maps, unsigned *num_maps,
+                          const char *group, unsigned long *configs,
+                          unsigned num_configs)
+{
+       unsigned long *dup_configs;
+
+       if (WARN_ON(*num_maps == *reserved_maps))
+               return -ENOSPC;
+
+       dup_configs = kmemdup(configs, num_configs * sizeof(*dup_configs),
+                             GFP_KERNEL);
+       if (!dup_configs) {
+               dev_err(dev, "kmemdup(configs) failed\n");
+               return -ENOMEM;
+       }
+
+       (*map)[*num_maps].type = PIN_MAP_TYPE_CONFIGS_GROUP;
+       (*map)[*num_maps].data.configs.group_or_pin = group;
+       (*map)[*num_maps].data.configs.configs = dup_configs;
+       (*map)[*num_maps].data.configs.num_configs = num_configs;
+       (*num_maps)++;
+
+       return 0;
+}
+
+static int add_config(struct device *dev, unsigned long **configs,
+                     unsigned *num_configs, unsigned long config)
+{
+       unsigned old_num = *num_configs;
+       unsigned new_num = old_num + 1;
+       unsigned long *new_configs;
+
+       new_configs = krealloc(*configs, sizeof(*new_configs) * new_num,
+                              GFP_KERNEL);
+       if (!new_configs) {
+               dev_err(dev, "krealloc(configs) failed\n");
+               return -ENOMEM;
+       }
+
+       new_configs[old_num] = config;
+
+       *configs = new_configs;
+       *num_configs = new_num;
+
+       return 0;
+}
+
+static void samsung_dt_free_map(struct pinctrl_dev *pctldev,
+                                     struct pinctrl_map *map,
+                                     unsigned num_maps)
+{
+       int i;
+
+       for (i = 0; i < num_maps; i++)
+               if (map[i].type == PIN_MAP_TYPE_CONFIGS_GROUP)
+                       kfree(map[i].data.configs.configs);
+
+       kfree(map);
+}
+
+static int samsung_dt_subnode_to_map(struct samsung_pinctrl_drv_data *drvdata,
+                                    struct device *dev,
+                                    struct device_node *np,
+                                    struct pinctrl_map **map,
+                                    unsigned *reserved_maps,
+                                    unsigned *num_maps)
+{
+       int ret, i;
+       u32 val;
+       unsigned long config;
+       unsigned long *configs = NULL;
+       unsigned num_configs = 0;
+       unsigned reserve;
+       struct property *prop;
+       const char *group;
+       bool has_func = false;
+
+       ret = of_property_read_u32(np, "samsung,pin-function", &val);
+       if (!ret)
+               has_func = true;
+
+       for (i = 0; i < ARRAY_SIZE(cfg_params); i++) {
+               ret = of_property_read_u32(np, cfg_params[i].property, &val);
+               if (!ret) {
+                       config = PINCFG_PACK(cfg_params[i].param, val);
+                       ret = add_config(dev, &configs, &num_configs, config);
+                       if (ret < 0)
+                               goto exit;
+               /* EINVAL=missing, which is fine since it's optional */
+               } else if (ret != -EINVAL) {
+                       dev_err(dev, "could not parse property %s\n",
+                               cfg_params[i].property);
+               }
+       }
+
+       reserve = 0;
+       if (has_func)
+               reserve++;
+       if (num_configs)
+               reserve++;
+       ret = of_property_count_strings(np, "samsung,pins");
+       if (ret < 0) {
+               dev_err(dev, "could not parse property samsung,pins\n");
+               goto exit;
+       }
+       reserve *= ret;
+
+       ret = reserve_map(dev, map, reserved_maps, num_maps, reserve);
+       if (ret < 0)
+               goto exit;
+
+       of_property_for_each_string(np, "samsung,pins", prop, group) {
+               if (has_func) {
+                       ret = add_map_mux(map, reserved_maps,
+                                               num_maps, group, np->full_name);
+                       if (ret < 0)
+                               goto exit;
+               }
+
+               if (num_configs) {
+                       ret = add_map_configs(dev, map, reserved_maps,
+                                             num_maps, group, configs,
+                                             num_configs);
+                       if (ret < 0)
+                               goto exit;
+               }
+       }
+
+       ret = 0;
+
+exit:
+       kfree(configs);
+       return ret;
+}
+
+static int samsung_dt_node_to_map(struct pinctrl_dev *pctldev,
+                                       struct device_node *np_config,
+                                       struct pinctrl_map **map,
+                                       unsigned *num_maps)
+{
+       struct samsung_pinctrl_drv_data *drvdata;
+       unsigned reserved_maps;
+       struct device_node *np;
+       int ret;
+
+       drvdata = pinctrl_dev_get_drvdata(pctldev);
+
+       reserved_maps = 0;
+       *map = NULL;
+       *num_maps = 0;
+
+       if (!of_get_child_count(np_config))
+               return samsung_dt_subnode_to_map(drvdata, pctldev->dev,
+                                                       np_config, map,
+                                                       &reserved_maps,
+                                                       num_maps);
+
+       for_each_child_of_node(np_config, np) {
+               ret = samsung_dt_subnode_to_map(drvdata, pctldev->dev, np, map,
+                                               &reserved_maps, num_maps);
+               if (ret < 0) {
+                       samsung_dt_free_map(pctldev, *map, *num_maps);
+                       return ret;
+               }
+       }
+
+       return 0;
+}
+
+/* list of pinctrl callbacks for the pinctrl core */
+static const struct pinctrl_ops samsung_pctrl_ops = {
+       .get_groups_count       = samsung_get_group_count,
+       .get_group_name         = samsung_get_group_name,
+       .get_group_pins         = samsung_get_group_pins,
+       .dt_node_to_map         = samsung_dt_node_to_map,
+       .dt_free_map            = samsung_dt_free_map,
+};
+
+/* check if the selector is a valid pin function selector */
+static int samsung_get_functions_count(struct pinctrl_dev *pctldev)
+{
+       struct samsung_pinctrl_drv_data *drvdata;
+
+       drvdata = pinctrl_dev_get_drvdata(pctldev);
+       return drvdata->nr_functions;
+}
+
+/* return the name of the pin function specified */
+static const char *samsung_pinmux_get_fname(struct pinctrl_dev *pctldev,
+                                               unsigned selector)
+{
+       struct samsung_pinctrl_drv_data *drvdata;
+
+       drvdata = pinctrl_dev_get_drvdata(pctldev);
+       return drvdata->pmx_functions[selector].name;
+}
+
+/* return the groups associated for the specified function selector */
+static int samsung_pinmux_get_groups(struct pinctrl_dev *pctldev,
+               unsigned selector, const char * const **groups,
+               unsigned * const num_groups)
+{
+       struct samsung_pinctrl_drv_data *drvdata;
+
+       drvdata = pinctrl_dev_get_drvdata(pctldev);
+       *groups = drvdata->pmx_functions[selector].groups;
+       *num_groups = drvdata->pmx_functions[selector].num_groups;
+       return 0;
+}
+
+/*
+ * given a pin number that is local to a pin controller, find out the pin bank
+ * and the register base of the pin bank.
+ */
+static void pin_to_reg_bank(struct samsung_pinctrl_drv_data *drvdata,
+                       unsigned pin, void __iomem **reg, u32 *offset,
+                       struct samsung_pin_bank **bank)
+{
+       struct samsung_pin_bank *b;
+
+       b = drvdata->ctrl->pin_banks;
+
+       while ((pin >= b->pin_base) &&
+                       ((b->pin_base + b->nr_pins - 1) < pin))
+               b++;
+
+       *reg = drvdata->virt_base + b->pctl_offset;
+       *offset = pin - b->pin_base;
+       if (bank)
+               *bank = b;
+}
+
+/* enable or disable a pinmux function */
+static void samsung_pinmux_setup(struct pinctrl_dev *pctldev, unsigned selector,
+                                       unsigned group, bool enable)
+{
+       struct samsung_pinctrl_drv_data *drvdata;
+       struct samsung_pin_bank_type *type;
+       struct samsung_pin_bank *bank;
+       void __iomem *reg;
+       u32 mask, shift, data, pin_offset;
+       unsigned long flags;
+       const struct samsung_pmx_func *func;
+       const struct samsung_pin_group *grp;
+
+       drvdata = pinctrl_dev_get_drvdata(pctldev);
+       func = &drvdata->pmx_functions[selector];
+       grp = &drvdata->pin_groups[group];
+
+       pin_to_reg_bank(drvdata, grp->pins[0] - drvdata->ctrl->base,
+                       &reg, &pin_offset, &bank);
+       type = bank->type;
+       mask = (1 << type->fld_width[PINCFG_TYPE_FUNC]) - 1;
+       shift = pin_offset * type->fld_width[PINCFG_TYPE_FUNC];
+       if (shift >= 32) {
+               /* Some banks have two config registers */
+               shift -= 32;
+               reg += 4;
+       }
+
+       spin_lock_irqsave(&bank->slock, flags);
+
+       data = readl(reg + type->reg_offset[PINCFG_TYPE_FUNC]);
+       data &= ~(mask << shift);
+       if (enable)
+               data |= func->val << shift;
+       writel(data, reg + type->reg_offset[PINCFG_TYPE_FUNC]);
+
+       spin_unlock_irqrestore(&bank->slock, flags);
+}
+
+/* enable a specified pinmux by writing to registers */
+static int samsung_pinmux_enable(struct pinctrl_dev *pctldev, unsigned selector,
+                                       unsigned group)
+{
+       samsung_pinmux_setup(pctldev, selector, group, true);
+       return 0;
+}
+
+/* list of pinmux callbacks for the pinmux vertical in pinctrl core */
+static const struct pinmux_ops samsung_pinmux_ops = {
+       .get_functions_count    = samsung_get_functions_count,
+       .get_function_name      = samsung_pinmux_get_fname,
+       .get_function_groups    = samsung_pinmux_get_groups,
+       .enable                 = samsung_pinmux_enable,
+};
+
+/* set or get the pin config settings for a specified pin */
+static int samsung_pinconf_rw(struct pinctrl_dev *pctldev, unsigned int pin,
+                               unsigned long *config, bool set)
+{
+       struct samsung_pinctrl_drv_data *drvdata;
+       struct samsung_pin_bank_type *type;
+       struct samsung_pin_bank *bank;
+       void __iomem *reg_base;
+       enum pincfg_type cfg_type = PINCFG_UNPACK_TYPE(*config);
+       u32 data, width, pin_offset, mask, shift;
+       u32 cfg_value, cfg_reg;
+       unsigned long flags;
+
+       drvdata = pinctrl_dev_get_drvdata(pctldev);
+       pin_to_reg_bank(drvdata, pin - drvdata->ctrl->base, &reg_base,
+                                       &pin_offset, &bank);
+       type = bank->type;
+
+       if (cfg_type >= PINCFG_TYPE_NUM || !type->fld_width[cfg_type])
+               return -EINVAL;
+
+       width = type->fld_width[cfg_type];
+       cfg_reg = type->reg_offset[cfg_type];
+
+       spin_lock_irqsave(&bank->slock, flags);
+
+       mask = (1 << width) - 1;
+       shift = pin_offset * width;
+       data = readl(reg_base + cfg_reg);
+
+       if (set) {
+               cfg_value = PINCFG_UNPACK_VALUE(*config);
+               data &= ~(mask << shift);
+               data |= (cfg_value << shift);
+               writel(data, reg_base + cfg_reg);
+       } else {
+               data >>= shift;
+               data &= mask;
+               *config = PINCFG_PACK(cfg_type, data);
+       }
+
+       spin_unlock_irqrestore(&bank->slock, flags);
+
+       return 0;
+}
+
+/* set the pin config settings for a specified pin */
+static int samsung_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
+                               unsigned long *configs, unsigned num_configs)
+{
+       int i, ret;
+
+       for (i = 0; i < num_configs; i++) {
+               ret = samsung_pinconf_rw(pctldev, pin, &configs[i], true);
+               if (ret < 0)
+                       return ret;
+       } /* for each config */
+
+       return 0;
+}
+
+/* get the pin config settings for a specified pin */
+static int samsung_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
+                                       unsigned long *config)
+{
+       return samsung_pinconf_rw(pctldev, pin, config, false);
+}
+
+/* set the pin config settings for a specified pin group */
+static int samsung_pinconf_group_set(struct pinctrl_dev *pctldev,
+                       unsigned group, unsigned long *configs,
+                       unsigned num_configs)
+{
+       struct samsung_pinctrl_drv_data *drvdata;
+       const unsigned int *pins;
+       unsigned int cnt;
+
+       drvdata = pinctrl_dev_get_drvdata(pctldev);
+       pins = drvdata->pin_groups[group].pins;
+
+       for (cnt = 0; cnt < drvdata->pin_groups[group].num_pins; cnt++)
+               samsung_pinconf_set(pctldev, pins[cnt], configs, num_configs);
+
+       return 0;
+}
+
+/* get the pin config settings for a specified pin group */
+static int samsung_pinconf_group_get(struct pinctrl_dev *pctldev,
+                               unsigned int group, unsigned long *config)
+{
+       struct samsung_pinctrl_drv_data *drvdata;
+       const unsigned int *pins;
+
+       drvdata = pinctrl_dev_get_drvdata(pctldev);
+       pins = drvdata->pin_groups[group].pins;
+       samsung_pinconf_get(pctldev, pins[0], config);
+       return 0;
+}
+
+/* list of pinconfig callbacks for pinconfig vertical in the pinctrl code */
+static const struct pinconf_ops samsung_pinconf_ops = {
+       .pin_config_get         = samsung_pinconf_get,
+       .pin_config_set         = samsung_pinconf_set,
+       .pin_config_group_get   = samsung_pinconf_group_get,
+       .pin_config_group_set   = samsung_pinconf_group_set,
+};
+
+/* gpiolib gpio_set callback function */
+static void samsung_gpio_set(struct gpio_chip *gc, unsigned offset, int value)
+{
+       struct samsung_pin_bank *bank = gc_to_pin_bank(gc);
+       struct samsung_pin_bank_type *type = bank->type;
+       unsigned long flags;
+       void __iomem *reg;
+       u32 data;
+
+       reg = bank->drvdata->virt_base + bank->pctl_offset;
+
+       spin_lock_irqsave(&bank->slock, flags);
+
+       data = readl(reg + type->reg_offset[PINCFG_TYPE_DAT]);
+       data &= ~(1 << offset);
+       if (value)
+               data |= 1 << offset;
+       writel(data, reg + type->reg_offset[PINCFG_TYPE_DAT]);
+
+       spin_unlock_irqrestore(&bank->slock, flags);
+}
+
+/* gpiolib gpio_get callback function */
+static int samsung_gpio_get(struct gpio_chip *gc, unsigned offset)
+{
+       void __iomem *reg;
+       u32 data;
+       struct samsung_pin_bank *bank = gc_to_pin_bank(gc);
+       struct samsung_pin_bank_type *type = bank->type;
+
+       reg = bank->drvdata->virt_base + bank->pctl_offset;
+
+       data = readl(reg + type->reg_offset[PINCFG_TYPE_DAT]);
+       data >>= offset;
+       data &= 1;
+       return data;
+}
+
+/*
+ * The calls to gpio_direction_output() and gpio_direction_input()
+ * leads to this function call.
+ */
+static int samsung_gpio_set_direction(struct gpio_chip *gc,
+                                            unsigned offset, bool input)
+{
+       struct samsung_pin_bank_type *type;
+       struct samsung_pin_bank *bank;
+       struct samsung_pinctrl_drv_data *drvdata;
+       void __iomem *reg;
+       u32 data, mask, shift;
+       unsigned long flags;
+
+       bank = gc_to_pin_bank(gc);
+       type = bank->type;
+       drvdata = bank->drvdata;
+
+       reg = drvdata->virt_base + bank->pctl_offset +
+                                       type->reg_offset[PINCFG_TYPE_FUNC];
+
+       mask = (1 << type->fld_width[PINCFG_TYPE_FUNC]) - 1;
+       shift = offset * type->fld_width[PINCFG_TYPE_FUNC];
+       if (shift >= 32) {
+               /* Some banks have two config registers */
+               shift -= 32;
+               reg += 4;
+       }
+
+       spin_lock_irqsave(&bank->slock, flags);
+
+       data = readl(reg);
+       data &= ~(mask << shift);
+       if (!input)
+               data |= FUNC_OUTPUT << shift;
+       writel(data, reg);
+
+       spin_unlock_irqrestore(&bank->slock, flags);
+
+       return 0;
+}
+
+/* gpiolib gpio_direction_input callback function. */
+static int samsung_gpio_direction_input(struct gpio_chip *gc, unsigned offset)
+{
+       return samsung_gpio_set_direction(gc, offset, true);
+}
+
+/* gpiolib gpio_direction_output callback function. */
+static int samsung_gpio_direction_output(struct gpio_chip *gc, unsigned offset,
+                                                       int value)
+{
+       samsung_gpio_set(gc, offset, value);
+       return samsung_gpio_set_direction(gc, offset, false);
+}
+
+/*
+ * gpiolib gpio_to_irq callback function. Creates a mapping between a GPIO pin
+ * and a virtual IRQ, if not already present.
+ */
+static int samsung_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
+{
+       struct samsung_pin_bank *bank = gc_to_pin_bank(gc);
+       unsigned int virq;
+
+       if (!bank->irq_domain)
+               return -ENXIO;
+
+       virq = irq_create_mapping(bank->irq_domain, offset);
+
+       return (virq) ? : -ENXIO;
+}
+
+static struct samsung_pin_group *samsung_pinctrl_create_groups(
+                               struct device *dev,
+                               struct samsung_pinctrl_drv_data *drvdata,
+                               unsigned int *cnt)
+{
+       struct pinctrl_desc *ctrldesc = &drvdata->pctl;
+       struct samsung_pin_group *groups, *grp;
+       const struct pinctrl_pin_desc *pdesc;
+       int i;
+
+       groups = devm_kzalloc(dev, ctrldesc->npins * sizeof(*groups),
+                               GFP_KERNEL);
+       if (!groups)
+               return ERR_PTR(-EINVAL);
+       grp = groups;
+
+       pdesc = ctrldesc->pins;
+       for (i = 0; i < ctrldesc->npins; ++i, ++pdesc, ++grp) {
+               grp->name = pdesc->name;
+               grp->pins = &pdesc->number;
+               grp->num_pins = 1;
+       }
+
+       *cnt = ctrldesc->npins;
+       return groups;
+}
+
+static int samsung_pinctrl_create_function(struct device *dev,
+                               struct samsung_pinctrl_drv_data *drvdata,
+                               struct device_node *func_np,
+                               struct samsung_pmx_func *func)
+{
+       int npins;
+       int ret;
+       int i;
+
+       if (of_property_read_u32(func_np, "samsung,pin-function", &func->val))
+               return 0;
+
+       npins = of_property_count_strings(func_np, "samsung,pins");
+       if (npins < 1) {
+               dev_err(dev, "invalid pin list in %s node", func_np->name);
+               return -EINVAL;
+       }
+
+       func->name = func_np->full_name;
+
+       func->groups = devm_kzalloc(dev, npins * sizeof(char *), GFP_KERNEL);
+       if (!func->groups)
+               return -ENOMEM;
+
+       for (i = 0; i < npins; ++i) {
+               const char *gname;
+
+               ret = of_property_read_string_index(func_np, "samsung,pins",
+                                                       i, &gname);
+               if (ret) {
+                       dev_err(dev,
+                               "failed to read pin name %d from %s node\n",
+                               i, func_np->name);
+                       return ret;
+               }
+
+               func->groups[i] = gname;
+       }
+
+       func->num_groups = npins;
+       return 1;
+}
+
+static struct samsung_pmx_func *samsung_pinctrl_create_functions(
+                               struct device *dev,
+                               struct samsung_pinctrl_drv_data *drvdata,
+                               unsigned int *cnt)
+{
+       struct samsung_pmx_func *functions, *func;
+       struct device_node *dev_np = dev->of_node;
+       struct device_node *cfg_np;
+       unsigned int func_cnt = 0;
+       int ret;
+
+       /*
+        * Iterate over all the child nodes of the pin controller node
+        * and create pin groups and pin function lists.
+        */
+       for_each_child_of_node(dev_np, cfg_np) {
+               struct device_node *func_np;
+
+               if (!of_get_child_count(cfg_np)) {
+                       if (!of_find_property(cfg_np,
+                           "samsung,pin-function", NULL))
+                               continue;
+                       ++func_cnt;
+                       continue;
+               }
+
+               for_each_child_of_node(cfg_np, func_np) {
+                       if (!of_find_property(func_np,
+                           "samsung,pin-function", NULL))
+                               continue;
+                       ++func_cnt;
+               }
+       }
+
+       functions = devm_kzalloc(dev, func_cnt * sizeof(*functions),
+                                       GFP_KERNEL);
+       if (!functions) {
+               dev_err(dev, "failed to allocate memory for function list\n");
+               return ERR_PTR(-EINVAL);
+       }
+       func = functions;
+
+       /*
+        * Iterate over all the child nodes of the pin controller node
+        * and create pin groups and pin function lists.
+        */
+       func_cnt = 0;
+       for_each_child_of_node(dev_np, cfg_np) {
+               struct device_node *func_np;
+
+               if (!of_get_child_count(cfg_np)) {
+                       ret = samsung_pinctrl_create_function(dev, drvdata,
+                                                       cfg_np, func);
+                       if (ret < 0)
+                               return ERR_PTR(ret);
+                       if (ret > 0) {
+                               ++func;
+                               ++func_cnt;
+                       }
+                       continue;
+               }
+
+               for_each_child_of_node(cfg_np, func_np) {
+                       ret = samsung_pinctrl_create_function(dev, drvdata,
+                                               func_np, func);
+                       if (ret < 0)
+                               return ERR_PTR(ret);
+                       if (ret > 0) {
+                               ++func;
+                               ++func_cnt;
+                       }
+               }
+       }
+
+       *cnt = func_cnt;
+       return functions;
+}
+
+/*
+ * Parse the information about all the available pin groups and pin functions
+ * from device node of the pin-controller. A pin group is formed with all
+ * the pins listed in the "samsung,pins" property.
+ */
+
+static int samsung_pinctrl_parse_dt(struct platform_device *pdev,
+                                   struct samsung_pinctrl_drv_data *drvdata)
+{
+       struct device *dev = &pdev->dev;
+       struct samsung_pin_group *groups;
+       struct samsung_pmx_func *functions;
+       unsigned int grp_cnt = 0, func_cnt = 0;
+
+       groups = samsung_pinctrl_create_groups(dev, drvdata, &grp_cnt);
+       if (IS_ERR(groups)) {
+               dev_err(dev, "failed to parse pin groups\n");
+               return PTR_ERR(groups);
+       }
+
+       functions = samsung_pinctrl_create_functions(dev, drvdata, &func_cnt);
+       if (IS_ERR(functions)) {
+               dev_err(dev, "failed to parse pin functions\n");
+               return PTR_ERR(groups);
+       }
+
+       drvdata->pin_groups = groups;
+       drvdata->nr_groups = grp_cnt;
+       drvdata->pmx_functions = functions;
+       drvdata->nr_functions = func_cnt;
+
+       return 0;
+}
+
+/* register the pinctrl interface with the pinctrl subsystem */
+static int samsung_pinctrl_register(struct platform_device *pdev,
+                                   struct samsung_pinctrl_drv_data *drvdata)
+{
+       struct pinctrl_desc *ctrldesc = &drvdata->pctl;
+       struct pinctrl_pin_desc *pindesc, *pdesc;
+       struct samsung_pin_bank *pin_bank;
+       char *pin_names;
+       int pin, bank, ret;
+
+       ctrldesc->name = "samsung-pinctrl";
+       ctrldesc->owner = THIS_MODULE;
+       ctrldesc->pctlops = &samsung_pctrl_ops;
+       ctrldesc->pmxops = &samsung_pinmux_ops;
+       ctrldesc->confops = &samsung_pinconf_ops;
+
+       pindesc = devm_kzalloc(&pdev->dev, sizeof(*pindesc) *
+                       drvdata->ctrl->nr_pins, GFP_KERNEL);
+       if (!pindesc) {
+               dev_err(&pdev->dev, "mem alloc for pin descriptors failed\n");
+               return -ENOMEM;
+       }
+       ctrldesc->pins = pindesc;
+       ctrldesc->npins = drvdata->ctrl->nr_pins;
+
+       /* dynamically populate the pin number and pin name for pindesc */
+       for (pin = 0, pdesc = pindesc; pin < ctrldesc->npins; pin++, pdesc++)
+               pdesc->number = pin + drvdata->ctrl->base;
+
+       /*
+        * allocate space for storing the dynamically generated names for all
+        * the pins which belong to this pin-controller.
+        */
+       pin_names = devm_kzalloc(&pdev->dev, sizeof(char) * PIN_NAME_LENGTH *
+                                       drvdata->ctrl->nr_pins, GFP_KERNEL);
+       if (!pin_names) {
+               dev_err(&pdev->dev, "mem alloc for pin names failed\n");
+               return -ENOMEM;
+       }
+
+       /* for each pin, the name of the pin is pin-bank name + pin number */
+       for (bank = 0; bank < drvdata->ctrl->nr_banks; bank++) {
+               pin_bank = &drvdata->ctrl->pin_banks[bank];
+               for (pin = 0; pin < pin_bank->nr_pins; pin++) {
+                       sprintf(pin_names, "%s-%d", pin_bank->name, pin);
+                       pdesc = pindesc + pin_bank->pin_base + pin;
+                       pdesc->name = pin_names;
+                       pin_names += PIN_NAME_LENGTH;
+               }
+       }
+
+       ret = samsung_pinctrl_parse_dt(pdev, drvdata);
+       if (ret)
+               return ret;
+
+       drvdata->pctl_dev = pinctrl_register(ctrldesc, &pdev->dev, drvdata);
+       if (!drvdata->pctl_dev) {
+               dev_err(&pdev->dev, "could not register pinctrl driver\n");
+               return -EINVAL;
+       }
+
+       for (bank = 0; bank < drvdata->ctrl->nr_banks; ++bank) {
+               pin_bank = &drvdata->ctrl->pin_banks[bank];
+               pin_bank->grange.name = pin_bank->name;
+               pin_bank->grange.id = bank;
+               pin_bank->grange.pin_base = drvdata->ctrl->base
+                                               + pin_bank->pin_base;
+               pin_bank->grange.base = pin_bank->gpio_chip.base;
+               pin_bank->grange.npins = pin_bank->gpio_chip.ngpio;
+               pin_bank->grange.gc = &pin_bank->gpio_chip;
+               pinctrl_add_gpio_range(drvdata->pctl_dev, &pin_bank->grange);
+       }
+
+       return 0;
+}
+
+static int samsung_gpio_request(struct gpio_chip *chip, unsigned offset)
+{
+       return pinctrl_request_gpio(chip->base + offset);
+}
+
+static void samsung_gpio_free(struct gpio_chip *chip, unsigned offset)
+{
+       pinctrl_free_gpio(chip->base + offset);
+}
+
+static const struct gpio_chip samsung_gpiolib_chip = {
+       .request = samsung_gpio_request,
+       .free = samsung_gpio_free,
+       .set = samsung_gpio_set,
+       .get = samsung_gpio_get,
+       .direction_input = samsung_gpio_direction_input,
+       .direction_output = samsung_gpio_direction_output,
+       .to_irq = samsung_gpio_to_irq,
+       .owner = THIS_MODULE,
+};
+
+/* register the gpiolib interface with the gpiolib subsystem */
+static int samsung_gpiolib_register(struct platform_device *pdev,
+                                   struct samsung_pinctrl_drv_data *drvdata)
+{
+       struct samsung_pin_ctrl *ctrl = drvdata->ctrl;
+       struct samsung_pin_bank *bank = ctrl->pin_banks;
+       struct gpio_chip *gc;
+       int ret;
+       int i;
+
+       for (i = 0; i < ctrl->nr_banks; ++i, ++bank) {
+               bank->gpio_chip = samsung_gpiolib_chip;
+
+               gc = &bank->gpio_chip;
+               gc->base = ctrl->base + bank->pin_base;
+               gc->ngpio = bank->nr_pins;
+               gc->dev = &pdev->dev;
+               gc->of_node = bank->of_node;
+               gc->label = bank->name;
+
+               ret = gpiochip_add(gc);
+               if (ret) {
+                       dev_err(&pdev->dev, "failed to register gpio_chip %s, error code: %d\n",
+                                                       gc->label, ret);
+                       goto fail;
+               }
+       }
+
+       return 0;
+
+fail:
+       for (--i, --bank; i >= 0; --i, --bank)
+               if (gpiochip_remove(&bank->gpio_chip))
+                       dev_err(&pdev->dev, "gpio chip %s remove failed\n",
+                                                       bank->gpio_chip.label);
+       return ret;
+}
+
+/* unregister the gpiolib interface with the gpiolib subsystem */
+static int samsung_gpiolib_unregister(struct platform_device *pdev,
+                                     struct samsung_pinctrl_drv_data *drvdata)
+{
+       struct samsung_pin_ctrl *ctrl = drvdata->ctrl;
+       struct samsung_pin_bank *bank = ctrl->pin_banks;
+       int ret = 0;
+       int i;
+
+       for (i = 0; !ret && i < ctrl->nr_banks; ++i, ++bank)
+               ret = gpiochip_remove(&bank->gpio_chip);
+
+       if (ret)
+               dev_err(&pdev->dev, "gpio chip remove failed\n");
+
+       return ret;
+}
+
+static const struct of_device_id samsung_pinctrl_dt_match[];
+
+/* retrieve the soc specific data */
+static struct samsung_pin_ctrl *samsung_pinctrl_get_soc_data(
+                               struct samsung_pinctrl_drv_data *d,
+                               struct platform_device *pdev)
+{
+       int id;
+       const struct of_device_id *match;
+       struct device_node *node = pdev->dev.of_node;
+       struct device_node *np;
+       struct samsung_pin_ctrl *ctrl;
+       struct samsung_pin_bank *bank;
+       int i;
+
+       id = of_alias_get_id(node, "pinctrl");
+       if (id < 0) {
+               dev_err(&pdev->dev, "failed to get alias id\n");
+               return NULL;
+       }
+       match = of_match_node(samsung_pinctrl_dt_match, node);
+       ctrl = (struct samsung_pin_ctrl *)match->data + id;
+
+       bank = ctrl->pin_banks;
+       for (i = 0; i < ctrl->nr_banks; ++i, ++bank) {
+               spin_lock_init(&bank->slock);
+               bank->drvdata = d;
+               bank->pin_base = ctrl->nr_pins;
+               ctrl->nr_pins += bank->nr_pins;
+       }
+
+       for_each_child_of_node(node, np) {
+               if (!of_find_property(np, "gpio-controller", NULL))
+                       continue;
+               bank = ctrl->pin_banks;
+               for (i = 0; i < ctrl->nr_banks; ++i, ++bank) {
+                       if (!strcmp(bank->name, np->name)) {
+                               bank->of_node = np;
+                               break;
+                       }
+               }
+       }
+
+       ctrl->base = pin_base;
+       pin_base += ctrl->nr_pins;
+
+       return ctrl;
+}
+
+static int samsung_pinctrl_probe(struct platform_device *pdev)
+{
+       struct samsung_pinctrl_drv_data *drvdata;
+       struct device *dev = &pdev->dev;
+       struct samsung_pin_ctrl *ctrl;
+       struct resource *res;
+       int ret;
+
+       if (!dev->of_node) {
+               dev_err(dev, "device tree node not found\n");
+               return -ENODEV;
+       }
+
+       drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
+       if (!drvdata) {
+               dev_err(dev, "failed to allocate memory for driver's "
+                               "private data\n");
+               return -ENOMEM;
+       }
+
+       ctrl = samsung_pinctrl_get_soc_data(drvdata, pdev);
+       if (!ctrl) {
+               dev_err(&pdev->dev, "driver data not available\n");
+               return -EINVAL;
+       }
+       drvdata->ctrl = ctrl;
+       drvdata->dev = dev;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       drvdata->virt_base = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(drvdata->virt_base))
+               return PTR_ERR(drvdata->virt_base);
+
+       res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+       if (res)
+               drvdata->irq = res->start;
+
+       ret = samsung_gpiolib_register(pdev, drvdata);
+       if (ret)
+               return ret;
+
+       ret = samsung_pinctrl_register(pdev, drvdata);
+       if (ret) {
+               samsung_gpiolib_unregister(pdev, drvdata);
+               return ret;
+       }
+
+       if (ctrl->eint_gpio_init)
+               ctrl->eint_gpio_init(drvdata);
+       if (ctrl->eint_wkup_init)
+               ctrl->eint_wkup_init(drvdata);
+
+       platform_set_drvdata(pdev, drvdata);
+
+       /* Add to the global list */
+       list_add_tail(&drvdata->node, &drvdata_list);
+
+       return 0;
+}
+
+#ifdef CONFIG_PM
+
+/**
+ * samsung_pinctrl_suspend_dev - save pinctrl state for suspend for a device
+ *
+ * Save data for all banks handled by this device.
+ */
+static void samsung_pinctrl_suspend_dev(
+       struct samsung_pinctrl_drv_data *drvdata)
+{
+       struct samsung_pin_ctrl *ctrl = drvdata->ctrl;
+       void __iomem *virt_base = drvdata->virt_base;
+       int i;
+
+       for (i = 0; i < ctrl->nr_banks; i++) {
+               struct samsung_pin_bank *bank = &ctrl->pin_banks[i];
+               void __iomem *reg = virt_base + bank->pctl_offset;
+
+               u8 *offs = bank->type->reg_offset;
+               u8 *widths = bank->type->fld_width;
+               enum pincfg_type type;
+
+               /* Registers without a powerdown config aren't lost */
+               if (!widths[PINCFG_TYPE_CON_PDN])
+                       continue;
+
+               for (type = 0; type < PINCFG_TYPE_NUM; type++)
+                       if (widths[type])
+                               bank->pm_save[type] = readl(reg + offs[type]);
+
+               if (widths[PINCFG_TYPE_FUNC] * bank->nr_pins > 32) {
+                       /* Some banks have two config registers */
+                       bank->pm_save[PINCFG_TYPE_NUM] =
+                               readl(reg + offs[PINCFG_TYPE_FUNC] + 4);
+                       pr_debug("Save %s @ %p (con %#010x %08x)\n",
+                                bank->name, reg,
+                                bank->pm_save[PINCFG_TYPE_FUNC],
+                                bank->pm_save[PINCFG_TYPE_NUM]);
+               } else {
+                       pr_debug("Save %s @ %p (con %#010x)\n", bank->name,
+                                reg, bank->pm_save[PINCFG_TYPE_FUNC]);
+               }
+       }
+
+       if (ctrl->suspend)
+               ctrl->suspend(drvdata);
+}
+
+/**
+ * samsung_pinctrl_resume_dev - restore pinctrl state from suspend for a device
+ *
+ * Restore one of the banks that was saved during suspend.
+ *
+ * We don't bother doing anything complicated to avoid glitching lines since
+ * we're called before pad retention is turned off.
+ */
+static void samsung_pinctrl_resume_dev(struct samsung_pinctrl_drv_data *drvdata)
+{
+       struct samsung_pin_ctrl *ctrl = drvdata->ctrl;
+       void __iomem *virt_base = drvdata->virt_base;
+       int i;
+
+       if (ctrl->resume)
+               ctrl->resume(drvdata);
+
+       for (i = 0; i < ctrl->nr_banks; i++) {
+               struct samsung_pin_bank *bank = &ctrl->pin_banks[i];
+               void __iomem *reg = virt_base + bank->pctl_offset;
+
+               u8 *offs = bank->type->reg_offset;
+               u8 *widths = bank->type->fld_width;
+               enum pincfg_type type;
+
+               /* Registers without a powerdown config aren't lost */
+               if (!widths[PINCFG_TYPE_CON_PDN])
+                       continue;
+
+               if (widths[PINCFG_TYPE_FUNC] * bank->nr_pins > 32) {
+                       /* Some banks have two config registers */
+                       pr_debug("%s @ %p (con %#010x %08x => %#010x %08x)\n",
+                                bank->name, reg,
+                                readl(reg + offs[PINCFG_TYPE_FUNC]),
+                                readl(reg + offs[PINCFG_TYPE_FUNC] + 4),
+                                bank->pm_save[PINCFG_TYPE_FUNC],
+                                bank->pm_save[PINCFG_TYPE_NUM]);
+                       writel(bank->pm_save[PINCFG_TYPE_NUM],
+                              reg + offs[PINCFG_TYPE_FUNC] + 4);
+               } else {
+                       pr_debug("%s @ %p (con %#010x => %#010x)\n", bank->name,
+                                reg, readl(reg + offs[PINCFG_TYPE_FUNC]),
+                                bank->pm_save[PINCFG_TYPE_FUNC]);
+               }
+               for (type = 0; type < PINCFG_TYPE_NUM; type++)
+                       if (widths[type])
+                               writel(bank->pm_save[type], reg + offs[type]);
+       }
+}
+
+/**
+ * samsung_pinctrl_suspend - save pinctrl state for suspend
+ *
+ * Save data for all banks across all devices.
+ */
+static int samsung_pinctrl_suspend(void)
+{
+       struct samsung_pinctrl_drv_data *drvdata;
+
+       list_for_each_entry(drvdata, &drvdata_list, node) {
+               samsung_pinctrl_suspend_dev(drvdata);
+       }
+
+       return 0;
+}
+
+/**
+ * samsung_pinctrl_resume - restore pinctrl state for suspend
+ *
+ * Restore data for all banks across all devices.
+ */
+static void samsung_pinctrl_resume(void)
+{
+       struct samsung_pinctrl_drv_data *drvdata;
+
+       list_for_each_entry_reverse(drvdata, &drvdata_list, node) {
+               samsung_pinctrl_resume_dev(drvdata);
+       }
+}
+
+#else
+#define samsung_pinctrl_suspend                NULL
+#define samsung_pinctrl_resume         NULL
+#endif
+
+static struct syscore_ops samsung_pinctrl_syscore_ops = {
+       .suspend        = samsung_pinctrl_suspend,
+       .resume         = samsung_pinctrl_resume,
+};
+
+static const struct of_device_id samsung_pinctrl_dt_match[] = {
+#ifdef CONFIG_PINCTRL_EXYNOS
+       { .compatible = "samsung,exynos3250-pinctrl",
+               .data = (void *)exynos3250_pin_ctrl },
+       { .compatible = "samsung,exynos4210-pinctrl",
+               .data = (void *)exynos4210_pin_ctrl },
+       { .compatible = "samsung,exynos4x12-pinctrl",
+               .data = (void *)exynos4x12_pin_ctrl },
+       { .compatible = "samsung,exynos5250-pinctrl",
+               .data = (void *)exynos5250_pin_ctrl },
+       { .compatible = "samsung,exynos5260-pinctrl",
+               .data = (void *)exynos5260_pin_ctrl },
+       { .compatible = "samsung,exynos5420-pinctrl",
+               .data = (void *)exynos5420_pin_ctrl },
+       { .compatible = "samsung,s5pv210-pinctrl",
+               .data = (void *)s5pv210_pin_ctrl },
+#endif
+#ifdef CONFIG_PINCTRL_S3C64XX
+       { .compatible = "samsung,s3c64xx-pinctrl",
+               .data = s3c64xx_pin_ctrl },
+#endif
+#ifdef CONFIG_PINCTRL_S3C24XX
+       { .compatible = "samsung,s3c2412-pinctrl",
+               .data = s3c2412_pin_ctrl },
+       { .compatible = "samsung,s3c2416-pinctrl",
+               .data = s3c2416_pin_ctrl },
+       { .compatible = "samsung,s3c2440-pinctrl",
+               .data = s3c2440_pin_ctrl },
+       { .compatible = "samsung,s3c2450-pinctrl",
+               .data = s3c2450_pin_ctrl },
+#endif
+       {},
+};
+MODULE_DEVICE_TABLE(of, samsung_pinctrl_dt_match);
+
+static struct platform_driver samsung_pinctrl_driver = {
+       .probe          = samsung_pinctrl_probe,
+       .driver = {
+               .name   = "samsung-pinctrl",
+               .owner  = THIS_MODULE,
+               .of_match_table = samsung_pinctrl_dt_match,
+       },
+};
+
+static int __init samsung_pinctrl_drv_register(void)
+{
+       /*
+        * Register syscore ops for save/restore of registers across suspend.
+        * It's important to ensure that this driver is running at an earlier
+        * initcall level than any arch-specific init calls that install syscore
+        * ops that turn off pad retention (like exynos_pm_resume).
+        */
+       register_syscore_ops(&samsung_pinctrl_syscore_ops);
+
+       return platform_driver_register(&samsung_pinctrl_driver);
+}
+postcore_initcall(samsung_pinctrl_drv_register);
+
+static void __exit samsung_pinctrl_drv_unregister(void)
+{
+       platform_driver_unregister(&samsung_pinctrl_driver);
+}
+module_exit(samsung_pinctrl_drv_unregister);
+
+MODULE_AUTHOR("Thomas Abraham <thomas.ab@samsung.com>");
+MODULE_DESCRIPTION("Samsung pinctrl driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.h b/drivers/pinctrl/samsung/pinctrl-samsung.h
new file mode 100644 (file)
index 0000000..2b88232
--- /dev/null
@@ -0,0 +1,251 @@
+/*
+ * pin-controller/pin-mux/pin-config/gpio-driver for Samsung's SoC's.
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ * Copyright (c) 2012 Linaro Ltd
+ *             http://www.linaro.org
+ *
+ * Author: Thomas Abraham <thomas.ab@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __PINCTRL_SAMSUNG_H
+#define __PINCTRL_SAMSUNG_H
+
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/pinctrl/machine.h>
+
+#include <linux/gpio.h>
+
+/* pinmux function number for pin as gpio output line */
+#define FUNC_OUTPUT    0x1
+
+/**
+ * enum pincfg_type - possible pin configuration types supported.
+ * @PINCFG_TYPE_FUNC: Function configuration.
+ * @PINCFG_TYPE_DAT: Pin value configuration.
+ * @PINCFG_TYPE_PUD: Pull up/down configuration.
+ * @PINCFG_TYPE_DRV: Drive strength configuration.
+ * @PINCFG_TYPE_CON_PDN: Pin function in power down mode.
+ * @PINCFG_TYPE_PUD_PDN: Pull up/down configuration in power down mode.
+ */
+enum pincfg_type {
+       PINCFG_TYPE_FUNC,
+       PINCFG_TYPE_DAT,
+       PINCFG_TYPE_PUD,
+       PINCFG_TYPE_DRV,
+       PINCFG_TYPE_CON_PDN,
+       PINCFG_TYPE_PUD_PDN,
+
+       PINCFG_TYPE_NUM
+};
+
+/*
+ * pin configuration (pull up/down and drive strength) type and its value are
+ * packed together into a 16-bits. The upper 8-bits represent the configuration
+ * type and the lower 8-bits hold the value of the configuration type.
+ */
+#define PINCFG_TYPE_MASK               0xFF
+#define PINCFG_VALUE_SHIFT             8
+#define PINCFG_VALUE_MASK              (0xFF << PINCFG_VALUE_SHIFT)
+#define PINCFG_PACK(type, value)       (((value) << PINCFG_VALUE_SHIFT) | type)
+#define PINCFG_UNPACK_TYPE(cfg)                ((cfg) & PINCFG_TYPE_MASK)
+#define PINCFG_UNPACK_VALUE(cfg)       (((cfg) & PINCFG_VALUE_MASK) >> \
+                                               PINCFG_VALUE_SHIFT)
+/**
+ * enum eint_type - possible external interrupt types.
+ * @EINT_TYPE_NONE: bank does not support external interrupts
+ * @EINT_TYPE_GPIO: bank supportes external gpio interrupts
+ * @EINT_TYPE_WKUP: bank supportes external wakeup interrupts
+ * @EINT_TYPE_WKUP_MUX: bank supports multiplexed external wakeup interrupts
+ *
+ * Samsung GPIO controller groups all the available pins into banks. The pins
+ * in a pin bank can support external gpio interrupts or external wakeup
+ * interrupts or no interrupts at all. From a software perspective, the only
+ * difference between external gpio and external wakeup interrupts is that
+ * the wakeup interrupts can additionally wakeup the system if it is in
+ * suspended state.
+ */
+enum eint_type {
+       EINT_TYPE_NONE,
+       EINT_TYPE_GPIO,
+       EINT_TYPE_WKUP,
+       EINT_TYPE_WKUP_MUX,
+};
+
+/* maximum length of a pin in pin descriptor (example: "gpa0-0") */
+#define PIN_NAME_LENGTH        10
+
+#define PIN_GROUP(n, p, f)                             \
+       {                                               \
+               .name           = n,                    \
+               .pins           = p,                    \
+               .num_pins       = ARRAY_SIZE(p),        \
+               .func           = f                     \
+       }
+
+#define PMX_FUNC(n, g)                                 \
+       {                                               \
+               .name           = n,                    \
+               .groups         = g,                    \
+               .num_groups     = ARRAY_SIZE(g),        \
+       }
+
+struct samsung_pinctrl_drv_data;
+
+/**
+ * struct samsung_pin_bank_type: pin bank type description
+ * @fld_width: widths of configuration bitfields (0 if unavailable)
+ * @reg_offset: offsets of configuration registers (don't care of width is 0)
+ */
+struct samsung_pin_bank_type {
+       u8 fld_width[PINCFG_TYPE_NUM];
+       u8 reg_offset[PINCFG_TYPE_NUM];
+};
+
+/**
+ * struct samsung_pin_bank: represent a controller pin-bank.
+ * @type: type of the bank (register offsets and bitfield widths)
+ * @pctl_offset: starting offset of the pin-bank registers.
+ * @pin_base: starting pin number of the bank.
+ * @nr_pins: number of pins included in this bank.
+ * @eint_func: function to set in CON register to configure pin as EINT.
+ * @eint_type: type of the external interrupt supported by the bank.
+ * @eint_mask: bit mask of pins which support EINT function.
+ * @name: name to be prefixed for each pin in this pin bank.
+ * @of_node: OF node of the bank.
+ * @drvdata: link to controller driver data
+ * @irq_domain: IRQ domain of the bank.
+ * @gpio_chip: GPIO chip of the bank.
+ * @grange: linux gpio pin range supported by this bank.
+ * @slock: spinlock protecting bank registers
+ * @pm_save: saved register values during suspend
+ */
+struct samsung_pin_bank {
+       struct samsung_pin_bank_type *type;
+       u32             pctl_offset;
+       u32             pin_base;
+       u8              nr_pins;
+       u8              eint_func;
+       enum eint_type  eint_type;
+       u32             eint_mask;
+       u32             eint_offset;
+       char            *name;
+       void            *soc_priv;
+       struct device_node *of_node;
+       struct samsung_pinctrl_drv_data *drvdata;
+       struct irq_domain *irq_domain;
+       struct gpio_chip gpio_chip;
+       struct pinctrl_gpio_range grange;
+       spinlock_t slock;
+
+       u32 pm_save[PINCFG_TYPE_NUM + 1]; /* +1 to handle double CON registers*/
+};
+
+/**
+ * struct samsung_pin_ctrl: represent a pin controller.
+ * @pin_banks: list of pin banks included in this controller.
+ * @nr_banks: number of pin banks.
+ * @base: starting system wide pin number.
+ * @nr_pins: number of pins supported by the controller.
+ * @eint_gpio_init: platform specific callback to setup the external gpio
+ *     interrupts for the controller.
+ * @eint_wkup_init: platform specific callback to setup the external wakeup
+ *     interrupts for the controller.
+ * @label: for debug information.
+ */
+struct samsung_pin_ctrl {
+       struct samsung_pin_bank *pin_banks;
+       u32             nr_banks;
+
+       u32             base;
+       u32             nr_pins;
+
+       int             (*eint_gpio_init)(struct samsung_pinctrl_drv_data *);
+       int             (*eint_wkup_init)(struct samsung_pinctrl_drv_data *);
+       void            (*suspend)(struct samsung_pinctrl_drv_data *);
+       void            (*resume)(struct samsung_pinctrl_drv_data *);
+
+       char            *label;
+};
+
+/**
+ * struct samsung_pinctrl_drv_data: wrapper for holding driver data together.
+ * @node: global list node
+ * @virt_base: register base address of the controller.
+ * @dev: device instance representing the controller.
+ * @irq: interrpt number used by the controller to notify gpio interrupts.
+ * @ctrl: pin controller instance managed by the driver.
+ * @pctl: pin controller descriptor registered with the pinctrl subsystem.
+ * @pctl_dev: cookie representing pinctrl device instance.
+ * @pin_groups: list of pin groups available to the driver.
+ * @nr_groups: number of such pin groups.
+ * @pmx_functions: list of pin functions available to the driver.
+ * @nr_function: number of such pin functions.
+ */
+struct samsung_pinctrl_drv_data {
+       struct list_head                node;
+       void __iomem                    *virt_base;
+       struct device                   *dev;
+       int                             irq;
+
+       struct samsung_pin_ctrl         *ctrl;
+       struct pinctrl_desc             pctl;
+       struct pinctrl_dev              *pctl_dev;
+
+       const struct samsung_pin_group  *pin_groups;
+       unsigned int                    nr_groups;
+       const struct samsung_pmx_func   *pmx_functions;
+       unsigned int                    nr_functions;
+};
+
+/**
+ * struct samsung_pin_group: represent group of pins of a pinmux function.
+ * @name: name of the pin group, used to lookup the group.
+ * @pins: the pins included in this group.
+ * @num_pins: number of pins included in this group.
+ * @func: the function number to be programmed when selected.
+ */
+struct samsung_pin_group {
+       const char              *name;
+       const unsigned int      *pins;
+       u8                      num_pins;
+       u8                      func;
+};
+
+/**
+ * struct samsung_pmx_func: represent a pin function.
+ * @name: name of the pin function, used to lookup the function.
+ * @groups: one or more names of pin groups that provide this function.
+ * @num_groups: number of groups included in @groups.
+ */
+struct samsung_pmx_func {
+       const char              *name;
+       const char              **groups;
+       u8                      num_groups;
+       u32                     val;
+};
+
+/* list of all exported SoC specific data */
+extern struct samsung_pin_ctrl exynos3250_pin_ctrl[];
+extern struct samsung_pin_ctrl exynos4210_pin_ctrl[];
+extern struct samsung_pin_ctrl exynos4x12_pin_ctrl[];
+extern struct samsung_pin_ctrl exynos5250_pin_ctrl[];
+extern struct samsung_pin_ctrl exynos5260_pin_ctrl[];
+extern struct samsung_pin_ctrl exynos5420_pin_ctrl[];
+extern struct samsung_pin_ctrl s3c64xx_pin_ctrl[];
+extern struct samsung_pin_ctrl s3c2412_pin_ctrl[];
+extern struct samsung_pin_ctrl s3c2416_pin_ctrl[];
+extern struct samsung_pin_ctrl s3c2440_pin_ctrl[];
+extern struct samsung_pin_ctrl s3c2450_pin_ctrl[];
+extern struct samsung_pin_ctrl s5pv210_pin_ctrl[];
+
+#endif /* __PINCTRL_SAMSUNG_H */
index a9288ab01f7ba50e2ee7a144fb7ad2c3038a1397..80f641ee4dea31468d60de86127b979947078c22 100644 (file)
@@ -409,11 +409,8 @@ int sh_pfc_register_gpiochip(struct sh_pfc *pfc)
 
 int sh_pfc_unregister_gpiochip(struct sh_pfc *pfc)
 {
-       int err;
-       int ret;
-
-       ret = gpiochip_remove(&pfc->gpio->gpio_chip);
-       err = gpiochip_remove(&pfc->func->gpio_chip);
+       gpiochip_remove(&pfc->gpio->gpio_chip);
+       gpiochip_remove(&pfc->func->gpio_chip);
 
-       return ret < 0 ? ret : err;
+       return 0;
 }
index 2e688dc4a3c8393a69928ba16a75828549ba7b96..576d41b459e97fd4f3675e2a8f1cf981a3a2b410 100644 (file)
@@ -1726,6 +1726,133 @@ static const unsigned int audio_clkout_mux[] = {
        AUDIO_CLKOUT_MARK,
 };
 
+/* - CAN -------------------------------------------------------------------- */
+
+static const unsigned int can0_data_pins[] = {
+       /* TX, RX */
+       RCAR_GP_PIN(3, 26), RCAR_GP_PIN(3, 29),
+};
+
+static const unsigned int can0_data_mux[] = {
+       CAN0_TX_MARK, CAN0_RX_MARK,
+};
+
+static const unsigned int can0_data_b_pins[] = {
+       /* TX, RX */
+       RCAR_GP_PIN(7, 4), RCAR_GP_PIN(7, 3),
+};
+
+static const unsigned int can0_data_b_mux[] = {
+       CAN0_TX_B_MARK, CAN0_RX_B_MARK,
+};
+
+static const unsigned int can0_data_c_pins[] = {
+       /* TX, RX */
+       RCAR_GP_PIN(5, 17), RCAR_GP_PIN(5, 18),
+};
+
+static const unsigned int can0_data_c_mux[] = {
+       CAN0_TX_C_MARK, CAN0_RX_C_MARK,
+};
+
+static const unsigned int can0_data_d_pins[] = {
+       /* TX, RX */
+       RCAR_GP_PIN(2, 26), RCAR_GP_PIN(2, 27),
+};
+
+static const unsigned int can0_data_d_mux[] = {
+       CAN0_TX_D_MARK, CAN0_RX_D_MARK,
+};
+
+static const unsigned int can0_data_e_pins[] = {
+       /* TX, RX */
+       RCAR_GP_PIN(4, 18), RCAR_GP_PIN(4, 28),
+};
+
+static const unsigned int can0_data_e_mux[] = {
+       CAN0_TX_E_MARK, CAN0_RX_E_MARK,
+};
+
+static const unsigned int can0_data_f_pins[] = {
+       /* TX, RX */
+       RCAR_GP_PIN(6, 7), RCAR_GP_PIN(6, 6),
+};
+
+static const unsigned int can0_data_f_mux[] = {
+       CAN0_TX_F_MARK, CAN0_RX_F_MARK,
+};
+
+static const unsigned int can1_data_pins[] = {
+       /* TX, RX */
+        RCAR_GP_PIN(3, 21), RCAR_GP_PIN(3, 20),
+};
+
+static const unsigned int can1_data_mux[] = {
+       CAN1_TX_MARK, CAN1_RX_MARK,
+};
+
+static const unsigned int can1_data_b_pins[] = {
+       /* TX, RX */
+       RCAR_GP_PIN(7, 8), RCAR_GP_PIN(7, 9),
+};
+
+static const unsigned int can1_data_b_mux[] = {
+       CAN1_TX_B_MARK, CAN1_RX_B_MARK,
+};
+
+static const unsigned int can1_data_c_pins[] = {
+       /* TX, RX */
+       RCAR_GP_PIN(5, 20), RCAR_GP_PIN(5, 19),
+};
+
+static const unsigned int can1_data_c_mux[] = {
+       CAN1_TX_C_MARK, CAN1_RX_C_MARK,
+};
+
+static const unsigned int can1_data_d_pins[] = {
+       /* TX, RX */
+        RCAR_GP_PIN(4, 29), RCAR_GP_PIN(4, 31),
+};
+
+static const unsigned int can1_data_d_mux[] = {
+       CAN1_TX_D_MARK, CAN1_RX_D_MARK,
+};
+
+static const unsigned int can_clk_pins[] = {
+       /* CLK */
+       RCAR_GP_PIN(7, 2),
+};
+
+static const unsigned int can_clk_mux[] = {
+       CAN_CLK_MARK,
+};
+
+static const unsigned int can_clk_b_pins[] = {
+       /* CLK */
+       RCAR_GP_PIN(5, 21),
+};
+
+static const unsigned int can_clk_b_mux[] = {
+       CAN_CLK_B_MARK,
+};
+
+static const unsigned int can_clk_c_pins[] = {
+       /* CLK */
+       RCAR_GP_PIN(4, 30),
+};
+
+static const unsigned int can_clk_c_mux[] = {
+       CAN_CLK_C_MARK,
+};
+
+static const unsigned int can_clk_d_pins[] = {
+       /* CLK */
+       RCAR_GP_PIN(7, 19),
+};
+
+static const unsigned int can_clk_d_mux[] = {
+       CAN_CLK_D_MARK,
+};
 
 /* - DU --------------------------------------------------------------------- */
 static const unsigned int du_rgb666_pins[] = {
@@ -1867,6 +1994,192 @@ static const unsigned int eth_rmii_mux[] = {
        ETH_RXD0_MARK, ETH_RXD1_MARK, ETH_RX_ER_MARK, ETH_CRS_DV_MARK,
        ETH_TXD0_MARK, ETH_TXD1_MARK, ETH_TX_EN_MARK, ETH_REFCLK_MARK,
 };
+
+/* - HSCIF0 ----------------------------------------------------------------- */
+static const unsigned int hscif0_data_pins[] = {
+       /* RX, TX */
+       RCAR_GP_PIN(7, 3), RCAR_GP_PIN(7, 4),
+};
+static const unsigned int hscif0_data_mux[] = {
+       HRX0_MARK, HTX0_MARK,
+};
+static const unsigned int hscif0_clk_pins[] = {
+       /* SCK */
+       RCAR_GP_PIN(7, 2),
+};
+static const unsigned int hscif0_clk_mux[] = {
+       HSCK0_MARK,
+};
+static const unsigned int hscif0_ctrl_pins[] = {
+       /* RTS, CTS */
+       RCAR_GP_PIN(7, 1), RCAR_GP_PIN(7, 0),
+};
+static const unsigned int hscif0_ctrl_mux[] = {
+       HRTS0_N_MARK, HCTS0_N_MARK,
+};
+static const unsigned int hscif0_data_b_pins[] = {
+       /* RX, TX */
+       RCAR_GP_PIN(3, 12), RCAR_GP_PIN(3, 15),
+};
+static const unsigned int hscif0_data_b_mux[] = {
+       HRX0_B_MARK, HTX0_B_MARK,
+};
+static const unsigned int hscif0_ctrl_b_pins[] = {
+       /* RTS, CTS */
+       RCAR_GP_PIN(3, 14), RCAR_GP_PIN(3, 13),
+};
+static const unsigned int hscif0_ctrl_b_mux[] = {
+       HRTS0_N_B_MARK, HCTS0_N_B_MARK,
+};
+static const unsigned int hscif0_data_c_pins[] = {
+       /* RX, TX */
+       RCAR_GP_PIN(2, 0), RCAR_GP_PIN(2, 1),
+};
+static const unsigned int hscif0_data_c_mux[] = {
+       HRX0_C_MARK, HTX0_C_MARK,
+};
+static const unsigned int hscif0_clk_c_pins[] = {
+       /* SCK */
+       RCAR_GP_PIN(5, 31),
+};
+static const unsigned int hscif0_clk_c_mux[] = {
+       HSCK0_C_MARK,
+};
+/* - HSCIF1 ----------------------------------------------------------------- */
+static const unsigned int hscif1_data_pins[] = {
+       /* RX, TX */
+       RCAR_GP_PIN(7, 5), RCAR_GP_PIN(7, 6),
+};
+static const unsigned int hscif1_data_mux[] = {
+       HRX1_MARK, HTX1_MARK,
+};
+static const unsigned int hscif1_clk_pins[] = {
+       /* SCK */
+       RCAR_GP_PIN(7, 7),
+};
+static const unsigned int hscif1_clk_mux[] = {
+       HSCK1_MARK,
+};
+static const unsigned int hscif1_ctrl_pins[] = {
+       /* RTS, CTS */
+       RCAR_GP_PIN(7, 9), RCAR_GP_PIN(7, 8),
+};
+static const unsigned int hscif1_ctrl_mux[] = {
+       HRTS1_N_MARK, HCTS1_N_MARK,
+};
+static const unsigned int hscif1_data_b_pins[] = {
+       /* RX, TX */
+       RCAR_GP_PIN(1, 17), RCAR_GP_PIN(1, 18),
+};
+static const unsigned int hscif1_data_b_mux[] = {
+       HRX1_B_MARK, HTX1_B_MARK,
+};
+static const unsigned int hscif1_data_c_pins[] = {
+       /* RX, TX */
+       RCAR_GP_PIN(7, 14), RCAR_GP_PIN(7, 15),
+};
+static const unsigned int hscif1_data_c_mux[] = {
+       HRX1_C_MARK, HTX1_C_MARK,
+};
+static const unsigned int hscif1_clk_c_pins[] = {
+       /* SCK */
+       RCAR_GP_PIN(7, 16),
+};
+static const unsigned int hscif1_clk_c_mux[] = {
+       HSCK1_C_MARK,
+};
+static const unsigned int hscif1_ctrl_c_pins[] = {
+       /* RTS, CTS */
+       RCAR_GP_PIN(7, 18), RCAR_GP_PIN(7, 17),
+};
+static const unsigned int hscif1_ctrl_c_mux[] = {
+       HRTS1_N_C_MARK, HCTS1_N_C_MARK,
+};
+static const unsigned int hscif1_data_d_pins[] = {
+       /* RX, TX */
+       RCAR_GP_PIN(4, 28), RCAR_GP_PIN(4, 18),
+};
+static const unsigned int hscif1_data_d_mux[] = {
+       HRX1_D_MARK, HTX1_D_MARK,
+};
+static const unsigned int hscif1_data_e_pins[] = {
+       /* RX, TX */
+       RCAR_GP_PIN(7, 14), RCAR_GP_PIN(7, 15),
+};
+static const unsigned int hscif1_data_e_mux[] = {
+       HRX1_C_MARK, HTX1_C_MARK,
+};
+static const unsigned int hscif1_clk_e_pins[] = {
+       /* SCK */
+       RCAR_GP_PIN(2, 6),
+};
+static const unsigned int hscif1_clk_e_mux[] = {
+       HSCK1_E_MARK,
+};
+static const unsigned int hscif1_ctrl_e_pins[] = {
+       /* RTS, CTS */
+       RCAR_GP_PIN(2, 8), RCAR_GP_PIN(2, 7),
+};
+static const unsigned int hscif1_ctrl_e_mux[] = {
+       HRTS1_N_E_MARK, HCTS1_N_E_MARK,
+};
+/* - HSCIF2 ----------------------------------------------------------------- */
+static const unsigned int hscif2_data_pins[] = {
+       /* RX, TX */
+       RCAR_GP_PIN(4, 16), RCAR_GP_PIN(4, 17),
+};
+static const unsigned int hscif2_data_mux[] = {
+       HRX2_MARK, HTX2_MARK,
+};
+static const unsigned int hscif2_clk_pins[] = {
+       /* SCK */
+       RCAR_GP_PIN(4, 15),
+};
+static const unsigned int hscif2_clk_mux[] = {
+       HSCK2_MARK,
+};
+static const unsigned int hscif2_ctrl_pins[] = {
+       /* RTS, CTS */
+       RCAR_GP_PIN(4, 14), RCAR_GP_PIN(4, 13),
+};
+static const unsigned int hscif2_ctrl_mux[] = {
+       HRTS2_N_MARK, HCTS2_N_MARK,
+};
+static const unsigned int hscif2_data_b_pins[] = {
+       /* RX, TX */
+       RCAR_GP_PIN(1, 20), RCAR_GP_PIN(1, 22),
+};
+static const unsigned int hscif2_data_b_mux[] = {
+       HRX2_B_MARK, HTX2_B_MARK,
+};
+static const unsigned int hscif2_ctrl_b_pins[] = {
+       /* RTS, CTS */
+       RCAR_GP_PIN(1, 23), RCAR_GP_PIN(1, 21),
+};
+static const unsigned int hscif2_ctrl_b_mux[] = {
+       HRTS2_N_B_MARK, HCTS2_N_B_MARK,
+};
+static const unsigned int hscif2_data_c_pins[] = {
+       /* RX, TX */
+       RCAR_GP_PIN(2, 0), RCAR_GP_PIN(2, 1),
+};
+static const unsigned int hscif2_data_c_mux[] = {
+       HRX2_C_MARK, HTX2_C_MARK,
+};
+static const unsigned int hscif2_clk_c_pins[] = {
+       /* SCK */
+       RCAR_GP_PIN(5, 31),
+};
+static const unsigned int hscif2_clk_c_mux[] = {
+       HSCK2_C_MARK,
+};
+static const unsigned int hscif2_data_d_pins[] = {
+       /* RX, TX */
+       RCAR_GP_PIN(1, 20), RCAR_GP_PIN(5, 31),
+};
+static const unsigned int hscif2_data_d_mux[] = {
+       HRX2_B_MARK, HTX2_D_MARK,
+};
 /* - I2C0 ------------------------------------------------------------------- */
 static const unsigned int i2c0_pins[] = {
        /* SCL, SDA */
@@ -3869,6 +4182,20 @@ static const struct sh_pfc_pin_group pinmux_groups[] = {
        SH_PFC_PIN_GROUP(audio_clk_b_b),
        SH_PFC_PIN_GROUP(audio_clk_c),
        SH_PFC_PIN_GROUP(audio_clkout),
+       SH_PFC_PIN_GROUP(can0_data),
+       SH_PFC_PIN_GROUP(can0_data_b),
+       SH_PFC_PIN_GROUP(can0_data_c),
+       SH_PFC_PIN_GROUP(can0_data_d),
+       SH_PFC_PIN_GROUP(can0_data_e),
+       SH_PFC_PIN_GROUP(can0_data_f),
+       SH_PFC_PIN_GROUP(can1_data),
+       SH_PFC_PIN_GROUP(can1_data_b),
+       SH_PFC_PIN_GROUP(can1_data_c),
+       SH_PFC_PIN_GROUP(can1_data_d),
+       SH_PFC_PIN_GROUP(can_clk),
+       SH_PFC_PIN_GROUP(can_clk_b),
+       SH_PFC_PIN_GROUP(can_clk_c),
+       SH_PFC_PIN_GROUP(can_clk_d),
        SH_PFC_PIN_GROUP(du_rgb666),
        SH_PFC_PIN_GROUP(du_rgb888),
        SH_PFC_PIN_GROUP(du_clk_out_0),
@@ -3885,6 +4212,32 @@ static const struct sh_pfc_pin_group pinmux_groups[] = {
        SH_PFC_PIN_GROUP(eth_magic),
        SH_PFC_PIN_GROUP(eth_mdio),
        SH_PFC_PIN_GROUP(eth_rmii),
+       SH_PFC_PIN_GROUP(hscif0_data),
+       SH_PFC_PIN_GROUP(hscif0_clk),
+       SH_PFC_PIN_GROUP(hscif0_ctrl),
+       SH_PFC_PIN_GROUP(hscif0_data_b),
+       SH_PFC_PIN_GROUP(hscif0_ctrl_b),
+       SH_PFC_PIN_GROUP(hscif0_data_c),
+       SH_PFC_PIN_GROUP(hscif0_clk_c),
+       SH_PFC_PIN_GROUP(hscif1_data),
+       SH_PFC_PIN_GROUP(hscif1_clk),
+       SH_PFC_PIN_GROUP(hscif1_ctrl),
+       SH_PFC_PIN_GROUP(hscif1_data_b),
+       SH_PFC_PIN_GROUP(hscif1_data_c),
+       SH_PFC_PIN_GROUP(hscif1_clk_c),
+       SH_PFC_PIN_GROUP(hscif1_ctrl_c),
+       SH_PFC_PIN_GROUP(hscif1_data_d),
+       SH_PFC_PIN_GROUP(hscif1_data_e),
+       SH_PFC_PIN_GROUP(hscif1_clk_e),
+       SH_PFC_PIN_GROUP(hscif1_ctrl_e),
+       SH_PFC_PIN_GROUP(hscif2_data),
+       SH_PFC_PIN_GROUP(hscif2_clk),
+       SH_PFC_PIN_GROUP(hscif2_ctrl),
+       SH_PFC_PIN_GROUP(hscif2_data_b),
+       SH_PFC_PIN_GROUP(hscif2_ctrl_b),
+       SH_PFC_PIN_GROUP(hscif2_data_c),
+       SH_PFC_PIN_GROUP(hscif2_clk_c),
+       SH_PFC_PIN_GROUP(hscif2_data_d),
        SH_PFC_PIN_GROUP(i2c0),
        SH_PFC_PIN_GROUP(i2c0_b),
        SH_PFC_PIN_GROUP(i2c0_c),
@@ -4155,6 +4508,30 @@ static const char * const audio_clk_groups[] = {
        "audio_clkout",
 };
 
+static const char * const can0_groups[] = {
+       "can0_data_a",
+       "can0_data_b",
+       "can0_data_c",
+       "can0_data_d",
+       "can0_data_e",
+       "can0_data_f",
+       "can_clk_a",
+       "can_clk_b",
+       "can_clk_c",
+       "can_clk_d",
+};
+
+static const char * const can1_groups[] = {
+       "can1_data_a",
+       "can1_data_b",
+       "can1_data_c",
+       "can1_data_d",
+       "can_clk_a",
+       "can_clk_b",
+       "can_clk_c",
+       "can_clk_d",
+};
+
 static const char * const du_groups[] = {
        "du_rgb666",
        "du_rgb888",
@@ -4183,6 +4560,41 @@ static const char * const eth_groups[] = {
        "eth_rmii",
 };
 
+static const char * const hscif0_groups[] = {
+       "hscif0_data",
+       "hscif0_clk",
+       "hscif0_ctrl",
+       "hscif0_data_b",
+       "hscif0_ctrl_b",
+       "hscif0_data_c",
+       "hscif0_clk_c",
+};
+
+static const char * const hscif1_groups[] = {
+       "hscif1_data",
+       "hscif1_clk",
+       "hscif1_ctrl",
+       "hscif1_data_b",
+       "hscif1_data_c",
+       "hscif1_clk_c",
+       "hscif1_ctrl_c",
+       "hscif1_data_d",
+       "hscif1_data_e",
+       "hscif1_clk_e",
+       "hscif1_ctrl_e",
+};
+
+static const char * const hscif2_groups[] = {
+       "hscif2_data",
+       "hscif2_clk",
+       "hscif2_ctrl",
+       "hscif2_data_b",
+       "hscif2_ctrl_b",
+       "hscif2_data_c",
+       "hscif2_clk_c",
+       "hscif2_data_d",
+};
+
 static const char * const i2c0_groups[] = {
        "i2c0",
        "i2c0_b",
@@ -4543,10 +4955,15 @@ static const char * const vin2_groups[] = {
 
 static const struct sh_pfc_function pinmux_functions[] = {
        SH_PFC_FUNCTION(audio_clk),
+       SH_PFC_FUNCTION(can0),
+       SH_PFC_FUNCTION(can1),
        SH_PFC_FUNCTION(du),
        SH_PFC_FUNCTION(du0),
        SH_PFC_FUNCTION(du1),
        SH_PFC_FUNCTION(eth),
+       SH_PFC_FUNCTION(hscif0),
+       SH_PFC_FUNCTION(hscif1),
+       SH_PFC_FUNCTION(hscif2),
        SH_PFC_FUNCTION(i2c0),
        SH_PFC_FUNCTION(i2c1),
        SH_PFC_FUNCTION(i2c2),
index ee370de4609aa17bfec30f8ef0518a45be0462c7..0bd8f4401b428301e040652246001776a63e5bf8 100644 (file)
@@ -3842,7 +3842,8 @@ static int sh73a0_pinmux_soc_init(struct sh_pfc *pfc)
        cfg.init_data = &sh73a0_vccq_mc0_init_data;
        cfg.driver_data = pfc;
 
-       data->vccq_mc0 = regulator_register(&sh73a0_vccq_mc0_desc, &cfg);
+       data->vccq_mc0 = devm_regulator_register(pfc->dev,
+                                                &sh73a0_vccq_mc0_desc, &cfg);
        if (IS_ERR(data->vccq_mc0)) {
                ret = PTR_ERR(data->vccq_mc0);
                dev_err(pfc->dev, "Failed to register VCCQ MC0 regulator: %d\n",
@@ -3855,16 +3856,8 @@ static int sh73a0_pinmux_soc_init(struct sh_pfc *pfc)
        return 0;
 }
 
-static void sh73a0_pinmux_soc_exit(struct sh_pfc *pfc)
-{
-       struct sh73a0_pinmux_data *data = pfc->soc_data;
-
-       regulator_unregister(data->vccq_mc0);
-}
-
 static const struct sh_pfc_soc_operations sh73a0_pinmux_ops = {
        .init = sh73a0_pinmux_soc_init,
-       .exit = sh73a0_pinmux_soc_exit,
        .get_bias = sh73a0_pinmux_get_bias,
        .set_bias = sh73a0_pinmux_set_bias,
 };
index e758af95c209324f91d547877bc2b6a9bc2aab1f..11db3ee39d40eaf824c351b0a354d88c8b21b6c6 100644 (file)
@@ -345,27 +345,6 @@ done:
        return ret;
 }
 
-static void sh_pfc_func_disable(struct pinctrl_dev *pctldev, unsigned selector,
-                               unsigned group)
-{
-       struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
-       struct sh_pfc *pfc = pmx->pfc;
-       const struct sh_pfc_pin_group *grp = &pfc->info->groups[group];
-       unsigned long flags;
-       unsigned int i;
-
-       spin_lock_irqsave(&pfc->lock, flags);
-
-       for (i = 0; i < grp->nr_pins; ++i) {
-               int idx = sh_pfc_get_pin_index(pfc, grp->pins[i]);
-               struct sh_pfc_pin_config *cfg = &pmx->configs[idx];
-
-               cfg->type = PINMUX_TYPE_NONE;
-       }
-
-       spin_unlock_irqrestore(&pfc->lock, flags);
-}
-
 static int sh_pfc_gpio_request_enable(struct pinctrl_dev *pctldev,
                                      struct pinctrl_gpio_range *range,
                                      unsigned offset)
@@ -464,7 +443,6 @@ static const struct pinmux_ops sh_pfc_pinmux_ops = {
        .get_function_name      = sh_pfc_get_function_name,
        .get_function_groups    = sh_pfc_get_function_groups,
        .enable                 = sh_pfc_func_enable,
-       .disable                = sh_pfc_func_disable,
        .gpio_request_enable    = sh_pfc_gpio_request_enable,
        .gpio_disable_free      = sh_pfc_gpio_disable_free,
        .gpio_set_direction     = sh_pfc_gpio_set_direction,
index 014f5b1fee551f9ba586fe68908049236c97e0c6..4c1d7c68666d0fca2f2691757a2479eeefc50ab1 100644 (file)
@@ -186,15 +186,6 @@ static int sirfsoc_pinmux_enable(struct pinctrl_dev *pmxdev, unsigned selector,
        return 0;
 }
 
-static void sirfsoc_pinmux_disable(struct pinctrl_dev *pmxdev, unsigned selector,
-       unsigned group)
-{
-       struct sirfsoc_pmx *spmx;
-
-       spmx = pinctrl_dev_get_drvdata(pmxdev);
-       sirfsoc_pinmux_endisable(spmx, selector, false);
-}
-
 static int sirfsoc_pinmux_get_funcs_count(struct pinctrl_dev *pmxdev)
 {
        return sirfsoc_pmxfunc_cnt;
@@ -240,7 +231,6 @@ static int sirfsoc_pinmux_request_gpio(struct pinctrl_dev *pmxdev,
 
 static struct pinmux_ops sirfsoc_pinmux_ops = {
        .enable = sirfsoc_pinmux_enable,
-       .disable = sirfsoc_pinmux_disable,
        .get_functions_count = sirfsoc_pinmux_get_funcs_count,
        .get_function_name = sirfsoc_pinmux_get_func_name,
        .get_function_groups = sirfsoc_pinmux_get_groups,
index 04d93e602674c6f2489bba44c4febd4cc5628cf9..9ef18eb958e15c924eaa0eaedd0ae3ddefb16e29 100644 (file)
@@ -48,6 +48,7 @@ config PINCTRL_SPEAR1340
 config PINCTRL_SPEAR_PLGPIO
        bool "SPEAr SoC PLGPIO Controller"
        depends on GPIOLIB && PINCTRL_SPEAR
+       select GPIOLIB_IRQCHIP
        help
          Say yes here to support PLGPIO controller on ST Microelectronics SPEAr
          SoCs.
index ff2940e9f2a7455cd0c93ac24dff0ce4f70849ad..bddb79105d67fa31118033f985412c70fca15cea 100644 (file)
 
 #include <linux/clk.h>
 #include <linux/err.h>
-#include <linux/gpio.h>
+#include <linux/gpio/driver.h>
 #include <linux/io.h>
-#include <linux/irq.h>
-#include <linux/irqdomain.h>
-#include <linux/irqchip/chained_irq.h>
 #include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
 #include <linux/pinctrl/consumer.h>
 #include <linux/platform_device.h>
 #include <linux/pm.h>
@@ -54,7 +53,6 @@ struct plgpio_regs {
  *
  * lock: lock for guarding gpio registers
  * base: base address of plgpio block
- * irq_base: irq number of plgpio0
  * chip: gpio framework specific chip information structure
  * p2o: function ptr for pin to offset conversion. This is required only for
  *     machines where mapping b/w pin and offset is not 1-to-1.
@@ -68,8 +66,6 @@ struct plgpio {
        spinlock_t              lock;
        void __iomem            *base;
        struct clk              *clk;
-       unsigned                irq_base;
-       struct irq_domain       *irq_domain;
        struct gpio_chip        chip;
        int                     (*p2o)(int pin);        /* pin_to_offset */
        int                     (*o2p)(int offset);     /* offset_to_pin */
@@ -280,21 +276,12 @@ disable_clk:
        pinctrl_free_gpio(gpio);
 }
 
-static int plgpio_to_irq(struct gpio_chip *chip, unsigned offset)
-{
-       struct plgpio *plgpio = container_of(chip, struct plgpio, chip);
-
-       if (IS_ERR_VALUE(plgpio->irq_base))
-               return -EINVAL;
-
-       return irq_find_mapping(plgpio->irq_domain, offset);
-}
-
 /* PLGPIO IRQ */
 static void plgpio_irq_disable(struct irq_data *d)
 {
-       struct plgpio *plgpio = irq_data_get_irq_chip_data(d);
-       int offset = d->irq - plgpio->irq_base;
+       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+       struct plgpio *plgpio = container_of(gc, struct plgpio, chip);
+       int offset = d->hwirq;
        unsigned long flags;
 
        /* get correct offset for "offset" pin */
@@ -311,8 +298,9 @@ static void plgpio_irq_disable(struct irq_data *d)
 
 static void plgpio_irq_enable(struct irq_data *d)
 {
-       struct plgpio *plgpio = irq_data_get_irq_chip_data(d);
-       int offset = d->irq - plgpio->irq_base;
+       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+       struct plgpio *plgpio = container_of(gc, struct plgpio, chip);
+       int offset = d->hwirq;
        unsigned long flags;
 
        /* get correct offset for "offset" pin */
@@ -329,8 +317,9 @@ static void plgpio_irq_enable(struct irq_data *d)
 
 static int plgpio_irq_set_type(struct irq_data *d, unsigned trigger)
 {
-       struct plgpio *plgpio = irq_data_get_irq_chip_data(d);
-       int offset = d->irq - plgpio->irq_base;
+       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+       struct plgpio *plgpio = container_of(gc, struct plgpio, chip);
+       int offset = d->hwirq;
        void __iomem *reg_off;
        unsigned int supported_type = 0, val;
 
@@ -369,7 +358,8 @@ static struct irq_chip plgpio_irqchip = {
 
 static void plgpio_irq_handler(unsigned irq, struct irq_desc *desc)
 {
-       struct plgpio *plgpio = irq_get_handler_data(irq);
+       struct gpio_chip *gc = irq_desc_get_handler_data(desc);
+       struct plgpio *plgpio = container_of(gc, struct plgpio, chip);
        struct irq_chip *irqchip = irq_desc_get_chip(desc);
        int regs_count, count, pin, offset, i = 0;
        unsigned long pending;
@@ -410,7 +400,8 @@ static void plgpio_irq_handler(unsigned irq, struct irq_desc *desc)
 
                        /* get correct irq line number */
                        pin = i * MAX_GPIO_PER_REG + pin;
-                       generic_handle_irq(plgpio_to_irq(&plgpio->chip, pin));
+                       generic_handle_irq(
+                               irq_find_mapping(gc->irqdomain, pin));
                }
        }
        chained_irq_exit(irqchip, desc);
@@ -523,10 +514,9 @@ end:
 }
 static int plgpio_probe(struct platform_device *pdev)
 {
-       struct device_node *np = pdev->dev.of_node;
        struct plgpio *plgpio;
        struct resource *res;
-       int ret, irq, i;
+       int ret, irq;
 
        plgpio = devm_kzalloc(&pdev->dev, sizeof(*plgpio), GFP_KERNEL);
        if (!plgpio) {
@@ -563,7 +553,6 @@ static int plgpio_probe(struct platform_device *pdev)
        platform_set_drvdata(pdev, plgpio);
        spin_lock_init(&plgpio->lock);
 
-       plgpio->irq_base = -1;
        plgpio->chip.base = -1;
        plgpio->chip.request = plgpio_request;
        plgpio->chip.free = plgpio_free;
@@ -571,10 +560,10 @@ static int plgpio_probe(struct platform_device *pdev)
        plgpio->chip.direction_output = plgpio_direction_output;
        plgpio->chip.get = plgpio_get_value;
        plgpio->chip.set = plgpio_set_value;
-       plgpio->chip.to_irq = plgpio_to_irq;
        plgpio->chip.label = dev_name(&pdev->dev);
        plgpio->chip.dev = &pdev->dev;
        plgpio->chip.owner = THIS_MODULE;
+       plgpio->chip.of_node = pdev->dev.of_node;
 
        if (!IS_ERR(plgpio->clk)) {
                ret = clk_prepare(plgpio->clk);
@@ -592,43 +581,32 @@ static int plgpio_probe(struct platform_device *pdev)
 
        irq = platform_get_irq(pdev, 0);
        if (irq < 0) {
-               dev_info(&pdev->dev, "irqs not supported\n");
-               return 0;
-       }
-
-       plgpio->irq_base = irq_alloc_descs(-1, 0, plgpio->chip.ngpio, 0);
-       if (IS_ERR_VALUE(plgpio->irq_base)) {
-               /* we would not support irq for gpio */
-               dev_warn(&pdev->dev, "couldn't allocate irq base\n");
+               dev_info(&pdev->dev, "PLGPIO registered without IRQs\n");
                return 0;
        }
 
-       plgpio->irq_domain = irq_domain_add_legacy(np, plgpio->chip.ngpio,
-                       plgpio->irq_base, 0, &irq_domain_simple_ops, NULL);
-       if (WARN_ON(!plgpio->irq_domain)) {
-               dev_err(&pdev->dev, "irq domain init failed\n");
-               irq_free_descs(plgpio->irq_base, plgpio->chip.ngpio);
-               ret = -ENXIO;
+       ret = gpiochip_irqchip_add(&plgpio->chip,
+                                  &plgpio_irqchip,
+                                  0,
+                                  handle_simple_irq,
+                                  IRQ_TYPE_NONE);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to add irqchip to gpiochip\n");
                goto remove_gpiochip;
        }
 
-       irq_set_chained_handler(irq, plgpio_irq_handler);
-       for (i = 0; i < plgpio->chip.ngpio; i++) {
-               irq_set_chip_and_handler(i + plgpio->irq_base, &plgpio_irqchip,
-                               handle_simple_irq);
-               set_irq_flags(i + plgpio->irq_base, IRQF_VALID);
-               irq_set_chip_data(i + plgpio->irq_base, plgpio);
-       }
+       gpiochip_set_chained_irqchip(&plgpio->chip,
+                                    &plgpio_irqchip,
+                                    irq,
+                                    plgpio_irq_handler);
 
-       irq_set_handler_data(irq, plgpio);
        dev_info(&pdev->dev, "PLGPIO registered with IRQs\n");
 
        return 0;
 
 remove_gpiochip:
        dev_info(&pdev->dev, "Remove gpiochip\n");
-       if (gpiochip_remove(&plgpio->chip))
-               dev_err(&pdev->dev, "unable to remove gpiochip\n");
+       gpiochip_remove(&plgpio->chip);
 unprepare_clk:
        if (!IS_ERR(plgpio->clk))
                clk_unprepare(plgpio->clk);
index 58bf6867aa17b69992aa0038111898526c81d11a..f72cc4e192bd34bb5c6c95defe6f1aff88258530 100644 (file)
@@ -274,12 +274,6 @@ static int spear_pinctrl_enable(struct pinctrl_dev *pctldev, unsigned function,
        return spear_pinctrl_endisable(pctldev, function, group, true);
 }
 
-static void spear_pinctrl_disable(struct pinctrl_dev *pctldev,
-               unsigned function, unsigned group)
-{
-       spear_pinctrl_endisable(pctldev, function, group, false);
-}
-
 /* gpio with pinmux */
 static struct spear_gpio_pingroup *get_gpio_pingroup(struct spear_pmx *pmx,
                unsigned pin)
@@ -345,7 +339,6 @@ static const struct pinmux_ops spear_pinmux_ops = {
        .get_function_name = spear_pinctrl_get_func_name,
        .get_function_groups = spear_pinctrl_get_func_groups,
        .enable = spear_pinctrl_enable,
-       .disable = spear_pinctrl_disable,
        .gpio_request_enable = gpio_request_enable,
        .gpio_disable_free = gpio_disable_free,
 };
index 73e0a305ea13f5ce4251c9ec024b18a6b7784056..a5e10f777ed2f6270db8669e8cda86816af33699 100644 (file)
@@ -1,36 +1,42 @@
 if ARCH_SUNXI
 
-config PINCTRL_SUNXI
-       bool
-
 config PINCTRL_SUNXI_COMMON
        bool
        select PINMUX
        select GENERIC_PINCONF
 
 config PINCTRL_SUN4I_A10
-       def_bool PINCTRL_SUNXI || MACH_SUN4I
+       def_bool MACH_SUN4I
        select PINCTRL_SUNXI_COMMON
 
 config PINCTRL_SUN5I_A10S
-       def_bool PINCTRL_SUNXI || MACH_SUN5I
+       def_bool MACH_SUN5I
        select PINCTRL_SUNXI_COMMON
 
 config PINCTRL_SUN5I_A13
-       def_bool PINCTRL_SUNXI || MACH_SUN5I
+       def_bool MACH_SUN5I
        select PINCTRL_SUNXI_COMMON
 
 config PINCTRL_SUN6I_A31
-       def_bool PINCTRL_SUNXI || MACH_SUN6I
+       def_bool MACH_SUN6I
        select PINCTRL_SUNXI_COMMON
 
 config PINCTRL_SUN6I_A31_R
-       def_bool PINCTRL_SUNXI || MACH_SUN6I
+       def_bool MACH_SUN6I
        depends on RESET_CONTROLLER
        select PINCTRL_SUNXI_COMMON
 
 config PINCTRL_SUN7I_A20
-       def_bool PINCTRL_SUNXI || MACH_SUN7I
+       def_bool MACH_SUN7I
+       select PINCTRL_SUNXI_COMMON
+
+config PINCTRL_SUN8I_A23
+       def_bool MACH_SUN8I
+       select PINCTRL_SUNXI_COMMON
+
+config PINCTRL_SUN8I_A23_R
+       def_bool MACH_SUN8I
+       depends on RESET_CONTROLLER
        select PINCTRL_SUNXI_COMMON
 
 endif
index 0f4461cbe11d66ca85e0f6b423bdb6a22d36f957..e797efb02901f10fca70407051be36c13a78426e 100644 (file)
@@ -8,3 +8,5 @@ obj-$(CONFIG_PINCTRL_SUN5I_A13)         += pinctrl-sun5i-a13.o
 obj-$(CONFIG_PINCTRL_SUN6I_A31)                += pinctrl-sun6i-a31.o
 obj-$(CONFIG_PINCTRL_SUN6I_A31_R)      += pinctrl-sun6i-a31-r.o
 obj-$(CONFIG_PINCTRL_SUN7I_A20)                += pinctrl-sun7i-a20.o
+obj-$(CONFIG_PINCTRL_SUN8I_A23)                += pinctrl-sun8i-a23.o
+obj-$(CONFIG_PINCTRL_SUN8I_A23_R)      += pinctrl-sun8i-a23-r.o
index fa1ff7c7e35714085e00ebbd7f173d3fd3c57979..86b608bedca6ab6d2a6b998fb9ca49a333a4311a 100644 (file)
@@ -1010,6 +1010,7 @@ static const struct sunxi_desc_pin sun4i_a10_pins[] = {
 static const struct sunxi_pinctrl_desc sun4i_a10_pinctrl_data = {
        .pins = sun4i_a10_pins,
        .npins = ARRAY_SIZE(sun4i_a10_pins),
+       .irq_banks = 1,
 };
 
 static int sun4i_a10_pinctrl_probe(struct platform_device *pdev)
index 164d743f526ce72ea1f661ef290dea94b3f0c57f..2fa7430cabafd23043f8bb384ec22231fecbedda 100644 (file)
@@ -661,6 +661,7 @@ static const struct sunxi_desc_pin sun5i_a10s_pins[] = {
 static const struct sunxi_pinctrl_desc sun5i_a10s_pinctrl_data = {
        .pins = sun5i_a10s_pins,
        .npins = ARRAY_SIZE(sun5i_a10s_pins),
+       .irq_banks = 1,
 };
 
 static int sun5i_a10s_pinctrl_probe(struct platform_device *pdev)
index 1188a2b7b9881b5613b06fac3d38b5e17b381c84..e47c33dbae3ab539062b28c762dad7ced64a57ab 100644 (file)
@@ -330,15 +330,12 @@ static const struct sunxi_desc_pin sun5i_a13_pins[] = {
        /* Hole */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 0),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
-                 SUNXI_FUNCTION(0x1, "gpio_out"),
                  SUNXI_FUNCTION_IRQ(0x6, 0)),          /* EINT0 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 1),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
-                 SUNXI_FUNCTION(0x1, "gpio_out"),
                  SUNXI_FUNCTION_IRQ(0x6, 1)),          /* EINT1 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 2),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
-                 SUNXI_FUNCTION(0x1, "gpio_out"),
                  SUNXI_FUNCTION_IRQ(0x6, 2)),          /* EINT2 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 3),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
@@ -382,6 +379,7 @@ static const struct sunxi_desc_pin sun5i_a13_pins[] = {
 static const struct sunxi_pinctrl_desc sun5i_a13_pinctrl_data = {
        .pins = sun5i_a13_pins,
        .npins = ARRAY_SIZE(sun5i_a13_pins),
+       .irq_banks = 1,
 };
 
 static int sun5i_a13_pinctrl_probe(struct platform_device *pdev)
index 8fcba48e0a424b05ed805b4288013689838bca51..9a2517b6511342d6759c80ebdb9eea45c7c39712 100644 (file)
@@ -93,6 +93,7 @@ static const struct sunxi_pinctrl_desc sun6i_a31_r_pinctrl_data = {
        .pins = sun6i_a31_r_pins,
        .npins = ARRAY_SIZE(sun6i_a31_r_pins),
        .pin_base = PL_BASE,
+       .irq_banks = 2,
 };
 
 static int sun6i_a31_r_pinctrl_probe(struct platform_device *pdev)
index 8dea5856458bf1edd2ecb1b938d7720a8fea9947..a2b4b85c5ad551722a72b3ecc735368d7f65d011 100644 (file)
@@ -24,208 +24,244 @@ static const struct sunxi_desc_pin sun6i_a31_pins[] = {
                  SUNXI_FUNCTION(0x1, "gpio_out"),
                  SUNXI_FUNCTION(0x2, "gmac"),          /* TXD0 */
                  SUNXI_FUNCTION(0x3, "lcd1"),          /* D0 */
-                 SUNXI_FUNCTION(0x4, "uart1")),        /* DTR */
+                 SUNXI_FUNCTION(0x4, "uart1"),         /* DTR */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 0)),  /* PA_EINT0 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 1),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
                  SUNXI_FUNCTION(0x2, "gmac"),          /* TXD1 */
                  SUNXI_FUNCTION(0x3, "lcd1"),          /* D1 */
-                 SUNXI_FUNCTION(0x4, "uart1")),        /* DSR */
+                 SUNXI_FUNCTION(0x4, "uart1"),         /* DSR */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 1)),  /* PA_EINT1 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 2),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
                  SUNXI_FUNCTION(0x2, "gmac"),          /* TXD2 */
                  SUNXI_FUNCTION(0x3, "lcd1"),          /* D2 */
-                 SUNXI_FUNCTION(0x4, "uart1")),        /* DCD */
+                 SUNXI_FUNCTION(0x4, "uart1"),         /* DCD */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 2)),  /* PA_EINT2 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 3),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
                  SUNXI_FUNCTION(0x2, "gmac"),          /* TXD3 */
                  SUNXI_FUNCTION(0x3, "lcd1"),          /* D3 */
-                 SUNXI_FUNCTION(0x4, "uart1")),        /* RING */
+                 SUNXI_FUNCTION(0x4, "uart1"),         /* RING */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 3)),  /* PA_EINT3 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 4),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
                  SUNXI_FUNCTION(0x2, "gmac"),          /* TXD4 */
                  SUNXI_FUNCTION(0x3, "lcd1"),          /* D4 */
-                 SUNXI_FUNCTION(0x4, "uart1")),        /* TX */
+                 SUNXI_FUNCTION(0x4, "uart1"),         /* TX */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 4)),  /* PA_EINT4 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 5),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
                  SUNXI_FUNCTION(0x2, "gmac"),          /* TXD5 */
                  SUNXI_FUNCTION(0x3, "lcd1"),          /* D5 */
-                 SUNXI_FUNCTION(0x4, "uart1")),        /* RX */
+                 SUNXI_FUNCTION(0x4, "uart1"),         /* RX */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 5)),  /* PA_EINT5 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 6),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
                  SUNXI_FUNCTION(0x2, "gmac"),          /* TXD6 */
                  SUNXI_FUNCTION(0x3, "lcd1"),          /* D6 */
-                 SUNXI_FUNCTION(0x4, "uart1")),        /* RTS */
+                 SUNXI_FUNCTION(0x4, "uart1"),         /* RTS */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 6)),  /* PA_EINT6 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 7),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
                  SUNXI_FUNCTION(0x2, "gmac"),          /* TXD7 */
                  SUNXI_FUNCTION(0x3, "lcd1"),          /* D7 */
-                 SUNXI_FUNCTION(0x4, "uart1")),        /* CTS */
+                 SUNXI_FUNCTION(0x4, "uart1"),         /* CTS */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 7)),  /* PA_EINT7 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 8),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
                  SUNXI_FUNCTION(0x2, "gmac"),          /* TXCLK */
-                 SUNXI_FUNCTION(0x3, "lcd1")),         /* D8 */
+                 SUNXI_FUNCTION(0x3, "lcd1"),          /* D8 */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 8)),  /* PA_EINT8 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 9),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
                  SUNXI_FUNCTION(0x2, "gmac"),          /* TXEN */
                  SUNXI_FUNCTION(0x3, "lcd1"),          /* D9 */
                  SUNXI_FUNCTION(0x4, "mmc3"),          /* CMD */
-                 SUNXI_FUNCTION(0x5, "mmc2")),         /* CMD */
+                 SUNXI_FUNCTION(0x5, "mmc2"),          /* CMD */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 9)),  /* PA_EINT9 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 10),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
                  SUNXI_FUNCTION(0x2, "gmac"),          /* GTXCLK */
                  SUNXI_FUNCTION(0x3, "lcd1"),          /* D10 */
                  SUNXI_FUNCTION(0x4, "mmc3"),          /* CLK */
-                 SUNXI_FUNCTION(0x5, "mmc2")),         /* CLK */
+                 SUNXI_FUNCTION(0x5, "mmc2"),          /* CLK */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 10)), /* PA_EINT10 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 11),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
                  SUNXI_FUNCTION(0x2, "gmac"),          /* RXD0 */
                  SUNXI_FUNCTION(0x3, "lcd1"),          /* D11 */
                  SUNXI_FUNCTION(0x4, "mmc3"),          /* D0 */
-                 SUNXI_FUNCTION(0x5, "mmc2")),         /* D0 */
+                 SUNXI_FUNCTION(0x5, "mmc2"),          /* D0 */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 11)), /* PA_EINT11 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 12),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
                  SUNXI_FUNCTION(0x2, "gmac"),          /* RXD1 */
                  SUNXI_FUNCTION(0x3, "lcd1"),          /* D12 */
                  SUNXI_FUNCTION(0x4, "mmc3"),          /* D1 */
-                 SUNXI_FUNCTION(0x5, "mmc2")),         /* D1 */
+                 SUNXI_FUNCTION(0x5, "mmc2"),          /* D1 */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 12)), /* PA_EINT12 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 13),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
                  SUNXI_FUNCTION(0x2, "gmac"),          /* RXD2 */
                  SUNXI_FUNCTION(0x3, "lcd1"),          /* D13 */
                  SUNXI_FUNCTION(0x4, "mmc3"),          /* D2 */
-                 SUNXI_FUNCTION(0x5, "mmc2")),         /* D2 */
+                 SUNXI_FUNCTION(0x5, "mmc2"),          /* D2 */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 13)), /* PA_EINT13 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 14),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
                  SUNXI_FUNCTION(0x2, "gmac"),          /* RXD3 */
                  SUNXI_FUNCTION(0x3, "lcd1"),          /* D14 */
                  SUNXI_FUNCTION(0x4, "mmc3"),          /* D3 */
-                 SUNXI_FUNCTION(0x5, "mmc2")),         /* D3 */
+                 SUNXI_FUNCTION(0x5, "mmc2"),          /* D3 */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 14)), /* PA_EINT14 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 15),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
                  SUNXI_FUNCTION(0x2, "gmac"),          /* RXD4 */
-                 SUNXI_FUNCTION(0x3, "lcd1")),         /* D15 */
+                 SUNXI_FUNCTION(0x3, "lcd1"),          /* D15 */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 15)), /* PA_EINT15 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 16),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
                  SUNXI_FUNCTION(0x2, "gmac"),          /* RXD5 */
-                 SUNXI_FUNCTION(0x3, "lcd1")),         /* D16 */
+                 SUNXI_FUNCTION(0x3, "lcd1"),          /* D16 */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 16)), /* PA_EINT16 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 17),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
                  SUNXI_FUNCTION(0x2, "gmac"),          /* RXD6 */
-                 SUNXI_FUNCTION(0x3, "lcd1")),         /* D17 */
+                 SUNXI_FUNCTION(0x3, "lcd1"),          /* D17 */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 17)), /* PA_EINT17 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 18),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
                  SUNXI_FUNCTION(0x2, "gmac"),          /* RXD7 */
-                 SUNXI_FUNCTION(0x3, "lcd1")),         /* D18 */
+                 SUNXI_FUNCTION(0x3, "lcd1"),          /* D18 */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 18)), /* PA_EINT18 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 19),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
                  SUNXI_FUNCTION(0x2, "gmac"),          /* RXDV */
                  SUNXI_FUNCTION(0x3, "lcd1"),          /* D19 */
-                 SUNXI_FUNCTION(0x4, "pwm3")),         /* Positive */
+                 SUNXI_FUNCTION(0x4, "pwm3"),          /* Positive */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 19)), /* PA_EINT19 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 20),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
                  SUNXI_FUNCTION(0x2, "gmac"),          /* RXCLK */
                  SUNXI_FUNCTION(0x3, "lcd1"),          /* D20 */
-                 SUNXI_FUNCTION(0x4, "pwm3")),         /* Negative */
+                 SUNXI_FUNCTION(0x4, "pwm3"),          /* Negative */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 20)), /* PA_EINT20 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 21),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
                  SUNXI_FUNCTION(0x2, "gmac"),          /* TXERR */
                  SUNXI_FUNCTION(0x3, "lcd1"),          /* D21 */
-                 SUNXI_FUNCTION(0x4, "spi3")),         /* CS0 */
+                 SUNXI_FUNCTION(0x4, "spi3"),          /* CS0 */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 21)), /* PA_EINT21 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 22),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
                  SUNXI_FUNCTION(0x2, "gmac"),          /* RXERR */
                  SUNXI_FUNCTION(0x3, "lcd1"),          /* D22 */
-                 SUNXI_FUNCTION(0x4, "spi3")),         /* CLK */
+                 SUNXI_FUNCTION(0x4, "spi3"),          /* CLK */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 22)), /* PA_EINT22 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 23),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
                  SUNXI_FUNCTION(0x2, "gmac"),          /* COL */
                  SUNXI_FUNCTION(0x3, "lcd1"),          /* D23 */
-                 SUNXI_FUNCTION(0x4, "spi3")),         /* MOSI */
+                 SUNXI_FUNCTION(0x4, "spi3"),          /* MOSI */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 23)), /* PA_EINT23 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 24),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
                  SUNXI_FUNCTION(0x2, "gmac"),          /* CRS */
                  SUNXI_FUNCTION(0x3, "lcd1"),          /* CLK */
-                 SUNXI_FUNCTION(0x4, "spi3")),         /* MISO */
+                 SUNXI_FUNCTION(0x4, "spi3"),          /* MISO */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 24)), /* PA_EINT24 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 25),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
                  SUNXI_FUNCTION(0x2, "gmac"),          /* CLKIN */
                  SUNXI_FUNCTION(0x3, "lcd1"),          /* DE */
-                 SUNXI_FUNCTION(0x4, "spi3")),         /* CS1 */
+                 SUNXI_FUNCTION(0x4, "spi3"),          /* CS1 */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 25)), /* PA_EINT25 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 26),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
                  SUNXI_FUNCTION(0x2, "gmac"),          /* MDC */
-                 SUNXI_FUNCTION(0x3, "lcd1")),         /* HSYNC */
+                 SUNXI_FUNCTION(0x3, "lcd1"),          /* HSYNC */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 26)), /* PA_EINT26 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 27),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
                  SUNXI_FUNCTION(0x2, "gmac"),          /* MDIO */
-                 SUNXI_FUNCTION(0x3, "lcd1")),         /* VSYNC */
+                 SUNXI_FUNCTION(0x3, "lcd1"),          /* VSYNC */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 27)), /* PA_EINT27 */
        /* Hole */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 0),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
                  SUNXI_FUNCTION(0x2, "i2s0"),          /* MCLK */
                  SUNXI_FUNCTION(0x3, "uart3"),         /* CTS */
-                 SUNXI_FUNCTION(0x4, "csi")),          /* MCLK1 */
+                 SUNXI_FUNCTION(0x4, "csi"),           /* MCLK1 */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 0)),  /* PB_EINT0 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 1),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
-                 SUNXI_FUNCTION(0x2, "i2s0")),         /* BCLK */
+                 SUNXI_FUNCTION(0x2, "i2s0"),          /* BCLK */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 1)),  /* PB_EINT1 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 2),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
-                 SUNXI_FUNCTION(0x2, "i2s0")),         /* LRCK */
+                 SUNXI_FUNCTION(0x2, "i2s0"),          /* LRCK */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 2)),  /* PB_EINT2 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 3),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
-                 SUNXI_FUNCTION(0x2, "i2s0")),         /* DO0 */
+                 SUNXI_FUNCTION(0x2, "i2s0"),          /* DO0 */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 3)),  /* PB_EINT3 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 4),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
                  SUNXI_FUNCTION(0x2, "i2s0"),          /* DO1 */
-                 SUNXI_FUNCTION(0x3, "uart3")),        /* RTS */
+                 SUNXI_FUNCTION(0x3, "uart3"),         /* RTS */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 4)),  /* PB_EINT4 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 5),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
                  SUNXI_FUNCTION(0x2, "i2s0"),          /* DO2 */
                  SUNXI_FUNCTION(0x3, "uart3"),         /* TX */
-                 SUNXI_FUNCTION(0x4, "i2c3")),         /* SCK */
+                 SUNXI_FUNCTION(0x4, "i2c3"),          /* SCK */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 5)),  /* PB_EINT5 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 6),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
                  SUNXI_FUNCTION(0x2, "i2s0"),          /* DO3 */
                  SUNXI_FUNCTION(0x3, "uart3"),         /* RX */
-                 SUNXI_FUNCTION(0x4, "i2c3")),         /* SDA */
+                 SUNXI_FUNCTION(0x4, "i2c3"),          /* SDA */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 6)),  /* PB_EINT6 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 7),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
-                 SUNXI_FUNCTION(0x3, "i2s0")),         /* DI */
+                 SUNXI_FUNCTION(0x3, "i2s0"),          /* DI */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 7)),  /* PB_EINT7 */
        /* Hole */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 0),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
@@ -510,86 +546,103 @@ static const struct sunxi_desc_pin sun6i_a31_pins[] = {
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
                  SUNXI_FUNCTION(0x2, "csi"),           /* PCLK */
-                 SUNXI_FUNCTION(0x3, "ts")),           /* CLK */
+                 SUNXI_FUNCTION(0x3, "ts"),            /* CLK */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 0)),  /* PE_EINT0 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 1),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
                  SUNXI_FUNCTION(0x2, "csi"),           /* MCLK */
-                 SUNXI_FUNCTION(0x3, "ts")),           /* ERR */
+                 SUNXI_FUNCTION(0x3, "ts"),            /* ERR */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 1)),  /* PE_EINT1 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 2),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
                  SUNXI_FUNCTION(0x2, "csi"),           /* HSYNC */
-                 SUNXI_FUNCTION(0x3, "ts")),           /* SYNC */
+                 SUNXI_FUNCTION(0x3, "ts"),            /* SYNC */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 2)),  /* PE_EINT2 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 3),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
                  SUNXI_FUNCTION(0x2, "csi"),           /* VSYNC */
-                 SUNXI_FUNCTION(0x3, "ts")),           /* DVLD */
+                 SUNXI_FUNCTION(0x3, "ts"),            /* DVLD */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 3)),  /* PE_EINT3 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 4),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
                  SUNXI_FUNCTION(0x2, "csi"),           /* D0 */
-                 SUNXI_FUNCTION(0x3, "uart5")),        /* TX */
+                 SUNXI_FUNCTION(0x3, "uart5"),         /* TX */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 4)),  /* PE_EINT4 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 5),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
                  SUNXI_FUNCTION(0x2, "csi"),           /* D1 */
-                 SUNXI_FUNCTION(0x3, "uart5")),        /* RX */
+                 SUNXI_FUNCTION(0x3, "uart5"),         /* RX */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 5)),  /* PE_EINT5 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 6),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
                  SUNXI_FUNCTION(0x2, "csi"),           /* D2 */
-                 SUNXI_FUNCTION(0x3, "uart5")),        /* RTS */
+                 SUNXI_FUNCTION(0x3, "uart5"),         /* RTS */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 6)),  /* PE_EINT6 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 7),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
                  SUNXI_FUNCTION(0x2, "csi"),           /* D3 */
-                 SUNXI_FUNCTION(0x3, "uart5")),        /* CTS */
+                 SUNXI_FUNCTION(0x3, "uart5"),         /* CTS */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 7)),  /* PE_EINT7 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 8),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
                  SUNXI_FUNCTION(0x2, "csi"),           /* D4 */
-                 SUNXI_FUNCTION(0x3, "ts")),           /* D0 */
+                 SUNXI_FUNCTION(0x3, "ts"),            /* D0 */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 8)),  /* PE_EINT8 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 9),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
                  SUNXI_FUNCTION(0x2, "csi"),           /* D5 */
-                 SUNXI_FUNCTION(0x3, "ts")),           /* D1 */
+                 SUNXI_FUNCTION(0x3, "ts"),            /* D1 */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 9)),  /* PE_EINT9 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 10),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
                  SUNXI_FUNCTION(0x2, "csi"),           /* D6 */
-                 SUNXI_FUNCTION(0x3, "ts")),           /* D2 */
+                 SUNXI_FUNCTION(0x3, "ts"),            /* D2 */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 10)), /* PE_EINT10 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 11),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
                  SUNXI_FUNCTION(0x2, "csi"),           /* D7 */
-                 SUNXI_FUNCTION(0x3, "ts")),           /* D3 */
+                 SUNXI_FUNCTION(0x3, "ts"),            /* D3 */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 11)), /* PE_EINT11 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 12),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
                  SUNXI_FUNCTION(0x2, "csi"),           /* D8 */
-                 SUNXI_FUNCTION(0x3, "ts")),           /* D4 */
+                 SUNXI_FUNCTION(0x3, "ts"),            /* D4 */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 12)), /* PE_EINT12 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 13),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
                  SUNXI_FUNCTION(0x2, "csi"),           /* D9 */
-                 SUNXI_FUNCTION(0x3, "ts")),           /* D5 */
+                 SUNXI_FUNCTION(0x3, "ts"),            /* D5 */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 13)), /* PE_EINT13 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 14),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
                  SUNXI_FUNCTION(0x2, "csi"),           /* D10 */
-                 SUNXI_FUNCTION(0x3, "ts")),           /* D6 */
+                 SUNXI_FUNCTION(0x3, "ts"),            /* D6 */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 14)), /* PE_EINT14 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 15),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
                  SUNXI_FUNCTION(0x2, "csi"),           /* D11 */
-                 SUNXI_FUNCTION(0x3, "ts")),           /* D7 */
+                 SUNXI_FUNCTION(0x3, "ts"),            /* D7 */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 15)), /* PE_EINT15 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 16),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
-                 SUNXI_FUNCTION(0x2, "csi")),          /* MIPI CSI MCLK */
+                 SUNXI_FUNCTION(0x2, "csi"),           /* MIPI CSI MCLK */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 16)), /* PE_EINT16 */
        /* Hole */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 0),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
@@ -625,86 +678,105 @@ static const struct sunxi_desc_pin sun6i_a31_pins[] = {
        SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 0),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
-                 SUNXI_FUNCTION(0x2, "mmc1")),         /* CLK */
+                 SUNXI_FUNCTION(0x2, "mmc1"),          /* CLK */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 0)),  /* PG_EINT0 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 1),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
-                 SUNXI_FUNCTION(0x2, "mmc1")),         /* CMD */
+                 SUNXI_FUNCTION(0x2, "mmc1"),          /* CMD */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 1)),  /* PG_EINT1 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 2),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
-                 SUNXI_FUNCTION(0x2, "mmc1")),         /* D0 */
+                 SUNXI_FUNCTION(0x2, "mmc1"),          /* D0 */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 2)),  /* PG_EINT2 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 3),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
-                 SUNXI_FUNCTION(0x2, "mmc1")),         /* D1 */
+                 SUNXI_FUNCTION(0x2, "mmc1"),          /* D1 */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 3)),  /* PG_EINT3 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 4),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
-                 SUNXI_FUNCTION(0x2, "mmc1")),         /* D2 */
+                 SUNXI_FUNCTION(0x2, "mmc1"),          /* D2 */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 4)),  /* PG_EINT4 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 5),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
-                 SUNXI_FUNCTION(0x2, "mmc1")),         /* D3 */
+                 SUNXI_FUNCTION(0x2, "mmc1"),          /* D3 */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 5)),  /* PG_EINT5 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 6),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
-                 SUNXI_FUNCTION(0x2, "uart2")),        /* TX */
+                 SUNXI_FUNCTION(0x2, "uart2"),         /* TX */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 6)),  /* PG_EINT6 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 7),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
-                 SUNXI_FUNCTION(0x2, "uart2")),        /* RX */
+                 SUNXI_FUNCTION(0x2, "uart2"),         /* RX */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 7)),  /* PG_EINT7 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 8),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
-                 SUNXI_FUNCTION(0x2, "uart2")),        /* RTS */
+                 SUNXI_FUNCTION(0x2, "uart2"),         /* RTS */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 8)),  /* PG_EINT8 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 9),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
-                 SUNXI_FUNCTION(0x2, "uart2")),        /* CTS */
+                 SUNXI_FUNCTION(0x2, "uart2"),         /* CTS */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 9)),  /* PG_EINT9 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 10),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
                  SUNXI_FUNCTION(0x2, "i2c3"),          /* SCK */
-                 SUNXI_FUNCTION(0x3, "usb")),          /* DP3 */
+                 SUNXI_FUNCTION(0x3, "usb"),           /* DP3 */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 10)), /* PG_EINT10 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 11),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
                  SUNXI_FUNCTION(0x2, "i2c3"),          /* SDA */
-                 SUNXI_FUNCTION(0x3, "usb")),          /* DM3 */
+                 SUNXI_FUNCTION(0x3, "usb"),           /* DM3 */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 11)), /* PG_EINT11 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 12),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
                  SUNXI_FUNCTION(0x2, "spi1"),          /* CS1 */
-                 SUNXI_FUNCTION(0x3, "i2s1")),         /* MCLK */
+                 SUNXI_FUNCTION(0x3, "i2s1"),          /* MCLK */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 12)), /* PG_EINT12 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 13),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
                  SUNXI_FUNCTION(0x2, "spi1"),          /* CS0 */
-                 SUNXI_FUNCTION(0x3, "i2s1")),         /* BCLK */
+                 SUNXI_FUNCTION(0x3, "i2s1"),          /* BCLK */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 13)), /* PG_EINT13 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 14),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
                  SUNXI_FUNCTION(0x2, "spi1"),          /* CLK */
-                 SUNXI_FUNCTION(0x3, "i2s1")),         /* LRCK */
+                 SUNXI_FUNCTION(0x3, "i2s1"),          /* LRCK */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 14)), /* PG_EINT14 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 15),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
                  SUNXI_FUNCTION(0x2, "spi1"),          /* MOSI */
-                 SUNXI_FUNCTION(0x3, "i2s1")),         /* DIN */
+                 SUNXI_FUNCTION(0x3, "i2s1"),          /* DIN */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 15)), /* PG_EINT15 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 16),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
                  SUNXI_FUNCTION(0x2, "spi1"),          /* MISO */
-                 SUNXI_FUNCTION(0x3, "i2s1")),         /* DOUT */
+                 SUNXI_FUNCTION(0x3, "i2s1"),          /* DOUT */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 16)), /* PG_EINT16 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 17),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
-                 SUNXI_FUNCTION(0x2, "uart4")),        /* TX */
+                 SUNXI_FUNCTION(0x2, "uart4"),         /* TX */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 17)), /* PG_EINT17 */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 18),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
-                 SUNXI_FUNCTION(0x2, "uart4")),        /* RX */
+                 SUNXI_FUNCTION(0x2, "uart4"),         /* RX */
+                 SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 18)), /* PG_EINT18 */
        /* Hole */
        SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 0),
                  SUNXI_FUNCTION(0x0, "gpio_in"),
@@ -836,6 +908,7 @@ static const struct sunxi_desc_pin sun6i_a31_pins[] = {
 static const struct sunxi_pinctrl_desc sun6i_a31_pinctrl_data = {
        .pins = sun6i_a31_pins,
        .npins = ARRAY_SIZE(sun6i_a31_pins),
+       .irq_banks = 4,
 };
 
 static int sun6i_a31_pinctrl_probe(struct platform_device *pdev)
index d8577ce5f1a405dc49c61e0ddee01b7079bf5563..dac99e02bfdb9bd1bbe9138c98a228fb7797bfd1 100644 (file)
@@ -1036,6 +1036,7 @@ static const struct sunxi_desc_pin sun7i_a20_pins[] = {
 static const struct sunxi_pinctrl_desc sun7i_a20_pinctrl_data = {
        .pins = sun7i_a20_pins,
        .npins = ARRAY_SIZE(sun7i_a20_pins),
+       .irq_banks = 1,
 };
 
 static int sun7i_a20_pinctrl_probe(struct platform_device *pdev)
diff --git a/drivers/pinctrl/sunxi/pinctrl-sun8i-a23-r.c b/drivers/pinctrl/sunxi/pinctrl-sun8i-a23-r.c
new file mode 100644 (file)
index 0000000..90f3b3a
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ * Allwinner A23 SoCs special pins pinctrl driver.
+ *
+ * Copyright (C) 2014 Chen-Yu Tsai
+ * Chen-Yu Tsai <wens@csie.org>
+ *
+ * Copyright (C) 2014 Boris Brezillon
+ * Boris Brezillon <boris.brezillon@free-electrons.com>
+ *
+ * Copyright (C) 2014 Maxime Ripard
+ * Maxime Ripard <maxime.ripard@free-electrons.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/reset.h>
+
+#include "pinctrl-sunxi.h"
+
+static const struct sunxi_desc_pin sun8i_a23_r_pins[] = {
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 0),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "s_rsb"),         /* SCK */
+                 SUNXI_FUNCTION(0x3, "s_twi"),         /* SCK */
+                 SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 0)),  /* PL_EINT0 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 1),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "s_rsb"),         /* SDA */
+                 SUNXI_FUNCTION(0x3, "s_twi"),         /* SDA */
+                 SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 1)),  /* PL_EINT1 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 2),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "s_uart"),        /* TX */
+                 SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 2)),  /* PL_EINT2 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 3),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "s_uart"),        /* RX */
+                 SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 3)),  /* PL_EINT3 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 4),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x3, "s_jtag"),        /* MS */
+                 SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 4)),  /* PL_EINT4 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 5),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x3, "s_jtag"),        /* CK */
+                 SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 5)),  /* PL_EINT5 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 6),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x3, "s_jtag"),        /* DO */
+                 SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 6)),  /* PL_EINT6 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 7),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x3, "s_jtag"),        /* DI */
+                 SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 7)),  /* PL_EINT7 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 8),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "s_twi"),         /* SCK */
+                 SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 8)),  /* PL_EINT8 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 9),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "s_twi"),         /* SDA */
+                 SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 9)),  /* PL_EINT9 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 10),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "s_pwm"),
+                 SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 10)), /* PL_EINT10 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 11),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 11)), /* PL_EINT11 */
+};
+
+static const struct sunxi_pinctrl_desc sun8i_a23_r_pinctrl_data = {
+       .pins = sun8i_a23_r_pins,
+       .npins = ARRAY_SIZE(sun8i_a23_r_pins),
+       .pin_base = PL_BASE,
+       .irq_banks = 1,
+};
+
+static int sun8i_a23_r_pinctrl_probe(struct platform_device *pdev)
+{
+       struct reset_control *rstc;
+       int ret;
+
+       rstc = devm_reset_control_get(&pdev->dev, NULL);
+       if (IS_ERR(rstc)) {
+               dev_err(&pdev->dev, "Reset controller missing\n");
+               return PTR_ERR(rstc);
+       }
+
+       ret = reset_control_deassert(rstc);
+       if (ret)
+               return ret;
+
+       ret = sunxi_pinctrl_init(pdev,
+                                &sun8i_a23_r_pinctrl_data);
+
+       if (ret)
+               reset_control_assert(rstc);
+
+       return ret;
+}
+
+static struct of_device_id sun8i_a23_r_pinctrl_match[] = {
+       { .compatible = "allwinner,sun8i-a23-r-pinctrl", },
+       {}
+};
+MODULE_DEVICE_TABLE(of, sun8i_a23_r_pinctrl_match);
+
+static struct platform_driver sun8i_a23_r_pinctrl_driver = {
+       .probe  = sun8i_a23_r_pinctrl_probe,
+       .driver = {
+               .name           = "sun8i-a23-r-pinctrl",
+               .owner          = THIS_MODULE,
+               .of_match_table = sun8i_a23_r_pinctrl_match,
+       },
+};
+module_platform_driver(sun8i_a23_r_pinctrl_driver);
+
+MODULE_AUTHOR("Chen-Yu Tsai <wens@csie.org>");
+MODULE_AUTHOR("Boris Brezillon <boris.brezillon@free-electrons.com");
+MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com");
+MODULE_DESCRIPTION("Allwinner A23 R_PIO pinctrl driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/pinctrl/sunxi/pinctrl-sun8i-a23.c b/drivers/pinctrl/sunxi/pinctrl-sun8i-a23.c
new file mode 100644 (file)
index 0000000..ac71e8c
--- /dev/null
@@ -0,0 +1,593 @@
+/*
+ * Allwinner A23 SoCs pinctrl driver.
+ *
+ * Copyright (C) 2014 Chen-Yu Tsai
+ *
+ * Chen-Yu Tsai <wens@csie.org>
+ *
+ * Copyright (C) 2014 Maxime Ripard
+ *
+ * Maxime Ripard <maxime.ripard@free-electrons.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/pinctrl/pinctrl.h>
+
+#include "pinctrl-sunxi.h"
+
+static const struct sunxi_desc_pin sun8i_a23_pins[] = {
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 0),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "spi1"),          /* CS */
+                 SUNXI_FUNCTION(0x3, "jtag"),          /* MS0 */
+                 SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 0)),  /* PA_EINT0 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 1),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "spi1"),          /* CLK */
+                 SUNXI_FUNCTION(0x3, "jtag"),          /* CKO */
+                 SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 1)),  /* PA_EINT1 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 2),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "spi1"),          /* MOSI */
+                 SUNXI_FUNCTION(0x3, "jtag"),          /* DOO */
+                 SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 2)),  /* PA_EINT2 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 3),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "spi1"),          /* MISO */
+                 SUNXI_FUNCTION(0x3, "jtag"),          /* DIO */
+                 SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 3)),  /* PA_EINT3 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 4),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "uart4"),         /* TX */
+                 SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 4)),  /* PA_EINT4 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 5),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "uart4"),         /* RX */
+                 SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 5)),  /* PA_EINT5 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 6),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "uart4"),         /* RTS */
+                 SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 6)),  /* PA_EINT6 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 7),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "uart4"),         /* CTS */
+                 SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 7)),  /* PA_EINT7 */
+       /* Hole */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 0),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "uart2"),         /* TX */
+                 SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 0)),  /* PB_EINT0 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 1),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "uart2"),         /* RX */
+                 SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 1)),  /* PB_EINT1 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 2),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "uart2"),         /* RTS */
+                 SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 2)),  /* PB_EINT2 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 3),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "uart2"),         /* CTS */
+                 SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 3)),  /* PB_EINT3 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 4),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "i2s0"),          /* SYNC */
+                 SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 4)),  /* PB_EINT4 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 5),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "i2s0"),          /* DOUT */
+                 SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 5)),  /* PB_EINT5 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 6),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "i2s0"),          /* DIN */
+                 SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 6)),  /* PB_EINT6 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 7),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x3, "i2s0"),          /* DI */
+                 SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 7)),  /* PB_EINT7 */
+       /* Hole */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 0),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "nand0"),         /* WE */
+                 SUNXI_FUNCTION(0x3, "spi0")),         /* MOSI */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 1),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "nand0"),         /* ALE */
+                 SUNXI_FUNCTION(0x3, "spi0")),         /* MISO */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 2),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "nand0"),         /* CLE */
+                 SUNXI_FUNCTION(0x3, "spi0")),         /* CLK */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 3),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "nand0"),         /* CE1 */
+                 SUNXI_FUNCTION(0x3, "spi0")),         /* CS */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 4),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "nand0")),        /* CE0 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 5),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "nand0"),         /* RE */
+                 SUNXI_FUNCTION(0x3, "mmc2")),         /* CLK */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 6),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "nand0"),         /* RB0 */
+                 SUNXI_FUNCTION(0x3, "mmc2")),         /* CMD */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 7),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "nand0")),        /* RB1 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 8),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "nand0"),         /* DQ0 */
+                 SUNXI_FUNCTION(0x3, "mmc2")),         /* D0 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 9),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "nand0"),         /* DQ1 */
+                 SUNXI_FUNCTION(0x3, "mmc2")),         /* D1 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 10),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "nand0"),         /* DQ2 */
+                 SUNXI_FUNCTION(0x3, "mmc2")),         /* D2 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 11),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "nand0"),         /* DQ3 */
+                 SUNXI_FUNCTION(0x3, "mmc2")),         /* D3 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 12),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "nand0"),         /* DQ4 */
+                 SUNXI_FUNCTION(0x3, "mmc2")),         /* D4 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 13),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "nand0"),         /* DQ5 */
+                 SUNXI_FUNCTION(0x3, "mmc2")),         /* D5 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 14),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "nand"),          /* DQ6 */
+                 SUNXI_FUNCTION(0x3, "mmc2")),         /* D6 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 15),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "nand"),          /* DQ7 */
+                 SUNXI_FUNCTION(0x3, "mmc2")),         /* D7 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 16),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "nand"),          /* DQS */
+                 SUNXI_FUNCTION(0x3, "mmc2")),         /* RST */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 17),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "nand0")),        /* CE2 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 18),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "nand0")),        /* CE3 */
+       /* Hole */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 0),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "lcd0")),         /* D0 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 1),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "lcd0")),         /* D1 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 2),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "lcd0"),          /* D2 */
+                 SUNXI_FUNCTION(0x3, "mmc1")),         /* CLK */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 3),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "lcd0"),          /* D3 */
+                 SUNXI_FUNCTION(0x3, "mmc1")),         /* CMD */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 4),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "lcd0"),          /* D4 */
+                 SUNXI_FUNCTION(0x3, "mmc1")),         /* D0 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 5),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "lcd0"),          /* D5 */
+                 SUNXI_FUNCTION(0x3, "mmc1")),         /* D1 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 6),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "lcd0"),          /* D6 */
+                 SUNXI_FUNCTION(0x3, "mmc1")),         /* D2 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 7),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "lcd0"),          /* D7 */
+                 SUNXI_FUNCTION(0x3, "mmc1")),         /* D3 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 8),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "lcd0"),          /* D8 */
+                 SUNXI_FUNCTION(0x3, "uart3")),        /* TX */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 9),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "lcd0"),          /* D9 */
+                 SUNXI_FUNCTION(0x3, "uart3")),        /* RX */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 10),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "lcd0"),          /* D10 */
+                 SUNXI_FUNCTION(0x3, "uart1")),        /* TX */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 11),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "lcd0"),          /* D11 */
+                 SUNXI_FUNCTION(0x3, "uart1")),        /* RX */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 12),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "lcd0"),          /* D12 */
+                 SUNXI_FUNCTION(0x3, "uart1")),        /* RTS */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 13),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "lcd0"),          /* D13 */
+                 SUNXI_FUNCTION(0x3, "uart1")),        /* CTS */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 14),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "lcd0"),          /* D14 */
+                 SUNXI_FUNCTION(0x3, "i2s1")),         /* SYNC */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 15),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "lcd0"),          /* D15 */
+                 SUNXI_FUNCTION(0x3, "i2s1")),         /* CLK */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 16),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "lcd0"),          /* D16 */
+                 SUNXI_FUNCTION(0x3, "i2s1")),         /* DOUT */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 17),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "lcd0"),          /* D17 */
+                 SUNXI_FUNCTION(0x3, "i2s1")),         /* DIN */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 18),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "lcd0"),          /* D18 */
+                 SUNXI_FUNCTION(0x3, "lvds0")),        /* VN0 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 19),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "lcd0"),          /* D19 */
+                 SUNXI_FUNCTION(0x3, "lvds0")),        /* VP0 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 20),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "lcd0"),          /* D20 */
+                 SUNXI_FUNCTION(0x3, "lvds0")),        /* VP1 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 21),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "lcd0"),          /* D21 */
+                 SUNXI_FUNCTION(0x3, "lvds0")),        /* VN1 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 22),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "lcd0"),          /* D22 */
+                 SUNXI_FUNCTION(0x3, "lvds0")),        /* VP2 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 23),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "lcd0"),          /* D23 */
+                 SUNXI_FUNCTION(0x3, "lvds0")),        /* VN2 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 24),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "lcd0"),          /* CLK */
+                 SUNXI_FUNCTION(0x3, "lvds0")),        /* VPC */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 25),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "lcd0"),          /* DE */
+                 SUNXI_FUNCTION(0x3, "lvds0")),        /* VNC */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 26),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "lcd0"),          /* HSYNC */
+                 SUNXI_FUNCTION(0x3, "lvds0")),        /* VP3 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 27),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "lcd0"),          /* VSYNC */
+                 SUNXI_FUNCTION(0x3, "lvds0")),        /* VN3 */
+       /* Hole */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 0),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "csi")),          /* PCLK */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 1),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "csi")),          /* MCLK */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 2),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "csi")),          /* HSYNC */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 3),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "csi")),          /* VSYNC */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 4),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "csi")),          /* D0 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 5),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "csi")),          /* D1 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 6),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "csi")),          /* D2 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 7),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "csi")),          /* D3 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 8),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "csi")),          /* D4 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 9),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "csi")),          /* D5 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 10),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "csi")),          /* D6 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 11),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "csi")),          /* D7 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 12),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "csi"),           /* SCK */
+                 SUNXI_FUNCTION(0x3, "i2c2")),         /* SCK */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 13),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "csi"),           /* SDA */
+                 SUNXI_FUNCTION(0x3, "i2c2")),         /* SDA */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 14),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out")),
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 15),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out")),
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 16),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out")),
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 17),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out")),
+       /* Hole */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 0),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "mmc0"),          /* D1 */
+                 SUNXI_FUNCTION(0x3, "jtag")),         /* MS1 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 1),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "mmc0"),          /* D0 */
+                 SUNXI_FUNCTION(0x3, "jtag")),         /* DI1 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 2),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "mmc0"),          /* CLK */
+                 SUNXI_FUNCTION(0x3, "uart0")),        /* TX */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 3),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "mmc0"),          /* CMD */
+                 SUNXI_FUNCTION(0x3, "jtag")),         /* DO1 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 4),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "mmc0"),          /* D3 */
+                 SUNXI_FUNCTION(0x3, "uart0")),        /* RX */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 5),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "mmc0"),          /* D2 */
+                 SUNXI_FUNCTION(0x3, "jtag")),         /* CK1 */
+       /* Hole */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 0),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "mmc1"),          /* CLK */
+                 SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 0)),  /* PG_EINT0 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 1),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "mmc1"),          /* CMD */
+                 SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 1)),  /* PG_EINT1 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 2),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "mmc1"),          /* D0 */
+                 SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 2)),  /* PG_EINT2 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 3),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "mmc1"),          /* D1 */
+                 SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 3)),  /* PG_EINT3 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 4),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "mmc1"),          /* D2 */
+                 SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 4)),  /* PG_EINT4 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 5),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "mmc1"),          /* D3 */
+                 SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 5)),  /* PG_EINT5 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 6),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "uart1"),         /* TX */
+                 SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 6)),  /* PG_EINT6 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 7),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "uart1"),         /* RX */
+                 SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 7)),  /* PG_EINT7 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 8),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "uart2"),         /* RTS */
+                 SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 8)),  /* PG_EINT8 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 9),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "uart2"),         /* CTS */
+                 SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 9)),  /* PG_EINT9 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 10),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "i2s1"),          /* SYNC */
+                 SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 10)), /* PG_EINT10 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 11),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "i2s1"),          /* CLK */
+                 SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 11)), /* PG_EINT11 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 12),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "i2s1"),          /* DOUT */
+                 SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 12)), /* PG_EINT12 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 13),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "i2s1"),          /* DIN */
+                 SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 13)), /* PG_EINT13 */
+       /* Hole */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 0),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "pwm0")),
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 1),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "pwm1")),
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 2),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "i2c0")),         /* SCK */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 3),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "i2c0")),         /* SDA */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 4),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "i2c1")),         /* SCK */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 5),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "i2c1")),         /* SDA */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 6),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "spi0"),          /* CS */
+                 SUNXI_FUNCTION(0x3, "uart3")),        /* TX */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 7),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "spi0"),          /* CLK */
+                 SUNXI_FUNCTION(0x3, "uart3")),        /* RX */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 8),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "spi0"),          /* DOUT */
+                 SUNXI_FUNCTION(0x3, "uart3")),        /* RTS */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 9),
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "spi0"),          /* DIN */
+                 SUNXI_FUNCTION(0x3, "uart3")),        /* CTS */
+};
+
+static const struct sunxi_pinctrl_desc sun8i_a23_pinctrl_data = {
+       .pins = sun8i_a23_pins,
+       .npins = ARRAY_SIZE(sun8i_a23_pins),
+       .irq_banks = 3,
+};
+
+static int sun8i_a23_pinctrl_probe(struct platform_device *pdev)
+{
+       return sunxi_pinctrl_init(pdev,
+                                 &sun8i_a23_pinctrl_data);
+}
+
+static struct of_device_id sun8i_a23_pinctrl_match[] = {
+       { .compatible = "allwinner,sun8i-a23-pinctrl", },
+       {}
+};
+MODULE_DEVICE_TABLE(of, sun8i_a23_pinctrl_match);
+
+static struct platform_driver sun8i_a23_pinctrl_driver = {
+       .probe  = sun8i_a23_pinctrl_probe,
+       .driver = {
+               .name           = "sun8i-a23-pinctrl",
+               .owner          = THIS_MODULE,
+               .of_match_table = sun8i_a23_pinctrl_match,
+       },
+};
+module_platform_driver(sun8i_a23_pinctrl_driver);
+
+MODULE_AUTHOR("Chen-Yu Tsai <wens@csie.org>");
+MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com");
+MODULE_DESCRIPTION("Allwinner A23 pinctrl driver");
+MODULE_LICENSE("GPL");
index 5f38c7f67834d1cf8bd8bcc2f8d80cd03a76c04a..3df66e366c8775b25768e079d4febb91c8461b4a 100644 (file)
@@ -31,6 +31,9 @@
 #include "../core.h"
 #include "pinctrl-sunxi.h"
 
+static struct irq_chip sunxi_pinctrl_edge_irq_chip;
+static struct irq_chip sunxi_pinctrl_level_irq_chip;
+
 static struct sunxi_pinctrl_group *
 sunxi_pinctrl_find_group_by_name(struct sunxi_pinctrl *pctl, const char *group)
 {
@@ -508,7 +511,7 @@ static int sunxi_pinctrl_gpio_of_xlate(struct gpio_chip *gc,
        base = PINS_PER_BANK * gpiospec->args[0];
        pin = base + gpiospec->args[1];
 
-       if (pin > (gc->base + gc->ngpio))
+       if (pin > gc->ngpio)
                return -EINVAL;
 
        if (flags)
@@ -521,25 +524,61 @@ static int sunxi_pinctrl_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
 {
        struct sunxi_pinctrl *pctl = dev_get_drvdata(chip->dev);
        struct sunxi_desc_function *desc;
+       unsigned pinnum = pctl->desc->pin_base + offset;
+       unsigned irqnum;
 
        if (offset >= chip->ngpio)
                return -ENXIO;
 
-       desc = sunxi_pinctrl_desc_find_function_by_pin(pctl, offset, "irq");
+       desc = sunxi_pinctrl_desc_find_function_by_pin(pctl, pinnum, "irq");
        if (!desc)
                return -EINVAL;
 
+       irqnum = desc->irqbank * IRQ_PER_BANK + desc->irqnum;
+
        dev_dbg(chip->dev, "%s: request IRQ for GPIO %d, return %d\n",
-               chip->label, offset + chip->base, desc->irqnum);
+               chip->label, offset + chip->base, irqnum);
 
-       return irq_find_mapping(pctl->domain, desc->irqnum);
+       return irq_find_mapping(pctl->domain, irqnum);
 }
 
+static int sunxi_pinctrl_irq_request_resources(struct irq_data *d)
+{
+       struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d);
+       struct sunxi_desc_function *func;
+       int ret;
+
+       func = sunxi_pinctrl_desc_find_function_by_pin(pctl,
+                                       pctl->irq_array[d->hwirq], "irq");
+       if (!func)
+               return -EINVAL;
+
+       ret = gpio_lock_as_irq(pctl->chip,
+                       pctl->irq_array[d->hwirq] - pctl->desc->pin_base);
+       if (ret) {
+               dev_err(pctl->dev, "unable to lock HW IRQ %lu for IRQ\n",
+                       irqd_to_hwirq(d));
+               return ret;
+       }
+
+       /* Change muxing to INT mode */
+       sunxi_pmx_set(pctl->pctl_dev, pctl->irq_array[d->hwirq], func->muxval);
 
-static int sunxi_pinctrl_irq_set_type(struct irq_data *d,
-                                     unsigned int type)
+       return 0;
+}
+
+static void sunxi_pinctrl_irq_release_resources(struct irq_data *d)
+{
+       struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d);
+
+       gpio_unlock_as_irq(pctl->chip,
+                          pctl->irq_array[d->hwirq] - pctl->desc->pin_base);
+}
+
+static int sunxi_pinctrl_irq_set_type(struct irq_data *d, unsigned int type)
 {
        struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d);
+       struct irq_desc *desc = container_of(d, struct irq_desc, irq_data);
        u32 reg = sunxi_irq_cfg_reg(d->hwirq);
        u8 index = sunxi_irq_cfg_offset(d->hwirq);
        unsigned long flags;
@@ -566,6 +605,14 @@ static int sunxi_pinctrl_irq_set_type(struct irq_data *d,
                return -EINVAL;
        }
 
+       if (type & IRQ_TYPE_LEVEL_MASK) {
+               d->chip = &sunxi_pinctrl_level_irq_chip;
+               desc->handle_irq = handle_fasteoi_irq;
+       } else {
+               d->chip = &sunxi_pinctrl_edge_irq_chip;
+               desc->handle_irq = handle_edge_irq;
+       }
+
        spin_lock_irqsave(&pctl->lock, flags);
 
        regval = readl(pctl->membase + reg);
@@ -577,26 +624,14 @@ static int sunxi_pinctrl_irq_set_type(struct irq_data *d,
        return 0;
 }
 
-static void sunxi_pinctrl_irq_mask_ack(struct irq_data *d)
+static void sunxi_pinctrl_irq_ack(struct irq_data *d)
 {
        struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d);
-       u32 ctrl_reg = sunxi_irq_ctrl_reg(d->hwirq);
-       u8 ctrl_idx = sunxi_irq_ctrl_offset(d->hwirq);
        u32 status_reg = sunxi_irq_status_reg(d->hwirq);
        u8 status_idx = sunxi_irq_status_offset(d->hwirq);
-       unsigned long flags;
-       u32 val;
-
-       spin_lock_irqsave(&pctl->lock, flags);
-
-       /* Mask the IRQ */
-       val = readl(pctl->membase + ctrl_reg);
-       writel(val & ~(1 << ctrl_idx), pctl->membase + ctrl_reg);
 
        /* Clear the IRQ */
        writel(1 << status_idx, pctl->membase + status_reg);
-
-       spin_unlock_irqrestore(&pctl->lock, flags);
 }
 
 static void sunxi_pinctrl_irq_mask(struct irq_data *d)
@@ -619,19 +654,11 @@ static void sunxi_pinctrl_irq_mask(struct irq_data *d)
 static void sunxi_pinctrl_irq_unmask(struct irq_data *d)
 {
        struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d);
-       struct sunxi_desc_function *func;
        u32 reg = sunxi_irq_ctrl_reg(d->hwirq);
        u8 idx = sunxi_irq_ctrl_offset(d->hwirq);
        unsigned long flags;
        u32 val;
 
-       func = sunxi_pinctrl_desc_find_function_by_pin(pctl,
-                                                      pctl->irq_array[d->hwirq],
-                                                      "irq");
-
-       /* Change muxing to INT mode */
-       sunxi_pmx_set(pctl->pctl_dev, pctl->irq_array[d->hwirq], func->muxval);
-
        spin_lock_irqsave(&pctl->lock, flags);
 
        /* Unmask the IRQ */
@@ -641,28 +668,60 @@ static void sunxi_pinctrl_irq_unmask(struct irq_data *d)
        spin_unlock_irqrestore(&pctl->lock, flags);
 }
 
-static struct irq_chip sunxi_pinctrl_irq_chip = {
+static void sunxi_pinctrl_irq_ack_unmask(struct irq_data *d)
+{
+       sunxi_pinctrl_irq_ack(d);
+       sunxi_pinctrl_irq_unmask(d);
+}
+
+static struct irq_chip sunxi_pinctrl_edge_irq_chip = {
+       .irq_ack        = sunxi_pinctrl_irq_ack,
+       .irq_mask       = sunxi_pinctrl_irq_mask,
+       .irq_unmask     = sunxi_pinctrl_irq_unmask,
+       .irq_request_resources = sunxi_pinctrl_irq_request_resources,
+       .irq_release_resources = sunxi_pinctrl_irq_release_resources,
+       .irq_set_type   = sunxi_pinctrl_irq_set_type,
+       .flags          = IRQCHIP_SKIP_SET_WAKE,
+};
+
+static struct irq_chip sunxi_pinctrl_level_irq_chip = {
+       .irq_eoi        = sunxi_pinctrl_irq_ack,
        .irq_mask       = sunxi_pinctrl_irq_mask,
-       .irq_mask_ack   = sunxi_pinctrl_irq_mask_ack,
        .irq_unmask     = sunxi_pinctrl_irq_unmask,
+       /* Define irq_enable / disable to avoid spurious irqs for drivers
+        * using these to suppress irqs while they clear the irq source */
+       .irq_enable     = sunxi_pinctrl_irq_ack_unmask,
+       .irq_disable    = sunxi_pinctrl_irq_mask,
+       .irq_request_resources = sunxi_pinctrl_irq_request_resources,
+       .irq_release_resources = sunxi_pinctrl_irq_release_resources,
        .irq_set_type   = sunxi_pinctrl_irq_set_type,
+       .flags          = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_EOI_THREADED |
+                         IRQCHIP_EOI_IF_HANDLED,
 };
 
 static void sunxi_pinctrl_irq_handler(unsigned irq, struct irq_desc *desc)
 {
        struct irq_chip *chip = irq_get_chip(irq);
        struct sunxi_pinctrl *pctl = irq_get_handler_data(irq);
-       const unsigned long reg = readl(pctl->membase + IRQ_STATUS_REG);
+       unsigned long bank, reg, val;
+
+       for (bank = 0; bank < pctl->desc->irq_banks; bank++)
+               if (irq == pctl->irq[bank])
+                       break;
+
+       if (bank == pctl->desc->irq_banks)
+               return;
 
-       /* Clear all interrupts */
-       writel(reg, pctl->membase + IRQ_STATUS_REG);
+       reg = sunxi_irq_status_reg_from_bank(bank);
+       val = readl(pctl->membase + reg);
 
-       if (reg) {
+       if (val) {
                int irqoffset;
 
                chained_irq_enter(chip, desc);
-               for_each_set_bit(irqoffset, &reg, SUNXI_IRQ_NUMBER) {
-                       int pin_irq = irq_find_mapping(pctl->domain, irqoffset);
+               for_each_set_bit(irqoffset, &val, IRQ_PER_BANK) {
+                       int pin_irq = irq_find_mapping(pctl->domain,
+                                                      bank * IRQ_PER_BANK + irqoffset);
                        generic_handle_irq(pin_irq);
                }
                chained_irq_exit(chip, desc);
@@ -730,8 +789,11 @@ static int sunxi_pinctrl_build_state(struct platform_device *pdev)
 
                while (func->name) {
                        /* Create interrupt mapping while we're at it */
-                       if (!strcmp(func->name, "irq"))
-                               pctl->irq_array[func->irqnum] = pin->pin.number;
+                       if (!strcmp(func->name, "irq")) {
+                               int irqnum = func->irqnum + func->irqbank * IRQ_PER_BANK;
+                               pctl->irq_array[irqnum] = pin->pin.number;
+                       }
+
                        sunxi_pinctrl_add_function(pctl, func->name);
                        func++;
                }
@@ -801,6 +863,13 @@ int sunxi_pinctrl_init(struct platform_device *pdev,
        pctl->dev = &pdev->dev;
        pctl->desc = desc;
 
+       pctl->irq_array = devm_kcalloc(&pdev->dev,
+                                      IRQ_PER_BANK * pctl->desc->irq_banks,
+                                      sizeof(*pctl->irq_array),
+                                      GFP_KERNEL);
+       if (!pctl->irq_array)
+               return -ENOMEM;
+
        ret = sunxi_pinctrl_build_state(pdev);
        if (ret) {
                dev_err(&pdev->dev, "dt probe failed: %d\n", ret);
@@ -869,7 +938,7 @@ int sunxi_pinctrl_init(struct platform_device *pdev,
                const struct sunxi_desc_pin *pin = pctl->desc->pins + i;
 
                ret = gpiochip_add_pin_range(pctl->chip, dev_name(&pdev->dev),
-                                            pin->pin.number,
+                                            pin->pin.number - pctl->desc->pin_base,
                                             pin->pin.number, 1);
                if (ret)
                        goto gpiochip_error;
@@ -885,30 +954,51 @@ int sunxi_pinctrl_init(struct platform_device *pdev,
        if (ret)
                goto gpiochip_error;
 
-       pctl->irq = irq_of_parse_and_map(node, 0);
+       pctl->irq = devm_kcalloc(&pdev->dev,
+                                pctl->desc->irq_banks,
+                                sizeof(*pctl->irq),
+                                GFP_KERNEL);
        if (!pctl->irq) {
-               ret = -EINVAL;
+               ret = -ENOMEM;
                goto clk_error;
        }
 
-       pctl->domain = irq_domain_add_linear(node, SUNXI_IRQ_NUMBER,
-                                            &irq_domain_simple_ops, NULL);
+       for (i = 0; i < pctl->desc->irq_banks; i++) {
+               pctl->irq[i] = platform_get_irq(pdev, i);
+               if (pctl->irq[i] < 0) {
+                       ret = pctl->irq[i];
+                       goto clk_error;
+               }
+       }
+
+       pctl->domain = irq_domain_add_linear(node,
+                                            pctl->desc->irq_banks * IRQ_PER_BANK,
+                                            &irq_domain_simple_ops,
+                                            NULL);
        if (!pctl->domain) {
                dev_err(&pdev->dev, "Couldn't register IRQ domain\n");
                ret = -ENOMEM;
                goto clk_error;
        }
 
-       for (i = 0; i < SUNXI_IRQ_NUMBER; i++) {
+       for (i = 0; i < (pctl->desc->irq_banks * IRQ_PER_BANK); i++) {
                int irqno = irq_create_mapping(pctl->domain, i);
 
-               irq_set_chip_and_handler(irqno, &sunxi_pinctrl_irq_chip,
-                                        handle_simple_irq);
+               irq_set_chip_and_handler(irqno, &sunxi_pinctrl_edge_irq_chip,
+                                        handle_edge_irq);
                irq_set_chip_data(irqno, pctl);
        };
 
-       irq_set_chained_handler(pctl->irq, sunxi_pinctrl_irq_handler);
-       irq_set_handler_data(pctl->irq, pctl);
+       for (i = 0; i < pctl->desc->irq_banks; i++) {
+               /* Mask and clear all IRQs before registering a handler */
+               writel(0, pctl->membase + sunxi_irq_ctrl_reg_from_bank(i));
+               writel(0xffffffff,
+                       pctl->membase + sunxi_irq_status_reg_from_bank(i));
+
+               irq_set_chained_handler(pctl->irq[i],
+                                       sunxi_pinctrl_irq_handler);
+               irq_set_handler_data(pctl->irq[i], pctl);
+       }
 
        dev_info(&pdev->dev, "initialized sunXi PIO driver\n");
 
@@ -917,8 +1007,7 @@ int sunxi_pinctrl_init(struct platform_device *pdev,
 clk_error:
        clk_disable_unprepare(clk);
 gpiochip_error:
-       if (gpiochip_remove(pctl->chip))
-               dev_err(&pdev->dev, "failed to remove gpio chip\n");
+       gpiochip_remove(pctl->chip);
 pinctrl_error:
        pinctrl_unregister(pctl->pctl_dev);
        return ret;
index 8169ba5988767f51b7f40ce07d66ec89ab9285ad..4245b96c799649b91241cbedd13ad2b5b201ee4b 100644 (file)
@@ -53,7 +53,7 @@
 #define PULL_PINS_BITS         2
 #define PULL_PINS_MASK         0x03
 
-#define SUNXI_IRQ_NUMBER       32
+#define IRQ_PER_BANK           32
 
 #define IRQ_CFG_REG            0x200
 #define IRQ_CFG_IRQ_PER_REG            8
@@ -68,6 +68,8 @@
 #define IRQ_STATUS_IRQ_BITS            1
 #define IRQ_STATUS_IRQ_MASK            ((1 << IRQ_STATUS_IRQ_BITS) - 1)
 
+#define IRQ_MEM_SIZE           0x20
+
 #define IRQ_EDGE_RISING                0x00
 #define IRQ_EDGE_FALLING       0x01
 #define IRQ_LEVEL_HIGH         0x02
@@ -77,6 +79,7 @@
 struct sunxi_desc_function {
        const char      *name;
        u8              muxval;
+       u8              irqbank;
        u8              irqnum;
 };
 
@@ -89,6 +92,7 @@ struct sunxi_pinctrl_desc {
        const struct sunxi_desc_pin     *pins;
        int                             npins;
        unsigned                        pin_base;
+       unsigned                        irq_banks;
 };
 
 struct sunxi_pinctrl_function {
@@ -113,8 +117,8 @@ struct sunxi_pinctrl {
        unsigned                        nfunctions;
        struct sunxi_pinctrl_group      *groups;
        unsigned                        ngroups;
-       int                             irq;
-       int                             irq_array[SUNXI_IRQ_NUMBER];
+       int                             *irq;
+       unsigned                        *irq_array;
        spinlock_t                      lock;
        struct pinctrl_dev              *pctl_dev;
 };
@@ -139,6 +143,14 @@ struct sunxi_pinctrl {
                .irqnum = _irq,                                 \
        }
 
+#define SUNXI_FUNCTION_IRQ_BANK(_val, _bank, _irq)             \
+       {                                                       \
+               .name = "irq",                                  \
+               .muxval = _val,                                 \
+               .irqbank = _bank,                               \
+               .irqnum = _irq,                                 \
+       }
+
 /*
  * The sunXi PIO registers are organized as is:
  * 0x00 - 0x0c Muxing values.
@@ -218,8 +230,10 @@ static inline u32 sunxi_pull_offset(u16 pin)
 
 static inline u32 sunxi_irq_cfg_reg(u16 irq)
 {
-       u8 reg = irq / IRQ_CFG_IRQ_PER_REG * 0x04;
-       return reg + IRQ_CFG_REG;
+       u8 bank = irq / IRQ_PER_BANK;
+       u8 reg = (irq % IRQ_PER_BANK) / IRQ_CFG_IRQ_PER_REG * 0x04;
+
+       return IRQ_CFG_REG + bank * IRQ_MEM_SIZE + reg;
 }
 
 static inline u32 sunxi_irq_cfg_offset(u16 irq)
@@ -228,10 +242,16 @@ static inline u32 sunxi_irq_cfg_offset(u16 irq)
        return irq_num * IRQ_CFG_IRQ_BITS;
 }
 
+static inline u32 sunxi_irq_ctrl_reg_from_bank(u8 bank)
+{
+       return IRQ_CTRL_REG + bank * IRQ_MEM_SIZE;
+}
+
 static inline u32 sunxi_irq_ctrl_reg(u16 irq)
 {
-       u8 reg = irq / IRQ_CTRL_IRQ_PER_REG * 0x04;
-       return reg + IRQ_CTRL_REG;
+       u8 bank = irq / IRQ_PER_BANK;
+
+       return sunxi_irq_ctrl_reg_from_bank(bank);
 }
 
 static inline u32 sunxi_irq_ctrl_offset(u16 irq)
@@ -240,10 +260,16 @@ static inline u32 sunxi_irq_ctrl_offset(u16 irq)
        return irq_num * IRQ_CTRL_IRQ_BITS;
 }
 
+static inline u32 sunxi_irq_status_reg_from_bank(u8 bank)
+{
+       return IRQ_STATUS_REG + bank * IRQ_MEM_SIZE;
+}
+
 static inline u32 sunxi_irq_status_reg(u16 irq)
 {
-       u8 reg = irq / IRQ_STATUS_IRQ_PER_REG * 0x04;
-       return reg + IRQ_STATUS_REG;
+       u8 bank = irq / IRQ_PER_BANK;
+
+       return sunxi_irq_status_reg_from_bank(bank);
 }
 
 static inline u32 sunxi_irq_status_offset(u16 irq)
index 2c61281bebd7666f6b12e87a7618c47a3a3aae18..8cea355f9a810ebd6babf1c49c0da00257029752 100644 (file)
@@ -141,17 +141,6 @@ static int wmt_pmx_enable(struct pinctrl_dev *pctldev,
        return wmt_set_pinmux(data, func_selector, pinnum);
 }
 
-static void wmt_pmx_disable(struct pinctrl_dev *pctldev,
-                           unsigned func_selector,
-                           unsigned group_selector)
-{
-       struct wmt_pinctrl_data *data = pinctrl_dev_get_drvdata(pctldev);
-       u32 pinnum = data->pins[group_selector].number;
-
-       /* disable by setting GPIO_IN */
-       wmt_set_pinmux(data, WMT_FSEL_GPIO_IN, pinnum);
-}
-
 static void wmt_pmx_gpio_disable_free(struct pinctrl_dev *pctldev,
                                      struct pinctrl_gpio_range *range,
                                      unsigned offset)
@@ -180,7 +169,6 @@ static struct pinmux_ops wmt_pinmux_ops = {
        .get_function_name = wmt_pmx_get_function_name,
        .get_function_groups = wmt_pmx_get_function_groups,
        .enable = wmt_pmx_enable,
-       .disable = wmt_pmx_disable,
        .gpio_disable_free = wmt_pmx_gpio_disable_free,
        .gpio_set_direction = wmt_pmx_gpio_set_direction,
 };
@@ -627,8 +615,7 @@ int wmt_pinctrl_probe(struct platform_device *pdev,
        return 0;
 
 fail_range:
-       if (gpiochip_remove(&data->gpio_chip))
-               dev_err(&pdev->dev, "failed to remove gpio chip\n");
+       gpiochip_remove(&data->gpio_chip);
 fail_gpio:
        pinctrl_unregister(data->pctl_dev);
        return err;
@@ -637,12 +624,8 @@ fail_gpio:
 int wmt_pinctrl_remove(struct platform_device *pdev)
 {
        struct wmt_pinctrl_data *data = platform_get_drvdata(pdev);
-       int err;
-
-       err = gpiochip_remove(&data->gpio_chip);
-       if (err)
-               dev_err(&pdev->dev, "failed to remove gpio chip\n");
 
+       gpiochip_remove(&data->gpio_chip);
        pinctrl_unregister(data->pctl_dev);
 
        return 0;
index c15395031cb30008d03f514ae5128ff550ce09fa..3097aafbeb24599ba3d9ee64946e60601b23ef13 100644 (file)
@@ -70,8 +70,6 @@ struct pinmux_ops {
                                  unsigned * const num_groups);
        int (*enable) (struct pinctrl_dev *pctldev, unsigned func_selector,
                       unsigned group_selector);
-       void (*disable) (struct pinctrl_dev *pctldev, unsigned func_selector,
-                        unsigned group_selector);
        int (*gpio_request_enable) (struct pinctrl_dev *pctldev,
                                    struct pinctrl_gpio_range *range,
                                    unsigned offset);
This page took 0.452533 seconds and 5 git commands to generate.