diff options
-rw-r--r-- | drivers/acpi/acpica/evxfevnt.c | 67 | ||||
-rw-r--r-- | drivers/acpi/sleep.c | 15 | ||||
-rw-r--r-- | drivers/acpi/wakeup.c | 18 | ||||
-rw-r--r-- | include/acpi/acpixf.h | 2 | ||||
-rw-r--r-- | include/acpi/actypes.h | 2 |
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 | ******************************************************************************/ | ||
322 | acpi_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 | |||
369 | unlock_and_exit: | ||
370 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | ||
371 | return_ACPI_STATUS(status); | ||
372 | } | ||
373 | |||
374 | ACPI_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 | ||
293 | acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number); | 293 | acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number); |
294 | 294 | ||
295 | acpi_status acpi_gpe_wakeup(acpi_handle gpe_device, u32 gpe_number, u8 action); | ||
296 | |||
295 | acpi_status | 297 | acpi_status |
296 | acpi_get_gpe_status(acpi_handle gpe_device, | 298 | acpi_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 |