Loading drivers/mmc/core/mmc.c +37 −9 Original line number Diff line number Diff line Loading @@ -1046,9 +1046,11 @@ static int mmc_select_hs(struct mmc_card *card) err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS, card->ext_csd.generic_cmd6_time, true, true, true); if (!err) true, false, true); if (!err) { mmc_set_timing(card->host, MMC_TIMING_MMC_HS); err = mmc_switch_status(card, false); } return err; } Loading @@ -1072,10 +1074,11 @@ static int mmc_select_hs_ddr(struct mmc_card *card) ext_csd_bits = (bus_width == MMC_BUS_WIDTH_8) ? EXT_CSD_DDR_BUS_WIDTH_8 : EXT_CSD_DDR_BUS_WIDTH_4; err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH, ext_csd_bits, card->ext_csd.generic_cmd6_time); card->ext_csd.generic_cmd6_time, true, false, false); if (err) { pr_warn("%s: switch to bus width %d ddr failed\n", mmc_hostname(host), 1 << bus_width); Loading Loading @@ -1118,8 +1121,10 @@ static int mmc_select_hs_ddr(struct mmc_card *card) if (err) err = __mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_330); if (!err) if (!err) { mmc_set_timing(host, MMC_TIMING_MMC_DDR52); err = mmc_switch_status(card, false); } return err; } Loading Loading @@ -1163,7 +1168,7 @@ static int mmc_select_hs400(struct mmc_card *card) err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS, card->ext_csd.generic_cmd6_time, true, true, true); true, false, true); if (err) { pr_warn("%s: switch to high-speed from hs200 failed, err:%d\n", mmc_hostname(host), err); Loading @@ -1173,6 +1178,10 @@ static int mmc_select_hs400(struct mmc_card *card) mmc_set_timing(card->host, MMC_TIMING_MMC_HS); mmc_set_bus_speed(card); err = mmc_switch_status(card, false); if (err) goto out_err; val = EXT_CSD_DDR_BUS_WIDTH_8; if (card->ext_csd.strobe_support) { err = mmc_select_bus_width(card); Loading @@ -1193,7 +1202,7 @@ static int mmc_select_hs400(struct mmc_card *card) err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS400, card->ext_csd.generic_cmd6_time, true, true, true); true, false, true); if (err) { pr_warn("%s: switch to hs400 failed, err:%d\n", mmc_hostname(host), err); Loading @@ -1219,6 +1228,17 @@ static int mmc_select_hs400(struct mmc_card *card) mmc_hostname(host)); } /* * Sending of CMD13 should be done after the host calibration * for enhanced_strobe or HS400 mode is completed. * Otherwise may see CMD13 timeouts or CRC errors. */ err = mmc_switch_status(card, false); out_err: if (err) pr_err("%s: %s failed, error %d\n", mmc_hostname(card->host), __func__, err); return err; } Loading Loading @@ -1253,9 +1273,17 @@ static int mmc_select_hs200(struct mmc_card *card) err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS200, card->ext_csd.generic_cmd6_time, true, true, true); if (!err) true, false, true); if (!err) { mmc_set_timing(host, MMC_TIMING_MMC_HS200); /* * Since after switching to hs200, crc errors might * occur for commands send before tuning. * So ignore crc error for cmd13. */ err = mmc_switch_status(card, true); } } err: return err; Loading drivers/mmc/core/mmc_ops.c +29 −11 Original line number Diff line number Diff line Loading @@ -57,6 +57,33 @@ int mmc_send_status(struct mmc_card *card, u32 *status) return __mmc_send_status(card, status, false); } static int mmc_switch_status_error(struct mmc_host *host, u32 status) { if (mmc_host_is_spi(host)) { if (status & R1_SPI_ILLEGAL_COMMAND) return -EBADMSG; } else { if (status & 0xFDFFA000) pr_warn("%s: unexpected status %#x after switch\n", mmc_hostname(host), status); if (status & R1_SWITCH_ERROR) return -EBADMSG; } return 0; } int mmc_switch_status(struct mmc_card *card, bool ignore_crc) { u32 status; int err; err = __mmc_send_status(card, &status, ignore_crc); if (err) return err; return mmc_switch_status_error(card->host, status); } static int _mmc_select_card(struct mmc_host *host, struct mmc_card *card) { int err; Loading Loading @@ -564,18 +591,9 @@ int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value, } } while (R1_CURRENT_STATE(status) == R1_STATE_PRG); if (mmc_host_is_spi(host)) { if (status & R1_SPI_ILLEGAL_COMMAND) return -EBADMSG; } else { if (status & 0xFDFFA000) pr_warn("%s: unexpected status %#x after switch\n", mmc_hostname(host), status); if (status & R1_SWITCH_ERROR) return -EBADMSG; } err = mmc_switch_status_error(host, status); return 0; return err; } EXPORT_SYMBOL_GPL(__mmc_switch); Loading drivers/mmc/core/mmc_ops.h +1 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ int mmc_bus_test(struct mmc_card *card, u8 bus_width); int mmc_send_hpi_cmd(struct mmc_card *card, u32 *status); int mmc_can_ext_csd(struct mmc_card *card); int mmc_discard_queue(struct mmc_host *host, u32 tasks); int mmc_switch_status(struct mmc_card *card, bool ignore_crc); #endif Loading
drivers/mmc/core/mmc.c +37 −9 Original line number Diff line number Diff line Loading @@ -1046,9 +1046,11 @@ static int mmc_select_hs(struct mmc_card *card) err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS, card->ext_csd.generic_cmd6_time, true, true, true); if (!err) true, false, true); if (!err) { mmc_set_timing(card->host, MMC_TIMING_MMC_HS); err = mmc_switch_status(card, false); } return err; } Loading @@ -1072,10 +1074,11 @@ static int mmc_select_hs_ddr(struct mmc_card *card) ext_csd_bits = (bus_width == MMC_BUS_WIDTH_8) ? EXT_CSD_DDR_BUS_WIDTH_8 : EXT_CSD_DDR_BUS_WIDTH_4; err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH, ext_csd_bits, card->ext_csd.generic_cmd6_time); card->ext_csd.generic_cmd6_time, true, false, false); if (err) { pr_warn("%s: switch to bus width %d ddr failed\n", mmc_hostname(host), 1 << bus_width); Loading Loading @@ -1118,8 +1121,10 @@ static int mmc_select_hs_ddr(struct mmc_card *card) if (err) err = __mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_330); if (!err) if (!err) { mmc_set_timing(host, MMC_TIMING_MMC_DDR52); err = mmc_switch_status(card, false); } return err; } Loading Loading @@ -1163,7 +1168,7 @@ static int mmc_select_hs400(struct mmc_card *card) err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS, card->ext_csd.generic_cmd6_time, true, true, true); true, false, true); if (err) { pr_warn("%s: switch to high-speed from hs200 failed, err:%d\n", mmc_hostname(host), err); Loading @@ -1173,6 +1178,10 @@ static int mmc_select_hs400(struct mmc_card *card) mmc_set_timing(card->host, MMC_TIMING_MMC_HS); mmc_set_bus_speed(card); err = mmc_switch_status(card, false); if (err) goto out_err; val = EXT_CSD_DDR_BUS_WIDTH_8; if (card->ext_csd.strobe_support) { err = mmc_select_bus_width(card); Loading @@ -1193,7 +1202,7 @@ static int mmc_select_hs400(struct mmc_card *card) err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS400, card->ext_csd.generic_cmd6_time, true, true, true); true, false, true); if (err) { pr_warn("%s: switch to hs400 failed, err:%d\n", mmc_hostname(host), err); Loading @@ -1219,6 +1228,17 @@ static int mmc_select_hs400(struct mmc_card *card) mmc_hostname(host)); } /* * Sending of CMD13 should be done after the host calibration * for enhanced_strobe or HS400 mode is completed. * Otherwise may see CMD13 timeouts or CRC errors. */ err = mmc_switch_status(card, false); out_err: if (err) pr_err("%s: %s failed, error %d\n", mmc_hostname(card->host), __func__, err); return err; } Loading Loading @@ -1253,9 +1273,17 @@ static int mmc_select_hs200(struct mmc_card *card) err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS200, card->ext_csd.generic_cmd6_time, true, true, true); if (!err) true, false, true); if (!err) { mmc_set_timing(host, MMC_TIMING_MMC_HS200); /* * Since after switching to hs200, crc errors might * occur for commands send before tuning. * So ignore crc error for cmd13. */ err = mmc_switch_status(card, true); } } err: return err; Loading
drivers/mmc/core/mmc_ops.c +29 −11 Original line number Diff line number Diff line Loading @@ -57,6 +57,33 @@ int mmc_send_status(struct mmc_card *card, u32 *status) return __mmc_send_status(card, status, false); } static int mmc_switch_status_error(struct mmc_host *host, u32 status) { if (mmc_host_is_spi(host)) { if (status & R1_SPI_ILLEGAL_COMMAND) return -EBADMSG; } else { if (status & 0xFDFFA000) pr_warn("%s: unexpected status %#x after switch\n", mmc_hostname(host), status); if (status & R1_SWITCH_ERROR) return -EBADMSG; } return 0; } int mmc_switch_status(struct mmc_card *card, bool ignore_crc) { u32 status; int err; err = __mmc_send_status(card, &status, ignore_crc); if (err) return err; return mmc_switch_status_error(card->host, status); } static int _mmc_select_card(struct mmc_host *host, struct mmc_card *card) { int err; Loading Loading @@ -564,18 +591,9 @@ int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value, } } while (R1_CURRENT_STATE(status) == R1_STATE_PRG); if (mmc_host_is_spi(host)) { if (status & R1_SPI_ILLEGAL_COMMAND) return -EBADMSG; } else { if (status & 0xFDFFA000) pr_warn("%s: unexpected status %#x after switch\n", mmc_hostname(host), status); if (status & R1_SWITCH_ERROR) return -EBADMSG; } err = mmc_switch_status_error(host, status); return 0; return err; } EXPORT_SYMBOL_GPL(__mmc_switch); Loading
drivers/mmc/core/mmc_ops.h +1 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ int mmc_bus_test(struct mmc_card *card, u8 bus_width); int mmc_send_hpi_cmd(struct mmc_card *card, u32 *status); int mmc_can_ext_csd(struct mmc_card *card); int mmc_discard_queue(struct mmc_host *host, u32 tasks); int mmc_switch_status(struct mmc_card *card, bool ignore_crc); #endif