On 4 September 2013 14:21, Seungwon Jeon <tgih.jun@xxxxxxxxxxx> wrote: > While speed mode is changed, CMD13 cannot be guaranteed. > According to the spec., it is not recommended to use CMD13 > to check the busy completion of the timing change. > If CMD13 is used in this case, CRC error must be ignored. > > Signed-off-by: Seungwon Jeon <tgih.jun@xxxxxxxxxxx> > --- > Change in v3: > - Adjusted condition with MMC_CAP_WAIT_WHILE_BUSY.(From Ulf Hansson) > > Change in v2: > - Removed function declaration.(From Ulf Hansson) > > drivers/mmc/core/mmc_ops.c | 73 +++++++++++++++++++++++++++----------------- > 1 files changed, 45 insertions(+), 28 deletions(-) > > diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c > index ef18348..37f7d70 100644 > --- a/drivers/mmc/core/mmc_ops.c > +++ b/drivers/mmc/core/mmc_ops.c > @@ -23,6 +23,40 @@ > > #define MMC_OPS_TIMEOUT_MS (10 * 60 * 1000) /* 10 minute timeout */ > > +static inline int __mmc_send_status(struct mmc_card *card, u32 *status, > + bool ignore_crc) > +{ > + int err; > + struct mmc_command cmd = {0}; > + > + BUG_ON(!card); > + BUG_ON(!card->host); > + > + cmd.opcode = MMC_SEND_STATUS; > + if (!mmc_host_is_spi(card->host)) > + cmd.arg = card->rca << 16; > + cmd.flags = MMC_RSP_SPI_R2 | MMC_RSP_R1 | MMC_CMD_AC; > + if (ignore_crc) > + cmd.flags &= ~MMC_RSP_CRC; > + > + err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES); > + if (err) > + return err; > + > + /* NOTE: callers are required to understand the difference > + * between "native" and SPI format status words! > + */ > + if (status) > + *status = cmd.resp[0]; > + > + return 0; > +} > + > +int mmc_send_status(struct mmc_card *card, u32 *status) > +{ > + return __mmc_send_status(card, status, false); > +} > + > static int _mmc_select_card(struct mmc_host *host, struct mmc_card *card) > { > int err; > @@ -380,6 +414,7 @@ int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value, > struct mmc_command cmd = {0}; > unsigned long timeout; > u32 status; > + bool ignore_crc = false; > > BUG_ON(!card); > BUG_ON(!card->host); > @@ -408,10 +443,18 @@ int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value, > if (!use_busy_signal) > return 0; > > - /* Must check status to be sure of no errors */ > + /* > + * Must check status to be sure of no errors > + * If CMD13 is to check the busy completion of the timing change, > + * disable the check of CRC error. > + */ > + if (index == EXT_CSD_HS_TIMING && > + !(card->host->caps & MMC_CAP_WAIT_WHILE_BUSY)) > + ignore_crc = true; > + > timeout = jiffies + msecs_to_jiffies(MMC_OPS_TIMEOUT_MS); > do { > - err = mmc_send_status(card, &status); > + err = __mmc_send_status(card, &status, ignore_crc); > if (err) > return err; > if (card->host->caps & MMC_CAP_WAIT_WHILE_BUSY) > @@ -449,32 +492,6 @@ int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value, > } > EXPORT_SYMBOL_GPL(mmc_switch); > > -int mmc_send_status(struct mmc_card *card, u32 *status) > -{ > - int err; > - struct mmc_command cmd = {0}; > - > - BUG_ON(!card); > - BUG_ON(!card->host); > - > - cmd.opcode = MMC_SEND_STATUS; > - if (!mmc_host_is_spi(card->host)) > - cmd.arg = card->rca << 16; > - cmd.flags = MMC_RSP_SPI_R2 | MMC_RSP_R1 | MMC_CMD_AC; > - > - err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES); > - if (err) > - return err; > - > - /* NOTE: callers are required to understand the difference > - * between "native" and SPI format status words! > - */ > - if (status) > - *status = cmd.resp[0]; > - > - return 0; > -} > - > static int > mmc_send_bus_test(struct mmc_card *card, struct mmc_host *host, u8 opcode, > u8 len) > -- > 1.7.0.4 > > Acked-by: Ulf Hansson <ulf.hansson@xxxxxxxxxx> -- To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html