Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=c783837bc69dd0f329a441c1704f5a02d01d1bd5
Commit:     c783837bc69dd0f329a441c1704f5a02d01d1bd5
Parent:     599473cf15a3fae78cbc3192cfb38ca04d5abc72
Author:     Nicolas Pitre <[EMAIL PROTECTED]>
AuthorDate: Tue Oct 9 17:07:58 2007 -0400
Committer:  Pierre Ossman <[EMAIL PROTECTED]>
CommitDate: Wed Oct 10 20:13:29 2007 +0200

    pxamci: support arbitrary block size
    
    The PXA has two transmit FIFOes, each32 byte deep.  when one FIFO is
    full and the other one has been transmitted, they are automatically
    swapped and DMA is triggered for another 32 byte burst.  However, when
    there is less than 32 bytes left to send, the FIFO swap has to be done
    manually. This is required for some SDIO transfers which are not
    required to be multiples of 32 bytes.
    
    A DMA completion interrupt is set for each descriptor which length isn't
    a multiple of 32 in order to force the FIFO swap.  While at it, the DMA
    interrupt handler has been made a bit more resilient against errors.
    
    Signed-off-by: Nicolas Pitre <[EMAIL PROTECTED]>
    Signed-off-by: Pierre Ossman <[EMAIL PROTECTED]>
---
 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 91e2568..657901e 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)
                                   host->dma_dir);
 
        for (i = 0; i < host->dma_len; i++) {
+               unsigned int length = sg_dma_len(&data->sg[i]);
+               host->sg_cpu[i].dcmd = dcmd | length;
+               if (length & 31 && !(data->flags & MMC_DATA_READ))
+                       host->sg_cpu[i].dcmd |= DCMD_ENDIRQEN;
                if (data->flags & MMC_DATA_READ) {
                        host->sg_cpu[i].dsadr = host->res->start + MMC_RXFIFO;
                        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)
                        host->sg_cpu[i].dsadr = sg_dma_address(&data->sg[i]);
                        host->sg_cpu[i].dtadr = host->res->start + MMC_TXFIFO;
                }
-               host->sg_cpu[i].dcmd = dcmd | sg_dma_len(&data->sg[i]);
                host->sg_cpu[i].ddadr = host->sg_dma + (i + 1) *
                                        sizeof(struct pxa_dma_desc);
        }
@@ -414,8 +417,18 @@ static const struct mmc_host_ops pxamci_ops = {
 
 static void pxamci_dma_irq(int dma, void *devid)
 {
-       printk(KERN_ERR "DMA%d: IRQ???\n", dma);
-       DCSR(dma) = DCSR_STARTINTR|DCSR_ENDINTR|DCSR_BUSERR;
+       struct pxamci_host *host = devid;
+       int dcsr = DCSR(dma);
+       DCSR(dma) = dcsr & ~DCSR_STOPIRQEN;
+
+       if (dcsr & DCSR_ENDINTR) {
+               writel(BUF_PART_FULL, host->base + MMC_PRTBUF);
+       } else {
+               printk(KERN_ERR "%s: DMA error on channel %d (DCSR=%#x)\n",
+                      mmc_hostname(host->mmc), dma, dcsr);
+               host->data->error = -EIO;
+               pxamci_data_done(host, 0);
+       }
 }
 
 static irqreturn_t pxamci_detect_irq(int irq, void *devid)
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to