root/drivers/mmc/core/mmc.c
// SPDX-License-Identifier: GPL-2.0-only
/*
 *  linux/drivers/mmc/core/mmc.c
 *
 *  Copyright (C) 2003-2004 Russell King, All Rights Reserved.
 *  Copyright (C) 2005-2007 Pierre Ossman, All Rights Reserved.
 *  MMCv4 support Copyright (C) 2006 Philip Langdale, All Rights Reserved.
 */

#include <linux/err.h>
#include <linux/of.h>
#include <linux/slab.h>
#include <linux/stat.h>
#include <linux/string.h>
#include <linux/pm_runtime.h>
#include <linux/random.h>
#include <linux/sysfs.h>

#include <linux/mmc/host.h>
#include <linux/mmc/card.h>
#include <linux/mmc/mmc.h>

#include "core.h"
#include "card.h"
#include "host.h"
#include "bus.h"
#include "mmc_ops.h"
#include "quirks.h"
#include "sd_ops.h"
#include "pwrseq.h"

#define DEFAULT_CMD6_TIMEOUT_MS 500
#define MIN_CACHE_EN_TIMEOUT_MS 1600
#define CACHE_FLUSH_TIMEOUT_MS 30000 /* 30s */

enum mmc_poweroff_type {
        MMC_POWEROFF_SUSPEND,
        MMC_POWEROFF_SHUTDOWN,
        MMC_POWEROFF_UNDERVOLTAGE,
        MMC_POWEROFF_UNBIND,
};

static const unsigned int tran_exp[] = {
        10000,          100000,         1000000,        10000000,
        0,              0,              0,              0
};

static const unsigned char tran_mant[] = {
        0,      10,     12,     13,     15,     20,     25,     30,
        35,     40,     45,     50,     55,     60,     70,     80,
};

static const unsigned int taac_exp[] = {
        1,      10,     100,    1000,   10000,  100000, 1000000, 10000000,
};

static const unsigned int taac_mant[] = {
        0,      10,     12,     13,     15,     20,     25,     30,
        35,     40,     45,     50,     55,     60,     70,     80,
};

/*
 * Given the decoded CSD structure, decode the raw CID to our CID structure.
 */
static int mmc_decode_cid(struct mmc_card *card)
{
        u32 *resp = card->raw_cid;

        /*
         * Add the raw card ID (cid) data to the entropy pool. It doesn't
         * matter that not all of it is unique, it's just bonus entropy.
         */
        add_device_randomness(&card->raw_cid, sizeof(card->raw_cid));

        /*
         * The selection of the format here is based upon published
         * specs from SanDisk and from what people have reported.
         */
        switch (card->csd.mmca_vsn) {
        case 0: /* MMC v1.0 - v1.2 */
        case 1: /* MMC v1.4 */
                card->cid.manfid        = unstuff_bits(resp, 104, 24);
                card->cid.prod_name[0]  = unstuff_bits(resp, 96, 8);
                card->cid.prod_name[1]  = unstuff_bits(resp, 88, 8);
                card->cid.prod_name[2]  = unstuff_bits(resp, 80, 8);
                card->cid.prod_name[3]  = unstuff_bits(resp, 72, 8);
                card->cid.prod_name[4]  = unstuff_bits(resp, 64, 8);
                card->cid.prod_name[5]  = unstuff_bits(resp, 56, 8);
                card->cid.prod_name[6]  = unstuff_bits(resp, 48, 8);
                card->cid.hwrev         = unstuff_bits(resp, 44, 4);
                card->cid.fwrev         = unstuff_bits(resp, 40, 4);
                card->cid.serial        = unstuff_bits(resp, 16, 24);
                card->cid.month         = unstuff_bits(resp, 12, 4);
                card->cid.year          = unstuff_bits(resp, 8, 4) + 1997;
                break;

        case 2: /* MMC v2.0 - v2.2 */
        case 3: /* MMC v3.1 - v3.3 */
        case 4: /* MMC v4 */
                card->cid.manfid        = unstuff_bits(resp, 120, 8);
                card->cid.oemid         = unstuff_bits(resp, 104, 16);
                card->cid.prod_name[0]  = unstuff_bits(resp, 96, 8);
                card->cid.prod_name[1]  = unstuff_bits(resp, 88, 8);
                card->cid.prod_name[2]  = unstuff_bits(resp, 80, 8);
                card->cid.prod_name[3]  = unstuff_bits(resp, 72, 8);
                card->cid.prod_name[4]  = unstuff_bits(resp, 64, 8);
                card->cid.prod_name[5]  = unstuff_bits(resp, 56, 8);
                card->cid.prv           = unstuff_bits(resp, 48, 8);
                card->cid.serial        = unstuff_bits(resp, 16, 32);
                card->cid.month         = unstuff_bits(resp, 12, 4);
                card->cid.year          = unstuff_bits(resp, 8, 4) + 1997;
                break;

        default:
                pr_err("%s: card has unknown MMCA version %d\n",
                        mmc_hostname(card->host), card->csd.mmca_vsn);
                return -EINVAL;
        }

        /* some product names include trailing whitespace */
        strim(card->cid.prod_name);

        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);
}


static void mmc_set_wp_grp_size(struct mmc_card *card)
{
        if (card->ext_csd.erase_group_def & 1)
                card->wp_grp_size = card->ext_csd.hc_erase_size *
                        card->ext_csd.raw_hc_erase_gap_size;
        else
                card->wp_grp_size = card->csd.erase_size *
                        (card->csd.wp_grp_size + 1);
}

/*
 * 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, 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->structure = unstuff_bits(resp, 126, 2);
        if (csd->structure == 0) {
                pr_err("%s: unrecognised CSD structure version %d\n",
                        mmc_hostname(card->host), csd->structure);
                return -EINVAL;
        }

        csd->mmca_vsn    = unstuff_bits(resp, 122, 4);
        m = unstuff_bits(resp, 115, 4);
        e = unstuff_bits(resp, 112, 3);
        csd->taac_ns     = (taac_exp[e] * taac_mant[m] + 9) / 10;
        csd->taac_clks   = unstuff_bits(resp, 104, 8) * 100;

        m = unstuff_bits(resp, 99, 4);
        e = unstuff_bits(resp, 96, 3);
        csd->max_dtr      = tran_exp[e] * tran_mant[m];
        csd->cmdclass     = unstuff_bits(resp, 84, 12);

        e = unstuff_bits(resp, 47, 3);
        m = unstuff_bits(resp, 62, 12);
        csd->capacity     = (1 + m) << (e + 2);

        csd->read_blkbits = unstuff_bits(resp, 80, 4);
        csd->read_partial = unstuff_bits(resp, 79, 1);
        csd->write_misalign = unstuff_bits(resp, 78, 1);
        csd->read_misalign = unstuff_bits(resp, 77, 1);
        csd->dsr_imp = unstuff_bits(resp, 76, 1);
        csd->r2w_factor = unstuff_bits(resp, 26, 3);
        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;
                csd->wp_grp_size = unstuff_bits(resp, 32, 5);
        }

        return 0;
}

static void mmc_select_card_type(struct mmc_card *card)
{
        struct mmc_host *host = card->host;
        u8 card_type = card->ext_csd.raw_card_type;
        u32 caps = host->caps, caps2 = host->caps2;
        unsigned int hs_max_dtr = 0, hs200_max_dtr = 0;
        unsigned int avail_type = 0;

        if (caps & MMC_CAP_MMC_HIGHSPEED &&
            card_type & EXT_CSD_CARD_TYPE_HS_26) {
                hs_max_dtr = MMC_HIGH_26_MAX_DTR;
                avail_type |= EXT_CSD_CARD_TYPE_HS_26;
        }

        if (caps & MMC_CAP_MMC_HIGHSPEED &&
            card_type & EXT_CSD_CARD_TYPE_HS_52) {
                hs_max_dtr = MMC_HIGH_52_MAX_DTR;
                avail_type |= EXT_CSD_CARD_TYPE_HS_52;
        }

        if (caps & (MMC_CAP_1_8V_DDR | MMC_CAP_3_3V_DDR) &&
            card_type & EXT_CSD_CARD_TYPE_DDR_1_8V) {
                hs_max_dtr = MMC_HIGH_DDR_MAX_DTR;
                avail_type |= EXT_CSD_CARD_TYPE_DDR_1_8V;
        }

        if (caps & MMC_CAP_1_2V_DDR &&
            card_type & EXT_CSD_CARD_TYPE_DDR_1_2V) {
                hs_max_dtr = MMC_HIGH_DDR_MAX_DTR;
                avail_type |= EXT_CSD_CARD_TYPE_DDR_1_2V;
        }

        if (caps2 & MMC_CAP2_HS200_1_8V_SDR &&
            card_type & EXT_CSD_CARD_TYPE_HS200_1_8V) {
                hs200_max_dtr = MMC_HS200_MAX_DTR;
                avail_type |= EXT_CSD_CARD_TYPE_HS200_1_8V;
        }

        if (caps2 & MMC_CAP2_HS200_1_2V_SDR &&
            card_type & EXT_CSD_CARD_TYPE_HS200_1_2V) {
                hs200_max_dtr = MMC_HS200_MAX_DTR;
                avail_type |= EXT_CSD_CARD_TYPE_HS200_1_2V;
        }

        if (caps2 & MMC_CAP2_HS400_1_8V &&
            card_type & EXT_CSD_CARD_TYPE_HS400_1_8V) {
                hs200_max_dtr = MMC_HS200_MAX_DTR;
                avail_type |= EXT_CSD_CARD_TYPE_HS400_1_8V;
        }

        if (caps2 & MMC_CAP2_HS400_1_2V &&
            card_type & EXT_CSD_CARD_TYPE_HS400_1_2V) {
                hs200_max_dtr = MMC_HS200_MAX_DTR;
                avail_type |= EXT_CSD_CARD_TYPE_HS400_1_2V;
        }

        if ((caps2 & MMC_CAP2_HS400_ES) &&
            card->ext_csd.strobe_support &&
            (avail_type & EXT_CSD_CARD_TYPE_HS400))
                avail_type |= EXT_CSD_CARD_TYPE_HS400ES;

        card->ext_csd.hs_max_dtr = hs_max_dtr;
        card->ext_csd.hs200_max_dtr = hs200_max_dtr;
        card->mmc_avail_type = avail_type;
}

static void mmc_manage_enhanced_area(struct mmc_card *card, u8 *ext_csd)
{
        u8 hc_erase_grp_sz, hc_wp_grp_sz;

        /*
         * Disable these attributes by default
         */
        card->ext_csd.enhanced_area_offset = -EINVAL;
        card->ext_csd.enhanced_area_size = -EINVAL;

        /*
         * Enhanced area feature support -- check whether the eMMC
         * card has the Enhanced area enabled.  If so, export enhanced
         * area offset and size to user by adding sysfs interface.
         */
        if ((ext_csd[EXT_CSD_PARTITION_SUPPORT] & 0x2) &&
            (ext_csd[EXT_CSD_PARTITION_ATTRIBUTE] & 0x1)) {
                if (card->ext_csd.partition_setting_completed) {
                        hc_erase_grp_sz =
                                ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
                        hc_wp_grp_sz =
                                ext_csd[EXT_CSD_HC_WP_GRP_SIZE];

                        /*
                         * calculate the enhanced data area offset, in bytes
                         */
                        card->ext_csd.enhanced_area_offset =
                                (((unsigned long long)ext_csd[139]) << 24) +
                                (((unsigned long long)ext_csd[138]) << 16) +
                                (((unsigned long long)ext_csd[137]) << 8) +
                                (((unsigned long long)ext_csd[136]));
                        if (mmc_card_blockaddr(card))
                                card->ext_csd.enhanced_area_offset <<= 9;
                        /*
                         * calculate the enhanced data area size, in kilobytes
                         */
                        card->ext_csd.enhanced_area_size =
                                (ext_csd[142] << 16) + (ext_csd[141] << 8) +
                                ext_csd[140];
                        card->ext_csd.enhanced_area_size *=
                                (size_t)(hc_erase_grp_sz * hc_wp_grp_sz);
                        card->ext_csd.enhanced_area_size <<= 9;
                } else {
                        pr_warn("%s: defines enhanced area without partition setting complete\n",
                                mmc_hostname(card->host));
                }
        }
}

