From: Álvaro Fernández Rojas <noltari@gmail.com>
Date: Wed, 24 Feb 2021 20:28:08 +0000 (+0100)
Subject: bmips: rewrite pin controllers
X-Git-Url: http://git.cdn.openwrt.org/?a=commitdiff_plain;h=e2448e5e03ef2df8194f5705627c2bb6b867d989;p=openwrt%2Fstaging%2Fwigyori.git

bmips: rewrite pin controllers

This is needed in order to upstream them.

Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---

diff --git a/target/linux/bmips/config-5.10 b/target/linux/bmips/config-5.10
index 86c71aaeef..cfe8888f80 100644
--- a/target/linux/bmips/config-5.10
+++ b/target/linux/bmips/config-5.10
@@ -190,7 +190,6 @@ CONFIG_PINCTRL_BCM6328=y
 CONFIG_PINCTRL_BCM6358=y
 CONFIG_PINCTRL_BCM6362=y
 CONFIG_PINCTRL_BCM6368=y
-CONFIG_PINCTRL_BCM63XX=y
 CONFIG_PM=y
 CONFIG_PM_CLK=y
 CONFIG_PM_GENERIC_DOMAINS=y
diff --git a/target/linux/bmips/dts/bcm6318.dtsi b/target/linux/bmips/dts/bcm6318.dtsi
index ba12390814..d19f8ec964 100644
--- a/target/linux/bmips/dts/bcm6318.dtsi
+++ b/target/linux/bmips/dts/bcm6318.dtsi
@@ -143,112 +143,113 @@
 			mask = <0x1>;
 		};
 
