aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
authorAlexey Starikovskiy <astarikovskiy@suse.de>2008-10-25 13:48:46 -0400
committerLen Brown <len.brown@intel.com>2008-11-11 18:35:42 -0500
commit0b7084ac67fb84f0cf2f8bc02d7e0dea8521dd2d (patch)
tree0a619ac7a700543e6ba69aa5a568e5678ec0603d /drivers/acpi
parenta2f93aeadf97e870ff385030633a73e21146815d (diff)
ACPICA: Use spinlock for acpi_{en|dis}able_gpe
Disabling gpe might interfere with gpe detection/handling, thus producing "interrupt not handled" errors. Ironically, disabling of GPE from interrupt context is already under spinlock, so only userspace needs to start using it. Signed-off-by: Alexey Starikovskiy <astarikovskiy@suse.de> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/button.c2
-rw-r--r--drivers/acpi/ec.c10
-rw-r--r--drivers/acpi/events/evxfevnt.c35
-rw-r--r--drivers/acpi/sleep/wakeup.c8
-rw-r--r--drivers/acpi/system.c4
5 files changed, 21 insertions, 38 deletions
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index cb046c3fc3f2..eb6bf3025f97 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -479,7 +479,7 @@ static int acpi_button_add(struct acpi_device *device)
479 device->wakeup.gpe_number, 479 device->wakeup.gpe_number,
480 ACPI_GPE_TYPE_WAKE_RUN); 480 ACPI_GPE_TYPE_WAKE_RUN);
481 acpi_enable_gpe(device->wakeup.gpe_device, 481 acpi_enable_gpe(device->wakeup.gpe_device,
482 device->wakeup.gpe_number, ACPI_NOT_ISR); 482 device->wakeup.gpe_number);
483 device->wakeup.state.enabled = 1; 483 device->wakeup.state.enabled = 1;
484 } 484 }
485 485
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 34c67ca3bebe..89d6d2868e8c 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -282,7 +282,7 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec,
282 /* disable GPE during transaction if storm is detected */ 282 /* disable GPE during transaction if storm is detected */
283 if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) { 283 if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) {
284 clear_bit(EC_FLAGS_GPE_MODE, &ec->flags); 284 clear_bit(EC_FLAGS_GPE_MODE, &ec->flags);
285 acpi_disable_gpe(NULL, ec->gpe, ACPI_NOT_ISR); 285 acpi_disable_gpe(NULL, ec->gpe);
286 } 286 }
287 /* start transaction */ 287 /* start transaction */
288 spin_lock_irqsave(&ec->curr_lock, tmp); 288 spin_lock_irqsave(&ec->curr_lock, tmp);
@@ -305,7 +305,7 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec,
305 /* check if we received SCI during transaction */ 305 /* check if we received SCI during transaction */
306 ec_check_sci(ec, acpi_ec_read_status(ec)); 306 ec_check_sci(ec, acpi_ec_read_status(ec));
307 /* it is safe to enable GPE outside of transaction */ 307 /* it is safe to enable GPE outside of transaction */
308 acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR); 308 acpi_enable_gpe(NULL, ec->gpe);
309 } else if (test_bit(EC_FLAGS_GPE_MODE, &ec->flags) && 309 } else if (test_bit(EC_FLAGS_GPE_MODE, &ec->flags) &&
310 t->irq_count > ACPI_EC_STORM_THRESHOLD) { 310 t->irq_count > ACPI_EC_STORM_THRESHOLD) {
311 pr_info(PREFIX "GPE storm detected, " 311 pr_info(PREFIX "GPE storm detected, "
@@ -897,7 +897,7 @@ static int ec_install_handlers(struct acpi_ec *ec)
897 if (ACPI_FAILURE(status)) 897 if (ACPI_FAILURE(status))
898 return -ENODEV; 898 return -ENODEV;
899 acpi_set_gpe_type(NULL, ec->gpe, ACPI_GPE_TYPE_RUNTIME); 899 acpi_set_gpe_type(NULL, ec->gpe, ACPI_GPE_TYPE_RUNTIME);
900 acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR); 900 acpi_enable_gpe(NULL, ec->gpe);
901 status = acpi_install_address_space_handler(ec->handle, 901 status = acpi_install_address_space_handler(ec->handle,
902 ACPI_ADR_SPACE_EC, 902 ACPI_ADR_SPACE_EC,
903 &acpi_ec_space_handler, 903 &acpi_ec_space_handler,
@@ -1036,7 +1036,7 @@ static int acpi_ec_suspend(struct acpi_device *device, pm_message_t state)
1036 /* Stop using GPE */ 1036 /* Stop using GPE */
1037 set_bit(EC_FLAGS_NO_GPE, &ec->flags); 1037 set_bit(EC_FLAGS_NO_GPE, &ec->flags);
1038 clear_bit(EC_FLAGS_GPE_MODE, &ec->flags); 1038 clear_bit(EC_FLAGS_GPE_MODE, &ec->flags);
1039 acpi_disable_gpe(NULL, ec->gpe, ACPI_NOT_ISR); 1039 acpi_disable_gpe(NULL, ec->gpe);
1040 return 0; 1040 return 0;
1041} 1041}
1042 1042
@@ -1045,7 +1045,7 @@ static int acpi_ec_resume(struct acpi_device *device)
1045 struct acpi_ec *ec = acpi_driver_data(device); 1045 struct acpi_ec *ec = acpi_driver_data(device);
1046 /* Enable use of GPE back */ 1046 /* Enable use of GPE back */
1047 clear_bit(EC_FLAGS_NO_GPE, &ec->flags); 1047 clear_bit(EC_FLAGS_NO_GPE, &ec->flags);
1048 acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR); 1048 acpi_enable_gpe(NULL, ec->gpe);
1049 return 0; 1049 return 0;
1050} 1050}
1051 1051
diff --git a/drivers/acpi/events/evxfevnt.c b/drivers/acpi/events/evxfevnt.c
index 73bfd6bf962f..39db00874a22 100644
--- a/drivers/acpi/events/evxfevnt.c
+++ b/drivers/acpi/events/evxfevnt.c
@@ -248,21 +248,15 @@ ACPI_EXPORT_SYMBOL(acpi_set_gpe_type)
248 * DESCRIPTION: Enable an ACPI event (general purpose) 248 * DESCRIPTION: Enable an ACPI event (general purpose)
249 * 249 *
250 ******************************************************************************/ 250 ******************************************************************************/
251acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags) 251acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number)
252{ 252{
253 acpi_status status = AE_OK; 253 acpi_status status = AE_OK;
254 acpi_cpu_flags flags;
254 struct acpi_gpe_event_info *gpe_event_info; 255 struct acpi_gpe_event_info *gpe_event_info;
255 256
256 ACPI_FUNCTION_TRACE(acpi_enable_gpe); 257 ACPI_FUNCTION_TRACE(acpi_enable_gpe);
257 258
258 /* Use semaphore lock if not executing at interrupt level */ 259 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
259
260 if (flags & ACPI_NOT_ISR) {
261 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
262 if (ACPI_FAILURE(status)) {
263 return_ACPI_STATUS(status);
264 }
265 }
266 260
267 /* Ensure that we have a valid GPE number */ 261 /* Ensure that we have a valid GPE number */
268 262
@@ -277,9 +271,7 @@ acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags)
277 status = acpi_ev_enable_gpe(gpe_event_info, TRUE); 271 status = acpi_ev_enable_gpe(gpe_event_info, TRUE);
278 272
279 unlock_and_exit: 273 unlock_and_exit:
280 if (flags & ACPI_NOT_ISR) { 274 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
281 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
282 }
283 return_ACPI_STATUS(status); 275 return_ACPI_STATUS(status);
284} 276}
285 277
@@ -299,22 +291,15 @@ ACPI_EXPORT_SYMBOL(acpi_enable_gpe)
299 * DESCRIPTION: Disable an ACPI event (general purpose) 291 * DESCRIPTION: Disable an ACPI event (general purpose)
300 * 292 *
301 ******************************************************************************/ 293 ******************************************************************************/
302acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags) 294acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number)
303{ 295{
304 acpi_status status = AE_OK; 296 acpi_status status = AE_OK;
297 acpi_cpu_flags flags;
305 struct acpi_gpe_event_info *gpe_event_info; 298 struct acpi_gpe_event_info *gpe_event_info;
306 299
307 ACPI_FUNCTION_TRACE(acpi_disable_gpe); 300 ACPI_FUNCTION_TRACE(acpi_disable_gpe);
308 301
309 /* Use semaphore lock if not executing at interrupt level */ 302 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
310
311 if (flags & ACPI_NOT_ISR) {
312 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
313 if (ACPI_FAILURE(status)) {
314 return_ACPI_STATUS(status);
315 }
316 }
317
318 /* Ensure that we have a valid GPE number */ 303 /* Ensure that we have a valid GPE number */
319 304
320 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); 305 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
@@ -325,10 +310,8 @@ acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags)
325 310
326 status = acpi_ev_disable_gpe(gpe_event_info); 311 status = acpi_ev_disable_gpe(gpe_event_info);
327 312
328 unlock_and_exit: 313unlock_and_exit:
329 if (flags & ACPI_NOT_ISR) { 314 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
330 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
331 }
332 return_ACPI_STATUS(status); 315 return_ACPI_STATUS(status);
333} 316}
334 317
diff --git a/drivers/acpi/sleep/wakeup.c b/drivers/acpi/sleep/wakeup.c
index 38655eb132dc..dea4c23df764 100644
--- a/drivers/acpi/sleep/wakeup.c
+++ b/drivers/acpi/sleep/wakeup.c
@@ -88,7 +88,7 @@ void acpi_enable_wakeup_device(u8 sleep_state)
88 spin_unlock(&acpi_device_lock); 88 spin_unlock(&acpi_device_lock);
89 if (!dev->wakeup.flags.run_wake) 89 if (!dev->wakeup.flags.run_wake)
90 acpi_enable_gpe(dev->wakeup.gpe_device, 90 acpi_enable_gpe(dev->wakeup.gpe_device,
91 dev->wakeup.gpe_number, ACPI_ISR); 91 dev->wakeup.gpe_number);
92 spin_lock(&acpi_device_lock); 92 spin_lock(&acpi_device_lock);
93 } 93 }
94 spin_unlock(&acpi_device_lock); 94 spin_unlock(&acpi_device_lock);
@@ -122,7 +122,7 @@ void acpi_disable_wakeup_device(u8 sleep_state)
122 ACPI_GPE_TYPE_WAKE_RUN); 122 ACPI_GPE_TYPE_WAKE_RUN);
123 /* Re-enable it, since set_gpe_type will disable it */ 123 /* Re-enable it, since set_gpe_type will disable it */
124 acpi_enable_gpe(dev->wakeup.gpe_device, 124 acpi_enable_gpe(dev->wakeup.gpe_device,
125 dev->wakeup.gpe_number, ACPI_NOT_ISR); 125 dev->wakeup.gpe_number);
126 spin_lock(&acpi_device_lock); 126 spin_lock(&acpi_device_lock);
127 } 127 }
128 continue; 128 continue;
@@ -133,7 +133,7 @@ void acpi_disable_wakeup_device(u8 sleep_state)
133 /* Never disable run-wake GPE */ 133 /* Never disable run-wake GPE */
134 if (!dev->wakeup.flags.run_wake) { 134 if (!dev->wakeup.flags.run_wake) {
135 acpi_disable_gpe(dev->wakeup.gpe_device, 135 acpi_disable_gpe(dev->wakeup.gpe_device,
136 dev->wakeup.gpe_number, ACPI_NOT_ISR); 136 dev->wakeup.gpe_number);
137 acpi_clear_gpe(dev->wakeup.gpe_device, 137 acpi_clear_gpe(dev->wakeup.gpe_device,
138 dev->wakeup.gpe_number, ACPI_NOT_ISR); 138 dev->wakeup.gpe_number, ACPI_NOT_ISR);
139 } 139 }
@@ -162,7 +162,7 @@ static int __init acpi_wakeup_device_init(void)
162 dev->wakeup.gpe_number, 162 dev->wakeup.gpe_number,
163 ACPI_GPE_TYPE_WAKE_RUN); 163 ACPI_GPE_TYPE_WAKE_RUN);
164 acpi_enable_gpe(dev->wakeup.gpe_device, 164 acpi_enable_gpe(dev->wakeup.gpe_device,
165 dev->wakeup.gpe_number, ACPI_NOT_ISR); 165 dev->wakeup.gpe_number);
166 dev->wakeup.state.enabled = 1; 166 dev->wakeup.state.enabled = 1;
167 spin_lock(&acpi_device_lock); 167 spin_lock(&acpi_device_lock);
168 } 168 }
diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c
index 1d74171b7940..11995b612ad7 100644
--- a/drivers/acpi/system.c
+++ b/drivers/acpi/system.c
@@ -394,10 +394,10 @@ static ssize_t counter_set(struct kobject *kobj,
394 if (index < num_gpes) { 394 if (index < num_gpes) {
395 if (!strcmp(buf, "disable\n") && 395 if (!strcmp(buf, "disable\n") &&
396 (status & ACPI_EVENT_FLAG_ENABLED)) 396 (status & ACPI_EVENT_FLAG_ENABLED))
397 result = acpi_disable_gpe(handle, index, ACPI_NOT_ISR); 397 result = acpi_disable_gpe(handle, index);
398 else if (!strcmp(buf, "enable\n") && 398 else if (!strcmp(buf, "enable\n") &&
399 !(status & ACPI_EVENT_FLAG_ENABLED)) 399 !(status & ACPI_EVENT_FLAG_ENABLED))
400 result = acpi_enable_gpe(handle, index, ACPI_NOT_ISR); 400 result = acpi_enable_gpe(handle, index);
401 else if (!strcmp(buf, "clear\n") && 401 else if (!strcmp(buf, "clear\n") &&
402 (status & ACPI_EVENT_FLAG_SET)) 402 (status & ACPI_EVENT_FLAG_SET))
403 result = acpi_clear_gpe(handle, index, ACPI_NOT_ISR); 403 result = acpi_clear_gpe(handle, index, ACPI_NOT_ISR);