From: Alan Cox <alan@linux.intel.com>
To: linux-mmc@vger.kernel.org, cjb@laptop.org
Subject: [PATCH 4/7] mmc: serialization support
Date: Mon, 13 Sep 2010 18:39:32 +0100 [thread overview]
Message-ID: <20100913173920.20345.36169.stgit@localhost.localdomain> (raw)
In-Reply-To: <20100913172738.20345.61119.stgit@localhost.localdomain>
Some hardware has restrictions that require only one command is outstanding
per controller or some other similar restriction.
Provide optional serialization support and enable it for the Intel MID
platform devices with this restriction. Split up from some existing patches
by JiebingLi.
Signed-off-by: JiebingLi <jiebing.li@intel.com>
Signed-off-by: Alan Cox <alan@linux.intel.com>
---
drivers/mmc/core/core.c | 30 ++++++++++++++++++++++++++----
drivers/mmc/host/sdhci-intel-mid.c | 33 ++++++++++++++++++++-------------
drivers/mmc/host/sdhci-pci.c | 2 ++
drivers/mmc/host/sdhci.c | 18 ++++++++++++++++++
drivers/mmc/host/sdhci.h | 1 +
include/linux/mmc/core.h | 1 +
include/linux/mmc/host.h | 3 +++
7 files changed, 71 insertions(+), 17 deletions(-)
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 5db49b1..b2abb68 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -202,11 +202,14 @@ static void mmc_wait_done(struct mmc_request *mrq)
* @host: MMC host to start command
* @mrq: MMC request to start
*
- * Start a new MMC custom command request for a host, and wait
- * for the command to complete. Does not attempt to parse the
- * response.
+ * Implementation hander for starting a new MMC custom command request
+ * for a host, and wait for the command to complete. Does not attempt to
+ * parse the response.
+ *
+ * We provide this separately and export it so that it can be wrapped
+ * by callers who need serialization or have other issue constraints
*/
-void mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq)
+void mmc_do_wait_for_req(struct mmc_host *host, struct mmc_request *mrq)
{
DECLARE_COMPLETION_ONSTACK(complete);
@@ -218,6 +221,25 @@ void mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq)
wait_for_completion(&complete);
}
+EXPORT_SYMBOL(mmc_do_wait_for_req);
+
+/**
+ * mmc_wait_for_req - start a request and wait for completion
+ * @host: MMC host to start command
+ * @mrq: MMC request to start
+ *
+ * Start a new MMC custom command request for a host, and wait
+ * for the command to complete. Does not attempt to parse the
+ * response.
+ */
+void mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq)
+{
+ if (host->ops->wait_for_req)
+ host->ops->wait_for_req(host, mrq);
+ else
+ return mmc_do_wait_for_req(host, mrq);
+}
+
EXPORT_SYMBOL(mmc_wait_for_req);
/**
diff --git a/drivers/mmc/host/sdhci-intel-mid.c b/drivers/mmc/host/sdhci-intel-mid.c
index 2828831..436ee46 100644
--- a/drivers/mmc/host/sdhci-intel-mid.c
+++ b/drivers/mmc/host/sdhci-intel-mid.c
@@ -18,20 +18,27 @@
* that keeps them out of the main flow. We can't just make it a new
* driver as the shdci core code isn't really a library.
*/
-
+
+/*
+ * Support serialization
+ */
+
+static DEFINE_MUTEX(port_mutex);
+
+static void sdhci_intel_wait_req(struct sdhci_host *host,
+ struct mmc_request *mrq)
+{
+ mutex_lock(&port_mutex);
+ mmc_do_wait_for_req(host->mmc, mrq);
+ mutex_unlock(&port_mutex);
+}
+
+/*
+ * Handle the Moorestown reset
+ */
static void sdhci_broken_reset(struct sdhci_host *host, u8 mask)
{
unsigned long timeout;
- u32 uninitialized_var(ier);
-
- if (host->quirks & SDHCI_QUIRK_NO_CARD_NO_RESET) {
- if (!(sdhci_readl(host, SDHCI_PRESENT_STATE) &
- SDHCI_CARD_PRESENT))
- return;
- }
-
- if (host->quirks & SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET)
- ier = sdhci_readl(host, SDHCI_INT_ENABLE);
sdhci_writeb(host, mask, SDHCI_SOFTWARE_RESET);
@@ -46,12 +53,11 @@ static void sdhci_broken_reset(struct sdhci_host *host, u8 mask)
if (timeout == 0) {
printk(KERN_ERR "%s: Reset 0x%x never completed.\n",
mmc_hostname(host->mmc), (int)mask);
+ return;
}
timeout--;
mdelay(1);
}
- if (host->quirks & SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET)
- sdhci_clear_set_irqs(host, SDHCI_INT_ALL_MASK, ier);
}
static void sdhci_mid_broken_resetall(struct sdhci_host *host, int down)
@@ -156,6 +162,7 @@ struct sdhci_ops sdhci_intel_mrst_hc = {
.set_ios = sdhci_lnw_a3_set_ios,
.reset_all = sdhci_mid_broken_resetall,
.write_command = sdhci_clockreset_wcmd,
+ .wait_for_req = sdhci_intel_wait_req,
.unexpected_cmd_irq = sdhci_lnw_a3_unexpected_cmd,
};
EXPORT_SYMBOL_GPL(sdhci_intel_mrst_hc);
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c
index 1324369..bb14047 100644
--- a/drivers/mmc/host/sdhci-pci.c
+++ b/drivers/mmc/host/sdhci-pci.c
@@ -55,6 +55,8 @@ struct sdhci_pci_fixes {
pm_message_t);
int (*resume)(struct sdhci_pci_chip*);
+ /* Allow the driver to override some operations for particularly
+ quirky chips */
struct sdhci_ops *host_ops;
};
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 9d8091a..9d8047c 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1268,6 +1268,12 @@ out:
spin_unlock_irqrestore(&host->lock, flags);
}
+static void sdhci_wait_for_req(struct mmc_host *mmc, struct mmc_request *mrq)
+{
+ struct sdhci_host *host = mmc_priv(mmc);
+ host->ops->wait_for_req(host, mrq);
+}
+
static const struct mmc_host_ops sdhci_ops = {
.request = sdhci_request,
.set_ios = sdhci_set_ios,
@@ -1275,6 +1281,16 @@ static const struct mmc_host_ops sdhci_ops = {
.enable_sdio_irq = sdhci_enable_sdio_irq,
};
+/* Operations struct we use if the controller has an sdhci level
+ ops->wait_for_req */
+static const struct mmc_host_ops sdhci_ops_wait = {
+ .request = sdhci_request,
+ .set_ios = sdhci_set_ios,
+ .get_ro = sdhci_get_ro,
+ .enable_sdio_irq = sdhci_enable_sdio_irq,
+ .wait_for_req = sdhci_wait_for_req,
+};
+
/*****************************************************************************\
* *
* Tasklets *
@@ -1839,6 +1855,8 @@ int sdhci_add_host(struct sdhci_host *host)
* Set host parameters.
*/
mmc->ops = &sdhci_ops;
+ if (host->ops->wait_for_req)
+ mmc->ops = &sdhci_ops_wait;
if (host->ops->get_min_clock)
mmc->f_min = host->ops->get_min_clock(host);
else
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 182fcc3..7c934bd 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -334,6 +334,7 @@ struct sdhci_ops {
struct mmc_ios *ios, u8 ctrl);
void (*set_caps)(struct sdhci_host *host);
void (*unexpected_cmd_irq)(struct sdhci_host *host, u32 intmask);
+ void (*wait_for_req)(struct sdhci_host *host, struct mmc_request *mrq);
};
#ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS
diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h
index 7429033..6eaf5dd 100644
--- a/include/linux/mmc/core.h
+++ b/include/linux/mmc/core.h
@@ -132,6 +132,7 @@ struct mmc_host;
struct mmc_card;
extern void mmc_wait_for_req(struct mmc_host *, struct mmc_request *);
+extern void mmc_do_wait_for_req(struct mmc_host *, struct mmc_request *);
extern int mmc_wait_for_cmd(struct mmc_host *, struct mmc_command *, int);
extern int mmc_wait_for_app_cmd(struct mmc_host *, struct mmc_card *,
struct mmc_command *, int);
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index ded4017..1b0e162 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -111,6 +111,9 @@ struct mmc_host_ops {
/* optional callback for HC quirks */
void (*init_card)(struct mmc_host *host, struct mmc_card *card);
+ /* optional callback for serialization */
+ void (*wait_for_req)(struct mmc_host *host,
+ struct mmc_request *mrq);
};
struct mmc_card;
next prev parent reply other threads:[~2010-09-13 18:24 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-09-13 17:38 [PATCH 0/7] Intel MID SDHCI support (take two) Alan Cox
2010-09-13 17:38 ` [PATCH 1/7] sdhci: Rework some of the quirk behaviour Alan Cox
2010-09-14 14:34 ` Wolfram Sang
2010-09-14 14:20 ` Alan Cox
2010-09-13 17:39 ` [PATCH 2/7] sdhci: Allow the probe handler to override slots Alan Cox
2010-09-13 17:39 ` [PATCH 3/7] sdhci: Intel Medfield support Alan Cox
2010-09-13 17:39 ` Alan Cox [this message]
2010-09-13 17:39 ` [PATCH 5/7] sdhci: Tidy up spaces in sdhci_intel_mid Alan Cox
2010-09-14 14:21 ` Wolfram Sang
2010-09-14 13:40 ` Alan Cox
2010-09-14 14:45 ` Wolfram Sang
2010-09-14 14:21 ` Alan Cox
2010-09-14 16:57 ` Chris Ball
2010-09-14 16:41 ` Alan Cox
2010-09-14 20:00 ` Wolfram Sang
2010-09-13 17:39 ` [PATCH 6/7] sdhci_pci: Tidy this as well Alan Cox
2010-09-13 17:39 ` [PATCH 7/7] sdhci: Tidy up sdhci.c Alan Cox
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=20100913173920.20345.36169.stgit@localhost.localdomain \
--to=alan@linux.intel.com \
--cc=cjb@laptop.org \
--cc=linux-mmc@vger.kernel.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox