[S390] ftrace/mcount: fix kernel stack backchain
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / acpi / wakeup.c
CommitLineData
1da177e4
LT
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 <acpi/acpi_drivers.h>
9#include <linux/kernel.h>
10#include <linux/types.h>
1da177e4
LT
11#include "sleep.h"
12
13#define _COMPONENT ACPI_SYSTEM_COMPONENT
4be44fcd 14ACPI_MODULE_NAME("wakeup_devices")
1da177e4 15
4be44fcd 16extern struct list_head acpi_wakeup_device_list;
1da177e4
LT
17extern spinlock_t acpi_device_lock;
18
1da177e4
LT
19/**
20 * acpi_enable_wakeup_device_prep - prepare wakeup devices
21 * @sleep_state: ACPI state
22 * Enable all wakup devices power if the devices' wakeup level
23 * is higher than requested sleep level
24 */
25
4be44fcd 26void acpi_enable_wakeup_device_prep(u8 sleep_state)
1da177e4 27{
4be44fcd 28 struct list_head *node, *next;
1da177e4 29
1da177e4
LT
30 spin_lock(&acpi_device_lock);
31 list_for_each_safe(node, next, &acpi_wakeup_device_list) {
4be44fcd
LB
32 struct acpi_device *dev = container_of(node,
33 struct acpi_device,
34 wakeup_list);
35
36 if (!dev->wakeup.flags.valid ||
37 !dev->wakeup.state.enabled ||
38 (sleep_state > (u32) dev->wakeup.sleep_state))
1da177e4
LT
39 continue;
40
41 spin_unlock(&acpi_device_lock);
77e76609 42 acpi_enable_wakeup_device_power(dev, sleep_state);
1da177e4
LT
43 spin_lock(&acpi_device_lock);
44 }
45 spin_unlock(&acpi_device_lock);
46}
47
48/**
49 * acpi_enable_wakeup_device - enable wakeup devices
50 * @sleep_state: ACPI state
51 * Enable all wakup devices's GPE
52 */
4be44fcd 53void acpi_enable_wakeup_device(u8 sleep_state)
1da177e4 54{
4be44fcd 55 struct list_head *node, *next;
1da177e4
LT
56
57 /*
58 * Caution: this routine must be invoked when interrupt is disabled
59 * Refer ACPI2.0: P212
60 */
1da177e4
LT
61 spin_lock(&acpi_device_lock);
62 list_for_each_safe(node, next, &acpi_wakeup_device_list) {
9b039330
AS
63 struct acpi_device *dev =
64 container_of(node, struct acpi_device, wakeup_list);
eb9d0fe4 65
9b039330
AS
66 if (!dev->wakeup.flags.valid)
67 continue;
eb9d0fe4 68
1da177e4
LT
69 /* If users want to disable run-wake GPE,
70 * we only disable it for wake and leave it for runtime
71 */
eb9d0fe4
RW
72 if ((!dev->wakeup.state.enabled && !dev->wakeup.flags.prepared)
73 || sleep_state > (u32) dev->wakeup.sleep_state) {
9b039330
AS
74 if (dev->wakeup.flags.run_wake) {
75 spin_unlock(&acpi_device_lock);
76 /* set_gpe_type will disable GPE, leave it like that */
77 acpi_set_gpe_type(dev->wakeup.gpe_device,
78 dev->wakeup.gpe_number,
79 ACPI_GPE_TYPE_RUNTIME);
80 spin_lock(&acpi_device_lock);
81 }
1da177e4
LT
82 continue;
83 }
1da177e4 84 spin_unlock(&acpi_device_lock);
1da177e4 85 if (!dev->wakeup.flags.run_wake)
4be44fcd 86 acpi_enable_gpe(dev->wakeup.gpe_device,
0b7084ac 87 dev->wakeup.gpe_number);
1da177e4
LT
88 spin_lock(&acpi_device_lock);
89 }
90 spin_unlock(&acpi_device_lock);
91}
92
93/**
94 * acpi_disable_wakeup_device - disable devices' wakeup capability
95 * @sleep_state: ACPI state
96 * Disable all wakup devices's GPE and wakeup capability
97 */
4be44fcd 98void acpi_disable_wakeup_device(u8 sleep_state)
1da177e4 99{
4be44fcd 100 struct list_head *node, *next;
1da177e4 101
1da177e4
LT
102 spin_lock(&acpi_device_lock);
103 list_for_each_safe(node, next, &acpi_wakeup_device_list) {
9b039330
AS
104 struct acpi_device *dev =
105 container_of(node, struct acpi_device, wakeup_list);
1da177e4 106
9b039330 107 if (!dev->wakeup.flags.valid)
1da177e4 108 continue;
eb9d0fe4
RW
109
110 if ((!dev->wakeup.state.enabled && !dev->wakeup.flags.prepared)
111 || sleep_state > (u32) dev->wakeup.sleep_state) {
9b039330
AS
112 if (dev->wakeup.flags.run_wake) {
113 spin_unlock(&acpi_device_lock);
114 acpi_set_gpe_type(dev->wakeup.gpe_device,
115 dev->wakeup.gpe_number,
116 ACPI_GPE_TYPE_WAKE_RUN);
117 /* Re-enable it, since set_gpe_type will disable it */
118 acpi_enable_gpe(dev->wakeup.gpe_device,
0b7084ac 119 dev->wakeup.gpe_number);
9b039330
AS
120 spin_lock(&acpi_device_lock);
121 }
1da177e4 122 continue;
9b039330 123 }
1da177e4
LT
124
125 spin_unlock(&acpi_device_lock);
126 acpi_disable_wakeup_device_power(dev);
127 /* Never disable run-wake GPE */
128 if (!dev->wakeup.flags.run_wake) {
4be44fcd 129 acpi_disable_gpe(dev->wakeup.gpe_device,
0b7084ac 130 dev->wakeup.gpe_number);
4be44fcd
LB
131 acpi_clear_gpe(dev->wakeup.gpe_device,
132 dev->wakeup.gpe_number, ACPI_NOT_ISR);
1da177e4 133 }
1da177e4
LT
134 spin_lock(&acpi_device_lock);
135 }
136 spin_unlock(&acpi_device_lock);
137}
138
139static int __init acpi_wakeup_device_init(void)
140{
4be44fcd 141 struct list_head *node, *next;
1da177e4
LT
142
143 if (acpi_disabled)
144 return 0;
1da177e4
LT
145
146 spin_lock(&acpi_device_lock);
147 list_for_each_safe(node, next, &acpi_wakeup_device_list) {
4be44fcd
LB
148 struct acpi_device *dev = container_of(node,
149 struct acpi_device,
150 wakeup_list);
1da177e4 151 /* In case user doesn't load button driver */
9b039330
AS
152 if (!dev->wakeup.flags.run_wake || dev->wakeup.state.enabled)
153 continue;
154 spin_unlock(&acpi_device_lock);
155 acpi_set_gpe_type(dev->wakeup.gpe_device,
156 dev->wakeup.gpe_number,
157 ACPI_GPE_TYPE_WAKE_RUN);
158 acpi_enable_gpe(dev->wakeup.gpe_device,
0b7084ac 159 dev->wakeup.gpe_number);
9b039330
AS
160 dev->wakeup.state.enabled = 1;
161 spin_lock(&acpi_device_lock);
1da177e4
LT
162 }
163 spin_unlock(&acpi_device_lock);
1da177e4
LT
164 return 0;
165}
166
167late_initcall(acpi_wakeup_device_init);