linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2] pinctrl: amd: Fix wakeups when IRQ is shared with SCI
@ 2021-10-19  3:26 Mario Limonciello
  2021-10-19 10:04 ` Andy Shevchenko
  0 siblings, 1 reply; 2+ messages in thread
From: Mario Limonciello @ 2021-10-19  3:26 UTC (permalink / raw)
  To: Linus Walleij, Basavaraj Natikar, Shyam Sundar S K
  Cc: open list:PIN CONTROL SUBSYSTEM, open list, Nehal Shah,
	Rafael J . Wysocki, Mario Limonciello, Joerie de Gram

On some Lenovo AMD Gen2 platforms the IRQ for the SCI and pinctrl drivers
are shared.  Due to how the s2idle loop handling works, this case needs
an extra explicit check whether the interrupt was caused by SCI or by
the GPIO controller.

To fix this rework the existing IRQ handler function to function as a
checker and an IRQ handler depending on the calling arguments.

BugLink: https://gitlab.freedesktop.org/drm/amd/-/issues/1738
Reported-by: Joerie de Gram <j.de.gram@gmail.com>
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
---
Changes from v1->v2:
 * drop Kconfig changes to drop COMPILE_TEST, instead #ifdef CONFIG_ACPI
 * fix a logic error during wakeup
 * Use IRQ_RETVAL()
 drivers/pinctrl/pinctrl-amd.c | 35 ++++++++++++++++++++++++++++++-----
 1 file changed, 30 insertions(+), 5 deletions(-)

diff --git a/drivers/pinctrl/pinctrl-amd.c b/drivers/pinctrl/pinctrl-amd.c
index d19974aceb2e..f7b44ecbbb79 100644
--- a/drivers/pinctrl/pinctrl-amd.c
+++ b/drivers/pinctrl/pinctrl-amd.c
@@ -598,16 +598,16 @@ static struct irq_chip amd_gpio_irqchip = {
 
 #define PIN_IRQ_PENDING	(BIT(INTERRUPT_STS_OFF) | BIT(WAKE_STS_OFF))
 
-static irqreturn_t amd_gpio_irq_handler(int irq, void *dev_id)
+static bool _amd_gpio_irq_handler(int irq, void *dev_id)
 {
 	struct amd_gpio *gpio_dev = dev_id;
 	struct gpio_chip *gc = &gpio_dev->gc;
-	irqreturn_t ret = IRQ_NONE;
 	unsigned int i, irqnr;
 	unsigned long flags;
 	u32 __iomem *regs;
 	u32  regval;
 	u64 status, mask;
+	bool ret = false;
 
 	/* Read the wake status */
 	raw_spin_lock_irqsave(&gpio_dev->lock, flags);
@@ -627,6 +627,12 @@ static irqreturn_t amd_gpio_irq_handler(int irq, void *dev_id)
 		/* Each status bit covers four pins */
 		for (i = 0; i < 4; i++) {
 			regval = readl(regs + i);
+			/* called from resume context on a shared IRQ, just
+			 * checking wake source.
+			 */
+			if (irq < 0 && (regval & BIT(WAKE_STS_OFF)))
+				return true;
+
 			if (!(regval & PIN_IRQ_PENDING) ||
 			    !(regval & BIT(INTERRUPT_MASK_OFF)))
 				continue;
@@ -652,9 +658,12 @@ static irqreturn_t amd_gpio_irq_handler(int irq, void *dev_id)
 			}
 			writel(regval, regs + i);
 			raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
-			ret = IRQ_HANDLED;
+			ret = true;
 		}
 	}
+	/* called from resume context on shared IRQ but didn't cause wake */
+	if (irq < 0)
+		return false;
 
 	/* Signal EOI to the GPIO unit */
 	raw_spin_lock_irqsave(&gpio_dev->lock, flags);
@@ -666,6 +675,18 @@ static irqreturn_t amd_gpio_irq_handler(int irq, void *dev_id)
 	return ret;
 }
 
+static irqreturn_t amd_gpio_irq_handler(int irq, void *dev_id)
+{
+	return IRQ_RETVAL(_amd_gpio_irq_handler(irq, dev_id));
+}
+
+#ifdef CONFIG_ACPI
+static bool amd_gpio_check_wake(void *dev_id)
+{
+	return _amd_gpio_irq_handler(-1, dev_id);
+}
+#endif
+
 static int amd_get_groups_count(struct pinctrl_dev *pctldev)
 {
 	struct amd_gpio *gpio_dev = pinctrl_dev_get_drvdata(pctldev);
@@ -1004,7 +1025,9 @@ static int amd_gpio_probe(struct platform_device *pdev)
 		goto out2;
 
 	platform_set_drvdata(pdev, gpio_dev);
-
+#ifdef CONFIG_ACPI
+	acpi_register_wakeup_handler(gpio_dev->irq, amd_gpio_check_wake, gpio_dev);
+#endif
 	dev_dbg(&pdev->dev, "amd gpio driver loaded\n");
 	return ret;
 
@@ -1021,7 +1044,9 @@ static int amd_gpio_remove(struct platform_device *pdev)
 	gpio_dev = platform_get_drvdata(pdev);
 
 	gpiochip_remove(&gpio_dev->gc);
-
+#ifdef CONFIG_ACPI
+	acpi_unregister_wakeup_handler(amd_gpio_check_wake, gpio_dev);
+#endif
 	return 0;
 }
 
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH v2] pinctrl: amd: Fix wakeups when IRQ is shared with SCI
  2021-10-19  3:26 [PATCH v2] pinctrl: amd: Fix wakeups when IRQ is shared with SCI Mario Limonciello
@ 2021-10-19 10:04 ` Andy Shevchenko
  0 siblings, 0 replies; 2+ messages in thread
