mmc: Implement card detection.
authorThierry Reding <thierry.reding@avionic-design.de>
Mon, 2 Jan 2012 01:15:37 +0000 (01:15 +0000)
committerAndy Fleming <afleming@freescale.com>
Mon, 9 Jan 2012 03:28:27 +0000 (21:28 -0600)
Check for card detect each time an MMC/SD device is initialized. If card
detection is not implemented, this code behaves as before and continues
assuming a card is present. If no card is detected, has_init is reset
for the MMC/SD device (to force initialization next time) and an error
is returned.

Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
Tested-by: Jason Liu <jason.hui@linaro.org>
15 files changed:
drivers/mmc/arm_pl180_mmci.c
drivers/mmc/bfin_sdh.c
drivers/mmc/davinci_mmc.c
drivers/mmc/ftsdc010_esdhc.c
drivers/mmc/gen_atmel_mci.c
drivers/mmc/mmc.c
drivers/mmc/mmc_spi.c
drivers/mmc/mxcmmc.c
drivers/mmc/mxsmmc.c
drivers/mmc/omap_hsmmc.c
drivers/mmc/pxa_mmc_gen.c
drivers/mmc/s5p_mmc.c
drivers/mmc/sdhci.c
drivers/mmc/sh_mmcif.c
include/mmc.h

index e6467a2d186f3a86cf3f4baec0db5dfcf7905645..09d443ee39bf90df39059a273d63f13e004c8bba 100644 (file)
@@ -385,6 +385,7 @@ static int arm_pl180_mmci_host_init(struct mmc *dev)
        dev->send_cmd = host_request;
        dev->set_ios = host_set_ios;
        dev->init = mmc_host_reset;
+       dev->getcd = NULL;
        dev->host_caps = 0;
        dev->voltages = VOLTAGE_WINDOW_MMC;
        dev->f_min = dev->clock;
index bc9057fa9a5a444c359eb93d34032ec8e19cf384..08fc5c1d3e61d66d4daac74f0b5086917f2ce4a7 100644 (file)
@@ -250,6 +250,7 @@ int bfin_mmc_init(bd_t *bis)
        mmc->send_cmd = bfin_sdh_request;
        mmc->set_ios = bfin_sdh_set_ios;
        mmc->init = bfin_sdh_init;
+       mmc->getcd = NULL;
        mmc->host_caps = MMC_MODE_4BIT;
 
        mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
index ce96736942cc1fc592ad2966b18c17a5a53d4226..ee8f2614de5d152231d30a3ee25c371a78f34ceb 100644 (file)
@@ -387,6 +387,7 @@ int davinci_mmc_init(bd_t *bis, struct davinci_mmc *host)
        mmc->send_cmd = dmmc_send_cmd;
        mmc->set_ios = dmmc_set_ios;
        mmc->init = dmmc_init;
+       mmc->getcd = NULL;
 
        mmc->f_min = 200000;
        mmc->f_max = 25000000;
index 33cb5d67ef9a19189d5b0c7fa6455a705b803666..f1702fe33bedb560789bcb9afc4c465a531ab259 100644 (file)
@@ -665,6 +665,7 @@ int ftsdc010_mmc_init(int dev_index)
        mmc->send_cmd = ftsdc010_request;
        mmc->set_ios = ftsdc010_set_ios;
        mmc->init = ftsdc010_core_init;
+       mmc->getcd = NULL;
 
        mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
 
index f346b244be124e0502a9ec172584f4fccee78c2b..4968c5e4912aa46da6b68884e58fc9edda4375f3 100644 (file)
@@ -337,6 +337,7 @@ int atmel_mci_init(void *regs)
        mmc->send_cmd = mci_send_cmd;
        mmc->set_ios = mci_set_ios;
        mmc->init = mci_init;
+       mmc->getcd = NULL;
 
        /* need to be able to pass these in on a board by board basis */
        mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
index 11c6aa67c16bbe812c58c681044929fb1c2410f1..6db37b1fc548a49be870d06f4737e5b799e6db76 100644 (file)
@@ -674,6 +674,18 @@ int mmc_switch_part(int dev_num, unsigned int part_num)
                          | (part_num & PART_ACCESS_MASK));
 }
 
