Hi Len, The following code would not compile on ARM. The patch for this has already been posted by Trinabh earlier on, in the following link. https://lkml.org/lkml/2011/4/25/54 On Thursday 04 August 2011 10:51 PM, Trinabh Gupta wrote: > > > On Wed, Aug 3, 2011 at 12:44 PM, Len Brown <lenb@xxxxxxxxxx <mailto:lenb@xxxxxxxxxx>> wrote: > > From: Len Brown <len.brown@xxxxxxxxx <mailto:len.brown@xxxxxxxxx>> > > cpuidle users should call cpuidle_call_idle() directly > rather than via (pm_idle)() function pointer. > > Architecture may choose to continue using (pm_idle)(), > but cpuidle need not depend on it: > > my_arch_cpu_idle() > ... > if(cpuidle_call_idle()) > pm_idle(); > > cc: x86@xxxxxxxxxx <mailto:x86@xxxxxxxxxx> > cc: Kevin Hilman <khilman@xxxxxxxxxxxxxxxxxxx <mailto:khilman@xxxxxxxxxxxxxxxxxxx>> > cc: Paul Mundt <lethal@xxxxxxxxxxxx <mailto:lethal@xxxxxxxxxxxx>> > Signed-off-by: Len Brown <len.brown@xxxxxxxxx <mailto:len.brown@xxxxxxxxx>> > --- > arch/arm/kernel/process.c | 4 +++- > arch/sh/kernel/idle.c | 6 ++++-- > arch/x86/kernel/process_32.c | 4 +++- > arch/x86/kernel/process_64.c | 4 +++- > drivers/cpuidle/cpuidle.c | 38 ++++++++++++++++++-------------------- > include/linux/cpuidle.h | 2 ++ > 6 files changed, 33 insertions(+), 25 deletions(-) > > diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c > index 5e1e541..d7ee0d4 100644 > --- a/arch/arm/kernel/process.c > +++ b/arch/arm/kernel/process.c > @@ -30,6 +30,7 @@ > #include <linux/uaccess.h> > #include <linux/random.h> > #include <linux/hw_breakpoint.h> > +#include <linux/cpuidle.h> > > #include <asm/cacheflush.h> > #include <asm/leds.h> > @@ -196,7 +197,8 @@ void cpu_idle(void) > cpu_relax(); > } else { > stop_critical_timings(); > - pm_idle(); > + if (cpuidle_call_idle()) > > > Hi Len, > > This should be cpuidle_idle_call() > > > + pm_idle(); > start_critical_timings(); > /* > * This will eventually be removed - pm_idle > diff --git a/arch/sh/kernel/idle.c b/arch/sh/kernel/idle.c > index 425d604..9c7099e 100644 > --- a/arch/sh/kernel/idle.c > +++ b/arch/sh/kernel/idle.c > @@ -16,12 +16,13 @@ > #include <linux/thread_info.h> > #include <linux/irqflags.h> > #include <linux/smp.h> > +#include <linux/cpuidle.h> > #include <asm/pgalloc.h> > #include <asm/system.h> > #include <asm/atomic.h> > #include <asm/smp.h> > > -void (*pm_idle)(void) = NULL; > +static void (*pm_idle)(void); > > static int hlt_counter; > > @@ -100,7 +101,8 @@ void cpu_idle(void) > local_irq_disable(); > /* Don't trace irqs off for idle */ > stop_critical_timings(); > - pm_idle(); > + if (cpuidle_call_idle()) > > > Again this should be cpuidle_idle_call() > > + pm_idle(); > /* > * Sanity check to ensure that pm_idle() returns > * with IRQs enabled > diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c > index a3d0dc5..7a3b651 100644 > --- a/arch/x86/kernel/process_32.c > +++ b/arch/x86/kernel/process_32.c > @@ -38,6 +38,7 @@ > #include <linux/uaccess.h> > #include <linux/io.h> > #include <linux/kdebug.h> > +#include <linux/cpuidle.h> > > #include <asm/pgtable.h> > #include <asm/system.h> > @@ -109,7 +110,8 @@ void cpu_idle(void) > local_irq_disable(); > /* Don't trace irqs off for idle */ > stop_critical_timings(); > - pm_idle(); > + if (cpuidle_idle_call()) > + pm_idle(); > start_critical_timings(); > } > tick_nohz_restart_sched_tick(); > diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c > index ca6f7ab..f693e44 100644 > --- a/arch/x86/kernel/process_64.c > +++ b/arch/x86/kernel/process_64.c > @@ -37,6 +37,7 @@ > #include <linux/uaccess.h> > #include <linux/io.h> > #include <linux/ftrace.h> > +#include <linux/cpuidle.h> > > #include <asm/pgtable.h> > #include <asm/system.h> > @@ -136,7 +137,8 @@ void cpu_idle(void) > enter_idle(); > /* Don't trace irqs off for idle */ > stop_critical_timings(); > - pm_idle(); > + if (cpuidle_idle_call()) > + pm_idle(); > start_critical_timings(); > > /* In many cases the interrupt that ended idle > diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c > index 041df0b..d4c5423 100644 > --- a/drivers/cpuidle/cpuidle.c > +++ b/drivers/cpuidle/cpuidle.c > @@ -25,10 +25,10 @@ DEFINE_PER_CPU(struct cpuidle_device *, cpuidle_devices); > > DEFINE_MUTEX(cpuidle_lock); > LIST_HEAD(cpuidle_detected_devices); > -static void (*pm_idle_old)(void); > > static int enabled_devices; > static int off __read_mostly; > +static int initialized __read_mostly; > > int cpuidle_disabled(void) > { > @@ -56,25 +56,23 @@ static int __cpuidle_register_device(struct cpuidle_device *dev); > * cpuidle_idle_call - the main idle loop > * > * NOTE: no locks or semaphores should be used here > + * return non-zero on failure > */ > -static void cpuidle_idle_call(void) > +int cpuidle_idle_call(void) > { > struct cpuidle_device *dev = __this_cpu_read(cpuidle_devices); > struct cpuidle_state *target_state; > int next_state; > > + if (off) > + return -ENODEV; > + > + if (!initialized) > + return -ENODEV; > + > /* check if the device is ready */ > - if (!dev || !dev->enabled) { > - if (pm_idle_old) > - pm_idle_old(); > - else > -#if defined(CONFIG_ARCH_HAS_DEFAULT_IDLE) > - default_idle(); > -#else > - local_irq_enable(); > -#endif > - return; > - } > + if (!dev || !dev->enabled) > + return -EBUSY; > > #if 0 > /* shows regressions, re-enable for 2.6.29 */ > @@ -99,7 +97,7 @@ static void cpuidle_idle_call(void) > next_state = cpuidle_curr_governor->select(dev); > if (need_resched()) { > local_irq_enable(); > - return; > + return 0; > } > > target_state = &dev->states[next_state]; > @@ -124,6 +122,8 @@ static void cpuidle_idle_call(void) > /* give the governor an opportunity to reflect on the outcome */ > if (cpuidle_curr_governor->reflect) > cpuidle_curr_governor->reflect(dev); > + > + return 0; > } > > /** > @@ -131,10 +131,10 @@ static void cpuidle_idle_call(void) > */ > void cpuidle_install_idle_handler(void) > { > - if (enabled_devices && (pm_idle != cpuidle_idle_call)) { > + if (enabled_devices) { > /* Make sure all changes finished before we switch to new idle */ > smp_wmb(); > - pm_idle = cpuidle_idle_call; > + initialized = 1; > } > } > > @@ -143,8 +143,8 @@ void cpuidle_install_idle_handler(void) > */ > void cpuidle_uninstall_idle_handler(void) > { > - if (enabled_devices && pm_idle_old && (pm_idle != pm_idle_old)) { > - pm_idle = pm_idle_old; > + if (enabled_devices) { > + initialized = 0; > cpuidle_kick_cpus(); > } > } > @@ -440,8 +440,6 @@ static int __init cpuidle_init(void) > if (cpuidle_disabled()) > return -ENODEV; > > - pm_idle_old = pm_idle; > - > ret = cpuidle_add_class_sysfs(&cpu_sysdev_class); > if (ret) > return ret; > diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h > index b89f67d..b51629e 100644 > --- a/include/linux/cpuidle.h > +++ b/include/linux/cpuidle.h > @@ -123,6 +123,7 @@ struct cpuidle_driver { > > #ifdef CONFIG_CPU_IDLE > extern void disable_cpuidle(void); > +extern int cpuidle_idle_call(void); > > extern int cpuidle_register_driver(struct cpuidle_driver *drv); > struct cpuidle_driver *cpuidle_get_driver(void); > @@ -137,6 +138,7 @@ extern void cpuidle_disable_device(struct cpuidle_device *dev); > > #else > static inline void disable_cpuidle(void) { } > +static inline int cpuidle_idle_call(void) { return -ENODEV; } > > static inline int cpuidle_register_driver(struct cpuidle_driver *drv) > {return -ENODEV; } > -- > 1.7.6.396.ge0613 > > _______________________________________________ > linux-pm mailing list > linux-pm@xxxxxxxxxxxxxxxxxxxxxxxxxx <mailto:linux-pm@xxxxxxxxxxxxxxxxxxxxxxxxxx> > https://lists.linux-foundation.org/mailman/listinfo/linux-pm > > > > > _______________________________________________ > linux-pm mailing list > linux-pm@xxxxxxxxxxxxxxxxxxxxxxxxxx > https://lists.linux-foundation.org/mailman/listinfo/linux-pm Regards, Deepthi _______________________________________________ linux-pm mailing list linux-pm@xxxxxxxxxxxxxxxxxxxxxxxxxx https://lists.linux-foundation.org/mailman/listinfo/linux-pm