aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorSeungwon Jeon <tgih.jun@samsung.com>2012-07-31 20:30:46 -0400
committerChris Ball <cjb@laptop.org>2012-09-04 13:58:09 -0400
commite74f3a9c993a088f0a067e13941075e4acb7300a (patch)
tree451f7589d217d85607c5e6eb8567fa77a40ec329 /drivers
parent9b2026a12511439d906a5d8d302ae285ebe7378a (diff)
mmc: dw_mmc: fix error handling in PIO mode
Data transfer will be continued until all the bytes are transmitted, even if data crc error occurs during a multiple-block data transfer. This means RXDR/TXDR interrupts will occurs until data transfer is terminated. Early setting of host->sg to NULL prevents going into xxx_data_pio functions, hence permanent unhandled RXDR/TXDR interrupts occurs. And checking error interrupt status in the xxx_data_pio functions is no need because dw_mci_interrupt does do the same. This patch also removes it. Signed-off-by: Seungwon Jeon <tgih.jun@samsung.com> Acked-by: Jaehoon Chung <jh80.chung@samsung.com> Acked-by: Will Newton <will.newton@imgtec.com> Signed-off-by: Chris Ball <cjb@laptop.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mmc/host/dw_mmc.c29
1 files changed, 2 insertions, 27 deletions
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index 1a5db20133ee..cf8511b80782 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -1429,22 +1429,10 @@ static void dw_mci_read_data_pio(struct dw_mci *host)
1429 nbytes += len; 1429 nbytes += len;
1430 remain -= len; 1430 remain -= len;
1431 } while (remain); 1431 } while (remain);
1432 sg_miter->consumed = offset;
1433 1432
1433 sg_miter->consumed = offset;
1434 status = mci_readl(host, MINTSTS); 1434 status = mci_readl(host, MINTSTS);
1435 mci_writel(host, RINTSTS, SDMMC_INT_RXDR); 1435 mci_writel(host, RINTSTS, SDMMC_INT_RXDR);
1436 if (status & DW_MCI_DATA_ERROR_FLAGS) {
1437 host->data_status = status;
1438 data->bytes_xfered += nbytes;
1439 sg_miter_stop(sg_miter);
1440 host->sg = NULL;
1441 smp_wmb();
1442
1443 set_bit(EVENT_DATA_ERROR, &host->pending_events);
1444
1445 tasklet_schedule(&host->tasklet);
1446 return;
1447 }
1448 } while (status & SDMMC_INT_RXDR); /*if the RXDR is ready read again*/ 1436 } while (status & SDMMC_INT_RXDR); /*if the RXDR is ready read again*/
1449 data->bytes_xfered += nbytes; 1437 data->bytes_xfered += nbytes;
1450 1438
@@ -1497,23 +1485,10 @@ static void dw_mci_write_data_pio(struct dw_mci *host)
1497 nbytes += len; 1485 nbytes += len;
1498 remain -= len; 1486 remain -= len;
1499 } while (remain); 1487 } while (remain);
1500 sg_miter->consumed = offset;
1501 1488
1489 sg_miter->consumed = offset;
1502 status = mci_readl(host, MINTSTS); 1490 status = mci_readl(host, MINTSTS);
1503 mci_writel(host, RINTSTS, SDMMC_INT_TXDR); 1491 mci_writel(host, RINTSTS, SDMMC_INT_TXDR);
1504 if (status & DW_MCI_DATA_ERROR_FLAGS) {
1505 host->data_status = status;
1506 data->bytes_xfered += nbytes;
1507 sg_miter_stop(sg_miter);
1508 host->sg = NULL;
1509
1510 smp_wmb();
1511
1512 set_bit(EVENT_DATA_ERROR, &host->pending_events);
1513
1514 tasklet_schedule(&host->tasklet);
1515 return;
1516 }
1517 } while (status & SDMMC_INT_TXDR); /* if TXDR write again */ 1492 } while (status & SDMMC_INT_TXDR); /* if TXDR write again */
1518 data->bytes_xfered += nbytes; 1493 data->bytes_xfered += nbytes;
1519 1494