All of lore.kernel.org
 help / color / mirror / Atom feed
From: Adrian Hunter <adrian.hunter@intel.com>
To: Ulf Hansson <ulf.hansson@linaro.org>, Chris Ball <chris@printf.net>
Cc: linux-mmc <linux-mmc@vger.kernel.org>,
	Aaron Lu <aaron.lu@intel.com>, Philip Rakity <prakity@nvidia.com>,
	Girish K S <girish.shivananjappa@linaro.org>,
	Al Cooper <alcooperx@gmail.com>,
	Arend van Spriel <arend@broadcom.com>
Subject: [PATCH V2 01/15] mmc: host: Add facility to support re-tuning
Date: Thu, 29 Jan 2015 11:00:16 +0200	[thread overview]
Message-ID: <1422522030-17793-2-git-send-email-adrian.hunter@intel.com> (raw)
In-Reply-To: <1422522030-17793-1-git-send-email-adrian.hunter@intel.com>

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 5 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 */
  int			need_retune;	/* re-tuning is needed */
  int			hold_retune;	/* hold off re-tuning */
  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  | 46 ++++++++++++++++++++++++++++++++++++++
 include/linux/mmc/host.h | 58 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 104 insertions(+)

diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
index 8be0df7..221d46d 100644
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -301,6 +301,51 @@ static inline void mmc_host_clk_sysfs_init(struct mmc_host *host)
 
 #endif
 
+void mmc_retune_enable(struct mmc_host *host, unsigned int period)
+{
+	host->can_retune = 1;
+	if (period)
+		mod_timer(&host->retune_timer, jiffies + period * HZ);
+}
+
+void mmc_retune_disable(struct mmc_host *host)
+{
+	host->can_retune = 0;
+	del_timer_sync(&host->retune_timer);
+	host->need_retune = 0;
+}
+
+void mmc_retune_timer_stop(struct mmc_host *host)
+{
+	del_timer_sync(&host->retune_timer);
+}
+
+int mmc_retune(struct mmc_host *host)
+{
+	int err;
+
+	if (!host->need_retune || host->doing_retune || host->hold_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 +549,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/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 0c8cbe5..e9a7470 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>
@@ -327,10 +328,16 @@ 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 */
 
 	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 */
+	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 */
@@ -519,4 +526,55 @@ static inline bool mmc_card_hs400(struct mmc_card *card)
 	return card->host->ios.timing == MMC_TIMING_MMC_HS400;
 }
 
+void mmc_retune_enable(struct mmc_host *host, unsigned int period);
+void mmc_retune_disable(struct mmc_host *host);
+void mmc_retune_timer_stop(struct mmc_host *host);
+int mmc_retune(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_not_needed(struct mmc_host *host)
+{
+	host->need_retune = 0;
+}
+
+static inline void mmc_retune_hold(struct mmc_host *host)
+{
+	host->hold_retune += 1;
+}
+
+static inline void mmc_retune_release(struct mmc_host *host)
+{
+	if (host->hold_retune)
+		host->hold_retune -= 1;
+	else
+		WARN_ON(1);
+}
+
+static inline int mmc_retune_and_hold(struct mmc_host *host)
+{
+	int err;
+
+	err = mmc_retune(host);
+	if (!err)
+		mmc_retune_hold(host);
+
+	return err;
+}
+
+static inline int mmc_retune_recheck(struct mmc_host *host)
+{
+	int err;
+
+	mmc_retune_release(host);
+	err = mmc_retune(host);
+	mmc_retune_hold(host);
+
+	return err;
+}
+
 #endif /* LINUX_MMC_HOST_H */
-- 
1.9.1


  reply	other threads:[~2015-01-29  9:02 UTC|newest]

Thread overview: 37+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-01-29  9:00 [PATCH V2 00/15] mmc: host: Add facility to support re-tuning Adrian Hunter
2015-01-29  9:00 ` Adrian Hunter [this message]
2015-01-29  9:00 ` [PATCH V2 02/15] mmc: core: Disable re-tuning when card is no longer initialized Adrian Hunter
2015-01-29  9:00 ` [PATCH V2 03/15] mmc: core: Add support for re-tuning before each request Adrian Hunter
2015-01-29  9:00 ` [PATCH V2 04/15] mmc: core: Check re-tuning before retrying Adrian Hunter
2015-01-29  9:00 ` [PATCH V2 05/15] mmc: core: Hold re-tuning during switch commands Adrian Hunter
2015-01-29  9:00 ` [PATCH V2 06/15] mmc: core: Hold re-tuning during erase commands Adrian Hunter
2015-01-29  9:00 ` [PATCH V2 07/15] mmc: core: Hold re-tuning while bkops ongoing Adrian Hunter
2015-01-29  9:00 ` [PATCH V2 08/15] mmc: mmc: Comment that callers need to hold re-tuning if the card is put to sleep Adrian Hunter
2015-01-29  9:00 ` [PATCH V2 09/15] mmc: core: Separate out the mmc_switch status check so it can be re-used Adrian Hunter
2015-01-29  9:00 ` [PATCH V2 10/15] mmc: core: Add support for HS400 re-tuning Adrian Hunter
2015-02-04 13:35   ` [PATCH V3 " Adrian Hunter
2015-01-29  9:00 ` [PATCH V2 11/15] mmc: sdhci: Change to new way of doing re-tuning Adrian Hunter
2015-03-06 12:51   ` Ulf Hansson
2015-03-09  8:37     ` Adrian Hunter
2015-03-10 13:55       ` Ulf Hansson
2015-03-10 14:20         ` Adrian Hunter
2015-03-23 12:54           ` Ulf Hansson
2015-03-23 14:26             ` Adrian Hunter
2015-03-23 15:02               ` Ulf Hansson
2015-03-23 21:11                 ` Adrian Hunter
2015-03-24 21:12                   ` Ulf Hansson
2015-03-25 13:48                     ` Adrian Hunter
2015-03-26 16:06                       ` Ulf Hansson
2015-03-27  9:54                         ` Adrian Hunter
2015-03-27 12:04                           ` Adrian Hunter
2015-03-24  2:49               ` NeilBrown
2015-03-24  9:40                 ` Ulf Hansson
2015-01-29  9:00 ` [PATCH V2 12/15] mmc: sdhci: Flag re-tuning is needed on CRC or End-Bit errors Adrian Hunter
2015-01-29  9:00 ` [PATCH V2 13/15] mmc: block: Check re-tuning in the recovery path Adrian Hunter
2015-01-29  9:00 ` [PATCH V2 14/15] mmc: block: Retry data requests when re-tuning is needed Adrian Hunter
2015-02-27 12:55   ` [PATCH V3 14/15] mmc: block: Retry errored " Adrian Hunter
2015-01-29  9:00 ` [PATCH V2 15/15] mmc: core: Don't print reset warning if reset is not supported Adrian Hunter
2015-02-09  9:33   ` Arend van Spriel
2015-02-09  9:47     ` Adrian Hunter
2015-02-09 16:05       ` Johan Rudholm
2015-02-09  8:43 ` [PATCH V2 00/15] mmc: host: Add facility to support re-tuning Adrian Hunter

Reply instructions:

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

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

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

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

  git send-email \
    --in-reply-to=1422522030-17793-2-git-send-email-adrian.hunter@intel.com \
    --to=adrian.hunter@intel.com \
    --cc=aaron.lu@intel.com \
    --cc=alcooperx@gmail.com \
    --cc=arend@broadcom.com \
    --cc=chris@printf.net \
    --cc=girish.shivananjappa@linaro.org \
    --cc=linux-mmc@vger.kernel.org \
    --cc=prakity@nvidia.com \
    --cc=ulf.hansson@linaro.org \
    /path/to/YOUR_REPLY

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

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