]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
Merge branches 'release', 'dmi', 'idle' and 'misc' into release
authorLen Brown <len.brown@intel.com>
Thu, 14 Feb 2008 07:44:28 +0000 (02:44 -0500)
committerLen Brown <len.brown@intel.com>
Thu, 14 Feb 2008 07:44:28 +0000 (02:44 -0500)
14 files changed:
Documentation/00-INDEX
Documentation/cpuidle/core.txt [new file with mode: 0644]
Documentation/cpuidle/driver.txt [new file with mode: 0644]
Documentation/cpuidle/governor.txt [new file with mode: 0644]
Documentation/cpuidle/sysfs.txt [new file with mode: 0644]
arch/x86/kernel/acpi/cstate.c
drivers/acpi/blacklist.c
drivers/acpi/osl.c
drivers/acpi/processor_idle.c
drivers/cpuidle/cpuidle.c
drivers/cpuidle/sysfs.c
include/acpi/processor.h
include/linux/acpi.h
include/linux/cpuidle.h

index 8d556707bb68e9ca8357143f0c318027b16319bc..30b327a116eaa8d15af97c3047ab2c07ebc41089 100644 (file)
@@ -109,6 +109,8 @@ cpu-hotplug.txt
        - document describing CPU hotplug support in the Linux kernel.
 cpu-load.txt
        - document describing how CPU load statistics are collected.
+cpuidle/
+       - info on CPU_IDLE, CPU idle state management subsystem.
 cpusets.txt
        - documents the cpusets feature; assign CPUs and Mem to a set of tasks.
 cputopology.txt
