[PATCH v14 REPOST 12/12] OMAP: dmtimer: Off mode support
Santosh
santosh.shilimkar at ti.com
Fri Aug 26 12:04:33 EDT 2011
On Friday 15 July 2011 05:35 PM, Tarun Kanti DebBarma wrote:
> Clock is enabled only when timer is started and disabled when the the timer
> is stopped. Therefore before accessing registers in functions clock is enabled
> and then disabled back at the end of access.
> Context save and restore functions are called as needed based upon whether the
> context is lost or not.
>
> Signed-off-by: Tarun Kanti DebBarma<tarun.kanti at ti.com>
> ---
> arch/arm/mach-omap2/timer.c | 17 +++++
> arch/arm/plat-omap/dmtimer.c | 97 +++++++++++++++++++++++++++--
> arch/arm/plat-omap/include/plat/dmtimer.h | 9 +++
> 3 files changed, 118 insertions(+), 5 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
> index 9d47300..d1c6219 100644
> --- a/arch/arm/mach-omap2/timer.c
> +++ b/arch/arm/mach-omap2/timer.c
> @@ -44,6 +44,9 @@
> #include<plat/common.h>
> #include<plat/omap_hwmod.h>
> #include<plat/omap_device.h>
> +#include<plat/omap-pm.h>
> +
> +#include "powerdomain.h"
>
> /* Parent clocks, eventually these will come from the clock framework */
>
> @@ -409,6 +412,16 @@ static int omap2_dm_timer_set_src(struct platform_device *pdev, int source)
> return ret;
> }
>
> +#ifdef CONFIG_PM
> +static int omap_timer_get_context_loss(struct device *dev)
> +{
> + return omap_pm_get_dev_context_loss_count(dev);
> +}
> +
> +#else
> +#define omap_gpio_get_context_loss NULL
> +#endif
> +
> struct omap_device_pm_latency omap2_dmtimer_latency[] = {
> {
> .deactivate_func = omap_device_idle_hwmods,
> @@ -437,6 +450,7 @@ static int __init omap_timer_init(struct omap_hwmod *oh, void *unused)
> struct dmtimer_platform_data *pdata;
> struct omap_device *od;
> struct omap_timer_capability_dev_attr *timer_dev_attr;
> + struct powerdomain *pwrdm;
>
> pr_debug("%s: %s\n", __func__, oh->name);
>
> @@ -466,6 +480,9 @@ static int __init omap_timer_init(struct omap_hwmod *oh, void *unused)
>
> pdata->set_timer_src = omap2_dm_timer_set_src;
> pdata->timer_ip_type = oh->class->rev;
> + pwrdm = omap_hwmod_get_pwrdm(oh);
> + pdata->loses_context = pwrdm_can_ever_lose_context(pwrdm);
> + pdata->get_context_loss_count = omap_timer_get_context_loss;
>
> od = omap_device_build(name, id, oh, pdata, sizeof(*pdata),
> omap2_dmtimer_latency,
> diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
> index cdef48b..db14d7f 100644
> --- a/arch/arm/plat-omap/dmtimer.c
> +++ b/arch/arm/plat-omap/dmtimer.c
> @@ -151,12 +151,14 @@ static void omap_dm_timer_wait_for_reset(struct omap_dm_timer *timer)
>
> 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->io_base, 0, 0, timer->func_offset);
> + omap_dm_timer_disable(timer);
> timer->posted = 1;
> }
>
> @@ -171,14 +173,13 @@ void omap_dm_timer_prepare(struct omap_dm_timer *timer)
> return;
> }
>
> - omap_dm_timer_enable(timer);
> -
> if (pdata->needs_manual_reset)
> omap_dm_timer_reset(timer);
>
> omap_dm_timer_set_source(timer, OMAP_TIMER_SRC_32_KHZ);
>
> timer->posted = 1;
> + timer->context_changed = true;
You should protect these variables from races.
> }
>
> struct omap_dm_timer *omap_dm_timer_request(void)
> @@ -230,7 +231,6 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_request_specific);
>
> void omap_dm_timer_free(struct omap_dm_timer *timer)
> {
> - omap_dm_timer_disable(timer);
> clk_put(timer->fclk);
>
> WARN_ON(!timer->reserved);
> @@ -311,6 +311,11 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_modify_idlect_mask);
>
> void omap_dm_timer_trigger(struct omap_dm_timer *timer)
> {
> + if (unlikely(!timer->reserved)) {
> + pr_err("%s: timer%d not enabled.\n", __func__, timer->id);
> + return;
> + }
> +
> omap_dm_timer_write_reg(timer, OMAP_TIMER_TRIGGER_REG, 0);
> }
> EXPORT_SYMBOL_GPL(omap_dm_timer_trigger);
> @@ -319,6 +324,20 @@ void omap_dm_timer_start(struct omap_dm_timer *timer)
> {
> u32 l;
>
> + omap_dm_timer_enable(timer);
> +
> + if (timer->loses_context) {
> + u32 ctx_loss_cnt_after;
> +
> + ctx_loss_cnt_after =
> + timer->get_context_loss_count(&timer->pdev->dev);
> + if ((ctx_loss_cnt_after != timer->ctx_loss_count)&&
> + timer->context_saved) {
> + omap_timer_restore_context(timer);
> + timer->context_saved = false;
Ditto. It applies to rest of the patch.
Rest look ok.
Regards
Santosh
More information about the linux-arm-kernel
mailing list