On 04/03/2012 12:50 AM, Daniel Lezcano wrote: > The usual cpuidle initialization routines register the driver and > then register a cpuidle device per cpu. > > By default, most drivers initialize the device state count with the > driver state count. > > We can then add a new function 'cpuidle_register' where we register > the driver and the devices. These devices can be defined in a global > static variable in cpuidle.c. We will be able to factor out and > remove a lot of duplicate lines of code. > > As we still have some drivers, with different initialization routines, > we keep 'cpuidle_register_driver' and 'cpuidle_register_device' as low > level initialization routines to do some specific operations on the > cpuidle devices. > > Signed-off-by: Daniel Lezcano <daniel.lezcano@xxxxxxxxxx> Looks good to me now. Acked-by: Srivatsa S. Bhat <srivatsa.bhat@xxxxxxxxxxxxxxxxxx> Regards, Srivatsa S. Bhat > --- > drivers/cpuidle/cpuidle.c | 42 ++++++++++++++++++++++++++++++++++++++++++ > include/linux/cpuidle.h | 3 +++ > 2 files changed, 45 insertions(+), 0 deletions(-) > > diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c > index 87411ce..4d1f79b 100644 > --- a/drivers/cpuidle/cpuidle.c > +++ b/drivers/cpuidle/cpuidle.c > @@ -23,6 +23,7 @@ > #include "cpuidle.h" > > DEFINE_PER_CPU(struct cpuidle_device *, cpuidle_devices); > +DEFINE_PER_CPU(struct cpuidle_device, cpuidle_device); > > DEFINE_MUTEX(cpuidle_lock); > LIST_HEAD(cpuidle_detected_devices); > @@ -419,6 +420,47 @@ int cpuidle_register_device(struct cpuidle_device *dev) > > EXPORT_SYMBOL_GPL(cpuidle_register_device); > > +/* > + * cpuidle_register : register cpuidle driver and devices > + * Note this function must be called after smp_init. > + * @drv : the cpuidle driver > + * Returns 0 on success, < 0 otherwise > + */ > +int cpuidle_register(struct cpuidle_driver *drv) > +{ > + int ret, cpu, i; > + struct cpuidle_device *dev; > + > + ret = cpuidle_register_driver(drv); > + if (ret) > + return ret; > + > + for_each_online_cpu(cpu) { > + dev = &per_cpu(cpuidle_device, cpu); > + dev->cpu = cpu; > + > + ret = cpuidle_register_device(dev); > + if (ret) > + goto out_unregister; > + } > + > +out: > + return ret; > + > +out_unregister: > + for_each_online_cpu(i) { > + if (i == cpu) > + break; > + dev = &per_cpu(cpuidle_device, i); > + cpuidle_unregister_device(dev); > + } > + > + cpuidle_unregister_driver(drv); > + > + goto out; > +} > +EXPORT_SYMBOL_GPL(cpuidle_register); > + > /** > * cpuidle_unregister_device - unregisters a CPU's idle PM feature > * @dev: the cpu > diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h > index 6c26a3d..3475294 100644 > --- a/include/linux/cpuidle.h > +++ b/include/linux/cpuidle.h > @@ -135,6 +135,7 @@ struct cpuidle_driver { > #ifdef CONFIG_CPU_IDLE > extern void disable_cpuidle(void); > extern int cpuidle_idle_call(void); > +extern int cpuidle_register(struct cpuidle_driver *drv); > extern int cpuidle_register_driver(struct cpuidle_driver *drv); > struct cpuidle_driver *cpuidle_get_driver(void); > extern void cpuidle_unregister_driver(struct cpuidle_driver *drv); > @@ -154,6 +155,8 @@ extern int cpuidle_play_dead(void); > #else > static inline void disable_cpuidle(void) { } > static inline int cpuidle_idle_call(void) { return -ENODEV; } > +static inline int cpuidle_register(struct cpuidle_driver *drv) > +{return -ENODEV; } > static inline int cpuidle_register_driver(struct cpuidle_driver *drv) > {return -ENODEV; } > static inline struct cpuidle_driver *cpuidle_get_driver(void) {return NULL; } _______________________________________________ linux-pm mailing list linux-pm@xxxxxxxxxxxxxxxxxxxxxxxxxx https://lists.linuxfoundation.org/mailman/listinfo/linux-pm