ACPICA: Use spinlock for acpi_{en|dis}able_gpe
Alexey Starikovskiy [Sat, 25 Oct 2008 17:48:46 +0000 (21:48 +0400)]
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>

drivers/acpi/button.c
drivers/acpi/ec.c
drivers/acpi/events/evxfevnt.c
drivers/acpi/sleep/wakeup.c
drivers/acpi/system.c
include/acpi/acpixf.h

index cb046c3..eb6bf30 100644 (file)
@@ -479,7 +479,7 @@ static int acpi_button_add(struct acpi_device *device)
                                  device->wakeup.gpe_number,
                                  ACPI_GPE_TYPE_WAKE_RUN);
                acpi_enable_gpe(device->wakeup.gpe_device,
-                               device->wakeup.gpe_number, ACPI_NOT_ISR);
+                               device->wakeup.gpe_number);
                device->wakeup.state.enabled = 1;
        }
 
index 34c67ca..89d6d28 100644 (file)
@@ -282,7 +282,7 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec,
        /* disable GPE during transaction if storm is detected */
        if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) {
                clear_bit(EC_FLAGS_GPE_MODE, &ec->flags);
-               acpi_disable_gpe(NULL, ec->gpe, ACPI_NOT_ISR);
+               acpi_disable_gpe(NULL, ec->gpe);
        }
        /* start transaction */
        spin_lock_irqsave(&ec->curr_lock, tmp);
@@ -305,7 +305,7 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec,
                /* check if we received SCI during transaction */
                ec_check_sci(ec, acpi_ec_read_status(ec));
                /* it is safe to enable GPE outside of transaction */
-               acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR);
+               acpi_enable_gpe(NULL, ec->gpe);
        } else if (test_bit(EC_FLAGS_GPE_MODE, &ec->flags) &&
                   t->irq_count > ACPI_EC_STORM_THRESHOLD) {
                pr_info(PREFIX "GPE storm detected, "
@@ -897,7 +897,7 @@ static int ec_install_handlers(struct acpi_ec *ec)
        if (ACPI_FAILURE(status))
                return -ENODEV;
        acpi_set_gpe_type(NULL, ec->gpe, ACPI_GPE_TYPE_RUNTIME);
-       acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR);
+       acpi_enable_gpe(NULL, ec->gpe);
        status = acpi_install_address_space_handler(ec->handle,
                                                    ACPI_ADR_SPACE_EC,
                                                    &acpi_ec_space_handler,
@@ -1036,7 +1036,7 @@ static int acpi_ec_suspend(struct acpi_device *device, pm_message_t state)
        /* Stop using GPE */
        set_bit(EC_FLAGS_NO_GPE, &ec->flags);
        clear_bit(EC_FLAGS_GPE_MODE, &ec->flags);
-       acpi_disable_gpe(NULL, ec->gpe, ACPI_NOT_ISR);
+       acpi_disable_gpe(NULL, ec->gpe);
        return 0;
 }
 
@@ -1045,7 +1045,7 @@ static int acpi_ec_resume(struct acpi_device *device)
        struct acpi_ec *ec = acpi_driver_data(device);
        /* Enable use of GPE back */
        clear_bit(EC_FLAGS_NO_GPE, &ec->flags);
-       acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR);
+       acpi_enable_gpe(NULL, ec->gpe);
        return 0;
 }
 
index 73bfd6b..39db008 100644 (file)
@@ -248,21 +248,15 @@ ACPI_EXPORT_SYMBOL(acpi_set_gpe_type)
  * DESCRIPTION: Enable an ACPI event (general purpose)
  *
  ******************************************************************************/
-acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags)
+acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number)
 {
        acpi_status status = AE_OK;
+       acpi_cpu_flags flags;
        struct acpi_gpe_event_info *gpe_event_info;
 
        ACPI_FUNCTION_TRACE(acpi_enable_gpe);
 
-       /* Use semaphore lock if not executing at interrupt level */
-
-       if (flags & ACPI_NOT_ISR) {
-               status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
-               if (ACPI_FAILURE(status)) {
-                       return_ACPI_STATUS(status);
-               }
-       }
+       flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
 
        /* Ensure that we have a valid GPE number */
 
@@ -277,9 +271,7 @@ acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags)
        status = acpi_ev_enable_gpe(gpe_event_info, TRUE);
 
       unlock_and_exit:
-       if (flags & ACPI_NOT_ISR) {
-               (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
-       }
+       acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
        return_ACPI_STATUS(status);
 }
 
