linux-gpio.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/2] Add pinctrl support to EN7581 SoC
@ 2024-08-11 16:12 Lorenzo Bianconi
  2024-08-11 16:12 ` [PATCH 1/2] dt-bindings: pinctrl: airoha: Add EN7581 pinctrl controller Lorenzo Bianconi
  2024-08-11 16:12 ` [PATCH 2/2] pinctrl: airoha: Add support for EN7581 SoC Lorenzo Bianconi
  0 siblings, 2 replies; 19+ messages in thread
From: Lorenzo Bianconi @ 2024-08-11 16:12 UTC (permalink / raw)
  To: linux-gpio
  Cc: linus.walleij, sean.wang, linux-mediatek, lorenzo.bianconi83,
	krzk+dt, robh, devicetree, linux-arm-kernel, upstream,
	angelogioacchino.delregno, benjamin.larsson, conor+dt, ansuelsmth

Introduce pinctrl driver for EN7581 SoC. Current EN7581 pinctrl driver
supports the following functionalities:
- pin multiplexing
- pin pull-up, pull-down, open-drain, current strength,
  {input,output}_enable, output_{low,high}
- gpio controller
- irq controller

Lorenzo Bianconi (2):
  dt-bindings: pinctrl: airoha: Add EN7581 pinctrl controller
  pinctrl: airoha: Add support for EN7581 SoC

 .../pinctrl/airoha,en7581-pinctrl.yaml        |  467 +++
 MAINTAINERS                                   |    7 +
 drivers/pinctrl/mediatek/Kconfig              |   14 +-
 drivers/pinctrl/mediatek/Makefile             |    1 +
 drivers/pinctrl/mediatek/pinctrl-airoha.c     | 2983 +++++++++++++++++
 5 files changed, 3471 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/airoha,en7581-pinctrl.yaml
 create mode 100644 drivers/pinctrl/mediatek/pinctrl-airoha.c

-- 
2.46.0


^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 1/2] dt-bindings: pinctrl: airoha: Add EN7581 pinctrl controller
  2024-08-11 16:12 [PATCH 0/2] Add pinctrl support to EN7581 SoC Lorenzo Bianconi
@ 2024-08-11 16:12 ` Lorenzo Bianconi
  2024-08-12  6:48   ` Krzysztof Kozlowski
  2024-08-11 16:12 ` [PATCH 2/2] pinctrl: airoha: Add support for EN7581 SoC Lorenzo Bianconi
  1 sibling, 1 reply; 19+ messages in thread
From: Lorenzo Bianconi @ 2024-08-11 16:12 UTC (permalink / raw)
  To: linux-gpio
  Cc: linus.walleij, sean.wang, linux-mediatek, lorenzo.bianconi83,
	krzk+dt, robh, devicetree, linux-arm-kernel, upstream,
	angelogioacchino.delregno, benjamin.larsson, conor+dt, ansuelsmth

Introduce device-tree binding documentation for Airoha EN7581 pinctrl
controller.

Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
 .../pinctrl/airoha,en7581-pinctrl.yaml        | 467 ++++++++++++++++++
 1 file changed, 467 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/airoha,en7581-pinctrl.yaml

diff --git a/Documentation/devicetree/bindings/pinctrl/airoha,en7581-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/airoha,en7581-pinctrl.yaml
new file mode 100644
index 000000000000..b1f980613864
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/airoha,en7581-pinctrl.yaml
@@ -0,0 +1,467 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/airoha,en7581-pinctrl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Airoha EN7581 Pin Controller
+
+maintainers:
+  - Lorenzo Bianconi <lorenzo@kernel.org>
+
+description:
+  The Airoha's EN7581 Pin controller is used to control SoC pins.
+
+properties:
+  compatible:
+    enum:
+      - airoha,en7581-pinctrl
+
+  reg:
+    items:
+      - description: IOMUX base address
+      - description: LED IOMUX base address
+      - description: GPIO flash mode base address
+      - description: GPIO flash mode extended base address
+      - description: IO pin configuration base address
+      - description: PCIE reset open-drain base address
+      - description: GPIO bank0 data register base address
+      - description: GPIO bank1 data register base address
+      - description: GPIO bank0 first control register base address
+      - description: GPIO bank0 second control register base address
+      - description: GPIO bank1 first control register base address
+      - description: GPIO bank1 second control register base address
+      - description: GPIO bank0 output enable register base address
+      - description: GPIO bank1 output enable register base address
+      - description: GPIO bank0 irq status register base address
+      - description: GPIO bank1 irq status register base address
+      - description: GPIO bank0 irq level first control register base address
+      - description: GPIO bank0 irq level second control register base address
+      - description: GPIO bank1 irq level first control register base address
+      - description: GPIO bank1 irq level second control register base address
+      - description: GPIO bank0 irq edge first control register base address
+      - description: GPIO bank0 irq edge second control register base address
+      - description: GPIO bank1 irq edge first control register base address
+      - description: GPIO bank1 irq edge second control register base address
+
+  gpio-controller: true
+
+  "#gpio-cells":
+    const: 2
+    description:
+      Number of cells in GPIO specifier. Since the generic GPIO binding is
+      used, the amount of cells must be specified as 2. See the below mentioned
+      gpio binding representation for description of particular cells.
+
+  gpio-ranges:
+    maxItems: 1
+    description:
+      GPIO valid number range.
+
+  interrupt-controller: true
+
+  interrupts:
+    maxItems: 1
+
+  "#interrupt-cells":
+    const: 2
+
+allOf:
+  - $ref: pinctrl.yaml#
+
+required:
+  - compatible
+  - reg
+  - gpio-controller
+  - "#gpio-cells"
+
+patternProperties:
+  '-pins$':
+    type: object
+    additionalProperties: false
+
+    patternProperties:
+      '^.*mux.*$':
+        type: object
+        additionalProperties: false
+        description: |
+          pinmux configuration nodes.
+
+        $ref: /schemas/pinctrl/pinmux-node.yaml
+        properties:
+          function:
+            description:
+              A string containing the name of the function to mux to the group.
+            enum: [pon, tod_1pps, sipo, mdio, uart, i2c, jtag, pcm, spi,
+                   pcm_spi, i2s, emmc, pnand, pcie_reset, pwm, phy1_led0,
+                   phy2_led0, phy3_led0, phy4_led0, phy1_led1, phy2_led1,
+                   phy3_led1, phy4_led1]
+          groups:
+            description:
+              An array of strings. Each string contains the name of a group.
+        required:
+          - function
+          - groups
+
+        allOf:
+          - if:
+              properties:
+                function:
+                  const: pon
+            then:
+              properties:
+                groups:
+                  enum: [pon]
+          - if:
+              properties:
+                function:
+                  const: tod_1pps
+            then:
+              properties:
+                groups:
+                  enum: [pon_tod_1pps, gsw_tod_1pps]
+          - if:
+              properties:
+                function:
+                  const: sipo
+            then:
+              properties:
+                groups:
+                  enum: [sipo, sipo_rclk]
+          - if:
+              properties:
+                function:
+                  const: mdio
+            then:
+              properties:
+                groups:
+                  enum: [mdio]
+          - if:
+              properties:
+                function:
+                  const: uart
+            then:
+              properties:
+                groups:
+                  items:
+                    enum: [uart2, uart2_cts_rts, hsuart, hsuart_cts_rts, uart4,
+                           uart5]
+                  maxItems: 2
+          - if:
+              properties:
+                function:
+                  const: i2c
+            then:
+              properties:
+                groups:
+                  enum: [i2c1]
+          - if:
+              properties:
+                function:
+                  const: jtag
+            then:
+              properties:
+                groups:
+                  enum: [jtag_udi, jtag_dfd]
+          - if:
+              properties:
+                function:
+                  const: pcm
+            then:
+              properties:
+                groups:
+                  enum: [pcm1, pcm2]
+          - if:
+              properties:
+                function:
+                  const: spi
+            then:
+              properties:
+                groups:
+                  items:
+                    enum: [spi_quad, spi_cs1]
+                  maxItems: 2
+          - if:
+              properties:
+                function:
+                  const: pcm_spi
+            then:
+              properties:
+                groups:
+                  items:
+                    enum: [pcm_spi, pcm_spi_int, pcm_spi_rst, pcm_spi_cs1,
+                           pcm_spi_cs2_p156, pcm_spi_cs2_p128, pcm_spi_cs3,
+                           pcm_spi_cs4]
+                  maxItems: 7
+          - if:
+              properties:
+                function:
+                  const: i2c
+            then:
+              properties:
+                groups:
+                  enum: [i2s]
+          - if:
+              properties:
+                function:
+                  const: emmc
+            then:
+              properties:
+                groups:
+                  enum: [emmc]
+          - if:
+              properties:
+                function:
+                  const: pnand
+            then:
+              properties:
+                groups:
+                  enum: [pnand]
+          - if:
+              properties:
+                function:
+                  const: pcie_reset
+            then:
+              properties:
+                groups:
+                  enum: [pcie_reset0, pcie_reset1, pcie_reset2]
+          - if:
+              properties:
+                function:
+                  const: pwm
+            then:
+              properties:
+                groups:
+                  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, gpio28, gpio29, gpio30, gpio31,
+                         gpio36, gpio37, gpio38, gpio39, gpio40, gpio41,
+                         gpio42, gpio43, gpio44, gpio45, gpio46, gpio47]
+          - if:
+              properties:
+                function:
+                  const: phy1_led0
+            then:
+              properties:
+                groups:
+                  enum: [gpio33, gpio34, gpio35, gpio42]
+          - if:
+              properties:
+                function:
+                  const: phy2_led0
+            then:
+              properties:
+                groups:
+                  enum: [gpio33, gpio34, gpio35, gpio42]
+          - if:
+              properties:
+                function:
+                  const: phy3_led0
+            then:
+              properties:
+                groups:
+                  enum: [gpio33, gpio34, gpio35, gpio42]
+          - if:
+              properties:
+                function:
+                  const: phy4_led0
+            then:
+              properties:
+                groups:
+                  enum: [gpio33, gpio34, gpio35, gpio42]
+          - if:
+              properties:
+                function:
+                  const: phy1_led1
+            then:
+              properties:
+                groups:
+                  enum: [gpio43, gpio44, gpio45, gpio46]
+          - if:
+              properties:
+                function:
+                  const: phy2_led1
+            then:
+              properties:
+                groups:
+                  enum: [gpio43, gpio44, gpio45, gpio46]
+          - if:
+              properties:
+                function:
+                  const: phy3_led1
+            then:
+              properties:
+                groups:
+                  enum: [gpio43, gpio44, gpio45, gpio46]
+          - if:
+              properties:
+                function:
+                  const: phy4_led1
+            then:
+              properties:
+                groups:
+                  enum: [gpio43, gpio44, gpio45, gpio46]
+
+      '^.*conf.*$':
+        type: object
+        additionalProperties: false
+        description:
+          pinconf configuration nodes.
+        $ref: /schemas/pinctrl/pincfg-node.yaml
+
+        properties:
+          pins:
+            description:
+              An array of strings. Each string contains the name of a pin.
+            items:
+              enum: [uart1_txd, uart1_rxd, i2c_scl, i2c_sda, spi_cs0, spi_clk,
+                     spi_mosi, spi_miso, gpio0, gpio1, gpio2, gpio3, gpio4,
+                     gpio5, gpio6, gpio7, gpio8, gpio9, gpio10, gpio11, gpio12,
+                     gpio13, gpio14, gpio15, gpio16, gpio17, gpio18, gpio19,
+                     gpio20, gpio21, gpio22, gpio23, gpio24, gpio25, gpio26,
+                     gpio27, gpio28, gpio29, gpio30, gpio31, gpio32, gpio33,
+                     gpio34, gpio35, gpio36, gpio37, gpio38, gpio39, gpio40,
+                     gpio41, gpio42, gpio43, gpio44, gpio45, gpio46,
+                     pcie_reset0, pcie_reset1, pcie_reset2]
+            maxItems: 58
+
+          bias-disable: true
+
+          bias-pull-up: true
+
+          bias-pull-down: true
+
+          input-enable: true
+
+          output-enable: true
+
+          output-low: true
+
+          output-high: true
+
+          drive-open-drain: true
+
+          drive-strength:
+            enum: [2, 4, 6, 8]
+
+        required:
+          - pins
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    soc {
+      #address-cells = <2>;
+      #size-cells = <2>;
+
+      pio: pinctrl@1fa20214 {
+        compatible = "airoha,en7581-pinctrl";
+        reg = <0x0 0x1fa20214 0x0 0x30>,
+              <0x0 0x1fa2027c 0x0 0x8>,
+              <0x0 0x1fbf0234 0x0 0x4>,
+              <0x0 0x1fbf0268 0x0 0x4>,
+              <0x0 0x1fa2001c 0x0 0x50>,
+              <0x0 0x1fa2018c 0x0 0x4>,
+              <0x0 0x1fbf0204 0x0 0x4>,
+              <0x0 0x1fbf0270 0x0 0x4>,
+              <0x0 0x1fbf0200 0x0 0x4>,
+              <0x0 0x1fbf0220 0x0 0x4>,
+              <0x0 0x1fbf0260 0x0 0x4>,
+              <0x0 0x1fbf0264 0x0 0x4>,
+              <0x0 0x1fbf0214 0x0 0x4>,
+              <0x0 0x1fbf0278 0x0 0x4>,
+              <0x0 0x1fbf0208 0x0 0x4>,
+              <0x0 0x1fbf027c 0x0 0x4>,
+              <0x0 0x1fbf0210 0x0 0x4>,
+              <0x0 0x1fbf028c 0x0 0x4>,
+              <0x0 0x1fbf0290 0x0 0x4>,
+              <0x0 0x1fbf0294 0x0 0x4>,
+              <0x0 0x1fbf020c 0x0 0x4>,
+              <0x0 0x1fbf0280 0x0 0x4>,
+              <0x0 0x1fbf0284 0x0 0x4>,
+              <0x0 0x1fbf0288 0x0 0x4>;
+
+        gpio-controller;
+        #gpio-cells = <2>;
+        gpio-ranges = <&pio 0 13 47>;
+
+        interrupt-controller;
+        #interrupt-cells = <2>;
+        interrupt-parent = <&gic>;
+        interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+
+        pcie1-rst-pins {
+          conf {
+            pins = "pcie_reset1";
+            drive-open-drain = <1>;
+          };
+        };
+
+        pwm-pins {
+          mux {
+            function = "pwm";
+            groups = "gpio18";
+          };
+        };
+
+        spi-pins {
+          mux {
+            function = "spi";
+            groups = "spi_quad", "spi_cs1";
+          };
+        };
+
+        uuart2-pins {
+          mux {
+            function = "uart";
+            groups = "uart2", "uart2_cts_rts";
+          };
+        };
+
+        uar5-pins {
+          mux {
+            function = "uart";
+            groups = "uart5";
+          };
+        };
+
+        mmc-pins {
+          mux {
+            function = "emmc";
+            groups = "emmc";
+          };
+        };
+
+        mdio-pins {
+          mux {
+            function = "mdio";
+            groups = "mdio";
+          };
+
+          conf {
+            pins = "gpio2";
+            output-enable;
+          };
+        };
+
+        gswp1-led0-pins {
+          mux {
+            function = "phy1_led0";
+            groups = "gpio33";
+          };
+        };
+
+        gswp2-led1-pins {
+          mux {
+            function = "phy2_led1";
+            groups = "gpio44";
+          };
+        };
+      };
+    };
-- 
2.46.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 2/2] pinctrl: airoha: Add support for EN7581 SoC
  2024-08-11 16:12 [PATCH 0/2] Add pinctrl support to EN7581 SoC Lorenzo Bianconi
  2024-08-11 16:12 ` [PATCH 1/2] dt-bindings: pinctrl: airoha: Add EN7581 pinctrl controller Lorenzo Bianconi
