From 62a3aa000055efcc86483e8953775943513fe44d Mon Sep 17 00:00:00 2001 From: Sneh Mankad Date: Wed, 10 Jun 2026 11:46:58 +0530 Subject: pinctrl: qcom: Avoid assigning unused private context in test cases tlmm_test_rising_while_disabled() sets thread_op_remain to 10, but this variable is only used by the threaded IRQ handler to control the number of GPIO pin toggles. Since tlmm_test_rising_while_disabled() does not register a threaded IRQ handler, the assignment is never used. Similarly, tlmm_test_high() and tlmm_test_low() set intr_op_remain to 9, but the variable is used to denote the IRQ handler the number of times GPIO signal has to be toggled from the hard IRQ handler. Since tlmm_test_high() and tlmm_test_low() themselves toggle the signal and do not require the hard IRQ handler to do it, the assignment is never used. Remove the thread_op_remain assignment from tlmm_test_rising_while_disabled() and intr_op_remain assignment from tlmm_test_high() and tlmm_test_low() test cases. This does not cause any change in functionality. Signed-off-by: Sneh Mankad Link: https://patch.msgid.link/20260610-tlmm_test_changes-v2-1-f34536da4717@oss.qualcomm.com Signed-off-by: Bartosz Golaszewski --- drivers/pinctrl/qcom/tlmm-test.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/pinctrl/qcom/tlmm-test.c b/drivers/pinctrl/qcom/tlmm-test.c index 007d6539cece..13c417731be7 100644 --- a/drivers/pinctrl/qcom/tlmm-test.c +++ b/drivers/pinctrl/qcom/tlmm-test.c @@ -273,7 +273,6 @@ static void tlmm_test_low(struct kunit *test) int i; priv->intr_op = TLMM_TEST_COUNT | TLMM_TEST_OUTPUT_HIGH; - atomic_set(&priv->intr_op_remain, 9); tlmm_output_high(); @@ -298,7 +297,6 @@ static void tlmm_test_high(struct kunit *test) int i; priv->intr_op = TLMM_TEST_COUNT | TLMM_TEST_OUTPUT_LOW; - atomic_set(&priv->intr_op_remain, 9); tlmm_output_low(); @@ -521,7 +519,6 @@ static void tlmm_test_rising_while_disabled(struct kunit *test) unsigned int before_edge; priv->intr_op = TLMM_TEST_COUNT; - atomic_set(&priv->thread_op_remain, 10); tlmm_output_low(); -- cgit v1.2.3 From 32bd01532af59cf0cc6994e2794e0aaa9af5bc8d Mon Sep 17 00:00:00 2001 From: Fenglin Wu Date: Wed, 10 Jun 2026 00:05:46 -0700 Subject: dt-bindings: pinctrl: qcom,pmic-gpio: Document PMG1110 GPIO support Update the binding documentation to include the compatible string for PMG1110 PMIC which is used on Maili platform. Signed-off-by: Fenglin Wu Reviewed-by: Krzysztof Kozlowski Reviewed-by: Linus Walleij Link: https://patch.msgid.link/20260610-pmg1110-gpio-v1-1-a9c50cd8b5d9@oss.qualcomm.com Signed-off-by: Bartosz Golaszewski --- Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.yaml index b8109e6c2a10..c27e24cb206f 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.yaml @@ -62,6 +62,7 @@ properties: - qcom,pmc8380-gpio - qcom,pmcx0102-gpio - qcom,pmd8028-gpio + - qcom,pmg1110-gpio - qcom,pmh0101-gpio - qcom,pmh0104-gpio - qcom,pmh0110-gpio @@ -155,6 +156,7 @@ allOf: - qcom,pm8450-gpio - qcom,pm8916-gpio - qcom,pmd8028-gpio + - qcom,pmg1110-gpio - qcom,pmk8350-gpio - qcom,pmr735a-gpio - qcom,pmr735b-gpio @@ -496,6 +498,7 @@ $defs: - gpio1-gpio22 for pma8084 - gpio1-gpio14 for pmcx0102 - gpio1-gpio4 for pmd8028 + - gpio1-gpio4 for pmg1110 - gpio1-gpio18 for pmh0101 - gpio1-gpio8 for pmh0104 - gpio1-gpio14 for pmh0110 -- cgit v1.2.3 From 8a762912365d4e7402fb8942934681acd0a3bcd6 Mon Sep 17 00:00:00 2001 From: Fenglin Wu Date: Wed, 10 Jun 2026 00:05:47 -0700 Subject: pinctrl: qcom: spmi-gpio: Add PMG1110 GPIO support Add PMG1110 GPIO support with its compatible string and match data. Reviewed-by: Konrad Dybcio Signed-off-by: Fenglin Wu Acked-by: Linus Walleij Reviewed-by: Dmitry Baryshkov Reviewed-by: Linus Walleij Link: https://patch.msgid.link/20260610-pmg1110-gpio-v1-2-a9c50cd8b5d9@oss.qualcomm.com Signed-off-by: Bartosz Golaszewski --- drivers/pinctrl/qcom/pinctrl-spmi-gpio.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c index cdd61dae74cf..922c27177b5a 100644 --- a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c +++ b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c @@ -1262,6 +1262,7 @@ static const struct of_device_id pmic_gpio_of_match[] = { { .compatible = "qcom,pmc8380-gpio", .data = (void *) 10 }, { .compatible = "qcom,pmcx0102-gpio", .data = (void *)14 }, { .compatible = "qcom,pmd8028-gpio", .data = (void *) 4 }, + { .compatible = "qcom,pmg1110-gpio", .data = (void *) 4 }, { .compatible = "qcom,pmh0101-gpio", .data = (void *)18 }, { .compatible = "qcom,pmh0104-gpio", .data = (void *)8 }, { .compatible = "qcom,pmh0110-gpio", .data = (void *)14 }, -- cgit v1.2.3 From 72323d7dc5118f5c7c269ff67797d342ed9effc7 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 23 Jun 2026 14:27:31 +0200 Subject: pinctrl: qcom: Drop unnecessary bitmap_fill() call Drop an unnecessary bitmap_fill() call from msm_gpio_irq_init_valid_mask(), this is unnecessary because gpiochip_allocate_mask() already does this. Signed-off-by: Hans de Goede Acked-by: Linus Walleij Reviewed-by: Konrad Dybcio Reviewed-by: Mukesh Ojha Link: https://patch.msgid.link/20260623122732.6439-1-johannes.goede@oss.qualcomm.com Signed-off-by: Bartosz Golaszewski --- drivers/pinctrl/qcom/pinctrl-msm.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c index 11db6564c44d..a035cb6a74fe 100644 --- a/drivers/pinctrl/qcom/pinctrl-msm.c +++ b/drivers/pinctrl/qcom/pinctrl-msm.c @@ -1035,8 +1035,6 @@ static void msm_gpio_irq_init_valid_mask(struct gpio_chip *gc, const struct msm_pingroup *g; int i; - bitmap_fill(valid_mask, ngpios); - for (i = 0; i < ngpios; i++) { g = &pctrl->soc->groups[i]; -- cgit v1.2.3 From e417d51c7f2ee08361b57a97869a2870bb417782 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 23 Jun 2026 14:27:32 +0200 Subject: pinctrl: qcom: Drop unused irq_data argument from msm_gpio_update_dual_edge_pos() The "struct irq_data *d" argument to msm_gpio_update_dual_edge_pos() is unused, drop it. Signed-off-by: Hans de Goede Acked-by: Linus Walleij Reviewed-by: Konrad Dybcio Reviewed-by: Mukesh Ojha Link: https://patch.msgid.link/20260623122732.6439-2-johannes.goede@oss.qualcomm.com Signed-off-by: Bartosz Golaszewski --- drivers/pinctrl/qcom/pinctrl-msm.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c index a035cb6a74fe..1055d42381bb 100644 --- a/drivers/pinctrl/qcom/pinctrl-msm.c +++ b/drivers/pinctrl/qcom/pinctrl-msm.c @@ -810,8 +810,7 @@ static const struct gpio_chip msm_gpio_template = { * Algorithm comes from Google's msmgpio driver. */ static void msm_gpio_update_dual_edge_pos(struct msm_pinctrl *pctrl, - const struct msm_pingroup *g, - struct irq_data *d) + const struct msm_pingroup *g) { int loop_limit = 100; unsigned val, val2, intstat; @@ -1005,7 +1004,7 @@ static void msm_gpio_irq_ack(struct irq_data *d) msm_ack_intr_status(pctrl, g); if (test_bit(d->hwirq, pctrl->dual_edge_irqs)) - msm_gpio_update_dual_edge_pos(pctrl, g, d); + msm_gpio_update_dual_edge_pos(pctrl, g); raw_spin_unlock_irqrestore(&pctrl->lock, flags); } @@ -1175,7 +1174,7 @@ static int msm_gpio_irq_set_type(struct irq_data *d, unsigned int type) msm_ack_intr_status(pctrl, g); if (test_bit(d->hwirq, pctrl->dual_edge_irqs)) - msm_gpio_update_dual_edge_pos(pctrl, g, d); + msm_gpio_update_dual_edge_pos(pctrl, g); raw_spin_unlock_irqrestore(&pctrl->lock, flags); -- cgit v1.2.3 From e95f2b212c4a8ec422b1627e36e951e778809965 Mon Sep 17 00:00:00 2001 From: Jingyi Wang Date: Mon, 22 Jun 2026 01:35:32 -0700 Subject: dt-bindings: pinctrl: qcom: Describe Maili TLMM block The Top Level Mode Multiplexer (TLMM) in the Qualcomm Maili SoC provides GPIO and pinctrl functionality for UFS, SDC and 226 GPIO pins. Add a DeviceTree binding to describe the TLMM block on Qualcomm's Maili SoC. Reviewed-by: Krzysztof Kozlowski Signed-off-by: Jingyi Wang Acked-by: Linus Walleij Link: https://patch.msgid.link/20260622-maili-pinctrl-v3-1-9724e1000471@oss.qualcomm.com Signed-off-by: Bartosz Golaszewski --- .../bindings/pinctrl/qcom,maili-tlmm.yaml | 120 +++++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 Documentation/devicetree/bindings/pinctrl/qcom,maili-tlmm.yaml diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,maili-tlmm.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,maili-tlmm.yaml new file mode 100644 index 000000000000..64fe90b2391b --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/qcom,maili-tlmm.yaml @@ -0,0 +1,120 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pinctrl/qcom,maili-tlmm.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm Technologies, Inc. Maili TLMM block + +maintainers: + - Jingyi Wang + +description: + Top Level Mode Multiplexer pin controller in Qualcomm Maili SoC. + +allOf: + - $ref: /schemas/pinctrl/qcom,tlmm-common.yaml# + +properties: + compatible: + const: qcom,maili-tlmm + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + gpio-reserved-ranges: + minItems: 1 + maxItems: 113 + + gpio-line-names: + maxItems: 226 + +patternProperties: + "-state$": + oneOf: + - $ref: "#/$defs/qcom-maili-tlmm-state" + - patternProperties: + "-pins$": + $ref: "#/$defs/qcom-maili-tlmm-state" + additionalProperties: false + +$defs: + qcom-maili-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-9][0-9]|20[0-9]|21[0-9]|22[0-5])$" + - enum: [ ufs_reset, sdc2_clk, sdc2_cmd, sdc2_data ] + minItems: 1 + maxItems: 36 + + function: + description: + Specify the alternative function to be configured for the specified + pins. + enum: [ gpio, aoss_cti, atest_char, atest_usb, audio_ext_mclk, + audio_ref_clk, cam_mclk, cci_async_in, cci_i2c0, cci_i2c1, + cci_i2c2, cci_i2c3, cci_timer, coex_espmi, coex_uart1_rx, + coex_uart1_tx, dbg_out_clk, ddr_bist, ddr_pxi, dp_hot, egpio, + gcc_gp, gnss_adc, host2wlan_sol, host_rst, i2chub0_se0, + i2chub0_se1, i2chub0_se2, i2chub0_se3, i2chub0_se4, i2s0, i2s1, + ibi_i3c, ibi_i3c_qup5_se0, jitter_bist, mdp_esync0, mdp_esync1, + mdp_esync2, mdp_vsync, mdp_vsync_e, mdp_vsync_p, mdp_vsync0_out, + mdp_vsync1_out, mdp_vsync2_out, mdp_vsync3_out, mdp_vsync5_out, + modem_pps_in, modem_pps_out, nav_gpio, nav_gpio0, nav_gpio3, + nav_rffe, pcie0_clk_req_n, pcie1_clk_req_n, pcie1_rst_n, + phase_flag, pll_bist_sync, pll_clk_aux, qdss_cti, qlink, qspi, + qspi_clk, qspi_cs, qup1_se0, qup1_se1, qup1_se2, qup1_se3, + qup1_se4, qup1_se5, qup1_se6, qup1_se7, qup2_se0, qup2_se1, + qup2_se2, qup2_se3, qup2_se4_01, qup2_se4_23, qup3_se0, + qup3_se1, qup3_se2, qup3_se3, qup3_se4, qup3_se5, qup4_se0, + qup4_se1, qup4_se2, qup4_se3_01, qup4_se3_23, qup4_se3_l3, + qup4_se4_01, qup4_se4_23, qup4_se4_l3, qup5_se0, rng_rosc, + sd_write_protect, sdc2_clk, sdc2_cmd, sdc2_data, sdc2_rclk, + sdc4_clk, sdc4_cmd, sdc4_data, sys_throttle, tb_trig_sdc, + tmess_rng, tsense_clm, tsense_pwm, uim0, uim1, usb0_hs, usb_phy, + vfr, vsense_trigger_mirnat, wcn_sw ] + + required: + - pins + +required: + - compatible + - reg + +unevaluatedProperties: false + +examples: + - | + #include + + tlmm: pinctrl@f100000 { + compatible = "qcom,maili-tlmm"; + reg = <0x0f100000 0x300000>; + interrupts = ; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&tlmm 0 0 227>; + interrupt-controller; + #interrupt-cells = <2>; + + qup-uart7-state { + pins = "gpio62", "gpio63"; + function = "qup1_se7"; + }; + }; +... -- cgit v1.2.3 From 251b53103a2e5770658ae106c490cdd2b7512c3a Mon Sep 17 00:00:00 2001 From: Jingyi Wang Date: Mon, 22 Jun 2026 01:35:33 -0700 Subject: pinctrl: qcom: Add the tlmm driver for Maili platform Add support for Maili TLMM configuration and control via the pinctrl framework. Reviewed-by: Dmitry Baryshkov Reviewed-by: Konrad Dybcio Signed-off-by: Jingyi Wang Acked-by: Linus Walleij Link: https://patch.msgid.link/20260622-maili-pinctrl-v3-2-9724e1000471@oss.qualcomm.com Signed-off-by: Bartosz Golaszewski --- drivers/pinctrl/qcom/Kconfig.msm | 10 + drivers/pinctrl/qcom/Makefile | 1 + drivers/pinctrl/qcom/pinctrl-maili.c | 1625 ++++++++++++++++++++++++++++++++++ 3 files changed, 1636 insertions(+) create mode 100644 drivers/pinctrl/qcom/pinctrl-maili.c diff --git a/drivers/pinctrl/qcom/Kconfig.msm b/drivers/pinctrl/qcom/Kconfig.msm index 9409e678ec6d..42875457b5fc 100644 --- a/drivers/pinctrl/qcom/Kconfig.msm +++ b/drivers/pinctrl/qcom/Kconfig.msm @@ -153,6 +153,16 @@ config PINCTRL_KAANAPALI Qualcomm Technologies Inc TLMM block found on the Qualcomm Technologies Inc Kaanapali platform. +config PINCTRL_MAILI + tristate "Qualcomm Technologies Inc Maili pin controller driver" + depends on ARM64 || COMPILE_TEST + default ARCH_QCOM + help + This is the pinctrl, pinmux, pinconf and gpiolib driver for the + Qualcomm Technologies Inc TLMM block found on the Maili platform. + Say Y here to compile statically, or M here to compile it as a module. + If unsure, say N. + config PINCTRL_MSM8226 tristate "Qualcomm 8226 pin controller driver" depends on ARM || COMPILE_TEST diff --git a/drivers/pinctrl/qcom/Makefile b/drivers/pinctrl/qcom/Makefile index 93cc4e7965ca..43ecd246afe8 100644 --- a/drivers/pinctrl/qcom/Makefile +++ b/drivers/pinctrl/qcom/Makefile @@ -17,6 +17,7 @@ obj-$(CONFIG_PINCTRL_IPQ6018) += pinctrl-ipq6018.o obj-$(CONFIG_PINCTRL_IPQ9574) += pinctrl-ipq9574.o obj-$(CONFIG_PINCTRL_IPQ9650) += pinctrl-ipq9650.o obj-$(CONFIG_PINCTRL_KAANAPALI) += pinctrl-kaanapali.o +obj-$(CONFIG_PINCTRL_MAILI) += pinctrl-maili.o obj-$(CONFIG_PINCTRL_MSM8226) += pinctrl-msm8226.o obj-$(CONFIG_PINCTRL_MSM8660) += pinctrl-msm8660.o obj-$(CONFIG_PINCTRL_MSM8960) += pinctrl-msm8960.o diff --git a/drivers/pinctrl/qcom/pinctrl-maili.c b/drivers/pinctrl/qcom/pinctrl-maili.c new file mode 100644 index 000000000000..ffa084cfad64 --- /dev/null +++ b/drivers/pinctrl/qcom/pinctrl-maili.c @@ -0,0 +1,1625 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include + +#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)), \ + .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, \ + .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, \ + } + +#define SDC_QDSD_PINGROUP(pg_name, ctl, pull, drv) \ + { \ + .grp = PINCTRL_PINGROUP(#pg_name, \ + pg_name##_pins, \ + ARRAY_SIZE(pg_name##_pins)), \ + .ctl_reg = ctl, \ + .io_reg = 0, \ + .intr_cfg_reg = 0, \ + .intr_status_reg = 0, \ + .mux_bit = -1, \ + .pull_bit = pull, \ + .drv_bit = drv, \ + .oe_bit = -1, \ + .in_bit = -1, \ + .out_bit = -1, \ + .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, \ + } + +#define UFS_RESET(pg_name, ctl, io) \ + { \ + .grp = PINCTRL_PINGROUP(#pg_name, \ + pg_name##_pins, \ + ARRAY_SIZE(pg_name##_pins)), \ + .ctl_reg = ctl, \ + .io_reg = io, \ + .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 maili_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, "GPIO_181"), + PINCTRL_PIN(182, "GPIO_182"), + PINCTRL_PIN(183, "GPIO_183"), + PINCTRL_PIN(184, "GPIO_184"), + PINCTRL_PIN(185, "GPIO_185"), + PINCTRL_PIN(186, "GPIO_186"), + PINCTRL_PIN(187, "GPIO_187"), + PINCTRL_PIN(188, "GPIO_188"), + PINCTRL_PIN(189, "GPIO_189"), + PINCTRL_PIN(190, "GPIO_190"), + PINCTRL_PIN(191, "GPIO_191"), + PINCTRL_PIN(192, "GPIO_192"), + PINCTRL_PIN(193, "GPIO_193"), + PINCTRL_PIN(194, "GPIO_194"), + PINCTRL_PIN(195, "GPIO_195"), + PINCTRL_PIN(196, "GPIO_196"), + PINCTRL_PIN(197, "GPIO_197"), + PINCTRL_PIN(198, "GPIO_198"), + PINCTRL_PIN(199, "GPIO_199"), + PINCTRL_PIN(200, "GPIO_200"), + PINCTRL_PIN(201, "GPIO_201"), + PINCTRL_PIN(202, "GPIO_202"), + PINCTRL_PIN(203, "GPIO_203"), + PINCTRL_PIN(204, "GPIO_204"), + PINCTRL_PIN(205, "GPIO_205"), + PINCTRL_PIN(206, "GPIO_206"), + PINCTRL_PIN(207, "GPIO_207"), + PINCTRL_PIN(208, "GPIO_208"), + PINCTRL_PIN(209, "GPIO_209"), + PINCTRL_PIN(210, "GPIO_210"), + PINCTRL_PIN(211, "GPIO_211"), + PINCTRL_PIN(212, "GPIO_212"), + PINCTRL_PIN(213, "GPIO_213"), + PINCTRL_PIN(214, "GPIO_214"), + PINCTRL_PIN(215, "GPIO_215"), + PINCTRL_PIN(216, "GPIO_216"), + PINCTRL_PIN(217, "GPIO_217"), + PINCTRL_PIN(218, "GPIO_218"), + PINCTRL_PIN(219, "GPIO_219"), + PINCTRL_PIN(220, "GPIO_220"), + PINCTRL_PIN(221, "GPIO_221"), + PINCTRL_PIN(222, "GPIO_222"), + PINCTRL_PIN(223, "GPIO_223"), + PINCTRL_PIN(224, "GPIO_224"), + PINCTRL_PIN(225, "GPIO_225"), + PINCTRL_PIN(226, "UFS_RESET"), + PINCTRL_PIN(227, "SDC2_CLK"), + PINCTRL_PIN(228, "SDC2_CMD"), + PINCTRL_PIN(229, "SDC2_DATA"), +}; + +#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); +DECLARE_MSM_GPIO_PINS(181); +DECLARE_MSM_GPIO_PINS(182); +DECLARE_MSM_GPIO_PINS(183); +DECLARE_MSM_GPIO_PINS(184); +DECLARE_MSM_GPIO_PINS(185); +DECLARE_MSM_GPIO_PINS(186); +DECLARE_MSM_GPIO_PINS(187); +DECLARE_MSM_GPIO_PINS(188); +DECLARE_MSM_GPIO_PINS(189); +DECLARE_MSM_GPIO_PINS(190); +DECLARE_MSM_GPIO_PINS(191); +DECLARE_MSM_GPIO_PINS(192); +DECLARE_MSM_GPIO_PINS(193); +DECLARE_MSM_GPIO_PINS(194); +DECLARE_MSM_GPIO_PINS(195); +DECLARE_MSM_GPIO_PINS(196); +DECLARE_MSM_GPIO_PINS(197); +DECLARE_MSM_GPIO_PINS(198); +DECLARE_MSM_GPIO_PINS(199); +DECLARE_MSM_GPIO_PINS(200); +DECLARE_MSM_GPIO_PINS(201); +DECLARE_MSM_GPIO_PINS(202); +DECLARE_MSM_GPIO_PINS(203); +DECLARE_MSM_GPIO_PINS(204); +DECLARE_MSM_GPIO_PINS(205); +DECLARE_MSM_GPIO_PINS(206); +DECLARE_MSM_GPIO_PINS(207); +DECLARE_MSM_GPIO_PINS(208); +DECLARE_MSM_GPIO_PINS(209); +DECLARE_MSM_GPIO_PINS(210); +DECLARE_MSM_GPIO_PINS(211); +DECLARE_MSM_GPIO_PINS(212); +DECLARE_MSM_GPIO_PINS(213); +DECLARE_MSM_GPIO_PINS(214); +DECLARE_MSM_GPIO_PINS(215); +DECLARE_MSM_GPIO_PINS(216); +DECLARE_MSM_GPIO_PINS(217); +DECLARE_MSM_GPIO_PINS(218); +DECLARE_MSM_GPIO_PINS(219); +DECLARE_MSM_GPIO_PINS(220); +DECLARE_MSM_GPIO_PINS(221); +DECLARE_MSM_GPIO_PINS(222); +DECLARE_MSM_GPIO_PINS(223); +DECLARE_MSM_GPIO_PINS(224); +DECLARE_MSM_GPIO_PINS(225); + +static const unsigned int ufs_reset_pins[] = { 226 }; +static const unsigned int sdc2_clk_pins[] = { 227 }; +static const unsigned int sdc2_cmd_pins[] = { 228 }; +static const unsigned int sdc2_data_pins[] = { 229 }; + +enum maili_functions { + msm_mux_gpio, + msm_mux_aoss_cti, + msm_mux_atest_char, + msm_mux_atest_usb, + msm_mux_audio_ext_mclk, + msm_mux_audio_ref_clk, + msm_mux_cam_mclk, + msm_mux_cci_async_in, + msm_mux_cci_i2c0, + msm_mux_cci_i2c1, + msm_mux_cci_i2c2, + msm_mux_cci_i2c3, + msm_mux_cci_timer, + msm_mux_coex_espmi, + msm_mux_coex_uart1_rx, + msm_mux_coex_uart1_tx, + msm_mux_dbg_out_clk, + msm_mux_ddr_bist, + msm_mux_ddr_pxi, + msm_mux_dp_hot, + msm_mux_egpio, + msm_mux_gcc_gp, + msm_mux_gnss_adc, + msm_mux_host2wlan_sol, + msm_mux_host_rst, + msm_mux_i2chub0_se0, + msm_mux_i2chub0_se1, + msm_mux_i2chub0_se2, + msm_mux_i2chub0_se3, + msm_mux_i2chub0_se4, + msm_mux_i2s0, + msm_mux_i2s1, + msm_mux_ibi_i3c, + msm_mux_ibi_i3c_qup5_se0, + msm_mux_jitter_bist, + msm_mux_mdp_esync0, + msm_mux_mdp_esync1, + msm_mux_mdp_esync2, + msm_mux_mdp_vsync, + msm_mux_mdp_vsync_e, + msm_mux_mdp_vsync_p, + msm_mux_mdp_vsync0_out, + msm_mux_mdp_vsync1_out, + msm_mux_mdp_vsync2_out, + msm_mux_mdp_vsync3_out, + msm_mux_mdp_vsync5_out, + msm_mux_modem_pps_in, + msm_mux_modem_pps_out, + msm_mux_nav_gpio, + msm_mux_nav_gpio0, + msm_mux_nav_gpio3, + msm_mux_nav_rffe, + msm_mux_pcie0_clk_req_n, + msm_mux_pcie1_clk_req_n, + msm_mux_pcie1_rst_n, + msm_mux_phase_flag, + msm_mux_pll_bist_sync, + msm_mux_pll_clk_aux, + msm_mux_qdss_cti, + msm_mux_qlink, + msm_mux_qspi, + msm_mux_qspi_clk, + msm_mux_qspi_cs, + 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_qup1_se7, + msm_mux_qup2_se0, + msm_mux_qup2_se1, + msm_mux_qup2_se2, + msm_mux_qup2_se3, + msm_mux_qup2_se4_01, + msm_mux_qup2_se4_23, + msm_mux_qup3_se0, + msm_mux_qup3_se1, + msm_mux_qup3_se2, + msm_mux_qup3_se3, + msm_mux_qup3_se4, + msm_mux_qup3_se5, + msm_mux_qup4_se0, + msm_mux_qup4_se1, + msm_mux_qup4_se2, + msm_mux_qup4_se3_01, + msm_mux_qup4_se3_23, + msm_mux_qup4_se3_l3, + msm_mux_qup4_se4_01, + msm_mux_qup4_se4_23, + msm_mux_qup4_se4_l3, + msm_mux_qup5_se0, + msm_mux_rng_rosc, + msm_mux_sd_write_protect, + msm_mux_sdc2_clk, + msm_mux_sdc2_cmd, + msm_mux_sdc2_data, + msm_mux_sdc2_rclk, + msm_mux_sdc4_clk, + msm_mux_sdc4_cmd, + msm_mux_sdc4_data, + msm_mux_sys_throttle, + msm_mux_tb_trig_sdc, + msm_mux_tmess_rng, + msm_mux_tsense_clm, + msm_mux_tsense_pwm, + msm_mux_uim0, + msm_mux_uim1, + msm_mux_usb0_hs, + msm_mux_usb_phy, + msm_mux_vfr, + msm_mux_vsense_trigger_mirnat, + msm_mux_wcn_sw, + 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", "gpio181", "gpio182", "gpio183", "gpio184", "gpio185", + "gpio186", "gpio187", "gpio188", "gpio189", "gpio190", "gpio191", + "gpio192", "gpio193", "gpio194", "gpio195", "gpio196", "gpio197", + "gpio198", "gpio199", "gpio200", "gpio201", "gpio202", "gpio203", + "gpio204", "gpio205", "gpio206", "gpio207", "gpio208", "gpio209", + "gpio210", "gpio211", "gpio212", "gpio213", "gpio214", "gpio215", + "gpio216", "gpio217", "gpio218", "gpio219", "gpio220", "gpio221", + "gpio222", "gpio223", "gpio224", "gpio225", +}; + +static const char *const aoss_cti_groups[] = { + "gpio74", "gpio75", "gpio76", "gpio77", +}; + +static const char *const atest_char_groups[] = { + "gpio126", "gpio127", "gpio128", "gpio129", "gpio133", +}; + +static const char *const atest_usb_groups[] = { + "gpio78", "gpio79", "gpio102", "gpio103", "gpio104", +}; + +static const char *const audio_ext_mclk_groups[] = { + "gpio120", "gpio121", +}; + +static const char *const audio_ref_clk_groups[] = { + "gpio120", +}; + +static const char *const cam_mclk_groups[] = { + "gpio90", "gpio91", "gpio92", "gpio93", "gpio94", "gpio95", +}; + +static const char *const cci_async_in_groups[] = { + "gpio15", "gpio109", "gpio110", +}; + +static const char *const cci_i2c0_groups[] = { + "gpio109", "gpio110", +}; + +static const char *const cci_i2c1_groups[] = { + "gpio111", "gpio112", +}; + +static const char *const cci_i2c2_groups[] = { + "gpio113", "gpio114", +}; + +static const char *const cci_i2c3_groups[] = { + "gpio107", "gpio160", +}; + +static const char *const cci_timer_groups[] = { + "gpio105", "gpio106", "gpio107", "gpio159", "gpio160", +}; + +static const char *const coex_espmi_groups[] = { + "gpio144", "gpio145", +}; + +static const char *const coex_uart1_rx_groups[] = { + "gpio144", +}; + +static const char *const coex_uart1_tx_groups[] = { + "gpio145", +}; + +static const char *const dbg_out_clk_groups[] = { + "gpio82", +}; + +static const char *const ddr_bist_groups[] = { + "gpio40", "gpio41", "gpio44", "gpio45", +}; + +static const char *const ddr_pxi_groups[] = { + "gpio66", "gpio67", "gpio68", "gpio69", "gpio70", "gpio71", "gpio72", "gpio73", +}; + +static const char *const dp_hot_groups[] = { + "gpio47", +}; + +static const char *const egpio_groups[] = { + "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5", + "gpio6", "gpio7", "gpio28", "gpio29", "gpio30", "gpio31", + "gpio48", "gpio49", "gpio50", "gpio51", "gpio163", "gpio164", + "gpio165", "gpio166", "gpio167", "gpio168", "gpio169", "gpio170", + "gpio171", "gpio172", "gpio173", "gpio174", "gpio175", "gpio176", + "gpio177", "gpio178", "gpio179", "gpio180", "gpio181", "gpio182", + "gpio183", "gpio184", "gpio185", "gpio186", "gpio187", "gpio188", + "gpio189", "gpio190", "gpio191", "gpio192", "gpio193", "gpio194", + "gpio195", "gpio196", "gpio197", "gpio198", "gpio199", "gpio200", + "gpio201", "gpio202", "gpio203", "gpio204", "gpio205", "gpio206", + "gpio207", "gpio208", "gpio209", "gpio212", "gpio213", "gpio214", + "gpio215", "gpio216", "gpio217", "gpio218", +}; + +static const char *const gcc_gp_groups[] = { + "gpio17", "gpio86", "gpio87", "gpio97", "gpio155", "gpio156", +}; + +static const char *const gnss_adc_groups[] = { + "gpio18", "gpio19", "gpio20", "gpio23", +}; + +static const char *const host2wlan_sol_groups[] = { + "gpio204", +}; + +static const char *const host_rst_groups[] = { + "gpio106", +}; + +static const char *const i2chub0_se0_groups[] = { + "gpio66", "gpio67", +}; + +static const char *const i2chub0_se1_groups[] = { + "gpio78", "gpio79", +}; + +static const char *const i2chub0_se2_groups[] = { + "gpio68", "gpio69", +}; + +static const char *const i2chub0_se3_groups[] = { + "gpio70", "gpio71", +}; + +static const char *const i2chub0_se4_groups[] = { + "gpio72", "gpio73", +}; + +static const char *const i2s0_groups[] = { + "gpio46", "gpio84", "gpio161", "gpio162", +}; + +static const char *const i2s1_groups[] = { + "gpio222", "gpio223", "gpio224", "gpio225", +}; + +static const char *const ibi_i3c_groups[] = { + "gpio0", "gpio1", "gpio4", "gpio5", "gpio8", "gpio9", + "gpio12", "gpio13", "gpio24", "gpio25", "gpio28", "gpio29", + "gpio32", "gpio33", "gpio36", "gpio37", "gpio48", "gpio49", + "gpio60", "gpio61", "gpio64", "gpio65", "gpio85", "gpio89", + "gpio117", "gpio118", +}; + +static const char *const ibi_i3c_qup5_se0_groups[] = { + "gpio8", "gpio9", +}; + +static const char *const jitter_bist_groups[] = { + "gpio73", +}; + +static const char *const mdp_esync0_groups[] = { + "gpio88", "gpio100", +}; + +static const char *const mdp_esync1_groups[] = { + "gpio86", "gpio100", +}; + +static const char *const mdp_esync2_groups[] = { + "gpio87", "gpio97", +}; + +static const char *const mdp_vsync_groups[] = { + "gpio86", "gpio87", "gpio88", "gpio97", +}; + +static const char *const mdp_vsync_e_groups[] = { + "gpio98", +}; + +static const char *const mdp_vsync_p_groups[] = { + "gpio98", +}; + +static const char *const mdp_vsync0_out_groups[] = { + "gpio86", +}; + +static const char *const mdp_vsync1_out_groups[] = { + "gpio86", +}; + +static const char *const mdp_vsync2_out_groups[] = { + "gpio87", +}; + +static const char *const mdp_vsync3_out_groups[] = { + "gpio87", +}; + +static const char *const mdp_vsync5_out_groups[] = { + "gpio87", +}; + +static const char *const modem_pps_in_groups[] = { + "gpio151", +}; + +static const char *const modem_pps_out_groups[] = { + "gpio151", +}; + +static const char *const nav_gpio_groups[] = { + "gpio146", "gpio147", "gpio148", "gpio151", +}; + +static const char *const nav_gpio0_groups[] = { + "gpio150", +}; + +static const char *const nav_gpio3_groups[] = { + "gpio150", +}; + +static const char *const nav_rffe_groups[] = { + "gpio134", "gpio135", "gpio138", "gpio139", +}; + +static const char *const pcie0_clk_req_n_groups[] = { + "gpio103", +}; + +static const char *const pcie1_clk_req_n_groups[] = { + "gpio221", +}; + +static const char *const pcie1_rst_n_groups[] = { + "gpio220", +}; + +static const char *const phase_flag_groups[] = { + "gpio40", "gpio41", "gpio44", "gpio45", "gpio46", "gpio47", "gpio126", + "gpio127", "gpio128", "gpio129", "gpio130", "gpio131", "gpio132", + "gpio133", "gpio161", "gpio162", "gpio169", "gpio170", "gpio171", + "gpio174", "gpio175", "gpio178", "gpio179", "gpio180", "gpio181", + "gpio182", "gpio183", "gpio205", "gpio222", "gpio223", "gpio224", + "gpio225", +}; + +static const char *const pll_bist_sync_groups[] = { + "gpio104", +}; + +static const char *const pll_clk_aux_groups[] = { + "gpio94", +}; + +static const char *const qdss_cti_groups[] = { + "gpio72", "gpio73", "gpio82", "gpio83", "gpio222", "gpio223", + "gpio224", "gpio225", +}; + +static const char *const qlink_groups[] = { + "gpio152", "gpio153", "gpio154", +}; + +static const char *const qspi_groups[] = { + "gpio80", "gpio81", "gpio82", "gpio147", +}; + +static const char *const qspi_clk_groups[] = { + "gpio83", +}; + +static const char *const qspi_cs_groups[] = { + "gpio146", "gpio148", +}; + +static const char *const qup1_se0_groups[] = { + "gpio222", "gpio223", "gpio224", "gpio225", +}; + +static const char *const qup1_se1_groups[] = { + "gpio74", "gpio75", "gpio76", "gpio77", "gpio188", "gpio189", "gpio192", "gpio193", +}; + +static const char *const qup1_se2_groups[] = { + "gpio40", "gpio41", "gpio42", "gpio43", "gpio130", "gpio131", "gpio132", +}; + +static const char *const qup1_se3_groups[] = { + "gpio44", "gpio45", "gpio46", "gpio47", +}; + +static const char *const qup1_se4_groups[] = { + "gpio36", "gpio37", "gpio38", "gpio39", +}; + +static const char *const qup1_se5_groups[] = { + "gpio52", "gpio53", "gpio54", "gpio55", +}; + +static const char *const qup1_se6_groups[] = { + "gpio56", "gpio57", "gpio58", "gpio59", +}; + +static const char *const qup1_se7_groups[] = { + "gpio60", "gpio61", "gpio62", "gpio63", +}; + +static const char *const qup2_se0_groups[] = { + "gpio0", "gpio1", "gpio2", "gpio3", +}; + +static const char *const qup2_se1_groups[] = { + "gpio4", "gpio5", "gpio6", "gpio7", +}; + +static const char *const qup2_se2_groups[] = { + "gpio117", "gpio118", "gpio119", "gpio120", +}; + +static const char *const qup2_se3_groups[] = { + "gpio97", "gpio122", "gpio123", "gpio124", "gpio125", +}; + +static const char *const qup2_se4_01_groups[] = { + "gpio208", "gpio209", +}; + +static const char *const qup2_se4_23_groups[] = { + "gpio208", "gpio209", +}; + +static const char *const qup3_se0_groups[] = { + "gpio64", "gpio65", "gpio66", "gpio67", "gpio82", "gpio83", +}; + +static const char *const qup3_se1_groups[] = { + "gpio8", "gpio9", "gpio10", "gpio11", "gpio12", "gpio13", "gpio15", +}; + +static const char *const qup3_se2_groups[] = { + "gpio12", "gpio13", "gpio14", "gpio15", +}; + +static const char *const qup3_se3_groups[] = { + "gpio16", "gpio17", "gpio18", "gpio19", +}; + +static const char *const qup3_se4_groups[] = { + "gpio20", "gpio21", "gpio22", "gpio23", +}; + +static const char *const qup3_se5_groups[] = { + "gpio24", "gpio25", "gpio26", "gpio27", +}; + +static const char *const qup4_se0_groups[] = { + "gpio48", "gpio49", "gpio50", "gpio51", +}; + +static const char *const qup4_se1_groups[] = { + "gpio28", "gpio29", "gpio30", "gpio31", +}; + +static const char *const qup4_se2_groups[] = { + "gpio32", "gpio33", "gpio34", "gpio35", +}; + +static const char *const qup4_se3_01_groups[] = { + "gpio84", "gpio121", +}; + +static const char *const qup4_se3_23_groups[] = { + "gpio84", "gpio121", +}; + +static const char *const qup4_se3_l3_groups[] = { + "gpio98", +}; + +static const char *const qup4_se4_01_groups[] = { + "gpio161", "gpio162", +}; + +static const char *const qup4_se4_23_groups[] = { + "gpio161", "gpio162", +}; + +static const char *const qup4_se4_l3_groups[] = { + "gpio88", +}; + +static const char *const qup5_se0_groups[] = { + "gpio8", "gpio9", "gpio10", "gpio11", "gpio12", "gpio13", "gpio14", + "gpio16", "gpio17", "gpio85", "gpio89", "gpio100", "gpio214", "gpio215", +}; + +static const char *const rng_rosc_groups[] = { + "gpio64", "gpio65", "gpio66", "gpio84", +}; + +static const char *const sd_write_protect_groups[] = { + "gpio85", +}; + +static const char *const sdc2_clk_groups[] = { + "gpio56", +}; + +static const char *const sdc2_cmd_groups[] = { + "gpio57", +}; + +static const char *const sdc2_data_groups[] = { + "gpio74", "gpio75", "gpio76", "gpio77", +}; + +static const char *const sdc2_rclk_groups[] = { + "gpio54", +}; + +static const char *const sdc4_clk_groups[] = { + "gpio83", +}; + +static const char *const sdc4_cmd_groups[] = { + "gpio148", +}; + +static const char *const sdc4_data_groups[] = { + "gpio80", "gpio81", "gpio82", "gpio147", +}; + +static const char *const sys_throttle_groups[] = { + "gpio99", +}; + +static const char *const tb_trig_sdc_groups[] = { + "gpio88", "gpio146", +}; + +static const char *const tmess_rng_groups[] = { + "gpio64", "gpio65", "gpio66", "gpio84", +}; + +static const char *const tsense_clm_groups[] = { + "gpio87", "gpio97", "gpio98", "gpio99", "gpio105", "gpio106", + "gpio159", +}; + +static const char *const tsense_pwm_groups[] = { + "gpio35", "gpio38", "gpio58", "gpio87", "gpio97", "gpio98", "gpio99", +}; + +static const char *const uim0_groups[] = { + "gpio126", "gpio127", "gpio128", "gpio129", +}; + +static const char *const uim1_groups[] = { + "gpio36", "gpio37", "gpio39", "gpio54", "gpio55", "gpio56", "gpio70", + "gpio71", "gpio72", "gpio130", "gpio131", "gpio132", "gpio133", +}; + +static const char *const usb0_hs_groups[] = { + "gpio79", +}; + +static const char *const usb_phy_groups[] = { + "gpio59", "gpio60", +}; + +static const char *const vfr_groups[] = { + "gpio146", "gpio151", +}; + +static const char *const vsense_trigger_mirnat_groups[] = { + "gpio16", +}; + +static const char *const wcn_sw_groups[] = { + "gpio18", "gpio19", "gpio155", "gpio156", +}; + +static const struct pinfunction maili_functions[] = { + MSM_GPIO_PIN_FUNCTION(gpio), + MSM_PIN_FUNCTION(aoss_cti), + MSM_PIN_FUNCTION(atest_char), + MSM_PIN_FUNCTION(atest_usb), + MSM_PIN_FUNCTION(audio_ext_mclk), + MSM_PIN_FUNCTION(audio_ref_clk), + MSM_PIN_FUNCTION(cam_mclk), + MSM_PIN_FUNCTION(cci_async_in), + MSM_PIN_FUNCTION(cci_i2c0), + MSM_PIN_FUNCTION(cci_i2c1), + MSM_PIN_FUNCTION(cci_i2c2), + MSM_PIN_FUNCTION(cci_i2c3), + MSM_PIN_FUNCTION(cci_timer), + MSM_PIN_FUNCTION(coex_espmi), + MSM_PIN_FUNCTION(coex_uart1_rx), + MSM_PIN_FUNCTION(coex_uart1_tx), + MSM_PIN_FUNCTION(dbg_out_clk), + MSM_PIN_FUNCTION(ddr_bist), + MSM_PIN_FUNCTION(ddr_pxi), + MSM_PIN_FUNCTION(dp_hot), + MSM_PIN_FUNCTION(egpio), + MSM_PIN_FUNCTION(gcc_gp), + MSM_PIN_FUNCTION(gnss_adc), + MSM_PIN_FUNCTION(host2wlan_sol), + MSM_PIN_FUNCTION(host_rst), + MSM_PIN_FUNCTION(i2chub0_se0), + MSM_PIN_FUNCTION(i2chub0_se1), + MSM_PIN_FUNCTION(i2chub0_se2), + MSM_PIN_FUNCTION(i2chub0_se3), + MSM_PIN_FUNCTION(i2chub0_se4), + MSM_PIN_FUNCTION(i2s0), + MSM_PIN_FUNCTION(i2s1), + MSM_PIN_FUNCTION(ibi_i3c), + MSM_PIN_FUNCTION(ibi_i3c_qup5_se0), + MSM_PIN_FUNCTION(jitter_bist), + MSM_PIN_FUNCTION(mdp_esync0), + MSM_PIN_FUNCTION(mdp_esync1), + MSM_PIN_FUNCTION(mdp_esync2), + MSM_PIN_FUNCTION(mdp_vsync), + MSM_PIN_FUNCTION(mdp_vsync_e), + MSM_PIN_FUNCTION(mdp_vsync_p), + MSM_PIN_FUNCTION(mdp_vsync0_out), + MSM_PIN_FUNCTION(mdp_vsync1_out), + MSM_PIN_FUNCTION(mdp_vsync2_out), + MSM_PIN_FUNCTION(mdp_vsync3_out), + MSM_PIN_FUNCTION(mdp_vsync5_out), + MSM_PIN_FUNCTION(modem_pps_in), + MSM_PIN_FUNCTION(modem_pps_out), + MSM_PIN_FUNCTION(nav_gpio), + MSM_PIN_FUNCTION(nav_gpio0), + MSM_PIN_FUNCTION(nav_gpio3), + MSM_PIN_FUNCTION(nav_rffe), + MSM_PIN_FUNCTION(pcie0_clk_req_n), + MSM_PIN_FUNCTION(pcie1_clk_req_n), + MSM_PIN_FUNCTION(pcie1_rst_n), + MSM_PIN_FUNCTION(phase_flag), + MSM_PIN_FUNCTION(pll_bist_sync), + MSM_PIN_FUNCTION(pll_clk_aux), + MSM_PIN_FUNCTION(qdss_cti), + MSM_PIN_FUNCTION(qlink), + MSM_PIN_FUNCTION(qspi), + MSM_PIN_FUNCTION(qspi_clk), + MSM_PIN_FUNCTION(qspi_cs), + 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(qup1_se7), + 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_01), + MSM_PIN_FUNCTION(qup2_se4_23), + MSM_PIN_FUNCTION(qup3_se0), + MSM_PIN_FUNCTION(qup3_se1), + MSM_PIN_FUNCTION(qup3_se2), + MSM_PIN_FUNCTION(qup3_se3), + MSM_PIN_FUNCTION(qup3_se4), + MSM_PIN_FUNCTION(qup3_se5), + MSM_PIN_FUNCTION(qup4_se0), + MSM_PIN_FUNCTION(qup4_se1), + MSM_PIN_FUNCTION(qup4_se2), + MSM_PIN_FUNCTION(qup4_se3_01), + MSM_PIN_FUNCTION(qup4_se3_23), + MSM_PIN_FUNCTION(qup4_se3_l3), + MSM_PIN_FUNCTION(qup4_se4_01), + MSM_PIN_FUNCTION(qup4_se4_23), + MSM_PIN_FUNCTION(qup4_se4_l3), + MSM_PIN_FUNCTION(qup5_se0), + MSM_PIN_FUNCTION(rng_rosc), + MSM_PIN_FUNCTION(sd_write_protect), + MSM_PIN_FUNCTION(sdc2_clk), + MSM_PIN_FUNCTION(sdc2_cmd), + MSM_PIN_FUNCTION(sdc2_data), + MSM_PIN_FUNCTION(sdc2_rclk), + MSM_PIN_FUNCTION(sdc4_clk), + MSM_PIN_FUNCTION(sdc4_cmd), + MSM_PIN_FUNCTION(sdc4_data), + MSM_PIN_FUNCTION(sys_throttle), + MSM_PIN_FUNCTION(tb_trig_sdc), + MSM_PIN_FUNCTION(tmess_rng), + MSM_PIN_FUNCTION(tsense_clm), + MSM_PIN_FUNCTION(tsense_pwm), + MSM_PIN_FUNCTION(uim0), + MSM_PIN_FUNCTION(uim1), + MSM_PIN_FUNCTION(usb0_hs), + MSM_PIN_FUNCTION(usb_phy), + MSM_PIN_FUNCTION(vfr), + MSM_PIN_FUNCTION(vsense_trigger_mirnat), + MSM_PIN_FUNCTION(wcn_sw), +}; + +static const struct msm_pingroup maili_groups[] = { + [0] = PINGROUP(0, qup2_se0, ibi_i3c, _, _, _, _, _, _, _, _, egpio), + [1] = PINGROUP(1, qup2_se0, ibi_i3c, _, _, _, _, _, _, _, _, egpio), + [2] = PINGROUP(2, qup2_se0, _, _, _, _, _, _, _, _, _, egpio), + [3] = PINGROUP(3, qup2_se0, _, _, _, _, _, _, _, _, _, egpio), + [4] = PINGROUP(4, qup2_se1, ibi_i3c, _, _, _, _, _, _, _, _, egpio), + [5] = PINGROUP(5, qup2_se1, ibi_i3c, _, _, _, _, _, _, _, _, egpio), + [6] = PINGROUP(6, qup2_se1, _, _, _, _, _, _, _, _, _, egpio), + [7] = PINGROUP(7, qup2_se1, _, _, _, _, _, _, _, _, _, egpio), + [8] = PINGROUP(8, qup3_se1, ibi_i3c, qup5_se0, ibi_i3c_qup5_se0, _, _, _, _, _, _, _), + [9] = PINGROUP(9, qup3_se1, ibi_i3c, qup5_se0, ibi_i3c_qup5_se0, _, _, _, _, _, _, _), + [10] = PINGROUP(10, qup3_se1, qup5_se0, _, _, _, _, _, _, _, _, _), + [11] = PINGROUP(11, qup3_se1, qup5_se0, _, _, _, _, _, _, _, _, _), + [12] = PINGROUP(12, qup3_se2, ibi_i3c, qup3_se1, qup5_se0, _, _, _, _, _, _, _), + [13] = PINGROUP(13, qup3_se2, ibi_i3c, qup3_se1, qup5_se0, _, _, _, _, _, _, _), + [14] = PINGROUP(14, qup3_se2, qup5_se0, _, _, _, _, _, _, _, _, _), + [15] = PINGROUP(15, qup3_se2, cci_async_in, qup3_se1, _, _, _, _, _, _, _, _), + [16] = PINGROUP(16, qup3_se3, qup5_se0, _, vsense_trigger_mirnat, _, _, _, _, _, _, _), + [17] = PINGROUP(17, qup3_se3, qup5_se0, gcc_gp, _, _, _, _, _, _, _, _), + [18] = PINGROUP(18, wcn_sw, qup3_se3, _, gnss_adc, _, _, _, _, _, _, _), + [19] = PINGROUP(19, wcn_sw, qup3_se3, _, gnss_adc, _, _, _, _, _, _, _), + [20] = PINGROUP(20, qup3_se4, _, gnss_adc, _, _, _, _, _, _, _, _), + [21] = PINGROUP(21, qup3_se4, _, _, _, _, _, _, _, _, _, _), + [22] = PINGROUP(22, qup3_se4, _, _, _, _, _, _, _, _, _, _), + [23] = PINGROUP(23, qup3_se4, _, gnss_adc, _, _, _, _, _, _, _, _), + [24] = PINGROUP(24, qup3_se5, ibi_i3c, _, _, _, _, _, _, _, _, _), + [25] = PINGROUP(25, qup3_se5, ibi_i3c, _, _, _, _, _, _, _, _, _), + [26] = PINGROUP(26, qup3_se5, _, _, _, _, _, _, _, _, _, _), + [27] = PINGROUP(27, qup3_se5, _, _, _, _, _, _, _, _, _, _), + [28] = PINGROUP(28, qup4_se1, ibi_i3c, _, _, _, _, _, _, _, _, egpio), + [29] = PINGROUP(29, qup4_se1, ibi_i3c, _, _, _, _, _, _, _, _, egpio), + [30] = PINGROUP(30, qup4_se1, _, _, _, _, _, _, _, _, _, egpio), + [31] = PINGROUP(31, qup4_se1, _, _, _, _, _, _, _, _, _, egpio), + [32] = PINGROUP(32, qup4_se2, ibi_i3c, _, _, _, _, _, _, _, _, _), + [33] = PINGROUP(33, qup4_se2, ibi_i3c, _, _, _, _, _, _, _, _, _), + [34] = PINGROUP(34, qup4_se2, _, _, _, _, _, _, _, _, _, _), + [35] = PINGROUP(35, qup4_se2, tsense_pwm, _, _, _, _, _, _, _, _, _), + [36] = PINGROUP(36, qup1_se4, uim1, ibi_i3c, _, _, _, _, _, _, _, _), + [37] = PINGROUP(37, qup1_se4, uim1, ibi_i3c, _, _, _, _, _, _, _, _), + [38] = PINGROUP(38, qup1_se4, tsense_pwm, _, _, _, _, _, _, _, _, _), + [39] = PINGROUP(39, qup1_se4, uim1, _, _, _, _, _, _, _, _, _), + [40] = PINGROUP(40, qup1_se2, ddr_bist, phase_flag, _, _, _, _, _, _, _, _), + [41] = PINGROUP(41, qup1_se2, ddr_bist, phase_flag, _, _, _, _, _, _, _, _), + [42] = PINGROUP(42, qup1_se2, _, _, _, _, _, _, _, _, _, _), + [43] = PINGROUP(43, qup1_se2, _, _, _, _, _, _, _, _, _, _), + [44] = PINGROUP(44, qup1_se3, ddr_bist, phase_flag, _, _, _, _, _, _, _, _), + [45] = PINGROUP(45, qup1_se3, ddr_bist, phase_flag, _, _, _, _, _, _, _, _), + [46] = PINGROUP(46, qup1_se3, i2s0, phase_flag, _, _, _, _, _, _, _, _), + [47] = PINGROUP(47, qup1_se3, dp_hot, phase_flag, _, _, _, _, _, _, _, _), + [48] = PINGROUP(48, qup4_se0, ibi_i3c, _, _, _, _, _, _, _, _, egpio), + [49] = PINGROUP(49, qup4_se0, ibi_i3c, _, _, _, _, _, _, _, _, egpio), + [50] = PINGROUP(50, qup4_se0, _, _, _, _, _, _, _, _, _, egpio), + [51] = PINGROUP(51, qup4_se0, _, _, _, _, _, _, _, _, _, egpio), + [52] = PINGROUP(52, qup1_se5, _, _, _, _, _, _, _, _, _, _), + [53] = PINGROUP(53, qup1_se5, _, _, _, _, _, _, _, _, _, _), + [54] = PINGROUP(54, qup1_se5, uim1, sdc2_rclk, _, _, _, _, _, _, _, _), + [55] = PINGROUP(55, qup1_se5, uim1, _, _, _, _, _, _, _, _, _), + [56] = PINGROUP(56, qup1_se6, uim1, sdc2_clk, _, _, _, _, _, _, _, _), + [57] = PINGROUP(57, qup1_se6, sdc2_cmd, _, _, _, _, _, _, _, _, _), + [58] = PINGROUP(58, qup1_se6, tsense_pwm, _, _, _, _, _, _, _, _, _), + [59] = PINGROUP(59, qup1_se6, usb_phy, _, _, _, _, _, _, _, _, _), + [60] = PINGROUP(60, qup1_se7, usb_phy, ibi_i3c, _, _, _, _, _, _, _, _), + [61] = PINGROUP(61, qup1_se7, ibi_i3c, _, _, _, _, _, _, _, _, _), + [62] = PINGROUP(62, qup1_se7, _, _, _, _, _, _, _, _, _, _), + [63] = PINGROUP(63, qup1_se7, _, _, _, _, _, _, _, _, _, _), + [64] = PINGROUP(64, qup3_se0, rng_rosc, tmess_rng, ibi_i3c, _, _, _, _, _, _, _), + [65] = PINGROUP(65, qup3_se0, rng_rosc, tmess_rng, ibi_i3c, _, _, _, _, _, _, _), + [66] = PINGROUP(66, i2chub0_se0, qup3_se0, rng_rosc, tmess_rng, _, ddr_pxi, _, _, _, _, _), + [67] = PINGROUP(67, i2chub0_se0, qup3_se0, _, ddr_pxi, _, _, _, _, _, _, _), + [68] = PINGROUP(68, i2chub0_se2, _, ddr_pxi, _, _, _, _, _, _, _, _), + [69] = PINGROUP(69, i2chub0_se2, _, ddr_pxi, _, _, _, _, _, _, _, _), + [70] = PINGROUP(70, i2chub0_se3, uim1, _, _, ddr_pxi, _, _, _, _, _, _), + [71] = PINGROUP(71, i2chub0_se3, uim1, _, _, ddr_pxi, _, _, _, _, _, _), + [72] = PINGROUP(72, i2chub0_se4, uim1, qdss_cti, _, ddr_pxi, _, _, _, _, _, _), + [73] = PINGROUP(73, i2chub0_se4, qdss_cti, jitter_bist, ddr_pxi, _, _, _, _, _, _, _), + [74] = PINGROUP(74, qup1_se1, aoss_cti, sdc2_data, _, _, _, _, _, _, _, _), + [75] = PINGROUP(75, qup1_se1, aoss_cti, sdc2_data, _, _, _, _, _, _, _, _), + [76] = PINGROUP(76, qup1_se1, aoss_cti, sdc2_data, _, _, _, _, _, _, _, _), + [77] = PINGROUP(77, qup1_se1, aoss_cti, sdc2_data, _, _, _, _, _, _, _, _), + [78] = PINGROUP(78, i2chub0_se1, _, atest_usb, _, _, _, _, _, _, _, _), + [79] = PINGROUP(79, i2chub0_se1, usb0_hs, _, atest_usb, _, _, _, _, _, _, _), + [80] = PINGROUP(80, sdc4_data, qspi, _, _, _, _, _, _, _, _, _), + [81] = PINGROUP(81, sdc4_data, qspi, _, _, _, _, _, _, _, _, _), + [82] = PINGROUP(82, sdc4_data, qdss_cti, qspi, qup3_se0, dbg_out_clk, _, _, _, _, _, _), + [83] = PINGROUP(83, sdc4_clk, qdss_cti, qspi_clk, qup3_se0, _, _, _, _, _, _, _), + [84] = PINGROUP(84, qup4_se3_01, qup4_se3_23, rng_rosc, tmess_rng, i2s0, _, _, _, _, _, _), + [85] = PINGROUP(85, sd_write_protect, qup5_se0, ibi_i3c, _, _, _, _, _, _, _, _), + [86] = PINGROUP(86, mdp_vsync, mdp_vsync0_out, mdp_vsync1_out, mdp_esync1, gcc_gp, + _, _, _, _, _, _), + [87] = PINGROUP(87, mdp_vsync, mdp_vsync2_out, mdp_vsync3_out, mdp_vsync5_out, mdp_esync2, + gcc_gp, tsense_clm, tsense_pwm, _, _, _), + [88] = PINGROUP(88, mdp_esync0, mdp_vsync, qup4_se4_l3, tb_trig_sdc, _, _, _, _, _, _, _), + [89] = PINGROUP(89, qup5_se0, ibi_i3c, _, _, _, _, _, _, _, _, _), + [90] = PINGROUP(90, cam_mclk, _, _, _, _, _, _, _, _, _, _), + [91] = PINGROUP(91, cam_mclk, _, _, _, _, _, _, _, _, _, _), + [92] = PINGROUP(92, cam_mclk, _, _, _, _, _, _, _, _, _, _), + [93] = PINGROUP(93, cam_mclk, _, _, _, _, _, _, _, _, _, _), + [94] = PINGROUP(94, cam_mclk, pll_clk_aux, _, _, _, _, _, _, _, _, _), + [95] = PINGROUP(95, cam_mclk, _, _, _, _, _, _, _, _, _, _), + [96] = PINGROUP(96, _, _, _, _, _, _, _, _, _, _, _), + [97] = PINGROUP(97, mdp_esync2, qup2_se3, mdp_vsync, gcc_gp, tsense_clm, tsense_pwm, + _, _, _, _, _), + [98] = PINGROUP(98, mdp_vsync_e, qup4_se3_l3, mdp_vsync_p, tsense_clm, tsense_pwm, + _, _, _, _, _, _), + [99] = PINGROUP(99, sys_throttle, tsense_clm, tsense_pwm, _, _, _, _, _, _, _, _), + [100] = PINGROUP(100, mdp_esync1, mdp_esync0, qup5_se0, _, _, _, _, _, _, _, _), + [101] = PINGROUP(101, _, _, _, _, _, _, _, _, _, _, _), + [102] = PINGROUP(102, atest_usb, _, _, _, _, _, _, _, _, _, _), + [103] = PINGROUP(103, pcie0_clk_req_n, atest_usb, _, _, _, _, _, _, _, _, _), + [104] = PINGROUP(104, pll_bist_sync, atest_usb, _, _, _, _, _, _, _, _, _), + [105] = PINGROUP(105, cci_timer, tsense_clm, _, _, _, _, _, _, _, _, _), + [106] = PINGROUP(106, host_rst, cci_timer, tsense_clm, _, _, _, _, _, _, _, _), + [107] = PINGROUP(107, cci_i2c3, cci_timer, _, _, _, _, _, _, _, _, _), + [108] = PINGROUP(108, _, _, _, _, _, _, _, _, _, _, _), + [109] = PINGROUP(109, cci_i2c0, cci_async_in, _, _, _, _, _, _, _, _, _), + [110] = PINGROUP(110, cci_i2c0, cci_async_in, _, _, _, _, _, _, _, _, _), + [111] = PINGROUP(111, cci_i2c1, _, _, _, _, _, _, _, _, _, _), + [112] = PINGROUP(112, cci_i2c1, _, _, _, _, _, _, _, _, _, _), + [113] = PINGROUP(113, cci_i2c2, _, _, _, _, _, _, _, _, _, _), + [114] = PINGROUP(114, cci_i2c2, _, _, _, _, _, _, _, _, _, _), + [115] = PINGROUP(115, _, _, _, _, _, _, _, _, _, _, _), + [116] = PINGROUP(116, _, _, _, _, _, _, _, _, _, _, _), + [117] = PINGROUP(117, qup2_se2, ibi_i3c, _, _, _, _, _, _, _, _, _), + [118] = PINGROUP(118, qup2_se2, ibi_i3c, _, _, _, _, _, _, _, _, _), + [119] = PINGROUP(119, qup2_se2, _, _, _, _, _, _, _, _, _, _), + [120] = PINGROUP(120, qup2_se2, audio_ext_mclk, audio_ref_clk, _, _, _, _, _, _, _, _), + [121] = PINGROUP(121, audio_ext_mclk, qup4_se3_01, qup4_se3_23, _, _, _, _, _, _, _, _), + [122] = PINGROUP(122, qup2_se3, _, _, _, _, _, _, _, _, _, _), + [123] = PINGROUP(123, qup2_se3, _, _, _, _, _, _, _, _, _, _), + [124] = PINGROUP(124, qup2_se3, _, _, _, _, _, _, _, _, _, _), + [125] = PINGROUP(125, qup2_se3, _, _, _, _, _, _, _, _, _, _), + [126] = PINGROUP(126, uim0, phase_flag, _, atest_char, _, _, _, _, _, _, _), + [127] = PINGROUP(127, uim0, phase_flag, _, atest_char, _, _, _, _, _, _, _), + [128] = PINGROUP(128, uim0, phase_flag, _, atest_char, _, _, _, _, _, _, _), + [129] = PINGROUP(129, uim0, phase_flag, _, atest_char, _, _, _, _, _, _, _), + [130] = PINGROUP(130, uim1, qup1_se2, _, phase_flag, _, _, _, _, _, _, _), + [131] = PINGROUP(131, uim1, qup1_se2, _, phase_flag, _, _, _, _, _, _, _), + [132] = PINGROUP(132, uim1, qup1_se2, _, phase_flag, _, _, _, _, _, _, _), + [133] = PINGROUP(133, uim1, phase_flag, _, atest_char, _, _, _, _, _, _, _), + [134] = PINGROUP(134, _, _, nav_rffe, _, _, _, _, _, _, _, _), + [135] = PINGROUP(135, _, _, nav_rffe, _, _, _, _, _, _, _, _), + [136] = PINGROUP(136, _, _, _, _, _, _, _, _, _, _, _), + [137] = PINGROUP(137, _, _, _, _, _, _, _, _, _, _, _), + [138] = PINGROUP(138, _, _, nav_rffe, _, _, _, _, _, _, _, _), + [139] = PINGROUP(139, _, _, nav_rffe, _, _, _, _, _, _, _, _), + [140] = PINGROUP(140, _, _, _, _, _, _, _, _, _, _, _), + [141] = PINGROUP(141, _, _, _, _, _, _, _, _, _, _, _), + [142] = PINGROUP(142, _, _, _, _, _, _, _, _, _, _, _), + [143] = PINGROUP(143, _, _, _, _, _, _, _, _, _, _, _), + [144] = PINGROUP(144, coex_uart1_rx, coex_espmi, _, _, _, _, _, _, _, _, _), + [145] = PINGROUP(145, coex_uart1_tx, coex_espmi, _, _, _, _, _, _, _, _, _), + [146] = PINGROUP(146, _, vfr, nav_gpio, tb_trig_sdc, qspi_cs, _, _, _, _, _, _), + [147] = PINGROUP(147, _, nav_gpio, sdc4_data, qspi, _, _, _, _, _, _, _), + [148] = PINGROUP(148, nav_gpio, _, sdc4_cmd, qspi_cs, _, _, _, _, _, _, _), + [149] = PINGROUP(149, _, _, _, _, _, _, _, _, _, _, _), + [150] = PINGROUP(150, nav_gpio0, nav_gpio3, _, _, _, _, _, _, _, _, _), + [151] = PINGROUP(151, nav_gpio, vfr, modem_pps_in, modem_pps_out, _, _, _, _, _, _, _), + [152] = PINGROUP(152, qlink, _, _, _, _, _, _, _, _, _, _), + [153] = PINGROUP(153, qlink, _, _, _, _, _, _, _, _, _, _), + [154] = PINGROUP(154, qlink, _, _, _, _, _, _, _, _, _, _), + [155] = PINGROUP(155, wcn_sw, gcc_gp, _, _, _, _, _, _, _, _, _), + [156] = PINGROUP(156, wcn_sw, gcc_gp, _, _, _, _, _, _, _, _, _), + [157] = PINGROUP(157, _, _, _, _, _, _, _, _, _, _, _), + [158] = PINGROUP(158, _, _, _, _, _, _, _, _, _, _, _), + [159] = PINGROUP(159, cci_timer, tsense_clm, _, _, _, _, _, _, _, _, _), + [160] = PINGROUP(160, cci_timer, cci_i2c3, _, _, _, _, _, _, _, _, _), + [161] = PINGROUP(161, qup4_se4_01, qup4_se4_23, i2s0, phase_flag, _, _, _, _, _, _, _), + [162] = PINGROUP(162, qup4_se4_01, qup4_se4_23, i2s0, phase_flag, _, _, _, _, _, _, _), + [163] = PINGROUP(163, _, _, _, _, _, _, _, _, _, _, egpio), + [164] = PINGROUP(164, _, _, _, _, _, _, _, _, _, _, egpio), + [165] = PINGROUP(165, _, _, _, _, _, _, _, _, _, _, egpio), + [166] = PINGROUP(166, _, _, _, _, _, _, _, _, _, _, egpio), + [167] = PINGROUP(167, _, _, _, _, _, _, _, _, _, _, egpio), + [168] = PINGROUP(168, _, _, _, _, _, _, _, _, _, _, egpio), + [169] = PINGROUP(169, phase_flag, _, _, _, _, _, _, _, _, _, egpio), + [170] = PINGROUP(170, phase_flag, _, _, _, _, _, _, _, _, _, egpio), + [171] = PINGROUP(171, phase_flag, _, _, _, _, _, _, _, _, _, egpio), + [172] = PINGROUP(172, _, _, _, _, _, _, _, _, _, _, egpio), + [173] = PINGROUP(173, _, _, _, _, _, _, _, _, _, _, egpio), + [174] = PINGROUP(174, phase_flag, _, _, _, _, _, _, _, _, _, egpio), + [175] = PINGROUP(175, phase_flag, _, _, _, _, _, _, _, _, _, egpio), + [176] = PINGROUP(176, _, _, _, _, _, _, _, _, _, _, egpio), + [177] = PINGROUP(177, _, _, _, _, _, _, _, _, _, _, egpio), + [178] = PINGROUP(178, phase_flag, _, _, _, _, _, _, _, _, _, egpio), + [179] = PINGROUP(179, phase_flag, _, _, _, _, _, _, _, _, _, egpio), + [180] = PINGROUP(180, phase_flag, _, _, _, _, _, _, _, _, _, egpio), + [181] = PINGROUP(181, phase_flag, _, _, _, _, _, _, _, _, _, egpio), + [182] = PINGROUP(182, phase_flag, _, _, _, _, _, _, _, _, _, egpio), + [183] = PINGROUP(183, phase_flag, _, _, _, _, _, _, _, _, _, egpio), + [184] = PINGROUP(184, _, _, _, _, _, _, _, _, _, _, egpio), + [185] = PINGROUP(185, _, _, _, _, _, _, _, _, _, _, egpio), + [186] = PINGROUP(186, _, _, _, _, _, _, _, _, _, _, egpio), + [187] = PINGROUP(187, _, _, _, _, _, _, _, _, _, _, egpio), + [188] = PINGROUP(188, qup1_se1, _, _, _, _, _, _, _, _, _, egpio), + [189] = PINGROUP(189, qup1_se1, _, _, _, _, _, _, _, _, _, egpio), + [190] = PINGROUP(190, _, _, _, _, _, _, _, _, _, _, egpio), + [191] = PINGROUP(191, _, _, _, _, _, _, _, _, _, _, egpio), + [192] = PINGROUP(192, qup1_se1, _, _, _, _, _, _, _, _, _, egpio), + [193] = PINGROUP(193, qup1_se1, _, _, _, _, _, _, _, _, _, egpio), + [194] = PINGROUP(194, _, _, _, _, _, _, _, _, _, _, egpio), + [195] = PINGROUP(195, _, _, _, _, _, _, _, _, _, _, egpio), + [196] = PINGROUP(196, _, _, _, _, _, _, _, _, _, _, egpio), + [197] = PINGROUP(197, _, _, _, _, _, _, _, _, _, _, egpio), + [198] = PINGROUP(198, _, _, _, _, _, _, _, _, _, _, egpio), + [199] = PINGROUP(199, _, _, _, _, _, _, _, _, _, _, egpio), + [200] = PINGROUP(200, _, _, _, _, _, _, _, _, _, _, egpio), + [201] = PINGROUP(201, _, _, _, _, _, _, _, _, _, _, egpio), + [202] = PINGROUP(202, _, _, _, _, _, _, _, _, _, _, egpio), + [203] = PINGROUP(203, _, _, _, _, _, _, _, _, _, _, egpio), + [204] = PINGROUP(204, host2wlan_sol, _, _, _, _, _, _, _, _, _, egpio), + [205] = PINGROUP(205, phase_flag, _, _, _, _, _, _, _, _, _, egpio), + [206] = PINGROUP(206, _, _, _, _, _, _, _, _, _, _, egpio), + [207] = PINGROUP(207, _, _, _, _, _, _, _, _, _, _, egpio), + [208] = PINGROUP(208, qup2_se4_01, qup2_se4_23, _, _, _, _, _, _, _, _, egpio), + [209] = PINGROUP(209, qup2_se4_01, qup2_se4_23, _, _, _, _, _, _, _, _, egpio), + [210] = PINGROUP(210, _, _, _, _, _, _, _, _, _, _, _), + [211] = PINGROUP(211, _, _, _, _, _, _, _, _, _, _, _), + [212] = PINGROUP(212, _, _, _, _, _, _, _, _, _, _, egpio), + [213] = PINGROUP(213, _, _, _, _, _, _, _, _, _, _, egpio), + [214] = PINGROUP(214, qup5_se0, _, _, _, _, _, _, _, _, _, egpio), + [215] = PINGROUP(215, qup5_se0, _, _, _, _, _, _, _, _, _, egpio), + [216] = PINGROUP(216, _, _, _, _, _, _, _, _, _, _, egpio), + [217] = PINGROUP(217, _, _, _, _, _, _, _, _, _, _, egpio), + [218] = PINGROUP(218, _, _, _, _, _, _, _, _, _, _, egpio), + [219] = PINGROUP(219, _, _, _, _, _, _, _, _, _, _, _), + [220] = PINGROUP(220, pcie1_rst_n, _, _, _, _, _, _, _, _, _, _), + [221] = PINGROUP(221, pcie1_clk_req_n, _, _, _, _, _, _, _, _, _, _), + [222] = PINGROUP(222, qup1_se0, i2s1, qdss_cti, phase_flag, _, _, _, _, _, _, _), + [223] = PINGROUP(223, qup1_se0, i2s1, qdss_cti, phase_flag, _, _, _, _, _, _, _), + [224] = PINGROUP(224, qup1_se0, i2s1, qdss_cti, phase_flag, _, _, _, _, _, _, _), + [225] = PINGROUP(225, qup1_se0, i2s1, qdss_cti, phase_flag, _, _, _, _, _, _, _), + [226] = UFS_RESET(ufs_reset, 0xf1004, 0xf2000), + [227] = SDC_QDSD_PINGROUP(sdc2_clk, 0xe6000, 14, 6), + [228] = SDC_QDSD_PINGROUP(sdc2_cmd, 0xe6000, 11, 3), + [229] = SDC_QDSD_PINGROUP(sdc2_data, 0xe6000, 9, 0), +}; + +static const struct msm_gpio_wakeirq_map maili_pdc_map[] = { + { 0, 111 }, { 3, 119 }, { 4, 112 }, { 7, 113 }, { 8, 114 }, { 11, 115 }, + { 12, 121 }, { 15, 137 }, { 16, 122 }, { 17, 147 }, { 18, 149 }, { 19, 118 }, + { 23, 123 }, { 24, 124 }, { 27, 125 }, { 28, 131 }, { 31, 132 }, { 32, 133 }, + { 35, 107 }, { 36, 134 }, { 39, 135 }, { 43, 136 }, { 47, 160 }, { 48, 141 }, + { 51, 120 }, { 55, 110 }, { 57, 142 }, { 58, 143 }, { 59, 144 }, { 60, 145 }, + { 61, 151 }, { 63, 130 }, { 64, 116 }, { 65, 129 }, { 67, 138 }, { 68, 152 }, + { 69, 153 }, { 75, 157 }, { 77, 154 }, { 78, 155 }, { 79, 161 }, { 80, 162 }, + { 81, 163 }, { 82, 164 }, { 83, 171 }, { 84, 140 }, { 85, 165 }, { 86, 166 }, + { 87, 167 }, { 88, 168 }, { 95, 169 }, { 96, 170 }, { 97, 139 }, { 98, 156 }, + { 99, 117 }, { 100, 199 }, { 103, 173 }, { 104, 174 }, { 117, 201 }, { 120, 175 }, + { 123, 176 }, { 125, 177 }, { 129, 159 }, { 133, 106 }, { 144, 178 }, { 146, 179 }, + { 151, 180 }, { 152, 181 }, { 155, 128 }, { 158, 126 }, { 162, 148 }, { 164, 182 }, + { 165, 183 }, { 167, 184 }, { 168, 185 }, { 174, 186 }, { 177, 187 }, { 179, 188 }, + { 183, 189 }, { 184, 190 }, { 185, 191 }, { 186, 158 }, { 188, 150 }, { 202, 108 }, + { 203, 109 }, { 205, 146 }, { 209, 192 }, { 213, 127 }, { 215, 200 }, { 216, 193 }, + { 220, 172 }, { 221, 194 }, { 222, 195 }, { 223, 196 }, { 224, 197 }, { 225, 198 }, +}; + +static const struct msm_pinctrl_soc_data maili_tlmm = { + .pins = maili_pins, + .npins = ARRAY_SIZE(maili_pins), + .functions = maili_functions, + .nfunctions = ARRAY_SIZE(maili_functions), + .groups = maili_groups, + .ngroups = ARRAY_SIZE(maili_groups), + .ngpios = 227, + .wakeirq_map = maili_pdc_map, + .nwakeirq_map = ARRAY_SIZE(maili_pdc_map), + .egpio_func = 11, +}; + +static const struct of_device_id maili_tlmm_of_match[] = { + { .compatible = "qcom,maili-tlmm", }, + {}, +}; +MODULE_DEVICE_TABLE(of, maili_tlmm_of_match); + +static int maili_tlmm_probe(struct platform_device *pdev) +{ + return msm_pinctrl_probe(pdev, &maili_tlmm); +} + +static struct platform_driver maili_tlmm_driver = { + .driver = { + .name = "maili-tlmm", + .of_match_table = maili_tlmm_of_match, + }, + .probe = maili_tlmm_probe, +}; + +static int __init maili_tlmm_init(void) +{ + return platform_driver_register(&maili_tlmm_driver); +} +arch_initcall(maili_tlmm_init); + +static void __exit maili_tlmm_exit(void) +{ + platform_driver_unregister(&maili_tlmm_driver); +} +module_exit(maili_tlmm_exit); + +MODULE_DESCRIPTION("Qualcomm Maili TLMM driver"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 83e089ef0d4e045efa743dcbc8de5ea0a9e4195d Mon Sep 17 00:00:00 2001 From: Maulik Shah Date: Tue, 7 Jul 2026 14:51:33 +0530 Subject: irqchip/qcom-pdc: Restructure version support The PDC irqchip driver updates IRQ_ENABLE and IRQ_CFG for three different versions v2.7, v3.0 and v3.2. These registers are organized in hardware as below on various SoCs: +---------------------------------------------------------------+ | SM8350, SM8450 | SM8550, Hamoa | SM8650, SM8750 | |---------------------------------------------------------------| | v2.7 | v3.0 | v3.2 | |---------------------------------------------------------------| | IRQ_ENABLE_BANK | IRQ_ENABLE_BANK | NA | |---------------------------------------------------------------| | IRQ_CFG | IRQ_CFG | IRQ_CFG | | | | | | | | [31:6] Unused | | | [31:5] Unused | [5] GPIO_STATUS | | | [4] GPIO_STATUS| [4] GPIO_MASK | | [31:3] Unused | [3] GPIO_MASK | [3] IRQ_ENABLE | | [0:2] Type | [0:2] Type | [0:2] Type | +---------------------------------------------------------------| All SoCs PDC chips support "pass through mode" in which all interrupts are forwarded to the GIC without any latching in the PDC hardware. So far the driver did not utilize GPIO_STATUS and GPIO_MASK from IRQ_CFG register for v3.0 and v3.2 since they are only needed to be configured when PDC runs in a specific mode named "second level interrupt controller". In that mode it can latch the GPIO interrupts in GPIO_STATUS and forward GPIO interrupts to GIC as LEVEL_HIGH type SPI interrupt. All the SoCs defaulted to pass through mode with the exception of some x1e types. x1e PDC may be set to secondary controller mode for builds on CRD boards whereas it may be set to pass through mode for IoT-EVK boards. Restructure in preparation to add the second level interrupt controller mode utilizing GPIO_STATUS and GPIO_MASK bits which changed the bit positions between v3.0 and v3.2. No functional change intended. [ tglx: Massaged change log ] Signed-off-by: Maulik Shah Signed-off-by: Thomas Gleixner Reviewed-by: Konrad Dybcio Link: https://patch.msgid.link/20260707-hamoa_pdc_v3-v4-1-dfd1f4a3ae89@oss.qualcomm.com --- drivers/irqchip/qcom-pdc.c | 224 +++++++++++++++++++++++++++++++-------------- 1 file changed, 154 insertions(+), 70 deletions(-) diff --git a/drivers/irqchip/qcom-pdc.c b/drivers/irqchip/qcom-pdc.c index 2014dbb0bc43..3d272a8e506e 100644 --- a/drivers/irqchip/qcom-pdc.c +++ b/drivers/irqchip/qcom-pdc.c @@ -21,21 +21,12 @@ #include #include -#define PDC_MAX_GPIO_IRQS 256 -#define PDC_DRV_SIZE 0x10000 - -/* Valid only on HW version < 3.2 */ -#define IRQ_ENABLE_BANK 0x10 -#define IRQ_ENABLE_BANK_MAX (IRQ_ENABLE_BANK + BITS_TO_BYTES(PDC_MAX_GPIO_IRQS)) +#define PDC_MAX_IRQS 256 +#define IRQ_ENABLE_BANK_MAX BITS_TO_BYTES(PDC_MAX_IRQS) #define IRQ_ENABLE_BANK_INDEX_MASK GENMASK(31, 5) #define IRQ_ENABLE_BANK_BIT_MASK GENMASK(4, 0) -#define IRQ_i_CFG 0x110 - -/* Valid only on HW version >= 3.2 */ -#define IRQ_i_CFG_IRQ_ENABLE 3 - -#define IRQ_i_CFG_TYPE_MASK GENMASK(2, 0) +#define PDC_DRV_SIZE 0x10000 #define PDC_VERSION_REG 0x1000 #define PDC_VERSION_MAJOR GENMASK(23, 16) #define PDC_VERSION_MINOR GENMASK(15, 8) @@ -46,22 +37,113 @@ /* Notable PDC versions */ #define PDC_VERSION_3_2 PDC_VERSION(3, 2, 0) +#define PDC_VERSION_3_0 PDC_VERSION(3, 0, 0) +#define PDC_VERSION_2_7 PDC_VERSION(2, 7, 0) + +/* + * PDC Hardware registers layout per version: + * + * IRQ_ENABLE_BANK[b], b = 0....BITS_TO_BYTES(PDC_MAX_IRQS) + * IRQ_CFG[n], n = 0....PDC_MAX_IRQS + * + * +---------------------------------------------------------------+ + * | v2.7 | v3.0 | v3.2 | + * |---------------------------------------------------------------| + * | BASE | BASE | BASE | + * |---------------------------------------------------------------| + * | | + * | IRQ_ENABLE_BANK | IRQ_ENABLE_BANK | NA | + * |---------------------------------------------------------------| + * | IRQ_CFG | IRQ_CFG | IRQ_CFG | + * | | | | + * | | | [31:6] Unused | + * | | [31:5] Unused | [5] GPIO_STATUS | + * | | [4] GPIO_STATUS| [4] GPIO_MASK | + * | [31:3] Unused | [3] GPIO_MASK | [3] IRQ_ENABLE | + * | [0:2] Type | [0:2] Type | [0:2] Type | + * +---------------------------------------------------------------+ + */ + +/** + * struct pdc_regs: PDC registers location + * + * @irq_en_reg: IRQ_ENABLE_BANK register location + * @irq_cfg_reg: IRQ_CFG register location + */ +struct pdc_regs { + u32 irq_en_reg; + u32 irq_cfg_reg; +}; + +/** + * struct pdc_irq_cfg: bit fields for PDC IRQ_CFG register + * + * @irq_enable: bit number for IRQ_ENABLE field + * @irq_type: GENMASK for IRQ_TYPE field + */ +struct pdc_irq_cfg { + u32 irq_enable; + u32 irq_type; +}; + +/** + * struct pdc_desc: PDC driver state + * + * @base: PDC base register for DRV2 / HLOS + * @prev_base: PDC DRV1 base, applicable only for x1e RTL bug. + * @version: PDC version + * @regs: PDC regs (IRQ_ENABLE_BANK and IRQ_CFG) + * @cfg_fields: Fields of IRQ_CFG reg + */ +struct pdc_desc { + void __iomem *base; + void __iomem *prev_base; + u32 version; + const struct pdc_regs *regs; + const struct pdc_irq_cfg *cfg_fields; +}; + +static const struct pdc_regs pdc_v3_2 = { + .irq_cfg_reg = 0x110, +}; + +static const struct pdc_irq_cfg pdc_cfg_v3_2 = { + .irq_enable = 3, + .irq_type = GENMASK(2, 0), +}; + +static const struct pdc_regs pdc_v3_0 = { + .irq_en_reg = 0x10, + .irq_cfg_reg = 0x110, +}; + +static const struct pdc_irq_cfg pdc_cfg_v3_0 = { + .irq_type = GENMASK(2, 0), +}; + +static const struct pdc_regs pdc_v2_7 = { + .irq_en_reg = 0x10, + .irq_cfg_reg = 0x110, +}; + +static const struct pdc_irq_cfg pdc_cfg_v2_7 = { + .irq_type = GENMASK(2, 0), +}; struct pdc_pin_region { - u32 pin_base; - u32 parent_base; - u32 cnt; + u32 pin_base; + u32 parent_base; + u32 cnt; }; #define pin_to_hwirq(r, p) ((r)->parent_base + (p) - (r)->pin_base) static DEFINE_RAW_SPINLOCK(pdc_lock); -static void __iomem *pdc_base; -static void __iomem *pdc_prev_base; static struct pdc_pin_region *pdc_region; static int pdc_region_cnt; static unsigned int pdc_version; static bool pdc_x1e_quirk; +static struct pdc_desc *pdc; static void pdc_base_reg_write(void __iomem *base, int reg, u32 i, u32 val) { @@ -70,12 +152,12 @@ static void pdc_base_reg_write(void __iomem *base, int reg, u32 i, u32 val) static void pdc_reg_write(int reg, u32 i, u32 val) { - pdc_base_reg_write(pdc_base, reg, i, val); + pdc_base_reg_write(pdc->base, reg, i, val); } static u32 pdc_reg_read(int reg, u32 i) { - return readl_relaxed(pdc_base + reg + i * sizeof(u32)); + return readl_relaxed(pdc->base + reg + i * sizeof(u32)); } static void pdc_x1e_irq_enable_write(u32 bank, u32 enable) @@ -86,24 +168,24 @@ static void pdc_x1e_irq_enable_write(u32 bank, u32 enable) switch (bank) { case 0 ... 1: /* Use previous DRV (client) region and shift to bank 3-4 */ - base = pdc_prev_base; + base = pdc->prev_base; bank += 3; break; case 2 ... 4: /* Use our own region and shift to bank 0-2 */ - base = pdc_base; + base = pdc->base; bank -= 2; break; case 5: /* No fixup required for bank 5 */ - base = pdc_base; + base = pdc->base; break; default: WARN_ON(1); return; } - pdc_base_reg_write(base, IRQ_ENABLE_BANK, bank, enable); + pdc_base_reg_write(base, pdc->regs->irq_en_reg, bank, enable); } static void pdc_enable_intr_bank(int pin_out, bool on) @@ -114,21 +196,21 @@ static void pdc_enable_intr_bank(int pin_out, bool on) index = FIELD_GET(IRQ_ENABLE_BANK_INDEX_MASK, pin_out); mask = FIELD_GET(IRQ_ENABLE_BANK_BIT_MASK, pin_out); - enable = pdc_reg_read(IRQ_ENABLE_BANK, index); + enable = pdc_reg_read(pdc->regs->irq_en_reg, index); __assign_bit(mask, &enable, on); if (pdc_x1e_quirk) pdc_x1e_irq_enable_write(index, enable); else - pdc_reg_write(IRQ_ENABLE_BANK, index, enable); + pdc_reg_write(pdc->regs->irq_en_reg, index, enable); } static void pdc_enable_intr_cfg(int pin_out, bool on) { - unsigned long enable = pdc_reg_read(IRQ_i_CFG, pin_out); + unsigned long enable = pdc_reg_read(pdc->regs->irq_cfg_reg, pin_out); - __assign_bit(IRQ_i_CFG_IRQ_ENABLE, &enable, on); - pdc_reg_write(IRQ_i_CFG, pin_out, enable); + __assign_bit(pdc->cfg_fields->irq_enable, &enable, on); + pdc_reg_write(pdc->regs->irq_cfg_reg, pin_out, enable); } static void __pdc_enable_intr(int pin_out, bool on) @@ -224,9 +306,9 @@ static int qcom_pdc_gic_set_type(struct irq_data *d, unsigned int type) return -EINVAL; } - old_pdc_type = pdc_reg_read(IRQ_i_CFG, d->hwirq); - pdc_type |= (old_pdc_type & ~IRQ_i_CFG_TYPE_MASK); - pdc_reg_write(IRQ_i_CFG, d->hwirq, pdc_type); + old_pdc_type = pdc_reg_read(pdc->regs->irq_cfg_reg, d->hwirq); + pdc_type |= (old_pdc_type & ~pdc->cfg_fields->irq_type); + pdc_reg_write(pdc->regs->irq_cfg_reg, d->hwirq, pdc_type); ret = irq_chip_set_type_parent(d, type); if (ret) @@ -317,8 +399,7 @@ static int qcom_pdc_alloc(struct irq_domain *domain, unsigned int virq, parent_fwspec.param[1] = pin_to_hwirq(region, hwirq); parent_fwspec.param[2] = type; - return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, - &parent_fwspec); + return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, &parent_fwspec); } static const struct irq_domain_ops qcom_pdc_ops = { @@ -327,8 +408,9 @@ static const struct irq_domain_ops qcom_pdc_ops = { .free = irq_domain_free_irqs_common, }; -static int pdc_setup_pin_mapping(struct device_node *np) +static int pdc_setup_pin_mapping(struct device *dev) { + struct device_node *np = dev->of_node; int ret, n, i; n = of_property_count_elems_of_size(np, "qcom,pdc-ranges", sizeof(u32)); @@ -336,25 +418,22 @@ static int pdc_setup_pin_mapping(struct device_node *np) return -EINVAL; pdc_region_cnt = n / 3; - pdc_region = kzalloc_objs(*pdc_region, pdc_region_cnt); + pdc_region = devm_kcalloc(dev, pdc_region_cnt, sizeof(*pdc_region), GFP_KERNEL); if (!pdc_region) { pdc_region_cnt = 0; return -ENOMEM; } for (n = 0; n < pdc_region_cnt; n++) { - ret = of_property_read_u32_index(np, "qcom,pdc-ranges", - n * 3 + 0, + ret = of_property_read_u32_index(np, "qcom,pdc-ranges", n * 3 + 0, &pdc_region[n].pin_base); if (ret) return ret; - ret = of_property_read_u32_index(np, "qcom,pdc-ranges", - n * 3 + 1, + ret = of_property_read_u32_index(np, "qcom,pdc-ranges", n * 3 + 1, &pdc_region[n].parent_base); if (ret) return ret; - ret = of_property_read_u32_index(np, "qcom,pdc-ranges", - n * 3 + 2, + ret = of_property_read_u32_index(np, "qcom,pdc-ranges", n * 3 + 2, &pdc_region[n].cnt); if (ret) return ret; @@ -366,11 +445,11 @@ static int pdc_setup_pin_mapping(struct device_node *np) return 0; } - static int qcom_pdc_probe(struct platform_device *pdev, struct device_node *parent) { struct irq_domain *parent_domain, *pdc_domain; struct device_node *node = pdev->dev.of_node; + struct device *dev = &pdev->dev; resource_size_t res_size; struct resource res; int ret; @@ -383,6 +462,29 @@ static int qcom_pdc_probe(struct platform_device *pdev, struct device_node *pare if (res_size > resource_size(&res)) pr_warn("%pOF: invalid reg size, please fix DT\n", node); + pdc = devm_kzalloc(dev, sizeof(*pdc), GFP_KERNEL); + if (!pdc) + return -ENOMEM; + + pdc->base = devm_ioremap(dev, res.start, res_size); + if (!pdc->base) { + pr_err("%pOF: unable to map PDC registers\n", node); + return -ENXIO; + } + + pdc->version = pdc_reg_read(PDC_VERSION_REG, 0); + + if (pdc->version >= PDC_VERSION_3_2) { + pdc->cfg_fields = &pdc_cfg_v3_2; + pdc->regs = &pdc_v3_2; + } else if (pdc->version >= PDC_VERSION_3_0) { + pdc->cfg_fields = &pdc_cfg_v3_0; + pdc->regs = &pdc_v3_0; + } else { + pdc->cfg_fields = &pdc_cfg_v2_7; + pdc->regs = &pdc_v2_7; + } + /* * PDC has multiple DRV regions, each one provides the same set of * registers for a particular client in the system. Due to a hardware @@ -392,8 +494,9 @@ static int qcom_pdc_probe(struct platform_device *pdev, struct device_node *pare * region with the expected offset to preserve support for old DTs. */ if (of_device_is_compatible(node, "qcom,x1e80100-pdc")) { - pdc_prev_base = ioremap(res.start - PDC_DRV_SIZE, IRQ_ENABLE_BANK_MAX); - if (!pdc_prev_base) { + pdc->prev_base = devm_ioremap(dev, res.start - PDC_DRV_SIZE, + pdc->regs->irq_en_reg + IRQ_ENABLE_BANK_MAX); + if (!pdc->prev_base) { pr_err("%pOF: unable to map previous PDC DRV region\n", node); return -ENXIO; } @@ -401,48 +504,29 @@ static int qcom_pdc_probe(struct platform_device *pdev, struct device_node *pare pdc_x1e_quirk = true; } - pdc_base = ioremap(res.start, res_size); - if (!pdc_base) { - pr_err("%pOF: unable to map PDC registers\n", node); - ret = -ENXIO; - goto fail; - } - - pdc_version = pdc_reg_read(PDC_VERSION_REG, 0); - parent_domain = irq_find_host(parent); if (!parent_domain) { pr_err("%pOF: unable to find PDC's parent domain\n", node); - ret = -ENXIO; - goto fail; + return -ENXIO; } - ret = pdc_setup_pin_mapping(node); + ret = pdc_setup_pin_mapping(dev); if (ret) { pr_err("%pOF: failed to init PDC pin-hwirq mapping\n", node); - goto fail; + return ret; } - pdc_domain = irq_domain_create_hierarchy(parent_domain, - IRQ_DOMAIN_FLAG_QCOM_PDC_WAKEUP, - PDC_MAX_GPIO_IRQS, - of_fwnode_handle(node), - &qcom_pdc_ops, NULL); + pdc_domain = irq_domain_create_hierarchy(parent_domain, IRQ_DOMAIN_FLAG_QCOM_PDC_WAKEUP, + PDC_MAX_IRQS, of_fwnode_handle(node), + &qcom_pdc_ops, NULL); if (!pdc_domain) { pr_err("%pOF: PDC domain add failed\n", node); - ret = -ENOMEM; - goto fail; + return -ENOMEM; } irq_domain_update_bus_token(pdc_domain, DOMAIN_BUS_WAKEUP); return 0; - -fail: - kfree(pdc_region); - iounmap(pdc_base); - iounmap(pdc_prev_base); - return ret; } IRQCHIP_PLATFORM_DRIVER_BEGIN(qcom_pdc) -- cgit v1.2.3 From 60caa95aa14aed8d05abc03b70e2ff14e5ab6820 Mon Sep 17 00:00:00 2001 From: Maulik Shah Date: Tue, 7 Jul 2026 14:51:34 +0530 Subject: irqchip/qcom-pdc: Move all static variables to struct pdc_desc There are multiple static variables used in the driver. Move all to struct pdc_desc to better align with versioning support. Document them. Add a new pdc->enable_intr() callback to point to the respective versions specific enable function. Remove pdc_enable_intr() and __pdc_enable_intr() and invoke pdc->enable_intr() from the call sites. Locking in pdc_enable_intr() applies lock to all version specific pdc->enable_intr() however lock is needed only for pdc_enable_intr_bank() which uses a shared bank across on PDC v2.7 and PDC v3.0. pdc_enable_intr_cfg() do not require locking as IRQ_CFG registers are one per interrupt. Move the locking to pdc_enable_intr_bank(). No functional impact intended [ tglx: Massage change log. ] Signed-off-by: Maulik Shah Signed-off-by: Thomas Gleixner Link: https://patch.msgid.link/20260707-hamoa_pdc_v3-v4-2-dfd1f4a3ae89@oss.qualcomm.com --- drivers/irqchip/qcom-pdc.c | 84 ++++++++++++++++++++++------------------------ 1 file changed, 41 insertions(+), 43 deletions(-) diff --git a/drivers/irqchip/qcom-pdc.c b/drivers/irqchip/qcom-pdc.c index 3d272a8e506e..5100a10415e0 100644 --- a/drivers/irqchip/qcom-pdc.c +++ b/drivers/irqchip/qcom-pdc.c @@ -92,15 +92,30 @@ struct pdc_irq_cfg { * @base: PDC base register for DRV2 / HLOS * @prev_base: PDC DRV1 base, applicable only for x1e RTL bug. * @version: PDC version + * @region: PDC interrupt continuous range + * @region_cnt: Total PDC ranges + * @x1e_quirk: x1e H/W Bug handling + * @lock: lock for IRQ_ENABLE_BANK protection * @regs: PDC regs (IRQ_ENABLE_BANK and IRQ_CFG) * @cfg_fields: Fields of IRQ_CFG reg + * @enable_intr: pointer to enable function based on PDC version */ struct pdc_desc { void __iomem *base; void __iomem *prev_base; u32 version; + + struct pdc_pin_region *region; + int region_cnt; + + bool x1e_quirk; + + raw_spinlock_t lock; + const struct pdc_regs *regs; const struct pdc_irq_cfg *cfg_fields; + + void (*enable_intr)(int pin_out, bool on); }; static const struct pdc_regs pdc_v3_2 = { @@ -138,11 +153,6 @@ struct pdc_pin_region { #define pin_to_hwirq(r, p) ((r)->parent_base + (p) - (r)->pin_base) -static DEFINE_RAW_SPINLOCK(pdc_lock); -static struct pdc_pin_region *pdc_region; -static int pdc_region_cnt; -static unsigned int pdc_version; -static bool pdc_x1e_quirk; static struct pdc_desc *pdc; static void pdc_base_reg_write(void __iomem *base, int reg, u32 i, u32 val) @@ -196,10 +206,12 @@ static void pdc_enable_intr_bank(int pin_out, bool on) index = FIELD_GET(IRQ_ENABLE_BANK_INDEX_MASK, pin_out); mask = FIELD_GET(IRQ_ENABLE_BANK_BIT_MASK, pin_out); + guard(raw_spinlock_irqsave)(&pdc->lock); + enable = pdc_reg_read(pdc->regs->irq_en_reg, index); __assign_bit(mask, &enable, on); - if (pdc_x1e_quirk) + if (pdc->x1e_quirk) pdc_x1e_irq_enable_write(index, enable); else pdc_reg_write(pdc->regs->irq_en_reg, index, enable); @@ -213,32 +225,15 @@ static void pdc_enable_intr_cfg(int pin_out, bool on) pdc_reg_write(pdc->regs->irq_cfg_reg, pin_out, enable); } -static void __pdc_enable_intr(int pin_out, bool on) -{ - if (pdc_version < PDC_VERSION_3_2) - pdc_enable_intr_bank(pin_out, on); - else - pdc_enable_intr_cfg(pin_out, on); -} - -static void pdc_enable_intr(struct irq_data *d, bool on) -{ - unsigned long flags; - - raw_spin_lock_irqsave(&pdc_lock, flags); - __pdc_enable_intr(d->hwirq, on); - raw_spin_unlock_irqrestore(&pdc_lock, flags); -} - static void qcom_pdc_gic_disable(struct irq_data *d) { - pdc_enable_intr(d, false); + pdc->enable_intr(d->hwirq, false); irq_chip_disable_parent(d); } static void qcom_pdc_gic_enable(struct irq_data *d) { - pdc_enable_intr(d, true); + pdc->enable_intr(d->hwirq, true); irq_chip_enable_parent(d); } @@ -350,12 +345,10 @@ static struct irq_chip qcom_pdc_gic_chip = { static struct pdc_pin_region *get_pin_region(int pin) { - int i; - - for (i = 0; i < pdc_region_cnt; i++) { - if (pin >= pdc_region[i].pin_base && - pin < pdc_region[i].pin_base + pdc_region[i].cnt) - return &pdc_region[i]; + for (int i = 0; i < pdc->region_cnt; i++) { + if (pin >= pdc->region[i].pin_base && + pin < pdc->region[i].pin_base + pdc->region[i].cnt) + return &pdc->region[i]; } return NULL; @@ -411,35 +404,35 @@ static const struct irq_domain_ops qcom_pdc_ops = { static int pdc_setup_pin_mapping(struct device *dev) { struct device_node *np = dev->of_node; - int ret, n, i; + int ret, n; n = of_property_count_elems_of_size(np, "qcom,pdc-ranges", sizeof(u32)); if (n <= 0 || n % 3) return -EINVAL; - pdc_region_cnt = n / 3; - pdc_region = devm_kcalloc(dev, pdc_region_cnt, sizeof(*pdc_region), GFP_KERNEL); - if (!pdc_region) { - pdc_region_cnt = 0; + pdc->region_cnt = n / 3; + pdc->region = devm_kcalloc(dev, pdc->region_cnt, sizeof(*pdc->region), GFP_KERNEL); + if (!pdc->region) { + pdc->region_cnt = 0; return -ENOMEM; } - for (n = 0; n < pdc_region_cnt; n++) { + for (n = 0; n < pdc->region_cnt; n++) { ret = of_property_read_u32_index(np, "qcom,pdc-ranges", n * 3 + 0, - &pdc_region[n].pin_base); + &pdc->region[n].pin_base); if (ret) return ret; ret = of_property_read_u32_index(np, "qcom,pdc-ranges", n * 3 + 1, - &pdc_region[n].parent_base); + &pdc->region[n].parent_base); if (ret) return ret; ret = of_property_read_u32_index(np, "qcom,pdc-ranges", n * 3 + 2, - &pdc_region[n].cnt); + &pdc->region[n].cnt); if (ret) return ret; - for (i = 0; i < pdc_region[n].cnt; i++) - __pdc_enable_intr(i + pdc_region[n].pin_base, 0); + for (int i = 0; i < pdc->region[n].cnt; i++) + pdc->enable_intr(i + pdc->region[n].pin_base, 0); } return 0; @@ -477,12 +470,15 @@ static int qcom_pdc_probe(struct platform_device *pdev, struct device_node *pare if (pdc->version >= PDC_VERSION_3_2) { pdc->cfg_fields = &pdc_cfg_v3_2; pdc->regs = &pdc_v3_2; + pdc->enable_intr = pdc_enable_intr_cfg; } else if (pdc->version >= PDC_VERSION_3_0) { pdc->cfg_fields = &pdc_cfg_v3_0; pdc->regs = &pdc_v3_0; + pdc->enable_intr = pdc_enable_intr_bank; } else { pdc->cfg_fields = &pdc_cfg_v2_7; pdc->regs = &pdc_v2_7; + pdc->enable_intr = pdc_enable_intr_bank; } /* @@ -501,7 +497,7 @@ static int qcom_pdc_probe(struct platform_device *pdev, struct device_node *pare return -ENXIO; } - pdc_x1e_quirk = true; + pdc->x1e_quirk = true; } parent_domain = irq_find_host(parent); @@ -510,6 +506,8 @@ static int qcom_pdc_probe(struct platform_device *pdev, struct device_node *pare return -ENXIO; } + raw_spin_lock_init(&pdc->lock); + ret = pdc_setup_pin_mapping(dev); if (ret) { pr_err("%pOF: failed to init PDC pin-hwirq mapping\n", node); -- cgit v1.2.3 From 45af2d61edf62938b021b86439a1dd797fd74a91 Mon Sep 17 00:00:00 2001 From: Maulik Shah Date: Tue, 7 Jul 2026 14:51:35 +0530 Subject: irqchip/qcom-pdc: Differentiate between direct SPI and GPIO as SPI Before commit 4dc70713dc24 ("irqchip/qcom-pdc: Kill non-wakeup irqdomain") there were separate domains for direct SPIs and GPIOs used as SPIs. Separate domains can be useful to have separate interrupt chips for different functionalities. Since the commit unified both domains there is no way to differentiate. In preparation to add the second level interrupt controller support where GPIO interrupts get latched at PDC (but not direct SPIs) there is a need to differentiate between SPIs and GPIOs as SPIs. Reverting above commit does is not a good option as it leads to waste of resources. PDC hardware provides the IRQ_PARAM register to enumerate the number of direct SPIs and the number of GPIOs as SPIs. Further PDC allocates direct SPIs at the beginning and all GPIOs as SPIs are allocated at the end. This information can be used in the driver to differentiate them. Add the support to read this register and keep this information in struct pdc_desc. Later change utilizes it. [ tglx: Massage change log ] Signed-off-by: Maulik Shah Signed-off-by: Thomas Gleixner Link: https://patch.msgid.link/20260707-hamoa_pdc_v3-v4-3-dfd1f4a3ae89@oss.qualcomm.com --- drivers/irqchip/qcom-pdc.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/irqchip/qcom-pdc.c b/drivers/irqchip/qcom-pdc.c index 5100a10415e0..253fb69e7ef2 100644 --- a/drivers/irqchip/qcom-pdc.c +++ b/drivers/irqchip/qcom-pdc.c @@ -61,6 +61,11 @@ * | | [4] GPIO_STATUS| [4] GPIO_MASK | * | [31:3] Unused | [3] GPIO_MASK | [3] IRQ_ENABLE | * | [0:2] Type | [0:2] Type | [0:2] Type | + * |---------------------------------------------------------------| + * | IRQ_PARAM | IRQ_PARAM | IRQ_PARAM | + * | | | + * | [15:8] NUM_GPIO | [15:8] NUM_GPIO | [15:8] NUM_GPIO | + * | [7:0] NUM_SPI | [7:0] NUM_SPI | [7:0] NUM_SPI | * +---------------------------------------------------------------+ */ @@ -69,10 +74,12 @@ * * @irq_en_reg: IRQ_ENABLE_BANK register location * @irq_cfg_reg: IRQ_CFG register location + * @irq_param_reg: IRQ_PARAM register location */ struct pdc_regs { u32 irq_en_reg; u32 irq_cfg_reg; + u32 irq_param_reg; }; /** @@ -92,6 +99,7 @@ struct pdc_irq_cfg { * @base: PDC base register for DRV2 / HLOS * @prev_base: PDC DRV1 base, applicable only for x1e RTL bug. * @version: PDC version + * @num_spis: Total number of direct SPI interrupts * @region: PDC interrupt continuous range * @region_cnt: Total PDC ranges * @x1e_quirk: x1e H/W Bug handling @@ -104,6 +112,7 @@ struct pdc_desc { void __iomem *base; void __iomem *prev_base; u32 version; + u32 num_spis; struct pdc_pin_region *region; int region_cnt; @@ -120,6 +129,7 @@ struct pdc_desc { static const struct pdc_regs pdc_v3_2 = { .irq_cfg_reg = 0x110, + .irq_param_reg = 0x100c, }; static const struct pdc_irq_cfg pdc_cfg_v3_2 = { @@ -130,6 +140,7 @@ static const struct pdc_irq_cfg pdc_cfg_v3_2 = { static const struct pdc_regs pdc_v3_0 = { .irq_en_reg = 0x10, .irq_cfg_reg = 0x110, + .irq_param_reg = 0x100c, }; static const struct pdc_irq_cfg pdc_cfg_v3_0 = { @@ -139,6 +150,7 @@ static const struct pdc_irq_cfg pdc_cfg_v3_0 = { static const struct pdc_regs pdc_v2_7 = { .irq_en_reg = 0x10, .irq_cfg_reg = 0x110, + .irq_param_reg = 0x100c, }; static const struct pdc_irq_cfg pdc_cfg_v2_7 = { @@ -445,6 +457,7 @@ static int qcom_pdc_probe(struct platform_device *pdev, struct device_node *pare struct device *dev = &pdev->dev; resource_size_t res_size; struct resource res; + u32 irq_param; int ret; /* compat with old sm8150 DT which had very small region for PDC */ @@ -500,6 +513,9 @@ static int qcom_pdc_probe(struct platform_device *pdev, struct device_node *pare pdc->x1e_quirk = true; } + irq_param = pdc_reg_read(pdc->regs->irq_param_reg, 0); + pdc->num_spis = FIELD_GET(GENMASK(7, 0), irq_param); + parent_domain = irq_find_host(parent); if (!parent_domain) { pr_err("%pOF: unable to find PDC's parent domain\n", node); -- cgit v1.2.3 From ad01c2b2f29163ca0bbe1fd4f9343fbc5119c239 Mon Sep 17 00:00:00 2001 From: Maulik Shah Date: Tue, 7 Jul 2026 14:51:36 +0530 Subject: irqchip/qcom-pdc: Configure PDC to pass through mode All PDC hardware versions support pass-through mode in which both Direct SPIs and GPIO interrupts (as SPIs) are sent to the GIC without latching at the PDC level. Newer PDCs (v3.0 onwards) also support an additional secondary controller mode where PDC latches the GPIO interrupts and sends them to the GIC as level type interrupts. Direct SPIs works the same as pass-through mode without latching at PDC even in secondary controller mode. All the SoCs use pass-through mode with the exception of x1e. The x1e PDC may be set to secondary controller mode for builds on CRD boards whereas it may be set to pass through mode for IoT-EVK boards. The mode configuration is done in firmware and initially shipped windows firmware did not have a SCM interface to read or modify the PDC mode. Only later write access was opened up for the non-secure world. The availability of write access can be probed. Therefore try to modify the to modify the PDC mode to pass-through mode via SCM write. When the write fails on older firmware assume it to work in secondary mode. In secondary mode set the separate irqchip for the GPIOs to perform additional operations only for the GPIO interrupts. [ tglx: Massage change log ] Co-developed-by: Sneh Mankad Signed-off-by: Sneh Mankad Signed-off-by: Maulik Shah Signed-off-by: Thomas Gleixner Link: https://patch.msgid.link/20260707-hamoa_pdc_v3-v4-4-dfd1f4a3ae89@oss.qualcomm.com --- drivers/irqchip/qcom-pdc.c | 240 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 227 insertions(+), 13 deletions(-) diff --git a/drivers/irqchip/qcom-pdc.c b/drivers/irqchip/qcom-pdc.c index 253fb69e7ef2..f38ee74b0397 100644 --- a/drivers/irqchip/qcom-pdc.c +++ b/drivers/irqchip/qcom-pdc.c @@ -20,12 +20,18 @@ #include #include #include +#include #define PDC_MAX_IRQS 256 #define IRQ_ENABLE_BANK_MAX BITS_TO_BYTES(PDC_MAX_IRQS) #define IRQ_ENABLE_BANK_INDEX_MASK GENMASK(31, 5) #define IRQ_ENABLE_BANK_BIT_MASK GENMASK(4, 0) +/* Secure DRV register to configure the PDC mode via qcom_scm_io_writel() */ +#define PDC_GPIO_INT_CTL_ENABLE 0xb2045e8 +#define PDC_PASS_THROUGH_MODE 0x0 +#define PDC_SECONDARY_MODE 0x1 + #define PDC_DRV_SIZE 0x10000 #define PDC_VERSION_REG 0x1000 #define PDC_VERSION_MAJOR GENMASK(23, 16) @@ -85,10 +91,14 @@ struct pdc_regs { /** * struct pdc_irq_cfg: bit fields for PDC IRQ_CFG register * + * @gpio_irq_sts: bit number for GPIO_STATUS field + * @gpio_irq_mask: bit number for GPIO_MASK field * @irq_enable: bit number for IRQ_ENABLE field * @irq_type: GENMASK for IRQ_TYPE field */ struct pdc_irq_cfg { + u32 gpio_irq_sts; + u32 gpio_irq_mask; u32 irq_enable; u32 irq_type; }; @@ -102,11 +112,14 @@ struct pdc_irq_cfg { * @num_spis: Total number of direct SPI interrupts * @region: PDC interrupt continuous range * @region_cnt: Total PDC ranges + * @mode: PDC_PASS_THROUGH_MODE or PDC_SECONDARY_MODE * @x1e_quirk: x1e H/W Bug handling * @lock: lock for IRQ_ENABLE_BANK protection * @regs: PDC regs (IRQ_ENABLE_BANK and IRQ_CFG) * @cfg_fields: Fields of IRQ_CFG reg * @enable_intr: pointer to enable function based on PDC version + * @unmask_gpio: pointer to GPIO irq unmask function + * @clear_gpio: pointer to GPIO irq clear function */ struct pdc_desc { void __iomem *base; @@ -119,12 +132,15 @@ struct pdc_desc { bool x1e_quirk; + u8 mode; raw_spinlock_t lock; const struct pdc_regs *regs; const struct pdc_irq_cfg *cfg_fields; void (*enable_intr)(int pin_out, bool on); + void (*unmask_gpio)(int pin_out, bool on); + void (*clear_gpio)(int pin_out); }; static const struct pdc_regs pdc_v3_2 = { @@ -133,6 +149,8 @@ static const struct pdc_regs pdc_v3_2 = { }; static const struct pdc_irq_cfg pdc_cfg_v3_2 = { + .gpio_irq_sts = 5, + .gpio_irq_mask = 4, .irq_enable = 3, .irq_type = GENMASK(2, 0), }; @@ -144,6 +162,8 @@ static const struct pdc_regs pdc_v3_0 = { }; static const struct pdc_irq_cfg pdc_cfg_v3_0 = { + .gpio_irq_sts = 4, + .gpio_irq_mask = 3, .irq_type = GENMASK(2, 0), }; @@ -182,6 +202,15 @@ static u32 pdc_reg_read(int reg, u32 i) return readl_relaxed(pdc->base + reg + i * sizeof(u32)); } +static inline bool pdc_pin_is_gpio(int pin_out) +{ + /* + * PDC allocates direct SPIs at the beginning and + * all GPIOs as SPIs are allocated after direct SPIs. + */ + return pin_out >= pdc->num_spis; +} + static void pdc_x1e_irq_enable_write(u32 bank, u32 enable) { void __iomem *base; @@ -229,6 +258,24 @@ static void pdc_enable_intr_bank(int pin_out, bool on) pdc_reg_write(pdc->regs->irq_en_reg, index, enable); } +static void pdc_clear_gpio_cfg(int pin_out) +{ + unsigned long gpio_sts; + + gpio_sts = pdc_reg_read(pdc->regs->irq_cfg_reg, pin_out); + __clear_bit(pdc->cfg_fields->gpio_irq_sts, &gpio_sts); + pdc_reg_write(pdc->regs->irq_cfg_reg, pin_out, gpio_sts); +} + +static void pdc_unmask_gpio_cfg(int pin_out, bool unmask) +{ + unsigned long gpio_mask; + + gpio_mask = pdc_reg_read(pdc->regs->irq_cfg_reg, pin_out); + __assign_bit(pdc->cfg_fields->gpio_irq_mask, &gpio_mask, !unmask); + pdc_reg_write(pdc->regs->irq_cfg_reg, pin_out, gpio_mask); +} + static void pdc_enable_intr_cfg(int pin_out, bool on) { unsigned long enable = pdc_reg_read(pdc->regs->irq_cfg_reg, pin_out); @@ -237,6 +284,13 @@ static void pdc_enable_intr_cfg(int pin_out, bool on) pdc_reg_write(pdc->regs->irq_cfg_reg, pin_out, enable); } +static void qcom_pdc_gic_secondary_disable(struct irq_data *d) +{ + pdc->enable_intr(d->hwirq, false); + pdc->unmask_gpio(d->hwirq, false); + irq_chip_disable_parent(d); +} + static void qcom_pdc_gic_disable(struct irq_data *d) { pdc->enable_intr(d->hwirq, false); @@ -249,6 +303,41 @@ static void qcom_pdc_gic_enable(struct irq_data *d) irq_chip_enable_parent(d); } +static void qcom_pdc_gic_secondary_enable(struct irq_data *d) +{ + pdc->enable_intr(d->hwirq, true); + pdc->unmask_gpio(d->hwirq, true); + irq_chip_enable_parent(d); +} + +static void qcom_pdc_secondary_ack(struct irq_data *d) +{ + if (!irqd_is_level_type(d)) + pdc->clear_gpio(d->hwirq); +} + +static void qcom_pdc_gic_secondary_eoi(struct irq_data *d) +{ + if (irqd_is_level_type(d)) + pdc->clear_gpio(d->hwirq); + + irq_chip_eoi_parent(d); +} + +static void qcom_pdc_secondary_mask(struct irq_data *d) +{ + pdc->enable_intr(d->hwirq, false); + pdc->unmask_gpio(d->hwirq, false); + irq_chip_mask_parent(d); +} + +static void qcom_pdc_secondary_unmask(struct irq_data *d) +{ + pdc->enable_intr(d->hwirq, true); + pdc->unmask_gpio(d->hwirq, true); + irq_chip_unmask_parent(d); +} + /* * GIC does not handle falling edge or active low. To allow falling edge and * active low interrupts to be handled at GIC, PDC has an inverter that inverts @@ -275,18 +364,18 @@ enum pdc_irq_config_bits { /** * qcom_pdc_gic_set_type: Configure PDC for the interrupt * - * @d: the interrupt data + * @d: the interrupt data * @type: the interrupt type * - * If @type is edge triggered, forward that as Rising edge as PDC - * takes care of converting falling edge to rising edge signal + * If @type is edge triggered, forward that as rising edge as PDC + * takes care of converting all edge types to rising edge signal * If @type is level, then forward that as level high as PDC - * takes care of converting falling edge to rising edge signal + * takes care of converting all level types to level high signal */ static int qcom_pdc_gic_set_type(struct irq_data *d, unsigned int type) { - enum pdc_irq_config_bits pdc_type; enum pdc_irq_config_bits old_pdc_type; + enum pdc_irq_config_bits pdc_type; int ret; switch (type) { @@ -336,6 +425,72 @@ static int qcom_pdc_gic_set_type(struct irq_data *d, unsigned int type) return 0; } +/** + * qcom_pdc_gic_set_type: Configure PDC for the interrupt + * + * @d: the interrupt data + * @type: the interrupt type + * + * All @type are forwarded as level high type to parent GIC + */ +static int qcom_pdc_gic_secondary_set_type(struct irq_data *d, unsigned int type) +{ + enum pdc_irq_config_bits old_pdc_type; + enum pdc_irq_config_bits pdc_type; + int ret; + + switch (type) { + case IRQ_TYPE_EDGE_RISING: + pdc_type = PDC_EDGE_RISING; + break; + case IRQ_TYPE_EDGE_FALLING: + pdc_type = PDC_EDGE_FALLING; + break; + case IRQ_TYPE_EDGE_BOTH: + pdc_type = PDC_EDGE_DUAL; + break; + case IRQ_TYPE_LEVEL_HIGH: + pdc_type = PDC_LEVEL_HIGH; + break; + case IRQ_TYPE_LEVEL_LOW: + pdc_type = PDC_LEVEL_LOW; + break; + default: + WARN_ON(1); + return -EINVAL; + } + + old_pdc_type = pdc_reg_read(pdc->regs->irq_cfg_reg, d->hwirq); + pdc_type |= (old_pdc_type & ~pdc->cfg_fields->irq_type); + pdc_reg_write(pdc->regs->irq_cfg_reg, d->hwirq, pdc_type); + + /* + * PDC forwards GPIOs as level high to GIC in secondary + * mode. Update the type and clear any previously latched + * phantom interrupt at PDC. + */ + type = IRQ_TYPE_LEVEL_HIGH; + pdc->clear_gpio(d->hwirq); + + ret = irq_chip_set_type_parent(d, type); + if (ret) + return ret; + + /* + * When we change types the PDC can give a phantom interrupt. + * Clear it. Specifically the phantom shows up when reconfiguring + * polarity of interrupt without changing the state of the signal + * but let's be consistent and clear it always. + * + * Doing this works because we have IRQCHIP_SET_TYPE_MASKED so the + * interrupt will be cleared before the rest of the system sees it. + */ + if (old_pdc_type != pdc_type) + irq_chip_set_parent_state(d, IRQCHIP_STATE_PENDING, false); + + return 0; +} + static struct irq_chip qcom_pdc_gic_chip = { .name = "PDC", .irq_eoi = irq_chip_eoi_parent, @@ -355,6 +510,26 @@ static struct irq_chip qcom_pdc_gic_chip = { .irq_set_affinity = irq_chip_set_affinity_parent, }; +static struct irq_chip qcom_pdc_gic_secondary_chip = { + .name = "PDC", + .irq_ack = qcom_pdc_secondary_ack, + .irq_eoi = qcom_pdc_gic_secondary_eoi, + .irq_mask = qcom_pdc_secondary_mask, + .irq_unmask = qcom_pdc_secondary_unmask, + .irq_disable = qcom_pdc_gic_secondary_disable, + .irq_enable = qcom_pdc_gic_secondary_enable, + .irq_get_irqchip_state = irq_chip_get_parent_state, + .irq_set_irqchip_state = irq_chip_set_parent_state, + .irq_retrigger = irq_chip_retrigger_hierarchy, + .irq_set_type = qcom_pdc_gic_secondary_set_type, + .flags = IRQCHIP_MASK_ON_SUSPEND | + IRQCHIP_SET_TYPE_MASKED | + IRQCHIP_SKIP_SET_WAKE | + IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND, + .irq_set_vcpu_affinity = irq_chip_set_vcpu_affinity_parent, + .irq_set_affinity = irq_chip_set_affinity_parent, +}; + static struct pdc_pin_region *get_pin_region(int pin) { for (int i = 0; i < pdc->region_cnt; i++) { @@ -388,16 +563,38 @@ static int qcom_pdc_alloc(struct irq_domain *domain, unsigned int virq, if (ret) return ret; + /* + * PDC secondary chip is only set for the GPIO interrupts as SPIs. + * Direct SPI interrupts are still in pass through mode (no latching + * at PDC). + */ + if (pdc->mode == PDC_SECONDARY_MODE && pdc_pin_is_gpio(hwirq)) { + ret = irq_domain_set_hwirq_and_chip(domain, virq, hwirq, + &qcom_pdc_gic_secondary_chip, + NULL); + if (ret) + return ret; + + /* Secondary mode converts all interrupts to LEVEL HIGH type */ + type = IRQ_TYPE_LEVEL_HIGH; + } else { + ret = irq_domain_set_hwirq_and_chip(domain, virq, hwirq, + &qcom_pdc_gic_chip, + NULL); + if (ret) + return ret; + + if (type & IRQ_TYPE_EDGE_BOTH) + type = IRQ_TYPE_EDGE_RISING; + + if (type & IRQ_TYPE_LEVEL_MASK) + type = IRQ_TYPE_LEVEL_HIGH; + } + region = get_pin_region(hwirq); if (!region) return irq_domain_disconnect_hierarchy(domain->parent, virq); - if (type & IRQ_TYPE_EDGE_BOTH) - type = IRQ_TYPE_EDGE_RISING; - - if (type & IRQ_TYPE_LEVEL_MASK) - type = IRQ_TYPE_LEVEL_HIGH; - parent_fwspec.fwnode = domain->parent->fwnode; parent_fwspec.param_count = 3; parent_fwspec.param[0] = 0; @@ -443,8 +640,13 @@ static int pdc_setup_pin_mapping(struct device *dev) if (ret) return ret; - for (int i = 0; i < pdc->region[n].cnt; i++) - pdc->enable_intr(i + pdc->region[n].pin_base, 0); + for (int i = 0; i < pdc->region[n].cnt; i++) { + if (pdc_pin_is_gpio(i + pdc->region[n].pin_base) && + pdc->mode == PDC_SECONDARY_MODE) + pdc->clear_gpio(i + pdc->region[n].pin_base); + + pdc->enable_intr(i + pdc->region[n].pin_base, false); + } } return 0; @@ -494,6 +696,8 @@ static int qcom_pdc_probe(struct platform_device *pdev, struct device_node *pare pdc->enable_intr = pdc_enable_intr_bank; } + pdc->mode = PDC_PASS_THROUGH_MODE; + /* * PDC has multiple DRV regions, each one provides the same set of * registers for a particular client in the system. Due to a hardware @@ -511,6 +715,16 @@ static int qcom_pdc_probe(struct platform_device *pdev, struct device_node *pare } pdc->x1e_quirk = true; + + if (!qcom_scm_is_available()) + return -EPROBE_DEFER; + + ret = qcom_scm_io_writel(PDC_GPIO_INT_CTL_ENABLE, PDC_PASS_THROUGH_MODE); + if (ret) { + pdc->mode = PDC_SECONDARY_MODE; + pdc->unmask_gpio = pdc_unmask_gpio_cfg; + pdc->clear_gpio = pdc_clear_gpio_cfg; + } } irq_param = pdc_reg_read(pdc->regs->irq_param_reg, 0); -- cgit v1.2.3 From f790ea0b699d95d18572979b1bc1673d8f31eb3c Mon Sep 17 00:00:00 2001 From: Stephan Gerhold Date: Tue, 7 Jul 2026 14:51:37 +0530 Subject: pinctrl: qcom: Acknowledge IRQs for PDC interrupt controller PDC needs to acknowledge incoming GPIO interrupts to clear the latched interrupt status in secondary mode of PDC. For level-triggered IRQs this happens automatically in irq_eoi() but for edge-triggered IRQs this needs to happen as early as possible in the IRQ handler. Implement this by using handle_fasteoi_ack_irq() as IRQ handler in this situation and forward the irq_ack() callback to the parent IRQ chip. Signed-off-by: Stephan Gerhold Signed-off-by: Maulik Shah Link: https://patch.msgid.link/20260707-hamoa_pdc_v3-v4-5-dfd1f4a3ae89@oss.qualcomm.com Signed-off-by: Bartosz Golaszewski --- drivers/pinctrl/qcom/pinctrl-msm.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c index 1055d42381bb..838969186185 100644 --- a/drivers/pinctrl/qcom/pinctrl-msm.c +++ b/drivers/pinctrl/qcom/pinctrl-msm.c @@ -994,6 +994,16 @@ static void msm_gpio_irq_ack(struct irq_data *d) if (test_bit(d->hwirq, pctrl->skip_wake_irqs)) { if (test_bit(d->hwirq, pctrl->dual_edge_irqs)) msm_gpio_update_dual_edge_parent(d); + + /* + * During early initialization of the IRQ hierarchy, + * irq_ack() is called by __irq_set_handler() before + * the parent IRQ chip has been set up. This is why + * we additionally need to check for d->parent_data->chip. + */ + + if (d->parent_data->chip && d->parent_data->chip->irq_ack) + irq_chip_ack_parent(d); return; } @@ -1064,7 +1074,10 @@ static int msm_gpio_irq_set_type(struct irq_data *d, unsigned int type) if (test_bit(d->hwirq, pctrl->skip_wake_irqs)) { clear_bit(d->hwirq, pctrl->dual_edge_irqs); - irq_set_handler_locked(d, handle_fasteoi_irq); + if (type & IRQ_TYPE_LEVEL_MASK) + irq_set_handler_locked(d, handle_fasteoi_irq); + else + irq_set_handler_locked(d, handle_fasteoi_ack_irq); return 0; } -- cgit v1.2.3 From 77fbc756d9cbe53a9496cb2c53ae209d37d5af2d Mon Sep 17 00:00:00 2001 From: Maulik Shah Date: Tue, 7 Jul 2026 14:51:38 +0530 Subject: Revert "pinctrl: qcom: x1e80100: Bypass PDC wakeup parent for now" This reverts commit 602cb14e310a ("pinctrl: qcom: x1e80100: Bypass PDC wakeup parent for now"). PDC interrupts no more break GPIOs PDC irqchip is updated to work for pass through or secondary mode. Update nwakeirq_map to reflect the GPIO to PDC irq map size. Signed-off-by: Maulik Shah Link: https://patch.msgid.link/20260707-hamoa_pdc_v3-v4-6-dfd1f4a3ae89@oss.qualcomm.com Signed-off-by: Bartosz Golaszewski --- drivers/pinctrl/qcom/pinctrl-x1e80100.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/pinctrl/qcom/pinctrl-x1e80100.c b/drivers/pinctrl/qcom/pinctrl-x1e80100.c index 8d2b8246170b..e4c0abcd95b9 100644 --- a/drivers/pinctrl/qcom/pinctrl-x1e80100.c +++ b/drivers/pinctrl/qcom/pinctrl-x1e80100.c @@ -1836,9 +1836,7 @@ static const struct msm_pinctrl_soc_data x1e80100_pinctrl = { .ngroups = ARRAY_SIZE(x1e80100_groups), .ngpios = 239, .wakeirq_map = x1e80100_pdc_map, - /* TODO: Enabling PDC currently breaks GPIO interrupts */ - .nwakeirq_map = 0, - /* .nwakeirq_map = ARRAY_SIZE(x1e80100_pdc_map), */ + .nwakeirq_map = ARRAY_SIZE(x1e80100_pdc_map), .egpio_func = 9, }; -- cgit v1.2.3 From f81bcaae1edde95c684436310edad8cf849f1f1f Mon Sep 17 00:00:00 2001 From: Ravi Hothi Date: Wed, 15 Jul 2026 18:51:49 +0530 Subject: dt-bindings: pinctrl: qcom,milos-lpass-lpi-pinctrl: Add Eliza pinctrl Document compatible for Qualcomm Eliza SoC LPASS LPI pin controller. Eliza has the same pin mux functions as Milos but uses a different slew rate register layout where the slew rate field is in the same GPIO config register rather than a separate dedicated register. As a result, Eliza only has a single reg entry instead of two. Signed-off-by: Ravi Hothi Reviewed-by: Krzysztof Kozlowski Link: https://patch.msgid.link/20260715132150.1322663-2-ravi.hothi@oss.qualcomm.com Signed-off-by: Bartosz Golaszewski --- .../bindings/pinctrl/qcom,milos-lpass-lpi-pinctrl.yaml | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,milos-lpass-lpi-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,milos-lpass-lpi-pinctrl.yaml index 73e84f188591..86c1da0f577c 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,milos-lpass-lpi-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,milos-lpass-lpi-pinctrl.yaml @@ -15,9 +15,12 @@ description: properties: compatible: - const: qcom,milos-lpass-lpi-pinctrl + enum: + - qcom,eliza-lpass-lpi-pinctrl + - qcom,milos-lpass-lpi-pinctrl reg: + minItems: 1 items: - description: LPASS LPI TLMM Control and Status registers - description: LPASS LPI MCC registers @@ -74,6 +77,19 @@ $defs: allOf: - $ref: qcom,lpass-lpi-common.yaml# + - if: + properties: + compatible: + const: qcom,eliza-lpass-lpi-pinctrl + then: + properties: + reg: + maxItems: 1 + else: + properties: + reg: + minItems: 2 + required: - compatible - reg -- cgit v1.2.3 From 82c3edf8701154e2768973ebd4c0d2f3bd29621e Mon Sep 17 00:00:00 2001 From: Ravi Hothi Date: Wed, 15 Jul 2026 18:51:50 +0530 Subject: pinctrl: qcom: milos-lpass-lpi: Add Eliza LPASS LPI TLMM Eliza SoC has the same LPASS LPI pin mux functions as Milos but the slew rate control is in the same GPIO config register rather than a separate register. Add a new variant data struct with updated slew offsets and LPI_FLAG_SLEW_RATE_SAME_REG flag, reusing the existing pin descriptors and function table from Milos. Signed-off-by: Ravi Hothi Reviewed-by: Konrad Dybcio Link: https://patch.msgid.link/20260715132150.1322663-3-ravi.hothi@oss.qualcomm.com Signed-off-by: Bartosz Golaszewski --- drivers/pinctrl/qcom/pinctrl-milos-lpass-lpi.c | 40 ++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/drivers/pinctrl/qcom/pinctrl-milos-lpass-lpi.c b/drivers/pinctrl/qcom/pinctrl-milos-lpass-lpi.c index 72b8ffd97860..cb4934cd6f75 100644 --- a/drivers/pinctrl/qcom/pinctrl-milos-lpass-lpi.c +++ b/drivers/pinctrl/qcom/pinctrl-milos-lpass-lpi.c @@ -148,6 +148,33 @@ static const struct lpi_pingroup milos_groups[] = { LPI_PINGROUP(22, LPI_NO_SLEW, i2s3_data, dmic4_data, ext_mclk1_e, _), }; +static const struct lpi_pingroup eliza_groups[] = { + LPI_PINGROUP(0, 11, swr_tx_clk, i2s0_clk, _, _), + LPI_PINGROUP(1, 11, swr_tx_data, i2s0_ws, _, _), + LPI_PINGROUP(2, 11, swr_tx_data, i2s0_data, _, _), + LPI_PINGROUP(3, 11, swr_rx_clk, i2s0_data, _, _), + LPI_PINGROUP(4, 11, swr_rx_data, i2s0_data, _, _), + LPI_PINGROUP(5, 11, swr_rx_data, ext_mclk1_c, i2s0_data, _), + LPI_PINGROUP(6, LPI_NO_SLEW, dmic1_clk, i2s1_clk, _, _), + LPI_PINGROUP(7, LPI_NO_SLEW, dmic1_data, i2s1_ws, _, _), + LPI_PINGROUP(8, LPI_NO_SLEW, dmic2_clk, i2s1_data, _, _), + LPI_PINGROUP(9, LPI_NO_SLEW, dmic2_data, i2s1_data, ext_mclk1_b, _), + LPI_PINGROUP(10, 11, wsa_swr_clk, i2s2_clk, _, _), + LPI_PINGROUP(11, 11, wsa_swr_data, i2s2_ws, _, _), + LPI_PINGROUP(12, LPI_NO_SLEW, dmic3_clk, i2s2_data, _, _), + LPI_PINGROUP(13, LPI_NO_SLEW, dmic3_data, i2s2_data, ext_mclk1_a, _), + LPI_PINGROUP(14, 11, swr_tx_data, ext_mclk1_d, _, _), + /* gpio15 - gpio18 do not really exist */ + LPI_PINGROUP(15, 11, _, _, _, _), + LPI_PINGROUP(16, 11, _, _, _, _), + LPI_PINGROUP(17, LPI_NO_SLEW, _, _, _, _), + LPI_PINGROUP(18, LPI_NO_SLEW, _, _, _, _), + LPI_PINGROUP(19, LPI_NO_SLEW, i2s3_clk, slimbus_clk, qca_swr_clk, _), + LPI_PINGROUP(20, LPI_NO_SLEW, i2s3_ws, slimbus_data, qca_swr_data, _), + LPI_PINGROUP(21, LPI_NO_SLEW, i2s3_data, dmic4_clk, _, _), + LPI_PINGROUP(22, LPI_NO_SLEW, i2s3_data, dmic4_data, ext_mclk1_e, _), +}; + static const struct lpi_function milos_functions[] = { LPI_FUNCTION(gpio), LPI_FUNCTION(dmic1_clk), @@ -196,8 +223,21 @@ static const struct lpi_pinctrl_variant_data milos_lpi_data = { .nfunctions = ARRAY_SIZE(milos_functions), }; +static const struct lpi_pinctrl_variant_data eliza_lpi_data = { + .pins = milos_lpi_pins, + .npins = ARRAY_SIZE(milos_lpi_pins), + .groups = eliza_groups, + .ngroups = ARRAY_SIZE(eliza_groups), + .functions = milos_functions, + .nfunctions = ARRAY_SIZE(milos_functions), + .flags = LPI_FLAG_SLEW_RATE_SAME_REG, +}; + static const struct of_device_id lpi_pinctrl_of_match[] = { { + .compatible = "qcom,eliza-lpass-lpi-pinctrl", + .data = &eliza_lpi_data, + }, { .compatible = "qcom,milos-lpass-lpi-pinctrl", .data = &milos_lpi_data, }, -- cgit v1.2.3 From 1860fb0be224dec0e4d170f46d1cbbc77e25e09e Mon Sep 17 00:00:00 2001 From: Maulik Shah Date: Fri, 24 Apr 2026 12:01:24 +0530 Subject: pinctrl: qcom: Add irq_get/set_irqchip_state() for msm gpio irqchip MPM irqchip monitors the interrupts during SoC sleep state and after wakeup replays the edge interrupt by making it pending at respective irqchip by invoking irq_set_irqchip_state() API. The msm gpio irqchip however do not implement this function making it impossible to replay the gpio interrupt on any MPM irqchip based SoC. Add the missing irq_get/set_irqchip_state() APIs. Implement only IRQCHIP_STATE_PENDING case which MPM irqchip uses. Signed-off-by: Maulik Shah Signed-off-by: Sneh Mankad Acked-by: Linus Walleij Reviewed-by: Navya Malempati Link: https://patch.msgid.link/20260424-pinctrl_irqchip_states-v1-1-85286f078916@oss.qualcomm.com Signed-off-by: Bartosz Golaszewski --- drivers/pinctrl/qcom/pinctrl-msm.c | 39 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c index 838969186185..3cb48ba31b78 100644 --- a/drivers/pinctrl/qcom/pinctrl-msm.c +++ b/drivers/pinctrl/qcom/pinctrl-msm.c @@ -1313,6 +1313,43 @@ static int msm_gpio_irq_set_affinity(struct irq_data *d, return -EINVAL; } +static int msm_gpio_irq_set_irqchip_state(struct irq_data *d, + enum irqchip_irq_state which, bool val) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct msm_pinctrl *pctrl = gpiochip_get_data(gc); + const struct msm_pingroup *g = &pctrl->soc->groups[d->hwirq]; + + if (which != IRQCHIP_STATE_PENDING) + return -EINVAL; + + if (test_bit(d->hwirq, pctrl->skip_wake_irqs)) + return -EINVAL; + + msm_writel_intr_status(val, pctrl, g); + + return 0; +} + +static int msm_gpio_irq_get_irqchip_state(struct irq_data *d, + enum irqchip_irq_state which, bool *val) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct msm_pinctrl *pctrl = gpiochip_get_data(gc); + const struct msm_pingroup *g = &pctrl->soc->groups[d->hwirq]; + + if (which != IRQCHIP_STATE_PENDING) + return -EINVAL; + + if (test_bit(d->hwirq, pctrl->skip_wake_irqs)) + return -EINVAL; + + g = &pctrl->soc->groups[d->hwirq]; + *val = msm_readl_intr_status(pctrl, g); + + return 0; +} + static int msm_gpio_irq_set_vcpu_affinity(struct irq_data *d, void *vcpu_info) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); @@ -1401,6 +1438,8 @@ static const struct irq_chip msm_gpio_irq_chip = { .irq_request_resources = msm_gpio_irq_reqres, .irq_release_resources = msm_gpio_irq_relres, .irq_set_affinity = msm_gpio_irq_set_affinity, + .irq_set_irqchip_state = msm_gpio_irq_set_irqchip_state, + .irq_get_irqchip_state = msm_gpio_irq_get_irqchip_state, .irq_set_vcpu_affinity = msm_gpio_irq_set_vcpu_affinity, .flags = (IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_SET_TYPE_MASKED | -- cgit v1.2.3