8 #include <linux/kernel.h>
9 #include <linux/module.h>
18 #include <asm/machdep.h>
26 .name =
"pseries_idle",
30 #define MAX_IDLE_STATE_COUNT 2
36 static inline void idle_loop_prolog(
unsigned long *in_purr,
ktime_t *kt_before)
40 *in_purr =
mfspr(SPRN_PURR);
45 get_lppaca()->idle = 1;
48 static inline s64 idle_loop_epilog(
unsigned long in_purr,
ktime_t kt_before)
50 get_lppaca()->wait_state_cycles +=
mfspr(SPRN_PURR) - in_purr;
51 get_lppaca()->idle = 0;
60 unsigned long in_purr;
64 idle_loop_prolog(&in_purr, &kt_before);
66 set_thread_flag(TIF_POLLING_NRFLAG);
75 clear_thread_flag(TIF_POLLING_NRFLAG);
79 (
int)idle_loop_epilog(in_purr, kt_before);
83 static void check_and_cede_processor(
void)
90 if (prep_irq_for_idle()) {
92 #ifdef CONFIG_TRACE_IRQFLAGS
104 unsigned long in_purr;
107 idle_loop_prolog(&in_purr, &kt_before);
108 get_lppaca()->donate_dedicated_cpu = 1;
112 check_and_cede_processor();
114 get_lppaca()->donate_dedicated_cpu = 0;
116 (
int)idle_loop_epilog(in_purr, kt_before);
124 unsigned long in_purr;
127 idle_loop_prolog(&in_purr, &kt_before);
136 check_and_cede_processor();
139 (
int)idle_loop_epilog(in_purr, kt_before);
152 .target_residency = 0,
153 .enter = &snooze_loop },
159 .target_residency = 100,
160 .enter = &dedicated_cede_loop },
168 .name =
"Shared Cede",
169 .desc =
"Shared Cede",
172 .target_residency = 0,
173 .enter = &shared_cede_loop },
181 if (cpuidle_state_table != dedicated_states)
190 drv->
states[1].target_residency = residency;
194 unsigned long action,
void *hcpu)
196 int hotcpu = (
unsigned long)hcpu;
224 .notifier_call = pseries_cpuidle_add_cpu_notifier,
230 static int pseries_cpuidle_driver_init(
void)
239 if (idle_state > max_idle_state)
243 if (cpuidle_state_table[idle_state].
enter ==
NULL)
247 cpuidle_state_table[idle_state];
258 static void pseries_idle_devices_uninit(
void)
275 static int pseries_idle_devices_init(
void)
282 if (pseries_cpuidle_devices ==
NULL)
291 "cpuidle_register_device %d failed!\n", i);
303 static int pseries_idle_probe(
void)
306 if (!firmware_has_feature(FW_FEATURE_SPLPAR))
312 if (max_idle_state == 0) {
317 if (get_lppaca()->shared_proc)
318 cpuidle_state_table = shared_states;
320 cpuidle_state_table = dedicated_states;
325 static int __init pseries_processor_idle_init(
void)
329 retval = pseries_idle_probe();
333 pseries_cpuidle_driver_init();
340 retval = pseries_idle_devices_init();
342 pseries_idle_devices_uninit();
347 register_cpu_notifier(&setup_hotplug_notifier);
353 static void __exit pseries_processor_idle_exit(
void)
356 unregister_cpu_notifier(&setup_hotplug_notifier);
357 pseries_idle_devices_uninit();