VisionFive2 Linux kernel

StarFive Tech Linux Kernel for VisionFive (JH7110) boards (mirror)

More than 9999 Commits   33 Branches   55 Tags
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400   1) /*
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400   2)  * cpuidle.c - core cpuidle infrastructure
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400   3)  *
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400   4)  * (C) 2006-2007 Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400   5)  *               Shaohua Li <shaohua.li@intel.com>
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400   6)  *               Adam Belay <abelay@novell.com>
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400   7)  *
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400   8)  * This code is licenced under the GPL.
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400   9)  */
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400  10) 
b60e6a0eb0273 (Daniel Lezcano                2013-03-21 12:21:31 +0000  11) #include <linux/clockchips.h>
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400  12) #include <linux/kernel.h>
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400  13) #include <linux/mutex.h>
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400  14) #include <linux/sched.h>
e601757102cfd (Ingo Molnar                   2017-02-01 16:36:40 +0100  15) #include <linux/sched/clock.h>
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400  16) #include <linux/notifier.h>
e8db0be1245de (Jean Pihet                    2011-08-25 15:35:03 +0200  17) #include <linux/pm_qos.h>
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400  18) #include <linux/cpu.h>
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400  19) #include <linux/cpuidle.h>
9a0b841586c3c (venkatesh.pallipadi@intel.com 2008-01-31 17:35:06 -0800  20) #include <linux/ktime.h>
2e94d1f71f7e4 (Arjan van de Ven              2008-09-10 16:06:00 -0700  21) #include <linux/hrtimer.h>
884b17e109d61 (Paul Gortmaker                2011-08-29 17:52:39 -0400  22) #include <linux/module.h>
3810631332465 (Rafael J. Wysocki             2015-02-12 23:33:15 +0100  23) #include <linux/suspend.h>
124cf9117c5f9 (Rafael J. Wysocki             2015-02-13 23:50:43 +0100  24) #include <linux/tick.h>
bf9282dc26e7f (Peter Zijlstra                2020-08-12 12:22:17 +0200  25) #include <linux/mmu_context.h>
288f023e708ef (Arjan van de Ven              2009-09-19 13:35:33 +0200  26) #include <trace/events/power.h>
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400  27) 
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400  28) #include "cpuidle.h"
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400  29) 
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400  30) DEFINE_PER_CPU(struct cpuidle_device *, cpuidle_devices);
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000  31) DEFINE_PER_CPU(struct cpuidle_device, cpuidle_dev);
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400  32) 
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400  33) DEFINE_MUTEX(cpuidle_lock);
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400  34) LIST_HEAD(cpuidle_detected_devices);
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400  35) 
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400  36) static int enabled_devices;
62027aea23fcd (Len Brown                     2011-04-01 18:13:10 -0400  37) static int off __read_mostly;
a0bfa1373859e (Len Brown                     2011-04-01 19:34:59 -0400  38) static int initialized __read_mostly;
62027aea23fcd (Len Brown                     2011-04-01 18:13:10 -0400  39) 
62027aea23fcd (Len Brown                     2011-04-01 18:13:10 -0400  40) int cpuidle_disabled(void)
62027aea23fcd (Len Brown                     2011-04-01 18:13:10 -0400  41) {
62027aea23fcd (Len Brown                     2011-04-01 18:13:10 -0400  42) 	return off;
62027aea23fcd (Len Brown                     2011-04-01 18:13:10 -0400  43) }
d91ee5863b71e (Len Brown                     2011-04-01 18:28:35 -0400  44) void disable_cpuidle(void)
d91ee5863b71e (Len Brown                     2011-04-01 18:28:35 -0400  45) {
d91ee5863b71e (Len Brown                     2011-04-01 18:28:35 -0400  46) 	off = 1;
d91ee5863b71e (Len Brown                     2011-04-01 18:28:35 -0400  47) }
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400  48) 
ef2b22ac540c0 (Rafael J. Wysocki             2015-03-02 22:26:55 +0100  49) bool cpuidle_not_available(struct cpuidle_driver *drv,
ef2b22ac540c0 (Rafael J. Wysocki             2015-03-02 22:26:55 +0100  50) 			   struct cpuidle_device *dev)
31a3409065d1d (Rafael J. Wysocki             2015-02-27 00:39:56 +0100  51) {
31a3409065d1d (Rafael J. Wysocki             2015-02-27 00:39:56 +0100  52) 	return off || !initialized || !drv || !dev || !dev->enabled;
31a3409065d1d (Rafael J. Wysocki             2015-02-27 00:39:56 +0100  53) }
31a3409065d1d (Rafael J. Wysocki             2015-02-27 00:39:56 +0100  54) 
1a022e3f1be11 (Boris Ostrovsky               2012-03-13 19:55:09 +0100  55) /**
1a022e3f1be11 (Boris Ostrovsky               2012-03-13 19:55:09 +0100  56)  * cpuidle_play_dead - cpu off-lining
1a022e3f1be11 (Boris Ostrovsky               2012-03-13 19:55:09 +0100  57)  *
ee01e66337334 (Toshi Kani                    2012-03-31 21:37:02 -0600  58)  * Returns in case of an error or no driver
1a022e3f1be11 (Boris Ostrovsky               2012-03-13 19:55:09 +0100  59)  */
1a022e3f1be11 (Boris Ostrovsky               2012-03-13 19:55:09 +0100  60) int cpuidle_play_dead(void)
1a022e3f1be11 (Boris Ostrovsky               2012-03-13 19:55:09 +0100  61) {
1a022e3f1be11 (Boris Ostrovsky               2012-03-13 19:55:09 +0100  62) 	struct cpuidle_device *dev = __this_cpu_read(cpuidle_devices);
bf4d1b5ddb78f (Daniel Lezcano                2012-10-31 16:44:48 +0000  63) 	struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev);
8aef33a7cf40c (Daniel Lezcano                2013-01-15 14:18:04 +0100  64) 	int i;
1a022e3f1be11 (Boris Ostrovsky               2012-03-13 19:55:09 +0100  65) 
ee01e66337334 (Toshi Kani                    2012-03-31 21:37:02 -0600  66) 	if (!drv)
ee01e66337334 (Toshi Kani                    2012-03-31 21:37:02 -0600  67) 		return -ENODEV;
ee01e66337334 (Toshi Kani                    2012-03-31 21:37:02 -0600  68) 
1a022e3f1be11 (Boris Ostrovsky               2012-03-13 19:55:09 +0100  69) 	/* Find lowest-power state that supports long-term idle */
7d51d97925e6c (Rafael J. Wysocki             2015-05-28 04:09:24 +0200  70) 	for (i = drv->state_count - 1; i >= 0; i--)
8aef33a7cf40c (Daniel Lezcano                2013-01-15 14:18:04 +0100  71) 		if (drv->states[i].enter_dead)
8aef33a7cf40c (Daniel Lezcano                2013-01-15 14:18:04 +0100  72) 			return drv->states[i].enter_dead(dev, i);
1a022e3f1be11 (Boris Ostrovsky               2012-03-13 19:55:09 +0100  73) 
1a022e3f1be11 (Boris Ostrovsky               2012-03-13 19:55:09 +0100  74) 	return -ENODEV;
1a022e3f1be11 (Boris Ostrovsky               2012-03-13 19:55:09 +0100  75) }
1a022e3f1be11 (Boris Ostrovsky               2012-03-13 19:55:09 +0100  76) 
ef2b22ac540c0 (Rafael J. Wysocki             2015-03-02 22:26:55 +0100  77) static int find_deepest_state(struct cpuidle_driver *drv,
0d94039fabcca (Rafael J. Wysocki             2015-05-10 01:19:52 +0200  78) 			      struct cpuidle_device *dev,
c1d51f684c72b (Rafael J. Wysocki             2019-11-07 15:25:12 +0100  79) 			      u64 max_latency_ns,
0d94039fabcca (Rafael J. Wysocki             2015-05-10 01:19:52 +0200  80) 			      unsigned int forbidden_flags,
28ba086ed30fb (Rafael J. Wysocki             2017-08-10 00:14:45 +0200  81) 			      bool s2idle)
a6220fc19afc0 (Rafael J. Wysocki             2014-05-05 00:51:54 +0200  82) {
c1d51f684c72b (Rafael J. Wysocki             2019-11-07 15:25:12 +0100  83) 	u64 latency_req = 0;
51164251f5c35 (Rafael J. Wysocki             2016-01-16 00:54:53 +0100  84) 	int i, ret = 0;
a6220fc19afc0 (Rafael J. Wysocki             2014-05-05 00:51:54 +0200  85) 
51164251f5c35 (Rafael J. Wysocki             2016-01-16 00:54:53 +0100  86) 	for (i = 1; i < drv->state_count; i++) {
a6220fc19afc0 (Rafael J. Wysocki             2014-05-05 00:51:54 +0200  87) 		struct cpuidle_state *s = &drv->states[i];
a6220fc19afc0 (Rafael J. Wysocki             2014-05-05 00:51:54 +0200  88) 
99e98d3fb1008 (Rafael J. Wysocki             2019-11-04 12:16:17 +0100  89) 		if (dev->states_usage[i].disable ||
c1d51f684c72b (Rafael J. Wysocki             2019-11-07 15:25:12 +0100  90) 		    s->exit_latency_ns <= latency_req ||
c1d51f684c72b (Rafael J. Wysocki             2019-11-07 15:25:12 +0100  91) 		    s->exit_latency_ns > max_latency_ns ||
99e98d3fb1008 (Rafael J. Wysocki             2019-11-04 12:16:17 +0100  92) 		    (s->flags & forbidden_flags) ||
99e98d3fb1008 (Rafael J. Wysocki             2019-11-04 12:16:17 +0100  93) 		    (s2idle && !s->enter_s2idle))
a6220fc19afc0 (Rafael J. Wysocki             2014-05-05 00:51:54 +0200  94) 			continue;
a6220fc19afc0 (Rafael J. Wysocki             2014-05-05 00:51:54 +0200  95) 
c1d51f684c72b (Rafael J. Wysocki             2019-11-07 15:25:12 +0100  96) 		latency_req = s->exit_latency_ns;
a6220fc19afc0 (Rafael J. Wysocki             2014-05-05 00:51:54 +0200  97) 		ret = i;
a6220fc19afc0 (Rafael J. Wysocki             2014-05-05 00:51:54 +0200  98) 	}
a6220fc19afc0 (Rafael J. Wysocki             2014-05-05 00:51:54 +0200  99) 	return ret;
a6220fc19afc0 (Rafael J. Wysocki             2014-05-05 00:51:54 +0200 100) }
a6220fc19afc0 (Rafael J. Wysocki             2014-05-05 00:51:54 +0200 101) 
0e7414b7aa8b2 (Rafael J. Wysocki             2016-12-01 23:31:32 +0100 102) /**
c55b51a06b01d (Daniel Lezcano                2019-11-16 14:16:12 +0100 103)  * cpuidle_use_deepest_state - Set/unset governor override mode.
c55b51a06b01d (Daniel Lezcano                2019-11-16 14:16:12 +0100 104)  * @latency_limit_ns: Idle state exit latency limit (or no override if 0).
0e7414b7aa8b2 (Rafael J. Wysocki             2016-12-01 23:31:32 +0100 105)  *
c55b51a06b01d (Daniel Lezcano                2019-11-16 14:16:12 +0100 106)  * If @latency_limit_ns is nonzero, set the current CPU to use the deepest idle
c55b51a06b01d (Daniel Lezcano                2019-11-16 14:16:12 +0100 107)  * state with exit latency within @latency_limit_ns (override governors going
c55b51a06b01d (Daniel Lezcano                2019-11-16 14:16:12 +0100 108)  * forward), or do not override governors if it is zero.
0e7414b7aa8b2 (Rafael J. Wysocki             2016-12-01 23:31:32 +0100 109)  */
c55b51a06b01d (Daniel Lezcano                2019-11-16 14:16:12 +0100 110) void cpuidle_use_deepest_state(u64 latency_limit_ns)
bb8313b603eb8 (Jacob Pan                     2016-11-28 23:03:04 -0800 111) {
bb8313b603eb8 (Jacob Pan                     2016-11-28 23:03:04 -0800 112) 	struct cpuidle_device *dev;
bb8313b603eb8 (Jacob Pan                     2016-11-28 23:03:04 -0800 113) 
bb8313b603eb8 (Jacob Pan                     2016-11-28 23:03:04 -0800 114) 	preempt_disable();
bb8313b603eb8 (Jacob Pan                     2016-11-28 23:03:04 -0800 115) 	dev = cpuidle_get_device();
41dc750ea67f3 (Li, Fei                       2017-04-27 01:47:25 +0000 116) 	if (dev)
c55b51a06b01d (Daniel Lezcano                2019-11-16 14:16:12 +0100 117) 		dev->forced_idle_latency_limit_ns = latency_limit_ns;
bb8313b603eb8 (Jacob Pan                     2016-11-28 23:03:04 -0800 118) 	preempt_enable();
bb8313b603eb8 (Jacob Pan                     2016-11-28 23:03:04 -0800 119) }
bb8313b603eb8 (Jacob Pan                     2016-11-28 23:03:04 -0800 120) 
ef2b22ac540c0 (Rafael J. Wysocki             2015-03-02 22:26:55 +0100 121) /**
ef2b22ac540c0 (Rafael J. Wysocki             2015-03-02 22:26:55 +0100 122)  * cpuidle_find_deepest_state - Find the deepest available idle state.
ef2b22ac540c0 (Rafael J. Wysocki             2015-03-02 22:26:55 +0100 123)  * @drv: cpuidle driver for the given CPU.
ef2b22ac540c0 (Rafael J. Wysocki             2015-03-02 22:26:55 +0100 124)  * @dev: cpuidle device for the given CPU.
cefb9409ff995 (Benjamin Gaignard             2020-01-21 09:27:58 +0100 125)  * @latency_limit_ns: Idle state exit latency limit
cefb9409ff995 (Benjamin Gaignard             2020-01-21 09:27:58 +0100 126)  *
cefb9409ff995 (Benjamin Gaignard             2020-01-21 09:27:58 +0100 127)  * Return: the index of the deepest available idle state.
ef2b22ac540c0 (Rafael J. Wysocki             2015-03-02 22:26:55 +0100 128)  */
ef2b22ac540c0 (Rafael J. Wysocki             2015-03-02 22:26:55 +0100 129) int cpuidle_find_deepest_state(struct cpuidle_driver *drv,
5aa9ba6312e36 (Daniel Lezcano                2019-11-16 14:16:13 +0100 130) 			       struct cpuidle_device *dev,
5aa9ba6312e36 (Daniel Lezcano                2019-11-16 14:16:13 +0100 131) 			       u64 latency_limit_ns)
ef2b22ac540c0 (Rafael J. Wysocki             2015-03-02 22:26:55 +0100 132) {
5aa9ba6312e36 (Daniel Lezcano                2019-11-16 14:16:13 +0100 133) 	return find_deepest_state(drv, dev, latency_limit_ns, 0, false);
ef2b22ac540c0 (Rafael J. Wysocki             2015-03-02 22:26:55 +0100 134) }
ef2b22ac540c0 (Rafael J. Wysocki             2015-03-02 22:26:55 +0100 135) 
bb8313b603eb8 (Jacob Pan                     2016-11-28 23:03:04 -0800 136) #ifdef CONFIG_SUSPEND
28ba086ed30fb (Rafael J. Wysocki             2017-08-10 00:14:45 +0200 137) static void enter_s2idle_proper(struct cpuidle_driver *drv,
124cf9117c5f9 (Rafael J. Wysocki             2015-02-13 23:50:43 +0100 138) 				struct cpuidle_device *dev, int index)
124cf9117c5f9 (Rafael J. Wysocki             2015-02-13 23:50:43 +0100 139) {
64bdff698092a (Rafael J. Wysocki             2018-03-14 12:27:21 +0100 140) 	ktime_t time_start, time_end;
8747f2022fe8d (Peter Zijlstra                2020-09-15 12:32:00 +0200 141) 	struct cpuidle_state *target_state = &drv->states[index];
64bdff698092a (Rafael J. Wysocki             2018-03-14 12:27:21 +0100 142) 
64bdff698092a (Rafael J. Wysocki             2018-03-14 12:27:21 +0100 143) 	time_start = ns_to_ktime(local_clock());
64bdff698092a (Rafael J. Wysocki             2018-03-14 12:27:21 +0100 144) 
1098582a0f6c4 (Peter Zijlstra                2020-08-07 20:50:19 +0200 145) 	tick_freeze();
124cf9117c5f9 (Rafael J. Wysocki             2015-02-13 23:50:43 +0100 146) 	/*
124cf9117c5f9 (Rafael J. Wysocki             2015-02-13 23:50:43 +0100 147) 	 * The state used here cannot be a "coupled" one, because the "coupled"
124cf9117c5f9 (Rafael J. Wysocki             2015-02-13 23:50:43 +0100 148) 	 * cpuidle mechanism enables interrupts and doing that with timekeeping
124cf9117c5f9 (Rafael J. Wysocki             2015-02-13 23:50:43 +0100 149) 	 * suspended is generally unsafe.
124cf9117c5f9 (Rafael J. Wysocki             2015-02-13 23:50:43 +0100 150) 	 */
63caae8480921 (Lucas Stach                   2015-07-20 18:34:50 +0200 151) 	stop_critical_timings();
8747f2022fe8d (Peter Zijlstra                2020-09-15 12:32:00 +0200 152) 	if (!(target_state->flags & CPUIDLE_FLAG_RCU_IDLE))
8747f2022fe8d (Peter Zijlstra                2020-09-15 12:32:00 +0200 153) 		rcu_idle_enter();
8747f2022fe8d (Peter Zijlstra                2020-09-15 12:32:00 +0200 154) 	target_state->enter_s2idle(dev, drv, index);
49d9c5936314e (Peter Zijlstra                2020-08-20 16:47:24 +0200 155) 	if (WARN_ON_ONCE(!irqs_disabled()))
49d9c5936314e (Peter Zijlstra                2020-08-20 16:47:24 +0200 156) 		local_irq_disable();
8747f2022fe8d (Peter Zijlstra                2020-09-15 12:32:00 +0200 157) 	if (!(target_state->flags & CPUIDLE_FLAG_RCU_IDLE))
8747f2022fe8d (Peter Zijlstra                2020-09-15 12:32:00 +0200 158) 		rcu_idle_exit();
1098582a0f6c4 (Peter Zijlstra                2020-08-07 20:50:19 +0200 159) 	tick_unfreeze();
63caae8480921 (Lucas Stach                   2015-07-20 18:34:50 +0200 160) 	start_critical_timings();
64bdff698092a (Rafael J. Wysocki             2018-03-14 12:27:21 +0100 161) 
64bdff698092a (Rafael J. Wysocki             2018-03-14 12:27:21 +0100 162) 	time_end = ns_to_ktime(local_clock());
64bdff698092a (Rafael J. Wysocki             2018-03-14 12:27:21 +0100 163) 
64bdff698092a (Rafael J. Wysocki             2018-03-14 12:27:21 +0100 164) 	dev->states_usage[index].s2idle_time += ktime_us_delta(time_end, time_start);
64bdff698092a (Rafael J. Wysocki             2018-03-14 12:27:21 +0100 165) 	dev->states_usage[index].s2idle_usage++;
124cf9117c5f9 (Rafael J. Wysocki             2015-02-13 23:50:43 +0100 166) }
124cf9117c5f9 (Rafael J. Wysocki             2015-02-13 23:50:43 +0100 167) 
3810631332465 (Rafael J. Wysocki             2015-02-12 23:33:15 +0100 168) /**
28ba086ed30fb (Rafael J. Wysocki             2017-08-10 00:14:45 +0200 169)  * cpuidle_enter_s2idle - Enter an idle state suitable for suspend-to-idle.
ef2b22ac540c0 (Rafael J. Wysocki             2015-03-02 22:26:55 +0100 170)  * @drv: cpuidle driver for the given CPU.
ef2b22ac540c0 (Rafael J. Wysocki             2015-03-02 22:26:55 +0100 171)  * @dev: cpuidle device for the given CPU.
3810631332465 (Rafael J. Wysocki             2015-02-12 23:33:15 +0100 172)  *
28ba086ed30fb (Rafael J. Wysocki             2017-08-10 00:14:45 +0200 173)  * If there are states with the ->enter_s2idle callback, find the deepest of
ef2b22ac540c0 (Rafael J. Wysocki             2015-03-02 22:26:55 +0100 174)  * them and enter it with frozen tick.
3810631332465 (Rafael J. Wysocki             2015-02-12 23:33:15 +0100 175)  */
28ba086ed30fb (Rafael J. Wysocki             2017-08-10 00:14:45 +0200 176) int cpuidle_enter_s2idle(struct cpuidle_driver *drv, struct cpuidle_device *dev)
3810631332465 (Rafael J. Wysocki             2015-02-12 23:33:15 +0100 177) {
3810631332465 (Rafael J. Wysocki             2015-02-12 23:33:15 +0100 178) 	int index;
3810631332465 (Rafael J. Wysocki             2015-02-12 23:33:15 +0100 179) 
124cf9117c5f9 (Rafael J. Wysocki             2015-02-13 23:50:43 +0100 180) 	/*
28ba086ed30fb (Rafael J. Wysocki             2017-08-10 00:14:45 +0200 181) 	 * Find the deepest state with ->enter_s2idle present, which guarantees
124cf9117c5f9 (Rafael J. Wysocki             2015-02-13 23:50:43 +0100 182) 	 * that interrupts won't be enabled when it exits and allows the tick to
124cf9117c5f9 (Rafael J. Wysocki             2015-02-13 23:50:43 +0100 183) 	 * be frozen safely.
124cf9117c5f9 (Rafael J. Wysocki             2015-02-13 23:50:43 +0100 184) 	 */
c1d51f684c72b (Rafael J. Wysocki             2019-11-07 15:25:12 +0100 185) 	index = find_deepest_state(drv, dev, U64_MAX, 0, true);
10e8b11eb3195 (Rafael J. Wysocki             2020-06-25 13:52:53 +0200 186) 	if (index > 0) {
28ba086ed30fb (Rafael J. Wysocki             2017-08-10 00:14:45 +0200 187) 		enter_s2idle_proper(drv, dev, index);
10e8b11eb3195 (Rafael J. Wysocki             2020-06-25 13:52:53 +0200 188) 		local_irq_enable();
10e8b11eb3195 (Rafael J. Wysocki             2020-06-25 13:52:53 +0200 189) 	}
ef2b22ac540c0 (Rafael J. Wysocki             2015-03-02 22:26:55 +0100 190) 	return index;
3810631332465 (Rafael J. Wysocki             2015-02-12 23:33:15 +0100 191) }
87e9b9f1d86c2 (Rafael J. Wysocki             2015-05-16 01:38:15 +0200 192) #endif /* CONFIG_SUSPEND */
3810631332465 (Rafael J. Wysocki             2015-02-12 23:33:15 +0100 193) 
56cfbf74a17c4 (Colin Cross                   2012-05-07 17:57:39 -0700 194) /**
56cfbf74a17c4 (Colin Cross                   2012-05-07 17:57:39 -0700 195)  * cpuidle_enter_state - enter the state and update stats
56cfbf74a17c4 (Colin Cross                   2012-05-07 17:57:39 -0700 196)  * @dev: cpuidle device for this cpu
56cfbf74a17c4 (Colin Cross                   2012-05-07 17:57:39 -0700 197)  * @drv: cpuidle driver for this cpu
7312280bd2ad9 (Rafael J. Wysocki             2015-05-09 21:50:32 +0200 198)  * @index: index into the states table in @drv of the state to enter
56cfbf74a17c4 (Colin Cross                   2012-05-07 17:57:39 -0700 199)  */
56cfbf74a17c4 (Colin Cross                   2012-05-07 17:57:39 -0700 200) int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv,
554c06ba3ee29 (Daniel Lezcano                2013-04-23 08:54:31 +0000 201) 			int index)
56cfbf74a17c4 (Colin Cross                   2012-05-07 17:57:39 -0700 202) {
56cfbf74a17c4 (Colin Cross                   2012-05-07 17:57:39 -0700 203) 	int entered_state;
56cfbf74a17c4 (Colin Cross                   2012-05-07 17:57:39 -0700 204) 
554c06ba3ee29 (Daniel Lezcano                2013-04-23 08:54:31 +0000 205) 	struct cpuidle_state *target_state = &drv->states[index];
df8d9eeadd0f7 (Rafael J. Wysocki             2015-04-29 15:19:21 +0200 206) 	bool broadcast = !!(target_state->flags & CPUIDLE_FLAG_TIMER_STOP);
dbd1b8ea43b17 (Shreyas B. Prabhu             2016-07-01 09:24:14 -0500 207) 	ktime_t time_start, time_end;
554c06ba3ee29 (Daniel Lezcano                2013-04-23 08:54:31 +0000 208) 
df8d9eeadd0f7 (Rafael J. Wysocki             2015-04-29 15:19:21 +0200 209) 	/*
df8d9eeadd0f7 (Rafael J. Wysocki             2015-04-29 15:19:21 +0200 210) 	 * Tell the time framework to switch to a broadcast timer because our
df8d9eeadd0f7 (Rafael J. Wysocki             2015-04-29 15:19:21 +0200 211) 	 * local timer will be shut down.  If a local timer is used from another
df8d9eeadd0f7 (Rafael J. Wysocki             2015-04-29 15:19:21 +0200 212) 	 * CPU as a broadcast timer, this call may fail if it is not available.
df8d9eeadd0f7 (Rafael J. Wysocki             2015-04-29 15:19:21 +0200 213) 	 */
827a5aefc542b (Rafael J. Wysocki             2015-05-10 01:18:46 +0200 214) 	if (broadcast && tick_broadcast_enter()) {
c1d51f684c72b (Rafael J. Wysocki             2019-11-07 15:25:12 +0100 215) 		index = find_deepest_state(drv, dev, target_state->exit_latency_ns,
0d94039fabcca (Rafael J. Wysocki             2015-05-10 01:19:52 +0200 216) 					   CPUIDLE_FLAG_TIMER_STOP, false);
0d94039fabcca (Rafael J. Wysocki             2015-05-10 01:19:52 +0200 217) 		if (index < 0) {
0d94039fabcca (Rafael J. Wysocki             2015-05-10 01:19:52 +0200 218) 			default_idle_call();
0d94039fabcca (Rafael J. Wysocki             2015-05-10 01:19:52 +0200 219) 			return -EBUSY;
0d94039fabcca (Rafael J. Wysocki             2015-05-10 01:19:52 +0200 220) 		}
0d94039fabcca (Rafael J. Wysocki             2015-05-10 01:19:52 +0200 221) 		target_state = &drv->states[index];
f187851b9b4a7 (Nicholas Piggin               2017-09-01 14:29:56 +1000 222) 		broadcast = false;
827a5aefc542b (Rafael J. Wysocki             2015-05-10 01:18:46 +0200 223) 	}
df8d9eeadd0f7 (Rafael J. Wysocki             2015-04-29 15:19:21 +0200 224) 
bf9282dc26e7f (Peter Zijlstra                2020-08-12 12:22:17 +0200 225) 	if (target_state->flags & CPUIDLE_FLAG_TLB_FLUSHED)
bf9282dc26e7f (Peter Zijlstra                2020-08-12 12:22:17 +0200 226) 		leave_mm(dev->cpu);
bf9282dc26e7f (Peter Zijlstra                2020-08-12 12:22:17 +0200 227) 
faad384928141 (Rafael J. Wysocki             2015-05-10 01:18:03 +0200 228) 	/* Take note of the planned idle state. */
faad384928141 (Rafael J. Wysocki             2015-05-10 01:18:03 +0200 229) 	sched_idle_set_state(target_state);
faad384928141 (Rafael J. Wysocki             2015-05-10 01:18:03 +0200 230) 
1098582a0f6c4 (Peter Zijlstra                2020-08-07 20:50:19 +0200 231) 	trace_cpu_idle(index, dev->cpu);
dbd1b8ea43b17 (Shreyas B. Prabhu             2016-07-01 09:24:14 -0500 232) 	time_start = ns_to_ktime(local_clock());
554c06ba3ee29 (Daniel Lezcano                2013-04-23 08:54:31 +0000 233) 
63caae8480921 (Lucas Stach                   2015-07-20 18:34:50 +0200 234) 	stop_critical_timings();
8747f2022fe8d (Peter Zijlstra                2020-09-15 12:32:00 +0200 235) 	if (!(target_state->flags & CPUIDLE_FLAG_RCU_IDLE))
8747f2022fe8d (Peter Zijlstra                2020-09-15 12:32:00 +0200 236) 		rcu_idle_enter();
554c06ba3ee29 (Daniel Lezcano                2013-04-23 08:54:31 +0000 237) 	entered_state = target_state->enter(dev, drv, index);
8747f2022fe8d (Peter Zijlstra                2020-09-15 12:32:00 +0200 238) 	if (!(target_state->flags & CPUIDLE_FLAG_RCU_IDLE))
8747f2022fe8d (Peter Zijlstra                2020-09-15 12:32:00 +0200 239) 		rcu_idle_exit();
63caae8480921 (Lucas Stach                   2015-07-20 18:34:50 +0200 240) 	start_critical_timings();
554c06ba3ee29 (Daniel Lezcano                2013-04-23 08:54:31 +0000 241) 
f9fccdb9efef6 (Peter Zijlstra                2017-04-21 12:43:59 +0200 242) 	sched_clock_idle_wakeup_event();
dbd1b8ea43b17 (Shreyas B. Prabhu             2016-07-01 09:24:14 -0500 243) 	time_end = ns_to_ktime(local_clock());
1098582a0f6c4 (Peter Zijlstra                2020-08-07 20:50:19 +0200 244) 	trace_cpu_idle(PWR_EVENT_EXIT, dev->cpu);
554c06ba3ee29 (Daniel Lezcano                2013-04-23 08:54:31 +0000 245) 
faad384928141 (Rafael J. Wysocki             2015-05-10 01:18:03 +0200 246) 	/* The cpu is no longer idle or about to enter idle. */
faad384928141 (Rafael J. Wysocki             2015-05-10 01:18:03 +0200 247) 	sched_idle_set_state(NULL);
faad384928141 (Rafael J. Wysocki             2015-05-10 01:18:03 +0200 248) 
df8d9eeadd0f7 (Rafael J. Wysocki             2015-04-29 15:19:21 +0200 249) 	if (broadcast) {
df8d9eeadd0f7 (Rafael J. Wysocki             2015-04-29 15:19:21 +0200 250) 		if (WARN_ON_ONCE(!irqs_disabled()))
df8d9eeadd0f7 (Rafael J. Wysocki             2015-04-29 15:19:21 +0200 251) 			local_irq_disable();
df8d9eeadd0f7 (Rafael J. Wysocki             2015-04-29 15:19:21 +0200 252) 
df8d9eeadd0f7 (Rafael J. Wysocki             2015-04-29 15:19:21 +0200 253) 		tick_broadcast_exit();
df8d9eeadd0f7 (Rafael J. Wysocki             2015-04-29 15:19:21 +0200 254) 	}
df8d9eeadd0f7 (Rafael J. Wysocki             2015-04-29 15:19:21 +0200 255) 
e7387da52028b (Daniel Lezcano                2016-05-17 16:54:00 +0200 256) 	if (!cpuidle_state_is_coupled(drv, index))
0b89e9aa28566 (Paul Burton                   2014-03-06 11:02:01 +0000 257) 		local_irq_enable();
554c06ba3ee29 (Daniel Lezcano                2013-04-23 08:54:31 +0000 258) 
56cfbf74a17c4 (Colin Cross                   2012-05-07 17:57:39 -0700 259) 	if (entered_state >= 0) {
c1d51f684c72b (Rafael J. Wysocki             2019-11-07 15:25:12 +0100 260) 		s64 diff, delay = drv->states[entered_state].exit_latency_ns;
04dab58a39d40 (Rafael J. Wysocki             2018-12-10 12:30:23 +0100 261) 		int i;
04dab58a39d40 (Rafael J. Wysocki             2018-12-10 12:30:23 +0100 262) 
7037b43e0076c (Fieah Lim                     2018-09-11 05:47:25 +0800 263) 		/*
7037b43e0076c (Fieah Lim                     2018-09-11 05:47:25 +0800 264) 		 * Update cpuidle counters
7037b43e0076c (Fieah Lim                     2018-09-11 05:47:25 +0800 265) 		 * This can be moved to within driver enter routine,
56cfbf74a17c4 (Colin Cross                   2012-05-07 17:57:39 -0700 266) 		 * but that results in multiple copies of same code.
56cfbf74a17c4 (Colin Cross                   2012-05-07 17:57:39 -0700 267) 		 */
c1d51f684c72b (Rafael J. Wysocki             2019-11-07 15:25:12 +0100 268) 		diff = ktime_sub(time_end, time_start);
7037b43e0076c (Fieah Lim                     2018-09-11 05:47:25 +0800 269) 
c1d51f684c72b (Rafael J. Wysocki             2019-11-07 15:25:12 +0100 270) 		dev->last_residency_ns = diff;
c1d51f684c72b (Rafael J. Wysocki             2019-11-07 15:25:12 +0100 271) 		dev->states_usage[entered_state].time_ns += diff;
56cfbf74a17c4 (Colin Cross                   2012-05-07 17:57:39 -0700 272) 		dev->states_usage[entered_state].usage++;
04dab58a39d40 (Rafael J. Wysocki             2018-12-10 12:30:23 +0100 273) 
c1d51f684c72b (Rafael J. Wysocki             2019-11-07 15:25:12 +0100 274) 		if (diff < drv->states[entered_state].target_residency_ns) {
04dab58a39d40 (Rafael J. Wysocki             2018-12-10 12:30:23 +0100 275) 			for (i = entered_state - 1; i >= 0; i--) {
99e98d3fb1008 (Rafael J. Wysocki             2019-11-04 12:16:17 +0100 276) 				if (dev->states_usage[i].disable)
04dab58a39d40 (Rafael J. Wysocki             2018-12-10 12:30:23 +0100 277) 					continue;
04dab58a39d40 (Rafael J. Wysocki             2018-12-10 12:30:23 +0100 278) 
04dab58a39d40 (Rafael J. Wysocki             2018-12-10 12:30:23 +0100 279) 				/* Shallower states are enabled, so update. */
04dab58a39d40 (Rafael J. Wysocki             2018-12-10 12:30:23 +0100 280) 				dev->states_usage[entered_state].above++;
04dab58a39d40 (Rafael J. Wysocki             2018-12-10 12:30:23 +0100 281) 				break;
04dab58a39d40 (Rafael J. Wysocki             2018-12-10 12:30:23 +0100 282) 			}
04dab58a39d40 (Rafael J. Wysocki             2018-12-10 12:30:23 +0100 283) 		} else if (diff > delay) {
04dab58a39d40 (Rafael J. Wysocki             2018-12-10 12:30:23 +0100 284) 			for (i = entered_state + 1; i < drv->state_count; i++) {
99e98d3fb1008 (Rafael J. Wysocki             2019-11-04 12:16:17 +0100 285) 				if (dev->states_usage[i].disable)
04dab58a39d40 (Rafael J. Wysocki             2018-12-10 12:30:23 +0100 286) 					continue;
04dab58a39d40 (Rafael J. Wysocki             2018-12-10 12:30:23 +0100 287) 
04dab58a39d40 (Rafael J. Wysocki             2018-12-10 12:30:23 +0100 288) 				/*
04dab58a39d40 (Rafael J. Wysocki             2018-12-10 12:30:23 +0100 289) 				 * Update if a deeper state would have been a
04dab58a39d40 (Rafael J. Wysocki             2018-12-10 12:30:23 +0100 290) 				 * better match for the observed idle duration.
04dab58a39d40 (Rafael J. Wysocki             2018-12-10 12:30:23 +0100 291) 				 */
c1d51f684c72b (Rafael J. Wysocki             2019-11-07 15:25:12 +0100 292) 				if (diff - delay >= drv->states[i].target_residency_ns)
04dab58a39d40 (Rafael J. Wysocki             2018-12-10 12:30:23 +0100 293) 					dev->states_usage[entered_state].below++;
04dab58a39d40 (Rafael J. Wysocki             2018-12-10 12:30:23 +0100 294) 
04dab58a39d40 (Rafael J. Wysocki             2018-12-10 12:30:23 +0100 295) 				break;
04dab58a39d40 (Rafael J. Wysocki             2018-12-10 12:30:23 +0100 296) 			}
04dab58a39d40 (Rafael J. Wysocki             2018-12-10 12:30:23 +0100 297) 		}
56cfbf74a17c4 (Colin Cross                   2012-05-07 17:57:39 -0700 298) 	} else {
c1d51f684c72b (Rafael J. Wysocki             2019-11-07 15:25:12 +0100 299) 		dev->last_residency_ns = 0;
f49735f4978f4 (Lina Iyer                     2020-09-22 12:34:16 -0600 300) 		dev->states_usage[index].rejected++;
56cfbf74a17c4 (Colin Cross                   2012-05-07 17:57:39 -0700 301) 	}
56cfbf74a17c4 (Colin Cross                   2012-05-07 17:57:39 -0700 302) 
56cfbf74a17c4 (Colin Cross                   2012-05-07 17:57:39 -0700 303) 	return entered_state;
56cfbf74a17c4 (Colin Cross                   2012-05-07 17:57:39 -0700 304) }
56cfbf74a17c4 (Colin Cross                   2012-05-07 17:57:39 -0700 305) 
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 306) /**
907e30f1bb4a9 (Daniel Lezcano                2014-03-03 08:48:50 +0100 307)  * cpuidle_select - ask the cpuidle framework to choose an idle state
907e30f1bb4a9 (Daniel Lezcano                2014-03-03 08:48:50 +0100 308)  *
907e30f1bb4a9 (Daniel Lezcano                2014-03-03 08:48:50 +0100 309)  * @drv: the cpuidle driver
907e30f1bb4a9 (Daniel Lezcano                2014-03-03 08:48:50 +0100 310)  * @dev: the cpuidle device
45f1ff59e27ca (Rafael J. Wysocki             2018-03-22 17:50:49 +0100 311)  * @stop_tick: indication on whether or not to stop the tick
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 312)  *
51164251f5c35 (Rafael J. Wysocki             2016-01-16 00:54:53 +0100 313)  * Returns the index of the idle state.  The return value must not be negative.
45f1ff59e27ca (Rafael J. Wysocki             2018-03-22 17:50:49 +0100 314)  *
45f1ff59e27ca (Rafael J. Wysocki             2018-03-22 17:50:49 +0100 315)  * The memory location pointed to by @stop_tick is expected to be written the
45f1ff59e27ca (Rafael J. Wysocki             2018-03-22 17:50:49 +0100 316)  * 'false' boolean value if the scheduler tick should not be stopped before
45f1ff59e27ca (Rafael J. Wysocki             2018-03-22 17:50:49 +0100 317)  * entering the returned state.
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 318)  */
45f1ff59e27ca (Rafael J. Wysocki             2018-03-22 17:50:49 +0100 319) int cpuidle_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
45f1ff59e27ca (Rafael J. Wysocki             2018-03-22 17:50:49 +0100 320) 		   bool *stop_tick)
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 321) {
45f1ff59e27ca (Rafael J. Wysocki             2018-03-22 17:50:49 +0100 322) 	return cpuidle_curr_governor->select(drv, dev, stop_tick);
907e30f1bb4a9 (Daniel Lezcano                2014-03-03 08:48:50 +0100 323) }
ba8f20c2eb415 (Preeti U Murthy               2014-02-07 13:36:52 +0530 324) 
907e30f1bb4a9 (Daniel Lezcano                2014-03-03 08:48:50 +0100 325) /**
907e30f1bb4a9 (Daniel Lezcano                2014-03-03 08:48:50 +0100 326)  * cpuidle_enter - enter into the specified idle state
907e30f1bb4a9 (Daniel Lezcano                2014-03-03 08:48:50 +0100 327)  *
907e30f1bb4a9 (Daniel Lezcano                2014-03-03 08:48:50 +0100 328)  * @drv:   the cpuidle driver tied with the cpu
907e30f1bb4a9 (Daniel Lezcano                2014-03-03 08:48:50 +0100 329)  * @dev:   the cpuidle device
907e30f1bb4a9 (Daniel Lezcano                2014-03-03 08:48:50 +0100 330)  * @index: the index in the idle state table
907e30f1bb4a9 (Daniel Lezcano                2014-03-03 08:48:50 +0100 331)  *
907e30f1bb4a9 (Daniel Lezcano                2014-03-03 08:48:50 +0100 332)  * Returns the index in the idle state, < 0 in case of error.
907e30f1bb4a9 (Daniel Lezcano                2014-03-03 08:48:50 +0100 333)  * The error code depends on the backend driver
907e30f1bb4a9 (Daniel Lezcano                2014-03-03 08:48:50 +0100 334)  */
907e30f1bb4a9 (Daniel Lezcano                2014-03-03 08:48:50 +0100 335) int cpuidle_enter(struct cpuidle_driver *drv, struct cpuidle_device *dev,
907e30f1bb4a9 (Daniel Lezcano                2014-03-03 08:48:50 +0100 336) 		  int index)
907e30f1bb4a9 (Daniel Lezcano                2014-03-03 08:48:50 +0100 337) {
6f9b83ac877fb (Ulf Hansson                   2019-03-27 15:35:47 +0100 338) 	int ret = 0;
6f9b83ac877fb (Ulf Hansson                   2019-03-27 15:35:47 +0100 339) 
6f9b83ac877fb (Ulf Hansson                   2019-03-27 15:35:47 +0100 340) 	/*
6f9b83ac877fb (Ulf Hansson                   2019-03-27 15:35:47 +0100 341) 	 * Store the next hrtimer, which becomes either next tick or the next
6f9b83ac877fb (Ulf Hansson                   2019-03-27 15:35:47 +0100 342) 	 * timer event, whatever expires first. Additionally, to make this data
6f9b83ac877fb (Ulf Hansson                   2019-03-27 15:35:47 +0100 343) 	 * useful for consumers outside cpuidle, we rely on that the governor's
6f9b83ac877fb (Ulf Hansson                   2019-03-27 15:35:47 +0100 344) 	 * ->select() callback have decided, whether to stop the tick or not.
6f9b83ac877fb (Ulf Hansson                   2019-03-27 15:35:47 +0100 345) 	 */
6f9b83ac877fb (Ulf Hansson                   2019-03-27 15:35:47 +0100 346) 	WRITE_ONCE(dev->next_hrtimer, tick_nohz_get_next_hrtimer());
6f9b83ac877fb (Ulf Hansson                   2019-03-27 15:35:47 +0100 347) 
4c1ed5a607907 (Xunlei Pang                   2015-08-04 13:48:56 +0800 348) 	if (cpuidle_state_is_coupled(drv, index))
6f9b83ac877fb (Ulf Hansson                   2019-03-27 15:35:47 +0100 349) 		ret = cpuidle_enter_state_coupled(dev, drv, index);
6f9b83ac877fb (Ulf Hansson                   2019-03-27 15:35:47 +0100 350) 	else
6f9b83ac877fb (Ulf Hansson                   2019-03-27 15:35:47 +0100 351) 		ret = cpuidle_enter_state(dev, drv, index);
6f9b83ac877fb (Ulf Hansson                   2019-03-27 15:35:47 +0100 352) 
6f9b83ac877fb (Ulf Hansson                   2019-03-27 15:35:47 +0100 353) 	WRITE_ONCE(dev->next_hrtimer, 0);
6f9b83ac877fb (Ulf Hansson                   2019-03-27 15:35:47 +0100 354) 	return ret;
907e30f1bb4a9 (Daniel Lezcano                2014-03-03 08:48:50 +0100 355) }
b60e6a0eb0273 (Daniel Lezcano                2013-03-21 12:21:31 +0000 356) 
907e30f1bb4a9 (Daniel Lezcano                2014-03-03 08:48:50 +0100 357) /**
907e30f1bb4a9 (Daniel Lezcano                2014-03-03 08:48:50 +0100 358)  * cpuidle_reflect - tell the underlying governor what was the state
907e30f1bb4a9 (Daniel Lezcano                2014-03-03 08:48:50 +0100 359)  * we were in
907e30f1bb4a9 (Daniel Lezcano                2014-03-03 08:48:50 +0100 360)  *
907e30f1bb4a9 (Daniel Lezcano                2014-03-03 08:48:50 +0100 361)  * @dev  : the cpuidle device
907e30f1bb4a9 (Daniel Lezcano                2014-03-03 08:48:50 +0100 362)  * @index: the index in the idle state table
907e30f1bb4a9 (Daniel Lezcano                2014-03-03 08:48:50 +0100 363)  *
907e30f1bb4a9 (Daniel Lezcano                2014-03-03 08:48:50 +0100 364)  */
907e30f1bb4a9 (Daniel Lezcano                2014-03-03 08:48:50 +0100 365) void cpuidle_reflect(struct cpuidle_device *dev, int index)
907e30f1bb4a9 (Daniel Lezcano                2014-03-03 08:48:50 +0100 366) {
a802ea9645457 (Rafael J. Wysocki             2015-05-04 22:53:28 +0200 367) 	if (cpuidle_curr_governor->reflect && index >= 0)
907e30f1bb4a9 (Daniel Lezcano                2014-03-03 08:48:50 +0100 368) 		cpuidle_curr_governor->reflect(dev, index);
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 369) }
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 370) 
7a25759eaa04b (Mel Gorman                    2020-11-30 22:32:02 +0000 371) /*
7a25759eaa04b (Mel Gorman                    2020-11-30 22:32:02 +0000 372)  * Min polling interval of 10usec is a guess. It is assuming that
7a25759eaa04b (Mel Gorman                    2020-11-30 22:32:02 +0000 373)  * for most users, the time for a single ping-pong workload like
7a25759eaa04b (Mel Gorman                    2020-11-30 22:32:02 +0000 374)  * perf bench pipe would generally complete within 10usec but
7a25759eaa04b (Mel Gorman                    2020-11-30 22:32:02 +0000 375)  * this is hardware dependant. Actual time can be estimated with
7a25759eaa04b (Mel Gorman                    2020-11-30 22:32:02 +0000 376)  *
7a25759eaa04b (Mel Gorman                    2020-11-30 22:32:02 +0000 377)  * perf bench sched pipe -l 10000
7a25759eaa04b (Mel Gorman                    2020-11-30 22:32:02 +0000 378)  *
7a25759eaa04b (Mel Gorman                    2020-11-30 22:32:02 +0000 379)  * Run multiple times to avoid cpufreq effects.
7a25759eaa04b (Mel Gorman                    2020-11-30 22:32:02 +0000 380)  */
7a25759eaa04b (Mel Gorman                    2020-11-30 22:32:02 +0000 381) #define CPUIDLE_POLL_MIN 10000
7a25759eaa04b (Mel Gorman                    2020-11-30 22:32:02 +0000 382) #define CPUIDLE_POLL_MAX (TICK_NSEC / 16)
7a25759eaa04b (Mel Gorman                    2020-11-30 22:32:02 +0000 383) 
259231a045616 (Marcelo Tosatti               2019-07-03 20:51:26 -0300 384) /**
259231a045616 (Marcelo Tosatti               2019-07-03 20:51:26 -0300 385)  * cpuidle_poll_time - return amount of time to poll for,
259231a045616 (Marcelo Tosatti               2019-07-03 20:51:26 -0300 386)  * governors can override dev->poll_limit_ns if necessary
259231a045616 (Marcelo Tosatti               2019-07-03 20:51:26 -0300 387)  *
259231a045616 (Marcelo Tosatti               2019-07-03 20:51:26 -0300 388)  * @drv:   the cpuidle driver tied with the cpu
259231a045616 (Marcelo Tosatti               2019-07-03 20:51:26 -0300 389)  * @dev:   the cpuidle device
259231a045616 (Marcelo Tosatti               2019-07-03 20:51:26 -0300 390)  *
259231a045616 (Marcelo Tosatti               2019-07-03 20:51:26 -0300 391)  */
259231a045616 (Marcelo Tosatti               2019-07-03 20:51:26 -0300 392) u64 cpuidle_poll_time(struct cpuidle_driver *drv,
259231a045616 (Marcelo Tosatti               2019-07-03 20:51:26 -0300 393) 		      struct cpuidle_device *dev)
259231a045616 (Marcelo Tosatti               2019-07-03 20:51:26 -0300 394) {
259231a045616 (Marcelo Tosatti               2019-07-03 20:51:26 -0300 395) 	int i;
259231a045616 (Marcelo Tosatti               2019-07-03 20:51:26 -0300 396) 	u64 limit_ns;
259231a045616 (Marcelo Tosatti               2019-07-03 20:51:26 -0300 397) 
7a25759eaa04b (Mel Gorman                    2020-11-30 22:32:02 +0000 398) 	BUILD_BUG_ON(CPUIDLE_POLL_MIN > CPUIDLE_POLL_MAX);
7a25759eaa04b (Mel Gorman                    2020-11-30 22:32:02 +0000 399) 
259231a045616 (Marcelo Tosatti               2019-07-03 20:51:26 -0300 400) 	if (dev->poll_limit_ns)
259231a045616 (Marcelo Tosatti               2019-07-03 20:51:26 -0300 401) 		return dev->poll_limit_ns;
259231a045616 (Marcelo Tosatti               2019-07-03 20:51:26 -0300 402) 
7a25759eaa04b (Mel Gorman                    2020-11-30 22:32:02 +0000 403) 	limit_ns = CPUIDLE_POLL_MAX;
259231a045616 (Marcelo Tosatti               2019-07-03 20:51:26 -0300 404) 	for (i = 1; i < drv->state_count; i++) {
7a25759eaa04b (Mel Gorman                    2020-11-30 22:32:02 +0000 405) 		u64 state_limit;
7a25759eaa04b (Mel Gorman                    2020-11-30 22:32:02 +0000 406) 
99e98d3fb1008 (Rafael J. Wysocki             2019-11-04 12:16:17 +0100 407) 		if (dev->states_usage[i].disable)
259231a045616 (Marcelo Tosatti               2019-07-03 20:51:26 -0300 408) 			continue;
259231a045616 (Marcelo Tosatti               2019-07-03 20:51:26 -0300 409) 
7a25759eaa04b (Mel Gorman                    2020-11-30 22:32:02 +0000 410) 		state_limit = drv->states[i].target_residency_ns;
7a25759eaa04b (Mel Gorman                    2020-11-30 22:32:02 +0000 411) 		if (state_limit < CPUIDLE_POLL_MIN)
7a25759eaa04b (Mel Gorman                    2020-11-30 22:32:02 +0000 412) 			continue;
7a25759eaa04b (Mel Gorman                    2020-11-30 22:32:02 +0000 413) 
7a25759eaa04b (Mel Gorman                    2020-11-30 22:32:02 +0000 414) 		limit_ns = min_t(u64, state_limit, CPUIDLE_POLL_MAX);
36fcb4292473c (Marcelo Tosatti               2019-12-06 13:07:41 -0200 415) 		break;
259231a045616 (Marcelo Tosatti               2019-07-03 20:51:26 -0300 416) 	}
259231a045616 (Marcelo Tosatti               2019-07-03 20:51:26 -0300 417) 
259231a045616 (Marcelo Tosatti               2019-07-03 20:51:26 -0300 418) 	dev->poll_limit_ns = limit_ns;
259231a045616 (Marcelo Tosatti               2019-07-03 20:51:26 -0300 419) 
259231a045616 (Marcelo Tosatti               2019-07-03 20:51:26 -0300 420) 	return dev->poll_limit_ns;
259231a045616 (Marcelo Tosatti               2019-07-03 20:51:26 -0300 421) }
259231a045616 (Marcelo Tosatti               2019-07-03 20:51:26 -0300 422) 
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 423) /**
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 424)  * cpuidle_install_idle_handler - installs the cpuidle idle loop handler
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 425)  */
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 426) void cpuidle_install_idle_handler(void)
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 427) {
a0bfa1373859e (Len Brown                     2011-04-01 19:34:59 -0400 428) 	if (enabled_devices) {
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 429) 		/* Make sure all changes finished before we switch to new idle */
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 430) 		smp_wmb();
a0bfa1373859e (Len Brown                     2011-04-01 19:34:59 -0400 431) 		initialized = 1;
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 432) 	}
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 433) }
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 434) 
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 435) /**
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 436)  * cpuidle_uninstall_idle_handler - uninstalls the cpuidle idle loop handler
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 437)  */
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 438) void cpuidle_uninstall_idle_handler(void)
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 439) {
a0bfa1373859e (Len Brown                     2011-04-01 19:34:59 -0400 440) 	if (enabled_devices) {
a0bfa1373859e (Len Brown                     2011-04-01 19:34:59 -0400 441) 		initialized = 0;
2ed903c5485ba (Chuansheng Liu                2014-09-04 15:17:55 +0800 442) 		wake_up_all_idle_cpus();
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 443) 	}
442bf3aaf55a9 (Daniel Lezcano                2014-09-04 11:32:09 -0400 444) 
442bf3aaf55a9 (Daniel Lezcano                2014-09-04 11:32:09 -0400 445) 	/*
442bf3aaf55a9 (Daniel Lezcano                2014-09-04 11:32:09 -0400 446) 	 * Make sure external observers (such as the scheduler)
442bf3aaf55a9 (Daniel Lezcano                2014-09-04 11:32:09 -0400 447) 	 * are done looking at pointed idle states.
442bf3aaf55a9 (Daniel Lezcano                2014-09-04 11:32:09 -0400 448) 	 */
442bf3aaf55a9 (Daniel Lezcano                2014-09-04 11:32:09 -0400 449) 	synchronize_rcu();
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 450) }
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 451) 
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 452) /**
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 453)  * cpuidle_pause_and_lock - temporarily disables CPUIDLE
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 454)  */
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 455) void cpuidle_pause_and_lock(void)
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 456) {
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 457) 	mutex_lock(&cpuidle_lock);
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 458) 	cpuidle_uninstall_idle_handler();
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 459) }
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 460) 
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 461) EXPORT_SYMBOL_GPL(cpuidle_pause_and_lock);
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 462) 
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 463) /**
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 464)  * cpuidle_resume_and_unlock - resumes CPUIDLE operation
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 465)  */
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 466) void cpuidle_resume_and_unlock(void)
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 467) {
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 468) 	cpuidle_install_idle_handler();
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 469) 	mutex_unlock(&cpuidle_lock);
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 470) }
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 471) 
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 472) EXPORT_SYMBOL_GPL(cpuidle_resume_and_unlock);
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 473) 
8651f97bd951d (Preeti U Murthy               2012-07-09 10:12:56 +0200 474) /* Currently used in suspend/resume path to suspend cpuidle */
8651f97bd951d (Preeti U Murthy               2012-07-09 10:12:56 +0200 475) void cpuidle_pause(void)
8651f97bd951d (Preeti U Murthy               2012-07-09 10:12:56 +0200 476) {
8651f97bd951d (Preeti U Murthy               2012-07-09 10:12:56 +0200 477) 	mutex_lock(&cpuidle_lock);
8651f97bd951d (Preeti U Murthy               2012-07-09 10:12:56 +0200 478) 	cpuidle_uninstall_idle_handler();
8651f97bd951d (Preeti U Murthy               2012-07-09 10:12:56 +0200 479) 	mutex_unlock(&cpuidle_lock);
8651f97bd951d (Preeti U Murthy               2012-07-09 10:12:56 +0200 480) }
8651f97bd951d (Preeti U Murthy               2012-07-09 10:12:56 +0200 481) 
8651f97bd951d (Preeti U Murthy               2012-07-09 10:12:56 +0200 482) /* Currently used in suspend/resume path to resume cpuidle */
8651f97bd951d (Preeti U Murthy               2012-07-09 10:12:56 +0200 483) void cpuidle_resume(void)
8651f97bd951d (Preeti U Murthy               2012-07-09 10:12:56 +0200 484) {
8651f97bd951d (Preeti U Murthy               2012-07-09 10:12:56 +0200 485) 	mutex_lock(&cpuidle_lock);
8651f97bd951d (Preeti U Murthy               2012-07-09 10:12:56 +0200 486) 	cpuidle_install_idle_handler();
8651f97bd951d (Preeti U Murthy               2012-07-09 10:12:56 +0200 487) 	mutex_unlock(&cpuidle_lock);
8651f97bd951d (Preeti U Murthy               2012-07-09 10:12:56 +0200 488) }
8651f97bd951d (Preeti U Murthy               2012-07-09 10:12:56 +0200 489) 
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 490) /**
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 491)  * cpuidle_enable_device - enables idle PM for a CPU
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 492)  * @dev: the CPU
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 493)  *
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 494)  * This function must be called between cpuidle_pause_and_lock and
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 495)  * cpuidle_resume_and_unlock when used externally.
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 496)  */
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 497) int cpuidle_enable_device(struct cpuidle_device *dev)
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 498) {
5df0aa7341bd9 (Daniel Lezcano                2013-06-12 15:08:54 +0200 499) 	int ret;
bf4d1b5ddb78f (Daniel Lezcano                2012-10-31 16:44:48 +0000 500) 	struct cpuidle_driver *drv;
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 501) 
1b0a0e9a15b97 (Srivatsa S. Bhat              2012-05-04 14:06:02 -0700 502) 	if (!dev)
1b0a0e9a15b97 (Srivatsa S. Bhat              2012-05-04 14:06:02 -0700 503) 		return -EINVAL;
1b0a0e9a15b97 (Srivatsa S. Bhat              2012-05-04 14:06:02 -0700 504) 
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 505) 	if (dev->enabled)
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 506) 		return 0;
bf4d1b5ddb78f (Daniel Lezcano                2012-10-31 16:44:48 +0000 507) 
e7b06a09e7d87 (Gaurav Jindal                 2017-09-01 20:37:26 +0530 508) 	if (!cpuidle_curr_governor)
e7b06a09e7d87 (Gaurav Jindal                 2017-09-01 20:37:26 +0530 509) 		return -EIO;
e7b06a09e7d87 (Gaurav Jindal                 2017-09-01 20:37:26 +0530 510) 
bf4d1b5ddb78f (Daniel Lezcano                2012-10-31 16:44:48 +0000 511) 	drv = cpuidle_get_cpu_driver(dev);
bf4d1b5ddb78f (Daniel Lezcano                2012-10-31 16:44:48 +0000 512) 
e7b06a09e7d87 (Gaurav Jindal                 2017-09-01 20:37:26 +0530 513) 	if (!drv)
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 514) 		return -EIO;
bf4d1b5ddb78f (Daniel Lezcano                2012-10-31 16:44:48 +0000 515) 
10b9d3f8a4d5c (Daniel Lezcano                2013-06-12 15:08:49 +0200 516) 	if (!dev->registered)
10b9d3f8a4d5c (Daniel Lezcano                2013-06-12 15:08:49 +0200 517) 		return -EINVAL;
10b9d3f8a4d5c (Daniel Lezcano                2013-06-12 15:08:49 +0200 518) 
bf4d1b5ddb78f (Daniel Lezcano                2012-10-31 16:44:48 +0000 519) 	ret = cpuidle_add_device_sysfs(dev);
bf4d1b5ddb78f (Daniel Lezcano                2012-10-31 16:44:48 +0000 520) 	if (ret)
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 521) 		return ret;
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 522) 
3fc74bd8a723c (Gaurav Jindal                 2017-09-02 00:56:38 +0530 523) 	if (cpuidle_curr_governor->enable) {
3fc74bd8a723c (Gaurav Jindal                 2017-09-02 00:56:38 +0530 524) 		ret = cpuidle_curr_governor->enable(drv, dev);
3fc74bd8a723c (Gaurav Jindal                 2017-09-02 00:56:38 +0530 525) 		if (ret)
3fc74bd8a723c (Gaurav Jindal                 2017-09-02 00:56:38 +0530 526) 			goto fail_sysfs;
3fc74bd8a723c (Gaurav Jindal                 2017-09-02 00:56:38 +0530 527) 	}
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 528) 
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 529) 	smp_wmb();
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 530) 
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 531) 	dev->enabled = 1;
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 532) 
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 533) 	enabled_devices++;
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 534) 	return 0;
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 535) 
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 536) fail_sysfs:
bf4d1b5ddb78f (Daniel Lezcano                2012-10-31 16:44:48 +0000 537) 	cpuidle_remove_device_sysfs(dev);
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 538) 
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 539) 	return ret;
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 540) }
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 541) 
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 542) EXPORT_SYMBOL_GPL(cpuidle_enable_device);
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 543) 
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 544) /**
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 545)  * cpuidle_disable_device - disables idle PM for a CPU
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 546)  * @dev: the CPU
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 547)  *
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 548)  * This function must be called between cpuidle_pause_and_lock and
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 549)  * cpuidle_resume_and_unlock when used externally.
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 550)  */
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 551) void cpuidle_disable_device(struct cpuidle_device *dev)
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 552) {
bf4d1b5ddb78f (Daniel Lezcano                2012-10-31 16:44:48 +0000 553) 	struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev);
bf4d1b5ddb78f (Daniel Lezcano                2012-10-31 16:44:48 +0000 554) 
cf31cd1a0c692 (Srivatsa S. Bhat              2012-10-08 13:43:08 +0530 555) 	if (!dev || !dev->enabled)
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 556) 		return;
bf4d1b5ddb78f (Daniel Lezcano                2012-10-31 16:44:48 +0000 557) 
bf4d1b5ddb78f (Daniel Lezcano                2012-10-31 16:44:48 +0000 558) 	if (!drv || !cpuidle_curr_governor)
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 559) 		return;
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 560) 
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 561) 	dev->enabled = 0;
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 562) 
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 563) 	if (cpuidle_curr_governor->disable)
bf4d1b5ddb78f (Daniel Lezcano                2012-10-31 16:44:48 +0000 564) 		cpuidle_curr_governor->disable(drv, dev);
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 565) 
bf4d1b5ddb78f (Daniel Lezcano                2012-10-31 16:44:48 +0000 566) 	cpuidle_remove_device_sysfs(dev);
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 567) 	enabled_devices--;
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 568) }
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 569) 
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 570) EXPORT_SYMBOL_GPL(cpuidle_disable_device);
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 571) 
f6bb51a53a753 (Daniel Lezcano                2013-06-12 15:08:53 +0200 572) static void __cpuidle_unregister_device(struct cpuidle_device *dev)
f6bb51a53a753 (Daniel Lezcano                2013-06-12 15:08:53 +0200 573) {
f6bb51a53a753 (Daniel Lezcano                2013-06-12 15:08:53 +0200 574) 	struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev);
f6bb51a53a753 (Daniel Lezcano                2013-06-12 15:08:53 +0200 575) 
f6bb51a53a753 (Daniel Lezcano                2013-06-12 15:08:53 +0200 576) 	list_del(&dev->device_list);
f6bb51a53a753 (Daniel Lezcano                2013-06-12 15:08:53 +0200 577) 	per_cpu(cpuidle_devices, dev->cpu) = NULL;
f6bb51a53a753 (Daniel Lezcano                2013-06-12 15:08:53 +0200 578) 	module_put(drv->owner);
c998c07836f98 (Dave Gerlach                  2016-04-05 14:05:38 -0500 579) 
c998c07836f98 (Dave Gerlach                  2016-04-05 14:05:38 -0500 580) 	dev->registered = 0;
f6bb51a53a753 (Daniel Lezcano                2013-06-12 15:08:53 +0200 581) }
f6bb51a53a753 (Daniel Lezcano                2013-06-12 15:08:53 +0200 582) 
267d4bf8ee6db (Viresh Kumar                  2013-10-03 21:26:43 +0530 583) static void __cpuidle_device_init(struct cpuidle_device *dev)
5df0aa7341bd9 (Daniel Lezcano                2013-06-12 15:08:54 +0200 584) {
5df0aa7341bd9 (Daniel Lezcano                2013-06-12 15:08:54 +0200 585) 	memset(dev->states_usage, 0, sizeof(dev->states_usage));
c1d51f684c72b (Rafael J. Wysocki             2019-11-07 15:25:12 +0100 586) 	dev->last_residency_ns = 0;
6f9b83ac877fb (Ulf Hansson                   2019-03-27 15:35:47 +0100 587) 	dev->next_hrtimer = 0;
5df0aa7341bd9 (Daniel Lezcano                2013-06-12 15:08:54 +0200 588) }
5df0aa7341bd9 (Daniel Lezcano                2013-06-12 15:08:54 +0200 589) 
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 590) /**
dcb84f335bee9 (Venkatesh Pallipadi           2008-05-19 19:09:27 -0400 591)  * __cpuidle_register_device - internal register function called before register
dcb84f335bee9 (Venkatesh Pallipadi           2008-05-19 19:09:27 -0400 592)  * and enable routines
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 593)  * @dev: the cpu
dcb84f335bee9 (Venkatesh Pallipadi           2008-05-19 19:09:27 -0400 594)  *
dcb84f335bee9 (Venkatesh Pallipadi           2008-05-19 19:09:27 -0400 595)  * cpuidle_lock mutex must be held before this is called
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 596)  */
dcb84f335bee9 (Venkatesh Pallipadi           2008-05-19 19:09:27 -0400 597) static int __cpuidle_register_device(struct cpuidle_device *dev)
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 598) {
bf4d1b5ddb78f (Daniel Lezcano                2012-10-31 16:44:48 +0000 599) 	struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev);
99e98d3fb1008 (Rafael J. Wysocki             2019-11-04 12:16:17 +0100 600) 	int i, ret;
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 601) 
bf4d1b5ddb78f (Daniel Lezcano                2012-10-31 16:44:48 +0000 602) 	if (!try_module_get(drv->owner))
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 603) 		return -EINVAL;
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 604) 
75a80267410e3 (Rafael J. Wysocki             2019-12-13 09:56:13 +0100 605) 	for (i = 0; i < drv->state_count; i++) {
ba1e78a1dc0ca (Rafael J. Wysocki             2019-11-21 19:41:51 +0100 606) 		if (drv->states[i].flags & CPUIDLE_FLAG_UNUSABLE)
99e98d3fb1008 (Rafael J. Wysocki             2019-11-04 12:16:17 +0100 607) 			dev->states_usage[i].disable |= CPUIDLE_STATE_DISABLED_BY_DRIVER;
99e98d3fb1008 (Rafael J. Wysocki             2019-11-04 12:16:17 +0100 608) 
75a80267410e3 (Rafael J. Wysocki             2019-12-13 09:56:13 +0100 609) 		if (drv->states[i].flags & CPUIDLE_FLAG_OFF)
75a80267410e3 (Rafael J. Wysocki             2019-12-13 09:56:13 +0100 610) 			dev->states_usage[i].disable |= CPUIDLE_STATE_DISABLED_BY_USER;
75a80267410e3 (Rafael J. Wysocki             2019-12-13 09:56:13 +0100 611) 	}
75a80267410e3 (Rafael J. Wysocki             2019-12-13 09:56:13 +0100 612) 
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 613) 	per_cpu(cpuidle_devices, dev->cpu) = dev;
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 614) 	list_add(&dev->device_list, &cpuidle_detected_devices);
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 615) 
4126c0197bc8c (Colin Cross                   2012-05-07 17:57:41 -0700 616) 	ret = cpuidle_coupled_register_device(dev);
47182668ca140 (Viresh Kumar                  2013-10-03 21:26:46 +0530 617) 	if (ret)
f6bb51a53a753 (Daniel Lezcano                2013-06-12 15:08:53 +0200 618) 		__cpuidle_unregister_device(dev);
47182668ca140 (Viresh Kumar                  2013-10-03 21:26:46 +0530 619) 	else
47182668ca140 (Viresh Kumar                  2013-10-03 21:26:46 +0530 620) 		dev->registered = 1;
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 621) 
47182668ca140 (Viresh Kumar                  2013-10-03 21:26:46 +0530 622) 	return ret;
dcb84f335bee9 (Venkatesh Pallipadi           2008-05-19 19:09:27 -0400 623) }
dcb84f335bee9 (Venkatesh Pallipadi           2008-05-19 19:09:27 -0400 624) 
dcb84f335bee9 (Venkatesh Pallipadi           2008-05-19 19:09:27 -0400 625) /**
dcb84f335bee9 (Venkatesh Pallipadi           2008-05-19 19:09:27 -0400 626)  * cpuidle_register_device - registers a CPU's idle PM feature
dcb84f335bee9 (Venkatesh Pallipadi           2008-05-19 19:09:27 -0400 627)  * @dev: the cpu
dcb84f335bee9 (Venkatesh Pallipadi           2008-05-19 19:09:27 -0400 628)  */
dcb84f335bee9 (Venkatesh Pallipadi           2008-05-19 19:09:27 -0400 629) int cpuidle_register_device(struct cpuidle_device *dev)
dcb84f335bee9 (Venkatesh Pallipadi           2008-05-19 19:09:27 -0400 630) {
c878a52d3c7ca (Daniel Lezcano                2013-06-12 15:08:55 +0200 631) 	int ret = -EBUSY;
dcb84f335bee9 (Venkatesh Pallipadi           2008-05-19 19:09:27 -0400 632) 
1b0a0e9a15b97 (Srivatsa S. Bhat              2012-05-04 14:06:02 -0700 633) 	if (!dev)
1b0a0e9a15b97 (Srivatsa S. Bhat              2012-05-04 14:06:02 -0700 634) 		return -EINVAL;
1b0a0e9a15b97 (Srivatsa S. Bhat              2012-05-04 14:06:02 -0700 635) 
dcb84f335bee9 (Venkatesh Pallipadi           2008-05-19 19:09:27 -0400 636) 	mutex_lock(&cpuidle_lock);
dcb84f335bee9 (Venkatesh Pallipadi           2008-05-19 19:09:27 -0400 637) 
c878a52d3c7ca (Daniel Lezcano                2013-06-12 15:08:55 +0200 638) 	if (dev->registered)
c878a52d3c7ca (Daniel Lezcano                2013-06-12 15:08:55 +0200 639) 		goto out_unlock;
c878a52d3c7ca (Daniel Lezcano                2013-06-12 15:08:55 +0200 640) 
267d4bf8ee6db (Viresh Kumar                  2013-10-03 21:26:43 +0530 641) 	__cpuidle_device_init(dev);
5df0aa7341bd9 (Daniel Lezcano                2013-06-12 15:08:54 +0200 642) 
f6bb51a53a753 (Daniel Lezcano                2013-06-12 15:08:53 +0200 643) 	ret = __cpuidle_register_device(dev);
f6bb51a53a753 (Daniel Lezcano                2013-06-12 15:08:53 +0200 644) 	if (ret)
f6bb51a53a753 (Daniel Lezcano                2013-06-12 15:08:53 +0200 645) 		goto out_unlock;
f6bb51a53a753 (Daniel Lezcano                2013-06-12 15:08:53 +0200 646) 
f6bb51a53a753 (Daniel Lezcano                2013-06-12 15:08:53 +0200 647) 	ret = cpuidle_add_sysfs(dev);
f6bb51a53a753 (Daniel Lezcano                2013-06-12 15:08:53 +0200 648) 	if (ret)
f6bb51a53a753 (Daniel Lezcano                2013-06-12 15:08:53 +0200 649) 		goto out_unregister;
dcb84f335bee9 (Venkatesh Pallipadi           2008-05-19 19:09:27 -0400 650) 
10b9d3f8a4d5c (Daniel Lezcano                2013-06-12 15:08:49 +0200 651) 	ret = cpuidle_enable_device(dev);
f6bb51a53a753 (Daniel Lezcano                2013-06-12 15:08:53 +0200 652) 	if (ret)
f6bb51a53a753 (Daniel Lezcano                2013-06-12 15:08:53 +0200 653) 		goto out_sysfs;
10b9d3f8a4d5c (Daniel Lezcano                2013-06-12 15:08:49 +0200 654) 
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 655) 	cpuidle_install_idle_handler();
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 656) 
f6bb51a53a753 (Daniel Lezcano                2013-06-12 15:08:53 +0200 657) out_unlock:
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 658) 	mutex_unlock(&cpuidle_lock);
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 659) 
f6bb51a53a753 (Daniel Lezcano                2013-06-12 15:08:53 +0200 660) 	return ret;
f6bb51a53a753 (Daniel Lezcano                2013-06-12 15:08:53 +0200 661) 
f6bb51a53a753 (Daniel Lezcano                2013-06-12 15:08:53 +0200 662) out_sysfs:
f6bb51a53a753 (Daniel Lezcano                2013-06-12 15:08:53 +0200 663) 	cpuidle_remove_sysfs(dev);
f6bb51a53a753 (Daniel Lezcano                2013-06-12 15:08:53 +0200 664) out_unregister:
f6bb51a53a753 (Daniel Lezcano                2013-06-12 15:08:53 +0200 665) 	__cpuidle_unregister_device(dev);
f6bb51a53a753 (Daniel Lezcano                2013-06-12 15:08:53 +0200 666) 	goto out_unlock;
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 667) }
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 668) 
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 669) EXPORT_SYMBOL_GPL(cpuidle_register_device);
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 670) 
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 671) /**
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 672)  * cpuidle_unregister_device - unregisters a CPU's idle PM feature
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 673)  * @dev: the cpu
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 674)  */
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 675) void cpuidle_unregister_device(struct cpuidle_device *dev)
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 676) {
813e8e3d6aaa0 (Konrad Rzeszutek Wilk         2013-12-03 10:59:58 -0500 677) 	if (!dev || dev->registered == 0)
dcb84f335bee9 (Venkatesh Pallipadi           2008-05-19 19:09:27 -0400 678) 		return;
dcb84f335bee9 (Venkatesh Pallipadi           2008-05-19 19:09:27 -0400 679) 
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 680) 	cpuidle_pause_and_lock();
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 681) 
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 682) 	cpuidle_disable_device(dev);
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 683) 
1aef40e288acf (Daniel Lezcano                2012-10-26 12:26:24 +0200 684) 	cpuidle_remove_sysfs(dev);
f6bb51a53a753 (Daniel Lezcano                2013-06-12 15:08:53 +0200 685) 
f6bb51a53a753 (Daniel Lezcano                2013-06-12 15:08:53 +0200 686) 	__cpuidle_unregister_device(dev);
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 687) 
4126c0197bc8c (Colin Cross                   2012-05-07 17:57:41 -0700 688) 	cpuidle_coupled_unregister_device(dev);
4126c0197bc8c (Colin Cross                   2012-05-07 17:57:41 -0700 689) 
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 690) 	cpuidle_resume_and_unlock();
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 691) }
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 692) 
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 693) EXPORT_SYMBOL_GPL(cpuidle_unregister_device);
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 694) 
1c192d047a0dd (Daniel Lezcano                2013-04-23 15:28:44 +0000 695) /**
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 696)  * cpuidle_unregister: unregister a driver and the devices. This function
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 697)  * can be used only if the driver has been previously registered through
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 698)  * the cpuidle_register function.
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 699)  *
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 700)  * @drv: a valid pointer to a struct cpuidle_driver
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 701)  */
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 702) void cpuidle_unregister(struct cpuidle_driver *drv)
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 703) {
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 704) 	int cpu;
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 705) 	struct cpuidle_device *device;
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 706) 
82467a5a885dd (Daniel Lezcano                2013-06-07 21:53:09 +0000 707) 	for_each_cpu(cpu, drv->cpumask) {
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 708) 		device = &per_cpu(cpuidle_dev, cpu);
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 709) 		cpuidle_unregister_device(device);
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 710) 	}
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 711) 
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 712) 	cpuidle_unregister_driver(drv);
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 713) }
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 714) EXPORT_SYMBOL_GPL(cpuidle_unregister);
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 715) 
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 716) /**
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 717)  * cpuidle_register: registers the driver and the cpu devices with the
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 718)  * coupled_cpus passed as parameter. This function is used for all common
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 719)  * initialization pattern there are in the arch specific drivers. The
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 720)  * devices is globally defined in this file.
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 721)  *
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 722)  * @drv         : a valid pointer to a struct cpuidle_driver
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 723)  * @coupled_cpus: a cpumask for the coupled states
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 724)  *
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 725)  * Returns 0 on success, < 0 otherwise
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 726)  */
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 727) int cpuidle_register(struct cpuidle_driver *drv,
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 728) 		     const struct cpumask *const coupled_cpus)
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 729) {
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 730) 	int ret, cpu;
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 731) 	struct cpuidle_device *device;
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 732) 
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 733) 	ret = cpuidle_register_driver(drv);
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 734) 	if (ret) {
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 735) 		pr_err("failed to register cpuidle driver\n");
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 736) 		return ret;
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 737) 	}
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 738) 
82467a5a885dd (Daniel Lezcano                2013-06-07 21:53:09 +0000 739) 	for_each_cpu(cpu, drv->cpumask) {
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 740) 		device = &per_cpu(cpuidle_dev, cpu);
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 741) 		device->cpu = cpu;
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 742) 
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 743) #ifdef CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 744) 		/*
caf4a36e818ba (Viresh Kumar                  2013-10-03 21:26:41 +0530 745) 		 * On multiplatform for ARM, the coupled idle states could be
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 746) 		 * enabled in the kernel even if the cpuidle driver does not
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 747) 		 * use it. Note, coupled_cpus is a struct copy.
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 748) 		 */
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 749) 		if (coupled_cpus)
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 750) 			device->coupled_cpus = *coupled_cpus;
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 751) #endif
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 752) 		ret = cpuidle_register_device(device);
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 753) 		if (!ret)
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 754) 			continue;
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 755) 
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 756) 		pr_err("Failed to register cpuidle device for cpu%d\n", cpu);
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 757) 
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 758) 		cpuidle_unregister(drv);
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 759) 		break;
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 760) 	}
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 761) 
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 762) 	return ret;
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 763) }
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 764) EXPORT_SYMBOL_GPL(cpuidle_register);
4c637b2175a0d (Daniel Lezcano                2013-04-23 08:54:33 +0000 765) 
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 766) /**
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 767)  * cpuidle_init - core initializer
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 768)  */
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 769) static int __init cpuidle_init(void)
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 770) {
62027aea23fcd (Len Brown                     2011-04-01 18:13:10 -0400 771) 	if (cpuidle_disabled())
62027aea23fcd (Len Brown                     2011-04-01 18:13:10 -0400 772) 		return -ENODEV;
62027aea23fcd (Len Brown                     2011-04-01 18:13:10 -0400 773) 
3a4a0042228a8 (Rafael J. Wysocki             2020-02-12 00:02:30 +0100 774) 	return cpuidle_add_interface(cpu_subsys.dev_root);
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 775) }
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 776) 
62027aea23fcd (Len Brown                     2011-04-01 18:13:10 -0400 777) module_param(off, int, 0444);
61cb5758d3c46 (Rafael J. Wysocki             2018-12-05 23:45:34 +0100 778) module_param_string(governor, param_governor, CPUIDLE_NAME_LEN, 0444);
4f86d3a8e2972 (Len Brown                     2007-10-03 18:58:00 -0400 779) core_initcall(cpuidle_init);