ACPI, cpuidle: Clarify C-state description in sysfs

Add a new sysfs entry under cpuidle states. desc - can be used by driver to
communicate to userspace any specific information about the state.
This helps in identifying the exact hardware C-states behind the ACPI C-state
definition.

Idea is to export this through powertop, which will help to map the C-state
reported by powertop to actual hardware C-state.

Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>

authored by Venkatesh Pallipadi and committed by Len Brown 4fcb2fcd e760e716

+34 -7
+2
arch/x86/kernel/acpi/cstate.c
··· 126 printk(KERN_DEBUG "Monitor-Mwait will be used to enter C-%d " 127 "state\n", cx->type); 128 } 129 130 out: 131 set_cpus_allowed(current, saved_mask);
··· 126 printk(KERN_DEBUG "Monitor-Mwait will be used to enter C-%d " 127 "state\n", cx->type); 128 } 129 + snprintf(cx->desc, ACPI_CX_DESC_LEN, "ACPI FFH INTEL MWAIT 0x%x", 130 + cx->address); 131 132 out: 133 set_cpus_allowed(current, saved_mask);
+11
drivers/acpi/processor_idle.c
··· 945 * Otherwise, ignore this info and continue. 946 */ 947 cx.entry_method = ACPI_CSTATE_HALT; 948 } else { 949 continue; 950 } 951 } 952 953 obj = &(element->package.elements[2]); 954 if (obj->type != ACPI_TYPE_INTEGER) ··· 1648 return -EINVAL; 1649 } 1650 1651 for (i = 1; i < ACPI_PROCESSOR_MAX_POWER && i <= max_cstate; i++) { 1652 cx = &pr->power.states[i]; 1653 state = &dev->states[count]; ··· 1669 cpuidle_set_statedata(state, cx); 1670 1671 snprintf(state->name, CPUIDLE_NAME_LEN, "C%d", i); 1672 state->exit_latency = cx->latency; 1673 state->target_residency = cx->latency * latency_factor; 1674 state->power_usage = cx->power;
··· 945 * Otherwise, ignore this info and continue. 946 */ 947 cx.entry_method = ACPI_CSTATE_HALT; 948 + snprintf(cx.desc, ACPI_CX_DESC_LEN, "ACPI HLT"); 949 } else { 950 continue; 951 } 952 + } else { 953 + snprintf(cx.desc, ACPI_CX_DESC_LEN, "ACPI IOPORT 0x%x", 954 + cx.address); 955 } 956 + 957 958 obj = &(element->package.elements[2]); 959 if (obj->type != ACPI_TYPE_INTEGER) ··· 1643 return -EINVAL; 1644 } 1645 1646 + for (i = 0; i < CPUIDLE_STATE_MAX; i++) { 1647 + dev->states[i].name[0] = '\0'; 1648 + dev->states[i].desc[0] = '\0'; 1649 + } 1650 + 1651 for (i = 1; i < ACPI_PROCESSOR_MAX_POWER && i <= max_cstate; i++) { 1652 cx = &pr->power.states[i]; 1653 state = &dev->states[count]; ··· 1659 cpuidle_set_statedata(state, cx); 1660 1661 snprintf(state->name, CPUIDLE_NAME_LEN, "C%d", i); 1662 + strncpy(state->desc, cx->desc, CPUIDLE_DESC_LEN); 1663 state->exit_latency = cx->latency; 1664 state->target_residency = cx->latency * latency_factor; 1665 state->power_usage = cx->power;
+2 -1
drivers/cpuidle/cpuidle.c
··· 219 220 cpuidle_set_statedata(state, NULL); 221 222 - snprintf(state->name, CPUIDLE_NAME_LEN, "C0 (poll idle)"); 223 state->exit_latency = 0; 224 state->target_residency = 0; 225 state->power_usage = -1;
··· 219 220 cpuidle_set_statedata(state, NULL); 221 222 + snprintf(state->name, CPUIDLE_NAME_LEN, "C0"); 223 + snprintf(state->desc, CPUIDLE_DESC_LEN, "CPUIDLE CORE POLL IDLE"); 224 state->exit_latency = 0; 225 state->target_residency = 0; 226 state->power_usage = -1;
+11 -3
drivers/cpuidle/sysfs.c
··· 218 return sprintf(buf, "%u\n", state->_name);\ 219 } 220 221 - static ssize_t show_state_name(struct cpuidle_state *state, char *buf) 222 - { 223 - return sprintf(buf, "%s\n", state->name); 224 } 225 226 define_show_state_function(exit_latency) 227 define_show_state_function(power_usage) 228 define_show_state_function(usage) 229 define_show_state_function(time) 230 define_one_state_ro(name, show_state_name); 231 define_one_state_ro(latency, show_state_exit_latency); 232 define_one_state_ro(power, show_state_power_usage); 233 define_one_state_ro(usage, show_state_usage); ··· 242 243 static struct attribute *cpuidle_state_default_attrs[] = { 244 &attr_name.attr, 245 &attr_latency.attr, 246 &attr_power.attr, 247 &attr_usage.attr,
··· 218 return sprintf(buf, "%u\n", state->_name);\ 219 } 220 221 + #define define_show_state_str_function(_name) \ 222 + static ssize_t show_state_##_name(struct cpuidle_state *state, char *buf) \ 223 + { \ 224 + if (state->_name[0] == '\0')\ 225 + return sprintf(buf, "<null>\n");\ 226 + return sprintf(buf, "%s\n", state->_name);\ 227 } 228 229 define_show_state_function(exit_latency) 230 define_show_state_function(power_usage) 231 define_show_state_function(usage) 232 define_show_state_function(time) 233 + define_show_state_str_function(name) 234 + define_show_state_str_function(desc) 235 + 236 define_one_state_ro(name, show_state_name); 237 + define_one_state_ro(desc, show_state_desc); 238 define_one_state_ro(latency, show_state_exit_latency); 239 define_one_state_ro(power, show_state_power_usage); 240 define_one_state_ro(usage, show_state_usage); ··· 235 236 static struct attribute *cpuidle_state_default_attrs[] = { 237 &attr_name.attr, 238 + &attr_desc.attr, 239 &attr_latency.attr, 240 &attr_power.attr, 241 &attr_usage.attr,
+6 -3
include/acpi/processor.h
··· 32 #define DOMAIN_COORD_TYPE_SW_ANY 0xfd 33 #define DOMAIN_COORD_TYPE_HW_ALL 0xfe 34 35 - #define ACPI_CSTATE_SYSTEMIO (0) 36 - #define ACPI_CSTATE_FFH (1) 37 - #define ACPI_CSTATE_HALT (2) 38 39 /* Power Management */ 40 ··· 76 u64 time; 77 struct acpi_processor_cx_policy promotion; 78 struct acpi_processor_cx_policy demotion; 79 }; 80 81 struct acpi_processor_power {
··· 32 #define DOMAIN_COORD_TYPE_SW_ANY 0xfd 33 #define DOMAIN_COORD_TYPE_HW_ALL 0xfe 34 35 + #define ACPI_CSTATE_SYSTEMIO 0 36 + #define ACPI_CSTATE_FFH 1 37 + #define ACPI_CSTATE_HALT 2 38 + 39 + #define ACPI_CX_DESC_LEN 32 40 41 /* Power Management */ 42 ··· 74 u64 time; 75 struct acpi_processor_cx_policy promotion; 76 struct acpi_processor_cx_policy demotion; 77 + char desc[ACPI_CX_DESC_LEN]; 78 }; 79 80 struct acpi_processor_power {
+2
include/linux/cpuidle.h
··· 19 20 #define CPUIDLE_STATE_MAX 8 21 #define CPUIDLE_NAME_LEN 16 22 23 struct cpuidle_device; 24 ··· 30 31 struct cpuidle_state { 32 char name[CPUIDLE_NAME_LEN]; 33 void *driver_data; 34 35 unsigned int flags;
··· 19 20 #define CPUIDLE_STATE_MAX 8 21 #define CPUIDLE_NAME_LEN 16 22 + #define CPUIDLE_DESC_LEN 32 23 24 struct cpuidle_device; 25 ··· 29 30 struct cpuidle_state { 31 char name[CPUIDLE_NAME_LEN]; 32 + char desc[CPUIDLE_DESC_LEN]; 33 void *driver_data; 34 35 unsigned int flags;