@ 2024-08-11 16:12 ` Lorenzo Bianconi
  2024-08-11 21:08   ` kernel test robot
                     ` (2 more replies)
  1 sibling, 3 replies; 19+ messages in thread
From: Lorenzo Bianconi @ 2024-08-11 16:12 UTC (permalink / raw)
  To: linux-gpio
  Cc: linus.walleij, sean.wang, linux-mediatek, lorenzo.bianconi83,
	krzk+dt, robh, devicetree, linux-arm-kernel, upstream,
	angelogioacchino.delregno, benjamin.larsson, conor+dt, ansuelsmth

Introduce pinctrl driver for EN7581 SoC. Current EN7581 pinctrl driver
supports the following functionalities:
- pin multiplexing
- pin pull-up, pull-down, open-drain, current strength,
  {input,output}_enable, output_{low,high}
- gpio controller
- irq controller

Tested-by: Benjamin Larsson <benjamin.larsson@genexis.eu>
Co-developed-by: Benjamin Larsson <benjamin.larsson@genexis.eu>
Signed-off-by: Benjamin Larsson <benjamin.larsson@genexis.eu>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
 MAINTAINERS                               |    7 +
 drivers/pinctrl/mediatek/Kconfig          |   14 +-
 drivers/pinctrl/mediatek/Makefile         |    1 +
 drivers/pinctrl/mediatek/pinctrl-airoha.c | 2983 +++++++++++++++++++++
 4 files changed, 3004 insertions(+), 1 deletion(-)
 create mode 100644 drivers/pinctrl/mediatek/pinctrl-airoha.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 804dcbc448b6..dfea9a52abb4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -17670,6 +17670,13 @@ F:	drivers/pinctrl/
 F:	include/dt-bindings/pinctrl/
 F:	include/linux/pinctrl/
 
+PIN CONTROLLER - AIROHA
+M:	Lorenzo Bianconi <lorenzo@kernel.org>
+L:	linux-mediatek@lists.infradead.org (moderated for non-subscribers)
+S:	Maintained
+F:	Documentation/devicetree/bindings/pinctrl/airoha,en7581-pinctrl.yaml
+F:	drivers/pinctrl/mediatek/pinctrl-airoha.c
+
 PIN CONTROLLER - AMD
 M:	Basavaraj Natikar <Basavaraj.Natikar@amd.com>
 M:	Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
diff --git a/drivers/pinctrl/mediatek/Kconfig b/drivers/pinctrl/mediatek/Kconfig
index 7af287252834..7443a090d40b 100644
--- a/drivers/pinctrl/mediatek/Kconfig
+++ b/drivers/pinctrl/mediatek/Kconfig
@@ -1,6 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0-only
 menu "MediaTek pinctrl drivers"
-	depends on ARCH_MEDIATEK || RALINK || COMPILE_TEST
+	depends on ARCH_MEDIATEK || ARCH_AIROHA || RALINK || COMPILE_TEST
 
 config EINT_MTK
 	tristate "MediaTek External Interrupt Support"
@@ -126,6 +126,18 @@ config PINCTRL_MT8127
 	select PINCTRL_MTK
 
 # For ARMv8 SoCs
+config PINCTRL_AIROHA
+	tristate "Airoha pin control"
+	depends on OF
+	depends on ARM64 || COMPILE_TEST
+	select PINMUX
+	select GENERIC_PINCONF
+	select GPIOLIB
+	select GPIOLIB_IRQCHIP
+	help
+	  Say yes here to support pin controller and gpio driver
+	  on Airoha EN7581 SoC.
+
 config PINCTRL_MT2712
 	bool "MediaTek MT2712 pin control"
 	depends on OF
diff --git a/drivers/pinctrl/mediatek/Makefile b/drivers/pinctrl/mediatek/Makefile
index 680f7e8526e0..1405d434218e 100644
--- a/drivers/pinctrl/mediatek/Makefile
+++ b/drivers/pinctrl/mediatek/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_PINCTRL_MTK_MOORE)		+= pinctrl-moore.o
 obj-$(CONFIG_PINCTRL_MTK_PARIS)		+= pinctrl-paris.o
 
 # SoC Drivers
+obj-$(CONFIG_PINCTRL_AIROHA)		+= pinctrl-airoha.o
 obj-$(CONFIG_PINCTRL_MT7620)		+= pinctrl-mt7620.o
 obj-$(CONFIG_PINCTRL_MT7621)		+= pinctrl-mt7621.o
 obj-$(CONFIG_PINCTRL_MT76X8)		+= pinctrl-mt76x8.o
diff --git a/drivers/pinctrl/mediatek/pinctrl-airoha.c b/drivers/pinctrl/mediatek/pinctrl-airoha.c
new file mode 100644
index 000000000000..29de4fd70f49
--- /dev/null
+++ b/drivers/pinctrl/mediatek/pinctrl-airoha.c
@@ -0,0 +1,2983 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Author: Lorenzo Bianconi <lorenzo@kernel.org>
+ * Author: Benjamin Larsson <benjamin.larsson@genexis.eu>
+ * Author: Markus Gothe <markus.gothe@genexis.eu>
+ */
+
+#include <dt-bindings/pinctrl/mt65xx.h>
+#include <linux/gpio/driver.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinconf-generic.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/platform_device.h>
+
+#include "../core.h"
+#include "../pinconf.h"
+#include "../pinmux.h"
+
+#define PINCTRL_PIN_GROUP(id)						\
+	PINCTRL_PINGROUP(#id, id##_pins, ARRAY_SIZE(id##_pins))
+
+#define PINCTRL_FUNC_DESC(id)						\
+	{								\
+		.desc = { #id, id##_groups, ARRAY_SIZE(id##_groups) },	\
+		.groups = id##_func_group,				\
+		.group_size = ARRAY_SIZE(id##_func_group),		\
+	}
+
+#define PINCTRL_CONF_DESC(p, offset, mask)				\
+	{								\
+		.pin = p,						\
+		.reg = { offset, mask },				\
+	}
+
+/* MUX */
+#define REG_GPIO_2ND_I2C_MODE			0x00
+#define GPIO_MDC_IO_MASTER_MODE_MODE		BIT(14)
+#define GPIO_I2C_MASTER_MODE_MODE		BIT(13)
+#define GPIO_I2S_MODE_MASK			BIT(12)
+#define GPIO_I2C_SLAVE_MODE_MODE		BIT(11)
+#define GPIO_LAN3_LED1_MODE_MASK		BIT(10)
+#define GPIO_LAN3_LED0_MODE_MASK		BIT(9)
+#define GPIO_LAN2_LED1_MODE_MASK		BIT(8)
+#define GPIO_LAN2_LED0_MODE_MASK		BIT(7)
+#define GPIO_LAN1_LED1_MODE_MASK		BIT(6)
+#define GPIO_LAN1_LED0_MODE_MASK		BIT(5)
+#define GPIO_LAN0_LED1_MODE_MASK		BIT(4)
+#define GPIO_LAN0_LED0_MODE_MASK		BIT(3)
+#define PON_TOD_1PPS_MODE_MASK			BIT(2)
+#define GSW_TOD_1PPS_MODE_MASK			BIT(1)
+#define GPIO_2ND_I2C_MODE_MASK			BIT(0)
+
+#define REG_GPIO_SPI_CS1_MODE			0x04
+#define GPIO_PCM_SPI_CS4_MODE_MASK		BIT(21)
+#define GPIO_PCM_SPI_CS3_MODE_MASK		BIT(20)
+#define GPIO_PCM_SPI_CS2_MODE_P156_MASK		BIT(19)
+#define GPIO_PCM_SPI_CS2_MODE_P128_MASK		BIT(18)
+#define GPIO_PCM_SPI_CS1_MODE_MASK		BIT(17)
+#define GPIO_PCM_SPI_MODE_MASK			BIT(16)
+#define GPIO_PCM2_MODE_MASK			BIT(13)
+#define GPIO_PCM1_MODE_MASK			BIT(12)
+#define GPIO_PCM_INT_MODE_MASK			BIT(9)
+#define GPIO_PCM_RESET_MODE_MASK		BIT(8)
+#define GPIO_SPI_QUAD_MODE_MASK			BIT(4)
+#define GPIO_SPI_CS4_MODE_MASK			BIT(3)
+#define GPIO_SPI_CS3_MODE_MASK			BIT(2)
+#define GPIO_SPI_CS2_MODE_MASK			BIT(1)
+#define GPIO_SPI_CS1_MODE_MASK			BIT(0)
+
+#define REG_GPIO_PON_MODE			0x08
+#define GPIO_PARALLEL_NAND_MODE_MASK		BIT(14)
+#define GPIO_SGMII_MDIO_MODE_MASK		BIT(13)
+#define GPIO_PCIE_RESET2_MASK			BIT(12)
+#define SIPO_RCLK_MODE_MASK			BIT(11)
+#define GPIO_PCIE_RESET1_MASK			BIT(10)
+#define GPIO_PCIE_RESET0_MASK			BIT(9)
+#define GPIO_UART5_MODE_MASK			BIT(8)
+#define GPIO_UART4_MODE_MASK			BIT(7)
+#define GPIO_HSUART_CTS_RTS_MODE_MASK		BIT(6)
+#define GPIO_HSUART_MODE_MASK			BIT(5)
+#define GPIO_UART2_CTS_RTS_MODE_MASK		BIT(4)
+#define GPIO_UART2_MODE_MASK			BIT(3)
+#define GPIO_SIPO_MODE_MASK			BIT(2)
+#define GPIO_EMMC_MODE_MASK			BIT(1)
+#define GPIO_PON_MODE_MASK			BIT(0)
+
+#define REG_NPU_UART_EN				0x10
+#define JTAG_UDI_EN_MASK			BIT(4)
+#define JTAG_DFD_EN_MASK			BIT(3)
+
+#define REG_FORCE_GPIO0_EN			0x14
+#define REG_FORCE_GPIO32_EN			0x18
+#define REG_INIC_MDIO_SLV_MOD			0x1c
+
+/* LED MAP */
+#define REG_LAN_LED0_MAPPING			0x00
+#define REG_LAN_LED1_MAPPING			0x04
+
+#define LAN4_LED_MAPPING_MASK			GENMASK(18, 16)
+#define LAN4_PHY4_LED_MAP			BIT(18)
+#define LAN4_PHY2_LED_MAP			BIT(17)
+#define LAN4_PHY1_LED_MAP			BIT(16)
+#define LAN4_PHY0_LED_MAP			0
+#define LAN4_PHY3_LED_MAP			GENMASK(17, 16)
+
+#define LAN3_LED_MAPPING_MASK			GENMASK(14, 12)
+#define LAN3_PHY4_LED_MAP			BIT(14)
+#define LAN3_PHY2_LED_MAP			BIT(13)
+#define LAN3_PHY1_LED_MAP			BIT(12)
+#define LAN3_PHY0_LED_MAP			0
+#define LAN3_PHY3_LED_MAP			GENMASK(13, 12)
+
+#define LAN2_LED_MAPPING_MASK			GENMASK(10, 8)
+#define LAN2_PHY4_LED_MAP			BIT(12)
+#define LAN2_PHY2_LED_MAP			BIT(11)
+#define LAN2_PHY1_LED_MAP			BIT(10)
+#define LAN2_PHY0_LED_MAP			0
+#define LAN2_PHY3_LED_MAP			GENMASK(11, 10)
+
+#define LAN1_LED_MAPPING_MASK			GENMASK(6, 4)
+#define LAN1_PHY4_LED_MAP			BIT(6)
+#define LAN1_PHY2_LED_MAP			BIT(5)
+#define LAN1_PHY1_LED_MAP			BIT(4)
+#define LAN1_PHY0_LED_MAP			0
+#define LAN1_PHY3_LED_MAP			GENMASK(5, 4)
+
+#define LAN0_LED_MAPPING_MASK			GENMASK(2, 0)
+#define LAN0_PHY4_LED_MAP			BIT(3)
+#define LAN0_PHY2_LED_MAP			BIT(2)
+#define LAN0_PHY1_LED_MAP			BIT(1)
+#define LAN0_PHY0_LED_MAP			0
+#define LAN0_PHY3_LED_MAP			GENMASK(2, 1)
+
+/* CONF */
+#define REG_I2C_SDA_E2				0x00
+#define SPI_MISO_E2_MASK			BIT(14)
+#define SPI_MOSI_E2_MASK			BIT(13)
+#define SPI_CLK_E2_MASK				BIT(12)
+#define SPI_CS0_E2_MASK				BIT(11)
+#define PCIE2_RESET_E2_MASK			BIT(10)
+#define PCIE1_RESET_E2_MASK			BIT(9)
+#define PCIE0_RESET_E2_MASK			BIT(8)
+#define UART1_RXD_E2_MASK			BIT(3)
+#define UART1_TXD_E2_MASK			BIT(2)
+#define I2C_SCL_E2_MASK				BIT(1)
+#define I2C_SDA_E2_MASK				BIT(0)
+
+#define REG_I2C_SDA_E4				0x04
+#define SPI_MISO_E4_MASK			BIT(14)
+#define SPI_MOSI_E4_MASK			BIT(13)
+#define SPI_CLK_E4_MASK				BIT(12)
+#define SPI_CS0_E4_MASK				BIT(11)
+#define PCIE2_RESET_E4_MASK			BIT(10)
+#define PCIE1_RESET_E4_MASK			BIT(9)
+#define PCIE0_RESET_E4_MASK			BIT(8)
+#define UART1_RXD_E4_MASK			BIT(3)
+#define UART1_TXD_E4_MASK			BIT(2)
+#define I2C_SCL_E4_MASK				BIT(1)
+#define I2C_SDA_E4_MASK				BIT(0)
+
+#define REG_GPIO_L_E2				0x08
+#define REG_GPIO_L_E4				0x0c
+#define REG_GPIO_H_E2				0x10
+#define REG_GPIO_H_E4				0x14
+
+#define REG_I2C_SDA_PU				0x28
+#define SPI_MISO_PU_MASK			BIT(14)
+#define SPI_MOSI_PU_MASK			BIT(13)
+#define SPI_CLK_PU_MASK				BIT(12)
+#define SPI_CS0_PU_MASK				BIT(11)
+#define PCIE2_RESET_PU_MASK			BIT(10)
+#define PCIE1_RESET_PU_MASK			BIT(9)
+#define PCIE0_RESET_PU_MASK			BIT(8)
+#define UART1_RXD_PU_MASK			BIT(3)
+#define UART1_TXD_PU_MASK			BIT(2)
+#define I2C_SCL_PU_MASK				BIT(1)
+#define I2C_SDA_PU_MASK				BIT(0)
+
+#define REG_I2C_SDA_PD				0x2c
+#define SPI_MISO_PD_MASK			BIT(14)
+#define SPI_MOSI_PD_MASK			BIT(13)
+#define SPI_CLK_PD_MASK				BIT(12)
+#define SPI_CS0_PD_MASK				BIT(11)
+#define PCIE2_RESET_PD_MASK			BIT(10)
+#define PCIE1_RESET_PD_MASK			BIT(9)
+#define PCIE0_RESET_PD_MASK			BIT(8)
+#define UART1_RXD_PD_MASK			BIT(3)
+#define UART1_TXD_PD_MASK			BIT(2)
+#define I2C_SCL_PD_MASK				BIT(1)
+#define I2C_SDA_PD_MASK				BIT(0)
+
+#define REG_GPIO_L_PU				0x30
+#define REG_GPIO_L_PD				0x34
+#define REG_GPIO_H_PU				0x38
+#define REG_GPIO_H_PD				0x3c
+
+#define REG_PCIE_RESET_OD			0x00
+#define PCIE2_RESET_OD_MASK			BIT(2)
+#define PCIE1_RESET_OD_MASK			BIT(1)
+#define PCIE0_RESET_OD_MASK			BIT(0)
+
+/* PWM MODE CONF */
+#define REG_GPIO_FLASH_MODE_CFG			0x00
+#define GPIO15_FLASH_MODE_CFG			BIT(15)
+#define GPIO14_FLASH_MODE_CFG			BIT(14)
+#define GPIO13_FLASH_MODE_CFG			BIT(13)
+#define GPIO12_FLASH_MODE_CFG			BIT(12)
+#define GPIO11_FLASH_MODE_CFG			BIT(11)
+#define GPIO10_FLASH_MODE_CFG			BIT(10)
+#define GPIO9_FLASH_MODE_CFG			BIT(9)
+#define GPIO8_FLASH_MODE_CFG			BIT(8)
+#define GPIO7_FLASH_MODE_CFG			BIT(7)
+#define GPIO6_FLASH_MODE_CFG			BIT(6)
+#define GPIO5_FLASH_MODE_CFG			BIT(5)
+#define GPIO4_FLASH_MODE_CFG			BIT(4)
+#define GPIO3_FLASH_MODE_CFG			BIT(3)
+#define GPIO2_FLASH_MODE_CFG			BIT(2)
+#define GPIO1_FLASH_MODE_CFG			BIT(1)
+#define GPIO0_FLASH_MODE_CFG			BIT(0)
+
+/* PWM MODE CONF EXT */
+#define REG_GPIO_FLASH_MODE_CFG_EXT		0x00
+#define GPIO51_FLASH_MODE_CFG			BIT(31)
+#define GPIO50_FLASH_MODE_CFG			BIT(30)
+#define GPIO49_FLASH_MODE_CFG			BIT(29)
+#define GPIO48_FLASH_MODE_CFG			BIT(28)
+#define GPIO47_FLASH_MODE_CFG			BIT(27)
+#define GPIO46_FLASH_MODE_CFG			BIT(26)
+#define GPIO45_FLASH_MODE_CFG			BIT(25)
+#define GPIO44_FLASH_MODE_CFG			BIT(24)
+#define GPIO43_FLASH_MODE_CFG			BIT(23)
+#define GPIO42_FLASH_MODE_CFG			BIT(22)
+#define GPIO41_FLASH_MODE_CFG			BIT(21)
+#define GPIO40_FLASH_MODE_CFG			BIT(20)
+#define GPIO39_FLASH_MODE_CFG			BIT(19)
+#define GPIO38_FLASH_MODE_CFG			BIT(18)
+#define GPIO37_FLASH_MODE_CFG			BIT(17)
+#define GPIO36_FLASH_MODE_CFG			BIT(16)
+#define GPIO31_FLASH_MODE_CFG			BIT(15)
+#define GPIO30_FLASH_MODE_CFG			BIT(14)
+#define GPIO29_FLASH_MODE_CFG			BIT(13)
+#define GPIO28_FLASH_MODE_CFG			BIT(12)
+#define GPIO27_FLASH_MODE_CFG			BIT(11)
+#define GPIO26_FLASH_MODE_CFG			BIT(10)
+#define GPIO25_FLASH_MODE_CFG			BIT(9)
+#define GPIO24_FLASH_MODE_CFG			BIT(8)
+#define GPIO23_FLASH_MODE_CFG			BIT(7)
+#define GPIO22_FLASH_MODE_CFG			BIT(6)
+#define GPIO21_FLASH_MODE_CFG			BIT(5)
+#define GPIO20_FLASH_MODE_CFG			BIT(4)
+#define GPIO19_FLASH_MODE_CFG			BIT(3)
+#define GPIO18_FLASH_MODE_CFG			BIT(2)
+#define GPIO17_FLASH_MODE_CFG			BIT(1)
+#define GPIO16_FLASH_MODE_CFG			BIT(0)
+
+#define AIROHA_NUM_GPIOS			64
+#define AIROHA_GPIO_BANK_SIZE			(AIROHA_NUM_GPIOS / 2)
+#define AIROHA_REG_GPIOCTRL_NUM_GPIO		(AIROHA_NUM_GPIOS / 4)
+
+struct airoha_pinctrl_reg {
+	u32 offset;
+	u32 mask;
+};
+
+enum airoha_pinctrl_mux_func {
+	AIROHA_FUNC_MUX,
+	AIROHA_FUNC_LED_MUX,
+	AIROHA_FUNC_PWM_MUX,
+	AIROHA_FUNC_PWM_EXT_MUX,
+};
+
+struct airoha_pinctrl_func_group {
+	const char *name;
+	struct {
+		enum airoha_pinctrl_mux_func mux;
+		u32 offset;
+		u32 mask;
+		u32 val;
+	} regmap[2];
+	int regmap_size;
+};
+
+struct airoha_pinctrl_func {
+	const struct function_desc desc;
+	const struct airoha_pinctrl_func_group *groups;
+	u8 group_size;
+};
+
+struct airoha_pinctrl_conf {
+	u32 pin;
+	struct airoha_pinctrl_reg reg;
+};
+
+struct airoha_pinctrl_gpiochip {
+	struct gpio_chip chip;
+
+	void __iomem *data[2];
+	void __iomem *dir[4];
+	void __iomem *out[2];
+
+	/* protect concurrent register accesses */
+	spinlock_t lock;
+	void __iomem *status[2];
+	void __iomem *level[4];
+	void __iomem *edge[4];
+
+	u32 irq_type[AIROHA_NUM_GPIOS];
+};
+
+struct airoha_pinctrl {
+	struct pinctrl_dev *ctrl;
+
+	/* protect concurrent register accesses */
+	struct mutex mutex;
+	struct {
+		void __iomem *mux[4];
+		void __iomem *conf;
+		void __iomem *pcie_rst;
+	} regs;
+
+	struct airoha_pinctrl_gpiochip gpiochip;
+};
+
+static struct pinctrl_pin_desc airoha_pinctrl_pins[] = {
+	PINCTRL_PIN(0, "uart1_txd"),
+	PINCTRL_PIN(1, "uart1_rxd"),
+	PINCTRL_PIN(2, "i2c_scl"),
+	PINCTRL_PIN(3, "i2c_sda"),
+	PINCTRL_PIN(4, "spi_cs0"),
+	PINCTRL_PIN(5, "spi_clk"),
+	PINCTRL_PIN(6, "spi_mosi"),
+	PINCTRL_PIN(7, "spi_miso"),
+	PINCTRL_PIN(13, "gpio0"),
+	PINCTRL_PIN(14, "gpio1"),
+	PINCTRL_PIN(15, "gpio2"),
+	PINCTRL_PIN(16, "gpio3"),
+	PINCTRL_PIN(17, "gpio4"),
+	PINCTRL_PIN(18, "gpio5"),
+	PINCTRL_PIN(19, "gpio6"),
+	PINCTRL_PIN(20, "gpio7"),
+	PINCTRL_PIN(21, "gpio8"),
+	PINCTRL_PIN(22, "gpio9"),
+	PINCTRL_PIN(23, "gpio10"),
+	PINCTRL_PIN(24, "gpio11"),
+	PINCTRL_PIN(25, "gpio12"),
+	PINCTRL_PIN(26, "gpio13"),
+	PINCTRL_PIN(27, "gpio14"),
+	PINCTRL_PIN(28, "gpio15"),
+	PINCTRL_PIN(29, "gpio16"),
+	PINCTRL_PIN(30, "gpio17"),
+	PINCTRL_PIN(31, "gpio18"),
+	PINCTRL_PIN(32, "gpio19"),
+	PINCTRL_PIN(33, "gpio20"),
+	PINCTRL_PIN(34, "gpio21"),
+	PINCTRL_PIN(35, "gpio22"),
+	PINCTRL_PIN(36, "gpio23"),
+	PINCTRL_PIN(37, "gpio24"),
+	PINCTRL_PIN(38, "gpio25"),
+	PINCTRL_PIN(39, "gpio26"),
+	PINCTRL_PIN(40, "gpio27"),
+	PINCTRL_PIN(41, "gpio28"),
+	PINCTRL_PIN(42, "gpio29"),
+	PINCTRL_PIN(43, "gpio30"),
+	PINCTRL_PIN(44, "gpio31"),
+	PINCTRL_PIN(45, "gpio32"),
+	PINCTRL_PIN(46, "gpio33"),
+	PINCTRL_PIN(47, "gpio34"),
+	PINCTRL_PIN(48, "gpio35"),
+	PINCTRL_PIN(49, "gpio36"),
+	PINCTRL_PIN(50, "gpio37"),
+	PINCTRL_PIN(51, "gpio38"),
+	PINCTRL_PIN(52, "gpio39"),
+	PINCTRL_PIN(53, "gpio40"),
+	PINCTRL_PIN(54, "gpio41"),
+	PINCTRL_PIN(55, "gpio42"),
+	PINCTRL_PIN(56, "gpio43"),
+	PINCTRL_PIN(57, "gpio44"),
+	PINCTRL_PIN(58, "gpio45"),
+	PINCTRL_PIN(59, "gpio46"),
+	PINCTRL_PIN(61, "pcie_reset0"),
+	PINCTRL_PIN(62, "pcie_reset1"),
+	PINCTRL_PIN(63, "pcie_reset2"),
+};
+
+static const int pon_pins[] = { 49, 50, 51, 52, 53, 54 };
+static const int pon_tod_1pps_pins[] = { 46 };
+static const int gsw_tod_1pps_pins[] = { 46 };
+static const int sipo_pins[] = { 16, 17 };
+static const int sipo_rclk_pins[] = { 16, 17, 43 };
+static const int mdio_pins[] = { 14, 15 };
+static const int uart2_pins[] = { 48, 55 };
+static const int uart2_cts_rts_pins[] = { 46, 47 };
+static const int hsuart_pins[] = { 28, 29 };
+static const int hsuart_cts_rts_pins[] = { 26, 27 };
+static const int uart4_pins[] = { 38, 39 };
+static const int uart5_pins[] = { 18, 19 };
+static const int i2c0_pins[] = { 2, 3 };
+static const int i2c1_pins[] = { 14, 15 };
+static const int jtag_udi_pins[] = { 16, 17, 18, 19, 20 };
+static const int jtag_dfd_pins[] = { 16, 17, 18, 19, 20 };
+static const int i2s_pins[] = { 26, 27, 28, 29 };
+static const int pcm1_pins[] = { 22, 23, 24, 25 };
+static const int pcm2_pins[] = { 18, 19, 20, 21 };
+static const int spi_quad_pins[] = { 32, 33 };
+static const int spi_pins[] = { 4, 5, 6, 7 };
+static const int spi_cs1_pins[] = { 34 };
+static const int pcm_spi_pins[] = { 18, 19, 20, 21, 22, 23, 24, 25 };
+static const int pcm_spi_int_pins[] = { 14 };
+static const int pcm_spi_rst_pins[] = { 15 };
+static const int pcm_spi_cs1_pins[] = { 43 };
+static const int pcm_spi_cs2_pins[] = { 40 };
+static const int pcm_spi_cs2_p128_pins[] = { 40 };
+static const int pcm_spi_cs2_p156_pins[] = { 40 };
+static const int pcm_spi_cs3_pins[] = { 41 };
+static const int pcm_spi_cs4_pins[] = { 42 };
+static const int emmc_pins[] = { 4, 5, 6, 30, 31, 32, 33, 34, 35, 36, 37 };
+static const int pnand_pins[] = { 4, 5, 6, 7, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42 };
+static const int gpio0_pins[] = { 13 };
+static const int gpio1_pins[] = { 14 };
+static const int gpio2_pins[] = { 15 };
+static const int gpio3_pins[] = { 16 };
+static const int gpio4_pins[] = { 17 };
+static const int gpio5_pins[] = { 18 };
+static const int gpio6_pins[] = { 19 };
+static const int gpio7_pins[] = { 20 };
+static const int gpio8_pins[] = { 21 };
+static const int gpio9_pins[] = { 22 };
+static const int gpio10_pins[] = { 23 };
+static const int gpio11_pins[] = { 24 };
+static const int gpio12_pins[] = { 25 };
+static const int gpio13_pins[] = { 26 };
+static const int gpio14_pins[] = { 27 };
+static const int gpio15_pins[] = { 28 };
+static const int gpio16_pins[] = { 29 };
+static const int gpio17_pins[] = { 30 };
+static const int gpio18_pins[] = { 31 };
+static const int gpio19_pins[] = { 32 };
+static const int gpio20_pins[] = { 33 };
+static const int gpio21_pins[] = { 34 };
+static const int gpio22_pins[] = { 35 };
+static const int gpio23_pins[] = { 36 };
+static const int gpio24_pins[] = { 37 };
+static const int gpio25_pins[] = { 38 };
+static const int gpio26_pins[] = { 39 };
+static const int gpio27_pins[] = { 40 };
+static const int gpio28_pins[] = { 41 };
+static const int gpio29_pins[] = { 42 };
+static const int gpio30_pins[] = { 43 };
+static const int gpio31_pins[] = { 44 };
+static const int gpio33_pins[] = { 46 };
+static const int gpio34_pins[] = { 47 };
+static const int gpio35_pins[] = { 48 };
+static const int gpio36_pins[] = { 49 };
+static const int gpio37_pins[] = { 50 };
+static const int gpio38_pins[] = { 51 };
+static const int gpio39_pins[] = { 52 };
+static const int gpio40_pins[] = { 53 };
+static const int gpio41_pins[] = { 54 };
+static const int gpio42_pins[] = { 55 };
+static const int gpio43_pins[] = { 56 };
+static const int gpio44_pins[] = { 57 };
+static const int gpio45_pins[] = { 58 };
+static const int gpio46_pins[] = { 59 };
+static const int pcie_reset0_pins[] = { 61 };
+static const int pcie_reset1_pins[] = { 62 };
+static const int pcie_reset2_pins[] = { 63 };
+
+static const struct pingroup airoha_pinctrl_groups[] = {
+	PINCTRL_PIN_GROUP(pon),
+	PINCTRL_PIN_GROUP(pon_tod_1pps),
+	PINCTRL_PIN_GROUP(gsw_tod_1pps),
+	PINCTRL_PIN_GROUP(sipo),
+	PINCTRL_PIN_GROUP(sipo_rclk),
+	PINCTRL_PIN_GROUP(mdio),
+	PINCTRL_PIN_GROUP(uart2),
+	PINCTRL_PIN_GROUP(uart2_cts_rts),
+	PINCTRL_PIN_GROUP(hsuart),
+	PINCTRL_PIN_GROUP(hsuart_cts_rts),
+	PINCTRL_PIN_GROUP(uart4),
+	PINCTRL_PIN_GROUP(uart5),
+	PINCTRL_PIN_GROUP(i2c0),
+	PINCTRL_PIN_GROUP(i2c1),
+	PINCTRL_PIN_GROUP(jtag_udi),
+	PINCTRL_PIN_GROUP(jtag_dfd),
+	PINCTRL_PIN_GROUP(i2s),
+	PINCTRL_PIN_GROUP(pcm1),
+	PINCTRL_PIN_GROUP(pcm2),
+	PINCTRL_PIN_GROUP(spi),
+	PINCTRL_PIN_GROUP(spi_quad),
+	PINCTRL_PIN_GROUP(spi_cs1),
+	PINCTRL_PIN_GROUP(pcm_spi),
+	PINCTRL_PIN_GROUP(pcm_spi_int),
+	PINCTRL_PIN_GROUP(pcm_spi_rst),
+	PINCTRL_PIN_GROUP(pcm_spi_cs1),
+	PINCTRL_PIN_GROUP(pcm_spi_cs2_p128),
+	PINCTRL_PIN_GROUP(pcm_spi_cs2_p156),
+	PINCTRL_PIN_GROUP(pcm_spi_cs2),
+	PINCTRL_PIN_GROUP(pcm_spi_cs3),
+	PINCTRL_PIN_GROUP(pcm_spi_cs4),
+	PINCTRL_PIN_GROUP(emmc),
+	PINCTRL_PIN_GROUP(pnand),
+	PINCTRL_PIN_GROUP(gpio0),
+	PINCTRL_PIN_GROUP(gpio1),
+	PINCTRL_PIN_GROUP(gpio2),
+	PINCTRL_PIN_GROUP(gpio3),
+	PINCTRL_PIN_GROUP(gpio4),
+	PINCTRL_PIN_GROUP(gpio5),
+	PINCTRL_PIN_GROUP(gpio6),
+	PINCTRL_PIN_GROUP(gpio7),
+	PINCTRL_PIN_GROUP(gpio8),
+	PINCTRL_PIN_GROUP(gpio9),
+	PINCTRL_PIN_GROUP(gpio10),
+	PINCTRL_PIN_GROUP(gpio11),
+	PINCTRL_PIN_GROUP(gpio12),
+	PINCTRL_PIN_GROUP(gpio13),
+	PINCTRL_PIN_GROUP(gpio14),
+	PINCTRL_PIN_GROUP(gpio15),
+	PINCTRL_PIN_GROUP(gpio16),
+	PINCTRL_PIN_GROUP(gpio17),
+	PINCTRL_PIN_GROUP(gpio18),
+	PINCTRL_PIN_GROUP(gpio19),
+	PINCTRL_PIN_GROUP(gpio20),
+	PINCTRL_PIN_GROUP(gpio21),
+	PINCTRL_PIN_GROUP(gpio22),
+	PINCTRL_PIN_GROUP(gpio23),
+	PINCTRL_PIN_GROUP(gpio24),
+	PINCTRL_PIN_GROUP(gpio25),
+	PINCTRL_PIN_GROUP(gpio26),
+	PINCTRL_PIN_GROUP(gpio27),
+	PINCTRL_PIN_GROUP(gpio28),
+	PINCTRL_PIN_GROUP(gpio29),
+	PINCTRL_PIN_GROUP(gpio30),
+	PINCTRL_PIN_GROUP(gpio31),
+	PINCTRL_PIN_GROUP(gpio33),
+	PINCTRL_PIN_GROUP(gpio34),
+	PINCTRL_PIN_GROUP(gpio35),
+	PINCTRL_PIN_GROUP(gpio36),
+	PINCTRL_PIN_GROUP(gpio37),
+	PINCTRL_PIN_GROUP(gpio38),
+	PINCTRL_PIN_GROUP(gpio39),
+	PINCTRL_PIN_GROUP(gpio40),
+	PINCTRL_PIN_GROUP(gpio41),
+	PINCTRL_PIN_GROUP(gpio42),
+	PINCTRL_PIN_GROUP(gpio43),
+	PINCTRL_PIN_GROUP(gpio44),
+	PINCTRL_PIN_GROUP(gpio45),
+	PINCTRL_PIN_GROUP(gpio46),
+	PINCTRL_PIN_GROUP(pcie_reset0),
+	PINCTRL_PIN_GROUP(pcie_reset1),
+	PINCTRL_PIN_GROUP(pcie_reset2),
+};
+
+static const char *const pon_groups[] = { "pon" };
+static const char *const tod_1pps_groups[] = { "pon_tod_1pps", "gsw_tod_1pps" };
+static const char *const sipo_groups[] = { "sipo", "sipo_rclk" };
+static const char *const mdio_groups[] = { "mdio" };
+static const char *const uart_groups[] = { "uart2", "uart2_cts_rts", "hsuart",
+					   "hsuart_cts_rts", "uart4",
+					   "uart5" };
+static const char *const i2c_groups[] = { "i2c1" };
+static const char *const jtag_groups[] = { "jtag_udi", "jtag_dfd" };
+static const char *const pcm_groups[] = { "pcm1", "pcm2" };
+static const char *const spi_groups[] = { "spi_quad", "spi_cs1" };
+static const char *const pcm_spi_groups[] = { "pcm_spi", "pcm_spi_int",
+					      "pcm_spi_rst", "pcm_spi_cs1",
+					      "pcm_spi_cs2_p156",
+					      "pcm_spi_cs2_p128",
+					      "pcm_spi_cs3", "pcm_spi_cs4" };
+static const char *const i2s_groups[] = { "i2s" };
+static const char *const emmc_groups[] = { "emmc" };
+static const char *const pnand_groups[] = { "pnand" };
+static const char *const pcie_reset_groups[] = { "pcie_reset0", "pcie_reset1",
+						 "pcie_reset2" };
+static const char *const pwm_groups[] = { "gpio0", "gpio1",
+					  "gpio2", "gpio3",
+					  "gpio4", "gpio5",
+					  "gpio6", "gpio7",
+					  "gpio8", "gpio9",
+					  "gpio10", "gpio11",
+					  "gpio12", "gpio13",
+					  "gpio14", "gpio15",
+					  "gpio16", "gpio17",
+					  "gpio18", "gpio19",
+					  "gpio20", "gpio21",
+					  "gpio22", "gpio23",
+					  "gpio24", "gpio25",
+					  "gpio26", "gpio27",
+					  "gpio28", "gpio29",
+					  "gpio30", "gpio31",
+					  "gpio36", "gpio37",
+					  "gpio38", "gpio39",
+					  "gpio40", "gpio41",
+					  "gpio42", "gpio43",
+					  "gpio44", "gpio45",
+					  "gpio46", "gpio47" };
+static const char *const phy1_led0_groups[] = { "gpio33", "gpio34",
+						"gpio35", "gpio42" };
+static const char *const phy2_led0_groups[] = { "gpio33", "gpio34",
+						"gpio35", "gpio42" };
+static const char *const phy3_led0_groups[] = { "gpio33", "gpio34",
+						"gpio35", "gpio42" };
+static const char *const phy4_led0_groups[] = { "gpio33", "gpio34",
+						"gpio35", "gpio42" };
+static const char *const phy1_led1_groups[] = { "gpio43", "gpio44",
+						"gpio45", "gpio46" };
+static const char *const phy2_led1_groups[] = { "gpio43", "gpio44",
+						"gpio45", "gpio46" };
+static const char *const phy3_led1_groups[] = { "gpio43", "gpio44",
+						"gpio45", "gpio46" };
+static const char *const phy4_led1_groups[] = { "gpio43", "gpio44",
+						"gpio45", "gpio46" };
+
+static const struct airoha_pinctrl_func_group pon_func_group[] = {
+	{
+		.name = "pon",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_PON_MODE,
+			GPIO_PON_MODE_MASK,
+			GPIO_PON_MODE_MASK
+		},
+		.regmap_size = 1,
+	},
+};
+
+static const struct airoha_pinctrl_func_group tod_1pps_func_group[] = {
+	{
+		.name = "pon_tod_1pps",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_2ND_I2C_MODE,
+			PON_TOD_1PPS_MODE_MASK,
+			PON_TOD_1PPS_MODE_MASK
+		},
+		.regmap_size = 1,
+	}, {
+		.name = "gsw_tod_1pps",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_2ND_I2C_MODE,
+			GSW_TOD_1PPS_MODE_MASK,
+			GSW_TOD_1PPS_MODE_MASK
+		},
+		.regmap_size = 1,
+	},
+};
+
+static const struct airoha_pinctrl_func_group sipo_func_group[] = {
+	{
+		.name = "sipo",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_PON_MODE,
+			GPIO_SIPO_MODE_MASK | SIPO_RCLK_MODE_MASK,
+			GPIO_SIPO_MODE_MASK
+		},
+		.regmap_size = 1,
+	}, {
+		.name = "sipo_rclk",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_PON_MODE,
+			GPIO_SIPO_MODE_MASK | SIPO_RCLK_MODE_MASK,
+			GPIO_SIPO_MODE_MASK | SIPO_RCLK_MODE_MASK
+		},
+		.regmap_size = 1,
+	},
+};
+
+static const struct airoha_pinctrl_func_group mdio_func_group[] = {
+	{
+		.name = "mdio",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_PON_MODE,
+			GPIO_SGMII_MDIO_MODE_MASK,
+			GPIO_SGMII_MDIO_MODE_MASK
+		},
+		.regmap[1] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_2ND_I2C_MODE,
+			GPIO_MDC_IO_MASTER_MODE_MODE,
+			GPIO_MDC_IO_MASTER_MODE_MODE
+		},
+		.regmap_size = 2,
+	},
+};
+
+static const struct airoha_pinctrl_func_group uart_func_group[] = {
+	{
+		.name = "uart2",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_PON_MODE,
+			GPIO_UART2_MODE_MASK,
+			GPIO_UART2_MODE_MASK
+		},
+		.regmap_size = 1,
+	}, {
+		.name = "uart2_cts_rts",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_PON_MODE,
+			GPIO_UART2_MODE_MASK | GPIO_UART2_CTS_RTS_MODE_MASK,
+			GPIO_UART2_MODE_MASK | GPIO_UART2_CTS_RTS_MODE_MASK
+		},
+		.regmap_size = 1,
+	}, {
+		.name = "hsuart",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_PON_MODE,
+			GPIO_HSUART_MODE_MASK | GPIO_HSUART_CTS_RTS_MODE_MASK,
+			GPIO_HSUART_MODE_MASK
+		},
+		.regmap_size = 1,
+	},
+	{
+		.name = "hsuart_cts_rts",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_PON_MODE,
+			GPIO_HSUART_MODE_MASK | GPIO_HSUART_CTS_RTS_MODE_MASK,
+			GPIO_HSUART_MODE_MASK | GPIO_HSUART_CTS_RTS_MODE_MASK
+		},
+		.regmap_size = 1,
+	}, {
+		.name = "uart4",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_PON_MODE,
+			GPIO_UART4_MODE_MASK,
+			GPIO_UART4_MODE_MASK
+		},
+		.regmap_size = 1,
+	}, {
+		.name = "uart5",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_PON_MODE,
+			GPIO_UART5_MODE_MASK,
+			GPIO_UART5_MODE_MASK
+		},
+		.regmap_size = 1,
+	},
+};
+
+static const struct airoha_pinctrl_func_group i2c_func_group[] = {
+	{
+		.name = "i2c1",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_2ND_I2C_MODE,
+			GPIO_2ND_I2C_MODE_MASK,
+			GPIO_2ND_I2C_MODE_MASK
+		},
+		.regmap_size = 1,
+	},
+};
+
+static const struct airoha_pinctrl_func_group jtag_func_group[] = {
+	{
+		.name = "jtag_udi",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_NPU_UART_EN,
+			JTAG_UDI_EN_MASK,
+			JTAG_UDI_EN_MASK
+		},
+		.regmap_size = 1,
+	}, {
+		.name = "jtag_dfd",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_NPU_UART_EN,
+			JTAG_DFD_EN_MASK,
+			JTAG_DFD_EN_MASK
+		},
+		.regmap_size = 1,
+	},
+};
+
+static const struct airoha_pinctrl_func_group pcm_func_group[] = {
+	{
+		.name = "pcm1",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_SPI_CS1_MODE,
+			GPIO_PCM1_MODE_MASK,
+			GPIO_PCM1_MODE_MASK
+		},
+		.regmap_size = 1,
+	}, {
+		.name = "pcm2",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_SPI_CS1_MODE,
+			GPIO_PCM2_MODE_MASK,
+			GPIO_PCM2_MODE_MASK
+		},
+		.regmap_size = 1,
+	},
+};
+
+static const struct airoha_pinctrl_func_group spi_func_group[] = {
+	{
+		.name = "spi_quad",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_SPI_CS1_MODE,
+			GPIO_SPI_QUAD_MODE_MASK,
+			GPIO_SPI_QUAD_MODE_MASK
+		},
+		.regmap_size = 1,
+	}, {
+		.name = "spi_cs1",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_SPI_CS1_MODE,
+			GPIO_SPI_CS1_MODE_MASK,
+			GPIO_SPI_CS1_MODE_MASK
+		},
+		.regmap_size = 1,
+	}, {
+		.name = "spi_cs2",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_SPI_CS1_MODE,
+			GPIO_SPI_CS2_MODE_MASK,
+			GPIO_SPI_CS2_MODE_MASK
+		},
+		.regmap_size = 1,
+	}, {
+		.name = "spi_cs3",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_SPI_CS1_MODE,
+			GPIO_SPI_CS3_MODE_MASK,
+			GPIO_SPI_CS3_MODE_MASK
+		},
+		.regmap_size = 1,
+	}, {
+		.name = "spi_cs4",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_SPI_CS1_MODE,
+			GPIO_SPI_CS4_MODE_MASK,
+			GPIO_SPI_CS4_MODE_MASK
+		},
+		.regmap_size = 1,
+	},
+};
+
+static const struct airoha_pinctrl_func_group pcm_spi_func_group[] = {
+	{
+		.name = "pcm_spi",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_SPI_CS1_MODE,
+			GPIO_PCM_SPI_MODE_MASK,
+			GPIO_PCM_SPI_MODE_MASK
+		},
+		.regmap_size = 1,
+	}, {
+		.name = "pcm_spi_int",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_SPI_CS1_MODE,
+			GPIO_PCM_INT_MODE_MASK,
+			GPIO_PCM_INT_MODE_MASK
+		},
+		.regmap_size = 1,
+	}, {
+		.name = "pcm_spi_rst",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_SPI_CS1_MODE,
+			GPIO_PCM_RESET_MODE_MASK,
+			GPIO_PCM_RESET_MODE_MASK
+		},
+		.regmap_size = 1,
+	}, {
+		.name = "pcm_spi_cs1",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_SPI_CS1_MODE,
+			GPIO_PCM_SPI_CS1_MODE_MASK,
+			GPIO_PCM_SPI_CS1_MODE_MASK
+		},
+		.regmap_size = 1,
+	}, {
+		.name = "pcm_spi_cs2_p128",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_SPI_CS1_MODE,
+			GPIO_PCM_SPI_CS2_MODE_P128_MASK,
+			GPIO_PCM_SPI_CS2_MODE_P128_MASK
+		},
+		.regmap_size = 1,
+	}, {
+		.name = "pcm_spi_cs2_p156",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_SPI_CS1_MODE,
+			GPIO_PCM_SPI_CS2_MODE_P156_MASK,
+			GPIO_PCM_SPI_CS2_MODE_P156_MASK
+		},
+		.regmap_size = 1,
+	}, {
+		.name = "pcm_spi_cs3",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_SPI_CS1_MODE,
+			GPIO_PCM_SPI_CS3_MODE_MASK,
+			GPIO_PCM_SPI_CS3_MODE_MASK
+		},
+		.regmap_size = 1,
+	}, {
+		.name = "pcm_spi_cs4",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_SPI_CS1_MODE,
+			GPIO_PCM_SPI_CS4_MODE_MASK,
+			GPIO_PCM_SPI_CS4_MODE_MASK
+		},
+		.regmap_size = 1,
+	},
+};
+
+static const struct airoha_pinctrl_func_group i2s_func_group[] = {
+	{
+		.name = "i2s",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_2ND_I2C_MODE,
+			GPIO_I2S_MODE_MASK,
+			GPIO_I2S_MODE_MASK
+		},
+		.regmap_size = 1,
+	},
+};
+
+static const struct airoha_pinctrl_func_group emmc_func_group[] = {
+	{
+		.name = "emmc",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_PON_MODE,
+			GPIO_EMMC_MODE_MASK,
+			GPIO_EMMC_MODE_MASK
+		},
+		.regmap_size = 1,
+	},
+};
+
+static const struct airoha_pinctrl_func_group pnand_func_group[] = {
+	{
+		.name = "pnand",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_PON_MODE,
+			GPIO_PARALLEL_NAND_MODE_MASK,
+			GPIO_PARALLEL_NAND_MODE_MASK
+		},
+		.regmap_size = 1,
+	},
+};
+
+static const struct airoha_pinctrl_func_group pcie_reset_func_group[] = {
+	{
+		.name = "pcie_reset0",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_PON_MODE,
+			GPIO_PCIE_RESET0_MASK,
+			GPIO_PCIE_RESET0_MASK
+		},
+		.regmap_size = 1,
+	}, {
+		.name = "pcie_reset1",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_PON_MODE,
+			GPIO_PCIE_RESET1_MASK,
+			GPIO_PCIE_RESET1_MASK
+		},
+		.regmap_size = 1,
+	}, {
+		.name = "pcie_reset2",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_PON_MODE,
+			GPIO_PCIE_RESET2_MASK,
+			GPIO_PCIE_RESET2_MASK
+		},
+		.regmap_size = 1,
+	},
+};
+
+/* PWM */
+static const struct airoha_pinctrl_func_group pwm_func_group[] = {
+	{
+		.name = "gpio0",
+		.regmap[0] = {
+			AIROHA_FUNC_PWM_MUX,
+			REG_GPIO_FLASH_MODE_CFG,
+			GPIO0_FLASH_MODE_CFG,
+			GPIO0_FLASH_MODE_CFG
+		},
+		.regmap_size = 1,
+	}, {
+		.name = "gpio1",
+		.regmap[0] = {
+			AIROHA_FUNC_PWM_MUX,
+			REG_GPIO_FLASH_MODE_CFG,
+			GPIO1_FLASH_MODE_CFG,
+			GPIO1_FLASH_MODE_CFG
+		},
+		.regmap_size = 1,
+	}, {
+		.name = "gpio2",
+		.regmap[0] = {
+			AIROHA_FUNC_PWM_MUX,
+			REG_GPIO_FLASH_MODE_CFG,
+			GPIO2_FLASH_MODE_CFG,
+			GPIO2_FLASH_MODE_CFG
+		},
+		.regmap_size = 1,
+	}, {
+		.name = "gpio3",
+		.regmap[0] = {
+			AIROHA_FUNC_PWM_MUX,
+			REG_GPIO_FLASH_MODE_CFG,
+			GPIO3_FLASH_MODE_CFG,
+			GPIO3_FLASH_MODE_CFG
+		},
+		.regmap_size = 1,
+	}, {
+		.name = "gpio4",
+		.regmap[0] = {
+			AIROHA_FUNC_PWM_MUX,
+			REG_GPIO_FLASH_MODE_CFG,
+			GPIO4_FLASH_MODE_CFG,
+			GPIO4_FLASH_MODE_CFG
+		},
+		.regmap_size = 1,
+	}, {
+		.name = "gpio5",
+		.regmap[0] = {
+			AIROHA_FUNC_PWM_MUX,
+			REG_GPIO_FLASH_MODE_CFG,
+			GPIO5_FLASH_MODE_CFG,
+			GPIO5_FLASH_MODE_CFG
+		},
+		.regmap_size = 1,
+	}, {
+		.name = "gpio6",
+		.regmap[0] = {
+			AIROHA_FUNC_PWM_MUX,
+			REG_GPIO_FLASH_MODE_CFG,
+			GPIO6_FLASH_MODE_CFG,
+			GPIO6_FLASH_MODE_CFG
+		},
+		.regmap_size = 1,
+	}, {
+		.name = "gpio7",
+		.regmap[0] = {
+			AIROHA_FUNC_PWM_MUX,
+			REG_GPIO_FLASH_MODE_CFG,
+			GPIO7_FLASH_MODE_CFG,
+			GPIO7_FLASH_MODE_CFG
+		},
+		.regmap_size = 1,
+	}, {
+		.name = "gpio8",
+		.regmap[0] = {
+			AIROHA_FUNC_PWM_MUX,
+			REG_GPIO_FLASH_MODE_CFG,
+			GPIO8_FLASH_MODE_CFG,
+			GPIO8_FLASH_MODE_CFG
+		},
+		.regmap_size = 1,
+	}, {
+		.name = "gpio9",
+		.regmap[0] = {
+			AIROHA_FUNC_PWM_MUX,
+			REG_GPIO_FLASH_MODE_CFG,
+			GPIO9_FLASH_MODE_CFG,
+			GPIO9_FLASH_MODE_CFG
+		},
+		.regmap_size = 1,
+	}, {
+		.name = "gpio10",
+		.regmap[0] = {
+			AIROHA_FUNC_PWM_MUX,
+			REG_GPIO_FLASH_MODE_CFG,
+			GPIO10_FLASH_MODE_CFG,
+			GPIO10_FLASH_MODE_CFG
+		},
+		.regmap_size = 1,
+	}, {
+		.name = "gpio11",
+		.regmap[0] = {
+			AIROHA_FUNC_PWM_MUX,
+			REG_GPIO_FLASH_MODE_CFG,
+			GPIO11_FLASH_MODE_CFG,
+			GPIO11_FLASH_MODE_CFG
+		},
+		.regmap_size = 1,
+	}, {
+		.name = "gpio12",
+		.regmap[0] = {
+			AIROHA_FUNC_PWM_MUX,
+			REG_GPIO_FLASH_MODE_CFG,
+			GPIO12_FLASH_MODE_CFG,
+			GPIO12_FLASH_MODE_CFG
+		},
+		.regmap_size = 1,
+	}, {
+		.name = "gpio13",
+		.regmap[0] = {
+			AIROHA_FUNC_PWM_MUX,
+			REG_GPIO_FLASH_MODE_CFG,
+			GPIO13_FLASH_MODE_CFG,
+			GPIO13_FLASH_MODE_CFG
+		},
+		.regmap_size = 1,
+	}, {
+		.name = "gpio14",
+		.regmap[0] = {
+			AIROHA_FUNC_PWM_MUX,
+			REG_GPIO_FLASH_MODE_CFG,
+			GPIO14_FLASH_MODE_CFG,
+			GPIO14_FLASH_MODE_CFG
+		},
+		.regmap_size = 1,
+	}, {
+		.name = "gpio15",
+		.regmap[0] = {
+			AIROHA_FUNC_PWM_MUX,
+			REG_GPIO_FLASH_MODE_CFG,
+			GPIO15_FLASH_MODE_CFG,
+			GPIO15_FLASH_MODE_CFG
+		},
+		.regmap_size = 1,
+	}, {
+		.name = "gpio16",
+		.regmap[0] = {
+			AIROHA_FUNC_PWM_EXT_MUX,
+			REG_GPIO_FLASH_MODE_CFG_EXT,
+			GPIO16_FLASH_MODE_CFG,
+			GPIO16_FLASH_MODE_CFG
+		},
+		.regmap_size = 1,
+	}, {
+		.name = "gpio17",
+		.regmap[0] = {
+			AIROHA_FUNC_PWM_EXT_MUX,
+			REG_GPIO_FLASH_MODE_CFG_EXT,
+			GPIO17_FLASH_MODE_CFG,
+			GPIO17_FLASH_MODE_CFG
+		},
+		.regmap_size = 1,
+	}, {
+		.name = "gpio18",
+		.regmap[0] = {
+			AIROHA_FUNC_PWM_EXT_MUX,
+			REG_GPIO_FLASH_MODE_CFG_EXT,
+			GPIO18_FLASH_MODE_CFG,
+			GPIO18_FLASH_MODE_CFG
+		},
+		.regmap_size = 1,
+	}, {
+		.name = "gpio19",
+		.regmap[0] = {
+			AIROHA_FUNC_PWM_EXT_MUX,
+			REG_GPIO_FLASH_MODE_CFG_EXT,
+			GPIO19_FLASH_MODE_CFG,
+			GPIO19_FLASH_MODE_CFG
+		},
+		.regmap_size = 1,
+	}, {
+		.name = "gpio20",
+		.regmap[0] = {
+			AIROHA_FUNC_PWM_EXT_MUX,
+			REG_GPIO_FLASH_MODE_CFG_EXT,
+			GPIO20_FLASH_MODE_CFG,
+			GPIO20_FLASH_MODE_CFG
+		},
+		.regmap_size = 1,
+	}, {
+		.name = "gpio21",
+		.regmap[0] = {
+			AIROHA_FUNC_PWM_EXT_MUX,
+			REG_GPIO_FLASH_MODE_CFG_EXT,
+			GPIO21_FLASH_MODE_CFG,
+			GPIO21_FLASH_MODE_CFG
+		},
+		.regmap_size = 1,
+	}, {
+		.name = "gpio22",
+		.regmap[0] = {
+			AIROHA_FUNC_PWM_EXT_MUX,
+			REG_GPIO_FLASH_MODE_CFG_EXT,
+			GPIO22_FLASH_MODE_CFG,
+			GPIO22_FLASH_MODE_CFG
+		},
+		.regmap_size = 1,
+	}, {
+		.name = "gpio23",
+		.regmap[0] = {
+			AIROHA_FUNC_PWM_EXT_MUX,
+			REG_GPIO_FLASH_MODE_CFG_EXT,
+			GPIO23_FLASH_MODE_CFG,
+			GPIO23_FLASH_MODE_CFG
+		},
+		.regmap_size = 1,
+	}, {
+		.name = "gpio24",
+		.regmap[0] = {
+			AIROHA_FUNC_PWM_EXT_MUX,
+			REG_GPIO_FLASH_MODE_CFG_EXT,
+			GPIO24_FLASH_MODE_CFG,
+			GPIO24_FLASH_MODE_CFG
+		},
+		.regmap_size = 1,
+	}, {
+		.name = "gpio25",
+		.regmap[0] = {
+			AIROHA_FUNC_PWM_EXT_MUX,
+			REG_GPIO_FLASH_MODE_CFG_EXT,
+			GPIO25_FLASH_MODE_CFG,
+			GPIO25_FLASH_MODE_CFG
+		},
+		.regmap_size = 1,
+	}, {
+		.name = "gpio26",
+		.regmap[0] = {
+			AIROHA_FUNC_PWM_EXT_MUX,
+			REG_GPIO_FLASH_MODE_CFG_EXT,
+			GPIO26_FLASH_MODE_CFG,
+			GPIO26_FLASH_MODE_CFG
+		},
+		.regmap_size = 1,
+	}, {
+		.name = "gpio27",
+		.regmap[0] = {
+			AIROHA_FUNC_PWM_EXT_MUX,
+			REG_GPIO_FLASH_MODE_CFG_EXT,
+			GPIO27_FLASH_MODE_CFG,
+			GPIO27_FLASH_MODE_CFG
+		},
+		.regmap_size = 1,
+	}, {
+		.name = "gpio28",
+		.regmap[0] = {
+			AIROHA_FUNC_PWM_EXT_MUX,
+			REG_GPIO_FLASH_MODE_CFG_EXT,
+			GPIO28_FLASH_MODE_CFG,
+			GPIO28_FLASH_MODE_CFG
+		},
+		.regmap_size = 1,
+	}, {
+		.name = "gpio29",
+		.regmap[0] = {
+			AIROHA_FUNC_PWM_EXT_MUX,
+			REG_GPIO_FLASH_MODE_CFG_EXT,
+			GPIO29_FLASH_MODE_CFG,
+			GPIO29_FLASH_MODE_CFG
+		},
+		.regmap_size = 1,
+	}, {
+		.name = "gpio30",
+		.regmap[0] = {
+			AIROHA_FUNC_PWM_EXT_MUX,
+			REG_GPIO_FLASH_MODE_CFG_EXT,
+			GPIO30_FLASH_MODE_CFG,
+			GPIO30_FLASH_MODE_CFG
+		},
+		.regmap_size = 1,
+	}, {
+		.name = "gpio31",
+		.regmap[0] = {
+			AIROHA_FUNC_PWM_EXT_MUX,
+			REG_GPIO_FLASH_MODE_CFG_EXT,
+			GPIO31_FLASH_MODE_CFG,
+			GPIO31_FLASH_MODE_CFG
+		},
+		.regmap_size = 1,
+	}, {
+		.name = "gpio36",
+		.regmap[0] = {
+			AIROHA_FUNC_PWM_EXT_MUX,
+			REG_GPIO_FLASH_MODE_CFG_EXT,
+			GPIO36_FLASH_MODE_CFG,
+			GPIO36_FLASH_MODE_CFG
+		},
+		.regmap_size = 1,
+	}, {
+		.name = "gpio37",
+		.regmap[0] = {
+			AIROHA_FUNC_PWM_EXT_MUX,
+			REG_GPIO_FLASH_MODE_CFG_EXT,
+			GPIO37_FLASH_MODE_CFG,
+			GPIO37_FLASH_MODE_CFG
+		},
+		.regmap_size = 1,
+	}, {
+		.name = "gpio38",
+		.regmap[0] = {
+			AIROHA_FUNC_PWM_EXT_MUX,
+			REG_GPIO_FLASH_MODE_CFG_EXT,
+			GPIO38_FLASH_MODE_CFG,
+			GPIO38_FLASH_MODE_CFG
+		},
+		.regmap_size = 1,
+	}, {
+		.name = "gpio39",
+		.regmap[0] = {
+			AIROHA_FUNC_PWM_EXT_MUX,
+			REG_GPIO_FLASH_MODE_CFG_EXT,
+			GPIO39_FLASH_MODE_CFG,
+			GPIO39_FLASH_MODE_CFG
+		},
+		.regmap_size = 1,
+	}, {
+		.name = "gpio40",
+		.regmap[0] = {
+			AIROHA_FUNC_PWM_EXT_MUX,
+			REG_GPIO_FLASH_MODE_CFG_EXT,
+			GPIO40_FLASH_MODE_CFG,
+			GPIO40_FLASH_MODE_CFG
+		},
+		.regmap_size = 1,
+	}, {
+		.name = "gpio41",
+		.regmap[0] = {
+			AIROHA_FUNC_PWM_EXT_MUX,
+			REG_GPIO_FLASH_MODE_CFG_EXT,
+			GPIO41_FLASH_MODE_CFG,
+			GPIO41_FLASH_MODE_CFG
+		},
+		.regmap_size = 1,
+	}, {
+		.name = "gpio42",
+		.regmap[0] = {
+			AIROHA_FUNC_PWM_EXT_MUX,
+			REG_GPIO_FLASH_MODE_CFG_EXT,
+			GPIO42_FLASH_MODE_CFG,
+			GPIO42_FLASH_MODE_CFG
+		},
+		.regmap_size = 1,
+	}, {
+		.name = "gpio43",
+		.regmap[0] = {
+			AIROHA_FUNC_PWM_EXT_MUX,
+			REG_GPIO_FLASH_MODE_CFG_EXT,
+			GPIO43_FLASH_MODE_CFG,
+			GPIO43_FLASH_MODE_CFG
+		},
+		.regmap_size = 1,
+	}, {
+		.name = "gpio44",
+		.regmap[0] = {
+			AIROHA_FUNC_PWM_EXT_MUX,
+			REG_GPIO_FLASH_MODE_CFG_EXT,
+			GPIO44_FLASH_MODE_CFG,
+			GPIO44_FLASH_MODE_CFG
+		},
+		.regmap_size = 1,
+	}, {
+		.name = "gpio45",
+		.regmap[0] = {
+			AIROHA_FUNC_PWM_EXT_MUX,
+			REG_GPIO_FLASH_MODE_CFG_EXT,
+			GPIO45_FLASH_MODE_CFG,
+			GPIO45_FLASH_MODE_CFG
+		},
+		.regmap_size = 1,
+	}, {
+		.name = "gpio46",
+		.regmap[0] = {
+			AIROHA_FUNC_PWM_EXT_MUX,
+			REG_GPIO_FLASH_MODE_CFG_EXT,
+			GPIO46_FLASH_MODE_CFG,
+			GPIO46_FLASH_MODE_CFG
+		},
+		.regmap_size = 1,
+	}, {
+		.name = "gpio47",
+		.regmap[0] = {
+			AIROHA_FUNC_PWM_EXT_MUX,
+			REG_GPIO_FLASH_MODE_CFG_EXT,
+			GPIO47_FLASH_MODE_CFG,
+			GPIO47_FLASH_MODE_CFG
+		},
+		.regmap_size = 1,
+	},
+};
+
+static const struct airoha_pinctrl_func_group phy1_led0_func_group[] = {
+	{
+		.name = "gpio33",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_2ND_I2C_MODE,
+			GPIO_LAN0_LED0_MODE_MASK,
+			GPIO_LAN0_LED0_MODE_MASK
+		},
+		.regmap[1] = {
+			AIROHA_FUNC_LED_MUX,
+			REG_LAN_LED0_MAPPING,
+			LAN1_LED_MAPPING_MASK,
+			LAN1_PHY1_LED_MAP
+		},
+		.regmap_size = 2,
+	}, {
+		.name = "gpio34",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_2ND_I2C_MODE,
+			GPIO_LAN1_LED0_MODE_MASK,
+			GPIO_LAN1_LED0_MODE_MASK
+		},
+		.regmap[1] = {
+			AIROHA_FUNC_LED_MUX,
+			REG_LAN_LED0_MAPPING,
+			LAN2_LED_MAPPING_MASK,
+			LAN2_PHY1_LED_MAP
+		},
+		.regmap_size = 2,
+	}, {
+		.name = "gpio35",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_2ND_I2C_MODE,
+			GPIO_LAN2_LED0_MODE_MASK,
+			GPIO_LAN2_LED0_MODE_MASK
+		},
+		.regmap[1] = {
+			AIROHA_FUNC_LED_MUX,
+			REG_LAN_LED0_MAPPING,
+			LAN3_LED_MAPPING_MASK,
+			LAN3_PHY1_LED_MAP
+		},
+		.regmap_size = 2,
+	}, {
+		.name = "gpio42",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_2ND_I2C_MODE,
+			GPIO_LAN3_LED0_MODE_MASK,
+			GPIO_LAN3_LED0_MODE_MASK
+		},
+		.regmap[1] = {
+			AIROHA_FUNC_LED_MUX,
+			REG_LAN_LED0_MAPPING,
+			LAN4_LED_MAPPING_MASK,
+			LAN4_PHY1_LED_MAP
+		},
+		.regmap_size = 2,
+	},
+};
+
+static const struct airoha_pinctrl_func_group phy2_led0_func_group[] = {
+	{
+		.name = "gpio33",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_2ND_I2C_MODE,
+			GPIO_LAN0_LED0_MODE_MASK,
+			GPIO_LAN0_LED0_MODE_MASK
+		},
+		.regmap[1] = {
+			AIROHA_FUNC_LED_MUX,
+			REG_LAN_LED0_MAPPING,
+			LAN1_LED_MAPPING_MASK,
+			LAN1_PHY2_LED_MAP
+		},
+		.regmap_size = 2,
+	}, {
+		.name = "gpio34",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_2ND_I2C_MODE,
+			GPIO_LAN1_LED0_MODE_MASK,
+			GPIO_LAN1_LED0_MODE_MASK
+		},
+		.regmap[1] = {
+			AIROHA_FUNC_LED_MUX,
+			REG_LAN_LED0_MAPPING,
+			LAN2_LED_MAPPING_MASK,
+			LAN2_PHY2_LED_MAP
+		},
+		.regmap_size = 2,
+	}, {
+		.name = "gpio35",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_2ND_I2C_MODE,
+			GPIO_LAN2_LED0_MODE_MASK,
+			GPIO_LAN2_LED0_MODE_MASK
+		},
+		.regmap[1] = {
+			AIROHA_FUNC_LED_MUX,
+			REG_LAN_LED0_MAPPING,
+			LAN3_LED_MAPPING_MASK,
+			LAN3_PHY2_LED_MAP
+		},
+		.regmap_size = 2,
+	}, {
+		.name = "gpio42",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_2ND_I2C_MODE,
+			GPIO_LAN3_LED0_MODE_MASK,
+			GPIO_LAN3_LED0_MODE_MASK
+		},
+		.regmap[1] = {
+			AIROHA_FUNC_LED_MUX,
+			REG_LAN_LED0_MAPPING,
+			LAN4_LED_MAPPING_MASK,
+			LAN4_PHY2_LED_MAP
+		},
+		.regmap_size = 2,
+	},
+};
+
+static const struct airoha_pinctrl_func_group phy3_led0_func_group[] = {
+	{
+		.name = "gpio33",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_2ND_I2C_MODE,
+			GPIO_LAN0_LED0_MODE_MASK,
+			GPIO_LAN0_LED0_MODE_MASK
+		},
+		.regmap[1] = {
+			AIROHA_FUNC_LED_MUX,
+			REG_LAN_LED0_MAPPING,
+			LAN1_LED_MAPPING_MASK,
+			LAN1_PHY3_LED_MAP
+		},
+		.regmap_size = 2,
+	}, {
+		.name = "gpio34",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_2ND_I2C_MODE,
+			GPIO_LAN1_LED0_MODE_MASK,
+			GPIO_LAN1_LED0_MODE_MASK
+		},
+		.regmap[1] = {
+			AIROHA_FUNC_LED_MUX,
+			REG_LAN_LED0_MAPPING,
+			LAN2_LED_MAPPING_MASK,
+			LAN2_PHY3_LED_MAP
+		},
+		.regmap_size = 2,
+	}, {
+		.name = "gpio35",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_2ND_I2C_MODE,
+			GPIO_LAN2_LED0_MODE_MASK,
+			GPIO_LAN2_LED0_MODE_MASK
+		},
+		.regmap[1] = {
+			AIROHA_FUNC_LED_MUX,
+			REG_LAN_LED0_MAPPING,
+			LAN3_LED_MAPPING_MASK,
+			LAN3_PHY3_LED_MAP
+		},
+		.regmap_size = 2,
+	}, {
+		.name = "gpio42",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_2ND_I2C_MODE,
+			GPIO_LAN3_LED0_MODE_MASK,
+			GPIO_LAN3_LED0_MODE_MASK
+		},
+		.regmap[1] = {
+			AIROHA_FUNC_LED_MUX,
+			REG_LAN_LED0_MAPPING,
+			LAN4_LED_MAPPING_MASK,
+			LAN4_PHY3_LED_MAP
+		},
+		.regmap_size = 2,
+	},
+};
+
+static const struct airoha_pinctrl_func_group phy4_led0_func_group[] = {
+	{
+		.name = "gpio33",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_2ND_I2C_MODE,
+			GPIO_LAN0_LED0_MODE_MASK,
+			GPIO_LAN0_LED0_MODE_MASK
+		},
+		.regmap[1] = {
+			AIROHA_FUNC_LED_MUX,
+			REG_LAN_LED0_MAPPING,
+			LAN1_LED_MAPPING_MASK,
+			LAN1_PHY4_LED_MAP
+		},
+		.regmap_size = 2,
+	}, {
+		.name = "gpio34",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_2ND_I2C_MODE,
+			GPIO_LAN1_LED0_MODE_MASK,
+			GPIO_LAN1_LED0_MODE_MASK
+		},
+		.regmap[1] = {
+			AIROHA_FUNC_LED_MUX,
+			REG_LAN_LED0_MAPPING,
+			LAN2_LED_MAPPING_MASK,
+			LAN2_PHY4_LED_MAP
+		},
+		.regmap_size = 2,
+	}, {
+		.name = "gpio35",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_2ND_I2C_MODE,
+			GPIO_LAN2_LED0_MODE_MASK,
+			GPIO_LAN2_LED0_MODE_MASK
+		},
+		.regmap[1] = {
+			AIROHA_FUNC_LED_MUX,
+			REG_LAN_LED0_MAPPING,
+			LAN3_LED_MAPPING_MASK,
+			LAN3_PHY4_LED_MAP
+		},
+		.regmap_size = 2,
+	}, {
+		.name = "gpio42",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_2ND_I2C_MODE,
+			GPIO_LAN3_LED0_MODE_MASK,
+			GPIO_LAN3_LED0_MODE_MASK
+		},
+		.regmap[1] = {
+			AIROHA_FUNC_LED_MUX,
+			REG_LAN_LED0_MAPPING,
+			LAN4_LED_MAPPING_MASK,
+			LAN4_PHY4_LED_MAP
+		},
+		.regmap_size = 2,
+	},
+};
+
+static const struct airoha_pinctrl_func_group phy1_led1_func_group[] = {
+	{
+		.name = "gpio43",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_2ND_I2C_MODE,
+			GPIO_LAN0_LED1_MODE_MASK,
+			GPIO_LAN0_LED1_MODE_MASK
+		},
+		.regmap[1] = {
+			AIROHA_FUNC_LED_MUX,
+			REG_LAN_LED1_MAPPING,
+			LAN1_LED_MAPPING_MASK,
+			LAN1_PHY1_LED_MAP
+		},
+		.regmap_size = 2,
+	}, {
+		.name = "gpio44",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_2ND_I2C_MODE,
+			GPIO_LAN1_LED1_MODE_MASK,
+			GPIO_LAN1_LED1_MODE_MASK
+		},
+		.regmap[1] = {
+			AIROHA_FUNC_LED_MUX,
+			REG_LAN_LED1_MAPPING,
+			LAN2_LED_MAPPING_MASK,
+			LAN2_PHY1_LED_MAP
+		},
+		.regmap_size = 2,
+	}, {
+		.name = "gpio45",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_2ND_I2C_MODE,
+			GPIO_LAN2_LED1_MODE_MASK,
+			GPIO_LAN2_LED1_MODE_MASK
+		},
+		.regmap[1] = {
+			AIROHA_FUNC_LED_MUX,
+			REG_LAN_LED1_MAPPING,
+			LAN3_LED_MAPPING_MASK,
+			LAN3_PHY1_LED_MAP
+		},
+		.regmap_size = 2,
+	}, {
+		.name = "gpio46",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_2ND_I2C_MODE,
+			GPIO_LAN3_LED0_MODE_MASK,
+			GPIO_LAN3_LED0_MODE_MASK
+		},
+		.regmap[1] = {
+			AIROHA_FUNC_LED_MUX,
+			REG_LAN_LED1_MAPPING,
+			LAN4_LED_MAPPING_MASK,
+			LAN4_PHY1_LED_MAP
+		},
+		.regmap_size = 2,
+	},
+};
+
+static const struct airoha_pinctrl_func_group phy2_led1_func_group[] = {
+	{
+		.name = "gpio43",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_2ND_I2C_MODE,
+			GPIO_LAN0_LED1_MODE_MASK,
+			GPIO_LAN0_LED1_MODE_MASK
+		},
+		.regmap[1] = {
+			AIROHA_FUNC_LED_MUX,
+			REG_LAN_LED1_MAPPING,
+			LAN1_LED_MAPPING_MASK,
+			LAN1_PHY2_LED_MAP
+		},
+		.regmap_size = 2,
+	}, {
+		.name = "gpio44",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_2ND_I2C_MODE,
+			GPIO_LAN1_LED1_MODE_MASK,
+			GPIO_LAN1_LED1_MODE_MASK
+		},
+		.regmap[1] = {
+			AIROHA_FUNC_LED_MUX,
+			REG_LAN_LED1_MAPPING,
+			LAN2_LED_MAPPING_MASK,
+			LAN2_PHY2_LED_MAP
+		},
+		.regmap_size = 2,
+	}, {
+		.name = "gpio45",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_2ND_I2C_MODE,
+			GPIO_LAN2_LED1_MODE_MASK,
+			GPIO_LAN2_LED1_MODE_MASK
+		},
+		.regmap[1] = {
+			AIROHA_FUNC_LED_MUX,
+			REG_LAN_LED1_MAPPING,
+			LAN3_LED_MAPPING_MASK,
+			LAN3_PHY2_LED_MAP
+		},
+		.regmap_size = 2,
+	}, {
+		.name = "gpio46",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_2ND_I2C_MODE,
+			GPIO_LAN3_LED0_MODE_MASK,
+			GPIO_LAN3_LED0_MODE_MASK
+		},
+		.regmap[1] = {
+			AIROHA_FUNC_LED_MUX,
+			REG_LAN_LED1_MAPPING,
+			LAN4_LED_MAPPING_MASK,
+			LAN4_PHY2_LED_MAP
+		},
+		.regmap_size = 2,
+	},
+};
+
+static const struct airoha_pinctrl_func_group phy3_led1_func_group[] = {
+	{
+		.name = "gpio43",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_2ND_I2C_MODE,
+			GPIO_LAN0_LED1_MODE_MASK,
+			GPIO_LAN0_LED1_MODE_MASK
+		},
+		.regmap[1] = {
+			AIROHA_FUNC_LED_MUX,
+			REG_LAN_LED1_MAPPING,
+			LAN1_LED_MAPPING_MASK,
+			LAN1_PHY3_LED_MAP
+		},
+		.regmap_size = 2,
+	}, {
+		.name = "gpio44",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_2ND_I2C_MODE,
+			GPIO_LAN1_LED1_MODE_MASK,
+			GPIO_LAN1_LED1_MODE_MASK
+		},
+		.regmap[1] = {
+			AIROHA_FUNC_LED_MUX,
+			REG_LAN_LED1_MAPPING,
+			LAN2_LED_MAPPING_MASK,
+			LAN2_PHY3_LED_MAP
+		},
+		.regmap_size = 2,
+	}, {
+		.name = "gpio45",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_2ND_I2C_MODE,
+			GPIO_LAN2_LED1_MODE_MASK,
+			GPIO_LAN2_LED1_MODE_MASK
+		},
+		.regmap[1] = {
+			AIROHA_FUNC_LED_MUX,
+			REG_LAN_LED1_MAPPING,
+			LAN3_LED_MAPPING_MASK,
+			LAN3_PHY3_LED_MAP
+		},
+		.regmap_size = 2,
+	}, {
+		.name = "gpio46",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_2ND_I2C_MODE,
+			GPIO_LAN3_LED0_MODE_MASK,
+			GPIO_LAN3_LED0_MODE_MASK
+		},
+		.regmap[1] = {
+			AIROHA_FUNC_LED_MUX,
+			REG_LAN_LED1_MAPPING,
+			LAN4_LED_MAPPING_MASK,
+			LAN4_PHY3_LED_MAP
+		},
+		.regmap_size = 2,
+	},
+};
+
+static const struct airoha_pinctrl_func_group phy4_led1_func_group[] = {
+	{
+		.name = "gpio43",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_2ND_I2C_MODE,
+			GPIO_LAN0_LED1_MODE_MASK,
+			GPIO_LAN0_LED1_MODE_MASK
+		},
+		.regmap[1] = {
+			AIROHA_FUNC_LED_MUX,
+			REG_LAN_LED1_MAPPING,
+			LAN1_LED_MAPPING_MASK,
+			LAN1_PHY4_LED_MAP
+		},
+		.regmap_size = 2,
+	}, {
+		.name = "gpio44",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_2ND_I2C_MODE,
+			GPIO_LAN1_LED1_MODE_MASK,
+			GPIO_LAN1_LED1_MODE_MASK
+		},
+		.regmap[1] = {
+			AIROHA_FUNC_LED_MUX,
+			REG_LAN_LED1_MAPPING,
+			LAN2_LED_MAPPING_MASK,
+			LAN2_PHY4_LED_MAP
+		},
+		.regmap_size = 2,
+	}, {
+		.name = "gpio45",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_2ND_I2C_MODE,
+			GPIO_LAN2_LED1_MODE_MASK,
+			GPIO_LAN2_LED1_MODE_MASK
+		},
+		.regmap[1] = {
+			AIROHA_FUNC_LED_MUX,
+			REG_LAN_LED1_MAPPING,
+			LAN3_LED_MAPPING_MASK,
+			LAN3_PHY4_LED_MAP
+		},
+		.regmap_size = 2,
+	}, {
+		.name = "gpio46",
+		.regmap[0] = {
+			AIROHA_FUNC_MUX,
+			REG_GPIO_2ND_I2C_MODE,
+			GPIO_LAN3_LED0_MODE_MASK,
+			GPIO_LAN3_LED0_MODE_MASK
+		},
+		.regmap[1] = {
+			AIROHA_FUNC_LED_MUX,
+			REG_LAN_LED1_MAPPING,
+			LAN4_LED_MAPPING_MASK,
+			LAN4_PHY4_LED_MAP
+		},
+		.regmap_size = 2,
+	},
+};
+
+static const struct airoha_pinctrl_func airoha_pinctrl_funcs[] = {
+	PINCTRL_FUNC_DESC(pon),
+	PINCTRL_FUNC_DESC(tod_1pps),
+	PINCTRL_FUNC_DESC(sipo),
+	PINCTRL_FUNC_DESC(mdio),
+	PINCTRL_FUNC_DESC(uart),
+	PINCTRL_FUNC_DESC(i2c),
+	PINCTRL_FUNC_DESC(jtag),
+	PINCTRL_FUNC_DESC(pcm),
+	PINCTRL_FUNC_DESC(spi),
+	PINCTRL_FUNC_DESC(pcm_spi),
+	PINCTRL_FUNC_DESC(i2s),
+	PINCTRL_FUNC_DESC(emmc),
+	PINCTRL_FUNC_DESC(pnand),
+	PINCTRL_FUNC_DESC(pcie_reset),
+	PINCTRL_FUNC_DESC(pwm),
+	PINCTRL_FUNC_DESC(phy1_led0),
+	PINCTRL_FUNC_DESC(phy2_led0),
+	PINCTRL_FUNC_DESC(phy3_led0),
+	PINCTRL_FUNC_DESC(phy4_led0),
+	PINCTRL_FUNC_DESC(phy1_led1),
+	PINCTRL_FUNC_DESC(phy2_led1),
+	PINCTRL_FUNC_DESC(phy3_led1),
+	PINCTRL_FUNC_DESC(phy4_led1),
+};
+
+static const struct airoha_pinctrl_conf airoha_pinctrl_pullup_conf[] = {
+	PINCTRL_CONF_DESC(0, REG_I2C_SDA_PU, UART1_TXD_PU_MASK),
+	PINCTRL_CONF_DESC(1, REG_I2C_SDA_PU, UART1_RXD_PU_MASK),
+	PINCTRL_CONF_DESC(2, REG_I2C_SDA_PU, I2C_SDA_PU_MASK),
+	PINCTRL_CONF_DESC(3, REG_I2C_SDA_PU, I2C_SCL_PU_MASK),
+	PINCTRL_CONF_DESC(4, REG_I2C_SDA_PU, SPI_CS0_PU_MASK),
+	PINCTRL_CONF_DESC(5, REG_I2C_SDA_PU, SPI_CLK_PU_MASK),
+	PINCTRL_CONF_DESC(6, REG_I2C_SDA_PU, SPI_MOSI_PU_MASK),
+	PINCTRL_CONF_DESC(7, REG_I2C_SDA_PU, SPI_MISO_PU_MASK),
+	PINCTRL_CONF_DESC(13, REG_GPIO_L_PU, BIT(0)),
+	PINCTRL_CONF_DESC(14, REG_GPIO_L_PU, BIT(1)),
+	PINCTRL_CONF_DESC(15, REG_GPIO_L_PU, BIT(2)),
+	PINCTRL_CONF_DESC(16, REG_GPIO_L_PU, BIT(3)),
+	PINCTRL_CONF_DESC(17, REG_GPIO_L_PU, BIT(4)),
+	PINCTRL_CONF_DESC(18, REG_GPIO_L_PU, BIT(5)),
+	PINCTRL_CONF_DESC(19, REG_GPIO_L_PU, BIT(6)),
+	PINCTRL_CONF_DESC(20, REG_GPIO_L_PU, BIT(7)),
+	PINCTRL_CONF_DESC(21, REG_GPIO_L_PU, BIT(8)),
+	PINCTRL_CONF_DESC(22, REG_GPIO_L_PU, BIT(9)),
+	PINCTRL_CONF_DESC(23, REG_GPIO_L_PU, BIT(10)),
+	PINCTRL_CONF_DESC(24, REG_GPIO_L_PU, BIT(11)),
+	PINCTRL_CONF_DESC(25, REG_GPIO_L_PU, BIT(12)),
+	PINCTRL_CONF_DESC(26, REG_GPIO_L_PU, BIT(13)),
+	PINCTRL_CONF_DESC(27, REG_GPIO_L_PU, BIT(14)),
+	PINCTRL_CONF_DESC(28, REG_GPIO_L_PU, BIT(15)),
+	PINCTRL_CONF_DESC(29, REG_GPIO_L_PU, BIT(16)),
+	PINCTRL_CONF_DESC(30, REG_GPIO_L_PU, BIT(17)),
+	PINCTRL_CONF_DESC(31, REG_GPIO_L_PU, BIT(18)),
+	PINCTRL_CONF_DESC(32, REG_GPIO_L_PU, BIT(18)),
+	PINCTRL_CONF_DESC(33, REG_GPIO_L_PU, BIT(20)),
+	PINCTRL_CONF_DESC(34, REG_GPIO_L_PU, BIT(21)),
+	PINCTRL_CONF_DESC(35, REG_GPIO_L_PU, BIT(22)),
+	PINCTRL_CONF_DESC(36, REG_GPIO_L_PU, BIT(23)),
+	PINCTRL_CONF_DESC(37, REG_GPIO_L_PU, BIT(24)),
+	PINCTRL_CONF_DESC(38, REG_GPIO_L_PU, BIT(25)),
+	PINCTRL_CONF_DESC(39, REG_GPIO_L_PU, BIT(26)),
+	PINCTRL_CONF_DESC(40, REG_GPIO_L_PU, BIT(27)),
+	PINCTRL_CONF_DESC(41, REG_GPIO_L_PU, BIT(28)),
+	PINCTRL_CONF_DESC(42, REG_GPIO_L_PU, BIT(29)),
+	PINCTRL_CONF_DESC(43, REG_GPIO_L_PU, BIT(30)),
+	PINCTRL_CONF_DESC(44, REG_GPIO_L_PU, BIT(31)),
+	PINCTRL_CONF_DESC(45, REG_GPIO_H_PU, BIT(0)),
+	PINCTRL_CONF_DESC(46, REG_GPIO_H_PU, BIT(1)),
+	PINCTRL_CONF_DESC(47, REG_GPIO_H_PU, BIT(2)),
+	PINCTRL_CONF_DESC(48, REG_GPIO_H_PU, BIT(3)),
+	PINCTRL_CONF_DESC(49, REG_GPIO_H_PU, BIT(4)),
+	PINCTRL_CONF_DESC(50, REG_GPIO_H_PU, BIT(5)),
+	PINCTRL_CONF_DESC(51, REG_GPIO_H_PU, BIT(6)),
+	PINCTRL_CONF_DESC(52, REG_GPIO_H_PU, BIT(7)),
+	PINCTRL_CONF_DESC(53, REG_GPIO_H_PU, BIT(8)),
+	PINCTRL_CONF_DESC(54, REG_GPIO_H_PU, BIT(9)),
+	PINCTRL_CONF_DESC(55, REG_GPIO_H_PU, BIT(10)),
+	PINCTRL_CONF_DESC(56, REG_GPIO_H_PU, BIT(11)),
+	PINCTRL_CONF_DESC(57, REG_GPIO_H_PU, BIT(12)),
+	PINCTRL_CONF_DESC(58, REG_GPIO_H_PU, BIT(13)),
+	PINCTRL_CONF_DESC(59, REG_GPIO_H_PU, BIT(14)),
+	PINCTRL_CONF_DESC(61, REG_I2C_SDA_PU, PCIE0_RESET_PU_MASK),
+	PINCTRL_CONF_DESC(62, REG_I2C_SDA_PU, PCIE1_RESET_PU_MASK),
+	PINCTRL_CONF_DESC(63, REG_I2C_SDA_PU, PCIE2_RESET_PU_MASK),
+};
+
+static const struct airoha_pinctrl_conf airoha_pinctrl_pulldown_conf[] = {
+	PINCTRL_CONF_DESC(0, REG_I2C_SDA_PD, UART1_TXD_PD_MASK),
+	PINCTRL_CONF_DESC(1, REG_I2C_SDA_PD, UART1_RXD_PD_MASK),
+	PINCTRL_CONF_DESC(2, REG_I2C_SDA_PD, I2C_SDA_PD_MASK),
+	PINCTRL_CONF_DESC(3, REG_I2C_SDA_PD, I2C_SCL_PD_MASK),
+	PINCTRL_CONF_DESC(4, REG_I2C_SDA_PD, SPI_CS0_PD_MASK),
+	PINCTRL_CONF_DESC(5, REG_I2C_SDA_PD, SPI_CLK_PD_MASK),
+	PINCTRL_CONF_DESC(6, REG_I2C_SDA_PD, SPI_MOSI_PD_MASK),
+	PINCTRL_CONF_DESC(7, REG_I2C_SDA_PD, SPI_MISO_PD_MASK),
+	PINCTRL_CONF_DESC(13, REG_GPIO_L_PD, BIT(0)),
+	PINCTRL_CONF_DESC(14, REG_GPIO_L_PD, BIT(1)),
+	PINCTRL_CONF_DESC(15, REG_GPIO_L_PD, BIT(2)),
+	PINCTRL_CONF_DESC(16, REG_GPIO_L_PD, BIT(3)),
+	PINCTRL_CONF_DESC(17, REG_GPIO_L_PD, BIT(4)),
+	PINCTRL_CONF_DESC(18, REG_GPIO_L_PD, BIT(5)),
+	PINCTRL_CONF_DESC(19, REG_GPIO_L_PD, BIT(6)),
+	PINCTRL_CONF_DESC(20, REG_GPIO_L_PD, BIT(7)),
+	PINCTRL_CONF_DESC(21, REG_GPIO_L_PD, BIT(8)),
+	PINCTRL_CONF_DESC(22, REG_GPIO_L_PD, BIT(9)),
+	PINCTRL_CONF_DESC(23, REG_GPIO_L_PD, BIT(10)),
+	PINCTRL_CONF_DESC(24, REG_GPIO_L_PD, BIT(11)),
+	PINCTRL_CONF_DESC(25, REG_GPIO_L_PD, BIT(12)),
+	PINCTRL_CONF_DESC(26, REG_GPIO_L_PD, BIT(13)),
+	PINCTRL_CONF_DESC(27, REG_GPIO_L_PD, BIT(14)),
+	PINCTRL_CONF_DESC(28, REG_GPIO_L_PD, BIT(15)),
+	PINCTRL_CONF_DESC(29, REG_GPIO_L_PD, BIT(16)),
+	PINCTRL_CONF_DESC(30, REG_GPIO_L_PD, BIT(17)),
+	PINCTRL_CONF_DESC(31, REG_GPIO_L_PD, BIT(18)),
+	PINCTRL_CONF_DESC(32, REG_GPIO_L_PD, BIT(18)),
+	PINCTRL_CONF_DESC(33, REG_GPIO_L_PD, BIT(20)),
+	PINCTRL_CONF_DESC(34, REG_GPIO_L_PD, BIT(21)),
+	PINCTRL_CONF_DESC(35, REG_GPIO_L_PD, BIT(22)),
+	PINCTRL_CONF_DESC(36, REG_GPIO_L_PD, BIT(23)),
+	PINCTRL_CONF_DESC(37, REG_GPIO_L_PD, BIT(24)),
+	PINCTRL_CONF_DESC(38, REG_GPIO_L_PD, BIT(25)),
+	PINCTRL_CONF_DESC(39, REG_GPIO_L_PD, BIT(26)),
+	PINCTRL_CONF_DESC(40, REG_GPIO_L_PD, BIT(27)),
+	PINCTRL_CONF_DESC(41, REG_GPIO_L_PD, BIT(28)),
+	PINCTRL_CONF_DESC(42, REG_GPIO_L_PD, BIT(29)),
+	PINCTRL_CONF_DESC(43, REG_GPIO_L_PD, BIT(30)),
+	PINCTRL_CONF_DESC(44, REG_GPIO_L_PD, BIT(31)),
+	PINCTRL_CONF_DESC(45, REG_GPIO_H_PD, BIT(0)),
+	PINCTRL_CONF_DESC(46, REG_GPIO_H_PD, BIT(1)),
+	PINCTRL_CONF_DESC(47, REG_GPIO_H_PD, BIT(2)),
+	PINCTRL_CONF_DESC(48, REG_GPIO_H_PD, BIT(3)),
+	PINCTRL_CONF_DESC(49, REG_GPIO_H_PD, BIT(4)),
+	PINCTRL_CONF_DESC(50, REG_GPIO_H_PD, BIT(5)),
+	PINCTRL_CONF_DESC(51, REG_GPIO_H_PD, BIT(6)),
+	PINCTRL_CONF_DESC(52, REG_GPIO_H_PD, BIT(7)),
+	PINCTRL_CONF_DESC(53, REG_GPIO_H_PD, BIT(8)),
+	PINCTRL_CONF_DESC(54, REG_GPIO_H_PD, BIT(9)),
+	PINCTRL_CONF_DESC(55, REG_GPIO_H_PD, BIT(10)),
+	PINCTRL_CONF_DESC(56, REG_GPIO_H_PD, BIT(11)),
+	PINCTRL_CONF_DESC(57, REG_GPIO_H_PD, BIT(12)),
+	PINCTRL_CONF_DESC(58, REG_GPIO_H_PD, BIT(13)),
+	PINCTRL_CONF_DESC(59, REG_GPIO_H_PD, BIT(14)),
+	PINCTRL_CONF_DESC(61, REG_I2C_SDA_PD, PCIE0_RESET_PD_MASK),
+	PINCTRL_CONF_DESC(62, REG_I2C_SDA_PD, PCIE1_RESET_PD_MASK),
+	PINCTRL_CONF_DESC(63, REG_I2C_SDA_PD, PCIE2_RESET_PD_MASK),
+};
+
+static const struct airoha_pinctrl_conf airoha_pinctrl_drive_e2_conf[] = {
+	PINCTRL_CONF_DESC(0, REG_I2C_SDA_E2, UART1_TXD_E2_MASK),
+	PINCTRL_CONF_DESC(1, REG_I2C_SDA_E2, UART1_RXD_E2_MASK),
+	PINCTRL_CONF_DESC(2, REG_I2C_SDA_E2, I2C_SDA_E2_MASK),
+	PINCTRL_CONF_DESC(3, REG_I2C_SDA_E2, I2C_SCL_E2_MASK),
+	PINCTRL_CONF_DESC(4, REG_I2C_SDA_E2, SPI_CS0_E2_MASK),
+	PINCTRL_CONF_DESC(5, REG_I2C_SDA_E2, SPI_CLK_E2_MASK),
+	PINCTRL_CONF_DESC(6, REG_I2C_SDA_E2, SPI_MOSI_E2_MASK),
+	PINCTRL_CONF_DESC(7, REG_I2C_SDA_E2, SPI_MISO_E2_MASK),
+	PINCTRL_CONF_DESC(13, REG_GPIO_L_E2, BIT(0)),
+	PINCTRL_CONF_DESC(14, REG_GPIO_L_E2, BIT(1)),
+	PINCTRL_CONF_DESC(15, REG_GPIO_L_E2, BIT(2)),
+	PINCTRL_CONF_DESC(16, REG_GPIO_L_E2, BIT(3)),
+	PINCTRL_CONF_DESC(17, REG_GPIO_L_E2, BIT(4)),
+	PINCTRL_CONF_DESC(18, REG_GPIO_L_E2, BIT(5)),
+	PINCTRL_CONF_DESC(19, REG_GPIO_L_E2, BIT(6)),
+	PINCTRL_CONF_DESC(20, REG_GPIO_L_E2, BIT(7)),
+	PINCTRL_CONF_DESC(21, REG_GPIO_L_E2, BIT(8)),
+	PINCTRL_CONF_DESC(22, REG_GPIO_L_E2, BIT(9)),
+	PINCTRL_CONF_DESC(23, REG_GPIO_L_E2, BIT(10)),
+	PINCTRL_CONF_DESC(24, REG_GPIO_L_E2, BIT(11)),
+	PINCTRL_CONF_DESC(25, REG_GPIO_L_E2, BIT(12)),
+	PINCTRL_CONF_DESC(26, REG_GPIO_L_E2, BIT(13)),
+	PINCTRL_CONF_DESC(27, REG_GPIO_L_E2, BIT(14)),
+	PINCTRL_CONF_DESC(28, REG_GPIO_L_E2, BIT(15)),
+	PINCTRL_CONF_DESC(29, REG_GPIO_L_E2, BIT(16)),
+	PINCTRL_CONF_DESC(30, REG_GPIO_L_E2, BIT(17)),
+	PINCTRL_CONF_DESC(31, REG_GPIO_L_E2, BIT(18)),
+	PINCTRL_CONF_DESC(32, REG_GPIO_L_E2, BIT(18)),
+	PINCTRL_CONF_DESC(33, REG_GPIO_L_E2, BIT(20)),
+	PINCTRL_CONF_DESC(34, REG_GPIO_L_E2, BIT(21)),
+	PINCTRL_CONF_DESC(35, REG_GPIO_L_E2, BIT(22)),
+	PINCTRL_CONF_DESC(36, REG_GPIO_L_E2, BIT(23)),
+	PINCTRL_CONF_DESC(37, REG_GPIO_L_E2, BIT(24)),
+	PINCTRL_CONF_DESC(38, REG_GPIO_L_E2, BIT(25)),
+	PINCTRL_CONF_DESC(39, REG_GPIO_L_E2, BIT(26)),
+	PINCTRL_CONF_DESC(40, REG_GPIO_L_E2, BIT(27)),
+	PINCTRL_CONF_DESC(41, REG_GPIO_L_E2, BIT(28)),
+	PINCTRL_CONF_DESC(42, REG_GPIO_L_E2, BIT(29)),
+	PINCTRL_CONF_DESC(43, REG_GPIO_L_E2, BIT(30)),
+	PINCTRL_CONF_DESC(44, REG_GPIO_L_E2, BIT(31)),
+	PINCTRL_CONF_DESC(45, REG_GPIO_H_E2, BIT(0)),
+	PINCTRL_CONF_DESC(46, REG_GPIO_H_E2, BIT(1)),
+	PINCTRL_CONF_DESC(47, REG_GPIO_H_E2, BIT(2)),
+	PINCTRL_CONF_DESC(48, REG_GPIO_H_E2, BIT(3)),
+	PINCTRL_CONF_DESC(49, REG_GPIO_H_E2, BIT(4)),
+	PINCTRL_CONF_DESC(50, REG_GPIO_H_E2, BIT(5)),
+	PINCTRL_CONF_DESC(51, REG_GPIO_H_E2, BIT(6)),
+	PINCTRL_CONF_DESC(52, REG_GPIO_H_E2, BIT(7)),
+	PINCTRL_CONF_DESC(53, REG_GPIO_H_E2, BIT(8)),
+	PINCTRL_CONF_DESC(54, REG_GPIO_H_E2, BIT(9)),
+	PINCTRL_CONF_DESC(55, REG_GPIO_H_E2, BIT(10)),
+	PINCTRL_CONF_DESC(56, REG_GPIO_H_E2, BIT(11)),
+	PINCTRL_CONF_DESC(57, REG_GPIO_H_E2, BIT(12)),
+	PINCTRL_CONF_DESC(58, REG_GPIO_H_E2, BIT(13)),
+	PINCTRL_CONF_DESC(59, REG_GPIO_H_E2, BIT(14)),
+	PINCTRL_CONF_DESC(61, REG_I2C_SDA_E2, PCIE0_RESET_E2_MASK),
+	PINCTRL_CONF_DESC(62, REG_I2C_SDA_E2, PCIE1_RESET_E2_MASK),
+	PINCTRL_CONF_DESC(63, REG_I2C_SDA_E2, PCIE2_RESET_E2_MASK),
+};
+
+static const struct airoha_pinctrl_conf airoha_pinctrl_drive_e4_conf[] = {
+	PINCTRL_CONF_DESC(0, REG_I2C_SDA_E4, UART1_TXD_E4_MASK),
+	PINCTRL_CONF_DESC(1, REG_I2C_SDA_E4, UART1_RXD_E4_MASK),
+	PINCTRL_CONF_DESC(2, REG_I2C_SDA_E4, I2C_SDA_E4_MASK),
+	PINCTRL_CONF_DESC(3, REG_I2C_SDA_E4, I2C_SCL_E4_MASK),
+	PINCTRL_CONF_DESC(4, REG_I2C_SDA_E4, SPI_CS0_E4_MASK),
+	PINCTRL_CONF_DESC(5, REG_I2C_SDA_E4, SPI_CLK_E4_MASK),
+	PINCTRL_CONF_DESC(6, REG_I2C_SDA_E4, SPI_MOSI_E4_MASK),
+	PINCTRL_CONF_DESC(7, REG_I2C_SDA_E4, SPI_MISO_E4_MASK),
+	PINCTRL_CONF_DESC(13, REG_GPIO_L_E4, BIT(0)),
+	PINCTRL_CONF_DESC(14, REG_GPIO_L_E4, BIT(1)),
+	PINCTRL_CONF_DESC(15, REG_GPIO_L_E4, BIT(2)),
+	PINCTRL_CONF_DESC(16, REG_GPIO_L_E4, BIT(3)),
+	PINCTRL_CONF_DESC(17, REG_GPIO_L_E4, BIT(4)),
+	PINCTRL_CONF_DESC(18, REG_GPIO_L_E4, BIT(5)),
+	PINCTRL_CONF_DESC(19, REG_GPIO_L_E4, BIT(6)),
+	PINCTRL_CONF_DESC(20, REG_GPIO_L_E4, BIT(7)),
+	PINCTRL_CONF_DESC(21, REG_GPIO_L_E4, BIT(8)),
+	PINCTRL_CONF_DESC(22, REG_GPIO_L_E4, BIT(9)),
+	PINCTRL_CONF_DESC(23, REG_GPIO_L_E4, BIT(10)),
+	PINCTRL_CONF_DESC(24, REG_GPIO_L_E4, BIT(11)),
+	PINCTRL_CONF_DESC(25, REG_GPIO_L_E4, BIT(12)),
+	PINCTRL_CONF_DESC(26, REG_GPIO_L_E4, BIT(13)),
+	PINCTRL_CONF_DESC(27, REG_GPIO_L_E4, BIT(14)),
+	PINCTRL_CONF_DESC(28, REG_GPIO_L_E4, BIT(15)),
+	PINCTRL_CONF_DESC(29, REG_GPIO_L_E4, BIT(16)),
+	PINCTRL_CONF_DESC(30, REG_GPIO_L_E4, BIT(17)),
+	PINCTRL_CONF_DESC(31, REG_GPIO_L_E4, BIT(18)),
+	PINCTRL_CONF_DESC(32, REG_GPIO_L_E4, BIT(18)),
+	PINCTRL_CONF_DESC(33, REG_GPIO_L_E4, BIT(20)),
+	PINCTRL_CONF_DESC(34, REG_GPIO_L_E4, BIT(21)),
+	PINCTRL_CONF_DESC(35, REG_GPIO_L_E4, BIT(22)),
+	PINCTRL_CONF_DESC(36, REG_GPIO_L_E4, BIT(23)),
+	PINCTRL_CONF_DESC(37, REG_GPIO_L_E4, BIT(24)),
+	PINCTRL_CONF_DESC(38, REG_GPIO_L_E4, BIT(25)),
+	PINCTRL_CONF_DESC(39, REG_GPIO_L_E4, BIT(26)),
+	PINCTRL_CONF_DESC(40, REG_GPIO_L_E4, BIT(27)),
+	PINCTRL_CONF_DESC(41, REG_GPIO_L_E4, BIT(28)),
+	PINCTRL_CONF_DESC(42, REG_GPIO_L_E4, BIT(29)),
+	PINCTRL_CONF_DESC(43, REG_GPIO_L_E4, BIT(30)),
+	PINCTRL_CONF_DESC(44, REG_GPIO_L_E4, BIT(31)),
+	PINCTRL_CONF_DESC(45, REG_GPIO_H_E4, BIT(0)),
+	PINCTRL_CONF_DESC(46, REG_GPIO_H_E4, BIT(1)),
+	PINCTRL_CONF_DESC(47, REG_GPIO_H_E4, BIT(2)),
+	PINCTRL_CONF_DESC(48, REG_GPIO_H_E4, BIT(3)),
+	PINCTRL_CONF_DESC(49, REG_GPIO_H_E4, BIT(4)),
+	PINCTRL_CONF_DESC(50, REG_GPIO_H_E4, BIT(5)),
+	PINCTRL_CONF_DESC(51, REG_GPIO_H_E4, BIT(6)),
+	PINCTRL_CONF_DESC(52, REG_GPIO_H_E4, BIT(7)),
+	PINCTRL_CONF_DESC(53, REG_GPIO_H_E4, BIT(8)),
+	PINCTRL_CONF_DESC(54, REG_GPIO_H_E4, BIT(9)),
+	PINCTRL_CONF_DESC(55, REG_GPIO_H_E4, BIT(10)),
+	PINCTRL_CONF_DESC(56, REG_GPIO_H_E4, BIT(11)),
+	PINCTRL_CONF_DESC(57, REG_GPIO_H_E4, BIT(12)),
+	PINCTRL_CONF_DESC(58, REG_GPIO_H_E4, BIT(13)),
+	PINCTRL_CONF_DESC(59, REG_GPIO_H_E4, BIT(14)),
+	PINCTRL_CONF_DESC(61, REG_I2C_SDA_E4, PCIE0_RESET_E4_MASK),
+	PINCTRL_CONF_DESC(62, REG_I2C_SDA_E4, PCIE1_RESET_E4_MASK),
+	PINCTRL_CONF_DESC(63, REG_I2C_SDA_E4, PCIE2_RESET_E4_MASK),
+};
+
+static const struct airoha_pinctrl_conf airoha_pinctrl_pcie_rst_od_conf[] = {
+	PINCTRL_CONF_DESC(61, REG_PCIE_RESET_OD, PCIE0_RESET_OD_MASK),
+	PINCTRL_CONF_DESC(62, REG_PCIE_RESET_OD, PCIE1_RESET_OD_MASK),
+	PINCTRL_CONF_DESC(63, REG_PCIE_RESET_OD, PCIE2_RESET_OD_MASK),
+};
+
+static u32 airoha_pinctrl_rmw_unlock(void __iomem *addr, u32 mask, u32 val)
+{
+	val |= (readl(addr) & ~mask);
+	writel(val, addr);
+
+	return val;
+}
+
+#define airoha_pinctrl_set_unlock(addr, val)					\
+	airoha_pinctrl_rmw_unlock((addr), 0, (val))
+#define airoha_pinctrl_clear_unlock(addr, mask)					\
+	airoha_pinctrl_rmw_unlock((addr), (mask), (0))
+
+static u32 airoha_pinctrl_rmw(struct airoha_pinctrl *pinctrl,
+			      void __iomem *addr, u32 mask, u32 val)
+{
+	mutex_lock(&pinctrl->mutex);
+	val = airoha_pinctrl_rmw_unlock(addr, mask, val);
+	mutex_unlock(&pinctrl->mutex);
+
+	return val;
+}
+
+static void airoha_pinctrl_gpio_set_direction(struct airoha_pinctrl *pinctrl,
+					      unsigned int gpio, bool input)
+{
+	u32 mask, index;
+
+	/* set output enable */
+	mask = BIT(gpio % AIROHA_GPIO_BANK_SIZE);
+	index = gpio / AIROHA_GPIO_BANK_SIZE;
+	airoha_pinctrl_rmw(pinctrl, pinctrl->gpiochip.out[index],
+			   mask, !input ? mask : 0);
+
+	/* set gpio direction */
+	mask = BIT(2 * (gpio % AIROHA_REG_GPIOCTRL_NUM_GPIO));
+	index = gpio / AIROHA_REG_GPIOCTRL_NUM_GPIO;
+	airoha_pinctrl_rmw(pinctrl, pinctrl->gpiochip.dir[index],
+			   mask, !input ? mask : 0);
+}
+
+static void airoha_pinctrl_gpio_set_value(struct airoha_pinctrl *pinctrl,
+					  unsigned int gpio, bool value)
+{
+	u8 index = gpio / AIROHA_GPIO_BANK_SIZE;
+	u32 pin = gpio % AIROHA_GPIO_BANK_SIZE;
+
+	airoha_pinctrl_rmw(pinctrl, pinctrl->gpiochip.data[index],
+			   BIT(pin), value ? BIT(pin) : 0);
+}
+
+static int airoha_pinctrl_gpio_get_direction(struct airoha_pinctrl *pinctrl,
+					     unsigned int gpio)
+{
+	u32 val, mask = BIT(2 * (gpio % AIROHA_REG_GPIOCTRL_NUM_GPIO));
+	u8 index = gpio / AIROHA_REG_GPIOCTRL_NUM_GPIO;
+
+	val = (readl(pinctrl->gpiochip.dir[index]) & mask);
+
+	return val ? PIN_CONFIG_OUTPUT_ENABLE : PIN_CONFIG_INPUT_ENABLE;
+}
+
+static int airoha_pinmux_set_mux(struct pinctrl_dev *pctrl_dev,
+				 unsigned int selector,
+				 unsigned int group)
+{
+	struct airoha_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
+	const struct airoha_pinctrl_func *func;
+	struct function_desc *desc;
+	struct group_desc *grp;
+	int i;
+
+	desc = pinmux_generic_get_function(pctrl_dev, selector);
+	if (!desc)
+		return -EINVAL;
+
+	grp = pinctrl_generic_get_group(pctrl_dev, group);
+	if (!grp)
+		return -EINVAL;
+
+	dev_dbg(pctrl_dev->dev, "enable function %s group %s\n",
+		desc->name, grp->grp.name);
+
+	func = desc->data;
+	for (i = 0; i < func->group_size; i++) {
+		const struct airoha_pinctrl_func_group *group;
+		int j;
+
+		group = &func->groups[i];
+		if (strcmp(group->name, grp->grp.name))
+			continue;
+
+		for (j = 0; j < group->regmap_size; j++) {
+			void __iomem *base;
+
+			base = pinctrl->regs.mux[group->regmap[j].mux];
+			airoha_pinctrl_rmw(pinctrl,
+					   base + group->regmap[j].offset,
+					   group->regmap[j].mask,
+					   group->regmap[j].val);
+		}
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
+static int airoha_pinmux_gpio_set_direction(struct pinctrl_dev *pctrl_dev,
+					    struct pinctrl_gpio_range *range,
+					    unsigned int pin, bool input)
+{
+	struct airoha_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
+	int gpio = pin - range->pin_base;
+
+	airoha_pinctrl_gpio_set_direction(pinctrl, gpio, input);
+
+	return 0;
+}
+
+static int airoha_pinctrl_get_gpio_from_pin(struct pinctrl_dev *pctrl_dev,
+					    int pin)
+{
+	struct pinctrl_gpio_range *range;
+	int gpio;
+
+	range = pinctrl_find_gpio_range_from_pin_nolock(pctrl_dev, pin);
+	if (!range)
+		return -EINVAL;
+
+	gpio = pin - range->pin_base;
+	if (gpio < 0)
+		return -EINVAL;
+
+	return gpio;
+}
+
+static const struct airoha_pinctrl_reg *
+airoha_pinctrl_get_conf_reg(const struct airoha_pinctrl_conf *conf,
+			    int conf_size, int pin)
+{
+	int i;
+
+	for (i = 0; i < conf_size; i++) {
+		if (conf[i].pin == pin)
+			return &conf[i].reg;
+	}
+
+	return NULL;
+}
+
+static int airoha_pinctrl_get_conf(void __iomem *base,
+				   const struct airoha_pinctrl_conf *conf,
+				   int conf_size, int pin, u32 *val)
+{
+	const struct airoha_pinctrl_reg *reg;
+
+	reg = airoha_pinctrl_get_conf_reg(conf, conf_size, pin);
+	if (!reg)
+		return -EINVAL;
+
+	*val = readl(base + reg->offset);
+	*val = (*val & reg->mask) >> __bf_shf(reg->mask);
+
+	return 0;
+}
+
+static int airoha_pinctrl_set_conf(struct airoha_pinctrl *pinctrl,
+				   void __iomem *base,
+				   const struct airoha_pinctrl_conf *conf,
+				   int conf_size, int pin, u32 val)
+{
+	const struct airoha_pinctrl_reg *reg = NULL;
+
+	reg = airoha_pinctrl_get_conf_reg(conf, conf_size, pin);
+	if (!reg)
+		return -EINVAL;
+
+	airoha_pinctrl_rmw(pinctrl, base + reg->offset, reg->mask,
+			   val << __bf_shf(reg->mask));
+
+	return 0;
+}
+
+#define airoha_pinctrl_get_pullup_conf(pinctrl, pin, val)			\
+	airoha_pinctrl_get_conf(((pinctrl)->regs.conf),				\
+				airoha_pinctrl_pullup_conf,			\
+				ARRAY_SIZE(airoha_pinctrl_pullup_conf),		\
+				(pin), (val))
+#define airoha_pinctrl_get_pulldown_conf(pinctrl, pin, val)			\
+	airoha_pinctrl_get_conf(((pinctrl)->regs.conf),				\
+				airoha_pinctrl_pulldown_conf,			\
+				ARRAY_SIZE(airoha_pinctrl_pulldown_conf),	\
+				(pin), (val))
+#define airoha_pinctrl_get_drive_e2_conf(pinctrl, pin, val)			\
+	airoha_pinctrl_get_conf(((pinctrl)->regs.conf),				\
+				airoha_pinctrl_drive_e2_conf,			\
+				ARRAY_SIZE(airoha_pinctrl_drive_e2_conf),	\
+				(pin), (val))
+#define airoha_pinctrl_get_drive_e4_conf(pinctrl, pin, val)			\
+	airoha_pinctrl_get_conf(((pinctrl)->regs.conf),				\
+				airoha_pinctrl_drive_e4_conf,			\
+				ARRAY_SIZE(airoha_pinctrl_drive_e4_conf),	\
+				(pin), (val))
+#define airoha_pinctrl_get_pcie_rst_od_conf(pinctrl, pin, val)			\
+	airoha_pinctrl_get_conf(((pinctrl)->regs.pcie_rst),			\
+				airoha_pinctrl_pcie_rst_od_conf,		\
+				ARRAY_SIZE(airoha_pinctrl_pcie_rst_od_conf),	\
+				(pin), (val))
+#define airoha_pinctrl_set_pullup_conf(pinctrl, pin, val)			\
+	airoha_pinctrl_set_conf((pinctrl), ((pinctrl)->regs.conf),		\
+				airoha_pinctrl_pullup_conf,			\
+				ARRAY_SIZE(airoha_pinctrl_pullup_conf),		\
+				(pin), (val))
+#define airoha_pinctrl_set_pulldown_conf(pinctrl, pin, val)			\
+	airoha_pinctrl_set_conf((pinctrl), ((pinctrl)->regs.conf),		\
+				airoha_pinctrl_pulldown_conf,			\
+				ARRAY_SIZE(airoha_pinctrl_pulldown_conf),	\
+				(pin), (val))
+#define airoha_pinctrl_set_drive_e2_conf(pinctrl, pin, val)			\
+	airoha_pinctrl_set_conf((pinctrl), ((pinctrl)->regs.conf),		\
+				airoha_pinctrl_drive_e2_conf,			\
+				ARRAY_SIZE(airoha_pinctrl_drive_e2_conf),	\
+				(pin), (val))
+#define airoha_pinctrl_set_drive_e4_conf(pinctrl, pin, val)			\
+	airoha_pinctrl_set_conf((pinctrl), ((pinctrl)->regs.conf),		\
+				airoha_pinctrl_drive_e4_conf,			\
+				ARRAY_SIZE(airoha_pinctrl_drive_e4_conf),	\
+				(pin), (val))
+#define airoha_pinctrl_set_pcie_rst_od_conf(pinctrl, pin, val)			\
+	airoha_pinctrl_set_conf((pinctrl), ((pinctrl)->regs.pcie_rst),		\
+				airoha_pinctrl_pcie_rst_od_conf,		\
+				ARRAY_SIZE(airoha_pinctrl_pcie_rst_od_conf),	\
+				(pin), (val))
+
+static int airoha_pinconf_get(struct pinctrl_dev *pctrl_dev,
+			      unsigned int pin, unsigned long *config)
+{
+	struct airoha_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
+	enum pin_config_param param = pinconf_to_config_param(*config);
+	u32 arg;
+
+	switch (param) {
+	case PIN_CONFIG_BIAS_PULL_DOWN:
+	case PIN_CONFIG_BIAS_DISABLE:
+	case PIN_CONFIG_BIAS_PULL_UP: {
+		u32 pull_up, pull_down;
+
+		if (airoha_pinctrl_get_pullup_conf(pinctrl, pin, &pull_up) ||
+		    airoha_pinctrl_get_pulldown_conf(pinctrl, pin, &pull_down))
+			return -EINVAL;
+
+		if (param == PIN_CONFIG_BIAS_PULL_UP &&
+		    !(pull_up && !pull_down))
+			return -EINVAL;
+		else if (param == PIN_CONFIG_BIAS_PULL_DOWN &&
+			 !(pull_down && !pull_up))
+			return -EINVAL;
+		else if (pull_up || pull_down)
+			return -EINVAL;
+
+		arg = 1;
+		break;
+	}
+	case PIN_CONFIG_DRIVE_STRENGTH: {
+		u32 e2, e4;
+
+		if (airoha_pinctrl_get_drive_e2_conf(pinctrl, pin, &e2) ||
+		    airoha_pinctrl_get_drive_e4_conf(pinctrl, pin, &e4))
+			return -EINVAL;
+
+		arg = e4 << 1 | e2;
+		break;
+	}
+	case PIN_CONFIG_DRIVE_OPEN_DRAIN:
+		if (airoha_pinctrl_get_pcie_rst_od_conf(pinctrl, pin, &arg))
+			return -EINVAL;
+		break;
+	case PIN_CONFIG_OUTPUT_ENABLE:
+	case PIN_CONFIG_INPUT_ENABLE: {
+		int gpio = airoha_pinctrl_get_gpio_from_pin(pctrl_dev, pin);
+
+		if (gpio < 0)
+			return gpio;
+
+		arg = airoha_pinctrl_gpio_get_direction(pinctrl, gpio);
+		if (arg != param)
+			return -EINVAL;
+
+		arg = 1;
+		break;
+	}
+	default:
+		return -EOPNOTSUPP;
+	}
+
+	*config = pinconf_to_config_packed(param, arg);
+
+	return 0;
+}
+
+static int airoha_pinconf_set(struct pinctrl_dev *pctrl_dev,
+			      unsigned int pin, unsigned long *configs,
+			      unsigned int num_configs)
+{
+	struct airoha_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
+	int i;
+
+	for (i = 0; i < num_configs; i++) {
+		u32 param = pinconf_to_config_param(configs[i]);
+		u32 arg = pinconf_to_config_argument(configs[i]);
+
+		switch (param) {
+		case PIN_CONFIG_BIAS_DISABLE:
+			airoha_pinctrl_set_pulldown_conf(pinctrl, pin, 0);
+			airoha_pinctrl_set_pullup_conf(pinctrl, pin, 0);
+			break;
+		case PIN_CONFIG_BIAS_PULL_UP:
+			airoha_pinctrl_set_pulldown_conf(pinctrl, pin, 0);
+			airoha_pinctrl_set_pullup_conf(pinctrl, pin, 1);
+			break;
+		case PIN_CONFIG_BIAS_PULL_DOWN:
+			airoha_pinctrl_set_pulldown_conf(pinctrl, pin, 1);
+			airoha_pinctrl_set_pullup_conf(pinctrl, pin, 0);
+			break;
+		case PIN_CONFIG_DRIVE_STRENGTH: {
+			u32 e2 = 0, e4 = 0;
+
+			switch (arg) {
+			case MTK_DRIVE_2mA:
+				break;
+			case MTK_DRIVE_4mA:
+				e2 = 1;
+				break;
+			case MTK_DRIVE_6mA:
+				e4 = 1;
+				break;
+			case MTK_DRIVE_8mA:
+				e2 = 1;
+				e4 = 1;
+				break;
+			default:
+				return -EINVAL;
+			}
+
+			airoha_pinctrl_set_drive_e2_conf(pinctrl, pin, e2);
+			airoha_pinctrl_set_drive_e4_conf(pinctrl, pin, e4);
+			break;
+		}
+		case PIN_CONFIG_DRIVE_OPEN_DRAIN:
+			airoha_pinctrl_set_pcie_rst_od_conf(pinctrl, pin, !!arg);
+			break;
+		case PIN_CONFIG_OUTPUT_ENABLE:
+		case PIN_CONFIG_INPUT_ENABLE:
+		case PIN_CONFIG_OUTPUT: {
+			int gpio = airoha_pinctrl_get_gpio_from_pin(pctrl_dev, pin);
+			bool input = param == PIN_CONFIG_INPUT_ENABLE;
+
+			if (gpio < 0)
+				return gpio;
+
+			airoha_pinctrl_gpio_set_direction(pinctrl, gpio, input);
+			if (param == PIN_CONFIG_OUTPUT)
+				airoha_pinctrl_gpio_set_value(pinctrl, gpio, !!arg);
+			break;
+		}
+		default:
+			return -EOPNOTSUPP;
+		}
+	}
+
+	return 0;
+}
+
+static int airoha_pinconf_group_get(struct pinctrl_dev *pctrl_dev,
+				    unsigned int group, unsigned long *config)
+{
+	u32 cur_config = 0;
+	int i;
+
+	for (i = 0; i < airoha_pinctrl_groups[group].npins; i++) {
+		if (airoha_pinconf_get(pctrl_dev,
+				       airoha_pinctrl_groups[group].pins[i],
+				       config))
+			return -EOPNOTSUPP;
+
+		if (i && cur_config != *config)
+			return -EOPNOTSUPP;
+
+		cur_config = *config;
+	}
+
+	return 0;
+}
+
+static int airoha_pinconf_group_set(struct pinctrl_dev *pctrl_dev,
+				    unsigned int group, unsigned long *configs,
+				    unsigned int num_configs)
+{
+	int i;
+
+	for (i = 0; i < airoha_pinctrl_groups[group].npins; i++) {
+		int err;
+
+		err = airoha_pinconf_set(pctrl_dev,
+					 airoha_pinctrl_groups[group].pins[i],
+					 configs, num_configs);
+		if (err)
+			return err;
+	}
+
+	return 0;
+}
+
+static const struct pinconf_ops airoha_confops = {
+	.is_generic = true,
+	.pin_config_get = airoha_pinconf_get,
+	.pin_config_set = airoha_pinconf_set,
+	.pin_config_group_get = airoha_pinconf_group_get,
+	.pin_config_group_set = airoha_pinconf_group_set,
+	.pin_config_config_dbg_show = pinconf_generic_dump_config,
+};
+
+static const struct pinctrl_ops airoha_pctlops = {
+	.get_groups_count = pinctrl_generic_get_group_count,
+	.get_group_name = pinctrl_generic_get_group_name,
+	.get_group_pins = pinctrl_generic_get_group_pins,
+	.dt_node_to_map = pinconf_generic_dt_node_to_map_all,
+	.dt_free_map = pinconf_generic_dt_free_map,
+};
+
+static const struct pinmux_ops airoha_pmxops = {
+	.get_functions_count = pinmux_generic_get_function_count,
+	.get_function_name = pinmux_generic_get_function_name,
+	.get_function_groups = pinmux_generic_get_function_groups,
+	.gpio_set_direction = airoha_pinmux_gpio_set_direction,
+	.set_mux = airoha_pinmux_set_mux,
+	.strict = true,
+};
+
+static struct pinctrl_desc airoha_pinctrl_desc = {
+	.name = KBUILD_MODNAME,
+	.owner = THIS_MODULE,
+	.pctlops = &airoha_pctlops,
+	.pmxops = &airoha_pmxops,
+	.confops = &airoha_confops,
+	.pins = airoha_pinctrl_pins,
+	.npins = ARRAY_SIZE(airoha_pinctrl_pins),
+};
+
+static void airoha_pinctrl_gpio_set(struct gpio_chip *chip, unsigned int gpio,
+				    int value)
+{
+	struct airoha_pinctrl *pinctrl = gpiochip_get_data(chip);
+
+	airoha_pinctrl_gpio_set_value(pinctrl, gpio, value);
+}
+
+static int airoha_pinctrl_gpio_get(struct gpio_chip *chip, unsigned int gpio)
+{
+	struct airoha_pinctrl *pinctrl = gpiochip_get_data(chip);
+	u8 index = gpio / AIROHA_GPIO_BANK_SIZE;
+	u32 pin = gpio % AIROHA_GPIO_BANK_SIZE;
+
+	return !!(readl(pinctrl->gpiochip.data[index]) & BIT(pin));
+}
+
+static int airoha_pinctrl_gpio_direction_output(struct gpio_chip *chip,
+						unsigned int gpio, int value)
+{
+	int err;
+
+	err = pinctrl_gpio_direction_output(chip, gpio);
+	if (err)
+		return err;
+
+	airoha_pinctrl_gpio_set(chip, gpio, value);
+
+	return 0;
+}
+
+static void airoha_pinctrl_gpio_irq_unmask(struct irq_data *data)
+{
+	u8 offset = data->hwirq % AIROHA_REG_GPIOCTRL_NUM_GPIO;
+	u8 index = data->hwirq / AIROHA_REG_GPIOCTRL_NUM_GPIO;
+	u32 mask = GENMASK(2 * offset + 1, 2 * offset);
+	struct airoha_pinctrl_gpiochip *gpiochip;
+	u32 val = BIT(2 * offset);
+	unsigned long flags;
+
+	gpiochip = irq_data_get_irq_chip_data(data);
+	if (WARN_ON_ONCE(data->hwirq >= ARRAY_SIZE(gpiochip->irq_type)))
+		return;
+
+	spin_lock_irqsave(&gpiochip->lock, flags);
+
+	switch (gpiochip->irq_type[data->hwirq] & IRQ_TYPE_SENSE_MASK) {
+	case IRQ_TYPE_LEVEL_LOW:
+		val = val << 1;
+		fallthrough;
+	case IRQ_TYPE_LEVEL_HIGH:
+		airoha_pinctrl_rmw_unlock(gpiochip->level[index], mask, val);
+		break;
+	case IRQ_TYPE_EDGE_FALLING:
+		val = val << 1;
+		fallthrough;
+	case IRQ_TYPE_EDGE_RISING:
+		airoha_pinctrl_rmw_unlock(gpiochip->edge[index], mask, val);
+		break;
+	case IRQ_TYPE_EDGE_BOTH:
+		airoha_pinctrl_set_unlock(gpiochip->edge[index], mask);
+		break;
+	default:
+		break;
+	}
+
+	spin_unlock_irqrestore(&gpiochip->lock, flags);
+}
+
+static void airoha_pinctrl_gpio_irq_mask(struct irq_data *data)
+{
+	u8 offset = data->hwirq % AIROHA_REG_GPIOCTRL_NUM_GPIO;
+	u8 index = data->hwirq / AIROHA_REG_GPIOCTRL_NUM_GPIO;
+	u32 mask = GENMASK(2 * offset + 1, 2 * offset);
+	struct airoha_pinctrl_gpiochip *gpiochip;
+	unsigned long flags;
+
+	gpiochip = irq_data_get_irq_chip_data(data);
+
+	spin_lock_irqsave(&gpiochip->lock, flags);
+
+	airoha_pinctrl_clear_unlock(gpiochip->edge[index], mask);
+	airoha_pinctrl_clear_unlock(gpiochip->level[index], mask);
+
+	spin_unlock_irqrestore(&gpiochip->lock, flags);
+}
+
+static int airoha_pinctrl_gpio_irq_type(struct irq_data *data,
+					unsigned int type)
+{
+	struct airoha_pinctrl_gpiochip *gpiochip;
+	unsigned long flags;
+
+	gpiochip = irq_data_get_irq_chip_data(data);
+	if (data->hwirq >= ARRAY_SIZE(gpiochip->irq_type))
+		return -EINVAL;
+
+	spin_lock_irqsave(&gpiochip->lock, flags);
+
+	if (type == IRQ_TYPE_PROBE) {
+		if (gpiochip->irq_type[data->hwirq])
+			goto unlock;
+
+		type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
+	}
+	gpiochip->irq_type[data->hwirq] = type & IRQ_TYPE_SENSE_MASK;
+unlock:
+	spin_unlock_irqrestore(&gpiochip->lock, flags);
+
+	return 0;
+}
+
+static irqreturn_t airoha_pinctrl_gpio_irq_handler(int irq, void *data)
+{
+	struct airoha_pinctrl_gpiochip *gpiochip;
+	bool handled = false;
+	int i;
+
+	gpiochip = container_of(data, struct airoha_pinctrl_gpiochip, chip);
+	for (i = 0; i < ARRAY_SIZE(gpiochip->status); i++) {
+		unsigned long status = readl(gpiochip->status[i]);
+		struct gpio_irq_chip *girq = &gpiochip->chip.irq;
+		int irq;
+
+		for_each_set_bit(irq, &status, AIROHA_GPIO_BANK_SIZE) {
+			u32 offset = irq + i * AIROHA_GPIO_BANK_SIZE;
+
+			generic_handle_irq(irq_find_mapping(girq->domain,
+							    offset));
+			writel(BIT(irq), gpiochip->status[i]);
+		}
+		handled |= !!status;
+	}
+
+	return handled ? IRQ_HANDLED : IRQ_NONE;
+}
+
+static int airoha_pinctrl_add_gpiochip(struct airoha_pinctrl *pinctrl,
+				       struct platform_device *pdev,
+				       int index)
+{
+	struct gpio_chip *chip = &pinctrl->gpiochip.chip;
+	struct gpio_irq_chip *girq = &chip->irq;
+	struct device *dev = &pdev->dev;
+	void __iomem *ptr;
+	int i, irq, err;
+
+	for (i = 0; i < ARRAY_SIZE(pinctrl->gpiochip.data); i++) {
+		ptr = devm_platform_ioremap_resource(pdev, index++);
+		if (IS_ERR(ptr))
+			return dev_err_probe(dev, PTR_ERR(ptr),
+					     "failed to map gpio data regs\n");
+
+		pinctrl->gpiochip.data[i] = ptr;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(pinctrl->gpiochip.dir); i++) {
+		ptr = devm_platform_ioremap_resource(pdev, index++);
+		if (IS_ERR(ptr))
+			return dev_err_probe(dev, PTR_ERR(ptr),
+					     "failed to map gpio dir regs\n");
+
+		pinctrl->gpiochip.dir[i] = ptr;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(pinctrl->gpiochip.out); i++) {
+		ptr = devm_platform_ioremap_resource(pdev, index++);
+		if (IS_ERR(ptr))
+			return dev_err_probe(dev, PTR_ERR(ptr),
+					     "failed to map gpio out regs\n");
+
+		pinctrl->gpiochip.out[i] = ptr;
+	}
+
+	chip->parent = dev;
+	chip->label = dev_name(dev);
+	chip->request = gpiochip_generic_request;
+	chip->free = gpiochip_generic_free;
+	chip->direction_input = pinctrl_gpio_direction_input;
+	chip->direction_output = airoha_pinctrl_gpio_direction_output;
+	chip->set = airoha_pinctrl_gpio_set;
+	chip->get = airoha_pinctrl_gpio_get;
+	chip->base = -1;
+	chip->ngpio = AIROHA_NUM_GPIOS;
+
+	if (!of_property_read_bool(dev->of_node, "interrupt-controller"))
+		goto out;
+
+	for (i = 0; i < ARRAY_SIZE(pinctrl->gpiochip.status); i++) {
+		ptr = devm_platform_ioremap_resource(pdev, index++);
+		if (IS_ERR(ptr))
+			return dev_err_probe(dev, PTR_ERR(ptr),
+					     "failed to map irq status regs\n");
+
+		pinctrl->gpiochip.status[i] = ptr;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(pinctrl->gpiochip.level); i++) {
+		ptr = devm_platform_ioremap_resource(pdev, index++);
+		if (IS_ERR(ptr))
+			return dev_err_probe(dev, PTR_ERR(ptr),
+					     "failed to map irq level regs\n");
+
+		pinctrl->gpiochip.level[i] = ptr;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(pinctrl->gpiochip.edge); i++) {
+		ptr = devm_platform_ioremap_resource(pdev, index++);
+		if (IS_ERR(ptr))
+			return dev_err_probe(dev, PTR_ERR(ptr),
+					     "failed to map irq edge regs\n");
+
+		pinctrl->gpiochip.edge[i] = ptr;
+	}
+
+	spin_lock_init(&pinctrl->gpiochip.lock);
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0)
+		return irq;
+
+	err = devm_request_irq(dev, irq, airoha_pinctrl_gpio_irq_handler,
+			       IRQF_SHARED, dev_name(dev), chip);
+	if (err) {
+		dev_err(dev, "error requesting irq %d: %d\n", irq, err);
+		return err;
+	}
+
+	girq->chip = devm_kzalloc(dev, sizeof(*girq->chip), GFP_KERNEL);
+	if (!girq->chip)
+		return -ENOMEM;
+
+	girq->chip->name = dev_name(dev);
+	girq->chip->irq_unmask = airoha_pinctrl_gpio_irq_unmask;
+	girq->chip->irq_mask = airoha_pinctrl_gpio_irq_mask;
+	girq->chip->irq_mask_ack = airoha_pinctrl_gpio_irq_mask;
+	girq->chip->irq_set_type = airoha_pinctrl_gpio_irq_type;
+	girq->chip->flags = IRQCHIP_SET_TYPE_MASKED;
+	girq->default_type = IRQ_TYPE_NONE;
+	girq->handler = handle_simple_irq;
+out:
+	return devm_gpiochip_add_data(dev, chip, pinctrl);
+}
+
+static int airoha_pinctrl_probe(struct platform_device *pdev)
+{
+	struct airoha_pinctrl *pinctrl;
+	int err, i, index = 0;
+
+	pinctrl = devm_kzalloc(&pdev->dev, sizeof(*pinctrl), GFP_KERNEL);
+	if (!pinctrl)
+		return -ENOMEM;
+
+	mutex_init(&pinctrl->mutex);
+
+	for (i = 0; i < ARRAY_SIZE(pinctrl->regs.mux); i++) {
+		pinctrl->regs.mux[i] = devm_platform_ioremap_resource(pdev,
+								      index++);
+		if (IS_ERR(pinctrl->regs.mux[i]))
+			return dev_err_probe(&pdev->dev,
+					     PTR_ERR(pinctrl->regs.mux[i]),
+					     "failed to iomap mux regs\n");
+	}
+
+	pinctrl->regs.conf = devm_platform_ioremap_resource(pdev, index++);
+	if (IS_ERR(pinctrl->regs.conf))
+		return dev_err_probe(&pdev->dev, PTR_ERR(pinctrl->regs.conf),
+				     "failed to iomap conf regs\n");
+
+	pinctrl->regs.pcie_rst = devm_platform_ioremap_resource(pdev, index++);
+	if (IS_ERR(pinctrl->regs.pcie_rst))
+		return dev_err_probe(&pdev->dev,
+				     PTR_ERR(pinctrl->regs.pcie_rst),
+				     "failed to iomap pcie rst od regs\n");
+
+	err = devm_pinctrl_register_and_init(&pdev->dev, &airoha_pinctrl_desc,
+					     pinctrl, &pinctrl->ctrl);
+	if (err)
+		return err;
+
+	/* build pin groups */
+	for (i = 0; i < ARRAY_SIZE(airoha_pinctrl_groups); i++) {
+		const struct pingroup *grp = &airoha_pinctrl_groups[i];
+
+		err = pinctrl_generic_add_group(pinctrl->ctrl, grp->name,
+						grp->pins, grp->npins,
+						(void *)grp);
+		if (err < 0) {
+			dev_err(&pdev->dev, "Failed to register group %s\n",
+				grp->name);
+			return err;
+		}
+	}
+
+	/* build functions */
+	for (i = 0; i < ARRAY_SIZE(airoha_pinctrl_funcs); i++) {
+		const struct airoha_pinctrl_func *func;
+
+		func = &airoha_pinctrl_funcs[i];
+		err = pinmux_generic_add_function(pinctrl->ctrl,
+						  func->desc.name,
+						  func->desc.group_names,
+						  func->desc.num_group_names,
+						  (void *)func);
+		if (err < 0) {
+			dev_err(&pdev->dev, "Failed to register function %s\n",
+				func->desc.name);
+			return err;
+		}
+	}
+
+	err = pinctrl_enable(pinctrl->ctrl);
+	if (err)
+		return err;
+
+	/* build gpio-chip */
+	return airoha_pinctrl_add_gpiochip(pinctrl, pdev, index);
+}
+
+const struct of_device_id of_airoha_pinctrl_match[] = {
+	{ .compatible = "airoha,en7581-pinctrl" },
+	{ /* sentinel */ }
+};
+
+static struct platform_driver airoha_pinctrl_driver = {
+	.probe = airoha_pinctrl_probe,
+	.driver = {
+		.name = KBUILD_MODNAME,
+		.of_match_table = of_airoha_pinctrl_match,
+	},
+};
+module_platform_driver(airoha_pinctrl_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>");
+MODULE_AUTHOR("Benjamin Larsson <benjamin.larsson@genexis.eu>");
+MODULE_AUTHOR("Markus Gothe <markus.gothe@genexis.eu>");
+MODULE_DESCRIPTION("Pinctrl driver for Airoha SoC");
-- 
2.46.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: [PATCH 2/2] pinctrl: airoha: Add support for EN7581 SoC
  2024-08-11 16:12 ` [PATCH 2/2] pinctrl: airoha: Add support for EN7581 SoC Lorenzo Bianconi
