| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * linux/drivers/mmc/core/mmc.c |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright (C) 2003-2004 Russell King, All Rights Reserved. |
|---|
| 5 | 6 | * Copyright (C) 2005-2007 Pierre Ossman, All Rights Reserved. |
|---|
| 6 | 7 | * MMCv4 support Copyright (C) 2006 Philip Langdale, All Rights Reserved. |
|---|
| 7 | | - * |
|---|
| 8 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 9 | | - * it under the terms of the GNU General Public License version 2 as |
|---|
| 10 | | - * published by the Free Software Foundation. |
|---|
| 11 | 8 | */ |
|---|
| 12 | 9 | |
|---|
| 13 | 10 | #include <linux/err.h> |
|---|
| .. | .. |
|---|
| 661 | 658 | mmc_hostname(card->host), |
|---|
| 662 | 659 | card->ext_csd.cmdq_depth); |
|---|
| 663 | 660 | } |
|---|
| 661 | + card->ext_csd.enhanced_rpmb_supported = |
|---|
| 662 | + (card->ext_csd.rel_param & |
|---|
| 663 | + EXT_CSD_WR_REL_PARAM_EN_RPMB_REL_WR); |
|---|
| 664 | 664 | } |
|---|
| 665 | 665 | out: |
|---|
| 666 | 666 | return err; |
|---|
| .. | .. |
|---|
| 697 | 697 | u8 *ext_csd; |
|---|
| 698 | 698 | int err; |
|---|
| 699 | 699 | #ifdef CONFIG_ROCKCHIP_THUNDER_BOOT_MMC |
|---|
| 700 | | - void *ecsd = NULL; |
|---|
| 700 | + void *ecsd; |
|---|
| 701 | 701 | bool valid_ecsd = false; |
|---|
| 702 | 702 | bool valid_reserved = false; |
|---|
| 703 | 703 | struct device_node *mem; |
|---|
| .. | .. |
|---|
| 875 | 875 | card->ext_csd.enhanced_area_offset); |
|---|
| 876 | 876 | MMC_DEV_ATTR(enhanced_area_size, "%u\n", card->ext_csd.enhanced_area_size); |
|---|
| 877 | 877 | MMC_DEV_ATTR(raw_rpmb_size_mult, "%#x\n", card->ext_csd.raw_rpmb_size_mult); |
|---|
| 878 | +MMC_DEV_ATTR(enhanced_rpmb_supported, "%#x\n", |
|---|
| 879 | + card->ext_csd.enhanced_rpmb_supported); |
|---|
| 878 | 880 | MMC_DEV_ATTR(rel_sectors, "%#x\n", card->ext_csd.rel_sectors); |
|---|
| 879 | 881 | MMC_DEV_ATTR(ocr, "0x%08x\n", card->ocr); |
|---|
| 880 | 882 | MMC_DEV_ATTR(rca, "0x%04x\n", card->rca); |
|---|
| .. | .. |
|---|
| 932 | 934 | &dev_attr_enhanced_area_offset.attr, |
|---|
| 933 | 935 | &dev_attr_enhanced_area_size.attr, |
|---|
| 934 | 936 | &dev_attr_raw_rpmb_size_mult.attr, |
|---|
| 937 | + &dev_attr_enhanced_rpmb_supported.attr, |
|---|
| 935 | 938 | &dev_attr_rel_sectors.attr, |
|---|
| 936 | 939 | &dev_attr_ocr.attr, |
|---|
| 937 | 940 | &dev_attr_rca.attr, |
|---|
| .. | .. |
|---|
| 1048 | 1051 | /* |
|---|
| 1049 | 1052 | * Set the bus speed for the selected speed mode. |
|---|
| 1050 | 1053 | */ |
|---|
| 1051 | | -static void mmc_set_bus_speed(struct mmc_card *card) |
|---|
| 1054 | +void mmc_set_bus_speed(struct mmc_card *card) |
|---|
| 1052 | 1055 | { |
|---|
| 1053 | 1056 | unsigned int max_dtr = (unsigned int)-1; |
|---|
| 1054 | 1057 | |
|---|
| .. | .. |
|---|
| 1068 | 1071 | * If the bus width is changed successfully, return the selected width value. |
|---|
| 1069 | 1072 | * Zero is returned instead of error value if the wide width is not supported. |
|---|
| 1070 | 1073 | */ |
|---|
| 1071 | | -static int mmc_select_bus_width(struct mmc_card *card) |
|---|
| 1074 | +int mmc_select_bus_width(struct mmc_card *card) |
|---|
| 1072 | 1075 | { |
|---|
| 1073 | 1076 | static unsigned ext_csd_bits[] = { |
|---|
| 1074 | 1077 | EXT_CSD_BUS_WIDTH_8, |
|---|
| .. | .. |
|---|
| 1134 | 1137 | |
|---|
| 1135 | 1138 | return err; |
|---|
| 1136 | 1139 | } |
|---|
| 1140 | +EXPORT_SYMBOL_GPL(mmc_select_bus_width); |
|---|
| 1137 | 1141 | |
|---|
| 1138 | 1142 | /* |
|---|
| 1139 | 1143 | * Switch to the high-speed mode |
|---|
| 1140 | 1144 | */ |
|---|
| 1141 | | -static int mmc_select_hs(struct mmc_card *card) |
|---|
| 1145 | +int mmc_select_hs(struct mmc_card *card) |
|---|
| 1142 | 1146 | { |
|---|
| 1143 | 1147 | int err; |
|---|
| 1144 | 1148 | |
|---|
| 1145 | 1149 | err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, |
|---|
| 1146 | 1150 | EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS, |
|---|
| 1147 | 1151 | card->ext_csd.generic_cmd6_time, MMC_TIMING_MMC_HS, |
|---|
| 1148 | | - true, true, true); |
|---|
| 1152 | + true, true); |
|---|
| 1149 | 1153 | if (err) |
|---|
| 1150 | 1154 | pr_warn("%s: switch to high-speed failed, err:%d\n", |
|---|
| 1151 | 1155 | mmc_hostname(card->host), err); |
|---|
| 1152 | 1156 | |
|---|
| 1153 | 1157 | return err; |
|---|
| 1154 | 1158 | } |
|---|
| 1159 | +EXPORT_SYMBOL_GPL(mmc_select_hs); |
|---|
| 1155 | 1160 | |
|---|
| 1156 | 1161 | /* |
|---|
| 1157 | 1162 | * Activate wide bus and DDR if supported. |
|---|
| 1158 | 1163 | */ |
|---|
| 1159 | | -static int mmc_select_hs_ddr(struct mmc_card *card) |
|---|
| 1164 | +int mmc_select_hs_ddr(struct mmc_card *card) |
|---|
| 1160 | 1165 | { |
|---|
| 1161 | 1166 | struct mmc_host *host = card->host; |
|---|
| 1162 | 1167 | u32 bus_width, ext_csd_bits; |
|---|
| .. | .. |
|---|
| 1177 | 1182 | ext_csd_bits, |
|---|
| 1178 | 1183 | card->ext_csd.generic_cmd6_time, |
|---|
| 1179 | 1184 | MMC_TIMING_MMC_DDR52, |
|---|
| 1180 | | - true, true, true); |
|---|
| 1185 | + true, true); |
|---|
| 1181 | 1186 | if (err) { |
|---|
| 1182 | 1187 | pr_err("%s: switch to bus width %d ddr failed\n", |
|---|
| 1183 | 1188 | mmc_hostname(host), 1 << bus_width); |
|---|
| .. | .. |
|---|
| 1225 | 1230 | |
|---|
| 1226 | 1231 | return err; |
|---|
| 1227 | 1232 | } |
|---|
| 1233 | +EXPORT_SYMBOL_GPL(mmc_select_hs_ddr); |
|---|
| 1228 | 1234 | |
|---|
| 1229 | | -static int mmc_select_hs400(struct mmc_card *card) |
|---|
| 1235 | +int mmc_select_hs400(struct mmc_card *card) |
|---|
| 1230 | 1236 | { |
|---|
| 1231 | 1237 | struct mmc_host *host = card->host; |
|---|
| 1232 | 1238 | unsigned int max_dtr; |
|---|
| .. | .. |
|---|
| 1245 | 1251 | err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, |
|---|
| 1246 | 1252 | EXT_CSD_HS_TIMING, val, |
|---|
| 1247 | 1253 | card->ext_csd.generic_cmd6_time, 0, |
|---|
| 1248 | | - true, false, true); |
|---|
| 1254 | + false, true); |
|---|
| 1249 | 1255 | if (err) { |
|---|
| 1250 | 1256 | pr_err("%s: switch to high-speed from hs200 failed, err:%d\n", |
|---|
| 1251 | 1257 | mmc_hostname(host), err); |
|---|
| 1252 | 1258 | return err; |
|---|
| 1253 | 1259 | } |
|---|
| 1254 | 1260 | |
|---|
| 1255 | | - /* Set host controller to HS timing */ |
|---|
| 1256 | | - mmc_set_timing(card->host, MMC_TIMING_MMC_HS); |
|---|
| 1257 | | - |
|---|
| 1258 | 1261 | /* Prepare host to downgrade to HS timing */ |
|---|
| 1259 | 1262 | if (host->ops->hs400_downgrade) |
|---|
| 1260 | 1263 | host->ops->hs400_downgrade(host); |
|---|
| 1264 | + |
|---|
| 1265 | + /* Set host controller to HS timing */ |
|---|
| 1266 | + mmc_set_timing(host, MMC_TIMING_MMC_HS); |
|---|
| 1261 | 1267 | |
|---|
| 1262 | 1268 | /* Reduce frequency to HS frequency */ |
|---|
| 1263 | 1269 | max_dtr = card->ext_csd.hs_max_dtr; |
|---|
| 1264 | 1270 | mmc_set_clock(host, max_dtr); |
|---|
| 1265 | 1271 | |
|---|
| 1266 | | - err = mmc_switch_status(card); |
|---|
| 1272 | + err = mmc_switch_status(card, true); |
|---|
| 1267 | 1273 | if (err) |
|---|
| 1268 | 1274 | goto out_err; |
|---|
| 1275 | + |
|---|
| 1276 | + if (host->ops->hs400_prepare_ddr) |
|---|
| 1277 | + host->ops->hs400_prepare_ddr(host); |
|---|
| 1269 | 1278 | |
|---|
| 1270 | 1279 | /* Switch card to DDR */ |
|---|
| 1271 | 1280 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, |
|---|
| .. | .. |
|---|
| 1284 | 1293 | err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, |
|---|
| 1285 | 1294 | EXT_CSD_HS_TIMING, val, |
|---|
| 1286 | 1295 | card->ext_csd.generic_cmd6_time, 0, |
|---|
| 1287 | | - true, false, true); |
|---|
| 1296 | + false, true); |
|---|
| 1288 | 1297 | if (err) { |
|---|
| 1289 | 1298 | pr_err("%s: switch to hs400 failed, err:%d\n", |
|---|
| 1290 | 1299 | mmc_hostname(host), err); |
|---|
| .. | .. |
|---|
| 1298 | 1307 | if (host->ops->hs400_complete) |
|---|
| 1299 | 1308 | host->ops->hs400_complete(host); |
|---|
| 1300 | 1309 | |
|---|
| 1301 | | - err = mmc_switch_status(card); |
|---|
| 1310 | + err = mmc_switch_status(card, true); |
|---|
| 1302 | 1311 | if (err) |
|---|
| 1303 | 1312 | goto out_err; |
|---|
| 1304 | 1313 | |
|---|
| .. | .. |
|---|
| 1309 | 1318 | __func__, err); |
|---|
| 1310 | 1319 | return err; |
|---|
| 1311 | 1320 | } |
|---|
| 1321 | +EXPORT_SYMBOL_GPL(mmc_select_hs400); |
|---|
| 1312 | 1322 | |
|---|
| 1313 | 1323 | int mmc_hs200_to_hs400(struct mmc_card *card) |
|---|
| 1314 | 1324 | { |
|---|
| .. | .. |
|---|
| 1330 | 1340 | val = EXT_CSD_TIMING_HS; |
|---|
| 1331 | 1341 | err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, |
|---|
| 1332 | 1342 | val, card->ext_csd.generic_cmd6_time, 0, |
|---|
| 1333 | | - true, false, true); |
|---|
| 1343 | + false, true); |
|---|
| 1334 | 1344 | if (err) |
|---|
| 1335 | 1345 | goto out_err; |
|---|
| 1336 | 1346 | |
|---|
| 1347 | + if (host->ops->hs400_downgrade) |
|---|
| 1348 | + host->ops->hs400_downgrade(host); |
|---|
| 1349 | + |
|---|
| 1337 | 1350 | mmc_set_timing(host, MMC_TIMING_MMC_DDR52); |
|---|
| 1338 | 1351 | |
|---|
| 1339 | | - err = mmc_switch_status(card); |
|---|
| 1352 | + err = mmc_switch_status(card, true); |
|---|
| 1340 | 1353 | if (err) |
|---|
| 1341 | 1354 | goto out_err; |
|---|
| 1342 | 1355 | |
|---|
| 1343 | 1356 | /* Switch HS DDR to HS */ |
|---|
| 1344 | 1357 | err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH, |
|---|
| 1345 | 1358 | EXT_CSD_BUS_WIDTH_8, card->ext_csd.generic_cmd6_time, |
|---|
| 1346 | | - 0, true, false, true); |
|---|
| 1359 | + 0, false, true); |
|---|
| 1347 | 1360 | if (err) |
|---|
| 1348 | 1361 | goto out_err; |
|---|
| 1349 | 1362 | |
|---|
| 1350 | 1363 | mmc_set_timing(host, MMC_TIMING_MMC_HS); |
|---|
| 1351 | 1364 | |
|---|
| 1352 | | - if (host->ops->hs400_downgrade) |
|---|
| 1353 | | - host->ops->hs400_downgrade(host); |
|---|
| 1354 | | - |
|---|
| 1355 | | - err = mmc_switch_status(card); |
|---|
| 1365 | + err = mmc_switch_status(card, true); |
|---|
| 1356 | 1366 | if (err) |
|---|
| 1357 | 1367 | goto out_err; |
|---|
| 1358 | 1368 | |
|---|
| .. | .. |
|---|
| 1361 | 1371 | card->drive_strength << EXT_CSD_DRV_STR_SHIFT; |
|---|
| 1362 | 1372 | err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, |
|---|
| 1363 | 1373 | val, card->ext_csd.generic_cmd6_time, 0, |
|---|
| 1364 | | - true, false, true); |
|---|
| 1374 | + false, true); |
|---|
| 1365 | 1375 | if (err) |
|---|
| 1366 | 1376 | goto out_err; |
|---|
| 1367 | 1377 | |
|---|
| .. | .. |
|---|
| 1372 | 1382 | * failed. If there really is a problem, we would expect tuning will |
|---|
| 1373 | 1383 | * fail and the result ends up the same. |
|---|
| 1374 | 1384 | */ |
|---|
| 1375 | | - err = __mmc_switch_status(card, false); |
|---|
| 1385 | + err = mmc_switch_status(card, false); |
|---|
| 1376 | 1386 | if (err) |
|---|
| 1377 | 1387 | goto out_err; |
|---|
| 1378 | 1388 | |
|---|
| .. | .. |
|---|
| 1445 | 1455 | err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, |
|---|
| 1446 | 1456 | EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS, |
|---|
| 1447 | 1457 | card->ext_csd.generic_cmd6_time, 0, |
|---|
| 1448 | | - true, false, true); |
|---|
| 1458 | + false, true); |
|---|
| 1449 | 1459 | if (err) { |
|---|
| 1450 | 1460 | pr_err("%s: switch to hs for hs400es failed, err:%d\n", |
|---|
| 1451 | 1461 | mmc_hostname(host), err); |
|---|
| 1452 | 1462 | goto out_err; |
|---|
| 1453 | 1463 | } |
|---|
| 1454 | 1464 | |
|---|
| 1465 | + /* |
|---|
| 1466 | + * Bump to HS timing and frequency. Some cards don't handle |
|---|
| 1467 | + * SEND_STATUS reliably at the initial frequency. |
|---|
| 1468 | + */ |
|---|
| 1455 | 1469 | mmc_set_timing(host, MMC_TIMING_MMC_HS); |
|---|
| 1456 | 1470 | /* Set clock immediately after changing timing */ |
|---|
| 1457 | | - mmc_set_clock(host, card->ext_csd.hs_max_dtr); |
|---|
| 1471 | + mmc_set_bus_speed(card); |
|---|
| 1458 | 1472 | |
|---|
| 1459 | | - err = mmc_switch_status(card); |
|---|
| 1473 | + err = mmc_switch_status(card, true); |
|---|
| 1460 | 1474 | if (err) |
|---|
| 1461 | 1475 | goto out_err; |
|---|
| 1462 | 1476 | |
|---|
| .. | .. |
|---|
| 1480 | 1494 | err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, |
|---|
| 1481 | 1495 | EXT_CSD_HS_TIMING, val, |
|---|
| 1482 | 1496 | card->ext_csd.generic_cmd6_time, 0, |
|---|
| 1483 | | - true, false, true); |
|---|
| 1497 | + false, true); |
|---|
| 1484 | 1498 | if (err) { |
|---|
| 1485 | 1499 | pr_err("%s: switch to hs400es failed, err:%d\n", |
|---|
| 1486 | 1500 | mmc_hostname(host), err); |
|---|
| .. | .. |
|---|
| 1495 | 1509 | if (host->ops->hs400_enhanced_strobe) |
|---|
| 1496 | 1510 | host->ops->hs400_enhanced_strobe(host, &host->ios); |
|---|
| 1497 | 1511 | |
|---|
| 1498 | | - /* some emmc device need a delay before read status */ |
|---|
| 1499 | | - usleep_range(100, 200); |
|---|
| 1500 | | - |
|---|
| 1501 | | - err = mmc_switch_status(card); |
|---|
| 1512 | + err = mmc_switch_status(card, true); |
|---|
| 1502 | 1513 | if (err) |
|---|
| 1503 | 1514 | goto out_err; |
|---|
| 1504 | 1515 | |
|---|
| .. | .. |
|---|
| 1520 | 1531 | static int mmc_select_hs200(struct mmc_card *card) |
|---|
| 1521 | 1532 | { |
|---|
| 1522 | 1533 | struct mmc_host *host = card->host; |
|---|
| 1523 | | - unsigned int old_timing, old_signal_voltage; |
|---|
| 1534 | + unsigned int old_timing, old_signal_voltage, old_clock; |
|---|
| 1524 | 1535 | int err = -EINVAL; |
|---|
| 1525 | 1536 | u8 val; |
|---|
| 1526 | 1537 | |
|---|
| .. | .. |
|---|
| 1548 | 1559 | err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, |
|---|
| 1549 | 1560 | EXT_CSD_HS_TIMING, val, |
|---|
| 1550 | 1561 | card->ext_csd.generic_cmd6_time, 0, |
|---|
| 1551 | | - true, false, true); |
|---|
| 1562 | + false, true); |
|---|
| 1552 | 1563 | if (err) |
|---|
| 1553 | 1564 | goto err; |
|---|
| 1565 | + |
|---|
| 1566 | + /* |
|---|
| 1567 | + * Bump to HS timing and frequency. Some cards don't handle |
|---|
| 1568 | + * SEND_STATUS reliably at the initial frequency. |
|---|
| 1569 | + * NB: We can't move to full (HS200) speeds until after we've |
|---|
| 1570 | + * successfully switched over. |
|---|
| 1571 | + */ |
|---|
| 1554 | 1572 | old_timing = host->ios.timing; |
|---|
| 1573 | + old_clock = host->ios.clock; |
|---|
| 1555 | 1574 | mmc_set_timing(host, MMC_TIMING_MMC_HS200); |
|---|
| 1575 | + mmc_set_clock(card->host, card->ext_csd.hs_max_dtr); |
|---|
| 1556 | 1576 | |
|---|
| 1557 | 1577 | /* |
|---|
| 1558 | 1578 | * For HS200, CRC errors are not a reliable way to know the |
|---|
| 1559 | 1579 | * switch failed. If there really is a problem, we would expect |
|---|
| 1560 | 1580 | * tuning will fail and the result ends up the same. |
|---|
| 1561 | 1581 | */ |
|---|
| 1562 | | - err = __mmc_switch_status(card, false); |
|---|
| 1582 | + err = mmc_switch_status(card, false); |
|---|
| 1563 | 1583 | |
|---|
| 1564 | 1584 | /* |
|---|
| 1565 | 1585 | * mmc_select_timing() assumes timing has not changed if |
|---|
| 1566 | 1586 | * it is a switch error. |
|---|
| 1567 | 1587 | */ |
|---|
| 1568 | | - if (err == -EBADMSG) |
|---|
| 1588 | + if (err == -EBADMSG) { |
|---|
| 1589 | + mmc_set_clock(host, old_clock); |
|---|
| 1569 | 1590 | mmc_set_timing(host, old_timing); |
|---|
| 1591 | + } |
|---|
| 1570 | 1592 | } |
|---|
| 1571 | 1593 | err: |
|---|
| 1572 | 1594 | if (err) { |
|---|
| .. | .. |
|---|
| 1583 | 1605 | /* |
|---|
| 1584 | 1606 | * Activate High Speed, HS200 or HS400ES mode if supported. |
|---|
| 1585 | 1607 | */ |
|---|
| 1586 | | -static int mmc_select_timing(struct mmc_card *card) |
|---|
| 1608 | +int mmc_select_timing(struct mmc_card *card) |
|---|
| 1587 | 1609 | { |
|---|
| 1588 | 1610 | int err = 0; |
|---|
| 1589 | 1611 | |
|---|
| .. | .. |
|---|
| 1608 | 1630 | mmc_set_bus_speed(card); |
|---|
| 1609 | 1631 | return 0; |
|---|
| 1610 | 1632 | } |
|---|
| 1633 | +EXPORT_SYMBOL_GPL(mmc_select_timing); |
|---|
| 1611 | 1634 | |
|---|
| 1612 | 1635 | /* |
|---|
| 1613 | 1636 | * Execute tuning sequence to seek the proper bus operating |
|---|
| 1614 | 1637 | * conditions for HS200 and HS400, which sends CMD21 to the device. |
|---|
| 1615 | 1638 | */ |
|---|
| 1616 | | -static int mmc_hs200_tuning(struct mmc_card *card) |
|---|
| 1639 | +int mmc_hs200_tuning(struct mmc_card *card) |
|---|
| 1617 | 1640 | { |
|---|
| 1618 | 1641 | struct mmc_host *host = card->host; |
|---|
| 1619 | 1642 | |
|---|
| .. | .. |
|---|
| 1628 | 1651 | |
|---|
| 1629 | 1652 | return mmc_execute_tuning(card); |
|---|
| 1630 | 1653 | } |
|---|
| 1654 | +EXPORT_SYMBOL_GPL(mmc_hs200_tuning); |
|---|
| 1631 | 1655 | |
|---|
| 1632 | 1656 | /* |
|---|
| 1633 | 1657 | * Handle the detection and initialisation of a card. |
|---|
| .. | .. |
|---|
| 1683 | 1707 | |
|---|
| 1684 | 1708 | if (oldcard) { |
|---|
| 1685 | 1709 | if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0) { |
|---|
| 1710 | + pr_debug("%s: Perhaps the card was replaced\n", |
|---|
| 1711 | + mmc_hostname(host)); |
|---|
| 1686 | 1712 | err = -ENOENT; |
|---|
| 1687 | 1713 | goto err; |
|---|
| 1688 | 1714 | } |
|---|
| .. | .. |
|---|
| 1836 | 1862 | card->ext_csd.power_off_notification = EXT_CSD_POWER_ON; |
|---|
| 1837 | 1863 | } |
|---|
| 1838 | 1864 | |
|---|
| 1865 | + /* set erase_arg */ |
|---|
| 1866 | + if (mmc_can_discard(card)) |
|---|
| 1867 | + card->erase_arg = MMC_DISCARD_ARG; |
|---|
| 1868 | + else if (mmc_can_trim(card)) |
|---|
| 1869 | + card->erase_arg = MMC_TRIM_ARG; |
|---|
| 1870 | + else |
|---|
| 1871 | + card->erase_arg = MMC_ERASE_ARG; |
|---|
| 1872 | + |
|---|
| 1839 | 1873 | /* |
|---|
| 1840 | 1874 | * Select timing interface |
|---|
| 1841 | 1875 | */ |
|---|
| .. | .. |
|---|
| 1844 | 1878 | goto free_card; |
|---|
| 1845 | 1879 | |
|---|
| 1846 | 1880 | if (mmc_card_hs200(card)) { |
|---|
| 1881 | + host->doing_init_tune = 1; |
|---|
| 1882 | + |
|---|
| 1847 | 1883 | err = mmc_hs200_tuning(card); |
|---|
| 1884 | + if (!err) |
|---|
| 1885 | + err = mmc_select_hs400(card); |
|---|
| 1886 | + |
|---|
| 1887 | + host->doing_init_tune = 0; |
|---|
| 1888 | + |
|---|
| 1848 | 1889 | if (err) |
|---|
| 1849 | 1890 | goto free_card; |
|---|
| 1850 | 1891 | |
|---|
| 1851 | | - err = mmc_select_hs400(card); |
|---|
| 1852 | | - if (err) |
|---|
| 1853 | | - goto free_card; |
|---|
| 1854 | 1892 | } else if (!mmc_card_hs400es(card)) { |
|---|
| 1855 | 1893 | /* Select the desired bus width optionally */ |
|---|
| 1856 | 1894 | err = mmc_select_bus_width(card); |
|---|
| .. | .. |
|---|
| 2050 | 2088 | |
|---|
| 2051 | 2089 | err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, |
|---|
| 2052 | 2090 | EXT_CSD_POWER_OFF_NOTIFICATION, |
|---|
| 2053 | | - notify_type, timeout, 0, true, false, false); |
|---|
| 2091 | + notify_type, timeout, 0, false, false); |
|---|
| 2054 | 2092 | if (err) |
|---|
| 2055 | 2093 | pr_err("%s: Power Off Notification timed out, %u\n", |
|---|
| 2056 | 2094 | mmc_hostname(card->host), timeout); |
|---|
| .. | .. |
|---|
| 2121 | 2159 | if (mmc_card_suspended(host->card)) |
|---|
| 2122 | 2160 | goto out; |
|---|
| 2123 | 2161 | |
|---|
| 2124 | | - if (mmc_card_doing_bkops(host->card)) { |
|---|
| 2125 | | - err = mmc_stop_bkops(host->card); |
|---|
| 2126 | | - if (err) |
|---|
| 2127 | | - goto out; |
|---|
| 2128 | | - } |
|---|
| 2129 | | - |
|---|
| 2130 | 2162 | err = mmc_flush_cache(host->card); |
|---|
| 2131 | 2163 | if (err) |
|---|
| 2132 | 2164 | goto out; |
|---|
| 2133 | 2165 | |
|---|
| 2134 | 2166 | if (mmc_can_poweroff_notify(host->card) && |
|---|
| 2135 | | - ((host->caps2 & MMC_CAP2_FULL_PWR_CYCLE) || !is_suspend)) |
|---|
| 2167 | + ((host->caps2 & MMC_CAP2_FULL_PWR_CYCLE) || !is_suspend || |
|---|
| 2168 | + (host->caps2 & MMC_CAP2_FULL_PWR_CYCLE_IN_SUSPEND))) |
|---|
| 2136 | 2169 | err = mmc_poweroff_notify(host->card, notify_type); |
|---|
| 2137 | 2170 | else if (mmc_can_sleep(host->card)) |
|---|
| 2138 | 2171 | err = mmc_sleep(host); |
|---|