From: Jaehoon Chung <jh80.chung@samsung.com>
To: "linux-mmc@vger.kernel.org" <linux-mmc@vger.kernel.org>
Cc: Chris Ball <cjb@laptop.org>, Per Forlin <per.forlin@linaro.org>,
will.newton@imgtec.com, Kyungmin Park <kyungmin.park@samsung.com>
Subject: [PATCH] dw_mmc: add support for pre_req and post_req
Date: Thu, 07 Apr 2011 17:04:52 +0900 [thread overview]
Message-ID: <4D9D7024.2030404@samsung.com> (raw)
This patch is based on Per Forlin's patches.
([PATCH v2 00/12]mmc: use nonblock mmc requests to minimize latency)
After applied Per Forlin's patches, this patch must be apply.
In dw_mmc.c, support for pre/post_reqeust().
Signed-off-by: Jaehoon Chung <jh80.chung@samsung.com>
Signed-off-by: kyungmin Park <kyungmin.park@samsung.com>
---
drivers/mmc/host/dw_mmc.c | 84 ++++++++++++++++++++++++++++++++++++++++----
include/linux/mmc/dw_mmc.h | 7 ++++
2 files changed, 84 insertions(+), 7 deletions(-)
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index 87e1f57..67eeb85 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -417,6 +417,42 @@ static int dw_mci_idmac_init(struct dw_mci *host)
return 0;
}
+static unsigned int dw_mci_pre_dma_transfer(struct dw_mci *host,
+ struct mmc_data *data, struct dw_mci_next *next)
+{
+ unsigned int sg_len;
+
+ BUG_ON(next && data->host_cookie);
+ BUG_ON(!next && data->host_cookie &&
+ data->host_cookie != host->next_data.cookie);
+
+ if (!next && data->host_cookie &&
+ data->host_cookie != host->next_data.cookie) {
+ data->host_cookie = 0;
+ }
+
+ if (next ||
+ (!next && data->host_cookie != host->next_data.cookie)) {
+ sg_len = dma_map_sg(&host->pdev->dev, data->sg,
+ data->sg_len, ((data->flags & MMC_DATA_WRITE)
+ ? DMA_TO_DEVICE : DMA_FROM_DEVICE));
+ } else {
+ sg_len = host->next_data.sg_len;
+ host->next_data.sg_len = 0;
+ }
+
+ if (sg_len == 0)
+ return -EINVAL;
+
+ if (next) {
+ next->sg_len = sg_len;
+ data->host_cookie = ++next->cookie < 0 ? 1 : next->cookie;
+ } else
+ data->sg_len = sg_len;
+
+ return sg_len;
+}
+
static struct dw_mci_dma_ops dw_mci_idmac_ops = {
.init = dw_mci_idmac_init,
.start = dw_mci_idmac_start_dma,
@@ -451,13 +487,9 @@ static int dw_mci_submit_data_dma(struct dw_mci *host, struct mmc_data *data)
return -EINVAL;
}
- if (data->flags & MMC_DATA_READ)
- direction = DMA_FROM_DEVICE;
- else
- direction = DMA_TO_DEVICE;
-
- sg_len = dma_map_sg(&host->pdev->dev, data->sg, data->sg_len,
- direction);
+ sg_len = dw_mci_pre_dma_transfer(host, data, NULL);
+ if (sg_len < 0)
+ return sg_len;
dev_vdbg(&host->pdev->dev,
"sd sg_cpu: %#lx sg_dma: %#lx sg_len: %d\n",
@@ -643,6 +675,42 @@ static void dw_mci_queue_request(struct dw_mci *host, struct dw_mci_slot *slot,
spin_unlock_bh(&host->lock);
}
+static void dw_mci_post_request(struct mmc_host *mmc, struct mmc_request *mrq,
+ int err)
+{
+ struct dw_mci_slot *slot = mmc_priv(mmc);
+ struct mmc_data *data = mrq->data;
+
+ if (!data)
+ return;
+
+ if (slot->host->use_dma) {
+ dma_unmap_sg(&slot->host->pdev->dev, data->sg, data->sg_len,
+ ((data->flags & MMC_DATA_WRITE)
+ ? DMA_TO_DEVICE : DMA_FROM_DEVICE));
+
+ data->host_cookie = 0;
+ }
+}
+
+static void dw_mci_pre_request(struct mmc_host *mmc, struct mmc_request *mrq,
+ bool is_first_req)
+{
+ struct dw_mci_slot *slot = mmc_priv(mmc);
+ struct mmc_data *data = mrq->data;
+
+ if (!data)
+ return;
+
+ BUG_ON(mrq->data->host_cookie);
+
+ if (slot->host->use_dma) {
+ if (dw_mci_pre_dma_transfer(slot->host, mrq->data,
+ &slot->host->next_data))
+ mrq->data->host_cookie = 0;
+ }
+}
+
static void dw_mci_request(struct mmc_host *mmc, struct mmc_request *mrq)
{
struct dw_mci_slot *slot = mmc_priv(mmc);
@@ -748,6 +816,8 @@ static int dw_mci_get_cd(struct mmc_host *mmc)
static const struct mmc_host_ops dw_mci_ops = {
.request = dw_mci_request,
+ .pre_req = dw_mci_pre_request,
+ .post_req = dw_mci_post_request,
.set_ios = dw_mci_set_ios,
.get_ro = dw_mci_get_ro,
.get_cd = dw_mci_get_cd,
diff --git a/include/linux/mmc/dw_mmc.h b/include/linux/mmc/dw_mmc.h
index c0207a7..dca82ee 100644
--- a/include/linux/mmc/dw_mmc.h
+++ b/include/linux/mmc/dw_mmc.h
@@ -35,6 +35,11 @@ enum {
struct mmc_data;
+struct dw_mci_next {
+ unsigned int sg_len;
+ s32 cookie;
+};
+
/**
* struct dw_mci - MMC controller state shared between all slots
* @lock: Spinlock protecting the queue and associated data.
@@ -154,6 +159,8 @@ struct dw_mci {
u32 quirks;
struct regulator *vmmc; /* Power regulator */
+
+ struct dw_mci_next next_data;
};
/* DMA ops for Internal/External DMAC interface */
next reply other threads:[~2011-04-07 8:06 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-04-07 8:04 Jaehoon Chung [this message]
2011-04-16 16:16 ` [PATCH] dw_mmc: add support for pre_req and post_req Shawn Guo
2011-04-18 4:55 ` Jaehoon Chung
2011-04-18 5:10 ` Shawn Guo
2011-04-18 5:10 ` Jaehoon Chung
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=4D9D7024.2030404@samsung.com \
--to=jh80.chung@samsung.com \
--cc=cjb@laptop.org \
--cc=kyungmin.park@samsung.com \
--cc=linux-mmc@vger.kernel.org \
--cc=per.forlin@linaro.org \
--cc=will.newton@imgtec.com \
/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.