static void mmc_part_add(struct mmc_card *card, u64 size,
                         unsigned int part_cfg, char *name, int idx, bool ro,
                         int area_type)
{
        card->part[card->nr_parts].size = size;
        card->part[card->nr_parts].part_cfg = part_cfg;
        sprintf(card->part[card->nr_parts].name, name, idx);
        card->part[card->nr_parts].force_ro = ro;
        card->part[card->nr_parts].area_type = area_type;
        card->nr_parts++;
}

static void mmc_manage_gp_partitions(struct mmc_card *card, u8 *ext_csd)
{
        int idx;
        u8 hc_erase_grp_sz, hc_wp_grp_sz;
        u64 part_size;

        /*
         * General purpose partition feature support --
         * If ext_csd has the size of general purpose partitions,
         * set size, part_cfg, partition name in mmc_part.
         */
        if (ext_csd[EXT_CSD_PARTITION_SUPPORT] &
            EXT_CSD_PART_SUPPORT_PART_EN) {
                hc_erase_grp_sz =
                        ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
                hc_wp_grp_sz =
                        ext_csd[EXT_CSD_HC_WP_GRP_SIZE];

                for (idx = 0; idx < MMC_NUM_GP_PARTITION; idx++) {
                        if (!ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3] &&
                            !ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3 + 1] &&
                            !ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3 + 2])
                                continue;
                        if (card->ext_csd.partition_setting_completed == 0) {
                                pr_warn("%s: has partition size defined without partition complete\n",
                                        mmc_hostname(card->host));
                                break;
                        }
                        part_size =
                                (ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3 + 2]
                                << 16) +
                                (ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3 + 1]
                                << 8) +
                                ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3];
                        part_size *= (hc_erase_grp_sz * hc_wp_grp_sz);
                        mmc_part_add(card, part_size << 19,
                                EXT_CSD_PART_CONFIG_ACC_GP0 + idx,
                                "gp%d", idx, false,
                                MMC_BLK_DATA_AREA_GP);
                }
        }
}

/* Minimum partition switch timeout in milliseconds */
#define MMC_MIN_PART_SWITCH_TIME        300

/*
 * Decode extended CSD.
 */
