* [PATCH v5 1/2] ACPI: Add stubs for wakeup handler functions
@ 2021-10-28 14:45 Mario Limonciello
2021-10-28 14:45 ` [PATCH v5 2/2] pinctrl: amd: Fix wakeups when IRQ is shared with SCI Mario Limonciello
0 siblings, 1 reply; 4+ messages in thread
From: Mario Limonciello @ 2021-10-28 14:45 UTC (permalink / raw)
To: Linus Walleij, Basavaraj Natikar, Shyam Sundar S K
Cc: open list:PIN CONTROL SUBSYSTEM, open list, linux-acpi,
Nehal Shah, Mario Limonciello, stable, Rafael J . Wysocki
The commit ddfd9dcf270c ("ACPI: PM: Add acpi_[un]register_wakeup_handler()")
added new functions for drivers to use during the s2idle wakeup path, but
didn't add stubs for when CONFIG_ACPI wasn't set.
Add those stubs in for other drivers to be able to use.
Cc: stable@kernel.org
Fixes: ddfd9dcf270c ("ACPI: PM: Add acpi_[un]register_wakeup_handler()")
Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
---
Changes from v4->v5:
* Pick up Rafael's tag
* Target to stable as well
Changes from v3->v4:
* Reword commit message
* Adjust whitespace
* Return -ENXIO instead of -EINVAL
include/linux/acpi.h | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 72e4f7fd268c..e29b4c1da377 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -976,6 +976,15 @@ static inline int acpi_get_local_address(acpi_handle handle, u32 *addr)
return -ENODEV;
}
+static inline int acpi_register_wakeup_handler(int wake_irq,
+ bool (*wakeup)(void *context), void *context)
+{
+ return -ENXIO;
+}
+
+static inline void acpi_unregister_wakeup_handler(
+ bool (*wakeup)(void *context), void *context) { }
+
#endif /* !CONFIG_ACPI */
#ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
--
2.25.1
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH v5 2/2] pinctrl: amd: Fix wakeups when IRQ is shared with SCI
2021-10-28 14:45 [PATCH v5 1/2] ACPI: Add stubs for wakeup handler functions Mario Limonciello
@ 2021-10-28 14:45 ` Mario Limonciello
2021-10-28 14:58 ` Basavaraj Natikar
2021-10-29 15:01 ` kernel test robot
0 siblings, 2 replies; 4+ messages in thread
From: Mario Limonciello @ 2021-10-28 14:45 UTC (permalink / raw)
To: Linus Walleij, Basavaraj Natikar, Shyam Sundar S K
Cc: open list:PIN CONTROL SUBSYSTEM, open list, linux-acpi,
Nehal Shah, Mario Limonciello, stable, 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.
Cc: stable@kernel.org
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>
---
Note:
This is *possibly* a fix from fdde0ff8590b, 56b991849009 or other
changes in the acpi_s2idle_wake handling, but AMD didn't support
s2idle across the kernel widely until 5.14 or later. This is the
reason for lack of a fixes tag.
Changes from v4->v5:
* Correct debugging statement that was obfuscated by kernel %p behavior.
* Instead show actual GPIO number, which is much more useful for debugging
* Target to stable as well
Changes from v3->v4:
* Adjust to reverse xmas for newly added variable
* Add a debugging line to show the values in the register that caused system
wake to allow for debugging of spurious wakeups
Changes from v2->v3:
* Add new precursor patch for fixing missing ACPI function stubs
* Add __maybe_unused for unused function when set with COMPILE_TEST
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 | 31 ++++++++++++++++++++++++++++---
1 file changed, 28 insertions(+), 3 deletions(-)
diff --git a/drivers/pinctrl/pinctrl-amd.c b/drivers/pinctrl/pinctrl-amd.c
index d19974aceb2e..83fbcdad0904 100644
--- a/drivers/pinctrl/pinctrl-amd.c
+++ b/drivers/pinctrl/pinctrl-amd.c
@@ -598,14 +598,14 @@ 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;
+ bool ret = false;
u32 regval;
u64 status, mask;
@@ -627,6 +627,16 @@ 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))) {
+ dev_dbg(&gpio_dev->pdev->dev,
+ "Waking due to GPIO %ld: 0x%x",
+ regs + i - ((u32 __iomem *)gpio_dev->base), regval);
+ return true;
+ }
+
if (!(regval & PIN_IRQ_PENDING) ||
!(regval & BIT(INTERRUPT_MASK_OFF)))
continue;
@@ -652,9 +662,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 +679,16 @@ 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));
+}
+
+static bool __maybe_unused amd_gpio_check_wake(void *dev_id)
+{
+ return _amd_gpio_irq_handler(-1, dev_id);
+}
+
static int amd_get_groups_count(struct pinctrl_dev *pctldev)
{
struct amd_gpio *gpio_dev = pinctrl_dev_get_drvdata(pctldev);
@@ -1004,6 +1027,7 @@ static int amd_gpio_probe(struct platform_device *pdev)
goto out2;
platform_set_drvdata(pdev, gpio_dev);
+ acpi_register_wakeup_handler(gpio_dev->irq, amd_gpio_check_wake, gpio_dev);
dev_dbg(&pdev->dev, "amd gpio driver loaded\n");
return ret;
@@ -1021,6 +1045,7 @@ static int amd_gpio_remove(struct platform_device *pdev)
gpio_dev = platform_get_drvdata(pdev);
gpiochip_remove(&gpio_dev->gc);
+ acpi_unregister_wakeup_handler(amd_gpio_check_wake, gpio_dev);
return 0;
}
--
2.25.1
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH v5 2/2] pinctrl: amd: Fix wakeups when IRQ is shared with SCI
2021-10-28 14:45 ` [PATCH v5 2/2] pinctrl: amd: Fix wakeups when IRQ is shared with SCI Mario Limonciello
@ 2021-10-28 14:58 ` Basavaraj Natikar
2021-10-29 15:01 ` kernel test robot
1 sibling, 0 replies; 4+ messages in thread
From: Basavaraj Natikar @ 2021-10-28 14:58 UTC (permalink / raw)
To: Mario Limonciello, Linus Walleij, Basavaraj Natikar, Shyam Sundar S K
Cc: open list:PIN CONTROL SUBSYSTEM, open list, linux-acpi,
Nehal Shah, stable, Joerie de Gram
On 10/28/2021 8:15 PM, Mario Limonciello 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.
>
> Cc: stable@kernel.org
> 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>
> ---
> Note:
> This is *possibly* a fix from fdde0ff8590b, 56b991849009 or other
> changes in the acpi_s2idle_wake handling, but AMD didn't support
> s2idle across the kernel widely until 5.14 or later. This is the
> reason for lack of a fixes tag.
> Changes from v4->v5:
> * Correct debugging statement that was obfuscated by kernel %p behavior.
> * Instead show actual GPIO number, which is much more useful for debugging
> * Target to stable as well
> Changes from v3->v4:
> * Adjust to reverse xmas for newly added variable
> * Add a debugging line to show the values in the register that caused system
> wake to allow for debugging of spurious wakeups
> Changes from v2->v3:
> * Add new precursor patch for fixing missing ACPI function stubs
> * Add __maybe_unused for unused function when set with COMPILE_TEST
> 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 | 31 ++++++++++++++++++++++++++++---
> 1 file changed, 28 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/pinctrl/pinctrl-amd.c b/drivers/pinctrl/pinctrl-amd.c
> index d19974aceb2e..83fbcdad0904 100644
> --- a/drivers/pinctrl/pinctrl-amd.c
> +++ b/drivers/pinctrl/pinctrl-amd.c
> @@ -598,14 +598,14 @@ 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;
> + bool ret = false;
> u32 regval;
> u64 status, mask;
>
> @@ -627,6 +627,16 @@ 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))) {
> + dev_dbg(&gpio_dev->pdev->dev,
> + "Waking due to GPIO %ld: 0x%x",
> + regs + i - ((u32 __iomem *)gpio_dev->base), regval);
> + return true;
> + }
> +
> if (!(regval & PIN_IRQ_PENDING) ||
> !(regval & BIT(INTERRUPT_MASK_OFF)))
> continue;
> @@ -652,9 +662,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 +679,16 @@ 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));
> +}
> +
> +static bool __maybe_unused amd_gpio_check_wake(void *dev_id)
> +{
> + return _amd_gpio_irq_handler(-1, dev_id);
> +}
> +
> static int amd_get_groups_count(struct pinctrl_dev *pctldev)
> {
> struct amd_gpio *gpio_dev = pinctrl_dev_get_drvdata(pctldev);
> @@ -1004,6 +1027,7 @@ static int amd_gpio_probe(struct platform_device *pdev)
> goto out2;
>
> platform_set_drvdata(pdev, gpio_dev);
> + acpi_register_wakeup_handler(gpio_dev->irq, amd_gpio_check_wake, gpio_dev);
>
> dev_dbg(&pdev->dev, "amd gpio driver loaded\n");
> return ret;
> @@ -1021,6 +1045,7 @@ static int amd_gpio_remove(struct platform_device *pdev)
> gpio_dev = platform_get_drvdata(pdev);
>
> gpiochip_remove(&gpio_dev->gc);
> + acpi_unregister_wakeup_handler(amd_gpio_check_wake, gpio_dev);
>
> return 0;
> }
Looks good to me
Acked-by: Basavaraj Natikar <Basavaraj.Natikar@amd.com>
Thanks,
Basavaraj
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH v5 2/2] pinctrl: amd: Fix wakeups when IRQ is shared with SCI
2021-10-28 14:45 ` [PATCH v5 2/2] pinctrl: amd: Fix wakeups when IRQ is shared with SCI Mario Limonciello
2021-10-28 14:58 ` Basavaraj Natikar
@ 2021-10-29 15:01 ` kernel test robot
1 sibling, 0 replies; 4+ messages in thread
From: kernel test robot @ 2021-10-29 15:01 UTC (permalink / raw)
To: Mario Limonciello, Linus Walleij, Basavaraj Natikar, Shyam Sundar S K
Cc: kbuild-all, open list:PIN CONTROL SUBSYSTEM, open list,
linux-acpi, Nehal Shah, Mario Limonciello, stable,
Joerie de Gram
[-- Attachment #1: Type: text/plain, Size: 7011 bytes --]
Hi Mario,
Thank you for the patch! Yet something to improve:
[auto build test ERROR on linusw-pinctrl/devel]
[also build test ERROR on rafael-pm/linux-next linus/master v5.15-rc7 next-20211028]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]
url: https://github.com/0day-ci/linux/commits/Mario-Limonciello/ACPI-Add-stubs-for-wakeup-handler-functions/20211028-224738
base: https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl.git devel
config: powerpc-allyesconfig (attached as .config)
compiler: powerpc-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/0day-ci/linux/commit/aa823b07a228116ebb416d3c49ec526e78c6c138
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Mario-Limonciello/ACPI-Add-stubs-for-wakeup-handler-functions/20211028-224738
git checkout aa823b07a228116ebb416d3c49ec526e78c6c138
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross ARCH=powerpc
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
All errors (new ones prefixed by >>):
In file included from include/linux/printk.h:555,
from include/asm-generic/bug.h:22,
from arch/powerpc/include/asm/bug.h:149,
from include/linux/bug.h:5,
from drivers/pinctrl/pinctrl-amd.c:14:
drivers/pinctrl/pinctrl-amd.c: In function '_amd_gpio_irq_handler':
>> drivers/pinctrl/pinctrl-amd.c:625:41: error: format '%ld' expects argument of type 'long int', but argument 4 has type 'int' [-Werror=format=]
625 | "Waking due to GPIO %ld: 0x%x",
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/dynamic_debug.h:134:29: note: in definition of macro '__dynamic_func_call'
134 | func(&id, ##__VA_ARGS__); \
| ^~~~~~~~~~~
include/linux/dynamic_debug.h:166:9: note: in expansion of macro '_dynamic_func_call'
166 | _dynamic_func_call(fmt,__dynamic_dev_dbg, \
| ^~~~~~~~~~~~~~~~~~
include/linux/dev_printk.h:155:9: note: in expansion of macro 'dynamic_dev_dbg'
155 | dynamic_dev_dbg(dev, dev_fmt(fmt), ##__VA_ARGS__)
| ^~~~~~~~~~~~~~~
include/linux/dev_printk.h:155:30: note: in expansion of macro 'dev_fmt'
155 | dynamic_dev_dbg(dev, dev_fmt(fmt), ##__VA_ARGS__)
| ^~~~~~~
drivers/pinctrl/pinctrl-amd.c:624:33: note: in expansion of macro 'dev_dbg'
624 | dev_dbg(&gpio_dev->pdev->dev,
| ^~~~~~~
drivers/pinctrl/pinctrl-amd.c:625:63: note: format string is defined here
625 | "Waking due to GPIO %ld: 0x%x",
| ~~^
| |
| long int
| %d
drivers/pinctrl/pinctrl-amd.c: In function 'amd_gpio_probe':
drivers/pinctrl/pinctrl-amd.c:1019:46: error: 'struct amd_gpio' has no member named 'irq'
1019 | acpi_register_wakeup_handler(gpio_dev->irq, amd_gpio_check_wake, gpio_dev);
| ^~
cc1: all warnings being treated as errors
vim +625 drivers/pinctrl/pinctrl-amd.c
590
591 static bool _amd_gpio_irq_handler(int irq, void *dev_id)
592 {
593 struct amd_gpio *gpio_dev = dev_id;
594 struct gpio_chip *gc = &gpio_dev->gc;
595 unsigned int i, irqnr;
596 unsigned long flags;
597 u32 __iomem *regs;
598 bool ret = false;
599 u32 regval;
600 u64 status, mask;
601
602 /* Read the wake status */
603 raw_spin_lock_irqsave(&gpio_dev->lock, flags);
604 status = readl(gpio_dev->base + WAKE_INT_STATUS_REG1);
605 status <<= 32;
606 status |= readl(gpio_dev->base + WAKE_INT_STATUS_REG0);
607 raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
608
609 /* Bit 0-45 contain the relevant status bits */
610 status &= (1ULL << 46) - 1;
611 regs = gpio_dev->base;
612 for (mask = 1, irqnr = 0; status; mask <<= 1, regs += 4, irqnr += 4) {
613 if (!(status & mask))
614 continue;
615 status &= ~mask;
616
617 /* Each status bit covers four pins */
618 for (i = 0; i < 4; i++) {
619 regval = readl(regs + i);
620 /* called from resume context on a shared IRQ, just
621 * checking wake source.
622 */
623 if (irq < 0 && (regval & BIT(WAKE_STS_OFF))) {
624 dev_dbg(&gpio_dev->pdev->dev,
> 625 "Waking due to GPIO %ld: 0x%x",
626 regs + i - ((u32 __iomem *)gpio_dev->base), regval);
627 return true;
628 }
629
630 if (!(regval & PIN_IRQ_PENDING) ||
631 !(regval & BIT(INTERRUPT_MASK_OFF)))
632 continue;
633 generic_handle_domain_irq(gc->irq.domain, irqnr + i);
634
635 /* Clear interrupt.
636 * We must read the pin register again, in case the
637 * value was changed while executing
638 * generic_handle_domain_irq() above.
639 * If we didn't find a mapping for the interrupt,
640 * disable it in order to avoid a system hang caused
641 * by an interrupt storm.
642 */
643 raw_spin_lock_irqsave(&gpio_dev->lock, flags);
644 regval = readl(regs + i);
645 if (irq == 0) {
646 regval &= ~BIT(INTERRUPT_ENABLE_OFF);
647 dev_dbg(&gpio_dev->pdev->dev,
648 "Disabling spurious GPIO IRQ %d\n",
649 irqnr + i);
650 }
651 writel(regval, regs + i);
652 raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
653 ret = true;
654 }
655 }
656 /* called from resume context on shared IRQ but didn't cause wake */
657 if (irq < 0)
658 return false;
659
660 /* Signal EOI to the GPIO unit */
661 raw_spin_lock_irqsave(&gpio_dev->lock, flags);
662 regval = readl(gpio_dev->base + WAKE_INT_MASTER_REG);
663 regval |= EOI_MASK;
664 writel(regval, gpio_dev->base + WAKE_INT_MASTER_REG);
665 raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
666
667 return ret;
668 }
669
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 72134 bytes --]
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2021-10-29 15:03 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-10-28 14:45 [PATCH v5 1/2] ACPI: Add stubs for wakeup handler functions Mario Limonciello
2021-10-28 14:45 ` [PATCH v5 2/2] pinctrl: amd: Fix wakeups when IRQ is shared with SCI Mario Limonciello
2021-10-28 14:58 ` Basavaraj Natikar
2021-10-29 15:01 ` kernel test robot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®