mirror of
https://github.com/torvalds/linux.git
synced 2024-12-01 00:21:32 +00:00
mmc: mmc: Relax checking for switch errors after HS200 switch
The JEDEC specification indicates CMD13 can be used after a HS200 switch to check for errors. However in practice some boards experience CRC errors in the CMD13 response. Consequently, for HS200, CRC errors are not a reliable way to know the switch failed. If there really is a problem, we would expect tuning will fail and the result ends up the same. So change the error condition to ignore CRC errors in that case. Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> Acked-by: Jaehoon Chung <jh80.chung@samsung.com> Reviewed-by: Shawn Lin <shawn.lin@rock-chips.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
This commit is contained in:
parent
db52d4f8a4
commit
ef3d232245
@ -1240,7 +1240,12 @@ int mmc_hs400_to_hs200(struct mmc_card *card)
|
||||
|
||||
mmc_set_timing(host, MMC_TIMING_MMC_HS200);
|
||||
|
||||
err = mmc_switch_status(card);
|
||||
/*
|
||||
* For HS200, CRC errors are not a reliable way to know the switch
|
||||
* failed. If there really is a problem, we would expect tuning will
|
||||
* fail and the result ends up the same.
|
||||
*/
|
||||
err = __mmc_switch_status(card, false);
|
||||
if (err)
|
||||
goto out_err;
|
||||
|
||||
@ -1403,7 +1408,13 @@ static int mmc_select_hs200(struct mmc_card *card)
|
||||
old_timing = host->ios.timing;
|
||||
mmc_set_timing(host, MMC_TIMING_MMC_HS200);
|
||||
|
||||
err = mmc_switch_status(card);
|
||||
/*
|
||||
* For HS200, CRC errors are not a reliable way to know the
|
||||
* switch failed. If there really is a problem, we would expect
|
||||
* tuning will fail and the result ends up the same.
|
||||
*/
|
||||
err = __mmc_switch_status(card, false);
|
||||
|
||||
/*
|
||||
* mmc_select_timing() assumes timing has not changed if
|
||||
* it is a switch error.
|
||||
|
@ -431,18 +431,25 @@ static int mmc_switch_status_error(struct mmc_host *host, u32 status)
|
||||
}
|
||||
|
||||
/* Caller must hold re-tuning */
|
||||
int mmc_switch_status(struct mmc_card *card)
|
||||
int __mmc_switch_status(struct mmc_card *card, bool crc_err_fatal)
|
||||
{
|
||||
u32 status;
|
||||
int err;
|
||||
|
||||
err = mmc_send_status(card, &status);
|
||||
if (!crc_err_fatal && err == -EILSEQ)
|
||||
return 0;
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return mmc_switch_status_error(card->host, status);
|
||||
}
|
||||
|
||||
int mmc_switch_status(struct mmc_card *card)
|
||||
{
|
||||
return __mmc_switch_status(card, true);
|
||||
}
|
||||
|
||||
static int mmc_poll_for_busy(struct mmc_card *card, unsigned int timeout_ms,
|
||||
bool send_status, bool retry_crc_err)
|
||||
{
|
||||
|
@ -28,6 +28,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_switch_status(struct mmc_card *card);
|
||||
int __mmc_switch_status(struct mmc_card *card, bool crc_err_fatal);
|
||||
int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
|
||||
unsigned int timeout_ms, unsigned char timing,
|
||||
bool use_busy_signal, bool send_status, bool retry_crc_err);
|
||||
|
Loading…
Reference in New Issue
Block a user