diff options
author | Robert Lee <rob.lee@linaro.org> | 2012-03-20 16:22:45 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2012-03-21 02:00:41 -0400 |
commit | 19976c2a88d125aec16b9255c7197c297bbdd637 (patch) | |
tree | f3e4a923b833923cc36c7545879acc2fbfae156e /arch/arm/mach-davinci/cpuidle.c | |
parent | b334648db0ff2d07b00d81cf033c6eddff277680 (diff) |
ARM: davinci: Consolidate time keeping and irq enable
Enable core cpuidle timekeeping and irq enabling and remove that
handling from this code.
Signed-off-by: Robert Lee <rob.lee@linaro.org>
Reviewed-by: Kevin Hilman <khilman@ti.com>
Reviewed-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Acked-by: Jean Pihet <j-pihet@ti.com>
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'arch/arm/mach-davinci/cpuidle.c')
-rw-r--r-- | arch/arm/mach-davinci/cpuidle.c | 82 |
1 files changed, 33 insertions, 49 deletions
diff --git a/arch/arm/mach-davinci/cpuidle.c b/arch/arm/mach-davinci/cpuidle.c index a30c7c5a6d83..93ae096c4ab2 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,42 @@ struct davinci_ops { | |||
30 | u32 flags; | 31 | u32 flags; |
31 | }; | 32 | }; |
32 | 33 | ||
34 | /* Actual code that puts the SoC in different idle states */ | ||
35 | static 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 | ||
36 | static struct cpuidle_driver davinci_idle_driver = { | 57 | static struct cpuidle_driver davinci_idle_driver = { |
37 | .name = "cpuidle-davinci", | 58 | .name = "cpuidle-davinci", |
38 | .owner = THIS_MODULE, | 59 | .owner = THIS_MODULE, |
60 | .states[0] = ARM_CPUIDLE_WFI_STATE, | ||
61 | .states[1] = { | ||
62 | .enter = davinci_enter_idle, | ||
63 | .exit_latency = 10, | ||
64 | .target_residency = 100000, | ||
65 | .flags = CPUIDLE_FLAG_TIME_VALID, | ||
66 | .name = "DDR SR", | ||
67 | .desc = "WFI and DDR Self Refresh", | ||
68 | }, | ||
69 | .state_count = DAVINCI_CPUIDLE_MAX_STATES, | ||
39 | }; | 70 | }; |
40 | 71 | ||
41 | static DEFINE_PER_CPU(struct cpuidle_device, davinci_cpuidle_device); | 72 | static DEFINE_PER_CPU(struct cpuidle_device, davinci_cpuidle_device); |
@@ -77,41 +108,10 @@ static struct davinci_ops davinci_states[DAVINCI_CPUIDLE_MAX_STATES] = { | |||
77 | }, | 108 | }, |
78 | }; | 109 | }; |
79 | 110 | ||
80 | /* Actual code that puts the SoC in different idle states */ | ||
81 | static 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 | |||
110 | static int __init davinci_cpuidle_probe(struct platform_device *pdev) | 111 | static int __init davinci_cpuidle_probe(struct platform_device *pdev) |
111 | { | 112 | { |
112 | int ret; | 113 | int ret; |
113 | struct cpuidle_device *device; | 114 | struct cpuidle_device *device; |
114 | struct cpuidle_driver *driver = &davinci_idle_driver; | ||
115 | struct davinci_cpuidle_config *pdata = pdev->dev.platform_data; | 115 | struct davinci_cpuidle_config *pdata = pdev->dev.platform_data; |
116 | 116 | ||
117 | device = &per_cpu(davinci_cpuidle_device, smp_processor_id()); | 117 | device = &per_cpu(davinci_cpuidle_device, smp_processor_id()); |
@@ -123,27 +123,11 @@ static int __init davinci_cpuidle_probe(struct platform_device *pdev) | |||
123 | 123 | ||
124 | ddr2_reg_base = pdata->ddr2_ctlr_base; | 124 | ddr2_reg_base = pdata->ddr2_ctlr_base; |
125 | 125 | ||
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) | 126 | if (pdata->ddr2_pdown) |
142 | davinci_states[1].flags |= DAVINCI_CPUIDLE_FLAGS_DDR2_PWDN; | 127 | davinci_states[1].flags |= DAVINCI_CPUIDLE_FLAGS_DDR2_PWDN; |
143 | cpuidle_set_statedata(&device->states_usage[1], &davinci_states[1]); | 128 | cpuidle_set_statedata(&device->states_usage[1], &davinci_states[1]); |
144 | 129 | ||
145 | device->state_count = DAVINCI_CPUIDLE_MAX_STATES; | 130 | device->state_count = DAVINCI_CPUIDLE_MAX_STATES; |
146 | driver->state_count = DAVINCI_CPUIDLE_MAX_STATES; | ||
147 | 131 | ||
148 | ret = cpuidle_register_driver(&davinci_idle_driver); | 132 | ret = cpuidle_register_driver(&davinci_idle_driver); |
149 | if (ret) { | 133 | if (ret) { |