Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/davej/cpufreq
[safe/jmp/linux-2.6] / drivers / acpi / wakeup.c
index 2d34806..e0ee0c0 100644 (file)
@@ -8,14 +8,18 @@
 #include <acpi/acpi_drivers.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
+
+#include "internal.h"
 #include "sleep.h"
 
+/*
+ * We didn't lock acpi_device_lock in the file, because it invokes oops in
+ * suspend/resume and isn't really required as this is called in S-state. At
+ * that time, there is no device hotplug
+ **/
 #define _COMPONENT             ACPI_SYSTEM_COMPONENT
 ACPI_MODULE_NAME("wakeup_devices")
 
-extern struct list_head acpi_wakeup_device_list;
-extern spinlock_t acpi_device_lock;
-
 /**
  * acpi_enable_wakeup_device_prep - prepare wakeup devices
  *     @sleep_state:   ACPI state
@@ -27,7 +31,6 @@ void acpi_enable_wakeup_device_prep(u8 sleep_state)
 {
        struct list_head *node, *next;
 
-       spin_lock(&acpi_device_lock);
        list_for_each_safe(node, next, &acpi_wakeup_device_list) {
                struct acpi_device *dev = container_of(node,
                                                       struct acpi_device,
@@ -38,11 +41,8 @@ void acpi_enable_wakeup_device_prep(u8 sleep_state)
                    (sleep_state > (u32) dev->wakeup.sleep_state))
                        continue;
 
-               spin_unlock(&acpi_device_lock);
                acpi_enable_wakeup_device_power(dev, sleep_state);
-               spin_lock(&acpi_device_lock);
        }
-       spin_unlock(&acpi_device_lock);
 }
 
 /**
@@ -58,7 +58,6 @@ void acpi_enable_wakeup_device(u8 sleep_state)
         * Caution: this routine must be invoked when interrupt is disabled 
         * Refer ACPI2.0: P212
         */
-       spin_lock(&acpi_device_lock);
        list_for_each_safe(node, next, &acpi_wakeup_device_list) {
                struct acpi_device *dev =
                        container_of(node, struct acpi_device, wakeup_list);
@@ -69,25 +68,20 @@ void acpi_enable_wakeup_device(u8 sleep_state)
                /* If users want to disable run-wake GPE,
                 * we only disable it for wake and leave it for runtime
                 */
-               if ((!dev->wakeup.state.enabled && !dev->wakeup.flags.prepared)
+               if ((!dev->wakeup.state.enabled && !dev->wakeup.prepare_count)
                    || sleep_state > (u32) dev->wakeup.sleep_state) {
                        if (dev->wakeup.flags.run_wake) {
-                               spin_unlock(&acpi_device_lock);
                                /* set_gpe_type will disable GPE, leave it like that */
                                acpi_set_gpe_type(dev->wakeup.gpe_device,
                                                  dev->wakeup.gpe_number,
                                                  ACPI_GPE_TYPE_RUNTIME);
-                               spin_lock(&acpi_device_lock);
                        }
                        continue;
                }
-               spin_unlock(&acpi_device_lock);
                if (!dev->wakeup.flags.run_wake)
                        acpi_enable_gpe(dev->wakeup.gpe_device,
                                        dev->wakeup.gpe_number);
-               spin_lock(&acpi_device_lock);
        }
-       spin_unlock(&acpi_device_lock);
 }
 
 /**
@@ -99,7 +93,6 @@ void acpi_disable_wakeup_device(u8 sleep_state)
 {
        struct list_head *node, *next;
 
-       spin_lock(&acpi_device_lock);
        list_for_each_safe(node, next, &acpi_wakeup_device_list) {
                struct acpi_device *dev =
                        container_of(node, struct acpi_device, wakeup_list);
@@ -107,22 +100,19 @@ void acpi_disable_wakeup_device(u8 sleep_state)
                if (!dev->wakeup.flags.valid)
                        continue;
 
-               if ((!dev->wakeup.state.enabled && !dev->wakeup.flags.prepared)
+               if ((!dev->wakeup.state.enabled && !dev->wakeup.prepare_count)
                    || sleep_state > (u32) dev->wakeup.sleep_state) {
                        if (dev->wakeup.flags.run_wake) {
-                               spin_unlock(&acpi_device_lock);
                                acpi_set_gpe_type(dev->wakeup.gpe_device,
                                                  dev->wakeup.gpe_number,
                                                  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);
-                               spin_lock(&acpi_device_lock);
                        }
                        continue;
                }
 
-               spin_unlock(&acpi_device_lock);
                acpi_disable_wakeup_device_power(dev);
                /* Never disable run-wake GPE */
                if (!dev->wakeup.flags.run_wake) {
@@ -131,19 +121,14 @@ void acpi_disable_wakeup_device(u8 sleep_state)
                        acpi_clear_gpe(dev->wakeup.gpe_device,
                                       dev->wakeup.gpe_number, ACPI_NOT_ISR);
                }
-               spin_lock(&acpi_device_lock);
        }
-       spin_unlock(&acpi_device_lock);
 }
 
-static int __init acpi_wakeup_device_init(void)
+int __init acpi_wakeup_device_init(void)
 {
        struct list_head *node, *next;
 
-       if (acpi_disabled)
-               return 0;
-
-       spin_lock(&acpi_device_lock);
+       mutex_lock(&acpi_device_lock);
        list_for_each_safe(node, next, &acpi_wakeup_device_list) {
                struct acpi_device *dev = container_of(node,
                                                       struct acpi_device,
@@ -151,17 +136,13 @@ static int __init acpi_wakeup_device_init(void)
                /* In case user doesn't load button driver */
                if (!dev->wakeup.flags.run_wake || dev->wakeup.state.enabled)
                        continue;
-               spin_unlock(&acpi_device_lock);
                acpi_set_gpe_type(dev->wakeup.gpe_device,
                                  dev->wakeup.gpe_number,
                                  ACPI_GPE_TYPE_WAKE_RUN);
                acpi_enable_gpe(dev->wakeup.gpe_device,
                                dev->wakeup.gpe_number);
                dev->wakeup.state.enabled = 1;
-               spin_lock(&acpi_device_lock);
        }
-       spin_unlock(&acpi_device_lock);
+       mutex_unlock(&acpi_device_lock);
        return 0;
 }
-
-late_initcall(acpi_wakeup_device_init);