Commit | Line | Data |
---|---|---|
2874c5fd | 1 | // SPDX-License-Identifier: GPL-2.0-or-later |
1da177e4 LT |
2 | /* |
3 | * Idle daemon for PowerPC. Idle daemon will handle any action | |
4 | * that needs to be taken when the system becomes idle. | |
5 | * | |
a0652fc9 PM |
6 | * Originally written by Cort Dougan (cort@cs.nmt.edu). |
7 | * Subsequent 32-bit hacking by Tom Rini, Armin Kuster, | |
8 | * Paul Mackerras and others. | |
1da177e4 LT |
9 | * |
10 | * iSeries supported added by Mike Corrigan <mikejc@us.ibm.com> | |
11 | * | |
12 | * Additional shared processor, SMT, and firmware support | |
13 | * Copyright (c) 2003 Dave Engebretsen <engebret@us.ibm.com> | |
14 | * | |
a0652fc9 | 15 | * 32-bit and 64-bit versions merged by Paul Mackerras <paulus@samba.org> |
1da177e4 LT |
16 | */ |
17 | ||
1da177e4 LT |
18 | #include <linux/sched.h> |
19 | #include <linux/kernel.h> | |
20 | #include <linux/smp.h> | |
21 | #include <linux/cpu.h> | |
1da177e4 | 22 | #include <linux/sysctl.h> |
1ad74998 | 23 | #include <linux/tick.h> |
1da177e4 | 24 | |
1da177e4 | 25 | #include <asm/processor.h> |
1da177e4 LT |
26 | #include <asm/cputable.h> |
27 | #include <asm/time.h> | |
fd899c0c | 28 | #include <asm/machdep.h> |
ae3a197e | 29 | #include <asm/runlatch.h> |
2249ca9d | 30 | #include <asm/smp.h> |
1da177e4 | 31 | |
1da177e4 | 32 | |
771dae81 DD |
33 | unsigned long cpuidle_disable = IDLE_NO_OVERRIDE; |
34 | EXPORT_SYMBOL(cpuidle_disable); | |
35 | ||
302eca18 | 36 | static int __init powersave_off(char *arg) |
37 | { | |
38 | ppc_md.power_save = NULL; | |
771dae81 | 39 | cpuidle_disable = IDLE_POWERSAVE_OFF; |
b793a010 | 40 | return 1; |
302eca18 | 41 | } |
42 | __setup("powersave=off", powersave_off); | |
43 | ||
799fef06 TG |
44 | void arch_cpu_idle(void) |
45 | { | |
46 | ppc64_runlatch_off(); | |
47 | ||
48 | if (ppc_md.power_save) { | |
49 | ppc_md.power_save(); | |
50 | /* | |
51 | * Some power_save functions return with | |
52 | * interrupts enabled, some don't. | |
53 | */ | |
89b30987 PZ |
54 | if (!irqs_disabled()) |
55 | raw_local_irq_disable(); | |
799fef06 | 56 | } else { |
799fef06 TG |
57 | /* |
58 | * Go into low thread priority and possibly | |
59 | * low power mode. | |
60 | */ | |
61 | HMT_low(); | |
62 | HMT_very_low(); | |
1da177e4 | 63 | } |
799fef06 TG |
64 | |
65 | HMT_medium(); | |
66 | ppc64_runlatch_on(); | |
1da177e4 LT |
67 | } |
68 | ||
1da177e4 LT |
69 | int powersave_nap; |
70 | ||
ed0bc98f NP |
71 | #ifdef CONFIG_PPC_970_NAP |
72 | void power4_idle(void) | |
73 | { | |
74 | if (!cpu_has_feature(CPU_FTR_CAN_NAP)) | |
75 | return; | |
76 | ||
77 | if (!powersave_nap) | |
78 | return; | |
79 | ||
80 | if (!prep_irq_for_idle()) | |
81 | return; | |
82 | ||
83 | if (cpu_has_feature(CPU_FTR_ALTIVEC)) | |
d51f86cf | 84 | asm volatile(PPC_DSSALL " ; sync" ::: "memory"); |
ed0bc98f NP |
85 | |
86 | power4_idle_nap(); | |
87 | ||
88 | /* | |
89 | * power4_idle_nap returns with interrupts enabled (soft and hard). | |
90 | * to our caller with interrupts enabled (soft and hard). Our caller | |
91 | * can cope with either interrupts disabled or enabled upon return. | |
92 | */ | |
93 | } | |
94 | #endif | |
95 | ||
1da177e4 LT |
96 | #ifdef CONFIG_SYSCTL |
97 | /* | |
98 | * Register the sysctl to set/clear powersave_nap. | |
99 | */ | |
cc293bf7 | 100 | static struct ctl_table powersave_nap_ctl_table[] = { |
1da177e4 | 101 | { |
1da177e4 LT |
102 | .procname = "powersave-nap", |
103 | .data = &powersave_nap, | |
104 | .maxlen = sizeof(int), | |
105 | .mode = 0644, | |
6d456111 | 106 | .proc_handler = proc_dointvec, |
1da177e4 | 107 | }, |
1da177e4 | 108 | }; |
1da177e4 LT |
109 | |
110 | static int __init | |
111 | register_powersave_nap_sysctl(void) | |
112 | { | |
bfedee5d | 113 | register_sysctl("kernel", powersave_nap_ctl_table); |
1da177e4 LT |
114 | |
115 | return 0; | |
116 | } | |
117 | __initcall(register_powersave_nap_sysctl); | |
118 | #endif |