kernel 2.6.15: cpm_uart driver broken?
Kenneth Poole
kpoole at mrv.com
Thu Apr 20 05:24:55 EST 2006
>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
More information about the Linuxppc-embedded
mailing list