RE: android-omap-2.6.29 for gumstix overo

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Vikram,
                  I took a look at the zoom2_pm_defconfig file that you sent me, and it is mising the following entries to activate power management

#
# Power management options
#
CONFIG_PM_SLEEP=y
CONFIG_SUSPEND=y
CONFIG_SUSPEND_FREEZER=y

For the mmc off patch set, there are 2 patches, with one being slightly different from the other. Why is this so? Also which one should I use. I have reproduced the differences between patch set 1 and patch set 2 below:

It differs in 3 areas:

1. use of int vs. unsigned
2. static int omap_hsmmc_enable_clks in patch set 1 has more code than the one in patch set 2
3. host->off_counter = 0;

Patch set 1

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);
+	OMAP_HSMMC_WRITE(host->base, HCTL, OMAP_HSMMC_READ(host->base,
+		HCTL) | SDBP);
+}
+
 static int omap_hsmmc_enable_clks(struct mmc_omap_host *host)
 {
-	unsigned long flags;
+	unsigned long flags, timeout;
 	int ret = 0;
 
 	spin_lock_irqsave(&host->clk_lock, flags);
@@ -190,6 +228,24 @@ static int omap_hsmmc_enable_clks(struct mmc_omap_host *host)
 				host->dbclk_enabled = 1;
 	}
 
+	if (!(host->pdata->context_loss) ||
+		(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);
+	}
+
 done:
 	spin_unlock_irqrestore(&host->clk_lock, flags);
 	return ret;
@@ -211,6 +267,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;

@@ -1094,6 +1154,8 @@ static int __init omap_mmc_probe(struct platform_device *pdev)
 	host->inact_timer.data = (unsigned long) host;
 
 	host->clks_enabled = 0;
+	host->off_counter = 0;
+
 	host->iclk = clk_get(&pdev->dev, "mmchs_ick");
 	if (IS_ERR(host->iclk)) {
 		ret = PTR_ERR(host->iclk);


Best regards,

Elvis
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Arm (vger)]     [ARM Kernel]     [ARM MSM]     [Linux Tegra]     [Linux WPAN Networking]     [Linux Wireless Networking]     [Maemo Users]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux