public inbox for linux-mmc@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH V7 00/14] mmc: host: Add facility to support re-tuning
@ 2015-05-07 10:10 Adrian Hunter
  2015-05-07 10:10 ` [PATCH V7 01/14] " Adrian Hunter
                   ` (14 more replies)
  0 siblings, 15 replies; 17+ messages in thread
From: Adrian Hunter @ 2015-05-07 10:10 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: linux-mmc, Aaron Lu, Philip Rakity, Al Cooper, Arend van Spriel

Hi

Here is V7 of some patches to move re-tuning support
out of sdhci and into the core, and add support for HS400
re-tuning.

Currently sdhci does re-tuning transparently by
calling sdhci_execute_tuning() from its ->request()
function.

The problem with HS400 re-tuning is that it must be
done in HS200 mode. That means using switch commands
and making ios changes. That means it potentially
conflicts with other command sequences. The new
re-tuning support accomodates that.

Changes in V7:

    mmc: host: Add facility to support re-tuning
	Remove unused mmc_retune_not_needed()

    mmc: core: Enable / disable re-tuning
	As already sent separately as V7:
	Also flag re-tune needed in SDIO 'keep_power'
	case, when a re-tuning timer is being used.

    mmc: core: Add support for re-tuning before each request
	Fold in next patch

    mmc: core: Check re-tuning before retrying
	Folded into previous patch

    mmc: mmc: Hold re-tuning if the card is put to sleep
	Change title to:
    mmc: mmc: Hold re-tuning in mmc_sleep()
	Remove changes from V6
	Hold re-tuning while card is deselected

    mmc: core: Flag re-tuning is needed on CRC errors
	Do it from core rather than the host

Changes in V6:

    mmc: host: Add facility to support re-tuning
	Don't export functions only used in core

    mmc: core: Enable / disable re-tuning
	Ensure re-tuning timer is disabled in SDIO suspend

    mmc: core: Hold re-tuning while bkops ongoing
	Hold re-tuning always and release only if
	bkops is not ongoing.

    mmc: mmc: Hold re-tuning if the card is put to sleep
	Hold re-tuning for mmc_sleep even if card is
	immediately powered off, disabling re-tuning.

Changes in V5:

    mmc: host: Add facility to support re-tuning
	Make mmc_retune_enable() / mmc_retune_disable()
	only called from core.

    mmc: core: Enable / disable re-tuning
	Replaces mmc: core: Disable re-tuning when card is no longer initialized
	Enables re-tuning when tuning is executed

    mmc: sdhci: Change to new way of doing re-tuning
	Set host->retune_period instead of enabling re-tuning.

Changes in V4:

    These patches now depend on Ulf's patch:
	mmc: core: Enable runtime PM management of host devices

    mmc: host: Add facility to support re-tuning

	Assume mmc_claim_host() runtime resumes the host
	controller so there are no races with runtime pm.
	Consequently remove now un-needed re-tuning host
	operations.

    mmc: core: Add support for re-tuning before each request

	Call mmc_retune() prior to ->request()

    mmc: sdhci: Change to new way of doing re-tuning

	Updated to reflect the changes above.

Changes in V3:

    mmc: host: Add facility to support re-tuning

        Add host->retune_now flag so re-tuning can be
        started in the host drivers ->request()
        function to avoid racing with Runtime PM.

        Add host operations to let the host know when
        re-tuning is held, for eaxmple, to enable
        synchronization with runtime suspend / resume.

        Ensure functions are exported.

    mmc: core: Add support for re-tuning before each request
        Updated to reflect the change above.

    mmc: core: Check re-tuning before retrying
        Updated to reflect the change above.

    mmc: core: Hold re-tuning during switch commands
        Updated to reflect the change above.

    mmc: core: Hold re-tuning during erase commands
        Updated to reflect the change above.

    mmc: core: Hold re-tuning while bkops ongoing
        Updated to reflect the change above.

    mmc: core: Add support for HS400 re-tuning
        Updated and as already sent separately as V3:
        Remember to mmc_set_bus_speed(card) in mmc_hs400_to_hs200()

    mmc: sdhci: Change to new way of doing re-tuning
        Call mmc_retune() from ->request() function to
        avoid racing with Runtime PM. And implement
        hold_tuning / release_tuning operations to prevent
        runtime suspend while re-tuning is held.

    mmc: block: Retry errored data requests when re-tuning is needed
        Updated and as already sent separately as V3:
        Only retry when there is an error

Changes in V2:

    Added support to the block driver for re-tuning
    and retrying after a CRC error. The host driver
    is left to decide when an error indicates re-tuning
    is needed. The block driver will retry a data request
    once if re-tuning is flagged as needed.

    SDIO drivers need not be aware of re-tuning because
    retrying will anyway cause re-tuning when re-tuning
    is flagged as needed. Nevertheless SDIO drivers could
    use the need_retune flag to instigate a retry when
    otherwise they might not have.

    mmc: core: Simplify by adding mmc_execute_tuning()
        Dropped because it has been applied

    mmc: host: Add facility to support re-tuning
        Renamed mmc_retune_retry() to mmc_retune_recheck()
        to better reflect what it does.

    mmc: core: Move mmc_card_removed() into mmc_start_request()
        Dropped because it has been applied

    mmc: core: Add support for re-tuning before each request
        Fixed un-balanced re-tune hold / release

    mmc: sdhci: Always init buf_ready_int
        Dropped because it has been applied

    mmc: core: Separate out the mmc_switch status check so it can be re-used
        New patch

    mmc: core: Add support for HS400 re-tuning
        It was found that that the original code was not reliable
        after a CRC error. The problem was that the CMD13 after a
        switch was faiing. So the code was changed to check the
        switch status *after* changing the I/O state to match the
        switch i.e. the new I/O state is the correct one to use
        after a switch.

    mmc: sdhci: Flag re-tuning is needed on CRC or End-Bit errors
        New patch

    mmc: block: Check re-tuning in the recovery path
        New patch

    mmc: block: Retry data requests when re-tuning is needed
        New patch

    mmc: core: Don't print reset warning if reset is not supported
        New patch


Adrian Hunter (14):
      mmc: host: Add facility to support re-tuning
      mmc: core: Enable / disable re-tuning
      mmc: core: Add support for re-tuning before each request
      mmc: core: Hold re-tuning during switch commands
      mmc: core: Hold re-tuning during erase commands
      mmc: core: Hold re-tuning while bkops ongoing
      mmc: mmc: Hold re-tuning in mmc_sleep()
      mmc: core: Separate out the mmc_switch status check so it can be re-used
      mmc: core: Add support for HS400 re-tuning
      mmc: sdhci: Change to new way of doing re-tuning
      mmc: core: Flag re-tuning is needed on CRC errors
      mmc: block: Check re-tuning in the recovery path
      mmc: block: Retry errored data requests when re-tuning is needed
      mmc: core: Don't print reset warning if reset is not supported

 drivers/mmc/card/block.c   |  14 +++++-
 drivers/mmc/card/queue.h   |   1 +
 drivers/mmc/core/core.c    |  57 +++++++++++++++++++----
 drivers/mmc/core/core.h    |   2 +
 drivers/mmc/core/host.c    |  85 ++++++++++++++++++++++++++++++++++
 drivers/mmc/core/host.h    |   6 +++
 drivers/mmc/core/mmc.c     |  98 ++++++++++++++++++++++++++++++++++++++-
 drivers/mmc/core/mmc_ops.c |  44 +++++++++++-------
 drivers/mmc/core/mmc_ops.h |   1 +
 drivers/mmc/core/sdio.c    |   6 ++-
 drivers/mmc/host/sdhci.c   | 112 ++++++---------------------------------------
 drivers/mmc/host/sdhci.h   |   3 --
 include/linux/mmc/host.h   |  23 ++++++++++
 13 files changed, 322 insertions(+), 130 deletions(-)


Regards
Adrian


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

* [PATCH V7 01/14] mmc: host: Add facility to support re-tuning
  2015-05-07 10:10 [PATCH V7 00/14] mmc: host: Add facility to support re-tuning Adrian Hunter