@@ -299,22 +291,15 @@ ACPI_EXPORT_SYMBOL(acpi_enable_gpe)
  * DESCRIPTION: Disable an ACPI event (general purpose)
  *
  ******************************************************************************/
-acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags)
+acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number)
 {
        acpi_status status = AE_OK;
+       acpi_cpu_flags flags;
        struct acpi_gpe_event_info *gpe_event_info;
 
        ACPI_FUNCTION_TRACE(acpi_disable_gpe);
 
-       /* Use semaphore lock if not executing at interrupt level */
-
-       if (flags & ACPI_NOT_ISR) {
-               status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
-               if (ACPI_FAILURE(status)) {
-                       return_ACPI_STATUS(status);
-               }
-       }
-
+       flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
        /* Ensure that we have a valid GPE number */
 
        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)
 
        status = acpi_ev_disable_gpe(gpe_event_info);
 
-      unlock_and_exit:
-       if (flags & ACPI_NOT_ISR) {
-               (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
-       }
+unlock_and_exit:
+       acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
        return_ACPI_STATUS(status);
 }
 
index 38655eb..dea4c23 100644 (file)
@@ -88,7 +88,7 @@ void acpi_enable_wakeup_device(u8 sleep_state)
                spin_unlock(&acpi_device_lock);
                if (!dev->wakeup.flags.run_wake)
                        acpi_enable_gpe(dev->wakeup.gpe_device,
-                                       dev->wakeup.gpe_number, ACPI_ISR);
+                                       dev->wakeup.gpe_number);
                spin_lock(&acpi_device_lock);
        }
        spin_unlock(&acpi_device_lock);
@@ -122,7 +122,7 @@ void acpi_disable_wakeup_device(u8 sleep_state)
                                                  ACPI_GPE_TYPE_WAKE_RUN);
                                /* Re-enable it, since set_gpe_type will disable it */
                                acpi_enable_gpe(dev->wakeup.gpe_device,
-                                               dev->wakeup.gpe_number, ACPI_NOT_ISR);
+                                               dev->wakeup.gpe_number);
                                spin_lock(&acpi_device_lock);
                        }
                        continue;
@@ -133,7 +133,7 @@ void acpi_disable_wakeup_device(u8 sleep_state)
                /* Never disable run-wake GPE */
                if (!dev->wakeup.flags.run_wake) {
                        acpi_disable_gpe(dev->wakeup.gpe_device,
-                                        dev->wakeup.gpe_number, ACPI_NOT_ISR);
+                                        dev->wakeup.gpe_number);
                        acpi_clear_gpe(dev->wakeup.gpe_device,
                                       dev->wakeup.gpe_number, ACPI_NOT_ISR);
                }
@@ -162,7 +162,7 @@ static int __init acpi_wakeup_device_init(void)
                                  dev->wakeup.gpe_number,
                                  ACPI_GPE_TYPE_WAKE_RUN);
                acpi_enable_gpe(dev->wakeup.gpe_device,
-                               dev->wakeup.gpe_number, ACPI_NOT_ISR);
+                               dev->wakeup.gpe_number);
                dev->wakeup.state.enabled = 1;
                spin_lock(&acpi_device_lock);
        }
index 1d74171..11995b6 100644 (file)
@@ -394,10 +394,10 @@ static ssize_t counter_set(struct kobject *kobj,
        if (index < num_gpes) {
                if (!strcmp(buf, "disable\n") &&
                                (status & ACPI_EVENT_FLAG_ENABLED))
-                       result = acpi_disable_gpe(handle, index, ACPI_NOT_ISR);
+                       result = acpi_disable_gpe(handle, index);
                else if (!strcmp(buf, "enable\n") &&
                                !(status & ACPI_EVENT_FLAG_ENABLED))
-                       result = acpi_enable_gpe(handle, index, ACPI_NOT_ISR);
+                       result = acpi_enable_gpe(handle, index);
                else if (!strcmp(buf, "clear\n") &&
                                (status & ACPI_EVENT_FLAG_SET))
                        result = acpi_clear_gpe(handle, index, ACPI_NOT_ISR);
index 94d94e1..33bc0e3 100644 (file)
@@ -252,9 +252,9 @@ acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status);
 
 acpi_status acpi_set_gpe_type(acpi_handle gpe_device, u32 gpe_number, u8 type);
 
-acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags);
+acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number);
 
-acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags);
+acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number);
 
 acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags);