aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/platform
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2019-07-30 05:55:59 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2019-07-30 06:26:21 -0400
commit10a08fd65ec1a68ccd86b19ec822ed5f2e50113f (patch)
tree2f3385d230b870c37e2f9067193aaeed73d1adeb /drivers/platform
parentb605c44c30b59990e806f930c37bd288b9d901a5 (diff)
ACPI: PM: Set up EC GPE for system wakeup from drivers that need it
The EC GPE needs to be set up for system wakeup only if there is a driver depending on it, either intel-hid or intel-vbtn, bound to a button device that is expected to wake up the system from sleep (such as the power button on some Dell systems, like the XPS13 9360). It doesn't need to be set up for waking up the system from sleep in any other cases and whether or not it is expected to wake up the system from sleep doesn't depend on whether or not the LPS0 device is present in the ACPI namespace. For this reason, rearrange the ACPI suspend-to-idle code to make the drivers depending on the EC GPE wakeup take care of setting it up and decouple that from the LPS0 device handling. While at it, make intel-hid and intel-vbtn prepare for system wakeup only if they are allowed to wake up the system from sleep by user space (via sysfs). [Note that acpi_ec_mark_gpe_for_wake() and acpi_ec_set_gpe_wake_mask() are there to prevent the EC GPE from being disabled by the acpi_enable_all_wakeup_gpes() call in acpi_s2idle_prepare(), so on systems with either intel-hid or intel-vbtn this change doesn't affect any interactions with the hardware or platform firmware.] Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Diffstat (limited to 'drivers/platform')
-rw-r--r--drivers/platform/x86/intel-hid.c20
-rw-r--r--drivers/platform/x86/intel-vbtn.c20
2 files changed, 32 insertions, 8 deletions
diff --git a/drivers/platform/x86/intel-hid.c b/drivers/platform/x86/intel-hid.c
index bc0d55a59015..e51c72b92cbd 100644
--- a/drivers/platform/x86/intel-hid.c
+++ b/drivers/platform/x86/intel-hid.c
@@ -253,9 +253,12 @@ static void intel_button_array_enable(struct device *device, bool enable)
253 253
254static int intel_hid_pm_prepare(struct device *device) 254static int intel_hid_pm_prepare(struct device *device)
255{ 255{
256 struct intel_hid_priv *priv = dev_get_drvdata(device); 256 if (device_may_wakeup(device)) {
257 struct intel_hid_priv *priv = dev_get_drvdata(device);
257 258
258 priv->wakeup_mode = true; 259 priv->wakeup_mode = true;
260 acpi_ec_set_gpe_wake_mask(ACPI_GPE_ENABLE);
261 }
259 return 0; 262 return 0;
260} 263}
261 264
@@ -270,9 +273,12 @@ static int intel_hid_pl_suspend_handler(struct device *device)
270 273
271static int intel_hid_pl_resume_handler(struct device *device) 274static int intel_hid_pl_resume_handler(struct device *device)
272{ 275{
273 struct intel_hid_priv *priv = dev_get_drvdata(device); 276 if (device_may_wakeup(device)) {
277 struct intel_hid_priv *priv = dev_get_drvdata(device);
274 278
275 priv->wakeup_mode = false; 279 acpi_ec_set_gpe_wake_mask(ACPI_GPE_DISABLE);
280 priv->wakeup_mode = false;
281 }
276 if (pm_resume_via_firmware()) { 282 if (pm_resume_via_firmware()) {
277 intel_hid_set_enable(device, true); 283 intel_hid_set_enable(device, true);
278 intel_button_array_enable(device, true); 284 intel_button_array_enable(device, true);
@@ -491,6 +497,12 @@ static int intel_hid_probe(struct platform_device *device)
491 } 497 }
492 498
493 device_init_wakeup(&device->dev, true); 499 device_init_wakeup(&device->dev, true);
500 /*
501 * In order for system wakeup to work, the EC GPE has to be marked as
502 * a wakeup one, so do that here (this setting will persist, but it has
503 * no effect until the wakeup mask is set for the EC GPE).
504 */
505 acpi_ec_mark_gpe_for_wake();
494 return 0; 506 return 0;
495 507
496err_remove_notify: 508err_remove_notify:
diff --git a/drivers/platform/x86/intel-vbtn.c b/drivers/platform/x86/intel-vbtn.c
index a0d0cecff55f..ab84e1bbdedd 100644
--- a/drivers/platform/x86/intel-vbtn.c
+++ b/drivers/platform/x86/intel-vbtn.c
@@ -176,6 +176,12 @@ static int intel_vbtn_probe(struct platform_device *device)
176 return -EBUSY; 176 return -EBUSY;
177 177
178 device_init_wakeup(&device->dev, true); 178 device_init_wakeup(&device->dev, true);
179 /*
180 * In order for system wakeup to work, the EC GPE has to be marked as
181 * a wakeup one, so do that here (this setting will persist, but it has
182 * no effect until the wakeup mask is set for the EC GPE).
183 */
184 acpi_ec_mark_gpe_for_wake();
179 return 0; 185 return 0;
180} 186}
181 187
@@ -195,17 +201,23 @@ static int intel_vbtn_remove(struct platform_device *device)
195 201
196static int intel_vbtn_pm_prepare(struct device *dev) 202static int intel_vbtn_pm_prepare(struct device *dev)
197{ 203{
198 struct intel_vbtn_priv *priv = dev_get_drvdata(dev); 204 if (device_may_wakeup(dev)) {
205 struct intel_vbtn_priv *priv = dev_get_drvdata(dev);
199 206
200 priv->wakeup_mode = true; 207 priv->wakeup_mode = true;
208 acpi_ec_set_gpe_wake_mask(ACPI_GPE_ENABLE);
209 }
201 return 0; 210 return 0;
202} 211}
203 212
204static int intel_vbtn_pm_resume(struct device *dev) 213static int intel_vbtn_pm_resume(struct device *dev)
205{ 214{
206 struct intel_vbtn_priv *priv = dev_get_drvdata(dev); 215 if (device_may_wakeup(dev)) {
216 struct intel_vbtn_priv *priv = dev_get_drvdata(dev);
207 217
208 priv->wakeup_mode = false; 218 acpi_ec_set_gpe_wake_mask(ACPI_GPE_DISABLE);
219 priv->wakeup_mode = false;
220 }
209 return 0; 221 return 0;
210} 222}
211 223