These patches have been accepted for linux v5.13.
External interrupts not supported for now.
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
reset {
label = "reset";
- gpios = <&pinctrl 32 GPIO_ACTIVE_LOW>;
+ gpios = <&gpio 32 GPIO_ACTIVE_LOW>;
linux,code = <KEY_RESTART>;
debounce-interval = <60>;
};
wps {
label = "wps";
- gpios = <&pinctrl 33 GPIO_ACTIVE_LOW>;
+ gpios = <&gpio 33 GPIO_ACTIVE_LOW>;
linux,code = <KEY_WPS_BUTTON>;
debounce-interval = <60>;
};
};
};
- gpio: syscon@10000080 {
- compatible = "syscon", "simple-mfd";
+ gpio_cntl: syscon@10000080 {
+ compatible = "brcm,bcm6318-gpio-sysctl",
+ "syscon", "simple-mfd";
reg = <0x10000080 0x80>;
+ ranges = <0 0x10000080 0x80>;
native-endian;
- pinctrl: pin-controller {
- compatible = "brcm,bcm6318-pinctrl";
+ gpio: gpio@0 {
+ compatible = "brcm,bcm6318-gpio";
+ reg-names = "dirout", "dat";
+ reg = <0x0 0x8>, <0x8 0x8>;
gpio-controller;
+ gpio-ranges = <&pinctrl 0 0 50>;
#gpio-cells = <2>;
+ };
- interrupts-extended = <&ext_intc 0 0>,
- <&ext_intc 1 0>;
- interrupt-names = "gpio33",
- "gpio34";
+ pinctrl: pinctrl@18 {
+ compatible = "brcm,bcm6318-pinctrl";
+ reg = <0x18 0x10>, <0x54 0x18>;
- pinctrl_ephy0_spd_led: ephy0_spd_led {
+ pinctrl_ephy0_spd_led: ephy0_spd_led-pins {
function = "ephy0_spd_led";
pins = "gpio0";
};
- pinctrl_ephy1_spd_led: ephy1_spd_led {
+ pinctrl_ephy1_spd_led: ephy1_spd_led-pins {
function = "ephy1_spd_led";
pins = "gpio1";
};
- pinctrl_ephy2_spd_led: ephy2_spd_led {
+ pinctrl_ephy2_spd_led: ephy2_spd_led-pins {
function = "ephy2_spd_led";
pins = "gpio2";
};
- pinctrl_ephy3_spd_led: ephy3_spd_led {
+ pinctrl_ephy3_spd_led: ephy3_spd_led-pins {
function = "ephy3_spd_led";
pins = "gpio3";
};
- pinctrl_ephy0_act_led: ephy0_act_led {
+ pinctrl_ephy0_act_led: ephy0_act_led-pins {
function = "ephy0_act_led";
pins = "gpio4";
};
- pinctrl_ephy1_act_led: ephy1_act_led {
+ pinctrl_ephy1_act_led: ephy1_act_led-pins {
function = "ephy1_act_led";
pins = "gpio5";
};
- pinctrl_ephy2_act_led: ephy2_act_led {
+ pinctrl_ephy2_act_led: ephy2_act_led-pins {
function = "ephy2_act_led";
pins = "gpio6";
};
- pinctrl_ephy3_act_led: ephy3_act_led {
+ pinctrl_ephy3_act_led: ephy3_act_led-pins {
function = "ephy3_act_led";
pins = "gpio7";
};
- pinctrl_serial_led: serial_led {
- pinctrl_serial_led_data: serial_led_data {
+ pinctrl_serial_led: serial_led-pins {
+ pinctrl_serial_led_data: serial_led_data-pins {
function = "serial_led_data";
pins = "gpio6";
};
- pinctrl_serial_led_clk: serial_led_clk {
+ pinctrl_serial_led_clk: serial_led_clk-pins {
function = "serial_led_clk";
pins = "gpio7";
};
};
- pinctrl_inet_act_led: inet_act_led {
+ pinctrl_inet_act_led: inet_act_led-pins {
function = "inet_act_led";
pins = "gpio8";
};
- pinctrl_inet_fail_led: inet_fail_led {
+ pinctrl_inet_fail_led: inet_fail_led-pins {
function = "inet_fail_led";
pins = "gpio9";
};
- pinctrl_dsl_led: dsl_led {
+ pinctrl_dsl_led: dsl_led-pins {
function = "dsl_led";
pins = "gpio10";
};
- pinctrl_post_fail_led: post_fail_led {
+ pinctrl_post_fail_led: post_fail_led-pins {
function = "post_fail_led";
pins = "gpio11";
};
- pinctrl_wlan_wps_led: wlan_wps_led {
+ pinctrl_wlan_wps_led: wlan_wps_led-pins {
function = "wlan_wps_led";
pins = "gpio12";
};
- pinctrl_usb_pwron: usb_pwron {
+ pinctrl_usb_pwron: usb_pwron-pins {
function = "usb_pwron";
pins = "gpio13";
};
- pinctrl_usb_device_led: usb_device_led {
+ pinctrl_usb_device_led: usb_device_led-pins {
function = "usb_device_led";
pins = "gpio13";
};
- pinctrl_usb_active: usb_active {
+ pinctrl_usb_active: usb_active-pins {
function = "usb_active";
pins = "gpio40";
};
#reset-cells = <1>;
};
- gpio: syscon@100000c0 {
- compatible = "syscon", "simple-mfd";
+ gpio_cntl: syscon@100000c0 {
+ compatible = "brcm,bcm63268-gpio-sysctl",
+ "syscon", "simple-mfd";
reg = <0x100000c0 0x80>;
+ ranges = <0 0x100000c0 0x80>;
native-endian;
- pinctrl: pin-controller {
- compatible = "brcm,bcm63268-pinctrl";
+ gpio: gpio@0 {
+ compatible = "brcm,bcm63268-gpio";
+ reg-names = "dirout", "dat";
+ reg = <0x0 0x8>, <0x8 0x8>;
gpio-controller;
+ gpio-ranges = <&pinctrl 0 0 52>;
#gpio-cells = <2>;
+ };
+
+ pinctrl: pinctrl@10 {
+ compatible = "brcm,bcm63268-pinctrl";
+ reg = <0x10 0x4>, <0x18 0x8>, <0x38 0x4>;
- 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 {
+ pinctrl_serial_led: serial_led-pins {
+ pinctrl_serial_led_clk: serial_led_clk-pins {
function = "serial_led_clk";
pins = "gpio0";
};
- pinctrl_serial_led_data: serial_led_data {
+ pinctrl_serial_led_data: serial_led_data-pins {
function = "serial_led_data";
pins = "gpio1";
};
};
- pinctrl_hsspi_cs4: hsspi_cs4 {
+ pinctrl_hsspi_cs4: hsspi_cs4-pins {
function = "hsspi_cs4";
pins = "gpio16";
};
- pinctrl_hsspi_cs5: hsspi_cs5 {
+ pinctrl_hsspi_cs5: hsspi_cs5-pins {
function = "hsspi_cs5";
pins = "gpio17";
};
- pinctrl_hsspi_cs6: hsspi_cs6 {
+ pinctrl_hsspi_cs6: hsspi_cs6-pins {
function = "hsspi_cs6";
pins = "gpio8";
};
- pinctrl_hsspi_cs7: hsspi_cs7 {
+ pinctrl_hsspi_cs7: hsspi_cs7-pins {
function = "hsspi_cs7";
pins = "gpio9";
};
pinctrl_adsl_spi: adsl_spi {
- pinctrl_adsl_spi_miso: adsl_spi_miso {
+ pinctrl_adsl_spi_miso: adsl_spi_miso-pins {
function = "adsl_spi_miso";
pins = "gpio18";
};
- pinctrl_adsl_spi_mosi: adsl_spi_mosi {
+ pinctrl_adsl_spi_mosi: adsl_spi_mosi-pins {
function = "adsl_spi_mosi";
pins = "gpio19";
};
};
- pinctrl_vreq_clk: vreq_clk {
+ pinctrl_vreq_clk: vreq_clk-pins {
function = "vreq_clk";
pins = "gpio22";
};
- pinctrl_pcie_clkreq_b: pcie_clkreq_b {
+ pinctrl_pcie_clkreq_b: pcie_clkreq_b-pins {
function = "pcie_clkreq_b";
pins = "gpio23";
};
- pinctrl_robosw_led_clk: robosw_led_clk {
+ pinctrl_robosw_led_clk: robosw_led_clk-pins {
function = "robosw_led_clk";
pins = "gpio30";
};
- pinctrl_robosw_led_data: robosw_led_data {
+ pinctrl_robosw_led_data: robosw_led_data-pins {
function = "robosw_led_data";
pins = "gpio31";
};
- pinctrl_nand: nand {
+ pinctrl_nand: nand-pins {
function = "nand";
group = "nand_grp";
};
- pinctrl_gpio35_alt: gpio35_alt {
+ pinctrl_gpio35_alt: gpio35_alt-pins {
function = "gpio35_alt";
pin = "gpio35";
};
- pinctrl_dectpd: dectpd {
+ pinctrl_dectpd: dectpd-pins {
function = "dectpd";
group = "dectpd_grp";
};
- pinctrl_vdsl_phy_override_0: vdsl_phy_override_0 {
+ pinctrl_vdsl_phy_override_0: vdsl_phy_override_0-pins {
function = "vdsl_phy_override_0";
group = "vdsl_phy_override_0_grp";
};
- pinctrl_vdsl_phy_override_1: vdsl_phy_override_1 {
+ pinctrl_vdsl_phy_override_1: vdsl_phy_override_1-pins {
function = "vdsl_phy_override_1";
group = "vdsl_phy_override_1_grp";
};
- pinctrl_vdsl_phy_override_2: vdsl_phy_override_2 {
+ pinctrl_vdsl_phy_override_2: vdsl_phy_override_2-pins {
function = "vdsl_phy_override_2";
group = "vdsl_phy_override_2_grp";
};
- pinctrl_vdsl_phy_override_3: vdsl_phy_override_3 {
+ pinctrl_vdsl_phy_override_3: vdsl_phy_override_3-pins {
function = "vdsl_phy_override_3";
group = "vdsl_phy_override_3_grp";
};
- pinctrl_dsl_gpio8: dsl_gpio8 {
+ pinctrl_dsl_gpio8: dsl_gpio8-pins {
function = "dsl_gpio8";
group = "dsl_gpio8";
};
- pinctrl_dsl_gpio9: dsl_gpio9 {
+ pinctrl_dsl_gpio9: dsl_gpio9-pins {
function = "dsl_gpio9";
group = "dsl_gpio9";
};
reset {
label = "reset";
- gpios = <&pinctrl 23 GPIO_ACTIVE_LOW>;
+ gpios = <&gpio 23 GPIO_ACTIVE_LOW>;
linux,code = <KEY_RESTART>;
debounce-interval = <60>;
};
};
};
- gpio: syscon@10000080 {
- compatible = "syscon", "simple-mfd";
+ gpio_cntl: syscon@10000080 {
+ compatible = "brcm,bcm6328-gpio-sysctl",
+ "syscon", "simple-mfd";
reg = <0x10000080 0x80>;
+ ranges = <0 0x10000080 0x80>;
native-endian;
- pinctrl: pin-controller {
- compatible = "brcm,bcm6328-pinctrl";
+ gpio: gpio@0 {
+ compatible = "brcm,bcm6328-gpio";
+ reg-names = "dirout", "dat";
+ reg = <0x0 0x8>, <0x8 0x8>;
gpio-controller;
+ gpio-ranges = <&pinctrl 0 0 32>;
#gpio-cells = <2>;
+ };
+
+ pinctrl: pinctrl@18 {
+ compatible = "brcm,bcm6328-pinctrl";
+ reg = <0x18 0x10>;
- 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 {
+ pinctrl_serial_led: serial_led-pins {
+ pinctrl_serial_led_data: serial_led_data-pins {
function = "serial_led_data";
pins = "gpio6";
};
- pinctrl_serial_led_clk: serial_led_clk {
+ pinctrl_serial_led_clk: serial_led_clk-pins {
function = "serial_led_clk";
pins = "gpio7";
};
};
- pinctrl_inet_act_led: inet_act_led {
+ pinctrl_inet_act_led: inet_act_led-pins {
function = "inet_act_led";
pins = "gpio11";
};
- pinctrl_pcie_clkreq: pcie_clkreq {
+ pinctrl_pcie_clkreq: pcie_clkreq-pins {
function = "pcie_clkreq";
pins = "gpio16";
};
- pinctrl_ephy0_spd_led: ephy0_spd_led {
+ pinctrl_ephy0_spd_led: ephy0_spd_led-pins {
function = "led";
pins = "gpio17";
};
- pinctrl_ephy1_spd_led: ephy1_spd_led {
+ pinctrl_ephy1_spd_led: ephy1_spd_led-pins {
function = "led";
pins = "gpio18";
};
- pinctrl_ephy2_spd_led: ephy2_spd_led {
+ pinctrl_ephy2_spd_led: ephy2_spd_led-pins {
function = "led";
pins = "gpio19";
};
- pinctrl_ephy3_spd_led: ephy3_spd_led {
+ pinctrl_ephy3_spd_led: ephy3_spd_led-pins {
function = "led";
pins = "gpio20";
};
- pinctrl_ephy0_act_led: ephy0_act_led {
+ pinctrl_ephy0_act_led: ephy0_act_led-pins {
function = "ephy0_act_led";
pins = "gpio25";
};
- pinctrl_ephy1_act_led: ephy1_act_led {
+ pinctrl_ephy1_act_led: ephy1_act_led-pins {
function = "ephy1_act_led";
pins = "gpio26";
};
- pinctrl_ephy2_act_led: ephy2_act_led {
+ pinctrl_ephy2_act_led: ephy2_act_led-pins {
function = "ephy2_act_led";
pins = "gpio27";
};
- pinctrl_ephy3_act_led: ephy3_act_led {
+ pinctrl_ephy3_act_led: ephy3_act_led-pins {
function = "ephy3_act_led";
pins = "gpio28";
};
- pinctrl_hsspi_cs1: hsspi_cs1 {
+ pinctrl_hsspi_cs1: hsspi_cs1-pins {
function = "hsspi_cs1";
pins = "hsspi_cs1";
};
- pinctrl_usb_port1_device: usb_port1_device {
+ pinctrl_usb_port1_device: usb_port1_device-pins {
function = "usb_device_port";
pins = "usb_port1";
};
- pinctrl_usb_port1_host: usb_port1_host {
+ pinctrl_usb_port1_host: usb_port1_host-pins {
function = "usb_host_port";
pins = "usb_port1";
};
help {
label = "help";
- gpios = <&pinctrl 8 GPIO_ACTIVE_LOW>;
+ gpios = <&gpio 8 GPIO_ACTIVE_LOW>;
linux,code = <KEY_HELP>;
debounce-interval = <60>;
};
wlan {
label = "wlan";
- gpios = <&pinctrl 9 GPIO_ACTIVE_LOW>;
+ gpios = <&gpio 9 GPIO_ACTIVE_LOW>;
linux,code = <KEY_WLAN>;
debounce-interval = <60>;
};
restart {
label = "restart";
- gpios = <&pinctrl 10 GPIO_ACTIVE_LOW>;
+ gpios = <&gpio 10 GPIO_ACTIVE_LOW>;
linux,code = <KEY_RESTART>;
debounce-interval = <60>;
};
reset {
label = "reset";
- gpios = <&pinctrl 11 GPIO_ACTIVE_LOW>;
+ gpios = <&gpio 11 GPIO_ACTIVE_LOW>;
linux,code = <KEY_CONFIG>;
debounce-interval = <60>;
};
led@0 {
label = "red:message";
- gpios = <&pinctrl 0 GPIO_ACTIVE_LOW>;
+ gpios = <&gpio 0 GPIO_ACTIVE_LOW>;
};
hspa_red: led@1 {
label = "red:hspa";
- gpios = <&pinctrl 1 GPIO_ACTIVE_LOW>;
+ gpios = <&gpio 1 GPIO_ACTIVE_LOW>;
};
dsl_red: led@2 {
label = "red:dsl";
- gpios = <&pinctrl 2 GPIO_ACTIVE_LOW>;
+ gpios = <&gpio 2 GPIO_ACTIVE_LOW>;
};
power_red: led@3 {
label = "red:power";
- gpios = <&pinctrl 3 GPIO_ACTIVE_LOW>;
+ gpios = <&gpio 3 GPIO_ACTIVE_LOW>;
};
led@6 {
label = "all";
- gpios = <&pinctrl 6 GPIO_ACTIVE_LOW>;
+ gpios = <&gpio 6 GPIO_ACTIVE_LOW>;
default-state = "on";
};
led@12 {
label = "green:lan1";
- gpios = <&pinctrl 12 GPIO_ACTIVE_LOW>;
+ gpios = <&gpio 12 GPIO_ACTIVE_LOW>;
};
led@13 {
label = "red:lan1";
- gpios = <&pinctrl 13 GPIO_ACTIVE_LOW>;
+ gpios = <&gpio 13 GPIO_ACTIVE_LOW>;
};
led@15 {
label = "green:lan2";
- gpios = <&pinctrl 15 GPIO_ACTIVE_LOW>;
+ gpios = <&gpio 15 GPIO_ACTIVE_LOW>;
};
led@22 {
label = "red:lan2";
- gpios = <&pinctrl 22 GPIO_ACTIVE_LOW>;
+ gpios = <&gpio 22 GPIO_ACTIVE_LOW>;
};
led@23 {
label = "green:lan3";
- gpios = <&pinctrl 23 GPIO_ACTIVE_LOW>;
+ gpios = <&gpio 23 GPIO_ACTIVE_LOW>;
};
led@26 {
label = "red:lan3";
- gpios = <&pinctrl 26 GPIO_ACTIVE_LOW>;
+ gpios = <&gpio 26 GPIO_ACTIVE_LOW>;
};
led@27 {
label = "green:lan4";
- gpios = <&pinctrl 27 GPIO_ACTIVE_LOW>;
+ gpios = <&gpio 27 GPIO_ACTIVE_LOW>;
};
led@28 {
label = "red:lan4";
- gpios = <&pinctrl 28 GPIO_ACTIVE_LOW>;
+ gpios = <&gpio 28 GPIO_ACTIVE_LOW>;
};
};
timeout-sec = <30>;
};
- gpio: syscon@fffe0080 {
- compatible = "syscon", "simple-mfd";
+ gpio_cntl: syscon@fffe0080 {
+ compatible = "brcm,bcm6358-gpio-sysctl",
+ "syscon", "simple-mfd";
reg = <0xfffe0080 0x50>;
+ ranges = <0 0xfffe0080 0x80>;
native-endian;
- pinctrl: pin-controller {
- compatible = "brcm,bcm6358-pinctrl";
+ gpio: gpio@0 {
+ compatible = "brcm,bcm6358-gpio";
+ reg-names = "dirout", "dat";
+ reg = <0x0 0x8>, <0x8 0x8>;
gpio-controller;
+ gpio-ranges = <&pinctrl 0 0 40>;
#gpio-cells = <2>;
+ };
+
+ pinctrl: pinctrl@18 {
+ compatible = "brcm,bcm6358-pinctrl";
+ reg = <0x18 0x4>;
- 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 {
+ pinctrl_ebi_cs: ebi_cs-pins {
function = "ebi_cs";
groups = "ebi_cs_grp";
};
- pinctrl_uart1: uart1 {
+ pinctrl_uart1: uart1-pins {
function = "uart1";
groups = "uart1_grp";
};
- pinctrl_serial_led: serial_led {
+ pinctrl_serial_led: serial_led-pins {
function = "serial_led";
groups = "serial_led_grp";
};
- pinctrl_legacy_led: legacy_led {
+ pinctrl_legacy_led: legacy_led-pins {
function = "legacy_led";
groups = "legacy_led_grp";
};
- pinctrl_led: led {
+ pinctrl_led: led-pins {
function = "led";
groups = "led_grp";
};
- pinctrl_spi_cs_23: spi_cs {
+ pinctrl_spi_cs_23: spi_cs-pins {
function = "spi_cs";
groups = "spi_cs_grp";
};
- pinctrl_utopia: utopia {
+ pinctrl_utopia: utopia-pins {
function = "utopia";
groups = "utopia_grp";
};
- pinctrl_pwm_syn_clk: pwm_syn_clk {
+ pinctrl_pwm_syn_clk: pwm_syn_clk-pins {
function = "pwm_syn_clk";
groups = "pwm_syn_clk_grp";
};
- pinctrl_sys_irq: sys_irq {
+ pinctrl_sys_irq: sys_irq-pins {
function = "sys_irq";
groups = "sys_irq_grp";
};
wlan {
label = "wlan";
- gpios = <&pinctrl 11 GPIO_ACTIVE_LOW>;
+ gpios = <&gpio 11 GPIO_ACTIVE_LOW>;
linux,code = <KEY_WLAN>;
debounce-interval = <60>;
};
wps {
label = "wps";
- gpios = <&pinctrl 25 GPIO_ACTIVE_LOW>;
+ gpios = <&gpio 25 GPIO_ACTIVE_LOW>;
linux,code = <KEY_WPS_BUTTON>;
debounce-interval = <60>;
};
reset {
label = "reset";
- gpios = <&pinctrl 31 GPIO_ACTIVE_LOW>;
+ gpios = <&gpio 31 GPIO_ACTIVE_LOW>;
linux,code = <KEY_RESTART>;
debounce-interval = <60>;
};
led@28 {
label = "green:dsl";
- gpios = <&pinctrl 28 GPIO_ACTIVE_LOW>;
+ gpios = <&gpio 28 GPIO_ACTIVE_LOW>;
};
led@34 {
label = "red:power";
- gpios = <&pinctrl 34 GPIO_ACTIVE_LOW>;
+ gpios = <&gpio 34 GPIO_ACTIVE_LOW>;
};
};
};
timeout-sec = <30>;
};
- gpio: syscon@10000080 {
- compatible = "syscon", "simple-mfd";
+ gpio_cntl: syscon@10000080 {
+ compatible = "brcm,bcm6362-gpio-sysctl",
+ "syscon", "simple-mfd";
reg = <0x10000080 0x80>;
+ ranges = <0 0x10000080 0x80>;
native-endian;
- pinctrl: pin-controller {
- compatible = "brcm,bcm6362-pinctrl";
+ gpio: gpio@0 {
+ compatible = "brcm,bcm6362-gpio";
+ reg-names = "dirout", "dat";
+ reg = <0x0 0x8>, <0x8 0x8>;
gpio-controller;
+ gpio-ranges = <&pinctrl 0 0 48>;
#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: pinctrl@18 {
+ compatible = "brcm,bcm6362-pinctrl";
+ reg = <0x18 0x10>, <0x38 0x4>;
- pinctrl_usb_device_led: usb_device_led {
+ pinctrl_usb_device_led: usb_device_led-pins {
function = "usb_device_led";
pins = "gpio0";
};
- pinctrl_sys_irq: sys_irq {
+ pinctrl_sys_irq: sys_irq-pins {
function = "sys_irq";
pins = "gpio1";
};
- pinctrl_serial_led: serial_led {
- pinctrl_serial_led_clk: serial_led_clk {
+ pinctrl_serial_led: serial_led-pins {
+ pinctrl_serial_led_clk: serial_led_clk-pins {
function = "serial_led_clk";
pins = "gpio2";
};
- pinctrl_serial_led_data: serial_led_data {
+ pinctrl_serial_led_data: serial_led_data-pins {
function = "serial_led_data";
pins = "gpio3";
};
};
- pinctrl_robosw_led_data: robosw_led_data {
+ pinctrl_robosw_led_data: robosw_led_data-pins {
function = "robosw_led_data";
pins = "gpio4";
};
- pinctrl_robosw_led_clk: robosw_led_clk {
+ pinctrl_robosw_led_clk: robosw_led_clk-pins {
function = "robosw_led_clk";
pins = "gpio5";
};
- pinctrl_robosw_led0: robosw_led0 {
+ pinctrl_robosw_led0: robosw_led0-pins {
function = "robosw_led0";
pins = "gpio6";
};
- pinctrl_robosw_led1: robosw_led1 {
+ pinctrl_robosw_led1: robosw_led1-pins {
function = "robosw_led1";
pins = "gpio7";
};
- pinctrl_inet_led: inet_led {
+ pinctrl_inet_led: inet_led-pins {
function = "inet_led";
pins = "gpio8";
};
- pinctrl_spi_cs2: spi_cs2 {
+ pinctrl_spi_cs2: spi_cs2-pins {
function = "spi_cs2";
pins = "gpio9";
};
- pinctrl_spi_cs3: spi_cs3 {
+ pinctrl_spi_cs3: spi_cs3-pins {
function = "spi_cs3";
pins = "gpio10";
};
- pinctrl_ntr_pulse: ntr_pulse {
+ pinctrl_ntr_pulse: ntr_pulse-pins {
function = "ntr_pulse";
pins = "gpio11";
};
- pinctrl_uart1_scts: uart1_scts {
+ pinctrl_uart1_scts: uart1_scts-pins {
function = "uart1_scts";
pins = "gpio12";
};
- pinctrl_uart1_srts: uart1_srts {
+ pinctrl_uart1_srts: uart1_srts-pins {
function = "uart1_srts";
pins = "gpio13";
};
- pinctrl_uart1: uart1 {
- pinctrl_uart1_sdin: uart1_sdin {
+ pinctrl_uart1: uart1-pins {
+ pinctrl_uart1_sdin: uart1_sdin-pins {
function = "uart1_sdin";
pins = "gpio14";
};
- pinctrl_uart1_sdout: uart1_sdout {
+ pinctrl_uart1_sdout: uart1_sdout-pins {
function = "uart1_sdout";
pins = "gpio15";
};
};
- pinctrl_adsl_spi: adsl_spi {
- pinctrl_adsl_spi_miso: adsl_spi_miso {
+ pinctrl_adsl_spi: adsl_spi-pins {
+ pinctrl_adsl_spi_miso: adsl_spi_miso-pins {
function = "adsl_spi_miso";
pins = "gpio16";
};
- pinctrl_adsl_spi_mosi: adsl_spi_mosi {
+ pinctrl_adsl_spi_mosi: adsl_spi_mosi-pins {
function = "adsl_spi_mosi";
pins = "gpio17";
};
- pinctrl_adsl_spi_clk: adsl_spi_clk {
+ pinctrl_adsl_spi_clk: adsl_spi_clk-pins {
function = "adsl_spi_clk";
pins = "gpio18";
};
- pinctrl_adsl_spi_cs: adsl_spi_cs {
+ pinctrl_adsl_spi_cs: adsl_spi_cs-pins {
function = "adsl_spi_cs";
pins = "gpio19";
};
};
- pinctrl_ephy0_led: ephy0_led {
+ pinctrl_ephy0_led: ephy0_led-pins {
function = "ephy0_led";
pins = "gpio20";
};
- pinctrl_ephy1_led: ephy1_led {
+ pinctrl_ephy1_led: ephy1_led-pins {
function = "ephy1_led";
pins = "gpio21";
};
- pinctrl_ephy2_led: ephy2_led {
+ pinctrl_ephy2_led: ephy2_led-pins {
function = "ephy2_led";
pins = "gpio22";
};
- pinctrl_ephy3_led: ephy3_led {
+ pinctrl_ephy3_led: ephy3_led-pins {
function = "ephy3_led";
pins = "gpio23";
};
- pinctrl_ext_irq0: ext_irq0 {
+ pinctrl_ext_irq0: ext_irq0-pins {
function = "ext_irq0";
pins = "gpio24";
};
- pinctrl_ext_irq1: ext_irq1 {
+ pinctrl_ext_irq1: ext_irq1-pins {
function = "ext_irq1";
pins = "gpio25";
};
- pinctrl_ext_irq2: ext_irq2 {
+ pinctrl_ext_irq2: ext_irq2-pins {
function = "ext_irq2";
pins = "gpio26";
};
- pinctrl_ext_irq3: ext_irq3 {
+ pinctrl_ext_irq3: ext_irq3-pins {
function = "ext_irq3";
pins = "gpio27";
};
- pinctrl_nand: nand {
+ pinctrl_nand: nand-pins {
function = "nand";
group = "nand_grp";
};
reset {
label = "reset";
- gpios = <&pinctrl 34 GPIO_ACTIVE_LOW>;
+ gpios = <&gpio 34 GPIO_ACTIVE_LOW>;
linux,code = <KEY_RESTART>;
debounce-interval = <60>;
};
led@2 {
label = "green:dsl";
- gpios = <&pinctrl 2 GPIO_ACTIVE_LOW>;
+ gpios = <&gpio 2 GPIO_ACTIVE_LOW>;
};
led@5 {
label = "green:internet";
- gpios = <&pinctrl 5 GPIO_ACTIVE_HIGH>;
+ gpios = <&gpio 5 GPIO_ACTIVE_HIGH>;
};
led_power_green: led@22 {
label = "green:power";
- gpios = <&pinctrl 22 GPIO_ACTIVE_HIGH>;
+ gpios = <&gpio 22 GPIO_ACTIVE_HIGH>;
};
led_power_red: led@24 {
label = "red:power";
- gpios = <&pinctrl 24 GPIO_ACTIVE_HIGH>;
+ gpios = <&gpio 24 GPIO_ACTIVE_HIGH>;
};
led@31 {
label = "red:internet";
- gpios = <&pinctrl 31 GPIO_ACTIVE_HIGH>;
+ gpios = <&gpio 31 GPIO_ACTIVE_HIGH>;
};
};
timeout-sec = <30>;
};
- gpio: syscon@10000080 {
- compatible = "syscon", "simple-mfd";
+ gpio_cntl: syscon@10000080 {
+ compatible = "brcm,bcm6368-gpio-sysctl",
+ "syscon", "simple-mfd";
reg = <0x10000080 0x80>;
+ ranges = <0 0x10000080 0x80>;
native-endian;
- pinctrl: pin-controller {
- compatible = "brcm,bcm6368-pinctrl";
+ gpio: gpio@0 {
+ compatible = "brcm,bcm6368-gpio";
+ reg-names = "dirout", "dat";
+ reg = <0x0 0x8>, <0x8 0x8>;
gpio-controller;
+ gpio-ranges = <&pinctrl 0 0 38>;
#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 {
+ pinctrl: pinctrl@18 {
+ compatible = "brcm,bcm6368-pinctrl";
+ reg = <0x18 0x4>, <0x38 0x4>;
+
+ pinctrl_analog_afe_0: analog_afe_0-pins {
function = "analog_afe_0";
pins = "gpio0";
};
- pinctrl_analog_afe_1: analog_afe_1 {
+ pinctrl_analog_afe_1: analog_afe_1-pins {
function = "analog_afe_1";
pins = "gpio1";
};
- pinctrl_sys_irq: sys_irq {
+ pinctrl_sys_irq: sys_irq-pins {
function = "sys_irq";
pins = "gpio2";
};
- pinctrl_serial_led: serial_led {
- pinctrl_serial_led_data: serial_led_data {
+ pinctrl_serial_led: serial_led-pins {
+ pinctrl_serial_led_data: serial_led_data-pins {
function = "serial_led_data";
pins = "gpio3";
};
- pinctrl_serial_led_clk: serial_led_clk {
+ pinctrl_serial_led_clk: serial_led_clk-pins {
function = "serial_led_clk";
pins = "gpio4";
};
};
- pinctrl_inet_led: inet_led {
+ pinctrl_inet_led: inet_led-pins {
function = "inet_led";
pins = "gpio5";
};
- pinctrl_ephy0_led: ephy0_led {
+ pinctrl_ephy0_led: ephy0_led-pins {
function = "ephy0_led";
pins = "gpio6";
};
- pinctrl_ephy1_led: ephy1_led {
+ pinctrl_ephy1_led: ephy1_led-pins {
function = "ephy1_led";
pins = "gpio7";
};
- pinctrl_ephy2_led: ephy2_led {
+ pinctrl_ephy2_led: ephy2_led-pins {
function = "ephy2_led";
pins = "gpio8";
};
- pinctrl_ephy3_led: ephy3_led {
+ pinctrl_ephy3_led: ephy3_led-pins {
function = "ephy3_led";
pins = "gpio9";
};
- pinctrl_robosw_led_data: robosw_led_data {
+ pinctrl_robosw_led_data: robosw_led_data-pins {
function = "robosw_led_data";
pins = "gpio10";
};
- pinctrl_robosw_led_clk: robosw_led_clk {
+ pinctrl_robosw_led_clk: robosw_led_clk-pins {
function = "robosw_led_clk";
pins = "gpio11";
};
- pinctrl_robosw_led0: robosw_led0 {
+ pinctrl_robosw_led0: robosw_led0-pins {
function = "robosw_led0";
pins = "gpio12";
};
- pinctrl_robosw_led1: robosw_led1 {
+ pinctrl_robosw_led1: robosw_led1-pins {
function = "robosw_led1";
pins = "gpio13";
};
- pinctrl_usb_device_led: usb_device_led {
+ pinctrl_usb_device_led: usb_device_led-pins {
function = "usb_device_led";
pins = "gpio14";
};
- pinctrl_pci: pci {
- pinctrl_pci_req1: pci_req1 {
+ pinctrl_pci: pci-pins {
+ pinctrl_pci_req1: pci_req1-pins {
function = "pci_req1";
pins = "gpio16";
};
- pinctrl_pci_gnt1: pci_gnt1 {
+ pinctrl_pci_gnt1: pci_gnt1-pins {
function = "pci_gnt1";
pins = "gpio17";
};
- pinctrl_pci_intb: pci_intb {
+ pinctrl_pci_intb: pci_intb-pins {
function = "pci_intb";
pins = "gpio18";
};
- pinctrl_pci_req0: pci_req0 {
+ pinctrl_pci_req0: pci_req0-pins {
function = "pci_req0";
pins = "gpio19";
};
- pinctrl_pci_gnt0: pci_gnt0 {
+ pinctrl_pci_gnt0: pci_gnt0-pins {
function = "pci_gnt0";
pins = "gpio20";
};
};
- pinctrl_pcmcia: pcmcia {
- pinctrl_pcmcia_cd1: pcmcia_cd1 {
+ pinctrl_pcmcia: pcmcia-pins {
+ pinctrl_pcmcia_cd1: pcmcia_cd1-pins {
function = "pcmcia_cd1";
pins = "gpio22";
};
- pinctrl_pcmcia_cd2: pcmcia_cd2 {
+ pinctrl_pcmcia_cd2: pcmcia_cd2-pins {
function = "pcmcia_cd2";
pins = "gpio23";
};
- pinctrl_pcmcia_vs1: pcmcia_vs1 {
+ pinctrl_pcmcia_vs1: pcmcia_vs1-pins {
function = "pcmcia_vs1";
pins = "gpio24";
};
- pinctrl_pcmcia_vs2: pcmcia_vs2 {
+ pinctrl_pcmcia_vs2: pcmcia_vs2-pins {
function = "pcmcia_vs2";
pins = "gpio25";
};
};
- pinctrl_ebi_cs2: ebi_cs2 {
+ pinctrl_ebi_cs2: ebi_cs2-pins {
function = "ebi_cs2";
pins = "gpio26";
};
- pinctrl_ebi_cs3: ebi_cs3 {
+ pinctrl_ebi_cs3: ebi_cs3-pins {
function = "ebi_cs3";
pins = "gpio27";
};
- pinctrl_spi_cs2: spi_cs2 {
+ pinctrl_spi_cs2: spi_cs2-pins {
function = "spi_cs2";
pins = "gpio28";
};
- pinctrl_spi_cs3: spi_cs3 {
+ pinctrl_spi_cs3: spi_cs3-pins {
function = "spi_cs3";
pins = "gpio29";
};
- pinctrl_spi_cs4: spi_cs4 {
+ pinctrl_spi_cs4: spi_cs4-pins {
function = "spi_cs4";
pins = "gpio30";
};
- pinctrl_spi_cs5: spi_cs5 {
+ pinctrl_spi_cs5: spi_cs5-pins {
function = "spi_cs5";
pins = "gpio31";
};
- pinctrl_uart1: uart1 {
+ pinctrl_uart1: uart1-pins {
function = "uart1";
group = "uart1_grp";
};
};
};
- gpiobasemode: gpiobasemode@100000b8 {
- compatible = "brcm,bcm6368-gpiobasemode", "syscon";
- reg = <0x100000b8 0x4>;
- };
-
leds: led-controller@100000d0 {
#address-cells = <1>;
#size-cells = <0>;
--- /dev/null
+From 9c7d24693d864f90b27aad5d15fbfe226c02898b Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
+Date: Wed, 24 Mar 2021 09:19:02 +0100
+Subject: [PATCH 01/22] gpio: guard gpiochip_irqchip_add_domain() with
+ GPIOLIB_IRQCHIP
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The current code doesn't check if GPIOLIB_IRQCHIP is enabled, which results in
+a compilation error when trying to build gpio-regmap if CONFIG_GPIOLIB_IRQCHIP
+isn't enabled.
+
+Fixes: 6a45b0e2589f ("gpiolib: Introduce gpiochip_irqchip_add_domain()")
+Suggested-by: Michael Walle <michael@walle.cc>
+Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
+Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
+Reviewed-by: Michael Walle <michael@walle.cc>
+Acked-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
+Link: https://lore.kernel.org/r/20210324081923.20379-2-noltari@gmail.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ include/linux/gpio/driver.h | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+--- a/include/linux/gpio/driver.h
++++ b/include/linux/gpio/driver.h
+@@ -637,8 +637,17 @@ int gpiochip_irqchip_add_key(struct gpio
+ bool gpiochip_irqchip_irq_valid(const struct gpio_chip *gc,
+ unsigned int offset);
+
++#ifdef CONFIG_GPIOLIB_IRQCHIP
+ int gpiochip_irqchip_add_domain(struct gpio_chip *gc,
+ struct irq_domain *domain);
++#else
++static inline int gpiochip_irqchip_add_domain(struct gpio_chip *gc,
++ struct irq_domain *domain)
++{
++ WARN_ON(1);
++ return -EINVAL;
++}
++#endif
+
+ #ifdef CONFIG_LOCKDEP
+
--- /dev/null
+From d46bf9ec4596654f36245e3b14765bcb422be6ad Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
+Date: Wed, 24 Mar 2021 09:19:03 +0100
+Subject: [PATCH 02/22] gpio: regmap: set gpio_chip of_node
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This is needed for properly registering GPIO regmap as a child of a regmap
+pin controller.
+
+Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
+Reviewed-by: Michael Walle <michael@walle.cc>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Acked-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
+Link: https://lore.kernel.org/r/20210324081923.20379-3-noltari@gmail.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ drivers/gpio/gpio-regmap.c | 5 +++++
+ include/linux/gpio/regmap.h | 4 ++++
+ 2 files changed, 9 insertions(+)
+
+--- a/drivers/gpio/gpio-regmap.c
++++ b/drivers/gpio/gpio-regmap.c
+@@ -254,6 +254,11 @@ struct gpio_regmap *gpio_regmap_register
+ chip->names = config->names;
+ chip->label = config->label ?: dev_name(config->parent);
+
++#if defined(CONFIG_OF_GPIO)
++ /* gpiolib will use of_node of the parent if chip->of_node is NULL */
++ chip->of_node = to_of_node(config->fwnode);
++#endif /* CONFIG_OF_GPIO */
++
+ /*
+ * If our regmap is fast_io we should probably set can_sleep to false.
+ * Right now, the regmap doesn't save this property, nor is there any
+--- a/include/linux/gpio/regmap.h
++++ b/include/linux/gpio/regmap.h
+@@ -4,6 +4,7 @@
+ #define _LINUX_GPIO_REGMAP_H
+
+ struct device;
++struct fwnode_handle;
+ struct gpio_regmap;
+ struct irq_domain;
+ struct regmap;
+@@ -16,6 +17,8 @@ struct regmap;
+ * @parent: The parent device
+ * @regmap: The regmap used to access the registers
+ * given, the name of the device is used
++ * @fwnode: (Optional) The firmware node.
++ * If not given, the fwnode of the parent is used.
+ * @label: (Optional) Descriptive name for GPIO controller.
+ * If not given, the name of the device is used.
+ * @ngpio: Number of GPIOs
+@@ -57,6 +60,7 @@ struct regmap;
+ struct gpio_regmap_config {
+ struct device *parent;
+ struct regmap *regmap;
++ struct fwnode_handle *fwnode;
+
+ const char *label;
+ int ngpio;
--- /dev/null
+From fb9da17bd26552f48cda4f2f658379e7f5860691 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
+Date: Wed, 24 Mar 2021 09:19:04 +0100
+Subject: [PATCH 03/22] dt-bindings: improve BCM6345 GPIO binding documentation
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Convert existing BCM6345 GPIO binding documentation to YAML and add binding
+documentation for the GPIO controller found in BCM6318, BCM6328, BCM6358,
+BCM6362, BCM6368 and BCM63268 SoCs.
+
+Co-developed-by: Jonas Gorski <jonas.gorski@gmail.com>
+Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
+Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Link: https://lore.kernel.org/r/20210324081923.20379-4-noltari@gmail.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ .../bindings/gpio/brcm,bcm6345-gpio.txt | 46 ----------
+ .../bindings/gpio/brcm,bcm6345-gpio.yaml | 86 +++++++++++++++++++
+ 2 files changed, 86 insertions(+), 46 deletions(-)
+ delete mode 100644 Documentation/devicetree/bindings/gpio/brcm,bcm6345-gpio.txt
+ create mode 100644 Documentation/devicetree/bindings/gpio/brcm,bcm6345-gpio.yaml
+
+--- a/Documentation/devicetree/bindings/gpio/brcm,bcm6345-gpio.txt
++++ /dev/null
+@@ -1,46 +0,0 @@
+-Bindings for the Broadcom's brcm,bcm6345-gpio memory-mapped GPIO controllers.
+-
+-These bindings can be used on any BCM63xx SoC. However, BCM6338 and BCM6345
+-are the only ones which don't need a pinctrl driver.
+-BCM6338 have 8-bit data and dirout registers, where GPIO state can be read
+-and/or written, and the direction changed from input to output.
+-BCM6345 have 16-bit data and dirout registers, where GPIO state can be read
+-and/or written, and the direction changed from input to output.
+-
+-Required properties:
+- - compatible: should be "brcm,bcm6345-gpio"
+- - reg-names: must contain
+- "dat" - data register
+- "dirout" - direction (output) register
+- - reg: address + size pairs describing the GPIO register sets;
+- order must correspond with the order of entries in reg-names
+- - #gpio-cells: must be set to 2. The first cell is the pin number and
+- the second cell is used to specify the gpio polarity:
+- 0 = active high
+- 1 = active low
+- - gpio-controller: Marks the device node as a gpio controller.
+-
+-Optional properties:
+- - native-endian: use native endian memory.
+-
+-Examples:
+- - BCM6338:
+- gpio: gpio-controller@fffe0407 {
+- compatible = "brcm,bcm6345-gpio";
+- reg-names = "dirout", "dat";
+- reg = <0xfffe0407 1>, <0xfffe040f 1>;
+-
+- #gpio-cells = <2>;
+- gpio-controller;
+- };
+-
+- - BCM6345:
+- gpio: gpio-controller@fffe0406 {
+- compatible = "brcm,bcm6345-gpio";
+- reg-names = "dirout", "dat";
+- reg = <0xfffe0406 2>, <0xfffe040a 2>;
+- native-endian;
+-
+- #gpio-cells = <2>;
+- gpio-controller;
+- };
+--- /dev/null
++++ b/Documentation/devicetree/bindings/gpio/brcm,bcm6345-gpio.yaml
+@@ -0,0 +1,86 @@
++# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/gpio/brcm,bcm6345-gpio.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: Broadcom BCM6345 GPIO controller
++
++maintainers:
++ - Álvaro Fernández Rojas <noltari@gmail.com>
++ - Jonas Gorski <jonas.gorski@gmail.com>
++
++description: |+
++ Bindings for Broadcom's BCM63xx memory-mapped GPIO controllers.
++
++ These bindings can be used on any BCM63xx SoC. However, BCM6338 and BCM6345
++ are the only ones which don't need a pinctrl driver.
++
++ BCM6338 have 8-bit data and dirout registers, where GPIO state can be read
++ and/or written, and the direction changed from input to output.
++ BCM6345 have 16-bit data and dirout registers, where GPIO state can be read
++ and/or written, and the direction changed from input to output.
++ BCM6318, BCM6328, BCM6358, BCM6362, BCM6368 and BCM63268 have 32-bit data
++ and dirout registers, where GPIO state can be read and/or written, and the
++ direction changed from input to output.
++
++properties:
++ compatible:
++ enum:
++ - brcm,bcm6318-gpio
++ - brcm,bcm6328-gpio
++ - brcm,bcm6345-gpio
++ - brcm,bcm6358-gpio
++ - brcm,bcm6362-gpio
++ - brcm,bcm6368-gpio
++ - brcm,bcm63268-gpio
++
++ gpio-controller: true
++
++ "#gpio-cells":
++ const: 2
++
++ gpio-ranges:
++ maxItems: 1
++
++ native-endian: true
++
++ reg:
++ maxItems: 2
++
++ reg-names:
++ items:
++ - const: dirout
++ - const: dat
++
++required:
++ - compatible
++ - reg
++ - reg-names
++ - gpio-controller
++ - '#gpio-cells'
++
++additionalProperties: false
++
++examples:
++ - |
++ gpio@fffe0406 {
++ compatible = "brcm,bcm6345-gpio";
++ reg-names = "dirout", "dat";
++ reg = <0xfffe0406 2>, <0xfffe040a 2>;
++ native-endian;
++
++ gpio-controller;
++ #gpio-cells = <2>;
++ };
++
++ - |
++ gpio@0 {
++ compatible = "brcm,bcm63268-gpio";
++ reg-names = "dirout", "dat";
++ reg = <0x0 0x8>, <0x8 0x8>;
++
++ gpio-controller;
++ gpio-ranges = <&pinctrl 0 0 52>;
++ #gpio-cells = <2>;
++ };
--- /dev/null
+From 132f95016db0a0a0659e99b471a7d3fd0c60f961 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
+Date: Wed, 24 Mar 2021 09:19:05 +0100
+Subject: [PATCH 04/22] pinctrl: bcm: add bcm63xx base code
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add a helper for registering BCM63XX pin controllers.
+
+Co-developed-by: Jonas Gorski <jonas.gorski@gmail.com>
+Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
+Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
+Link: https://lore.kernel.org/r/20210324081923.20379-5-noltari@gmail.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ drivers/pinctrl/bcm/Kconfig | 7 ++
+ drivers/pinctrl/bcm/Makefile | 1 +
+ drivers/pinctrl/bcm/pinctrl-bcm63xx.c | 109 ++++++++++++++++++++++++++
+ drivers/pinctrl/bcm/pinctrl-bcm63xx.h | 43 ++++++++++
+ 4 files changed, 160 insertions(+)
+ create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm63xx.c
+ create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm63xx.h
+
+--- a/drivers/pinctrl/bcm/Kconfig
++++ b/drivers/pinctrl/bcm/Kconfig
+@@ -29,6 +29,13 @@ config PINCTRL_BCM2835
+ help
+ Say Y here to enable the Broadcom BCM2835 GPIO driver.
+
++config PINCTRL_BCM63XX
++ bool
++ select GENERIC_PINCONF
++ select GPIO_REGMAP
++ select PINCONF
++ select PINMUX
++
+ 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_BCM63XX) += pinctrl-bcm63xx.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-bcm63xx.c
+@@ -0,0 +1,109 @@
++// SPDX-License-Identifier: GPL-2.0+
++/*
++ * Driver for BCM63xx 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/gpio/regmap.h>
++#include <linux/mfd/syscon.h>
++#include <linux/mod_devicetable.h>
++#include <linux/of.h>
++#include <linux/platform_device.h>
++
++#include "pinctrl-bcm63xx.h"
++
++#define BCM63XX_BANK_SIZE 4
++
++#define BCM63XX_DIROUT_REG 0x04
++#define BCM63XX_DATA_REG 0x0c
++
++static int bcm63xx_reg_mask_xlate(struct gpio_regmap *gpio,
++ unsigned int base, unsigned int offset,
++ unsigned int *reg, unsigned int *mask)
++{
++ unsigned int line = offset % BCM63XX_BANK_GPIOS;
++ unsigned int stride = offset / BCM63XX_BANK_GPIOS;
++
++ *reg = base - stride * BCM63XX_BANK_SIZE;
++ *mask = BIT(line);
++
++ return 0;
++}
++
++static const struct of_device_id bcm63xx_gpio_of_match[] = {
++ { .compatible = "brcm,bcm6318-gpio", },
++ { .compatible = "brcm,bcm6328-gpio", },
++ { .compatible = "brcm,bcm6358-gpio", },
++ { .compatible = "brcm,bcm6362-gpio", },
++ { .compatible = "brcm,bcm6368-gpio", },
++ { .compatible = "brcm,bcm63268-gpio", },
++ { /* sentinel */ }
++};
++
++static int bcm63xx_gpio_probe(struct device *dev, struct device_node *node,
++ const struct bcm63xx_pinctrl_soc *soc,
++ struct bcm63xx_pinctrl *pc)
++{
++ struct gpio_regmap_config grc = {0};
++
++ grc.parent = dev;
++ grc.fwnode = &node->fwnode;
++ grc.ngpio = soc->ngpios;
++ grc.ngpio_per_reg = BCM63XX_BANK_GPIOS;
++ grc.regmap = pc->regs;
++ grc.reg_dat_base = BCM63XX_DATA_REG;
++ grc.reg_dir_out_base = BCM63XX_DIROUT_REG;
++ grc.reg_set_base = BCM63XX_DATA_REG;
++ grc.reg_mask_xlate = bcm63xx_reg_mask_xlate;
++
++ return PTR_ERR_OR_ZERO(devm_gpio_regmap_register(dev, &grc));
++}
++
++int bcm63xx_pinctrl_probe(struct platform_device *pdev,
++ const struct bcm63xx_pinctrl_soc *soc,
++ void *driver_data)
++{
++ struct device *dev = &pdev->dev;
++ struct bcm63xx_pinctrl *pc;
++ struct device_node *node;
++ int err;
++
++ pc = devm_kzalloc(dev, sizeof(*pc), GFP_KERNEL);
++ if (!pc)
++ return -ENOMEM;
++
++ platform_set_drvdata(pdev, pc);
++
++ pc->dev = dev;
++ pc->driver_data = driver_data;
++
++ pc->regs = syscon_node_to_regmap(dev->parent->of_node);
++ if (IS_ERR(pc->regs))
++ return PTR_ERR(pc->regs);
++
++ pc->pctl_desc.name = dev_name(dev);
++ pc->pctl_desc.pins = soc->pins;
++ pc->pctl_desc.npins = soc->npins;
++ pc->pctl_desc.pctlops = soc->pctl_ops;
++ pc->pctl_desc.pmxops = soc->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))
++ return PTR_ERR(pc->pctl_dev);
++
++ for_each_child_of_node(dev->parent->of_node, node) {
++ if (of_match_node(bcm63xx_gpio_of_match, node)) {
++ err = bcm63xx_gpio_probe(dev, node, soc, pc);
++ if (err) {
++ dev_err(dev, "could not add GPIO chip\n");
++ of_node_put(node);
++ return err;
++ }
++ }
++ }
++
++ return 0;
++}
+--- /dev/null
++++ b/drivers/pinctrl/bcm/pinctrl-bcm63xx.h
+@@ -0,0 +1,43 @@
++// SPDX-License-Identifier: GPL-2.0+
++/*
++ * Copyright (C) 2021 Álvaro Fernández Rojas <noltari@gmail.com>
++ * Copyright (C) 2016 Jonas Gorski <jonas.gorski@gmail.com>
++ */
++
++#ifndef __PINCTRL_BCM63XX_H__
++#define __PINCTRL_BCM63XX_H__
++
++#include <linux/pinctrl/pinctrl.h>
++
++#define BCM63XX_BANK_GPIOS 32
++
++struct bcm63xx_pinctrl_soc {
++ struct pinctrl_ops *pctl_ops;
++ struct pinmux_ops *pmx_ops;
++
++ const struct pinctrl_pin_desc *pins;
++ unsigned npins;
++
++ unsigned int ngpios;
++};
++
++struct bcm63xx_pinctrl {
++ struct device *dev;
++ struct regmap *regs;
++
++ struct pinctrl_desc pctl_desc;
++ struct pinctrl_dev *pctl_dev;
++
++ void *driver_data;
++};
++
++static inline unsigned int bcm63xx_bank_pin(unsigned int pin)
++{
++ return pin % BCM63XX_BANK_GPIOS;
++}
++
++int bcm63xx_pinctrl_probe(struct platform_device *pdev,
++ const struct bcm63xx_pinctrl_soc *soc,
++ void *driver_data);
++
++#endif /* __PINCTRL_BCM63XX_H__ */
--- /dev/null
+From 44dbcd8eb08a0febbb46ac7b9331f28a320bdf9a Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
+Date: Wed, 24 Mar 2021 09:19:06 +0100
+Subject: [PATCH 05/22] dt-bindings: 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.
+
+Co-developed-by: Jonas Gorski <jonas.gorski@gmail.com>
+Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
+Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Link: https://lore.kernel.org/r/20210324081923.20379-6-noltari@gmail.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ .../pinctrl/brcm,bcm6328-pinctrl.yaml | 127 ++++++++++++++++++
+ 1 file changed, 127 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,127 @@
++# 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:
++ Bindings for Broadcom's BCM6328 memory-mapped pin controller.
++
++properties:
++ compatible:
++ const: brcm,bcm6328-pinctrl
++
++ reg:
++ maxItems: 1
++
++patternProperties:
++ '-pins$':
++ type: object
++ $ref: pinmux-node.yaml#
++
++ properties:
++ function:
++ 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:
++ enum: [ gpio6, gpio7, gpio11, gpio16, gpio17, gpio18, gpio19,
++ gpio20, gpio25, gpio26, gpio27, gpio28, hsspi_cs1,
++ usb_port1 ]
++
++required:
++ - compatible
++ - reg
++
++additionalProperties: false
++
++examples:
++ - |
++ pinctrl@18 {
++ compatible = "brcm,bcm6328-pinctrl";
++ reg = <0x18 0x10>;
++
++ pinctrl_serial_led: serial_led-pins {
++ pinctrl_serial_led_data: serial_led_data-pins {
++ function = "serial_led_data";
++ pins = "gpio6";
++ };
++
++ pinctrl_serial_led_clk: serial_led_clk-pins {
++ function = "serial_led_clk";
++ pins = "gpio7";
++ };
++ };
++
++ pinctrl_inet_act_led: inet_act_led-pins {
++ function = "inet_act_led";
++ pins = "gpio11";
++ };
++
++ pinctrl_pcie_clkreq: pcie_clkreq-pins {
++ function = "pcie_clkreq";
++ pins = "gpio16";
++ };
++
++ pinctrl_ephy0_spd_led: ephy0_spd_led-pins {
++ function = "led";
++ pins = "gpio17";
++ };
++
++ pinctrl_ephy1_spd_led: ephy1_spd_led-pins {
++ function = "led";
++ pins = "gpio18";
++ };
++
++ pinctrl_ephy2_spd_led: ephy2_spd_led-pins {
++ function = "led";
++ pins = "gpio19";
++ };
++
++ pinctrl_ephy3_spd_led: ephy3_spd_led-pins {
++ function = "led";
++ pins = "gpio20";
++ };
++
++ pinctrl_ephy0_act_led: ephy0_act_led-pins {
++ function = "ephy0_act_led";
++ pins = "gpio25";
++ };
++
++ pinctrl_ephy1_act_led: ephy1_act_led-pins {
++ function = "ephy1_act_led";
++ pins = "gpio26";
++ };
++
++ pinctrl_ephy2_act_led: ephy2_act_led-pins {
++ function = "ephy2_act_led";
++ pins = "gpio27";
++ };
++
++ pinctrl_ephy3_act_led: ephy3_act_led-pins {
++ function = "ephy3_act_led";
++ pins = "gpio28";
++ };
++
++ pinctrl_hsspi_cs1: hsspi_cs1-pins {
++ function = "hsspi_cs1";
++ pins = "hsspi_cs1";
++ };
++
++ pinctrl_usb_port1_device: usb_port1_device-pins {
++ function = "usb_device_port";
++ pins = "usb_port1";
++ };
++
++ pinctrl_usb_port1_host: usb_port1_host-pins {
++ function = "usb_host_port";
++ pins = "usb_port1";
++ };
++ };
--- /dev/null
+From 7f9dfaa2afb6bc3481e531c405b05acf6091af29 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
+Date: Wed, 24 Mar 2021 09:19:07 +0100
+Subject: [PATCH 06/22] dt-bindings: add BCM6328 GPIO sysctl binding
+ documentation
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add binding documentation for the GPIO sysctl found in BCM6328 SoCs.
+
+Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Link: https://lore.kernel.org/r/20210324081923.20379-7-noltari@gmail.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ .../mfd/brcm,bcm6328-gpio-sysctl.yaml | 162 ++++++++++++++++++
+ 1 file changed, 162 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/mfd/brcm,bcm6328-gpio-sysctl.yaml
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/mfd/brcm,bcm6328-gpio-sysctl.yaml
+@@ -0,0 +1,162 @@
++# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/mfd/brcm,bcm6328-gpio-sysctl.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: Broadcom BCM6328 GPIO System Controller Device Tree Bindings
++
++maintainers:
++ - Álvaro Fernández Rojas <noltari@gmail.com>
++ - Jonas Gorski <jonas.gorski@gmail.com>
++
++description:
++ Broadcom BCM6328 SoC GPIO system controller which provides a register map
++ for controlling the GPIO and pins of the SoC.
++
++properties:
++ "#address-cells": true
++
++ "#size-cells": true
++
++ compatible:
++ items:
++ - const: brcm,bcm6328-gpio-sysctl
++ - const: syscon
++ - const: simple-mfd
++
++ ranges:
++ maxItems: 1
++
++ reg:
++ maxItems: 1
++
++patternProperties:
++ "^gpio@[0-9a-f]+$":
++ # Child node
++ type: object
++ $ref: "../gpio/brcm,bcm6345-gpio.yaml"
++ description:
++ GPIO controller for the SoC GPIOs. This child node definition
++ should follow the bindings specified in
++ Documentation/devicetree/bindings/gpio/brcm,bcm6345-gpio.yaml.
++
++ "^pinctrl@[0-9a-f]+$":
++ # Child node
++ type: object
++ $ref: "../pinctrl/brcm,bcm6328-pinctrl.yaml"
++ description:
++ Pin controller for the SoC pins. This child node definition
++ should follow the bindings specified in
++ Documentation/devicetree/bindings/pinctrl/brcm,bcm6328-pinctrl.yaml.
++
++required:
++ - "#address-cells"
++ - compatible
++ - ranges
++ - reg
++ - "#size-cells"
++
++additionalProperties: false
++
++examples:
++ - |
++ syscon@10000080 {
++ #address-cells = <1>;
++ #size-cells = <1>;
++ compatible = "brcm,bcm6328-gpio-sysctl", "syscon", "simple-mfd";
++ reg = <0x10000080 0x80>;
++ ranges = <0 0x10000080 0x80>;
++
++ gpio@0 {
++ compatible = "brcm,bcm6328-gpio";
++ reg-names = "dirout", "dat";
++ reg = <0x0 0x8>, <0x8 0x8>;
++
++ gpio-controller;
++ gpio-ranges = <&pinctrl 0 0 32>;
++ #gpio-cells = <2>;
++ };
++
++ pinctrl: pinctrl@18 {
++ compatible = "brcm,bcm6328-pinctrl";
++ reg = <0x18 0x10>;
++
++ pinctrl_serial_led: serial_led-pins {
++ pinctrl_serial_led_data: serial_led_data-pins {
++ function = "serial_led_data";
++ pins = "gpio6";
++ };
++
++ pinctrl_serial_led_clk: serial_led_clk-pins {
++ function = "serial_led_clk";
++ pins = "gpio7";
++ };
++ };
++
++ pinctrl_inet_act_led: inet_act_led-pins {
++ function = "inet_act_led";
++ pins = "gpio11";
++ };
++
++ pinctrl_pcie_clkreq: pcie_clkreq-pins {
++ function = "pcie_clkreq";
++ pins = "gpio16";
++ };
++
++ pinctrl_ephy0_spd_led: ephy0_spd_led-pins {
++ function = "led";
++ pins = "gpio17";
++ };
++
++ pinctrl_ephy1_spd_led: ephy1_spd_led-pins {
++ function = "led";
++ pins = "gpio18";
++ };
++
++ pinctrl_ephy2_spd_led: ephy2_spd_led-pins {
++ function = "led";
++ pins = "gpio19";
++ };
++
++ pinctrl_ephy3_spd_led: ephy3_spd_led-pins {
++ function = "led";
++ pins = "gpio20";
++ };
++
++ pinctrl_ephy0_act_led: ephy0_act_led-pins {
++ function = "ephy0_act_led";
++ pins = "gpio25";
++ };
++
++ pinctrl_ephy1_act_led: ephy1_act_led-pins {
++ function = "ephy1_act_led";
++ pins = "gpio26";
++ };
++
++ pinctrl_ephy2_act_led: ephy2_act_led-pins {
++ function = "ephy2_act_led";
++ pins = "gpio27";
++ };
++
++ pinctrl_ephy3_act_led: ephy3_act_led-pins {
++ function = "ephy3_act_led";
++ pins = "gpio28";
++ };
++
++ pinctrl_hsspi_cs1: hsspi_cs1-pins {
++ function = "hsspi_cs1";
++ pins = "hsspi_cs1";
++ };
++
++ pinctrl_usb_port1_device: usb_port1_device-pins {
++ function = "usb_device_port";
++ pins = "usb_port1";
++ };
++
++ pinctrl_usb_port1_host: usb_port1_host-pins {
++ function = "usb_host_port";
++ pins = "usb_port1";
++ };
++ };
++ };
--- /dev/null
+From 9bf34ac5ab5805f0a798d40423c05596b7a0cee6 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
+Date: Wed, 24 Mar 2021 09:19:08 +0100
+Subject: [PATCH 07/22] 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. BCM6328 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.
+
+Co-developed-by: Jonas Gorski <jonas.gorski@gmail.com>
+Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
+Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
+Link: https://lore.kernel.org/r/20210324081923.20379-8-noltari@gmail.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ drivers/pinctrl/bcm/Kconfig | 8 +
+ drivers/pinctrl/bcm/Makefile | 1 +
+ drivers/pinctrl/bcm/pinctrl-bcm6328.c | 404 ++++++++++++++++++++++++++
+ 3 files changed, 413 insertions(+)
+ create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm6328.c
+
+--- a/drivers/pinctrl/bcm/Kconfig
++++ b/drivers/pinctrl/bcm/Kconfig
+@@ -36,6 +36,14 @@ config PINCTRL_BCM63XX
+ select PINCONF
+ select PINMUX
+
++config PINCTRL_BCM6328
++ bool "Broadcom BCM6328 GPIO driver"
++ depends on (BMIPS_GENERIC || COMPILE_TEST)
++ select PINCTRL_BCM63XX
++ 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
+@@ -4,6 +4,7 @@
+ obj-$(CONFIG_PINCTRL_BCM281XX) += pinctrl-bcm281xx.o
+ obj-$(CONFIG_PINCTRL_BCM2835) += pinctrl-bcm2835.o
+ obj-$(CONFIG_PINCTRL_BCM63XX) += pinctrl-bcm63xx.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,404 @@
++// 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/bits.h>
++#include <linux/gpio/driver.h>
++#include <linux/kernel.h>
++#include <linux/of.h>
++#include <linux/pinctrl/pinmux.h>
++#include <linux/platform_device.h>
++#include <linux/regmap.h>
++
++#include "../pinctrl-utils.h"
++
++#include "pinctrl-bcm63xx.h"
++
++#define BCM6328_NUM_GPIOS 32
++
++#define BCM6328_MODE_REG 0x18
++#define BCM6328_MUX_HI_REG 0x1c
++#define BCM6328_MUX_LO_REG 0x20
++#define BCM6328_MUX_OTHER_REG 0x24
++#define BCM6328_MUX_MASK GENMASK(1, 0)
++
++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;
++};
++
++static const unsigned int bcm6328_mux[] = {
++ BCM6328_MUX_LO_REG,
++ BCM6328_MUX_HI_REG,
++ BCM6328_MUX_OTHER_REG
++};
++
++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_mux_off(unsigned int pin)
++{
++ return bcm6328_mux[pin / 16];
++}
++
++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 bcm63xx_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, bcm6328_mux_off(pin),
++ BCM6328_MUX_MASK << ((pin % 16) * 2),
++ mux << ((pin % 16) * 2));
++}
++
++static int bcm6328_pinctrl_set_mux(struct pinctrl_dev *pctldev,
++ unsigned selector, unsigned group)
++{
++ struct bcm63xx_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 bcm63xx_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 = {
++ .dt_free_map = pinctrl_utils_free_map,
++ .dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
++ .get_group_name = bcm6328_pinctrl_get_group_name,
++ .get_group_pins = bcm6328_pinctrl_get_group_pins,
++ .get_groups_count = bcm6328_pinctrl_get_group_count,
++};
++
++static struct pinmux_ops bcm6328_pmx_ops = {
++ .get_function_groups = bcm6328_pinctrl_get_groups,
++ .get_function_name = bcm6328_pinctrl_get_func_name,
++ .get_functions_count = bcm6328_pinctrl_get_func_count,
++ .gpio_request_enable = bcm6328_gpio_request_enable,
++ .set_mux = bcm6328_pinctrl_set_mux,
++ .strict = true,
++};
++
++static const struct bcm63xx_pinctrl_soc bcm6328_soc = {
++ .ngpios = BCM6328_NUM_GPIOS,
++ .npins = ARRAY_SIZE(bcm6328_pins),
++ .pctl_ops = &bcm6328_pctl_ops,
++ .pins = bcm6328_pins,
++ .pmx_ops = &bcm6328_pmx_ops,
++};
++
++static int bcm6328_pinctrl_probe(struct platform_device *pdev)
++{
++ return bcm63xx_pinctrl_probe(pdev, &bcm6328_soc, NULL);
++}
++
++static const struct of_device_id bcm6328_pinctrl_match[] = {
++ { .compatible = "brcm,bcm6328-pinctrl", },
++ { /* sentinel */ }
++};
++
++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);
--- /dev/null
+From 6d591614bfe881bb7664c9bebb6a48231c059411 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
+Date: Wed, 24 Mar 2021 09:19:09 +0100
+Subject: [PATCH 08/22] dt-bindings: 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.
+
+Co-developed-by: Jonas Gorski <jonas.gorski@gmail.com>
+Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
+Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Link: https://lore.kernel.org/r/20210324081923.20379-9-noltari@gmail.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ .../pinctrl/brcm,bcm6358-pinctrl.yaml | 93 +++++++++++++++++++
+ 1 file changed, 93 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,93 @@
++# 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:
++ Bindings for Broadcom's BCM6358 memory-mapped pin controller.
++
++properties:
++ compatible:
++ const: brcm,bcm6358-pinctrl
++
++ reg:
++ maxItems: 1
++
++patternProperties:
++ '-pins$':
++ type: object
++ $ref: pinmux-node.yaml#
++
++ properties:
++ function:
++ enum: [ ebi_cs, uart1, serial_led, legacy_led, led, spi_cs, utopia,
++ pwm_syn_clk, sys_irq ]
++
++ pins:
++ 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
++ - reg
++
++additionalProperties: false
++
++examples:
++ - |
++ pinctrl@18 {
++ compatible = "brcm,bcm6358-pinctrl";
++ reg = <0x18 0x4>;
++
++ pinctrl_ebi_cs: ebi_cs-pins {
++ function = "ebi_cs";
++ groups = "ebi_cs_grp";
++ };
++
++ pinctrl_uart1: uart1-pins {
++ function = "uart1";
++ groups = "uart1_grp";
++ };
++
++ pinctrl_serial_led: serial_led-pins {
++ function = "serial_led";
++ groups = "serial_led_grp";
++ };
++
++ pinctrl_legacy_led: legacy_led-pins {
++ function = "legacy_led";
++ groups = "legacy_led_grp";
++ };
++
++ pinctrl_led: led-pins {
++ function = "led";
++ groups = "led_grp";
++ };
++
++ pinctrl_spi_cs_23: spi_cs-pins {
++ function = "spi_cs";
++ groups = "spi_cs_grp";
++ };
++
++ pinctrl_utopia: utopia-pins {
++ function = "utopia";
++ groups = "utopia_grp";
++ };
++
++ pinctrl_pwm_syn_clk: pwm_syn_clk-pins {
++ function = "pwm_syn_clk";
++ groups = "pwm_syn_clk_grp";
++ };
++
++ pinctrl_sys_irq: sys_irq-pins {
++ function = "sys_irq";
++ groups = "sys_irq_grp";
++ };
++ };
--- /dev/null
+From cfb1b98bc8d5ffd813428cb03c63b54cf63dd785 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
+Date: Wed, 24 Mar 2021 09:19:10 +0100
+Subject: [PATCH 09/22] dt-bindings: add BCM6358 GPIO sysctl binding
+ documentation
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add binding documentation for the GPIO sysctl found in BCM6358 SoCs.
+
+Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Link: https://lore.kernel.org/r/20210324081923.20379-10-noltari@gmail.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ .../mfd/brcm,bcm6358-gpio-sysctl.yaml | 130 ++++++++++++++++++
+ 1 file changed, 130 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/mfd/brcm,bcm6358-gpio-sysctl.yaml
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/mfd/brcm,bcm6358-gpio-sysctl.yaml
+@@ -0,0 +1,130 @@
++# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/mfd/brcm,bcm6358-gpio-sysctl.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: Broadcom BCM6358 GPIO System Controller Device Tree Bindings
++
++maintainers:
++ - Álvaro Fernández Rojas <noltari@gmail.com>
++ - Jonas Gorski <jonas.gorski@gmail.com>
++
++description:
++ Broadcom BCM6358 SoC GPIO system controller which provides a register map
++ for controlling the GPIO and pins of the SoC.
++
++properties:
++ "#address-cells": true
++
++ "#size-cells": true
++
++ compatible:
++ items:
++ - const: brcm,bcm6358-gpio-sysctl
++ - const: syscon
++ - const: simple-mfd
++
++ ranges:
++ maxItems: 1
++
++ reg:
++ maxItems: 1
++
++patternProperties:
++ "^gpio@[0-9a-f]+$":
++ # Child node
++ type: object
++ $ref: "../gpio/brcm,bcm6345-gpio.yaml"
++ description:
++ GPIO controller for the SoC GPIOs. This child node definition
++ should follow the bindings specified in
++ Documentation/devicetree/bindings/gpio/brcm,bcm6345-gpio.yaml.
++
++ "^pinctrl@[0-9a-f]+$":
++ # Child node
++ type: object
++ $ref: "../pinctrl/brcm,bcm6358-pinctrl.yaml"
++ description:
++ Pin controller for the SoC pins. This child node definition
++ should follow the bindings specified in
++ Documentation/devicetree/bindings/pinctrl/brcm,bcm6358-pinctrl.yaml.
++
++required:
++ - "#address-cells"
++ - compatible
++ - ranges
++ - reg
++ - "#size-cells"
++
++additionalProperties: false
++
++examples:
++ - |
++ syscon@fffe0080 {
++ #address-cells = <1>;
++ #size-cells = <1>;
++ compatible = "brcm,bcm6358-gpio-sysctl", "syscon", "simple-mfd";
++ reg = <0xfffe0080 0x80>;
++ ranges = <0 0xfffe0080 0x80>;
++
++ gpio@0 {
++ compatible = "brcm,bcm6358-gpio";
++ reg-names = "dirout", "dat";
++ reg = <0x0 0x8>, <0x8 0x8>;
++
++ gpio-controller;
++ gpio-ranges = <&pinctrl 0 0 40>;
++ #gpio-cells = <2>;
++ };
++
++ pinctrl: pinctrl@18 {
++ compatible = "brcm,bcm6358-pinctrl";
++ reg = <0x18 0x4>;
++
++ pinctrl_ebi_cs: ebi_cs-pins {
++ function = "ebi_cs";
++ groups = "ebi_cs_grp";
++ };
++
++ pinctrl_uart1: uart1-pins {
++ function = "uart1";
++ groups = "uart1_grp";
++ };
++
++ pinctrl_serial_led: serial_led-pins {
++ function = "serial_led";
++ groups = "serial_led_grp";
++ };
++
++ pinctrl_legacy_led: legacy_led-pins {
++ function = "legacy_led";
++ groups = "legacy_led_grp";
++ };
++
++ pinctrl_led: led-pins {
++ function = "led";
++ groups = "led_grp";
++ };
++
++ pinctrl_spi_cs_23: spi_cs-pins {
++ function = "spi_cs";
++ groups = "spi_cs_grp";
++ };
++
++ pinctrl_utopia: utopia-pins {
++ function = "utopia";
++ groups = "utopia_grp";
++ };
++
++ pinctrl_pwm_syn_clk: pwm_syn_clk-pins {
++ function = "pwm_syn_clk";
++ groups = "pwm_syn_clk_grp";
++ };
++
++ pinctrl_sys_irq: sys_irq-pins {
++ function = "sys_irq";
++ groups = "sys_irq_grp";
++ };
++ };
++ };
--- /dev/null
+From 9494b16976e1ae3afc643abf638a25f2ce4c3f2b Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
+Date: Wed, 24 Mar 2021 09:19:11 +0100
+Subject: [PATCH 10/22] 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.
+
+Co-developed-by: Jonas Gorski <jonas.gorski@gmail.com>
+Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
+Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
+Link: https://lore.kernel.org/r/20210324081923.20379-11-noltari@gmail.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ drivers/pinctrl/bcm/Kconfig | 8 +
+ drivers/pinctrl/bcm/Makefile | 1 +
+ drivers/pinctrl/bcm/pinctrl-bcm6358.c | 369 ++++++++++++++++++++++++++
+ 3 files changed, 378 insertions(+)
+ create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm6358.c
+
+--- a/drivers/pinctrl/bcm/Kconfig
++++ b/drivers/pinctrl/bcm/Kconfig
+@@ -44,6 +44,14 @@ config PINCTRL_BCM6328
+ help
+ Say Y here to enable the Broadcom BCM6328 GPIO driver.
+
++config PINCTRL_BCM6358
++ bool "Broadcom BCM6358 GPIO driver"
++ depends on (BMIPS_GENERIC || COMPILE_TEST)
++ select PINCTRL_BCM63XX
++ 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
+@@ -5,6 +5,7 @@ obj-$(CONFIG_PINCTRL_BCM281XX) += pinct
+ obj-$(CONFIG_PINCTRL_BCM2835) += pinctrl-bcm2835.o
+ obj-$(CONFIG_PINCTRL_BCM63XX) += pinctrl-bcm63xx.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,369 @@
++// 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/bits.h>
++#include <linux/gpio/driver.h>
++#include <linux/kernel.h>
++#include <linux/of.h>
++#include <linux/pinctrl/pinmux.h>
++#include <linux/platform_device.h>
++#include <linux/regmap.h>
++
++#include "../pinctrl-utils.h"
++
++#include "pinctrl-bcm63xx.h"
++
++#define BCM6358_NUM_GPIOS 40
++
++#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_priv {
++ struct regmap_field *overlays;
++};
++
++#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 bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
++ struct bcm6358_priv *priv = pc->driver_data;
++ 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(priv->overlays, mask, val);
++
++ for (pin = 0; pin < pg->num_pins; pin++) {
++ struct pinctrl_gpio_range *range;
++ unsigned int hw_gpio = bcm6358_pins[pin].number;
++
++ range = pinctrl_find_gpio_range_from_pin(pctldev, hw_gpio);
++ if (range) {
++ struct gpio_chip *gc = range->gc;
++
++ 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 bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
++ struct bcm6358_priv *priv = pc->driver_data;
++ 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(priv->overlays, mask, 0);
++}
++
++static struct pinctrl_ops bcm6358_pctl_ops = {
++ .dt_free_map = pinctrl_utils_free_map,
++ .dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
++ .get_group_name = bcm6358_pinctrl_get_group_name,
++ .get_group_pins = bcm6358_pinctrl_get_group_pins,
++ .get_groups_count = bcm6358_pinctrl_get_group_count,
++};
++
++static struct pinmux_ops bcm6358_pmx_ops = {
++ .get_function_groups = bcm6358_pinctrl_get_groups,
++ .get_function_name = bcm6358_pinctrl_get_func_name,
++ .get_functions_count = bcm6358_pinctrl_get_func_count,
++ .gpio_request_enable = bcm6358_gpio_request_enable,
++ .set_mux = bcm6358_pinctrl_set_mux,
++ .strict = true,
++};
++
++static const struct bcm63xx_pinctrl_soc bcm6358_soc = {
++ .ngpios = BCM6358_NUM_GPIOS,
++ .npins = ARRAY_SIZE(bcm6358_pins),
++ .pctl_ops = &bcm6358_pctl_ops,
++ .pins = bcm6358_pins,
++ .pmx_ops = &bcm6358_pmx_ops,
++};
++
++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 bcm63xx_pinctrl *pc;
++ struct bcm6358_priv *priv;
++ int err;
++
++ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
++ if (!priv)
++ return -ENOMEM;
++
++ err = bcm63xx_pinctrl_probe(pdev, &bcm6358_soc, (void *) priv);
++ if (err)
++ return err;
++
++ pc = platform_get_drvdata(pdev);
++
++ priv->overlays = devm_regmap_field_alloc(dev, pc->regs, overlays);
++ if (IS_ERR(priv->overlays))
++ return PTR_ERR(priv->overlays);
++
++ return 0;
++}
++
++static const struct of_device_id bcm6358_pinctrl_match[] = {
++ { .compatible = "brcm,bcm6358-pinctrl", },
++ { /* sentinel */ }
++};
++
++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);
--- /dev/null
+From 6e4b5e1fc77513359989112e002e08553d0d8d5c Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
+Date: Wed, 24 Mar 2021 09:19:12 +0100
+Subject: [PATCH 11/22] dt-bindings: 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.
+
+Co-developed-by: Jonas Gorski <jonas.gorski@gmail.com>
+Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
+Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Link: https://lore.kernel.org/r/20210324081923.20379-12-noltari@gmail.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ .../pinctrl/brcm,bcm6362-pinctrl.yaml | 206 ++++++++++++++++++
+ 1 file changed, 206 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,206 @@
++# 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:
++ Bindings for Broadcom's BCM6362 memory-mapped pin controller.
++
++properties:
++ compatible:
++ const: brcm,bcm6362-pinctrl
++
++ reg:
++ maxItems: 2
++
++patternProperties:
++ '-pins$':
++ type: object
++ $ref: pinmux-node.yaml#
++
++ properties:
++ function:
++ 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:
++ 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
++ - reg
++
++additionalProperties: false
++
++examples:
++ - |
++ pinctrl@18 {
++ compatible = "brcm,bcm6362-pinctrl";
++ reg = <0x18 0x10>, <0x38 0x4>;
++
++ pinctrl_usb_device_led: usb_device_led-pins {
++ function = "usb_device_led";
++ pins = "gpio0";
++ };
++
++ pinctrl_sys_irq: sys_irq-pins {
++ function = "sys_irq";
++ pins = "gpio1";
++ };
++
++ pinctrl_serial_led: serial_led-pins {
++ pinctrl_serial_led_clk: serial_led_clk-pins {
++ function = "serial_led_clk";
++ pins = "gpio2";
++ };
++
++ pinctrl_serial_led_data: serial_led_data-pins {
++ function = "serial_led_data";
++ pins = "gpio3";
++ };
++ };
++
++ pinctrl_robosw_led_data: robosw_led_data-pins {
++ function = "robosw_led_data";
++ pins = "gpio4";
++ };
++
++ pinctrl_robosw_led_clk: robosw_led_clk-pins {
++ function = "robosw_led_clk";
++ pins = "gpio5";
++ };
++
++ pinctrl_robosw_led0: robosw_led0-pins {
++ function = "robosw_led0";
++ pins = "gpio6";
++ };
++
++ pinctrl_robosw_led1: robosw_led1-pins {
++ function = "robosw_led1";
++ pins = "gpio7";
++ };
++
++ pinctrl_inet_led: inet_led-pins {
++ function = "inet_led";
++ pins = "gpio8";
++ };
++
++ pinctrl_spi_cs2: spi_cs2-pins {
++ function = "spi_cs2";
++ pins = "gpio9";
++ };
++
++ pinctrl_spi_cs3: spi_cs3-pins {
++ function = "spi_cs3";
++ pins = "gpio10";
++ };
++
++ pinctrl_ntr_pulse: ntr_pulse-pins {
++ function = "ntr_pulse";
++ pins = "gpio11";
++ };
++
++ pinctrl_uart1_scts: uart1_scts-pins {
++ function = "uart1_scts";
++ pins = "gpio12";
++ };
++
++ pinctrl_uart1_srts: uart1_srts-pins {
++ function = "uart1_srts";
++ pins = "gpio13";
++ };
++
++ pinctrl_uart1: uart1-pins {
++ pinctrl_uart1_sdin: uart1_sdin-pins {
++ function = "uart1_sdin";
++ pins = "gpio14";
++ };
++
++ pinctrl_uart1_sdout: uart1_sdout-pins {
++ function = "uart1_sdout";
++ pins = "gpio15";
++ };
++ };
++
++ pinctrl_adsl_spi: adsl_spi-pins {
++ pinctrl_adsl_spi_miso: adsl_spi_miso-pins {
++ function = "adsl_spi_miso";
++ pins = "gpio16";
++ };
++
++ pinctrl_adsl_spi_mosi: adsl_spi_mosi-pins {
++ function = "adsl_spi_mosi";
++ pins = "gpio17";
++ };
++
++ pinctrl_adsl_spi_clk: adsl_spi_clk-pins {
++ function = "adsl_spi_clk";
++ pins = "gpio18";
++ };
++
++ pinctrl_adsl_spi_cs: adsl_spi_cs-pins {
++ function = "adsl_spi_cs";
++ pins = "gpio19";
++ };
++ };
++
++ pinctrl_ephy0_led: ephy0_led-pins {
++ function = "ephy0_led";
++ pins = "gpio20";
++ };
++
++ pinctrl_ephy1_led: ephy1_led-pins {
++ function = "ephy1_led";
++ pins = "gpio21";
++ };
++
++ pinctrl_ephy2_led: ephy2_led-pins {
++ function = "ephy2_led";
++ pins = "gpio22";
++ };
++
++ pinctrl_ephy3_led: ephy3_led-pins {
++ function = "ephy3_led";
++ pins = "gpio23";
++ };
++
++ pinctrl_ext_irq0: ext_irq0-pins {
++ function = "ext_irq0";
++ pins = "gpio24";
++ };
++
++ pinctrl_ext_irq1: ext_irq1-pins {
++ function = "ext_irq1";
++ pins = "gpio25";
++ };
++
++ pinctrl_ext_irq2: ext_irq2-pins {
++ function = "ext_irq2";
++ pins = "gpio26";
++ };
++
++ pinctrl_ext_irq3: ext_irq3-pins {
++ function = "ext_irq3";
++ pins = "gpio27";
++ };
++
++ pinctrl_nand: nand-pins {
++ function = "nand";
++ group = "nand_grp";
++ };
++ };
--- /dev/null
+From 7ca989eafbd6ce1c216a775556c4893baab1959b Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
+Date: Wed, 24 Mar 2021 09:19:13 +0100
+Subject: [PATCH 12/22] dt-bindings: add BCM6362 GPIO sysctl binding
+ documentation
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add binding documentation for the GPIO sysctl found in BCM6362 SoCs.
+
+Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Link: https://lore.kernel.org/r/20210324081923.20379-13-noltari@gmail.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ .../mfd/brcm,bcm6362-gpio-sysctl.yaml | 236 ++++++++++++++++++
+ 1 file changed, 236 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/mfd/brcm,bcm6362-gpio-sysctl.yaml
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/mfd/brcm,bcm6362-gpio-sysctl.yaml
+@@ -0,0 +1,236 @@
++# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/mfd/brcm,bcm6362-gpio-sysctl.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: Broadcom BCM6362 GPIO System Controller Device Tree Bindings
++
++maintainers:
++ - Álvaro Fernández Rojas <noltari@gmail.com>
++ - Jonas Gorski <jonas.gorski@gmail.com>
++
++description:
++ Broadcom BCM6362 SoC GPIO system controller which provides a register map
++ for controlling the GPIO and pins of the SoC.
++
++properties:
++ "#address-cells": true
++
++ "#size-cells": true
++
++ compatible:
++ items:
++ - const: brcm,bcm6362-gpio-sysctl
++ - const: syscon
++ - const: simple-mfd
++
++ ranges:
++ maxItems: 1
++
++ reg:
++ maxItems: 1
++
++patternProperties:
++ "^gpio@[0-9a-f]+$":
++ # Child node
++ type: object
++ $ref: "../gpio/brcm,bcm6345-gpio.yaml"
++ description:
++ GPIO controller for the SoC GPIOs. This child node definition
++ should follow the bindings specified in
++ Documentation/devicetree/bindings/gpio/brcm,bcm6345-gpio.yaml.
++
++ "^pinctrl@[0-9a-f]+$":
++ # Child node
++ type: object
++ $ref: "../pinctrl/brcm,bcm6362-pinctrl.yaml"
++ description:
++ Pin controller for the SoC pins. This child node definition
++ should follow the bindings specified in
++ Documentation/devicetree/bindings/pinctrl/brcm,bcm6362-pinctrl.yaml.
++
++required:
++ - "#address-cells"
++ - compatible
++ - ranges
++ - reg
++ - "#size-cells"
++
++additionalProperties: false
++
++examples:
++ - |
++ syscon@10000080 {
++ #address-cells = <1>;
++ #size-cells = <1>;
++ compatible = "brcm,bcm6362-gpio-sysctl", "syscon", "simple-mfd";
++ reg = <0x10000080 0x80>;
++ ranges = <0 0x10000080 0x80>;
++
++ gpio@0 {
++ compatible = "brcm,bcm6362-gpio";
++ reg-names = "dirout", "dat";
++ reg = <0x0 0x8>, <0x8 0x8>;
++
++ gpio-controller;
++ gpio-ranges = <&pinctrl 0 0 48>;
++ #gpio-cells = <2>;
++ };
++
++ pinctrl: pinctrl@18 {
++ compatible = "brcm,bcm6362-pinctrl";
++ reg = <0x18 0x10>, <0x38 0x4>;
++
++ pinctrl_usb_device_led: usb_device_led-pins {
++ function = "usb_device_led";
++ pins = "gpio0";
++ };
++
++ pinctrl_sys_irq: sys_irq-pins {
++ function = "sys_irq";
++ pins = "gpio1";
++ };
++
++ pinctrl_serial_led: serial_led-pins {
++ pinctrl_serial_led_clk: serial_led_clk-pins {
++ function = "serial_led_clk";
++ pins = "gpio2";
++ };
++
++ pinctrl_serial_led_data: serial_led_data-pins {
++ function = "serial_led_data";
++ pins = "gpio3";
++ };
++ };
++
++ pinctrl_robosw_led_data: robosw_led_data-pins {
++ function = "robosw_led_data";
++ pins = "gpio4";
++ };
++
++ pinctrl_robosw_led_clk: robosw_led_clk-pins {
++ function = "robosw_led_clk";
++ pins = "gpio5";
++ };
++
++ pinctrl_robosw_led0: robosw_led0-pins {
++ function = "robosw_led0";
++ pins = "gpio6";
++ };
++
++ pinctrl_robosw_led1: robosw_led1-pins {
++ function = "robosw_led1";
++ pins = "gpio7";
++ };
++
++ pinctrl_inet_led: inet_led-pins {
++ function = "inet_led";
++ pins = "gpio8";
++ };
++
++ pinctrl_spi_cs2: spi_cs2-pins {
++ function = "spi_cs2";
++ pins = "gpio9";
++ };
++
++ pinctrl_spi_cs3: spi_cs3-pins {
++ function = "spi_cs3";
++ pins = "gpio10";
++ };
++
++ pinctrl_ntr_pulse: ntr_pulse-pins {
++ function = "ntr_pulse";
++ pins = "gpio11";
++ };
++
++ pinctrl_uart1_scts: uart1_scts-pins {
++ function = "uart1_scts";
++ pins = "gpio12";
++ };
++
++ pinctrl_uart1_srts: uart1_srts-pins {
++ function = "uart1_srts";
++ pins = "gpio13";
++ };
++
++ pinctrl_uart1: uart1-pins {
++ pinctrl_uart1_sdin: uart1_sdin-pins {
++ function = "uart1_sdin";
++ pins = "gpio14";
++ };
++
++ pinctrl_uart1_sdout: uart1_sdout-pins {
++ function = "uart1_sdout";
++ pins = "gpio15";
++ };
++ };
++
++ pinctrl_adsl_spi: adsl_spi-pins {
++ pinctrl_adsl_spi_miso: adsl_spi_miso-pins {
++ function = "adsl_spi_miso";
++ pins = "gpio16";
++ };
++
++ pinctrl_adsl_spi_mosi: adsl_spi_mosi-pins {
++ function = "adsl_spi_mosi";
++ pins = "gpio17";
++ };
++
++ pinctrl_adsl_spi_clk: adsl_spi_clk-pins {
++ function = "adsl_spi_clk";
++ pins = "gpio18";
++ };
++
++ pinctrl_adsl_spi_cs: adsl_spi_cs-pins {
++ function = "adsl_spi_cs";
++ pins = "gpio19";
++ };
++ };
++
++ pinctrl_ephy0_led: ephy0_led-pins {
++ function = "ephy0_led";
++ pins = "gpio20";
++ };
++
++ pinctrl_ephy1_led: ephy1_led-pins {
++ function = "ephy1_led";
++ pins = "gpio21";
++ };
++
++ pinctrl_ephy2_led: ephy2_led-pins {
++ function = "ephy2_led";
++ pins = "gpio22";
++ };
++
++ pinctrl_ephy3_led: ephy3_led-pins {
++ function = "ephy3_led";
++ pins = "gpio23";
++ };
++
++ pinctrl_ext_irq0: ext_irq0-pins {
++ function = "ext_irq0";
++ pins = "gpio24";
++ };
++
++ pinctrl_ext_irq1: ext_irq1-pins {
++ function = "ext_irq1";
++ pins = "gpio25";
++ };
++
++ pinctrl_ext_irq2: ext_irq2-pins {
++ function = "ext_irq2";
++ pins = "gpio26";
++ };
++
++ pinctrl_ext_irq3: ext_irq3-pins {
++ function = "ext_irq3";
++ pins = "gpio27";
++ };
++
++ pinctrl_nand: nand-pins {
++ function = "nand";
++ group = "nand_grp";
++ };
++ };
++ };
--- /dev/null
+From 705791e23ecd93d6c2697234fdf0c22b499c0a5b Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
+Date: Wed, 24 Mar 2021 09:19:14 +0100
+Subject: [PATCH 13/22] 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.
+
+Co-developed-by: Jonas Gorski <jonas.gorski@gmail.com>
+Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
+Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
+Link: https://lore.kernel.org/r/20210324081923.20379-14-noltari@gmail.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ drivers/pinctrl/bcm/Kconfig | 8 +
+ drivers/pinctrl/bcm/Makefile | 1 +
+ drivers/pinctrl/bcm/pinctrl-bcm6362.c | 617 ++++++++++++++++++++++++++
+ 3 files changed, 626 insertions(+)
+ create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm6362.c
+
+--- a/drivers/pinctrl/bcm/Kconfig
++++ b/drivers/pinctrl/bcm/Kconfig
+@@ -52,6 +52,14 @@ config PINCTRL_BCM6358
+ help
+ Say Y here to enable the Broadcom BCM6358 GPIO driver.
+
++config PINCTRL_BCM6362
++ bool "Broadcom BCM6362 GPIO driver"
++ depends on (BMIPS_GENERIC || COMPILE_TEST)
++ select PINCTRL_BCM63XX
++ 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
+@@ -6,6 +6,7 @@ obj-$(CONFIG_PINCTRL_BCM2835) += pinctr
+ 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
+ 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,617 @@
++// 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/bits.h>
++#include <linux/gpio/driver.h>
++#include <linux/kernel.h>
++#include <linux/of.h>
++#include <linux/pinctrl/pinmux.h>
++#include <linux/platform_device.h>
++#include <linux/regmap.h>
++
++#include "../pinctrl-utils.h"
++
++#include "pinctrl-bcm63xx.h"
++
++#define BCM6362_BANK_GPIOS 32
++#define BCM6362_NUM_GPIOS 48
++#define BCM6362_NUM_LEDS 24
++
++#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;
++};
++
++#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_set_gpio(struct bcm63xx_pinctrl *pc, unsigned pin)
++{
++ const struct pinctrl_pin_desc *desc = &bcm6362_pins[pin];
++ unsigned int mask = bcm63xx_bank_pin(pin);
++
++ if (desc->drv_data)
++ regmap_update_bits(pc->regs, BCM6362_BASEMODE_REG,
++ (uint32_t) desc->drv_data, 0);
++
++ if (pin < BCM63XX_BANK_GPIOS) {
++ /* 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 bcm63xx_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 bcm63xx_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 = {
++ .dt_free_map = pinctrl_utils_free_map,
++ .dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
++ .get_group_name = bcm6362_pinctrl_get_group_name,
++ .get_group_pins = bcm6362_pinctrl_get_group_pins,
++ .get_groups_count = bcm6362_pinctrl_get_group_count,
++};
++
++static struct pinmux_ops bcm6362_pmx_ops = {
++ .get_function_groups = bcm6362_pinctrl_get_groups,
++ .get_function_name = bcm6362_pinctrl_get_func_name,
++ .get_functions_count = bcm6362_pinctrl_get_func_count,
++ .gpio_request_enable = bcm6362_gpio_request_enable,
++ .set_mux = bcm6362_pinctrl_set_mux,
++ .strict = true,
++};
++
++static const struct bcm63xx_pinctrl_soc bcm6362_soc = {
++ .ngpios = BCM6362_NUM_GPIOS,
++ .npins = ARRAY_SIZE(bcm6362_pins),
++ .pctl_ops = &bcm6362_pctl_ops,
++ .pins = bcm6362_pins,
++ .pmx_ops = &bcm6362_pmx_ops,
++};
++
++static int bcm6362_pinctrl_probe(struct platform_device *pdev)
++{
++ return bcm63xx_pinctrl_probe(pdev, &bcm6362_soc, NULL);
++}
++
++static const struct of_device_id bcm6362_pinctrl_match[] = {
++ { .compatible = "brcm,bcm6362-pinctrl", },
++ { /* sentinel */ }
++};
++
++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);
--- /dev/null
+From 9fbf8303796c89ecab026eb3dbadae7f98c49922 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
+Date: Wed, 24 Mar 2021 09:19:15 +0100
+Subject: [PATCH 14/22] dt-bindings: 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.
+
+Co-developed-by: Jonas Gorski <jonas.gorski@gmail.com>
+Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
+Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Link: https://lore.kernel.org/r/20210324081923.20379-15-noltari@gmail.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ .../pinctrl/brcm,bcm6368-pinctrl.yaml | 217 ++++++++++++++++++
+ 1 file changed, 217 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,217 @@
++# 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:
++ Bindings for Broadcom's BCM6368 memory-mapped pin controller.
++
++properties:
++ compatible:
++ const: brcm,bcm6368-pinctrl
++
++ reg:
++ maxItems: 2
++
++patternProperties:
++ '-pins$':
++ type: object
++ $ref: pinmux-node.yaml#
++
++ properties:
++ function:
++ 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:
++ 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
++ - reg
++
++additionalProperties: false
++
++examples:
++ - |
++ pinctrl@18 {
++ compatible = "brcm,bcm6368-pinctrl";
++ reg = <0x18 0x4>, <0x38 0x4>;
++
++ pinctrl_analog_afe_0: analog_afe_0-pins {
++ function = "analog_afe_0";
++ pins = "gpio0";
++ };
++
++ pinctrl_analog_afe_1: analog_afe_1-pins {
++ function = "analog_afe_1";
++ pins = "gpio1";
++ };
++
++ pinctrl_sys_irq: sys_irq-pins {
++ function = "sys_irq";
++ pins = "gpio2";
++ };
++
++ pinctrl_serial_led: serial_led-pins {
++ pinctrl_serial_led_data: serial_led_data-pins {
++ function = "serial_led_data";
++ pins = "gpio3";
++ };
++
++ pinctrl_serial_led_clk: serial_led_clk-pins {
++ function = "serial_led_clk";
++ pins = "gpio4";
++ };
++ };
++
++ pinctrl_inet_led: inet_led-pins {
++ function = "inet_led";
++ pins = "gpio5";
++ };
++
++ pinctrl_ephy0_led: ephy0_led-pins {
++ function = "ephy0_led";
++ pins = "gpio6";
++ };
++
++ pinctrl_ephy1_led: ephy1_led-pins {
++ function = "ephy1_led";
++ pins = "gpio7";
++ };
++
++ pinctrl_ephy2_led: ephy2_led-pins {
++ function = "ephy2_led";
++ pins = "gpio8";
++ };
++
++ pinctrl_ephy3_led: ephy3_led-pins {
++ function = "ephy3_led";
++ pins = "gpio9";
++ };
++
++ pinctrl_robosw_led_data: robosw_led_data-pins {
++ function = "robosw_led_data";
++ pins = "gpio10";
++ };
++
++ pinctrl_robosw_led_clk: robosw_led_clk-pins {
++ function = "robosw_led_clk";
++ pins = "gpio11";
++ };
++
++ pinctrl_robosw_led0: robosw_led0-pins {
++ function = "robosw_led0";
++ pins = "gpio12";
++ };
++
++ pinctrl_robosw_led1: robosw_led1-pins {
++ function = "robosw_led1";
++ pins = "gpio13";
++ };
++
++ pinctrl_usb_device_led: usb_device_led-pins {
++ function = "usb_device_led";
++ pins = "gpio14";
++ };
++
++ pinctrl_pci: pci-pins {
++ pinctrl_pci_req1: pci_req1-pins {
++ function = "pci_req1";
++ pins = "gpio16";
++ };
++
++ pinctrl_pci_gnt1: pci_gnt1-pins {
++ function = "pci_gnt1";
++ pins = "gpio17";
++ };
++
++ pinctrl_pci_intb: pci_intb-pins {
++ function = "pci_intb";
++ pins = "gpio18";
++ };
++
++ pinctrl_pci_req0: pci_req0-pins {
++ function = "pci_req0";
++ pins = "gpio19";
++ };
++
++ pinctrl_pci_gnt0: pci_gnt0-pins {
++ function = "pci_gnt0";
++ pins = "gpio20";
++ };
++ };
++
++ pinctrl_pcmcia: pcmcia-pins {
++ pinctrl_pcmcia_cd1: pcmcia_cd1-pins {
++ function = "pcmcia_cd1";
++ pins = "gpio22";
++ };
++
++ pinctrl_pcmcia_cd2: pcmcia_cd2-pins {
++ function = "pcmcia_cd2";
++ pins = "gpio23";
++ };
++
++ pinctrl_pcmcia_vs1: pcmcia_vs1-pins {
++ function = "pcmcia_vs1";
++ pins = "gpio24";
++ };
++
++ pinctrl_pcmcia_vs2: pcmcia_vs2-pins {
++ function = "pcmcia_vs2";
++ pins = "gpio25";
++ };
++ };
++
++ pinctrl_ebi_cs2: ebi_cs2-pins {
++ function = "ebi_cs2";
++ pins = "gpio26";
++ };
++
++ pinctrl_ebi_cs3: ebi_cs3-pins {
++ function = "ebi_cs3";
++ pins = "gpio27";
++ };
++
++ pinctrl_spi_cs2: spi_cs2-pins {
++ function = "spi_cs2";
++ pins = "gpio28";
++ };
++
++ pinctrl_spi_cs3: spi_cs3-pins {
++ function = "spi_cs3";
++ pins = "gpio29";
++ };
++
++ pinctrl_spi_cs4: spi_cs4-pins {
++ function = "spi_cs4";
++ pins = "gpio30";
++ };
++
++ pinctrl_spi_cs5: spi_cs5-pins {
++ function = "spi_cs5";
++ pins = "gpio31";
++ };
++
++ pinctrl_uart1: uart1-pins {
++ function = "uart1";
++ group = "uart1_grp";
++ };
++ };
--- /dev/null
+From fd22635f222f44dcb4dd6382d97de13144edad2b Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
+Date: Wed, 24 Mar 2021 09:19:16 +0100
+Subject: [PATCH 15/22] dt-bindings: add BCM6368 GPIO sysctl binding
+ documentation
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add binding documentation for the GPIO sysctl found in BCM6368 SoCs.
+
+Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Link: https://lore.kernel.org/r/20210324081923.20379-16-noltari@gmail.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ .../mfd/brcm,bcm6368-gpio-sysctl.yaml | 246 ++++++++++++++++++
+ 1 file changed, 246 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/mfd/brcm,bcm6368-gpio-sysctl.yaml
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/mfd/brcm,bcm6368-gpio-sysctl.yaml
+@@ -0,0 +1,246 @@
++# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/mfd/brcm,bcm6368-gpio-sysctl.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: Broadcom BCM6368 GPIO System Controller Device Tree Bindings
++
++maintainers:
++ - Álvaro Fernández Rojas <noltari@gmail.com>
++ - Jonas Gorski <jonas.gorski@gmail.com>
++
++description:
++ Broadcom BCM6368 SoC GPIO system controller which provides a register map
++ for controlling the GPIO and pins of the SoC.
++
++properties:
++ "#address-cells": true
++
++ "#size-cells": true
++
++ compatible:
++ items:
++ - const: brcm,bcm6368-gpio-sysctl
++ - const: syscon
++ - const: simple-mfd
++
++ ranges:
++ maxItems: 1
++
++ reg:
++ maxItems: 1
++
++patternProperties:
++ "^gpio@[0-9a-f]+$":
++ # Child node
++ type: object
++ $ref: "../gpio/brcm,bcm6345-gpio.yaml"
++ description:
++ GPIO controller for the SoC GPIOs. This child node definition
++ should follow the bindings specified in
++ Documentation/devicetree/bindings/gpio/brcm,bcm6345-gpio.yaml.
++
++ "^pinctrl@[0-9a-f]+$":
++ # Child node
++ type: object
++ $ref: "../pinctrl/brcm,bcm6368-pinctrl.yaml"
++ description:
++ Pin controller for the SoC pins. This child node definition
++ should follow the bindings specified in
++ Documentation/devicetree/bindings/pinctrl/brcm,bcm6368-pinctrl.yaml.
++
++required:
++ - "#address-cells"
++ - compatible
++ - ranges
++ - reg
++ - "#size-cells"
++
++additionalProperties: false
++
++examples:
++ - |
++ syscon@10000080 {
++ #address-cells = <1>;
++ #size-cells = <1>;
++ compatible = "brcm,bcm6368-gpio-sysctl", "syscon", "simple-mfd";
++ reg = <0x10000080 0x80>;
++ ranges = <0 0x10000080 0x80>;
++
++ gpio@0 {
++ compatible = "brcm,bcm6368-gpio";
++ reg-names = "dirout", "dat";
++ reg = <0x0 0x8>, <0x8 0x8>;
++
++ gpio-controller;
++ gpio-ranges = <&pinctrl 0 0 38>;
++ #gpio-cells = <2>;
++ };
++
++ pinctrl: pinctrl@18 {
++ compatible = "brcm,bcm6368-pinctrl";
++ reg = <0x18 0x4>, <0x38 0x4>;
++
++ pinctrl_analog_afe_0: analog_afe_0-pins {
++ function = "analog_afe_0";
++ pins = "gpio0";
++ };
++
++ pinctrl_analog_afe_1: analog_afe_1-pins {
++ function = "analog_afe_1";
++ pins = "gpio1";
++ };
++
++ pinctrl_sys_irq: sys_irq-pins {
++ function = "sys_irq";
++ pins = "gpio2";
++ };
++
++ pinctrl_serial_led: serial_led-pins {
++ pinctrl_serial_led_data: serial_led_data-pins {
++ function = "serial_led_data";
++ pins = "gpio3";
++ };
++
++ pinctrl_serial_led_clk: serial_led_clk-pins {
++ function = "serial_led_clk";
++ pins = "gpio4";
++ };
++ };
++
++ pinctrl_inet_led: inet_led-pins {
++ function = "inet_led";
++ pins = "gpio5";
++ };
++
++ pinctrl_ephy0_led: ephy0_led-pins {
++ function = "ephy0_led";
++ pins = "gpio6";
++ };
++
++ pinctrl_ephy1_led: ephy1_led-pins {
++ function = "ephy1_led";
++ pins = "gpio7";
++ };
++
++ pinctrl_ephy2_led: ephy2_led-pins {
++ function = "ephy2_led";
++ pins = "gpio8";
++ };
++
++ pinctrl_ephy3_led: ephy3_led-pins {
++ function = "ephy3_led";
++ pins = "gpio9";
++ };
++
++ pinctrl_robosw_led_data: robosw_led_data-pins {
++ function = "robosw_led_data";
++ pins = "gpio10";
++ };
++
++ pinctrl_robosw_led_clk: robosw_led_clk-pins {
++ function = "robosw_led_clk";
++ pins = "gpio11";
++ };
++
++ pinctrl_robosw_led0: robosw_led0-pins {
++ function = "robosw_led0";
++ pins = "gpio12";
++ };
++
++ pinctrl_robosw_led1: robosw_led1-pins {
++ function = "robosw_led1";
++ pins = "gpio13";
++ };
++
++ pinctrl_usb_device_led: usb_device_led-pins {
++ function = "usb_device_led";
++ pins = "gpio14";
++ };
++
++ pinctrl_pci: pci-pins {
++ pinctrl_pci_req1: pci_req1-pins {
++ function = "pci_req1";
++ pins = "gpio16";
++ };
++
++ pinctrl_pci_gnt1: pci_gnt1-pins {
++ function = "pci_gnt1";
++ pins = "gpio17";
++ };
++
++ pinctrl_pci_intb: pci_intb-pins {
++ function = "pci_intb";
++ pins = "gpio18";
++ };
++
++ pinctrl_pci_req0: pci_req0-pins {
++ function = "pci_req0";
++ pins = "gpio19";
++ };
++
++ pinctrl_pci_gnt0: pci_gnt0-pins {
++ function = "pci_gnt0";
++ pins = "gpio20";
++ };
++ };
++
++ pinctrl_pcmcia: pcmcia-pins {
++ pinctrl_pcmcia_cd1: pcmcia_cd1-pins {
++ function = "pcmcia_cd1";
++ pins = "gpio22";
++ };
++
++ pinctrl_pcmcia_cd2: pcmcia_cd2-pins {
++ function = "pcmcia_cd2";
++ pins = "gpio23";
++ };
++
++ pinctrl_pcmcia_vs1: pcmcia_vs1-pins {
++ function = "pcmcia_vs1";
++ pins = "gpio24";
++ };
++
++ pinctrl_pcmcia_vs2: pcmcia_vs2-pins {
++ function = "pcmcia_vs2";
++ pins = "gpio25";
++ };
++ };
++
++ pinctrl_ebi_cs2: ebi_cs2-pins {
++ function = "ebi_cs2";
++ pins = "gpio26";
++ };
++
++ pinctrl_ebi_cs3: ebi_cs3-pins {
++ function = "ebi_cs3";
++ pins = "gpio27";
++ };
++
++ pinctrl_spi_cs2: spi_cs2-pins {
++ function = "spi_cs2";
++ pins = "gpio28";
++ };
++
++ pinctrl_spi_cs3: spi_cs3-pins {
++ function = "spi_cs3";
++ pins = "gpio29";
++ };
++
++ pinctrl_spi_cs4: spi_cs4-pins {
++ function = "spi_cs4";
++ pins = "gpio30";
++ };
++
++ pinctrl_spi_cs5: spi_cs5-pins {
++ function = "spi_cs5";
++ pins = "gpio31";
++ };
++
++ pinctrl_uart1: uart1-pins {
++ function = "uart1";
++ group = "uart1_grp";
++ };
++ };
++ };
--- /dev/null
+From 50554accf7a79980cd04481e8903073bdb706daf Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
+Date: Wed, 24 Mar 2021 09:19:17 +0100
+Subject: [PATCH 16/22] 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.
+
+Co-developed-by: Jonas Gorski <jonas.gorski@gmail.com>
+Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
+Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
+Link: https://lore.kernel.org/r/20210324081923.20379-17-noltari@gmail.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ drivers/pinctrl/bcm/Kconfig | 8 +
+ drivers/pinctrl/bcm/Makefile | 1 +
+ drivers/pinctrl/bcm/pinctrl-bcm6368.c | 523 ++++++++++++++++++++++++++
+ 3 files changed, 532 insertions(+)
+ create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm6368.c
+
+--- a/drivers/pinctrl/bcm/Kconfig
++++ b/drivers/pinctrl/bcm/Kconfig
+@@ -60,6 +60,14 @@ config PINCTRL_BCM6362
+ help
+ Say Y here to enable the Broadcom BCM6362 GPIO driver.
+
++config PINCTRL_BCM6368
++ bool "Broadcom BCM6368 GPIO driver"
++ depends on (BMIPS_GENERIC || COMPILE_TEST)
++ select PINCTRL_BCM63XX
++ 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
+@@ -7,6 +7,7 @@ obj-$(CONFIG_PINCTRL_BCM63XX) += 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,523 @@
++// 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/bits.h>
++#include <linux/gpio/driver.h>
++#include <linux/kernel.h>
++#include <linux/of.h>
++#include <linux/pinctrl/pinmux.h>
++#include <linux/platform_device.h>
++#include <linux/regmap.h>
++
++#include "../pinctrl-utils.h"
++
++#include "pinctrl-bcm63xx.h"
++
++#define BCM6368_NUM_GPIOS 38
++
++#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_priv {
++ struct regmap_field *overlays;
++};
++
++#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 int bcm6368_pinctrl_set_mux(struct pinctrl_dev *pctldev,
++ unsigned selector, unsigned group)
++{
++ struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
++ struct bcm6368_priv *priv = pc->driver_data;
++ 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 < BCM63XX_BANK_GPIOS)
++ mask |= BIT(pin);
++ }
++
++ regmap_update_bits(pc->regs, BCM6368_MODE_REG, mask, 0);
++ regmap_field_write(priv->overlays, fun->basemode);
++ } else {
++ pin = pg->pins[0];
++
++ if (bcm6368_pins[pin].drv_data)
++ regmap_field_write(priv->overlays,
++ BCM6368_BASEMODE_GPIO);
++
++ regmap_update_bits(pc->regs, BCM6368_MODE_REG, BIT(pin),
++ BIT(pin));
++ }
++
++ for (pin = 0; pin < pg->num_pins; pin++) {
++ struct pinctrl_gpio_range *range;
++ int hw_gpio = bcm6368_pins[pin].number;
++
++ range = pinctrl_find_gpio_range_from_pin(pctldev, hw_gpio);
++ if (range) {
++ struct gpio_chip *gc = range->gc;
++
++ 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 bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
++ struct bcm6368_priv *priv = pc->driver_data;
++
++ if (offset >= BCM63XX_BANK_GPIOS && !bcm6368_pins[offset].drv_data)
++ return 0;
++
++ /* disable all functions using this pin */
++ if (offset < BCM63XX_BANK_GPIOS)
++ regmap_update_bits(pc->regs, BCM6368_MODE_REG, BIT(offset), 0);
++
++ if (bcm6368_pins[offset].drv_data)
++ regmap_field_write(priv->overlays, BCM6368_BASEMODE_GPIO);
++
++ return 0;
++}
++
++static struct pinctrl_ops bcm6368_pctl_ops = {
++ .dt_free_map = pinctrl_utils_free_map,
++ .dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
++ .get_group_name = bcm6368_pinctrl_get_group_name,
++ .get_group_pins = bcm6368_pinctrl_get_group_pins,
++ .get_groups_count = bcm6368_pinctrl_get_group_count,
++};
++
++static struct pinmux_ops bcm6368_pmx_ops = {
++ .get_function_groups = bcm6368_pinctrl_get_groups,
++ .get_function_name = bcm6368_pinctrl_get_func_name,
++ .get_functions_count = bcm6368_pinctrl_get_func_count,
++ .gpio_request_enable = bcm6368_gpio_request_enable,
++ .set_mux = bcm6368_pinctrl_set_mux,
++ .strict = true,
++};
++
++static const struct bcm63xx_pinctrl_soc bcm6368_soc = {
++ .ngpios = BCM6368_NUM_GPIOS,
++ .npins = ARRAY_SIZE(bcm6368_pins),
++ .pctl_ops = &bcm6368_pctl_ops,
++ .pins = bcm6368_pins,
++ .pmx_ops = &bcm6368_pmx_ops,
++};
++
++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 bcm63xx_pinctrl *pc;
++ struct bcm6368_priv *priv;
++ int err;
++
++ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
++ if (!priv)
++ return -ENOMEM;
++
++ err = bcm63xx_pinctrl_probe(pdev, &bcm6368_soc, (void *) priv);
++ if (err)
++ return err;
++
++ pc = platform_get_drvdata(pdev);
++
++ priv->overlays = devm_regmap_field_alloc(dev, pc->regs, overlays);
++ if (IS_ERR(priv->overlays))
++ return PTR_ERR(priv->overlays);
++
++ return 0;
++}
++
++static const struct of_device_id bcm6368_pinctrl_match[] = {
++ { .compatible = "brcm,bcm6368-pinctrl", },
++ { /* sentinel */ }
++};
++
++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);
--- /dev/null
+From 9b3303413379af8bed307cd465fe7aa1bc3569ea Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
+Date: Wed, 24 Mar 2021 09:19:18 +0100
+Subject: [PATCH 17/22] dt-bindings: 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.
+
+Co-developed-by: Jonas Gorski <jonas.gorski@gmail.com>
+Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
+Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Link: https://lore.kernel.org/r/20210324081923.20379-18-noltari@gmail.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ .../pinctrl/brcm,bcm63268-pinctrl.yaml | 164 ++++++++++++++++++
+ 1 file changed, 164 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,164 @@
++# 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:
++ Bindings for Broadcom's BCM63268 memory-mapped pin controller.
++
++properties:
++ compatible:
++ const: brcm,bcm63268-pinctrl
++
++ reg:
++ maxItems: 3
++
++patternProperties:
++ '-pins$':
++ type: object
++ $ref: pinmux-node.yaml#
++
++ properties:
++ function:
++ 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:
++ 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
++ - reg
++
++additionalProperties: false
++
++examples:
++ - |
++ pinctrl@10 {
++ compatible = "brcm,bcm63268-pinctrl";
++ reg = <0x10 0x4>, <0x18 0x8>, <0x38 0x4>;
++
++ pinctrl_serial_led: serial_led-pins {
++ pinctrl_serial_led_clk: serial_led_clk-pins {
++ function = "serial_led_clk";
++ pins = "gpio0";
++ };
++
++ pinctrl_serial_led_data: serial_led_data-pins {
++ function = "serial_led_data";
++ pins = "gpio1";
++ };
++ };
++
++ pinctrl_hsspi_cs4: hsspi_cs4-pins {
++ function = "hsspi_cs4";
++ pins = "gpio16";
++ };
++
++ pinctrl_hsspi_cs5: hsspi_cs5-pins {
++ function = "hsspi_cs5";
++ pins = "gpio17";
++ };
++
++ pinctrl_hsspi_cs6: hsspi_cs6-pins {
++ function = "hsspi_cs6";
++ pins = "gpio8";
++ };
++
++ pinctrl_hsspi_cs7: hsspi_cs7-pins {
++ function = "hsspi_cs7";
++ pins = "gpio9";
++ };
++
++ pinctrl_adsl_spi: adsl_spi-pins {
++ pinctrl_adsl_spi_miso: adsl_spi_miso-pins {
++ function = "adsl_spi_miso";
++ pins = "gpio18";
++ };
++
++ pinctrl_adsl_spi_mosi: adsl_spi_mosi-pins {
++ function = "adsl_spi_mosi";
++ pins = "gpio19";
++ };
++ };
++
++ pinctrl_vreq_clk: vreq_clk-pins {
++ function = "vreq_clk";
++ pins = "gpio22";
++ };
++
++ pinctrl_pcie_clkreq_b: pcie_clkreq_b-pins {
++ function = "pcie_clkreq_b";
++ pins = "gpio23";
++ };
++
++ pinctrl_robosw_led_clk: robosw_led_clk-pins {
++ function = "robosw_led_clk";
++ pins = "gpio30";
++ };
++
++ pinctrl_robosw_led_data: robosw_led_data-pins {
++ function = "robosw_led_data";
++ pins = "gpio31";
++ };
++
++ pinctrl_nand: nand-pins {
++ function = "nand";
++ group = "nand_grp";
++ };
++
++ pinctrl_gpio35_alt: gpio35_alt-pins {
++ function = "gpio35_alt";
++ pin = "gpio35";
++ };
++
++ pinctrl_dectpd: dectpd-pins {
++ function = "dectpd";
++ group = "dectpd_grp";
++ };
++
++ pinctrl_vdsl_phy_override_0: vdsl_phy_override_0-pins {
++ function = "vdsl_phy_override_0";
++ group = "vdsl_phy_override_0_grp";
++ };
++
++ pinctrl_vdsl_phy_override_1: vdsl_phy_override_1-pins {
++ function = "vdsl_phy_override_1";
++ group = "vdsl_phy_override_1_grp";
++ };
++
++ pinctrl_vdsl_phy_override_2: vdsl_phy_override_2-pins {
++ function = "vdsl_phy_override_2";
++ group = "vdsl_phy_override_2_grp";
++ };
++
++ pinctrl_vdsl_phy_override_3: vdsl_phy_override_3-pins {
++ function = "vdsl_phy_override_3";
++ group = "vdsl_phy_override_3_grp";
++ };
++
++ pinctrl_dsl_gpio8: dsl_gpio8-pins {
++ function = "dsl_gpio8";
++ group = "dsl_gpio8";
++ };
++
++ pinctrl_dsl_gpio9: dsl_gpio9-pins {
++ function = "dsl_gpio9";
++ group = "dsl_gpio9";
++ };
++ };
--- /dev/null
+From ff8324355d7ae2e4ebbd304de27bb5fa75e20c6a Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
+Date: Wed, 24 Mar 2021 09:19:19 +0100
+Subject: [PATCH 18/22] dt-bindings: add BCM63268 GPIO sysctl binding
+ documentation
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add binding documentation for the GPIO sysctl found in BCM63268 SoCs.
+
+Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Link: https://lore.kernel.org/r/20210324081923.20379-19-noltari@gmail.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ .../mfd/brcm,bcm63268-gpio-sysctl.yaml | 194 ++++++++++++++++++
+ 1 file changed, 194 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/mfd/brcm,bcm63268-gpio-sysctl.yaml
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/mfd/brcm,bcm63268-gpio-sysctl.yaml
+@@ -0,0 +1,194 @@
++# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/mfd/brcm,bcm63268-gpio-sysctl.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: Broadcom BCM63268 GPIO System Controller Device Tree Bindings
++
++maintainers:
++ - Álvaro Fernández Rojas <noltari@gmail.com>
++ - Jonas Gorski <jonas.gorski@gmail.com>
++
++description:
++ Broadcom BCM63268 SoC GPIO system controller which provides a register map
++ for controlling the GPIO and pins of the SoC.
++
++properties:
++ "#address-cells": true
++
++ "#size-cells": true
++
++ compatible:
++ items:
++ - const: brcm,bcm63268-gpio-sysctl
++ - const: syscon
++ - const: simple-mfd
++
++ ranges:
++ maxItems: 1
++
++ reg:
++ maxItems: 1
++
++patternProperties:
++ "^gpio@[0-9a-f]+$":
++ # Child node
++ type: object
++ $ref: "../gpio/brcm,bcm6345-gpio.yaml"
++ description:
++ GPIO controller for the SoC GPIOs. This child node definition
++ should follow the bindings specified in
++ Documentation/devicetree/bindings/gpio/brcm,bcm6345-gpio.yaml.
++
++ "^pinctrl@[0-9a-f]+$":
++ # Child node
++ type: object
++ $ref: "../pinctrl/brcm,bcm63268-pinctrl.yaml"
++ description:
++ Pin controller for the SoC pins. This child node definition
++ should follow the bindings specified in
++ Documentation/devicetree/bindings/pinctrl/brcm,bcm63268-pinctrl.yaml.
++
++required:
++ - "#address-cells"
++ - compatible
++ - ranges
++ - reg
++ - "#size-cells"
++
++additionalProperties: false
++
++examples:
++ - |
++ syscon@100000c0 {
++ #address-cells = <1>;
++ #size-cells = <1>;
++ compatible = "brcm,bcm63268-gpio-sysctl", "syscon", "simple-mfd";
++ reg = <0x100000c0 0x80>;
++ ranges = <0 0x100000c0 0x80>;
++
++ gpio@0 {
++ compatible = "brcm,bcm63268-gpio";
++ reg-names = "dirout", "dat";
++ reg = <0x0 0x8>, <0x8 0x8>;
++
++ gpio-controller;
++ gpio-ranges = <&pinctrl 0 0 52>;
++ #gpio-cells = <2>;
++ };
++
++ pinctrl: pinctrl@10 {
++ compatible = "brcm,bcm63268-pinctrl";
++ reg = <0x10 0x4>, <0x18 0x8>, <0x38 0x4>;
++
++ pinctrl_serial_led: serial_led-pins {
++ pinctrl_serial_led_clk: serial_led_clk-pins {
++ function = "serial_led_clk";
++ pins = "gpio0";
++ };
++
++ pinctrl_serial_led_data: serial_led_data-pins {
++ function = "serial_led_data";
++ pins = "gpio1";
++ };
++ };
++
++ pinctrl_hsspi_cs4: hsspi_cs4-pins {
++ function = "hsspi_cs4";
++ pins = "gpio16";
++ };
++
++ pinctrl_hsspi_cs5: hsspi_cs5-pins {
++ function = "hsspi_cs5";
++ pins = "gpio17";
++ };
++
++ pinctrl_hsspi_cs6: hsspi_cs6-pins {
++ function = "hsspi_cs6";
++ pins = "gpio8";
++ };
++
++ pinctrl_hsspi_cs7: hsspi_cs7-pins {
++ function = "hsspi_cs7";
++ pins = "gpio9";
++ };
++
++ pinctrl_adsl_spi: adsl_spi-pins {
++ pinctrl_adsl_spi_miso: adsl_spi_miso-pins {
++ function = "adsl_spi_miso";
++ pins = "gpio18";
++ };
++
++ pinctrl_adsl_spi_mosi: adsl_spi_mosi-pins {
++ function = "adsl_spi_mosi";
++ pins = "gpio19";
++ };
++ };
++
++ pinctrl_vreq_clk: vreq_clk-pins {
++ function = "vreq_clk";
++ pins = "gpio22";
++ };
++
++ pinctrl_pcie_clkreq_b: pcie_clkreq_b-pins {
++ function = "pcie_clkreq_b";
++ pins = "gpio23";
++ };
++
++ pinctrl_robosw_led_clk: robosw_led_clk-pins {
++ function = "robosw_led_clk";
++ pins = "gpio30";
++ };
++
++ pinctrl_robosw_led_data: robosw_led_data-pins {
++ function = "robosw_led_data";
++ pins = "gpio31";
++ };
++
++ pinctrl_nand: nand-pins {
++ function = "nand";
++ group = "nand_grp";
++ };
++
++ pinctrl_gpio35_alt: gpio35_alt-pins {
++ function = "gpio35_alt";
++ pin = "gpio35";
++ };
++
++ pinctrl_dectpd: dectpd-pins {
++ function = "dectpd";
++ group = "dectpd_grp";
++ };
++
++ pinctrl_vdsl_phy_override_0: vdsl_phy_override_0-pins {
++ function = "vdsl_phy_override_0";
++ group = "vdsl_phy_override_0_grp";
++ };
++
++ pinctrl_vdsl_phy_override_1: vdsl_phy_override_1-pins {
++ function = "vdsl_phy_override_1";
++ group = "vdsl_phy_override_1_grp";
++ };
++
++ pinctrl_vdsl_phy_override_2: vdsl_phy_override_2-pins {
++ function = "vdsl_phy_override_2";
++ group = "vdsl_phy_override_2_grp";
++ };
++
++ pinctrl_vdsl_phy_override_3: vdsl_phy_override_3-pins {
++ function = "vdsl_phy_override_3";
++ group = "vdsl_phy_override_3_grp";
++ };
++
++ pinctrl_dsl_gpio8: dsl_gpio8-pins {
++ function = "dsl_gpio8";
++ group = "dsl_gpio8";
++ };
++
++ pinctrl_dsl_gpio9: dsl_gpio9-pins {
++ function = "dsl_gpio9";
++ group = "dsl_gpio9";
++ };
++ };
++ };
--- /dev/null
+From 155cca1b0794a8f541e7eaa45be70df0a49964f3 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
+Date: Wed, 24 Mar 2021 09:19:20 +0100
+Subject: [PATCH 19/22] 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.
+
+Co-developed-by: Jonas Gorski <jonas.gorski@gmail.com>
+Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
+Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
+Link: https://lore.kernel.org/r/20210324081923.20379-20-noltari@gmail.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ drivers/pinctrl/bcm/Kconfig | 8 +
+ drivers/pinctrl/bcm/Makefile | 1 +
+ drivers/pinctrl/bcm/pinctrl-bcm63268.c | 643 +++++++++++++++++++++++++
+ 3 files changed, 652 insertions(+)
+ create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm63268.c
+
+--- a/drivers/pinctrl/bcm/Kconfig
++++ b/drivers/pinctrl/bcm/Kconfig
+@@ -68,6 +68,14 @@ config PINCTRL_BCM6368
+ help
+ Say Y here to enable the Broadcom BCM6368 GPIO driver.
+
++config PINCTRL_BCM63268
++ bool "Broadcom BCM63268 GPIO driver"
++ depends on (BMIPS_GENERIC || COMPILE_TEST)
++ select PINCTRL_BCM63XX
++ 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
+@@ -8,6 +8,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,643 @@
++// 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/bits.h>
++#include <linux/gpio/driver.h>
++#include <linux/kernel.h>
++#include <linux/of.h>
++#include <linux/pinctrl/pinmux.h>
++#include <linux/platform_device.h>
++#include <linux/regmap.h>
++
++#include "../pinctrl-utils.h"
++
++#include "pinctrl-bcm63xx.h"
++
++#define BCM63268_NUM_GPIOS 52
++#define BCM63268_NUM_LEDS 24
++
++#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;
++};
++
++#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 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 bcm63xx_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(bcm63xx_bank_pin(pin));
++
++ if (basemode)
++ regmap_update_bits(pc->regs, BCM63268_BASEMODE_REG, basemode,
++ 0);
++
++ if (pin < BCM63XX_BANK_GPIOS) {
++ /* 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 bcm63xx_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 bcm63xx_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 = {
++ .dt_free_map = pinctrl_utils_free_map,
++ .dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
++ .get_group_name = bcm63268_pinctrl_get_group_name,
++ .get_group_pins = bcm63268_pinctrl_get_group_pins,
++ .get_groups_count = bcm63268_pinctrl_get_group_count,
++};
++
++static struct pinmux_ops bcm63268_pmx_ops = {
++ .get_function_groups = bcm63268_pinctrl_get_groups,
++ .get_function_name = bcm63268_pinctrl_get_func_name,
++ .get_functions_count = bcm63268_pinctrl_get_func_count,
++ .gpio_request_enable = bcm63268_gpio_request_enable,
++ .set_mux = bcm63268_pinctrl_set_mux,
++ .strict = true,
++};
++
++static const struct bcm63xx_pinctrl_soc bcm63268_soc = {
++ .ngpios = BCM63268_NUM_GPIOS,
++ .npins = ARRAY_SIZE(bcm63268_pins),
++ .pctl_ops = &bcm63268_pctl_ops,
++ .pins = bcm63268_pins,
++ .pmx_ops = &bcm63268_pmx_ops,
++};
++
++static int bcm63268_pinctrl_probe(struct platform_device *pdev)
++{
++ return bcm63xx_pinctrl_probe(pdev, &bcm63268_soc, NULL);
++}
++
++static const struct of_device_id bcm63268_pinctrl_match[] = {
++ { .compatible = "brcm,bcm63268-pinctrl", },
++ { /* sentinel */ }
++};
++
++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);
--- /dev/null
+From b2f215141b985d5d39ed16fe7e2089d5aa162302 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
+Date: Wed, 24 Mar 2021 09:19:21 +0100
+Subject: [PATCH 20/22] dt-bindings: 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.
+
+Co-developed-by: Jonas Gorski <jonas.gorski@gmail.com>
+Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
+Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Link: https://lore.kernel.org/r/20210324081923.20379-21-noltari@gmail.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ .../pinctrl/brcm,bcm6318-pinctrl.yaml | 143 ++++++++++++++++++
+ 1 file changed, 143 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,143 @@
++# 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:
++ Bindings for Broadcom's BCM6318 memory-mapped pin controller.
++
++properties:
++ compatible:
++ const: brcm,bcm6318-pinctrl
++
++ reg:
++ maxItems: 2
++
++patternProperties:
++ '-pins$':
++ type: object
++ $ref: pinmux-node.yaml#
++
++ properties:
++ function:
++ 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:
++ enum: [ gpio0, gpio1, gpio2, gpio3, gpio4, gpio5, gpio6, gpio7,
++ gpio8, gpio9, gpio10, gpio11, gpio12, gpio13, gpio40 ]
++
++required:
++ - compatible
++ - reg
++
++additionalProperties: false
++
++examples:
++ - |
++ pinctrl@18 {
++ compatible = "brcm,bcm6318-pinctrl";
++ reg = <0x18 0x10>, <0x54 0x18>;
++
++ pinctrl_ephy0_spd_led: ephy0_spd_led-pins {
++ function = "ephy0_spd_led";
++ pins = "gpio0";
++ };
++
++ pinctrl_ephy1_spd_led: ephy1_spd_led-pins {
++ function = "ephy1_spd_led";
++ pins = "gpio1";
++ };
++
++ pinctrl_ephy2_spd_led: ephy2_spd_led-pins {
++ function = "ephy2_spd_led";
++ pins = "gpio2";
++ };
++
++ pinctrl_ephy3_spd_led: ephy3_spd_led-pins {
++ function = "ephy3_spd_led";
++ pins = "gpio3";
++ };
++
++ pinctrl_ephy0_act_led: ephy0_act_led-pins {
++ function = "ephy0_act_led";
++ pins = "gpio4";
++ };
++
++ pinctrl_ephy1_act_led: ephy1_act_led-pins {
++ function = "ephy1_act_led";
++ pins = "gpio5";
++ };
++
++ pinctrl_ephy2_act_led: ephy2_act_led-pins {
++ function = "ephy2_act_led";
++ pins = "gpio6";
++ };
++
++ pinctrl_ephy3_act_led: ephy3_act_led-pins {
++ function = "ephy3_act_led";
++ pins = "gpio7";
++ };
++
++ pinctrl_serial_led: serial_led-pins {
++ pinctrl_serial_led_data: serial_led_data-pins {
++ function = "serial_led_data";
++ pins = "gpio6";
++ };
++
++ pinctrl_serial_led_clk: serial_led_clk-pins {
++ function = "serial_led_clk";
++ pins = "gpio7";
++ };
++ };
++
++ pinctrl_inet_act_led: inet_act_led-pins {
++ function = "inet_act_led";
++ pins = "gpio8";
++ };
++
++ pinctrl_inet_fail_led: inet_fail_led-pins {
++ function = "inet_fail_led";
++ pins = "gpio9";
++ };
++
++ pinctrl_dsl_led: dsl_led-pins {
++ function = "dsl_led";
++ pins = "gpio10";
++ };
++
++ pinctrl_post_fail_led: post_fail_led-pins {
++ function = "post_fail_led";
++ pins = "gpio11";
++ };
++
++ pinctrl_wlan_wps_led: wlan_wps_led-pins {
++ function = "wlan_wps_led";
++ pins = "gpio12";
++ };
++
++ pinctrl_usb_pwron: usb_pwron-pins {
++ function = "usb_pwron";
++ pins = "gpio13";
++ };
++
++ pinctrl_usb_device_led: usb_device_led-pins {
++ function = "usb_device_led";
++ pins = "gpio13";
++ };
++
++ pinctrl_usb_active: usb_active-pins {
++ function = "usb_active";
++ pins = "gpio40";
++ };
++ };
--- /dev/null
+From b6d46b9454742a25f9d923be072869e40b2ecebb Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
+Date: Wed, 24 Mar 2021 09:19:22 +0100
+Subject: [PATCH 21/22] dt-bindings: add BCM6318 GPIO sysctl binding
+ documentation
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add binding documentation for the GPIO sysctl found in BCM6318 SoCs.
+
+Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Link: https://lore.kernel.org/r/20210324081923.20379-22-noltari@gmail.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ .../mfd/brcm,bcm6318-gpio-sysctl.yaml | 177 ++++++++++++++++++
+ 1 file changed, 177 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/mfd/brcm,bcm6318-gpio-sysctl.yaml
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/mfd/brcm,bcm6318-gpio-sysctl.yaml
+@@ -0,0 +1,177 @@
++# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/mfd/brcm,bcm6318-gpio-sysctl.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: Broadcom BCM6318 GPIO System Controller Device Tree Bindings
++
++maintainers:
++ - Álvaro Fernández Rojas <noltari@gmail.com>
++ - Jonas Gorski <jonas.gorski@gmail.com>
++
++description:
++ Broadcom BCM6318 SoC GPIO system controller which provides a register map
++ for controlling the GPIO and pins of the SoC.
++
++properties:
++ "#address-cells": true
++
++ "#size-cells": true
++
++ compatible:
++ items:
++ - const: brcm,bcm6318-gpio-sysctl
++ - const: syscon
++ - const: simple-mfd
++
++ ranges:
++ maxItems: 1
++
++ reg:
++ maxItems: 1
++
++patternProperties:
++ "^gpio@[0-9a-f]+$":
++ # Child node
++ type: object
++ $ref: "../gpio/brcm,bcm6345-gpio.yaml"
++ description:
++ GPIO controller for the SoC GPIOs. This child node definition
++ should follow the bindings specified in
++ Documentation/devicetree/bindings/gpio/brcm,bcm6345-gpio.yaml.
++
++ "^pinctrl@[0-9a-f]+$":
++ # Child node
++ type: object
++ $ref: "../pinctrl/brcm,bcm6318-pinctrl.yaml"
++ description:
++ Pin controller for the SoC pins. This child node definition
++ should follow the bindings specified in
++ Documentation/devicetree/bindings/pinctrl/brcm,bcm6318-pinctrl.yaml.
++
++required:
++ - "#address-cells"
++ - compatible
++ - ranges
++ - reg
++ - "#size-cells"
++
++additionalProperties: false
++
++examples:
++ - |
++ syscon@10000080 {
++ #address-cells = <1>;
++ #size-cells = <1>;
++ compatible = "brcm,bcm6318-gpio-sysctl", "syscon", "simple-mfd";
++ reg = <0x10000080 0x80>;
++ ranges = <0 0x10000080 0x80>;
++
++ gpio@0 {
++ compatible = "brcm,bcm6318-gpio";
++ reg-names = "dirout", "dat";
++ reg = <0x0 0x8>, <0x8 0x8>;
++
++ gpio-controller;
++ gpio-ranges = <&pinctrl 0 0 50>;
++ #gpio-cells = <2>;
++ };
++
++ pinctrl: pinctrl@10 {
++ compatible = "brcm,bcm6318-pinctrl";
++ reg = <0x18 0x10>, <0x54 0x18>;
++
++ pinctrl_ephy0_spd_led: ephy0_spd_led-pins {
++ function = "ephy0_spd_led";
++ pins = "gpio0";
++ };
++
++ pinctrl_ephy1_spd_led: ephy1_spd_led-pins {
++ function = "ephy1_spd_led";
++ pins = "gpio1";
++ };
++
++ pinctrl_ephy2_spd_led: ephy2_spd_led-pins {
++ function = "ephy2_spd_led";
++ pins = "gpio2";
++ };
++
++ pinctrl_ephy3_spd_led: ephy3_spd_led-pins {
++ function = "ephy3_spd_led";
++ pins = "gpio3";
++ };
++
++ pinctrl_ephy0_act_led: ephy0_act_led-pins {
++ function = "ephy0_act_led";
++ pins = "gpio4";
++ };
++
++ pinctrl_ephy1_act_led: ephy1_act_led-pins {
++ function = "ephy1_act_led";
++ pins = "gpio5";
++ };
++
++ pinctrl_ephy2_act_led: ephy2_act_led-pins {
++ function = "ephy2_act_led";
++ pins = "gpio6";
++ };
++
++ pinctrl_ephy3_act_led: ephy3_act_led-pins {
++ function = "ephy3_act_led";
++ pins = "gpio7";
++ };
++
++ pinctrl_serial_led: serial_led-pins {
++ pinctrl_serial_led_data: serial_led_data-pins {
++ function = "serial_led_data";
++ pins = "gpio6";
++ };
++
++ pinctrl_serial_led_clk: serial_led_clk-pins {
++ function = "serial_led_clk";
++ pins = "gpio7";
++ };
++ };
++
++ pinctrl_inet_act_led: inet_act_led-pins {
++ function = "inet_act_led";
++ pins = "gpio8";
++ };
++
++ pinctrl_inet_fail_led: inet_fail_led-pins {
++ function = "inet_fail_led";
++ pins = "gpio9";
++ };
++
++ pinctrl_dsl_led: dsl_led-pins {
++ function = "dsl_led";
++ pins = "gpio10";
++ };
++
++ pinctrl_post_fail_led: post_fail_led-pins {
++ function = "post_fail_led";
++ pins = "gpio11";
++ };
++
++ pinctrl_wlan_wps_led: wlan_wps_led-pins {
++ function = "wlan_wps_led";
++ pins = "gpio12";
++ };
++
++ pinctrl_usb_pwron: usb_pwron-pins {
++ function = "usb_pwron";
++ pins = "gpio13";
++ };
++
++ pinctrl_usb_device_led: usb_device_led-pins {
++ function = "usb_device_led";
++ pins = "gpio13";
++ };
++
++ pinctrl_usb_active: usb_active-pins {
++ function = "usb_active";
++ pins = "gpio40";
++ };
++ };
++ };
--- /dev/null
+From d28039fccf948a407de69106465caa465b1dcf32 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
+Date: Wed, 24 Mar 2021 09:19:23 +0100
+Subject: [PATCH 22/22] 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.
+
+Co-developed-by: Jonas Gorski <jonas.gorski@gmail.com>
+Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
+Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
+Link: https://lore.kernel.org/r/20210324081923.20379-23-noltari@gmail.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ drivers/pinctrl/bcm/Kconfig | 8 +
+ drivers/pinctrl/bcm/Makefile | 1 +
+ drivers/pinctrl/bcm/pinctrl-bcm6318.c | 498 ++++++++++++++++++++++++++
+ 3 files changed, 507 insertions(+)
+ create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm6318.c
+
+--- a/drivers/pinctrl/bcm/Kconfig
++++ b/drivers/pinctrl/bcm/Kconfig
+@@ -36,6 +36,14 @@ config PINCTRL_BCM63XX
+ select PINCONF
+ select PINMUX
+
++config PINCTRL_BCM6318
++ bool "Broadcom BCM6318 GPIO driver"
++ depends on (BMIPS_GENERIC || COMPILE_TEST)
++ select PINCTRL_BCM63XX
++ default BMIPS_GENERIC
++ help
++ Say Y here to enable the Broadcom BCM6318 GPIO driver.
++
+ config PINCTRL_BCM6328
+ bool "Broadcom BCM6328 GPIO driver"
+ depends on (BMIPS_GENERIC || 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_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/bcm/pinctrl-bcm6318.c
+@@ -0,0 +1,498 @@
++// 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/bits.h>
++#include <linux/gpio/driver.h>
++#include <linux/kernel.h>
++#include <linux/of.h>
++#include <linux/pinctrl/pinmux.h>
++#include <linux/platform_device.h>
++#include <linux/regmap.h>
++
++#include "../pinctrl-utils.h"
++
++#include "pinctrl-bcm63xx.h"
++
++#define BCM6318_NUM_GPIOS 50
++#define BCM6318_NUM_MUX 48
++
++#define BCM6318_MODE_REG 0x18
++#define BCM6318_MUX_REG 0x1c
++#define BCM6328_MUX_MASK GENMASK(1, 0)
++#define BCM6318_PAD_REG 0x54
++#define BCM6328_PAD_MASK GENMASK(3, 0)
++
++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;
++};
++
++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_mux_off(unsigned int pin)
++{
++ return BCM6318_MUX_REG + (pin / 16) * 4;
++}
++
++static inline unsigned int bcm6318_pad_off(unsigned int pin)
++{
++ return BCM6318_PAD_REG + (pin / 8) * 4;
++}
++
++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 bcm63xx_pinctrl *pc, unsigned pin,
++ unsigned int mode, unsigned int mux)
++{
++ if (pin < BCM63XX_BANK_GPIOS)
++ 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),
++ BCM6328_MUX_MASK << ((pin % 16) * 2),
++ mux << ((pin % 16) * 2));
++}
++
++static inline void bcm6318_set_pad(struct bcm63xx_pinctrl *pc, unsigned pin,
++ uint8_t val)
++{
++ regmap_update_bits(pc->regs, bcm6318_pad_off(pin),
++ BCM6328_PAD_MASK << ((pin % 8) * 4),
++ val << ((pin % 8) * 4));
++}
++
++static int bcm6318_pinctrl_set_mux(struct pinctrl_dev *pctldev,
++ unsigned selector, unsigned group)
++{
++ struct bcm63xx_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 bcm63xx_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 = {
++ .dt_free_map = pinctrl_utils_free_map,
++ .dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
++ .get_group_name = bcm6318_pinctrl_get_group_name,
++ .get_group_pins = bcm6318_pinctrl_get_group_pins,
++ .get_groups_count = bcm6318_pinctrl_get_group_count,
++};
++
++static struct pinmux_ops bcm6318_pmx_ops = {
++ .get_function_groups = bcm6318_pinctrl_get_groups,
++ .get_function_name = bcm6318_pinctrl_get_func_name,
++ .get_functions_count = bcm6318_pinctrl_get_func_count,
++ .gpio_request_enable = bcm6318_gpio_request_enable,
++ .set_mux = bcm6318_pinctrl_set_mux,
++ .strict = true,
++};
++
++static const struct bcm63xx_pinctrl_soc bcm6318_soc = {
++ .ngpios = BCM6318_NUM_GPIOS,
++ .npins = ARRAY_SIZE(bcm6318_pins),
++ .pctl_ops = &bcm6318_pctl_ops,
++ .pins = bcm6318_pins,
++ .pmx_ops = &bcm6318_pmx_ops,
++};
++
++static int bcm6318_pinctrl_probe(struct platform_device *pdev)
++{
++ return bcm63xx_pinctrl_probe(pdev, &bcm6318_soc, NULL);
++}
++
++static const struct of_device_id bcm6318_pinctrl_match[] = {
++ { .compatible = "brcm,bcm6318-pinctrl", },
++ { /* sentinel */ }
++};
++
++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);
+++ /dev/null
-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";
-+ };
-+ };
-+ };
+++ /dev/null
-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);
+++ /dev/null
-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";
-+ };
-+ };
-+ };
+++ /dev/null
-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);
+++ /dev/null
-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";
-+ };
-+ };
-+ };
+++ /dev/null
-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);
+++ /dev/null
-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";
-+ };
-+ };
-+ };
+++ /dev/null
-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);
+++ /dev/null
-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";
-+ };
-+ };
-+ };
+++ /dev/null
-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);
+++ /dev/null
-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";
-+ };
-+ };
-+ };
+++ /dev/null
-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);