static int mmc_decode_ext_csd(struct mmc_card *card, u8 *ext_csd)
{
        int err = 0, idx;
        u64 part_size;
        struct device_node *np;
        bool broken_hpi = false;

        /* Version is coded in the CSD_STRUCTURE byte in the EXT_CSD register */
        card->ext_csd.raw_ext_csd_structure = ext_csd[EXT_CSD_STRUCTURE];
        if (card->csd.structure == 3) {
                if (card->ext_csd.raw_ext_csd_structure > 2) {
                        pr_err("%s: unrecognised EXT_CSD structure "
                                "version %d\n", mmc_hostname(card->host),
                                        card->ext_csd.raw_ext_csd_structure);
                        err = -EINVAL;
                        goto out;
                }
        }

        np = mmc_of_find_child_device(card->host, 0);
        if (np && of_device_is_compatible(np, "mmc-card"))
                broken_hpi = of_property_read_bool(np, "broken-hpi");
        of_node_put(np);

        /*
         * The EXT_CSD format is meant to be forward compatible. As long
         * as CSD_STRUCTURE does not change, all values for EXT_CSD_REV
         * are authorized, see JEDEC JESD84-B50 section B.8.
         */
        card->ext_csd.rev = ext_csd[EXT_CSD_REV];

        /* fixup device after ext_csd revision field is updated */
        mmc_fixup_device(card, mmc_ext_csd_fixups);

        card->ext_csd.raw_sectors[0] = ext_csd[EXT_CSD_SEC_CNT + 0];
        card->ext_csd.raw_sectors[1] = ext_csd[EXT_CSD_SEC_CNT + 1];
        card->ext_csd.raw_sectors[2] = ext_csd[EXT_CSD_SEC_CNT + 2];
        card->ext_csd.raw_sectors[3] = ext_csd[EXT_CSD_SEC_CNT + 3];
        if (card->ext_csd.rev >= 2) {
                card->ext_csd.sectors =
                        ext_csd[EXT_CSD_SEC_CNT + 0] << 0 |
                        ext_csd[EXT_CSD_SEC_CNT + 1] << 8 |
                        ext_csd[EXT_CSD_SEC_CNT + 2] << 16 |
                        ext_csd[EXT_CSD_SEC_CNT + 3] << 24;

                /* Cards with density > 2GiB are sector addressed */
                if (card->ext_csd.sectors > (2u * 1024 * 1024 * 1024) / 512)
                        mmc_card_set_blockaddr(card);
        }

        card->ext_csd.strobe_support = ext_csd[EXT_CSD_STROBE_SUPPORT];
        card->ext_csd.raw_card_type = ext_csd[EXT_CSD_CARD_TYPE];

        card->ext_csd.raw_s_a_timeout = ext_csd[EXT_CSD_S_A_TIMEOUT];
        card->ext_csd.raw_erase_timeout_mult =
                ext_csd[EXT_CSD_ERASE_TIMEOUT_MULT];
        card->ext_csd.raw_hc_erase_grp_size =
                ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
        card->ext_csd.raw_boot_mult =
                ext_csd[EXT_CSD_BOOT_MULT];
        if (card->ext_csd.rev >= 3) {
                u8 sa_shift = ext_csd[EXT_CSD_S_A_TIMEOUT];
                card->ext_csd.part_config = ext_csd[EXT_CSD_PART_CONFIG];

                /* EXT_CSD value is in units of 10ms, but we store in ms */
                card->ext_csd.part_time = 10 * ext_csd[EXT_CSD_PART_SWITCH_TIME];

                /* Sleep / awake timeout in 100ns units */
                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;

                card->ext_csd.rel_sectors = ext_csd[EXT_CSD_REL_WR_SEC_C];

                /*
                 * There are two boot regions of equal size, defined in
                 * multiples of 128K.
                 */
                if (ext_csd[EXT_CSD_BOOT_MULT] && mmc_host_can_access_boot(card->host)) {
                        for (idx = 0; idx < MMC_NUM_BOOT_PARTITION; idx++) {
                                part_size = ext_csd[EXT_CSD_BOOT_MULT] << 17;
                                mmc_part_add(card, part_size,
                                        EXT_CSD_PART_CONFIG_ACC_BOOT0 + idx,
                                        "boot%d", idx, true,
                                        MMC_BLK_DATA_AREA_BOOT);
                        }
                }
        }

        card->ext_csd.raw_hc_erase_gap_size =
                ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
        card->ext_csd.raw_sec_trim_mult =
                ext_csd[EXT_CSD_SEC_TRIM_MULT];
        card->ext_csd.raw_sec_erase_mult =
                ext_csd[EXT_CSD_SEC_ERASE_MULT];
        card->ext_csd.raw_sec_feature_support =
                ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT];
        card->ext_csd.raw_trim_mult =
                ext_csd[EXT_CSD_TRIM_MULT];
        card->ext_csd.raw_partition_support = ext_csd[EXT_CSD_PARTITION_SUPPORT];
        card->ext_csd.raw_driver_strength = ext_csd[EXT_CSD_DRIVER_STRENGTH];
        if (card->ext_csd.rev >= 4) {
                if (ext_csd[EXT_CSD_PARTITION_SETTING_COMPLETED] &
                    EXT_CSD_PART_SETTING_COMPLETED)
                        card->ext_csd.partition_setting_completed = 1;
                else
                        card->ext_csd.partition_setting_completed = 0;

                mmc_manage_enhanced_area(card, ext_csd);

                mmc_manage_gp_partitions(card, ext_csd);

                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];

                /*
                 * Note that the call to mmc_part_add above defaults to read
                 * only. If this default assumption is changed, the call must
                 * take into account the value of boot_locked below.
                 */
                card->ext_csd.boot_ro_lock = ext_csd[EXT_CSD_BOOT_WP];
                card->ext_csd.boot_ro_lockable = true;

                /* Save power class values */
                card->ext_csd.raw_pwr_cl_52_195 =
                        ext_csd[EXT_CSD_PWR_CL_52_195];
                card->ext_csd.raw_pwr_cl_26_195 =
                        ext_csd[EXT_CSD_PWR_CL_26_195];
                card->ext_csd.raw_pwr_cl_52_360 =
                        ext_csd[EXT_CSD_PWR_CL_52_360];
                card->ext_csd.raw_pwr_cl_26_360 =
                        ext_csd[EXT_CSD_PWR_CL_26_360];
                card->ext_csd.raw_pwr_cl_200_195 =
                        ext_csd[EXT_CSD_PWR_CL_200_195];
                card->ext_csd.raw_pwr_cl_200_360 =
                        ext_csd[EXT_CSD_PWR_CL_200_360];
                card->ext_csd.raw_pwr_cl_ddr_52_195 =
                        ext_csd[EXT_CSD_PWR_CL_DDR_52_195];
                card->ext_csd.raw_pwr_cl_ddr_52_360 =
                        ext_csd[EXT_CSD_PWR_CL_DDR_52_360];
                card->ext_csd.raw_pwr_cl_ddr_200_360 =
                        ext_csd[EXT_CSD_PWR_CL_DDR_200_360];
        }

        if (card->ext_csd.rev >= 5) {
                /* Adjust production date as per JEDEC JESD84-B451 */
                if (card->cid.year < 2010)
                        card->cid.year += 16;

                /* check whether the eMMC card supports BKOPS */
                if (ext_csd[EXT_CSD_BKOPS_SUPPORT] & 0x1) {
                        card->ext_csd.bkops = 1;
                        card->ext_csd.man_bkops_en =
                                        (ext_csd[EXT_CSD_BKOPS_EN] &
                                                EXT_CSD_MANUAL_BKOPS_MASK);
                        card->ext_csd.raw_bkops_status =
                                ext_csd[EXT_CSD_BKOPS_STATUS];
                        if (card->ext_csd.man_bkops_en)
                                pr_debug("%s: MAN_BKOPS_EN bit is set\n",
                                        mmc_hostname(card->host));
                        card->ext_csd.auto_bkops_en =
                                        (ext_csd[EXT_CSD_BKOPS_EN] &
                                                EXT_CSD_AUTO_BKOPS_MASK);
                        if (card->ext_csd.auto_bkops_en)
                                pr_debug("%s: AUTO_BKOPS_EN bit is set\n",
                                        mmc_hostname(card->host));
                }

                /* check whether the eMMC card supports HPI */
                if (!mmc_card_broken_hpi(card) &&
                    !broken_hpi && (ext_csd[EXT_CSD_HPI_FEATURES] & 0x1)) {
                        card->ext_csd.hpi = 1;
                        if (ext_csd[EXT_CSD_HPI_FEATURES] & 0x2)
                                card->ext_csd.hpi_cmd = MMC_STOP_TRANSMISSION;
                        else
                                card->ext_csd.hpi_cmd = MMC_SEND_STATUS;
                        /*
                         * Indicate the maximum timeout to close
                         * a command interrupted by HPI
                         */
                        card->ext_csd.out_of_int_time =
                                ext_csd[EXT_CSD_OUT_OF_INTERRUPT_TIME] * 10;
                }

                card->ext_csd.rel_param = ext_csd[EXT_CSD_WR_REL_PARAM];
                card->ext_csd.rst_n_function = ext_csd[EXT_CSD_RST_N_FUNCTION];

                /*
                 * RPMB regions are defined in multiples of 128K.
                 */
                card->ext_csd.raw_rpmb_size_mult = ext_csd[EXT_CSD_RPMB_MULT];
                if (ext_csd[EXT_CSD_RPMB_MULT] && mmc_host_can_cmd23(card->host)) {
                        mmc_part_add(card, ext_csd[EXT_CSD_RPMB_MULT] << 17,
                                EXT_CSD_PART_CONFIG_ACC_RPMB,
                                "rpmb", 0, false,
                                MMC_BLK_DATA_AREA_RPMB);
                }
        }

        card->ext_csd.raw_erased_mem_count = ext_csd[EXT_CSD_ERASED_MEM_CONT];
        if (ext_csd[EXT_CSD_ERASED_MEM_CONT])
                card->erased_byte = 0xFF;
        else
                card->erased_byte = 0x0;

        /* eMMC v4.5 or later */
        card->ext_csd.generic_cmd6_time = DEFAULT_CMD6_TIMEOUT_MS;
        if (card->ext_csd.rev >= 6) {
                card->ext_csd.feature_support |= MMC_DISCARD_FEATURE;

                card->ext_csd.generic_cmd6_time = 10 *
                        ext_csd[EXT_CSD_GENERIC_CMD6_TIME];
                card->ext_csd.power_off_longtime = 10 *
                        ext_csd[EXT_CSD_POWER_OFF_LONG_TIME];

                card->ext_csd.cache_size =
                        ext_csd[EXT_CSD_CACHE_SIZE + 0] << 0 |
                        ext_csd[EXT_CSD_CACHE_SIZE + 1] << 8 |
                        ext_csd[EXT_CSD_CACHE_SIZE + 2] << 16 |
                        ext_csd[EXT_CSD_CACHE_SIZE + 3] << 24;

                if (ext_csd[EXT_CSD_DATA_SECTOR_SIZE] == 1)
                        card->ext_csd.data_sector_size = 4096;
                else
                        card->ext_csd.data_sector_size = 512;

                if ((ext_csd[EXT_CSD_DATA_TAG_SUPPORT] & 1) &&
                    (ext_csd[EXT_CSD_TAG_UNIT_SIZE] <= 8)) {
                        card->ext_csd.data_tag_unit_size =
                        ((unsigned int) 1 << ext_csd[EXT_CSD_TAG_UNIT_SIZE]) *
                        (card->ext_csd.data_sector_size);
                } else {
                        card->ext_csd.data_tag_unit_size = 0;
                }
        } else {
                card->ext_csd.data_sector_size = 512;
        }

        /*
         * GENERIC_CMD6_TIME is to be used "unless a specific timeout is defined
         * when accessing a specific field", so use it here if there is no
         * PARTITION_SWITCH_TIME.
         */
        if (!card->ext_csd.part_time)
                card->ext_csd.part_time = card->ext_csd.generic_cmd6_time;
        /* Some eMMC set the value too low so set a minimum */
        if (card->ext_csd.part_time < MMC_MIN_PART_SWITCH_TIME)
                card->ext_csd.part_time = MMC_MIN_PART_SWITCH_TIME;

        /* eMMC v5 or later */
        if (card->ext_csd.rev >= 7) {
                memcpy(card->ext_csd.fwrev, &ext_csd[EXT_CSD_FIRMWARE_VERSION],
                       MMC_FIRMWARE_LEN);
                card->ext_csd.ffu_capable =
                        (ext_csd[EXT_CSD_SUPPORTED_MODE] & 0x1) &&
                        !(ext_csd[EXT_CSD_FW_CONFIG] & 0x1);

                card->ext_csd.pre_eol_info = ext_csd[EXT_CSD_PRE_EOL_INFO];
                card->ext_csd.device_life_time_est_typ_a =
                        ext_csd[EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_A];
                card->ext_csd.device_life_time_est_typ_b =
                        ext_csd[EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_B];
        }

        /* eMMC v5.1 or later */
        if (card->ext_csd.rev >= 8) {
                card->ext_csd.cmdq_support = ext_csd[EXT_CSD_CMDQ_SUPPORT] &
                                             EXT_CSD_CMDQ_SUPPORTED;
                card->ext_csd.cmdq_depth = (ext_csd[EXT_CSD_CMDQ_DEPTH] &
                                            EXT_CSD_CMDQ_DEPTH_MASK) + 1;
                /* Exclude inefficiently small queue depths */
                if (card->ext_csd.cmdq_depth <= 2) {
                        card->ext_csd.cmdq_support = false;
                        card->ext_csd.cmdq_depth = 0;
                }
                if (card->ext_csd.cmdq_support) {
                        pr_debug("%s: Command Queue supported depth %u\n",
                                 mmc_hostname(card->host),
                                 card->ext_csd.cmdq_depth);
                }
                card->ext_csd.enhanced_rpmb_supported =
                                        (card->ext_csd.rel_param &
                                         EXT_CSD_WR_REL_PARAM_EN_RPMB_REL_WR);
        }
out:
        return err;
}

static int mmc_read_ext_csd(struct mmc_card *card)
{
        u8 *ext_csd;
        int err;

        if (!mmc_card_can_ext_csd(card))
                return 0;

        err = mmc_get_ext_csd(card, &ext_csd);
        if (err) {
                /* If the host or the card can't do the switch,
                 * fail more gracefully. */
                if ((err != -EINVAL)
                 && (err != -ENOSYS)
                 && (err != -EFAULT))
                        return err;

                /*
                 * High capacity cards should have this "magic" size
                 * stored in their CSD.
                 */
                if (card->csd.capacity == (4096 * 512)) {
                        pr_err("%s: unable to read EXT_CSD on a possible high capacity card. Card will be ignored.\n",
                                mmc_hostname(card->host));
                } else {
                        pr_warn("%s: unable to read EXT_CSD, performance might suffer\n",
                                mmc_hostname(card->host));
                        err = 0;
                }

                return err;
        }

        err = mmc_decode_ext_csd(card, ext_csd);
        kfree(ext_csd);
        return err;
}

static int mmc_compare_ext_csds(struct mmc_card *card, unsigned bus_width)
{
        u8 *bw_ext_csd;
        int err;

        if (bus_width == MMC_BUS_WIDTH_1)
                return 0;

        err = mmc_get_ext_csd(card, &bw_ext_csd);
        if (err)
                return err;

        /* only compare read only fields */
        err = !((card->ext_csd.raw_partition_support ==
                        bw_ext_csd[EXT_CSD_PARTITION_SUPPORT]) &&
                (card->ext_csd.raw_erased_mem_count ==
                        bw_ext_csd[EXT_CSD_ERASED_MEM_CONT]) &&
                (card->ext_csd.rev ==
                        bw_ext_csd[EXT_CSD_REV]) &&
                (card->ext_csd.raw_ext_csd_structure ==
                        bw_ext_csd[EXT_CSD_STRUCTURE]) &&
                (card->ext_csd.raw_card_type ==
                        bw_ext_csd[EXT_CSD_CARD_TYPE]) &&
                (card->ext_csd.raw_s_a_timeout ==
                        bw_ext_csd[EXT_CSD_S_A_TIMEOUT]) &&
                (card->ext_csd.raw_hc_erase_gap_size ==
                        bw_ext_csd[EXT_CSD_HC_WP_GRP_SIZE]) &&
                (card->ext_csd.raw_erase_timeout_mult ==
                        bw_ext_csd[EXT_CSD_ERASE_TIMEOUT_MULT]) &&
                (card->ext_csd.raw_hc_erase_grp_size ==
                        bw_ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]) &&
                (card->ext_csd.raw_sec_trim_mult ==
                        bw_ext_csd[EXT_CSD_SEC_TRIM_MULT]) &&
                (card->ext_csd.raw_sec_erase_mult ==
                        bw_ext_csd[EXT_CSD_SEC_ERASE_MULT]) &&
                (card->ext_csd.raw_sec_feature_support ==
                        bw_ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT]) &&
                (card->ext_csd.raw_trim_mult ==
                        bw_ext_csd[EXT_CSD_TRIM_MULT]) &&
                (card->ext_csd.raw_sectors[0] ==
                        bw_ext_csd[EXT_CSD_SEC_CNT + 0]) &&
                (card->ext_csd.raw_sectors[1] ==
                        bw_ext_csd[EXT_CSD_SEC_CNT + 1]) &&
                (card->ext_csd.raw_sectors[2] ==
                        bw_ext_csd[EXT_CSD_SEC_CNT + 2]) &&
                (card->ext_csd.raw_sectors[3] ==
                        bw_ext_csd[EXT_CSD_SEC_CNT + 3]) &&
                (card->ext_csd.raw_pwr_cl_52_195 ==
                        bw_ext_csd[EXT_CSD_PWR_CL_52_195]) &&
                (card->ext_csd.raw_pwr_cl_26_195 ==
                        bw_ext_csd[EXT_CSD_PWR_CL_26_195]) &&
                (card->ext_csd.raw_pwr_cl_52_360 ==
                        bw_ext_csd[EXT_CSD_PWR_CL_52_360]) &&
                (card->ext_csd.raw_pwr_cl_26_360 ==
                        bw_ext_csd[EXT_CSD_PWR_CL_26_360]) &&
                (card->ext_csd.raw_pwr_cl_200_195 ==
                        bw_ext_csd[EXT_CSD_PWR_CL_200_195]) &&
                (card->ext_csd.raw_pwr_cl_200_360 ==
                        bw_ext_csd[EXT_CSD_PWR_CL_200_360]) &&
                (card->ext_csd.raw_pwr_cl_ddr_52_195 ==
                        bw_ext_csd[EXT_CSD_PWR_CL_DDR_52_195]) &&
                (card->ext_csd.raw_pwr_cl_ddr_52_360 ==
                        bw_ext_csd[EXT_CSD_PWR_CL_DDR_52_360]) &&
                (card->ext_csd.raw_pwr_cl_ddr_200_360 ==
                        bw_ext_csd[EXT_CSD_PWR_CL_DDR_200_360]));

        if (err)
                err = -EINVAL;

        kfree(bw_ext_csd);
        return err;
}

