aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorDeepthi Dharwar <deepthi@linux.vnet.ibm.com>2011-10-28 06:50:42 -0400
committerLen Brown <len.brown@intel.com>2011-11-06 21:13:58 -0500
commit46bcfad7a819bd17ac4e831b04405152d59784ab (patch)
tree20041e788154d103edff2699f88d4a30320e3ee2 /include
parent4202735e8ab6ecfb0381631a0d0b58fefe0bd4e2 (diff)
cpuidle: Single/Global registration of idle states
This patch makes the cpuidle_states structure global (single copy) instead of per-cpu. The statistics needed on per-cpu basis by the governor are kept per-cpu. This simplifies the cpuidle subsystem as state registration is done by single cpu only. Having single copy of cpuidle_states saves memory. Rare case of asymmetric C-states can be handled within the cpuidle driver and architectures such as POWER do not have asymmetric C-states. Having single/global registration of all the idle states, dynamic C-state transitions on x86 are handled by the boot cpu. Here, the boot cpu would disable all the devices, re-populate the states and later enable all the devices, irrespective of the cpu that would receive the notification first. Reference: https://lkml.org/lkml/2011/4/25/83 Signed-off-by: Deepthi Dharwar <deepthi@linux.vnet.ibm.com> Signed-off-by: Trinabh Gupta <g.trinabh@gmail.com> Tested-by: Jean Pihet <j-pihet@ti.com> Reviewed-by: Kevin Hilman <khilman@ti.com> Acked-by: Arjan van de Ven <arjan@linux.intel.com> Acked-by: Kevin Hilman <khilman@ti.com> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'include')
-rw-r--r--include/acpi/processor.h1
-rw-r--r--include/linux/cpuidle.h19
2 files changed, 14 insertions, 6 deletions
diff --git a/include/acpi/processor.h b/include/acpi/processor.h
index 67055f180330..610f6fb1bbc2 100644
--- a/include/acpi/processor.h
+++ b/include/acpi/processor.h
@@ -329,6 +329,7 @@ extern void acpi_processor_throttling_init(void);
329int acpi_processor_power_init(struct acpi_processor *pr, 329int acpi_processor_power_init(struct acpi_processor *pr,
330 struct acpi_device *device); 330 struct acpi_device *device);
331int acpi_processor_cst_has_changed(struct acpi_processor *pr); 331int acpi_processor_cst_has_changed(struct acpi_processor *pr);
332int acpi_processor_hotplug(struct acpi_processor *pr);
332int acpi_processor_power_exit(struct acpi_processor *pr, 333int acpi_processor_power_exit(struct acpi_processor *pr,
333 struct acpi_device *device); 334 struct acpi_device *device);
334int acpi_processor_suspend(struct acpi_device * device, pm_message_t state); 335int acpi_processor_suspend(struct acpi_device * device, pm_message_t state);
diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h
index 0156540b3f79..c90418822f40 100644
--- a/include/linux/cpuidle.h
+++ b/include/linux/cpuidle.h
@@ -22,6 +22,7 @@
22#define CPUIDLE_DESC_LEN 32 22#define CPUIDLE_DESC_LEN 32
23 23
24struct cpuidle_device; 24struct cpuidle_device;
25struct cpuidle_driver;
25 26
26 27
27/**************************** 28/****************************
@@ -45,6 +46,7 @@ struct cpuidle_state {
45 unsigned int target_residency; /* in US */ 46 unsigned int target_residency; /* in US */
46 47
47 int (*enter) (struct cpuidle_device *dev, 48 int (*enter) (struct cpuidle_device *dev,
49 struct cpuidle_driver *drv,
48 int index); 50 int index);
49}; 51};
50 52
@@ -83,12 +85,10 @@ struct cpuidle_state_kobj {
83struct cpuidle_device { 85struct cpuidle_device {
84 unsigned int registered:1; 86 unsigned int registered:1;
85 unsigned int enabled:1; 87 unsigned int enabled:1;
86 unsigned int power_specified:1;
87 unsigned int cpu; 88 unsigned int cpu;
88 89
89 int last_residency; 90 int last_residency;
90 int state_count; 91 int state_count;
91 struct cpuidle_state states[CPUIDLE_STATE_MAX];
92 struct cpuidle_state_usage states_usage[CPUIDLE_STATE_MAX]; 92 struct cpuidle_state_usage states_usage[CPUIDLE_STATE_MAX];
93 struct cpuidle_state_kobj *kobjs[CPUIDLE_STATE_MAX]; 93 struct cpuidle_state_kobj *kobjs[CPUIDLE_STATE_MAX];
94 94
@@ -96,7 +96,6 @@ struct cpuidle_device {
96 struct kobject kobj; 96 struct kobject kobj;
97 struct completion kobj_unregister; 97 struct completion kobj_unregister;
98 void *governor_data; 98 void *governor_data;
99 int safe_state_index;
100}; 99};
101 100
102DECLARE_PER_CPU(struct cpuidle_device *, cpuidle_devices); 101DECLARE_PER_CPU(struct cpuidle_device *, cpuidle_devices);
@@ -120,6 +119,11 @@ static inline int cpuidle_get_last_residency(struct cpuidle_device *dev)
120struct cpuidle_driver { 119struct cpuidle_driver {
121 char name[CPUIDLE_NAME_LEN]; 120 char name[CPUIDLE_NAME_LEN];
122 struct module *owner; 121 struct module *owner;
122
123 unsigned int power_specified:1;
124 struct cpuidle_state states[CPUIDLE_STATE_MAX];
125 int state_count;
126 int safe_state_index;
123}; 127};
124 128
125#ifdef CONFIG_CPU_IDLE 129#ifdef CONFIG_CPU_IDLE
@@ -166,10 +170,13 @@ struct cpuidle_governor {
166 struct list_head governor_list; 170 struct list_head governor_list;
167 unsigned int rating; 171 unsigned int rating;
168 172
169 int (*enable) (struct cpuidle_device *dev); 173 int (*enable) (struct cpuidle_driver *drv,
170 void (*disable) (struct cpuidle_device *dev); 174 struct cpuidle_device *dev);
175 void (*disable) (struct cpuidle_driver *drv,
176 struct cpuidle_device *dev);
171 177
172 int (*select) (struct cpuidle_device *dev); 178 int (*select) (struct cpuidle_driver *drv,
179 struct cpuidle_device *dev);
173 void (*reflect) (struct cpuidle_device *dev, int index); 180 void (*reflect) (struct cpuidle_device *dev, int index);
174 181
175 struct module *owner; 182 struct module *owner;