public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Adrian Hunter <adrian.hunter@nokia.com>
To: Andrew Morton <akpm@linux-foundation.org>
Cc: Jarkko Lavinen <jarkko.lavinen@nokia.com>,
	Adrian Hunter <adrian.hunter@nokia.com>,
	linux-omap Mailing List <linux-omap@vger.kernel.org>,
	Pierre Ossman <pierre@ossman.eu>,
	Denis Karpov <ext-denis.2.karpov@nokia.com>,
	Matt Fleming <matt@console-pimps.org>,
	lkml <linux-kernel@vger.kernel.org>
Subject: [PATCH V2 20/32] omap_hsmmc: put MMC regulator to sleep
Date: Tue, 28 Jul 2009 13:41:02 +0300	[thread overview]
Message-ID: <20090728104102.2371.11129.sendpatchset@ahunter-laptop> (raw)
In-Reply-To: <20090728103834.2371.65809.sendpatchset@ahunter-laptop>

>From a5e206faac032a8e52721904dbdda0bd4ba01ecf Mon Sep 17 00:00:00 2001
From: Adrian Hunter <adrian.hunter@nokia.com>
Date: Tue, 12 May 2009 20:54:51 +0300
Subject: [PATCH] omap_hsmmc: put MMC regulator to sleep

When a card is not in use, the voltage regulator can be put
to sleep.  This is an alternative to powering the card off,
when powering off is not safe because the card might be
replaced without the driver being aware of it.

That situation happens if:
	- the card is removable i.e. not eMMC
	- and there is no card detect
	- and there is a cover switch but the cover is open

Signed-off-by: Adrian Hunter <adrian.hunter@nokia.com>
---
 drivers/mmc/host/omap_hsmmc.c |   59 +++++++++++++++++++++++++++++++++++++---
 1 files changed, 54 insertions(+), 5 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index a3418b5..7a17901 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -160,6 +160,7 @@ struct mmc_omap_host {
 	int			response_busy;
 	int			context_loss;
 	int			dpm_state;
+	int			vdd;
 
 	struct	omap_mmc_platform_data	*pdata;
 };
@@ -1031,10 +1032,12 @@ static void omap_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 		case MMC_POWER_OFF:
 			mmc_slot(host).set_power(host->dev, host->slot_id,
 						 0, 0);
+			host->vdd = 0;
 			break;
 		case MMC_POWER_UP:
 			mmc_slot(host).set_power(host->dev, host->slot_id,
 						 1, ios->vdd);
+			host->vdd = ios->vdd;
 			break;
 		case MMC_POWER_ON:
 			do_send_init_stream = 1;
@@ -1172,19 +1175,20 @@ static void omap_hsmmc_init(struct mmc_omap_host *host)
 
 /*
  * Dynamic power saving handling, FSM:
- *   ENABLED -> DISABLED -> OFF
+ *   ENABLED -> DISABLED -> OFF / REGSLEEP
  *     ^___________|          |
  *     |______________________|
  *
  * ENABLED:   mmc host is fully functional
  * DISABLED:  fclk is off
  * OFF:       fclk is off,voltage regulator is off
+ * REGSLEEP:  fclk is off,voltage regulator is asleep
  *
  * Transition handlers return the timeout for the next state transition
  * or negative error.
  */
 
-enum {ENABLED = 0, DISABLED, OFF};
+enum {ENABLED = 0, DISABLED, REGSLEEP, OFF};
 
 /* Handler for [ENABLED -> DISABLED] transition */
 static int omap_mmc_enabled_to_disabled(struct mmc_omap_host *host)
@@ -1221,8 +1225,12 @@ static int omap_mmc_disabled_to_off(struct mmc_omap_host *host)
 	     mmc_slot(host).get_cover_state(host->dev, host->slot_id))) {
 		mmc_power_save_host(host->mmc);
 		new_state = OFF;
-	} else
-		new_state = DISABLED;
+	} else {
+		if (mmc_slot(host).set_sleep)
+			mmc_slot(host).set_sleep(host->dev, host->slot_id,
+						 1, 0, 0);
+		new_state = REGSLEEP;
+	}
 
 	OMAP_HSMMC_WRITE(host->base, ISE, 0);
 	OMAP_HSMMC_WRITE(host->base, IE, 0);
