mmc: core: fix merge bug
[firefly-linux-kernel-4.4.55.git] / drivers / mmc / core / mmc.c
index 32eefeb98aa5ebc476756ac18407f5b30a799545..1f4fd781ef29749a4d62288c0d2cc83695b6df80 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <linux/err.h>
+#include <linux/slab.h>
 
 #include <linux/mmc/host.h>
 #include <linux/mmc/card.h>
@@ -107,23 +108,34 @@ static int mmc_decode_cid(struct mmc_card *card)
        return 0;
 }
 
+static void mmc_set_erase_size(struct mmc_card *card)
+{
+       if (card->ext_csd.erase_group_def & 1)
+               card->erase_size = card->ext_csd.hc_erase_size;
+       else
+               card->erase_size = card->csd.erase_size;
+
+       mmc_init_erase(card);
+}
+
 /*
  * Given a 128-bit response, decode to our card CSD structure.
  */
 static int mmc_decode_csd(struct mmc_card *card)
 {
        struct mmc_csd *csd = &card->csd;
-       unsigned int e, m, csd_struct;
+       unsigned int e, m, a, b;
        u32 *resp = card->raw_csd;
 
        /*
         * We only understand CSD structure v1.1 and v1.2.
         * v1.2 has extra information in bits 15, 11 and 10.
+        * We also support eMMC v4.4 & v4.41.
         */
-       csd_struct = UNSTUFF_BITS(resp, 126, 2);
-       if (csd_struct != 1 && csd_struct != 2) {
+       csd->structure = UNSTUFF_BITS(resp, 126, 2);
+       if (csd->structure == 0) {
                printk(KERN_ERR "%s: unrecognised CSD structure version %d\n",
-                       mmc_hostname(card->host), csd_struct);
+                       mmc_hostname(card->host), csd->structure);
                return -EINVAL;
        }
 
@@ -150,6 +162,13 @@ static int mmc_decode_csd(struct mmc_card *card)
        csd->write_blkbits = UNSTUFF_BITS(resp, 22, 4);
        csd->write_partial = UNSTUFF_BITS(resp, 21, 1);
 
+       if (csd->write_blkbits >= 9) {
+               a = UNSTUFF_BITS(resp, 42, 5);
+               b = UNSTUFF_BITS(resp, 37, 5);
+               csd->erase_size = (a + 1) * (b + 1);
+               csd->erase_size <<= csd->write_blkbits - 9;
+       }
+
        return 0;
 }
 
@@ -206,11 +225,22 @@ static int mmc_read_ext_csd(struct mmc_card *card)
                goto out;
        }
 
+       /* Version is coded in the CSD_STRUCTURE byte in the EXT_CSD register */
+       if (card->csd.structure == 3) {
+               int ext_csd_struct = ext_csd[EXT_CSD_STRUCTURE];
+               if (ext_csd_struct > 2) {
+                       printk(KERN_ERR "%s: unrecognised EXT_CSD structure "
+                               "version %d\n", mmc_hostname(card->host),
+                                       ext_csd_struct);
+                       err = -EINVAL;
+                       goto out;
+               }
+       }
+
        card->ext_csd.rev = ext_csd[EXT_CSD_REV];
        if (card->ext_csd.rev > 5) {
-               printk(KERN_ERR "%s: unrecognised EXT_CSD structure "
-                       "version %d\n", mmc_hostname(card->host),
-                       card->ext_csd.rev);
+               printk(KERN_ERR "%s: unrecognised EXT_CSD revision %d\n",
+                       mmc_hostname(card->host), card->ext_csd.rev);
                err = -EINVAL;
                goto out;
        }
@@ -221,11 +251,13 @@ static int mmc_read_ext_csd(struct mmc_card *card)
                        ext_csd[EXT_CSD_SEC_CNT + 1] << 8 |
                        ext_csd[EXT_CSD_SEC_CNT + 2] << 16 |
                        ext_csd[EXT_CSD_SEC_CNT + 3] << 24;
