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
next prev parent 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.