diff options
-rw-r--r-- | drivers/mmc/host/pxamci.c | 19 |
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 | ||
415 | static void pxamci_dma_irq(int dma, void *devid) | 418 | static 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 | ||
421 | static irqreturn_t pxamci_detect_irq(int irq, void *devid) | 434 | static irqreturn_t pxamci_detect_irq(int irq, void *devid) |