diff options
Diffstat (limited to 'drivers/mmc')
-rw-r--r-- | drivers/mmc/card/block.c | 11 | ||||
-rw-r--r-- | drivers/mmc/core/mmc.c | 93 | ||||
-rw-r--r-- | drivers/mmc/host/Kconfig | 1 | ||||
-rw-r--r-- | drivers/mmc/host/mtk-sd.c | 2 | ||||
-rw-r--r-- | drivers/mmc/host/pxamci.c | 2 |
5 files changed, 75 insertions, 34 deletions
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 23b6c8e8701c..d8486168415a 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c | |||
@@ -65,8 +65,7 @@ MODULE_ALIAS("mmc:block"); | |||
65 | #define MMC_SANITIZE_REQ_TIMEOUT 240000 | 65 | #define MMC_SANITIZE_REQ_TIMEOUT 240000 |
66 | #define MMC_EXTRACT_INDEX_FROM_ARG(x) ((x & 0x00FF0000) >> 16) | 66 | #define MMC_EXTRACT_INDEX_FROM_ARG(x) ((x & 0x00FF0000) >> 16) |
67 | 67 | ||
68 | #define mmc_req_rel_wr(req) (((req->cmd_flags & REQ_FUA) || \ | 68 | #define mmc_req_rel_wr(req) ((req->cmd_flags & REQ_FUA) && \ |
69 | (req->cmd_flags & REQ_META)) && \ | ||
70 | (rq_data_dir(req) == WRITE)) | 69 | (rq_data_dir(req) == WRITE)) |
71 | #define PACKED_CMD_VER 0x01 | 70 | #define PACKED_CMD_VER 0x01 |
72 | #define PACKED_CMD_WR 0x02 | 71 | #define PACKED_CMD_WR 0x02 |
@@ -1467,13 +1466,9 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq, | |||
1467 | 1466 | ||
1468 | /* | 1467 | /* |
1469 | * Reliable writes are used to implement Forced Unit Access and | 1468 | * Reliable writes are used to implement Forced Unit Access and |
1470 | * REQ_META accesses, and are supported only on MMCs. | 1469 | * are supported only on MMCs. |
1471 | * | ||
1472 | * XXX: this really needs a good explanation of why REQ_META | ||
1473 | * is treated special. | ||
1474 | */ | 1470 | */ |
1475 | bool do_rel_wr = ((req->cmd_flags & REQ_FUA) || | 1471 | bool do_rel_wr = (req->cmd_flags & REQ_FUA) && |
1476 | (req->cmd_flags & REQ_META)) && | ||
1477 | (rq_data_dir(req) == WRITE) && | 1472 | (rq_data_dir(req) == WRITE) && |
1478 | (md->flags & MMC_BLK_REL_WR); | 1473 | (md->flags & MMC_BLK_REL_WR); |
1479 | 1474 | ||
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index c793fda27321..3a9a79ec4343 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c | |||
@@ -1040,9 +1040,24 @@ static int mmc_select_hs_ddr(struct mmc_card *card) | |||
1040 | return err; | 1040 | return err; |
1041 | } | 1041 | } |
1042 | 1042 | ||
1043 | /* Caller must hold re-tuning */ | ||
1044 | static int mmc_switch_status(struct mmc_card *card) | ||
1045 | { | ||
1046 | u32 status; | ||
1047 | int err; | ||
1048 | |||
1049 | err = mmc_send_status(card, &status); | ||
1050 | if (err) | ||
1051 | return err; | ||
1052 | |||
1053 | return mmc_switch_status_error(card->host, status); | ||
1054 | } | ||
1055 | |||
1043 | static int mmc_select_hs400(struct mmc_card *card) | 1056 | static int mmc_select_hs400(struct mmc_card *card) |
1044 | { | 1057 | { |
1045 | struct mmc_host *host = card->host; | 1058 | struct mmc_host *host = card->host; |
1059 | bool send_status = true; | ||
1060 | unsigned int max_dtr; | ||
1046 | int err = 0; | 1061 | int err = 0; |
1047 | u8 val; | 1062 | u8 val; |
1048 | 1063 | ||
@@ -1053,25 +1068,36 @@ static int mmc_select_hs400(struct mmc_card *card) | |||
1053 | host->ios.bus_width == MMC_BUS_WIDTH_8)) | 1068 | host->ios.bus_width == MMC_BUS_WIDTH_8)) |
1054 | return 0; | 1069 | return 0; |
1055 | 1070 | ||
1056 | /* | 1071 | if (host->caps & MMC_CAP_WAIT_WHILE_BUSY) |
1057 | * Before switching to dual data rate operation for HS400, | 1072 | send_status = false; |
1058 | * it is required to convert from HS200 mode to HS mode. | ||
1059 | */ | ||
1060 | mmc_set_timing(card->host, MMC_TIMING_MMC_HS); | ||
1061 | mmc_set_bus_speed(card); | ||
1062 | 1073 | ||
1074 | /* Reduce frequency to HS frequency */ | ||
1075 | max_dtr = card->ext_csd.hs_max_dtr; | ||
1076 | mmc_set_clock(host, max_dtr); | ||
1077 | |||
1078 | /* Switch card to HS mode */ | ||
1063 | val = EXT_CSD_TIMING_HS | | 1079 | val = EXT_CSD_TIMING_HS | |
1064 | card->drive_strength << EXT_CSD_DRV_STR_SHIFT; | 1080 | card->drive_strength << EXT_CSD_DRV_STR_SHIFT; |
1065 | err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, | 1081 | err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, |
1066 | EXT_CSD_HS_TIMING, val, | 1082 | EXT_CSD_HS_TIMING, val, |
1067 | card->ext_csd.generic_cmd6_time, | 1083 | card->ext_csd.generic_cmd6_time, |
1068 | true, true, true); | 1084 | true, send_status, true); |
1069 | if (err) { | 1085 | if (err) { |
1070 | pr_err("%s: switch to high-speed from hs200 failed, err:%d\n", | 1086 | pr_err("%s: switch to high-speed from hs200 failed, err:%d\n", |
1071 | mmc_hostname(host), err); | 1087 | mmc_hostname(host), err); |
1072 | return err; | 1088 | return err; |
1073 | } | 1089 | } |
1074 | 1090 | ||
1091 | /* Set host controller to HS timing */ | ||
1092 | mmc_set_timing(card->host, MMC_TIMING_MMC_HS); | ||
1093 | |||
1094 | if (!send_status) { | ||
1095 | err = mmc_switch_status(card); | ||
1096 | if (err) | ||
1097 | goto out_err; | ||
1098 | } | ||
1099 | |||
1100 | /* Switch card to DDR */ | ||
1075 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, | 1101 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, |
1076 | EXT_CSD_BUS_WIDTH, | 1102 | EXT_CSD_BUS_WIDTH, |
1077 | EXT_CSD_DDR_BUS_WIDTH_8, | 1103 | EXT_CSD_DDR_BUS_WIDTH_8, |
@@ -1082,22 +1108,35 @@ static int mmc_select_hs400(struct mmc_card *card) | |||
1082 | return err; | 1108 | return err; |
1083 | } | 1109 | } |
1084 | 1110 | ||
1111 | /* Switch card to HS400 */ | ||
1085 | val = EXT_CSD_TIMING_HS400 | | 1112 | val = EXT_CSD_TIMING_HS400 | |
1086 | card->drive_strength << EXT_CSD_DRV_STR_SHIFT; | 1113 | card->drive_strength << EXT_CSD_DRV_STR_SHIFT; |
1087 | err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, | 1114 | err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, |
1088 | EXT_CSD_HS_TIMING, val, | 1115 | EXT_CSD_HS_TIMING, val, |
1089 | card->ext_csd.generic_cmd6_time, | 1116 | card->ext_csd.generic_cmd6_time, |
1090 | true, true, true); | 1117 | true, send_status, true); |
1091 | if (err) { | 1118 | if (err) { |
1092 | pr_err("%s: switch to hs400 failed, err:%d\n", | 1119 | pr_err("%s: switch to hs400 failed, err:%d\n", |
1093 | mmc_hostname(host), err); | 1120 | mmc_hostname(host), err); |
1094 | return err; | 1121 | return err; |
1095 | } | 1122 | } |
1096 | 1123 | ||
1124 | /* Set host controller to HS400 timing and frequency */ | ||
1097 | mmc_set_timing(host, MMC_TIMING_MMC_HS400); | 1125 | mmc_set_timing(host, MMC_TIMING_MMC_HS400); |
1098 | mmc_set_bus_speed(card); | 1126 | mmc_set_bus_speed(card); |
1099 | 1127 | ||
1128 | if (!send_status) { | ||
1129 | err = mmc_switch_status(card); | ||
1130 | if (err) | ||
1131 | goto out_err; | ||
1132 | } | ||
1133 | |||
1100 | return 0; | 1134 | return 0; |
1135 | |||
1136 | out_err: | ||
1137 | pr_err("%s: %s failed, error %d\n", mmc_hostname(card->host), | ||
1138 | __func__, err); | ||
1139 | return err; | ||
1101 | } | 1140 | } |
1102 | 1141 | ||
1103 | int mmc_hs200_to_hs400(struct mmc_card *card) | 1142 | int mmc_hs200_to_hs400(struct mmc_card *card) |
@@ -1105,19 +1144,6 @@ int mmc_hs200_to_hs400(struct mmc_card *card) | |||
1105 | return mmc_select_hs400(card); | 1144 | return mmc_select_hs400(card); |
1106 | } | 1145 | } |
1107 | 1146 | ||
1108 | /* Caller must hold re-tuning */ | ||
1109 | static int mmc_switch_status(struct mmc_card *card) | ||
1110 | { | ||
1111 | u32 status; | ||
1112 | int err; | ||
1113 | |||
1114 | err = mmc_send_status(card, &status); | ||
1115 | if (err) | ||
1116 | return err; | ||
1117 | |||
1118 | return mmc_switch_status_error(card->host, status); | ||
1119 | } | ||
1120 | |||
1121 | int mmc_hs400_to_hs200(struct mmc_card *card) | 1147 | int mmc_hs400_to_hs200(struct mmc_card *card) |
1122 | { | 1148 | { |
1123 | struct mmc_host *host = card->host; | 1149 | struct mmc_host *host = card->host; |
@@ -1219,6 +1245,8 @@ static void mmc_select_driver_type(struct mmc_card *card) | |||
1219 | static int mmc_select_hs200(struct mmc_card *card) | 1245 | static int mmc_select_hs200(struct mmc_card *card) |
1220 | { | 1246 | { |
1221 | struct mmc_host *host = card->host; | 1247 | struct mmc_host *host = card->host; |
1248 | bool send_status = true; | ||
1249 | unsigned int old_timing; | ||
1222 | int err = -EINVAL; | 1250 | int err = -EINVAL; |
1223 | u8 val; | 1251 | u8 val; |
1224 | 1252 | ||
@@ -1234,6 +1262,9 @@ static int mmc_select_hs200(struct mmc_card *card) | |||
1234 | 1262 | ||
1235 | mmc_select_driver_type(card); | 1263 | mmc_select_driver_type(card); |
1236 | 1264 | ||
1265 | if (host->caps & MMC_CAP_WAIT_WHILE_BUSY) | ||
1266 | send_status = false; | ||
1267 | |||
1237 | /* | 1268 | /* |
1238 | * Set the bus width(4 or 8) with host's support and | 1269 | * Set the bus width(4 or 8) with host's support and |
1239 | * switch to HS200 mode if bus width is set successfully. | 1270 | * switch to HS200 mode if bus width is set successfully. |
@@ -1245,11 +1276,25 @@ static int mmc_select_hs200(struct mmc_card *card) | |||
1245 | err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, | 1276 | err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, |
1246 | EXT_CSD_HS_TIMING, val, | 1277 | EXT_CSD_HS_TIMING, val, |
1247 | card->ext_csd.generic_cmd6_time, | 1278 | card->ext_csd.generic_cmd6_time, |
1248 | true, true, true); | 1279 | true, send_status, true); |
1249 | if (!err) | 1280 | if (err) |
1250 | mmc_set_timing(host, MMC_TIMING_MMC_HS200); | 1281 | goto err; |
1282 | old_timing = host->ios.timing; | ||
1283 | mmc_set_timing(host, MMC_TIMING_MMC_HS200); | ||
1284 | if (!send_status) { | ||
1285 | err = mmc_switch_status(card); | ||
1286 | /* | ||
1287 | * mmc_select_timing() assumes timing has not changed if | ||
1288 | * it is a switch error. | ||
1289 | */ | ||
1290 | if (err == -EBADMSG) | ||
1291 | mmc_set_timing(host, old_timing); | ||
1292 | } | ||
1251 | } | 1293 | } |
1252 | err: | 1294 | err: |
1295 | if (err) | ||
1296 | pr_err("%s: %s failed, error %d\n", mmc_hostname(card->host), | ||
1297 | __func__, err); | ||
1253 | return err; | 1298 | return err; |
1254 | } | 1299 | } |
1255 | 1300 | ||
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index af71de5fda3b..1dee533634c9 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig | |||
@@ -473,6 +473,7 @@ config MMC_DAVINCI | |||
473 | 473 | ||
474 | config MMC_GOLDFISH | 474 | config MMC_GOLDFISH |
475 | tristate "goldfish qemu Multimedia Card Interface support" | 475 | tristate "goldfish qemu Multimedia Card Interface support" |
476 | depends on HAS_DMA | ||
476 | depends on GOLDFISH || COMPILE_TEST | 477 | depends on GOLDFISH || COMPILE_TEST |
477 | help | 478 | help |
478 | This selects the Goldfish Multimedia card Interface emulation | 479 | This selects the Goldfish Multimedia card Interface emulation |
diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c index 39568cc29a2a..33dfd7e72516 100644 --- a/drivers/mmc/host/mtk-sd.c +++ b/drivers/mmc/host/mtk-sd.c | |||
@@ -1276,7 +1276,7 @@ static struct msdc_delay_phase get_best_delay(struct msdc_host *host, u32 delay) | |||
1276 | int start = 0, len = 0; | 1276 | int start = 0, len = 0; |
1277 | int start_final = 0, len_final = 0; | 1277 | int start_final = 0, len_final = 0; |
1278 | u8 final_phase = 0xff; | 1278 | u8 final_phase = 0xff; |
1279 | struct msdc_delay_phase delay_phase; | 1279 | struct msdc_delay_phase delay_phase = { 0, }; |
1280 | 1280 | ||
1281 | if (delay == 0) { | 1281 | if (delay == 0) { |
1282 | dev_err(host->dev, "phase error: [map:%x]\n", delay); | 1282 | dev_err(host->dev, "phase error: [map:%x]\n", delay); |
diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c index 8cadd74e8407..ce08896b9d69 100644 --- a/drivers/mmc/host/pxamci.c +++ b/drivers/mmc/host/pxamci.c | |||
@@ -805,7 +805,7 @@ static int pxamci_probe(struct platform_device *pdev) | |||
805 | goto out; | 805 | goto out; |
806 | } else { | 806 | } else { |
807 | mmc->caps |= host->pdata->gpio_card_ro_invert ? | 807 | mmc->caps |= host->pdata->gpio_card_ro_invert ? |
808 | MMC_CAP2_RO_ACTIVE_HIGH : 0; | 808 | 0 : MMC_CAP2_RO_ACTIVE_HIGH; |
809 | } | 809 | } |
810 | 810 | ||
811 | if (gpio_is_valid(gpio_cd)) | 811 | if (gpio_is_valid(gpio_cd)) |