diff options
author | NeilBrown <neilb@suse.de> | 2013-01-07 07:53:03 +1100 |
---|---|---|
committer | Denis 'GNUtoo' Carikli <GNUtoo@no-log.org> | 2013-03-09 20:27:30 +0100 |
commit | 21784223171965c8c6c9a55f8125344a76eff07d (patch) | |
tree | 764a7c6c36376d1556cf86fa5fb41ce79bd7ceab | |
parent | 5408f4fc887a83e063da2a441c5578e09eb28940 (diff) | |
download | kernel_goldelico_gta04-21784223171965c8c6c9a55f8125344a76eff07d.zip kernel_goldelico_gta04-21784223171965c8c6c9a55f8125344a76eff07d.tar.gz kernel_goldelico_gta04-21784223171965c8c6c9a55f8125344a76eff07d.tar.bz2 |
OMAP dmtimer - simplify 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 call 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>
-rw-r--r-- | arch/arm/plat-omap/dmtimer.c | 29 |
1 files changed, 9 insertions, 20 deletions
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c index 7b433f3..628196d 100644 --- a/arch/arm/plat-omap/dmtimer.c +++ b/arch/arm/plat-omap/dmtimer.c @@ -316,6 +316,15 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_free); void omap_dm_timer_enable(struct omap_dm_timer *timer) { pm_runtime_get_sync(&timer->pdev->dev); + + if (!(timer->capability & OMAP_TIMER_ALWON)) { + int loss_count = + timer->get_context_loss_count(&timer->pdev->dev); + if (loss_count != timer->ctx_loss_count) { + omap_timer_restore_context(timer); + timer->ctx_loss_count = loss_count; + } + } } EXPORT_SYMBOL_GPL(omap_dm_timer_enable); @@ -410,13 +419,6 @@ int omap_dm_timer_start(struct omap_dm_timer *timer) omap_dm_timer_enable(timer); - if (!(timer->capability & OMAP_TIMER_ALWON)) { - if (timer->get_context_loss_count && - timer->get_context_loss_count(&timer->pdev->dev) != - timer->ctx_loss_count) - omap_timer_restore_context(timer); - } - l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); if (!(l & OMAP_TIMER_CTRL_ST)) { l |= OMAP_TIMER_CTRL_ST; @@ -441,12 +443,6 @@ int omap_dm_timer_stop(struct omap_dm_timer *timer) __omap_dm_timer_stop(timer, timer->posted, rate); - if (!(timer->capability & OMAP_TIMER_ALWON)) { - if (timer->get_context_loss_count) - timer->ctx_loss_count = - timer->get_context_loss_count(&timer->pdev->dev); - } - /* * Since the register values are computed and written within * __omap_dm_timer_stop, we need to use read to retrieve the @@ -553,13 +549,6 @@ int omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload, omap_dm_timer_enable(timer); - if (!(timer->capability & OMAP_TIMER_ALWON)) { - if (timer->get_context_loss_count && - timer->get_context_loss_count(&timer->pdev->dev) != - timer->ctx_loss_count) - omap_timer_restore_context(timer); - } - l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); if (autoreload) { l |= OMAP_TIMER_CTRL_AR; |