aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/gemini/patches-4.14/0026-power-gemini-poweroff-Avoid-spurious-poweroff.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/gemini/patches-4.14/0026-power-gemini-poweroff-Avoid-spurious-poweroff.patch')
-rw-r--r--target/linux/gemini/patches-4.14/0026-power-gemini-poweroff-Avoid-spurious-poweroff.patch80
1 files changed, 80 insertions, 0 deletions
diff --git a/target/linux/gemini/patches-4.14/0026-power-gemini-poweroff-Avoid-spurious-poweroff.patch b/target/linux/gemini/patches-4.14/0026-power-gemini-poweroff-Avoid-spurious-poweroff.patch
new file mode 100644
index 0000000000..e97aeaca43
--- /dev/null
+++ b/target/linux/gemini/patches-4.14/0026-power-gemini-poweroff-Avoid-spurious-poweroff.patch
@@ -0,0 +1,80 @@
+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;