@ 2024-08-11 21:08   ` kernel test robot
  2024-08-11 21:49   ` kernel test robot
  2024-08-11 21:59   ` kernel test robot
  2 siblings, 0 replies; 19+ messages in thread
From: kernel test robot @ 2024-08-11 21:08 UTC (permalink / raw)
  To: Lorenzo Bianconi, linux-gpio
  Cc: oe-kbuild-all, linus.walleij, sean.wang, linux-mediatek,
	lorenzo.bianconi83, krzk+dt, robh, devicetree, linux-arm-kernel,
	upstream, angelogioacchino.delregno, benjamin.larsson, conor+dt,
	ansuelsmth

Hi Lorenzo,

kernel test robot noticed the following build warnings:

[auto build test WARNING on linusw-pinctrl/devel]
[also build test WARNING on linusw-pinctrl/for-next linus/master v6.11-rc2 next-20240809]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Lorenzo-Bianconi/dt-bindings-pinctrl-airoha-Add-EN7581-pinctrl-controller/20240812-001436
base:   https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl.git devel
patch link:    https://lore.kernel.org/r/c69c4a9b8e57eebdde0521731b8cd9f92ed4891b.1723392444.git.lorenzo%40kernel.org
patch subject: [PATCH 2/2] pinctrl: airoha: Add support for EN7581 SoC
config: m68k-allmodconfig (https://download.01.org/0day-ci/archive/20240812/202408120430.3N4wwLLo-lkp@intel.com/config)
compiler: m68k-linux-gcc (GCC) 14.1.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240812/202408120430.3N4wwLLo-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202408120430.3N4wwLLo-lkp@intel.com/

All warnings (new ones prefixed by >>):

>> drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
    1922 | static const struct airoha_pinctrl_func airoha_pinctrl_funcs[] = {
         |                                                                  ^
>> drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
>> drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
>> drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
>> drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
>> drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
>> drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
>> drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
>> drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
>> drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
>> drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
>> drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
>> drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
>> drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
>> drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
>> drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
>> drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
>> drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
>> drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
>> drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   In file included from include/linux/printk.h:574,
                    from include/asm-generic/bug.h:22,
                    from arch/m68k/include/asm/bug.h:32,
                    from include/linux/bug.h:5,
                    from include/linux/thread_info.h:13,
                    from include/asm-generic/preempt.h:5,
                    from ./arch/m68k/include/generated/asm/preempt.h:1,
                    from include/linux/preempt.h:79,
                    from include/linux/spinlock.h:56,
                    from include/linux/irq.h:14,
                    from include/linux/irqchip/chained_irq.h:10,
                    from include/linux/gpio/driver.h:8,
                    from drivers/pinctrl/mediatek/pinctrl-airoha.c:9:
   drivers/pinctrl/mediatek/pinctrl-airoha.c: In function 'airoha_pinmux_set_mux':
   drivers/pinctrl/mediatek/pinctrl-airoha.c:2279:21: error: 'struct function_desc' has no member named 'name'
    2279 |                 desc->name, grp->grp.name);
         |                     ^~
   include/linux/dynamic_debug.h:224:29: note: in definition of macro '__dynamic_func_call_cls'
     224 |                 func(&id, ##__VA_ARGS__);                       \
         |                             ^~~~~~~~~~~
   include/linux/dynamic_debug.h:250:9: note: in expansion of macro '_dynamic_func_call_cls'
     250 |         _dynamic_func_call_cls(_DPRINTK_CLASS_DFLT, fmt, func, ##__VA_ARGS__)
         |         ^~~~~~~~~~~~~~~~~~~~~~
   include/linux/dynamic_debug.h:273:9: note: in expansion of macro '_dynamic_func_call'
     273 |         _dynamic_func_call(fmt, __dynamic_dev_dbg,              \
         |         ^~~~~~~~~~~~~~~~~~
   include/linux/dev_printk.h:165:9: note: in expansion of macro 'dynamic_dev_dbg'
     165 |         dynamic_dev_dbg(dev, dev_fmt(fmt), ##__VA_ARGS__)
         |         ^~~~~~~~~~~~~~~
   drivers/pinctrl/mediatek/pinctrl-airoha.c:2278:9: note: in expansion of macro 'dev_dbg'
    2278 |         dev_dbg(pctrl_dev->dev, "enable function %s group %s\n",
         |         ^~~~~~~
   drivers/pinctrl/mediatek/pinctrl-airoha.c: In function 'airoha_pinctrl_get_conf':
   drivers/pinctrl/mediatek/pinctrl-airoha.c:2359:38: error: implicit declaration of function '__bf_shf' [-Wimplicit-function-declaration]
    2359 |         *val = (*val & reg->mask) >> __bf_shf(reg->mask);
         |                                      ^~~~~~~~
   drivers/pinctrl/mediatek/pinctrl-airoha.c: In function 'airoha_pinctrl_probe':
   drivers/pinctrl/mediatek/pinctrl-airoha.c:2946:61: error: 'const struct function_desc' has no member named 'name'
    2946 |                                                   func->desc.name,
         |                                                             ^
   drivers/pinctrl/mediatek/pinctrl-airoha.c:2947:61: error: 'const struct function_desc' has no member named 'group_names'
    2947 |                                                   func->desc.group_names,
         |                                                             ^
   drivers/pinctrl/mediatek/pinctrl-airoha.c:2948:61: error: 'const struct function_desc' has no member named 'num_group_names'
    2948 |                                                   func->desc.num_group_names,
         |                                                             ^
   In file included from include/linux/device.h:15,
                    from include/linux/platform_device.h:13,
                    from drivers/pinctrl/mediatek/pinctrl-airoha.c:22:
   drivers/pinctrl/mediatek/pinctrl-airoha.c:2952:43: error: 'const struct function_desc' has no member named 'name'
    2952 |                                 func->desc.name);
         |                                           ^
   include/linux/dev_printk.h:110:37: note: in definition of macro 'dev_printk_index_wrap'
     110 |                 _p_func(dev, fmt, ##__VA_ARGS__);                       \
         |                                     ^~~~~~~~~~~
   drivers/pinctrl/mediatek/pinctrl-airoha.c:2951:25: note: in expansion of macro 'dev_err'
    2951 |                         dev_err(&pdev->dev, "Failed to register function %s\n",
         |                         ^~~~~~~


vim +1922 drivers/pinctrl/mediatek/pinctrl-airoha.c

  1921	
> 1922	static const struct airoha_pinctrl_func airoha_pinctrl_funcs[] = {
  1923		PINCTRL_FUNC_DESC(pon),
  1924		PINCTRL_FUNC_DESC(tod_1pps),
  1925		PINCTRL_FUNC_DESC(sipo),
  1926		PINCTRL_FUNC_DESC(mdio),
  1927		PINCTRL_FUNC_DESC(uart),
  1928		PINCTRL_FUNC_DESC(i2c),
  1929		PINCTRL_FUNC_DESC(jtag),
  1930		PINCTRL_FUNC_DESC(pcm),
  1931		PINCTRL_FUNC_DESC(spi),
  1932		PINCTRL_FUNC_DESC(pcm_spi),
  1933		PINCTRL_FUNC_DESC(i2s),
  1934		PINCTRL_FUNC_DESC(emmc),
  1935		PINCTRL_FUNC_DESC(pnand),
  1936		PINCTRL_FUNC_DESC(pcie_reset),
  1937		PINCTRL_FUNC_DESC(pwm),
  1938		PINCTRL_FUNC_DESC(phy1_led0),
  1939		PINCTRL_FUNC_DESC(phy2_led0),
  1940		PINCTRL_FUNC_DESC(phy3_led0),
  1941		PINCTRL_FUNC_DESC(phy4_led0),
  1942		PINCTRL_FUNC_DESC(phy1_led1),
  1943		PINCTRL_FUNC_DESC(phy2_led1),
  1944		PINCTRL_FUNC_DESC(phy3_led1),
  1945		PINCTRL_FUNC_DESC(phy4_led1),
  1946	};
  1947	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 2/2] pinctrl: airoha: Add support for EN7581 SoC
  2024-08-11 16:12 ` [PATCH 2/2] pinctrl: airoha: Add support for EN7581 SoC Lorenzo Bianconi
  2024-08-11 21:08   ` kernel test robot
@ 2024-08-11 21:49   ` kernel test robot
  2024-08-11 21:59   ` kernel test robot
  2 siblings, 0 replies; 19+ messages in thread
From: kernel test robot @ 2024-08-11 21:49 UTC (permalink / raw)
  To: Lorenzo Bianconi, linux-gpio
  Cc: llvm, oe-kbuild-all, linus.walleij, sean.wang, linux-mediatek,
	lorenzo.bianconi83, krzk+dt, robh, devicetree, linux-arm-kernel,
	upstream, angelogioacchino.delregno, benjamin.larsson, conor+dt,
	ansuelsmth

Hi Lorenzo,

kernel test robot noticed the following build errors:

[auto build test ERROR on linusw-pinctrl/devel]
[also build test ERROR on linusw-pinctrl/for-next linus/master v6.11-rc2 next-20240809]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Lorenzo-Bianconi/dt-bindings-pinctrl-airoha-Add-EN7581-pinctrl-controller/20240812-001436
base:   https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl.git devel
patch link:    https://lore.kernel.org/r/c69c4a9b8e57eebdde0521731b8cd9f92ed4891b.1723392444.git.lorenzo%40kernel.org
patch subject: [PATCH 2/2] pinctrl: airoha: Add support for EN7581 SoC
config: hexagon-allmodconfig (https://download.01.org/0day-ci/archive/20240812/202408120556.EjlJhjXg-lkp@intel.com/config)
compiler: clang version 20.0.0git (https://github.com/llvm/llvm-project f86594788ce93b696675c94f54016d27a6c21d18)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240812/202408120556.EjlJhjXg-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202408120556.EjlJhjXg-lkp@intel.com/

All error/warnings (new ones prefixed by >>):

   In file included from drivers/pinctrl/mediatek/pinctrl-airoha.c:9:
   In file included from include/linux/gpio/driver.h:8:
   In file included from include/linux/irqchip/chained_irq.h:10:
   In file included from include/linux/irq.h:20:
   In file included from include/linux/io.h:14:
   In file included from arch/hexagon/include/asm/io.h:328:
   include/asm-generic/io.h:548:31: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     548 |         val = __raw_readb(PCI_IOBASE + addr);
         |                           ~~~~~~~~~~ ^
   include/asm-generic/io.h:561:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     561 |         val = __le16_to_cpu((__le16 __force)__raw_readw(PCI_IOBASE + addr));
         |                                                         ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/little_endian.h:37:51: note: expanded from macro '__le16_to_cpu'
      37 | #define __le16_to_cpu(x) ((__force __u16)(__le16)(x))
         |                                                   ^
   In file included from drivers/pinctrl/mediatek/pinctrl-airoha.c:9:
   In file included from include/linux/gpio/driver.h:8:
   In file included from include/linux/irqchip/chained_irq.h:10:
   In file included from include/linux/irq.h:20:
   In file included from include/linux/io.h:14:
   In file included from arch/hexagon/include/asm/io.h:328:
   include/asm-generic/io.h:574:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     574 |         val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr));
         |                                                         ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/little_endian.h:35:51: note: expanded from macro '__le32_to_cpu'
      35 | #define __le32_to_cpu(x) ((__force __u32)(__le32)(x))
         |                                                   ^
   In file included from drivers/pinctrl/mediatek/pinctrl-airoha.c:9:
   In file included from include/linux/gpio/driver.h:8:
   In file included from include/linux/irqchip/chained_irq.h:10:
   In file included from include/linux/irq.h:20:
   In file included from include/linux/io.h:14:
   In file included from arch/hexagon/include/asm/io.h:328:
   include/asm-generic/io.h:585:33: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     585 |         __raw_writeb(value, PCI_IOBASE + addr);
         |                             ~~~~~~~~~~ ^
   include/asm-generic/io.h:595:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     595 |         __raw_writew((u16 __force)cpu_to_le16(value), PCI_IOBASE + addr);
         |                                                       ~~~~~~~~~~ ^
   include/asm-generic/io.h:605:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     605 |         __raw_writel((u32 __force)cpu_to_le32(value), PCI_IOBASE + addr);
         |                                                       ~~~~~~~~~~ ^
>> drivers/pinctrl/mediatek/pinctrl-airoha.c:1923:2: warning: suggest braces around initialization of subobject [-Wmissing-braces]
    1923 |         PINCTRL_FUNC_DESC(pon),
         |         ^~~~~~~~~~~~~~~~~~~~~~
   drivers/pinctrl/mediatek/pinctrl-airoha.c:33:13: note: expanded from macro 'PINCTRL_FUNC_DESC'
      33 |                 .desc = { #id, id##_groups, ARRAY_SIZE(id##_groups) },  \
         |                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   <scratch space>:279:1: note: expanded from here
     279 | "pon"
         | ^
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1924:2: warning: suggest braces around initialization of subobject [-Wmissing-braces]
    1924 |         PINCTRL_FUNC_DESC(tod_1pps),
         |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/pinctrl/mediatek/pinctrl-airoha.c:33:13: note: expanded from macro 'PINCTRL_FUNC_DESC'
      33 |                 .desc = { #id, id##_groups, ARRAY_SIZE(id##_groups) },  \
         |                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   <scratch space>:284:1: note: expanded from here
     284 | "tod_1pps"
         | ^
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1925:2: warning: suggest braces around initialization of subobject [-Wmissing-braces]
    1925 |         PINCTRL_FUNC_DESC(sipo),
         |         ^~~~~~~~~~~~~~~~~~~~~~~
   drivers/pinctrl/mediatek/pinctrl-airoha.c:33:13: note: expanded from macro 'PINCTRL_FUNC_DESC'
      33 |                 .desc = { #id, id##_groups, ARRAY_SIZE(id##_groups) },  \
         |                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   <scratch space>:289:1: note: expanded from here
     289 | "sipo"
         | ^
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1926:2: warning: suggest braces around initialization of subobject [-Wmissing-braces]
    1926 |         PINCTRL_FUNC_DESC(mdio),
         |         ^~~~~~~~~~~~~~~~~~~~~~~
   drivers/pinctrl/mediatek/pinctrl-airoha.c:33:13: note: expanded from macro 'PINCTRL_FUNC_DESC'
      33 |                 .desc = { #id, id##_groups, ARRAY_SIZE(id##_groups) },  \
         |                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   <scratch space>:294:1: note: expanded from here
     294 | "mdio"
         | ^
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1927:2: warning: suggest braces around initialization of subobject [-Wmissing-braces]
    1927 |         PINCTRL_FUNC_DESC(uart),
         |         ^~~~~~~~~~~~~~~~~~~~~~~
   drivers/pinctrl/mediatek/pinctrl-airoha.c:33:13: note: expanded from macro 'PINCTRL_FUNC_DESC'
      33 |                 .desc = { #id, id##_groups, ARRAY_SIZE(id##_groups) },  \
         |                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   <scratch space>:299:1: note: expanded from here
     299 | "uart"
         | ^
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1928:2: warning: suggest braces around initialization of subobject [-Wmissing-braces]
    1928 |         PINCTRL_FUNC_DESC(i2c),
         |         ^~~~~~~~~~~~~~~~~~~~~~
   drivers/pinctrl/mediatek/pinctrl-airoha.c:33:13: note: expanded from macro 'PINCTRL_FUNC_DESC'
      33 |                 .desc = { #id, id##_groups, ARRAY_SIZE(id##_groups) },  \
         |                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   <scratch space>:304:1: note: expanded from here
     304 | "i2c"
         | ^
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1929:2: warning: suggest braces around initialization of subobject [-Wmissing-braces]
    1929 |         PINCTRL_FUNC_DESC(jtag),
         |         ^~~~~~~~~~~~~~~~~~~~~~~
   drivers/pinctrl/mediatek/pinctrl-airoha.c:33:13: note: expanded from macro 'PINCTRL_FUNC_DESC'
      33 |                 .desc = { #id, id##_groups, ARRAY_SIZE(id##_groups) },  \
         |                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   <scratch space>:309:1: note: expanded from here
     309 | "jtag"
         | ^
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1930:2: warning: suggest braces around initialization of subobject [-Wmissing-braces]
    1930 |         PINCTRL_FUNC_DESC(pcm),
         |         ^~~~~~~~~~~~~~~~~~~~~~
   drivers/pinctrl/mediatek/pinctrl-airoha.c:33:13: note: expanded from macro 'PINCTRL_FUNC_DESC'
      33 |                 .desc = { #id, id##_groups, ARRAY_SIZE(id##_groups) },  \
         |                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   <scratch space>:314:1: note: expanded from here
     314 | "pcm"
         | ^
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1931:2: warning: suggest braces around initialization of subobject [-Wmissing-braces]
    1931 |         PINCTRL_FUNC_DESC(spi),
         |         ^~~~~~~~~~~~~~~~~~~~~~
   drivers/pinctrl/mediatek/pinctrl-airoha.c:33:13: note: expanded from macro 'PINCTRL_FUNC_DESC'
      33 |                 .desc = { #id, id##_groups, ARRAY_SIZE(id##_groups) },  \
         |                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   <scratch space>:319:1: note: expanded from here
     319 | "spi"
         | ^
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1932:2: warning: suggest braces around initialization of subobject [-Wmissing-braces]
    1932 |         PINCTRL_FUNC_DESC(pcm_spi),
         |         ^~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/pinctrl/mediatek/pinctrl-airoha.c:33:13: note: expanded from macro 'PINCTRL_FUNC_DESC'
      33 |                 .desc = { #id, id##_groups, ARRAY_SIZE(id##_groups) },  \
         |                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   <scratch space>:324:1: note: expanded from here
     324 | "pcm_spi"
         | ^
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1933:2: warning: suggest braces around initialization of subobject [-Wmissing-braces]
    1933 |         PINCTRL_FUNC_DESC(i2s),
         |         ^~~~~~~~~~~~~~~~~~~~~~
   drivers/pinctrl/mediatek/pinctrl-airoha.c:33:13: note: expanded from macro 'PINCTRL_FUNC_DESC'
      33 |                 .desc = { #id, id##_groups, ARRAY_SIZE(id##_groups) },  \
         |                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   <scratch space>:329:1: note: expanded from here
     329 | "i2s"
         | ^
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1934:2: warning: suggest braces around initialization of subobject [-Wmissing-braces]
    1934 |         PINCTRL_FUNC_DESC(emmc),
--
         | ^
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1935:2: warning: suggest braces around initialization of subobject [-Wmissing-braces]
    1935 |         PINCTRL_FUNC_DESC(pnand),
         |         ^~~~~~~~~~~~~~~~~~~~~~~~
   drivers/pinctrl/mediatek/pinctrl-airoha.c:33:13: note: expanded from macro 'PINCTRL_FUNC_DESC'
      33 |                 .desc = { #id, id##_groups, ARRAY_SIZE(id##_groups) },  \
         |                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   <scratch space>:339:1: note: expanded from here
     339 | "pnand"
         | ^
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1936:2: warning: suggest braces around initialization of subobject [-Wmissing-braces]
    1936 |         PINCTRL_FUNC_DESC(pcie_reset),
         |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/pinctrl/mediatek/pinctrl-airoha.c:33:13: note: expanded from macro 'PINCTRL_FUNC_DESC'
      33 |                 .desc = { #id, id##_groups, ARRAY_SIZE(id##_groups) },  \
         |                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   <scratch space>:344:1: note: expanded from here
     344 | "pcie_reset"
         | ^
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1937:2: warning: suggest braces around initialization of subobject [-Wmissing-braces]
    1937 |         PINCTRL_FUNC_DESC(pwm),
         |         ^~~~~~~~~~~~~~~~~~~~~~
   drivers/pinctrl/mediatek/pinctrl-airoha.c:33:13: note: expanded from macro 'PINCTRL_FUNC_DESC'
      33 |                 .desc = { #id, id##_groups, ARRAY_SIZE(id##_groups) },  \
         |                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   <scratch space>:349:1: note: expanded from here
     349 | "pwm"
         | ^
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1938:2: warning: suggest braces around initialization of subobject [-Wmissing-braces]
    1938 |         PINCTRL_FUNC_DESC(phy1_led0),
         |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/pinctrl/mediatek/pinctrl-airoha.c:33:13: note: expanded from macro 'PINCTRL_FUNC_DESC'
      33 |                 .desc = { #id, id##_groups, ARRAY_SIZE(id##_groups) },  \
         |                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   <scratch space>:354:1: note: expanded from here
     354 | "phy1_led0"
         | ^
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1939:2: warning: suggest braces around initialization of subobject [-Wmissing-braces]
    1939 |         PINCTRL_FUNC_DESC(phy2_led0),
         |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/pinctrl/mediatek/pinctrl-airoha.c:33:13: note: expanded from macro 'PINCTRL_FUNC_DESC'
      33 |                 .desc = { #id, id##_groups, ARRAY_SIZE(id##_groups) },  \
         |                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   <scratch space>:359:1: note: expanded from here
     359 | "phy2_led0"
         | ^
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1940:2: warning: suggest braces around initialization of subobject [-Wmissing-braces]
    1940 |         PINCTRL_FUNC_DESC(phy3_led0),
         |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/pinctrl/mediatek/pinctrl-airoha.c:33:13: note: expanded from macro 'PINCTRL_FUNC_DESC'
      33 |                 .desc = { #id, id##_groups, ARRAY_SIZE(id##_groups) },  \
         |                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   <scratch space>:364:1: note: expanded from here
     364 | "phy3_led0"
         | ^
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1941:2: warning: suggest braces around initialization of subobject [-Wmissing-braces]
    1941 |         PINCTRL_FUNC_DESC(phy4_led0),
         |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/pinctrl/mediatek/pinctrl-airoha.c:33:13: note: expanded from macro 'PINCTRL_FUNC_DESC'
      33 |                 .desc = { #id, id##_groups, ARRAY_SIZE(id##_groups) },  \
         |                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   <scratch space>:369:1: note: expanded from here
     369 | "phy4_led0"
         | ^
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1942:2: warning: suggest braces around initialization of subobject [-Wmissing-braces]
    1942 |         PINCTRL_FUNC_DESC(phy1_led1),
         |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/pinctrl/mediatek/pinctrl-airoha.c:33:13: note: expanded from macro 'PINCTRL_FUNC_DESC'
      33 |                 .desc = { #id, id##_groups, ARRAY_SIZE(id##_groups) },  \
         |                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   <scratch space>:374:1: note: expanded from here
     374 | "phy1_led1"
         | ^
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1943:2: warning: suggest braces around initialization of subobject [-Wmissing-braces]
    1943 |         PINCTRL_FUNC_DESC(phy2_led1),
         |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/pinctrl/mediatek/pinctrl-airoha.c:33:13: note: expanded from macro 'PINCTRL_FUNC_DESC'
      33 |                 .desc = { #id, id##_groups, ARRAY_SIZE(id##_groups) },  \
         |                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   <scratch space>:379:1: note: expanded from here
     379 | "phy2_led1"
         | ^
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1944:2: warning: suggest braces around initialization of subobject [-Wmissing-braces]
    1944 |         PINCTRL_FUNC_DESC(phy3_led1),
         |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/pinctrl/mediatek/pinctrl-airoha.c:33:13: note: expanded from macro 'PINCTRL_FUNC_DESC'
      33 |                 .desc = { #id, id##_groups, ARRAY_SIZE(id##_groups) },  \
         |                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   <scratch space>:384:1: note: expanded from here
     384 | "phy3_led1"
         | ^
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1945:2: warning: suggest braces around initialization of subobject [-Wmissing-braces]
    1945 |         PINCTRL_FUNC_DESC(phy4_led1),
         |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/pinctrl/mediatek/pinctrl-airoha.c:33:13: note: expanded from macro 'PINCTRL_FUNC_DESC'
      33 |                 .desc = { #id, id##_groups, ARRAY_SIZE(id##_groups) },  \
         |                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   <scratch space>:389:1: note: expanded from here
     389 | "phy4_led1"
         | ^
>> drivers/pinctrl/mediatek/pinctrl-airoha.c:2279:9: error: no member named 'name' in 'struct function_desc'
    2279 |                 desc->name, grp->grp.name);
         |                 ~~~~  ^
   include/linux/dev_printk.h:165:39: note: expanded from macro 'dev_dbg'
     165 |         dynamic_dev_dbg(dev, dev_fmt(fmt), ##__VA_ARGS__)
         |                                              ^~~~~~~~~~~
   include/linux/dynamic_debug.h:274:19: note: expanded from macro 'dynamic_dev_dbg'
     274 |                            dev, fmt, ##__VA_ARGS__)
         |                                        ^~~~~~~~~~~
   include/linux/dynamic_debug.h:250:59: note: expanded from macro '_dynamic_func_call'
     250 |         _dynamic_func_call_cls(_DPRINTK_CLASS_DFLT, fmt, func, ##__VA_ARGS__)
         |                                                                  ^~~~~~~~~~~
   include/linux/dynamic_debug.h:248:65: note: expanded from macro '_dynamic_func_call_cls'
     248 |         __dynamic_func_call_cls(__UNIQUE_ID(ddebug), cls, fmt, func, ##__VA_ARGS__)
         |                                                                        ^~~~~~~~~~~
   include/linux/dynamic_debug.h:224:15: note: expanded from macro '__dynamic_func_call_cls'
     224 |                 func(&id, ##__VA_ARGS__);                       \
         |                             ^~~~~~~~~~~
>> drivers/pinctrl/mediatek/pinctrl-airoha.c:2359:31: error: call to undeclared function '__bf_shf'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
    2359 |         *val = (*val & reg->mask) >> __bf_shf(reg->mask);
         |                                      ^
   drivers/pinctrl/mediatek/pinctrl-airoha.c:2376:14: error: call to undeclared function '__bf_shf'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
    2376 |                            val << __bf_shf(reg->mask));
         |                                   ^
   drivers/pinctrl/mediatek/pinctrl-airoha.c:2946:20: error: no member named 'name' in 'struct function_desc'
    2946 |                                                   func->desc.name,
         |                                                   ~~~~~~~~~~ ^
>> drivers/pinctrl/mediatek/pinctrl-airoha.c:2947:20: error: no member named 'group_names' in 'struct function_desc'
    2947 |                                                   func->desc.group_names,
         |                                                   ~~~~~~~~~~ ^
>> drivers/pinctrl/mediatek/pinctrl-airoha.c:2948:20: error: no member named 'num_group_names' in 'struct function_desc'
    2948 |                                                   func->desc.num_group_names,
         |                                                   ~~~~~~~~~~ ^
   drivers/pinctrl/mediatek/pinctrl-airoha.c:2952:16: error: no member named 'name' in 'struct function_desc'
    2952 |                                 func->desc.name);
         |                                 ~~~~~~~~~~ ^
   include/linux/dev_printk.h:154:65: note: expanded from macro 'dev_err'
     154 |         dev_printk_index_wrap(_dev_err, KERN_ERR, dev, dev_fmt(fmt), ##__VA_ARGS__)
         |                                                                        ^~~~~~~~~~~
   include/linux/dev_printk.h:110:23: note: expanded from macro 'dev_printk_index_wrap'
     110 |                 _p_func(dev, fmt, ##__VA_ARGS__);                       \
         |                                     ^~~~~~~~~~~
   29 warnings and 7 errors generated.


vim +2279 drivers/pinctrl/mediatek/pinctrl-airoha.c

  2259	
  2260	static int airoha_pinmux_set_mux(struct pinctrl_dev *pctrl_dev,
  2261					 unsigned int selector,
  2262					 unsigned int group)
  2263	{
  2264		struct airoha_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
  2265		const struct airoha_pinctrl_func *func;
  2266		struct function_desc *desc;
  2267		struct group_desc *grp;
  2268		int i;
  2269	
  2270		desc = pinmux_generic_get_function(pctrl_dev, selector);
  2271		if (!desc)
  2272			return -EINVAL;
  2273	
  2274		grp = pinctrl_generic_get_group(pctrl_dev, group);
  2275		if (!grp)
  2276			return -EINVAL;
  2277	
  2278		dev_dbg(pctrl_dev->dev, "enable function %s group %s\n",
> 2279			desc->name, grp->grp.name);
  2280	
  2281		func = desc->data;
  2282		for (i = 0; i < func->group_size; i++) {
  2283			const struct airoha_pinctrl_func_group *group;
  2284			int j;
  2285	
  2286			group = &func->groups[i];
  2287			if (strcmp(group->name, grp->grp.name))
  2288				continue;
  2289	
  2290			for (j = 0; j < group->regmap_size; j++) {
  2291				void __iomem *base;
  2292	
  2293				base = pinctrl->regs.mux[group->regmap[j].mux];
  2294				airoha_pinctrl_rmw(pinctrl,
  2295						   base + group->regmap[j].offset,
  2296						   group->regmap[j].mask,
  2297						   group->regmap[j].val);
  2298			}
  2299			return 0;
  2300		}
  2301	
  2302		return -EINVAL;
  2303	}
  2304	
  2305	static int airoha_pinmux_gpio_set_direction(struct pinctrl_dev *pctrl_dev,
  2306						    struct pinctrl_gpio_range *range,
  2307						    unsigned int pin, bool input)
  2308	{
  2309		struct airoha_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
  2310		int gpio = pin - range->pin_base;
  2311	
  2312		airoha_pinctrl_gpio_set_direction(pinctrl, gpio, input);
  2313	
  2314		return 0;
  2315	}
  2316	
  2317	static int airoha_pinctrl_get_gpio_from_pin(struct pinctrl_dev *pctrl_dev,
  2318						    int pin)
  2319	{
  2320		struct pinctrl_gpio_range *range;
  2321		int gpio;
  2322	
  2323		range = pinctrl_find_gpio_range_from_pin_nolock(pctrl_dev, pin);
  2324		if (!range)
  2325			return -EINVAL;
  2326	
  2327		gpio = pin - range->pin_base;
  2328		if (gpio < 0)
  2329			return -EINVAL;
  2330	
  2331		return gpio;
  2332	}
  2333	
  2334	static const struct airoha_pinctrl_reg *
  2335	airoha_pinctrl_get_conf_reg(const struct airoha_pinctrl_conf *conf,
  2336				    int conf_size, int pin)
  2337	{
  2338		int i;
  2339	
  2340		for (i = 0; i < conf_size; i++) {
  2341			if (conf[i].pin == pin)
  2342				return &conf[i].reg;
  2343		}
  2344	
  2345		return NULL;
  2346	}
  2347	
  2348	static int airoha_pinctrl_get_conf(void __iomem *base,
  2349					   const struct airoha_pinctrl_conf *conf,
  2350					   int conf_size, int pin, u32 *val)
  2351	{
  2352		const struct airoha_pinctrl_reg *reg;
  2353	
  2354		reg = airoha_pinctrl_get_conf_reg(conf, conf_size, pin);
  2355		if (!reg)
  2356			return -EINVAL;
  2357	
  2358		*val = readl(base + reg->offset);
> 2359		*val = (*val & reg->mask) >> __bf_shf(reg->mask);
  2360	
  2361		return 0;
  2362	}
  2363	
  2364	static int airoha_pinctrl_set_conf(struct airoha_pinctrl *pinctrl,
  2365					   void __iomem *base,
  2366					   const struct airoha_pinctrl_conf *conf,
  2367					   int conf_size, int pin, u32 val)
  2368	{
  2369		const struct airoha_pinctrl_reg *reg = NULL;
  2370	
  2371		reg = airoha_pinctrl_get_conf_reg(conf, conf_size, pin);
  2372		if (!reg)
  2373			return -EINVAL;
  2374	
  2375		airoha_pinctrl_rmw(pinctrl, base + reg->offset, reg->mask,
> 2376				   val << __bf_shf(reg->mask));
  2377	
  2378		return 0;
  2379	}
  2380	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 2/2] pinctrl: airoha: Add support for EN7581 SoC
  2024-08-11 16:12 ` [PATCH 2/2] pinctrl: airoha: Add support for EN7581 SoC Lorenzo Bianconi
  2024-08-11 21:08   ` kernel test robot
  2024-08-11 21:49   ` kernel test robot
