* [PATCH v2] pinctrl: intel: fix unexpected interrupt
@ 2022-01-24 12:55 Lukasz Bartosik
2022-01-24 13:30 ` Andy Shevchenko
0 siblings, 1 reply; 2+ messages in thread
From: Lukasz Bartosik @ 2022-01-24 12:55 UTC (permalink / raw)
To: Andy Shevchenko, Mika Westerberg, linus.walleij; +Cc: linux-gpio, upstream
From: Łukasz Bartosik <lb@semihalf.com>
ASUS Chromebook C223 with Celeron N3350 crashes sometimes during
cold booot. Inspection of the kernel log showed that it gets into
an inifite loop logging the following message:
->handle_irq(): 000000009cdb51e8, handle_bad_irq+0x0/0x251
->irq_data.chip(): 000000005ec212a7, 0xffffa043009d8e7
->action(): 00000
IRQ_NOPROBE set
unexpected IRQ trap at vector 7c
The issue happens during cold boot but only if cold boot happens
at most several dozen seconds after Chromebook is powered off. For
longer intervals between power off and power on (cold boot) the issue
does not reproduce. The unexpected interrupt is sourced from INT3452
GPIO pin which is used for SD card detect. Investigation relevealed
that when the interval between power off and power on (cold boot)
is less than several dozen seconds then values of INT3452 GPIO interrupt
enable and interrupt pending registers survive power off and power
on sequence and interrupt for SD card detect pin is enabled and pending
during probe of SD controller which causes the unexpected IRQ message.
"Intel Pentium and Celeron Processor N- and J- Series" volume 3 doc
mentions that GPIO interrupt enable and status registers default
value is 0x0.
The fix clears INT3452 GPIO interrupt enabled and interrupt pending
registers in its probe function.
Fixes: 7981c0015af2 ("pinctrl: intel: Add Intel Sunrisepoint pin controller and GPIO support")
Signed-off-by: Łukasz Bartosik <lb@semihalf.com>
---
drivers/pinctrl/intel/pinctrl-intel.c | 54 +++++++++++++++++----------
1 file changed, 34 insertions(+), 20 deletions(-)
diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c
index b6ef1911c1dd..12bad1a9aa9c 100644
--- a/drivers/pinctrl/intel/pinctrl-intel.c
+++ b/drivers/pinctrl/intel/pinctrl-intel.c
@@ -1268,6 +1268,39 @@ static unsigned int intel_gpio_ngpio(const struct intel_pinctrl *pctrl)
return ngpio;
}
+static void intel_gpio_irq_init(struct intel_pinctrl *pctrl)
+{
+ size_t i;
+
+ for (i = 0; i < pctrl->ncommunities; i++) {
+ const struct intel_community *community;
+ void __iomem *base;
+ unsigned int gpp;
+
+ community = &pctrl->communities[i];
+ base = community->regs;
+
+ for (gpp = 0; gpp < community->ngpps; gpp++) {
+ /* Mask and clear all interrupts */
+ writel(0, base + community->ie_offset + gpp * 4);
+ writel(0xffff, base + community->is_offset + gpp * 4);
+ }
+ }
+}
+
+static int init_hw(struct gpio_chip *gc)
+{
+ struct intel_pinctrl *pctrl = container_of(gc, struct intel_pinctrl,
+ chip);
+ /*
+ * Make sure the interrupt lines are in a proper state before
+ * further configuration
+ */
+ intel_gpio_irq_init(pctrl);
+
+ return 0;
+}
+
static int intel_gpio_probe(struct intel_pinctrl *pctrl, int irq)
{
int ret;
@@ -1311,6 +1344,7 @@ static int intel_gpio_probe(struct intel_pinctrl *pctrl, int irq)
girq->num_parents = 0;
girq->default_type = IRQ_TYPE_NONE;
girq->handler = handle_bad_irq;
+ girq->init_hw = init_hw;
ret = devm_gpiochip_add_data(pctrl->dev, &pctrl->chip, pctrl);
if (ret) {
@@ -1640,26 +1674,6 @@ int intel_pinctrl_suspend_noirq(struct device *dev)
}
EXPORT_SYMBOL_GPL(intel_pinctrl_suspend_noirq);
-static void intel_gpio_irq_init(struct intel_pinctrl *pctrl)
-{
- size_t i;
-
- for (i = 0; i < pctrl->ncommunities; i++) {
- const struct intel_community *community;
- void __iomem *base;
- unsigned int gpp;
-
- community = &pctrl->communities[i];
- base = community->regs;
-
- for (gpp = 0; gpp < community->ngpps; gpp++) {
- /* Mask and clear all interrupts */
- writel(0, base + community->ie_offset + gpp * 4);
- writel(0xffff, base + community->is_offset + gpp * 4);
- }
- }
-}
-
static bool intel_gpio_update_reg(void __iomem *reg, u32 mask, u32 value)
{
u32 curr, updated;
--
2.35.0.rc0.227.g00780c9af4-goog
^ permalink raw reply related [flat|nested] 2+ messages in thread* Re: [PATCH v2] pinctrl: intel: fix unexpected interrupt
2022-01-24 12:55 [PATCH v2] pinctrl: intel: fix unexpected interrupt Lukasz Bartosik
@ 2022-01-24 13:30 ` Andy Shevchenko
0 siblings, 0 replies; 2+ messages in thread
From: Andy Shevchenko @ 2022-01-24 13:30 UTC (permalink / raw)
To: Lukasz Bartosik
Cc: Andy Shevchenko, Mika Westerberg, linus.walleij, linux-gpio,
upstream
On Mon, Jan 24, 2022 at 01:55:29PM +0100, Lukasz Bartosik wrote:
> From: Łukasz Bartosik <lb@semihalf.com>
>
> ASUS Chromebook C223 with Celeron N3350 crashes sometimes during
> cold booot. Inspection of the kernel log showed that it gets into
> an inifite loop logging the following message:
>
> ->handle_irq(): 000000009cdb51e8, handle_bad_irq+0x0/0x251
> ->irq_data.chip(): 000000005ec212a7, 0xffffa043009d8e7
> ->action(): 00000
> IRQ_NOPROBE set
> unexpected IRQ trap at vector 7c
>
> The issue happens during cold boot but only if cold boot happens
> at most several dozen seconds after Chromebook is powered off. For
> longer intervals between power off and power on (cold boot) the issue
> does not reproduce. The unexpected interrupt is sourced from INT3452
> GPIO pin which is used for SD card detect. Investigation relevealed
> that when the interval between power off and power on (cold boot)
> is less than several dozen seconds then values of INT3452 GPIO interrupt
> enable and interrupt pending registers survive power off and power
> on sequence and interrupt for SD card detect pin is enabled and pending
> during probe of SD controller which causes the unexpected IRQ message.
> "Intel Pentium and Celeron Processor N- and J- Series" volume 3 doc
> mentions that GPIO interrupt enable and status registers default
> value is 0x0.
> The fix clears INT3452 GPIO interrupt enabled and interrupt pending
> registers in its probe function.
Pushed to my review and testing queue, thanks!
> Fixes: 7981c0015af2 ("pinctrl: intel: Add Intel Sunrisepoint pin controller and GPIO support")
> Signed-off-by: Łukasz Bartosik <lb@semihalf.com>
> ---
> drivers/pinctrl/intel/pinctrl-intel.c | 54 +++++++++++++++++----------
> 1 file changed, 34 insertions(+), 20 deletions(-)
>
> diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c
> index b6ef1911c1dd..12bad1a9aa9c 100644
> --- a/drivers/pinctrl/intel/pinctrl-intel.c
> +++ b/drivers/pinctrl/intel/pinctrl-intel.c
> @@ -1268,6 +1268,39 @@ static unsigned int intel_gpio_ngpio(const struct intel_pinctrl *pctrl)
> return ngpio;
> }
>
> +static void intel_gpio_irq_init(struct intel_pinctrl *pctrl)
> +{
> + size_t i;
> +
> + for (i = 0; i < pctrl->ncommunities; i++) {
> + const struct intel_community *community;
> + void __iomem *base;
> + unsigned int gpp;
> +
> + community = &pctrl->communities[i];
> + base = community->regs;
> +
> + for (gpp = 0; gpp < community->ngpps; gpp++) {
> + /* Mask and clear all interrupts */
> + writel(0, base + community->ie_offset + gpp * 4);
> + writel(0xffff, base + community->is_offset + gpp * 4);
> + }
> + }
> +}
> +
> +static int init_hw(struct gpio_chip *gc)
> +{
> + struct intel_pinctrl *pctrl = container_of(gc, struct intel_pinctrl,
> + chip);
> + /*
> + * Make sure the interrupt lines are in a proper state before
> + * further configuration
> + */
> + intel_gpio_irq_init(pctrl);
> +
> + return 0;
> +}
> +
> static int intel_gpio_probe(struct intel_pinctrl *pctrl, int irq)
> {
> int ret;
> @@ -1311,6 +1344,7 @@ static int intel_gpio_probe(struct intel_pinctrl *pctrl, int irq)
> girq->num_parents = 0;
> girq->default_type = IRQ_TYPE_NONE;
> girq->handler = handle_bad_irq;
> + girq->init_hw = init_hw;
>
> ret = devm_gpiochip_add_data(pctrl->dev, &pctrl->chip, pctrl);
> if (ret) {
> @@ -1640,26 +1674,6 @@ int intel_pinctrl_suspend_noirq(struct device *dev)
> }
> EXPORT_SYMBOL_GPL(intel_pinctrl_suspend_noirq);
>
> -static void intel_gpio_irq_init(struct intel_pinctrl *pctrl)
> -{
> - size_t i;
> -
> - for (i = 0; i < pctrl->ncommunities; i++) {
> - const struct intel_community *community;
> - void __iomem *base;
> - unsigned int gpp;
> -
> - community = &pctrl->communities[i];
> - base = community->regs;
> -
> - for (gpp = 0; gpp < community->ngpps; gpp++) {
> - /* Mask and clear all interrupts */
> - writel(0, base + community->ie_offset + gpp * 4);
> - writel(0xffff, base + community->is_offset + gpp * 4);
> - }
> - }
> -}
> -
> static bool intel_gpio_update_reg(void __iomem *reg, u32 mask, u32 value)
> {
> u32 curr, updated;
> --
> 2.35.0.rc0.227.g00780c9af4-goog
>
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2022-01-24 13:31 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-01-24 12:55 [PATCH v2] pinctrl: intel: fix unexpected interrupt Lukasz Bartosik
2022-01-24 13:30 ` Andy Shevchenko
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox