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