diff --git a/arch/arm/plat-omap/include/mach/mmc.h b/arch/arm/plat-omap/include/mach/mmc.h
index de23cc8..ae4eea8 100644
--- a/arch/arm/plat-omap/include/mach/mmc.h
+++ b/arch/arm/plat-omap/include/mach/mmc.h
@@ -62,6 +62,9 @@ struct omap_mmc_platform_data {
 	int (*suspend)(struct device *dev, int slot);
 	int (*resume)(struct device *dev, int slot);
  
+	/* To get the OFF mode counter */
+	int (*context_loss) (struct device *dev);
+

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index eb40a47..546b49d 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -150,14 +152,50 @@ struct mmc_omap_host {
 	int			slot_id;
 	int			dbclk_enabled;
 	int 			clks_enabled;
+	int			off_counter;
 	spinlock_t		clk_lock;
 	struct timer_list	inact_timer;
 	struct	omap_mmc_platform_data	*pdata;
 };

@@ -190,6 +228,43 @@ static int omap_hsmmc_enable_clks(struct mmc_omap_host *host)
 				host->dbclk_enabled = 1;
 	}
 
+	if (host->pdata->context_loss) {
+		if (host->pdata->context_loss(host->dev) > 0) {
+			if (host->pdata->context_loss(host->dev) >
+				host->off_counter) {
+				/* Coming out of OFF:
+				 * The SRA bit of SYSCTL reg has a wrong reset
+				 * value.
+				 * The bit resets automatically in subsequent
+				 * reads. Idealy it should have been 0 as per
+				 * the reset value of the register.
+				 * Wait for the reset to complete */
+				timeout = jiffies +
+					msecs_to_jiffies(MMC_TIMEOUT_MS);
+				while ((OMAP_HSMMC_READ(host->base, SYSSTATUS)
+					& RESETDONE) != RESETDONE
+					&& time_before(jiffies, timeout))
+					;
+				omap2_hsmmc_restore_ctx(host);
+			}
+		}
+	} else {
+		/* Restore allways */
+		/* Coming out of OFF:
+		 * The SRA bit of SYSCTL reg has a wrong reset
+		 * value.
+		 * The bit resets automatically in subsequent
+		 * reads. Idealy it should have been 0 as per
+		 * the reset value of the register.
+		 * Wait for the reset to complete */
+		timeout = jiffies + msecs_to_jiffies(MMC_TIMEOUT_MS);
+		while ((OMAP_HSMMC_READ(host->base, SYSSTATUS)
+			& RESETDONE) != RESETDONE
+			&& time_before(jiffies, timeout))
+			;
+		omap2_hsmmc_restore_ctx(host);
+	}
+
 done:
 	spin_unlock_irqrestore(&host->clk_lock, flags);
 	return ret;
@@ -211,6 +286,10 @@ static void omap_hsmmc_disable_clks(struct mmc_omap_host *host)
 	if (!host->clks_enabled)
 		goto done;
 
+	omap2_hsmmc_save_ctx(host);
+	if (host->pdata->context_loss)
+		host->off_counter = host->pdata->context_loss(host->dev);
+
 	clk_disable(host->fclk);
 	clk_disable(host->iclk);
 	host->clks_enabled = 0;


patch set 2

diff --git a/arch/arm/plat-omap/include/mach/mmc.h b/arch/arm/plat-omap/include/mach/mmc.h
index de23cc8..94617d3 100644
--- a/arch/arm/plat-omap/include/mach/mmc.h
+++ b/arch/arm/plat-omap/include/mach/mmc.h
@@ -62,6 +62,9 @@ struct omap_mmc_platform_data {
 	int (*suspend)(struct device *dev, int slot);
 	int (*resume)(struct device *dev, int slot);
 
+	/* To get the OFF mode counter */
+	unsigned (*context_loss) (struct device *dev);
+

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index eb40a47..d9b962e 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -150,14 +152,50 @@ struct mmc_omap_host {
 	int			slot_id;
 	int			dbclk_enabled;
 	int 			clks_enabled;
+	unsigned		off_counter;
 	spinlock_t		clk_lock;
 	struct timer_list	inact_timer;
 	struct	omap_mmc_platform_data	*pdata;
 };

@@ -150,14 +152,50 @@ struct mmc_omap_host {
 	int			slot_id;
 	int			dbclk_enabled;
 	int 			clks_enabled;
+	unsigned		off_counter;
 	spinlock_t		clk_lock;
 	struct timer_list	inact_timer;
 	struct	omap_mmc_platform_data	*pdata;
 };
 
+struct omap_hsmmc_regs {
+	u32 hctl;
+	u32 capa;
+	u32 sysconfig;
+	u32 ise;
+	u32 ie;
+	u32 con;
+	u32 sysctl;
+};
+static struct omap_hsmmc_regs hsmmc_ctx[3];
+
+static void omap2_hsmmc_save_ctx(struct mmc_omap_host *host)
+{
+	/* MMC : context save */
+	hsmmc_ctx[host->id].hctl = OMAP_HSMMC_READ(host->base, HCTL);
+	hsmmc_ctx[host->id].capa = OMAP_HSMMC_READ(host->base, CAPA);
+	hsmmc_ctx[host->id].ise = OMAP_HSMMC_READ(host->base, ISE);
+	hsmmc_ctx[host->id].ie = OMAP_HSMMC_READ(host->base, IE);
+	hsmmc_ctx[host->id].con = OMAP_HSMMC_READ(host->base, CON);
+	hsmmc_ctx[host->id].sysctl = OMAP_HSMMC_READ(host->base, SYSCTL);
+}
+
+static void omap2_hsmmc_restore_ctx(struct mmc_omap_host *host)
+{
+	/* MMC : context restore */
+	OMAP_HSMMC_WRITE(host->base, HCTL, hsmmc_ctx[host->id].hctl);
+	OMAP_HSMMC_WRITE(host->base, CAPA, hsmmc_ctx[host->id].capa);
+	OMAP_HSMMC_WRITE(host->base, CON, hsmmc_ctx[host->id].con);
+	OMAP_HSMMC_WRITE(host->base, ISE, hsmmc_ctx[host->id].ise);
+	OMAP_HSMMC_WRITE(host->base, IE, hsmmc_ctx[host->id].ie);
+	OMAP_HSMMC_WRITE(host->base, SYSCTL, hsmmc_ctx[host->id].sysctl);
