aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/acpi/acpica/evxfevnt.c67
-rw-r--r--drivers/acpi/sleep.c15
-rw-r--r--drivers/acpi/wakeup.c18
-rw-r--r--include/acpi/acpixf.h2
-rw-r--r--include/acpi/actypes.h2
5 files changed, 84 insertions, 20 deletions
diff --git a/drivers/acpi/acpica/evxfevnt.c b/drivers/acpi/acpica/evxfevnt.c
index d97b8dce1668..d6a6d4a76592 100644
--- a/drivers/acpi/acpica/evxfevnt.c
+++ b/drivers/acpi/acpica/evxfevnt.c
@@ -308,6 +308,73 @@ ACPI_EXPORT_SYMBOL(acpi_set_gpe)
308 308
309/******************************************************************************* 309/*******************************************************************************
310 * 310 *
311 * FUNCTION: acpi_gpe_wakeup
312 *
313 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
314 * gpe_number - GPE level within the GPE block
315 * Action - Enable or Disable
316 *
317 * RETURN: Status
318 *
319 * DESCRIPTION: Set or clear the GPE's wakeup enable mask bit.
320 *
321 ******************************************************************************/
322acpi_status acpi_gpe_wakeup(acpi_handle gpe_device, u32 gpe_number, u8 action)
323{
324 acpi_status status = AE_OK;
325 struct acpi_gpe_event_info *gpe_event_info;
326 struct acpi_gpe_register_info *gpe_register_info;
327 acpi_cpu_flags flags;
328 u32 register_bit;
329
330 ACPI_FUNCTION_TRACE(acpi_gpe_wakeup);
331
332 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
333
334 /* Ensure that we have a valid GPE number */
335
336 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
337 if (!gpe_event_info) {
338 status = AE_BAD_PARAMETER;
339 goto unlock_and_exit;
340 }
341
342 gpe_register_info = gpe_event_info->register_info;
343 if (!gpe_register_info) {
344 status = AE_NOT_EXIST;
345 goto unlock_and_exit;
346 }
347
348 register_bit =
349 acpi_hw_get_gpe_register_bit(gpe_event_info, gpe_register_info);
350
351 /* Perform the action */
352
353 switch (action) {
354 case ACPI_GPE_ENABLE:
355 ACPI_SET_BIT(gpe_register_info->enable_for_wake, register_bit);
356 break;
357
358 case ACPI_GPE_DISABLE:
359 ACPI_CLEAR_BIT(gpe_register_info->enable_for_wake,
360 register_bit);
361 break;
362
363 default:
364 ACPI_ERROR((AE_INFO, "%u, Invalid action", action));
365 status = AE_BAD_PARAMETER;
366 break;
367 }
368
369unlock_and_exit:
370 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
371 return_ACPI_STATUS(status);
372}
373
374ACPI_EXPORT_SYMBOL(acpi_gpe_wakeup)
375
376/*******************************************************************************
377 *
311 * FUNCTION: acpi_enable_gpe 378 * FUNCTION: acpi_enable_gpe
312 * 379 *
313 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 380 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c
index 5b7c52e4a00f..aaa1af55e280 100644
--- a/drivers/acpi/sleep.c
+++ b/drivers/acpi/sleep.c
@@ -664,18 +664,9 @@ int acpi_pm_device_sleep_wake(struct device *dev, bool enable)
664 return -ENODEV; 664 return -ENODEV;
665 } 665 }
666 666
667 if (enable) { 667 error = enable ?
668 error = acpi_enable_wakeup_device_power(adev, 668 acpi_enable_wakeup_device_power(adev, acpi_target_sleep_state) :
669 acpi_target_sleep_state); 669 acpi_disable_wakeup_device_power(adev);
670 if (!error)
671 acpi_enable_gpe(adev->wakeup.gpe_device,
672 adev->wakeup.gpe_number,
673 ACPI_GPE_TYPE_WAKE);
674 } else {
675 acpi_disable_gpe(adev->wakeup.gpe_device, adev->wakeup.gpe_number,
676 ACPI_GPE_TYPE_WAKE);
677 error = acpi_disable_wakeup_device_power(adev);
678 }
679 if (!error) 670 if (!error)
680 dev_info(dev, "wake-up capability %s by ACPI\n", 671 dev_info(dev, "wake-up capability %s by ACPI\n",
681 enable ? "enabled" : "disabled"); 672 enable ? "enabled" : "disabled");
diff --git a/drivers/acpi/wakeup.c b/drivers/acpi/wakeup.c
index 388747a7ef4f..c80537bc3234 100644
--- a/drivers/acpi/wakeup.c
+++ b/drivers/acpi/wakeup.c
@@ -64,13 +64,14 @@ void acpi_enable_wakeup_device(u8 sleep_state)
64 struct acpi_device *dev = 64 struct acpi_device *dev =
65 container_of(node, struct acpi_device, wakeup_list); 65 container_of(node, struct acpi_device, wakeup_list);
66 66
67 if (!dev->wakeup.flags.valid || !dev->wakeup.state.enabled 67 if (!dev->wakeup.flags.valid
68 || !(dev->wakeup.state.enabled || dev->wakeup.prepare_count)
68 || sleep_state > (u32) dev->wakeup.sleep_state) 69 || sleep_state > (u32) dev->wakeup.sleep_state)
69 continue; 70 continue;
70 71
71 /* The wake-up power should have been enabled already. */ 72 /* The wake-up power should have been enabled already. */
72 acpi_enable_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number, 73 acpi_gpe_wakeup(dev->wakeup.gpe_device, dev->wakeup.gpe_number,
73 ACPI_GPE_TYPE_WAKE); 74 ACPI_GPE_ENABLE);
74 } 75 }
75} 76}
76 77
@@ -89,13 +90,16 @@ void acpi_disable_wakeup_device(u8 sleep_state)
89 struct acpi_device *dev = 90 struct acpi_device *dev =
90 container_of(node, struct acpi_device, wakeup_list); 91 container_of(node, struct acpi_device, wakeup_list);
91 92
92 if (!dev->wakeup.flags.valid || !dev->wakeup.state.enabled 93 if (!dev->wakeup.flags.valid
94 || !(dev->wakeup.state.enabled || dev->wakeup.prepare_count)
93 || (sleep_state > (u32) dev->wakeup.sleep_state)) 95 || (sleep_state > (u32) dev->wakeup.sleep_state))
94 continue; 96 continue;
95 97
96 acpi_disable_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number, 98 acpi_gpe_wakeup(dev->wakeup.gpe_device, dev->wakeup.gpe_number,
97 ACPI_GPE_TYPE_WAKE); 99 ACPI_GPE_DISABLE);
98 acpi_disable_wakeup_device_power(dev); 100
101 if (dev->wakeup.state.enabled)
102 acpi_disable_wakeup_device_power(dev);
99 } 103 }
100} 104}
101 105
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h
index 8aaa596e1208..17396e83e1a4 100644
--- a/include/acpi/acpixf.h
+++ b/include/acpi/acpixf.h
@@ -292,6 +292,8 @@ acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 gpe_type);
292 292
293acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number); 293acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number);
294 294
295acpi_status acpi_gpe_wakeup(acpi_handle gpe_device, u32 gpe_number, u8 action);
296
295acpi_status 297acpi_status
296acpi_get_gpe_status(acpi_handle gpe_device, 298acpi_get_gpe_status(acpi_handle gpe_device,
297 u32 gpe_number, acpi_event_status *event_status); 299 u32 gpe_number, acpi_event_status *event_status);
diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h
index d55f4a7b824d..6a65a94897bf 100644
--- a/include/acpi/actypes.h
+++ b/include/acpi/actypes.h
@@ -663,7 +663,7 @@ typedef u32 acpi_event_status;
663#define ACPI_GPE_MAX 0xFF 663#define ACPI_GPE_MAX 0xFF
664#define ACPI_NUM_GPE 256 664#define ACPI_NUM_GPE 256
665 665
666/* Actions for acpi_set_gpe and acpi_hw_low_set_gpe */ 666/* Actions for acpi_set_gpe, acpi_gpe_wakeup, acpi_hw_low_set_gpe */
667 667
668#define ACPI_GPE_ENABLE 0 668#define ACPI_GPE_ENABLE 0
669#define ACPI_GPE_DISABLE 1 669#define ACPI_GPE_DISABLE 1