]> Pileus Git - ~andy/linux/blobdiff - drivers/mmc/core/sdio.c
mmc: core: Fix low speed mmc card detection failure
[~andy/linux] / drivers / mmc / core / sdio.c
index 8c04f7f46dec6dc6dbf988912eaadc4d74934b00..12cde6ee17f50732ac5cd05f6843928abf87d0c9 100644 (file)
@@ -14,6 +14,7 @@
 
 #include <linux/mmc/host.h>
 #include <linux/mmc/card.h>
+#include <linux/mmc/mmc.h>
 #include <linux/mmc/sdio.h>
 #include <linux/mmc/sdio_func.h>
 #include <linux/mmc/sdio_ids.h>
@@ -97,10 +98,11 @@ fail:
        return ret;
 }
 
-static int sdio_read_cccr(struct mmc_card *card)
+static int sdio_read_cccr(struct mmc_card *card, u32 ocr)
 {
        int ret;
        int cccr_vsn;
+       int uhs = ocr & R4_18V_PRESENT;
        unsigned char data;
        unsigned char speed;
 
@@ -148,7 +150,7 @@ static int sdio_read_cccr(struct mmc_card *card)
                card->scr.sda_spec3 = 0;
                card->sw_caps.sd3_bus_mode = 0;
                card->sw_caps.sd3_drv_type = 0;
-               if (cccr_vsn >= SDIO_CCCR_REV_3_00) {
+               if (cccr_vsn >= SDIO_CCCR_REV_3_00 && uhs) {
                        card->scr.sda_spec3 = 1;
                        ret = mmc_io_rw_direct(card, 0, 0,
                                SDIO_CCCR_UHS, 0, &data);
@@ -556,7 +558,8 @@ static int mmc_sdio_init_uhs_card(struct mmc_card *card)
 
        /* Initialize and start re-tuning timer */
        if (!mmc_host_is_spi(card->host) && card->host->ops->execute_tuning)
-               err = card->host->ops->execute_tuning(card->host);
+               err = card->host->ops->execute_tuning(card->host,
+                                                     MMC_SEND_TUNING_BLOCK);
 
 out:
 
@@ -710,7 +713,7 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
        /*
         * Read the common registers.
         */
-       err = sdio_read_cccr(card);
+       err = sdio_read_cccr(card, ocr);
        if (err)
                goto remove;
 
@@ -819,6 +822,14 @@ static void mmc_sdio_remove(struct mmc_host *host)
        host->card = NULL;
 }
 
+/*
+ * Card detection - card is alive.
+ */
+static int mmc_sdio_alive(struct mmc_host *host)
+{
+       return mmc_select_card(host->card);
+}
+
 /*
  * Card detection callback from host.
  */
@@ -841,7 +852,7 @@ static void mmc_sdio_detect(struct mmc_host *host)
        /*
         * Just check if our card has been removed.
         */
-       err = mmc_select_card(host->card);
+       err = _mmc_detect_card_removed(host);
 
        mmc_release_host(host);
 
@@ -1019,6 +1030,7 @@ static const struct mmc_bus_ops mmc_sdio_ops = {
        .suspend = mmc_sdio_suspend,
        .resume = mmc_sdio_resume,
        .power_restore = mmc_sdio_power_restore,
+       .alive = mmc_sdio_alive,
 };