diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-10-09 03:02:35 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-10-09 03:02:35 -0400 |
commit | 1236d6bb6e19fc72ffc6bbcdeb1bfefe450e54ee (patch) | |
tree | 47da3feee8e263e8c9352c85cf518e624be3c211 /drivers/mmc/core | |
parent | 750b1a6894ecc9b178c6e3d0a1170122971b2036 (diff) | |
parent | 8a5776a5f49812d29fe4b2d0a2d71675c3facf3f (diff) |
Merge 4.14-rc4 into staging-next
We want the staging/iio fixes in here as well to handle merge issues.
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/mmc/core')
-rw-r--r-- | drivers/mmc/core/block.c | 3 | ||||
-rw-r--r-- | drivers/mmc/core/mmc.c | 36 | ||||
-rw-r--r-- | drivers/mmc/core/queue.c | 120 | ||||
-rw-r--r-- | drivers/mmc/core/queue.h | 6 |
4 files changed, 28 insertions, 137 deletions
diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c index 29fc1e662891..2ad7b5c69156 100644 --- a/drivers/mmc/core/block.c +++ b/drivers/mmc/core/block.c | |||
@@ -1634,8 +1634,6 @@ static void mmc_blk_data_prep(struct mmc_queue *mq, struct mmc_queue_req *mqrq, | |||
1634 | } | 1634 | } |
1635 | 1635 | ||
1636 | mqrq->areq.mrq = &brq->mrq; | 1636 | mqrq->areq.mrq = &brq->mrq; |
1637 | |||
1638 | mmc_queue_bounce_pre(mqrq); | ||
1639 | } | 1637 | } |
1640 | 1638 | ||
1641 | static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq, | 1639 | static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq, |
@@ -1829,7 +1827,6 @@ static void mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *new_req) | |||
1829 | brq = &mq_rq->brq; | 1827 | brq = &mq_rq->brq; |
1830 | old_req = mmc_queue_req_to_req(mq_rq); | 1828 | old_req = mmc_queue_req_to_req(mq_rq); |
1831 | type = rq_data_dir(old_req) == READ ? MMC_BLK_READ : MMC_BLK_WRITE; | 1829 | type = rq_data_dir(old_req) == READ ? MMC_BLK_READ : MMC_BLK_WRITE; |
1832 | mmc_queue_bounce_post(mq_rq); | ||
1833 | 1830 | ||
1834 | switch (status) { | 1831 | switch (status) { |
1835 | case MMC_BLK_SUCCESS: | 1832 | case MMC_BLK_SUCCESS: |
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index a7eb623f8daa..36217ad5e9b1 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c | |||
@@ -1286,6 +1286,23 @@ out_err: | |||
1286 | return err; | 1286 | return err; |
1287 | } | 1287 | } |
1288 | 1288 | ||
1289 | static void mmc_select_driver_type(struct mmc_card *card) | ||
1290 | { | ||
1291 | int card_drv_type, drive_strength, drv_type; | ||
1292 | |||
1293 | card_drv_type = card->ext_csd.raw_driver_strength | | ||
1294 | mmc_driver_type_mask(0); | ||
1295 | |||
1296 | drive_strength = mmc_select_drive_strength(card, | ||
1297 | card->ext_csd.hs200_max_dtr, | ||
1298 | card_drv_type, &drv_type); | ||
1299 | |||
1300 | card->drive_strength = drive_strength; | ||
1301 | |||
1302 | if (drv_type) | ||
1303 | mmc_set_driver_type(card->host, drv_type); | ||
1304 | } | ||
1305 | |||
1289 | static int mmc_select_hs400es(struct mmc_card *card) | 1306 | static int mmc_select_hs400es(struct mmc_card *card) |
1290 | { | 1307 | { |
1291 | struct mmc_host *host = card->host; | 1308 | struct mmc_host *host = card->host; |
@@ -1341,6 +1358,8 @@ static int mmc_select_hs400es(struct mmc_card *card) | |||
1341 | goto out_err; | 1358 | goto out_err; |
1342 | } | 1359 | } |
1343 | 1360 | ||
1361 | mmc_select_driver_type(card); | ||
1362 | |||
1344 | /* Switch card to HS400 */ | 1363 | /* Switch card to HS400 */ |
1345 | val = EXT_CSD_TIMING_HS400 | | 1364 | val = EXT_CSD_TIMING_HS400 | |
1346 | card->drive_strength << EXT_CSD_DRV_STR_SHIFT; | 1365 | card->drive_strength << EXT_CSD_DRV_STR_SHIFT; |
@@ -1374,23 +1393,6 @@ out_err: | |||
1374 | return err; | 1393 | return err; |
1375 | } | 1394 | } |
1376 | 1395 | ||
1377 | static void mmc_select_driver_type(struct mmc_card *card) | ||
1378 | { | ||
1379 | int card_drv_type, drive_strength, drv_type; | ||
1380 | |||
1381 | card_drv_type = card->ext_csd.raw_driver_strength | | ||
1382 | mmc_driver_type_mask(0); | ||
1383 | |||
1384 | drive_strength = mmc_select_drive_strength(card, | ||
1385 | card->ext_csd.hs200_max_dtr, | ||
1386 | card_drv_type, &drv_type); | ||
1387 | |||
1388 | card->drive_strength = drive_strength; | ||
1389 | |||
1390 | if (drv_type) | ||
1391 | mmc_set_driver_type(card->host, drv_type); | ||
1392 | } | ||
1393 | |||
1394 | /* | 1396 | /* |
1395 | * For device supporting HS200 mode, the following sequence | 1397 | * For device supporting HS200 mode, the following sequence |
1396 | * should be done before executing the tuning process. | 1398 | * should be done before executing the tuning process. |
diff --git a/drivers/mmc/core/queue.c b/drivers/mmc/core/queue.c index affa7370ba82..0a4e77a5ba33 100644 --- a/drivers/mmc/core/queue.c +++ b/drivers/mmc/core/queue.c | |||
@@ -23,8 +23,6 @@ | |||
23 | #include "core.h" | 23 | #include "core.h" |
24 | #include "card.h" | 24 | #include "card.h" |
25 | 25 | ||
26 | #define MMC_QUEUE_BOUNCESZ 65536 | ||
27 | |||
28 | /* | 26 | /* |
29 | * Prepare a MMC request. This just filters out odd stuff. | 27 | * Prepare a MMC request. This just filters out odd stuff. |
30 | */ | 28 | */ |
@@ -150,26 +148,6 @@ static void mmc_queue_setup_discard(struct request_queue *q, | |||
150 | queue_flag_set_unlocked(QUEUE_FLAG_SECERASE, q); | 148 | queue_flag_set_unlocked(QUEUE_FLAG_SECERASE, q); |
151 | } | 149 | } |
152 | 150 | ||
153 | static unsigned int mmc_queue_calc_bouncesz(struct mmc_host *host) | ||
154 | { | ||
155 | unsigned int bouncesz = MMC_QUEUE_BOUNCESZ; | ||
156 | |||
157 | if (host->max_segs != 1 || (host->caps & MMC_CAP_NO_BOUNCE_BUFF)) | ||
158 | return 0; | ||
159 | |||
160 | if (bouncesz > host->max_req_size) | ||
161 | bouncesz = host->max_req_size; | ||
162 | if (bouncesz > host->max_seg_size) | ||
163 | bouncesz = host->max_seg_size; | ||
164 | if (bouncesz > host->max_blk_count * 512) | ||
165 | bouncesz = host->max_blk_count * 512; | ||
166 | |||
167 | if (bouncesz <= 512) | ||
168 | return 0; | ||
169 | |||
170 | return bouncesz; | ||
171 | } | ||
172 | |||
173 | /** | 151 | /** |
174 | * mmc_init_request() - initialize the MMC-specific per-request data | 152 | * mmc_init_request() - initialize the MMC-specific per-request data |
175 | * @q: the request queue | 153 | * @q: the request queue |
@@ -184,26 +162,9 @@ static int mmc_init_request(struct request_queue *q, struct request *req, | |||
184 | struct mmc_card *card = mq->card; | 162 | struct mmc_card *card = mq->card; |
185 | struct mmc_host *host = card->host; | 163 | struct mmc_host *host = card->host; |
186 | 164 | ||
187 | if (card->bouncesz) { | 165 | mq_rq->sg = mmc_alloc_sg(host->max_segs, gfp); |
188 | mq_rq->bounce_buf = kmalloc(card->bouncesz, gfp); | 166 | if (!mq_rq->sg) |
189 | if (!mq_rq->bounce_buf) | 167 | return -ENOMEM; |
190 | return -ENOMEM; | ||
191 | if (card->bouncesz > 512) { | ||
192 | mq_rq->sg = mmc_alloc_sg(1, gfp); | ||
193 | if (!mq_rq->sg) | ||
194 | return -ENOMEM; | ||
195 | mq_rq->bounce_sg = mmc_alloc_sg(card->bouncesz / 512, | ||
196 | gfp); | ||
197 | if (!mq_rq->bounce_sg) | ||
198 | return -ENOMEM; | ||
199 | } | ||
200 | } else { | ||
201 | mq_rq->bounce_buf = NULL; | ||
202 | mq_rq->bounce_sg = NULL; | ||
203 | mq_rq->sg = mmc_alloc_sg(host->max_segs, gfp); | ||
204 | if (!mq_rq->sg) | ||
205 | return -ENOMEM; | ||
206 | } | ||
207 | 168 | ||
208 | return 0; | 169 | return 0; |
209 | } | 170 | } |
@@ -212,13 +173,6 @@ static void mmc_exit_request(struct request_queue *q, struct request *req) | |||
212 | { | 173 | { |
213 | struct mmc_queue_req *mq_rq = req_to_mmc_queue_req(req); | 174 | struct mmc_queue_req *mq_rq = req_to_mmc_queue_req(req); |
214 | 175 | ||
215 | /* It is OK to kfree(NULL) so this will be smooth */ | ||
216 | kfree(mq_rq->bounce_sg); | ||
217 | mq_rq->bounce_sg = NULL; | ||
218 | |||
219 | kfree(mq_rq->bounce_buf); | ||
220 | mq_rq->bounce_buf = NULL; | ||
221 | |||
222 | kfree(mq_rq->sg); | 176 | kfree(mq_rq->sg); |
223 | mq_rq->sg = NULL; | 177 | mq_rq->sg = NULL; |
224 | } | 178 | } |
@@ -265,18 +219,11 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, | |||
265 | if (mmc_can_erase(card)) | 219 | if (mmc_can_erase(card)) |
266 | mmc_queue_setup_discard(mq->queue, card); | 220 | mmc_queue_setup_discard(mq->queue, card); |
267 | 221 | ||
268 | card->bouncesz = mmc_queue_calc_bouncesz(host); | 222 | blk_queue_bounce_limit(mq->queue, limit); |
269 | if (card->bouncesz) { | 223 | blk_queue_max_hw_sectors(mq->queue, |
270 | blk_queue_max_hw_sectors(mq->queue, card->bouncesz / 512); | 224 | min(host->max_blk_count, host->max_req_size / 512)); |
271 | blk_queue_max_segments(mq->queue, card->bouncesz / 512); | 225 | blk_queue_max_segments(mq->queue, host->max_segs); |
272 | blk_queue_max_segment_size(mq->queue, card->bouncesz); | 226 | blk_queue_max_segment_size(mq->queue, host->max_seg_size); |
273 | } else { | ||
274 | blk_queue_bounce_limit(mq->queue, limit); | ||
275 | blk_queue_max_hw_sectors(mq->queue, | ||
276 | min(host->max_blk_count, host->max_req_size / 512)); | ||
277 | blk_queue_max_segments(mq->queue, host->max_segs); | ||
278 | blk_queue_max_segment_size(mq->queue, host->max_seg_size); | ||
279 | } | ||
280 | 227 | ||
281 | sema_init(&mq->thread_sem, 1); | 228 | sema_init(&mq->thread_sem, 1); |
282 | 229 | ||
@@ -365,56 +312,7 @@ void mmc_queue_resume(struct mmc_queue *mq) | |||
365 | */ | 312 | */ |
366 | unsigned int mmc_queue_map_sg(struct mmc_queue *mq, struct mmc_queue_req *mqrq) | 313 | unsigned int mmc_queue_map_sg(struct mmc_queue *mq, struct mmc_queue_req *mqrq) |
367 | { | 314 | { |
368 | unsigned int sg_len; | ||
369 | size_t buflen; | ||
370 | struct scatterlist *sg; | ||
371 | struct request *req = mmc_queue_req_to_req(mqrq); | 315 | struct request *req = mmc_queue_req_to_req(mqrq); |
372 | int i; | ||
373 | |||
374 | if (!mqrq->bounce_buf) | ||
375 | return blk_rq_map_sg(mq->queue, req, mqrq->sg); | ||
376 | |||
377 | sg_len = blk_rq_map_sg(mq->queue, req, mqrq->bounce_sg); | ||
378 | |||
379 | mqrq->bounce_sg_len = sg_len; | ||
380 | |||
381 | buflen = 0; | ||
382 | for_each_sg(mqrq->bounce_sg, sg, sg_len, i) | ||
383 | buflen += sg->length; | ||
384 | |||
385 | sg_init_one(mqrq->sg, mqrq->bounce_buf, buflen); | ||
386 | |||
387 | return 1; | ||
388 | } | ||
389 | |||
390 | /* | ||
391 | * If writing, bounce the data to the buffer before the request | ||
392 | * is sent to the host driver | ||
393 | */ | ||
394 | void mmc_queue_bounce_pre(struct mmc_queue_req *mqrq) | ||
395 | { | ||
396 | if (!mqrq->bounce_buf) | ||
397 | return; | ||
398 | |||
399 | if (rq_data_dir(mmc_queue_req_to_req(mqrq)) != WRITE) | ||
400 | return; | ||
401 | |||
402 | sg_copy_to_buffer(mqrq->bounce_sg, mqrq->bounce_sg_len, | ||
403 | mqrq->bounce_buf, mqrq->sg[0].length); | ||
404 | } | ||
405 | |||
406 | /* | ||
407 | * If reading, bounce the data from the buffer after the request | ||
408 | * has been handled by the host driver | ||
409 | */ | ||
410 | void mmc_queue_bounce_post(struct mmc_queue_req *mqrq) | ||
411 | { | ||
412 | if (!mqrq->bounce_buf) | ||
413 | return; | ||
414 | |||
415 | if (rq_data_dir(mmc_queue_req_to_req(mqrq)) != READ) | ||
416 | return; | ||
417 | 316 | ||
418 | sg_copy_from_buffer(mqrq->bounce_sg, mqrq->bounce_sg_len, | 317 | return blk_rq_map_sg(mq->queue, req, mqrq->sg); |
419 | mqrq->bounce_buf, mqrq->sg[0].length); | ||
420 | } | 318 | } |
diff --git a/drivers/mmc/core/queue.h b/drivers/mmc/core/queue.h index 04fc89360a7a..f18d3f656baa 100644 --- a/drivers/mmc/core/queue.h +++ b/drivers/mmc/core/queue.h | |||
@@ -49,9 +49,6 @@ enum mmc_drv_op { | |||
49 | struct mmc_queue_req { | 49 | struct mmc_queue_req { |
50 | struct mmc_blk_request brq; | 50 | struct mmc_blk_request brq; |
51 | struct scatterlist *sg; | 51 | struct scatterlist *sg; |
52 | char *bounce_buf; | ||
53 | struct scatterlist *bounce_sg; | ||
54 | unsigned int bounce_sg_len; | ||
55 | struct mmc_async_req areq; | 52 | struct mmc_async_req areq; |
56 | enum mmc_drv_op drv_op; | 53 | enum mmc_drv_op drv_op; |
57 | int drv_op_result; | 54 | int drv_op_result; |
@@ -81,11 +78,8 @@ extern int mmc_init_queue(struct mmc_queue *, struct mmc_card *, spinlock_t *, | |||
81 | extern void mmc_cleanup_queue(struct mmc_queue *); | 78 | extern void mmc_cleanup_queue(struct mmc_queue *); |
82 | extern void mmc_queue_suspend(struct mmc_queue *); | 79 | extern void mmc_queue_suspend(struct mmc_queue *); |
83 | extern void mmc_queue_resume(struct mmc_queue *); | 80 | extern void mmc_queue_resume(struct mmc_queue *); |
84 | |||
85 | extern unsigned int mmc_queue_map_sg(struct mmc_queue *, | 81 | extern unsigned int mmc_queue_map_sg(struct mmc_queue *, |
86 | struct mmc_queue_req *); | 82 | struct mmc_queue_req *); |
87 | extern void mmc_queue_bounce_pre(struct mmc_queue_req *); | ||
88 | extern void mmc_queue_bounce_post(struct mmc_queue_req *); | ||
89 | 83 | ||
90 | extern int mmc_access_rpmb(struct mmc_queue *); | 84 | extern int mmc_access_rpmb(struct mmc_queue *); |
91 | 85 | ||