Skip to content

Commit 1cada2f

Browse files
committed
pinctrl: qcom: Assign irq_eoi conditionally
The hierarchical parts of MSM pinctrl/GPIO is only used when the device tree has a "wakeup-parent" as a phandle, but the .irq_eoi is anyway assigned leading to semantic problems on elder Qualcomm chipsets. When the drivers/mfd/qcom-pm8xxx.c driver calls chained_irq_exit() that call will in turn call chip->irq_eoi() which is set to irq_chip_eoi_parent() by default on a hierachical IRQ chip, and the parent is pinctrl-msm.c so that will in turn unconditionally call irq_chip_eoi_parent() again, but its parent is invalid so we get the following crash: Unnable to handle kernel NULL pointer dereference at virtual address 00000010 pgd = (ptrval) [00000010] *pgd=00000000 Internal error: Oops: 5 [#1] PREEMPT SMP ARM (...) PC is at irq_chip_eoi_parent+0x4/0x10 LR is at pm8xxx_irq_handler+0x1b4/0x2d8 If we solve this crash by avoiding to call up to irq_chip_eoi_parent(), the machine will hang and get reset by the watchdog, because of semantic issues, probably inside irq_chip. As a solution, just assign the .irq_eoi conditionally if we are actually using a wakeup parent. Cc: David Heidelberg <[email protected]> Cc: Bjorn Andersson <[email protected]> Cc: Lina Iyer <[email protected]> Cc: Stephen Boyd <[email protected]> Cc: [email protected] Fixes: e35a6ae ("pinctrl/msm: Setup GPIO chip in hierarchy") Link: https://lore.kernel.org/r/[email protected] Link: https://lore.kernel.org/r/[email protected] Link: https://lore.kernel.org/r/[email protected] Tested-by: David Heidelberg <[email protected]> Acked-by: Marc Zyngier <[email protected]> Signed-off-by: Linus Walleij <[email protected]>
1 parent d62e7fb commit 1cada2f

File tree

1 file changed

+1
-2
lines changed

1 file changed

+1
-2
lines changed

drivers/pinctrl/qcom/pinctrl-msm.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1104,7 +1104,6 @@ static int msm_gpio_init(struct msm_pinctrl *pctrl)
11041104
pctrl->irq_chip.irq_mask = msm_gpio_irq_mask;
11051105
pctrl->irq_chip.irq_unmask = msm_gpio_irq_unmask;
11061106
pctrl->irq_chip.irq_ack = msm_gpio_irq_ack;
1107-
pctrl->irq_chip.irq_eoi = irq_chip_eoi_parent;
11081107
pctrl->irq_chip.irq_set_type = msm_gpio_irq_set_type;
11091108
pctrl->irq_chip.irq_set_wake = msm_gpio_irq_set_wake;
11101109
pctrl->irq_chip.irq_request_resources = msm_gpio_irq_reqres;
@@ -1118,7 +1117,7 @@ static int msm_gpio_init(struct msm_pinctrl *pctrl)
11181117
if (!chip->irq.parent_domain)
11191118
return -EPROBE_DEFER;
11201119
chip->irq.child_to_parent_hwirq = msm_gpio_wakeirq;
1121-
1120+
pctrl->irq_chip.irq_eoi = irq_chip_eoi_parent;
11221121
/*
11231122
* Let's skip handling the GPIOs, if the parent irqchip
11241123
* is handling the direct connect IRQ of the GPIO.

0 commit comments

Comments
 (0)