aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/wakeup.c
diff options
context:
space:
mode:
authorShaohua Li <shaohua.li@intel.com>2009-04-06 22:24:29 -0400
committerLen Brown <len.brown@intel.com>2009-04-07 00:02:40 -0400
commit9090589d87506c578ea1523ffd7ae7fd9424fb28 (patch)
tree215163d13dbfa514a4121594cd4c6e27fde9b911 /drivers/acpi/wakeup.c
parentd508afb437daee7cf07da085b635c44a4ebf9b38 (diff)
ACPI: convert acpi_device_lock spinlock to mutex
Convert acpi_device_lock to a mutex to avoid a potential race upon access to /proc/acpi/wakeup Delete the lock entirely in wakeup.c since it is not necessary (and can not sleep) Found-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Shaohua Li <shaohua.li@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/wakeup.c')
-rw-r--r--drivers/acpi/wakeup.c30
1 files changed, 7 insertions, 23 deletions
diff --git a/drivers/acpi/wakeup.c b/drivers/acpi/wakeup.c
index 5aee8c26cc9f..88725dcdf8bc 100644
--- a/drivers/acpi/wakeup.c
+++ b/drivers/acpi/wakeup.c
@@ -12,12 +12,14 @@
12#include "internal.h" 12#include "internal.h"
13#include "sleep.h" 13#include "sleep.h"
14 14
15/*
16 * We didn't lock acpi_device_lock in the file, because it invokes oops in
17 * suspend/resume and isn't really required as this is called in S-state. At
18 * that time, there is no device hotplug
19 **/
15#define _COMPONENT ACPI_SYSTEM_COMPONENT 20#define _COMPONENT ACPI_SYSTEM_COMPONENT
16ACPI_MODULE_NAME("wakeup_devices") 21ACPI_MODULE_NAME("wakeup_devices")
17 22
18extern struct list_head acpi_wakeup_device_list;
19extern spinlock_t acpi_device_lock;
20
21/** 23/**
22 * acpi_enable_wakeup_device_prep - prepare wakeup devices 24 * acpi_enable_wakeup_device_prep - prepare wakeup devices
23 * @sleep_state: ACPI state 25 * @sleep_state: ACPI state
@@ -29,7 +31,6 @@ void acpi_enable_wakeup_device_prep(u8 sleep_state)
29{ 31{
30 struct list_head *node, *next; 32 struct list_head *node, *next;
31 33
32 spin_lock(&acpi_device_lock);
33 list_for_each_safe(node, next, &acpi_wakeup_device_list) { 34 list_for_each_safe(node, next, &acpi_wakeup_device_list) {
34 struct acpi_device *dev = container_of(node, 35 struct acpi_device *dev = container_of(node,
35 struct acpi_device, 36 struct acpi_device,
@@ -40,11 +41,8 @@ void acpi_enable_wakeup_device_prep(u8 sleep_state)
40 (sleep_state > (u32) dev->wakeup.sleep_state)) 41 (sleep_state > (u32) dev->wakeup.sleep_state))
41 continue; 42 continue;
42 43
43 spin_unlock(&acpi_device_lock);
44 acpi_enable_wakeup_device_power(dev, sleep_state); 44 acpi_enable_wakeup_device_power(dev, sleep_state);
45 spin_lock(&acpi_device_lock);
46 } 45 }
47 spin_unlock(&acpi_device_lock);
48} 46}
49 47
50/** 48/**
@@ -60,7 +58,6 @@ void acpi_enable_wakeup_device(u8 sleep_state)
60 * Caution: this routine must be invoked when interrupt is disabled 58 * Caution: this routine must be invoked when interrupt is disabled
61 * Refer ACPI2.0: P212 59 * Refer ACPI2.0: P212
62 */ 60 */
63 spin_lock(&acpi_device_lock);
64 list_for_each_safe(node, next, &acpi_wakeup_device_list) { 61 list_for_each_safe(node, next, &acpi_wakeup_device_list) {
65 struct acpi_device *dev = 62 struct acpi_device *dev =
66 container_of(node, struct acpi_device, wakeup_list); 63 container_of(node, struct acpi_device, wakeup_list);
@@ -74,22 +71,17 @@ void acpi_enable_wakeup_device(u8 sleep_state)
74 if ((!dev->wakeup.state.enabled && !dev->wakeup.flags.prepared) 71 if ((!dev->wakeup.state.enabled && !dev->wakeup.flags.prepared)
75 || sleep_state > (u32) dev->wakeup.sleep_state) { 72 || sleep_state > (u32) dev->wakeup.sleep_state) {
76 if (dev->wakeup.flags.run_wake) { 73 if (dev->wakeup.flags.run_wake) {
77 spin_unlock(&acpi_device_lock);
78 /* set_gpe_type will disable GPE, leave it like that */ 74 /* set_gpe_type will disable GPE, leave it like that */
79 acpi_set_gpe_type(dev->wakeup.gpe_device, 75 acpi_set_gpe_type(dev->wakeup.gpe_device,
80 dev->wakeup.gpe_number, 76 dev->wakeup.gpe_number,
81 ACPI_GPE_TYPE_RUNTIME); 77 ACPI_GPE_TYPE_RUNTIME);
82 spin_lock(&acpi_device_lock);
83 } 78 }
84 continue; 79 continue;
85 } 80 }
86 spin_unlock(&acpi_device_lock);
87 if (!dev->wakeup.flags.run_wake) 81 if (!dev->wakeup.flags.run_wake)
88 acpi_enable_gpe(dev->wakeup.gpe_device, 82 acpi_enable_gpe(dev->wakeup.gpe_device,
89 dev->wakeup.gpe_number); 83 dev->wakeup.gpe_number);
90 spin_lock(&acpi_device_lock);
91 } 84 }
92 spin_unlock(&acpi_device_lock);
93} 85}
94 86
95/** 87/**
@@ -101,7 +93,6 @@ void acpi_disable_wakeup_device(u8 sleep_state)
101{ 93{
102 struct list_head *node, *next; 94 struct list_head *node, *next;
103 95
104 spin_lock(&acpi_device_lock);
105 list_for_each_safe(node, next, &acpi_wakeup_device_list) { 96 list_for_each_safe(node, next, &acpi_wakeup_device_list) {
106 struct acpi_device *dev = 97 struct acpi_device *dev =
107 container_of(node, struct acpi_device, wakeup_list); 98 container_of(node, struct acpi_device, wakeup_list);
@@ -112,19 +103,16 @@ void acpi_disable_wakeup_device(u8 sleep_state)
112 if ((!dev->wakeup.state.enabled && !dev->wakeup.flags.prepared) 103 if ((!dev->wakeup.state.enabled && !dev->wakeup.flags.prepared)
113 || sleep_state > (u32) dev->wakeup.sleep_state) { 104 || sleep_state > (u32) dev->wakeup.sleep_state) {
114 if (dev->wakeup.flags.run_wake) { 105 if (dev->wakeup.flags.run_wake) {
115 spin_unlock(&acpi_device_lock);
116 acpi_set_gpe_type(dev->wakeup.gpe_device, 106 acpi_set_gpe_type(dev->wakeup.gpe_device,
117 dev->wakeup.gpe_number, 107 dev->wakeup.gpe_number,
118 ACPI_GPE_TYPE_WAKE_RUN); 108 ACPI_GPE_TYPE_WAKE_RUN);
119 /* Re-enable it, since set_gpe_type will disable it */ 109 /* Re-enable it, since set_gpe_type will disable it */
120 acpi_enable_gpe(dev->wakeup.gpe_device, 110 acpi_enable_gpe(dev->wakeup.gpe_device,
121 dev->wakeup.gpe_number); 111 dev->wakeup.gpe_number);
122 spin_lock(&acpi_device_lock);
123 } 112 }
124 continue; 113 continue;
125 } 114 }
126 115
127 spin_unlock(&acpi_device_lock);
128 acpi_disable_wakeup_device_power(dev); 116 acpi_disable_wakeup_device_power(dev);
129 /* Never disable run-wake GPE */ 117 /* Never disable run-wake GPE */
130 if (!dev->wakeup.flags.run_wake) { 118 if (!dev->wakeup.flags.run_wake) {
@@ -133,16 +121,14 @@ void acpi_disable_wakeup_device(u8 sleep_state)
133 acpi_clear_gpe(dev->wakeup.gpe_device, 121 acpi_clear_gpe(dev->wakeup.gpe_device,
134 dev->wakeup.gpe_number, ACPI_NOT_ISR); 122 dev->wakeup.gpe_number, ACPI_NOT_ISR);
135 } 123 }
136 spin_lock(&acpi_device_lock);
137 } 124 }
138 spin_unlock(&acpi_device_lock);
139} 125}
140 126
141int __init acpi_wakeup_device_init(void) 127int __init acpi_wakeup_device_init(void)
142{ 128{
143 struct list_head *node, *next; 129 struct list_head *node, *next;
144 130
145 spin_lock(&acpi_device_lock); 131 mutex_lock(&acpi_device_lock);
146 list_for_each_safe(node, next, &acpi_wakeup_device_list) { 132 list_for_each_safe(node, next, &acpi_wakeup_device_list) {
147 struct acpi_device *dev = container_of(node, 133 struct acpi_device *dev = container_of(node,
148 struct acpi_device, 134 struct acpi_device,
@@ -150,15 +136,13 @@ int __init acpi_wakeup_device_init(void)
150 /* In case user doesn't load button driver */ 136 /* In case user doesn't load button driver */
151 if (!dev->wakeup.flags.run_wake || dev->wakeup.state.enabled) 137 if (!dev->wakeup.flags.run_wake || dev->wakeup.state.enabled)
152 continue; 138 continue;
153 spin_unlock(&acpi_device_lock);
154 acpi_set_gpe_type(dev->wakeup.gpe_device, 139 acpi_set_gpe_type(dev->wakeup.gpe_device,
155 dev->wakeup.gpe_number, 140 dev->wakeup.gpe_number,
156 ACPI_GPE_TYPE_WAKE_RUN); 141 ACPI_GPE_TYPE_WAKE_RUN);
157 acpi_enable_gpe(dev->wakeup.gpe_device, 142 acpi_enable_gpe(dev->wakeup.gpe_device,
158 dev->wakeup.gpe_number); 143 dev->wakeup.gpe_number);
159 dev->wakeup.state.enabled = 1; 144 dev->wakeup.state.enabled = 1;
160 spin_lock(&acpi_device_lock);
161 } 145 }
162 spin_unlock(&acpi_device_lock); 146 mutex_unlock(&acpi_device_lock);
163 return 0; 147 return 0;
164} 148}