@ 2024-08-11 21:59   ` kernel test robot
  2 siblings, 0 replies; 19+ messages in thread
From: kernel test robot @ 2024-08-11 21:59 UTC (permalink / raw)
  To: Lorenzo Bianconi, linux-gpio
  Cc: oe-kbuild-all, linus.walleij, sean.wang, linux-mediatek,
	lorenzo.bianconi83, krzk+dt, robh, devicetree, linux-arm-kernel,
	upstream, angelogioacchino.delregno, benjamin.larsson, conor+dt,
	ansuelsmth

Hi Lorenzo,

kernel test robot noticed the following build errors:

[auto build test ERROR on linusw-pinctrl/devel]
[also build test ERROR on linusw-pinctrl/for-next linus/master v6.11-rc2 next-20240809]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Lorenzo-Bianconi/dt-bindings-pinctrl-airoha-Add-EN7581-pinctrl-controller/20240812-001436
base:   https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl.git devel
patch link:    https://lore.kernel.org/r/c69c4a9b8e57eebdde0521731b8cd9f92ed4891b.1723392444.git.lorenzo%40kernel.org
patch subject: [PATCH 2/2] pinctrl: airoha: Add support for EN7581 SoC
config: alpha-allyesconfig (https://download.01.org/0day-ci/archive/20240812/202408120527.crbqc6PI-lkp@intel.com/config)
compiler: alpha-linux-gcc (GCC) 13.3.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240812/202408120527.crbqc6PI-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202408120527.crbqc6PI-lkp@intel.com/

All errors (new ones prefixed by >>):

   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
    1922 | static const struct airoha_pinctrl_func airoha_pinctrl_funcs[] = {
         |                                                                  ^
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   drivers/pinctrl/mediatek/pinctrl-airoha.c:1922:66: warning: missing braces around initializer [-Wmissing-braces]
   In file included from include/linux/printk.h:574,
                    from include/asm-generic/bug.h:22,
                    from arch/alpha/include/asm/bug.h:23,
                    from include/linux/bug.h:5,
                    from include/linux/thread_info.h:13,
                    from include/asm-generic/preempt.h:5,
                    from ./arch/alpha/include/generated/asm/preempt.h:1,
                    from include/linux/preempt.h:79,
                    from include/linux/spinlock.h:56,
                    from include/linux/irq.h:14,
                    from include/linux/irqchip/chained_irq.h:10,
                    from include/linux/gpio/driver.h:8,
                    from drivers/pinctrl/mediatek/pinctrl-airoha.c:9:
   drivers/pinctrl/mediatek/pinctrl-airoha.c: In function 'airoha_pinmux_set_mux':
>> drivers/pinctrl/mediatek/pinctrl-airoha.c:2279:21: error: 'struct function_desc' has no member named 'name'
    2279 |                 desc->name, grp->grp.name);
         |                     ^~
   include/linux/dynamic_debug.h:224:29: note: in definition of macro '__dynamic_func_call_cls'
     224 |                 func(&id, ##__VA_ARGS__);                       \
         |                             ^~~~~~~~~~~
   include/linux/dynamic_debug.h:250:9: note: in expansion of macro '_dynamic_func_call_cls'
     250 |         _dynamic_func_call_cls(_DPRINTK_CLASS_DFLT, fmt, func, ##__VA_ARGS__)
         |         ^~~~~~~~~~~~~~~~~~~~~~
   include/linux/dynamic_debug.h:273:9: note: in expansion of macro '_dynamic_func_call'
     273 |         _dynamic_func_call(fmt, __dynamic_dev_dbg,              \
         |         ^~~~~~~~~~~~~~~~~~
   include/linux/dev_printk.h:165:9: note: in expansion of macro 'dynamic_dev_dbg'
     165 |         dynamic_dev_dbg(dev, dev_fmt(fmt), ##__VA_ARGS__)
         |         ^~~~~~~~~~~~~~~
   drivers/pinctrl/mediatek/pinctrl-airoha.c:2278:9: note: in expansion of macro 'dev_dbg'
    2278 |         dev_dbg(pctrl_dev->dev, "enable function %s group %s\n",
         |         ^~~~~~~
   drivers/pinctrl/mediatek/pinctrl-airoha.c: In function 'airoha_pinctrl_get_conf':
>> drivers/pinctrl/mediatek/pinctrl-airoha.c:2359:38: error: implicit declaration of function '__bf_shf' [-Werror=implicit-function-declaration]
    2359 |         *val = (*val & reg->mask) >> __bf_shf(reg->mask);
         |                                      ^~~~~~~~
   drivers/pinctrl/mediatek/pinctrl-airoha.c: In function 'airoha_pinctrl_probe':
>> drivers/pinctrl/mediatek/pinctrl-airoha.c:2946:61: error: 'const struct function_desc' has no member named 'name'
    2946 |                                                   func->desc.name,
         |                                                             ^
>> drivers/pinctrl/mediatek/pinctrl-airoha.c:2947:61: error: 'const struct function_desc' has no member named 'group_names'
    2947 |                                                   func->desc.group_names,
         |                                                             ^
>> drivers/pinctrl/mediatek/pinctrl-airoha.c:2948:61: error: 'const struct function_desc' has no member named 'num_group_names'
    2948 |                                                   func->desc.num_group_names,
         |                                                             ^
   In file included from include/linux/device.h:15,
                    from include/linux/platform_device.h:13,
                    from drivers/pinctrl/mediatek/pinctrl-airoha.c:22:
   drivers/pinctrl/mediatek/pinctrl-airoha.c:2952:43: error: 'const struct function_desc' has no member named 'name'
    2952 |                                 func->desc.name);
         |                                           ^
   include/linux/dev_printk.h:110:37: note: in definition of macro 'dev_printk_index_wrap'
     110 |                 _p_func(dev, fmt, ##__VA_ARGS__);                       \
         |                                     ^~~~~~~~~~~
   drivers/pinctrl/mediatek/pinctrl-airoha.c:2951:25: note: in expansion of macro 'dev_err'
    2951 |                         dev_err(&pdev->dev, "Failed to register function %s\n",
         |                         ^~~~~~~
   cc1: some warnings being treated as errors


vim +2279 drivers/pinctrl/mediatek/pinctrl-airoha.c

  2259	
  2260	static int airoha_pinmux_set_mux(struct pinctrl_dev *pctrl_dev,
  2261					 unsigned int selector,
  2262					 unsigned int group)
  2263	{
  2264		struct airoha_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
  2265		const struct airoha_pinctrl_func *func;
  2266		struct function_desc *desc;
  2267		struct group_desc *grp;
  2268		int i;
  2269	
  2270		desc = pinmux_generic_get_function(pctrl_dev, selector);
  2271		if (!desc)
  2272			return -EINVAL;
  2273	
  2274		grp = pinctrl_generic_get_group(pctrl_dev, group);
  2275		if (!grp)
  2276			return -EINVAL;
  2277	
  2278		dev_dbg(pctrl_dev->dev, "enable function %s group %s\n",
> 2279			desc->name, grp->grp.name);
  2280	
  2281		func = desc->data;
  2282		for (i = 0; i < func->group_size; i++) {
  2283			const struct airoha_pinctrl_func_group *group;
  2284			int j;
  2285	
  2286			group = &func->groups[i];
  2287			if (strcmp(group->name, grp->grp.name))
  2288				continue;
  2289	
  2290			for (j = 0; j < group->regmap_size; j++) {
  2291				void __iomem *base;
  2292	
  2293				base = pinctrl->regs.mux[group->regmap[j].mux];
  2294				airoha_pinctrl_rmw(pinctrl,
  2295						   base + group->regmap[j].offset,
  2296						   group->regmap[j].mask,
  2297						   group->regmap[j].val);
  2298			}
  2299			return 0;
  2300		}
  2301	
  2302		return -EINVAL;
  2303	}
  2304	
  2305	static int airoha_pinmux_gpio_set_direction(struct pinctrl_dev *pctrl_dev,
  2306						    struct pinctrl_gpio_range *range,
  2307						    unsigned int pin, bool input)
  2308	{
  2309		struct airoha_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
  2310		int gpio = pin - range->pin_base;
  2311	
  2312		airoha_pinctrl_gpio_set_direction(pinctrl, gpio, input);
  2313	
  2314		return 0;
  2315	}
  2316	
  2317	static int airoha_pinctrl_get_gpio_from_pin(struct pinctrl_dev *pctrl_dev,
  2318						    int pin)
  2319	{
  2320		struct pinctrl_gpio_range *range;
  2321		int gpio;
  2322	
  2323		range = pinctrl_find_gpio_range_from_pin_nolock(pctrl_dev, pin);
  2324		if (!range)
  2325			return -EINVAL;
  2326	
  2327		gpio = pin - range->pin_base;
  2328		if (gpio < 0)
  2329			return -EINVAL;
  2330	
  2331		return gpio;
  2332	}
  2333	
  2334	static const struct airoha_pinctrl_reg *
  2335	airoha_pinctrl_get_conf_reg(const struct airoha_pinctrl_conf *conf,
  2336				    int conf_size, int pin)
  2337	{
  2338		int i;
  2339	
  2340		for (i = 0; i < conf_size; i++) {
  2341			if (conf[i].pin == pin)
  2342				return &conf[i].reg;
  2343		}
  2344	
  2345		return NULL;
  2346	}
  2347	
  2348	static int airoha_pinctrl_get_conf(void __iomem *base,
  2349					   const struct airoha_pinctrl_conf *conf,
  2350					   int conf_size, int pin, u32 *val)
  2351	{
  2352		const struct airoha_pinctrl_reg *reg;
  2353	
  2354		reg = airoha_pinctrl_get_conf_reg(conf, conf_size, pin);
  2355		if (!reg)
  2356			return -EINVAL;
  2357	
  2358		*val = readl(base + reg->offset);
> 2359		*val = (*val & reg->mask) >> __bf_shf(reg->mask);
  2360	
  2361		return 0;
  2362	}
  2363	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 1/2] dt-bindings: pinctrl: airoha: Add EN7581 pinctrl controller
  2024-08-11 16:12 ` [PATCH 1/2] dt-bindings: pinctrl: airoha: Add EN7581 pinctrl controller Lorenzo Bianconi
