Skip to content

Commit fe77f9b

Browse files
smaeuldtor
authored andcommitted
Input: axp20x-pek - respect userspace wakeup configuration
Unlike most other power button drivers, this driver unconditionally enables its wakeup IRQ. It should be using device_may_wakeup() to respect the userspace configuration of wakeup sources. Because the AXP20x MFD device uses regmap-irq, the AXP20x PEK IRQs are nested off of regmap-irq's threaded interrupt handler. The device core ignores such interrupts, so to actually disable wakeup, we must explicitly disable all non-wakeup interrupts during suspend. Signed-off-by: Samuel Holland <[email protected]> Reviewed-by: Hans de Goede <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Dmitry Torokhov <[email protected]>
1 parent 0dfed6d commit fe77f9b

File tree

1 file changed

+36
-1
lines changed

1 file changed

+36
-1
lines changed

drivers/input/misc/axp20x-pek.c

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ static int axp20x_pek_probe_input_device(struct axp20x_pek *axp20x_pek,
281281
}
282282

283283
if (axp20x_pek->axp20x->variant == AXP288_ID)
284-
enable_irq_wake(axp20x_pek->irq_dbr);
284+
device_init_wakeup(&pdev->dev, true);
285285

286286
return 0;
287287
}
@@ -353,6 +353,40 @@ static int axp20x_pek_probe(struct platform_device *pdev)
353353
return 0;
354354
}
355355

356+
static int __maybe_unused axp20x_pek_suspend(struct device *dev)
357+
{
358+
struct axp20x_pek *axp20x_pek = dev_get_drvdata(dev);
359+
360+
/*
361+
* As nested threaded IRQs are not automatically disabled during
362+
* suspend, we must explicitly disable non-wakeup IRQs.
363+
*/
364+
if (device_may_wakeup(dev)) {
365+
enable_irq_wake(axp20x_pek->irq_dbf);
366+
enable_irq_wake(axp20x_pek->irq_dbr);
367+
} else {
368+
disable_irq(axp20x_pek->irq_dbf);
369+
disable_irq(axp20x_pek->irq_dbr);
370+
}
371+
372+
return 0;
373+
}
374+
375+
static int __maybe_unused axp20x_pek_resume(struct device *dev)
376+
{
377+
struct axp20x_pek *axp20x_pek = dev_get_drvdata(dev);
378+
379+
if (device_may_wakeup(dev)) {
380+
disable_irq_wake(axp20x_pek->irq_dbf);
381+
disable_irq_wake(axp20x_pek->irq_dbr);
382+
} else {
383+
enable_irq(axp20x_pek->irq_dbf);
384+
enable_irq(axp20x_pek->irq_dbr);
385+
}
386+
387+
return 0;
388+
}
389+
356390
static int __maybe_unused axp20x_pek_resume_noirq(struct device *dev)
357391
{
358392
struct axp20x_pek *axp20x_pek = dev_get_drvdata(dev);
@@ -372,6 +406,7 @@ static int __maybe_unused axp20x_pek_resume_noirq(struct device *dev)
372406
}
373407

374408
static const struct dev_pm_ops axp20x_pek_pm_ops = {
409+
SET_SYSTEM_SLEEP_PM_OPS(axp20x_pek_suspend, axp20x_pek_resume)
375410
#ifdef CONFIG_PM_SLEEP
376411
.resume_noirq = axp20x_pek_resume_noirq,
377412
#endif

0 commit comments

Comments
 (0)