aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host/msm_sdcc.c
diff options
context:
space:
mode:
authorSahitya Tummala <stummala@codeaurora.org>2010-12-08 04:33:07 -0500
committerDavid Brown <davidb@codeaurora.org>2010-12-20 15:28:32 -0500
commit0c521ccbd0c9ad5623ff9b37b20b3ff9d4ad65a7 (patch)
tree5cd3b61994a3891ec2ceff729ac33eea35ae205e /drivers/mmc/host/msm_sdcc.c
parent71dd9106af54de0f758875fa4b595af42a327448 (diff)
mmc: msm_sdcc: Check for only DATA_END interrupt to end a request
The current code checks for both DATA_END and DATA_BLK_END bits in MCI_STATUS register and ends a request only if both are set at a time. The hardware doesn't always set DATA_BLK_END when DATA_END is set. But DATA_END status itself is sufficient condition from hardware that data transfer is done and hence, check for only DATA_END interrupt in software to end a request. Signed-off-by: Sahitya Tummala <stummala@codeaurora.org> Signed-off-by: David Brown <davidb@codeaurora.org>
Diffstat (limited to 'drivers/mmc/host/msm_sdcc.c')
-rw-r--r--drivers/mmc/host/msm_sdcc.c15
1 files changed, 4 insertions, 11 deletions
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index 9badc51bc4db..5decfd0bd61d 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -190,7 +190,7 @@ static void
190msmsdcc_stop_data(struct msmsdcc_host *host) 190msmsdcc_stop_data(struct msmsdcc_host *host)
191{ 191{
192 host->curr.data = NULL; 192 host->curr.data = NULL;
193 host->curr.got_dataend = host->curr.got_datablkend = 0; 193 host->curr.got_dataend = 0;
194} 194}
195 195
196uint32_t msmsdcc_fifo_addr(struct msmsdcc_host *host) 196uint32_t msmsdcc_fifo_addr(struct msmsdcc_host *host)
@@ -277,8 +277,7 @@ msmsdcc_dma_complete_tlet(unsigned long data)
277 host->dma.sg = NULL; 277 host->dma.sg = NULL;
278 host->dma.busy = 0; 278 host->dma.busy = 0;
279 279
280 if ((host->curr.got_dataend && host->curr.got_datablkend) 280 if (host->curr.got_dataend || mrq->data->error) {
281 || mrq->data->error) {
282 281
283 /* 282 /*
284 * If we've already gotten our DATAEND / DATABLKEND 283 * If we've already gotten our DATAEND / DATABLKEND
@@ -506,7 +505,6 @@ msmsdcc_start_data(struct msmsdcc_host *host, struct mmc_data *data,
506 host->curr.xfer_remain = host->curr.xfer_size; 505 host->curr.xfer_remain = host->curr.xfer_size;
507 host->curr.data_xfered = 0; 506 host->curr.data_xfered = 0;
508 host->curr.got_dataend = 0; 507 host->curr.got_dataend = 0;
509 host->curr.got_datablkend = 0;
510 508
511 memset(&host->pio, 0, sizeof(host->pio)); 509 memset(&host->pio, 0, sizeof(host->pio));
512 510
@@ -827,14 +825,10 @@ msmsdcc_handle_irq_data(struct msmsdcc_host *host, u32 status,
827 if (!host->curr.got_dataend && (status & MCI_DATAEND)) 825 if (!host->curr.got_dataend && (status & MCI_DATAEND))
828 host->curr.got_dataend = 1; 826 host->curr.got_dataend = 1;
829 827
830 if (!host->curr.got_datablkend && (status & MCI_DATABLOCKEND))
831 host->curr.got_datablkend = 1;
832
833 /* 828 /*
834 * If DMA is still in progress, we complete via the completion handler 829 * If DMA is still in progress, we complete via the completion handler
835 */ 830 */
836 if (host->curr.got_dataend && host->curr.got_datablkend && 831 if (host->curr.got_dataend && !host->dma.busy) {
837 !host->dma.busy) {
838 /* 832 /*
839 * There appears to be an issue in the controller where 833 * There appears to be an issue in the controller where
840 * if you request a small block transfer (< fifo size), 834 * if you request a small block transfer (< fifo size),
@@ -871,8 +865,7 @@ msmsdcc_irq(int irq, void *dev_id)
871 865
872 do { 866 do {
873 status = msmsdcc_readl(host, MMCISTATUS); 867 status = msmsdcc_readl(host, MMCISTATUS);
874 status &= (msmsdcc_readl(host, MMCIMASK0) | 868 status &= msmsdcc_readl(host, MMCIMASK0);
875 MCI_DATABLOCKENDMASK);
876 msmsdcc_writel(host, status, MMCICLEAR); 869 msmsdcc_writel(host, status, MMCICLEAR);
877 870
878 if (status & MCI_SDIOINTR) 871 if (status & MCI_SDIOINTR)