@ 2024-08-12  6:48   ` Krzysztof Kozlowski
  2024-08-13  8:06     ` Benjamin Larsson
  2024-08-18 14:20     ` Lorenzo Bianconi
  0 siblings, 2 replies; 19+ messages in thread
From: Krzysztof Kozlowski @ 2024-08-12  6:48 UTC (permalink / raw)
  To: Lorenzo Bianconi, linux-gpio
  Cc: linus.walleij, sean.wang, linux-mediatek, lorenzo.bianconi83,
	krzk+dt, robh, devicetree, linux-arm-kernel, upstream,
	angelogioacchino.delregno, benjamin.larsson, conor+dt, ansuelsmth

On 11/08/2024 18:12, Lorenzo Bianconi wrote:
> Introduce device-tree binding documentation for Airoha EN7581 pinctrl
> controller.
> 
> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
> ---
>  .../pinctrl/airoha,en7581-pinctrl.yaml        | 467 ++++++++++++++++++
>  1 file changed, 467 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/pinctrl/airoha,en7581-pinctrl.yaml
> 
> diff --git a/Documentation/devicetree/bindings/pinctrl/airoha,en7581-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/airoha,en7581-pinctrl.yaml
> new file mode 100644
> index 000000000000..b1f980613864
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pinctrl/airoha,en7581-pinctrl.yaml
> @@ -0,0 +1,467 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/pinctrl/airoha,en7581-pinctrl.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Airoha EN7581 Pin Controller
> +
> +maintainers:
> +  - Lorenzo Bianconi <lorenzo@kernel.org>
> +
> +description:
> +  The Airoha's EN7581 Pin controller is used to control SoC pins.
> +
> +properties:
> +  compatible:
> +    enum:
> +      - airoha,en7581-pinctrl
> +
> +  reg:
> +    items:
> +      - description: IOMUX base address
> +      - description: LED IOMUX base address
> +      - description: GPIO flash mode base address
> +      - description: GPIO flash mode extended base address
> +      - description: IO pin configuration base address
> +      - description: PCIE reset open-drain base address
> +      - description: GPIO bank0 data register base address
> +      - description: GPIO bank1 data register base address
> +      - description: GPIO bank0 first control register base address
> +      - description: GPIO bank0 second control register base address
> +      - description: GPIO bank1 first control register base address
> +      - description: GPIO bank1 second control register base address
> +      - description: GPIO bank0 output enable register base address
> +      - description: GPIO bank1 output enable register base address
> +      - description: GPIO bank0 irq status register base address
> +      - description: GPIO bank1 irq status register base address
> +      - description: GPIO bank0 irq level first control register base address
> +      - description: GPIO bank0 irq level second control register base address
> +      - description: GPIO bank1 irq level first control register base address
> +      - description: GPIO bank1 irq level second control register base address
> +      - description: GPIO bank0 irq edge first control register base address
> +      - description: GPIO bank0 irq edge second control register base address
> +      - description: GPIO bank1 irq edge first control register base address
> +      - description: GPIO bank1 irq edge second control register base address
> +
> +  gpio-controller: true
> +
> +  "#gpio-cells":
> +    const: 2
> +    description:
> +      Number of cells in GPIO specifier. Since the generic GPIO binding is
> +      used, the amount of cells must be specified as 2. See the below mentioned
> +      gpio binding representation for description of particular cells.
> +
> +  gpio-ranges:
> +    maxItems: 1
> +    description:
> +      GPIO valid number range.
> +
> +  interrupt-controller: true
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  "#interrupt-cells":
> +    const: 2
> +
> +allOf:
> +  - $ref: pinctrl.yaml#
> +
> +required:
> +  - compatible
> +  - reg
> +  - gpio-controller
> +  - "#gpio-cells"
> +
> +patternProperties:

Keep it after properties: block.

> +  '-pins$':
> +    type: object
> +    additionalProperties: false
> +
> +    patternProperties:
> +      '^.*mux.*$':
> +        type: object
> +        additionalProperties: false
> +        description: |

Do not need '|' unless you need to preserve formatting.

> +          pinmux configuration nodes.
> +
> +        $ref: /schemas/pinctrl/pinmux-node.yaml
> +        properties:
> +          function:
> +            description:
> +              A string containing the name of the function to mux to the group.
> +            enum: [pon, tod_1pps, sipo, mdio, uart, i2c, jtag, pcm, spi,
> +                   pcm_spi, i2s, emmc, pnand, pcie_reset, pwm, phy1_led0,
> +                   phy2_led0, phy3_led0, phy4_led0, phy1_led1, phy2_led1,
> +                   phy3_led1, phy4_led1]
> +          groups:

minItems: 1
maxItems: 32 (or whatever is sensible)

> +            description:
> +              An array of strings. Each string contains the name of a group.
> +        required:
> +          - function
> +          - groups
> +
> +        allOf:
> +          - if:
> +              properties:
> +                function:
> +                  const: pon
> +            then:
> +              properties:
> +                groups:
> +                  enum: [pon]
> +          - if:
> +              properties:
> +                function:
> +                  const: tod_1pps
> +            then:
> +              properties:
> +                groups:
> +                  enum: [pon_tod_1pps, gsw_tod_1pps]
> +          - if:
> +              properties:
> +                function:
> +                  const: sipo
> +            then:
> +              properties:
> +                groups:
> +                  enum: [sipo, sipo_rclk]
> +          - if:
> +              properties:
> +                function:
> +                  const: mdio
> +            then:
> +              properties:
> +                groups:
> +                  enum: [mdio]
> +          - if:
> +              properties:
> +                function:
> +                  const: uart
> +            then:
> +              properties:
> +                groups:
> +                  items:
> +                    enum: [uart2, uart2_cts_rts, hsuart, hsuart_cts_rts, uart4,
> +                           uart5]
> +                  maxItems: 2
> +          - if:
> +              properties:
> +                function:
> +                  const: i2c
> +            then:
> +              properties:
> +                groups:
> +                  enum: [i2c1]
> +          - if:
> +              properties:
> +                function:
> +                  const: jtag
> +            then:
> +              properties:
> +                groups:
> +                  enum: [jtag_udi, jtag_dfd]
> +          - if:
> +              properties:
> +                function:
> +                  const: pcm
> +            then:
> +              properties:
> +                groups:
> +                  enum: [pcm1, pcm2]
> +          - if:
> +              properties:
> +                function:
> +                  const: spi
> +            then:
> +              properties:
> +                groups:
> +                  items:
> +                    enum: [spi_quad, spi_cs1]
> +                  maxItems: 2
> +          - if:
> +              properties:
> +                function:
> +                  const: pcm_spi
> +            then:
> +              properties:
> +                groups:
> +                  items:
> +                    enum: [pcm_spi, pcm_spi_int, pcm_spi_rst, pcm_spi_cs1,
> +                           pcm_spi_cs2_p156, pcm_spi_cs2_p128, pcm_spi_cs3,
> +                           pcm_spi_cs4]
> +                  maxItems: 7
> +          - if:
> +              properties:
> +                function:
> +                  const: i2c
> +            then:
> +              properties:
> +                groups:
> +                  enum: [i2s]
> +          - if:
> +              properties:
> +                function:
> +                  const: emmc
> +            then:
> +              properties:
> +                groups:
> +                  enum: [emmc]
> +          - if:
> +              properties:
> +                function:
> +                  const: pnand
> +            then:
> +              properties:
> +                groups:
> +                  enum: [pnand]
> +          - if:
> +              properties:
> +                function:
> +                  const: pcie_reset
> +            then:
> +              properties:
> +                groups:
> +                  enum: [pcie_reset0, pcie_reset1, pcie_reset2]
> +          - if:
> +              properties:
> +                function:
> +                  const: pwm
> +            then:
> +              properties:
> +                groups:
> +                  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, gpio28, gpio29, gpio30, gpio31,
> +                         gpio36, gpio37, gpio38, gpio39, gpio40, gpio41,
> +                         gpio42, gpio43, gpio44, gpio45, gpio46, gpio47]
> +          - if:
> +              properties:
> +                function:
> +                  const: phy1_led0
> +            then:
> +              properties:
> +                groups:
> +                  enum: [gpio33, gpio34, gpio35, gpio42]
> +          - if:
> +              properties:
> +                function:
> +                  const: phy2_led0
> +            then:
> +              properties:
> +                groups:
> +                  enum: [gpio33, gpio34, gpio35, gpio42]
> +          - if:
> +              properties:
> +                function:
> +                  const: phy3_led0
> +            then:
> +              properties:
> +                groups:
> +                  enum: [gpio33, gpio34, gpio35, gpio42]
> +          - if:
> +              properties:
> +                function:
> +                  const: phy4_led0
> +            then:
> +              properties:
> +                groups:
> +                  enum: [gpio33, gpio34, gpio35, gpio42]
> +          - if:
> +              properties:
> +                function:
> +                  const: phy1_led1
> +            then:
> +              properties:
> +                groups:
> +                  enum: [gpio43, gpio44, gpio45, gpio46]
> +          - if:
> +              properties:
> +                function:
> +                  const: phy2_led1
> +            then:
> +              properties:
> +                groups:
> +                  enum: [gpio43, gpio44, gpio45, gpio46]
> +          - if:
> +              properties:
> +                function:
> +                  const: phy3_led1
> +            then:
> +              properties:
> +                groups:
> +                  enum: [gpio43, gpio44, gpio45, gpio46]
> +          - if:
> +              properties:
> +                function:
> +                  const: phy4_led1
> +            then:
> +              properties:
> +                groups:
> +                  enum: [gpio43, gpio44, gpio45, gpio46]
> +
> +      '^.*conf.*$':
> +        type: object
> +        additionalProperties: false
> +        description:
> +          pinconf configuration nodes.
> +        $ref: /schemas/pinctrl/pincfg-node.yaml
> +
> +        properties:
> +          pins:
> +            description:
> +              An array of strings. Each string contains the name of a pin.
> +            items:
> +              enum: [uart1_txd, uart1_rxd, i2c_scl, i2c_sda, spi_cs0, spi_clk,
> +                     spi_mosi, spi_miso, gpio0, gpio1, gpio2, gpio3, gpio4,
> +                     gpio5, gpio6, gpio7, gpio8, gpio9, gpio10, gpio11, gpio12,
> +                     gpio13, gpio14, gpio15, gpio16, gpio17, gpio18, gpio19,
> +                     gpio20, gpio21, gpio22, gpio23, gpio24, gpio25, gpio26,
> +                     gpio27, gpio28, gpio29, gpio30, gpio31, gpio32, gpio33,
> +                     gpio34, gpio35, gpio36, gpio37, gpio38, gpio39, gpio40,
> +                     gpio41, gpio42, gpio43, gpio44, gpio45, gpio46,
> +                     pcie_reset0, pcie_reset1, pcie_reset2]

minItems

> +            maxItems: 58
> +
> +          bias-disable: true
> +
> +          bias-pull-up: true
> +
> +          bias-pull-down: true
> +
> +          input-enable: true
> +
> +          output-enable: true
> +
> +          output-low: true
> +
> +          output-high: true
> +
> +          drive-open-drain: true

Drop blank lines between these.
> +
> +          drive-strength:

What are the units? Shouldn't this be drive-strength-microamp?

> +            enum: [2, 4, 6, 8]
> +
> +        required:
> +          - pins
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/interrupt-controller/irq.h>
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +
> +    soc {
> +      #address-cells = <2>;
> +      #size-cells = <2>;
> +
> +      pio: pinctrl@1fa20214 {
> +        compatible = "airoha,en7581-pinctrl";
> +        reg = <0x0 0x1fa20214 0x0 0x30>,
> +              <0x0 0x1fa2027c 0x0 0x8>,
> +              <0x0 0x1fbf0234 0x0 0x4>,
> +              <0x0 0x1fbf0268 0x0 0x4>,
> +              <0x0 0x1fa2001c 0x0 0x50>,
> +              <0x0 0x1fa2018c 0x0 0x4>,
> +              <0x0 0x1fbf0204 0x0 0x4>,
> +              <0x0 0x1fbf0270 0x0 0x4>,
> +              <0x0 0x1fbf0200 0x0 0x4>,
> +              <0x0 0x1fbf0220 0x0 0x4>,
> +              <0x0 0x1fbf0260 0x0 0x4>,
> +              <0x0 0x1fbf0264 0x0 0x4>,
> +              <0x0 0x1fbf0214 0x0 0x4>,
> +              <0x0 0x1fbf0278 0x0 0x4>,
> +              <0x0 0x1fbf0208 0x0 0x4>,
> +              <0x0 0x1fbf027c 0x0 0x4>,
> +              <0x0 0x1fbf0210 0x0 0x4>,
> +              <0x0 0x1fbf028c 0x0 0x4>,
> +              <0x0 0x1fbf0290 0x0 0x4>,
> +              <0x0 0x1fbf0294 0x0 0x4>,
> +              <0x0 0x1fbf020c 0x0 0x4>,
> +              <0x0 0x1fbf0280 0x0 0x4>,
> +              <0x0 0x1fbf0284 0x0 0x4>,
> +              <0x0 0x1fbf0288 0x0 0x4>;

Why are you mapping individual registers? At least half of these are
continuous.

> +
> +        gpio-controller;
> +        #gpio-cells = <2>;
> +        gpio-ranges = <&pio 0 13 47>;
> +
> +        interrupt-controller;
> +        #interrupt-cells = <2>;
> +        interrupt-parent = <&gic>;
> +        interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
> +
> +        pcie1-rst-pins {
> +          conf {
> +            pins = "pcie_reset1";
> +            drive-open-drain = <1>;
> +          };
> +        };
> +
> +        pwm-pins {
> +          mux {
> +            function = "pwm";
> +            groups = "gpio18";
> +          };
> +        };
> +
> +        spi-pins {
> +          mux {
> +            function = "spi";
> +            groups = "spi_quad", "spi_cs1";
> +          };
> +        };
> +
> +        uuart2-pins {
> +          mux {
> +            function = "uart";
> +            groups = "uart2", "uart2_cts_rts";
> +          };
> +        };
> +
> +        uar5-pins {
> +          mux {
> +            function = "uart";
> +            groups = "uart5";
> +          };
> +        };
> +
> +        mmc-pins {
> +          mux {
> +            function = "emmc";
> +            groups = "emmc";
> +          };
> +        };
> +
> +        mdio-pins {
> +          mux {
> +            function = "mdio";
> +            groups = "mdio";
> +          };
> +
> +          conf {
> +            pins = "gpio2";

What is the point of having both groups and pins?

> +            output-enable;
> +          };
> +        };
> +
> +        gswp1-led0-pins {
> +          mux {
> +            function = "phy1_led0";
> +            groups = "gpio33";
> +          };
> +        };
> +
> +        gswp2-led1-pins {
> +          mux {
> +            function = "phy2_led1";
> +            groups = "gpio44";

That's not a group but pin name.

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 1/2] dt-bindings: pinctrl: airoha: Add EN7581 pinctrl controller
  2024-08-12  6:48   ` Krzysztof Kozlowski
