diff options
author | Per Forlin <per.forlin@linaro.org> | 2011-07-01 12:55:22 -0400 |
---|---|---|
committer | Chris Ball <cjb@laptop.org> | 2011-07-20 17:21:10 -0400 |
commit | aa8b683a7d392271ed349c6ab9f36b8c313794b7 (patch) | |
tree | 82c97c089844a03492be55968c1d3cc993aaafa6 /include/linux/mmc | |
parent | 0500f10cc2d624034f350edae2529975c0f1c1f8 (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.h | 6 | ||||
-rw-r--r-- | include/linux/mmc/host.h | 21 |
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 | ||
122 | struct mmc_request { | 123 | struct 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 | ||
132 | struct mmc_host; | 133 | struct mmc_host; |
133 | struct mmc_card; | 134 | struct mmc_card; |
135 | struct mmc_async_req; | ||
134 | 136 | ||
137 | extern struct mmc_async_req *mmc_start_req(struct mmc_host *, | ||
138 | struct mmc_async_req *, int *); | ||
135 | extern void mmc_wait_for_req(struct mmc_host *, struct mmc_request *); | 139 | extern void mmc_wait_for_req(struct mmc_host *, struct mmc_request *); |
136 | extern int mmc_wait_for_cmd(struct mmc_host *, struct mmc_command *, int); | 140 | extern int mmc_wait_for_cmd(struct mmc_host *, struct mmc_command *, int); |
137 | extern int mmc_app_cmd(struct mmc_host *, struct mmc_card *); | 141 | extern 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 { | |||
144 | struct mmc_card; | 153 | struct mmc_card; |
145 | struct device; | 154 | struct device; |
146 | 155 | ||
156 | struct 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 | |||
147 | struct mmc_host { | 166 | struct 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 | ||