-               if (card->ext_csd.sectors)
+
+               /* Cards with density > 2GiB are sector addressed */
+               if (card->ext_csd.sectors > (2u * 1024 * 1024 * 1024) / 512)
                        mmc_card_set_blockaddr(card);
        }
 
-       switch (ext_csd[EXT_CSD_CARD_TYPE]) {
+       switch (ext_csd[EXT_CSD_CARD_TYPE] & EXT_CSD_CARD_TYPE_MASK) {
        case EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26:
                card->ext_csd.hs_max_dtr = 52000000;
                break;
@@ -237,7 +269,6 @@ static int mmc_read_ext_csd(struct mmc_card *card)
                printk(KERN_WARNING "%s: card is mmc v4 but doesn't "
                        "support any high-speed modes.\n",
                        mmc_hostname(card->host));
-               goto out;
        }
 
        if (card->ext_csd.rev >= 3) {
@@ -247,8 +278,30 @@ static int mmc_read_ext_csd(struct mmc_card *card)
                if (sa_shift > 0 && sa_shift <= 0x17)
                        card->ext_csd.sa_timeout =
                                        1 << ext_csd[EXT_CSD_S_A_TIMEOUT];
+               card->ext_csd.erase_group_def =
+                       ext_csd[EXT_CSD_ERASE_GROUP_DEF];
+               card->ext_csd.hc_erase_timeout = 300 *
+                       ext_csd[EXT_CSD_ERASE_TIMEOUT_MULT];
+               card->ext_csd.hc_erase_size =
+                       ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] << 10;
+       }
+
+       if (card->ext_csd.rev >= 4) {
+               card->ext_csd.sec_trim_mult =
+                       ext_csd[EXT_CSD_SEC_TRIM_MULT];
+               card->ext_csd.sec_erase_mult =
+                       ext_csd[EXT_CSD_SEC_ERASE_MULT];
+               card->ext_csd.sec_feature_support =
+                       ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT];
+               card->ext_csd.trim_timeout = 300 *
+                       ext_csd[EXT_CSD_TRIM_MULT];
        }
 
+       if (ext_csd[EXT_CSD_ERASED_MEM_CONT])
+               card->erased_byte = 0xFF;
+       else
+               card->erased_byte = 0x0;
+
 out:
        kfree(ext_csd);
 
