]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/4.17.12/acpi-lpss-avoid-pm-quirks-on-suspend-and-resume-from-hibernation.patch
4.14-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 4.17.12 / acpi-lpss-avoid-pm-quirks-on-suspend-and-resume-from-hibernation.patch
CommitLineData
d7d5500c
GKH
1From 12864ff8545f6b8144fdf1bb89b5663357f29ec4 Mon Sep 17 00:00:00 2001
2From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
3Date: Thu, 26 Jul 2018 10:58:20 +0200
4Subject: ACPI / LPSS: Avoid PM quirks on suspend and resume from hibernation
5
6From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
7
8commit 12864ff8545f6b8144fdf1bb89b5663357f29ec4 upstream.
9
10Commit a09c59130688 (ACPI / LPSS: Avoid PM quirks on suspend and
11resume from S3) modified the ACPI driver for Intel SoCs (LPSS) to
12avoid applying PM quirks on suspend and resume from S3 to address
13system-wide suspend and resume problems on some systems, but it is
14reported that the same issue also affects hibernation, so extend
15the approach used by that commit to cover hibernation as well.
16
17Fixes: a09c59130688 (ACPI / LPSS: Avoid PM quirks on suspend and resume from S3)
18Link: https://bugs.launchpad.net/bugs/1774950
19Reported-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
20Cc: 4.15+ <stable@vger.kernel.org> # 4.15+
21Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
22Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
23Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
24
25---
26 drivers/acpi/acpi_lpss.c | 26 +++++++++++++++++---------
27 1 file changed, 17 insertions(+), 9 deletions(-)
28
29--- a/drivers/acpi/acpi_lpss.c
30+++ b/drivers/acpi/acpi_lpss.c
31@@ -879,6 +879,7 @@ static void acpi_lpss_dismiss(struct dev
32 #define LPSS_GPIODEF0_DMA_LLP BIT(13)
33
34 static DEFINE_MUTEX(lpss_iosf_mutex);
35+static bool lpss_iosf_d3_entered;
36
37 static void lpss_iosf_enter_d3_state(void)
38 {
39@@ -921,6 +922,9 @@ static void lpss_iosf_enter_d3_state(voi
40
41 iosf_mbi_modify(LPSS_IOSF_UNIT_LPIOEP, MBI_CR_WRITE,
42 LPSS_IOSF_GPIODEF0, value1, mask1);
43+
44+ lpss_iosf_d3_entered = true;
45+
46 exit:
47 mutex_unlock(&lpss_iosf_mutex);
48 }
49@@ -935,6 +939,11 @@ static void lpss_iosf_exit_d3_state(void
50
51 mutex_lock(&lpss_iosf_mutex);
52
53+ if (!lpss_iosf_d3_entered)
54+ goto exit;
55+
56+ lpss_iosf_d3_entered = false;
57+
58 iosf_mbi_modify(LPSS_IOSF_UNIT_LPIOEP, MBI_CR_WRITE,
59 LPSS_IOSF_GPIODEF0, value1, mask1);
60
61@@ -944,13 +953,13 @@ static void lpss_iosf_exit_d3_state(void
62 iosf_mbi_modify(LPSS_IOSF_UNIT_LPIO1, MBI_CFG_WRITE,
63 LPSS_IOSF_PMCSR, value2, mask2);
64
65+exit:
66 mutex_unlock(&lpss_iosf_mutex);
67 }
68
69-static int acpi_lpss_suspend(struct device *dev, bool runtime)
70+static int acpi_lpss_suspend(struct device *dev, bool wakeup)
71 {
72 struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev));
73- bool wakeup = runtime || device_may_wakeup(dev);
74 int ret;
75
76 if (pdata->dev_desc->flags & LPSS_SAVE_CTX)
77@@ -963,14 +972,14 @@ static int acpi_lpss_suspend(struct devi
78 * wrong status for devices being about to be powered off. See
79 * lpss_iosf_enter_d3_state() for further information.
80 */
81- if ((runtime || !pm_suspend_via_firmware()) &&
82+ if (acpi_target_system_state() == ACPI_STATE_S0 &&
83 lpss_quirks & LPSS_QUIRK_ALWAYS_POWER_ON && iosf_mbi_available())
84 lpss_iosf_enter_d3_state();
85
86 return ret;
87 }
88
89-static int acpi_lpss_resume(struct device *dev, bool runtime)
90+static int acpi_lpss_resume(struct device *dev)
91 {
92 struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev));
93 int ret;
94@@ -979,8 +988,7 @@ static int acpi_lpss_resume(struct devic
95 * This call is kept first to be in symmetry with
96 * acpi_lpss_runtime_suspend() one.
97 */
98- if ((runtime || !pm_resume_via_firmware()) &&
99- lpss_quirks & LPSS_QUIRK_ALWAYS_POWER_ON && iosf_mbi_available())
100+ if (lpss_quirks & LPSS_QUIRK_ALWAYS_POWER_ON && iosf_mbi_available())
101 lpss_iosf_exit_d3_state();
102
103 ret = acpi_dev_resume(dev);
104@@ -1004,12 +1012,12 @@ static int acpi_lpss_suspend_late(struct
105 return 0;
106
107 ret = pm_generic_suspend_late(dev);
108- return ret ? ret : acpi_lpss_suspend(dev, false);
109+ return ret ? ret : acpi_lpss_suspend(dev, device_may_wakeup(dev));
110 }
111
112 static int acpi_lpss_resume_early(struct device *dev)
113 {
114- int ret = acpi_lpss_resume(dev, false);
115+ int ret = acpi_lpss_resume(dev);
116
117 return ret ? ret : pm_generic_resume_early(dev);
118 }
119@@ -1024,7 +1032,7 @@ static int acpi_lpss_runtime_suspend(str
120
121 static int acpi_lpss_runtime_resume(struct device *dev)
122 {
123- int ret = acpi_lpss_resume(dev, true);
124+ int ret = acpi_lpss_resume(dev);
125
126 return ret ? ret : pm_generic_runtime_resume(dev);
127 }