mmc: sdhci: fix the wrong operation when response type is R1b
PATCH 1/3 mmc: sdhci: fix the wrong operation when response type is R1b
When response type is R1b, mask value is added the SDHCI_INT_DAT_END. but in while(), didn't check that flag.
So sdhci controller didn't work fine.
CMD6 didn't always complete.
Signed-off-by Jaehoon Chung <[email protected]>
Signed-off-by Kyungmin Park <[email protected]>
--- drivers/mmc/sdhci.c | 33 +++++++++++++++++++++++---------- 1 files changed, 23 insertions(+), 10 deletions(-)
drivers/mmc/sdhci.c +23 -10
@@ -124,10 +124,11 @@ int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd, {struct sdhci_host *host = (struct sdhci_host *)mmc->priv;unsigned int stat =0 ; -int ret =0 ; +int i, ret =0 ;int trans_bytes =0 , is_aligned =1 ;u32 mask, flags, mode;unsigned int timeout, start_addr =0 ; +unsigned int retry =10000 ;/* Wait max 10 ms */ timeout =10 ;
@@ -206,19 +207,31 @@ int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd,flush_cache (start_addr, trans_bytes);#endif sdhci_writew (host,SDHCI_MAKE_CMD (cmd->cmdidx, flags),SDHCI_COMMAND ); -do { + +for (i =0 ; i < retry; i++) { stat =sdhci_readl (host,SDHCI_INT_STATUS ); -if (stat &SDHCI_INT_ERROR ) +if (stat & (SDHCI_INT_RESPONSE |SDHCI_INT_DATA_END )) { +sdhci_cmd_done (host, cmd); +sdhci_writel (host, mask,SDHCI_INT_STATUS ); +if (!data) { +sdhci_writel (host, stat,SDHCI_INT_STATUS ); + }break ; - }while ((stat & mask) != mask); + } + } -if ((stat & (SDHCI_INT_ERROR | mask)) == mask) { -sdhci_cmd_done (host, cmd); -sdhci_writel (host, mask,SDHCI_INT_STATUS ); - }else - ret =-1 ; +if (i == retry) { +printf ("%s: waiting for status update\n" ,__func__); +return TIMEOUT ; + } + +if (stat &SDHCI_INT_TIMEOUT ) { +return TIMEOUT ; + }else if (stat &SDHCI_INT_ERROR ) { +return -1 ; + } -if (!ret && data) +if (data) ret =sdhci_transfer_data (host, data, start_addr); stat =sdhci_readl (host,SDHCI_INT_STATUS );