aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/mmc/host/pxamci.c19
1 files changed, 16 insertions, 3 deletions
diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c
index 91e25683b397..657901eecfce 100644
--- a/drivers/mmc/host/pxamci.c
+++ b/drivers/mmc/host/pxamci.c
@@ -142,6 +142,10 @@ static void pxamci_setup_data(struct pxamci_host *host, struct mmc_data *data)
142 host->dma_dir); 142 host->dma_dir);
143 143
144 for (i = 0; i < host->dma_len; i++) { 144 for (i = 0; i < host->dma_len; i++) {
145 unsigned int length = sg_dma_len(&data->sg[i]);
146 host->sg_cpu[i].dcmd = dcmd | length;
147 if (length & 31 && !(data->flags & MMC_DATA_READ))
148 host->sg_cpu[i].dcmd |= DCMD_ENDIRQEN;
145 if (data->flags & MMC_DATA_READ) { 149 if (data->flags & MMC_DATA_READ) {
146 host->sg_cpu[i].dsadr = host->res->start + MMC_RXFIFO; 150 host->sg_cpu[i].dsadr = host->res->start + MMC_RXFIFO;
147 host->sg_cpu[i].dtadr = sg_dma_address(&data->sg[i]); 151 host->sg_cpu[i].dtadr = sg_dma_address(&data->sg[i]);
@@ -149,7 +153,6 @@ static void pxamci_setup_data(struct pxamci_host *host, struct mmc_data *data)
149 host->sg_cpu[i].dsadr = sg_dma_address(&data->sg[i]); 153 host->sg_cpu[i].dsadr = sg_dma_address(&data->sg[i]);
150 host->sg_cpu[i].dtadr = host->res->start + MMC_TXFIFO; 154 host->sg_cpu[i].dtadr = host->res->start + MMC_TXFIFO;
151 } 155 }
152 host->sg_cpu[i].dcmd = dcmd | sg_dma_len(&data->sg[i]);
153 host->sg_cpu[i].ddadr = host->sg_dma + (i + 1) * 156 host->sg_cpu[i].ddadr = host->sg_dma + (i + 1) *
154 sizeof(struct pxa_dma_desc); 157 sizeof(struct pxa_dma_desc);
155 } 158 }
@@ -414,8 +417,18 @@ static const struct mmc_host_ops pxamci_ops = {
414 417
415static void pxamci_dma_irq(int dma, void *devid) 418static void pxamci_dma_irq(int dma, void *devid)
416{ 419{
417 printk(KERN_ERR "DMA%d: IRQ???\n", dma); 420 struct pxamci_host *host = devid;
418 DCSR(dma) = DCSR_STARTINTR|DCSR_ENDINTR|DCSR_BUSERR; 421 int dcsr = DCSR(dma);
422 DCSR(dma) = dcsr & ~DCSR_STOPIRQEN;
423
424 if (dcsr & DCSR_ENDINTR) {
425 writel(BUF_PART_FULL, host->base + MMC_PRTBUF);
426 } else {
427 printk(KERN_ERR "%s: DMA error on channel %d (DCSR=%#x)\n",
428 mmc_hostname(host->mmc), dma, dcsr);
429 host->data->error = -EIO;
430 pxamci_data_done(host, 0);
431 }
419} 432}
420 433
421static irqreturn_t pxamci_detect_irq(int irq, void *devid) 434static irqreturn_t pxamci_detect_irq(int irq, void *devid)