浏览代码

[ARM] 4256/1: i.MX/MX1 SDHC fix/workaround of SD card recognition problems

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>
Pavel Pisa 18 年之前
父节点
当前提交
2cb3320b3f
共有 1 个文件被更改,包括 12 次插入1 次删除
  1. 12 1
      drivers/mmc/imxmmc.c

+ 12 - 1
drivers/mmc/imxmmc.c

@@ -569,10 +569,12 @@ static int imxmci_cpu_driven_data(struct imxmci_host *host, unsigned int *pstat)
 
 
 	if(host->dma_dir == DMA_FROM_DEVICE) {
 	if(host->dma_dir == DMA_FROM_DEVICE) {
 		imxmci_busy_wait_for_status(host, &stat,
 		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");
 				50, "imxmci_cpu_driven_data read");
 
 
 		while((stat & (STATUS_APPL_BUFF_FF |  STATUS_DATA_TRANS_DONE)) &&
 		while((stat & (STATUS_APPL_BUFF_FF |  STATUS_DATA_TRANS_DONE)) &&
+		      !(stat & STATUS_TIME_OUT_READ) &&
 		      (host->data_cnt < 512)) {
 		      (host->data_cnt < 512)) {
 
 
 			udelay(20);	/* required for clocks < 8MHz*/
 			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)
 		if(host->dma_size & 0x1ff)
 			stat &= ~STATUS_CRC_READ_ERR;
 			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 {
 	} else {
 		imxmci_busy_wait_for_status(host, &stat,
 		imxmci_busy_wait_for_status(host, &stat,
 				STATUS_APPL_BUFF_FE,
 				STATUS_APPL_BUFF_FE,
@@ -709,6 +717,9 @@ static void imxmci_tasklet_fnc(unsigned long data)
 		 */
 		 */
 		stat |= host->status_reg;
 		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)) {
 		if(test_bit(IMXMCI_PEND_WAIT_RESP_b, &host->pending_events)) {
 			imxmci_busy_wait_for_status(host, &stat,
 			imxmci_busy_wait_for_status(host, &stat,
 					STATUS_END_CMD_RESP | STATUS_ERR_MASK,
 					STATUS_END_CMD_RESP | STATUS_ERR_MASK,