xref: /openbmc/linux/drivers/mmc/core/mmc.c (revision 076ec38a)
17ea239d9SPierre Ossman /*
270f10482SPierre Ossman  *  linux/drivers/mmc/core/mmc.c
37ea239d9SPierre Ossman  *
47ea239d9SPierre Ossman  *  Copyright (C) 2003-2004 Russell King, All Rights Reserved.
57ea239d9SPierre Ossman  *  Copyright (C) 2005-2007 Pierre Ossman, All Rights Reserved.
67ea239d9SPierre Ossman  *  MMCv4 support Copyright (C) 2006 Philip Langdale, All Rights Reserved.
77ea239d9SPierre Ossman  *
87ea239d9SPierre Ossman  * This program is free software; you can redistribute it and/or modify
97ea239d9SPierre Ossman  * it under the terms of the GNU General Public License version 2 as
107ea239d9SPierre Ossman  * published by the Free Software Foundation.
117ea239d9SPierre Ossman  */
127ea239d9SPierre Ossman 
137ea239d9SPierre Ossman #include <linux/err.h>
145a0e3ad6STejun Heo #include <linux/slab.h>
150205a904SPaul Gortmaker #include <linux/stat.h>
160cb403a2SUlf Hansson #include <linux/pm_runtime.h>
177ea239d9SPierre Ossman 
187ea239d9SPierre Ossman #include <linux/mmc/host.h>
197ea239d9SPierre Ossman #include <linux/mmc/card.h>
207ea239d9SPierre Ossman #include <linux/mmc/mmc.h>
217ea239d9SPierre Ossman 
227ea239d9SPierre Ossman #include "core.h"
234101c16aSPierre Ossman #include "bus.h"
247ea239d9SPierre Ossman #include "mmc_ops.h"
254c4cb171SPhilip Rakity #include "sd_ops.h"
267ea239d9SPierre Ossman 
277ea239d9SPierre Ossman static const unsigned int tran_exp[] = {
287ea239d9SPierre Ossman 	10000,		100000,		1000000,	10000000,
297ea239d9SPierre Ossman 	0,		0,		0,		0
307ea239d9SPierre Ossman };
317ea239d9SPierre Ossman 
327ea239d9SPierre Ossman static const unsigned char tran_mant[] = {
337ea239d9SPierre Ossman 	0,	10,	12,	13,	15,	20,	25,	30,
347ea239d9SPierre Ossman 	35,	40,	45,	50,	55,	60,	70,	80,
357ea239d9SPierre Ossman };
367ea239d9SPierre Ossman 
377ea239d9SPierre Ossman static const unsigned int tacc_exp[] = {
387ea239d9SPierre Ossman 	1,	10,	100,	1000,	10000,	100000,	1000000, 10000000,
397ea239d9SPierre Ossman };
407ea239d9SPierre Ossman 
417ea239d9SPierre Ossman static const unsigned int tacc_mant[] = {
427ea239d9SPierre Ossman 	0,	10,	12,	13,	15,	20,	25,	30,
437ea239d9SPierre Ossman 	35,	40,	45,	50,	55,	60,	70,	80,
447ea239d9SPierre Ossman };
457ea239d9SPierre Ossman 
467ea239d9SPierre Ossman #define UNSTUFF_BITS(resp,start,size)					\
477ea239d9SPierre Ossman 	({								\
487ea239d9SPierre Ossman 		const int __size = size;				\
497ea239d9SPierre Ossman 		const u32 __mask = (__size < 32 ? 1 << __size : 0) - 1;	\
507ea239d9SPierre Ossman 		const int __off = 3 - ((start) / 32);			\
517ea239d9SPierre Ossman 		const int __shft = (start) & 31;			\
527ea239d9SPierre Ossman 		u32 __res;						\
537ea239d9SPierre Ossman 									\
547ea239d9SPierre Ossman 		__res = resp[__off] >> __shft;				\
557ea239d9SPierre Ossman 		if (__size + __shft > 32)				\
567ea239d9SPierre Ossman 			__res |= resp[__off-1] << ((32 - __shft) % 32);	\
577ea239d9SPierre Ossman 		__res & __mask;						\
587ea239d9SPierre Ossman 	})
597ea239d9SPierre Ossman 
607ea239d9SPierre Ossman /*
617ea239d9SPierre Ossman  * Given the decoded CSD structure, decode the raw CID to our CID structure.
627ea239d9SPierre Ossman  */
63bd766312SPierre Ossman static int mmc_decode_cid(struct mmc_card *card)
647ea239d9SPierre Ossman {
657ea239d9SPierre Ossman 	u32 *resp = card->raw_cid;
667ea239d9SPierre Ossman 
677ea239d9SPierre Ossman 	/*
687ea239d9SPierre Ossman 	 * The selection of the format here is based upon published
697ea239d9SPierre Ossman 	 * specs from sandisk and from what people have reported.
707ea239d9SPierre Ossman 	 */
717ea239d9SPierre Ossman 	switch (card->csd.mmca_vsn) {
727ea239d9SPierre Ossman 	case 0: /* MMC v1.0 - v1.2 */
737ea239d9SPierre Ossman 	case 1: /* MMC v1.4 */
747ea239d9SPierre Ossman 		card->cid.manfid	= UNSTUFF_BITS(resp, 104, 24);
757ea239d9SPierre Ossman 		card->cid.prod_name[0]	= UNSTUFF_BITS(resp, 96, 8);
767ea239d9SPierre Ossman 		card->cid.prod_name[1]	= UNSTUFF_BITS(resp, 88, 8);
777ea239d9SPierre Ossman 		card->cid.prod_name[2]	= UNSTUFF_BITS(resp, 80, 8);
787ea239d9SPierre Ossman 		card->cid.prod_name[3]	= UNSTUFF_BITS(resp, 72, 8);
797ea239d9SPierre Ossman 		card->cid.prod_name[4]	= UNSTUFF_BITS(resp, 64, 8);
807ea239d9SPierre Ossman 		card->cid.prod_name[5]	= UNSTUFF_BITS(resp, 56, 8);
817ea239d9SPierre Ossman 		card->cid.prod_name[6]	= UNSTUFF_BITS(resp, 48, 8);
827ea239d9SPierre Ossman 		card->cid.hwrev		= UNSTUFF_BITS(resp, 44, 4);
837ea239d9SPierre Ossman 		card->cid.fwrev		= UNSTUFF_BITS(resp, 40, 4);
847ea239d9SPierre Ossman 		card->cid.serial	= UNSTUFF_BITS(resp, 16, 24);
857ea239d9SPierre Ossman 		card->cid.month		= UNSTUFF_BITS(resp, 12, 4);
867ea239d9SPierre Ossman 		card->cid.year		= UNSTUFF_BITS(resp, 8, 4) + 1997;
877ea239d9SPierre Ossman 		break;
887ea239d9SPierre Ossman 
897ea239d9SPierre Ossman 	case 2: /* MMC v2.0 - v2.2 */
907ea239d9SPierre Ossman 	case 3: /* MMC v3.1 - v3.3 */
917ea239d9SPierre Ossman 	case 4: /* MMC v4 */
927ea239d9SPierre Ossman 		card->cid.manfid	= UNSTUFF_BITS(resp, 120, 8);
937ea239d9SPierre Ossman 		card->cid.oemid		= UNSTUFF_BITS(resp, 104, 16);
947ea239d9SPierre Ossman 		card->cid.prod_name[0]	= UNSTUFF_BITS(resp, 96, 8);
957ea239d9SPierre Ossman 		card->cid.prod_name[1]	= UNSTUFF_BITS(resp, 88, 8);
967ea239d9SPierre Ossman 		card->cid.prod_name[2]	= UNSTUFF_BITS(resp, 80, 8);
977ea239d9SPierre Ossman 		card->cid.prod_name[3]	= UNSTUFF_BITS(resp, 72, 8);
987ea239d9SPierre Ossman 		card->cid.prod_name[4]	= UNSTUFF_BITS(resp, 64, 8);
997ea239d9SPierre Ossman 		card->cid.prod_name[5]	= UNSTUFF_BITS(resp, 56, 8);
10051e7e8b6SBernie Thompson 		card->cid.prv		= UNSTUFF_BITS(resp, 48, 8);
1017ea239d9SPierre Ossman 		card->cid.serial	= UNSTUFF_BITS(resp, 16, 32);
1027ea239d9SPierre Ossman 		card->cid.month		= UNSTUFF_BITS(resp, 12, 4);
1037ea239d9SPierre Ossman 		card->cid.year		= UNSTUFF_BITS(resp, 8, 4) + 1997;
1047ea239d9SPierre Ossman 		break;
1057ea239d9SPierre Ossman 
1067ea239d9SPierre Ossman 	default:
107a3c76eb9SGirish K S 		pr_err("%s: card has unknown MMCA version %d\n",
1087ea239d9SPierre Ossman 			mmc_hostname(card->host), card->csd.mmca_vsn);
109bd766312SPierre Ossman 		return -EINVAL;
1107ea239d9SPierre Ossman 	}
111bd766312SPierre Ossman 
112bd766312SPierre Ossman 	return 0;
1137ea239d9SPierre Ossman }
1147ea239d9SPierre Ossman 
115dfe86cbaSAdrian Hunter static void mmc_set_erase_size(struct mmc_card *card)
116dfe86cbaSAdrian Hunter {
117dfe86cbaSAdrian Hunter 	if (card->ext_csd.erase_group_def & 1)
118dfe86cbaSAdrian Hunter 		card->erase_size = card->ext_csd.hc_erase_size;
119dfe86cbaSAdrian Hunter 	else
120dfe86cbaSAdrian Hunter 		card->erase_size = card->csd.erase_size;
121dfe86cbaSAdrian Hunter 
122dfe86cbaSAdrian Hunter 	mmc_init_erase(card);
123dfe86cbaSAdrian Hunter }
124dfe86cbaSAdrian Hunter 
1257ea239d9SPierre Ossman /*
1267ea239d9SPierre Ossman  * Given a 128-bit response, decode to our card CSD structure.
1277ea239d9SPierre Ossman  */
128bd766312SPierre Ossman static int mmc_decode_csd(struct mmc_card *card)
1297ea239d9SPierre Ossman {
1307ea239d9SPierre Ossman 	struct mmc_csd *csd = &card->csd;
131dfe86cbaSAdrian Hunter 	unsigned int e, m, a, b;
1327ea239d9SPierre Ossman 	u32 *resp = card->raw_csd;
1337ea239d9SPierre Ossman 
1347ea239d9SPierre Ossman 	/*
1357ea239d9SPierre Ossman 	 * We only understand CSD structure v1.1 and v1.2.
1367ea239d9SPierre Ossman 	 * v1.2 has extra information in bits 15, 11 and 10.
1376da24b78SKyungmin Park 	 * We also support eMMC v4.4 & v4.41.
1387ea239d9SPierre Ossman 	 */
1396da24b78SKyungmin Park 	csd->structure = UNSTUFF_BITS(resp, 126, 2);
1406da24b78SKyungmin Park 	if (csd->structure == 0) {
141a3c76eb9SGirish K S 		pr_err("%s: unrecognised CSD structure version %d\n",
1426da24b78SKyungmin Park 			mmc_hostname(card->host), csd->structure);
143bd766312SPierre Ossman 		return -EINVAL;
1447ea239d9SPierre Ossman 	}
1457ea239d9SPierre Ossman 
1467ea239d9SPierre Ossman 	csd->mmca_vsn	 = UNSTUFF_BITS(resp, 122, 4);
1477ea239d9SPierre Ossman 	m = UNSTUFF_BITS(resp, 115, 4);
1487ea239d9SPierre Ossman 	e = UNSTUFF_BITS(resp, 112, 3);
1497ea239d9SPierre Ossman 	csd->tacc_ns	 = (tacc_exp[e] * tacc_mant[m] + 9) / 10;
1507ea239d9SPierre Ossman 	csd->tacc_clks	 = UNSTUFF_BITS(resp, 104, 8) * 100;
1517ea239d9SPierre Ossman 
1527ea239d9SPierre Ossman 	m = UNSTUFF_BITS(resp, 99, 4);
1537ea239d9SPierre Ossman 	e = UNSTUFF_BITS(resp, 96, 3);
1547ea239d9SPierre Ossman 	csd->max_dtr	  = tran_exp[e] * tran_mant[m];
1557ea239d9SPierre Ossman 	csd->cmdclass	  = UNSTUFF_BITS(resp, 84, 12);
1567ea239d9SPierre Ossman 
1577ea239d9SPierre Ossman 	e = UNSTUFF_BITS(resp, 47, 3);
1587ea239d9SPierre Ossman 	m = UNSTUFF_BITS(resp, 62, 12);
1597ea239d9SPierre Ossman 	csd->capacity	  = (1 + m) << (e + 2);
1607ea239d9SPierre Ossman 
1617ea239d9SPierre Ossman 	csd->read_blkbits = UNSTUFF_BITS(resp, 80, 4);
1627ea239d9SPierre Ossman 	csd->read_partial = UNSTUFF_BITS(resp, 79, 1);
1637ea239d9SPierre Ossman 	csd->write_misalign = UNSTUFF_BITS(resp, 78, 1);
1647ea239d9SPierre Ossman 	csd->read_misalign = UNSTUFF_BITS(resp, 77, 1);
1653d705d14SSascha Hauer 	csd->dsr_imp = UNSTUFF_BITS(resp, 76, 1);
1667ea239d9SPierre Ossman 	csd->r2w_factor = UNSTUFF_BITS(resp, 26, 3);
1677ea239d9SPierre Ossman 	csd->write_blkbits = UNSTUFF_BITS(resp, 22, 4);
1687ea239d9SPierre Ossman 	csd->write_partial = UNSTUFF_BITS(resp, 21, 1);
169bd766312SPierre Ossman 
170dfe86cbaSAdrian Hunter 	if (csd->write_blkbits >= 9) {
171dfe86cbaSAdrian Hunter 		a = UNSTUFF_BITS(resp, 42, 5);
172dfe86cbaSAdrian Hunter 		b = UNSTUFF_BITS(resp, 37, 5);
173dfe86cbaSAdrian Hunter 		csd->erase_size = (a + 1) * (b + 1);
174dfe86cbaSAdrian Hunter 		csd->erase_size <<= csd->write_blkbits - 9;
175dfe86cbaSAdrian Hunter 	}
176dfe86cbaSAdrian Hunter 
177bd766312SPierre Ossman 	return 0;
1787ea239d9SPierre Ossman }
1797ea239d9SPierre Ossman 
1807ea239d9SPierre Ossman /*
18108ee80ccSPhilip Rakity  * Read extended CSD.
1827ea239d9SPierre Ossman  */
18308ee80ccSPhilip Rakity static int mmc_get_ext_csd(struct mmc_card *card, u8 **new_ext_csd)
1847ea239d9SPierre Ossman {
1857ea239d9SPierre Ossman 	int err;
1867ea239d9SPierre Ossman 	u8 *ext_csd;
1877ea239d9SPierre Ossman 
1887ea239d9SPierre Ossman 	BUG_ON(!card);
18908ee80ccSPhilip Rakity 	BUG_ON(!new_ext_csd);
19008ee80ccSPhilip Rakity 
19108ee80ccSPhilip Rakity 	*new_ext_csd = NULL;
1927ea239d9SPierre Ossman 
193148bcab2SUlf Hansson 	if (!mmc_can_ext_csd(card))
19417b0429dSPierre Ossman 		return 0;
1957ea239d9SPierre Ossman 
1967ea239d9SPierre Ossman 	/*
1977ea239d9SPierre Ossman 	 * As the ext_csd is so large and mostly unused, we don't store the
1987ea239d9SPierre Ossman 	 * raw block in mmc_card.
1997ea239d9SPierre Ossman 	 */
2007ea239d9SPierre Ossman 	ext_csd = kmalloc(512, GFP_KERNEL);
201a1fc444eSUlf Hansson 	if (!ext_csd)
20217b0429dSPierre Ossman 		return -ENOMEM;
2037ea239d9SPierre Ossman 
2047ea239d9SPierre Ossman 	err = mmc_send_ext_csd(card, ext_csd);
20517b0429dSPierre Ossman 	if (err) {
20608ee80ccSPhilip Rakity 		kfree(ext_csd);
20708ee80ccSPhilip Rakity 		*new_ext_csd = NULL;
20808ee80ccSPhilip Rakity 
209d08ebeddSWolfgang Muees 		/* If the host or the card can't do the switch,
210d08ebeddSWolfgang Muees 		 * fail more gracefully. */
211d08ebeddSWolfgang Muees 		if ((err != -EINVAL)
212d08ebeddSWolfgang Muees 		 && (err != -ENOSYS)
213d08ebeddSWolfgang Muees 		 && (err != -EFAULT))
21408ee80ccSPhilip Rakity 			return err;
215adf66a0dSPierre Ossman 
216adf66a0dSPierre Ossman 		/*
2177ea239d9SPierre Ossman 		 * High capacity cards should have this "magic" size
2187ea239d9SPierre Ossman 		 * stored in their CSD.
2197ea239d9SPierre Ossman 		 */
2207ea239d9SPierre Ossman 		if (card->csd.capacity == (4096 * 512)) {
221a3c76eb9SGirish K S 			pr_err("%s: unable to read EXT_CSD "
2227ea239d9SPierre Ossman 				"on a possible high capacity card. "
2237ea239d9SPierre Ossman 				"Card will be ignored.\n",
2247ea239d9SPierre Ossman 				mmc_hostname(card->host));
2257ea239d9SPierre Ossman 		} else {
2266606110dSJoe Perches 			pr_warn("%s: unable to read EXT_CSD, performance might suffer\n",
2277ea239d9SPierre Ossman 				mmc_hostname(card->host));
22817b0429dSPierre Ossman 			err = 0;
2297ea239d9SPierre Ossman 		}
23008ee80ccSPhilip Rakity 	} else
23108ee80ccSPhilip Rakity 		*new_ext_csd = ext_csd;
232adf66a0dSPierre Ossman 
23308ee80ccSPhilip Rakity 	return err;
2347ea239d9SPierre Ossman }
2357ea239d9SPierre Ossman 
23696cf5f02SSeungwon Jeon static void mmc_select_card_type(struct mmc_card *card)
23796cf5f02SSeungwon Jeon {
23896cf5f02SSeungwon Jeon 	struct mmc_host *host = card->host;
2390a5b6438SSeungwon Jeon 	u8 card_type = card->ext_csd.raw_card_type;
2405f1a4dd0SLee Jones 	u32 caps = host->caps, caps2 = host->caps2;
241577fb131SSeungwon Jeon 	unsigned int hs_max_dtr = 0, hs200_max_dtr = 0;
2422415c0efSSeungwon Jeon 	unsigned int avail_type = 0;
24396cf5f02SSeungwon Jeon 
24496cf5f02SSeungwon Jeon 	if (caps & MMC_CAP_MMC_HIGHSPEED &&
2452415c0efSSeungwon Jeon 	    card_type & EXT_CSD_CARD_TYPE_HS_26) {
2462415c0efSSeungwon Jeon 		hs_max_dtr = MMC_HIGH_26_MAX_DTR;
2472415c0efSSeungwon Jeon 		avail_type |= EXT_CSD_CARD_TYPE_HS_26;
2482415c0efSSeungwon Jeon 	}
2492415c0efSSeungwon Jeon 
2502415c0efSSeungwon Jeon 	if (caps & MMC_CAP_MMC_HIGHSPEED &&
2512415c0efSSeungwon Jeon 	    card_type & EXT_CSD_CARD_TYPE_HS_52) {
25296cf5f02SSeungwon Jeon 		hs_max_dtr = MMC_HIGH_52_MAX_DTR;
2532415c0efSSeungwon Jeon 		avail_type |= EXT_CSD_CARD_TYPE_HS_52;
2542415c0efSSeungwon Jeon 	}
25596cf5f02SSeungwon Jeon 
2562415c0efSSeungwon Jeon 	if (caps & MMC_CAP_1_8V_DDR &&
2572415c0efSSeungwon Jeon 	    card_type & EXT_CSD_CARD_TYPE_DDR_1_8V) {
25896cf5f02SSeungwon Jeon 		hs_max_dtr = MMC_HIGH_DDR_MAX_DTR;
2592415c0efSSeungwon Jeon 		avail_type |= EXT_CSD_CARD_TYPE_DDR_1_8V;
2602415c0efSSeungwon Jeon 	}
26196cf5f02SSeungwon Jeon 
2622415c0efSSeungwon Jeon 	if (caps & MMC_CAP_1_2V_DDR &&
2632415c0efSSeungwon Jeon 	    card_type & EXT_CSD_CARD_TYPE_DDR_1_2V) {
2642415c0efSSeungwon Jeon 		hs_max_dtr = MMC_HIGH_DDR_MAX_DTR;
2652415c0efSSeungwon Jeon 		avail_type |= EXT_CSD_CARD_TYPE_DDR_1_2V;
2662415c0efSSeungwon Jeon 	}
2672415c0efSSeungwon Jeon 
2682415c0efSSeungwon Jeon 	if (caps2 & MMC_CAP2_HS200_1_8V_SDR &&
2692415c0efSSeungwon Jeon 	    card_type & EXT_CSD_CARD_TYPE_HS200_1_8V) {
270577fb131SSeungwon Jeon 		hs200_max_dtr = MMC_HS200_MAX_DTR;
2712415c0efSSeungwon Jeon 		avail_type |= EXT_CSD_CARD_TYPE_HS200_1_8V;
2722415c0efSSeungwon Jeon 	}
2732415c0efSSeungwon Jeon 
2742415c0efSSeungwon Jeon 	if (caps2 & MMC_CAP2_HS200_1_2V_SDR &&
2752415c0efSSeungwon Jeon 	    card_type & EXT_CSD_CARD_TYPE_HS200_1_2V) {
276577fb131SSeungwon Jeon 		hs200_max_dtr = MMC_HS200_MAX_DTR;
2772415c0efSSeungwon Jeon 		avail_type |= EXT_CSD_CARD_TYPE_HS200_1_2V;
2782415c0efSSeungwon Jeon 	}
27996cf5f02SSeungwon Jeon 
2800a5b6438SSeungwon Jeon 	if (caps2 & MMC_CAP2_HS400_1_8V &&
2810a5b6438SSeungwon Jeon 	    card_type & EXT_CSD_CARD_TYPE_HS400_1_8V) {
2820a5b6438SSeungwon Jeon 		hs200_max_dtr = MMC_HS200_MAX_DTR;
2830a5b6438SSeungwon Jeon 		avail_type |= EXT_CSD_CARD_TYPE_HS400_1_8V;
2840a5b6438SSeungwon Jeon 	}
2850a5b6438SSeungwon Jeon 
2860a5b6438SSeungwon Jeon 	if (caps2 & MMC_CAP2_HS400_1_2V &&
2870a5b6438SSeungwon Jeon 	    card_type & EXT_CSD_CARD_TYPE_HS400_1_2V) {
2880a5b6438SSeungwon Jeon 		hs200_max_dtr = MMC_HS200_MAX_DTR;
2890a5b6438SSeungwon Jeon 		avail_type |= EXT_CSD_CARD_TYPE_HS400_1_2V;
2900a5b6438SSeungwon Jeon 	}
2910a5b6438SSeungwon Jeon 
29296cf5f02SSeungwon Jeon 	card->ext_csd.hs_max_dtr = hs_max_dtr;
293577fb131SSeungwon Jeon 	card->ext_csd.hs200_max_dtr = hs200_max_dtr;
2942415c0efSSeungwon Jeon 	card->mmc_avail_type = avail_type;
29596cf5f02SSeungwon Jeon }
29696cf5f02SSeungwon Jeon 
297b4493eeaSGrégory Soutadé static void mmc_manage_enhanced_area(struct mmc_card *card, u8 *ext_csd)
298b4493eeaSGrégory Soutadé {
299994324bbSGrégory Soutadé 	u8 hc_erase_grp_sz, hc_wp_grp_sz;
300994324bbSGrégory Soutadé 
301994324bbSGrégory Soutadé 	/*
302994324bbSGrégory Soutadé 	 * Disable these attributes by default
303994324bbSGrégory Soutadé 	 */
304994324bbSGrégory Soutadé 	card->ext_csd.enhanced_area_offset = -EINVAL;
305994324bbSGrégory Soutadé 	card->ext_csd.enhanced_area_size = -EINVAL;
306b4493eeaSGrégory Soutadé 
307b4493eeaSGrégory Soutadé 	/*
308b4493eeaSGrégory Soutadé 	 * Enhanced area feature support -- check whether the eMMC
309b4493eeaSGrégory Soutadé 	 * card has the Enhanced area enabled.  If so, export enhanced
310b4493eeaSGrégory Soutadé 	 * area offset and size to user by adding sysfs interface.
311b4493eeaSGrégory Soutadé 	 */
312b4493eeaSGrégory Soutadé 	if ((ext_csd[EXT_CSD_PARTITION_SUPPORT] & 0x2) &&
313b4493eeaSGrégory Soutadé 	    (ext_csd[EXT_CSD_PARTITION_ATTRIBUTE] & 0x1)) {
314994324bbSGrégory Soutadé 		if (card->ext_csd.partition_setting_completed) {
315b4493eeaSGrégory Soutadé 			hc_erase_grp_sz =
316b4493eeaSGrégory Soutadé 				ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
317b4493eeaSGrégory Soutadé 			hc_wp_grp_sz =
318b4493eeaSGrégory Soutadé 				ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
319b4493eeaSGrégory Soutadé 
320b4493eeaSGrégory Soutadé 			/*
321b4493eeaSGrégory Soutadé 			 * calculate the enhanced data area offset, in bytes
322b4493eeaSGrégory Soutadé 			 */
323b4493eeaSGrégory Soutadé 			card->ext_csd.enhanced_area_offset =
324b4493eeaSGrégory Soutadé 				(ext_csd[139] << 24) + (ext_csd[138] << 16) +
325b4493eeaSGrégory Soutadé 				(ext_csd[137] << 8) + ext_csd[136];
326b4493eeaSGrégory Soutadé 			if (mmc_card_blockaddr(card))
327b4493eeaSGrégory Soutadé 				card->ext_csd.enhanced_area_offset <<= 9;
328b4493eeaSGrégory Soutadé 			/*
329b4493eeaSGrégory Soutadé 			 * calculate the enhanced data area size, in kilobytes
330b4493eeaSGrégory Soutadé 			 */
331b4493eeaSGrégory Soutadé 			card->ext_csd.enhanced_area_size =
332b4493eeaSGrégory Soutadé 				(ext_csd[142] << 16) + (ext_csd[141] << 8) +
333b4493eeaSGrégory Soutadé 				ext_csd[140];
334b4493eeaSGrégory Soutadé 			card->ext_csd.enhanced_area_size *=
335b4493eeaSGrégory Soutadé 				(size_t)(hc_erase_grp_sz * hc_wp_grp_sz);
336b4493eeaSGrégory Soutadé 			card->ext_csd.enhanced_area_size <<= 9;
337b4493eeaSGrégory Soutadé 		} else {
338994324bbSGrégory Soutadé 			pr_warn("%s: defines enhanced area without partition setting complete\n",
339994324bbSGrégory Soutadé 				mmc_hostname(card->host));
340994324bbSGrégory Soutadé 		}
341b4493eeaSGrégory Soutadé 	}
342b4493eeaSGrégory Soutadé }
343b4493eeaSGrégory Soutadé 
344b4493eeaSGrégory Soutadé static void mmc_manage_gp_partitions(struct mmc_card *card, u8 *ext_csd)
345b4493eeaSGrégory Soutadé {
346b4493eeaSGrégory Soutadé 	int idx;
347994324bbSGrégory Soutadé 	u8 hc_erase_grp_sz, hc_wp_grp_sz;
348994324bbSGrégory Soutadé 	unsigned int part_size;
349b4493eeaSGrégory Soutadé 
350b4493eeaSGrégory Soutadé 	/*
351b4493eeaSGrégory Soutadé 	 * General purpose partition feature support --
352b4493eeaSGrégory Soutadé 	 * If ext_csd has the size of general purpose partitions,
353b4493eeaSGrégory Soutadé 	 * set size, part_cfg, partition name in mmc_part.
354b4493eeaSGrégory Soutadé 	 */
355b4493eeaSGrégory Soutadé 	if (ext_csd[EXT_CSD_PARTITION_SUPPORT] &
356b4493eeaSGrégory Soutadé 	    EXT_CSD_PART_SUPPORT_PART_EN) {
357b4493eeaSGrégory Soutadé 		hc_erase_grp_sz =
358b4493eeaSGrégory Soutadé 			ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
359b4493eeaSGrégory Soutadé 		hc_wp_grp_sz =
360b4493eeaSGrégory Soutadé 			ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
361b4493eeaSGrégory Soutadé 
362b4493eeaSGrégory Soutadé 		for (idx = 0; idx < MMC_NUM_GP_PARTITION; idx++) {
363b4493eeaSGrégory Soutadé 			if (!ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3] &&
364b4493eeaSGrégory Soutadé 			    !ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3 + 1] &&
365b4493eeaSGrégory Soutadé 			    !ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3 + 2])
366b4493eeaSGrégory Soutadé 				continue;
367994324bbSGrégory Soutadé 			if (card->ext_csd.partition_setting_completed == 0) {
368994324bbSGrégory Soutadé 				pr_warn("%s: has partition size defined without partition complete\n",
369994324bbSGrégory Soutadé 					mmc_hostname(card->host));
370994324bbSGrégory Soutadé 				break;
371994324bbSGrégory Soutadé 			}
372b4493eeaSGrégory Soutadé 			part_size =
373b4493eeaSGrégory Soutadé 				(ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3 + 2]
374b4493eeaSGrégory Soutadé 				<< 16) +
375b4493eeaSGrégory Soutadé 				(ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3 + 1]
376b4493eeaSGrégory Soutadé 				<< 8) +
377b4493eeaSGrégory Soutadé 				ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3];
378b4493eeaSGrégory Soutadé 			part_size *= (size_t)(hc_erase_grp_sz *
379b4493eeaSGrégory Soutadé 				hc_wp_grp_sz);
380b4493eeaSGrégory Soutadé 			mmc_part_add(card, part_size << 19,
381b4493eeaSGrégory Soutadé 				EXT_CSD_PART_CONFIG_ACC_GP0 + idx,
382b4493eeaSGrégory Soutadé 				"gp%d", idx, false,
383b4493eeaSGrégory Soutadé 				MMC_BLK_DATA_AREA_GP);
384b4493eeaSGrégory Soutadé 		}
385b4493eeaSGrégory Soutadé 	}
386b4493eeaSGrégory Soutadé }
387b4493eeaSGrégory Soutadé 
38808ee80ccSPhilip Rakity /*
38908ee80ccSPhilip Rakity  * Decode extended CSD.
39008ee80ccSPhilip Rakity  */
391076ec38aSUlf Hansson static int mmc_decode_ext_csd(struct mmc_card *card, u8 *ext_csd)
39208ee80ccSPhilip Rakity {
393e0c368d5SNamjae Jeon 	int err = 0, idx;
394e0c368d5SNamjae Jeon 	unsigned int part_size;
39508ee80ccSPhilip Rakity 
39608ee80ccSPhilip Rakity 	BUG_ON(!card);
39708ee80ccSPhilip Rakity 
39808ee80ccSPhilip Rakity 	if (!ext_csd)
39908ee80ccSPhilip Rakity 		return 0;
40008ee80ccSPhilip Rakity 
4016da24b78SKyungmin Park 	/* Version is coded in the CSD_STRUCTURE byte in the EXT_CSD register */
402f39b2dd9SPhilip Rakity 	card->ext_csd.raw_ext_csd_structure = ext_csd[EXT_CSD_STRUCTURE];
4036da24b78SKyungmin Park 	if (card->csd.structure == 3) {
404f39b2dd9SPhilip Rakity 		if (card->ext_csd.raw_ext_csd_structure > 2) {
405a3c76eb9SGirish K S 			pr_err("%s: unrecognised EXT_CSD structure "
4068fdd8521SPierre Ossman 				"version %d\n", mmc_hostname(card->host),
407f39b2dd9SPhilip Rakity 					card->ext_csd.raw_ext_csd_structure);
4086da24b78SKyungmin Park 			err = -EINVAL;
4096da24b78SKyungmin Park 			goto out;
4106da24b78SKyungmin Park 		}
4116da24b78SKyungmin Park 	}
4126da24b78SKyungmin Park 
41303a59437SRomain Izard 	/*
41403a59437SRomain Izard 	 * The EXT_CSD format is meant to be forward compatible. As long
41503a59437SRomain Izard 	 * as CSD_STRUCTURE does not change, all values for EXT_CSD_REV
41603a59437SRomain Izard 	 * are authorized, see JEDEC JESD84-B50 section B.8.
41703a59437SRomain Izard 	 */
4186da24b78SKyungmin Park 	card->ext_csd.rev = ext_csd[EXT_CSD_REV];
419d7604d76SPierre Ossman 
420f39b2dd9SPhilip Rakity 	card->ext_csd.raw_sectors[0] = ext_csd[EXT_CSD_SEC_CNT + 0];
421f39b2dd9SPhilip Rakity 	card->ext_csd.raw_sectors[1] = ext_csd[EXT_CSD_SEC_CNT + 1];
422f39b2dd9SPhilip Rakity 	card->ext_csd.raw_sectors[2] = ext_csd[EXT_CSD_SEC_CNT + 2];
423f39b2dd9SPhilip Rakity 	card->ext_csd.raw_sectors[3] = ext_csd[EXT_CSD_SEC_CNT + 3];
424b1ebe384SJarkko Lavinen 	if (card->ext_csd.rev >= 2) {
4257ea239d9SPierre Ossman 		card->ext_csd.sectors =
4267ea239d9SPierre Ossman 			ext_csd[EXT_CSD_SEC_CNT + 0] << 0 |
4277ea239d9SPierre Ossman 			ext_csd[EXT_CSD_SEC_CNT + 1] << 8 |
4287ea239d9SPierre Ossman 			ext_csd[EXT_CSD_SEC_CNT + 2] << 16 |
4297ea239d9SPierre Ossman 			ext_csd[EXT_CSD_SEC_CNT + 3] << 24;
430fc8a0985SHanumath Prasad 
431fc8a0985SHanumath Prasad 		/* Cards with density > 2GiB are sector addressed */
432fc8a0985SHanumath Prasad 		if (card->ext_csd.sectors > (2u * 1024 * 1024 * 1024) / 512)
4337ea239d9SPierre Ossman 			mmc_card_set_blockaddr(card);
434d7604d76SPierre Ossman 	}
43596cf5f02SSeungwon Jeon 
436f39b2dd9SPhilip Rakity 	card->ext_csd.raw_card_type = ext_csd[EXT_CSD_CARD_TYPE];
43796cf5f02SSeungwon Jeon 	mmc_select_card_type(card);
4387ea239d9SPierre Ossman 
439f39b2dd9SPhilip Rakity 	card->ext_csd.raw_s_a_timeout = ext_csd[EXT_CSD_S_A_TIMEOUT];
440f39b2dd9SPhilip Rakity 	card->ext_csd.raw_erase_timeout_mult =
441f39b2dd9SPhilip Rakity 		ext_csd[EXT_CSD_ERASE_TIMEOUT_MULT];
442f39b2dd9SPhilip Rakity 	card->ext_csd.raw_hc_erase_grp_size =
443f39b2dd9SPhilip Rakity 		ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
444b1ebe384SJarkko Lavinen 	if (card->ext_csd.rev >= 3) {
445b1ebe384SJarkko Lavinen 		u8 sa_shift = ext_csd[EXT_CSD_S_A_TIMEOUT];
446371a689fSAndrei Warkentin 		card->ext_csd.part_config = ext_csd[EXT_CSD_PART_CONFIG];
447371a689fSAndrei Warkentin 
448371a689fSAndrei Warkentin 		/* EXT_CSD value is in units of 10ms, but we store in ms */
449371a689fSAndrei Warkentin 		card->ext_csd.part_time = 10 * ext_csd[EXT_CSD_PART_SWITCH_TIME];
450b1ebe384SJarkko Lavinen 
451b1ebe384SJarkko Lavinen 		/* Sleep / awake timeout in 100ns units */
452b1ebe384SJarkko Lavinen 		if (sa_shift > 0 && sa_shift <= 0x17)
453b1ebe384SJarkko Lavinen 			card->ext_csd.sa_timeout =
454b1ebe384SJarkko Lavinen 					1 << ext_csd[EXT_CSD_S_A_TIMEOUT];
455dfe86cbaSAdrian Hunter 		card->ext_csd.erase_group_def =
456dfe86cbaSAdrian Hunter 			ext_csd[EXT_CSD_ERASE_GROUP_DEF];
457dfe86cbaSAdrian Hunter 		card->ext_csd.hc_erase_timeout = 300 *
458dfe86cbaSAdrian Hunter 			ext_csd[EXT_CSD_ERASE_TIMEOUT_MULT];
459dfe86cbaSAdrian Hunter 		card->ext_csd.hc_erase_size =
460dfe86cbaSAdrian Hunter 			ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] << 10;
461f4c5522bSAndrei Warkentin 
462f4c5522bSAndrei Warkentin 		card->ext_csd.rel_sectors = ext_csd[EXT_CSD_REL_WR_SEC_C];
463371a689fSAndrei Warkentin 
464371a689fSAndrei Warkentin 		/*
465371a689fSAndrei Warkentin 		 * There are two boot regions of equal size, defined in
466371a689fSAndrei Warkentin 		 * multiples of 128K.
467371a689fSAndrei Warkentin 		 */
468e0c368d5SNamjae Jeon 		if (ext_csd[EXT_CSD_BOOT_MULT] && mmc_boot_partition_access(card->host)) {
469e0c368d5SNamjae Jeon 			for (idx = 0; idx < MMC_NUM_BOOT_PARTITION; idx++) {
470e0c368d5SNamjae Jeon 				part_size = ext_csd[EXT_CSD_BOOT_MULT] << 17;
471e0c368d5SNamjae Jeon 				mmc_part_add(card, part_size,
472e0c368d5SNamjae Jeon 					EXT_CSD_PART_CONFIG_ACC_BOOT0 + idx,
473add710eaSJohan Rudholm 					"boot%d", idx, true,
474add710eaSJohan Rudholm 					MMC_BLK_DATA_AREA_BOOT);
475e0c368d5SNamjae Jeon 			}
476e0c368d5SNamjae Jeon 		}
477b1ebe384SJarkko Lavinen 	}
478b1ebe384SJarkko Lavinen 
479f39b2dd9SPhilip Rakity 	card->ext_csd.raw_hc_erase_gap_size =
480dd13b4edSJurgen Heeks 		ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
481f39b2dd9SPhilip Rakity 	card->ext_csd.raw_sec_trim_mult =
482f39b2dd9SPhilip Rakity 		ext_csd[EXT_CSD_SEC_TRIM_MULT];
483f39b2dd9SPhilip Rakity 	card->ext_csd.raw_sec_erase_mult =
484f39b2dd9SPhilip Rakity 		ext_csd[EXT_CSD_SEC_ERASE_MULT];
485f39b2dd9SPhilip Rakity 	card->ext_csd.raw_sec_feature_support =
486f39b2dd9SPhilip Rakity 		ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT];
487f39b2dd9SPhilip Rakity 	card->ext_csd.raw_trim_mult =
488f39b2dd9SPhilip Rakity 		ext_csd[EXT_CSD_TRIM_MULT];
489836dc2feSPhilip Rakity 	card->ext_csd.raw_partition_support = ext_csd[EXT_CSD_PARTITION_SUPPORT];
490dfe86cbaSAdrian Hunter 	if (card->ext_csd.rev >= 4) {
49169803d4fSGrégory Soutadé 		if (ext_csd[EXT_CSD_PARTITION_SETTING_COMPLETED] &
49269803d4fSGrégory Soutadé 		    EXT_CSD_PART_SETTING_COMPLETED)
49369803d4fSGrégory Soutadé 			card->ext_csd.partition_setting_completed = 1;
49469803d4fSGrégory Soutadé 		else
49569803d4fSGrégory Soutadé 			card->ext_csd.partition_setting_completed = 0;
49669803d4fSGrégory Soutadé 
497b4493eeaSGrégory Soutadé 		mmc_manage_enhanced_area(card, ext_csd);
498709de99dSChuanxiao Dong 
499b4493eeaSGrégory Soutadé 		mmc_manage_gp_partitions(card, ext_csd);
500e0c368d5SNamjae Jeon 
501dfe86cbaSAdrian Hunter 		card->ext_csd.sec_trim_mult =
502dfe86cbaSAdrian Hunter 			ext_csd[EXT_CSD_SEC_TRIM_MULT];
503dfe86cbaSAdrian Hunter 		card->ext_csd.sec_erase_mult =
504dfe86cbaSAdrian Hunter 			ext_csd[EXT_CSD_SEC_ERASE_MULT];
505dfe86cbaSAdrian Hunter 		card->ext_csd.sec_feature_support =
506dfe86cbaSAdrian Hunter 			ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT];
507dfe86cbaSAdrian Hunter 		card->ext_csd.trim_timeout = 300 *
508dfe86cbaSAdrian Hunter 			ext_csd[EXT_CSD_TRIM_MULT];
509add710eaSJohan Rudholm 
510add710eaSJohan Rudholm 		/*
511add710eaSJohan Rudholm 		 * Note that the call to mmc_part_add above defaults to read
512add710eaSJohan Rudholm 		 * only. If this default assumption is changed, the call must
513add710eaSJohan Rudholm 		 * take into account the value of boot_locked below.
514add710eaSJohan Rudholm 		 */
515add710eaSJohan Rudholm 		card->ext_csd.boot_ro_lock = ext_csd[EXT_CSD_BOOT_WP];
516add710eaSJohan Rudholm 		card->ext_csd.boot_ro_lockable = true;
51760443712SFredrik Soderstedt 
51860443712SFredrik Soderstedt 		/* Save power class values */
51960443712SFredrik Soderstedt 		card->ext_csd.raw_pwr_cl_52_195 =
52060443712SFredrik Soderstedt 			ext_csd[EXT_CSD_PWR_CL_52_195];
52160443712SFredrik Soderstedt 		card->ext_csd.raw_pwr_cl_26_195 =
52260443712SFredrik Soderstedt 			ext_csd[EXT_CSD_PWR_CL_26_195];
52360443712SFredrik Soderstedt 		card->ext_csd.raw_pwr_cl_52_360 =
52460443712SFredrik Soderstedt 			ext_csd[EXT_CSD_PWR_CL_52_360];
52560443712SFredrik Soderstedt 		card->ext_csd.raw_pwr_cl_26_360 =
52660443712SFredrik Soderstedt 			ext_csd[EXT_CSD_PWR_CL_26_360];
52760443712SFredrik Soderstedt 		card->ext_csd.raw_pwr_cl_200_195 =
52860443712SFredrik Soderstedt 			ext_csd[EXT_CSD_PWR_CL_200_195];
52960443712SFredrik Soderstedt 		card->ext_csd.raw_pwr_cl_200_360 =
53060443712SFredrik Soderstedt 			ext_csd[EXT_CSD_PWR_CL_200_360];
53160443712SFredrik Soderstedt 		card->ext_csd.raw_pwr_cl_ddr_52_195 =
53260443712SFredrik Soderstedt 			ext_csd[EXT_CSD_PWR_CL_DDR_52_195];
53360443712SFredrik Soderstedt 		card->ext_csd.raw_pwr_cl_ddr_52_360 =
53460443712SFredrik Soderstedt 			ext_csd[EXT_CSD_PWR_CL_DDR_52_360];
5350a5b6438SSeungwon Jeon 		card->ext_csd.raw_pwr_cl_ddr_200_360 =
5360a5b6438SSeungwon Jeon 			ext_csd[EXT_CSD_PWR_CL_DDR_200_360];
537dfe86cbaSAdrian Hunter 	}
538dfe86cbaSAdrian Hunter 
539b2499518SAdrian Hunter 	if (card->ext_csd.rev >= 5) {
5407c4f10acSRomain Izard 		/* Adjust production date as per JEDEC JESD84-B451 */
5417c4f10acSRomain Izard 		if (card->cid.year < 2010)
5427c4f10acSRomain Izard 			card->cid.year += 16;
5437c4f10acSRomain Izard 
544950d56acSJaehoon Chung 		/* check whether the eMMC card supports BKOPS */
545950d56acSJaehoon Chung 		if (ext_csd[EXT_CSD_BKOPS_SUPPORT] & 0x1) {
546950d56acSJaehoon Chung 			card->ext_csd.bkops = 1;
547950d56acSJaehoon Chung 			card->ext_csd.bkops_en = ext_csd[EXT_CSD_BKOPS_EN];
548950d56acSJaehoon Chung 			card->ext_csd.raw_bkops_status =
549950d56acSJaehoon Chung 				ext_csd[EXT_CSD_BKOPS_STATUS];
550950d56acSJaehoon Chung 			if (!card->ext_csd.bkops_en)
551950d56acSJaehoon Chung 				pr_info("%s: BKOPS_EN bit is not set\n",
552950d56acSJaehoon Chung 					mmc_hostname(card->host));
553950d56acSJaehoon Chung 		}
554950d56acSJaehoon Chung 
555eb0d8f13SJaehoon Chung 		/* check whether the eMMC card supports HPI */
556eb0d8f13SJaehoon Chung 		if (ext_csd[EXT_CSD_HPI_FEATURES] & 0x1) {
557eb0d8f13SJaehoon Chung 			card->ext_csd.hpi = 1;
558eb0d8f13SJaehoon Chung 			if (ext_csd[EXT_CSD_HPI_FEATURES] & 0x2)
559eb0d8f13SJaehoon Chung 				card->ext_csd.hpi_cmd =	MMC_STOP_TRANSMISSION;
560eb0d8f13SJaehoon Chung 			else
561eb0d8f13SJaehoon Chung 				card->ext_csd.hpi_cmd = MMC_SEND_STATUS;
562eb0d8f13SJaehoon Chung 			/*
563eb0d8f13SJaehoon Chung 			 * Indicate the maximum timeout to close
564eb0d8f13SJaehoon Chung 			 * a command interrupted by HPI
565eb0d8f13SJaehoon Chung 			 */
566eb0d8f13SJaehoon Chung 			card->ext_csd.out_of_int_time =
567eb0d8f13SJaehoon Chung 				ext_csd[EXT_CSD_OUT_OF_INTERRUPT_TIME] * 10;
568eb0d8f13SJaehoon Chung 		}
569eb0d8f13SJaehoon Chung 
570f4c5522bSAndrei Warkentin 		card->ext_csd.rel_param = ext_csd[EXT_CSD_WR_REL_PARAM];
571b2499518SAdrian Hunter 		card->ext_csd.rst_n_function = ext_csd[EXT_CSD_RST_N_FUNCTION];
572090d25feSLoic Pallardy 
573090d25feSLoic Pallardy 		/*
574090d25feSLoic Pallardy 		 * RPMB regions are defined in multiples of 128K.
575090d25feSLoic Pallardy 		 */
576090d25feSLoic Pallardy 		card->ext_csd.raw_rpmb_size_mult = ext_csd[EXT_CSD_RPMB_MULT];
577d0123ccaSBalaji T K 		if (ext_csd[EXT_CSD_RPMB_MULT] && mmc_host_cmd23(card->host)) {
578090d25feSLoic Pallardy 			mmc_part_add(card, ext_csd[EXT_CSD_RPMB_MULT] << 17,
579090d25feSLoic Pallardy 				EXT_CSD_PART_CONFIG_ACC_RPMB,
580090d25feSLoic Pallardy 				"rpmb", 0, false,
581090d25feSLoic Pallardy 				MMC_BLK_DATA_AREA_RPMB);
582090d25feSLoic Pallardy 		}
583b2499518SAdrian Hunter 	}
584f4c5522bSAndrei Warkentin 
5855238acbeSAndrei Warkentin 	card->ext_csd.raw_erased_mem_count = ext_csd[EXT_CSD_ERASED_MEM_CONT];
586dfe86cbaSAdrian Hunter 	if (ext_csd[EXT_CSD_ERASED_MEM_CONT])
587dfe86cbaSAdrian Hunter 		card->erased_byte = 0xFF;
588dfe86cbaSAdrian Hunter 	else
589dfe86cbaSAdrian Hunter 		card->erased_byte = 0x0;
590dfe86cbaSAdrian Hunter 
591336c716aSSeungwon Jeon 	/* eMMC v4.5 or later */
592bec8726aSGirish K S 	if (card->ext_csd.rev >= 6) {
593336c716aSSeungwon Jeon 		card->ext_csd.feature_support |= MMC_DISCARD_FEATURE;
594336c716aSSeungwon Jeon 
595b23cf0bdSSeungwon Jeon 		card->ext_csd.generic_cmd6_time = 10 *
596b23cf0bdSSeungwon Jeon 			ext_csd[EXT_CSD_GENERIC_CMD6_TIME];
597bec8726aSGirish K S 		card->ext_csd.power_off_longtime = 10 *
598bec8726aSGirish K S 			ext_csd[EXT_CSD_POWER_OFF_LONG_TIME];
599b23cf0bdSSeungwon Jeon 
600881d1c25SSeungwon Jeon 		card->ext_csd.cache_size =
601881d1c25SSeungwon Jeon 			ext_csd[EXT_CSD_CACHE_SIZE + 0] << 0 |
602881d1c25SSeungwon Jeon 			ext_csd[EXT_CSD_CACHE_SIZE + 1] << 8 |
603881d1c25SSeungwon Jeon 			ext_csd[EXT_CSD_CACHE_SIZE + 2] << 16 |
604881d1c25SSeungwon Jeon 			ext_csd[EXT_CSD_CACHE_SIZE + 3] << 24;
6054265900eSSaugata Das 
6064265900eSSaugata Das 		if (ext_csd[EXT_CSD_DATA_SECTOR_SIZE] == 1)
6074265900eSSaugata Das 			card->ext_csd.data_sector_size = 4096;
6084265900eSSaugata Das 		else
6094265900eSSaugata Das 			card->ext_csd.data_sector_size = 512;
6104265900eSSaugata Das 
6114265900eSSaugata Das 		if ((ext_csd[EXT_CSD_DATA_TAG_SUPPORT] & 1) &&
6124265900eSSaugata Das 		    (ext_csd[EXT_CSD_TAG_UNIT_SIZE] <= 8)) {
6134265900eSSaugata Das 			card->ext_csd.data_tag_unit_size =
6144265900eSSaugata Das 			((unsigned int) 1 << ext_csd[EXT_CSD_TAG_UNIT_SIZE]) *
6154265900eSSaugata Das 			(card->ext_csd.data_sector_size);
6164265900eSSaugata Das 		} else {
6174265900eSSaugata Das 			card->ext_csd.data_tag_unit_size = 0;
6184265900eSSaugata Das 		}
619abd9ac14SSeungwon Jeon 
620abd9ac14SSeungwon Jeon 		card->ext_csd.max_packed_writes =
621abd9ac14SSeungwon Jeon 			ext_csd[EXT_CSD_MAX_PACKED_WRITES];
622abd9ac14SSeungwon Jeon 		card->ext_csd.max_packed_reads =
623abd9ac14SSeungwon Jeon 			ext_csd[EXT_CSD_MAX_PACKED_READS];
624a5075eb9SSaugata Das 	} else {
625a5075eb9SSaugata Das 		card->ext_csd.data_sector_size = 512;
626336c716aSSeungwon Jeon 	}
627881d1c25SSeungwon Jeon 
6280f762426SGwendal Grignou 	/* eMMC v5 or later */
6290f762426SGwendal Grignou 	if (card->ext_csd.rev >= 7) {
6300f762426SGwendal Grignou 		memcpy(card->ext_csd.fwrev, &ext_csd[EXT_CSD_FIRMWARE_VERSION],
6310f762426SGwendal Grignou 		       MMC_FIRMWARE_LEN);
6320f762426SGwendal Grignou 		card->ext_csd.ffu_capable =
6330f762426SGwendal Grignou 			(ext_csd[EXT_CSD_SUPPORTED_MODE] & 0x1) &&
6340f762426SGwendal Grignou 			!(ext_csd[EXT_CSD_FW_CONFIG] & 0x1);
6350f762426SGwendal Grignou 	}
6367ea239d9SPierre Ossman out:
63708ee80ccSPhilip Rakity 	return err;
63808ee80ccSPhilip Rakity }
6397ea239d9SPierre Ossman 
640076ec38aSUlf Hansson static int mmc_read_ext_csd(struct mmc_card *card)
641076ec38aSUlf Hansson {
642076ec38aSUlf Hansson 	u8 *ext_csd = NULL;
643076ec38aSUlf Hansson 	int err;
644076ec38aSUlf Hansson 
645076ec38aSUlf Hansson 	err = mmc_get_ext_csd(card, &ext_csd);
646076ec38aSUlf Hansson 	if (err)
647076ec38aSUlf Hansson 		return err;
648076ec38aSUlf Hansson 
649076ec38aSUlf Hansson 	err = mmc_decode_ext_csd(card, ext_csd);
650076ec38aSUlf Hansson 	kfree(ext_csd);
651076ec38aSUlf Hansson 	return err;
652076ec38aSUlf Hansson }
653076ec38aSUlf Hansson 
654f39b2dd9SPhilip Rakity static int mmc_compare_ext_csds(struct mmc_card *card, unsigned bus_width)
65508ee80ccSPhilip Rakity {
65608ee80ccSPhilip Rakity 	u8 *bw_ext_csd;
65708ee80ccSPhilip Rakity 	int err;
65808ee80ccSPhilip Rakity 
659f39b2dd9SPhilip Rakity 	if (bus_width == MMC_BUS_WIDTH_1)
660f39b2dd9SPhilip Rakity 		return 0;
66108ee80ccSPhilip Rakity 
662f39b2dd9SPhilip Rakity 	err = mmc_get_ext_csd(card, &bw_ext_csd);
663f39b2dd9SPhilip Rakity 
664f39b2dd9SPhilip Rakity 	if (err || bw_ext_csd == NULL) {
66508ee80ccSPhilip Rakity 		err = -EINVAL;
66608ee80ccSPhilip Rakity 		goto out;
66708ee80ccSPhilip Rakity 	}
66808ee80ccSPhilip Rakity 
66908ee80ccSPhilip Rakity 	/* only compare read only fields */
670dd13b4edSJurgen Heeks 	err = !((card->ext_csd.raw_partition_support ==
67108ee80ccSPhilip Rakity 			bw_ext_csd[EXT_CSD_PARTITION_SUPPORT]) &&
672f39b2dd9SPhilip Rakity 		(card->ext_csd.raw_erased_mem_count ==
67308ee80ccSPhilip Rakity 			bw_ext_csd[EXT_CSD_ERASED_MEM_CONT]) &&
674f39b2dd9SPhilip Rakity 		(card->ext_csd.rev ==
67508ee80ccSPhilip Rakity 			bw_ext_csd[EXT_CSD_REV]) &&
676f39b2dd9SPhilip Rakity 		(card->ext_csd.raw_ext_csd_structure ==
67708ee80ccSPhilip Rakity 			bw_ext_csd[EXT_CSD_STRUCTURE]) &&
678f39b2dd9SPhilip Rakity 		(card->ext_csd.raw_card_type ==
67908ee80ccSPhilip Rakity 			bw_ext_csd[EXT_CSD_CARD_TYPE]) &&
680f39b2dd9SPhilip Rakity 		(card->ext_csd.raw_s_a_timeout ==
68108ee80ccSPhilip Rakity 			bw_ext_csd[EXT_CSD_S_A_TIMEOUT]) &&
682f39b2dd9SPhilip Rakity 		(card->ext_csd.raw_hc_erase_gap_size ==
68308ee80ccSPhilip Rakity 			bw_ext_csd[EXT_CSD_HC_WP_GRP_SIZE]) &&
684f39b2dd9SPhilip Rakity 		(card->ext_csd.raw_erase_timeout_mult ==
68508ee80ccSPhilip Rakity 			bw_ext_csd[EXT_CSD_ERASE_TIMEOUT_MULT]) &&
686f39b2dd9SPhilip Rakity 		(card->ext_csd.raw_hc_erase_grp_size ==
68708ee80ccSPhilip Rakity 			bw_ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]) &&
688f39b2dd9SPhilip Rakity 		(card->ext_csd.raw_sec_trim_mult ==
68908ee80ccSPhilip Rakity 			bw_ext_csd[EXT_CSD_SEC_TRIM_MULT]) &&
690f39b2dd9SPhilip Rakity 		(card->ext_csd.raw_sec_erase_mult ==
69108ee80ccSPhilip Rakity 			bw_ext_csd[EXT_CSD_SEC_ERASE_MULT]) &&
692f39b2dd9SPhilip Rakity 		(card->ext_csd.raw_sec_feature_support ==
69308ee80ccSPhilip Rakity 			bw_ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT]) &&
694f39b2dd9SPhilip Rakity 		(card->ext_csd.raw_trim_mult ==
69508ee80ccSPhilip Rakity 			bw_ext_csd[EXT_CSD_TRIM_MULT]) &&
696f39b2dd9SPhilip Rakity 		(card->ext_csd.raw_sectors[0] ==
697f39b2dd9SPhilip Rakity 			bw_ext_csd[EXT_CSD_SEC_CNT + 0]) &&
698f39b2dd9SPhilip Rakity 		(card->ext_csd.raw_sectors[1] ==
699f39b2dd9SPhilip Rakity 			bw_ext_csd[EXT_CSD_SEC_CNT + 1]) &&
700f39b2dd9SPhilip Rakity 		(card->ext_csd.raw_sectors[2] ==
701f39b2dd9SPhilip Rakity 			bw_ext_csd[EXT_CSD_SEC_CNT + 2]) &&
702f39b2dd9SPhilip Rakity 		(card->ext_csd.raw_sectors[3] ==
70360443712SFredrik Soderstedt 			bw_ext_csd[EXT_CSD_SEC_CNT + 3]) &&
70460443712SFredrik Soderstedt 		(card->ext_csd.raw_pwr_cl_52_195 ==
70560443712SFredrik Soderstedt 			bw_ext_csd[EXT_CSD_PWR_CL_52_195]) &&
70660443712SFredrik Soderstedt 		(card->ext_csd.raw_pwr_cl_26_195 ==
70760443712SFredrik Soderstedt 			bw_ext_csd[EXT_CSD_PWR_CL_26_195]) &&
70860443712SFredrik Soderstedt 		(card->ext_csd.raw_pwr_cl_52_360 ==
70960443712SFredrik Soderstedt 			bw_ext_csd[EXT_CSD_PWR_CL_52_360]) &&
71060443712SFredrik Soderstedt 		(card->ext_csd.raw_pwr_cl_26_360 ==
71160443712SFredrik Soderstedt 			bw_ext_csd[EXT_CSD_PWR_CL_26_360]) &&
71260443712SFredrik Soderstedt 		(card->ext_csd.raw_pwr_cl_200_195 ==
71360443712SFredrik Soderstedt 			bw_ext_csd[EXT_CSD_PWR_CL_200_195]) &&
71460443712SFredrik Soderstedt 		(card->ext_csd.raw_pwr_cl_200_360 ==
71560443712SFredrik Soderstedt 			bw_ext_csd[EXT_CSD_PWR_CL_200_360]) &&
71660443712SFredrik Soderstedt 		(card->ext_csd.raw_pwr_cl_ddr_52_195 ==
71760443712SFredrik Soderstedt 			bw_ext_csd[EXT_CSD_PWR_CL_DDR_52_195]) &&
71860443712SFredrik Soderstedt 		(card->ext_csd.raw_pwr_cl_ddr_52_360 ==
7190a5b6438SSeungwon Jeon 			bw_ext_csd[EXT_CSD_PWR_CL_DDR_52_360]) &&
7200a5b6438SSeungwon Jeon 		(card->ext_csd.raw_pwr_cl_ddr_200_360 ==
7210a5b6438SSeungwon Jeon 			bw_ext_csd[EXT_CSD_PWR_CL_DDR_200_360]));
7220a5b6438SSeungwon Jeon 
72308ee80ccSPhilip Rakity 	if (err)
72408ee80ccSPhilip Rakity 		err = -EINVAL;
72508ee80ccSPhilip Rakity 
72608ee80ccSPhilip Rakity out:
72700b41b58SUlf Hansson 	kfree(bw_ext_csd);
7287ea239d9SPierre Ossman 	return err;
7297ea239d9SPierre Ossman }
7307ea239d9SPierre Ossman 
73151ec92e2SPierre Ossman MMC_DEV_ATTR(cid, "%08x%08x%08x%08x\n", card->raw_cid[0], card->raw_cid[1],
73251ec92e2SPierre Ossman 	card->raw_cid[2], card->raw_cid[3]);
73351ec92e2SPierre Ossman MMC_DEV_ATTR(csd, "%08x%08x%08x%08x\n", card->raw_csd[0], card->raw_csd[1],
73451ec92e2SPierre Ossman 	card->raw_csd[2], card->raw_csd[3]);
73551ec92e2SPierre Ossman MMC_DEV_ATTR(date, "%02d/%04d\n", card->cid.month, card->cid.year);
736dfe86cbaSAdrian Hunter MMC_DEV_ATTR(erase_size, "%u\n", card->erase_size << 9);
737dfe86cbaSAdrian Hunter MMC_DEV_ATTR(preferred_erase_size, "%u\n", card->pref_erase << 9);
7380f762426SGwendal Grignou MMC_DEV_ATTR(ffu_capable, "%d\n", card->ext_csd.ffu_capable);
73951ec92e2SPierre Ossman MMC_DEV_ATTR(hwrev, "0x%x\n", card->cid.hwrev);
74051ec92e2SPierre Ossman MMC_DEV_ATTR(manfid, "0x%06x\n", card->cid.manfid);
74151ec92e2SPierre Ossman MMC_DEV_ATTR(name, "%s\n", card->cid.prod_name);
74251ec92e2SPierre Ossman MMC_DEV_ATTR(oemid, "0x%04x\n", card->cid.oemid);
74351e7e8b6SBernie Thompson MMC_DEV_ATTR(prv, "0x%x\n", card->cid.prv);
74451ec92e2SPierre Ossman MMC_DEV_ATTR(serial, "0x%08x\n", card->cid.serial);
745709de99dSChuanxiao Dong MMC_DEV_ATTR(enhanced_area_offset, "%llu\n",
746709de99dSChuanxiao Dong 		card->ext_csd.enhanced_area_offset);
747709de99dSChuanxiao Dong MMC_DEV_ATTR(enhanced_area_size, "%u\n", card->ext_csd.enhanced_area_size);
748188cc042SLoic Pallardy MMC_DEV_ATTR(raw_rpmb_size_mult, "%#x\n", card->ext_csd.raw_rpmb_size_mult);
749188cc042SLoic Pallardy MMC_DEV_ATTR(rel_sectors, "%#x\n", card->ext_csd.rel_sectors);
75051ec92e2SPierre Ossman 
7510f762426SGwendal Grignou static ssize_t mmc_fwrev_show(struct device *dev,
7520f762426SGwendal Grignou 			      struct device_attribute *attr,
7530f762426SGwendal Grignou 			      char *buf)
7540f762426SGwendal Grignou {
7550f762426SGwendal Grignou 	struct mmc_card *card = mmc_dev_to_card(dev);
7560f762426SGwendal Grignou 
7570f762426SGwendal Grignou 	if (card->ext_csd.rev < 7) {
7580f762426SGwendal Grignou 		return sprintf(buf, "0x%x\n", card->cid.fwrev);
7590f762426SGwendal Grignou 	} else {
7600f762426SGwendal Grignou 		return sprintf(buf, "0x%*phN\n", MMC_FIRMWARE_LEN,
7610f762426SGwendal Grignou 			       card->ext_csd.fwrev);
7620f762426SGwendal Grignou 	}
7630f762426SGwendal Grignou }
7640f762426SGwendal Grignou 
7650f762426SGwendal Grignou static DEVICE_ATTR(fwrev, S_IRUGO, mmc_fwrev_show, NULL);
7660f762426SGwendal Grignou 
76751ec92e2SPierre Ossman static struct attribute *mmc_std_attrs[] = {
76851ec92e2SPierre Ossman 	&dev_attr_cid.attr,
76951ec92e2SPierre Ossman 	&dev_attr_csd.attr,
77051ec92e2SPierre Ossman 	&dev_attr_date.attr,
771dfe86cbaSAdrian Hunter 	&dev_attr_erase_size.attr,
772dfe86cbaSAdrian Hunter 	&dev_attr_preferred_erase_size.attr,
77351ec92e2SPierre Ossman 	&dev_attr_fwrev.attr,
7740f762426SGwendal Grignou 	&dev_attr_ffu_capable.attr,
77551ec92e2SPierre Ossman 	&dev_attr_hwrev.attr,
77651ec92e2SPierre Ossman 	&dev_attr_manfid.attr,
77751ec92e2SPierre Ossman 	&dev_attr_name.attr,
77851ec92e2SPierre Ossman 	&dev_attr_oemid.attr,
77951e7e8b6SBernie Thompson 	&dev_attr_prv.attr,
78051ec92e2SPierre Ossman 	&dev_attr_serial.attr,
781709de99dSChuanxiao Dong 	&dev_attr_enhanced_area_offset.attr,
782709de99dSChuanxiao Dong 	&dev_attr_enhanced_area_size.attr,
783188cc042SLoic Pallardy 	&dev_attr_raw_rpmb_size_mult.attr,
784188cc042SLoic Pallardy 	&dev_attr_rel_sectors.attr,
78551ec92e2SPierre Ossman 	NULL,
78651ec92e2SPierre Ossman };
787d1e58212SAxel Lin ATTRIBUTE_GROUPS(mmc_std);
78851ec92e2SPierre Ossman 
78951ec92e2SPierre Ossman static struct device_type mmc_type = {
790d1e58212SAxel Lin 	.groups = mmc_std_groups,
79151ec92e2SPierre Ossman };
79251ec92e2SPierre Ossman 
7937ea239d9SPierre Ossman /*
794b87d8dbfSGirish K S  * Select the PowerClass for the current bus width
795b87d8dbfSGirish K S  * If power class is defined for 4/8 bit bus in the
796b87d8dbfSGirish K S  * extended CSD register, select it by executing the
797b87d8dbfSGirish K S  * mmc_switch command.
798b87d8dbfSGirish K S  */
7992385049dSSeungwon Jeon static int __mmc_select_powerclass(struct mmc_card *card,
80060443712SFredrik Soderstedt 				   unsigned int bus_width)
801b87d8dbfSGirish K S {
8022385049dSSeungwon Jeon 	struct mmc_host *host = card->host;
8032385049dSSeungwon Jeon 	struct mmc_ext_csd *ext_csd = &card->ext_csd;
80460443712SFredrik Soderstedt 	unsigned int pwrclass_val = 0;
8052385049dSSeungwon Jeon 	int err = 0;
806b87d8dbfSGirish K S 
807b87d8dbfSGirish K S 	switch (1 << host->ios.vdd) {
808b87d8dbfSGirish K S 	case MMC_VDD_165_195:
8092385049dSSeungwon Jeon 		if (host->ios.clock <= MMC_HIGH_26_MAX_DTR)
8102385049dSSeungwon Jeon 			pwrclass_val = ext_csd->raw_pwr_cl_26_195;
8112385049dSSeungwon Jeon 		else if (host->ios.clock <= MMC_HIGH_52_MAX_DTR)
81260443712SFredrik Soderstedt 			pwrclass_val = (bus_width <= EXT_CSD_BUS_WIDTH_8) ?
8132385049dSSeungwon Jeon 				ext_csd->raw_pwr_cl_52_195 :
8142385049dSSeungwon Jeon 				ext_csd->raw_pwr_cl_ddr_52_195;
8152385049dSSeungwon Jeon 		else if (host->ios.clock <= MMC_HS200_MAX_DTR)
8162385049dSSeungwon Jeon 			pwrclass_val = ext_csd->raw_pwr_cl_200_195;
817b87d8dbfSGirish K S 		break;
81893fc5a47SSubhash Jadavani 	case MMC_VDD_27_28:
81993fc5a47SSubhash Jadavani 	case MMC_VDD_28_29:
82093fc5a47SSubhash Jadavani 	case MMC_VDD_29_30:
82193fc5a47SSubhash Jadavani 	case MMC_VDD_30_31:
82293fc5a47SSubhash Jadavani 	case MMC_VDD_31_32:
823b87d8dbfSGirish K S 	case MMC_VDD_32_33:
824b87d8dbfSGirish K S 	case MMC_VDD_33_34:
825b87d8dbfSGirish K S 	case MMC_VDD_34_35:
826b87d8dbfSGirish K S 	case MMC_VDD_35_36:
8272385049dSSeungwon Jeon 		if (host->ios.clock <= MMC_HIGH_26_MAX_DTR)
8282385049dSSeungwon Jeon 			pwrclass_val = ext_csd->raw_pwr_cl_26_360;
8292385049dSSeungwon Jeon 		else if (host->ios.clock <= MMC_HIGH_52_MAX_DTR)
83060443712SFredrik Soderstedt 			pwrclass_val = (bus_width <= EXT_CSD_BUS_WIDTH_8) ?
8312385049dSSeungwon Jeon 				ext_csd->raw_pwr_cl_52_360 :
8322385049dSSeungwon Jeon 				ext_csd->raw_pwr_cl_ddr_52_360;
8332385049dSSeungwon Jeon 		else if (host->ios.clock <= MMC_HS200_MAX_DTR)
8340a5b6438SSeungwon Jeon 			pwrclass_val = (bus_width == EXT_CSD_DDR_BUS_WIDTH_8) ?
8350a5b6438SSeungwon Jeon 				ext_csd->raw_pwr_cl_ddr_200_360 :
8360a5b6438SSeungwon Jeon 				ext_csd->raw_pwr_cl_200_360;
837b87d8dbfSGirish K S 		break;
838b87d8dbfSGirish K S 	default:
8396606110dSJoe Perches 		pr_warn("%s: Voltage range not supported for power class\n",
8406606110dSJoe Perches 			mmc_hostname(host));
841b87d8dbfSGirish K S 		return -EINVAL;
842b87d8dbfSGirish K S 	}
843b87d8dbfSGirish K S 
844b87d8dbfSGirish K S 	if (bus_width & (EXT_CSD_BUS_WIDTH_8 | EXT_CSD_DDR_BUS_WIDTH_8))
845b87d8dbfSGirish K S 		pwrclass_val = (pwrclass_val & EXT_CSD_PWR_CL_8BIT_MASK) >>
846b87d8dbfSGirish K S 				EXT_CSD_PWR_CL_8BIT_SHIFT;
847b87d8dbfSGirish K S 	else
848b87d8dbfSGirish K S 		pwrclass_val = (pwrclass_val & EXT_CSD_PWR_CL_4BIT_MASK) >>
849b87d8dbfSGirish K S 				EXT_CSD_PWR_CL_4BIT_SHIFT;
850b87d8dbfSGirish K S 
851b87d8dbfSGirish K S 	/* If the power class is different from the default value */
852b87d8dbfSGirish K S 	if (pwrclass_val > 0) {
853b87d8dbfSGirish K S 		err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
854b87d8dbfSGirish K S 				 EXT_CSD_POWER_CLASS,
855b87d8dbfSGirish K S 				 pwrclass_val,
85671fe3eb0SSeungwon Jeon 				 card->ext_csd.generic_cmd6_time);
857b87d8dbfSGirish K S 	}
858b87d8dbfSGirish K S 
859b87d8dbfSGirish K S 	return err;
860b87d8dbfSGirish K S }
861b87d8dbfSGirish K S 
8622385049dSSeungwon Jeon static int mmc_select_powerclass(struct mmc_card *card)
8632385049dSSeungwon Jeon {
8642385049dSSeungwon Jeon 	struct mmc_host *host = card->host;
8652385049dSSeungwon Jeon 	u32 bus_width, ext_csd_bits;
8662385049dSSeungwon Jeon 	int err, ddr;
8672385049dSSeungwon Jeon 
8682385049dSSeungwon Jeon 	/* Power class selection is supported for versions >= 4.0 */
869148bcab2SUlf Hansson 	if (!mmc_can_ext_csd(card))
8702385049dSSeungwon Jeon 		return 0;
8712385049dSSeungwon Jeon 
8722385049dSSeungwon Jeon 	bus_width = host->ios.bus_width;
8732385049dSSeungwon Jeon 	/* Power class values are defined only for 4/8 bit bus */
8742385049dSSeungwon Jeon 	if (bus_width == MMC_BUS_WIDTH_1)
8752385049dSSeungwon Jeon 		return 0;
8762385049dSSeungwon Jeon 
8772385049dSSeungwon Jeon 	ddr = card->mmc_avail_type & EXT_CSD_CARD_TYPE_DDR_52;
8782385049dSSeungwon Jeon 	if (ddr)
8792385049dSSeungwon Jeon 		ext_csd_bits = (bus_width == MMC_BUS_WIDTH_8) ?
8802385049dSSeungwon Jeon 			EXT_CSD_DDR_BUS_WIDTH_8 : EXT_CSD_DDR_BUS_WIDTH_4;
8812385049dSSeungwon Jeon 	else
8822385049dSSeungwon Jeon 		ext_csd_bits = (bus_width == MMC_BUS_WIDTH_8) ?
8832385049dSSeungwon Jeon 			EXT_CSD_BUS_WIDTH_8 :  EXT_CSD_BUS_WIDTH_4;
8842385049dSSeungwon Jeon 
8852385049dSSeungwon Jeon 	err = __mmc_select_powerclass(card, ext_csd_bits);
8862385049dSSeungwon Jeon 	if (err)
8872385049dSSeungwon Jeon 		pr_warn("%s: power class selection to bus width %d ddr %d failed\n",
8882385049dSSeungwon Jeon 			mmc_hostname(host), 1 << bus_width, ddr);
8892385049dSSeungwon Jeon 
8902385049dSSeungwon Jeon 	return err;
8912385049dSSeungwon Jeon }
8922385049dSSeungwon Jeon 
893b87d8dbfSGirish K S /*
894577fb131SSeungwon Jeon  * Set the bus speed for the selected speed mode.
895a4924c71SGirish K S  */
896577fb131SSeungwon Jeon static void mmc_set_bus_speed(struct mmc_card *card)
897a4924c71SGirish K S {
898577fb131SSeungwon Jeon 	unsigned int max_dtr = (unsigned int)-1;
899577fb131SSeungwon Jeon 
9000a5b6438SSeungwon Jeon 	if ((mmc_card_hs200(card) || mmc_card_hs400(card)) &&
9010a5b6438SSeungwon Jeon 	     max_dtr > card->ext_csd.hs200_max_dtr)
902577fb131SSeungwon Jeon 		max_dtr = card->ext_csd.hs200_max_dtr;
903577fb131SSeungwon Jeon 	else if (mmc_card_hs(card) && max_dtr > card->ext_csd.hs_max_dtr)
904577fb131SSeungwon Jeon 		max_dtr = card->ext_csd.hs_max_dtr;
905577fb131SSeungwon Jeon 	else if (max_dtr > card->csd.max_dtr)
906577fb131SSeungwon Jeon 		max_dtr = card->csd.max_dtr;
907577fb131SSeungwon Jeon 
908577fb131SSeungwon Jeon 	mmc_set_clock(card->host, max_dtr);
909577fb131SSeungwon Jeon }
910577fb131SSeungwon Jeon 
911577fb131SSeungwon Jeon /*
912577fb131SSeungwon Jeon  * Select the bus width amoung 4-bit and 8-bit(SDR).
913577fb131SSeungwon Jeon  * If the bus width is changed successfully, return the selected width value.
914577fb131SSeungwon Jeon  * Zero is returned instead of error value if the wide width is not supported.
915577fb131SSeungwon Jeon  */
916577fb131SSeungwon Jeon static int mmc_select_bus_width(struct mmc_card *card)
917577fb131SSeungwon Jeon {
918a4924c71SGirish K S 	static unsigned ext_csd_bits[] = {
919a4924c71SGirish K S 		EXT_CSD_BUS_WIDTH_8,
920577fb131SSeungwon Jeon 		EXT_CSD_BUS_WIDTH_4,
921a4924c71SGirish K S 	};
922a4924c71SGirish K S 	static unsigned bus_widths[] = {
923a4924c71SGirish K S 		MMC_BUS_WIDTH_8,
924577fb131SSeungwon Jeon 		MMC_BUS_WIDTH_4,
925a4924c71SGirish K S 	};
926577fb131SSeungwon Jeon 	struct mmc_host *host = card->host;
927577fb131SSeungwon Jeon 	unsigned idx, bus_width = 0;
928577fb131SSeungwon Jeon 	int err = 0;
929a4924c71SGirish K S 
930148bcab2SUlf Hansson 	if (!mmc_can_ext_csd(card) &&
931577fb131SSeungwon Jeon 	    !(host->caps & (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA)))
932577fb131SSeungwon Jeon 		return 0;
933a4924c71SGirish K S 
934577fb131SSeungwon Jeon 	idx = (host->caps & MMC_CAP_8_BIT_DATA) ? 0 : 1;
935a4924c71SGirish K S 
936a4924c71SGirish K S 	/*
937a4924c71SGirish K S 	 * Unlike SD, MMC cards dont have a configuration register to notify
938a4924c71SGirish K S 	 * supported bus width. So bus test command should be run to identify
939a4924c71SGirish K S 	 * the supported bus width or compare the ext csd values of current
940a4924c71SGirish K S 	 * bus width and ext csd values of 1 bit mode read earlier.
941a4924c71SGirish K S 	 */
942577fb131SSeungwon Jeon 	for (; idx < ARRAY_SIZE(bus_widths); idx++) {
943a4924c71SGirish K S 		/*
944a4924c71SGirish K S 		 * Host is capable of 8bit transfer, then switch
945a4924c71SGirish K S 		 * the device to work in 8bit transfer mode. If the
946a4924c71SGirish K S 		 * mmc switch command returns error then switch to
947a4924c71SGirish K S 		 * 4bit transfer mode. On success set the corresponding
948a4924c71SGirish K S 		 * bus width on the host.
949a4924c71SGirish K S 		 */
950a4924c71SGirish K S 		err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
951a4924c71SGirish K S 				 EXT_CSD_BUS_WIDTH,
952a4924c71SGirish K S 				 ext_csd_bits[idx],
953a4924c71SGirish K S 				 card->ext_csd.generic_cmd6_time);
954a4924c71SGirish K S 		if (err)
955a4924c71SGirish K S 			continue;
956a4924c71SGirish K S 
957577fb131SSeungwon Jeon 		bus_width = bus_widths[idx];
958577fb131SSeungwon Jeon 		mmc_set_bus_width(host, bus_width);
959a4924c71SGirish K S 
960577fb131SSeungwon Jeon 		/*
961577fb131SSeungwon Jeon 		 * If controller can't handle bus width test,
962577fb131SSeungwon Jeon 		 * compare ext_csd previously read in 1 bit mode
963577fb131SSeungwon Jeon 		 * against ext_csd at new bus width
964577fb131SSeungwon Jeon 		 */
965a4924c71SGirish K S 		if (!(host->caps & MMC_CAP_BUS_WIDTH_TEST))
966577fb131SSeungwon Jeon 			err = mmc_compare_ext_csds(card, bus_width);
967a4924c71SGirish K S 		else
968577fb131SSeungwon Jeon 			err = mmc_bus_test(card, bus_width);
969577fb131SSeungwon Jeon 
970577fb131SSeungwon Jeon 		if (!err) {
971577fb131SSeungwon Jeon 			err = bus_width;
972a4924c71SGirish K S 			break;
973577fb131SSeungwon Jeon 		} else {
974577fb131SSeungwon Jeon 			pr_warn("%s: switch to bus width %d failed\n",
975577fb131SSeungwon Jeon 				mmc_hostname(host), ext_csd_bits[idx]);
976577fb131SSeungwon Jeon 		}
977a4924c71SGirish K S 	}
978a4924c71SGirish K S 
979577fb131SSeungwon Jeon 	return err;
980577fb131SSeungwon Jeon }
981577fb131SSeungwon Jeon 
982577fb131SSeungwon Jeon /*
983577fb131SSeungwon Jeon  * Switch to the high-speed mode
984577fb131SSeungwon Jeon  */
985577fb131SSeungwon Jeon static int mmc_select_hs(struct mmc_card *card)
986577fb131SSeungwon Jeon {
987577fb131SSeungwon Jeon 	int err;
988577fb131SSeungwon Jeon 
9894509f847SUlf Hansson 	err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
990577fb131SSeungwon Jeon 			   EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS,
99157de31f6SUlf Hansson 			   card->ext_csd.generic_cmd6_time,
99257de31f6SUlf Hansson 			   true, true, true);
993577fb131SSeungwon Jeon 	if (!err)
994577fb131SSeungwon Jeon 		mmc_set_timing(card->host, MMC_TIMING_MMC_HS);
995577fb131SSeungwon Jeon 
996577fb131SSeungwon Jeon 	return err;
997577fb131SSeungwon Jeon }
998577fb131SSeungwon Jeon 
999577fb131SSeungwon Jeon /*
1000577fb131SSeungwon Jeon  * Activate wide bus and DDR if supported.
1001577fb131SSeungwon Jeon  */
1002577fb131SSeungwon Jeon static int mmc_select_hs_ddr(struct mmc_card *card)
1003577fb131SSeungwon Jeon {
1004577fb131SSeungwon Jeon 	struct mmc_host *host = card->host;
1005577fb131SSeungwon Jeon 	u32 bus_width, ext_csd_bits;
1006577fb131SSeungwon Jeon 	int err = 0;
1007577fb131SSeungwon Jeon 
1008577fb131SSeungwon Jeon 	if (!(card->mmc_avail_type & EXT_CSD_CARD_TYPE_DDR_52))
1009577fb131SSeungwon Jeon 		return 0;
1010577fb131SSeungwon Jeon 
1011577fb131SSeungwon Jeon 	bus_width = host->ios.bus_width;
1012577fb131SSeungwon Jeon 	if (bus_width == MMC_BUS_WIDTH_1)
1013577fb131SSeungwon Jeon 		return 0;
1014577fb131SSeungwon Jeon 
1015577fb131SSeungwon Jeon 	ext_csd_bits = (bus_width == MMC_BUS_WIDTH_8) ?
1016577fb131SSeungwon Jeon 		EXT_CSD_DDR_BUS_WIDTH_8 : EXT_CSD_DDR_BUS_WIDTH_4;
1017577fb131SSeungwon Jeon 
1018577fb131SSeungwon Jeon 	err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
1019577fb131SSeungwon Jeon 			EXT_CSD_BUS_WIDTH,
1020577fb131SSeungwon Jeon 			ext_csd_bits,
1021577fb131SSeungwon Jeon 			card->ext_csd.generic_cmd6_time);
1022577fb131SSeungwon Jeon 	if (err) {
10234b75bffcSAndrew Gabbasov 		pr_err("%s: switch to bus width %d ddr failed\n",
1024577fb131SSeungwon Jeon 			mmc_hostname(host), 1 << bus_width);
1025577fb131SSeungwon Jeon 		return err;
1026577fb131SSeungwon Jeon 	}
1027577fb131SSeungwon Jeon 
1028577fb131SSeungwon Jeon 	/*
1029577fb131SSeungwon Jeon 	 * eMMC cards can support 3.3V to 1.2V i/o (vccq)
1030577fb131SSeungwon Jeon 	 * signaling.
1031577fb131SSeungwon Jeon 	 *
1032577fb131SSeungwon Jeon 	 * EXT_CSD_CARD_TYPE_DDR_1_8V means 3.3V or 1.8V vccq.
1033577fb131SSeungwon Jeon 	 *
1034577fb131SSeungwon Jeon 	 * 1.8V vccq at 3.3V core voltage (vcc) is not required
1035577fb131SSeungwon Jeon 	 * in the JEDEC spec for DDR.
1036577fb131SSeungwon Jeon 	 *
1037312449efSChuanxiao.Dong 	 * Even (e)MMC card can support 3.3v to 1.2v vccq, but not all
1038312449efSChuanxiao.Dong 	 * host controller can support this, like some of the SDHCI
1039312449efSChuanxiao.Dong 	 * controller which connect to an eMMC device. Some of these
1040312449efSChuanxiao.Dong 	 * host controller still needs to use 1.8v vccq for supporting
1041312449efSChuanxiao.Dong 	 * DDR mode.
1042312449efSChuanxiao.Dong 	 *
1043312449efSChuanxiao.Dong 	 * So the sequence will be:
1044312449efSChuanxiao.Dong 	 * if (host and device can both support 1.2v IO)
1045312449efSChuanxiao.Dong 	 *	use 1.2v IO;
1046312449efSChuanxiao.Dong 	 * else if (host and device can both support 1.8v IO)
1047312449efSChuanxiao.Dong 	 *	use 1.8v IO;
1048312449efSChuanxiao.Dong 	 * so if host and device can only support 3.3v IO, this is the
1049312449efSChuanxiao.Dong 	 * last choice.
1050577fb131SSeungwon Jeon 	 *
1051577fb131SSeungwon Jeon 	 * WARNING: eMMC rules are NOT the same as SD DDR
1052577fb131SSeungwon Jeon 	 */
1053312449efSChuanxiao.Dong 	err = -EINVAL;
1054312449efSChuanxiao.Dong 	if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_DDR_1_2V)
1055312449efSChuanxiao.Dong 		err = __mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120);
1056577fb131SSeungwon Jeon 
1057312449efSChuanxiao.Dong 	if (err && (card->mmc_avail_type & EXT_CSD_CARD_TYPE_DDR_1_8V))
1058312449efSChuanxiao.Dong 		err = __mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180);
1059312449efSChuanxiao.Dong 
1060312449efSChuanxiao.Dong 	/* make sure vccq is 3.3v after switching disaster */
1061312449efSChuanxiao.Dong 	if (err)
1062312449efSChuanxiao.Dong 		err = __mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_330);
1063312449efSChuanxiao.Dong 
1064312449efSChuanxiao.Dong 	if (!err)
1065577fb131SSeungwon Jeon 		mmc_set_timing(host, MMC_TIMING_MMC_DDR52);
1066577fb131SSeungwon Jeon 
1067577fb131SSeungwon Jeon 	return err;
1068577fb131SSeungwon Jeon }
1069577fb131SSeungwon Jeon 
10700a5b6438SSeungwon Jeon static int mmc_select_hs400(struct mmc_card *card)
10710a5b6438SSeungwon Jeon {
10720a5b6438SSeungwon Jeon 	struct mmc_host *host = card->host;
10730a5b6438SSeungwon Jeon 	int err = 0;
10740a5b6438SSeungwon Jeon 
10750a5b6438SSeungwon Jeon 	/*
10760a5b6438SSeungwon Jeon 	 * HS400 mode requires 8-bit bus width
10770a5b6438SSeungwon Jeon 	 */
10780a5b6438SSeungwon Jeon 	if (!(card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400 &&
10790a5b6438SSeungwon Jeon 	      host->ios.bus_width == MMC_BUS_WIDTH_8))
10800a5b6438SSeungwon Jeon 		return 0;
10810a5b6438SSeungwon Jeon 
10820a5b6438SSeungwon Jeon 	/*
10830a5b6438SSeungwon Jeon 	 * Before switching to dual data rate operation for HS400,
10840a5b6438SSeungwon Jeon 	 * it is required to convert from HS200 mode to HS mode.
10850a5b6438SSeungwon Jeon 	 */
10860a5b6438SSeungwon Jeon 	mmc_set_timing(card->host, MMC_TIMING_MMC_HS);
10870a5b6438SSeungwon Jeon 	mmc_set_bus_speed(card);
10880a5b6438SSeungwon Jeon 
10890a5b6438SSeungwon Jeon 	err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
10900a5b6438SSeungwon Jeon 			   EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS,
10910a5b6438SSeungwon Jeon 			   card->ext_csd.generic_cmd6_time,
10920a5b6438SSeungwon Jeon 			   true, true, true);
10930a5b6438SSeungwon Jeon 	if (err) {
10944b75bffcSAndrew Gabbasov 		pr_err("%s: switch to high-speed from hs200 failed, err:%d\n",
10950a5b6438SSeungwon Jeon 			mmc_hostname(host), err);
10960a5b6438SSeungwon Jeon 		return err;
10970a5b6438SSeungwon Jeon 	}
10980a5b6438SSeungwon Jeon 
10990a5b6438SSeungwon Jeon 	err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
11000a5b6438SSeungwon Jeon 			 EXT_CSD_BUS_WIDTH,
11010a5b6438SSeungwon Jeon 			 EXT_CSD_DDR_BUS_WIDTH_8,
11020a5b6438SSeungwon Jeon 			 card->ext_csd.generic_cmd6_time);
11030a5b6438SSeungwon Jeon 	if (err) {
11044b75bffcSAndrew Gabbasov 		pr_err("%s: switch to bus width for hs400 failed, err:%d\n",
11050a5b6438SSeungwon Jeon 			mmc_hostname(host), err);
11060a5b6438SSeungwon Jeon 		return err;
11070a5b6438SSeungwon Jeon 	}
11080a5b6438SSeungwon Jeon 
11090a5b6438SSeungwon Jeon 	err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
11100a5b6438SSeungwon Jeon 			   EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS400,
11110a5b6438SSeungwon Jeon 			   card->ext_csd.generic_cmd6_time,
11120a5b6438SSeungwon Jeon 			   true, true, true);
11130a5b6438SSeungwon Jeon 	if (err) {
11144b75bffcSAndrew Gabbasov 		pr_err("%s: switch to hs400 failed, err:%d\n",
11150a5b6438SSeungwon Jeon 			 mmc_hostname(host), err);
11160a5b6438SSeungwon Jeon 		return err;
11170a5b6438SSeungwon Jeon 	}
11180a5b6438SSeungwon Jeon 
11190a5b6438SSeungwon Jeon 	mmc_set_timing(host, MMC_TIMING_MMC_HS400);
11200a5b6438SSeungwon Jeon 	mmc_set_bus_speed(card);
11210a5b6438SSeungwon Jeon 
11220a5b6438SSeungwon Jeon 	return 0;
11230a5b6438SSeungwon Jeon }
11240a5b6438SSeungwon Jeon 
1125577fb131SSeungwon Jeon /*
1126577fb131SSeungwon Jeon  * For device supporting HS200 mode, the following sequence
1127577fb131SSeungwon Jeon  * should be done before executing the tuning process.
1128577fb131SSeungwon Jeon  * 1. set the desired bus width(4-bit or 8-bit, 1-bit is not supported)
1129577fb131SSeungwon Jeon  * 2. switch to HS200 mode
1130577fb131SSeungwon Jeon  * 3. set the clock to > 52Mhz and <=200MHz
1131577fb131SSeungwon Jeon  */
1132577fb131SSeungwon Jeon static int mmc_select_hs200(struct mmc_card *card)
1133577fb131SSeungwon Jeon {
1134577fb131SSeungwon Jeon 	struct mmc_host *host = card->host;
1135577fb131SSeungwon Jeon 	int err = -EINVAL;
1136577fb131SSeungwon Jeon 
1137577fb131SSeungwon Jeon 	if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200_1_2V)
1138577fb131SSeungwon Jeon 		err = __mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120);
1139577fb131SSeungwon Jeon 
1140577fb131SSeungwon Jeon 	if (err && card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200_1_8V)
1141577fb131SSeungwon Jeon 		err = __mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180);
1142577fb131SSeungwon Jeon 
1143577fb131SSeungwon Jeon 	/* If fails try again during next card power cycle */
1144577fb131SSeungwon Jeon 	if (err)
1145577fb131SSeungwon Jeon 		goto err;
1146577fb131SSeungwon Jeon 
1147577fb131SSeungwon Jeon 	/*
1148577fb131SSeungwon Jeon 	 * Set the bus width(4 or 8) with host's support and
1149577fb131SSeungwon Jeon 	 * switch to HS200 mode if bus width is set successfully.
1150577fb131SSeungwon Jeon 	 */
1151577fb131SSeungwon Jeon 	err = mmc_select_bus_width(card);
1152577fb131SSeungwon Jeon 	if (!IS_ERR_VALUE(err)) {
1153577fb131SSeungwon Jeon 		err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
1154577fb131SSeungwon Jeon 				   EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS200,
1155577fb131SSeungwon Jeon 				   card->ext_csd.generic_cmd6_time,
1156577fb131SSeungwon Jeon 				   true, true, true);
1157577fb131SSeungwon Jeon 		if (!err)
1158577fb131SSeungwon Jeon 			mmc_set_timing(host, MMC_TIMING_MMC_HS200);
1159577fb131SSeungwon Jeon 	}
1160a4924c71SGirish K S err:
1161a4924c71SGirish K S 	return err;
1162a4924c71SGirish K S }
1163a4924c71SGirish K S 
1164a4924c71SGirish K S /*
1165577fb131SSeungwon Jeon  * Activate High Speed or HS200 mode if supported.
1166577fb131SSeungwon Jeon  */
1167577fb131SSeungwon Jeon static int mmc_select_timing(struct mmc_card *card)
1168577fb131SSeungwon Jeon {
1169577fb131SSeungwon Jeon 	int err = 0;
1170577fb131SSeungwon Jeon 
1171148bcab2SUlf Hansson 	if (!mmc_can_ext_csd(card))
1172577fb131SSeungwon Jeon 		goto bus_speed;
1173577fb131SSeungwon Jeon 
1174577fb131SSeungwon Jeon 	if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200)
1175577fb131SSeungwon Jeon 		err = mmc_select_hs200(card);
1176577fb131SSeungwon Jeon 	else if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS)
1177577fb131SSeungwon Jeon 		err = mmc_select_hs(card);
1178577fb131SSeungwon Jeon 
1179577fb131SSeungwon Jeon 	if (err && err != -EBADMSG)
1180577fb131SSeungwon Jeon 		return err;
1181577fb131SSeungwon Jeon 
1182577fb131SSeungwon Jeon 	if (err) {
1183577fb131SSeungwon Jeon 		pr_warn("%s: switch to %s failed\n",
1184577fb131SSeungwon Jeon 			mmc_card_hs(card) ? "high-speed" :
1185577fb131SSeungwon Jeon 			(mmc_card_hs200(card) ? "hs200" : ""),
1186577fb131SSeungwon Jeon 			mmc_hostname(card->host));
1187577fb131SSeungwon Jeon 		err = 0;
1188577fb131SSeungwon Jeon 	}
1189577fb131SSeungwon Jeon 
1190577fb131SSeungwon Jeon bus_speed:
1191577fb131SSeungwon Jeon 	/*
1192577fb131SSeungwon Jeon 	 * Set the bus speed to the selected bus timing.
1193577fb131SSeungwon Jeon 	 * If timing is not selected, backward compatible is the default.
1194577fb131SSeungwon Jeon 	 */
1195577fb131SSeungwon Jeon 	mmc_set_bus_speed(card);
1196577fb131SSeungwon Jeon 	return err;
1197577fb131SSeungwon Jeon }
1198577fb131SSeungwon Jeon 
119948d11e06SStephen Boyd const u8 tuning_blk_pattern_4bit[MMC_TUNING_BLK_PATTERN_4BIT_SIZE] = {
120048d11e06SStephen Boyd 	0xff, 0x0f, 0xff, 0x00, 0xff, 0xcc, 0xc3, 0xcc,
120148d11e06SStephen Boyd 	0xc3, 0x3c, 0xcc, 0xff, 0xfe, 0xff, 0xfe, 0xef,
120248d11e06SStephen Boyd 	0xff, 0xdf, 0xff, 0xdd, 0xff, 0xfb, 0xff, 0xfb,
120348d11e06SStephen Boyd 	0xbf, 0xff, 0x7f, 0xff, 0x77, 0xf7, 0xbd, 0xef,
120448d11e06SStephen Boyd 	0xff, 0xf0, 0xff, 0xf0, 0x0f, 0xfc, 0xcc, 0x3c,
120548d11e06SStephen Boyd 	0xcc, 0x33, 0xcc, 0xcf, 0xff, 0xef, 0xff, 0xee,
120648d11e06SStephen Boyd 	0xff, 0xfd, 0xff, 0xfd, 0xdf, 0xff, 0xbf, 0xff,
120748d11e06SStephen Boyd 	0xbb, 0xff, 0xf7, 0xff, 0xf7, 0x7f, 0x7b, 0xde,
120848d11e06SStephen Boyd };
120948d11e06SStephen Boyd EXPORT_SYMBOL(tuning_blk_pattern_4bit);
121048d11e06SStephen Boyd 
121148d11e06SStephen Boyd const u8 tuning_blk_pattern_8bit[MMC_TUNING_BLK_PATTERN_8BIT_SIZE] = {
121248d11e06SStephen Boyd 	0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00,
121348d11e06SStephen Boyd 	0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, 0xcc,
121448d11e06SStephen Boyd 	0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, 0xff,
121548d11e06SStephen Boyd 	0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, 0xff,
121648d11e06SStephen Boyd 	0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, 0xdd,
121748d11e06SStephen Boyd 	0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb,
121848d11e06SStephen Boyd 	0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, 0xff,
121948d11e06SStephen Boyd 	0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, 0xff,
122048d11e06SStephen Boyd 	0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00,
122148d11e06SStephen Boyd 	0x00, 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc,
122248d11e06SStephen Boyd 	0xcc, 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff,
122348d11e06SStephen Boyd 	0xff, 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee,
122448d11e06SStephen Boyd 	0xff, 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd,
122548d11e06SStephen Boyd 	0xdd, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff,
122648d11e06SStephen Boyd 	0xbb, 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff,
122748d11e06SStephen Boyd 	0xff, 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee,
122848d11e06SStephen Boyd };
122948d11e06SStephen Boyd EXPORT_SYMBOL(tuning_blk_pattern_8bit);
123048d11e06SStephen Boyd 
1231577fb131SSeungwon Jeon /*
1232577fb131SSeungwon Jeon  * Execute tuning sequence to seek the proper bus operating
12330a5b6438SSeungwon Jeon  * conditions for HS200 and HS400, which sends CMD21 to the device.
1234577fb131SSeungwon Jeon  */
1235577fb131SSeungwon Jeon static int mmc_hs200_tuning(struct mmc_card *card)
1236577fb131SSeungwon Jeon {
1237577fb131SSeungwon Jeon 	struct mmc_host *host = card->host;
1238577fb131SSeungwon Jeon 	int err = 0;
1239577fb131SSeungwon Jeon 
12400a5b6438SSeungwon Jeon 	/*
12410a5b6438SSeungwon Jeon 	 * Timing should be adjusted to the HS400 target
12420a5b6438SSeungwon Jeon 	 * operation frequency for tuning process
12430a5b6438SSeungwon Jeon 	 */
12440a5b6438SSeungwon Jeon 	if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400 &&
12450a5b6438SSeungwon Jeon 	    host->ios.bus_width == MMC_BUS_WIDTH_8)
12460a5b6438SSeungwon Jeon 		if (host->ops->prepare_hs400_tuning)
12470a5b6438SSeungwon Jeon 			host->ops->prepare_hs400_tuning(host, &host->ios);
12480a5b6438SSeungwon Jeon 
1249577fb131SSeungwon Jeon 	if (host->ops->execute_tuning) {
1250577fb131SSeungwon Jeon 		mmc_host_clk_hold(host);
1251577fb131SSeungwon Jeon 		err = host->ops->execute_tuning(host,
1252577fb131SSeungwon Jeon 				MMC_SEND_TUNING_BLOCK_HS200);
1253577fb131SSeungwon Jeon 		mmc_host_clk_release(host);
1254577fb131SSeungwon Jeon 
1255577fb131SSeungwon Jeon 		if (err)
12564b75bffcSAndrew Gabbasov 			pr_err("%s: tuning execution failed\n",
1257577fb131SSeungwon Jeon 				mmc_hostname(host));
1258577fb131SSeungwon Jeon 	}
1259577fb131SSeungwon Jeon 
1260577fb131SSeungwon Jeon 	return err;
1261577fb131SSeungwon Jeon }
1262577fb131SSeungwon Jeon 
1263577fb131SSeungwon Jeon /*
12646abaa0c9SPierre Ossman  * Handle the detection and initialisation of a card.
12656abaa0c9SPierre Ossman  *
12668769392bSDeepak Saxena  * In the case of a resume, "oldcard" will contain the card
12676abaa0c9SPierre Ossman  * we're trying to reinitialise.
12687ea239d9SPierre Ossman  */
12698c75deaeSPierre Ossman static int mmc_init_card(struct mmc_host *host, u32 ocr,
12706abaa0c9SPierre Ossman 	struct mmc_card *oldcard)
12717ea239d9SPierre Ossman {
12727ea239d9SPierre Ossman 	struct mmc_card *card;
1273577fb131SSeungwon Jeon 	int err;
12747ea239d9SPierre Ossman 	u32 cid[4];
1275b676f039SPhilip Rakity 	u32 rocr;
12767ea239d9SPierre Ossman 
12777ea239d9SPierre Ossman 	BUG_ON(!host);
1278d84075c8SPierre Ossman 	WARN_ON(!host->claimed);
12797ea239d9SPierre Ossman 
128044669034SStefan Nilsson XK 	/* Set correct bus mode for MMC before attempting init */
128144669034SStefan Nilsson XK 	if (!mmc_host_is_spi(host))
128244669034SStefan Nilsson XK 		mmc_set_bus_mode(host, MMC_BUSMODE_OPENDRAIN);
128344669034SStefan Nilsson XK 
12847ea239d9SPierre Ossman 	/*
12857ea239d9SPierre Ossman 	 * Since we're changing the OCR value, we seem to
12867ea239d9SPierre Ossman 	 * need to tell some cards to go back to the idle
12877ea239d9SPierre Ossman 	 * state.  We wait 1ms to give cards time to
12887ea239d9SPierre Ossman 	 * respond.
1289c3805467SBalaji T K 	 * mmc_go_idle is needed for eMMC that are asleep
12907ea239d9SPierre Ossman 	 */
12917ea239d9SPierre Ossman 	mmc_go_idle(host);
12927ea239d9SPierre Ossman 
12937ea239d9SPierre Ossman 	/* The extra bit indicates that we support high capacity */
1294b676f039SPhilip Rakity 	err = mmc_send_op_cond(host, ocr | (1 << 30), &rocr);
129517b0429dSPierre Ossman 	if (err)
12966abaa0c9SPierre Ossman 		goto err;
12977ea239d9SPierre Ossman 
12987ea239d9SPierre Ossman 	/*
1299af517150SDavid Brownell 	 * For SPI, enable CRC as appropriate.
1300af517150SDavid Brownell 	 */
1301af517150SDavid Brownell 	if (mmc_host_is_spi(host)) {
1302af517150SDavid Brownell 		err = mmc_spi_set_crc(host, use_spi_crc);
1303af517150SDavid Brownell 		if (err)
1304af517150SDavid Brownell 			goto err;
1305af517150SDavid Brownell 	}
1306af517150SDavid Brownell 
1307af517150SDavid Brownell 	/*
13087ea239d9SPierre Ossman 	 * Fetch CID from card.
13097ea239d9SPierre Ossman 	 */
1310af517150SDavid Brownell 	if (mmc_host_is_spi(host))
1311af517150SDavid Brownell 		err = mmc_send_cid(host, cid);
1312af517150SDavid Brownell 	else
13137ea239d9SPierre Ossman 		err = mmc_all_send_cid(host, cid);
131417b0429dSPierre Ossman 	if (err)
13157ea239d9SPierre Ossman 		goto err;
13167ea239d9SPierre Ossman 
13176abaa0c9SPierre Ossman 	if (oldcard) {
1318adf66a0dSPierre Ossman 		if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0) {
1319adf66a0dSPierre Ossman 			err = -ENOENT;
13206abaa0c9SPierre Ossman 			goto err;
1321adf66a0dSPierre Ossman 		}
13226abaa0c9SPierre Ossman 
13236abaa0c9SPierre Ossman 		card = oldcard;
13246abaa0c9SPierre Ossman 	} else {
13257ea239d9SPierre Ossman 		/*
13267ea239d9SPierre Ossman 		 * Allocate card structure.
13277ea239d9SPierre Ossman 		 */
132851ec92e2SPierre Ossman 		card = mmc_alloc_card(host, &mmc_type);
1329adf66a0dSPierre Ossman 		if (IS_ERR(card)) {
1330adf66a0dSPierre Ossman 			err = PTR_ERR(card);
13317ea239d9SPierre Ossman 			goto err;
1332adf66a0dSPierre Ossman 		}
13337ea239d9SPierre Ossman 
133469041150SUlf Hansson 		card->ocr = ocr;
13357ea239d9SPierre Ossman 		card->type = MMC_TYPE_MMC;
13367ea239d9SPierre Ossman 		card->rca = 1;
13377ea239d9SPierre Ossman 		memcpy(card->raw_cid, cid, sizeof(card->raw_cid));
13386abaa0c9SPierre Ossman 	}
13397ea239d9SPierre Ossman 
13407ea239d9SPierre Ossman 	/*
1341af517150SDavid Brownell 	 * For native busses:  set card RCA and quit open drain mode.
13427ea239d9SPierre Ossman 	 */
1343af517150SDavid Brownell 	if (!mmc_host_is_spi(host)) {
13447ea239d9SPierre Ossman 		err = mmc_set_relative_addr(card);
134517b0429dSPierre Ossman 		if (err)
13467ea239d9SPierre Ossman 			goto free_card;
13477ea239d9SPierre Ossman 
13487ea239d9SPierre Ossman 		mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL);
1349af517150SDavid Brownell 	}
13507ea239d9SPierre Ossman 
13516abaa0c9SPierre Ossman 	if (!oldcard) {
13527ea239d9SPierre Ossman 		/*
13537ea239d9SPierre Ossman 		 * Fetch CSD from card.
13547ea239d9SPierre Ossman 		 */
13557ea239d9SPierre Ossman 		err = mmc_send_csd(card, card->raw_csd);
135617b0429dSPierre Ossman 		if (err)
13577ea239d9SPierre Ossman 			goto free_card;
13587ea239d9SPierre Ossman 
1359bd766312SPierre Ossman 		err = mmc_decode_csd(card);
1360adf66a0dSPierre Ossman 		if (err)
1361bd766312SPierre Ossman 			goto free_card;
1362bd766312SPierre Ossman 		err = mmc_decode_cid(card);
1363adf66a0dSPierre Ossman 		if (err)
1364bd766312SPierre Ossman 			goto free_card;
13656abaa0c9SPierre Ossman 	}
13667ea239d9SPierre Ossman 
13677ea239d9SPierre Ossman 	/*
13683d705d14SSascha Hauer 	 * handling only for cards supporting DSR and hosts requesting
13693d705d14SSascha Hauer 	 * DSR configuration
13703d705d14SSascha Hauer 	 */
13713d705d14SSascha Hauer 	if (card->csd.dsr_imp && host->dsr_req)
13723d705d14SSascha Hauer 		mmc_set_dsr(host);
13733d705d14SSascha Hauer 
13743d705d14SSascha Hauer 	/*
137589a73cf5SPierre Ossman 	 * Select card, as all following commands rely on that.
13767ea239d9SPierre Ossman 	 */
1377af517150SDavid Brownell 	if (!mmc_host_is_spi(host)) {
13787ea239d9SPierre Ossman 		err = mmc_select_card(card);
137917b0429dSPierre Ossman 		if (err)
13807ea239d9SPierre Ossman 			goto free_card;
1381af517150SDavid Brownell 	}
13827ea239d9SPierre Ossman 
13836abaa0c9SPierre Ossman 	if (!oldcard) {
1384076ec38aSUlf Hansson 		/* Read extended CSD. */
1385076ec38aSUlf Hansson 		err = mmc_read_ext_csd(card);
138617b0429dSPierre Ossman 		if (err)
13877ea239d9SPierre Ossman 			goto free_card;
1388b676f039SPhilip Rakity 
1389b676f039SPhilip Rakity 		/* If doing byte addressing, check if required to do sector
1390b676f039SPhilip Rakity 		 * addressing.  Handle the case of <2GB cards needing sector
1391b676f039SPhilip Rakity 		 * addressing.  See section 8.1 JEDEC Standard JED84-A441;
1392b676f039SPhilip Rakity 		 * ocr register has bit 30 set for sector addressing.
1393b676f039SPhilip Rakity 		 */
1394b676f039SPhilip Rakity 		if (!(mmc_card_blockaddr(card)) && (rocr & (1<<30)))
1395b676f039SPhilip Rakity 			mmc_card_set_blockaddr(card);
1396b676f039SPhilip Rakity 
1397dfe86cbaSAdrian Hunter 		/* Erase size depends on CSD and Extended CSD */
1398dfe86cbaSAdrian Hunter 		mmc_set_erase_size(card);
13996abaa0c9SPierre Ossman 	}
14007ea239d9SPierre Ossman 
14017ea239d9SPierre Ossman 	/*
1402709de99dSChuanxiao Dong 	 * If enhanced_area_en is TRUE, host needs to enable ERASE_GRP_DEF
1403709de99dSChuanxiao Dong 	 * bit.  This bit will be lost every time after a reset or power off.
1404709de99dSChuanxiao Dong 	 */
140569803d4fSGrégory Soutadé 	if (card->ext_csd.partition_setting_completed ||
140683bb24aaSAdrian Hunter 	    (card->ext_csd.rev >= 3 && (host->caps2 & MMC_CAP2_HC_ERASE_SZ))) {
1407709de99dSChuanxiao Dong 		err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
1408b23cf0bdSSeungwon Jeon 				 EXT_CSD_ERASE_GROUP_DEF, 1,
1409b23cf0bdSSeungwon Jeon 				 card->ext_csd.generic_cmd6_time);
1410709de99dSChuanxiao Dong 
1411709de99dSChuanxiao Dong 		if (err && err != -EBADMSG)
1412709de99dSChuanxiao Dong 			goto free_card;
1413709de99dSChuanxiao Dong 
1414709de99dSChuanxiao Dong 		if (err) {
1415709de99dSChuanxiao Dong 			err = 0;
1416709de99dSChuanxiao Dong 			/*
1417709de99dSChuanxiao Dong 			 * Just disable enhanced area off & sz
1418709de99dSChuanxiao Dong 			 * will try to enable ERASE_GROUP_DEF
1419709de99dSChuanxiao Dong 			 * during next time reinit
1420709de99dSChuanxiao Dong 			 */
1421709de99dSChuanxiao Dong 			card->ext_csd.enhanced_area_offset = -EINVAL;
1422709de99dSChuanxiao Dong 			card->ext_csd.enhanced_area_size = -EINVAL;
1423709de99dSChuanxiao Dong 		} else {
1424709de99dSChuanxiao Dong 			card->ext_csd.erase_group_def = 1;
1425709de99dSChuanxiao Dong 			/*
1426709de99dSChuanxiao Dong 			 * enable ERASE_GRP_DEF successfully.
1427709de99dSChuanxiao Dong 			 * This will affect the erase size, so
1428709de99dSChuanxiao Dong 			 * here need to reset erase size
1429709de99dSChuanxiao Dong 			 */
1430709de99dSChuanxiao Dong 			mmc_set_erase_size(card);
1431709de99dSChuanxiao Dong 		}
1432709de99dSChuanxiao Dong 	}
1433709de99dSChuanxiao Dong 
1434709de99dSChuanxiao Dong 	/*
143541e2a489SPhilip Rakity 	 * Ensure eMMC user default partition is enabled
143641e2a489SPhilip Rakity 	 */
1437371a689fSAndrei Warkentin 	if (card->ext_csd.part_config & EXT_CSD_PART_CONFIG_ACC_MASK) {
1438371a689fSAndrei Warkentin 		card->ext_csd.part_config &= ~EXT_CSD_PART_CONFIG_ACC_MASK;
1439371a689fSAndrei Warkentin 		err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONFIG,
1440371a689fSAndrei Warkentin 				 card->ext_csd.part_config,
1441371a689fSAndrei Warkentin 				 card->ext_csd.part_time);
1442371a689fSAndrei Warkentin 		if (err && err != -EBADMSG)
1443371a689fSAndrei Warkentin 			goto free_card;
144441e2a489SPhilip Rakity 	}
144541e2a489SPhilip Rakity 
144641e2a489SPhilip Rakity 	/*
144743235679SUlf Hansson 	 * Enable power_off_notification byte in the ext_csd register
1448bec8726aSGirish K S 	 */
144943235679SUlf Hansson 	if (card->ext_csd.rev >= 6) {
1450bec8726aSGirish K S 		err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
1451bec8726aSGirish K S 				 EXT_CSD_POWER_OFF_NOTIFICATION,
1452bec8726aSGirish K S 				 EXT_CSD_POWER_ON,
1453bec8726aSGirish K S 				 card->ext_csd.generic_cmd6_time);
1454bec8726aSGirish K S 		if (err && err != -EBADMSG)
1455bec8726aSGirish K S 			goto free_card;
1456bec8726aSGirish K S 
145796a85d54SGirish K S 		/*
145896a85d54SGirish K S 		 * The err can be -EBADMSG or 0,
145996a85d54SGirish K S 		 * so check for success and update the flag
146096a85d54SGirish K S 		 */
1461bec8726aSGirish K S 		if (!err)
1462e6c08586SUlf Hansson 			card->ext_csd.power_off_notification = EXT_CSD_POWER_ON;
146396a85d54SGirish K S 	}
1464bec8726aSGirish K S 
1465bec8726aSGirish K S 	/*
1466577fb131SSeungwon Jeon 	 * Select timing interface
146789a73cf5SPierre Ossman 	 */
1468577fb131SSeungwon Jeon 	err = mmc_select_timing(card);
1469577fb131SSeungwon Jeon 	if (err)
147089a73cf5SPierre Ossman 		goto free_card;
147189a73cf5SPierre Ossman 
1472a4924c71SGirish K S 	if (mmc_card_hs200(card)) {
1473577fb131SSeungwon Jeon 		err = mmc_hs200_tuning(card);
14744c4cb171SPhilip Rakity 		if (err)
14754b75bffcSAndrew Gabbasov 			goto free_card;
14760a5b6438SSeungwon Jeon 
14770a5b6438SSeungwon Jeon 		err = mmc_select_hs400(card);
14780a5b6438SSeungwon Jeon 		if (err)
14794b75bffcSAndrew Gabbasov 			goto free_card;
1480577fb131SSeungwon Jeon 	} else if (mmc_card_hs(card)) {
1481577fb131SSeungwon Jeon 		/* Select the desired bus width optionally */
1482577fb131SSeungwon Jeon 		err = mmc_select_bus_width(card);
1483577fb131SSeungwon Jeon 		if (!IS_ERR_VALUE(err)) {
1484577fb131SSeungwon Jeon 			err = mmc_select_hs_ddr(card);
1485577fb131SSeungwon Jeon 			if (err)
14864b75bffcSAndrew Gabbasov 				goto free_card;
148789a73cf5SPierre Ossman 		}
1488ef0b27d4SAdrian Hunter 	}
148989a73cf5SPierre Ossman 
1490881d1c25SSeungwon Jeon 	/*
14912385049dSSeungwon Jeon 	 * Choose the power class with selected bus interface
14922385049dSSeungwon Jeon 	 */
14932385049dSSeungwon Jeon 	mmc_select_powerclass(card);
14942385049dSSeungwon Jeon 
14952385049dSSeungwon Jeon 	/*
149652d0974eSSubhash Jadavani 	 * Enable HPI feature (if supported)
149752d0974eSSubhash Jadavani 	 */
149852d0974eSSubhash Jadavani 	if (card->ext_csd.hpi) {
149952d0974eSSubhash Jadavani 		err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
150052d0974eSSubhash Jadavani 				EXT_CSD_HPI_MGMT, 1,
150152d0974eSSubhash Jadavani 				card->ext_csd.generic_cmd6_time);
150252d0974eSSubhash Jadavani 		if (err && err != -EBADMSG)
150352d0974eSSubhash Jadavani 			goto free_card;
150452d0974eSSubhash Jadavani 		if (err) {
15056606110dSJoe Perches 			pr_warn("%s: Enabling HPI failed\n",
150652d0974eSSubhash Jadavani 				mmc_hostname(card->host));
150752d0974eSSubhash Jadavani 			err = 0;
150852d0974eSSubhash Jadavani 		} else
150952d0974eSSubhash Jadavani 			card->ext_csd.hpi_en = 1;
151052d0974eSSubhash Jadavani 	}
151152d0974eSSubhash Jadavani 
151252d0974eSSubhash Jadavani 	/*
1513881d1c25SSeungwon Jeon 	 * If cache size is higher than 0, this indicates
1514881d1c25SSeungwon Jeon 	 * the existence of cache and it can be turned on.
1515881d1c25SSeungwon Jeon 	 */
15167536d3f8SUlf Hansson 	if (card->ext_csd.cache_size > 0) {
1517881d1c25SSeungwon Jeon 		err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
15188bc0678bSSeungwon Jeon 				EXT_CSD_CACHE_CTRL, 1,
15198bc0678bSSeungwon Jeon 				card->ext_csd.generic_cmd6_time);
1520881d1c25SSeungwon Jeon 		if (err && err != -EBADMSG)
1521881d1c25SSeungwon Jeon 			goto free_card;
1522881d1c25SSeungwon Jeon 
1523881d1c25SSeungwon Jeon 		/*
1524881d1c25SSeungwon Jeon 		 * Only if no error, cache is turned on successfully.
1525881d1c25SSeungwon Jeon 		 */
15268bc0678bSSeungwon Jeon 		if (err) {
15276606110dSJoe Perches 			pr_warn("%s: Cache is supported, but failed to turn on (%d)\n",
15288bc0678bSSeungwon Jeon 				mmc_hostname(card->host), err);
15298bc0678bSSeungwon Jeon 			card->ext_csd.cache_ctrl = 0;
15308bc0678bSSeungwon Jeon 			err = 0;
15318bc0678bSSeungwon Jeon 		} else {
15328bc0678bSSeungwon Jeon 			card->ext_csd.cache_ctrl = 1;
15338bc0678bSSeungwon Jeon 		}
1534881d1c25SSeungwon Jeon 	}
1535881d1c25SSeungwon Jeon 
1536abd9ac14SSeungwon Jeon 	/*
1537abd9ac14SSeungwon Jeon 	 * The mandatory minimum values are defined for packed command.
1538abd9ac14SSeungwon Jeon 	 * read: 5, write: 3
1539abd9ac14SSeungwon Jeon 	 */
1540abd9ac14SSeungwon Jeon 	if (card->ext_csd.max_packed_writes >= 3 &&
1541abd9ac14SSeungwon Jeon 	    card->ext_csd.max_packed_reads >= 5 &&
1542abd9ac14SSeungwon Jeon 	    host->caps2 & MMC_CAP2_PACKED_CMD) {
1543abd9ac14SSeungwon Jeon 		err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
1544abd9ac14SSeungwon Jeon 				EXT_CSD_EXP_EVENTS_CTRL,
1545abd9ac14SSeungwon Jeon 				EXT_CSD_PACKED_EVENT_EN,
1546abd9ac14SSeungwon Jeon 				card->ext_csd.generic_cmd6_time);
1547abd9ac14SSeungwon Jeon 		if (err && err != -EBADMSG)
1548abd9ac14SSeungwon Jeon 			goto free_card;
1549abd9ac14SSeungwon Jeon 		if (err) {
1550abd9ac14SSeungwon Jeon 			pr_warn("%s: Enabling packed event failed\n",
1551abd9ac14SSeungwon Jeon 				mmc_hostname(card->host));
1552abd9ac14SSeungwon Jeon 			card->ext_csd.packed_event_en = 0;
1553abd9ac14SSeungwon Jeon 			err = 0;
1554abd9ac14SSeungwon Jeon 		} else {
1555abd9ac14SSeungwon Jeon 			card->ext_csd.packed_event_en = 1;
1556abd9ac14SSeungwon Jeon 		}
1557abd9ac14SSeungwon Jeon 	}
1558abd9ac14SSeungwon Jeon 
15596abaa0c9SPierre Ossman 	if (!oldcard)
15607ea239d9SPierre Ossman 		host->card = card;
15617ea239d9SPierre Ossman 
156217b0429dSPierre Ossman 	return 0;
15636abaa0c9SPierre Ossman 
15646abaa0c9SPierre Ossman free_card:
15656abaa0c9SPierre Ossman 	if (!oldcard)
15666abaa0c9SPierre Ossman 		mmc_remove_card(card);
15676abaa0c9SPierre Ossman err:
1568adf66a0dSPierre Ossman 	return err;
15696abaa0c9SPierre Ossman }
15706abaa0c9SPierre Ossman 
157107a68216SUlf Hansson static int mmc_can_sleep(struct mmc_card *card)
157207a68216SUlf Hansson {
157307a68216SUlf Hansson 	return (card && card->ext_csd.rev >= 3);
157407a68216SUlf Hansson }
157507a68216SUlf Hansson 
157607a68216SUlf Hansson static int mmc_sleep(struct mmc_host *host)
157707a68216SUlf Hansson {
157807a68216SUlf Hansson 	struct mmc_command cmd = {0};
157907a68216SUlf Hansson 	struct mmc_card *card = host->card;
1580cb962e04SUlf Hansson 	unsigned int timeout_ms = DIV_ROUND_UP(card->ext_csd.sa_timeout, 10000);
158107a68216SUlf Hansson 	int err;
158207a68216SUlf Hansson 
158307a68216SUlf Hansson 	err = mmc_deselect_cards(host);
158407a68216SUlf Hansson 	if (err)
158507a68216SUlf Hansson 		return err;
158607a68216SUlf Hansson 
158707a68216SUlf Hansson 	cmd.opcode = MMC_SLEEP_AWAKE;
158807a68216SUlf Hansson 	cmd.arg = card->rca << 16;
158907a68216SUlf Hansson 	cmd.arg |= 1 << 15;
159007a68216SUlf Hansson 
1591cb962e04SUlf Hansson 	/*
1592cb962e04SUlf Hansson 	 * If the max_busy_timeout of the host is specified, validate it against
1593cb962e04SUlf Hansson 	 * the sleep cmd timeout. A failure means we need to prevent the host
1594cb962e04SUlf Hansson 	 * from doing hw busy detection, which is done by converting to a R1
1595cb962e04SUlf Hansson 	 * response instead of a R1B.
1596cb962e04SUlf Hansson 	 */
1597cb962e04SUlf Hansson 	if (host->max_busy_timeout && (timeout_ms > host->max_busy_timeout)) {
1598cb962e04SUlf Hansson 		cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
1599cb962e04SUlf Hansson 	} else {
160007a68216SUlf Hansson 		cmd.flags = MMC_RSP_R1B | MMC_CMD_AC;
1601cb962e04SUlf Hansson 		cmd.busy_timeout = timeout_ms;
1602cb962e04SUlf Hansson 	}
1603cb962e04SUlf Hansson 
160407a68216SUlf Hansson 	err = mmc_wait_for_cmd(host, &cmd, 0);
160507a68216SUlf Hansson 	if (err)
160607a68216SUlf Hansson 		return err;
160707a68216SUlf Hansson 
160807a68216SUlf Hansson 	/*
160907a68216SUlf Hansson 	 * If the host does not wait while the card signals busy, then we will
161007a68216SUlf Hansson 	 * will have to wait the sleep/awake timeout.  Note, we cannot use the
161107a68216SUlf Hansson 	 * SEND_STATUS command to poll the status because that command (and most
161207a68216SUlf Hansson 	 * others) is invalid while the card sleeps.
161307a68216SUlf Hansson 	 */
1614cb962e04SUlf Hansson 	if (!cmd.busy_timeout || !(host->caps & MMC_CAP_WAIT_WHILE_BUSY))
1615cb962e04SUlf Hansson 		mmc_delay(timeout_ms);
161607a68216SUlf Hansson 
161707a68216SUlf Hansson 	return err;
161807a68216SUlf Hansson }
161907a68216SUlf Hansson 
1620e6c08586SUlf Hansson static int mmc_can_poweroff_notify(const struct mmc_card *card)
1621e6c08586SUlf Hansson {
1622e6c08586SUlf Hansson 	return card &&
1623e6c08586SUlf Hansson 		mmc_card_mmc(card) &&
1624e6c08586SUlf Hansson 		(card->ext_csd.power_off_notification == EXT_CSD_POWER_ON);
1625e6c08586SUlf Hansson }
1626e6c08586SUlf Hansson 
1627e6c08586SUlf Hansson static int mmc_poweroff_notify(struct mmc_card *card, unsigned int notify_type)
1628e6c08586SUlf Hansson {
1629e6c08586SUlf Hansson 	unsigned int timeout = card->ext_csd.generic_cmd6_time;
1630e6c08586SUlf Hansson 	int err;
1631e6c08586SUlf Hansson 
1632e6c08586SUlf Hansson 	/* Use EXT_CSD_POWER_OFF_SHORT as default notification type. */
1633e6c08586SUlf Hansson 	if (notify_type == EXT_CSD_POWER_OFF_LONG)
1634e6c08586SUlf Hansson 		timeout = card->ext_csd.power_off_longtime;
1635e6c08586SUlf Hansson 
1636878e200bSUlf Hansson 	err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
1637e6c08586SUlf Hansson 			EXT_CSD_POWER_OFF_NOTIFICATION,
16384509f847SUlf Hansson 			notify_type, timeout, true, false, false);
1639e6c08586SUlf Hansson 	if (err)
1640e6c08586SUlf Hansson 		pr_err("%s: Power Off Notification timed out, %u\n",
1641e6c08586SUlf Hansson 		       mmc_hostname(card->host), timeout);
1642e6c08586SUlf Hansson 
1643e6c08586SUlf Hansson 	/* Disable the power off notification after the switch operation. */
1644e6c08586SUlf Hansson 	card->ext_csd.power_off_notification = EXT_CSD_NO_POWER_NOTIFICATION;
1645e6c08586SUlf Hansson 
1646e6c08586SUlf Hansson 	return err;
1647e6c08586SUlf Hansson }
1648e6c08586SUlf Hansson 
16496abaa0c9SPierre Ossman /*
16506abaa0c9SPierre Ossman  * Host is being removed. Free up the current card.
16516abaa0c9SPierre Ossman  */
16526abaa0c9SPierre Ossman static void mmc_remove(struct mmc_host *host)
16536abaa0c9SPierre Ossman {
16546abaa0c9SPierre Ossman 	BUG_ON(!host);
16556abaa0c9SPierre Ossman 	BUG_ON(!host->card);
16566abaa0c9SPierre Ossman 
16576abaa0c9SPierre Ossman 	mmc_remove_card(host->card);
16586abaa0c9SPierre Ossman 	host->card = NULL;
16596abaa0c9SPierre Ossman }
16606abaa0c9SPierre Ossman 
16616abaa0c9SPierre Ossman /*
1662d3049504SAdrian Hunter  * Card detection - card is alive.
1663d3049504SAdrian Hunter  */
1664d3049504SAdrian Hunter static int mmc_alive(struct mmc_host *host)
1665d3049504SAdrian Hunter {
1666d3049504SAdrian Hunter 	return mmc_send_status(host->card, NULL);
1667d3049504SAdrian Hunter }
1668d3049504SAdrian Hunter 
1669d3049504SAdrian Hunter /*
16706abaa0c9SPierre Ossman  * Card detection callback from host.
16716abaa0c9SPierre Ossman  */
16726abaa0c9SPierre Ossman static void mmc_detect(struct mmc_host *host)
16736abaa0c9SPierre Ossman {
16746abaa0c9SPierre Ossman 	int err;
16756abaa0c9SPierre Ossman 
16766abaa0c9SPierre Ossman 	BUG_ON(!host);
16776abaa0c9SPierre Ossman 	BUG_ON(!host->card);
16786abaa0c9SPierre Ossman 
1679e94cfef6SUlf Hansson 	mmc_get_card(host->card);
16806abaa0c9SPierre Ossman 
16816abaa0c9SPierre Ossman 	/*
16826abaa0c9SPierre Ossman 	 * Just check if our card has been removed.
16836abaa0c9SPierre Ossman 	 */
1684d3049504SAdrian Hunter 	err = _mmc_detect_card_removed(host);
16856abaa0c9SPierre Ossman 
1686e94cfef6SUlf Hansson 	mmc_put_card(host->card);
16877ea239d9SPierre Ossman 
168817b0429dSPierre Ossman 	if (err) {
16894101c16aSPierre Ossman 		mmc_remove(host);
16906abaa0c9SPierre Ossman 
16916abaa0c9SPierre Ossman 		mmc_claim_host(host);
16926abaa0c9SPierre Ossman 		mmc_detach_bus(host);
16937f7e4129SUlf Hansson 		mmc_power_off(host);
16946abaa0c9SPierre Ossman 		mmc_release_host(host);
16956abaa0c9SPierre Ossman 	}
16966abaa0c9SPierre Ossman }
16976abaa0c9SPierre Ossman 
169803d071fcSUlf Hansson static int _mmc_suspend(struct mmc_host *host, bool is_suspend)
16996abaa0c9SPierre Ossman {
1700c3805467SBalaji T K 	int err = 0;
170103d071fcSUlf Hansson 	unsigned int notify_type = is_suspend ? EXT_CSD_POWER_OFF_SHORT :
170203d071fcSUlf Hansson 					EXT_CSD_POWER_OFF_LONG;
1703c3805467SBalaji T K 
17046abaa0c9SPierre Ossman 	BUG_ON(!host);
17056abaa0c9SPierre Ossman 	BUG_ON(!host->card);
17066abaa0c9SPierre Ossman 
17076abaa0c9SPierre Ossman 	mmc_claim_host(host);
1708881d926dSMaya Erez 
17099ec775f7SUlf Hansson 	if (mmc_card_suspended(host->card))
17109ec775f7SUlf Hansson 		goto out;
17119ec775f7SUlf Hansson 
171239b9431bSUlf Hansson 	if (mmc_card_doing_bkops(host->card)) {
171339b9431bSUlf Hansson 		err = mmc_stop_bkops(host->card);
171439b9431bSUlf Hansson 		if (err)
171539b9431bSUlf Hansson 			goto out;
171639b9431bSUlf Hansson 	}
171739b9431bSUlf Hansson 
171810e5d965SUlf Hansson 	err = mmc_flush_cache(host->card);
1719881d926dSMaya Erez 	if (err)
1720881d926dSMaya Erez 		goto out;
1721881d926dSMaya Erez 
172243235679SUlf Hansson 	if (mmc_can_poweroff_notify(host->card) &&
172353275c21SUlf Hansson 		((host->caps2 & MMC_CAP2_FULL_PWR_CYCLE) || !is_suspend))
172403d071fcSUlf Hansson 		err = mmc_poweroff_notify(host->card, notify_type);
172507a68216SUlf Hansson 	else if (mmc_can_sleep(host->card))
172607a68216SUlf Hansson 		err = mmc_sleep(host);
1727e6c08586SUlf Hansson 	else if (!mmc_host_is_spi(host))
172885e727edSJaehoon Chung 		err = mmc_deselect_cards(host);
172995cdfb72SNicolas Pitre 
17309ec775f7SUlf Hansson 	if (!err) {
173174590263SUlf Hansson 		mmc_power_off(host);
17329ec775f7SUlf Hansson 		mmc_card_set_suspended(host->card);
17339ec775f7SUlf Hansson 	}
1734881d926dSMaya Erez out:
1735881d926dSMaya Erez 	mmc_release_host(host);
1736c3805467SBalaji T K 	return err;
17376abaa0c9SPierre Ossman }
17386abaa0c9SPierre Ossman 
17396abaa0c9SPierre Ossman /*
17400cb403a2SUlf Hansson  * Suspend callback
174103d071fcSUlf Hansson  */
174203d071fcSUlf Hansson static int mmc_suspend(struct mmc_host *host)
174303d071fcSUlf Hansson {
17440cb403a2SUlf Hansson 	int err;
17450cb403a2SUlf Hansson 
17460cb403a2SUlf Hansson 	err = _mmc_suspend(host, true);
17470cb403a2SUlf Hansson 	if (!err) {
17480cb403a2SUlf Hansson 		pm_runtime_disable(&host->card->dev);
17490cb403a2SUlf Hansson 		pm_runtime_set_suspended(&host->card->dev);
17500cb403a2SUlf Hansson 	}
17510cb403a2SUlf Hansson 
17520cb403a2SUlf Hansson 	return err;
175303d071fcSUlf Hansson }
175403d071fcSUlf Hansson 
175503d071fcSUlf Hansson /*
17566abaa0c9SPierre Ossman  * This function tries to determine if the same card is still present
17576abaa0c9SPierre Ossman  * and, if so, restore all state to it.
17586abaa0c9SPierre Ossman  */
17590cb403a2SUlf Hansson static int _mmc_resume(struct mmc_host *host)
17606abaa0c9SPierre Ossman {
17619ec775f7SUlf Hansson 	int err = 0;
17626abaa0c9SPierre Ossman 
17636abaa0c9SPierre Ossman 	BUG_ON(!host);
17646abaa0c9SPierre Ossman 	BUG_ON(!host->card);
17656abaa0c9SPierre Ossman 
17666abaa0c9SPierre Ossman 	mmc_claim_host(host);
17679ec775f7SUlf Hansson 
17689ec775f7SUlf Hansson 	if (!mmc_card_suspended(host->card))
17699ec775f7SUlf Hansson 		goto out;
17709ec775f7SUlf Hansson 
177169041150SUlf Hansson 	mmc_power_up(host, host->card->ocr);
177269041150SUlf Hansson 	err = mmc_init_card(host, host->card->ocr, host->card);
17739ec775f7SUlf Hansson 	mmc_card_clr_suspended(host->card);
17742986d0bfSPierre Ossman 
17759ec775f7SUlf Hansson out:
17769ec775f7SUlf Hansson 	mmc_release_host(host);
177795cdfb72SNicolas Pitre 	return err;
17786abaa0c9SPierre Ossman }
17796abaa0c9SPierre Ossman 
17809ec775f7SUlf Hansson /*
17819ec775f7SUlf Hansson  * Shutdown callback
17829ec775f7SUlf Hansson  */
17839ec775f7SUlf Hansson static int mmc_shutdown(struct mmc_host *host)
17849ec775f7SUlf Hansson {
17859ec775f7SUlf Hansson 	int err = 0;
17869ec775f7SUlf Hansson 
17879ec775f7SUlf Hansson 	/*
17889ec775f7SUlf Hansson 	 * In a specific case for poweroff notify, we need to resume the card
17899ec775f7SUlf Hansson 	 * before we can shutdown it properly.
17909ec775f7SUlf Hansson 	 */
17919ec775f7SUlf Hansson 	if (mmc_can_poweroff_notify(host->card) &&
17929ec775f7SUlf Hansson 		!(host->caps2 & MMC_CAP2_FULL_PWR_CYCLE))
17930cb403a2SUlf Hansson 		err = _mmc_resume(host);
17949ec775f7SUlf Hansson 
17959ec775f7SUlf Hansson 	if (!err)
17969ec775f7SUlf Hansson 		err = _mmc_suspend(host, false);
17979ec775f7SUlf Hansson 
17989ec775f7SUlf Hansson 	return err;
17999ec775f7SUlf Hansson }
1800c4d770d7SUlf Hansson 
1801c4d770d7SUlf Hansson /*
18020cb403a2SUlf Hansson  * Callback for resume.
18030cb403a2SUlf Hansson  */
18040cb403a2SUlf Hansson static int mmc_resume(struct mmc_host *host)
18050cb403a2SUlf Hansson {
18064d223782SUlf Hansson 	int err = 0;
18070cb403a2SUlf Hansson 
18084d223782SUlf Hansson 	if (!(host->caps & MMC_CAP_RUNTIME_RESUME)) {
18090cb403a2SUlf Hansson 		err = _mmc_resume(host);
18100cb403a2SUlf Hansson 		pm_runtime_set_active(&host->card->dev);
18110cb403a2SUlf Hansson 		pm_runtime_mark_last_busy(&host->card->dev);
18124d223782SUlf Hansson 	}
18130cb403a2SUlf Hansson 	pm_runtime_enable(&host->card->dev);
18140cb403a2SUlf Hansson 
18150cb403a2SUlf Hansson 	return err;
18160cb403a2SUlf Hansson }
18170cb403a2SUlf Hansson 
18180cb403a2SUlf Hansson /*
1819c4d770d7SUlf Hansson  * Callback for runtime_suspend.
1820c4d770d7SUlf Hansson  */
1821c4d770d7SUlf Hansson static int mmc_runtime_suspend(struct mmc_host *host)
1822c4d770d7SUlf Hansson {
1823c4d770d7SUlf Hansson 	int err;
1824c4d770d7SUlf Hansson 
1825c4d770d7SUlf Hansson 	if (!(host->caps & MMC_CAP_AGGRESSIVE_PM))
1826c4d770d7SUlf Hansson 		return 0;
1827c4d770d7SUlf Hansson 
18280cb403a2SUlf Hansson 	err = _mmc_suspend(host, true);
18290cc81a8cSUlf Hansson 	if (err)
1830c4d770d7SUlf Hansson 		pr_err("%s: error %d doing aggessive suspend\n",
1831c4d770d7SUlf Hansson 			mmc_hostname(host), err);
1832c4d770d7SUlf Hansson 
1833c4d770d7SUlf Hansson 	return err;
1834c4d770d7SUlf Hansson }
1835c4d770d7SUlf Hansson 
1836c4d770d7SUlf Hansson /*
1837c4d770d7SUlf Hansson  * Callback for runtime_resume.
1838c4d770d7SUlf Hansson  */
1839c4d770d7SUlf Hansson static int mmc_runtime_resume(struct mmc_host *host)
1840c4d770d7SUlf Hansson {
1841c4d770d7SUlf Hansson 	int err;
1842c4d770d7SUlf Hansson 
18434d223782SUlf Hansson 	if (!(host->caps & (MMC_CAP_AGGRESSIVE_PM | MMC_CAP_RUNTIME_RESUME)))
1844c4d770d7SUlf Hansson 		return 0;
1845c4d770d7SUlf Hansson 
18460cb403a2SUlf Hansson 	err = _mmc_resume(host);
1847c4d770d7SUlf Hansson 	if (err)
1848c4d770d7SUlf Hansson 		pr_err("%s: error %d doing aggessive resume\n",
1849c4d770d7SUlf Hansson 			mmc_hostname(host), err);
1850c4d770d7SUlf Hansson 
1851c4d770d7SUlf Hansson 	return 0;
1852c4d770d7SUlf Hansson }
1853c4d770d7SUlf Hansson 
185412ae637fSOhad Ben-Cohen static int mmc_power_restore(struct mmc_host *host)
1855eae1aeeeSAdrian Hunter {
185612ae637fSOhad Ben-Cohen 	int ret;
185712ae637fSOhad Ben-Cohen 
1858eae1aeeeSAdrian Hunter 	mmc_claim_host(host);
185969041150SUlf Hansson 	ret = mmc_init_card(host, host->card->ocr, host->card);
1860eae1aeeeSAdrian Hunter 	mmc_release_host(host);
186112ae637fSOhad Ben-Cohen 
186212ae637fSOhad Ben-Cohen 	return ret;
1863eae1aeeeSAdrian Hunter }
1864eae1aeeeSAdrian Hunter 
18659feae246SAdrian Hunter static const struct mmc_bus_ops mmc_ops = {
18669feae246SAdrian Hunter 	.remove = mmc_remove,
18679feae246SAdrian Hunter 	.detect = mmc_detect,
18689feae246SAdrian Hunter 	.suspend = mmc_suspend,
18699feae246SAdrian Hunter 	.resume = mmc_resume,
1870c4d770d7SUlf Hansson 	.runtime_suspend = mmc_runtime_suspend,
1871c4d770d7SUlf Hansson 	.runtime_resume = mmc_runtime_resume,
1872eae1aeeeSAdrian Hunter 	.power_restore = mmc_power_restore,
1873d3049504SAdrian Hunter 	.alive = mmc_alive,
1874486fdbbcSUlf Hansson 	.shutdown = mmc_shutdown,
18759feae246SAdrian Hunter };
18769feae246SAdrian Hunter 
18776abaa0c9SPierre Ossman /*
18786abaa0c9SPierre Ossman  * Starting point for MMC card init.
18796abaa0c9SPierre Ossman  */
1880807e8e40SAndy Ross int mmc_attach_mmc(struct mmc_host *host)
18816abaa0c9SPierre Ossman {
18826abaa0c9SPierre Ossman 	int err;
188369041150SUlf Hansson 	u32 ocr, rocr;
18846abaa0c9SPierre Ossman 
18856abaa0c9SPierre Ossman 	BUG_ON(!host);
1886d84075c8SPierre Ossman 	WARN_ON(!host->claimed);
18876abaa0c9SPierre Ossman 
188844669034SStefan Nilsson XK 	/* Set correct bus mode for MMC before attempting attach */
188944669034SStefan Nilsson XK 	if (!mmc_host_is_spi(host))
189044669034SStefan Nilsson XK 		mmc_set_bus_mode(host, MMC_BUSMODE_OPENDRAIN);
189144669034SStefan Nilsson XK 
1892807e8e40SAndy Ross 	err = mmc_send_op_cond(host, 0, &ocr);
1893807e8e40SAndy Ross 	if (err)
1894807e8e40SAndy Ross 		return err;
1895807e8e40SAndy Ross 
18962501c917SUlf Hansson 	mmc_attach_bus(host, &mmc_ops);
18978f230f45STakashi Iwai 	if (host->ocr_avail_mmc)
18988f230f45STakashi Iwai 		host->ocr_avail = host->ocr_avail_mmc;
18996abaa0c9SPierre Ossman 
19006abaa0c9SPierre Ossman 	/*
1901af517150SDavid Brownell 	 * We need to get OCR a different way for SPI.
1902af517150SDavid Brownell 	 */
1903af517150SDavid Brownell 	if (mmc_host_is_spi(host)) {
1904af517150SDavid Brownell 		err = mmc_spi_read_ocr(host, 1, &ocr);
1905af517150SDavid Brownell 		if (err)
1906af517150SDavid Brownell 			goto err;
1907af517150SDavid Brownell 	}
1908af517150SDavid Brownell 
190969041150SUlf Hansson 	rocr = mmc_select_voltage(host, ocr);
19106abaa0c9SPierre Ossman 
19116abaa0c9SPierre Ossman 	/*
19126abaa0c9SPierre Ossman 	 * Can we support the voltage of the card?
19136abaa0c9SPierre Ossman 	 */
191469041150SUlf Hansson 	if (!rocr) {
1915109b5bedSPierre Ossman 		err = -EINVAL;
19166abaa0c9SPierre Ossman 		goto err;
1917109b5bedSPierre Ossman 	}
19186abaa0c9SPierre Ossman 
19196abaa0c9SPierre Ossman 	/*
19206abaa0c9SPierre Ossman 	 * Detect and init the card.
19216abaa0c9SPierre Ossman 	 */
192269041150SUlf Hansson 	err = mmc_init_card(host, rocr, NULL);
192317b0429dSPierre Ossman 	if (err)
19246abaa0c9SPierre Ossman 		goto err;
19256abaa0c9SPierre Ossman 
19266abaa0c9SPierre Ossman 	mmc_release_host(host);
19274101c16aSPierre Ossman 	err = mmc_add_card(host->card);
1928807e8e40SAndy Ross 	mmc_claim_host(host);
19297ea239d9SPierre Ossman 	if (err)
19302986d0bfSPierre Ossman 		goto remove_card;
19317ea239d9SPierre Ossman 
19327ea239d9SPierre Ossman 	return 0;
19337ea239d9SPierre Ossman 
19342986d0bfSPierre Ossman remove_card:
1935807e8e40SAndy Ross 	mmc_release_host(host);
19366abaa0c9SPierre Ossman 	mmc_remove_card(host->card);
19372986d0bfSPierre Ossman 	mmc_claim_host(host);
1938807e8e40SAndy Ross 	host->card = NULL;
19397ea239d9SPierre Ossman err:
19407ea239d9SPierre Ossman 	mmc_detach_bus(host);
19417ea239d9SPierre Ossman 
1942a3c76eb9SGirish K S 	pr_err("%s: error %d whilst initialising MMC card\n",
1943109b5bedSPierre Ossman 		mmc_hostname(host), err);
1944109b5bedSPierre Ossman 
1945adf66a0dSPierre Ossman 	return err;
19467ea239d9SPierre Ossman }
1947