diff options
Diffstat (limited to 'drivers/mmc/core/core.c')
-rw-r--r-- | drivers/mmc/core/core.c | 41 |
1 files changed, 37 insertions, 4 deletions
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 01ced4c5a61d..3ee5b8c3b5ce 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Copyright (C) 2003-2004 Russell King, All Rights Reserved. | 4 | * Copyright (C) 2003-2004 Russell King, All Rights Reserved. |
5 | * SD support Copyright (C) 2004 Ian Molton, All Rights Reserved. | 5 | * SD support Copyright (C) 2004 Ian Molton, All Rights Reserved. |
6 | * Copyright (C) 2005-2007 Pierre Ossman, All Rights Reserved. | 6 | * Copyright (C) 2005-2008 Pierre Ossman, All Rights Reserved. |
7 | * MMCv4 support Copyright (C) 2006 Philip Langdale, All Rights Reserved. | 7 | * MMCv4 support Copyright (C) 2006 Philip Langdale, All Rights Reserved. |
8 | * | 8 | * |
9 | * This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
@@ -295,6 +295,33 @@ void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card) | |||
295 | EXPORT_SYMBOL(mmc_set_data_timeout); | 295 | EXPORT_SYMBOL(mmc_set_data_timeout); |
296 | 296 | ||
297 | /** | 297 | /** |
298 | * mmc_align_data_size - pads a transfer size to a more optimal value | ||
299 | * @card: the MMC card associated with the data transfer | ||
300 | * @sz: original transfer size | ||
301 | * | ||
302 | * Pads the original data size with a number of extra bytes in | ||
303 | * order to avoid controller bugs and/or performance hits | ||
304 | * (e.g. some controllers revert to PIO for certain sizes). | ||
305 | * | ||
306 | * Returns the improved size, which might be unmodified. | ||
307 | * | ||
308 | * Note that this function is only relevant when issuing a | ||
309 | * single scatter gather entry. | ||
310 | */ | ||
311 | unsigned int mmc_align_data_size(struct mmc_card *card, unsigned int sz) | ||
312 | { | ||
313 | /* | ||
314 | * FIXME: We don't have a system for the controller to tell | ||
315 | * the core about its problems yet, so for now we just 32-bit | ||
316 | * align the size. | ||
317 | */ | ||
318 | sz = ((sz + 3) / 4) * 4; | ||
319 | |||
320 | return sz; | ||
321 | } | ||
322 | EXPORT_SYMBOL(mmc_align_data_size); | ||
323 | |||
324 | /** | ||
298 | * __mmc_claim_host - exclusively claim a host | 325 | * __mmc_claim_host - exclusively claim a host |
299 | * @host: mmc host to claim | 326 | * @host: mmc host to claim |
300 | * @abort: whether or not the operation should be aborted | 327 | * @abort: whether or not the operation should be aborted |
@@ -638,6 +665,9 @@ void mmc_rescan(struct work_struct *work) | |||
638 | */ | 665 | */ |
639 | mmc_bus_put(host); | 666 | mmc_bus_put(host); |
640 | 667 | ||
668 | if (host->ops->get_cd && host->ops->get_cd(host) == 0) | ||
669 | goto out; | ||
670 | |||
641 | mmc_claim_host(host); | 671 | mmc_claim_host(host); |
642 | 672 | ||
643 | mmc_power_up(host); | 673 | mmc_power_up(host); |
@@ -652,7 +682,7 @@ void mmc_rescan(struct work_struct *work) | |||
652 | if (!err) { | 682 | if (!err) { |
653 | if (mmc_attach_sdio(host, ocr)) | 683 | if (mmc_attach_sdio(host, ocr)) |
654 | mmc_power_off(host); | 684 | mmc_power_off(host); |
655 | return; | 685 | goto out; |
656 | } | 686 | } |
657 | 687 | ||
658 | /* | 688 | /* |
@@ -662,7 +692,7 @@ void mmc_rescan(struct work_struct *work) | |||
662 | if (!err) { | 692 | if (!err) { |
663 | if (mmc_attach_sd(host, ocr)) | 693 | if (mmc_attach_sd(host, ocr)) |
664 | mmc_power_off(host); | 694 | mmc_power_off(host); |
665 | return; | 695 | goto out; |
666 | } | 696 | } |
667 | 697 | ||
668 | /* | 698 | /* |
@@ -672,7 +702,7 @@ void mmc_rescan(struct work_struct *work) | |||
672 | if (!err) { | 702 | if (!err) { |
673 | if (mmc_attach_mmc(host, ocr)) | 703 | if (mmc_attach_mmc(host, ocr)) |
674 | mmc_power_off(host); | 704 | mmc_power_off(host); |
675 | return; | 705 | goto out; |
676 | } | 706 | } |
677 | 707 | ||
678 | mmc_release_host(host); | 708 | mmc_release_host(host); |
@@ -683,6 +713,9 @@ void mmc_rescan(struct work_struct *work) | |||
683 | 713 | ||
684 | mmc_bus_put(host); | 714 | mmc_bus_put(host); |
685 | } | 715 | } |
716 | out: | ||
717 | if (host->caps & MMC_CAP_NEEDS_POLL) | ||
718 | mmc_schedule_delayed_work(&host->detect, HZ); | ||
686 | } | 719 | } |
687 | 720 | ||
688 | void mmc_start_host(struct mmc_host *host) | 721 | void mmc_start_host(struct mmc_host *host) |