@ 2015-05-07 10:10 ` Adrian Hunter
  2015-05-07 10:10 ` [PATCH V7 02/14] mmc: core: Enable / disable re-tuning Adrian Hunter
                   ` (13 subsequent siblings)
  14 siblings, 0 replies; 17+ messages in thread
From: Adrian Hunter @ 2015-05-07 10:10 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: linux-mmc, Aaron Lu, Philip Rakity, Al Cooper, Arend van Spriel

Currently, there is core support for tuning during
initialization. There can also be a need to re-tune
periodically (e.g. sdhci) or to re-tune after the
host controller is powered off (e.g. after PM
runtime suspend / resume) or to re-tune in response
to CRC errors.

The main requirements for re-tuning are:
  - ability to enable / disable re-tuning
  - ability to flag that re-tuning is needed
  - ability to re-tune before any request
  - ability to hold off re-tuning if the card is busy
  - ability to hold off re-tuning if re-tuning is in
  progress
  - ability to run a re-tuning timer

To support those requirements 7 members are added to struct
mmc_host:

  unsigned int		can_retune:1;	/* re-tuning can be used */
  unsigned int		doing_retune:1;	/* re-tuning in progress */
  unsigned int		retune_now:1;   /* do re-tuning at next req */
  int			need_retune;	/* re-tuning is needed */
  int			hold_retune;	/* hold off re-tuning */
  unsigned int		retune_period;  /* re-tuning period in secs */
  struct timer_list	retune_timer;	/* for periodic re-tuning */

need_retune is an integer so it can be set without needing
synchronization. hold_retune is a integer to allow nesting.

Various simple functions are provided to set / clear those
variables.

Subsequent patches take those functions into use.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 drivers/mmc/core/host.c  | 68 ++++++++++++++++++++++++++++++++++++++++++++++++
 drivers/mmc/core/host.h  |  6 +++++
 include/linux/mmc/host.h | 23 ++++++++++++++++
 3 files changed, 97 insertions(+)

diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
index 8be0df7..e90e02f 100644
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -301,6 +301,73 @@ static inline void mmc_host_clk_sysfs_init(struct mmc_host *host)
 
 #endif
 
+void mmc_retune_enable(struct mmc_host *host)
+{
+	host->can_retune = 1;
+	if (host->retune_period)
+		mod_timer(&host->retune_timer,
+			  jiffies + host->retune_period * HZ);
+}
+
+void mmc_retune_disable(struct mmc_host *host)
+{
+	host->can_retune = 0;
+	del_timer_sync(&host->retune_timer);
+	host->retune_now = 0;
+	host->need_retune = 0;
+}
+
+void mmc_retune_timer_stop(struct mmc_host *host)
+{
+	del_timer_sync(&host->retune_timer);
+}
+EXPORT_SYMBOL(mmc_retune_timer_stop);
+
+void mmc_retune_hold(struct mmc_host *host)
+{
+	if (!host->hold_retune)
+		host->retune_now = 1;
+	host->hold_retune += 1;
+}
+
+void mmc_retune_release(struct mmc_host *host)
+{
+	if (host->hold_retune)
+		host->hold_retune -= 1;
+	else
+		WARN_ON(1);
+}
+
+int mmc_retune(struct mmc_host *host)
+{
+	int err;
+
+	if (host->retune_now)
+		host->retune_now = 0;
+	else
+		return 0;
+
+	if (!host->need_retune || host->doing_retune || !host->card)
+		return 0;
+
+	host->need_retune = 0;
+
+	host->doing_retune = 1;
+
+	err = mmc_execute_tuning(host->card);
+
+	host->doing_retune = 0;
+
+	return err;
+}
+
+static void mmc_retune_timer(unsigned long data)
+{
+	struct mmc_host *host = (struct mmc_host *)data;
+
+	mmc_retune_needed(host);
+}
+
 /**
  *	mmc_of_parse() - parse host's device-tree node
  *	@host: host whose node should be parsed.
@@ -504,6 +571,7 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
 #ifdef CONFIG_PM
 	host->pm_notify.notifier_call = mmc_pm_notify;
 #endif
+	setup_timer(&host->retune_timer, mmc_retune_timer, (unsigned long)host);
 
 	/*
 	 * By default, hosts do not support SGIO or large requests.
diff --git a/drivers/mmc/core/host.h b/drivers/mmc/core/host.h
index f2ab9e5..992bf53 100644
--- a/drivers/mmc/core/host.h
+++ b/drivers/mmc/core/host.h
@@ -15,5 +15,11 @@
 int mmc_register_host_class(void);
 void mmc_unregister_host_class(void);
 
+void mmc_retune_enable(struct mmc_host *host);
+void mmc_retune_disable(struct mmc_host *host);
+void mmc_retune_hold(struct mmc_host *host);
+void mmc_retune_release(struct mmc_host *host);
+int mmc_retune(struct mmc_host *host);
+
 #endif
 
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index b5bedae..f471193 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -12,6 +12,7 @@
 
 #include <linux/leds.h>
 #include <linux/mutex.h>
+#include <linux/timer.h>
 #include <linux/sched.h>
 #include <linux/device.h>
 #include <linux/fault-inject.h>
@@ -321,10 +322,18 @@ struct mmc_host {
 #ifdef CONFIG_MMC_DEBUG
 	unsigned int		removed:1;	/* host is being removed */
 #endif
+	unsigned int		can_retune:1;	/* re-tuning can be used */
+	unsigned int		doing_retune:1;	/* re-tuning in progress */
+	unsigned int		retune_now:1;	/* do re-tuning at next req */
 
 	int			rescan_disable;	/* disable card detection */
 	int			rescan_entered;	/* used with nonremovable devices */
 
+	int			need_retune;	/* re-tuning is needed */
+	int			hold_retune;	/* hold off re-tuning */
+	unsigned int		retune_period;	/* re-tuning period in secs */
+	struct timer_list	retune_timer;	/* for periodic re-tuning */
+
 	bool			trigger_card_event; /* card_event necessary */
 
 	struct mmc_card		*card;		/* device attached to this host */
@@ -513,4 +522,18 @@ static inline bool mmc_card_hs400(struct mmc_card *card)
 	return card->host->ios.timing == MMC_TIMING_MMC_HS400;
 }
 
+void mmc_retune_timer_stop(struct mmc_host *host);
+
+static inline void mmc_retune_needed(struct mmc_host *host)
+{
+	if (host->can_retune)
+		host->need_retune = 1;
+}
+
+static inline void mmc_retune_recheck(struct mmc_host *host)
+{
+	if (host->hold_retune <= 1)
+		host->retune_now = 1;
+}
+
 #endif /* LINUX_MMC_HOST_H */
-- 
1.9.1


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

* [PATCH V7 02/14] mmc: core: Enable / disable re-tuning
  2015-05-07 10:10 [PATCH V7 00/14] mmc: host: Add facility to support re-tuning Adrian Hunter
  2015-05-07 10:10 ` [PATCH V7 01/14] " Adrian Hunter
@ 2015-05-07 10:10 ` Adrian Hunter
  2015-05-07 10:10 ` [PATCH V7 03/14] mmc: core: Add support for re-tuning before each request Adrian Hunter
                   ` (12 subsequent siblings)
  14 siblings, 0 replies; 17+ messages in thread
From: Adrian Hunter @ 2015-05-07 10:10 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: linux-mmc, Aaron Lu, Philip Rakity, Al Cooper, Arend van Spriel

Enable re-tuning when tuning is executed and
disable re-tuning when card is no longer initialized.

In the case of SDIO suspend, the card can keep power.
In that case, re-tuning need not be disabled, but, if
a re-tuning timer is being used, ensure it is disabled
and assume that re-tuning will be needed upon resume
since it is not known how long the suspend will last.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 drivers/mmc/core/core.c | 4 ++++
 drivers/mmc/core/sdio.c | 6 +++++-
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 92e7671..007c444 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -1109,6 +1109,8 @@ int mmc_execute_tuning(struct mmc_card *card)
 
 	if (err)
 		pr_err("%s: tuning execution failed\n", mmc_hostname(host));
+	else
+		mmc_retune_enable(host);
 
 	return err;
 }
@@ -1140,6 +1142,8 @@ void mmc_set_bus_width(struct mmc_host *host, unsigned int width)
  */
 void mmc_set_initial_state(struct mmc_host *host)
 {
+	mmc_retune_disable(host);
+
 	if (mmc_host_is_spi(host))
 		host->ios.chip_select = MMC_CS_HIGH;
 	else
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
index f6c28a7..5c1423a3 100644
--- a/drivers/mmc/core/sdio.c
+++ b/drivers/mmc/core/sdio.c
@@ -934,8 +934,12 @@ static int mmc_sdio_suspend(struct mmc_host *host)
 		mmc_release_host(host);
 	}
 
-	if (!mmc_card_keep_power(host))
+	if (!mmc_card_keep_power(host)) {
 		mmc_power_off(host);
+	} else if (host->retune_period) {
+		mmc_retune_timer_stop(host);
+		mmc_retune_needed(host);
+	}
 
 	return 0;
 }
-- 
1.9.1


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

* [PATCH V7 03/14] mmc: core: Add support for re-tuning before each request
  2015-05-07 10:10 [PATCH V7 00/14] mmc: host: Add facility to support re-tuning Adrian Hunter
  2015-05-07 10:10 ` [PATCH V7 01/14] " Adrian Hunter
  2015-05-07 10:10 ` [PATCH V7 02/14] mmc: core: Enable / disable re-tuning Adrian Hunter
@ 2015-05-07 10:10 ` Adrian Hunter
  2015-05-07 10:10 ` [PATCH V7 04/14] mmc: core: Hold re-tuning during switch commands Adrian Hunter
                   ` (11 subsequent siblings)
  14 siblings, 0 replies; 17+ messages in thread
From: Adrian Hunter @ 2015-05-07 10:10 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: linux-mmc, Aaron Lu, Philip Rakity, Al Cooper, Arend van Spriel

At the start of each request, re-tune if needed and
then hold off re-tuning again until the request is done.

Note that though there is one function that starts
requests (mmc_start_request) there are two that wait for
the request to be done (mmc_wait_for_req_done and
mmc_wait_for_data_req_done).  Also note that
mmc_wait_for_data_req_done can return even when the
request is not done (which allows the block driver
to prepare a newly arrived request while still
waiting for the previous request).

This patch ensures re-tuning is held for the duration
of a request.  Subsequent patches will also hold
re-tuning at other times when it might cause a
conflict.

In addition, possibly a command is failing because
re-tuning is needed. Use mmc_retune_recheck() to check
re-tuning. At that point re-tuning is held, at least by
the request, so mmc_retune_recheck() flags host->retune_now
if the hold count is 1.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 drivers/mmc/core/core.c | 35 ++++++++++++++++++++++++++++-------
 1 file changed, 28 insertions(+), 7 deletions(-)

diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 007c444..ec3453f 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -186,12 +186,29 @@ void mmc_request_done(struct mmc_host *host, struct mmc_request *mrq)
 
 EXPORT_SYMBOL(mmc_request_done);
 
+static void __mmc_start_request(struct mmc_host *host, struct mmc_request *mrq)
+{
+	int err;
+
+	/* Assumes host controller has been runtime resumed by mmc_claim_host */
+	err = mmc_retune(host);
+	if (err) {
+		mrq->cmd->error = err;
+		mmc_request_done(host, mrq);
+		return;
+	}
+
+	host->ops->request(host, mrq);
+}
+
 static int mmc_start_request(struct mmc_host *host, struct mmc_request *mrq)
 {
 #ifdef CONFIG_MMC_DEBUG
 	unsigned int i, sz;
 	struct scatterlist *sg;
 #endif
+	mmc_retune_hold(host);
+
 	if (mmc_card_removed(host->card))
 		return -ENOMEDIUM;
 
@@ -252,7 +269,7 @@ static int mmc_start_request(struct mmc_host *host, struct mmc_request *mrq)
 	}
 	mmc_host_clk_hold(host);
 	led_trigger_event(host->led, LED_FULL);
-	host->ops->request(host, mrq);
+	__mmc_start_request(host, mrq);
 
 	return 0;
 }
@@ -417,22 +434,22 @@ static int mmc_wait_for_data_req_done(struct mmc_host *host,
 							    host->areq);
 				break; /* return err */
 			} else {
+				mmc_retune_recheck(host);
 				pr_info("%s: req failed (CMD%u): %d, retrying...\n",
 					mmc_hostname(host),
 					cmd->opcode, cmd->error);
 				cmd->retries--;
 				cmd->error = 0;
-				host->ops->request(host, mrq);
+				__mmc_start_request(host, mrq);
 				continue; /* wait for done/new event again */
 			}
 		} else if (context_info->is_new_req) {
 			context_info->is_new_req = false;
-			if (!next_req) {
-				err = MMC_BLK_NEW_REQUEST;
-				break; /* return err */
-			}
+			if (!next_req)
+				return MMC_BLK_NEW_REQUEST;
 		}
 	}
+	mmc_retune_release(host);
 	return err;
 }
 
@@ -467,12 +484,16 @@ static void mmc_wait_for_req_done(struct mmc_host *host,
 		    mmc_card_removed(host->card))
 			break;
 
+		mmc_retune_recheck(host);
+
 		pr_debug("%s: req failed (CMD%u): %d, retrying...\n",
 			 mmc_hostname(host), cmd->opcode, cmd->error);
 		cmd->retries--;
 		cmd->error = 0;
-		host->ops->request(host, mrq);
+		__mmc_start_request(host, mrq);
 	}
+
+	mmc_retune_release(host);
 }
 
 /**
-- 
1.9.1


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

* [PATCH V7 04/14] mmc: core: Hold re-tuning during switch commands
  2015-05-07 10:10 [PATCH V7 00/14] mmc: host: Add facility to support re-tuning Adrian Hunter
                   ` (2 preceding siblings ...)
  2015-05-07 10:10 ` [PATCH V7 03/14] mmc: core: Add support for re-tuning before each request Adrian Hunter
@ 2015-05-07 10:10 ` Adrian Hunter
  2015-05-07 10:10 ` [PATCH V7 05/14] mmc: core: Hold re-tuning during erase commands Adrian Hunter
                   ` (10 subsequent siblings)
  14 siblings, 0 replies; 17+ messages in thread
From: Adrian Hunter @ 2015-05-07 10:10 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: linux-mmc, Aaron Lu, Philip Rakity, Al Cooper, Arend van Spriel

Hold re-tuning during switch commands to prevent
it from conflicting with the busy state or the CMD13
verification.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 drivers/mmc/core/mmc_ops.c | 30 ++++++++++++++++++++----------
 1 file changed, 20 insertions(+), 10 deletions(-)

diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c
index 0ea042d..4cad5f0 100644
--- a/drivers/mmc/core/mmc_ops.c
+++ b/drivers/mmc/core/mmc_ops.c
@@ -19,6 +19,7 @@
 #include <linux/mmc/mmc.h>
 
 #include "core.h"
+#include "host.h"
 #include "mmc_ops.h"
 
 #define MMC_OPS_TIMEOUT_MS	(10 * 60 * 1000) /* 10 minute timeout */
@@ -474,6 +475,8 @@ int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
 	u32 status = 0;
 	bool use_r1b_resp = use_busy_signal;
 
+	mmc_retune_hold(host);
+
 	/*
 	 * If the cmd timeout and the max_busy_timeout of the host are both
 	 * specified, let's validate them. A failure means we need to prevent
@@ -506,11 +509,11 @@ int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
 
 	err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES);
 	if (err)
-		return err;
+		goto out;
 
 	/* No need to check card status in case of unblocking command */
 	if (!use_busy_signal)
-		return 0;
+		goto out;
 
 	/*
 	 * CRC errors shall only be ignored in cases were CMD13 is used to poll
@@ -529,7 +532,7 @@ int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
 		if (send_status) {
 			err = __mmc_send_status(card, &status, ignore_crc);
 			if (err)
-				return err;
+				goto out;
 		}
 		if ((host->caps & MMC_CAP_WAIT_WHILE_BUSY) && use_r1b_resp)
 			break;
@@ -543,29 +546,36 @@ int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
 		 */
 		if (!send_status) {
 			mmc_delay(timeout_ms);
-			return 0;
+			goto out;
 		}
 
 		/* Timeout if the device never leaves the program state. */
 		if (time_after(jiffies, timeout)) {
 			pr_err("%s: Card stuck in programming state! %s\n",
 				mmc_hostname(host), __func__);
-			return -ETIMEDOUT;
+			err = -ETIMEDOUT;
+			goto out;
 		}
 	} while (R1_CURRENT_STATE(status) == R1_STATE_PRG);
 
 	if (mmc_host_is_spi(host)) {
-		if (status & R1_SPI_ILLEGAL_COMMAND)
-			return -EBADMSG;
+		if (status & R1_SPI_ILLEGAL_COMMAND) {
+			err = -EBADMSG;
+			goto out;
+		}
 	} else {
 		if (status & 0xFDFFA000)
 			pr_warn("%s: unexpected status %#x after switch\n",
 				mmc_hostname(host), status);
-		if (status & R1_SWITCH_ERROR)
-			return -EBADMSG;
+		if (status & R1_SWITCH_ERROR) {
+			err = -EBADMSG;
+			goto out;
+		}
 	}
+out:
+	mmc_retune_release(host);
 
-	return 0;
+	return err;
 }
 EXPORT_SYMBOL_GPL(__mmc_switch);
 
-- 
1.9.1


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

* [PATCH V7 05/14] mmc: core: Hold re-tuning during erase commands
  2015-05-07 10:10 [PATCH V7 00/14] mmc: host: Add facility to support re-tuning Adrian Hunter
                   ` (3 preceding siblings ...)
  2015-05-07 10:10 ` [PATCH V7 04/14] mmc: core: Hold re-tuning during switch commands Adrian Hunter
@ 2015-05-07 10:10 ` Adrian Hunter
  2015-05-07 10:10 ` [PATCH V7 06/14] mmc: core: Hold re-tuning while bkops ongoing Adrian Hunter
                   ` (9 subsequent siblings)
  14 siblings, 0 replies; 17+ messages in thread
From: Adrian Hunter @ 2015-05-07 10:10 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: linux-mmc, Aaron Lu, Philip Rakity, Al Cooper, Arend van Spriel

Hold re-tuning during erase commands to prevent
it from conflicting with the sequence of commands.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 drivers/mmc/core/core.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index ec3453f..ff1e384 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -1995,6 +1995,8 @@ static int mmc_do_erase(struct mmc_card *card, unsigned int from,
 	unsigned long timeout;
 	int err;
 
+	mmc_retune_hold(card->host);
+
 	/*
 	 * qty is used to calculate the erase timeout which depends on how many
 	 * erase groups (or allocation units in SD terminology) are affected.
@@ -2098,6 +2100,7 @@ static int mmc_do_erase(struct mmc_card *card, unsigned int from,
 	} while (!(cmd.resp[0] & R1_READY_FOR_DATA) ||
 		 (R1_CURRENT_STATE(cmd.resp[0]) == R1_STATE_PRG));
 out:
+	mmc_retune_release(card->host);
 	return err;
 }
 
-- 
1.9.1


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

* [PATCH V7 06/14] mmc: core: Hold re-tuning while bkops ongoing
  2015-05-07 10:10 [PATCH V7 00/14] mmc: host: Add facility to support re-tuning Adrian Hunter
                   ` (4 preceding siblings ...)
  2015-05-07 10:10 ` [PATCH V7 05/14] mmc: core: Hold re-tuning during erase commands Adrian Hunter
@ 2015-05-07 10:10 ` Adrian Hunter
  2015-05-07 10:10 ` [PATCH V7 07/14] mmc: mmc: Hold re-tuning in mmc_sleep() Adrian Hunter
                   ` (8 subsequent siblings)
  14 siblings, 0 replies; 17+ messages in thread