@ 2024-08-13  8:06     ` Benjamin Larsson
  2024-08-16 22:52       ` Rob Herring
  2024-08-18 14:20     ` Lorenzo Bianconi
  1 sibling, 1 reply; 19+ messages in thread
From: Benjamin Larsson @ 2024-08-13  8:06 UTC (permalink / raw)
  To: Krzysztof Kozlowski, Lorenzo Bianconi, linux-gpio
  Cc: linus.walleij, sean.wang, linux-mediatek, lorenzo.bianconi83,
	krzk+dt, robh, devicetree, linux-arm-kernel, upstream,
	angelogioacchino.delregno, conor+dt, ansuelsmth

On 2024-08-12 08:48, Krzysztof Kozlowski wrote:
>> +      pio: pinctrl@1fa20214 {
>> +        compatible = "airoha,en7581-pinctrl";
>> +        reg = <0x0 0x1fa20214 0x0 0x30>,
>> +              <0x0 0x1fa2027c 0x0 0x8>,
>> +              <0x0 0x1fbf0234 0x0 0x4>,
>> +              <0x0 0x1fbf0268 0x0 0x4>,
>> +              <0x0 0x1fa2001c 0x0 0x50>,
>> +              <0x0 0x1fa2018c 0x0 0x4>,
>> +              <0x0 0x1fbf0204 0x0 0x4>,
>> +              <0x0 0x1fbf0270 0x0 0x4>,
>> +              <0x0 0x1fbf0200 0x0 0x4>,
>> +              <0x0 0x1fbf0220 0x0 0x4>,
>> +              <0x0 0x1fbf0260 0x0 0x4>,
>> +              <0x0 0x1fbf0264 0x0 0x4>,
>> +              <0x0 0x1fbf0214 0x0 0x4>,
>> +              <0x0 0x1fbf0278 0x0 0x4>,
>> +              <0x0 0x1fbf0208 0x0 0x4>,
>> +              <0x0 0x1fbf027c 0x0 0x4>,
>> +              <0x0 0x1fbf0210 0x0 0x4>,
>> +              <0x0 0x1fbf028c 0x0 0x4>,
>> +              <0x0 0x1fbf0290 0x0 0x4>,
>> +              <0x0 0x1fbf0294 0x0 0x4>,
>> +              <0x0 0x1fbf020c 0x0 0x4>,
>> +              <0x0 0x1fbf0280 0x0 0x4>,
>> +              <0x0 0x1fbf0284 0x0 0x4>,
>> +              <0x0 0x1fbf0288 0x0 0x4>;
> Why are you mapping individual registers? At least half of these are
> continuous.

Hi, this is by design because of the register placement in the gpio 
block and the fact that the pwm functionality is intermixed in there 
also. As example the following registers are all GPIOCTRL:

<0x0 0x1fbf0200 0x0 0x4>,
<0x0 0x1fbf0220 0x0 0x4>,
<0x0 0x1fbf0260 0x0 0x4>,
<0x0 0x1fbf0264 0x0 0x4>,

To simplify the driver code logic the complexity is moved to the dts 
because of that.

MvH

Benjamin Larsson


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 1/2] dt-bindings: pinctrl: airoha: Add EN7581 pinctrl controller
  2024-08-13  8:06     ` Benjamin Larsson
