Skip to content

Commit

Permalink
Input: axp20x-pek - respect userspace wakeup configuration
Browse files Browse the repository at this point in the history
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 <samuel@sholland.org>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Link: https://lore.kernel.org/r/20200115051253.32603-2-samuel@sholland.org
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
  • Loading branch information
Samuel Holland authored and Dmitry Torokhov committed Jan 22, 2020
1 parent 0dfed6d commit fe77f9b
Showing 1 changed file with 36 additions and 1 deletion.
37 changes: 36 additions & 1 deletion drivers/input/misc/axp20x-pek.c
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ static int axp20x_pek_probe_input_device(struct axp20x_pek *axp20x_pek,
}

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

return 0;
}
Expand Down Expand Up @@ -353,6 +353,40 @@ static int axp20x_pek_probe(struct platform_device *pdev)
return 0;
}

static int __maybe_unused axp20x_pek_suspend(struct device *dev)
{
struct axp20x_pek *axp20x_pek = dev_get_drvdata(dev);

/*
* As nested threaded IRQs are not automatically disabled during
* suspend, we must explicitly disable non-wakeup IRQs.
*/
if (device_may_wakeup(dev)) {
enable_irq_wake(axp20x_pek->irq_dbf);
enable_irq_wake(axp20x_pek->irq_dbr);
} else {
disable_irq(axp20x_pek->irq_dbf);
disable_irq(axp20x_pek->irq_dbr);
}

return 0;
}

static int __maybe_unused axp20x_pek_resume(struct device *dev)
{
struct axp20x_pek *axp20x_pek = dev_get_drvdata(dev);

if (device_may_wakeup(dev)) {
disable_irq_wake(axp20x_pek->irq_dbf);
disable_irq_wake(axp20x_pek->irq_dbr);
} else {
enable_irq(axp20x_pek->irq_dbf);
enable_irq(axp20x_pek->irq_dbr);
}

return 0;
}

static int __maybe_unused axp20x_pek_resume_noirq(struct device *dev)
{
struct axp20x_pek *axp20x_pek = dev_get_drvdata(dev);
Expand All @@ -372,6 +406,7 @@ static int __maybe_unused axp20x_pek_resume_noirq(struct device *dev)
}

static const struct dev_pm_ops axp20x_pek_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(axp20x_pek_suspend, axp20x_pek_resume)
#ifdef CONFIG_PM_SLEEP
.resume_noirq = axp20x_pek_resume_noirq,
#endif
Expand Down

0 comments on commit fe77f9b

Please sign in to comment.