[PATCH] pinctrl: qcom: Add irq_get/set_irqchip_state() for msm gpio irqchip

From: Sneh Mankad

Date: Fri Apr 24 2026 - 02:31:54 EST


From: Maulik Shah <maulik.shah@xxxxxxxxxxxxxxxx>

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 <maulik.shah@xxxxxxxxxxxxxxxx>
Signed-off-by: Sneh Mankad <sneh.mankad@xxxxxxxxxxxxxxxx>
---
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 45b3a2763eb85405fecdd4770ba3d4ab684563f0..925fca82252413d8e21fb47a0cc3a9ade7d5fe67 100644
--- a/drivers/pinctrl/qcom/pinctrl-msm.c
+++ b/drivers/pinctrl/qcom/pinctrl-msm.c
@@ -1305,6 +1305,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);
@@ -1393,6 +1430,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 |

---
base-commit: b4e07588e743c989499ca24d49e752c074924a9a
change-id: 20260424-pinctrl_irqchip_states-aae4f32f9f6e

Best regards,
--
Sneh Mankad <sneh.mankad@xxxxxxxxxxxxxxxx>