@ 2024-08-16 22:52       ` Rob Herring
  2024-08-17 20:46         ` Benjamin Larsson
  2024-08-18 14:22         ` Lorenzo Bianconi
  0 siblings, 2 replies; 19+ messages in thread
From: Rob Herring @ 2024-08-16 22:52 UTC (permalink / raw)
  To: Benjamin Larsson
  Cc: Krzysztof Kozlowski, Lorenzo Bianconi, linux-gpio, linus.walleij,
	sean.wang, linux-mediatek, lorenzo.bianconi83, krzk+dt,
	devicetree, linux-arm-kernel, upstream, angelogioacchino.delregno,
	conor+dt, ansuelsmth

On Tue, Aug 13, 2024 at 10:06:41AM +0200, Benjamin Larsson wrote:
> On 2024-08-12 08:48, Krzysztof Kozlowski wrote:
> > > +      pio: pinctrl@1fa20214 {
> > > +        compatible = "airoha,en7581-pinctrl";
> > > +        reg = <0x0 0x1fa20214 0x0 0x30>,
> > > +              <0x0 0x1fa2027c 0x0 0x8>,
> > > +              <0x0 0x1fbf0234 0x0 0x4>,
> > > +              <0x0 0x1fbf0268 0x0 0x4>,
> > > +              <0x0 0x1fa2001c 0x0 0x50>,
> > > +              <0x0 0x1fa2018c 0x0 0x4>,
> > > +              <0x0 0x1fbf0204 0x0 0x4>,
> > > +              <0x0 0x1fbf0270 0x0 0x4>,
> > > +              <0x0 0x1fbf0200 0x0 0x4>,
> > > +              <0x0 0x1fbf0220 0x0 0x4>,
> > > +              <0x0 0x1fbf0260 0x0 0x4>,
> > > +              <0x0 0x1fbf0264 0x0 0x4>,
> > > +              <0x0 0x1fbf0214 0x0 0x4>,
> > > +              <0x0 0x1fbf0278 0x0 0x4>,
> > > +              <0x0 0x1fbf0208 0x0 0x4>,
> > > +              <0x0 0x1fbf027c 0x0 0x4>,
> > > +              <0x0 0x1fbf0210 0x0 0x4>,
> > > +              <0x0 0x1fbf028c 0x0 0x4>,
> > > +              <0x0 0x1fbf0290 0x0 0x4>,
> > > +              <0x0 0x1fbf0294 0x0 0x4>,
> > > +              <0x0 0x1fbf020c 0x0 0x4>,
> > > +              <0x0 0x1fbf0280 0x0 0x4>,
> > > +              <0x0 0x1fbf0284 0x0 0x4>,
> > > +              <0x0 0x1fbf0288 0x0 0x4>;
> > Why are you mapping individual registers? At least half of these are
> > continuous.
> 
> Hi, this is by design because of the register placement in the gpio block
> and the fact that the pwm functionality is intermixed in there also. As
> example the following registers are all GPIOCTRL:
> 
> <0x0 0x1fbf0200 0x0 0x4>,
> <0x0 0x1fbf0220 0x0 0x4>,
> <0x0 0x1fbf0260 0x0 0x4>,
> <0x0 0x1fbf0264 0x0 0x4>,
> 
> To simplify the driver code logic the complexity is moved to the dts because
> of that.

DT to OS is an ABI. Don't put the complexity there. The driver is easy 
to change.

Lot's of h/w blocks are just bit soup. This is not special. If a few 
regions is helpful, then that would be fine.

Rob

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 1/2] dt-bindings: pinctrl: airoha: Add EN7581 pinctrl controller
  2024-08-16 22:52       ` Rob Herring
@ 2024-08-17 20:46         ` Benjamin Larsson
  2024-08-17 21:39           ` Andrew Lunn
  2024-08-18 14:22         ` Lorenzo Bianconi
  1 sibling, 1 reply; 19+ messages in thread
From: Benjamin Larsson @ 2024-08-17 20:46 UTC (permalink / raw)
  To: Rob Herring
  Cc: Krzysztof Kozlowski, Lorenzo Bianconi, linux-gpio, linus.walleij,
	sean.wang, linux-mediatek, lorenzo.bianconi83, krzk+dt,
	devicetree, linux-arm-kernel, upstream, angelogioacchino.delregno,
	conor+dt, ansuelsmth

On 17/08/2024 00:52, Rob Herring wrote:
>> Hi, this is by design because of the register placement in the gpio block
>> and the fact that the pwm functionality is intermixed in there also. As
>> example the following registers are all GPIOCTRL:
>>
>> <0x0 0x1fbf0200 0x0 0x4>,
>> <0x0 0x1fbf0220 0x0 0x4>,
>> <0x0 0x1fbf0260 0x0 0x4>,
>> <0x0 0x1fbf0264 0x0 0x4>,
>>
>> To simplify the driver code logic the complexity is moved to the dts because
>> of that.
> DT to OS is an ABI. Don't put the complexity there. The driver is easy
> to change.
>
> Lot's of h/w blocks are just bit soup. This is not special. If a few
> regions is helpful, then that would be fine.
>
> Rob

Hi, the pwm functionality is to blame.

The following is the logic that populates the direction registers 
(GPIOCTRL).

     for (i = 0; i < ARRAY_SIZE(pinctrl->gpiochip.dir); i++) {
         ptr = devm_platform_ioremap_resource(pdev, index++);
         if (IS_ERR(ptr))
             return dev_err_probe(dev, PTR_ERR(ptr),
                          "failed to map gpio dir regs\n");

         pinctrl->gpiochip.dir[i] = ptr;
     }


As example in between 0x1fbf0200, 0x1fbf0220 and 0x1fbf0260 we have pwm 
related registers.

The gpio block could if I count it correctly be split into 8+ regions. 
The dts list contain 18 rows related to the gpio block. So the savings 
would be ca 10 rows but a register mapping list in the driver would be 
needed instead.

Is that savings worth the addition of a register lookup table ?

MvH

Benjamin Larsson


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 1/2] dt-bindings: pinctrl: airoha: Add EN7581 pinctrl controller
  2024-08-17 20:46         ` Benjamin Larsson
@ 2024-08-17 21:39           ` Andrew Lunn
  2024-08-18 12:48             ` Benjamin Larsson
  0 siblings, 1 reply; 19+ messages in thread
From: Andrew Lunn @ 2024-08-17 21:39 UTC (permalink / raw)
  To: Benjamin Larsson
  Cc: Rob Herring, Krzysztof Kozlowski, Lorenzo Bianconi, linux-gpio,
	linus.walleij, sean.wang, linux-mediatek, lorenzo.bianconi83,
	krzk+dt, devicetree, linux-arm-kernel, upstream,
	angelogioacchino.delregno, conor+dt, ansuelsmth

On Sat, Aug 17, 2024 at 10:46:10PM +0200, Benjamin Larsson wrote:
> On 17/08/2024 00:52, Rob Herring wrote:
> > > Hi, this is by design because of the register placement in the gpio block
> > > and the fact that the pwm functionality is intermixed in there also. As
> > > example the following registers are all GPIOCTRL:
> > > 
> > > <0x0 0x1fbf0200 0x0 0x4>,
> > > <0x0 0x1fbf0220 0x0 0x4>,
> > > <0x0 0x1fbf0260 0x0 0x4>,
> > > <0x0 0x1fbf0264 0x0 0x4>,
> > > 
> > > To simplify the driver code logic the complexity is moved to the dts because
> > > of that.
> > DT to OS is an ABI. Don't put the complexity there. The driver is easy
> > to change.
> > 
> > Lot's of h/w blocks are just bit soup. This is not special. If a few
> > regions is helpful, then that would be fine.
> > 
> > Rob
> 
> Hi, the pwm functionality is to blame.
> 
> The following is the logic that populates the direction registers
> (GPIOCTRL).
> 
>     for (i = 0; i < ARRAY_SIZE(pinctrl->gpiochip.dir); i++) {
>         ptr = devm_platform_ioremap_resource(pdev, index++);
>         if (IS_ERR(ptr))
>             return dev_err_probe(dev, PTR_ERR(ptr),
>                          "failed to map gpio dir regs\n");
> 
>         pinctrl->gpiochip.dir[i] = ptr;
>     }
> 
> 
> As example in between 0x1fbf0200, 0x1fbf0220 and 0x1fbf0260 we have pwm
> related registers.
> 
> The gpio block could if I count it correctly be split into 8+ regions. The
> dts list contain 18 rows related to the gpio block. So the savings would be
> ca 10 rows but a register mapping list in the driver would be needed
> instead.

How messy are the GPIO and PWM registers? Are there N blocks of
independent GPIO registers? and M blocks of independent PWM registers?
By that, does one block of GPIO registers contain all you need for one
GPIO controller? One block of PWM registers give you all you need for
one PWM controller? Or are the registers for one GPIO controller
scattered all over the place?

Could you point at a public datasheet?

      Andrew


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 1/2] dt-bindings: pinctrl: airoha: Add EN7581 pinctrl controller
  2024-08-17 21:39           ` Andrew Lunn
@ 2024-08-18 12:48             ` Benjamin Larsson
  2024-08-18 16:02               ` Andrew Lunn
  0 siblings, 1 reply; 19+ messages in thread
From: Benjamin Larsson @ 2024-08-18 12:48 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Rob Herring, Krzysztof Kozlowski, Lorenzo Bianconi, linux-gpio,
	linus.walleij, sean.wang, linux-mediatek, lorenzo.bianconi83,
	krzk+dt, devicetree, linux-arm-kernel, upstream,
	angelogioacchino.delregno, conor+dt, ansuelsmth

On 17/08/2024 23:39, Andrew Lunn wrote:
> How messy are the GPIO and PWM registers? Are there N blocks of
> independent GPIO registers? and M blocks of independent PWM registers?
> By that, does one block of GPIO registers contain all you need for one
> GPIO controller? One block of PWM registers give you all you need for
> one PWM controller? Or are the registers for one GPIO controller
> scattered all over the place?
>
> Could you point at a public datasheet?
>
>        Andrew
>
Hi, per my understanding there is no public datasheet/register reference 
manual.

But here is the division of regions of the registers in the gpio block 
and how it is currently divided between the drivers (according to my 
current understanding).

1FBF0200, gpio/pinctrl
1FBF0204, gpio/pinctrl
1FBF0208, gpio/pinctrl
1FBF020C, gpio/pinctrl
1FBF0210, gpio/pinctrl
1FBF0214, gpio/pinctrl
1FBF0218, unclaimed
1FBF021C, pwm
1FBF0220, gpio/pinctrl
1FBF0224, pwm
1FBF0228, pwm
1FBF022C, pwm
1FBF0230, pwm
1FBF0234, pwm
1FBF0238, unclaimed
1FBF023C, pwm
1FBF0240, pwm
1FBF0244, pwm
1FBF0248, pwm
1FBF024C, pwm
1FBF0250, pwm
1FBF0254, pwm
1FBF0258, pwm
1FBF025C, pwm
1FBF0260, gpio/pinctrl
1FBF0264, gpio/pinctrl
1FBF0268, gpio/pinctrl
1FBF0270, gpio/pinctrl
1FBF0278, gpio/pinctrl
1FBF027C, gpio/pinctrl
1FBF0280, gpio/pinctrl
1FBF0284, gpio/pinctrl
1FBF0288, gpio/pinctrl
1FBF028C, gpio/pinctrl
1FBF0290, gpio/pinctrl
1FBF0294, gpio/pinctrl
1FBF0298, pwm
1FBF029C, pwm
1FBF02A0, unclaimed
1FBF02A4, unclaimed
1FBF02A8, unclaimed
1FBF02AC, unclaimed
1FBF02B0, unclaimed
1FBF02B4, unclaimed
1FBF02B8, unclaimed
1FBF02BC, pwm (but currently unclaimed)

The gpio functions are split in 2x32bit register banks. The pin-io and 
interrupt support for these are split amongst the regions.

MvH

Benjamin Larsson


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 1/2] dt-bindings: pinctrl: airoha: Add EN7581 pinctrl controller
  2024-08-12  6:48   ` Krzysztof Kozlowski
  2024-08-13  8:06     ` Benjamin Larsson
@ 2024-08-18 14:20     ` Lorenzo Bianconi
  1 sibling, 0 replies; 19+ messages in thread
