[ARM] 4256/1: i.MX/MX1 SDHC fix/workaround of SD card recognition problems
authorPavel Pisa <ppisa@pikron.com>
Wed, 7 Mar 2007 23:00:40 +0000 (00:00 +0100)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Mon, 12 Mar 2007 16:49:37 +0000 (16:49 +0000)
The SDHC controllers cannot process shorter transfers.
They has to be handled as longer ones, but it such case CRC
error is evaluated. There was a case in the code still,
where this error is not ignored as it should to be process
these transfers.

Signed-off-by: Pavel Pisa <pisa@cmp.felk.cvut.cz>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
drivers/mmc/imxmmc.c

index b060d4b..0de5c9e 100644 (file)
@@ -569,10 +569,12 @@ static int imxmci_cpu_driven_data(struct imxmci_host *host, unsigned int *pstat)
 
        if(host->dma_dir == DMA_FROM_DEVICE) {
                imxmci_busy_wait_for_status(host, &stat,
-                               STATUS_APPL_BUFF_FF | STATUS_DATA_TRANS_DONE,
+                               STATUS_APPL_BUFF_FF | STATUS_DATA_TRANS_DONE |
+                               STATUS_TIME_OUT_READ,
                                50, "imxmci_cpu_driven_data read");
 
                while((stat & (STATUS_APPL_BUFF_FF |  STATUS_DATA_TRANS_DONE)) &&
+                     !(stat & STATUS_TIME_OUT_READ) &&
                      (host->data_cnt < 512)) {
 
                        udelay(20);     /* required for clocks < 8MHz*/
@@ -602,6 +604,12 @@ static int imxmci_cpu_driven_data(struct imxmci_host *host, unsigned int *pstat)
                if(host->dma_size & 0x1ff)
                        stat &= ~STATUS_CRC_READ_ERR;
 
+               if(stat & STATUS_TIME_OUT_READ) {
+                       dev_dbg(mmc_dev(host->mmc), "imxmci_cpu_driven_data read timeout STATUS = 0x%x\n",
+                               stat);
+                       trans_done = -1;
+               }
+
        } else {
                imxmci_busy_wait_for_status(host, &stat,
                                STATUS_APPL_BUFF_FE,
@@ -709,6 +717,9 @@ static void imxmci_tasklet_fnc(unsigned long data)
                 */
                stat |= host->status_reg;
 
+               if(test_bit(IMXMCI_PEND_CPU_DATA_b, &host->pending_events))
+                       stat &= ~STATUS_CRC_READ_ERR;
+
                if(test_bit(IMXMCI_PEND_WAIT_RESP_b, &host->pending_events)) {
                        imxmci_busy_wait_for_status(host, &stat,
                                        STATUS_END_CMD_RESP | STATUS_ERR_MASK,