[source] brcm63xx: add pinctrl support

LEDE Commits lede-commits at lists.infradead.org
Sun Jun 11 03:01:43 PDT 2017


jogo pushed a commit to source.git, branch master:
https://git.lede-project.org/0755c2d117060a252674191b98bc852ccd8840fe

commit 0755c2d117060a252674191b98bc852ccd8840fe
Author: Jonas Gorski <jonas.gorski at gmail.com>
AuthorDate: Fri Jul 1 11:23:06 2016 +0200

    brcm63xx: add pinctrl support
    
    Add and enable pincontrol drivers, and update dts(i) files with
    appropriate hogs.
    
    Signed-off-by: Jonas Gorski <jonas.gorski at gmail.com>
---
 target/linux/brcm63xx/config-4.4                   |  13 +
 target/linux/brcm63xx/dts/a226g.dts                |  30 +-
 target/linux/brcm63xx/dts/a226m-fwb.dts            |  30 +-
 target/linux/brcm63xx/dts/a226m.dts                |  30 +-
 target/linux/brcm63xx/dts/a4001n.dts               |  14 +-
 target/linux/brcm63xx/dts/a4001n1.dts              |  28 +-
 target/linux/brcm63xx/dts/agpf-s0.dts              |  32 +-
 target/linux/brcm63xx/dts/ar-5381u.dts             |   8 +-
 target/linux/brcm63xx/dts/ar-5387un.dts            |  12 +-
 target/linux/brcm63xx/dts/ar1004g.dts              |  13 +-
 target/linux/brcm63xx/dts/av4202n.dts              |  18 +-
 target/linux/brcm63xx/dts/bcm6318.dtsi             | 118 +++-
 target/linux/brcm63xx/dts/bcm63268.dtsi            | 137 +++-
 target/linux/brcm63xx/dts/bcm6328.dtsi             |  89 ++-
 target/linux/brcm63xx/dts/bcm6348.dtsi             |  64 +-
 target/linux/brcm63xx/dts/bcm6358.dtsi             |  72 +-
 target/linux/brcm63xx/dts/bcm6362.dtsi             | 178 ++++-
 target/linux/brcm63xx/dts/bcm6368.dtsi             | 189 +++++-
 target/linux/brcm63xx/dts/bcm96318ref.dts          |  15 +-
 target/linux/brcm63xx/dts/bcm96318ref_p300.dts     |  17 +-
 target/linux/brcm63xx/dts/bcm963268bu_p300.dts     |   4 +-
 target/linux/brcm63xx/dts/bcm963269bhr.dts         |   6 +-
 target/linux/brcm63xx/dts/bcm963281TAN.dts         |  12 +-
 target/linux/brcm63xx/dts/bcm96328avng.dts         |  17 +-
 target/linux/brcm63xx/dts/bcm96348GW-10.dts        |  17 +-
 target/linux/brcm63xx/dts/bcm96348GW-11.dts        |  17 +-
 target/linux/brcm63xx/dts/bcm96348GW.dts           |  17 +-
 target/linux/brcm63xx/dts/bcm96348R.dts            |  15 +-
 target/linux/brcm63xx/dts/bcm96358VW.dts           |  10 +-
 target/linux/brcm63xx/dts/bcm96358VW2.dts          |   8 +-
 target/linux/brcm63xx/dts/bcm96368MVNgr.dts        |  15 +-
 target/linux/brcm63xx/dts/bcm96368MVWG.dts         |  15 +-
 target/linux/brcm63xx/dts/cpva502plus.dts          |  11 +-
 target/linux/brcm63xx/dts/cpva642.dts              |  24 +-
 target/linux/brcm63xx/dts/ct-5365.dts              |  17 +-
 target/linux/brcm63xx/dts/ct-6373.dts              |  12 +-
 target/linux/brcm63xx/dts/ct536plus.dts            |  11 +-
 target/linux/brcm63xx/dts/dg834g_v4.dts            |  15 +-
 target/linux/brcm63xx/dts/dg834gtpn.dts            |  17 +-
 target/linux/brcm63xx/dts/dgnd3700v1.dts           |  33 +-
 target/linux/brcm63xx/dts/dsl-2640b-b.dts          |  15 +-
 target/linux/brcm63xx/dts/dsl-2650u.dts            |   8 +-
 target/linux/brcm63xx/dts/dsl-274xb-c.dts          |  12 +-
 target/linux/brcm63xx/dts/dsl-274xb-f.dts          |  18 +-
 target/linux/brcm63xx/dts/dsl-275xb-d.dts          |  20 +-
 target/linux/brcm63xx/dts/dv-201amr.dts            |   5 +
 target/linux/brcm63xx/dts/dva-g3810bn_tl.dts       |  12 +-
 target/linux/brcm63xx/dts/evg2000.dts              |  29 +-
 target/linux/brcm63xx/dts/f5d7633.dts              |  17 +-
 target/linux/brcm63xx/dts/fast2404.dts             |   5 +
 target/linux/brcm63xx/dts/fast2504n.dts            |  16 +-
 target/linux/brcm63xx/dts/fast2604.dts             |  15 +-
 target/linux/brcm63xx/dts/fast2704n.dts            |  28 +-
 target/linux/brcm63xx/dts/fast2704v2.dts           |  20 +-
 target/linux/brcm63xx/dts/gw6000.dts               |   7 +-
 target/linux/brcm63xx/dts/gw6200.dts               |  15 +-
 target/linux/brcm63xx/dts/hg520v.dts               |   4 +-
 target/linux/brcm63xx/dts/hg553.dts                |  22 +-
 target/linux/brcm63xx/dts/hg556a-a.dts             |  34 +-
 target/linux/brcm63xx/dts/hg556a-b.dts             |  34 +-
 target/linux/brcm63xx/dts/hg556a-c.dts             |  32 +-
 target/linux/brcm63xx/dts/hg622.dts                |  17 +-
 target/linux/brcm63xx/dts/hg655b.dts               |  25 +-
 target/linux/brcm63xx/dts/homehub2a.dts            |  12 +-
 target/linux/brcm63xx/dts/livebox-blue-5g.dts      |  19 +-
 target/linux/brcm63xx/dts/magic.dts                |  19 +-
 target/linux/brcm63xx/dts/nb4-fxc-r1.dts           |  22 +-
 target/linux/brcm63xx/dts/nb4-ser-r0.dts           |  22 +-
 target/linux/brcm63xx/dts/nb6-ser-r0.dts           |  12 +-
 target/linux/brcm63xx/dts/p870hw-51a-v2.dts        |  19 +-
 target/linux/brcm63xx/dts/r5010unv2.dts            |  18 +-
 target/linux/brcm63xx/dts/rg100a.dts               |   8 +-
 target/linux/brcm63xx/dts/rta1025w.dts             |   5 +
 target/linux/brcm63xx/dts/spw303v.dts              |  16 +-
 target/linux/brcm63xx/dts/spw500v.dts              |  17 +-
 target/linux/brcm63xx/dts/td-w8900gb.dts           |  17 +-
 target/linux/brcm63xx/dts/usr9108.dts              |   9 +-
 target/linux/brcm63xx/dts/v2110.dts                |  17 +-
 target/linux/brcm63xx/dts/v2500v-bb.dts            |  17 +-
 target/linux/brcm63xx/dts/vg50.dts                 |   4 +-
 target/linux/brcm63xx/dts/vh4032n.dts              |  22 +-
 target/linux/brcm63xx/dts/vr-3025u.dts             |  18 +-
 target/linux/brcm63xx/dts/vr-3025un.dts            |  18 +-
 target/linux/brcm63xx/dts/vr-3026e.dts             |  18 +-
 target/linux/brcm63xx/dts/wap-5813n.dts            |  21 +-
 ...vm_-apis-for-gpiochip_add_data-and-gpioch.patch | 115 ++++
 ...-devm_-apis-for-pinctrl_-register-unregis.patch | 108 +++
 ...ame-pinctrl_utils_dt_free_map-to-pinctrl_.patch |  59 ++
 .../130-pinctrl-add-bcm63xx-base-code.patch        | 226 +++++++
 ...on-add-BCM6328-pincontroller-binding-docu.patch |  78 +++
 ...nctrl-add-a-pincontrol-driver-for-BCM6328.patch | 495 ++++++++++++++
 ...on-add-BCM6348-pincontroller-binding-docu.patch |  49 ++
 ...nctrl-add-a-pincontrol-driver-for-BCM6348.patch | 432 ++++++++++++
 ...on-add-BCM6358-pincontroller-binding-docu.patch |  61 ++
 ...nctrl-add-a-pincontrol-driver-for-BCM6358.patch | 436 ++++++++++++
 ...on-add-BCM6362-pincontroller-binding-docu.patch |  96 +++
 ...nctrl-add-a-pincontrol-driver-for-BCM6362.patch | 733 ++++++++++++++++++++
 ...on-add-BCM6368-pincontroller-binding-docu.patch |  84 +++
 ...nctrl-add-a-pincontrol-driver-for-BCM6368.patch | 620 +++++++++++++++++
 ...on-add-BCM63268-pincontroller-binding-doc.patch | 106 +++
 ...ctrl-add-a-pincontrol-driver-for-BCM63268.patch | 736 +++++++++++++++++++++
 ...X-do-not-register-gpio-controller-if-pres.patch |   5 +-
 ...on-add-BCM6318-pincontroller-binding-docu.patch |  96 +++
 ...tup-pinctrl-for-internal-switch-leds-on-b.patch |  27 -
 ...nctrl-add-a-pincontrol-driver-for-BCM6318.patch | 609 +++++++++++++++++
 .../patches-4.4/383-bcm63xx_select_pinctrl.patch   |  65 ++
 ...S-BCM63XX-do-not-register-SPI-controllers.patch |   2 +-
 .../403-6358-enet1-external-mii-clk.patch          |   2 +-
 ...-allow-providing-fixup-data-in-board-data.patch |   4 +-
 .../420-BCM63XX-add-endian-check-for-ath9k.patch   |   2 +-
 .../421-BCM63XX-add-led-pin-for-ath9k.patch        |   2 +-
 ...22-BCM63XX-add-a-fixup-for-rt2x00-devices.patch |   2 +-
 112 files changed, 6728 insertions(+), 682 deletions(-)

diff --git a/target/linux/brcm63xx/config-4.4 b/target/linux/brcm63xx/config-4.4
index 2cd3fcb..337c14c 100644
--- a/target/linux/brcm63xx/config-4.4
+++ b/target/linux/brcm63xx/config-4.4
@@ -75,6 +75,7 @@ CONFIG_GENERIC_IO=y
 CONFIG_GENERIC_IRQ_CHIP=y
 CONFIG_GENERIC_IRQ_SHOW=y
 CONFIG_GENERIC_PCI_IOMAP=y
+CONFIG_GENERIC_PINCONF=y
 CONFIG_GENERIC_SCHED_CLOCK=y
 CONFIG_GENERIC_SMP_IDLE_THREAD=y
 CONFIG_GENERIC_TIME_VSYSCALL=y
@@ -141,6 +142,7 @@ CONFIG_KEXEC_CORE=y
 CONFIG_LEDS_GPIO=y
 CONFIG_LIBFDT=y
 CONFIG_MDIO_BOARDINFO=y
+CONFIG_MFD_SYSCON=y
 CONFIG_MIPS=y
 CONFIG_MIPS_CLOCK_VSYSCALL=y
 # CONFIG_MIPS_CMDLINE_DTB_EXTEND is not set
@@ -193,9 +195,20 @@ CONFIG_PCI_DOMAINS=y
 CONFIG_PERF_USE_VMALLOC=y
 CONFIG_PGTABLE_LEVELS=2
 CONFIG_PHYLIB=y
+CONFIG_PINCTRL=y
+CONFIG_PINCTRL_BCM6318=y
+CONFIG_PINCTRL_BCM63268=y
+CONFIG_PINCTRL_BCM6328=y
+CONFIG_PINCTRL_BCM6348=y
+CONFIG_PINCTRL_BCM6358=y
+CONFIG_PINCTRL_BCM6362=y
+CONFIG_PINCTRL_BCM6368=y
+CONFIG_PINCTRL_BCM63XX=y
 CONFIG_POSIX_MQUEUE=y
 CONFIG_POSIX_MQUEUE_SYSCTL=y
 # CONFIG_RCU_STALL_COMMON is not set
+CONFIG_REGMAP=y
+CONFIG_REGMAP_MMIO=y
 CONFIG_RELAY=y
 CONFIG_RTL8366_SMI=y
 CONFIG_RTL8367_PHY=y
diff --git a/target/linux/brcm63xx/dts/a226g.dts b/target/linux/brcm63xx/dts/a226g.dts
index dc24e5a..f7a0b72 100644
--- a/target/linux/brcm63xx/dts/a226g.dts
+++ b/target/linux/brcm63xx/dts/a226g.dts
@@ -21,12 +21,12 @@
 
 		wps {
 			label = "wps";
-			gpios = <&gpio1 2 1>;
+			gpios = <&pinctrl 34 1>;
 			linux,code = <KEY_WPS_BUTTON>;
 		};
 		reset {
 			label = "reset";
-			gpios = <&gpio1 5 1>;
+			gpios = <&pinctrl 37 1>;
 			linux,code = <KEY_RESTART>;
 		};
 	};
@@ -36,56 +36,56 @@
 
 		voip_red {
 			label = "DWV-S0:red:VoIP";
-			gpios = <&gpio0 0 1>;
+			gpios = <&pinctrl 0 1>;
 		};
 		eth_red {
 			label = "DWV-S0:red:ethernet";
-			gpios = <&gpio0 1 1>;
+			gpios = <&pinctrl 1 1>;
 		};
 		dsl_green {
 			label = "DWV-S0:green:ADSL";
-			gpios = <&gpio0 2 1>;
+			gpios = <&pinctrl 2 1>;
 		};
 		usb_green {
 			label = "DWV-S0:green:USB";
-			gpios = <&gpio0 3 1>;
+			gpios = <&pinctrl 3 1>;
 		};
 		power_green {
 			label = "DWV-S0:green:power";
-			gpios = <&gpio0 4 1>;
+			gpios = <&pinctrl 4 1>;
 			default-state = "on";
 		};
 		power_red {
 			label = "DWV-S0:red:power";
-			gpios = <&gpio0 5 1>;
+			gpios = <&pinctrl 5 1>;
 		};
 		inet_red {
 			label = "DWV-S0:red:internet";
-			gpios = <&gpio0 6 1>;
+			gpios = <&pinctrl 6 1>;
 		};
 		inet_green {
 			label = "DWV-S0:green:internet";
-			gpios = <&gpio0 7 1>;
+			gpios = <&pinctrl 7 1>;
 		};
 		eth_green {
 			label = "DWV-S0:green:ethernet";
-			gpios = <&gpio0 8 1>;
+			gpios = <&pinctrl 8 1>;
 		};
 		voip_green {
 			label = "DWV-S0:green:VoIP";
-			gpios = <&gpio0 9 1>;
+			gpios = <&pinctrl 9 1>;
 		};
 		wifi_red {
 			label = "DWV-S0:red:wifi";
-			gpios = <&gpio0 10 1>;
+			gpios = <&pinctrl 10 1>;
 		};
 		usb_red {
 			label = "DWV-S0:red:USB";
-			gpios = <&gpio0 11 1>;
+			gpios = <&pinctrl 11 1>;
 		};
 		dsl_red {
 			label = "DWV-S0:red:ADSL";
-			gpios = <&gpio0 12 1>;
+			gpios = <&pinctrl 12 1>;
 		};
 	};
 };
diff --git a/target/linux/brcm63xx/dts/a226m-fwb.dts b/target/linux/brcm63xx/dts/a226m-fwb.dts
index ced66dd..43a82bb 100644
--- a/target/linux/brcm63xx/dts/a226m-fwb.dts
+++ b/target/linux/brcm63xx/dts/a226m-fwb.dts
@@ -21,12 +21,12 @@
 
 		wps {
 			label = "wps";
-			gpios = <&gpio1 2 1>;
+			gpios = <&pinctrl 34 1>;
 			linux,code = <KEY_WPS_BUTTON>;
 		};
 		reset {
 			label = "reset";
-			gpios = <&gpio1 5 1>;
+			gpios = <&pinctrl 37 1>;
 			linux,code = <KEY_RESTART>;
 		};
 	};
@@ -36,56 +36,56 @@
 
 		voip_red {
 			label = "DWV-S0:red:VoIP";
-			gpios = <&gpio0 0 1>;
+			gpios = <&pinctrl 0 1>;
 		};
 		eth_red {
 			label = "DWV-S0:red:ethernet";
-			gpios = <&gpio0 1 1>;
+			gpios = <&pinctrl 1 1>;
 		};
 		dsl_green {
 			label = "DWV-S0:green:ADSL";
-			gpios = <&gpio0 2 1>;
+			gpios = <&pinctrl 2 1>;
 		};
 		usb_green {
 			label = "DWV-S0:green:USB";
-			gpios = <&gpio0 3 1>;
+			gpios = <&pinctrl 3 1>;
 		};
 		power_green {
 			label = "DWV-S0:green:power";
-			gpios = <&gpio0 4 1>;
+			gpios = <&pinctrl 4 1>;
 			default-state = "on";
 		};
 		power_red {
 			label = "DWV-S0:red:power";
-			gpios = <&gpio0 5 1>;
+			gpios = <&pinctrl 5 1>;
 		};
 		inet_red {
 			label = "DWV-S0:red:internet";
-			gpios = <&gpio0 6 1>;
+			gpios = <&pinctrl 6 1>;
 		};
 		inet_green {
 			label = "DWV-S0:green:internet";
-			gpios = <&gpio0 7 1>;
+			gpios = <&pinctrl 7 1>;
 		};
 		eth_green {
 			label = "DWV-S0:green:ethernet";
-			gpios = <&gpio0 8 1>;
+			gpios = <&pinctrl 8 1>;
 		};
 		voip_green {
 			label = "DWV-S0:green:VoIP";
-			gpios = <&gpio0 9 1>;
+			gpios = <&pinctrl 9 1>;
 		};
 		wifi_red {
 			label = "DWV-S0:red:wifi";
-			gpios = <&gpio0 10 1>;
+			gpios = <&pinctrl 10 1>;
 		};
 		usb_red {
 			label = "DWV-S0:red:USB";
-			gpios = <&gpio0 11 1>;
+			gpios = <&pinctrl 11 1>;
 		};
 		dsl_red {
 			label = "DWV-S0:red:ADSL";
-			gpios = <&gpio0 12 1>;
+			gpios = <&pinctrl 12 1>;
 		};
 	};
 };
diff --git a/target/linux/brcm63xx/dts/a226m.dts b/target/linux/brcm63xx/dts/a226m.dts
index 9a9ec1e..269c4ed 100644
--- a/target/linux/brcm63xx/dts/a226m.dts
+++ b/target/linux/brcm63xx/dts/a226m.dts
@@ -21,12 +21,12 @@
 
 		wps {
 			label = "wps";
-			gpios = <&gpio1 2 1>;
+			gpios = <&pinctrl 34 1>;
 			linux,code = <KEY_WPS_BUTTON>;
 		};
 		reset {
 			label = "reset";
-			gpios = <&gpio1 5 1>;
+			gpios = <&pinctrl 37 1>;
 			linux,code = <KEY_RESTART>;
 		};
 	};
@@ -36,56 +36,56 @@
 
 		voip_red {
 			label = "DWV-S0:red:VoIP";
-			gpios = <&gpio0 0 1>;
+			gpios = <&pinctrl 0 1>;
 		};
 		eth_red {
 			label = "DWV-S0:red:ethernet";
-			gpios = <&gpio0 1 1>;
+			gpios = <&pinctrl 1 1>;
 		};
 		dsl_green {
 			label = "DWV-S0:green:ADSL";
-			gpios = <&gpio0 2 1>;
+			gpios = <&pinctrl 2 1>;
 		};
 		usb_green {
 			label = "DWV-S0:green:USB";
-			gpios = <&gpio0 3 1>;
+			gpios = <&pinctrl 3 1>;
 		};
 		power_green {
 			label = "DWV-S0:green:power";
-			gpios = <&gpio0 4 1>;
+			gpios = <&pinctrl 4 1>;
 			default-state = "on";
 		};
 		power_red {
 			label = "DWV-S0:red:power";
-			gpios = <&gpio0 5 1>;
+			gpios = <&pinctrl 5 1>;
 		};
 		inet_red {
 			label = "DWV-S0:red:internet";
-			gpios = <&gpio0 6 1>;
+			gpios = <&pinctrl 6 1>;
 		};
 		inet_green {
 			label = "DWV-S0:green:internet";
-			gpios = <&gpio0 7 1>;
+			gpios = <&pinctrl 7 1>;
 		};
 		eth_green {
 			label = "DWV-S0:green:ethernet";
-			gpios = <&gpio0 8 1>;
+			gpios = <&pinctrl 8 1>;
 		};
 		voip_green {
 			label = "DWV-S0:green:VoIP";
-			gpios = <&gpio0 9 1>;
+			gpios = <&pinctrl 9 1>;
 		};
 		wifi_red {
 			label = "DWV-S0:red:wifi";
-			gpios = <&gpio0 10 1>;
+			gpios = <&pinctrl 10 1>;
 		};
 		usb_red {
 			label = "DWV-S0:red:USB";
-			gpios = <&gpio0 11 1>;
+			gpios = <&pinctrl 11 1>;
 		};
 		dsl_red {
 			label = "DWV-S0:red:ADSL";
-			gpios = <&gpio0 12 1>;
+			gpios = <&pinctrl 12 1>;
 		};
 	};
 };
diff --git a/target/linux/brcm63xx/dts/a4001n.dts b/target/linux/brcm63xx/dts/a4001n.dts
index 70eb8ce..d29b834 100644
--- a/target/linux/brcm63xx/dts/a4001n.dts
+++ b/target/linux/brcm63xx/dts/a4001n.dts
@@ -21,12 +21,12 @@
 
 		reset {
 			label = "reset";
-			gpios = <&gpio0 23 1>;
+			gpios = <&pinctrl 23 1>;
 			linux,code = <KEY_RESTART>;
 		};
 		wps {
 			label = "wps";
-			gpios = <&gpio0 24 1>;
+			gpios = <&pinctrl 24 1>;
 			linux,code = <KEY_WPS_BUTTON>;
 		};
 	};
@@ -36,24 +36,24 @@
 
 		inet_red {
 			label = "A4001N:red:inet";
-			gpios = <&gpio0 1 0>;
+			gpios = <&pinctrl 1 0>;
 		};
 		power_red {
 			label = "A4001N:red:power";
-			gpios = <&gpio0 4 0>;
+			gpios = <&pinctrl 4 0>;
 		};
 		power_green {
 			label = "A4001N:green:power";
-			gpios = <&gpio0 8 0>;
+			gpios = <&pinctrl 8 0>;
 			default-state = "on";
 		};
 		usb_green {
 			label = "A4001N:green:usb";
-			gpios = <&gpio0 10 1>;
+			gpios = <&pinctrl 10 1>;
 		};
 		dsl_green {
 			label = "A4001N:green:dsl";
-			gpios = <&gpio0 11 1>;
+			gpios = <&pinctrl 11 1>;
 		};
 	};
 };
diff --git a/target/linux/brcm63xx/dts/a4001n1.dts b/target/linux/brcm63xx/dts/a4001n1.dts
index 8e20686..3254897 100644
--- a/target/linux/brcm63xx/dts/a4001n1.dts
+++ b/target/linux/brcm63xx/dts/a4001n1.dts
@@ -21,12 +21,12 @@
 
 		reset {
 			label = "reset";
-			gpios = <&gpio0 23 1>;
+			gpios = <&pinctrl 23 1>;
 			linux,code = <KEY_RESTART>;
 		};
 		wps {
 			label = "wlan";
-			gpios = <&gpio0 24 1>;
+			gpios = <&pinctrl 24 1>;
 			linux,code = <KEY_WLAN>;
 		};
 	};
@@ -36,52 +36,52 @@
 
 		inet_red {
 			label = "A4001N1:red:inet";
-			gpios = <&gpio0 2 1>;
+			gpios = <&pinctrl 2 1>;
 		};
 		ppp_green {
 			label = "A4001N1:green:ppp";
-			gpios = <&gpio0 3 1>;
+			gpios = <&pinctrl 3 1>;
 		};
 		power_green {
 			label = "A4001N1:green:power";
-			gpios = <&gpio0 4 1>;
+			gpios = <&pinctrl 4 1>;
 			default-state = "on";
 		};
 		ppp_red {
 			label = "A4001N1:red:ppp";
-			gpios = <&gpio0 5 1>;
+			gpios = <&pinctrl 5 1>;
 		};
 		usb_green {
 			label = "A4001N1:green:3g";
-			gpios = <&gpio0 6 1>;
+			gpios = <&pinctrl 6 1>;
 		};
 		usb_red {
 			label = "A4001N1:red:3g";
-			gpios = <&gpio0 7 1>;
+			gpios = <&pinctrl 7 1>;
 		};
 		power_red {
 			label = "A4001N1:red:power";
-			gpios = <&gpio0 8 1>;
+			gpios = <&pinctrl 8 1>;
 		};
 		wlan_green {
 			label = "A4001N1:green:wlan";
-			gpios = <&gpio0 9 1>;
+			gpios = <&pinctrl 9 1>;
 		};
 		wlan_red {
 			label = "A4001N1:red:wlan";
-			gpios = <&gpio0 10 1>;
+			gpios = <&pinctrl 10 1>;
 		};
 		inet_green {
 			label = "A4001N1:green:inet";
-			gpios = <&gpio0 11 1>;
+			gpios = <&pinctrl 11 1>;
 		};
 		eth_red {
 			label = "A4001N1:red:eth";
-			gpios = <&gpio0 20 1>;
+			gpios = <&pinctrl 20 1>;
 		};
 		eth_green {
 			label = "A4001N1:green:eth";
-			gpios = <&gpio0 31 1>;
+			gpios = <&pinctrl 31 1>;
 		};
 	};
 };
diff --git a/target/linux/brcm63xx/dts/agpf-s0.dts b/target/linux/brcm63xx/dts/agpf-s0.dts
index 3ff9cb2..be1f9fb 100644
--- a/target/linux/brcm63xx/dts/agpf-s0.dts
+++ b/target/linux/brcm63xx/dts/agpf-s0.dts
@@ -21,12 +21,12 @@
 
 		wps {
 			label = "wps";
-			gpios = <&gpio1 2 1>;
+			gpios = <&pinctrl 34 1>;
 			linux,code = <KEY_WPS_BUTTON>;
 		};
 		reset {
 			label = "reset";
-			gpios = <&gpio1 5 1>;
+			gpios = <&pinctrl 37 1>;
 			linux,code = <KEY_RESTART>;
 		};
 	};
@@ -36,60 +36,60 @@
 
 		power_green {
 			label = "AGPF-S0:green:power";
-			gpios = <&gpio0 4 1>;
+			gpios = <&pinctrl 4 1>;
 			default-state = "on";
 		};
 		power_red {
 			label = "AGPF-S0:red:power";
-			gpios = <&gpio0 5 1>;
+			gpios = <&pinctrl 5 1>;
 		};
 		service_green {
 			label = "AGPF-S0:green:service";
-			gpios = <&gpio0 6 1>;
+			gpios = <&pinctrl 6 1>;
 		};
 		service_red {
 			label = "AGPF-S0:red:service";
-			gpios = <&gpio0 7 1>;
+			gpios = <&pinctrl 7 1>;
 		};
 		dsl_green {
 			label = "AGPF-S0:green:adsl";
-			gpios = <&gpio0 9 1>;
+			gpios = <&pinctrl 9 1>;
 		};
 		dsl_red {
 			label = "AGPF-S0:red:adsl";
-			gpios = <&gpio0 10 1>;
+			gpios = <&pinctrl 10 1>;
 		};
 		wifi_green {
 			label = "AGPF-S0:green:wifi";
-			gpios = <&gpio0 22 1>;
+			gpios = <&pinctrl 22 1>;
 		};
 		wifi_red {
 			label = "AGPF-S0:red:wifi";
-			gpios = <&gpio0 23 1>;
+			gpios = <&pinctrl 23 1>;
 		};
 		inet_red {
 			label = "AGPF-S0:red:internet";
-			gpios = <&gpio0 24 1>;
+			gpios = <&pinctrl 24 1>;
 		};
 		inet_green {
 			label = "AGPF-S0:green:internet";
-			gpios = <&gpio0 25 1>;
+			gpios = <&pinctrl 25 1>;
 		};
 		usr1_green {
 			label = "AGPF-S0:green:usr1";
-			gpios = <&gpio0 26 1>;
+			gpios = <&pinctrl 26 1>;
 		};
 		usr1_red {
 			label = "AGPF-S0:red:usr1";
-			gpios = <&gpio0 27 1>;
+			gpios = <&pinctrl 27 1>;
 		};
 		usr2_green {
 			label = "AGPF-S0:green:usr2";
-			gpios = <&gpio0 29 1>;
+			gpios = <&pinctrl 29 1>;
 		};
 		usr2_red {
 			label = "AGPF-S0:red:usr2";
-			gpios = <&gpio0 30 1>;
+			gpios = <&pinctrl 30 1>;
 		};
 	};
 };
diff --git a/target/linux/brcm63xx/dts/ar-5381u.dts b/target/linux/brcm63xx/dts/ar-5381u.dts
index 1912fca..883198c 100644
--- a/target/linux/brcm63xx/dts/ar-5381u.dts
+++ b/target/linux/brcm63xx/dts/ar-5381u.dts
@@ -21,7 +21,7 @@
 
 		reset {
 			label = "reset";
-			gpios = <&gpio0 23 1>;
+			gpios = <&pinctrl 23 1>;
 			linux,code = <KEY_RESTART>;
 		};
 	};
@@ -31,15 +31,15 @@
 
 		alarm_red {
 			label = "AR-5381u:red:alarm";
-			gpios = <&gpio0 2 1>;
+			gpios = <&pinctrl 2 1>;
 		};
 		inet_green {
 			label = "AR-5381u:green:inet";
-			gpios = <&gpio0 3 1>;
+			gpios = <&pinctrl 3 1>;
 		};
 		power_green {
 			label = "AR-5381u:green:power";
-			gpios = <&gpio0 4 1>;
+			gpios = <&pinctrl 4 1>;
 			default-state = "on";
 		};
 	};
diff --git a/target/linux/brcm63xx/dts/ar-5387un.dts b/target/linux/brcm63xx/dts/ar-5387un.dts
index bfcd71e..a0e07fb 100644
--- a/target/linux/brcm63xx/dts/ar-5387un.dts
+++ b/target/linux/brcm63xx/dts/ar-5387un.dts
@@ -21,7 +21,7 @@
 
 		reset {
 			label = "reset";
-			gpios = <&gpio0 23 1>;
+			gpios = <&pinctrl 23 1>;
 			linux,code = <KEY_RESTART>;
 		};
 	};
@@ -31,24 +31,24 @@
 
 		inet_red {
 			label = "AR-5387un:red:inet";
-			gpios = <&gpio0 1 0>;
+			gpios = <&pinctrl 1 0>;
 		};
 		power_red {
 			label = "AR-5387un:red:power";
-			gpios = <&gpio0 4 0>;
+			gpios = <&pinctrl 4 0>;
 		};
 		inet_green {
 			label = "AR-5387un:green:inet";
-			gpios = <&gpio0 7 0>;
+			gpios = <&pinctrl 7 0>;
 		};
 		power_green {
 			label = "AR-5387un:green:power";
-			gpios = <&gpio0 8 0>;
+			gpios = <&pinctrl 8 0>;
 			default-state = "on";
 		};
 		dsl_green {
 			label = "AR-5387un:green:dsl";
-			gpios = <&gpio0 11 1>;
+			gpios = <&pinctrl 11 1>;
 		};
 	};
 };
diff --git a/target/linux/brcm63xx/dts/ar1004g.dts b/target/linux/brcm63xx/dts/ar1004g.dts
index 479c934..eb6d9a2 100644
--- a/target/linux/brcm63xx/dts/ar1004g.dts
+++ b/target/linux/brcm63xx/dts/ar1004g.dts
@@ -21,7 +21,7 @@
 
 		reset {
 			label = "reset";
-			gpios = <&gpio1 1 1>;
+			gpios = <&pinctrl 33 1>;
 			linux,code = <KEY_RESTART>;
 		};
 	};
@@ -31,16 +31,16 @@
 
 		power_green {
 			label = "AR1004G:green:power";
-			gpios = <&gpio0 0 1>;
+			gpios = <&pinctrl 0 1>;
 			default-state = "on";
 		};
 		inet_green {
 			label = "AR1004G:green:inet";
-			gpios = <&gpio0 3 1>;
+			gpios = <&pinctrl 3 1>;
 		};
 		power_red {
 			label = "AR1004G:red:power";
-			gpios = <&gpio0 6 1>;
+			gpios = <&pinctrl 6 1>;
 		};
 	};
 };
@@ -66,3 +66,8 @@
 		reg = <0x3f0000 0x010000>;
 	};
 };
+
+&pinctrl {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_ext_mii &pinctrl_pci>;
+};
diff --git a/target/linux/brcm63xx/dts/av4202n.dts b/target/linux/brcm63xx/dts/av4202n.dts
index 960e233..a105f36 100644
--- a/target/linux/brcm63xx/dts/av4202n.dts
+++ b/target/linux/brcm63xx/dts/av4202n.dts
@@ -22,12 +22,12 @@
 
 		reset {
 			label = "reset";
-			gpios = <&gpio1 2 GPIO_ACTIVE_LOW>;
+			gpios = <&pinctrl 34 GPIO_ACTIVE_LOW>;
 			linux,code = <KEY_RESTART>;
 		};
 		wlan {
 			label = "wlan";
-			gpios = <&gpio1 5 GPIO_ACTIVE_LOW>;
+			gpios = <&pinctrl 37 GPIO_ACTIVE_LOW>;
 			linux,code = <KEY_WLAN>;
 		};
 	};
@@ -37,32 +37,32 @@
 
 		power_white {
 			label = "AV4202N:white:power";
-			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+			gpios = <&pinctrl 10 GPIO_ACTIVE_LOW>;
 			default-state = "on";
 		};
 		power_red {
 			label = "AV4202N:red:power";
-			gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
+			gpios = <&pinctrl 11 GPIO_ACTIVE_LOW>;
 		};
 		wan_white {
 			label = "AV4202N:white:wan";
-			gpios = <&gpio0 26 GPIO_ACTIVE_LOW>;
+			gpios = <&pinctrl 26 GPIO_ACTIVE_LOW>;
 		};
 		wan_red {
 			label = "AV4202N:red:wan";
-			gpios = <&gpio0 27 GPIO_ACTIVE_LOW>;
+			gpios = <&pinctrl 27 GPIO_ACTIVE_LOW>;
 		};
 		phone_white {
 			label = "AV4202N:white:phone";
-			gpios = <&gpio0 24 GPIO_ACTIVE_LOW>;
+			gpios = <&pinctrl 24 GPIO_ACTIVE_LOW>;
 		};
 		phone_red {
 			label = "AV4202N:red:phone";
-			gpios = <&gpio0 25 GPIO_ACTIVE_LOW>;
+			gpios = <&pinctrl 25 GPIO_ACTIVE_LOW>;
 		};
 		wifi {
 			label = "AV4202N:blue:wifi";
-			gpios = <&gpio0 22 GPIO_ACTIVE_LOW>;
+			gpios = <&pinctrl 22 GPIO_ACTIVE_LOW>;
 		};
 	};
 };
diff --git a/target/linux/brcm63xx/dts/bcm6318.dtsi b/target/linux/brcm63xx/dts/bcm6318.dtsi
index a199b03..c1dcad3 100644
--- a/target/linux/brcm63xx/dts/bcm6318.dtsi
+++ b/target/linux/brcm63xx/dts/bcm6318.dtsi
@@ -4,8 +4,7 @@
 	compatible = "brcm,bcm6318";
 
 	aliases {
-		gpio0 = &gpio0;
-		gpio1 = &gpio1;
+		pinctrl = &pinctrl;
 		spi1 = &hsspi;
 	};
 
@@ -58,26 +57,113 @@
 			interrupts = <2>;
 		};
 
-		gpio1: gpio-controller at 10000080 {
-			compatible = "brcm,bcm6345-gpio";
-			reg = <0x10000080 4>, <0x10000088 4>;
+		pinctrl: pin-controller at 10000080 {
+			compatible = "brcm,bcm6318-pinctrl";
+			reg = <0x10000080 0x08>,
+			      <0x10000088 0x08>,
+			      <0x10000098 0x04>,
+			      <0x1000009c 0x0c>,
+			      <0x100000d4 0x18>;
+			reg-names = "dirout", "dat", "mode", "mux", "pad";
 
 			gpio-controller;
 			#gpio-cells = <2>;
 
-			ngpios = <18>;
-
 			interrupt-parent = <&ext_intc>;
 			interrupts = <0 0>, <1 0>;
-			interrupt-names = "gpio1", "gpio2";
-		};
-
-		gpio0: gpio-controller at 10000084 {
-			compatible = "brcm,bcm6345-gpio";
-			reg = <0x10000084 4>, <0x1000008c 4>;
-
-			gpio-controller;
-			#gpio-cells = <2>;
+			interrupt-names = "gpio33", "gpio34";
+
+			pinctrl_ephy0_spd_led: ephy0_spd_led {
+				function = "ephy0_spd_led";
+				pins = "gpio0";
+			};
+
+			pinctrl_ephy1_spd_led: ephy1_spd_led {
+				function = "ephy1_spd_led";
+				pins = "gpio1";
+			};
+
+			pinctrl_ephy2_spd_led: ephy2_spd_led {
+				function = "ephy2_spd_led";
+				pins = "gpio2";
+			};
+
+			pinctrl_ephy3_spd_led: ephy3_spd_led {
+				function = "ephy3_spd_led";
+				pins = "gpio3";
+			};
+
+			pinctrl_ephy0_act_led: ephy0_act_led {
+				function = "ephy0_act_led";
+				pins = "gpio4";
+			};
+
+			pinctrl_ephy1_act_led: ephy1_act_led {
+				function = "ephy1_act_led";
+				pins = "gpio5";
+			};
+
+			pinctrl_ephy2_act_led: ephy2_act_led {
+				function = "ephy2_act_led";
+				pins = "gpio6";
+			};
+
+			pinctrl_ephy3_act_led: ephy3_act_led {
+				function = "ephy3_act_led";
+				pins = "gpio7";
+			};
+
+			pinctrl_serial_led: serial_led {
+				pinctrl_serial_led_data: serial_led_data {
+					function = "serial_led_data";
+					pins = "gpio6";
+				};
+
+				pinctrl_serial_led_clk: serial_led_clk {
+					function = "serial_led_clk";
+					pins = "gpio7";
+				};
+			};
+
+			pinctrl_inet_act_led: inet_act_led {
+				function = "inet_act_led";
+				pins = "gpio8";
+			};
+
+			pinctrl_inet_fail_led: inet_fail_led {
+				function = "inet_fail_led";
+				pins = "gpio9";
+			};
+
+			pinctrl_dsl_led: dsl_led {
+				function = "dsl_led";
+				pins = "gpio10";
+			};
+
+			pinctrl_post_fail_led: post_fail_led {
+				function = "post_fail_led";
+				pins = "gpio11";
+			};
+
+			pinctrl_wlan_wps_led: wlan_wps_led {
+				function = "wlan_wps_led";
+				pins = "gpio12";
+			};
+
+			pinctrl_usb_pwron: usb_pwron {
+				function = "usb_pwron";
+				pins = "gpio13";
+			};
+
+			pinctrl_usb_device_led: usb_device_led {
+				function = "usb_device_led";
+				pins = "gpio13";
+			};
+
+			pinctrl_usb_active: usb_active {
+				function = "usb_active";
+				pins = "gpio40";
+			};
 		};
 
 		hsspi: spi at 10003000 {
diff --git a/target/linux/brcm63xx/dts/bcm63268.dtsi b/target/linux/brcm63xx/dts/bcm63268.dtsi
index a2b683a..d64fe19 100644
--- a/target/linux/brcm63xx/dts/bcm63268.dtsi
+++ b/target/linux/brcm63xx/dts/bcm63268.dtsi
@@ -4,8 +4,7 @@
 	compatible = "brcm,bcm63268";
 
 	aliases {
-		gpio0 = &gpio0;
-		gpio1 = &gpio1;
+		pinctrl = &pinctrl;
 		spi0 = &lsspi;
 		spi1 = &hsspi;
 	};
@@ -66,26 +65,132 @@
 			interrupts = <2>, <3>;
 		};
 
-		gpio1: gpio-controller at 100000c0 {
-			compatible = "brcm,bcm6345-gpio";
-			reg = <0x100000c0 4>, <0x100000c8 4>;
+		pinctrl: pin-controller at 100000c0 {
+			compatible = "brcm,bcm63268-pinctrl";
+			reg = <0x100000c0 0x8>,
+			      <0x100000c8 0x8>,
+			      <0x100000d0 0x4>,
+			      <0x100000d8 0x4>,
+			      <0x100000dc 0x4>,
+			      <0x100000f8 0x4>;
+			reg-names = "dirout", "dat", "led", "mode",
+				    "ctrl", "basemode";
 
 			gpio-controller;
 			#gpio-cells = <2>;
 
-			ngpios = <20>;
-
 			interrupt-parent = <&periph_intc>;
 			interrupts = <0 0>, <1 0>, <2 0>, <3 0>;
-			interrupt-names = "gpio0", "gpio1", "gpio2", "gpio3";
-		};
-
-		gpio0: gpio-controller at 100000c4 {
-			compatible = "brcm,bcm6345-gpio";
-			reg = <0x100000c4 4>, <0x100000cc 4>;
-
-			gpio-controller;
-			#gpio-cells = <2>;
+			interrupt-names = "gpio32", "gpio33", "gpio34", "gpio35";
+
+			pinctrl_serial_led: serial_led {
+				pinctrl_serial_led_clk: serial_led_clk {
+					function = "serial_led_clk";
+					pins = "gpio0";
+				};
+
+				pinctrl_serial_led_data: serial_led_data {
+					function = "serial_led_data";
+					pins = "gpio1";
+				};
+			};
+
+			pinctrl_hsspi_cs4: hsspi_cs4 {
+				function = "hsspi_cs4";
+				pins = "gpio16";
+			};
+
+			pinctrl_hsspi_cs5: hsspi_cs5 {
+				function = "hsspi_cs5";
+				pins = "gpio17";
+			};
+
+			pinctrl_hsspi_cs6: hsspi_cs6 {
+				function = "hsspi_cs6";
+				pins = "gpio8";
+			};
+
+			pinctrl_hsspi_cs7: hsspi_cs7 {
+				function = "hsspi_cs7";
+				pins = "gpio9";
+			};
+
+			pinctrl_adsl_spi: adsl_spi {
+				pinctrl_adsl_spi_miso: adsl_spi_miso {
+					function = "adsl_spi_miso";
+					pins = "gpio18";
+				};
+
+				pinctrl_adsl_spi_mosi: adsl_spi_mosi {
+					function = "adsl_spi_mosi";
+					pins = "gpio19";
+				};
+			};
+
+			pinctrl_vreq_clk: vreq_clk {
+				function = "vreq_clk";
+				pins = "gpio22";
+			};
+
+			pinctrl_pcie_clkreq_b: pcie_clkreq_b {
+				function = "pcie_clkreq_b";
+				pins = "gpio23";
+			};
+
+			pinctrl_robosw_led_clk: robosw_led_clk {
+				function = "robosw_led_clk";
+				pins = "gpio30";
+			};
+
+			pinctrl_robosw_led_data: robosw_led_data {
+				function = "robosw_led_data";
+				pins = "gpio31";
+			};
+
+			pinctrl_nand: nand {
+				function = "nand";
+				group = "nand_grp";
+			};
+
+			pinctrl_gpio35_alt: gpio35_alt {
+				function = "gpio35_alt";
+				pin = "gpio35";
+			};
+
+			pinctrl_dectpd: dectpd {
+				function = "dectpd";
+				group = "dectpd_grp";
+			};
+
+			pinctrl_vdsl_phy_override_0: vdsl_phy_override_0 {
+				function = "vdsl_phy_override_0";
+				group = "vdsl_phy_override_0_grp";
+			};
+
+			pinctrl_vdsl_phy_override_1: vdsl_phy_override_1 {
+				function = "vdsl_phy_override_1";
+				group = "vdsl_phy_override_1_grp";
+			};
+
+			pinctrl_vdsl_phy_override_2: vdsl_phy_override_2 {
+				function = "vdsl_phy_override_2";
+				group = "vdsl_phy_override_2_grp";
+			};
+
+			pinctrl_vdsl_phy_override_3: vdsl_phy_override_3 {
+				function = "vdsl_phy_override_3";
+				group = "vdsl_phy_override_3_grp";
+			};
+
+			pinctrl_dsl_gpio8: dsl_gpio8 {
+				function = "dsl_gpio8";
+				group = "dsl_gpio8";
+			};
+
+			pinctrl_dsl_gpio9: dsl_gpio9 {
+				function = "dsl_gpio9";
+				group = "dsl_gpio9";
+			};
 		};
 
 		lsspi: spi at 10000800 {
diff --git a/target/linux/brcm63xx/dts/bcm6328.dtsi b/target/linux/brcm63xx/dts/bcm6328.dtsi
index 9a17869..0bb41cf 100644
--- a/target/linux/brcm63xx/dts/bcm6328.dtsi
+++ b/target/linux/brcm63xx/dts/bcm6328.dtsi
@@ -4,7 +4,7 @@
 	compatible = "brcm,bcm6328";
 
 	aliases {
-		gpio0 = &gpio0;
+		pinctrl = &pinctrl;
 		spi1 = &hsspi;
 	};
 
@@ -57,9 +57,13 @@
 			interrupts = <2>;
 		};
 
-		gpio0: gpio-controller at 10000084 {
-			compatible = "brcm,bcm6345-gpio";
-			reg = <0x10000084 4>, <0x1000008c 4>;
+		pinctrl: pin-controller at 10000080 {
+			compatible = "brcm,bcm6328-pinctrl";
+			reg = <0x10000080 0x8>,
+			      <0x10000088 0x8>,
+			      <0x10000098 0x4>,
+			      <0x1000009c 0xc>;
+			reg-names = "dirout", "dat", "mode", "mux";
 
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -68,6 +72,83 @@
 			interrupts = <3 0>, <2 0>, <0 0>, <1 0>;
 			interrupt-names = "gpio12", "gpio15",
 					  "gpio23", "gpio24";
+
+			pinctrl_serial_led: serial_led {
+				pinctrl_serial_led_data: serial_led_data {
+					function = "serial_led_data";
+					pins = "gpio6";
+				};
+
+				pinctrl_serial_led_clk: serial_led_clk {
+					function = "serial_led_clk";
+					pins = "gpio7";
+				};
+			};
+
+			pinctrl_inet_act_led: inet_act_led {
+				function = "inet_act_led";
+				pins = "gpio11";
+			};
+
+			pinctrl_pcie_clkreq: pcie_clkreq {
+				function = "pcie_clkreq";
+				pins = "gpio16";
+			};
+
+			pinctrl_ephy0_spd_led: ephy0_spd_led {
+				function = "led";
+				pins = "gpio17";
+			};
+
+			pinctrl_ephy1_spd_led: ephy1_spd_led {
+				function = "led";
+				pins = "gpio18";
+			};
+
+			pinctrl_ephy2_spd_led: ephy2_spd_led {
+				function = "led";
+				pins = "gpio19";
+			};
+
+			pinctrl_ephy3_spd_led: ephy3_spd_led {
+				function = "led";
+				pins = "gpio20";
+			};
+
+			pinctrl_ephy0_act_led: ephy0_act_led {
+				function = "ephy0_act_led";
+				pins = "gpio25";
+			};
+
+			pinctrl_ephy1_act_led: ephy1_act_led {
+				function = "ephy1_act_led";
+				pins = "gpio26";
+			};
+
+			pinctrl_ephy2_act_led: ephy2_act_led {
+				function = "ephy2_act_led";
+				pins = "gpio27";
+			};
+
+			pinctrl_ephy3_act_led: ephy3_act_led {
+				function = "ephy3_act_led";
+				pins = "gpio28";
+			};
+
+			pinctrl_hsspi_cs1: hsspi_cs1 {
+				function = "hsspi_cs1";
+				pins = "hsspi_cs1";
+			};
+
+			pinctrl_usb_port1_device: usb_port1_device {
+				function = "usb_device_port";
+				pins = "usb_port1";
+			};
+
+			pinctrl_usb_port1_host: usb_port1_host {
+				function = "usb_host_port";
+				pins = "usb_port1";
+			};
 		};
 
 		hsspi: spi at 10001000 {
diff --git a/target/linux/brcm63xx/dts/bcm6348.dtsi b/target/linux/brcm63xx/dts/bcm6348.dtsi
index 47c06d0..b6dafee 100644
--- a/target/linux/brcm63xx/dts/bcm6348.dtsi
+++ b/target/linux/brcm63xx/dts/bcm6348.dtsi
@@ -5,8 +5,7 @@
 
 	aliases {
 		pflash = &pflash;
-		gpio0 = &gpio0;
-		gpio1 = &gpio1;
+		pinctrl = &pinctrl;
 		spi0 = &lsspi;
 	};
 
@@ -72,26 +71,59 @@
 			brcm,field-width = <5>;
 		};
 
-		gpio1: gpio-controller at fffe0400 {
-			compatible = "brcm,bcm6345-gpio";
-			reg = <0xfffe0400 4>, <0xfffe0408 4>;
+		pinctrl: pin-controller at fffe0400 {
+			compatible = "brcm,bcm6348-pinctrl";
+			reg = <0xfffe0400 0x8>,
+			      <0xfffe0408 0x8>,
+			      <0xfffe0418 0x4>;
+			reg-names = "dirout", "dat", "mode";
 
 			gpio-controller;
 			#gpio-cells = <2>;
 
-			ngpios = <5>;
-
 			interrupt-parent = <&ext_intc>;
 			interrupts = <0 0>, <1 0>, <2 0>, <3 0>;
-			interrupt-names = "gpio0", "gpio1", "gpio2", "gpio3";
-		};
-
-		gpio0: gpio-controller at fffe0404 {
-			compatible = "brcm,bcm6345-gpio";
-			reg = <0xfffe0404 4>, <0xfffe040c 4>;
-
-			gpio-controller;
-			#gpio-cells = <2>;
+			interrupt-names = "gpio32", "gpio33", "gpio34", "gpio35";
+
+			pinctrl_ext_ephy: ext_ephy {
+				function = "ext_ephy";
+				groups = "group1", "group4";
+			};
+
+			pinctrl_mii_snoop: mii_snoop {
+				function = "ext_ephy";
+				groups = "group1", "group4";
+			};
+
+			pinctrl_legacy_led: legacy_led {
+				function = "legacy_led";
+				groups = "group4";
+			};
+
+			pinctrl_mii_pccard: mii_pccard {
+				function = "mii_pccard";
+				groups = "group1";
+			};
+
+			pinctrl_pci: pci {
+				function = "pci";
+				groups = "group2";
+			};
+
+			pinctrl_spi_master_uart: spi_master_uart {
+				function = "spi_master_uart";
+				groups = "group1";
+			};
+
+			pinctrl_ext_mii: ext_mii {
+				function = "ext_mii";
+				groups = "group0", "group3";
+			};
+
+			pinctrl_utopia: utopia {
+				function = "utopia";
+				groups = "group0", "group1", "group3";
+			};
 		};
 
 		lsspi: spi at fffe0c00 {
diff --git a/target/linux/brcm63xx/dts/bcm6358.dtsi b/target/linux/brcm63xx/dts/bcm6358.dtsi
index e4aecf7..36b19e7 100644
--- a/target/linux/brcm63xx/dts/bcm6358.dtsi
+++ b/target/linux/brcm63xx/dts/bcm6358.dtsi
@@ -5,8 +5,7 @@
 
 	aliases {
 		pflash = &pflash;
-		gpio0 = &gpio0;
-		gpio1 = &gpio1;
+		pinctrl = &pinctrl;
 		spi0 = &lsspi;
 	};
 
@@ -86,31 +85,74 @@
 			interrupts = <20>, <21>;
 		};
 
-		gpio1: gpio-controller at fffe0080 {
-			compatible = "brcm,bcm6345-gpio";
-			reg = <0xfffe0080 4>, <0xfffe0088 4>;
+		pinctrl: pin-controller at fffe0080 {
+			compatible = "brcm,bcm6358-pinctrl";
+			reg = <0xfffe0080 0x8>,
+			      <0xfffe0088 0x8>;
+			reg-names = "dirout", "dat", "mode";
+			brcm,gpiomode = <&gpiomode>;
 
 			gpio-controller;
 			#gpio-cells = <2>;
 
-			ngpios = <8>;
-
 			interrupts-extended = <&ext_intc1 0 0>,
 					      <&ext_intc1 1 0>,
 					      <&ext_intc0 0 0>,
 					      <&ext_intc0 1 0>,
 					      <&ext_intc0 2 0>,
 					      <&ext_intc0 3 0>;
-			interrupt-names = "gpio0", "gpio1", "gpio2", "gpio3",
-					  "gpio4", "gpio5";
+			interrupt-names = "gpio32", "gpio33", "gpio34", "gpio35",
+					  "gpio36", "gpio37";
+
+			pinctrl_ebi_cs: ebi_cs {
+				function = "ebi_cs";
+				groups = "ebi_cs_grp";
+			};
+
+			pinctrl_uart1: uart1 {
+				function = "uart1";
+				groups = "uart1_grp";
+			};
+
+			pinctrl_serial_led: serial_led {
+				function = "serial_led";
+				groups = "serial_led_grp";
+			};
+
+			pinctrl_legacy_led: legacy_led {
+				function = "legacy_led";
+				groups = "legacy_led_grp";
+			};
+
+			pinctrl_led: led {
+				function = "led";
+				groups = "led_grp";
+			};
+
+			pinctrl_spi_cs_23: spi_cs {
+				function = "spi_cs";
+				groups = "spi_cs_grp";
+			};
+
+			pinctrl_utopia: utopia {
+				function = "utopia";
+				groups = "utopia_grp";
+			};
+
+			pinctrl_pwm_syn_clk: pwm_syn_clk {
+				function = "pwm_syn_clk";
+				groups = "pwm_syn_clk_grp";
+			};
+
+			pinctrl_sys_irq: sys_irq {
+				function = "sys_irq";
+				groups = "sys_irq_grp";
+			};
 		};
 
-		gpio0: gpio-controller at fffe0084 {
-			compatible = "brcm,bcm6345-gpio";
-			reg = <0xfffe0084 4>, <0xfffe008c 4>;
-
-			gpio-controller;
-			#gpio-cells = <2>;
+		gpiomode: gpiomode at fffe0098 {
+			compatible = "brcm,bcm6358-gpiomode", "syscon";
+			reg = <0xfffe0098 0x4>;
 		};
 
 		lsspi: spi at fffe0800 {
diff --git a/target/linux/brcm63xx/dts/bcm6362.dtsi b/target/linux/brcm63xx/dts/bcm6362.dtsi
index 2085fd5..11edf71 100644
--- a/target/linux/brcm63xx/dts/bcm6362.dtsi
+++ b/target/linux/brcm63xx/dts/bcm6362.dtsi
@@ -4,8 +4,7 @@
 	compatible = "brcm,bcm6362";
 
 	aliases {
-		gpio0 = &gpio0;
-		gpio1 = &gpio1;
+		pinctrl = &pinctrl;
 		spi0 = &lsspi;
 		spi1 = &hsspi;
 	};
@@ -66,19 +65,16 @@
 			interrupts = <2>, <3>;
 		};
 
-		gpio1: gpio-controller at 10000080 {
-			compatible = "brcm,bcm6345-gpio";
-			reg = <0x10000080 4>, <0x10000088 4>;
-
-			gpio-controller;
-			#gpio-cells = <2>;
-
-			ngpios = <16>;
-		};
-
-		gpio0: gpio-controller at 10000084 {
-			compatible = "brcm,bcm6345-gpio";
-			reg = <0x10000084 4>, <0x1000008c 4>;
+		pinctrl: pin-controller at 10000080 {
+			compatible = "brcm,bcm6362-pinctrl";
+			reg = <0x10000080 0x8>,
+			      <0x10000088 0x8>,
+			      <0x10000090 0x4>,
+			      <0x10000098 0x4>,
+			      <0x1000009c 0x4>,
+			      <0x100000b8 0x4>;
+			reg-names = "dirout", "dat", "led",
+				    "mode", "ctrl", "basemode";
 
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -87,6 +83,158 @@
 			interrupts = <0 0>, <1 0>, <2 0>, <3 0>;
 			interrupt-names = "gpio24", "gpio25",
 					  "gpio26", "gpio27";
+
+			pinctrl_usb_device_led: usb_device_led {
+				function = "usb_device_led";
+				pins = "gpio0";
+			};
+
+			pinctrl_sys_irq: sys_irq {
+				function = "sys_irq";
+				pins = "gpio1";
+			};
+
+			pinctrl_serial_led: serial_led {
+				pinctrl_serial_led_clk: serial_led_clk {
+					function = "serial_led_clk";
+					pins = "gpio2";
+				};
+
+				pinctrl_serial_led_data: serial_led_data {
+					function = "serial_led_data";
+					pins = "gpio3";
+				};
+			};
+
+			pinctrl_robosw_led_data: robosw_led_data {
+				function = "robosw_led_data";
+				pins = "gpio4";
+			};
+
+			pinctrl_robosw_led_clk: robosw_led_clk {
+				function = "robosw_led_clk";
+				pins = "gpio5";
+			};
+
+			pinctrl_robosw_led0: robosw_led0 {
+				function = "robosw_led0";
+				pins = "gpio6";
+			};
+
+			pinctrl_robosw_led1: robosw_led1 {
+				function = "robosw_led1";
+				pins = "gpio7";
+			};
+
+			pinctrl_inet_led: inet_led {
+				function = "inet_led";
+				pins = "gpio8";
+			};
+
+			pinctrl_spi_cs2: spi_cs2 {
+				function = "spi_cs2";
+				pins = "gpio9";
+			};
+
+			pinctrl_spi_cs3: spi_cs3 {
+				function = "spi_cs3";
+				pins = "gpio10";
+			};
+
+			pinctrl_ntr_pulse: ntr_pulse {
+				function = "ntr_pulse";
+				pins = "gpio11";
+			};
+
+			pinctrl_uart1_scts: uart1_scts {
+				function = "uart1_scts";
+				pins = "gpio12";
+			};
+
+			pinctrl_uart1_srts: uart1_srts {
+				function = "uart1_srts";
+				pins = "gpio13";
+			};
+
+
+			pinctrl_uart1: uart1 {
+				pinctrl_uart1_sdin: uart1_sdin {
+					function = "uart1_sdin";
+					pins = "gpio14";
+				};
+
+				pinctrl_uart1_sdout: uart1_sdout {
+					function = "uart1_sdout";
+					pins = "gpio15";
+				};
+			};
+
+			pinctrl_adsl_spi: adsl_spi {
+				pinctrl_adsl_spi_miso: adsl_spi_miso {
+					function = "adsl_spi_miso";
+					pins = "gpio16";
+				};
+
+				pinctrl_adsl_spi_mosi: adsl_spi_mosi {
+					function = "adsl_spi_mosi";
+					pins = "gpio17";
+				};
+
+				pinctrl_adsl_spi_clk: adsl_spi_clk {
+					function = "adsl_spi_clk";
+					pins = "gpio18";
+				};
+
+				pinctrl_adsl_spi_cs: adsl_spi_cs {
+					function = "adsl_spi_cs";
+					pins = "gpio19";
+				};
+			};
+
+			pinctrl_ephy0_led: ephy0_led {
+				function = "ephy0_led";
+				pins = "gpio20";
+			};
+
+			pinctrl_ephy1_led: ephy1_led {
+				function = "ephy1_led";
+				pins = "gpio21";
+			};
+
+			pinctrl_ephy2_led: ephy2_led {
+				function = "ephy2_led";
+				pins = "gpio22";
+			};
+
+			pinctrl_ephy3_led: ephy3_led {
+				function = "ephy3_led";
+				pins = "gpio23";
+			};
+
+			pinctrl_ext_irq0: ext_irq0 {
+				function = "ext_irq0";
+				pins = "gpio24";
+			};
+
+			pinctrl_ext_irq1: ext_irq1 {
+				function = "ext_irq1";
+				pins = "gpio25";
+			};
+
+			pinctrl_ext_irq2: ext_irq2 {
+				function = "ext_irq2";
+				pins = "gpio26";
+			};
+
+			pinctrl_ext_irq3: ext_irq3 {
+				function = "ext_irq3";
+				pins = "gpio27";
+			};
+
+			pinctrl_nand: nand {
+				function = "nand";
+				group = "nand_grp";
+			};
 		};
 
 		lsspi: spi at 10000800 {
diff --git a/target/linux/brcm63xx/dts/bcm6368.dtsi b/target/linux/brcm63xx/dts/bcm6368.dtsi
index 40f2f0f..a49f24a 100644
--- a/target/linux/brcm63xx/dts/bcm6368.dtsi
+++ b/target/linux/brcm63xx/dts/bcm6368.dtsi
@@ -5,8 +5,7 @@
 
 	aliases {
 		pflash = &pflash;
-		gpio0 = &gpio0;
-		gpio1 = &gpio1;
+		pinctrl = &pinctrl;
 		spi0 = &lsspi;
 	};
 
@@ -76,31 +75,191 @@
 			interrupts = <2>, <3>;
 		};
 
-		gpio1: gpio-controller at 10000080 {
-			compatible = "brcm,bcm6345-gpio";
-			reg = <0x10000080 4>, <0x10000088 4>;
+		pinctrl: pin-controller at 10000080 {
+			compatible = "brcm,bcm6368-pinctrl";
+			reg = <0x10000080 0x8>,
+			      <0x10000088 0x8>,
+			      <0x10000098 0x4>;
+			reg-names = "dirout", "dat", "mode";
+			brcm,gpiobasemode = <&gpiobasemode>;
 
 			gpio-controller;
 			#gpio-cells = <2>;
 
-			ngpios = <6>;
-
 			interrupts-extended = <&ext_intc1 0 0>,
 					      <&ext_intc1 1 0>,
 					      <&ext_intc0 0 0>,
 					      <&ext_intc0 1 0>,
 					      <&ext_intc0 2 0>,
 					      <&ext_intc0 3 0>;
-			interrupt-names = "gpio0", "gpio1", "gpio2", "gpio3",
-					  "gpio4", "gpio5";
-		};
+			interrupt-names = "gpio32", "gpio33", "gpio34", "gpio35",
+					  "gpio36", "gpio37";
 
-		gpio0: gpio-controller at 10000084 {
-			compatible = "brcm,bcm6345-gpio";
-			reg = <0x10000084 4>, <0x1000008c 4>;
+			pinctrl_analog_afe_0: analog_afe_0 {
+				function = "analog_afe_0";
+				pins = "gpio0";
+			};
 
-			gpio-controller;
-			#gpio-cells = <2>;
+			pinctrl_analog_afe_1: analog_afe_1 {
+				function = "analog_afe_1";
+				pins = "gpio1";
+			};
+
+			pinctrl_sys_irq: sys_irq {
+				function = "sys_irq";
+				pins = "gpio2";
+			};
+
+			pinctrl_serial_led: serial_led {
+				pinctrl_serial_led_data: serial_led_data {
+					function = "serial_led_data";
+					pins = "gpio3";
+				};
+
+				pinctrl_serial_led_clk: serial_led_clk {
+					function = "serial_led_clk";
+					pins = "gpio4";
+				};
+			};
+
+			pinctrl_inet_led: inet_led {
+				function = "inet_led";
+				pins = "gpio5";
+			};
+
+			pinctrl_ephy0_led: ephy0_led {
+				function = "ephy0_led";
+				pins = "gpio6";
+			};
+
+			pinctrl_ephy1_led: ephy1_led {
+				function = "ephy1_led";
+				pins = "gpio7";
+			};
+
+			pinctrl_ephy2_led: ephy2_led {
+				function = "ephy2_led";
+				pins = "gpio8";
+			};
+
+			pinctrl_ephy3_led: ephy3_led {
+				function = "ephy3_led";
+				pins = "gpio9";
+			};
+
+			pinctrl_robosw_led_data: robosw_led_data {
+				function = "robosw_led_data";
+				pins = "gpio10";
+			};
+
+			pinctrl_robosw_led_clk: robosw_led_clk {
+				function = "robosw_led_clk";
+				pins = "gpio11";
+			};
+
+			pinctrl_robosw_led0: robosw_led0 {
+				function = "robosw_led0";
+				pins = "gpio12";
+			};
+
+			pinctrl_robosw_led1: robosw_led1 {
+				function = "robosw_led1";
+				pins = "gpio13";
+			};
+
+			pinctrl_usb_device_led: usb_device_led {
+				function = "usb_device_led";
+				pins = "gpio14";
+			};
+
+			pinctrl_pci: pci {
+				pinctrl_pci_req1: pci_req1 {
+					function = "pci_req1";
+					pins = "gpio16";
+				};
+
+				pinctrl_pci_gnt1: pci_gnt1 {
+					function = "pci_gnt1";
+					pins = "gpio17";
+				};
+
+				pinctrl_pci_intb: pci_intb {
+					function = "pci_intb";
+					pins = "gpio18";
+				};
+
+				pinctrl_pci_req0: pci_req0 {
+					function = "pci_req0";
+					pins = "gpio19";
+				};
+
+				pinctrl_pci_gnt0: pci_gnt0 {
+					function = "pci_gnt0";
+					pins = "gpio20";
+				};
+			};
+
+			pinctrl_pcmcia: pcmcia {
+				pinctrl_pcmcia_cd1: pcmcia_cd1 {
+					function = "pcmcia_cd1";
+					pins = "gpio22";
+				};
+
+				pinctrl_pcmcia_cd2: pcmcia_cd2 {
+					function = "pcmcia_cd2";
+					pins = "gpio23";
+				};
+
+				pinctrl_pcmcia_vs1: pcmcia_vs1 {
+					function = "pcmcia_vs1";
+					pins = "gpio24";
+				};
+
+				pinctrl_pcmcia_vs2: pcmcia_vs2 {
+					function = "pcmcia_vs2";
+					pins = "gpio25";
+				};
+			};
+
+			pinctrl_ebi_cs2: ebi_cs2 {
+				function = "ebi_cs2";
+				pins = "gpio26";
+			};
+
+			pinctrl_ebi_cs3: ebi_cs3 {
+				function = "ebi_cs2";
+				pins = "gpio27";
+			};
+
+			pinctrl_spi_cs2: spi_cs2 {
+				function = "spi_cs2";
+				pins = "gpio28";
+			};
+
+			pinctrl_spi_cs3: spi_cs3 {
+				function = "spi_cs3";
+				pins = "gpio29";
+			};
+
+			pinctrl_spi_cs4: spi_cs4 {
+				function = "spi_cs4";
+				pins = "gpio30";
+			};
+
+			pinctrl_spi_cs5: spi_cs5 {
+				function = "spi_cs5";
+				pins = "gpio31";
+			};
+
+			pinctrl_uart1: uart1 {
+				function = "uart1";
+				group = "uart1_grp";
+			};
+		};
+
+		gpiobasemode: gpiobasemode at 100000b8 {
+			compatible = "brcm,bcm6368-gpiobasemode", "syscon";
+			reg = <0x100000b8 0x4>;
 		};
 
 		lsspi: spi at 10000800 {
diff --git a/target/linux/brcm63xx/dts/bcm96318ref.dts b/target/linux/brcm63xx/dts/bcm96318ref.dts
index 11d67fa..5780ccb 100644
--- a/target/linux/brcm63xx/dts/bcm96318ref.dts
+++ b/target/linux/brcm63xx/dts/bcm96318ref.dts
@@ -21,13 +21,13 @@
 
 		wps {
 			label = "wps";
-			gpios = <&gpio1 1 1>;
+			gpios = <&pinctrl 33 1>;
 			linux,code = <KEY_WPS_BUTTON>;
 		};
 
 		reset {
 			label = "reset";
-			gpios = <&gpio1 2 1>;
+			gpios = <&pinctrl 34 1>;
 			linux,code = <KEY_RESTART>;
 		};
         };
@@ -37,17 +37,17 @@
 
 		inet {
 			label = "96318REF:green:inet";
-			gpios = <&gpio0 8 1>;
+			gpios = <&pinctrl 8 1>;
 		};
 
 		inet_fail {
 			label = "96318REF:red:inet-fail";
-			gpios = <&gpio0 9 1>;
+			gpios = <&pinctrl 9 1>;
 		};
 
 		post_failed {
 			label = "96318REF:red:post-failed";
-			gpios = <&gpio0 11 1>;
+			gpios = <&pinctrl 11 1>;
 		};
 	};
 };
@@ -68,3 +68,8 @@
 		linux,part-probe = "bcm63xxpart";
 	};
 };
+
+&pinctrl {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usb_pwron>;
+};
diff --git a/target/linux/brcm63xx/dts/bcm96318ref_p300.dts b/target/linux/brcm63xx/dts/bcm96318ref_p300.dts
index cb648a3..8fae7fa 100644
--- a/target/linux/brcm63xx/dts/bcm96318ref_p300.dts
+++ b/target/linux/brcm63xx/dts/bcm96318ref_p300.dts
@@ -21,13 +21,13 @@
 
 		wps {
 			label = "wps";
-			gpios = <&gpio1 1 1>;
+			gpios = <&pinctrl 33 1>;
 			linux,code = <KEY_WPS_BUTTON>;
 		};
 
 		reset {
 			label = "reset";
-			gpios = <&gpio1 2 1>;
+			gpios = <&pinctrl 34 1>;
 			linux,code = <KEY_RESTART>;
 		};
         };
@@ -37,22 +37,22 @@
 
 		inet {
 			label = "96318REF_P300:green:inet";
-			gpios = <&gpio0 8 1>;
+			gpios = <&pinctrl 8 1>;
 		};
 
 		inet_fail {
 			label = "96318REF_P300:red:inet-fail";
-			gpios = <&gpio0 9 1>;
+			gpios = <&pinctrl 9 1>;
 		};
 
 		post_failed {
 			label = "96318REF_P300:red:post-failed";
-			gpios = <&gpio0 11 1>;
+			gpios = <&pinctrl 11 1>;
 		};
 
 		usb_pwron {
 			label = "96318REF_P300::usb-pwron";
-			gpios = <&gpio0 13 1>;
+			gpios = <&pinctrl 13 1>;
 			default-state = "on";
 		};
 	};
@@ -74,3 +74,8 @@
 		linux,part-probe = "bcm63xxpart";
 	};
 };
+
+&pinctrl {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usb_pwron>;
+};
diff --git a/target/linux/brcm63xx/dts/bcm963268bu_p300.dts b/target/linux/brcm63xx/dts/bcm963268bu_p300.dts
index eba47d7..a96bed7 100644
--- a/target/linux/brcm63xx/dts/bcm963268bu_p300.dts
+++ b/target/linux/brcm63xx/dts/bcm963268bu_p300.dts
@@ -21,13 +21,13 @@
 
 		reset {
 			label = "reset";
-			gpios = <&gpio1 0 0>;
+			gpios = <&pinctrl 32 0>;
 			linux,code = <KEY_RESTART>;
 		};
 
 		wps {
 			label = "wps";
-			gpios = <&gpio1 1 0>;
+			gpios = <&pinctrl 33 0>;
 			linux,code = <KEY_WPS_BUTTON>;
 		};
         };
diff --git a/target/linux/brcm63xx/dts/bcm963269bhr.dts b/target/linux/brcm63xx/dts/bcm963269bhr.dts
index 68c17eb..4984f8f 100644
--- a/target/linux/brcm63xx/dts/bcm963269bhr.dts
+++ b/target/linux/brcm63xx/dts/bcm963269bhr.dts
@@ -21,7 +21,7 @@
 
 		reset {
 			label = "reset";
-			gpios = <&gpio1 0 0>;
+			gpios = <&pinctrl 32 0>;
 			linux,code = <KEY_RESTART>;
 		};
         };
@@ -31,12 +31,12 @@
 
 		usb1 {
 			label = "963269BHR:green:usb1";
-			gpios = <&gpio0 9 1>;
+			gpios = <&pinctrl 9 1>;
 		};
 
 		usb2 {
 			label = "963269BHR:green:usb2";
-			gpios = <&gpio0 10 1>;
+			gpios = <&pinctrl 10 1>;
 		};
 	};
 };
diff --git a/target/linux/brcm63xx/dts/bcm963281TAN.dts b/target/linux/brcm63xx/dts/bcm963281TAN.dts
index 468a855..a1c5d7a 100644
--- a/target/linux/brcm63xx/dts/bcm963281TAN.dts
+++ b/target/linux/brcm63xx/dts/bcm963281TAN.dts
@@ -17,28 +17,28 @@
 
 		inet {
 			label = "963281TAN::internet";
-			gpios = <&gpio0 1 1>;
+			gpios = <&pinctrl 1 1>;
 		};
 		power {
 			label = "963281TAN::power";
-			gpios = <&gpio0 4 1>;
+			gpios = <&pinctrl 4 1>;
 			default-state = "on";
 		};
 		inet_fail {
 			label = "963281TAN::internet-fail";
-			gpios = <&gpio0 7 1>;
+			gpios = <&pinctrl 7 1>;
 		};
 		power_fail {
 			label = "963281TAN::power-fail";
-			gpios = <&gpio0 8 1>;
+			gpios = <&pinctrl 8 1>;
 		};
 		wps {
 			label = "963281TAN::wps";
-			gpios = <&gpio0 9 1>;
+			gpios = <&pinctrl 9 1>;
 		};
 		dsl {
 			label = "963281TAN::dsl";
-			gpios = <&gpio0 11 1>;
+			gpios = <&pinctrl 11 1>;
 		};
 	};
 };
diff --git a/target/linux/brcm63xx/dts/bcm96328avng.dts b/target/linux/brcm63xx/dts/bcm96328avng.dts
index 37f289b..e74a60a 100644
--- a/target/linux/brcm63xx/dts/bcm96328avng.dts
+++ b/target/linux/brcm63xx/dts/bcm96328avng.dts
@@ -17,28 +17,28 @@
 
 		inet_fail {
 			label = "96328avng::internet-fail";
-			gpios = <&gpio0 2 1>;
+			gpios = <&pinctrl 2 1>;
 		};
 		dsl {
 			label = "96328avng::dsl";
-			gpios = <&gpio0 3 1>;
+			gpios = <&pinctrl 3 1>;
 		};
 		power {
 			label = "96328avng::power";
-			gpios = <&gpio0 4 1>;
+			gpios = <&pinctrl 4 1>;
 			default-state = "on";
 		};
 		power_fail {
 			label = "96328avng::power-fail";
-			gpios = <&gpio0 8 1>;
+			gpios = <&pinctrl 8 1>;
 		};
 		wps {
 			label = "96328avng::wps";
-			gpios = <&gpio0 9 1>;
+			gpios = <&pinctrl 9 1>;
 		};
 		inet {
 			label = "96328avng::internet";
-			gpios = <&gpio0 11 1>;
+			gpios = <&pinctrl 11 1>;
 		};
 	};
 };
@@ -59,3 +59,8 @@
 		linux,part-probe = "bcm63xxpart";
 	};
 };
+
+&pinctrl {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usb_port1_device>;
+};
diff --git a/target/linux/brcm63xx/dts/bcm96348GW-10.dts b/target/linux/brcm63xx/dts/bcm96348GW-10.dts
index 5648d03..d788057 100644
--- a/target/linux/brcm63xx/dts/bcm96348GW-10.dts
+++ b/target/linux/brcm63xx/dts/bcm96348GW-10.dts
@@ -21,7 +21,7 @@
 
 		reset {
 			label = "reset";
-			gpios = <&gpio0 6 1>;
+			gpios = <&pinctrl 6 1>;
 			linux,code = <KEY_RESTART>;
 		};
 	};
@@ -31,24 +31,24 @@
 
 		power_green {
 			label = "96348GW-10:green:power";
-			gpios = <&gpio0 0 1>;
+			gpios = <&pinctrl 0 1>;
 			default-state = "on";
 		};
 		stop_green {
 			label = "96348GW-10:green:stop";
-			gpios = <&gpio0 1 1>;
+			gpios = <&pinctrl 1 1>;
 		};
 		adsl_fail_green {
 			label = "96348GW-10:green:adsl-fail";
-			gpios = <&gpio0 2 1>;
+			gpios = <&pinctrl 2 1>;
 		};
 		ppp_green {
 			label = "96348GW-10:green:ppp";
-			gpios = <&gpio0 3 1>;
+			gpios = <&pinctrl 3 1>;
 		};
 		ppp_fail_green {
 			label = "96348GW-10:green:ppp-fail";
-			gpios = <&gpio0 4 1>;
+			gpios = <&pinctrl 4 1>;
 		};
 	};
 };
@@ -58,3 +58,8 @@
 
 	linux,part-probe = "bcm63xxpart";
 };
+
+&pinctrl {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pci &pinctrl_ext_mii &pinctrl_mii_pccard>;
+};
diff --git a/target/linux/brcm63xx/dts/bcm96348GW-11.dts b/target/linux/brcm63xx/dts/bcm96348GW-11.dts
index 78fba83..9ef82e6 100644
--- a/target/linux/brcm63xx/dts/bcm96348GW-11.dts
+++ b/target/linux/brcm63xx/dts/bcm96348GW-11.dts
@@ -21,7 +21,7 @@
 
 		reset {
 			label = "reset";
-			gpios = <&gpio1 1 1>;
+			gpios = <&pinctrl 33 1>;
 			linux,code = <KEY_RESTART>;
 		};
 	};
@@ -31,24 +31,24 @@
 
 		power_green {
 			label = "96348GW-11:green:power";
-			gpios = <&gpio0 0 1>;
+			gpios = <&pinctrl 0 1>;
 			default-state = "on";
 		};
 		stop_green {
 			label = "96348GW-11:green:stop";
-			gpios = <&gpio0 1 1>;
+			gpios = <&pinctrl 1 1>;
 		};
 		adsl_fail_green {
 			label = "96348GW-11:green:adsl-fail";
-			gpios = <&gpio0 2 1>;
+			gpios = <&pinctrl 2 1>;
 		};
 		ppp_green {
 			label = "96348GW-11:green:ppp";
-			gpios = <&gpio0 3 1>;
+			gpios = <&pinctrl 3 1>;
 		};
 		ppp_fail_green {
 			label = "96348GW-11:green:ppp-fail";
-			gpios = <&gpio0 4 1>;
+			gpios = <&pinctrl 4 1>;
 		};
 	};
 };
@@ -58,3 +58,8 @@
 
 	linux,part-probe = "bcm63xxpart";
 };
+
+&pinctrl {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pci &pinctrl_ext_mii &pinctrl_mii_pccard>;
+};
diff --git a/target/linux/brcm63xx/dts/bcm96348GW.dts b/target/linux/brcm63xx/dts/bcm96348GW.dts
index 7699562..d7511b0 100644
--- a/target/linux/brcm63xx/dts/bcm96348GW.dts
+++ b/target/linux/brcm63xx/dts/bcm96348GW.dts
@@ -21,7 +21,7 @@
 
 		reset {
 			label = "reset";
-			gpios = <&gpio1 4 1>;
+			gpios = <&pinctrl 36 1>;
 			linux,code = <KEY_RESTART>;
 		};
 	};
@@ -31,24 +31,24 @@
 
 		power_green {
 			label = "96348GW:green:power";
-			gpios = <&gpio0 0 1>;
+			gpios = <&pinctrl 0 1>;
 			default-state = "on";
 		};
 		stop_green {
 			label = "96348GW:green:stop";
-			gpios = <&gpio0 1 1>;
+			gpios = <&pinctrl 1 1>;
 		};
 		adsl_fail_green {
 			label = "96348GW:green:adsl-fail";
-			gpios = <&gpio0 2 1>;
+			gpios = <&pinctrl 2 1>;
 		};
 		ppp_green {
 			label = "96348GW:green:ppp";
-			gpios = <&gpio0 3 1>;
+			gpios = <&pinctrl 3 1>;
 		};
 		ppp_fail_green {
 			label = "96348GW:green:ppp-fail";
-			gpios = <&gpio0 4 1>;
+			gpios = <&pinctrl 4 1>;
 		};
 	};
 };
@@ -58,3 +58,8 @@
 
 	linux,part-probe = "bcm63xxpart";
 };
+
+&pinctrl {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pci &pinctrl_ext_mii>;
+};
diff --git a/target/linux/brcm63xx/dts/bcm96348R.dts b/target/linux/brcm63xx/dts/bcm96348R.dts
index b103ece..3042693 100644
--- a/target/linux/brcm63xx/dts/bcm96348R.dts
+++ b/target/linux/brcm63xx/dts/bcm96348R.dts
@@ -17,24 +17,24 @@
 
 		power_green {
 			label = "96348R:green:power";
-			gpios = <&gpio0 0 1>;
+			gpios = <&pinctrl 0 1>;
 			default-state = "on";
 		};
 		stop_green {
 			label = "96348R:green:stop";
-			gpios = <&gpio0 1 1>;
+			gpios = <&pinctrl 1 1>;
 		};
 		adsl_fail_green {
 			label = "96348R:green:adsl-fail";
-			gpios = <&gpio0 2 1>;
+			gpios = <&pinctrl 2 1>;
 		};
 		ppp_green {
 			label = "96348R:green:ppp";
-			gpios = <&gpio0 3 1>;
+			gpios = <&pinctrl 3 1>;
 		};
 		ppp_fail_green {
 			label = "96348R:green:ppp-fail";
-			gpios = <&gpio0 4 1>;
+			gpios = <&pinctrl 4 1>;
 		};
 	};
 };
@@ -44,3 +44,8 @@
 
 	linux,part-probe = "bcm63xxpart";
 };
+
+&pinctrl {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pci>;
+};
diff --git a/target/linux/brcm63xx/dts/bcm96358VW.dts b/target/linux/brcm63xx/dts/bcm96358VW.dts
index f916d9d..c2fe5b0 100644
--- a/target/linux/brcm63xx/dts/bcm96358VW.dts
+++ b/target/linux/brcm63xx/dts/bcm96358VW.dts
@@ -17,24 +17,24 @@
 
 		power_green {
 			label = "96358VW:green:power";
-			gpios = <&gpio0 4 0>;
+			gpios = <&pinctrl 4 0>;
 			default-state = "on";
 		};
 		stop_green {
 			label = "96358VW:green:stop";
-			gpios = <&gpio0 5 0>;
+			gpios = <&pinctrl 5 0>;
 		};
 		adsl_fail_green {
 			label = "96358VW:green:adsl-fail";
-			gpios = <&gpio0 15 1>;
+			gpios = <&pinctrl 15 1>;
 		};
 		ppp_green {
 			label = "96358VW:green:ppp";
-			gpios = <&gpio0 22 1>;
+			gpios = <&pinctrl 22 1>;
 		};
 		ppp_fail_green {
 			label = "96358VW:green:ppp-fail";
-			gpios = <&gpio0 23 1>;
+			gpios = <&pinctrl 23 1>;
 		};
 	};
 };
diff --git a/target/linux/brcm63xx/dts/bcm96358VW2.dts b/target/linux/brcm63xx/dts/bcm96358VW2.dts
index 20af61a..cc4a8b5 100644
--- a/target/linux/brcm63xx/dts/bcm96358VW2.dts
+++ b/target/linux/brcm63xx/dts/bcm96358VW2.dts
@@ -17,20 +17,20 @@
 
 		stop_green {
 			label = "96358VW2:green:stop";
-			gpios = <&gpio0 4 1>;
+			gpios = <&pinctrl 4 1>;
 		};
 		power_green {
 			label = "96358VW2:green:power";
-			gpios = <&gpio0 5 1>;
+			gpios = <&pinctrl 5 1>;
 			default-state = "on";
 		};
 		adsl_green {
 			label = "96358VW2:green:adsl";
-			gpios = <&gpio0 22 1>;
+			gpios = <&pinctrl 22 1>;
 		};
 		ppp_fail_green {
 			label = "96358VW2:green:ppp-fail";
-			gpios = <&gpio0 23 0>;
+			gpios = <&pinctrl 23 0>;
 		};
 	};
 };
diff --git a/target/linux/brcm63xx/dts/bcm96368MVNgr.dts b/target/linux/brcm63xx/dts/bcm96368MVNgr.dts
index ca07b65..1078be7 100644
--- a/target/linux/brcm63xx/dts/bcm96368MVNgr.dts
+++ b/target/linux/brcm63xx/dts/bcm96368MVNgr.dts
@@ -17,24 +17,24 @@
 
 		dsl_green {
 			label = "96368MVNgr:green:adsl";
-			gpios = <&gpio0 2 1>;
+			gpios = <&pinctrl 2 1>;
 		};
 		inet_fail_green {
 			label = "96368MVNgr:green:inet-fail";
-			gpios = <&gpio0 3 0>;
+			gpios = <&pinctrl 3 0>;
 		};
 		inet_green {
 			label = "96368MVNgr:green:inet";
-			gpios = <&gpio0 5 0>;
+			gpios = <&pinctrl 5 0>;
 		};
 		power_green {
 			label = "96368MVNgr:green:power";
-			gpios = <&gpio0 22 0>;
+			gpios = <&pinctrl 22 0>;
 			default-state = "on";
 		};
 		wps_green {
 			label = "96368MVNgr:green:wps";
-			gpios = <&gpio0 23 1>;
+			gpios = <&pinctrl 23 1>;
 		};
 	};
 };
@@ -44,3 +44,8 @@
 
 	linux,part-probe = "bcm63xxpart";
 };
+
+&pinctrl {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pci>;
+};
diff --git a/target/linux/brcm63xx/dts/bcm96368MVWG.dts b/target/linux/brcm63xx/dts/bcm96368MVWG.dts
index 9f13ca4..0f7c42b 100644
--- a/target/linux/brcm63xx/dts/bcm96368MVWG.dts
+++ b/target/linux/brcm63xx/dts/bcm96368MVWG.dts
@@ -17,24 +17,24 @@
 
 		dsl_green {
 			label = "96368MVWG:green:adsl";
-			gpios = <&gpio0 2 1>;
+			gpios = <&pinctrl 2 1>;
 		};
 		ppp_green {
 			label = "96368MVWG:green:ppp";
-			gpios = <&gpio0 5 0>;
+			gpios = <&pinctrl 5 0>;
 		};
 		power_green {
 			label = "96368MVWG:green:power";
-			gpios = <&gpio0 22 0>;
+			gpios = <&pinctrl 22 0>;
 			default-state = "on";
 		};
 		wps_green {
 			label = "96368MVWG:green:wps";
-			gpios = <&gpio0 23 1>;
+			gpios = <&pinctrl 23 1>;
 		};
 		ppp_fail_red {
 			label = "96368MVWG:red:ppp-fail";
-			gpios = <&gpio0 31 0>;
+			gpios = <&pinctrl 31 0>;
 		};
 	};
 };
@@ -44,3 +44,8 @@
 
 	linux,part-probe = "bcm63xxpart";
 };
+
+&pinctrl {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pci>;
+};
diff --git a/target/linux/brcm63xx/dts/cpva502plus.dts b/target/linux/brcm63xx/dts/cpva502plus.dts
index 3ddc459..dbe7aae 100644
--- a/target/linux/brcm63xx/dts/cpva502plus.dts
+++ b/target/linux/brcm63xx/dts/cpva502plus.dts
@@ -21,7 +21,7 @@
 
 		reset {
 			label = "reset";
-			gpios = <&gpio1 4 1>;
+			gpios = <&pinctrl 36 1>;
 			linux,code = <KEY_RESTART>;
 		};
 	};
@@ -31,12 +31,12 @@
 
 		phone_green {
 			label = "CPVA502+:green:phone";
-			gpios = <&gpio0 0 1>;
+			gpios = <&pinctrl 0 1>;
 		};
 
 		link_amber {
 			label = "CPVA502+:amber:link";
-			gpios = <&gpio0 5 1>;
+			gpios = <&pinctrl 5 1>;
 		};
 	};
 };
@@ -62,3 +62,8 @@
 		reg = <0x3f0000 0x010000>;
 	};
 };
+
+&pinctrl {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pci &pinctrl_ext_mii>;
+};
diff --git a/target/linux/brcm63xx/dts/cpva642.dts b/target/linux/brcm63xx/dts/cpva642.dts
index 1a0522d..108997d 100644
--- a/target/linux/brcm63xx/dts/cpva642.dts
+++ b/target/linux/brcm63xx/dts/cpva642.dts
@@ -21,12 +21,12 @@
 
 		reset {
 			label = "reset";
-			gpios = <&gpio1 4 1>;
+			gpios = <&pinctrl 36 1>;
 			linux,code = <KEY_RESTART>;
 		};
 		wps {
 			label = "wps";
-			gpios = <&gpio1 5 0>;
+			gpios = <&pinctrl 37 0>;
 			linux,code = <KEY_WPS_BUTTON>;
 		};
 	};
@@ -36,44 +36,44 @@
 
 		eth_green {
 			label = "CPVA642:green:ether";
-			gpios = <&gpio0 1 1>;
+			gpios = <&pinctrl 1 1>;
 		};
 		phone2_green {
 			label = "CPVA642:green:phone2";
-			gpios = <&gpio0 2 1>;
+			gpios = <&pinctrl 2 1>;
 		};
 		usb_green {
 			label = "CPVA642:green:usb";
-			gpios = <&gpio0 3 1>;
+			gpios = <&pinctrl 3 1>;
 		};
 		phone1_green {
 			label = "CPVA642:green:phone1";
-			gpios = <&gpio0 4 1>;
+			gpios = <&pinctrl 4 1>;
 		};
 		wifi_red {
 			label = "CPVA642:red:wifi";
-			gpios = <&gpio0 6 1>;
+			gpios = <&pinctrl 6 1>;
 		};
 		link_red {
 			label = "CPVA642:red:link";
-			gpios = <&gpio0 9 1>;
+			gpios = <&pinctrl 9 1>;
 		};
 		link_green {
 			label = "CPVA642:green:link";
-			gpios = <&gpio0 10 1>;
+			gpios = <&pinctrl 10 1>;
 		};
 		power_green {
 			label = "CPVA642:green:power";
-			gpios = <&gpio0 11 1>;
+			gpios = <&pinctrl 11 1>;
 			default-state = "on";
 		};
 		power_red {
 			label = "CPVA642:red:power";
-			gpios = <&gpio0 14 1>;
+			gpios = <&pinctrl 14 1>;
 		};
 		wifi_green {
 			label = "CPVA642:green:wifi";
-			gpios = <&gpio0 28 0>;
+			gpios = <&pinctrl 28 0>;
 		};
 	};
 };
diff --git a/target/linux/brcm63xx/dts/ct-5365.dts b/target/linux/brcm63xx/dts/ct-5365.dts
index 8187be6..f067649 100644
--- a/target/linux/brcm63xx/dts/ct-5365.dts
+++ b/target/linux/brcm63xx/dts/ct-5365.dts
@@ -21,17 +21,17 @@
 
 		reset {
 			label = "reset";
-			gpios = <&gpio1 1 1>;
+			gpios = <&pinctrl 33 1>;
 			linux,code = <KEY_RESTART>;
 		};
 		wlan {
 			label = "wlan";
-			gpios = <&gpio1 2 1>;
+			gpios = <&pinctrl 34 1>;
 			linux,code = <KEY_WLAN>;
 		};
 		wps {
 			label = "wps";
-			gpios = <&gpio1 3 1>;
+			gpios = <&pinctrl 35 1>;
 			linux,code = <KEY_WPS_BUTTON>;
 		};
 	};
@@ -41,16 +41,16 @@
 
 		power_green {
 			label = "96348A-122:green:power";
-			gpios = <&gpio0 0 1>;
+			gpios = <&pinctrl 0 1>;
 			default-state = "on";
 		};
 		alarm_red {
 			label = "96348A-122:red:alarm";
-			gpios = <&gpio0 2 1>;
+			gpios = <&pinctrl 2 1>;
 		};
 		wps_green {
 			label = "96348A-122:green:wps";
-			gpios = <&gpio0 6 1>;
+			gpios = <&pinctrl 6 1>;
 		};
 	};
 };
@@ -76,3 +76,8 @@
 		reg = <0x3f0000 0x010000>;
 	};
 };
+
+&pinctrl {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pci &pinctrl_ext_mii>;
+};
diff --git a/target/linux/brcm63xx/dts/ct-6373.dts b/target/linux/brcm63xx/dts/ct-6373.dts
index f2a5842..8e6eb45 100644
--- a/target/linux/brcm63xx/dts/ct-6373.dts
+++ b/target/linux/brcm63xx/dts/ct-6373.dts
@@ -17,8 +17,8 @@
 		#size-cells = <0>;
 		compatible = "spi-gpio";
 
-		gpio-mosi = <&gpio0 7 0>;
-		gpio-sck = <&gpio0 6 0>;
+		gpio-mosi = <&pinctrl 7 0>;
+		gpio-sck = <&pinctrl 6 0>;
 		num-chipselects = <0>;
 
 		hc595: gpio-spi-controller at 0 {
@@ -41,7 +41,7 @@
 
 		reset {
 			label = "reset";
-			gpios = <&gpio1 3 1>;
+			gpios = <&pinctrl 35 1>;
 			linux,code = <KEY_RESTART>;
 		};
 	};
@@ -51,16 +51,16 @@
 
 		power_green {
 			label = "CT6373-1:green:power";
-			gpios = <&gpio0 0 0>;
+			gpios = <&pinctrl 0 0>;
 			default-state = "on";
 		};
 		usb_green {
 			label = "CT6373-1:green:usb";
-			gpios = <&gpio0 3 1>;
+			gpios = <&pinctrl 3 1>;
 		};
 		wlan_green {
 			label = "CT6373-1:green:wlan";
-			gpios = <&gpio0 9 1>;
+			gpios = <&pinctrl 9 1>;
 		};
 		dsl_green {
 			label = "CT6373-1:green:adsl";
diff --git a/target/linux/brcm63xx/dts/ct536plus.dts b/target/linux/brcm63xx/dts/ct536plus.dts
index 8be4940..8aa4757 100644
--- a/target/linux/brcm63xx/dts/ct536plus.dts
+++ b/target/linux/brcm63xx/dts/ct536plus.dts
@@ -21,7 +21,7 @@
 
 		reset {
 			label = "reset";
-			gpios = <&gpio1 1 1>;
+			gpios = <&pinctrl 33 1>;
 			linux,code = <KEY_RESTART>;
 		};
 	};
@@ -31,12 +31,12 @@
 
 		power_green {
 			label = "CT536_CT5621:green:power";
-			gpios = <&gpio0 0 1>;
+			gpios = <&pinctrl 0 1>;
 			default-state = "on";
 		};
 		adsl_fail_green {
 			label = "CT536_CT5621:green:adsl-fail";
-			gpios = <&gpio0 2 1>;
+			gpios = <&pinctrl 2 1>;
 		};
 	};
 };
@@ -62,3 +62,8 @@
 		reg = <0x3f0000 0x010000>;
 	};
 };
+
+&pinctrl {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pci &pinctrl_ext_mii &pinctrl_mii_pccard>;
+};
diff --git a/target/linux/brcm63xx/dts/dg834g_v4.dts b/target/linux/brcm63xx/dts/dg834g_v4.dts
index ee63473..0af695d 100644
--- a/target/linux/brcm63xx/dts/dg834g_v4.dts
+++ b/target/linux/brcm63xx/dts/dg834g_v4.dts
@@ -21,7 +21,7 @@
 
 		reset {
 			label = "reset";
-			gpios = <&gpio0 6 1>;
+			gpios = <&pinctrl 6 1>;
 			linux,code = <KEY_RESTART>;
 		};
 	};
@@ -31,20 +31,20 @@
 
 		power_green {
 			label = "96348W3:green:power";
-			gpios = <&gpio0 0 1>;
+			gpios = <&pinctrl 0 1>;
 			default-state = "on";
 		};
 		status {
 			label = "96348W3:red:power";
-			gpios = <&gpio0 1 1>;
+			gpios = <&pinctrl 1 1>;
 		};
 		inet_green {
 			label = "96348W3::adsl";
-			gpios = <&gpio0 2 1>;
+			gpios = <&pinctrl 2 1>;
 		};
 		inet_red {
 			label = "96348W3::internet";
-			gpios = <&gpio0 3 1>;
+			gpios = <&pinctrl 3 1>;
 		};
 	};
 };
@@ -70,3 +70,8 @@
 		reg = <0x3f0000 0x010000>;
 	};
 };
+
+&pinctrl {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pci &pinctrl_ext_mii>;
+};
diff --git a/target/linux/brcm63xx/dts/dg834gtpn.dts b/target/linux/brcm63xx/dts/dg834gtpn.dts
index 9bd67f4..84ef9b2 100644
--- a/target/linux/brcm63xx/dts/dg834gtpn.dts
+++ b/target/linux/brcm63xx/dts/dg834gtpn.dts
@@ -21,7 +21,7 @@
 
 		reset {
 			label = "reset";
-			gpios = <&gpio0 6 1>;
+			gpios = <&pinctrl 6 1>;
 			linux,code = <KEY_RESTART>;
 		};
 	};
@@ -31,24 +31,24 @@
 
 		power_green {
 			label = "96348GW-10:green:power";
-			gpios = <&gpio0 0 1>;
+			gpios = <&pinctrl 0 1>;
 			default-state = "on";
 		};
 		stop_green {
 			label = "96348GW-10:green:stop";
-			gpios = <&gpio0 1 1>;
+			gpios = <&pinctrl 1 1>;
 		};
 		adsl_fail_green {
 			label = "96348GW-10:green:adsl-fail";
-			gpios = <&gpio0 2 1>;
+			gpios = <&pinctrl 2 1>;
 		};
 		ppp_green {
 			label = "96348GW-10:green:ppp";
-			gpios = <&gpio0 3 1>;
+			gpios = <&pinctrl 3 1>;
 		};
 		ppp_fail_green {
 			label = "96348GW-10:green:ppp-fail";
-			gpios = <&gpio0 4 1>;
+			gpios = <&pinctrl 4 1>;
 		};
 	};
 };
@@ -74,3 +74,8 @@
 		reg = <0x3f0000 0x010000>;
 	};
 };
+
+&pinctrl {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pci &pinctrl_ext_mii &pinctrl_mii_pccard>;
+};
diff --git a/target/linux/brcm63xx/dts/dgnd3700v1.dts b/target/linux/brcm63xx/dts/dgnd3700v1.dts
index 2b6248b..7701bd0 100644
--- a/target/linux/brcm63xx/dts/dgnd3700v1.dts
+++ b/target/linux/brcm63xx/dts/dgnd3700v1.dts
@@ -21,17 +21,17 @@
 
 		wlan {
 			label = "wlan";
-			gpios = <&gpio0 10 1>;
+			gpios = <&pinctrl 10 1>;
 			linux,code = <KEY_WLAN>;
 		};
 		reset {
 			label = "reset";
-			gpios = <&gpio0 12 1>;
+			gpios = <&pinctrl 12 1>;
 			linux,code = <KEY_RESTART>;
 		};
 		wps {
 			label = "wps";
-			gpios = <&gpio1 3 1>;
+			gpios = <&pinctrl 35 1>;
 			linux,code = <KEY_WPS_BUTTON>;
 		};
 	};
@@ -41,48 +41,48 @@
 
 		dsl_green {
 			label = "DGND3700v1_3800B:green:dsl";
-			gpios = <&gpio0 2 1>;
+			gpios = <&pinctrl 2 1>;
 		};
 		inet_red {
 			label = "DGND3700v1_3800B:red:inet";
-			gpios = <&gpio0 4 1>;
+			gpios = <&pinctrl 4 1>;
 		};
 		inet_green {
 			label = "DGND3700v1_3800B:green:inet";
-			gpios = <&gpio0 5 1>;
+			gpios = <&pinctrl 5 1>;
 		};
 		wps_green {
 			label = "DGND3700v1_3800B:green:wps";
-			gpios = <&gpio0 11 1>;
+			gpios = <&pinctrl 11 1>;
 		};
 		usbfront_green {
 			label = "DGND3700v1_3800B:green:usb-front";
-			gpios = <&gpio0 13 1>;
+			gpios = <&pinctrl 13 1>;
 		};
 		usbback_green {
 			label = "DGND3700v1_3800B:green:usb-back";
-			gpios = <&gpio0 14 1>;
+			gpios = <&pinctrl 14 1>;
 		};
 		power_red {
 			label = "DGND3700v1_3800B:red:power";
-			gpios = <&gpio0 22 1>;
+			gpios = <&pinctrl 22 1>;
 		};
 		lan_green {
 			label = "DGND3700v1_3800B:green:lan";
-			gpios = <&gpio0 23 1>;
+			gpios = <&pinctrl 23 1>;
 		};
 		power_green {
 			label = "DGND3700v1_3800B:green:power";
-			gpios = <&gpio0 24 1>;
+			gpios = <&pinctrl 24 1>;
 			default-state = "on";
 		};
 		wifi2g_green {
 			label = "DGND3700v1_3800B:green:wifi2g";
-			gpios = <&gpio0 26 1>;
+			gpios = <&pinctrl 26 1>;
 		};
 		wifi5g_blue {
 			label = "DGND3700v1_3800B:blue:wifi5g";
-			gpios = <&gpio0 27 1>;
+			gpios = <&pinctrl 27 1>;
 		};
 	};
 };
@@ -113,4 +113,9 @@
 		label = "nvram";
 		reg = <0x1fe0000 0x20000>;
 	};
+}; 
+
+&pinctrl {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pci>;
 };
diff --git a/target/linux/brcm63xx/dts/dsl-2640b-b.dts b/target/linux/brcm63xx/dts/dsl-2640b-b.dts
index 767586d..fce774d 100644
--- a/target/linux/brcm63xx/dts/dsl-2640b-b.dts
+++ b/target/linux/brcm63xx/dts/dsl-2640b-b.dts
@@ -21,7 +21,7 @@
 
 		reset {
 			label = "reset";
-			gpios = <&gpio0 7 1>;
+			gpios = <&pinctrl 7 1>;
 			linux,code = <KEY_RESTART>;
 		};
 	};
@@ -31,20 +31,20 @@
 
 		power_green {
 			label = "D-4P-W:green:power";
-			gpios = <&gpio0 0 1>;
+			gpios = <&pinctrl 0 1>;
 			default-state = "on";
 		};
 		status {
 			label = "D-4P-W::status";
-			gpios = <&gpio0 3 1>;
+			gpios = <&pinctrl 3 1>;
 		};
 		inet_green {
 			label = "D-4P-W:green:internet";
-			gpios = <&gpio0 4 1>;
+			gpios = <&pinctrl 4 1>;
 		};
 		inet_red {
 			label = "D-4P-W:red:internet";
-			gpios = <&gpio0 5 1>;
+			gpios = <&pinctrl 5 1>;
 		};
 	};
 };
@@ -70,3 +70,8 @@
 		reg = <0x3f0000 0x010000>;
 	};
 };
+
+&pinctrl {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pci &pinctrl_ext_mii>;
+};
diff --git a/target/linux/brcm63xx/dts/dsl-2650u.dts b/target/linux/brcm63xx/dts/dsl-2650u.dts
index ed42f63..4b45151 100644
--- a/target/linux/brcm63xx/dts/dsl-2650u.dts
+++ b/target/linux/brcm63xx/dts/dsl-2650u.dts
@@ -17,20 +17,20 @@
 
 		stop_green {
 			label = "96358VW2:green:stop";
-			gpios = <&gpio0 4 1>;
+			gpios = <&pinctrl 4 1>;
 		};
 		power_green {
 			label = "96358VW2:green:power";
-			gpios = <&gpio0 5 1>;
+			gpios = <&pinctrl 5 1>;
 			default-state = "on";
 		};
 		adsl_green {
 			label = "96358VW2:green:adsl";
-			gpios = <&gpio0 22 1>;
+			gpios = <&pinctrl 22 1>;
 		};
 		ppp_fail_green {
 			label = "96358VW2:green:ppp-fail";
-			gpios = <&gpio0 23 0>;
+			gpios = <&pinctrl 23 0>;
 		};
 	};
 };
diff --git a/target/linux/brcm63xx/dts/dsl-274xb-c.dts b/target/linux/brcm63xx/dts/dsl-274xb-c.dts
index 10bf9a5..fb67fc9 100644
--- a/target/linux/brcm63xx/dts/dsl-274xb-c.dts
+++ b/target/linux/brcm63xx/dts/dsl-274xb-c.dts
@@ -21,7 +21,7 @@
 
 		reset {
 			label = "reset";
-			gpios = <&gpio1 2 1>;
+			gpios = <&pinctrl 34 1>;
 			linux,code = <KEY_RESTART>;
 		};
 	};
@@ -31,24 +31,24 @@
 
 		inet_green {
 			label = "dsl-274xb:green:internet";
-			gpios = <&gpio0 2 0>;
+			gpios = <&pinctrl 2 0>;
 		};
 		power_red {
 			label = "dsl-274xb:red:power";
-			gpios = <&gpio0 4 1>;
+			gpios = <&pinctrl 4 1>;
 		};
 		power_green {
 			label = "dsl-274xb:green:power";
-			gpios = <&gpio0 5 1>;
+			gpios = <&pinctrl 5 1>;
 			default-state = "on";
 		};
 		dsl_green {
 			label = "dsl-274xb:green:adsl";
-			gpios = <&gpio0 9 1>;
+			gpios = <&pinctrl 9 1>;
 		};
 		inet_red {
 			label = "dsl-274xb:red:internet";
-			gpios = <&gpio0 10 0>;
+			gpios = <&pinctrl 10 0>;
 		};
 	};
 };
diff --git a/target/linux/brcm63xx/dts/dsl-274xb-f.dts b/target/linux/brcm63xx/dts/dsl-274xb-f.dts
index 08a5592..be1d16b 100644
--- a/target/linux/brcm63xx/dts/dsl-274xb-f.dts
+++ b/target/linux/brcm63xx/dts/dsl-274xb-f.dts
@@ -21,17 +21,17 @@
 
 		wifi {
 			label = "wifi";
-			gpios = <&gpio0 10 1>;
+			gpios = <&pinctrl 10 1>;
 			linux,code = <KEY_WLAN>;
 		};
 		reset {
 			label = "reset";
-			gpios = <&gpio0 23 1>;
+			gpios = <&pinctrl 23 1>;
 			linux,code = <KEY_RESTART>;
 		};
 		wps {
 			label = "wps";
-			gpios = <&gpio0 24 1>;
+			gpios = <&pinctrl 24 1>;
 			linux,code = <KEY_WPS_BUTTON>;
 		};
 	};
@@ -41,28 +41,28 @@
 
 		inet_red {
 			label = "dsl-274xb:red:internet";
-			gpios = <&gpio0 2 1>;
+			gpios = <&pinctrl 2 1>;
 		};
 		dsl_green {
 			label = "dsl-274xb:green:dsl";
-			gpios = <&gpio0 3 1>;
+			gpios = <&pinctrl 3 1>;
 		};
 		power_green {
 			label = "dsl-274xb:green:power";
-			gpios = <&gpio0 4 1>;
+			gpios = <&pinctrl 4 1>;
 			default-state = "on";
 		};
 		power_red {
 			label = "dsl-274xb:red:power";
-			gpios = <&gpio0 8 1>;
+			gpios = <&pinctrl 8 1>;
 		};
 		wps_blue {
 			label = "dsl-274xb:blue:wps";
-			gpios = <&gpio0 9 1>;
+			gpios = <&pinctrl 9 1>;
 		};
 		inet_green {
 			label = "dsl-274xb:green:internet";
-			gpios = <&gpio0 11 1>;
+			gpios = <&pinctrl 11 1>;
 		};
 	};
 };
diff --git a/target/linux/brcm63xx/dts/dsl-275xb-d.dts b/target/linux/brcm63xx/dts/dsl-275xb-d.dts
index cae6f37..bbcce3c3 100644
--- a/target/linux/brcm63xx/dts/dsl-275xb-d.dts
+++ b/target/linux/brcm63xx/dts/dsl-275xb-d.dts
@@ -21,19 +21,19 @@
 
 		wifi {
 			label = "wifi";
-			gpios = <&gpio0 2 1>;
+			gpios = <&pinctrl 2 1>;
 			linux,code = <KEY_WLAN>;
 		};
 
 		wps {
 			label = "wps";
-			gpios = <&gpio1 1 1>;
+			gpios = <&pinctrl 33 1>;
 			linux,code = <KEY_WPS_BUTTON>;
 		};
 
 		reset {
 			label = "reset";
-			gpios = <&gpio1 2 1>;
+			gpios = <&pinctrl 34 1>;
 			linux,code = <KEY_RESTART>;
 		};
 	};
@@ -43,39 +43,39 @@
 
 		power_green {
 			label = "dsl-275xb:green:power";
-			gpios = <&gpio0 3 1>;
+			gpios = <&pinctrl 3 1>;
 			default-state = "on";
 		};
 
 		inet_green {
 			label = "dsl-275xb:green:inet";
-			gpios = <&gpio0 8 1>;
+			gpios = <&pinctrl 8 1>;
 		};
 
 		inet_red {
 			label = "dsl-275xb:red:inet-fail";
-			gpios = <&gpio0 9 1>;
+			gpios = <&pinctrl 9 1>;
 		};
 
 		power_red {
 			label = "dsl-275xb:red:post-failed";
-			gpios = <&gpio0 11 1>;
+			gpios = <&pinctrl 11 1>;
 		};
 
 		wps_blue {
 			label = "dsl-275xb:blue:wps";
-			gpios = <&gpio0 16 1>;
+			gpios = <&pinctrl 16 1>;
 		};
 
 		dsl_green {
 			label = "dsl-275xb:green:dsl";
-			gpios = <&gpio0 17 1>;
+			gpios = <&pinctrl 17 1>;
 		};
 
 		usb_green {
 			/* not user controllable? */
 			label = "dsl-275xb:green:usb";
-			gpios = <&gpio1 17 1>;
+			gpios = <&pinctrl 49 1>;
 		};
 	};
 };
diff --git a/target/linux/brcm63xx/dts/dv-201amr.dts b/target/linux/brcm63xx/dts/dv-201amr.dts
index 9d96e74..e695519 100644
--- a/target/linux/brcm63xx/dts/dv-201amr.dts
+++ b/target/linux/brcm63xx/dts/dv-201amr.dts
@@ -34,3 +34,8 @@
 		reg = <0x410000 0x3f0000>;
 	};
 };
+
+&pinctrl {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pci &pinctrl_ext_mii>;
+};
diff --git a/target/linux/brcm63xx/dts/dva-g3810bn_tl.dts b/target/linux/brcm63xx/dts/dva-g3810bn_tl.dts
index abd358e..4ebb25d 100644
--- a/target/linux/brcm63xx/dts/dva-g3810bn_tl.dts
+++ b/target/linux/brcm63xx/dts/dva-g3810bn_tl.dts
@@ -21,7 +21,7 @@
 
 		reset {
 			label = "reset";
-			gpios = <&gpio1 2 1>;
+			gpios = <&pinctrl 34 1>;
 			linux,code = <KEY_RESTART>;
 		};
 	};
@@ -31,24 +31,24 @@
 
 		voip {
 			label = "DVAG3810BN::voip";
-			gpios = <&gpio0 1 0>;
+			gpios = <&pinctrl 1 0>;
 		};
 		power {
 			label = "DVAG3810BN::power";
-			gpios = <&gpio0 4 0>;
+			gpios = <&pinctrl 4 0>;
 			default-state = "on";
 		};
 		stop {
 			label = "DVAG3810BN::stop";
-			gpios = <&gpio0 5 0>;
+			gpios = <&pinctrl 5 0>;
 		};
 		dsl {
 			label = "DVAG3810BN::dsl";
-			gpios = <&gpio0 22 1>;
+			gpios = <&pinctrl 22 1>;
 		};
 		inet {
 			label = "DVAG3810BN::internet";
-			gpios = <&gpio0 23 1>;
+			gpios = <&pinctrl 23 1>;
 		};
 	};
 };
diff --git a/target/linux/brcm63xx/dts/evg2000.dts b/target/linux/brcm63xx/dts/evg2000.dts
index 79f26b9..07c98f1 100644
--- a/target/linux/brcm63xx/dts/evg2000.dts
+++ b/target/linux/brcm63xx/dts/evg2000.dts
@@ -21,12 +21,12 @@
 
 		reset {
 			label = "reset";
-			gpios = <&gpio0 25 1>;
+			gpios = <&pinctrl 25 1>;
 			linux,code = <KEY_RESTART>;
 		};
 		wps {
 			label = "wps";
-			gpios = <&gpio0 26 1>;
+			gpios = <&pinctrl 26 1>;
 			linux,code = <KEY_WPS_BUTTON>;
 		};
 	};
@@ -36,44 +36,44 @@
 
 		voip1_green {
 			label = "EVG2000:green:voip1";
-			gpios = <&gpio0 14 1>;
+			gpios = <&pinctrl 14 1>;
 		};
 		voip2_green {
 			label = "EVG2000:green:voip2";
-			gpios = <&gpio0 2 1>;
+			gpios = <&pinctrl 2 1>;
 		};
 		inet_red {
 			label = "EVG2000:red:inet";
-			gpios = <&gpio0 4 1>;
+			gpios = <&pinctrl 4 1>;
 		};
 		inet_green {
 			label = "EVG2000:green:inet";
-			gpios = <&gpio0 5 1>;
+			gpios = <&pinctrl 5 1>;
 		};
 		usb_green {
 			label = "EVG2000:green:usb";
-			gpios = <&gpio0 15 1>;
+			gpios = <&pinctrl 15 1>;
 		};
 		power_green {
 			label = "EVG2000:green:power";
-			gpios = <&gpio0 22 1>;
+			gpios = <&pinctrl 22 1>;
 			default-state = "on";
 		};
 		power_red {
 			label = "EVG2000:red:power";
-			gpios = <&gpio0 23 1>;
+			gpios = <&pinctrl 23 1>;
 		};
 		lan_green {
 			label = "EVG2000:green:lan";
-			gpios = <&gpio0 24 1>;
+			gpios = <&pinctrl 24 1>;
 		};
 		wireless_green {
 			label = "EVG2000:green:wireless";
-			gpios = <&gpio0 26 1>;
+			gpios = <&pinctrl 26 1>;
 		};
 		wan_green {
 			label = "EVG2000:green:wan";
-			gpios = <&gpio0 27 1>;
+			gpios = <&pinctrl 27 1>;
 		};
 	};
 };
@@ -105,3 +105,8 @@
 		reg = <0x00fe0000 0x00020000>;
 	};
 };
+
+&pinctrl {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pci>;
+};
diff --git a/target/linux/brcm63xx/dts/f5d7633.dts b/target/linux/brcm63xx/dts/f5d7633.dts
index 2dae1af..27e81a3 100644
--- a/target/linux/brcm63xx/dts/f5d7633.dts
+++ b/target/linux/brcm63xx/dts/f5d7633.dts
@@ -21,7 +21,7 @@
 
 		reset {
 			label = "reset";
-			gpios = <&gpio0 6 1>;
+			gpios = <&pinctrl 6 1>;
 			linux,code = <KEY_RESTART>;
 		};
 	};
@@ -31,24 +31,24 @@
 
 		power_green {
 			label = "96348GW-10:green:power";
-			gpios = <&gpio0 0 1>;
+			gpios = <&pinctrl 0 1>;
 			default-state = "on";
 		};
 		stop_green {
 			label = "96348GW-10:green:stop";
-			gpios = <&gpio0 1 1>;
+			gpios = <&pinctrl 1 1>;
 		};
 		adsl_fail_green {
 			label = "96348GW-10:green:adsl-fail";
-			gpios = <&gpio0 2 1>;
+			gpios = <&pinctrl 2 1>;
 		};
 		ppp_green {
 			label = "96348GW-10:green:ppp";
-			gpios = <&gpio0 3 1>;
+			gpios = <&pinctrl 3 1>;
 		};
 		ppp_fail_green {
 			label = "96348GW-10:green:ppp-fail";
-			gpios = <&gpio0 4 1>;
+			gpios = <&pinctrl 4 1>;
 		};
 	};
 };
@@ -74,3 +74,8 @@
 		reg = <0x3e0000 0x020000>;
 	};
 };
+
+&pinctrl {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pci &pinctrl_ext_mii &pinctrl_mii_pccard>;
+};
diff --git a/target/linux/brcm63xx/dts/fast2404.dts b/target/linux/brcm63xx/dts/fast2404.dts
index 29211e6..ce52af6 100644
--- a/target/linux/brcm63xx/dts/fast2404.dts
+++ b/target/linux/brcm63xx/dts/fast2404.dts
@@ -34,3 +34,8 @@
 		reg = <0x3f0000 0x010000>;
 	};
 };
+
+&pinctrl {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pci &pinctrl_ext_mii &pinctrl_mii_pccard>;
+};
diff --git a/target/linux/brcm63xx/dts/fast2504n.dts b/target/linux/brcm63xx/dts/fast2504n.dts
index 5492338..296bc09 100644
--- a/target/linux/brcm63xx/dts/fast2504n.dts
+++ b/target/linux/brcm63xx/dts/fast2504n.dts
@@ -21,12 +21,12 @@
 
 		reset {
 			label = "reset";
-			gpios = <&gpio0 24 1>;
+			gpios = <&pinctrl 24 1>;
 			linux,code = <KEY_RESTART>;
 		};
 		wps {
 			label = "wps";
-			gpios = <&gpio0 25 1>;
+			gpios = <&pinctrl 25 1>;
 			linux,code = <KEY_WPS_BUTTON>;
 		};
 	};
@@ -36,28 +36,28 @@
 
 		power_orange {
 			label = "fast2504n:orange:power";
-			gpios = <&gpio0 2 1>;
+			gpios = <&pinctrl 2 1>;
 		};
 		power_green {
 			label = "fast2504n:green:power";
-			gpios = <&gpio0 10 1>;
+			gpios = <&pinctrl 10 1>;
 			default-state = "on";
 		};
 		inet_red {
 			label = "fast2504n:red:internet";
-			gpios = <&gpio0 26 1>;
+			gpios = <&pinctrl 26 1>;
 		};
 		ok_green {
 			label = "fast2504n:green:ok";
-			gpios = <&gpio0 28 1>;
+			gpios = <&pinctrl 28 1>;
 		};
 		ok_orange {
 			label = "fast2504n:orange:ok";
-			gpios = <&gpio0 29 1>;
+			gpios = <&pinctrl 29 1>;
 		};
 		wlan_orangee {
 			label = "fast2504n:orange:wlan";
-			gpios = <&gpio0 30 1>;
+			gpios = <&pinctrl 30 1>;
 		};
 	};
 };
diff --git a/target/linux/brcm63xx/dts/fast2604.dts b/target/linux/brcm63xx/dts/fast2604.dts
index 5d7192f..952b668 100644
--- a/target/linux/brcm63xx/dts/fast2604.dts
+++ b/target/linux/brcm63xx/dts/fast2604.dts
@@ -21,7 +21,7 @@
 
 		reset {
 			label = "reset";
-			gpios = <&gpio1 1 1>;
+			gpios = <&pinctrl 33 1>;
 			linux,code = <KEY_RESTART>;
 		};
 	};
@@ -31,20 +31,20 @@
 
 		power_green {
 			label = "F at ST2604:green:power";
-			gpios = <&gpio0 0 1>;
+			gpios = <&pinctrl 0 1>;
 			default-state = "on";
 		};
 		power_red {
 			label = "F at ST2604:red:power";
-			gpios = <&gpio0 1 1>;
+			gpios = <&pinctrl 1 1>;
 		};
 		inet_red {
 			label = "F at ST2604:red:inet";
-			gpios = <&gpio0 4 1>;
+			gpios = <&pinctrl 4 1>;
 		};
 		wps_green {
 			label = "F at ST2604:green:wps";
-			gpios = <&gpio0 5 1>;
+			gpios = <&pinctrl 5 1>;
 		};
 	};
 };
@@ -70,3 +70,8 @@
 		reg = <0x3f0000 0x010000>;
 	};
 };
+
+&pinctrl {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pci &pinctrl_ext_mii>;
+};
diff --git a/target/linux/brcm63xx/dts/fast2704n.dts b/target/linux/brcm63xx/dts/fast2704n.dts
index 8a3c05b..ee343a6 100644
--- a/target/linux/brcm63xx/dts/fast2704n.dts
+++ b/target/linux/brcm63xx/dts/fast2704n.dts
@@ -21,17 +21,17 @@
 
 		wlan {
 			label = "wlan";
-			gpios = <&gpio0 1 0>;
+			gpios = <&pinctrl 1 0>;
 			linux,code = <KEY_WLAN>;
 		};
 		wps {
 			label = "wps";
-			gpios = <&gpio1 1 1>;
+			gpios = <&pinctrl 33 1>;
 			linux,code = <KEY_WPS_BUTTON>;
 		};
 		reset {
 			label = "reset";
-			gpios = <&gpio1 2 1>;
+			gpios = <&pinctrl 34 1>;
 			linux,code = <KEY_RESTART>;
 		};
 	};
@@ -41,48 +41,48 @@
 
 		wps_green {
 			label = "F at ST2704N:green:wps";
-			gpios = <&gpio0 2 1>;
+			gpios = <&pinctrl 2 1>;
 		};
 		lan1_green {
 			label = "F at ST2704N:green:lan1";
-			gpios = <&gpio0 4 1>;
+			gpios = <&pinctrl 4 1>;
 		};
 		lan2_green {
 			label = "F at ST2704N:green:lan2";
-			gpios = <&gpio0 5 1>;
+			gpios = <&pinctrl 5 1>;
 		};
 		lan3_green {
 			label = "F at ST2704N:green:lan3";
-			gpios = <&gpio0 6 1>;
+			gpios = <&pinctrl 6 1>;
 		};
 		lan4_green {
 			label = "F at ST2704N:green:lan4";
-			gpios = <&gpio0 7 1>;
+			gpios = <&pinctrl 7 1>;
 		};
 		inet_green {
 			label = "F at ST2704N:green:inet";
-			gpios = <&gpio0 8 1>;
+			gpios = <&pinctrl 8 1>;
 		};
 		inet_red {
 			label = "F at ST2704N:red:inet";
-			gpios = <&gpio0 9 1>;
+			gpios = <&pinctrl 9 1>;
 		};
 		dsl_green {
 			label = "F at ST2704N:green:dsl";
-			gpios = <&gpio0 10 1>;
+			gpios = <&pinctrl 10 1>;
 		};
 		power_red {
 			label = "F at ST2704N:red:power";
-			gpios = <&gpio0 11 1>;
+			gpios = <&pinctrl 11 1>;
 		};
 		power_green {
 			label = "F at ST2704N:green:power";
-			gpios = <&gpio1 15 1>;
+			gpios = <&pinctrl 47 1>;
 			default-state = "on";
 		};
 		usb_green {
 			label = "F at ST2704N:green:usb";
-			gpios = <&gpio1 17 1>;
+			gpios = <&pinctrl 49 1>;
 		};
 	};
 };
diff --git a/target/linux/brcm63xx/dts/fast2704v2.dts b/target/linux/brcm63xx/dts/fast2704v2.dts
index 617b1ed..bbd23da 100644
--- a/target/linux/brcm63xx/dts/fast2704v2.dts
+++ b/target/linux/brcm63xx/dts/fast2704v2.dts
@@ -21,17 +21,17 @@
 
 		rfkill {
 			label = "rfkill";
-			gpios = <&gpio0 15 1>;
+			gpios = <&pinctrl 15 1>;
 			linux,code = <KEY_WLAN>;
 		};
 		reset {
 			label = "reset";
-			gpios = <&gpio0 23 1>;
+			gpios = <&pinctrl 23 1>;
 			linux,code = <KEY_RESTART>;
 		};
 		wps {
 			label = "wps";
-			gpios = <&gpio0 24 1>;
+			gpios = <&pinctrl 24 1>;
 			linux,code = <KEY_WPS_BUTTON>;
 		};
 	};
@@ -41,32 +41,32 @@
 
 		usb_green {
 			label = "F at ST2704V2:green:usb";
-			gpios = <&gpio0 1 1>;
+			gpios = <&pinctrl 1 1>;
 		};
 		inet_red {
 			label = "F at ST2704V2:red:inet";
-			gpios = <&gpio0 2 1>;
+			gpios = <&pinctrl 2 1>;
 		};
 		dsl_green {
 			label = "F at ST2704V2:green:dsl";
-			gpios = <&gpio0 3 1>;
+			gpios = <&pinctrl 3 1>;
 		};
 		power_green {
 			label = "F at ST2704V2:green:power";
-			gpios = <&gpio0 4 1>;
+			gpios = <&pinctrl 4 1>;
 			default-state = "on";
 		};
 		power_red {
 			label = "F at ST2704V2:red:power";
-			gpios = <&gpio0 5 1>;
+			gpios = <&pinctrl 5 1>;
 		};
 		wps_green {
 			label = "F at ST2704V2:green:wps";
-			gpios = <&gpio0 10 1>;
+			gpios = <&pinctrl 10 1>;
 		};
 		inet_green {
 			label = "F at ST2704V2:green:inet";
-			gpios = <&gpio0 11 1>;
+			gpios = <&pinctrl 11 1>;
 		};
 	};
 };
diff --git a/target/linux/brcm63xx/dts/gw6000.dts b/target/linux/brcm63xx/dts/gw6000.dts
index 14c6330..5645ae0 100644
--- a/target/linux/brcm63xx/dts/gw6000.dts
+++ b/target/linux/brcm63xx/dts/gw6000.dts
@@ -21,7 +21,7 @@
 
 		reset {
 			label = "reset";
-			gpios = <&gpio1 4 1>;
+			gpios = <&pinctrl 36 1>;
 			linux,code = <KEY_RESTART>;
 		};
 	};
@@ -48,3 +48,8 @@
 		reg = <0x3f0000 0x010000>;
 	};
 };
+
+&pinctrl {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pci &pinctrl_ext_mii>;
+};
diff --git a/target/linux/brcm63xx/dts/gw6200.dts b/target/linux/brcm63xx/dts/gw6200.dts
index c02975e..3e0037a 100644
--- a/target/linux/brcm63xx/dts/gw6200.dts
+++ b/target/linux/brcm63xx/dts/gw6200.dts
@@ -21,7 +21,7 @@
 
 		reset {
 			label = "reset";
-			gpios = <&gpio1 4 1>;
+			gpios = <&pinctrl 36 1>;
 			linux,code = <KEY_RESTART>;
 		};
 	};
@@ -31,19 +31,19 @@
 
 		line1_green {
 			label = "GW6200:green:line1";
-			gpios = <&gpio0 4 1>;
+			gpios = <&pinctrl 4 1>;
 		};
 		line2_green {
 			label = "GW6200:green:line2";
-			gpios = <&gpio0 5 1>;
+			gpios = <&pinctrl 5 1>;
 		};
 		line3_green {
 			label = "GW6200:green:line3";
-			gpios = <&gpio0 6 1>;
+			gpios = <&pinctrl 6 1>;
 		};
 		tel_green {
 			label = "GW6200:green:tel";
-			gpios = <&gpio0 7 1>;
+			gpios = <&pinctrl 7 1>;
 		};
 	};
 };
@@ -69,3 +69,8 @@
 		reg = <0x7f0000 0x010000>;
 	};
 };
+
+&pinctrl {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pci &pinctrl_ext_mii &pinctrl_mii_pccard>;
+};
diff --git a/target/linux/brcm63xx/dts/hg520v.dts b/target/linux/brcm63xx/dts/hg520v.dts
index a86311f..f0eefc0 100644
--- a/target/linux/brcm63xx/dts/hg520v.dts
+++ b/target/linux/brcm63xx/dts/hg520v.dts
@@ -21,7 +21,7 @@
 
 		reset {
 			label = "reset";
-			gpios = <&gpio1 5 1>;
+			gpios = <&pinctrl 37 1>;
 			linux,code = <KEY_RESTART>;
 		};
 	};
@@ -31,7 +31,7 @@
 
 		inet_green {
 			label = "HW520:green:net";
-			gpios = <&gpio1 0 1>;
+			gpios = <&pinctrl 32 1>;
 		};
 	};
 };
diff --git a/target/linux/brcm63xx/dts/hg553.dts b/target/linux/brcm63xx/dts/hg553.dts
index cc6b331..a00821f 100644
--- a/target/linux/brcm63xx/dts/hg553.dts
+++ b/target/linux/brcm63xx/dts/hg553.dts
@@ -21,13 +21,13 @@
 
 		rfkill {
 			label = "rfkill";
-			gpios = <&gpio0 9 1>;
+			gpios = <&pinctrl 9 1>;
 			linux,code = <KEY_RFKILL>;
 		};
 
 		reset {
 			label = "reset";
-			gpios = <&gpio1 5 1>;
+			gpios = <&pinctrl 37 1>;
 			linux,code = <KEY_RESTART>;
 		};
 	};
@@ -37,40 +37,40 @@
 
 		power_green {
 			label = "HW553:blue:power";
-			gpios = <&gpio0 4 1>;
+			gpios = <&pinctrl 4 1>;
 			default-state = "on";
 		};
 		power_red {
 			label = "HW553:red:power";
-			gpios = <&gpio0 5 1>;
+			gpios = <&pinctrl 5 1>;
 		};
 		hspa_red {
 			label = "HW553:red:hspa";
-			gpios = <&gpio0 12 1>;
+			gpios = <&pinctrl 12 1>;
 		};
 		hspa_blue {
 			label = "HW553:blue:hspa";
-			gpios = <&gpio0 13 1>;
+			gpios = <&pinctrl 13 1>;
 		};
 		lan_red {
 			label = "HW553:red:lan";
-			gpios = <&gpio0 22 1>;
+			gpios = <&pinctrl 22 1>;
 		};
 		lan_blue {
 			label = "HW553:blue:lan";
-			gpios = <&gpio0 23 1>;
+			gpios = <&pinctrl 23 1>;
 		};
 		wifi_red {
 			label = "HW553:red:wifi";
-			gpios = <&gpio0 25 1>;
+			gpios = <&pinctrl 25 1>;
 		};
 		dsl_red {
 			label = "HW553:red:adsl";
-			gpios = <&gpio1 2 1>;
+			gpios = <&pinctrl 34 1>;
 		};
 		dsl_blue {
 			label = "HW553:blue:adsl";
-			gpios = <&gpio1 3 1>;
+			gpios = <&pinctrl 35 1>;
 		};
 	};
 };
diff --git a/target/linux/brcm63xx/dts/hg556a-a.dts b/target/linux/brcm63xx/dts/hg556a-a.dts
index b9f5842..de17500 100644
--- a/target/linux/brcm63xx/dts/hg556a-a.dts
+++ b/target/linux/brcm63xx/dts/hg556a-a.dts
@@ -21,22 +21,22 @@
 
 		help {
 			label = "help";
-			gpios = <&gpio0 8 1>;
+			gpios = <&pinctrl 8 1>;
 			linux,code = <KEY_HELP>;
 		};
 		wlan {
 			label = "wlan";
-			gpios = <&gpio0 9 1>;
+			gpios = <&pinctrl 9 1>;
 			linux,code = <KEY_WLAN>;
 		};
 		restart {
 			label = "restart";
-			gpios = <&gpio0 10 1>;
+			gpios = <&pinctrl 10 1>;
 			linux,code = <KEY_RESTART>;
 		};
 		reset {
 			label = "reset";
-			gpios = <&gpio0 11 1>;
+			gpios = <&pinctrl 11 1>;
 			linux,code = <KEY_CONFIG>;
 		};
 	};
@@ -46,57 +46,57 @@
 
 		message_red {
 			label = "HW556:red:message";
-			gpios = <&gpio0 0 1>;
+			gpios = <&pinctrl 0 1>;
 		};
 		hspa_red {
 			label = "HW556:red:hspa";
-			gpios = <&gpio0 1 1>;
+			gpios = <&pinctrl 1 1>;
 		};
 		dsl_red {
 			label = "HW556:red:dsl";
-			gpios = <&gpio0 2 1>;
+			gpios = <&pinctrl 2 1>;
 		};
 		power_red {
 			label = "HW556:red:power";
-			gpios = <&gpio0 3 1>;
+			gpios = <&pinctrl 3 1>;
 			default-state = "on";
 		};
 		all_red {
 			label = "HW556:red:all";
-			gpios = <&gpio0 6 1>;
+			gpios = <&pinctrl 6 1>;
 			default-state = "on";
 		};
 		lan1_green {
 			label = "HW556:green:lan1";
-			gpios = <&gpio0 12 1>;
+			gpios = <&pinctrl 12 1>;
 		};
 		lan1_red {
 			label = "HW556:red:lan1";
-			gpios = <&gpio0 13 1>;
+			gpios = <&pinctrl 13 1>;
 		};
 		lan2_green {
 			label = "HW556:green:lan2";
-			gpios = <&gpio0 15 1>;
+			gpios = <&pinctrl 15 1>;
 		};
 		lan2_red {
 			label = "HW556:red:lan2";
-			gpios = <&gpio0 22 1>;
+			gpios = <&pinctrl 22 1>;
 		};
 		lan3_green {
 			label = "HW556:green:lan3";
-			gpios = <&gpio0 23 1>;
+			gpios = <&pinctrl 23 1>;
 		};
 		lan3_red {
 			label = "HW556:red:lan3";
-			gpios = <&gpio0 26 1>;
+			gpios = <&pinctrl 26 1>;
 		};
 		lan4_green {
 			label = "HW556:green:lan4";
-			gpios = <&gpio0 27 1>;
+			gpios = <&pinctrl 27 1>;
 		};
 		lan4_red {
 			label = "HW556:red:lan4";
-			gpios = <&gpio0 28 1>;
+			gpios = <&pinctrl 28 1>;
 		};
 	};
 };
diff --git a/target/linux/brcm63xx/dts/hg556a-b.dts b/target/linux/brcm63xx/dts/hg556a-b.dts
index 40f79cd..782beda 100644
--- a/target/linux/brcm63xx/dts/hg556a-b.dts
+++ b/target/linux/brcm63xx/dts/hg556a-b.dts
@@ -21,22 +21,22 @@
 
 		help {
 			label = "help";
-			gpios = <&gpio0 8 1>;
+			gpios = <&pinctrl 8 1>;
 			linux,code = <KEY_HELP>;
 		};
 		wlan {
 			label = "wlan";
-			gpios = <&gpio0 9 1>;
+			gpios = <&pinctrl 9 1>;
 			linux,code = <KEY_WLAN>;
 		};
 		restart {
 			label = "restart";
-			gpios = <&gpio0 10 1>;
+			gpios = <&pinctrl 10 1>;
 			linux,code = <KEY_RESTART>;
 		};
 		reset {
 			label = "reset";
-			gpios = <&gpio0 11 1>;
+			gpios = <&pinctrl 11 1>;
 			linux,code = <KEY_CONFIG>;
 		};
 	};
@@ -46,57 +46,57 @@
 
 		message_red {
 			label = "HW556:red:message";
-			gpios = <&gpio0 0 1>;
+			gpios = <&pinctrl 0 1>;
 		};
 		hspa_red {
 			label = "HW556:red:hspa";
-			gpios = <&gpio0 1 1>;
+			gpios = <&pinctrl 1 1>;
 		};
 		dsl_red {
 			label = "HW556:red:dsl";
-			gpios = <&gpio0 2 1>;
+			gpios = <&pinctrl 2 1>;
 		};
 		power_red {
 			label = "HW556:red:power";
-			gpios = <&gpio0 3 1>;
+			gpios = <&pinctrl 3 1>;
 			default-state = "on";
 		};
 		all_red {
 			label = "HW556:red:all";
-			gpios = <&gpio0 6 1>;
+			gpios = <&pinctrl 6 1>;
 			default-state = "on";
 		};
 		lan1_green {
 			label = "HW556:green:lan1";
-			gpios = <&gpio0 12 1>;
+			gpios = <&pinctrl 12 1>;
 		};
 		lan1_red {
 			label = "HW556:red:lan1";
-			gpios = <&gpio0 13 1>;
+			gpios = <&pinctrl 13 1>;
 		};
 		lan2_green {
 			label = "HW556:green:lan2";
-			gpios = <&gpio0 15 1>;
+			gpios = <&pinctrl 15 1>;
 		};
 		lan2_red {
 			label = "HW556:red:lan2";
-			gpios = <&gpio0 22 1>;
+			gpios = <&pinctrl 22 1>;
 		};
 		lan3_green {
 			label = "HW556:green:lan3";
-			gpios = <&gpio0 23 1>;
+			gpios = <&pinctrl 23 1>;
 		};
 		lan3_red {
 			label = "HW556:red:lan3";
-			gpios = <&gpio0 26 1>;
+			gpios = <&pinctrl 26 1>;
 		};
 		lan4_green {
 			label = "HW556:green:lan4";
-			gpios = <&gpio0 27 1>;
+			gpios = <&pinctrl 27 1>;
 		};
 		lan4_red {
 			label = "HW556:red:lan4";
-			gpios = <&gpio0 28 1>;
+			gpios = <&pinctrl 28 1>;
 		};
 	};
 };
diff --git a/target/linux/brcm63xx/dts/hg556a-c.dts b/target/linux/brcm63xx/dts/hg556a-c.dts
index ada2a8c..36f298b 100644
--- a/target/linux/brcm63xx/dts/hg556a-c.dts
+++ b/target/linux/brcm63xx/dts/hg556a-c.dts
@@ -21,22 +21,22 @@
 
 		help {
 			label = "help";
-			gpios = <&gpio1 4 1>;
+			gpios = <&pinctrl 36 1>;
 			linux,code = <KEY_HELP>;
 		};
 		wlan {
 			label = "wlan";
-			gpios = <&gpio0 9 1>;
+			gpios = <&pinctrl 9 1>;
 			linux,code = <KEY_WLAN>;
 		};
 		restart {
 			label = "restart";
-			gpios = <&gpio0 10 1>;
+			gpios = <&pinctrl 10 1>;
 			linux,code = <KEY_RESTART>;
 		};
 		reset {
 			label = "reset";
-			gpios = <&gpio0 11 1>;
+			gpios = <&pinctrl 11 1>;
 			linux,code = <KEY_CONFIG>;
 		};
 	};
@@ -46,52 +46,52 @@
 
 		lan1_green {
 			label = "HW556:green:lan1";
-			gpios = <&gpio0 0 1>;
+			gpios = <&pinctrl 0 1>;
 		};
 		lan2_green {
 			label = "HW556:green:lan2";
-			gpios = <&gpio0 1 1>;
+			gpios = <&pinctrl 1 1>;
 		};
 		dsl_red {
 			label = "HW556:red:dsl";
-			gpios = <&gpio0 2 1>;
+			gpios = <&pinctrl 2 1>;
 		};
 		power_red {
 			label = "HW556:red:power";
-			gpios = <&gpio0 3 1>;
+			gpios = <&pinctrl 3 1>;
 			default-state = "on";
 		};
 		message_red {
 			label = "HW556:red:message";
-			gpios = <&gpio0 12 1>;
+			gpios = <&pinctrl 12 1>;
 		};
 		lan1_red {
 			label = "HW556:red:lan1";
-			gpios = <&gpio0 13 1>;
+			gpios = <&pinctrl 13 1>;
 		};
 		hspa_red {
 			label = "HW556:red:hspa";
-			gpios = <&gpio0 15 1>;
+			gpios = <&pinctrl 15 1>;
 		};
 		lan2_red {
 			label = "HW556:red:lan2";
-			gpios = <&gpio0 22 1>;
+			gpios = <&pinctrl 22 1>;
 		};
 		lan3_green {
 			label = "HW556:green:lan3";
-			gpios = <&gpio0 23 1>;
+			gpios = <&pinctrl 23 1>;
 		};
 		lan3_red {
 			label = "HW556:red:lan3";
-			gpios = <&gpio0 26 1>;
+			gpios = <&pinctrl 26 1>;
 		};
 		lan4_green {
 			label = "HW556:green:lan4";
-			gpios = <&gpio0 27 1>;
+			gpios = <&pinctrl 27 1>;
 		};
 		lan4_red {
 			label = "HW556:red:lan4";
-			gpios = <&gpio0 28 1>;
+			gpios = <&pinctrl 28 1>;
 		};
 	};
 };
diff --git a/target/linux/brcm63xx/dts/hg622.dts b/target/linux/brcm63xx/dts/hg622.dts
index 6dee418..f96af2b 100644
--- a/target/linux/brcm63xx/dts/hg622.dts
+++ b/target/linux/brcm63xx/dts/hg622.dts
@@ -22,7 +22,7 @@
 
 		reset {
 			label = "reset";
-			gpios = <&gpio1 2 1>;
+			gpios = <&pinctrl 34 1>;
 			linux,code = <KEY_RESTART>;
 		};
 	};
@@ -32,19 +32,19 @@
 
 		dsl_green {
 			label = "HG622:green:dsl";
-			gpios = <&gpio0 2 1>;
+			gpios = <&pinctrl 2 1>;
 		};
 		inet_green {
 			label = "HG622:green:inet";
-			gpios = <&gpio0 5 1>;
+			gpios = <&pinctrl 5 1>;
 		};
 		usb_green {
 			label = "HG622:green:usb";
-			gpios = <&gpio0 11 1>;
+			gpios = <&pinctrl 11 1>;
 		};
 		power_green {
 			label = "HG622:green:power";
-			gpios = <&gpio0 22 1>;
+			gpios = <&pinctrl 22 1>;
 			default-state = "on";
 		};
 	};
@@ -77,3 +77,10 @@
 		reg = <0xfe0000 0x020000>;
 	};
 };
+
+&pinctrl {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pci_gnt0 &pinctrl_pci_req0
+		     &pinctrl_pci_intb &pinctrl_pci_gnt1
+		     &pinctrl_pci_req1>;
+};
diff --git a/target/linux/brcm63xx/dts/hg655b.dts b/target/linux/brcm63xx/dts/hg655b.dts
index 58ef715..63e1309 100644
--- a/target/linux/brcm63xx/dts/hg655b.dts
+++ b/target/linux/brcm63xx/dts/hg655b.dts
@@ -21,17 +21,17 @@
 
 		wps {
 			label = "wps";
-			gpios = <&gpio0 12 1>;
+			gpios = <&pinctrl 12 1>;
 			linux,code = <KEY_WPS_BUTTON>;
 		};
 		wlan {
 			label = "wlan";
-			gpios = <&gpio0 23 1>;
+			gpios = <&pinctrl 23 1>;
 			linux,code = <KEY_WLAN>;
 		};
 		reset {
 			label = "reset";
-			gpios = <&gpio1 2 1>;
+			gpios = <&pinctrl 34 1>;
 			linux,code = <KEY_RESTART>;
 		};
 	};
@@ -41,28 +41,29 @@
 
 		dsl_green {
 			label = "HW65x:green:dsl";
-			gpios = <&gpio0 2 1>;
+			gpios = <&pinctrl 2 1>;
 		};
 		internet_green {
 			label = "HW65x:green:internet";
-			gpios = <&gpio0 5 1>;
+			gpios = <&pinctrl 5 1>;
 		};
+
 		usb_green {
 			label = "HW65x:green:usb";
-			gpios = <&gpio0 14 1>;
+			gpios = <&pinctrl 14 1>;
 		};
 		power_green {
 			label = "HW65x:green:power";
-			gpios = <&gpio0 22 1>;
+			gpios = <&pinctrl 22 1>;
 			default-state = "on";
 		};
 		voip_green {
 			label = "HW65x:green:voip";
-			gpios = <&gpio0 25 1>;
+			gpios = <&pinctrl 25 1>;
 		};
 		wps_green {
 			label = "HW65x:green:wps";
-			gpios = <&gpio0 27 1>;
+			gpios = <&pinctrl 27 1>;
 		};
 	};
 };
@@ -98,3 +99,9 @@
 		reg = <0x7e0000 0x020000>;
 	};
 };
+
+&pinctrl {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pci &pinctrl_ephy0_led &pinctrl_ephy1_led
+		     &pinctrl_ephy2_led &pinctrl_ephy3_led>;
+};
diff --git a/target/linux/brcm63xx/dts/homehub2a.dts b/target/linux/brcm63xx/dts/homehub2a.dts
index b86a48f..0d51c87 100644
--- a/target/linux/brcm63xx/dts/homehub2a.dts
+++ b/target/linux/brcm63xx/dts/homehub2a.dts
@@ -17,9 +17,9 @@
 		#size-cells = <0>;
 		compatible = "spi-gpio";
 
-		gpio-mosi = <&gpio0 7 0>;
-		gpio-sck = <&gpio0 6 0>;
-		cs-gpios = <&gpio0 5 0>;
+		gpio-mosi = <&pinctrl 7 0>;
+		gpio-sck = <&pinctrl 6 0>;
+		cs-gpios = <&pinctrl 5 0>;
 		num-chipselects = <1>;
 
 		hc595: gpio-spi-controller at 0 {
@@ -42,17 +42,17 @@
 
 		phone {
 			label = "phone";
-			gpios = <&gpio0 1 1>;
+			gpios = <&pinctrl 1 1>;
 			linux,code = <KEY_PHONE>;
 		};
 		reset {
 			label = "reset";
-			gpios = <&gpio0 9 1>;
+			gpios = <&pinctrl 9 1>;
 			linux,code = <KEY_RESTART>;
 		};
 		wps {
 			label = "wps";
-			gpios = <&gpio0 11 1>;
+			gpios = <&pinctrl 11 1>;
 			linux,code = <KEY_WPS_BUTTON>;
 		};
 	};
diff --git a/target/linux/brcm63xx/dts/livebox-blue-5g.dts b/target/linux/brcm63xx/dts/livebox-blue-5g.dts
index c0ef0d4..8a06073 100644
--- a/target/linux/brcm63xx/dts/livebox-blue-5g.dts
+++ b/target/linux/brcm63xx/dts/livebox-blue-5g.dts
@@ -22,13 +22,13 @@
 
 		button1 {
 			label = "1";
-			gpios = <&gpio1 4 1>;
+			gpios = <&pinctrl 36 1>;
 			linux,code = <KEY_RESTART>;
 		};
 
 		button2 {
 			label = "2";
-			gpios = <&gpio0 7 1>;
+			gpios = <&pinctrl 7 1>;
 			linux,code = <BTN_2>;
 		};
 	};
@@ -38,28 +38,28 @@
 
 		red_adsl_fail {
 			label = "Livebox1:red:adsl-fail-power";
-			gpios = <&gpio0 0 0>;
+			gpios = <&pinctrl 0 0>;
 			default-state = "on";
 		};
 
 		red_adsl {
 			label = "Livebox1:red:adsl";
-			gpios = <&gpio0 1 0>;
+			gpios = <&pinctrl 1 0>;
 		};
 
 		red_traffic {
 			label = "Livebox1:red:traffic";
-			gpios = <&gpio0 2 0>;
+			gpios = <&pinctrl 2 0>;
 		};
 
 		red_phone {
 			label = "Livebox1:red:phone";
-			gpios = <&gpio0 3 0>;
+			gpios = <&pinctrl 3 0>;
 		};
 
 		red_wifi {
 			label = "Livebox1:red:wifi";
-			gpios = <&gpio0 4 0>;
+			gpios = <&pinctrl 4 0>;
 		};
 	};
 };
@@ -70,3 +70,8 @@
 
 	linux,part-probe = "RedBoot";
 };
+
+&pinctrl {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pci &pinctrl_ext_mii &pinctrl_mii_pccard>;
+};
diff --git a/target/linux/brcm63xx/dts/magic.dts b/target/linux/brcm63xx/dts/magic.dts
index be10524..9053c26 100644
--- a/target/linux/brcm63xx/dts/magic.dts
+++ b/target/linux/brcm63xx/dts/magic.dts
@@ -17,38 +17,38 @@
 
 		power {
 			label = "MAGIC:green:power";
-			gpios = <&gpio0 0 1>;
+			gpios = <&pinctrl 0 1>;
 			default-state = "on";
 		};
 
 		stop {
 			label = "MAGIC:green:stop";
-			gpios = <&gpio0 1 1>;
+			gpios = <&pinctrl 1 1>;
 		};
 
 		hpna {
 			label = "MAGIC:green:hpna";
-			gpios = <&gpio0 4 1>;
+			gpios = <&pinctrl 4 1>;
 		};
 
 		status {
 			label = "MAGIC:green:adsl";
-			gpios = <&gpio0 5 1>;
+			gpios = <&pinctrl 5 1>;
 		};
 
 		voip {
 			label = "MAGIC:green:voip";
-			gpios = <&gpio0 22 1>;
+			gpios = <&pinctrl 22 1>;
 		};
 
 		wifi {
 			label = "MAGIC:green:wifi";
-			gpios = <&gpio0 28 0>;
+			gpios = <&pinctrl 28 0>;
 		};
 
 		usb {
 			label = "MAGIC:green:usb";
-			gpios = <&gpio1 3 1>;
+			gpios = <&pinctrl 35 1>;
 		};
 	};
 };
@@ -74,3 +74,8 @@
 		reg = <0x3f0000 0x010000>;
 	};
 };
+
+&pinctrl {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pci &pinctrl_ext_mii &pinctrl_mii_pccard>;
+};
diff --git a/target/linux/brcm63xx/dts/nb4-fxc-r1.dts b/target/linux/brcm63xx/dts/nb4-fxc-r1.dts
index d94bf0e..4960afb 100644
--- a/target/linux/brcm63xx/dts/nb4-fxc-r1.dts
+++ b/target/linux/brcm63xx/dts/nb4-fxc-r1.dts
@@ -17,8 +17,8 @@
 		#size-cells = <0>;
 		compatible = "spi-gpio";
 
-		gpio-mosi = <&gpio0 7 0>;
-		gpio-sck = <&gpio0 6 0>;
+		gpio-mosi = <&pinctrl 7 0>;
+		gpio-sck = <&pinctrl 6 0>;
 		num-chipselects = <0>;
 
 		hc595: gpio-spi-controller at 0 {
@@ -41,22 +41,22 @@
 
 		service {
 			label = "service";
-			gpios = <&gpio0 27 1>;
+			gpios = <&pinctrl 27 1>;
 			linux,code = <BTN_0>;
 		};
 		clip {
 			label = "clip";
-			gpios = <&gpio0 31 1>;
+			gpios = <&pinctrl 31 1>;
 			linux,code = <BTN_1>;
 		};
 		reset {
 			label = "reset";
-			gpios = <&gpio1 2 1>;
+			gpios = <&pinctrl 34 1>;
 			linux,code = <KEY_RESTART>;
 		};
 		wps {
 			label = "wps";
-			gpios = <&gpio1 5 1>;
+			gpios = <&pinctrl 37 1>;
 			linux,code = <KEY_WPS_BUTTON>;
 		};
 	};
@@ -66,23 +66,23 @@
 
 		traffic_white {
 			label = "NB4-FXC-r1:white:traffic";
-			gpios = <&gpio0 2 0>;
+			gpios = <&pinctrl 2 0>;
 		};
 		service_blue {
 			label = "NB4-FXC-r1:blue:service";
-			gpios = <&gpio0 4 0>;
+			gpios = <&pinctrl 4 0>;
 		};
 		wifi_white {
 			label = "NB4-FXC-r1:white:wifi";
-			gpios = <&gpio0 15 0>;
+			gpios = <&pinctrl 15 0>;
 		};
 		service_red {
 			label = "NB4-FXC-r1:red:service";
-			gpios = <&gpio0 29 0>;
+			gpios = <&pinctrl 29 0>;
 		};
 		service_green {
 			label = "NB4-FXC-r1:green:service";
-			gpios = <&gpio0 30 0>;
+			gpios = <&pinctrl 30 0>;
 		};
 		alarm_white {
 			label = "NB4-FXC-r1:white:alarm";
diff --git a/target/linux/brcm63xx/dts/nb4-ser-r0.dts b/target/linux/brcm63xx/dts/nb4-ser-r0.dts
index 75cb214..128a16a 100644
--- a/target/linux/brcm63xx/dts/nb4-ser-r0.dts
+++ b/target/linux/brcm63xx/dts/nb4-ser-r0.dts
@@ -17,8 +17,8 @@
 		#size-cells = <0>;
 		compatible = "spi-gpio";
 
-		gpio-mosi = <&gpio0 7 0>;
-		gpio-sck = <&gpio0 6 0>;
+		gpio-mosi = <&pinctrl 7 0>;
+		gpio-sck = <&pinctrl 6 0>;
 		num-chipselects = <0>;
 
 		hc595: gpio-spi-controller at 0 {
@@ -41,22 +41,22 @@
 
 		service {
 			label = "service";
-			gpios = <&gpio0 27 1>;
+			gpios = <&pinctrl 27 1>;
 			linux,code = <BTN_0>;
 		};
 		clip {
 			label = "clip";
-			gpios = <&gpio0 31 1>;
+			gpios = <&pinctrl 31 1>;
 			linux,code = <BTN_1>;
 		};
 		reset {
 			label = "reset";
-			gpios = <&gpio1 2 1>;
+			gpios = <&pinctrl 34 1>;
 			linux,code = <KEY_RESTART>;
 		};
 		wps {
 			label = "wps";
-			gpios = <&gpio1 5 1>;
+			gpios = <&pinctrl 37 1>;
 			linux,code = <KEY_WPS_BUTTON>;
 		};
 	};
@@ -66,23 +66,23 @@
 
 		traffic_white {
 			label = "NB4-SER-r0:white:traffic";
-			gpios = <&gpio0 2 1>;
+			gpios = <&pinctrl 2 1>;
 		};
 		service_blue {
 			label = "NB4-SER-r0:blue:service";
-			gpios = <&gpio0 4 1>;
+			gpios = <&pinctrl 4 1>;
 		};
 		wifi_white {
 			label = "NB4-SER-r0:white:wifi";
-			gpios = <&gpio0 15 1>;
+			gpios = <&pinctrl 15 1>;
 		};
 		service_red {
 			label = "NB4-SER-r0:red:service";
-			gpios = <&gpio0 29 1>;
+			gpios = <&pinctrl 29 1>;
 		};
 		service_green {
 			label = "NB4-SER-r0:green:service";
-			gpios = <&gpio0 30 1>;
+			gpios = <&pinctrl 30 1>;
 		};
 		alarm_white {
 			label = "NB4-SER-r0:white:alarm";
diff --git a/target/linux/brcm63xx/dts/nb6-ser-r0.dts b/target/linux/brcm63xx/dts/nb6-ser-r0.dts
index c0182f3..8fb434f 100644
--- a/target/linux/brcm63xx/dts/nb6-ser-r0.dts
+++ b/target/linux/brcm63xx/dts/nb6-ser-r0.dts
@@ -21,30 +21,30 @@
 
 		service {
 			label = "service";
-			gpios = <&gpio0 10 1>;
+			gpios = <&pinctrl 10 1>;
 			linux,code = <BTN_0>;
 		};
 		wlan {
 			label = "wlan";
-			gpios = <&gpio0 12 1>;
+			gpios = <&pinctrl 12 1>;
 			linux,code = <KEY_WLAN>;
 		};
 		reset {
 			label = "reset";
-			gpios = <&gpio0 24 1>;
+			gpios = <&pinctrl 24 1>;
 			linux,code = <KEY_RESTART>;
 		};
 		wps {
 			label = "wps";
-			gpios = <&gpio0 25 1>;
+			gpios = <&pinctrl 25 1>;
 			linux,code = <KEY_WPS_BUTTON>;
 		};
 	};
 
 	switch {
 		compatible = "realtek,rtl8367";
-		gpio-sda = <&gpio0 18 0>;
-		gpio-sck = <&gpio0 20 0>;
+		gpio-sda = <&pinctrl 18 0>;
+		gpio-sck = <&pinctrl 20 0>;
 
 		realtek,extif0 = <1 5 1 1 1 1 1 1 2>;
 	};
diff --git a/target/linux/brcm63xx/dts/p870hw-51a-v2.dts b/target/linux/brcm63xx/dts/p870hw-51a-v2.dts
index 962d474..eea3021 100644
--- a/target/linux/brcm63xx/dts/p870hw-51a-v2.dts
+++ b/target/linux/brcm63xx/dts/p870hw-51a-v2.dts
@@ -21,12 +21,12 @@
 
 		reset {
 			label = "reset";
-			gpios = <&gpio1 2 1>;
+			gpios = <&pinctrl 35 1>;
 			linux,code = <KEY_RESTART>;
 		};
 		wps {
 			label = "wps";
-			gpios = <&gpio1 3 1>;
+			gpios = <&pinctrl 36 1>;
 			linux,code = <KEY_WPS_BUTTON>;
 		};
 	};
@@ -36,24 +36,24 @@
 
 		power_green {
 			label = "P870HW-51a:green:power";
-			gpios = <&gpio0 0 0>;
+			gpios = <&pinctrl 0 0>;
 			default-state = "on";
 		};
 		dsl_green {
 			label = "P870HW-51a:green:dsl";
-			gpios = <&gpio0 2 1>;
+			gpios = <&pinctrl 2 1>;
 		};
 		inet_green {
 			label = "P870HW-51a:green:inet";
-			gpios = <&gpio0 22 1>;
+			gpios = <&pinctrl 22 1>;
 		};
 		wps_orange {
 			label = "P870HW-51a:orange:wps";
-			gpios = <&gpio0 24 1>;
+			gpios = <&pinctrl 24 1>;
 		};
 		inet_red {
 			label = "P870HW-51a:red:inet";
-			gpios = <&gpio1 1 1>;
+			gpios = <&pinctrl 33 1>;
 		};
 	};
 };
@@ -79,3 +79,8 @@
 		reg = <0x3f0000 0x010000>;
 	};
 };
+
+&pinctrl {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pci>;
+};
diff --git a/target/linux/brcm63xx/dts/r5010unv2.dts b/target/linux/brcm63xx/dts/r5010unv2.dts
index cce861b..0bd88b2 100644
--- a/target/linux/brcm63xx/dts/r5010unv2.dts
+++ b/target/linux/brcm63xx/dts/r5010unv2.dts
@@ -22,12 +22,12 @@
 
 		reset {
 			label = "reset";
-			gpios = <&gpio0 23 1>;
+			gpios = <&pinctrl 23 1>;
 			linux,code = <KEY_RESTART>;
 		};
 		wps {
 			label = "wps";
-			gpios = <&gpio0 24 1>;
+			gpios = <&pinctrl 24 1>;
 			linux,code = <KEY_WPS_BUTTON>;
 		};
 	};
@@ -37,32 +37,32 @@
 
 		inet_green {
 			label = "R5010UNv2:green:inet";
-			gpios = <&gpio0 1 1>;
+			gpios = <&pinctrl 1 1>;
 		};
 		inet_fail_red {
 			label = "R5010UNv2:red:inet-fail";
-			gpios = <&gpio0 2 1>;
+			gpios = <&pinctrl 2 1>;
 		};
 		dsl_red {
 			label = "R5010UNv2:green:dsl";
-			gpios = <&gpio0 3 1>;
+			gpios = <&pinctrl 3 1>;
 		};
 		power_green {
 			label = "R5010UNv2:green:power";
-			gpios = <&gpio0 4 1>;
+			gpios = <&pinctrl 4 1>;
 			default-state = "on";
 		};
 		power_fail_red {
 			label = "R5010UNv2:red:power-fail";
-			gpios = <&gpio0 5 1>;
+			gpios = <&pinctrl 5 1>;
 		};
 		wps_green {
 			label = "R5010UNv2:green:wps";
-			gpios = <&gpio0 10 1>;
+			gpios = <&pinctrl 10 1>;
 		};
 		usb_green {
 			label = "R5010UNv2:green:usb";
-			gpios = <&gpio0 11 1>;
+			gpios = <&pinctrl 11 1>;
 		};
 	};
 };
diff --git a/target/linux/brcm63xx/dts/rg100a.dts b/target/linux/brcm63xx/dts/rg100a.dts
index 770ceee..e96e310 100644
--- a/target/linux/brcm63xx/dts/rg100a.dts
+++ b/target/linux/brcm63xx/dts/rg100a.dts
@@ -17,20 +17,20 @@
 
 		stop_green {
 			label = "96358VW2:green:stop";
-			gpios = <&gpio0 4 1>;
+			gpios = <&pinctrl 4 1>;
 		};
 		power_green {
 			label = "96358VW2:green:power";
-			gpios = <&gpio0 5 1>;
+			gpios = <&pinctrl 5 1>;
 			default-state = "on";
 		};
 		adsl_green {
 			label = "96358VW2:green:adsl";
-			gpios = <&gpio0 22 1>;
+			gpios = <&pinctrl 22 1>;
 		};
 		ppp_fail_green {
 			label = "96358VW2:green:ppp-fail";
-			gpios = <&gpio0 23 0>;
+			gpios = <&pinctrl 23 0>;
 		};
 	};
 };
diff --git a/target/linux/brcm63xx/dts/rta1025w.dts b/target/linux/brcm63xx/dts/rta1025w.dts
index 4758ab3..16c3abf 100644
--- a/target/linux/brcm63xx/dts/rta1025w.dts
+++ b/target/linux/brcm63xx/dts/rta1025w.dts
@@ -34,3 +34,8 @@
 		reg = <0x3f0000 0x010000>;
 	};
 };
+
+&pinctrl {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pci &pinctrl_ext_mii>;
+};
diff --git a/target/linux/brcm63xx/dts/spw303v.dts b/target/linux/brcm63xx/dts/spw303v.dts
index 8128fbd..0040540 100644
--- a/target/linux/brcm63xx/dts/spw303v.dts
+++ b/target/linux/brcm63xx/dts/spw303v.dts
@@ -21,12 +21,12 @@
 
 		reset {
 			label = "reset";
-			gpios = <&gpio0 11 0>;
+			gpios = <&pinctrl 11 0>;
 			linux,code = <KEY_RESTART>;
 		};
 		ses {
 			label = "ses";
-			gpios = <&gpio1 5 1>;
+			gpios = <&pinctrl 37 1>;
 			linux,code = <KEY_WPS_BUTTON>;
 		};
 	};
@@ -36,28 +36,28 @@
 
 		ses_green {
 			label = "spw303v:green:ses";
-			gpios = <&gpio0 0 1>;
+			gpios = <&pinctrl 0 1>;
 		};
 		power_adsl_red {
 			label = "spw303v:red:power+adsl";
-			gpios = <&gpio0 2 1>;
+			gpios = <&pinctrl 2 1>;
 		};
 		ppp_green {
 			label = "spw303v:green:ppp";
-			gpios = <&gpio0 5 1>;
+			gpios = <&pinctrl 5 1>;
 		};
 		power_adsl_green {
 			label = "spw303v:green:power+adsl";
-			gpios = <&gpio0 22 1>;
+			gpios = <&pinctrl 22 1>;
 			default-state = "on";
 		};
 		voip_green {
 			label = "spw303v:green:voip";
-			gpios = <&gpio0 27 1>;
+			gpios = <&pinctrl 27 1>;
 		};
 		pots_green {
 			label = "spw303v:green:pots";
-			gpios = <&gpio0 31 1>;
+			gpios = <&pinctrl 31 1>;
 		};
 	};
 };
diff --git a/target/linux/brcm63xx/dts/spw500v.dts b/target/linux/brcm63xx/dts/spw500v.dts
index 4fe32d6..a9603b3 100644
--- a/target/linux/brcm63xx/dts/spw500v.dts
+++ b/target/linux/brcm63xx/dts/spw500v.dts
@@ -21,7 +21,7 @@
 
 		reset {
 			label = "reset";
-			gpios = <&gpio1 1 1>;
+			gpios = <&pinctrl 33 1>;
 			linux,code = <KEY_RESTART>;
 		};
 	};
@@ -31,24 +31,24 @@
 
 		power_green {
 			label = "SPW500V:green:power";
-			gpios = <&gpio0 0 1>;
+			gpios = <&pinctrl 0 1>;
 			default-state = "on";
 		};
 		power_red {
 			label = "SPW500V:red:power";
-			gpios = <&gpio0 1 1>;
+			gpios = <&pinctrl 1 1>;
 		};
 		ppp_green {
 			label = "SPW500V:green:ppp";
-			gpios = <&gpio0 3 1>;
+			gpios = <&pinctrl 3 1>;
 		};
 		pstn_green {
 			label = "SPW500V:green:pstn";
-			gpios = <&gpio0 28 1>;
+			gpios = <&pinctrl 28 1>;
 		};
 		voip_green {
 			label = "SPW500V:green:voip";
-			gpios = <&gpio1 0 1>;
+			gpios = <&pinctrl 32 1>;
 		};
 	};
 };
@@ -74,3 +74,8 @@
 		reg = <0x3f0000 0x010000>;
 	};
 };
+
+&pinctrl {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pci>;
+};
diff --git a/target/linux/brcm63xx/dts/td-w8900gb.dts b/target/linux/brcm63xx/dts/td-w8900gb.dts
index 6e13f3f..b52670b 100644
--- a/target/linux/brcm63xx/dts/td-w8900gb.dts
+++ b/target/linux/brcm63xx/dts/td-w8900gb.dts
@@ -21,7 +21,7 @@
 
 		reset {
 			label = "reset";
-			gpios = <&gpio1 1 1>;
+			gpios = <&pinctrl 33 1>;
 			linux,code = <KEY_RESTART>;
 		};
 	};
@@ -31,24 +31,24 @@
 
 		power_green {
 			label = "96348GW-11:green:power";
-			gpios = <&gpio0 0 1>;
+			gpios = <&pinctrl 0 1>;
 			default-state = "on";
 		};
 		stop_green {
 			label = "96348GW-11:green:stop";
-			gpios = <&gpio0 1 1>;
+			gpios = <&pinctrl 1 1>;
 		};
 		adsl_fail_green {
 			label = "96348GW-11:green:adsl-fail";
-			gpios = <&gpio0 2 1>;
+			gpios = <&pinctrl 2 1>;
 		};
 		ppp_green {
 			label = "96348GW-11:green:ppp";
-			gpios = <&gpio0 3 1>;
+			gpios = <&pinctrl 3 1>;
 		};
 		ppp_fail_green {
 			label = "96348GW-11:green:ppp-fail";
-			gpios = <&gpio0 4 1>;
+			gpios = <&pinctrl 4 1>;
 		};
 	};
 };
@@ -74,3 +74,8 @@
 		reg = <0x3f0000 0x010000>;
 	};
 };
+
+&pinctrl {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pci &pinctrl_ext_mii &pinctrl_mii_pccard>;
+};
diff --git a/target/linux/brcm63xx/dts/usr9108.dts b/target/linux/brcm63xx/dts/usr9108.dts
index 25415ab..81af20b 100644
--- a/target/linux/brcm63xx/dts/usr9108.dts
+++ b/target/linux/brcm63xx/dts/usr9108.dts
@@ -17,11 +17,11 @@
 
 		usb {
 			label = "96348GW-A::usb";
-			gpios = <&gpio0 0 1>;
+			gpios = <&pinctrl 0 1>;
 		};
 		dsl {
 			label = "96348GW-A::adsl";
-			gpios = <&gpio0 3 1>;
+			gpios = <&pinctrl 3 1>;
 		};
 	};
 };
@@ -47,3 +47,8 @@
 		reg = <0x3f0000 0x010000>;
 	};
 };
+
+&pinctrl {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pci &pinctrl_ext_mii>;
+};
diff --git a/target/linux/brcm63xx/dts/v2110.dts b/target/linux/brcm63xx/dts/v2110.dts
index 13230a0..23378a4 100644
--- a/target/linux/brcm63xx/dts/v2110.dts
+++ b/target/linux/brcm63xx/dts/v2110.dts
@@ -21,7 +21,7 @@
 
 		reset {
 			label = "reset";
-			gpios = <&gpio1 1 1>;
+			gpios = <&pinctrl 33 1>;
 			linux,code = <KEY_RESTART>;
 		};
 	};
@@ -31,23 +31,23 @@
 
 		power_green {
 			label = "V2110:green:power";
-			gpios = <&gpio0 0 1>;
+			gpios = <&pinctrl 0 1>;
 		};
 		power_red {
 			label = "V2110:red:power";
-			gpios = <&gpio0 1 1>;
+			gpios = <&pinctrl 1 1>;
 		};
 		adsl_green {
 			label = "V2110:green:adsl";
-			gpios = <&gpio0 2 1>;
+			gpios = <&pinctrl 2 1>;
 		};
 		ppp_green {
 			label = "V2110:green:ppp";
-			gpios = <&gpio0 3 1>;
+			gpios = <&pinctrl 3 1>;
 		};
 		wireless_green {
 			label = "V2110:green:wireless";
-			gpios = <&gpio0 6 1>;
+			gpios = <&pinctrl 6 1>;
 		};
 	};
 };
@@ -73,3 +73,8 @@
 		reg = <0x3f0000 0x010000>;
 	};
 };
+
+&pinctrl {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pci &pinctrl_ext_mii>;
+};
diff --git a/target/linux/brcm63xx/dts/v2500v-bb.dts b/target/linux/brcm63xx/dts/v2500v-bb.dts
index bc1a717..b6370ee 100644
--- a/target/linux/brcm63xx/dts/v2500v-bb.dts
+++ b/target/linux/brcm63xx/dts/v2500v-bb.dts
@@ -21,7 +21,7 @@
 
 		reset {
 			label = "reset";
-			gpios = <&gpio0 31 1>;
+			gpios = <&pinctrl 31 1>;
 			linux,code = <KEY_RESTART>;
 		};
 	};
@@ -31,23 +31,23 @@
 
 		power_green {
 			label = "V2500V_BB:green:power";
-			gpios = <&gpio0 0 1>;
+			gpios = <&pinctrl 0 1>;
 		};
 		power_red {
 			label = "V2500V_BB:red:power";
-			gpios = <&gpio0 1 1>;
+			gpios = <&pinctrl 1 1>;
 		};
 		adsl_green {
 			label = "V2500V_BB:green:adsl";
-			gpios = <&gpio0 2 1>;
+			gpios = <&pinctrl 2 1>;
 		};
 		ppp_green {
 			label = "V2500V_BB:green:ppp";
-			gpios = <&gpio0 3 1>;
+			gpios = <&pinctrl 3 1>;
 		};
 		wireless_green {
 			label = "V2500V_BB:green:wireless";
-			gpios = <&gpio0 6 1>;
+			gpios = <&pinctrl 6 1>;
 		};
 	};
 };
@@ -73,3 +73,8 @@
 		reg = <0x3f0000 0x010000>;
 	};
 };
+
+&pinctrl {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pci &pinctrl_ext_mii>;
+};
diff --git a/target/linux/brcm63xx/dts/vg50.dts b/target/linux/brcm63xx/dts/vg50.dts
index 0eb7eb6..2180802 100644
--- a/target/linux/brcm63xx/dts/vg50.dts
+++ b/target/linux/brcm63xx/dts/vg50.dts
@@ -21,13 +21,13 @@
 
 		reset {
 			label = "reset";
-			gpios = <&gpio1 0 0>;
+			gpios = <&pinctrl 32 0>;
 			linux,code = <KEY_RESTART>;
 		};
 
 		wps {
 			label = "wps";
-			gpios = <&gpio1 2 0>;
+			gpios = <&pinctrl 34 0>;
 			linux,code = <KEY_WPS_BUTTON>;
 		};
         };
diff --git a/target/linux/brcm63xx/dts/vh4032n.dts b/target/linux/brcm63xx/dts/vh4032n.dts
index 8b8abd9..1b646ce 100644
--- a/target/linux/brcm63xx/dts/vh4032n.dts
+++ b/target/linux/brcm63xx/dts/vh4032n.dts
@@ -21,12 +21,12 @@
 
 		reset {
 			label = "reset";
-			gpios = <&gpio1 2 1>;
+			gpios = <&pinctrl 34 1>;
 			linux,code = <KEY_RESTART>;
 		};
 		wps {
 			label = "wps";
-			gpios = <&gpio1 3 1>;
+			gpios = <&pinctrl 35 1>;
 			linux,code = <KEY_WPS_BUTTON>;
 		};
 	};
@@ -36,41 +36,41 @@
 
 		dsl_blue {
 			label = "VH4032N:blue:dsl";
-			gpios = <&gpio0 2 1>;
+			gpios = <&pinctrl 2 1>;
 		};
 		dsl_red {
 			label = "VH4032N:red:dsl";
-			gpios = <&gpio0 5 1>;
+			gpios = <&pinctrl 5 1>;
 		};
 		hspa_blue {
 			label = "VH4032N:blue:hspa";
-			gpios = <&gpio0 11 1>;
+			gpios = <&pinctrl 11 1>;
 		};
 		hspa_red {
 			label = "VH4032N:red:hspa";
-			gpios = <&gpio0 12 1>;
+			gpios = <&pinctrl 12 1>;
 		};
 		power_blue {
 			label = "VH4032N:blue:power";
-			gpios = <&gpio0 22 0>;
+			gpios = <&pinctrl 22 0>;
 		};
 		power_red {
 			label = "VH4032N:red:power";
-			gpios = <&gpio0 24 0>;
+			gpios = <&pinctrl 24 0>;
 			default-state = "on";
 		};
 		voice_blue {
 			label = "VH4032N:blue:voice";
-			gpios = <&gpio0 25 1>;
+			gpios = <&pinctrl 25 1>;
 		};
 		voice_red {
 			label = "VH4032N:red:voice";
-			gpios = <&gpio0 26 1>;
+			gpios = <&pinctrl 26 1>;
 		};
 	};
 };
 
-&gpio0 {
+&pinctrl {
 	usb_hub_reset {
 		gpio-hog;
 		gpios = <27 0>;
diff --git a/target/linux/brcm63xx/dts/vr-3025u.dts b/target/linux/brcm63xx/dts/vr-3025u.dts
index 63b1427..2c53f51 100644
--- a/target/linux/brcm63xx/dts/vr-3025u.dts
+++ b/target/linux/brcm63xx/dts/vr-3025u.dts
@@ -21,7 +21,7 @@
 
 		reset {
 			label = "reset";
-			gpios = <&gpio1 2 1>;
+			gpios = <&pinctrl 34 1>;
 			linux,code = <KEY_RESTART>;
 		};
 	};
@@ -31,24 +31,24 @@
 
 		dsl_green {
 			label = "VR-3025u:green:dsl";
-			gpios = <&gpio0 2 1>;
+			gpios = <&pinctrl 2 1>;
 		};
 		inet_green {
 			label = "VR-3025u:green:inet";
-			gpios = <&gpio0 5 0>;
+			gpios = <&pinctrl 5 0>;
 		};
 		power_green {
 			label = "VR-3025u:green:power";
-			gpios = <&gpio0 22 0>;
+			gpios = <&pinctrl 22 0>;
 			default-state = "on";
 		};
 		power_red {
 			label = "VR-3025u:red:power";
-			gpios = <&gpio0 24 0>;
+			gpios = <&pinctrl 24 0>;
 		};
 		inet_red {
 			label = "VR-3025u:red:inet";
-			gpios = <&gpio0 31 0>;
+			gpios = <&pinctrl 31 0>;
 		};
 	};
 };
@@ -74,3 +74,9 @@
 		reg = <0x1fe0000 0x020000>;
 	};
 };
+
+&pinctrl {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pci &pinctrl_ephy0_led &pinctrl_ephy1_led
+		     &pinctrl_ephy2_led &pinctrl_ephy3_led>;
+};
diff --git a/target/linux/brcm63xx/dts/vr-3025un.dts b/target/linux/brcm63xx/dts/vr-3025un.dts
index 864eb82..f9aed51 100644
--- a/target/linux/brcm63xx/dts/vr-3025un.dts
+++ b/target/linux/brcm63xx/dts/vr-3025un.dts
@@ -21,7 +21,7 @@
 
 		reset {
 			label = "reset";
-			gpios = <&gpio1 2 1>;
+			gpios = <&pinctrl 34 1>;
 			linux,code = <KEY_RESTART>;
 		};
 	};
@@ -31,24 +31,24 @@
 
 		dsl_green {
 			label = "VR-3025un:green:dsl";
-			gpios = <&gpio0 2 1>;
+			gpios = <&pinctrl 2 1>;
 		};
 		inet_green {
 			label = "VR-3025un:green:inet";
-			gpios = <&gpio0 5 0>;
+			gpios = <&pinctrl 5 0>;
 		};
 		power_green {
 			label = "VR-3025un:green:power";
-			gpios = <&gpio0 22 0>;
+			gpios = <&pinctrl 22 0>;
 			default-state = "on";
 		};
 		power_red {
 			label = "VR-3025un:red:power";
-			gpios = <&gpio0 24 0>;
+			gpios = <&pinctrl 24 0>;
 		};
 		inet_red {
 			label = "VR-3025un:red:inet";
-			gpios = <&gpio0 31 0>;
+			gpios = <&pinctrl 31 0>;
 		};
 	};
 };
@@ -74,3 +74,9 @@
 		reg = <0x7f0000 0x010000>;
 	};
 };
+
+&pinctrl {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pci &pinctrl_ephy0_led &pinctrl_ephy1_led
+		     &pinctrl_ephy2_led &pinctrl_ephy3_led>;
+};
diff --git a/target/linux/brcm63xx/dts/vr-3026e.dts b/target/linux/brcm63xx/dts/vr-3026e.dts
index eecbf56..da75df8 100644
--- a/target/linux/brcm63xx/dts/vr-3026e.dts
+++ b/target/linux/brcm63xx/dts/vr-3026e.dts
@@ -21,7 +21,7 @@
 
 		reset {
 			label = "reset";
-			gpios = <&gpio1 2 1>;
+			gpios = <&pinctrl 34 1>;
 			linux,code = <KEY_RESTART>;
 		};
 	};
@@ -31,24 +31,24 @@
 
 		dsl_green {
 			label = "VR-3026e:green:dsl";
-			gpios = <&gpio0 2 1>;
+			gpios = <&pinctrl 2 1>;
 		};
 		inet_green {
 			label = "VR-3026e:green:inet";
-			gpios = <&gpio0 5 0>;
+			gpios = <&pinctrl 5 0>;
 		};
 		power_green {
 			label = "VR-3026e:green:power";
-			gpios = <&gpio0 22 0>;
+			gpios = <&pinctrl 22 0>;
 			default-state = "on";
 		};
 		power_red {
 			label = "VR-3026e:red:power";
-			gpios = <&gpio0 24 0>;
+			gpios = <&pinctrl 24 0>;
 		};
 		inet_red {
 			label = "VR-3026e:red:inet";
-			gpios = <&gpio0 31 0>;
+			gpios = <&pinctrl 31 0>;
 		};
 	};
 };
@@ -74,3 +74,9 @@
 		reg = <0x7f0000 0x010000>;
 	};
 };
+
+&pinctrl {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pci &pinctrl_ephy0_led &pinctrl_ephy1_led
+		     &pinctrl_ephy2_led &pinctrl_ephy3_led>;
+};
diff --git a/target/linux/brcm63xx/dts/wap-5813n.dts b/target/linux/brcm63xx/dts/wap-5813n.dts
index 9312bed..d5c0a5f 100644
--- a/target/linux/brcm63xx/dts/wap-5813n.dts
+++ b/target/linux/brcm63xx/dts/wap-5813n.dts
@@ -21,17 +21,17 @@
 
 		wlan {
 			label = "wlan";
-			gpios = <&gpio1 0 1>;
+			gpios = <&pinctrl 32 1>;
 			linux,code = <KEY_WLAN>;
 		};
 		reset {
 			label = "reset";
-			gpios = <&gpio1 2 1>;
+			gpios = <&pinctrl 34 1>;
 			linux,code = <KEY_RESTART>;
 		};
 		wps {
 			label = "wps";
-			gpios = <&gpio1 3 1>;
+			gpios = <&pinctrl 35 1>;
 			linux,code = <KEY_WPS_BUTTON>;
 		};
 	};
@@ -41,24 +41,24 @@
 
 		inet_green {
 			label = "WAP-5813n:green:inet";
-			gpios = <&gpio0 5 0>;
+			gpios = <&pinctrl 5 0>;
 		};
 		power_green {
 			label = "WAP-5813n:green:power";
-			gpios = <&gpio0 22 0>;
+			gpios = <&pinctrl 22 0>;
 			default-state = "on";
 		};
 		wps_green {
 			label = "WAP-5813n:green:wps";
-			gpios = <&gpio0 23 1>;
+			gpios = <&pinctrl 23 1>;
 		};
 		power_red {
 			label = "WAP-5813n:red:power";
-			gpios = <&gpio0 24 0>;
+			gpios = <&pinctrl 24 0>;
 		};
 		inet_red {
 			label = "WAP-5813n:red:inet";
-			gpios = <&gpio0 31 0>;
+			gpios = <&pinctrl 31 0>;
 		};
 	};
 };
@@ -84,3 +84,8 @@
 		reg = <0x7f0000 0x010000>;
 	};
 };
+
+&pinctrl {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pci>;
+};
diff --git a/target/linux/brcm63xx/patches-4.4/000-4.6-01-gpio-Add-devm_-apis-for-gpiochip_add_data-and-gpioch.patch b/target/linux/brcm63xx/patches-4.4/000-4.6-01-gpio-Add-devm_-apis-for-gpiochip_add_data-and-gpioch.patch
new file mode 100644
index 0000000..ab2fb07
--- /dev/null
+++ b/target/linux/brcm63xx/patches-4.4/000-4.6-01-gpio-Add-devm_-apis-for-gpiochip_add_data-and-gpioch.patch
@@ -0,0 +1,115 @@
+From 0cf3292cde22f8843ae5d1eeb8466d8121243c1a Mon Sep 17 00:00:00 2001
+From: Laxman Dewangan <ldewangan at nvidia.com>
+Date: Mon, 15 Feb 2016 16:32:09 +0530
+Subject: [PATCH] gpio: Add devm_ apis for gpiochip_add_data and
+ gpiochip_remove
+
+Add device managed APIs devm_gpiochip_add_data() and
+devm_gpiochip_remove() for the APIs gpiochip_add_data()
+and gpiochip_remove().
+
+This helps in reducing code in error path and sometimes
+removal of .remove callback for driver unbind.
+
+Signed-off-by: Laxman Dewangan <ldewangan at nvidia.com>
+---
+ drivers/gpio/gpiolib.c      | 74 +++++++++++++++++++++++++++++++++++++++++++++
+ include/linux/gpio/driver.h |  4 +++
+ 2 files changed, 78 insertions(+)
+
+--- a/drivers/gpio/gpiolib.c
++++ b/drivers/gpio/gpiolib.c
+@@ -433,6 +433,80 @@ void gpiochip_remove(struct gpio_chip *c
+ }
+ EXPORT_SYMBOL_GPL(gpiochip_remove);
+ 
++static void devm_gpio_chip_release(struct device *dev, void *res)
++{
++	struct gpio_chip *chip = *(struct gpio_chip **)res;
++
++	gpiochip_remove(chip);
++}
++
++static int devm_gpio_chip_match(struct device *dev, void *res, void *data)
++
++{
++	struct gpio_chip **r = res;
++
++	if (!r || !*r) {
++		WARN_ON(!r || !*r);
++		return 0;
++	}
++
++	return *r == data;
++}
++
++/**
++ * devm_gpiochip_add_data() - Resource manager piochip_add_data()
++ * @dev: the device pointer on which irq_chip belongs to.
++ * @chip: the chip to register, with chip->base initialized
++ * Context: potentially before irqs will work
++ *
++ * Returns a negative errno if the chip can't be registered, such as
++ * because the chip->base is invalid or already associated with a
++ * different chip.  Otherwise it returns zero as a success code.
++ *
++ * The gpio chip automatically be released when the device is unbound.
++ */
++int devm_gpiochip_add_data(struct device *dev, struct gpio_chip *chip,
++			   void *data)
++{
++	struct gpio_chip **ptr;
++	int ret;
++
++	ptr = devres_alloc(devm_gpio_chip_release, sizeof(*ptr),
++			     GFP_KERNEL);
++	if (!ptr)
++		return -ENOMEM;
++
++	ret = gpiochip_add_data(chip, data);
++	if (ret < 0) {
++		devres_free(ptr);
++		return ret;
++	}
++
++	*ptr = chip;
++	devres_add(dev, ptr);
++
++	return 0;
++}
++EXPORT_SYMBOL_GPL(devm_gpiochip_add_data);
++
++/**
++ * devm_gpiochip_remove() - Resource manager of gpiochip_remove()
++ * @dev: device for which which resource was allocated
++ * @chip: the chip to remove
++ *
++ * A gpio_chip with any GPIOs still requested may not be removed.
++ */
++void devm_gpiochip_remove(struct device *dev, struct gpio_chip *chip)
++{
++	int ret;
++
++	ret = devres_release(dev, devm_gpio_chip_release,
++			     devm_gpio_chip_match, chip);
++	if (!ret)
++		WARN_ON(ret);
++}
++EXPORT_SYMBOL_GPL(devm_gpiochip_remove);
++
+ /**
+  * gpiochip_find() - iterator for locating a specific gpio_chip
+  * @data: data to pass to match function
+--- a/include/linux/gpio/driver.h
++++ b/include/linux/gpio/driver.h
+@@ -206,6 +206,10 @@ static inline int gpiochip_add(struct gp
+ 	return gpiochip_add_data(chip, NULL);
+ }
+ extern void gpiochip_remove(struct gpio_chip *chip);
++extern int devm_gpiochip_add_data(struct device *dev, struct gpio_chip *chip,
++				  void *data);
++extern void devm_gpiochip_remove(struct device *dev, struct gpio_chip *chip);
++
+ extern struct gpio_chip *gpiochip_find(void *data,
+ 			      int (*match)(struct gpio_chip *chip, void *data));
+ 
diff --git a/target/linux/brcm63xx/patches-4.4/000-4.7-01-pinctrl-Add-devm_-apis-for-pinctrl_-register-unregis.patch b/target/linux/brcm63xx/patches-4.4/000-4.7-01-pinctrl-Add-devm_-apis-for-pinctrl_-register-unregis.patch
new file mode 100644
index 0000000..205b6d7
--- /dev/null
+++ b/target/linux/brcm63xx/patches-4.4/000-4.7-01-pinctrl-Add-devm_-apis-for-pinctrl_-register-unregis.patch
@@ -0,0 +1,108 @@
+From 80e0f8d94d3090f0f7bf3faf3e6180e920ee0d22 Mon Sep 17 00:00:00 2001
+From: Laxman Dewangan <ldewangan at nvidia.com>
+Date: Wed, 24 Feb 2016 14:12:59 +0530
+Subject: [PATCH] pinctrl: Add devm_ apis for pinctrl_{register, unregister}
+
+Add device managed APIs devm_pinctrl_register() and
+devm_pinctrl_unregister() for the APIs pinctrl_register()
+and pinctrl_unregister().
+
+This helps in reducing code in error path and sometimes
+removal of .remove callback for driver unbind.
+
+Signed-off-by: Laxman Dewangan <ldewangan at nvidia.com>
+Reviewed-by: Philipp Zabel <p.zabel at pengutronix.de>
+Acked-by: Bjorn Andersson <bjorn.andersson at linaro.org>
+Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
+---
+ drivers/pinctrl/core.c          | 63 +++++++++++++++++++++++++++++++++++++++++
+ include/linux/pinctrl/pinctrl.h |  6 ++++
+ 2 files changed, 69 insertions(+)
+
+--- a/drivers/pinctrl/core.c
++++ b/drivers/pinctrl/core.c
+@@ -1861,6 +1861,69 @@ void pinctrl_unregister(struct pinctrl_d
+ }
+ EXPORT_SYMBOL_GPL(pinctrl_unregister);
+ 
++static void devm_pinctrl_dev_release(struct device *dev, void *res)
++{
++	struct pinctrl_dev *pctldev = *(struct pinctrl_dev **)res;
++
++	pinctrl_unregister(pctldev);
++}
++
++static int devm_pinctrl_dev_match(struct device *dev, void *res, void *data)
++{
++	struct pctldev **r = res;
++
++	if (WARN_ON(!r || !*r))
++		return 0;
++
++	return *r == data;
++}
++
++/**
++ * devm_pinctrl_register() - Resource managed version of pinctrl_register().
++ * @dev: parent device for this pin controller
++ * @pctldesc: descriptor for this pin controller
++ * @driver_data: private pin controller data for this pin controller
++ *
++ * Returns an error pointer if pincontrol register failed. Otherwise
++ * it returns valid pinctrl handle.
++ *
++ * The pinctrl device will be automatically released when the device is unbound.
++ */
++struct pinctrl_dev *devm_pinctrl_register(struct device *dev,
++					  struct pinctrl_desc *pctldesc,
++					  void *driver_data)
++{
++	struct pinctrl_dev **ptr, *pctldev;
++
++	ptr = devres_alloc(devm_pinctrl_dev_release, sizeof(*ptr), GFP_KERNEL);
++	if (!ptr)
++		return ERR_PTR(-ENOMEM);
++
++	pctldev = pinctrl_register(pctldesc, dev, driver_data);
++	if (IS_ERR(pctldev)) {
++		devres_free(ptr);
++		return pctldev;
++	}
++
++	*ptr = pctldev;
++	devres_add(dev, ptr);
++
++	return pctldev;
++}
++EXPORT_SYMBOL_GPL(devm_pinctrl_register);
++
++/**
++ * devm_pinctrl_unregister() - Resource managed version of pinctrl_unregister().
++ * @dev: device for which which resource was allocated
++ * @pctldev: the pinctrl device to unregister.
++ */
++void devm_pinctrl_unregister(struct device *dev, struct pinctrl_dev *pctldev)
++{
++	WARN_ON(devres_release(dev, devm_pinctrl_dev_release,
++			       devm_pinctrl_dev_match, pctldev));
++}
++EXPORT_SYMBOL_GPL(devm_pinctrl_unregister);
++
+ static int __init pinctrl_init(void)
+ {
+ 	pr_info("initialized pinctrl subsystem\n");
+--- a/include/linux/pinctrl/pinctrl.h
++++ b/include/linux/pinctrl/pinctrl.h
+@@ -144,6 +144,12 @@ struct pinctrl_desc {
+ extern struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc,
+ 				struct device *dev, void *driver_data);
+ extern void pinctrl_unregister(struct pinctrl_dev *pctldev);
++extern struct pinctrl_dev *devm_pinctrl_register(struct device *dev,
++				struct pinctrl_desc *pctldesc,
++				void *driver_data);
++extern void devm_pinctrl_unregister(struct device *dev,
++				struct pinctrl_dev *pctldev);
++
+ extern bool pin_is_valid(struct pinctrl_dev *pctldev, int pin);
+ extern void pinctrl_add_gpio_range(struct pinctrl_dev *pctldev,
+ 				struct pinctrl_gpio_range *range);
diff --git a/target/linux/brcm63xx/patches-4.4/000-4.7-02-pinctrl-Rename-pinctrl_utils_dt_free_map-to-pinctrl_.patch b/target/linux/brcm63xx/patches-4.4/000-4.7-02-pinctrl-Rename-pinctrl_utils_dt_free_map-to-pinctrl_.patch
new file mode 100644
index 0000000..5acb379
--- /dev/null
+++ b/target/linux/brcm63xx/patches-4.4/000-4.7-02-pinctrl-Rename-pinctrl_utils_dt_free_map-to-pinctrl_.patch
@@ -0,0 +1,59 @@
+From d32f7fd3bbc32732b094d938b95169521503a9fb Mon Sep 17 00:00:00 2001
+From: Irina Tirdea <irina.tirdea at intel.com>
+Date: Thu, 31 Mar 2016 14:44:42 +0300
+Subject: [PATCH] pinctrl: Rename pinctrl_utils_dt_free_map to
+ pinctrl_utils_free_map
+
+Rename pinctrl_utils_dt_free_map to pinctrl_utils_free_map, since
+it does not depend on device tree despite the current name. This
+will enforce a consistent naming in pinctr-utils.c and will make
+it clear it can be called from outside device tree (e.g. from
+ACPI handling code).
+
+Signed-off-by: Irina Tirdea <irina.tirdea at intel.com>
+Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
+---
+ drivers/pinctrl/pinconf-generic.c                | 2 +-
+ drivers/pinctrl/pinctrl-utils.c                  | 4 ++--
+ drivers/pinctrl/pinctrl-utils.h                  | 2 +-
+ 3 files changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/pinctrl/pinconf-generic.c
++++ b/drivers/pinctrl/pinconf-generic.c
+@@ -385,7 +385,7 @@ int pinconf_generic_dt_node_to_map(struc
+ 	return 0;
+ 
+ exit:
+-	pinctrl_utils_dt_free_map(pctldev, *map, *num_maps);
++	pinctrl_utils_free_map(pctldev, *map, *num_maps);
+ 	return ret;
+ }
+ EXPORT_SYMBOL_GPL(pinconf_generic_dt_node_to_map);
+--- a/drivers/pinctrl/pinctrl-utils.c
++++ b/drivers/pinctrl/pinctrl-utils.c
+@@ -122,7 +122,7 @@ int pinctrl_utils_add_config(struct pinc
+ }
+ EXPORT_SYMBOL_GPL(pinctrl_utils_add_config);
+ 
+-void pinctrl_utils_dt_free_map(struct pinctrl_dev *pctldev,
++void pinctrl_utils_free_map(struct pinctrl_dev *pctldev,
+ 	      struct pinctrl_map *map, unsigned num_maps)
+ {
+ 	int i;
+@@ -139,4 +139,4 @@ void pinctrl_utils_dt_free_map(struct pi
+ 	}
+ 	kfree(map);
+ }
+-EXPORT_SYMBOL_GPL(pinctrl_utils_dt_free_map);
++EXPORT_SYMBOL_GPL(pinctrl_utils_free_map);
+--- a/drivers/pinctrl/pinctrl-utils.h
++++ b/drivers/pinctrl/pinctrl-utils.h
+@@ -37,7 +37,7 @@ int pinctrl_utils_add_map_configs(struct
+ int pinctrl_utils_add_config(struct pinctrl_dev *pctldev,
+ 		unsigned long **configs, unsigned *num_configs,
+ 		unsigned long config);
+-void pinctrl_utils_dt_free_map(struct pinctrl_dev *pctldev,
++void pinctrl_utils_free_map(struct pinctrl_dev *pctldev,
+ 		struct pinctrl_map *map, unsigned num_maps);
+ 
+ #endif /* __PINCTRL_UTILS_H__ */
diff --git a/target/linux/brcm63xx/patches-4.4/130-pinctrl-add-bcm63xx-base-code.patch b/target/linux/brcm63xx/patches-4.4/130-pinctrl-add-bcm63xx-base-code.patch
new file mode 100644
index 0000000..57614c2
--- /dev/null
+++ b/target/linux/brcm63xx/patches-4.4/130-pinctrl-add-bcm63xx-base-code.patch
@@ -0,0 +1,226 @@
+From ab2f33e35e35905a76204138143875251f3e1088 Mon Sep 17 00:00:00 2001
+From: Jonas Gorski <jonas.gorski at gmail.com>
+Date: Fri, 24 Jun 2016 22:07:42 +0200
+Subject: [PATCH 01/13] pinctrl: add bcm63xx base code
+
+Setup directory and add a helper for bcm63xx pinctrl support.
+
+Signed-off-by: Jonas Gorski <jonas.gorski at gmail.com>
+---
+ drivers/pinctrl/Kconfig                   |   1 +
+ drivers/pinctrl/Makefile                  |   1 +
+ drivers/pinctrl/bcm63xx/Kconfig           |   3 +
+ drivers/pinctrl/bcm63xx/Makefile          |   1 +
+ drivers/pinctrl/bcm63xx/pinctrl-bcm63xx.c | 142 ++++++++++++++++++++++++++++++
+ drivers/pinctrl/bcm63xx/pinctrl-bcm63xx.h |  14 +++
+ 7 files changed, 163 insertions(+)
+ create mode 100644 drivers/pinctrl/bcm63xx/Kconfig
+ create mode 100644 drivers/pinctrl/bcm63xx/Makefile
+ create mode 100644 drivers/pinctrl/bcm63xx/pinctrl-bcm63xx.c
+ create mode 100644 drivers/pinctrl/bcm63xx/pinctrl-bcm63xx.h
+
+--- a/drivers/pinctrl/Kconfig
++++ b/drivers/pinctrl/Kconfig
+@@ -247,6 +247,7 @@ config PINCTRL_ZYNQ
+ 	  This selectes the pinctrl driver for Xilinx Zynq.
+ 
+ source "drivers/pinctrl/bcm/Kconfig"
++source "drivers/pinctrl/bcm63xx/Kconfig"
+ source "drivers/pinctrl/berlin/Kconfig"
+ source "drivers/pinctrl/freescale/Kconfig"
+ source "drivers/pinctrl/intel/Kconfig"
+--- a/drivers/pinctrl/Makefile
++++ b/drivers/pinctrl/Makefile
+@@ -41,6 +41,7 @@ obj-$(CONFIG_PINCTRL_ST) 	+= pinctrl-st.
+ obj-$(CONFIG_PINCTRL_ZYNQ)	+= pinctrl-zynq.o
+ 
+ obj-$(CONFIG_ARCH_BCM)		+= bcm/
++obj-y				+= bcm63xx/
+ obj-$(CONFIG_ARCH_BERLIN)	+= berlin/
+ obj-y				+= freescale/
+ obj-$(CONFIG_X86)		+= intel/
+--- /dev/null
++++ b/drivers/pinctrl/bcm63xx/Kconfig
+@@ -0,0 +1,3 @@
++config PINCTRL_BCM63XX
++	bool
++	select GPIO_GENERIC
+--- /dev/null
++++ b/drivers/pinctrl/bcm63xx/Makefile
+@@ -0,0 +1 @@
++obj-$(CONFIG_PINCTRL_BCM63XX)	+= pinctrl-bcm63xx.o
+--- /dev/null
++++ b/drivers/pinctrl/bcm63xx/pinctrl-bcm63xx.c
+@@ -0,0 +1,155 @@
++/*
++ * This file is subject to the terms and conditions of the GNU General Public
++ * License.  See the file "COPYING" in the main directory of this archive
++ * for more details.
++ *
++ * Copyright (C) 2016 Jonas Gorski <jonas.gorski at gmail.com>
++ */
++
++#include <linux/bitops.h>
++#include <linux/device.h>
++#include <linux/gpio/driver.h>
++#include <linux/of_irq.h>
++
++#include "pinctrl-bcm63xx.h"
++#include "../core.h"
++
++#define BANK_SIZE	sizeof(u32)
++#define PINS_PER_BANK	(BANK_SIZE * BITS_PER_BYTE)
++
++#ifdef CONFIG_OF
++static int bcm63xx_gpio_of_xlate(struct gpio_chip *gc,
++				 const struct of_phandle_args *gpiospec,
++				 u32 *flags)
++{
++	struct gpio_chip *base = gpiochip_get_data(gc);
++	int pin = gpiospec->args[0];
++
++	if (gc != &base[pin / PINS_PER_BANK])
++		return -EINVAL;
++
++	pin = pin % PINS_PER_BANK;
++
++	if (pin >= gc->ngpio)
++		return -EINVAL;
++
++	if (flags)
++		*flags = gpiospec->args[1];
++
++	return pin;
++}
++#endif
++
++static int bcm63xx_gpio_to_irq(struct gpio_chip *chip, unsigned gpio)
++{
++	struct gpio_chip *base = gpiochip_get_data(chip);
++	char irq_name[7]; /* "gpioXX" */
++
++	/* FIXME: this is ugly */
++	sprintf(irq_name, "gpio%d", gpio + PINS_PER_BANK * (chip - base));
++	return of_irq_get_byname(chip->of_node, irq_name);
++}
++
++static int bcm63xx_setup_gpio(struct device *dev, struct gpio_chip *gc,
++			      void __iomem *dirout, void __iomem *data,
++			      size_t sz, int ngpio)
++
++{
++	int banks, chips, i, ret = -EINVAL;
++
++	chips = DIV_ROUND_UP(ngpio, PINS_PER_BANK);
++	banks = sz / BANK_SIZE;
++
++	for (i = 0; i < chips; i++) {
++		int offset, pins;
++		int reg_offset;
++		char *label;
++
++		label = devm_kasprintf(dev, GFP_KERNEL, "bcm63xx-gpio.%i", i);
++		if (!label)
++			return -ENOMEM;
++
++		offset = i * PINS_PER_BANK;
++		pins = min_t(int, ngpio - offset, PINS_PER_BANK);
++
++		/* the registers are treated like a huge big endian register */
++		reg_offset = (banks - i - 1) * BANK_SIZE;
++
++		ret = bgpio_init(&gc[i], dev, BANK_SIZE, data + reg_offset,
++				 NULL, NULL, dirout + reg_offset, NULL,
++				 BGPIOF_BIG_ENDIAN_BYTE_ORDER);
++		if (ret)
++			return ret;
++
++		gc[i].request = gpiochip_generic_request;
++		gc[i].free = gpiochip_generic_free;
++
++		if (of_get_property(dev->of_node, "interrupt-names", NULL))
++			gc[i].to_irq = bcm63xx_gpio_to_irq;
++
++#ifdef CONFIG_OF
++		gc[i].of_gpio_n_cells = 2;
++		gc[i].of_xlate = bcm63xx_gpio_of_xlate;
++#endif
++
++		gc[i].label = label;
++		gc[i].ngpio = pins;
++
++		devm_gpiochip_add_data(dev, &gc[i], gc);
++	}
++
++	return 0;
++}
++
++static void bcm63xx_setup_pinranges(struct gpio_chip *gc, const char *name,
++				    int ngpio)
++{
++	int i, chips = DIV_ROUND_UP(ngpio, PINS_PER_BANK);
++
++	for (i = 0; i < chips; i++) {
++		int offset, pins;
++
++		offset = i * PINS_PER_BANK;
++		pins = min_t(int, ngpio - offset, PINS_PER_BANK);
++
++		gpiochip_add_pin_range(&gc[i], name, 0, offset, pins);
++	}
++}
++
++struct pinctrl_dev *bcm63xx_pinctrl_register(struct platform_device *pdev,
++					     struct pinctrl_desc *desc,
++					     void *priv, struct gpio_chip *gc,
++					     int ngpio)
++{
++	struct pinctrl_dev *pctldev;
++	struct resource *res;
++	void __iomem *dirout, *data;
++	size_t sz;
++	int ret;
++
++	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dirout");
++	dirout = devm_ioremap_resource(&pdev->dev, res);
++	if (IS_ERR(dirout))
++		return ERR_CAST(dirout);
++
++	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dat");
++	data = devm_ioremap_resource(&pdev->dev, res);
++	if (IS_ERR(data))
++		return ERR_CAST(data);
++
++	sz = resource_size(res);
++
++	ret = bcm63xx_setup_gpio(&pdev->dev, gc, dirout, data, sz, ngpio);
++	if (ret)
++		return ERR_PTR(ret);
++
++	pctldev = devm_pinctrl_register(&pdev->dev, desc, priv);
++	if (IS_ERR(pctldev))
++		return pctldev;
++
++	bcm63xx_setup_pinranges(gc, pinctrl_dev_get_devname(pctldev), ngpio);
++
++	dev_info(&pdev->dev, "registered at mmio %p\n", dirout);
++
++	return pctldev;
++}
+--- /dev/null
++++ b/drivers/pinctrl/bcm63xx/pinctrl-bcm63xx.h
+@@ -0,0 +1,14 @@
++#ifndef __PINCTRL_BCM63XX
++#define __PINCTRL_BCM63XX
++
++#include <linux/kernel.h>
++#include <linux/gpio.h>
++#include <linux/pinctrl/pinctrl.h>
++#include <linux/platform_device.h>
++
++struct pinctrl_dev *bcm63xx_pinctrl_register(struct platform_device *pdev,
++					     struct pinctrl_desc *desc,
++					     void *priv, struct gpio_chip *gc,
++					     int ngpio);
++
++#endif
diff --git a/target/linux/brcm63xx/patches-4.4/131-Documentation-add-BCM6328-pincontroller-binding-docu.patch b/target/linux/brcm63xx/patches-4.4/131-Documentation-add-BCM6328-pincontroller-binding-docu.patch
new file mode 100644
index 0000000..3a2a781
--- /dev/null
+++ b/target/linux/brcm63xx/patches-4.4/131-Documentation-add-BCM6328-pincontroller-binding-docu.patch
@@ -0,0 +1,78 @@
+From 4bdd40849632608d5cb7d3a64380cd76e7eea07b Mon Sep 17 00:00:00 2001
+From: Jonas Gorski <jonas.gorski at gmail.com>
+Date: Wed, 27 Jul 2016 11:33:56 +0200
+Subject: [PATCH 02/16] Documentation: add BCM6328 pincontroller binding
+ documentation
+
+Add binding documentation for the pincontrol core found in BCM6328 SoCs.
+
+Signed-off-by: Jonas Gorski <jonas.gorski at gmail.com>
+---
+ .../bindings/pinctrl/brcm,bcm6328-pinctrl.txt      | 61 ++++++++++++++++++++++
+ 1 file changed, 61 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.txt
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.txt
+@@ -0,0 +1,61 @@
++* Broadcom BCM6328 pin controller
++
++Required properties:
++- compatible: Must be "brcm,bcm6328-pinctrl".
++- reg: Register specifies of dirout, dat, mode, mux registers.
++- reg-names: Must be "dirout", "dat", "mode", "mux".
++- gpio-controller: Identifies this node as a GPIO controller.
++- #gpio-cells: Must be <2>
++
++Example:
++
++pinctrl: pin-controller at 10000080 {
++	compatible = "brcm,bcm6328-pinctrl";
++	reg = <0x10000080 0x8>,
++	      <0x10000088 0x8>,
++	      <0x10000098 0x4>,
++	      <0x1000009c 0xc>;
++	reg-names = "dirout", "dat", "mode", "mux";
++
++	gpio-controller;
++	#gpio-cells = <2>;
++};
++
++Available pins/groups and functions:
++
++name		pins	functions
++-----------------------------------------------------------
++gpio0		0	led
++gpio1		1	led
++gpio2		2	led
++gpio3		3	led
++gpio4		4	led
++gpio5		5	led
++gpio6		6	led, serial_led_data
++gpio7		7	led, serial_led_clk
++gpio8		8	led
++gpio9		9	led
++gpio10		10	led
++gpio11		11	led
++gpio12		12	led
++gpio13		13	led
++gpio14		14	led
++gpio15		15	led
++gpio16		16	led, pcie_clkreq
++gpio17		17	led
++gpio18		18	led
++gpio19		19	led
++gpio20		20	led
++gpio21		21	led
++gpio22		22	led
++gpio23		23	led
++gpio24		24	-
++gpio25		25	ephy0_act_led
++gpio26		26	ephy1_act_led
++gpio27		27	ephy2_act_led
++gpio28		28	ephy3_act_led
++gpio29		29	-
++gpio30		30	-
++gpio31		31	-
++hsspi_cs1	-	hsspi_cs1
++usb_port1	-	usb_host_port, usb_device_port
diff --git a/target/linux/brcm63xx/patches-4.4/132-pinctrl-add-a-pincontrol-driver-for-BCM6328.patch b/target/linux/brcm63xx/patches-4.4/132-pinctrl-add-a-pincontrol-driver-for-BCM6328.patch
new file mode 100644
index 0000000..e1f2140
--- /dev/null
+++ b/target/linux/brcm63xx/patches-4.4/132-pinctrl-add-a-pincontrol-driver-for-BCM6328.patch
@@ -0,0 +1,495 @@
+From 393e9753f6492c1fdf55891ddee60d955ae8b119 Mon Sep 17 00:00:00 2001
+From: Jonas Gorski <jonas.gorski at gmail.com>
+Date: Fri, 24 Jun 2016 22:12:50 +0200
+Subject: [PATCH 03/16] pinctrl: add a pincontrol driver for BCM6328
+
+Add a pincontrol driver for BCM6328. BCM628 supports muxing 32 pins as
+GPIOs, as LEDs for the integrated LED controller, or various other
+functions. Its pincontrol mux registers also control other aspects, like
+switching the second USB port between host and device mode.
+
+Signed-off-by: Jonas Gorski <jonas.gorski at gmail.com>
+---
+ drivers/pinctrl/bcm63xx/Kconfig           |   7 +
+ drivers/pinctrl/bcm63xx/Makefile          |   1 +
+ drivers/pinctrl/bcm63xx/pinctrl-bcm6328.c | 456 ++++++++++++++++++++++++++++++
+ 3 files changed, 464 insertions(+)
+ create mode 100644 drivers/pinctrl/bcm63xx/pinctrl-bcm6328.c
+
+--- a/drivers/pinctrl/bcm63xx/Kconfig
++++ b/drivers/pinctrl/bcm63xx/Kconfig
+@@ -1,3 +1,10 @@
+ config PINCTRL_BCM63XX
+ 	bool
+ 	select GPIO_GENERIC
++
++config PINCTRL_BCM6328
++	bool "BCM6328 pincontrol driver" if COMPILE_TEST
++	select PINMUX
++	select PINCONF
++	select PINCTRL_BCM63XX
++	select GENERIC_PINCONF
+--- a/drivers/pinctrl/bcm63xx/Makefile
++++ b/drivers/pinctrl/bcm63xx/Makefile
+@@ -1 +1,2 @@
+ obj-$(CONFIG_PINCTRL_BCM63XX)	+= pinctrl-bcm63xx.o
++obj-$(CONFIG_PINCTRL_BCM6328)	+= pinctrl-bcm6328.o
+--- /dev/null
++++ b/drivers/pinctrl/bcm63xx/pinctrl-bcm6328.c
+@@ -0,0 +1,456 @@
++/*
++ * This file is subject to the terms and conditions of the GNU General Public
++ * License.  See the file "COPYING" in the main directory of this archive
++ * for more details.
++ *
++ * Copyright (C) 2016 Jonas Gorski <jonas.gorski at gmail.com>
++ */
++
++#include <linux/bitops.h>
++#include <linux/gpio.h>
++#include <linux/kernel.h>
++#include <linux/slab.h>
++#include <linux/spinlock.h>
++#include <linux/of.h>
++#include <linux/of_gpio.h>
++#include <linux/platform_device.h>
++
++#include <linux/pinctrl/machine.h>
++#include <linux/pinctrl/pinconf.h>
++#include <linux/pinctrl/pinconf-generic.h>
++#include <linux/pinctrl/pinmux.h>
++
++#include "../core.h"
++#include "../pinctrl-utils.h"
++
++#include "pinctrl-bcm63xx.h"
++
++#define BCM6328_MUX_LO_REG	0x4
++#define BCM6328_MUX_HI_REG	0x0
++#define BCM6328_MUX_OTHER_REG	0xc
++
++#define BCM6328_NGPIO		32
++
++struct bcm6328_pingroup {
++	const char *name;
++	const unsigned * const pins;
++	const unsigned num_pins;
++};
++
++struct bcm6328_function {
++	const char *name;
++	const char * const *groups;
++	const unsigned num_groups;
++
++	unsigned mode_val:1;
++	unsigned mux_val:2;
++};
++
++struct bcm6328_pinctrl {
++	struct pinctrl_dev *pctldev;
++	struct pinctrl_desc desc;
++
++	void __iomem *mode;
++	void __iomem *mux[3];
++
++	/* register access lock */
++	spinlock_t lock;
++
++	struct gpio_chip gpio;
++};
++
++static const struct pinctrl_pin_desc bcm6328_pins[] = {
++	PINCTRL_PIN(0, "gpio0"),
++	PINCTRL_PIN(1, "gpio1"),
++	PINCTRL_PIN(2, "gpio2"),
++	PINCTRL_PIN(3, "gpio3"),
++	PINCTRL_PIN(4, "gpio4"),
++	PINCTRL_PIN(5, "gpio5"),
++	PINCTRL_PIN(6, "gpio6"),
++	PINCTRL_PIN(7, "gpio7"),
++	PINCTRL_PIN(8, "gpio8"),
++	PINCTRL_PIN(9, "gpio9"),
++	PINCTRL_PIN(10, "gpio10"),
++	PINCTRL_PIN(11, "gpio11"),
++	PINCTRL_PIN(12, "gpio12"),
++	PINCTRL_PIN(13, "gpio13"),
++	PINCTRL_PIN(14, "gpio14"),
++	PINCTRL_PIN(15, "gpio15"),
++	PINCTRL_PIN(16, "gpio16"),
++	PINCTRL_PIN(17, "gpio17"),
++	PINCTRL_PIN(18, "gpio18"),
++	PINCTRL_PIN(19, "gpio19"),
++	PINCTRL_PIN(20, "gpio20"),
++	PINCTRL_PIN(21, "gpio21"),
++	PINCTRL_PIN(22, "gpio22"),
++	PINCTRL_PIN(23, "gpio23"),
++	PINCTRL_PIN(24, "gpio24"),
++	PINCTRL_PIN(25, "gpio25"),
++	PINCTRL_PIN(26, "gpio26"),
++	PINCTRL_PIN(27, "gpio27"),
++	PINCTRL_PIN(28, "gpio28"),
++	PINCTRL_PIN(29, "gpio29"),
++	PINCTRL_PIN(30, "gpio30"),
++	PINCTRL_PIN(31, "gpio31"),
++
++	/*
++	 * No idea where they really are; so let's put them according
++	 * to their mux offsets.
++	 */
++	PINCTRL_PIN(36, "hsspi_cs1"),
++	PINCTRL_PIN(38, "usb_p2"),
++};
++
++static unsigned gpio0_pins[] = { 0 };
++static unsigned gpio1_pins[] = { 1 };
++static unsigned gpio2_pins[] = { 2 };
++static unsigned gpio3_pins[] = { 3 };
++static unsigned gpio4_pins[] = { 4 };
++static unsigned gpio5_pins[] = { 5 };
++static unsigned gpio6_pins[] = { 6 };
++static unsigned gpio7_pins[] = { 7 };
++static unsigned gpio8_pins[] = { 8 };
++static unsigned gpio9_pins[] = { 9 };
++static unsigned gpio10_pins[] = { 10 };
++static unsigned gpio11_pins[] = { 11 };
++static unsigned gpio12_pins[] = { 12 };
++static unsigned gpio13_pins[] = { 13 };
++static unsigned gpio14_pins[] = { 14 };
++static unsigned gpio15_pins[] = { 15 };
++static unsigned gpio16_pins[] = { 16 };
++static unsigned gpio17_pins[] = { 17 };
++static unsigned gpio18_pins[] = { 18 };
++static unsigned gpio19_pins[] = { 19 };
++static unsigned gpio20_pins[] = { 20 };
++static unsigned gpio21_pins[] = { 21 };
++static unsigned gpio22_pins[] = { 22 };
++static unsigned gpio23_pins[] = { 23 };
++static unsigned gpio24_pins[] = { 24 };
++static unsigned gpio25_pins[] = { 25 };
++static unsigned gpio26_pins[] = { 26 };
++static unsigned gpio27_pins[] = { 27 };
++static unsigned gpio28_pins[] = { 28 };
++static unsigned gpio29_pins[] = { 29 };
++static unsigned gpio30_pins[] = { 30 };
++static unsigned gpio31_pins[] = { 31 };
++
++static unsigned hsspi_cs1_pins[] = { 36 };
++static unsigned usb_port1_pins[] = { 38 };
++
++#define BCM6328_GROUP(n)					\
++	{							\
++		.name = #n,					\
++		.pins = n##_pins,				\
++		.num_pins = ARRAY_SIZE(n##_pins),		\
++	}
++
++static struct bcm6328_pingroup bcm6328_groups[] = {
++	BCM6328_GROUP(gpio0),
++	BCM6328_GROUP(gpio1),
++	BCM6328_GROUP(gpio2),
++	BCM6328_GROUP(gpio3),
++	BCM6328_GROUP(gpio4),
++	BCM6328_GROUP(gpio5),
++	BCM6328_GROUP(gpio6),
++	BCM6328_GROUP(gpio7),
++	BCM6328_GROUP(gpio8),
++	BCM6328_GROUP(gpio9),
++	BCM6328_GROUP(gpio10),
++	BCM6328_GROUP(gpio11),
++	BCM6328_GROUP(gpio12),
++	BCM6328_GROUP(gpio13),
++	BCM6328_GROUP(gpio14),
++	BCM6328_GROUP(gpio15),
++	BCM6328_GROUP(gpio16),
++	BCM6328_GROUP(gpio17),
++	BCM6328_GROUP(gpio18),
++	BCM6328_GROUP(gpio19),
++	BCM6328_GROUP(gpio20),
++	BCM6328_GROUP(gpio21),
++	BCM6328_GROUP(gpio22),
++	BCM6328_GROUP(gpio23),
++	BCM6328_GROUP(gpio24),
++	BCM6328_GROUP(gpio25),
++	BCM6328_GROUP(gpio26),
++	BCM6328_GROUP(gpio27),
++	BCM6328_GROUP(gpio28),
++	BCM6328_GROUP(gpio29),
++	BCM6328_GROUP(gpio30),
++	BCM6328_GROUP(gpio31),
++
++	BCM6328_GROUP(hsspi_cs1),
++	BCM6328_GROUP(usb_port1),
++};
++
++/* GPIO_MODE */
++static const char * const led_groups[] = {
++	"gpio0",
++	"gpio1",
++	"gpio2",
++	"gpio3",
++	"gpio4",
++	"gpio5",
++	"gpio6",
++	"gpio7",
++	"gpio8",
++	"gpio9",
++	"gpio10",
++	"gpio11",
++	"gpio12",
++	"gpio13",
++	"gpio14",
++	"gpio15",
++	"gpio16",
++	"gpio17",
++	"gpio18",
++	"gpio19",
++	"gpio20",
++	"gpio21",
++	"gpio22",
++	"gpio23",
++};
++
++/* PINMUX_SEL */
++static const char * const serial_led_data_groups[] = {
++	"gpio6",
++};
++
++static const char * const serial_led_clk_groups[] = {
++	"gpio7",
++};
++
++static const char * const inet_act_led_groups[] = {
++	"gpio11",
++};
++
++static const char * const pcie_clkreq_groups[] = {
++	"gpio16",
++};
++
++static const char * const ephy0_act_led_groups[] = {
++	"gpio25",
++};
++
++static const char * const ephy1_act_led_groups[] = {
++	"gpio26",
++};
++
++static const char * const ephy2_act_led_groups[] = {
++	"gpio27",
++};
++
++static const char * const ephy3_act_led_groups[] = {
++	"gpio28",
++};
++
++static const char * const hsspi_cs1_groups[] = {
++	"hsspi_cs1"
++};
++
++static const char * const usb_host_port_groups[] = {
++	"usb_port1",
++};
++
++static const char * const usb_device_port_groups[] = {
++	"usb_port1",
++};
++
++#define BCM6328_MODE_FUN(n)				\
++	{						\
++		.name = #n,				\
++		.groups = n##_groups,			\
++		.num_groups = ARRAY_SIZE(n##_groups),	\
++		.mode_val = 1,				\
++	}
++
++#define BCM6328_MUX_FUN(n, mux)				\
++	{						\
++		.name = #n,				\
++		.groups = n##_groups,			\
++		.num_groups = ARRAY_SIZE(n##_groups),	\
++		.mux_val = mux,				\
++	}
++
++static const struct bcm6328_function bcm6328_funcs[] = {
++	BCM6328_MODE_FUN(led),
++	BCM6328_MUX_FUN(serial_led_data, 2),
++	BCM6328_MUX_FUN(serial_led_clk, 2),
++	BCM6328_MUX_FUN(inet_act_led, 1),
++	BCM6328_MUX_FUN(pcie_clkreq, 2),
++	BCM6328_MUX_FUN(ephy0_act_led, 1),
++	BCM6328_MUX_FUN(ephy1_act_led, 1),
++	BCM6328_MUX_FUN(ephy2_act_led, 1),
++	BCM6328_MUX_FUN(ephy3_act_led, 1),
++	BCM6328_MUX_FUN(hsspi_cs1, 2),
++	BCM6328_MUX_FUN(usb_host_port, 1),
++	BCM6328_MUX_FUN(usb_device_port, 2),
++};
++
++static int bcm6328_pinctrl_get_group_count(struct pinctrl_dev *pctldev)
++{
++	return ARRAY_SIZE(bcm6328_groups);
++}
++
++static const char *bcm6328_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
++						  unsigned group)
++{
++	return bcm6328_groups[group].name;
++}
++
++static int bcm6328_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
++					  unsigned group, const unsigned **pins,
++					  unsigned *num_pins)
++{
++	*pins = bcm6328_groups[group].pins;
++	*num_pins = bcm6328_groups[group].num_pins;
++
++	return 0;
++}
++
++static int bcm6328_pinctrl_get_func_count(struct pinctrl_dev *pctldev)
++{
++	return ARRAY_SIZE(bcm6328_funcs);
++}
++
++static const char *bcm6328_pinctrl_get_func_name(struct pinctrl_dev *pctldev,
++						 unsigned selector)
++{
++	return bcm6328_funcs[selector].name;
++}
++
++static int bcm6328_pinctrl_get_groups(struct pinctrl_dev *pctldev,
++				      unsigned selector,
++				      const char * const **groups,
++				      unsigned * const num_groups)
++{
++	*groups = bcm6328_funcs[selector].groups;
++	*num_groups = bcm6328_funcs[selector].num_groups;
++
++	return 0;
++}
++
++static void bcm6328_rmw_mux(struct bcm6328_pinctrl *pctl, unsigned pin,
++			    u32 mode, u32 mux)
++{
++	unsigned long flags;
++	u32 reg;
++
++	spin_lock_irqsave(&pctl->lock, flags);
++	if (pin < 32) {
++		reg = __raw_readl(pctl->mode);
++		reg &= ~BIT(pin);
++		if (mode)
++			reg |= BIT(pin);
++		__raw_writel(reg, pctl->mode);
++	}
++
++	reg = __raw_readl(pctl->mux[pin / 16]);
++	reg &= ~(3UL << ((pin % 16) * 2));
++	reg |= mux << ((pin % 16) * 2);
++	__raw_writel(reg, pctl->mux[pin / 16]);
++
++	spin_unlock_irqrestore(&pctl->lock, flags);
++}
++
++static int bcm6328_pinctrl_set_mux(struct pinctrl_dev *pctldev,
++				   unsigned selector, unsigned group)
++{
++	struct bcm6328_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
++	const struct bcm6328_pingroup *grp = &bcm6328_groups[group];
++	const struct bcm6328_function *f = &bcm6328_funcs[selector];
++
++	bcm6328_rmw_mux(pctl, grp->pins[0], f->mode_val, f->mux_val);
++
++	return 0;
++}
++
++static int bcm6328_gpio_request_enable(struct pinctrl_dev *pctldev,
++				       struct pinctrl_gpio_range *range,
++				       unsigned offset)
++{
++	struct bcm6328_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
++
++	/* disable all functions using this pin */
++	bcm6328_rmw_mux(pctl, offset, 0, 0);
++
++	return 0;
++}
++
++static struct pinctrl_ops bcm6328_pctl_ops = {
++	.get_groups_count	= bcm6328_pinctrl_get_group_count,
++	.get_group_name		= bcm6328_pinctrl_get_group_name,
++	.get_group_pins		= bcm6328_pinctrl_get_group_pins,
++#ifdef CONFIG_OF
++	.dt_node_to_map		= pinconf_generic_dt_node_to_map_pin,
++	.dt_free_map		= pinctrl_utils_free_map,
++#endif
++};
++
++static struct pinmux_ops bcm6328_pmx_ops = {
++	.get_functions_count	= bcm6328_pinctrl_get_func_count,
++	.get_function_name	= bcm6328_pinctrl_get_func_name,
++	.get_function_groups	= bcm6328_pinctrl_get_groups,
++	.set_mux		= bcm6328_pinctrl_set_mux,
++	.gpio_request_enable	= bcm6328_gpio_request_enable,
++	.strict			= true,
++};
++
++static int bcm6328_pinctrl_probe(struct platform_device *pdev)
++{
++	struct bcm6328_pinctrl *pctl;
++	struct resource *res;
++	void __iomem *mode, *mux;
++
++	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mode");
++	mode = devm_ioremap_resource(&pdev->dev, res);
++	if (IS_ERR(mode))
++		return PTR_ERR(mode);
++
++	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mux");
++	mux = devm_ioremap_resource(&pdev->dev, res);
++	if (IS_ERR(mux))
++		return PTR_ERR(mux);
++
++	pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL);
++	if (!pctl)
++		return -ENOMEM;
++
++	spin_lock_init(&pctl->lock);
++
++	pctl->mode = mode;
++	pctl->mux[0] = mux + BCM6328_MUX_LO_REG;
++	pctl->mux[1] = mux + BCM6328_MUX_HI_REG;
++	pctl->mux[2] = mux + BCM6328_MUX_OTHER_REG;
++
++	pctl->desc.name = dev_name(&pdev->dev);
++	pctl->desc.owner = THIS_MODULE;
++	pctl->desc.pctlops = &bcm6328_pctl_ops;
++	pctl->desc.pmxops = &bcm6328_pmx_ops;
++
++	pctl->desc.npins = ARRAY_SIZE(bcm6328_pins);
++	pctl->desc.pins = bcm6328_pins;
++
++	platform_set_drvdata(pdev, pctl);
++
++	pctl->pctldev = bcm63xx_pinctrl_register(pdev, &pctl->desc, pctl,
++						 &pctl->gpio, BCM6328_NGPIO);
++	if (IS_ERR(pctl->pctldev))
++		return PTR_ERR(pctl->pctldev);
++
++	return 0;
++}
++
++static const struct of_device_id bcm6328_pinctrl_match[] = {
++	{ .compatible = "brcm,bcm6328-pinctrl", },
++	{ },
++};
++
++static struct platform_driver bcm6328_pinctrl_driver = {
++	.probe = bcm6328_pinctrl_probe,
++	.driver = {
++		.name = "bcm6328-pinctrl",
++		.of_match_table = bcm6328_pinctrl_match,
++	},
++};
++
++builtin_platform_driver(bcm6328_pinctrl_driver);
diff --git a/target/linux/brcm63xx/patches-4.4/133-Documentation-add-BCM6348-pincontroller-binding-docu.patch b/target/linux/brcm63xx/patches-4.4/133-Documentation-add-BCM6348-pincontroller-binding-docu.patch
new file mode 100644
index 0000000..6bac903
--- /dev/null
+++ b/target/linux/brcm63xx/patches-4.4/133-Documentation-add-BCM6348-pincontroller-binding-docu.patch
@@ -0,0 +1,49 @@
+From 962c46bf7f43df730e2d3698930e77958cc6b191 Mon Sep 17 00:00:00 2001
+From: Jonas Gorski <jonas.gorski at gmail.com>
+Date: Wed, 27 Jul 2016 11:35:45 +0200
+Subject: [PATCH 04/16] Documentation: add BCM6348 pincontroller binding
+ documentation
+
+Add binding documentation for the pincontrol core found in BCM6348 SoCs.
+
+Signed-off-by: Jonas Gorski <jonas.gorski at gmail.com>
+---
+ .../bindings/pinctrl/brcm,bcm6348-pinctrl.txt      | 32 ++++++++++++++++++++++
+ 1 file changed, 32 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6348-pinctrl.txt
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6348-pinctrl.txt
+@@ -0,0 +1,32 @@
++* Broadcom BCM6348 pin controller
++
++Required properties:
++- compatible: Must be "brcm,bcm6348-pinctrl".
++- reg: register Specifiers of dirout, dat, mode registers.
++- reg-names: Must be "dirout", "dat", "mode".
++- gpio-controller: Identifies this node as a GPIO controller.
++- #gpio-cells: Must be <2>.
++
++Example:
++
++pinctrl: pin-controller at fffe0080 {
++	compatible = "brcm,bcm6348-pinctrl";
++	reg = <0xfffe0080 0x8>,
++	      <0xfffe0088 0x8>,
++	      <0xfffe0098 0x4>;
++	reg-names = "dirout", "dat", "mode";
++
++	gpio-controller;
++	#gpio-cells = <2>;
++};
++
++Available pins/groups and functions:
++
++name		pins	functions
++-----------------------------------------------------------
++group0		32-36	ext_mii, utopia, diag
++group1		22-31	ext_ephy, mii_snoop, mii_pccard,
++			spi_master_uart, utopia, diag
++group2		16-21	pci, diag
++group3		8-15	ext_mii, utopia
++group4		0-7	ext_ephy, mii_snoop, legacy_led, diag
diff --git a/target/linux/brcm63xx/patches-4.4/134-pinctrl-add-a-pincontrol-driver-for-BCM6348.patch b/target/linux/brcm63xx/patches-4.4/134-pinctrl-add-a-pincontrol-driver-for-BCM6348.patch
new file mode 100644
index 0000000..19b8075
--- /dev/null
+++ b/target/linux/brcm63xx/patches-4.4/134-pinctrl-add-a-pincontrol-driver-for-BCM6348.patch
@@ -0,0 +1,432 @@
+From 45444cb631555e2dc16b95d779b10aa075c7482e Mon Sep 17 00:00:00 2001
+From: Jonas Gorski <jonas.gorski at gmail.com>
+Date: Fri, 24 Jun 2016 22:14:13 +0200
+Subject: [PATCH 05/16] pinctrl: add a pincontrol driver for BCM6348
+
+Add a pincotrol driver for BCM6348. BCM6348 allow muxing five groups of
+up to ten gpios into fourteen potential functions. It does not allow
+muxing individual pins. Some functions require more than one group to be
+muxed to the same function.
+
+Signed-off-by: Jonas Gorski <jonas.gorski at gmail.com>
+---
+ drivers/pinctrl/bcm63xx/Kconfig           |   7 +
+ drivers/pinctrl/bcm63xx/Makefile          |   1 +
+ drivers/pinctrl/bcm63xx/pinctrl-bcm6348.c | 392 ++++++++++++++++++++++++++++++
+ 3 files changed, 400 insertions(+)
+ create mode 100644 drivers/pinctrl/bcm63xx/pinctrl-bcm6348.c
+
+--- a/drivers/pinctrl/bcm63xx/Kconfig
++++ b/drivers/pinctrl/bcm63xx/Kconfig
+@@ -8,3 +8,10 @@ config PINCTRL_BCM6328
+ 	select PINCONF
+ 	select PINCTRL_BCM63XX
+ 	select GENERIC_PINCONF
++
++config PINCTRL_BCM6348
++	bool "BCM6348 pincontrol driver" if COMPILE_TEST
++	select PINMUX
++	select PINCONF
++	select PINCTRL_BCM63XX
++	select GENERIC_PINCONF
+--- a/drivers/pinctrl/bcm63xx/Makefile
++++ b/drivers/pinctrl/bcm63xx/Makefile
+@@ -1,2 +1,3 @@
+ obj-$(CONFIG_PINCTRL_BCM63XX)	+= pinctrl-bcm63xx.o
+ obj-$(CONFIG_PINCTRL_BCM6328)	+= pinctrl-bcm6328.o
++obj-$(CONFIG_PINCTRL_BCM6348)	+= pinctrl-bcm6348.o
+--- /dev/null
++++ b/drivers/pinctrl/bcm63xx/pinctrl-bcm6348.c
+@@ -0,0 +1,392 @@
++/*
++ * This file is subject to the terms and conditions of the GNU General Public
++ * License.  See the file "COPYING" in the main directory of this archive
++ * for more details.
++ *
++ * Copyright (C) 2016 Jonas Gorski <jonas.gorski at gmail.com>
++ */
++
++#include <linux/kernel.h>
++#include <linux/spinlock.h>
++#include <linux/bitops.h>
++#include <linux/gpio.h>
++#include <linux/of.h>
++#include <linux/of_gpio.h>
++#include <linux/slab.h>
++#include <linux/platform_device.h>
++
++#include <linux/pinctrl/machine.h>
++#include <linux/pinctrl/pinconf.h>
++#include <linux/pinctrl/pinconf-generic.h>
++#include <linux/pinctrl/pinmux.h>
++
++#include "../core.h"
++#include "../pinctrl-utils.h"
++
++#include "pinctrl-bcm63xx.h"
++
++#define BCM6348_NGPIO		37
++
++#define MAX_GROUP		4
++#define PINS_PER_GROUP		8
++#define PIN_TO_GROUP(pin)	(MAX_GROUP - ((pin) / PINS_PER_GROUP))
++#define GROUP_SHIFT(pin)	(PIN_TO_GROUP(pin) * 4)
++#define GROUP_MASK(pin)		(0xf << GROUP_SHIFT(pin))
++
++struct bcm6348_pingroup {
++	const char *name;
++	const unsigned * const pins;
++	const unsigned num_pins;
++};
++
++struct bcm6348_function {
++	const char *name;
++	const char * const *groups;
++	const unsigned num_groups;
++	unsigned int value;
++};
++
++struct bcm6348_pinctrl {
++	struct pinctrl_dev *pctldev;
++	struct pinctrl_desc desc;
++
++	void __iomem *mode;
++
++	/* register access lock */
++	spinlock_t lock;
++
++	struct gpio_chip gpio[2];
++};
++
++#define BCM6348_PIN(a, b, group)		\
++	{					\
++		.number = a,			\
++		.name = b,			\
++		.drv_data = (void *)(group),	\
++	}
++
++static const struct pinctrl_pin_desc bcm6348_pins[] = {
++	BCM6348_PIN(0, "gpio0", 4),
++	BCM6348_PIN(1, "gpio1", 4),
++	BCM6348_PIN(2, "gpio2", 4),
++	BCM6348_PIN(3, "gpio3", 4),
++	BCM6348_PIN(4, "gpio4", 4),
++	BCM6348_PIN(5, "gpio5", 4),
++	BCM6348_PIN(6, "gpio6", 4),
++	BCM6348_PIN(7, "gpio7", 4),
++	BCM6348_PIN(8, "gpio8", 3),
++	BCM6348_PIN(9, "gpio9", 3),
++	BCM6348_PIN(10, "gpio10", 3),
++	BCM6348_PIN(11, "gpio11", 3),
++	BCM6348_PIN(12, "gpio12", 3),
++	BCM6348_PIN(13, "gpio13", 3),
++	BCM6348_PIN(14, "gpio14", 3),
++	BCM6348_PIN(15, "gpio15", 3),
++	BCM6348_PIN(16, "gpio16", 2),
++	BCM6348_PIN(17, "gpio17", 2),
++	BCM6348_PIN(18, "gpio18", 2),
++	BCM6348_PIN(19, "gpio19", 2),
++	BCM6348_PIN(20, "gpio20", 2),
++	BCM6348_PIN(21, "gpio21", 2),
++	BCM6348_PIN(22, "gpio22", 1),
++	BCM6348_PIN(23, "gpio23", 1),
++	BCM6348_PIN(24, "gpio24", 1),
++	BCM6348_PIN(25, "gpio25", 1),
++	BCM6348_PIN(26, "gpio26", 1),
++	BCM6348_PIN(27, "gpio27", 1),
++	BCM6348_PIN(28, "gpio28", 1),
++	BCM6348_PIN(29, "gpio29", 1),
++	BCM6348_PIN(30, "gpio30", 1),
++	BCM6348_PIN(31, "gpio31", 1),
++	BCM6348_PIN(32, "gpio32", 0),
++	BCM6348_PIN(33, "gpio33", 0),
++	BCM6348_PIN(34, "gpio34", 0),
++	BCM6348_PIN(35, "gpio35", 0),
++	BCM6348_PIN(36, "gpio36", 0),
++};
++
++enum bcm6348_muxes {
++	BCM6348_MUX_GPIO = 0,
++	BCM6348_MUX_EXT_EPHY,
++	BCM6348_MUX_MII_SNOOP,
++	BCM6348_MUX_LEGACY_LED,
++	BCM6348_MUX_MII_PCCARD,
++	BCM6348_MUX_PCI,
++	BCM6348_MUX_SPI_MASTER_UART,
++	BCM6348_MUX_EXT_MII,
++	BCM6348_MUX_UTOPIA,
++	BCM6348_MUX_DIAG,
++};
++
++static unsigned group0_pins[] = {
++	32, 33, 34, 35, 36,
++};
++
++static unsigned group1_pins[] = {
++	22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
++};
++
++static unsigned group2_pins[] = {
++	16, 17, 18, 19, 20, 21,
++};
++
++static unsigned group3_pins[] = {
++	8, 9, 10, 11, 12, 13, 14, 15,
++};
++
++static unsigned group4_pins[] = {
++	0, 1, 2, 3, 4, 5, 6, 7,
++};
++
++#define BCM6348_GROUP(n)				\
++	{						\
++		.name = #n,				\
++		.pins = n##_pins,			\
++		.num_pins = ARRAY_SIZE(n##_pins),	\
++	} \
++
++static struct bcm6348_pingroup bcm6348_groups[] = {
++	BCM6348_GROUP(group0),
++	BCM6348_GROUP(group1),
++	BCM6348_GROUP(group2),
++	BCM6348_GROUP(group3),
++	BCM6348_GROUP(group4),
++};
++
++static const char * const ext_mii_groups[] = {
++	"group0",
++	"group3",
++};
++
++static const char * const ext_ephy_groups[] = {
++	"group1",
++	"group4"
++};
++
++static const char * const mii_snoop_groups[] = {
++	"group1",
++	"group4",
++};
++
++static const char * const legacy_led_groups[] = {
++	"group4",
++};
++
++static const char * const mii_pccard_groups[] = {
++	"group1",
++};
++
++static const char * const pci_groups[] = {
++	"group2",
++};
++
++static const char * const spi_master_uart_groups[] = {
++	"group1",
++};
++
++static const char * const utopia_groups[] = {
++	"group0",
++	"group1",
++	"group3",
++};
++
++static const char * const diag_groups[] = {
++	"group0",
++	"group1",
++	"group2",
++	"group4",
++};
++
++#define BCM6348_FUN(n, f)				\
++	{						\
++		.name = #n,				\
++		.groups = n##_groups,			\
++		.num_groups = ARRAY_SIZE(n##_groups),	\
++		.value = BCM6348_MUX_##f,		\
++	}
++
++static const struct bcm6348_function bcm6348_funcs[] = {
++	BCM6348_FUN(ext_mii, EXT_MII),
++	BCM6348_FUN(ext_ephy, EXT_EPHY),
++	BCM6348_FUN(mii_snoop, MII_SNOOP),
++	BCM6348_FUN(legacy_led, LEGACY_LED),
++	BCM6348_FUN(mii_pccard, MII_PCCARD),
++	BCM6348_FUN(pci, PCI),
++	BCM6348_FUN(spi_master_uart, SPI_MASTER_UART),
++	BCM6348_FUN(utopia, UTOPIA),
++	BCM6348_FUN(diag, DIAG),
++};
++
++static int bcm6348_pinctrl_get_group_count(struct pinctrl_dev *pctldev)
++{
++	return ARRAY_SIZE(bcm6348_groups);
++}
++
++static const char *bcm6348_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
++						  unsigned group)
++{
++	return bcm6348_groups[group].name;
++}
++
++static int bcm6348_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
++					  unsigned group, const unsigned **pins,
++					  unsigned *num_pins)
++{
++	*pins = bcm6348_groups[group].pins;
++	*num_pins = bcm6348_groups[group].num_pins;
++
++	return 0;
++}
++
++static int bcm6348_pinctrl_get_func_count(struct pinctrl_dev *pctldev)
++{
++	return ARRAY_SIZE(bcm6348_funcs);
++}
++
++static const char *bcm6348_pinctrl_get_func_name(struct pinctrl_dev *pctldev,
++						 unsigned selector)
++{
++	return bcm6348_funcs[selector].name;
++}
++
++static int bcm6348_pinctrl_get_groups(struct pinctrl_dev *pctldev,
++				      unsigned selector,
++				      const char * const **groups,
++				      unsigned * const num_groups)
++{
++	*groups = bcm6348_funcs[selector].groups;
++	*num_groups = bcm6348_funcs[selector].num_groups;
++
++	return 0;
++}
++
++static void bcm6348_rmw_mux(struct bcm6348_pinctrl *pctl, u32 mask, u32 val)
++{
++	unsigned long flags;
++	u32 reg;
++
++	spin_lock_irqsave(&pctl->lock, flags);
++
++	reg = __raw_readl(pctl->mode);
++	reg &= ~mask;
++	reg |= val & mask;
++	__raw_writel(reg, pctl->mode);
++
++	spin_unlock_irqrestore(&pctl->lock, flags);
++}
++
++static int bcm6348_pinctrl_set_mux(struct pinctrl_dev *pctldev,
++				   unsigned selector, unsigned group)
++{
++	struct bcm6348_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
++	const struct bcm6348_pingroup *grp = &bcm6348_groups[group];
++	const struct bcm6348_function *f = &bcm6348_funcs[selector];
++	u32 group_num, mask, val;
++
++	/*
++	 * pins n..(n+7) share the same group, so we only need to look at
++	 * the first pin.
++	 */
++	group_num = (unsigned long)bcm6348_pins[grp->pins[0]].drv_data;
++	mask = GROUP_MASK(group_num);
++	val = f->value << GROUP_SHIFT(group_num);
++
++	bcm6348_rmw_mux(pctl, mask, val);
++
++	return 0;
++}
++
++static int bcm6348_gpio_request_enable(struct pinctrl_dev *pctldev,
++				       struct pinctrl_gpio_range *range,
++				       unsigned offset)
++{
++	struct bcm6348_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
++	struct pin_desc *desc;
++	u32 mask;
++
++	/* don't reconfigure if already muxed */
++	desc = pin_desc_get(pctldev, offset);
++	if (desc->mux_usecount)
++		return 0;
++
++	mask = GROUP_MASK(offset);
++
++	/* disable all functions using this pin */
++	bcm6348_rmw_mux(pctl, mask, 0);
++
++	return 0;
++}
++
++static struct pinctrl_ops bcm6348_pctl_ops = {
++	.get_groups_count	= bcm6348_pinctrl_get_group_count,
++	.get_group_name		= bcm6348_pinctrl_get_group_name,
++	.get_group_pins		= bcm6348_pinctrl_get_group_pins,
++#ifdef CONFIG_OF
++	.dt_node_to_map		= pinconf_generic_dt_node_to_map_pin,
++	.dt_free_map		= pinctrl_utils_free_map,
++#endif
++};
++
++static struct pinmux_ops bcm6348_pmx_ops = {
++	.get_functions_count	= bcm6348_pinctrl_get_func_count,
++	.get_function_name	= bcm6348_pinctrl_get_func_name,
++	.get_function_groups	= bcm6348_pinctrl_get_groups,
++	.set_mux		= bcm6348_pinctrl_set_mux,
++	.gpio_request_enable	= bcm6348_gpio_request_enable,
++	.strict			= true,
++};
++
++static int bcm6348_pinctrl_probe(struct platform_device *pdev)
++{
++	struct bcm6348_pinctrl *pctl;
++	struct resource *res;
++	void __iomem *mode;
++
++	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mode");
++	mode = devm_ioremap_resource(&pdev->dev, res);
++	if (IS_ERR(mode))
++		return PTR_ERR(mode);
++
++	pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL);
++	if (!pctl)
++		return -ENOMEM;
++
++	spin_lock_init(&pctl->lock);
++
++	pctl->mode = mode;
++
++	/* disable all muxes by default */
++	__raw_writel(0, pctl->mode);
++
++	pctl->desc.name = dev_name(&pdev->dev);
++	pctl->desc.owner = THIS_MODULE;
++	pctl->desc.pctlops = &bcm6348_pctl_ops;
++	pctl->desc.pmxops = &bcm6348_pmx_ops;
++
++	pctl->desc.npins = ARRAY_SIZE(bcm6348_pins);
++	pctl->desc.pins = bcm6348_pins;
++
++	platform_set_drvdata(pdev, pctl);
++
++	pctl->pctldev = bcm63xx_pinctrl_register(pdev, &pctl->desc, pctl,
++						 pctl->gpio, BCM6348_NGPIO);
++	if (IS_ERR(pctl->pctldev))
++		return PTR_ERR(pctl->pctldev);
++
++	return 0;
++}
++
++static const struct of_device_id bcm6348_pinctrl_match[] = {
++	{ .compatible = "brcm,bcm6348-pinctrl", },
++	{ },
++};
++
++static struct platform_driver bcm6348_pinctrl_driver = {
++	.probe = bcm6348_pinctrl_probe,
++	.driver = {
++		.name = "bcm6348-pinctrl",
++		.of_match_table = bcm6348_pinctrl_match,
++	},
++};
++
++builtin_platform_driver(bcm6348_pinctrl_driver);
diff --git a/target/linux/brcm63xx/patches-4.4/135-Documentation-add-BCM6358-pincontroller-binding-docu.patch b/target/linux/brcm63xx/patches-4.4/135-Documentation-add-BCM6358-pincontroller-binding-docu.patch
new file mode 100644
index 0000000..e8a7479
--- /dev/null
+++ b/target/linux/brcm63xx/patches-4.4/135-Documentation-add-BCM6358-pincontroller-binding-docu.patch
@@ -0,0 +1,61 @@
+From c7c8fa7f5b5ee9bea751fa7bdae8ff4acde8f26e Mon Sep 17 00:00:00 2001
+From: Jonas Gorski <jonas.gorski at gmail.com>
+Date: Wed, 27 Jul 2016 11:36:00 +0200
+Subject: [PATCH 06/16] Documentation: add BCM6358 pincontroller binding
+ documentation
+
+Add binding documentation for the pincontrol core found in BCM6358 SoCs.
+
+Signed-off-by: Jonas Gorski <jonas.gorski at gmail.com>
+---
+ .../bindings/pinctrl/brcm,bcm6358-pinctrl.txt      | 44 ++++++++++++++++++++++
+ 1 file changed, 44 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6358-pinctrl.txt
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6358-pinctrl.txt
+@@ -0,0 +1,44 @@
++* Broadcom BCM6358 pin controller
++
++Required properties:
++- compatible: Must be "brcm,bcm6358-pinctrl".
++- reg: Register specifiers of dirout, dat registers.
++- reg-names: Must be "dirout", "dat".
++- brcm,gpiomode: Phandle to the shared gpiomode register.
++- gpio-controller: Identifies this node as a gpio-controller.
++- #gpio-cells: Must be <2>.
++
++Example:
++
++pinctrl: pin-controller at fffe0080 {
++	compatible = "brcm,bcm6358-pinctrl";
++	reg = <0xfffe0080 0x8>,
++	      <0xfffe0088 0x8>,
++	      <0xfffe0098 0x4>;
++	reg-names = "dirout", "dat";
++	brcm,gpiomode = <&gpiomode>;
++
++	gpio-controller;
++	#gpio-cells = <2>;
++};
++
++gpiomode: syscon at fffe0098 {
++	compatible = "brcm,bcm6358-gpiomode", "syscon";
++	reg = <0xfffe0098 0x4>;
++	native-endian;
++};
++
++Available pins/groups and functions:
++
++name		pins		functions
++-----------------------------------------------------------
++ebi_cs_grp	30-31		ebi_cs
++uart1_grp	28-31		uart1
++spi_cs_grp	32-33		spi_cs
++async_modem_grp	12-15		async_modem
++legacy_led_grp	9-15		legacy_led
++serial_led_grp	6-7		serial_led
++led_grp		0-3		led
++utopia_grp	12-15, 22-31	utopia
++pwm_syn_clk_grp	8		pwm_syn_clk
++sys_irq_grp	5		sys_irq
diff --git a/target/linux/brcm63xx/patches-4.4/136-pinctrl-add-a-pincontrol-driver-for-BCM6358.patch b/target/linux/brcm63xx/patches-4.4/136-pinctrl-add-a-pincontrol-driver-for-BCM6358.patch
new file mode 100644
index 0000000..87dc741
--- /dev/null
+++ b/target/linux/brcm63xx/patches-4.4/136-pinctrl-add-a-pincontrol-driver-for-BCM6358.patch
@@ -0,0 +1,436 @@
+From fb00ef462f3f8b70ea8902151cc72810fe90b999 Mon Sep 17 00:00:00 2001
+From: Jonas Gorski <jonas.gorski at gmail.com>
+Date: Fri, 24 Jun 2016 22:16:01 +0200
+Subject: [PATCH 07/16] pinctrl: add a pincontrol driver for BCM6358
+
+Add a pincotrol driver for BCM6358. BCM6358 allow overlaying different
+functions onto the GPIO pins. It does not support configuring individual
+pins but only whole groups. These groups may overlap, and still require
+the directions to be set correctly in the GPIO register. In addition the
+functions register controls other, not directly mux related functions.
+
+Signed-off-by: Jonas Gorski <jonas.gorski at gmail.com>
+---
+ drivers/pinctrl/bcm63xx/Kconfig           |   8 +
+ drivers/pinctrl/bcm63xx/Makefile          |   1 +
+ drivers/pinctrl/bcm63xx/pinctrl-bcm6358.c | 393 ++++++++++++++++++++++++++++++
+ 3 files changed, 402 insertions(+)
+ create mode 100644 drivers/pinctrl/bcm63xx/pinctrl-bcm6358.c
+
+--- a/drivers/pinctrl/bcm63xx/Kconfig
++++ b/drivers/pinctrl/bcm63xx/Kconfig
+@@ -15,3 +15,11 @@ config PINCTRL_BCM6348
+ 	select PINCONF
+ 	select PINCTRL_BCM63XX
+ 	select GENERIC_PINCONF
++
++config PINCTRL_BCM6358
++	bool "BCM6358 pincontrol driver" if COMPILE_TEST
++	select PINMUX
++	select PINCONF
++	select PINCTRL_BCM63XX
++	select GENERIC_PINCONF
++	select MFD_SYSCON
+--- a/drivers/pinctrl/bcm63xx/Makefile
++++ b/drivers/pinctrl/bcm63xx/Makefile
+@@ -1,3 +1,4 @@
+ obj-$(CONFIG_PINCTRL_BCM63XX)	+= pinctrl-bcm63xx.o
+ obj-$(CONFIG_PINCTRL_BCM6328)	+= pinctrl-bcm6328.o
+ obj-$(CONFIG_PINCTRL_BCM6348)	+= pinctrl-bcm6348.o
++obj-$(CONFIG_PINCTRL_BCM6358)	+= pinctrl-bcm6358.o
+--- /dev/null
++++ b/drivers/pinctrl/bcm63xx/pinctrl-bcm6358.c
+@@ -0,0 +1,393 @@
++/*
++ * This file is subject to the terms and conditions of the GNU General Public
++ * License.  See the file "COPYING" in the main directory of this archive
++ * for more details.
++ *
++ * Copyright (C) 2016 Jonas Gorski <jonas.gorski at gmail.com>
++ */
++
++#include <linux/kernel.h>
++#include <linux/bitops.h>
++#include <linux/gpio.h>
++#include <linux/gpio/driver.h>
++#include <linux/mfd/syscon.h>
++#include <linux/of.h>
++#include <linux/of_gpio.h>
++#include <linux/of_address.h>
++#include <linux/slab.h>
++#include <linux/regmap.h>
++#include <linux/platform_device.h>
++
++#include <linux/pinctrl/pinconf.h>
++#include <linux/pinctrl/pinconf-generic.h>
++#include <linux/pinctrl/pinmux.h>
++#include <linux/pinctrl/machine.h>
++
++#include "../core.h"
++#include "../pinctrl-utils.h"
++
++#include "pinctrl-bcm63xx.h"
++
++/* GPIO_MODE register */
++#define BCM6358_MODE_MUX_NONE		0
++
++/* overlays on gpio pins */
++#define BCM6358_MODE_MUX_EBI_CS		BIT(5)
++#define BCM6358_MODE_MUX_UART1		BIT(6)
++#define BCM6358_MODE_MUX_SPI_CS		BIT(7)
++#define BCM6358_MODE_MUX_ASYNC_MODEM	BIT(8)
++#define BCM6358_MODE_MUX_LEGACY_LED	BIT(9)
++#define BCM6358_MODE_MUX_SERIAL_LED	BIT(10)
++#define BCM6358_MODE_MUX_LED		BIT(11)
++#define BCM6358_MODE_MUX_UTOPIA		BIT(12)
++#define BCM6358_MODE_MUX_CLKRST		BIT(13)
++#define BCM6358_MODE_MUX_PWM_SYN_CLK	BIT(14)
++#define BCM6358_MODE_MUX_SYS_IRQ	BIT(15)
++
++#define BCM6358_NGPIO			40
++
++struct bcm6358_pingroup {
++	const char *name;
++	const unsigned * const pins;
++	const unsigned num_pins;
++
++	const u16 mode_val;
++
++	/* non-GPIO function muxes require the gpio direction to be set */
++	const u16 direction;
++};
++
++struct bcm6358_function {
++	const char *name;
++	const char * const *groups;
++	const unsigned num_groups;
++};
++
++struct bcm6358_pinctrl {
++	struct device *dev;
++	struct pinctrl_dev *pctldev;
++	struct pinctrl_desc desc;
++
++	struct regmap_field *overlays;
++
++	struct gpio_chip gpio[2];
++};
++
++#define BCM6358_GPIO_PIN(a, b, bit1, bit2, bit3)		\
++	{							\
++		.number = a,					\
++		.name = b,					\
++		.drv_data = (void *)(BCM6358_MODE_MUX_##bit1 |	\
++				     BCM6358_MODE_MUX_##bit2 |	\
++				     BCM6358_MODE_MUX_##bit3),	\
++	}
++
++static const struct pinctrl_pin_desc bcm6358_pins[] = {
++	BCM6358_GPIO_PIN(0, "gpio0", LED, NONE, NONE),
++	BCM6358_GPIO_PIN(1, "gpio1", LED, NONE, NONE),
++	BCM6358_GPIO_PIN(2, "gpio2", LED, NONE, NONE),
++	BCM6358_GPIO_PIN(3, "gpio3", LED, NONE, NONE),
++	PINCTRL_PIN(4, "gpio4"),
++	BCM6358_GPIO_PIN(5, "gpio5", SYS_IRQ, NONE, NONE),
++	BCM6358_GPIO_PIN(6, "gpio6", SERIAL_LED, NONE, NONE),
++	BCM6358_GPIO_PIN(7, "gpio7", SERIAL_LED, NONE, NONE),
++	BCM6358_GPIO_PIN(8, "gpio8", PWM_SYN_CLK, NONE, NONE),
++	BCM6358_GPIO_PIN(9, "gpio09", LEGACY_LED, NONE, NONE),
++	BCM6358_GPIO_PIN(10, "gpio10", LEGACY_LED, NONE, NONE),
++	BCM6358_GPIO_PIN(11, "gpio11", LEGACY_LED, NONE, NONE),
++	BCM6358_GPIO_PIN(12, "gpio12", LEGACY_LED, ASYNC_MODEM, UTOPIA),
++	BCM6358_GPIO_PIN(13, "gpio13", LEGACY_LED, ASYNC_MODEM, UTOPIA),
++	BCM6358_GPIO_PIN(14, "gpio14", LEGACY_LED, ASYNC_MODEM, UTOPIA),
++	BCM6358_GPIO_PIN(15, "gpio15", LEGACY_LED, ASYNC_MODEM, UTOPIA),
++	PINCTRL_PIN(16, "gpio16"),
++	PINCTRL_PIN(17, "gpio17"),
++	PINCTRL_PIN(18, "gpio18"),
++	PINCTRL_PIN(19, "gpio19"),
++	PINCTRL_PIN(20, "gpio20"),
++	PINCTRL_PIN(21, "gpio21"),
++	BCM6358_GPIO_PIN(22, "gpio22", UTOPIA, NONE, NONE),
++	BCM6358_GPIO_PIN(23, "gpio23", UTOPIA, NONE, NONE),
++	BCM6358_GPIO_PIN(24, "gpio24", UTOPIA, NONE, NONE),
++	BCM6358_GPIO_PIN(25, "gpio25", UTOPIA, NONE, NONE),
++	BCM6358_GPIO_PIN(26, "gpio26", UTOPIA, NONE, NONE),
++	BCM6358_GPIO_PIN(27, "gpio27", UTOPIA, NONE, NONE),
++	BCM6358_GPIO_PIN(28, "gpio28", UTOPIA, UART1, NONE),
++	BCM6358_GPIO_PIN(29, "gpio29", UTOPIA, UART1, NONE),
++	BCM6358_GPIO_PIN(30, "gpio30", UTOPIA, UART1, EBI_CS),
++	BCM6358_GPIO_PIN(31, "gpio31", UTOPIA, UART1, EBI_CS),
++	BCM6358_GPIO_PIN(32, "gpio32", SPI_CS, NONE, NONE),
++	BCM6358_GPIO_PIN(33, "gpio33", SPI_CS, NONE, NONE),
++	PINCTRL_PIN(34, "gpio34"),
++	PINCTRL_PIN(35, "gpio35"),
++	PINCTRL_PIN(36, "gpio36"),
++	PINCTRL_PIN(37, "gpio37"),
++	PINCTRL_PIN(38, "gpio38"),
++	PINCTRL_PIN(39, "gpio39"),
++};
++
++static unsigned ebi_cs_grp_pins[] = { 30, 31 };
++
++static unsigned uart1_grp_pins[] = { 28, 29, 30, 31 };
++
++static unsigned spi_cs_grp_pins[] = { 32, 33 };
++
++static unsigned async_modem_grp_pins[] = { 12, 13, 14, 15 };
++
++static unsigned serial_led_grp_pins[] = { 6, 7 };
++
++static unsigned legacy_led_grp_pins[] = { 9, 10, 11, 12, 13, 14, 15 };
++
++static unsigned led_grp_pins[] = { 0, 1, 2, 3 };
++
++static unsigned utopia_grp_pins[] = {
++	12, 13, 14, 15, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
++};
++
++static unsigned pwm_syn_clk_grp_pins[] = { 8 };
++
++static unsigned sys_irq_grp_pins[] = { 5 };
++
++#define BCM6358_GPIO_MUX_GROUP(n, bit, dir)			\
++	{							\
++		.name = #n,					\
++		.pins = n##_pins,				\
++		.num_pins = ARRAY_SIZE(n##_pins),		\
++		.mode_val = BCM6358_MODE_MUX_##bit,		\
++		.direction = dir,				\
++	}
++
++static const struct bcm6358_pingroup bcm6358_groups[] = {
++	BCM6358_GPIO_MUX_GROUP(ebi_cs_grp, EBI_CS, 0x3),
++	BCM6358_GPIO_MUX_GROUP(uart1_grp, UART1, 0x2),
++	BCM6358_GPIO_MUX_GROUP(spi_cs_grp, SPI_CS, 0x6),
++	BCM6358_GPIO_MUX_GROUP(async_modem_grp, ASYNC_MODEM, 0x6),
++	BCM6358_GPIO_MUX_GROUP(legacy_led_grp, LEGACY_LED, 0x7f),
++	BCM6358_GPIO_MUX_GROUP(serial_led_grp, SERIAL_LED, 0x3),
++	BCM6358_GPIO_MUX_GROUP(led_grp, LED, 0xf),
++	BCM6358_GPIO_MUX_GROUP(utopia_grp, UTOPIA, 0x000f),
++	BCM6358_GPIO_MUX_GROUP(pwm_syn_clk_grp, PWM_SYN_CLK, 0x1),
++	BCM6358_GPIO_MUX_GROUP(sys_irq_grp, SYS_IRQ, 0x1),
++};
++
++static const char * const ebi_cs_groups[] = {
++	"ebi_cs_grp"
++};
++
++static const char * const uart1_groups[] = {
++	"uart1_grp"
++};
++
++static const char * const spi_cs_2_3_groups[] = {
++	"spi_cs_2_3_grp"
++};
++
++static const char * const async_modem_groups[] = {
++	"async_modem_grp"
++};
++
++static const char * const legacy_led_groups[] = {
++	"legacy_led_grp",
++};
++
++static const char * const serial_led_groups[] = {
++	"serial_led_grp",
++};
++
++static const char * const led_groups[] = {
++	"led_grp",
++};
++
++static const char * const clkrst_groups[] = {
++	"clkrst_grp",
++};
++
++static const char * const pwm_syn_clk_groups[] = {
++	"pwm_syn_clk_grp",
++};
++
++static const char * const sys_irq_groups[] = {
++	"sys_irq_grp",
++};
++
++#define BCM6358_FUN(n)					\
++	{						\
++		.name = #n,				\
++		.groups = n##_groups,			\
++		.num_groups = ARRAY_SIZE(n##_groups),	\
++	}
++
++static const struct bcm6358_function bcm6358_funcs[] = {
++	BCM6358_FUN(ebi_cs),
++	BCM6358_FUN(uart1),
++	BCM6358_FUN(spi_cs_2_3),
++	BCM6358_FUN(async_modem),
++	BCM6358_FUN(legacy_led),
++	BCM6358_FUN(serial_led),
++	BCM6358_FUN(led),
++	BCM6358_FUN(clkrst),
++	BCM6358_FUN(pwm_syn_clk),
++	BCM6358_FUN(sys_irq),
++};
++
++static int bcm6358_pinctrl_get_group_count(struct pinctrl_dev *pctldev)
++{
++	return ARRAY_SIZE(bcm6358_groups);
++}
++
++static const char *bcm6358_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
++						  unsigned group)
++{
++	return bcm6358_groups[group].name;
++}
++
++static int bcm6358_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
++					  unsigned group, const unsigned **pins,
++					  unsigned *num_pins)
++{
++	*pins = bcm6358_groups[group].pins;
++	*num_pins = bcm6358_groups[group].num_pins;
++
++	return 0;
++}
++
++static int bcm6358_pinctrl_get_func_count(struct pinctrl_dev *pctldev)
++{
++	return ARRAY_SIZE(bcm6358_funcs);
++}
++
++static const char *bcm6358_pinctrl_get_func_name(struct pinctrl_dev *pctldev,
++						 unsigned selector)
++{
++	return bcm6358_funcs[selector].name;
++}
++
++static int bcm6358_pinctrl_get_groups(struct pinctrl_dev *pctldev,
++				      unsigned selector,
++				      const char * const **groups,
++				      unsigned * const num_groups)
++{
++	*groups = bcm6358_funcs[selector].groups;
++	*num_groups = bcm6358_funcs[selector].num_groups;
++
++	return 0;
++}
++
++static int bcm6358_pinctrl_set_mux(struct pinctrl_dev *pctldev,
++				   unsigned selector, unsigned group)
++{
++	struct bcm6358_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
++	const struct bcm6358_pingroup *grp = &bcm6358_groups[group];
++	u32 val = grp->mode_val;
++	u32 mask = val;
++	unsigned pin;
++
++	for (pin = 0; pin < grp->num_pins; pin++)
++		mask |= (unsigned long)bcm6358_pins[pin].drv_data;
++
++	regmap_field_update_bits(pctl->overlays, mask, val);
++
++	for (pin = 0; pin < grp->num_pins; pin++) {
++		int hw_gpio = bcm6358_pins[pin].number;
++		struct gpio_chip *gc = &pctl->gpio[hw_gpio / 32];
++
++		if (grp->direction & BIT(pin))
++			gc->direction_output(gc, hw_gpio % 32, 0);
++		else
++			gc->direction_input(gc, hw_gpio % 32);
++	}
++
++	return 0;
++}
++
++static int bcm6358_gpio_request_enable(struct pinctrl_dev *pctldev,
++				       struct pinctrl_gpio_range *range,
++				       unsigned offset)
++{
++	struct bcm6358_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
++	u32 mask;
++
++	mask = (unsigned long)bcm6358_pins[offset].drv_data;
++	if (!mask)
++		return 0;
++
++	/* disable all functions using this pin */
++	return regmap_field_update_bits(pctl->overlays, mask, 0);
++}
++
++static struct pinctrl_ops bcm6358_pctl_ops = {
++	.get_groups_count	= bcm6358_pinctrl_get_group_count,
++	.get_group_name		= bcm6358_pinctrl_get_group_name,
++	.get_group_pins		= bcm6358_pinctrl_get_group_pins,
++#ifdef CONFIG_OF
++	.dt_node_to_map		= pinconf_generic_dt_node_to_map_pin,
++	.dt_free_map		= pinctrl_utils_free_map,
++#endif
++};
++
++static struct pinmux_ops bcm6358_pmx_ops = {
++	.get_functions_count	= bcm6358_pinctrl_get_func_count,
++	.get_function_name	= bcm6358_pinctrl_get_func_name,
++	.get_function_groups	= bcm6358_pinctrl_get_groups,
++	.set_mux		= bcm6358_pinctrl_set_mux,
++	.gpio_request_enable	= bcm6358_gpio_request_enable,
++	.strict			= true,
++};
++
++static int bcm6358_pinctrl_probe(struct platform_device *pdev)
++{
++	struct bcm6358_pinctrl *pctl;
++	struct regmap *mode;
++	struct reg_field overlays = REG_FIELD(0, 0, 15);
++
++	if (pdev->dev.of_node)
++		mode = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
++						       "brcm,gpiomode");
++	else
++		mode = syscon_regmap_lookup_by_pdevname("syscon.fffe0098");
++
++	if (IS_ERR(mode))
++		return PTR_ERR(mode);
++
++	pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL);
++	if (!pctl)
++		return -ENOMEM;
++
++	pctl->overlays = devm_regmap_field_alloc(&pdev->dev, mode, overlays);
++	if (IS_ERR(pctl->overlays))
++		return PTR_ERR(pctl->overlays);
++
++	/* disable all muxes by default */
++	regmap_field_write(pctl->overlays, 0);
++
++	pctl->desc.name = dev_name(&pdev->dev);
++	pctl->desc.owner = THIS_MODULE;
++	pctl->desc.pctlops = &bcm6358_pctl_ops;
++	pctl->desc.pmxops = &bcm6358_pmx_ops;
++
++	pctl->desc.npins = ARRAY_SIZE(bcm6358_pins);
++	pctl->desc.pins = bcm6358_pins;
++
++	platform_set_drvdata(pdev, pctl);
++
++	pctl->pctldev = bcm63xx_pinctrl_register(pdev, &pctl->desc, pctl,
++						 pctl->gpio, BCM6358_NGPIO);
++	if (IS_ERR(pctl->pctldev))
++		return PTR_ERR(pctl->pctldev);
++
++	return 0;
++}
++
++static const struct of_device_id bcm6358_pinctrl_match[] = {
++	{ .compatible = "brcm,bcm6358-pinctrl", },
++	{ },
++};
++
++static struct platform_driver bcm6358_pinctrl_driver = {
++	.probe = bcm6358_pinctrl_probe,
++	.driver = {
++		.name = "bcm6358-pinctrl",
++		.of_match_table = bcm6358_pinctrl_match,
++	},
++};
++
++builtin_platform_driver(bcm6358_pinctrl_driver);
diff --git a/target/linux/brcm63xx/patches-4.4/137-Documentation-add-BCM6362-pincontroller-binding-docu.patch b/target/linux/brcm63xx/patches-4.4/137-Documentation-add-BCM6362-pincontroller-binding-docu.patch
new file mode 100644
index 0000000..9fc424c
--- /dev/null
+++ b/target/linux/brcm63xx/patches-4.4/137-Documentation-add-BCM6362-pincontroller-binding-docu.patch
@@ -0,0 +1,96 @@
+From ba03ea8ada2ca71c9095d96a1e4085c2c5cf0e69 Mon Sep 17 00:00:00 2001
+From: Jonas Gorski <jonas.gorski at gmail.com>
+Date: Wed, 27 Jul 2016 11:36:18 +0200
+Subject: [PATCH 08/16] Documentation: add BCM6362 pincontroller binding
+ documentation
+
+Add binding documentation for the pincontrol core found in BCM6362 SoCs.
+
+Signed-off-by: Jonas Gorski <jonas.gorski at gmail.com>
+---
+ .../bindings/pinctrl/brcm,bcm6362-pinctrl.txt      | 79 ++++++++++++++++++++++
+ 1 file changed, 79 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6362-pinctrl.txt
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6362-pinctrl.txt
+@@ -0,0 +1,79 @@
++* Broadcom BCM6362 pin controller
++
++Required properties:
++- compatible: Must be "brcm,bcm6362-pinctrl"
++- reg: Register specifiers of dirout, dat, led, mode, ctrl, basemode registers.
++- reg-names: Must be "dirout", "dat", "led", "mode", "ctrl", "basemode".
++- gpio-controller: Identifies this node as a GPIO controller.
++- #gpio-cells: Must be <2>.
++
++Example:
++
++pinctrl: pin-controller at 10000080 {
++	compatible = "brcm,bcm6362-pinctrl";
++	reg = <0x10000080 0x8>,
++	      <0x10000088 0x8>,
++	      <0x10000090 0x4>,
++	      <0x10000098 0x4>,
++	      <0x1000009c 0x4>,
++	      <0x100000b8 0x4>;
++	reg-names = "dirout", "dat", "led",
++		    "mode", "ctrl", "basemode";
++
++	gpio-controller;
++	#gpio-cells = <2>;
++};
++
++Available pins/groups and functions:
++
++name		pins		functions
++-----------------------------------------------------------
++gpio0		0		led, usb_device_led
++gpio1		1		led, sys_irq
++gpio2		2		led, serial_led_clk
++gpio3		3		led, serial_led_data
++gpio4		4		led, robosw_led_data
++gpio5		5		led, robosw_led_clk
++gpio6		6		led, robosw_led0
++gpio7		7		led, robosw_led1
++gpio8		8		led, inet_led
++gpio9		9		led, spi_cs2
++gpio10		10		led, spi_cs3
++gpio11		11		led, ntr_pulse
++gpio12		12		led, uart1_scts
++gpio13		13		led, uart1_srts
++gpio14		14		led, uart1_sdin
++gpio15		15		led, uart1_sdout
++gpio16		16		led, adsl_spi_miso
++gpio17		17		led, adsl_spi_mosi
++gpio18		18		led, adsl_spi_clk
++gpio19		19		led, adsl_spi_cs
++gpio20		20		led, ephy0_led
++gpio21		21		led, ephy1_led
++gpio22		22		led, ephy2_led
++gpio23		23		led, ephy3_led
++gpio24		24		ext_irq0
++gpio25		25		ext_irq1
++gpio26		26		ext_irq2
++gpio27		27		ext_irq3
++gpio28		28		-
++gpio29		29		-
++gpio30		30		-
++gpio31		31		-
++gpio32		32		wifi
++gpio33		33		wifi
++gpio34		34		wifi
++gpio35		35		wifi
++gpio36		36		wifi
++gpio37		37		wifi
++gpio38		38		wifi
++gpio39		39		wifi
++gpio40		40		wifi
++gpio41		41		wifi
++gpio42		42		wifi
++gpio43		43		wifi
++gpio44		44		wifi
++gpio45		45		wifi
++gpio46		46		wifi
++gpio47		47		wifi
++nand_grp	8, 12-23, 27	nand
diff --git a/target/linux/brcm63xx/patches-4.4/138-pinctrl-add-a-pincontrol-driver-for-BCM6362.patch b/target/linux/brcm63xx/patches-4.4/138-pinctrl-add-a-pincontrol-driver-for-BCM6362.patch
new file mode 100644
index 0000000..726a97f
--- /dev/null
+++ b/target/linux/brcm63xx/patches-4.4/138-pinctrl-add-a-pincontrol-driver-for-BCM6362.patch
@@ -0,0 +1,733 @@
+From eea6b96701d734095e2f823f3a82d9b063f553ae Mon Sep 17 00:00:00 2001
+From: Jonas Gorski <jonas.gorski at gmail.com>
+Date: Fri, 24 Jun 2016 22:17:20 +0200
+Subject: [PATCH 09/16] pinctrl: add a pincontrol driver for BCM6362
+
+Add a pincotrol driver for BCM6362. BCM6362 allows muxing individual
+GPIO pins to the LED controller, to be available by the integrated
+wifi, or other functions. It also supports overlay groups, of which
+only NAND is documented.
+
+Signed-off-by: Jonas Gorski <jonas.gorski at gmail.com>
+---
+ drivers/pinctrl/bcm63xx/Kconfig           |   7 +
+ drivers/pinctrl/bcm63xx/Makefile          |   1 +
+ drivers/pinctrl/bcm63xx/pinctrl-bcm6362.c | 692 ++++++++++++++++++++++++++++++
+ 3 files changed, 700 insertions(+)
+ create mode 100644 drivers/pinctrl/bcm63xx/pinctrl-bcm6362.c
+
+--- a/drivers/pinctrl/bcm63xx/Kconfig
++++ b/drivers/pinctrl/bcm63xx/Kconfig
+@@ -23,3 +23,10 @@ config PINCTRL_BCM6358
+ 	select PINCTRL_BCM63XX
+ 	select GENERIC_PINCONF
+ 	select MFD_SYSCON
++
++config PINCTRL_BCM6362
++	bool "BCM6362 pincontrol driver" if COMPILE_TEST
++	select PINMUX
++	select PINCONF
++	select PINCTRL_BCM63XX
++	select GENERIC_PINCONF
+--- a/drivers/pinctrl/bcm63xx/Makefile
++++ b/drivers/pinctrl/bcm63xx/Makefile
+@@ -2,3 +2,4 @@ obj-$(CONFIG_PINCTRL_BCM63XX)	+= pinctrl
+ obj-$(CONFIG_PINCTRL_BCM6328)	+= pinctrl-bcm6328.o
+ obj-$(CONFIG_PINCTRL_BCM6348)	+= pinctrl-bcm6348.o
+ obj-$(CONFIG_PINCTRL_BCM6358)	+= pinctrl-bcm6358.o
++obj-$(CONFIG_PINCTRL_BCM6362)	+= pinctrl-bcm6362.o
+--- /dev/null
++++ b/drivers/pinctrl/bcm63xx/pinctrl-bcm6362.c
+@@ -0,0 +1,692 @@
++/*
++ * This file is subject to the terms and conditions of the GNU General Public
++ * License.  See the file "COPYING" in the main directory of this archive
++ * for more details.
++ *
++ * Copyright (C) 2016 Jonas Gorski <jonas.gorski at gmail.com>
++ */
++
++#include <linux/kernel.h>
++#include <linux/spinlock.h>
++#include <linux/bitops.h>
++#include <linux/gpio.h>
++#include <linux/of.h>
++#include <linux/of_gpio.h>
++#include <linux/slab.h>
++#include <linux/platform_device.h>
++
++#include <linux/pinctrl/pinconf.h>
++#include <linux/pinctrl/pinconf-generic.h>
++#include <linux/pinctrl/pinmux.h>
++#include <linux/pinctrl/machine.h>
++
++#include "../core.h"
++#include "../pinctrl-utils.h"
++
++#include "pinctrl-bcm63xx.h"
++
++#define BCM6362_NGPIO	48
++
++/* GPIO_BASEMODE register */
++#define BASEMODE_NAND	BIT(2)
++
++enum bcm6362_pinctrl_reg {
++	BCM6362_LEDCTRL,
++	BCM6362_MODE,
++	BCM6362_CTRL,
++	BCM6362_BASEMODE,
++};
++
++struct bcm6362_pingroup {
++	const char *name;
++	const unsigned * const pins;
++	const unsigned num_pins;
++};
++
++struct bcm6362_function {
++	const char *name;
++	const char * const *groups;
++	const unsigned num_groups;
++
++	enum bcm6362_pinctrl_reg reg;
++	u32 basemode_mask;
++};
++
++struct bcm6362_pinctrl {
++	struct pinctrl_dev *pctldev;
++	struct pinctrl_desc desc;
++
++	void __iomem *led;
++	void __iomem *mode;
++	void __iomem *ctrl;
++	void __iomem *basemode;
++
++	/* register access lock */
++	spinlock_t lock;
++
++	struct gpio_chip gpio[2];
++};
++
++#define BCM6362_PIN(a, b, mask)			\
++	{					\
++		.number = a,			\
++		.name = b,			\
++		.drv_data = (void *)(mask),	\
++	}
++
++static const struct pinctrl_pin_desc bcm6362_pins[] = {
++	PINCTRL_PIN(0, "gpio0"),
++	PINCTRL_PIN(1, "gpio1"),
++	PINCTRL_PIN(2, "gpio2"),
++	PINCTRL_PIN(3, "gpio3"),
++	PINCTRL_PIN(4, "gpio4"),
++	PINCTRL_PIN(5, "gpio5"),
++	PINCTRL_PIN(6, "gpio6"),
++	PINCTRL_PIN(7, "gpio7"),
++	BCM6362_PIN(8, "gpio8", BASEMODE_NAND),
++	PINCTRL_PIN(9, "gpio9"),
++	PINCTRL_PIN(10, "gpio10"),
++	PINCTRL_PIN(11, "gpio11"),
++	BCM6362_PIN(12, "gpio12", BASEMODE_NAND),
++	BCM6362_PIN(13, "gpio13", BASEMODE_NAND),
++	BCM6362_PIN(14, "gpio14", BASEMODE_NAND),
++	BCM6362_PIN(15, "gpio15", BASEMODE_NAND),
++	BCM6362_PIN(16, "gpio16", BASEMODE_NAND),
++	BCM6362_PIN(17, "gpio17", BASEMODE_NAND),
++	BCM6362_PIN(18, "gpio18", BASEMODE_NAND),
++	BCM6362_PIN(19, "gpio19", BASEMODE_NAND),
++	BCM6362_PIN(20, "gpio20", BASEMODE_NAND),
++	BCM6362_PIN(21, "gpio21", BASEMODE_NAND),
++	BCM6362_PIN(22, "gpio22", BASEMODE_NAND),
++	BCM6362_PIN(23, "gpio23", BASEMODE_NAND),
++	PINCTRL_PIN(24, "gpio24"),
++	PINCTRL_PIN(25, "gpio25"),
++	PINCTRL_PIN(26, "gpio26"),
++	BCM6362_PIN(27, "gpio27", BASEMODE_NAND),
++	PINCTRL_PIN(28, "gpio28"),
++	PINCTRL_PIN(29, "gpio29"),
++	PINCTRL_PIN(30, "gpio30"),
++	PINCTRL_PIN(31, "gpio31"),
++	PINCTRL_PIN(32, "gpio32"),
++	PINCTRL_PIN(33, "gpio33"),
++	PINCTRL_PIN(34, "gpio34"),
++	PINCTRL_PIN(35, "gpio35"),
++	PINCTRL_PIN(36, "gpio36"),
++	PINCTRL_PIN(37, "gpio37"),
++	PINCTRL_PIN(38, "gpio38"),
++	PINCTRL_PIN(39, "gpio39"),
++	PINCTRL_PIN(40, "gpio40"),
++	PINCTRL_PIN(41, "gpio41"),
++	PINCTRL_PIN(42, "gpio42"),
++	PINCTRL_PIN(43, "gpio43"),
++	PINCTRL_PIN(44, "gpio44"),
++	PINCTRL_PIN(45, "gpio45"),
++	PINCTRL_PIN(46, "gpio46"),
++	PINCTRL_PIN(47, "gpio47"),
++};
++
++static unsigned gpio0_pins[] = { 0 };
++static unsigned gpio1_pins[] = { 1 };
++static unsigned gpio2_pins[] = { 2 };
++static unsigned gpio3_pins[] = { 3 };
++static unsigned gpio4_pins[] = { 4 };
++static unsigned gpio5_pins[] = { 5 };
++static unsigned gpio6_pins[] = { 6 };
++static unsigned gpio7_pins[] = { 7 };
++static unsigned gpio8_pins[] = { 8 };
++static unsigned gpio9_pins[] = { 9 };
++static unsigned gpio10_pins[] = { 10 };
++static unsigned gpio11_pins[] = { 11 };
++static unsigned gpio12_pins[] = { 12 };
++static unsigned gpio13_pins[] = { 13 };
++static unsigned gpio14_pins[] = { 14 };
++static unsigned gpio15_pins[] = { 15 };
++static unsigned gpio16_pins[] = { 16 };
++static unsigned gpio17_pins[] = { 17 };
++static unsigned gpio18_pins[] = { 18 };
++static unsigned gpio19_pins[] = { 19 };
++static unsigned gpio20_pins[] = { 20 };
++static unsigned gpio21_pins[] = { 21 };
++static unsigned gpio22_pins[] = { 22 };
++static unsigned gpio23_pins[] = { 23 };
++static unsigned gpio24_pins[] = { 24 };
++static unsigned gpio25_pins[] = { 25 };
++static unsigned gpio26_pins[] = { 26 };
++static unsigned gpio27_pins[] = { 27 };
++static unsigned gpio28_pins[] = { 28 };
++static unsigned gpio29_pins[] = { 29 };
++static unsigned gpio30_pins[] = { 30 };
++static unsigned gpio31_pins[] = { 31 };
++static unsigned gpio32_pins[] = { 32 };
++static unsigned gpio33_pins[] = { 33 };
++static unsigned gpio34_pins[] = { 34 };
++static unsigned gpio35_pins[] = { 35 };
++static unsigned gpio36_pins[] = { 36 };
++static unsigned gpio37_pins[] = { 37 };
++static unsigned gpio38_pins[] = { 38 };
++static unsigned gpio39_pins[] = { 39 };
++static unsigned gpio40_pins[] = { 40 };
++static unsigned gpio41_pins[] = { 41 };
++static unsigned gpio42_pins[] = { 42 };
++static unsigned gpio43_pins[] = { 43 };
++static unsigned gpio44_pins[] = { 44 };
++static unsigned gpio45_pins[] = { 45 };
++static unsigned gpio46_pins[] = { 46 };
++static unsigned gpio47_pins[] = { 47 };
++
++static unsigned nand_grp_pins[] = {
++	8, 12, 13, 14, 15, 16, 17,
++	18, 19, 20, 21, 22, 23, 27,
++};
++
++#define BCM6362_GROUP(n)				\
++	{						\
++		.name = #n,				\
++		.pins = n##_pins,			\
++		.num_pins = ARRAY_SIZE(n##_pins),	\
++	}
++
++static struct bcm6362_pingroup bcm6362_groups[] = {
++	BCM6362_GROUP(gpio0),
++	BCM6362_GROUP(gpio1),
++	BCM6362_GROUP(gpio2),
++	BCM6362_GROUP(gpio3),
++	BCM6362_GROUP(gpio4),
++	BCM6362_GROUP(gpio5),
++	BCM6362_GROUP(gpio6),
++	BCM6362_GROUP(gpio7),
++	BCM6362_GROUP(gpio8),
++	BCM6362_GROUP(gpio9),
++	BCM6362_GROUP(gpio10),
++	BCM6362_GROUP(gpio11),
++	BCM6362_GROUP(gpio12),
++	BCM6362_GROUP(gpio13),
++	BCM6362_GROUP(gpio14),
++	BCM6362_GROUP(gpio15),
++	BCM6362_GROUP(gpio16),
++	BCM6362_GROUP(gpio17),
++	BCM6362_GROUP(gpio18),
++	BCM6362_GROUP(gpio19),
++	BCM6362_GROUP(gpio20),
++	BCM6362_GROUP(gpio21),
++	BCM6362_GROUP(gpio22),
++	BCM6362_GROUP(gpio23),
++	BCM6362_GROUP(gpio24),
++	BCM6362_GROUP(gpio25),
++	BCM6362_GROUP(gpio26),
++	BCM6362_GROUP(gpio27),
++	BCM6362_GROUP(gpio28),
++	BCM6362_GROUP(gpio29),
++	BCM6362_GROUP(gpio30),
++	BCM6362_GROUP(gpio31),
++	BCM6362_GROUP(gpio32),
++	BCM6362_GROUP(gpio33),
++	BCM6362_GROUP(gpio34),
++	BCM6362_GROUP(gpio35),
++	BCM6362_GROUP(gpio36),
++	BCM6362_GROUP(gpio37),
++	BCM6362_GROUP(gpio38),
++	BCM6362_GROUP(gpio39),
++	BCM6362_GROUP(gpio40),
++	BCM6362_GROUP(gpio41),
++	BCM6362_GROUP(gpio42),
++	BCM6362_GROUP(gpio43),
++	BCM6362_GROUP(gpio44),
++	BCM6362_GROUP(gpio45),
++	BCM6362_GROUP(gpio46),
++	BCM6362_GROUP(gpio47),
++	BCM6362_GROUP(nand_grp),
++};
++
++static const char * const led_groups[] = {
++	"gpio0",
++	"gpio1",
++	"gpio2",
++	"gpio3",
++	"gpio4",
++	"gpio5",
++	"gpio6",
++	"gpio7",
++	"gpio8",
++	"gpio9",
++	"gpio10",
++	"gpio11",
++	"gpio12",
++	"gpio13",
++	"gpio14",
++	"gpio15",
++	"gpio16",
++	"gpio17",
++	"gpio18",
++	"gpio19",
++	"gpio20",
++	"gpio21",
++	"gpio22",
++	"gpio23",
++};
++
++static const char * const usb_device_led_groups[] = {
++	"gpio0",
++};
++
++static const char * const sys_irq_groups[] = {
++	"gpio1",
++};
++
++static const char * const serial_led_clk_groups[] = {
++	"gpio2",
++};
++
++static const char * const serial_led_data_groups[] = {
++	"gpio3",
++};
++
++static const char * const robosw_led_data_groups[] = {
++	"gpio4",
++};
++
++static const char * const robosw_led_clk_groups[] = {
++	"gpio5",
++};
++
++static const char * const robosw_led0_groups[] = {
++	"gpio6",
++};
++
++static const char * const robosw_led1_groups[] = {
++	"gpio7",
++};
++
++static const char * const inet_led_groups[] = {
++	"gpio8",
++};
++
++static const char * const spi_cs2_groups[] = {
++	"gpio9",
++};
++
++static const char * const spi_cs3_groups[] = {
++	"gpio10",
++};
++
++static const char * const ntr_pulse_groups[] = {
++	"gpio11",
++};
++
++static const char * const uart1_scts_groups[] = {
++	"gpio12",
++};
++
++static const char * const uart1_srts_groups[] = {
++	"gpio13",
++};
++
++static const char * const uart1_sdin_groups[] = {
++	"gpio14",
++};
++
++static const char * const uart1_sdout_groups[] = {
++	"gpio15",
++};
++
++static const char * const adsl_spi_miso_groups[] = {
++	"gpio16",
++};
++
++static const char * const adsl_spi_mosi_groups[] = {
++	"gpio17",
++};
++
++static const char * const adsl_spi_clk_groups[] = {
++	"gpio18",
++};
++
++static const char * const adsl_spi_cs_groups[] = {
++	"gpio19",
++};
++
++static const char * const ephy0_led_groups[] = {
++	"gpio20",
++};
++
++static const char * const ephy1_led_groups[] = {
++	"gpio21",
++};
++
++static const char * const ephy2_led_groups[] = {
++	"gpio22",
++};
++
++static const char * const ephy3_led_groups[] = {
++	"gpio23",
++};
++
++static const char * const ext_irq0_groups[] = {
++	"gpio24",
++};
++
++static const char * const ext_irq1_groups[] = {
++	"gpio25",
++};
++
++static const char * const ext_irq2_groups[] = {
++	"gpio26",
++};
++
++static const char * const ext_irq3_groups[] = {
++	"gpio27",
++};
++
++static const char * const wifi_groups[] = {
++	"gpio32",
++	"gpio33",
++	"gpio34",
++	"gpio35",
++	"gpio36",
++	"gpio37",
++	"gpio38",
++	"gpio39",
++	"gpio40",
++	"gpio41",
++	"gpio42",
++	"gpio43",
++	"gpio44",
++	"gpio45",
++	"gpio46",
++	"gpio47",
++};
++
++static const char * const nand_groups[] = {
++	"nand_grp",
++};
++
++#define BCM6362_LED_FUN(n)				\
++	{						\
++		.name = #n,				\
++		.groups = n##_groups,			\
++		.num_groups = ARRAY_SIZE(n##_groups),	\
++		.reg = BCM6362_LEDCTRL,			\
++	}
++
++#define BCM6362_MODE_FUN(n)				\
++	{						\
++		.name = #n,				\
++		.groups = n##_groups,			\
++		.num_groups = ARRAY_SIZE(n##_groups),	\
++		.reg = BCM6362_MODE,			\
++	}
++
++#define BCM6362_CTRL_FUN(n)				\
++	{						\
++		.name = #n,				\
++		.groups = n##_groups,			\
++		.num_groups = ARRAY_SIZE(n##_groups),	\
++		.reg = BCM6362_CTRL,			\
++	}
++
++#define BCM6362_BASEMODE_FUN(n, mask)			\
++	{						\
++		.name = #n,				\
++		.groups = n##_groups,			\
++		.num_groups = ARRAY_SIZE(n##_groups),	\
++		.reg = BCM6362_BASEMODE,		\
++		.basemode_mask = (mask),		\
++	}
++
++static const struct bcm6362_function bcm6362_funcs[] = {
++	BCM6362_LED_FUN(led),
++	BCM6362_MODE_FUN(usb_device_led),
++	BCM6362_MODE_FUN(sys_irq),
++	BCM6362_MODE_FUN(serial_led_clk),
++	BCM6362_MODE_FUN(serial_led_data),
++	BCM6362_MODE_FUN(robosw_led_data),
++	BCM6362_MODE_FUN(robosw_led_clk),
++	BCM6362_MODE_FUN(robosw_led0),
++	BCM6362_MODE_FUN(robosw_led1),
++	BCM6362_MODE_FUN(inet_led),
++	BCM6362_MODE_FUN(spi_cs2),
++	BCM6362_MODE_FUN(spi_cs3),
++	BCM6362_MODE_FUN(ntr_pulse),
++	BCM6362_MODE_FUN(uart1_scts),
++	BCM6362_MODE_FUN(uart1_srts),
++	BCM6362_MODE_FUN(uart1_sdin),
++	BCM6362_MODE_FUN(uart1_sdout),
++	BCM6362_MODE_FUN(adsl_spi_miso),
++	BCM6362_MODE_FUN(adsl_spi_mosi),
++	BCM6362_MODE_FUN(adsl_spi_clk),
++	BCM6362_MODE_FUN(adsl_spi_cs),
++	BCM6362_MODE_FUN(ephy0_led),
++	BCM6362_MODE_FUN(ephy1_led),
++	BCM6362_MODE_FUN(ephy2_led),
++	BCM6362_MODE_FUN(ephy3_led),
++	BCM6362_MODE_FUN(ext_irq0),
++	BCM6362_MODE_FUN(ext_irq1),
++	BCM6362_MODE_FUN(ext_irq2),
++	BCM6362_MODE_FUN(ext_irq3),
++	BCM6362_CTRL_FUN(wifi),
++	BCM6362_BASEMODE_FUN(nand, BASEMODE_NAND),
++};
++
++static int bcm6362_pinctrl_get_group_count(struct pinctrl_dev *pctldev)
++{
++	return ARRAY_SIZE(bcm6362_groups);
++}
++
++static const char *bcm6362_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
++						  unsigned group)
++{
++	return bcm6362_groups[group].name;
++}
++
++static int bcm6362_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
++					  unsigned group, const unsigned **pins,
++					  unsigned *num_pins)
++{
++	*pins = bcm6362_groups[group].pins;
++	*num_pins = bcm6362_groups[group].num_pins;
++
++	return 0;
++}
++
++static int bcm6362_pinctrl_get_func_count(struct pinctrl_dev *pctldev)
++{
++	return ARRAY_SIZE(bcm6362_funcs);
++}
++
++static const char *bcm6362_pinctrl_get_func_name(struct pinctrl_dev *pctldev,
++						 unsigned selector)
++{
++	return bcm6362_funcs[selector].name;
++}
++
++static int bcm6362_pinctrl_get_groups(struct pinctrl_dev *pctldev,
++				      unsigned selector,
++				      const char * const **groups,
++				      unsigned * const num_groups)
++{
++	*groups = bcm6362_funcs[selector].groups;
++	*num_groups = bcm6362_funcs[selector].num_groups;
++
++	return 0;
++}
++
++static void bcm6362_rmw_mux(struct bcm6362_pinctrl *pctl, void __iomem *reg,
++			    u32 mask, u32 val)
++{
++	unsigned long flags;
++	u32 tmp;
++
++	spin_lock_irqsave(&pctl->lock, flags);
++	tmp = __raw_readl(reg);
++	tmp &= ~mask;
++	tmp |= val & mask;
++	__raw_writel(tmp, reg);
++
++	spin_unlock_irqrestore(&pctl->lock, flags);
++}
++
++static void bcm6362_set_gpio(struct bcm6362_pinctrl *pctl, unsigned pin)
++{
++	const struct pinctrl_pin_desc *desc = &bcm6362_pins[pin];
++	u32 mask = BIT(pin % 32);
++
++	if (desc->drv_data)
++		bcm6362_rmw_mux(pctl, pctl->basemode, (u32)desc->drv_data, 0);
++
++	if (pin < 32) {
++		/* base mode 0 => gpio 1 => mux function */
++		bcm6362_rmw_mux(pctl, pctl->mode, mask, 0);
++
++		/* pins 0-23 might be muxed to led */
++		if (pin < 24)
++			bcm6362_rmw_mux(pctl, pctl->led, mask, 0);
++	} else {
++		/* ctrl reg 0 => wifi function 1 => gpio */
++		bcm6362_rmw_mux(pctl, pctl->ctrl, mask, mask);
++	}
++}
++
++static int bcm6362_pinctrl_set_mux(struct pinctrl_dev *pctldev,
++				   unsigned selector, unsigned group)
++{
++	struct bcm6362_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
++	const struct bcm6362_pingroup *grp = &bcm6362_groups[group];
++	const struct bcm6362_function *f = &bcm6362_funcs[selector];
++	unsigned i;
++	void __iomem *reg;
++	u32 val, mask;
++
++	for (i = 0; i < grp->num_pins; i++)
++		bcm6362_set_gpio(pctl, grp->pins[i]);
++
++	switch (f->reg) {
++	case BCM6362_LEDCTRL:
++		reg = pctl->led;
++		mask = BIT(grp->pins[0]);
++		val = BIT(grp->pins[0]);
++		break;
++	case BCM6362_MODE:
++		reg = pctl->ctrl;
++		mask = BIT(grp->pins[0]);
++		val = BIT(grp->pins[0]);
++		break;
++	case BCM6362_CTRL:
++		reg = pctl->ctrl;
++		mask = BIT(grp->pins[0]);
++		val = 0;
++		break;
++	case BCM6362_BASEMODE:
++		reg = pctl->basemode;
++		mask = f->basemode_mask;
++		val = f->basemode_mask;
++		break;
++	default:
++		WARN_ON(1);
++		return -EINVAL;
++	}
++
++	bcm6362_rmw_mux(pctl, reg, mask, val);
++
++	return 0;
++}
++
++static int bcm6362_gpio_request_enable(struct pinctrl_dev *pctldev,
++				       struct pinctrl_gpio_range *range,
++				       unsigned offset)
++{
++	struct bcm6362_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
++
++	/* disable all functions using this pin */
++	bcm6362_set_gpio(pctl, offset);
++
++	return 0;
++}
++
++static struct pinctrl_ops bcm6362_pctl_ops = {
++	.get_groups_count	= bcm6362_pinctrl_get_group_count,
++	.get_group_name		= bcm6362_pinctrl_get_group_name,
++	.get_group_pins		= bcm6362_pinctrl_get_group_pins,
++#ifdef CONFIG_OF
++	.dt_node_to_map		= pinconf_generic_dt_node_to_map_pin,
++	.dt_free_map		= pinctrl_utils_free_map,
++#endif
++};
++
++static struct pinmux_ops bcm6362_pmx_ops = {
++	.get_functions_count	= bcm6362_pinctrl_get_func_count,
++	.get_function_name	= bcm6362_pinctrl_get_func_name,
++	.get_function_groups	= bcm6362_pinctrl_get_groups,
++	.set_mux		= bcm6362_pinctrl_set_mux,
++	.gpio_request_enable	= bcm6362_gpio_request_enable,
++	.strict			= true,
++};
++
++static int bcm6362_pinctrl_probe(struct platform_device *pdev)
++{
++	struct bcm6362_pinctrl *pctl;
++	struct resource *res;
++	void __iomem *led, *mode, *ctrl, *basemode;
++
++	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "led");
++	led = devm_ioremap_resource(&pdev->dev, res);
++	if (IS_ERR(led))
++		return PTR_ERR(led);
++
++	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mode");
++	mode = devm_ioremap_resource(&pdev->dev, res);
++	if (IS_ERR(mode))
++		return PTR_ERR(mode);
++
++	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ctrl");
++	ctrl = devm_ioremap_resource(&pdev->dev, res);
++	if (IS_ERR(ctrl))
++		return PTR_ERR(ctrl);
++
++	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "basemode");
++	basemode = devm_ioremap_resource(&pdev->dev, res);
++	if (IS_ERR(basemode))
++		return PTR_ERR(basemode);
++
++	pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL);
++	if (!pctl)
++		return -ENOMEM;
++
++	spin_lock_init(&pctl->lock);
++
++	pctl->led = led;
++	pctl->mode = mode;
++	pctl->ctrl = ctrl;
++	pctl->basemode = basemode;
++
++	pctl->desc.name = dev_name(&pdev->dev);
++	pctl->desc.owner = THIS_MODULE;
++	pctl->desc.pctlops = &bcm6362_pctl_ops;
++	pctl->desc.pmxops = &bcm6362_pmx_ops;
++
++	pctl->desc.npins = ARRAY_SIZE(bcm6362_pins);
++	pctl->desc.pins = bcm6362_pins;
++
++	platform_set_drvdata(pdev, pctl);
++
++	pctl->pctldev = bcm63xx_pinctrl_register(pdev, &pctl->desc, pctl,
++						 pctl->gpio, BCM6362_NGPIO);
++	if (IS_ERR(pctl->pctldev))
++		return PTR_ERR(pctl->pctldev);
++
++	return 0;
++}
++
++static const struct of_device_id bcm6362_pinctrl_match[] = {
++	{ .compatible = "brcm,bcm6362-pinctrl", },
++	{ },
++};
++
++static struct platform_driver bcm6362_pinctrl_driver = {
++	.probe = bcm6362_pinctrl_probe,
++	.driver = {
++		.name = "bcm6362-pinctrl",
++		.of_match_table = bcm6362_pinctrl_match,
++	},
++};
++
++builtin_platform_driver(bcm6362_pinctrl_driver);
diff --git a/target/linux/brcm63xx/patches-4.4/139-Documentation-add-BCM6368-pincontroller-binding-docu.patch b/target/linux/brcm63xx/patches-4.4/139-Documentation-add-BCM6368-pincontroller-binding-docu.patch
new file mode 100644
index 0000000..e0a698f
--- /dev/null
+++ b/target/linux/brcm63xx/patches-4.4/139-Documentation-add-BCM6368-pincontroller-binding-docu.patch
@@ -0,0 +1,84 @@
+From 30594cf9bfff176a9e4b14c50dcd8b9d0cc3edec Mon Sep 17 00:00:00 2001
+From: Jonas Gorski <jonas.gorski at gmail.com>
+Date: Wed, 27 Jul 2016 11:36:51 +0200
+Subject: [PATCH 10/16] Documentation: add BCM6368 pincontroller binding
+ documentation
+
+Add binding documentation for the pincontrol core found in BCM6368 SoCs.
+
+Signed-off-by: Jonas Gorski <jonas.gorski at gmail.com>
+---
+ .../bindings/pinctrl/brcm,bcm6368-pinctrl.txt      | 67 ++++++++++++++++++++++
+ 1 file changed, 67 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6368-pinctrl.txt
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6368-pinctrl.txt
+@@ -0,0 +1,67 @@
++* Broadcom BCM6368 pin controller
++
++Required properties:
++- compatible: Must be "brcm,bcm6368-pinctrl".
++- reg: Register specifiers of dirout, dat, mode registers.
++- reg-names: Must be "dirout", "dat", "mode".
++- brcm,gpiobasemode: Phandle to the gpio basemode register.
++- gpio-controller: Identifies this node as a GPIO controller.
++- #gpio-cells: Must be <2>.
++
++Example:
++
++pinctrl: pin-controller at 10000080 {
++	compatible = "brcm,bcm6368-pinctrl";
++	reg = <0x10000080 0x08>,
++	      <0x10000088 0x08>,
++	      <0x10000098 0x04>;
++	reg-names = "dirout", "dat", "mode";
++	brcm,gpiobasemode = <&gpiobasemode>;
++
++	gpio-controller;
++	#gpio-cells = <2>;
++};
++
++gpiobasemode: syscon at 100000b8 {
++	compatible = "brcm,bcm6368-gpiobasemode", "syscon";
++	reg = <0x100000b8 4>;
++	native-endian;
++};
++
++Available pins/groups and functions:
++
++name		pins	functions
++-----------------------------------------------------------
++gpio0		0	analog_afe0
++gpio1		1	analog_afe1
++gpio2		2	sys_irq
++gpio3		3	serial_led_data
++gpio4		4	serial_led_clk
++gpio5		5	inet_led
++gpio6		6	ephy0_led
++gpio7		7	ephy1_led
++gpio8		8	ephy2_led
++gpio9		9	ephy3_led
++gpio10		10	robosw_led_data
++gpio11		11	robosw_led_clk
++gpio12		12	robosw_led0
++gpio13		13	robosw_led1
++gpio14		14	usb_device_led
++gpio15		15	-
++gpio16		16	pci_req1
++gpio17		17	pci_gnt1
++gpio18		18	pci_intb
++gpio19		19	pci_req0
++gpio20		20	pci_gnt0
++gpio21		21	-
++gpio22		22	pcmcia_cd1
++gpio23		23	pcmcia_cd2
++gpio24		24	pcmcia_vs1
++gpio25		25	pcmcia_vs2
++gpio26		26	ebi_cs2
++gpio27		27	ebi_cs3
++gpio28		28	spi_cs2
++gpio29		29	spi_cs3
++gpio30		30	spi_cs4
++gpio31		31	spi_cs5
++uart1_grp	30-33	uart1
diff --git a/target/linux/brcm63xx/patches-4.4/140-pinctrl-add-a-pincontrol-driver-for-BCM6368.patch b/target/linux/brcm63xx/patches-4.4/140-pinctrl-add-a-pincontrol-driver-for-BCM6368.patch
new file mode 100644
index 0000000..9d086a6
--- /dev/null
+++ b/target/linux/brcm63xx/patches-4.4/140-pinctrl-add-a-pincontrol-driver-for-BCM6368.patch
@@ -0,0 +1,620 @@
+From 90be3cb4f1a45b8be4a4ec264cd66c2f8e893fcb Mon Sep 17 00:00:00 2001
+From: Jonas Gorski <jonas.gorski at gmail.com>
+Date: Fri, 24 Jun 2016 22:18:25 +0200
+Subject: [PATCH 11/16] pinctrl: add a pincontrol driver for BCM6368
+
+Add a pincontrol driver for BCM6368. BCM6368 allows muxing the first 32
+GPIOs onto alternative functions. Not all are documented.
+
+Signed-off-by: Jonas Gorski <jonas.gorski at gmail.com>
+---
+ drivers/pinctrl/bcm63xx/Kconfig           |  15 +
+ drivers/pinctrl/bcm63xx/Makefile          |   1 +
+ drivers/pinctrl/bcm63xx/pinctrl-bcm6368.c | 573 ++++++++++++++++++++++++++++++
+ 3 files changed, 589 insertions(+)
+ create mode 100644 drivers/pinctrl/bcm63xx/pinctrl-bcm6368.c
+
+--- a/drivers/pinctrl/bcm63xx/Kconfig
++++ b/drivers/pinctrl/bcm63xx/Kconfig
+@@ -30,3 +30,18 @@ config PINCTRL_BCM6362
+ 	select PINCONF
+ 	select PINCTRL_BCM63XX
+ 	select GENERIC_PINCONF
++
++config PINCTRL_BCM6368
++	bool "BCM6368 pincontrol driver" if COMPILE_TEST
++	select PINMUX
++	select PINCONF
++	select PINCTRL_BCM63XX
++	select GENERIC_PINCONF
++	select MFD_SYSCON
++
++config PINCTRL_BCM63268
++	bool "BCM63268 pincontrol driver" if COMPILE_TEST
++	select PINMUX
++	select PINCONF
++	select PINCTRL_BCM63XX
++	select GENERIC_PINCONF
+--- a/drivers/pinctrl/bcm63xx/Makefile
++++ b/drivers/pinctrl/bcm63xx/Makefile
+@@ -3,3 +3,4 @@ obj-$(CONFIG_PINCTRL_BCM6328)	+= pinctrl
+ obj-$(CONFIG_PINCTRL_BCM6348)	+= pinctrl-bcm6348.o
+ obj-$(CONFIG_PINCTRL_BCM6358)	+= pinctrl-bcm6358.o
+ obj-$(CONFIG_PINCTRL_BCM6362)	+= pinctrl-bcm6362.o
++obj-$(CONFIG_PINCTRL_BCM6368)	+= pinctrl-bcm6368.o
+--- /dev/null
++++ b/drivers/pinctrl/bcm63xx/pinctrl-bcm6368.c
+@@ -0,0 +1,573 @@
++/*
++ * This file is subject to the terms and conditions of the GNU General Public
++ * License.  See the file "COPYING" in the main directory of this archive
++ * for more details.
++ *
++ * Copyright (C) 2016 Jonas Gorski <jonas.gorski at gmail.com>
++ */
++
++#include <linux/bitops.h>
++#include <linux/kernel.h>
++#include <linux/gpio.h>
++#include <linux/mfd/syscon.h>
++#include <linux/of.h>
++#include <linux/of_address.h>
++#include <linux/of_gpio.h>
++#include <linux/pinctrl/pinconf.h>
++#include <linux/pinctrl/pinconf-generic.h>
++#include <linux/pinctrl/pinmux.h>
++#include <linux/pinctrl/machine.h>
++#include <linux/platform_device.h>
++#include <linux/regmap.h>
++#include <linux/slab.h>
++#include <linux/spinlock.h>
++
++#include "../core.h"
++#include "../pinctrl-utils.h"
++
++#include "pinctrl-bcm63xx.h"
++
++#define BCM6368_NGPIO	38
++
++#define BCM6368_BASEMODE_MASK	0x7
++#define BCM6368_BASEMODE_GPIO	0x0
++#define BCM6368_BASEMODE_UART1	0x1
++
++struct bcm6368_pingroup {
++	const char *name;
++	const unsigned * const pins;
++	const unsigned num_pins;
++};
++
++struct bcm6368_function {
++	const char *name;
++	const char * const *groups;
++	const unsigned num_groups;
++
++	unsigned dir_out:16;
++	unsigned basemode:3;
++};
++
++struct bcm6368_pinctrl {
++	struct pinctrl_dev *pctldev;
++	struct pinctrl_desc desc;
++
++	void __iomem *mode;
++	struct regmap_field *overlay;
++
++	/* register access lock */
++	spinlock_t lock;
++
++	struct gpio_chip gpio[2];
++};
++
++#define BCM6368_BASEMODE_PIN(a, b)		\
++	{					\
++		.number = a,			\
++		.name = b,			\
++		.drv_data = (void *)true	\
++	}
++
++static const struct pinctrl_pin_desc bcm6368_pins[] = {
++	PINCTRL_PIN(0, "gpio0"),
++	PINCTRL_PIN(1, "gpio1"),
++	PINCTRL_PIN(2, "gpio2"),
++	PINCTRL_PIN(3, "gpio3"),
++	PINCTRL_PIN(4, "gpio4"),
++	PINCTRL_PIN(5, "gpio5"),
++	PINCTRL_PIN(6, "gpio6"),
++	PINCTRL_PIN(7, "gpio7"),
++	PINCTRL_PIN(8, "gpio8"),
++	PINCTRL_PIN(9, "gpio9"),
++	PINCTRL_PIN(10, "gpio10"),
++	PINCTRL_PIN(11, "gpio11"),
++	PINCTRL_PIN(12, "gpio12"),
++	PINCTRL_PIN(13, "gpio13"),
++	PINCTRL_PIN(14, "gpio14"),
++	PINCTRL_PIN(15, "gpio15"),
++	PINCTRL_PIN(16, "gpio16"),
++	PINCTRL_PIN(17, "gpio17"),
++	PINCTRL_PIN(18, "gpio18"),
++	PINCTRL_PIN(19, "gpio19"),
++	PINCTRL_PIN(20, "gpio20"),
++	PINCTRL_PIN(21, "gpio21"),
++	PINCTRL_PIN(22, "gpio22"),
++	PINCTRL_PIN(23, "gpio23"),
++	PINCTRL_PIN(24, "gpio24"),
++	PINCTRL_PIN(25, "gpio25"),
++	PINCTRL_PIN(26, "gpio26"),
++	PINCTRL_PIN(27, "gpio27"),
++	PINCTRL_PIN(28, "gpio28"),
++	PINCTRL_PIN(29, "gpio29"),
++	BCM6368_BASEMODE_PIN(30, "gpio30"),
++	BCM6368_BASEMODE_PIN(31, "gpio31"),
++	BCM6368_BASEMODE_PIN(32, "gpio32"),
++	BCM6368_BASEMODE_PIN(33, "gpio33"),
++	PINCTRL_PIN(34, "gpio34"),
++	PINCTRL_PIN(35, "gpio35"),
++	PINCTRL_PIN(36, "gpio36"),
++	PINCTRL_PIN(37, "gpio37"),
++};
++
++static unsigned gpio0_pins[] = { 0 };
++static unsigned gpio1_pins[] = { 1 };
++static unsigned gpio2_pins[] = { 2 };
++static unsigned gpio3_pins[] = { 3 };
++static unsigned gpio4_pins[] = { 4 };
++static unsigned gpio5_pins[] = { 5 };
++static unsigned gpio6_pins[] = { 6 };
++static unsigned gpio7_pins[] = { 7 };
++static unsigned gpio8_pins[] = { 8 };
++static unsigned gpio9_pins[] = { 9 };
++static unsigned gpio10_pins[] = { 10 };
++static unsigned gpio11_pins[] = { 11 };
++static unsigned gpio12_pins[] = { 12 };
++static unsigned gpio13_pins[] = { 13 };
++static unsigned gpio14_pins[] = { 14 };
++static unsigned gpio15_pins[] = { 15 };
++static unsigned gpio16_pins[] = { 16 };
++static unsigned gpio17_pins[] = { 17 };
++static unsigned gpio18_pins[] = { 18 };
++static unsigned gpio19_pins[] = { 19 };
++static unsigned gpio20_pins[] = { 20 };
++static unsigned gpio21_pins[] = { 21 };
++static unsigned gpio22_pins[] = { 22 };
++static unsigned gpio23_pins[] = { 23 };
++static unsigned gpio24_pins[] = { 24 };
++static unsigned gpio25_pins[] = { 25 };
++static unsigned gpio26_pins[] = { 26 };
++static unsigned gpio27_pins[] = { 27 };
++static unsigned gpio28_pins[] = { 28 };
++static unsigned gpio29_pins[] = { 29 };
++static unsigned gpio30_pins[] = { 30 };
++static unsigned gpio31_pins[] = { 31 };
++static unsigned uart1_grp_pins[] = { 30, 31, 32, 33 };
++
++#define BCM6368_GROUP(n)				\
++	{						\
++		.name = #n,				\
++		.pins = n##_pins,			\
++		.num_pins = ARRAY_SIZE(n##_pins),	\
++	}
++
++static struct bcm6368_pingroup bcm6368_groups[] = {
++	BCM6368_GROUP(gpio0),
++	BCM6368_GROUP(gpio1),
++	BCM6368_GROUP(gpio2),
++	BCM6368_GROUP(gpio3),
++	BCM6368_GROUP(gpio4),
++	BCM6368_GROUP(gpio5),
++	BCM6368_GROUP(gpio6),
++	BCM6368_GROUP(gpio7),
++	BCM6368_GROUP(gpio8),
++	BCM6368_GROUP(gpio9),
++	BCM6368_GROUP(gpio10),
++	BCM6368_GROUP(gpio11),
++	BCM6368_GROUP(gpio12),
++	BCM6368_GROUP(gpio13),
++	BCM6368_GROUP(gpio14),
++	BCM6368_GROUP(gpio15),
++	BCM6368_GROUP(gpio16),
++	BCM6368_GROUP(gpio17),
++	BCM6368_GROUP(gpio18),
++	BCM6368_GROUP(gpio19),
++	BCM6368_GROUP(gpio20),
++	BCM6368_GROUP(gpio21),
++	BCM6368_GROUP(gpio22),
++	BCM6368_GROUP(gpio23),
++	BCM6368_GROUP(gpio24),
++	BCM6368_GROUP(gpio25),
++	BCM6368_GROUP(gpio26),
++	BCM6368_GROUP(gpio27),
++	BCM6368_GROUP(gpio28),
++	BCM6368_GROUP(gpio29),
++	BCM6368_GROUP(gpio30),
++	BCM6368_GROUP(gpio31),
++	BCM6368_GROUP(uart1_grp),
++};
++
++static const char * const analog_afe_0_groups[] = {
++	"gpio0",
++};
++
++static const char * const analog_afe_1_groups[] = {
++	"gpio1",
++};
++
++static const char * const sys_irq_groups[] = {
++	"gpio2",
++};
++
++static const char * const serial_led_data_groups[] = {
++	"gpio3",
++};
++
++static const char * const serial_led_clk_groups[] = {
++	"gpio4",
++};
++
++static const char * const inet_led_groups[] = {
++	"gpio5",
++};
++
++static const char * const ephy0_led_groups[] = {
++	"gpio6",
++};
++
++static const char * const ephy1_led_groups[] = {
++	"gpio7",
++};
++
++static const char * const ephy2_led_groups[] = {
++	"gpio8",
++};
++
++static const char * const ephy3_led_groups[] = {
++	"gpio9",
++};
++
++static const char * const robosw_led_data_groups[] = {
++	"gpio10",
++};
++
++static const char * const robosw_led_clk_groups[] = {
++	"gpio11",
++};
++
++static const char * const robosw_led0_groups[] = {
++	"gpio12",
++};
++
++static const char * const robosw_led1_groups[] = {
++	"gpio13",
++};
++
++static const char * const usb_device_led_groups[] = {
++	"gpio14",
++};
++
++static const char * const pci_req1_groups[] = {
++	"gpio16",
++};
++
++static const char * const pci_gnt1_groups[] = {
++	"gpio17",
++};
++
++static const char * const pci_intb_groups[] = {
++	"gpio18",
++};
++
++static const char * const pci_req0_groups[] = {
++	"gpio19",
++};
++
++static const char * const pci_gnt0_groups[] = {
++	"gpio20",
++};
++
++static const char * const pcmcia_cd1_groups[] = {
++	"gpio22",
++};
++
++static const char * const pcmcia_cd2_groups[] = {
++	"gpio23",
++};
++
++static const char * const pcmcia_vs1_groups[] = {
++	"gpio24",
++};
++
++static const char * const pcmcia_vs2_groups[] = {
++	"gpio25",
++};
++
++static const char * const ebi_cs2_groups[] = {
++	"gpio26",
++};
++
++static const char * const ebi_cs3_groups[] = {
++	"gpio27",
++};
++
++static const char * const spi_cs2_groups[] = {
++	"gpio28",
++};
++
++static const char * const spi_cs3_groups[] = {
++	"gpio29",
++};
++
++static const char * const spi_cs4_groups[] = {
++	"gpio30",
++};
++
++static const char * const spi_cs5_groups[] = {
++	"gpio31",
++};
++
++static const char * const uart1_groups[] = {
++	"uart1_grp",
++};
++
++#define BCM6368_FUN(n, out)				\
++	{						\
++		.name = #n,				\
++		.groups = n##_groups,			\
++		.num_groups = ARRAY_SIZE(n##_groups),	\
++		.dir_out = out,				\
++	}
++
++#define BCM6368_BASEMODE_FUN(n, val, out)		\
++	{						\
++		.name = #n,				\
++		.groups = n##_groups,			\
++		.num_groups = ARRAY_SIZE(n##_groups),	\
++		.basemode = BCM6368_BASEMODE_##val,	\
++		.dir_out = out,				\
++	}
++
++static const struct bcm6368_function bcm6368_funcs[] = {
++	BCM6368_FUN(analog_afe_0, 1),
++	BCM6368_FUN(analog_afe_1, 1),
++	BCM6368_FUN(sys_irq, 1),
++	BCM6368_FUN(serial_led_data, 1),
++	BCM6368_FUN(serial_led_clk, 1),
++	BCM6368_FUN(inet_led, 1),
++	BCM6368_FUN(ephy0_led, 1),
++	BCM6368_FUN(ephy1_led, 1),
++	BCM6368_FUN(ephy2_led, 1),
++	BCM6368_FUN(ephy3_led, 1),
++	BCM6368_FUN(robosw_led_data, 1),
++	BCM6368_FUN(robosw_led_clk, 1),
++	BCM6368_FUN(robosw_led0, 1),
++	BCM6368_FUN(robosw_led1, 1),
++	BCM6368_FUN(usb_device_led, 1),
++	BCM6368_FUN(pci_req1, 0),
++	BCM6368_FUN(pci_gnt1, 0),
++	BCM6368_FUN(pci_intb, 0),
++	BCM6368_FUN(pci_req0, 0),
++	BCM6368_FUN(pci_gnt0, 0),
++	BCM6368_FUN(pcmcia_cd1, 0),
++	BCM6368_FUN(pcmcia_cd2, 0),
++	BCM6368_FUN(pcmcia_vs1, 0),
++	BCM6368_FUN(pcmcia_vs2, 0),
++	BCM6368_FUN(ebi_cs2, 1),
++	BCM6368_FUN(ebi_cs3, 1),
++	BCM6368_FUN(spi_cs2, 1),
++	BCM6368_FUN(spi_cs3, 1),
++	BCM6368_FUN(spi_cs4, 1),
++	BCM6368_FUN(spi_cs5, 1),
++	BCM6368_BASEMODE_FUN(uart1, UART1, 0x6),
++};
++
++static int bcm6368_pinctrl_get_group_count(struct pinctrl_dev *pctldev)
++{
++	return ARRAY_SIZE(bcm6368_groups);
++}
++
++static const char *bcm6368_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
++						  unsigned group)
++{
++	return bcm6368_groups[group].name;
++}
++
++static int bcm6368_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
++					  unsigned group, const unsigned **pins,
++					  unsigned *num_pins)
++{
++	*pins = bcm6368_groups[group].pins;
++	*num_pins = bcm6368_groups[group].num_pins;
++
++	return 0;
++}
++
++static int bcm6368_pinctrl_get_func_count(struct pinctrl_dev *pctldev)
++{
++	return ARRAY_SIZE(bcm6368_funcs);
++}
++
++static const char *bcm6368_pinctrl_get_func_name(struct pinctrl_dev *pctldev,
++						 unsigned selector)
++{
++	return bcm6368_funcs[selector].name;
++}
++
++static int bcm6368_pinctrl_get_groups(struct pinctrl_dev *pctldev,
++				      unsigned selector,
++				      const char * const **groups,
++				      unsigned * const num_groups)
++{
++	*groups = bcm6368_funcs[selector].groups;
++	*num_groups = bcm6368_funcs[selector].num_groups;
++
++	return 0;
++}
++
++static void bcm6368_rmw_mux(struct bcm6368_pinctrl *pctl, void __iomem *reg,
++			    u32 mask, u32 val)
++{
++	u32 tmp;
++
++	tmp = __raw_readl(reg);
++	tmp &= ~mask;
++	tmp |= (val & mask);
++	__raw_writel(tmp, reg);
++}
++
++static int bcm6368_pinctrl_set_mux(struct pinctrl_dev *pctldev,
++				   unsigned selector, unsigned group)
++{
++	struct bcm6368_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
++	const struct bcm6368_pingroup *grp = &bcm6368_groups[group];
++	const struct bcm6368_function *fun = &bcm6368_funcs[selector];
++	unsigned long flags;
++	int i, pin;
++
++	spin_lock_irqsave(&pctl->lock, flags);
++	if (fun->basemode) {
++		u32 mask = 0;
++
++		for (i = 0; i < grp->num_pins; i++) {
++			pin = grp->pins[i];
++			if (pin < 32)
++				mask |= BIT(pin);
++		}
++
++		bcm6368_rmw_mux(pctl, pctl->mode, mask, 0);
++		regmap_field_write(pctl->overlay, fun->basemode);
++	} else {
++		pin = grp->pins[0];
++
++		if (bcm6368_pins[pin].drv_data)
++			regmap_field_write(pctl->overlay,
++					   BCM6368_BASEMODE_GPIO);
++
++		bcm6368_rmw_mux(pctl, pctl->mode, BIT(pin), BIT(pin));
++	}
++	spin_unlock_irqrestore(&pctl->lock, flags);
++
++	for (pin = 0; pin < grp->num_pins; pin++) {
++		int hw_gpio = bcm6368_pins[pin].number;
++		struct gpio_chip *gc = &pctl->gpio[hw_gpio / 32];
++
++		if (fun->dir_out & BIT(pin))
++			gc->direction_output(gc, hw_gpio % 32, 0);
++		else
++			gc->direction_input(gc, hw_gpio % 32);
++	}
++
++	return 0;
++}
++
++static int bcm6368_gpio_request_enable(struct pinctrl_dev *pctldev,
++				       struct pinctrl_gpio_range *range,
++				       unsigned offset)
++{
++	struct bcm6368_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
++	unsigned long flags;
++
++	if (offset >= 32 && !bcm6368_pins[offset].drv_data)
++		return 0;
++
++	spin_lock_irqsave(&pctl->lock, flags);
++	/* disable all functions using this pin */
++	if (offset < 32)
++		bcm6368_rmw_mux(pctl, pctl->mode, BIT(offset), 0);
++
++	if (bcm6368_pins[offset].drv_data)
++		regmap_field_write(pctl->overlay, BCM6368_BASEMODE_GPIO);
++
++	spin_unlock_irqrestore(&pctl->lock, flags);
++
++	return 0;
++}
++
++static struct pinctrl_ops bcm6368_pctl_ops = {
++	.get_groups_count	= bcm6368_pinctrl_get_group_count,
++	.get_group_name		= bcm6368_pinctrl_get_group_name,
++	.get_group_pins		= bcm6368_pinctrl_get_group_pins,
++#ifdef CONFIG_OF
++	.dt_node_to_map		= pinconf_generic_dt_node_to_map_pin,
++	.dt_free_map		= pinctrl_utils_free_map,
++#endif
++};
++
++static struct pinmux_ops bcm6368_pmx_ops = {
++	.get_functions_count	= bcm6368_pinctrl_get_func_count,
++	.get_function_name	= bcm6368_pinctrl_get_func_name,
++	.get_function_groups	= bcm6368_pinctrl_get_groups,
++	.set_mux		= bcm6368_pinctrl_set_mux,
++	.gpio_request_enable	= bcm6368_gpio_request_enable,
++	.strict			= true,
++};
++
++static int bcm6368_pinctrl_probe(struct platform_device *pdev)
++{
++	struct bcm6368_pinctrl *pctl;
++	struct resource *res;
++	void __iomem *mode;
++	struct regmap *basemode;
++	struct reg_field overlay = REG_FIELD(0, 0, 3);
++
++	if (pdev->dev.of_node)
++		basemode = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
++							   "brcm,gpiobasemode");
++	else
++		basemode = syscon_regmap_lookup_by_pdevname("syscon.b00000b8");
++
++	if (IS_ERR(basemode))
++		return PTR_ERR(basemode);
++
++	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mode");
++	mode = devm_ioremap_resource(&pdev->dev, res);
++	if (IS_ERR(mode))
++		return PTR_ERR(mode);
++
++	pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL);
++	if (!pctl)
++		return -ENOMEM;
++
++	pctl->overlay = devm_regmap_field_alloc(&pdev->dev, mode, overlay);
++	if (IS_ERR(pctl->overlay))
++		return PTR_ERR(pctl->overlay);
++
++	spin_lock_init(&pctl->lock);
++
++	pctl->mode = mode;
++
++	/* disable all muxes by default */
++	__raw_writel(0, pctl->mode);
++
++	pctl->desc.name = dev_name(&pdev->dev);
++	pctl->desc.owner = THIS_MODULE;
++	pctl->desc.pctlops = &bcm6368_pctl_ops;
++	pctl->desc.pmxops = &bcm6368_pmx_ops;
++
++	pctl->desc.npins = ARRAY_SIZE(bcm6368_pins);
++	pctl->desc.pins = bcm6368_pins;
++
++	platform_set_drvdata(pdev, pctl);
++
++	pctl->pctldev = bcm63xx_pinctrl_register(pdev, &pctl->desc, pctl,
++						 pctl->gpio, BCM6368_NGPIO);
++	if (IS_ERR(pctl->pctldev))
++		return PTR_ERR(pctl->pctldev);
++
++	return 0;
++}
++
++static const struct of_device_id bcm6368_pinctrl_match[] = {
++	{ .compatible = "brcm,bcm6368-pinctrl", },
++	{ },
++};
++
++static struct platform_driver bcm6368_pinctrl_driver = {
++	.probe = bcm6368_pinctrl_probe,
++	.driver = {
++		.name = "bcm6368-pinctrl",
++		.of_match_table = bcm6368_pinctrl_match,
++	},
++};
++
++builtin_platform_driver(bcm6368_pinctrl_driver);
diff --git a/target/linux/brcm63xx/patches-4.4/141-Documentation-add-BCM63268-pincontroller-binding-doc.patch b/target/linux/brcm63xx/patches-4.4/141-Documentation-add-BCM63268-pincontroller-binding-doc.patch
new file mode 100644
index 0000000..ffe842f
--- /dev/null
+++ b/target/linux/brcm63xx/patches-4.4/141-Documentation-add-BCM63268-pincontroller-binding-doc.patch
@@ -0,0 +1,106 @@
+From 28cc80e4ada5d73d5305fd268297825cd8d01936 Mon Sep 17 00:00:00 2001
+From: Jonas Gorski <jonas.gorski at gmail.com>
+Date: Wed, 27 Jul 2016 11:37:08 +0200
+Subject: [PATCH 12/16] Documentation: add BCM63268 pincontroller binding
+ documentation
+
+Add binding documentation for the pincontrol core found in the BCM63268
+family SoCs.
+
+Signed-off-by: Jonas Gorski <jonas.gorski at gmail.com>
+---
+ .../bindings/pinctrl/brcm,bcm63268-pinctrl.txt     | 88 ++++++++++++++++++++++
+ 1 file changed, 88 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm63268-pinctrl.txt
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm63268-pinctrl.txt
+@@ -0,0 +1,88 @@
++* Broadcom BCM63268 pin controller
++
++Required properties:
++- compatible: Must be "brcm,bcm6362-pinctrl".
++- reg: Register specifiers of dirout, dat, led, mode, ctrl, basemode registers.
++- reg-names: Must be "dirout", "dat", "led", "mode", "ctrl", "basemode".
++- gpio-controller: Identifies this node as a GPIO controller.
++- #gpio-cells: Must be <2>.
++
++Example:
++
++pinctrl: pin-controller at 100000c0 {
++	compatible = "brcm,bcm63268-pinctrl";
++	reg = <0x100000c0 0x8>,
++	      <0x100000c8 0x8>,
++	      <0x100000d0 0x4>,
++	      <0x100000d8 0x4>,
++	      <0x100000dc 0x4>,
++	      <0x100000f8 0x4>;
++	reg-names = "dirout", "dat", "led", "mode",
++		    "ctrl", "basemode";
++
++	gpio-controller;
++	#gpio-cells = <2>;
++};
++
++Available pins/groups and functions:
++
++name		pins		functions
++-----------------------------------------------------------
++gpio0		0		led, serial_led_clk
++gpio1		1		led, serial_led_data
++gpio2		2		led,
++gpio3		3		led,
++gpio4		4		led,
++gpio5		5		led,
++gpio6		6		led,
++gpio7		7		led,
++gpio8		8		led, hsspi_cs6
++gpio9		9		led, hsspi_cs7
++gpio10		10		led, uart1_scts
++gpio11		11		led, uart1_srts
++gpio12		12		led, uart1_sdin
++gpio13		13		led, uart1_sdout
++gpio14		14		led, ntr_pulse_in
++gpio15		15		led, dsl_ntr_pulse_out
++gpio16		16		led, hsspi_cs4
++gpio17		17		led, hsspi_cs5
++gpio18		18		led, adsl_spi_miso
++gpio19		19		led, adsl_spi_mosi
++gpio20		20		led,
++gpio21		21		led,
++gpio22		22		led, vreg_clk
++gpio23		23		led, pcie_clkreq_b
++gpio24		24		uart1_scts
++gpio25		25		uart1_srts
++gpio26		26		uart1_sdin
++gpio27		27		uart1_sdout
++gpio28		28		ntr_pulse_in
++gpio29		29		dsl_ntr_pulse_out
++gpio30		30		switch_led_clk
++gpio31		31		switch_led_data
++gpio32		32		wifi
++gpio33		33		wifi
++gpio34		34		wifi
++gpio35		35		wifi
++gpio36		36		wifi
++gpio37		37		wifi
++gpio38		38		wifi
++gpio39		39		wifi
++gpio40		40		wifi
++gpio41		41		wifi
++gpio42		42		wifi
++gpio43		43		wifi
++gpio44		44		wifi
++gpio45		45		wifi
++gpio46		46		wifi
++gpio47		47		wifi
++gpio48		48		wifi
++gpio49		49		wifi
++gpio50		50		wifi
++gpio51		51		wifi
++nand_grp	2-7,24-31	nand
++dect_pd_grp	8-9		dect_pd
++vdsl_phy0_grp	10-11		vdsl_phy0
++vdsl_phy1_grp	12-13		vdsl_phy1
++vdsl_phy2_grp	24-25		vdsl_phy2
++vdsl_phy3_grp	26-27		vdsl_phy3
diff --git a/target/linux/brcm63xx/patches-4.4/142-pinctrl-add-a-pincontrol-driver-for-BCM63268.patch b/target/linux/brcm63xx/patches-4.4/142-pinctrl-add-a-pincontrol-driver-for-BCM63268.patch
new file mode 100644
index 0000000..089d14e
--- /dev/null
+++ b/target/linux/brcm63xx/patches-4.4/142-pinctrl-add-a-pincontrol-driver-for-BCM63268.patch
@@ -0,0 +1,736 @@
+From 8665d3ea63649cc155286c75f83f694a930580e5 Mon Sep 17 00:00:00 2001
+From: Jonas Gorski <jonas.gorski at gmail.com>
+Date: Fri, 24 Jun 2016 22:19:12 +0200
+Subject: [PATCH 13/16] pinctrl: add a pincontrol driver for BCM63268
+
+Add a pincontrol driver for BCM63268. BCM63268 allows muxing GPIOs
+to different functions. Depending on the mux, these are either single
+pin configurations or whole pin groups.
+
+Signed-off-by: Jonas Gorski <jonas.gorski at gmail.com>
+---
+ drivers/pinctrl/bcm63xx/Makefile           |   1 +
+ drivers/pinctrl/bcm63xx/pinctrl-bcm63268.c | 710 +++++++++++++++++++++++++++++
+ 2 files changed, 711 insertions(+)
+ create mode 100644 drivers/pinctrl/bcm63xx/pinctrl-bcm63268.c
+
+--- a/drivers/pinctrl/bcm63xx/Makefile
++++ b/drivers/pinctrl/bcm63xx/Makefile
+@@ -4,3 +4,4 @@ obj-$(CONFIG_PINCTRL_BCM6348)	+= pinctrl
+ obj-$(CONFIG_PINCTRL_BCM6358)	+= pinctrl-bcm6358.o
+ obj-$(CONFIG_PINCTRL_BCM6362)	+= pinctrl-bcm6362.o
+ obj-$(CONFIG_PINCTRL_BCM6368)	+= pinctrl-bcm6368.o
++obj-$(CONFIG_PINCTRL_BCM63268)	+= pinctrl-bcm63268.o
+--- /dev/null
++++ b/drivers/pinctrl/bcm63xx/pinctrl-bcm63268.c
+@@ -0,0 +1,710 @@
++/*
++ * This file is subject to the terms and conditions of the GNU General Public
++ * License.  See the file "COPYING" in the main directory of this archive
++ * for more details.
++ *
++ * Copyright (C) 2016 Jonas Gorski <jonas.gorski at gmail.com>
++ */
++
++#include <linux/kernel.h>
++#include <linux/spinlock.h>
++#include <linux/bitops.h>
++#include <linux/gpio.h>
++#include <linux/of.h>
++#include <linux/of_gpio.h>
++#include <linux/slab.h>
++#include <linux/platform_device.h>
++
++#include <linux/pinctrl/pinconf.h>
++#include <linux/pinctrl/pinconf-generic.h>
++#include <linux/pinctrl/pinmux.h>
++#include <linux/pinctrl/machine.h>
++
++#include "../core.h"
++#include "../pinctrl-utils.h"
++
++#include "pinctrl-bcm63xx.h"
++
++#define BCM63268_NGPIO			52
++
++/* GPIO_BASEMODE register */
++#define BASEMODE_NAND			BIT(2) /* GPIOs 2-7, 24-31 */
++#define BASEMODE_GPIO35			BIT(4) /* GPIO 35 */
++#define BASEMODE_DECTPD			BIT(5) /* GPIOs 8/9 */
++#define BASEMODE_VDSL_PHY_0		BIT(6) /* GPIOs 10/11 */
++#define BASEMODE_VDSL_PHY_1		BIT(7) /* GPIOs 12/13 */
++#define BASEMODE_VDSL_PHY_2		BIT(8) /* GPIOs 24/25 */
++#define BASEMODE_VDSL_PHY_3		BIT(9) /* GPIOs 26/27 */
++
++enum bcm63268_pinctrl_reg {
++	BCM63268_LEDCTRL,
++	BCM63268_MODE,
++	BCM63268_CTRL,
++	BCM63268_BASEMODE,
++};
++
++struct bcm63268_pingroup {
++	const char *name;
++	const unsigned * const pins;
++	const unsigned num_pins;
++};
++
++struct bcm63268_function {
++	const char *name;
++	const char * const *groups;
++	const unsigned num_groups;
++
++	enum bcm63268_pinctrl_reg reg;
++	u32 mask;
++};
++
++struct bcm63268_pinctrl {
++	struct pinctrl_dev *pctldev;
++	struct pinctrl_desc desc;
++
++	void __iomem *led;
++	void __iomem *mode;
++	void __iomem *ctrl;
++	void __iomem *basemode;
++
++	/* register access lock */
++	spinlock_t lock;
++
++	struct gpio_chip gpio[2];
++};
++
++#define BCM63268_PIN(a, b, basemode)			\
++	{						\
++		.number = a,				\
++		.name = b,				\
++		.drv_data = (void *)(basemode)		\
++	}
++
++static const struct pinctrl_pin_desc bcm63268_pins[] = {
++	PINCTRL_PIN(0, "gpio0"),
++	PINCTRL_PIN(1, "gpio1"),
++	BCM63268_PIN(2, "gpio2", BASEMODE_NAND),
++	BCM63268_PIN(3, "gpio3", BASEMODE_NAND),
++	BCM63268_PIN(4, "gpio4", BASEMODE_NAND),
++	BCM63268_PIN(5, "gpio5", BASEMODE_NAND),
++	BCM63268_PIN(6, "gpio6", BASEMODE_NAND),
++	BCM63268_PIN(7, "gpio7", BASEMODE_NAND),
++	BCM63268_PIN(8, "gpio8", BASEMODE_DECTPD),
++	BCM63268_PIN(9, "gpio9", BASEMODE_DECTPD),
++	BCM63268_PIN(10, "gpio10", BASEMODE_VDSL_PHY_0),
++	BCM63268_PIN(11, "gpio11", BASEMODE_VDSL_PHY_0),
++	BCM63268_PIN(12, "gpio12", BASEMODE_VDSL_PHY_1),
++	BCM63268_PIN(13, "gpio13", BASEMODE_VDSL_PHY_1),
++	PINCTRL_PIN(14, "gpio14"),
++	PINCTRL_PIN(15, "gpio15"),
++	PINCTRL_PIN(16, "gpio16"),
++	PINCTRL_PIN(17, "gpio17"),
++	PINCTRL_PIN(18, "gpio18"),
++	PINCTRL_PIN(19, "gpio19"),
++	PINCTRL_PIN(20, "gpio20"),
++	PINCTRL_PIN(21, "gpio21"),
++	PINCTRL_PIN(22, "gpio22"),
++	PINCTRL_PIN(23, "gpio23"),
++	BCM63268_PIN(24, "gpio24", BASEMODE_NAND | BASEMODE_VDSL_PHY_2),
++	BCM63268_PIN(25, "gpio25", BASEMODE_NAND | BASEMODE_VDSL_PHY_2),
++	BCM63268_PIN(26, "gpio26", BASEMODE_NAND | BASEMODE_VDSL_PHY_3),
++	BCM63268_PIN(27, "gpio27", BASEMODE_NAND | BASEMODE_VDSL_PHY_3),
++	BCM63268_PIN(28, "gpio28", BASEMODE_NAND),
++	BCM63268_PIN(29, "gpio29", BASEMODE_NAND),
++	BCM63268_PIN(30, "gpio30", BASEMODE_NAND),
++	BCM63268_PIN(31, "gpio31", BASEMODE_NAND),
++	PINCTRL_PIN(32, "gpio32"),
++	PINCTRL_PIN(33, "gpio33"),
++	PINCTRL_PIN(34, "gpio34"),
++	PINCTRL_PIN(35, "gpio35"),
++	PINCTRL_PIN(36, "gpio36"),
++	PINCTRL_PIN(37, "gpio37"),
++	PINCTRL_PIN(38, "gpio38"),
++	PINCTRL_PIN(39, "gpio39"),
++	PINCTRL_PIN(40, "gpio40"),
++	PINCTRL_PIN(41, "gpio41"),
++	PINCTRL_PIN(42, "gpio42"),
++	PINCTRL_PIN(43, "gpio43"),
++	PINCTRL_PIN(44, "gpio44"),
++	PINCTRL_PIN(45, "gpio45"),
++	PINCTRL_PIN(46, "gpio46"),
++	PINCTRL_PIN(47, "gpio47"),
++	PINCTRL_PIN(48, "gpio48"),
++	PINCTRL_PIN(49, "gpio49"),
++	PINCTRL_PIN(50, "gpio50"),
++	PINCTRL_PIN(51, "gpio51"),
++};
++
++static unsigned gpio0_pins[] = { 0 };
++static unsigned gpio1_pins[] = { 1 };
++static unsigned gpio2_pins[] = { 2 };
++static unsigned gpio3_pins[] = { 3 };
++static unsigned gpio4_pins[] = { 4 };
++static unsigned gpio5_pins[] = { 5 };
++static unsigned gpio6_pins[] = { 6 };
++static unsigned gpio7_pins[] = { 7 };
++static unsigned gpio8_pins[] = { 8 };
++static unsigned gpio9_pins[] = { 9 };
++static unsigned gpio10_pins[] = { 10 };
++static unsigned gpio11_pins[] = { 11 };
++static unsigned gpio12_pins[] = { 12 };
++static unsigned gpio13_pins[] = { 13 };
++static unsigned gpio14_pins[] = { 14 };
++static unsigned gpio15_pins[] = { 15 };
++static unsigned gpio16_pins[] = { 16 };
++static unsigned gpio17_pins[] = { 17 };
++static unsigned gpio18_pins[] = { 18 };
++static unsigned gpio19_pins[] = { 19 };
++static unsigned gpio20_pins[] = { 20 };
++static unsigned gpio21_pins[] = { 21 };
++static unsigned gpio22_pins[] = { 22 };
++static unsigned gpio23_pins[] = { 23 };
++static unsigned gpio24_pins[] = { 24 };
++static unsigned gpio25_pins[] = { 25 };
++static unsigned gpio26_pins[] = { 26 };
++static unsigned gpio27_pins[] = { 27 };
++static unsigned gpio28_pins[] = { 28 };
++static unsigned gpio29_pins[] = { 29 };
++static unsigned gpio30_pins[] = { 30 };
++static unsigned gpio31_pins[] = { 31 };
++static unsigned gpio32_pins[] = { 32 };
++static unsigned gpio33_pins[] = { 33 };
++static unsigned gpio34_pins[] = { 34 };
++static unsigned gpio35_pins[] = { 35 };
++static unsigned gpio36_pins[] = { 36 };
++static unsigned gpio37_pins[] = { 37 };
++static unsigned gpio38_pins[] = { 38 };
++static unsigned gpio39_pins[] = { 39 };
++static unsigned gpio40_pins[] = { 40 };
++static unsigned gpio41_pins[] = { 41 };
++static unsigned gpio42_pins[] = { 42 };
++static unsigned gpio43_pins[] = { 43 };
++static unsigned gpio44_pins[] = { 44 };
++static unsigned gpio45_pins[] = { 45 };
++static unsigned gpio46_pins[] = { 46 };
++static unsigned gpio47_pins[] = { 47 };
++static unsigned gpio48_pins[] = { 48 };
++static unsigned gpio49_pins[] = { 49 };
++static unsigned gpio50_pins[] = { 50 };
++static unsigned gpio51_pins[] = { 51 };
++
++static unsigned nand_grp_pins[] = {
++	2, 3, 4, 5, 6, 7, 24,
++	25, 26, 27, 28, 29, 30, 31,
++};
++
++static unsigned dectpd_grp_pins[] = { 8, 9 };
++static unsigned vdsl_phy0_grp_pins[] = { 10, 11 };
++static unsigned vdsl_phy1_grp_pins[] = { 12, 13 };
++static unsigned vdsl_phy2_grp_pins[] = { 24, 25 };
++static unsigned vdsl_phy3_grp_pins[] = { 26, 27 };
++
++#define BCM63268_GROUP(n)					\
++	{							\
++		.name = #n,					\
++		.pins = n##_pins,				\
++		.num_pins = ARRAY_SIZE(n##_pins),		\
++	}
++
++static struct bcm63268_pingroup bcm63268_groups[] = {
++	BCM63268_GROUP(gpio0),
++	BCM63268_GROUP(gpio1),
++	BCM63268_GROUP(gpio2),
++	BCM63268_GROUP(gpio3),
++	BCM63268_GROUP(gpio4),
++	BCM63268_GROUP(gpio5),
++	BCM63268_GROUP(gpio6),
++	BCM63268_GROUP(gpio7),
++	BCM63268_GROUP(gpio8),
++	BCM63268_GROUP(gpio9),
++	BCM63268_GROUP(gpio10),
++	BCM63268_GROUP(gpio11),
++	BCM63268_GROUP(gpio12),
++	BCM63268_GROUP(gpio13),
++	BCM63268_GROUP(gpio14),
++	BCM63268_GROUP(gpio15),
++	BCM63268_GROUP(gpio16),
++	BCM63268_GROUP(gpio17),
++	BCM63268_GROUP(gpio18),
++	BCM63268_GROUP(gpio19),
++	BCM63268_GROUP(gpio20),
++	BCM63268_GROUP(gpio21),
++	BCM63268_GROUP(gpio22),
++	BCM63268_GROUP(gpio23),
++	BCM63268_GROUP(gpio24),
++	BCM63268_GROUP(gpio25),
++	BCM63268_GROUP(gpio26),
++	BCM63268_GROUP(gpio27),
++	BCM63268_GROUP(gpio28),
++	BCM63268_GROUP(gpio29),
++	BCM63268_GROUP(gpio30),
++	BCM63268_GROUP(gpio31),
++	BCM63268_GROUP(gpio32),
++	BCM63268_GROUP(gpio33),
++	BCM63268_GROUP(gpio34),
++	BCM63268_GROUP(gpio35),
++	BCM63268_GROUP(gpio36),
++	BCM63268_GROUP(gpio37),
++	BCM63268_GROUP(gpio38),
++	BCM63268_GROUP(gpio39),
++	BCM63268_GROUP(gpio40),
++	BCM63268_GROUP(gpio41),
++	BCM63268_GROUP(gpio42),
++	BCM63268_GROUP(gpio43),
++	BCM63268_GROUP(gpio44),
++	BCM63268_GROUP(gpio45),
++	BCM63268_GROUP(gpio46),
++	BCM63268_GROUP(gpio47),
++	BCM63268_GROUP(gpio48),
++	BCM63268_GROUP(gpio49),
++	BCM63268_GROUP(gpio50),
++	BCM63268_GROUP(gpio51),
++
++	/* multi pin groups */
++	BCM63268_GROUP(nand_grp),
++	BCM63268_GROUP(dectpd_grp),
++	BCM63268_GROUP(vdsl_phy0_grp),
++	BCM63268_GROUP(vdsl_phy1_grp),
++	BCM63268_GROUP(vdsl_phy2_grp),
++	BCM63268_GROUP(vdsl_phy3_grp),
++};
++
++static const char * const led_groups[] = {
++	"gpio0",
++	"gpio1",
++	"gpio2",
++	"gpio3",
++	"gpio4",
++	"gpio5",
++	"gpio6",
++	"gpio7",
++	"gpio8",
++	"gpio9",
++	"gpio10",
++	"gpio11",
++	"gpio12",
++	"gpio13",
++	"gpio14",
++	"gpio15",
++	"gpio16",
++	"gpio17",
++	"gpio18",
++	"gpio19",
++	"gpio20",
++	"gpio21",
++	"gpio22",
++	"gpio23",
++};
++
++static const char * const serial_led_clk_groups[] = {
++	"gpio0",
++};
++
++static const char * const serial_led_data_groups[] = {
++	"gpio1",
++};
++
++static const char * const hsspi_cs4_groups[] = {
++	"gpio16",
++};
++
++static const char * const hsspi_cs5_groups[] = {
++	"gpio17",
++};
++
++static const char * const hsspi_cs6_groups[] = {
++	"gpio8",
++};
++
++static const char * const hsspi_cs7_groups[] = {
++	"gpio9",
++};
++
++static const char * const uart1_scts_groups[] = {
++	"gpio10",
++	"gpio24",
++};
++
++static const char * const uart1_srts_groups[] = {
++	"gpio11",
++	"gpio25",
++};
++
++static const char * const uart1_sdin_groups[] = {
++	"gpio12",
++	"gpio26",
++};
++
++static const char * const uart1_sdout_groups[] = {
++	"gpio13",
++	"gpio27",
++};
++
++static const char * const ntr_pulse_in_groups[] = {
++	"gpio14",
++	"gpio28",
++};
++
++static const char * const dsl_ntr_pulse_out_groups[] = {
++	"gpio15",
++	"gpio29",
++};
++
++static const char * const adsl_spi_miso_groups[] = {
++	"gpio18",
++};
++
++static const char * const adsl_spi_mosi_groups[] = {
++	"gpio19",
++};
++
++static const char * const vreg_clk_groups[] = {
++	"gpio22",
++};
++
++static const char * const pcie_clkreq_b_groups[] = {
++	"gpio23",
++};
++
++static const char * const switch_led_clk_groups[] = {
++	"gpio30",
++};
++
++static const char * const switch_led_data_groups[] = {
++	"gpio31",
++};
++
++static const char * const wifi_groups[] = {
++	"gpio32",
++	"gpio33",
++	"gpio34",
++	"gpio35",
++	"gpio36",
++	"gpio37",
++	"gpio38",
++	"gpio39",
++	"gpio40",
++	"gpio41",
++	"gpio42",
++	"gpio43",
++	"gpio44",
++	"gpio45",
++	"gpio46",
++	"gpio47",
++	"gpio48",
++	"gpio49",
++	"gpio50",
++	"gpio51",
++};
++
++static const char * const nand_groups[] = {
++	"nand_grp",
++};
++
++static const char * const dectpd_groups[] = {
++	"dectpd_grp",
++};
++
++static const char * const vdsl_phy_override_0_groups[] = {
++	"vdsl_phy_override_0_grp",
++};
++
++static const char * const vdsl_phy_override_1_groups[] = {
++	"vdsl_phy_override_1_grp",
++};
++
++static const char * const vdsl_phy_override_2_groups[] = {
++	"vdsl_phy_override_2_grp",
++};
++
++static const char * const vdsl_phy_override_3_groups[] = {
++	"vdsl_phy_override_3_grp",
++};
++
++#define BCM63268_LED_FUN(n)				\
++	{						\
++		.name = #n,				\
++		.groups = n##_groups,			\
++		.num_groups = ARRAY_SIZE(n##_groups),	\
++		.reg = BCM63268_LEDCTRL,		\
++	}
++
++#define BCM63268_MODE_FUN(n)				\
++	{						\
++		.name = #n,				\
++		.groups = n##_groups,			\
++		.num_groups = ARRAY_SIZE(n##_groups),	\
++		.reg = BCM63268_MODE,			\
++	}
++
++#define BCM63268_CTRL_FUN(n)				\
++	{						\
++		.name = #n,				\
++		.groups = n##_groups,			\
++		.num_groups = ARRAY_SIZE(n##_groups),	\
++		.reg = BCM63268_CTRL,			\
++	}
++
++#define BCM63268_BASEMODE_FUN(n, val)			\
++	{						\
++		.name = #n,				\
++		.groups = n##_groups,			\
++		.num_groups = ARRAY_SIZE(n##_groups),	\
++		.reg = BCM63268_BASEMODE,		\
++		.mask = val,				\
++	}
++
++static const struct bcm63268_function bcm63268_funcs[] = {
++	BCM63268_LED_FUN(led),
++	BCM63268_MODE_FUN(serial_led_clk),
++	BCM63268_MODE_FUN(serial_led_data),
++	BCM63268_MODE_FUN(hsspi_cs6),
++	BCM63268_MODE_FUN(hsspi_cs7),
++	BCM63268_MODE_FUN(uart1_scts),
++	BCM63268_MODE_FUN(uart1_srts),
++	BCM63268_MODE_FUN(uart1_sdin),
++	BCM63268_MODE_FUN(uart1_sdout),
++	BCM63268_MODE_FUN(ntr_pulse_in),
++	BCM63268_MODE_FUN(dsl_ntr_pulse_out),
++	BCM63268_MODE_FUN(hsspi_cs4),
++	BCM63268_MODE_FUN(hsspi_cs5),
++	BCM63268_MODE_FUN(adsl_spi_miso),
++	BCM63268_MODE_FUN(adsl_spi_mosi),
++	BCM63268_MODE_FUN(vreg_clk),
++	BCM63268_MODE_FUN(pcie_clkreq_b),
++	BCM63268_MODE_FUN(switch_led_clk),
++	BCM63268_MODE_FUN(switch_led_data),
++	BCM63268_CTRL_FUN(wifi),
++	BCM63268_BASEMODE_FUN(nand, BASEMODE_NAND),
++	BCM63268_BASEMODE_FUN(dectpd, BASEMODE_DECTPD),
++	BCM63268_BASEMODE_FUN(vdsl_phy_override_0, BASEMODE_VDSL_PHY_0),
++	BCM63268_BASEMODE_FUN(vdsl_phy_override_1, BASEMODE_VDSL_PHY_1),
++	BCM63268_BASEMODE_FUN(vdsl_phy_override_2, BASEMODE_VDSL_PHY_2),
++	BCM63268_BASEMODE_FUN(vdsl_phy_override_3, BASEMODE_VDSL_PHY_3),
++};
++
++static int bcm63268_pinctrl_get_group_count(struct pinctrl_dev *pctldev)
++{
++	return ARRAY_SIZE(bcm63268_groups);
++}
++
++static const char *bcm63268_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
++						   unsigned group)
++{
++	return bcm63268_groups[group].name;
++}
++
++static int bcm63268_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
++					   unsigned group,
++					   const unsigned **pins,
++					   unsigned *num_pins)
++{
++	*pins = bcm63268_groups[group].pins;
++	*num_pins = bcm63268_groups[group].num_pins;
++
++	return 0;
++}
++
++static int bcm63268_pinctrl_get_func_count(struct pinctrl_dev *pctldev)
++{
++	return ARRAY_SIZE(bcm63268_funcs);
++}
++
++static const char *bcm63268_pinctrl_get_func_name(struct pinctrl_dev *pctldev,
++						  unsigned selector)
++{
++	return bcm63268_funcs[selector].name;
++}
++
++static int bcm63268_pinctrl_get_groups(struct pinctrl_dev *pctldev,
++				       unsigned selector,
++				       const char * const **groups,
++				       unsigned * const num_groups)
++{
++	*groups = bcm63268_funcs[selector].groups;
++	*num_groups = bcm63268_funcs[selector].num_groups;
++
++	return 0;
++}
++
++static void bcm63268_rmw_mux(struct bcm63268_pinctrl *pctl, void __iomem *reg,
++			     u32 mask, u32 val)
++{
++	unsigned long flags;
++	u32 tmp;
++
++	spin_lock_irqsave(&pctl->lock, flags);
++	tmp = __raw_readl(reg);
++	tmp &= ~mask;
++	tmp |= val;
++	__raw_writel(tmp, reg);
++
++	spin_unlock_irqrestore(&pctl->lock, flags);
++}
++
++static void bcm63268_set_gpio(struct bcm63268_pinctrl *pctl, unsigned pin)
++{
++	const struct pinctrl_pin_desc *desc = &bcm63268_pins[pin];
++	u32 basemode = (unsigned long)desc->drv_data;
++	u32 mask = BIT(pin % 32);
++
++	if (basemode)
++		bcm63268_rmw_mux(pctl, pctl->basemode, basemode, 0);
++
++	if (pin < 32) {
++		/* base mode: 0 => gpio, 1 => mux function */
++		bcm63268_rmw_mux(pctl, pctl->mode, mask, 0);
++
++		/* pins 0-23 might be muxed to led */
++		if (pin < 24)
++			bcm63268_rmw_mux(pctl, pctl->led, mask, 0);
++	} else if (pin < 52) {
++		/* ctrl reg: 0 => wifi function, 1 => gpio */
++		bcm63268_rmw_mux(pctl, pctl->ctrl, mask, mask);
++	}
++}
++
++static int bcm63268_pinctrl_set_mux(struct pinctrl_dev *pctldev,
++				    unsigned selector, unsigned group)
++{
++	struct bcm63268_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
++	const struct bcm63268_pingroup *grp = &bcm63268_groups[group];
++	const struct bcm63268_function *f = &bcm63268_funcs[selector];
++	unsigned i;
++	void __iomem *reg;
++	u32 val, mask;
++
++	for (i = 0; i < grp->num_pins; i++)
++		bcm63268_set_gpio(pctl, grp->pins[i]);
++
++	switch (f->reg) {
++	case BCM63268_LEDCTRL:
++		reg = pctl->led;
++		mask = BIT(grp->pins[0]);
++		val = BIT(grp->pins[0]);
++		break;
++	case BCM63268_MODE:
++		reg = pctl->mode;
++		mask = BIT(grp->pins[0]);
++		val = BIT(grp->pins[0]);
++		break;
++	case BCM63268_CTRL:
++		reg = pctl->ctrl;
++		mask = BIT(grp->pins[0]);
++		val = 0;
++		break;
++	case BCM63268_BASEMODE:
++		reg = pctl->basemode;
++		mask = f->mask;
++		val = f->mask;
++		break;
++	default:
++		WARN_ON(1);
++		return -EINVAL;
++	}
++
++	bcm63268_rmw_mux(pctl, reg, mask, val);
++
++	return 0;
++}
++
++static int bcm63268_gpio_request_enable(struct pinctrl_dev *pctldev,
++					struct pinctrl_gpio_range *range,
++					unsigned offset)
++{
++	struct bcm63268_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
++
++	/* disable all functions using this pin */
++	bcm63268_set_gpio(pctl, offset);
++
++	return 0;
++}
++
++static struct pinctrl_ops bcm63268_pctl_ops = {
++	.get_groups_count	= bcm63268_pinctrl_get_group_count,
++	.get_group_name		= bcm63268_pinctrl_get_group_name,
++	.get_group_pins		= bcm63268_pinctrl_get_group_pins,
++#ifdef CONFIG_OF
++	.dt_node_to_map		= pinconf_generic_dt_node_to_map_pin,
++	.dt_free_map		= pinctrl_utils_free_map,
++#endif
++};
++
++static struct pinmux_ops bcm63268_pmx_ops = {
++	.get_functions_count	= bcm63268_pinctrl_get_func_count,
++	.get_function_name	= bcm63268_pinctrl_get_func_name,
++	.get_function_groups	= bcm63268_pinctrl_get_groups,
++	.set_mux		= bcm63268_pinctrl_set_mux,
++	.gpio_request_enable	= bcm63268_gpio_request_enable,
++	.strict			= true,
++};
++
++static int bcm63268_pinctrl_probe(struct platform_device *pdev)
++{
++	struct bcm63268_pinctrl *pctl;
++	struct resource *res;
++	void __iomem *led, *mode, *ctrl, *basemode;
++
++	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "led");
++	led = devm_ioremap_resource(&pdev->dev, res);
++	if (IS_ERR(led))
++		return PTR_ERR(led);
++
++	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mode");
++	mode = devm_ioremap_resource(&pdev->dev, res);
++	if (IS_ERR(mode))
++		return PTR_ERR(mode);
++
++	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ctrl");
++	ctrl = devm_ioremap_resource(&pdev->dev, res);
++	if (IS_ERR(ctrl))
++		return PTR_ERR(ctrl);
++
++	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "basemode");
++	basemode = devm_ioremap_resource(&pdev->dev, res);
++	if (IS_ERR(basemode))
++		return PTR_ERR(basemode);
++
++	pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL);
++	if (!pctl)
++		return -ENOMEM;
++
++	spin_lock_init(&pctl->lock);
++
++	pctl->led = led;
++	pctl->mode = mode;
++	pctl->ctrl = ctrl;
++	pctl->basemode = basemode;
++
++	pctl->desc.name = dev_name(&pdev->dev);
++	pctl->desc.owner = THIS_MODULE;
++	pctl->desc.pctlops = &bcm63268_pctl_ops;
++	pctl->desc.pmxops = &bcm63268_pmx_ops;
++
++	pctl->desc.npins = ARRAY_SIZE(bcm63268_pins);
++	pctl->desc.pins = bcm63268_pins;
++
++	platform_set_drvdata(pdev, pctl);
++
++	pctl->pctldev = bcm63xx_pinctrl_register(pdev, &pctl->desc, pctl,
++						 pctl->gpio, BCM63268_NGPIO);
++	if (IS_ERR(pctl->pctldev))
++		return PTR_ERR(pctl->pctldev);
++
++	return 0;
++}
++
++static const struct of_device_id bcm63268_pinctrl_match[] = {
++	{ .compatible = "brcm,bcm63268-pinctrl", },
++	{ },
++};
++
++static struct platform_driver bcm63268_pinctrl_driver = {
++	.probe = bcm63268_pinctrl_probe,
++	.driver = {
++		.name = "bcm63268-pinctrl",
++		.of_match_table = bcm63268_pinctrl_match,
++	},
++};
++
++builtin_platform_driver(bcm63268_pinctrl_driver);
diff --git a/target/linux/brcm63xx/patches-4.4/378-MIPS-BCM63XX-do-not-register-gpio-controller-if-pres.patch b/target/linux/brcm63xx/patches-4.4/378-MIPS-BCM63XX-do-not-register-gpio-controller-if-pres.patch
index af6eaff..6eb1bd0 100644
--- a/target/linux/brcm63xx/patches-4.4/378-MIPS-BCM63XX-do-not-register-gpio-controller-if-pres.patch
+++ b/target/linux/brcm63xx/patches-4.4/378-MIPS-BCM63XX-do-not-register-gpio-controller-if-pres.patch
@@ -20,13 +20,14 @@ Signed-off-by: Jonas Gorski <jogo at openwrt.org>
  static const char * const gpio_chip_labels[] = {
  	"bcm63xx-gpio.0",
  	"bcm63xx-gpio.1",
-@@ -48,8 +50,9 @@ static void __init bcm63xx_gpio_init_one
+@@ -48,8 +50,10 @@ static void __init bcm63xx_gpio_init_one
  	pdata.base = id * 32;
  	pdata.ngpio = ngpio;
  
 -	platform_device_register_resndata(NULL, "bcm63xx-gpio", id, res, 2,
 -					  &pdata, sizeof(pdata));
-+	if (!board_of_device_present("gpio0"))
++	if (!board_of_device_present("gpio0") &&
++	    !board_of_device_present("pinctrl"))
 +		platform_device_register_resndata(NULL, "bcm63xx-gpio", id, res,
 +						  2, &pdata, sizeof(pdata));
  }
diff --git a/target/linux/brcm63xx/patches-4.4/381-Documentation-add-BCM6318-pincontroller-binding-docu.patch b/target/linux/brcm63xx/patches-4.4/381-Documentation-add-BCM6318-pincontroller-binding-docu.patch
new file mode 100644
index 0000000..5d4265f
--- /dev/null
+++ b/target/linux/brcm63xx/patches-4.4/381-Documentation-add-BCM6318-pincontroller-binding-docu.patch
@@ -0,0 +1,96 @@
+From 8439e5d2e69f54a532bb5f8ec001b4b5a3035574 Mon Sep 17 00:00:00 2001
+From: Jonas Gorski <jonas.gorski at gmail.com>
+Date: Wed, 27 Jul 2016 11:38:05 +0200
+Subject: [PATCH 14/16] Documentation: add BCM6318 pincontroller binding
+ documentation
+
+Add binding documentation for the pincontrol core found in BCM6318 SoCs.
+
+Signed-off-by: Jonas Gorski <jonas.gorski at gmail.com>
+---
+ .../bindings/pinctrl/brcm,bcm6318-pinctrl.txt      | 79 ++++++++++++++++++++++
+ 1 file changed, 79 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6318-pinctrl.txt
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6318-pinctrl.txt
+@@ -0,0 +1,79 @@
++* Broadcom BCM6318 pin controller
++
++Required properties:
++- compatible: Must be "brcm,bcm6318-pinctrl".
++- regs: Register specifiers of dirout, dat, mode, mux, and pad registers.
++- reg-names: Must be "dirout", "dat", "mode", "mux", "pad".
++- gpio-controller: Identifies this node as a gpio controller.
++- #gpio-cells: Must be <2>.
++
++Example:
++
++pinctrl: pin-controller at 10000080 {
++	compatible = "brcm,bcm6318-pinctrl";
++	reg = <0x10000080 0x08>,
++	      <0x10000088 0x08>,
++	      <0x10000098 0x04>,
++	      <0x1000009c 0x0c>,
++	      <0x100000d4 0x18>;
++	reg-names = "dirout", "dat", "mode", "mux", "pad";
++
++	gpio-controller;
++	#gpio-cells = <2>;
++};
++
++
++Available pins/groups and functions:
++
++name		pins	functions
++-----------------------------------------------------------
++gpio0		0	led, ephy0_spd_led
++gpio1		1	led, ephy1_spd_led
++gpio2		2	led, ephy2_spd_led
++gpio3		3	led, ephy3_spd_led
++gpio4		4	led, ephy0_act_led
++gpio5		5	led, ephy1_act_led
++gpio6		6	led, ephy2_act_led, serial_led_data
++gpio7		7	led, ephy3_act_led, serial_led_clk
++gpio8		8	led, inet_act_led
++gpio9		9	led, inet_fail_led
++gpio10		10	led, dsl_led
++gpio11		11	led, post_fail_led
++gpio12		12	led, wlan_wps_led
++gpio13		13	led, usb_pwron, usb_device_led
++gpio14		14	led
++gpio15		15	led
++gpio16		16	led
++gpio17		17	led
++gpio18		18	led
++gpio19		19	led
++gpio20		20	led
++gpio21		21	led
++gpio22		22	led
++gpio23		23	led
++gpio24		24	-
++gpio25		25	-
++gpio26		26	-
++gpio27		27	-
++gpio28		28	-
++gpio29		29	-
++gpio30		30	-
++gpio31		31	-
++gpio32		32	-
++gpio33		33	-
++gpio34		34	-
++gpio35		35	-
++gpio36		36	-
++gpio37		37	-
++gpio38		38	-
++gpio39		39	-
++gpio40		40	usb_active
++gpio41		41	-
++gpio42		42	-
++gpio43		43	-
++gpio44		44	-
++gpio45		45	-
++gpio46		46	-
++gpio47		47	-
++gpio48		48	-
++gpio49		49	-
diff --git a/target/linux/brcm63xx/patches-4.4/382-brcm63xx-setup-pinctrl-for-internal-switch-leds-on-b.patch b/target/linux/brcm63xx/patches-4.4/382-brcm63xx-setup-pinctrl-for-internal-switch-leds-on-b.patch
deleted file mode 100644
index 83e1ddc..0000000
--- a/target/linux/brcm63xx/patches-4.4/382-brcm63xx-setup-pinctrl-for-internal-switch-leds-on-b.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From 8940437e017d446d61a035e847c2a1d7a57a4354 Mon Sep 17 00:00:00 2001
-From: Jonas Gorski <jonas.gorski at gmail.com>
-Date: Wed, 1 Feb 2017 12:17:13 +0100
-Subject: [PATCH] brcm63xx: setup pinctrl for internal switch leds on bcm6368
-
----
- arch/mips/bcm63xx/boards/board_common.c | 9 +++++++++
- 1 file changed, 9 insertions(+)
-
---- a/arch/mips/bcm63xx/boards/board_common.c
-+++ b/arch/mips/bcm63xx/boards/board_common.c
-@@ -104,6 +104,15 @@ void __init board_early_setup(const stru
- 				GPIO_MODE_6348_G0_EXT_MII;
- 	}
- 
-+	if (BCMCPU_IS_6368() && board.has_enetsw) {
-+		int i;
-+
-+		for (i = 0; i < 4; i++) {
-+			if (board.enetsw.used_ports[i].used)
-+				val |= (GPIO_MODE_6368_EPHY0_LED << i);
-+		}
-+	}
-+
- 	bcm_gpio_writel(val, GPIO_MODE_REG);
- 
- #if IS_ENABLED(CONFIG_USB)
diff --git a/target/linux/brcm63xx/patches-4.4/382-pinctrl-add-a-pincontrol-driver-for-BCM6318.patch b/target/linux/brcm63xx/patches-4.4/382-pinctrl-add-a-pincontrol-driver-for-BCM6318.patch
new file mode 100644
index 0000000..2a89dde
--- /dev/null
+++ b/target/linux/brcm63xx/patches-4.4/382-pinctrl-add-a-pincontrol-driver-for-BCM6318.patch
@@ -0,0 +1,609 @@
+From bd9c250ef85e6f99aa5d59b21abb87d0a48f2f61 Mon Sep 17 00:00:00 2001
+From: Jonas Gorski <jonas.gorski at gmail.com>
+Date: Fri, 24 Jun 2016 22:20:39 +0200
+Subject: [PATCH 15/16] pinctrl: add a pincontrol driver for BCM6318
+
+Add a pincontrol driver for BCM6318. BCM6318 allows muxing most GPIOs
+to different functions. BCM6318 is similar to BCM6328 with the addition
+of a pad register, and the GPIO meaning of the mux register changes
+based on the GPIO number.
+
+Signed-off-by: Jonas Gorski <jonas.gorski at gmail.com>
+---
+ drivers/pinctrl/bcm63xx/Kconfig           |   7 +
+ drivers/pinctrl/bcm63xx/Makefile          |   1 +
+ drivers/pinctrl/bcm63xx/pinctrl-bcm6318.c | 564 ++++++++++++++++++++++++++++++
+ 3 files changed, 572 insertions(+)
+ create mode 100644 drivers/pinctrl/bcm63xx/pinctrl-bcm6318.c
+
+--- a/drivers/pinctrl/bcm63xx/Kconfig
++++ b/drivers/pinctrl/bcm63xx/Kconfig
+@@ -2,6 +2,13 @@ config PINCTRL_BCM63XX
+ 	bool
+ 	select GPIO_GENERIC
+ 
++config PINCTRL_BCM6318
++	bool "BCM6318 pincontrol driver" if COMPILE_TEST
++	select PINMUX
++	select PINCONF
++	select PINCTRL_BCM63XX
++	select GENERIC_PINCONF
++
+ config PINCTRL_BCM6328
+ 	bool "BCM6328 pincontrol driver" if COMPILE_TEST
+ 	select PINMUX
+--- a/drivers/pinctrl/bcm63xx/Makefile
++++ b/drivers/pinctrl/bcm63xx/Makefile
+@@ -1,4 +1,5 @@
+ obj-$(CONFIG_PINCTRL_BCM63XX)	+= pinctrl-bcm63xx.o
++obj-$(CONFIG_PINCTRL_BCM6318)	+= pinctrl-bcm6318.o
+ obj-$(CONFIG_PINCTRL_BCM6328)	+= pinctrl-bcm6328.o
+ obj-$(CONFIG_PINCTRL_BCM6348)	+= pinctrl-bcm6348.o
+ obj-$(CONFIG_PINCTRL_BCM6358)	+= pinctrl-bcm6358.o
+--- /dev/null
++++ b/drivers/pinctrl/bcm63xx/pinctrl-bcm6318.c
+@@ -0,0 +1,564 @@
++/*
++ * This file is subject to the terms and conditions of the GNU General Public
++ * License.  See the file "COPYING" in the main directory of this archive
++ * for more details.
++ *
++ * Copyright (C) 2016 Jonas Gorski <jonas.gorski at gmail.com>
++ */
++
++#include <linux/kernel.h>
++#include <linux/spinlock.h>
++#include <linux/bitops.h>
++#include <linux/gpio.h>
++#include <linux/gpio/driver.h>
++#include <linux/of.h>
++#include <linux/of_gpio.h>
++#include <linux/slab.h>
++#include <linux/platform_device.h>
++
++#include <linux/pinctrl/pinconf.h>
++#include <linux/pinctrl/pinconf-generic.h>
++#include <linux/pinctrl/pinmux.h>
++#include <linux/pinctrl/machine.h>
++
++#include "../core.h"
++#include "../pinctrl-utils.h"
++
++#include "pinctrl-bcm63xx.h"
++
++#define BCM6318_NGPIO		50
++
++struct bcm6318_pingroup {
++	const char *name;
++	const unsigned * const pins;
++	const unsigned num_pins;
++};
++
++struct bcm6318_function {
++	const char *name;
++	const char * const *groups;
++	const unsigned num_groups;
++
++	unsigned mode_val:1;
++	unsigned mux_val:2;
++};
++
++struct bcm6318_pinctrl {
++	struct pinctrl_dev *pctldev;
++	struct pinctrl_desc desc;
++
++	void __iomem *mode;
++	void __iomem *mux[3];
++	void __iomem *pad[6];
++
++	/* register access lock */
++	spinlock_t lock;
++
++	struct gpio_chip gpio[2];
++};
++
++static const struct pinctrl_pin_desc bcm6318_pins[] = {
++	PINCTRL_PIN(0, "gpio0"),
++	PINCTRL_PIN(1, "gpio1"),
++	PINCTRL_PIN(2, "gpio2"),
++	PINCTRL_PIN(3, "gpio3"),
++	PINCTRL_PIN(4, "gpio4"),
++	PINCTRL_PIN(5, "gpio5"),
++	PINCTRL_PIN(6, "gpio6"),
++	PINCTRL_PIN(7, "gpio7"),
++	PINCTRL_PIN(8, "gpio8"),
++	PINCTRL_PIN(9, "gpio9"),
++	PINCTRL_PIN(10, "gpio10"),
++	PINCTRL_PIN(11, "gpio11"),
++	PINCTRL_PIN(12, "gpio12"),
++	PINCTRL_PIN(13, "gpio13"),
++	PINCTRL_PIN(14, "gpio14"),
++	PINCTRL_PIN(15, "gpio15"),
++	PINCTRL_PIN(16, "gpio16"),
++	PINCTRL_PIN(17, "gpio17"),
++	PINCTRL_PIN(18, "gpio18"),
++	PINCTRL_PIN(19, "gpio19"),
++	PINCTRL_PIN(20, "gpio20"),
++	PINCTRL_PIN(21, "gpio21"),
++	PINCTRL_PIN(22, "gpio22"),
++	PINCTRL_PIN(23, "gpio23"),
++	PINCTRL_PIN(24, "gpio24"),
++	PINCTRL_PIN(25, "gpio25"),
++	PINCTRL_PIN(26, "gpio26"),
++	PINCTRL_PIN(27, "gpio27"),
++	PINCTRL_PIN(28, "gpio28"),
++	PINCTRL_PIN(29, "gpio29"),
++	PINCTRL_PIN(30, "gpio30"),
++	PINCTRL_PIN(31, "gpio31"),
++	PINCTRL_PIN(32, "gpio32"),
++	PINCTRL_PIN(33, "gpio33"),
++	PINCTRL_PIN(34, "gpio34"),
++	PINCTRL_PIN(35, "gpio35"),
++	PINCTRL_PIN(36, "gpio36"),
++	PINCTRL_PIN(37, "gpio37"),
++	PINCTRL_PIN(38, "gpio38"),
++	PINCTRL_PIN(39, "gpio39"),
++	PINCTRL_PIN(40, "gpio40"),
++	PINCTRL_PIN(41, "gpio41"),
++	PINCTRL_PIN(42, "gpio42"),
++	PINCTRL_PIN(43, "gpio43"),
++	PINCTRL_PIN(44, "gpio44"),
++	PINCTRL_PIN(45, "gpio45"),
++	PINCTRL_PIN(46, "gpio46"),
++	PINCTRL_PIN(47, "gpio47"),
++	PINCTRL_PIN(48, "gpio48"),
++	PINCTRL_PIN(49, "gpio49"),
++};
++
++static unsigned gpio0_pins[] = { 0 };
++static unsigned gpio1_pins[] = { 1 };
++static unsigned gpio2_pins[] = { 2 };
++static unsigned gpio3_pins[] = { 3 };
++static unsigned gpio4_pins[] = { 4 };
++static unsigned gpio5_pins[] = { 5 };
++static unsigned gpio6_pins[] = { 6 };
++static unsigned gpio7_pins[] = { 7 };
++static unsigned gpio8_pins[] = { 8 };
++static unsigned gpio9_pins[] = { 9 };
++static unsigned gpio10_pins[] = { 10 };
++static unsigned gpio11_pins[] = { 11 };
++static unsigned gpio12_pins[] = { 12 };
++static unsigned gpio13_pins[] = { 13 };
++static unsigned gpio14_pins[] = { 14 };
++static unsigned gpio15_pins[] = { 15 };
++static unsigned gpio16_pins[] = { 16 };
++static unsigned gpio17_pins[] = { 17 };
++static unsigned gpio18_pins[] = { 18 };
++static unsigned gpio19_pins[] = { 19 };
++static unsigned gpio20_pins[] = { 20 };
++static unsigned gpio21_pins[] = { 21 };
++static unsigned gpio22_pins[] = { 22 };
++static unsigned gpio23_pins[] = { 23 };
++static unsigned gpio24_pins[] = { 24 };
++static unsigned gpio25_pins[] = { 25 };
++static unsigned gpio26_pins[] = { 26 };
++static unsigned gpio27_pins[] = { 27 };
++static unsigned gpio28_pins[] = { 28 };
++static unsigned gpio29_pins[] = { 29 };
++static unsigned gpio30_pins[] = { 30 };
++static unsigned gpio31_pins[] = { 31 };
++static unsigned gpio32_pins[] = { 32 };
++static unsigned gpio33_pins[] = { 33 };
++static unsigned gpio34_pins[] = { 34 };
++static unsigned gpio35_pins[] = { 35 };
++static unsigned gpio36_pins[] = { 36 };
++static unsigned gpio37_pins[] = { 37 };
++static unsigned gpio38_pins[] = { 38 };
++static unsigned gpio39_pins[] = { 39 };
++static unsigned gpio40_pins[] = { 40 };
++static unsigned gpio41_pins[] = { 41 };
++static unsigned gpio42_pins[] = { 42 };
++static unsigned gpio43_pins[] = { 43 };
++static unsigned gpio44_pins[] = { 44 };
++static unsigned gpio45_pins[] = { 45 };
++static unsigned gpio46_pins[] = { 46 };
++static unsigned gpio47_pins[] = { 47 };
++static unsigned gpio48_pins[] = { 48 };
++static unsigned gpio49_pins[] = { 49 };
++
++#define BCM6318_GROUP(n)					\
++	{							\
++		.name = #n,					\
++		.pins = n##_pins,				\
++		.num_pins = ARRAY_SIZE(n##_pins),		\
++	}
++
++static struct bcm6318_pingroup bcm6318_groups[] = {
++	BCM6318_GROUP(gpio0),
++	BCM6318_GROUP(gpio1),
++	BCM6318_GROUP(gpio2),
++	BCM6318_GROUP(gpio3),
++	BCM6318_GROUP(gpio4),
++	BCM6318_GROUP(gpio5),
++	BCM6318_GROUP(gpio6),
++	BCM6318_GROUP(gpio7),
++	BCM6318_GROUP(gpio8),
++	BCM6318_GROUP(gpio9),
++	BCM6318_GROUP(gpio10),
++	BCM6318_GROUP(gpio11),
++	BCM6318_GROUP(gpio12),
++	BCM6318_GROUP(gpio13),
++	BCM6318_GROUP(gpio14),
++	BCM6318_GROUP(gpio15),
++	BCM6318_GROUP(gpio16),
++	BCM6318_GROUP(gpio17),
++	BCM6318_GROUP(gpio18),
++	BCM6318_GROUP(gpio19),
++	BCM6318_GROUP(gpio20),
++	BCM6318_GROUP(gpio21),
++	BCM6318_GROUP(gpio22),
++	BCM6318_GROUP(gpio23),
++	BCM6318_GROUP(gpio24),
++	BCM6318_GROUP(gpio25),
++	BCM6318_GROUP(gpio26),
++	BCM6318_GROUP(gpio27),
++	BCM6318_GROUP(gpio28),
++	BCM6318_GROUP(gpio29),
++	BCM6318_GROUP(gpio30),
++	BCM6318_GROUP(gpio31),
++	BCM6318_GROUP(gpio32),
++	BCM6318_GROUP(gpio33),
++	BCM6318_GROUP(gpio34),
++	BCM6318_GROUP(gpio35),
++	BCM6318_GROUP(gpio36),
++	BCM6318_GROUP(gpio37),
++	BCM6318_GROUP(gpio38),
++	BCM6318_GROUP(gpio39),
++	BCM6318_GROUP(gpio40),
++	BCM6318_GROUP(gpio41),
++	BCM6318_GROUP(gpio42),
++	BCM6318_GROUP(gpio43),
++	BCM6318_GROUP(gpio44),
++	BCM6318_GROUP(gpio45),
++	BCM6318_GROUP(gpio46),
++	BCM6318_GROUP(gpio47),
++	BCM6318_GROUP(gpio48),
++	BCM6318_GROUP(gpio49),
++};
++
++/* GPIO_MODE */
++static const char * const led_groups[] = {
++	"gpio0",
++	"gpio1",
++	"gpio2",
++	"gpio3",
++	"gpio4",
++	"gpio5",
++	"gpio6",
++	"gpio7",
++	"gpio8",
++	"gpio9",
++	"gpio10",
++	"gpio11",
++	"gpio12",
++	"gpio13",
++	"gpio14",
++	"gpio15",
++	"gpio16",
++	"gpio17",
++	"gpio18",
++	"gpio19",
++	"gpio20",
++	"gpio21",
++	"gpio22",
++	"gpio23",
++};
++
++/* PINMUX_SEL */
++static const char * const ephy0_spd_led_groups[] = {
++	"gpio0",
++};
++
++static const char * const ephy1_spd_led_groups[] = {
++	"gpio1",
++};
++
++static const char * const ephy2_spd_led_groups[] = {
++	"gpio2",
++};
++
++static const char * const ephy3_spd_led_groups[] = {
++	"gpio3",
++};
++
++static const char * const ephy0_act_led_groups[] = {
++	"gpio4",
++};
++
++static const char * const ephy1_act_led_groups[] = {
++	"gpio5",
++};
++
++static const char * const ephy2_act_led_groups[] = {
++	"gpio6",
++};
++
++static const char * const ephy3_act_led_groups[] = {
++	"gpio7",
++};
++
++static const char * const serial_led_data_groups[] = {
++	"gpio6",
++};
++
++static const char * const serial_led_clk_groups[] = {
++	"gpio7",
++};
++
++static const char * const inet_act_led_groups[] = {
++	"gpio8",
++};
++
++static const char * const inet_fail_led_groups[] = {
++	"gpio9",
++};
++
++static const char * const dsl_led_groups[] = {
++	"gpio10",
++};
++
++static const char * const post_fail_led_groups[] = {
++	"gpio11",
++};
++
++static const char * const wlan_wps_led_groups[] = {
++	"gpio12",
++};
++
++static const char * const usb_pwron_groups[] = {
++	"gpio13",
++};
++
++static const char * const usb_device_led_groups[] = {
++	"gpio13",
++};
++
++static const char * const usb_active_groups[] = {
++	"gpio40",
++};
++
++#define BCM6318_MODE_FUN(n)				\
++	{						\
++		.name = #n,				\
++		.groups = n##_groups,			\
++		.num_groups = ARRAY_SIZE(n##_groups),	\
++		.mode_val = 1,				\
++	}
++
++#define BCM6318_MUX_FUN(n, mux)				\
++	{						\
++		.name = #n,				\
++		.groups = n##_groups,			\
++		.num_groups = ARRAY_SIZE(n##_groups),	\
++		.mux_val = mux,				\
++	}
++
++static const struct bcm6318_function bcm6318_funcs[] = {
++	BCM6318_MODE_FUN(led),
++	BCM6318_MUX_FUN(ephy0_spd_led, 1),
++	BCM6318_MUX_FUN(ephy1_spd_led, 1),
++	BCM6318_MUX_FUN(ephy2_spd_led, 1),
++	BCM6318_MUX_FUN(ephy3_spd_led, 1),
++	BCM6318_MUX_FUN(ephy0_act_led, 1),
++	BCM6318_MUX_FUN(ephy1_act_led, 1),
++	BCM6318_MUX_FUN(ephy2_act_led, 1),
++	BCM6318_MUX_FUN(ephy3_act_led, 1),
++	BCM6318_MUX_FUN(serial_led_data, 3),
++	BCM6318_MUX_FUN(serial_led_clk, 3),
++	BCM6318_MUX_FUN(inet_act_led, 1),
++	BCM6318_MUX_FUN(inet_fail_led, 1),
++	BCM6318_MUX_FUN(dsl_led, 1),
++	BCM6318_MUX_FUN(post_fail_led, 1),
++	BCM6318_MUX_FUN(wlan_wps_led, 1),
++	BCM6318_MUX_FUN(usb_pwron, 1),
++	BCM6318_MUX_FUN(usb_device_led, 2),
++	BCM6318_MUX_FUN(usb_active, 2),
++};
++
++static int bcm6318_pinctrl_get_group_count(struct pinctrl_dev *pctldev)
++{
++	return ARRAY_SIZE(bcm6318_groups);
++}
++
++static const char *bcm6318_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
++						  unsigned group)
++{
++	return bcm6318_groups[group].name;
++}
++
++static int bcm6318_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
++					  unsigned group, const unsigned **pins,
++					  unsigned *num_pins)
++{
++	*pins = bcm6318_groups[group].pins;
++	*num_pins = bcm6318_groups[group].num_pins;
++
++	return 0;
++}
++
++static int bcm6318_pinctrl_get_func_count(struct pinctrl_dev *pctldev)
++{
++	return ARRAY_SIZE(bcm6318_funcs);
++}
++
++static const char *bcm6318_pinctrl_get_func_name(struct pinctrl_dev *pctldev,
++						 unsigned selector)
++{
++	return bcm6318_funcs[selector].name;
++}
++
++static int bcm6318_pinctrl_get_groups(struct pinctrl_dev *pctldev,
++				      unsigned selector,
++				      const char * const **groups,
++				      unsigned * const num_groups)
++{
++	*groups = bcm6318_funcs[selector].groups;
++	*num_groups = bcm6318_funcs[selector].num_groups;
++
++	return 0;
++}
++
++static void bcm6318_rmw_mux(struct bcm6318_pinctrl *pctl, unsigned pin,
++			    u32 mode, u32 mux)
++{
++	unsigned long flags;
++	u32 reg;
++
++	spin_lock_irqsave(&pctl->lock, flags);
++	if (pin < 32) {
++		reg = __raw_readl(pctl->mode);
++		reg &= ~BIT(pin);
++		if (mode)
++			reg |= BIT(pin);
++		__raw_writel(reg, pctl->mode);
++	}
++
++	if (pin < 48) {
++		reg = __raw_readl(pctl->mux[pin / 16]);
++		reg &= ~(3UL << ((pin % 16) * 2));
++		reg |= mux << ((pin % 16) * 2);
++		__raw_writel(reg, pctl->mux[pin / 16]);
++	}
++	spin_unlock_irqrestore(&pctl->lock, flags);
++}
++
++static void bcm6318_set_pad(struct bcm6318_pinctrl *pctl, unsigned pin, u8 val)
++{
++	unsigned long flags;
++	u32 reg;
++
++	spin_lock_irqsave(&pctl->lock, flags);
++	reg = __raw_readl(pctl->pad[pin / 8]);
++	reg &= ~(0xfUL << ((pin % 8) * 4));
++	reg |= val << ((pin % 8) * 4);
++	__raw_writel(reg, pctl->pad[pin / 8]);
++	spin_unlock_irqrestore(&pctl->lock, flags);
++}
++
++static int bcm6318_pinctrl_set_mux(struct pinctrl_dev *pctldev,
++				   unsigned selector, unsigned group)
++{
++	struct bcm6318_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
++	const struct bcm6318_pingroup *grp = &bcm6318_groups[group];
++	const struct bcm6318_function *f = &bcm6318_funcs[selector];
++
++	bcm6318_rmw_mux(pctl, grp->pins[0], f->mode_val, f->mux_val);
++
++	return 0;
++}
++
++static int bcm6318_gpio_request_enable(struct pinctrl_dev *pctldev,
++				       struct pinctrl_gpio_range *range,
++				       unsigned offset)
++{
++	struct bcm6318_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
++
++	/* disable all functions using this pin */
++	if (offset < 13) {
++		/* GPIOs 0-12 use mux 0 as GPIO function */
++		bcm6318_rmw_mux(pctl, offset, 0, 0);
++	} else if (offset < 42) {
++		/* GPIOs 13-41 use mux 3 as GPIO function */
++		bcm6318_rmw_mux(pctl, offset, 0, 3);
++
++		/* FIXME: revert to old value for non gpio? */
++		bcm6318_set_pad(pctl, offset, 0);
++	} else {
++		/* no idea, really */
++	}
++
++	return 0;
++}
++
++static struct pinctrl_ops bcm6318_pctl_ops = {
++	.get_groups_count	= bcm6318_pinctrl_get_group_count,
++	.get_group_name		= bcm6318_pinctrl_get_group_name,
++	.get_group_pins		= bcm6318_pinctrl_get_group_pins,
++#ifdef CONFIG_OF
++	.dt_node_to_map		= pinconf_generic_dt_node_to_map_pin,
++	.dt_free_map		= pinctrl_utils_free_map,
++#endif
++};
++
++static struct pinmux_ops bcm6318_pmx_ops = {
++	.get_functions_count	= bcm6318_pinctrl_get_func_count,
++	.get_function_name	= bcm6318_pinctrl_get_func_name,
++	.get_function_groups	= bcm6318_pinctrl_get_groups,
++	.set_mux		= bcm6318_pinctrl_set_mux,
++	.gpio_request_enable	= bcm6318_gpio_request_enable,
++	.strict 		= true,
++};
++
++static int bcm6318_pinctrl_probe(struct platform_device *pdev)
++{
++	struct bcm6318_pinctrl *pctl;
++	struct resource *res;
++	void __iomem *mode, *mux, *pad;
++	unsigned i;
++
++	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mode");
++	mode = devm_ioremap_resource(&pdev->dev, res);
++	if (IS_ERR(mode))
++		return PTR_ERR(mode);
++
++	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mux");
++	mux = devm_ioremap_resource(&pdev->dev, res);
++	if (IS_ERR(mux))
++		return PTR_ERR(mux);
++
++	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pad");
++	pad = devm_ioremap_resource(&pdev->dev, res);
++	if (IS_ERR(pad))
++		return PTR_ERR(pad);
++
++	pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL);
++	if (!pctl)
++		return -ENOMEM;
++
++	spin_lock_init(&pctl->lock);
++
++	pctl->mode = mode;
++
++	for (i = 0; i < 3; i++)
++		pctl->mux[i] = mux + (i * 4);
++
++	for (i = 0; i < 6; i++)
++		pctl->pad[i] = pad + (i * 4);
++
++	pctl->desc.name = dev_name(&pdev->dev);
++	pctl->desc.owner = THIS_MODULE;
++	pctl->desc.pctlops = &bcm6318_pctl_ops;
++	pctl->desc.pmxops = &bcm6318_pmx_ops;
++
++	pctl->desc.npins = ARRAY_SIZE(bcm6318_pins);
++	pctl->desc.pins = bcm6318_pins;
++
++	platform_set_drvdata(pdev, pctl);
++
++	pctl->pctldev = bcm63xx_pinctrl_register(pdev, &pctl->desc, pctl,
++						 pctl->gpio, BCM6318_NGPIO);
++	if (IS_ERR(pctl->pctldev))
++		return PTR_ERR(pctl->pctldev);
++
++	return 0;
++}
++
++static const struct of_device_id bcm6318_pinctrl_match[] = {
++	{ .compatible = "brcm,bcm6318-pinctrl", },
++	{ },
++};
++
++static struct platform_driver bcm6318_pinctrl_driver = {
++	.probe = bcm6318_pinctrl_probe,
++	.driver = {
++		.name = "bcm6318-pinctrl",
++		.of_match_table = bcm6318_pinctrl_match,
++	},
++};
++
++builtin_platform_driver(bcm6318_pinctrl_driver);
diff --git a/target/linux/brcm63xx/patches-4.4/383-bcm63xx_select_pinctrl.patch b/target/linux/brcm63xx/patches-4.4/383-bcm63xx_select_pinctrl.patch
new file mode 100644
index 0000000..52c240f
--- /dev/null
+++ b/target/linux/brcm63xx/patches-4.4/383-bcm63xx_select_pinctrl.patch
@@ -0,0 +1,65 @@
+--- a/arch/mips/bcm63xx/Kconfig
++++ b/arch/mips/bcm63xx/Kconfig
+@@ -24,6 +24,8 @@ config BCM63XX_CPU_6318
+ 	select HW_HAS_PCI
+ 	select BCM63XX_OHCI
+ 	select BCM63XX_EHCI
++	select PINCTRL
++	select PINCTRL_BCM6318
+ 
+ config BCM63XX_CPU_6328
+ 	bool "support 6328 CPU"
+@@ -31,6 +33,8 @@ config BCM63XX_CPU_6328
+ 	select HW_HAS_PCI
+ 	select BCM63XX_OHCI
+ 	select BCM63XX_EHCI
++	select PINCTRL
++	select PINCTRL_BCM6328
+ 
+ config BCM63XX_CPU_6338
+ 	bool "support 6338 CPU"
+@@ -46,6 +50,8 @@ config BCM63XX_CPU_6348
+ 	select SYS_HAS_CPU_BMIPS32_3300
+ 	select HW_HAS_PCI
+ 	select BCM63XX_OHCI
++	select PINCTRL
++	select PINCTRL_BCM6348
+ 
+ config BCM63XX_CPU_6358
+ 	bool "support 6358 CPU"
+@@ -53,6 +59,8 @@ config BCM63XX_CPU_6358
+ 	select HW_HAS_PCI
+ 	select BCM63XX_OHCI
+ 	select BCM63XX_EHCI
++	select PINCTRL
++	select PINCTRL_BCM6358
+ 
+ config BCM63XX_CPU_6362
+ 	bool "support 6362 CPU"
+@@ -60,6 +68,8 @@ config BCM63XX_CPU_6362
+ 	select HW_HAS_PCI
+ 	select BCM63XX_OHCI
+ 	select BCM63XX_EHCI
++	select PINCTRL
++	select PINCTRL_BCM6362
+ 
+ config BCM63XX_CPU_6368
+ 	bool "support 6368 CPU"
+@@ -67,6 +77,8 @@ config BCM63XX_CPU_6368
+ 	select HW_HAS_PCI
+ 	select BCM63XX_OHCI
+ 	select BCM63XX_EHCI
++	select PINCTRL
++	select PINCTRL_BCM6368
+ 
+ config BCM63XX_CPU_63268
+ 	bool "support 63268 CPU"
+@@ -74,6 +86,8 @@ config BCM63XX_CPU_63268
+ 	select HW_HAS_PCI
+ 	select BCM63XX_OHCI
+ 	select BCM63XX_EHCI
++	select PINCTRL
++	select PINCTRL_BCM63268
+ endmenu
+ 
+ source "arch/mips/bcm63xx/boards/Kconfig"
diff --git a/target/linux/brcm63xx/patches-4.4/390-MIPS-BCM63XX-do-not-register-SPI-controllers.patch b/target/linux/brcm63xx/patches-4.4/390-MIPS-BCM63XX-do-not-register-SPI-controllers.patch
index 2e5e872..ee04cff 100644
--- a/target/linux/brcm63xx/patches-4.4/390-MIPS-BCM63XX-do-not-register-SPI-controllers.patch
+++ b/target/linux/brcm63xx/patches-4.4/390-MIPS-BCM63XX-do-not-register-SPI-controllers.patch
@@ -22,7 +22,7 @@ Signed-off-by: Jonas Gorski <jonas.gorski at gmail.com>
  #include <bcm63xx_dev_usb_ehci.h>
  #include <bcm63xx_dev_usb_ohci.h>
  #include <bcm63xx_dev_usb_usbd.h>
-@@ -250,10 +248,6 @@ int __init board_register_devices(void)
+@@ -241,10 +239,6 @@ int __init board_register_devices(void)
  	     bcm63xx_register_fallback_sprom(&board.fallback_sprom)))
  		pr_err(PFX "failed to register fallback SPROM\n");
  
diff --git a/target/linux/brcm63xx/patches-4.4/403-6358-enet1-external-mii-clk.patch b/target/linux/brcm63xx/patches-4.4/403-6358-enet1-external-mii-clk.patch
index 75d60d6..a51700a 100644
--- a/target/linux/brcm63xx/patches-4.4/403-6358-enet1-external-mii-clk.patch
+++ b/target/linux/brcm63xx/patches-4.4/403-6358-enet1-external-mii-clk.patch
@@ -8,7 +8,7 @@
 +			val |= GPIO_MODE_6358_ENET1_MII_CLK_INV;
  	}
  
- 	if (BCMCPU_IS_6368() && board.has_enetsw) {
+ 	bcm_gpio_writel(val, GPIO_MODE_REG);
 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
 +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
 @@ -651,6 +651,8 @@
diff --git a/target/linux/brcm63xx/patches-4.4/413-BCM63XX-allow-providing-fixup-data-in-board-data.patch b/target/linux/brcm63xx/patches-4.4/413-BCM63XX-allow-providing-fixup-data-in-board-data.patch
index 9d79e6c..d8f9169 100644
--- a/target/linux/brcm63xx/patches-4.4/413-BCM63XX-allow-providing-fixup-data-in-board-data.patch
+++ b/target/linux/brcm63xx/patches-4.4/413-BCM63XX-allow-providing-fixup-data-in-board-data.patch
@@ -18,7 +18,7 @@ Subject: [PATCH 58/72] BCM63XX: allow providing fixup data in board data
  
  #include "board_common.h"
  
-@@ -189,6 +190,7 @@ static struct of_device_id of_ids[] = {
+@@ -180,6 +181,7 @@ static struct of_device_id of_ids[] = {
  int __init board_register_devices(void)
  {
  	int usbh_ports = 0;
@@ -26,7 +26,7 @@ Subject: [PATCH 58/72] BCM63XX: allow providing fixup data in board data
  
  #if CONFIG_OF
  	if (of_have_populated_dt()) {
-@@ -265,6 +267,10 @@ int __init board_register_devices(void)
+@@ -256,6 +258,10 @@ int __init board_register_devices(void)
  					board.ephy_reset_gpio_flags);
  	}
  
diff --git a/target/linux/brcm63xx/patches-4.4/420-BCM63XX-add-endian-check-for-ath9k.patch b/target/linux/brcm63xx/patches-4.4/420-BCM63XX-add-endian-check-for-ath9k.patch
index 6599bf2..7407acc 100644
--- a/target/linux/brcm63xx/patches-4.4/420-BCM63XX-add-endian-check-for-ath9k.patch
+++ b/target/linux/brcm63xx/patches-4.4/420-BCM63XX-add-endian-check-for-ath9k.patch
@@ -39,7 +39,7 @@
  		return;
 --- a/arch/mips/bcm63xx/boards/board_common.c
 +++ b/arch/mips/bcm63xx/boards/board_common.c
-@@ -269,7 +269,8 @@ int __init board_register_devices(void)
+@@ -260,7 +260,8 @@ int __init board_register_devices(void)
  
  	/* register any fixups */
  	for (i = 0; i < board.has_caldata; i++)
diff --git a/target/linux/brcm63xx/patches-4.4/421-BCM63XX-add-led-pin-for-ath9k.patch b/target/linux/brcm63xx/patches-4.4/421-BCM63XX-add-led-pin-for-ath9k.patch
index 83ea2ad..da69318 100644
--- a/target/linux/brcm63xx/patches-4.4/421-BCM63XX-add-led-pin-for-ath9k.patch
+++ b/target/linux/brcm63xx/patches-4.4/421-BCM63XX-add-led-pin-for-ath9k.patch
@@ -1,6 +1,6 @@
 --- a/arch/mips/bcm63xx/boards/board_common.c
 +++ b/arch/mips/bcm63xx/boards/board_common.c
-@@ -270,7 +270,7 @@ int __init board_register_devices(void)
+@@ -261,7 +261,7 @@ int __init board_register_devices(void)
  	/* register any fixups */
  	for (i = 0; i < board.has_caldata; i++)
  		pci_enable_ath9k_fixup(board.caldata[i].slot, board.caldata[i].caldata_offset,
diff --git a/target/linux/brcm63xx/patches-4.4/422-BCM63XX-add-a-fixup-for-rt2x00-devices.patch b/target/linux/brcm63xx/patches-4.4/422-BCM63XX-add-a-fixup-for-rt2x00-devices.patch
index ddc6f39..0f3413a 100644
--- a/target/linux/brcm63xx/patches-4.4/422-BCM63XX-add-a-fixup-for-rt2x00-devices.patch
+++ b/target/linux/brcm63xx/patches-4.4/422-BCM63XX-add-a-fixup-for-rt2x00-devices.patch
@@ -36,7 +36,7 @@ Subject: [PATCH 72/72] 446-BCM63XX-add-a-fixup-for-rt2x00-devices
  
  #include "board_common.h"
  
-@@ -268,9 +269,19 @@ int __init board_register_devices(void)
+@@ -259,9 +260,19 @@ int __init board_register_devices(void)
  	}
  
  	/* register any fixups */



More information about the lede-commits mailing list