@@ -1279,6 +1287,44 @@ static int omap_mmc_off_to_enabled(struct mmc_omap_host *host)
 	return 0;
 }
 
+/* Handler for [REGSLEEP -> ENABLED] transition */
+static int omap_mmc_regsleep_to_enabled(struct mmc_omap_host *host)
+{
+	unsigned long timeout;
+
+	dev_dbg(mmc_dev(host->mmc), "REGSLEEP -> ENABLED\n");
+
+	clk_enable(host->fclk);
+	clk_enable(host->iclk);
+
+	if (clk_enable(host->dbclk))
+		dev_dbg(mmc_dev(host->mmc),
+			"Enabling debounce clk failed\n");
+
+	omap_mmc_restore_ctx(host);
+
+	/*
+	 * We turned off interrupts and bus power.  Interrupts
+	 * are turned on by 'mmc_omap_start_command()' so we
+	 * just need to turn on the bus power here.
+	 */
+	OMAP_HSMMC_WRITE(host->base, HCTL,
+			 OMAP_HSMMC_READ(host->base, HCTL) | SDBP);
+
+	timeout = jiffies + msecs_to_jiffies(MMC_TIMEOUT_MS);
+	while ((OMAP_HSMMC_READ(host->base, HCTL) & SDBP) != SDBP &&
+	       time_before(jiffies, timeout))
+		;
+
+	if (mmc_slot(host).set_sleep)
+		mmc_slot(host).set_sleep(host->dev, host->slot_id,
+					 0, host->vdd, 0);
+
+	host->dpm_state = ENABLED;
+
+	return 0;
+}
+
 /*
  * Bring MMC host to ENABLED from any other PM state.
  */
@@ -1289,6 +1335,8 @@ static int omap_mmc_enable(struct mmc_host *mmc)
 	switch (host->dpm_state) {
 	case DISABLED:
 		return omap_mmc_disabled_to_enabled(host);
+	case REGSLEEP:
+		return omap_mmc_regsleep_to_enabled(host);
 	case OFF:
 		return omap_mmc_off_to_enabled(host);
 	default:
@@ -1386,7 +1434,8 @@ static int mmc_regs_show(struct seq_file *s, void *data)
 			host->dpm_state, mmc->nesting_cnt,
 			host->context_loss, context_loss);
 
-	if (host->suspended || host->dpm_state == OFF) {
+	if (host->suspended || host->dpm_state == OFF ||
+	    host->dpm_state == REGSLEEP) {
 		seq_printf(s, "host suspended, can't read registers\n");
 		return 0;
 	}
-- 
1.5.6.3


  parent reply	other threads:[~2009-07-28 10:40 UTC|newest]

Thread overview: 43+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-07-28 10:38 [PATCH V2 0/32] mmc and omap_hsmmc patches Adrian Hunter
2009-07-28 10:38 ` [PATCH V2 1/32] mmc: add 'enable' and 'disable' methods to mmc host Adrian Hunter
2009-07-28 10:38 ` [PATCH V2 2/32] mmc: allow host claim / release nesting Adrian Hunter
2009-07-28 10:38 ` [PATCH V2 3/32] mmc: add MMC_CAP_NONREMOVABLE host capability Adrian Hunter
2009-07-28 10:39 ` [PATCH V2 4/32] mmc: add ability to save power by powering off cards Adrian Hunter
2009-07-30  1:05   ` Madhusudhan
2009-07-30  7:16     ` Adrian Hunter
2009-07-28 10:39 ` [PATCH V2 5/32] mmc: add mmc card sleep and awake support Adrian Hunter
2009-07-28 10:39 ` [PATCH V2 6/32] mmc: power off once at removal Adrian Hunter
2009-07-28 10:39 ` [PATCH V2 7/32] mmc: add host capabilities for SD only and MMC only Adrian Hunter
2009-07-28 10:39 ` [PATCH V2 8/32] mmc: check status after MMC SWITCH command Adrian Hunter
2009-07-28 10:39 ` [PATCH V2 9/32] omap_hsmmc: add debugfs entry (host registers) Adrian Hunter
2009-07-28 10:39 ` [PATCH V2 10/32] omap_hsmmc: make use of new enable/disable interface Adrian Hunter
2009-07-28 10:39 ` [PATCH V2 11/32] ARM: OMAP: mmc-twl4030: add context loss counter support Adrian Hunter
2009-07-28 10:40 ` [PATCH V2 12/32] omap_hsmmc: keep track of power mode Adrian Hunter
2009-07-28 10:40 ` [PATCH V2 13/32] omap_hsmmc: context save/restore support Adrian Hunter
2009-07-30  2:00   ` Madhusudhan
2009-07-30  7:40     ` Adrian Hunter
2009-07-30 19:12       ` Madhusudhan
2009-07-30 19:33         ` Adrian Hunter
2009-07-28 10:40 ` [PATCH V2 14/32] omap_hsmmc: set open drain bit correctly Adrian Hunter
2009-07-28 10:40 ` [PATCH V2 15/32] omap_hsmmc: ensure workqueues are empty before suspend Adrian Hunter
2009-07-28 10:40 ` [PATCH V2 16/32] omap_hsmmc: fix scatter-gather list sanity checking Adrian Hunter
2009-07-28 10:40 ` [PATCH V2 17/32] omap_hsmmc: make use of new MMC_CAP_NONREMOVABLE host capability Adrian Hunter
2009-07-28 10:40 ` [PATCH V2 18/32] omap_hsmmc: support for deeper power saving states Adrian Hunter
2009-07-28 10:40 ` [PATCH V2 19/32] ARM: OMAP: mmc-twl4030: add regulator sleep / wake function Adrian Hunter
2009-07-28 10:41 ` Adrian Hunter [this message]
2009-07-28 10:41 ` [PATCH V2 21/32] omap_hsmmc: add mmc card sleep and awake support Adrian Hunter
2009-07-28 10:41 ` [PATCH V2 22/32] omap_hsmmc: fix NULL pointer dereference Adrian Hunter
2009-07-28 10:41 ` [PATCH V2 23/32] omap_hsmmc: cleanup macro usage Adrian Hunter
2009-07-28 10:41 ` [PATCH V2 24/32] omap_hsmmc: clear interrupt status after init sequence Adrian Hunter
2009-07-28 10:41 ` [PATCH V2 25/32] omap_hsmmc: cater for weird CMD6 behaviour Adrian Hunter
2009-07-28 10:41 ` [PATCH V2 26/32] omap_hsmmc: prevent races with irq handler Adrian Hunter
2009-07-28 10:41 ` [PATCH V2 27/32] omap_hsmmc: pass host capabilities for SD only and MMC only Adrian Hunter
2009-07-28 10:42 ` [PATCH V2 28/32] omap_hsmmc: code refactoring Adrian Hunter
2009-07-28 10:42 ` [PATCH V2 29/32] omap_hsmmc: protect the card when the cover is open Adrian Hunter
2009-07-28 10:42 ` [PATCH V2 30/32] omap_hsmmc: ensure all clock enables and disables are paired Adrian Hunter
2009-07-28 10:42 ` [PATCH V2 31/32] omap_hsmmc: set a large data timeout for commands with busy signal Adrian Hunter
2009-07-28 10:42 ` [PATCH V2 32/32] ARM: OMAP: RX51: set MMC capabilities and power-saving flag Adrian Hunter
2009-07-29 11:13 ` [PATCH V2 0/32] mmc and omap_hsmmc patches Matt Fleming
2009-07-31  0:52   ` Madhusudhan
2009-08-13 15:27     ` Madhusudhan
2009-08-13 16:29       ` Andrew Morton

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20090728104102.2371.11129.sendpatchset@ahunter-laptop \
    --to=adrian.hunter@nokia.com \
    --cc=akpm@linux-foundation.org \
    --cc=ext-denis.2.karpov@nokia.com \
    --cc=jarkko.lavinen@nokia.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-omap@vger.kernel.org \
    --cc=matt@console-pimps.org \
    --cc=pierre@ossman.eu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox