pinctrl: qcom: Move clearing pending IRQ to .irq_request_resources callback
Subsystems (5)
PATCH 1/1 pinctrl: qcom: Move clearing pending IRQ to .irq_request_resources callback
When GPIOs that are routed to PDC are used as output they can still latch the IRQ pending at GIC. As a result the spurious IRQ was handled when the client driver change the direction to input to starts using it as IRQ.
Currently such erroneous latched IRQ are cleared with .irq_enable callback however if the driver continue to use GPIO as interrupt and invokes disable_irq() followed by enable_irq() then everytime during enable_irq() previously latched interrupt gets cleared.
This can make edge IRQs not seen after enable_irq() if they had arrived after the driver has invoked disable_irq() and were pending at GIC.
Move clearing erroneous IRQ to .irq_request_resources callback as this is the place where GPIO direction is changed as input and its locked as IRQ.
While at this add a missing check to invoke msm_gpio_irq_clear_unmask() from .irq_enable callback only when GPIO is not routed to PDC.
--- drivers/pinctrl/qcom/pinctrl-msm.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-)
drivers/pinctrl/qcom/pinctrl-msm.c +19 -13
@@ -815,21 +815,14 @@ static void msm_gpio_irq_clear_unmask(struct irq_data *d, bool status_clear)static void msm_gpio_irq_enable (struct irq_data *d) { -/* -* Clear the interrupt that may be pending before we enable -* the line. -* This is especially a problem with the GPIOs routed to the -* PDC. These GPIOs are direct-connect interrupts to the GIC. -* Disabling the interrupt line at the PDC does not prevent -* the interrupt from being latched at the GIC. The state at -* GIC needs to be cleared before enabling. -*/ -if (d->parent_data) { -irq_chip_set_parent_state (d,IRQCHIP_STATE_PENDING ,0 ); +struct gpio_chip *gc =irq_data_get_irq_chip_data (d); +struct msm_pinctrl *pctrl =gpiochip_get_data (gc); + +if (d->parent_data)irq_chip_enable_parent (d); - } -msm_gpio_irq_clear_unmask (d, true); +if (!test_bit (d->hwirq, pctrl->skip_wake_irqs)) +msm_gpio_irq_clear_unmask (d, true); }static void msm_gpio_irq_disable (struct irq_data *d)
@@ -1104,6 +1097,19 @@ static int msm_gpio_irq_reqres(struct irq_data *d) ret = -EINVAL ; goto out; } + +/* +* Clear the interrupt that may be pending before we enable +* the line. +* This is especially a problem with the GPIOs routed to the +* PDC. These GPIOs are direct-connect interrupts to the GIC. +* Disabling the interrupt line at the PDC does not prevent +* the interrupt from being latched at the GIC. The state at +* GIC needs to be cleared before enabling. +*/ +if (d->parent_data &&test_bit (d->hwirq, pctrl->skip_wake_irqs)) +irq_chip_set_parent_state (d,IRQCHIP_STATE_PENDING ,0 ); +return 0 ; out:module_put (gc->owner);
Signature · 2 lines
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
Quoted 12 lines · Maulik Shah
When GPIOs that are routed to PDC are used as output they can still latch the IRQ pending at GIC. As a result the spurious IRQ was handled when the client driver change the direction to input to starts using it as IRQ.
Currently such erroneous latched IRQ are cleared with .irq_enable callback however if the driver continue to use GPIO as interrupt and invokes
disable_irq()followed byenable_irq()then everytime duringenable_irq()previously latched interrupt gets cleared.This can make edge IRQs not seen after
enable_irq()if they had arrived after the driver has invokeddisable_irq()and were pending at GIC.
Quoted 8 lines
Move clearing erroneous IRQ to .irq_request_resources callback as this is the place where GPIO direction is changed as input and its locked as IRQ.
While at this add a missing check to invoke
msm_gpio_irq_clear_unmask()from .irq_enable callback only when GPIO is not routed to PDC.Fixes e35a6ae0eb3a ("pinctrl/msm: Setup GPIO chip in hierarchy")Signed-off-by Maulik Shah <[email protected]>
This looks critical so I applied it for fixes so we get some rotation in linux-next.
If Bjorn has other opinions he will tell us :)
Yours,
Linus Walleij
Bjorn Andersson
Acked-byQuoted 20 lines · Linus Walleij
Quoted 18 lines · Maulik Shah
When GPIOs that are routed to PDC are used as output they can still latch the IRQ pending at GIC. As a result the spurious IRQ was handled when the client driver change the direction to input to starts using it as IRQ.
Currently such erroneous latched IRQ are cleared with .irq_enable callback however if the driver continue to use GPIO as interrupt and invokes
disable_irq()followed byenable_irq()then everytime duringenable_irq()previously latched interrupt gets cleared.This can make edge IRQs not seen after
enable_irq()if they had arrived after the driver has invokeddisable_irq()and were pending at GIC.Move clearing erroneous IRQ to .irq_request_resources callback as this is the place where GPIO direction is changed as input and its locked as IRQ.
While at this add a missing check to invoke
msm_gpio_irq_clear_unmask()from .irq_enable callback only when GPIO is not routed to PDC.
Quoted 8 lines
Quoted 2 lines
Fixes e35a6ae0eb3a ("pinctrl/msm: Setup GPIO chip in hierarchy")Signed-off-by Maulik Shah <[email protected]>This looks critical so I applied it for fixes so we get some rotation in linux-next.
If Bjorn has other opinions he will tell us :)
No objections, the patch looks reasonable to me.
Regards,
Bjorn
Hi,
Quoted 44 lines · Maulik Shah
When GPIOs that are routed to PDC are used as output they can still latch the IRQ pending at GIC. As a result the spurious IRQ was handled when the client driver change the direction to input to starts using it as IRQ.
Currently such erroneous latched IRQ are cleared with .irq_enable callback however if the driver continue to use GPIO as interrupt and invokes
disable_irq()followed byenable_irq()then everytime duringenable_irq()previously latched interrupt gets cleared.This can make edge IRQs not seen after
enable_irq()if they had arrived after the driver has invokeddisable_irq()and were pending at GIC.Move clearing erroneous IRQ to .irq_request_resources callback as this is the place where GPIO direction is changed as input and its locked as IRQ.
While at this add a missing check to invoke
msm_gpio_irq_clear_unmask()from .irq_enable callback only when GPIO is not routed to PDC.Fixes e35a6ae0eb3a ("pinctrl/msm: Setup GPIO chip in hierarchy")Signed-off-by Maulik Shah <[email protected]>--- drivers/pinctrl/qcom/pinctrl-msm.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-)drivers/pinctrl/qcom/pinctrl-msm.c +0
-11@@ -815,21 +815,14 @@ static void msm_gpio_irq_clear_unmask(struct irq_data *d, bool status_clear)static void msm_gpio_irq_enable (struct irq_data *d) { -/* -* Clear the interrupt that may be pending before we enable -* the line. -* This is especially a problem with the GPIOs routed to the -* PDC. These GPIOs are direct-connect interrupts to the GIC. -* Disabling the interrupt line at the PDC does not prevent -* the interrupt from being latched at the GIC. The state at -* GIC needs to be cleared before enabling. -*/ -if (d->parent_data) { -irq_chip_set_parent_state (d,IRQCHIP_STATE_PENDING ,0 );
drivers/pinctrl/qcom/pinctrl-msm.c static void msm_gpio_irq_clear_unmask(struct irq_data *d, bool status_clear) · line 825
Quoted 10 lines
drivers/pinctrl/qcom/pinctrl-msm.c +6
-2+struct gpio_chip *gc =irq_data_get_irq_chip_data (d); +struct msm_pinctrl *pctrl =gpiochip_get_data (gc); + +if (d->parent_data)irq_chip_enable_parent (d); - } -msm_gpio_irq_clear_unmask (d, true); +if (!test_bit (d->hwirq, pctrl->skip_wake_irqs)) +msm_gpio_irq_clear_unmask (d, true);
I'm happy that this patch landed and it seems a definite improvement. However, it seems like we're still clearing important edges in the case where the PDC isn't used. Can't we just unconditionally move the clearing to msm_gpio_irq_reqres()?
-Doug
This patch was applied to qcom/linux.git (refs/heads/for-next):
Hello:
This patch was applied to qcom/linux.git (refs/heads/for-next):
Quoted 10 lines · On Thu, 5 Nov 2020 13:08:04 +0530 you wrote:
When GPIOs that are routed to PDC are used as output they can still latch the IRQ pending at GIC. As a result the spurious IRQ was handled when the client driver change the direction to input to starts using it as IRQ.
Currently such erroneous latched IRQ are cleared with .irq_enable callback however if the driver continue to use GPIO as interrupt and invokes
disable_irq()followed byenable_irq()then everytime duringenable_irq()previously latched interrupt gets cleared.[...]
Here is the summary with links:
- pinctrl: qcom: Move clearing pending IRQ to .irq_request_resources callback
https://git.kernel.org/qcom/c/71266d9d3936
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html