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>
This commit is contained in:
parent
4202735e8a
commit
46bcfad7a8
16 changed files with 438 additions and 206 deletions
|
@ -22,6 +22,7 @@
|
|||
#define CPUIDLE_DESC_LEN 32
|
||||
|
||||
struct cpuidle_device;
|
||||
struct cpuidle_driver;
|
||||
|
||||
|
||||
/****************************
|
||||
|
@ -45,6 +46,7 @@ struct cpuidle_state {
|
|||
unsigned int target_residency; /* in US */
|
||||
|
||||
int (*enter) (struct cpuidle_device *dev,
|
||||
struct cpuidle_driver *drv,
|
||||
int index);
|
||||
};
|
||||
|
||||
|
@ -83,12 +85,10 @@ struct cpuidle_state_kobj {
|
|||
struct cpuidle_device {
|
||||
unsigned int registered:1;
|
||||
unsigned int enabled:1;
|
||||
unsigned int power_specified:1;
|
||||
unsigned int cpu;
|
||||
|
||||
int last_residency;
|
||||
int state_count;
|
||||
struct cpuidle_state states[CPUIDLE_STATE_MAX];
|
||||
struct cpuidle_state_usage states_usage[CPUIDLE_STATE_MAX];
|
||||
struct cpuidle_state_kobj *kobjs[CPUIDLE_STATE_MAX];
|
||||
|
||||
|
@ -96,7 +96,6 @@ struct cpuidle_device {
|
|||
struct kobject kobj;
|
||||
struct completion kobj_unregister;
|
||||
void *governor_data;
|
||||
int safe_state_index;
|
||||
};
|
||||
|
||||
DECLARE_PER_CPU(struct cpuidle_device *, cpuidle_devices);
|
||||
|
@ -120,6 +119,11 @@ static inline int cpuidle_get_last_residency(struct cpuidle_device *dev)
|
|||
struct cpuidle_driver {
|
||||
char name[CPUIDLE_NAME_LEN];
|
||||
struct module *owner;
|
||||
|
||||
unsigned int power_specified:1;
|
||||
struct cpuidle_state states[CPUIDLE_STATE_MAX];
|
||||
int state_count;
|
||||
int safe_state_index;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_CPU_IDLE
|
||||
|
@ -166,10 +170,13 @@ struct cpuidle_governor {
|
|||
struct list_head governor_list;
|
||||
unsigned int rating;
|
||||
|
||||
int (*enable) (struct cpuidle_device *dev);
|
||||
void (*disable) (struct cpuidle_device *dev);
|
||||
int (*enable) (struct cpuidle_driver *drv,
|
||||
struct cpuidle_device *dev);
|
||||
void (*disable) (struct cpuidle_driver *drv,
|
||||
struct cpuidle_device *dev);
|
||||
|
||||
int (*select) (struct cpuidle_device *dev);
|
||||
int (*select) (struct cpuidle_driver *drv,
|
||||
struct cpuidle_device *dev);
|
||||
void (*reflect) (struct cpuidle_device *dev, int index);
|
||||
|
||||
struct module *owner;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue