diff options
author | Sahitya Tummala <stummala@codeaurora.org> | 2010-12-08 04:33:07 -0500 |
---|---|---|
committer | David Brown <davidb@codeaurora.org> | 2010-12-20 15:28:32 -0500 |
commit | 0c521ccbd0c9ad5623ff9b37b20b3ff9d4ad65a7 (patch) | |
tree | 5cd3b61994a3891ec2ceff729ac33eea35ae205e /drivers/mmc/host/msm_sdcc.c | |
parent | 71dd9106af54de0f758875fa4b595af42a327448 (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.c | 15 |
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 | |||
190 | msmsdcc_stop_data(struct msmsdcc_host *host) | 190 | msmsdcc_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 | ||
196 | uint32_t msmsdcc_fifo_addr(struct msmsdcc_host *host) | 196 | uint32_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) |