>If there is any code to reference, I'd appreciate it (and merge to the
>driver). 

Ok, here's a patch, below. It includes changes for DMA buffer allocation
as discussed. This is untested, because the CPM uart driver for our
platforms has many other modifications that don't apply.

It also includes a fix for sending x_char in cpm_uart_tx_pump(). This
allows the actual x_char to be sent, instead of the next regular
character.

-------------------------------------------------------------
--- cpm_uart_core.c.orig        2006-04-19 10:24:47.000000000 -0400
+++ cpm_uart_core.c     2006-04-19 10:51:43.000000000 -0400
@@ -71,20 +71,6 @@
 
 /**************************************************************/
 
-static inline unsigned long cpu2cpm_addr(void *addr)
-{
-       if ((unsigned long)addr >= CPM_ADDR)
-               return (unsigned long)addr;
-       return virt_to_bus(addr);
-}
-
-static inline void *cpm2cpu_addr(unsigned long addr)
-{
-       if (addr >= CPM_ADDR)
-               return (void *)addr;
-       return bus_to_virt(addr);
-}
-
 /*
  * Check, if transmit buffers are processed
 */
@@ -261,7 +247,7 @@
                }
 
                /* get pointer */
-               cp = cpm2cpu_addr(bdp->cbd_bufaddr);
+               cp = (unsigned char *)pinfo->mem_addr +
(bdp->cbd_bufaddr - pinfo->dma_addr);
 
                /* loop through the buffer */
                while (i-- > 0) {
@@ -606,11 +592,12 @@
                /* Pick next descriptor and fill from buffer */
                bdp = pinfo->tx_cur;
 
-               p = cpm2cpu_addr(bdp->cbd_bufaddr);
+               p = (unsigned char *)pinfo->mem_addr + (bdp->cbd_bufaddr
- pinfo->dma_addr);
 
-               *p++ = xmit->buf[xmit->tail];
+               *p = port->x_char;
                bdp->cbd_datlen = 1;
                bdp->cbd_sc |= BD_SC_READY;
+               __asm__("eieio");
                /* Get next BD. */
                if (bdp->cbd_sc & BD_SC_WRAP)
                        bdp = pinfo->tx_bd_base;
@@ -633,7 +620,7 @@
 
        while (!(bdp->cbd_sc & BD_SC_READY) && (xmit->tail !=
xmit->head)) {
                count = 0;
-               p = cpm2cpu_addr(bdp->cbd_bufaddr);
+               p = (unsigned char *)pinfo->mem_addr + (bdp->cbd_bufaddr
- pinfo->dma_addr);
                while (count < pinfo->tx_fifosize) {
                        *p++ = xmit->buf[xmit->tail];
                        xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE
- 1);
@@ -670,39 +657,37 @@
 static void cpm_uart_initbd(struct uart_cpm_port *pinfo)
 {
        int i;
-       u8 *mem_addr;
+       dma_addr_t dma_addr;
        volatile cbd_t *bdp;
 
        pr_debug("CPM uart[%d]:initbd\n", pinfo->port.line);
 
        /* Set the physical address of the host memory
-        * buffers in the buffer descriptors, and the
-        * virtual address for us to work with.
+        * buffers in the buffer descriptors.
         */
-       mem_addr = pinfo->mem_addr;
+       dma_addr = pinfo->dma_addr;
        bdp = pinfo->rx_cur = pinfo->rx_bd_base;
        for (i = 0; i < (pinfo->rx_nrfifos - 1); i++, bdp++) {
-               bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr);
+               bdp->cbd_bufaddr = dma_addr;
                bdp->cbd_sc = BD_SC_EMPTY | BD_SC_INTRPT;
-               mem_addr += pinfo->rx_fifosize;
+               dma_addr += pinfo->rx_fifosize;
        }
-
-       bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr);
+       
+       bdp->cbd_bufaddr = dma_addr;
        bdp->cbd_sc = BD_SC_WRAP | BD_SC_EMPTY | BD_SC_INTRPT;
 
        /* Set the physical address of the host memory
-        * buffers in the buffer descriptors, and the
-        * virtual address for us to work with.
+        * buffers in the buffer descriptors.
         */
-       mem_addr = pinfo->mem_addr + L1_CACHE_ALIGN(pinfo->rx_nrfifos *
pinfo->rx_fifosize);
+       dma_addr = pinfo->dma_addr + L1_CACHE_ALIGN(pinfo->rx_nrfifos *
pinfo->rx_fifosize);
        bdp = pinfo->tx_cur = pinfo->tx_bd_base;
        for (i = 0; i < (pinfo->tx_nrfifos - 1); i++, bdp++) {
-               bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr);
+               bdp->cbd_bufaddr = dma_addr;
                bdp->cbd_sc = BD_SC_INTRPT;
-               mem_addr += pinfo->tx_fifosize;
+               dma_addr += pinfo->tx_fifosize;
        }
-
-       bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr);
+       
+       bdp->cbd_bufaddr = dma_addr;
        bdp->cbd_sc = BD_SC_WRAP | BD_SC_INTRPT;
 }
 
@@ -1032,7 +1017,7 @@
                 * If the buffer address is in the CPM DPRAM, don't
                 * convert it.
                 */
-               cp = cpm2cpu_addr(bdp->cbd_bufaddr);
+               cp = (unsigned char *)pinfo->mem_addr +
(bdp->cbd_bufaddr - pinfo->dma_addr);
 
                *cp = *s;
 
@@ -1049,7 +1034,7 @@
                        while ((bdp->cbd_sc & BD_SC_READY) != 0)
                                ;
 
-                       cp = cpm2cpu_addr(bdp->cbd_bufaddr);
+                       cp = (unsigned char *)pinfo->mem_addr +
(bdp->cbd_bufaddr - pinfo->dma_addr);
 
                        *cp = 13;
                        bdp->cbd_datlen = 1;
--- cpm_uart_cpm1.c.orig        2006-04-19 10:26:46.000000000 -0400
+++ cpm_uart_cpm1.c     2006-04-19 10:32:05.000000000 -0400
@@ -191,7 +191,7 @@
                /* was hostalloc but changed cause it blows away the */
                /* large tlb mapping when pinning the kernel area    */
                mem_addr = (u8 *) cpm_dpram_addr(cpm_dpalloc(memsz, 8));
-               dma_addr = 0;
+               dma_addr = (dma_addr_t)mem_addr;
        } else
                mem_addr = dma_alloc_coherent(NULL, memsz, &dma_addr,
                                              GFP_KERNEL);

----------------------------------------------------------

Ken Poole
kpoole at bos.mrv.com
 

Reply via email to