+int mmc_getcd(struct mmc *mmc)
+{
+       int cd;
+
+       cd = board_mmc_getcd(mmc);
+
+       if ((cd < 0) && mmc->getcd)
+               cd = mmc->getcd(mmc);
+
+       return cd;
+}
+
 int sd_switch(struct mmc *mmc, int mode, int group, u8 value, u8 *resp)
 {
        struct mmc_cmd cmd;
@@ -1202,6 +1214,12 @@ int mmc_init(struct mmc *mmc)
 {
        int err;
 
+       if (mmc_getcd(mmc) == 0) {
+               mmc->has_init = 0;
+               printf("MMC: no card present\n");
+               return NO_CARD_ERR;
+       }
+
        if (mmc->has_init)
                return 0;
 
index 49fb9e02a91e039837c85729c36e0171407dcf17..de43a85355f4755a4088cbc387740240d8c08ed1 100644 (file)
@@ -272,6 +272,7 @@ struct mmc *mmc_spi_init(uint bus, uint cs, uint speed, uint mode)
        mmc->send_cmd = mmc_spi_request;
        mmc->set_ios = mmc_spi_set_ios;
        mmc->init = mmc_spi_init_p;
+       mmc->getcd = NULL;
        mmc->host_caps = MMC_MODE_SPI;
 
        mmc->voltages = MMC_SPI_VOLTAGE;
index ab1fc82fbb68dd3f0d6f90f55b3be916fd8eac56..8afb22159ab518e5ea3ed9acbba769220523c943 100644 (file)
@@ -500,6 +500,7 @@ static int mxcmci_initialize(bd_t *bis)
        mmc->send_cmd = mxcmci_request;
        mmc->set_ios = mxcmci_set_ios;
        mmc->init = mxcmci_init;
+       mmc->getcd = NULL;
        mmc->host_caps = MMC_MODE_4BIT;
 
        host->base = (struct mxcmci_regs *)CONFIG_MXC_MCI_REGS_BASE;
index 2a9949eb942ef489745a69ea18df55be5a3a1006..5f87a1efd6ce2c29190cc89108c5d7ee16b2bbcb 100644 (file)
@@ -329,6 +329,7 @@ int mxsmmc_initialize(bd_t *bis, int id, int (*wp)(int))
        mmc->send_cmd = mxsmmc_send_cmd;
        mmc->set_ios = mxsmmc_set_ios;
        mmc->init = mxsmmc_init;
+       mmc->getcd = NULL;
        mmc->priv = priv;
 
        mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
index c38b9e603846d0a224ff4e7ef914c086af5df805..ef64e37411f235dfb9b21ac6c719e1a9f5b07c8c 100644 (file)
@@ -472,6 +472,7 @@ int omap_mmc_init(int dev_index)
        mmc->send_cmd = mmc_send_cmd;
        mmc->set_ios = mmc_set_ios;
        mmc->init = mmc_init_setup;
+       mmc->getcd = NULL;
 
        switch (dev_index) {
        case 0:
index 4a7c67a6bda1cb44482c93e5ad8290672baf09a8..2c5bf17bb3c5b7750e71e0ffa600125ed3218b43 100644 (file)
@@ -411,6 +411,7 @@ int pxa_mmc_register(int card_index)
        mmc->send_cmd   = pxa_mmc_request;
        mmc->set_ios    = pxa_mmc_set_ios;
        mmc->init       = pxa_mmc_init;
+       mmc->getcd      = NULL;
 
        mmc->voltages   = MMC_VDD_32_33 | MMC_VDD_33_34;
        mmc->f_max      = PXAMMC_MAX_SPEED;
index 7786ecf2be87e02ed5727082326f8b15d5632ddf..4ae3aaf7738d8ced7d51dd5500022f39759b88a0 100644 (file)
@@ -463,6 +463,7 @@ static int s5p_mmc_initialize(int dev_index, int bus_width)
        mmc->send_cmd = mmc_send_cmd;
        mmc->set_ios = mmc_set_ios;
        mmc->init = mmc_core_init;
+       mmc->getcd = NULL;
 
        mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
        if (bus_width == 8)
index fce0ef091184b39e07adf8a0acc8c29ab6a2d3dc..fc904b5308eaa855a5a758b56e0f840d9892a608 100644 (file)
@@ -390,6 +390,7 @@ int add_sdhci(struct sdhci_host *host, u32 max_clk, u32 min_clk)
        mmc->send_cmd = sdhci_send_command;
        mmc->set_ios = sdhci_set_ios;
        mmc->init = sdhci_init;
+       mmc->getcd = NULL;
 
        caps = sdhci_readl(host, SDHCI_CAPABILITIES);
 #ifdef CONFIG_MMC_SDMA
index 567e2cb61d32ba8b63f574a2ee14c4dff72b989c..2835e242f8943bdaeb763f072e5b75e451d5c712 100644 (file)
@@ -598,6 +598,7 @@ int mmcif_mmc_init(void)
        mmc->send_cmd = sh_mmcif_request;
        mmc->set_ios = sh_mmcif_set_ios;
        mmc->init = sh_mmcif_init;
+       mmc->getcd = NULL;
        host->regs = (struct sh_mmcif_regs *)CONFIG_SH_MMCIF_ADDR;
        host->clk = CONFIG_SH_MMCIF_CLK;
        mmc->priv = host;
index a850174ab869f6ad3a6cbd464d3a2526b87194ee..8744604ead1b7db30287d744494e0957c285bbd9 100644 (file)
@@ -302,6 +302,7 @@ struct mmc {
                        struct mmc_cmd *cmd, struct mmc_data *data);
        void (*set_ios)(struct mmc *mmc);
        int (*init)(struct mmc *mmc);
+       int (*getcd)(struct mmc *mmc);
        uint b_max;
 };
 
@@ -316,6 +317,7 @@ void print_mmc_devices(char separator);
 int get_mmc_num(void);
 int board_mmc_getcd(struct mmc *mmc);
 int mmc_switch_part(int dev_num, unsigned int part_num);
+int mmc_getcd(struct mmc *mmc);
 
 #ifdef CONFIG_GENERIC_MMC
 int atmel_mci_init(void *regs);