linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
From: shawn.guo@linaro.org (Shawn Guo)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v2] mmc: mxs-mmc: add support for pre_req and post_req
Date: Wed, 20 Apr 2011 21:51:56 +0800	[thread overview]
Message-ID: <1303307516-1549-1-git-send-email-shawn.guo@linaro.org> (raw)
In-Reply-To: <1303058010-30256-1-git-send-email-shawn.guo@linaro.org>

pre_req() runs dma_map_sg() post_req() runs dma_unmap_sg.
If not calling pre_req() before mxs_mmc_request(), request()
will prepare the cache just like it did it before.
It is optional to use pre_req() and post_req().

Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
---
Changes since v1:
* Get dma_unmap_sg() call in mxs_mmc_request_done() non-blocking

 drivers/mmc/host/mxs-mmc.c |   81 +++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 76 insertions(+), 5 deletions(-)

diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c
index 99d39a6..235acfa 100644
--- a/drivers/mmc/host/mxs-mmc.c
+++ b/drivers/mmc/host/mxs-mmc.c
@@ -137,6 +137,10 @@
 
 #define SSP_PIO_NUM	3
 
+struct mxs_mmc_next {
+	s32 cookie;
+};
+
 struct mxs_mmc_host {
 	struct mmc_host			*mmc;
 	struct mmc_request		*mrq;
@@ -154,6 +158,7 @@ struct mxs_mmc_host {
 	struct mxs_dma_data		dma_data;
 	unsigned int			dma_dir;
 	u32				ssp_pio_words[SSP_PIO_NUM];
+	struct mxs_mmc_next		next_data;
 
 	unsigned int			version;
 	unsigned char			bus_width;
@@ -236,8 +241,10 @@ static void mxs_mmc_request_done(struct mxs_mmc_host *host)
 	}
 
 	if (data) {
-		dma_unmap_sg(mmc_dev(host->mmc), data->sg,
-			     data->sg_len, host->dma_dir);
+		if (!data->host_cookie)
+			dma_unmap_sg(mmc_dev(host->mmc), data->sg,
+				     data->sg_len, host->dma_dir);
+
 		/*
 		 * If there was an error on any block, we mark all
 		 * data blocks as being in error.
@@ -302,6 +309,31 @@ static irqreturn_t mxs_mmc_irq_handler(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
+static int mxs_mmc_prep_dma_data(struct mxs_mmc_host *host,
+				struct mmc_data *data,
+				struct mxs_mmc_next *next)
+{
+	if (!next && data->host_cookie &&
+	    data->host_cookie != host->next_data.cookie) {
+		printk(KERN_WARNING "[%s] invalid cookie: data->host_cookie %d"
+		       " host->next_data.cookie %d\n",
+		       __func__, data->host_cookie, host->next_data.cookie);
+		data->host_cookie = 0;
+	}
+
+	/* Check if next job is already prepared */
+	if (next || (!next && data->host_cookie != host->next_data.cookie))
+		if (dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len,
+			       (data->flags & MMC_DATA_WRITE) ?
+			       DMA_TO_DEVICE : DMA_FROM_DEVICE) == 0)
+			return -EINVAL;
+
+	if (next)
+		data->host_cookie = ++next->cookie < 0 ? 1 : next->cookie;
+
+	return 0;
+}
+
 static struct dma_async_tx_descriptor *mxs_mmc_prep_dma(
 	struct mxs_mmc_host *host, unsigned int append)
 {
@@ -312,8 +344,8 @@ static struct dma_async_tx_descriptor *mxs_mmc_prep_dma(
 
 	if (data) {
 		/* data */
-		dma_map_sg(mmc_dev(host->mmc), data->sg,
-			   data->sg_len, host->dma_dir);
+		if (mxs_mmc_prep_dma_data(host, data, NULL))
+			return NULL;
 		sgl = data->sg;
 		sg_len = data->sg_len;
 	} else {
@@ -328,9 +360,11 @@ static struct dma_async_tx_descriptor *mxs_mmc_prep_dma(
 		desc->callback = mxs_mmc_dma_irq_callback;
 		desc->callback_param = host;
 	} else {
-		if (data)
+		if (data) {
 			dma_unmap_sg(mmc_dev(host->mmc), data->sg,
 				     data->sg_len, host->dma_dir);
+			data->host_cookie = 0;
+		}
 	}
 
 	return desc;
@@ -553,6 +587,40 @@ static void mxs_mmc_start_cmd(struct mxs_mmc_host *host,
 	}
 }
 
+static void mxs_mmc_pre_req(struct mmc_host *mmc, struct mmc_request *mrq,
+			    bool is_first_req)
+{
+	struct mxs_mmc_host *host = mmc_priv(mmc);
+	struct mmc_data *data = mrq->data;
+
+	if (!data)
+		return;
+
+	if (data->host_cookie) {
+		data->host_cookie = 0;
+		return;
+	}
+
+	if (mxs_mmc_prep_dma_data(host, data, &host->next_data))
+		data->host_cookie = 0;
+}
+
+static void mxs_mmc_post_req(struct mmc_host *mmc, struct mmc_request *mrq,
+			     int err)
+{
+	struct mxs_mmc_host *host = mmc_priv(mmc);
+	struct mmc_data *data = mrq->data;
+
+	if (!data)
+		return;
+
+	if (data->host_cookie) {
+		dma_unmap_sg(mmc_dev(host->mmc), data->sg,
+			     data->sg_len, host->dma_dir);
+		data->host_cookie = 0;
+	}
+}
+
 static void mxs_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
 {
 	struct mxs_mmc_host *host = mmc_priv(mmc);
@@ -644,6 +712,8 @@ static void mxs_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable)
 }
 
 static const struct mmc_host_ops mxs_mmc_ops = {
+	.pre_req = mxs_mmc_pre_req,
+	.post_req = mxs_mmc_post_req,
 	.request = mxs_mmc_request,
 	.get_ro = mxs_mmc_get_ro,
 	.get_cd = mxs_mmc_get_cd,
@@ -708,6 +778,7 @@ static int mxs_mmc_probe(struct platform_device *pdev)
 	host->dma_res = dmares;
 	host->irq = irq_err;
 	host->sdio_irq_en = 0;
+	host->next_data.cookie = 1;
 
 	host->clk = clk_get(&pdev->dev, NULL);
 	if (IS_ERR(host->clk)) {
-- 
1.7.4.1

      parent reply	other threads:[~2011-04-20 13:51 UTC|newest]

Thread overview: 56+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-04-06 19:07 [PATCH v2 00/12] mmc: use nonblock mmc requests to minimize latency Per Forlin
2011-04-06 19:07 ` [PATCH v2 01/12] mmc: add none blocking mmc request function Per Forlin
2011-04-15 10:34   ` David Vrabel
2011-04-20  7:17     ` Per Forlin
2011-04-26 13:29       ` David Vrabel
2011-04-26 14:22         ` Per Forlin
2011-04-06 19:07 ` [PATCH v2 02/12] mmc: mmc_test: add debugfs file to list all tests Per Forlin
2011-04-06 19:07 ` [PATCH v2 03/12] mmc: mmc_test: add test for none blocking transfers Per Forlin
2011-04-17  7:09   ` Lin Tony-B19295
2011-04-20  7:30     ` Per Forlin
2011-04-17 15:46   ` Shawn Guo
2011-04-20  7:41     ` Per Forlin
2011-04-06 19:07 ` [PATCH v2 04/12] mmc: add member in mmc queue struct to hold request data Per Forlin
2011-04-06 19:07 ` [PATCH v2 05/12] mmc: add a block request prepare function Per Forlin
2011-04-06 19:07 ` [PATCH v2 06/12] mmc: move error code in mmc_block_issue_rw_rq to a separate function Per Forlin
2011-04-06 19:07 ` [PATCH v2 07/12] mmc: add a second mmc queue request member Per Forlin
2011-04-06 19:07 ` [PATCH v2 08/12] mmc: add handling for two parallel block requests in issue_rw_rq Per Forlin
2011-04-20 11:32   ` Per Forlin
2011-04-06 19:07 ` [PATCH v2 09/12] mmc: test: add random fault injection in core.c Per Forlin
2011-04-06 19:07 ` [PATCH v2 10/12] omap_hsmmc: use original sg_len for dma_unmap_sg Per Forlin
2011-04-06 19:07 ` [PATCH v2 11/12] omap_hsmmc: add support for pre_req and post_req Per Forlin
2011-04-06 19:07 ` [PATCH v2 12/12] mmci: implement pre_req() and post_req() Per Forlin
2011-04-08 16:49 ` [PATCH v2 00/12] mmc: use nonblock mmc requests to minimize latency Linus Walleij
2011-04-09 11:55   ` Jae hoon Chung
2011-04-10  3:33     ` anish singh
2011-04-11  9:03       ` Per Forlin
2011-04-11  9:07         ` Sachin Nikam
2011-04-11  9:08     ` Per Forlin
2011-04-19 14:30       ` Jae hoon Chung
2011-04-16 15:48 ` Shawn Guo
2011-04-20  8:19   ` Per Forlin
2011-04-16 16:48 ` [PATCH] mmc: sdhci: add support for pre_req and post_req Shawn Guo
2011-04-16 23:06   ` Andrei Warkentin
2011-04-22 11:01     ` Jaehoon Chung
2011-04-27  0:59       ` Andrei Warkentin
2011-04-26  1:26     ` Jaehoon Chung
2011-04-26  2:47       ` Shawn Guo
2011-04-26 10:21         ` Per Forlin
2011-04-17 16:33 ` [PATCH] mmc: mxs-mmc: " Shawn Guo
2011-04-17 16:48   ` Shawn Guo
2011-04-20  8:01     ` Per Forlin
2011-04-20 14:01       ` Shawn Guo
2011-04-20 15:22         ` Per Forlin
2011-04-21  6:25           ` Shawn Guo
2011-04-21  8:52             ` Per Forlin
2011-04-20 15:30         ` Per Forlin
2011-04-21  6:29           ` Shawn Guo
2011-04-21  8:46             ` Per Forlin
2011-04-21  9:11               ` Shawn Guo
2011-04-21  9:47                 ` Per Forlin
2011-04-21 10:15                   ` Per Forlin
2011-04-28  7:52                   ` Per Forlin
2011-04-28 10:10                     ` Russell King - ARM Linux
2011-04-20  7:58   ` Per Forlin
2011-04-20  8:17     ` Shawn Guo
2011-04-20 13:51   ` Shawn Guo [this message]

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=1303307516-1549-1-git-send-email-shawn.guo@linaro.org \
    --to=shawn.guo@linaro.org \
    --cc=linux-arm-kernel@lists.infradead.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;
as well as URLs for NNTP newsgroup(s).