Netdev List
 help / color / mirror / Atom feed
* [PATCH v2 0/2] pinctrl: qcom: add support for the TLMM controller on Nord platforms
From: Bartosz Golaszewski @ 2026-04-27 14:00 UTC (permalink / raw)
  To: Bjorn Andersson, Linus Walleij, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Richard Cochran, Bartosz Golaszewski, Shawn Guo,
	Arnd Bergmann, Dmitry Baryshkov
  Cc: linux-arm-msm, linux-gpio, devicetree, linux-kernel, netdev,
	Bartosz Golaszewski

This adds DT bindings describing the TLMM controller on Qualcomm Nord
platforms and implements the pinctrl driver.

More info on the platform here:
    https://lore.kernel.org/all/20260427003531.229671-1-shengchao.guo@oss.qualcomm.com/

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
---
Changes in v2:
- Order Kconfig entries alphabetically
- Fix the regex for the pin state pattern
- Fix maxItems for gpio-line-names
- Drop unneeded line break from bindings
- Rework the pin function naming to make resulting state entries in
  devicetree more concise (drop the line number suffix)
- drop .intr_target_reg from PINGROUP()
- fix values for interrupt entries in PINGROUP()
- drop unused SDC_QDSD_PINGROUP() and QUP_I3C()
- drop the arm64 defconfig updates from series
- rebased on top of v7.1-rc1
- Link to v1: https://patch.msgid.link/20260403-nord-tlmm-v1-0-4864f400c700@oss.qualcomm.com

---
Bartosz Golaszewski (2):
      dt-bindings: pinctrl: describe the Qualcomm nord-tlmm
      pinctrl: qcom: add the TLMM driver for the Nord platforms

 .../bindings/pinctrl/qcom,nord-tlmm.yaml           |  184 ++
 drivers/pinctrl/qcom/Kconfig.msm                   |    7 +
 drivers/pinctrl/qcom/Makefile                      |    1 +
 drivers/pinctrl/qcom/pinctrl-nord.c                | 2843 ++++++++++++++++++++
 4 files changed, 3035 insertions(+)
---
base-commit: 254f49634ee16a731174d2ae34bc50bd5f45e731
change-id: 20260403-nord-tlmm-b5878960cec6

Best regards,
-- 
Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>


^ permalink raw reply

* [PATCH v2 1/2] dt-bindings: pinctrl: describe the Qualcomm nord-tlmm
From: Bartosz Golaszewski @ 2026-04-27 14:00 UTC (permalink / raw)
  To: Bjorn Andersson, Linus Walleij, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Richard Cochran, Bartosz Golaszewski, Shawn Guo,
	Arnd Bergmann, Dmitry Baryshkov
  Cc: linux-arm-msm, linux-gpio, devicetree, linux-kernel, netdev,
	Bartosz Golaszewski
In-Reply-To: <20260427-nord-tlmm-v2-0-ade8e0f3d803@oss.qualcomm.com>

Add a DT binding document describing the TLMM pin controller available
on the Nord platforms from Qualcomm.

Co-developed-by: Shawn Guo <shengchao.guo@oss.qualcomm.com>
Signed-off-by: Shawn Guo <shengchao.guo@oss.qualcomm.com>
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
---
 .../bindings/pinctrl/qcom,nord-tlmm.yaml           | 184 +++++++++++++++++++++
 1 file changed, 184 insertions(+)

diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,nord-tlmm.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,nord-tlmm.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..b776dd20e15b6cfd3d99c7b96cf23733ada817bc
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/qcom,nord-tlmm.yaml
@@ -0,0 +1,184 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/qcom,nord-tlmm.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Technologies, Inc. SA8797P TLMM block
+
+maintainers:
+  - Bartosz Golaszewski <brgl@kernel.org>
+
+description:
+  Top Level Mode Multiplexer pin controller in Qualcomm SA8797P SoC.
+
+allOf:
+  - $ref: /schemas/pinctrl/qcom,tlmm-common.yaml#
+
+properties:
+  compatible:
+    const: qcom,nord-tlmm
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  gpio-reserved-ranges:
+    minItems: 1
+    maxItems: 90
+
+  gpio-line-names:
+    maxItems: 181
+
+patternProperties:
+  "-state$":
+    oneOf:
+      - $ref: "#/$defs/qcom-nord-tlmm-state"
+      - patternProperties:
+          "-pins$":
+            $ref: "#/$defs/qcom-nord-tlmm-state"
+        additionalProperties: false
+
+$defs:
+  qcom-nord-tlmm-state:
+    type: object
+    description:
+      Pinctrl node's client devices use subnodes for desired pin configuration.
+      Client device subnodes use below standard properties.
+    $ref: qcom,tlmm-common.yaml#/$defs/qcom-tlmm-state
+    unevaluatedProperties: false
+
+    properties:
+      pins:
+        description:
+          List of gpio pins affected by the properties specified in this
+          subnode.
+        items:
+          oneOf:
+            - pattern: "^gpio([0-9]|[1-9][0-9]|1[0-7][0-9]|180)$"
+            - enum: [ ufs_reset ]
+        minItems: 1
+        maxItems: 16
+
+      function:
+        description:
+          Specify the alternative function to be configured for the specified
+          pins.
+
+        enum: [ aoss_cti, atest_char0, atest_char1, atest_char2, atest_char3,
+                atest_char_start, atest_usb20, atest_usb21, aud_intfc0_clk,
+                aud_intfc0_data0, aud_intfc0_data1, aud_intfc0_data2,
+                aud_intfc0_data3, aud_intfc0_data4, aud_intfc0_data5,
+                aud_intfc0_data6, aud_intfc0_data7, aud_intfc0_ws,
+                aud_intfc10_clk, aud_intfc10_data0, aud_intfc10_data1,
+                aud_intfc10_ws, aud_intfc1_clk, aud_intfc1_data0,
+                aud_intfc1_data1, aud_intfc1_data2, aud_intfc1_data3,
+                aud_intfc1_data4, aud_intfc1_data5, aud_intfc1_data6,
+                aud_intfc1_data7, aud_intfc1_ws, aud_intfc2_clk,
+                aud_intfc2_data0, aud_intfc2_data1, aud_intfc2_data2,
+                aud_intfc2_data3, aud_intfc2_ws, aud_intfc3_clk,
+                aud_intfc3_data0, aud_intfc3_data1, aud_intfc3_ws,
+                aud_intfc4_clk, aud_intfc4_data0, aud_intfc4_data1,
+                aud_intfc4_ws, aud_intfc5_clk, aud_intfc5_data0,
+                aud_intfc5_data1, aud_intfc5_ws, aud_intfc6_clk,
+                aud_intfc6_data0, aud_intfc6_data1, aud_intfc6_ws,
+                aud_intfc7_clk, aud_intfc7_data0, aud_intfc7_data1,
+                aud_intfc7_ws, aud_intfc8_clk, aud_intfc8_data0,
+                aud_intfc8_data1, aud_intfc8_ws, aud_intfc9_clk,
+                aud_intfc9_data0, aud_intfc9_ws, aud_mclk0_mira,
+                aud_mclk0_mirb, aud_mclk1_mira, aud_mclk1_mirb,
+                aud_mclk2_mira, aud_mclk2_mirb, aud_refclk0, aud_refclk1,
+                bist_done, ccu_async_in0, ccu_async_in1, ccu_async_in2,
+                ccu_async_in3, ccu_async_in4, ccu_async_in5, ccu_i2c_scl0,
+                ccu_i2c_scl1, ccu_i2c_scl2, ccu_i2c_scl3, ccu_i2c_scl4,
+                ccu_i2c_scl5, ccu_i2c_scl6, ccu_i2c_scl7, ccu_i2c_scl8,
+                ccu_i2c_scl9, ccu_i2c_sda0, ccu_i2c_sda1, ccu_i2c_sda2,
+                ccu_i2c_sda3, ccu_i2c_sda4, ccu_i2c_sda5, ccu_i2c_sda6,
+                ccu_i2c_sda7, ccu_i2c_sda8, ccu_i2c_sda9, ccu_timer0,
+                ccu_timer1, ccu_timer10, ccu_timer11, ccu_timer12, ccu_timer13,
+                ccu_timer14, ccu_timer15, ccu_timer2, ccu_timer3, ccu_timer4,
+                ccu_timer5, ccu_timer6, ccu_timer7, ccu_timer8, ccu_timer9,
+                clink_debug, dbg_out, dbg_out_clk, ddr_bist_complete,
+                ddr_bist_fail, ddr_bist_start, ddr_bist_stop, ddr_pxi0,
+                ddr_pxi1, ddr_pxi10, ddr_pxi11, ddr_pxi12, ddr_pxi13, ddr_pxi14,
+                ddr_pxi15, ddr_pxi2, ddr_pxi3, ddr_pxi4, ddr_pxi5, ddr_pxi6,
+                ddr_pxi7, ddr_pxi8, ddr_pxi9, dp_rx0, dp_rx00, dp_rx01,
+                dp_rx0_mute, dp_rx1, dp_rx10, dp_rx11, dp_rx1_mute, edp0_hot,
+                edp0_lcd, edp1_hot, edp1_lcd, edp2_hot, edp2_lcd, edp3_hot,
+                edp3_lcd, emac0_mcg0, emac0_mcg1, emac0_mcg2, emac0_mcg3,
+                emac0_mdc, emac0_mdio, emac0_ptp, emac1_mcg0, emac1_mcg1,
+                emac1_mcg2, emac1_mcg3, emac1_mdc, emac1_mdio, emac1_ptp,
+                gcc_gp1_clk, gcc_gp2_clk, gcc_gp3_clk, gcc_gp4_clk, gcc_gp5_clk,
+                gcc_gp6_clk, gcc_gp7_clk, gcc_gp8_clk, jitter_bist, lbist_pass,
+                mbist_pass, mdp0_vsync0_out, mdp0_vsync10_out, mdp0_vsync1_out,
+                mdp0_vsync2_out, mdp0_vsync3_out, mdp0_vsync4_out,
+                mdp0_vsync5_out, mdp0_vsync6_out, mdp0_vsync7_out,
+                mdp0_vsync8_out, mdp0_vsync9_out, mdp1_vsync0_out,
+                mdp1_vsync10_out, mdp1_vsync1_out, mdp1_vsync2_out,
+                mdp1_vsync3_out, mdp1_vsync4_out, mdp1_vsync5_out,
+                mdp1_vsync6_out, mdp1_vsync7_out, mdp1_vsync8_out,
+                mdp1_vsync9_out, mdp_vsync_e, mdp_vsync_p, mdp_vsync_s,
+                pcie0_clk_req_n, pcie1_clk_req_n, pcie2_clk_req_n,
+                pcie3_clk_req_n, phase_flag0, phase_flag1, phase_flag10,
+                phase_flag11, phase_flag12, phase_flag13, phase_flag14,
+                phase_flag15, phase_flag16, phase_flag17, phase_flag18,
+                phase_flag19, phase_flag2, phase_flag20, phase_flag21,
+                phase_flag22, phase_flag23, phase_flag24, phase_flag25,
+                phase_flag26, phase_flag27, phase_flag28, phase_flag29,
+                phase_flag3, phase_flag30, phase_flag31, phase_flag4,
+                phase_flag5, phase_flag6, phase_flag7, phase_flag8,
+                phase_flag9, pll_bist_sync, pll_clk_aux, prng_rosc0, prng_rosc1,
+                pwrbrk_i_n, qdss_cti, qdss_gpio, qdss_gpio0, qdss_gpio1,
+                qdss_gpio10, qdss_gpio11, qdss_gpio12, qdss_gpio13, qdss_gpio14,
+                qdss_gpio15, qdss_gpio2, qdss_gpio3, qdss_gpio4, qdss_gpio5,
+                qdss_gpio6, qdss_gpio7, qdss_gpio8, qdss_gpio9, qspi0, qspi1,
+                qspi2, qspi3, qspi_clk, qspi_cs0_n, qspi_cs1_n,
+                qup0_se0, qup0_se1, qup0_se2, qup0_se3, qup0_se4, qup0_se5,
+                qup1_se0, qup1_se1, qup1_se2, qup1_se3, qup1_se4, qup1_se5,
+                qup1_se6,
+                qup2_se0, qup2_se1, qup2_se2, qup2_se3, qup2_se4, qup2_se5,
+                qup2_se6,
+                qup3_se0_mira, qup3_se0_mirb,
+                sailss_ospi, sdc4_clk, sdc4_cmd, sdc4_data, smb_alert,
+                smb_alert_n, smb_clk, smb_dat, tb_trig_sdc4, tmess_prng0,
+                tmess_prng1, tsc_timer0, tsc_timer1, tsc_timer2, tsc_timer3,
+                tsc_timer4, tsc_timer5, tsc_timer6, tsc_timer7, tsc_timer8,
+                tsc_timer9, tsense_pwm1, tsense_pwm2, tsense_pwm3, tsense_pwm4,
+                tsense_pwm5, tsense_pwm6, tsense_pwm7, tsense_pwm8, usb0_hs,
+                usb0_phy_ps, usb1_hs, usb1_phy_ps, usb2_hs, usxgmii0_phy,
+                usxgmii1_phy, vsense_trigger_mirnat, wcn_sw, wcn_sw_ctrl]
+
+    required:
+      - pins
+
+required:
+  - compatible
+  - reg
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    tlmm: pinctrl@f100000 {
+        compatible = "qcom,nord-tlmm";
+        reg = <0x0f100000 0xc0000>;
+        interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>;
+        gpio-controller;
+        #gpio-cells = <2>;
+        interrupt-controller;
+        #interrupt-cells = <2>;
+        gpio-ranges = <&tlmm 0 0 181>;
+        wakeup-parent = <&pdc>;
+
+        qup_uart15_default: qup-uart15-default-state {
+            pins = "gpio147", "gpio148";
+            function = "qup2_se2";
+            drive-strength = <2>;
+            bias-disable;
+        };
+    };
+...

-- 
2.47.3


^ permalink raw reply related

* [PATCH v2 2/2] pinctrl: qcom: add the TLMM driver for the Nord platforms
From: Bartosz Golaszewski @ 2026-04-27 14:00 UTC (permalink / raw)
  To: Bjorn Andersson, Linus Walleij, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Richard Cochran, Bartosz Golaszewski, Shawn Guo,
	Arnd Bergmann, Dmitry Baryshkov
  Cc: linux-arm-msm, linux-gpio, devicetree, linux-kernel, netdev,
	Bartosz Golaszewski
In-Reply-To: <20260427-nord-tlmm-v2-0-ade8e0f3d803@oss.qualcomm.com>

Add support for the TLMM controller on the Qualcomm Nord platform.

Co-developed-by: Shawn Guo <shengchao.guo@oss.qualcomm.com>
Signed-off-by: Shawn Guo <shengchao.guo@oss.qualcomm.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
---
 drivers/pinctrl/qcom/Kconfig.msm    |    7 +
 drivers/pinctrl/qcom/Makefile       |    1 +
 drivers/pinctrl/qcom/pinctrl-nord.c | 2843 +++++++++++++++++++++++++++++++++++
 3 files changed, 2851 insertions(+)

diff --git a/drivers/pinctrl/qcom/Kconfig.msm b/drivers/pinctrl/qcom/Kconfig.msm
index 836cdeca1006ff7ad5030ac5c537d775d3f0261b..67124ac607baa0f317e0713760a0a2fefba1e2de 100644
--- a/drivers/pinctrl/qcom/Kconfig.msm
+++ b/drivers/pinctrl/qcom/Kconfig.msm
@@ -229,6 +229,13 @@ config PINCTRL_MSM8998
 	  This is the pinctrl, pinmux, pinconf and gpiolib driver for the
 	  Qualcomm TLMM block found in the Qualcomm MSM8998 platform.
 
+config PINCTRL_NORD
+	tristate "Qualcomm Technologies Inc NORD (SA8797p) pin controller driver"
+	depends on ARM64 || COMPILE_TEST
+	help
+	  This is the pinctrl, pinmux and pinconf driver for the Qualcomm
+	  TLMM block found on the Qualcomm NORD platforms.
+
 config PINCTRL_QCM2290
 	tristate "Qualcomm QCM2290 pin controller driver"
 	depends on ARM64 || COMPILE_TEST
diff --git a/drivers/pinctrl/qcom/Makefile b/drivers/pinctrl/qcom/Makefile
index 84bda3ada8749e89077c2d4d1065d0db0e4e4181..12e7a51ad894261a37b00dc5520484803ecb8607 100644
--- a/drivers/pinctrl/qcom/Makefile
+++ b/drivers/pinctrl/qcom/Makefile
@@ -37,6 +37,7 @@ obj-$(CONFIG_PINCTRL_MDM9607)	+= pinctrl-mdm9607.o
 obj-$(CONFIG_PINCTRL_MDM9615)	+= pinctrl-mdm9615.o
 obj-$(CONFIG_PINCTRL_MILOS) += pinctrl-milos.o
 obj-$(CONFIG_PINCTRL_MILOS_LPASS_LPI) += pinctrl-milos-lpass-lpi.o
+obj-$(CONFIG_PINCTRL_NORD)	+= pinctrl-nord.o
 obj-$(CONFIG_PINCTRL_QCOM_SPMI_PMIC) += pinctrl-spmi-gpio.o
 obj-$(CONFIG_PINCTRL_QCOM_SPMI_PMIC) += pinctrl-spmi-mpp.o
 obj-$(CONFIG_PINCTRL_QCOM_SSBI_PMIC) += pinctrl-ssbi-gpio.o
