]>
Commit | Line | Data |
---|---|---|
1 | /* | |
2 | * wakeup.c - support wakeup devices | |
3 | * Copyright (C) 2004 Li Shaohua <shaohua.li@intel.com> | |
4 | */ | |
5 | ||
6 | #include <linux/init.h> | |
7 | #include <linux/acpi.h> | |
8 | #include <linux/kernel.h> | |
9 | #include <linux/types.h> | |
10 | ||
11 | #include "internal.h" | |
12 | #include "sleep.h" | |
13 | ||
14 | /* | |
15 | * We didn't lock acpi_device_lock in the file, because it invokes oops in | |
16 | * suspend/resume and isn't really required as this is called in S-state. At | |
17 | * that time, there is no device hotplug | |
18 | **/ | |
19 | #define _COMPONENT ACPI_SYSTEM_COMPONENT | |
20 | ACPI_MODULE_NAME("wakeup_devices") | |
21 | ||
22 | /** | |
23 | * acpi_enable_wakeup_devices - Enable wake-up device GPEs. | |
24 | * @sleep_state: ACPI system sleep state. | |
25 | * | |
26 | * Enable wakeup device power of devices with the state.enable flag set and set | |
27 | * the wakeup enable mask bits in the GPE registers that correspond to wakeup | |
28 | * devices. | |
29 | */ | |
30 | void acpi_enable_wakeup_devices(u8 sleep_state) | |
31 | { | |
32 | struct list_head *node, *next; | |
33 | ||
34 | list_for_each_safe(node, next, &acpi_wakeup_device_list) { | |
35 | struct acpi_device *dev = | |
36 | container_of(node, struct acpi_device, wakeup_list); | |
37 | ||
38 | if (!dev->wakeup.flags.valid | |
39 | || sleep_state > (u32) dev->wakeup.sleep_state | |
40 | || !(device_may_wakeup(&dev->dev) | |
41 | || dev->wakeup.prepare_count)) | |
42 | continue; | |
43 | ||
44 | if (device_may_wakeup(&dev->dev)) | |
45 | acpi_enable_wakeup_device_power(dev, sleep_state); | |
46 | ||
47 | /* The wake-up power should have been enabled already. */ | |
48 | acpi_set_gpe_wake_mask(dev->wakeup.gpe_device, dev->wakeup.gpe_number, | |
49 | ACPI_GPE_ENABLE); | |
50 | } | |
51 | } | |
52 | ||
53 | /** | |
54 | * acpi_disable_wakeup_devices - Disable devices' wakeup capability. | |
55 | * @sleep_state: ACPI system sleep state. | |
56 | */ | |
57 | void acpi_disable_wakeup_devices(u8 sleep_state) | |
58 | { | |
59 | struct list_head *node, *next; | |
60 | ||
61 | list_for_each_safe(node, next, &acpi_wakeup_device_list) { | |
62 | struct acpi_device *dev = | |
63 | container_of(node, struct acpi_device, wakeup_list); | |
64 | ||
65 | if (!dev->wakeup.flags.valid | |
66 | || sleep_state > (u32) dev->wakeup.sleep_state | |
67 | || !(device_may_wakeup(&dev->dev) | |
68 | || dev->wakeup.prepare_count)) | |
69 | continue; | |
70 | ||
71 | acpi_set_gpe_wake_mask(dev->wakeup.gpe_device, dev->wakeup.gpe_number, | |
72 | ACPI_GPE_DISABLE); | |
73 | ||
74 | if (device_may_wakeup(&dev->dev)) | |
75 | acpi_disable_wakeup_device_power(dev); | |
76 | } | |
77 | } | |
78 | ||
79 | int __init acpi_wakeup_device_init(void) | |
80 | { | |
81 | struct list_head *node, *next; | |
82 | ||
83 | mutex_lock(&acpi_device_lock); | |
84 | list_for_each_safe(node, next, &acpi_wakeup_device_list) { | |
85 | struct acpi_device *dev = container_of(node, | |
86 | struct acpi_device, | |
87 | wakeup_list); | |
88 | if (device_can_wakeup(&dev->dev)) { | |
89 | /* Button GPEs are supposed to be always enabled. */ | |
90 | acpi_enable_gpe(dev->wakeup.gpe_device, | |
91 | dev->wakeup.gpe_number); | |
92 | device_set_wakeup_enable(&dev->dev, true); | |
93 | } | |
94 | } | |
95 | mutex_unlock(&acpi_device_lock); | |
96 | return 0; | |
97 | } |