]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - drivers/mmc/mmc.c
mmc: read extcsd and check if requested change of RST_N_FUNCTION is possible
[karo-tx-uboot.git] / drivers / mmc / mmc.c
index b8039cd092abd43a14022f0a1e7a646198c30aa6..c0bab82714c50f2649af8095077464b3b5741423 100644 (file)
@@ -20,6 +20,7 @@
 
 static struct list_head mmc_devices;
 static int cur_dev_num = -1;
+static int mmc_dev_count;
 
 __weak int board_mmc_getwp(struct mmc *mmc)
 {
@@ -324,8 +325,7 @@ static int sd_send_op_cond(struct mmc *mmc)
 
                udelay(1000);
        } while ((!(cmd.response[0] & OCR_BUSY)) && timeout--);
-
-       if (timeout <= 0)
+       if (!(cmd.response[0] & OCR_BUSY))
                return UNUSABLE_ERR;
 
        if (mmc->version != SD_VERSION_2)
@@ -383,7 +383,7 @@ static int mmc_send_op_cond(struct mmc *mmc)
        /* Some cards seem to need this */
        mmc_go_idle(mmc);
 
-       /* Asking to the card its capabilities */
+       /* Asking to the card its capabilities */
        mmc->op_cond_pending = 1;
        for (i = 0; i < 2; i++) {
                err = mmc_send_op_cond_iter(mmc, &cmd, i != 0);
@@ -411,9 +411,13 @@ static int mmc_complete_op_cond(struct mmc *mmc)
                if (err)
                        return err;
                if (get_timer(start) > timeout)
-                       return UNUSABLE_ERR;
+                       break;
                udelay(100);
        } while (!(mmc->op_cond_response & OCR_BUSY));
+       if (!(mmc->op_cond_response & OCR_BUSY)) {
+               debug("%s: timeout\n", __func__);
+               return UNUSABLE_ERR;
+       }
 
        if (mmc_host_is_spi(mmc)) { /* read OCR for spi */
                cmd.cmdidx = MMC_CMD_SPI_READ_OCR;
@@ -1546,6 +1550,7 @@ struct mmc *mmc_create(const struct mmc_config *cfg, void *priv)
        INIT_LIST_HEAD(&mmc->link);
 
        list_add_tail(&mmc->link, &mmc_devices);
+       mmc_dev_count++;
 
        return mmc;
 }
@@ -1718,6 +1723,11 @@ int get_mmc_num(void)
        return cur_dev_num;
 }
 
+int get_mmc_dev_count(void)
+{
+       return mmc_dev_count;
+}
+
 void mmc_set_preinit(struct mmc *mmc, int preinit)
 {
        mmc->preinit = preinit;
@@ -1871,6 +1881,19 @@ int mmc_set_part_conf(struct mmc *mmc, u8 ack, u8 part_num, u8 access)
  */
 int mmc_set_rst_n_function(struct mmc *mmc, u8 enable)
 {
+       int ret;
+       ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
+
+       ret = mmc_send_ext_csd(mmc, ext_csd);
+       if (ret)
+               return ret;
+
+       if (ext_csd[EXT_CSD_RST_N_FUNCTION] != 0 &&
+               ext_csd[EXT_CSD_RST_N_FUNCTION] != enable) {
+               printf("RST_N_FUNCTION is already set to %u; cannot change to %u\n",
+                       ext_csd[EXT_CSD_RST_N_FUNCTION], enable);
+               return -EINVAL;
+       }
        return mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_RST_N_FUNCTION,
                          enable);
 }