diff --git a/drivers/pinctrl/qcom/pinctrl-nord.c b/drivers/pinctrl/qcom/pinctrl-nord.c
new file mode 100644
index 0000000000000000000000000000000000000000..f9b91b9341c9d8e277762bf0ba9a6708fb50529e
--- /dev/null
+++ b/drivers/pinctrl/qcom/pinctrl-nord.c
@@ -0,0 +1,2843 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+#include "pinctrl-msm.h"
+
+#define REG_SIZE 0x1000
+#define PINGROUP(id, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11)    \
+	{                                                             \
+		.grp = PINCTRL_PINGROUP("gpio" #id,                   \
+					gpio##id##_pins,              \
+					ARRAY_SIZE(gpio##id##_pins)), \
+		.ctl_reg = REG_SIZE * id,                             \
+		.io_reg = 0x4 + REG_SIZE * id,                        \
+		.intr_cfg_reg = 0x8 + REG_SIZE * id,                  \
+		.intr_status_reg = 0xc + REG_SIZE * id,               \
+		.mux_bit = 2,                                         \
+		.pull_bit = 0,                                        \
+		.drv_bit = 6,                                         \
+		.egpio_enable = 12,                                   \
+		.egpio_present = 11,                                  \
+		.oe_bit = 9,                                          \
+		.in_bit = 0,                                          \
+		.out_bit = 1,                                         \
+		.intr_enable_bit = 0,                                 \
+		.intr_status_bit = 0,                                 \
+		.intr_wakeup_present_bit = 6,                         \
+		.intr_wakeup_enable_bit = 7,                          \
+		.intr_target_bit = 8,                                 \
+		.intr_target_kpss_val = 3,                            \
+		.intr_raw_status_bit = 4,                             \
+		.intr_polarity_bit = 1,                               \
+		.intr_detection_bit = 2,                              \
+		.intr_detection_width = 2,                            \
+		.funcs = (int[]){                                     \
+			msm_mux_gpio, /* gpio mode */                 \
+			msm_mux_##f1,                                 \
+			msm_mux_##f2,                                 \
+			msm_mux_##f3,                                 \
+			msm_mux_##f4,                                 \
+			msm_mux_##f5,                                 \
+			msm_mux_##f6,                                 \
+			msm_mux_##f7,                                 \
+			msm_mux_##f8,                                 \
+			msm_mux_##f9,                                 \
+			msm_mux_##f10,                                \
+			msm_mux_##f11 /* egpio mode */                \
+		},                                                    \
+		.nfuncs = 12,                                         \
+	}
+
+#define UFS_RESET(pg_name, offset)                                   \
+	{                                                            \
+		.grp = PINCTRL_PINGROUP(#pg_name,                    \
+					pg_name##_pins,              \
+					ARRAY_SIZE(pg_name##_pins)), \
+		.ctl_reg = offset,                                   \
+		.io_reg = offset + 0x4,                              \
+		.intr_cfg_reg = 0,                                   \
+		.intr_status_reg = 0,                                \
+		.mux_bit = -1,                                       \
+		.pull_bit = 3,                                       \
+		.drv_bit = 0,                                        \
+		.oe_bit = -1,                                        \
+		.in_bit = -1,                                        \
+		.out_bit = 0,                                        \
+		.intr_enable_bit = -1,                               \
+		.intr_status_bit = -1,                               \
+		.intr_target_bit = -1,                               \
+		.intr_raw_status_bit = -1,                           \
+		.intr_polarity_bit = -1,                             \
+		.intr_detection_bit = -1,                            \
+		.intr_detection_width = -1,                          \
+	}
+
+static const struct pinctrl_pin_desc nord_pins[] = {
+	PINCTRL_PIN(0, "GPIO_0"),
+	PINCTRL_PIN(1, "GPIO_1"),
+	PINCTRL_PIN(2, "GPIO_2"),
+	PINCTRL_PIN(3, "GPIO_3"),
+	PINCTRL_PIN(4, "GPIO_4"),
+	PINCTRL_PIN(5, "GPIO_5"),
+	PINCTRL_PIN(6, "GPIO_6"),
+	PINCTRL_PIN(7, "GPIO_7"),
+	PINCTRL_PIN(8, "GPIO_8"),
+	PINCTRL_PIN(9, "GPIO_9"),
+	PINCTRL_PIN(10, "GPIO_10"),
+	PINCTRL_PIN(11, "GPIO_11"),
+	PINCTRL_PIN(12, "GPIO_12"),
+	PINCTRL_PIN(13, "GPIO_13"),
+	PINCTRL_PIN(14, "GPIO_14"),
+	PINCTRL_PIN(15, "GPIO_15"),
+	PINCTRL_PIN(16, "GPIO_16"),
+	PINCTRL_PIN(17, "GPIO_17"),
+	PINCTRL_PIN(18, "GPIO_18"),
+	PINCTRL_PIN(19, "GPIO_19"),
+	PINCTRL_PIN(20, "GPIO_20"),
+	PINCTRL_PIN(21, "GPIO_21"),
+	PINCTRL_PIN(22, "GPIO_22"),
+	PINCTRL_PIN(23, "GPIO_23"),
+	PINCTRL_PIN(24, "GPIO_24"),
+	PINCTRL_PIN(25, "GPIO_25"),
+	PINCTRL_PIN(26, "GPIO_26"),
+	PINCTRL_PIN(27, "GPIO_27"),
+	PINCTRL_PIN(28, "GPIO_28"),
+	PINCTRL_PIN(29, "GPIO_29"),
+	PINCTRL_PIN(30, "GPIO_30"),
+	PINCTRL_PIN(31, "GPIO_31"),
+	PINCTRL_PIN(32, "GPIO_32"),
+	PINCTRL_PIN(33, "GPIO_33"),
+	PINCTRL_PIN(34, "GPIO_34"),
+	PINCTRL_PIN(35, "GPIO_35"),
+	PINCTRL_PIN(36, "GPIO_36"),
+	PINCTRL_PIN(37, "GPIO_37"),
+	PINCTRL_PIN(38, "GPIO_38"),
+	PINCTRL_PIN(39, "GPIO_39"),
+	PINCTRL_PIN(40, "GPIO_40"),
+	PINCTRL_PIN(41, "GPIO_41"),
+	PINCTRL_PIN(42, "GPIO_42"),
+	PINCTRL_PIN(43, "GPIO_43"),
+	PINCTRL_PIN(44, "GPIO_44"),
+	PINCTRL_PIN(45, "GPIO_45"),
+	PINCTRL_PIN(46, "GPIO_46"),
+	PINCTRL_PIN(47, "GPIO_47"),
+	PINCTRL_PIN(48, "GPIO_48"),
+	PINCTRL_PIN(49, "GPIO_49"),
+	PINCTRL_PIN(50, "GPIO_50"),
+	PINCTRL_PIN(51, "GPIO_51"),
+	PINCTRL_PIN(52, "GPIO_52"),
+	PINCTRL_PIN(53, "GPIO_53"),
+	PINCTRL_PIN(54, "GPIO_54"),
+	PINCTRL_PIN(55, "GPIO_55"),
+	PINCTRL_PIN(56, "GPIO_56"),
+	PINCTRL_PIN(57, "GPIO_57"),
+	PINCTRL_PIN(58, "GPIO_58"),
+	PINCTRL_PIN(59, "GPIO_59"),
+	PINCTRL_PIN(60, "GPIO_60"),
+	PINCTRL_PIN(61, "GPIO_61"),
+	PINCTRL_PIN(62, "GPIO_62"),
+	PINCTRL_PIN(63, "GPIO_63"),
+	PINCTRL_PIN(64, "GPIO_64"),
+	PINCTRL_PIN(65, "GPIO_65"),
+	PINCTRL_PIN(66, "GPIO_66"),
+	PINCTRL_PIN(67, "GPIO_67"),
+	PINCTRL_PIN(68, "GPIO_68"),
+	PINCTRL_PIN(69, "GPIO_69"),
+	PINCTRL_PIN(70, "GPIO_70"),
+	PINCTRL_PIN(71, "GPIO_71"),
+	PINCTRL_PIN(72, "GPIO_72"),
+	PINCTRL_PIN(73, "GPIO_73"),
+	PINCTRL_PIN(74, "GPIO_74"),
+	PINCTRL_PIN(75, "GPIO_75"),
+	PINCTRL_PIN(76, "GPIO_76"),
+	PINCTRL_PIN(77, "GPIO_77"),
+	PINCTRL_PIN(78, "GPIO_78"),
+	PINCTRL_PIN(79, "GPIO_79"),
+	PINCTRL_PIN(80, "GPIO_80"),
+	PINCTRL_PIN(81, "GPIO_81"),
+	PINCTRL_PIN(82, "GPIO_82"),
+	PINCTRL_PIN(83, "GPIO_83"),
+	PINCTRL_PIN(84, "GPIO_84"),
+	PINCTRL_PIN(85, "GPIO_85"),
+	PINCTRL_PIN(86, "GPIO_86"),
+	PINCTRL_PIN(87, "GPIO_87"),
+	PINCTRL_PIN(88, "GPIO_88"),
+	PINCTRL_PIN(89, "GPIO_89"),
+	PINCTRL_PIN(90, "GPIO_90"),
+	PINCTRL_PIN(91, "GPIO_91"),
+	PINCTRL_PIN(92, "GPIO_92"),
+	PINCTRL_PIN(93, "GPIO_93"),
+	PINCTRL_PIN(94, "GPIO_94"),
+	PINCTRL_PIN(95, "GPIO_95"),
+	PINCTRL_PIN(96, "GPIO_96"),
+	PINCTRL_PIN(97, "GPIO_97"),
+	PINCTRL_PIN(98, "GPIO_98"),
+	PINCTRL_PIN(99, "GPIO_99"),
+	PINCTRL_PIN(100, "GPIO_100"),
+	PINCTRL_PIN(101, "GPIO_101"),
+	PINCTRL_PIN(102, "GPIO_102"),
+	PINCTRL_PIN(103, "GPIO_103"),
+	PINCTRL_PIN(104, "GPIO_104"),
+	PINCTRL_PIN(105, "GPIO_105"),
+	PINCTRL_PIN(106, "GPIO_106"),
+	PINCTRL_PIN(107, "GPIO_107"),
+	PINCTRL_PIN(108, "GPIO_108"),
+	PINCTRL_PIN(109, "GPIO_109"),
+	PINCTRL_PIN(110, "GPIO_110"),
+	PINCTRL_PIN(111, "GPIO_111"),
+	PINCTRL_PIN(112, "GPIO_112"),
+	PINCTRL_PIN(113, "GPIO_113"),
+	PINCTRL_PIN(114, "GPIO_114"),
+	PINCTRL_PIN(115, "GPIO_115"),
+	PINCTRL_PIN(116, "GPIO_116"),
+	PINCTRL_PIN(117, "GPIO_117"),
+	PINCTRL_PIN(118, "GPIO_118"),
+	PINCTRL_PIN(119, "GPIO_119"),
+	PINCTRL_PIN(120, "GPIO_120"),
+	PINCTRL_PIN(121, "GPIO_121"),
+	PINCTRL_PIN(122, "GPIO_122"),
+	PINCTRL_PIN(123, "GPIO_123"),
+	PINCTRL_PIN(124, "GPIO_124"),
+	PINCTRL_PIN(125, "GPIO_125"),
+	PINCTRL_PIN(126, "GPIO_126"),
+	PINCTRL_PIN(127, "GPIO_127"),
+	PINCTRL_PIN(128, "GPIO_128"),
+	PINCTRL_PIN(129, "GPIO_129"),
+	PINCTRL_PIN(130, "GPIO_130"),
+	PINCTRL_PIN(131, "GPIO_131"),
+	PINCTRL_PIN(132, "GPIO_132"),
+	PINCTRL_PIN(133, "GPIO_133"),
+	PINCTRL_PIN(134, "GPIO_134"),
+	PINCTRL_PIN(135, "GPIO_135"),
+	PINCTRL_PIN(136, "GPIO_136"),
+	PINCTRL_PIN(137, "GPIO_137"),
+	PINCTRL_PIN(138, "GPIO_138"),
+	PINCTRL_PIN(139, "GPIO_139"),
+	PINCTRL_PIN(140, "GPIO_140"),
+	PINCTRL_PIN(141, "GPIO_141"),
+	PINCTRL_PIN(142, "GPIO_142"),
+	PINCTRL_PIN(143, "GPIO_143"),
+	PINCTRL_PIN(144, "GPIO_144"),
+	PINCTRL_PIN(145, "GPIO_145"),
+	PINCTRL_PIN(146, "GPIO_146"),
+	PINCTRL_PIN(147, "GPIO_147"),
+	PINCTRL_PIN(148, "GPIO_148"),
+	PINCTRL_PIN(149, "GPIO_149"),
+	PINCTRL_PIN(150, "GPIO_150"),
+	PINCTRL_PIN(151, "GPIO_151"),
+	PINCTRL_PIN(152, "GPIO_152"),
+	PINCTRL_PIN(153, "GPIO_153"),
+	PINCTRL_PIN(154, "GPIO_154"),
+	PINCTRL_PIN(155, "GPIO_155"),
+	PINCTRL_PIN(156, "GPIO_156"),
+	PINCTRL_PIN(157, "GPIO_157"),
+	PINCTRL_PIN(158, "GPIO_158"),
+	PINCTRL_PIN(159, "GPIO_159"),
+	PINCTRL_PIN(160, "GPIO_160"),
+	PINCTRL_PIN(161, "GPIO_161"),
+	PINCTRL_PIN(162, "GPIO_162"),
+	PINCTRL_PIN(163, "GPIO_163"),
+	PINCTRL_PIN(164, "GPIO_164"),
+	PINCTRL_PIN(165, "GPIO_165"),
+	PINCTRL_PIN(166, "GPIO_166"),
+	PINCTRL_PIN(167, "GPIO_167"),
+	PINCTRL_PIN(168, "GPIO_168"),
+	PINCTRL_PIN(169, "GPIO_169"),
+	PINCTRL_PIN(170, "GPIO_170"),
+	PINCTRL_PIN(171, "GPIO_171"),
+	PINCTRL_PIN(172, "GPIO_172"),
+	PINCTRL_PIN(173, "GPIO_173"),
+	PINCTRL_PIN(174, "GPIO_174"),
+	PINCTRL_PIN(175, "GPIO_175"),
+	PINCTRL_PIN(176, "GPIO_176"),
+	PINCTRL_PIN(177, "GPIO_177"),
+	PINCTRL_PIN(178, "GPIO_178"),
+	PINCTRL_PIN(179, "GPIO_179"),
+	PINCTRL_PIN(180, "GPIO_180"),
+	PINCTRL_PIN(181, "UFS_RESET"),
+};
+
+#define DECLARE_MSM_GPIO_PINS(pin) \
+	static const unsigned int gpio##pin##_pins[] = { pin }
+DECLARE_MSM_GPIO_PINS(0);
+DECLARE_MSM_GPIO_PINS(1);
+DECLARE_MSM_GPIO_PINS(2);
+DECLARE_MSM_GPIO_PINS(3);
+DECLARE_MSM_GPIO_PINS(4);
+DECLARE_MSM_GPIO_PINS(5);
+DECLARE_MSM_GPIO_PINS(6);
+DECLARE_MSM_GPIO_PINS(7);
+DECLARE_MSM_GPIO_PINS(8);
+DECLARE_MSM_GPIO_PINS(9);
+DECLARE_MSM_GPIO_PINS(10);
+DECLARE_MSM_GPIO_PINS(11);
+DECLARE_MSM_GPIO_PINS(12);
+DECLARE_MSM_GPIO_PINS(13);
+DECLARE_MSM_GPIO_PINS(14);
+DECLARE_MSM_GPIO_PINS(15);
+DECLARE_MSM_GPIO_PINS(16);
+DECLARE_MSM_GPIO_PINS(17);
+DECLARE_MSM_GPIO_PINS(18);
+DECLARE_MSM_GPIO_PINS(19);
+DECLARE_MSM_GPIO_PINS(20);
+DECLARE_MSM_GPIO_PINS(21);
+DECLARE_MSM_GPIO_PINS(22);
+DECLARE_MSM_GPIO_PINS(23);
+DECLARE_MSM_GPIO_PINS(24);
+DECLARE_MSM_GPIO_PINS(25);
+DECLARE_MSM_GPIO_PINS(26);
+DECLARE_MSM_GPIO_PINS(27);
+DECLARE_MSM_GPIO_PINS(28);
+DECLARE_MSM_GPIO_PINS(29);
+DECLARE_MSM_GPIO_PINS(30);
+DECLARE_MSM_GPIO_PINS(31);
+DECLARE_MSM_GPIO_PINS(32);
+DECLARE_MSM_GPIO_PINS(33);
+DECLARE_MSM_GPIO_PINS(34);
+DECLARE_MSM_GPIO_PINS(35);
+DECLARE_MSM_GPIO_PINS(36);
+DECLARE_MSM_GPIO_PINS(37);
+DECLARE_MSM_GPIO_PINS(38);
+DECLARE_MSM_GPIO_PINS(39);
+DECLARE_MSM_GPIO_PINS(40);
+DECLARE_MSM_GPIO_PINS(41);
+DECLARE_MSM_GPIO_PINS(42);
+DECLARE_MSM_GPIO_PINS(43);
+DECLARE_MSM_GPIO_PINS(44);
+DECLARE_MSM_GPIO_PINS(45);
+DECLARE_MSM_GPIO_PINS(46);
+DECLARE_MSM_GPIO_PINS(47);
+DECLARE_MSM_GPIO_PINS(48);
+DECLARE_MSM_GPIO_PINS(49);
+DECLARE_MSM_GPIO_PINS(50);
+DECLARE_MSM_GPIO_PINS(51);
+DECLARE_MSM_GPIO_PINS(52);
+DECLARE_MSM_GPIO_PINS(53);
+DECLARE_MSM_GPIO_PINS(54);
+DECLARE_MSM_GPIO_PINS(55);
+DECLARE_MSM_GPIO_PINS(56);
+DECLARE_MSM_GPIO_PINS(57);
+DECLARE_MSM_GPIO_PINS(58);
+DECLARE_MSM_GPIO_PINS(59);
+DECLARE_MSM_GPIO_PINS(60);
+DECLARE_MSM_GPIO_PINS(61);
+DECLARE_MSM_GPIO_PINS(62);
+DECLARE_MSM_GPIO_PINS(63);
+DECLARE_MSM_GPIO_PINS(64);
+DECLARE_MSM_GPIO_PINS(65);
+DECLARE_MSM_GPIO_PINS(66);
+DECLARE_MSM_GPIO_PINS(67);
+DECLARE_MSM_GPIO_PINS(68);
+DECLARE_MSM_GPIO_PINS(69);
+DECLARE_MSM_GPIO_PINS(70);
+DECLARE_MSM_GPIO_PINS(71);
+DECLARE_MSM_GPIO_PINS(72);
+DECLARE_MSM_GPIO_PINS(73);
+DECLARE_MSM_GPIO_PINS(74);
+DECLARE_MSM_GPIO_PINS(75);
+DECLARE_MSM_GPIO_PINS(76);
+DECLARE_MSM_GPIO_PINS(77);
+DECLARE_MSM_GPIO_PINS(78);
+DECLARE_MSM_GPIO_PINS(79);
+DECLARE_MSM_GPIO_PINS(80);
+DECLARE_MSM_GPIO_PINS(81);
+DECLARE_MSM_GPIO_PINS(82);
+DECLARE_MSM_GPIO_PINS(83);
+DECLARE_MSM_GPIO_PINS(84);
+DECLARE_MSM_GPIO_PINS(85);
+DECLARE_MSM_GPIO_PINS(86);
+DECLARE_MSM_GPIO_PINS(87);
+DECLARE_MSM_GPIO_PINS(88);
+DECLARE_MSM_GPIO_PINS(89);
+DECLARE_MSM_GPIO_PINS(90);
+DECLARE_MSM_GPIO_PINS(91);
+DECLARE_MSM_GPIO_PINS(92);
+DECLARE_MSM_GPIO_PINS(93);
+DECLARE_MSM_GPIO_PINS(94);
+DECLARE_MSM_GPIO_PINS(95);
+DECLARE_MSM_GPIO_PINS(96);
+DECLARE_MSM_GPIO_PINS(97);
+DECLARE_MSM_GPIO_PINS(98);
+DECLARE_MSM_GPIO_PINS(99);
+DECLARE_MSM_GPIO_PINS(100);
+DECLARE_MSM_GPIO_PINS(101);
+DECLARE_MSM_GPIO_PINS(102);
+DECLARE_MSM_GPIO_PINS(103);
+DECLARE_MSM_GPIO_PINS(104);
+DECLARE_MSM_GPIO_PINS(105);
+DECLARE_MSM_GPIO_PINS(106);
+DECLARE_MSM_GPIO_PINS(107);
+DECLARE_MSM_GPIO_PINS(108);
+DECLARE_MSM_GPIO_PINS(109);
+DECLARE_MSM_GPIO_PINS(110);
+DECLARE_MSM_GPIO_PINS(111);
+DECLARE_MSM_GPIO_PINS(112);
+DECLARE_MSM_GPIO_PINS(113);
+DECLARE_MSM_GPIO_PINS(114);
+DECLARE_MSM_GPIO_PINS(115);
+DECLARE_MSM_GPIO_PINS(116);
+DECLARE_MSM_GPIO_PINS(117);
+DECLARE_MSM_GPIO_PINS(118);
+DECLARE_MSM_GPIO_PINS(119);
+DECLARE_MSM_GPIO_PINS(120);
+DECLARE_MSM_GPIO_PINS(121);
+DECLARE_MSM_GPIO_PINS(122);
+DECLARE_MSM_GPIO_PINS(123);
+DECLARE_MSM_GPIO_PINS(124);
+DECLARE_MSM_GPIO_PINS(125);
+DECLARE_MSM_GPIO_PINS(126);
+DECLARE_MSM_GPIO_PINS(127);
+DECLARE_MSM_GPIO_PINS(128);
+DECLARE_MSM_GPIO_PINS(129);
+DECLARE_MSM_GPIO_PINS(130);
+DECLARE_MSM_GPIO_PINS(131);
+DECLARE_MSM_GPIO_PINS(132);
+DECLARE_MSM_GPIO_PINS(133);
+DECLARE_MSM_GPIO_PINS(134);
+DECLARE_MSM_GPIO_PINS(135);
+DECLARE_MSM_GPIO_PINS(136);
+DECLARE_MSM_GPIO_PINS(137);
+DECLARE_MSM_GPIO_PINS(138);
+DECLARE_MSM_GPIO_PINS(139);
+DECLARE_MSM_GPIO_PINS(140);
+DECLARE_MSM_GPIO_PINS(141);
+DECLARE_MSM_GPIO_PINS(142);
+DECLARE_MSM_GPIO_PINS(143);
+DECLARE_MSM_GPIO_PINS(144);
+DECLARE_MSM_GPIO_PINS(145);
+DECLARE_MSM_GPIO_PINS(146);
+DECLARE_MSM_GPIO_PINS(147);
+DECLARE_MSM_GPIO_PINS(148);
+DECLARE_MSM_GPIO_PINS(149);
+DECLARE_MSM_GPIO_PINS(150);
+DECLARE_MSM_GPIO_PINS(151);
+DECLARE_MSM_GPIO_PINS(152);
+DECLARE_MSM_GPIO_PINS(153);
+DECLARE_MSM_GPIO_PINS(154);
+DECLARE_MSM_GPIO_PINS(155);
+DECLARE_MSM_GPIO_PINS(156);
+DECLARE_MSM_GPIO_PINS(157);
+DECLARE_MSM_GPIO_PINS(158);
+DECLARE_MSM_GPIO_PINS(159);
+DECLARE_MSM_GPIO_PINS(160);
+DECLARE_MSM_GPIO_PINS(161);
+DECLARE_MSM_GPIO_PINS(162);
+DECLARE_MSM_GPIO_PINS(163);
+DECLARE_MSM_GPIO_PINS(164);
+DECLARE_MSM_GPIO_PINS(165);
+DECLARE_MSM_GPIO_PINS(166);
+DECLARE_MSM_GPIO_PINS(167);
+DECLARE_MSM_GPIO_PINS(168);
+DECLARE_MSM_GPIO_PINS(169);
+DECLARE_MSM_GPIO_PINS(170);
+DECLARE_MSM_GPIO_PINS(171);
+DECLARE_MSM_GPIO_PINS(172);
+DECLARE_MSM_GPIO_PINS(173);
+DECLARE_MSM_GPIO_PINS(174);
+DECLARE_MSM_GPIO_PINS(175);
+DECLARE_MSM_GPIO_PINS(176);
+DECLARE_MSM_GPIO_PINS(177);
+DECLARE_MSM_GPIO_PINS(178);
+DECLARE_MSM_GPIO_PINS(179);
+DECLARE_MSM_GPIO_PINS(180);
+
+static const unsigned int ufs_reset_pins[] = { 181 };
+
+enum nord_functions {
+	msm_mux_gpio,
+	msm_mux_aoss_cti,
+	msm_mux_atest_char0,
+	msm_mux_atest_char1,
+	msm_mux_atest_char2,
+	msm_mux_atest_char3,
+	msm_mux_atest_char_start,
+	msm_mux_atest_usb20,
+	msm_mux_atest_usb21,
+	msm_mux_aud_intfc0_clk,
+	msm_mux_aud_intfc0_data0,
+	msm_mux_aud_intfc0_data1,
+	msm_mux_aud_intfc0_data2,
+	msm_mux_aud_intfc0_data3,
+	msm_mux_aud_intfc0_data4,
+	msm_mux_aud_intfc0_data5,
+	msm_mux_aud_intfc0_data6,
+	msm_mux_aud_intfc0_data7,
+	msm_mux_aud_intfc0_ws,
+	msm_mux_aud_intfc10_clk,
+	msm_mux_aud_intfc10_data0,
+	msm_mux_aud_intfc10_data1,
+	msm_mux_aud_intfc10_ws,
+	msm_mux_aud_intfc1_clk,
+	msm_mux_aud_intfc1_data0,
+	msm_mux_aud_intfc1_data1,
+	msm_mux_aud_intfc1_data2,
+	msm_mux_aud_intfc1_data3,
+	msm_mux_aud_intfc1_data4,
+	msm_mux_aud_intfc1_data5,
+	msm_mux_aud_intfc1_data6,
+	msm_mux_aud_intfc1_data7,
+	msm_mux_aud_intfc1_ws,
+	msm_mux_aud_intfc2_clk,
+	msm_mux_aud_intfc2_data0,
+	msm_mux_aud_intfc2_data1,
+	msm_mux_aud_intfc2_data2,
+	msm_mux_aud_intfc2_data3,
+	msm_mux_aud_intfc2_ws,
+	msm_mux_aud_intfc3_clk,
+	msm_mux_aud_intfc3_data0,
+	msm_mux_aud_intfc3_data1,
+	msm_mux_aud_intfc3_ws,
+	msm_mux_aud_intfc4_clk,
+	msm_mux_aud_intfc4_data0,
+	msm_mux_aud_intfc4_data1,
+	msm_mux_aud_intfc4_ws,
+	msm_mux_aud_intfc5_clk,
+	msm_mux_aud_intfc5_data0,
+	msm_mux_aud_intfc5_data1,
+	msm_mux_aud_intfc5_ws,
+	msm_mux_aud_intfc6_clk,
+	msm_mux_aud_intfc6_data0,
+	msm_mux_aud_intfc6_data1,
+	msm_mux_aud_intfc6_ws,
+	msm_mux_aud_intfc7_clk,
+	msm_mux_aud_intfc7_data0,
+	msm_mux_aud_intfc7_data1,
+	msm_mux_aud_intfc7_ws,
+	msm_mux_aud_intfc8_clk,
+	msm_mux_aud_intfc8_data0,
+	msm_mux_aud_intfc8_data1,
+	msm_mux_aud_intfc8_ws,
+	msm_mux_aud_intfc9_clk,
+	msm_mux_aud_intfc9_data0,
+	msm_mux_aud_intfc9_ws,
+	msm_mux_aud_mclk0_mira,
+	msm_mux_aud_mclk0_mirb,
+	msm_mux_aud_mclk1_mira,
+	msm_mux_aud_mclk1_mirb,
+	msm_mux_aud_mclk2_mira,
+	msm_mux_aud_mclk2_mirb,
+	msm_mux_aud_refclk0,
+	msm_mux_aud_refclk1,
+	msm_mux_bist_done,
+	msm_mux_ccu_async_in0,
+	msm_mux_ccu_async_in1,
+	msm_mux_ccu_async_in2,
+	msm_mux_ccu_async_in3,
+	msm_mux_ccu_async_in4,
+	msm_mux_ccu_async_in5,
+	msm_mux_ccu_i2c_scl0,
+	msm_mux_ccu_i2c_scl1,
+	msm_mux_ccu_i2c_scl2,
+	msm_mux_ccu_i2c_scl3,
+	msm_mux_ccu_i2c_scl4,
+	msm_mux_ccu_i2c_scl5,
+	msm_mux_ccu_i2c_scl6,
+	msm_mux_ccu_i2c_scl7,
+	msm_mux_ccu_i2c_scl8,
+	msm_mux_ccu_i2c_scl9,
+	msm_mux_ccu_i2c_sda0,
+	msm_mux_ccu_i2c_sda1,
+	msm_mux_ccu_i2c_sda2,
+	msm_mux_ccu_i2c_sda3,
+	msm_mux_ccu_i2c_sda4,
+	msm_mux_ccu_i2c_sda5,
+	msm_mux_ccu_i2c_sda6,
+	msm_mux_ccu_i2c_sda7,
+	msm_mux_ccu_i2c_sda8,
+	msm_mux_ccu_i2c_sda9,
+	msm_mux_ccu_timer0,
+	msm_mux_ccu_timer1,
+	msm_mux_ccu_timer10,
+	msm_mux_ccu_timer11,
+	msm_mux_ccu_timer12,
+	msm_mux_ccu_timer13,
+	msm_mux_ccu_timer14,
+	msm_mux_ccu_timer15,
+	msm_mux_ccu_timer2,
+	msm_mux_ccu_timer3,
+	msm_mux_ccu_timer4,
+	msm_mux_ccu_timer5,
+	msm_mux_ccu_timer6,
+	msm_mux_ccu_timer7,
+	msm_mux_ccu_timer8,
+	msm_mux_ccu_timer9,
+	msm_mux_clink_debug,
+	msm_mux_dbg_out,
+	msm_mux_dbg_out_clk,
+	msm_mux_ddr_bist_complete,
+	msm_mux_ddr_bist_fail,
+	msm_mux_ddr_bist_start,
+	msm_mux_ddr_bist_stop,
+	msm_mux_ddr_pxi0,
+	msm_mux_ddr_pxi1,
+	msm_mux_ddr_pxi10,
+	msm_mux_ddr_pxi11,
+	msm_mux_ddr_pxi12,
+	msm_mux_ddr_pxi13,
+	msm_mux_ddr_pxi14,
+	msm_mux_ddr_pxi15,
+	msm_mux_ddr_pxi2,
+	msm_mux_ddr_pxi3,
+	msm_mux_ddr_pxi4,
+	msm_mux_ddr_pxi5,
+	msm_mux_ddr_pxi6,
+	msm_mux_ddr_pxi7,
+	msm_mux_ddr_pxi8,
+	msm_mux_ddr_pxi9,
+	msm_mux_dp_rx0,
+	msm_mux_dp_rx00,
+	msm_mux_dp_rx01,
+	msm_mux_dp_rx0_mute,
+	msm_mux_dp_rx1,
+	msm_mux_dp_rx10,
+	msm_mux_dp_rx11,
+	msm_mux_dp_rx1_mute,
+	msm_mux_edp0_hot,
+	msm_mux_edp0_lcd,
+	msm_mux_edp1_hot,
+	msm_mux_edp1_lcd,
+	msm_mux_edp2_hot,
+	msm_mux_edp2_lcd,
+	msm_mux_edp3_hot,
+	msm_mux_edp3_lcd,
+	msm_mux_emac0_mcg0,
+	msm_mux_emac0_mcg1,
+	msm_mux_emac0_mcg2,
+	msm_mux_emac0_mcg3,
+	msm_mux_emac0_mdc,
+	msm_mux_emac0_mdio,
+	msm_mux_emac0_ptp,
+	msm_mux_emac1_mcg0,
+	msm_mux_emac1_mcg1,
+	msm_mux_emac1_mcg2,
+	msm_mux_emac1_mcg3,
+	msm_mux_emac1_mdc,
+	msm_mux_emac1_mdio,
+	msm_mux_emac1_ptp,
+	msm_mux_gcc_gp1_clk,
+	msm_mux_gcc_gp2_clk,
+	msm_mux_gcc_gp3_clk,
+	msm_mux_gcc_gp4_clk,
+	msm_mux_gcc_gp5_clk,
+	msm_mux_gcc_gp6_clk,
+	msm_mux_gcc_gp7_clk,
+	msm_mux_gcc_gp8_clk,
+	msm_mux_jitter_bist,
+	msm_mux_lbist_pass,
+	msm_mux_mbist_pass,
+	msm_mux_mdp0_vsync0_out,
+	msm_mux_mdp0_vsync10_out,
+	msm_mux_mdp0_vsync1_out,
+	msm_mux_mdp0_vsync2_out,
+	msm_mux_mdp0_vsync3_out,
+	msm_mux_mdp0_vsync4_out,
+	msm_mux_mdp0_vsync5_out,
+	msm_mux_mdp0_vsync6_out,
+	msm_mux_mdp0_vsync7_out,
+	msm_mux_mdp0_vsync8_out,
+	msm_mux_mdp0_vsync9_out,
+	msm_mux_mdp1_vsync0_out,
+	msm_mux_mdp1_vsync10_out,
+	msm_mux_mdp1_vsync1_out,
+	msm_mux_mdp1_vsync2_out,
+	msm_mux_mdp1_vsync3_out,
+	msm_mux_mdp1_vsync4_out,
+	msm_mux_mdp1_vsync5_out,
+	msm_mux_mdp1_vsync6_out,
+	msm_mux_mdp1_vsync7_out,
+	msm_mux_mdp1_vsync8_out,
+	msm_mux_mdp1_vsync9_out,
+	msm_mux_mdp_vsync_e,
+	msm_mux_mdp_vsync_p,
+	msm_mux_mdp_vsync_s,
+	msm_mux_pcie0_clk_req_n,
+	msm_mux_pcie1_clk_req_n,
+	msm_mux_pcie2_clk_req_n,
+	msm_mux_pcie3_clk_req_n,
+	msm_mux_phase_flag0,
+	msm_mux_phase_flag1,
+	msm_mux_phase_flag10,
+	msm_mux_phase_flag11,
+	msm_mux_phase_flag12,
+	msm_mux_phase_flag13,
+	msm_mux_phase_flag14,
+	msm_mux_phase_flag15,
+	msm_mux_phase_flag16,
+	msm_mux_phase_flag17,
+	msm_mux_phase_flag18,
+	msm_mux_phase_flag19,
+	msm_mux_phase_flag2,
+	msm_mux_phase_flag20,
+	msm_mux_phase_flag21,
+	msm_mux_phase_flag22,
+	msm_mux_phase_flag23,
+	msm_mux_phase_flag24,
+	msm_mux_phase_flag25,
+	msm_mux_phase_flag26,
+	msm_mux_phase_flag27,
+	msm_mux_phase_flag28,
+	msm_mux_phase_flag29,
+	msm_mux_phase_flag3,
+	msm_mux_phase_flag30,
+	msm_mux_phase_flag31,
+	msm_mux_phase_flag4,
+	msm_mux_phase_flag5,
+	msm_mux_phase_flag6,
+	msm_mux_phase_flag7,
+	msm_mux_phase_flag8,
+	msm_mux_phase_flag9,
+	msm_mux_pll_bist_sync,
+	msm_mux_pll_clk_aux,
+	msm_mux_prng_rosc0,
+	msm_mux_prng_rosc1,
+	msm_mux_pwrbrk_i_n,
+	msm_mux_qdss_cti,
+	msm_mux_qdss_gpio,
+	msm_mux_qdss_gpio0,
+	msm_mux_qdss_gpio1,
+	msm_mux_qdss_gpio10,
+	msm_mux_qdss_gpio11,
+	msm_mux_qdss_gpio12,
+	msm_mux_qdss_gpio13,
+	msm_mux_qdss_gpio14,
+	msm_mux_qdss_gpio15,
+	msm_mux_qdss_gpio2,
+	msm_mux_qdss_gpio3,
+	msm_mux_qdss_gpio4,
+	msm_mux_qdss_gpio5,
+	msm_mux_qdss_gpio6,
+	msm_mux_qdss_gpio7,
+	msm_mux_qdss_gpio8,
+	msm_mux_qdss_gpio9,
+	msm_mux_qspi0,
+	msm_mux_qspi1,
+	msm_mux_qspi2,
+	msm_mux_qspi3,
+	msm_mux_qspi_clk,
+	msm_mux_qspi_cs0_n,
+	msm_mux_qspi_cs1_n,
+	msm_mux_qup0_se0,
+	msm_mux_qup0_se1,
+	msm_mux_qup0_se2,
+	msm_mux_qup0_se3,
+	msm_mux_qup0_se4,
+	msm_mux_qup0_se5,
+	msm_mux_qup1_se0,
+	msm_mux_qup1_se1,
+	msm_mux_qup1_se2,
+	msm_mux_qup1_se3,
+	msm_mux_qup1_se4,
+	msm_mux_qup1_se5,
+	msm_mux_qup1_se6,
+	msm_mux_qup2_se0,
+	msm_mux_qup2_se1,
+	msm_mux_qup2_se2,
+	msm_mux_qup2_se3,
+	msm_mux_qup2_se4,
+	msm_mux_qup2_se5,
+	msm_mux_qup2_se6,
+	msm_mux_qup3_se0_mira,
+	msm_mux_qup3_se0_mirb,
+	msm_mux_sailss_ospi,
+	msm_mux_sdc4_clk,
+	msm_mux_sdc4_cmd,
+	msm_mux_sdc4_data,
+	msm_mux_smb_alert,
+	msm_mux_smb_alert_n,
+	msm_mux_smb_clk,
+	msm_mux_smb_dat,
+	msm_mux_tb_trig_sdc4,
+	msm_mux_tmess_prng0,
+	msm_mux_tmess_prng1,
+	msm_mux_tsc_timer0,
+	msm_mux_tsc_timer1,
+	msm_mux_tsc_timer2,
+	msm_mux_tsc_timer3,
+	msm_mux_tsc_timer4,
+	msm_mux_tsc_timer5,
+	msm_mux_tsc_timer6,
+	msm_mux_tsc_timer7,
+	msm_mux_tsc_timer8,
+	msm_mux_tsc_timer9,
+	msm_mux_tsense_pwm1,
+	msm_mux_tsense_pwm2,
+	msm_mux_tsense_pwm3,
+	msm_mux_tsense_pwm4,
+	msm_mux_tsense_pwm5,
+	msm_mux_tsense_pwm6,
+	msm_mux_tsense_pwm7,
+	msm_mux_tsense_pwm8,
+	msm_mux_usb0_hs,
+	msm_mux_usb0_phy_ps,
+	msm_mux_usb1_hs,
+	msm_mux_usb1_phy_ps,
+	msm_mux_usb2_hs,
+	msm_mux_usxgmii0_phy,
+	msm_mux_usxgmii1_phy,
+	msm_mux_vsense_trigger_mirnat,
+	msm_mux_wcn_sw,
+	msm_mux_wcn_sw_ctrl,
+	msm_mux__,
+};
+
+static const char *const gpio_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",  "gpio32",	 "gpio33",  "gpio34",  "gpio35",
+	"gpio36",  "gpio37",  "gpio38",	 "gpio39",  "gpio40",  "gpio41",
+	"gpio42",  "gpio43",  "gpio44",	 "gpio45",  "gpio46",  "gpio47",
+	"gpio48",  "gpio49",  "gpio50",	 "gpio51",  "gpio52",  "gpio53",
+	"gpio54",  "gpio55",  "gpio56",	 "gpio57",  "gpio58",  "gpio59",
+	"gpio60",  "gpio61",  "gpio62",	 "gpio63",  "gpio64",  "gpio65",
+	"gpio66",  "gpio67",  "gpio68",	 "gpio69",  "gpio70",  "gpio71",
+	"gpio72",  "gpio73",  "gpio74",	 "gpio75",  "gpio76",  "gpio77",
+	"gpio78",  "gpio79",  "gpio80",	 "gpio81",  "gpio82",  "gpio83",
+	"gpio84",  "gpio85",  "gpio86",	 "gpio87",  "gpio88",  "gpio89",
+	"gpio90",  "gpio91",  "gpio92",	 "gpio93",  "gpio94",  "gpio95",
+	"gpio96",  "gpio97",  "gpio98",	 "gpio99",  "gpio100", "gpio101",
+	"gpio102", "gpio103", "gpio104", "gpio105", "gpio106", "gpio107",
+	"gpio108", "gpio109", "gpio110", "gpio111", "gpio112", "gpio113",
+	"gpio114", "gpio115", "gpio116", "gpio117", "gpio118", "gpio119",
+	"gpio120", "gpio121", "gpio122", "gpio123", "gpio124", "gpio125",
+	"gpio126", "gpio127", "gpio128", "gpio129", "gpio130", "gpio131",
+	"gpio132", "gpio133", "gpio134", "gpio135", "gpio136", "gpio137",
+	"gpio138", "gpio139", "gpio140", "gpio141", "gpio142", "gpio143",
+	"gpio144", "gpio145", "gpio146", "gpio147", "gpio148", "gpio149",
+	"gpio150", "gpio151", "gpio152", "gpio153", "gpio154", "gpio155",
+	"gpio156", "gpio157", "gpio158", "gpio159", "gpio160", "gpio161",
+	"gpio162", "gpio163", "gpio164", "gpio165", "gpio166", "gpio167",
+	"gpio168", "gpio169", "gpio170", "gpio171", "gpio172", "gpio173",
+	"gpio174", "gpio175", "gpio176", "gpio177", "gpio178", "gpio179",
+	"gpio180",
+};
+
+static const char *const aoss_cti_groups[] = {
+	"gpio83",
+	"gpio84",
+	"gpio85",
+	"gpio86",
+};
+
+static const char *const atest_char0_groups[] = {
+	"gpio177",
+};
+
+static const char *const atest_char1_groups[] = {
+	"gpio178",
+};
+
+static const char *const atest_char2_groups[] = {
+	"gpio179",
+};
+
+static const char *const atest_char3_groups[] = {
+	"gpio180",
+};
+
+static const char *const atest_char_start_groups[] = {
+	"gpio176",
+};
+
+static const char *const atest_usb20_groups[] = {
+	"gpio126",
+	"gpio128",
+	"gpio130",
+};
+
+static const char *const atest_usb21_groups[] = {
+	"gpio127",
+	"gpio129",
+	"gpio131",
+};
+
+static const char *const aud_intfc0_clk_groups[] = {
+	"gpio57",
+};
+
+static const char *const aud_intfc0_data0_groups[] = {
+	"gpio59",
+};
+
+static const char *const aud_intfc0_data1_groups[] = {
+	"gpio60",
+};
+
+static const char *const aud_intfc0_data2_groups[] = {
+	"gpio61",
+};
+
+static const char *const aud_intfc0_data3_groups[] = {
+	"gpio62",
+};
+
+static const char *const aud_intfc0_data4_groups[] = {
+	"gpio63",
+};
+
+static const char *const aud_intfc0_data5_groups[] = {
+	"gpio64",
+};
+
+static const char *const aud_intfc0_data6_groups[] = {
+	"gpio65",
+};
+
+static const char *const aud_intfc0_data7_groups[] = {
+	"gpio66",
+};
+
+static const char *const aud_intfc0_ws_groups[] = {
+	"gpio58",
+};
+
+static const char *const aud_intfc10_clk_groups[] = {
+	"gpio61",
+};
+
+static const char *const aud_intfc10_data0_groups[] = {
+	"gpio81",
+};
+
+static const char *const aud_intfc10_data1_groups[] = {
+	"gpio82",
+};
+
+static const char *const aud_intfc10_ws_groups[] = {
+	"gpio62",
+};
+
+static const char *const aud_intfc1_clk_groups[] = {
+	"gpio67",
+};
+
+static const char *const aud_intfc1_data0_groups[] = {
+	"gpio69",
+};
+
+static const char *const aud_intfc1_data1_groups[] = {
+	"gpio70",
+};
+
+static const char *const aud_intfc1_data2_groups[] = {
+	"gpio71",
+};
+
+static const char *const aud_intfc1_data3_groups[] = {
+	"gpio72",
+};
+
+static const char *const aud_intfc1_data4_groups[] = {
+	"gpio73",
+};
+
+static const char *const aud_intfc1_data5_groups[] = {
+	"gpio74",
+};
+
+static const char *const aud_intfc1_data6_groups[] = {
+	"gpio75",
+};
+
+static const char *const aud_intfc1_data7_groups[] = {
+	"gpio76",
+};
+
+static const char *const aud_intfc1_ws_groups[] = {
+	"gpio68",
+};
+
+static const char *const aud_intfc2_clk_groups[] = {
+	"gpio77",
+};
+
+static const char *const aud_intfc2_data0_groups[] = {
+	"gpio79",
+};
+
+static const char *const aud_intfc2_data1_groups[] = {
+	"gpio80",
+};
+
+static const char *const aud_intfc2_data2_groups[] = {
+	"gpio81",
+};
+
+static const char *const aud_intfc2_data3_groups[] = {
+	"gpio82",
+};
+
+static const char *const aud_intfc2_ws_groups[] = {
+	"gpio78",
+};
+
+static const char *const aud_intfc3_clk_groups[] = {
+	"gpio83",
+};
+
+static const char *const aud_intfc3_data0_groups[] = {
+	"gpio85",
+};
+
+static const char *const aud_intfc3_data1_groups[] = {
+	"gpio86",
+};
+
+static const char *const aud_intfc3_ws_groups[] = {
+	"gpio84",
+};
+
+static const char *const aud_intfc4_clk_groups[] = {
+	"gpio87",
+};
+
+static const char *const aud_intfc4_data0_groups[] = {
+	"gpio89",
+};
+
+static const char *const aud_intfc4_data1_groups[] = {
+	"gpio90",
+};
+
+static const char *const aud_intfc4_ws_groups[] = {
+	"gpio88",
+};
+
+static const char *const aud_intfc5_clk_groups[] = {
+	"gpio91",
+};
+
+static const char *const aud_intfc5_data0_groups[] = {
+	"gpio93",
+};
+
+static const char *const aud_intfc5_data1_groups[] = {
+	"gpio94",
+};
+
+static const char *const aud_intfc5_ws_groups[] = {
+	"gpio92",
+};
+
+static const char *const aud_intfc6_clk_groups[] = {
+	"gpio95",
+};
+
+static const char *const aud_intfc6_data0_groups[] = {
+	"gpio97",
+};
+
+static const char *const aud_intfc6_data1_groups[] = {
+	"gpio98",
+};
+
+static const char *const aud_intfc6_ws_groups[] = {
+	"gpio96",
+};
+
+static const char *const aud_intfc7_clk_groups[] = {
+	"gpio63",
+};
+
+static const char *const aud_intfc7_data0_groups[] = {
+	"gpio65",
+};
+
+static const char *const aud_intfc7_data1_groups[] = {
+	"gpio66",
+};
+
+static const char *const aud_intfc7_ws_groups[] = {
+	"gpio64",
+};
+
+static const char *const aud_intfc8_clk_groups[] = {
+	"gpio73",
+};
+
+static const char *const aud_intfc8_data0_groups[] = {
+	"gpio75",
+};
+
+static const char *const aud_intfc8_data1_groups[] = {
+	"gpio76",
+};
+
+static const char *const aud_intfc8_ws_groups[] = {
+	"gpio74",
+};
+
+static const char *const aud_intfc9_clk_groups[] = {
+	"gpio70",
+};
+
+static const char *const aud_intfc9_data0_groups[] = {
+	"gpio72",
+};
+
+static const char *const aud_intfc9_ws_groups[] = {
+	"gpio71",
+};
+
+static const char *const aud_mclk0_mira_groups[] = {
+	"gpio99",
+};
+
+static const char *const aud_mclk0_mirb_groups[] = {
+	"gpio86",
+};
+
+static const char *const aud_mclk1_mira_groups[] = {
+	"gpio100",
+};
+
+static const char *const aud_mclk1_mirb_groups[] = {
+	"gpio90",
+};
+
+static const char *const aud_mclk2_mira_groups[] = {
+	"gpio101",
+};
+
+static const char *const aud_mclk2_mirb_groups[] = {
+	"gpio94",
+};
+
+static const char *const aud_refclk0_groups[] = {
+	"gpio100",
+};
+
+static const char *const aud_refclk1_groups[] = {
+	"gpio101",
+};
+
+static const char *const bist_done_groups[] = {
+	"gpio168",
+};
+
+static const char *const ccu_async_in0_groups[] = {
+	"gpio176",
+};
+
+static const char *const ccu_async_in1_groups[] = {
+	"gpio177",
+};
+
+static const char *const ccu_async_in2_groups[] = {
+	"gpio178",
+};
+
+static const char *const ccu_async_in3_groups[] = {
+	"gpio179",
+};
+
+static const char *const ccu_async_in4_groups[] = {
+	"gpio180",
+};
+
+static const char *const ccu_async_in5_groups[] = {
+	"gpio45",
+};
+
+static const char *const ccu_i2c_scl0_groups[] = {
+	"gpio16",
+};
+
+static const char *const ccu_i2c_scl1_groups[] = {
+	"gpio18",
+};
+
+static const char *const ccu_i2c_scl2_groups[] = {
+	"gpio20",
+};
+
+static const char *const ccu_i2c_scl3_groups[] = {
+	"gpio22",
+};
+
+static const char *const ccu_i2c_scl4_groups[] = {
+	"gpio24",
+};
+
+static const char *const ccu_i2c_scl5_groups[] = {
+	"gpio114",
+};
+
+static const char *const ccu_i2c_scl6_groups[] = {
+	"gpio116",
+};
+
+static const char *const ccu_i2c_scl7_groups[] = {
+	"gpio126",
+};
+
+static const char *const ccu_i2c_scl8_groups[] = {
+	"gpio130",
+};
+
+static const char *const ccu_i2c_scl9_groups[] = {
+	"gpio132",
+};
+
+static const char *const ccu_i2c_sda0_groups[] = {
+	"gpio15",
+};
+
+static const char *const ccu_i2c_sda1_groups[] = {
+	"gpio17",
+};
+
+static const char *const ccu_i2c_sda2_groups[] = {
+	"gpio19",
+};
+
+static const char *const ccu_i2c_sda3_groups[] = {
+	"gpio21",
+};
+
+static const char *const ccu_i2c_sda4_groups[] = {
+	"gpio23",
+};
+
+static const char *const ccu_i2c_sda5_groups[] = {
+	"gpio113",
+};
+
+static const char *const ccu_i2c_sda6_groups[] = {
+	"gpio115",
+};
+
+static const char *const ccu_i2c_sda7_groups[] = {
+	"gpio125",
+};
+
+static const char *const ccu_i2c_sda8_groups[] = {
+	"gpio129",
+};
+
+static const char *const ccu_i2c_sda9_groups[] = {
+	"gpio131",
+};
+
+static const char *const ccu_timer0_groups[] = {
+	"gpio25",
+};
+
+static const char *const ccu_timer1_groups[] = {
+	"gpio26",
+};
+
+static const char *const ccu_timer10_groups[] = {
+	"gpio143",
+};
+
+static const char *const ccu_timer11_groups[] = {
+	"gpio144",
+};
+
+static const char *const ccu_timer12_groups[] = {
+	"gpio150",
+};
+
+static const char *const ccu_timer13_groups[] = {
+	"gpio151",
+};
+
+static const char *const ccu_timer14_groups[] = {
+	"gpio152",
+};
+
+static const char *const ccu_timer15_groups[] = {
+	"gpio153",
+};
+
+static const char *const ccu_timer2_groups[] = {
+	"gpio27",
+};
+
+static const char *const ccu_timer3_groups[] = {
+	"gpio28",
+};
+
+static const char *const ccu_timer4_groups[] = {
+	"gpio29",
+};
+
+static const char *const ccu_timer5_groups[] = {
+	"gpio30",
+};
+
+static const char *const ccu_timer6_groups[] = {
+	"gpio31",
+};
+
+static const char *const ccu_timer7_groups[] = {
+	"gpio32",
+};
+
+static const char *const ccu_timer8_groups[] = {
+	"gpio33",
+};
+
+static const char *const ccu_timer9_groups[] = {
+	"gpio34",
+};
+
+static const char *const clink_debug_groups[] = {
+	"gpio12", "gpio13", "gpio14", "gpio51",
+	"gpio52", "gpio53", "gpio54", "gpio55",
+};
+
+static const char *const dbg_out_groups[] = {
+	"gpio113",
+};
+
+static const char *const dbg_out_clk_groups[] = {
+	"gpio165",
+};
+
+static const char *const ddr_bist_complete_groups[] = {
+	"gpio37",
+};
+
+static const char *const ddr_bist_fail_groups[] = {
+	"gpio39",
+};
+
+static const char *const ddr_bist_start_groups[] = {
+	"gpio36",
+};
+
+static const char *const ddr_bist_stop_groups[] = {
+	"gpio38",
+};
+
+static const char *const ddr_pxi0_groups[] = {
+	"gpio99",
+	"gpio100",
+};
+
+static const char *const ddr_pxi1_groups[] = {
+	"gpio109",
+	"gpio110",
+};
+
+static const char *const ddr_pxi10_groups[] = {
+	"gpio130",
+	"gpio131",
+};
+
+static const char *const ddr_pxi11_groups[] = {
+	"gpio132",
+	"gpio133",
+};
+
+static const char *const ddr_pxi12_groups[] = {
+	"gpio134",
+	"gpio135",
+};
+
+static const char *const ddr_pxi13_groups[] = {
+	"gpio136",
+	"gpio137",
+};
+
+static const char *const ddr_pxi14_groups[] = {
+	"gpio138",
+	"gpio139",
+};
+
+static const char *const ddr_pxi15_groups[] = {
+	"gpio162",
+	"gpio163",
+};
+
+static const char *const ddr_pxi2_groups[] = {
+	"gpio113",
+	"gpio114",
+};
+
+static const char *const ddr_pxi3_groups[] = {
+	"gpio115",
+	"gpio116",
+};
+
+static const char *const ddr_pxi4_groups[] = {
+	"gpio117",
+	"gpio118",
+};
+
+static const char *const ddr_pxi5_groups[] = {
+	"gpio164",
+	"gpio165",
+};
+
+static const char *const ddr_pxi6_groups[] = {
+	"gpio119",
+	"gpio120",
+};
+
+static const char *const ddr_pxi7_groups[] = {
+	"gpio121",
+	"gpio122",
+};
+
+static const char *const ddr_pxi8_groups[] = {
+	"gpio126",
+	"gpio127",
+};
+
+static const char *const ddr_pxi9_groups[] = {
+	"gpio128",
+	"gpio129",
+};
+
+static const char *const dp_rx0_groups[] = {
+	"gpio55", "gpio83", "gpio84",  "gpio85",  "gpio86",
+	"gpio88", "gpio89", "gpio137", "gpio138",
+};
+
+static const char *const dp_rx00_groups[] = {
+	"gpio99",
+};
+
+static const char *const dp_rx01_groups[] = {
+	"gpio100",
+};
+
+static const char *const dp_rx0_mute_groups[] = {
+	"gpio35",
+};
+
+static const char *const dp_rx1_groups[] = {
+	"gpio56", "gpio92", "gpio93",  "gpio95",  "gpio96",
+	"gpio97", "gpio98", "gpio158", "gpio159",
+};
+
+static const char *const dp_rx10_groups[] = {
+	"gpio121",
+};
+
+static const char *const dp_rx11_groups[] = {
+	"gpio122",
+};
+
+static const char *const dp_rx1_mute_groups[] = {
+	"gpio36",
+};
+
+static const char *const edp0_hot_groups[] = {
+	"gpio51",
+};
+
+static const char *const edp0_lcd_groups[] = {
+	"gpio47",
+};
+
+static const char *const edp1_hot_groups[] = {
+	"gpio52",
+};
+
+static const char *const edp1_lcd_groups[] = {
+	"gpio48",
+};
+
+static const char *const edp2_hot_groups[] = {
+	"gpio53",
+};
+
+static const char *const edp2_lcd_groups[] = {
+	"gpio49",
+};
+
+static const char *const edp3_hot_groups[] = {
+	"gpio54",
+};
+
+static const char *const edp3_lcd_groups[] = {
+	"gpio50",
+};
+
+static const char *const emac0_mcg0_groups[] = {
+	"gpio16",
+};
+
+static const char *const emac0_mcg1_groups[] = {
+	"gpio17",
+};
+
+static const char *const emac0_mcg2_groups[] = {
+	"gpio18",
+};
+
+static const char *const emac0_mcg3_groups[] = {
+	"gpio19",
+};
+
+static const char *const emac0_mdc_groups[] = {
+	"gpio47",
+};
+
+static const char *const emac0_mdio_groups[] = {
+	"gpio48",
+};
+
+static const char *const emac0_ptp_groups[] = {
+	"gpio133", "gpio134", "gpio135", "gpio136",
+	"gpio139", "gpio140", "gpio141", "gpio142",
+};
+
+static const char *const emac1_mcg0_groups[] = {
+	"gpio20",
+};
+
+static const char *const emac1_mcg1_groups[] = {
+	"gpio21",
+};
+
+static const char *const emac1_mcg2_groups[] = {
+	"gpio22",
+};
+
+static const char *const emac1_mcg3_groups[] = {
+	"gpio23",
+};
+
+static const char *const emac1_mdc_groups[] = {
+	"gpio49",
+};
+
+static const char *const emac1_mdio_groups[] = {
+	"gpio50",
+};
+
+static const char *const emac1_ptp_groups[] = {
+	"gpio37", "gpio38", "gpio39", "gpio40",
+	"gpio41", "gpio42", "gpio43", "gpio44",
+};
+
+static const char *const gcc_gp1_clk_groups[] = {
+	"gpio51",
+};
+
+static const char *const gcc_gp2_clk_groups[] = {
+	"gpio52",
+};
+
+static const char *const gcc_gp3_clk_groups[] = {
+	"gpio42",
+};
+
+static const char *const gcc_gp4_clk_groups[] = {
+	"gpio43",
+};
+
+static const char *const gcc_gp5_clk_groups[] = {
+	"gpio105",
+};
+
+static const char *const gcc_gp6_clk_groups[] = {
+	"gpio106",
+};
+
+static const char *const gcc_gp7_clk_groups[] = {
+	"gpio13",
+};
+
+static const char *const gcc_gp8_clk_groups[] = {
+	"gpio14",
+};
+
+static const char *const jitter_bist_groups[] = {
+	"gpio123",
+	"gpio138",
+};
+
+static const char *const lbist_pass_groups[] = {
+	"gpio121",
+};
+
+static const char *const mbist_pass_groups[] = {
+	"gpio122",
+};
+
+static const char *const mdp0_vsync0_out_groups[] = {
+	"gpio113",
+};
+
+static const char *const mdp0_vsync10_out_groups[] = {
+	"gpio143",
+};
+
+static const char *const mdp0_vsync1_out_groups[] = {
+	"gpio114",
+};
+
+static const char *const mdp0_vsync2_out_groups[] = {
+	"gpio115",
+};
+
+static const char *const mdp0_vsync3_out_groups[] = {
+	"gpio116",
+};
+
+static const char *const mdp0_vsync4_out_groups[] = {
+	"gpio121",
+};
+
+static const char *const mdp0_vsync5_out_groups[] = {
+	"gpio122",
+};
+
+static const char *const mdp0_vsync6_out_groups[] = {
+	"gpio139",
+};
+
+static const char *const mdp0_vsync7_out_groups[] = {
+	"gpio140",
+};
+
+static const char *const mdp0_vsync8_out_groups[] = {
+	"gpio141",
+};
+
+static const char *const mdp0_vsync9_out_groups[] = {
+	"gpio142",
+};
+
+static const char *const mdp1_vsync0_out_groups[] = {
+	"gpio123",
+};
+
+static const char *const mdp1_vsync10_out_groups[] = {
+	"gpio135",
+};
+
+static const char *const mdp1_vsync1_out_groups[] = {
+	"gpio124",
+};
+
+static const char *const mdp1_vsync2_out_groups[] = {
+	"gpio125",
+};
+
+static const char *const mdp1_vsync3_out_groups[] = {
+	"gpio126",
+};
+
+static const char *const mdp1_vsync4_out_groups[] = {
+	"gpio129",
+};
+
+static const char *const mdp1_vsync5_out_groups[] = {
+	"gpio130",
+};
+
+static const char *const mdp1_vsync6_out_groups[] = {
+	"gpio131",
+};
+
+static const char *const mdp1_vsync7_out_groups[] = {
+	"gpio132",
+};
+
+static const char *const mdp1_vsync8_out_groups[] = {
+	"gpio133",
+};
+
+static const char *const mdp1_vsync9_out_groups[] = {
+	"gpio134",
+};
+
+static const char *const mdp_vsync_e_groups[] = {
+	"gpio109",
+};
+
+static const char *const mdp_vsync_p_groups[] = {
+	"gpio110",
+};
+
+static const char *const mdp_vsync_s_groups[] = {
+	"gpio144",
+};
+
+static const char *const pcie0_clk_req_n_groups[] = {
+	"gpio1",
+};
+
+static const char *const pcie1_clk_req_n_groups[] = {
+	"gpio4",
+};
+
+static const char *const pcie2_clk_req_n_groups[] = {
+	"gpio7",
+};
+
+static const char *const pcie3_clk_req_n_groups[] = {
+	"gpio10",
+};
+
+static const char *const phase_flag0_groups[] = {
+	"gpio98",
+};
+
+static const char *const phase_flag1_groups[] = {
+	"gpio82",
+};
+
+static const char *const phase_flag10_groups[] = {
+	"gpio90",
+};
+
+static const char *const phase_flag11_groups[] = {
+	"gpio91",
+};
+
+static const char *const phase_flag12_groups[] = {
+	"gpio92",
+};
+
+static const char *const phase_flag13_groups[] = {
+	"gpio93",
+};
+
+static const char *const phase_flag14_groups[] = {
+	"gpio94",
+};
+
+static const char *const phase_flag15_groups[] = {
+	"gpio95",
+};
+
+static const char *const phase_flag16_groups[] = {
+	"gpio96",
+};
+
+static const char *const phase_flag17_groups[] = {
+	"gpio101",
+};
+
+static const char *const phase_flag18_groups[] = {
+	"gpio67",
+};
+
+static const char *const phase_flag19_groups[] = {
+	"gpio68",
+};
+
+static const char *const phase_flag2_groups[] = {
+	"gpio81",
+};
+
+static const char *const phase_flag20_groups[] = {
+	"gpio69",
+};
+
+static const char *const phase_flag21_groups[] = {
+	"gpio70",
+};
+
+static const char *const phase_flag22_groups[] = {
+	"gpio71",
+};
+
+static const char *const phase_flag23_groups[] = {
+	"gpio72",
+};
+
+static const char *const phase_flag24_groups[] = {
+	"gpio73",
+};
+
+static const char *const phase_flag25_groups[] = {
+	"gpio74",
+};
+
+static const char *const phase_flag26_groups[] = {
+	"gpio75",
+};
+
+static const char *const phase_flag27_groups[] = {
+	"gpio76",
+};
+
+static const char *const phase_flag28_groups[] = {
+	"gpio83",
+};
+
+static const char *const phase_flag29_groups[] = {
+	"gpio84",
+};
+
+static const char *const phase_flag3_groups[] = {
+	"gpio80",
+};
+
+static const char *const phase_flag30_groups[] = {
+	"gpio85",
+};
+
+static const char *const phase_flag31_groups[] = {
+	"gpio86",
+};
+
+static const char *const phase_flag4_groups[] = {
+	"gpio79",
+};
+
+static const char *const phase_flag5_groups[] = {
+	"gpio78",
+};
+
+static const char *const phase_flag6_groups[] = {
+	"gpio77",
+};
+
+static const char *const phase_flag7_groups[] = {
+	"gpio87",
+};
+
+static const char *const phase_flag8_groups[] = {
+	"gpio88",
+};
+
+static const char *const phase_flag9_groups[] = {
+	"gpio89",
+};
+
+static const char *const pll_bist_sync_groups[] = {
+	"gpio176",
+};
+
+static const char *const pll_clk_aux_groups[] = {
+	"gpio100",
+};
+
+static const char *const prng_rosc0_groups[] = {
+	"gpio117",
+};
+
+static const char *const prng_rosc1_groups[] = {
+	"gpio118",
+};
+
+static const char *const pwrbrk_i_n_groups[] = {
+	"gpio167",
+};
+
+static const char *const qdss_cti_groups[] = {
+	"gpio41",  "gpio42",  "gpio110", "gpio138",
+	"gpio142", "gpio144", "gpio162", "gpio163",
+};
+
+static const char *const qdss_gpio_groups[] = {
+	"gpio75",
+	"gpio76",
+	"gpio93",
+	"gpio108",
+};
+
+static const char *const qdss_gpio0_groups[] = {
+	"gpio67",
+	"gpio85",
+};
+
+static const char *const qdss_gpio1_groups[] = {
+	"gpio68",
+	"gpio86",
+};
+
+static const char *const qdss_gpio10_groups[] = {
+	"gpio79",
+	"gpio96",
+};
+
+static const char *const qdss_gpio11_groups[] = {
+	"gpio80",
+	"gpio97",
+};
+
+static const char *const qdss_gpio12_groups[] = {
+	"gpio81",
+	"gpio98",
+};
+
+static const char *const qdss_gpio13_groups[] = {
+	"gpio82",
+	"gpio99",
+};
+
+static const char *const qdss_gpio14_groups[] = {
+	"gpio83",
+	"gpio100",
+};
+
+static const char *const qdss_gpio15_groups[] = {
+	"gpio84",
+	"gpio101",
+};
+
+static const char *const qdss_gpio2_groups[] = {
+	"gpio69",
+	"gpio87",
+};
+
+static const char *const qdss_gpio3_groups[] = {
+	"gpio70",
+	"gpio88",
+};
+
+static const char *const qdss_gpio4_groups[] = {
+	"gpio71",
+	"gpio89",
+};
+
+static const char *const qdss_gpio5_groups[] = {
+	"gpio72",
+	"gpio90",
+};
+
+static const char *const qdss_gpio6_groups[] = {
+	"gpio73",
+	"gpio91",
+};
+
+static const char *const qdss_gpio7_groups[] = {
+	"gpio74",
+	"gpio92",
+};
+
+static const char *const qdss_gpio8_groups[] = {
+	"gpio77",
+	"gpio94",
+};
+
+static const char *const qdss_gpio9_groups[] = {
+	"gpio78",
+	"gpio95",
+};
+
+static const char *const qspi0_groups[] = {
+	"gpio102",
+};
+
+static const char *const qspi1_groups[] = {
+	"gpio103",
+};
+
+static const char *const qspi2_groups[] = {
+	"gpio106",
+};
+
+static const char *const qspi3_groups[] = {
+	"gpio107",
+};
+
+static const char *const qspi_clk_groups[] = {
+	"gpio104",
+};
+
+static const char *const qspi_cs0_n_groups[] = {
+	"gpio105",
+};
+
+static const char *const qspi_cs1_n_groups[] = {
+	"gpio108",
+};
+
+static const char *const qup0_se0_groups[] = {
+	"gpio109", "gpio110", "gpio111", "gpio112",
+};
+
+static const char *const qup0_se1_groups[] = {
+	"gpio109", "gpio110", "gpio111", "gpio112",
+};
+
+static const char *const qup0_se2_groups[] = {
+	"gpio113", "gpio114", "gpio115", "gpio116",
+};
+
+static const char *const qup0_se3_groups[] = {
+	"gpio113", "gpio114", "gpio115", "gpio116",
+};
+
+static const char *const qup0_se4_groups[] = {
+	"gpio117", "gpio118", "gpio119", "gpio120",
+};
+
+static const char *const qup0_se5_groups[] = {
+	"gpio109", "gpio110", "gpio121", "gpio122",
+};
+
+static const char *const qup1_se0_groups[] = {
+	"gpio123", "gpio124", "gpio125", "gpio126",
+};
+
+static const char *const qup1_se1_groups[] = {
+	"gpio123", "gpio124", "gpio125", "gpio126",
+};
+
+static const char *const qup1_se2_groups[] = {
+	"gpio127", "gpio128", "gpio129", "gpio130",
+};
+
+static const char *const qup1_se3_groups[] = {
+	"gpio129", "gpio130",
+};
+
+static const char *const qup1_se4_groups[] = {
+	"gpio131", "gpio132", "gpio137", "gpio138",
+};
+
+static const char *const qup1_se5_groups[] = {
+	"gpio133", "gpio134", "gpio135", "gpio136",
+};
+
+static const char *const qup1_se6_groups[] = {
+	"gpio131", "gpio132", "gpio137", "gpio138",
+};
+
+static const char *const qup2_se0_groups[] = {
+	"gpio139", "gpio140", "gpio141", "gpio142",
+};
+
+static const char *const qup2_se1_groups[] = {
+	"gpio143", "gpio144", "gpio154", "gpio155",
+};
+
+static const char *const qup2_se2_groups[] = {
+	"gpio145", "gpio146", "gpio147", "gpio148", "gpio149",
+};
+
+static const char *const qup2_se3_groups[] = {
+	"gpio150", "gpio151", "gpio152", "gpio153",
+};
+
+static const char *const qup2_se4_groups[] = {
+	"gpio143", "gpio144", "gpio150", "gpio151",
+	"gpio152", "gpio154", "gpio155",
+};
+
+static const char *const qup2_se5_groups[] = {
+	"gpio156", "gpio157", "gpio158", "gpio159",
+};
+
+static const char *const qup2_se6_groups[] = {
+	"gpio156", "gpio157", "gpio158", "gpio159",
+};
+
+static const char *const qup3_se0_mira_groups[] = {
+	"gpio102", "gpio103", "gpio104", "gpio105",
+	"gpio106", "gpio107", "gpio108",
+};
+
+static const char *const qup3_se0_mirb_groups[] = {
+	"gpio102", "gpio103",
+};
+
+static const char *const sailss_ospi_groups[] = {
+	"gpio164",
+	"gpio165",
+};
+
+static const char *const sdc4_clk_groups[] = {
+	"gpio175",
+};
+
+static const char *const sdc4_cmd_groups[] = {
+	"gpio174",
+};
+
+static const char *const sdc4_data_groups[] = {
+	"gpio170",
+	"gpio171",
+	"gpio172",
+	"gpio173",
+};
+
+static const char *const smb_alert_groups[] = {
+	"gpio110",
+};
+
+static const char *const smb_alert_n_groups[] = {
+	"gpio109",
+};
+
+static const char *const smb_clk_groups[] = {
+	"gpio112",
+};
+
+static const char *const smb_dat_groups[] = {
+	"gpio111",
+};
+
+static const char *const tb_trig_sdc4_groups[] = {
+	"gpio169",
+};
+
+static const char *const tmess_prng0_groups[] = {
+	"gpio94",
+};
+
+static const char *const tmess_prng1_groups[] = {
+	"gpio95",
+};
+
+static const char *const tsc_timer0_groups[] = {
+	"gpio25",
+};
+
+static const char *const tsc_timer1_groups[] = {
+	"gpio26",
+};
+
+static const char *const tsc_timer2_groups[] = {
+	"gpio27",
+};
+
+static const char *const tsc_timer3_groups[] = {
+	"gpio28",
+};
+
+static const char *const tsc_timer4_groups[] = {
+	"gpio29",
+};
+
+static const char *const tsc_timer5_groups[] = {
+	"gpio30",
+};
+
+static const char *const tsc_timer6_groups[] = {
+	"gpio31",
+};
+
+static const char *const tsc_timer7_groups[] = {
+	"gpio32",
+};
+
+static const char *const tsc_timer8_groups[] = {
+	"gpio33",
+};
+
+static const char *const tsc_timer9_groups[] = {
+	"gpio34",
+};
+
+static const char *const tsense_pwm1_groups[] = {
+	"gpio43",
+};
+
+static const char *const tsense_pwm2_groups[] = {
+	"gpio44",
+};
+
+static const char *const tsense_pwm3_groups[] = {
+	"gpio45",
+};
+
+static const char *const tsense_pwm4_groups[] = {
+	"gpio46",
+};
+
+static const char *const tsense_pwm5_groups[] = {
+	"gpio47",
+};
+
+static const char *const tsense_pwm6_groups[] = {
+	"gpio48",
+};
+
+static const char *const tsense_pwm7_groups[] = {
+	"gpio49",
+};
+
+static const char *const tsense_pwm8_groups[] = {
+	"gpio50",
+};
+
+static const char *const usb0_hs_groups[] = {
+	"gpio12",
+};
+
+static const char *const usb0_phy_ps_groups[] = {
+	"gpio164",
+};
+
+static const char *const usb1_hs_groups[] = {
+	"gpio13",
+};
+
+static const char *const usb1_phy_ps_groups[] = {
+	"gpio165",
+};
+
+static const char *const usb2_hs_groups[] = {
+	"gpio14",
+};
+
+static const char *const usxgmii0_phy_groups[] = {
+	"gpio45",
+};
+
+static const char *const usxgmii1_phy_groups[] = {
+	"gpio46",
+};
+
+static const char *const vsense_trigger_mirnat_groups[] = {
+	"gpio132",
+};
+
+static const char *const wcn_sw_groups[] = {
+	"gpio161",
+};
+
+static const char *const wcn_sw_ctrl_groups[] = {
+	"gpio160",
+};
+
+static const struct pinfunction nord_functions[] = {
+	MSM_GPIO_PIN_FUNCTION(gpio),
+	MSM_PIN_FUNCTION(aoss_cti),
+	MSM_PIN_FUNCTION(atest_char0),
+	MSM_PIN_FUNCTION(atest_char1),
+	MSM_PIN_FUNCTION(atest_char2),
+	MSM_PIN_FUNCTION(atest_char3),
+	MSM_PIN_FUNCTION(atest_char_start),
+	MSM_PIN_FUNCTION(atest_usb20),
+	MSM_PIN_FUNCTION(atest_usb21),
+	MSM_PIN_FUNCTION(aud_intfc0_clk),
+	MSM_PIN_FUNCTION(aud_intfc0_data0),
+	MSM_PIN_FUNCTION(aud_intfc0_data1),
+	MSM_PIN_FUNCTION(aud_intfc0_data2),
+	MSM_PIN_FUNCTION(aud_intfc0_data3),
+	MSM_PIN_FUNCTION(aud_intfc0_data4),
+	MSM_PIN_FUNCTION(aud_intfc0_data5),
+	MSM_PIN_FUNCTION(aud_intfc0_data6),
+	MSM_PIN_FUNCTION(aud_intfc0_data7),
+	MSM_PIN_FUNCTION(aud_intfc0_ws),
+	MSM_PIN_FUNCTION(aud_intfc10_clk),
+	MSM_PIN_FUNCTION(aud_intfc10_data0),
+	MSM_PIN_FUNCTION(aud_intfc10_data1),
+	MSM_PIN_FUNCTION(aud_intfc10_ws),
+	MSM_PIN_FUNCTION(aud_intfc1_clk),
+	MSM_PIN_FUNCTION(aud_intfc1_data0),
+	MSM_PIN_FUNCTION(aud_intfc1_data1),
+	MSM_PIN_FUNCTION(aud_intfc1_data2),
+	MSM_PIN_FUNCTION(aud_intfc1_data3),
+	MSM_PIN_FUNCTION(aud_intfc1_data4),
+	MSM_PIN_FUNCTION(aud_intfc1_data5),
+	MSM_PIN_FUNCTION(aud_intfc1_data6),
+	MSM_PIN_FUNCTION(aud_intfc1_data7),
+	MSM_PIN_FUNCTION(aud_intfc1_ws),
+	MSM_PIN_FUNCTION(aud_intfc2_clk),
+	MSM_PIN_FUNCTION(aud_intfc2_data0),
+	MSM_PIN_FUNCTION(aud_intfc2_data1),
+	MSM_PIN_FUNCTION(aud_intfc2_data2),
+	MSM_PIN_FUNCTION(aud_intfc2_data3),
+	MSM_PIN_FUNCTION(aud_intfc2_ws),
+	MSM_PIN_FUNCTION(aud_intfc3_clk),
+	MSM_PIN_FUNCTION(aud_intfc3_data0),
+	MSM_PIN_FUNCTION(aud_intfc3_data1),
+	MSM_PIN_FUNCTION(aud_intfc3_ws),
+	MSM_PIN_FUNCTION(aud_intfc4_clk),
+	MSM_PIN_FUNCTION(aud_intfc4_data0),
+	MSM_PIN_FUNCTION(aud_intfc4_data1),
+	MSM_PIN_FUNCTION(aud_intfc4_ws),
+	MSM_PIN_FUNCTION(aud_intfc5_clk),
+	MSM_PIN_FUNCTION(aud_intfc5_data0),
+	MSM_PIN_FUNCTION(aud_intfc5_data1),
+	MSM_PIN_FUNCTION(aud_intfc5_ws),
+	MSM_PIN_FUNCTION(aud_intfc6_clk),
+	MSM_PIN_FUNCTION(aud_intfc6_data0),
+	MSM_PIN_FUNCTION(aud_intfc6_data1),
+	MSM_PIN_FUNCTION(aud_intfc6_ws),
+	MSM_PIN_FUNCTION(aud_intfc7_clk),
+	MSM_PIN_FUNCTION(aud_intfc7_data0),
+	MSM_PIN_FUNCTION(aud_intfc7_data1),
+	MSM_PIN_FUNCTION(aud_intfc7_ws),
+	MSM_PIN_FUNCTION(aud_intfc8_clk),
+	MSM_PIN_FUNCTION(aud_intfc8_data0),
+	MSM_PIN_FUNCTION(aud_intfc8_data1),
+	MSM_PIN_FUNCTION(aud_intfc8_ws),
+	MSM_PIN_FUNCTION(aud_intfc9_clk),
+	MSM_PIN_FUNCTION(aud_intfc9_data0),
+	MSM_PIN_FUNCTION(aud_intfc9_ws),
+	MSM_PIN_FUNCTION(aud_mclk0_mira),
+	MSM_PIN_FUNCTION(aud_mclk0_mirb),
+	MSM_PIN_FUNCTION(aud_mclk1_mira),
+	MSM_PIN_FUNCTION(aud_mclk1_mirb),
+	MSM_PIN_FUNCTION(aud_mclk2_mira),
+	MSM_PIN_FUNCTION(aud_mclk2_mirb),
+	MSM_PIN_FUNCTION(aud_refclk0),
+	MSM_PIN_FUNCTION(aud_refclk1),
+	MSM_PIN_FUNCTION(bist_done),
+	MSM_PIN_FUNCTION(ccu_async_in0),
+	MSM_PIN_FUNCTION(ccu_async_in1),
+	MSM_PIN_FUNCTION(ccu_async_in2),
+	MSM_PIN_FUNCTION(ccu_async_in3),
+	MSM_PIN_FUNCTION(ccu_async_in4),
+	MSM_PIN_FUNCTION(ccu_async_in5),
+	MSM_PIN_FUNCTION(ccu_i2c_scl0),
+	MSM_PIN_FUNCTION(ccu_i2c_scl1),
+	MSM_PIN_FUNCTION(ccu_i2c_scl2),
+	MSM_PIN_FUNCTION(ccu_i2c_scl3),
+	MSM_PIN_FUNCTION(ccu_i2c_scl4),
+	MSM_PIN_FUNCTION(ccu_i2c_scl5),
+	MSM_PIN_FUNCTION(ccu_i2c_scl6),
+	MSM_PIN_FUNCTION(ccu_i2c_scl7),
+	MSM_PIN_FUNCTION(ccu_i2c_scl8),
+	MSM_PIN_FUNCTION(ccu_i2c_scl9),
+	MSM_PIN_FUNCTION(ccu_i2c_sda0),
+	MSM_PIN_FUNCTION(ccu_i2c_sda1),
+	MSM_PIN_FUNCTION(ccu_i2c_sda2),
+	MSM_PIN_FUNCTION(ccu_i2c_sda3),
+	MSM_PIN_FUNCTION(ccu_i2c_sda4),
+	MSM_PIN_FUNCTION(ccu_i2c_sda5),
+	MSM_PIN_FUNCTION(ccu_i2c_sda6),
+	MSM_PIN_FUNCTION(ccu_i2c_sda7),
+	MSM_PIN_FUNCTION(ccu_i2c_sda8),
+	MSM_PIN_FUNCTION(ccu_i2c_sda9),
+	MSM_PIN_FUNCTION(ccu_timer0),
+	MSM_PIN_FUNCTION(ccu_timer1),
+	MSM_PIN_FUNCTION(ccu_timer10),
+	MSM_PIN_FUNCTION(ccu_timer11),
+	MSM_PIN_FUNCTION(ccu_timer12),
+	MSM_PIN_FUNCTION(ccu_timer13),
+	MSM_PIN_FUNCTION(ccu_timer14),
+	MSM_PIN_FUNCTION(ccu_timer15),
+	MSM_PIN_FUNCTION(ccu_timer2),
+	MSM_PIN_FUNCTION(ccu_timer3),
+	MSM_PIN_FUNCTION(ccu_timer4),
+	MSM_PIN_FUNCTION(ccu_timer5),
+	MSM_PIN_FUNCTION(ccu_timer6),
+	MSM_PIN_FUNCTION(ccu_timer7),
+	MSM_PIN_FUNCTION(ccu_timer8),
+	MSM_PIN_FUNCTION(ccu_timer9),
+	MSM_PIN_FUNCTION(clink_debug),
+	MSM_PIN_FUNCTION(dbg_out),
+	MSM_PIN_FUNCTION(dbg_out_clk),
+	MSM_PIN_FUNCTION(ddr_bist_complete),
+	MSM_PIN_FUNCTION(ddr_bist_fail),
+	MSM_PIN_FUNCTION(ddr_bist_start),
+	MSM_PIN_FUNCTION(ddr_bist_stop),
+	MSM_PIN_FUNCTION(ddr_pxi0),
+	MSM_PIN_FUNCTION(ddr_pxi1),
+	MSM_PIN_FUNCTION(ddr_pxi10),
+	MSM_PIN_FUNCTION(ddr_pxi11),
+	MSM_PIN_FUNCTION(ddr_pxi12),
+	MSM_PIN_FUNCTION(ddr_pxi13),
+	MSM_PIN_FUNCTION(ddr_pxi14),
+	MSM_PIN_FUNCTION(ddr_pxi15),
+	MSM_PIN_FUNCTION(ddr_pxi2),
+	MSM_PIN_FUNCTION(ddr_pxi3),
+	MSM_PIN_FUNCTION(ddr_pxi4),
+	MSM_PIN_FUNCTION(ddr_pxi5),
+	MSM_PIN_FUNCTION(ddr_pxi6),
+	MSM_PIN_FUNCTION(ddr_pxi7),
+	MSM_PIN_FUNCTION(ddr_pxi8),
+	MSM_PIN_FUNCTION(ddr_pxi9),
+	MSM_PIN_FUNCTION(dp_rx0),
+	MSM_PIN_FUNCTION(dp_rx00),
+	MSM_PIN_FUNCTION(dp_rx01),
+	MSM_PIN_FUNCTION(dp_rx0_mute),
+	MSM_PIN_FUNCTION(dp_rx1),
+	MSM_PIN_FUNCTION(dp_rx10),
+	MSM_PIN_FUNCTION(dp_rx11),
+	MSM_PIN_FUNCTION(dp_rx1_mute),
+	MSM_PIN_FUNCTION(edp0_hot),
+	MSM_PIN_FUNCTION(edp0_lcd),
+	MSM_PIN_FUNCTION(edp1_hot),
+	MSM_PIN_FUNCTION(edp1_lcd),
+	MSM_PIN_FUNCTION(edp2_hot),
+	MSM_PIN_FUNCTION(edp2_lcd),
+	MSM_PIN_FUNCTION(edp3_hot),
+	MSM_PIN_FUNCTION(edp3_lcd),
+	MSM_PIN_FUNCTION(emac0_mcg0),
+	MSM_PIN_FUNCTION(emac0_mcg1),
+	MSM_PIN_FUNCTION(emac0_mcg2),
+	MSM_PIN_FUNCTION(emac0_mcg3),
+	MSM_PIN_FUNCTION(emac0_mdc),
+	MSM_PIN_FUNCTION(emac0_mdio),
+	MSM_PIN_FUNCTION(emac0_ptp),
+	MSM_PIN_FUNCTION(emac1_mcg0),
+	MSM_PIN_FUNCTION(emac1_mcg1),
+	MSM_PIN_FUNCTION(emac1_mcg2),
+	MSM_PIN_FUNCTION(emac1_mcg3),
+	MSM_PIN_FUNCTION(emac1_mdc),
+	MSM_PIN_FUNCTION(emac1_mdio),
+	MSM_PIN_FUNCTION(emac1_ptp),
+	MSM_PIN_FUNCTION(gcc_gp1_clk),
+	MSM_PIN_FUNCTION(gcc_gp2_clk),
+	MSM_PIN_FUNCTION(gcc_gp3_clk),
+	MSM_PIN_FUNCTION(gcc_gp4_clk),
+	MSM_PIN_FUNCTION(gcc_gp5_clk),
+	MSM_PIN_FUNCTION(gcc_gp6_clk),
+	MSM_PIN_FUNCTION(gcc_gp7_clk),
+	MSM_PIN_FUNCTION(gcc_gp8_clk),
+	MSM_PIN_FUNCTION(jitter_bist),
+	MSM_PIN_FUNCTION(lbist_pass),
+	MSM_PIN_FUNCTION(mbist_pass),
+	MSM_PIN_FUNCTION(mdp0_vsync0_out),
+	MSM_PIN_FUNCTION(mdp0_vsync10_out),
+	MSM_PIN_FUNCTION(mdp0_vsync1_out),
+	MSM_PIN_FUNCTION(mdp0_vsync2_out),
+	MSM_PIN_FUNCTION(mdp0_vsync3_out),
+	MSM_PIN_FUNCTION(mdp0_vsync4_out),
+	MSM_PIN_FUNCTION(mdp0_vsync5_out),
+	MSM_PIN_FUNCTION(mdp0_vsync6_out),
+	MSM_PIN_FUNCTION(mdp0_vsync7_out),
+	MSM_PIN_FUNCTION(mdp0_vsync8_out),
+	MSM_PIN_FUNCTION(mdp0_vsync9_out),
+	MSM_PIN_FUNCTION(mdp1_vsync0_out),
+	MSM_PIN_FUNCTION(mdp1_vsync10_out),
+	MSM_PIN_FUNCTION(mdp1_vsync1_out),
+	MSM_PIN_FUNCTION(mdp1_vsync2_out),
+	MSM_PIN_FUNCTION(mdp1_vsync3_out),
+	MSM_PIN_FUNCTION(mdp1_vsync4_out),
+	MSM_PIN_FUNCTION(mdp1_vsync5_out),
+	MSM_PIN_FUNCTION(mdp1_vsync6_out),
+	MSM_PIN_FUNCTION(mdp1_vsync7_out),
+	MSM_PIN_FUNCTION(mdp1_vsync8_out),
+	MSM_PIN_FUNCTION(mdp1_vsync9_out),
+	MSM_PIN_FUNCTION(mdp_vsync_e),
+	MSM_PIN_FUNCTION(mdp_vsync_p),
+	MSM_PIN_FUNCTION(mdp_vsync_s),
+	MSM_PIN_FUNCTION(pcie0_clk_req_n),
+	MSM_PIN_FUNCTION(pcie1_clk_req_n),
+	MSM_PIN_FUNCTION(pcie2_clk_req_n),
+	MSM_PIN_FUNCTION(pcie3_clk_req_n),
+	MSM_PIN_FUNCTION(phase_flag0),
+	MSM_PIN_FUNCTION(phase_flag1),
+	MSM_PIN_FUNCTION(phase_flag10),
+	MSM_PIN_FUNCTION(phase_flag11),
+	MSM_PIN_FUNCTION(phase_flag12),
+	MSM_PIN_FUNCTION(phase_flag13),
+	MSM_PIN_FUNCTION(phase_flag14),
+	MSM_PIN_FUNCTION(phase_flag15),
+	MSM_PIN_FUNCTION(phase_flag16),
+	MSM_PIN_FUNCTION(phase_flag17),
+	MSM_PIN_FUNCTION(phase_flag18),
+	MSM_PIN_FUNCTION(phase_flag19),
+	MSM_PIN_FUNCTION(phase_flag2),
+	MSM_PIN_FUNCTION(phase_flag20),
+	MSM_PIN_FUNCTION(phase_flag21),
+	MSM_PIN_FUNCTION(phase_flag22),
+	MSM_PIN_FUNCTION(phase_flag23),
+	MSM_PIN_FUNCTION(phase_flag24),
+	MSM_PIN_FUNCTION(phase_flag25),
+	MSM_PIN_FUNCTION(phase_flag26),
+	MSM_PIN_FUNCTION(phase_flag27),
+	MSM_PIN_FUNCTION(phase_flag28),
+	MSM_PIN_FUNCTION(phase_flag29),
+	MSM_PIN_FUNCTION(phase_flag3),
+	MSM_PIN_FUNCTION(phase_flag30),
+	MSM_PIN_FUNCTION(phase_flag31),
+	MSM_PIN_FUNCTION(phase_flag4),
+	MSM_PIN_FUNCTION(phase_flag5),
+	MSM_PIN_FUNCTION(phase_flag6),
+	MSM_PIN_FUNCTION(phase_flag7),
+	MSM_PIN_FUNCTION(phase_flag8),
+	MSM_PIN_FUNCTION(phase_flag9),
+	MSM_PIN_FUNCTION(pll_bist_sync),
+	MSM_PIN_FUNCTION(pll_clk_aux),
+	MSM_PIN_FUNCTION(prng_rosc0),
+	MSM_PIN_FUNCTION(prng_rosc1),
+	MSM_PIN_FUNCTION(pwrbrk_i_n),
+	MSM_PIN_FUNCTION(qdss_cti),
+	MSM_PIN_FUNCTION(qdss_gpio),
+	MSM_PIN_FUNCTION(qdss_gpio0),
+	MSM_PIN_FUNCTION(qdss_gpio1),
+	MSM_PIN_FUNCTION(qdss_gpio10),
+	MSM_PIN_FUNCTION(qdss_gpio11),
+	MSM_PIN_FUNCTION(qdss_gpio12),
+	MSM_PIN_FUNCTION(qdss_gpio13),
+	MSM_PIN_FUNCTION(qdss_gpio14),
+	MSM_PIN_FUNCTION(qdss_gpio15),
+	MSM_PIN_FUNCTION(qdss_gpio2),
+	MSM_PIN_FUNCTION(qdss_gpio3),
+	MSM_PIN_FUNCTION(qdss_gpio4),
+	MSM_PIN_FUNCTION(qdss_gpio5),
+	MSM_PIN_FUNCTION(qdss_gpio6),
+	MSM_PIN_FUNCTION(qdss_gpio7),
+	MSM_PIN_FUNCTION(qdss_gpio8),
+	MSM_PIN_FUNCTION(qdss_gpio9),
+	MSM_PIN_FUNCTION(qspi0),
+	MSM_PIN_FUNCTION(qspi1),
+	MSM_PIN_FUNCTION(qspi2),
+	MSM_PIN_FUNCTION(qspi3),
+	MSM_PIN_FUNCTION(qspi_clk),
+	MSM_PIN_FUNCTION(qspi_cs0_n),
+	MSM_PIN_FUNCTION(qspi_cs1_n),
+	MSM_PIN_FUNCTION(qup0_se0),
+	MSM_PIN_FUNCTION(qup0_se1),
+	MSM_PIN_FUNCTION(qup0_se2),
+	MSM_PIN_FUNCTION(qup0_se3),
+	MSM_PIN_FUNCTION(qup0_se4),
+	MSM_PIN_FUNCTION(qup0_se5),
+	MSM_PIN_FUNCTION(qup1_se0),
+	MSM_PIN_FUNCTION(qup1_se1),
+	MSM_PIN_FUNCTION(qup1_se2),
+	MSM_PIN_FUNCTION(qup1_se3),
+	MSM_PIN_FUNCTION(qup1_se4),
+	MSM_PIN_FUNCTION(qup1_se5),
+	MSM_PIN_FUNCTION(qup1_se6),
+	MSM_PIN_FUNCTION(qup2_se0),
+	MSM_PIN_FUNCTION(qup2_se1),
+	MSM_PIN_FUNCTION(qup2_se2),
+	MSM_PIN_FUNCTION(qup2_se3),
+	MSM_PIN_FUNCTION(qup2_se4),
+	MSM_PIN_FUNCTION(qup2_se5),
+	MSM_PIN_FUNCTION(qup2_se6),
+	MSM_PIN_FUNCTION(qup3_se0_mira),
+	MSM_PIN_FUNCTION(qup3_se0_mirb),
+	MSM_PIN_FUNCTION(sailss_ospi),
+	MSM_PIN_FUNCTION(sdc4_clk),
+	MSM_PIN_FUNCTION(sdc4_cmd),
+	MSM_PIN_FUNCTION(sdc4_data),
+	MSM_PIN_FUNCTION(smb_alert),
+	MSM_PIN_FUNCTION(smb_alert_n),
+	MSM_PIN_FUNCTION(smb_clk),
+	MSM_PIN_FUNCTION(smb_dat),
+	MSM_PIN_FUNCTION(tb_trig_sdc4),
+	MSM_PIN_FUNCTION(tmess_prng0),
+	MSM_PIN_FUNCTION(tmess_prng1),
+	MSM_PIN_FUNCTION(tsc_timer0),
+	MSM_PIN_FUNCTION(tsc_timer1),
+	MSM_PIN_FUNCTION(tsc_timer2),
+	MSM_PIN_FUNCTION(tsc_timer3),
+	MSM_PIN_FUNCTION(tsc_timer4),
+	MSM_PIN_FUNCTION(tsc_timer5),
+	MSM_PIN_FUNCTION(tsc_timer6),
+	MSM_PIN_FUNCTION(tsc_timer7),
+	MSM_PIN_FUNCTION(tsc_timer8),
+	MSM_PIN_FUNCTION(tsc_timer9),
+	MSM_PIN_FUNCTION(tsense_pwm1),
+	MSM_PIN_FUNCTION(tsense_pwm2),
+	MSM_PIN_FUNCTION(tsense_pwm3),
+	MSM_PIN_FUNCTION(tsense_pwm4),
+	MSM_PIN_FUNCTION(tsense_pwm5),
+	MSM_PIN_FUNCTION(tsense_pwm6),
+	MSM_PIN_FUNCTION(tsense_pwm7),
+	MSM_PIN_FUNCTION(tsense_pwm8),
+	MSM_PIN_FUNCTION(usb0_hs),
+	MSM_PIN_FUNCTION(usb0_phy_ps),
+	MSM_PIN_FUNCTION(usb1_hs),
+	MSM_PIN_FUNCTION(usb1_phy_ps),
+	MSM_PIN_FUNCTION(usb2_hs),
+	MSM_PIN_FUNCTION(usxgmii0_phy),
+	MSM_PIN_FUNCTION(usxgmii1_phy),
+	MSM_PIN_FUNCTION(vsense_trigger_mirnat),
+	MSM_PIN_FUNCTION(wcn_sw),
+	MSM_PIN_FUNCTION(wcn_sw_ctrl),
+};
+
+/* Every pin is maintained as a single group, and missing or non-existing pin
+ * would be maintained as dummy group to synchronize pin group index with
+ * pin descriptor registered with pinctrl core.
+ * Clients would not be able to request these dummy pin groups.
+ */
+static const struct msm_pingroup nord_groups[] = {
+	[0] = PINGROUP(0, _, _, _, _, _, _, _, _, _, _, _),
+	[1] = PINGROUP(1, pcie0_clk_req_n, _, _, _, _, _, _, _, _, _, _),
+	[2] = PINGROUP(2, _, _, _, _, _, _, _, _, _, _, _),
+	[3] = PINGROUP(3, _, _, _, _, _, _, _, _, _, _, _),
+	[4] = PINGROUP(4, pcie1_clk_req_n, _, _, _, _, _, _, _, _, _, _),
+	[5] = PINGROUP(5, _, _, _, _, _, _, _, _, _, _, _),
+	[6] = PINGROUP(6, _, _, _, _, _, _, _, _, _, _, _),
+	[7] = PINGROUP(7, pcie2_clk_req_n, _, _, _, _, _, _, _, _, _, _),
+	[8] = PINGROUP(8, _, _, _, _, _, _, _, _, _, _, _),
+	[9] = PINGROUP(9, _, _, _, _, _, _, _, _, _, _, _),
+	[10] = PINGROUP(10, pcie3_clk_req_n, _, _, _, _, _, _, _, _, _, _),
+	[11] = PINGROUP(11, _, _, _, _, _, _, _, _, _, _, _),
+	[12] = PINGROUP(12, usb0_hs, clink_debug, _, _, _, _, _, _, _, _, _),
+	[13] = PINGROUP(13, usb1_hs, clink_debug, gcc_gp7_clk, _, _, _, _, _, _, _, _),
+	[14] = PINGROUP(14, usb2_hs, clink_debug, gcc_gp8_clk, _, _, _, _, _, _, _, _),
+	[15] = PINGROUP(15, ccu_i2c_sda0, _, _, _, _, _, _, _, _, _, _),
+	[16] = PINGROUP(16, ccu_i2c_scl0, emac0_mcg0, _, _, _, _, _, _, _, _, _),
+	[17] = PINGROUP(17, ccu_i2c_sda1, emac0_mcg1, _, _, _, _, _, _, _, _, _),
+	[18] = PINGROUP(18, ccu_i2c_scl1, emac0_mcg2, _, _, _, _, _, _, _, _, _),
+	[19] = PINGROUP(19, ccu_i2c_sda2, emac0_mcg3, _, _, _, _, _, _, _, _, _),
+	[20] = PINGROUP(20, ccu_i2c_scl2, emac1_mcg0, _, _, _, _, _, _, _, _, _),
+	[21] = PINGROUP(21, ccu_i2c_sda3, emac1_mcg1, _, _, _, _, _, _, _, _, _),
+	[22] = PINGROUP(22, ccu_i2c_scl3, emac1_mcg2, _, _, _, _, _, _, _, _, _),
+	[23] = PINGROUP(23, ccu_i2c_sda4, emac1_mcg3, _, _, _, _, _, _, _, _, _),
+	[24] = PINGROUP(24, ccu_i2c_scl4, _, _, _, _, _, _, _, _, _, _),
+	[25] = PINGROUP(25, ccu_timer0, tsc_timer0, _, _, _, _, _, _, _, _, _),
+	[26] = PINGROUP(26, ccu_timer1, tsc_timer1, _, _, _, _, _, _, _, _, _),
+	[27] = PINGROUP(27, ccu_timer2, tsc_timer2, _, _, _, _, _, _, _, _, _),
+	[28] = PINGROUP(28, ccu_timer3, tsc_timer3, _, _, _, _, _, _, _, _, _),
+	[29] = PINGROUP(29, ccu_timer4, tsc_timer4, _, _, _, _, _, _, _, _, _),
+	[30] = PINGROUP(30, ccu_timer5, tsc_timer5, _, _, _, _, _, _, _, _, _),
+	[31] = PINGROUP(31, ccu_timer6, tsc_timer6, _, _, _, _, _, _, _, _, _),
+	[32] = PINGROUP(32, ccu_timer7, tsc_timer7, _, _, _, _, _, _, _, _, _),
+	[33] = PINGROUP(33, ccu_timer8, tsc_timer8, _, _, _, _, _, _, _, _, _),
+	[34] = PINGROUP(34, ccu_timer9, tsc_timer9, _, _, _, _, _, _, _, _, _),
+	[35] = PINGROUP(35, dp_rx0_mute, _, _, _, _, _, _, _, _, _, _),
+	[36] = PINGROUP(36, dp_rx1_mute, ddr_bist_start, _, _, _, _, _, _, _, _, _),
+	[37] = PINGROUP(37, emac1_ptp, ddr_bist_complete, _, _, _, _, _, _, _, _, _),
+	[38] = PINGROUP(38, emac1_ptp, ddr_bist_stop, _, _, _, _, _, _, _, _, _),
+	[39] = PINGROUP(39, emac1_ptp, ddr_bist_fail, _, _, _, _, _, _, _, _, _),
+	[40] = PINGROUP(40, emac1_ptp, _, _, _, _, _, _, _, _, _, _),
+	[41] = PINGROUP(41, emac1_ptp, qdss_cti, _, _, _, _, _, _, _, _, _),
+	[42] = PINGROUP(42, emac1_ptp, qdss_cti, gcc_gp3_clk, _, _, _, _, _, _, _, _),
+	[43] = PINGROUP(43, emac1_ptp, gcc_gp4_clk, tsense_pwm1, _, _, _, _, _, _, _, _),
+	[44] = PINGROUP(44, emac1_ptp, tsense_pwm2, _, _, _, _, _, _, _, _, _),
+	[45] = PINGROUP(45, usxgmii0_phy, ccu_async_in5, tsense_pwm3, _, _, _, _, _, _, _, _),
+	[46] = PINGROUP(46, usxgmii1_phy, tsense_pwm4, _, _, _, _, _, _, _, _, _),
+	[47] = PINGROUP(47, emac0_mdc, edp0_lcd, tsense_pwm5, _, _, _, _, _, _, _, _),
+	[48] = PINGROUP(48, emac0_mdio, edp1_lcd, tsense_pwm6, _, _, _, _, _, _, _, _),
+	[49] = PINGROUP(49, emac1_mdc, edp2_lcd, tsense_pwm7, _, _, _, _, _, _, _, _),
+	[50] = PINGROUP(50, emac1_mdio, edp3_lcd, tsense_pwm8, _, _, _, _, _, _, _, _),
+	[51] = PINGROUP(51, edp0_hot, clink_debug, gcc_gp1_clk, _, _, _, _, _, _, _, _),
+	[52] = PINGROUP(52, edp1_hot, clink_debug, gcc_gp2_clk, _, _, _, _, _, _, _, _),
+	[53] = PINGROUP(53, edp2_hot, clink_debug, _, _, _, _, _, _, _, _, _),
+	[54] = PINGROUP(54, edp3_hot, clink_debug, _, _, _, _, _, _, _, _, _),
+	[55] = PINGROUP(55, dp_rx0, clink_debug, _, _, _, _, _, _, _, _, _),
+	[56] = PINGROUP(56, dp_rx1, _, _, _, _, _, _, _, _, _, _),
+	[57] = PINGROUP(57, aud_intfc0_clk, _, _, _, _, _, _, _, _, _, _),
+	[58] = PINGROUP(58, aud_intfc0_ws, _, _, _, _, _, _, _, _, _, _),
+	[59] = PINGROUP(59, aud_intfc0_data0, _, _, _, _, _, _, _, _, _, _),
+	[60] = PINGROUP(60, aud_intfc0_data1, _, _, _, _, _, _, _, _, _, _),
+	[61] = PINGROUP(61, aud_intfc0_data2, aud_intfc10_clk, _, _, _, _, _, _, _, _, _),
+	[62] = PINGROUP(62, aud_intfc0_data3, aud_intfc10_ws, _, _, _, _, _, _, _, _, _),
+	[63] = PINGROUP(63, aud_intfc0_data4, aud_intfc7_clk, _, _, _, _, _, _, _, _, _),
+	[64] = PINGROUP(64, aud_intfc0_data5, aud_intfc7_ws, _, _, _, _, _, _, _, _, _),
+	[65] = PINGROUP(65, aud_intfc0_data6, aud_intfc7_data0, _, _, _, _, _, _, _, _, _),
+	[66] = PINGROUP(66, aud_intfc0_data7, aud_intfc7_data1, _, _, _, _, _, _, _, _, _),
+	[67] = PINGROUP(67, aud_intfc1_clk, phase_flag18, _, qdss_gpio0, _, _, _, _, _, _, _),
+	[68] = PINGROUP(68, aud_intfc1_ws, phase_flag19, _, qdss_gpio1, _, _, _, _, _, _, _),
+	[69] = PINGROUP(69, aud_intfc1_data0, phase_flag20, _, qdss_gpio2, _, _, _, _, _, _, _),
+	[70] = PINGROUP(70, aud_intfc1_data1, aud_intfc9_clk, phase_flag21,
+			_, qdss_gpio3, _, _, _, _, _, _),
+	[71] = PINGROUP(71, aud_intfc1_data2, aud_intfc9_ws, phase_flag22,
+			_, qdss_gpio4, _, _, _, _, _, _),
+	[72] = PINGROUP(72, aud_intfc1_data3, aud_intfc9_data0, phase_flag23,
+			_, qdss_gpio5, _, _, _, _, _, _),
+	[73] = PINGROUP(73, aud_intfc1_data4, aud_intfc8_clk, phase_flag24,
+			_, qdss_gpio6, _, _, _, _, _, _),
+	[74] = PINGROUP(74, aud_intfc1_data5, aud_intfc8_ws, phase_flag25,
+			_, qdss_gpio7, _, _, _, _, _, _),
+	[75] = PINGROUP(75, aud_intfc1_data6, aud_intfc8_data0, phase_flag26,
+			_, qdss_gpio, _, _, _, _, _, _),
+	[76] = PINGROUP(76, aud_intfc1_data7, aud_intfc8_data1, phase_flag27,
+			_, qdss_gpio, _, _, _, _, _, _),
+	[77] = PINGROUP(77, aud_intfc2_clk, phase_flag6, _, qdss_gpio8, _, _, _, _, _, _, _),
+	[78] = PINGROUP(78, aud_intfc2_ws, phase_flag5, _, qdss_gpio9, _, _, _, _, _, _, _),
+	[79] = PINGROUP(79, aud_intfc2_data0, phase_flag4, _, qdss_gpio10, _, _, _, _, _, _, _),
+	[80] = PINGROUP(80, aud_intfc2_data1, phase_flag3, _, _, qdss_gpio11, _, _, _, _, _, _),
+	[81] = PINGROUP(81, aud_intfc2_data2, aud_intfc10_data0, phase_flag2,
+			_, _, qdss_gpio12, _, _, _, _, _),
+	[82] = PINGROUP(82, aud_intfc2_data3, aud_intfc10_data1, phase_flag1,
+			_, qdss_gpio13, _, _, _, _, _, _),
+	[83] = PINGROUP(83, aud_intfc3_clk, dp_rx0, aoss_cti, phase_flag28, _, qdss_gpio14,
+			_, _, _, _, _),
+	[84] = PINGROUP(84, aud_intfc3_ws, dp_rx0, aoss_cti, phase_flag29, _, qdss_gpio15,
+			_, _, _, _, _),
+	[85] = PINGROUP(85, aud_intfc3_data0, dp_rx0, aoss_cti, phase_flag30,
+			_, qdss_gpio0, _, _, _, _, _),
+	[86] = PINGROUP(86, aud_intfc3_data1, aud_mclk0_mirb, dp_rx0, aoss_cti, phase_flag31,
+			_, qdss_gpio1, _, _, _, _),
+	[87] = PINGROUP(87, aud_intfc4_clk, phase_flag7, _, qdss_gpio2, _, _, _, _, _, _, _),
+	[88] = PINGROUP(88, aud_intfc4_ws, dp_rx0, phase_flag8, _, qdss_gpio3, _, _, _, _, _, _),
+	[89] = PINGROUP(89, aud_intfc4_data0, dp_rx0, phase_flag9, _, qdss_gpio4,
+			_, _, _, _, _, _),
+	[90] = PINGROUP(90, aud_intfc4_data1, aud_mclk1_mirb, phase_flag10,
+			_, qdss_gpio5, _, _, _, _, _, _),
+	[91] = PINGROUP(91, aud_intfc5_clk, phase_flag11, _, qdss_gpio6, _, _, _, _, _, _, _),
+	[92] = PINGROUP(92, aud_intfc5_ws, dp_rx1, phase_flag12, _, qdss_gpio7, _, _, _, _, _, _),
+	[93] = PINGROUP(93, aud_intfc5_data0, dp_rx1, phase_flag13, _, qdss_gpio,
+			_, _, _, _, _, _),
+	[94] = PINGROUP(94, aud_intfc5_data1, aud_mclk2_mirb, phase_flag14, tmess_prng0,
+			_, qdss_gpio8, _, _, _, _, _),
+	[95] = PINGROUP(95, aud_intfc6_clk, dp_rx1, phase_flag15, tmess_prng1,
+			_, qdss_gpio9, _, _, _, _, _),
+	[96] = PINGROUP(96, aud_intfc6_ws, dp_rx1, phase_flag16, _, qdss_gpio10,
+			_, _, _, _, _, _),
+	[97] = PINGROUP(97, aud_intfc6_data0, dp_rx1, qdss_gpio11, _, _, _, _, _, _, _, _),
+	[98] = PINGROUP(98, aud_intfc6_data1, dp_rx1, phase_flag0, _, qdss_gpio12,
+			_, _, _, _, _, _),
+	[99] = PINGROUP(99, aud_mclk0_mira, qdss_gpio13, dp_rx00, ddr_pxi0, _, _, _, _, _, _, _),
+	[100] = PINGROUP(100, aud_mclk1_mira, aud_refclk0, pll_clk_aux,
+			 qdss_gpio14, dp_rx01, ddr_pxi0, _, _, _, _, _),
+	[101] = PINGROUP(101, aud_mclk2_mira, aud_refclk1, phase_flag17, _, qdss_gpio15,
+			 _, _, _, _, _, _),
+	[102] = PINGROUP(102, qspi0, qup3_se0_mira, qup3_se0_mirb, _, _, _, _, _, _, _, _),
+	[103] = PINGROUP(103, qspi1, qup3_se0_mira, qup3_se0_mirb, _, _, _, _, _, _, _, _),
+	[104] = PINGROUP(104, qspi_clk, qup3_se0_mira, _, _, _, _, _, _, _, _, _),
+	[105] = PINGROUP(105, qspi_cs0_n, qup3_se0_mira, gcc_gp5_clk, _, _, _, _, _, _, _, _),
+	[106] = PINGROUP(106, qspi2, qup3_se0_mira, gcc_gp6_clk, _, _, _, _, _, _, _, _),
+	[107] = PINGROUP(107, qspi3, qup3_se0_mira, _, _, _, _, _, _, _, _, _),
+	[108] = PINGROUP(108, qspi_cs1_n, qup3_se0_mira, qdss_gpio, _, _, _, _, _, _, _, _),
+	[109] = PINGROUP(109, qup0_se0, qup0_se1, qup0_se5, mdp_vsync_e,
+			 smb_alert_n, _, ddr_pxi1, _, _, _, _),
+	[110] = PINGROUP(110, qup0_se0, qup0_se1, qup0_se5, qdss_cti,
+			 mdp_vsync_p, smb_alert, _, ddr_pxi1, _, _, _),
+	[111] = PINGROUP(111, qup0_se1, qup0_se0, smb_dat, _, _, _, _, _, _, _, _),
+	[112] = PINGROUP(112, qup0_se1, qup0_se0, smb_clk, _, _, _, _, _, _, _, _),
+	[113] = PINGROUP(113, qup0_se2, qup0_se3, ccu_i2c_sda5, mdp0_vsync0_out,
+			 dbg_out, ddr_pxi2, _, _, _, _, _),
+	[114] = PINGROUP(114, qup0_se2, qup0_se3, ccu_i2c_scl5, mdp0_vsync1_out,
+			 _, ddr_pxi2, _, _, _, _, _),
+	[115] = PINGROUP(115, qup0_se3, qup0_se2, ccu_i2c_sda6, mdp0_vsync2_out,
+			 _, ddr_pxi3, _, _, _, _, _),
+	[116] = PINGROUP(116, qup0_se3, qup0_se2, ccu_i2c_scl6, mdp0_vsync3_out,
+			 _, ddr_pxi3, _, _, _, _, _),
+	[117] = PINGROUP(117, qup0_se4, prng_rosc0, _, ddr_pxi4, _, _, _, _, _, _, _),
+	[118] = PINGROUP(118, qup0_se4, prng_rosc1, _, ddr_pxi4, _, _, _, _, _, _, _),
+	[119] = PINGROUP(119, qup0_se4, _, ddr_pxi6, _, _, _, _, _, _, _, _),
+	[120] = PINGROUP(120, qup0_se4, _, ddr_pxi6, _, _, _, _, _, _, _, _),
+	[121] = PINGROUP(121, qup0_se5, lbist_pass, mdp0_vsync4_out, _, dp_rx10, ddr_pxi7,
+			 _, _, _, _, _),
+	[122] = PINGROUP(122, qup0_se5, mbist_pass, mdp0_vsync5_out, _, dp_rx11, ddr_pxi7,
+			 _, _, _, _, _),
+	[123] = PINGROUP(123, qup1_se0, qup1_se1, mdp1_vsync0_out, jitter_bist,
+			 _, _, _, _, _, _, _),
+	[124] = PINGROUP(124, qup1_se0, qup1_se1, mdp1_vsync1_out, _, _, _, _, _, _, _, _),
+	[125] = PINGROUP(125, qup1_se1, qup1_se0, ccu_i2c_sda7, mdp1_vsync2_out,
+			 _, _, _, _, _, _, _),
+	[126] = PINGROUP(126, qup1_se1, qup1_se0, ccu_i2c_scl7, mdp1_vsync3_out,
+			 _, atest_usb20, ddr_pxi8, _, _, _, _),
+	[127] = PINGROUP(127, qup1_se2, qup1_se2, _, atest_usb21, ddr_pxi8,
+			 _, _, _, _, _, _),
+	[128] = PINGROUP(128, qup1_se2, qup1_se2, _, atest_usb20, ddr_pxi9,
+			 _, _, _, _, _, _),
+	[129] = PINGROUP(129, qup1_se3, qup1_se3, ccu_i2c_sda8, mdp1_vsync4_out,
+			 _, atest_usb21, ddr_pxi9, _, _, _, _),
+	[130] = PINGROUP(130, qup1_se3, qup1_se3, ccu_i2c_scl8, mdp1_vsync5_out,
+			 _, atest_usb20, ddr_pxi10, _, _, _, _),
+	[131] = PINGROUP(131, qup1_se4, qup1_se6, ccu_i2c_sda9, mdp1_vsync6_out,
+			 _, atest_usb21, ddr_pxi10, _, _, _, _),
+	[132] = PINGROUP(132, qup1_se4, qup1_se6, ccu_i2c_scl9, mdp1_vsync7_out,
+			 _, vsense_trigger_mirnat, ddr_pxi11, _, _, _, _),
+	[133] = PINGROUP(133, qup1_se5, emac0_ptp, mdp1_vsync8_out, _, ddr_pxi11,
+			 _, _, _, _, _, _),
+	[134] = PINGROUP(134, qup1_se5, emac0_ptp, mdp1_vsync9_out, _, ddr_pxi12,
+			 _, _, _, _, _, _),
+	[135] = PINGROUP(135, qup1_se5, emac0_ptp, mdp1_vsync10_out, _, ddr_pxi12,
+			 _, _, _, _, _, _),
+	[136] = PINGROUP(136, qup1_se5, emac0_ptp, _, ddr_pxi13, _, _, _, _, _, _, _),
+	[137] = PINGROUP(137, qup1_se6, qup1_se4, dp_rx0, _, ddr_pxi13, _, _, _, _, _, _),
+	[138] = PINGROUP(138, qup1_se6, qup1_se4, dp_rx0, qdss_cti, jitter_bist, ddr_pxi14,
+			 _, _, _, _, _),
+	[139] = PINGROUP(139, qup2_se0, emac0_ptp, mdp0_vsync6_out, ddr_pxi14,
+			 _, _, _, _, _, _, _),
+	[140] = PINGROUP(140, qup2_se0, emac0_ptp, mdp0_vsync7_out, _, _, _, _, _, _, _, _),
+	[141] = PINGROUP(141, qup2_se0, emac0_ptp, mdp0_vsync8_out, _, _, _, _, _, _, _, _),
+	[142] = PINGROUP(142, qup2_se0, emac0_ptp, qdss_cti, mdp0_vsync9_out, _, _, _, _, _, _, _),
+	[143] = PINGROUP(143, qup2_se1, qup2_se4, ccu_timer10, mdp0_vsync10_out,
+			 _, _, _, _, _, _, _),
+	[144] = PINGROUP(144, qup2_se1, qup2_se4, ccu_timer11, qdss_cti, mdp_vsync_s,
+			 _, _, _, _, _, _),
+	[145] = PINGROUP(145, qup2_se2, _, _, _, _, _, _, _, _, _, _),
+	[146] = PINGROUP(146, qup2_se2, _, _, _, _, _, _, _, _, _, _),
+	[147] = PINGROUP(147, qup2_se2, _, _, _, _, _, _, _, _, _, _),
+	[148] = PINGROUP(148, qup2_se2, _, _, _, _, _, _, _, _, _, _),
+	[149] = PINGROUP(149, qup2_se2, _, _, _, _, _, _, _, _, _, _),
+	[150] = PINGROUP(150, qup2_se3, qup2_se4, ccu_timer12, _, _, _, _, _, _, _, _),
+	[151] = PINGROUP(151, qup2_se3, qup2_se4, ccu_timer13, _, _, _, _, _, _, _, _),
+	[152] = PINGROUP(152, qup2_se3, qup2_se4, ccu_timer14, _, _, _, _, _, _, _, _),
+	[153] = PINGROUP(153, qup2_se3, ccu_timer15, _, _, _, _, _, _, _, _, _),
+	[154] = PINGROUP(154, qup2_se4, qup2_se1, _, _, _, _, _, _, _, _, _),
+	[155] = PINGROUP(155, qup2_se4, qup2_se1, _, _, _, _, _, _, _, _, _),
+	[156] = PINGROUP(156, qup2_se5, qup2_se6, _, _, _, _, _, _, _, _, _),
+	[157] = PINGROUP(157, qup2_se5, qup2_se6, _, _, _, _, _, _, _, _, _),
+	[158] = PINGROUP(158, qup2_se6, qup2_se5, dp_rx1, _, _, _, _, _, _, _, _),
+	[159] = PINGROUP(159, qup2_se6, qup2_se5, dp_rx1, _, _, _, _, _, _, _, _),
+	[160] = PINGROUP(160, wcn_sw_ctrl, _, _, _, _, _, _, _, _, _, _),
+	[161] = PINGROUP(161, wcn_sw, _, _, _, _, _, _, _, _, _, _),
+	[162] = PINGROUP(162, qdss_cti, _, ddr_pxi15, _, _, _, _, _, _, _, _),
+	[163] = PINGROUP(163, qdss_cti, _, ddr_pxi15, _, _, _, _, _, _, _, _),
+	[164] = PINGROUP(164, usb0_phy_ps, _, sailss_ospi, ddr_pxi5, _, _, _, _, _, _, _),
+	[165] = PINGROUP(165, usb1_phy_ps, dbg_out_clk, sailss_ospi, ddr_pxi5,
+			 _, _, _, _, _, _, _),
+	[166] = PINGROUP(166, _, _, _, _, _, _, _, _, _, _, _),
+	[167] = PINGROUP(167, pwrbrk_i_n, _, _, _, _, _, _, _, _, _, _),
+	[168] = PINGROUP(168, bist_done, _, _, _, _, _, _, _, _, _, _),
+	[169] = PINGROUP(169, tb_trig_sdc4, _, _, _, _, _, _, _, _, _, _),
+	[170] = PINGROUP(170, sdc4_data, _, _, _, _, _, _, _, _, _, _),
+	[171] = PINGROUP(171, sdc4_data, _, _, _, _, _, _, _, _, _, _),
+	[172] = PINGROUP(172, sdc4_data, _, _, _, _, _, _, _, _, _, _),
+	[173] = PINGROUP(173, sdc4_data, _, _, _, _, _, _, _, _, _, _),
+	[174] = PINGROUP(174, sdc4_cmd, _, _, _, _, _, _, _, _, _, _),
+	[175] = PINGROUP(175, sdc4_clk, _, _, _, _, _, _, _, _, _, _),
+	[176] = PINGROUP(176, ccu_async_in0, pll_bist_sync, atest_char_start,
+			 _, _, _, _, _, _, _, _),
+	[177] = PINGROUP(177, ccu_async_in1, atest_char0, _, _, _, _, _, _, _, _, _),
+	[178] = PINGROUP(178, ccu_async_in2, atest_char1, _, _, _, _, _, _, _, _, _),
+	[179] = PINGROUP(179, ccu_async_in3, atest_char2, _, _, _, _, _, _, _, _, _),
+	[180] = PINGROUP(180, ccu_async_in4, atest_char3, _, _, _, _, _, _, _, _, _),
+	[181] = UFS_RESET(ufs_reset, 0xBD004),
+};
+
+static const struct msm_gpio_wakeirq_map nord_pdc_map[] = {
+	{ 0, 67 },    { 1, 68 },    { 2, 82 },	  { 3, 69 },	{ 4, 70 },
+	{ 5, 83 },    { 6, 71 },    { 7, 72 },	  { 8, 84 },	{ 9, 73 },
+	{ 10, 119 },  { 11, 85 },   { 45, 107 },  { 46, 98 },	{ 102, 77 },
+	{ 108, 78 },  { 110, 120 }, { 114, 80 },  { 116, 81 },	{ 120, 117 },
+	{ 124, 108 }, { 126, 99 },  { 128, 100 }, { 132, 101 }, { 138, 87 },
+	{ 142, 88 },  { 144, 89 },  { 153, 90 },  { 157, 91 },	{ 159, 118 },
+	{ 160, 110 }, { 161, 79 },  { 166, 109 }, { 168, 111 },
+};
+
+static const struct msm_pinctrl_soc_data nord_tlmm = {
+	.pins = nord_pins,
+	.npins = ARRAY_SIZE(nord_pins),
+	.functions = nord_functions,
+	.nfunctions = ARRAY_SIZE(nord_functions),
+	.groups = nord_groups,
+	.ngroups = ARRAY_SIZE(nord_groups),
+	.ngpios = 182,
+	.wakeirq_map = nord_pdc_map,
+	.nwakeirq_map = ARRAY_SIZE(nord_pdc_map),
+	.egpio_func = 11,
+};
+
+static const struct of_device_id nord_tlmm_of_match[] = {
+	{ .compatible = "qcom,nord-tlmm", .data = &nord_tlmm },
+	{},
+};
+MODULE_DEVICE_TABLE(of, nord_tlmm_of_match);
+
+static int nord_tlmm_probe(struct platform_device *pdev)
+{
+	const struct msm_pinctrl_soc_data *pinctrl_data;
+	struct device *dev = &pdev->dev;
+
+	pinctrl_data = device_get_match_data(dev);
+	if (!pinctrl_data)
+		return -EINVAL;
+
+	return msm_pinctrl_probe(pdev, &nord_tlmm);
+}
+
+static struct platform_driver nord_tlmm_driver = {
+	.driver = {
+		.name = "nord-tlmm",
+		.of_match_table = nord_tlmm_of_match,
+	},
+	.probe = nord_tlmm_probe,
+};
+
+static int __init nord_tlmm_init(void)
+{
+	return platform_driver_register(&nord_tlmm_driver);
+}
+arch_initcall(nord_tlmm_init);
+
+static void __exit nord_tlmm_exit(void)
+{
+	platform_driver_unregister(&nord_tlmm_driver);
+}
+module_exit(nord_tlmm_exit);
+
+MODULE_DESCRIPTION("Qualcomm Technologies Inc. Nordschleife TLMM driver");
+MODULE_AUTHOR("Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>");
+MODULE_LICENSE("GPL");

-- 
2.47.3


^ permalink raw reply related

* Re: [PATCH DRAFT] net: cirrus: ep93xx: fix probe error unwind
From: Andrew Lunn @ 2026-04-27 14:12 UTC (permalink / raw)
  To: Myeonghun Pak
  Cc: Hartley Sweeten, Andrew Lunn, David S . Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Ijae Kim, netdev, linux-kernel
In-Reply-To: <CAGEsz8EkSB8T=D3uPzAt+1Qbh0h+-u6=1ABE13uwK5ZF=uVLkw@mail.gmail.com>

On Mon, Apr 27, 2026 at 12:18:33PM +0900, Myeonghun Pak wrote:
> For the repro, I used an x86 COMPILE_TEST QEMU boot with ep93xx_eth.ko loaded
> and a synthetic ep93xx-eth platform device. I configured failslab with a
> stacktrace filter so the injected allocation failure happened inside
> register_netdevice(). That made register_netdev() fail from ep93xx_eth_probe().

So totally synthetic, not real world.

This driver was added in 2006. Can you point to reports of this being
a real problem any time in the last 20 years? Is this a problem worth
fixing because it does actually happen?

> This was originally found as part of the results from an ongoing research
> project with my fellow researchers.

Please redirect your effort to drivers which are still in use. Drivers
from the last 5-10 years. Drivers which are worth fixing, and have
Maintainers who cares about the driver. And problems which are likely
to happen in the real world, not an synthetic setting.

     Andrew

^ permalink raw reply

* RE: [PATCH iwl-net v2] ice: fix SMA and U.FL pin state changes affecting paired pin
From: Kubalewski, Arkadiusz @ 2026-04-27 14:14 UTC (permalink / raw)
  To: Oros, Petr, netdev@vger.kernel.org
  Cc: Oros, Petr, Nguyen, Anthony L, Kitszel, Przemyslaw, Andrew Lunn,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, intel-wired-lan@lists.osuosl.org,
	linux-kernel@vger.kernel.org
In-Reply-To: <20260408110504.1032879-1-poros@redhat.com>

>From: Petr Oros <poros@redhat.com>
>Sent: Wednesday, April 8, 2026 1:05 PM
>
>SMA and U.FL pins share physical signal paths in pairs (SMA1/U.FL1 and
>SMA2/U.FL2) controlled by the PCA9575 GPIO expander.  Each pair can
>only have one active pin at a time: SMA1 output and U.FL1 output share
>the same CGU output, SMA2 input and U.FL2 input share the same CGU
>input.  The PCA9575 register bits determine which connector in each
>pair owns the signal path.
>
>The driver does not account for this pairing in two places:
>
>ice_dpll_ufl_pin_state_set() modifies PCA9575 bits and disables the
>backing CGU pin without checking whether the U.FL pin is currently
>active.  Disconnecting an already inactive U.FL pin flips bits that
>the paired SMA pin relies on, breaking its connection.
>
>ice_dpll_sma_direction_set() does not propagate direction changes to
>the paired U.FL pin.  For SMA2/U.FL2 the ICE_SMA2_UFL2_RX_DIS bit is
>never managed, so U.FL2 stays disconnected after SMA2 switches to
>output.  For both pairs the backing CGU pin of the U.FL side is never
>enabled when a direction change activates it, so userspace sees the
>pin as disconnected even though the routing is correct.
>
>Fix by guarding the U.FL disconnect path against inactive pins and by
>updating the paired U.FL pin fully on SMA direction changes: manage
>ICE_SMA2_UFL2_RX_DIS for the SMA2/U.FL2 pair and enable the backing
>CGU pin whenever the peer becomes active.
>
>Fixes: 2dd5d03c77e2 ("ice: redesign dpll sma/u.fl pins control")

LGTM,

Reviewed-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>

>Signed-off-by: Petr Oros <poros@redhat.com>
>---
>v2:
> - fix ice_dpll_sma_direction_set() to manage ICE_SMA2_UFL2_RX_DIS
>   when SMA2 direction changes
> - enable paired U.FL backing CGU pin when direction change makes
>   it active, so it reports as connected immediately
> - (both reported by Intel test on the SMA init and notification
>   patch threads)
>v1: https://lore.kernel.org/all/20260325151050.2081977-1-poros@redhat.com/
>---
> drivers/net/ethernet/intel/ice/ice_dpll.c | 50 ++++++++++++++++++++++-
> 1 file changed, 49 insertions(+), 1 deletion(-)
>
>diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c
>b/drivers/net/ethernet/intel/ice/ice_dpll.c
>index 498ec2c045f384..3f8cd5b8298b57 100644
>--- a/drivers/net/ethernet/intel/ice/ice_dpll.c
>+++ b/drivers/net/ethernet/intel/ice/ice_dpll.c
>@@ -1171,6 +1171,8 @@ static int ice_dpll_sma_direction_set(struct
>ice_dpll_pin *p,
> 				      enum dpll_pin_direction direction,
> 				      struct netlink_ext_ack *extack)
> {
>+	struct ice_dplls *d = &p->pf->dplls;
>+	struct ice_dpll_pin *peer;
> 	u8 data;
> 	int ret;
>
>@@ -1189,8 +1191,9 @@ static int ice_dpll_sma_direction_set(struct
>ice_dpll_pin *p,
> 	case ICE_DPLL_PIN_SW_2_IDX:
> 		if (direction == DPLL_PIN_DIRECTION_INPUT) {
> 			data &= ~ICE_SMA2_DIR_EN;
>+			data |= ICE_SMA2_UFL2_RX_DIS;
> 		} else {
>-			data &= ~ICE_SMA2_TX_EN;
>+			data &= ~(ICE_SMA2_TX_EN | ICE_SMA2_UFL2_RX_DIS);
> 			data |= ICE_SMA2_DIR_EN;
> 		}
> 		break;
>@@ -1202,6 +1205,34 @@ static int ice_dpll_sma_direction_set(struct
>ice_dpll_pin *p,
> 		ret = ice_dpll_pin_state_update(p->pf, p,
> 						ICE_DPLL_PIN_TYPE_SOFTWARE,
> 						extack);
>+	if (ret)
>+		return ret;
>+
>+	/* When a direction change activates the paired U.FL pin, enable
>+	 * its backing CGU pin so the pin reports as connected. Without
>+	 * this the U.FL routing is correct but the CGU pin stays disabled
>+	 * and userspace sees the pin as disconnected.  Do not disable the
>+	 * backing pin when U.FL becomes inactive because the SMA pin may
>+	 * still be using it.
>+	 */
>+	peer = &d->ufl[p->idx];
>+	if (peer->active) {
>+		struct ice_dpll_pin *target;
>+		enum ice_dpll_pin_type type;
>+
>+		if (peer->output) {
>+			target = peer->output;
>+			type = ICE_DPLL_PIN_TYPE_OUTPUT;
>+		} else {
>+			target = peer->input;
>+			type = ICE_DPLL_PIN_TYPE_INPUT;
>+		}
>+		ret = ice_dpll_pin_enable(&p->pf->hw, target,
>+					  d->eec.dpll_idx, type, extack);
>+		if (!ret)
>+			ret = ice_dpll_pin_state_update(p->pf, target,
>+							type, extack);
>+	}
>
> 	return ret;
> }
>@@ -1253,6 +1284,14 @@ ice_dpll_ufl_pin_state_set(const struct dpll_pin
>*pin, void *pin_priv,
> 			data &= ~ICE_SMA1_MASK;
> 			enable = true;
> 		} else if (state == DPLL_PIN_STATE_DISCONNECTED) {
>+			/* Skip if U.FL1 is not active, setting TX_EN
>+			 * while DIR_EN is set would also deactivate
>+			 * the paired SMA1 output.
>+			 */
>+			if (data & (ICE_SMA1_DIR_EN | ICE_SMA1_TX_EN)) {
>+				ret = 0;
>+				goto unlock;
>+			}
> 			data |= ICE_SMA1_TX_EN;
> 			enable = false;
> 		} else {
>@@ -1267,6 +1306,15 @@ ice_dpll_ufl_pin_state_set(const struct dpll_pin
>*pin, void *pin_priv,
> 			data &= ~ICE_SMA2_UFL2_RX_DIS;
> 			enable = true;
> 		} else if (state == DPLL_PIN_STATE_DISCONNECTED) {
>+			/* Skip if U.FL2 is not active, setting
>+			 * UFL2_RX_DIS could also disable the paired
>+			 * SMA2 input.
>+			 */
>+			if (!(data & ICE_SMA2_DIR_EN) ||
>+			    (data & ICE_SMA2_UFL2_RX_DIS)) {
>+				ret = 0;
>+				goto unlock;
>+			}
> 			data |= ICE_SMA2_UFL2_RX_DIS;
> 			enable = false;
> 		} else {
>--
>2.52.0


^ permalink raw reply

* RE: [PATCH net] ice: fix missing SMA pin initialization in DPLL subsystem
From: Kubalewski, Arkadiusz @ 2026-04-27 14:14 UTC (permalink / raw)
  To: Oros, Petr, netdev@vger.kernel.org
  Cc: Vecera, Ivan, Oros, Petr, Nguyen, Anthony L, Kitszel, Przemyslaw,
	Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, intel-wired-lan@lists.osuosl.org,
	linux-kernel@vger.kernel.org
In-Reply-To: <20260213141651.2231124-1-poros@redhat.com>

>From: Petr Oros <poros@redhat.com>
>Sent: Friday, February 13, 2026 3:17 PM
>
>The DPLL SMA/U.FL pin redesign introduced ice_dpll_sw_pin_frequency_get()
>which gates frequency reporting on the pin's active flag. This flag is
>determined by ice_dpll_sw_pins_update() from the PCA9575 GPIO expander
>state. Before the redesign, SMA pins were exposed as direct HW
>input/output pins and ice_dpll_frequency_get() returned the CGU
>frequency unconditionally — the PCA9575 state was never consulted.
>
>The PCA9575 powers on with all outputs high, setting ICE_SMA1_DIR_EN,
>ICE_SMA1_TX_EN, ICE_SMA2_DIR_EN and ICE_SMA2_TX_EN. Nothing in the
>driver writes the register during initialization, so
>ice_dpll_sw_pins_update() sees all pins as inactive and
>ice_dpll_sw_pin_frequency_get() permanently returns 0 Hz for every
>SW pin.
>
>Fix this by writing a default SMA configuration in
>ice_dpll_init_info_sw_pins(): clear all SMA bits, then set SMA1 and
>SMA2 as active inputs (DIR_EN=0) with U.FL1 output and U.FL2 input
>disabled. Each SMA/U.FL pair shares a physical signal path so only
>one pin per pair can be active at a time. U.FL pins still report
>frequency 0 after this fix: U.FL1 (output-only) is disabled by
>ICE_SMA1_TX_EN which keeps the TX output buffer off, and U.FL2
>(input-only) is disabled by ICE_SMA2_UFL2_RX_DIS. They can be
>activated by changing the corresponding SMA pin direction via dpll
>netlink.
>
>Fixes: 2dd5d03c77e2 ("ice: redesign dpll sma/u.fl pins control")


LGTM,

Reviewed-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>

>Signed-off-by: Petr Oros <poros@redhat.com>
>---
> drivers/net/ethernet/intel/ice/ice_dpll.c | 17 +++++++++++++++++
> 1 file changed, 17 insertions(+)
>
>diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c
>b/drivers/net/ethernet/intel/ice/ice_dpll.c
>index 53b54e395a2ed8..c2ad39bfe177db 100644
>--- a/drivers/net/ethernet/intel/ice/ice_dpll.c
>+++ b/drivers/net/ethernet/intel/ice/ice_dpll.c
>@@ -3545,6 +3545,7 @@ static int ice_dpll_init_info_sw_pins(struct ice_pf
>*pf)
> 	struct ice_dpll_pin *pin;
> 	u32 phase_adj_max, caps;
> 	int i, ret;
>+	u8 data;
>
> 	if (pf->hw.device_id == ICE_DEV_ID_E810C_QSFP)
> 		input_idx_offset = ICE_E810_RCLK_PINS_NUM;
>@@ -3604,6 +3605,22 @@ static int ice_dpll_init_info_sw_pins(struct ice_pf
>*pf)
> 		}
> 		ice_dpll_phase_range_set(&pin->prop.phase_range,
>phase_adj_max);
> 	}
>+
>+	/* Initialize the SMA control register to a known-good default
>state.
>+	 * Without this write the PCA9575 GPIO expander retains its power-on
>+	 * default (all outputs high) which makes all SW pins appear
>inactive.
>+	 * Set SMA1 and SMA2 as active inputs, disable U.FL1 output and
>+	 * U.FL2 input.
>+	 */
>+	ret = ice_read_sma_ctrl(&pf->hw, &data);
>+	if (ret)
>+		return ret;
>+	data &= ~ICE_ALL_SMA_MASK;
>+	data |= ICE_SMA1_TX_EN | ICE_SMA2_TX_EN | ICE_SMA2_UFL2_RX_DIS;
>+	ret = ice_write_sma_ctrl(&pf->hw, data);
>+	if (ret)
>+		return ret;
>+
> 	ret = ice_dpll_pin_state_update(pf, pin, ICE_DPLL_PIN_TYPE_SOFTWARE,
> 					NULL);
> 	if (ret)
>--
>2.52.0


^ permalink raw reply

* Re: [PATCH v2 2/2] pinctrl: qcom: add the TLMM driver for the Nord platforms
From: Bjorn Andersson @ 2026-04-27 14:17 UTC (permalink / raw)
  To: Bartosz Golaszewski
  Cc: Linus Walleij, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Richard Cochran, Bartosz Golaszewski, Shawn Guo, Arnd Bergmann,
	Dmitry Baryshkov, linux-arm-msm, linux-gpio, devicetree,
	linux-kernel, netdev
In-Reply-To: <20260427-nord-tlmm-v2-2-ade8e0f3d803@oss.qualcomm.com>

On Mon, Apr 27, 2026 at 04:00:30PM +0200, Bartosz Golaszewski wrote:
> diff --git a/drivers/pinctrl/qcom/pinctrl-nord.c b/drivers/pinctrl/qcom/pinctrl-nord.c
[..]
> +enum nord_functions {
> +	msm_mux_gpio,
> +	msm_mux_aoss_cti,
> +	msm_mux_atest_char0,
> +	msm_mux_atest_char1,
> +	msm_mux_atest_char2,
> +	msm_mux_atest_char3,
> +	msm_mux_atest_char_start,
> +	msm_mux_atest_usb20,
> +	msm_mux_atest_usb21,
> +	msm_mux_aud_intfc0_clk,
> +	msm_mux_aud_intfc0_data0,
> +	msm_mux_aud_intfc0_data1,
> +	msm_mux_aud_intfc0_data2,
> +	msm_mux_aud_intfc0_data3,
> +	msm_mux_aud_intfc0_data4,
> +	msm_mux_aud_intfc0_data5,
> +	msm_mux_aud_intfc0_data6,
> +	msm_mux_aud_intfc0_data7,
> +	msm_mux_aud_intfc0_ws,
> +	msm_mux_aud_intfc10_clk,
> +	msm_mux_aud_intfc10_data0,
> +	msm_mux_aud_intfc10_data1,
> +	msm_mux_aud_intfc10_ws,
> +	msm_mux_aud_intfc1_clk,
> +	msm_mux_aud_intfc1_data0,
> +	msm_mux_aud_intfc1_data1,
> +	msm_mux_aud_intfc1_data2,
> +	msm_mux_aud_intfc1_data3,
> +	msm_mux_aud_intfc1_data4,
> +	msm_mux_aud_intfc1_data5,
> +	msm_mux_aud_intfc1_data6,
> +	msm_mux_aud_intfc1_data7,

Is there any reason to keep these 8 "data" lanes as separate pingroups?

> +	msm_mux_aud_intfc1_ws,
> +	msm_mux_aud_intfc2_clk,
> +	msm_mux_aud_intfc2_data0,
> +	msm_mux_aud_intfc2_data1,
> +	msm_mux_aud_intfc2_data2,
> +	msm_mux_aud_intfc2_data3,
> +	msm_mux_aud_intfc2_ws,
> +	msm_mux_aud_intfc3_clk,
> +	msm_mux_aud_intfc3_data0,
> +	msm_mux_aud_intfc3_data1,
> +	msm_mux_aud_intfc3_ws,
> +	msm_mux_aud_intfc4_clk,
> +	msm_mux_aud_intfc4_data0,
> +	msm_mux_aud_intfc4_data1,
> +	msm_mux_aud_intfc4_ws,
> +	msm_mux_aud_intfc5_clk,
> +	msm_mux_aud_intfc5_data0,
> +	msm_mux_aud_intfc5_data1,
> +	msm_mux_aud_intfc5_ws,
> +	msm_mux_aud_intfc6_clk,
> +	msm_mux_aud_intfc6_data0,
> +	msm_mux_aud_intfc6_data1,
> +	msm_mux_aud_intfc6_ws,
> +	msm_mux_aud_intfc7_clk,
> +	msm_mux_aud_intfc7_data0,
> +	msm_mux_aud_intfc7_data1,
> +	msm_mux_aud_intfc7_ws,
> +	msm_mux_aud_intfc8_clk,
> +	msm_mux_aud_intfc8_data0,
> +	msm_mux_aud_intfc8_data1,
> +	msm_mux_aud_intfc8_ws,
> +	msm_mux_aud_intfc9_clk,
> +	msm_mux_aud_intfc9_data0,
> +	msm_mux_aud_intfc9_ws,
> +	msm_mux_aud_mclk0_mira,
> +	msm_mux_aud_mclk0_mirb,
> +	msm_mux_aud_mclk1_mira,
> +	msm_mux_aud_mclk1_mirb,
> +	msm_mux_aud_mclk2_mira,
> +	msm_mux_aud_mclk2_mirb,
> +	msm_mux_aud_refclk0,
> +	msm_mux_aud_refclk1,
> +	msm_mux_bist_done,
> +	msm_mux_ccu_async_in0,
> +	msm_mux_ccu_async_in1,
> +	msm_mux_ccu_async_in2,
> +	msm_mux_ccu_async_in3,
> +	msm_mux_ccu_async_in4,
> +	msm_mux_ccu_async_in5,
> +	msm_mux_ccu_i2c_scl0,

If you combine scl and sda, you don't force the DT author to split the
state.

> +	msm_mux_ccu_i2c_scl1,
> +	msm_mux_ccu_i2c_scl2,
> +	msm_mux_ccu_i2c_scl3,
> +	msm_mux_ccu_i2c_scl4,
> +	msm_mux_ccu_i2c_scl5,
> +	msm_mux_ccu_i2c_scl6,
> +	msm_mux_ccu_i2c_scl7,
> +	msm_mux_ccu_i2c_scl8,
> +	msm_mux_ccu_i2c_scl9,
> +	msm_mux_ccu_i2c_sda0,
> +	msm_mux_ccu_i2c_sda1,
> +	msm_mux_ccu_i2c_sda2,
> +	msm_mux_ccu_i2c_sda3,
> +	msm_mux_ccu_i2c_sda4,
> +	msm_mux_ccu_i2c_sda5,
> +	msm_mux_ccu_i2c_sda6,
> +	msm_mux_ccu_i2c_sda7,
> +	msm_mux_ccu_i2c_sda8,
> +	msm_mux_ccu_i2c_sda9,
> +	msm_mux_ccu_timer0,
> +	msm_mux_ccu_timer1,
> +	msm_mux_ccu_timer10,
> +	msm_mux_ccu_timer11,
> +	msm_mux_ccu_timer12,
> +	msm_mux_ccu_timer13,
> +	msm_mux_ccu_timer14,
> +	msm_mux_ccu_timer15,
> +	msm_mux_ccu_timer2,
> +	msm_mux_ccu_timer3,
> +	msm_mux_ccu_timer4,
> +	msm_mux_ccu_timer5,
> +	msm_mux_ccu_timer6,
> +	msm_mux_ccu_timer7,
> +	msm_mux_ccu_timer8,
> +	msm_mux_ccu_timer9,
> +	msm_mux_clink_debug,
> +	msm_mux_dbg_out,
> +	msm_mux_dbg_out_clk,
> +	msm_mux_ddr_bist_complete,
> +	msm_mux_ddr_bist_fail,
> +	msm_mux_ddr_bist_start,
> +	msm_mux_ddr_bist_stop,
> +	msm_mux_ddr_pxi0,
> +	msm_mux_ddr_pxi1,
> +	msm_mux_ddr_pxi10,
> +	msm_mux_ddr_pxi11,
> +	msm_mux_ddr_pxi12,
> +	msm_mux_ddr_pxi13,
> +	msm_mux_ddr_pxi14,
> +	msm_mux_ddr_pxi15,
> +	msm_mux_ddr_pxi2,
> +	msm_mux_ddr_pxi3,
> +	msm_mux_ddr_pxi4,
> +	msm_mux_ddr_pxi5,
> +	msm_mux_ddr_pxi6,
> +	msm_mux_ddr_pxi7,
> +	msm_mux_ddr_pxi8,
> +	msm_mux_ddr_pxi9,

These can be a single group. Perhaps all the ddr_* is a single group?

> +	msm_mux_dp_rx0,
> +	msm_mux_dp_rx00,
> +	msm_mux_dp_rx01,
> +	msm_mux_dp_rx0_mute,
> +	msm_mux_dp_rx1,
> +	msm_mux_dp_rx10,
> +	msm_mux_dp_rx11,
> +	msm_mux_dp_rx1_mute,
> +	msm_mux_edp0_hot,
> +	msm_mux_edp0_lcd,
> +	msm_mux_edp1_hot,
> +	msm_mux_edp1_lcd,
> +	msm_mux_edp2_hot,
> +	msm_mux_edp2_lcd,
> +	msm_mux_edp3_hot,
> +	msm_mux_edp3_lcd,
> +	msm_mux_emac0_mcg0,
> +	msm_mux_emac0_mcg1,
> +	msm_mux_emac0_mcg2,
> +	msm_mux_emac0_mcg3,

Single group?

> +	msm_mux_emac0_mdc,
> +	msm_mux_emac0_mdio,
> +	msm_mux_emac0_ptp,
> +	msm_mux_emac1_mcg0,
> +	msm_mux_emac1_mcg1,
> +	msm_mux_emac1_mcg2,
> +	msm_mux_emac1_mcg3,
> +	msm_mux_emac1_mdc,
> +	msm_mux_emac1_mdio,
> +	msm_mux_emac1_ptp,
> +	msm_mux_gcc_gp1_clk,
> +	msm_mux_gcc_gp2_clk,
> +	msm_mux_gcc_gp3_clk,
> +	msm_mux_gcc_gp4_clk,
> +	msm_mux_gcc_gp5_clk,
> +	msm_mux_gcc_gp6_clk,
> +	msm_mux_gcc_gp7_clk,
> +	msm_mux_gcc_gp8_clk,
> +	msm_mux_jitter_bist,
> +	msm_mux_lbist_pass,
> +	msm_mux_mbist_pass,
> +	msm_mux_mdp0_vsync0_out,
> +	msm_mux_mdp0_vsync10_out,
> +	msm_mux_mdp0_vsync1_out,
> +	msm_mux_mdp0_vsync2_out,
> +	msm_mux_mdp0_vsync3_out,
> +	msm_mux_mdp0_vsync4_out,
> +	msm_mux_mdp0_vsync5_out,
> +	msm_mux_mdp0_vsync6_out,
> +	msm_mux_mdp0_vsync7_out,
> +	msm_mux_mdp0_vsync8_out,
> +	msm_mux_mdp0_vsync9_out,
> +	msm_mux_mdp1_vsync0_out,
> +	msm_mux_mdp1_vsync10_out,
> +	msm_mux_mdp1_vsync1_out,
> +	msm_mux_mdp1_vsync2_out,
> +	msm_mux_mdp1_vsync3_out,
> +	msm_mux_mdp1_vsync4_out,
> +	msm_mux_mdp1_vsync5_out,
> +	msm_mux_mdp1_vsync6_out,
> +	msm_mux_mdp1_vsync7_out,
> +	msm_mux_mdp1_vsync8_out,
> +	msm_mux_mdp1_vsync9_out,
> +	msm_mux_mdp_vsync_e,
> +	msm_mux_mdp_vsync_p,
> +	msm_mux_mdp_vsync_s,
> +	msm_mux_pcie0_clk_req_n,
> +	msm_mux_pcie1_clk_req_n,
> +	msm_mux_pcie2_clk_req_n,
> +	msm_mux_pcie3_clk_req_n,
> +	msm_mux_phase_flag0,
> +	msm_mux_phase_flag1,
> +	msm_mux_phase_flag10,
> +	msm_mux_phase_flag11,
> +	msm_mux_phase_flag12,
> +	msm_mux_phase_flag13,
> +	msm_mux_phase_flag14,
> +	msm_mux_phase_flag15,
> +	msm_mux_phase_flag16,
> +	msm_mux_phase_flag17,
> +	msm_mux_phase_flag18,
> +	msm_mux_phase_flag19,
> +	msm_mux_phase_flag2,
> +	msm_mux_phase_flag20,
> +	msm_mux_phase_flag21,
> +	msm_mux_phase_flag22,
> +	msm_mux_phase_flag23,
> +	msm_mux_phase_flag24,
> +	msm_mux_phase_flag25,
> +	msm_mux_phase_flag26,
> +	msm_mux_phase_flag27,
> +	msm_mux_phase_flag28,
> +	msm_mux_phase_flag29,
> +	msm_mux_phase_flag3,
> +	msm_mux_phase_flag30,
> +	msm_mux_phase_flag31,
> +	msm_mux_phase_flag4,
> +	msm_mux_phase_flag5,
> +	msm_mux_phase_flag6,
> +	msm_mux_phase_flag7,
> +	msm_mux_phase_flag8,
> +	msm_mux_phase_flag9,

Single group.

> +	msm_mux_pll_bist_sync,
> +	msm_mux_pll_clk_aux,
> +	msm_mux_prng_rosc0,
> +	msm_mux_prng_rosc1,
> +	msm_mux_pwrbrk_i_n,
> +	msm_mux_qdss_cti,
> +	msm_mux_qdss_gpio,
> +	msm_mux_qdss_gpio0,
> +	msm_mux_qdss_gpio1,
> +	msm_mux_qdss_gpio10,
> +	msm_mux_qdss_gpio11,
> +	msm_mux_qdss_gpio12,
> +	msm_mux_qdss_gpio13,
> +	msm_mux_qdss_gpio14,
> +	msm_mux_qdss_gpio15,
> +	msm_mux_qdss_gpio2,
> +	msm_mux_qdss_gpio3,
> +	msm_mux_qdss_gpio4,
> +	msm_mux_qdss_gpio5,
> +	msm_mux_qdss_gpio6,
> +	msm_mux_qdss_gpio7,
> +	msm_mux_qdss_gpio8,
> +	msm_mux_qdss_gpio9,

Single group. Perhaps even single "qdss" group?

> +	msm_mux_qspi0,
> +	msm_mux_qspi1,
> +	msm_mux_qspi2,
> +	msm_mux_qspi3,

Single group.

> +	msm_mux_qspi_clk,
> +	msm_mux_qspi_cs0_n,
> +	msm_mux_qspi_cs1_n,
> +	msm_mux_qup0_se0,
> +	msm_mux_qup0_se1,
> +	msm_mux_qup0_se2,
> +	msm_mux_qup0_se3,
> +	msm_mux_qup0_se4,
> +	msm_mux_qup0_se5,
> +	msm_mux_qup1_se0,
> +	msm_mux_qup1_se1,
> +	msm_mux_qup1_se2,
> +	msm_mux_qup1_se3,
> +	msm_mux_qup1_se4,
> +	msm_mux_qup1_se5,
> +	msm_mux_qup1_se6,
> +	msm_mux_qup2_se0,
> +	msm_mux_qup2_se1,
> +	msm_mux_qup2_se2,
> +	msm_mux_qup2_se3,
> +	msm_mux_qup2_se4,
> +	msm_mux_qup2_se5,
> +	msm_mux_qup2_se6,
> +	msm_mux_qup3_se0_mira,
> +	msm_mux_qup3_se0_mirb,

Nice, that's clean.

Regards,
Bjorn

^ permalink raw reply

* Re: [PATCH v2 2/2] pinctrl: qcom: add the TLMM driver for the Nord platforms
From: Bartosz Golaszewski @ 2026-04-27 14:19 UTC (permalink / raw)
  To: Bjorn Andersson
  Cc: Bartosz Golaszewski, Linus Walleij, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Richard Cochran, Shawn Guo,
	Arnd Bergmann, Dmitry Baryshkov, linux-arm-msm, linux-gpio,
	devicetree, linux-kernel, netdev
In-Reply-To: <ae9usgOf-KtgEJ4q@baldur>

On Mon, Apr 27, 2026 at 4:17 PM Bjorn Andersson <andersson@kernel.org> wrote:
>
> On Mon, Apr 27, 2026 at 04:00:30PM +0200, Bartosz Golaszewski wrote:
> > diff --git a/drivers/pinctrl/qcom/pinctrl-nord.c b/drivers/pinctrl/qcom/pinctrl-nord.c
> [..]
> > +enum nord_functions {
> > +     msm_mux_gpio,
> > +     msm_mux_aoss_cti,
> > +     msm_mux_atest_char0,
> > +     msm_mux_atest_char1,
> > +     msm_mux_atest_char2,
> > +     msm_mux_atest_char3,
> > +     msm_mux_atest_char_start,
> > +     msm_mux_atest_usb20,
> > +     msm_mux_atest_usb21,
> > +     msm_mux_aud_intfc0_clk,
> > +     msm_mux_aud_intfc0_data0,
> > +     msm_mux_aud_intfc0_data1,
> > +     msm_mux_aud_intfc0_data2,
> > +     msm_mux_aud_intfc0_data3,
> > +     msm_mux_aud_intfc0_data4,
> > +     msm_mux_aud_intfc0_data5,
> > +     msm_mux_aud_intfc0_data6,
> > +     msm_mux_aud_intfc0_data7,
> > +     msm_mux_aud_intfc0_ws,
> > +     msm_mux_aud_intfc10_clk,
> > +     msm_mux_aud_intfc10_data0,
> > +     msm_mux_aud_intfc10_data1,
> > +     msm_mux_aud_intfc10_ws,
> > +     msm_mux_aud_intfc1_clk,
> > +     msm_mux_aud_intfc1_data0,
> > +     msm_mux_aud_intfc1_data1,
> > +     msm_mux_aud_intfc1_data2,
> > +     msm_mux_aud_intfc1_data3,
> > +     msm_mux_aud_intfc1_data4,
> > +     msm_mux_aud_intfc1_data5,
> > +     msm_mux_aud_intfc1_data6,
> > +     msm_mux_aud_intfc1_data7,
>
> Is there any reason to keep these 8 "data" lanes as separate pingroups?
>

The answer here and elsewhere is: no. I just didn't have other states
in DTS to visualize the resulting nodes and it didn't occur to me to
update other functions as well. I'll do it in v3.

Bart

^ permalink raw reply

* Re: [PATCH net-next] net: enc28j60: use of_get_ethdev_address
From: Andrew Lunn @ 2026-04-27 14:19 UTC (permalink / raw)
  To: Rosen Penev
  Cc: netdev, Andrew Lunn, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, open list
In-Reply-To: <20260427052533.960487-1-rosenp@gmail.com>

On Sun, Apr 26, 2026 at 10:25:33PM -0700, Rosen Penev wrote:
> Since this is an OF only driver, of_ instead of device_ allows nvmem to
> be used to specify the MAC address.

Now that is usual, somebody converting device_ to of_. It is normally
the other way around, for not particularly good reasons. Nice.

> -	if (device_get_ethdev_address(&spi->dev, dev))
> +	ret = of_get_ethdev_address(spi->dev.of_node, dev);
> +	if (ret == -EPROBE_DEFER)
> +		return ret;

/**
 * device_get_mac_address - Get the MAC for a given device
 * @dev:	Pointer to the device
 * @addr:	Address of buffer to store the MAC in
 */
int device_get_mac_address(struct device *dev, char *addr)
{
	if (!fwnode_get_mac_address(dev_fwnode(dev), addr))
		return 0;

	return nvmem_get_mac_address(dev, addr);
}
EXPORT_SYMBOL(device_get_mac_address);

This appears to support nvmem. Would device_get_mac_address() actually
work? I'm not against swapping to of_get_ethdev_address, but the
commit message should be accurate.

   Andrew

^ permalink raw reply

* Re: [RFC Patch net-next v1 1/9] r8169: add some register definitions
From: Andrew Lunn @ 2026-04-27 14:22 UTC (permalink / raw)
  To: Javen
  Cc: Heiner Kallweit, nic_swsd@realtek.com, andrew+netdev@lunn.ch,
	davem@davemloft.net, edumazet@google.com, kuba@kernel.org,
	pabeni@redhat.com, horms@kernel.org, netdev@vger.kernel.org,
	linux-kernel@vger.kernel.org
In-Reply-To: <335ace172e20415ead8e56ae117b0fce@realsil.com.cn>

On Mon, Apr 27, 2026 at 06:41:22AM +0000, Javen wrote:
> >On 20.04.2026 04:19, javen wrote:
> >> From: Javen Xu <javen_xu@realsil.com.cn>
> >>
> >> To support rss, this patch adds some macro definitions and register
> >> definitions.
> >>
> >> Signed-off-by: Javen Xu <javen_xu@realsil.com.cn>
> >> ---
> >>  drivers/net/ethernet/realtek/r8169_main.c | 75
> >> +++++++++++++++++++++++
> >>  1 file changed, 75 insertions(+)
> >>
> >> diff --git a/drivers/net/ethernet/realtek/r8169_main.c
> >> b/drivers/net/ethernet/realtek/r8169_main.c
> >> index 791277e750ba..0fbec27e4a0d 100644
> >> --- a/drivers/net/ethernet/realtek/r8169_main.c
> >> +++ b/drivers/net/ethernet/realtek/r8169_main.c
> >> @@ -77,6 +77,23 @@
> >>  #define R8169_RX_RING_BYTES  (NUM_RX_DESC * sizeof(struct RxDesc))
> >>  #define R8169_TX_STOP_THRS   (MAX_SKB_FRAGS + 1)
> >>  #define R8169_TX_START_THRS  (2 * R8169_TX_STOP_THRS)
> >> +#define R8169_MAX_RX_QUEUES  8
> >> +#define R8169_MAX_TX_QUEUES  1
> >> +#define R8169_MAX_MSIX_VEC   32
> >> +#define R8127_MAX_TX_QUEUES  1
> >
> >Then why multi tx queue support?
> >
> >> +#define R8127_MAX_RX_QUEUES  8
> >> +#define R8127_MAX_IRQ                32
> >> +#define R8127_MIN_IRQ                30
> >
> >This isn't self-explanatory. What do min and max refer to here?
> 
> The hardware actually reserves a 64-bit interrupt status space for the new mapping in RTL8127. Although I don't think it is reasonable, its hardware design.
> - Vector 0-7 (from reg 0x0d04): Rx queues
> - Vector 8-15 (from reg 0x0d04): Tx queues
> - Vector 29 (from reg 0x0d06): Link Status Change (LSC)
> As the Link Status Change interrupt is fixed at vector index 29, we are forced to request a minimum of 30 MSI-X vectors from the PCI core.


Thanks for the explanation. Now please try to explain that in code, so
developers can understand what the driver is doing and why.

	Andrew

^ permalink raw reply

* [PATCH v3 0/3] wireless: p54 devicetree conversion
From: Arnd Bergmann @ 2026-04-27 14:23 UTC (permalink / raw)
  Cc: Arnd Bergmann, Aaro Koskinen, Andreas Kemnade,
	Bartosz Golaszewski, Benoît Cousson, David S. Miller,
	Dmitry Torokhov, Eric Dumazet, Felipe Balbi, Jakub Kicinski,
	Johannes Berg, Kevin Hilman, Krzysztof Kozlowski, Linus Walleij,
	Paolo Abeni, Rob Herring, Roger Quadros, Tony Lindgren,
	linux-wireless, netdev, devicetree, linux-kernel,
	linux-arm-kernel, linux-gpio, linux-omap

From: Arnd Bergmann <arnd@arndb.de>

This is an older patch of mine that I lost track of. We already decided
a while ago that the OMAP2 platform should probably be removed entirely,
and this is the only known user, but it's probably a good idea to still
get the driver changes in, in case there are other out-of-tree users.

We probably don't have to worry about bisectability any more though,
so the devicetree and driver changes can just get merged independently
through the OMAP and wireless trees, respectively.

     Arnd

v2 Link: https://lore.kernel.org/all/20230404082401.1087835-1-arnd@kernel.org/

Cc: "Aaro Koskinen" <aaro.koskinen@iki.fi>
Cc: "Andreas Kemnade" <andreas@kemnade.info>
Cc: "Arnd Bergmann" <arnd@arndb.de>
Cc: "Bartosz Golaszewski" <brgl@kernel.org>
Cc: "Benoît Cousson" <bcousson@baylibre.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: "Dmitry Torokhov" <dmitry.torokhov@gmail.com>
Cc: "Eric Dumazet" <edumazet@google.com>
Cc: "Felipe Balbi" <balbi@kernel.org>
Cc: "Jakub Kicinski" <kuba@kernel.org>
Cc: "Johannes Berg" <johannes@sipsolutions.net>
Cc: "Kevin Hilman" <khilman@baylibre.com>
Cc: "Krzysztof Kozlowski" <krzk+dt@kernel.org>
Cc: "Linus Walleij" <linusw@kernel.org>
Cc: "Paolo Abeni" <pabeni@redhat.com>
Cc: "Rob Herring" <robh+dt@kernel.org>
Cc: "Roger Quadros" <rogerq@kernel.org>
Cc: "Tony Lindgren" <tony@atomide.com>
Cc: linux-wireless@vger.kernel.org
Cc: netdev@vger.kernel.org
Cc: devicetree@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-gpio@vger.kernel.org
Cc: linux-omap@vger.kernel.org


Arnd Bergmann (3):
  dt-bindings: net: add st,stlc45xx/p54spi binding
  ARM: dts: omap2: add stlc4560 spi-wireless node
  p54spi: convert to devicetree

 .../bindings/net/wireless/st,stlc45xx.yaml    | 58 ++++++++++++++++
 MAINTAINERS                                   |  1 +
 arch/arm/boot/dts/ti/omap/omap2.dtsi          |  4 ++
 .../dts/ti/omap/omap2420-n8x0-common.dtsi     | 12 ++++
 arch/arm/mach-omap2/board-n8x0.c              | 18 -----
 drivers/net/wireless/intersil/p54/p54spi.c    | 68 +++++++------------
 drivers/net/wireless/intersil/p54/p54spi.h    |  3 +
 7 files changed, 103 insertions(+), 61 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/net/wireless/st,stlc45xx.yaml

-- 
2.39.5


^ permalink raw reply

* [PATCH v3 1/3] dt-bindings: net: add st,stlc45xx/p54spi binding
From: Arnd Bergmann @ 2026-04-27 14:23 UTC (permalink / raw)
  Cc: Arnd Bergmann, Aaro Koskinen, Andreas Kemnade,
	Bartosz Golaszewski, Benoît Cousson, David S. Miller,
	Dmitry Torokhov, Eric Dumazet, Felipe Balbi, Jakub Kicinski,
	Johannes Berg, Kevin Hilman, Krzysztof Kozlowski, Linus Walleij,
	Paolo Abeni, Rob Herring, Roger Quadros, Tony Lindgren,
	linux-wireless, netdev, devicetree, linux-kernel,
	linux-arm-kernel, linux-gpio, linux-omap, Christian Lamparter
In-Reply-To: <20260427142355.2532714-1-arnd@kernel.org>

From: Arnd Bergmann <arnd@arndb.de>

The SPI version of Prism54 was sold under a couple of different
names and supported by the Linux p54spi driver, but there was
never a DT binding for it.

Document the four known names of this device and the properties
that are sufficient for its use on the Nokia N8x0 tablet.

As I don't have this hardware or documentation for it, this is
purely based on existing usage in the driver.

Link: https://lore.kernel.org/all/e8dc9acb-6f85-e0a9-a145-d101ca6da201@gmail.com/
Acked-by: Christian Lamparter <chunkeey@gmail.com>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 .../bindings/net/wireless/st,stlc45xx.yaml    | 58 +++++++++++++++++++
 MAINTAINERS                                   |  1 +
 2 files changed, 59 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/net/wireless/st,stlc45xx.yaml

diff --git a/Documentation/devicetree/bindings/net/wireless/st,stlc45xx.yaml b/Documentation/devicetree/bindings/net/wireless/st,stlc45xx.yaml
new file mode 100644
index 000000000000..12d907720ec4
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/wireless/st,stlc45xx.yaml
@@ -0,0 +1,58 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/net/wireless/st,stlc45xx.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: ST/Intersil/Conexant stlc45xx/p54spi/cx3110x SPI wireless device
+
+maintainers:
+  - Christian Lamparter <chunkeey@gmail.com>
+
+description:
+  The SPI variant of the Intersil Prism54 wireless device was sold
+  under a variety of names, including Conexant CX3110x and
+  ST Microelectronics STLC5460.
+
+allOf:
+  - $ref: ieee80211.yaml#
+  - $ref: /schemas/spi/spi-peripheral-props.yaml#
+
+properties:
+  compatible:
+    enum:
+      - cnxt,3110x
+      - isil,p54spi
+      - st,stlc4550
+      - st,stlc4560
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  powerdown-gpios:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    spi {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        wifi@0 {
+            compatible = "st,stlc4560";
+            reg = <0>;
+            spi-max-frequency = <48000000>;
+            interrupts-extended = <&gpio 23>;
+            powerdown-gpios = <&gpio 1>;
+        };
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index 84afd29c9b1b..deacfc4e244d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -20098,6 +20098,7 @@ M:	Christian Lamparter <chunkeey@googlemail.com>
 L:	linux-wireless@vger.kernel.org
 S:	Maintained
 W:	https://wireless.wiki.kernel.org/en/users/Drivers/p54
+F:	Documentation/devicetree/bindings/net/wireless/st,stlc45xx.yaml
 F:	drivers/net/wireless/intersil/
 
 PACKET SOCKETS
-- 
2.39.5


^ permalink raw reply related

* [PATCH v3 2/3] ARM: dts: omap2: add stlc4560 spi-wireless node
From: Arnd Bergmann @ 2026-04-27 14:23 UTC (permalink / raw)
  Cc: Arnd Bergmann, Aaro Koskinen, Andreas Kemnade,
	Bartosz Golaszewski, Benoît Cousson, David S. Miller,
	Dmitry Torokhov, Eric Dumazet, Felipe Balbi, Jakub Kicinski,
	Johannes Berg, Kevin Hilman, Krzysztof Kozlowski, Linus Walleij,
	Paolo Abeni, Rob Herring, Roger Quadros, Tony Lindgren,
	linux-wireless, netdev, devicetree, linux-kernel,
	linux-arm-kernel, linux-gpio, linux-omap, Krzysztof Kozlowski
In-Reply-To: <20260427142355.2532714-1-arnd@kernel.org>

From: Arnd Bergmann <arnd@arndb.de>

Converted from the platform_device creation in board-n8x0.c.

Link: https://lore.kernel.org/all/20230314163201.955689-1-arnd@kernel.org/
Reviewed-by: Krzysztof Kozlowski <krzk@kernel.org>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 arch/arm/boot/dts/ti/omap/omap2.dtsi                |  4 ++++
 arch/arm/boot/dts/ti/omap/omap2420-n8x0-common.dtsi | 12 ++++++++++++
 2 files changed, 16 insertions(+)

diff --git a/arch/arm/boot/dts/ti/omap/omap2.dtsi b/arch/arm/boot/dts/ti/omap/omap2.dtsi
index afabb36a8ac1..fdc1790adf43 100644
--- a/arch/arm/boot/dts/ti/omap/omap2.dtsi
+++ b/arch/arm/boot/dts/ti/omap/omap2.dtsi
@@ -129,6 +129,8 @@ i2c2: i2c@48072000 {
 		};
 
 		mcspi1: spi@48098000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
 			compatible = "ti,omap2-mcspi";
 			ti,hwmods = "mcspi1";
 			reg = <0x48098000 0x100>;
@@ -140,6 +142,8 @@ mcspi1: spi@48098000 {
 		};
 
 		mcspi2: spi@4809a000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
 			compatible = "ti,omap2-mcspi";
 			ti,hwmods = "mcspi2";
 			reg = <0x4809a000 0x100>;
diff --git a/arch/arm/boot/dts/ti/omap/omap2420-n8x0-common.dtsi b/arch/arm/boot/dts/ti/omap/omap2420-n8x0-common.dtsi
index 63b0b4921e4e..fe9dd8bbfc85 100644
--- a/arch/arm/boot/dts/ti/omap/omap2420-n8x0-common.dtsi
+++ b/arch/arm/boot/dts/ti/omap/omap2420-n8x0-common.dtsi
@@ -109,3 +109,15 @@ partition@5 {
 		};
 	};
 };
+
+&mcspi2 {
+	status = "okay";
+
+	wifi@0 {
+		reg = <0>;
+		compatible = "st,stlc4560";
+		spi-max-frequency = <48000000>;
+		interrupts-extended = <&gpio3 23 IRQ_TYPE_EDGE_RISING>;
+		powerdown-gpios = <&gpio4 1 GPIO_ACTIVE_LOW>; /* gpio 97 */
+	};
+};
-- 
2.39.5


^ permalink raw reply related

* [PATCH v3 3/3] p54spi: convert to devicetree
From: Arnd Bergmann @ 2026-04-27 14:23 UTC (permalink / raw)
  Cc: Arnd Bergmann, Aaro Koskinen, Andreas Kemnade,
	Bartosz Golaszewski, Benoît Cousson, David S. Miller,
	Dmitry Torokhov, Eric Dumazet, Felipe Balbi, Jakub Kicinski,
	Johannes Berg, Kevin Hilman, Krzysztof Kozlowski, Linus Walleij,
	Paolo Abeni, Rob Herring, Roger Quadros, Tony Lindgren,
	linux-wireless, netdev, devicetree, linux-kernel,
	linux-arm-kernel, linux-gpio, linux-omap, Christian Lamparter
In-Reply-To: <20260427142355.2532714-1-arnd@kernel.org>

From: Arnd Bergmann <arnd@arndb.de>

The Prism54 SPI driver hardcodes GPIO numbers and expects users to
pass them as module parameters, apparently a relic from its life as a
staging driver. This works because there is only one user, the Nokia
N8x0 tablet.

Convert this to the gpio descriptor interface and DT based probing
to improve this and simplify the code at the same time.

Acked-by: Christian Lamparter <chunkeey@gmail.com>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 arch/arm/mach-omap2/board-n8x0.c           | 18 ------
 drivers/net/wireless/intersil/p54/p54spi.c | 68 ++++++++--------------
 drivers/net/wireless/intersil/p54/p54spi.h |  3 +
 3 files changed, 28 insertions(+), 61 deletions(-)

diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c
index 969265d5d5c6..d9acd32c5457 100644
--- a/arch/arm/mach-omap2/board-n8x0.c
+++ b/arch/arm/mach-omap2/board-n8x0.c
@@ -20,7 +20,6 @@
 #include <linux/spi/spi.h>
 #include <linux/usb/musb.h>
 #include <linux/mmc/host.h>
-#include <linux/platform_data/spi-omap2-mcspi.h>
 #include <linux/platform_data/mmc-omap.h>
 #include <linux/mfd/menelaus.h>
 
@@ -106,21 +105,6 @@ static void __init n8x0_usb_init(void) {}
 
 #endif /*CONFIG_USB_MUSB_TUSB6010 */
 
-
-static struct omap2_mcspi_device_config p54spi_mcspi_config = {
-	.turbo_mode	= 0,
-};
-
-static struct spi_board_info n800_spi_board_info[] __initdata = {
-	{
-		.modalias	= "p54spi",
-		.bus_num	= 2,
-		.chip_select	= 0,
-		.max_speed_hz   = 48000000,
-		.controller_data = &p54spi_mcspi_config,
-	},
-};
-
 #if defined(CONFIG_MENELAUS) && IS_ENABLED(CONFIG_MMC_OMAP)
 
 /*
@@ -524,7 +508,5 @@ omap_late_initcall(n8x0_late_initcall);
 void * __init n8x0_legacy_init(void)
 {
 	board_check_revision();
-	spi_register_board_info(n800_spi_board_info,
-				ARRAY_SIZE(n800_spi_board_info));
 	return &mmc1_data;
 }
diff --git a/drivers/net/wireless/intersil/p54/p54spi.c b/drivers/net/wireless/intersil/p54/p54spi.c
index 9d66dcae54e0..1cda3b42b5d7 100644
--- a/drivers/net/wireless/intersil/p54/p54spi.c
+++ b/drivers/net/wireless/intersil/p54/p54spi.c
@@ -8,6 +8,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/mod_devicetable.h>
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
 #include <linux/firmware.h>
@@ -15,7 +16,7 @@
 #include <linux/irq.h>
 #include <linux/spi/spi.h>
 #include <linux/etherdevice.h>
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
 #include <linux/slab.h>
 
 #include "p54spi.h"
@@ -30,19 +31,6 @@
 MODULE_FIRMWARE("3826.arm");
 MODULE_FIRMWARE("3826.eeprom");
 
-/* gpios should be handled in board files and provided via platform data,
- * but because it's currently impossible for p54spi to have a header file
- * in include/linux, let's use module parameters for now
- */
-
-static int p54spi_gpio_power = 97;
-module_param(p54spi_gpio_power, int, 0444);
-MODULE_PARM_DESC(p54spi_gpio_power, "gpio number for power line");
-
-static int p54spi_gpio_irq = 87;
-module_param(p54spi_gpio_irq, int, 0444);
-MODULE_PARM_DESC(p54spi_gpio_irq, "gpio number for irq line");
-
 static void p54spi_spi_read(struct p54s_priv *priv, u8 address,
 			      void *buf, size_t len)
 {
@@ -262,14 +250,14 @@ static int p54spi_upload_firmware(struct ieee80211_hw *dev)
 
 static void p54spi_power_off(struct p54s_priv *priv)
 {
-	disable_irq(gpio_to_irq(p54spi_gpio_irq));
-	gpio_set_value(p54spi_gpio_power, 0);
+	disable_irq(priv->irq);
+	gpiod_set_value(priv->gpio_powerdown, 1);
 }
 
 static void p54spi_power_on(struct p54s_priv *priv)
 {
-	gpio_set_value(p54spi_gpio_power, 1);
-	enable_irq(gpio_to_irq(p54spi_gpio_irq));
+	gpiod_set_value(priv->gpio_powerdown, 0);
+	enable_irq(priv->irq);
 
 	/* need to wait a while before device can be accessed, the length
 	 * is just a guess
@@ -608,30 +596,19 @@ static int p54spi_probe(struct spi_device *spi)
 		goto err_free;
 	}
 
-	ret = gpio_request(p54spi_gpio_power, "p54spi power");
-	if (ret < 0) {
-		dev_err(&priv->spi->dev, "power GPIO request failed: %d", ret);
+	priv->gpio_powerdown = gpiod_get(&spi->dev, "powerdown", GPIOD_OUT_HIGH);
+	if (IS_ERR(priv->gpio_powerdown)) {
+		ret = PTR_ERR(priv->gpio_powerdown);
+		dev_err(&priv->spi->dev, "powerdown GPIO request failed: %d", ret);
 		goto err_free;
 	}
 
-	ret = gpio_request(p54spi_gpio_irq, "p54spi irq");
-	if (ret < 0) {
-		dev_err(&priv->spi->dev, "irq GPIO request failed: %d", ret);
-		goto err_free_gpio_power;
-	}
-
-	gpio_direction_output(p54spi_gpio_power, 0);
-	gpio_direction_input(p54spi_gpio_irq);
-
-	ret = request_irq(gpio_to_irq(p54spi_gpio_irq),
-			  p54spi_interrupt, IRQF_NO_AUTOEN, "p54spi",
-			  priv->spi);
+	ret = request_irq(spi->irq, p54spi_interrupt, IRQF_NO_AUTOEN, "p54spi", priv->spi);
 	if (ret < 0) {
 		dev_err(&priv->spi->dev, "request_irq() failed");
-		goto err_free_gpio_irq;
+		goto err_free_gpio_power;
 	}
 
-	irq_set_irq_type(gpio_to_irq(p54spi_gpio_irq), IRQ_TYPE_EDGE_RISING);
 
 	INIT_WORK(&priv->work, p54spi_work);
 	init_completion(&priv->fw_comp);
@@ -659,11 +636,9 @@ static int p54spi_probe(struct spi_device *spi)
 
 err_free_common:
 	release_firmware(priv->firmware);
-	free_irq(gpio_to_irq(p54spi_gpio_irq), spi);
-err_free_gpio_irq:
-	gpio_free(p54spi_gpio_irq);
+	free_irq(priv->irq, spi);
 err_free_gpio_power:
-	gpio_free(p54spi_gpio_power);
+	gpiod_put(priv->gpio_powerdown);
 err_free:
 	p54_free_common(priv->hw);
 	return ret;
@@ -675,10 +650,8 @@ static void p54spi_remove(struct spi_device *spi)
 
 	p54_unregister_common(priv->hw);
 
-	free_irq(gpio_to_irq(p54spi_gpio_irq), spi);
-
-	gpio_free(p54spi_gpio_power);
-	gpio_free(p54spi_gpio_irq);
+	free_irq(priv->irq, spi);
+	gpiod_put(priv->gpio_powerdown);
 	release_firmware(priv->firmware);
 
 	mutex_destroy(&priv->mutex);
@@ -686,10 +659,19 @@ static void p54spi_remove(struct spi_device *spi)
 	p54_free_common(priv->hw);
 }
 
+struct of_device_id p54spi_of_ids[] = {
+	{ .compatible = "cnxt,3110x", },
+	{ .compatible = "isil,p54spi", },
+	{ .compatible = "st,stlc4550", },
+	{ .compatible = "st,stlc4560", },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, p54spi_of_ids);
 
 static struct spi_driver p54spi_driver = {
 	.driver = {
 		.name		= "p54spi",
+		.of_match_table = p54spi_of_ids,
 	},
 
 	.probe		= p54spi_probe,
diff --git a/drivers/net/wireless/intersil/p54/p54spi.h b/drivers/net/wireless/intersil/p54/p54spi.h
index e5619a13fd61..118785cc635a 100644
--- a/drivers/net/wireless/intersil/p54/p54spi.h
+++ b/drivers/net/wireless/intersil/p54/p54spi.h
@@ -107,6 +107,9 @@ struct p54s_priv {
 
 	enum fw_state fw_state;
 	const struct firmware *firmware;
+
+	struct gpio_desc *gpio_powerdown;
+	int irq;
 };
 
 #endif /* P54SPI_H */
-- 
2.39.5


^ permalink raw reply related

* RE: [PATCH iwl-net v7 1/3] dpll: export __dpll_pin_change_ntf() for use under dpll_lock
From: Kubalewski, Arkadiusz @ 2026-04-27 14:27 UTC (permalink / raw)
  To: Oros, Petr, netdev@vger.kernel.org
  Cc: Vecera, Ivan, Vadim Fedorenko, Oros, Petr, Nguyen, Anthony L,
	Kitszel, Przemyslaw, Andrew Lunn, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Simon Horman, Jiri Pirko,
	Schmidt, Michal, Keller, Jacob E, Loktionov, Aleksandr,
	Rinitha, SX, intel-wired-lan@lists.osuosl.org,
	linux-kernel@vger.kernel.org
In-Reply-To: <20260417145907.696307-2-poros@redhat.com>

>From: Petr Oros <poros@redhat.com>
>Sent: Friday, April 17, 2026 4:59 PM
>
>From: Ivan Vecera <ivecera@redhat.com>
>
>Export __dpll_pin_change_ntf() so that drivers can send pin change
>notifications from within pin callbacks, which are already called
>under dpll_lock. Using dpll_pin_change_ntf() in that context would
>deadlock.
>
>Add lockdep_assert_held() to catch misuse without the lock held.
>
>Acked-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
>Signed-off-by: Ivan Vecera <ivecera@redhat.com>

LGTM,
Reviewed-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>

>Signed-off-by: Petr Oros <poros@redhat.com>
>---
> drivers/dpll/dpll_netlink.c | 10 ++++++++++
> drivers/dpll/dpll_netlink.h |  2 --
> include/linux/dpll.h        |  1 +
> 3 files changed, 11 insertions(+), 2 deletions(-)
>
>diff --git a/drivers/dpll/dpll_netlink.c b/drivers/dpll/dpll_netlink.c
>index af7ce62ec55ca8..0ff1658c2dc1ba 100644
>--- a/drivers/dpll/dpll_netlink.c
>+++ b/drivers/dpll/dpll_netlink.c
>@@ -900,11 +900,21 @@ int dpll_pin_delete_ntf(struct dpll_pin *pin)
> 	return dpll_pin_event_send(DPLL_CMD_PIN_DELETE_NTF, pin);
> }
>
>+/**
>+ * __dpll_pin_change_ntf - notify that the pin has been changed
>+ * @pin: registered pin pointer
>+ *
>+ * Context: caller must hold dpll_lock. Suitable for use inside pin
>+ *          callbacks which are already invoked under dpll_lock.
>+ * Return: 0 if succeeds, error code otherwise.
>+ */
> int __dpll_pin_change_ntf(struct dpll_pin *pin)
> {
>+	lockdep_assert_held(&dpll_lock);
> 	dpll_pin_notify(pin, DPLL_PIN_CHANGED);
> 	return dpll_pin_event_send(DPLL_CMD_PIN_CHANGE_NTF, pin);
> }
>+EXPORT_SYMBOL_GPL(__dpll_pin_change_ntf);
>
> /**
>  * dpll_pin_change_ntf - notify that the pin has been changed
>diff --git a/drivers/dpll/dpll_netlink.h b/drivers/dpll/dpll_netlink.h
>index dd28b56d27c56d..a9cfd55f57fc42 100644
>--- a/drivers/dpll/dpll_netlink.h
>+++ b/drivers/dpll/dpll_netlink.h
>@@ -11,5 +11,3 @@ int dpll_device_delete_ntf(struct dpll_device *dpll);
> int dpll_pin_create_ntf(struct dpll_pin *pin);
>
> int dpll_pin_delete_ntf(struct dpll_pin *pin);
>-
>-int __dpll_pin_change_ntf(struct dpll_pin *pin);
>diff --git a/include/linux/dpll.h b/include/linux/dpll.h
>index b7277a8b484d26..f8037f1ab20b60 100644
>--- a/include/linux/dpll.h
>+++ b/include/linux/dpll.h
>@@ -286,6 +286,7 @@ int dpll_pin_ref_sync_pair_add(struct dpll_pin *pin,
>
> int dpll_device_change_ntf(struct dpll_device *dpll);
>
>+int __dpll_pin_change_ntf(struct dpll_pin *pin);
> int dpll_pin_change_ntf(struct dpll_pin *pin);
>
> int register_dpll_notifier(struct notifier_block *nb);
>--
>2.52.0


^ permalink raw reply

* Re: [PATCH v1 1/2] vfio: add callback to get tph info for dma-buf
From: Zhiping Zhang @ 2026-04-27 14:28 UTC (permalink / raw)
  To: Leon Romanovsky
  Cc: Alex Williamson, Stanislav Fomichev, Keith Busch, Jason Gunthorpe,
	Bjorn Helgaas, linux-rdma, linux-pci, netdev, dri-devel,
	Yochai Cohen, Yishai Hadas
In-Reply-To: <20260427133746.GJ440345@unreal>

On Mon, Apr 27, 2026 at 6:37 AM Leon Romanovsky <leon@kernel.org> wrote:
>
> >
> On Wed, Apr 22, 2026 at 09:23:27AM -0600, Alex Williamson wrote:
> > On Mon, 20 Apr 2026 11:39:15 -0700
> > Zhiping Zhang <zhipingz@meta.com> wrote:
> >
> > > Add a dma-buf callback that returns raw TPH metadata from the exporter
> > > so peer devices can reuse the steering tag and processing hint
> > > associated with a VFIO-exported buffer.
> > >
> > > Keep the existing VFIO_DEVICE_FEATURE_DMA_BUF uAPI layout intact by
> > > using a flag plus one extra trailing entries[] object for the optional
> > > TPH metadata. Rename the uAPI field dma_ranges to entries. The
> > > nr_ranges field remains the DMA range count; when VFIO_DMABUF_FLAG_TPH
> > > is set the kernel reads one extra entry beyond nr_ranges for the TPH
> > > metadata.
> > >
> > > Add an st_width parameter to get_tph() so the exporter can reject
> > > steering tags that exceed the consumer's supported width (8 vs 16 bit).
> > > When no TPH metadata was supplied, make get_tph() return -EOPNOTSUPP.
> > >
> > > Signed-off-by: Zhiping Zhang <zhipingz@meta.com>
> > > ---
> > >  drivers/vfio/pci/vfio_pci_dmabuf.c | 62 +++++++++++++++++++++++-------
> > >  include/linux/dma-buf.h            | 17 ++++++++
> > >  include/uapi/linux/vfio.h          | 28 ++++++++++++--
> > >  3 files changed, 89 insertions(+), 18 deletions(-)
>
> <...>
>
> > > diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h
> > > index bb7b89330d35..a0bd24623c52 100644
> > > --- a/include/uapi/linux/vfio.h
> > > +++ b/include/uapi/linux/vfio.h
> > > @@ -1490,16 +1490,36 @@ struct vfio_device_feature_bus_master {
> > >   * open_flags are the typical flags passed to open(2), eg O_RDWR, O_CLOEXEC,
> > >   * etc. offset/length specify a slice of the region to create the dmabuf from.
> > >   * nr_ranges is the total number of (P2P DMA) ranges that comprise the dmabuf.
> > > + * When VFIO_DMABUF_FLAG_TPH is set, entries[] contains one extra trailing
> > > + * object after the nr_ranges DMA ranges carrying the TPH steering tag and
> > > + * processing hint.
> >
> > I really don't think we want to design an API where entries is
> > implicitly one-off from what's actually there.  This feeds back into
> > the below removal of the __counted by attribute, which is a red flag
> > that this is the wrong approach.
>
> I believe removing `__counted` is a mistake. In my proposal, the intent
> was to adjust the meaning of the storage object based on the flag bit.
> The size of the array should still be represented correctly.
>
> Thanks

Thanks Leon — you're right that __counted_by should be preserved. In
your approach, when the flag is set, the last entry in the array
carries the TPH data, so the effective DMA range count is nr_ranges -
1.

That said, after discussing internally, we're leaning toward
introducing a new VFIO device feature with dedicated TPH fields (as
Alex suggested too), to avoid overloading vfio_region_dma_range with a
union that changes semantics based on position.

Would you have concerns with that direction? I'll post a v3 with the
new approach.

^ permalink raw reply

* [PATCH] [v4] wiznet: convert to GPIO descriptors
From: Arnd Bergmann @ 2026-04-27 14:28 UTC (permalink / raw)
  To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Linus Walleij, Bartosz Golaszewski
  Cc: Arnd Bergmann, Marco Crivellari, netdev, devicetree, linux-kernel,
	linux-gpio

From: Arnd Bergmann <arnd@arndb.de>

The w5100/w5300 drivers only support probing with old platform data in
MMIO mode, or probing with DT in SPI mode. There are no users of this
platform data in tree, and from the git history it appears that the only
users of MMIO mode were on the (since removed) blackfin architecture.

Remove the platform data option, as it's unlikely to still be needed, and
change the internal operation to GPIO descriptors, making the behavior
the same for SPI and MMIO mode. The other data in the platform_data
structure is the MAC address, so make that also handled the same for both.

It would probably be possible to just remove the MMIO mode driver
completely, but it seems fine otherwise, and fixing it to use the modern
interface seems easy enough.

The CONFIG_WIZNET_BUS_SHIFT value was apparently meant to be set
at compile time to a machine specific value. This was always broken
for multiplatform configurations with conflicting requirements, and
in the mainline kernel it was set to 0 anyway. Leave it defined
locally as 0 but rename it to something without the CONFIG_ prefix.

Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Link: https://lore.kernel.org/all/20230127095839.3266452-1-arnd@kernel.org/
---
v4: rebase to 7.1
v3: include linux/gpio/consumer.h to avoid build failure without GPIOLIB
v2: replace CONFIG_WIZNET_BUS_SHIFT with a constant
---
 .../devicetree/bindings/net/wiznet,w5x00.txt  |  4 +-
 drivers/net/ethernet/wiznet/w5100-spi.c       |  9 +--
 drivers/net/ethernet/wiznet/w5100.c           | 61 ++++++++++---------
 drivers/net/ethernet/wiznet/w5100.h           |  3 +-
 drivers/net/ethernet/wiznet/w5300.c           | 54 ++++++++--------
 include/linux/platform_data/wiznet.h          | 23 -------
 6 files changed, 67 insertions(+), 87 deletions(-)
 delete mode 100644 include/linux/platform_data/wiznet.h

diff --git a/Documentation/devicetree/bindings/net/wiznet,w5x00.txt b/Documentation/devicetree/bindings/net/wiznet,w5x00.txt
index e9665798c4be..e8a802d65817 100644
--- a/Documentation/devicetree/bindings/net/wiznet,w5x00.txt
+++ b/Documentation/devicetree/bindings/net/wiznet,w5x00.txt
@@ -1,6 +1,6 @@
 * Wiznet w5x00
 
-This is a standalone 10/100 MBit Ethernet controller with SPI interface.
+This is a standalone 10/100 MBit Ethernet controller with SPI or MMIO interface.
 
 For each device connected to a SPI bus, define a child node within
 the SPI master node.
@@ -9,6 +9,7 @@ Required properties:
 - compatible: Should be one of the following strings:
 	      "wiznet,w5100"
 	      "wiznet,w5200"
+	      "wiznet,w5300"
 	      "wiznet,w5500"
 - reg: Specify the SPI chip select the chip is wired to.
 - interrupts: Specify the interrupt index within the interrupt controller (referred
@@ -25,6 +26,7 @@ Optional properties:
   According to the w5500 datasheet, the chip allows a maximum of 80 MHz, however,
   board designs may need to limit this value.
 - local-mac-address: See ethernet.txt in the same directory.
+- link-gpios: a GPIO line used for the link detection interrupt
 
 
 Example (for Raspberry Pi with pin control stuff for GPIO irq):
diff --git a/drivers/net/ethernet/wiznet/w5100-spi.c b/drivers/net/ethernet/wiznet/w5100-spi.c
index 990a3cce8c0f..0626fcb8db5a 100644
--- a/drivers/net/ethernet/wiznet/w5100-spi.c
+++ b/drivers/net/ethernet/wiznet/w5100-spi.c
@@ -422,14 +422,7 @@ static int w5100_spi_probe(struct spi_device *spi)
 {
 	const struct w5100_ops *ops;
 	kernel_ulong_t driver_data;
-	const void *mac = NULL;
-	u8 tmpmac[ETH_ALEN];
 	int priv_size;
-	int ret;
-
-	ret = of_get_mac_address(spi->dev.of_node, tmpmac);
-	if (!ret)
-		mac = tmpmac;
 
 	driver_data = (uintptr_t)spi_get_device_match_data(spi);
 
@@ -450,7 +443,7 @@ static int w5100_spi_probe(struct spi_device *spi)
 		return -EINVAL;
 	}
 
-	return w5100_probe(&spi->dev, ops, priv_size, mac, spi->irq, -EINVAL);
+	return w5100_probe(&spi->dev, ops, priv_size, spi->irq);
 }
 
 static void w5100_spi_remove(struct spi_device *spi)
diff --git a/drivers/net/ethernet/wiznet/w5100.c b/drivers/net/ethernet/wiznet/w5100.c
index c5424d882135..62b2f24106cd 100644
--- a/drivers/net/ethernet/wiznet/w5100.c
+++ b/drivers/net/ethernet/wiznet/w5100.c
@@ -11,7 +11,6 @@
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/platform_device.h>
-#include <linux/platform_data/wiznet.h>
 #include <linux/ethtool.h>
 #include <linux/skbuff.h>
 #include <linux/types.h>
@@ -23,7 +22,8 @@
 #include <linux/ioport.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
+#include <linux/of_net.h>
 
 #include "w5100.h"
 
@@ -139,6 +139,10 @@ MODULE_LICENSE("GPL");
 #define W5500_RX_MEM_START	0x30000
 #define W5500_RX_MEM_SIZE	0x04000
 
+#define WIZNET_BUS_SHIFT 0	/* possibly machine specific */
+
+#define W5100_BUS_DIRECT_SIZE  (0x8000 << WIZNET_BUS_SHIFT)
+
 /*
  * Device driver private data structure
  */
@@ -157,7 +161,7 @@ struct w5100_priv {
 
 	int irq;
 	int link_irq;
-	int link_gpio;
+	struct gpio_desc *link_gpio;
 
 	struct napi_struct napi;
 	struct net_device *ndev;
@@ -204,13 +208,13 @@ static inline void __iomem *w5100_mmio(struct net_device *ndev)
  */
 static inline int w5100_read_direct(struct net_device *ndev, u32 addr)
 {
-	return ioread8(w5100_mmio(ndev) + (addr << CONFIG_WIZNET_BUS_SHIFT));
+	return ioread8(w5100_mmio(ndev) + (addr << WIZNET_BUS_SHIFT));
 }
 
 static inline int __w5100_write_direct(struct net_device *ndev, u32 addr,
 				       u8 data)
 {
-	iowrite8(data, w5100_mmio(ndev) + (addr << CONFIG_WIZNET_BUS_SHIFT));
+	iowrite8(data, w5100_mmio(ndev) + (addr << WIZNET_BUS_SHIFT));
 
 	return 0;
 }
@@ -729,8 +733,8 @@ static u32 w5100_get_link(struct net_device *ndev)
 {
 	struct w5100_priv *priv = netdev_priv(ndev);
 
-	if (gpio_is_valid(priv->link_gpio))
-		return !!gpio_get_value(priv->link_gpio);
+	if (priv->link_gpio)
+		return !!gpiod_get_value(priv->link_gpio);
 
 	return 1;
 }
@@ -943,7 +947,7 @@ static irqreturn_t w5100_detect_link(int irq, void *ndev_instance)
 	struct w5100_priv *priv = netdev_priv(ndev);
 
 	if (netif_running(ndev)) {
-		if (gpio_get_value(priv->link_gpio) != 0) {
+		if (gpiod_get_value(priv->link_gpio) != 0) {
 			netif_info(priv, link, ndev, "link is up\n");
 			netif_carrier_on(ndev);
 		} else {
@@ -998,8 +1002,8 @@ static int w5100_open(struct net_device *ndev)
 	w5100_hw_start(priv);
 	napi_enable(&priv->napi);
 	netif_start_queue(ndev);
-	if (!gpio_is_valid(priv->link_gpio) ||
-	    gpio_get_value(priv->link_gpio) != 0)
+	if (!priv->link_gpio ||
+	    gpiod_get_value(priv->link_gpio) != 0)
 		netif_carrier_on(ndev);
 	return 0;
 }
@@ -1037,15 +1041,10 @@ static const struct net_device_ops w5100_netdev_ops = {
 
 static int w5100_mmio_probe(struct platform_device *pdev)
 {
-	struct wiznet_platform_data *data = dev_get_platdata(&pdev->dev);
-	const void *mac_addr = NULL;
 	struct resource *mem;
 	const struct w5100_ops *ops;
 	int irq;
 
-	if (data && is_valid_ether_addr(data->mac_addr))
-		mac_addr = data->mac_addr;
-
 	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!mem)
 		return -EINVAL;
@@ -1058,8 +1057,7 @@ static int w5100_mmio_probe(struct platform_device *pdev)
 	if (irq < 0)
 		return irq;
 
-	return w5100_probe(&pdev->dev, ops, sizeof(struct w5100_mmio_priv),
-			   mac_addr, irq, data ? data->link_gpio : -EINVAL);
+	return w5100_probe(&pdev->dev, ops, sizeof(struct w5100_mmio_priv), irq);
 }
 
 static void w5100_mmio_remove(struct platform_device *pdev)
@@ -1075,13 +1073,13 @@ void *w5100_ops_priv(const struct net_device *ndev)
 EXPORT_SYMBOL_GPL(w5100_ops_priv);
 
 int w5100_probe(struct device *dev, const struct w5100_ops *ops,
-		int sizeof_ops_priv, const void *mac_addr, int irq,
-		int link_gpio)
+		int sizeof_ops_priv, int irq)
 {
 	struct w5100_priv *priv;
 	struct net_device *ndev;
 	int err;
 	size_t alloc_size;
+	u8 tmpmac[ETH_ALEN];
 
 	alloc_size = sizeof(*priv);
 	if (sizeof_ops_priv) {
@@ -1127,7 +1125,9 @@ int w5100_probe(struct device *dev, const struct w5100_ops *ops,
 	priv->ndev = ndev;
 	priv->ops = ops;
 	priv->irq = irq;
-	priv->link_gpio = link_gpio;
+	priv->link_gpio = gpiod_get_optional(dev, "link", GPIOD_IN);
+	if (IS_ERR(priv->link_gpio))
+		return PTR_ERR(priv->link_gpio);
 
 	ndev->netdev_ops = &w5100_netdev_ops;
 	ndev->ethtool_ops = &w5100_ethtool_ops;
@@ -1154,8 +1154,9 @@ int w5100_probe(struct device *dev, const struct w5100_ops *ops,
 	INIT_WORK(&priv->setrx_work, w5100_setrx_work);
 	INIT_WORK(&priv->restart_work, w5100_restart_work);
 
-	if (mac_addr)
-		eth_hw_addr_set(ndev, mac_addr);
+	err = of_get_mac_address(dev->of_node, tmpmac);
+	if (!err)
+		eth_hw_addr_set(ndev, tmpmac);
 	else
 		eth_hw_addr_random(ndev);
 
@@ -1180,7 +1181,7 @@ int w5100_probe(struct device *dev, const struct w5100_ops *ops,
 	if (err)
 		goto err_hw;
 
-	if (gpio_is_valid(priv->link_gpio)) {
+	if (priv->link_gpio) {
 		char *link_name = devm_kzalloc(dev, 16, GFP_KERNEL);
 
 		if (!link_name) {
@@ -1188,12 +1189,14 @@ int w5100_probe(struct device *dev, const struct w5100_ops *ops,
 			goto err_gpio;
 		}
 		snprintf(link_name, 16, "%s-link", netdev_name(ndev));
-		priv->link_irq = gpio_to_irq(priv->link_gpio);
+		priv->link_irq = gpiod_to_irq(priv->link_gpio);
 		if (request_any_context_irq(priv->link_irq, w5100_detect_link,
 					    IRQF_TRIGGER_RISING |
 					    IRQF_TRIGGER_FALLING,
-					    link_name, priv->ndev) < 0)
-			priv->link_gpio = -EINVAL;
+					    link_name, priv->ndev) < 0) {
+			gpiod_put(priv->link_gpio);
+			priv->link_gpio = NULL;
+		}
 	}
 
 	return 0;
@@ -1217,7 +1220,7 @@ void w5100_remove(struct device *dev)
 
 	w5100_hw_reset(priv);
 	free_irq(priv->irq, ndev);
-	if (gpio_is_valid(priv->link_gpio))
+	if (priv->link_gpio)
 		free_irq(priv->link_irq, ndev);
 
 	flush_work(&priv->setrx_work);
@@ -1254,8 +1257,8 @@ static int w5100_resume(struct device *dev)
 		w5100_hw_start(priv);
 
 		netif_device_attach(ndev);
-		if (!gpio_is_valid(priv->link_gpio) ||
-		    gpio_get_value(priv->link_gpio) != 0)
+		if (!priv->link_gpio ||
+		    gpiod_get_value(priv->link_gpio) != 0)
 			netif_carrier_on(ndev);
 	}
 	return 0;
diff --git a/drivers/net/ethernet/wiznet/w5100.h b/drivers/net/ethernet/wiznet/w5100.h
index 481af3b6d9e8..013ef2835115 100644
--- a/drivers/net/ethernet/wiznet/w5100.h
+++ b/drivers/net/ethernet/wiznet/w5100.h
@@ -29,8 +29,7 @@ struct w5100_ops {
 void *w5100_ops_priv(const struct net_device *ndev);
 
 int w5100_probe(struct device *dev, const struct w5100_ops *ops,
-		int sizeof_ops_priv, const void *mac_addr, int irq,
-		int link_gpio);
+		int sizeof_ops_priv, int irq);
 void w5100_remove(struct device *dev);
 
 extern const struct dev_pm_ops w5100_pm_ops;
diff --git a/drivers/net/ethernet/wiznet/w5300.c b/drivers/net/ethernet/wiznet/w5300.c
index 3e711dea3b2c..303c04cb7fc4 100644
--- a/drivers/net/ethernet/wiznet/w5300.c
+++ b/drivers/net/ethernet/wiznet/w5300.c
@@ -12,7 +12,6 @@
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/platform_device.h>
-#include <linux/platform_data/wiznet.h>
 #include <linux/ethtool.h>
 #include <linux/skbuff.h>
 #include <linux/types.h>
@@ -24,7 +23,8 @@
 #include <linux/ioport.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
+#include <linux/of_net.h>
 
 #define DRV_NAME	"w5300"
 #define DRV_VERSION	"2012-04-04"
@@ -80,6 +80,10 @@ MODULE_LICENSE("GPL");
 #define W5300_S0_RX_FIFO	0x0230	/* S0 Receive FIFO */
 #define W5300_REGS_LEN		0x0400
 
+#define WIZNET_BUS_SHIFT 0
+
+#define W5300_BUS_DIRECT_SIZE  (0x0400 << WIZNET_BUS_SHIFT)
+
 /*
  * Device driver private data structure
  */
@@ -91,7 +95,7 @@ struct w5300_priv {
 	void (*write)(struct w5300_priv *priv, u16 addr, u16 data);
 	int irq;
 	int link_irq;
-	int link_gpio;
+	struct gpio_desc *link_gpio;
 
 	struct napi_struct napi;
 	struct net_device *ndev;
@@ -113,13 +117,13 @@ struct w5300_priv {
  */
 static inline u16 w5300_read_direct(struct w5300_priv *priv, u16 addr)
 {
-	return ioread16(priv->base + (addr << CONFIG_WIZNET_BUS_SHIFT));
+	return ioread16(priv->base + (addr << WIZNET_BUS_SHIFT));
 }
 
 static inline void w5300_write_direct(struct w5300_priv *priv,
 				      u16 addr, u16 data)
 {
-	iowrite16(data, priv->base + (addr << CONFIG_WIZNET_BUS_SHIFT));
+	iowrite16(data, priv->base + (addr << WIZNET_BUS_SHIFT));
 }
 
 /*
@@ -292,8 +296,8 @@ static u32 w5300_get_link(struct net_device *ndev)
 {
 	struct w5300_priv *priv = netdev_priv(ndev);
 
-	if (gpio_is_valid(priv->link_gpio))
-		return !!gpio_get_value(priv->link_gpio);
+	if (priv->link_gpio)
+		return !!gpiod_get_value(priv->link_gpio);
 
 	return 1;
 }
@@ -442,7 +446,7 @@ static irqreturn_t w5300_detect_link(int irq, void *ndev_instance)
 	struct w5300_priv *priv = netdev_priv(ndev);
 
 	if (netif_running(ndev)) {
-		if (gpio_get_value(priv->link_gpio) != 0) {
+		if (gpiod_get_value(priv->link_gpio) != 0) {
 			netif_info(priv, link, ndev, "link is up\n");
 			netif_carrier_on(ndev);
 		} else {
@@ -485,8 +489,8 @@ static int w5300_open(struct net_device *ndev)
 	w5300_hw_start(priv);
 	napi_enable(&priv->napi);
 	netif_start_queue(ndev);
-	if (!gpio_is_valid(priv->link_gpio) ||
-	    gpio_get_value(priv->link_gpio) != 0)
+	if (!priv->link_gpio ||
+	    gpiod_get_value(priv->link_gpio) != 0)
 		netif_carrier_on(ndev);
 	return 0;
 }
@@ -524,7 +528,6 @@ static const struct net_device_ops w5300_netdev_ops = {
 
 static int w5300_hw_probe(struct platform_device *pdev)
 {
-	struct wiznet_platform_data *data = dev_get_platdata(&pdev->dev);
 	struct net_device *ndev = platform_get_drvdata(pdev);
 	struct w5300_priv *priv = netdev_priv(ndev);
 	const char *name = netdev_name(ndev);
@@ -533,11 +536,9 @@ static int w5300_hw_probe(struct platform_device *pdev)
 	int irq;
 	int ret;
 
-	if (data && is_valid_ether_addr(data->mac_addr)) {
-		eth_hw_addr_set(ndev, data->mac_addr);
-	} else {
-		eth_hw_addr_random(ndev);
-	}
+        ret = of_get_ethdev_address(pdev->dev.of_node, ndev);
+        if (ret)
+                eth_hw_addr_random(ndev);
 
 	priv->base = devm_platform_get_and_ioremap_resource(pdev, 0, &mem);
 	if (IS_ERR(priv->base))
@@ -568,17 +569,22 @@ static int w5300_hw_probe(struct platform_device *pdev)
 		return ret;
 	priv->irq = irq;
 
-	priv->link_gpio = data ? data->link_gpio : -EINVAL;
-	if (gpio_is_valid(priv->link_gpio)) {
+	priv->link_gpio = gpiod_get_optional(&pdev->dev, "link", GPIOD_IN);
+	if (IS_ERR(priv->link_gpio))
+		return PTR_ERR(priv->link_gpio);
+
+	if (priv->link_gpio) {
 		char *link_name = devm_kzalloc(&pdev->dev, 16, GFP_KERNEL);
 		if (!link_name)
 			return -ENOMEM;
 		snprintf(link_name, 16, "%s-link", name);
-		priv->link_irq = gpio_to_irq(priv->link_gpio);
+		priv->link_irq = gpiod_to_irq(priv->link_gpio);
 		if (request_any_context_irq(priv->link_irq, w5300_detect_link,
 				IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
-				link_name, priv->ndev) < 0)
-			priv->link_gpio = -EINVAL;
+				link_name, priv->ndev) < 0) {
+			priv->link_gpio = NULL;
+			gpiod_put(priv->link_gpio);
+		}
 	}
 
 	netdev_info(ndev, "at 0x%llx irq %d\n", (u64)mem->start, irq);
@@ -633,7 +639,7 @@ static void w5300_remove(struct platform_device *pdev)
 
 	w5300_hw_reset(priv);
 	free_irq(priv->irq, ndev);
-	if (gpio_is_valid(priv->link_gpio))
+	if (priv->link_gpio)
 		free_irq(priv->link_irq, ndev);
 
 	unregister_netdev(ndev);
@@ -665,8 +671,8 @@ static int w5300_resume(struct device *dev)
 		w5300_hw_start(priv);
 
 		netif_device_attach(ndev);
-		if (!gpio_is_valid(priv->link_gpio) ||
-		    gpio_get_value(priv->link_gpio) != 0)
+		if (!priv->link_gpio ||
+		    gpiod_get_value(priv->link_gpio) != 0)
 			netif_carrier_on(ndev);
 	}
 	return 0;
diff --git a/include/linux/platform_data/wiznet.h b/include/linux/platform_data/wiznet.h
deleted file mode 100644
index 1154c4db8a13..000000000000
--- a/include/linux/platform_data/wiznet.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * Ethernet driver for the WIZnet W5x00 chip.
- */
-
-#ifndef PLATFORM_DATA_WIZNET_H
-#define PLATFORM_DATA_WIZNET_H
-
-#include <linux/if_ether.h>
-
-struct wiznet_platform_data {
-	int	link_gpio;
-	u8	mac_addr[ETH_ALEN];
-};
-
-#ifndef CONFIG_WIZNET_BUS_SHIFT
-#define CONFIG_WIZNET_BUS_SHIFT 0
-#endif
-
-#define W5100_BUS_DIRECT_SIZE	(0x8000 << CONFIG_WIZNET_BUS_SHIFT)
-#define W5300_BUS_DIRECT_SIZE	(0x0400 << CONFIG_WIZNET_BUS_SHIFT)
-
-#endif /* PLATFORM_DATA_WIZNET_H */
-- 
2.39.5


^ permalink raw reply related

* RE: [PATCH iwl-net v7 3/3] ice: add dpll peer notification for paired SMA and U.FL pins
From: Kubalewski, Arkadiusz @ 2026-04-27 14:29 UTC (permalink / raw)
  To: Oros, Petr, netdev@vger.kernel.org
  Cc: Oros, Petr, Nguyen, Anthony L, Kitszel, Przemyslaw, Andrew Lunn,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Jiri Pirko, Vadim Fedorenko, Vecera, Ivan,
	Schmidt, Michal, Keller, Jacob E, Loktionov, Aleksandr,
	Rinitha, SX, intel-wired-lan@lists.osuosl.org,
	linux-kernel@vger.kernel.org
In-Reply-To: <20260417145907.696307-4-poros@redhat.com>

>From: Petr Oros <poros@redhat.com>
>Sent: Friday, April 17, 2026 4:59 PM
>
>SMA and U.FL pins share physical signal paths in pairs (SMA1/U.FL1 and
>SMA2/U.FL2).  When one pin's state changes via a PCA9575 GPIO write,
>the paired pin's state also changes, but no notification is sent for
>the peer pin.  Userspace consumers monitoring the peer via dpll netlink
>subscribe never learn about the update.
>
>Add ice_dpll_sw_pin_notify_peer() which sends a change notification for
>the paired SW pin.  Call it from ice_dpll_pin_sma_direction_set(),
>ice_dpll_sma_pin_state_set(), and ice_dpll_ufl_pin_state_set() after
>pf->dplls.lock is released.  Use __dpll_pin_change_ntf() because
>dpll_lock is still held by the dpll netlink layer (dpll_pin_pre_doit).
>
>Fixes: 2dd5d03c77e2 ("ice: redesign dpll sma/u.fl pins control")

LGTM,
Reviewed-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>

>Signed-off-by: Petr Oros <poros@redhat.com>
>---
> drivers/net/ethernet/intel/ice/ice_dpll.c | 32 +++++++++++++++++++++++
> 1 file changed, 32 insertions(+)
>
>diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c
>b/drivers/net/ethernet/intel/ice/ice_dpll.c
>index 11b942b83500fb..be72a076f7a15c 100644
>--- a/drivers/net/ethernet/intel/ice/ice_dpll.c
>+++ b/drivers/net/ethernet/intel/ice/ice_dpll.c
>@@ -1154,6 +1154,32 @@ ice_dpll_input_state_get(const struct dpll_pin
>*pin, void *pin_priv,
> 				      extack, ICE_DPLL_PIN_TYPE_INPUT);
> }
>
>+/**
>+ * ice_dpll_sw_pin_notify_peer - notify the paired SW pin after a state
>change
>+ * @d: pointer to dplls struct
>+ * @changed: the SW pin that was explicitly changed (already notified by
>dpll core)
>+ *
>+ * SMA and U.FL pins share physical signal paths in pairs (SMA1/U.FL1 and
>+ * SMA2/U.FL2).  When one pin's routing changes via the PCA9575 GPIO
>+ * expander, the paired pin's state may also change.  Send a change
>+ * notification for the peer pin so userspace consumers monitoring the
>+ * peer via dpll netlink learn about the update.
>+ *
>+ * Context: Called from dpll_pin_ops callbacks after pf->dplls.lock is
>+ *          released.  Uses __dpll_pin_change_ntf() because dpll_lock is
>+ *          still held by the dpll netlink layer.
>+ */
>+static void ice_dpll_sw_pin_notify_peer(struct ice_dplls *d,
>+					struct ice_dpll_pin *changed)
>+{
>+	struct ice_dpll_pin *peer;
>+
>+	peer = (changed >= d->sma && changed < d->sma + ICE_DPLL_PIN_SW_NUM)
>?
>+		&d->ufl[changed->idx] : &d->sma[changed->idx];
>+	if (peer->pin)
>+		__dpll_pin_change_ntf(peer->pin);
>+}
>+
> /**
>  * ice_dpll_sma_direction_set - set direction of SMA pin
>  * @p: pointer to a pin
>@@ -1344,6 +1370,8 @@ ice_dpll_ufl_pin_state_set(const struct dpll_pin
>*pin, void *pin_priv,
>
> unlock:
> 	mutex_unlock(&pf->dplls.lock);
>+	if (!ret)
>+		ice_dpll_sw_pin_notify_peer(&pf->dplls, p);
>
> 	return ret;
> }
>@@ -1462,6 +1490,8 @@ ice_dpll_sma_pin_state_set(const struct dpll_pin
>*pin, void *pin_priv,
>
> unlock:
> 	mutex_unlock(&pf->dplls.lock);
>+	if (!ret)
>+		ice_dpll_sw_pin_notify_peer(&pf->dplls, sma);
>
> 	return ret;
> }
>@@ -1657,6 +1687,8 @@ ice_dpll_pin_sma_direction_set(const struct dpll_pin
>*pin, void *pin_priv,
> 	mutex_lock(&pf->dplls.lock);
> 	ret = ice_dpll_sma_direction_set(p, direction, extack);
> 	mutex_unlock(&pf->dplls.lock);
>+	if (!ret)
>+		ice_dpll_sw_pin_notify_peer(&pf->dplls, p);
>
> 	return ret;
> }
>--
>2.52.0


^ permalink raw reply

* [PATCH] dsa: b53: hide legacy gpiolib usage on non-mips
From: Arnd Bergmann @ 2026-04-27 14:30 UTC (permalink / raw)
  To: Florian Fainelli, Jonas Gorski, Andrew Lunn, Vladimir Oltean,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Linus Walleij, Bartosz Golaszewski
  Cc: Arnd Bergmann, Álvaro Fernández Rojas, Kyle Hendry,
	netdev, linux-kernel, linux-gpio

From: Arnd Bergmann <arnd@arndb.de>

The MIPS bcm53xx platform still uses the legacy gpiolib interfaces based
on gpio numbers, but other platforms do not.

Hide these interfaces inside of the existing #ifdef block and use the
modern interfaces in the common parts of the driver to allow building
it when the gpio_set_value() is left out of the kernel.

Reviewed-by: Jonas Gorski <jonas.gorski@gmail.com>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 drivers/net/dsa/b53/b53_common.c | 17 +++++------------
 drivers/net/dsa/b53/b53_priv.h   | 25 +++++++++++++++++++------
 2 files changed, 24 insertions(+), 18 deletions(-)

diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c
index 2c4131ed7e30..d838511ae674 100644
--- a/drivers/net/dsa/b53/b53_common.c
+++ b/drivers/net/dsa/b53/b53_common.c
@@ -19,7 +19,7 @@
 
 #include <linux/delay.h>
 #include <linux/export.h>
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
 #include <linux/kernel.h>
 #include <linux/math.h>
 #include <linux/minmax.h>
@@ -965,17 +965,17 @@ EXPORT_SYMBOL(b53_configure_vlan);
 
 static void b53_switch_reset_gpio(struct b53_device *dev)
 {
-	int gpio = dev->reset_gpio;
+	struct gpio_desc *gpio = dev->reset_gpio;
 
-	if (gpio < 0)
+	if (IS_ERR(gpio))
 		return;
 
 	/* Reset sequence: RESET low(50ms)->high(20ms)
 	 */
-	gpio_set_value(gpio, 0);
+	gpiod_set_value(gpio, 0);
 	mdelay(50);
 
-	gpio_set_value(gpio, 1);
+	gpiod_set_value(gpio, 1);
 	mdelay(20);
 
 	dev->current_page = 0xff;
@@ -3092,7 +3092,6 @@ static int b53_switch_init(struct b53_device *dev)
 {
 	u32 chip_id = dev->chip_id;
 	unsigned int i;
-	int ret;
 
 	if (is63xx(dev))
 		chip_id = BCM63XX_DEVICE_ID;
@@ -3173,12 +3172,6 @@ static int b53_switch_init(struct b53_device *dev)
 		return -ENOMEM;
 
 	dev->reset_gpio = b53_switch_get_reset_gpio(dev);
-	if (dev->reset_gpio >= 0) {
-		ret = devm_gpio_request_one(dev->dev, dev->reset_gpio,
-					    GPIOF_OUT_INIT_HIGH, "robo_reset");
-		if (ret)
-			return ret;
-	}
 
 	return 0;
 }
diff --git a/drivers/net/dsa/b53/b53_priv.h b/drivers/net/dsa/b53/b53_priv.h
index 923d56bbd061..ad0c65a9bdc3 100644
--- a/drivers/net/dsa/b53/b53_priv.h
+++ b/drivers/net/dsa/b53/b53_priv.h
@@ -149,7 +149,7 @@ struct b53_device {
 	u8 duplex_reg;
 	u8 jumbo_pm_reg;
 	u8 jumbo_size_reg;
-	int reset_gpio;
+	struct gpio_desc *reset_gpio;
 	u8 num_arl_bins;
 	u16 num_arl_buckets;
 	enum dsa_tag_protocol tag_protocol;
@@ -468,23 +468,36 @@ static inline void b53_arl_search_read(struct b53_device *dev, u8 idx,
 #ifdef CONFIG_BCM47XX
 
 #include <linux/bcm47xx_nvram.h>
+#include <linux/gpio.h>
 #include <bcm47xx_board.h>
-static inline int b53_switch_get_reset_gpio(struct b53_device *dev)
+static inline struct gpio_desc *b53_switch_get_reset_gpio(struct b53_device *dev)
 {
 	enum bcm47xx_board board = bcm47xx_board_get();
+	int gpio, ret;
 
 	switch (board) {
 	case BCM47XX_BOARD_LINKSYS_WRT300NV11:
 	case BCM47XX_BOARD_LINKSYS_WRT310NV1:
-		return 8;
+		gpio = 8;
+		break;
 	default:
-		return bcm47xx_nvram_gpio_pin("robo_reset");
+		gpio = bcm47xx_nvram_gpio_pin("robo_reset");
 	}
+
+	if (!gpio_is_valid(gpio))
+		return ERR_PTR(-EINVAL);
+
+	ret = devm_gpio_request_one(dev->dev, gpio,
+				    GPIOF_OUT_INIT_HIGH, "robo_reset");
+	if (ret)
+		return ERR_PTR(ret);
+
+	return gpio_to_desc(gpio);
 }
 #else
-static inline int b53_switch_get_reset_gpio(struct b53_device *dev)
+static inline struct gpio_desc *b53_switch_get_reset_gpio(struct b53_device *dev)
 {
-	return -ENOENT;
+	return ERR_PTR(-ENODEV);
 }
 #endif
 
-- 
2.39.5


^ permalink raw reply related

* [PATCH net v2 0/4] netconsole: configfs store callback fixes
From: Breno Leitao @ 2026-04-27 14:30 UTC (permalink / raw)
  To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Keiichi Kii, Satyam Sharma, Andrew Morton,
	Matthew Wood, asantostc, gustavold
  Cc: netdev, linux-kernel, Breno Leitao, kernel-team, Simon Horman

V2 for issues in netconsole's configfs store callbacks.

There are still some changes I want to make, such as, having the dynamic
lock when reading from configfs (_show() callbacks), wich will solve
other issues, but I will keep it for later.

Signed-off-by: Breno Leitao <leitao@debian.org>
---
Changes in v2:
- dev_name_store: strip optional trailing newline before length check
  so 15-char ifnames written via echo aren't rejected (Simon, Sashiko)
- userdatum_value_store: snapshot and restore udm->value on
  update_userdata() failure to keep visible state in sync with the live
  payload (Simon/Sashiko)
- Link to v1: https://patch.msgid.link/20260423-netconsole_ai_fixes-v1-0-92b8b7de9a2c@debian.org

---
Breno Leitao (4):
      netconsole: return count instead of strnlen(buf, count) from store callbacks
      netconsole: avoid clobbering userdatum value on truncated write
      netconsole: propagate device name truncation in dev_name_store()
      netconsole: restore userdatum value on update_userdata() failure

 drivers/net/netconsole.c | 49 +++++++++++++++++++++++++++++-------------------
 1 file changed, 30 insertions(+), 19 deletions(-)
---
base-commit: 7080e32d3f09d8688c4a87d81bdcc71f7f606b16
change-id: 20260422-netconsole_ai_fixes-24599337a79d

Best regards,
--  
Breno Leitao <leitao@debian.org>


^ permalink raw reply

* [PATCH net v2 1/4] netconsole: return count instead of strnlen(buf, count) from store callbacks
From: Breno Leitao @ 2026-04-27 14:30 UTC (permalink / raw)
  To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Keiichi Kii, Satyam Sharma, Andrew Morton,
	Matthew Wood, asantostc, gustavold
  Cc: netdev, linux-kernel, Breno Leitao, kernel-team, Simon Horman
In-Reply-To: <20260427-netconsole_ai_fixes-v2-0-59965f29d9cc@debian.org>

Several configfs store callbacks in netconsole end with:

	ret = strnlen(buf, count);

This under-reports the number of bytes consumed when the input
contains an embedded NUL within count, telling the VFS that fewer
bytes were written than userspace actually handed in. A conformant
partial-write loop would then retry the trailing bytes against a
callback that has already accepted them.

Every other configfs driver in the tree returns count directly from
its store callbacks once parsing has succeeded, including
drivers/nvme/target/configfs.c, drivers/gpio/gpio-sim.c,
drivers/most/configfs.c, drivers/block/null_blk/main.c,
drivers/pci/endpoint/pci-ep-cfs.c, and the rest of the configfs
users. netconsole was the outlier (along with
drivers/infiniband/core/cma_configfs.c, which has the same latent
issue).

Align netconsole with the rest of the configfs ecosystem: return
count once the parser/validator has accepted the input. The numeric
and boolean parsers (kstrtobool, kstrtou16, mac_pton,
netpoll_parse_ip_addr) have already validated the meaningful prefix;
any trailing bytes are padding and should simply be reported as
consumed.

Fixes: 0bcc1816188e ("[NET] netconsole: Support dynamic reconfiguration using configfs")
Reviewed-by: Simon Horman <horms@kernel.org>
Signed-off-by: Breno Leitao <leitao@debian.org>
---
 drivers/net/netconsole.c | 26 +++++++++++++-------------
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c
index 205384dab89a6..76d7fbf9e1883 100644
--- a/drivers/net/netconsole.c
+++ b/drivers/net/netconsole.c
@@ -752,7 +752,7 @@ static ssize_t enabled_store(struct config_item *item,
 		unregister_netcons_consoles();
 	}
 
-	ret = strnlen(buf, count);
+	ret = count;
 	/* Deferred cleanup */
 	netconsole_process_cleanups();
 out_unlock:
@@ -781,7 +781,7 @@ static ssize_t release_store(struct config_item *item, const char *buf,
 
 	nt->release = release;
 
-	ret = strnlen(buf, count);
+	ret = count;
 out_unlock:
 	dynamic_netconsole_mutex_unlock();
 	return ret;
@@ -807,7 +807,7 @@ static ssize_t extended_store(struct config_item *item, const char *buf,
 		goto out_unlock;
 
 	nt->extended = extended;
-	ret = strnlen(buf, count);
+	ret = count;
 out_unlock:
 	dynamic_netconsole_mutex_unlock();
 	return ret;
@@ -830,7 +830,7 @@ static ssize_t dev_name_store(struct config_item *item, const char *buf,
 	trim_newline(nt->np.dev_name, IFNAMSIZ);
 
 	dynamic_netconsole_mutex_unlock();
-	return strnlen(buf, count);
+	return count;
 }
 
 static ssize_t local_port_store(struct config_item *item, const char *buf,
@@ -849,7 +849,7 @@ static ssize_t local_port_store(struct config_item *item, const char *buf,
 	ret = kstrtou16(buf, 10, &nt->np.local_port);
 	if (ret < 0)
 		goto out_unlock;
-	ret = strnlen(buf, count);
+	ret = count;
 out_unlock:
 	dynamic_netconsole_mutex_unlock();
 	return ret;
@@ -871,7 +871,7 @@ static ssize_t remote_port_store(struct config_item *item,
 	ret = kstrtou16(buf, 10, &nt->np.remote_port);
 	if (ret < 0)
 		goto out_unlock;
-	ret = strnlen(buf, count);
+	ret = count;
 out_unlock:
 	dynamic_netconsole_mutex_unlock();
 	return ret;
@@ -896,7 +896,7 @@ static ssize_t local_ip_store(struct config_item *item, const char *buf,
 		goto out_unlock;
 	nt->np.ipv6 = !!ipv6;
 
-	ret = strnlen(buf, count);
+	ret = count;
 out_unlock:
 	dynamic_netconsole_mutex_unlock();
 	return ret;
@@ -921,7 +921,7 @@ static ssize_t remote_ip_store(struct config_item *item, const char *buf,
 		goto out_unlock;
 	nt->np.ipv6 = !!ipv6;
 
-	ret = strnlen(buf, count);
+	ret = count;
 out_unlock:
 	dynamic_netconsole_mutex_unlock();
 	return ret;
@@ -957,7 +957,7 @@ static ssize_t remote_mac_store(struct config_item *item, const char *buf,
 		goto out_unlock;
 	memcpy(nt->np.remote_mac, remote_mac, ETH_ALEN);
 
-	ret = strnlen(buf, count);
+	ret = count;
 out_unlock:
 	dynamic_netconsole_mutex_unlock();
 	return ret;
@@ -1133,7 +1133,7 @@ static ssize_t sysdata_msgid_enabled_store(struct config_item *item,
 		disable_sysdata_feature(nt, SYSDATA_MSGID);
 
 unlock_ok:
-	ret = strnlen(buf, count);
+	ret = count;
 	dynamic_netconsole_mutex_unlock();
 	mutex_unlock(&netconsole_subsys.su_mutex);
 	return ret;
@@ -1162,7 +1162,7 @@ static ssize_t sysdata_release_enabled_store(struct config_item *item,
 		disable_sysdata_feature(nt, SYSDATA_RELEASE);
 
 unlock_ok:
-	ret = strnlen(buf, count);
+	ret = count;
 	dynamic_netconsole_mutex_unlock();
 	mutex_unlock(&netconsole_subsys.su_mutex);
 	return ret;
@@ -1191,7 +1191,7 @@ static ssize_t sysdata_taskname_enabled_store(struct config_item *item,
 		disable_sysdata_feature(nt, SYSDATA_TASKNAME);
 
 unlock_ok:
-	ret = strnlen(buf, count);
+	ret = count;
 	dynamic_netconsole_mutex_unlock();
 	mutex_unlock(&netconsole_subsys.su_mutex);
 	return ret;
@@ -1225,7 +1225,7 @@ static ssize_t sysdata_cpu_nr_enabled_store(struct config_item *item,
 		disable_sysdata_feature(nt, SYSDATA_CPU_NR);
 
 unlock_ok:
-	ret = strnlen(buf, count);
+	ret = count;
 	dynamic_netconsole_mutex_unlock();
 	mutex_unlock(&netconsole_subsys.su_mutex);
 	return ret;

-- 
2.52.0


^ permalink raw reply related

* [PATCH net v2 2/4] netconsole: avoid clobbering userdatum value on truncated write
From: Breno Leitao @ 2026-04-27 14:30 UTC (permalink / raw)
  To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Keiichi Kii, Satyam Sharma, Andrew Morton,
	Matthew Wood, asantostc, gustavold
  Cc: netdev, linux-kernel, Breno Leitao, kernel-team
In-Reply-To: <20260427-netconsole_ai_fixes-v2-0-59965f29d9cc@debian.org>

userdatum_value_store() bounds count by MAX_EXTRADATA_VALUE_LEN (200)
and then copies straight into udm->value, which is itself 200 bytes:

	if (count > MAX_EXTRADATA_VALUE_LEN)
		return -EMSGSIZE;
	...
	ret = strscpy(udm->value, buf, sizeof(udm->value));
	if (ret < 0)
		goto out_unlock;

If userspace writes exactly MAX_EXTRADATA_VALUE_LEN bytes with no NUL
within them, strscpy() copies 199 bytes plus a NUL into udm->value and
returns -E2BIG. The function jumps to out_unlock and reports the error
to userspace, but udm->value has already been overwritten with the
truncated string and update_userdata() is skipped, so the corruption
is not yet visible on the wire.

The next successful write to any userdatum entry under the same target
calls update_userdata(), which packs udm->value into the active
netconsole payload. From that point on, every netconsole message
carries the silently truncated value, and userspace has no indication
that a previous, error-returning write left state behind.

Tighten the entry check from "count > MAX_EXTRADATA_VALUE_LEN" to
"count >= MAX_EXTRADATA_VALUE_LEN". With count strictly less than
sizeof(udm->value), strscpy() can no longer return -E2BIG here, so
the corrupting truncation path is removed entirely.

Fixes: 8a6d5fec6c7f ("net: netconsole: add a userdata config_group member to netconsole_target")
Signed-off-by: Breno Leitao <leitao@debian.org>
---
 drivers/net/netconsole.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c
index 76d7fbf9e1883..595e09bd1ccfc 100644
--- a/drivers/net/netconsole.c
+++ b/drivers/net/netconsole.c
@@ -1076,15 +1076,13 @@ static ssize_t userdatum_value_store(struct config_item *item, const char *buf,
 	struct userdata *ud;
 	ssize_t ret;
 
-	if (count > MAX_EXTRADATA_VALUE_LEN)
+	if (count >= MAX_EXTRADATA_VALUE_LEN)
 		return -EMSGSIZE;
 
 	mutex_lock(&netconsole_subsys.su_mutex);
 	dynamic_netconsole_mutex_lock();
-
-	ret = strscpy(udm->value, buf, sizeof(udm->value));
-	if (ret < 0)
-		goto out_unlock;
+	/* count is bounded above, so strscpy() cannot truncate here */
+	strscpy(udm->value, buf, sizeof(udm->value));
 	trim_newline(udm->value, sizeof(udm->value));
 
 	ud = to_userdata(item->ci_parent);

-- 
2.52.0


^ permalink raw reply related

* [PATCH net v2 3/4] netconsole: propagate device name truncation in dev_name_store()
From: Breno Leitao @ 2026-04-27 14:30 UTC (permalink / raw)
  To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Keiichi Kii, Satyam Sharma, Andrew Morton,
	Matthew Wood, asantostc, gustavold
  Cc: netdev, linux-kernel, Breno Leitao, kernel-team
In-Reply-To: <20260427-netconsole_ai_fixes-v2-0-59965f29d9cc@debian.org>

dev_name_store() calls strscpy(nt->np.dev_name, buf, IFNAMSIZ) without
checking the return value. If userspace writes an interface name longer
than IFNAMSIZ - 1, strscpy() silently truncates and returns -E2BIG, but
the function ignores it and reports a fully successful write back to
userspace.

If a real interface happens to match the truncated name, netconsole will
bind to the wrong device on the next enable, sending kernel logs and
panic output to an unintended network segment with no indication to
userspace that anything was rewritten.

Reject writes whose length cannot fit in nt->np.dev_name up front:

	if (count >= IFNAMSIZ)
		return -ENAMETOOLONG;

This is not a big deal of a problem, but, it is still the correct
approach.

Fixes: 0bcc1816188e57 ("[NET] netconsole: Support dynamic reconfiguration using configfs")
Signed-off-by: Breno Leitao <leitao@debian.org>
---
 drivers/net/netconsole.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c
index 595e09bd1ccfc..b3b36e3ddd03d 100644
--- a/drivers/net/netconsole.c
+++ b/drivers/net/netconsole.c
@@ -817,6 +817,13 @@ static ssize_t dev_name_store(struct config_item *item, const char *buf,
 		size_t count)
 {
 	struct netconsole_target *nt = to_target(item);
+	size_t len = count;
+
+	/* Account for a trailing newline appended by tools like echo */
+	if (len && buf[len - 1] == '\n')
+		len--;
+	if (len >= IFNAMSIZ)
+		return -ENAMETOOLONG;
 
 	dynamic_netconsole_mutex_lock();
 	if (nt->state == STATE_ENABLED) {

-- 
2.52.0


^ permalink raw reply related

* [PATCH net v2 4/4] netconsole: restore userdatum value on update_userdata() failure
From: Breno Leitao @ 2026-04-27 14:30 UTC (permalink / raw)
  To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Keiichi Kii, Satyam Sharma, Andrew Morton,
	Matthew Wood, asantostc, gustavold
  Cc: netdev, linux-kernel, Breno Leitao, kernel-team
In-Reply-To: <20260427-netconsole_ai_fixes-v2-0-59965f29d9cc@debian.org>

userdatum_value_store() updates udm->value first and only then calls
update_userdata() to rebuild the on-the-wire payload. If
update_userdata() fails (e.g. -ENOMEM from kmalloc), the function
returns the error to userspace, but udm->value already holds the new
string while the live nt->userdata buffer still reflects the old one.

The next successful write to any sibling userdatum on the same target
will call update_userdata() again, which walks every entry and packs
the now-stale udm->value into the payload. The failed write is thus
silently activated later, with no indication to userspace that the
value it tried to set was rejected.

Snapshot the previous value before overwriting udm->value and restore
it if update_userdata() fails so the visible state and the active
payload stay consistent.

Fixes: eb83801af2dc ("netconsole: Dynamic allocation of userdata buffer")
Signed-off-by: Breno Leitao <leitao@debian.org>
---
 drivers/net/netconsole.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c
index b3b36e3ddd03d..57dd6821a8aa9 100644
--- a/drivers/net/netconsole.c
+++ b/drivers/net/netconsole.c
@@ -1079,6 +1079,7 @@ static ssize_t userdatum_value_store(struct config_item *item, const char *buf,
 				     size_t count)
 {
 	struct userdatum *udm = to_userdatum(item);
+	char old_value[MAX_EXTRADATA_VALUE_LEN];
 	struct netconsole_target *nt;
 	struct userdata *ud;
 	ssize_t ret;
@@ -1088,6 +1089,8 @@ static ssize_t userdatum_value_store(struct config_item *item, const char *buf,
 
 	mutex_lock(&netconsole_subsys.su_mutex);
 	dynamic_netconsole_mutex_lock();
+	/* Snapshot for rollback if update_userdata() fails below */
+	strscpy(old_value, udm->value, sizeof(old_value));
 	/* count is bounded above, so strscpy() cannot truncate here */
 	strscpy(udm->value, buf, sizeof(udm->value));
 	trim_newline(udm->value, sizeof(udm->value));
@@ -1095,8 +1098,11 @@ static ssize_t userdatum_value_store(struct config_item *item, const char *buf,
 	ud = to_userdata(item->ci_parent);
 	nt = userdata_to_target(ud);
 	ret = update_userdata(nt);
-	if (ret < 0)
+	if (ret < 0) {
+		/* Restore the previous value so it matches the live payload */
+		strscpy(udm->value, old_value, sizeof(udm->value));
 		goto out_unlock;
+	}
 	ret = count;
 out_unlock:
 	dynamic_netconsole_mutex_unlock();

-- 
2.52.0


^ permalink raw reply related

* Re: [PATCH v2 2/2] pinctrl: qcom: add the TLMM driver for the Nord platforms
From: Konrad Dybcio @ 2026-04-27 14:33 UTC (permalink / raw)
  To: Bartosz Golaszewski, Bjorn Andersson, Linus Walleij, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Richard Cochran,
	Bartosz Golaszewski, Shawn Guo, Arnd Bergmann, Dmitry Baryshkov
  Cc: linux-arm-msm, linux-gpio, devicetree, linux-kernel, netdev
In-Reply-To: <20260427-nord-tlmm-v2-2-ade8e0f3d803@oss.qualcomm.com>

On 4/27/26 4:00 PM, Bartosz Golaszewski wrote:
> Add support for the TLMM controller on the Qualcomm Nord platform.
> 
> Co-developed-by: Shawn Guo <shengchao.guo@oss.qualcomm.com>
> Signed-off-by: Shawn Guo <shengchao.guo@oss.qualcomm.com>
> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
> ---

[...]

> +	[177] = PINGROUP(177, ccu_async_in1, atest_char0, _, _, _, _, _, _, _, _, _),
> +	[178] = PINGROUP(178, ccu_async_in2, atest_char1, _, _, _, _, _, _, _, _, _),
> +	[179] = PINGROUP(179, ccu_async_in3, atest_char2, _, _, _, _, _, _, _, _, _),
> +	[180] = PINGROUP(180, ccu_async_in4, atest_char3, _, _, _, _, _, _, _, _, _),
> +	[181] = UFS_RESET(ufs_reset, 0xBD004),

lowercase hex, please

You'll also need to alter the macro definition - the CTL reg is where
you suggest, but the IO reg is at +0xbe000

Konrad

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox