Skip to content

Commit

Permalink
Merge branches 'release', 'dmi', 'idle' and 'misc' into release
Browse files Browse the repository at this point in the history
  • Loading branch information
Len Brown committed Feb 14, 2008
3 parents 46c1fbd + fe8e288 + 6bf69b5 commit f60d63f
Show file tree
Hide file tree
Showing 16 changed files with 213 additions and 13 deletions.
2 changes: 2 additions & 0 deletions Documentation/00-INDEX
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
23 changes: 23 additions & 0 deletions Documentation/cpuidle/core.txt
Original file line number Diff line number Diff line change
@@ -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.
31 changes: 31 additions & 0 deletions Documentation/cpuidle/driver.txt
Original file line number Diff line number Diff line change
@@ -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);
29 changes: 29 additions & 0 deletions Documentation/cpuidle/governor.txt
Original file line number Diff line number Diff line change
@@ -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
79 changes: 79 additions & 0 deletions Documentation/cpuidle/sysfs.txt
Original file line number Diff line number Diff line change
@@ -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)
2 changes: 2 additions & 0 deletions arch/x86/kernel/acpi/cstate.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion drivers/acpi/event.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ static const struct file_operations acpi_system_event_ops = {
#endif /* CONFIG_ACPI_PROC_EVENT */

/* ACPI notifier chain */
BLOCKING_NOTIFIER_HEAD(acpi_chain_head);
static BLOCKING_NOTIFIER_HEAD(acpi_chain_head);

int acpi_notifier_call_chain(struct acpi_device *dev, u32 type, u32 data)
{
Expand Down
1 change: 1 addition & 0 deletions drivers/acpi/hardware/hwsleep.c
Original file line number Diff line number Diff line change
Expand Up @@ -616,6 +616,7 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state)
return_ACPI_STATUS(status);
}

arg.integer.value = sleep_state;
status = acpi_evaluate_object(NULL, METHOD_NAME__WAK, &arg_list, NULL);
if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
ACPI_EXCEPTION((AE_INFO, status, "During Method _WAK"));
Expand Down
4 changes: 2 additions & 2 deletions drivers/acpi/osl.c
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ acpi_os_predefined_override(const struct acpi_predefined_names *init_val,
}

#ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD
struct acpi_table_header *acpi_find_dsdt_initrd(void)
static struct acpi_table_header *acpi_find_dsdt_initrd(void)
{
struct file *firmware_file;
mm_segment_t oldfs;
Expand Down Expand Up @@ -419,7 +419,7 @@ acpi_os_table_override(struct acpi_table_header * existing_table,
}

#ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD
int __init acpi_no_initrd_override_setup(char *s)
static int __init acpi_no_initrd_override_setup(char *s)
{
acpi_no_initrd_override = 1;
return 1;
Expand Down
19 changes: 19 additions & 0 deletions drivers/acpi/processor_idle.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -1420,6 +1425,14 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev,
return 0;

local_irq_disable();

/* Do not access any ACPI IO ports in suspend path */
if (acpi_idle_suspend) {
acpi_safe_halt();
local_irq_enable();
return 0;
}

if (pr->flags.bm_check)
acpi_idle_update_bm_rld(pr, cx);

Expand Down Expand Up @@ -1643,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];
Expand All @@ -1659,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;
Expand Down
3 changes: 2 additions & 1 deletion drivers/cpuidle/cpuidle.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
14 changes: 11 additions & 3 deletions drivers/cpuidle/sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -218,23 +218,31 @@ 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);
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,
Expand Down
4 changes: 2 additions & 2 deletions drivers/misc/thinkpad_acpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -1689,7 +1689,7 @@ static ssize_t hotkey_wakeup_reason_show(struct device *dev,
static struct device_attribute dev_attr_hotkey_wakeup_reason =
__ATTR(wakeup_reason, S_IRUGO, hotkey_wakeup_reason_show, NULL);

void hotkey_wakeup_reason_notify_change(void)
static void hotkey_wakeup_reason_notify_change(void)
{
if (tp_features.hotkey_mask)
sysfs_notify(&tpacpi_pdev->dev.kobj, NULL,
Expand All @@ -1708,7 +1708,7 @@ static struct device_attribute dev_attr_hotkey_wakeup_hotunplug_complete =
__ATTR(wakeup_hotunplug_complete, S_IRUGO,
hotkey_wakeup_hotunplug_complete_show, NULL);

void hotkey_wakeup_hotunplug_complete_notify_change(void)
static void hotkey_wakeup_hotunplug_complete_notify_change(void)
{
if (tp_features.hotkey_mask)
sysfs_notify(&tpacpi_pdev->dev.kobj, NULL,
Expand Down
2 changes: 1 addition & 1 deletion drivers/pnp/pnpacpi/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ static int num = 0;
* have irqs (PIC, Timer) because we call acpi_register_gsi.
* Finally, only devices that have a CRS method need to be in this list.
*/
static struct __initdata acpi_device_id excluded_id_list[] = {
static struct acpi_device_id excluded_id_list[] __initdata = {
{"PNP0C09", 0}, /* EC */
{"PNP0C0F", 0}, /* Link device */
{"PNP0000", 0}, /* PIC */
Expand Down
9 changes: 6 additions & 3 deletions include/acpi/processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,11 @@
#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 */

Expand Down Expand Up @@ -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 {
Expand Down
2 changes: 2 additions & 0 deletions include/linux/cpuidle.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

#define CPUIDLE_STATE_MAX 8
#define CPUIDLE_NAME_LEN 16
#define CPUIDLE_DESC_LEN 32

struct cpuidle_device;

Expand All @@ -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;
Expand Down

0 comments on commit f60d63f

Please sign in to comment.