diff options
author | NeilBrown <neilb@suse.de> | 2013-03-19 13:38:15 -0400 |
---|---|---|
committer | Benoit Cousson <benoit.cousson@linaro.org> | 2013-04-08 18:21:29 -0400 |
commit | 9cc268d5bbc097ae5a3ae236fb2461ea113274bf (patch) | |
tree | 05751016c7bde8b73ee2fbe6564ddb6bd1fb8db0 /arch/arm/plat-omap | |
parent | 7b3754c63e8d6528002386b313c527a826236d82 (diff) |
ARM: OMAP: Simplify dmtimer context-loss handling
The context loss handling in dmtimer appears to assume that
omap_dm_timer_set_load_start() or omap_dm_timer_start() and
omap_dm_timer_stop() bracket all interactions. Only the first two
restore the context and the last updates the context loss counter.
However omap_dm_timer_set_load() or omap_dm_timer_set_match() can
reasonably be called outside this bracketing, and the fact that they
call omap_dm_timer_enable() / omap_dm_timer_disable() suggest that
is expected.
So if, after a transition into and out of off-mode which would cause
the dm timer to loose all state, omap_dm_timer_set_match() is called
before omap_dm_timer_start(), the value read from OMAP_TIMER_CTRL_REG
will be 'wrong' and this wrong value will be stored context.tclr so
a subsequent omap_dm_timer_start() can fail (As the control register
is wrong).
Simplify this be doing the restore-from-context in
omap_dm_timer_enable() so that whenever the timer is enabled, the
context is correct. Also update the ctx_loss_count at the same time as
we notice it is wrong - these is no value in delaying this until the
omap_dm_timer_disable() as it cannot change while the timer is enabled.
Signed-off-by: NeilBrown <neilb@suse.de>
[jon-hunter@ti.com: minor update to subject and changed variable name]
Signed-off-by: Jon Hunter <jon-hunter@ti.com>
Acked-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: Benoit Cousson <benoit.cousson@linaro.org>
Diffstat (limited to 'arch/arm/plat-omap')
-rw-r--r-- | arch/arm/plat-omap/dmtimer.c | 32 |
1 files changed, 12 insertions, 20 deletions
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c index a0daa2fb5de6..5cae1dd1f365 100644 --- a/arch/arm/plat-omap/dmtimer.c +++ b/arch/arm/plat-omap/dmtimer.c | |||
@@ -315,7 +315,19 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_free); | |||
315 | 315 | ||
316 | void omap_dm_timer_enable(struct omap_dm_timer *timer) | 316 | void omap_dm_timer_enable(struct omap_dm_timer *timer) |
317 | { | 317 | { |
318 | int c; | ||
319 | |||
318 | pm_runtime_get_sync(&timer->pdev->dev); | 320 | pm_runtime_get_sync(&timer->pdev->dev); |
321 | |||
322 | if (!(timer->capability & OMAP_TIMER_ALWON)) { | ||
323 | if (timer->get_context_loss_count) { | ||
324 | c = timer->get_context_loss_count(&timer->pdev->dev); | ||
325 | if (c != timer->ctx_loss_count) { | ||
326 | omap_timer_restore_context(timer); | ||
327 | timer->ctx_loss_count = c; | ||
328 | } | ||
329 | } | ||
330 | } | ||
319 | } | 331 | } |
320 | EXPORT_SYMBOL_GPL(omap_dm_timer_enable); | 332 | EXPORT_SYMBOL_GPL(omap_dm_timer_enable); |
321 | 333 | ||
@@ -410,13 +422,6 @@ int omap_dm_timer_start(struct omap_dm_timer *timer) | |||
410 | 422 | ||
411 | omap_dm_timer_enable(timer); | 423 | omap_dm_timer_enable(timer); |
412 | 424 | ||
413 | if (!(timer->capability & OMAP_TIMER_ALWON)) { | ||
414 | if (timer->get_context_loss_count && | ||
415 | timer->get_context_loss_count(&timer->pdev->dev) != | ||
416 | timer->ctx_loss_count) | ||
417 | omap_timer_restore_context(timer); | ||
418 | } | ||
419 | |||
420 | l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); | 425 | l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); |
421 | if (!(l & OMAP_TIMER_CTRL_ST)) { | 426 | if (!(l & OMAP_TIMER_CTRL_ST)) { |
422 | l |= OMAP_TIMER_CTRL_ST; | 427 | l |= OMAP_TIMER_CTRL_ST; |
@@ -441,12 +446,6 @@ int omap_dm_timer_stop(struct omap_dm_timer *timer) | |||
441 | 446 | ||
442 | __omap_dm_timer_stop(timer, timer->posted, rate); | 447 | __omap_dm_timer_stop(timer, timer->posted, rate); |
443 | 448 | ||
444 | if (!(timer->capability & OMAP_TIMER_ALWON)) { | ||
445 | if (timer->get_context_loss_count) | ||
446 | timer->ctx_loss_count = | ||
447 | timer->get_context_loss_count(&timer->pdev->dev); | ||
448 | } | ||
449 | |||
450 | /* | 449 | /* |
451 | * Since the register values are computed and written within | 450 | * Since the register values are computed and written within |
452 | * __omap_dm_timer_stop, we need to use read to retrieve the | 451 | * __omap_dm_timer_stop, we need to use read to retrieve the |
@@ -553,13 +552,6 @@ int omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload, | |||
553 | 552 | ||
554 | omap_dm_timer_enable(timer); | 553 | omap_dm_timer_enable(timer); |
555 | 554 | ||
556 | if (!(timer->capability & OMAP_TIMER_ALWON)) { | ||
557 | if (timer->get_context_loss_count && | ||
558 | timer->get_context_loss_count(&timer->pdev->dev) != | ||
559 | timer->ctx_loss_count) | ||
560 | omap_timer_restore_context(timer); | ||
561 | } | ||
562 | |||
563 | l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); | 555 | l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); |
564 | if (autoreload) { | 556 | if (autoreload) { |
565 | l |= OMAP_TIMER_CTRL_AR; | 557 | l |= OMAP_TIMER_CTRL_AR; |