diff options
author | Iliyan Malchev <malchev@google.com> | 2011-09-06 22:06:04 -0700 |
---|---|---|
committer | Iliyan Malchev <malchev@google.com> | 2011-09-06 22:06:04 -0700 |
commit | f0684621648fc997915507188ce512a445a9bab1 (patch) | |
tree | e3fa78fd3f9a1f6b085ba6e5774c69947e238dcb /arch/arm/plat-omap | |
parent | e16ec00c7a8db14c665cac8417d17d2232e62f1e (diff) | |
parent | f7dfd268d6c63662c222d226b835b8f273f9daab (diff) | |
download | kernel_samsung_tuna-f0684621648fc997915507188ce512a445a9bab1.zip kernel_samsung_tuna-f0684621648fc997915507188ce512a445a9bab1.tar.gz kernel_samsung_tuna-f0684621648fc997915507188ce512a445a9bab1.tar.bz2 |
Merge branch 'linux-omap-3.0' into android-omap-3.0
Diffstat (limited to 'arch/arm/plat-omap')
-rw-r--r-- | arch/arm/plat-omap/dmtimer.c | 9 | ||||
-rw-r--r-- | arch/arm/plat-omap/include/plat/gpio.h | 3 | ||||
-rw-r--r-- | arch/arm/plat-omap/include/plat/omap-pm.h | 23 | ||||
-rw-r--r-- | arch/arm/plat-omap/include/plat/omap_hwmod.h | 4 | ||||
-rw-r--r-- | arch/arm/plat-omap/omap-pm-interface.c | 56 |
5 files changed, 47 insertions, 48 deletions
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c index 26e572c..bccbb30 100644 --- a/arch/arm/plat-omap/dmtimer.c +++ b/arch/arm/plat-omap/dmtimer.c @@ -45,6 +45,7 @@ #include <plat/dmtimer.h> #include <plat/common.h> +#include <plat/omap-pm.h> /* register offsets */ #define _OMAP_TIMER_ID_OFFSET 0x00 @@ -575,9 +576,7 @@ int omap_dm_timer_start(struct omap_dm_timer *timer) u32 ctx_loss_cnt_after; __timer_enable(timer); - ctx_loss_cnt_after = - timer->get_context_loss_count(&timer->pdev->dev); - if ((ctx_loss_cnt_after != timer->ctx_loss_count) && + if (omap_pm_was_context_lost(&timer->pdev->dev) && timer->context_saved) { omap_timer_restore_context(timer); timer->context_saved = false; @@ -630,9 +629,6 @@ int omap_dm_timer_stop(struct omap_dm_timer *timer) OMAP_TIMER_INT_OVERFLOW); if (timer->loses_context) { - if (timer->get_context_loss_count) - timer->ctx_loss_count = - timer->get_context_loss_count(&timer->pdev->dev); omap_timer_save_context(timer); timer->context_saved = true; __timer_disable(timer); @@ -988,7 +984,6 @@ static int __devinit omap_dm_timer_probe(struct platform_device *pdev) timer->is_early_init = pdata->is_early_init; timer->needs_manual_reset = pdata->needs_manual_reset; timer->loses_context = pdata->loses_context; - timer->get_context_loss_count = pdata->get_context_loss_count; spin_lock_init(&timer->lock); /* Skip pm_runtime_enable during early boot and for OMAP1 */ diff --git a/arch/arm/plat-omap/include/plat/gpio.h b/arch/arm/plat-omap/include/plat/gpio.h index 921ece3..24b61af 100644 --- a/arch/arm/plat-omap/include/plat/gpio.h +++ b/arch/arm/plat-omap/include/plat/gpio.h @@ -211,9 +211,6 @@ struct omap_gpio_platform_data { u32 non_wakeup_gpios; struct omap_gpio_reg_offs *regs; - - /* Return context loss count due to PM states changing */ - int (*get_context_loss_count)(struct device *dev); }; extern void omap2_gpio_prepare_for_idle(int off_mode); diff --git a/arch/arm/plat-omap/include/plat/omap-pm.h b/arch/arm/plat-omap/include/plat/omap-pm.h index c57a07e..2efbff5 100644 --- a/arch/arm/plat-omap/include/plat/omap-pm.h +++ b/arch/arm/plat-omap/include/plat/omap-pm.h @@ -343,23 +343,14 @@ unsigned long omap_pm_cpu_get_freq(void); */ /** - * omap_pm_get_dev_context_loss_count - return count of times dev has lost ctx - * @dev: struct device * - * - * This function returns the number of times that the device @dev has - * lost its internal context. This generally occurs on a powerdomain - * transition to OFF. Drivers use this as an optimization to avoid restoring - * context if the device hasn't lost it. To use, drivers should initially - * call this in their context save functions and store the result. Early in - * the driver's context restore function, the driver should call this function - * again, and compare the result to the stored counter. If they differ, the - * driver must restore device context. If the number of context losses - * exceeds the maximum positive integer, the function will wrap to 0 and - * continue counting. Returns the number of context losses for this device, - * or -EINVAL upon error. + * omap_pm_was_context_lost - return true if a device lost hw context + * + * This function returns a bool value indication if a device has lost + * its context. Depending on the HW implementation of the device, Context + * can be lost in OFF or OSWR. This function reads and *CLEARS* the context + * lost registers for the device. */ -int omap_pm_get_dev_context_loss_count(struct device *dev); - +bool omap_pm_was_context_lost(struct device *dev); /** * omap_pm_set_min_mpu_freq - sets the min frequency the mpu should be allowed diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h index 42dacc6..2f279ad 100644 --- a/arch/arm/plat-omap/include/plat/omap_hwmod.h +++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h @@ -369,11 +369,15 @@ struct omap_hwmod_omap2_prcm { * struct omap_hwmod_omap4_prcm - OMAP4-specific PRCM data * @clkctrl_reg: PRCM address of the clock control register * @rstctrl_reg: address of the XXX_RSTCTRL register located in the PRM + * @context_reg: addres of the context register + * @ctx_restore_trig : indicates if RFF or DFF or both lost + * should trigger ctx restore. * @submodule_wkdep_bit: bit shift of the WKDEP range */ struct omap_hwmod_omap4_prcm { void __iomem *clkctrl_reg; void __iomem *rstctrl_reg; + void __iomem *context_reg; u8 submodule_wkdep_bit; }; diff --git a/arch/arm/plat-omap/omap-pm-interface.c b/arch/arm/plat-omap/omap-pm-interface.c index b47e784..e166395 100644 --- a/arch/arm/plat-omap/omap-pm-interface.c +++ b/arch/arm/plat-omap/omap-pm-interface.c @@ -19,12 +19,13 @@ #include <linux/cpufreq.h> #include <linux/device.h> #include <linux/platform_device.h> - +#include <linux/io.h> /* Interface documentation is in mach/omap-pm.h */ #include <plat/omap-pm.h> #include <plat/omap_device.h> #include "omap-pm-helper.h" +#include "../mach-omap2/prm44xx.h" bool off_mode_enabled; @@ -193,32 +194,43 @@ void omap_pm_disable_off_mode(void) off_mode_enabled = false; } -/* - * Device context loss tracking - * WARNING: at this point we dont have a reliable context loss reporting - * mechanism. Instead, we ensure that we report context loss always. - */ -int omap_pm_get_dev_context_loss_count(struct device *dev) +bool omap_pm_was_context_lost(struct device *dev) { - static u32 count = 1; + struct platform_device *pdev; + struct omap_device *od; + struct omap_hwmod *oh; - if (!dev) { - WARN_ON(1); - return -EINVAL; - }; + if (!dev) + goto save_ctx; + + pdev = container_of(dev, struct platform_device, dev); + od = container_of(pdev, struct omap_device, pdev); + oh = od->hwmods[0]; + + if (!oh || !cpu_is_omap44xx()) + goto save_ctx; + + if (oh->prcm.omap4.context_reg) { + u32 context_reg_val = 0; + + /*Read what context was lost.*/ + context_reg_val = __raw_readl(oh->prcm.omap4.context_reg); + + /*clear context lost bits after read*/ + __raw_writel(context_reg_val, oh->prcm.omap4.context_reg); - count++; + /* ABE special case, only report ctx lost when we loose + * mem, otherwise, constant firmware reload causes problems. + */ + if (oh->prcm.omap4.context_reg == OMAP4430_RM_ABE_AESS_CONTEXT) + context_reg_val &= (1 << 8); - /* - * Context loss count has to be a non-negative value. - * Clear the sign bit to get a value range from 0 to - * INT_MAX. Roll over to 1 - */ - count = (count & ~INT_MAX) ? 1 : count; + return (context_reg_val != 0); + } - pr_debug("OMAP PM: returning context loss count for dev %s count %ul\n", - dev_name(dev), count); - return count; +save_ctx: + /* by default return true so that driver will restore context*/ + return true; } /* Should be called before clk framework init */ |