aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2013-01-07 07:53:03 +1100
committerDenis 'GNUtoo' Carikli <GNUtoo@no-log.org>2013-03-09 20:27:30 +0100
commit21784223171965c8c6c9a55f8125344a76eff07d (patch)
tree764a7c6c36376d1556cf86fa5fb41ce79bd7ceab
parent5408f4fc887a83e063da2a441c5578e09eb28940 (diff)
downloadkernel_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.c29
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;