|
@@ -1438,7 +1438,7 @@ static void dw_mci_pull_data(struct dw_mci *host, void *buf, int cnt)
|
|
|
host->pull_data(host, buf, cnt);
|
|
|
}
|
|
|
|
|
|
-static void dw_mci_read_data_pio(struct dw_mci *host)
|
|
|
+static void dw_mci_read_data_pio(struct dw_mci *host, bool dto)
|
|
|
{
|
|
|
struct sg_mapping_iter *sg_miter = &host->sg_miter;
|
|
|
void *buf;
|
|
@@ -1473,7 +1473,9 @@ static void dw_mci_read_data_pio(struct dw_mci *host)
|
|
|
sg_miter->consumed = offset;
|
|
|
status = mci_readl(host, MINTSTS);
|
|
|
mci_writel(host, RINTSTS, SDMMC_INT_RXDR);
|
|
|
- } while (status & SDMMC_INT_RXDR); /*if the RXDR is ready read again*/
|
|
|
+ /* if the RXDR is ready read again */
|
|
|
+ } while ((status & SDMMC_INT_RXDR) ||
|
|
|
+ (dto && SDMMC_GET_FCNT(mci_readl(host, STATUS))));
|
|
|
data->bytes_xfered += nbytes;
|
|
|
|
|
|
if (!remain) {
|
|
@@ -1605,7 +1607,7 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id)
|
|
|
smp_wmb();
|
|
|
if (host->dir_status == DW_MCI_RECV_STATUS) {
|
|
|
if (host->sg != NULL)
|
|
|
- dw_mci_read_data_pio(host);
|
|
|
+ dw_mci_read_data_pio(host, true);
|
|
|
}
|
|
|
set_bit(EVENT_DATA_COMPLETE, &host->pending_events);
|
|
|
tasklet_schedule(&host->tasklet);
|
|
@@ -1614,7 +1616,7 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id)
|
|
|
if (pending & SDMMC_INT_RXDR) {
|
|
|
mci_writel(host, RINTSTS, SDMMC_INT_RXDR);
|
|
|
if (host->dir_status == DW_MCI_RECV_STATUS && host->sg)
|
|
|
- dw_mci_read_data_pio(host);
|
|
|
+ dw_mci_read_data_pio(host, false);
|
|
|
}
|
|
|
|
|
|
if (pending & SDMMC_INT_TXDR) {
|