]> pilppa.com Git - linux-2.6-omap-h63xx.git/commitdiff
ACPI: Add "acpi.power_nocheck=1" to disable power state check in power transition
authorZhao Yakui <yakui.zhao@intel.com>
Mon, 11 Aug 2008 06:57:50 +0000 (14:57 +0800)
committerLen Brown <len.brown@intel.com>
Wed, 22 Oct 2008 21:59:57 +0000 (17:59 -0400)
   Maybe the incorrect power state is returned on the bogus bios, which
is different with the real power state. For example: the bios returns D0
state and the real power state is D3. OS expects to set the device to D0
state. In  such case if OS uses the power state returned by the BIOS and
checks the device power state very strictly in power transition, the device
can't be transited to the correct power state.

   So the boot option of "acpi.power_nocheck=1" is added to avoid checking
the device power in the course of device power transition.

http://bugzilla.kernel.org/show_bug.cgi?id=8049
http://bugzilla.kernel.org/show_bug.cgi?id=11000

Signed-off-by: Zhao Yakui <yakui.zhao@intel.com>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
Signed-off-by: Li Shaohua <shaohua.li@intel.com>
Signed-off-by: Andi Kleen <ak@linux.intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
Documentation/kernel-parameters.txt
drivers/acpi/bus.c
drivers/acpi/power.c
include/acpi/acpi_drivers.h

index 44d1bd142edf83fdf7c83ee509c44c0b6b20a136..99cf83fd69478aab1e675688cab2463d8815edc8 100644 (file)
@@ -251,6 +251,14 @@ and is between 256 and 4096 characters. It is defined in the file
                        Warning: Many of these options can produce a lot of
                        output and make your system unusable. Be very careful.
 
+       acpi.power_nocheck=     [HW,ACPI]
+                       Format: 1/0 enable/disable the check of power state.
+                       On some bogus BIOS the _PSC object/_STA object of
+                       power resource can't return the correct device power
+                       state. In such case it is unneccessary to check its
+                       power state again in power transition.
+                       1 : disable the power state check
+
        acpi_pm_good    [X86-32,X86-64]
                        Override the pmtimer bug detection: force the kernel
                        to assume that this machine's pmtimer latches its value
index ccae305ee55dcb554c441d908c20b43d509b3709..91bdeb3b081e7d5f7f2dde1309e6a597175fd9c1 100644 (file)
@@ -223,7 +223,19 @@ int acpi_bus_set_power(acpi_handle handle, int state)
        /*
         * Get device's current power state
         */
-       acpi_bus_get_power(device->handle, &device->power.state);
+       if (!acpi_power_nocheck) {
+               /*
+                * Maybe the incorrect power state is returned on the bogus
+                * bios, which is different with the real power state.
+                * For example: the bios returns D0 state and the real power
+                * state is D3. OS expects to set the device to D0 state. In
+                * such case if OS uses the power state returned by the BIOS,
+                * the device can't be transisted to the correct power state.
+                * So if the acpi_power_nocheck is set, it is unnecessary to
+                * get the power state by calling acpi_bus_get_power.
+                */
+               acpi_bus_get_power(device->handle, &device->power.state);
+       }
        if ((state == device->power.state) && !device->flags.force_power_state) {
                ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at D%d\n",
                                  state));
index e7bab75075a90dce99ad98e085f264f96d56cc68..7ff7349c0c52b92d02e230a4322b3b85f4baa516 100644 (file)
@@ -54,6 +54,14 @@ ACPI_MODULE_NAME("power");
 #define ACPI_POWER_RESOURCE_STATE_OFF  0x00
 #define ACPI_POWER_RESOURCE_STATE_ON   0x01
 #define ACPI_POWER_RESOURCE_STATE_UNKNOWN 0xFF
+
+#ifdef MODULE_PARAM_PREFIX
+#undef MODULE_PARAM_PREFIX
+#endif
+#define MODULE_PARAM_PREFIX "acpi."
+int acpi_power_nocheck;
+module_param_named(power_nocheck, acpi_power_nocheck, bool, 000);
+
 static int acpi_power_add(struct acpi_device *device);
 static int acpi_power_remove(struct acpi_device *device, int type);
 static int acpi_power_resume(struct acpi_device *device);
@@ -228,12 +236,18 @@ static int acpi_power_on(acpi_handle handle, struct acpi_device *dev)
        if (ACPI_FAILURE(status))
                return -ENODEV;
 
-       result = acpi_power_get_state(resource->device->handle, &state);
-       if (result)
-               return result;
-       if (state != ACPI_POWER_RESOURCE_STATE_ON)
-               return -ENOEXEC;
-
+       if (!acpi_power_nocheck) {
+               /*
+                * If acpi_power_nocheck is set, it is unnecessary to check
+                * the power state after power transition.
+                */
+               result = acpi_power_get_state(resource->device->handle,
+                               &state);
+               if (result)
+                       return result;
+               if (state != ACPI_POWER_RESOURCE_STATE_ON)
+                       return -ENOEXEC;
+       }
        /* Update the power resource's _device_ power state */
        resource->device->power.state = ACPI_STATE_D0;
 
@@ -279,11 +293,17 @@ static int acpi_power_off_device(acpi_handle handle, struct acpi_device *dev)
        if (ACPI_FAILURE(status))
                return -ENODEV;
 
-       result = acpi_power_get_state(handle, &state);
-       if (result)
-               return result;
-       if (state != ACPI_POWER_RESOURCE_STATE_OFF)
-               return -ENOEXEC;
+       if (!acpi_power_nocheck) {
+               /*
+                * If acpi_power_nocheck is set, it is unnecessary to check
+                * the power state after power transition.
+                */
+               result = acpi_power_get_state(handle, &state);
+               if (result)
+                       return result;
+               if (state != ACPI_POWER_RESOURCE_STATE_OFF)
+                       return -ENOEXEC;
+       }
 
        /* Update the power resource's _device_ power state */
        resource->device->power.state = ACPI_STATE_D3;
index e5f38e5ce86fc5a4e28ec624e529ee1db59c16c0..efbaa271ee11517b66f0d764df3a297f115dc72b 100644 (file)
@@ -93,6 +93,7 @@ int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state);
 int acpi_disable_wakeup_device_power(struct acpi_device *dev);
 int acpi_power_get_inferred_state(struct acpi_device *device);
 int acpi_power_transition(struct acpi_device *device, int state);
+extern int acpi_power_nocheck;
 #endif
 
 /* --------------------------------------------------------------------------