MMC_DEV_ATTR(cid, "%08x%08x%08x%08x\n", card->raw_cid[0], card->raw_cid[1],
        card->raw_cid[2], card->raw_cid[3]);
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(wp_grp_size, "%u\n", card->wp_grp_size << 9);
MMC_DEV_ATTR(ffu_capable, "%d\n", card->ext_csd.ffu_capable);
MMC_DEV_ATTR(hwrev, "0x%x\n", card->cid.hwrev);
MMC_DEV_ATTR(manfid, "0x%06x\n", card->cid.manfid);
MMC_DEV_ATTR(name, "%s\n", card->cid.prod_name);
MMC_DEV_ATTR(oemid, "0x%04x\n", card->cid.oemid);
MMC_DEV_ATTR(prv, "0x%x\n", card->cid.prv);
MMC_DEV_ATTR(rev, "0x%x\n", card->ext_csd.rev);
MMC_DEV_ATTR(pre_eol_info, "0x%02x\n", card->ext_csd.pre_eol_info);
MMC_DEV_ATTR(life_time, "0x%02x 0x%02x\n",
        card->ext_csd.device_life_time_est_typ_a,
        card->ext_csd.device_life_time_est_typ_b);
MMC_DEV_ATTR(serial, "0x%08x\n", card->cid.serial);
MMC_DEV_ATTR(enhanced_area_offset, "%llu\n",
                card->ext_csd.enhanced_area_offset);
MMC_DEV_ATTR(enhanced_area_size, "%u\n", card->ext_csd.enhanced_area_size);
MMC_DEV_ATTR(raw_rpmb_size_mult, "%#x\n", card->ext_csd.raw_rpmb_size_mult);
MMC_DEV_ATTR(enhanced_rpmb_supported, "%#x\n",
        card->ext_csd.enhanced_rpmb_supported);
MMC_DEV_ATTR(rel_sectors, "%#x\n", card->ext_csd.rel_sectors);
MMC_DEV_ATTR(ocr, "0x%08x\n", card->ocr);
MMC_DEV_ATTR(rca, "0x%04x\n", card->rca);
MMC_DEV_ATTR(cmdq_en, "%d\n", card->ext_csd.cmdq_en);

static ssize_t mmc_fwrev_show(struct device *dev,
                              struct device_attribute *attr,
                              char *buf)
{
        struct mmc_card *card = mmc_dev_to_card(dev);

        if (card->ext_csd.rev < 7)
                return sysfs_emit(buf, "0x%x\n", card->cid.fwrev);
        else
                return sysfs_emit(buf, "0x%*phN\n", MMC_FIRMWARE_LEN,
                                  card->ext_csd.fwrev);
}

static DEVICE_ATTR(fwrev, 0444, mmc_fwrev_show, NULL);

static ssize_t mmc_dsr_show(struct device *dev,
                            struct device_attribute *attr,
                            char *buf)
{
        struct mmc_card *card = mmc_dev_to_card(dev);
        struct mmc_host *host = card->host;

        if (card->csd.dsr_imp && host->dsr_req)
                return sysfs_emit(buf, "0x%x\n", host->dsr);
        else
                /* return default DSR value */
                return sysfs_emit(buf, "0x%x\n", 0x404);
}

static DEVICE_ATTR(dsr, 0444, mmc_dsr_show, NULL);

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_wp_grp_size.attr,
        &dev_attr_fwrev.attr,
        &dev_attr_ffu_capable.attr,
        &dev_attr_hwrev.attr,
        &dev_attr_manfid.attr,
        &dev_attr_name.attr,
        &dev_attr_oemid.attr,
        &dev_attr_prv.attr,
        &dev_attr_rev.attr,
        &dev_attr_pre_eol_info.attr,
        &dev_attr_life_time.attr,
        &dev_attr_serial.attr,
        &dev_attr_enhanced_area_offset.attr,
        &dev_attr_enhanced_area_size.attr,
        &dev_attr_raw_rpmb_size_mult.attr,
        &dev_attr_enhanced_rpmb_supported.attr,
        &dev_attr_rel_sectors.attr,
        &dev_attr_ocr.attr,
        &dev_attr_rca.attr,
        &dev_attr_dsr.attr,
        &dev_attr_cmdq_en.attr,
        NULL,
};
ATTRIBUTE_GROUPS(mmc_std);

static const struct device_type mmc_type = {
        .groups = mmc_std_groups,
};

/*
 * Select the PowerClass for the current bus width
 * If power class is defined for 4/8 bit bus in the
 * extended CSD register, select it by executing the
 * mmc_switch command.
 */
static int __mmc_select_powerclass(struct mmc_card *card,
                                   unsigned int bus_width)
{
        struct mmc_host *host = card->host;
        struct mmc_ext_csd *ext_csd = &card->ext_csd;
        unsigned int pwrclass_val = 0;
        int err = 0;

        switch (1 << host->ios.vdd) {
        case MMC_VDD_165_195:
                if (host->ios.clock <= MMC_HIGH_26_MAX_DTR)
                        pwrclass_val = ext_csd->raw_pwr_cl_26_195;
                else if (host->ios.clock <= MMC_HIGH_52_MAX_DTR)
                        pwrclass_val = (bus_width <= EXT_CSD_BUS_WIDTH_8) ?
                                ext_csd->raw_pwr_cl_52_195 :
                                ext_csd->raw_pwr_cl_ddr_52_195;
                else if (host->ios.clock <= MMC_HS200_MAX_DTR)
                        pwrclass_val = ext_csd->raw_pwr_cl_200_195;
                break;
        case MMC_VDD_27_28:
        case MMC_VDD_28_29:
        case MMC_VDD_29_30:
        case MMC_VDD_30_31:
        case MMC_VDD_31_32:
        case MMC_VDD_32_33:
        case MMC_VDD_33_34:
        case MMC_VDD_34_35:
        case MMC_VDD_35_36:
                if (host->ios.clock <= MMC_HIGH_26_MAX_DTR)
                        pwrclass_val = ext_csd->raw_pwr_cl_26_360;
                else if (host->ios.clock <= MMC_HIGH_52_MAX_DTR)
                        pwrclass_val = (bus_width <= EXT_CSD_BUS_WIDTH_8) ?
                                ext_csd->raw_pwr_cl_52_360 :
                                ext_csd->raw_pwr_cl_ddr_52_360;
                else if (host->ios.clock <= MMC_HS200_MAX_DTR)
                        pwrclass_val = (bus_width == EXT_CSD_DDR_BUS_WIDTH_8) ?
                                ext_csd->raw_pwr_cl_ddr_200_360 :
                                ext_csd->raw_pwr_cl_200_360;
                break;
        default:
                pr_warn("%s: Voltage range not supported for power class\n",
                        mmc_hostname(host));
                return -EINVAL;
        }

        if (bus_width & (EXT_CSD_BUS_WIDTH_8 | EXT_CSD_DDR_BUS_WIDTH_8))
                pwrclass_val = (pwrclass_val & EXT_CSD_PWR_CL_8BIT_MASK) >>
                                EXT_CSD_PWR_CL_8BIT_SHIFT;
        else
                pwrclass_val = (pwrclass_val & EXT_CSD_PWR_CL_4BIT_MASK) >>
                                EXT_CSD_PWR_CL_4BIT_SHIFT;

        /* If the power class is different from the default value */
        if (pwrclass_val > 0) {
                err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
                                 EXT_CSD_POWER_CLASS,
                                 pwrclass_val,
                                 card->ext_csd.generic_cmd6_time);
        }

        return err;
}

static int mmc_select_powerclass(struct mmc_card *card)
{
        struct mmc_host *host = card->host;
        u32 bus_width, ext_csd_bits;
        int err, ddr;

        /* Power class selection is supported for versions >= 4.0 */
        if (!mmc_card_can_ext_csd(card))
                return 0;

        bus_width = host->ios.bus_width;
        /* Power class values are defined only for 4/8 bit bus */
        if (bus_width == MMC_BUS_WIDTH_1)
                return 0;

        ddr = card->mmc_avail_type & EXT_CSD_CARD_TYPE_DDR_52;
        if (ddr)
                ext_csd_bits = (bus_width == MMC_BUS_WIDTH_8) ?
                        EXT_CSD_DDR_BUS_WIDTH_8 : EXT_CSD_DDR_BUS_WIDTH_4;
        else
                ext_csd_bits = (bus_width == MMC_BUS_WIDTH_8) ?
                        EXT_CSD_BUS_WIDTH_8 :  EXT_CSD_BUS_WIDTH_4;

        err = __mmc_select_powerclass(card, ext_csd_bits);
        if (err)
                pr_warn("%s: power class selection to bus width %d ddr %d failed\n",
                        mmc_hostname(host), 1 << bus_width, ddr);

        return err;
}

/*
 * Set the bus speed for the selected speed mode.
 */
