* [PATCH] platform/x86/amd/pmc: Only disable IRQ1 wakeup where i8042 actually enabled it
@ 2024-12-29 16:43 Maciej S. Szmigiero
2024-12-29 16:58 ` Ilpo Järvinen
2025-01-06 3:11 ` Mario Limonciello
0 siblings, 2 replies; 8+ messages in thread
From: Maciej S. Szmigiero @ 2024-12-29 16:43 UTC (permalink / raw)
To: Shyam Sundar S K, Mario Limonciello
Cc: Hans de Goede, Ilpo Järvinen, platform-driver-x86,
linux-kernel
Wakeup for IRQ1 should be disabled only in cases where i8042 had actually
enabled it, otherwise "wake_depth" for this IRQ will try do drop below zero
and there will be an unpleasant WARN() logged:
kernel: atkbd serio0: Disabling IRQ1 wakeup source to avoid platform firmware bug
kernel: ------------[ cut here ]------------
kernel: Unbalanced IRQ 1 wake disable
kernel: WARNING: CPU: 10 PID: 6431 at kernel/irq/manage.c:920 irq_set_irq_wake+0x147/0x1a0
To fix this call the PMC suspend handler only from the same set of
dev_pm_ops handlers as i8042_pm_suspend() is called, which currently means
just the ".suspend" handler.
Previously, the code would use DEFINE_SIMPLE_DEV_PM_OPS() to define its
dev_pm_ops, which also called this handler on ".freeze" and ".poweroff".
To reproduce this issue try hibernating (S4) the machine after a fresh boot
without putting it into s2idle first.
Fixes: 8e60615e8932 ("platform/x86/amd: pmc: Disable IRQ1 wakeup for RN/CZN")
Signed-off-by: Maciej S. Szmigiero <mail@maciej.szmigiero.name>
---
drivers/platform/x86/amd/pmc/pmc.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/platform/x86/amd/pmc/pmc.c b/drivers/platform/x86/amd/pmc/pmc.c
index 26b878ee5191..a254debb9256 100644
--- a/drivers/platform/x86/amd/pmc/pmc.c
+++ b/drivers/platform/x86/amd/pmc/pmc.c
@@ -947,6 +947,10 @@ static int amd_pmc_suspend_handler(struct device *dev)
{
struct amd_pmc_dev *pdev = dev_get_drvdata(dev);
+ /*
+ * Must be called only from the same set of dev_pm_ops handlers
+ * as i8042_pm_suspend() is called: currently just from .suspend.
+ */
if (pdev->disable_8042_wakeup && !disable_workarounds) {
int rc = amd_pmc_wa_irq1(pdev);
@@ -959,7 +963,9 @@ static int amd_pmc_suspend_handler(struct device *dev)
return 0;
}
-static DEFINE_SIMPLE_DEV_PM_OPS(amd_pmc_pm, amd_pmc_suspend_handler, NULL);
+static const struct dev_pm_ops amd_pmc_pm = {
+ .suspend = amd_pmc_suspend_handler,
+};
static const struct pci_device_id pmc_pci_ids[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, AMD_CPU_ID_PS) },
^ permalink raw reply related [flat|nested] 8+ messages in thread* Re: [PATCH] platform/x86/amd/pmc: Only disable IRQ1 wakeup where i8042 actually enabled it 2024-12-29 16:43 [PATCH] platform/x86/amd/pmc: Only disable IRQ1 wakeup where i8042 actually enabled it Maciej S. Szmigiero @ 2024-12-29 16:58 ` Ilpo Järvinen 2024-12-29 17:03 ` Maciej S. Szmigiero 2025-01-06 3:11 ` Mario Limonciello 1 sibling, 1 reply; 8+ messages in thread From: Ilpo Järvinen @ 2024-12-29 16:58 UTC (permalink / raw) To: Maciej S. Szmigiero Cc: Shyam Sundar S K, Mario Limonciello, Hans de Goede, platform-driver-x86, LKML On Sun, 29 Dec 2024, Maciej S. Szmigiero wrote: > Wakeup for IRQ1 should be disabled only in cases where i8042 had actually > enabled it, otherwise "wake_depth" for this IRQ will try do drop below zero > and there will be an unpleasant WARN() logged: > kernel: atkbd serio0: Disabling IRQ1 wakeup source to avoid platform firmware bug > kernel: ------------[ cut here ]------------ > kernel: Unbalanced IRQ 1 wake disable > kernel: WARNING: CPU: 10 PID: 6431 at kernel/irq/manage.c:920 irq_set_irq_wake+0x147/0x1a0 > > To fix this call the PMC suspend handler only from the same set of > dev_pm_ops handlers as i8042_pm_suspend() is called, which currently means > just the ".suspend" handler. > Previously, the code would use DEFINE_SIMPLE_DEV_PM_OPS() to define its > dev_pm_ops, which also called this handler on ".freeze" and ".poweroff". > > To reproduce this issue try hibernating (S4) the machine after a fresh boot > without putting it into s2idle first. > > Fixes: 8e60615e8932 ("platform/x86/amd: pmc: Disable IRQ1 wakeup for RN/CZN") > Signed-off-by: Maciej S. Szmigiero <mail@maciej.szmigiero.name> > --- > drivers/platform/x86/amd/pmc/pmc.c | 8 +++++++- > 1 file changed, 7 insertions(+), 1 deletion(-) > > diff --git a/drivers/platform/x86/amd/pmc/pmc.c b/drivers/platform/x86/amd/pmc/pmc.c > index 26b878ee5191..a254debb9256 100644 > --- a/drivers/platform/x86/amd/pmc/pmc.c > +++ b/drivers/platform/x86/amd/pmc/pmc.c > @@ -947,6 +947,10 @@ static int amd_pmc_suspend_handler(struct device *dev) > { > struct amd_pmc_dev *pdev = dev_get_drvdata(dev); > > + /* > + * Must be called only from the same set of dev_pm_ops handlers > + * as i8042_pm_suspend() is called: currently just from .suspend. > + */ > if (pdev->disable_8042_wakeup && !disable_workarounds) { > int rc = amd_pmc_wa_irq1(pdev); > > @@ -959,7 +963,9 @@ static int amd_pmc_suspend_handler(struct device *dev) > return 0; > } > > -static DEFINE_SIMPLE_DEV_PM_OPS(amd_pmc_pm, amd_pmc_suspend_handler, NULL); > +static const struct dev_pm_ops amd_pmc_pm = { > + .suspend = amd_pmc_suspend_handler, > +}; ??? I cannot see what this change is supposed to achieve. #define _DEFINE_DEV_PM_OPS(name, \ suspend_fn, resume_fn, \ runtime_suspend_fn, runtime_resume_fn, idle_fn) \ const struct dev_pm_ops name = { \ SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \ RUNTIME_PM_OPS(runtime_suspend_fn, runtime_resume_fn, idle_fn) \ } #define DEFINE_SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn) \ _DEFINE_DEV_PM_OPS(name, suspend_fn, resume_fn, NULL, NULL, NULL) #define SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \ .suspend = pm_sleep_ptr(suspend_fn), \ .resume = pm_sleep_ptr(resume_fn), \ .freeze = pm_sleep_ptr(suspend_fn), \ .thaw = pm_sleep_ptr(resume_fn), \ .poweroff = pm_sleep_ptr(suspend_fn), \ .restore = pm_sleep_ptr(resume_fn), #define pm_sleep_ptr(_ptr) PTR_IF(IS_ENABLED(CONFIG_PM_SLEEP), (_ptr)) Under what circumstances does this change result in some difference? -- i. ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] platform/x86/amd/pmc: Only disable IRQ1 wakeup where i8042 actually enabled it 2024-12-29 16:58 ` Ilpo Järvinen @ 2024-12-29 17:03 ` Maciej S. Szmigiero 2024-12-29 17:13 ` Ilpo Järvinen 2024-12-29 17:19 ` Ilpo Järvinen 0 siblings, 2 replies; 8+ messages in thread From: Maciej S. Szmigiero @ 2024-12-29 17:03 UTC (permalink / raw) To: Ilpo Järvinen Cc: Shyam Sundar S K, Mario Limonciello, Hans de Goede, platform-driver-x86, LKML On 29.12.2024 17:58, Ilpo Järvinen wrote: > On Sun, 29 Dec 2024, Maciej S. Szmigiero wrote: > >> Wakeup for IRQ1 should be disabled only in cases where i8042 had actually >> enabled it, otherwise "wake_depth" for this IRQ will try do drop below zero >> and there will be an unpleasant WARN() logged: >> kernel: atkbd serio0: Disabling IRQ1 wakeup source to avoid platform firmware bug >> kernel: ------------[ cut here ]------------ >> kernel: Unbalanced IRQ 1 wake disable >> kernel: WARNING: CPU: 10 PID: 6431 at kernel/irq/manage.c:920 irq_set_irq_wake+0x147/0x1a0 >> >> To fix this call the PMC suspend handler only from the same set of >> dev_pm_ops handlers as i8042_pm_suspend() is called, which currently means >> just the ".suspend" handler. >> Previously, the code would use DEFINE_SIMPLE_DEV_PM_OPS() to define its >> dev_pm_ops, which also called this handler on ".freeze" and ".poweroff". >> >> To reproduce this issue try hibernating (S4) the machine after a fresh boot >> without putting it into s2idle first. >> >> Fixes: 8e60615e8932 ("platform/x86/amd: pmc: Disable IRQ1 wakeup for RN/CZN") >> Signed-off-by: Maciej S. Szmigiero <mail@maciej.szmigiero.name> >> --- >> drivers/platform/x86/amd/pmc/pmc.c | 8 +++++++- >> 1 file changed, 7 insertions(+), 1 deletion(-) >> >> diff --git a/drivers/platform/x86/amd/pmc/pmc.c b/drivers/platform/x86/amd/pmc/pmc.c >> index 26b878ee5191..a254debb9256 100644 >> --- a/drivers/platform/x86/amd/pmc/pmc.c >> +++ b/drivers/platform/x86/amd/pmc/pmc.c >> @@ -947,6 +947,10 @@ static int amd_pmc_suspend_handler(struct device *dev) >> { >> struct amd_pmc_dev *pdev = dev_get_drvdata(dev); >> >> + /* >> + * Must be called only from the same set of dev_pm_ops handlers >> + * as i8042_pm_suspend() is called: currently just from .suspend. >> + */ >> if (pdev->disable_8042_wakeup && !disable_workarounds) { >> int rc = amd_pmc_wa_irq1(pdev); >> >> @@ -959,7 +963,9 @@ static int amd_pmc_suspend_handler(struct device *dev) >> return 0; >> } >> >> -static DEFINE_SIMPLE_DEV_PM_OPS(amd_pmc_pm, amd_pmc_suspend_handler, NULL); >> +static const struct dev_pm_ops amd_pmc_pm = { >> + .suspend = amd_pmc_suspend_handler, >> +}; > > ??? > > I cannot see what this change is supposed to achieve. > > #define _DEFINE_DEV_PM_OPS(name, \ > suspend_fn, resume_fn, \ > runtime_suspend_fn, runtime_resume_fn, idle_fn) \ > const struct dev_pm_ops name = { \ > SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \ > RUNTIME_PM_OPS(runtime_suspend_fn, runtime_resume_fn, idle_fn) \ > } > > #define DEFINE_SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn) \ > _DEFINE_DEV_PM_OPS(name, suspend_fn, resume_fn, NULL, NULL, NULL) > > #define SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \ > .suspend = pm_sleep_ptr(suspend_fn), \ > .resume = pm_sleep_ptr(resume_fn), \ > .freeze = pm_sleep_ptr(suspend_fn), \ > .thaw = pm_sleep_ptr(resume_fn), \ > .poweroff = pm_sleep_ptr(suspend_fn), \ > .restore = pm_sleep_ptr(resume_fn), > > #define pm_sleep_ptr(_ptr) PTR_IF(IS_ENABLED(CONFIG_PM_SLEEP), (_ptr)) > > Under what circumstances does this change result in some difference? > .freeze and .poweroff are now both NULL, just like in the i8042 driver. As I wrote in the commit message: >> Previously, the code would use DEFINE_SIMPLE_DEV_PM_OPS() to define its >> dev_pm_ops, *which also called this handler on ".freeze" and ".poweroff".* Thanks, Maciej ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] platform/x86/amd/pmc: Only disable IRQ1 wakeup where i8042 actually enabled it 2024-12-29 17:03 ` Maciej S. Szmigiero @ 2024-12-29 17:13 ` Ilpo Järvinen 2024-12-29 17:36 ` Maciej S. Szmigiero 2024-12-29 17:19 ` Ilpo Järvinen 1 sibling, 1 reply; 8+ messages in thread From: Ilpo Järvinen @ 2024-12-29 17:13 UTC (permalink / raw) To: Maciej S. Szmigiero Cc: Shyam Sundar S K, Mario Limonciello, Hans de Goede, platform-driver-x86, LKML [-- Attachment #1: Type: text/plain, Size: 4206 bytes --] On Sun, 29 Dec 2024, Maciej S. Szmigiero wrote: > On 29.12.2024 17:58, Ilpo Järvinen wrote: > > On Sun, 29 Dec 2024, Maciej S. Szmigiero wrote: > > > > > Wakeup for IRQ1 should be disabled only in cases where i8042 had actually > > > enabled it, otherwise "wake_depth" for this IRQ will try do drop below > > > zero > > > and there will be an unpleasant WARN() logged: > > > kernel: atkbd serio0: Disabling IRQ1 wakeup source to avoid platform > > > firmware bug > > > kernel: ------------[ cut here ]------------ > > > kernel: Unbalanced IRQ 1 wake disable > > > kernel: WARNING: CPU: 10 PID: 6431 at kernel/irq/manage.c:920 > > > irq_set_irq_wake+0x147/0x1a0 > > > > > > To fix this call the PMC suspend handler only from the same set of > > > dev_pm_ops handlers as i8042_pm_suspend() is called, which currently means > > > just the ".suspend" handler. > > > Previously, the code would use DEFINE_SIMPLE_DEV_PM_OPS() to define its > > > dev_pm_ops, which also called this handler on ".freeze" and ".poweroff". > > > > > > To reproduce this issue try hibernating (S4) the machine after a fresh > > > boot > > > without putting it into s2idle first. > > > > > > Fixes: 8e60615e8932 ("platform/x86/amd: pmc: Disable IRQ1 wakeup for > > > RN/CZN") > > > Signed-off-by: Maciej S. Szmigiero <mail@maciej.szmigiero.name> > > > --- > > > drivers/platform/x86/amd/pmc/pmc.c | 8 +++++++- > > > 1 file changed, 7 insertions(+), 1 deletion(-) > > > > > > diff --git a/drivers/platform/x86/amd/pmc/pmc.c > > > b/drivers/platform/x86/amd/pmc/pmc.c > > > index 26b878ee5191..a254debb9256 100644 > > > --- a/drivers/platform/x86/amd/pmc/pmc.c > > > +++ b/drivers/platform/x86/amd/pmc/pmc.c > > > @@ -947,6 +947,10 @@ static int amd_pmc_suspend_handler(struct device > > > *dev) > > > { > > > struct amd_pmc_dev *pdev = dev_get_drvdata(dev); > > > + /* > > > + * Must be called only from the same set of dev_pm_ops handlers > > > + * as i8042_pm_suspend() is called: currently just from .suspend. > > > + */ > > > if (pdev->disable_8042_wakeup && !disable_workarounds) { > > > int rc = amd_pmc_wa_irq1(pdev); > > > @@ -959,7 +963,9 @@ static int amd_pmc_suspend_handler(struct device > > > *dev) > > > return 0; > > > } > > > -static DEFINE_SIMPLE_DEV_PM_OPS(amd_pmc_pm, amd_pmc_suspend_handler, > > > NULL); > > > +static const struct dev_pm_ops amd_pmc_pm = { > > > + .suspend = amd_pmc_suspend_handler, > > > +}; > > > > ??? > > > > I cannot see what this change is supposed to achieve. > > > > #define _DEFINE_DEV_PM_OPS(name, \ > > suspend_fn, resume_fn, \ > > runtime_suspend_fn, runtime_resume_fn, idle_fn) > > \ > > const struct dev_pm_ops name = { \ > > SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \ > > RUNTIME_PM_OPS(runtime_suspend_fn, runtime_resume_fn, idle_fn) \ > > } > > > > #define DEFINE_SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn) \ > > _DEFINE_DEV_PM_OPS(name, suspend_fn, resume_fn, NULL, NULL, NULL) > > > > #define SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \ > > .suspend = pm_sleep_ptr(suspend_fn), \ > > .resume = pm_sleep_ptr(resume_fn), \ > > .freeze = pm_sleep_ptr(suspend_fn), \ > > .thaw = pm_sleep_ptr(resume_fn), \ > > .poweroff = pm_sleep_ptr(suspend_fn), \ > > .restore = pm_sleep_ptr(resume_fn), > > > > #define pm_sleep_ptr(_ptr) PTR_IF(IS_ENABLED(CONFIG_PM_SLEEP), (_ptr)) > > > > Under what circumstances does this change result in some difference? > > > > .freeze and .poweroff are now both NULL, just like in the i8042 driver. > > As I wrote in the commit message: > > > Previously, the code would use DEFINE_SIMPLE_DEV_PM_OPS() to define its > > > dev_pm_ops, *which also called this handler on ".freeze" and ".poweroff".* Ah, I'm sorry. Too much not aligned macro text to parse. Will it now trigger a warning if some PM CONFIG is not enabled? Those pm_sleep_ptr() are there to avoid those warnings so the handler pointer would likely need to be wrapped inside pm_sleep_ptr(). -- i. ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] platform/x86/amd/pmc: Only disable IRQ1 wakeup where i8042 actually enabled it 2024-12-29 17:13 ` Ilpo Järvinen @ 2024-12-29 17:36 ` Maciej S. Szmigiero 0 siblings, 0 replies; 8+ messages in thread From: Maciej S. Szmigiero @ 2024-12-29 17:36 UTC (permalink / raw) To: Ilpo Järvinen Cc: Shyam Sundar S K, Mario Limonciello, Hans de Goede, platform-driver-x86, LKML On 29.12.2024 18:13, Ilpo Järvinen wrote: > On Sun, 29 Dec 2024, Maciej S. Szmigiero wrote: > >> On 29.12.2024 17:58, Ilpo Järvinen wrote: >>> On Sun, 29 Dec 2024, Maciej S. Szmigiero wrote: >>> >>>> Wakeup for IRQ1 should be disabled only in cases where i8042 had actually >>>> enabled it, otherwise "wake_depth" for this IRQ will try do drop below >>>> zero >>>> and there will be an unpleasant WARN() logged: >>>> kernel: atkbd serio0: Disabling IRQ1 wakeup source to avoid platform >>>> firmware bug >>>> kernel: ------------[ cut here ]------------ >>>> kernel: Unbalanced IRQ 1 wake disable >>>> kernel: WARNING: CPU: 10 PID: 6431 at kernel/irq/manage.c:920 >>>> irq_set_irq_wake+0x147/0x1a0 >>>> >>>> To fix this call the PMC suspend handler only from the same set of >>>> dev_pm_ops handlers as i8042_pm_suspend() is called, which currently means >>>> just the ".suspend" handler. >>>> Previously, the code would use DEFINE_SIMPLE_DEV_PM_OPS() to define its >>>> dev_pm_ops, which also called this handler on ".freeze" and ".poweroff". >>>> >>>> To reproduce this issue try hibernating (S4) the machine after a fresh >>>> boot >>>> without putting it into s2idle first. >>>> >>>> Fixes: 8e60615e8932 ("platform/x86/amd: pmc: Disable IRQ1 wakeup for >>>> RN/CZN") >>>> Signed-off-by: Maciej S. Szmigiero <mail@maciej.szmigiero.name> >>>> --- >>>> drivers/platform/x86/amd/pmc/pmc.c | 8 +++++++- >>>> 1 file changed, 7 insertions(+), 1 deletion(-) >>>> >>>> diff --git a/drivers/platform/x86/amd/pmc/pmc.c >>>> b/drivers/platform/x86/amd/pmc/pmc.c >>>> index 26b878ee5191..a254debb9256 100644 >>>> --- a/drivers/platform/x86/amd/pmc/pmc.c >>>> +++ b/drivers/platform/x86/amd/pmc/pmc.c >>>> @@ -947,6 +947,10 @@ static int amd_pmc_suspend_handler(struct device >>>> *dev) >>>> { >>>> struct amd_pmc_dev *pdev = dev_get_drvdata(dev); >>>> + /* >>>> + * Must be called only from the same set of dev_pm_ops handlers >>>> + * as i8042_pm_suspend() is called: currently just from .suspend. >>>> + */ >>>> if (pdev->disable_8042_wakeup && !disable_workarounds) { >>>> int rc = amd_pmc_wa_irq1(pdev); >>>> @@ -959,7 +963,9 @@ static int amd_pmc_suspend_handler(struct device >>>> *dev) >>>> return 0; >>>> } >>>> -static DEFINE_SIMPLE_DEV_PM_OPS(amd_pmc_pm, amd_pmc_suspend_handler, >>>> NULL); >>>> +static const struct dev_pm_ops amd_pmc_pm = { >>>> + .suspend = amd_pmc_suspend_handler, >>>> +}; >>> >>> ??? >>> >>> I cannot see what this change is supposed to achieve. >>> >>> #define _DEFINE_DEV_PM_OPS(name, \ >>> suspend_fn, resume_fn, \ >>> runtime_suspend_fn, runtime_resume_fn, idle_fn) >>> \ >>> const struct dev_pm_ops name = { \ >>> SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \ >>> RUNTIME_PM_OPS(runtime_suspend_fn, runtime_resume_fn, idle_fn) \ >>> } >>> >>> #define DEFINE_SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn) \ >>> _DEFINE_DEV_PM_OPS(name, suspend_fn, resume_fn, NULL, NULL, NULL) >>> >>> #define SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \ >>> .suspend = pm_sleep_ptr(suspend_fn), \ >>> .resume = pm_sleep_ptr(resume_fn), \ >>> .freeze = pm_sleep_ptr(suspend_fn), \ >>> .thaw = pm_sleep_ptr(resume_fn), \ >>> .poweroff = pm_sleep_ptr(suspend_fn), \ >>> .restore = pm_sleep_ptr(resume_fn), >>> >>> #define pm_sleep_ptr(_ptr) PTR_IF(IS_ENABLED(CONFIG_PM_SLEEP), (_ptr)) >>> >>> Under what circumstances does this change result in some difference? >>> >> >> .freeze and .poweroff are now both NULL, just like in the i8042 driver. >> >> As I wrote in the commit message: >>>> Previously, the code would use DEFINE_SIMPLE_DEV_PM_OPS() to define its >>>> dev_pm_ops, *which also called this handler on ".freeze" and ".poweroff".* > > Ah, I'm sorry. Too much not aligned macro text to parse. > > Will it now trigger a warning if some PM CONFIG is not enabled? Those > pm_sleep_ptr() are there to avoid those warnings so the handler pointer > would likely need to be wrapped inside pm_sleep_ptr(). > pm_sleep_ptr() only changes its meaning based on CONFIG_PM_SLEEP: #define pm_sleep_ptr(_ptr) PTR_IF(IS_ENABLED(CONFIG_PM_SLEEP), (_ptr)) CONFIG_PM_SLEEP gets enabled if CONFIG_SUSPEND is on: > config PM_SLEEP > def_bool y > depends on SUSPEND || HIBERNATE_CALLBACKS And CONFIG_SUSPEND has to be on since the whole driver depends on it: > config AMD_PMC > tristate "AMD SoC PMC driver" > depends on ACPI && PCI && RTC_CLASS && AMD_NB > depends on SUSPEND Thanks, Maciej ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] platform/x86/amd/pmc: Only disable IRQ1 wakeup where i8042 actually enabled it 2024-12-29 17:03 ` Maciej S. Szmigiero 2024-12-29 17:13 ` Ilpo Järvinen @ 2024-12-29 17:19 ` Ilpo Järvinen 2024-12-29 17:36 ` Maciej S. Szmigiero 1 sibling, 1 reply; 8+ messages in thread From: Ilpo Järvinen @ 2024-12-29 17:19 UTC (permalink / raw) To: Maciej S. Szmigiero Cc: Shyam Sundar S K, Mario Limonciello, Hans de Goede, platform-driver-x86, LKML [-- Attachment #1: Type: text/plain, Size: 4044 bytes --] On Sun, 29 Dec 2024, Maciej S. Szmigiero wrote: > On 29.12.2024 17:58, Ilpo Järvinen wrote: > > On Sun, 29 Dec 2024, Maciej S. Szmigiero wrote: > > > > > Wakeup for IRQ1 should be disabled only in cases where i8042 had actually > > > enabled it, otherwise "wake_depth" for this IRQ will try do drop below > > > zero > > > and there will be an unpleasant WARN() logged: > > > kernel: atkbd serio0: Disabling IRQ1 wakeup source to avoid platform > > > firmware bug > > > kernel: ------------[ cut here ]------------ > > > kernel: Unbalanced IRQ 1 wake disable > > > kernel: WARNING: CPU: 10 PID: 6431 at kernel/irq/manage.c:920 > > > irq_set_irq_wake+0x147/0x1a0 > > > > > > To fix this call the PMC suspend handler only from the same set of > > > dev_pm_ops handlers as i8042_pm_suspend() is called, which currently means > > > just the ".suspend" handler. > > > Previously, the code would use DEFINE_SIMPLE_DEV_PM_OPS() to define its > > > dev_pm_ops, which also called this handler on ".freeze" and ".poweroff". > > > > > > To reproduce this issue try hibernating (S4) the machine after a fresh > > > boot > > > without putting it into s2idle first. > > > > > > Fixes: 8e60615e8932 ("platform/x86/amd: pmc: Disable IRQ1 wakeup for > > > RN/CZN") > > > Signed-off-by: Maciej S. Szmigiero <mail@maciej.szmigiero.name> > > > --- > > > drivers/platform/x86/amd/pmc/pmc.c | 8 +++++++- > > > 1 file changed, 7 insertions(+), 1 deletion(-) > > > > > > diff --git a/drivers/platform/x86/amd/pmc/pmc.c > > > b/drivers/platform/x86/amd/pmc/pmc.c > > > index 26b878ee5191..a254debb9256 100644 > > > --- a/drivers/platform/x86/amd/pmc/pmc.c > > > +++ b/drivers/platform/x86/amd/pmc/pmc.c > > > @@ -947,6 +947,10 @@ static int amd_pmc_suspend_handler(struct device > > > *dev) > > > { > > > struct amd_pmc_dev *pdev = dev_get_drvdata(dev); > > > + /* > > > + * Must be called only from the same set of dev_pm_ops handlers > > > + * as i8042_pm_suspend() is called: currently just from .suspend. > > > + */ > > > if (pdev->disable_8042_wakeup && !disable_workarounds) { > > > int rc = amd_pmc_wa_irq1(pdev); > > > @@ -959,7 +963,9 @@ static int amd_pmc_suspend_handler(struct device > > > *dev) > > > return 0; > > > } > > > -static DEFINE_SIMPLE_DEV_PM_OPS(amd_pmc_pm, amd_pmc_suspend_handler, > > > NULL); > > > +static const struct dev_pm_ops amd_pmc_pm = { > > > + .suspend = amd_pmc_suspend_handler, > > > +}; > > > > ??? > > > > I cannot see what this change is supposed to achieve. > > > > #define _DEFINE_DEV_PM_OPS(name, \ > > suspend_fn, resume_fn, \ > > runtime_suspend_fn, runtime_resume_fn, idle_fn) > > \ > > const struct dev_pm_ops name = { \ > > SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \ > > RUNTIME_PM_OPS(runtime_suspend_fn, runtime_resume_fn, idle_fn) \ > > } > > > > #define DEFINE_SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn) \ > > _DEFINE_DEV_PM_OPS(name, suspend_fn, resume_fn, NULL, NULL, NULL) > > > > #define SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \ > > .suspend = pm_sleep_ptr(suspend_fn), \ > > .resume = pm_sleep_ptr(resume_fn), \ > > .freeze = pm_sleep_ptr(suspend_fn), \ > > .thaw = pm_sleep_ptr(resume_fn), \ > > .poweroff = pm_sleep_ptr(suspend_fn), \ > > .restore = pm_sleep_ptr(resume_fn), > > > > #define pm_sleep_ptr(_ptr) PTR_IF(IS_ENABLED(CONFIG_PM_SLEEP), (_ptr)) > > > > Under what circumstances does this change result in some difference? > > > > .freeze and .poweroff are now both NULL, just like in the i8042 driver. > > As I wrote in the commit message: > > > Previously, the code would use DEFINE_SIMPLE_DEV_PM_OPS() to define its > > > dev_pm_ops, *which also called this handler on ".freeze" and ".poweroff".* Also, please avoid using "previously" like this. I interpreted it like some old kernel did that. -- i. ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] platform/x86/amd/pmc: Only disable IRQ1 wakeup where i8042 actually enabled it 2024-12-29 17:19 ` Ilpo Järvinen @ 2024-12-29 17:36 ` Maciej S. Szmigiero 0 siblings, 0 replies; 8+ messages in thread From: Maciej S. Szmigiero @ 2024-12-29 17:36 UTC (permalink / raw) To: Ilpo Järvinen Cc: Shyam Sundar S K, Mario Limonciello, Hans de Goede, platform-driver-x86, LKML On 29.12.2024 18:19, Ilpo Järvinen wrote: > On Sun, 29 Dec 2024, Maciej S. Szmigiero wrote: > >> On 29.12.2024 17:58, Ilpo Järvinen wrote: >>> On Sun, 29 Dec 2024, Maciej S. Szmigiero wrote: >>> >>>> Wakeup for IRQ1 should be disabled only in cases where i8042 had actually >>>> enabled it, otherwise "wake_depth" for this IRQ will try do drop below >>>> zero >>>> and there will be an unpleasant WARN() logged: >>>> kernel: atkbd serio0: Disabling IRQ1 wakeup source to avoid platform >>>> firmware bug >>>> kernel: ------------[ cut here ]------------ >>>> kernel: Unbalanced IRQ 1 wake disable >>>> kernel: WARNING: CPU: 10 PID: 6431 at kernel/irq/manage.c:920 >>>> irq_set_irq_wake+0x147/0x1a0 >>>> >>>> To fix this call the PMC suspend handler only from the same set of >>>> dev_pm_ops handlers as i8042_pm_suspend() is called, which currently means >>>> just the ".suspend" handler. >>>> Previously, the code would use DEFINE_SIMPLE_DEV_PM_OPS() to define its >>>> dev_pm_ops, which also called this handler on ".freeze" and ".poweroff". >>>> >>>> To reproduce this issue try hibernating (S4) the machine after a fresh >>>> boot >>>> without putting it into s2idle first. >>>> >>>> Fixes: 8e60615e8932 ("platform/x86/amd: pmc: Disable IRQ1 wakeup for >>>> RN/CZN") >>>> Signed-off-by: Maciej S. Szmigiero <mail@maciej.szmigiero.name> >>>> --- >>>> drivers/platform/x86/amd/pmc/pmc.c | 8 +++++++- >>>> 1 file changed, 7 insertions(+), 1 deletion(-) >>>> >>>> diff --git a/drivers/platform/x86/amd/pmc/pmc.c >>>> b/drivers/platform/x86/amd/pmc/pmc.c >>>> index 26b878ee5191..a254debb9256 100644 >>>> --- a/drivers/platform/x86/amd/pmc/pmc.c >>>> +++ b/drivers/platform/x86/amd/pmc/pmc.c >>>> @@ -947,6 +947,10 @@ static int amd_pmc_suspend_handler(struct device >>>> *dev) >>>> { >>>> struct amd_pmc_dev *pdev = dev_get_drvdata(dev); >>>> + /* >>>> + * Must be called only from the same set of dev_pm_ops handlers >>>> + * as i8042_pm_suspend() is called: currently just from .suspend. >>>> + */ >>>> if (pdev->disable_8042_wakeup && !disable_workarounds) { >>>> int rc = amd_pmc_wa_irq1(pdev); >>>> @@ -959,7 +963,9 @@ static int amd_pmc_suspend_handler(struct device >>>> *dev) >>>> return 0; >>>> } >>>> -static DEFINE_SIMPLE_DEV_PM_OPS(amd_pmc_pm, amd_pmc_suspend_handler, >>>> NULL); >>>> +static const struct dev_pm_ops amd_pmc_pm = { >>>> + .suspend = amd_pmc_suspend_handler, >>>> +}; >>> >>> ??? >>> >>> I cannot see what this change is supposed to achieve. >>> >>> #define _DEFINE_DEV_PM_OPS(name, \ >>> suspend_fn, resume_fn, \ >>> runtime_suspend_fn, runtime_resume_fn, idle_fn) >>> \ >>> const struct dev_pm_ops name = { \ >>> SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \ >>> RUNTIME_PM_OPS(runtime_suspend_fn, runtime_resume_fn, idle_fn) \ >>> } >>> >>> #define DEFINE_SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn) \ >>> _DEFINE_DEV_PM_OPS(name, suspend_fn, resume_fn, NULL, NULL, NULL) >>> >>> #define SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \ >>> .suspend = pm_sleep_ptr(suspend_fn), \ >>> .resume = pm_sleep_ptr(resume_fn), \ >>> .freeze = pm_sleep_ptr(suspend_fn), \ >>> .thaw = pm_sleep_ptr(resume_fn), \ >>> .poweroff = pm_sleep_ptr(suspend_fn), \ >>> .restore = pm_sleep_ptr(resume_fn), >>> >>> #define pm_sleep_ptr(_ptr) PTR_IF(IS_ENABLED(CONFIG_PM_SLEEP), (_ptr)) >>> >>> Under what circumstances does this change result in some difference? >>> >> >> .freeze and .poweroff are now both NULL, just like in the i8042 driver. >> >> As I wrote in the commit message: >>>> Previously, the code would use DEFINE_SIMPLE_DEV_PM_OPS() to define its >>>> dev_pm_ops, *which also called this handler on ".freeze" and ".poweroff".* > > Also, please avoid using "previously" like this. I interpreted it like > some old kernel did that. > Sure, that sentence in the commit message could be rewritten using "the code before this patch" or something similar if that's easier to parse. Thanks, Maciej ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] platform/x86/amd/pmc: Only disable IRQ1 wakeup where i8042 actually enabled it 2024-12-29 16:43 [PATCH] platform/x86/amd/pmc: Only disable IRQ1 wakeup where i8042 actually enabled it Maciej S. Szmigiero 2024-12-29 16:58 ` Ilpo Järvinen @ 2025-01-06 3:11 ` Mario Limonciello 1 sibling, 0 replies; 8+ messages in thread From: Mario Limonciello @ 2025-01-06 3:11 UTC (permalink / raw) To: Maciej S. Szmigiero, Shyam Sundar S K Cc: Hans de Goede, Ilpo Järvinen, platform-driver-x86, linux-kernel On 12/29/2024 10:43, Maciej S. Szmigiero wrote: > Wakeup for IRQ1 should be disabled only in cases where i8042 had actually > enabled it, otherwise "wake_depth" for this IRQ will try do drop below zero > and there will be an unpleasant WARN() logged: > kernel: atkbd serio0: Disabling IRQ1 wakeup source to avoid platform firmware bug > kernel: ------------[ cut here ]------------ > kernel: Unbalanced IRQ 1 wake disable > kernel: WARNING: CPU: 10 PID: 6431 at kernel/irq/manage.c:920 irq_set_irq_wake+0x147/0x1a0 > > To fix this call the PMC suspend handler only from the same set of > dev_pm_ops handlers as i8042_pm_suspend() is called, which currently means > just the ".suspend" handler. > Previously, the code would use DEFINE_SIMPLE_DEV_PM_OPS() to define its > dev_pm_ops, which also called this handler on ".freeze" and ".poweroff". > > To reproduce this issue try hibernating (S4) the machine after a fresh boot > without putting it into s2idle first. > > Fixes: 8e60615e8932 ("platform/x86/amd: pmc: Disable IRQ1 wakeup for RN/CZN") > Signed-off-by: Maciej S. Szmigiero <mail@maciej.szmigiero.name> The code change makes sense to me. You can add this when you resubmit v2 for the commit message changes requested by Ilpo. Reviewed-by: Mario Limonciello <mario.limonciello@amd.com> > --- > drivers/platform/x86/amd/pmc/pmc.c | 8 +++++++- > 1 file changed, 7 insertions(+), 1 deletion(-) > > diff --git a/drivers/platform/x86/amd/pmc/pmc.c b/drivers/platform/x86/amd/pmc/pmc.c > index 26b878ee5191..a254debb9256 100644 > --- a/drivers/platform/x86/amd/pmc/pmc.c > +++ b/drivers/platform/x86/amd/pmc/pmc.c > @@ -947,6 +947,10 @@ static int amd_pmc_suspend_handler(struct device *dev) > { > struct amd_pmc_dev *pdev = dev_get_drvdata(dev); > > + /* > + * Must be called only from the same set of dev_pm_ops handlers > + * as i8042_pm_suspend() is called: currently just from .suspend. > + */ > if (pdev->disable_8042_wakeup && !disable_workarounds) { > int rc = amd_pmc_wa_irq1(pdev); > > @@ -959,7 +963,9 @@ static int amd_pmc_suspend_handler(struct device *dev) > return 0; > } > > -static DEFINE_SIMPLE_DEV_PM_OPS(amd_pmc_pm, amd_pmc_suspend_handler, NULL); > +static const struct dev_pm_ops amd_pmc_pm = { > + .suspend = amd_pmc_suspend_handler, > +}; > > static const struct pci_device_id pmc_pci_ids[] = { > { PCI_DEVICE(PCI_VENDOR_ID_AMD, AMD_CPU_ID_PS) }, ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2025-01-06 3:11 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2024-12-29 16:43 [PATCH] platform/x86/amd/pmc: Only disable IRQ1 wakeup where i8042 actually enabled it Maciej S. Szmigiero 2024-12-29 16:58 ` Ilpo Järvinen 2024-12-29 17:03 ` Maciej S. Szmigiero 2024-12-29 17:13 ` Ilpo Järvinen 2024-12-29 17:36 ` Maciej S. Szmigiero 2024-12-29 17:19 ` Ilpo Järvinen 2024-12-29 17:36 ` Maciej S. Szmigiero 2025-01-06 3:11 ` Mario Limonciello
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox