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) |