static void mmc_set_bus_speed(struct mmc_card *card)
{
        unsigned int max_dtr = (unsigned int)-1;

        if ((mmc_card_hs200(card) || mmc_card_hs400(card)) &&
             max_dtr > card->ext_csd.hs200_max_dtr)
                max_dtr = card->ext_csd.hs200_max_dtr;
        else if (mmc_card_hs(card) && max_dtr > card->ext_csd.hs_max_dtr)
                max_dtr = card->ext_csd.hs_max_dtr;
        else if (max_dtr > card->csd.max_dtr)
                max_dtr = card->csd.max_dtr;

        mmc_set_clock(card->host, max_dtr);
}

/*
 * Select the bus width amoung 4-bit and 8-bit(SDR).
 * If the bus width is changed successfully, return the selected width value.
 * Zero is returned instead of error value if the wide width is not supported.
 */
static int mmc_select_bus_width(struct mmc_card *card)
{
        static unsigned ext_csd_bits[] = {
                EXT_CSD_BUS_WIDTH_8,
                EXT_CSD_BUS_WIDTH_4,
                EXT_CSD_BUS_WIDTH_1,
        };
        static unsigned bus_widths[] = {
                MMC_BUS_WIDTH_8,
                MMC_BUS_WIDTH_4,
                MMC_BUS_WIDTH_1,
        };
        struct mmc_host *host = card->host;
        unsigned idx, bus_width = 0;
        int err = 0;

        if (!mmc_card_can_ext_csd(card) ||
            !(host->caps & (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA)))
                return 0;

        idx = (host->caps & MMC_CAP_8_BIT_DATA) ? 0 : 1;

        /*
         * Unlike SD, MMC cards dont have a configuration register to notify
         * supported bus width. So bus test command should be run to identify
         * the supported bus width or compare the ext csd values of current
         * bus width and ext csd values of 1 bit mode read earlier.
         */
        for (; idx < ARRAY_SIZE(bus_widths); idx++) {
                /*
                 * Host is capable of 8bit transfer, then switch
                 * the device to work in 8bit transfer mode. If the
                 * mmc switch command returns error then switch to
                 * 4bit transfer mode. On success set the corresponding
                 * bus width on the host.
                 */
                err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
                                 EXT_CSD_BUS_WIDTH,
                                 ext_csd_bits[idx],
                                 card->ext_csd.generic_cmd6_time);
                if (err)
                        continue;

                bus_width = bus_widths[idx];
                mmc_set_bus_width(host, bus_width);

                /*
                 * If controller can't handle bus width test,
                 * compare ext_csd previously read in 1 bit mode
                 * against ext_csd at new bus width
                 */
                if (!(host->caps & MMC_CAP_BUS_WIDTH_TEST))
                        err = mmc_compare_ext_csds(card, bus_width);
                else
                        err = mmc_bus_test(card, bus_width);

                if (!err) {
                        err = bus_width;
                        break;
                } else {
                        pr_warn("%s: switch to bus width %d failed\n",
                                mmc_hostname(host), 1 << bus_width);
                }
        }

        return err;
}

/*
 * Switch to the high-speed mode
 */
static int mmc_select_hs(struct mmc_card *card)
{
        int err;

        err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
                           EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS,
                           card->ext_csd.generic_cmd6_time, MMC_TIMING_MMC_HS,
                           true, true, MMC_CMD_RETRIES);
        if (err)
                pr_warn("%s: switch to high-speed failed, err:%d\n",
                        mmc_hostname(card->host), err);

        return err;
}

/*
 * Activate wide bus and DDR if supported.
 */
static int mmc_select_hs_ddr(struct mmc_card *card)
{
        struct mmc_host *host = card->host;
        u32 bus_width, ext_csd_bits;
        int err = 0;

        if (!(card->mmc_avail_type & EXT_CSD_CARD_TYPE_DDR_52))
                return 0;

        bus_width = host->ios.bus_width;
        if (bus_width == MMC_BUS_WIDTH_1)
                return 0;

        ext_csd_bits = (bus_width == MMC_BUS_WIDTH_8) ?
                EXT_CSD_DDR_BUS_WIDTH_8 : EXT_CSD_DDR_BUS_WIDTH_4;

        err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
                           EXT_CSD_BUS_WIDTH,
                           ext_csd_bits,
                           card->ext_csd.generic_cmd6_time,
                           MMC_TIMING_MMC_DDR52,
                           true, true, MMC_CMD_RETRIES);
        if (err) {
                pr_err("%s: switch to bus width %d ddr failed\n",
                        mmc_hostname(host), 1 << bus_width);
                return err;
        }

        /*
         * eMMC cards can support 3.3V to 1.2V i/o (vccq)
         * signaling.
         *
         * EXT_CSD_CARD_TYPE_DDR_1_8V means 3.3V or 1.8V vccq.
         *
         * 1.8V vccq at 3.3V core voltage (vcc) is not required
         * in the JEDEC spec for DDR.
         *
         * Even (e)MMC card can support 3.3v to 1.2v vccq, but not all
         * host controller can support this, like some of the SDHCI
         * controller which connect to an eMMC device. Some of these
         * host controller still needs to use 1.8v vccq for supporting
         * DDR mode.
         *
         * So the sequence will be:
         * if (host and device can both support 1.2v IO)
         *      use 1.2v IO;
         * else if (host and device can both support 1.8v IO)
         *      use 1.8v IO;
         * so if host and device can only support 3.3v IO, this is the
         * last choice.
         *
         * WARNING: eMMC rules are NOT the same as SD DDR
         */
        if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_DDR_1_2V) {
                err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120);
                if (!err)
                        return 0;
        }

        if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_DDR_1_8V &&
            host->caps & MMC_CAP_1_8V_DDR)
                err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180);

        /* make sure vccq is 3.3v after switching disaster */
        if (err)
                err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_330);

        return err;
}

static int mmc_select_hs400(struct mmc_card *card)
{
        struct mmc_host *host = card->host;
        unsigned int max_dtr;
        int err = 0;
        u8 val;

        /*
         * HS400 mode requires 8-bit bus width
         */
        if (!(card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400 &&
              host->ios.bus_width == MMC_BUS_WIDTH_8))
                return 0;

        /* Switch card to HS mode */
        val = EXT_CSD_TIMING_HS;
        err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
                           EXT_CSD_HS_TIMING, val,
                           card->ext_csd.generic_cmd6_time, 0,
                           false, true, MMC_CMD_RETRIES);
        if (err) {
                pr_err("%s: switch to high-speed from hs200 failed, err:%d\n",
                        mmc_hostname(host), err);
                return err;
        }

        /* Prepare host to downgrade to HS timing */
        if (host->ops->hs400_downgrade)
                host->ops->hs400_downgrade(host);

        /* Set host controller to HS timing */
        mmc_set_timing(host, MMC_TIMING_MMC_HS);

        /* Reduce frequency to HS frequency */
        max_dtr = card->ext_csd.hs_max_dtr;
        mmc_set_clock(host, max_dtr);

        err = mmc_switch_status(card, true);
        if (err)
                goto out_err;

        if (host->ops->hs400_prepare_ddr)
                host->ops->hs400_prepare_ddr(host);

        /* Switch card to DDR */
        err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
                         EXT_CSD_BUS_WIDTH,
                         EXT_CSD_DDR_BUS_WIDTH_8,
                         card->ext_csd.generic_cmd6_time);
        if (err) {
                pr_err("%s: switch to bus width for hs400 failed, err:%d\n",
                        mmc_hostname(host), err);
                return err;
        }

        /* Switch card to HS400 */
        val = EXT_CSD_TIMING_HS400 |
              card->drive_strength << EXT_CSD_DRV_STR_SHIFT;
        err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
                           EXT_CSD_HS_TIMING, val,
                           card->ext_csd.generic_cmd6_time, 0,
                           false, true, MMC_CMD_RETRIES);
        if (err) {
                pr_err("%s: switch to hs400 failed, err:%d\n",
                         mmc_hostname(host), err);
                return err;
        }

        /* Set host controller to HS400 timing and frequency */
        mmc_set_timing(host, MMC_TIMING_MMC_HS400);
        mmc_set_bus_speed(card);

        if (host->ops->execute_hs400_tuning) {
                mmc_retune_disable(host);
                err = host->ops->execute_hs400_tuning(host, card);
                mmc_retune_enable(host);
                if (err)
                        goto out_err;
        }

        if (host->ops->hs400_complete)
                host->ops->hs400_complete(host);

        err = mmc_switch_status(card, true);
        if (err)
                goto out_err;

        return 0;

out_err:
        pr_err("%s: %s failed, error %d\n", mmc_hostname(card->host),
               __func__, err);
        return err;
}

int mmc_hs200_to_hs400(struct mmc_card *card)
{
        return mmc_select_hs400(card);
}

int mmc_hs400_to_hs200(struct mmc_card *card)
{
        struct mmc_host *host = card->host;
        unsigned int max_dtr;
        int err;
        u8 val;

        /* Reduce frequency to HS */
        max_dtr = card->ext_csd.hs_max_dtr;
        mmc_set_clock(host, max_dtr);

        /* Switch HS400 to HS DDR */
        val = EXT_CSD_TIMING_HS;
        err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING,
                           val, card->ext_csd.generic_cmd6_time, 0,
                           false, true, MMC_CMD_RETRIES);
        if (err)
                goto out_err;

        if (host->ops->hs400_downgrade)
                host->ops->hs400_downgrade(host);

        mmc_set_timing(host, MMC_TIMING_MMC_DDR52);

        err = mmc_switch_status(card, true);
        if (err)
                goto out_err;

        /* Switch HS DDR to HS */
        err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH,
                           EXT_CSD_BUS_WIDTH_8, card->ext_csd.generic_cmd6_time,
                           0, false, true, MMC_CMD_RETRIES);
        if (err)
                goto out_err;

        mmc_set_timing(host, MMC_TIMING_MMC_HS);

        err = mmc_switch_status(card, true);
        if (err)
                goto out_err;

        /* Switch HS to HS200 */
        val = EXT_CSD_TIMING_HS200 |
              card->drive_strength << EXT_CSD_DRV_STR_SHIFT;
        err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING,
                           val, card->ext_csd.generic_cmd6_time, 0,
                           false, true, MMC_CMD_RETRIES);
        if (err)
                goto out_err;

        mmc_set_timing(host, MMC_TIMING_MMC_HS200);

        /*
         * For HS200, CRC errors are not a reliable way to know the switch
         * failed. If there really is a problem, we would expect tuning will
         * fail and the result ends up the same.
         */
        err = mmc_switch_status(card, false);
        if (err)
                goto out_err;

        mmc_set_bus_speed(card);

        /* Prepare tuning for HS400 mode. */
        if (host->ops->prepare_hs400_tuning)
                host->ops->prepare_hs400_tuning(host, &host->ios);

        return 0;