@@ -260,6 +313,8 @@ MMC_DEV_ATTR(cid, "%08x%08x%08x%08x\n", card->raw_cid[0], card->raw_cid[1],
 MMC_DEV_ATTR(csd, "%08x%08x%08x%08x\n", card->raw_csd[0], card->raw_csd[1],
        card->raw_csd[2], card->raw_csd[3]);
 MMC_DEV_ATTR(date, "%02d/%04d\n", card->cid.month, card->cid.year);
+MMC_DEV_ATTR(erase_size, "%u\n", card->erase_size << 9);
+MMC_DEV_ATTR(preferred_erase_size, "%u\n", card->pref_erase << 9);
 MMC_DEV_ATTR(fwrev, "0x%x\n", card->cid.fwrev);
 MMC_DEV_ATTR(hwrev, "0x%x\n", card->cid.hwrev);
 MMC_DEV_ATTR(manfid, "0x%06x\n", card->cid.manfid);
@@ -271,6 +326,8 @@ static struct attribute *mmc_std_attrs[] = {
        &dev_attr_cid.attr,
        &dev_attr_csd.attr,
        &dev_attr_date.attr,
+       &dev_attr_erase_size.attr,
+       &dev_attr_preferred_erase_size.attr,
        &dev_attr_fwrev.attr,
        &dev_attr_hwrev.attr,
        &dev_attr_manfid.attr,
@@ -322,7 +379,10 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
        err = mmc_send_op_cond(host, ocr | (1 << 30), NULL);
        if (err)
        {
-           printk("%s..%d..  ====*Identify the card as MMC , but OCR error, so fail to initialize.===xbw[%s]===\n", __FUNCTION__, __LINE__, mmc_hostname(host));
+#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) 
+           printk("%s..%d..  ====*Identify the card as MMC , but OCR error, so fail to initialize.===xbw[%s]===\n",\
+               __FUNCTION__, __LINE__, mmc_hostname(host));
+#endif         
                goto err;
        }
 
@@ -410,6 +470,8 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
                err = mmc_read_ext_csd(card);
                if (err)
                        goto free_card;
+               /* Erase size depends on CSD and Extended CSD */
+               mmc_set_erase_size(card);
        }
 
        /*
@@ -441,7 +503,10 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
                if (max_dtr > card->ext_csd.hs_max_dtr)
                        max_dtr = card->ext_csd.hs_max_dtr;
        } else if (max_dtr > card->csd.max_dtr) {
-               card->csd.max_dtr = (card->csd.max_dtr > MMC_FPP_FREQ) ? MMC_FPP_FREQ : (card->csd.max_dtr); //in order to expand the compatibility of card. Added by xbw@2011-03-21
+#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD)
+        //in order to expand the compatibility of card. Added by xbw@2011-03-21
+               card->csd.max_dtr = (card->csd.max_dtr > MMC_FPP_FREQ) ? MMC_FPP_FREQ : (card->csd.max_dtr); 
+#endif
                max_dtr = card->csd.max_dtr;
        }
 
@@ -606,25 +671,6 @@ static int mmc_awake(struct mmc_host *host)
        return err;
 }
 
-#ifdef CONFIG_MMC_UNSAFE_RESUME
-
-static const struct mmc_bus_ops mmc_ops = {
-       .awake = mmc_awake,
-       .sleep = mmc_sleep,
-       .remove = mmc_remove,
-       .detect = mmc_detect,
-       .suspend = mmc_suspend,
-       .resume = mmc_resume,
-       .power_restore = mmc_power_restore,
-};
-
-static void mmc_attach_bus_ops(struct mmc_host *host)
-{
-       mmc_attach_bus(host, &mmc_ops);
-}
-
-#else
-
 static const struct mmc_bus_ops mmc_ops = {
        .awake = mmc_awake,
        .sleep = mmc_sleep,
@@ -649,22 +695,22 @@ static void mmc_attach_bus_ops(struct mmc_host *host)
 {
        const struct mmc_bus_ops *bus_ops;
 
-       if (host->caps & MMC_CAP_NONREMOVABLE)
+       if (host->caps & MMC_CAP_NONREMOVABLE || !mmc_assume_removable)
                bus_ops = &mmc_ops_unsafe;
        else
                bus_ops = &mmc_ops;
        mmc_attach_bus(host, bus_ops);
 }
 
-#endif
-
 /*
  * Starting point for MMC card init.
  */
 int mmc_attach_mmc(struct mmc_host *host, u32 ocr)
 {
        int err;
+#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD)      
        int retry_times = 3;
+#endif 
 
        BUG_ON(!host);
        WARN_ON(!host->claimed);
@@ -709,14 +755,9 @@ int mmc_attach_mmc(struct mmc_host *host, u32 ocr)
                goto err;
 
        mmc_release_host(host);
-
-#if 0 // Deleted by xbw at 2011-04-09
-    err = mmc_add_card(host->card);
-       if (err)
-               goto remove_card;
-
-#else //modifyed by xbw at 2011--04-11
-
+#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD)
+//modifyed by xbw at 2011--04-11
 Retry_add:
        err = mmc_add_card(host->card);
        if (err)
@@ -735,6 +776,10 @@ Retry_add:
                goto remove_card;
     
        }
+#else
+    err = mmc_add_card(host->card);
+       if (err)
+               goto remove_card;
 #endif