* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#include <linux/module.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/err.h>
static void omap_timer_restore_context(struct omap_dm_timer *timer)
{
- omap_dm_timer_write_reg(timer, OMAP_TIMER_OCP_CFG_OFFSET,
- timer->context.tiocp_cfg);
- if (timer->revision > 1)
- __raw_writel(timer->context.tistat, timer->sys_stat);
-
- __raw_writel(timer->context.tisr, timer->irq_stat);
omap_dm_timer_write_reg(timer, OMAP_TIMER_WAKEUP_EN_REG,
timer->context.twer);
omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG,
static void omap_dm_timer_reset(struct omap_dm_timer *timer)
{
- omap_dm_timer_enable(timer);
if (timer->pdev->id != 1) {
omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, 0x06);
omap_dm_timer_wait_for_reset(timer);
}
__omap_dm_timer_reset(timer, 0, 0);
- omap_dm_timer_disable(timer);
- timer->posted = 1;
}
int omap_dm_timer_prepare(struct omap_dm_timer *timer)
{
struct dmtimer_platform_data *pdata = timer->pdev->dev.platform_data;
- int ret;
timer->fclk = clk_get(&timer->pdev->dev, "fck");
if (WARN_ON_ONCE(IS_ERR_OR_NULL(timer->fclk))) {
return -EINVAL;
}
+ omap_dm_timer_enable(timer);
+
if (pdata->needs_manual_reset)
omap_dm_timer_reset(timer);
- ret = omap_dm_timer_set_source(timer, OMAP_TIMER_SRC_32_KHZ);
+ __omap_dm_timer_enable_posted(timer);
+ omap_dm_timer_disable(timer);
- timer->posted = 1;
- return ret;
+ return omap_dm_timer_set_source(timer, OMAP_TIMER_SRC_32_KHZ);
}
struct omap_dm_timer *omap_dm_timer_request(void)
timer->reserved = 1;
break;
}
+ spin_unlock_irqrestore(&dm_timer_lock, flags);
if (timer) {
ret = omap_dm_timer_prepare(timer);
timer = NULL;
}
}
- spin_unlock_irqrestore(&dm_timer_lock, flags);
if (!timer)
pr_debug("%s: timer request failed!\n", __func__);
break;
}
}
+ spin_unlock_irqrestore(&dm_timer_lock, flags);
if (timer) {
ret = omap_dm_timer_prepare(timer);
timer = NULL;
}
}
- spin_unlock_irqrestore(&dm_timer_lock, flags);
if (!timer)
pr_debug("%s: timer%d request failed!\n", __func__, id);
void omap_dm_timer_disable(struct omap_dm_timer *timer)
{
- pm_runtime_put(&timer->pdev->dev);
+ pm_runtime_put_sync(&timer->pdev->dev);
}
EXPORT_SYMBOL_GPL(omap_dm_timer_disable);
__omap_dm_timer_stop(timer, timer->posted, rate);
+ if (timer->loses_context && 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
+ * context.
+ */
+ timer->context.tclr =
+ omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
+ omap_dm_timer_disable(timer);
return 0;
}
EXPORT_SYMBOL_GPL(omap_dm_timer_stop);
l |= OMAP_TIMER_CTRL_CE;
else
l &= ~OMAP_TIMER_CTRL_CE;
- omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
omap_dm_timer_write_reg(timer, OMAP_TIMER_MATCH_REG, match);
+ omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
/* Save the context */
timer->context.tclr = l;
return -EINVAL;
__omap_dm_timer_write_status(timer, value);
- /* Save the context */
- timer->context.tisr = value;
+
return 0;
}
EXPORT_SYMBOL_GPL(omap_dm_timer_write_status);
}
timer->id = pdev->id;
+ timer->errata = pdata->timer_errata;
timer->irq = irq->start;
timer->reserved = pdata->reserved;
timer->pdev = pdev;