out_err:
        pr_err("%s: %s failed, error %d\n", mmc_hostname(card->host),
               __func__, err);
        return err;
}

static void mmc_select_driver_type(struct mmc_card *card)
{
        int card_drv_type, drive_strength, drv_type = 0;
        int fixed_drv_type = card->host->fixed_drv_type;

        card_drv_type = card->ext_csd.raw_driver_strength |
                        mmc_driver_type_mask(0);

        if (fixed_drv_type >= 0)
                drive_strength = card_drv_type & mmc_driver_type_mask(fixed_drv_type)
                                 ? fixed_drv_type : 0;
        else
                drive_strength = mmc_select_drive_strength(card,
                                                           card->ext_csd.hs200_max_dtr,
                                                           card_drv_type, &drv_type);

        card->drive_strength = drive_strength;

        if (drv_type)
                mmc_set_driver_type(card->host, drv_type);
}

static int mmc_select_hs400es(struct mmc_card *card)
{
        struct mmc_host *host = card->host;
        int err = -EINVAL;
        u8 val;

        if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400_1_2V)
                err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120);

        if (err && card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400_1_8V)
                err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180);

        /* If fails try again during next card power cycle */
        if (err)
                goto out_err;

        err = mmc_select_bus_width(card);
        if (err != MMC_BUS_WIDTH_8) {
                pr_err("%s: switch to 8bit bus width failed, err:%d\n",
                        mmc_hostname(host), err);
                err = err < 0 ? err : -ENOTSUPP;
                goto out_err;
        }

        /* Switch card to HS mode */
        err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
                           EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS,
                           card->ext_csd.generic_cmd6_time, 0,
                           false, true, MMC_CMD_RETRIES);
        if (err) {
                pr_err("%s: switch to hs for hs400es failed, err:%d\n",
                        mmc_hostname(host), err);
                goto out_err;
        }

        /*
         * Bump to HS timing and frequency. Some cards don't handle
         * SEND_STATUS reliably at the initial frequency.
         */
        mmc_set_timing(host, MMC_TIMING_MMC_HS);
        mmc_set_bus_speed(card);

        err = mmc_switch_status(card, true);
        if (err)
                goto out_err;

        /* Switch card to DDR with strobe bit */
        val = EXT_CSD_DDR_BUS_WIDTH_8 | EXT_CSD_BUS_WIDTH_STROBE;
        err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
                         EXT_CSD_BUS_WIDTH,
                         val,
                         card->ext_csd.generic_cmd6_time);
        if (err) {
                pr_err("%s: switch to bus width for hs400es failed, err:%d\n",
                        mmc_hostname(host), err);
                goto out_err;
        }

        mmc_select_driver_type(card);

        /* Switch card to HS400 */
        val = EXT_CSD_TIMING_HS400 |
              card->drive_strength << EXT_CSD_DRV_STR_SHIFT;
        err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
                           EXT_CSD_HS_TIMING, val,
                           card->ext_csd.generic_cmd6_time, 0,
                           false, true, MMC_CMD_RETRIES);
        if (err) {
                pr_err("%s: switch to hs400es failed, err:%d\n",
                        mmc_hostname(host), err);
                goto out_err;
        }

        /* Set host controller to HS400 timing and frequency */
        mmc_set_timing(host, MMC_TIMING_MMC_HS400);

        /* Controller enable enhanced strobe function */
        host->ios.enhanced_strobe = true;
        if (host->ops->hs400_enhanced_strobe)
                host->ops->hs400_enhanced_strobe(host, &host->ios);

        err = mmc_switch_status(card, true);
        if (err)
                goto out_err;

        return 0;

out_err:
        pr_err("%s: %s failed, error %d\n", mmc_hostname(card->host),
               __func__, err);
        return err;
}

/*
 * For device supporting HS200 mode, the following sequence
 * should be done before executing the tuning process.
 * 1. set the desired bus width(4-bit or 8-bit, 1-bit is not supported)
 * 2. switch to HS200 mode
 * 3. set the clock to > 52Mhz and <=200MHz
 */
static int mmc_select_hs200(struct mmc_card *card)
{
        struct mmc_host *host = card->host;
        unsigned int old_timing, old_signal_voltage, old_clock;
        int err = -EINVAL;
        u8 val;

        old_signal_voltage = host->ios.signal_voltage;
        if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200_1_2V)
                err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120);

        if (err && card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200_1_8V)
                err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180);

        /* If fails try again during next card power cycle */
        if (err)
                return err;

        mmc_select_driver_type(card);

        /*
         * Set the bus width(4 or 8) with host's support and
         * switch to HS200 mode if bus width is set successfully.
         */
        err = mmc_select_bus_width(card);
        if (err > 0) {
                val = EXT_CSD_TIMING_HS200 |
                      card->drive_strength << EXT_CSD_DRV_STR_SHIFT;
                err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
                                   EXT_CSD_HS_TIMING, val,
                                   card->ext_csd.generic_cmd6_time, 0,
                                   false, true, MMC_CMD_RETRIES);
                if (err)
                        goto err;

                /*
                 * Bump to HS timing and frequency. Some cards don't handle
                 * SEND_STATUS reliably at the initial frequency.
                 * NB: We can't move to full (HS200) speeds until after we've
                 * successfully switched over.
                 */
                old_timing = host->ios.timing;
                old_clock = host->ios.clock;
                mmc_set_timing(host, MMC_TIMING_MMC_HS200);
                mmc_set_clock(card->host, card->ext_csd.hs_max_dtr);

                /*
                 * For HS200, CRC errors are not a reliable way to know the
                 * switch failed. If there really is a problem, we would expect
                 * tuning will fail and the result ends up the same.
                 */
                err = mmc_switch_status(card, false);

                /*
                 * mmc_select_timing() assumes timing has not changed if
                 * it is a switch error.
                 */
                if (err == -EBADMSG) {
                        mmc_set_clock(host, old_clock);
                        mmc_set_timing(host, old_timing);
                }
        }
err:
        if (err) {
                /* fall back to the old signal voltage, if fails report error */
                if (mmc_set_signal_voltage(host, old_signal_voltage))
                        err = -EIO;

                pr_err("%s: %s failed, error %d\n", mmc_hostname(card->host),
                       __func__, err);
        }
        return err;
}

/*
 * Activate High Speed, HS200 or HS400ES mode if supported.
 */
static int mmc_select_timing(struct mmc_card *card)
{
        int err = 0;

        if (!mmc_card_can_ext_csd(card))
                goto bus_speed;

        if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400ES) {
                err = mmc_select_hs400es(card);
                goto out;
        }

        if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200) {
                err = mmc_select_hs200(card);
                if (err == -EBADMSG)
                        card->mmc_avail_type &= ~EXT_CSD_CARD_TYPE_HS200;
                else
                        goto out;
        }

        if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS)
                err = mmc_select_hs(card);

out:
        if (err && err != -EBADMSG)
                return err;

bus_speed:
        /*
         * Set the bus speed to the selected bus timing.
         * If timing is not selected, backward compatible is the default.
         */
        mmc_set_bus_speed(card);
        return 0;
}

/*
 * Execute tuning sequence to seek the proper bus operating
 * conditions for HS200 and HS400, which sends CMD21 to the device.
 */
static int mmc_hs200_tuning(struct mmc_card *card)
{
        struct mmc_host *host = card->host;

        /*
         * Timing should be adjusted to the HS400 target
         * operation frequency for tuning process
         */
        if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400 &&
            host->ios.bus_width == MMC_BUS_WIDTH_8)
                if (host->ops->prepare_hs400_tuning)
                        host->ops->prepare_hs400_tuning(host, &host->ios);

        return mmc_execute_tuning(card);
}

/*
 * Handle the detection and initialisation of a card.
 *
 * In the case of a resume, "oldcard" will contain the card
 * we're trying to reinitialise.
 */
static int mmc_init_card(struct mmc_host *host, u32 ocr,
        struct mmc_card *oldcard)
{
        struct mmc_card *card;
        int err;
        u32 cid[4];
        u32 rocr;

        WARN_ON(!host->claimed);

        /* Set correct bus mode for MMC before attempting init */
        if (!mmc_host_is_spi(host))
                mmc_set_bus_mode(host, MMC_BUSMODE_OPENDRAIN);

        /*
         * Since we're changing the OCR value, we seem to
         * need to tell some cards to go back to the idle
         * state.  We wait 1ms to give cards time to
         * respond.
         * mmc_go_idle is needed for eMMC that are asleep
         */
        mmc_go_idle(host);

        /* The extra bit indicates that we support high capacity */
        err = mmc_send_op_cond(host, ocr | (1 << 30), &rocr);
        if (err)
                goto err;

        /*
         * For SPI, enable CRC as appropriate.
         */
        if (mmc_host_is_spi(host)) {
                err = mmc_spi_set_crc(host, use_spi_crc);
                if (err)
                        goto err;
        }

        /*
         * Fetch CID from card.
         */
        err = mmc_send_cid(host, cid);
        if (err)
                goto err;

        if (oldcard) {
                if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0) {
                        pr_debug("%s: Perhaps the card was replaced\n",
                                mmc_hostname(host));
                        err = -ENOENT;
                        goto err;
                }

