81 lines
2.8 KiB
Diff
81 lines
2.8 KiB
Diff
|
From da443bc125265cae24a0e5f7d1c7bba196a9319f Mon Sep 17 00:00:00 2001
|
||
|
From: Linus Walleij <linus.walleij@linaro.org>
|
||
|
Date: Thu, 22 Feb 2018 08:34:35 +0100
|
||
|
Subject: [PATCH 26/31] power: gemini-poweroff: Avoid spurious poweroff
|
||
|
|
||
|
On the D-Link DIR-685 we get spurious poweroff from
|
||
|
infrared. Since that block (CIR) doesn't even have a
|
||
|
driver this can be safely ignored, we can revisit this
|
||
|
code once we have a device supporting CIR.
|
||
|
|
||
|
On the D-Link DNS-313 we get spurious poweroff from
|
||
|
the power button. This appears to be an initialization
|
||
|
issue: we need to enable the block (start the state
|
||
|
machine) before we clear any dangling IRQ.
|
||
|
|
||
|
This patch fixes both issues.
|
||
|
|
||
|
Fixes: f7a388d6cd1c ("power: reset: Add a driver for the Gemini poweroff")
|
||
|
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
|
||
|
---
|
||
|
ChangeLog v1->v2:
|
||
|
- Fix both issues and rename the patch.
|
||
|
- Proper commit message with specifics.
|
||
|
---
|
||
|
drivers/power/reset/gemini-poweroff.c | 30 +++++++++++++++++-------------
|
||
|
1 file changed, 17 insertions(+), 13 deletions(-)
|
||
|
|
||
|
--- a/drivers/power/reset/gemini-poweroff.c
|
||
|
+++ b/drivers/power/reset/gemini-poweroff.c
|
||
|
@@ -47,8 +47,12 @@ static irqreturn_t gemini_powerbutton_in
|
||
|
val &= 0x70U;
|
||
|
switch (val) {
|
||
|
case GEMINI_STAT_CIR:
|
||
|
- dev_info(gpw->dev, "infrared poweroff\n");
|
||
|
- orderly_poweroff(true);
|
||
|
+ /*
|
||
|
+ * We do not yet have a driver for the infrared
|
||
|
+ * controller so it can cause spurious poweroff
|
||
|
+ * events. Ignore those for now.
|
||
|
+ */
|
||
|
+ dev_info(gpw->dev, "infrared poweroff - ignored\n");
|
||
|
break;
|
||
|
case GEMINI_STAT_RTC:
|
||
|
dev_info(gpw->dev, "RTC poweroff\n");
|
||
|
@@ -116,7 +120,17 @@ static int gemini_poweroff_probe(struct
|
||
|
return -ENODEV;
|
||
|
}
|
||
|
|
||
|
- /* Clear the power management IRQ */
|
||
|
+ /*
|
||
|
+ * Enable the power controller. This is crucial on Gemini
|
||
|
+ * systems: if this is not done, pressing the power button
|
||
|
+ * will result in unconditional poweroff without any warning.
|
||
|
+ * This makes the kernel handle the poweroff.
|
||
|
+ */
|
||
|
+ val = readl(gpw->base + GEMINI_PWC_CTRLREG);
|
||
|
+ val |= GEMINI_CTRL_ENABLE;
|
||
|
+ writel(val, gpw->base + GEMINI_PWC_CTRLREG);
|
||
|
+
|
||
|
+ /* Now that the state machine is active, clear the IRQ */
|
||
|
val = readl(gpw->base + GEMINI_PWC_CTRLREG);
|
||
|
val |= GEMINI_CTRL_IRQ_CLR;
|
||
|
writel(val, gpw->base + GEMINI_PWC_CTRLREG);
|
||
|
@@ -129,16 +143,6 @@ static int gemini_poweroff_probe(struct
|
||
|
pm_power_off = gemini_poweroff;
|
||
|
gpw_poweroff = gpw;
|
||
|
|
||
|
- /*
|
||
|
- * Enable the power controller. This is crucial on Gemini
|
||
|
- * systems: if this is not done, pressing the power button
|
||
|
- * will result in unconditional poweroff without any warning.
|
||
|
- * This makes the kernel handle the poweroff.
|
||
|
- */
|
||
|
- val = readl(gpw->base + GEMINI_PWC_CTRLREG);
|
||
|
- val |= GEMINI_CTRL_ENABLE;
|
||
|
- writel(val, gpw->base + GEMINI_PWC_CTRLREG);
|
||
|
-
|
||
|
dev_info(dev, "Gemini poweroff driver registered\n");
|
||
|
|
||
|
return 0;
|