aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-omap2/display.c2
-rw-r--r--arch/arm/mach-omap2/dmtimer.c11
-rw-r--r--arch/arm/mach-omap2/gpio.c11
-rw-r--r--arch/arm/mach-omap2/hsmmc.c13
-rw-r--r--arch/arm/mach-omap2/serial.c1
-rw-r--r--arch/arm/plat-omap/dmtimer.c9
-rw-r--r--arch/arm/plat-omap/include/plat/gpio.h3
-rw-r--r--arch/arm/plat-omap/include/plat/omap-pm.h23
-rw-r--r--arch/arm/plat-omap/include/plat/omap_hwmod.h4
-rw-r--r--arch/arm/plat-omap/omap-pm-interface.c29
-rw-r--r--drivers/gpio/gpio-omap.c16
-rw-r--r--drivers/misc/omap_temp_sensor.c23
-rw-r--r--drivers/mmc/host/omap_hsmmc.c35
-rw-r--r--drivers/tty/serial/omap-serial.c9
-rw-r--r--drivers/video/omap2/dss/dispc.c5
15 files changed, 38 insertions, 156 deletions
diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c
index a5b7a23..dd91c20 100644
--- a/arch/arm/mach-omap2/display.c
+++ b/arch/arm/mach-omap2/display.c
@@ -97,8 +97,6 @@ int __init omap_display_init(struct omap_dss_board_info *board_data)
}
pdata.board_data = board_data;
- pdata.board_data->get_context_loss_count =
- omap_pm_get_dev_context_loss_count;
for (i = 0; i < oh_count; i++) {
oh = omap_hwmod_lookup(curr_dss_hwmod[i].oh_name);
diff --git a/arch/arm/mach-omap2/dmtimer.c b/arch/arm/mach-omap2/dmtimer.c
index de25e98..e9cba71 100644
--- a/arch/arm/mach-omap2/dmtimer.c
+++ b/arch/arm/mach-omap2/dmtimer.c
@@ -94,16 +94,6 @@ 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_timer_get_context_loss NULL
-#endif
-
struct omap_device_pm_latency omap2_dmtimer_latency[] = {
{
.deactivate_func = omap_device_idle_hwmods,
@@ -169,7 +159,6 @@ static int __init omap_timer_init(struct omap_hwmod *oh, void *unused)
return -EINVAL;
}
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/mach-omap2/gpio.c b/arch/arm/mach-omap2/gpio.c
index a6ecd00..1045c72 100644
--- a/arch/arm/mach-omap2/gpio.c
+++ b/arch/arm/mach-omap2/gpio.c
@@ -35,16 +35,6 @@ static struct omap_device_pm_latency omap_gpio_latency[] = {
},
};
-#ifdef CONFIG_PM
-static int omap_gpio_get_context_loss(struct device *dev)
-{
- return omap_pm_get_dev_context_loss_count(dev);
-}
-
-#else
-#define omap_gpio_get_context_loss NULL
-#endif
-
static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused)
{
struct omap_device *od;
@@ -75,7 +65,6 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused)
pdata->suspend_support = true;
pdata->dbck_flag = dev_attr->dbck_flag;
pdata->virtual_irq_start = IH_GPIO_BASE + 32 * (id - 1);
- pdata->get_context_loss_count = omap_gpio_get_context_loss;
pdata->regs = kzalloc(sizeof(struct omap_gpio_reg_offs), GFP_KERNEL);
if (!pdata) {
diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
index 4baa1cc..f2697e2 100644
--- a/arch/arm/mach-omap2/hsmmc.c
+++ b/arch/arm/mach-omap2/hsmmc.c
@@ -31,17 +31,6 @@ static u16 control_mmc1;
#define HSMMC_NAME_LEN 9
-#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4) \
- && defined(CONFIG_PM)
-
-static int hsmmc_get_context_loss(struct device *dev)
-{
- return omap_pm_get_dev_context_loss_count(dev);
-}
-
-#else
-#define hsmmc_get_context_loss NULL
-#endif
static void omap_hsmmc1_before_set_reg(struct device *dev, int slot,
int power_on, int vdd)
@@ -319,8 +308,6 @@ static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c,
else
mmc->reg_offset = 0;
- mmc->get_context_loss_count = hsmmc_get_context_loss;
-
mmc->slots[0].switch_pin = c->gpio_cd;
mmc->slots[0].gpio_wp = c->gpio_wp;
diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
index c838629..2735777 100644
--- a/arch/arm/mach-omap2/serial.c
+++ b/arch/arm/mach-omap2/serial.c
@@ -32,6 +32,7 @@
#include <plat/clock.h>
#include <plat/dma.h>
#include <plat/omap_device.h>
+#include <plat/omap-pm.h>
#include "prm2xxx_3xxx.h"
#include "pm.h"
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..a9a9140 100644
--- a/arch/arm/plat-omap/omap-pm-interface.c
+++ b/arch/arm/plat-omap/omap-pm-interface.c
@@ -19,7 +19,7 @@
#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>
@@ -193,32 +193,9 @@ 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;
-
- if (!dev) {
- WARN_ON(1);
- return -EINVAL;
- };
-
- count++;
-
- /*
- * 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;
-
- pr_debug("OMAP PM: returning context loss count for dev %s count %ul\n",
- dev_name(dev), count);
- return count;
+ return true;
}
/* Should be called before clk framework init */
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
index 110567e..b20d3164 100644
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -27,6 +27,7 @@
#include <mach/irqs.h>
#include <mach/gpio.h>
#include <asm/mach/irq.h>
+#include <plat/omap-pm.h>
static LIST_HEAD(omap_gpio_list);
@@ -74,12 +75,9 @@ struct gpio_bank {
bool saved_context;
int stride;
u32 width;
- u32 ctx_loss_count;
u16 id;
void (*set_dataout)(struct gpio_bank *bank, int gpio, int enable);
- int (*get_context_loss_count)(struct device *dev);
-
struct omap_gpio_reg_offs *regs;
};
@@ -1139,7 +1137,6 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev)
bank->non_wakeup_gpios = pdata->non_wakeup_gpios;
bank->loses_context = pdata->loses_context;
bank->regs = pdata->regs;
- bank->get_context_loss_count = pdata->get_context_loss_count;
bank->saved_context = 0;
if (bank->regs->set_dataout && bank->regs->clr_dataout)
bank->set_dataout = _set_gpio_dataout_reg;
@@ -1285,8 +1282,6 @@ static int omap_gpio_pm_runtime_suspend(struct device *dev)
__raw_writel(l2, bank->base + bank->regs->risingdetect);
save_gpio_ctx:
- if (bank->get_context_loss_count)
- bank->ctx_loss_count = bank->get_context_loss_count(bank->dev);
omap_gpio_save_context(bank);
for (j = 0; j < hweight_long(bank->dbck_enable_mask); j++)
clk_disable(bank->dbck);
@@ -1300,19 +1295,14 @@ static int omap_gpio_pm_runtime_resume(struct device *dev)
#ifdef CONFIG_ARCH_OMAP2PLUS
struct platform_device *pdev = to_platform_device(dev);
struct gpio_bank *bank = platform_get_drvdata(pdev);
- u32 ctx_lost_cnt_after;
u32 l = 0, gen, gen0, gen1;
int j;
for (j = 0; j < hweight_long(bank->dbck_enable_mask); j++)
clk_enable(bank->dbck);
- if (bank->get_context_loss_count) {
- ctx_lost_cnt_after =
- bank->get_context_loss_count(bank->dev);
- if (ctx_lost_cnt_after != bank->ctx_loss_count)
- omap_gpio_restore_context(bank);
- }
+ if (omap_pm_was_context_lost(dev))
+ omap_gpio_restore_context(bank);
if (!(bank->enabled_non_wakeup_gpios))
return 0;
diff --git a/drivers/misc/omap_temp_sensor.c b/drivers/misc/omap_temp_sensor.c
index e53ea5c..3ec381f 100644
--- a/drivers/misc/omap_temp_sensor.c
+++ b/drivers/misc/omap_temp_sensor.c
@@ -40,6 +40,7 @@
#include <linux/types.h>
#include <plat/common.h>
+#include <plat/omap-pm.h>
#include <plat/omap_device.h>
#include <plat/temperature_sensor.h>
#include <plat/omap-pm.h>
@@ -85,6 +86,7 @@ struct omap_temp_sensor {
u8 clk_on;
unsigned long clk_rate;
u32 current_temp;
+ u32 save_ctx;
};
#ifdef CONFIG_PM
@@ -464,6 +466,7 @@ static int __devinit omap_temp_sensor_probe(struct platform_device *pdev)
temp_sensor->phy_base = pdata->offset;
temp_sensor->pdev = pdev;
temp_sensor->dev = dev;
+ temp_sensor->save_ctx = 0;
pm_runtime_enable(dev);
pm_runtime_irq_safe(dev);
@@ -647,34 +650,26 @@ omap_temp_sensor_suspend NULL
omap_temp_sensor_resume NULL
#endif /* CONFIG_PM */
-
static int omap_temp_sensor_runtime_suspend(struct device *dev)
{
struct omap_temp_sensor *temp_sensor =
platform_get_drvdata(to_platform_device(dev));
omap_temp_sensor_save_ctxt(temp_sensor);
-
+ temp_sensor->save_ctx = 1;
return 0;
}
static int omap_temp_sensor_runtime_resume(struct device *dev)
{
- static int context_loss_count;
- int temp;
struct omap_temp_sensor *temp_sensor =
platform_get_drvdata(to_platform_device(dev));
-
- temp = omap_pm_get_dev_context_loss_count(dev);
-
- /* consider error return from context loss as:
- * force context restore with a WARN_ON() */
- if (WARN_ON(temp < 0) ||
- (temp != context_loss_count && context_loss_count != 0))
+ if (temp_sensor->save_ctx)
+ return 0;
+ if (omap_pm_was_context_lost(dev)) {
omap_temp_sensor_restore_ctxt(temp_sensor);
-
- context_loss_count = temp;
-
+ temp_sensor->save_ctx = 0;
+ }
return 0;
}
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 2ca145b..18fc306 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -41,6 +41,7 @@
#include <plat/board.h>
#include <plat/mmc.h>
#include <plat/cpu.h>
+#include <plat/omap-pm.h>
/* OMAP HSMMC Host Controller Registers */
#define OMAP_HSMMC_SYSCONFIG 0x0010
@@ -181,7 +182,6 @@ struct omap_hsmmc_host {
int slot_id;
int got_dbclk;
int response_busy;
- int context_loss;
int dpm_state;
int vdd;
int protect_card;
@@ -597,21 +597,11 @@ static void omap_hsmmc_disable_irq(struct omap_hsmmc_host *host)
static int omap_hsmmc_context_restore(struct omap_hsmmc_host *host)
{
struct mmc_ios *ios = &host->mmc->ios;
- struct omap_mmc_platform_data *pdata = host->pdata;
- int context_loss = 0;
u32 hctl, capa, con;
u16 dsor = 0;
unsigned long timeout;
- if (pdata->get_context_loss_count) {
- context_loss = pdata->get_context_loss_count(host->dev);
- if (context_loss < 0)
- return 1;
- }
-
- dev_dbg(mmc_dev(host->mmc), "context was %slost\n",
- context_loss == host->context_loss ? "not " : "");
- if (host->context_loss == context_loss)
+ if (!omap_pm_was_context_lost(host->dev))
return 1;
/* Wait for hardware reset */
@@ -711,8 +701,6 @@ static int omap_hsmmc_context_restore(struct omap_hsmmc_host *host)
else
OMAP_HSMMC_WRITE(host->base, CON, con & ~OD);
out:
- host->context_loss = context_loss;
-
dev_dbg(mmc_dev(host->mmc), "context is restored\n");
return 0;
}
@@ -722,15 +710,7 @@ out:
*/
static void omap_hsmmc_context_save(struct omap_hsmmc_host *host)
{
- struct omap_mmc_platform_data *pdata = host->pdata;
- int context_loss;
-
- if (pdata->get_context_loss_count) {
- context_loss = pdata->get_context_loss_count(host->dev);
- if (context_loss < 0)
- return;
- host->context_loss = context_loss;
- }
+ return;
}
#else
@@ -1946,20 +1926,15 @@ static int omap_hsmmc_regs_show(struct seq_file *s, void *data)
{
struct mmc_host *mmc = s->private;
struct omap_hsmmc_host *host = mmc_priv(mmc);
- int context_loss = 0;
- if (host->pdata->get_context_loss_count)
- context_loss = host->pdata->get_context_loss_count(host->dev);
seq_printf(s, "mmc%d:\n"
" enabled:\t%d\n"
" dpm_state:\t%d\n"
" nesting_cnt:\t%d\n"
- " ctx_loss:\t%d:%d\n"
- "\nregs:\n",
+ " ct",
mmc->index, mmc->enabled ? 1 : 0,
- host->dpm_state, mmc->nesting_cnt,
- host->context_loss, context_loss);
+ host->dpm_state, mmc->nesting_cnt);
if (host->suspended || host->dpm_state == OFF) {
seq_printf(s, "host suspended, can't read registers\n");
diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c
index f2330bd..548cc88 100644
--- a/drivers/tty/serial/omap-serial.c
+++ b/drivers/tty/serial/omap-serial.c
@@ -1608,7 +1608,6 @@ static int omap_serial_runtime_suspend(struct device *dev)
if (up->rts_mux_driver_control)
omap_rts_mux_write(MUX_PULL_UP, up->port.line);
- up->context_loss_cnt = omap_pm_get_dev_context_loss_count(dev);
if (device_may_wakeup(dev))
up->enable_wakeup(up->pdev, true);
else
@@ -1623,13 +1622,7 @@ static int omap_serial_runtime_resume(struct device *dev)
struct omap_device *od;
if (up) {
- int loss_cnt = omap_pm_get_dev_context_loss_count(dev);
-
- /* We don't expect error in this function
- * Just in case its an error:
- * treat it as force-context-restore */
- if (WARN_ON(loss_cnt < 0) ||
- (up->context_loss_cnt != loss_cnt))
+ if (omap_pm_was_context_lost(dev))
omap_uart_restore_context(up);
if (up->use_dma) {
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 6bc2f29..b3d7bc8 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -39,7 +39,7 @@
#include <plat/sram.h>
#include <plat/clock.h>
#include <mach/tiler.h>
-
+#include <plat/omap-pm.h>
#include <video/omapdss.h>
#include "dss.h"
@@ -303,6 +303,7 @@ static void dispc_save_context(void)
static void dispc_restore_context(void)
{
+ struct device *dev = &dispc.pdev->dev;
int i, o, ctx;
DSSDBG("dispc_restore_context\n");
@@ -312,7 +313,7 @@ static void dispc_restore_context(void)
ctx = dispc_get_ctx_loss_count();
- if (ctx >= 0 && ctx == dispc.ctx_loss_cnt)
+ if (!omap_pm_was_context_lost(dev))
return;
DSSDBG("ctx_loss_count: saved %d, current %d\n",