                card = oldcard;
        } else {
                /*
                 * Allocate card structure.
                 */
                card = mmc_alloc_card(host, &mmc_type);
                if (IS_ERR(card)) {
                        err = PTR_ERR(card);
                        goto err;
                }

                card->ocr = ocr;
                card->type = MMC_TYPE_MMC;
                card->rca = 1;
                memcpy(card->raw_cid, cid, sizeof(card->raw_cid));
        }

        /*
         * Call the optional HC's init_card function to handle quirks.
         */
        if (host->ops->init_card)
                host->ops->init_card(host, card);

        /*
         * For native busses:  set card RCA and quit open drain mode.
         */
        if (!mmc_host_is_spi(host)) {
                err = mmc_set_relative_addr(card);
                if (err)
                        goto free_card;

                mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL);
        }

        if (!oldcard) {
                /*
                 * Fetch CSD from card.
                 */
                err = mmc_send_csd(card, card->raw_csd);
                if (err)
                        goto free_card;

                err = mmc_decode_csd(card);
                if (err)
                        goto free_card;
                err = mmc_decode_cid(card);
                if (err)
                        goto free_card;
        }

        /*
         * handling only for cards supporting DSR and hosts requesting
         * DSR configuration
         */
        if (card->csd.dsr_imp && host->dsr_req)
                mmc_set_dsr(host);

        /*
         * Select card, as all following commands rely on that.
         */
        if (!mmc_host_is_spi(host)) {
                err = mmc_select_card(card);
                if (err)
                        goto free_card;
        }

        if (!oldcard) {
                /* Read extended CSD. */
                err = mmc_read_ext_csd(card);
                if (err)
                        goto free_card;

                /*
                 * If doing byte addressing, check if required to do sector
                 * addressing.  Handle the case of <2GB cards needing sector
                 * addressing.  See section 8.1 JEDEC Standard JED84-A441;
                 * ocr register has bit 30 set for sector addressing.
                 */
                if (rocr & BIT(30))
                        mmc_card_set_blockaddr(card);

                /* Erase size depends on CSD and Extended CSD */
                mmc_set_erase_size(card);
        }

        /*
         * Reselect the card type since host caps could have been changed when
         * debugging even if the card is not new.
         */
        mmc_select_card_type(card);

        /* Enable ERASE_GRP_DEF. This bit is lost after a reset or power off. */
        if (card->ext_csd.rev >= 3) {
                err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
                                 EXT_CSD_ERASE_GROUP_DEF, 1,
                                 card->ext_csd.generic_cmd6_time);

                if (err && err != -EBADMSG)
                        goto free_card;

                if (err) {
                        /*
                         * Just disable enhanced area off & sz
                         * will try to enable ERASE_GROUP_DEF
                         * during next time reinit
                         */
                        card->ext_csd.enhanced_area_offset = -EINVAL;
                        card->ext_csd.enhanced_area_size = -EINVAL;
                } else {
                        card->ext_csd.erase_group_def = 1;
                        /*
                         * enable ERASE_GRP_DEF successfully.
                         * This will affect the erase size, so
                         * here need to reset erase size
                         */
                        mmc_set_erase_size(card);
                }
        }
        mmc_set_wp_grp_size(card);
        /*
         * Ensure eMMC user default partition is enabled
         */
        if (card->ext_csd.part_config & EXT_CSD_PART_CONFIG_ACC_MASK) {
                card->ext_csd.part_config &= ~EXT_CSD_PART_CONFIG_ACC_MASK;
                err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONFIG,
                                 card->ext_csd.part_config,
                                 card->ext_csd.part_time);
                if (err && err != -EBADMSG)
                        goto free_card;
        }

        /*
         * Enable power_off_notification byte in the ext_csd register
         */
        if (card->ext_csd.rev >= 6) {
                err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
                                 EXT_CSD_POWER_OFF_NOTIFICATION,
                                 EXT_CSD_POWER_ON,
                                 card->ext_csd.generic_cmd6_time);
                if (err && err != -EBADMSG)
                        goto free_card;

                /*
                 * The err can be -EBADMSG or 0,
                 * so check for success and update the flag
                 */
                if (!err)
                        card->ext_csd.power_off_notification = EXT_CSD_POWER_ON;
        }

        /* set erase_arg */
        if (mmc_card_can_discard(card))
                card->erase_arg = MMC_DISCARD_ARG;
        else if (mmc_card_can_trim(card))
                card->erase_arg = MMC_TRIM_ARG;
        else
                card->erase_arg = MMC_ERASE_ARG;

        /*
         * Select timing interface
         */
        err = mmc_select_timing(card);
        if (err)
                goto free_card;

        if (mmc_card_hs200(card)) {
                host->doing_init_tune = 1;

                err = mmc_hs200_tuning(card);
                if (!err)
                        err = mmc_select_hs400(card);

                host->doing_init_tune = 0;

                if (err)
                        goto free_card;
        } else if (mmc_card_hs400es(card)) {
                if (host->ops->execute_hs400_tuning) {
                        err = host->ops->execute_hs400_tuning(host, card);
                        if (err)
                                goto free_card;
                }
        } else {
                /* Select the desired bus width optionally */
                err = mmc_select_bus_width(card);
                if (err > 0 && mmc_card_hs(card)) {
                        err = mmc_select_hs_ddr(card);
                        if (err)
                                goto free_card;
                }
        }

        /*
         * Choose the power class with selected bus interface
         */
        mmc_select_powerclass(card);

        /*
         * Enable HPI feature (if supported)
         */
        if (card->ext_csd.hpi) {
                err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
                                EXT_CSD_HPI_MGMT, 1,
                                card->ext_csd.generic_cmd6_time);
                if (err && err != -EBADMSG)
                        goto free_card;
                if (err) {
                        pr_warn("%s: Enabling HPI failed\n",
                                mmc_hostname(card->host));
                        card->ext_csd.hpi_en = 0;
                } else {
                        card->ext_csd.hpi_en = 1;
                }
        }

        /*
         * If cache size is higher than 0, this indicates the existence of cache
         * and it can be turned on. Note that some eMMCs from Micron has been
         * reported to need ~800 ms timeout, while enabling the cache after
         * sudden power failure tests. Let's extend the timeout to a minimum of
         * DEFAULT_CACHE_EN_TIMEOUT_MS and do it for all cards.
         */
        if (card->ext_csd.cache_size > 0) {
                unsigned int timeout_ms = MIN_CACHE_EN_TIMEOUT_MS;

                timeout_ms = max(card->ext_csd.generic_cmd6_time, timeout_ms);
                err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
                                EXT_CSD_CACHE_CTRL, 1, timeout_ms);
                if (err && err != -EBADMSG)
                        goto free_card;

                /*
                 * Only if no error, cache is turned on successfully.
                 */
                if (err) {
                        pr_warn("%s: Cache is supported, but failed to turn on (%d)\n",
                                mmc_hostname(card->host), err);
                        card->ext_csd.cache_ctrl = 0;
                } else {
                        card->ext_csd.cache_ctrl = 1;
                }
        }

        /*
         * Enable Command Queue if supported. Note that Packed Commands cannot
         * be used with Command Queue.
         */
        card->ext_csd.cmdq_en = false;
        if (card->ext_csd.cmdq_support && host->caps2 & MMC_CAP2_CQE) {
                err = mmc_cmdq_enable(card);
                if (err && err != -EBADMSG)
                        goto free_card;
                if (err) {
                        pr_warn("%s: Enabling CMDQ failed\n",
                                mmc_hostname(card->host));
                        card->ext_csd.cmdq_support = false;
                        card->ext_csd.cmdq_depth = 0;
                }
        }
        /*
         * In some cases (e.g. RPMB or mmc_test), the Command Queue must be
         * disabled for a time, so a flag is needed to indicate to re-enable the
         * Command Queue.
         */
        card->reenable_cmdq = card->ext_csd.cmdq_en;

        if (host->cqe_ops && !host->cqe_enabled) {
                err = host->cqe_ops->cqe_enable(host, card);
                if (!err) {
                        host->cqe_enabled = true;

                        if (card->ext_csd.cmdq_en) {
                                pr_info("%s: Command Queue Engine enabled\n",
                                        mmc_hostname(host));
                        } else {
                                host->hsq_enabled = true;
                                pr_info("%s: Host Software Queue enabled\n",
                                        mmc_hostname(host));
                        }
                }
        }

        if (host->caps2 & MMC_CAP2_AVOID_3_3V &&
            host->ios.signal_voltage == MMC_SIGNAL_VOLTAGE_330) {
                pr_err("%s: Host failed to negotiate down from 3.3V\n",
                        mmc_hostname(host));
                err = -EINVAL;
                goto free_card;
        }

        if (!oldcard)
                host->card = card;

        return 0;

free_card:
        if (!oldcard)
                mmc_remove_card(card);
err:
        return err;
}

static bool mmc_card_can_sleep(struct mmc_card *card)
{
        return card->ext_csd.rev >= 3;
}

static int mmc_sleep_busy_cb(void *cb_data, bool *busy)
{
        struct mmc_host *host = cb_data;

        *busy = host->ops->card_busy(host);
        return 0;
}

static int mmc_sleep(struct mmc_host *host)
{
        struct mmc_command cmd = {};
        struct mmc_card *card = host->card;
        unsigned int timeout_ms = DIV_ROUND_UP(card->ext_csd.sa_timeout, 10000);
        bool use_r1b_resp;
        int err;

        /* Re-tuning can't be done once the card is deselected */
        mmc_retune_hold(host);

        err = mmc_deselect_cards(host);
        if (err)
                goto out_release;

        cmd.opcode = MMC_SLEEP_AWAKE;
        cmd.arg = card->rca << 16;
        cmd.arg |= 1 << 15;
        use_r1b_resp = mmc_prepare_busy_cmd(host, &cmd, timeout_ms);

        err = mmc_wait_for_cmd(host, &cmd, 0);
        if (err)
                goto out_release;

        /*
         * If the host does not wait while the card signals busy, then we can
         * try to poll, but only if the host supports HW polling, as the
         * SEND_STATUS cmd is not allowed. If we can't poll, then we simply need
         * to wait the sleep/awake timeout.
         */
        if (host->caps & MMC_CAP_WAIT_WHILE_BUSY && use_r1b_resp)
                goto out_release;

        if (!host->ops->card_busy) {
                mmc_delay(timeout_ms);
                goto out_release;
        }

        err = __mmc_poll_for_busy(host, 0, timeout_ms, &mmc_sleep_busy_cb, host);

out_release:
        mmc_retune_release(host);
        return err;
}

static bool mmc_card_can_poweroff_notify(const struct mmc_card *card)
{
        return card &&
                mmc_card_mmc(card) &&
                (card->ext_csd.power_off_notification == EXT_CSD_POWER_ON);
}

static bool mmc_host_can_poweroff_notify(const struct mmc_host *host,
                                         enum mmc_poweroff_type pm_type)
{
        if (host->caps2 & MMC_CAP2_FULL_PWR_CYCLE)
                return true;

        if (host->caps2 & MMC_CAP2_FULL_PWR_CYCLE_IN_SUSPEND &&
            pm_type == MMC_POWEROFF_SUSPEND)
                return true;

        return pm_type == MMC_POWEROFF_SHUTDOWN;
}

static int mmc_poweroff_notify(struct mmc_card *card, unsigned int notify_type)
{
        unsigned int timeout = card->ext_csd.generic_cmd6_time;
        int err;

        /* Use EXT_CSD_POWER_OFF_SHORT as default notification type. */
        if (notify_type == EXT_CSD_POWER_OFF_LONG)
                timeout = card->ext_csd.power_off_longtime;

        err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
                        EXT_CSD_POWER_OFF_NOTIFICATION,
                        notify_type, timeout, 0, false, false, MMC_CMD_RETRIES);
        if (err)
                pr_err("%s: Power Off Notification timed out, %u\n",
                       mmc_hostname(card->host), timeout);

        /* Disable the power off notification after the switch operation. */
        card->ext_csd.power_off_notification = EXT_CSD_NO_POWER_NOTIFICATION;

        return err;
}

/*
 * Card detection - card is alive.
 */
