aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-03-30 19:45:38 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-03-30 19:45:39 -0400
commita335750b9a039a9d4cd727cdccacfb90fd63c4e8 (patch)
tree8f3198984fb75fe494e771d9431f6799228623c5 /arch/arm
parent10f3cb41d48ab30f5c754b30eea557371892b4c2 (diff)
parentd326f44e5f2204c7a24db69bfc6dd3fe5f86182b (diff)
Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux
Pull ACPI & Power Management changes from Len Brown: - ACPI 5.0 after-ripples, ACPICA/Linux divergence cleanup - cpuidle evolving, more ARM use - thermal sub-system evolving, ditto - assorted other PM bits Fix up conflicts in various cpuidle implementations due to ARM cpuidle cleanups (ARM at91 self-refresh and cpu idle code rewritten into "standby" in asm conflicting with the consolidation of cpuidle time keeping), trivial SH include file context conflict and RCU tracing fixes in generic code. * 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux: (77 commits) ACPI throttling: fix endian bug in acpi_read_throttling_status() Disable MCP limit exceeded messages from Intel IPS driver ACPI video: Don't start video device until its associated input device has been allocated ACPI video: Harden video bus adding. ACPI: Add support for exposing BGRT data ACPI: export acpi_kobj ACPI: Fix logic for removing mappings in 'acpi_unmap' CPER failed to handle generic error records with multiple sections ACPI: Clean redundant codes in scan.c ACPI: Fix unprotected smp_processor_id() in acpi_processor_cst_has_changed() ACPI: consistently use should_use_kmap() PNPACPI: Fix device ref leaking in acpi_pnp_match ACPI: Fix use-after-free in acpi_map_lsapic ACPI: processor_driver: add missing kfree ACPI, APEI: Fix incorrect APEI register bit width check and usage Update documentation for parameter *notrigger* in einj.txt ACPI, APEI, EINJ, new parameter to control trigger action ACPI, APEI, EINJ, limit the range of einj_param ACPI, APEI, Fix ERST header length check cpuidle: power_usage should be declared signed integer ...
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/include/asm/cpuidle.h29
-rw-r--r--arch/arm/kernel/Makefile2
-rw-r--r--arch/arm/kernel/cpuidle.c21
-rw-r--r--arch/arm/mach-at91/cpuidle.c59
-rw-r--r--arch/arm/mach-davinci/cpuidle.c83
-rw-r--r--arch/arm/mach-kirkwood/cpuidle.c72
-rw-r--r--arch/arm/mach-omap2/cpuidle34xx.c42
-rw-r--r--arch/arm/mach-omap2/cpuidle44xx.c21
-rw-r--r--arch/arm/mach-shmobile/cpuidle.c31
9 files changed, 152 insertions, 208 deletions
diff --git a/arch/arm/include/asm/cpuidle.h b/arch/arm/include/asm/cpuidle.h
new file mode 100644
index 000000000000..2fca60ab513a
--- /dev/null
+++ b/arch/arm/include/asm/cpuidle.h
@@ -0,0 +1,29 @@
1#ifndef __ASM_ARM_CPUIDLE_H
2#define __ASM_ARM_CPUIDLE_H
3
4#ifdef CONFIG_CPU_IDLE
5extern int arm_cpuidle_simple_enter(struct cpuidle_device *dev,
6 struct cpuidle_driver *drv, int index);
7#else
8static inline int arm_cpuidle_simple_enter(struct cpuidle_device *dev,
9 struct cpuidle_driver *drv, int index) { return -ENODEV; }
10#endif
11
12/* Common ARM WFI state */
13#define ARM_CPUIDLE_WFI_STATE_PWR(p) {\
14 .enter = arm_cpuidle_simple_enter,\
15 .exit_latency = 1,\
16 .target_residency = 1,\
17 .power_usage = p,\
18 .flags = CPUIDLE_FLAG_TIME_VALID,\
19 .name = "WFI",\
20 .desc = "ARM WFI",\
21}
22
23/*
24 * in case power_specified == 1, give a default WFI power value needed
25 * by some governors
26 */
27#define ARM_CPUIDLE_WFI_STATE ARM_CPUIDLE_WFI_STATE_PWR(UINT_MAX)
28
29#endif
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 8269d8928742..7b787d642af4 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -23,7 +23,7 @@ obj-$(CONFIG_DEPRECATED_PARAM_STRUCT) += compat.o
23 23
24obj-$(CONFIG_LEDS) += leds.o 24obj-$(CONFIG_LEDS) += leds.o
25obj-$(CONFIG_OC_ETM) += etm.o 25obj-$(CONFIG_OC_ETM) += etm.o
26 26obj-$(CONFIG_CPU_IDLE) += cpuidle.o
27obj-$(CONFIG_ISA_DMA_API) += dma.o 27obj-$(CONFIG_ISA_DMA_API) += dma.o
28obj-$(CONFIG_FIQ) += fiq.o fiqasm.o 28obj-$(CONFIG_FIQ) += fiq.o fiqasm.o
29obj-$(CONFIG_MODULES) += armksyms.o module.o 29obj-$(CONFIG_MODULES) += armksyms.o module.o
diff --git a/arch/arm/kernel/cpuidle.c b/arch/arm/kernel/cpuidle.c
new file mode 100644
index 000000000000..89545f6c8403
--- /dev/null
+++ b/arch/arm/kernel/cpuidle.c
@@ -0,0 +1,21 @@
1/*
2 * Copyright 2012 Linaro Ltd.
3 *
4 * The code contained herein is licensed under the GNU General Public
5 * License. You may obtain a copy of the GNU General Public License
6 * Version 2 or later at the following locations:
7 *
8 * http://www.opensource.org/licenses/gpl-license.html
9 * http://www.gnu.org/copyleft/gpl.html
10 */
11
12#include <linux/cpuidle.h>
13#include <asm/proc-fns.h>
14
15int arm_cpuidle_simple_enter(struct cpuidle_device *dev,
16 struct cpuidle_driver *drv, int index)
17{
18 cpu_do_idle();
19
20 return index;
21}
diff --git a/arch/arm/mach-at91/cpuidle.c b/arch/arm/mach-at91/cpuidle.c
index 555d956b3a57..ece1f9aefb47 100644
--- a/arch/arm/mach-at91/cpuidle.c
+++ b/arch/arm/mach-at91/cpuidle.c
@@ -17,9 +17,10 @@
17#include <linux/init.h> 17#include <linux/init.h>
18#include <linux/platform_device.h> 18#include <linux/platform_device.h>
19#include <linux/cpuidle.h> 19#include <linux/cpuidle.h>
20#include <asm/proc-fns.h>
21#include <linux/io.h> 20#include <linux/io.h>
22#include <linux/export.h> 21#include <linux/export.h>
22#include <asm/proc-fns.h>
23#include <asm/cpuidle.h>
23 24
24#include "pm.h" 25#include "pm.h"
25 26
@@ -27,61 +28,39 @@
27 28
28static DEFINE_PER_CPU(struct cpuidle_device, at91_cpuidle_device); 29static DEFINE_PER_CPU(struct cpuidle_device, at91_cpuidle_device);
29 30
30static struct cpuidle_driver at91_idle_driver = {
31 .name = "at91_idle",
32 .owner = THIS_MODULE,
33};
34
35/* Actual code that puts the SoC in different idle states */ 31/* Actual code that puts the SoC in different idle states */
36static int at91_enter_idle(struct cpuidle_device *dev, 32static int at91_enter_idle(struct cpuidle_device *dev,
37 struct cpuidle_driver *drv, 33 struct cpuidle_driver *drv,
38 int index) 34 int index)
39{ 35{
40 struct timeval before, after; 36 at91_standby();
41 int idle_time;
42
43 local_irq_disable();
44 do_gettimeofday(&before);
45 if (index == 0)
46 /* Wait for interrupt state */
47 cpu_do_idle();
48 else if (index == 1)
49 at91_standby();
50 37
51 do_gettimeofday(&after);
52 local_irq_enable();
53 idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC +
54 (after.tv_usec - before.tv_usec);
55
56 dev->last_residency = idle_time;
57 return index; 38 return index;
58} 39}
59 40
41static struct cpuidle_driver at91_idle_driver = {
42 .name = "at91_idle",
43 .owner = THIS_MODULE,
44 .en_core_tk_irqen = 1,
45 .states[0] = ARM_CPUIDLE_WFI_STATE,
46 .states[1] = {
47 .enter = at91_enter_idle,
48 .exit_latency = 10,
49 .target_residency = 100000,
50 .flags = CPUIDLE_FLAG_TIME_VALID,
51 .name = "RAM_SR",
52 .desc = "WFI and DDR Self Refresh",
53 },
54 .state_count = AT91_MAX_STATES,
55};
56
60/* Initialize CPU idle by registering the idle states */ 57/* Initialize CPU idle by registering the idle states */
61static int at91_init_cpuidle(void) 58static int at91_init_cpuidle(void)
62{ 59{
63 struct cpuidle_device *device; 60 struct cpuidle_device *device;
64 struct cpuidle_driver *driver = &at91_idle_driver;
65 61
66 device = &per_cpu(at91_cpuidle_device, smp_processor_id()); 62 device = &per_cpu(at91_cpuidle_device, smp_processor_id());
67 device->state_count = AT91_MAX_STATES; 63 device->state_count = AT91_MAX_STATES;
68 driver->state_count = AT91_MAX_STATES;
69
70 /* Wait for interrupt state */
71 driver->states[0].enter = at91_enter_idle;
72 driver->states[0].exit_latency = 1;
73 driver->states[0].target_residency = 10000;
74 driver->states[0].flags = CPUIDLE_FLAG_TIME_VALID;
75 strcpy(driver->states[0].name, "WFI");
76 strcpy(driver->states[0].desc, "Wait for interrupt");
77
78 /* Wait for interrupt and RAM self refresh state */
79 driver->states[1].enter = at91_enter_idle;
80 driver->states[1].exit_latency = 10;
81 driver->states[1].target_residency = 10000;
82 driver->states[1].flags = CPUIDLE_FLAG_TIME_VALID;
83 strcpy(driver->states[1].name, "RAM_SR");
84 strcpy(driver->states[1].desc, "WFI and RAM Self Refresh");
85 64
86 cpuidle_register_driver(&at91_idle_driver); 65 cpuidle_register_driver(&at91_idle_driver);
87 66
diff --git a/arch/arm/mach-davinci/cpuidle.c b/arch/arm/mach-davinci/cpuidle.c
index a30c7c5a6d83..9107691adbdb 100644
--- a/arch/arm/mach-davinci/cpuidle.c
+++ b/arch/arm/mach-davinci/cpuidle.c
@@ -18,6 +18,7 @@
18#include <linux/io.h> 18#include <linux/io.h>
19#include <linux/export.h> 19#include <linux/export.h>
20#include <asm/proc-fns.h> 20#include <asm/proc-fns.h>
21#include <asm/cpuidle.h>
21 22
22#include <mach/cpuidle.h> 23#include <mach/cpuidle.h>
23#include <mach/ddr2.h> 24#include <mach/ddr2.h>
@@ -30,12 +31,43 @@ struct davinci_ops {
30 u32 flags; 31 u32 flags;
31}; 32};
32 33
34/* Actual code that puts the SoC in different idle states */
35static int davinci_enter_idle(struct cpuidle_device *dev,
36 struct cpuidle_driver *drv,
37 int index)
38{
39 struct cpuidle_state_usage *state_usage = &dev->states_usage[index];
40 struct davinci_ops *ops = cpuidle_get_statedata(state_usage);
41
42 if (ops && ops->enter)
43 ops->enter(ops->flags);
44
45 index = cpuidle_wrap_enter(dev, drv, index,
46 arm_cpuidle_simple_enter);
47
48 if (ops && ops->exit)
49 ops->exit(ops->flags);
50
51 return index;
52}
53
33/* fields in davinci_ops.flags */ 54/* fields in davinci_ops.flags */
34#define DAVINCI_CPUIDLE_FLAGS_DDR2_PWDN BIT(0) 55#define DAVINCI_CPUIDLE_FLAGS_DDR2_PWDN BIT(0)
35 56
36static struct cpuidle_driver davinci_idle_driver = { 57static struct cpuidle_driver davinci_idle_driver = {
37 .name = "cpuidle-davinci", 58 .name = "cpuidle-davinci",
38 .owner = THIS_MODULE, 59 .owner = THIS_MODULE,
60 .en_core_tk_irqen = 1,
61 .states[0] = ARM_CPUIDLE_WFI_STATE,
62 .states[1] = {
63 .enter = davinci_enter_idle,
64 .exit_latency = 10,
65 .target_residency = 100000,
66 .flags = CPUIDLE_FLAG_TIME_VALID,
67 .name = "DDR SR",
68 .desc = "WFI and DDR Self Refresh",
69 },
70 .state_count = DAVINCI_CPUIDLE_MAX_STATES,
39}; 71};
40 72
41static DEFINE_PER_CPU(struct cpuidle_device, davinci_cpuidle_device); 73static DEFINE_PER_CPU(struct cpuidle_device, davinci_cpuidle_device);
@@ -77,41 +109,10 @@ static struct davinci_ops davinci_states[DAVINCI_CPUIDLE_MAX_STATES] = {
77 }, 109 },
78}; 110};
79 111
80/* Actual code that puts the SoC in different idle states */
81static int davinci_enter_idle(struct cpuidle_device *dev,
82 struct cpuidle_driver *drv,
83 int index)
84{
85 struct cpuidle_state_usage *state_usage = &dev->states_usage[index];
86 struct davinci_ops *ops = cpuidle_get_statedata(state_usage);
87 struct timeval before, after;
88 int idle_time;
89
90 local_irq_disable();
91 do_gettimeofday(&before);
92
93 if (ops && ops->enter)
94 ops->enter(ops->flags);
95 /* Wait for interrupt state */
96 cpu_do_idle();
97 if (ops && ops->exit)
98 ops->exit(ops->flags);
99
100 do_gettimeofday(&after);
101 local_irq_enable();
102 idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC +
103 (after.tv_usec - before.tv_usec);
104
105 dev->last_residency = idle_time;
106
107 return index;
108}
109
110static int __init davinci_cpuidle_probe(struct platform_device *pdev) 112static int __init davinci_cpuidle_probe(struct platform_device *pdev)
111{ 113{
112 int ret; 114 int ret;
113 struct cpuidle_device *device; 115 struct cpuidle_device *device;
114 struct cpuidle_driver *driver = &davinci_idle_driver;
115 struct davinci_cpuidle_config *pdata = pdev->dev.platform_data; 116 struct davinci_cpuidle_config *pdata = pdev->dev.platform_data;
116 117
117 device = &per_cpu(davinci_cpuidle_device, smp_processor_id()); 118 device = &per_cpu(davinci_cpuidle_device, smp_processor_id());
@@ -123,27 +124,11 @@ static int __init davinci_cpuidle_probe(struct platform_device *pdev)
123 124
124 ddr2_reg_base = pdata->ddr2_ctlr_base; 125 ddr2_reg_base = pdata->ddr2_ctlr_base;
125 126
126 /* Wait for interrupt state */
127 driver->states[0].enter = davinci_enter_idle;
128 driver->states[0].exit_latency = 1;
129 driver->states[0].target_residency = 10000;
130 driver->states[0].flags = CPUIDLE_FLAG_TIME_VALID;
131 strcpy(driver->states[0].name, "WFI");
132 strcpy(driver->states[0].desc, "Wait for interrupt");
133
134 /* Wait for interrupt and DDR self refresh state */
135 driver->states[1].enter = davinci_enter_idle;
136 driver->states[1].exit_latency = 10;
137 driver->states[1].target_residency = 10000;
138 driver->states[1].flags = CPUIDLE_FLAG_TIME_VALID;
139 strcpy(driver->states[1].name, "DDR SR");
140 strcpy(driver->states[1].desc, "WFI and DDR Self Refresh");
141 if (pdata->ddr2_pdown) 127 if (pdata->ddr2_pdown)
142 davinci_states[1].flags |= DAVINCI_CPUIDLE_FLAGS_DDR2_PWDN; 128 davinci_states[1].flags |= DAVINCI_CPUIDLE_FLAGS_DDR2_PWDN;
143 cpuidle_set_statedata(&device->states_usage[1], &davinci_states[1]); 129 cpuidle_set_statedata(&device->states_usage[1], &davinci_states[1]);
144 130
145 device->state_count = DAVINCI_CPUIDLE_MAX_STATES; 131 device->state_count = DAVINCI_CPUIDLE_MAX_STATES;
146 driver->state_count = DAVINCI_CPUIDLE_MAX_STATES;
147 132
148 ret = cpuidle_register_driver(&davinci_idle_driver); 133 ret = cpuidle_register_driver(&davinci_idle_driver);
149 if (ret) { 134 if (ret) {
diff --git a/arch/arm/mach-kirkwood/cpuidle.c b/arch/arm/mach-kirkwood/cpuidle.c
index 7088180b018b..0f1710941878 100644
--- a/arch/arm/mach-kirkwood/cpuidle.c
+++ b/arch/arm/mach-kirkwood/cpuidle.c
@@ -20,77 +20,47 @@
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> 22#include <asm/proc-fns.h>
23#include <asm/cpuidle.h>
23#include <mach/kirkwood.h> 24#include <mach/kirkwood.h>
24 25
25#define KIRKWOOD_MAX_STATES 2 26#define KIRKWOOD_MAX_STATES 2
26 27
27static struct cpuidle_driver kirkwood_idle_driver = {
28 .name = "kirkwood_idle",
29 .owner = THIS_MODULE,
30};
31
32static DEFINE_PER_CPU(struct cpuidle_device, kirkwood_cpuidle_device);
33
34/* Actual code that puts the SoC in different idle states */ 28/* Actual code that puts the SoC in different idle states */
35static int kirkwood_enter_idle(struct cpuidle_device *dev, 29static int kirkwood_enter_idle(struct cpuidle_device *dev,
36 struct cpuidle_driver *drv, 30 struct cpuidle_driver *drv,
37 int index) 31 int index)
38{ 32{
39 struct timeval before, after; 33 writel(0x7, DDR_OPERATION_BASE);
40 int idle_time; 34 cpu_do_idle();
41
42 local_irq_disable();
43 do_gettimeofday(&before);
44 if (index == 0)
45 /* Wait for interrupt state */
46 cpu_do_idle();
47 else if (index == 1) {
48 /*
49 * Following write will put DDR in self refresh.
50 * Note that we have 256 cycles before DDR puts it
51 * self in self-refresh, so the wait-for-interrupt
52 * call afterwards won't get the DDR from self refresh
53 * mode.
54 */
55 writel(0x7, DDR_OPERATION_BASE);
56 cpu_do_idle();
57 }
58 do_gettimeofday(&after);
59 local_irq_enable();
60 idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC +
61 (after.tv_usec - before.tv_usec);
62
63 /* Update last residency */
64 dev->last_residency = idle_time;
65 35
66 return index; 36 return index;
67} 37}
68 38
39static struct cpuidle_driver kirkwood_idle_driver = {
40 .name = "kirkwood_idle",
41 .owner = THIS_MODULE,
42 .en_core_tk_irqen = 1,
43 .states[0] = ARM_CPUIDLE_WFI_STATE,
44 .states[1] = {
45 .enter = kirkwood_enter_idle,
46 .exit_latency = 10,
47 .target_residency = 100000,
48 .flags = CPUIDLE_FLAG_TIME_VALID,
49 .name = "DDR SR",
50 .desc = "WFI and DDR Self Refresh",
51 },
52 .state_count = KIRKWOOD_MAX_STATES,
53};
54
55static DEFINE_PER_CPU(struct cpuidle_device, kirkwood_cpuidle_device);
56
69/* Initialize CPU idle by registering the idle states */ 57/* Initialize CPU idle by registering the idle states */
70static int kirkwood_init_cpuidle(void) 58static int kirkwood_init_cpuidle(void)
71{ 59{
72 struct cpuidle_device *device; 60 struct cpuidle_device *device;
73 struct cpuidle_driver *driver = &kirkwood_idle_driver;
74 61
75 device = &per_cpu(kirkwood_cpuidle_device, smp_processor_id()); 62 device = &per_cpu(kirkwood_cpuidle_device, smp_processor_id());
76 device->state_count = KIRKWOOD_MAX_STATES; 63 device->state_count = KIRKWOOD_MAX_STATES;
77 driver->state_count = KIRKWOOD_MAX_STATES;
78
79 /* Wait for interrupt state */
80 driver->states[0].enter = kirkwood_enter_idle;
81 driver->states[0].exit_latency = 1;
82 driver->states[0].target_residency = 10000;
83 driver->states[0].flags = CPUIDLE_FLAG_TIME_VALID;
84 strcpy(driver->states[0].name, "WFI");
85 strcpy(driver->states[0].desc, "Wait for interrupt");
86
87 /* Wait for interrupt and DDR self refresh state */
88 driver->states[1].enter = kirkwood_enter_idle;
89 driver->states[1].exit_latency = 10;
90 driver->states[1].target_residency = 10000;
91 driver->states[1].flags = CPUIDLE_FLAG_TIME_VALID;
92 strcpy(driver->states[1].name, "DDR SR");
93 strcpy(driver->states[1].desc, "WFI and DDR Self Refresh");
94 64
95 cpuidle_register_driver(&kirkwood_idle_driver); 65 cpuidle_register_driver(&kirkwood_idle_driver);
96 if (cpuidle_register_device(device)) { 66 if (cpuidle_register_device(device)) {
diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c
index 464cffde58fe..535866489ce3 100644
--- a/arch/arm/mach-omap2/cpuidle34xx.c
+++ b/arch/arm/mach-omap2/cpuidle34xx.c
@@ -87,29 +87,14 @@ static int _cpuidle_deny_idle(struct powerdomain *pwrdm,
87 return 0; 87 return 0;
88} 88}
89 89
90/** 90static int __omap3_enter_idle(struct cpuidle_device *dev,
91 * omap3_enter_idle - Programs OMAP3 to enter the specified state
92 * @dev: cpuidle device
93 * @drv: cpuidle driver
94 * @index: the index of state to be entered
95 *
96 * Called from the CPUidle framework to program the device to the
97 * specified target state selected by the governor.
98 */
99static int omap3_enter_idle(struct cpuidle_device *dev,
100 struct cpuidle_driver *drv, 91 struct cpuidle_driver *drv,
101 int index) 92 int index)
102{ 93{
103 struct omap3_idle_statedata *cx = 94 struct omap3_idle_statedata *cx =
104 cpuidle_get_statedata(&dev->states_usage[index]); 95 cpuidle_get_statedata(&dev->states_usage[index]);
105 struct timespec ts_preidle, ts_postidle, ts_idle;
106 u32 mpu_state = cx->mpu_state, core_state = cx->core_state; 96 u32 mpu_state = cx->mpu_state, core_state = cx->core_state;
107 int idle_time;
108
109 /* Used to keep track of the total time in idle */
110 getnstimeofday(&ts_preidle);
111 97
112 local_irq_disable();
113 local_fiq_disable(); 98 local_fiq_disable();
114 99
115 pwrdm_set_next_pwrst(mpu_pd, mpu_state); 100 pwrdm_set_next_pwrst(mpu_pd, mpu_state);
@@ -148,22 +133,29 @@ static int omap3_enter_idle(struct cpuidle_device *dev,
148 } 133 }
149 134
150return_sleep_time: 135return_sleep_time:
151 getnstimeofday(&ts_postidle);
152 ts_idle = timespec_sub(ts_postidle, ts_preidle);
153 136
154 local_irq_enable();
155 local_fiq_enable(); 137 local_fiq_enable();
156 138
157 idle_time = ts_idle.tv_nsec / NSEC_PER_USEC + ts_idle.tv_sec * \
158 USEC_PER_SEC;
159
160 /* Update cpuidle counters */
161 dev->last_residency = idle_time;
162
163 return index; 139 return index;
164} 140}
165 141
166/** 142/**
143 * omap3_enter_idle - Programs OMAP3 to enter the specified state
144 * @dev: cpuidle device
145 * @drv: cpuidle driver
146 * @index: the index of state to be entered
147 *
148 * Called from the CPUidle framework to program the device to the
149 * specified target state selected by the governor.
150 */
151static inline int omap3_enter_idle(struct cpuidle_device *dev,
152 struct cpuidle_driver *drv,
153 int index)
154{
155 return cpuidle_wrap_enter(dev, drv, index, __omap3_enter_idle);
156}
157
158/**
167 * next_valid_state - Find next valid C-state 159 * next_valid_state - Find next valid C-state
168 * @dev: cpuidle device 160 * @dev: cpuidle device
169 * @drv: cpuidle driver 161 * @drv: cpuidle driver
diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c
index 72e018b9b260..f386cbe9c889 100644
--- a/arch/arm/mach-omap2/cpuidle44xx.c
+++ b/arch/arm/mach-omap2/cpuidle44xx.c
@@ -62,15 +62,9 @@ static int omap4_enter_idle(struct cpuidle_device *dev,
62{ 62{
63 struct omap4_idle_statedata *cx = 63 struct omap4_idle_statedata *cx =
64 cpuidle_get_statedata(&dev->states_usage[index]); 64 cpuidle_get_statedata(&dev->states_usage[index]);
65 struct timespec ts_preidle, ts_postidle, ts_idle;
66 u32 cpu1_state; 65 u32 cpu1_state;
67 int idle_time;
68 int cpu_id = smp_processor_id(); 66 int cpu_id = smp_processor_id();
69 67
70 /* Used to keep track of the total time in idle */
71 getnstimeofday(&ts_preidle);
72
73 local_irq_disable();
74 local_fiq_disable(); 68 local_fiq_disable();
75 69
76 /* 70 /*
@@ -128,26 +122,17 @@ static int omap4_enter_idle(struct cpuidle_device *dev,
128 if (index > 0) 122 if (index > 0)
129 clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu_id); 123 clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu_id);
130 124
131 getnstimeofday(&ts_postidle);
132 ts_idle = timespec_sub(ts_postidle, ts_preidle);
133
134 local_irq_enable();
135 local_fiq_enable(); 125 local_fiq_enable();
136 126
137 idle_time = ts_idle.tv_nsec / NSEC_PER_USEC + ts_idle.tv_sec * \
138 USEC_PER_SEC;
139
140 /* Update cpuidle counters */
141 dev->last_residency = idle_time;
142
143 return index; 127 return index;
144} 128}
145 129
146DEFINE_PER_CPU(struct cpuidle_device, omap4_idle_dev); 130DEFINE_PER_CPU(struct cpuidle_device, omap4_idle_dev);
147 131
148struct cpuidle_driver omap4_idle_driver = { 132struct cpuidle_driver omap4_idle_driver = {
149 .name = "omap4_idle", 133 .name = "omap4_idle",
150 .owner = THIS_MODULE, 134 .owner = THIS_MODULE,
135 .en_core_tk_irqen = 1,
151}; 136};
152 137
153static inline void _fill_cstate(struct cpuidle_driver *drv, 138static inline void _fill_cstate(struct cpuidle_driver *drv,
diff --git a/arch/arm/mach-shmobile/cpuidle.c b/arch/arm/mach-shmobile/cpuidle.c
index 21b09b6455e4..7e6559105d40 100644
--- a/arch/arm/mach-shmobile/cpuidle.c
+++ b/arch/arm/mach-shmobile/cpuidle.c
@@ -13,6 +13,7 @@
13#include <linux/suspend.h> 13#include <linux/suspend.h>
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/err.h> 15#include <linux/err.h>
16#include <asm/cpuidle.h>
16#include <asm/io.h> 17#include <asm/io.h>
17 18
18static void shmobile_enter_wfi(void) 19static void shmobile_enter_wfi(void)
@@ -28,37 +29,19 @@ static int shmobile_cpuidle_enter(struct cpuidle_device *dev,
28 struct cpuidle_driver *drv, 29 struct cpuidle_driver *drv,
29 int index) 30 int index)
30{ 31{
31 ktime_t before, after;
32
33 before = ktime_get();
34
35 local_irq_disable();
36 local_fiq_disable();
37
38 shmobile_cpuidle_modes[index](); 32 shmobile_cpuidle_modes[index]();
39 33
40 local_irq_enable();
41 local_fiq_enable();
42
43 after = ktime_get();
44 dev->last_residency = ktime_to_ns(ktime_sub(after, before)) >> 10;
45
46 return index; 34 return index;
47} 35}
48 36
49static struct cpuidle_device shmobile_cpuidle_dev; 37static struct cpuidle_device shmobile_cpuidle_dev;
50static struct cpuidle_driver shmobile_cpuidle_driver = { 38static struct cpuidle_driver shmobile_cpuidle_driver = {
51 .name = "shmobile_cpuidle", 39 .name = "shmobile_cpuidle",
52 .owner = THIS_MODULE, 40 .owner = THIS_MODULE,
53 .states[0] = { 41 .en_core_tk_irqen = 1,
54 .name = "C1", 42 .states[0] = ARM_CPUIDLE_WFI_STATE,
55 .desc = "WFI", 43 .safe_state_index = 0, /* C1 */
56 .exit_latency = 1, 44 .state_count = 1,
57 .target_residency = 1 * 2,
58 .flags = CPUIDLE_FLAG_TIME_VALID,
59 },
60 .safe_state_index = 0, /* C1 */
61 .state_count = 1,
62}; 45};
63 46
64void (*shmobile_cpuidle_setup)(struct cpuidle_driver *drv); 47void (*shmobile_cpuidle_setup)(struct cpuidle_driver *drv);