diff options
| author | Santosh Shilimkar <santosh.shilimkar@ti.com> | 2012-04-17 05:39:20 -0400 |
|---|---|---|
| committer | Kevin Hilman <khilman@ti.com> | 2012-07-25 19:06:08 -0400 |
| commit | b93d70aeb8f3b5ed2d74643f5009239a55634e1d (patch) | |
| tree | 925d3102051db9664772911f29a59155825c671d | |
| parent | 5b4d5bcc68940497722d98d99abee72a0ab1d6f1 (diff) | |
ARM: OMAP4: CPUidle: Open broadcast clock-event device.
OMAP4 idle driver uses CLOCK_EVT_NOTIFY_BROADCAST_[ENTER/EXIT]
for broadcast clock events. But _ENTER/_EXIT doesn't really open
broadcast clock events and to explicitly setup the broadcast device,
CLOCK_EVT_NOTIFY_BROADCAST_ON should be used.
Add the missing CLOCK_EVT_NOTIFY_BROADCAST_ON clockevent notifications.
This will setup the broadcast timer in either periodic/oneshot modes
correctly. Recent clockevent infrastructure change 77b0d60 {leave the
broadcast device in shutdown mode when not needed} exposed this bug
leading to boot hangs in oneshot mode. Prior to this, periodic broadcast
mode was also broken. This change fixes both the periodic/oneshot broadcast
modes.
Discussion thread :
https://lkml.org/lkml/2012/4/9/13
Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Signed-off-by: Kevin Hilman <khilman@ti.com>
| -rw-r--r-- | arch/arm/mach-omap2/cpuidle44xx.c | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c index eb93e45d3271..45e6a54d5818 100644 --- a/arch/arm/mach-omap2/cpuidle44xx.c +++ b/arch/arm/mach-omap2/cpuidle44xx.c | |||
| @@ -202,6 +202,16 @@ struct cpuidle_driver omap4_idle_driver = { | |||
| 202 | .safe_state_index = 0, | 202 | .safe_state_index = 0, |
| 203 | }; | 203 | }; |
| 204 | 204 | ||
| 205 | /* | ||
| 206 | * For each cpu, setup the broadcast timer because local timers | ||
| 207 | * stops for the states above C1. | ||
| 208 | */ | ||
| 209 | static void omap_setup_broadcast_timer(void *arg) | ||
| 210 | { | ||
| 211 | int cpu = smp_processor_id(); | ||
| 212 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ON, &cpu); | ||
| 213 | } | ||
| 214 | |||
| 205 | /** | 215 | /** |
| 206 | * omap4_idle_init - Init routine for OMAP4 idle | 216 | * omap4_idle_init - Init routine for OMAP4 idle |
| 207 | * | 217 | * |
| @@ -224,6 +234,9 @@ int __init omap4_idle_init(void) | |||
| 224 | if (!cpu_clkdm[0] || !cpu_clkdm[1]) | 234 | if (!cpu_clkdm[0] || !cpu_clkdm[1]) |
| 225 | return -ENODEV; | 235 | return -ENODEV; |
| 226 | 236 | ||
| 237 | /* Configure the broadcast timer on each cpu */ | ||
| 238 | on_each_cpu(omap_setup_broadcast_timer, NULL, 1); | ||
| 239 | |||
| 227 | for_each_cpu(cpu_id, cpu_online_mask) { | 240 | for_each_cpu(cpu_id, cpu_online_mask) { |
| 228 | dev = &per_cpu(omap4_idle_dev, cpu_id); | 241 | dev = &per_cpu(omap4_idle_dev, cpu_id); |
| 229 | dev->cpu = cpu_id; | 242 | dev->cpu = cpu_id; |