static int mmc_alive(struct mmc_host *host)
{
        return mmc_send_status(host->card, NULL);
}

/*
 * Card detection callback from host.
 */
static void mmc_detect(struct mmc_host *host)
{
        int err;

        mmc_get_card(host->card, NULL);

        /*
         * Just check if our card has been removed.
         */
        err = _mmc_detect_card_removed(host);

        mmc_put_card(host->card, NULL);

        if (err) {
                mmc_remove_card(host->card);
                host->card = NULL;

                mmc_claim_host(host);
                mmc_detach_bus(host);
                mmc_power_off(host);
                mmc_release_host(host);
        }
}

static bool _mmc_cache_enabled(struct mmc_host *host)
{
        return host->card->ext_csd.cache_size > 0 &&
               host->card->ext_csd.cache_ctrl & 1;
}

/*
 * Flush the internal cache of the eMMC to non-volatile storage.
 */
static int _mmc_flush_cache(struct mmc_host *host)
{
        int err = 0;

        if (mmc_card_broken_cache_flush(host->card) && !host->card->written_flag)
                return 0;

        if (_mmc_cache_enabled(host)) {
                err = mmc_switch(host->card, EXT_CSD_CMD_SET_NORMAL,
                                 EXT_CSD_FLUSH_CACHE, 1,
                                 CACHE_FLUSH_TIMEOUT_MS);
                if (err)
                        pr_err("%s: cache flush error %d\n", mmc_hostname(host), err);
                else
                        host->card->written_flag = false;
        }

        return err;
}

static int _mmc_suspend(struct mmc_host *host, enum mmc_poweroff_type pm_type)
{
        unsigned int notify_type = EXT_CSD_POWER_OFF_SHORT;
        int err = 0;

        if (pm_type == MMC_POWEROFF_SHUTDOWN)
                notify_type = EXT_CSD_POWER_OFF_LONG;

        mmc_claim_host(host);

        if (mmc_card_suspended(host->card))
                goto out;

        /*
         * For the undervoltage case, we care more about device integrity.
         * Avoid cache flush and notify the device to power off quickly.
         */
        if (pm_type != MMC_POWEROFF_UNDERVOLTAGE) {
                err = _mmc_flush_cache(host);
                if (err)
                        goto out;
        }

        if (mmc_card_can_poweroff_notify(host->card) &&
            mmc_host_can_poweroff_notify(host, pm_type))
                err = mmc_poweroff_notify(host->card, notify_type);
        else if (mmc_card_can_sleep(host->card))
                err = mmc_sleep(host);
        else if (!mmc_host_is_spi(host))
                err = mmc_deselect_cards(host);

        if (!err) {
                mmc_power_off(host);
                mmc_card_set_suspended(host->card);
        }
out:
        mmc_release_host(host);
        return err;
}

/*
 * Host is being removed. Free up the current card and do a graceful power-off.
 */
static void mmc_remove(struct mmc_host *host)
{
        get_device(&host->card->dev);
        mmc_remove_card(host->card);

        _mmc_suspend(host, MMC_POWEROFF_UNBIND);

        put_device(&host->card->dev);
        host->card = NULL;
}

/*
 * Suspend callback
 */
static int mmc_suspend(struct mmc_host *host)
{
        int err;

        err = _mmc_suspend(host, MMC_POWEROFF_SUSPEND);
        if (!err) {
                pm_runtime_disable(&host->card->dev);
                pm_runtime_set_suspended(&host->card->dev);
        }

        return err;
}

/*
 * This function tries to determine if the same card is still present
 * and, if so, restore all state to it.
 */
static int _mmc_resume(struct mmc_host *host)
{
        int err = 0;

        mmc_claim_host(host);

        if (!mmc_card_suspended(host->card))
                goto out;

        mmc_power_up(host, host->card->ocr);
        err = mmc_init_card(host, host->card->ocr, host->card);
        mmc_card_clr_suspended(host->card);

out:
        mmc_release_host(host);
        return err;
}

/*
 * Shutdown callback
 */
static int mmc_shutdown(struct mmc_host *host)
{
        int err = 0;

        /*
         * In case of undervoltage, the card will be powered off (removed) by
         * _mmc_handle_undervoltage()
         */
        if (mmc_card_removed(host->card))
                return 0;

        /*
         * If the card remains suspended at this point and it was done by using
         * the sleep-cmd (CMD5), we may need to re-initialize it first, to allow
         * us to send the preferred poweroff-notification cmd at shutdown.
         */
        if (mmc_card_can_poweroff_notify(host->card) &&
            !mmc_host_can_poweroff_notify(host, MMC_POWEROFF_SUSPEND))
                err = _mmc_resume(host);

        if (!err)
                err = _mmc_suspend(host, MMC_POWEROFF_SHUTDOWN);

        return err;
}

/*
 * Callback for resume.
 */
static int mmc_resume(struct mmc_host *host)
{
        pm_runtime_enable(&host->card->dev);
        return 0;
}

/*
 * Callback for runtime_suspend.
 */
static int mmc_runtime_suspend(struct mmc_host *host)
{
        int err;

        if (!(host->caps & MMC_CAP_AGGRESSIVE_PM))
                return 0;

        err = _mmc_suspend(host, MMC_POWEROFF_SUSPEND);
        if (err)
                pr_err("%s: error %d doing aggressive suspend\n",
                        mmc_hostname(host), err);

        return err;
}

/*
 * Callback for runtime_resume.
 */
static int mmc_runtime_resume(struct mmc_host *host)
{
        int err;

        err = _mmc_resume(host);
        if (err && err != -ENOMEDIUM)
                pr_err("%s: error %d doing runtime resume\n",
                        mmc_hostname(host), err);

        return 0;
}

static bool mmc_card_can_reset(struct mmc_card *card)
{
        u8 rst_n_function;

        rst_n_function = card->ext_csd.rst_n_function;
        return ((rst_n_function & EXT_CSD_RST_N_EN_MASK) == EXT_CSD_RST_N_ENABLED);
}

static int _mmc_hw_reset(struct mmc_host *host)
{
        struct mmc_card *card = host->card;

        /*
         * In the case of recovery, we can't expect flushing the cache to work
         * always, but we have a go and ignore errors.
         */
        _mmc_flush_cache(host);

        if ((host->caps & MMC_CAP_HW_RESET) && host->ops->card_hw_reset &&
             mmc_card_can_reset(card)) {
                /* If the card accept RST_n signal, send it. */
                mmc_set_clock(host, host->f_init);
                host->ops->card_hw_reset(host);
                /* Set initial state and call mmc_set_ios */
                mmc_set_initial_state(host);
        } else {
                /* Do a brute force power cycle */
                mmc_power_cycle(host, card->ocr);
                mmc_pwrseq_reset(host);
        }
        return mmc_init_card(host, card->ocr, card);
}

/**
 * _mmc_handle_undervoltage - Handle an undervoltage event for MMC/eMMC devices
 * @host: MMC host structure
 *
 * This function is triggered when an undervoltage condition is detected.
 * It attempts to transition the device into a low-power or safe state to
 * prevent data corruption.
 *
 * Steps performed:
 * - Perform an emergency suspend using EXT_CSD_POWER_OFF_SHORT if possible.
 *    - If power-off notify is not supported, fallback mechanisms like sleep or
 *      deselecting the card are attempted.
 *    - Cache flushing is skipped to reduce execution time.
 * - Mark the card as removed to prevent further interactions after
 *    undervoltage.
 *
 * Note: This function does not handle host claiming or releasing. The caller
 *       must ensure that the host is properly claimed before calling this
 *       function and released afterward.
 *
 * Returns: 0 on success, or a negative error code if any step fails.
 */
static int _mmc_handle_undervoltage(struct mmc_host *host)
{
        struct mmc_card *card = host->card;
        int err;

        /*
         * Perform an emergency suspend to power off the eMMC quickly.
         * This ensures the device enters a safe state before power is lost.
         * We first attempt EXT_CSD_POWER_OFF_SHORT, but if power-off notify
         * is not supported, we fall back to sleep mode or deselecting the card.
         * Cache flushing is skipped to minimize delay.
         */
        err = _mmc_suspend(host, MMC_POWEROFF_UNDERVOLTAGE);
        if (err)
                pr_err("%s: undervoltage suspend failed: %pe\n",
                       mmc_hostname(host), ERR_PTR(err));

        /*
         * Mark the card as removed to prevent further operations.
         * This ensures the system does not attempt to access the device
         * after an undervoltage event, avoiding potential corruption.
         */
        mmc_card_set_removed(card);

        return err;
}

static const struct mmc_bus_ops mmc_ops = {
        .remove = mmc_remove,
        .detect = mmc_detect,
        .suspend = mmc_suspend,
        .resume = mmc_resume,
        .runtime_suspend = mmc_runtime_suspend,
        .runtime_resume = mmc_runtime_resume,
        .alive = mmc_alive,
        .shutdown = mmc_shutdown,
        .hw_reset = _mmc_hw_reset,
        .cache_enabled = _mmc_cache_enabled,
        .flush_cache = _mmc_flush_cache,
        .handle_undervoltage = _mmc_handle_undervoltage,
};

/*
 * Starting point for MMC card init.
 */
int mmc_attach_mmc(struct mmc_host *host)
{
        int err;
        u32 ocr, rocr;

        WARN_ON(!host->claimed);

        /* Set correct bus mode for MMC before attempting attach */
        if (!mmc_host_is_spi(host))
                mmc_set_bus_mode(host, MMC_BUSMODE_OPENDRAIN);

        err = mmc_send_op_cond(host, 0, &ocr);
        if (err)
                return err;

        mmc_attach_bus(host, &mmc_ops);
        if (host->ocr_avail_mmc)
                host->ocr_avail = host->ocr_avail_mmc;

        /*
         * We need to get OCR a different way for SPI.
         */
        if (mmc_host_is_spi(host)) {
                err = mmc_spi_read_ocr(host, 1, &ocr);
                if (err)
                        goto err;
        }

        rocr = mmc_select_voltage(host, ocr);

        /*
         * Can we support the voltage of the card?
         */
        if (!rocr) {
                err = -EINVAL;
                goto err;
        }

        /*
         * Detect and init the card.
         */
        err = mmc_init_card(host, rocr, NULL);
        if (err)
                goto err;

        mmc_release_host(host);
        err = mmc_add_card(host->card);
        if (err)
                goto remove_card;

        mmc_claim_host(host);
        return 0;

remove_card:
        mmc_remove_card(host->card);
        mmc_claim_host(host);
        host->card = NULL;
err:
        mmc_detach_bus(host);

        pr_err("%s: error %d whilst initialising MMC card\n",
                mmc_hostname(host), err);

        return err;
}