aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/cpuidle
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-11-13 23:41:48 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-11-13 23:41:48 -0500
commitf9300eaaac1ca300083ad41937923a90cc3a2394 (patch)
tree724b72ad729a8b85c09d2d54f8ca7d8ba22d774f /drivers/cpuidle
parent7f2dc5c4bcbff035b0d03f7aa78a182664b21e47 (diff)
parentfaddf2f5d278f1656e9444961bdd8d9db4deb5bf (diff)
Merge tag 'pm+acpi-3.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull ACPI and power management updates from Rafael J Wysocki: - New power capping framework and the the Intel Running Average Power Limit (RAPL) driver using it from Srinivas Pandruvada and Jacob Pan. - Addition of the in-kernel switching feature to the arm_big_little cpufreq driver from Viresh Kumar and Nicolas Pitre. - cpufreq support for iMac G5 from Aaro Koskinen. - Baytrail processors support for intel_pstate from Dirk Brandewie. - cpufreq support for Midway/ECX-2000 from Mark Langsdorf. - ARM vexpress/TC2 cpufreq support from Sudeep KarkadaNagesha. - ACPI power management support for the I2C and SPI bus types from Mika Westerberg and Lv Zheng. - cpufreq core fixes and cleanups from Viresh Kumar, Srivatsa S Bhat, Stratos Karafotis, Xiaoguang Chen, Lan Tianyu. - cpufreq drivers updates (mostly fixes and cleanups) from Viresh Kumar, Aaro Koskinen, Jungseok Lee, Sudeep KarkadaNagesha, Lukasz Majewski, Manish Badarkhe, Hans-Christian Egtvedt, Evgeny Kapaev. - intel_pstate updates from Dirk Brandewie and Adrian Huang. - ACPICA update to version 20130927 includig fixes and cleanups and some reduction of divergences between the ACPICA code in the kernel and ACPICA upstream in order to improve the automatic ACPICA patch generation process. From Bob Moore, Lv Zheng, Tomasz Nowicki, Naresh Bhat, Bjorn Helgaas, David E Box. - ACPI IPMI driver fixes and cleanups from Lv Zheng. - ACPI hotplug fixes and cleanups from Bjorn Helgaas, Toshi Kani, Zhang Yanfei, Rafael J Wysocki. - Conversion of the ACPI AC driver to the platform bus type and multiple driver fixes and cleanups related to ACPI from Zhang Rui. - ACPI processor driver fixes and cleanups from Hanjun Guo, Jiang Liu, Bartlomiej Zolnierkiewicz, Mathieu Rhéaume, Rafael J Wysocki. - Fixes and cleanups and new blacklist entries related to the ACPI video support from Aaron Lu, Felipe Contreras, Lennart Poettering, Kirill Tkhai. - cpuidle core cleanups from Viresh Kumar and Lorenzo Pieralisi. - cpuidle drivers fixes and cleanups from Daniel Lezcano, Jingoo Han, Bartlomiej Zolnierkiewicz, Prarit Bhargava. - devfreq updates from Sachin Kamat, Dan Carpenter, Manish Badarkhe. - Operation Performance Points (OPP) core updates from Nishanth Menon. - Runtime power management core fix from Rafael J Wysocki and update from Ulf Hansson. - Hibernation fixes from Aaron Lu and Rafael J Wysocki. - Device suspend/resume lockup detection mechanism from Benoit Goby. - Removal of unused proc directories created for various ACPI drivers from Lan Tianyu. - ACPI LPSS driver fix and new device IDs for the ACPI platform scan handler from Heikki Krogerus and Jarkko Nikula. - New ACPI _OSI blacklist entry for Toshiba NB100 from Levente Kurusa. - Assorted fixes and cleanups related to ACPI from Andy Shevchenko, Al Stone, Bartlomiej Zolnierkiewicz, Colin Ian King, Dan Carpenter, Felipe Contreras, Jianguo Wu, Lan Tianyu, Yinghai Lu, Mathias Krause, Liu Chuansheng. - Assorted PM fixes and cleanups from Andy Shevchenko, Thierry Reding, Jean-Christophe Plagniol-Villard. * tag 'pm+acpi-3.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (386 commits) cpufreq: conservative: fix requested_freq reduction issue ACPI / hotplug: Consolidate deferred execution of ACPI hotplug routines PM / runtime: Use pm_runtime_put_sync() in __device_release_driver() ACPI / event: remove unneeded NULL pointer check Revert "ACPI / video: Ignore BIOS initial backlight value for HP 250 G1" ACPI / video: Quirk initial backlight level 0 ACPI / video: Fix initial level validity test intel_pstate: skip the driver if ACPI has power mgmt option PM / hibernate: Avoid overflow in hibernate_preallocate_memory() ACPI / hotplug: Do not execute "insert in progress" _OST ACPI / hotplug: Carry out PCI root eject directly ACPI / hotplug: Merge device hot-removal routines ACPI / hotplug: Make acpi_bus_hot_remove_device() internal ACPI / hotplug: Simplify device ejection routines ACPI / hotplug: Fix handle_root_bridge_removal() ACPI / hotplug: Refuse to hot-remove all objects with disabled hotplug ACPI / scan: Start matching drivers after trying scan handlers ACPI: Remove acpi_pci_slot_init() headers from internal.h ACPI / blacklist: fix name of ThinkPad Edge E530 PowerCap: Fix build error with option -Werror=format-security ... Conflicts: arch/arm/mach-omap2/opp.c drivers/Kconfig drivers/spi/spi.c
Diffstat (limited to 'drivers/cpuidle')
-rw-r--r--drivers/cpuidle/Kconfig.arm25
-rw-r--r--drivers/cpuidle/Makefile3
-rw-r--r--drivers/cpuidle/coupled.c2
-rw-r--r--drivers/cpuidle/cpuidle-at91.c69
-rw-r--r--drivers/cpuidle/cpuidle-ux500.c2
-rw-r--r--drivers/cpuidle/cpuidle-zynq.c17
-rw-r--r--drivers/cpuidle/cpuidle.c78
-rw-r--r--drivers/cpuidle/driver.c67
-rw-r--r--drivers/cpuidle/governor.c43
-rw-r--r--drivers/cpuidle/sysfs.c7
10 files changed, 170 insertions, 143 deletions
diff --git a/drivers/cpuidle/Kconfig.arm b/drivers/cpuidle/Kconfig.arm
index d6f57d5d9631..d988948a89a0 100644
--- a/drivers/cpuidle/Kconfig.arm
+++ b/drivers/cpuidle/Kconfig.arm
@@ -2,6 +2,17 @@
2# ARM CPU Idle drivers 2# ARM CPU Idle drivers
3# 3#
4 4
5config ARM_BIG_LITTLE_CPUIDLE
6 bool "Support for ARM big.LITTLE processors"
7 depends on ARCH_VEXPRESS_TC2_PM
8 select ARM_CPU_SUSPEND
9 select CPU_IDLE_MULTIPLE_DRIVERS
10 help
11 Select this option to enable CPU idle driver for big.LITTLE based
12 ARM systems. Driver manages CPUs coordination through MCPM and
13 define different C-states for little and big cores through the
14 multiple CPU idle drivers infrastructure.
15
5config ARM_HIGHBANK_CPUIDLE 16config ARM_HIGHBANK_CPUIDLE
6 bool "CPU Idle Driver for Calxeda processors" 17 bool "CPU Idle Driver for Calxeda processors"
7 depends on ARM_PSCI 18 depends on ARM_PSCI
@@ -27,13 +38,9 @@ config ARM_U8500_CPUIDLE
27 help 38 help
28 Select this to enable cpuidle for ST-E u8500 processors 39 Select this to enable cpuidle for ST-E u8500 processors
29 40
30config CPU_IDLE_BIG_LITTLE 41config ARM_AT91_CPUIDLE
31 bool "Support for ARM big.LITTLE processors" 42 bool "Cpu Idle Driver for the AT91 processors"
32 depends on ARCH_VEXPRESS_TC2_PM 43 default y
33 select ARM_CPU_SUSPEND 44 depends on ARCH_AT91
34 select CPU_IDLE_MULTIPLE_DRIVERS
35 help 45 help
36 Select this option to enable CPU idle driver for big.LITTLE based 46 Select this to enable cpuidle for AT91 processors
37 ARM systems. Driver manages CPUs coordination through MCPM and
38 define different C-states for little and big cores through the
39 multiple CPU idle drivers infrastructure.
diff --git a/drivers/cpuidle/Makefile b/drivers/cpuidle/Makefile
index cea5ef58876d..527be28e5c1e 100644
--- a/drivers/cpuidle/Makefile
+++ b/drivers/cpuidle/Makefile
@@ -7,8 +7,9 @@ obj-$(CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED) += coupled.o
7 7
8################################################################################## 8##################################################################################
9# ARM SoC drivers 9# ARM SoC drivers
10obj-$(CONFIG_ARM_BIG_LITTLE_CPUIDLE) += cpuidle-big_little.o
10obj-$(CONFIG_ARM_HIGHBANK_CPUIDLE) += cpuidle-calxeda.o 11obj-$(CONFIG_ARM_HIGHBANK_CPUIDLE) += cpuidle-calxeda.o
11obj-$(CONFIG_ARM_KIRKWOOD_CPUIDLE) += cpuidle-kirkwood.o 12obj-$(CONFIG_ARM_KIRKWOOD_CPUIDLE) += cpuidle-kirkwood.o
12obj-$(CONFIG_ARM_ZYNQ_CPUIDLE) += cpuidle-zynq.o 13obj-$(CONFIG_ARM_ZYNQ_CPUIDLE) += cpuidle-zynq.o
13obj-$(CONFIG_ARM_U8500_CPUIDLE) += cpuidle-ux500.o 14obj-$(CONFIG_ARM_U8500_CPUIDLE) += cpuidle-ux500.o
14obj-$(CONFIG_CPU_IDLE_BIG_LITTLE) += cpuidle-big_little.o 15obj-$(CONFIG_ARM_AT91_CPUIDLE) += cpuidle-at91.o
diff --git a/drivers/cpuidle/coupled.c b/drivers/cpuidle/coupled.c
index f8a86364c6b6..e952936418d0 100644
--- a/drivers/cpuidle/coupled.c
+++ b/drivers/cpuidle/coupled.c
@@ -147,7 +147,7 @@ static cpumask_t cpuidle_coupled_poked;
147 * has returned from this function, the barrier is immediately available for 147 * has returned from this function, the barrier is immediately available for
148 * reuse. 148 * reuse.
149 * 149 *
150 * The atomic variable a must be initialized to 0 before any cpu calls 150 * The atomic variable must be initialized to 0 before any cpu calls
151 * this function, will be reset to 0 before any cpu returns from this function. 151 * this function, will be reset to 0 before any cpu returns from this function.
152 * 152 *
153 * Must only be called from within a coupled idle state handler 153 * Must only be called from within a coupled idle state handler
diff --git a/drivers/cpuidle/cpuidle-at91.c b/drivers/cpuidle/cpuidle-at91.c
new file mode 100644
index 000000000000..a0774370c6bc
--- /dev/null
+++ b/drivers/cpuidle/cpuidle-at91.c
@@ -0,0 +1,69 @@
1/*
2 * based on arch/arm/mach-kirkwood/cpuidle.c
3 *
4 * CPU idle support for AT91 SoC
5 *
6 * This file is licensed under the terms of the GNU General Public
7 * License version 2. This program is licensed "as is" without any
8 * warranty of any kind, whether express or implied.
9 *
10 * The cpu idle uses wait-for-interrupt and RAM self refresh in order
11 * to implement two idle states -
12 * #1 wait-for-interrupt
13 * #2 wait-for-interrupt and RAM self refresh
14 */
15
16#include <linux/kernel.h>
17#include <linux/init.h>
18#include <linux/platform_device.h>
19#include <linux/cpuidle.h>
20#include <linux/io.h>
21#include <linux/export.h>
22#include <asm/proc-fns.h>
23#include <asm/cpuidle.h>
24
25#define AT91_MAX_STATES 2
26
27static void (*at91_standby)(void);
28
29/* Actual code that puts the SoC in different idle states */
30static int at91_enter_idle(struct cpuidle_device *dev,
31 struct cpuidle_driver *drv,
32 int index)
33{
34 at91_standby();
35 return index;
36}
37
38static struct cpuidle_driver at91_idle_driver = {
39 .name = "at91_idle",
40 .owner = THIS_MODULE,
41 .states[0] = ARM_CPUIDLE_WFI_STATE,
42 .states[1] = {
43 .enter = at91_enter_idle,
44 .exit_latency = 10,
45 .target_residency = 10000,
46 .flags = CPUIDLE_FLAG_TIME_VALID,
47 .name = "RAM_SR",
48 .desc = "WFI and DDR Self Refresh",
49 },
50 .state_count = AT91_MAX_STATES,
51};
52
53/* Initialize CPU idle by registering the idle states */
54static int at91_cpuidle_probe(struct platform_device *dev)
55{
56 at91_standby = (void *)(dev->dev.platform_data);
57
58 return cpuidle_register(&at91_idle_driver, NULL);
59}
60
61static struct platform_driver at91_cpuidle_driver = {
62 .driver = {
63 .name = "cpuidle-at91",
64 .owner = THIS_MODULE,
65 },
66 .probe = at91_cpuidle_probe,
67};
68
69module_platform_driver(at91_cpuidle_driver);
diff --git a/drivers/cpuidle/cpuidle-ux500.c b/drivers/cpuidle/cpuidle-ux500.c
index e0564652af35..5e35804b1a95 100644
--- a/drivers/cpuidle/cpuidle-ux500.c
+++ b/drivers/cpuidle/cpuidle-ux500.c
@@ -111,7 +111,7 @@ static struct cpuidle_driver ux500_idle_driver = {
111 .state_count = 2, 111 .state_count = 2,
112}; 112};
113 113
114static int __init dbx500_cpuidle_probe(struct platform_device *pdev) 114static int dbx500_cpuidle_probe(struct platform_device *pdev)
115{ 115{
116 /* Configure wake up reasons */ 116 /* Configure wake up reasons */
117 prcmu_enable_wakeups(PRCMU_WAKEUP(ARM) | PRCMU_WAKEUP(RTC) | 117 prcmu_enable_wakeups(PRCMU_WAKEUP(ARM) | PRCMU_WAKEUP(RTC) |
diff --git a/drivers/cpuidle/cpuidle-zynq.c b/drivers/cpuidle/cpuidle-zynq.c
index 38e03a183591..aded75928028 100644
--- a/drivers/cpuidle/cpuidle-zynq.c
+++ b/drivers/cpuidle/cpuidle-zynq.c
@@ -28,7 +28,7 @@
28#include <linux/init.h> 28#include <linux/init.h>
29#include <linux/cpu_pm.h> 29#include <linux/cpu_pm.h>
30#include <linux/cpuidle.h> 30#include <linux/cpuidle.h>
31#include <linux/of.h> 31#include <linux/platform_device.h>
32#include <asm/proc-fns.h> 32#include <asm/proc-fns.h>
33#include <asm/cpuidle.h> 33#include <asm/cpuidle.h>
34 34
@@ -70,14 +70,19 @@ static struct cpuidle_driver zynq_idle_driver = {
70}; 70};
71 71
72/* Initialize CPU idle by registering the idle states */ 72/* Initialize CPU idle by registering the idle states */
73static int __init zynq_cpuidle_init(void) 73static int zynq_cpuidle_probe(struct platform_device *pdev)
74{ 74{
75 if (!of_machine_is_compatible("xlnx,zynq-7000"))
76 return -ENODEV;
77
78 pr_info("Xilinx Zynq CpuIdle Driver started\n"); 75 pr_info("Xilinx Zynq CpuIdle Driver started\n");
79 76
80 return cpuidle_register(&zynq_idle_driver, NULL); 77 return cpuidle_register(&zynq_idle_driver, NULL);
81} 78}
82 79
83device_initcall(zynq_cpuidle_init); 80static struct platform_driver zynq_cpuidle_driver = {
81 .driver = {
82 .name = "cpuidle-zynq",
83 .owner = THIS_MODULE,
84 },
85 .probe = zynq_cpuidle_probe,
86};
87
88module_platform_driver(zynq_cpuidle_driver);
diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
index d75040ddd2b3..2a991e468f78 100644
--- a/drivers/cpuidle/cpuidle.c
+++ b/drivers/cpuidle/cpuidle.c
@@ -118,11 +118,9 @@ int cpuidle_idle_call(void)
118 struct cpuidle_device *dev = __this_cpu_read(cpuidle_devices); 118 struct cpuidle_device *dev = __this_cpu_read(cpuidle_devices);
119 struct cpuidle_driver *drv; 119 struct cpuidle_driver *drv;
120 int next_state, entered_state; 120 int next_state, entered_state;
121 bool broadcast;
121 122
122 if (off) 123 if (off || !initialized)
123 return -ENODEV;
124
125 if (!initialized)
126 return -ENODEV; 124 return -ENODEV;
127 125
128 /* check if the device is ready */ 126 /* check if the device is ready */
@@ -144,9 +142,10 @@ int cpuidle_idle_call(void)
144 142
145 trace_cpu_idle_rcuidle(next_state, dev->cpu); 143 trace_cpu_idle_rcuidle(next_state, dev->cpu);
146 144
147 if (drv->states[next_state].flags & CPUIDLE_FLAG_TIMER_STOP) 145 broadcast = !!(drv->states[next_state].flags & CPUIDLE_FLAG_TIMER_STOP);
148 clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, 146
149 &dev->cpu); 147 if (broadcast)
148 clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu);
150 149
151 if (cpuidle_state_is_coupled(dev, drv, next_state)) 150 if (cpuidle_state_is_coupled(dev, drv, next_state))
152 entered_state = cpuidle_enter_state_coupled(dev, drv, 151 entered_state = cpuidle_enter_state_coupled(dev, drv,
@@ -154,9 +153,8 @@ int cpuidle_idle_call(void)
154 else 153 else
155 entered_state = cpuidle_enter_state(dev, drv, next_state); 154 entered_state = cpuidle_enter_state(dev, drv, next_state);
156 155
157 if (drv->states[next_state].flags & CPUIDLE_FLAG_TIMER_STOP) 156 if (broadcast)
158 clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, 157 clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu);
159 &dev->cpu);
160 158
161 trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, dev->cpu); 159 trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, dev->cpu);
162 160
@@ -228,45 +226,6 @@ void cpuidle_resume(void)
228 mutex_unlock(&cpuidle_lock); 226 mutex_unlock(&cpuidle_lock);
229} 227}
230 228
231#ifdef CONFIG_ARCH_HAS_CPU_RELAX
232static int poll_idle(struct cpuidle_device *dev,
233 struct cpuidle_driver *drv, int index)
234{
235 ktime_t t1, t2;
236 s64 diff;
237
238 t1 = ktime_get();
239 local_irq_enable();
240 while (!need_resched())
241 cpu_relax();
242
243 t2 = ktime_get();
244 diff = ktime_to_us(ktime_sub(t2, t1));
245 if (diff > INT_MAX)
246 diff = INT_MAX;
247
248 dev->last_residency = (int) diff;
249
250 return index;
251}
252
253static void poll_idle_init(struct cpuidle_driver *drv)
254{
255 struct cpuidle_state *state = &drv->states[0];
256
257 snprintf(state->name, CPUIDLE_NAME_LEN, "POLL");
258 snprintf(state->desc, CPUIDLE_DESC_LEN, "CPUIDLE CORE POLL IDLE");
259 state->exit_latency = 0;
260 state->target_residency = 0;
261 state->power_usage = -1;
262 state->flags = 0;
263 state->enter = poll_idle;
264 state->disabled = false;
265}
266#else
267static void poll_idle_init(struct cpuidle_driver *drv) {}
268#endif /* CONFIG_ARCH_HAS_CPU_RELAX */
269
270/** 229/**
271 * cpuidle_enable_device - enables idle PM for a CPU 230 * cpuidle_enable_device - enables idle PM for a CPU
272 * @dev: the CPU 231 * @dev: the CPU
@@ -296,8 +255,6 @@ int cpuidle_enable_device(struct cpuidle_device *dev)
296 if (!dev->state_count) 255 if (!dev->state_count)
297 dev->state_count = drv->state_count; 256 dev->state_count = drv->state_count;
298 257
299 poll_idle_init(drv);
300
301 ret = cpuidle_add_device_sysfs(dev); 258 ret = cpuidle_add_device_sysfs(dev);
302 if (ret) 259 if (ret)
303 return ret; 260 return ret;
@@ -358,12 +315,10 @@ static void __cpuidle_unregister_device(struct cpuidle_device *dev)
358 module_put(drv->owner); 315 module_put(drv->owner);
359} 316}
360 317
361static int __cpuidle_device_init(struct cpuidle_device *dev) 318static void __cpuidle_device_init(struct cpuidle_device *dev)
362{ 319{
363 memset(dev->states_usage, 0, sizeof(dev->states_usage)); 320 memset(dev->states_usage, 0, sizeof(dev->states_usage));
364 dev->last_residency = 0; 321 dev->last_residency = 0;
365
366 return 0;
367} 322}
368 323
369/** 324/**
@@ -385,13 +340,12 @@ static int __cpuidle_register_device(struct cpuidle_device *dev)
385 list_add(&dev->device_list, &cpuidle_detected_devices); 340 list_add(&dev->device_list, &cpuidle_detected_devices);
386 341
387 ret = cpuidle_coupled_register_device(dev); 342 ret = cpuidle_coupled_register_device(dev);
388 if (ret) { 343 if (ret)
389 __cpuidle_unregister_device(dev); 344 __cpuidle_unregister_device(dev);
390 return ret; 345 else
391 } 346 dev->registered = 1;
392 347
393 dev->registered = 1; 348 return ret;
394 return 0;
395} 349}
396 350
397/** 351/**
@@ -410,9 +364,7 @@ int cpuidle_register_device(struct cpuidle_device *dev)
410 if (dev->registered) 364 if (dev->registered)
411 goto out_unlock; 365 goto out_unlock;
412 366
413 ret = __cpuidle_device_init(dev); 367 __cpuidle_device_init(dev);
414 if (ret)
415 goto out_unlock;
416 368
417 ret = __cpuidle_register_device(dev); 369 ret = __cpuidle_register_device(dev);
418 if (ret) 370 if (ret)
@@ -516,7 +468,7 @@ int cpuidle_register(struct cpuidle_driver *drv,
516 468
517#ifdef CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED 469#ifdef CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED
518 /* 470 /*
519 * On multiplatform for ARM, the coupled idle states could 471 * On multiplatform for ARM, the coupled idle states could be
520 * enabled in the kernel even if the cpuidle driver does not 472 * enabled in the kernel even if the cpuidle driver does not
521 * use it. Note, coupled_cpus is a struct copy. 473 * use it. Note, coupled_cpus is a struct copy.
522 */ 474 */
diff --git a/drivers/cpuidle/driver.c b/drivers/cpuidle/driver.c
index 6e11701f0fca..06dbe7c86199 100644
--- a/drivers/cpuidle/driver.c
+++ b/drivers/cpuidle/driver.c
@@ -10,6 +10,7 @@
10 10
11#include <linux/mutex.h> 11#include <linux/mutex.h>
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/sched.h>
13#include <linux/cpuidle.h> 14#include <linux/cpuidle.h>
14#include <linux/cpumask.h> 15#include <linux/cpumask.h>
15#include <linux/clockchips.h> 16#include <linux/clockchips.h>
@@ -56,7 +57,7 @@ static inline void __cpuidle_unset_driver(struct cpuidle_driver *drv)
56} 57}
57 58
58/** 59/**
59 * __cpuidle_set_driver - set per CPU driver variables the the given driver. 60 * __cpuidle_set_driver - set per CPU driver variables for the given driver.
60 * @drv: a valid pointer to a struct cpuidle_driver 61 * @drv: a valid pointer to a struct cpuidle_driver
61 * 62 *
62 * For each CPU in the driver's cpumask, unset the registered driver per CPU 63 * For each CPU in the driver's cpumask, unset the registered driver per CPU
@@ -132,7 +133,7 @@ static inline void __cpuidle_unset_driver(struct cpuidle_driver *drv)
132 * cpuidle_setup_broadcast_timer - enable/disable the broadcast timer 133 * cpuidle_setup_broadcast_timer - enable/disable the broadcast timer
133 * @arg: a void pointer used to match the SMP cross call API 134 * @arg: a void pointer used to match the SMP cross call API
134 * 135 *
135 * @arg is used as a value of type 'long' with on of the two values: 136 * @arg is used as a value of type 'long' with one of the two values:
136 * - CLOCK_EVT_NOTIFY_BROADCAST_ON 137 * - CLOCK_EVT_NOTIFY_BROADCAST_ON
137 * - CLOCK_EVT_NOTIFY_BROADCAST_OFF 138 * - CLOCK_EVT_NOTIFY_BROADCAST_OFF
138 * 139 *
@@ -149,10 +150,8 @@ static void cpuidle_setup_broadcast_timer(void *arg)
149/** 150/**
150 * __cpuidle_driver_init - initialize the driver's internal data 151 * __cpuidle_driver_init - initialize the driver's internal data
151 * @drv: a valid pointer to a struct cpuidle_driver 152 * @drv: a valid pointer to a struct cpuidle_driver
152 *
153 * Returns 0 on success, a negative error code otherwise.
154 */ 153 */
155static int __cpuidle_driver_init(struct cpuidle_driver *drv) 154static void __cpuidle_driver_init(struct cpuidle_driver *drv)
156{ 155{
157 int i; 156 int i;
158 157
@@ -169,20 +168,55 @@ static int __cpuidle_driver_init(struct cpuidle_driver *drv)
169 /* 168 /*
170 * Look for the timer stop flag in the different states, so that we know 169 * Look for the timer stop flag in the different states, so that we know
171 * if the broadcast timer has to be set up. The loop is in the reverse 170 * if the broadcast timer has to be set up. The loop is in the reverse
172 * order, because usually on of the the deeper states has this flag set. 171 * order, because usually one of the deeper states have this flag set.
173 */ 172 */
174 for (i = drv->state_count - 1; i >= 0 ; i--) { 173 for (i = drv->state_count - 1; i >= 0 ; i--) {
174 if (drv->states[i].flags & CPUIDLE_FLAG_TIMER_STOP) {
175 drv->bctimer = 1;
176 break;
177 }
178 }
179}
175 180
176 if (!(drv->states[i].flags & CPUIDLE_FLAG_TIMER_STOP)) 181#ifdef CONFIG_ARCH_HAS_CPU_RELAX
177 continue; 182static int poll_idle(struct cpuidle_device *dev,
183 struct cpuidle_driver *drv, int index)
184{
185 ktime_t t1, t2;
186 s64 diff;
178 187
179 drv->bctimer = 1; 188 t1 = ktime_get();
180 break; 189 local_irq_enable();
181 } 190 while (!need_resched())
191 cpu_relax();
182 192
183 return 0; 193 t2 = ktime_get();
194 diff = ktime_to_us(ktime_sub(t2, t1));
195 if (diff > INT_MAX)
196 diff = INT_MAX;
197
198 dev->last_residency = (int) diff;
199
200 return index;
184} 201}
185 202
203static void poll_idle_init(struct cpuidle_driver *drv)
204{
205 struct cpuidle_state *state = &drv->states[0];
206
207 snprintf(state->name, CPUIDLE_NAME_LEN, "POLL");
208 snprintf(state->desc, CPUIDLE_DESC_LEN, "CPUIDLE CORE POLL IDLE");
209 state->exit_latency = 0;
210 state->target_residency = 0;
211 state->power_usage = -1;
212 state->flags = 0;
213 state->enter = poll_idle;
214 state->disabled = false;
215}
216#else
217static void poll_idle_init(struct cpuidle_driver *drv) {}
218#endif /* !CONFIG_ARCH_HAS_CPU_RELAX */
219
186/** 220/**
187 * __cpuidle_register_driver: register the driver 221 * __cpuidle_register_driver: register the driver
188 * @drv: a valid pointer to a struct cpuidle_driver 222 * @drv: a valid pointer to a struct cpuidle_driver
@@ -206,9 +240,7 @@ static int __cpuidle_register_driver(struct cpuidle_driver *drv)
206 if (cpuidle_disabled()) 240 if (cpuidle_disabled())
207 return -ENODEV; 241 return -ENODEV;
208 242
209 ret = __cpuidle_driver_init(drv); 243 __cpuidle_driver_init(drv);
210 if (ret)
211 return ret;
212 244
213 ret = __cpuidle_set_driver(drv); 245 ret = __cpuidle_set_driver(drv);
214 if (ret) 246 if (ret)
@@ -218,6 +250,8 @@ static int __cpuidle_register_driver(struct cpuidle_driver *drv)
218 on_each_cpu_mask(drv->cpumask, cpuidle_setup_broadcast_timer, 250 on_each_cpu_mask(drv->cpumask, cpuidle_setup_broadcast_timer,
219 (void *)CLOCK_EVT_NOTIFY_BROADCAST_ON, 1); 251 (void *)CLOCK_EVT_NOTIFY_BROADCAST_ON, 1);
220 252
253 poll_idle_init(drv);
254
221 return 0; 255 return 0;
222} 256}
223 257
@@ -346,10 +380,11 @@ struct cpuidle_driver *cpuidle_driver_ref(void)
346 */ 380 */
347void cpuidle_driver_unref(void) 381void cpuidle_driver_unref(void)
348{ 382{
349 struct cpuidle_driver *drv = cpuidle_get_driver(); 383 struct cpuidle_driver *drv;
350 384
351 spin_lock(&cpuidle_driver_lock); 385 spin_lock(&cpuidle_driver_lock);
352 386
387 drv = cpuidle_get_driver();
353 if (drv && !WARN_ON(drv->refcnt <= 0)) 388 if (drv && !WARN_ON(drv->refcnt <= 0))
354 drv->refcnt--; 389 drv->refcnt--;
355 390
diff --git a/drivers/cpuidle/governor.c b/drivers/cpuidle/governor.c
index ea2f8e7aa24a..ca89412f5122 100644
--- a/drivers/cpuidle/governor.c
+++ b/drivers/cpuidle/governor.c
@@ -96,46 +96,3 @@ int cpuidle_register_governor(struct cpuidle_governor *gov)
96 96
97 return ret; 97 return ret;
98} 98}
99
100/**
101 * cpuidle_replace_governor - find a replacement governor
102 * @exclude_rating: the rating that will be skipped while looking for
103 * new governor.
104 */
105static struct cpuidle_governor *cpuidle_replace_governor(int exclude_rating)
106{
107 struct cpuidle_governor *gov;
108 struct cpuidle_governor *ret_gov = NULL;
109 unsigned int max_rating = 0;
110
111 list_for_each_entry(gov, &cpuidle_governors, governor_list) {
112 if (gov->rating == exclude_rating)
113 continue;
114 if (gov->rating > max_rating) {
115 max_rating = gov->rating;
116 ret_gov = gov;
117 }
118 }
119
120 return ret_gov;
121}
122
123/**
124 * cpuidle_unregister_governor - unregisters a governor
125 * @gov: the governor
126 */
127void cpuidle_unregister_governor(struct cpuidle_governor *gov)
128{
129 if (!gov)
130 return;
131
132 mutex_lock(&cpuidle_lock);
133 if (gov == cpuidle_curr_governor) {
134 struct cpuidle_governor *new_gov;
135 new_gov = cpuidle_replace_governor(gov->rating);
136 cpuidle_switch_governor(new_gov);
137 }
138 list_del(&gov->governor_list);
139 mutex_unlock(&cpuidle_lock);
140}
141
diff --git a/drivers/cpuidle/sysfs.c b/drivers/cpuidle/sysfs.c
index 8739cc05228c..e918b6d0caf7 100644
--- a/drivers/cpuidle/sysfs.c
+++ b/drivers/cpuidle/sysfs.c
@@ -52,11 +52,12 @@ static ssize_t show_current_driver(struct device *dev,
52 char *buf) 52 char *buf)
53{ 53{
54 ssize_t ret; 54 ssize_t ret;
55 struct cpuidle_driver *cpuidle_driver = cpuidle_get_driver(); 55 struct cpuidle_driver *drv;
56 56
57 spin_lock(&cpuidle_driver_lock); 57 spin_lock(&cpuidle_driver_lock);
58 if (cpuidle_driver) 58 drv = cpuidle_get_driver();
59 ret = sprintf(buf, "%s\n", cpuidle_driver->name); 59 if (drv)
60 ret = sprintf(buf, "%s\n", drv->name);
60 else 61 else
61 ret = sprintf(buf, "none\n"); 62 ret = sprintf(buf, "none\n");
62 spin_unlock(&cpuidle_driver_lock); 63 spin_unlock(&cpuidle_driver_lock);