linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] mmc: dw_mmc: Disable low power mode if SDIO interrupts are used
@ 2012-07-20 18:13 Doug Anderson
  2012-07-21 10:40 ` Will Newton
  0 siblings, 1 reply; 17+ messages in thread
From: Doug Anderson @ 2012-07-20 18:13 UTC (permalink / raw)
  To: linux-mmc
  Cc: Chris Ball, Will Newton, James Hogan, Seungwon Jeon,
	Jaehoon Chung, linux-kernel, Doug Anderson

The documentation for the dw_mmc part says that the low power
mode should normally only be set for MMC and SD memory and should
be turned off for SDIO cards that need interrupts detected.

The best place I could find to do this is when the SDIO interrupt
was first enabled.  I rely on the fact that dw_mci_setup_bus()
will be called when it's time to reenable.

Change-Id: Id0e33a4e3a0a77ce8a5053b6e73197d53a5d46bb
Signed-off-by: Doug Anderson <dianders@chromium.org>
---
 drivers/mmc/host/dw_mmc.c |   33 +++++++++++++++++++++++++++++++++
 1 files changed, 33 insertions(+), 0 deletions(-)

diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index 72dc3cd..0cb2756 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -862,6 +862,31 @@ static int dw_mci_get_cd(struct mmc_host *mmc)
 	return present;
 }
 
+/*
+ * Disable lower power mode.
+ *
+ * Low power mode will stop the card clock when idle.  According to
+ * documentation we should disable low power mode for SDIO cards if we
+ * need interrupts to work.
+ *
+ * This function is fast if the power mode is already disabled.
+ */
+static void dw_mci_disable_low_power(struct mmc_host *mmc)
+{
+	struct dw_mci_slot *slot = mmc_priv(mmc);
+	struct dw_mci *host = slot->host;
+	u32 clk_en_a;
+	const u32 clken_low_pwr = SDMMC_CLKEN_LOW_PWR << slot->id;
+
+	clk_en_a = mci_readl(host, CLKENA);
+
+	if (clk_en_a & clken_low_pwr) {
+		mci_writel(host, CLKENA, clk_en_a & ~clken_low_pwr);
+		mci_send_cmd(slot, SDMMC_CMD_UPD_CLK |
+			     SDMMC_CMD_PRV_DAT_WAIT, 0);
+	}
+}
+
 static void dw_mci_enable_sdio_irq(struct mmc_host *mmc, int enb)
 {
 	struct dw_mci_slot *slot = mmc_priv(mmc);
@@ -871,6 +896,14 @@ static void dw_mci_enable_sdio_irq(struct mmc_host *mmc, int enb)
 	/* Enable/disable Slot Specific SDIO interrupt */
 	int_mask = mci_readl(host, INTMASK);
 	if (enb) {
+		/*
+		 * Turn off low power mode if it was enabled.  This is a bit of
+		 * a heavy operation and we disable / enable IRQs a lot, so
+		 * we'll leave them disabled; they will get re-enabled again in
+		 * dw_mci_setup_bus().
+		 */
+		dw_mci_disable_low_power(mmc);
+
 		mci_writel(host, INTMASK,
 			   (int_mask | SDMMC_INT_SDIO(slot->id)));
 	} else {
-- 
1.7.7.3


^ permalink raw reply related	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2012-08-08  3:41 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-07-20 18:13 [PATCH] mmc: dw_mmc: Disable low power mode if SDIO interrupts are used Doug Anderson
2012-07-21 10:40 ` Will Newton
2012-07-23  2:48   ` Doug Anderson
2012-07-23  9:19     ` Will Newton
2012-07-23 17:00       ` Doug Anderson
2012-07-23 17:02         ` [PATCH v2] " Doug Anderson
2012-07-24  1:17           ` Seungwon Jeon
2012-07-24 16:58             ` Doug Anderson
2012-07-24  1:36           ` Jaehoon Chung
2012-07-24 16:58             ` Doug Anderson
2012-07-24 16:59               ` [PATCH v3] " Doug Anderson
2012-07-25  9:11                 ` Will Newton
2012-07-25 10:02                 ` Jaehoon Chung
2012-07-25 15:32                   ` Doug Anderson
2012-07-25 15:33                     ` [PATCH v4] " Doug Anderson
2012-07-26  4:00                       ` Seungwon Jeon
2012-08-08  3:40                         ` Chris Ball

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).