aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/cpuidle
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@osg.samsung.com>2015-04-21 05:33:03 -0400
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>2015-04-21 08:44:55 -0400
commit64131a87f2aae2ed9e05d8227c5b009ca6c50d98 (patch)
treefdea23fd59216120bf54a48c60ca24489a733f14 /drivers/cpuidle
parent676ee36be04985062522804c2de04f0764212be6 (diff)
parent2c33ce009ca2389dbf0535d0672214d09738e35e (diff)
Merge branch 'drm-next-merged' of git://people.freedesktop.org/~airlied/linux into v4l_for_linus
* 'drm-next-merged' of git://people.freedesktop.org/~airlied/linux: (9717 commits) media-bus: Fixup RGB444_1X12, RGB565_1X16, and YUV8_1X24 media bus format hexdump: avoid warning in test function fs: take i_mutex during prepare_binprm for set[ug]id executables smp: Fix error case handling in smp_call_function_*() iommu-common: Fix PARISC compile-time warnings sparc: Make LDC use common iommu poll management functions sparc: Make sparc64 use scalable lib/iommu-common.c functions Break up monolithic iommu table/lock into finer graularity pools and lock sparc: Revert generic IOMMU allocator. tools/power turbostat: correct dumped pkg-cstate-limit value tools/power turbostat: calculate TSC frequency from CPUID(0x15) on SKL tools/power turbostat: correct DRAM RAPL units on recent Xeon processors tools/power turbostat: Initial Skylake support tools/power turbostat: Use $(CURDIR) instead of $(PWD) and add support for O= option in Makefile tools/power turbostat: modprobe msr, if needed tools/power turbostat: dump MSR_TURBO_RATIO_LIMIT2 tools/power turbostat: use new MSR_TURBO_RATIO_LIMIT names Bluetooth: hidp: Fix regression with older userspace and flags validation config: Enable NEED_DMA_MAP_STATE by default when SWIOTLB is selected perf/x86/intel/pt: Fix and clean up error handling in pt_event_add() ... That solves several merge conflicts: Documentation/DocBook/media/v4l/subdev-formats.xml Documentation/devicetree/bindings/vendor-prefixes.txt drivers/staging/media/mn88473/mn88473.c include/linux/kconfig.h include/uapi/linux/media-bus-format.h The ones at subdev-formats.xml and media-bus-format.h are not trivial. That's why we opted to merge from DRM.
Diffstat (limited to 'drivers/cpuidle')
-rw-r--r--drivers/cpuidle/Kconfig7
-rw-r--r--drivers/cpuidle/Kconfig.arm28
-rw-r--r--drivers/cpuidle/Kconfig.arm6413
-rw-r--r--drivers/cpuidle/Makefile5
-rw-r--r--drivers/cpuidle/cpuidle-arm.c (renamed from drivers/cpuidle/cpuidle-arm64.c)83
-rw-r--r--drivers/cpuidle/cpuidle-at91.c1
-rw-r--r--drivers/cpuidle/cpuidle-exynos.c1
-rw-r--r--drivers/cpuidle/cpuidle-kirkwood.c1
-rw-r--r--drivers/cpuidle/cpuidle-mvebu-v7.c12
-rw-r--r--drivers/cpuidle/cpuidle-ux500.c1
-rw-r--r--drivers/cpuidle/cpuidle-zynq.c1
-rw-r--r--drivers/cpuidle/cpuidle.c64
-rw-r--r--drivers/cpuidle/driver.c23
-rw-r--r--drivers/cpuidle/governors/menu.c8
-rw-r--r--drivers/cpuidle/sysfs.c5
15 files changed, 130 insertions, 123 deletions
diff --git a/drivers/cpuidle/Kconfig b/drivers/cpuidle/Kconfig
index c5029c1209b4..8c7930b5a65f 100644
--- a/drivers/cpuidle/Kconfig
+++ b/drivers/cpuidle/Kconfig
@@ -29,15 +29,10 @@ config DT_IDLE_STATES
29 bool 29 bool
30 30
31menu "ARM CPU Idle Drivers" 31menu "ARM CPU Idle Drivers"
32depends on ARM 32depends on ARM || ARM64
33source "drivers/cpuidle/Kconfig.arm" 33source "drivers/cpuidle/Kconfig.arm"
34endmenu 34endmenu
35 35
36menu "ARM64 CPU Idle Drivers"
37depends on ARM64
38source "drivers/cpuidle/Kconfig.arm64"
39endmenu
40
41menu "MIPS CPU Idle Drivers" 36menu "MIPS CPU Idle Drivers"
42depends on MIPS 37depends on MIPS
43source "drivers/cpuidle/Kconfig.mips" 38source "drivers/cpuidle/Kconfig.mips"
diff --git a/drivers/cpuidle/Kconfig.arm b/drivers/cpuidle/Kconfig.arm
index 8e07c9419153..21340e0be73e 100644
--- a/drivers/cpuidle/Kconfig.arm
+++ b/drivers/cpuidle/Kconfig.arm
@@ -1,10 +1,20 @@
1# 1#
2# ARM CPU Idle drivers 2# ARM CPU Idle drivers
3# 3#
4config ARM_CPUIDLE
5 bool "Generic ARM/ARM64 CPU idle Driver"
6 select DT_IDLE_STATES
7 help
8 Select this to enable generic cpuidle driver for ARM.
9 It provides a generic idle driver whose idle states are configured
10 at run-time through DT nodes. The CPUidle suspend backend is
11 initialized by calling the CPU operations init idle hook
12 provided by architecture code.
13
4config ARM_BIG_LITTLE_CPUIDLE 14config ARM_BIG_LITTLE_CPUIDLE
5 bool "Support for ARM big.LITTLE processors" 15 bool "Support for ARM big.LITTLE processors"
6 depends on ARCH_VEXPRESS_TC2_PM || ARCH_EXYNOS 16 depends on ARCH_VEXPRESS_TC2_PM || ARCH_EXYNOS
7 depends on MCPM 17 depends on MCPM && !ARM64
8 select ARM_CPU_SUSPEND 18 select ARM_CPU_SUSPEND
9 select CPU_IDLE_MULTIPLE_DRIVERS 19 select CPU_IDLE_MULTIPLE_DRIVERS
10 select DT_IDLE_STATES 20 select DT_IDLE_STATES
@@ -16,51 +26,51 @@ config ARM_BIG_LITTLE_CPUIDLE
16 26
17config ARM_CLPS711X_CPUIDLE 27config ARM_CLPS711X_CPUIDLE
18 bool "CPU Idle Driver for CLPS711X processors" 28 bool "CPU Idle Driver for CLPS711X processors"
19 depends on ARCH_CLPS711X || COMPILE_TEST 29 depends on ARCH_CLPS711X && !ARM64 || COMPILE_TEST
20 help 30 help
21 Select this to enable cpuidle on Cirrus Logic CLPS711X SOCs. 31 Select this to enable cpuidle on Cirrus Logic CLPS711X SOCs.
22 32
23config ARM_HIGHBANK_CPUIDLE 33config ARM_HIGHBANK_CPUIDLE
24 bool "CPU Idle Driver for Calxeda processors" 34 bool "CPU Idle Driver for Calxeda processors"
25 depends on ARM_PSCI 35 depends on ARM_PSCI && !ARM64
26 select ARM_CPU_SUSPEND 36 select ARM_CPU_SUSPEND
27 help 37 help
28 Select this to enable cpuidle on Calxeda processors. 38 Select this to enable cpuidle on Calxeda processors.
29 39
30config ARM_KIRKWOOD_CPUIDLE 40config ARM_KIRKWOOD_CPUIDLE
31 bool "CPU Idle Driver for Marvell Kirkwood SoCs" 41 bool "CPU Idle Driver for Marvell Kirkwood SoCs"
32 depends on MACH_KIRKWOOD 42 depends on MACH_KIRKWOOD && !ARM64
33 help 43 help
34 This adds the CPU Idle driver for Marvell Kirkwood SoCs. 44 This adds the CPU Idle driver for Marvell Kirkwood SoCs.
35 45
36config ARM_ZYNQ_CPUIDLE 46config ARM_ZYNQ_CPUIDLE
37 bool "CPU Idle Driver for Xilinx Zynq processors" 47 bool "CPU Idle Driver for Xilinx Zynq processors"
38 depends on ARCH_ZYNQ 48 depends on ARCH_ZYNQ && !ARM64
39 help 49 help
40 Select this to enable cpuidle on Xilinx Zynq processors. 50 Select this to enable cpuidle on Xilinx Zynq processors.
41 51
42config ARM_U8500_CPUIDLE 52config ARM_U8500_CPUIDLE
43 bool "Cpu Idle Driver for the ST-E u8500 processors" 53 bool "Cpu Idle Driver for the ST-E u8500 processors"
44 depends on ARCH_U8500 54 depends on ARCH_U8500 && !ARM64
45 help 55 help
46 Select this to enable cpuidle for ST-E u8500 processors 56 Select this to enable cpuidle for ST-E u8500 processors
47 57
48config ARM_AT91_CPUIDLE 58config ARM_AT91_CPUIDLE
49 bool "Cpu Idle Driver for the AT91 processors" 59 bool "Cpu Idle Driver for the AT91 processors"
50 default y 60 default y
51 depends on ARCH_AT91 61 depends on ARCH_AT91 && !ARM64
52 help 62 help
53 Select this to enable cpuidle for AT91 processors 63 Select this to enable cpuidle for AT91 processors
54 64
55config ARM_EXYNOS_CPUIDLE 65config ARM_EXYNOS_CPUIDLE
56 bool "Cpu Idle Driver for the Exynos processors" 66 bool "Cpu Idle Driver for the Exynos processors"
57 depends on ARCH_EXYNOS 67 depends on ARCH_EXYNOS && !ARM64
58 select ARCH_NEEDS_CPU_IDLE_COUPLED if SMP 68 select ARCH_NEEDS_CPU_IDLE_COUPLED if SMP
59 help 69 help
60 Select this to enable cpuidle for Exynos processors 70 Select this to enable cpuidle for Exynos processors
61 71
62config ARM_MVEBU_V7_CPUIDLE 72config ARM_MVEBU_V7_CPUIDLE
63 bool "CPU Idle Driver for mvebu v7 family processors" 73 bool "CPU Idle Driver for mvebu v7 family processors"
64 depends on ARCH_MVEBU 74 depends on ARCH_MVEBU && !ARM64
65 help 75 help
66 Select this to enable cpuidle on Armada 370, 38x and XP processors. 76 Select this to enable cpuidle on Armada 370, 38x and XP processors.
diff --git a/drivers/cpuidle/Kconfig.arm64 b/drivers/cpuidle/Kconfig.arm64
deleted file mode 100644
index 6effb3656735..000000000000
--- a/drivers/cpuidle/Kconfig.arm64
+++ /dev/null
@@ -1,13 +0,0 @@
1#
2# ARM64 CPU Idle drivers
3#
4
5config ARM64_CPUIDLE
6 bool "Generic ARM64 CPU idle Driver"
7 select DT_IDLE_STATES
8 help
9 Select this to enable generic cpuidle driver for ARM64.
10 It provides a generic idle driver whose idle states are configured
11 at run-time through DT nodes. The CPUidle suspend backend is
12 initialized by calling the CPU operations init idle hook
13 provided by architecture code.
diff --git a/drivers/cpuidle/Makefile b/drivers/cpuidle/Makefile
index 4d177b916f75..3ba81b1dffad 100644
--- a/drivers/cpuidle/Makefile
+++ b/drivers/cpuidle/Makefile
@@ -17,16 +17,13 @@ obj-$(CONFIG_ARM_ZYNQ_CPUIDLE) += cpuidle-zynq.o
17obj-$(CONFIG_ARM_U8500_CPUIDLE) += cpuidle-ux500.o 17obj-$(CONFIG_ARM_U8500_CPUIDLE) += cpuidle-ux500.o
18obj-$(CONFIG_ARM_AT91_CPUIDLE) += cpuidle-at91.o 18obj-$(CONFIG_ARM_AT91_CPUIDLE) += cpuidle-at91.o
19obj-$(CONFIG_ARM_EXYNOS_CPUIDLE) += cpuidle-exynos.o 19obj-$(CONFIG_ARM_EXYNOS_CPUIDLE) += cpuidle-exynos.o
20obj-$(CONFIG_ARM_CPUIDLE) += cpuidle-arm.o
20 21
21############################################################################### 22###############################################################################
22# MIPS drivers 23# MIPS drivers
23obj-$(CONFIG_MIPS_CPS_CPUIDLE) += cpuidle-cps.o 24obj-$(CONFIG_MIPS_CPS_CPUIDLE) += cpuidle-cps.o
24 25
25############################################################################### 26###############################################################################
26# ARM64 drivers
27obj-$(CONFIG_ARM64_CPUIDLE) += cpuidle-arm64.o
28
29###############################################################################
30# POWERPC drivers 27# POWERPC drivers
31obj-$(CONFIG_PSERIES_CPUIDLE) += cpuidle-pseries.o 28obj-$(CONFIG_PSERIES_CPUIDLE) += cpuidle-pseries.o
32obj-$(CONFIG_POWERNV_CPUIDLE) += cpuidle-powernv.o 29obj-$(CONFIG_POWERNV_CPUIDLE) += cpuidle-powernv.o
diff --git a/drivers/cpuidle/cpuidle-arm64.c b/drivers/cpuidle/cpuidle-arm.c
index 39a2c62716c3..545069d5fdfb 100644
--- a/drivers/cpuidle/cpuidle-arm64.c
+++ b/drivers/cpuidle/cpuidle-arm.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * ARM64 generic CPU idle driver. 2 * ARM/ARM64 generic CPU idle driver.
3 * 3 *
4 * Copyright (C) 2014 ARM Ltd. 4 * Copyright (C) 2014 ARM Ltd.
5 * Author: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> 5 * Author: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
@@ -9,7 +9,7 @@
9 * published by the Free Software Foundation. 9 * published by the Free Software Foundation.
10 */ 10 */
11 11
12#define pr_fmt(fmt) "CPUidle arm64: " fmt 12#define pr_fmt(fmt) "CPUidle arm: " fmt
13 13
14#include <linux/cpuidle.h> 14#include <linux/cpuidle.h>
15#include <linux/cpumask.h> 15#include <linux/cpumask.h>
@@ -17,13 +17,14 @@
17#include <linux/kernel.h> 17#include <linux/kernel.h>
18#include <linux/module.h> 18#include <linux/module.h>
19#include <linux/of.h> 19#include <linux/of.h>
20#include <linux/slab.h>
20 21
21#include <asm/cpuidle.h> 22#include <asm/cpuidle.h>
22 23
23#include "dt_idle_states.h" 24#include "dt_idle_states.h"
24 25
25/* 26/*
26 * arm64_enter_idle_state - Programs CPU to enter the specified state 27 * arm_enter_idle_state - Programs CPU to enter the specified state
27 * 28 *
28 * dev: cpuidle device 29 * dev: cpuidle device
29 * drv: cpuidle driver 30 * drv: cpuidle driver
@@ -32,8 +33,8 @@
32 * Called from the CPUidle framework to program the device to the 33 * Called from the CPUidle framework to program the device to the
33 * specified target state selected by the governor. 34 * specified target state selected by the governor.
34 */ 35 */
35static int arm64_enter_idle_state(struct cpuidle_device *dev, 36static int arm_enter_idle_state(struct cpuidle_device *dev,
36 struct cpuidle_driver *drv, int idx) 37 struct cpuidle_driver *drv, int idx)
37{ 38{
38 int ret; 39 int ret;
39 40
@@ -49,7 +50,7 @@ static int arm64_enter_idle_state(struct cpuidle_device *dev,
49 * call the CPU ops suspend protocol with idle index as a 50 * call the CPU ops suspend protocol with idle index as a
50 * parameter. 51 * parameter.
51 */ 52 */
52 ret = cpu_suspend(idx); 53 arm_cpuidle_suspend(idx);
53 54
54 cpu_pm_exit(); 55 cpu_pm_exit();
55 } 56 }
@@ -57,8 +58,8 @@ static int arm64_enter_idle_state(struct cpuidle_device *dev,
57 return ret ? -1 : idx; 58 return ret ? -1 : idx;
58} 59}
59 60
60static struct cpuidle_driver arm64_idle_driver = { 61static struct cpuidle_driver arm_idle_driver = {
61 .name = "arm64_idle", 62 .name = "arm_idle",
62 .owner = THIS_MODULE, 63 .owner = THIS_MODULE,
63 /* 64 /*
64 * State at index 0 is standby wfi and considered standard 65 * State at index 0 is standby wfi and considered standard
@@ -68,32 +69,33 @@ static struct cpuidle_driver arm64_idle_driver = {
68 * handler for idle state index 0. 69 * handler for idle state index 0.
69 */ 70 */
70 .states[0] = { 71 .states[0] = {
71 .enter = arm64_enter_idle_state, 72 .enter = arm_enter_idle_state,
72 .exit_latency = 1, 73 .exit_latency = 1,
73 .target_residency = 1, 74 .target_residency = 1,
74 .power_usage = UINT_MAX, 75 .power_usage = UINT_MAX,
75 .name = "WFI", 76 .name = "WFI",
76 .desc = "ARM64 WFI", 77 .desc = "ARM WFI",
77 } 78 }
78}; 79};
79 80
80static const struct of_device_id arm64_idle_state_match[] __initconst = { 81static const struct of_device_id arm_idle_state_match[] __initconst = {
81 { .compatible = "arm,idle-state", 82 { .compatible = "arm,idle-state",
82 .data = arm64_enter_idle_state }, 83 .data = arm_enter_idle_state },
83 { }, 84 { },
84}; 85};
85 86
86/* 87/*
87 * arm64_idle_init 88 * arm_idle_init
88 * 89 *
89 * Registers the arm64 specific cpuidle driver with the cpuidle 90 * Registers the arm specific cpuidle driver with the cpuidle
90 * framework. It relies on core code to parse the idle states 91 * framework. It relies on core code to parse the idle states
91 * and initialize them using driver data structures accordingly. 92 * and initialize them using driver data structures accordingly.
92 */ 93 */
93static int __init arm64_idle_init(void) 94static int __init arm_idle_init(void)
94{ 95{
95 int cpu, ret; 96 int cpu, ret;
96 struct cpuidle_driver *drv = &arm64_idle_driver; 97 struct cpuidle_driver *drv = &arm_idle_driver;
98 struct cpuidle_device *dev;
97 99
98 /* 100 /*
99 * Initialize idle states data, starting at index 1. 101 * Initialize idle states data, starting at index 1.
@@ -101,22 +103,61 @@ static int __init arm64_idle_init(void)
101 * let the driver initialization fail accordingly since there is no 103 * let the driver initialization fail accordingly since there is no
102 * reason to initialize the idle driver if only wfi is supported. 104 * reason to initialize the idle driver if only wfi is supported.
103 */ 105 */
104 ret = dt_init_idle_driver(drv, arm64_idle_state_match, 1); 106 ret = dt_init_idle_driver(drv, arm_idle_state_match, 1);
105 if (ret <= 0) 107 if (ret <= 0)
106 return ret ? : -ENODEV; 108 return ret ? : -ENODEV;
107 109
110 ret = cpuidle_register_driver(drv);
111 if (ret) {
112 pr_err("Failed to register cpuidle driver\n");
113 return ret;
114 }
115
108 /* 116 /*
109 * Call arch CPU operations in order to initialize 117 * Call arch CPU operations in order to initialize
110 * idle states suspend back-end specific data 118 * idle states suspend back-end specific data
111 */ 119 */
112 for_each_possible_cpu(cpu) { 120 for_each_possible_cpu(cpu) {
113 ret = cpu_init_idle(cpu); 121 ret = arm_cpuidle_init(cpu);
122
123 /*
124 * Skip the cpuidle device initialization if the reported
125 * failure is a HW misconfiguration/breakage (-ENXIO).
126 */
127 if (ret == -ENXIO)
128 continue;
129
114 if (ret) { 130 if (ret) {
115 pr_err("CPU %d failed to init idle CPU ops\n", cpu); 131 pr_err("CPU %d failed to init idle CPU ops\n", cpu);
116 return ret; 132 goto out_fail;
133 }
134
135 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
136 if (!dev) {
137 pr_err("Failed to allocate cpuidle device\n");
138 goto out_fail;
139 }
140 dev->cpu = cpu;
141
142 ret = cpuidle_register_device(dev);
143 if (ret) {
144 pr_err("Failed to register cpuidle device for CPU %d\n",
145 cpu);
146 kfree(dev);
147 goto out_fail;
117 } 148 }
118 } 149 }
119 150
120 return cpuidle_register(drv, NULL); 151 return 0;
152out_fail:
153 while (--cpu >= 0) {
154 dev = per_cpu(cpuidle_devices, cpu);
155 cpuidle_unregister_device(dev);
156 kfree(dev);
157 }
158
159 cpuidle_unregister_driver(drv);
160
161 return ret;
121} 162}
122device_initcall(arm64_idle_init); 163device_initcall(arm_idle_init);
diff --git a/drivers/cpuidle/cpuidle-at91.c b/drivers/cpuidle/cpuidle-at91.c
index aae7bfc1ea36..f2446c78d87c 100644
--- a/drivers/cpuidle/cpuidle-at91.c
+++ b/drivers/cpuidle/cpuidle-at91.c
@@ -19,7 +19,6 @@
19#include <linux/cpuidle.h> 19#include <linux/cpuidle.h>
20#include <linux/io.h> 20#include <linux/io.h>
21#include <linux/export.h> 21#include <linux/export.h>
22#include <asm/proc-fns.h>
23#include <asm/cpuidle.h> 22#include <asm/cpuidle.h>
24 23
25#define AT91_MAX_STATES 2 24#define AT91_MAX_STATES 2
diff --git a/drivers/cpuidle/cpuidle-exynos.c b/drivers/cpuidle/cpuidle-exynos.c
index 26f5f29fdb03..0c06ea2f50bb 100644
--- a/drivers/cpuidle/cpuidle-exynos.c
+++ b/drivers/cpuidle/cpuidle-exynos.c
@@ -19,7 +19,6 @@
19#include <linux/of.h> 19#include <linux/of.h>
20#include <linux/platform_data/cpuidle-exynos.h> 20#include <linux/platform_data/cpuidle-exynos.h>
21 21
22#include <asm/proc-fns.h>
23#include <asm/suspend.h> 22#include <asm/suspend.h>
24#include <asm/cpuidle.h> 23#include <asm/cpuidle.h>
25 24
diff --git a/drivers/cpuidle/cpuidle-kirkwood.c b/drivers/cpuidle/cpuidle-kirkwood.c
index cea0a6c4b1db..d23d8f468c12 100644
--- a/drivers/cpuidle/cpuidle-kirkwood.c
+++ b/drivers/cpuidle/cpuidle-kirkwood.c
@@ -21,7 +21,6 @@
21#include <linux/cpuidle.h> 21#include <linux/cpuidle.h>
22#include <linux/io.h> 22#include <linux/io.h>
23#include <linux/export.h> 23#include <linux/export.h>
24#include <asm/proc-fns.h>
25#include <asm/cpuidle.h> 24#include <asm/cpuidle.h>
26 25
27#define KIRKWOOD_MAX_STATES 2 26#define KIRKWOOD_MAX_STATES 2
diff --git a/drivers/cpuidle/cpuidle-mvebu-v7.c b/drivers/cpuidle/cpuidle-mvebu-v7.c
index 38e68618513a..980151f34707 100644
--- a/drivers/cpuidle/cpuidle-mvebu-v7.c
+++ b/drivers/cpuidle/cpuidle-mvebu-v7.c
@@ -37,11 +37,11 @@ static int mvebu_v7_enter_idle(struct cpuidle_device *dev,
37 deepidle = true; 37 deepidle = true;
38 38
39 ret = mvebu_v7_cpu_suspend(deepidle); 39 ret = mvebu_v7_cpu_suspend(deepidle);
40 cpu_pm_exit();
41
40 if (ret) 42 if (ret)
41 return ret; 43 return ret;
42 44
43 cpu_pm_exit();
44
45 return index; 45 return index;
46} 46}
47 47
@@ -50,17 +50,17 @@ static struct cpuidle_driver armadaxp_idle_driver = {
50 .states[0] = ARM_CPUIDLE_WFI_STATE, 50 .states[0] = ARM_CPUIDLE_WFI_STATE,
51 .states[1] = { 51 .states[1] = {
52 .enter = mvebu_v7_enter_idle, 52 .enter = mvebu_v7_enter_idle,
53 .exit_latency = 10, 53 .exit_latency = 100,
54 .power_usage = 50, 54 .power_usage = 50,
55 .target_residency = 100, 55 .target_residency = 1000,
56 .name = "MV CPU IDLE", 56 .name = "MV CPU IDLE",
57 .desc = "CPU power down", 57 .desc = "CPU power down",
58 }, 58 },
59 .states[2] = { 59 .states[2] = {
60 .enter = mvebu_v7_enter_idle, 60 .enter = mvebu_v7_enter_idle,
61 .exit_latency = 100, 61 .exit_latency = 1000,
62 .power_usage = 5, 62 .power_usage = 5,
63 .target_residency = 1000, 63 .target_residency = 10000,
64 .flags = MVEBU_V7_FLAG_DEEP_IDLE, 64 .flags = MVEBU_V7_FLAG_DEEP_IDLE,
65 .name = "MV CPU DEEP IDLE", 65 .name = "MV CPU DEEP IDLE",
66 .desc = "CPU and L2 Fabric power down", 66 .desc = "CPU and L2 Fabric power down",
diff --git a/drivers/cpuidle/cpuidle-ux500.c b/drivers/cpuidle/cpuidle-ux500.c
index 66f81e410f0d..8bf895c0017d 100644
--- a/drivers/cpuidle/cpuidle-ux500.c
+++ b/drivers/cpuidle/cpuidle-ux500.c
@@ -19,7 +19,6 @@
19#include <linux/platform_device.h> 19#include <linux/platform_device.h>
20 20
21#include <asm/cpuidle.h> 21#include <asm/cpuidle.h>
22#include <asm/proc-fns.h>
23 22
24static atomic_t master = ATOMIC_INIT(0); 23static atomic_t master = ATOMIC_INIT(0);
25static DEFINE_SPINLOCK(master_lock); 24static DEFINE_SPINLOCK(master_lock);
diff --git a/drivers/cpuidle/cpuidle-zynq.c b/drivers/cpuidle/cpuidle-zynq.c
index 002b8c9f98f5..543292b1d38e 100644
--- a/drivers/cpuidle/cpuidle-zynq.c
+++ b/drivers/cpuidle/cpuidle-zynq.c
@@ -28,7 +28,6 @@
28#include <linux/init.h> 28#include <linux/init.h>
29#include <linux/cpuidle.h> 29#include <linux/cpuidle.h>
30#include <linux/platform_device.h> 30#include <linux/platform_device.h>
31#include <asm/proc-fns.h>
32#include <asm/cpuidle.h> 31#include <asm/cpuidle.h>
33 32
34#define ZYNQ_MAX_STATES 2 33#define ZYNQ_MAX_STATES 2
diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
index 4d534582514e..7a73a279e179 100644
--- a/drivers/cpuidle/cpuidle.c
+++ b/drivers/cpuidle/cpuidle.c
@@ -44,6 +44,12 @@ void disable_cpuidle(void)
44 off = 1; 44 off = 1;
45} 45}
46 46
47bool cpuidle_not_available(struct cpuidle_driver *drv,
48 struct cpuidle_device *dev)
49{
50 return off || !initialized || !drv || !dev || !dev->enabled;
51}
52
47/** 53/**
48 * cpuidle_play_dead - cpu off-lining 54 * cpuidle_play_dead - cpu off-lining
49 * 55 *
@@ -66,14 +72,8 @@ int cpuidle_play_dead(void)
66 return -ENODEV; 72 return -ENODEV;
67} 73}
68 74
69/** 75static int find_deepest_state(struct cpuidle_driver *drv,
70 * cpuidle_find_deepest_state - Find deepest state meeting specific conditions. 76 struct cpuidle_device *dev, bool freeze)
71 * @drv: cpuidle driver for the given CPU.
72 * @dev: cpuidle device for the given CPU.
73 * @freeze: Whether or not the state should be suitable for suspend-to-idle.
74 */
75static int cpuidle_find_deepest_state(struct cpuidle_driver *drv,
76 struct cpuidle_device *dev, bool freeze)
77{ 77{
78 unsigned int latency_req = 0; 78 unsigned int latency_req = 0;
79 int i, ret = freeze ? -1 : CPUIDLE_DRIVER_STATE_START - 1; 79 int i, ret = freeze ? -1 : CPUIDLE_DRIVER_STATE_START - 1;
@@ -92,6 +92,17 @@ static int cpuidle_find_deepest_state(struct cpuidle_driver *drv,
92 return ret; 92 return ret;
93} 93}
94 94
95/**
96 * cpuidle_find_deepest_state - Find the deepest available idle state.
97 * @drv: cpuidle driver for the given CPU.
98 * @dev: cpuidle device for the given CPU.
99 */
100int cpuidle_find_deepest_state(struct cpuidle_driver *drv,
101 struct cpuidle_device *dev)
102{
103 return find_deepest_state(drv, dev, false);
104}
105
95static void enter_freeze_proper(struct cpuidle_driver *drv, 106static void enter_freeze_proper(struct cpuidle_driver *drv,
96 struct cpuidle_device *dev, int index) 107 struct cpuidle_device *dev, int index)
97{ 108{
@@ -113,15 +124,14 @@ static void enter_freeze_proper(struct cpuidle_driver *drv,
113 124
114/** 125/**
115 * cpuidle_enter_freeze - Enter an idle state suitable for suspend-to-idle. 126 * cpuidle_enter_freeze - Enter an idle state suitable for suspend-to-idle.
127 * @drv: cpuidle driver for the given CPU.
128 * @dev: cpuidle device for the given CPU.
116 * 129 *
117 * If there are states with the ->enter_freeze callback, find the deepest of 130 * If there are states with the ->enter_freeze callback, find the deepest of
118 * them and enter it with frozen tick. Otherwise, find the deepest state 131 * them and enter it with frozen tick.
119 * available and enter it normally.
120 */ 132 */
121void cpuidle_enter_freeze(void) 133int cpuidle_enter_freeze(struct cpuidle_driver *drv, struct cpuidle_device *dev)
122{ 134{
123 struct cpuidle_device *dev = __this_cpu_read(cpuidle_devices);
124 struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev);
125 int index; 135 int index;
126 136
127 /* 137 /*
@@ -129,24 +139,11 @@ void cpuidle_enter_freeze(void)
129 * that interrupts won't be enabled when it exits and allows the tick to 139 * that interrupts won't be enabled when it exits and allows the tick to
130 * be frozen safely. 140 * be frozen safely.
131 */ 141 */
132 index = cpuidle_find_deepest_state(drv, dev, true); 142 index = find_deepest_state(drv, dev, true);
133 if (index >= 0) {
134 enter_freeze_proper(drv, dev, index);
135 return;
136 }
137
138 /*
139 * It is not safe to freeze the tick, find the deepest state available
140 * at all and try to enter it normally.
141 */
142 index = cpuidle_find_deepest_state(drv, dev, false);
143 if (index >= 0) 143 if (index >= 0)
144 cpuidle_enter(drv, dev, index); 144 enter_freeze_proper(drv, dev, index);
145 else
146 arch_cpu_idle();
147 145
148 /* Interrupts are enabled again here. */ 146 return index;
149 local_irq_disable();
150} 147}
151 148
152/** 149/**
@@ -205,12 +202,6 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv,
205 */ 202 */
206int cpuidle_select(struct cpuidle_driver *drv, struct cpuidle_device *dev) 203int cpuidle_select(struct cpuidle_driver *drv, struct cpuidle_device *dev)
207{ 204{
208 if (off || !initialized)
209 return -ENODEV;
210
211 if (!drv || !dev || !dev->enabled)
212 return -EBUSY;
213
214 return cpuidle_curr_governor->select(drv, dev); 205 return cpuidle_curr_governor->select(drv, dev);
215} 206}
216 207
@@ -339,9 +330,6 @@ int cpuidle_enable_device(struct cpuidle_device *dev)
339 if (!dev->registered) 330 if (!dev->registered)
340 return -EINVAL; 331 return -EINVAL;
341 332
342 if (!dev->state_count)
343 dev->state_count = drv->state_count;
344
345 ret = cpuidle_add_device_sysfs(dev); 333 ret = cpuidle_add_device_sysfs(dev);
346 if (ret) 334 if (ret)
347 return ret; 335 return ret;
diff --git a/drivers/cpuidle/driver.c b/drivers/cpuidle/driver.c
index 2697e87d5b34..5db147859b90 100644
--- a/drivers/cpuidle/driver.c
+++ b/drivers/cpuidle/driver.c
@@ -13,7 +13,7 @@
13#include <linux/sched.h> 13#include <linux/sched.h>
14#include <linux/cpuidle.h> 14#include <linux/cpuidle.h>
15#include <linux/cpumask.h> 15#include <linux/cpumask.h>
16#include <linux/clockchips.h> 16#include <linux/tick.h>
17 17
18#include "cpuidle.h" 18#include "cpuidle.h"
19 19
@@ -130,21 +130,20 @@ static inline void __cpuidle_unset_driver(struct cpuidle_driver *drv)
130#endif 130#endif
131 131
132/** 132/**
133 * cpuidle_setup_broadcast_timer - enable/disable the broadcast timer 133 * cpuidle_setup_broadcast_timer - enable/disable the broadcast timer on a cpu
134 * @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
135 * 135 *
136 * @arg is used as a value of type 'long' with one of the two values: 136 * If @arg is NULL broadcast is disabled otherwise enabled
137 * - CLOCK_EVT_NOTIFY_BROADCAST_ON
138 * - CLOCK_EVT_NOTIFY_BROADCAST_OFF
139 * 137 *
140 * Set the broadcast timer notification for the current CPU. This function 138 * This function is executed per CPU by an SMP cross call. It's not
141 * is executed per CPU by an SMP cross call. It not supposed to be called 139 * supposed to be called directly.
142 * directly.
143 */ 140 */
144static void cpuidle_setup_broadcast_timer(void *arg) 141static void cpuidle_setup_broadcast_timer(void *arg)
145{ 142{
146 int cpu = smp_processor_id(); 143 if (arg)
147 clockevents_notify((long)(arg), &cpu); 144 tick_broadcast_enable();
145 else
146 tick_broadcast_disable();
148} 147}
149 148
150/** 149/**
@@ -239,7 +238,7 @@ static int __cpuidle_register_driver(struct cpuidle_driver *drv)
239 238
240 if (drv->bctimer) 239 if (drv->bctimer)
241 on_each_cpu_mask(drv->cpumask, cpuidle_setup_broadcast_timer, 240 on_each_cpu_mask(drv->cpumask, cpuidle_setup_broadcast_timer,
242 (void *)CLOCK_EVT_NOTIFY_BROADCAST_ON, 1); 241 (void *)1, 1);
243 242
244 poll_idle_init(drv); 243 poll_idle_init(drv);
245 244
@@ -263,7 +262,7 @@ static void __cpuidle_unregister_driver(struct cpuidle_driver *drv)
263 if (drv->bctimer) { 262 if (drv->bctimer) {
264 drv->bctimer = 0; 263 drv->bctimer = 0;
265 on_each_cpu_mask(drv->cpumask, cpuidle_setup_broadcast_timer, 264 on_each_cpu_mask(drv->cpumask, cpuidle_setup_broadcast_timer,
266 (void *)CLOCK_EVT_NOTIFY_BROADCAST_OFF, 1); 265 NULL, 1);
267 } 266 }
268 267
269 __cpuidle_unset_driver(drv); 268 __cpuidle_unset_driver(drv);
diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c
index 40580794e23d..b8a5fa15ca24 100644
--- a/drivers/cpuidle/governors/menu.c
+++ b/drivers/cpuidle/governors/menu.c
@@ -190,12 +190,6 @@ static DEFINE_PER_CPU(struct menu_device, menu_devices);
190 190
191static void menu_update(struct cpuidle_driver *drv, struct cpuidle_device *dev); 191static void menu_update(struct cpuidle_driver *drv, struct cpuidle_device *dev);
192 192
193/* This implements DIV_ROUND_CLOSEST but avoids 64 bit division */
194static u64 div_round64(u64 dividend, u32 divisor)
195{
196 return div_u64(dividend + (divisor / 2), divisor);
197}
198
199/* 193/*
200 * Try detecting repeating patterns by keeping track of the last 8 194 * Try detecting repeating patterns by keeping track of the last 8
201 * intervals, and checking if the standard deviation of that set 195 * intervals, and checking if the standard deviation of that set
@@ -317,7 +311,7 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev)
317 * operands are 32 bits. 311 * operands are 32 bits.
318 * Make sure to round up for half microseconds. 312 * Make sure to round up for half microseconds.
319 */ 313 */
320 data->predicted_us = div_round64((uint64_t)data->next_timer_us * 314 data->predicted_us = DIV_ROUND_CLOSEST_ULL((uint64_t)data->next_timer_us *
321 data->correction_factor[data->bucket], 315 data->correction_factor[data->bucket],
322 RESOLUTION * DECAY); 316 RESOLUTION * DECAY);
323 317
diff --git a/drivers/cpuidle/sysfs.c b/drivers/cpuidle/sysfs.c
index 97c5903b4606..832a2c3f01ff 100644
--- a/drivers/cpuidle/sysfs.c
+++ b/drivers/cpuidle/sysfs.c
@@ -401,7 +401,7 @@ static int cpuidle_add_state_sysfs(struct cpuidle_device *device)
401 struct cpuidle_driver *drv = cpuidle_get_cpu_driver(device); 401 struct cpuidle_driver *drv = cpuidle_get_cpu_driver(device);
402 402
403 /* state statistics */ 403 /* state statistics */
404 for (i = 0; i < device->state_count; i++) { 404 for (i = 0; i < drv->state_count; i++) {
405 kobj = kzalloc(sizeof(struct cpuidle_state_kobj), GFP_KERNEL); 405 kobj = kzalloc(sizeof(struct cpuidle_state_kobj), GFP_KERNEL);
406 if (!kobj) 406 if (!kobj)
407 goto error_state; 407 goto error_state;
@@ -433,9 +433,10 @@ error_state:
433 */ 433 */
434static void cpuidle_remove_state_sysfs(struct cpuidle_device *device) 434static void cpuidle_remove_state_sysfs(struct cpuidle_device *device)
435{ 435{
436 struct cpuidle_driver *drv = cpuidle_get_cpu_driver(device);
436 int i; 437 int i;
437 438
438 for (i = 0; i < device->state_count; i++) 439 for (i = 0; i < drv->state_count; i++)
439 cpuidle_free_state_kobj(device, i); 440 cpuidle_free_state_kobj(device, i);
440} 441}
441 442