aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/mmc
diff options
context:
space:
mode:
authorPer Forlin <per.forlin@linaro.org>2011-07-01 12:55:22 -0400
committerChris Ball <cjb@laptop.org>2011-07-20 17:21:10 -0400
commitaa8b683a7d392271ed349c6ab9f36b8c313794b7 (patch)
tree82c97c089844a03492be55968c1d3cc993aaafa6 /include/linux/mmc
parent0500f10cc2d624034f350edae2529975c0f1c1f8 (diff)
mmc: core: add non-blocking mmc request function
Previously there has only been one function mmc_wait_for_req() to start and wait for a request. This patch adds: * mmc_start_req() - starts a request wihtout waiting If there is on ongoing request wait for completion of that request and start the new one and return. Does not wait for the new command to complete. This patch also adds new function members in struct mmc_host_ops only called from core.c: * pre_req - asks the host driver to prepare for the next job * post_req - asks the host driver to clean up after a completed job The intention is to use pre_req() and post_req() to do cache maintenance while a request is active. pre_req() can be called while a request is active to minimize latency to start next job. post_req() can be used after the next job is started to clean up the request. This will minimize the host driver request end latency. post_req() is typically used before ending the block request and handing over the buffer to the block layer. Add a host-private member in mmc_data to be used by pre_req to mark the data. The host driver will then check this mark to see if the data is prepared or not. Signed-off-by: Per Forlin <per.forlin@linaro.org> Acked-by: Kyungmin Park <kyungmin.park@samsung.com> Acked-by: Arnd Bergmann <arnd@arndb.de> Reviewed-by: Venkatraman S <svenkatr@ti.com> Tested-by: Sourav Poddar <sourav.poddar@ti.com> Tested-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Chris Ball <cjb@laptop.org>
Diffstat (limited to 'include/linux/mmc')
-rw-r--r--include/linux/mmc/core.h6
-rw-r--r--include/linux/mmc/host.h21
2 files changed, 26 insertions, 1 deletions
diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h
index 86d81cf75b70..b8b1b7a311f1 100644
--- a/include/linux/mmc/core.h
+++ b/include/linux/mmc/core.h
@@ -117,6 +117,7 @@ struct mmc_data {
117 117
118 unsigned int sg_len; /* size of scatter list */ 118 unsigned int sg_len; /* size of scatter list */
119 struct scatterlist *sg; /* I/O scatter list */ 119 struct scatterlist *sg; /* I/O scatter list */
120 s32 host_cookie; /* host private data */
120}; 121};
121 122
122struct mmc_request { 123struct mmc_request {
@@ -125,13 +126,16 @@ struct mmc_request {
125 struct mmc_data *data; 126 struct mmc_data *data;
126 struct mmc_command *stop; 127 struct mmc_command *stop;
127 128
128 void *done_data; /* completion data */ 129 struct completion completion;
129 void (*done)(struct mmc_request *);/* completion function */ 130 void (*done)(struct mmc_request *);/* completion function */
130}; 131};
131 132
132struct mmc_host; 133struct mmc_host;
133struct mmc_card; 134struct mmc_card;
135struct mmc_async_req;
134 136
137extern struct mmc_async_req *mmc_start_req(struct mmc_host *,
138 struct mmc_async_req *, int *);
135extern void mmc_wait_for_req(struct mmc_host *, struct mmc_request *); 139extern void mmc_wait_for_req(struct mmc_host *, struct mmc_request *);
136extern int mmc_wait_for_cmd(struct mmc_host *, struct mmc_command *, int); 140extern int mmc_wait_for_cmd(struct mmc_host *, struct mmc_command *, int);
137extern int mmc_app_cmd(struct mmc_host *, struct mmc_card *); 141extern int mmc_app_cmd(struct mmc_host *, struct mmc_card *);
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index c67d19b5542a..9f9a4c64cde7 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -106,6 +106,15 @@ struct mmc_host_ops {
106 */ 106 */
107 int (*enable)(struct mmc_host *host); 107 int (*enable)(struct mmc_host *host);
108 int (*disable)(struct mmc_host *host, int lazy); 108 int (*disable)(struct mmc_host *host, int lazy);
109 /*
110 * It is optional for the host to implement pre_req and post_req in
111 * order to support double buffering of requests (prepare one
112 * request while another request is active).
113 */
114 void (*post_req)(struct mmc_host *host, struct mmc_request *req,
115 int err);
116 void (*pre_req)(struct mmc_host *host, struct mmc_request *req,
117 bool is_first_req);
109 void (*request)(struct mmc_host *host, struct mmc_request *req); 118 void (*request)(struct mmc_host *host, struct mmc_request *req);
110 /* 119 /*
111 * Avoid calling these three functions too often or in a "fast path", 120 * Avoid calling these three functions too often or in a "fast path",
@@ -144,6 +153,16 @@ struct mmc_host_ops {
144struct mmc_card; 153struct mmc_card;
145struct device; 154struct device;
146 155
156struct mmc_async_req {
157 /* active mmc request */
158 struct mmc_request *mrq;
159 /*
160 * Check error status of completed mmc request.
161 * Returns 0 if success otherwise non zero.
162 */
163 int (*err_check) (struct mmc_card *, struct mmc_async_req *);
164};
165
147struct mmc_host { 166struct mmc_host {
148 struct device *parent; 167 struct device *parent;
149 struct device class_dev; 168 struct device class_dev;
@@ -282,6 +301,8 @@ struct mmc_host {
282 301
283 struct dentry *debugfs_root; 302 struct dentry *debugfs_root;
284 303
304 struct mmc_async_req *areq; /* active async req */
305
285 unsigned long private[0] ____cacheline_aligned; 306 unsigned long private[0] ____cacheline_aligned;
286}; 307};
287 308