linux-mmc.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/12] mmc: core: mmc_bus to handle suspend|resume|shutdown
@ 2013-06-10 15:03 Ulf Hansson
  2013-06-10 15:03 ` [PATCH 01/12] mmc: core: Remove unnecessary check for the remove callback Ulf Hansson
                   ` (13 more replies)
  0 siblings, 14 replies; 16+ messages in thread
From: Ulf Hansson @ 2013-06-10 15:03 UTC (permalink / raw)
  To: linux-mmc, Chris Ball; +Cc: Ulf Hansson

From: Ulf Hansson <ulf.hansson@linaro.org>

The MMC/SD/SDIO cards are registered on the mmc_bus and should from a power
management perspective be controlled from there. As of today each and every
host driver needs to issue mmc_suspend|resume_host from their respective
.suspend|resume methods, which seems like an unnecessary requirement to
put on them. Additionally, a shutdown sequence shall be initiated from the
mmc_bus.

This patch set moves the responsiblity to suspend the cards into the mmc_bus.
It also invents the shutdown sequence, also to be handled from the mmc_bus.
In the SDIO case, the shutdown sequence will not involve any SDIO specific
operations. If this would be desired, I suggest to handle that as and separate
step, since it would involve the sdio bus and potentially the sdio drivers.

As a part of the patches releated to adding the shutdown sequence, specific
issues to handle eMMC power off notification properly are included in this
patch set as well.

The mmc_suspend|resume_host functions are not removed, but will instead always
return successful. A separate patch(es) build on top of this patch set, shall
remove the API:s together with updating each and every host driver.

Do note, that patch 1 to 4 has been sent earlier in the set "mmc: core: Let the
mmc_bus handle suspend|resume sequence". Since the functionallity are very close
releated I decided to fold them in into this patch set.

A big thank you to Jaehoon Chung who has tested the patches 1 to 4.

Ulf Hansson (12):
  mmc: core: Remove unnecessary check for the remove callback
  mmc: core: Validate suspend prerequisites for SDIO at SUSPEND_PREPARE
  mmc: core: Push common suspend|resume code into each bus_ops
  mmc: core: Initiate suspend|resume from mmc bus instead of mmc host
  mmc: core: Handle card shutdown from mmc_bus
  mmc: core: Extend shutdown sequence to handle bus operations
  mmc: core: Add shutdown callback for SD bus_ops
  mmc: core: Handle both poweroff notification types for eMMC
  mmc: core: Add shutdown callback for (e)MMC bus_ops
  mmc: core: Enable power_off_notify for eMMC shutdown sequence
  mmc: core: Invent MMC_CAP2_FULL_PWR_CYCLE
  mmc: core: Add DT-bindings for MMC_CAP2_FULL_PWR_CYCLE

 Documentation/devicetree/bindings/mmc/mmc.txt |    1 +
 drivers/mmc/card/block.c                      |   15 ++++-
 drivers/mmc/card/mmc_test.c                   |    5 ++
 drivers/mmc/core/bus.c                        |   37 ++++++++++-
 drivers/mmc/core/core.c                       |   87 ++++---------------------
 drivers/mmc/core/core.h                       |    2 +
 drivers/mmc/core/host.c                       |    2 +
 drivers/mmc/core/mmc.c                        |   40 +++++++++---
 drivers/mmc/core/sd.c                         |    6 ++
 drivers/mmc/core/sdio.c                       |   48 ++++++++++++--
 include/linux/mmc/card.h                      |    1 +
 include/linux/mmc/host.h                      |    2 +-
 12 files changed, 153 insertions(+), 93 deletions(-)

-- 
1.7.10


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

* [PATCH 01/12] mmc: core: Remove unnecessary check for the remove callback
  2013-06-10 15:03 [PATCH 00/12] mmc: core: mmc_bus to handle suspend|resume|shutdown Ulf Hansson
@ 2013-06-10 15:03 ` Ulf Hansson
  2013-06-10 15:03 ` [PATCH 02/12] mmc: core: Validate suspend prerequisites for SDIO at SUSPEND_PREPARE Ulf Hansson
                   ` (12 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: Ulf Hansson @ 2013-06-10 15:03 UTC (permalink / raw)
  To: linux-mmc, Chris Ball; +Cc: Ulf Hansson

From: Ulf Hansson <ulf.hansson@linaro.org>

For every bus_ops type the .remove callback always exist, thus there
are no need to check the existence of it, before we decide to call it.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Tested-by: Jaehoon Chung <jh80.chung@samsung.com>
---
 drivers/mmc/core/core.c |   11 +++--------
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index e9a104b..d2ee282 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -2483,9 +2483,7 @@ void mmc_stop_host(struct mmc_host *host)
 	mmc_bus_get(host);
 	if (host->bus_ops && !host->bus_dead) {
 		/* Calling bus_ops->remove() with a claimed host can deadlock */
-		if (host->bus_ops->remove)
-			host->bus_ops->remove(host);
-
+		host->bus_ops->remove(host);
 		mmc_claim_host(host);
 		mmc_detach_bus(host);
 		mmc_power_off(host);
@@ -2638,8 +2636,7 @@ int mmc_suspend_host(struct mmc_host *host)
 			 * bus_ops->remove() with a claimed host can
 			 * deadlock.)
 			 */
-			if (host->bus_ops->remove)
-				host->bus_ops->remove(host);
+			host->bus_ops->remove(host);
 			mmc_claim_host(host);
 			mmc_detach_bus(host);
 			mmc_power_off(host);
@@ -2722,9 +2719,7 @@ int mmc_pm_notify(struct notifier_block *notify_block,
 			break;
 
 		/* Calling bus_ops->remove() with a claimed host can deadlock */
-		if (host->bus_ops->remove)
-			host->bus_ops->remove(host);
-
+		host->bus_ops->remove(host);
 		mmc_claim_host(host);
 		mmc_detach_bus(host);
 		mmc_power_off(host);
-- 
1.7.10


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

* [PATCH 02/12] mmc: core: Validate suspend prerequisites for SDIO at SUSPEND_PREPARE
  2013-06-10 15:03 [PATCH 00/12] mmc: core: mmc_bus to handle suspend|resume|shutdown Ulf Hansson
  2013-06-10 15:03 ` [PATCH 01/12] mmc: core: Remove unnecessary check for the remove callback Ulf Hansson