From: Lorenzo Bianconi @ 2024-08-18 14:20 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: linux-gpio, linus.walleij, sean.wang, linux-mediatek,
	lorenzo.bianconi83, krzk+dt, robh, devicetree, linux-arm-kernel,
	upstream, angelogioacchino.delregno, benjamin.larsson, conor+dt,
	ansuelsmth

[-- Attachment #1: Type: text/plain, Size: 14475 bytes --]

[...]
> > +allOf:
> > +  - $ref: pinctrl.yaml#
> > +
> > +required:
> > +  - compatible
> > +  - reg
> > +  - gpio-controller
> > +  - "#gpio-cells"
> > +
> > +patternProperties:
> 
> Keep it after properties: block.

ack, I will fix it in v2

> 
> > +  '-pins$':
> > +    type: object
> > +    additionalProperties: false
> > +
> > +    patternProperties:
> > +      '^.*mux.*$':
> > +        type: object
> > +        additionalProperties: false
> > +        description: |
> 
> Do not need '|' unless you need to preserve formatting.

ack, I will fix it in v2

> 
> > +          pinmux configuration nodes.
> > +
> > +        $ref: /schemas/pinctrl/pinmux-node.yaml
> > +        properties:
> > +          function:
> > +            description:
> > +              A string containing the name of the function to mux to the group.
> > +            enum: [pon, tod_1pps, sipo, mdio, uart, i2c, jtag, pcm, spi,
> > +                   pcm_spi, i2s, emmc, pnand, pcie_reset, pwm, phy1_led0,
> > +                   phy2_led0, phy3_led0, phy4_led0, phy1_led1, phy2_led1,
> > +                   phy3_led1, phy4_led1]
> > +          groups:
> 
> minItems: 1
> maxItems: 32 (or whatever is sensible)

I was assuming the default values are minIems = maxItems = 1 and we can
overwrite maxItems if required (e.g. for "uart" or for "pcm_spi" blocks).
Am I missing something?

> 
> > +            description:
> > +              An array of strings. Each string contains the name of a group.
> > +        required:
> > +          - function
> > +          - groups
> > +
> > +        allOf:
> > +          - if:
> > +              properties:
> > +                function:
> > +                  const: pon
> > +            then:
> > +              properties:
> > +                groups:
> > +                  enum: [pon]
> > +          - if:
> > +              properties:
> > +                function:
> > +                  const: tod_1pps
> > +            then:
> > +              properties:
> > +                groups:
> > +                  enum: [pon_tod_1pps, gsw_tod_1pps]
> > +          - if:
> > +              properties:
> > +                function:
> > +                  const: sipo
> > +            then:
> > +              properties:
> > +                groups:
> > +                  enum: [sipo, sipo_rclk]
> > +          - if:
> > +              properties:
> > +                function:
> > +                  const: mdio
> > +            then:
> > +              properties:
> > +                groups:
> > +                  enum: [mdio]
> > +          - if:
> > +              properties:
> > +                function:
> > +                  const: uart
> > +            then:
> > +              properties:
> > +                groups:
> > +                  items:
> > +                    enum: [uart2, uart2_cts_rts, hsuart, hsuart_cts_rts, uart4,
> > +                           uart5]
> > +                  maxItems: 2
> > +          - if:
> > +              properties:
> > +                function:
> > +                  const: i2c
> > +            then:
> > +              properties:
> > +                groups:
> > +                  enum: [i2c1]
> > +          - if:
> > +              properties:
> > +                function:
> > +                  const: jtag
> > +            then:
> > +              properties:
> > +                groups:
> > +                  enum: [jtag_udi, jtag_dfd]
> > +          - if:
> > +              properties:
> > +                function:
> > +                  const: pcm
> > +            then:
> > +              properties:
> > +                groups:
> > +                  enum: [pcm1, pcm2]
> > +          - if:
> > +              properties:
> > +                function:
> > +                  const: spi
> > +            then:
> > +              properties:
> > +                groups:
> > +                  items:
> > +                    enum: [spi_quad, spi_cs1]
> > +                  maxItems: 2
> > +          - if:
> > +              properties:
> > +                function:
> > +                  const: pcm_spi
> > +            then:
> > +              properties:
> > +                groups:
> > +                  items:
> > +                    enum: [pcm_spi, pcm_spi_int, pcm_spi_rst, pcm_spi_cs1,
> > +                           pcm_spi_cs2_p156, pcm_spi_cs2_p128, pcm_spi_cs3,
> > +                           pcm_spi_cs4]
> > +                  maxItems: 7
> > +          - if:
> > +              properties:
> > +                function:
> > +                  const: i2c
> > +            then:
> > +              properties:
> > +                groups:
> > +                  enum: [i2s]
> > +          - if:
> > +              properties:
> > +                function:
> > +                  const: emmc
> > +            then:
> > +              properties:
> > +                groups:
> > +                  enum: [emmc]
> > +          - if:
> > +              properties:
> > +                function:
> > +                  const: pnand
> > +            then:
> > +              properties:
> > +                groups:
> > +                  enum: [pnand]
> > +          - if:
> > +              properties:
> > +                function:
> > +                  const: pcie_reset
> > +            then:
> > +              properties:
> > +                groups:
> > +                  enum: [pcie_reset0, pcie_reset1, pcie_reset2]
> > +          - if:
> > +              properties:
> > +                function:
> > +                  const: pwm
> > +            then:
> > +              properties:
> > +                groups:
> > +                  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, gpio28, gpio29, gpio30, gpio31,
> > +                         gpio36, gpio37, gpio38, gpio39, gpio40, gpio41,
> > +                         gpio42, gpio43, gpio44, gpio45, gpio46, gpio47]
> > +          - if:
> > +              properties:
> > +                function:
> > +                  const: phy1_led0
> > +            then:
> > +              properties:
> > +                groups:
> > +                  enum: [gpio33, gpio34, gpio35, gpio42]
> > +          - if:
> > +              properties:
> > +                function:
> > +                  const: phy2_led0
> > +            then:
> > +              properties:
> > +                groups:
> > +                  enum: [gpio33, gpio34, gpio35, gpio42]
> > +          - if:
> > +              properties:
> > +                function:
> > +                  const: phy3_led0
> > +            then:
> > +              properties:
> > +                groups:
> > +                  enum: [gpio33, gpio34, gpio35, gpio42]
> > +          - if:
> > +              properties:
> > +                function:
> > +                  const: phy4_led0
> > +            then:
> > +              properties:
> > +                groups:
> > +                  enum: [gpio33, gpio34, gpio35, gpio42]
> > +          - if:
> > +              properties:
> > +                function:
> > +                  const: phy1_led1
> > +            then:
> > +              properties:
> > +                groups:
> > +                  enum: [gpio43, gpio44, gpio45, gpio46]
> > +          - if:
> > +              properties:
> > +                function:
> > +                  const: phy2_led1
> > +            then:
> > +              properties:
> > +                groups:
> > +                  enum: [gpio43, gpio44, gpio45, gpio46]
> > +          - if:
> > +              properties:
> > +                function:
> > +                  const: phy3_led1
> > +            then:
> > +              properties:
> > +                groups:
> > +                  enum: [gpio43, gpio44, gpio45, gpio46]
> > +          - if:
> > +              properties:
> > +                function:
> > +                  const: phy4_led1
> > +            then:
> > +              properties:
> > +                groups:
> > +                  enum: [gpio43, gpio44, gpio45, gpio46]
> > +
> > +      '^.*conf.*$':
> > +        type: object
> > +        additionalProperties: false
> > +        description:
> > +          pinconf configuration nodes.
> > +        $ref: /schemas/pinctrl/pincfg-node.yaml
> > +
> > +        properties:
> > +          pins:
> > +            description:
> > +              An array of strings. Each string contains the name of a pin.
> > +            items:
> > +              enum: [uart1_txd, uart1_rxd, i2c_scl, i2c_sda, spi_cs0, spi_clk,
> > +                     spi_mosi, spi_miso, gpio0, gpio1, gpio2, gpio3, gpio4,
> > +                     gpio5, gpio6, gpio7, gpio8, gpio9, gpio10, gpio11, gpio12,
> > +                     gpio13, gpio14, gpio15, gpio16, gpio17, gpio18, gpio19,
> > +                     gpio20, gpio21, gpio22, gpio23, gpio24, gpio25, gpio26,
> > +                     gpio27, gpio28, gpio29, gpio30, gpio31, gpio32, gpio33,
> > +                     gpio34, gpio35, gpio36, gpio37, gpio38, gpio39, gpio40,
> > +                     gpio41, gpio42, gpio43, gpio44, gpio45, gpio46,
> > +                     pcie_reset0, pcie_reset1, pcie_reset2]
> 
> minItems

ack, I will fix it in v2.

> 
> > +            maxItems: 58
> > +
> > +          bias-disable: true
> > +
> > +          bias-pull-up: true
> > +
> > +          bias-pull-down: true
> > +
> > +          input-enable: true
> > +
> > +          output-enable: true
> > +
> > +          output-low: true
> > +
> > +          output-high: true
> > +
> > +          drive-open-drain: true
> 
> Drop blank lines between these.

ack, I will fix it in v2.

> > +
> > +          drive-strength:
> 
> What are the units? Shouldn't this be drive-strength-microamp?

nope, it is in mA. I will add a description to specify it.

> 
> > +            enum: [2, 4, 6, 8]
> > +
> > +        required:
> > +          - pins
> > +
> > +additionalProperties: false
> > +
> > +examples:
> > +  - |
> > +    #include <dt-bindings/interrupt-controller/irq.h>
> > +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> > +
> > +    soc {
> > +      #address-cells = <2>;
> > +      #size-cells = <2>;
> > +
> > +      pio: pinctrl@1fa20214 {
> > +        compatible = "airoha,en7581-pinctrl";
> > +        reg = <0x0 0x1fa20214 0x0 0x30>,
> > +              <0x0 0x1fa2027c 0x0 0x8>,
> > +              <0x0 0x1fbf0234 0x0 0x4>,
> > +              <0x0 0x1fbf0268 0x0 0x4>,
> > +              <0x0 0x1fa2001c 0x0 0x50>,
> > +              <0x0 0x1fa2018c 0x0 0x4>,
> > +              <0x0 0x1fbf0204 0x0 0x4>,
> > +              <0x0 0x1fbf0270 0x0 0x4>,
> > +              <0x0 0x1fbf0200 0x0 0x4>,
> > +              <0x0 0x1fbf0220 0x0 0x4>,
> > +              <0x0 0x1fbf0260 0x0 0x4>,
> > +              <0x0 0x1fbf0264 0x0 0x4>,
> > +              <0x0 0x1fbf0214 0x0 0x4>,
> > +              <0x0 0x1fbf0278 0x0 0x4>,
> > +              <0x0 0x1fbf0208 0x0 0x4>,
> > +              <0x0 0x1fbf027c 0x0 0x4>,
> > +              <0x0 0x1fbf0210 0x0 0x4>,
> > +              <0x0 0x1fbf028c 0x0 0x4>,
> > +              <0x0 0x1fbf0290 0x0 0x4>,
> > +              <0x0 0x1fbf0294 0x0 0x4>,
> > +              <0x0 0x1fbf020c 0x0 0x4>,
> > +              <0x0 0x1fbf0280 0x0 0x4>,
> > +              <0x0 0x1fbf0284 0x0 0x4>,
> > +              <0x0 0x1fbf0288 0x0 0x4>;
> 
> Why are you mapping individual registers? At least half of these are
> continuous.
> 
> > +
> > +        gpio-controller;
> > +        #gpio-cells = <2>;
> > +        gpio-ranges = <&pio 0 13 47>;
> > +
> > +        interrupt-controller;
> > +        #interrupt-cells = <2>;
> > +        interrupt-parent = <&gic>;
> > +        interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
> > +
> > +        pcie1-rst-pins {
> > +          conf {
> > +            pins = "pcie_reset1";
> > +            drive-open-drain = <1>;
> > +          };
> > +        };
> > +
> > +        pwm-pins {
> > +          mux {
> > +            function = "pwm";
> > +            groups = "gpio18";
> > +          };
> > +        };
> > +
> > +        spi-pins {
> > +          mux {
> > +            function = "spi";
> > +            groups = "spi_quad", "spi_cs1";
> > +          };
> > +        };
> > +
> > +        uuart2-pins {
> > +          mux {
> > +            function = "uart";
> > +            groups = "uart2", "uart2_cts_rts";
> > +          };
> > +        };
> > +
> > +        uar5-pins {
> > +          mux {
> > +            function = "uart";
> > +            groups = "uart5";
> > +          };
> > +        };
> > +
> > +        mmc-pins {
> > +          mux {
> > +            function = "emmc";
> > +            groups = "emmc";
> > +          };
> > +        };
> > +
> > +        mdio-pins {
> > +          mux {
> > +            function = "mdio";
> > +            groups = "mdio";
> > +          };
> > +
> > +          conf {
> > +            pins = "gpio2";
> 
> What is the point of having both groups and pins?

"pins" is specific for "conf" block and it is used to specify the pins where
we need to apply the configuration while "group" is just used in the "mux"
block. Am I missing something?

> 
> > +            output-enable;
> > +          };
> > +        };
> > +
> > +        gswp1-led0-pins {
> > +          mux {
> > +            function = "phy1_led0";
> > +            groups = "gpio33";
> > +          };
> > +        };
> > +
> > +        gswp2-led1-pins {
> > +          mux {
> > +            function = "phy2_led1";
> > +            groups = "gpio44";
> 
> That's not a group but pin name.

Looking at the patch 2/2, "gpio44" is actually a group used to specify a single
pin group.

Regards,
Lorenzo

> 
> Best regards,
> Krzysztof
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 1/2] dt-bindings: pinctrl: airoha: Add EN7581 pinctrl controller
  2024-08-16 22:52       ` Rob Herring
  2024-08-17 20:46         ` Benjamin Larsson
@ 2024-08-18 14:22         ` Lorenzo Bianconi
  1 sibling, 0 replies; 19+ messages in thread
From: Lorenzo Bianconi @ 2024-08-18 14:22 UTC (permalink / raw)
  To: Rob Herring
  Cc: Benjamin Larsson, Krzysztof Kozlowski, linux-gpio, linus.walleij,
	sean.wang, linux-mediatek, lorenzo.bianconi83, krzk+dt,
	devicetree, linux-arm-kernel, upstream, angelogioacchino.delregno,
	conor+dt, ansuelsmth

[-- Attachment #1: Type: text/plain, Size: 2368 bytes --]

> On Tue, Aug 13, 2024 at 10:06:41AM +0200, Benjamin Larsson wrote:
> > On 2024-08-12 08:48, Krzysztof Kozlowski wrote:
> > > > +      pio: pinctrl@1fa20214 {
> > > > +        compatible = "airoha,en7581-pinctrl";
> > > > +        reg = <0x0 0x1fa20214 0x0 0x30>,
> > > > +              <0x0 0x1fa2027c 0x0 0x8>,
> > > > +              <0x0 0x1fbf0234 0x0 0x4>,
> > > > +              <0x0 0x1fbf0268 0x0 0x4>,
> > > > +              <0x0 0x1fa2001c 0x0 0x50>,
> > > > +              <0x0 0x1fa2018c 0x0 0x4>,
> > > > +              <0x0 0x1fbf0204 0x0 0x4>,
> > > > +              <0x0 0x1fbf0270 0x0 0x4>,
> > > > +              <0x0 0x1fbf0200 0x0 0x4>,
> > > > +              <0x0 0x1fbf0220 0x0 0x4>,
> > > > +              <0x0 0x1fbf0260 0x0 0x4>,
> > > > +              <0x0 0x1fbf0264 0x0 0x4>,
> > > > +              <0x0 0x1fbf0214 0x0 0x4>,
> > > > +              <0x0 0x1fbf0278 0x0 0x4>,
> > > > +              <0x0 0x1fbf0208 0x0 0x4>,
> > > > +              <0x0 0x1fbf027c 0x0 0x4>,
> > > > +              <0x0 0x1fbf0210 0x0 0x4>,
> > > > +              <0x0 0x1fbf028c 0x0 0x4>,
> > > > +              <0x0 0x1fbf0290 0x0 0x4>,
> > > > +              <0x0 0x1fbf0294 0x0 0x4>,
> > > > +              <0x0 0x1fbf020c 0x0 0x4>,
> > > > +              <0x0 0x1fbf0280 0x0 0x4>,
> > > > +              <0x0 0x1fbf0284 0x0 0x4>,
> > > > +              <0x0 0x1fbf0288 0x0 0x4>;
> > > Why are you mapping individual registers? At least half of these are
> > > continuous.
> > 
> > Hi, this is by design because of the register placement in the gpio block
> > and the fact that the pwm functionality is intermixed in there also. As
> > example the following registers are all GPIOCTRL:
> > 
> > <0x0 0x1fbf0200 0x0 0x4>,
> > <0x0 0x1fbf0220 0x0 0x4>,
> > <0x0 0x1fbf0260 0x0 0x4>,
> > <0x0 0x1fbf0264 0x0 0x4>,
> > 
> > To simplify the driver code logic the complexity is moved to the dts because
> > of that.
> 
> DT to OS is an ABI. Don't put the complexity there. The driver is easy 
> to change.
> 
> Lot's of h/w blocks are just bit soup. This is not special. If a few 
> regions is helpful, then that would be fine.

ack, I guess we can try to move the complexity in the driver, at least for
gpio-irq controllers, merging regs whenever possible. I will work on it.

Regards,
Lorenzo

> 
> Rob

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 1/2] dt-bindings: pinctrl: airoha: Add EN7581 pinctrl controller
  2024-08-18 16:02               ` Andrew Lunn
@ 2024-08-18 15:42                 ` Christian Marangi
  2024-08-18 16:15                 ` Lorenzo Bianconi
  2024-08-18 16:59                 ` Benjamin Larsson
  2 siblings, 0 replies; 19+ messages in thread
From: Christian Marangi @ 2024-08-18 15:42 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Benjamin Larsson, Rob Herring, Krzysztof Kozlowski,
	Lorenzo Bianconi, linux-gpio, linus.walleij, sean.wang,
	linux-mediatek, lorenzo.bianconi83, krzk+dt, devicetree,
	linux-arm-kernel, upstream, angelogioacchino.delregno, conor+dt

On Sun, Aug 18, 2024 at 06:02:28PM +0200, Andrew Lunn wrote:
> On Sun, Aug 18, 2024 at 02:48:05PM +0200, Benjamin Larsson wrote:
> > On 17/08/2024 23:39, Andrew Lunn wrote:
> > > How messy are the GPIO and PWM registers? Are there N blocks of
> > > independent GPIO registers? and M blocks of independent PWM registers?
> > > By that, does one block of GPIO registers contain all you need for one
> > > GPIO controller? One block of PWM registers give you all you need for
> > > one PWM controller? Or are the registers for one GPIO controller
> > > scattered all over the place?
> > > 
> > > Could you point at a public datasheet?
> > > 
> > >        Andrew
> > > 
> > Hi, per my understanding there is no public datasheet/register reference
> > manual.
> > 
> > But here is the division of regions of the registers in the gpio block and
> > how it is currently divided between the drivers (according to my current
> > understanding).
> > 
> > 1FBF0200, gpio/pinctrl
> > 1FBF0204, gpio/pinctrl
> > 1FBF0208, gpio/pinctrl
> > 1FBF020C, gpio/pinctrl
> > 1FBF0210, gpio/pinctrl
> > 1FBF0214, gpio/pinctrl
> 
> A typical SoC has multiple instances of a GPIO controller. Each GPIO
> controller typically has 4 or 5 registers: In, Out, Direction,
> Interrupt Enable, Interrupt Status. If these 4 or 5 registers are
> contiguous, you could have one DT node per controller, rather than one
> node for all GPIO controllers.
> 
> If the hardware designer has really messed up and fully interleaved
> GPIO and PWM, it might be better to have an MFD. The MFD node has a
> single reg covering the entire range. The MFD would then map the whole
> range, and provide accessors to the child devices. Hard code the
> knowledge of what registers are where. Given how badly the hardware is
> designed, it is unlikely it will get reused in the future, so there is
> no point putting lots of stuff into DT. Hard code it.
>

Problem is that the MFD will also affect other stuff like watchdog...
thermal sensor/monitor, clocks... They really messed and put in that
range all kind of stuff so we would end up in a very big mapped range
and lots of child for the MFD.

-- 
	Ansuel

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 1/2] dt-bindings: pinctrl: airoha: Add EN7581 pinctrl controller
  2024-08-18 12:48             ` Benjamin Larsson
@ 2024-08-18 16:02               ` Andrew Lunn
  2024-08-18 15:42                 ` Christian Marangi
                                   ` (2 more replies)
  0 siblings, 3 replies; 19+ messages in thread
From: Andrew Lunn @ 2024-08-18 16:02 UTC (permalink / raw)
  To: Benjamin Larsson
  Cc: Rob Herring, Krzysztof Kozlowski, Lorenzo Bianconi, linux-gpio,
	linus.walleij, sean.wang, linux-mediatek, lorenzo.bianconi83,
	krzk+dt, devicetree, linux-arm-kernel, upstream,
	angelogioacchino.delregno, conor+dt, ansuelsmth

On Sun, Aug 18, 2024 at 02:48:05PM +0200, Benjamin Larsson wrote:
> On 17/08/2024 23:39, Andrew Lunn wrote:
> > How messy are the GPIO and PWM registers? Are there N blocks of
> > independent GPIO registers? and M blocks of independent PWM registers?
> > By that, does one block of GPIO registers contain all you need for one
> > GPIO controller? One block of PWM registers give you all you need for
> > one PWM controller? Or are the registers for one GPIO controller
> > scattered all over the place?
> > 
> > Could you point at a public datasheet?
> > 
> >        Andrew
> > 
> Hi, per my understanding there is no public datasheet/register reference
> manual.
> 
> But here is the division of regions of the registers in the gpio block and
> how it is currently divided between the drivers (according to my current
> understanding).
> 
> 1FBF0200, gpio/pinctrl
> 1FBF0204, gpio/pinctrl
> 1FBF0208, gpio/pinctrl
> 1FBF020C, gpio/pinctrl
> 1FBF0210, gpio/pinctrl
> 1FBF0214, gpio/pinctrl

A typical SoC has multiple instances of a GPIO controller. Each GPIO
controller typically has 4 or 5 registers: In, Out, Direction,
Interrupt Enable, Interrupt Status. If these 4 or 5 registers are
contiguous, you could have one DT node per controller, rather than one
node for all GPIO controllers.

If the hardware designer has really messed up and fully interleaved
GPIO and PWM, it might be better to have an MFD. The MFD node has a
single reg covering the entire range. The MFD would then map the whole
range, and provide accessors to the child devices. Hard code the
knowledge of what registers are where. Given how badly the hardware is
designed, it is unlikely it will get reused in the future, so there is
no point putting lots of stuff into DT. Hard code it.

	Andrew

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 1/2] dt-bindings: pinctrl: airoha: Add EN7581 pinctrl controller
  2024-08-18 16:02               ` Andrew Lunn
  2024-08-18 15:42                 ` Christian Marangi
@ 2024-08-18 16:15                 ` Lorenzo Bianconi
  2024-08-18 16:59                 ` Benjamin Larsson
  2 siblings, 0 replies; 19+ messages in thread
From: Lorenzo Bianconi @ 2024-08-18 16:15 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Benjamin Larsson, Rob Herring, Krzysztof Kozlowski, linux-gpio,
	linus.walleij, sean.wang, linux-mediatek, lorenzo.bianconi83,
	krzk+dt, devicetree, linux-arm-kernel, upstream,
	angelogioacchino.delregno, conor+dt, ansuelsmth

[-- Attachment #1: Type: text/plain, Size: 2361 bytes --]

On Aug 18, Andrew Lunn wrote:
> On Sun, Aug 18, 2024 at 02:48:05PM +0200, Benjamin Larsson wrote:
> > On 17/08/2024 23:39, Andrew Lunn wrote:
> > > How messy are the GPIO and PWM registers? Are there N blocks of
> > > independent GPIO registers? and M blocks of independent PWM registers?
> > > By that, does one block of GPIO registers contain all you need for one
> > > GPIO controller? One block of PWM registers give you all you need for
> > > one PWM controller? Or are the registers for one GPIO controller
> > > scattered all over the place?
> > > 
> > > Could you point at a public datasheet?
> > > 
> > >        Andrew
> > > 
> > Hi, per my understanding there is no public datasheet/register reference
> > manual.
> > 
> > But here is the division of regions of the registers in the gpio block and
> > how it is currently divided between the drivers (according to my current
> > understanding).
> > 
> > 1FBF0200, gpio/pinctrl
> > 1FBF0204, gpio/pinctrl
> > 1FBF0208, gpio/pinctrl
> > 1FBF020C, gpio/pinctrl
> > 1FBF0210, gpio/pinctrl
> > 1FBF0214, gpio/pinctrl
> 
> A typical SoC has multiple instances of a GPIO controller. Each GPIO
> controller typically has 4 or 5 registers: In, Out, Direction,
> Interrupt Enable, Interrupt Status. If these 4 or 5 registers are
> contiguous, you could have one DT node per controller, rather than one
> node for all GPIO controllers.

it is the same for en7581 pinctrl too. I think we can squash most of the
gpio/irq registers into "bigger" io-regions (just keeping a couple of holes
for pwm and leds). It is just a matter of moving the logic from the dts to
the driver. I am currently working on it. I will post v2 soon.

> 
> If the hardware designer has really messed up and fully interleaved
> GPIO and PWM, it might be better to have an MFD. The MFD node has a
> single reg covering the entire range. The MFD would then map the whole
> range, and provide accessors to the child devices. Hard code the
> knowledge of what registers are where. Given how badly the hardware is
> designed, it is unlikely it will get reused in the future, so there is
> no point putting lots of stuff into DT. Hard code it.

I am not sure it is possible/feasible to implement a MFD device here since
the mapped region is huge and sparse.

Regards,
Lorenzo

> 
> 	Andrew

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 1/2] dt-bindings: pinctrl: airoha: Add EN7581 pinctrl controller
  2024-08-18 16:02               ` Andrew Lunn
  2024-08-18 15:42                 ` Christian Marangi
  2024-08-18 16:15                 ` Lorenzo Bianconi
@ 2024-08-18 16:59                 ` Benjamin Larsson
  2024-08-18 17:35                   ` Andrew Lunn
  2 siblings, 1 reply; 19+ messages in thread
From: Benjamin Larsson @ 2024-08-18 16:59 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Rob Herring, Krzysztof Kozlowski, Lorenzo Bianconi, linux-gpio,
	linus.walleij, sean.wang, linux-mediatek, lorenzo.bianconi83,
	krzk+dt, devicetree, linux-arm-kernel, upstream,
	angelogioacchino.delregno, conor+dt, ansuelsmth

On 18/08/2024 18:02, Andrew Lunn wrote:
>>
>> Hi, per my understanding there is no public datasheet/register reference
>> manual.
>>
>> But here is the division of regions of the registers in the gpio block and
>> how it is currently divided between the drivers (according to my current
>> understanding).
>>
>> 1FBF0200, gpio/pinctrl
>> 1FBF0204, gpio/pinctrl
>> 1FBF0208, gpio/pinctrl
>> 1FBF020C, gpio/pinctrl
>> 1FBF0210, gpio/pinctrl
>> 1FBF0214, gpio/pinctrl
> A typical SoC has multiple instances of a GPIO controller. Each GPIO
> controller typically has 4 or 5 registers: In, Out, Direction,
> Interrupt Enable, Interrupt Status. If these 4 or 5 registers are
> contiguous, you could have one DT node per controller, rather than one
> node for all GPIO controllers.
>
> If the hardware designer has really messed up and fully interleaved
> GPIO and PWM, it might be better to have an MFD. The MFD node has a
> single reg covering the entire range. The MFD would then map the whole
> range, and provide accessors to the child devices. Hard code the
> knowledge of what registers are where. Given how badly the hardware is
> designed, it is unlikely it will get reused in the future, so there is
> no point putting lots of stuff into DT. Hard code it.
>
> 	Andrew

Hi, the pwm driver could be re-used on the EN7523 SoC. Future Airoha 
SoCs will most likely have the same ip-block also.

MvH

Benjamin Larsson


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 1/2] dt-bindings: pinctrl: airoha: Add EN7581 pinctrl controller
  2024-08-18 16:59                 ` Benjamin Larsson
@ 2024-08-18 17:35                   ` Andrew Lunn
  0 siblings, 0 replies; 19+ messages in thread
From: Andrew Lunn @ 2024-08-18 17:35 UTC (permalink / raw)
  To: Benjamin Larsson
  Cc: Rob Herring, Krzysztof Kozlowski, Lorenzo Bianconi, linux-gpio,
	linus.walleij, sean.wang, linux-mediatek, lorenzo.bianconi83,
	krzk+dt, devicetree, linux-arm-kernel, upstream,
	angelogioacchino.delregno, conor+dt, ansuelsmth

> Hi, the pwm driver could be re-used on the EN7523 SoC. Future Airoha SoCs
> will most likely have the same ip-block also.

A lot will depend on if they sort out the mess they made with the
registers. Given how simple these drivers are, it is sometimes better
to just write a new driver once the registers are in sane blocks,
rather than all interleaved.

       Andrew


^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2024-08-18 17:35 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-08-11 16:12 [PATCH 0/2] Add pinctrl support to EN7581 SoC Lorenzo Bianconi
2024-08-11 16:12 ` [PATCH 1/2] dt-bindings: pinctrl: airoha: Add EN7581 pinctrl controller Lorenzo Bianconi
2024-08-12  6:48   ` Krzysztof Kozlowski
2024-08-13  8:06     ` Benjamin Larsson
2024-08-16 22:52       ` Rob Herring
2024-08-17 20:46         ` Benjamin Larsson
2024-08-17 21:39           ` Andrew Lunn
2024-08-18 12:48             ` Benjamin Larsson
2024-08-18 16:02               ` Andrew Lunn
2024-08-18 15:42                 ` Christian Marangi
2024-08-18 16:15                 ` Lorenzo Bianconi
2024-08-18 16:59                 ` Benjamin Larsson
2024-08-18 17:35                   ` Andrew Lunn
2024-08-18 14:22         ` Lorenzo Bianconi
2024-08-18 14:20     ` Lorenzo Bianconi
2024-08-11 16:12 ` [PATCH 2/2] pinctrl: airoha: Add support for EN7581 SoC Lorenzo Bianconi
2024-08-11 21:08   ` kernel test robot
2024-08-11 21:49   ` kernel test robot
2024-08-11 21:59   ` kernel test robot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).