aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJorg Schummer <ext-jorg.2.schummer@nokia.com>2009-03-31 10:51:21 -0400
committerPierre Ossman <pierre@ossman.eu>2009-06-13 16:42:56 -0400
commit94d89efb2c347a82a08a61dbac8565b1087c3259 (patch)
tree78e4cfaec79e4ae6346635d859f4d1501dd7e0e7 /drivers
parentf3ad116588151b3371ae4e092290e4f48e62b8bb (diff)
mmc: mmc_rescan detects card change in one run
With this patch, mmc_rescan can detect the removal of an mmc card and the insertion of (possibly another) card in the same run. This means that a card change can be detected without having to call mmc_detect_change multiple times. This change generalises the core such that it can be easily used by hosts which provide a mechanism to detect only the presence of a card reader cover, which has to be taken off in order to insert a card. Other hosts ("card detect" or "MMC_CAP_NEEDS_POLL") each receive an event when a card is removed and when a card is inserted, so it is sufficient for them if mmc_rescan handles only one event at a time. "Cover detect" hosts, however, only receive events about the cover status. This means that between 2 subsequent events, both a card removal and a card insertion can occur. In this case, the pre-patch version of mmc_rescan would only detect the removal of the previous card but not the insertion of the new card. Signed-off-by: Jorg Schummer <ext-jorg.2.schummer@nokia.com> Signed-off-by: Pierre Ossman <pierre@ossman.eu>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mmc/core/core.c99
1 files changed, 55 insertions, 44 deletions
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 264911732756..23fb2c39d9ed 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -855,61 +855,72 @@ void mmc_rescan(struct work_struct *work)
855 855
856 mmc_bus_get(host); 856 mmc_bus_get(host);
857 857
858 if (host->bus_ops == NULL) { 858 /* if there is a card registered, check whether it is still present */
859 /* 859 if ((host->bus_ops != NULL) && host->bus_ops->detect && !host->bus_dead)
860 * Only we can add a new handler, so it's safe to 860 host->bus_ops->detect(host);
861 * release the lock here. 861
862 */ 862 mmc_bus_put(host);
863
864
865 mmc_bus_get(host);
866
867 /* if there still is a card present, stop here */
868 if (host->bus_ops != NULL) {
863 mmc_bus_put(host); 869 mmc_bus_put(host);
870 goto out;
871 }
864 872
865 if (host->ops->get_cd && host->ops->get_cd(host) == 0) 873 /* detect a newly inserted card */
866 goto out;
867 874
868 mmc_claim_host(host); 875 /*
876 * Only we can add a new handler, so it's safe to
877 * release the lock here.
878 */
879 mmc_bus_put(host);
869 880
870 mmc_power_up(host); 881 if (host->ops->get_cd && host->ops->get_cd(host) == 0)
871 mmc_go_idle(host); 882 goto out;
872 883
873 mmc_send_if_cond(host, host->ocr_avail); 884 mmc_claim_host(host);
874 885
875 /* 886 mmc_power_up(host);
876 * First we search for SDIO... 887 mmc_go_idle(host);
877 */
878 err = mmc_send_io_op_cond(host, 0, &ocr);
879 if (!err) {
880 if (mmc_attach_sdio(host, ocr))
881 mmc_power_off(host);
882 goto out;
883 }
884 888
885 /* 889 mmc_send_if_cond(host, host->ocr_avail);
886 * ...then normal SD...
887 */
888 err = mmc_send_app_op_cond(host, 0, &ocr);
889 if (!err) {
890 if (mmc_attach_sd(host, ocr))
891 mmc_power_off(host);
892 goto out;
893 }
894 890
895 /* 891 /*
896 * ...and finally MMC. 892 * First we search for SDIO...
897 */ 893 */
898 err = mmc_send_op_cond(host, 0, &ocr); 894 err = mmc_send_io_op_cond(host, 0, &ocr);
899 if (!err) { 895 if (!err) {
900 if (mmc_attach_mmc(host, ocr)) 896 if (mmc_attach_sdio(host, ocr))
901 mmc_power_off(host); 897 mmc_power_off(host);
902 goto out; 898 goto out;
903 } 899 }
904 900
905 mmc_release_host(host); 901 /*
906 mmc_power_off(host); 902 * ...then normal SD...
907 } else { 903 */
908 if (host->bus_ops->detect && !host->bus_dead) 904 err = mmc_send_app_op_cond(host, 0, &ocr);
909 host->bus_ops->detect(host); 905 if (!err) {
906 if (mmc_attach_sd(host, ocr))
907 mmc_power_off(host);
908 goto out;
909 }
910 910
911 mmc_bus_put(host); 911 /*
912 * ...and finally MMC.
913 */
914 err = mmc_send_op_cond(host, 0, &ocr);
915 if (!err) {
916 if (mmc_attach_mmc(host, ocr))
917 mmc_power_off(host);
918 goto out;
912 } 919 }
920
921 mmc_release_host(host);
922 mmc_power_off(host);
923
913out: 924out:
914 if (host->caps & MMC_CAP_NEEDS_POLL) 925 if (host->caps & MMC_CAP_NEEDS_POLL)
915 mmc_schedule_delayed_work(&host->detect, HZ); 926 mmc_schedule_delayed_work(&host->detect, HZ);