@ 2013-06-10 15:03 ` Ulf Hansson
  2013-06-10 15:03 ` [PATCH 03/12] mmc: core: Push common suspend|resume code into each bus_ops Ulf Hansson
                   ` (11 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: Ulf Hansson @ 2013-06-10 15:03 UTC (permalink / raw)
  To: linux-mmc, Chris Ball; +Cc: Ulf Hansson

From: Ulf Hansson <ulf.hansson@linaro.org>

This patch moves the validation for all the suspend prerequisites to be
done at SUSPEND_PREPARE notification. Previously in the SDIO case parts
of the validation was done from mmc_suspend_host.

This patch invents a new pre_suspend bus_ops callback and implements it
for SDIO. Returning an error code from it, will mean at SUSPEND_PREPARE
notification, the card will be removed before proceeding with the
suspend sequence.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Tested-by: Jaehoon Chung <jh80.chung@samsung.com>
---
 drivers/mmc/core/core.c |   25 ++++++++-----------------
 drivers/mmc/core/core.h |    1 +
 drivers/mmc/core/sdio.c |   27 +++++++++++++++++++++++----
 3 files changed, 32 insertions(+), 21 deletions(-)

diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index d2ee282..7a8a42d 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -2628,22 +2628,6 @@ int mmc_suspend_host(struct mmc_host *host)
 	if (host->bus_ops && !host->bus_dead) {
 		if (host->bus_ops->suspend)
 			err = host->bus_ops->suspend(host);
-
-		if (err == -ENOSYS || !host->bus_ops->resume) {
-			/*
-			 * We simply "remove" the card in this case.
-			 * It will be redetected on resume.  (Calling
-			 * bus_ops->remove() with a claimed host can
-			 * deadlock.)
-			 */
-			host->bus_ops->remove(host);
-			mmc_claim_host(host);
-			mmc_detach_bus(host);
-			mmc_power_off(host);
-			mmc_release_host(host);
-			host->pm_flags = 0;
-			err = 0;
-		}
 	}
 	mmc_bus_put(host);
 
@@ -2706,6 +2690,7 @@ int mmc_pm_notify(struct notifier_block *notify_block,
 	struct mmc_host *host = container_of(
 		notify_block, struct mmc_host, pm_notify);
 	unsigned long flags;
+	int err = 0;
 
 	switch (mode) {
 	case PM_HIBERNATION_PREPARE:
@@ -2715,7 +2700,13 @@ int mmc_pm_notify(struct notifier_block *notify_block,
 		spin_unlock_irqrestore(&host->lock, flags);
 		cancel_delayed_work_sync(&host->detect);
 
-		if (!host->bus_ops || host->bus_ops->suspend)
+		if (!host->bus_ops)
+			break;
+
+		/* Validate prerequisites for suspend */
+		if (host->bus_ops->pre_suspend)
+			err = host->bus_ops->pre_suspend(host);
+		if (!err && host->bus_ops->suspend)
 			break;
 
 		/* Calling bus_ops->remove() with a claimed host can deadlock */
diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h
index 52a3650..79f37cf 100644
--- a/drivers/mmc/core/core.h
+++ b/drivers/mmc/core/core.h
@@ -18,6 +18,7 @@
 struct mmc_bus_ops {
 	void (*remove)(struct mmc_host *);
 	void (*detect)(struct mmc_host *);
+	int (*pre_suspend)(struct mmc_host *);
 	int (*suspend)(struct mmc_host *);
 	int (*resume)(struct mmc_host *);
 	int (*runtime_suspend)(struct mmc_host *);
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
index 1fbbd1b..be8cca8 100644
--- a/drivers/mmc/core/sdio.c
+++ b/drivers/mmc/core/sdio.c
@@ -910,11 +910,11 @@ out:
 }
 
 /*
- * SDIO suspend.  We need to suspend all functions separately.
+ * SDIO pre_suspend.  We need to suspend all functions separately.
  * Therefore all registered functions must have drivers with suspend
  * and resume methods.  Failing that we simply remove the whole card.
  */
-static int mmc_sdio_suspend(struct mmc_host *host)
+static int mmc_sdio_pre_suspend(struct mmc_host *host)
 {
 	int i, err = 0;
 
@@ -925,8 +925,26 @@ static int mmc_sdio_suspend(struct mmc_host *host)
 			if (!pmops || !pmops->suspend || !pmops->resume) {
 				/* force removal of entire card in that case */
 				err = -ENOSYS;
-			} else
-				err = pmops->suspend(&func->dev);
+				break;
+			}
+		}
+	}
+
+	return err;
+}
+
+/*
+ * SDIO suspend.  Suspend all functions separately.
+ */
+static int mmc_sdio_suspend(struct mmc_host *host)
+{
+	int i, err = 0;
+
+	for (i = 0; i < host->card->sdio_funcs; i++) {
+		struct sdio_func *func = host->card->sdio_func[i];
+		if (func && sdio_func_present(func) && func->dev.driver) {
+			const struct dev_pm_ops *pmops = func->dev.driver->pm;
+			err = pmops->suspend(&func->dev);
 			if (err)
 				break;
 		}
@@ -1076,6 +1094,7 @@ static int mmc_sdio_runtime_resume(struct mmc_host *host)
 static const struct mmc_bus_ops mmc_sdio_ops = {
 	.remove = mmc_sdio_remove,
 	.detect = mmc_sdio_detect,
+	.pre_suspend = mmc_sdio_pre_suspend,
 	.suspend = mmc_sdio_suspend,
 	.resume = mmc_sdio_resume,
 	.runtime_suspend = mmc_sdio_runtime_suspend,
-- 
1.7.10


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

* [PATCH 03/12] mmc: core: Push common suspend|resume code into each bus_ops
  2013-06-10 15:03 [PATCH 00/12] mmc: core: mmc_bus to handle suspend|resume|shutdown Ulf Hansson
  2013-06-10 15:03 ` [PATCH 01/12] mmc: core: Remove unnecessary check for the remove callback Ulf Hansson
  2013-06-10 15:03 ` [PATCH 02/12] mmc: core: Validate suspend prerequisites for SDIO at SUSPEND_PREPARE Ulf Hansson
@ 2013-06-10 15:03 ` Ulf Hansson
  2013-06-10 15:03 ` [PATCH 04/12] mmc: core: Initiate suspend|resume from mmc bus instead of mmc host Ulf Hansson
                   ` (10 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: Ulf Hansson @ 2013-06-10 15:03 UTC (permalink / raw)
  To: linux-mmc, Chris Ball; +Cc: Ulf Hansson

From: Ulf Hansson <ulf.hansson@linaro.org>

By moving code from the mmc_suspend|resume_host down into each
.suspend|resume bus_ops callback, we get a more flexible solution.

Some nice side effects are that we get a better understanding of each
bus_ops suspend|resume sequence and the common code don't have to take
care of specific corner cases, especially for the SDIO case.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Tested-by: Jaehoon Chung <jh80.chung@samsung.com>
---
 drivers/mmc/core/core.c |   31 +++----------------------------
 drivers/mmc/core/mmc.c  |    4 ++++
 drivers/mmc/core/sd.c   |    4 ++++
 drivers/mmc/core/sdio.c |   21 +++++++++++++++++++++
 4 files changed, 32 insertions(+), 28 deletions(-)

diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 7a8a42d..da3b907 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -2621,9 +2621,6 @@ int mmc_suspend_host(struct mmc_host *host)
 {
 	int err = 0;
 
-	cancel_delayed_work(&host->detect);
-	mmc_flush_scheduled_work();
-
 	mmc_bus_get(host);
 	if (host->bus_ops && !host->bus_dead) {
 		if (host->bus_ops->suspend)
@@ -2631,9 +2628,6 @@ int mmc_suspend_host(struct mmc_host *host)
 	}
 	mmc_bus_put(host);
 
-	if (!err && !mmc_card_keep_power(host))
-		mmc_power_off(host);
-
 	return err;
 }
 EXPORT_SYMBOL(mmc_suspend_host);
@@ -2644,39 +2638,20 @@ EXPORT_SYMBOL(mmc_suspend_host);
  */
 int mmc_resume_host(struct mmc_host *host)
 {
-	int err = 0;
+	int err;
 
 	mmc_bus_get(host);
 	if (host->bus_ops && !host->bus_dead) {
-		if (!mmc_card_keep_power(host)) {
-			mmc_power_up(host);
-			mmc_select_voltage(host, host->ocr);
-			/*
-			 * Tell runtime PM core we just powered up the card,
-			 * since it still believes the card is powered off.
-			 * Note that currently runtime PM is only enabled
-			 * for SDIO cards that are MMC_CAP_POWER_OFF_CARD
-			 */
-			if (mmc_card_sdio(host->card) &&
-			    (host->caps & MMC_CAP_POWER_OFF_CARD)) {
-				pm_runtime_disable(&host->card->dev);
-				pm_runtime_set_active(&host->card->dev);
-				pm_runtime_enable(&host->card->dev);
-			}
-		}
 		BUG_ON(!host->bus_ops->resume);
 		err = host->bus_ops->resume(host);
-		if (err) {
+		if (err)
 			pr_warning("%s: error %d during resume "
 					    "(card was removed?)\n",
 					    mmc_hostname(host), err);
-			err = 0;
-		}
 	}
-	host->pm_flags &= ~MMC_PM_KEEP_POWER;
 	mmc_bus_put(host);
 
-	return err;
+	return 0;
 }
 EXPORT_SYMBOL(mmc_resume_host);
 
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 3a69b94..86ca103 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -1494,6 +1494,8 @@ static int mmc_suspend(struct mmc_host *host)
 		err = mmc_deselect_cards(host);
 	host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_200);
 
+	if (!err)
+		mmc_power_off(host);
 out:
 	mmc_release_host(host);
 	return err;
@@ -1513,6 +1515,8 @@ static int mmc_resume(struct mmc_host *host)
 	BUG_ON(!host->card);
 
 	mmc_claim_host(host);
+	mmc_power_up(host);
+	mmc_select_voltage(host, host->ocr);
 	err = mmc_init_card(host, host->ocr, host->card);
 	mmc_release_host(host);
 
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index aeaae7c..cacef27 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -1075,6 +1075,8 @@ static int mmc_sd_suspend(struct mmc_host *host)
 	if (!mmc_host_is_spi(host))
 		err = mmc_deselect_cards(host);
 	host->card->state &= ~MMC_STATE_HIGHSPEED;
+	if (!err)
+		mmc_power_off(host);
 	mmc_release_host(host);
 
 	return err;
@@ -1094,6 +1096,8 @@ static int mmc_sd_resume(struct mmc_host *host)
 	BUG_ON(!host->card);
 
 	mmc_claim_host(host);
+	mmc_power_up(host);
+	mmc_select_voltage(host, host->ocr);
 	err = mmc_sd_init_card(host, host->ocr, host->card);
 	mmc_release_host(host);
 
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
index be8cca8..80d89cff 100644
--- a/drivers/mmc/core/sdio.c
+++ b/drivers/mmc/core/sdio.c
@@ -963,6 +963,9 @@ static int mmc_sdio_suspend(struct mmc_host *host)
 		mmc_release_host(host);
 	}
 
+	if (!err && !mmc_card_keep_power(host))
+		mmc_power_off(host);
+
 	return err;
 }
 
@@ -976,6 +979,23 @@ static int mmc_sdio_resume(struct mmc_host *host)
 	/* Basic card reinitialization. */
 	mmc_claim_host(host);
 
+	/* Restore power if needed */
+	if (!mmc_card_keep_power(host)) {
+		mmc_power_up(host);
+		mmc_select_voltage(host, host->ocr);
+		/*
+		 * Tell runtime PM core we just powered up the card,
+		 * since it still believes the card is powered off.
+		 * Note that currently runtime PM is only enabled
+		 * for SDIO cards that are MMC_CAP_POWER_OFF_CARD
+		 */
+		if (host->caps & MMC_CAP_POWER_OFF_CARD) {
+			pm_runtime_disable(&host->card->dev);
+			pm_runtime_set_active(&host->card->dev);
+			pm_runtime_enable(&host->card->dev);
+		}
+	}
+
 	/* No need to reinitialize powered-resumed nonremovable cards */
 	if (mmc_card_is_removable(host) || !mmc_card_keep_power(host)) {
 		sdio_reset(host);
@@ -1013,6 +1033,7 @@ static int mmc_sdio_resume(struct mmc_host *host)
 		}
 	}
 
+	host->pm_flags &= ~MMC_PM_KEEP_POWER;
 	return err;
 }
 
-- 
1.7.10


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

* [PATCH 04/12] mmc: core: Initiate suspend|resume from mmc bus instead of mmc host
  2013-06-10 15:03 [PATCH 00/12] mmc: core: mmc_bus to handle suspend|resume|shutdown Ulf Hansson
                   ` (2 preceding siblings ...)
  2013-06-10 15:03 ` [PATCH 03/12] mmc: core: Push common suspend|resume code into each bus_ops Ulf Hansson
@ 2013-06-10 15:03 ` Ulf Hansson
  2013-06-10 15:03 ` [PATCH 05/12] mmc: core: Handle card shutdown from mmc_bus Ulf Hansson
                   ` (9 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: Ulf Hansson @ 2013-06-10 15:03 UTC (permalink / raw)
  To: linux-mmc, Chris Ball; +Cc: Ulf Hansson

From: Ulf Hansson <ulf.hansson@linaro.org>

The host should be responsible to suspend|resume the host and not the
card. This patch changes this behaviour, by moving the responsiblity
to the mmc bus instead which already holds the card device.

The exported functions mmc_suspend|resume_host are now to be considered
as depcrecated. Once all host drivers moves away from using them, we
can remove them. As of now, a successful error code is always returned.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Tested-by: Jaehoon Chung <jh80.chung@samsung.com>
---
 drivers/mmc/core/bus.c  |   19 ++++++++++++++++---
 drivers/mmc/core/core.c |   26 +++-----------------------
 2 files changed, 19 insertions(+), 26 deletions(-)

diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c
index d9e8c2b..3b7ca8a 100644
--- a/drivers/mmc/core/bus.c
+++ b/drivers/mmc/core/bus.c
@@ -127,10 +127,16 @@ static int mmc_bus_suspend(struct device *dev)
 {
 	struct mmc_driver *drv = to_mmc_driver(dev->driver);
 	struct mmc_card *card = mmc_dev_to_card(dev);
-	int ret = 0;
+	struct mmc_host *host = card->host;
+	int ret;
 
-	if (dev->driver && drv->suspend)
+	if (dev->driver && drv->suspend) {
 		ret = drv->suspend(card);
+		if (ret)
+			return ret;
+	}
+
+	ret = host->bus_ops->suspend(host);
 	return ret;
 }
 
@@ -138,10 +144,17 @@ static int mmc_bus_resume(struct device *dev)
 {
 	struct mmc_driver *drv = to_mmc_driver(dev->driver);
 	struct mmc_card *card = mmc_dev_to_card(dev);
-	int ret = 0;
+	struct mmc_host *host = card->host;
+	int ret;
+
+	ret = host->bus_ops->resume(host);
+	if (ret)
+		pr_warn("%s: error %d during resume (card was removed?)\n",
+			mmc_hostname(host), ret);
 
 	if (dev->driver && drv->resume)
 		ret = drv->resume(card);
+
 	return ret;
 }
 #endif
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index da3b907..49a5bca 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -2619,16 +2619,8 @@ EXPORT_SYMBOL(mmc_cache_ctrl);
  */
 int mmc_suspend_host(struct mmc_host *host)
 {
-	int err = 0;
-
-	mmc_bus_get(host);
-	if (host->bus_ops && !host->bus_dead) {
-		if (host->bus_ops->suspend)
-			err = host->bus_ops->suspend(host);
-	}
-	mmc_bus_put(host);
-
-	return err;
+	/* This function is deprecated */
+	return 0;
 }
 EXPORT_SYMBOL(mmc_suspend_host);
 
@@ -2638,19 +2630,7 @@ EXPORT_SYMBOL(mmc_suspend_host);
  */
 int mmc_resume_host(struct mmc_host *host)
 {
-	int err;
-
-	mmc_bus_get(host);
-	if (host->bus_ops && !host->bus_dead) {
-		BUG_ON(!host->bus_ops->resume);
-		err = host->bus_ops->resume(host);
-		if (err)
-			pr_warning("%s: error %d during resume "
-					    "(card was removed?)\n",
-					    mmc_hostname(host), err);
-	}
-	mmc_bus_put(host);
-
+	/* This function is deprecated */
 	return 0;
 }
 EXPORT_SYMBOL(mmc_resume_host);
-- 
1.7.10


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

* [PATCH 05/12] mmc: core: Handle card shutdown from mmc_bus
  2013-06-10 15:03 [PATCH 00/12] mmc: core: mmc_bus to handle suspend|resume|shutdown Ulf Hansson
                   ` (3 preceding siblings ...)
  2013-06-10 15:03 ` [PATCH 04/12] mmc: core: Initiate suspend|resume from mmc bus instead of mmc host Ulf Hansson
@ 2013-06-10 15:03 ` Ulf Hansson
  2013-06-10 15:03 ` [PATCH 06/12] mmc: core: Extend shutdown sequence to handle bus operations Ulf Hansson
                   ` (8 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: Ulf Hansson @ 2013-06-10 15:03 UTC (permalink / raw)
  To: linux-mmc, Chris Ball; +Cc: Ulf Hansson

From: Ulf Hansson <ulf.hansson@linaro.org>

Considering shutdown of the card, the responsibility to initate this
sequence shall be driven from the mmc_bus.

This patch enables the mmc_bus to handle this sequence properly. A new
.shutdown callback is added in the mmc_driver struct which is used to
shutdown the blk device.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 drivers/mmc/card/block.c    |   15 +++++++++++++--
 drivers/mmc/card/mmc_test.c |    5 +++++
 drivers/mmc/core/bus.c      |    9 +++++++++
 include/linux/mmc/card.h    |    1 +
 4 files changed, 28 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index c900d28..d91507f 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -2400,8 +2400,7 @@ static void mmc_blk_remove(struct mmc_card *card)
 	mmc_set_drvdata(card, NULL);
 }
 
-#ifdef CONFIG_PM
-static int mmc_blk_suspend(struct mmc_card *card)
+static int _mmc_blk_suspend(struct mmc_card *card)
 {
 	struct mmc_blk_data *part_md;
 	struct mmc_blk_data *md = mmc_get_drvdata(card);
@@ -2416,6 +2415,17 @@ static int mmc_blk_suspend(struct mmc_card *card)
 	return 0;
 }
 
+static void mmc_blk_shutdown(struct mmc_card *card)
+{
+	_mmc_blk_suspend(card);
+}
+
+#ifdef CONFIG_PM
+static int mmc_blk_suspend(struct mmc_card *card)
+{
+	return _mmc_blk_suspend(card);
+}
+
 static int mmc_blk_resume(struct mmc_card *card)
 {
 	struct mmc_blk_data *part_md;
@@ -2448,6 +2458,7 @@ static struct mmc_driver mmc_driver = {
 	.remove		= mmc_blk_remove,
 	.suspend	= mmc_blk_suspend,
 	.resume		= mmc_blk_resume,
+	.shutdown	= mmc_blk_shutdown,
 };
 
 static int __init mmc_blk_init(void)
diff --git a/drivers/mmc/card/mmc_test.c b/drivers/mmc/card/mmc_test.c
index 759714e..a69df52 100644
--- a/drivers/mmc/card/mmc_test.c
+++ b/drivers/mmc/card/mmc_test.c
@@ -3025,12 +3025,17 @@ static void mmc_test_remove(struct mmc_card *card)
 	mmc_test_free_dbgfs_file(card);
 }
 
+static void mmc_test_shutdown(struct mmc_card *card)
+{
+}
+
 static struct mmc_driver mmc_driver = {
 	.drv		= {
 		.name	= "mmc_test",
 	},
 	.probe		= mmc_test_probe,
 	.remove		= mmc_test_remove,
+	.shutdown	= mmc_test_shutdown,
 };
 
 static int __init mmc_test_init(void)
diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c
index 3b7ca8a..219bf4b 100644
--- a/drivers/mmc/core/bus.c
+++ b/drivers/mmc/core/bus.c
@@ -122,6 +122,14 @@ static int mmc_bus_remove(struct device *dev)
 	return 0;
 }
 
+static void mmc_bus_shutdown(struct device *dev)
+{
+	struct mmc_driver *drv = to_mmc_driver(dev->driver);
+	struct mmc_card *card = mmc_dev_to_card(dev);
+
+	drv->shutdown(card);
+}
+
 #ifdef CONFIG_PM_SLEEP
 static int mmc_bus_suspend(struct device *dev)
 {
@@ -205,6 +213,7 @@ static struct bus_type mmc_bus_type = {
 	.uevent		= mmc_bus_uevent,
 	.probe		= mmc_bus_probe,
 	.remove		= mmc_bus_remove,
+	.shutdown	= mmc_bus_shutdown,
 	.pm		= &mmc_bus_pm_ops,
 };
 
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index 6a98f32..842de3e 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -520,6 +520,7 @@ struct mmc_driver {
 	void (*remove)(struct mmc_card *);
 	int (*suspend)(struct mmc_card *);
 	int (*resume)(struct mmc_card *);
+	void (*shutdown)(struct mmc_card *);
 };
 
 extern int mmc_register_driver(struct mmc_driver *);
-- 
1.7.10


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

* [PATCH 06/12] mmc: core: Extend shutdown sequence to handle bus operations
  2013-06-10 15:03 [PATCH 00/12] mmc: core: mmc_bus to handle suspend|resume|shutdown Ulf Hansson
                   ` (4 preceding siblings ...)
  2013-06-10 15:03 ` [PATCH 05/12] mmc: core: Handle card shutdown from mmc_bus Ulf Hansson
@ 2013-06-10 15:03 ` Ulf Hansson
  2013-06-10 15:03 ` [PATCH 07/12] mmc: core: Add shutdown callback for SD bus_ops Ulf Hansson
                   ` (7 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: Ulf Hansson @ 2013-06-10 15:03 UTC (permalink / raw)
  To: linux-mmc, Chris Ball; +Cc: Ulf Hansson

From: Ulf Hansson <ulf.hansson@linaro.org>

By adding an optional .shutdown callback to the bus_ops struct we
provide the possibility to let each bus type handle it's shutdown
requirements.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 drivers/mmc/core/bus.c  |    9 +++++++++
 drivers/mmc/core/core.h |    1 +
 2 files changed, 10 insertions(+)

diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c
index 219bf4b..4c0decf 100644
--- a/drivers/mmc/core/bus.c
+++ b/drivers/mmc/core/bus.c
@@ -126,8 +126,17 @@ static void mmc_bus_shutdown(struct device *dev)
 {
 	struct mmc_driver *drv = to_mmc_driver(dev->driver);
 	struct mmc_card *card = mmc_dev_to_card(dev);
+	struct mmc_host *host = card->host;
+	int ret;
 
 	drv->shutdown(card);
+
+	if (host->bus_ops->shutdown) {
+		ret = host->bus_ops->shutdown(host);
+		if (ret)
+			pr_warn("%s: error %d during shutdown\n",
+				mmc_hostname(host), ret);
+	}
 }
 
 #ifdef CONFIG_PM_SLEEP
diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h
index 79f37cf..5345d15 100644
--- a/drivers/mmc/core/core.h
+++ b/drivers/mmc/core/core.h
@@ -26,6 +26,7 @@ struct mmc_bus_ops {
 	int (*power_save)(struct mmc_host *);
 	int (*power_restore)(struct mmc_host *);
 	int (*alive)(struct mmc_host *);
+	int (*shutdown)(struct mmc_host *);
 };
 
 void mmc_attach_bus(struct mmc_host *host, const struct mmc_bus_ops *ops);
-- 
1.7.10


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

* [PATCH 07/12] mmc: core: Add shutdown callback for SD bus_ops
  2013-06-10 15:03 [PATCH 00/12] mmc: core: mmc_bus to handle suspend|resume|shutdown Ulf Hansson
                   ` (5 preceding siblings ...)
  2013-06-10 15:03 ` [PATCH 06/12] mmc: core: Extend shutdown sequence to handle bus operations Ulf Hansson
@ 2013-06-10 15:03 ` Ulf Hansson
  2013-06-10 15:03 ` [PATCH 08/12] mmc: core: Handle both poweroff notification types for eMMC Ulf Hansson
                   ` (6 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: Ulf Hansson @ 2013-06-10 15:03 UTC (permalink / raw)
  To: linux-mmc, Chris Ball; +Cc: Ulf Hansson

From: Ulf Hansson <ulf.hansson@linaro.org>

For the SD .shutdown callback we re-use the SD suspend function since
it performs the relevant actions.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 drivers/mmc/core/sd.c |    2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index cacef27..176d125 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -1170,6 +1170,7 @@ static const struct mmc_bus_ops mmc_sd_ops = {
 	.resume = NULL,
 	.power_restore = mmc_sd_power_restore,
 	.alive = mmc_sd_alive,
+	.shutdown = mmc_sd_suspend,
 };
 
 static const struct mmc_bus_ops mmc_sd_ops_unsafe = {
@@ -1181,6 +1182,7 @@ static const struct mmc_bus_ops mmc_sd_ops_unsafe = {
 	.resume = mmc_sd_resume,
 	.power_restore = mmc_sd_power_restore,
 	.alive = mmc_sd_alive,
+	.shutdown = mmc_sd_suspend,
 };
 
 static void mmc_sd_attach_bus_ops(struct mmc_host *host)
-- 
1.7.10


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

* [PATCH 08/12] mmc: core: Handle both poweroff notification types for eMMC
  2013-06-10 15:03 [PATCH 00/12] mmc: core: mmc_bus to handle suspend|resume|shutdown Ulf Hansson
                   ` (6 preceding siblings ...)
  2013-06-10 15:03 ` [PATCH 07/12] mmc: core: Add shutdown callback for SD bus_ops Ulf Hansson
@ 2013-06-10 15:03 ` Ulf Hansson
  2013-06-10 15:03 ` [PATCH 09/12] mmc: core: Add shutdown callback for (e)MMC bus_ops Ulf Hansson
                   ` (5 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: Ulf Hansson @ 2013-06-10 15:03 UTC (permalink / raw)
  To: linux-mmc, Chris Ball; +Cc: Ulf Hansson

From: Ulf Hansson <ulf.hansson@linaro.org>

Depending on the context of the operation while powering down the card,
either POWER_OFF_NOTIFY_SHORT or POWER_OFF_NOTIFY_LONG will be used. In
suspend context a short timeout is preferred while a long timeout would
be acceptable in a shutdown/hibernation context.

We add a new parameter to the mmc_suspend function so we can provide an
indication of what notification type to use.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 drivers/mmc/core/mmc.c |   17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 86ca103..dcf0169 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -1464,12 +1464,11 @@ static void mmc_detect(struct mmc_host *host)
 	}
 }
 
-/*
- * Suspend callback from host.
- */
-static int mmc_suspend(struct mmc_host *host)
+static int _mmc_suspend(struct mmc_host *host, bool is_suspend)
 {
 	int err = 0;
+	unsigned int notify_type = is_suspend ? EXT_CSD_POWER_OFF_SHORT :
+					EXT_CSD_POWER_OFF_LONG;
 
 	BUG_ON(!host);
 	BUG_ON(!host->card);
@@ -1487,7 +1486,7 @@ static int mmc_suspend(struct mmc_host *host)
 		goto out;
 
 	if (mmc_can_poweroff_notify(host->card))
-		err = mmc_poweroff_notify(host->card, EXT_CSD_POWER_OFF_SHORT);
+		err = mmc_poweroff_notify(host->card, notify_type);
 	else if (mmc_can_sleep(host->card))
 		err = mmc_sleep(host);
 	else if (!mmc_host_is_spi(host))
@@ -1502,6 +1501,14 @@ out:
 }
 
 /*
+ * Suspend callback from host.
+ */
+static int mmc_suspend(struct mmc_host *host)
+{
+	return _mmc_suspend(host, true);
+}
+
+/*
  * Resume callback from host.
  *
  * This function tries to determine if the same card is still present
-- 
1.7.10


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

* [PATCH 09/12] mmc: core: Add shutdown callback for (e)MMC bus_ops
  2013-06-10 15:03 [PATCH 00/12] mmc: core: mmc_bus to handle suspend|resume|shutdown Ulf Hansson
                   ` (7 preceding siblings ...)
  2013-06-10 15:03 ` [PATCH 08/12] mmc: core: Handle both poweroff notification types for eMMC Ulf Hansson
@ 2013-06-10 15:03 ` Ulf Hansson
  2013-06-10 15:03 ` [PATCH 10/12] mmc: core: Enable power_off_notify for eMMC shutdown sequence Ulf Hansson
                   ` (4 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: Ulf Hansson @ 2013-06-10 15:03 UTC (permalink / raw)
  To: linux-mmc, Chris Ball; +Cc: Ulf Hansson

From: Ulf Hansson <ulf.hansson@linaro.org>

The shutdown sequence of an (e)MMC is very similar to a suspend. We
re-use the suspend function and tell it we are not in suspend context.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 drivers/mmc/core/mmc.c |   10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index dcf0169..3aafb2e 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -1509,6 +1509,14 @@ static int mmc_suspend(struct mmc_host *host)
 }
 
 /*
+ * Shutdown callback
+ */
+static int mmc_shutdown(struct mmc_host *host)
+{
+	return _mmc_suspend(host, false);
+}
+
+/*
  * Resume callback from host.
  *
  * This function tries to determine if the same card is still present
@@ -1597,6 +1605,7 @@ static const struct mmc_bus_ops mmc_ops = {
 	.resume = NULL,
 	.power_restore = mmc_power_restore,
 	.alive = mmc_alive,
+	.shutdown = mmc_shutdown,
 };
 
 static const struct mmc_bus_ops mmc_ops_unsafe = {
@@ -1608,6 +1617,7 @@ static const struct mmc_bus_ops mmc_ops_unsafe = {
 	.runtime_resume = mmc_runtime_resume,
 	.power_restore = mmc_power_restore,
 	.alive = mmc_alive,
+	.shutdown = mmc_shutdown,
 };
 
 static void mmc_attach_bus_ops(struct mmc_host *host)
-- 
1.7.10


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

* [PATCH 10/12] mmc: core: Enable power_off_notify for eMMC shutdown sequence
  2013-06-10 15:03 [PATCH 00/12] mmc: core: mmc_bus to handle suspend|resume|shutdown Ulf Hansson
                   ` (8 preceding siblings ...)
  2013-06-10 15:03 ` [PATCH 09/12] mmc: core: Add shutdown callback for (e)MMC bus_ops Ulf Hansson
@ 2013-06-10 15:03 ` Ulf Hansson
  2013-06-10 15:03 ` [PATCH 11/12] mmc: core: Invent MMC_CAP2_FULL_PWR_CYCLE Ulf Hansson
                   ` (3 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: Ulf Hansson @ 2013-06-10 15:03 UTC (permalink / raw)
  To: linux-mmc, Chris Ball; +Cc: Ulf Hansson

From: Ulf Hansson <ulf.hansson@linaro.org>

In suspend mode it is important to save power. If the host is able to
cut buth vcc and vccq, the MMC_CAP2_POWEROFF_NOTIFY shall be set. It
will mean the card will be completely powered down at suspend and the
power off notification cmd will be sent prior power down.

It seems common not being able to cut both vcc and vccq for a host. In
this situation we issue the sleep cmd in favor of the power off
notification cmd, to save more power.

While maintainng the above policy, we also want to make use of the
power off notification in the shutdown sequence, even in the case were
the host has not set MMC_CAP2_POWEROFF_NOTIFY, since we know vcc and
vccq will regardless be cut.

We accomplish this by always enabling the power off notification byte
in the EXT_CSD and issue the power off notification when either
MMC_CAP2_POWEROFF_NOTIFY is set or we are executing a shutdown.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 drivers/mmc/core/mmc.c |    9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 3aafb2e..a96dcaa 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -1041,11 +1041,9 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
 	}
 
 	/*
-	 * If the host supports the power_off_notify capability then
-	 * set the notification byte in the ext_csd register of device
+	 * Enable power_off_notification byte in the ext_csd register
 	 */
-	if ((host->caps2 & MMC_CAP2_POWEROFF_NOTIFY) &&
-	    (card->ext_csd.rev >= 6)) {
+	if (card->ext_csd.rev >= 6) {
 		err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
 				 EXT_CSD_POWER_OFF_NOTIFICATION,
 				 EXT_CSD_POWER_ON,
@@ -1485,7 +1483,8 @@ static int _mmc_suspend(struct mmc_host *host, bool is_suspend)
 	if (err)
 		goto out;
 
-	if (mmc_can_poweroff_notify(host->card))
+	if (mmc_can_poweroff_notify(host->card) &&
+		((host->caps2 & MMC_CAP2_POWEROFF_NOTIFY) || !is_suspend))
 		err = mmc_poweroff_notify(host->card, notify_type);
 	else if (mmc_can_sleep(host->card))
 		err = mmc_sleep(host);
-- 
1.7.10


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

* [PATCH 11/12] mmc: core: Invent MMC_CAP2_FULL_PWR_CYCLE
  2013-06-10 15:03 [PATCH 00/12] mmc: core: mmc_bus to handle suspend|resume|shutdown Ulf Hansson
                   ` (9 preceding siblings ...)
  2013-06-10 15:03 ` [PATCH 10/12] mmc: core: Enable power_off_notify for eMMC shutdown sequence Ulf Hansson
@ 2013-06-10 15:03 ` Ulf Hansson
  2013-06-10 15:03 ` [PATCH 12/12] mmc: core: Add DT-bindings for MMC_CAP2_FULL_PWR_CYCLE Ulf Hansson
                   ` (2 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: Ulf Hansson @ 2013-06-10 15:03 UTC (permalink / raw)
  To: linux-mmc, Chris Ball; +Cc: Ulf Hansson

From: Ulf Hansson <ulf.hansson@linaro.org>

MMC_CAP2_FULL_PWR_CYCLE shall be set by host drivers which are able to
do a complete power cycle of the card. In the eMMC case that includes
both vcc and vccq.

This CAP is providing the protocol layer with important information,
needed to take optimized decisions during card initialization and in
the suspend/resume sequence.

MMC_CAP2_POWEROFF_NOTIFY is replaced by MMC_CAP2_FULL_PWR_CYCLE, since
it makes sense to use a wider scope for it.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 drivers/mmc/core/mmc.c   |    2 +-
 include/linux/mmc/host.h |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index a96dcaa..38315f8 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -1484,7 +1484,7 @@ static int _mmc_suspend(struct mmc_host *host, bool is_suspend)
 		goto out;
 
 	if (mmc_can_poweroff_notify(host->card) &&
-		((host->caps2 & MMC_CAP2_POWEROFF_NOTIFY) || !is_suspend))
+		((host->caps2 & MMC_CAP2_FULL_PWR_CYCLE) || !is_suspend))
 		err = mmc_poweroff_notify(host->card, notify_type);
 	else if (mmc_can_sleep(host->card))
 		err = mmc_sleep(host);
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 2e34ee5..c6dedc7 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -264,7 +264,7 @@ struct mmc_host {
 
 #define MMC_CAP2_BOOTPART_NOACC	(1 << 0)	/* Boot partition no access */
 #define MMC_CAP2_CACHE_CTRL	(1 << 1)	/* Allow cache control */
-#define MMC_CAP2_POWEROFF_NOTIFY (1 << 2)	/* Notify poweroff supported */
+#define MMC_CAP2_FULL_PWR_CYCLE	(1 << 2)	/* Can do full power cycle */
 #define MMC_CAP2_NO_MULTI_READ	(1 << 3)	/* Multiblock reads don't work */
 #define MMC_CAP2_NO_SLEEP_CMD	(1 << 4)	/* Don't allow sleep command */
 #define MMC_CAP2_HS200_1_8V_SDR	(1 << 5)        /* can support */
-- 
1.7.10


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

* [PATCH 12/12] mmc: core: Add DT-bindings for MMC_CAP2_FULL_PWR_CYCLE
  2013-06-10 15:03 [PATCH 00/12] mmc: core: mmc_bus to handle suspend|resume|shutdown Ulf Hansson
                   ` (10 preceding siblings ...)
  2013-06-10 15:03 ` [PATCH 11/12] mmc: core: Invent MMC_CAP2_FULL_PWR_CYCLE Ulf Hansson
@ 2013-06-10 15:03 ` Ulf Hansson
  2013-06-11  9:24 ` [PATCH 00/12] mmc: core: mmc_bus to handle suspend|resume|shutdown Linus Walleij
  2013-06-27 15:43 ` Chris Ball
  13 siblings, 0 replies; 16+ messages in thread
From: Ulf Hansson @ 2013-06-10 15:03 UTC (permalink / raw)
  To: linux-mmc, Chris Ball; +Cc: Ulf Hansson

From: Ulf Hansson <ulf.hansson@linaro.org>

The DT-binding for MMC_CAP2_FULL_PWR_CYCLE, is used to indicate whether
it is possible to perform a full power cycle of the card.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 Documentation/devicetree/bindings/mmc/mmc.txt |    1 +
 drivers/mmc/core/host.c                       |    2 ++
 2 files changed, 3 insertions(+)

diff --git a/Documentation/devicetree/bindings/mmc/mmc.txt b/Documentation/devicetree/bindings/mmc/mmc.txt
index 85aada2..458b57f 100644
--- a/Documentation/devicetree/bindings/mmc/mmc.txt
+++ b/Documentation/devicetree/bindings/mmc/mmc.txt
@@ -28,6 +28,7 @@ Optional properties:
 - cap-mmc-highspeed: MMC high-speed timing is supported
 - cap-power-off-card: powering off the card is safe
 - cap-sdio-irq: enable SDIO IRQ signalling on this interface
+- full-pwr-cycle: full power cycle of the card is supported
 
 *NOTE* on CD and WP polarity. To use common for all SD/MMC host controllers line
 polarity properties, we have to fix the meaning of the "normal" and "inverted"
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
index 2a3593d..17d8b37 100644
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -409,6 +409,8 @@ void mmc_of_parse(struct mmc_host *host)
 		host->caps |= MMC_CAP_POWER_OFF_CARD;
 	if (of_find_property(np, "cap-sdio-irq", &len))
 		host->caps |= MMC_CAP_SDIO_IRQ;
+	if (of_find_property(np, "full-pwr-cycle", &len))
+		host->caps2 |= MMC_CAP2_FULL_PWR_CYCLE;
 	if (of_find_property(np, "keep-power-in-suspend", &len))
 		host->pm_caps |= MMC_PM_KEEP_POWER;
 	if (of_find_property(np, "enable-sdio-wakeup", &len))
-- 
1.7.10


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

* Re: [PATCH 00/12] mmc: core: mmc_bus to handle suspend|resume|shutdown
  2013-06-10 15:03 [PATCH 00/12] mmc: core: mmc_bus to handle suspend|resume|shutdown Ulf Hansson
                   ` (11 preceding siblings ...)
  2013-06-10 15:03 ` [PATCH 12/12] mmc: core: Add DT-bindings for MMC_CAP2_FULL_PWR_CYCLE Ulf Hansson
@ 2013-06-11  9:24 ` Linus Walleij
  2013-06-12  8:15   ` Pierre Ossman
  2013-06-27 15:43 ` Chris Ball
  13 siblings, 1 reply; 16+ messages in thread
From: Linus Walleij @ 2013-06-11  9:24 UTC (permalink / raw)
  To: Ulf Hansson, Pierre Ossman; +Cc: linux-mmc@vger.kernel.org, Chris Ball

On Mon, Jun 10, 2013 at 5:03 PM, Ulf Hansson <ulf.hansson@stericsson.com> wrote:

> From: Ulf Hansson <ulf.hansson@linaro.org>
>
> The MMC/SD/SDIO cards are registered on the mmc_bus and should from a power
> management perspective be controlled from there. As of today each and every
> host driver needs to issue mmc_suspend|resume_host from their respective
> .suspend|resume methods, which seems like an unnecessary requirement to
> put on them. Additionally, a shutdown sequence shall be initiated from the
> mmc_bus.
>
> This patch set moves the responsiblity to suspend the cards into the mmc_bus.
> It also invents the shutdown sequence, also to be handled from the mmc_bus.
> In the SDIO case, the shutdown sequence will not involve any SDIO specific
> operations. If this would be desired, I suggest to handle that as and separate
> step, since it would involve the sdio bus and potentially the sdio drivers.
>
> As a part of the patches releated to adding the shutdown sequence, specific
> issues to handle eMMC power off notification properly are included in this
> patch set as well.
>
> The mmc_suspend|resume_host functions are not removed, but will instead always
> return successful. A separate patch(es) build on top of this patch set, shall
> remove the API:s together with updating each and every host driver.
>
> Do note, that patch 1 to 4 has been sent earlier in the set "mmc: core: Let the
> mmc_bus handle suspend|resume sequence". Since the functionallity are very close
> releated I decided to fold them in into this patch set.
>
> A big thank you to Jaehoon Chung who has tested the patches 1 to 4.

Hm a significant portion of this patch set hits code which has not
been touched since Pierre Ossman wrote the first MMC code.
E.g. patch 1.

I know Pierre has long since moved on to other things, but I'm
pinging him anyway since it's his code after all...

Pierre: tell us if you want a copy of this patch set.

Yours,
Linus Walleij

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

* Re: [PATCH 00/12] mmc: core: mmc_bus to handle suspend|resume|shutdown
  2013-06-11  9:24 ` [PATCH 00/12] mmc: core: mmc_bus to handle suspend|resume|shutdown Linus Walleij
@ 2013-06-12  8:15   ` Pierre Ossman
  0 siblings, 0 replies; 16+ messages in thread
From: Pierre Ossman @ 2013-06-12  8:15 UTC (permalink / raw)
  To: Linus Walleij; +Cc: Ulf Hansson, linux-mmc@vger.kernel.org, Chris Ball

[-- Attachment #1: Type: text/plain, Size: 996 bytes --]

On Tue, 11 Jun 2013 11:24:49 +0200
Linus Walleij <linus.walleij@linaro.org> wrote:

> 
> Hm a significant portion of this patch set hits code which has not
> been touched since Pierre Ossman wrote the first MMC code.
> E.g. patch 1.

In the spirit of giving credit where credit is due, the MMC code
existed long before I got involved (mostly written by Russell King
AFAIK). I just happen to change a lot of it. :)

> 
> I know Pierre has long since moved on to other things, but I'm
> pinging him anyway since it's his code after all...
> 
> Pierre: tell us if you want a copy of this patch set.
> 

I had a quick look, but I'm afraid I've managed to purge more or less
all knowledge of that code. You're on your own on this one. ;)

Rgds
-- 
     -- Pierre Ossman

  WARNING: This correspondence is being monitored by FRA, a
  Swedish intelligence agency. Make sure your server uses
  encryption for SMTP traffic and consider using PGP for
  end-to-end encryption.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 230 bytes --]

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

* Re: [PATCH 00/12] mmc: core: mmc_bus to handle suspend|resume|shutdown
  2013-06-10 15:03 [PATCH 00/12] mmc: core: mmc_bus to handle suspend|resume|shutdown Ulf Hansson
                   ` (12 preceding siblings ...)
  2013-06-11  9:24 ` [PATCH 00/12] mmc: core: mmc_bus to handle suspend|resume|shutdown Linus Walleij
@ 2013-06-27 15:43 ` Chris Ball
  13 siblings, 0 replies; 16+ messages in thread
From: Chris Ball @ 2013-06-27 15:43 UTC (permalink / raw)
  To: Ulf Hansson; +Cc: linux-mmc, Ulf Hansson

Hi Ulf,

On Mon, Jun 10 2013, Ulf Hansson wrote:
> From: Ulf Hansson <ulf.hansson@linaro.org>
>
> The MMC/SD/SDIO cards are registered on the mmc_bus and should from a power
> management perspective be controlled from there. As of today each and every
> host driver needs to issue mmc_suspend|resume_host from their respective
> .suspend|resume methods, which seems like an unnecessary requirement to
> put on them. Additionally, a shutdown sequence shall be initiated from the
> mmc_bus.
>
> This patch set moves the responsiblity to suspend the cards into the mmc_bus.
> It also invents the shutdown sequence, also to be handled from the mmc_bus.
> In the SDIO case, the shutdown sequence will not involve any SDIO specific
> operations. If this would be desired, I suggest to handle that as and separate
> step, since it would involve the sdio bus and potentially the sdio drivers.
>
> As a part of the patches releated to adding the shutdown sequence, specific
> issues to handle eMMC power off notification properly are included in this
> patch set as well.
>
> The mmc_suspend|resume_host functions are not removed, but will instead always
> return successful. A separate patch(es) build on top of this patch set, shall
> remove the API:s together with updating each and every host driver.
>
> Do note, that patch 1 to 4 has been sent earlier in the set "mmc: core: Let the
> mmc_bus handle suspend|resume sequence". Since the functionallity are very close
> releated I decided to fold them in into this patch set.
>
> A big thank you to Jaehoon Chung who has tested the patches 1 to 4.
>
> Ulf Hansson (12):
>   mmc: core: Remove unnecessary check for the remove callback
>   mmc: core: Validate suspend prerequisites for SDIO at SUSPEND_PREPARE
>   mmc: core: Push common suspend|resume code into each bus_ops
>   mmc: core: Initiate suspend|resume from mmc bus instead of mmc host
>   mmc: core: Handle card shutdown from mmc_bus
>   mmc: core: Extend shutdown sequence to handle bus operations
>   mmc: core: Add shutdown callback for SD bus_ops
>   mmc: core: Handle both poweroff notification types for eMMC
>   mmc: core: Add shutdown callback for (e)MMC bus_ops
>   mmc: core: Enable power_off_notify for eMMC shutdown sequence
>   mmc: core: Invent MMC_CAP2_FULL_PWR_CYCLE
>   mmc: core: Add DT-bindings for MMC_CAP2_FULL_PWR_CYCLE
>
>  Documentation/devicetree/bindings/mmc/mmc.txt |    1 +
>  drivers/mmc/card/block.c                      |   15 ++++-
>  drivers/mmc/card/mmc_test.c                   |    5 ++
>  drivers/mmc/core/bus.c                        |   37 ++++++++++-
>  drivers/mmc/core/core.c                       |   87 ++++---------------------
>  drivers/mmc/core/core.h                       |    2 +
>  drivers/mmc/core/host.c                       |    2 +
>  drivers/mmc/core/mmc.c                        |   40 +++++++++---
>  drivers/mmc/core/sd.c                         |    6 ++
>  drivers/mmc/core/sdio.c                       |   48 ++++++++++++--
>  include/linux/mmc/card.h                      |    1 +
>  include/linux/mmc/host.h                      |    2 +-
>  12 files changed, 153 insertions(+), 93 deletions(-)

Thanks, all pushed to mmc-next, hopefully for 3.11 depending on testing.

- Chris.
-- 
Chris Ball   <cjb@laptop.org>   <http://printf.net/>
One Laptop Per Child

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

end of thread, other threads:[~2013-06-27 15:43 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-06-10 15:03 [PATCH 00/12] mmc: core: mmc_bus to handle suspend|resume|shutdown Ulf Hansson
2013-06-10 15:03 ` [PATCH 01/12] mmc: core: Remove unnecessary check for the remove callback Ulf Hansson
2013-06-10 15:03 ` [PATCH 02/12] mmc: core: Validate suspend prerequisites for SDIO at SUSPEND_PREPARE Ulf Hansson
2013-06-10 15:03 ` [PATCH 03/12] mmc: core: Push common suspend|resume code into each bus_ops Ulf Hansson
2013-06-10 15:03 ` [PATCH 04/12] mmc: core: Initiate suspend|resume from mmc bus instead of mmc host Ulf Hansson
2013-06-10 15:03 ` [PATCH 05/12] mmc: core: Handle card shutdown from mmc_bus Ulf Hansson
2013-06-10 15:03 ` [PATCH 06/12] mmc: core: Extend shutdown sequence to handle bus operations Ulf Hansson
2013-06-10 15:03 ` [PATCH 07/12] mmc: core: Add shutdown callback for SD bus_ops Ulf Hansson
2013-06-10 15:03 ` [PATCH 08/12] mmc: core: Handle both poweroff notification types for eMMC Ulf Hansson
2013-06-10 15:03 ` [PATCH 09/12] mmc: core: Add shutdown callback for (e)MMC bus_ops Ulf Hansson
2013-06-10 15:03 ` [PATCH 10/12] mmc: core: Enable power_off_notify for eMMC shutdown sequence Ulf Hansson
2013-06-10 15:03 ` [PATCH 11/12] mmc: core: Invent MMC_CAP2_FULL_PWR_CYCLE Ulf Hansson
2013-06-10 15:03 ` [PATCH 12/12] mmc: core: Add DT-bindings for MMC_CAP2_FULL_PWR_CYCLE Ulf Hansson
2013-06-11  9:24 ` [PATCH 00/12] mmc: core: mmc_bus to handle suspend|resume|shutdown Linus Walleij
2013-06-12  8:15   ` Pierre Ossman
2013-06-27 15:43 ` 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).