Message ID | 1604561884-10166-1-git-send-email-mkshah@codeaurora.org (mailing list archive) |
---|---|
State | Accepted |
Commit | 71266d9d39366c9b24b866d811b3facaf837f13f |
Headers | show |
Series | pinctrl: qcom: Move clearing pending IRQ to .irq_request_resources callback | expand |
On Thu, Nov 5, 2020 at 8:38 AM Maulik Shah <mkshah@codeaurora.org> 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 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. > > Fixes: e35a6ae0eb3a ("pinctrl/msm: Setup GPIO chip in hierarchy") > Signed-off-by: Maulik Shah <mkshah@codeaurora.org> 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
On Tue 10 Nov 07:31 CST 2020, Linus Walleij wrote: > On Thu, Nov 5, 2020 at 8:38 AM Maulik Shah <mkshah@codeaurora.org> 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 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. > > > > Fixes: e35a6ae0eb3a ("pinctrl/msm: Setup GPIO chip in hierarchy") > > Signed-off-by: Maulik Shah <mkshah@codeaurora.org> > > 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. Acked-by: Bjorn Andersson <bjorn.andersson@linaro.org> Regards, Bjorn
Hi, On Wed, Nov 4, 2020 at 11:38 PM Maulik Shah <mkshah@codeaurora.org> 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 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. > > Fixes: e35a6ae0eb3a ("pinctrl/msm: Setup GPIO chip in hierarchy") > Signed-off-by: Maulik Shah <mkshah@codeaurora.org> > --- > drivers/pinctrl/qcom/pinctrl-msm.c | 32 +++++++++++++++++++------------- > 1 file changed, 19 insertions(+), 13 deletions(-) > > diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c > index c4bcda9..77a25bd 100644 > --- a/drivers/pinctrl/qcom/pinctrl-msm.c > +++ b/drivers/pinctrl/qcom/pinctrl-msm.c > @@ -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); 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
Hello: This patch was applied to qcom/linux.git (refs/heads/for-next): 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 by enable_irq() then everytime during enable_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
diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c index c4bcda9..77a25bd 100644 --- a/drivers/pinctrl/qcom/pinctrl-msm.c +++ b/drivers/pinctrl/qcom/pinctrl-msm.c @@ -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);
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. Fixes: e35a6ae0eb3a ("pinctrl/msm: Setup GPIO chip in hierarchy") Signed-off-by: Maulik Shah <mkshah@codeaurora.org> --- drivers/pinctrl/qcom/pinctrl-msm.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-)