-		pinctrl: pin-controller@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>;
-
-			interrupt-parent = <&ext_intc>;
-			interrupts = <0 0>, <1 0>;
-			interrupt-names = "gpio33", "gpio34";
-
-			pinctrl_ephy0_spd_led: ephy0_spd_led {
-				function = "ephy0_spd_led";
-				pins = "gpio0";
-			};
+		gpio: syscon@10000080 {
+			compatible = "syscon", "simple-mfd";
+			reg = <0x10000080 0x80>;
+			native-endian;
 
-			pinctrl_ephy1_spd_led: ephy1_spd_led {
-				function = "ephy1_spd_led";
-				pins = "gpio1";
-			};
+			pinctrl: pin-controller {
+				compatible = "brcm,bcm6318-pinctrl";
 
-			pinctrl_ephy2_spd_led: ephy2_spd_led {
-				function = "ephy2_spd_led";
-				pins = "gpio2";
-			};
+				gpio-controller;
+				#gpio-cells = <2>;
 
-			pinctrl_ephy3_spd_led: ephy3_spd_led {
-				function = "ephy3_spd_led";
-				pins = "gpio3";
-			};
+				interrupts-extended = <&ext_intc 0 0>,
+						      <&ext_intc 1 0>;
+				interrupt-names = "gpio33",
+						  "gpio34";
 
-			pinctrl_ephy0_act_led: ephy0_act_led {
-				function = "ephy0_act_led";
-				pins = "gpio4";
-			};
+				pinctrl_ephy0_spd_led: ephy0_spd_led {
+					function = "ephy0_spd_led";
+					pins = "gpio0";
+				};
 
-			pinctrl_ephy1_act_led: ephy1_act_led {
-				function = "ephy1_act_led";
-				pins = "gpio5";
-			};
+				pinctrl_ephy1_spd_led: ephy1_spd_led {
+					function = "ephy1_spd_led";
+					pins = "gpio1";
+				};
 
-			pinctrl_ephy2_act_led: ephy2_act_led {
-				function = "ephy2_act_led";
-				pins = "gpio6";
-			};
+				pinctrl_ephy2_spd_led: ephy2_spd_led {
+					function = "ephy2_spd_led";
+					pins = "gpio2";
+				};
 
-			pinctrl_ephy3_act_led: ephy3_act_led {
-				function = "ephy3_act_led";
-				pins = "gpio7";
-			};
+				pinctrl_ephy3_spd_led: ephy3_spd_led {
+					function = "ephy3_spd_led";
+					pins = "gpio3";
+				};
 
-			pinctrl_serial_led: serial_led {
-				pinctrl_serial_led_data: serial_led_data {
-					function = "serial_led_data";
+				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_serial_led_clk: serial_led_clk {
-					function = "serial_led_clk";
+				pinctrl_ephy3_act_led: ephy3_act_led {
+					function = "ephy3_act_led";
 					pins = "gpio7";
 				};
-			};
 
-			pinctrl_inet_act_led: inet_act_led {
-				function = "inet_act_led";
-				pins = "gpio8";
-			};
+				pinctrl_serial_led: serial_led {
+					pinctrl_serial_led_data: serial_led_data {
+						function = "serial_led_data";
+						pins = "gpio6";
+					};
 
-			pinctrl_inet_fail_led: inet_fail_led {
-				function = "inet_fail_led";
-				pins = "gpio9";
-			};
+					pinctrl_serial_led_clk: serial_led_clk {
+						function = "serial_led_clk";
+						pins = "gpio7";
+					};
+				};
 
-			pinctrl_dsl_led: dsl_led {
-				function = "dsl_led";
-				pins = "gpio10";
-			};
+				pinctrl_inet_act_led: inet_act_led {
+					function = "inet_act_led";
+					pins = "gpio8";
+				};
 
-			pinctrl_post_fail_led: post_fail_led {
-				function = "post_fail_led";
-				pins = "gpio11";
-			};
+				pinctrl_inet_fail_led: inet_fail_led {
+					function = "inet_fail_led";
+					pins = "gpio9";
+				};
 
-			pinctrl_wlan_wps_led: wlan_wps_led {
-				function = "wlan_wps_led";
-				pins = "gpio12";
-			};
+				pinctrl_dsl_led: dsl_led {
+					function = "dsl_led";
+					pins = "gpio10";
+				};
 
-			pinctrl_usb_pwron: usb_pwron {
-				function = "usb_pwron";
-				pins = "gpio13";
-			};
+				pinctrl_post_fail_led: post_fail_led {
+					function = "post_fail_led";
+					pins = "gpio11";
+				};
 
-			pinctrl_usb_device_led: usb_device_led {
-				function = "usb_device_led";
-				pins = "gpio13";
-			};
+				pinctrl_wlan_wps_led: wlan_wps_led {
+					function = "wlan_wps_led";
+					pins = "gpio12";
+				};
 
-			pinctrl_usb_active: usb_active {
-				function = "usb_active";
-				pins = "gpio40";
+				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";
+				};
 			};
 		};
 
diff --git a/target/linux/bmips/dts/bcm63268.dtsi b/target/linux/bmips/dts/bcm63268.dtsi
index be98bf181e..538b43754b 100644
--- a/target/linux/bmips/dts/bcm63268.dtsi
+++ b/target/linux/bmips/dts/bcm63268.dtsi
@@ -147,131 +147,134 @@
 			timeout-sec = <30>;
 		};
 
-		pinctrl: pin-controller@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>;
-
-			interrupt-parent = <&ext_intc>;
-			interrupts = <0 0>, <1 0>, <2 0>, <3 0>;
-			interrupt-names = "gpio32", "gpio33", "gpio34", "gpio35";
-
-			pinctrl_serial_led: serial_led {
-				pinctrl_serial_led_clk: serial_led_clk {
-					function = "serial_led_clk";
-					pins = "gpio0";
+		gpio: syscon@100000c0 {
+			compatible = "syscon", "simple-mfd";
+			reg = <0x100000c0 0x80>;
+			native-endian;
+
+			pinctrl: pin-controller {
+				compatible = "brcm,bcm63268-pinctrl";
+
+				gpio-controller;
+				#gpio-cells = <2>;
+
+				interrupts-extended = <&ext_intc 0 0>,
+						      <&ext_intc 1 0>,
+						      <&ext_intc 2 0>,
+						      <&ext_intc 3 0>;
+				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_serial_led_data: serial_led_data {
-					function = "serial_led_data";
-					pins = "gpio1";
+				pinctrl_hsspi_cs4: hsspi_cs4 {
+					function = "hsspi_cs4";
+					pins = "gpio16";
 				};
-			};
 
-			pinctrl_hsspi_cs4: hsspi_cs4 {
-				function = "hsspi_cs4";
-				pins = "gpio16";
-			};
+				pinctrl_hsspi_cs5: hsspi_cs5 {
+					function = "hsspi_cs5";
+					pins = "gpio17";
+				};
 
-			pinctrl_hsspi_cs5: hsspi_cs5 {
-				function = "hsspi_cs5";
-				pins = "gpio17";
-			};
+				pinctrl_hsspi_cs6: hsspi_cs6 {
+					function = "hsspi_cs6";
+					pins = "gpio8";
+				};
 
-			pinctrl_hsspi_cs6: hsspi_cs6 {
-				function = "hsspi_cs6";
-				pins = "gpio8";
-			};
+				pinctrl_hsspi_cs7: hsspi_cs7 {
+					function = "hsspi_cs7";
+					pins = "gpio9";
+				};
 
-			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: 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_adsl_spi_mosi: adsl_spi_mosi {
-					function = "adsl_spi_mosi";
-					pins = "gpio19";
+				pinctrl_vreq_clk: vreq_clk {
+					function = "vreq_clk";
+					pins = "gpio22";
 				};
-			};
 
-			pinctrl_vreq_clk: vreq_clk {
-				function = "vreq_clk";
-				pins = "gpio22";
-			};
-
-			pinctrl_pcie_clkreq_b: pcie_clkreq_b {
-				function = "pcie_clkreq_b";
-				pins = "gpio23";
-			};
+				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_clk: robosw_led_clk {
+					function = "robosw_led_clk";
+					pins = "gpio30";
+				};
 
-			pinctrl_robosw_led_data: robosw_led_data {
-				function = "robosw_led_data";
-				pins = "gpio31";
-			};
+				pinctrl_robosw_led_data: robosw_led_data {
+					function = "robosw_led_data";
+					pins = "gpio31";
+				};
 
-			pinctrl_nand: nand {
-				function = "nand";
-				group = "nand_grp";
-			};
+				pinctrl_nand: nand {
+					function = "nand";
+					group = "nand_grp";
+				};
 
-			pinctrl_gpio35_alt: gpio35_alt {
-				function = "gpio35_alt";
-				pin = "gpio35";
-			};
+				pinctrl_gpio35_alt: gpio35_alt {
+					function = "gpio35_alt";
+					pin = "gpio35";
+				};
 
-			pinctrl_dectpd: dectpd {
-				function = "dectpd";
-				group = "dectpd_grp";
-			};
+				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_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_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_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_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_gpio8: dsl_gpio8 {
+					function = "dsl_gpio8";
+					group = "dsl_gpio8";
+				};
 
-			pinctrl_dsl_gpio9: dsl_gpio9 {
-				function = "dsl_gpio9";
-				group = "dsl_gpio9";
+				pinctrl_dsl_gpio9: dsl_gpio9 {
+					function = "dsl_gpio9";
+					group = "dsl_gpio9";
+				};
 			};
 		};
 
diff --git a/target/linux/bmips/dts/bcm6328.dtsi b/target/linux/bmips/dts/bcm6328.dtsi
index 07ae773fe4..f4f86c381e 100644
--- a/target/linux/bmips/dts/bcm6328.dtsi
+++ b/target/linux/bmips/dts/bcm6328.dtsi
@@ -146,97 +146,102 @@
 			mask = <0x1>;
 		};
 
-		pinctrl: pin-controller@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>;
-
-			interrupt-parent = <&ext_intc>;
-			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";
-				};
+		gpio: syscon@10000080 {
+			compatible = "syscon", "simple-mfd";
+			reg = <0x10000080 0x80>;
+			native-endian;
 
-				pinctrl_serial_led_clk: serial_led_clk {
-					function = "serial_led_clk";
-					pins = "gpio7";
+			pinctrl: pin-controller {
+				compatible = "brcm,bcm6328-pinctrl";
+
+				gpio-controller;
+				#gpio-cells = <2>;
+
+				interrupts-extended = <&ext_intc 3 0>,
+						      <&ext_intc 2 0>,
+						      <&ext_intc 1 0>,
+						      <&ext_intc 0 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_inet_act_led: inet_act_led {
+					function = "inet_act_led";
+					pins = "gpio11";
+				};
 
-			pinctrl_pcie_clkreq: pcie_clkreq {
-				function = "pcie_clkreq";
-				pins = "gpio16";
-			};
+				pinctrl_pcie_clkreq: pcie_clkreq {
+					function = "pcie_clkreq";
+					pins = "gpio16";
+				};
 
-			pinctrl_ephy0_spd_led: ephy0_spd_led {
-				function = "led";
-				pins = "gpio17";
-			};
+				pinctrl_ephy0_spd_led: ephy0_spd_led {
+					function = "led";
+					pins = "gpio17";
+				};
 
-			pinctrl_ephy1_spd_led: ephy1_spd_led {
-				function = "led";
-				pins = "gpio18";
-			};
+				pinctrl_ephy1_spd_led: ephy1_spd_led {
+					function = "led";
+					pins = "gpio18";
+				};
 
-			pinctrl_ephy2_spd_led: ephy2_spd_led {
-				function = "led";
-				pins = "gpio19";
-			};
+				pinctrl_ephy2_spd_led: ephy2_spd_led {
+					function = "led";
+					pins = "gpio19";
+				};
 
-			pinctrl_ephy3_spd_led: ephy3_spd_led {
-				function = "led";
-				pins = "gpio20";
-			};
+				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_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_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_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_ephy3_act_led: ephy3_act_led {
+					function = "ephy3_act_led";
+					pins = "gpio28";
+				};
 
-			pinctrl_hsspi_cs1: hsspi_cs1 {
-				function = "hsspi_cs1";
-				pins = "hsspi_cs1";
-			};
+				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_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";
+				pinctrl_usb_port1_host: usb_port1_host {
+					function = "usb_host_port";
+					pins = "usb_port1";
+				};
 			};
 		};
 
diff --git a/target/linux/bmips/dts/bcm6358.dtsi b/target/linux/bmips/dts/bcm6358.dtsi
index 83cfb0ad90..8e2c9fa0ee 100644
--- a/target/linux/bmips/dts/bcm6358.dtsi
+++ b/target/linux/bmips/dts/bcm6358.dtsi
@@ -158,76 +158,77 @@
 			timeout-sec = <30>;
 		};
 
-		pinctrl: pin-controller@fffe0080 {
-			compatible = "brcm,bcm6358-pinctrl";
-			reg = <0xfffe0080 0x8>,
-			      <0xfffe0088 0x8>;
-			reg-names = "dirout", "dat", "mode";
-			brcm,gpiomode = <&gpiomode>;
-
-			gpio-controller;
-			#gpio-cells = <2>;
-
-			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 = "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";
-			};
+		gpio: syscon@fffe0080 {
+			compatible = "syscon", "simple-mfd";
+			reg = <0xfffe0080 0x50>;
+			native-endian;
 
-			pinctrl_sys_irq: sys_irq {
-				function = "sys_irq";
-				groups = "sys_irq_grp";
+			pinctrl: pin-controller {
+				compatible = "brcm,bcm6358-pinctrl";
+
+				gpio-controller;
+				#gpio-cells = <2>;
+
+				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 = "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";
+				};
 			};
 		};
 
-		gpiomode: gpiomode@fffe0098 {
-			compatible = "brcm,bcm6358-gpiomode", "syscon";
-			reg = <0xfffe0098 0x4>;
-		};
-
 		leds: led-controller@fffe00d0 {
 			#address-cells = <1>;
 			#size-cells = <0>;
diff --git a/target/linux/bmips/dts/bcm6362.dtsi b/target/linux/bmips/dts/bcm6362.dtsi
index 724ce5a2f8..d531ed4fe5 100644
--- a/target/linux/bmips/dts/bcm6362.dtsi
+++ b/target/linux/bmips/dts/bcm6362.dtsi
@@ -147,174 +147,176 @@
 			timeout-sec = <30>;
 		};
 
-		pinctrl: pin-controller@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>;
-
-			interrupt-parent = <&ext_intc>;
-			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";
-			};
+		gpio: syscon@10000080 {
+			compatible = "syscon", "simple-mfd";
+			reg = <0x10000080 0x80>;
+			native-endian;
 
-			pinctrl_sys_irq: sys_irq {
-				function = "sys_irq";
-				pins = "gpio1";
-			};
+			pinctrl: pin-controller {
+				compatible = "brcm,bcm6362-pinctrl";
 
-			pinctrl_serial_led: serial_led {
-				pinctrl_serial_led_clk: serial_led_clk {
-					function = "serial_led_clk";
-					pins = "gpio2";
-				};
+				gpio-controller;
+				#gpio-cells = <2>;
 
-				pinctrl_serial_led_data: serial_led_data {
-					function = "serial_led_data";
-					pins = "gpio3";
-				};
-			};
+				interrupts-extended = <&ext_intc 0 0>,
+						      <&ext_intc 1 0>,
+						      <&ext_intc 2 0>,
+						      <&ext_intc 3 0>;
+				interrupt-names = "gpio24",
+						  "gpio25",
+						  "gpio26",
+						  "gpio27";
 
-			pinctrl_robosw_led_data: robosw_led_data {
-				function = "robosw_led_data";
-				pins = "gpio4";
-			};
+				pinctrl_usb_device_led: usb_device_led {
+					function = "usb_device_led";
+					pins = "gpio0";
+				};
 
-			pinctrl_robosw_led_clk: robosw_led_clk {
-				function = "robosw_led_clk";
-				pins = "gpio5";
-			};
+				pinctrl_sys_irq: sys_irq {
+					function = "sys_irq";
+					pins = "gpio1";
+				};
 
-			pinctrl_robosw_led0: robosw_led0 {
-				function = "robosw_led0";
-				pins = "gpio6";
-			};
+				pinctrl_serial_led: serial_led {
+					pinctrl_serial_led_clk: serial_led_clk {
+						function = "serial_led_clk";
+						pins = "gpio2";
+					};
 
-			pinctrl_robosw_led1: robosw_led1 {
-				function = "robosw_led1";
-				pins = "gpio7";
-			};
+					pinctrl_serial_led_data: serial_led_data {
+						function = "serial_led_data";
+						pins = "gpio3";
+					};
+				};
 
-			pinctrl_inet_led: inet_led {
-				function = "inet_led";
-				pins = "gpio8";
-			};
+				pinctrl_robosw_led_data: robosw_led_data {
+					function = "robosw_led_data";
+					pins = "gpio4";
+				};
 
-			pinctrl_spi_cs2: spi_cs2 {
-				function = "spi_cs2";
-				pins = "gpio9";
-			};
+				pinctrl_robosw_led_clk: robosw_led_clk {
+					function = "robosw_led_clk";
+					pins = "gpio5";
+				};
 
-			pinctrl_spi_cs3: spi_cs3 {
-				function = "spi_cs3";
-				pins = "gpio10";
-			};
+				pinctrl_robosw_led0: robosw_led0 {
+					function = "robosw_led0";
+					pins = "gpio6";
+				};
 
-			pinctrl_ntr_pulse: ntr_pulse {
-				function = "ntr_pulse";
-				pins = "gpio11";
-			};
+				pinctrl_robosw_led1: robosw_led1 {
+					function = "robosw_led1";
+					pins = "gpio7";
+				};
 
-			pinctrl_uart1_scts: uart1_scts {
-				function = "uart1_scts";
-				pins = "gpio12";
-			};
+				pinctrl_inet_led: inet_led {
+					function = "inet_led";
+					pins = "gpio8";
+				};
 
-			pinctrl_uart1_srts: uart1_srts {
-				function = "uart1_srts";
-				pins = "gpio13";
-			};
+				pinctrl_spi_cs2: spi_cs2 {
+					function = "spi_cs2";
+					pins = "gpio9";
+				};
 
-			pinctrl_uart1: uart1 {
-				pinctrl_uart1_sdin: uart1_sdin {
-					function = "uart1_sdin";
-					pins = "gpio14";
+				pinctrl_spi_cs3: spi_cs3 {
+					function = "spi_cs3";
+					pins = "gpio10";
 				};
 
-				pinctrl_uart1_sdout: uart1_sdout {
-					function = "uart1_sdout";
-					pins = "gpio15";
+				pinctrl_ntr_pulse: ntr_pulse {
+					function = "ntr_pulse";
+					pins = "gpio11";
 				};
-			};
 
-			pinctrl_adsl_spi: adsl_spi {
-				pinctrl_adsl_spi_miso: adsl_spi_miso {
-					function = "adsl_spi_miso";
-					pins = "gpio16";
+				pinctrl_uart1_scts: uart1_scts {
+					function = "uart1_scts";
+					pins = "gpio12";
 				};
 
-				pinctrl_adsl_spi_mosi: adsl_spi_mosi {
-					function = "adsl_spi_mosi";
-					pins = "gpio17";
+				pinctrl_uart1_srts: uart1_srts {
+					function = "uart1_srts";
+					pins = "gpio13";
 				};
 
-				pinctrl_adsl_spi_clk: adsl_spi_clk {
-					function = "adsl_spi_clk";
-					pins = "gpio18";
+				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_cs: adsl_spi_cs {
-					function = "adsl_spi_cs";
-					pins = "gpio19";
+				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_ephy0_led: ephy0_led {
+					function = "ephy0_led";
+					pins = "gpio20";
+				};
 
-			pinctrl_ephy1_led: ephy1_led {
-				function = "ephy1_led";
-				pins = "gpio21";
-			};
+				pinctrl_ephy1_led: ephy1_led {
+					function = "ephy1_led";
+					pins = "gpio21";
+				};
 
-			pinctrl_ephy2_led: ephy2_led {
-				function = "ephy2_led";
-				pins = "gpio22";
-			};
+				pinctrl_ephy2_led: ephy2_led {
+					function = "ephy2_led";
+					pins = "gpio22";
+				};
 
-			pinctrl_ephy3_led: ephy3_led {
-				function = "ephy3_led";
-				pins = "gpio23";
-			};
+				pinctrl_ephy3_led: ephy3_led {
+					function = "ephy3_led";
+					pins = "gpio23";
+				};
 
-			pinctrl_ext_irq0: ext_irq0 {
-				function = "ext_irq0";
-				pins = "gpio24";
-			};
+				pinctrl_ext_irq0: ext_irq0 {
+					function = "ext_irq0";
+					pins = "gpio24";
+				};
 
-			pinctrl_ext_irq1: ext_irq1 {
-				function = "ext_irq1";
-				pins = "gpio25";
-			};
+				pinctrl_ext_irq1: ext_irq1 {
+					function = "ext_irq1";
+					pins = "gpio25";
+				};
 
-			pinctrl_ext_irq2: ext_irq2 {
-				function = "ext_irq2";
-				pins = "gpio26";
-			};
+				pinctrl_ext_irq2: ext_irq2 {
+					function = "ext_irq2";
+					pins = "gpio26";
+				};
 
-			pinctrl_ext_irq3: ext_irq3 {
-				function = "ext_irq3";
-				pins = "gpio27";
-			};
+				pinctrl_ext_irq3: ext_irq3 {
+					function = "ext_irq3";
+					pins = "gpio27";
+				};
 
-			pinctrl_nand: nand {
-				function = "nand";
-				group = "nand_grp";
+				pinctrl_nand: nand {
+					function = "nand";
+					group = "nand_grp";
+				};
 			};
 		};
 
diff --git a/target/linux/bmips/dts/bcm6368.dtsi b/target/linux/bmips/dts/bcm6368.dtsi
index babd8c7385..0b434c5c01 100644
--- a/target/linux/bmips/dts/bcm6368.dtsi
+++ b/target/linux/bmips/dts/bcm6368.dtsi
@@ -149,185 +149,190 @@
 			timeout-sec = <30>;
 		};
 
-		pinctrl: pin-controller@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>;
-
-			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 = "gpio32", "gpio33", "gpio34", "gpio35",
-					  "gpio36", "gpio37";
-
-			pinctrl_analog_afe_0: analog_afe_0 {
-				function = "analog_afe_0";
-				pins = "gpio0";
-			};
-
-			pinctrl_analog_afe_1: analog_afe_1 {
-				function = "analog_afe_1";
-				pins = "gpio1";
-			};
-
-			pinctrl_sys_irq: sys_irq {
-				function = "sys_irq";
-				pins = "gpio2";
-			};
+		gpio: syscon@10000080 {
+			compatible = "syscon", "simple-mfd";
+			reg = <0x10000080 0x80>;
+			native-endian;
 
-			pinctrl_serial_led: serial_led {
-				pinctrl_serial_led_data: serial_led_data {
-					function = "serial_led_data";
-					pins = "gpio3";
+			pinctrl: pin-controller {
+				compatible = "brcm,bcm6368-pinctrl";
+
+				gpio-controller;
+				#gpio-cells = <2>;
+
+				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 = "gpio32",
+						  "gpio33",
+						  "gpio34",
+						  "gpio35",
+						  "gpio36",
+						  "gpio37";
+
+				pinctrl_analog_afe_0: analog_afe_0 {
+					function = "analog_afe_0";
+					pins = "gpio0";
 				};
 
-				pinctrl_serial_led_clk: serial_led_clk {
-					function = "serial_led_clk";
-					pins = "gpio4";
+				pinctrl_analog_afe_1: analog_afe_1 {
+					function = "analog_afe_1";
+					pins = "gpio1";
 				};
-			};
-
-			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_sys_irq: sys_irq {
+					function = "sys_irq";
+					pins = "gpio2";
+				};
 
-			pinctrl_robosw_led_data: robosw_led_data {
-				function = "robosw_led_data";
-				pins = "gpio10";
-			};
+				pinctrl_serial_led: serial_led {
+					pinctrl_serial_led_data: serial_led_data {
+						function = "serial_led_data";
+						pins = "gpio3";
+					};
 
-			pinctrl_robosw_led_clk: robosw_led_clk {
-				function = "robosw_led_clk";
-				pins = "gpio11";
-			};
+					pinctrl_serial_led_clk: serial_led_clk {
+						function = "serial_led_clk";
+						pins = "gpio4";
+					};
+				};
 
-			pinctrl_robosw_led0: robosw_led0 {
-				function = "robosw_led0";
-				pins = "gpio12";
-			};
+				pinctrl_inet_led: inet_led {
+					function = "inet_led";
+					pins = "gpio5";
+				};
 
-			pinctrl_robosw_led1: robosw_led1 {
-				function = "robosw_led1";
-				pins = "gpio13";
-			};
+				pinctrl_ephy0_led: ephy0_led {
+					function = "ephy0_led";
+					pins = "gpio6";
+				};
 
-			pinctrl_usb_device_led: usb_device_led {
-				function = "usb_device_led";
-				pins = "gpio14";
-			};
+				pinctrl_ephy1_led: ephy1_led {
+					function = "ephy1_led";
+					pins = "gpio7";
+				};
 
-			pinctrl_pci: pci {
-				pinctrl_pci_req1: pci_req1 {
-					function = "pci_req1";
-					pins = "gpio16";
+				pinctrl_ephy2_led: ephy2_led {
+					function = "ephy2_led";
+					pins = "gpio8";
 				};
 
-				pinctrl_pci_gnt1: pci_gnt1 {
-					function = "pci_gnt1";
-					pins = "gpio17";
+				pinctrl_ephy3_led: ephy3_led {
+					function = "ephy3_led";
+					pins = "gpio9";
 				};
 
-				pinctrl_pci_intb: pci_intb {
-					function = "pci_intb";
-					pins = "gpio18";
+				pinctrl_robosw_led_data: robosw_led_data {
+					function = "robosw_led_data";
+					pins = "gpio10";
 				};
 
-				pinctrl_pci_req0: pci_req0 {
-					function = "pci_req0";
-					pins = "gpio19";
+				pinctrl_robosw_led_clk: robosw_led_clk {
+					function = "robosw_led_clk";
+					pins = "gpio11";
 				};
 
-				pinctrl_pci_gnt0: pci_gnt0 {
-					function = "pci_gnt0";
-					pins = "gpio20";
+				pinctrl_robosw_led0: robosw_led0 {
+					function = "robosw_led0";
+					pins = "gpio12";
 				};
-			};
 
-			pinctrl_pcmcia: pcmcia {
-				pinctrl_pcmcia_cd1: pcmcia_cd1 {
-					function = "pcmcia_cd1";
-					pins = "gpio22";
+				pinctrl_robosw_led1: robosw_led1 {
+					function = "robosw_led1";
+					pins = "gpio13";
 				};
 
-				pinctrl_pcmcia_cd2: pcmcia_cd2 {
-					function = "pcmcia_cd2";
-					pins = "gpio23";
+				pinctrl_usb_device_led: usb_device_led {
+					function = "usb_device_led";
+					pins = "gpio14";
 				};
 
-				pinctrl_pcmcia_vs1: pcmcia_vs1 {
-					function = "pcmcia_vs1";
-					pins = "gpio24";
+				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_vs2: pcmcia_vs2 {
-					function = "pcmcia_vs2";
-					pins = "gpio25";
+				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_cs2: ebi_cs2 {
+					function = "ebi_cs2";
+					pins = "gpio26";
+				};
 
-			pinctrl_ebi_cs3: ebi_cs3 {
-				function = "ebi_cs2";
-				pins = "gpio27";
-			};
+				pinctrl_ebi_cs3: ebi_cs3 {
+					function = "ebi_cs3";
+					pins = "gpio27";
+				};
 
-			pinctrl_spi_cs2: spi_cs2 {
-				function = "spi_cs2";
-				pins = "gpio28";
-			};
+				pinctrl_spi_cs2: spi_cs2 {
+					function = "spi_cs2";
+					pins = "gpio28";
+				};
 
-			pinctrl_spi_cs3: spi_cs3 {
-				function = "spi_cs3";
-				pins = "gpio29";
-			};
+				pinctrl_spi_cs3: spi_cs3 {
+					function = "spi_cs3";
+					pins = "gpio29";
+				};
 
-			pinctrl_spi_cs4: spi_cs4 {
-				function = "spi_cs4";
-				pins = "gpio30";
-			};
+				pinctrl_spi_cs4: spi_cs4 {
+					function = "spi_cs4";
+					pins = "gpio30";
+				};
 
-			pinctrl_spi_cs5: spi_cs5 {
-				function = "spi_cs5";
-				pins = "gpio31";
-			};
+				pinctrl_spi_cs5: spi_cs5 {
+					function = "spi_cs5";
+					pins = "gpio31";
+				};
 
-			pinctrl_uart1: uart1 {
-				function = "uart1";
-				group = "uart1_grp";
+				pinctrl_uart1: uart1 {
+					function = "uart1";
+					group = "uart1_grp";
+				};
 			};
 		};
 
diff --git a/target/linux/bmips/patches-5.10/400-Documentation-add-BCM6328-pincontroller-binding-docu.patch b/target/linux/bmips/patches-5.10/400-Documentation-add-BCM6328-pincontroller-binding-docu.patch
new file mode 100644
index 0000000000..4ad97ad1e0
--- /dev/null
+++ b/target/linux/bmips/patches-5.10/400-Documentation-add-BCM6328-pincontroller-binding-docu.patch
@@ -0,0 +1,182 @@
+From 3b6d70e7bae0dbba02435c53f878a042d6d4bd4d Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
+Date: Wed, 27 Jul 2016 11:33:56 +0200
+Subject: [PATCH 01/12] Documentation: add BCM6328 pincontroller binding
+ documentation
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add binding documentation for the pincontrol core found in BCM6328 SoCs.
+
+Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
+Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
+---
+ .../pinctrl/brcm,bcm6328-pinctrl.yaml         | 161 ++++++++++++++++++
+ 1 file changed, 161 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml
+@@ -0,0 +1,161 @@
++# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/pinctrl/brcm,bcm6328-pinctrl.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: Broadcom BCM6328 pin controller
++
++maintainers:
++  - Álvaro Fernández Rojas <noltari@gmail.com>
++  - Jonas Gorski <jonas.gorski@gmail.com>
++
++description: |+
++  The pin controller node should be the child of a syscon node.
++
++  Refer to the the bindings described in
++  Documentation/devicetree/bindings/mfd/syscon.yaml
++
++properties:
++  compatible:
++    const: brcm,bcm6328-pinctrl
++
++  gpio-controller: true
++
++  '#gpio-cells':
++    description:
++      Specifies the pin number and flags, as defined in
++      include/dt-bindings/gpio/gpio.h
++    const: 2
++
++  interrupts-extended:
++    description:
++      One interrupt per each of the 4 GPIO ports supported by the controller,
++      sorted by port number ascending order.
++    minItems: 4
++    maxItems: 4
++
++patternProperties:
++  '^.*$':
++    if:
++      type: object
++    then:
++      properties:
++        function:
++          $ref: "/schemas/types.yaml#/definitions/string"
++          enum: [ serial_led_data, serial_led_clk, inet_act_led, pcie_clkreq,
++                  led, ephy0_act_led, ephy1_act_led, ephy2_act_led,
++                  ephy3_act_led, hsspi_cs1, usb_device_port, usb_host_port ]
++
++        pins:
++          $ref: "/schemas/types.yaml#/definitions/string"
++          enum: [ gpio6, gpio7, gpio11, gpio16, gpio17, gpio18, gpio19,
++                  gpio20, gpio25, gpio26, gpio27, gpio28, hsspi_cs1,
++                  usb_port1 ]
++
++required:
++  - compatible
++  - gpio-controller
++  - '#gpio-cells'
++
++additionalProperties: false
++
++examples:
++  - |
++    gpio@10000080 {
++      compatible = "syscon", "simple-mfd";
++      reg = <0x10000080 0x80>;
++
++      pinctrl: pinctrl {
++        compatible = "brcm,bcm6328-pinctrl";
++
++        gpio-controller;
++        #gpio-cells = <2>;
++
++        interrupts-extended = <&ext_intc 3 0>,
++                              <&ext_intc 2 0>,
++                              <&ext_intc 1 0>,
++                              <&ext_intc 0 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";
++        };
++      };
++    };
diff --git a/target/linux/bmips/patches-5.10/400-pinctrl-add-bcm63xx-base-code.patch b/target/linux/bmips/patches-5.10/400-pinctrl-add-bcm63xx-base-code.patch
deleted file mode 100644
index 0f42bd2f83..0000000000
--- a/target/linux/bmips/patches-5.10/400-pinctrl-add-bcm63xx-base-code.patch
+++ /dev/null
@@ -1,226 +0,0 @@
-From ab2f33e35e35905a76204138143875251f3e1088 Mon Sep 17 00:00:00 2001
-From: Jonas Gorski <jonas.gorski@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@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
-@@ -377,6 +377,7 @@ config PINCTRL_OCELOT
- source "drivers/pinctrl/actions/Kconfig"
- source "drivers/pinctrl/aspeed/Kconfig"
- 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
-@@ -51,6 +51,7 @@ obj-$(CONFIG_PINCTRL_EQUILIBRIUM)   += p
- obj-y				+= actions/
- obj-$(CONFIG_ARCH_ASPEED)	+= aspeed/
- obj-y				+= bcm/
-+obj-y				+= bcm63xx/
- obj-$(CONFIG_PINCTRL_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@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/bmips/patches-5.10/401-Documentation-add-BCM6328-pincontroller-binding-docu.patch b/target/linux/bmips/patches-5.10/401-Documentation-add-BCM6328-pincontroller-binding-docu.patch
deleted file mode 100644
index 3a2a7811db..0000000000
--- a/target/linux/bmips/patches-5.10/401-Documentation-add-BCM6328-pincontroller-binding-docu.patch
+++ /dev/null
@@ -1,78 +0,0 @@
-From 4bdd40849632608d5cb7d3a64380cd76e7eea07b Mon Sep 17 00:00:00 2001
-From: Jonas Gorski <jonas.gorski@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@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@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/bmips/patches-5.10/401-pinctrl-add-a-pincontrol-driver-for-BCM6328.patch b/target/linux/bmips/patches-5.10/401-pinctrl-add-a-pincontrol-driver-for-BCM6328.patch
new file mode 100644
index 0000000000..0e223f2fca
--- /dev/null
+++ b/target/linux/bmips/patches-5.10/401-pinctrl-add-a-pincontrol-driver-for-BCM6328.patch
@@ -0,0 +1,636 @@
+From 3373a507212e6394921781766e9cd0dc155c62ba Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
+Date: Fri, 24 Jun 2016 22:12:50 +0200
+Subject: [PATCH 02/12] pinctrl: add a pincontrol driver for BCM6328
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+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: Álvaro Fernández Rojas <noltari@gmail.com>
+Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
+---
+ drivers/pinctrl/bcm/Kconfig           |  11 +
+ drivers/pinctrl/bcm/Makefile          |   1 +
+ drivers/pinctrl/bcm/pinctrl-bcm6328.c | 581 ++++++++++++++++++++++++++
+ 3 files changed, 593 insertions(+)
+ create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm6328.c
+
+--- a/drivers/pinctrl/bcm/Kconfig
++++ b/drivers/pinctrl/bcm/Kconfig
+@@ -29,6 +29,17 @@ config PINCTRL_BCM2835
+ 	help
+ 	   Say Y here to enable the Broadcom BCM2835 GPIO driver.
+ 
++config PINCTRL_BCM6328
++	bool "Broadcom BCM6328 GPIO driver"
++	depends on OF_GPIO && (BMIPS_GENERIC || COMPILE_TEST)
++	select PINMUX
++	select PINCONF
++	select GENERIC_PINCONF
++	select MFD_SYSCON
++	default BMIPS_GENERIC
++	help
++	   Say Y here to enable the Broadcom BCM6328 GPIO driver.
++
+ config PINCTRL_IPROC_GPIO
+ 	bool "Broadcom iProc GPIO (with PINCONF) driver"
+ 	depends on OF_GPIO && (ARCH_BCM_IPROC || COMPILE_TEST)
+--- a/drivers/pinctrl/bcm/Makefile
++++ b/drivers/pinctrl/bcm/Makefile
+@@ -3,6 +3,7 @@
+ 
+ obj-$(CONFIG_PINCTRL_BCM281XX)		+= pinctrl-bcm281xx.o
+ obj-$(CONFIG_PINCTRL_BCM2835)		+= pinctrl-bcm2835.o
++obj-$(CONFIG_PINCTRL_BCM6328)		+= pinctrl-bcm6328.o
+ obj-$(CONFIG_PINCTRL_IPROC_GPIO)	+= pinctrl-iproc-gpio.o
+ obj-$(CONFIG_PINCTRL_CYGNUS_MUX)	+= pinctrl-cygnus-mux.o
+ obj-$(CONFIG_PINCTRL_NS)		+= pinctrl-ns.o
+--- /dev/null
++++ b/drivers/pinctrl/bcm/pinctrl-bcm6328.c
+@@ -0,0 +1,581 @@
++// SPDX-License-Identifier: GPL-2.0+
++/*
++ * Driver for BCM6328 GPIO unit (pinctrl + GPIO)
++ *
++ * Copyright (C) 2021 Álvaro Fernández Rojas <noltari@gmail.com>
++ * Copyright (C) 2016 Jonas Gorski <jonas.gorski@gmail.com>
++ */
++
++#include <linux/bitops.h>
++#include <linux/gpio.h>
++#include <linux/kernel.h>
++#include <linux/mfd/syscon.h>
++#include <linux/of.h>
++#include <linux/of_gpio.h>
++#include <linux/of_irq.h>
++#include <linux/platform_device.h>
++#include <linux/regmap.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"
++
++#define MODULE_NAME		"bcm6328-pinctrl"
++#define BCM6328_NUM_GPIOS	32
++
++#define BANK_SIZE		sizeof(uint32_t)
++#define PINS_PER_BANK		(BANK_SIZE * BITS_PER_BYTE)
++
++#define BCM6328_DIROUT_REG	0x04
++#define BCM6328_DATA_REG	0x0c
++#define BCM6328_MODE_REG	0x18
++#define BCM6328_MUX_HI_REG	0x1c
++#define BCM6328_MUX_LO_REG	0x20
++#define BCM6328_MUX_OTHER_REG	0x24
++
++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 device *dev;
++	struct regmap *regs;
++
++	struct pinctrl_dev *pctl_dev;
++	struct gpio_chip gpio_chip;
++	struct pinctrl_desc pctl_desc;
++	struct pinctrl_gpio_range gpio_range;
++};
++
++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 inline unsigned int bcm6328_bank_pin(unsigned int pin)
++{
++	return pin % PINS_PER_BANK;
++}
++
++static inline unsigned int bcm6318_mux_off(unsigned int pin)
++{
++	static const unsigned int bcm6328_mux[] = {
++		BCM6328_MUX_LO_REG,
++		BCM6328_MUX_HI_REG,
++		BCM6328_MUX_OTHER_REG
++	};
++
++	return bcm6328_mux[pin / 16];
++}
++
++static inline unsigned int bcm6328_reg_off(unsigned int reg, unsigned int pin)
++{
++	return reg - (pin / PINS_PER_BANK) * BANK_SIZE;
++}
++
++static int bcm6328_gpio_direction_input(struct gpio_chip *chip,
++					unsigned int pin)
++{
++	struct bcm6328_pinctrl *pc = gpiochip_get_data(chip);
++	unsigned int dirout = bcm6328_reg_off(BCM6328_DIROUT_REG, pin);
++	unsigned int bank_pin = bcm6328_bank_pin(pin);
++	int ret;
++
++	/*
++	 * Check with the pinctrl driver whether this pin is usable as
++	 * an input GPIO
++	 */
++	ret = pinctrl_gpio_direction_input(chip->base + pin);
++	if (ret)
++		return ret;
++
++	regmap_update_bits(pc->regs, dirout, BIT(bank_pin), 0);
++
++	return 0;
++}
++
++static int bcm6328_gpio_direction_output(struct gpio_chip *chip,
++					 unsigned int pin, int value)
++{
++	struct bcm6328_pinctrl *pc = gpiochip_get_data(chip);
++	unsigned int data = bcm6328_reg_off(BCM6328_DATA_REG, pin);
++	unsigned int dirout = bcm6328_reg_off(BCM6328_DIROUT_REG, pin);
++	unsigned int bank_pin = bcm6328_bank_pin(pin);
++	unsigned int val = value ? BIT(bank_pin) : 0;
++	int ret;
++
++	/*
++	 * Check with the pinctrl driver whether this pin is usable as
++	 * an output GPIO
++	 */
++	ret = pinctrl_gpio_direction_output(chip->base + pin);
++	if (ret)
++		return ret;
++
++	regmap_update_bits(pc->regs, dirout, BIT(bank_pin), BIT(bank_pin));
++	regmap_update_bits(pc->regs, data, BIT(bank_pin), val);
++
++	return 0;
++}
++
++static int bcm6328_gpio_get(struct gpio_chip *chip, unsigned int pin)
++{
++	struct bcm6328_pinctrl *pc = gpiochip_get_data(chip);
++	unsigned int data = bcm6328_reg_off(BCM6328_DATA_REG, pin);
++	unsigned int bank_pin = bcm6328_bank_pin(pin);
++	unsigned int val;
++
++	regmap_read(pc->regs, data, &val);
++
++	return !!(val & BIT(bank_pin));
++}
++
++static int bcm6328_gpio_get_direction(struct gpio_chip *chip, unsigned int pin)
++{
++	struct bcm6328_pinctrl *pc = gpiochip_get_data(chip);
++	unsigned int dirout = bcm6328_reg_off(BCM6328_DIROUT_REG, pin);
++	unsigned int bank_pin = bcm6328_bank_pin(pin);
++	unsigned int val;
++
++	regmap_read(pc->regs, dirout, &val);
++
++	if (val & BIT(bank_pin))
++		return GPIO_LINE_DIRECTION_OUT;
++
++	return GPIO_LINE_DIRECTION_IN;
++}
++
++static void bcm6328_gpio_set(struct gpio_chip *chip, unsigned int pin,
++			     int value)
++{
++	struct bcm6328_pinctrl *pc = gpiochip_get_data(chip);
++	unsigned int data = bcm6328_reg_off(BCM6328_DATA_REG, pin);
++	unsigned int bank_pin = bcm6328_bank_pin(pin);
++	unsigned int val = value ? BIT(bank_pin) : 0;
++
++	regmap_update_bits(pc->regs, data, BIT(bank_pin), val);
++}
++
++static int bcm6328_gpio_to_irq(struct gpio_chip *chip, unsigned gpio)
++{
++	char irq_name[7];
++
++	sprintf(irq_name, "gpio%d", gpio);
++
++	return of_irq_get_byname(chip->of_node, irq_name);
++}
++
++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 *pc, unsigned pin,
++			    unsigned int mode, unsigned int mux)
++{
++	if (pin < BCM6328_NUM_GPIOS)
++		regmap_update_bits(pc->regs, BCM6328_MODE_REG, BIT(pin),
++				   mode ? BIT(pin) : 0);
++
++	regmap_update_bits(pc->regs, bcm6318_mux_off(pin),
++			   3UL << ((pin % 16) * 2),
++			   mux << ((pin % 16) * 2));
++}
++
++static int bcm6328_pinctrl_set_mux(struct pinctrl_dev *pctldev,
++				   unsigned selector, unsigned group)
++{
++	struct bcm6328_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
++	const struct bcm6328_pingroup *pg = &bcm6328_groups[group];
++	const struct bcm6328_function *f = &bcm6328_funcs[selector];
++
++	bcm6328_rmw_mux(pc, pg->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 *pc = pinctrl_dev_get_drvdata(pctldev);
++
++	/* disable all functions using this pin */
++	bcm6328_rmw_mux(pc, 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,
++	.dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
++	.dt_free_map = pinctrl_utils_free_map,
++};
++
++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 device *dev = &pdev->dev;
++	struct device_node *np = dev->of_node;
++	struct bcm6328_pinctrl *pc;
++	int err;
++
++	pc = devm_kzalloc(dev, sizeof(*pc), GFP_KERNEL);
++	if (!pc)
++		return -ENOMEM;
++
++	platform_set_drvdata(pdev, pc);
++	pc->dev = dev;
++
++	pc->regs = syscon_node_to_regmap(dev->parent->of_node);
++	if (IS_ERR(pc->regs))
++		return PTR_ERR(pc->regs);
++
++	pc->gpio_chip.label = MODULE_NAME;
++	pc->gpio_chip.owner = THIS_MODULE;
++	pc->gpio_chip.request = gpiochip_generic_request;
++	pc->gpio_chip.free = gpiochip_generic_free;
++	pc->gpio_chip.direction_input = bcm6328_gpio_direction_input;
++	pc->gpio_chip.direction_output = bcm6328_gpio_direction_output;
++	pc->gpio_chip.get_direction = bcm6328_gpio_get_direction;
++	pc->gpio_chip.get = bcm6328_gpio_get;
++	pc->gpio_chip.set = bcm6328_gpio_set;
++	pc->gpio_chip.set_config = gpiochip_generic_config;
++	pc->gpio_chip.base = -1;
++	pc->gpio_chip.ngpio = BCM6328_NUM_GPIOS;
++	pc->gpio_chip.can_sleep = false;
++	pc->gpio_chip.parent = dev;
++	pc->gpio_chip.of_node = np;
++
++	if (of_get_property(np, "interrupt-names", NULL))
++		pc->gpio_chip.to_irq = bcm6328_gpio_to_irq;
++
++	err = gpiochip_add_data(&pc->gpio_chip, pc);
++	if (err) {
++		dev_err(dev, "could not add GPIO chip\n");
++		return err;
++	}
++
++	pc->pctl_desc.name = MODULE_NAME,
++	pc->pctl_desc.pins = bcm6328_pins,
++	pc->pctl_desc.npins = ARRAY_SIZE(bcm6328_pins),
++	pc->pctl_desc.pctlops = &bcm6328_pctl_ops,
++	pc->pctl_desc.pmxops = &bcm6328_pmx_ops,
++	pc->pctl_desc.owner = THIS_MODULE,
++
++	pc->pctl_dev = devm_pinctrl_register(dev, &pc->pctl_desc, pc);
++	if (IS_ERR(pc->pctl_dev)) {
++		gpiochip_remove(&pc->gpio_chip);
++		return PTR_ERR(pc->pctl_dev);
++	}
++
++	pc->gpio_range.name = MODULE_NAME;
++	pc->gpio_range.npins = BCM6328_NUM_GPIOS;
++	pc->gpio_range.base = pc->gpio_chip.base;
++	pc->gpio_range.gc = &pc->gpio_chip;
++	pinctrl_add_gpio_range(pc->pctl_dev, &pc->gpio_range);
++
++	dev_info(dev, "registered\n");
++
++	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 = MODULE_NAME,
++		.of_match_table = bcm6328_pinctrl_match,
++	},
++};
++
++builtin_platform_driver(bcm6328_pinctrl_driver);
diff --git a/target/linux/bmips/patches-5.10/402-Documentation-add-BCM6358-pincontroller-binding-docu.patch b/target/linux/bmips/patches-5.10/402-Documentation-add-BCM6358-pincontroller-binding-docu.patch
new file mode 100644
index 0000000000..e4c6343e3f
--- /dev/null
+++ b/target/linux/bmips/patches-5.10/402-Documentation-add-BCM6358-pincontroller-binding-docu.patch
@@ -0,0 +1,152 @@
+From 9fbcbe08479bcb3609952b66627e2d612173229a Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
+Date: Wed, 27 Jul 2016 11:36:00 +0200
+Subject: [PATCH 03/12] Documentation: add BCM6358 pincontroller binding
+ documentation
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add binding documentation for the pincontrol core found in BCM6358 SoCs.
+
+Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
+Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
+---
+ .../pinctrl/brcm,bcm6358-pinctrl.yaml         | 131 ++++++++++++++++++
+ 1 file changed, 131 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6358-pinctrl.yaml
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6358-pinctrl.yaml
+@@ -0,0 +1,131 @@
++# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/pinctrl/brcm,bcm6358-pinctrl.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: Broadcom BCM6358 pin controller
++
++maintainers:
++  - Álvaro Fernández Rojas <noltari@gmail.com>
++  - Jonas Gorski <jonas.gorski@gmail.com>
++
++description: |+
++  The pin controller node should be the child of a syscon node.
++
++  Refer to the the bindings described in
++  Documentation/devicetree/bindings/mfd/syscon.yaml
++
++properties:
++  compatible:
++    const: brcm,bcm6358-pinctrl
++
++  gpio-controller: true
++
++  '#gpio-cells':
++    description:
++      Specifies the pin number and flags, as defined in
++      include/dt-bindings/gpio/gpio.h
++    const: 2
++
++  interrupts-extended:
++    description:
++      One interrupt per each of the 4 GPIO ports supported by the controller,
++      sorted by port number ascending order.
++    minItems: 6
++    maxItems: 6
++
++patternProperties:
++  '^.*$':
++    if:
++      type: object
++    then:
++      properties:
++        function:
++          $ref: "/schemas/types.yaml#/definitions/string"
++          enum: [ ebi_cs, uart1, serial_led, legacy_led, led, spi_cs, utopia,
++                  pwm_syn_clk, sys_irq ]
++
++        pins:
++          $ref: "/schemas/types.yaml#/definitions/string"
++          enum: [ ebi_cs_grp, uart1_grp, serial_led_grp, legacy_led_grp,
++                  led_grp, spi_cs_grp, utopia_grp, pwm_syn_clk, sys_irq_grp ]
++
++required:
++  - compatible
++  - gpio-controller
++  - '#gpio-cells'
++
++additionalProperties: false
++
++examples:
++  - |
++    gpio@fffe0080 {
++      compatible = "syscon", "simple-mfd";
++      reg = <0xfffe0080 0x80>;
++
++      pinctrl: pinctrl {
++        compatible = "brcm,bcm6358-pinctrl";
++
++        gpio-controller;
++        #gpio-cells = <2>;
++
++        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 = "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";
++        };
++      };
++    };
diff --git a/target/linux/bmips/patches-5.10/402-pinctrl-add-a-pincontrol-driver-for-BCM6328.patch b/target/linux/bmips/patches-5.10/402-pinctrl-add-a-pincontrol-driver-for-BCM6328.patch
deleted file mode 100644
index b4043bdc1c..0000000000
--- a/target/linux/bmips/patches-5.10/402-pinctrl-add-a-pincontrol-driver-for-BCM6328.patch
+++ /dev/null
@@ -1,495 +0,0 @@
-From 393e9753f6492c1fdf55891ddee60d955ae8b119 Mon Sep 17 00:00:00 2001
-From: Jonas Gorski <jonas.gorski@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@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"
-+	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@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	0x8
-+
-+#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/bmips/patches-5.10/403-Documentation-add-BCM6358-pincontroller-binding-docu.patch b/target/linux/bmips/patches-5.10/403-Documentation-add-BCM6358-pincontroller-binding-docu.patch
deleted file mode 100644
index e8a7479915..0000000000
--- a/target/linux/bmips/patches-5.10/403-Documentation-add-BCM6358-pincontroller-binding-docu.patch
+++ /dev/null
@@ -1,61 +0,0 @@
-From c7c8fa7f5b5ee9bea751fa7bdae8ff4acde8f26e Mon Sep 17 00:00:00 2001
-From: Jonas Gorski <jonas.gorski@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@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@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@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/bmips/patches-5.10/403-pinctrl-add-a-pincontrol-driver-for-BCM6358.patch b/target/linux/bmips/patches-5.10/403-pinctrl-add-a-pincontrol-driver-for-BCM6358.patch
new file mode 100644
index 0000000000..fb8681d904
--- /dev/null
+++ b/target/linux/bmips/patches-5.10/403-pinctrl-add-a-pincontrol-driver-for-BCM6358.patch
@@ -0,0 +1,582 @@
+From b0e1ebc79a6d7f84f71a758f5a504c8cf954e2e0 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
+Date: Fri, 24 Jun 2016 22:16:01 +0200
+Subject: [PATCH 04/12] pinctrl: add a pincontrol driver for BCM6358
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+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: Álvaro Fernández Rojas <noltari@gmail.com>
+Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
+---
+ drivers/pinctrl/bcm/Kconfig           |  11 +
+ drivers/pinctrl/bcm/Makefile          |   1 +
+ drivers/pinctrl/bcm/pinctrl-bcm6358.c | 526 ++++++++++++++++++++++++++
+ 3 files changed, 538 insertions(+)
+ create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm6358.c
+
+--- a/drivers/pinctrl/bcm/Kconfig
++++ b/drivers/pinctrl/bcm/Kconfig
+@@ -40,6 +40,17 @@ config PINCTRL_BCM6328
+ 	help
+ 	   Say Y here to enable the Broadcom BCM6328 GPIO driver.
+ 
++config PINCTRL_BCM6358
++	bool "Broadcom BCM6358 GPIO driver"
++	depends on OF_GPIO && (BMIPS_GENERIC || COMPILE_TEST)
++	select PINMUX
++	select PINCONF
++	select GENERIC_PINCONF
++	select MFD_SYSCON
++	default BMIPS_GENERIC
++	help
++	   Say Y here to enable the Broadcom BCM6358 GPIO driver.
++
+ config PINCTRL_IPROC_GPIO
+ 	bool "Broadcom iProc GPIO (with PINCONF) driver"
+ 	depends on OF_GPIO && (ARCH_BCM_IPROC || COMPILE_TEST)
+--- a/drivers/pinctrl/bcm/Makefile
++++ b/drivers/pinctrl/bcm/Makefile
+@@ -4,6 +4,7 @@
+ obj-$(CONFIG_PINCTRL_BCM281XX)		+= pinctrl-bcm281xx.o
+ obj-$(CONFIG_PINCTRL_BCM2835)		+= pinctrl-bcm2835.o
+ obj-$(CONFIG_PINCTRL_BCM6328)		+= pinctrl-bcm6328.o
++obj-$(CONFIG_PINCTRL_BCM6358)		+= pinctrl-bcm6358.o
+ obj-$(CONFIG_PINCTRL_IPROC_GPIO)	+= pinctrl-iproc-gpio.o
+ obj-$(CONFIG_PINCTRL_CYGNUS_MUX)	+= pinctrl-cygnus-mux.o
+ obj-$(CONFIG_PINCTRL_NS)		+= pinctrl-ns.o
+--- /dev/null
++++ b/drivers/pinctrl/bcm/pinctrl-bcm6358.c
+@@ -0,0 +1,526 @@
++// SPDX-License-Identifier: GPL-2.0+
++/*
++ * Driver for BCM6358 GPIO unit (pinctrl + GPIO)
++ *
++ * Copyright (C) 2021 Álvaro Fernández Rojas <noltari@gmail.com>
++ * Copyright (C) 2016 Jonas Gorski <jonas.gorski@gmail.com>
++ */
++
++#include <linux/bitops.h>
++#include <linux/gpio.h>
++#include <linux/kernel.h>
++#include <linux/mfd/syscon.h>
++#include <linux/of.h>
++#include <linux/of_gpio.h>
++#include <linux/of_irq.h>
++#include <linux/platform_device.h>
++#include <linux/regmap.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"
++
++#define MODULE_NAME		"bcm6358-pinctrl"
++#define BCM6358_NUM_GPIOS	40
++
++#define BANK_SIZE		sizeof(uint32_t)
++#define PINS_PER_BANK		(BANK_SIZE * BITS_PER_BYTE)
++
++#define BCM6358_DIROUT_REG	0x04
++#define BCM6358_DATA_REG	0x0c
++#define BCM6358_MODE_REG	0x18
++
++#define BCM6358_MODE_MUX_NONE		0
++#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)
++
++struct bcm6358_pingroup {
++	const char *name;
++	const unsigned * const pins;
++	const unsigned num_pins;
++
++	const uint16_t mode_val;
++
++	/* non-GPIO function muxes require the gpio direction to be set */
++	const uint16_t direction;
++};
++
++struct bcm6358_function {
++	const char *name;
++	const char * const *groups;
++	const unsigned num_groups;
++};
++
++struct bcm6358_pinctrl {
++	struct device *dev;
++	struct regmap *regs;
++	struct regmap_field *overlays;
++
++	struct pinctrl_dev *pctl_dev;
++	struct gpio_chip gpio_chip;
++	struct pinctrl_desc pctl_desc;
++	struct pinctrl_gpio_range gpio_range;
++};
++
++#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 inline unsigned int bcm6358_bank_pin(unsigned int pin)
++{
++	return pin % PINS_PER_BANK;
++}
++
++static inline unsigned int bcm6358_reg_off(unsigned int reg, unsigned int pin)
++{
++	return reg - (pin / PINS_PER_BANK) * BANK_SIZE;
++}
++
++static int bcm6358_gpio_direction_input(struct gpio_chip *chip,
++					unsigned int pin)
++{
++	struct bcm6358_pinctrl *pc = gpiochip_get_data(chip);
++	unsigned int dirout = bcm6358_reg_off(BCM6358_DIROUT_REG, pin);
++	unsigned int bank_pin = bcm6358_bank_pin(pin);
++	int ret;
++
++	/*
++	 * Check with the pinctrl driver whether this pin is usable as
++	 * an input GPIO
++	 */
++	ret = pinctrl_gpio_direction_input(chip->base + pin);
++	if (ret)
++		return ret;
++
++	regmap_update_bits(pc->regs, dirout, BIT(bank_pin), 0);
++
++	return 0;
++}
++
++static int bcm6358_gpio_direction_output(struct gpio_chip *chip,
++					 unsigned int pin, int value)
++{
++	struct bcm6358_pinctrl *pc = gpiochip_get_data(chip);
++	unsigned int data = bcm6358_reg_off(BCM6358_DATA_REG, pin);
++	unsigned int dirout = bcm6358_reg_off(BCM6358_DIROUT_REG, pin);
++	unsigned int bank_pin = bcm6358_bank_pin(pin);
++	unsigned int val = value ? BIT(bank_pin) : 0;
++	int ret;
++
++	/*
++	 * Check with the pinctrl driver whether this pin is usable as
++	 * an output GPIO
++	 */
++	ret = pinctrl_gpio_direction_output(chip->base + pin);
++	if (ret)
++		return ret;
++
++	regmap_update_bits(pc->regs, dirout, BIT(bank_pin), BIT(bank_pin));
++	regmap_update_bits(pc->regs, data, BIT(bank_pin), val);
++
++	return 0;
++}
++
++static int bcm6358_gpio_get(struct gpio_chip *chip, unsigned int pin)
++{
++	struct bcm6358_pinctrl *pc = gpiochip_get_data(chip);
++	unsigned int data = bcm6358_reg_off(BCM6358_DATA_REG, pin);
++	unsigned int bank_pin = bcm6358_bank_pin(pin);
++	unsigned int val;
++
++	regmap_read(pc->regs, data, &val);
++
++	return !!(val & BIT(bank_pin));
++}
++
++static int bcm6358_gpio_get_direction(struct gpio_chip *chip, unsigned int pin)
++{
++	struct bcm6358_pinctrl *pc = gpiochip_get_data(chip);
++	unsigned int dirout = bcm6358_reg_off(BCM6358_DIROUT_REG, pin);
++	unsigned int bank_pin = bcm6358_bank_pin(pin);
++	unsigned int val;
++
++	regmap_read(pc->regs, dirout, &val);
++
++	if (val & BIT(bank_pin))
++		return GPIO_LINE_DIRECTION_OUT;
++
++	return GPIO_LINE_DIRECTION_IN;
++}
++
++static void bcm6358_gpio_set(struct gpio_chip *chip, unsigned int pin,
++			     int value)
++{
++	struct bcm6358_pinctrl *pc = gpiochip_get_data(chip);
++	unsigned int data = bcm6358_reg_off(BCM6358_DATA_REG, pin);
++	unsigned int bank_pin = bcm6358_bank_pin(pin);
++	unsigned int val = value ? BIT(bank_pin) : 0;
++
++	regmap_update_bits(pc->regs, data, BIT(bank_pin), val);
++}
++
++static int bcm6358_gpio_to_irq(struct gpio_chip *chip, unsigned gpio)
++{
++	char irq_name[7];
++
++	sprintf(irq_name, "gpio%d", gpio);
++
++	return of_irq_get_byname(chip->of_node, irq_name);
++}
++
++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 *pc = pinctrl_dev_get_drvdata(pctldev);
++	const struct bcm6358_pingroup *pg = &bcm6358_groups[group];
++	unsigned int val = pg->mode_val;
++	unsigned int mask = val;
++	unsigned pin;
++
++	for (pin = 0; pin < pg->num_pins; pin++)
++		mask |= (unsigned long)bcm6358_pins[pin].drv_data;
++
++	regmap_field_update_bits(pc->overlays, mask, val);
++
++	for (pin = 0; pin < pg->num_pins; pin++) {
++		int hw_gpio = bcm6358_pins[pin].number;
++		struct gpio_chip *gc = &pc->gpio_chip;
++
++		if (pg->direction & BIT(pin))
++			gc->direction_output(gc, hw_gpio, 0);
++		else
++			gc->direction_input(gc, hw_gpio);
++	}
++
++	return 0;
++}
++
++static int bcm6358_gpio_request_enable(struct pinctrl_dev *pctldev,
++				       struct pinctrl_gpio_range *range,
++				       unsigned offset)
++{
++	struct bcm6358_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
++	unsigned int mask;
++
++	mask = (unsigned long) bcm6358_pins[offset].drv_data;
++	if (!mask)
++		return 0;
++
++	/* disable all functions using this pin */
++	return regmap_field_update_bits(pc->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,
++	.dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
++	.dt_free_map = pinctrl_utils_free_map,
++};
++
++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 reg_field overlays = REG_FIELD(BCM6358_MODE_REG, 0, 15);
++	struct device *dev = &pdev->dev;
++	struct device_node *np = dev->of_node;
++	struct bcm6358_pinctrl *pc;
++	int err;
++
++	pc = devm_kzalloc(dev, sizeof(*pc), GFP_KERNEL);
++	if (!pc)
++		return -ENOMEM;
++
++	platform_set_drvdata(pdev, pc);
++	pc->dev = dev;
++
++	pc->regs = syscon_node_to_regmap(dev->parent->of_node);
++	if (IS_ERR(pc->regs))
++		return PTR_ERR(pc->regs);
++
++	pc->overlays = devm_regmap_field_alloc(&pdev->dev, pc->regs, overlays);
++	if (IS_ERR(pc->overlays))
++		return PTR_ERR(pc->overlays);
++
++	/* disable all muxes by default */
++	regmap_field_write(pc->overlays, 0);
++
++	pc->gpio_chip.label = MODULE_NAME;
++	pc->gpio_chip.owner = THIS_MODULE;
++	pc->gpio_chip.request = gpiochip_generic_request;
++	pc->gpio_chip.free = gpiochip_generic_free;
++	pc->gpio_chip.direction_input = bcm6358_gpio_direction_input;
++	pc->gpio_chip.direction_output = bcm6358_gpio_direction_output;
++	pc->gpio_chip.get_direction = bcm6358_gpio_get_direction;
++	pc->gpio_chip.get = bcm6358_gpio_get;
++	pc->gpio_chip.set = bcm6358_gpio_set;
++	pc->gpio_chip.set_config = gpiochip_generic_config;
++	pc->gpio_chip.base = -1;
++	pc->gpio_chip.ngpio = BCM6358_NUM_GPIOS;
++	pc->gpio_chip.can_sleep = false;
++	pc->gpio_chip.parent = dev;
++	pc->gpio_chip.of_node = np;
++
++	if (of_get_property(np, "interrupt-names", NULL))
++		pc->gpio_chip.to_irq = bcm6358_gpio_to_irq;
++
++	err = gpiochip_add_data(&pc->gpio_chip, pc);
++	if (err) {
++		dev_err(dev, "could not add GPIO chip\n");
++		return err;
++	}
++
++	pc->pctl_desc.name = MODULE_NAME,
++	pc->pctl_desc.pins = bcm6358_pins,
++	pc->pctl_desc.npins = ARRAY_SIZE(bcm6358_pins),
++	pc->pctl_desc.pctlops = &bcm6358_pctl_ops,
++	pc->pctl_desc.pmxops = &bcm6358_pmx_ops,
++	pc->pctl_desc.owner = THIS_MODULE,
++
++	pc->pctl_dev = devm_pinctrl_register(dev, &pc->pctl_desc, pc);
++	if (IS_ERR(pc->pctl_dev)) {
++		gpiochip_remove(&pc->gpio_chip);
++		return PTR_ERR(pc->pctl_dev);
++	}
++
++	pc->gpio_range.name = MODULE_NAME;
++	pc->gpio_range.npins = BCM6358_NUM_GPIOS;
++	pc->gpio_range.base = pc->gpio_chip.base;
++	pc->gpio_range.gc = &pc->gpio_chip;
++	pinctrl_add_gpio_range(pc->pctl_dev, &pc->gpio_range);
++
++	dev_info(dev, "registered\n");
++
++	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 = MODULE_NAME,
++		.of_match_table = bcm6358_pinctrl_match,
++	},
++};
++
++builtin_platform_driver(bcm6358_pinctrl_driver);
diff --git a/target/linux/bmips/patches-5.10/404-Documentation-add-BCM6362-pincontroller-binding-docu.patch b/target/linux/bmips/patches-5.10/404-Documentation-add-BCM6362-pincontroller-binding-docu.patch
new file mode 100644
index 0000000000..18739091aa
--- /dev/null
+++ b/target/linux/bmips/patches-5.10/404-Documentation-add-BCM6362-pincontroller-binding-docu.patch
@@ -0,0 +1,261 @@
+From 1c839f287a008023b3b3ae7d892b4d25e3d224ad Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
+Date: Wed, 27 Jul 2016 11:36:18 +0200
+Subject: [PATCH 05/12] Documentation: add BCM6362 pincontroller binding
+ documentation
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add binding documentation for the pincontrol core found in BCM6362 SoCs.
+
+Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
+Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
+---
+ .../pinctrl/brcm,bcm6362-pinctrl.yaml         | 240 ++++++++++++++++++
+ 1 file changed, 240 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6362-pinctrl.yaml
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6362-pinctrl.yaml
+@@ -0,0 +1,240 @@
++# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/pinctrl/brcm,bcm6362-pinctrl.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: Broadcom BCM6362 pin controller
++
++maintainers:
++  - Álvaro Fernández Rojas <noltari@gmail.com>
++  - Jonas Gorski <jonas.gorski@gmail.com>
++
++description: |+
++  The pin controller node should be the child of a syscon node.
++
++  Refer to the the bindings described in
++  Documentation/devicetree/bindings/mfd/syscon.yaml
++
++properties:
++  compatible:
++    const: brcm,bcm6362-pinctrl
++
++  gpio-controller: true
++
++  '#gpio-cells':
++    description:
++      Specifies the pin number and flags, as defined in
++      include/dt-bindings/gpio/gpio.h
++    const: 2
++
++  interrupts-extended:
++    description:
++      One interrupt per each of the 4 GPIO ports supported by the controller,
++      sorted by port number ascending order.
++    minItems: 4
++    maxItems: 4
++
++patternProperties:
++  '^.*$':
++    if:
++      type: object
++    then:
++      properties:
++        function:
++          $ref: "/schemas/types.yaml#/definitions/string"
++          enum: [ usb_device_led, sys_irq, serial_led_clk, serial_led_data,
++                  robosw_led_data, robosw_led_clk, robosw_led0, robosw_led1,
++                  inet_led, spi_cs2, spi_cs3, ntr_pulse, uart1_scts,
++                  uart1_srts, uart1_sdin, uart1_sdout, adsl_spi_miso,
++                  adsl_spi_mosi, adsl_spi_clk, adsl_spi_cs, ephy0_led,
++                  ephy1_led, ephy2_led, ephy3_led, ext_irq0, ext_irq1,
++                  ext_irq2, ext_irq3, nand ]
++
++        pins:
++          $ref: "/schemas/types.yaml#/definitions/string"
++          enum: [ gpio0, gpio1, gpio2, gpio3, gpio4, gpio5, gpio6, gpio7,
++                  gpio8, gpio9, gpio10, gpio11, gpio12, gpio13, gpio14,
++                  gpio15, gpio16, gpio17, gpio18, gpio19, gpio20, gpio21,
++                  gpio22, gpio23, gpio24, gpio25, gpio26, gpio27, nand_grp ]
++
++required:
++  - compatible
++  - gpio-controller
++  - '#gpio-cells'
++
++additionalProperties: false
++
++examples:
++  - |
++    gpio@10000080 {
++      compatible = "syscon", "simple-mfd";
++      reg = <0x10000080 0x80>;
++
++      pinctrl: pinctrl {
++        compatible = "brcm,bcm6362-pinctrl";
++
++        gpio-controller;
++        #gpio-cells = <2>;
++
++        interrupts-extended = <&ext_intc 0 0>,
++                              <&ext_intc 1 0>,
++                              <&ext_intc 2 0>,
++                              <&ext_intc 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";
++        };
++      };
++    };
diff --git a/target/linux/bmips/patches-5.10/404-pinctrl-add-a-pincontrol-driver-for-BCM6358.patch b/target/linux/bmips/patches-5.10/404-pinctrl-add-a-pincontrol-driver-for-BCM6358.patch
deleted file mode 100644
index d102bda802..0000000000
--- a/target/linux/bmips/patches-5.10/404-pinctrl-add-a-pincontrol-driver-for-BCM6358.patch
+++ /dev/null
@@ -1,432 +0,0 @@
-From fb00ef462f3f8b70ea8902151cc72810fe90b999 Mon Sep 17 00:00:00 2001
-From: Jonas Gorski <jonas.gorski@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@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
-@@ -8,3 +8,11 @@ config PINCTRL_BCM6328
- 	select PINCONF
- 	select PINCTRL_BCM63XX
- 	select GENERIC_PINCONF
-+
-+config PINCTRL_BCM6358
-+	bool "BCM6358 pincontrol driver"
-+	select PINMUX
-+	select PINCONF
-+	select PINCTRL_BCM63XX
-+	select GENERIC_PINCONF
-+	select MFD_SYSCON
---- 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_BCM6358)	+= pinctrl-bcm6358.o
---- /dev/null
-+++ b/drivers/pinctrl/bcm63xx/pinctrl-bcm6358.c
-@@ -0,0 +1,390 @@
-+/*
-+ * 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@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);
-+
-+	mode = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
-+					       "brcm,gpiomode");
-+
-+	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/bmips/patches-5.10/405-Documentation-add-BCM6362-pincontroller-binding-docu.patch b/target/linux/bmips/patches-5.10/405-Documentation-add-BCM6362-pincontroller-binding-docu.patch
deleted file mode 100644
index 9fc424cb4c..0000000000
--- a/target/linux/bmips/patches-5.10/405-Documentation-add-BCM6362-pincontroller-binding-docu.patch
+++ /dev/null
@@ -1,96 +0,0 @@
-From ba03ea8ada2ca71c9095d96a1e4085c2c5cf0e69 Mon Sep 17 00:00:00 2001
-From: Jonas Gorski <jonas.gorski@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@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@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/bmips/patches-5.10/405-pinctrl-add-a-pincontrol-driver-for-BCM6362.patch b/target/linux/bmips/patches-5.10/405-pinctrl-add-a-pincontrol-driver-for-BCM6362.patch
new file mode 100644
index 0000000000..bfc6620ace
--- /dev/null
+++ b/target/linux/bmips/patches-5.10/405-pinctrl-add-a-pincontrol-driver-for-BCM6362.patch
@@ -0,0 +1,849 @@
+From 2872fcb5eac02d3a74d696e6350410a9e66281b4 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
+Date: Fri, 24 Jun 2016 22:17:20 +0200
+Subject: [PATCH 06/12] pinctrl: add a pincontrol driver for BCM6362
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+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: Álvaro Fernández Rojas <noltari@gmail.com>
+Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
+---
+ drivers/pinctrl/bcm/Kconfig           |  11 +
+ drivers/pinctrl/bcm/Makefile          |   1 +
+ drivers/pinctrl/bcm/pinctrl-bcm6362.c | 794 ++++++++++++++++++++++++++
+ 3 files changed, 806 insertions(+)
+ create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm6362.c
+
+--- a/drivers/pinctrl/bcm/Kconfig
++++ b/drivers/pinctrl/bcm/Kconfig
+@@ -51,6 +51,17 @@ config PINCTRL_BCM6358
+ 	help
+ 	   Say Y here to enable the Broadcom BCM6358 GPIO driver.
+ 
++config PINCTRL_BCM6362
++	bool "Broadcom BCM6362 GPIO driver"
++	depends on OF_GPIO && (BMIPS_GENERIC || COMPILE_TEST)
++	select PINMUX
++	select PINCONF
++	select GENERIC_PINCONF
++	select MFD_SYSCON
++	default BMIPS_GENERIC
++	help
++	   Say Y here to enable the Broadcom BCM6362 GPIO driver.
++
+ config PINCTRL_IPROC_GPIO
+ 	bool "Broadcom iProc GPIO (with PINCONF) driver"
+ 	depends on OF_GPIO && (ARCH_BCM_IPROC || COMPILE_TEST)
+--- a/drivers/pinctrl/bcm/Makefile
++++ b/drivers/pinctrl/bcm/Makefile
+@@ -5,6 +5,7 @@ obj-$(CONFIG_PINCTRL_BCM281XX)		+= pinct
+ obj-$(CONFIG_PINCTRL_BCM2835)		+= pinctrl-bcm2835.o
+ obj-$(CONFIG_PINCTRL_BCM6328)		+= pinctrl-bcm6328.o
+ obj-$(CONFIG_PINCTRL_BCM6358)		+= pinctrl-bcm6358.o
++obj-$(CONFIG_PINCTRL_BCM6362)		+= pinctrl-bcm6362.o
+ obj-$(CONFIG_PINCTRL_IPROC_GPIO)	+= pinctrl-iproc-gpio.o
+ obj-$(CONFIG_PINCTRL_CYGNUS_MUX)	+= pinctrl-cygnus-mux.o
+ obj-$(CONFIG_PINCTRL_NS)		+= pinctrl-ns.o
+--- /dev/null
++++ b/drivers/pinctrl/bcm/pinctrl-bcm6362.c
+@@ -0,0 +1,794 @@
++// SPDX-License-Identifier: GPL-2.0+
++/*
++ * Driver for BCM6362 GPIO unit (pinctrl + GPIO)
++ *
++ * Copyright (C) 2021 Álvaro Fernández Rojas <noltari@gmail.com>
++ * Copyright (C) 2016 Jonas Gorski <jonas.gorski@gmail.com>
++ */
++
++#include <linux/bitops.h>
++#include <linux/gpio.h>
++#include <linux/kernel.h>
++#include <linux/mfd/syscon.h>
++#include <linux/of.h>
++#include <linux/of_gpio.h>
++#include <linux/of_irq.h>
++#include <linux/platform_device.h>
++#include <linux/regmap.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"
++
++#define MODULE_NAME		"bcm6362-pinctrl"
++#define BCM6362_NUM_GPIOS	48
++#define BCM6362_NUM_LEDS	24
++
++#define BANK_SIZE		sizeof(uint32_t)
++#define PINS_PER_BANK		(BANK_SIZE * BITS_PER_BYTE)
++
++#define BCM6362_DIROUT_REG	0x04
++#define BCM6362_DATA_REG	0x0c
++#define BCM6362_LED_REG		0x10
++#define BCM6362_MODE_REG	0x18
++#define BCM6362_CTRL_REG	0x1c
++#define BCM6362_BASEMODE_REG	0x38
++#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;
++	uint32_t basemode_mask;
++};
++
++struct bcm6362_pinctrl {
++	struct device *dev;
++	struct regmap *regs;
++
++	struct pinctrl_dev *pctl_dev;
++	struct gpio_chip gpio_chip;
++	struct pinctrl_desc pctl_desc;
++	struct pinctrl_gpio_range gpio_range;
++};
++
++#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 inline unsigned int bcm6362_bank_pin(unsigned int pin)
++{
++	return pin % PINS_PER_BANK;
++}
++
++static inline unsigned int bcm6362_reg_off(unsigned int reg, unsigned int pin)
++{
++	return reg - (pin / PINS_PER_BANK) * BANK_SIZE;
++}
++
++static int bcm6362_gpio_direction_input(struct gpio_chip *chip,
++					unsigned int pin)
++{
++	struct bcm6362_pinctrl *pc = gpiochip_get_data(chip);
++	unsigned int dirout = bcm6362_reg_off(BCM6362_DIROUT_REG, pin);
++	unsigned int bank_pin = bcm6362_bank_pin(pin);
++	int ret;
++
++	/*
++	 * Check with the pinctrl driver whether this pin is usable as
++	 * an input GPIO
++	 */
++	ret = pinctrl_gpio_direction_input(chip->base + pin);
++	if (ret)
++		return ret;
++
++	regmap_update_bits(pc->regs, dirout, BIT(bank_pin), 0);
++
++	return 0;
++}
++
++static int bcm6362_gpio_direction_output(struct gpio_chip *chip,
++					 unsigned int pin, int value)
++{
++	struct bcm6362_pinctrl *pc = gpiochip_get_data(chip);
++	unsigned int data = bcm6362_reg_off(BCM6362_DATA_REG, pin);
++	unsigned int dirout = bcm6362_reg_off(BCM6362_DIROUT_REG, pin);
++	unsigned int bank_pin = bcm6362_bank_pin(pin);
++	unsigned int val = value ? BIT(bank_pin) : 0;
++	int ret;
++
++	/*
++	 * Check with the pinctrl driver whether this pin is usable as
++	 * an output GPIO
++	 */
++	ret = pinctrl_gpio_direction_output(chip->base + pin);
++	if (ret)
++		return ret;
++
++	regmap_update_bits(pc->regs, dirout, BIT(bank_pin), BIT(bank_pin));
++	regmap_update_bits(pc->regs, data, BIT(bank_pin), val);
++
++	return 0;
++}
++
++static int bcm6362_gpio_get(struct gpio_chip *chip, unsigned int pin)
++{
++	struct bcm6362_pinctrl *pc = gpiochip_get_data(chip);
++	unsigned int data = bcm6362_reg_off(BCM6362_DATA_REG, pin);
++	unsigned int bank_pin = bcm6362_bank_pin(pin);
++	unsigned int val;
++
++	regmap_read(pc->regs, data, &val);
++
++	return !!(val & BIT(bank_pin));
++}
++
++static int bcm6362_gpio_get_direction(struct gpio_chip *chip, unsigned int pin)
++{
++	struct bcm6362_pinctrl *pc = gpiochip_get_data(chip);
++	unsigned int dirout = bcm6362_reg_off(BCM6362_DIROUT_REG, pin);
++	unsigned int bank_pin = bcm6362_bank_pin(pin);
++	unsigned int val;
++
++	regmap_read(pc->regs, dirout, &val);
++
++	if (val & BIT(bank_pin))
++		return GPIO_LINE_DIRECTION_OUT;
++
++	return GPIO_LINE_DIRECTION_IN;
++}
++
++static void bcm6362_gpio_set(struct gpio_chip *chip, unsigned int pin,
++			     int value)
++{
++	struct bcm6362_pinctrl *pc = gpiochip_get_data(chip);
++	unsigned int data = bcm6362_reg_off(BCM6362_DATA_REG, pin);
++	unsigned int bank_pin = bcm6362_bank_pin(pin);
++	unsigned int val = value ? BIT(bank_pin) : 0;
++
++	regmap_update_bits(pc->regs, data, BIT(bank_pin), val);
++}
++
++static int bcm6362_gpio_to_irq(struct gpio_chip *chip, unsigned gpio)
++{
++	char irq_name[7];
++
++	sprintf(irq_name, "gpio%d", gpio);
++
++	return of_irq_get_byname(chip->of_node, irq_name);
++}
++
++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_set_gpio(struct bcm6362_pinctrl *pc, unsigned pin)
++{
++	const struct pinctrl_pin_desc *desc = &bcm6362_pins[pin];
++	unsigned int mask = bcm6362_bank_pin(pin);
++
++	if (desc->drv_data)
++		regmap_update_bits(pc->regs, BCM6362_BASEMODE_REG,
++				   (uint32_t) desc->drv_data, 0);
++
++	if (pin < PINS_PER_BANK) {
++		/* base mode 0 => gpio 1 => mux function */
++		regmap_update_bits(pc->regs, BCM6362_MODE_REG, mask, 0);
++
++		/* pins 0-23 might be muxed to led */
++		if (pin < BCM6362_NUM_LEDS)
++			regmap_update_bits(pc->regs, BCM6362_LED_REG, mask, 0);
++	} else {
++		/* ctrl reg 0 => wifi function 1 => gpio */
++		regmap_update_bits(pc->regs, BCM6362_CTRL_REG, mask, mask);
++	}
++}
++
++static int bcm6362_pinctrl_set_mux(struct pinctrl_dev *pctldev,
++				   unsigned selector, unsigned group)
++{
++	struct bcm6362_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
++	const struct bcm6362_pingroup *pg = &bcm6362_groups[group];
++	const struct bcm6362_function *f = &bcm6362_funcs[selector];
++	unsigned i;
++	unsigned int reg;
++	unsigned int val, mask;
++
++	for (i = 0; i < pg->num_pins; i++)
++		bcm6362_set_gpio(pc, pg->pins[i]);
++
++	switch (f->reg) {
++	case BCM6362_LEDCTRL:
++		reg = BCM6362_LED_REG;
++		mask = BIT(pg->pins[0]);
++		val = BIT(pg->pins[0]);
++		break;
++	case BCM6362_MODE:
++		reg = BCM6362_MODE_REG;
++		mask = BIT(pg->pins[0]);
++		val = BIT(pg->pins[0]);
++		break;
++	case BCM6362_CTRL:
++		reg = BCM6362_CTRL_REG;
++		mask = BIT(pg->pins[0]);
++		val = 0;
++		break;
++	case BCM6362_BASEMODE:
++		reg = BCM6362_BASEMODE_REG;
++		mask = f->basemode_mask;
++		val = f->basemode_mask;
++		break;
++	default:
++		WARN_ON(1);
++		return -EINVAL;
++	}
++
++	regmap_update_bits(pc->regs, 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 *pc = pinctrl_dev_get_drvdata(pctldev);
++
++	/* disable all functions using this pin */
++	bcm6362_set_gpio(pc, 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,
++	.dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
++	.dt_free_map = pinctrl_utils_free_map,
++};
++
++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 device *dev = &pdev->dev;
++	struct device_node *np = dev->of_node;
++	struct bcm6362_pinctrl *pc;
++	int err;
++
++	pc = devm_kzalloc(dev, sizeof(*pc), GFP_KERNEL);
++	if (!pc)
++		return -ENOMEM;
++
++	platform_set_drvdata(pdev, pc);
++	pc->dev = dev;
++
++	pc->regs = syscon_node_to_regmap(dev->parent->of_node);
++	if (IS_ERR(pc->regs))
++		return PTR_ERR(pc->regs);
++
++	pc->gpio_chip.label = MODULE_NAME;
++	pc->gpio_chip.owner = THIS_MODULE;
++	pc->gpio_chip.request = gpiochip_generic_request;
++	pc->gpio_chip.free = gpiochip_generic_free;
++	pc->gpio_chip.direction_input = bcm6362_gpio_direction_input;
++	pc->gpio_chip.direction_output = bcm6362_gpio_direction_output;
++	pc->gpio_chip.get_direction = bcm6362_gpio_get_direction;
++	pc->gpio_chip.get = bcm6362_gpio_get;
++	pc->gpio_chip.set = bcm6362_gpio_set;
++	pc->gpio_chip.set_config = gpiochip_generic_config;
++	pc->gpio_chip.base = -1;
++	pc->gpio_chip.ngpio = BCM6362_NUM_GPIOS;
++	pc->gpio_chip.can_sleep = false;
++	pc->gpio_chip.parent = dev;
++	pc->gpio_chip.of_node = np;
++
++	if (of_get_property(np, "interrupt-names", NULL))
++		pc->gpio_chip.to_irq = bcm6362_gpio_to_irq;
++
++	err = gpiochip_add_data(&pc->gpio_chip, pc);
++	if (err) {
++		dev_err(dev, "could not add GPIO chip\n");
++		return err;
++	}
++
++	pc->pctl_desc.name = MODULE_NAME,
++	pc->pctl_desc.pins = bcm6362_pins,
++	pc->pctl_desc.npins = ARRAY_SIZE(bcm6362_pins),
++	pc->pctl_desc.pctlops = &bcm6362_pctl_ops,
++	pc->pctl_desc.pmxops = &bcm6362_pmx_ops,
++	pc->pctl_desc.owner = THIS_MODULE,
++
++	pc->pctl_dev = devm_pinctrl_register(dev, &pc->pctl_desc, pc);
++	if (IS_ERR(pc->pctl_dev)) {
++		gpiochip_remove(&pc->gpio_chip);
++		return PTR_ERR(pc->pctl_dev);
++	}
++
++	pc->gpio_range.name = MODULE_NAME;
++	pc->gpio_range.npins = BCM6362_NUM_GPIOS;
++	pc->gpio_range.base = pc->gpio_chip.base;
++	pc->gpio_range.gc = &pc->gpio_chip;
++	pinctrl_add_gpio_range(pc->pctl_dev, &pc->gpio_range);
++
++	dev_info(dev, "registered\n");
++
++	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 = MODULE_NAME,
++		.of_match_table = bcm6362_pinctrl_match,
++	},
++};
++
++builtin_platform_driver(bcm6362_pinctrl_driver);
diff --git a/target/linux/bmips/patches-5.10/406-Documentation-add-BCM6368-pincontroller-binding-docu.patch b/target/linux/bmips/patches-5.10/406-Documentation-add-BCM6368-pincontroller-binding-docu.patch
new file mode 100644
index 0000000000..59fbdaeaaa
--- /dev/null
+++ b/target/linux/bmips/patches-5.10/406-Documentation-add-BCM6368-pincontroller-binding-docu.patch
@@ -0,0 +1,276 @@
+From 12f1d5123ee405266596eaea238d9810e0628d18 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
+Date: Wed, 27 Jul 2016 11:36:51 +0200
+Subject: [PATCH 07/12] Documentation: add BCM6368 pincontroller binding
+ documentation
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add binding documentation for the pincontrol core found in BCM6368 SoCs.
+
+Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
+Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
+---
+ .../pinctrl/brcm,bcm6368-pinctrl.yaml         | 255 ++++++++++++++++++
+ 1 file changed, 255 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6368-pinctrl.yaml
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6368-pinctrl.yaml
+@@ -0,0 +1,255 @@
++# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/pinctrl/brcm,bcm6368-pinctrl.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: Broadcom BCM6368 pin controller
++
++maintainers:
++  - Álvaro Fernández Rojas <noltari@gmail.com>
++  - Jonas Gorski <jonas.gorski@gmail.com>
++
++description: |+
++  The pin controller node should be the child of a syscon node.
++
++  Refer to the the bindings described in
++  Documentation/devicetree/bindings/mfd/syscon.yaml
++
++properties:
++  compatible:
++    const: brcm,bcm6368-pinctrl
++
++  gpio-controller: true
++
++  '#gpio-cells':
++    description:
++      Specifies the pin number and flags, as defined in
++      include/dt-bindings/gpio/gpio.h
++    const: 2
++
++  interrupts-extended:
++    description:
++      One interrupt per each of the 6 GPIO ports supported by the controller,
++      sorted by port number ascending order.
++    minItems: 6
++    maxItems: 6
++
++patternProperties:
++  '^.*$':
++    if:
++      type: object
++    then:
++      properties:
++        function:
++          $ref: "/schemas/types.yaml#/definitions/string"
++          enum: [ analog_afe_0, analog_afe_1, sys_irq, serial_led_data,
++                  serial_led_clk, inet_led, ephy0_led, ephy1_led, ephy2_led,
++                  ephy3_led, robosw_led_data, robosw_led_clk, robosw_led0,
++                  robosw_led1, usb_device_led, pci_req1, pci_gnt1, pci_intb,
++                  pci_req0, pci_gnt0, pcmcia_cd1, pcmcia_cd2, pcmcia_vs1,
++                  pcmcia_vs2, ebi_cs2, ebi_cs3, spi_cs2, spi_cs3, spi_cs4,
++                  spi_cs5, uart1 ]
++
++        pins:
++          $ref: "/schemas/types.yaml#/definitions/string"
++          enum: [ gpio0, gpio1, gpio2, gpio3, gpio4, gpio5, gpio6, gpio7,
++                  gpio8, gpio9, gpio10, gpio11, gpio12, gpio13, gpio14,
++                  gpio16, gpio17, gpio18, gpio19, gpio20, gpio22, gpio23,
++                  gpio24, gpio25, gpio26, gpio27, gpio28, gpio29, gpio30,
++                  gpio31, uart1_grp ]
++
++required:
++  - compatible
++  - gpio-controller
++  - '#gpio-cells'
++
++additionalProperties: false
++
++examples:
++  - |
++    gpio@10000080 {
++      compatible = "syscon", "simple-mfd";
++      reg = <0x10000080 0x80>;
++
++      pinctrl: pinctrl {
++        compatible = "brcm,bcm6368-pinctrl";
++
++        gpio-controller;
++        #gpio-cells = <2>;
++
++        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 = "gpio32",
++                          "gpio33",
++                          "gpio34",
++                          "gpio35",
++                          "gpio36",
++                          "gpio37";
++
++        pinctrl_analog_afe_0: analog_afe_0 {
++          function = "analog_afe_0";
++          pins = "gpio0";
++        };
++
++        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_cs3";
++          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";
++        };
++      };
++    };
diff --git a/target/linux/bmips/patches-5.10/406-pinctrl-add-a-pincontrol-driver-for-BCM6362.patch b/target/linux/bmips/patches-5.10/406-pinctrl-add-a-pincontrol-driver-for-BCM6362.patch
deleted file mode 100644
index 30b95158e4..0000000000
--- a/target/linux/bmips/patches-5.10/406-pinctrl-add-a-pincontrol-driver-for-BCM6362.patch
+++ /dev/null
@@ -1,733 +0,0 @@
-From eea6b96701d734095e2f823f3a82d9b063f553ae Mon Sep 17 00:00:00 2001
-From: Jonas Gorski <jonas.gorski@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@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
-@@ -16,3 +16,10 @@ config PINCTRL_BCM6358
- 	select PINCTRL_BCM63XX
- 	select GENERIC_PINCONF
- 	select MFD_SYSCON
-+
-+config PINCTRL_BCM6362
-+	bool "BCM6362 pincontrol driver"
-+	select PINMUX
-+	select PINCONF
-+	select PINCTRL_BCM63XX
-+	select GENERIC_PINCONF
---- 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_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@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->mode;
-+		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/bmips/patches-5.10/407-Documentation-add-BCM6368-pincontroller-binding-docu.patch b/target/linux/bmips/patches-5.10/407-Documentation-add-BCM6368-pincontroller-binding-docu.patch
deleted file mode 100644
index e0a698fc12..0000000000
--- a/target/linux/bmips/patches-5.10/407-Documentation-add-BCM6368-pincontroller-binding-docu.patch
+++ /dev/null
@@ -1,84 +0,0 @@
-From 30594cf9bfff176a9e4b14c50dcd8b9d0cc3edec Mon Sep 17 00:00:00 2001
-From: Jonas Gorski <jonas.gorski@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@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@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@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/bmips/patches-5.10/407-pinctrl-add-a-pincontrol-driver-for-BCM6368.patch b/target/linux/bmips/patches-5.10/407-pinctrl-add-a-pincontrol-driver-for-BCM6368.patch
new file mode 100644
index 0000000000..5a5dac3487
--- /dev/null
+++ b/target/linux/bmips/patches-5.10/407-pinctrl-add-a-pincontrol-driver-for-BCM6368.patch
@@ -0,0 +1,732 @@
+From a212dcb2f04ae42f35ec11122a2532b1bcf8a94f Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
+Date: Fri, 24 Jun 2016 22:18:25 +0200
+Subject: [PATCH 08/12] pinctrl: add a pincontrol driver for BCM6368
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add a pincontrol driver for BCM6368. BCM6368 allows muxing the first 32
+GPIOs onto alternative functions. Not all are documented.
+
+Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
+Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
+---
+ drivers/pinctrl/bcm/Kconfig           |  11 +
+ drivers/pinctrl/bcm/Makefile          |   1 +
+ drivers/pinctrl/bcm/pinctrl-bcm6368.c | 679 ++++++++++++++++++++++++++
+ 3 files changed, 691 insertions(+)
+ create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm6368.c
+
+--- a/drivers/pinctrl/bcm/Kconfig
++++ b/drivers/pinctrl/bcm/Kconfig
+@@ -62,6 +62,17 @@ config PINCTRL_BCM6362
+ 	help
+ 	   Say Y here to enable the Broadcom BCM6362 GPIO driver.
+ 
++config PINCTRL_BCM6368
++	bool "Broadcom BCM6368 GPIO driver"
++	depends on OF_GPIO && (BMIPS_GENERIC || COMPILE_TEST)
++	select PINMUX
++	select PINCONF
++	select GENERIC_PINCONF
++	select MFD_SYSCON
++	default BMIPS_GENERIC
++	help
++	   Say Y here to enable the Broadcom BCM6368 GPIO driver.
++
+ config PINCTRL_IPROC_GPIO
+ 	bool "Broadcom iProc GPIO (with PINCONF) driver"
+ 	depends on OF_GPIO && (ARCH_BCM_IPROC || COMPILE_TEST)
+--- a/drivers/pinctrl/bcm/Makefile
++++ b/drivers/pinctrl/bcm/Makefile
+@@ -6,6 +6,7 @@ obj-$(CONFIG_PINCTRL_BCM2835)		+= pinctr
+ obj-$(CONFIG_PINCTRL_BCM6328)		+= pinctrl-bcm6328.o
+ obj-$(CONFIG_PINCTRL_BCM6358)		+= pinctrl-bcm6358.o
+ obj-$(CONFIG_PINCTRL_BCM6362)		+= pinctrl-bcm6362.o
++obj-$(CONFIG_PINCTRL_BCM6368)		+= pinctrl-bcm6368.o
+ obj-$(CONFIG_PINCTRL_IPROC_GPIO)	+= pinctrl-iproc-gpio.o
+ obj-$(CONFIG_PINCTRL_CYGNUS_MUX)	+= pinctrl-cygnus-mux.o
+ obj-$(CONFIG_PINCTRL_NS)		+= pinctrl-ns.o
+--- /dev/null
++++ b/drivers/pinctrl/bcm/pinctrl-bcm6368.c
+@@ -0,0 +1,679 @@
++// SPDX-License-Identifier: GPL-2.0+
++/*
++ * Driver for BCM6368 GPIO unit (pinctrl + GPIO)
++ *
++ * Copyright (C) 2021 Álvaro Fernández Rojas <noltari@gmail.com>
++ * Copyright (C) 2016 Jonas Gorski <jonas.gorski@gmail.com>
++ */
++
++#include <linux/bitops.h>
++#include <linux/gpio.h>
++#include <linux/kernel.h>
++#include <linux/mfd/syscon.h>
++#include <linux/of.h>
++#include <linux/of_gpio.h>
++#include <linux/of_irq.h>
++#include <linux/platform_device.h>
++#include <linux/regmap.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"
++
++#define MODULE_NAME		"bcm6368-pinctrl"
++#define BCM6368_NUM_GPIOS	38
++
++#define BANK_SIZE		sizeof(uint32_t)
++#define PINS_PER_BANK		(BANK_SIZE * BITS_PER_BYTE)
++
++#define BCM6368_DIROUT_REG	0x04
++#define BCM6368_DATA_REG	0x0c
++#define BCM6368_MODE_REG	0x18
++#define BCM6368_BASEMODE_REG	0x38
++#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 device *dev;
++	struct regmap *regs;
++	struct regmap_field *overlays;
++
++	struct pinctrl_dev *pctl_dev;
++	struct gpio_chip gpio_chip;
++	struct pinctrl_desc pctl_desc;
++	struct pinctrl_gpio_range gpio_range;
++};
++
++#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 inline unsigned int bcm6368_bank_pin(unsigned int pin)
++{
++	return pin % PINS_PER_BANK;
++}
++
++static inline unsigned int bcm6368_reg_off(unsigned int reg, unsigned int pin)
++{
++	return reg - (pin / PINS_PER_BANK) * BANK_SIZE;
++}
++
++static int bcm6368_gpio_direction_input(struct gpio_chip *chip,
++					unsigned int pin)
++{
++	struct bcm6368_pinctrl *pc = gpiochip_get_data(chip);
++	unsigned int dirout = bcm6368_reg_off(BCM6368_DIROUT_REG, pin);
++	unsigned int bank_pin = bcm6368_bank_pin(pin);
++	int ret;
++
++	/*
++	 * Check with the pinctrl driver whether this pin is usable as
++	 * an input GPIO
++	 */
++	ret = pinctrl_gpio_direction_input(chip->base + pin);
++	if (ret)
++		return ret;
++
++	regmap_update_bits(pc->regs, dirout, BIT(bank_pin), 0);
++
++	return 0;
++}
++
++static int bcm6368_gpio_direction_output(struct gpio_chip *chip,
++					 unsigned int pin, int value)
++{
++	struct bcm6368_pinctrl *pc = gpiochip_get_data(chip);
++	unsigned int data = bcm6368_reg_off(BCM6368_DATA_REG, pin);
++	unsigned int dirout = bcm6368_reg_off(BCM6368_DIROUT_REG, pin);
++	unsigned int bank_pin = bcm6368_bank_pin(pin);
++	unsigned int val = value ? BIT(bank_pin) : 0;
++	int ret;
++
++	/*
++	 * Check with the pinctrl driver whether this pin is usable as
++	 * an output GPIO
++	 */
++	ret = pinctrl_gpio_direction_output(chip->base + pin);
++	if (ret)
++		return ret;
++
++	regmap_update_bits(pc->regs, dirout, BIT(bank_pin), BIT(bank_pin));
++	regmap_update_bits(pc->regs, data, BIT(bank_pin), val);
++
++	return 0;
++}
++
++static int bcm6368_gpio_get(struct gpio_chip *chip, unsigned int pin)
++{
++	struct bcm6368_pinctrl *pc = gpiochip_get_data(chip);
++	unsigned int data = bcm6368_reg_off(BCM6368_DATA_REG, pin);
++	unsigned int bank_pin = bcm6368_bank_pin(pin);
++	unsigned int val;
++
++	regmap_read(pc->regs, data, &val);
++
++	return !!(val & BIT(bank_pin));
++}
++
++static int bcm6368_gpio_get_direction(struct gpio_chip *chip, unsigned int pin)
++{
++	struct bcm6368_pinctrl *pc = gpiochip_get_data(chip);
++	unsigned int dirout = bcm6368_reg_off(BCM6368_DIROUT_REG, pin);
++	unsigned int bank_pin = bcm6368_bank_pin(pin);
++	unsigned int val;
++
++	regmap_read(pc->regs, dirout, &val);
++
++	if (val & BIT(bank_pin))
++		return GPIO_LINE_DIRECTION_OUT;
++
++	return GPIO_LINE_DIRECTION_IN;
++}
++
++static void bcm6368_gpio_set(struct gpio_chip *chip, unsigned int pin,
++			     int value)
++{
++	struct bcm6368_pinctrl *pc = gpiochip_get_data(chip);
++	unsigned int data = bcm6368_reg_off(BCM6368_DATA_REG, pin);
++	unsigned int bank_pin = bcm6368_bank_pin(pin);
++	unsigned int val = value ? BIT(bank_pin) : 0;
++
++	regmap_update_bits(pc->regs, data, BIT(bank_pin), val);
++}
++
++static int bcm6368_gpio_to_irq(struct gpio_chip *chip, unsigned gpio)
++{
++	char irq_name[7];
++
++	sprintf(irq_name, "gpio%d", gpio);
++
++	return of_irq_get_byname(chip->of_node, irq_name);
++}
++
++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 int bcm6368_pinctrl_set_mux(struct pinctrl_dev *pctldev,
++				   unsigned selector, unsigned group)
++{
++	struct bcm6368_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
++	const struct bcm6368_pingroup *pg = &bcm6368_groups[group];
++	const struct bcm6368_function *fun = &bcm6368_funcs[selector];
++	int i, pin;
++
++	if (fun->basemode) {
++		unsigned int mask = 0;
++
++		for (i = 0; i < pg->num_pins; i++) {
++			pin = pg->pins[i];
++			if (pin < PINS_PER_BANK)
++				mask |= BIT(pin);
++		}
++
++		regmap_update_bits(pc->regs, BCM6368_MODE_REG, mask, 0);
++		regmap_field_write(pc->overlays, fun->basemode);
++	} else {
++		pin = pg->pins[0];
++
++		if (bcm6368_pins[pin].drv_data)
++			regmap_field_write(pc->overlays,
++					   BCM6368_BASEMODE_GPIO);
++
++		regmap_update_bits(pc->regs, BCM6368_MODE_REG, BIT(pin),
++				   BIT(pin));
++	}
++
++	for (pin = 0; pin < pg->num_pins; pin++) {
++		int hw_gpio = bcm6368_pins[pin].number;
++		struct gpio_chip *gc = &pc->gpio_chip;
++
++		if (fun->dir_out & BIT(pin))
++			gc->direction_output(gc, hw_gpio, 0);
++		else
++			gc->direction_input(gc, hw_gpio);
++	}
++
++	return 0;
++}
++
++static int bcm6368_gpio_request_enable(struct pinctrl_dev *pctldev,
++				       struct pinctrl_gpio_range *range,
++				       unsigned offset)
++{
++	struct bcm6368_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
++
++	if (offset >= PINS_PER_BANK && !bcm6368_pins[offset].drv_data)
++		return 0;
++
++	/* disable all functions using this pin */
++	if (offset < PINS_PER_BANK)
++		regmap_update_bits(pc->regs, BCM6368_MODE_REG, BIT(offset), 0);
++
++	if (bcm6368_pins[offset].drv_data)
++		regmap_field_write(pc->overlays, BCM6368_BASEMODE_GPIO);
++
++	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,
++	.dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
++	.dt_free_map = pinctrl_utils_free_map,
++};
++
++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 reg_field overlays = REG_FIELD(BCM6368_BASEMODE_REG, 0, 15);
++	struct device *dev = &pdev->dev;
++	struct device_node *np = dev->of_node;
++	struct bcm6368_pinctrl *pc;
++	int err;
++
++	pc = devm_kzalloc(dev, sizeof(*pc), GFP_KERNEL);
++	if (!pc)
++		return -ENOMEM;
++
++	platform_set_drvdata(pdev, pc);
++	pc->dev = dev;
++
++	pc->regs = syscon_node_to_regmap(dev->parent->of_node);
++	if (IS_ERR(pc->regs))
++		return PTR_ERR(pc->regs);
++
++	pc->overlays = devm_regmap_field_alloc(&pdev->dev, pc->regs, overlays);
++	if (IS_ERR(pc->overlays))
++		return PTR_ERR(pc->overlays);
++
++	/* disable all muxes by default */
++	regmap_field_write(pc->overlays, 0);
++
++	pc->gpio_chip.label = MODULE_NAME;
++	pc->gpio_chip.owner = THIS_MODULE;
++	pc->gpio_chip.request = gpiochip_generic_request;
++	pc->gpio_chip.free = gpiochip_generic_free;
++	pc->gpio_chip.direction_input = bcm6368_gpio_direction_input;
++	pc->gpio_chip.direction_output = bcm6368_gpio_direction_output;
++	pc->gpio_chip.get_direction = bcm6368_gpio_get_direction;
++	pc->gpio_chip.get = bcm6368_gpio_get;
++	pc->gpio_chip.set = bcm6368_gpio_set;
++	pc->gpio_chip.set_config = gpiochip_generic_config;
++	pc->gpio_chip.base = -1;
++	pc->gpio_chip.ngpio = BCM6368_NUM_GPIOS;
++	pc->gpio_chip.can_sleep = false;
++	pc->gpio_chip.parent = dev;
++	pc->gpio_chip.of_node = np;
++
++	if (of_get_property(np, "interrupt-names", NULL))
++		pc->gpio_chip.to_irq = bcm6368_gpio_to_irq;
++
++	err = gpiochip_add_data(&pc->gpio_chip, pc);
++	if (err) {
++		dev_err(dev, "could not add GPIO chip\n");
++		return err;
++	}
++
++	pc->pctl_desc.name = MODULE_NAME,
++	pc->pctl_desc.pins = bcm6368_pins,
++	pc->pctl_desc.npins = ARRAY_SIZE(bcm6368_pins),
++	pc->pctl_desc.pctlops = &bcm6368_pctl_ops,
++	pc->pctl_desc.pmxops = &bcm6368_pmx_ops,
++	pc->pctl_desc.owner = THIS_MODULE,
++
++	pc->pctl_dev = devm_pinctrl_register(dev, &pc->pctl_desc, pc);
++	if (IS_ERR(pc->pctl_dev)) {
++		gpiochip_remove(&pc->gpio_chip);
++		return PTR_ERR(pc->pctl_dev);
++	}
++
++	pc->gpio_range.name = MODULE_NAME;
++	pc->gpio_range.npins = BCM6368_NUM_GPIOS;
++	pc->gpio_range.base = pc->gpio_chip.base;
++	pc->gpio_range.gc = &pc->gpio_chip;
++	pinctrl_add_gpio_range(pc->pctl_dev, &pc->gpio_range);
++
++	dev_info(dev, "registered\n");
++
++	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 = MODULE_NAME,
++		.of_match_table = bcm6368_pinctrl_match,
++	},
++};
++
++builtin_platform_driver(bcm6368_pinctrl_driver);
diff --git a/target/linux/bmips/patches-5.10/408-Documentation-add-BCM63268-pincontroller-binding-doc.patch b/target/linux/bmips/patches-5.10/408-Documentation-add-BCM63268-pincontroller-binding-doc.patch
new file mode 100644
index 0000000000..d51af84328
--- /dev/null
+++ b/target/linux/bmips/patches-5.10/408-Documentation-add-BCM63268-pincontroller-binding-doc.patch
@@ -0,0 +1,220 @@
+From 826266914f8397c996d2d4d821b315d614bfc325 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
+Date: Wed, 27 Jul 2016 11:37:08 +0200
+Subject: [PATCH 09/12] Documentation: add BCM63268 pincontroller binding
+ documentation
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add binding documentation for the pincontrol core found in the BCM63268
+family SoCs.
+
+Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
+Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
+---
+ .../pinctrl/brcm,bcm63268-pinctrl.yaml        | 198 ++++++++++++++++++
+ 1 file changed, 198 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm63268-pinctrl.yaml
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm63268-pinctrl.yaml
+@@ -0,0 +1,198 @@
++# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/pinctrl/brcm,bcm63268-pinctrl.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: Broadcom BCM63268 pin controller
++
++maintainers:
++  - Álvaro Fernández Rojas <noltari@gmail.com>
++  - Jonas Gorski <jonas.gorski@gmail.com>
++
++description: |+
++  The pin controller node should be the child of a syscon node.
++
++  Refer to the the bindings described in
++  Documentation/devicetree/bindings/mfd/syscon.yaml
++
++properties:
++  compatible:
++    const: brcm,bcm63268-pinctrl
++
++  gpio-controller: true
++
++  '#gpio-cells':
++    description:
++      Specifies the pin number and flags, as defined in
++      include/dt-bindings/gpio/gpio.h
++    const: 2
++
++  interrupts-extended:
++    description:
++      One interrupt per each of the 4 GPIO ports supported by the controller,
++      sorted by port number ascending order.
++    minItems: 4
++    maxItems: 4
++
++patternProperties:
++  '^.*$':
++    if:
++      type: object
++    then:
++      properties:
++        function:
++          $ref: "/schemas/types.yaml#/definitions/string"
++          enum: [ serial_led_clk, serial_led_data, hsspi_cs4, hsspi_cs5,
++                  hsspi_cs6, hsspi_cs7, adsl_spi_miso, adsl_spi_mosi,
++                  vreq_clk, pcie_clkreq_b, robosw_led_clk, robosw_led_data,
++                  nand, gpio35_alt, dectpd, vdsl_phy_override_0,
++                  vdsl_phy_override_1, vdsl_phy_override_2,
++                  vdsl_phy_override_3, dsl_gpio8, dsl_gpio9 ]
++
++        pins:
++          $ref: "/schemas/types.yaml#/definitions/string"
++          enum: [ gpio0, gpio1, gpio16, gpio17, gpio8, gpio9, gpio18, gpio19,
++                  gpio22, gpio23, gpio30, gpio31, nand_grp, gpio35
++                  dectpd_grp, vdsl_phy_override_0_grp,
++                  vdsl_phy_override_1_grp, vdsl_phy_override_2_grp,
++                  vdsl_phy_override_3_grp, dsl_gpio8, dsl_gpio9 ]
++
++required:
++  - compatible
++  - gpio-controller
++  - '#gpio-cells'
++
++additionalProperties: false
++
++examples:
++  - |
++    gpio@100000c0 {
++      compatible = "syscon", "simple-mfd";
++      reg = <0x100000c0 0x80>;
++
++      pinctrl: pinctrl {
++        compatible = "brcm,bcm63268-pinctrl";
++
++        gpio-controller;
++        #gpio-cells = <2>;
++
++        interrupts-extended = <&ext_intc 0 0>,
++                              <&ext_intc 1 0>,
++                              <&ext_intc 2 0>,
++                              <&ext_intc 3 0>;
++        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";
++        };
++      };
++    };
diff --git a/target/linux/bmips/patches-5.10/408-pinctrl-add-a-pincontrol-driver-for-BCM6368.patch b/target/linux/bmips/patches-5.10/408-pinctrl-add-a-pincontrol-driver-for-BCM6368.patch
deleted file mode 100644
index 80b007799f..0000000000
--- a/target/linux/bmips/patches-5.10/408-pinctrl-add-a-pincontrol-driver-for-BCM6368.patch
+++ /dev/null
@@ -1,610 +0,0 @@
-From 90be3cb4f1a45b8be4a4ec264cd66c2f8e893fcb Mon Sep 17 00:00:00 2001
-From: Jonas Gorski <jonas.gorski@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@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
-@@ -23,3 +23,11 @@ config PINCTRL_BCM6362
- 	select PINCONF
- 	select PINCTRL_BCM63XX
- 	select GENERIC_PINCONF
-+
-+config PINCTRL_BCM6368
-+	bool "BCM6368 pincontrol driver"
-+	select PINMUX
-+	select PINCONF
-+	select PINCTRL_BCM63XX
-+	select GENERIC_PINCONF
-+	select MFD_SYSCON
---- 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_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,570 @@
-+/*
-+ * 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@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);
-+
-+	basemode = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
-+						   "brcm,gpiobasemode");
-+
-+	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, basemode, 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/bmips/patches-5.10/409-Documentation-add-BCM63268-pincontroller-binding-doc.patch b/target/linux/bmips/patches-5.10/409-Documentation-add-BCM63268-pincontroller-binding-doc.patch
deleted file mode 100644
index ffe842fd73..0000000000
--- a/target/linux/bmips/patches-5.10/409-Documentation-add-BCM63268-pincontroller-binding-doc.patch
+++ /dev/null
@@ -1,106 +0,0 @@
-From 28cc80e4ada5d73d5305fd268297825cd8d01936 Mon Sep 17 00:00:00 2001
-From: Jonas Gorski <jonas.gorski@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@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@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/bmips/patches-5.10/409-pinctrl-add-a-pincontrol-driver-for-BCM63268.patch b/target/linux/bmips/patches-5.10/409-pinctrl-add-a-pincontrol-driver-for-BCM63268.patch
new file mode 100644
index 0000000000..8acc5dbfbb
--- /dev/null
+++ b/target/linux/bmips/patches-5.10/409-pinctrl-add-a-pincontrol-driver-for-BCM63268.patch
@@ -0,0 +1,875 @@
+From 8ec959299a6e4bbdc65d62180aa952ae04cdcf07 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
+Date: Fri, 24 Jun 2016 22:19:12 +0200
+Subject: [PATCH 10/12] pinctrl: add a pincontrol driver for BCM63268
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+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: Álvaro Fernández Rojas <noltari@gmail.com>
+Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
+---
+ drivers/pinctrl/bcm/Kconfig            |  11 +
+ drivers/pinctrl/bcm/Makefile           |   1 +
+ drivers/pinctrl/bcm/pinctrl-bcm63268.c | 821 +++++++++++++++++++++++++
+ 3 files changed, 833 insertions(+)
+ create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm63268.c
+
+--- a/drivers/pinctrl/bcm/Kconfig
++++ b/drivers/pinctrl/bcm/Kconfig
+@@ -73,6 +73,17 @@ config PINCTRL_BCM6368
+ 	help
+ 	   Say Y here to enable the Broadcom BCM6368 GPIO driver.
+ 
++config PINCTRL_BCM63268
++	bool "Broadcom BCM63268 GPIO driver"
++	depends on OF_GPIO && (BMIPS_GENERIC || COMPILE_TEST)
++	select PINMUX
++	select PINCONF
++	select GENERIC_PINCONF
++	select MFD_SYSCON
++	default BMIPS_GENERIC
++	help
++	   Say Y here to enable the Broadcom BCM63268 GPIO driver.
++
+ config PINCTRL_IPROC_GPIO
+ 	bool "Broadcom iProc GPIO (with PINCONF) driver"
+ 	depends on OF_GPIO && (ARCH_BCM_IPROC || COMPILE_TEST)
+--- a/drivers/pinctrl/bcm/Makefile
++++ b/drivers/pinctrl/bcm/Makefile
+@@ -7,6 +7,7 @@ obj-$(CONFIG_PINCTRL_BCM6328)		+= pinctr
+ 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
+ obj-$(CONFIG_PINCTRL_IPROC_GPIO)	+= pinctrl-iproc-gpio.o
+ obj-$(CONFIG_PINCTRL_CYGNUS_MUX)	+= pinctrl-cygnus-mux.o
+ obj-$(CONFIG_PINCTRL_NS)		+= pinctrl-ns.o
+--- /dev/null
++++ b/drivers/pinctrl/bcm/pinctrl-bcm63268.c
+@@ -0,0 +1,821 @@
++// SPDX-License-Identifier: GPL-2.0+
++/*
++ * Driver for BCM63268 GPIO unit (pinctrl + GPIO)
++ *
++ * Copyright (C) 2021 Álvaro Fernández Rojas <noltari@gmail.com>
++ * Copyright (C) 2016 Jonas Gorski <jonas.gorski@gmail.com>
++ */
++
++#include <linux/bitops.h>
++#include <linux/gpio.h>
++#include <linux/kernel.h>
++#include <linux/mfd/syscon.h>
++#include <linux/of.h>
++#include <linux/of_gpio.h>
++#include <linux/of_irq.h>
++#include <linux/platform_device.h>
++#include <linux/regmap.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"
++
++#define MODULE_NAME			"bcm63268-pinctrl"
++#define BCM63268_NUM_GPIOS		52
++#define BCM63268_NUM_LEDS		24
++
++#define BANK_SIZE			sizeof(uint32_t)
++#define PINS_PER_BANK			(BANK_SIZE * BITS_PER_BYTE)
++
++#define BCM63268_DIROUT_REG		0x04
++#define BCM63268_DATA_REG		0x0c
++#define BCM63268_LED_REG		0x10
++#define BCM63268_MODE_REG		0x18
++#define BCM63268_CTRL_REG		0x1c
++#define BCM63268_BASEMODE_REG		0x38
++#define  BCM63268_BASEMODE_NAND		BIT(2) /* GPIOs 2-7, 24-31 */
++#define  BCM63268_BASEMODE_GPIO35	BIT(4) /* GPIO 35 */
++#define  BCM63268_BASEMODE_DECTPD	BIT(5) /* GPIOs 8/9 */
++#define  BCM63268_BASEMODE_VDSL_PHY_0	BIT(6) /* GPIOs 10/11 */
++#define  BCM63268_BASEMODE_VDSL_PHY_1	BIT(7) /* GPIOs 12/13 */
++#define  BCM63268_BASEMODE_VDSL_PHY_2	BIT(8) /* GPIOs 24/25 */
++#define  BCM63268_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;
++	uint32_t mask;
++};
++
++struct bcm63268_pinctrl {
++	struct device *dev;
++	struct regmap *regs;
++
++	struct pinctrl_dev *pctl_dev;
++	struct gpio_chip gpio_chip;
++	struct pinctrl_desc pctl_desc;
++	struct pinctrl_gpio_range gpio_range;
++};
++
++#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", BCM63268_BASEMODE_NAND),
++	BCM63268_PIN(3, "gpio3", BCM63268_BASEMODE_NAND),
++	BCM63268_PIN(4, "gpio4", BCM63268_BASEMODE_NAND),
++	BCM63268_PIN(5, "gpio5", BCM63268_BASEMODE_NAND),
++	BCM63268_PIN(6, "gpio6", BCM63268_BASEMODE_NAND),
++	BCM63268_PIN(7, "gpio7", BCM63268_BASEMODE_NAND),
++	BCM63268_PIN(8, "gpio8", BCM63268_BASEMODE_DECTPD),
++	BCM63268_PIN(9, "gpio9", BCM63268_BASEMODE_DECTPD),
++	BCM63268_PIN(10, "gpio10", BCM63268_BASEMODE_VDSL_PHY_0),
++	BCM63268_PIN(11, "gpio11", BCM63268_BASEMODE_VDSL_PHY_0),
++	BCM63268_PIN(12, "gpio12", BCM63268_BASEMODE_VDSL_PHY_1),
++	BCM63268_PIN(13, "gpio13", BCM63268_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",
++		     BCM63268_BASEMODE_NAND | BCM63268_BASEMODE_VDSL_PHY_2),
++	BCM63268_PIN(25, "gpio25",
++		     BCM63268_BASEMODE_NAND | BCM63268_BASEMODE_VDSL_PHY_2),
++	BCM63268_PIN(26, "gpio26",
++		     BCM63268_BASEMODE_NAND | BCM63268_BASEMODE_VDSL_PHY_3),
++	BCM63268_PIN(27, "gpio27",
++		     BCM63268_BASEMODE_NAND | BCM63268_BASEMODE_VDSL_PHY_3),
++	BCM63268_PIN(28, "gpio28", BCM63268_BASEMODE_NAND),
++	BCM63268_PIN(29, "gpio29", BCM63268_BASEMODE_NAND),
++	BCM63268_PIN(30, "gpio30", BCM63268_BASEMODE_NAND),
++	BCM63268_PIN(31, "gpio31", BCM63268_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, BCM63268_BASEMODE_NAND),
++	BCM63268_BASEMODE_FUN(dectpd, BCM63268_BASEMODE_DECTPD),
++	BCM63268_BASEMODE_FUN(vdsl_phy_override_0,
++			      BCM63268_BASEMODE_VDSL_PHY_0),
++	BCM63268_BASEMODE_FUN(vdsl_phy_override_1,
++			      BCM63268_BASEMODE_VDSL_PHY_1),
++	BCM63268_BASEMODE_FUN(vdsl_phy_override_2,
++			      BCM63268_BASEMODE_VDSL_PHY_2),
++	BCM63268_BASEMODE_FUN(vdsl_phy_override_3,
++			      BCM63268_BASEMODE_VDSL_PHY_3),
++};
++
++static inline unsigned int bcm63268_bank_pin(unsigned int pin)
++{
++	return pin % PINS_PER_BANK;
++}
++
++static inline unsigned int bcm63268_reg_off(unsigned int reg, unsigned int pin)
++{
++	return reg - (pin / PINS_PER_BANK) * BANK_SIZE;
++}
++
++static int bcm63268_gpio_direction_input(struct gpio_chip *chip,
++					unsigned int pin)
++{
++	struct bcm63268_pinctrl *pc = gpiochip_get_data(chip);
++	unsigned int dirout = bcm63268_reg_off(BCM63268_DIROUT_REG, pin);
++	unsigned int bank_pin = bcm63268_bank_pin(pin);
++	int ret;
++
++	/*
++	 * Check with the pinctrl driver whether this pin is usable as
++	 * an input GPIO
++	 */
++	ret = pinctrl_gpio_direction_input(chip->base + pin);
++	if (ret)
++		return ret;
++
++	regmap_update_bits(pc->regs, dirout, BIT(bank_pin), 0);
++
++	return 0;
++}
++
++static int bcm63268_gpio_direction_output(struct gpio_chip *chip,
++					 unsigned int pin, int value)
++{
++	struct bcm63268_pinctrl *pc = gpiochip_get_data(chip);
++	unsigned int data = bcm63268_reg_off(BCM63268_DATA_REG, pin);
++	unsigned int dirout = bcm63268_reg_off(BCM63268_DIROUT_REG, pin);
++	unsigned int bank_pin = bcm63268_bank_pin(pin);
++	unsigned int val = value ? BIT(bank_pin) : 0;
++	int ret;
++
++	/*
++	 * Check with the pinctrl driver whether this pin is usable as
++	 * an output GPIO
++	 */
++	ret = pinctrl_gpio_direction_output(chip->base + pin);
++	if (ret)
++		return ret;
++
++	regmap_update_bits(pc->regs, dirout, BIT(bank_pin), BIT(bank_pin));
++	regmap_update_bits(pc->regs, data, BIT(bank_pin), val);
++
++	return 0;
++}
++
++static int bcm63268_gpio_get(struct gpio_chip *chip, unsigned int pin)
++{
++	struct bcm63268_pinctrl *pc = gpiochip_get_data(chip);
++	unsigned int data = bcm63268_reg_off(BCM63268_DATA_REG, pin);
++	unsigned int bank_pin = bcm63268_bank_pin(pin);
++	unsigned int val;
++
++	regmap_read(pc->regs, data, &val);
++
++	return !!(val & BIT(bank_pin));
++}
++
++static int bcm63268_gpio_get_direction(struct gpio_chip *chip, unsigned int pin)
++{
++	struct bcm63268_pinctrl *pc = gpiochip_get_data(chip);
++	unsigned int dirout = bcm63268_reg_off(BCM63268_DIROUT_REG, pin);
++	unsigned int bank_pin = bcm63268_bank_pin(pin);
++	unsigned int val;
++
++	regmap_read(pc->regs, dirout, &val);
++
++	if (val & BIT(bank_pin))
++		return GPIO_LINE_DIRECTION_OUT;
++
++	return GPIO_LINE_DIRECTION_IN;
++}
++
++static void bcm63268_gpio_set(struct gpio_chip *chip, unsigned int pin,
++			     int value)
++{
++	struct bcm63268_pinctrl *pc = gpiochip_get_data(chip);
++	unsigned int data = bcm63268_reg_off(BCM63268_DATA_REG, pin);
++	unsigned int bank_pin = bcm63268_bank_pin(pin);
++	unsigned int val = value ? BIT(bank_pin) : 0;
++
++	regmap_update_bits(pc->regs, data, BIT(bank_pin), val);
++}
++
++static int bcm63268_gpio_to_irq(struct gpio_chip *chip, unsigned gpio)
++{
++	char irq_name[7];
++
++	sprintf(irq_name, "gpio%d", gpio);
++
++	return of_irq_get_byname(chip->of_node, irq_name);
++}
++
++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_set_gpio(struct bcm63268_pinctrl *pc, unsigned pin)
++{
++	const struct pinctrl_pin_desc *desc = &bcm63268_pins[pin];
++	unsigned int basemode = (unsigned long) desc->drv_data;
++	unsigned int mask = BIT(bcm63268_bank_pin(pin));
++
++	if (basemode)
++		regmap_update_bits(pc->regs, BCM63268_BASEMODE_REG, basemode,
++				   0);
++
++	if (pin < PINS_PER_BANK) {
++		/* base mode: 0 => gpio, 1 => mux function */
++		regmap_update_bits(pc->regs, BCM63268_MODE_REG, mask, 0);
++
++		/* pins 0-23 might be muxed to led */
++		if (pin < BCM63268_NUM_LEDS)
++			regmap_update_bits(pc->regs, BCM63268_LED_REG, mask,
++					   0);
++	} else if (pin < BCM63268_NUM_GPIOS) {
++		/* ctrl reg: 0 => wifi function, 1 => gpio */
++		regmap_update_bits(pc->regs, BCM63268_CTRL_REG, mask, mask);
++	}
++}
++
++static int bcm63268_pinctrl_set_mux(struct pinctrl_dev *pctldev,
++				    unsigned selector, unsigned group)
++{
++	struct bcm63268_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
++	const struct bcm63268_pingroup *pg = &bcm63268_groups[group];
++	const struct bcm63268_function *f = &bcm63268_funcs[selector];
++	unsigned i;
++	unsigned int reg;
++	unsigned int val, mask;
++
++	for (i = 0; i < pg->num_pins; i++)
++		bcm63268_set_gpio(pc, pg->pins[i]);
++
++	switch (f->reg) {
++	case BCM63268_LEDCTRL:
++		reg = BCM63268_LED_REG;
++		mask = BIT(pg->pins[0]);
++		val = BIT(pg->pins[0]);
++		break;
++	case BCM63268_MODE:
++		reg = BCM63268_MODE_REG;
++		mask = BIT(pg->pins[0]);
++		val = BIT(pg->pins[0]);
++		break;
++	case BCM63268_CTRL:
++		reg = BCM63268_CTRL_REG;
++		mask = BIT(pg->pins[0]);
++		val = 0;
++		break;
++	case BCM63268_BASEMODE:
++		reg = BCM63268_BASEMODE_REG;
++		mask = f->mask;
++		val = f->mask;
++		break;
++	default:
++		WARN_ON(1);
++		return -EINVAL;
++	}
++
++	regmap_update_bits(pc->regs, 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 *pc = pinctrl_dev_get_drvdata(pctldev);
++
++	/* disable all functions using this pin */
++	bcm63268_set_gpio(pc, 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,
++	.dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
++	.dt_free_map = pinctrl_utils_free_map,
++};
++
++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 device *dev = &pdev->dev;
++	struct device_node *np = dev->of_node;
++	struct bcm63268_pinctrl *pc;
++	int err;
++
++	pc = devm_kzalloc(dev, sizeof(*pc), GFP_KERNEL);
++	if (!pc)
++		return -ENOMEM;
++
++	platform_set_drvdata(pdev, pc);
++	pc->dev = dev;
++
++	pc->regs = syscon_node_to_regmap(dev->parent->of_node);
++	if (IS_ERR(pc->regs))
++		return PTR_ERR(pc->regs);
++
++	pc->gpio_chip.label = MODULE_NAME;
++	pc->gpio_chip.owner = THIS_MODULE;
++	pc->gpio_chip.request = gpiochip_generic_request;
++	pc->gpio_chip.free = gpiochip_generic_free;
++	pc->gpio_chip.direction_input = bcm63268_gpio_direction_input;
++	pc->gpio_chip.direction_output = bcm63268_gpio_direction_output;
++	pc->gpio_chip.get_direction = bcm63268_gpio_get_direction;
++	pc->gpio_chip.get = bcm63268_gpio_get;
++	pc->gpio_chip.set = bcm63268_gpio_set;
++	pc->gpio_chip.set_config = gpiochip_generic_config;
++	pc->gpio_chip.base = -1;
++	pc->gpio_chip.ngpio = BCM63268_NUM_GPIOS;
++	pc->gpio_chip.can_sleep = false;
++	pc->gpio_chip.parent = dev;
++	pc->gpio_chip.of_node = np;
++
++	if (of_get_property(np, "interrupt-names", NULL))
++		pc->gpio_chip.to_irq = bcm63268_gpio_to_irq;
++
++	err = gpiochip_add_data(&pc->gpio_chip, pc);
++	if (err) {
++		dev_err(dev, "could not add GPIO chip\n");
++		return err;
++	}
++
++	pc->pctl_desc.name = MODULE_NAME,
++	pc->pctl_desc.pins = bcm63268_pins,
++	pc->pctl_desc.npins = ARRAY_SIZE(bcm63268_pins),
++	pc->pctl_desc.pctlops = &bcm63268_pctl_ops,
++	pc->pctl_desc.pmxops = &bcm63268_pmx_ops,
++	pc->pctl_desc.owner = THIS_MODULE,
++
++	pc->pctl_dev = devm_pinctrl_register(dev, &pc->pctl_desc, pc);
++	if (IS_ERR(pc->pctl_dev)) {
++		gpiochip_remove(&pc->gpio_chip);
++		return PTR_ERR(pc->pctl_dev);
++	}
++
++	pc->gpio_range.name = MODULE_NAME;
++	pc->gpio_range.npins = BCM63268_NUM_GPIOS;
++	pc->gpio_range.base = pc->gpio_chip.base;
++	pc->gpio_range.gc = &pc->gpio_chip;
++	pinctrl_add_gpio_range(pc->pctl_dev, &pc->gpio_range);
++
++	dev_info(dev, "registered\n");
++
++	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 = MODULE_NAME,
++		.of_match_table = bcm63268_pinctrl_match,
++	},
++};
++
++builtin_platform_driver(bcm63268_pinctrl_driver);
diff --git a/target/linux/bmips/patches-5.10/410-Documentation-add-BCM6318-pincontroller-binding-docu.patch b/target/linux/bmips/patches-5.10/410-Documentation-add-BCM6318-pincontroller-binding-docu.patch
new file mode 100644
index 0000000000..6577038756
--- /dev/null
+++ b/target/linux/bmips/patches-5.10/410-Documentation-add-BCM6318-pincontroller-binding-docu.patch
@@ -0,0 +1,194 @@
+From f909bf5d5cf3db6b35c082f27f7982dfcb1447c2 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
+Date: Wed, 27 Jul 2016 11:38:05 +0200
+Subject: [PATCH 11/12] Documentation: add BCM6318 pincontroller binding
+ documentation
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add binding documentation for the pincontrol core found in BCM6318 SoCs.
+
+Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
+Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
+---
+ .../pinctrl/brcm,bcm6318-pinctrl.yaml         | 173 ++++++++++++++++++
+ 1 file changed, 173 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,bcm6318-pinctrl.yaml
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm6318-pinctrl.yaml
+@@ -0,0 +1,173 @@
++# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/pinctrl/brcm,bcm6318-pinctrl.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: Broadcom BCM6318 pin controller
++
++maintainers:
++  - Álvaro Fernández Rojas <noltari@gmail.com>
++  - Jonas Gorski <jonas.gorski@gmail.com>
++
++description: |+
++  The pin controller node should be the child of a syscon node.
++
++  Refer to the the bindings described in
++  Documentation/devicetree/bindings/mfd/syscon.yaml
++
++properties:
++  compatible:
++    const: brcm,bcm6318-pinctrl
++
++  gpio-controller: true
++
++  '#gpio-cells':
++    description:
++      Specifies the pin number and flags, as defined in
++      include/dt-bindings/gpio/gpio.h
++    const: 2
++
++  interrupts-extended:
++    description:
++      One interrupt per each of the 2 GPIO ports supported by the controller,
++      sorted by port number ascending order.
++    minItems: 2
++    maxItems: 2
++
++patternProperties:
++  '^.*$':
++    if:
++      type: object
++    then:
++      properties:
++        function:
++          $ref: "/schemas/types.yaml#/definitions/string"
++          enum: [ ephy0_spd_led, ephy1_spd_led, ephy2_spd_led, ephy3_spd_led,
++                  ephy0_act_led, ephy1_act_led, ephy2_act_led, ephy3_act_led,
++                  serial_led_data, serial_led_clk, inet_act_led, inet_fail_led,
++                  dsl_led, post_fail_led, wlan_wps_led, usb_pwron,
++                  usb_device_led, usb_active ]
++
++        pins:
++          $ref: "/schemas/types.yaml#/definitions/string"
++          enum: [ gpio0, gpio1, gpio2, gpio3, gpio4, gpio5, gpio6, gpio7,
++                  gpio8, gpio9, gpio10, gpio11, gpio12, gpio13, gpio40 ]
++
++required:
++  - compatible
++  - gpio-controller
++  - '#gpio-cells'
++
++additionalProperties: false
++
++examples:
++  - |
++    gpio@10000080 {
++      compatible = "syscon", "simple-mfd";
++      reg = <0x10000080 0x80>;
++
++      pinctrl: pinctrl {
++        compatible = "brcm,bcm6318-pinctrl";
++
++        gpio-controller;
++        #gpio-cells = <2>;
++
++        interrupts-extended = <&ext_intc 0 0>,
++                              <&ext_intc 1 0>;
++        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";
++        };
++      };
++    };
diff --git a/target/linux/bmips/patches-5.10/410-pinctrl-add-a-pincontrol-driver-for-BCM63268.patch b/target/linux/bmips/patches-5.10/410-pinctrl-add-a-pincontrol-driver-for-BCM63268.patch
deleted file mode 100644
index 1607f23061..0000000000
--- a/target/linux/bmips/patches-5.10/410-pinctrl-add-a-pincontrol-driver-for-BCM63268.patch
+++ /dev/null
@@ -1,749 +0,0 @@
-From 8665d3ea63649cc155286c75f83f694a930580e5 Mon Sep 17 00:00:00 2001
-From: Jonas Gorski <jonas.gorski@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@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/Kconfig
-+++ b/drivers/pinctrl/bcm63xx/Kconfig
-@@ -31,3 +31,10 @@ config PINCTRL_BCM6368
- 	select PINCTRL_BCM63XX
- 	select GENERIC_PINCONF
- 	select MFD_SYSCON
-+
-+config PINCTRL_BCM63268
-+	bool "BCM63268 pincontrol driver"
-+	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_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@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/bmips/patches-5.10/411-Documentation-add-BCM6318-pincontroller-binding-docu.patch b/target/linux/bmips/patches-5.10/411-Documentation-add-BCM6318-pincontroller-binding-docu.patch
deleted file mode 100644
index 5d4265f7fe..0000000000
--- a/target/linux/bmips/patches-5.10/411-Documentation-add-BCM6318-pincontroller-binding-docu.patch
+++ /dev/null
@@ -1,96 +0,0 @@
-From 8439e5d2e69f54a532bb5f8ec001b4b5a3035574 Mon Sep 17 00:00:00 2001
-From: Jonas Gorski <jonas.gorski@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@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@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/bmips/patches-5.10/411-pinctrl-add-a-pincontrol-driver-for-BCM6318.patch b/target/linux/bmips/patches-5.10/411-pinctrl-add-a-pincontrol-driver-for-BCM6318.patch
new file mode 100644
index 0000000000..b57b49d35f
--- /dev/null
+++ b/target/linux/bmips/patches-5.10/411-pinctrl-add-a-pincontrol-driver-for-BCM6318.patch
@@ -0,0 +1,729 @@
+From e1764f96eb563a11c822ff91d1c6d7ed01c3925b Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
+Date: Fri, 24 Jun 2016 22:20:39 +0200
+Subject: [PATCH 12/12] pinctrl: add a pincontrol driver for BCM6318
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+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: Álvaro Fernández Rojas <noltari@gmail.com>
+Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
+---
+ drivers/pinctrl/bcm/Kconfig           |  11 +
+ drivers/pinctrl/bcm/Makefile          |   1 +
+ drivers/pinctrl/bcm/pinctrl-bcm6318.c | 674 ++++++++++++++++++++++++++
+ 3 files changed, 686 insertions(+)
+ create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm6318.c
+
+--- a/drivers/pinctrl/bcm/Kconfig
++++ b/drivers/pinctrl/bcm/Kconfig
+@@ -29,6 +29,17 @@ config PINCTRL_BCM2835
+ 	help
+ 	   Say Y here to enable the Broadcom BCM2835 GPIO driver.
+ 
++config PINCTRL_BCM6318
++	bool "Broadcom BCM6318 GPIO driver"
++	depends on OF_GPIO && (BMIPS_GENERIC || COMPILE_TEST)
++	select PINMUX
++	select PINCONF
++	select GENERIC_PINCONF
++	select MFD_SYSCON
++	default BMIPS_GENERIC
++	help
++	   Say Y here to enable the Broadcom BCM6318 GPIO driver.
++
+ config PINCTRL_BCM6328
+ 	bool "Broadcom BCM6328 GPIO driver"
+ 	depends on OF_GPIO && (BMIPS_GENERIC || COMPILE_TEST)
+--- a/drivers/pinctrl/bcm/Makefile
++++ b/drivers/pinctrl/bcm/Makefile
+@@ -3,6 +3,7 @@
+ 
+ obj-$(CONFIG_PINCTRL_BCM281XX)		+= pinctrl-bcm281xx.o
+ obj-$(CONFIG_PINCTRL_BCM2835)		+= pinctrl-bcm2835.o
++obj-$(CONFIG_PINCTRL_BCM6318)		+= pinctrl-bcm6318.o
+ obj-$(CONFIG_PINCTRL_BCM6328)		+= pinctrl-bcm6328.o
+ obj-$(CONFIG_PINCTRL_BCM6358)		+= pinctrl-bcm6358.o
+ obj-$(CONFIG_PINCTRL_BCM6362)		+= pinctrl-bcm6362.o
+--- /dev/null
++++ b/drivers/pinctrl/bcm/pinctrl-bcm6318.c
+@@ -0,0 +1,674 @@
++// SPDX-License-Identifier: GPL-2.0+
++/*
++ * Driver for BCM6318 GPIO unit (pinctrl + GPIO)
++ *
++ * Copyright (C) 2021 Álvaro Fernández Rojas <noltari@gmail.com>
++ * Copyright (C) 2016 Jonas Gorski <jonas.gorski@gmail.com>
++ */
++
++#include <linux/bitops.h>
++#include <linux/gpio.h>
++#include <linux/kernel.h>
++#include <linux/mfd/syscon.h>
++#include <linux/of.h>
++#include <linux/of_gpio.h>
++#include <linux/of_irq.h>
++#include <linux/platform_device.h>
++#include <linux/regmap.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"
++
++#define MODULE_NAME		"bcm6318-pinctrl"
++#define BCM6318_NUM_GPIOS	50
++#define BCM6318_NUM_MUX		48
++
++#define BANK_SIZE		sizeof(uint32_t)
++#define PINS_PER_BANK		(BANK_SIZE * BITS_PER_BYTE)
++
++#define BCM6318_DIROUT_REG	0x04
++#define BCM6318_DATA_REG	0x0c
++#define BCM6318_MODE_REG	0x18
++#define BCM6318_MUX_REG		0x1c
++#define BCM6318_PAD_REG		0x54
++
++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 device *dev;
++	struct regmap *regs;
++
++	struct pinctrl_dev *pctl_dev;
++	struct gpio_chip gpio_chip;
++	struct pinctrl_desc pctl_desc;
++	struct pinctrl_gpio_range gpio_range;
++};
++
++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 inline unsigned int bcm6318_bank_pin(unsigned int pin)
++{
++	return pin % PINS_PER_BANK;
++}
++
++static inline unsigned int bcm6318_mux_off(unsigned int pin)
++{
++	return BCM6318_MUX_REG + (pin / 16) * BANK_SIZE;
++}
++
++static inline unsigned int bcm6318_pad_off(unsigned int pin)
++{
++	return BCM6318_PAD_REG + (pin / 8) * BANK_SIZE;
++}
++
++static inline unsigned int bcm6318_reg_off(unsigned int reg, unsigned int pin)
++{
++	return reg - (pin / PINS_PER_BANK) * BANK_SIZE;
++}
++
++static int bcm6318_gpio_direction_input(struct gpio_chip *chip,
++					unsigned int pin)
++{
++	struct bcm6318_pinctrl *pc = gpiochip_get_data(chip);
++	unsigned int dirout = bcm6318_reg_off(BCM6318_DIROUT_REG, pin);
++	unsigned int bank_pin = bcm6318_bank_pin(pin);
++	int ret;
++
++	/*
++	 * Check with the pinctrl driver whether this pin is usable as
++	 * an input GPIO
++	 */
++	ret = pinctrl_gpio_direction_input(chip->base + pin);
++	if (ret)
++		return ret;
++
++	regmap_update_bits(pc->regs, dirout, BIT(bank_pin), 0);
++
++	return 0;
++}
++
++static int bcm6318_gpio_direction_output(struct gpio_chip *chip,
++					 unsigned int pin, int value)
++{
++	struct bcm6318_pinctrl *pc = gpiochip_get_data(chip);
++	unsigned int data = bcm6318_reg_off(BCM6318_DATA_REG, pin);
++	unsigned int dirout = bcm6318_reg_off(BCM6318_DIROUT_REG, pin);
++	unsigned int bank_pin = bcm6318_bank_pin(pin);
++	unsigned int val = value ? BIT(bank_pin) : 0;
++	int ret;
++
++	/*
++	 * Check with the pinctrl driver whether this pin is usable as
++	 * an output GPIO
++	 */
++	ret = pinctrl_gpio_direction_output(chip->base + pin);
++	if (ret)
++		return ret;
++
++	regmap_update_bits(pc->regs, dirout, BIT(bank_pin), BIT(bank_pin));
++	regmap_update_bits(pc->regs, data, BIT(bank_pin), val);
++
++	return 0;
++}
++
++static int bcm6318_gpio_get(struct gpio_chip *chip, unsigned int pin)
++{
++	struct bcm6318_pinctrl *pc = gpiochip_get_data(chip);
++	unsigned int data = bcm6318_reg_off(BCM6318_DATA_REG, pin);
++	unsigned int bank_pin = bcm6318_bank_pin(pin);
++	unsigned int val;
++
++	regmap_read(pc->regs, data, &val);
++
++	return !!(val & BIT(bank_pin));
++}
++
++static int bcm6318_gpio_get_direction(struct gpio_chip *chip, unsigned int pin)
++{
++	struct bcm6318_pinctrl *pc = gpiochip_get_data(chip);
++	unsigned int dirout = bcm6318_reg_off(BCM6318_DIROUT_REG, pin);
++	unsigned int bank_pin = bcm6318_bank_pin(pin);
++	unsigned int val;
++
++	regmap_read(pc->regs, dirout, &val);
++
++	if (val & BIT(bank_pin))
++		return GPIO_LINE_DIRECTION_OUT;
++
++	return GPIO_LINE_DIRECTION_IN;
++}
++
++static void bcm6318_gpio_set(struct gpio_chip *chip, unsigned int pin,
++			     int value)
++{
++	struct bcm6318_pinctrl *pc = gpiochip_get_data(chip);
++	unsigned int data = bcm6318_reg_off(BCM6318_DATA_REG, pin);
++	unsigned int bank_pin = bcm6318_bank_pin(pin);
++	unsigned int val = value ? BIT(bank_pin) : 0;
++
++	regmap_update_bits(pc->regs, data, BIT(bank_pin), val);
++}
++
++static int bcm6318_gpio_to_irq(struct gpio_chip *chip, unsigned gpio)
++{
++	char irq_name[7];
++
++	sprintf(irq_name, "gpio%d", gpio);
++
++	return of_irq_get_byname(chip->of_node, irq_name);
++}
++
++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 inline void bcm6318_rmw_mux(struct bcm6318_pinctrl *pc, unsigned pin,
++				   unsigned int mode, unsigned int mux)
++{
++	if (pin < PINS_PER_BANK)
++		regmap_update_bits(pc->regs, BCM6318_MODE_REG, BIT(pin),
++				   mode ? BIT(pin) : 0);
++
++	if (pin < BCM6318_NUM_MUX)
++		regmap_update_bits(pc->regs,
++				   bcm6318_mux_off(pin),
++				   3UL << ((pin % 16) * 2),
++				   mux << ((pin % 16) * 2));
++}
++
++static inline void bcm6318_set_pad(struct bcm6318_pinctrl *pc, unsigned pin,
++				   uint8_t val)
++{
++	regmap_update_bits(pc->regs, bcm6318_pad_off(pin),
++			   0xfUL << ((pin % 8) * 4),
++			   val << ((pin % 8) * 4));
++}
++
++static int bcm6318_pinctrl_set_mux(struct pinctrl_dev *pctldev,
++				   unsigned selector, unsigned group)
++{
++	struct bcm6318_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
++	const struct bcm6318_pingroup *pg = &bcm6318_groups[group];
++	const struct bcm6318_function *f = &bcm6318_funcs[selector];
++
++	bcm6318_rmw_mux(pc, pg->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 *pc = 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(pc, offset, 0, 0);
++	} else if (offset < 42) {
++		/* GPIOs 13-41 use mux 3 as GPIO function */
++		bcm6318_rmw_mux(pc, offset, 0, 3);
++
++		bcm6318_set_pad(pc, offset, 0);
++	}
++
++	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,
++	.dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
++	.dt_free_map = pinctrl_utils_free_map,
++};
++
++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 device *dev = &pdev->dev;
++	struct device_node *np = dev->of_node;
++	struct bcm6318_pinctrl *pc;
++	int err;
++
++	pc = devm_kzalloc(dev, sizeof(*pc), GFP_KERNEL);
++	if (!pc)
++		return -ENOMEM;
++
++	platform_set_drvdata(pdev, pc);
++	pc->dev = dev;
++
++	pc->regs = syscon_node_to_regmap(dev->parent->of_node);
++	if (IS_ERR(pc->regs))
++		return PTR_ERR(pc->regs);
++
++	pc->gpio_chip.label = MODULE_NAME;
++	pc->gpio_chip.owner = THIS_MODULE;
++	pc->gpio_chip.request = gpiochip_generic_request;
++	pc->gpio_chip.free = gpiochip_generic_free;
++	pc->gpio_chip.direction_input = bcm6318_gpio_direction_input;
++	pc->gpio_chip.direction_output = bcm6318_gpio_direction_output;
++	pc->gpio_chip.get_direction = bcm6318_gpio_get_direction;
++	pc->gpio_chip.get = bcm6318_gpio_get;
++	pc->gpio_chip.set = bcm6318_gpio_set;
++	pc->gpio_chip.set_config = gpiochip_generic_config;
++	pc->gpio_chip.base = -1;
++	pc->gpio_chip.ngpio = BCM6318_NUM_GPIOS;
++	pc->gpio_chip.can_sleep = false;
++	pc->gpio_chip.parent = dev;
++	pc->gpio_chip.of_node = np;
++
++	if (of_get_property(np, "interrupt-names", NULL))
++		pc->gpio_chip.to_irq = bcm6318_gpio_to_irq;
++
++	err = gpiochip_add_data(&pc->gpio_chip, pc);
++	if (err) {
++		dev_err(dev, "could not add GPIO chip\n");
++		return err;
++	}
++
++	pc->pctl_desc.name = MODULE_NAME,
++	pc->pctl_desc.pins = bcm6318_pins,
++	pc->pctl_desc.npins = ARRAY_SIZE(bcm6318_pins),
++	pc->pctl_desc.pctlops = &bcm6318_pctl_ops,
++	pc->pctl_desc.pmxops = &bcm6318_pmx_ops,
++	pc->pctl_desc.owner = THIS_MODULE,
++
++	pc->pctl_dev = devm_pinctrl_register(dev, &pc->pctl_desc, pc);
++	if (IS_ERR(pc->pctl_dev)) {
++		gpiochip_remove(&pc->gpio_chip);
++		return PTR_ERR(pc->pctl_dev);
++	}
++
++	pc->gpio_range.name = MODULE_NAME;
++	pc->gpio_range.npins = BCM6318_NUM_GPIOS;
++	pc->gpio_range.base = pc->gpio_chip.base;
++	pc->gpio_range.gc = &pc->gpio_chip;
++	pinctrl_add_gpio_range(pc->pctl_dev, &pc->gpio_range);
++
++	dev_info(dev, "registered\n");
++
++	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 = MODULE_NAME,
++		.of_match_table = bcm6318_pinctrl_match,
++	},
++};
++
++builtin_platform_driver(bcm6318_pinctrl_driver);
diff --git a/target/linux/bmips/patches-5.10/412-pinctrl-add-a-pincontrol-driver-for-BCM6318.patch b/target/linux/bmips/patches-5.10/412-pinctrl-add-a-pincontrol-driver-for-BCM6318.patch
deleted file mode 100644
index 1cc907434c..0000000000
--- a/target/linux/bmips/patches-5.10/412-pinctrl-add-a-pincontrol-driver-for-BCM6318.patch
+++ /dev/null
@@ -1,609 +0,0 @@
-From bd9c250ef85e6f99aa5d59b21abb87d0a48f2f61 Mon Sep 17 00:00:00 2001
-From: Jonas Gorski <jonas.gorski@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@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"
-+	select PINMUX
-+	select PINCONF
-+	select PINCTRL_BCM63XX
-+	select GENERIC_PINCONF
-+
- config PINCTRL_BCM6328
- 	bool "BCM6328 pincontrol driver"
- 	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_BCM6358)	+= pinctrl-bcm6358.o
- obj-$(CONFIG_PINCTRL_BCM6362)	+= pinctrl-bcm6362.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@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);