0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #include <linux/sched.h>
0019 #include <linux/kernel.h>
0020 #include <linux/smp.h>
0021 #include <linux/cpu.h>
0022 #include <linux/sysctl.h>
0023 #include <linux/tick.h>
0024
0025 #include <asm/processor.h>
0026 #include <asm/cputable.h>
0027 #include <asm/time.h>
0028 #include <asm/machdep.h>
0029 #include <asm/runlatch.h>
0030 #include <asm/smp.h>
0031
0032
0033 unsigned long cpuidle_disable = IDLE_NO_OVERRIDE;
0034 EXPORT_SYMBOL(cpuidle_disable);
0035
0036 static int __init powersave_off(char *arg)
0037 {
0038 ppc_md.power_save = NULL;
0039 cpuidle_disable = IDLE_POWERSAVE_OFF;
0040 return 1;
0041 }
0042 __setup("powersave=off", powersave_off);
0043
0044 void arch_cpu_idle(void)
0045 {
0046 ppc64_runlatch_off();
0047
0048 if (ppc_md.power_save) {
0049 ppc_md.power_save();
0050
0051
0052
0053
0054 if (irqs_disabled())
0055 raw_local_irq_enable();
0056 } else {
0057 raw_local_irq_enable();
0058
0059
0060
0061
0062 HMT_low();
0063 HMT_very_low();
0064 }
0065
0066 HMT_medium();
0067 ppc64_runlatch_on();
0068 }
0069
0070 int powersave_nap;
0071
0072 #ifdef CONFIG_PPC_970_NAP
0073 void power4_idle(void)
0074 {
0075 if (!cpu_has_feature(CPU_FTR_CAN_NAP))
0076 return;
0077
0078 if (!powersave_nap)
0079 return;
0080
0081 if (!prep_irq_for_idle())
0082 return;
0083
0084 if (cpu_has_feature(CPU_FTR_ALTIVEC))
0085 asm volatile(PPC_DSSALL " ; sync" ::: "memory");
0086
0087 power4_idle_nap();
0088
0089
0090
0091
0092
0093
0094 }
0095 #endif
0096
0097 #ifdef CONFIG_SYSCTL
0098
0099
0100
0101 static struct ctl_table powersave_nap_ctl_table[] = {
0102 {
0103 .procname = "powersave-nap",
0104 .data = &powersave_nap,
0105 .maxlen = sizeof(int),
0106 .mode = 0644,
0107 .proc_handler = proc_dointvec,
0108 },
0109 {}
0110 };
0111 static struct ctl_table powersave_nap_sysctl_root[] = {
0112 {
0113 .procname = "kernel",
0114 .mode = 0555,
0115 .child = powersave_nap_ctl_table,
0116 },
0117 {}
0118 };
0119
0120 static int __init
0121 register_powersave_nap_sysctl(void)
0122 {
0123 register_sysctl_table(powersave_nap_sysctl_root);
0124
0125 return 0;
0126 }
0127 __initcall(register_powersave_nap_sysctl);
0128 #endif