diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index 4217925..813db8a 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c @@ -494,6 +494,8 @@ static int acpi_processor_get_info(struc pr->id = cpu_index; + pr->cpu_sysdev = get_cpu_sysdev(cpu_index); + /* * Extra Processor objects may be enumerated on MP systems with * less than the max # of CPUs. They should be ignored _iff diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 573b6a9..85ae303 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -38,6 +38,7 @@ #include #include #include /* need_resched() */ +#include #include #include @@ -976,6 +977,238 @@ static int acpi_processor_power_seq_show return_VALUE(0); } + +static ssize_t show_active_state(struct sys_device * sd, char * buf) +{ + struct acpi_processor *pr = processors[sd->id]; + return sprintf(buf, "%d\n", pr->power.state ? + pr->power.state - pr->power.states : 0); +} + +SYSDEV_ATTR(active_state, S_IRUGO, show_active_state, NULL); + + +static ssize_t show_max_cstate(struct sys_device * sd, char * buf) +{ + return sprintf(buf, "%d\n", max_cstate); +} + +SYSDEV_ATTR(max_cstate, S_IRUGO, show_max_cstate, NULL); + + +static ssize_t show_bm_activity(struct sys_device * sd, char * buf) +{ + struct acpi_processor *pr = processors[sd->id]; + return sprintf(buf, "%d\n", pr->power.bm_activity); +} + +SYSDEV_ATTR(bm_activity, S_IRUGO, show_bm_activity, NULL); + + +static struct attribute *cpu_attr_common[] = { + &attr_active_state.attr, + &attr_max_cstate.attr, + &attr_bm_activity.attr, + NULL, +}; + +static struct attribute_group cpu_attr_common_group = { + .name = "acpi/pm", + .attrs = cpu_attr_common, +}; + + + +static ssize_t show_c1_promotion(struct sys_device * sd, char * buf) +{ + struct acpi_processor * pr = processors[sd->id]; + ssize_t ret; + + if (pr->power.states[ACPI_STATE_C1].promotion.state) + ret = sprintf(buf, "C%zd\n", + pr->power.states[ACPI_STATE_C1].promotion.state - + pr->power.states); + else + ret = sprintf(buf, "--\n"); + + return ret; +} +SYSDEV_ATTR(c1_promotion, S_IRUGO, show_c1_promotion, NULL); + +static ssize_t show_c1_demotion(struct sys_device * sd, char * buf) +{ + struct acpi_processor * pr = processors[sd->id]; + ssize_t ret; + + if (pr->power.states[ACPI_STATE_C1].demotion.state) + ret = sprintf(buf, "C%zd\n", + pr->power.states[ACPI_STATE_C1].demotion.state - + pr->power.states); + else + ret = sprintf(buf, "--\n"); + + return ret; +} +SYSDEV_ATTR(c1_demotion, S_IRUGO, show_c1_demotion, NULL); + +static ssize_t show_c1_latency(struct sys_device * sd, char * buf) +{ + struct acpi_processor * pr = processors[sd->id]; + + return sprintf(buf, "%03d\n", pr->power.states[ACPI_STATE_C1].latency); +} +SYSDEV_ATTR(c1_latency, S_IRUGO, show_c1_latency, NULL); + +static ssize_t show_c1_usage(struct sys_device * sd, char * buf) +{ + struct acpi_processor * pr = processors[sd->id]; + + return sprintf(buf, "%08d\n", pr->power.states[ACPI_STATE_C1].usage); +} +SYSDEV_ATTR(c1_usage, S_IRUGO, show_c1_usage, NULL); + +static struct attribute * cpu_attr_c1[] = { + &attr_c1_promotion.attr, + &attr_c1_demotion.attr, + &attr_c1_latency.attr, + &attr_c1_usage.attr, + NULL, +}; + + + +static ssize_t show_c2_promotion(struct sys_device * sd, char * buf) +{ + struct acpi_processor * pr = processors[sd->id]; + ssize_t ret; + + if (pr->power.states[ACPI_STATE_C2].promotion.state) + ret = sprintf(buf, "C%zd\n", + pr->power.states[ACPI_STATE_C2].promotion.state - + pr->power.states); + else + ret = sprintf(buf, "--\n"); + + return ret; +} +SYSDEV_ATTR(c2_promotion, S_IRUGO, show_c2_promotion, NULL); + +static ssize_t show_c2_demotion(struct sys_device * sd, char * buf) +{ + struct acpi_processor * pr = processors[sd->id]; + ssize_t ret; + + if (pr->power.states[ACPI_STATE_C2].demotion.state) + ret = sprintf(buf, "C%zd\n", + pr->power.states[ACPI_STATE_C2].demotion.state - + pr->power.states); + else + ret = sprintf(buf, "--\n"); + + return ret; +} +SYSDEV_ATTR(c2_demotion, S_IRUGO, show_c2_demotion, NULL); + +static ssize_t show_c2_latency(struct sys_device * sd, char * buf) +{ + struct acpi_processor * pr = processors[sd->id]; + + return sprintf(buf, "%03d\n", pr->power.states[ACPI_STATE_C2].latency); +} +SYSDEV_ATTR(c2_latency, S_IRUGO, show_c2_latency, NULL); + +static ssize_t show_c2_usage(struct sys_device * sd, char * buf) +{ + struct acpi_processor * pr = processors[sd->id]; + + return sprintf(buf, "%08d\n", pr->power.states[ACPI_STATE_C2].usage); +} +SYSDEV_ATTR(c2_usage, S_IRUGO, show_c2_usage, NULL); + +static struct attribute * cpu_attr_c2[] = { + &attr_c2_promotion.attr, + &attr_c2_demotion.attr, + &attr_c2_latency.attr, + &attr_c2_usage.attr, + NULL, +}; + + + +static ssize_t show_c3_promotion(struct sys_device * sd, char * buf) +{ + struct acpi_processor * pr = processors[sd->id]; + ssize_t ret; + + if (pr->power.states[ACPI_STATE_C3].promotion.state) + ret = sprintf(buf, "C%zd\n", + pr->power.states[ACPI_STATE_C3].promotion.state - + pr->power.states); + else + ret = sprintf(buf, "--\n"); + + return ret; +} +SYSDEV_ATTR(c3_promotion, S_IRUGO, show_c3_promotion, NULL); + +static ssize_t show_c3_demotion(struct sys_device * sd, char * buf) +{ + struct acpi_processor * pr = processors[sd->id]; + ssize_t ret; + + if (pr->power.states[ACPI_STATE_C3].demotion.state) + ret = sprintf(buf, "C%zd\n", + pr->power.states[ACPI_STATE_C3].demotion.state - + pr->power.states); + else + ret = sprintf(buf, "--\n"); + + return ret; +} +SYSDEV_ATTR(c3_demotion, S_IRUGO, show_c3_demotion, NULL); + +static ssize_t show_c3_latency(struct sys_device * sd, char * buf) +{ + struct acpi_processor * pr = processors[sd->id]; + + return sprintf(buf, "%03d\n", pr->power.states[ACPI_STATE_C3].latency); +} +SYSDEV_ATTR(c3_latency, S_IRUGO, show_c3_latency, NULL); + +static ssize_t show_c3_usage(struct sys_device * sd, char * buf) +{ + struct acpi_processor * pr = processors[sd->id]; + + return sprintf(buf, "%08d\n", pr->power.states[ACPI_STATE_C3].usage); +} +SYSDEV_ATTR(c3_usage, S_IRUGO, show_c3_usage, NULL); + +static struct attribute * cpu_attr_c3[] = { + &attr_c3_promotion.attr, + &attr_c3_demotion.attr, + &attr_c3_latency.attr, + &attr_c3_usage.attr, + NULL, +}; + + + +static struct attribute_group cpu_state_groups[] = { + { + .name = "acpi/pm/c1", + .attrs = cpu_attr_c1, + }, + { + .name = "acpi/pm/c2", + .attrs = cpu_attr_c2, + }, + { + .name = "acpi/pm/c3", + .attrs = cpu_attr_c3, + }, +}; + + static int acpi_processor_power_open_fs(struct inode *inode, struct file *file) { return single_open(file, acpi_processor_power_seq_show, @@ -1056,6 +1289,14 @@ int acpi_processor_power_init(struct acp entry->owner = THIS_MODULE; } + sysfs_create_group(&pr->cpu_sysdev->kobj, &cpu_attr_common_group); + + printk("ACPI CPU PM CPU %d: %d C States\n", pr->id, pr->power.count); + + sysfs_create_group(&pr->cpu_sysdev->kobj, &cpu_state_groups[0]); + sysfs_create_group(&pr->cpu_sysdev->kobj, &cpu_state_groups[1]); + sysfs_create_group(&pr->cpu_sysdev->kobj, &cpu_state_groups[2]); + pr->flags.power_setup_done = 1; return_VALUE(0); diff --git a/include/acpi/processor.h b/include/acpi/processor.h index 7a00d50..7843169 100644 --- a/include/acpi/processor.h +++ b/include/acpi/processor.h @@ -151,6 +151,7 @@ struct acpi_processor { struct acpi_processor_performance *performance; struct acpi_processor_throttling throttling; struct acpi_processor_limit limit; + struct sys_device * cpu_sysdev; }; struct acpi_processor_errata {