From: Andy Shevchenko @ 2021-10-19 10:04 UTC (permalink / raw)
  To: Mario Limonciello
  Cc: Linus Walleij, Basavaraj Natikar, Shyam Sundar S K,
	open list:PIN CONTROL SUBSYSTEM, open list, Nehal Shah,
	Rafael J . Wysocki, Joerie de Gram

On Tue, Oct 19, 2021 at 6:27 AM Mario Limonciello
<mario.limonciello@amd.com> wrote:
>
> On some Lenovo AMD Gen2 platforms the IRQ for the SCI and pinctrl drivers
> are shared.  Due to how the s2idle loop handling works, this case needs
> an extra explicit check whether the interrupt was caused by SCI or by
> the GPIO controller.
>
> To fix this rework the existing IRQ handler function to function as a
> checker and an IRQ handler depending on the calling arguments.
>
> BugLink: https://gitlab.freedesktop.org/drm/amd/-/issues/1738

Should it have a Fixes tag?

> Reported-by: Joerie de Gram <j.de.gram@gmail.com>
> Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>

...

> +#ifdef CONFIG_ACPI

__maybe_unused?

> +static bool amd_gpio_check_wake(void *dev_id)
> +{
> +       return _amd_gpio_irq_handler(-1, dev_id);
> +}
> +#endif

...

> +#ifdef CONFIG_ACPI
> +       acpi_register_wakeup_handler(gpio_dev->irq, amd_gpio_check_wake, gpio_dev);
> +#endif

Not what I expected.

...

> +#ifdef CONFIG_ACPI
> +       acpi_unregister_wakeup_handler(amd_gpio_check_wake, gpio_dev);
> +#endif

Ditto.

Yes, I see the problem, perhaps you need to add the stubs. If this is
a real regression fix, then probably this patch should follow by two:
adding stubs, removing ugly ifdeffery here. Otherwise, introduce stubs
as patch 1 preceding this one in a series.

-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2021-10-19 10:05 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-10-19  3:26 [PATCH v2] pinctrl: amd: Fix wakeups when IRQ is shared with SCI Mario Limonciello
2021-10-19 10:04 ` Andy Shevchenko

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).