diff --git a/Documentation/cpuidle/core.txt b/Documentation/cpuidle/core.txt
new file mode 100644 (file)
index 0000000..63ecc5d
--- /dev/null
@@ -0,0 +1,23 @@
+
+               Supporting multiple CPU idle levels in kernel
+
+                               cpuidle
+
+General Information:
+
+Various CPUs today support multiple idle levels that are differentiated
+by varying exit latencies and power consumption during idle.
+cpuidle is a generic in-kernel infrastructure that separates
+idle policy (governor) from idle mechanism (driver) and provides a
+standardized infrastructure to support independent development of
+governors and drivers.
+
+cpuidle resides under drivers/cpuidle.
+
+Boot options:
+"cpuidle_sysfs_switch"
+enables current_governor interface in /sys/devices/system/cpu/cpuidle/,
+which can be used to switch governors at run time. This boot option
+is meant for developer testing only. In normal usage, kernel picks the
+best governor based on governor ratings.
+SEE ALSO: sysfs.txt in this directory.
diff --git a/Documentation/cpuidle/driver.txt b/Documentation/cpuidle/driver.txt
new file mode 100644 (file)
index 0000000..7a9e09e
--- /dev/null
@@ -0,0 +1,31 @@
+
+
+               Supporting multiple CPU idle levels in kernel
+
+                               cpuidle drivers
+
+
+
+
+cpuidle driver hooks into the cpuidle infrastructure and handles the
+architecture/platform dependent part of CPU idle states. Driver
+provides the platform idle state detection capability and also
+has mechanisms in place to support actual entry-exit into CPU idle states.
+
+cpuidle driver initializes the cpuidle_device structure for each CPU device
+and registers with cpuidle using cpuidle_register_device.
+
+It can also support the dynamic changes (like battery <-> AC), by using
+cpuidle_pause_and_lock, cpuidle_disable_device and cpuidle_enable_device,
+cpuidle_resume_and_unlock.
+
+Interfaces:
+extern int cpuidle_register_driver(struct cpuidle_driver *drv);
+extern void cpuidle_unregister_driver(struct cpuidle_driver *drv);
+extern int cpuidle_register_device(struct cpuidle_device *dev);
+extern void cpuidle_unregister_device(struct cpuidle_device *dev);
+
+extern void cpuidle_pause_and_lock(void);
+extern void cpuidle_resume_and_unlock(void);
+extern int cpuidle_enable_device(struct cpuidle_device *dev);
+extern void cpuidle_disable_device(struct cpuidle_device *dev);
diff --git a/Documentation/cpuidle/governor.txt b/Documentation/cpuidle/governor.txt
new file mode 100644 (file)
index 0000000..12c6bd5
--- /dev/null
@@ -0,0 +1,29 @@
+
+
+
+               Supporting multiple CPU idle levels in kernel
+
+                               cpuidle governors
+
+
+
+
+cpuidle governor is policy routine that decides what idle state to enter at
+any given time. cpuidle core uses different callbacks to the governor.
+
+* enable() to enable governor for a particular device
+* disable() to disable governor for a particular device
+* select() to select an idle state to enter
+* reflect() called after returning from the idle state, which can be used
+  by the governor for some record keeping.
+
+More than one governor can be registered at the same time and
+users can switch between drivers using /sysfs interface (when enabled).
+More than one governor part is supported for developers to easily experiment
+with different governors. By default, most optimal governor based on your
+kernel configuration and platform will be selected by cpuidle.
+
+Interfaces:
+extern int cpuidle_register_governor(struct cpuidle_governor *gov);
+extern void cpuidle_unregister_governor(struct cpuidle_governor *gov);
+struct cpuidle_governor
diff --git a/Documentation/cpuidle/sysfs.txt b/Documentation/cpuidle/sysfs.txt
new file mode 100644 (file)
index 0000000..50d7b16
--- /dev/null
@@ -0,0 +1,79 @@
+
+
+               Supporting multiple CPU idle levels in kernel
+
+                               cpuidle sysfs
+
+System global cpuidle related information and tunables are under
+/sys/devices/system/cpu/cpuidle
+
+The current interfaces in this directory has self-explanatory names:
+* current_driver
+* current_governor_ro
+
+With cpuidle_sysfs_switch boot option (meant for developer testing)
+following objects are visible instead.
+* current_driver
+* available_governors
+* current_governor
+In this case users can switch the governor at run time by writing
+to current_governor.
+
+
+Per logical CPU specific cpuidle information are under
+/sys/devices/system/cpu/cpuX/cpuidle
+for each online cpu X
+
+--------------------------------------------------------------------------------
+# ls -lR /sys/devices/system/cpu/cpu0/cpuidle/
+/sys/devices/system/cpu/cpu0/cpuidle/:
+total 0
+drwxr-xr-x 2 root root 0 Feb  8 10:42 state0
+drwxr-xr-x 2 root root 0 Feb  8 10:42 state1
+drwxr-xr-x 2 root root 0 Feb  8 10:42 state2
+drwxr-xr-x 2 root root 0 Feb  8 10:42 state3
+
+/sys/devices/system/cpu/cpu0/cpuidle/state0:
+total 0
+-r--r--r-- 1 root root 4096 Feb  8 10:42 desc
+-r--r--r-- 1 root root 4096 Feb  8 10:42 latency
+-r--r--r-- 1 root root 4096 Feb  8 10:42 name
+-r--r--r-- 1 root root 4096 Feb  8 10:42 power
+-r--r--r-- 1 root root 4096 Feb  8 10:42 time
+-r--r--r-- 1 root root 4096 Feb  8 10:42 usage
+
+/sys/devices/system/cpu/cpu0/cpuidle/state1:
+total 0
+-r--r--r-- 1 root root 4096 Feb  8 10:42 desc
+-r--r--r-- 1 root root 4096 Feb  8 10:42 latency
+-r--r--r-- 1 root root 4096 Feb  8 10:42 name
+-r--r--r-- 1 root root 4096 Feb  8 10:42 power
+-r--r--r-- 1 root root 4096 Feb  8 10:42 time
+-r--r--r-- 1 root root 4096 Feb  8 10:42 usage
+
+/sys/devices/system/cpu/cpu0/cpuidle/state2:
+total 0
+-r--r--r-- 1 root root 4096 Feb  8 10:42 desc
+-r--r--r-- 1 root root 4096 Feb  8 10:42 latency
+-r--r--r-- 1 root root 4096 Feb  8 10:42 name
+-r--r--r-- 1 root root 4096 Feb  8 10:42 power
+-r--r--r-- 1 root root 4096 Feb  8 10:42 time
+-r--r--r-- 1 root root 4096 Feb  8 10:42 usage
+
+/sys/devices/system/cpu/cpu0/cpuidle/state3:
+total 0
+-r--r--r-- 1 root root 4096 Feb  8 10:42 desc
+-r--r--r-- 1 root root 4096 Feb  8 10:42 latency
+-r--r--r-- 1 root root 4096 Feb  8 10:42 name
+-r--r--r-- 1 root root 4096 Feb  8 10:42 power
+-r--r--r-- 1 root root 4096 Feb  8 10:42 time
+-r--r--r-- 1 root root 4096 Feb  8 10:42 usage
+--------------------------------------------------------------------------------
+
+
+* desc : Small description about the idle state (string)
+* latency : Latency to exit out of this idle state (in microseconds)
+* name : Name of the idle state (string)
+* power : Power consumed while in this idle state (in milliwatts)
+* time : Total time spent in this idle state (in microseconds)
+* usage : Number of times this state was entered (count)
index 10b67170b133eccc3ed2dff7fef44e95a44e76ad..8ca3557a6d599c947a8b71314902d2d9470e8d48 100644 (file)
@@ -126,6 +126,8 @@ int acpi_processor_ffh_cstate_probe(unsigned int cpu,
                printk(KERN_DEBUG "Monitor-Mwait will be used to enter C-%d "
                       "state\n", cx->type);
        }
+       snprintf(cx->desc, ACPI_CX_DESC_LEN, "ACPI FFH INTEL MWAIT 0x%x",
+                cx->address);
 
 out:
        set_cpus_allowed(current, saved_mask);
index 9ce983ed60f00f762af1c950455f5088ecc64161..ea92bac42c53dd438fae0c82b2e310b8098f7dff 100644 (file)
@@ -186,6 +186,12 @@ static int __init dmi_unknown_osi_linux(const struct dmi_system_id *d)
        acpi_dmi_osi_linux(-1, d);      /* unknown */
        return 0;
 }
+static int __init dmi_disable_osi_vista(const struct dmi_system_id *d)
+{
+       printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident);
+       acpi_osi_setup("!Windows 2006");
+       return 0;
+}
 
 /*
  * Most BIOS that invoke OSI(Linux) do nothing with it.
@@ -228,10 +234,10 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = {
         * DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 5520"),
         * DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 6460"),
         * DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 7510"),
-        * DMI_MATCH(DMI_PRODUCT_NAME, "Extensa 5220"),
         *
         * _OSI(Linux) is a NOP:
         * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5315"),
+        * DMI_MATCH(DMI_PRODUCT_NAME, "Extensa 5220"),
         */
        {
        .callback = dmi_disable_osi_linux,
@@ -327,12 +333,20 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = {
        },
        { /* OSI(Linux) effect unknown */
        .callback = dmi_unknown_osi_linux,
-       .ident = "Dell OP GX620",
+       .ident = "Dell OptiPlex GX620",
        .matches = {
                     DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
                     DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex GX620"),
                },
        },
+       { /* OSI(Linux) causes some USB initialization to not run */
+       .callback = dmi_unknown_osi_linux,
+       .ident = "Dell OptiPlex 755",
+       .matches = {
+                    DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+                    DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 755"),
+               },
+       },
        { /* OSI(Linux) effect unknown */
        .callback = dmi_unknown_osi_linux,
        .ident = "Dell PE 1900",
@@ -342,6 +356,14 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = {
                },
        },
        { /* OSI(Linux) is a NOP */
+       .callback = dmi_unknown_osi_linux,
+       .ident = "Dell PE 1950",
+       .matches = {
+                    DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+                    DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 1950"),
+               },
+       },
+       { /* OSI(Linux) is a NOP */
        .callback = dmi_disable_osi_linux,
        .ident = "Dell PE R200",
        .matches = {
@@ -357,6 +379,22 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = {
                     DMI_MATCH(DMI_PRODUCT_NAME, "Precision WorkStation 390"),
                },
        },
+       { /* OSI(Linux) touches USB */
+       .callback = dmi_unknown_osi_linux,
+       .ident = "Dell PR 390",
+       .matches = {
+                    DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+                    DMI_MATCH(DMI_PRODUCT_NAME, "Precision WorkStation 690"),
+               },
+       },
+       { /* OSI(Linux) unknown - ASL looks benign, but may effect dock/SMM */
+       .callback = dmi_unknown_osi_linux,
+       .ident = "Dell PR M4300",
+       .matches = {
+                    DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+                    DMI_MATCH(DMI_PRODUCT_NAME, "Precision M4300"),
+               },
+       },
        { /* OSI(Linux) is a NOP */
        .callback = dmi_disable_osi_linux,
        .ident = "Dell Vostro 1000",
@@ -390,10 +428,10 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = {
         * DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pi 1536"),
         * DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pi 1556"),
         * DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xi 1546"),
+        * DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO Mobile V5505"),
         * _OSI(Linux) unknown effect:
         * DMI_MATCH(DMI_PRODUCT_NAME, "Amilo M1425"),
         * DMI_MATCH(DMI_PRODUCT_NAME, "Amilo Si 1520"),
-        * DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO Mobile V5505"),
         */
        {
        .callback = dmi_disable_osi_linux,
@@ -402,6 +440,14 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = {
                     DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
                },
        },
+       {
+       .callback = dmi_disable_osi_vista,
+       .ident = "Fujitsu Siemens",
+       .matches = {
+                    DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
+                    DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO Mobile V5505"),
+               },
+       },
        /*
         * Disable OSI(Linux) warnings on all "Hewlett-Packard"
         *
@@ -443,10 +489,11 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = {
         * _OSI(Linux) helps sound
         * DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad R61"),
         * DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T61"),
+        * _OSI(Linux) has Linux specific hooks
+        * DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X61"),
         * _OSI(Linux) is a NOP:
         * DMI_MATCH(DMI_PRODUCT_VERSION, "3000 N100"),
-        * _OSI(Linux) effect unknown
-        * DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X61"),
+        * DMI_MATCH(DMI_PRODUCT_VERSION, "LENOVO3000 V100"),
         */
        {
        .callback = dmi_enable_osi_linux,
@@ -465,7 +512,7 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = {
                },
        },
        {
-       .callback = dmi_unknown_osi_linux,
+       .callback = dmi_enable_osi_linux,
        .ident = "Lenovo ThinkPad X61",
        .matches = {
                     DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
@@ -473,7 +520,7 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = {
                },
        },
        {
-       .callback = dmi_unknown_osi_linux,
+       .callback = dmi_disable_osi_linux,
        .ident = "Lenovo 3000 V100",
        .matches = {
                     DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
@@ -543,8 +590,9 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = {
         * Disable OSI(Linux) warnings on all "Sony Corporation"
         *
         * _OSI(Linux) is a NOP:
-        * DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SZ650N"),
+        * DMI_MATCH(DMI_PRODUCT_NAME, "VGN-NR11S_S"),
         * DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SZ38GP_C"),
+        * DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SZ650N"),
         * DMI_MATCH(DMI_PRODUCT_NAME, "VGN-TZ21MN_N"),
         * _OSI(Linux) unknown effect:
         * DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FZ11M"),
index b51954d80ef984980fedd00b402916fc9c722d67..8edba7b678eb9d33493f422472dc16fdb4c6f84e 100644 (file)
@@ -1109,7 +1109,7 @@ void __init acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d)
  * string starting with '!' disables that string
  * otherwise string is added to list, augmenting built-in strings
  */
-static int __init acpi_osi_setup(char *str)
+int __init acpi_osi_setup(char *str)
 {
        if (str == NULL || *str == '\0') {
                printk(KERN_INFO PREFIX "_OSI method disabled\n");
index 1f022b0846d477c00a01251dedd4aba5dbf12d4d..980e1c33e6c5eeb11a7ec91132c2aa1cb614ef0a 100644 (file)
@@ -945,11 +945,16 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr)
                                 * Otherwise, ignore this info and continue.
                                 */
                                cx.entry_method = ACPI_CSTATE_HALT;
+                               snprintf(cx.desc, ACPI_CX_DESC_LEN, "ACPI HLT");
                        } else {
                                continue;
                        }
+               } else {
+                       snprintf(cx.desc, ACPI_CX_DESC_LEN, "ACPI IOPORT 0x%x",
+                                cx.address);
                }
 
+
                obj = &(element->package.elements[2]);
                if (obj->type != ACPI_TYPE_INTEGER)
                        continue;
@@ -1651,6 +1656,11 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr)
                return -EINVAL;
        }
 
+       for (i = 0; i < CPUIDLE_STATE_MAX; i++) {
+               dev->states[i].name[0] = '\0';
+               dev->states[i].desc[0] = '\0';
+       }
+
        for (i = 1; i < ACPI_PROCESSOR_MAX_POWER && i <= max_cstate; i++) {
                cx = &pr->power.states[i];
                state = &dev->states[count];
@@ -1667,6 +1677,7 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr)
                cpuidle_set_statedata(state, cx);
 
                snprintf(state->name, CPUIDLE_NAME_LEN, "C%d", i);
+               strncpy(state->desc, cx->desc, CPUIDLE_DESC_LEN);
                state->exit_latency = cx->latency;
                state->target_residency = cx->latency * latency_factor;
                state->power_usage = cx->power;
index 60f71e6345e32ac11747d1dbd608349650172189..d73663a52324b89b93a7eb68f2fe0df9d21fbe26 100644 (file)
@@ -219,7 +219,8 @@ static void poll_idle_init(struct cpuidle_device *dev)
 
        cpuidle_set_statedata(state, NULL);
 
-       snprintf(state->name, CPUIDLE_NAME_LEN, "C0 (poll idle)");
+       snprintf(state->name, CPUIDLE_NAME_LEN, "C0");
+       snprintf(state->desc, CPUIDLE_DESC_LEN, "CPUIDLE CORE POLL IDLE");
        state->exit_latency = 0;
        state->target_residency = 0;
        state->power_usage = -1;
index 088ea74edd3480d42d883e7e7705e3a1f17af7fa..69102ca05685bdf9f7f48d0926edd160d3428074 100644 (file)
@@ -218,16 +218,23 @@ static ssize_t show_state_##_name(struct cpuidle_state *state, char *buf) \
        return sprintf(buf, "%u\n", state->_name);\
 }
 
-static ssize_t show_state_name(struct cpuidle_state *state, char *buf)
-{
-       return sprintf(buf, "%s\n", state->name);
+#define define_show_state_str_function(_name) \
+static ssize_t show_state_##_name(struct cpuidle_state *state, char *buf) \
+{ \
+       if (state->_name[0] == '\0')\
+               return sprintf(buf, "<null>\n");\
+       return sprintf(buf, "%s\n", state->_name);\
 }
 
 define_show_state_function(exit_latency)
 define_show_state_function(power_usage)
 define_show_state_function(usage)
 define_show_state_function(time)
+define_show_state_str_function(name)
+define_show_state_str_function(desc)
+
 define_one_state_ro(name, show_state_name);
+define_one_state_ro(desc, show_state_desc);
 define_one_state_ro(latency, show_state_exit_latency);
 define_one_state_ro(power, show_state_power_usage);
 define_one_state_ro(usage, show_state_usage);
@@ -235,6 +242,7 @@ define_one_state_ro(time, show_state_time);
 
 static struct attribute *cpuidle_state_default_attrs[] = {
        &attr_name.attr,
+       &attr_desc.attr,
        &attr_latency.attr,
        &attr_power.attr,
        &attr_usage.attr,
index cdc8004cfd12c73e7f0ffdc9ef2394779eefa536..06480bcabfdc0eb83bb99d8b56d17671a14b328a 100644 (file)
 #define DOMAIN_COORD_TYPE_SW_ANY       0xfd
 #define DOMAIN_COORD_TYPE_HW_ALL       0xfe
 
-#define ACPI_CSTATE_SYSTEMIO   (0)
-#define ACPI_CSTATE_FFH                (1)
-#define ACPI_CSTATE_HALT       (2)
+#define ACPI_CSTATE_SYSTEMIO   0
+#define ACPI_CSTATE_FFH                1
+#define ACPI_CSTATE_HALT       2
+
+#define ACPI_CX_DESC_LEN       32
 
 /* Power Management */
 
@@ -74,6 +76,7 @@ struct acpi_processor_cx {
        u64 time;
        struct acpi_processor_cx_policy promotion;
        struct acpi_processor_cx_policy demotion;
+       char desc[ACPI_CX_DESC_LEN];
 };
 
 struct acpi_processor_power {
index ddbe7efe590e96bdf25e8c1afa96038126f7a329..2c7e003356ac184f4d7848b44a98468df65e01ec 100644 (file)
@@ -203,6 +203,7 @@ extern bool wmi_has_guid(const char *guid);
 extern int acpi_blacklisted(void);
 #ifdef CONFIG_DMI
 extern void acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d);
+extern int acpi_osi_setup(char *str);
 #endif
 
 #ifdef CONFIG_ACPI_NUMA
index 385d45b616db2059e9aa71441b8e918ac11cac28..6b72a458408639becc0f60508d30406093329fe3 100644 (file)
@@ -19,6 +19,7 @@
 
 #define CPUIDLE_STATE_MAX      8
 #define CPUIDLE_NAME_LEN       16
+#define CPUIDLE_DESC_LEN       32
 
 struct cpuidle_device;
 
@@ -29,6 +30,7 @@ struct cpuidle_device;
 
 struct cpuidle_state {
        char            name[CPUIDLE_NAME_LEN];
+       char            desc[CPUIDLE_DESC_LEN];
        void            *driver_data;
 
        unsigned int    flags;