Merge tag 'pinctrl-for-v3.9' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl

Pull pinctrl changes from Linus Walleij:
 "These are the main pinctrl changes for the v3.9 merge window.  The
  most interesting change by far is how the device core grabs pinctrl
  default handles avoiding the need to stick boilerplate into driver
  consumers.

   - Grabbing of default pinctrl handles from the device core.  These
     are the hunks hitting drivers/base.  All is ACKed by Greg, after a
     long discussion about different alternatives.

   - Some stuff also touches the MFD and ARM SoC trees, this has been
     coordinated and ACKed.

   - New drivers for:
     - The Tegra 114 sub-SoC
     - Allwinner sunxi
     - New ABx500 driver and sub-SoC drivers for AB8500, AB8505, AB9540
       and AB8540.

   - Make it possible for hogged pins to enter a sleep mode, and make it
     possible for drivers to control that mode.

   - Various clean-up, extensions and device tree support to various pin
     controllers."

* tag 'pinctrl-for-v3.9' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl: (68 commits)
  pinctrl: tegra: add clfvs function to Tegra114 support
  pinctrl: generic: rename input schmitt disable
  pinctrl/pinconfig: add debug interface
  pinctrl: samsung: remove duplicated line
  ARM: ux500: use real AB8500 IRQ numbers instead of virtual ones
  ARM: ux500: remove irq_base property from platform_data
  pinctrl/abx500: use direct IRQ defines
  pinctrl/abx500: replace IRQ offsets with table read-in values
  pinctrl/abx500: move IRQ handling to ab8500-core
  pinctrl: exynos5440: remove erroneous __init
  pinctrl/abx500: adjust offset for get_mode()
  pinctrl/abx500: add Device Tree support
  pinctrl/abx500: align GPIO cluster boundaries
  pinctrl/abx500: prevent error path from corrupting returning error
  pinctrl: sunxi: add of_xlate function
  pinctrl/lantiq: fix pin number in ltq_pmx_gpio_request_enable
  pinctrl/lantiq: add functionality to falcon_pinconf_dbg_show
  pinctrl/lantiq: fix pinconfig parameters
  pinctrl/lantiq: one of the boot leds was defined incorrectly
  pinctrl/lantiq: only probe available pad controllers
  ...
diff --git a/Documentation/devicetree/bindings/pinctrl/allwinner,sunxi-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/allwinner,sunxi-pinctrl.txt
new file mode 100644
index 0000000..dff0e5f
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/allwinner,sunxi-pinctrl.txt
@@ -0,0 +1,60 @@
+* Allwinner A1X Pin Controller
+
+The pins controlled by sunXi pin controller are organized in banks,
+each bank has 32 pins.  Each pin has 7 multiplexing functions, with
+the first two functions being GPIO in and out. The configuration on
+the pins includes drive strength and pull-up.
+
+Required properties:
+- compatible: "allwinner,<soc>-pinctrl". Supported SoCs for now are:
+  sun5i-a13.
+- reg: Should contain the register physical address and length for the
+  pin controller.
+
+Please refer to pinctrl-bindings.txt in this directory for details of the
+common pinctrl bindings used by client devices.
+
+A pinctrl node should contain at least one subnodes representing the
+pinctrl groups available on the machine. Each subnode will list the
+pins it needs, and how they should be configured, with regard to muxer
+configuration, drive strength and pullups. If one of these options is
+not set, its actual value will be unspecified.
+
+Required subnode-properties:
+
+- allwinner,pins: List of strings containing the pin name.
+- allwinner,function: Function to mux the pins listed above to.
+
+Optional subnode-properties:
+- allwinner,drive: Integer. Represents the current sent to the pin
+    0: 10 mA
+    1: 20 mA
+    2: 30 mA
+    3: 40 mA
+- allwinner,pull: Integer.
+    0: No resistor
+    1: Pull-up resistor
+    2: Pull-down resistor
+
+Examples:
+
+pinctrl@01c20800 {
+	compatible = "allwinner,sun5i-a13-pinctrl";
+	reg = <0x01c20800 0x400>;
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	uart1_pins_a: uart1@0 {
+		allwinner,pins = "PE10", "PE11";
+		allwinner,function = "uart1";
+		allwinner,drive = <0>;
+		allwinner,pull = <0>;
+	};
+
+	uart1_pins_b: uart1@1 {
+		allwinner,pins = "PG3", "PG4";
+		allwinner,function = "uart1";
+		allwinner,drive = <0>;
+		allwinner,pull = <0>;
+	};
+};
diff --git a/Documentation/devicetree/bindings/pinctrl/nvidia,tegra114-pinmux.txt b/Documentation/devicetree/bindings/pinctrl/nvidia,tegra114-pinmux.txt
new file mode 100644
index 0000000..e204d00
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/nvidia,tegra114-pinmux.txt
@@ -0,0 +1,120 @@
+NVIDIA Tegra114 pinmux controller
+
+The Tegra114 pinctrl binding is very similar to the Tegra20 and Tegra30
+pinctrl binding, as described in nvidia,tegra20-pinmux.txt and
+nvidia,tegra30-pinmux.txt. In fact, this document assumes that binding as
+a baseline, and only documents the differences between the two bindings.
+
+Required properties:
+- compatible: "nvidia,tegra114-pinmux"
+- reg: Should contain the register physical address and length for each of
+  the pad control and mux registers. The first bank of address must be the
+  driver strength pad control register address and second bank address must
+  be pinmux register address.
+
+Tegra114 adds the following optional properties for pin configuration subnodes:
+- nvidia,enable-input: Integer. Enable the pin's input path. 0: no, 1: yes.
+- nvidia,open-drain: Integer. Enable open drain mode. 0: no, 1: yes.
+- nvidia,lock: Integer. Lock the pin configuration against further changes
+    until reset. 0: no, 1: yes.
+- nvidia,io-reset: Integer. Reset the IO path. 0: no, 1: yes.
+- nvidia,rcv-sel: Integer. Select VIL/VIH receivers. 0: normal, 1: high.
+- nvidia,drive-type: Integer. Valid range 0...3.
+
+As with Tegra20 and Terga30, see the Tegra TRM for complete details regarding
+which groups support which functionality.
+
+Valid values for pin and group names are:
+
+  per-pin mux groups:
+
+    These all support nvidia,function, nvidia,tristate, nvidia,pull,
+    nvidia,enable-input, nvidia,lock. Some support nvidia,open-drain,
+    nvidia,io-reset and nvidia,rcv-sel.
+
+    ulpi_data0_po1, ulpi_data1_po2, ulpi_data2_po3, ulpi_data3_po4,
+    ulpi_data4_po5, ulpi_data5_po6, ulpi_data6_po7, ulpi_data7_po0,
+    ulpi_clk_py0, ulpi_dir_py1, ulpi_nxt_py2, ulpi_stp_py3, dap3_fs_pp0,
+    dap3_din_pp1, dap3_dout_pp2, dap3_sclk_pp3, pv0, pv1, sdmmc1_clk_pz0,
+    sdmmc1_cmd_pz1, sdmmc1_dat3_py4, sdmmc1_dat2_py5, sdmmc1_dat1_py6,
+    sdmmc1_dat0_py7, clk2_out_pw5, clk2_req_pcc5, hdmi_int_pn7, ddc_scl_pv4,
+    ddc_sda_pv5, uart2_rxd_pc3, uart2_txd_pc2, uart2_rts_n_pj6,
+    uart2_cts_n_pj5, uart3_txd_pw6, uart3_rxd_pw7, uart3_cts_n_pa1,
+    uart3_rts_n_pc0, pu0, pu1, pu2, pu3, pu4, pu5, pu6, gen1_i2c_sda_pc5,
+    gen1_i2c_scl_pc4, dap4_fs_pp4, dap4_din_pp5, dap4_dout_pp6, dap4_sclk_pp7,
+    clk3_out_pee0, clk3_req_pee1, gmi_wp_n_pc7, gmi_iordy_pi5, gmi_wait_pi7,
+    gmi_adv_n_pk0, gmi_clk_pk1, gmi_cs0_n_pj0, gmi_cs1_n_pj2, gmi_cs2_n_pk3,
+    gmi_cs3_n_pk4, gmi_cs4_n_pk2, gmi_cs6_n_pi3, gmi_cs7_n_pi6, gmi_ad0_pg0,
+    gmi_ad1_pg1, gmi_ad2_pg2, gmi_ad3_pg3, gmi_ad4_pg4, gmi_ad5_pg5,
+    gmi_ad6_pg6, gmi_ad7_pg7, gmi_ad8_ph0, gmi_ad9_ph1, gmi_ad10_ph2,
+    gmi_ad11_ph3, gmi_ad12_ph4, gmi_ad13_ph5, gmi_ad14_ph6, gmi_ad15_ph7,
+    gmi_a16_pj7, gmi_a17_pb0, gmi_a18_pb1, gmi_a19_pk7, gmi_wr_n_pi0,
+    gmi_oe_n_pi1, gmi_dqs_p_pj3, gmi_rst_n_pi4, gen2_i2c_scl_pt5,
+    gen2_i2c_sda_pt6, sdmmc4_clk_pcc4, sdmmc4_cmd_pt7, sdmmc4_dat0_paa0,
+    sdmmc4_dat1_paa1, sdmmc4_dat2_paa2, sdmmc4_dat3_paa3, sdmmc4_dat4_paa4,
+    sdmmc4_dat5_paa5, sdmmc4_dat6_paa6, sdmmc4_dat7_paa7, cam_mclk_pcc0,
+    pcc1, pbb0, cam_i2c_scl_pbb1, cam_i2c_sda_pbb2, pbb3, pbb4, pbb5, pbb6,
+    pbb7, pcc2, pwr_i2c_scl_pz6, pwr_i2c_sda_pz7, kb_row0_pr0, kb_row1_pr1,
+    kb_row2_pr2, kb_row3_pr3, kb_row4_pr4, kb_row5_pr5, kb_row6_pr6,
+    kb_row7_pr7, kb_row8_ps0, kb_row9_ps1, kb_row10_ps2, kb_col0_pq0,
+    kb_col1_pq1, kb_col2_pq2, kb_col3_pq3, kb_col4_pq4, kb_col5_pq5,
+    kb_col6_pq6, kb_col7_pq7, clk_32k_out_pa0, sys_clk_req_pz5, core_pwr_req,
+    cpu_pwr_req, pwr_int_n, owr, dap1_fs_pn0, dap1_din_pn1, dap1_dout_pn2,
+    dap1_sclk_pn3, clk1_req_pee2, clk1_out_pw4, spdif_in_pk6, spdif_out_pk5,
+    dap2_fs_pa2, dap2_din_pa4, dap2_dout_pa5, dap2_sclk_pa3, dvfs_pwm_px0,
+    gpio_x1_aud_px1, gpio_x3_aud_px3, dvfs_clk_px2, gpio_x4_aud_px4,
+    gpio_x5_aud_px5, gpio_x6_aud_px6, gpio_x7_aud_px7, sdmmc3_clk_pa6,
+    sdmmc3_cmd_pa7, sdmmc3_dat0_pb7, sdmmc3_dat1_pb6, sdmmc3_dat2_pb5,
+    sdmmc3_dat3_pb4, hdmi_cec_pee3, sdmmc1_wp_n_pv3, sdmmc3_cd_n_pv2,
+    gpio_w2_aud_pw2, gpio_w3_aud_pw3, usb_vbus_en0_pn4, usb_vbus_en1_pn5,
+    sdmmc3_clk_lb_in_pee5, sdmmc3_clk_lb_out_pee4, reset_out_n.
+
+  drive groups:
+
+    These all support nvidia,pull-down-strength, nvidia,pull-up-strength,
+    nvidia,slew-rate-rising, nvidia,slew-rate-falling. Most but not all
+    support nvidia,high-speed-mode, nvidia,schmitt, nvidia,low-power-mode
+    and nvidia,drive-type.
+
+    ao1, ao2, at1, at2, at3, at4, at5, cdev1, cdev2, dap1, dap2, dap3, dap4,
+    dbg, sdio3, spi, uaa, uab, uart2, uart3, sdio1, ddc, gma, gme, gmf, gmg,
+    gmh, owr, uda.
+
+Example:
+
+	pinmux: pinmux {
+		compatible = "nvidia,tegra114-pinmux";
+		reg = <0x70000868 0x148		/* Pad control registers */
+		       0x70003000 0x40c>;	/* PinMux registers */
+	};
+
+Example board file extract:
+
+	pinctrl {
+		sdmmc4_default: pinmux {
+			sdmmc4_clk_pcc4 {
+				nvidia,pins = "sdmmc4_clk_pcc4",
+				nvidia,function = "sdmmc4";
+				nvidia,pull = <0>;
+				nvidia,tristate = <0>;
+			};
+			sdmmc4_dat0_paa0 {
+				nvidia,pins = "sdmmc4_dat0_paa0",
+						"sdmmc4_dat1_paa1",
+						"sdmmc4_dat2_paa2",
+						"sdmmc4_dat3_paa3",
+						"sdmmc4_dat4_paa4",
+						"sdmmc4_dat5_paa5",
+						"sdmmc4_dat6_paa6",
+						"sdmmc4_dat7_paa7";
+				nvidia,function = "sdmmc4";
+				nvidia,pull = <2>;
+				nvidia,tristate = <0>;
+			};
+		};
+	};
+
+	sdhci@78000400 {
+		pinctrl-names = "default";
+		pinctrl-0 = <&sdmmc4_default>;
+	};
diff --git a/Documentation/devicetree/bindings/pinctrl/ste,nomadik.txt b/Documentation/devicetree/bindings/pinctrl/ste,nomadik.txt
new file mode 100644
index 0000000..9a2f3f4
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/ste,nomadik.txt
@@ -0,0 +1,140 @@
+ST Ericsson Nomadik pinmux controller
+
+Required properties:
+- compatible: "stericsson,nmk-pinctrl", "stericsson,nmk-pinctrl-db8540",
+              "stericsson,nmk-pinctrl-stn8815"
+- reg: Should contain the register physical address and length of the PRCMU.
+
+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".
+
+ST Ericsson's pin configuration nodes act as a container for an arbitrary number of
+subnodes. Each of these subnodes represents some desired configuration for a
+pin, a group, or a list of pins or groups. This configuration can include the
+mux function to select on those pin(s)/group(s), and various pin configuration
+parameters, such as input, output, pull up, pull down...
+
+The name of each subnode is not important; all subnodes should be enumerated
+and processed purely based on their content.
+
+Required subnode-properties:
+- ste,pins : An array of strings. Each string contains the name of a pin or
+    group.
+
+Optional subnode-properties:
+- ste,function: A string containing the name of the function to mux to the
+  pin or group.
+
+- ste,config: Handle of pin configuration node (e.g. ste,config = <&slpm_in_wkup_pdis>)
+
+- ste,input : <0/1/2>
+	0: input with no pull
+	1: input with pull up,
+	2: input with pull down,
+
+- ste,output: <0/1/2>
+	0: output low,
+	1: output high,
+	2: output (value is not specified).
+
+- ste,sleep: <0/1>
+	0: sleep mode disable,
+	1: sleep mode enable.
+
+- ste,sleep-input: <0/1/2/3>
+	0: sleep input with no pull,
+	1: sleep input with pull up,
+	2: sleep input with pull down.
+	3: sleep input and keep last input configuration (no pull, pull up or pull down).
+
+- ste,sleep-output: <0/1/2>
+	0: sleep output low,
+	1: sleep output high,
+	2: sleep output (value is not specified).
+
+- ste,sleep-gpio: <0/1>
+	0: disable sleep gpio mode,
+	1: enable sleep gpio mode.
+
+- ste,sleep-wakeup: <0/1>
+	0: wake-up detection enabled,
+	1: wake-up detection disabled.
+
+- ste,sleep-pull-disable: <0/1>
+	0: GPIO pull-up or pull-down resistor is enabled, when pin is an input,
+	1: GPIO pull-up and pull-down resistor are disabled.
+
+Example board file extract:
+
+	pinctrl@80157000 {
+		compatible = "stericsson,nmk-pinctrl";
+		reg = <0x80157000 0x2000>;
+
+		pinctrl-names = "default";
+
+		slpm_in_wkup_pdis: slpm_in_wkup_pdis {
+			ste,sleep = <1>;
+			ste,sleep-input = <3>;
+			ste,sleep-wakeup = <1>;
+			ste,sleep-pull-disable = <0>;
+		};
+
+		slpm_out_hi_wkup_pdis: slpm_out_hi_wkup_pdis {
+			ste,sleep = <1>;
+			ste,sleep-output = <1>;
+			ste,sleep-wakeup = <1>;
+			ste,sleep-pull-disable = <0>;
+		};
+
+		slpm_out_wkup_pdis: slpm_out_wkup_pdis {
+			ste,sleep = <1>;
+			ste,sleep-output = <2>;
+			ste,sleep-wakeup = <1>;
+			ste,sleep-pull-disable = <0>;
+		};
+
+		uart0 {
+			uart0_default_mux: uart0_mux {
+				u0_default_mux {
+					ste,function = "u0";
+					ste,pins = "u0_a_1";
+				};
+			};
+			uart0_default_mode: uart0_default {
+				uart0_default_cfg1 {
+					ste,pins = "GPIO0", "GPIO2";
+					ste,input = <1>;
+				};
+
+				uart0_default_cfg2 {
+					ste,pins = "GPIO1", "GPIO3";
+					ste,output = <1>;
+				};
+			};
+			uart0_sleep_mode: uart0_sleep {
+				uart0_sleep_cfg1 {
+					ste,pins = "GPIO0", "GPIO2";
+					ste,config = <&slpm_in_wkup_pdis>;
+				};
+				uart0_sleep_cfg2 {
+					ste,pins = "GPIO1";
+					ste,config = <&slpm_out_hi_wkup_pdis>;
+				};
+				uart0_sleep_cfg3 {
+					ste,pins = "GPIO3";
+					ste,config = <&slpm_out_wkup_pdis>;
+				};
+			};
+		};
+	};
+
+	uart@80120000 {
+		compatible = "arm,pl011", "arm,primecell";
+		reg = <0x80120000 0x1000>;
+		interrupts = <0 11 0x4>;
+
+		pinctrl-names = "default","sleep";
+		pinctrl-0 = <&uart0_default_mux>, <&uart0_default_mode>;
+		pinctrl-1 = <&uart0_sleep_mode>;
+	};
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index 902b1b1..1532137 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -50,6 +50,7 @@
 sirf	SiRF Technology, Inc.
 snps 	Synopsys, Inc.
 st	STMicroelectronics
+ste	ST-Ericsson
 stericsson	ST-Ericsson
 ti	Texas Instruments
 via	VIA Technologies, Inc.
diff --git a/Documentation/pinctrl.txt b/Documentation/pinctrl.txt
index da40efb..a2b57e0 100644
--- a/Documentation/pinctrl.txt
+++ b/Documentation/pinctrl.txt
@@ -972,6 +972,18 @@
 Pin control requests from drivers
 =================================
 
+When a device driver is about to probe the device core will automatically
+attempt to issue pinctrl_get_select_default() on these devices.
+This way driver writers do not need to add any of the boilerplate code
+of the type found below. However when doing fine-grained state selection
+and not using the "default" state, you may have to do some device driver
+handling of the pinctrl handles and states.
+
+So if you just want to put the pins for a certain device into the default
+state and be done with it, there is nothing you need to do besides
+providing the proper mapping table. The device core will take care of
+the rest.
+
 Generally it is discouraged to let individual drivers get and enable pin
 control. So if possible, handle the pin control in platform code or some other
 place where you have access to all the affected struct device * pointers. In
@@ -1097,9 +1109,9 @@
 mux in and bias pins in a certain way before the GPIO subsystems starts to
 deal with them.
 
-The above can be hidden: using pinctrl hogs, the pin control driver may be
-setting up the config and muxing for the pins when it is probing,
-nevertheless orthogonal to the GPIO subsystem.
+The above can be hidden: using the device core, the pinctrl core may be
+setting up the config and muxing for the pins right before the device is
+probing, nevertheless orthogonal to the GPIO subsystem.
 
 But there are also situations where it makes sense for the GPIO subsystem
 to communicate directly with with the pinctrl subsystem, using the latter
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 9bbe760..6c0900a 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1636,7 +1636,7 @@
 	default 355 if ARCH_U8500
 	default 264 if MACH_H4700
 	default 512 if SOC_OMAP5
-	default 288 if ARCH_VT8500
+	default 288 if ARCH_VT8500 || ARCH_SUNXI
 	default 0
 	help
 	  Maximum number of GPIOs in the system.
diff --git a/arch/arm/boot/dts/dbx5x0.dtsi b/arch/arm/boot/dts/dbx5x0.dtsi
index 63f2fbc..69140ba 100644
--- a/arch/arm/boot/dts/dbx5x0.dtsi
+++ b/arch/arm/boot/dts/dbx5x0.dtsi
@@ -170,10 +170,9 @@
 			gpio-bank = <8>;
 		};
 
-		pinctrl@80157000 {
-			// This is actually the PRCMU base address
-			reg = <0x80157000 0x2000>;
-			compatible = "stericsson,nmk_pinctrl";
+		pinctrl {
+			compatible = "stericsson,nmk-pinctrl";
+			prcm = <&prcmu>;
 		};
 
 		usb@a03e0000 {
@@ -190,9 +189,10 @@
 			interrupts = <0 25 0x4>;
 		};
 
-		prcmu@80157000 {
+		prcmu: prcmu@80157000 {
 			compatible = "stericsson,db8500-prcmu";
 			reg = <0x80157000 0x1000>;
+			reg-names = "prcmu";
 			interrupts = <0 47 0x4>;
 			#address-cells = <1>;
 			#size-cells = <1>;
diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi
index e61fdd4..f99f60d 100644
--- a/arch/arm/boot/dts/sun4i-a10.dtsi
+++ b/arch/arm/boot/dts/sun4i-a10.dtsi
@@ -16,4 +16,34 @@
 	memory {
 		reg = <0x40000000 0x80000000>;
 	};
+
+	soc {
+		pinctrl@01c20800 {
+			compatible = "allwinner,sun4i-a10-pinctrl";
+			reg = <0x01c20800 0x400>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			uart0_pins_a: uart0@0 {
+				allwinner,pins = "PB22", "PB23";
+				allwinner,function = "uart0";
+				allwinner,drive = <0>;
+				allwinner,pull = <0>;
+			};
+
+			uart0_pins_b: uart0@1 {
+				allwinner,pins = "PF2", "PF4";
+				allwinner,function = "uart0";
+				allwinner,drive = <0>;
+				allwinner,pull = <0>;
+			};
+
+			uart1_pins_a: uart1@0 {
+				allwinner,pins = "PA10", "PA11";
+				allwinner,function = "uart1";
+				allwinner,drive = <0>;
+				allwinner,pull = <0>;
+			};
+		};
+	};
 };
diff --git a/arch/arm/boot/dts/sun5i-a13-olinuxino.dts b/arch/arm/boot/dts/sun5i-a13-olinuxino.dts
index 498a091..4a1e45d 100644
--- a/arch/arm/boot/dts/sun5i-a13-olinuxino.dts
+++ b/arch/arm/boot/dts/sun5i-a13-olinuxino.dts
@@ -24,6 +24,8 @@
 
 	soc {
 		uart1: uart@01c28400 {
+			pinctrl-names = "default";
+			pinctrl-0 = <&uart1_pins_b>;
 			status = "okay";
 		};
 	};
diff --git a/arch/arm/boot/dts/sun5i-a13.dtsi b/arch/arm/boot/dts/sun5i-a13.dtsi
index 59a2d26..e112189 100644
--- a/arch/arm/boot/dts/sun5i-a13.dtsi
+++ b/arch/arm/boot/dts/sun5i-a13.dtsi
@@ -17,4 +17,27 @@
 	memory {
 		reg = <0x40000000 0x20000000>;
 	};
+
+	soc {
+		pinctrl@01c20800 {
+			compatible = "allwinner,sun5i-a13-pinctrl";
+			reg = <0x01c20800 0x400>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			uart1_pins_a: uart1@0 {
+				allwinner,pins = "PE10", "PE11";
+				allwinner,function = "uart1";
+				allwinner,drive = <0>;
+				allwinner,pull = <0>;
+			};
+
+			uart1_pins_b: uart1@1 {
+				allwinner,pins = "PG3", "PG4";
+				allwinner,function = "uart1";
+				allwinner,drive = <0>;
+				allwinner,pull = <0>;
+			};
+		};
+	};
 };
diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
index 3fdd008..8709a39 100644
--- a/arch/arm/mach-sunxi/Kconfig
+++ b/arch/arm/mach-sunxi/Kconfig
@@ -7,3 +7,4 @@
 	select PINCTRL
 	select SPARSE_IRQ
 	select SUNXI_TIMER
+	select PINCTRL_SUNXI
\ No newline at end of file
diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig
index 5dea906..3e5bbd0 100644
--- a/arch/arm/mach-ux500/Kconfig
+++ b/arch/arm/mach-ux500/Kconfig
@@ -11,6 +11,7 @@
 	select COMMON_CLK
 	select PINCTRL
 	select PINCTRL_NOMADIK
+	select PINCTRL_ABX500
 	select PL310_ERRATA_753970 if CACHE_PL310
 
 config UX500_SOC_DB8500
@@ -18,6 +19,11 @@
 	select CPU_FREQ_TABLE if CPU_FREQ
 	select MFD_DB8500_PRCMU
 	select PINCTRL_DB8500
+	select PINCTRL_DB8540
+	select PINCTRL_AB8500
+	select PINCTRL_AB8505
+	select PINCTRL_AB9540
+	select PINCTRL_AB8540
 	select REGULATOR
 	select REGULATOR_DB8500_PRCMU
 
diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c
index d453522..b8781ca 100644
--- a/arch/arm/mach-ux500/board-mop500.c
+++ b/arch/arm/mach-ux500/board-mop500.c
@@ -90,26 +90,8 @@
        },
 };
 
-static struct ab8500_gpio_platform_data ab8500_gpio_pdata = {
+static struct abx500_gpio_platform_data ab8500_gpio_pdata = {
 	.gpio_base		= MOP500_AB8500_PIN_GPIO(1),
-	.irq_base		= MOP500_AB8500_VIR_GPIO_IRQ_BASE,
-	/* config_reg is the initial configuration of ab8500 pins.
-	 * The pins can be configured as GPIO or alt functions based
-	 * on value present in GpioSel1 to GpioSel6 and AlternatFunction
-	 * register. This is the array of 7 configuration settings.
-	 * One has to compile time decide these settings. Below is the
-	 * explanation of these setting
-	 * GpioSel1 = 0x00 => Pins GPIO1 to GPIO8 are not used as GPIO
-	 * GpioSel2 = 0x1E => Pins GPIO10 to GPIO13 are configured as GPIO
-	 * GpioSel3 = 0x80 => Pin GPIO24 is configured as GPIO
-	 * GpioSel4 = 0x01 => Pin GPIo25 is configured as GPIO
-	 * GpioSel5 = 0x7A => Pins GPIO34, GPIO36 to GPIO39 are conf as GPIO
-	 * GpioSel6 = 0x00 => Pins GPIO41 & GPIo42 are not configured as GPIO
-	 * AlternaFunction = 0x00 => If Pins GPIO10 to 13 are not configured
-	 * as GPIO then this register selectes the alternate fucntions
-	 */
-	.config_reg		= {0x00, 0x1E, 0x80, 0x01,
-					0x7A, 0x00, 0x00},
 };
 
 /* ab8500-codec */
diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c
index 5b286e0..b80ad96 100644
--- a/arch/arm/mach-ux500/cpu-db8500.c
+++ b/arch/arm/mach-ux500/cpu-db8500.c
@@ -285,7 +285,7 @@
 	OF_DEV_AUXDATA("st,nomadik-i2c", 0x80110000, "nmk-i2c.3", NULL),
 	OF_DEV_AUXDATA("st,nomadik-i2c", 0x8012a000, "nmk-i2c.4", NULL),
 	/* Requires device name bindings. */
-	OF_DEV_AUXDATA("stericsson,nmk_pinctrl", U8500_PRCMU_BASE,
+	OF_DEV_AUXDATA("stericsson,nmk-pinctrl", U8500_PRCMU_BASE,
 		"pinctrl-db8500", NULL),
 	/* Requires clock name and DMA bindings. */
 	OF_DEV_AUXDATA("stericsson,ux500-msp-i2s", 0x80123000,
diff --git a/arch/arm/mach-ux500/include/mach/irqs-board-mop500.h b/arch/arm/mach-ux500/include/mach/irqs-board-mop500.h
index 7d34c52..d526dd8 100644
--- a/arch/arm/mach-ux500/include/mach/irqs-board-mop500.h
+++ b/arch/arm/mach-ux500/include/mach/irqs-board-mop500.h
@@ -38,15 +38,7 @@
 #define MOP500_STMPE1601_IRQ_END	\
 	MOP500_STMPE1601_IRQ(STMPE_NR_INTERNAL_IRQS)
 
-/* AB8500 virtual gpio IRQ */
-#define AB8500_VIR_GPIO_NR_IRQS			16
-
-#define MOP500_AB8500_VIR_GPIO_IRQ_BASE		\
-	MOP500_STMPE1601_IRQ_END
-#define MOP500_AB8500_VIR_GPIO_IRQ_END		\
-	(MOP500_AB8500_VIR_GPIO_IRQ_BASE + AB8500_VIR_GPIO_NR_IRQS)
-
-#define MOP500_NR_IRQS		MOP500_AB8500_VIR_GPIO_IRQ_END
+#define MOP500_NR_IRQS		MOP500_STMPE1601_IRQ_END
 
 #define MOP500_IRQ_END		MOP500_NR_IRQS
 
diff --git a/drivers/base/Makefile b/drivers/base/Makefile
index 5aa2d70..4e22ce3 100644
--- a/drivers/base/Makefile
+++ b/drivers/base/Makefile
@@ -21,6 +21,7 @@
 obj-$(CONFIG_SYS_HYPERVISOR) += hypervisor.o
 obj-$(CONFIG_REGMAP)	+= regmap/
 obj-$(CONFIG_SOC_BUS) += soc.o
+obj-$(CONFIG_PINCTRL) += pinctrl.o
 
 ccflags-$(CONFIG_DEBUG_DRIVER) := -DDEBUG
 
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index e3bbed8..65631015 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -24,6 +24,7 @@
 #include <linux/wait.h>
 #include <linux/async.h>
 #include <linux/pm_runtime.h>
+#include <linux/pinctrl/devinfo.h>
 
 #include "base.h"
 #include "power/power.h"
@@ -269,6 +270,12 @@
 	WARN_ON(!list_empty(&dev->devres_head));
 
 	dev->driver = drv;
+
+	/* If using pinctrl, bind pins now before probing */
+	ret = pinctrl_bind_pins(dev);
+	if (ret)
+		goto probe_failed;
+
 	if (driver_sysfs_add(dev)) {
 		printk(KERN_ERR "%s: driver_sysfs_add(%s) failed\n",
 			__func__, dev_name(dev));
diff --git a/drivers/base/pinctrl.c b/drivers/base/pinctrl.c
new file mode 100644
index 0000000..67a274e
--- /dev/null
+++ b/drivers/base/pinctrl.c
@@ -0,0 +1,69 @@
+/*
+ * Driver core interface to the pinctrl subsystem.
+ *
+ * Copyright (C) 2012 ST-Ericsson SA
+ * Written on behalf of Linaro for ST-Ericsson
+ * Based on bits of regulator core, gpio core and clk core
+ *
+ * Author: Linus Walleij <linus.walleij@linaro.org>
+ *
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#include <linux/device.h>
+#include <linux/pinctrl/devinfo.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/slab.h>
+
+/**
+ * pinctrl_bind_pins() - called by the device core before probe
+ * @dev: the device that is just about to probe
+ */
+int pinctrl_bind_pins(struct device *dev)
+{
+	int ret;
+
+	dev->pins = devm_kzalloc(dev, sizeof(*(dev->pins)), GFP_KERNEL);
+	if (!dev->pins)
+		return -ENOMEM;
+
+	dev->pins->p = devm_pinctrl_get(dev);
+	if (IS_ERR(dev->pins->p)) {
+		dev_dbg(dev, "no pinctrl handle\n");
+		ret = PTR_ERR(dev->pins->p);
+		goto cleanup_alloc;
+	}
+
+	dev->pins->default_state = pinctrl_lookup_state(dev->pins->p,
+					PINCTRL_STATE_DEFAULT);
+	if (IS_ERR(dev->pins->default_state)) {
+		dev_dbg(dev, "no default pinctrl state\n");
+		ret = 0;
+		goto cleanup_get;
+	}
+
+	ret = pinctrl_select_state(dev->pins->p, dev->pins->default_state);
+	if (ret) {
+		dev_dbg(dev, "failed to activate default pinctrl state\n");
+		goto cleanup_get;
+	}
+
+	return 0;
+
+	/*
+	 * If no pinctrl handle or default state was found for this device,
+	 * let's explicitly free the pin container in the device, there is
+	 * no point in keeping it around.
+	 */
+cleanup_get:
+	devm_pinctrl_put(dev->pins->p);
+cleanup_alloc:
+	devm_kfree(dev, dev->pins);
+	dev->pins = NULL;
+
+	/* Only return deferrals */
+	if (ret != -EPROBE_DEFER)
+		ret = 0;
+
+	return ret;
+}
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 682de75..e5116fa8 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -657,12 +657,6 @@
 	  This driver provides support for driving the pins in output
 	  mode only. Input mode is not supported.
 
-config GPIO_AB8500
-	bool "ST-Ericsson AB8500 Mixed Signal Circuit gpio functions"
-	depends on AB8500_CORE && BROKEN
-	help
-	  Select this to enable the AB8500 IC GPIO driver
-
 config GPIO_TPS6586X
 	bool "TPS6586X GPIO"
 	depends on MFD_TPS6586X
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index c5aebd0..45a388c 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -10,7 +10,6 @@
 obj-$(CONFIG_GPIO_GENERIC)	+= gpio-generic.o
 
 obj-$(CONFIG_GPIO_74X164)	+= gpio-74x164.o
-obj-$(CONFIG_GPIO_AB8500)	+= gpio-ab8500.o
 obj-$(CONFIG_GPIO_ADNP)		+= gpio-adnp.o
 obj-$(CONFIG_GPIO_ADP5520)	+= gpio-adp5520.o
 obj-$(CONFIG_GPIO_ADP5588)	+= gpio-adp5588.o
diff --git a/drivers/gpio/gpio-ab8500.c b/drivers/gpio/gpio-ab8500.c
deleted file mode 100644
index 983ad42..0000000
--- a/drivers/gpio/gpio-ab8500.c
+++ /dev/null
@@ -1,520 +0,0 @@
-/*
- * Copyright (C) ST-Ericsson SA 2011
- *
- * Author: BIBEK BASU <bibek.basu@stericsson.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/platform_device.h>
-#include <linux/gpio.h>
-#include <linux/irq.h>
-#include <linux/interrupt.h>
-#include <linux/mfd/ab8500.h>
-#include <linux/mfd/abx500.h>
-#include <linux/mfd/ab8500/gpio.h>
-
-/*
- * 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 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 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 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 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 AB8500_GPIO_ALTFUN_REG	0x45
-#define ALTFUN_REG_INDEX	6
-#define AB8500_NUM_GPIO		42
-#define AB8500_NUM_VIR_GPIO_IRQ	16
-
-enum ab8500_gpio_action {
-	NONE,
-	STARTUP,
-	SHUTDOWN,
-	MASK,
-	UNMASK
-};
-
-struct ab8500_gpio {
-	struct gpio_chip chip;
-	struct ab8500 *parent;
-	struct device *dev;
-	struct mutex lock;
-	u32 irq_base;
-	enum ab8500_gpio_action irq_action;
-	u16 rising;
-	u16 falling;
-};
-/**
- * to_ab8500_gpio() - get the pointer to ab8500_gpio
- * @chip:	Member of the structure ab8500_gpio
- */
-static inline struct ab8500_gpio *to_ab8500_gpio(struct gpio_chip *chip)
-{
-	return container_of(chip, struct ab8500_gpio, chip);
-}
-
-static int ab8500_gpio_set_bits(struct gpio_chip *chip, u8 reg,
-					unsigned offset, int val)
-{
-	struct ab8500_gpio *ab8500_gpio = to_ab8500_gpio(chip);
-	u8 pos = offset % 8;
-	int ret;
-
-	reg = reg + (offset / 8);
-	ret = abx500_mask_and_set_register_interruptible(ab8500_gpio->dev,
-				AB8500_MISC, reg, 1 << pos, val << pos);
-	if (ret < 0)
-		dev_err(ab8500_gpio->dev, "%s write failed\n", __func__);
-	return ret;
-}
-/**
- * ab8500_gpio_get() - Get the particular GPIO value
- * @chip: Gpio device
- * @offset: GPIO number to read
- */
-static int ab8500_gpio_get(struct gpio_chip *chip, unsigned offset)
-{
-	struct ab8500_gpio *ab8500_gpio = to_ab8500_gpio(chip);
-	u8 mask = 1 << (offset % 8);
-	u8 reg = AB8500_GPIO_OUT1_REG + (offset / 8);
-	int ret;
-	u8 data;
-	ret = abx500_get_register_interruptible(ab8500_gpio->dev, AB8500_MISC,
-						reg, &data);
-	if (ret < 0) {
-		dev_err(ab8500_gpio->dev, "%s read failed\n", __func__);
-		return ret;
-	}
-	return (data & mask) >> (offset % 8);
-}
-
-static void ab8500_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
-{
-	struct ab8500_gpio *ab8500_gpio = to_ab8500_gpio(chip);
-	int ret;
-	/* Write the data */
-	ret = ab8500_gpio_set_bits(chip, AB8500_GPIO_OUT1_REG, offset, 1);
-	if (ret < 0)
-		dev_err(ab8500_gpio->dev, "%s write failed\n", __func__);
-}
-
-static int ab8500_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
-					int val)
-{
-	int ret;
-	/* set direction as output */
-	ret = ab8500_gpio_set_bits(chip, AB8500_GPIO_DIR1_REG, offset, 1);
-	if (ret < 0)
-		return ret;
-	/* disable pull down */
-	ret = ab8500_gpio_set_bits(chip, AB8500_GPIO_PUD1_REG, offset, 1);
-	if (ret < 0)
-		return ret;
-	/* set the output as 1 or 0 */
-	return ab8500_gpio_set_bits(chip, AB8500_GPIO_OUT1_REG, offset, val);
-
-}
-
-static int ab8500_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
-{
-	/* set the register as input */
-	return ab8500_gpio_set_bits(chip, AB8500_GPIO_DIR1_REG, offset, 0);
-}
-
-static int ab8500_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
-{
-	/*
-	 * Only some GPIOs are interrupt capable, and they are
-	 * organized in discontiguous clusters:
-	 *
-	 *	GPIO6 to GPIO13
-	 *	GPIO24 and GPIO25
-	 *	GPIO36 to GPIO41
-	 */
-	static struct ab8500_gpio_irq_cluster {
-		int start;
-		int end;
-	} clusters[] = {
-		{.start = 6,  .end = 13},
-		{.start = 24, .end = 25},
-		{.start = 36, .end = 41},
-	};
-	struct ab8500_gpio *ab8500_gpio = to_ab8500_gpio(chip);
-	int base = ab8500_gpio->irq_base;
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(clusters); i++) {
-		struct ab8500_gpio_irq_cluster *cluster = &clusters[i];
-
-		if (offset >= cluster->start && offset <= cluster->end)
-			return base + offset - cluster->start;
-
-		/* Advance by the number of gpios in this cluster */
-		base += cluster->end - cluster->start + 1;
-	}
-
-	return -EINVAL;
-}
-
-static struct gpio_chip ab8500gpio_chip = {
-	.label			= "ab8500_gpio",
-	.owner			= THIS_MODULE,
-	.direction_input	= ab8500_gpio_direction_input,
-	.get			= ab8500_gpio_get,
-	.direction_output	= ab8500_gpio_direction_output,
-	.set			= ab8500_gpio_set,
-	.to_irq			= ab8500_gpio_to_irq,
-};
-
-static unsigned int irq_to_rising(unsigned int irq)
-{
-	struct ab8500_gpio *ab8500_gpio = get_irq_chip_data(irq);
-	int offset = irq - ab8500_gpio->irq_base;
-	int new_irq = offset +  AB8500_INT_GPIO6R
-			+ ab8500_gpio->parent->irq_base;
-	return new_irq;
-}
-
-static unsigned int irq_to_falling(unsigned int irq)
-{
-	struct ab8500_gpio *ab8500_gpio = get_irq_chip_data(irq);
-	int offset = irq - ab8500_gpio->irq_base;
-	int new_irq = offset +  AB8500_INT_GPIO6F
-			+  ab8500_gpio->parent->irq_base;
-	return new_irq;
-
-}
-
-static unsigned int rising_to_irq(unsigned int irq, void *dev)
-{
-	struct ab8500_gpio *ab8500_gpio = dev;
-	int offset = irq - AB8500_INT_GPIO6R
-			- ab8500_gpio->parent->irq_base ;
-	int new_irq = offset + ab8500_gpio->irq_base;
-	return new_irq;
-}
-
-static unsigned int falling_to_irq(unsigned int irq, void *dev)
-{
-	struct ab8500_gpio *ab8500_gpio = dev;
-	int offset = irq - AB8500_INT_GPIO6F
-			- ab8500_gpio->parent->irq_base ;
-	int new_irq = offset + ab8500_gpio->irq_base;
-	return new_irq;
-
-}
-
-/*
- * IRQ handler
- */
-
-static irqreturn_t handle_rising(int irq, void *dev)
-{
-
-	handle_nested_irq(rising_to_irq(irq , dev));
-	return IRQ_HANDLED;
-}
-
-static irqreturn_t handle_falling(int irq, void *dev)
-{
-
-	handle_nested_irq(falling_to_irq(irq, dev));
-	return IRQ_HANDLED;
-}
-
-static void ab8500_gpio_irq_lock(unsigned int irq)
-{
-	struct ab8500_gpio *ab8500_gpio = get_irq_chip_data(irq);
-	mutex_lock(&ab8500_gpio->lock);
-}
-
-static void ab8500_gpio_irq_sync_unlock(unsigned int irq)
-{
-	struct ab8500_gpio *ab8500_gpio = get_irq_chip_data(irq);
-	int offset = irq - ab8500_gpio->irq_base;
-	bool rising = ab8500_gpio->rising & BIT(offset);
-	bool falling = ab8500_gpio->falling & BIT(offset);
-	int ret;
-
-	switch (ab8500_gpio->irq_action)	{
-	case STARTUP:
-		if (rising)
-			ret = request_threaded_irq(irq_to_rising(irq),
-					NULL, handle_rising,
-					IRQF_TRIGGER_RISING,
-					"ab8500-gpio-r", ab8500_gpio);
-		if (falling)
-			ret = request_threaded_irq(irq_to_falling(irq),
-				       NULL, handle_falling,
-				       IRQF_TRIGGER_FALLING,
-				       "ab8500-gpio-f", ab8500_gpio);
-		break;
-	case SHUTDOWN:
-		if (rising)
-			free_irq(irq_to_rising(irq), ab8500_gpio);
-		if (falling)
-			free_irq(irq_to_falling(irq), ab8500_gpio);
-		break;
-	case MASK:
-		if (rising)
-			disable_irq(irq_to_rising(irq));
-		if (falling)
-			disable_irq(irq_to_falling(irq));
-		break;
-	case UNMASK:
-		if (rising)
-			enable_irq(irq_to_rising(irq));
-		if (falling)
-			enable_irq(irq_to_falling(irq));
-		break;
-	case NONE:
-		break;
-	}
-	ab8500_gpio->irq_action = NONE;
-	ab8500_gpio->rising &= ~(BIT(offset));
-	ab8500_gpio->falling &= ~(BIT(offset));
-	mutex_unlock(&ab8500_gpio->lock);
-}
-
-
-static void ab8500_gpio_irq_mask(unsigned int irq)
-{
-	struct ab8500_gpio *ab8500_gpio = get_irq_chip_data(irq);
-	ab8500_gpio->irq_action = MASK;
-}
-
-static void ab8500_gpio_irq_unmask(unsigned int irq)
-{
-	struct ab8500_gpio *ab8500_gpio = get_irq_chip_data(irq);
-	ab8500_gpio->irq_action = UNMASK;
-}
-
-static int ab8500_gpio_irq_set_type(unsigned int irq, unsigned int type)
-{
-	struct ab8500_gpio *ab8500_gpio = get_irq_chip_data(irq);
-	int offset = irq - ab8500_gpio->irq_base;
-
-	if (type == IRQ_TYPE_EDGE_BOTH) {
-		ab8500_gpio->rising =  BIT(offset);
-		ab8500_gpio->falling = BIT(offset);
-	} else if (type == IRQ_TYPE_EDGE_RISING) {
-		ab8500_gpio->rising =  BIT(offset);
-	} else  {
-		ab8500_gpio->falling = BIT(offset);
-	}
-	return 0;
-}
-
-unsigned int ab8500_gpio_irq_startup(unsigned int irq)
-{
-	struct ab8500_gpio *ab8500_gpio = get_irq_chip_data(irq);
-	ab8500_gpio->irq_action = STARTUP;
-	return 0;
-}
-
-void ab8500_gpio_irq_shutdown(unsigned int irq)
-{
-	struct ab8500_gpio *ab8500_gpio = get_irq_chip_data(irq);
-	ab8500_gpio->irq_action = SHUTDOWN;
-}
-
-static struct irq_chip ab8500_gpio_irq_chip = {
-	.name			= "ab8500-gpio",
-	.startup		= ab8500_gpio_irq_startup,
-	.shutdown		= ab8500_gpio_irq_shutdown,
-	.bus_lock		= ab8500_gpio_irq_lock,
-	.bus_sync_unlock	= ab8500_gpio_irq_sync_unlock,
-	.mask			= ab8500_gpio_irq_mask,
-	.unmask			= ab8500_gpio_irq_unmask,
-	.set_type		= ab8500_gpio_irq_set_type,
-};
-
-static int ab8500_gpio_irq_init(struct ab8500_gpio *ab8500_gpio)
-{
-	u32 base = ab8500_gpio->irq_base;
-	int irq;
-
-	for (irq = base; irq < base + AB8500_NUM_VIR_GPIO_IRQ ; irq++) {
-		set_irq_chip_data(irq, ab8500_gpio);
-		set_irq_chip_and_handler(irq, &ab8500_gpio_irq_chip,
-				handle_simple_irq);
-		set_irq_nested_thread(irq, 1);
-#ifdef CONFIG_ARM
-		set_irq_flags(irq, IRQF_VALID);
-#else
-		set_irq_noprobe(irq);
-#endif
-	}
-
-	return 0;
-}
-
-static void ab8500_gpio_irq_remove(struct ab8500_gpio *ab8500_gpio)
-{
-	int base = ab8500_gpio->irq_base;
-	int irq;
-
-	for (irq = base; irq < base + AB8500_NUM_VIR_GPIO_IRQ; irq++) {
-#ifdef CONFIG_ARM
-		set_irq_flags(irq, 0);
-#endif
-		set_irq_chip_and_handler(irq, NULL, NULL);
-		set_irq_chip_data(irq, NULL);
-	}
-}
-
-static int ab8500_gpio_probe(struct platform_device *pdev)
-{
-	struct ab8500_platform_data *ab8500_pdata =
-				dev_get_platdata(pdev->dev.parent);
-	struct ab8500_gpio_platform_data *pdata;
-	struct ab8500_gpio *ab8500_gpio;
-	int ret;
-	int i;
-
-	pdata = ab8500_pdata->gpio;
-	if (!pdata)	{
-		dev_err(&pdev->dev, "gpio platform data missing\n");
-		return -ENODEV;
-	}
-
-	ab8500_gpio = kzalloc(sizeof(struct ab8500_gpio), GFP_KERNEL);
-	if (ab8500_gpio == NULL) {
-		dev_err(&pdev->dev, "failed to allocate memory\n");
-		return -ENOMEM;
-	}
-	ab8500_gpio->dev = &pdev->dev;
-	ab8500_gpio->parent = dev_get_drvdata(pdev->dev.parent);
-	ab8500_gpio->chip = ab8500gpio_chip;
-	ab8500_gpio->chip.ngpio = AB8500_NUM_GPIO;
-	ab8500_gpio->chip.dev = &pdev->dev;
-	ab8500_gpio->chip.base = pdata->gpio_base;
-	ab8500_gpio->irq_base = pdata->irq_base;
-	/* initialize the lock */
-	mutex_init(&ab8500_gpio->lock);
-	/*
-	 * AB8500 core will handle and clear the IRQ
-	 * configre GPIO based on config-reg value.
-	 * These values are for selecting the PINs as
-	 * GPIO or alternate function
-	 */
-	for (i = AB8500_GPIO_SEL1_REG; i <= AB8500_GPIO_SEL6_REG; i++)	{
-		ret = abx500_set_register_interruptible(ab8500_gpio->dev,
-				AB8500_MISC, i,
-				pdata->config_reg[i]);
-		if (ret < 0)
-			goto out_free;
-	}
-	ret = abx500_set_register_interruptible(ab8500_gpio->dev, AB8500_MISC,
-				AB8500_GPIO_ALTFUN_REG,
-				pdata->config_reg[ALTFUN_REG_INDEX]);
-	if (ret < 0)
-		goto out_free;
-
-	ret = ab8500_gpio_irq_init(ab8500_gpio);
-	if (ret)
-		goto out_free;
-	ret = gpiochip_add(&ab8500_gpio->chip);
-	if (ret) {
-		dev_err(&pdev->dev, "unable to add gpiochip: %d\n",
-				ret);
-		goto out_rem_irq;
-	}
-	platform_set_drvdata(pdev, ab8500_gpio);
-	return 0;
-
-out_rem_irq:
-	ab8500_gpio_irq_remove(ab8500_gpio);
-out_free:
-	mutex_destroy(&ab8500_gpio->lock);
-	kfree(ab8500_gpio);
-	return ret;
-}
-
-/*
- * ab8500_gpio_remove() - remove Ab8500-gpio driver
- * @pdev :	Platform device registered
- */
-static int ab8500_gpio_remove(struct platform_device *pdev)
-{
-	struct ab8500_gpio *ab8500_gpio = platform_get_drvdata(pdev);
-	int ret;
-
-	ret = gpiochip_remove(&ab8500_gpio->chip);
-	if (ret < 0) {
-		dev_err(ab8500_gpio->dev, "unable to remove gpiochip: %d\n",
-			ret);
-		return ret;
-	}
-
-	platform_set_drvdata(pdev, NULL);
-	mutex_destroy(&ab8500_gpio->lock);
-	kfree(ab8500_gpio);
-
-	return 0;
-}
-
-static struct platform_driver ab8500_gpio_driver = {
-	.driver = {
-		.name = "ab8500-gpio",
-		.owner = THIS_MODULE,
-	},
-	.probe = ab8500_gpio_probe,
-	.remove = ab8500_gpio_remove,
-};
-
-static int __init ab8500_gpio_init(void)
-{
-	return platform_driver_register(&ab8500_gpio_driver);
-}
-arch_initcall(ab8500_gpio_init);
-
-static void __exit ab8500_gpio_exit(void)
-{
-	platform_driver_unregister(&ab8500_gpio_driver);
-}
-module_exit(ab8500_gpio_exit);
-
-MODULE_AUTHOR("BIBEK BASU <bibek.basu@stericsson.com>");
-MODULE_DESCRIPTION("Driver allows to use AB8500 unused pins to be used as GPIO");
-MODULE_ALIAS("platform:ab8500-gpio");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c
index d542a14..25b1dbe 100644
--- a/drivers/gpio/gpiolib-of.c
+++ b/drivers/gpio/gpiolib-of.c
@@ -250,7 +250,7 @@
 		 * on the same GPIO chip.
 		 */
 		ret = gpiochip_add_pin_range(chip,
-					     pinctrl_dev_get_name(pctldev),
+					     pinctrl_dev_get_devname(pctldev),
 					     0, /* offset in gpiochip */
 					     pinspec.args[0],
 					     pinspec.args[1]);
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index a5f3c8c..393b0ec 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -26,6 +26,29 @@
 	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_AT91
 	bool "AT91 pinctrl driver"
 	depends on OF
@@ -151,6 +174,11 @@
 	depends on ARCH_SIRF
 	select PINMUX
 
+config PINCTRL_SUNXI
+	bool
+	select PINMUX
+	select GENERIC_PINCONF
+
 config PINCTRL_TEGRA
 	bool
 	select PINMUX
@@ -164,6 +192,10 @@
 	bool
 	select PINCTRL_TEGRA
 
+config PINCTRL_TEGRA114
+	bool
+	select PINCTRL_TEGRA
+
 config PINCTRL_U300
 	bool "U300 pin controller driver"
 	depends on ARCH_U300
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index 6e87e52..0fd5f57 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -9,6 +9,11 @@
 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_AT91)	+= pinctrl-at91.o
 obj-$(CONFIG_PINCTRL_BCM2835)	+= pinctrl-bcm2835.o
 obj-$(CONFIG_PINCTRL_IMX)	+= pinctrl-imx.o
@@ -30,9 +35,11 @@
 obj-$(CONFIG_PINCTRL_PXA910)	+= pinctrl-pxa910.o
 obj-$(CONFIG_PINCTRL_SINGLE)	+= pinctrl-single.o
 obj-$(CONFIG_PINCTRL_SIRF)	+= pinctrl-sirf.o
+obj-$(CONFIG_PINCTRL_SUNXI)	+= pinctrl-sunxi.o
 obj-$(CONFIG_PINCTRL_TEGRA)	+= pinctrl-tegra.o
 obj-$(CONFIG_PINCTRL_TEGRA20)	+= pinctrl-tegra20.o
 obj-$(CONFIG_PINCTRL_TEGRA30)	+= pinctrl-tegra30.o
+obj-$(CONFIG_PINCTRL_TEGRA114)	+= pinctrl-tegra114.o
 obj-$(CONFIG_PINCTRL_U300)	+= pinctrl-u300.o
 obj-$(CONFIG_PINCTRL_COH901)	+= pinctrl-coh901.o
 obj-$(CONFIG_PINCTRL_SAMSUNG)	+= pinctrl-samsung.o
diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c
index 59f5a96..b0de6e7 100644
--- a/drivers/pinctrl/core.c
+++ b/drivers/pinctrl/core.c
@@ -14,6 +14,7 @@
 #define pr_fmt(fmt) "pinctrl core: " fmt
 
 #include <linux/kernel.h>
+#include <linux/kref.h>
 #include <linux/export.h>
 #include <linux/init.h>
 #include <linux/device.h>
@@ -31,17 +32,6 @@
 #include "pinmux.h"
 #include "pinconf.h"
 
-/**
- * struct pinctrl_maps - a list item containing part of the mapping table
- * @node: mapping table list node
- * @maps: array of mapping table entries
- * @num_maps: the number of entries in @maps
- */
-struct pinctrl_maps {
-	struct list_head node;
-	struct pinctrl_map const *maps;
-	unsigned num_maps;
-};
 
 static bool pinctrl_dummy_state;
 
@@ -55,13 +45,8 @@
 static LIST_HEAD(pinctrl_list);
 
 /* List of pinctrl maps (struct pinctrl_maps) */
-static LIST_HEAD(pinctrl_maps);
+LIST_HEAD(pinctrl_maps);
 
-#define for_each_maps(_maps_node_, _i_, _map_) \
-	list_for_each_entry(_maps_node_, &pinctrl_maps, node) \
-		for (_i_ = 0, _map_ = &_maps_node_->maps[_i_]; \
-			_i_ < _maps_node_->num_maps; \
-			_i_++, _map_ = &_maps_node_->maps[_i_])
 
 /**
  * pinctrl_provide_dummies() - indicate if pinctrl provides dummy state support
@@ -83,6 +68,12 @@
 }
 EXPORT_SYMBOL_GPL(pinctrl_dev_get_name);
 
+const char *pinctrl_dev_get_devname(struct pinctrl_dev *pctldev)
+{
+	return dev_name(pctldev->dev);
+}
+EXPORT_SYMBOL_GPL(pinctrl_dev_get_devname);
+
 void *pinctrl_dev_get_drvdata(struct pinctrl_dev *pctldev)
 {
 	return pctldev->driver_data;
@@ -609,13 +600,16 @@
 
 	setting->pctldev = get_pinctrl_dev_from_devname(map->ctrl_dev_name);
 	if (setting->pctldev == NULL) {
-		dev_info(p->dev, "unknown pinctrl device %s in map entry, deferring probe",
-			map->ctrl_dev_name);
 		kfree(setting);
+		/* Do not defer probing of hogs (circular loop) */
+		if (!strcmp(map->ctrl_dev_name, map->dev_name))
+			return -ENODEV;
 		/*
 		 * OK let us guess that the driver is not there yet, and
 		 * let's defer obtaining this pinctrl handle to later...
 		 */
+		dev_info(p->dev, "unknown pinctrl device %s in map entry, deferring probe",
+			map->ctrl_dev_name);
 		return -EPROBE_DEFER;
 	}
 
@@ -694,11 +688,31 @@
 			continue;
 
 		ret = add_setting(p, map);
-		if (ret < 0) {
+		/*
+		 * At this point the adding of a setting may:
+		 *
+		 * - Defer, if the pinctrl device is not yet available
+		 * - Fail, if the pinctrl device is not yet available,
+		 *   AND the setting is a hog. We cannot defer that, since
+		 *   the hog will kick in immediately after the device
+		 *   is registered.
+		 *
+		 * If the error returned was not -EPROBE_DEFER then we
+		 * accumulate the errors to see if we end up with
+		 * an -EPROBE_DEFER later, as that is the worst case.
+		 */
+		if (ret == -EPROBE_DEFER) {
 			pinctrl_put_locked(p, false);
 			return ERR_PTR(ret);
 		}
 	}
+	if (ret < 0) {
+		/* If some other error than deferral occured, return here */
+		pinctrl_put_locked(p, false);
+		return ERR_PTR(ret);
+	}
+
+	kref_init(&p->users);
 
 	/* Add the pinctrl handle to the global list */
 	list_add_tail(&p->node, &pinctrl_list);
@@ -713,9 +727,17 @@
 	if (WARN_ON(!dev))
 		return ERR_PTR(-EINVAL);
 
+	/*
+	 * See if somebody else (such as the device core) has already
+	 * obtained a handle to the pinctrl for this device. In that case,
+	 * return another pointer to it.
+	 */
 	p = find_pinctrl(dev);
-	if (p != NULL)
-		return ERR_PTR(-EBUSY);
+	if (p != NULL) {
+		dev_dbg(dev, "obtain a copy of previously claimed pinctrl\n");
+		kref_get(&p->users);
+		return p;
+	}
 
 	return create_pinctrl(dev);
 }
@@ -771,13 +793,24 @@
 }
 
 /**
- * pinctrl_put() - release a previously claimed pinctrl handle
+ * pinctrl_release() - release the pinctrl handle
+ * @kref: the kref in the pinctrl being released
+ */
+static void pinctrl_release(struct kref *kref)
+{
+	struct pinctrl *p = container_of(kref, struct pinctrl, users);
+
+	pinctrl_put_locked(p, true);
+}
+
+/**
+ * pinctrl_put() - decrease use count on a previously claimed pinctrl handle
  * @p: the pinctrl handle to release
  */
 void pinctrl_put(struct pinctrl *p)
 {
 	mutex_lock(&pinctrl_mutex);
-	pinctrl_put_locked(p, true);
+	kref_put(&p->users, pinctrl_release);
 	mutex_unlock(&pinctrl_mutex);
 }
 EXPORT_SYMBOL_GPL(pinctrl_put);
@@ -1055,6 +1088,30 @@
 	}
 }
 
+/**
+ * pinctrl_force_sleep() - turn a given controller device into sleep state
+ * @pctldev: pin controller device
+ */
+int pinctrl_force_sleep(struct pinctrl_dev *pctldev)
+{
+	if (!IS_ERR(pctldev->p) && !IS_ERR(pctldev->hog_sleep))
+		return pinctrl_select_state(pctldev->p, pctldev->hog_sleep);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(pinctrl_force_sleep);
+
+/**
+ * pinctrl_force_default() - turn a given controller device into default state
+ * @pctldev: pin controller device
+ */
+int pinctrl_force_default(struct pinctrl_dev *pctldev)
+{
+	if (!IS_ERR(pctldev->p) && !IS_ERR(pctldev->hog_default))
+		return pinctrl_select_state(pctldev->p, pctldev->hog_default);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(pinctrl_force_default);
+
 #ifdef CONFIG_DEBUG_FS
 
 static int pinctrl_pins_show(struct seq_file *s, void *what)
@@ -1500,16 +1557,23 @@
 
 	pctldev->p = pinctrl_get_locked(pctldev->dev);
 	if (!IS_ERR(pctldev->p)) {
-		struct pinctrl_state *s =
+		pctldev->hog_default =
 			pinctrl_lookup_state_locked(pctldev->p,
 						    PINCTRL_STATE_DEFAULT);
-		if (IS_ERR(s)) {
+		if (IS_ERR(pctldev->hog_default)) {
 			dev_dbg(dev, "failed to lookup the default state\n");
 		} else {
-			if (pinctrl_select_state_locked(pctldev->p, s))
+			if (pinctrl_select_state_locked(pctldev->p,
+						pctldev->hog_default))
 				dev_err(dev,
 					"failed to select default state\n");
 		}
+
+		pctldev->hog_sleep =
+			pinctrl_lookup_state_locked(pctldev->p,
+						    PINCTRL_STATE_SLEEP);
+		if (IS_ERR(pctldev->hog_sleep))
+			dev_dbg(dev, "failed to lookup the sleep state\n");
 	}
 
 	mutex_unlock(&pinctrl_mutex);
diff --git a/drivers/pinctrl/core.h b/drivers/pinctrl/core.h
index 12f5694..ee72f1f 100644
--- a/drivers/pinctrl/core.h
+++ b/drivers/pinctrl/core.h
@@ -9,6 +9,7 @@
  * License terms: GNU General Public License (GPL) version 2
  */
 
+#include <linux/kref.h>
 #include <linux/mutex.h>
 #include <linux/radix-tree.h>
 #include <linux/pinctrl/pinconf.h>
@@ -30,6 +31,8 @@
  * @driver_data: driver data for drivers registering to the pin controller
  *	subsystem
  * @p: result of pinctrl_get() for this device
+ * @hog_default: default state for pins hogged by this device
+ * @hog_sleep: sleep state for pins hogged by this device
  * @device_root: debugfs root for this device
  */
 struct pinctrl_dev {
@@ -41,6 +44,8 @@
 	struct module *owner;
 	void *driver_data;
 	struct pinctrl *p;
+	struct pinctrl_state *hog_default;
+	struct pinctrl_state *hog_sleep;
 #ifdef CONFIG_DEBUG_FS
 	struct dentry *device_root;
 #endif
@@ -54,6 +59,7 @@
  * @state: the current state
  * @dt_maps: the mapping table chunks dynamically parsed from device tree for
  *	this device, if any
+ * @users: reference count
  */
 struct pinctrl {
 	struct list_head node;
@@ -61,6 +67,7 @@
 	struct list_head states;
 	struct pinctrl_state *state;
 	struct list_head dt_maps;
+	struct kref users;
 };
 
 /**
@@ -148,6 +155,18 @@
 #endif
 };
 
+/**
+ * struct pinctrl_maps - a list item containing part of the mapping table
+ * @node: mapping table list node
+ * @maps: array of mapping table entries
+ * @num_maps: the number of entries in @maps
+ */
+struct pinctrl_maps {
+	struct list_head node;
+	struct pinctrl_map const *maps;
+	unsigned num_maps;
+};
+
 struct pinctrl_dev *get_pinctrl_dev_from_devname(const char *dev_name);
 int pin_get_from_name(struct pinctrl_dev *pctldev, const char *name);
 const char *pin_get_name(struct pinctrl_dev *pctldev, const unsigned pin);
@@ -164,5 +183,15 @@
 			 bool dup, bool locked);
 void pinctrl_unregister_map(struct pinctrl_map const *map);
 
+extern int pinctrl_force_sleep(struct pinctrl_dev *pctldev);
+extern int pinctrl_force_default(struct pinctrl_dev *pctldev);
+
 extern struct mutex pinctrl_mutex;
 extern struct list_head pinctrldev_list;
+extern struct list_head pinctrl_maps;
+
+#define for_each_maps(_maps_node_, _i_, _map_) \
+	list_for_each_entry(_maps_node_, &pinctrl_maps, node) \
+		for (_i_ = 0, _map_ = &_maps_node_->maps[_i_]; \
+			_i_ < _maps_node_->num_maps; \
+			_i_++, _map_ = &_maps_node_->maps[_i_])
diff --git a/drivers/pinctrl/devicetree.c b/drivers/pinctrl/devicetree.c
index fe2d1af..fd40a11 100644
--- a/drivers/pinctrl/devicetree.c
+++ b/drivers/pinctrl/devicetree.c
@@ -141,6 +141,11 @@
 		pctldev = find_pinctrl_by_of_node(np_pctldev);
 		if (pctldev)
 			break;
+		/* Do not defer probing of hogs (circular loop) */
+		if (np_pctldev == p->dev->of_node) {
+			of_node_put(np_pctldev);
+			return -ENODEV;
+		}
 	}
 	of_node_put(np_pctldev);
 
diff --git a/drivers/pinctrl/pinconf-generic.c b/drivers/pinctrl/pinconf-generic.c
index 833a364..06c304a 100644
--- a/drivers/pinctrl/pinconf-generic.c
+++ b/drivers/pinctrl/pinconf-generic.c
@@ -41,11 +41,13 @@
 	PCONFDUMP(PIN_CONFIG_DRIVE_PUSH_PULL, "output drive push pull", NULL),
 	PCONFDUMP(PIN_CONFIG_DRIVE_OPEN_DRAIN, "output drive open drain", NULL),
 	PCONFDUMP(PIN_CONFIG_DRIVE_OPEN_SOURCE, "output drive open source", NULL),
-	PCONFDUMP(PIN_CONFIG_INPUT_SCHMITT_DISABLE, "input schmitt disabled", NULL),
+	PCONFDUMP(PIN_CONFIG_INPUT_SCHMITT_ENABLE, "input schmitt enabled", NULL),
 	PCONFDUMP(PIN_CONFIG_INPUT_SCHMITT, "input schmitt trigger", NULL),
 	PCONFDUMP(PIN_CONFIG_INPUT_DEBOUNCE, "input debounce", "time units"),
 	PCONFDUMP(PIN_CONFIG_POWER_SOURCE, "pin power source", "selector"),
+	PCONFDUMP(PIN_CONFIG_SLEW_RATE, "slew rate", NULL),
 	PCONFDUMP(PIN_CONFIG_LOW_POWER_MODE, "pin low power", "mode"),
+	PCONFDUMP(PIN_CONFIG_OUTPUT, "pin output", "level"),
 };
 
 void pinconf_generic_dump_pin(struct pinctrl_dev *pctldev,
diff --git a/drivers/pinctrl/pinconf.c b/drivers/pinctrl/pinconf.c
index baee2cc..ac8d382 100644
--- a/drivers/pinctrl/pinconf.c
+++ b/drivers/pinctrl/pinconf.c
@@ -574,6 +574,207 @@
 	.release	= single_release,
 };
 
+/* 32bit read/write ressources */
+#define MAX_NAME_LEN 16
+char dbg_pinname[MAX_NAME_LEN]; /* shared: name of the state of the pin*/
+char dbg_state_name[MAX_NAME_LEN]; /* shared: state of the pin*/
+static u32 dbg_config; /* shared: config to be read/set for the pin & state*/
+
+static int pinconf_dbg_pinname_print(struct seq_file *s, void *d)
+{
+	if (strlen(dbg_pinname))
+		seq_printf(s, "%s\n", dbg_pinname);
+	else
+		seq_printf(s, "No pin name set\n");
+	return 0;
+}
+
+static int pinconf_dbg_pinname_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, pinconf_dbg_pinname_print, inode->i_private);
+}
+
+static int pinconf_dbg_pinname_write(struct file *file,
+	const char __user *user_buf, size_t count, loff_t *ppos)
+{
+	int err;
+
+	if (count > MAX_NAME_LEN)
+		return -EINVAL;
+
+	err = sscanf(user_buf, "%15s", dbg_pinname);
+
+	if (err != 1)
+		return -EINVAL;
+
+	return count;
+}
+
+static const struct file_operations pinconf_dbg_pinname_fops = {
+	.open = pinconf_dbg_pinname_open,
+	.write = pinconf_dbg_pinname_write,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = single_release,
+	.owner = THIS_MODULE,
+};
+
+static int pinconf_dbg_state_print(struct seq_file *s, void *d)
+{
+	if (strlen(dbg_state_name))
+		seq_printf(s, "%s\n", dbg_pinname);
+	else
+		seq_printf(s, "No pin state set\n");
+	return 0;
+}
+
+static int pinconf_dbg_state_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, pinconf_dbg_state_print, inode->i_private);
+}
+
+static int pinconf_dbg_state_write(struct file *file,
+	const char __user *user_buf, size_t count, loff_t *ppos)
+{
+	int err;
+
+	if (count > MAX_NAME_LEN)
+		return -EINVAL;
+
+	err = sscanf(user_buf, "%15s", dbg_state_name);
+
+	if (err != 1)
+		return -EINVAL;
+
+	return count;
+}
+
+static const struct file_operations pinconf_dbg_pinstate_fops = {
+	.open = pinconf_dbg_state_open,
+	.write = pinconf_dbg_state_write,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = single_release,
+	.owner = THIS_MODULE,
+};
+
+/**
+ * pinconf_dbg_config_print() - display the pinctrl config from the pinctrl
+ * map, of a pin/state pair based on pinname and state that have been
+ * selected with the debugfs entries pinconf-name and pinconf-state
+ * @s: contains the 32bits config to be written
+ * @d: not used
+ */
+static int pinconf_dbg_config_print(struct seq_file *s, void *d)
+{
+	struct pinctrl_maps *maps_node;
+	struct pinctrl_map const *map;
+	struct pinctrl_dev *pctldev = NULL;
+	struct pinconf_ops *confops = NULL;
+	int i, j;
+	bool found = false;
+
+	mutex_lock(&pinctrl_mutex);
+
+	/* Parse the pinctrl map and look for the elected pin/state */
+	for_each_maps(maps_node, i, map) {
+		if (map->type != PIN_MAP_TYPE_CONFIGS_PIN)
+			continue;
+
+		if (strncmp(map->name, dbg_state_name, MAX_NAME_LEN) > 0)
+			continue;
+
+		for (j = 0; j < map->data.configs.num_configs; j++) {
+			if (0 == strncmp(map->data.configs.group_or_pin,
+						dbg_pinname, MAX_NAME_LEN)) {
+				/* We found the right pin / state, read the
+				 * config and store the pctldev */
+				dbg_config = map->data.configs.configs[j];
+				pctldev = get_pinctrl_dev_from_devname
+					(map->ctrl_dev_name);
+				found = true;
+				break;
+			}
+		}
+	}
+
+	mutex_unlock(&pinctrl_mutex);
+
+	if (found) {
+		seq_printf(s, "Config of %s in state %s: 0x%08X\n", dbg_pinname,
+				 dbg_state_name, dbg_config);
+
+		if (pctldev)
+			confops = pctldev->desc->confops;
+
+		if (confops && confops->pin_config_config_dbg_show)
+			confops->pin_config_config_dbg_show(pctldev,
+					s, dbg_config);
+	} else {
+		seq_printf(s, "No pin found for defined name/state\n");
+	}
+
+	return 0;
+}
+
+static int pinconf_dbg_config_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, pinconf_dbg_config_print, inode->i_private);
+}
+
+/**
+ * pinconf_dbg_config_write() - overwrite the pinctrl config in thepinctrl
+ * map, of a pin/state pair based on pinname and state that have been
+ * selected with the debugfs entries pinconf-name and pinconf-state
+ */
+static int pinconf_dbg_config_write(struct file *file,
+	const char __user *user_buf, size_t count, loff_t *ppos)
+{
+	int err;
+	unsigned long config;
+	struct pinctrl_maps *maps_node;
+	struct pinctrl_map const *map;
+	int i, j;
+
+	err = kstrtoul_from_user(user_buf, count, 0, &config);
+
+	if (err)
+		return err;
+
+	dbg_config = config;
+
+	mutex_lock(&pinctrl_mutex);
+
+	/* Parse the pinctrl map and look for the selected pin/state */
+	for_each_maps(maps_node, i, map) {
+		if (map->type != PIN_MAP_TYPE_CONFIGS_PIN)
+			continue;
+
+		if (strncmp(map->name, dbg_state_name, MAX_NAME_LEN) > 0)
+			continue;
+
+		/*  we found the right pin / state, so overwrite config */
+		for (j = 0; j < map->data.configs.num_configs; j++) {
+			if (strncmp(map->data.configs.group_or_pin, dbg_pinname,
+						MAX_NAME_LEN) == 0)
+				map->data.configs.configs[j] = dbg_config;
+		}
+	}
+
+	mutex_unlock(&pinctrl_mutex);
+
+	return count;
+}
+
+static const struct file_operations pinconf_dbg_pinconfig_fops = {
+	.open = pinconf_dbg_config_open,
+	.write = pinconf_dbg_config_write,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = single_release,
+	.owner = THIS_MODULE,
+};
+
 void pinconf_init_device_debugfs(struct dentry *devroot,
 			 struct pinctrl_dev *pctldev)
 {
@@ -581,6 +782,12 @@
 			    devroot, pctldev, &pinconf_pins_ops);
 	debugfs_create_file("pinconf-groups", S_IFREG | S_IRUGO,
 			    devroot, pctldev, &pinconf_groups_ops);
+	debugfs_create_file("pinconf-name", (S_IRUGO | S_IWUSR | S_IWGRP),
+			    devroot, pctldev, &pinconf_dbg_pinname_fops);
+	debugfs_create_file("pinconf-state",  (S_IRUGO | S_IWUSR | S_IWGRP),
+			    devroot, pctldev, &pinconf_dbg_pinstate_fops);
+	debugfs_create_file("pinconf-config",  (S_IRUGO | S_IWUSR | S_IWGRP),
+			    devroot, pctldev, &pinconf_dbg_pinconfig_fops);
 }
 
 #endif
diff --git a/drivers/pinctrl/pinctrl-ab8500.c b/drivers/pinctrl/pinctrl-ab8500.c
new file mode 100644
index 0000000..3b471d8
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-ab8500.c
@@ -0,0 +1,484 @@
+/*
+ * 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
+ */
+
+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
+ */
+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
new file mode 100644
index 0000000..3a4238e
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-ab8505.c
@@ -0,0 +1,380 @@
+/*
+ * 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
+ */
+
+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, UNUSED, 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
+ */
+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
new file mode 100644
index 0000000..8ee1e8d
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-ab8540.c
@@ -0,0 +1,407 @@
+/*
+ * 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
+ *
+ */
+
+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
+ */
+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
new file mode 100644
index 0000000..7610bd0
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-ab9540.c
@@ -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 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
+ */
+
+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, UNUSED, 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 */
+};
+
+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
new file mode 100644
index 0000000..caecdd3
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-abx500.c
@@ -0,0 +1,1012 @@
+/*
+ * 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/mfd/abx500/ab8500-gpio.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 "pinctrl-abx500.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
+
+struct abx500_pinctrl {
+	struct device *dev;
+	struct pinctrl_dev *pctldev;
+	struct abx500_pinctrl_soc_data *soc;
+	struct gpio_chip chip;
+	struct ab8500 *parent;
+	struct mutex lock;
+	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\n",
+			__func__, reg, offset);
+
+	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 failed\n", __func__);
+
+	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;
+	int ret;
+
+	ret = abx500_gpio_get_bit(chip, AB8500_GPIO_IN1_REG,
+				  offset, &bit);
+	if (ret < 0) {
+		dev_err(pct->dev, "%s failed\n", __func__);
+		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\n", __func__);
+}
+
+static int abx500_config_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 << 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 int abx500_gpio_direction_output(struct gpio_chip *chip,
+					unsigned offset,
+					int val)
+{
+	struct abx500_pinctrl *pct = to_abx500_pinctrl(chip);
+	struct pullud *pullud = pct->soc->pullud;
+	unsigned gpio;
+	int ret;
+
+	/* set direction as output */
+	ret = abx500_gpio_set_bits(chip, AB8500_GPIO_DIR1_REG, offset, 1);
+	if (ret < 0)
+		return ret;
+
+	/* disable pull down */
+	ret = abx500_gpio_set_bits(chip, AB8500_GPIO_PUD1_REG, offset, 1);
+	if (ret < 0)
+		return ret;
+
+	/* if supported, disable both pull down and pull up */
+	gpio = offset + 1;
+	if (pullud && gpio >= pullud->first_pin && gpio <= pullud->last_pin) {
+		ret = abx500_config_pull_updown(pct,
+				gpio,
+				ABX500_GPIO_PULL_NONE);
+		if (ret < 0)
+			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, 0);
+}
+
+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);
+			ret = abx500_gpio_set_bits(chip,
+					AB8500_GPIO_ALTFUN_REG,
+					af.alt_bit1,
+					!!(af.alta_val && BIT(0)));
+			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);
+		ret = abx500_gpio_set_bits(chip, AB8500_GPIO_ALTFUN_REG,
+				af.alt_bit1, !!(af.altb_val && BIT(0)));
+		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);
+		ret = abx500_gpio_set_bits(chip, AB8500_GPIO_ALTFUN_REG,
+				af.alt_bit2, !!(af.altc_val && BIT(0)));
+		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;
+	}
+
+	return ret;
+}
+
+static u8 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;
+
+	/*
+	 * 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 */
+	abx500_gpio_get_bit(chip, AB8500_GPIO_SEL1_REG + (offset / 8),
+			af.gpiosel_bit, &bit_mode);
+	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_bit1 == 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
+	 */
+	abx500_gpio_get_bit(chip, AB8500_GPIO_ALTFUN_REG,
+			    af.alt_bit1, &alt_bit1);
+
+	if (af.alt_bit2 != UNUSED)
+		/* read alt_bit2 value */
+		abx500_gpio_get_bit(chip, AB8500_GPIO_ALTFUN_REG, af.alt_bit2,
+				&alt_bit2);
+	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;
+}
+
+#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)
+{
+	const char *label = gpiochip_is_requested(chip, offset - 1);
+	u8 gpio_offset = offset - 1;
+	int mode = -1;
+	bool is_out;
+	bool pull;
+
+	const char *modes[] = {
+		[ABX500_DEFAULT]	= "default",
+		[ABX500_ALT_A]		= "altA",
+		[ABX500_ALT_B]		= "altB",
+		[ABX500_ALT_C]		= "altC",
+	};
+
+	abx500_gpio_get_bit(chip, AB8500_GPIO_DIR1_REG, gpio_offset, &is_out);
+	abx500_gpio_get_bit(chip, AB8500_GPIO_PUD1_REG, gpio_offset, &pull);
+
+	if (pctldev)
+		mode = abx500_get_mode(pctldev, chip, offset);
+
+	seq_printf(s, " gpio-%-3d (%-20.20s) %-3s %-9s %s",
+		   gpio, label ?: "(none)",
+		   is_out ? "out" : "in ",
+		   is_out ?
+		   (chip->get
+		   ? (chip->get(chip, offset) ? "hi" : "lo")
+		   : "?  ")
+		   : (pull ? "pull up" : "pull down"),
+		   (mode < 0) ? "unknown" : modes[mode]);
+}
+
+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
+
+int abx500_gpio_request(struct gpio_chip *chip, unsigned offset)
+{
+	int gpio = chip->base + offset;
+
+	return pinctrl_request_gpio(gpio);
+}
+
+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);
+	}
+
+	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);
+}
+
+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;
+	}
+
+	return ret;
+}
+
+static void abx500_gpio_disable_free(struct pinctrl_dev *pctldev,
+				     struct pinctrl_gpio_range *range,
+				     unsigned offset)
+{
+}
+
+static 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 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,
+};
+
+int abx500_pin_config_get(struct pinctrl_dev *pctldev,
+			  unsigned pin,
+			  unsigned long *config)
+{
+	return -ENOSYS;
+}
+
+int abx500_pin_config_set(struct pinctrl_dev *pctldev,
+			  unsigned pin,
+			  unsigned long config)
+{
+	struct abx500_pinctrl *pct = pinctrl_dev_get_drvdata(pctldev);
+	struct pullud *pullud = pct->soc->pullud;
+	struct gpio_chip *chip = &pct->chip;
+	unsigned offset;
+	int ret;
+	enum pin_config_param param = pinconf_to_config_param(config);
+	enum pin_config_param argument = pinconf_to_config_argument(config);
+
+	dev_dbg(chip->dev, "pin %d [%#lx]: %s %s\n",
+		pin, config, (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_PULL_DOWN:
+		/*
+		 * if argument = 1 set the pull down
+		 * else clear the pull down
+		 */
+		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, we
+		 * fall back to the old bit set that only support pull down.
+		 */
+		if (pullud &&
+		    pin >= pullud->first_pin &&
+		    pin <= pullud->last_pin)
+			ret = abx500_config_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 ? 0 : 1);
+		break;
+
+	case PIN_CONFIG_OUTPUT:
+		ret = abx500_gpio_direction_output(chip, offset, argument);
+
+		break;
+
+	default:
+		dev_err(chip->dev, "illegal configuration requested\n");
+
+		return -EINVAL;
+	}
+
+	return ret;
+}
+
+static 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 ab8500_platform_data *abx500_pdata =
+				dev_get_platdata(pdev->dev.parent);
+	struct abx500_gpio_platform_data *pdata = NULL;
+	struct device_node *np = pdev->dev.of_node;
+	struct abx500_pinctrl *pct;
+	const struct platform_device_id *platid = platform_get_device_id(pdev);
+	unsigned int id = -1;
+	int ret, err;
+	int i;
+
+	if (abx500_pdata)
+		pdata = abx500_pdata->gpio;
+	if (!pdata) {
+		if (np) {
+			const struct of_device_id *match;
+
+			match = of_match_device(abx500_gpio_match, &pdev->dev);
+			if (!match)
+				return -ENODEV;
+			id = (unsigned long)match->data;
+		} else {
+			dev_err(&pdev->dev, "gpio dt and platform data missing\n");
+			return -ENODEV;
+		}
+	}
+
+	if (platid)
+		id = platid->driver_data;
+
+	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 = pdata->gpio_base;
+	pct->chip.base = (np) ? -1 : pdata->gpio_base;
+
+	/* initialize the lock */
+	mutex_init(&pct->lock);
+
+	/* 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",
+				(int) platid->driver_data);
+		mutex_destroy(&pct->lock);
+		return -EINVAL;
+	}
+
+	if (!pct->soc) {
+		dev_err(&pdev->dev, "Invalid SOC data\n");
+		mutex_destroy(&pct->lock);
+		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);
+		mutex_destroy(&pct->lock);
+		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");
+
+	mutex_destroy(&pct->lock);
+	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;
+	}
+
+	mutex_destroy(&pct->lock);
+
+	return 0;
+}
+
+static const struct platform_device_id abx500_pinctrl_id[] = {
+	{ "pinctrl-ab8500", PINCTRL_AB8500 },
+	{ "pinctrl-ab8540", PINCTRL_AB8540 },
+	{ "pinctrl-ab9540", PINCTRL_AB9540 },
+	{ "pinctrl-ab8505", PINCTRL_AB8505 },
+	{ },
+};
+
+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,
+	.id_table = abx500_pinctrl_id,
+};
+
+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
new file mode 100644
index 0000000..eeca8f9
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-abx500.h
@@ -0,0 +1,234 @@
+#ifndef PINCTRL_PINCTRL_ABx5O0_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,
+};
+
+/**
+ * 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/pinctrl-falcon.c b/drivers/pinctrl/pinctrl-falcon.c
index 8ed20e8..4a0d54a 100644
--- a/drivers/pinctrl/pinctrl-falcon.c
+++ b/drivers/pinctrl/pinctrl-falcon.c
@@ -170,7 +170,7 @@
 static const unsigned pins_ntr8k[] = {GPIO5};
 static const unsigned pins_hrst[] = {GPIO6};
 static const unsigned pins_mdio[] = {GPIO7, GPIO8};
-static const unsigned pins_bled[] = {GPIO7, GPIO10, GPIO11,
+static const unsigned pins_bled[] = {GPIO9, GPIO10, GPIO11,
 					GPIO12, GPIO13, GPIO14};
 static const unsigned pins_asc0[] = {GPIO32, GPIO33};
 static const unsigned pins_spi[] = {GPIO34, GPIO35, GPIO36};
@@ -315,6 +315,37 @@
 static void falcon_pinconf_dbg_show(struct pinctrl_dev *pctrldev,
 			struct seq_file *s, unsigned offset)
 {
+	unsigned long config;
+	struct pin_desc *desc;
+
+	struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
+	int port = PORT(offset);
+
+	seq_printf(s, " (port %d) mux %d -- ", port,
+		pad_r32(info->membase[port], LTQ_PADC_MUX(PORT_PIN(offset))));
+
+	config = LTQ_PINCONF_PACK(LTQ_PINCONF_PARAM_PULL, 0);
+	if (!falcon_pinconf_get(pctrldev, offset, &config))
+		seq_printf(s, "pull %d ",
+			(int)LTQ_PINCONF_UNPACK_ARG(config));
+
+	config = LTQ_PINCONF_PACK(LTQ_PINCONF_PARAM_DRIVE_CURRENT, 0);
+	if (!falcon_pinconf_get(pctrldev, offset, &config))
+		seq_printf(s, "drive-current %d ",
+			(int)LTQ_PINCONF_UNPACK_ARG(config));
+
+	config = LTQ_PINCONF_PACK(LTQ_PINCONF_PARAM_SLEW_RATE, 0);
+	if (!falcon_pinconf_get(pctrldev, offset, &config))
+		seq_printf(s, "slew-rate %d ",
+			(int)LTQ_PINCONF_UNPACK_ARG(config));
+
+	desc = pin_desc_get(pctrldev, offset);
+	if (desc) {
+		if (desc->gpio_owner)
+			seq_printf(s, " owner: %s", desc->gpio_owner);
+	} else {
+		seq_printf(s, " not registered");
+	}
 }
 
 static void falcon_pinconf_group_dbg_show(struct pinctrl_dev *pctrldev,
@@ -360,6 +391,8 @@
 static struct ltq_pinmux_info falcon_info = {
 	.desc		= &falcon_pctrl_desc,
 	.apply_mux	= falcon_mux_apply,
+	.params		= falcon_cfg_params,
+	.num_params	= ARRAY_SIZE(falcon_cfg_params),
 };
 
 
@@ -398,6 +431,9 @@
 		u32 avail;
 		int pins;
 
+		if (!of_device_is_available(np))
+			continue;
+
 		if (!ppdev) {
 			dev_err(&pdev->dev, "failed to find pad pdev\n");
 			continue;
diff --git a/drivers/pinctrl/pinctrl-lantiq.c b/drivers/pinctrl/pinctrl-lantiq.c
index 15f501d..a703846 100644
--- a/drivers/pinctrl/pinctrl-lantiq.c
+++ b/drivers/pinctrl/pinctrl-lantiq.c
@@ -64,11 +64,13 @@
 	seq_printf(s, " %s", dev_name(pctldev->dev));
 }
 
-static int ltq_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
+static void ltq_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
 				struct device_node *np,
 				struct pinctrl_map **map)
 {
 	struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctldev);
+	struct property *pins = of_find_property(np, "lantiq,pins", NULL);
+	struct property *groups = of_find_property(np, "lantiq,groups", NULL);
 	unsigned long configs[3];
 	unsigned num_configs = 0;
 	struct property *prop;
@@ -76,8 +78,20 @@
 	const char *function;
 	int ret, i;
 
+	if (!pins && !groups) {
+		dev_err(pctldev->dev, "%s defines neither pins nor groups\n",
+			np->name);
+		return;
+	}
+
+	if (pins && groups) {
+		dev_err(pctldev->dev, "%s defines both pins and groups\n",
+			np->name);
+		return;
+	}
+
 	ret = of_property_read_string(np, "lantiq,function", &function);
-	if (!ret) {
+	if (groups && !ret) {
 		of_property_for_each_string(np, "lantiq,groups", prop, group) {
 			(*map)->type = PIN_MAP_TYPE_MUX_GROUP;
 			(*map)->name = function;
@@ -85,11 +99,6 @@
 			(*map)->data.mux.function = function;
 			(*map)++;
 		}
-		if (of_find_property(np, "lantiq,pins", NULL))
-			dev_err(pctldev->dev,
-				"%s mixes pins and groups settings\n",
-				np->name);
-		return 0;
 	}
 
 	for (i = 0; i < info->num_params; i++) {
@@ -103,7 +112,7 @@
 	}
 
 	if (!num_configs)
-		return -EINVAL;
+		return;
 
 	of_property_for_each_string(np, "lantiq,pins", prop, pin) {
 		(*map)->data.configs.configs = kmemdup(configs,
@@ -115,7 +124,16 @@
 		(*map)->data.configs.num_configs = num_configs;
 		(*map)++;
 	}
-	return 0;
+	of_property_for_each_string(np, "lantiq,groups", prop, group) {
+		(*map)->data.configs.configs = kmemdup(configs,
+					num_configs * sizeof(unsigned long),
+					GFP_KERNEL);
+		(*map)->type = PIN_MAP_TYPE_CONFIGS_GROUP;
+		(*map)->name = group;
+		(*map)->data.configs.group_or_pin = group;
+		(*map)->data.configs.num_configs = num_configs;
+		(*map)++;
+	}
 }
 
 static int ltq_pinctrl_dt_subnode_size(struct device_node *np)
@@ -135,23 +153,19 @@
 {
 	struct pinctrl_map *tmp;
 	struct device_node *np;
-	int ret;
+	int max_maps = 0;
 
-	*num_maps = 0;
 	for_each_child_of_node(np_config, np)
-		*num_maps += ltq_pinctrl_dt_subnode_size(np);
-	*map = kzalloc(*num_maps * sizeof(struct pinctrl_map), GFP_KERNEL);
+		max_maps += ltq_pinctrl_dt_subnode_size(np);
+	*map = kzalloc(max_maps * sizeof(struct pinctrl_map) * 2, GFP_KERNEL);
 	if (!*map)
 		return -ENOMEM;
 	tmp = *map;
 
-	for_each_child_of_node(np_config, np) {
-		ret = ltq_pinctrl_dt_subnode_to_map(pctldev, np, &tmp);
-		if (ret < 0) {
-			ltq_pinctrl_dt_free_map(pctldev, *map, *num_maps);
-			return ret;
-		}
-	}
+	for_each_child_of_node(np_config, np)
+		ltq_pinctrl_dt_subnode_to_map(pctldev, np, &tmp);
+	*num_maps = ((int)(tmp - *map));
+
 	return 0;
 }
 
@@ -280,7 +294,7 @@
 				unsigned pin)
 {
 	struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
-	int mfp = match_mfp(info, pin + (range->id * 32));
+	int mfp = match_mfp(info, pin);
 	int pin_func;
 
 	if (mfp < 0) {
diff --git a/drivers/pinctrl/pinctrl-lantiq.h b/drivers/pinctrl/pinctrl-lantiq.h
index 4419d32..6d07f02 100644
--- a/drivers/pinctrl/pinctrl-lantiq.h
+++ b/drivers/pinctrl/pinctrl-lantiq.h
@@ -34,6 +34,7 @@
 	LTQ_PINCONF_PARAM_OPEN_DRAIN,
 	LTQ_PINCONF_PARAM_DRIVE_CURRENT,
 	LTQ_PINCONF_PARAM_SLEW_RATE,
+	LTQ_PINCONF_PARAM_OUTPUT,
 };
 
 struct ltq_cfg_param {
diff --git a/drivers/pinctrl/pinctrl-nomadik.c b/drivers/pinctrl/pinctrl-nomadik.c
index 5767b18..de9e851 100644
--- a/drivers/pinctrl/pinctrl-nomadik.c
+++ b/drivers/pinctrl/pinctrl-nomadik.c
@@ -25,6 +25,8 @@
 #include <linux/irqdomain.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>
@@ -32,8 +34,8 @@
 #include <linux/pinctrl/consumer.h>
 #include <linux/platform_data/pinctrl-nomadik.h>
 #include <asm/mach/irq.h>
-#include <mach/irqs.h>
 #include "pinctrl-nomadik.h"
+#include "core.h"
 
 /*
  * The GPIO module in the Nomadik family of Systems-on-Chip is an
@@ -216,7 +218,7 @@
 	u32 falling = nmk_chip->fimsc & BIT(offset);
 	u32 rising = nmk_chip->rimsc & BIT(offset);
 	int gpio = nmk_chip->chip.base + offset;
-	int irq = NOMADIK_GPIO_TO_IRQ(gpio);
+	int irq = irq_find_mapping(nmk_chip->domain, offset);
 	struct irq_data *d = irq_get_irq_data(irq);
 
 	if (!rising && !falling)
@@ -1341,8 +1343,7 @@
 
 		if (of_property_read_u32(np, "gpio-bank", &dev->id)) {
 			dev_err(&dev->dev, "gpio-bank property not found\n");
-			ret = -EINVAL;
-			goto out;
+			return -EINVAL;
 		}
 
 		pdata->first_gpio = dev->id * NMK_GPIO_PER_CHIP;
@@ -1350,41 +1351,29 @@
 	}
 
 	res = platform_get_resource(dev, IORESOURCE_MEM, 0);
-	if (!res) {
-		ret = -ENOENT;
-		goto out;
-	}
+	if (!res)
+		return -ENOENT;
 
 	irq = platform_get_irq(dev, 0);
-	if (irq < 0) {
-		ret = irq;
-		goto out;
-	}
+	if (irq < 0)
+		return irq;
 
 	secondary_irq = platform_get_irq(dev, 1);
-	if (secondary_irq >= 0 && !pdata->get_secondary_status) {
-		ret = -EINVAL;
-		goto out;
-	}
+	if (secondary_irq >= 0 && !pdata->get_secondary_status)
+		return -EINVAL;
 
 	base = devm_request_and_ioremap(&dev->dev, res);
-	if (!base) {
-		ret = -ENOMEM;
-		goto out;
-	}
+	if (!base)
+		return -ENOMEM;
 
 	clk = devm_clk_get(&dev->dev, NULL);
-	if (IS_ERR(clk)) {
-		ret = PTR_ERR(clk);
-		goto out;
-	}
+	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) {
-		ret = -ENOMEM;
-		goto out;
-	}
+	if (!nmk_chip)
+		return -ENOMEM;
 
 	/*
 	 * The virt address in nmk_chip->addr is in the nomadik register space,
@@ -1418,7 +1407,7 @@
 
 	ret = gpiochip_add(&nmk_chip->chip);
 	if (ret)
-		goto out;
+		return ret;
 
 	BUG_ON(nmk_chip->bank >= ARRAY_SIZE(nmk_gpio_chips));
 
@@ -1427,14 +1416,15 @@
 	platform_set_drvdata(dev, nmk_chip);
 
 	if (!np)
-		irq_start = NOMADIK_GPIO_TO_IRQ(pdata->first_gpio);
+		irq_start = pdata->first_irq;
 	nmk_chip->domain = irq_domain_add_simple(np,
 				NMK_GPIO_PER_CHIP, irq_start,
 				&nmk_gpio_irq_simple_ops, nmk_chip);
 	if (!nmk_chip->domain) {
 		dev_err(&dev->dev, "failed to create irqdomain\n");
-		ret = -ENOSYS;
-		goto out;
+		/* Just do this, no matter if it fails */
+		ret = gpiochip_remove(&nmk_chip->chip);
+		return -ENOSYS;
 	}
 
 	nmk_gpio_init_irq(nmk_chip);
@@ -1442,12 +1432,6 @@
 	dev_info(&dev->dev, "at address %p\n", nmk_chip->addr);
 
 	return 0;
-
-out:
-	dev_err(&dev->dev, "Failure %i for GPIO %i-%i\n", ret,
-		  pdata->first_gpio, pdata->first_gpio+31);
-
-	return ret;
 }
 
 static int nmk_get_groups_cnt(struct pinctrl_dev *pctldev)
@@ -1508,11 +1492,285 @@
 	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;
+}
+
+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;
+}
+
+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 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)
@@ -1846,16 +2104,39 @@
 
 static const struct of_device_id nmk_pinctrl_match[] = {
 	{
-		.compatible = "stericsson,nmk_pinctrl",
+		.compatible = "stericsson,nmk-pinctrl",
 		.data = (void *)PINCTRL_NMK_DB8500,
 	},
 	{},
 };
 
+static int nmk_pinctrl_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	struct nmk_pinctrl *npct;
+
+	npct = platform_get_drvdata(pdev);
+	if (!npct)
+		return -EINVAL;
+
+	return pinctrl_force_sleep(npct->pctl);
+}
+
+static int nmk_pinctrl_resume(struct platform_device *pdev)
+{
+	struct nmk_pinctrl *npct;
+
+	npct = platform_get_drvdata(pdev);
+	if (!npct)
+		return -EINVAL;
+
+	return pinctrl_force_default(npct->pctl);
+}
+
 static int nmk_pinctrl_probe(struct platform_device *pdev)
 {
 	const struct platform_device_id *platid = platform_get_device_id(pdev);
 	struct device_node *np = pdev->dev.of_node;
+	struct device_node *prcm_np;
 	struct nmk_pinctrl *npct;
 	struct resource *res;
 	unsigned int version = 0;
@@ -1884,21 +2165,26 @@
 	if (version == PINCTRL_NMK_DB8540)
 		nmk_pinctrl_db8540_init(&npct->soc);
 
+	if (np) {
+		prcm_np = of_parse_phandle(np, "prcm", 0);
+		if (prcm_np)
+			npct->prcm_base = of_iomap(prcm_np, 0);
+	}
+
+	/* Allow platform passed information to over-write DT. */
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (res) {
+	if (res)
 		npct->prcm_base = devm_ioremap(&pdev->dev, res->start,
 					       resource_size(res));
-		if (!npct->prcm_base) {
-			dev_err(&pdev->dev,
-				"failed to ioremap PRCM registers\n");
-			return -ENOMEM;
+	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;
 		}
-	} else if (version == PINCTRL_NMK_STN8815) {
-		dev_info(&pdev->dev,
-			 "No PRCM base, assume no ALT-Cx control is available\n");
-	} else {
-		dev_err(&pdev->dev, "missing PRCM base address\n");
-		return -EINVAL;
 	}
 
 	/*
@@ -1963,6 +2249,10 @@
 	},
 	.probe = nmk_pinctrl_probe,
 	.id_table = nmk_pinctrl_id,
+#ifdef CONFIG_PM
+	.suspend = nmk_pinctrl_suspend,
+	.resume = nmk_pinctrl_resume,
+#endif
 };
 
 static int __init nmk_gpio_init(void)
diff --git a/drivers/pinctrl/pinctrl-samsung.c b/drivers/pinctrl/pinctrl-samsung.c
index fd7b24c..5c20ed0 100644
--- a/drivers/pinctrl/pinctrl-samsung.c
+++ b/drivers/pinctrl/pinctrl-samsung.c
@@ -716,7 +716,6 @@
 	}
 	ctrldesc->pins = pindesc;
 	ctrldesc->npins = drvdata->ctrl->nr_pins;
-	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++)
diff --git a/drivers/pinctrl/pinctrl-sunxi.c b/drivers/pinctrl/pinctrl-sunxi.c
new file mode 100644
index 0000000..80b11e3
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-sunxi.c
@@ -0,0 +1,1505 @@
+/*
+ * Allwinner A1X SoCs pinctrl driver.
+ *
+ * Copyright (C) 2012 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/io.h>
+#include <linux/gpio.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/pinctrl/machine.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinconf-generic.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include "core.h"
+#include "pinctrl-sunxi.h"
+
+static const struct sunxi_desc_pin sun4i_a10_pins[] = {
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA0,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA1,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA2,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA3,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA4,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA5,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA6,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA7,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA8,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA9,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA10,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out"),
+		SUNXI_FUNCTION(0x4, "uart1")),		/* TX */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA11,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out"),
+		SUNXI_FUNCTION(0x4, "uart1")),		/* RX */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA12,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out"),
+		SUNXI_FUNCTION(0x4, "uart1")),		/* RTS */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA13,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out"),
+		SUNXI_FUNCTION(0x4, "uart1")),		/* CTS */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA14,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out"),
+		SUNXI_FUNCTION(0x4, "uart1")),		/* DTR */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA15,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out"),
+		SUNXI_FUNCTION(0x4, "uart1")),		/* DSR */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA16,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out"),
+		SUNXI_FUNCTION(0x4, "uart1")),		/* DCD */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA17,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out"),
+		SUNXI_FUNCTION(0x4, "uart1")),		/* RING */
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB0,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB1,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB2,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB3,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB4,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB5,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB6,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB7,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB8,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB9,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB10,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB11,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB12,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB13,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB14,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB15,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB16,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB17,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB18,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB19,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB20,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB21,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB22,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out"),
+		SUNXI_FUNCTION(0x2, "uart0")),		/* TX */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB23,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out"),
+		SUNXI_FUNCTION(0x2, "uart0")),		/* RX */
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC0,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC1,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC2,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC3,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC4,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC5,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC6,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC7,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC8,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC9,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC10,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC11,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC12,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC13,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC14,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC15,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC16,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC17,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC18,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC19,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC20,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC21,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC22,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC23,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC24,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD0,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD1,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD2,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD3,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD4,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD5,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD6,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD7,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD8,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD9,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD10,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD11,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD12,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD13,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD14,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD15,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD16,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD17,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD18,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD19,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD20,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD21,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD22,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD23,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD24,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD25,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD26,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD27,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE0,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE1,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE2,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE3,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE4,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE5,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE6,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE7,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE8,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE9,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE10,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE11,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PF0,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PF1,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PF2,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out"),
+		SUNXI_FUNCTION(0x4, "uart0")),		/* TX */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PF3,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PF4,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out"),
+		SUNXI_FUNCTION(0x4, "uart0")),		/* RX */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PF5,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG0,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG1,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG2,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG3,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG4,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG5,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG6,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG7,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG8,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG9,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG10,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG11,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH0,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH1,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH2,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH3,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH4,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH5,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH6,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH7,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH8,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH9,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH10,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH11,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH12,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH13,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH14,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH15,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH16,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH17,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH18,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH19,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH20,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH21,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH22,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH23,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH24,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH25,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH26,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH27,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PI0,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PI1,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PI2,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PI3,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PI4,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PI5,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PI6,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PI7,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PI8,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PI9,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PI10,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PI11,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PI12,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PI13,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PI14,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PI15,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PI16,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PI17,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PI18,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PI19,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PI20,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PI21,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+};
+
+static const struct sunxi_desc_pin sun5i_a13_pins[] = {
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB0,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB1,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB2,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB3,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB4,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB10,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB15,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB16,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB17,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB18,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC0,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC1,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC2,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC3,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC4,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC5,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC6,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC7,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC8,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC9,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC10,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC11,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC12,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC13,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC14,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC15,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC19,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD2,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD3,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD4,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD5,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD6,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD7,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD10,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD11,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD12,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD13,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD14,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD15,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD18,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD19,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD20,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD21,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD22,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD23,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD24,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD25,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD26,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD27,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE0,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE1,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE2,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE3,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE4,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE5,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE6,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE7,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE8,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE9,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE10,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out"),
+		SUNXI_FUNCTION(0x4, "uart1")),		/* TX */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE11,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out"),
+		SUNXI_FUNCTION(0x4, "uart1")),		/* RX */
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PF0,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PF1,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PF2,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PF3,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PF4,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PF5,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG0,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG1,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG2,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG3,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out"),
+		SUNXI_FUNCTION(0x4, "uart1")),		/* TX */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG4,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out"),
+		SUNXI_FUNCTION(0x4, "uart1")),		/* RX */
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG9,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG10,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG11,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG12,
+		SUNXI_FUNCTION(0x0, "gpio_in"),
+		SUNXI_FUNCTION(0x1, "gpio_out")),
+};
+
+static const struct sunxi_pinctrl_desc sun4i_a10_pinctrl_data = {
+	.pins = sun4i_a10_pins,
+	.npins = ARRAY_SIZE(sun4i_a10_pins),
+};
+
+static const struct sunxi_pinctrl_desc sun5i_a13_pinctrl_data = {
+	.pins = sun5i_a13_pins,
+	.npins = ARRAY_SIZE(sun5i_a13_pins),
+};
+
+static struct sunxi_pinctrl_group *
+sunxi_pinctrl_find_group_by_name(struct sunxi_pinctrl *pctl, const char *group)
+{
+	int i;
+
+	for (i = 0; i < pctl->ngroups; i++) {
+		struct sunxi_pinctrl_group *grp = pctl->groups + i;
+
+		if (!strcmp(grp->name, group))
+			return grp;
+	}
+
+	return NULL;
+}
+
+static struct sunxi_pinctrl_function *
+sunxi_pinctrl_find_function_by_name(struct sunxi_pinctrl *pctl,
+				    const char *name)
+{
+	struct sunxi_pinctrl_function *func = pctl->functions;
+	int i;
+
+	for (i = 0; i < pctl->nfunctions; i++) {
+		if (!func[i].name)
+			break;
+
+		if (!strcmp(func[i].name, name))
+			return func + i;
+	}
+
+	return NULL;
+}
+
+static struct sunxi_desc_function *
+sunxi_pinctrl_desc_find_function_by_name(struct sunxi_pinctrl *pctl,
+					 const char *pin_name,
+					 const char *func_name)
+{
+	int i;
+
+	for (i = 0; i < pctl->desc->npins; i++) {
+		const struct sunxi_desc_pin *pin = pctl->desc->pins + i;
+
+		if (!strcmp(pin->pin.name, pin_name)) {
+			struct sunxi_desc_function *func = pin->functions;
+
+			while (func->name) {
+				if (!strcmp(func->name, func_name))
+					return func;
+
+				func++;
+			}
+		}
+	}
+
+	return NULL;
+}
+
+static int sunxi_pctrl_get_groups_count(struct pinctrl_dev *pctldev)
+{
+	struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+
+	return pctl->ngroups;
+}
+
+static const char *sunxi_pctrl_get_group_name(struct pinctrl_dev *pctldev,
+					      unsigned group)
+{
+	struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+
+	return pctl->groups[group].name;
+}
+
+static int sunxi_pctrl_get_group_pins(struct pinctrl_dev *pctldev,
+				      unsigned group,
+				      const unsigned **pins,
+				      unsigned *num_pins)
+{
+	struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+
+	*pins = (unsigned *)&pctl->groups[group].pin;
+	*num_pins = 1;
+
+	return 0;
+}
+
+static int sunxi_pctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
+				      struct device_node *node,
+				      struct pinctrl_map **map,
+				      unsigned *num_maps)
+{
+	struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+	unsigned long *pinconfig;
+	struct property *prop;
+	const char *function;
+	const char *group;
+	int ret, nmaps, i = 0;
+	u32 val;
+
+	*map = NULL;
+	*num_maps = 0;
+
+	ret = of_property_read_string(node, "allwinner,function", &function);
+	if (ret) {
+		dev_err(pctl->dev,
+			"missing allwinner,function property in node %s\n",
+			node->name);
+		return -EINVAL;
+	}
+
+	nmaps = of_property_count_strings(node, "allwinner,pins") * 2;
+	if (nmaps < 0) {
+		dev_err(pctl->dev,
+			"missing allwinner,pins property in node %s\n",
+			node->name);
+		return -EINVAL;
+	}
+
+	*map = kmalloc(nmaps * sizeof(struct pinctrl_map), GFP_KERNEL);
+	if (!map)
+		return -ENOMEM;
+
+	of_property_for_each_string(node, "allwinner,pins", prop, group) {
+		struct sunxi_pinctrl_group *grp =
+			sunxi_pinctrl_find_group_by_name(pctl, group);
+		int j = 0, configlen = 0;
+
+		if (!grp) {
+			dev_err(pctl->dev, "unknown pin %s", group);
+			continue;
+		}
+
+		if (!sunxi_pinctrl_desc_find_function_by_name(pctl,
+							      grp->name,
+							      function)) {
+			dev_err(pctl->dev, "unsupported function %s on pin %s",
+				function, group);
+			continue;
+		}
+
+		(*map)[i].type = PIN_MAP_TYPE_MUX_GROUP;
+		(*map)[i].data.mux.group = group;
+		(*map)[i].data.mux.function = function;
+
+		i++;
+
+		(*map)[i].type = PIN_MAP_TYPE_CONFIGS_GROUP;
+		(*map)[i].data.configs.group_or_pin = group;
+
+		if (of_find_property(node, "allwinner,drive", NULL))
+			configlen++;
+		if (of_find_property(node, "allwinner,pull", NULL))
+			configlen++;
+
+		pinconfig = kzalloc(configlen * sizeof(*pinconfig), GFP_KERNEL);
+
+		if (!of_property_read_u32(node, "allwinner,drive", &val)) {
+			u16 strength = (val + 1) * 10;
+			pinconfig[j++] =
+				pinconf_to_config_packed(PIN_CONFIG_DRIVE_STRENGTH,
+							 strength);
+		}
+
+		if (!of_property_read_u32(node, "allwinner,pull", &val)) {
+			enum pin_config_param pull = PIN_CONFIG_END;
+			if (val == 1)
+				pull = PIN_CONFIG_BIAS_PULL_UP;
+			else if (val == 2)
+				pull = PIN_CONFIG_BIAS_PULL_DOWN;
+			pinconfig[j++] = pinconf_to_config_packed(pull, 0);
+		}
+
+		(*map)[i].data.configs.configs = pinconfig;
+		(*map)[i].data.configs.num_configs = configlen;
+
+		i++;
+	}
+
+	*num_maps = nmaps;
+
+	return 0;
+}
+
+static void sunxi_pctrl_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 struct pinctrl_ops sunxi_pctrl_ops = {
+	.dt_node_to_map		= sunxi_pctrl_dt_node_to_map,
+	.dt_free_map		= sunxi_pctrl_dt_free_map,
+	.get_groups_count	= sunxi_pctrl_get_groups_count,
+	.get_group_name		= sunxi_pctrl_get_group_name,
+	.get_group_pins		= sunxi_pctrl_get_group_pins,
+};
+
+static int sunxi_pconf_group_get(struct pinctrl_dev *pctldev,
+				 unsigned group,
+				 unsigned long *config)
+{
+	struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+
+	*config = pctl->groups[group].config;
+
+	return 0;
+}
+
+static int sunxi_pconf_group_set(struct pinctrl_dev *pctldev,
+				 unsigned group,
+				 unsigned long config)
+{
+	struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+	struct sunxi_pinctrl_group *g = &pctl->groups[group];
+	u32 val, mask;
+	u16 strength;
+	u8 dlevel;
+
+	switch (pinconf_to_config_param(config)) {
+	case PIN_CONFIG_DRIVE_STRENGTH:
+		strength = pinconf_to_config_argument(config);
+		if (strength > 40)
+			return -EINVAL;
+		/*
+		 * We convert from mA to what the register expects:
+		 *   0: 10mA
+		 *   1: 20mA
+		 *   2: 30mA
+		 *   3: 40mA
+		 */
+		dlevel = strength / 10 - 1;
+		val = readl(pctl->membase + sunxi_dlevel_reg(g->pin));
+	        mask = DLEVEL_PINS_MASK << sunxi_dlevel_offset(g->pin);
+		writel((val & ~mask) | dlevel << sunxi_dlevel_offset(g->pin),
+			pctl->membase + sunxi_dlevel_reg(g->pin));
+		break;
+	case PIN_CONFIG_BIAS_PULL_UP:
+		val = readl(pctl->membase + sunxi_pull_reg(g->pin));
+		mask = PULL_PINS_MASK << sunxi_pull_offset(g->pin);
+		writel((val & ~mask) | 1 << sunxi_pull_offset(g->pin),
+			pctl->membase + sunxi_pull_reg(g->pin));
+		break;
+	case PIN_CONFIG_BIAS_PULL_DOWN:
+		val = readl(pctl->membase + sunxi_pull_reg(g->pin));
+		mask = PULL_PINS_MASK << sunxi_pull_offset(g->pin);
+		writel((val & ~mask) | 2 << sunxi_pull_offset(g->pin),
+			pctl->membase + sunxi_pull_reg(g->pin));
+		break;
+	default:
+		break;
+	}
+
+	/* cache the config value */
+	g->config = config;
+
+	return 0;
+}
+
+static struct pinconf_ops sunxi_pconf_ops = {
+	.pin_config_group_get	= sunxi_pconf_group_get,
+	.pin_config_group_set	= sunxi_pconf_group_set,
+};
+
+static int sunxi_pmx_get_funcs_cnt(struct pinctrl_dev *pctldev)
+{
+	struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+
+	return pctl->nfunctions;
+}
+
+static const char *sunxi_pmx_get_func_name(struct pinctrl_dev *pctldev,
+					   unsigned function)
+{
+	struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+
+	return pctl->functions[function].name;
+}
+
+static int sunxi_pmx_get_func_groups(struct pinctrl_dev *pctldev,
+				     unsigned function,
+				     const char * const **groups,
+				     unsigned * const num_groups)
+{
+	struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+
+	*groups = pctl->functions[function].groups;
+	*num_groups = pctl->functions[function].ngroups;
+
+	return 0;
+}
+
+static void sunxi_pmx_set(struct pinctrl_dev *pctldev,
+				 unsigned pin,
+				 u8 config)
+{
+	struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+
+	u32 val = readl(pctl->membase + sunxi_mux_reg(pin));
+	u32 mask = MUX_PINS_MASK << sunxi_mux_offset(pin);
+	writel((val & ~mask) | config << sunxi_mux_offset(pin),
+		pctl->membase + sunxi_mux_reg(pin));
+}
+
+static int sunxi_pmx_enable(struct pinctrl_dev *pctldev,
+			    unsigned function,
+			    unsigned group)
+{
+	struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+	struct sunxi_pinctrl_group *g = pctl->groups + group;
+	struct sunxi_pinctrl_function *func = pctl->functions + function;
+	struct sunxi_desc_function *desc =
+		sunxi_pinctrl_desc_find_function_by_name(pctl,
+							 g->name,
+							 func->name);
+
+	if (!desc)
+		return -EINVAL;
+
+	sunxi_pmx_set(pctldev, g->pin, desc->muxval);
+
+	return 0;
+}
+
+static int
+sunxi_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
+			struct pinctrl_gpio_range *range,
+			unsigned offset,
+			bool input)
+{
+	struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+	struct sunxi_desc_function *desc;
+	char pin_name[SUNXI_PIN_NAME_MAX_LEN];
+	const char *func;
+	u8 bank, pin;
+	int ret;
+
+	bank = (offset) / PINS_PER_BANK;
+	pin = (offset) % PINS_PER_BANK;
+
+	ret = sprintf(pin_name, "P%c%d", 'A' + bank, pin);
+	if (!ret)
+		goto error;
+
+	if (input)
+		func = "gpio_in";
+	else
+		func = "gpio_out";
+
+	desc = sunxi_pinctrl_desc_find_function_by_name(pctl,
+							pin_name,
+							func);
+	if (!desc) {
+		ret = -EINVAL;
+		goto error;
+	}
+
+	sunxi_pmx_set(pctldev, offset, desc->muxval);
+
+	ret = 0;
+
+error:
+	return ret;
+}
+
+static struct pinmux_ops sunxi_pmx_ops = {
+	.get_functions_count	= sunxi_pmx_get_funcs_cnt,
+	.get_function_name	= sunxi_pmx_get_func_name,
+	.get_function_groups	= sunxi_pmx_get_func_groups,
+	.enable			= sunxi_pmx_enable,
+	.gpio_set_direction	= sunxi_pmx_gpio_set_direction,
+};
+
+static struct pinctrl_desc sunxi_pctrl_desc = {
+	.confops	= &sunxi_pconf_ops,
+	.pctlops	= &sunxi_pctrl_ops,
+	.pmxops		= &sunxi_pmx_ops,
+};
+
+static int sunxi_pinctrl_gpio_request(struct gpio_chip *chip, unsigned offset)
+{
+	return pinctrl_request_gpio(chip->base + offset);
+}
+
+static void sunxi_pinctrl_gpio_free(struct gpio_chip *chip, unsigned offset)
+{
+	pinctrl_free_gpio(chip->base + offset);
+}
+
+static int sunxi_pinctrl_gpio_direction_input(struct gpio_chip *chip,
+					unsigned offset)
+{
+	return pinctrl_gpio_direction_input(chip->base + offset);
+}
+
+static int sunxi_pinctrl_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+	struct sunxi_pinctrl *pctl = dev_get_drvdata(chip->dev);
+
+	u32 reg = sunxi_data_reg(offset);
+	u8 index = sunxi_data_offset(offset);
+	u32 val = (readl(pctl->membase + reg) >> index) & DATA_PINS_MASK;
+
+	return val;
+}
+
+static int sunxi_pinctrl_gpio_direction_output(struct gpio_chip *chip,
+					unsigned offset, int value)
+{
+	return pinctrl_gpio_direction_output(chip->base + offset);
+}
+
+static void sunxi_pinctrl_gpio_set(struct gpio_chip *chip,
+				unsigned offset, int value)
+{
+	struct sunxi_pinctrl *pctl = dev_get_drvdata(chip->dev);
+	u32 reg = sunxi_data_reg(offset);
+	u8 index = sunxi_data_offset(offset);
+
+	writel((value & DATA_PINS_MASK) << index, pctl->membase + reg);
+}
+
+static int sunxi_pinctrl_gpio_of_xlate(struct gpio_chip *gc,
+				const struct of_phandle_args *gpiospec,
+				u32 *flags)
+{
+	int pin, base;
+
+	base = PINS_PER_BANK * gpiospec->args[0];
+	pin = base + gpiospec->args[1];
+
+	if (pin > (gc->base + gc->ngpio))
+		return -EINVAL;
+
+	if (flags)
+		*flags = gpiospec->args[2];
+
+	return pin;
+}
+
+static struct gpio_chip sunxi_pinctrl_gpio_chip = {
+	.owner			= THIS_MODULE,
+	.request		= sunxi_pinctrl_gpio_request,
+	.free			= sunxi_pinctrl_gpio_free,
+	.direction_input	= sunxi_pinctrl_gpio_direction_input,
+	.direction_output	= sunxi_pinctrl_gpio_direction_output,
+	.get			= sunxi_pinctrl_gpio_get,
+	.set			= sunxi_pinctrl_gpio_set,
+	.of_xlate		= sunxi_pinctrl_gpio_of_xlate,
+	.of_gpio_n_cells	= 3,
+	.can_sleep		= 0,
+};
+
+static struct of_device_id sunxi_pinctrl_match[] = {
+	{ .compatible = "allwinner,sun4i-a10-pinctrl", .data = (void *)&sun4i_a10_pinctrl_data },
+	{ .compatible = "allwinner,sun5i-a13-pinctrl", .data = (void *)&sun5i_a13_pinctrl_data },
+	{}
+};
+MODULE_DEVICE_TABLE(of, sunxi_pinctrl_match);
+
+static int sunxi_pinctrl_add_function(struct sunxi_pinctrl *pctl,
+					const char *name)
+{
+	struct sunxi_pinctrl_function *func = pctl->functions;
+
+	while (func->name) {
+		/* function already there */
+		if (strcmp(func->name, name) == 0) {
+			func->ngroups++;
+			return -EEXIST;
+		}
+		func++;
+	}
+
+	func->name = name;
+	func->ngroups = 1;
+
+	pctl->nfunctions++;
+
+	return 0;
+}
+
+static int sunxi_pinctrl_build_state(struct platform_device *pdev)
+{
+	struct sunxi_pinctrl *pctl = platform_get_drvdata(pdev);
+	int i;
+
+	pctl->ngroups = pctl->desc->npins;
+
+	/* Allocate groups */
+	pctl->groups = devm_kzalloc(&pdev->dev,
+				    pctl->ngroups * sizeof(*pctl->groups),
+				    GFP_KERNEL);
+	if (!pctl->groups)
+		return -ENOMEM;
+
+	for (i = 0; i < pctl->desc->npins; i++) {
+		const struct sunxi_desc_pin *pin = pctl->desc->pins + i;
+		struct sunxi_pinctrl_group *group = pctl->groups + i;
+
+		group->name = pin->pin.name;
+		group->pin = pin->pin.number;
+	}
+
+	/*
+	 * We suppose that we won't have any more functions than pins,
+	 * we'll reallocate that later anyway
+	 */
+	pctl->functions = devm_kzalloc(&pdev->dev,
+				pctl->desc->npins * sizeof(*pctl->functions),
+				GFP_KERNEL);
+	if (!pctl->functions)
+		return -ENOMEM;
+
+	/* Count functions and their associated groups */
+	for (i = 0; i < pctl->desc->npins; i++) {
+		const struct sunxi_desc_pin *pin = pctl->desc->pins + i;
+		struct sunxi_desc_function *func = pin->functions;
+
+		while (func->name) {
+			sunxi_pinctrl_add_function(pctl, func->name);
+			func++;
+		}
+	}
+
+	pctl->functions = krealloc(pctl->functions,
+				pctl->nfunctions * sizeof(*pctl->functions),
+				GFP_KERNEL);
+
+	for (i = 0; i < pctl->desc->npins; i++) {
+		const struct sunxi_desc_pin *pin = pctl->desc->pins + i;
+		struct sunxi_desc_function *func = pin->functions;
+
+		while (func->name) {
+			struct sunxi_pinctrl_function *func_item;
+			const char **func_grp;
+
+			func_item = sunxi_pinctrl_find_function_by_name(pctl,
+									func->name);
+			if (!func_item)
+				return -EINVAL;
+
+			if (!func_item->groups) {
+				func_item->groups =
+					devm_kzalloc(&pdev->dev,
+						     func_item->ngroups * sizeof(*func_item->groups),
+						     GFP_KERNEL);
+				if (!func_item->groups)
+					return -ENOMEM;
+			}
+
+			func_grp = func_item->groups;
+			while (*func_grp)
+				func_grp++;
+
+			*func_grp = pin->pin.name;
+			func++;
+		}
+	}
+
+	return 0;
+}
+
+static int sunxi_pinctrl_probe(struct platform_device *pdev)
+{
+	struct device_node *node = pdev->dev.of_node;
+	const struct of_device_id *device;
+	struct pinctrl_pin_desc *pins;
+	struct sunxi_pinctrl *pctl;
+	int i, ret, last_pin;
+
+	pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL);
+	if (!pctl)
+		return -ENOMEM;
+	platform_set_drvdata(pdev, pctl);
+
+	pctl->membase = of_iomap(node, 0);
+	if (!pctl->membase)
+		return -ENOMEM;
+
+	device = of_match_device(sunxi_pinctrl_match, &pdev->dev);
+	if (!device)
+		return -ENODEV;
+
+	pctl->desc = (struct sunxi_pinctrl_desc *)device->data;
+
+	ret = sunxi_pinctrl_build_state(pdev);
+	if (ret) {
+		dev_err(&pdev->dev, "dt probe failed: %d\n", ret);
+		return ret;
+	}
+
+	pins = devm_kzalloc(&pdev->dev,
+			    pctl->desc->npins * sizeof(*pins),
+			    GFP_KERNEL);
+	if (!pins)
+		return -ENOMEM;
+
+	for (i = 0; i < pctl->desc->npins; i++)
+		pins[i] = pctl->desc->pins[i].pin;
+
+	sunxi_pctrl_desc.name = dev_name(&pdev->dev);
+	sunxi_pctrl_desc.owner = THIS_MODULE;
+	sunxi_pctrl_desc.pins = pins;
+	sunxi_pctrl_desc.npins = pctl->desc->npins;
+	pctl->dev = &pdev->dev;
+	pctl->pctl_dev = pinctrl_register(&sunxi_pctrl_desc,
+					  &pdev->dev, pctl);
+	if (!pctl->pctl_dev) {
+		dev_err(&pdev->dev, "couldn't register pinctrl driver\n");
+		return -EINVAL;
+	}
+
+	pctl->chip = devm_kzalloc(&pdev->dev, sizeof(*pctl->chip), GFP_KERNEL);
+	if (!pctl->chip) {
+		ret = -ENOMEM;
+		goto pinctrl_error;
+	}
+
+	last_pin = pctl->desc->pins[pctl->desc->npins - 1].pin.number;
+	pctl->chip = &sunxi_pinctrl_gpio_chip;
+	pctl->chip->ngpio = round_up(last_pin, PINS_PER_BANK);
+	pctl->chip->label = dev_name(&pdev->dev);
+	pctl->chip->dev = &pdev->dev;
+	pctl->chip->base = 0;
+
+	ret = gpiochip_add(pctl->chip);
+	if (ret)
+		goto pinctrl_error;
+
+	for (i = 0; i < pctl->desc->npins; i++) {
+		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, 1);
+		if (ret)
+			goto gpiochip_error;
+	}
+
+	dev_info(&pdev->dev, "initialized sunXi PIO driver\n");
+
+	return 0;
+
+gpiochip_error:
+	ret = gpiochip_remove(pctl->chip);
+pinctrl_error:
+	pinctrl_unregister(pctl->pctl_dev);
+	return ret;
+}
+
+static struct platform_driver sunxi_pinctrl_driver = {
+	.probe = sunxi_pinctrl_probe,
+	.driver = {
+		.name = "sunxi-pinctrl",
+		.owner = THIS_MODULE,
+		.of_match_table = sunxi_pinctrl_match,
+	},
+};
+module_platform_driver(sunxi_pinctrl_driver);
+
+MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com");
+MODULE_DESCRIPTION("Allwinner A1X pinctrl driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/pinctrl/pinctrl-sunxi.h b/drivers/pinctrl/pinctrl-sunxi.h
new file mode 100644
index 0000000..e921621
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-sunxi.h
@@ -0,0 +1,478 @@
+/*
+ * Allwinner A1X SoCs pinctrl driver.
+ *
+ * Copyright (C) 2012 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.
+ */
+
+#ifndef __PINCTRL_SUNXI_H
+#define __PINCTRL_SUNXI_H
+
+#include <linux/kernel.h>
+
+#define PA_BASE	0
+#define PB_BASE	32
+#define PC_BASE	64
+#define PD_BASE	96
+#define PE_BASE	128
+#define PF_BASE	160
+#define PG_BASE	192
+#define PH_BASE	224
+#define PI_BASE	256
+
+#define SUNXI_PINCTRL_PIN_PA0	PINCTRL_PIN(PA_BASE + 0, "PA0")
+#define SUNXI_PINCTRL_PIN_PA1	PINCTRL_PIN(PA_BASE + 1, "PA1")
+#define SUNXI_PINCTRL_PIN_PA2	PINCTRL_PIN(PA_BASE + 2, "PA2")
+#define SUNXI_PINCTRL_PIN_PA3	PINCTRL_PIN(PA_BASE + 3, "PA3")
+#define SUNXI_PINCTRL_PIN_PA4	PINCTRL_PIN(PA_BASE + 4, "PA4")
+#define SUNXI_PINCTRL_PIN_PA5	PINCTRL_PIN(PA_BASE + 5, "PA5")
+#define SUNXI_PINCTRL_PIN_PA6	PINCTRL_PIN(PA_BASE + 6, "PA6")
+#define SUNXI_PINCTRL_PIN_PA7	PINCTRL_PIN(PA_BASE + 7, "PA7")
+#define SUNXI_PINCTRL_PIN_PA8	PINCTRL_PIN(PA_BASE + 8, "PA8")
+#define SUNXI_PINCTRL_PIN_PA9	PINCTRL_PIN(PA_BASE + 9, "PA9")
+#define SUNXI_PINCTRL_PIN_PA10	PINCTRL_PIN(PA_BASE + 10, "PA10")
+#define SUNXI_PINCTRL_PIN_PA11	PINCTRL_PIN(PA_BASE + 11, "PA11")
+#define SUNXI_PINCTRL_PIN_PA12	PINCTRL_PIN(PA_BASE + 12, "PA12")
+#define SUNXI_PINCTRL_PIN_PA13	PINCTRL_PIN(PA_BASE + 13, "PA13")
+#define SUNXI_PINCTRL_PIN_PA14	PINCTRL_PIN(PA_BASE + 14, "PA14")
+#define SUNXI_PINCTRL_PIN_PA15	PINCTRL_PIN(PA_BASE + 15, "PA15")
+#define SUNXI_PINCTRL_PIN_PA16	PINCTRL_PIN(PA_BASE + 16, "PA16")
+#define SUNXI_PINCTRL_PIN_PA17	PINCTRL_PIN(PA_BASE + 17, "PA17")
+#define SUNXI_PINCTRL_PIN_PA18	PINCTRL_PIN(PA_BASE + 18, "PA18")
+#define SUNXI_PINCTRL_PIN_PA19	PINCTRL_PIN(PA_BASE + 19, "PA19")
+#define SUNXI_PINCTRL_PIN_PA20	PINCTRL_PIN(PA_BASE + 20, "PA20")
+#define SUNXI_PINCTRL_PIN_PA21	PINCTRL_PIN(PA_BASE + 21, "PA21")
+#define SUNXI_PINCTRL_PIN_PA22	PINCTRL_PIN(PA_BASE + 22, "PA22")
+#define SUNXI_PINCTRL_PIN_PA23	PINCTRL_PIN(PA_BASE + 23, "PA23")
+#define SUNXI_PINCTRL_PIN_PA24	PINCTRL_PIN(PA_BASE + 24, "PA24")
+#define SUNXI_PINCTRL_PIN_PA25	PINCTRL_PIN(PA_BASE + 25, "PA25")
+#define SUNXI_PINCTRL_PIN_PA26	PINCTRL_PIN(PA_BASE + 26, "PA26")
+#define SUNXI_PINCTRL_PIN_PA27	PINCTRL_PIN(PA_BASE + 27, "PA27")
+#define SUNXI_PINCTRL_PIN_PA28	PINCTRL_PIN(PA_BASE + 28, "PA28")
+#define SUNXI_PINCTRL_PIN_PA29	PINCTRL_PIN(PA_BASE + 29, "PA29")
+#define SUNXI_PINCTRL_PIN_PA30	PINCTRL_PIN(PA_BASE + 30, "PA30")
+#define SUNXI_PINCTRL_PIN_PA31	PINCTRL_PIN(PA_BASE + 31, "PA31")
+
+#define SUNXI_PINCTRL_PIN_PB0	PINCTRL_PIN(PB_BASE + 0, "PB0")
+#define SUNXI_PINCTRL_PIN_PB1	PINCTRL_PIN(PB_BASE + 1, "PB1")
+#define SUNXI_PINCTRL_PIN_PB2	PINCTRL_PIN(PB_BASE + 2, "PB2")
+#define SUNXI_PINCTRL_PIN_PB3	PINCTRL_PIN(PB_BASE + 3, "PB3")
+#define SUNXI_PINCTRL_PIN_PB4	PINCTRL_PIN(PB_BASE + 4, "PB4")
+#define SUNXI_PINCTRL_PIN_PB5	PINCTRL_PIN(PB_BASE + 5, "PB5")
+#define SUNXI_PINCTRL_PIN_PB6	PINCTRL_PIN(PB_BASE + 6, "PB6")
+#define SUNXI_PINCTRL_PIN_PB7	PINCTRL_PIN(PB_BASE + 7, "PB7")
+#define SUNXI_PINCTRL_PIN_PB8	PINCTRL_PIN(PB_BASE + 8, "PB8")
+#define SUNXI_PINCTRL_PIN_PB9	PINCTRL_PIN(PB_BASE + 9, "PB9")
+#define SUNXI_PINCTRL_PIN_PB10	PINCTRL_PIN(PB_BASE + 10, "PB10")
+#define SUNXI_PINCTRL_PIN_PB11	PINCTRL_PIN(PB_BASE + 11, "PB11")
+#define SUNXI_PINCTRL_PIN_PB12	PINCTRL_PIN(PB_BASE + 12, "PB12")
+#define SUNXI_PINCTRL_PIN_PB13	PINCTRL_PIN(PB_BASE + 13, "PB13")
+#define SUNXI_PINCTRL_PIN_PB14	PINCTRL_PIN(PB_BASE + 14, "PB14")
+#define SUNXI_PINCTRL_PIN_PB15	PINCTRL_PIN(PB_BASE + 15, "PB15")
+#define SUNXI_PINCTRL_PIN_PB16	PINCTRL_PIN(PB_BASE + 16, "PB16")
+#define SUNXI_PINCTRL_PIN_PB17	PINCTRL_PIN(PB_BASE + 17, "PB17")
+#define SUNXI_PINCTRL_PIN_PB18	PINCTRL_PIN(PB_BASE + 18, "PB18")
+#define SUNXI_PINCTRL_PIN_PB19	PINCTRL_PIN(PB_BASE + 19, "PB19")
+#define SUNXI_PINCTRL_PIN_PB20	PINCTRL_PIN(PB_BASE + 20, "PB20")
+#define SUNXI_PINCTRL_PIN_PB21	PINCTRL_PIN(PB_BASE + 21, "PB21")
+#define SUNXI_PINCTRL_PIN_PB22	PINCTRL_PIN(PB_BASE + 22, "PB22")
+#define SUNXI_PINCTRL_PIN_PB23	PINCTRL_PIN(PB_BASE + 23, "PB23")
+#define SUNXI_PINCTRL_PIN_PB24	PINCTRL_PIN(PB_BASE + 24, "PB24")
+#define SUNXI_PINCTRL_PIN_PB25	PINCTRL_PIN(PB_BASE + 25, "PB25")
+#define SUNXI_PINCTRL_PIN_PB26	PINCTRL_PIN(PB_BASE + 26, "PB26")
+#define SUNXI_PINCTRL_PIN_PB27	PINCTRL_PIN(PB_BASE + 27, "PB27")
+#define SUNXI_PINCTRL_PIN_PB28	PINCTRL_PIN(PB_BASE + 28, "PB28")
+#define SUNXI_PINCTRL_PIN_PB29	PINCTRL_PIN(PB_BASE + 29, "PB29")
+#define SUNXI_PINCTRL_PIN_PB30	PINCTRL_PIN(PB_BASE + 30, "PB30")
+#define SUNXI_PINCTRL_PIN_PB31	PINCTRL_PIN(PB_BASE + 31, "PB31")
+
+#define SUNXI_PINCTRL_PIN_PC0	PINCTRL_PIN(PC_BASE + 0, "PC0")
+#define SUNXI_PINCTRL_PIN_PC1	PINCTRL_PIN(PC_BASE + 1, "PC1")
+#define SUNXI_PINCTRL_PIN_PC2	PINCTRL_PIN(PC_BASE + 2, "PC2")
+#define SUNXI_PINCTRL_PIN_PC3	PINCTRL_PIN(PC_BASE + 3, "PC3")
+#define SUNXI_PINCTRL_PIN_PC4	PINCTRL_PIN(PC_BASE + 4, "PC4")
+#define SUNXI_PINCTRL_PIN_PC5	PINCTRL_PIN(PC_BASE + 5, "PC5")
+#define SUNXI_PINCTRL_PIN_PC6	PINCTRL_PIN(PC_BASE + 6, "PC6")
+#define SUNXI_PINCTRL_PIN_PC7	PINCTRL_PIN(PC_BASE + 7, "PC7")
+#define SUNXI_PINCTRL_PIN_PC8	PINCTRL_PIN(PC_BASE + 8, "PC8")
+#define SUNXI_PINCTRL_PIN_PC9	PINCTRL_PIN(PC_BASE + 9, "PC9")
+#define SUNXI_PINCTRL_PIN_PC10	PINCTRL_PIN(PC_BASE + 10, "PC10")
+#define SUNXI_PINCTRL_PIN_PC11	PINCTRL_PIN(PC_BASE + 11, "PC11")
+#define SUNXI_PINCTRL_PIN_PC12	PINCTRL_PIN(PC_BASE + 12, "PC12")
+#define SUNXI_PINCTRL_PIN_PC13	PINCTRL_PIN(PC_BASE + 13, "PC13")
+#define SUNXI_PINCTRL_PIN_PC14	PINCTRL_PIN(PC_BASE + 14, "PC14")
+#define SUNXI_PINCTRL_PIN_PC15	PINCTRL_PIN(PC_BASE + 15, "PC15")
+#define SUNXI_PINCTRL_PIN_PC16	PINCTRL_PIN(PC_BASE + 16, "PC16")
+#define SUNXI_PINCTRL_PIN_PC17	PINCTRL_PIN(PC_BASE + 17, "PC17")
+#define SUNXI_PINCTRL_PIN_PC18	PINCTRL_PIN(PC_BASE + 18, "PC18")
+#define SUNXI_PINCTRL_PIN_PC19	PINCTRL_PIN(PC_BASE + 19, "PC19")
+#define SUNXI_PINCTRL_PIN_PC20	PINCTRL_PIN(PC_BASE + 20, "PC20")
+#define SUNXI_PINCTRL_PIN_PC21	PINCTRL_PIN(PC_BASE + 21, "PC21")
+#define SUNXI_PINCTRL_PIN_PC22	PINCTRL_PIN(PC_BASE + 22, "PC22")
+#define SUNXI_PINCTRL_PIN_PC23	PINCTRL_PIN(PC_BASE + 23, "PC23")
+#define SUNXI_PINCTRL_PIN_PC24	PINCTRL_PIN(PC_BASE + 24, "PC24")
+#define SUNXI_PINCTRL_PIN_PC25	PINCTRL_PIN(PC_BASE + 25, "PC25")
+#define SUNXI_PINCTRL_PIN_PC26	PINCTRL_PIN(PC_BASE + 26, "PC26")
+#define SUNXI_PINCTRL_PIN_PC27	PINCTRL_PIN(PC_BASE + 27, "PC27")
+#define SUNXI_PINCTRL_PIN_PC28	PINCTRL_PIN(PC_BASE + 28, "PC28")
+#define SUNXI_PINCTRL_PIN_PC29	PINCTRL_PIN(PC_BASE + 29, "PC29")
+#define SUNXI_PINCTRL_PIN_PC30	PINCTRL_PIN(PC_BASE + 30, "PC30")
+#define SUNXI_PINCTRL_PIN_PC31	PINCTRL_PIN(PC_BASE + 31, "PC31")
+
+#define SUNXI_PINCTRL_PIN_PD0	PINCTRL_PIN(PD_BASE + 0, "PD0")
+#define SUNXI_PINCTRL_PIN_PD1	PINCTRL_PIN(PD_BASE + 1, "PD1")
+#define SUNXI_PINCTRL_PIN_PD2	PINCTRL_PIN(PD_BASE + 2, "PD2")
+#define SUNXI_PINCTRL_PIN_PD3	PINCTRL_PIN(PD_BASE + 3, "PD3")
+#define SUNXI_PINCTRL_PIN_PD4	PINCTRL_PIN(PD_BASE + 4, "PD4")
+#define SUNXI_PINCTRL_PIN_PD5	PINCTRL_PIN(PD_BASE + 5, "PD5")
+#define SUNXI_PINCTRL_PIN_PD6	PINCTRL_PIN(PD_BASE + 6, "PD6")
+#define SUNXI_PINCTRL_PIN_PD7	PINCTRL_PIN(PD_BASE + 7, "PD7")
+#define SUNXI_PINCTRL_PIN_PD8	PINCTRL_PIN(PD_BASE + 8, "PD8")
+#define SUNXI_PINCTRL_PIN_PD9	PINCTRL_PIN(PD_BASE + 9, "PD9")
+#define SUNXI_PINCTRL_PIN_PD10	PINCTRL_PIN(PD_BASE + 10, "PD10")
+#define SUNXI_PINCTRL_PIN_PD11	PINCTRL_PIN(PD_BASE + 11, "PD11")
+#define SUNXI_PINCTRL_PIN_PD12	PINCTRL_PIN(PD_BASE + 12, "PD12")
+#define SUNXI_PINCTRL_PIN_PD13	PINCTRL_PIN(PD_BASE + 13, "PD13")
+#define SUNXI_PINCTRL_PIN_PD14	PINCTRL_PIN(PD_BASE + 14, "PD14")
+#define SUNXI_PINCTRL_PIN_PD15	PINCTRL_PIN(PD_BASE + 15, "PD15")
+#define SUNXI_PINCTRL_PIN_PD16	PINCTRL_PIN(PD_BASE + 16, "PD16")
+#define SUNXI_PINCTRL_PIN_PD17	PINCTRL_PIN(PD_BASE + 17, "PD17")
+#define SUNXI_PINCTRL_PIN_PD18	PINCTRL_PIN(PD_BASE + 18, "PD18")
+#define SUNXI_PINCTRL_PIN_PD19	PINCTRL_PIN(PD_BASE + 19, "PD19")
+#define SUNXI_PINCTRL_PIN_PD20	PINCTRL_PIN(PD_BASE + 20, "PD20")
+#define SUNXI_PINCTRL_PIN_PD21	PINCTRL_PIN(PD_BASE + 21, "PD21")
+#define SUNXI_PINCTRL_PIN_PD22	PINCTRL_PIN(PD_BASE + 22, "PD22")
+#define SUNXI_PINCTRL_PIN_PD23	PINCTRL_PIN(PD_BASE + 23, "PD23")
+#define SUNXI_PINCTRL_PIN_PD24	PINCTRL_PIN(PD_BASE + 24, "PD24")
+#define SUNXI_PINCTRL_PIN_PD25	PINCTRL_PIN(PD_BASE + 25, "PD25")
+#define SUNXI_PINCTRL_PIN_PD26	PINCTRL_PIN(PD_BASE + 26, "PD26")
+#define SUNXI_PINCTRL_PIN_PD27	PINCTRL_PIN(PD_BASE + 27, "PD27")
+#define SUNXI_PINCTRL_PIN_PD28	PINCTRL_PIN(PD_BASE + 28, "PD28")
+#define SUNXI_PINCTRL_PIN_PD29	PINCTRL_PIN(PD_BASE + 29, "PD29")
+#define SUNXI_PINCTRL_PIN_PD30	PINCTRL_PIN(PD_BASE + 30, "PD30")
+#define SUNXI_PINCTRL_PIN_PD31	PINCTRL_PIN(PD_BASE + 31, "PD31")
+
+#define SUNXI_PINCTRL_PIN_PE0	PINCTRL_PIN(PE_BASE + 0, "PE0")
+#define SUNXI_PINCTRL_PIN_PE1	PINCTRL_PIN(PE_BASE + 1, "PE1")
+#define SUNXI_PINCTRL_PIN_PE2	PINCTRL_PIN(PE_BASE + 2, "PE2")
+#define SUNXI_PINCTRL_PIN_PE3	PINCTRL_PIN(PE_BASE + 3, "PE3")
+#define SUNXI_PINCTRL_PIN_PE4	PINCTRL_PIN(PE_BASE + 4, "PE4")
+#define SUNXI_PINCTRL_PIN_PE5	PINCTRL_PIN(PE_BASE + 5, "PE5")
+#define SUNXI_PINCTRL_PIN_PE6	PINCTRL_PIN(PE_BASE + 6, "PE6")
+#define SUNXI_PINCTRL_PIN_PE7	PINCTRL_PIN(PE_BASE + 7, "PE7")
+#define SUNXI_PINCTRL_PIN_PE8	PINCTRL_PIN(PE_BASE + 8, "PE8")
+#define SUNXI_PINCTRL_PIN_PE9	PINCTRL_PIN(PE_BASE + 9, "PE9")
+#define SUNXI_PINCTRL_PIN_PE10	PINCTRL_PIN(PE_BASE + 10, "PE10")
+#define SUNXI_PINCTRL_PIN_PE11	PINCTRL_PIN(PE_BASE + 11, "PE11")
+#define SUNXI_PINCTRL_PIN_PE12	PINCTRL_PIN(PE_BASE + 12, "PE12")
+#define SUNXI_PINCTRL_PIN_PE13	PINCTRL_PIN(PE_BASE + 13, "PE13")
+#define SUNXI_PINCTRL_PIN_PE14	PINCTRL_PIN(PE_BASE + 14, "PE14")
+#define SUNXI_PINCTRL_PIN_PE15	PINCTRL_PIN(PE_BASE + 15, "PE15")
+#define SUNXI_PINCTRL_PIN_PE16	PINCTRL_PIN(PE_BASE + 16, "PE16")
+#define SUNXI_PINCTRL_PIN_PE17	PINCTRL_PIN(PE_BASE + 17, "PE17")
+#define SUNXI_PINCTRL_PIN_PE18	PINCTRL_PIN(PE_BASE + 18, "PE18")
+#define SUNXI_PINCTRL_PIN_PE19	PINCTRL_PIN(PE_BASE + 19, "PE19")
+#define SUNXI_PINCTRL_PIN_PE20	PINCTRL_PIN(PE_BASE + 20, "PE20")
+#define SUNXI_PINCTRL_PIN_PE21	PINCTRL_PIN(PE_BASE + 21, "PE21")
+#define SUNXI_PINCTRL_PIN_PE22	PINCTRL_PIN(PE_BASE + 22, "PE22")
+#define SUNXI_PINCTRL_PIN_PE23	PINCTRL_PIN(PE_BASE + 23, "PE23")
+#define SUNXI_PINCTRL_PIN_PE24	PINCTRL_PIN(PE_BASE + 24, "PE24")
+#define SUNXI_PINCTRL_PIN_PE25	PINCTRL_PIN(PE_BASE + 25, "PE25")
+#define SUNXI_PINCTRL_PIN_PE26	PINCTRL_PIN(PE_BASE + 26, "PE26")
+#define SUNXI_PINCTRL_PIN_PE27	PINCTRL_PIN(PE_BASE + 27, "PE27")
+#define SUNXI_PINCTRL_PIN_PE28	PINCTRL_PIN(PE_BASE + 28, "PE28")
+#define SUNXI_PINCTRL_PIN_PE29	PINCTRL_PIN(PE_BASE + 29, "PE29")
+#define SUNXI_PINCTRL_PIN_PE30	PINCTRL_PIN(PE_BASE + 30, "PE30")
+#define SUNXI_PINCTRL_PIN_PE31	PINCTRL_PIN(PE_BASE + 31, "PE31")
+
+#define SUNXI_PINCTRL_PIN_PF0	PINCTRL_PIN(PF_BASE + 0, "PF0")
+#define SUNXI_PINCTRL_PIN_PF1	PINCTRL_PIN(PF_BASE + 1, "PF1")
+#define SUNXI_PINCTRL_PIN_PF2	PINCTRL_PIN(PF_BASE + 2, "PF2")
+#define SUNXI_PINCTRL_PIN_PF3	PINCTRL_PIN(PF_BASE + 3, "PF3")
+#define SUNXI_PINCTRL_PIN_PF4	PINCTRL_PIN(PF_BASE + 4, "PF4")
+#define SUNXI_PINCTRL_PIN_PF5	PINCTRL_PIN(PF_BASE + 5, "PF5")
+#define SUNXI_PINCTRL_PIN_PF6	PINCTRL_PIN(PF_BASE + 6, "PF6")
+#define SUNXI_PINCTRL_PIN_PF7	PINCTRL_PIN(PF_BASE + 7, "PF7")
+#define SUNXI_PINCTRL_PIN_PF8	PINCTRL_PIN(PF_BASE + 8, "PF8")
+#define SUNXI_PINCTRL_PIN_PF9	PINCTRL_PIN(PF_BASE + 9, "PF9")
+#define SUNXI_PINCTRL_PIN_PF10	PINCTRL_PIN(PF_BASE + 10, "PF10")
+#define SUNXI_PINCTRL_PIN_PF11	PINCTRL_PIN(PF_BASE + 11, "PF11")
+#define SUNXI_PINCTRL_PIN_PF12	PINCTRL_PIN(PF_BASE + 12, "PF12")
+#define SUNXI_PINCTRL_PIN_PF13	PINCTRL_PIN(PF_BASE + 13, "PF13")
+#define SUNXI_PINCTRL_PIN_PF14	PINCTRL_PIN(PF_BASE + 14, "PF14")
+#define SUNXI_PINCTRL_PIN_PF15	PINCTRL_PIN(PF_BASE + 15, "PF15")
+#define SUNXI_PINCTRL_PIN_PF16	PINCTRL_PIN(PF_BASE + 16, "PF16")
+#define SUNXI_PINCTRL_PIN_PF17	PINCTRL_PIN(PF_BASE + 17, "PF17")
+#define SUNXI_PINCTRL_PIN_PF18	PINCTRL_PIN(PF_BASE + 18, "PF18")
+#define SUNXI_PINCTRL_PIN_PF19	PINCTRL_PIN(PF_BASE + 19, "PF19")
+#define SUNXI_PINCTRL_PIN_PF20	PINCTRL_PIN(PF_BASE + 20, "PF20")
+#define SUNXI_PINCTRL_PIN_PF21	PINCTRL_PIN(PF_BASE + 21, "PF21")
+#define SUNXI_PINCTRL_PIN_PF22	PINCTRL_PIN(PF_BASE + 22, "PF22")
+#define SUNXI_PINCTRL_PIN_PF23	PINCTRL_PIN(PF_BASE + 23, "PF23")
+#define SUNXI_PINCTRL_PIN_PF24	PINCTRL_PIN(PF_BASE + 24, "PF24")
+#define SUNXI_PINCTRL_PIN_PF25	PINCTRL_PIN(PF_BASE + 25, "PF25")
+#define SUNXI_PINCTRL_PIN_PF26	PINCTRL_PIN(PF_BASE + 26, "PF26")
+#define SUNXI_PINCTRL_PIN_PF27	PINCTRL_PIN(PF_BASE + 27, "PF27")
+#define SUNXI_PINCTRL_PIN_PF28	PINCTRL_PIN(PF_BASE + 28, "PF28")
+#define SUNXI_PINCTRL_PIN_PF29	PINCTRL_PIN(PF_BASE + 29, "PF29")
+#define SUNXI_PINCTRL_PIN_PF30	PINCTRL_PIN(PF_BASE + 30, "PF30")
+#define SUNXI_PINCTRL_PIN_PF31	PINCTRL_PIN(PF_BASE + 31, "PF31")
+
+#define SUNXI_PINCTRL_PIN_PG0	PINCTRL_PIN(PG_BASE + 0, "PG0")
+#define SUNXI_PINCTRL_PIN_PG1	PINCTRL_PIN(PG_BASE + 1, "PG1")
+#define SUNXI_PINCTRL_PIN_PG2	PINCTRL_PIN(PG_BASE + 2, "PG2")
+#define SUNXI_PINCTRL_PIN_PG3	PINCTRL_PIN(PG_BASE + 3, "PG3")
+#define SUNXI_PINCTRL_PIN_PG4	PINCTRL_PIN(PG_BASE + 4, "PG4")
+#define SUNXI_PINCTRL_PIN_PG5	PINCTRL_PIN(PG_BASE + 5, "PG5")
+#define SUNXI_PINCTRL_PIN_PG6	PINCTRL_PIN(PG_BASE + 6, "PG6")
+#define SUNXI_PINCTRL_PIN_PG7	PINCTRL_PIN(PG_BASE + 7, "PG7")
+#define SUNXI_PINCTRL_PIN_PG8	PINCTRL_PIN(PG_BASE + 8, "PG8")
+#define SUNXI_PINCTRL_PIN_PG9	PINCTRL_PIN(PG_BASE + 9, "PG9")
+#define SUNXI_PINCTRL_PIN_PG10	PINCTRL_PIN(PG_BASE + 10, "PG10")
+#define SUNXI_PINCTRL_PIN_PG11	PINCTRL_PIN(PG_BASE + 11, "PG11")
+#define SUNXI_PINCTRL_PIN_PG12	PINCTRL_PIN(PG_BASE + 12, "PG12")
+#define SUNXI_PINCTRL_PIN_PG13	PINCTRL_PIN(PG_BASE + 13, "PG13")
+#define SUNXI_PINCTRL_PIN_PG14	PINCTRL_PIN(PG_BASE + 14, "PG14")
+#define SUNXI_PINCTRL_PIN_PG15	PINCTRL_PIN(PG_BASE + 15, "PG15")
+#define SUNXI_PINCTRL_PIN_PG16	PINCTRL_PIN(PG_BASE + 16, "PG16")
+#define SUNXI_PINCTRL_PIN_PG17	PINCTRL_PIN(PG_BASE + 17, "PG17")
+#define SUNXI_PINCTRL_PIN_PG18	PINCTRL_PIN(PG_BASE + 18, "PG18")
+#define SUNXI_PINCTRL_PIN_PG19	PINCTRL_PIN(PG_BASE + 19, "PG19")
+#define SUNXI_PINCTRL_PIN_PG20	PINCTRL_PIN(PG_BASE + 20, "PG20")
+#define SUNXI_PINCTRL_PIN_PG21	PINCTRL_PIN(PG_BASE + 21, "PG21")
+#define SUNXI_PINCTRL_PIN_PG22	PINCTRL_PIN(PG_BASE + 22, "PG22")
+#define SUNXI_PINCTRL_PIN_PG23	PINCTRL_PIN(PG_BASE + 23, "PG23")
+#define SUNXI_PINCTRL_PIN_PG24	PINCTRL_PIN(PG_BASE + 24, "PG24")
+#define SUNXI_PINCTRL_PIN_PG25	PINCTRL_PIN(PG_BASE + 25, "PG25")
+#define SUNXI_PINCTRL_PIN_PG26	PINCTRL_PIN(PG_BASE + 26, "PG26")
+#define SUNXI_PINCTRL_PIN_PG27	PINCTRL_PIN(PG_BASE + 27, "PG27")
+#define SUNXI_PINCTRL_PIN_PG28	PINCTRL_PIN(PG_BASE + 28, "PG28")
+#define SUNXI_PINCTRL_PIN_PG29	PINCTRL_PIN(PG_BASE + 29, "PG29")
+#define SUNXI_PINCTRL_PIN_PG30	PINCTRL_PIN(PG_BASE + 30, "PG30")
+#define SUNXI_PINCTRL_PIN_PG31	PINCTRL_PIN(PG_BASE + 31, "PG31")
+
+#define SUNXI_PINCTRL_PIN_PH0	PINCTRL_PIN(PH_BASE + 0, "PH0")
+#define SUNXI_PINCTRL_PIN_PH1	PINCTRL_PIN(PH_BASE + 1, "PH1")
+#define SUNXI_PINCTRL_PIN_PH2	PINCTRL_PIN(PH_BASE + 2, "PH2")
+#define SUNXI_PINCTRL_PIN_PH3	PINCTRL_PIN(PH_BASE + 3, "PH3")
+#define SUNXI_PINCTRL_PIN_PH4	PINCTRL_PIN(PH_BASE + 4, "PH4")
+#define SUNXI_PINCTRL_PIN_PH5	PINCTRL_PIN(PH_BASE + 5, "PH5")
+#define SUNXI_PINCTRL_PIN_PH6	PINCTRL_PIN(PH_BASE + 6, "PH6")
+#define SUNXI_PINCTRL_PIN_PH7	PINCTRL_PIN(PH_BASE + 7, "PH7")
+#define SUNXI_PINCTRL_PIN_PH8	PINCTRL_PIN(PH_BASE + 8, "PH8")
+#define SUNXI_PINCTRL_PIN_PH9	PINCTRL_PIN(PH_BASE + 9, "PH9")
+#define SUNXI_PINCTRL_PIN_PH10	PINCTRL_PIN(PH_BASE + 10, "PH10")
+#define SUNXI_PINCTRL_PIN_PH11	PINCTRL_PIN(PH_BASE + 11, "PH11")
+#define SUNXI_PINCTRL_PIN_PH12	PINCTRL_PIN(PH_BASE + 12, "PH12")
+#define SUNXI_PINCTRL_PIN_PH13	PINCTRL_PIN(PH_BASE + 13, "PH13")
+#define SUNXI_PINCTRL_PIN_PH14	PINCTRL_PIN(PH_BASE + 14, "PH14")
+#define SUNXI_PINCTRL_PIN_PH15	PINCTRL_PIN(PH_BASE + 15, "PH15")
+#define SUNXI_PINCTRL_PIN_PH16	PINCTRL_PIN(PH_BASE + 16, "PH16")
+#define SUNXI_PINCTRL_PIN_PH17	PINCTRL_PIN(PH_BASE + 17, "PH17")
+#define SUNXI_PINCTRL_PIN_PH18	PINCTRL_PIN(PH_BASE + 18, "PH18")
+#define SUNXI_PINCTRL_PIN_PH19	PINCTRL_PIN(PH_BASE + 19, "PH19")
+#define SUNXI_PINCTRL_PIN_PH20	PINCTRL_PIN(PH_BASE + 20, "PH20")
+#define SUNXI_PINCTRL_PIN_PH21	PINCTRL_PIN(PH_BASE + 21, "PH21")
+#define SUNXI_PINCTRL_PIN_PH22	PINCTRL_PIN(PH_BASE + 22, "PH22")
+#define SUNXI_PINCTRL_PIN_PH23	PINCTRL_PIN(PH_BASE + 23, "PH23")
+#define SUNXI_PINCTRL_PIN_PH24	PINCTRL_PIN(PH_BASE + 24, "PH24")
+#define SUNXI_PINCTRL_PIN_PH25	PINCTRL_PIN(PH_BASE + 25, "PH25")
+#define SUNXI_PINCTRL_PIN_PH26	PINCTRL_PIN(PH_BASE + 26, "PH26")
+#define SUNXI_PINCTRL_PIN_PH27	PINCTRL_PIN(PH_BASE + 27, "PH27")
+#define SUNXI_PINCTRL_PIN_PH28	PINCTRL_PIN(PH_BASE + 28, "PH28")
+#define SUNXI_PINCTRL_PIN_PH29	PINCTRL_PIN(PH_BASE + 29, "PH29")
+#define SUNXI_PINCTRL_PIN_PH30	PINCTRL_PIN(PH_BASE + 30, "PH30")
+#define SUNXI_PINCTRL_PIN_PH31	PINCTRL_PIN(PH_BASE + 31, "PH31")
+
+#define SUNXI_PINCTRL_PIN_PI0	PINCTRL_PIN(PI_BASE + 0, "PI0")
+#define SUNXI_PINCTRL_PIN_PI1	PINCTRL_PIN(PI_BASE + 1, "PI1")
+#define SUNXI_PINCTRL_PIN_PI2	PINCTRL_PIN(PI_BASE + 2, "PI2")
+#define SUNXI_PINCTRL_PIN_PI3	PINCTRL_PIN(PI_BASE + 3, "PI3")
+#define SUNXI_PINCTRL_PIN_PI4	PINCTRL_PIN(PI_BASE + 4, "PI4")
+#define SUNXI_PINCTRL_PIN_PI5	PINCTRL_PIN(PI_BASE + 5, "PI5")
+#define SUNXI_PINCTRL_PIN_PI6	PINCTRL_PIN(PI_BASE + 6, "PI6")
+#define SUNXI_PINCTRL_PIN_PI7	PINCTRL_PIN(PI_BASE + 7, "PI7")
+#define SUNXI_PINCTRL_PIN_PI8	PINCTRL_PIN(PI_BASE + 8, "PI8")
+#define SUNXI_PINCTRL_PIN_PI9	PINCTRL_PIN(PI_BASE + 9, "PI9")
+#define SUNXI_PINCTRL_PIN_PI10	PINCTRL_PIN(PI_BASE + 10, "PI10")
+#define SUNXI_PINCTRL_PIN_PI11	PINCTRL_PIN(PI_BASE + 11, "PI11")
+#define SUNXI_PINCTRL_PIN_PI12	PINCTRL_PIN(PI_BASE + 12, "PI12")
+#define SUNXI_PINCTRL_PIN_PI13	PINCTRL_PIN(PI_BASE + 13, "PI13")
+#define SUNXI_PINCTRL_PIN_PI14	PINCTRL_PIN(PI_BASE + 14, "PI14")
+#define SUNXI_PINCTRL_PIN_PI15	PINCTRL_PIN(PI_BASE + 15, "PI15")
+#define SUNXI_PINCTRL_PIN_PI16	PINCTRL_PIN(PI_BASE + 16, "PI16")
+#define SUNXI_PINCTRL_PIN_PI17	PINCTRL_PIN(PI_BASE + 17, "PI17")
+#define SUNXI_PINCTRL_PIN_PI18	PINCTRL_PIN(PI_BASE + 18, "PI18")
+#define SUNXI_PINCTRL_PIN_PI19	PINCTRL_PIN(PI_BASE + 19, "PI19")
+#define SUNXI_PINCTRL_PIN_PI20	PINCTRL_PIN(PI_BASE + 20, "PI20")
+#define SUNXI_PINCTRL_PIN_PI21	PINCTRL_PIN(PI_BASE + 21, "PI21")
+#define SUNXI_PINCTRL_PIN_PI22	PINCTRL_PIN(PI_BASE + 22, "PI22")
+#define SUNXI_PINCTRL_PIN_PI23	PINCTRL_PIN(PI_BASE + 23, "PI23")
+#define SUNXI_PINCTRL_PIN_PI24	PINCTRL_PIN(PI_BASE + 24, "PI24")
+#define SUNXI_PINCTRL_PIN_PI25	PINCTRL_PIN(PI_BASE + 25, "PI25")
+#define SUNXI_PINCTRL_PIN_PI26	PINCTRL_PIN(PI_BASE + 26, "PI26")
+#define SUNXI_PINCTRL_PIN_PI27	PINCTRL_PIN(PI_BASE + 27, "PI27")
+#define SUNXI_PINCTRL_PIN_PI28	PINCTRL_PIN(PI_BASE + 28, "PI28")
+#define SUNXI_PINCTRL_PIN_PI29	PINCTRL_PIN(PI_BASE + 29, "PI29")
+#define SUNXI_PINCTRL_PIN_PI30	PINCTRL_PIN(PI_BASE + 30, "PI30")
+#define SUNXI_PINCTRL_PIN_PI31	PINCTRL_PIN(PI_BASE + 31, "PI31")
+
+#define SUNXI_PIN_NAME_MAX_LEN	5
+
+#define BANK_MEM_SIZE		0x24
+#define MUX_REGS_OFFSET		0x0
+#define DATA_REGS_OFFSET	0x10
+#define DLEVEL_REGS_OFFSET	0x14
+#define PULL_REGS_OFFSET	0x1c
+
+#define PINS_PER_BANK		32
+#define MUX_PINS_PER_REG	8
+#define MUX_PINS_BITS		4
+#define MUX_PINS_MASK		0x0f
+#define DATA_PINS_PER_REG	32
+#define DATA_PINS_BITS		1
+#define DATA_PINS_MASK		0x01
+#define DLEVEL_PINS_PER_REG	16
+#define DLEVEL_PINS_BITS	2
+#define DLEVEL_PINS_MASK	0x03
+#define PULL_PINS_PER_REG	16
+#define PULL_PINS_BITS		2
+#define PULL_PINS_MASK		0x03
+
+struct sunxi_desc_function {
+	const char	*name;
+	u8		muxval;
+};
+
+struct sunxi_desc_pin {
+	struct pinctrl_pin_desc		pin;
+	struct sunxi_desc_function	*functions;
+};
+
+struct sunxi_pinctrl_desc {
+	const struct sunxi_desc_pin	*pins;
+	int				npins;
+	struct pinctrl_gpio_range	*ranges;
+	int				nranges;
+};
+
+struct sunxi_pinctrl_function {
+	const char	*name;
+	const char	**groups;
+	unsigned	ngroups;
+};
+
+struct sunxi_pinctrl_group {
+	const char	*name;
+	unsigned long	config;
+	unsigned	pin;
+};
+
+struct sunxi_pinctrl {
+	void __iomem			*membase;
+	struct gpio_chip		*chip;
+	struct sunxi_pinctrl_desc	*desc;
+	struct device			*dev;
+	struct sunxi_pinctrl_function	*functions;
+	unsigned			nfunctions;
+	struct sunxi_pinctrl_group	*groups;
+	unsigned			ngroups;
+	struct pinctrl_dev		*pctl_dev;
+};
+
+#define SUNXI_PIN(_pin, ...)					\
+	{							\
+		.pin = _pin,					\
+		.functions = (struct sunxi_desc_function[]){	\
+			__VA_ARGS__, { } },			\
+	}
+
+#define SUNXI_FUNCTION(_val, _name)				\
+	{							\
+		.name = _name,					\
+		.muxval = _val,					\
+	}
+
+/*
+ * The sunXi PIO registers are organized as is:
+ * 0x00 - 0x0c	Muxing values.
+ *		8 pins per register, each pin having a 4bits value
+ * 0x10		Pin values
+ *		32 bits per register, each pin corresponding to one bit
+ * 0x14 - 0x18	Drive level
+ *		16 pins per register, each pin having a 2bits value
+ * 0x1c - 0x20	Pull-Up values
+ *		16 pins per register, each pin having a 2bits value
+ *
+ * This is for the first bank. Each bank will have the same layout,
+ * with an offset being a multiple of 0x24.
+ *
+ * The following functions calculate from the pin number the register
+ * and the bit offset that we should access.
+ */
+static inline u32 sunxi_mux_reg(u16 pin)
+{
+	u8 bank = pin / PINS_PER_BANK;
+	u32 offset = bank * BANK_MEM_SIZE;
+	offset += MUX_REGS_OFFSET;
+	offset += pin % PINS_PER_BANK / MUX_PINS_PER_REG * 0x04;
+	return round_down(offset, 4);
+}
+
+static inline u32 sunxi_mux_offset(u16 pin)
+{
+	u32 pin_num = pin % MUX_PINS_PER_REG;
+	return pin_num * MUX_PINS_BITS;
+}
+
+static inline u32 sunxi_data_reg(u16 pin)
+{
+	u8 bank = pin / PINS_PER_BANK;
+	u32 offset = bank * BANK_MEM_SIZE;
+	offset += DATA_REGS_OFFSET;
+	offset += pin % PINS_PER_BANK / DATA_PINS_PER_REG * 0x04;
+	return round_down(offset, 4);
+}
+
+static inline u32 sunxi_data_offset(u16 pin)
+{
+	u32 pin_num = pin % DATA_PINS_PER_REG;
+	return pin_num * DATA_PINS_BITS;
+}
+
+static inline u32 sunxi_dlevel_reg(u16 pin)
+{
+	u8 bank = pin / PINS_PER_BANK;
+	u32 offset = bank * BANK_MEM_SIZE;
+	offset += DLEVEL_REGS_OFFSET;
+	offset += pin % PINS_PER_BANK / DLEVEL_PINS_PER_REG * 0x04;
+	return round_down(offset, 4);
+}
+
+static inline u32 sunxi_dlevel_offset(u16 pin)
+{
+	u32 pin_num = pin % DLEVEL_PINS_PER_REG;
+	return pin_num * DLEVEL_PINS_BITS;
+}
+
+static inline u32 sunxi_pull_reg(u16 pin)
+{
+	u8 bank = pin / PINS_PER_BANK;
+	u32 offset = bank * BANK_MEM_SIZE;
+	offset += PULL_REGS_OFFSET;
+	offset += pin % PINS_PER_BANK / PULL_PINS_PER_REG * 0x04;
+	return round_down(offset, 4);
+}
+
+static inline u32 sunxi_pull_offset(u16 pin)
+{
+	u32 pin_num = pin % PULL_PINS_PER_REG;
+	return pin_num * PULL_PINS_BITS;
+}
+
+#endif /* __PINCTRL_SUNXI_H */
diff --git a/drivers/pinctrl/pinctrl-tegra.c b/drivers/pinctrl/pinctrl-tegra.c
index ae1e4bb..f195d77 100644
--- a/drivers/pinctrl/pinctrl-tegra.c
+++ b/drivers/pinctrl/pinctrl-tegra.c
@@ -201,6 +201,7 @@
 	{"nvidia,open-drain",		TEGRA_PINCONF_PARAM_OPEN_DRAIN},
 	{"nvidia,lock",			TEGRA_PINCONF_PARAM_LOCK},
 	{"nvidia,io-reset",		TEGRA_PINCONF_PARAM_IORESET},
+	{"nvidia,rcv-sel",		TEGRA_PINCONF_PARAM_RCV_SEL},
 	{"nvidia,high-speed-mode",	TEGRA_PINCONF_PARAM_HIGH_SPEED_MODE},
 	{"nvidia,schmitt",		TEGRA_PINCONF_PARAM_SCHMITT},
 	{"nvidia,low-power-mode",	TEGRA_PINCONF_PARAM_LOW_POWER_MODE},
@@ -208,6 +209,7 @@
 	{"nvidia,pull-up-strength",	TEGRA_PINCONF_PARAM_DRIVE_UP_STRENGTH},
 	{"nvidia,slew-rate-falling",	TEGRA_PINCONF_PARAM_SLEW_RATE_FALLING},
 	{"nvidia,slew-rate-rising",	TEGRA_PINCONF_PARAM_SLEW_RATE_RISING},
+	{"nvidia,drive-type",		TEGRA_PINCONF_PARAM_DRIVE_TYPE},
 };
 
 static int tegra_pinctrl_dt_subnode_to_map(struct device *dev,
@@ -450,6 +452,12 @@
 		*bit = g->ioreset_bit;
 		*width = 1;
 		break;
+	case TEGRA_PINCONF_PARAM_RCV_SEL:
+		*bank = g->rcv_sel_bank;
+		*reg = g->rcv_sel_reg;
+		*bit = g->rcv_sel_bit;
+		*width = 1;
+		break;
 	case TEGRA_PINCONF_PARAM_HIGH_SPEED_MODE:
 		*bank = g->drv_bank;
 		*reg = g->drv_reg;
@@ -492,6 +500,12 @@
 		*bit = g->slwr_bit;
 		*width = g->slwr_width;
 		break;
+	case TEGRA_PINCONF_PARAM_DRIVE_TYPE:
+		*bank = g->drvtype_bank;
+		*reg = g->drvtype_reg;
+		*bit = g->drvtype_bit;
+		*width = 2;
+		break;
 	default:
 		dev_err(pmx->dev, "Invalid config param %04x\n", param);
 		return -ENOTSUPP;
diff --git a/drivers/pinctrl/pinctrl-tegra.h b/drivers/pinctrl/pinctrl-tegra.h
index 62e3809..817f706 100644
--- a/drivers/pinctrl/pinctrl-tegra.h
+++ b/drivers/pinctrl/pinctrl-tegra.h
@@ -30,6 +30,8 @@
 	/* argument: Boolean */
 	TEGRA_PINCONF_PARAM_IORESET,
 	/* argument: Boolean */
+	TEGRA_PINCONF_PARAM_RCV_SEL,
+	/* argument: Boolean */
 	TEGRA_PINCONF_PARAM_HIGH_SPEED_MODE,
 	/* argument: Boolean */
 	TEGRA_PINCONF_PARAM_SCHMITT,
@@ -43,6 +45,8 @@
 	TEGRA_PINCONF_PARAM_SLEW_RATE_FALLING,
 	/* argument: Integer, range is HW-dependant */
 	TEGRA_PINCONF_PARAM_SLEW_RATE_RISING,
+	/* argument: Integer, range is HW-dependant */
+	TEGRA_PINCONF_PARAM_DRIVE_TYPE,
 };
 
 enum tegra_pinconf_pull {
@@ -95,6 +99,9 @@
  * @ioreset_reg:	IO reset register offset. -1 if unsupported.
  * @ioreset_bank:	IO reset register bank. 0 if unsupported.
  * @ioreset_bit:	IO reset register bit. 0 if unsupported.
+ * @rcv_sel_reg:	Receiver select offset. -1 if unsupported.
+ * @rcv_sel_bank:	Receiver select bank. 0 if unsupported.
+ * @rcv_sel_bit:	Receiver select bit. 0 if unsupported.
  * @drv_reg:		Drive fields register offset. -1 if unsupported.
  *			This register contains the hsm, schmitt, lpmd, drvdn,
  *			drvup, slwr, and slwf parameters.
@@ -110,6 +117,9 @@
  * @slwr_width:		Slew Rising field width. 0 if unsupported.
  * @slwf_bit:		Slew Falling register bit. 0 if unsupported.
  * @slwf_width:		Slew Falling field width. 0 if unsupported.
+ * @drvtype_reg:	Drive type fields register offset. -1 if unsupported.
+ * @drvtype_bank:	Drive type fields register bank. 0 if unsupported.
+ * @drvtype_bit:	Drive type register bit. 0 if unsupported.
  *
  * A representation of a group of pins (possibly just one pin) in the Tegra
  * pin controller. Each group allows some parameter or parameters to be
@@ -131,15 +141,19 @@
 	s16 odrain_reg;
 	s16 lock_reg;
 	s16 ioreset_reg;
+	s16 rcv_sel_reg;
 	s16 drv_reg;
+	s16 drvtype_reg;
 	u32 mux_bank:2;
 	u32 pupd_bank:2;
 	u32 tri_bank:2;
 	u32 einput_bank:2;
 	u32 odrain_bank:2;
 	u32 ioreset_bank:2;
+	u32 rcv_sel_bank:2;
 	u32 lock_bank:2;
 	u32 drv_bank:2;
+	u32 drvtype_bank:2;
 	u32 mux_bit:5;
 	u32 pupd_bit:5;
 	u32 tri_bit:5;
@@ -147,6 +161,7 @@
 	u32 odrain_bit:5;
 	u32 lock_bit:5;
 	u32 ioreset_bit:5;
+	u32 rcv_sel_bit:5;
 	u32 hsm_bit:5;
 	u32 schmitt_bit:5;
 	u32 lpmd_bit:5;
@@ -154,6 +169,7 @@
 	u32 drvup_bit:5;
 	u32 slwr_bit:5;
 	u32 slwf_bit:5;
+	u32 drvtype_bit:5;
 	u32 drvdn_width:6;
 	u32 drvup_width:6;
 	u32 slwr_width:6;
diff --git a/drivers/pinctrl/pinctrl-tegra114.c b/drivers/pinctrl/pinctrl-tegra114.c
new file mode 100644
index 0000000..622c485
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-tegra114.c
@@ -0,0 +1,2769 @@
+/*
+ * Pinctrl data and driver for the NVIDIA Tegra114 pinmux
+ *
+ * Copyright (c) 2012-2013, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * Arthur:  Pritesh Raithatha <praithatha@nvidia.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+
+#include "pinctrl-tegra.h"
+
+/*
+ * Most pins affected by the pinmux can also be GPIOs. Define these first.
+ * These must match how the GPIO driver names/numbers its pins.
+ */
+#define _GPIO(offset)				(offset)
+
+#define TEGRA_PIN_CLK_32K_OUT_PA0		_GPIO(0)
+#define TEGRA_PIN_UART3_CTS_N_PA1		_GPIO(1)
+#define TEGRA_PIN_DAP2_FS_PA2			_GPIO(2)
+#define TEGRA_PIN_DAP2_SCLK_PA3			_GPIO(3)
+#define TEGRA_PIN_DAP2_DIN_PA4			_GPIO(4)
+#define TEGRA_PIN_DAP2_DOUT_PA5			_GPIO(5)
+#define TEGRA_PIN_SDMMC3_CLK_PA6		_GPIO(6)
+#define TEGRA_PIN_SDMMC3_CMD_PA7		_GPIO(7)
+#define TEGRA_PIN_GMI_A17_PB0			_GPIO(8)
+#define TEGRA_PIN_GMI_A18_PB1			_GPIO(9)
+#define TEGRA_PIN_SDMMC3_DAT3_PB4		_GPIO(12)
+#define TEGRA_PIN_SDMMC3_DAT2_PB5		_GPIO(13)
+#define TEGRA_PIN_SDMMC3_DAT1_PB6		_GPIO(14)
+#define TEGRA_PIN_SDMMC3_DAT0_PB7		_GPIO(15)
+#define TEGRA_PIN_UART3_RTS_N_PC0		_GPIO(16)
+#define TEGRA_PIN_UART2_TXD_PC2			_GPIO(18)
+#define TEGRA_PIN_UART2_RXD_PC3			_GPIO(19)
+#define TEGRA_PIN_GEN1_I2C_SCL_PC4		_GPIO(20)
+#define TEGRA_PIN_GEN1_I2C_SDA_PC5		_GPIO(21)
+#define TEGRA_PIN_GMI_WP_N_PC7			_GPIO(23)
+#define TEGRA_PIN_GMI_AD0_PG0			_GPIO(48)
+#define TEGRA_PIN_GMI_AD1_PG1			_GPIO(49)
+#define TEGRA_PIN_GMI_AD2_PG2			_GPIO(50)
+#define TEGRA_PIN_GMI_AD3_PG3			_GPIO(51)
+#define TEGRA_PIN_GMI_AD4_PG4			_GPIO(52)
+#define TEGRA_PIN_GMI_AD5_PG5			_GPIO(53)
+#define TEGRA_PIN_GMI_AD6_PG6			_GPIO(54)
+#define TEGRA_PIN_GMI_AD7_PG7			_GPIO(55)
+#define TEGRA_PIN_GMI_AD8_PH0			_GPIO(56)
+#define TEGRA_PIN_GMI_AD9_PH1			_GPIO(57)
+#define TEGRA_PIN_GMI_AD10_PH2			_GPIO(58)
+#define TEGRA_PIN_GMI_AD11_PH3			_GPIO(59)
+#define TEGRA_PIN_GMI_AD12_PH4			_GPIO(60)
+#define TEGRA_PIN_GMI_AD13_PH5			_GPIO(61)
+#define TEGRA_PIN_GMI_AD14_PH6			_GPIO(62)
+#define TEGRA_PIN_GMI_AD15_PH7			_GPIO(63)
+#define TEGRA_PIN_GMI_WR_N_PI0			_GPIO(64)
+#define TEGRA_PIN_GMI_OE_N_PI1			_GPIO(65)
+#define TEGRA_PIN_GMI_CS6_N_PI3			_GPIO(67)
+#define TEGRA_PIN_GMI_RST_N_PI4			_GPIO(68)
+#define TEGRA_PIN_GMI_IORDY_PI5			_GPIO(69)
+#define TEGRA_PIN_GMI_CS7_N_PI6			_GPIO(70)
+#define TEGRA_PIN_GMI_WAIT_PI7			_GPIO(71)
+#define TEGRA_PIN_GMI_CS0_N_PJ0			_GPIO(72)
+#define TEGRA_PIN_GMI_CS1_N_PJ2			_GPIO(74)
+#define TEGRA_PIN_GMI_DQS_P_PJ3			_GPIO(75)
+#define TEGRA_PIN_UART2_CTS_N_PJ5		_GPIO(77)
+#define TEGRA_PIN_UART2_RTS_N_PJ6		_GPIO(78)
+#define TEGRA_PIN_GMI_A16_PJ7			_GPIO(79)
+#define TEGRA_PIN_GMI_ADV_N_PK0			_GPIO(80)
+#define TEGRA_PIN_GMI_CLK_PK1			_GPIO(81)
+#define TEGRA_PIN_GMI_CS4_N_PK2			_GPIO(82)
+#define TEGRA_PIN_GMI_CS2_N_PK3			_GPIO(83)
+#define TEGRA_PIN_GMI_CS3_N_PK4			_GPIO(84)
+#define TEGRA_PIN_SPDIF_OUT_PK5			_GPIO(85)
+#define TEGRA_PIN_SPDIF_IN_PK6			_GPIO(86)
+#define TEGRA_PIN_GMI_A19_PK7			_GPIO(87)
+#define TEGRA_PIN_DAP1_FS_PN0			_GPIO(104)
+#define TEGRA_PIN_DAP1_DIN_PN1			_GPIO(105)
+#define TEGRA_PIN_DAP1_DOUT_PN2			_GPIO(106)
+#define TEGRA_PIN_DAP1_SCLK_PN3			_GPIO(107)
+#define TEGRA_PIN_USB_VBUS_EN0_PN4		_GPIO(108)
+#define TEGRA_PIN_USB_VBUS_EN1_PN5		_GPIO(109)
+#define TEGRA_PIN_HDMI_INT_PN7			_GPIO(111)
+#define TEGRA_PIN_ULPI_DATA7_PO0		_GPIO(112)
+#define TEGRA_PIN_ULPI_DATA0_PO1		_GPIO(113)
+#define TEGRA_PIN_ULPI_DATA1_PO2		_GPIO(114)
+#define TEGRA_PIN_ULPI_DATA2_PO3		_GPIO(115)
+#define TEGRA_PIN_ULPI_DATA3_PO4		_GPIO(116)
+#define TEGRA_PIN_ULPI_DATA4_PO5		_GPIO(117)
+#define TEGRA_PIN_ULPI_DATA5_PO6		_GPIO(118)
+#define TEGRA_PIN_ULPI_DATA6_PO7		_GPIO(119)
+#define TEGRA_PIN_DAP3_FS_PP0			_GPIO(120)
+#define TEGRA_PIN_DAP3_DIN_PP1			_GPIO(121)
+#define TEGRA_PIN_DAP3_DOUT_PP2			_GPIO(122)
+#define TEGRA_PIN_DAP3_SCLK_PP3			_GPIO(123)
+#define TEGRA_PIN_DAP4_FS_PP4			_GPIO(124)
+#define TEGRA_PIN_DAP4_DIN_PP5			_GPIO(125)
+#define TEGRA_PIN_DAP4_DOUT_PP6			_GPIO(126)
+#define TEGRA_PIN_DAP4_SCLK_PP7			_GPIO(127)
+#define TEGRA_PIN_KB_COL0_PQ0			_GPIO(128)
+#define TEGRA_PIN_KB_COL1_PQ1			_GPIO(129)
+#define TEGRA_PIN_KB_COL2_PQ2			_GPIO(130)
+#define TEGRA_PIN_KB_COL3_PQ3			_GPIO(131)
+#define TEGRA_PIN_KB_COL4_PQ4			_GPIO(132)
+#define TEGRA_PIN_KB_COL5_PQ5			_GPIO(133)
+#define TEGRA_PIN_KB_COL6_PQ6			_GPIO(134)
+#define TEGRA_PIN_KB_COL7_PQ7			_GPIO(135)
+#define TEGRA_PIN_KB_ROW0_PR0			_GPIO(136)
+#define TEGRA_PIN_KB_ROW1_PR1			_GPIO(137)
+#define TEGRA_PIN_KB_ROW2_PR2			_GPIO(138)
+#define TEGRA_PIN_KB_ROW3_PR3			_GPIO(139)
+#define TEGRA_PIN_KB_ROW4_PR4			_GPIO(140)
+#define TEGRA_PIN_KB_ROW5_PR5			_GPIO(141)
+#define TEGRA_PIN_KB_ROW6_PR6			_GPIO(142)
+#define TEGRA_PIN_KB_ROW7_PR7			_GPIO(143)
+#define TEGRA_PIN_KB_ROW8_PS0			_GPIO(144)
+#define TEGRA_PIN_KB_ROW9_PS1			_GPIO(145)
+#define TEGRA_PIN_KB_ROW10_PS2			_GPIO(146)
+#define TEGRA_PIN_GEN2_I2C_SCL_PT5		_GPIO(157)
+#define TEGRA_PIN_GEN2_I2C_SDA_PT6		_GPIO(158)
+#define TEGRA_PIN_SDMMC4_CMD_PT7		_GPIO(159)
+#define TEGRA_PIN_PU0				_GPIO(160)
+#define TEGRA_PIN_PU1				_GPIO(161)
+#define TEGRA_PIN_PU2				_GPIO(162)
+#define TEGRA_PIN_PU3				_GPIO(163)
+#define TEGRA_PIN_PU4				_GPIO(164)
+#define TEGRA_PIN_PU5				_GPIO(165)
+#define TEGRA_PIN_PU6				_GPIO(166)
+#define TEGRA_PIN_PV0				_GPIO(168)
+#define TEGRA_PIN_PV1				_GPIO(169)
+#define TEGRA_PIN_SDMMC3_CD_N_PV2		_GPIO(170)
+#define TEGRA_PIN_SDMMC1_WP_N_PV3		_GPIO(171)
+#define TEGRA_PIN_DDC_SCL_PV4			_GPIO(172)
+#define TEGRA_PIN_DDC_SDA_PV5			_GPIO(173)
+#define TEGRA_PIN_GPIO_W2_AUD_PW2		_GPIO(178)
+#define TEGRA_PIN_GPIO_W3_AUD_PW3		_GPIO(179)
+#define TEGRA_PIN_CLK1_OUT_PW4			_GPIO(180)
+#define TEGRA_PIN_CLK2_OUT_PW5			_GPIO(181)
+#define TEGRA_PIN_UART3_TXD_PW6			_GPIO(182)
+#define TEGRA_PIN_UART3_RXD_PW7			_GPIO(183)
+#define TEGRA_PIN_DVFS_PWM_PX0			_GPIO(184)
+#define TEGRA_PIN_GPIO_X1_AUD_PX1		_GPIO(185)
+#define TEGRA_PIN_DVFS_CLK_PX2			_GPIO(186)
+#define TEGRA_PIN_GPIO_X3_AUD_PX3		_GPIO(187)
+#define TEGRA_PIN_GPIO_X4_AUD_PX4		_GPIO(188)
+#define TEGRA_PIN_GPIO_X5_AUD_PX5		_GPIO(189)
+#define TEGRA_PIN_GPIO_X6_AUD_PX6		_GPIO(190)
+#define TEGRA_PIN_GPIO_X7_AUD_PX7		_GPIO(191)
+#define TEGRA_PIN_ULPI_CLK_PY0			_GPIO(192)
+#define TEGRA_PIN_ULPI_DIR_PY1			_GPIO(193)
+#define TEGRA_PIN_ULPI_NXT_PY2			_GPIO(194)
+#define TEGRA_PIN_ULPI_STP_PY3			_GPIO(195)
+#define TEGRA_PIN_SDMMC1_DAT3_PY4		_GPIO(196)
+#define TEGRA_PIN_SDMMC1_DAT2_PY5		_GPIO(197)
+#define TEGRA_PIN_SDMMC1_DAT1_PY6		_GPIO(198)
+#define TEGRA_PIN_SDMMC1_DAT0_PY7		_GPIO(199)
+#define TEGRA_PIN_SDMMC1_CLK_PZ0		_GPIO(200)
+#define TEGRA_PIN_SDMMC1_CMD_PZ1		_GPIO(201)
+#define TEGRA_PIN_SYS_CLK_REQ_PZ5		_GPIO(205)
+#define TEGRA_PIN_PWR_I2C_SCL_PZ6		_GPIO(206)
+#define TEGRA_PIN_PWR_I2C_SDA_PZ7		_GPIO(207)
+#define TEGRA_PIN_SDMMC4_DAT0_PAA0		_GPIO(208)
+#define TEGRA_PIN_SDMMC4_DAT1_PAA1		_GPIO(209)
+#define TEGRA_PIN_SDMMC4_DAT2_PAA2		_GPIO(210)
+#define TEGRA_PIN_SDMMC4_DAT3_PAA3		_GPIO(211)
+#define TEGRA_PIN_SDMMC4_DAT4_PAA4		_GPIO(212)
+#define TEGRA_PIN_SDMMC4_DAT5_PAA5		_GPIO(213)
+#define TEGRA_PIN_SDMMC4_DAT6_PAA6		_GPIO(214)
+#define TEGRA_PIN_SDMMC4_DAT7_PAA7		_GPIO(215)
+#define TEGRA_PIN_PBB0				_GPIO(216)
+#define TEGRA_PIN_CAM_I2C_SCL_PBB1		_GPIO(217)
+#define TEGRA_PIN_CAM_I2C_SDA_PBB2		_GPIO(218)
+#define TEGRA_PIN_PBB3				_GPIO(219)
+#define TEGRA_PIN_PBB4				_GPIO(220)
+#define TEGRA_PIN_PBB5				_GPIO(221)
+#define TEGRA_PIN_PBB6				_GPIO(222)
+#define TEGRA_PIN_PBB7				_GPIO(223)
+#define TEGRA_PIN_CAM_MCLK_PCC0			_GPIO(224)
+#define TEGRA_PIN_PCC1				_GPIO(225)
+#define TEGRA_PIN_PCC2				_GPIO(226)
+#define TEGRA_PIN_SDMMC4_CLK_PCC4		_GPIO(228)
+#define TEGRA_PIN_CLK2_REQ_PCC5			_GPIO(229)
+#define TEGRA_PIN_CLK3_OUT_PEE0			_GPIO(240)
+#define TEGRA_PIN_CLK3_REQ_PEE1			_GPIO(241)
+#define TEGRA_PIN_CLK1_REQ_PEE2			_GPIO(242)
+#define TEGRA_PIN_HDMI_CEC_PEE3			_GPIO(243)
+#define TEGRA_PIN_SDMMC3_CLK_LB_OUT_PEE4	_GPIO(244)
+#define TEGRA_PIN_SDMMC3_CLK_LB_IN_PEE5		_GPIO(245)
+
+/* All non-GPIO pins follow */
+#define NUM_GPIOS	(TEGRA_PIN_SDMMC3_CLK_LB_IN_PEE5 + 1)
+#define _PIN(offset)	(NUM_GPIOS + (offset))
+
+/* Non-GPIO pins */
+#define TEGRA_PIN_CORE_PWR_REQ			_PIN(0)
+#define TEGRA_PIN_CPU_PWR_REQ			_PIN(1)
+#define TEGRA_PIN_PWR_INT_N			_PIN(2)
+#define TEGRA_PIN_RESET_OUT_N			_PIN(3)
+#define TEGRA_PIN_OWR				_PIN(4)
+
+static const struct pinctrl_pin_desc  tegra114_pins[] = {
+	PINCTRL_PIN(TEGRA_PIN_CLK_32K_OUT_PA0, "CLK_32K_OUT PA0"),
+	PINCTRL_PIN(TEGRA_PIN_UART3_CTS_N_PA1, "UART3_CTS_N PA1"),
+	PINCTRL_PIN(TEGRA_PIN_DAP2_FS_PA2, "DAP2_FS PA2"),
+	PINCTRL_PIN(TEGRA_PIN_DAP2_SCLK_PA3, "DAP2_SCLK PA3"),
+	PINCTRL_PIN(TEGRA_PIN_DAP2_DIN_PA4, "DAP2_DIN PA4"),
+	PINCTRL_PIN(TEGRA_PIN_DAP2_DOUT_PA5, "DAP2_DOUT PA5"),
+	PINCTRL_PIN(TEGRA_PIN_SDMMC3_CLK_PA6, "SDMMC3_CLK PA6"),
+	PINCTRL_PIN(TEGRA_PIN_SDMMC3_CMD_PA7, "SDMMC3_CMD PA7"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_A17_PB0, "GMI_A17 PB0"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_A18_PB1, "GMI_A18 PB1"),
+	PINCTRL_PIN(TEGRA_PIN_SDMMC3_DAT3_PB4, "SDMMC3_DAT3 PB4"),
+	PINCTRL_PIN(TEGRA_PIN_SDMMC3_DAT2_PB5, "SDMMC3_DAT2 PB5"),
+	PINCTRL_PIN(TEGRA_PIN_SDMMC3_DAT1_PB6, "SDMMC3_DAT1 PB6"),
+	PINCTRL_PIN(TEGRA_PIN_SDMMC3_DAT0_PB7, "SDMMC3_DAT0 PB7"),
+	PINCTRL_PIN(TEGRA_PIN_UART3_RTS_N_PC0, "UART3_RTS_N PC0"),
+	PINCTRL_PIN(TEGRA_PIN_UART2_TXD_PC2, "UART2_TXD PC2"),
+	PINCTRL_PIN(TEGRA_PIN_UART2_RXD_PC3, "UART2_RXD PC3"),
+	PINCTRL_PIN(TEGRA_PIN_GEN1_I2C_SCL_PC4, "GEN1_I2C_SCL PC4"),
+	PINCTRL_PIN(TEGRA_PIN_GEN1_I2C_SDA_PC5, "GEN1_I2C_SDA PC5"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_WP_N_PC7, "GMI_WP_N PC7"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_AD0_PG0, "GMI_AD0 PG0"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_AD1_PG1, "GMI_AD1 PG1"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_AD2_PG2, "GMI_AD2 PG2"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_AD3_PG3, "GMI_AD3 PG3"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_AD4_PG4, "GMI_AD4 PG4"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_AD5_PG5, "GMI_AD5 PG5"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_AD6_PG6, "GMI_AD6 PG6"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_AD7_PG7, "GMI_AD7 PG7"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_AD8_PH0, "GMI_AD8 PH0"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_AD9_PH1, "GMI_AD9 PH1"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_AD10_PH2, "GMI_AD10 PH2"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_AD11_PH3, "GMI_AD11 PH3"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_AD12_PH4, "GMI_AD12 PH4"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_AD13_PH5, "GMI_AD13 PH5"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_AD14_PH6, "GMI_AD14 PH6"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_AD15_PH7, "GMI_AD15 PH7"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_WR_N_PI0, "GMI_WR_N PI0"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_OE_N_PI1, "GMI_OE_N PI1"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_CS6_N_PI3, "GMI_CS6_N PI3"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_RST_N_PI4, "GMI_RST_N PI4"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_IORDY_PI5, "GMI_IORDY PI5"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_CS7_N_PI6, "GMI_CS7_N PI6"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_WAIT_PI7, "GMI_WAIT PI7"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_CS0_N_PJ0, "GMI_CS0_N PJ0"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_CS1_N_PJ2, "GMI_CS1_N PJ2"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_DQS_P_PJ3, "GMI_DQS_P PJ3"),
+	PINCTRL_PIN(TEGRA_PIN_UART2_CTS_N_PJ5, "UART2_CTS_N PJ5"),
+	PINCTRL_PIN(TEGRA_PIN_UART2_RTS_N_PJ6, "UART2_RTS_N PJ6"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_A16_PJ7, "GMI_A16 PJ7"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_ADV_N_PK0, "GMI_ADV_N PK0"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_CLK_PK1, "GMI_CLK PK1"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_CS4_N_PK2, "GMI_CS4_N PK2"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_CS2_N_PK3, "GMI_CS2_N PK3"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_CS3_N_PK4, "GMI_CS3_N PK4"),
+	PINCTRL_PIN(TEGRA_PIN_SPDIF_OUT_PK5, "SPDIF_OUT PK5"),
+	PINCTRL_PIN(TEGRA_PIN_SPDIF_IN_PK6, "SPDIF_IN PK6"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_A19_PK7, "GMI_A19 PK7"),
+	PINCTRL_PIN(TEGRA_PIN_DAP1_FS_PN0, "DAP1_FS PN0"),
+	PINCTRL_PIN(TEGRA_PIN_DAP1_DIN_PN1, "DAP1_DIN PN1"),
+	PINCTRL_PIN(TEGRA_PIN_DAP1_DOUT_PN2, "DAP1_DOUT PN2"),
+	PINCTRL_PIN(TEGRA_PIN_DAP1_SCLK_PN3, "DAP1_SCLK PN3"),
+	PINCTRL_PIN(TEGRA_PIN_USB_VBUS_EN0_PN4, "USB_VBUS_EN0 PN4"),
+	PINCTRL_PIN(TEGRA_PIN_USB_VBUS_EN1_PN5, "USB_VBUS_EN1 PN5"),
+	PINCTRL_PIN(TEGRA_PIN_HDMI_INT_PN7, "HDMI_INT PN7"),
+	PINCTRL_PIN(TEGRA_PIN_ULPI_DATA7_PO0, "ULPI_DATA7 PO0"),
+	PINCTRL_PIN(TEGRA_PIN_ULPI_DATA0_PO1, "ULPI_DATA0 PO1"),
+	PINCTRL_PIN(TEGRA_PIN_ULPI_DATA1_PO2, "ULPI_DATA1 PO2"),
+	PINCTRL_PIN(TEGRA_PIN_ULPI_DATA2_PO3, "ULPI_DATA2 PO3"),
+	PINCTRL_PIN(TEGRA_PIN_ULPI_DATA3_PO4, "ULPI_DATA3 PO4"),
+	PINCTRL_PIN(TEGRA_PIN_ULPI_DATA4_PO5, "ULPI_DATA4 PO5"),
+	PINCTRL_PIN(TEGRA_PIN_ULPI_DATA5_PO6, "ULPI_DATA5 PO6"),
+	PINCTRL_PIN(TEGRA_PIN_ULPI_DATA6_PO7, "ULPI_DATA6 PO7"),
+	PINCTRL_PIN(TEGRA_PIN_DAP3_FS_PP0, "DAP3_FS PP0"),
+	PINCTRL_PIN(TEGRA_PIN_DAP3_DIN_PP1, "DAP3_DIN PP1"),
+	PINCTRL_PIN(TEGRA_PIN_DAP3_DOUT_PP2, "DAP3_DOUT PP2"),
+	PINCTRL_PIN(TEGRA_PIN_DAP3_SCLK_PP3, "DAP3_SCLK PP3"),
+	PINCTRL_PIN(TEGRA_PIN_DAP4_FS_PP4, "DAP4_FS PP4"),
+	PINCTRL_PIN(TEGRA_PIN_DAP4_DIN_PP5, "DAP4_DIN PP5"),
+	PINCTRL_PIN(TEGRA_PIN_DAP4_DOUT_PP6, "DAP4_DOUT PP6"),
+	PINCTRL_PIN(TEGRA_PIN_DAP4_SCLK_PP7, "DAP4_SCLK PP7"),
+	PINCTRL_PIN(TEGRA_PIN_KB_COL0_PQ0, "KB_COL0 PQ0"),
+	PINCTRL_PIN(TEGRA_PIN_KB_COL1_PQ1, "KB_COL1 PQ1"),
+	PINCTRL_PIN(TEGRA_PIN_KB_COL2_PQ2, "KB_COL2 PQ2"),
+	PINCTRL_PIN(TEGRA_PIN_KB_COL3_PQ3, "KB_COL3 PQ3"),
+	PINCTRL_PIN(TEGRA_PIN_KB_COL4_PQ4, "KB_COL4 PQ4"),
+	PINCTRL_PIN(TEGRA_PIN_KB_COL5_PQ5, "KB_COL5 PQ5"),
+	PINCTRL_PIN(TEGRA_PIN_KB_COL6_PQ6, "KB_COL6 PQ6"),
+	PINCTRL_PIN(TEGRA_PIN_KB_COL7_PQ7, "KB_COL7 PQ7"),
+	PINCTRL_PIN(TEGRA_PIN_KB_ROW0_PR0, "KB_ROW0 PR0"),
+	PINCTRL_PIN(TEGRA_PIN_KB_ROW1_PR1, "KB_ROW1 PR1"),
+	PINCTRL_PIN(TEGRA_PIN_KB_ROW2_PR2, "KB_ROW2 PR2"),
+	PINCTRL_PIN(TEGRA_PIN_KB_ROW3_PR3, "KB_ROW3 PR3"),
+	PINCTRL_PIN(TEGRA_PIN_KB_ROW4_PR4, "KB_ROW4 PR4"),
+	PINCTRL_PIN(TEGRA_PIN_KB_ROW5_PR5, "KB_ROW5 PR5"),
+	PINCTRL_PIN(TEGRA_PIN_KB_ROW6_PR6, "KB_ROW6 PR6"),
+	PINCTRL_PIN(TEGRA_PIN_KB_ROW7_PR7, "KB_ROW7 PR7"),
+	PINCTRL_PIN(TEGRA_PIN_KB_ROW8_PS0, "KB_ROW8 PS0"),
+	PINCTRL_PIN(TEGRA_PIN_KB_ROW9_PS1, "KB_ROW9 PS1"),
+	PINCTRL_PIN(TEGRA_PIN_KB_ROW10_PS2, "KB_ROW10 PS2"),
+	PINCTRL_PIN(TEGRA_PIN_GEN2_I2C_SCL_PT5, "GEN2_I2C_SCL PT5"),
+	PINCTRL_PIN(TEGRA_PIN_GEN2_I2C_SDA_PT6, "GEN2_I2C_SDA PT6"),
+	PINCTRL_PIN(TEGRA_PIN_SDMMC4_CMD_PT7, "SDMMC4_CMD PT7"),
+	PINCTRL_PIN(TEGRA_PIN_PU0, "PU0"),
+	PINCTRL_PIN(TEGRA_PIN_PU1, "PU1"),
+	PINCTRL_PIN(TEGRA_PIN_PU2, "PU2"),
+	PINCTRL_PIN(TEGRA_PIN_PU3, "PU3"),
+	PINCTRL_PIN(TEGRA_PIN_PU4, "PU4"),
+	PINCTRL_PIN(TEGRA_PIN_PU5, "PU5"),
+	PINCTRL_PIN(TEGRA_PIN_PU6, "PU6"),
+	PINCTRL_PIN(TEGRA_PIN_PV0, "PV0"),
+	PINCTRL_PIN(TEGRA_PIN_PV1, "PV1"),
+	PINCTRL_PIN(TEGRA_PIN_SDMMC3_CD_N_PV2, "SDMMC3_CD_N PV2"),
+	PINCTRL_PIN(TEGRA_PIN_SDMMC1_WP_N_PV3, "SDMMC1_WP_N PV3"),
+	PINCTRL_PIN(TEGRA_PIN_DDC_SCL_PV4, "DDC_SCL PV4"),
+	PINCTRL_PIN(TEGRA_PIN_DDC_SDA_PV5, "DDC_SDA PV5"),
+	PINCTRL_PIN(TEGRA_PIN_GPIO_W2_AUD_PW2, "GPIO_W2_AUD PW2"),
+	PINCTRL_PIN(TEGRA_PIN_GPIO_W3_AUD_PW3, "GPIO_W3_AUD PW3"),
+	PINCTRL_PIN(TEGRA_PIN_CLK1_OUT_PW4, "CLK1_OUT PW4"),
+	PINCTRL_PIN(TEGRA_PIN_CLK2_OUT_PW5, "CLK2_OUT PW5"),
+	PINCTRL_PIN(TEGRA_PIN_UART3_TXD_PW6, "UART3_TXD PW6"),
+	PINCTRL_PIN(TEGRA_PIN_UART3_RXD_PW7, "UART3_RXD PW7"),
+	PINCTRL_PIN(TEGRA_PIN_DVFS_PWM_PX0, "DVFS_PWM PX0"),
+	PINCTRL_PIN(TEGRA_PIN_GPIO_X1_AUD_PX1, "GPIO_X1_AUD PX1"),
+	PINCTRL_PIN(TEGRA_PIN_DVFS_CLK_PX2, "DVFS_CLK PX2"),
+	PINCTRL_PIN(TEGRA_PIN_GPIO_X3_AUD_PX3, "GPIO_X3_AUD PX3"),
+	PINCTRL_PIN(TEGRA_PIN_GPIO_X4_AUD_PX4, "GPIO_X4_AUD PX4"),
+	PINCTRL_PIN(TEGRA_PIN_GPIO_X5_AUD_PX5, "GPIO_X5_AUD PX5"),
+	PINCTRL_PIN(TEGRA_PIN_GPIO_X6_AUD_PX6, "GPIO_X6_AUD PX6"),
+	PINCTRL_PIN(TEGRA_PIN_GPIO_X7_AUD_PX7, "GPIO_X7_AUD PX7"),
+	PINCTRL_PIN(TEGRA_PIN_ULPI_CLK_PY0, "ULPI_CLK PY0"),
+	PINCTRL_PIN(TEGRA_PIN_ULPI_DIR_PY1, "ULPI_DIR PY1"),
+	PINCTRL_PIN(TEGRA_PIN_ULPI_NXT_PY2, "ULPI_NXT PY2"),
+	PINCTRL_PIN(TEGRA_PIN_ULPI_STP_PY3, "ULPI_STP PY3"),
+	PINCTRL_PIN(TEGRA_PIN_SDMMC1_DAT3_PY4, "SDMMC1_DAT3 PY4"),
+	PINCTRL_PIN(TEGRA_PIN_SDMMC1_DAT2_PY5, "SDMMC1_DAT2 PY5"),
+	PINCTRL_PIN(TEGRA_PIN_SDMMC1_DAT1_PY6, "SDMMC1_DAT1 PY6"),
+	PINCTRL_PIN(TEGRA_PIN_SDMMC1_DAT0_PY7, "SDMMC1_DAT0 PY7"),
+	PINCTRL_PIN(TEGRA_PIN_SDMMC1_CLK_PZ0, "SDMMC1_CLK PZ0"),
+	PINCTRL_PIN(TEGRA_PIN_SDMMC1_CMD_PZ1, "SDMMC1_CMD PZ1"),
+	PINCTRL_PIN(TEGRA_PIN_SYS_CLK_REQ_PZ5, "SYS_CLK_REQ PZ5"),
+	PINCTRL_PIN(TEGRA_PIN_PWR_I2C_SCL_PZ6, "PWR_I2C_SCL PZ6"),
+	PINCTRL_PIN(TEGRA_PIN_PWR_I2C_SDA_PZ7, "PWR_I2C_SDA PZ7"),
+	PINCTRL_PIN(TEGRA_PIN_SDMMC4_DAT0_PAA0, "SDMMC4_DAT0 PAA0"),
+	PINCTRL_PIN(TEGRA_PIN_SDMMC4_DAT1_PAA1, "SDMMC4_DAT1 PAA1"),
+	PINCTRL_PIN(TEGRA_PIN_SDMMC4_DAT2_PAA2, "SDMMC4_DAT2 PAA2"),
+	PINCTRL_PIN(TEGRA_PIN_SDMMC4_DAT3_PAA3, "SDMMC4_DAT3 PAA3"),
+	PINCTRL_PIN(TEGRA_PIN_SDMMC4_DAT4_PAA4, "SDMMC4_DAT4 PAA4"),
+	PINCTRL_PIN(TEGRA_PIN_SDMMC4_DAT5_PAA5, "SDMMC4_DAT5 PAA5"),
+	PINCTRL_PIN(TEGRA_PIN_SDMMC4_DAT6_PAA6, "SDMMC4_DAT6 PAA6"),
+	PINCTRL_PIN(TEGRA_PIN_SDMMC4_DAT7_PAA7, "SDMMC4_DAT7 PAA7"),
+	PINCTRL_PIN(TEGRA_PIN_PBB0, "PBB0"),
+	PINCTRL_PIN(TEGRA_PIN_CAM_I2C_SCL_PBB1, "CAM_I2C_SCL PBB1"),
+	PINCTRL_PIN(TEGRA_PIN_CAM_I2C_SDA_PBB2, "CAM_I2C_SDA PBB2"),
+	PINCTRL_PIN(TEGRA_PIN_PBB3, "PBB3"),
+	PINCTRL_PIN(TEGRA_PIN_PBB4, "PBB4"),
+	PINCTRL_PIN(TEGRA_PIN_PBB5, "PBB5"),
+	PINCTRL_PIN(TEGRA_PIN_PBB6, "PBB6"),
+	PINCTRL_PIN(TEGRA_PIN_PBB7, "PBB7"),
+	PINCTRL_PIN(TEGRA_PIN_CAM_MCLK_PCC0, "CAM_MCLK PCC0"),
+	PINCTRL_PIN(TEGRA_PIN_PCC1, "PCC1"),
+	PINCTRL_PIN(TEGRA_PIN_PCC2, "PCC2"),
+	PINCTRL_PIN(TEGRA_PIN_SDMMC4_CLK_PCC4, "SDMMC4_CLK PCC4"),
+	PINCTRL_PIN(TEGRA_PIN_CLK2_REQ_PCC5, "CLK2_REQ PCC5"),
+	PINCTRL_PIN(TEGRA_PIN_CLK3_OUT_PEE0, "CLK3_OUT PEE0"),
+	PINCTRL_PIN(TEGRA_PIN_CLK3_REQ_PEE1, "CLK3_REQ PEE1"),
+	PINCTRL_PIN(TEGRA_PIN_CLK1_REQ_PEE2, "CLK1_REQ PEE2"),
+	PINCTRL_PIN(TEGRA_PIN_HDMI_CEC_PEE3, "HDMI_CEC PEE3"),
+	PINCTRL_PIN(TEGRA_PIN_SDMMC3_CLK_LB_OUT_PEE4, "SDMMC3_CLK_LB_OUT PEE4"),
+	PINCTRL_PIN(TEGRA_PIN_SDMMC3_CLK_LB_IN_PEE5, "SDMMC3_CLK_LB_IN PEE5"),
+	PINCTRL_PIN(TEGRA_PIN_CORE_PWR_REQ, "CORE_PWR_REQ"),
+	PINCTRL_PIN(TEGRA_PIN_CPU_PWR_REQ, "CPU_PWR_REQ"),
+	PINCTRL_PIN(TEGRA_PIN_OWR, "OWR"),
+	PINCTRL_PIN(TEGRA_PIN_PWR_INT_N, "PWR_INT_N"),
+	PINCTRL_PIN(TEGRA_PIN_RESET_OUT_N, "RESET_OUT_N"),
+};
+
+static const unsigned clk_32k_out_pa0_pins[] = {
+	TEGRA_PIN_CLK_32K_OUT_PA0,
+};
+
+static const unsigned uart3_cts_n_pa1_pins[] = {
+	TEGRA_PIN_UART3_CTS_N_PA1,
+};
+
+static const unsigned dap2_fs_pa2_pins[] = {
+	TEGRA_PIN_DAP2_FS_PA2,
+};
+
+static const unsigned dap2_sclk_pa3_pins[] = {
+	TEGRA_PIN_DAP2_SCLK_PA3,
+};
+
+static const unsigned dap2_din_pa4_pins[] = {
+	TEGRA_PIN_DAP2_DIN_PA4,
+};
+
+static const unsigned dap2_dout_pa5_pins[] = {
+	TEGRA_PIN_DAP2_DOUT_PA5,
+};
+
+static const unsigned sdmmc3_clk_pa6_pins[] = {
+	TEGRA_PIN_SDMMC3_CLK_PA6,
+};
+
+static const unsigned sdmmc3_cmd_pa7_pins[] = {
+	TEGRA_PIN_SDMMC3_CMD_PA7,
+};
+
+static const unsigned gmi_a17_pb0_pins[] = {
+	TEGRA_PIN_GMI_A17_PB0,
+};
+
+static const unsigned gmi_a18_pb1_pins[] = {
+	TEGRA_PIN_GMI_A18_PB1,
+};
+
+static const unsigned sdmmc3_dat3_pb4_pins[] = {
+	TEGRA_PIN_SDMMC3_DAT3_PB4,
+};
+
+static const unsigned sdmmc3_dat2_pb5_pins[] = {
+	TEGRA_PIN_SDMMC3_DAT2_PB5,
+};
+
+static const unsigned sdmmc3_dat1_pb6_pins[] = {
+	TEGRA_PIN_SDMMC3_DAT1_PB6,
+};
+
+static const unsigned sdmmc3_dat0_pb7_pins[] = {
+	TEGRA_PIN_SDMMC3_DAT0_PB7,
+};
+
+static const unsigned uart3_rts_n_pc0_pins[] = {
+	TEGRA_PIN_UART3_RTS_N_PC0,
+};
+
+static const unsigned uart2_txd_pc2_pins[] = {
+	TEGRA_PIN_UART2_TXD_PC2,
+};
+
+static const unsigned uart2_rxd_pc3_pins[] = {
+	TEGRA_PIN_UART2_RXD_PC3,
+};
+
+static const unsigned gen1_i2c_scl_pc4_pins[] = {
+	TEGRA_PIN_GEN1_I2C_SCL_PC4,
+};
+
+static const unsigned gen1_i2c_sda_pc5_pins[] = {
+	TEGRA_PIN_GEN1_I2C_SDA_PC5,
+};
+
+static const unsigned gmi_wp_n_pc7_pins[] = {
+	TEGRA_PIN_GMI_WP_N_PC7,
+};
+
+static const unsigned gmi_ad0_pg0_pins[] = {
+	TEGRA_PIN_GMI_AD0_PG0,
+};
+
+static const unsigned gmi_ad1_pg1_pins[] = {
+	TEGRA_PIN_GMI_AD1_PG1,
+};
+
+static const unsigned gmi_ad2_pg2_pins[] = {
+	TEGRA_PIN_GMI_AD2_PG2,
+};
+
+static const unsigned gmi_ad3_pg3_pins[] = {
+	TEGRA_PIN_GMI_AD3_PG3,
+};
+
+static const unsigned gmi_ad4_pg4_pins[] = {
+	TEGRA_PIN_GMI_AD4_PG4,
+};
+
+static const unsigned gmi_ad5_pg5_pins[] = {
+	TEGRA_PIN_GMI_AD5_PG5,
+};
+
+static const unsigned gmi_ad6_pg6_pins[] = {
+	TEGRA_PIN_GMI_AD6_PG6,
+};
+
+static const unsigned gmi_ad7_pg7_pins[] = {
+	TEGRA_PIN_GMI_AD7_PG7,
+};
+
+static const unsigned gmi_ad8_ph0_pins[] = {
+	TEGRA_PIN_GMI_AD8_PH0,
+};
+
+static const unsigned gmi_ad9_ph1_pins[] = {
+	TEGRA_PIN_GMI_AD9_PH1,
+};
+
+static const unsigned gmi_ad10_ph2_pins[] = {
+	TEGRA_PIN_GMI_AD10_PH2,
+};
+
+static const unsigned gmi_ad11_ph3_pins[] = {
+	TEGRA_PIN_GMI_AD11_PH3,
+};
+
+static const unsigned gmi_ad12_ph4_pins[] = {
+	TEGRA_PIN_GMI_AD12_PH4,
+};
+
+static const unsigned gmi_ad13_ph5_pins[] = {
+	TEGRA_PIN_GMI_AD13_PH5,
+};
+
+static const unsigned gmi_ad14_ph6_pins[] = {
+	TEGRA_PIN_GMI_AD14_PH6,
+};
+
+static const unsigned gmi_ad15_ph7_pins[] = {
+	TEGRA_PIN_GMI_AD15_PH7,
+};
+
+static const unsigned gmi_wr_n_pi0_pins[] = {
+	TEGRA_PIN_GMI_WR_N_PI0,
+};
+
+static const unsigned gmi_oe_n_pi1_pins[] = {
+	TEGRA_PIN_GMI_OE_N_PI1,
+};
+
+static const unsigned gmi_cs6_n_pi3_pins[] = {
+	TEGRA_PIN_GMI_CS6_N_PI3,
+};
+
+static const unsigned gmi_rst_n_pi4_pins[] = {
+	TEGRA_PIN_GMI_RST_N_PI4,
+};
+
+static const unsigned gmi_iordy_pi5_pins[] = {
+	TEGRA_PIN_GMI_IORDY_PI5,
+};
+
+static const unsigned gmi_cs7_n_pi6_pins[] = {
+	TEGRA_PIN_GMI_CS7_N_PI6,
+};
+
+static const unsigned gmi_wait_pi7_pins[] = {
+	TEGRA_PIN_GMI_WAIT_PI7,
+};
+
+static const unsigned gmi_cs0_n_pj0_pins[] = {
+	TEGRA_PIN_GMI_CS0_N_PJ0,
+};
+
+static const unsigned gmi_cs1_n_pj2_pins[] = {
+	TEGRA_PIN_GMI_CS1_N_PJ2,
+};
+
+static const unsigned gmi_dqs_p_pj3_pins[] = {
+	TEGRA_PIN_GMI_DQS_P_PJ3,
+};
+
+static const unsigned uart2_cts_n_pj5_pins[] = {
+	TEGRA_PIN_UART2_CTS_N_PJ5,
+};
+
+static const unsigned uart2_rts_n_pj6_pins[] = {
+	TEGRA_PIN_UART2_RTS_N_PJ6,
+};
+
+static const unsigned gmi_a16_pj7_pins[] = {
+	TEGRA_PIN_GMI_A16_PJ7,
+};
+
+static const unsigned gmi_adv_n_pk0_pins[] = {
+	TEGRA_PIN_GMI_ADV_N_PK0,
+};
+
+static const unsigned gmi_clk_pk1_pins[] = {
+	TEGRA_PIN_GMI_CLK_PK1,
+};
+
+static const unsigned gmi_cs4_n_pk2_pins[] = {
+	TEGRA_PIN_GMI_CS4_N_PK2,
+};
+
+static const unsigned gmi_cs2_n_pk3_pins[] = {
+	TEGRA_PIN_GMI_CS2_N_PK3,
+};
+
+static const unsigned gmi_cs3_n_pk4_pins[] = {
+	TEGRA_PIN_GMI_CS3_N_PK4,
+};
+
+static const unsigned spdif_out_pk5_pins[] = {
+	TEGRA_PIN_SPDIF_OUT_PK5,
+};
+
+static const unsigned spdif_in_pk6_pins[] = {
+	TEGRA_PIN_SPDIF_IN_PK6,
+};
+
+static const unsigned gmi_a19_pk7_pins[] = {
+	TEGRA_PIN_GMI_A19_PK7,
+};
+
+static const unsigned dap1_fs_pn0_pins[] = {
+	TEGRA_PIN_DAP1_FS_PN0,
+};
+
+static const unsigned dap1_din_pn1_pins[] = {
+	TEGRA_PIN_DAP1_DIN_PN1,
+};
+
+static const unsigned dap1_dout_pn2_pins[] = {
+	TEGRA_PIN_DAP1_DOUT_PN2,
+};
+
+static const unsigned dap1_sclk_pn3_pins[] = {
+	TEGRA_PIN_DAP1_SCLK_PN3,
+};
+
+static const unsigned usb_vbus_en0_pn4_pins[] = {
+	TEGRA_PIN_USB_VBUS_EN0_PN4,
+};
+
+static const unsigned usb_vbus_en1_pn5_pins[] = {
+	TEGRA_PIN_USB_VBUS_EN1_PN5,
+};
+
+static const unsigned hdmi_int_pn7_pins[] = {
+	TEGRA_PIN_HDMI_INT_PN7,
+};
+
+static const unsigned ulpi_data7_po0_pins[] = {
+	TEGRA_PIN_ULPI_DATA7_PO0,
+};
+
+static const unsigned ulpi_data0_po1_pins[] = {
+	TEGRA_PIN_ULPI_DATA0_PO1,
+};
+
+static const unsigned ulpi_data1_po2_pins[] = {
+	TEGRA_PIN_ULPI_DATA1_PO2,
+};
+
+static const unsigned ulpi_data2_po3_pins[] = {
+	TEGRA_PIN_ULPI_DATA2_PO3,
+};
+
+static const unsigned ulpi_data3_po4_pins[] = {
+	TEGRA_PIN_ULPI_DATA3_PO4,
+};
+
+static const unsigned ulpi_data4_po5_pins[] = {
+	TEGRA_PIN_ULPI_DATA4_PO5,
+};
+
+static const unsigned ulpi_data5_po6_pins[] = {
+	TEGRA_PIN_ULPI_DATA5_PO6,
+};
+
+static const unsigned ulpi_data6_po7_pins[] = {
+	TEGRA_PIN_ULPI_DATA6_PO7,
+};
+
+static const unsigned dap3_fs_pp0_pins[] = {
+	TEGRA_PIN_DAP3_FS_PP0,
+};
+
+static const unsigned dap3_din_pp1_pins[] = {
+	TEGRA_PIN_DAP3_DIN_PP1,
+};
+
+static const unsigned dap3_dout_pp2_pins[] = {
+	TEGRA_PIN_DAP3_DOUT_PP2,
+};
+
+static const unsigned dap3_sclk_pp3_pins[] = {
+	TEGRA_PIN_DAP3_SCLK_PP3,
+};
+
+static const unsigned dap4_fs_pp4_pins[] = {
+	TEGRA_PIN_DAP4_FS_PP4,
+};
+
+static const unsigned dap4_din_pp5_pins[] = {
+	TEGRA_PIN_DAP4_DIN_PP5,
+};
+
+static const unsigned dap4_dout_pp6_pins[] = {
+	TEGRA_PIN_DAP4_DOUT_PP6,
+};
+
+static const unsigned dap4_sclk_pp7_pins[] = {
+	TEGRA_PIN_DAP4_SCLK_PP7,
+};
+
+static const unsigned kb_col0_pq0_pins[] = {
+	TEGRA_PIN_KB_COL0_PQ0,
+};
+
+static const unsigned kb_col1_pq1_pins[] = {
+	TEGRA_PIN_KB_COL1_PQ1,
+};
+
+static const unsigned kb_col2_pq2_pins[] = {
+	TEGRA_PIN_KB_COL2_PQ2,
+};
+
+static const unsigned kb_col3_pq3_pins[] = {
+	TEGRA_PIN_KB_COL3_PQ3,
+};
+
+static const unsigned kb_col4_pq4_pins[] = {
+	TEGRA_PIN_KB_COL4_PQ4,
+};
+
+static const unsigned kb_col5_pq5_pins[] = {
+	TEGRA_PIN_KB_COL5_PQ5,
+};
+
+static const unsigned kb_col6_pq6_pins[] = {
+	TEGRA_PIN_KB_COL6_PQ6,
+};
+
+static const unsigned kb_col7_pq7_pins[] = {
+	TEGRA_PIN_KB_COL7_PQ7,
+};
+
+static const unsigned kb_row0_pr0_pins[] = {
+	TEGRA_PIN_KB_ROW0_PR0,
+};
+
+static const unsigned kb_row1_pr1_pins[] = {
+	TEGRA_PIN_KB_ROW1_PR1,
+};
+
+static const unsigned kb_row2_pr2_pins[] = {
+	TEGRA_PIN_KB_ROW2_PR2,
+};
+
+static const unsigned kb_row3_pr3_pins[] = {
+	TEGRA_PIN_KB_ROW3_PR3,
+};
+
+static const unsigned kb_row4_pr4_pins[] = {
+	TEGRA_PIN_KB_ROW4_PR4,
+};
+
+static const unsigned kb_row5_pr5_pins[] = {
+	TEGRA_PIN_KB_ROW5_PR5,
+};
+
+static const unsigned kb_row6_pr6_pins[] = {
+	TEGRA_PIN_KB_ROW6_PR6,
+};
+
+static const unsigned kb_row7_pr7_pins[] = {
+	TEGRA_PIN_KB_ROW7_PR7,
+};
+
+static const unsigned kb_row8_ps0_pins[] = {
+	TEGRA_PIN_KB_ROW8_PS0,
+};
+
+static const unsigned kb_row9_ps1_pins[] = {
+	TEGRA_PIN_KB_ROW9_PS1,
+};
+
+static const unsigned kb_row10_ps2_pins[] = {
+	TEGRA_PIN_KB_ROW10_PS2,
+};
+
+static const unsigned gen2_i2c_scl_pt5_pins[] = {
+	TEGRA_PIN_GEN2_I2C_SCL_PT5,
+};
+
+static const unsigned gen2_i2c_sda_pt6_pins[] = {
+	TEGRA_PIN_GEN2_I2C_SDA_PT6,
+};
+
+static const unsigned sdmmc4_cmd_pt7_pins[] = {
+	TEGRA_PIN_SDMMC4_CMD_PT7,
+};
+
+static const unsigned pu0_pins[] = {
+	TEGRA_PIN_PU0,
+};
+
+static const unsigned pu1_pins[] = {
+	TEGRA_PIN_PU1,
+};
+
+static const unsigned pu2_pins[] = {
+	TEGRA_PIN_PU2,
+};
+
+static const unsigned pu3_pins[] = {
+	TEGRA_PIN_PU3,
+};
+
+static const unsigned pu4_pins[] = {
+	TEGRA_PIN_PU4,
+};
+
+static const unsigned pu5_pins[] = {
+	TEGRA_PIN_PU5,
+};
+
+static const unsigned pu6_pins[] = {
+	TEGRA_PIN_PU6,
+};
+
+static const unsigned pv0_pins[] = {
+	TEGRA_PIN_PV0,
+};
+
+static const unsigned pv1_pins[] = {
+	TEGRA_PIN_PV1,
+};
+
+static const unsigned sdmmc3_cd_n_pv2_pins[] = {
+	TEGRA_PIN_SDMMC3_CD_N_PV2,
+};
+
+static const unsigned sdmmc1_wp_n_pv3_pins[] = {
+	TEGRA_PIN_SDMMC1_WP_N_PV3,
+};
+
+static const unsigned ddc_scl_pv4_pins[] = {
+	TEGRA_PIN_DDC_SCL_PV4,
+};
+
+static const unsigned ddc_sda_pv5_pins[] = {
+	TEGRA_PIN_DDC_SDA_PV5,
+};
+
+static const unsigned gpio_w2_aud_pw2_pins[] = {
+	TEGRA_PIN_GPIO_W2_AUD_PW2,
+};
+
+static const unsigned gpio_w3_aud_pw3_pins[] = {
+	TEGRA_PIN_GPIO_W3_AUD_PW3,
+};
+
+static const unsigned clk1_out_pw4_pins[] = {
+	TEGRA_PIN_CLK1_OUT_PW4,
+};
+
+static const unsigned clk2_out_pw5_pins[] = {
+	TEGRA_PIN_CLK2_OUT_PW5,
+};
+
+static const unsigned uart3_txd_pw6_pins[] = {
+	TEGRA_PIN_UART3_TXD_PW6,
+};
+
+static const unsigned uart3_rxd_pw7_pins[] = {
+	TEGRA_PIN_UART3_RXD_PW7,
+};
+
+static const unsigned dvfs_pwm_px0_pins[] = {
+	TEGRA_PIN_DVFS_PWM_PX0,
+};
+
+static const unsigned gpio_x1_aud_px1_pins[] = {
+	TEGRA_PIN_GPIO_X1_AUD_PX1,
+};
+
+static const unsigned dvfs_clk_px2_pins[] = {
+	TEGRA_PIN_DVFS_CLK_PX2,
+};
+
+static const unsigned gpio_x3_aud_px3_pins[] = {
+	TEGRA_PIN_GPIO_X3_AUD_PX3,
+};
+
+static const unsigned gpio_x4_aud_px4_pins[] = {
+	TEGRA_PIN_GPIO_X4_AUD_PX4,
+};
+
+static const unsigned gpio_x5_aud_px5_pins[] = {
+	TEGRA_PIN_GPIO_X5_AUD_PX5,
+};
+
+static const unsigned gpio_x6_aud_px6_pins[] = {
+	TEGRA_PIN_GPIO_X6_AUD_PX6,
+};
+
+static const unsigned gpio_x7_aud_px7_pins[] = {
+	TEGRA_PIN_GPIO_X7_AUD_PX7,
+};
+
+static const unsigned ulpi_clk_py0_pins[] = {
+	TEGRA_PIN_ULPI_CLK_PY0,
+};
+
+static const unsigned ulpi_dir_py1_pins[] = {
+	TEGRA_PIN_ULPI_DIR_PY1,
+};
+
+static const unsigned ulpi_nxt_py2_pins[] = {
+	TEGRA_PIN_ULPI_NXT_PY2,
+};
+
+static const unsigned ulpi_stp_py3_pins[] = {
+	TEGRA_PIN_ULPI_STP_PY3,
+};
+
+static const unsigned sdmmc1_dat3_py4_pins[] = {
+	TEGRA_PIN_SDMMC1_DAT3_PY4,
+};
+
+static const unsigned sdmmc1_dat2_py5_pins[] = {
+	TEGRA_PIN_SDMMC1_DAT2_PY5,
+};
+
+static const unsigned sdmmc1_dat1_py6_pins[] = {
+	TEGRA_PIN_SDMMC1_DAT1_PY6,
+};
+
+static const unsigned sdmmc1_dat0_py7_pins[] = {
+	TEGRA_PIN_SDMMC1_DAT0_PY7,
+};
+
+static const unsigned sdmmc1_clk_pz0_pins[] = {
+	TEGRA_PIN_SDMMC1_CLK_PZ0,
+};
+
+static const unsigned sdmmc1_cmd_pz1_pins[] = {
+	TEGRA_PIN_SDMMC1_CMD_PZ1,
+};
+
+static const unsigned sys_clk_req_pz5_pins[] = {
+	TEGRA_PIN_SYS_CLK_REQ_PZ5,
+};
+
+static const unsigned pwr_i2c_scl_pz6_pins[] = {
+	TEGRA_PIN_PWR_I2C_SCL_PZ6,
+};
+
+static const unsigned pwr_i2c_sda_pz7_pins[] = {
+	TEGRA_PIN_PWR_I2C_SDA_PZ7,
+};
+
+static const unsigned sdmmc4_dat0_paa0_pins[] = {
+	TEGRA_PIN_SDMMC4_DAT0_PAA0,
+};
+
+static const unsigned sdmmc4_dat1_paa1_pins[] = {
+	TEGRA_PIN_SDMMC4_DAT1_PAA1,
+};
+
+static const unsigned sdmmc4_dat2_paa2_pins[] = {
+	TEGRA_PIN_SDMMC4_DAT2_PAA2,
+};
+
+static const unsigned sdmmc4_dat3_paa3_pins[] = {
+	TEGRA_PIN_SDMMC4_DAT3_PAA3,
+};
+
+static const unsigned sdmmc4_dat4_paa4_pins[] = {
+	TEGRA_PIN_SDMMC4_DAT4_PAA4,
+};
+
+static const unsigned sdmmc4_dat5_paa5_pins[] = {
+	TEGRA_PIN_SDMMC4_DAT5_PAA5,
+};
+
+static const unsigned sdmmc4_dat6_paa6_pins[] = {
+	TEGRA_PIN_SDMMC4_DAT6_PAA6,
+};
+
+static const unsigned sdmmc4_dat7_paa7_pins[] = {
+	TEGRA_PIN_SDMMC4_DAT7_PAA7,
+};
+
+static const unsigned pbb0_pins[] = {
+	TEGRA_PIN_PBB0,
+};
+
+static const unsigned cam_i2c_scl_pbb1_pins[] = {
+	TEGRA_PIN_CAM_I2C_SCL_PBB1,
+};
+
+static const unsigned cam_i2c_sda_pbb2_pins[] = {
+	TEGRA_PIN_CAM_I2C_SDA_PBB2,
+};
+
+static const unsigned pbb3_pins[] = {
+	TEGRA_PIN_PBB3,
+};
+
+static const unsigned pbb4_pins[] = {
+	TEGRA_PIN_PBB4,
+};
+
+static const unsigned pbb5_pins[] = {
+	TEGRA_PIN_PBB5,
+};
+
+static const unsigned pbb6_pins[] = {
+	TEGRA_PIN_PBB6,
+};
+
+static const unsigned pbb7_pins[] = {
+	TEGRA_PIN_PBB7,
+};
+
+static const unsigned cam_mclk_pcc0_pins[] = {
+	TEGRA_PIN_CAM_MCLK_PCC0,
+};
+
+static const unsigned pcc1_pins[] = {
+	TEGRA_PIN_PCC1,
+};
+
+static const unsigned pcc2_pins[] = {
+	TEGRA_PIN_PCC2,
+};
+
+static const unsigned sdmmc4_clk_pcc4_pins[] = {
+	TEGRA_PIN_SDMMC4_CLK_PCC4,
+};
+
+static const unsigned clk2_req_pcc5_pins[] = {
+	TEGRA_PIN_CLK2_REQ_PCC5,
+};
+
+static const unsigned clk3_out_pee0_pins[] = {
+	TEGRA_PIN_CLK3_OUT_PEE0,
+};
+
+static const unsigned clk3_req_pee1_pins[] = {
+	TEGRA_PIN_CLK3_REQ_PEE1,
+};
+
+static const unsigned clk1_req_pee2_pins[] = {
+	TEGRA_PIN_CLK1_REQ_PEE2,
+};
+
+static const unsigned hdmi_cec_pee3_pins[] = {
+	TEGRA_PIN_HDMI_CEC_PEE3,
+};
+
+static const unsigned sdmmc3_clk_lb_out_pee4_pins[] = {
+	TEGRA_PIN_SDMMC3_CLK_LB_OUT_PEE4,
+};
+
+static const unsigned sdmmc3_clk_lb_in_pee5_pins[] = {
+	TEGRA_PIN_SDMMC3_CLK_LB_IN_PEE5,
+};
+
+static const unsigned core_pwr_req_pins[] = {
+	TEGRA_PIN_CORE_PWR_REQ,
+};
+
+static const unsigned cpu_pwr_req_pins[] = {
+	TEGRA_PIN_CPU_PWR_REQ,
+};
+
+static const unsigned owr_pins[] = {
+	TEGRA_PIN_OWR,
+};
+
+static const unsigned pwr_int_n_pins[] = {
+	TEGRA_PIN_PWR_INT_N,
+};
+
+static const unsigned reset_out_n_pins[] = {
+	TEGRA_PIN_RESET_OUT_N,
+};
+
+static const unsigned drive_ao1_pins[] = {
+	TEGRA_PIN_KB_ROW0_PR0,
+	TEGRA_PIN_KB_ROW1_PR1,
+	TEGRA_PIN_KB_ROW2_PR2,
+	TEGRA_PIN_KB_ROW3_PR3,
+	TEGRA_PIN_KB_ROW4_PR4,
+	TEGRA_PIN_KB_ROW5_PR5,
+	TEGRA_PIN_KB_ROW6_PR6,
+	TEGRA_PIN_KB_ROW7_PR7,
+	TEGRA_PIN_PWR_I2C_SCL_PZ6,
+	TEGRA_PIN_PWR_I2C_SDA_PZ7,
+};
+
+static const unsigned drive_ao2_pins[] = {
+	TEGRA_PIN_CLK_32K_OUT_PA0,
+	TEGRA_PIN_KB_COL0_PQ0,
+	TEGRA_PIN_KB_COL1_PQ1,
+	TEGRA_PIN_KB_COL2_PQ2,
+	TEGRA_PIN_KB_COL3_PQ3,
+	TEGRA_PIN_KB_COL4_PQ4,
+	TEGRA_PIN_KB_COL5_PQ5,
+	TEGRA_PIN_KB_COL6_PQ6,
+	TEGRA_PIN_KB_COL7_PQ7,
+	TEGRA_PIN_KB_ROW8_PS0,
+	TEGRA_PIN_KB_ROW9_PS1,
+	TEGRA_PIN_KB_ROW10_PS2,
+	TEGRA_PIN_SYS_CLK_REQ_PZ5,
+	TEGRA_PIN_CORE_PWR_REQ,
+	TEGRA_PIN_CPU_PWR_REQ,
+	TEGRA_PIN_RESET_OUT_N,
+};
+
+static const unsigned drive_at1_pins[] = {
+	TEGRA_PIN_GMI_AD8_PH0,
+	TEGRA_PIN_GMI_AD9_PH1,
+	TEGRA_PIN_GMI_AD10_PH2,
+	TEGRA_PIN_GMI_AD11_PH3,
+	TEGRA_PIN_GMI_AD12_PH4,
+	TEGRA_PIN_GMI_AD13_PH5,
+	TEGRA_PIN_GMI_AD14_PH6,
+	TEGRA_PIN_GMI_AD15_PH7,
+
+	TEGRA_PIN_GMI_IORDY_PI5,
+	TEGRA_PIN_GMI_CS7_N_PI6,
+};
+
+static const unsigned drive_at2_pins[] = {
+	TEGRA_PIN_GMI_AD0_PG0,
+	TEGRA_PIN_GMI_AD1_PG1,
+	TEGRA_PIN_GMI_AD2_PG2,
+	TEGRA_PIN_GMI_AD3_PG3,
+	TEGRA_PIN_GMI_AD4_PG4,
+	TEGRA_PIN_GMI_AD5_PG5,
+	TEGRA_PIN_GMI_AD6_PG6,
+	TEGRA_PIN_GMI_AD7_PG7,
+
+	TEGRA_PIN_GMI_WR_N_PI0,
+	TEGRA_PIN_GMI_OE_N_PI1,
+	TEGRA_PIN_GMI_CS6_N_PI3,
+	TEGRA_PIN_GMI_RST_N_PI4,
+	TEGRA_PIN_GMI_WAIT_PI7,
+
+	TEGRA_PIN_GMI_DQS_P_PJ3,
+
+	TEGRA_PIN_GMI_ADV_N_PK0,
+	TEGRA_PIN_GMI_CLK_PK1,
+	TEGRA_PIN_GMI_CS4_N_PK2,
+	TEGRA_PIN_GMI_CS2_N_PK3,
+	TEGRA_PIN_GMI_CS3_N_PK4,
+};
+
+static const unsigned drive_at3_pins[] = {
+	TEGRA_PIN_GMI_WP_N_PC7,
+	TEGRA_PIN_GMI_CS0_N_PJ0,
+};
+
+static const unsigned drive_at4_pins[] = {
+	TEGRA_PIN_GMI_A17_PB0,
+	TEGRA_PIN_GMI_A18_PB1,
+	TEGRA_PIN_GMI_CS1_N_PJ2,
+	TEGRA_PIN_GMI_A16_PJ7,
+	TEGRA_PIN_GMI_A19_PK7,
+};
+
+static const unsigned drive_at5_pins[] = {
+	TEGRA_PIN_GEN2_I2C_SCL_PT5,
+	TEGRA_PIN_GEN2_I2C_SDA_PT6,
+};
+
+static const unsigned drive_cdev1_pins[] = {
+	TEGRA_PIN_CLK1_OUT_PW4,
+	TEGRA_PIN_CLK1_REQ_PEE2,
+};
+
+static const unsigned drive_cdev2_pins[] = {
+	TEGRA_PIN_CLK2_OUT_PW5,
+	TEGRA_PIN_CLK2_REQ_PCC5,
+	TEGRA_PIN_SDMMC1_WP_N_PV3,
+};
+
+static const unsigned drive_dap1_pins[] = {
+	TEGRA_PIN_DAP1_FS_PN0,
+	TEGRA_PIN_DAP1_DIN_PN1,
+	TEGRA_PIN_DAP1_DOUT_PN2,
+	TEGRA_PIN_DAP1_SCLK_PN3,
+};
+
+static const unsigned drive_dap2_pins[] = {
+	TEGRA_PIN_DAP2_FS_PA2,
+	TEGRA_PIN_DAP2_SCLK_PA3,
+	TEGRA_PIN_DAP2_DIN_PA4,
+	TEGRA_PIN_DAP2_DOUT_PA5,
+};
+
+static const unsigned drive_dap3_pins[] = {
+	TEGRA_PIN_DAP3_FS_PP0,
+	TEGRA_PIN_DAP3_DIN_PP1,
+	TEGRA_PIN_DAP3_DOUT_PP2,
+	TEGRA_PIN_DAP3_SCLK_PP3,
+};
+
+static const unsigned drive_dap4_pins[] = {
+	TEGRA_PIN_DAP4_FS_PP4,
+	TEGRA_PIN_DAP4_DIN_PP5,
+	TEGRA_PIN_DAP4_DOUT_PP6,
+	TEGRA_PIN_DAP4_SCLK_PP7,
+};
+
+static const unsigned drive_dbg_pins[] = {
+	TEGRA_PIN_GEN1_I2C_SCL_PC4,
+	TEGRA_PIN_GEN1_I2C_SDA_PC5,
+	TEGRA_PIN_PU0,
+	TEGRA_PIN_PU1,
+	TEGRA_PIN_PU2,
+	TEGRA_PIN_PU3,
+	TEGRA_PIN_PU4,
+	TEGRA_PIN_PU5,
+	TEGRA_PIN_PU6,
+};
+
+static const unsigned drive_sdio3_pins[] = {
+	TEGRA_PIN_SDMMC3_CLK_PA6,
+	TEGRA_PIN_SDMMC3_CMD_PA7,
+	TEGRA_PIN_SDMMC3_DAT3_PB4,
+	TEGRA_PIN_SDMMC3_DAT2_PB5,
+	TEGRA_PIN_SDMMC3_DAT1_PB6,
+	TEGRA_PIN_SDMMC3_DAT0_PB7,
+	TEGRA_PIN_SDMMC3_CLK_LB_OUT_PEE4,
+	TEGRA_PIN_SDMMC3_CLK_LB_IN_PEE5,
+};
+
+static const unsigned drive_spi_pins[] = {
+	TEGRA_PIN_DVFS_PWM_PX0,
+	TEGRA_PIN_GPIO_X1_AUD_PX1,
+	TEGRA_PIN_DVFS_CLK_PX2,
+	TEGRA_PIN_GPIO_X3_AUD_PX3,
+	TEGRA_PIN_GPIO_X4_AUD_PX4,
+	TEGRA_PIN_GPIO_X5_AUD_PX5,
+	TEGRA_PIN_GPIO_X6_AUD_PX6,
+	TEGRA_PIN_GPIO_X7_AUD_PX7,
+	TEGRA_PIN_GPIO_W2_AUD_PW2,
+	TEGRA_PIN_GPIO_W3_AUD_PW3,
+};
+
+static const unsigned drive_uaa_pins[] = {
+	TEGRA_PIN_ULPI_DATA0_PO1,
+	TEGRA_PIN_ULPI_DATA1_PO2,
+	TEGRA_PIN_ULPI_DATA2_PO3,
+	TEGRA_PIN_ULPI_DATA3_PO4,
+};
+
+static const unsigned drive_uab_pins[] = {
+	TEGRA_PIN_ULPI_DATA7_PO0,
+	TEGRA_PIN_ULPI_DATA4_PO5,
+	TEGRA_PIN_ULPI_DATA5_PO6,
+	TEGRA_PIN_ULPI_DATA6_PO7,
+	TEGRA_PIN_PV0,
+	TEGRA_PIN_PV1,
+};
+
+static const unsigned drive_uart2_pins[] = {
+	TEGRA_PIN_UART2_TXD_PC2,
+	TEGRA_PIN_UART2_RXD_PC3,
+	TEGRA_PIN_UART2_CTS_N_PJ5,
+	TEGRA_PIN_UART2_RTS_N_PJ6,
+};
+
+static const unsigned drive_uart3_pins[] = {
+	TEGRA_PIN_UART3_CTS_N_PA1,
+	TEGRA_PIN_UART3_RTS_N_PC0,
+	TEGRA_PIN_UART3_TXD_PW6,
+	TEGRA_PIN_UART3_RXD_PW7,
+};
+
+static const unsigned drive_sdio1_pins[] = {
+	TEGRA_PIN_SDMMC1_DAT3_PY4,
+	TEGRA_PIN_SDMMC1_DAT2_PY5,
+	TEGRA_PIN_SDMMC1_DAT1_PY6,
+	TEGRA_PIN_SDMMC1_DAT0_PY7,
+	TEGRA_PIN_SDMMC1_CLK_PZ0,
+	TEGRA_PIN_SDMMC1_CMD_PZ1,
+};
+
+static const unsigned drive_ddc_pins[] = {
+	TEGRA_PIN_DDC_SCL_PV4,
+	TEGRA_PIN_DDC_SDA_PV5,
+};
+
+static const unsigned drive_gma_pins[] = {
+	TEGRA_PIN_SDMMC4_CLK_PCC4,
+	TEGRA_PIN_SDMMC4_CMD_PT7,
+	TEGRA_PIN_SDMMC4_DAT0_PAA0,
+	TEGRA_PIN_SDMMC4_DAT1_PAA1,
+	TEGRA_PIN_SDMMC4_DAT2_PAA2,
+	TEGRA_PIN_SDMMC4_DAT3_PAA3,
+	TEGRA_PIN_SDMMC4_DAT4_PAA4,
+	TEGRA_PIN_SDMMC4_DAT5_PAA5,
+	TEGRA_PIN_SDMMC4_DAT6_PAA6,
+	TEGRA_PIN_SDMMC4_DAT7_PAA7,
+};
+
+static const unsigned drive_gme_pins[] = {
+	TEGRA_PIN_PBB0,
+	TEGRA_PIN_CAM_I2C_SCL_PBB1,
+	TEGRA_PIN_CAM_I2C_SDA_PBB2,
+	TEGRA_PIN_PBB3,
+	TEGRA_PIN_PCC2,
+};
+
+static const unsigned drive_gmf_pins[] = {
+	TEGRA_PIN_PBB4,
+	TEGRA_PIN_PBB5,
+	TEGRA_PIN_PBB6,
+	TEGRA_PIN_PBB7,
+};
+
+static const unsigned drive_gmg_pins[] = {
+	TEGRA_PIN_CAM_MCLK_PCC0,
+};
+
+static const unsigned drive_gmh_pins[] = {
+	TEGRA_PIN_PCC1,
+};
+
+static const unsigned drive_owr_pins[] = {
+	TEGRA_PIN_SDMMC3_CD_N_PV2,
+};
+
+static const unsigned drive_uda_pins[] = {
+	TEGRA_PIN_ULPI_CLK_PY0,
+	TEGRA_PIN_ULPI_DIR_PY1,
+	TEGRA_PIN_ULPI_NXT_PY2,
+	TEGRA_PIN_ULPI_STP_PY3,
+};
+
+static const unsigned drive_dev3_pins[] = {
+	TEGRA_PIN_CLK3_OUT_PEE0,
+	TEGRA_PIN_CLK3_REQ_PEE1,
+};
+
+enum tegra_mux {
+	TEGRA_MUX_BLINK,
+	TEGRA_MUX_CEC,
+	TEGRA_MUX_CLDVFS,
+	TEGRA_MUX_CLK12,
+	TEGRA_MUX_CPU,
+	TEGRA_MUX_DAP,
+	TEGRA_MUX_DAP1,
+	TEGRA_MUX_DAP2,
+	TEGRA_MUX_DEV3,
+	TEGRA_MUX_DISPLAYA,
+	TEGRA_MUX_DISPLAYA_ALT,
+	TEGRA_MUX_DISPLAYB,
+	TEGRA_MUX_DTV,
+	TEGRA_MUX_EMC_DLL,
+	TEGRA_MUX_EXTPERIPH1,
+	TEGRA_MUX_EXTPERIPH2,
+	TEGRA_MUX_EXTPERIPH3,
+	TEGRA_MUX_GMI,
+	TEGRA_MUX_GMI_ALT,
+	TEGRA_MUX_HDA,
+	TEGRA_MUX_HSI,
+	TEGRA_MUX_I2C1,
+	TEGRA_MUX_I2C2,
+	TEGRA_MUX_I2C3,
+	TEGRA_MUX_I2C4,
+	TEGRA_MUX_I2CPWR,
+	TEGRA_MUX_I2S0,
+	TEGRA_MUX_I2S1,
+	TEGRA_MUX_I2S2,
+	TEGRA_MUX_I2S3,
+	TEGRA_MUX_I2S4,
+	TEGRA_MUX_IRDA,
+	TEGRA_MUX_KBC,
+	TEGRA_MUX_NAND,
+	TEGRA_MUX_NAND_ALT,
+	TEGRA_MUX_OWR,
+	TEGRA_MUX_PMI,
+	TEGRA_MUX_PWM0,
+	TEGRA_MUX_PWM1,
+	TEGRA_MUX_PWM2,
+	TEGRA_MUX_PWM3,
+	TEGRA_MUX_PWRON,
+	TEGRA_MUX_RESET_OUT_N,
+	TEGRA_MUX_RSVD1,
+	TEGRA_MUX_RSVD2,
+	TEGRA_MUX_RSVD3,
+	TEGRA_MUX_RSVD4,
+	TEGRA_MUX_SDMMC1,
+	TEGRA_MUX_SDMMC2,
+	TEGRA_MUX_SDMMC3,
+	TEGRA_MUX_SDMMC4,
+	TEGRA_MUX_SOC,
+	TEGRA_MUX_SPDIF,
+	TEGRA_MUX_SPI1,
+	TEGRA_MUX_SPI2,
+	TEGRA_MUX_SPI3,
+	TEGRA_MUX_SPI4,
+	TEGRA_MUX_SPI5,
+	TEGRA_MUX_SPI6,
+	TEGRA_MUX_SYSCLK,
+	TEGRA_MUX_TRACE,
+	TEGRA_MUX_UARTA,
+	TEGRA_MUX_UARTB,
+	TEGRA_MUX_UARTC,
+	TEGRA_MUX_UARTD,
+	TEGRA_MUX_ULPI,
+	TEGRA_MUX_USB,
+	TEGRA_MUX_VGP1,
+	TEGRA_MUX_VGP2,
+	TEGRA_MUX_VGP3,
+	TEGRA_MUX_VGP4,
+	TEGRA_MUX_VGP5,
+	TEGRA_MUX_VGP6,
+	TEGRA_MUX_VI,
+	TEGRA_MUX_VI_ALT1,
+	TEGRA_MUX_VI_ALT3,
+};
+
+static const char * const blink_groups[] = {
+	"clk_32k_out_pa0",
+};
+
+static const char * const cec_groups[] = {
+	"hdmi_cec_pee3",
+};
+
+static const char * const cldvfs_groups[] = {
+	"gmi_ad9_ph1",
+	"gmi_ad10_ph2",
+	"kb_row7_pr7",
+	"kb_row8_ps0",
+	"dvfs_pwm_px0",
+	"dvfs_clk_px2",
+};
+
+static const char * const clk12_groups[] = {
+	"sdmmc1_wp_n_pv3",
+	"sdmmc1_clk_pz0",
+};
+
+static const char * const cpu_groups[] = {
+	"cpu_pwr_req",
+};
+
+static const char * const dap_groups[] = {
+	"clk1_req_pee2",
+	"clk2_req_pcc5",
+};
+
+static const char * const dap1_groups[] = {
+	"clk1_req_pee2",
+};
+
+static const char * const dap2_groups[] = {
+	"clk1_out_pw4",
+	"gpio_x4_aud_px4",
+};
+
+static const char * const dev3_groups[] = {
+	"clk3_req_pee1",
+};
+
+static const char * const displaya_groups[] = {
+	"dap3_fs_pp0",
+	"dap3_din_pp1",
+	"dap3_dout_pp2",
+	"dap3_sclk_pp3",
+	"uart3_rts_n_pc0",
+	"pu3",
+	"pu4",
+	"pu5",
+	"pbb3",
+	"pbb4",
+	"pbb5",
+	"pbb6",
+	"kb_row3_pr3",
+	"kb_row4_pr4",
+	"kb_row5_pr5",
+	"kb_row6_pr6",
+	"kb_col3_pq3",
+	"sdmmc3_dat2_pb5",
+};
+
+static const char * const displaya_alt_groups[] = {
+	"kb_row6_pr6",
+};
+
+static const char * const displayb_groups[] = {
+	"dap3_fs_pp0",
+	"dap3_din_pp1",
+	"dap3_dout_pp2",
+	"dap3_sclk_pp3",
+	"pu3",
+	"pu4",
+	"pu5",
+	"pu6",
+	"pbb3",
+	"pbb4",
+	"pbb5",
+	"pbb6",
+	"kb_row3_pr3",
+	"kb_row4_pr4",
+	"kb_row5_pr5",
+	"kb_row6_pr6",
+	"sdmmc3_dat3_pb4",
+};
+
+static const char * const dtv_groups[] = {
+	"uart3_cts_n_pa1",
+	"uart3_rts_n_pc0",
+	"dap4_fs_pp4",
+	"dap4_dout_pp6",
+	"gmi_wait_pi7",
+	"gmi_ad8_ph0",
+	"gmi_ad14_ph6",
+	"gmi_ad15_ph7",
+};
+
+static const char * const emc_dll_groups[] = {
+	"kb_col0_pq0",
+	"kb_col1_pq1",
+};
+
+static const char * const extperiph1_groups[] = {
+	"clk1_out_pw4",
+};
+
+static const char * const extperiph2_groups[] = {
+	"clk2_out_pw5",
+};
+
+static const char * const extperiph3_groups[] = {
+	"clk3_out_pee0",
+};
+
+static const char * const gmi_groups[] = {
+	"gmi_wp_n_pc7",
+
+	"gmi_ad0_pg0",
+	"gmi_ad1_pg1",
+	"gmi_ad2_pg2",
+	"gmi_ad3_pg3",
+	"gmi_ad4_pg4",
+	"gmi_ad5_pg5",
+	"gmi_ad6_pg6",
+	"gmi_ad7_pg7",
+	"gmi_ad8_ph0",
+	"gmi_ad9_ph1",
+	"gmi_ad10_ph2",
+	"gmi_ad11_ph3",
+	"gmi_ad12_ph4",
+	"gmi_ad13_ph5",
+	"gmi_ad14_ph6",
+	"gmi_ad15_ph7",
+	"gmi_wr_n_pi0",
+	"gmi_oe_n_pi1",
+	"gmi_cs6_n_pi3",
+	"gmi_rst_n_pi4",
+	"gmi_iordy_pi5",
+	"gmi_cs7_n_pi6",
+	"gmi_wait_pi7",
+	"gmi_cs0_n_pj0",
+	"gmi_cs1_n_pj2",
+	"gmi_dqs_p_pj3",
+	"gmi_adv_n_pk0",
+	"gmi_clk_pk1",
+	"gmi_cs4_n_pk2",
+	"gmi_cs2_n_pk3",
+	"gmi_cs3_n_pk4",
+	"gmi_a16_pj7",
+	"gmi_a17_pb0",
+	"gmi_a18_pb1",
+	"gmi_a19_pk7",
+	"gen2_i2c_scl_pt5",
+	"gen2_i2c_sda_pt6",
+	"sdmmc4_dat0_paa0",
+	"sdmmc4_dat1_paa1",
+	"sdmmc4_dat2_paa2",
+	"sdmmc4_dat3_paa3",
+	"sdmmc4_dat4_paa4",
+	"sdmmc4_dat5_paa5",
+	"sdmmc4_dat6_paa6",
+	"sdmmc4_dat7_paa7",
+	"sdmmc4_clk_pcc4",
+	"sdmmc4_cmd_pt7",
+	"dap1_fs_pn0",
+	"dap1_din_pn1",
+	"dap1_dout_pn2",
+	"dap1_sclk_pn3",
+};
+
+static const char * const gmi_alt_groups[] = {
+	"gmi_wp_n_pc7",
+	"gmi_cs3_n_pk4",
+	"gmi_a16_pj7",
+};
+
+static const char * const hda_groups[] = {
+	"dap1_fs_pn0",
+	"dap1_din_pn1",
+	"dap1_dout_pn2",
+	"dap1_sclk_pn3",
+	"dap2_fs_pa2",
+	"dap2_sclk_pa3",
+	"dap2_din_pa4",
+	"dap2_dout_pa5",
+};
+
+static const char * const hsi_groups[] = {
+	"ulpi_data0_po1",
+	"ulpi_data1_po2",
+	"ulpi_data2_po3",
+	"ulpi_data3_po4",
+	"ulpi_data4_po5",
+	"ulpi_data5_po6",
+	"ulpi_data6_po7",
+	"ulpi_data7_po0",
+};
+
+static const char * const i2c1_groups[] = {
+	"gen1_i2c_scl_pc4",
+	"gen1_i2c_sda_pc5",
+	"gpio_w2_aud_pw2",
+	"gpio_w3_aud_pw3",
+};
+
+static const char * const i2c2_groups[] = {
+	"gen2_i2c_scl_pt5",
+	"gen2_i2c_sda_pt6",
+};
+
+static const char * const i2c3_groups[] = {
+	"cam_i2c_scl_pbb1",
+	"cam_i2c_sda_pbb2",
+};
+
+static const char * const i2c4_groups[] = {
+	"ddc_scl_pv4",
+	"ddc_sda_pv5",
+};
+
+static const char * const i2cpwr_groups[] = {
+	"pwr_i2c_scl_pz6",
+	"pwr_i2c_sda_pz7",
+};
+
+static const char * const i2s0_groups[] = {
+	"dap1_fs_pn0",
+	"dap1_din_pn1",
+	"dap1_dout_pn2",
+	"dap1_sclk_pn3",
+};
+
+static const char * const i2s1_groups[] = {
+	"dap2_fs_pa2",
+	"dap2_sclk_pa3",
+	"dap2_din_pa4",
+	"dap2_dout_pa5",
+};
+
+static const char * const i2s2_groups[] = {
+	"dap3_fs_pp0",
+	"dap3_din_pp1",
+	"dap3_dout_pp2",
+	"dap3_sclk_pp3",
+};
+
+static const char * const i2s3_groups[] = {
+	"dap4_fs_pp4",
+	"dap4_din_pp5",
+	"dap4_dout_pp6",
+	"dap4_sclk_pp7",
+};
+
+static const char * const i2s4_groups[] = {
+	"pcc1",
+	"pbb0",
+	"pbb7",
+	"pcc2",
+};
+
+static const char * const irda_groups[] = {
+	"uart2_rxd_pc3",
+	"uart2_txd_pc2",
+};
+
+static const char * const kbc_groups[] = {
+	"kb_row0_pr0",
+	"kb_row1_pr1",
+	"kb_row2_pr2",
+	"kb_row3_pr3",
+	"kb_row4_pr4",
+	"kb_row5_pr5",
+	"kb_row6_pr6",
+	"kb_row7_pr7",
+	"kb_row8_ps0",
+	"kb_row9_ps1",
+	"kb_row10_ps2",
+	"kb_col0_pq0",
+	"kb_col1_pq1",
+	"kb_col2_pq2",
+	"kb_col3_pq3",
+	"kb_col4_pq4",
+	"kb_col5_pq5",
+	"kb_col6_pq6",
+	"kb_col7_pq7",
+};
+
+static const char * const nand_groups[] = {
+	"gmi_wp_n_pc7",
+	"gmi_wait_pi7",
+	"gmi_adv_n_pk0",
+	"gmi_clk_pk1",
+	"gmi_cs0_n_pj0",
+	"gmi_cs1_n_pj2",
+	"gmi_cs2_n_pk3",
+	"gmi_cs3_n_pk4",
+	"gmi_cs4_n_pk2",
+	"gmi_cs6_n_pi3",
+	"gmi_cs7_n_pi6",
+	"gmi_ad0_pg0",
+	"gmi_ad1_pg1",
+	"gmi_ad2_pg2",
+	"gmi_ad3_pg3",
+	"gmi_ad4_pg4",
+	"gmi_ad5_pg5",
+	"gmi_ad6_pg6",
+	"gmi_ad7_pg7",
+	"gmi_ad8_ph0",
+	"gmi_ad9_ph1",
+	"gmi_ad10_ph2",
+	"gmi_ad11_ph3",
+	"gmi_ad12_ph4",
+	"gmi_ad13_ph5",
+	"gmi_ad14_ph6",
+	"gmi_ad15_ph7",
+	"gmi_wr_n_pi0",
+	"gmi_oe_n_pi1",
+	"gmi_dqs_p_pj3",
+	"gmi_rst_n_pi4",
+};
+
+static const char * const nand_alt_groups[] = {
+	"gmi_cs6_n_pi3",
+	"gmi_cs7_n_pi6",
+	"gmi_rst_n_pi4",
+};
+
+static const char * const owr_groups[] = {
+	"pu0",
+	"kb_col4_pq4",
+	"owr",
+	"sdmmc3_cd_n_pv2",
+};
+
+static const char * const pmi_groups[] = {
+	"pwr_int_n",
+};
+
+static const char * const pwm0_groups[] = {
+	"sdmmc1_dat2_py5",
+	"uart3_rts_n_pc0",
+	"pu3",
+	"gmi_ad8_ph0",
+	"sdmmc3_dat3_pb4",
+};
+
+static const char * const pwm1_groups[] = {
+	"sdmmc1_dat1_py6",
+	"pu4",
+	"gmi_ad9_ph1",
+	"sdmmc3_dat2_pb5",
+};
+
+static const char * const pwm2_groups[] = {
+	"pu5",
+	"gmi_ad10_ph2",
+	"kb_col3_pq3",
+	"sdmmc3_dat1_pb6",
+};
+
+static const char * const pwm3_groups[] = {
+	"pu6",
+	"gmi_ad11_ph3",
+	"sdmmc3_cmd_pa7",
+};
+
+static const char * const pwron_groups[] = {
+	"core_pwr_req",
+};
+
+static const char * const reset_out_n_groups[] = {
+	"reset_out_n",
+};
+
+static const char * const rsvd1_groups[] = {
+	"pv1",
+	"hdmi_int_pn7",
+	"pu1",
+	"pu2",
+	"gmi_wp_n_pc7",
+	"gmi_adv_n_pk0",
+	"gmi_cs0_n_pj0",
+	"gmi_cs1_n_pj2",
+	"gmi_ad0_pg0",
+	"gmi_ad1_pg1",
+	"gmi_ad2_pg2",
+	"gmi_ad3_pg3",
+	"gmi_ad4_pg4",
+	"gmi_ad5_pg5",
+	"gmi_ad6_pg6",
+	"gmi_ad7_pg7",
+	"gmi_wr_n_pi0",
+	"gmi_oe_n_pi1",
+	"gpio_x4_aud_px4",
+	"gpio_x5_aud_px5",
+	"gpio_x7_aud_px7",
+
+	"reset_out_n",
+};
+
+static const char * const rsvd2_groups[] = {
+	"pv0",
+	"pv1",
+	"sdmmc1_dat0_py7",
+	"clk2_out_pw5",
+	"clk2_req_pcc5",
+	"hdmi_int_pn7",
+	"ddc_scl_pv4",
+	"ddc_sda_pv5",
+	"uart3_txd_pw6",
+	"uart3_rxd_pw7",
+	"gen1_i2c_scl_pc4",
+	"gen1_i2c_sda_pc5",
+	"dap4_fs_pp4",
+	"dap4_din_pp5",
+	"dap4_dout_pp6",
+	"dap4_sclk_pp7",
+	"clk3_out_pee0",
+	"clk3_req_pee1",
+	"gmi_iordy_pi5",
+	"gmi_a17_pb0",
+	"gmi_a18_pb1",
+	"gen2_i2c_scl_pt5",
+	"gen2_i2c_sda_pt6",
+	"sdmmc4_clk_pcc4",
+	"sdmmc4_cmd_pt7",
+	"sdmmc4_dat7_paa7",
+	"pcc1",
+	"pbb7",
+	"pcc2",
+	"pwr_i2c_scl_pz6",
+	"pwr_i2c_sda_pz7",
+	"kb_row0_pr0",
+	"kb_row1_pr1",
+	"kb_row2_pr2",
+	"kb_row7_pr7",
+	"kb_row8_ps0",
+	"kb_row9_ps1",
+	"kb_row10_ps2",
+	"kb_col1_pq1",
+	"kb_col2_pq2",
+	"kb_col5_pq5",
+	"kb_col6_pq6",
+	"kb_col7_pq7",
+	"sys_clk_req_pz5",
+	"core_pwr_req",
+	"cpu_pwr_req",
+	"pwr_int_n",
+	"owr",
+	"spdif_out_pk5",
+	"gpio_x1_aud_px1",
+	"sdmmc3_clk_pa6",
+	"sdmmc3_dat0_pb7",
+	"gpio_w2_aud_pw2",
+	"usb_vbus_en0_pn4",
+	"usb_vbus_en1_pn5",
+	"sdmmc3_clk_lb_out_pee4",
+	"sdmmc3_clk_lb_in_pee5",
+	"reset_out_n",
+};
+
+static const char * const rsvd3_groups[] = {
+	"pv0",
+	"pv1",
+	"sdmmc1_clk_pz0",
+	"clk2_out_pw5",
+	"clk2_req_pcc5",
+	"hdmi_int_pn7",
+	"ddc_scl_pv4",
+	"ddc_sda_pv5",
+	"uart2_rts_n_pj6",
+	"uart2_cts_n_pj5",
+	"uart3_txd_pw6",
+	"uart3_rxd_pw7",
+	"pu0",
+	"pu1",
+	"pu2",
+	"gen1_i2c_scl_pc4",
+	"gen1_i2c_sda_pc5",
+	"dap4_din_pp5",
+	"dap4_sclk_pp7",
+	"clk3_out_pee0",
+	"clk3_req_pee1",
+	"pcc1",
+	"cam_i2c_scl_pbb1",
+	"cam_i2c_sda_pbb2",
+	"pbb7",
+	"pcc2",
+	"pwr_i2c_scl_pz6",
+	"pwr_i2c_sda_pz7",
+	"kb_row0_pr0",
+	"kb_row1_pr1",
+	"kb_row2_pr2",
+	"kb_row3_pr3",
+	"kb_row9_ps1",
+	"kb_row10_ps2",
+	"clk_32k_out_pa0",
+	"sys_clk_req_pz5",
+	"core_pwr_req",
+	"cpu_pwr_req",
+	"pwr_int_n",
+	"owr",
+	"clk1_req_pee2",
+	"clk1_out_pw4",
+	"spdif_out_pk5",
+	"spdif_in_pk6",
+	"dap2_fs_pa2",
+	"dap2_sclk_pa3",
+	"dap2_din_pa4",
+	"dap2_dout_pa5",
+	"dvfs_pwm_px0",
+	"gpio_x1_aud_px1",
+	"gpio_x3_aud_px3",
+	"dvfs_clk_px2",
+	"sdmmc3_clk_pa6",
+	"sdmmc3_dat0_pb7",
+	"hdmi_cec_pee3",
+	"sdmmc3_cd_n_pv2",
+	"usb_vbus_en0_pn4",
+	"usb_vbus_en1_pn5",
+	"sdmmc3_clk_lb_out_pee4",
+	"sdmmc3_clk_lb_in_pee5",
+	"reset_out_n",
+};
+
+static const char * const rsvd4_groups[] = {
+	"pv0",
+	"pv1",
+	"sdmmc1_clk_pz0",
+	"clk2_out_pw5",
+	"clk2_req_pcc5",
+	"hdmi_int_pn7",
+	"ddc_scl_pv4",
+	"ddc_sda_pv5",
+	"pu0",
+	"pu1",
+	"pu2",
+	"gen1_i2c_scl_pc4",
+	"gen1_i2c_sda_pc5",
+	"dap4_fs_pp4",
+	"dap4_din_pp5",
+	"dap4_dout_pp6",
+	"dap4_sclk_pp7",
+	"clk3_out_pee0",
+	"clk3_req_pee1",
+	"gmi_ad0_pg0",
+	"gmi_ad1_pg1",
+	"gmi_ad2_pg2",
+	"gmi_ad3_pg3",
+	"gmi_ad4_pg4",
+	"gmi_ad12_ph4",
+	"gmi_ad13_ph5",
+	"gmi_rst_n_pi4",
+	"gen2_i2c_scl_pt5",
+	"gen2_i2c_sda_pt6",
+	"sdmmc4_clk_pcc4",
+	"sdmmc4_cmd_pt7",
+	"sdmmc4_dat0_paa0",
+	"sdmmc4_dat1_paa1",
+	"sdmmc4_dat2_paa2",
+	"sdmmc4_dat3_paa3",
+	"sdmmc4_dat4_paa4",
+	"sdmmc4_dat5_paa5",
+	"sdmmc4_dat6_paa6",
+	"sdmmc4_dat7_paa7",
+	"cam_mclk_pcc0",
+	"pcc1",
+	"cam_i2c_scl_pbb1",
+	"cam_i2c_sda_pbb2",
+	"pbb3",
+	"pbb4",
+	"pbb5",
+	"pbb6",
+	"pbb7",
+	"pcc2",
+	"pwr_i2c_scl_pz6",
+	"pwr_i2c_sda_pz7",
+	"kb_row0_pr0",
+	"kb_row1_pr1",
+	"kb_row2_pr2",
+	"kb_col2_pq2",
+	"kb_col5_pq5",
+	"kb_col6_pq6",
+	"kb_col7_pq7",
+	"clk_32k_out_pa0",
+	"sys_clk_req_pz5",
+	"core_pwr_req",
+	"cpu_pwr_req",
+	"pwr_int_n",
+	"owr",
+	"dap1_fs_pn0",
+	"dap1_din_pn1",
+	"dap1_dout_pn2",
+	"dap1_sclk_pn3",
+	"clk1_req_pee2",
+	"clk1_out_pw4",
+	"spdif_in_pk6",
+	"spdif_out_pk5",
+	"dap2_fs_pa2",
+	"dap2_sclk_pa3",
+	"dap2_din_pa4",
+	"dap2_dout_pa5",
+	"dvfs_pwm_px0",
+	"gpio_x1_aud_px1",
+	"gpio_x3_aud_px3",
+	"dvfs_clk_px2",
+	"gpio_x5_aud_px5",
+	"gpio_x6_aud_px6",
+	"gpio_x7_aud_px7",
+	"sdmmc3_cd_n_pv2",
+	"usb_vbus_en0_pn4",
+	"usb_vbus_en1_pn5",
+	"sdmmc3_clk_lb_in_pee5",
+	"sdmmc3_clk_lb_out_pee4",
+};
+
+static const char * const sdmmc1_groups[] = {
+
+	"sdmmc1_clk_pz0",
+	"sdmmc1_cmd_pz1",
+	"sdmmc1_dat3_py4",
+	"sdmmc1_dat2_py5",
+	"sdmmc1_dat1_py6",
+	"sdmmc1_dat0_py7",
+	"uart3_cts_n_pa1",
+	"kb_col5_pq5",
+	"sdmmc1_wp_n_pv3",
+};
+
+static const char * const sdmmc2_groups[] = {
+	"gmi_iordy_pi5",
+	"gmi_clk_pk1",
+	"gmi_cs2_n_pk3",
+	"gmi_cs3_n_pk4",
+	"gmi_cs7_n_pi6",
+	"gmi_ad12_ph4",
+	"gmi_ad13_ph5",
+	"gmi_ad14_ph6",
+	"gmi_ad15_ph7",
+	"gmi_dqs_p_pj3",
+};
+
+static const char * const sdmmc3_groups[] = {
+	"kb_col4_pq4",
+	"sdmmc3_clk_pa6",
+	"sdmmc3_cmd_pa7",
+	"sdmmc3_dat0_pb7",
+	"sdmmc3_dat1_pb6",
+	"sdmmc3_dat2_pb5",
+	"sdmmc3_dat3_pb4",
+	"hdmi_cec_pee3",
+	"sdmmc3_cd_n_pv2",
+	"sdmmc3_clk_lb_in_pee5",
+	"sdmmc3_clk_lb_out_pee4",
+};
+
+static const char * const sdmmc4_groups[] = {
+	"sdmmc4_clk_pcc4",
+	"sdmmc4_cmd_pt7",
+	"sdmmc4_dat0_paa0",
+	"sdmmc4_dat1_paa1",
+	"sdmmc4_dat2_paa2",
+	"sdmmc4_dat3_paa3",
+	"sdmmc4_dat4_paa4",
+	"sdmmc4_dat5_paa5",
+	"sdmmc4_dat6_paa6",
+	"sdmmc4_dat7_paa7",
+};
+
+static const char * const soc_groups[] = {
+	"gmi_cs1_n_pj2",
+	"gmi_oe_n_pi1",
+	"clk_32k_out_pa0",
+	"hdmi_cec_pee3",
+};
+
+static const char * const spdif_groups[] = {
+	"sdmmc1_cmd_pz1",
+	"sdmmc1_dat3_py4",
+	"uart2_rxd_pc3",
+	"uart2_txd_pc2",
+	"spdif_in_pk6",
+	"spdif_out_pk5",
+};
+
+static const char * const spi1_groups[] = {
+	"ulpi_clk_py0",
+	"ulpi_dir_py1",
+	"ulpi_nxt_py2",
+	"ulpi_stp_py3",
+	"gpio_x3_aud_px3",
+	"gpio_x4_aud_px4",
+	"gpio_x5_aud_px5",
+	"gpio_x6_aud_px6",
+	"gpio_x7_aud_px7",
+	"gpio_w3_aud_pw3",
+};
+
+static const char * const spi2_groups[] = {
+	"ulpi_data4_po5",
+	"ulpi_data5_po6",
+	"ulpi_data6_po7",
+	"ulpi_data7_po0",
+	"kb_row4_pr4",
+	"kb_row5_pr5",
+	"kb_col0_pq0",
+	"kb_col1_pq1",
+	"kb_col2_pq2",
+	"kb_col6_pq6",
+	"kb_col7_pq7",
+	"gpio_x4_aud_px4",
+	"gpio_x5_aud_px5",
+	"gpio_x6_aud_px6",
+	"gpio_x7_aud_px7",
+	"gpio_w2_aud_pw2",
+	"gpio_w3_aud_pw3",
+};
+
+static const char * const spi3_groups[] = {
+	"ulpi_data0_po1",
+	"ulpi_data1_po2",
+	"ulpi_data2_po3",
+	"ulpi_data3_po4",
+	"sdmmc4_dat0_paa0",
+	"sdmmc4_dat1_paa1",
+	"sdmmc4_dat2_paa2",
+	"sdmmc4_dat3_paa3",
+	"sdmmc4_dat4_paa4",
+	"sdmmc4_dat5_paa5",
+	"sdmmc4_dat6_paa6",
+	"sdmmc3_clk_pa6",
+	"sdmmc3_cmd_pa7",
+	"sdmmc3_dat0_pb7",
+	"sdmmc3_dat1_pb6",
+	"sdmmc3_dat2_pb5",
+	"sdmmc3_dat3_pb4",
+};
+
+static const char * const spi4_groups[] = {
+	"sdmmc1_cmd_pz1",
+	"sdmmc1_dat3_py4",
+	"sdmmc1_dat2_py5",
+	"sdmmc1_dat1_py6",
+	"sdmmc1_dat0_py7",
+	"uart2_rxd_pc3",
+	"uart2_txd_pc2",
+	"uart2_rts_n_pj6",
+	"uart2_cts_n_pj5",
+	"uart3_txd_pw6",
+	"uart3_rxd_pw7",
+	"uart3_cts_n_pa1",
+	"gmi_wait_pi7",
+	"gmi_cs6_n_pi3",
+	"gmi_ad5_pg5",
+	"gmi_ad6_pg6",
+	"gmi_ad7_pg7",
+	"gmi_a19_pk7",
+	"gmi_wr_n_pi0",
+	"sdmmc1_wp_n_pv3",
+};
+
+static const char * const spi5_groups[] = {
+	"ulpi_clk_py0",
+	"ulpi_dir_py1",
+	"ulpi_nxt_py2",
+	"ulpi_stp_py3",
+	"dap3_fs_pp0",
+	"dap3_din_pp1",
+	"dap3_dout_pp2",
+	"dap3_sclk_pp3",
+};
+
+static const char * const spi6_groups[] = {
+	"dvfs_pwm_px0",
+	"gpio_x1_aud_px1",
+	"gpio_x3_aud_px3",
+	"dvfs_clk_px2",
+	"gpio_x6_aud_px6",
+	"gpio_w2_aud_pw2",
+	"gpio_w3_aud_pw3",
+};
+
+static const char * const sysclk_groups[] = {
+	"sys_clk_req_pz5",
+};
+
+static const char * const trace_groups[] = {
+	"gmi_iordy_pi5",
+	"gmi_adv_n_pk0",
+	"gmi_clk_pk1",
+	"gmi_cs2_n_pk3",
+	"gmi_cs4_n_pk2",
+	"gmi_a16_pj7",
+	"gmi_a17_pb0",
+	"gmi_a18_pb1",
+	"gmi_a19_pk7",
+	"gmi_dqs_p_pj3",
+};
+
+static const char * const uarta_groups[] = {
+	"ulpi_data0_po1",
+	"ulpi_data1_po2",
+	"ulpi_data2_po3",
+	"ulpi_data3_po4",
+	"ulpi_data4_po5",
+	"ulpi_data5_po6",
+	"ulpi_data6_po7",
+	"ulpi_data7_po0",
+	"sdmmc1_cmd_pz1",
+	"sdmmc1_dat3_py4",
+	"sdmmc1_dat2_py5",
+	"sdmmc1_dat1_py6",
+	"sdmmc1_dat0_py7",
+	"uart2_rxd_pc3",
+	"uart2_txd_pc2",
+	"uart2_rts_n_pj6",
+	"uart2_cts_n_pj5",
+	"pu0",
+	"pu1",
+	"pu2",
+	"pu3",
+	"pu4",
+	"pu5",
+	"pu6",
+	"kb_row7_pr7",
+	"kb_row8_ps0",
+	"kb_row9_ps1",
+	"kb_row10_ps2",
+	"kb_col3_pq3",
+	"kb_col4_pq4",
+	"sdmmc3_cmd_pa7",
+	"sdmmc3_dat1_pb6",
+	"sdmmc1_wp_n_pv3",
+};
+
+static const char * const uartb_groups[] = {
+	"uart2_rts_n_pj6",
+	"uart2_cts_n_pj5",
+};
+
+static const char * const uartc_groups[] = {
+	"uart3_txd_pw6",
+	"uart3_rxd_pw7",
+	"uart3_cts_n_pa1",
+	"uart3_rts_n_pc0",
+};
+
+static const char * const uartd_groups[] = {
+	"ulpi_clk_py0",
+	"ulpi_dir_py1",
+	"ulpi_nxt_py2",
+	"ulpi_stp_py3",
+	"gmi_a16_pj7",
+	"gmi_a17_pb0",
+	"gmi_a18_pb1",
+	"gmi_a19_pk7",
+};
+
+static const char * const ulpi_groups[] = {
+	"ulpi_data0_po1",
+	"ulpi_data1_po2",
+	"ulpi_data2_po3",
+	"ulpi_data3_po4",
+	"ulpi_data4_po5",
+	"ulpi_data5_po6",
+	"ulpi_data6_po7",
+	"ulpi_data7_po0",
+	"ulpi_clk_py0",
+	"ulpi_dir_py1",
+	"ulpi_nxt_py2",
+	"ulpi_stp_py3",
+};
+
+static const char * const usb_groups[] = {
+	"pv0",
+	"pu6",
+	"gmi_cs0_n_pj0",
+	"gmi_cs4_n_pk2",
+	"gmi_ad11_ph3",
+	"kb_col0_pq0",
+	"spdif_in_pk6",
+	"usb_vbus_en0_pn4",
+	"usb_vbus_en1_pn5",
+};
+
+static const char * const vgp1_groups[] = {
+	"cam_i2c_scl_pbb1",
+};
+
+static const char * const vgp2_groups[] = {
+	"cam_i2c_sda_pbb2",
+};
+
+static const char * const vgp3_groups[] = {
+	"pbb3",
+};
+
+static const char * const vgp4_groups[] = {
+	"pbb4",
+};
+
+static const char * const vgp5_groups[] = {
+	"pbb5",
+};
+
+static const char * const vgp6_groups[] = {
+	"pbb6",
+};
+
+static const char * const vi_groups[] = {
+	"cam_mclk_pcc0",
+	"pbb0",
+};
+
+static const char * const vi_alt1_groups[] = {
+	"cam_mclk_pcc0",
+	"pbb0",
+};
+
+static const char * const vi_alt3_groups[] = {
+	"cam_mclk_pcc0",
+	"pbb0",
+};
+
+#define FUNCTION(fname)					\
+	{						\
+		.name = #fname,				\
+		.groups = fname##_groups,		\
+		.ngroups = ARRAY_SIZE(fname##_groups),	\
+	}
+
+static const struct tegra_function  tegra114_functions[] = {
+	FUNCTION(blink),
+	FUNCTION(cec),
+	FUNCTION(cldvfs),
+	FUNCTION(clk12),
+	FUNCTION(cpu),
+	FUNCTION(dap),
+	FUNCTION(dap1),
+	FUNCTION(dap2),
+	FUNCTION(dev3),
+	FUNCTION(displaya),
+	FUNCTION(displaya_alt),
+	FUNCTION(displayb),
+	FUNCTION(dtv),
+	FUNCTION(emc_dll),
+	FUNCTION(extperiph1),
+	FUNCTION(extperiph2),
+	FUNCTION(extperiph3),
+	FUNCTION(gmi),
+	FUNCTION(gmi_alt),
+	FUNCTION(hda),
+	FUNCTION(hsi),
+	FUNCTION(i2c1),
+	FUNCTION(i2c2),
+	FUNCTION(i2c3),
+	FUNCTION(i2c4),
+	FUNCTION(i2cpwr),
+	FUNCTION(i2s0),
+	FUNCTION(i2s1),
+	FUNCTION(i2s2),
+	FUNCTION(i2s3),
+	FUNCTION(i2s4),
+	FUNCTION(irda),
+	FUNCTION(kbc),
+	FUNCTION(nand),
+	FUNCTION(nand_alt),
+	FUNCTION(owr),
+	FUNCTION(pmi),
+	FUNCTION(pwm0),
+	FUNCTION(pwm1),
+	FUNCTION(pwm2),
+	FUNCTION(pwm3),
+	FUNCTION(pwron),
+	FUNCTION(reset_out_n),
+	FUNCTION(rsvd1),
+	FUNCTION(rsvd2),
+	FUNCTION(rsvd3),
+	FUNCTION(rsvd4),
+	FUNCTION(sdmmc1),
+	FUNCTION(sdmmc2),
+	FUNCTION(sdmmc3),
+	FUNCTION(sdmmc4),
+	FUNCTION(soc),
+	FUNCTION(spdif),
+	FUNCTION(spi1),
+	FUNCTION(spi2),
+	FUNCTION(spi3),
+	FUNCTION(spi4),
+	FUNCTION(spi5),
+	FUNCTION(spi6),
+	FUNCTION(sysclk),
+	FUNCTION(trace),
+	FUNCTION(uarta),
+	FUNCTION(uartb),
+	FUNCTION(uartc),
+	FUNCTION(uartd),
+	FUNCTION(ulpi),
+	FUNCTION(usb),
+	FUNCTION(vgp1),
+	FUNCTION(vgp2),
+	FUNCTION(vgp3),
+	FUNCTION(vgp4),
+	FUNCTION(vgp5),
+	FUNCTION(vgp6),
+	FUNCTION(vi),
+	FUNCTION(vi_alt1),
+	FUNCTION(vi_alt3),
+};
+
+#define DRV_PINGROUP_REG_START			0x868	/* bank 0 */
+#define PINGROUP_REG_START			0x3000	/* bank 1 */
+
+#define PINGROUP_REG_Y(r)			((r) - PINGROUP_REG_START)
+#define PINGROUP_REG_N(r)			-1
+
+#define PINGROUP(pg_name, f0, f1, f2, f3, f_safe, r, od, ior, rcv_sel)	\
+	{								\
+		.name = #pg_name,					\
+		.pins = pg_name##_pins,					\
+		.npins = ARRAY_SIZE(pg_name##_pins),			\
+		.funcs = {						\
+			TEGRA_MUX_##f0,					\
+			TEGRA_MUX_##f1,					\
+			TEGRA_MUX_##f2,					\
+			TEGRA_MUX_##f3,					\
+		},							\
+		.func_safe = TEGRA_MUX_##f_safe,			\
+		.mux_reg = PINGROUP_REG_Y(r),				\
+		.mux_bank = 1,						\
+		.mux_bit = 0,						\
+		.pupd_reg = PINGROUP_REG_Y(r),				\
+		.pupd_bank = 1,						\
+		.pupd_bit = 2,						\
+		.tri_reg = PINGROUP_REG_Y(r),				\
+		.tri_bank = 1,						\
+		.tri_bit = 4,						\
+		.einput_reg = PINGROUP_REG_Y(r),			\
+		.einput_bank = 1,					\
+		.einput_bit = 5,					\
+		.odrain_reg = PINGROUP_REG_##od(r),			\
+		.odrain_bank = 1,					\
+		.odrain_bit = 6,					\
+		.lock_reg = PINGROUP_REG_Y(r),				\
+		.lock_bank = 1,						\
+		.lock_bit = 7,						\
+		.ioreset_reg = PINGROUP_REG_##ior(r),			\
+		.ioreset_bank = 1,					\
+		.ioreset_bit = 8,					\
+		.rcv_sel_reg = PINGROUP_REG_##rcv_sel(r),		\
+		.rcv_sel_bank = 1,					\
+		.rcv_sel_bit = 9,					\
+		.drv_reg = -1,						\
+		.drvtype_reg = -1,					\
+	}
+
+#define DRV_PINGROUP_DVRTYPE_Y(r) ((r) - DRV_PINGROUP_REG_START)
+#define DRV_PINGROUP_DVRTYPE_N(r) -1
+
+#define DRV_PINGROUP(pg_name, r, hsm_b, schmitt_b, lpmd_b,		\
+			drvdn_b, drvdn_w, drvup_b, drvup_w,		\
+			slwr_b, slwr_w, slwf_b, slwf_w,			\
+			drvtype)					\
+	{								\
+		.name = "drive_" #pg_name,				\
+		.pins = drive_##pg_name##_pins,				\
+		.npins = ARRAY_SIZE(drive_##pg_name##_pins),		\
+		.mux_reg = -1,						\
+		.pupd_reg = -1,						\
+		.tri_reg = -1,						\
+		.einput_reg = -1,					\
+		.odrain_reg = -1,					\
+		.lock_reg = -1,						\
+		.ioreset_reg = -1,					\
+		.rcv_sel_reg = -1,					\
+		.drv_reg = DRV_PINGROUP_DVRTYPE_Y(r),			\
+		.drv_bank = 0,						\
+		.hsm_bit = hsm_b,					\
+		.schmitt_bit = schmitt_b,				\
+		.lpmd_bit = lpmd_b,					\
+		.drvdn_bit = drvdn_b,					\
+		.drvdn_width = drvdn_w,					\
+		.drvup_bit = drvup_b,					\
+		.drvup_width = drvup_w,					\
+		.slwr_bit = slwr_b,					\
+		.slwr_width = slwr_w,					\
+		.slwf_bit = slwf_b,					\
+		.slwf_width = slwf_w,					\
+		.drvtype_reg = DRV_PINGROUP_DVRTYPE_##drvtype(r),	\
+		.drvtype_bank = 0,					\
+		.drvtype_bit = 6,					\
+	}
+
+static const struct tegra_pingroup tegra114_groups[] = {
+	/*       pg_name,                f0,         f1,         f2,           f3,          safe,     r,      od, ior, rcv_sel */
+	/* FIXME: Fill in correct data in safe column */
+	PINGROUP(ulpi_data0_po1,         SPI3,       HSI,        UARTA,        ULPI,        ULPI,     0x3000,  N,  N,  N),
+	PINGROUP(ulpi_data1_po2,         SPI3,       HSI,        UARTA,        ULPI,        ULPI,     0x3004,  N,  N,  N),
+	PINGROUP(ulpi_data2_po3,         SPI3,       HSI,        UARTA,        ULPI,        ULPI,     0x3008,  N,  N,  N),
+	PINGROUP(ulpi_data3_po4,         SPI3,       HSI,        UARTA,        ULPI,        ULPI,     0x300c,  N,  N,  N),
+	PINGROUP(ulpi_data4_po5,         SPI2,       HSI,        UARTA,        ULPI,        ULPI,     0x3010,  N,  N,  N),
+	PINGROUP(ulpi_data5_po6,         SPI2,       HSI,        UARTA,        ULPI,        ULPI,     0x3014,  N,  N,  N),
+	PINGROUP(ulpi_data6_po7,         SPI2,       HSI,        UARTA,        ULPI,        ULPI,     0x3018,  N,  N,  N),
+	PINGROUP(ulpi_data7_po0,         SPI2,       HSI,        UARTA,        ULPI,        ULPI,     0x301c,  N,  N,  N),
+	PINGROUP(ulpi_clk_py0,           SPI1,       SPI5,       UARTD,        ULPI,        ULPI,     0x3020,  N,  N,  N),
+	PINGROUP(ulpi_dir_py1,           SPI1,       SPI5,       UARTD,        ULPI,        ULPI,     0x3024,  N,  N,  N),
+	PINGROUP(ulpi_nxt_py2,           SPI1,       SPI5,       UARTD,        ULPI,        ULPI,     0x3028,  N,  N,  N),
+	PINGROUP(ulpi_stp_py3,           SPI1,       SPI5,       UARTD,        ULPI,        ULPI,     0x302c,  N,  N,  N),
+	PINGROUP(dap3_fs_pp0,            I2S2,       SPI5,       DISPLAYA,     DISPLAYB,    I2S2,     0x3030,  N,  N,  N),
+	PINGROUP(dap3_din_pp1,           I2S2,       SPI5,       DISPLAYA,     DISPLAYB,    I2S2,     0x3034,  N,  N,  N),
+	PINGROUP(dap3_dout_pp2,          I2S2,       SPI5,       DISPLAYA,     DISPLAYB,    I2S2,     0x3038,  N,  N,  N),
+	PINGROUP(dap3_sclk_pp3,          I2S2,       SPI5,       DISPLAYA,     DISPLAYB,    I2S2,     0x303c,  N,  N,  N),
+	PINGROUP(pv0,                    USB,        RSVD2,      RSVD3,        RSVD4,       RSVD4,    0x3040,  N,  N,  N),
+	PINGROUP(pv1,                    RSVD1,      RSVD2,      RSVD3,        RSVD4,       RSVD4,    0x3044,  N,  N,  N),
+	PINGROUP(sdmmc1_clk_pz0,         SDMMC1,     CLK12,      RSVD3,        RSVD4,       RSVD4,    0x3048,  N,  N,  N),
+	PINGROUP(sdmmc1_cmd_pz1,         SDMMC1,     SPDIF,      SPI4,         UARTA,       SDMMC1,   0x304c,  N,  N,  N),
+	PINGROUP(sdmmc1_dat3_py4,        SDMMC1,     SPDIF,      SPI4,         UARTA,       SDMMC1,   0x3050,  N,  N,  N),
+	PINGROUP(sdmmc1_dat2_py5,        SDMMC1,     PWM0,       SPI4,         UARTA,       SDMMC1,   0x3054,  N,  N,  N),
+	PINGROUP(sdmmc1_dat1_py6,        SDMMC1,     PWM1,       SPI4,         UARTA,       SDMMC1,   0x3058,  N,  N,  N),
+	PINGROUP(sdmmc1_dat0_py7,        SDMMC1,     RSVD2,      SPI4,         UARTA,       RSVD2,    0x305c,  N,  N,  N),
+	PINGROUP(clk2_out_pw5,           EXTPERIPH2, RSVD2,      RSVD3,        RSVD4,       RSVD4,    0x3068,  N,  N,  N),
+	PINGROUP(clk2_req_pcc5,          DAP,        RSVD2,      RSVD3,        RSVD4,       RSVD4,    0x306c,  N,  N,  N),
+	PINGROUP(hdmi_int_pn7,           RSVD1,      RSVD2,      RSVD3,        RSVD4,       RSVD4,    0x3110,  N,  N,  Y),
+	PINGROUP(ddc_scl_pv4,            I2C4,       RSVD2,      RSVD3,        RSVD4,       RSVD4,    0x3114,  N,  N,  Y),
+	PINGROUP(ddc_sda_pv5,            I2C4,       RSVD2,      RSVD3,        RSVD4,       RSVD4,    0x3118,  N,  N,  Y),
+	PINGROUP(uart2_rxd_pc3,          IRDA,       SPDIF,      UARTA,        SPI4,        IRDA,     0x3164,  N,  N,  N),
+	PINGROUP(uart2_txd_pc2,          IRDA,       SPDIF,      UARTA,        SPI4,        IRDA,     0x3168,  N,  N,  N),
+	PINGROUP(uart2_rts_n_pj6,        UARTA,      UARTB,      RSVD3,        SPI4,        RSVD3,    0x316c,  N,  N,  N),
+	PINGROUP(uart2_cts_n_pj5,        UARTA,      UARTB,      RSVD3,        SPI4,        RSVD3,    0x3170,  N,  N,  N),
+	PINGROUP(uart3_txd_pw6,          UARTC,      RSVD2,      RSVD3,        SPI4,        RSVD3,    0x3174,  N,  N,  N),
+	PINGROUP(uart3_rxd_pw7,          UARTC,      RSVD2,      RSVD3,        SPI4,        RSVD3,    0x3178,  N,  N,  N),
+	PINGROUP(uart3_cts_n_pa1,        UARTC,      SDMMC1,     DTV,          SPI4,        UARTC,    0x317c,  N,  N,  N),
+	PINGROUP(uart3_rts_n_pc0,        UARTC,      PWM0,       DTV,          DISPLAYA,    UARTC,    0x3180,  N,  N,  N),
+	PINGROUP(pu0,                    OWR,        UARTA,      RSVD3,        RSVD4,       RSVD4,    0x3184,  N,  N,  N),
+	PINGROUP(pu1,                    RSVD1,      UARTA,      RSVD3,        RSVD4,       RSVD4,    0x3188,  N,  N,  N),
+	PINGROUP(pu2,                    RSVD1,      UARTA,      RSVD3,        RSVD4,       RSVD4,    0x318c,  N,  N,  N),
+	PINGROUP(pu3,                    PWM0,       UARTA,      DISPLAYA,     DISPLAYB,    PWM0,     0x3190,  N,  N,  N),
+	PINGROUP(pu4,                    PWM1,       UARTA,      DISPLAYA,     DISPLAYB,    PWM1,     0x3194,  N,  N,  N),
+	PINGROUP(pu5,                    PWM2,       UARTA,      DISPLAYA,     DISPLAYB,    PWM2,     0x3198,  N,  N,  N),
+	PINGROUP(pu6,                    PWM3,       UARTA,      USB,          DISPLAYB,    PWM3,     0x319c,  N,  N,  N),
+	PINGROUP(gen1_i2c_sda_pc5,       I2C1,       RSVD2,      RSVD3,        RSVD4,       RSVD4,    0x31a0,  Y,  N,  N),
+	PINGROUP(gen1_i2c_scl_pc4,       I2C1,       RSVD2,      RSVD3,        RSVD4,       RSVD4,    0x31a4,  Y,  N,  N),
+	PINGROUP(dap4_fs_pp4,            I2S3,       RSVD2,      DTV,          RSVD4,       RSVD4,    0x31a8,  N,  N,  N),
+	PINGROUP(dap4_din_pp5,           I2S3,       RSVD2,      RSVD3,        RSVD4,       RSVD4,    0x31ac,  N,  N,  N),
+	PINGROUP(dap4_dout_pp6,          I2S3,       RSVD2,      DTV,          RSVD4,       RSVD4,    0x31b0,  N,  N,  N),
+	PINGROUP(dap4_sclk_pp7,          I2S3,       RSVD2,      RSVD3,        RSVD4,       RSVD4,    0x31b4,  N,  N,  N),
+	PINGROUP(clk3_out_pee0,          EXTPERIPH3, RSVD2,      RSVD3,        RSVD4,       RSVD4,    0x31b8,  N,  N,  N),
+	PINGROUP(clk3_req_pee1,          DEV3,       RSVD2,      RSVD3,        RSVD4,       RSVD4,    0x31bc,  N,  N,  N),
+	PINGROUP(gmi_wp_n_pc7,           RSVD1,      NAND,       GMI,          GMI_ALT,     RSVD1,    0x31c0,  N,  N,  N),
+	PINGROUP(gmi_iordy_pi5,          SDMMC2,     RSVD2,      GMI,          TRACE,       RSVD2,    0x31c4,  N,  N,  N),
+	PINGROUP(gmi_wait_pi7,           SPI4,       NAND,       GMI,          DTV,         NAND,     0x31c8,  N,  N,  N),
+	PINGROUP(gmi_adv_n_pk0,          RSVD1,      NAND,       GMI,          TRACE,       RSVD1,    0x31cc,  N,  N,  N),
+	PINGROUP(gmi_clk_pk1,            SDMMC2,     NAND,       GMI,          TRACE,       GMI,      0x31d0,  N,  N,  N),
+	PINGROUP(gmi_cs0_n_pj0,          RSVD1,      NAND,       GMI,          USB,         RSVD1,    0x31d4,  N,  N,  N),
+	PINGROUP(gmi_cs1_n_pj2,          RSVD1,      NAND,       GMI,          SOC,         RSVD1,    0x31d8,  N,  N,  N),
+	PINGROUP(gmi_cs2_n_pk3,          SDMMC2,     NAND,       GMI,          TRACE,       GMI,      0x31dc,  N,  N,  N),
+	PINGROUP(gmi_cs3_n_pk4,          SDMMC2,     NAND,       GMI,          GMI_ALT,     GMI,      0x31e0,  N,  N,  N),
+	PINGROUP(gmi_cs4_n_pk2,          USB,        NAND,       GMI,          TRACE,       GMI,      0x31e4,  N,  N,  N),
+	PINGROUP(gmi_cs6_n_pi3,          NAND,       NAND_ALT,   GMI,          SPI4,        NAND,     0x31e8,  N,  N,  N),
+	PINGROUP(gmi_cs7_n_pi6,          NAND,       NAND_ALT,   GMI,          SDMMC2,      NAND,     0x31ec,  N,  N,  N),
+	PINGROUP(gmi_ad0_pg0,            RSVD1,      NAND,       GMI,          RSVD4,       RSVD4,    0x31f0,  N,  N,  N),
+	PINGROUP(gmi_ad1_pg1,            RSVD1,      NAND,       GMI,          RSVD4,       RSVD4,    0x31f4,  N,  N,  N),
+	PINGROUP(gmi_ad2_pg2,            RSVD1,      NAND,       GMI,          RSVD4,       RSVD4,    0x31f8,  N,  N,  N),
+	PINGROUP(gmi_ad3_pg3,            RSVD1,      NAND,       GMI,          RSVD4,       RSVD4,    0x31fc,  N,  N,  N),
+	PINGROUP(gmi_ad4_pg4,            RSVD1,      NAND,       GMI,          RSVD4,       RSVD4,    0x3200,  N,  N,  N),
+	PINGROUP(gmi_ad5_pg5,            RSVD1,      NAND,       GMI,          SPI4,        RSVD1,    0x3204,  N,  N,  N),
+	PINGROUP(gmi_ad6_pg6,            RSVD1,      NAND,       GMI,          SPI4,        RSVD1,    0x3208,  N,  N,  N),
+	PINGROUP(gmi_ad7_pg7,            RSVD1,      NAND,       GMI,          SPI4,        RSVD1,    0x320c,  N,  N,  N),
+	PINGROUP(gmi_ad8_ph0,            PWM0,       NAND,       GMI,          DTV,         GMI,      0x3210,  N,  N,  N),
+	PINGROUP(gmi_ad9_ph1,            PWM1,       NAND,       GMI,          CLDVFS,      GMI,      0x3214,  N,  N,  N),
+	PINGROUP(gmi_ad10_ph2,           PWM2,       NAND,       GMI,          CLDVFS,      GMI,      0x3218,  N,  N,  N),
+	PINGROUP(gmi_ad11_ph3,           PWM3,       NAND,       GMI,          USB,         GMI,      0x321c,  N,  N,  N),
+	PINGROUP(gmi_ad12_ph4,           SDMMC2,     NAND,       GMI,          RSVD4,       RSVD4,    0x3220,  N,  N,  N),
+	PINGROUP(gmi_ad13_ph5,           SDMMC2,     NAND,       GMI,          RSVD4,       RSVD4,    0x3224,  N,  N,  N),
+	PINGROUP(gmi_ad14_ph6,           SDMMC2,     NAND,       GMI,          DTV,         GMI,      0x3228,  N,  N,  N),
+	PINGROUP(gmi_ad15_ph7,           SDMMC2,     NAND,       GMI,          DTV,         GMI,      0x322c,  N,  N,  N),
+	PINGROUP(gmi_a16_pj7,            UARTD,      TRACE,      GMI,          GMI_ALT,     GMI,      0x3230,  N,  N,  N),
+	PINGROUP(gmi_a17_pb0,            UARTD,      RSVD2,      GMI,          TRACE,       RSVD2,    0x3234,  N,  N,  N),
+	PINGROUP(gmi_a18_pb1,            UARTD,      RSVD2,      GMI,          TRACE,       RSVD2,    0x3238,  N,  N,  N),
+	PINGROUP(gmi_a19_pk7,            UARTD,      SPI4,       GMI,          TRACE,       GMI,      0x323c,  N,  N,  N),
+	PINGROUP(gmi_wr_n_pi0,           RSVD1,      NAND,       GMI,          SPI4,        RSVD1,    0x3240,  N,  N,  N),
+	PINGROUP(gmi_oe_n_pi1,           RSVD1,      NAND,       GMI,          SOC,         RSVD1,    0x3244,  N,  N,  N),
+	PINGROUP(gmi_dqs_p_pj3,          SDMMC2,     NAND,       GMI,          TRACE,       NAND,     0x3248,  N,  N,  N),
+	PINGROUP(gmi_rst_n_pi4,          NAND,       NAND_ALT,   GMI,          RSVD4,       RSVD4,    0x324c,  N,  N,  N),
+	PINGROUP(gen2_i2c_scl_pt5,       I2C2,       RSVD2,      GMI,          RSVD4,       RSVD4,    0x3250,  Y,  N,  N),
+	PINGROUP(gen2_i2c_sda_pt6,       I2C2,       RSVD2,      GMI,          RSVD4,       RSVD4,    0x3254,  Y,  N,  N),
+	PINGROUP(sdmmc4_clk_pcc4,        SDMMC4,     RSVD2,      GMI,          RSVD4,       RSVD4,    0x3258,  N,  Y,  N),
+	PINGROUP(sdmmc4_cmd_pt7,         SDMMC4,     RSVD2,      GMI,          RSVD4,       RSVD4,    0x325c,  N,  Y,  N),
+	PINGROUP(sdmmc4_dat0_paa0,       SDMMC4,     SPI3,       GMI,          RSVD4,       RSVD4,    0x3260,  N,  Y,  N),
+	PINGROUP(sdmmc4_dat1_paa1,       SDMMC4,     SPI3,       GMI,          RSVD4,       RSVD4,    0x3264,  N,  Y,  N),
+	PINGROUP(sdmmc4_dat2_paa2,       SDMMC4,     SPI3,       GMI,          RSVD4,       RSVD4,    0x3268,  N,  Y,  N),
+	PINGROUP(sdmmc4_dat3_paa3,       SDMMC4,     SPI3,       GMI,          RSVD4,       RSVD4,    0x326c,  N,  Y,  N),
+	PINGROUP(sdmmc4_dat4_paa4,       SDMMC4,     SPI3,       GMI,          RSVD4,       RSVD4,    0x3270,  N,  Y,  N),
+	PINGROUP(sdmmc4_dat5_paa5,       SDMMC4,     SPI3,       GMI,          RSVD4,       RSVD4,    0x3274,  N,  Y,  N),
+	PINGROUP(sdmmc4_dat6_paa6,       SDMMC4,     SPI3,       GMI,          RSVD4,       RSVD4,    0x3278,  N,  Y,  N),
+	PINGROUP(sdmmc4_dat7_paa7,       SDMMC4,     RSVD2,      GMI,          RSVD4,       RSVD4,    0x327c,  N,  Y,  N),
+	PINGROUP(cam_mclk_pcc0,          VI,         VI_ALT1,    VI_ALT3,      RSVD4,       RSVD4,    0x3284,  N,  N,  N),
+	PINGROUP(pcc1,                   I2S4,       RSVD2,      RSVD3,        RSVD4,       RSVD4,    0x3288,  N,  N,  N),
+	PINGROUP(pbb0,                   I2S4,       VI,         VI_ALT1,      VI_ALT3,     I2S4,     0x328c,  N,  N,  N),
+	PINGROUP(cam_i2c_scl_pbb1,       VGP1,       I2C3,       RSVD3,        RSVD4,       RSVD4,    0x3290,  Y,  N,  N),
+	PINGROUP(cam_i2c_sda_pbb2,       VGP2,       I2C3,       RSVD3,        RSVD4,       RSVD4,    0x3294,  Y,  N,  N),
+	PINGROUP(pbb3,                   VGP3,       DISPLAYA,   DISPLAYB,     RSVD4,       RSVD4,    0x3298,  N,  N,  N),
+	PINGROUP(pbb4,                   VGP4,       DISPLAYA,   DISPLAYB,     RSVD4,       RSVD4,    0x329c,  N,  N,  N),
+	PINGROUP(pbb5,                   VGP5,       DISPLAYA,   DISPLAYB,     RSVD4,       RSVD4,    0x32a0,  N,  N,  N),
+	PINGROUP(pbb6,                   VGP6,       DISPLAYA,   DISPLAYB,     RSVD4,       RSVD4,    0x32a4,  N,  N,  N),
+	PINGROUP(pbb7,                   I2S4,       RSVD2,      RSVD3,        RSVD4,       RSVD4,    0x32a8,  N,  N,  N),
+	PINGROUP(pcc2,                   I2S4,       RSVD2,      RSVD3,        RSVD4,       RSVD4,    0x32ac,  N,  N,  N),
+	PINGROUP(pwr_i2c_scl_pz6,        I2CPWR,     RSVD2,      RSVD3,        RSVD4,       RSVD4,    0x32b4,  Y,  N,  N),
+	PINGROUP(pwr_i2c_sda_pz7,        I2CPWR,     RSVD2,      RSVD3,        RSVD4,       RSVD4,    0x32b8,  Y,  N,  N),
+	PINGROUP(kb_row0_pr0,            KBC,        RSVD2,      RSVD3,        RSVD4,       RSVD4,    0x32bc,  N,  N,  N),
+	PINGROUP(kb_row1_pr1,            KBC,        RSVD2,      RSVD3,        RSVD4,       RSVD4,    0x32c0,  N,  N,  N),
+	PINGROUP(kb_row2_pr2,            KBC,        RSVD2,      RSVD3,        RSVD4,       RSVD4,    0x32c4,  N,  N,  N),
+	PINGROUP(kb_row3_pr3,            KBC,        DISPLAYA,   RSVD3,        DISPLAYB,    RSVD3,    0x32c8,  N,  N,  N),
+	PINGROUP(kb_row4_pr4,            KBC,        DISPLAYA,   SPI2,         DISPLAYB,    KBC,      0x32cc,  N,  N,  N),
+	PINGROUP(kb_row5_pr5,            KBC,        DISPLAYA,   SPI2,         DISPLAYB,    KBC,      0x32d0,  N,  N,  N),
+	PINGROUP(kb_row6_pr6,            KBC,        DISPLAYA,   DISPLAYA_ALT, DISPLAYB,    KBC,      0x32d4,  N,  N,  N),
+	PINGROUP(kb_row7_pr7,            KBC,        RSVD2,      CLDVFS,       UARTA,       RSVD2,    0x32d8,  N,  N,  N),
+	PINGROUP(kb_row8_ps0,            KBC,        RSVD2,      CLDVFS,       UARTA,       RSVD2,    0x32dc,  N,  N,  N),
+	PINGROUP(kb_row9_ps1,            KBC,        RSVD2,      RSVD3,        UARTA,       RSVD3,    0x32e0,  N,  N,  N),
+	PINGROUP(kb_row10_ps2,           KBC,        RSVD2,      RSVD3,        UARTA,       RSVD3,    0x32e4,  N,  N,  N),
+	PINGROUP(kb_col0_pq0,            KBC,        USB,        SPI2,         EMC_DLL,     KBC,      0x32fc,  N,  N,  N),
+	PINGROUP(kb_col1_pq1,            KBC,        RSVD2,      SPI2,         EMC_DLL,     RSVD2,    0x3300,  N,  N,  N),
+	PINGROUP(kb_col2_pq2,            KBC,        RSVD2,      SPI2,         RSVD4,       RSVD2,    0x3304,  N,  N,  N),
+	PINGROUP(kb_col3_pq3,            KBC,        DISPLAYA,   PWM2,         UARTA,       KBC,      0x3308,  N,  N,  N),
+	PINGROUP(kb_col4_pq4,            KBC,        OWR,        SDMMC3,       UARTA,       KBC,      0x330c,  N,  N,  N),
+	PINGROUP(kb_col5_pq5,            KBC,        RSVD2,      SDMMC1,       RSVD4,       RSVD4,    0x3310,  N,  N,  N),
+	PINGROUP(kb_col6_pq6,            KBC,        RSVD2,      SPI2,         RSVD4,       RSVD4,    0x3314,  N,  N,  N),
+	PINGROUP(kb_col7_pq7,            KBC,        RSVD2,      SPI2,         RSVD4,       RSVD4,    0x3318,  N,  N,  N),
+	PINGROUP(clk_32k_out_pa0,        BLINK,      SOC,        RSVD3,        RSVD4,       RSVD4,    0x331c,  N,  N,  N),
+	PINGROUP(sys_clk_req_pz5,        SYSCLK,     RSVD2,      RSVD3,        RSVD4,       RSVD4,    0x3320,  N,  N,  N),
+	PINGROUP(core_pwr_req,           PWRON,      RSVD2,      RSVD3,        RSVD4,       RSVD4,    0x3324,  N,  N,  N),
+	PINGROUP(cpu_pwr_req,            CPU,        RSVD2,      RSVD3,        RSVD4,       RSVD4,    0x3328,  N,  N,  N),
+	PINGROUP(pwr_int_n,              PMI,        RSVD2,      RSVD3,        RSVD4,       RSVD4,    0x332c,  N,  N,  N),
+	PINGROUP(owr,                    OWR,        RSVD2,      RSVD3,        RSVD4,       RSVD4,    0x3334,  N,  N,  Y),
+	PINGROUP(dap1_fs_pn0,            I2S0,       HDA,        GMI,          RSVD4,       RSVD4,    0x3338,  N,  N,  N),
+	PINGROUP(dap1_din_pn1,           I2S0,       HDA,        GMI,          RSVD4,       RSVD4,    0x333c,  N,  N,  N),
+	PINGROUP(dap1_dout_pn2,          I2S0,       HDA,        GMI,          RSVD4,       RSVD4,    0x3340,  N,  N,  N),
+	PINGROUP(dap1_sclk_pn3,          I2S0,       HDA,        GMI,          RSVD4,       RSVD4,    0x3344,  N,  N,  N),
+	PINGROUP(clk1_req_pee2,          DAP,        DAP1,       RSVD3,        RSVD4,       RSVD4,    0x3348,  N,  N,  N),
+	PINGROUP(clk1_out_pw4,           EXTPERIPH1, DAP2,       RSVD3,        RSVD4,       RSVD4,    0x334c,  N,  N,  N),
+	PINGROUP(spdif_in_pk6,           SPDIF,      USB,        RSVD3,        RSVD4,       RSVD4,    0x3350,  N,  N,  N),
+	PINGROUP(spdif_out_pk5,          SPDIF,      RSVD2,      RSVD3,        RSVD4,       RSVD4,    0x3354,  N,  N,  N),
+	PINGROUP(dap2_fs_pa2,            I2S1,       HDA,        RSVD3,        RSVD4,       RSVD4,    0x3358,  N,  N,  N),
+	PINGROUP(dap2_din_pa4,           I2S1,       HDA,        RSVD3,        RSVD4,       RSVD4,    0x335c,  N,  N,  N),
+	PINGROUP(dap2_dout_pa5,          I2S1,       HDA,        RSVD3,        RSVD4,       RSVD4,    0x3360,  N,  N,  N),
+	PINGROUP(dap2_sclk_pa3,          I2S1,       HDA,        RSVD3,        RSVD4,       RSVD4,    0x3364,  N,  N,  N),
+	PINGROUP(dvfs_pwm_px0,           SPI6,       CLDVFS,     RSVD3,        RSVD4,       RSVD4,    0x3368,  N,  N,  N),
+	PINGROUP(gpio_x1_aud_px1,        SPI6,       RSVD2,      RSVD3,        RSVD4,       RSVD4,    0x336c,  N,  N,  N),
+	PINGROUP(gpio_x3_aud_px3,        SPI6,       SPI1,       RSVD3,        RSVD4,       RSVD4,    0x3370,  N,  N,  N),
+	PINGROUP(dvfs_clk_px2,           SPI6,       CLDVFS,     RSVD3,        RSVD4,       RSVD4,    0x3374,  N,  N,  N),
+	PINGROUP(gpio_x4_aud_px4,        RSVD1,      SPI1,       SPI2,         DAP2,        RSVD1,    0x3378,  N,  N,  N),
+	PINGROUP(gpio_x5_aud_px5,        RSVD1,      SPI1,       SPI2,         RSVD4,       RSVD1,    0x337c,  N,  N,  N),
+	PINGROUP(gpio_x6_aud_px6,        SPI6,       SPI1,       SPI2,         RSVD4,       RSVD4,    0x3380,  N,  N,  N),
+	PINGROUP(gpio_x7_aud_px7,        RSVD1,      SPI1,       SPI2,         RSVD4,       RSVD4,    0x3384,  N,  N,  N),
+	PINGROUP(sdmmc3_clk_pa6,         SDMMC3,     RSVD2,      RSVD3,        SPI3,        RSVD3,    0x3390,  N,  N,  N),
+	PINGROUP(sdmmc3_cmd_pa7,         SDMMC3,     PWM3,       UARTA,        SPI3,        SDMMC3,   0x3394,  N,  N,  N),
+	PINGROUP(sdmmc3_dat0_pb7,        SDMMC3,     RSVD2,      RSVD3,        SPI3,        RSVD3,    0x3398,  N,  N,  N),
+	PINGROUP(sdmmc3_dat1_pb6,        SDMMC3,     PWM2,       UARTA,        SPI3,        SDMMC3,   0x339c,  N,  N,  N),
+	PINGROUP(sdmmc3_dat2_pb5,        SDMMC3,     PWM1,       DISPLAYA,     SPI3,        SDMMC3,   0x33a0,  N,  N,  N),
+	PINGROUP(sdmmc3_dat3_pb4,        SDMMC3,     PWM0,       DISPLAYB,     SPI3,        SDMMC3,   0x33a4,  N,  N,  N),
+	PINGROUP(hdmi_cec_pee3,          CEC,        SDMMC3,     RSVD3,        SOC,         RSVD3,    0x33e0,  Y,  N,  N),
+	PINGROUP(sdmmc1_wp_n_pv3,        SDMMC1,     CLK12,      SPI4,         UARTA,       SDMMC1,   0x33e4,  N,  N,  N),
+	PINGROUP(sdmmc3_cd_n_pv2,        SDMMC3,     OWR,        RSVD3,        RSVD4,       RSVD4,    0x33e8,  N,  N,  N),
+	PINGROUP(gpio_w2_aud_pw2,        SPI6,       RSVD2,      SPI2,         I2C1,        RSVD2,    0x33ec,  N,  N,  N),
+	PINGROUP(gpio_w3_aud_pw3,        SPI6,       SPI1,       SPI2,         I2C1,        SPI6,     0x33f0,  N,  N,  N),
+	PINGROUP(usb_vbus_en0_pn4,       USB,        RSVD2,      RSVD3,        RSVD4,       RSVD4,    0x33f4,  Y,  N,  N),
+	PINGROUP(usb_vbus_en1_pn5,       USB,        RSVD2,      RSVD3,        RSVD4,       RSVD4,    0x33f8,  Y,  N,  N),
+	PINGROUP(sdmmc3_clk_lb_in_pee5,  SDMMC3,     RSVD2,      RSVD3,        RSVD4,       RSVD4,    0x33fc,  N,  N,  N),
+	PINGROUP(sdmmc3_clk_lb_out_pee4, SDMMC3,     RSVD2,      RSVD3,        RSVD4,       RSVD4,    0x3400,  N,  N,  N),
+	PINGROUP(reset_out_n,            RSVD1,      RSVD2,      RSVD3,        RESET_OUT_N, RSVD3,    0x3408,  N,  N,  N),
+
+	/* pg_name, r, hsm_b, schmitt_b, lpmd_b, drvdn_b, drvdn_w, drvup_b, drvup_w, slwr_b, slwr_w, slwf_b, slwf_w, drvtype */
+	DRV_PINGROUP(ao1,   0x868,  2,  3,  4,  12,  5,  20,  5,  28,  2,  30,  2,  N),
+	DRV_PINGROUP(ao2,   0x86c,  2,  3,  4,  12,  5,  20,  5,  28,  2,  30,  2,  N),
+	DRV_PINGROUP(at1,   0x870,  2,  3,  4,  12,  7,  20,  7,  28,  2,  30,  2,  Y),
+	DRV_PINGROUP(at2,   0x874,  2,  3,  4,  12,  7,  20,  7,  28,  2,  30,  2,  Y),
+	DRV_PINGROUP(at3,   0x878,  2,  3,  4,  12,  7,  20,  7,  28,  2,  30,  2,  Y),
+	DRV_PINGROUP(at4,   0x87c,  2,  3,  4,  12,  7,  20,  7,  28,  2,  30,  2,  Y),
+	DRV_PINGROUP(at5,   0x880,  2,  3,  4,  14,  5,  19,  5,  28,  2,  30,  2,  N),
+	DRV_PINGROUP(cdev1, 0x884,  2,  3,  4,  12,  5,  20,  5,  28,  2,  30,  2,  N),
+	DRV_PINGROUP(cdev2, 0x888,  2,  3,  4,  12,  5,  20,  5,  28,  2,  30,  2,  N),
+	DRV_PINGROUP(dap1,  0x890,  2,  3,  4,  12,  5,  20,  5,  28,  2,  30,  2,  N),
+	DRV_PINGROUP(dap2,  0x894,  2,  3,  4,  12,  5,  20,  5,  28,  2,  30,  2,  N),
+	DRV_PINGROUP(dap3,  0x898,  2,  3,  4,  12,  5,  20,  5,  28,  2,  30,  2,  N),
+	DRV_PINGROUP(dap4,  0x89c,  2,  3,  4,  12,  5,  20,  5,  28,  2,  30,  2,  N),
+	DRV_PINGROUP(dbg,   0x8a0,  2,  3,  4,  12,  5,  20,  5,  28,  2,  30,  2,  N),
+	DRV_PINGROUP(sdio3, 0x8b0,  2,  3, -1,  12,  7,  20,  7,  28,  2,  30,  2,  N),
+	DRV_PINGROUP(spi,   0x8b4,  2,  3,  4,  12,  5,  20,  5,  28,  2,  30,  2,  N),
+	DRV_PINGROUP(uaa,   0x8b8,  2,  3,  4,  12,  5,  20,  5,  28,  2,  30,  2,  N),
+	DRV_PINGROUP(uab,   0x8bc,  2,  3,  4,  12,  5,  20,  5,  28,  2,  30,  2,  N),
+	DRV_PINGROUP(uart2, 0x8c0,  2,  3,  4,  12,  5,  20,  5,  28,  2,  30,  2,  N),
+	DRV_PINGROUP(uart3, 0x8c4,  2,  3,  4,  12,  5,  20,  5,  28,  2,  30,  2,  N),
+	DRV_PINGROUP(sdio1, 0x8ec,  2,  3, -1,  12,  7,  20,  7,  28,  2,  30,  2,  N),
+	DRV_PINGROUP(ddc,   0x8fc,  2,  3,  4,  12,  5,  20,  5,  28,  2,  30,  2,  N),
+	DRV_PINGROUP(gma,   0x900,  2,  3,  4,  14,  5,  20,  5,  28,  2,  30,  2,  Y),
+	DRV_PINGROUP(gme,   0x910,  2,  3,  4,  14,  5,  19,  5,  28,  2,  30,  2,  N),
+	DRV_PINGROUP(gmf,   0x914,  2,  3,  4,  14,  5,  19,  5,  28,  2,  30,  2,  N),
+	DRV_PINGROUP(gmg,   0x918,  2,  3,  4,  14,  5,  19,  5,  28,  2,  30,  2,  N),
+	DRV_PINGROUP(gmh,   0x91c,  2,  3,  4,  14,  5,  19,  5,  28,  2,  30,  2,  N),
+	DRV_PINGROUP(owr,   0x920,  2,  3,  4,  12,  5,  20,  5,  28,  2,  30,  2,  N),
+	DRV_PINGROUP(uda,   0x924,  2,  3,  4,  12,  5,  20,  5,  28,  2,  30,  2,  N),
+};
+
+static const struct tegra_pinctrl_soc_data tegra114_pinctrl = {
+	.ngpios = NUM_GPIOS,
+	.pins = tegra114_pins,
+	.npins = ARRAY_SIZE(tegra114_pins),
+	.functions = tegra114_functions,
+	.nfunctions = ARRAY_SIZE(tegra114_functions),
+	.groups = tegra114_groups,
+	.ngroups = ARRAY_SIZE(tegra114_groups),
+};
+
+static int tegra114_pinctrl_probe(struct platform_device *pdev)
+{
+	return tegra_pinctrl_probe(pdev, &tegra114_pinctrl);
+}
+
+static struct of_device_id tegra114_pinctrl_of_match[] = {
+	{ .compatible = "nvidia,tegra114-pinmux", },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, tegra114_pinctrl_of_match);
+
+static struct platform_driver tegra114_pinctrl_driver = {
+	.driver = {
+		.name = "tegra114-pinctrl",
+		.owner = THIS_MODULE,
+		.of_match_table = tegra114_pinctrl_of_match,
+	},
+	.probe = tegra114_pinctrl_probe,
+	.remove = tegra_pinctrl_remove,
+};
+module_platform_driver(tegra114_pinctrl_driver);
+
+MODULE_ALIAS("platform:tegra114-pinctrl");
+MODULE_AUTHOR("Pritesh Raithatha <praithatha@nvidia.com>");
+MODULE_DESCRIPTION("NVIDIA Tegra114 pincontrol driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/pinctrl/pinctrl-tegra20.c b/drivers/pinctrl/pinctrl-tegra20.c
index e848189..fcfb7d0 100644
--- a/drivers/pinctrl/pinctrl-tegra20.c
+++ b/drivers/pinctrl/pinctrl-tegra20.c
@@ -2624,7 +2624,9 @@
 		.odrain_reg = -1,				\
 		.lock_reg = -1,					\
 		.ioreset_reg = -1,				\
+		.rcv_sel_reg = -1,				\
 		.drv_reg = -1,					\
+		.drvtype_reg = -1,				\
 	}
 
 /* Pin groups with only pull up and pull down control */
@@ -2642,7 +2644,9 @@
 		.odrain_reg = -1,				\
 		.lock_reg = -1,					\
 		.ioreset_reg = -1,				\
+		.rcv_sel_reg = -1,				\
 		.drv_reg = -1,					\
+		.drvtype_reg = -1,				\
 	}
 
 /* Pin groups for drive strength registers (configurable version) */
@@ -2660,6 +2664,7 @@
 		.odrain_reg = -1,				\
 		.lock_reg = -1,					\
 		.ioreset_reg = -1,				\
+		.rcv_sel_reg = -1,				\
 		.drv_reg = ((r) - PINGROUP_REG_A),		\
 		.drv_bank = 3,					\
 		.hsm_bit = hsm_b,				\
@@ -2673,6 +2678,7 @@
 		.slwr_width = slwr_w,				\
 		.slwf_bit = slwf_b,				\
 		.slwf_width = slwf_w,				\
+		.drvtype_reg = -1,				\
 	}
 
 /* Pin groups for drive strength registers (simple version) */
diff --git a/drivers/pinctrl/pinctrl-tegra30.c b/drivers/pinctrl/pinctrl-tegra30.c
index 9ad87ea..2300deb 100644
--- a/drivers/pinctrl/pinctrl-tegra30.c
+++ b/drivers/pinctrl/pinctrl-tegra30.c
@@ -3384,7 +3384,9 @@
 		.ioreset_reg = PINGROUP_REG_##ior(r),		\
 		.ioreset_bank = 1,				\
 		.ioreset_bit = 8,				\
+		.rcv_sel_reg = -1,				\
 		.drv_reg = -1,					\
+		.drvtype_reg = -1,				\
 	}
 
 #define DRV_PINGROUP(pg_name, r, hsm_b, schmitt_b, lpmd_b,	\
@@ -3401,6 +3403,7 @@
 		.odrain_reg = -1,				\
 		.lock_reg = -1,					\
 		.ioreset_reg = -1,				\
+		.rcv_sel_reg = -1,				\
 		.drv_reg = ((r) - DRV_PINGROUP_REG_A),		\
 		.drv_bank = 0,					\
 		.hsm_bit = hsm_b,				\
@@ -3414,6 +3417,7 @@
 		.slwr_width = slwr_w,				\
 		.slwf_bit = slwf_b,				\
 		.slwf_width = slwf_w,				\
+		.drvtype_reg = -1,				\
 	}
 
 static const struct tegra_pingroup tegra30_groups[] = {
diff --git a/drivers/pinctrl/pinctrl-xway.c b/drivers/pinctrl/pinctrl-xway.c
index 5f0eb04..53cb6a3 100644
--- a/drivers/pinctrl/pinctrl-xway.c
+++ b/drivers/pinctrl/pinctrl-xway.c
@@ -441,17 +441,17 @@
 		if (port == PORT3)
 			reg = GPIO3_OD;
 		else
-			reg = GPIO_OD(port);
+			reg = GPIO_OD(pin);
 		*config = LTQ_PINCONF_PACK(param,
-			!!gpio_getbit(info->membase[0], reg, PORT_PIN(port)));
+			!gpio_getbit(info->membase[0], reg, PORT_PIN(pin)));
 		break;
 
 	case LTQ_PINCONF_PARAM_PULL:
 		if (port == PORT3)
 			reg = GPIO3_PUDEN;
 		else
-			reg = GPIO_PUDEN(port);
-		if (!gpio_getbit(info->membase[0], reg, PORT_PIN(port))) {
+			reg = GPIO_PUDEN(pin);
+		if (!gpio_getbit(info->membase[0], reg, PORT_PIN(pin))) {
 			*config = LTQ_PINCONF_PACK(param, 0);
 			break;
 		}
@@ -459,13 +459,18 @@
 		if (port == PORT3)
 			reg = GPIO3_PUDSEL;
 		else
-			reg = GPIO_PUDSEL(port);
-		if (!gpio_getbit(info->membase[0], reg, PORT_PIN(port)))
+			reg = GPIO_PUDSEL(pin);
+		if (!gpio_getbit(info->membase[0], reg, PORT_PIN(pin)))
 			*config = LTQ_PINCONF_PACK(param, 2);
 		else
 			*config = LTQ_PINCONF_PACK(param, 1);
 		break;
 
+	case LTQ_PINCONF_PARAM_OUTPUT:
+		reg = GPIO_DIR(pin);
+		*config = LTQ_PINCONF_PACK(param,
+			gpio_getbit(info->membase[0], reg, PORT_PIN(pin)));
+		break;
 	default:
 		dev_err(pctldev->dev, "Invalid config param %04x\n", param);
 		return -ENOTSUPP;
@@ -488,33 +493,44 @@
 		if (port == PORT3)
 			reg = GPIO3_OD;
 		else
-			reg = GPIO_OD(port);
-		gpio_setbit(info->membase[0], reg, PORT_PIN(port));
+			reg = GPIO_OD(pin);
+		if (arg == 0)
+			gpio_setbit(info->membase[0], reg, PORT_PIN(pin));
+		else
+			gpio_clearbit(info->membase[0], reg, PORT_PIN(pin));
 		break;
 
 	case LTQ_PINCONF_PARAM_PULL:
 		if (port == PORT3)
 			reg = GPIO3_PUDEN;
 		else
-			reg = GPIO_PUDEN(port);
+			reg = GPIO_PUDEN(pin);
 		if (arg == 0) {
-			gpio_clearbit(info->membase[0], reg, PORT_PIN(port));
+			gpio_clearbit(info->membase[0], reg, PORT_PIN(pin));
 			break;
 		}
-		gpio_setbit(info->membase[0], reg, PORT_PIN(port));
+		gpio_setbit(info->membase[0], reg, PORT_PIN(pin));
 
 		if (port == PORT3)
 			reg = GPIO3_PUDSEL;
 		else
-			reg = GPIO_PUDSEL(port);
+			reg = GPIO_PUDSEL(pin);
 		if (arg == 1)
-			gpio_clearbit(info->membase[0], reg, PORT_PIN(port));
+			gpio_clearbit(info->membase[0], reg, PORT_PIN(pin));
 		else if (arg == 2)
-			gpio_setbit(info->membase[0], reg, PORT_PIN(port));
+			gpio_setbit(info->membase[0], reg, PORT_PIN(pin));
 		else
 			dev_err(pctldev->dev, "Invalid pull value %d\n", arg);
 		break;
 
+	case LTQ_PINCONF_PARAM_OUTPUT:
+		reg = GPIO_DIR(pin);
+		if (arg == 0)
+			gpio_clearbit(info->membase[0], reg, PORT_PIN(pin));
+		else
+			gpio_setbit(info->membase[0], reg, PORT_PIN(pin));
+		break;
+
 	default:
 		dev_err(pctldev->dev, "Invalid config param %04x\n", param);
 		return -ENOTSUPP;
@@ -522,9 +538,24 @@
 	return 0;
 }
 
+int xway_pinconf_group_set(struct pinctrl_dev *pctldev,
+			unsigned selector,
+			unsigned long config)
+{
+	struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctldev);
+	int i, ret = 0;
+
+	for (i = 0; i < info->grps[selector].npins && !ret; i++)
+		ret = xway_pinconf_set(pctldev,
+				info->grps[selector].pins[i], config);
+
+	return ret;
+}
+
 static struct pinconf_ops xway_pinconf_ops = {
 	.pin_config_get	= xway_pinconf_get,
 	.pin_config_set	= xway_pinconf_set,
+	.pin_config_group_set = xway_pinconf_group_set,
 };
 
 static struct pinctrl_desc xway_pctrl_desc = {
@@ -558,6 +589,7 @@
 static const struct ltq_cfg_param xway_cfg_params[] = {
 	{"lantiq,pull",		LTQ_PINCONF_PARAM_PULL},
 	{"lantiq,open-drain",	LTQ_PINCONF_PARAM_OPEN_DRAIN},
+	{"lantiq,output",	LTQ_PINCONF_PARAM_OUTPUT},
 };
 
 static struct ltq_pinmux_info xway_info = {
diff --git a/include/linux/device.h b/include/linux/device.h
index 43dcda9..001f663 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -21,6 +21,7 @@
 #include <linux/compiler.h>
 #include <linux/types.h>
 #include <linux/mutex.h>
+#include <linux/pinctrl/devinfo.h>
 #include <linux/pm.h>
 #include <linux/atomic.h>
 #include <linux/ratelimit.h>
@@ -620,6 +621,8 @@
  * @pm_domain:	Provide callbacks that are executed during system suspend,
  * 		hibernation, system resume and during runtime PM transitions
  * 		along with subsystem-level and driver-level callbacks.
+ * @pins:	For device pin management.
+ *		See Documentation/pinctrl.txt for details.
  * @numa_node:	NUMA node this device is close to.
  * @dma_mask:	Dma mask (if dma'ble device).
  * @coherent_dma_mask: Like dma_mask, but for alloc_coherent mapping as not all
@@ -672,6 +675,10 @@
 	struct dev_pm_info	power;
 	struct dev_pm_domain	*pm_domain;
 
+#ifdef CONFIG_PINCTRL
+	struct dev_pin_info	*pins;
+#endif
+
 #ifdef CONFIG_NUMA
 	int		numa_node;	/* NUMA node this device is close to */
 #endif
diff --git a/include/linux/mfd/abx500/ab8500-gpio.h b/include/linux/mfd/abx500/ab8500-gpio.h
index 2387c20..172b2f2 100644
--- a/include/linux/mfd/abx500/ab8500-gpio.h
+++ b/include/linux/mfd/abx500/ab8500-gpio.h
@@ -14,10 +14,20 @@
  * registers.
  */
 
-struct ab8500_gpio_platform_data {
+struct abx500_gpio_platform_data {
 	int gpio_base;
-	u32 irq_base;
-	u8  config_reg[8];
+};
+
+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,
 };
 
 #endif /* _AB8500_GPIO_H */
diff --git a/include/linux/mfd/abx500/ab8500.h b/include/linux/mfd/abx500/ab8500.h
index 1cb5698..fc05344 100644
--- a/include/linux/mfd/abx500/ab8500.h
+++ b/include/linux/mfd/abx500/ab8500.h
@@ -24,7 +24,7 @@
 	AB8500_VERSION_AB8500 = 0x0,
 	AB8500_VERSION_AB8505 = 0x1,
 	AB8500_VERSION_AB9540 = 0x2,
-	AB8500_VERSION_AB8540 = 0x3,
+	AB8500_VERSION_AB8540 = 0x4,
 	AB8500_VERSION_UNDEFINED,
 };
 
@@ -32,6 +32,7 @@
 #define AB8500_CUTEARLY	0x00
 #define AB8500_CUT1P0	0x10
 #define AB8500_CUT1P1	0x11
+#define AB8500_CUT1P2	0x12 /* Only valid for AB8540 */
 #define AB8500_CUT2P0	0x20
 #define AB8500_CUT3P0	0x30
 #define AB8500_CUT3P3	0x33
@@ -39,6 +40,7 @@
 /*
  * AB8500 bank addresses
  */
+#define AB8500_M_FSM_RANK	0x0
 #define AB8500_SYS_CTRL1_BLOCK	0x1
 #define AB8500_SYS_CTRL2_BLOCK	0x2
 #define AB8500_REGU_CTRL1	0x3
@@ -58,6 +60,7 @@
 #define AB8500_DEVELOPMENT	0x11
 #define AB8500_DEBUG		0x12
 #define AB8500_PROD_TEST	0x13
+#define AB8500_STE_TEST		0x14
 #define AB8500_OTP_EMUL		0x15
 
 /*
@@ -65,11 +68,11 @@
  * Values used to index into array ab8500_irq_regoffset[] defined in
  * drivers/mdf/ab8500-core.c
  */
-/* Definitions for AB8500 and AB9540 */
+/* Definitions for AB8500, AB9540 and AB8540 */
 /* ab8500_irq_regoffset[0] -> IT[Source|Latch|Mask]1 */
 #define AB8500_INT_MAIN_EXT_CH_NOT_OK	0 /* not 8505/9540 */
-#define AB8500_INT_UN_PLUG_TV_DET	1 /* not 8505/9540 */
-#define AB8500_INT_PLUG_TV_DET		2 /* not 8505/9540 */
+#define AB8500_INT_UN_PLUG_TV_DET	1 /* not 8505/9540/8540 */
+#define AB8500_INT_PLUG_TV_DET		2 /* not 8505/9540/8540 */
 #define AB8500_INT_TEMP_WARM		3
 #define AB8500_INT_PON_KEY2DB_F		4
 #define AB8500_INT_PON_KEY2DB_R		5
@@ -77,18 +80,19 @@
 #define AB8500_INT_PON_KEY1DB_R		7
 /* ab8500_irq_regoffset[1] -> IT[Source|Latch|Mask]2 */
 #define AB8500_INT_BATT_OVV		8
-#define AB8500_INT_MAIN_CH_UNPLUG_DET	10 /* not 8505 */
-#define AB8500_INT_MAIN_CH_PLUG_DET	11 /* not 8505 */
+#define AB8500_INT_MAIN_CH_UNPLUG_DET	10 /* not 8505/8540 */
+#define AB8500_INT_MAIN_CH_PLUG_DET	11 /* not 8505/8540 */
 #define AB8500_INT_VBUS_DET_F		14
 #define AB8500_INT_VBUS_DET_R		15
 /* ab8500_irq_regoffset[2] -> IT[Source|Latch|Mask]3 */
 #define AB8500_INT_VBUS_CH_DROP_END	16
 #define AB8500_INT_RTC_60S		17
 #define AB8500_INT_RTC_ALARM		18
+#define AB8540_INT_BIF_INT		19
 #define AB8500_INT_BAT_CTRL_INDB	20
 #define AB8500_INT_CH_WD_EXP		21
 #define AB8500_INT_VBUS_OVV		22
-#define AB8500_INT_MAIN_CH_DROP_END	23 /* not 8505/9540 */
+#define AB8500_INT_MAIN_CH_DROP_END	23 /* not 8505/9540/8540 */
 /* ab8500_irq_regoffset[3] -> IT[Source|Latch|Mask]4 */
 #define AB8500_INT_CCN_CONV_ACC		24
 #define AB8500_INT_INT_AUD		25
@@ -99,7 +103,7 @@
 #define AB8500_INT_BUP_CHG_NOT_OK	30
 #define AB8500_INT_BUP_CHG_OK		31
 /* ab8500_irq_regoffset[4] -> IT[Source|Latch|Mask]5 */
-#define AB8500_INT_GP_HW_ADC_CONV_END	32 /* not 8505 */
+#define AB8500_INT_GP_HW_ADC_CONV_END	32 /* not 8505/8540 */
 #define AB8500_INT_ACC_DETECT_1DB_F	33
 #define AB8500_INT_ACC_DETECT_1DB_R	34
 #define AB8500_INT_ACC_DETECT_22DB_F	35
@@ -108,23 +112,23 @@
 #define AB8500_INT_ACC_DETECT_21DB_R	38
 #define AB8500_INT_GP_SW_ADC_CONV_END	39
 /* ab8500_irq_regoffset[5] -> IT[Source|Latch|Mask]7 */
-#define AB8500_INT_GPIO6R		40 /* not 8505/9540 */
-#define AB8500_INT_GPIO7R		41 /* not 8505/9540 */
-#define AB8500_INT_GPIO8R		42 /* not 8505/9540 */
-#define AB8500_INT_GPIO9R		43 /* not 8505/9540 */
-#define AB8500_INT_GPIO10R		44
-#define AB8500_INT_GPIO11R		45
-#define AB8500_INT_GPIO12R		46 /* not 8505 */
-#define AB8500_INT_GPIO13R		47
+#define AB8500_INT_GPIO6R		40 /* not 8505/9540/8540 */
+#define AB8500_INT_GPIO7R		41 /* not 8505/9540/8540 */
+#define AB8500_INT_GPIO8R		42 /* not 8505/9540/8540 */
+#define AB8500_INT_GPIO9R		43 /* not 8505/9540/8540 */
+#define AB8500_INT_GPIO10R		44 /* not 8540 */
+#define AB8500_INT_GPIO11R		45 /* not 8540 */
+#define AB8500_INT_GPIO12R		46 /* not 8505/8540 */
+#define AB8500_INT_GPIO13R		47 /* not 8540 */
 /* ab8500_irq_regoffset[6] -> IT[Source|Latch|Mask]8 */
-#define AB8500_INT_GPIO24R		48 /* not 8505 */
-#define AB8500_INT_GPIO25R		49 /* not 8505 */
-#define AB8500_INT_GPIO36R		50 /* not 8505/9540 */
-#define AB8500_INT_GPIO37R		51 /* not 8505/9540 */
-#define AB8500_INT_GPIO38R		52 /* not 8505/9540 */
-#define AB8500_INT_GPIO39R		53 /* not 8505/9540 */
-#define AB8500_INT_GPIO40R		54
-#define AB8500_INT_GPIO41R		55
+#define AB8500_INT_GPIO24R		48 /* not 8505/8540 */
+#define AB8500_INT_GPIO25R		49 /* not 8505/8540 */
+#define AB8500_INT_GPIO36R		50 /* not 8505/9540/8540 */
+#define AB8500_INT_GPIO37R		51 /* not 8505/9540/8540 */
+#define AB8500_INT_GPIO38R		52 /* not 8505/9540/8540 */
+#define AB8500_INT_GPIO39R		53 /* not 8505/9540/8540 */
+#define AB8500_INT_GPIO40R		54 /* not 8540 */
+#define AB8500_INT_GPIO41R		55 /* not 8540 */
 /* ab8500_irq_regoffset[7] -> IT[Source|Latch|Mask]9 */
 #define AB8500_INT_GPIO6F		56 /* not 8505/9540 */
 #define AB8500_INT_GPIO7F		57 /* not 8505/9540 */
@@ -135,14 +139,14 @@
 #define AB8500_INT_GPIO12F		62 /* not 8505 */
 #define AB8500_INT_GPIO13F		63
 /* ab8500_irq_regoffset[8] -> IT[Source|Latch|Mask]10 */
-#define AB8500_INT_GPIO24F		64 /* not 8505 */
-#define AB8500_INT_GPIO25F		65 /* not 8505 */
-#define AB8500_INT_GPIO36F		66 /* not 8505/9540 */
-#define AB8500_INT_GPIO37F		67 /* not 8505/9540 */
-#define AB8500_INT_GPIO38F		68 /* not 8505/9540 */
-#define AB8500_INT_GPIO39F		69 /* not 8505/9540 */
-#define AB8500_INT_GPIO40F		70
-#define AB8500_INT_GPIO41F		71
+#define AB8500_INT_GPIO24F		64 /* not 8505/8540 */
+#define AB8500_INT_GPIO25F		65 /* not 8505/8540 */
+#define AB8500_INT_GPIO36F		66 /* not 8505/9540/8540 */
+#define AB8500_INT_GPIO37F		67 /* not 8505/9540/8540 */
+#define AB8500_INT_GPIO38F		68 /* not 8505/9540/8540 */
+#define AB8500_INT_GPIO39F		69 /* not 8505/9540/8540 */
+#define AB8500_INT_GPIO40F		70 /* not 8540 */
+#define AB8500_INT_GPIO41F		71 /* not 8540 */
 /* ab8500_irq_regoffset[9] -> IT[Source|Latch|Mask]12 */
 #define AB8500_INT_ADP_SOURCE_ERROR	72
 #define AB8500_INT_ADP_SINK_ERROR	73
@@ -160,42 +164,44 @@
 #define AB8500_INT_SRP_DETECT		88
 #define AB8500_INT_USB_CHARGER_NOT_OKR	89
 #define AB8500_INT_ID_WAKEUP_R		90
+#define AB8500_INT_ID_DET_PLUGR         91 /* 8505/9540 cut2.0 */
 #define AB8500_INT_ID_DET_R1R		92
 #define AB8500_INT_ID_DET_R2R		93
 #define AB8500_INT_ID_DET_R3R		94
 #define AB8500_INT_ID_DET_R4R		95
 /* ab8500_irq_regoffset[12] -> IT[Source|Latch|Mask]21 */
-#define AB8500_INT_ID_WAKEUP_F		96
-#define AB8500_INT_ID_DET_R1F		98
-#define AB8500_INT_ID_DET_R2F		99
-#define AB8500_INT_ID_DET_R3F		100
-#define AB8500_INT_ID_DET_R4F		101
-#define AB8500_INT_CHAUTORESTARTAFTSEC  102
+#define AB8500_INT_ID_WAKEUP_F		96 /* not 8505/9540 */
+#define AB8500_INT_ID_DET_PLUGF		97 /* 8505/9540 cut2.0 */
+#define AB8500_INT_ID_DET_R1F		98 /* not 8505/9540 */
+#define AB8500_INT_ID_DET_R2F		99 /* not 8505/9540 */
+#define AB8500_INT_ID_DET_R3F		100 /* not 8505/9540 */
+#define AB8500_INT_ID_DET_R4F		101 /* not 8505/9540 */
+#define AB8500_INT_CHAUTORESTARTAFTSEC	102 /* not 8505/9540 */
 #define AB8500_INT_CHSTOPBYSEC		103
 /* ab8500_irq_regoffset[13] -> IT[Source|Latch|Mask]22 */
 #define AB8500_INT_USB_CH_TH_PROT_F	104
-#define AB8500_INT_USB_CH_TH_PROT_R    105
+#define AB8500_INT_USB_CH_TH_PROT_R	105
 #define AB8500_INT_MAIN_CH_TH_PROT_F	106 /* not 8505/9540 */
 #define AB8500_INT_MAIN_CH_TH_PROT_R	107 /* not 8505/9540 */
 #define AB8500_INT_CHCURLIMNOHSCHIRP	109
 #define AB8500_INT_CHCURLIMHSCHIRP	110
 #define AB8500_INT_XTAL32K_KO		111
 
-/* Definitions for AB9540 */
+/* Definitions for AB9540 / AB8505 */
 /* ab8500_irq_regoffset[14] -> IT[Source|Latch|Mask]13 */
-#define AB9540_INT_GPIO50R		113
-#define AB9540_INT_GPIO51R		114 /* not 8505 */
-#define AB9540_INT_GPIO52R		115
-#define AB9540_INT_GPIO53R		116
-#define AB9540_INT_GPIO54R		117 /* not 8505 */
+#define AB9540_INT_GPIO50R		113 /* not 8540 */
+#define AB9540_INT_GPIO51R		114 /* not 8505/8540 */
+#define AB9540_INT_GPIO52R		115 /* not 8540 */
+#define AB9540_INT_GPIO53R		116 /* not 8540 */
+#define AB9540_INT_GPIO54R		117 /* not 8505/8540 */
 #define AB9540_INT_IEXT_CH_RF_BFN_R	118
-#define AB9540_INT_IEXT_CH_RF_BFN_F	119
 /* ab8500_irq_regoffset[15] -> IT[Source|Latch|Mask]14 */
-#define AB9540_INT_GPIO50F		121
-#define AB9540_INT_GPIO51F		122 /* not 8505 */
-#define AB9540_INT_GPIO52F		123
-#define AB9540_INT_GPIO53F		124
-#define AB9540_INT_GPIO54F		125 /* not 8505 */
+#define AB9540_INT_GPIO50F		121 /* not 8540 */
+#define AB9540_INT_GPIO51F		122 /* not 8505/8540 */
+#define AB9540_INT_GPIO52F		123 /* not 8540 */
+#define AB9540_INT_GPIO53F		124 /* not 8540 */
+#define AB9540_INT_GPIO54F		125 /* not 8505/8540 */
+#define AB9540_INT_IEXT_CH_RF_BFN_F	126
 /* ab8500_irq_regoffset[16] -> IT[Source|Latch|Mask]25 */
 #define AB8505_INT_KEYSTUCK		128
 #define AB8505_INT_IKR			129
@@ -204,6 +210,87 @@
 #define AB8505_INT_KEYDEGLITCH		132
 #define AB8505_INT_MODPWRSTATUSF	134
 #define AB8505_INT_MODPWRSTATUSR	135
+/* ab8500_irq_regoffset[17] -> IT[Source|Latch|Mask]6 */
+#define AB8500_INT_HOOK_DET_NEG_F	138
+#define AB8500_INT_HOOK_DET_NEG_R	139
+#define AB8500_INT_HOOK_DET_POS_F	140
+#define AB8500_INT_HOOK_DET_POS_R	141
+#define AB8500_INT_PLUG_DET_COMP_F	142
+#define AB8500_INT_PLUG_DET_COMP_R	143
+/* ab8500_irq_regoffset[18] -> IT[Source|Latch|Mask]23 */
+#define AB8505_INT_COLL			144
+#define AB8505_INT_RESERR		145
+#define AB8505_INT_FRAERR		146
+#define AB8505_INT_COMERR		147
+#define AB8505_INT_SPDSET		148
+#define AB8505_INT_DSENT		149
+#define AB8505_INT_DREC			150
+#define AB8505_INT_ACC_INT		151
+/* ab8500_irq_regoffset[19] -> IT[Source|Latch|Mask]24 */
+#define AB8505_INT_NOPINT		152
+/* ab8540_irq_regoffset[20] -> IT[Source|Latch|Mask]26 */
+#define AB8540_INT_IDPLUGDETCOMPF	160
+#define AB8540_INT_IDPLUGDETCOMPR	161
+#define AB8540_INT_FMDETCOMPLOF		162
+#define AB8540_INT_FMDETCOMPLOR		163
+#define AB8540_INT_FMDETCOMPHIF		164
+#define AB8540_INT_FMDETCOMPHIR		165
+#define AB8540_INT_ID5VDETCOMPF		166
+#define AB8540_INT_ID5VDETCOMPR		167
+/* ab8540_irq_regoffset[21] -> IT[Source|Latch|Mask]27 */
+#define AB8540_INT_GPIO43F		168
+#define AB8540_INT_GPIO43R		169
+#define AB8540_INT_GPIO44F		170
+#define AB8540_INT_GPIO44R		171
+#define AB8540_INT_KEYPOSDETCOMPF	172
+#define AB8540_INT_KEYPOSDETCOMPR	173
+#define AB8540_INT_KEYNEGDETCOMPF	174
+#define AB8540_INT_KEYNEGDETCOMPR	175
+/* ab8540_irq_regoffset[22] -> IT[Source|Latch|Mask]28 */
+#define AB8540_INT_GPIO1VBATF		176
+#define AB8540_INT_GPIO1VBATR		177
+#define AB8540_INT_GPIO2VBATF		178
+#define AB8540_INT_GPIO2VBATR		179
+#define AB8540_INT_GPIO3VBATF		180
+#define AB8540_INT_GPIO3VBATR		181
+#define AB8540_INT_GPIO4VBATF		182
+#define AB8540_INT_GPIO4VBATR		183
+/* ab8540_irq_regoffset[23] -> IT[Source|Latch|Mask]29 */
+#define AB8540_INT_SYSCLKREQ2F		184
+#define AB8540_INT_SYSCLKREQ2R		185
+#define AB8540_INT_SYSCLKREQ3F		186
+#define AB8540_INT_SYSCLKREQ3R		187
+#define AB8540_INT_SYSCLKREQ4F		188
+#define AB8540_INT_SYSCLKREQ4R		189
+#define AB8540_INT_SYSCLKREQ5F		190
+#define AB8540_INT_SYSCLKREQ5R		191
+/* ab8540_irq_regoffset[24] -> IT[Source|Latch|Mask]30 */
+#define AB8540_INT_PWMOUT1F		192
+#define AB8540_INT_PWMOUT1R		193
+#define AB8540_INT_PWMCTRL0F		194
+#define AB8540_INT_PWMCTRL0R		195
+#define AB8540_INT_PWMCTRL1F		196
+#define AB8540_INT_PWMCTRL1R		197
+#define AB8540_INT_SYSCLKREQ6F		198
+#define AB8540_INT_SYSCLKREQ6R		199
+/* ab8540_irq_regoffset[25] -> IT[Source|Latch|Mask]31 */
+#define AB8540_INT_PWMEXTVIBRA1F	200
+#define AB8540_INT_PWMEXTVIBRA1R	201
+#define AB8540_INT_PWMEXTVIBRA2F	202
+#define AB8540_INT_PWMEXTVIBRA2R	203
+#define AB8540_INT_PWMOUT2F		204
+#define AB8540_INT_PWMOUT2R		205
+#define AB8540_INT_PWMOUT3F		206
+#define AB8540_INT_PWMOUT3R		207
+/* ab8540_irq_regoffset[26] -> IT[Source|Latch|Mask]32 */
+#define AB8540_INT_ADDATA2F		208
+#define AB8540_INT_ADDATA2R		209
+#define AB8540_INT_DADATA2F		210
+#define AB8540_INT_DADATA2R		211
+#define AB8540_INT_FSYNC2F		212
+#define AB8540_INT_FSYNC2R		213
+#define AB8540_INT_BITCLK2F		214
+#define AB8540_INT_BITCLK2R		215
 
 /*
  * AB8500_AB9540_NR_IRQS is used when configuring the IRQ numbers for the
@@ -213,13 +300,24 @@
  * which is larger.
  */
 #define AB8500_NR_IRQS			112
-#define AB8505_NR_IRQS			136
-#define AB9540_NR_IRQS			136
+#define AB8505_NR_IRQS			153
+#define AB9540_NR_IRQS			153
+#define AB8540_NR_IRQS			216
 /* This is set to the roof of any AB8500 chip variant IRQ counts */
-#define AB8500_MAX_NR_IRQS		AB9540_NR_IRQS
+#define AB8500_MAX_NR_IRQS		AB8540_NR_IRQS
 
 #define AB8500_NUM_IRQ_REGS		14
-#define AB9540_NUM_IRQ_REGS		17
+#define AB9540_NUM_IRQ_REGS		20
+#define AB8540_NUM_IRQ_REGS		27
+
+/* Turn On Status Event */
+#define AB8500_POR_ON_VBAT		0x01
+#define AB8500_POW_KEY_1_ON		0x02
+#define AB8500_POW_KEY_2_ON		0x04
+#define AB8500_RTC_ALARM		0x08
+#define AB8500_MAIN_CH_DET		0x10
+#define AB8500_VBUS_DET			0x20
+#define AB8500_USB_ID_DET		0x40
 
 /**
  * struct ab8500 - ab8500 internal structure
@@ -287,7 +385,7 @@
 	struct ab8500_regulator_reg_init *regulator_reg_init;
 	int num_regulator;
 	struct regulator_init_data *regulator;
-	struct ab8500_gpio_platform_data *gpio;
+	struct abx500_gpio_platform_data *gpio;
 	struct ab8500_codec_platform_data *codec;
 };
 
@@ -335,10 +433,79 @@
 	return (is_ab8500(ab) && (ab->chip_id <= AB8500_CUT2P0));
 }
 
+static inline int is_ab8500_3p3_or_earlier(struct ab8500 *ab)
+{
+	return (is_ab8500(ab) && (ab->chip_id <= AB8500_CUT3P3));
+}
+
 /* exclude also ab8505, ab9540... */
 static inline int is_ab8500_2p0(struct ab8500 *ab)
 {
 	return (is_ab8500(ab) && (ab->chip_id == AB8500_CUT2P0));
 }
 
+static inline int is_ab8505_1p0_or_earlier(struct ab8500 *ab)
+{
+	return (is_ab8505(ab) && (ab->chip_id <= AB8500_CUT1P0));
+}
+
+static inline int is_ab8505_2p0(struct ab8500 *ab)
+{
+	return (is_ab8505(ab) && (ab->chip_id == AB8500_CUT2P0));
+}
+
+static inline int is_ab9540_1p0_or_earlier(struct ab8500 *ab)
+{
+	return (is_ab9540(ab) && (ab->chip_id <= AB8500_CUT1P0));
+}
+
+static inline int is_ab9540_2p0(struct ab8500 *ab)
+{
+	return (is_ab9540(ab) && (ab->chip_id == AB8500_CUT2P0));
+}
+
+/*
+ * Be careful, the marketing name for this chip is 2.1
+ * but the value read from the chip is 3.0 (0x30)
+ */
+static inline int is_ab9540_3p0(struct ab8500 *ab)
+{
+	return (is_ab9540(ab) && (ab->chip_id == AB8500_CUT3P0));
+}
+
+static inline int is_ab8540_1p0_or_earlier(struct ab8500 *ab)
+{
+	return is_ab8540(ab) && (ab->chip_id <= AB8500_CUT1P0);
+}
+
+static inline int is_ab8540_1p1_or_earlier(struct ab8500 *ab)
+{
+	return is_ab8540(ab) && (ab->chip_id <= AB8500_CUT1P1);
+}
+
+static inline int is_ab8540_1p2_or_earlier(struct ab8500 *ab)
+{
+	return is_ab8540(ab) && (ab->chip_id <= AB8500_CUT1P2);
+}
+
+static inline int is_ab8540_2p0_or_earlier(struct ab8500 *ab)
+{
+	return is_ab8540(ab) && (ab->chip_id <= AB8500_CUT2P0);
+}
+
+static inline int is_ab8540_2p0(struct ab8500 *ab)
+{
+	return is_ab8540(ab) && (ab->chip_id == AB8500_CUT2P0);
+}
+
+static inline int is_ab8505_2p0_earlier(struct ab8500 *ab)
+{
+	return (is_ab8505(ab) && (ab->chip_id < AB8500_CUT2P0));
+}
+
+static inline int is_ab9540_2p0_or_earlier(struct ab8500 *ab)
+{
+	return (is_ab9540(ab) && (ab->chip_id < AB8500_CUT2P0));
+}
+
 #endif /* MFD_AB8500_H */
diff --git a/include/linux/pinctrl/devinfo.h b/include/linux/pinctrl/devinfo.h
new file mode 100644
index 0000000..6e5f8a9
--- /dev/null
+++ b/include/linux/pinctrl/devinfo.h
@@ -0,0 +1,45 @@
+/*
+ * Per-device information from the pin control system.
+ * This is the stuff that get included into the device
+ * core.
+ *
+ * Copyright (C) 2012 ST-Ericsson SA
+ * Written on behalf of Linaro for ST-Ericsson
+ * This interface is used in the core to keep track of pins.
+ *
+ * Author: Linus Walleij <linus.walleij@linaro.org>
+ *
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#ifndef PINCTRL_DEVINFO_H
+#define PINCTRL_DEVINFO_H
+
+#ifdef CONFIG_PINCTRL
+
+/* The device core acts as a consumer toward pinctrl */
+#include <linux/pinctrl/consumer.h>
+
+/**
+ * struct dev_pin_info - pin state container for devices
+ * @p: pinctrl handle for the containing device
+ * @default_state: the default state for the handle, if found
+ */
+struct dev_pin_info {
+	struct pinctrl *p;
+	struct pinctrl_state *default_state;
+};
+
+extern int pinctrl_bind_pins(struct device *dev);
+
+#else
+
+/* Stubs if we're not using pinctrl */
+
+static inline int pinctrl_bind_pins(struct device *dev)
+{
+	return 0;
+}
+
+#endif /* CONFIG_PINCTRL */
+#endif /* PINCTRL_DEVINFO_H */
diff --git a/include/linux/pinctrl/pinconf-generic.h b/include/linux/pinctrl/pinconf-generic.h
index 47a1bdd..72474e1 100644
--- a/include/linux/pinctrl/pinconf-generic.h
+++ b/include/linux/pinctrl/pinconf-generic.h
@@ -46,7 +46,11 @@
  * @PIN_CONFIG_DRIVE_OPEN_SOURCE: the pin will be driven with open source
  *	(open emitter). Sending this config will enabale open drain mode, the
  *	argument is ignored.
- * @PIN_CONFIG_INPUT_SCHMITT_DISABLE: disable schmitt-trigger mode on the pin.
+ * @PIN_CONFIG_DRIVE_STRENGTH: the pin will output the current passed as
+ * 	argument. The argument is in mA.
+ * @PIN_CONFIG_INPUT_SCHMITT_ENABLE: control schmitt-trigger mode on the pin.
+ *      If the argument != 0, schmitt-trigger mode is enabled. If it's 0,
+ *      schmitt-trigger mode is disabled.
  * @PIN_CONFIG_INPUT_SCHMITT: this will configure an input pin to run in
  *	schmitt-trigger mode. If the schmitt-trigger has adjustable hysteresis,
  *	the threshold value is given on a custom format as argument when
@@ -58,10 +62,15 @@
  * @PIN_CONFIG_POWER_SOURCE: if the pin can select between different power
  *	supplies, the argument to this parameter (on a custom format) tells
  *	the driver which alternative power source to use.
+ * @PIN_CONFIG_SLEW_RATE: if the pin can select slew rate, the argument to
+ * 	this parameter (on a custom format) tells the driver which alternative
+ * 	slew rate to use.
  * @PIN_CONFIG_LOW_POWER_MODE: this will configure the pin for low power
  *	operation, if several modes of operation are supported these can be
  *	passed in the argument on a custom form, else just use argument 1
  *	to indicate low power mode, argument 0 turns low power mode off.
+ * @PIN_CONFIG_OUTPUT: this will configure the pin in output, use argument
+ *	1 to indicate high level, argument 0 to indicate low level.
  * @PIN_CONFIG_END: this is the last enumerator for pin configurations, if
  *	you need to pass in custom configurations to the pin controller, use
  *	PIN_CONFIG_END+1 as the base offset.
@@ -74,11 +83,14 @@
 	PIN_CONFIG_DRIVE_PUSH_PULL,
 	PIN_CONFIG_DRIVE_OPEN_DRAIN,
 	PIN_CONFIG_DRIVE_OPEN_SOURCE,
-	PIN_CONFIG_INPUT_SCHMITT_DISABLE,
+	PIN_CONFIG_DRIVE_STRENGTH,
+	PIN_CONFIG_INPUT_SCHMITT_ENABLE,
 	PIN_CONFIG_INPUT_SCHMITT,
 	PIN_CONFIG_INPUT_DEBOUNCE,
 	PIN_CONFIG_POWER_SOURCE,
+	PIN_CONFIG_SLEW_RATE,
 	PIN_CONFIG_LOW_POWER_MODE,
+	PIN_CONFIG_OUTPUT,
 	PIN_CONFIG_END = 0x7FFF,
 };
 
diff --git a/include/linux/pinctrl/pinctrl.h b/include/linux/pinctrl/pinctrl.h
index 04d6700..778804d 100644
--- a/include/linux/pinctrl/pinctrl.h
+++ b/include/linux/pinctrl/pinctrl.h
@@ -154,6 +154,7 @@
 #endif /* CONFIG_OF */
 
 extern const char *pinctrl_dev_get_name(struct pinctrl_dev *pctldev);
+extern const char *pinctrl_dev_get_devname(struct pinctrl_dev *pctldev);
 extern void *pinctrl_dev_get_drvdata(struct pinctrl_dev *pctldev);
 #else