From: Adrian Hunter @ 2015-05-07 10:10 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: linux-mmc, Aaron Lu, Philip Rakity, Al Cooper, Arend van Spriel

Hold re-tuning during bkops to prevent
it from conflicting with the busy state.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 drivers/mmc/core/core.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index ff1e384..adb6408 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -318,12 +318,15 @@ void mmc_start_bkops(struct mmc_card *card, bool from_exception)
 		use_busy_signal = false;
 	}
 
+	mmc_retune_hold(card->host);
+
 	err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
 			EXT_CSD_BKOPS_START, 1, timeout,
 			use_busy_signal, true, false);
 	if (err) {
 		pr_warn("%s: Error %d starting bkops\n",
 			mmc_hostname(card->host), err);
+		mmc_retune_release(card->host);
 		goto out;
 	}
 
@@ -334,6 +337,8 @@ void mmc_start_bkops(struct mmc_card *card, bool from_exception)
 	 */
 	if (!use_busy_signal)
 		mmc_card_set_doing_bkops(card);
+	else
+		mmc_retune_release(card->host);
 out:
 	mmc_release_host(card->host);
 }
@@ -749,6 +754,7 @@ int mmc_stop_bkops(struct mmc_card *card)
 	 */
 	if (!err || (err == -EINVAL)) {
 		mmc_card_clr_doing_bkops(card);
+		mmc_retune_release(card->host);
 		err = 0;
 	}
 
-- 
1.9.1


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

* [PATCH V7 07/14] mmc: mmc: Hold re-tuning in mmc_sleep()
  2015-05-07 10:10 [PATCH V7 00/14] mmc: host: Add facility to support re-tuning Adrian Hunter
                   ` (5 preceding siblings ...)
  2015-05-07 10:10 ` [PATCH V7 06/14] mmc: core: Hold re-tuning while bkops ongoing Adrian Hunter
@ 2015-05-07 10:10 ` Adrian Hunter
  2015-05-07 10:10 ` [PATCH V7 08/14] mmc: core: Separate out the mmc_switch status check so it can be re-used Adrian Hunter
                   ` (7 subsequent siblings)
  14 siblings, 0 replies; 17+ messages in thread
From: Adrian Hunter @ 2015-05-07 10:10 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: linux-mmc, Aaron Lu, Philip Rakity, Al Cooper, Arend van Spriel

The sleep command is issued after deselecting the
card, but re-tuning won't work on a deselected card
so re-tuning must be held.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 drivers/mmc/core/mmc.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index f36c76f..fd41b28 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -21,6 +21,7 @@
 #include <linux/mmc/mmc.h>
 
 #include "core.h"
+#include "host.h"
 #include "bus.h"
 #include "mmc_ops.h"
 #include "sd_ops.h"
@@ -1511,9 +1512,12 @@ static int mmc_sleep(struct mmc_host *host)
 	unsigned int timeout_ms = DIV_ROUND_UP(card->ext_csd.sa_timeout, 10000);
 	int err;
 
+	/* Re-tuning can't be done once the card is deselected */
+	mmc_retune_hold(host);
+
 	err = mmc_deselect_cards(host);
 	if (err)
-		return err;
+		goto out_release;
 
 	cmd.opcode = MMC_SLEEP_AWAKE;
 	cmd.arg = card->rca << 16;
@@ -1534,7 +1538,7 @@ static int mmc_sleep(struct mmc_host *host)
 
 	err = mmc_wait_for_cmd(host, &cmd, 0);
 	if (err)
-		return err;
+		goto out_release;
 
 	/*
 	 * If the host does not wait while the card signals busy, then we will
@@ -1545,6 +1549,8 @@ static int mmc_sleep(struct mmc_host *host)
 	if (!cmd.busy_timeout || !(host->caps & MMC_CAP_WAIT_WHILE_BUSY))
 		mmc_delay(timeout_ms);
 
+out_release:
+	mmc_retune_release(host);
 	return err;
 }
 
-- 
1.9.1


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

* [PATCH V7 08/14] mmc: core: Separate out the mmc_switch status check so it can be re-used
  2015-05-07 10:10 [PATCH V7 00/14] mmc: host: Add facility to support re-tuning Adrian Hunter
                   ` (6 preceding siblings ...)
  2015-05-07 10:10 ` [PATCH V7 07/14] mmc: mmc: Hold re-tuning in mmc_sleep() Adrian Hunter
@ 2015-05-07 10:10 ` Adrian Hunter
  2015-05-07 10:10 ` [PATCH V7 09/14] mmc: core: Add support for HS400 re-tuning Adrian Hunter
                   ` (6 subsequent siblings)
  14 siblings, 0 replies; 17+ messages in thread
From: Adrian Hunter @ 2015-05-07 10:10 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: linux-mmc, Aaron Lu, Philip Rakity, Al Cooper, Arend van Spriel

Make a separate function to do the mmc_switch status check
so it can be re-used. This is preparation for adding support
for HS400 re-tuning.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 drivers/mmc/core/mmc_ops.c | 30 ++++++++++++++++--------------
 drivers/mmc/core/mmc_ops.h |  1 +
 2 files changed, 17 insertions(+), 14 deletions(-)

diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c
index 4cad5f0..0e9ae1c 100644
--- a/drivers/mmc/core/mmc_ops.c
+++ b/drivers/mmc/core/mmc_ops.c
@@ -450,6 +450,21 @@ int mmc_spi_set_crc(struct mmc_host *host, int use_crc)
 	return err;
 }
 
+int mmc_switch_status_error(struct mmc_host *host, u32 status)
+{
+	if (mmc_host_is_spi(host)) {
+		if (status & R1_SPI_ILLEGAL_COMMAND)
+			return -EBADMSG;
+	} else {
+		if (status & 0xFDFFA000)
+			pr_warn("%s: unexpected status %#x after switch\n",
+				mmc_hostname(host), status);
+		if (status & R1_SWITCH_ERROR)
+			return -EBADMSG;
+	}
+	return 0;
+}
+
 /**
  *	__mmc_switch - modify EXT_CSD register
  *	@card: the MMC card associated with the data transfer
@@ -558,20 +573,7 @@ int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
 		}
 	} while (R1_CURRENT_STATE(status) == R1_STATE_PRG);
 
-	if (mmc_host_is_spi(host)) {
-		if (status & R1_SPI_ILLEGAL_COMMAND) {
-			err = -EBADMSG;
-			goto out;
-		}
-	} else {
-		if (status & 0xFDFFA000)
-			pr_warn("%s: unexpected status %#x after switch\n",
-				mmc_hostname(host), status);
-		if (status & R1_SWITCH_ERROR) {
-			err = -EBADMSG;
-			goto out;
-		}
-	}
+	err = mmc_switch_status_error(host, status);
 out:
 	mmc_retune_release(host);
 
diff --git a/drivers/mmc/core/mmc_ops.h b/drivers/mmc/core/mmc_ops.h
index 6f4b00e..f498f9a 100644
--- a/drivers/mmc/core/mmc_ops.h
+++ b/drivers/mmc/core/mmc_ops.h
@@ -27,6 +27,7 @@ int mmc_spi_set_crc(struct mmc_host *host, int use_crc);
 int mmc_bus_test(struct mmc_card *card, u8 bus_width);
 int mmc_send_hpi_cmd(struct mmc_card *card, u32 *status);
 int mmc_can_ext_csd(struct mmc_card *card);
+int mmc_switch_status_error(struct mmc_host *host, u32 status);
 
 #endif
 
-- 
1.9.1


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

* [PATCH V7 09/14] mmc: core: Add support for HS400 re-tuning
  2015-05-07 10:10 [PATCH V7 00/14] mmc: host: Add facility to support re-tuning Adrian Hunter
                   ` (7 preceding siblings ...)
  2015-05-07 10:10 ` [PATCH V7 08/14] mmc: core: Separate out the mmc_switch status check so it can be re-used Adrian Hunter
@ 2015-05-07 10:10 ` Adrian Hunter
  2015-05-07 10:10 ` [PATCH V7 10/14] mmc: sdhci: Change to new way of doing re-tuning Adrian Hunter
                   ` (5 subsequent siblings)
  14 siblings, 0 replies; 17+ messages in thread
From: Adrian Hunter @ 2015-05-07 10:10 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: linux-mmc, Aaron Lu, Philip Rakity, Al Cooper, Arend van Spriel

HS400 re-tuning must be done in HS200 mode. Add
the ability to switch from HS400 mode to HS200
mode before re-tuning and switch back to HS400
after re-tuning.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 drivers/mmc/core/core.h |  2 ++
 drivers/mmc/core/host.c | 17 ++++++++++
 drivers/mmc/core/mmc.c  | 88 +++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 107 insertions(+)

diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h
index cfba3c0..e6f2de7 100644
--- a/drivers/mmc/core/core.h
+++ b/drivers/mmc/core/core.h
@@ -88,6 +88,8 @@ void mmc_remove_card_debugfs(struct mmc_card *card);
 void mmc_init_context_info(struct mmc_host *host);
 
 int mmc_execute_tuning(struct mmc_card *card);
+int mmc_hs200_to_hs400(struct mmc_card *card);
+int mmc_hs400_to_hs200(struct mmc_card *card);
 
 #endif
 
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
index e90e02f..86c495b 100644
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -340,6 +340,7 @@ void mmc_retune_release(struct mmc_host *host)
 
 int mmc_retune(struct mmc_host *host)
 {
+	bool return_to_hs400 = false;
 	int err;
 
 	if (host->retune_now)
@@ -354,8 +355,24 @@ int mmc_retune(struct mmc_host *host)
 
 	host->doing_retune = 1;
 
+	if (host->ios.timing == MMC_TIMING_MMC_HS400) {
+		err = mmc_hs400_to_hs200(host->card);
+		if (err)
+			goto out;
+
+		return_to_hs400 = true;
+
+		if (host->ops->prepare_hs400_tuning)
+			host->ops->prepare_hs400_tuning(host, &host->ios);
+	}
+
 	err = mmc_execute_tuning(host->card);
+	if (err)
+		goto out;
 
+	if (return_to_hs400)
+		err = mmc_hs200_to_hs400(host->card);
+out:
 	host->doing_retune = 0;
 
 	return err;
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index fd41b28..a802863 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -1092,6 +1092,94 @@ static int mmc_select_hs400(struct mmc_card *card)
 	return 0;
 }
 
+int mmc_hs200_to_hs400(struct mmc_card *card)
+{
+	return mmc_select_hs400(card);
+}
+
+/* Caller must hold re-tuning */
+static int mmc_switch_status(struct mmc_card *card)
+{
+	u32 status;
+	int err;
+
+	err = mmc_send_status(card, &status);
+	if (err)
+		return err;
+
+	return mmc_switch_status_error(card->host, status);
+}
+
+int mmc_hs400_to_hs200(struct mmc_card *card)
+{
+	struct mmc_host *host = card->host;
+	bool send_status = true;
+	unsigned int max_dtr;
+	int err;
+
+	if (host->caps & MMC_CAP_WAIT_WHILE_BUSY)
+		send_status = false;
+
+	/* Reduce frequency to HS */
+	max_dtr = card->ext_csd.hs_max_dtr;
+	mmc_set_clock(host, max_dtr);
+
+	/* Switch HS400 to HS DDR */
+	err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING,
+			   EXT_CSD_TIMING_HS, card->ext_csd.generic_cmd6_time,
+			   true, send_status, true);
+	if (err)
+		goto out_err;
+
+	mmc_set_timing(host, MMC_TIMING_MMC_DDR52);
+
+	if (!send_status) {
+		err = mmc_switch_status(card);
+		if (err)
+			goto out_err;
+	}
+
+	/* Switch HS DDR to HS */
+	err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH,
+			   EXT_CSD_BUS_WIDTH_8, card->ext_csd.generic_cmd6_time,
+			   true, send_status, true);
+	if (err)
+		goto out_err;
+
+	mmc_set_timing(host, MMC_TIMING_MMC_HS);
+
+	if (!send_status) {
+		err = mmc_switch_status(card);
+		if (err)
+			goto out_err;
+	}
+
+	/* Switch HS to HS200 */
+	err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING,
+			   EXT_CSD_TIMING_HS200,
+			   card->ext_csd.generic_cmd6_time, true, send_status,
+			   true);
+	if (err)
+		goto out_err;
+
+	mmc_set_timing(host, MMC_TIMING_MMC_HS200);
+
+	if (!send_status) {
+		err = mmc_switch_status(card);
+		if (err)
+			goto out_err;
+	}
+
+	mmc_set_bus_speed(card);
+
+	return 0;
+
+out_err:
+	pr_err("%s: %s failed, error %d\n", mmc_hostname(card->host),
+	       __func__, err);
+	return err;
+}
+
 /*
  * For device supporting HS200 mode, the following sequence
  * should be done before executing the tuning process.
-- 
1.9.1


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

* [PATCH V7 10/14] mmc: sdhci: Change to new way of doing re-tuning
  2015-05-07 10:10 [PATCH V7 00/14] mmc: host: Add facility to support re-tuning Adrian Hunter
                   ` (8 preceding siblings ...)
  2015-05-07 10:10 ` [PATCH V7 09/14] mmc: core: Add support for HS400 re-tuning Adrian Hunter
@ 2015-05-07 10:10 ` Adrian Hunter
  2015-05-07 10:10 ` [PATCH V7 11/14] mmc: core: Flag re-tuning is needed on CRC errors Adrian Hunter
                   ` (4 subsequent siblings)
  14 siblings, 0 replies; 17+ messages in thread
From: Adrian Hunter @ 2015-05-07 10:10 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: linux-mmc, Aaron Lu, Philip Rakity, Al Cooper, Arend van Spriel

Make use of mmc core support for re-tuning instead
of doing it all in the sdhci driver.

This patch also changes to flag the need for re-tuning
always after runtime suspend when tuning has been used
at initialization. Previously it was only done if
the re-tuning timer was in use.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 drivers/mmc/host/sdhci.c | 112 ++++++-----------------------------------------
 drivers/mmc/host/sdhci.h |   3 --
 2 files changed, 13 insertions(+), 102 deletions(-)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index c80287a..b345844 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -52,7 +52,6 @@ static void sdhci_finish_data(struct sdhci_host *);
 
 static void sdhci_finish_command(struct sdhci_host *);
 static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode);
-static void sdhci_tuning_timer(unsigned long data);
 static void sdhci_enable_preset_value(struct sdhci_host *host, bool enable);
 static int sdhci_pre_dma_transfer(struct sdhci_host *host,
 					struct mmc_data *data,
@@ -254,17 +253,6 @@ static void sdhci_init(struct sdhci_host *host, int soft)
 static void sdhci_reinit(struct sdhci_host *host)
 {
 	sdhci_init(host, 0);
-	/*
-	 * Retuning stuffs are affected by different cards inserted and only
-	 * applicable to UHS-I cards. So reset these fields to their initial
-	 * value when card is removed.
-	 */
-	if (host->flags & SDHCI_USING_RETUNING_TIMER) {
-		host->flags &= ~SDHCI_USING_RETUNING_TIMER;
-
-		del_timer_sync(&host->tuning_timer);
-		host->flags &= ~SDHCI_NEEDS_RETUNING;
-	}
 	sdhci_enable_card_detection(host);
 }
 
@@ -1353,7 +1341,6 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
 	struct sdhci_host *host;
 	int present;
 	unsigned long flags;
-	u32 tuning_opcode;
 
 	host = mmc_priv(mmc);
 
@@ -1387,39 +1374,6 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
 		host->mrq->cmd->error = -ENOMEDIUM;
 		tasklet_schedule(&host->finish_tasklet);
 	} else {
-		u32 present_state;
-
-		present_state = sdhci_readl(host, SDHCI_PRESENT_STATE);
-		/*
-		 * Check if the re-tuning timer has already expired and there
-		 * is no on-going data transfer and DAT0 is not busy. If so,
-		 * we need to execute tuning procedure before sending command.
-		 */
-		if ((host->flags & SDHCI_NEEDS_RETUNING) &&
-		    !(present_state & (SDHCI_DOING_WRITE | SDHCI_DOING_READ)) &&
-		    (present_state & SDHCI_DATA_0_LVL_MASK)) {
-			if (mmc->card) {
-				/* eMMC uses cmd21 but sd and sdio use cmd19 */
-				tuning_opcode =
-					mmc->card->type == MMC_TYPE_MMC ?
-					MMC_SEND_TUNING_BLOCK_HS200 :
-					MMC_SEND_TUNING_BLOCK;
-
-				/* Here we need to set the host->mrq to NULL,
-				 * in case the pending finish_tasklet
-				 * finishes it incorrectly.
-				 */
-				host->mrq = NULL;
-
-				spin_unlock_irqrestore(&host->lock, flags);
-				sdhci_execute_tuning(mmc, tuning_opcode);
-				spin_lock_irqsave(&host->lock, flags);
-
-				/* Restore original mmc_request structure */
-				host->mrq = mrq;
-			}
-		}
-
 		if (mrq->sbc && !(host->flags & SDHCI_AUTO_CMD23))
 			sdhci_send_command(host, mrq->sbc);
 		else
@@ -2065,23 +2019,18 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
 	}
 
 out:
