blob: a36fd053c3dbae785ca85cf2b5457f32bf21e9b6 [file] [log] [blame]
Thomas Gleixner2874c5f2019-05-27 08:55:01 +02001// SPDX-License-Identifier: GPL-2.0-or-later
Linus Torvalds1da177e2005-04-16 15:20:36 -07002/*
3 * Idle daemon for PowerPC. Idle daemon will handle any action
4 * that needs to be taken when the system becomes idle.
5 *
Paul Mackerrasa0652fc2006-03-27 15:03:03 +11006 * Originally written by Cort Dougan (cort@cs.nmt.edu).
7 * Subsequent 32-bit hacking by Tom Rini, Armin Kuster,
8 * Paul Mackerras and others.
Linus Torvalds1da177e2005-04-16 15:20:36 -07009 *
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 *
Paul Mackerrasa0652fc2006-03-27 15:03:03 +110015 * 32-bit and 64-bit versions merged by Paul Mackerras <paulus@samba.org>
Linus Torvalds1da177e2005-04-16 15:20:36 -070016 */
17
Linus Torvalds1da177e2005-04-16 15:20:36 -070018#include <linux/sched.h>
19#include <linux/kernel.h>
20#include <linux/smp.h>
21#include <linux/cpu.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070022#include <linux/sysctl.h>
Tony Breeds1ad74992007-09-21 13:26:03 +100023#include <linux/tick.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070024
Linus Torvalds1da177e2005-04-16 15:20:36 -070025#include <asm/processor.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070026#include <asm/cputable.h>
27#include <asm/time.h>
Michael Ellermanfd899c02005-07-07 17:56:28 -070028#include <asm/machdep.h>
David Howellsae3a1972012-03-28 18:30:02 +010029#include <asm/runlatch.h>
Paul Mackerras2249ca92005-11-07 13:18:13 +110030#include <asm/smp.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070031
Linus Torvalds1da177e2005-04-16 15:20:36 -070032
Deepthi Dharwar771dae82011-11-30 02:46:31 +000033unsigned long cpuidle_disable = IDLE_NO_OVERRIDE;
34EXPORT_SYMBOL(cpuidle_disable);
35
arnd@arndb.de302eca12006-10-24 18:31:26 +020036static int __init powersave_off(char *arg)
37{
38 ppc_md.power_save = NULL;
Deepthi Dharwar771dae82011-11-30 02:46:31 +000039 cpuidle_disable = IDLE_POWERSAVE_OFF;
arnd@arndb.de302eca12006-10-24 18:31:26 +020040 return 0;
41}
42__setup("powersave=off", powersave_off);
43
Thomas Gleixner799fef02013-03-21 22:49:56 +010044#ifdef CONFIG_HOTPLUG_CPU
45void arch_cpu_idle_dead(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -070046{
Thomas Gleixner799fef02013-03-21 22:49:56 +010047 sched_preempt_enable_no_resched();
48 cpu_die();
49}
50#endif
Frederic Weisbecker1268fbc2011-11-17 18:48:14 +010051
Thomas Gleixner799fef02013-03-21 22:49:56 +010052void arch_cpu_idle(void)
53{
54 ppc64_runlatch_off();
Anton Blanchardddafddc2006-04-02 19:54:09 +100055
Thomas Gleixner799fef02013-03-21 22:49:56 +010056 if (ppc_md.power_save) {
57 ppc_md.power_save();
58 /*
59 * Some power_save functions return with
60 * interrupts enabled, some don't.
61 */
62 if (irqs_disabled())
63 local_irq_enable();
64 } else {
65 local_irq_enable();
66 /*
67 * Go into low thread priority and possibly
68 * low power mode.
69 */
70 HMT_low();
71 HMT_very_low();
Linus Torvalds1da177e2005-04-16 15:20:36 -070072 }
Thomas Gleixner799fef02013-03-21 22:49:56 +010073
74 HMT_medium();
75 ppc64_runlatch_on();
Linus Torvalds1da177e2005-04-16 15:20:36 -070076}
77
Linus Torvalds1da177e2005-04-16 15:20:36 -070078int powersave_nap;
79
80#ifdef CONFIG_SYSCTL
81/*
82 * Register the sysctl to set/clear powersave_nap.
83 */
Joe Perchescc293bf2013-06-13 19:37:30 -070084static struct ctl_table powersave_nap_ctl_table[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -070085 {
Linus Torvalds1da177e2005-04-16 15:20:36 -070086 .procname = "powersave-nap",
87 .data = &powersave_nap,
88 .maxlen = sizeof(int),
89 .mode = 0644,
Eric W. Biederman6d456112009-11-16 03:11:48 -080090 .proc_handler = proc_dointvec,
Linus Torvalds1da177e2005-04-16 15:20:36 -070091 },
Eric W. Biedermanf5f10672007-02-14 00:33:46 -080092 {}
Linus Torvalds1da177e2005-04-16 15:20:36 -070093};
Joe Perchescc293bf2013-06-13 19:37:30 -070094static struct ctl_table powersave_nap_sysctl_root[] = {
Eric W. Biedermanf5f10672007-02-14 00:33:46 -080095 {
Eric W. Biedermanf5f10672007-02-14 00:33:46 -080096 .procname = "kernel",
Alexey Dobriyanfb293ae2007-10-28 05:34:53 +110097 .mode = 0555,
Eric W. Biedermanf5f10672007-02-14 00:33:46 -080098 .child = powersave_nap_ctl_table,
99 },
100 {}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700101};
102
103static int __init
104register_powersave_nap_sysctl(void)
105{
Eric W. Biederman0b4d4142007-02-14 00:34:09 -0800106 register_sysctl_table(powersave_nap_sysctl_root);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700107
108 return 0;
109}
110__initcall(register_powersave_nap_sysctl);
111#endif