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>
This commit is contained in:
parent
9b2026a125
commit
e74f3a9c99
@ -1429,22 +1429,10 @@ static void dw_mci_read_data_pio(struct dw_mci *host)
|
|||||||
nbytes += len;
|
nbytes += len;
|
||||||
remain -= len;
|
remain -= len;
|
||||||
} while (remain);
|
} while (remain);
|
||||||
sg_miter->consumed = offset;
|
|
||||||
|
|
||||||
|
sg_miter->consumed = offset;
|
||||||
status = mci_readl(host, MINTSTS);
|
status = mci_readl(host, MINTSTS);
|
||||||
mci_writel(host, RINTSTS, SDMMC_INT_RXDR);
|
mci_writel(host, RINTSTS, SDMMC_INT_RXDR);
|
||||||
if (status & DW_MCI_DATA_ERROR_FLAGS) {
|
|
||||||
host->data_status = status;
|
|
||||||
data->bytes_xfered += nbytes;
|
|
||||||
sg_miter_stop(sg_miter);
|
|
||||||
host->sg = NULL;
|
|
||||||
smp_wmb();
|
|
||||||
|
|
||||||
set_bit(EVENT_DATA_ERROR, &host->pending_events);
|
|
||||||
|
|
||||||
tasklet_schedule(&host->tasklet);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} while (status & SDMMC_INT_RXDR); /*if the RXDR is ready read again*/
|
} while (status & SDMMC_INT_RXDR); /*if the RXDR is ready read again*/
|
||||||
data->bytes_xfered += nbytes;
|
data->bytes_xfered += nbytes;
|
||||||
|
|
||||||
@ -1497,23 +1485,10 @@ static void dw_mci_write_data_pio(struct dw_mci *host)
|
|||||||
nbytes += len;
|
nbytes += len;
|
||||||
remain -= len;
|
remain -= len;
|
||||||
} while (remain);
|
} while (remain);
|
||||||
sg_miter->consumed = offset;
|
|
||||||
|
|
||||||
|
sg_miter->consumed = offset;
|
||||||
status = mci_readl(host, MINTSTS);
|
status = mci_readl(host, MINTSTS);
|
||||||
mci_writel(host, RINTSTS, SDMMC_INT_TXDR);
|
mci_writel(host, RINTSTS, SDMMC_INT_TXDR);
|
||||||
if (status & DW_MCI_DATA_ERROR_FLAGS) {
|
|
||||||
host->data_status = status;
|
|
||||||
data->bytes_xfered += nbytes;
|
|
||||||
sg_miter_stop(sg_miter);
|
|
||||||
host->sg = NULL;
|
|
||||||
|
|
||||||
smp_wmb();
|
|
||||||
|
|
||||||
set_bit(EVENT_DATA_ERROR, &host->pending_events);
|
|
||||||
|
|
||||||
tasklet_schedule(&host->tasklet);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} while (status & SDMMC_INT_TXDR); /* if TXDR write again */
|
} while (status & SDMMC_INT_TXDR); /* if TXDR write again */
|
||||||
data->bytes_xfered += nbytes;
|
data->bytes_xfered += nbytes;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user