-	host->flags &= ~SDHCI_NEEDS_RETUNING;
-
 	if (tuning_count) {
-		host->flags |= SDHCI_USING_RETUNING_TIMER;
-		mod_timer(&host->tuning_timer, jiffies + tuning_count * HZ);
+		/*
+		 * In case tuning fails, host controllers which support
+		 * re-tuning can try tuning again at a later time, when the
+		 * re-tuning timer expires.  So for these controllers, we
+		 * return 0. Since there might be other controllers who do not
+		 * have this capability, we return error for them.
+		 */
+		err = 0;
 	}
 
-	/*
-	 * In case tuning fails, host controllers which support re-tuning can
-	 * try tuning again at a later time, when the re-tuning timer expires.
-	 * So for these controllers, we return 0. Since there might be other
-	 * controllers who do not have this capability, we return error for
-	 * them. SDHCI_USING_RETUNING_TIMER means the host is currently using
-	 * a retuning timer to do the retuning for the card.
-	 */
-	if (err && (host->flags & SDHCI_USING_RETUNING_TIMER))
-		err = 0;
+	host->mmc->retune_period = err ? 0 : tuning_count;
 
 	sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
 	sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
@@ -2337,20 +2286,6 @@ static void sdhci_timeout_timer(unsigned long data)
 	spin_unlock_irqrestore(&host->lock, flags);
 }
 
-static void sdhci_tuning_timer(unsigned long data)
-{
-	struct sdhci_host *host;
-	unsigned long flags;
-
-	host = (struct sdhci_host *)data;
-
-	spin_lock_irqsave(&host->lock, flags);
-
-	host->flags |= SDHCI_NEEDS_RETUNING;
-
-	spin_unlock_irqrestore(&host->lock, flags);
-}
-
 /*****************************************************************************\
  *                                                                           *
  * Interrupt handling                                                        *
@@ -2728,11 +2663,8 @@ int sdhci_suspend_host(struct sdhci_host *host)
 {
 	sdhci_disable_card_detection(host);
 
-	/* Disable tuning since we are suspending */
-	if (host->flags & SDHCI_USING_RETUNING_TIMER) {
-		del_timer_sync(&host->tuning_timer);
-		host->flags &= ~SDHCI_NEEDS_RETUNING;
-	}
+	mmc_retune_timer_stop(host->mmc);
+	mmc_retune_needed(host->mmc);
 
 	if (!device_may_wakeup(mmc_dev(host->mmc))) {
 		host->ier = 0;
@@ -2782,10 +2714,6 @@ int sdhci_resume_host(struct sdhci_host *host)
 
 	sdhci_enable_card_detection(host);
 
-	/* Set the re-tuning expiration flag */
-	if (host->flags & SDHCI_USING_RETUNING_TIMER)
-		host->flags |= SDHCI_NEEDS_RETUNING;
-
 	return ret;
 }
 
@@ -2822,11 +2750,8 @@ int sdhci_runtime_suspend_host(struct sdhci_host *host)
 {
 	unsigned long flags;
 
-	/* Disable tuning since we are suspending */
-	if (host->flags & SDHCI_USING_RETUNING_TIMER) {
-		del_timer_sync(&host->tuning_timer);
-		host->flags &= ~SDHCI_NEEDS_RETUNING;
-	}
+	mmc_retune_timer_stop(host->mmc);
+	mmc_retune_needed(host->mmc);
 
 	spin_lock_irqsave(&host->lock, flags);
 	host->ier &= SDHCI_INT_CARD_INT;
@@ -2869,10 +2794,6 @@ int sdhci_runtime_resume_host(struct sdhci_host *host)
 		spin_unlock_irqrestore(&host->lock, flags);
 	}
 
-	/* Set the re-tuning expiration flag */
-	if (host->flags & SDHCI_USING_RETUNING_TIMER)
-		host->flags |= SDHCI_NEEDS_RETUNING;
-
 	spin_lock_irqsave(&host->lock, flags);
 
 	host->runtime_suspended = false;
@@ -3408,13 +3329,6 @@ int sdhci_add_host(struct sdhci_host *host)
 
 	init_waitqueue_head(&host->buf_ready_int);
 
-	if (host->version >= SDHCI_SPEC_300) {
-		/* Initialize re-tuning timer */
-		init_timer(&host->tuning_timer);
-		host->tuning_timer.data = (unsigned long)host;
-		host->tuning_timer.function = sdhci_tuning_timer;
-	}
-
 	sdhci_init(host, 0);
 
 	ret = request_threaded_irq(host->irq, sdhci_irq, sdhci_thread_irq,
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index e639b7f..923ff22 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -432,13 +432,11 @@ struct sdhci_host {
 #define SDHCI_REQ_USE_DMA	(1<<2)	/* Use DMA for this req. */
 #define SDHCI_DEVICE_DEAD	(1<<3)	/* Device unresponsive */
 #define SDHCI_SDR50_NEEDS_TUNING (1<<4)	/* SDR50 needs tuning */
-#define SDHCI_NEEDS_RETUNING	(1<<5)	/* Host needs retuning */
 #define SDHCI_AUTO_CMD12	(1<<6)	/* Auto CMD12 support */
 #define SDHCI_AUTO_CMD23	(1<<7)	/* Auto CMD23 support */
 #define SDHCI_PV_ENABLED	(1<<8)	/* Preset value enabled */
 #define SDHCI_SDIO_IRQ_ENABLED	(1<<9)	/* SDIO irq enabled */
 #define SDHCI_SDR104_NEEDS_TUNING (1<<10)	/* SDR104/HS200 needs tuning */
-#define SDHCI_USING_RETUNING_TIMER (1<<11)	/* Host is using a retuning timer for the card */
 #define SDHCI_USE_64_BIT_DMA	(1<<12)	/* Use 64-bit DMA */
 #define SDHCI_HS400_TUNING	(1<<13)	/* Tuning for HS400 */
 
@@ -504,7 +502,6 @@ struct sdhci_host {
 	unsigned int		tuning_count;	/* Timer count for re-tuning */
 	unsigned int		tuning_mode;	/* Re-tuning mode supported by host */
 #define SDHCI_TUNING_MODE_1	0
-	struct timer_list	tuning_timer;	/* Timer for tuning */
 
 	struct sdhci_host_next	next_data;
 	unsigned long private[0] ____cacheline_aligned;
-- 
1.9.1


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

* [PATCH V7 11/14] mmc: core: Flag re-tuning is needed on CRC errors
  2015-05-07 10:10 [PATCH V7 00/14] mmc: host: Add facility to support re-tuning Adrian Hunter
                   ` (9 preceding siblings ...)
  2015-05-07 10:10 ` [PATCH V7 10/14] mmc: sdhci: Change to new way of doing re-tuning Adrian Hunter
@ 2015-05-07 10:10 ` Adrian Hunter
  2015-05-07 10:10 ` [PATCH V7 12/14] mmc: block: Check re-tuning in the recovery path Adrian Hunter
                   ` (3 subsequent siblings)
  14 siblings, 0 replies; 17+ messages in thread
From: Adrian Hunter @ 2015-05-07 10:10 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: linux-mmc, Aaron Lu, Philip Rakity, Al Cooper, Arend van Spriel

CRC errors could possibly be alleviated by
re-tuning so flag re-tuning needed in those cases.
Note this has no effect if re-tuning has not been
enabled.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 drivers/mmc/core/core.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index adb6408..c93062b 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -133,6 +133,12 @@ void mmc_request_done(struct mmc_host *host, struct mmc_request *mrq)
 	struct mmc_command *cmd = mrq->cmd;
 	int err = cmd->error;
 
+	/* Flag re-tuning needed on CRC errors */
+	if (err == -EILSEQ || (mrq->sbc && mrq->sbc->error == -EILSEQ) ||
+	    (mrq->data && mrq->data->error == -EILSEQ) ||
+	    (mrq->stop && mrq->stop->error == -EILSEQ))
+		mmc_retune_needed(host);
+
 	if (err && cmd->retries && mmc_host_is_spi(host)) {
 		if (cmd->resp[0] & R1_SPI_ILLEGAL_COMMAND)
 			cmd->retries = 0;
-- 
1.9.1


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

* [PATCH V7 12/14] mmc: block: Check re-tuning in the recovery path
  2015-05-07 10:10 [PATCH V7 00/14] mmc: host: Add facility to support re-tuning Adrian Hunter
                   ` (10 preceding siblings ...)
  2015-05-07 10:10 ` [PATCH V7 11/14] mmc: core: Flag re-tuning is needed on CRC errors Adrian Hunter
@ 2015-05-07 10:10 ` Adrian Hunter
  2015-05-07 10:10 ` [PATCH V7 13/14] mmc: block: Retry errored data requests when re-tuning is needed Adrian Hunter
                   ` (2 subsequent siblings)
  14 siblings, 0 replies; 17+ messages in thread
From: Adrian Hunter @ 2015-05-07 10:10 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: linux-mmc, Aaron Lu, Philip Rakity, Al Cooper, Arend van Spriel

If re-tuning is needed, do it in the recovery path to
give recovery commands a better chance of success.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 drivers/mmc/card/block.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 2c25271..325ae1e 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -913,6 +913,9 @@ static int mmc_blk_cmd_recovery(struct mmc_card *card, struct request *req,
 		if (!err)
 			break;
 
+		/* Re-tune if needed */
+		mmc_retune_recheck(card->host);
+
 		prev_cmd_status_valid = false;
 		pr_err("%s: error %d sending status command, %sing\n",
 		       req->rq_disk->disk_name, err, retry ? "retry" : "abort");
-- 
1.9.1


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

* [PATCH V7 13/14] mmc: block: Retry errored data requests when re-tuning is needed
  2015-05-07 10:10 [PATCH V7 00/14] mmc: host: Add facility to support re-tuning Adrian Hunter
                   ` (11 preceding siblings ...)
  2015-05-07 10:10 ` [PATCH V7 12/14] mmc: block: Check re-tuning in the recovery path Adrian Hunter
@ 2015-05-07 10:10 ` Adrian Hunter
  2015-05-07 10:10 ` [PATCH V7 14/14] mmc: core: Don't print reset warning if reset is not supported Adrian Hunter
  2015-05-08 11:28 ` [PATCH V7 00/14] mmc: host: Add facility to support re-tuning Ulf Hansson
  14 siblings, 0 replies; 17+ messages in thread
From: Adrian Hunter @ 2015-05-07 10:10 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: linux-mmc, Aaron Lu, Philip Rakity, Al Cooper, Arend van Spriel

Retry errored data requests when re-tuning is needed and
add a flag to struct mmc_blk_request so that the retry
is only done once.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 drivers/mmc/card/block.c | 11 ++++++++++-
 drivers/mmc/card/queue.h |  1 +
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 325ae1e..509fcca 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -1195,6 +1195,7 @@ static int mmc_blk_err_check(struct mmc_card *card,
 						    mmc_active);
 	struct mmc_blk_request *brq = &mq_mrq->brq;
 	struct request *req = mq_mrq->req;
+	int need_retune = card->host->need_retune;
 	int ecc_err = 0, gen_err = 0;
 
 	/*
@@ -1262,6 +1263,12 @@ static int mmc_blk_err_check(struct mmc_card *card,
 	}
 
 	if (brq->data.error) {
+		if (need_retune && !brq->retune_retry_done) {
+			pr_info("%s: retrying because a re-tune was needed\n",
+				req->rq_disk->disk_name);
+			brq->retune_retry_done = 1;
+			return MMC_BLK_RETRY;
+		}
 		pr_err("%s: error %d transferring data, sector %u, nr %u, cmd response %#x, card status %#x\n",
 		       req->rq_disk->disk_name, brq->data.error,
 		       (unsigned)blk_rq_pos(req),
@@ -1821,7 +1828,7 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc)
 	struct mmc_blk_data *md = mq->data;
 	struct mmc_card *card = md->queue.card;
 	struct mmc_blk_request *brq = &mq->mqrq_cur->brq;
-	int ret = 1, disable_multi = 0, retry = 0, type;
+	int ret = 1, disable_multi = 0, retry = 0, type, retune_retry_done = 0;
 	enum mmc_blk_status status;
 	struct mmc_queue_req *mq_rq;
 	struct request *req = rqc;
@@ -1905,6 +1912,7 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc)
 				break;
 			goto cmd_abort;
 		case MMC_BLK_RETRY:
+			retune_retry_done = brq->retune_retry_done;
 			if (retry++ < 5)
 				break;
 			/* Fall through */
@@ -1967,6 +1975,7 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc)
 				mmc_start_req(card->host,
 						&mq_rq->mmc_active, NULL);
 			}
+			mq_rq->brq.retune_retry_done = retune_retry_done;
 		}
 	} while (ret);
 
diff --git a/drivers/mmc/card/queue.h b/drivers/mmc/card/queue.h
index 5752d50..7e27915 100644
--- a/drivers/mmc/card/queue.h
+++ b/drivers/mmc/card/queue.h
@@ -12,6 +12,7 @@ struct mmc_blk_request {
 	struct mmc_command	cmd;
 	struct mmc_command	stop;
 	struct mmc_data		data;
+	int			retune_retry_done;
 };
 
 enum mmc_packed_type {
-- 
1.9.1


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

* [PATCH V7 14/14] mmc: core: Don't print reset warning if reset is not supported
  2015-05-07 10:10 [PATCH V7 00/14] mmc: host: Add facility to support re-tuning Adrian Hunter
                   ` (12 preceding siblings ...)
  2015-05-07 10:10 ` [PATCH V7 13/14] mmc: block: Retry errored data requests when re-tuning is needed Adrian Hunter
@ 2015-05-07 10:10 ` Adrian Hunter
  2015-05-08 11:28 ` [PATCH V7 00/14] mmc: host: Add facility to support re-tuning Ulf Hansson
  14 siblings, 0 replies; 17+ messages in thread
From: Adrian Hunter @ 2015-05-07 10:10 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: linux-mmc, Aaron Lu, Philip Rakity, Al Cooper, Arend van Spriel

Check the error code for EOPNOTSUPP and do not print
reset warning in that case.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 drivers/mmc/core/core.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index c93062b..8c61ddd 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -2371,7 +2371,8 @@ int mmc_hw_reset(struct mmc_host *host)
 	ret = host->bus_ops->reset(host);
 	mmc_bus_put(host);
 
-	pr_warn("%s: tried to reset card\n", mmc_hostname(host));
+	if (ret != -EOPNOTSUPP)
+		pr_warn("%s: tried to reset card\n", mmc_hostname(host));
 
 	return ret;
 }
-- 
1.9.1


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

* Re: [PATCH V7 00/14] mmc: host: Add facility to support re-tuning
  2015-05-07 10:10 [PATCH V7 00/14] mmc: host: Add facility to support re-tuning Adrian Hunter
                   ` (13 preceding siblings ...)
  2015-05-07 10:10 ` [PATCH V7 14/14] mmc: core: Don't print reset warning if reset is not supported Adrian Hunter
@ 2015-05-08 11:28 ` Ulf Hansson
  2015-05-08 13:09   ` Adrian Hunter
  14 siblings, 1 reply; 17+ messages in thread
From: Ulf Hansson @ 2015-05-08 11:28 UTC (permalink / raw)
  To: Adrian Hunter
  Cc: linux-mmc, Aaron Lu, Philip Rakity, Al Cooper, Arend van Spriel

On 7 May 2015 at 12:10, Adrian Hunter <adrian.hunter@intel.com> wrote:
> Hi
>
> Here is V7 of some patches to move re-tuning support
> out of sdhci and into the core, and add support for HS400
> re-tuning.
>
> Currently sdhci does re-tuning transparently by
> calling sdhci_execute_tuning() from its ->request()
> function.
>
> The problem with HS400 re-tuning is that it must be
> done in HS200 mode. That means using switch commands
> and making ios changes. That means it potentially
> conflicts with other command sequences. The new
> re-tuning support accomodates that.
>
> Changes in V7:
>
>     mmc: host: Add facility to support re-tuning
>         Remove unused mmc_retune_not_needed()
>
>     mmc: core: Enable / disable re-tuning
>         As already sent separately as V7:
>         Also flag re-tune needed in SDIO 'keep_power'
>         case, when a re-tuning timer is being used.
>
>     mmc: core: Add support for re-tuning before each request
>         Fold in next patch
>
>     mmc: core: Check re-tuning before retrying
>         Folded into previous patch
>
>     mmc: mmc: Hold re-tuning if the card is put to sleep
>         Change title to:
>     mmc: mmc: Hold re-tuning in mmc_sleep()
>         Remove changes from V6
>         Hold re-tuning while card is deselected
>
>     mmc: core: Flag re-tuning is needed on CRC errors
>         Do it from core rather than the host
>
> Changes in V6:
>
>     mmc: host: Add facility to support re-tuning
>         Don't export functions only used in core
>
>     mmc: core: Enable / disable re-tuning
>         Ensure re-tuning timer is disabled in SDIO suspend
>
>     mmc: core: Hold re-tuning while bkops ongoing
>         Hold re-tuning always and release only if
>         bkops is not ongoing.
>
>     mmc: mmc: Hold re-tuning if the card is put to sleep
>         Hold re-tuning for mmc_sleep even if card is
>         immediately powered off, disabling re-tuning.
>
> Changes in V5:
>
>     mmc: host: Add facility to support re-tuning
>         Make mmc_retune_enable() / mmc_retune_disable()
>         only called from core.
>
>     mmc: core: Enable / disable re-tuning
>         Replaces mmc: core: Disable re-tuning when card is no longer initialized
>         Enables re-tuning when tuning is executed
>
>     mmc: sdhci: Change to new way of doing re-tuning
>         Set host->retune_period instead of enabling re-tuning.
>
> Changes in V4:
>
>     These patches now depend on Ulf's patch:
>         mmc: core: Enable runtime PM management of host devices
>
>     mmc: host: Add facility to support re-tuning
>
>         Assume mmc_claim_host() runtime resumes the host
>         controller so there are no races with runtime pm.
>         Consequently remove now un-needed re-tuning host
>         operations.
>
>     mmc: core: Add support for re-tuning before each request
>
>         Call mmc_retune() prior to ->request()
>
>     mmc: sdhci: Change to new way of doing re-tuning
>
>         Updated to reflect the changes above.
>
> Changes in V3:
>
>     mmc: host: Add facility to support re-tuning
>
>         Add host->retune_now flag so re-tuning can be
>         started in the host drivers ->request()
>         function to avoid racing with Runtime PM.
>
>         Add host operations to let the host know when
>         re-tuning is held, for eaxmple, to enable
>         synchronization with runtime suspend / resume.
>
>         Ensure functions are exported.
>
>     mmc: core: Add support for re-tuning before each request
>         Updated to reflect the change above.
>
>     mmc: core: Check re-tuning before retrying
>         Updated to reflect the change above.
>
>     mmc: core: Hold re-tuning during switch commands
>         Updated to reflect the change above.
>
>     mmc: core: Hold re-tuning during erase commands
>         Updated to reflect the change above.
>
>     mmc: core: Hold re-tuning while bkops ongoing
>         Updated to reflect the change above.
>
>     mmc: core: Add support for HS400 re-tuning
>         Updated and as already sent separately as V3:
>         Remember to mmc_set_bus_speed(card) in mmc_hs400_to_hs200()
>
>     mmc: sdhci: Change to new way of doing re-tuning
>         Call mmc_retune() from ->request() function to
>         avoid racing with Runtime PM. And implement
>         hold_tuning / release_tuning operations to prevent
>         runtime suspend while re-tuning is held.
>
>     mmc: block: Retry errored data requests when re-tuning is needed
>         Updated and as already sent separately as V3:
>         Only retry when there is an error
>
> Changes in V2:
>
>     Added support to the block driver for re-tuning
>     and retrying after a CRC error. The host driver
>     is left to decide when an error indicates re-tuning
>     is needed. The block driver will retry a data request
>     once if re-tuning is flagged as needed.
>
>     SDIO drivers need not be aware of re-tuning because
>     retrying will anyway cause re-tuning when re-tuning
>     is flagged as needed. Nevertheless SDIO drivers could
>     use the need_retune flag to instigate a retry when
>     otherwise they might not have.
>
>     mmc: core: Simplify by adding mmc_execute_tuning()
>         Dropped because it has been applied
>
>     mmc: host: Add facility to support re-tuning
>         Renamed mmc_retune_retry() to mmc_retune_recheck()
>         to better reflect what it does.
>
>     mmc: core: Move mmc_card_removed() into mmc_start_request()
>         Dropped because it has been applied
>
>     mmc: core: Add support for re-tuning before each request
>         Fixed un-balanced re-tune hold / release
>
>     mmc: sdhci: Always init buf_ready_int
>         Dropped because it has been applied
>
>     mmc: core: Separate out the mmc_switch status check so it can be re-used
>         New patch
>
>     mmc: core: Add support for HS400 re-tuning
>         It was found that that the original code was not reliable
>         after a CRC error. The problem was that the CMD13 after a
>         switch was faiing. So the code was changed to check the
>         switch status *after* changing the I/O state to match the
>         switch i.e. the new I/O state is the correct one to use
>         after a switch.
>
>     mmc: sdhci: Flag re-tuning is needed on CRC or End-Bit errors
>         New patch
>
>     mmc: block: Check re-tuning in the recovery path
>         New patch
>
>     mmc: block: Retry data requests when re-tuning is needed
>         New patch
>
>     mmc: core: Don't print reset warning if reset is not supported
>         New patch
>
>
> Adrian Hunter (14):
>       mmc: host: Add facility to support re-tuning
>       mmc: core: Enable / disable re-tuning
>       mmc: core: Add support for re-tuning before each request
>       mmc: core: Hold re-tuning during switch commands
>       mmc: core: Hold re-tuning during erase commands
>       mmc: core: Hold re-tuning while bkops ongoing
>       mmc: mmc: Hold re-tuning in mmc_sleep()
>       mmc: core: Separate out the mmc_switch status check so it can be re-used
>       mmc: core: Add support for HS400 re-tuning
>       mmc: sdhci: Change to new way of doing re-tuning
>       mmc: core: Flag re-tuning is needed on CRC errors
>       mmc: block: Check re-tuning in the recovery path
>       mmc: block: Retry errored data requests when re-tuning is needed
>       mmc: core: Don't print reset warning if reset is not supported
>
>  drivers/mmc/card/block.c   |  14 +++++-
>  drivers/mmc/card/queue.h   |   1 +
>  drivers/mmc/core/core.c    |  57 +++++++++++++++++++----
>  drivers/mmc/core/core.h    |   2 +
>  drivers/mmc/core/host.c    |  85 ++++++++++++++++++++++++++++++++++
>  drivers/mmc/core/host.h    |   6 +++
>  drivers/mmc/core/mmc.c     |  98 ++++++++++++++++++++++++++++++++++++++-
>  drivers/mmc/core/mmc_ops.c |  44 +++++++++++-------
>  drivers/mmc/core/mmc_ops.h |   1 +
>  drivers/mmc/core/sdio.c    |   6 ++-
>  drivers/mmc/host/sdhci.c   | 112 ++++++---------------------------------------
>  drivers/mmc/host/sdhci.h   |   3 --
>  include/linux/mmc/host.h   |  23 ++++++++++
>  13 files changed, 322 insertions(+), 130 deletions(-)
>
>
> Regards
> Adrian
>

Adrian, thanks for all your efforts around this patchset. I have now
applied for my next branch.

Kind regards
Uffe

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

* Re: [PATCH V7 00/14] mmc: host: Add facility to support re-tuning
  2015-05-08 11:28 ` [PATCH V7 00/14] mmc: host: Add facility to support re-tuning Ulf Hansson
@ 2015-05-08 13:09   ` Adrian Hunter
  0 siblings, 0 replies; 17+ messages in thread
From: Adrian Hunter @ 2015-05-08 13:09 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: linux-mmc, Aaron Lu, Philip Rakity, Al Cooper, Arend van Spriel

On 08/05/15 14:28, Ulf Hansson wrote:
> On 7 May 2015 at 12:10, Adrian Hunter <adrian.hunter@intel.com> wrote:
>> Hi
>>
>> Here is V7 of some patches to move re-tuning support
>> out of sdhci and into the core, and add support for HS400
>> re-tuning.
>>
> 
> Adrian, thanks for all your efforts around this patchset. I have now
> applied for my next branch.

Thank you! :-)


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

end of thread, other threads:[~2015-05-08 13:12 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-05-07 10:10 [PATCH V7 00/14] mmc: host: Add facility to support re-tuning Adrian Hunter
2015-05-07 10:10 ` [PATCH V7 01/14] " Adrian Hunter
2015-05-07 10:10 ` [PATCH V7 02/14] mmc: core: Enable / disable re-tuning Adrian Hunter
2015-05-07 10:10 ` [PATCH V7 03/14] mmc: core: Add support for re-tuning before each request Adrian Hunter
2015-05-07 10:10 ` [PATCH V7 04/14] mmc: core: Hold re-tuning during switch commands Adrian Hunter
2015-05-07 10:10 ` [PATCH V7 05/14] mmc: core: Hold re-tuning during erase commands Adrian Hunter
2015-05-07 10:10 ` [PATCH V7 06/14] mmc: core: Hold re-tuning while bkops ongoing Adrian Hunter
2015-05-07 10:10 ` [PATCH V7 07/14] mmc: mmc: Hold re-tuning in mmc_sleep() Adrian Hunter
2015-05-07 10:10 ` [PATCH V7 08/14] mmc: core: Separate out the mmc_switch status check so it can be re-used Adrian Hunter
2015-05-07 10:10 ` [PATCH V7 09/14] mmc: core: Add support for HS400 re-tuning Adrian Hunter
2015-05-07 10:10 ` [PATCH V7 10/14] mmc: sdhci: Change to new way of doing re-tuning Adrian Hunter
2015-05-07 10:10 ` [PATCH V7 11/14] mmc: core: Flag re-tuning is needed on CRC errors Adrian Hunter
2015-05-07 10:10 ` [PATCH V7 12/14] mmc: block: Check re-tuning in the recovery path Adrian Hunter
2015-05-07 10:10 ` [PATCH V7 13/14] mmc: block: Retry errored data requests when re-tuning is needed Adrian Hunter
2015-05-07 10:10 ` [PATCH V7 14/14] mmc: core: Don't print reset warning if reset is not supported Adrian Hunter
2015-05-08 11:28 ` [PATCH V7 00/14] mmc: host: Add facility to support re-tuning Ulf Hansson
2015-05-08 13:09   ` Adrian Hunter

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox