Skip to contentSkip to conversation

correct dpalloc handling for 8xx

PATCH New Pantelis Antoniou 1 participant 1 message Jun 8, 2004

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 correct dpalloc handling for 8xx

Hi Tom

The following patch implements dpalloc/dpfree routines as we talked about.

Also it updates the cpm_uart driver to use them.

Regards

Pantelis

arch/ppc/8xx_io/commproc.c +92 -28
@@ -36,11 +36,12 @@
 #include <asm/commproc.h>
 #include <asm/io.h>
 #include <asm/tlbflush.h>
+#include <asm/rheap.h>
 
 extern int get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep);
 
-static	uint	dp_alloc_base;	/* Starting offset in DP ram */
-static	uint	dp_alloc_top;	/* Max offset + 1 */
+static void m8xx_cpm_dpinit(void);
+
 static	uint	host_buffer;	/* One page of host buffer */
 static	uint	host_end;	/* end + 1 */
 cpm8xx_t	*cpmp;		/* Pointer to comm processor space */
@@ -134,8 +135,7 @@
 
 	/* Reclaim the DP memory for our use.
 	*/
-	dp_alloc_base = CPM_DATAONLY_BASE;
-	dp_alloc_top = dp_alloc_base + CPM_DATAONLY_SIZE;
+	m8xx_cpm_dpinit();
 
 	/* get the PTE for the bootpage */
 	if (!get_pteptr(&init_mm, bootpage, &pte))
@@ -309,30 +309,6 @@
 }
 
 
-/* Allocate some memory from the dual ported ram.  We may want to
- * enforce alignment restrictions, but right now everyone is a good
- * citizen.
- */
-uint
-m8xx_cpm_dpalloc(uint size)
-{
-	uint	retloc;
-
-	if ((dp_alloc_base + size) >= dp_alloc_top)
-		return(CPM_DP_NOSPACE);
-
-	retloc = dp_alloc_base;
-	dp_alloc_base += size;
-
-	return(retloc);
-}
-
-uint
-m8xx_cpm_dpalloc_index(void)
-{
-	return dp_alloc_base;
-}
-
 /* We also own one page of host buffer space for the allocation of
  * UART "fifos" and the like.
  */
@@ -379,4 +355,92 @@
 	else
 		*bp = (((BRG_UART_CLK_DIV16 / rate) - 1) << 1) |
 						CPM_BRG_EN | CPM_BRG_DIV16;
+}
+
+/********************************************************************************
+
+  dpalloc
+
+********************************************************************************/
+
+static spinlock_t cpm_dpmem_lock;
+/* 16 blocks should be enough to satisfy all requests
+   until the memory subsystem goes up... */
+static rh_block_t cpm_boot_dpmem_rh_block[16];
+static rh_info_t cpm_dpmem_info;
+
+/********************************************************************************/
+
+#define CPM_DPMEM_ALIGNMENT	8
+
+void m8xx_cpm_dpinit(void)
+{
+	cpm8xx_t *cp = &((immap_t *)IMAP_ADDR)->im_cpm;
+
+	spin_lock_init(&cpm_dpmem_lock);
+
+	/* initialize the info header */
+	rh_init(&cpm_dpmem_info, CPM_DPMEM_ALIGNMENT,
+			sizeof(cpm_boot_dpmem_rh_block)/sizeof(cpm_boot_dpmem_rh_block[0]),
+			cpm_boot_dpmem_rh_block);
+
+	/* attach the usable dpmem area */
+
+	/* XXX this is actually crap. CPM_DATAONLY_BASE & CPM_DATAONLY_SIZE is only
+	 * XXX a subset of the available dpram. It varies with the processor & the
+	 * XXX microcode patches activated. But the following should be at least safe.
+	 */
+	rh_attach_region(&cpm_dpmem_info, cp->cp_dpmem + CPM_DATAONLY_BASE, CPM_DATAONLY_SIZE);
+}
+
+void *m8xx_cpm_dpalloc(int size)
+{
+	void *start;
+	unsigned long flags;
+
+	spin_lock_irqsave(&cpm_dpmem_lock, flags);
+	start = rh_alloc(&cpm_dpmem_info, size, "commproc");
+	spin_unlock_irqrestore(&cpm_dpmem_lock, flags);
+
+	return start;
+}
+
+int m8xx_cpm_dpfree(void *addr)
+{
+	int ret;
+	unsigned long flags;
+
+	spin_lock_irqsave(&cpm_dpmem_lock, flags);
+	ret = rh_free(&cpm_dpmem_info, addr);
+	spin_unlock_irqrestore(&cpm_dpmem_lock, flags);
+
+	return ret;
+}
+
+void *m8xx_cpm_dpalloc_fixed(void *addr, int size)
+{
+	void *start;
+	unsigned long flags;
+
+	spin_lock_irqsave(&cpm_dpmem_lock, flags);
+	start = rh_alloc_fixed(&cpm_dpmem_info, addr, size, "commproc");
+	spin_unlock_irqrestore(&cpm_dpmem_lock, flags);
+
+	return start;
+}
+
+void m8xx_cpm_dpdump(void)
+{
+	rh_dump(&cpm_dpmem_info);
+}
+
+
+int m8xx_cpm_dpram_offset(void *addr)
+{
+	return (u_char *)addr - ((immap_t *)IMAP_ADDR)->im_cpm.cp_dpmem;
+}
+
+void *m8xx_cpm_dpram_addr(int offset)
+{
+	return ((immap_t *)IMAP_ADDR)->im_cpm.cp_dpmem + offset;
 }
arch/ppc/lib/rheap.c +688 -0

688 lines not on this page · raw message

drivers/serial/cpm_uart/cpm_uart_cpm1.c +7 -5
@@ -129,6 +129,7 @@
 int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con)
 {
 	int dpmemsz, memsz;
+	u8 *dp_mem;
 	uint dp_addr;
 	u8 *mem_addr;
 	dma_addr_t dma_addr;
@@ -136,12 +137,13 @@
 	pr_debug("CPM uart[%d]:allocbuf\n", pinfo->port.line);
 
 	dpmemsz = sizeof(cbd_t) * (pinfo->rx_nrfifos + pinfo->tx_nrfifos);
-	dp_addr = m8xx_cpm_dpalloc(dpmemsz);
-	if (dp_addr == CPM_DP_NOSPACE) {
+	dp_mem = m8xx_cpm_dpalloc(dpmemsz);
+	if (dp_mem == NULL) {
 		printk(KERN_ERR
 		       "cpm_uart_cpm1.c: could not allocate buffer descriptors\n");
 		return -ENOMEM;
 	}
+	dp_addr = m8xx_cpm_dpram_offset(dp_mem);
 
 	memsz = L1_CACHE_ALIGN(pinfo->rx_nrfifos * pinfo->rx_fifosize) +
 	    L1_CACHE_ALIGN(pinfo->tx_nrfifos * pinfo->tx_fifosize);
@@ -155,7 +157,7 @@
 	/* We cant really from memory allocated via cpm2_dpalloc,
 	 * fix this if in the future we can */
 	if (mem_addr == NULL) {
-		/* XXX cpm_dpalloc does not yet free */
+		m8xx_cpm_dpfree(dp_mem);
 		printk(KERN_ERR
 		       "cpm_uart_cpm1.c: could not allocate coherent memory\n");
 		return -ENOMEM;
@@ -169,7 +171,7 @@
 	pinfo->tx_buf = pinfo->rx_buf + L1_CACHE_ALIGN(pinfo->rx_nrfifos
 						       * pinfo->rx_fifosize);
 
-	pinfo->rx_bd_base = (volatile cbd_t *)(DPRAM_BASE + dp_addr);
+	pinfo->rx_bd_base = dp_mem;
 	pinfo->tx_bd_base = pinfo->rx_bd_base + pinfo->rx_nrfifos;
 
 	return 0;
@@ -183,7 +185,7 @@
 					 pinfo->tx_fifosize), pinfo->mem_addr,
 			  pinfo->dma_addr);
 
-	/* XXX cannot free dpmem yet */
+	m8xx_cpm_dpfree(m8xx_cpm_dpram_addr(pinfo->dp_addr));
 }
 
 /* Setup any dynamic params in the uart desc */
include/asm-ppc/commproc.h +7 -4
@@ -677,11 +677,14 @@
 		void (*handler)(void *, struct pt_regs *regs), void *dev_id);
 extern void cpm_free_handler(int vec);
 
-extern uint m8xx_cpm_dpalloc(uint size);
-extern int  m8xx_cpm_dpfree(uint offset);
-extern uint m8xx_cpm_dpalloc_fixed(uint offset, uint size);
-extern void m8xx_cpm_dpdump(void);
+extern void *m8xx_cpm_dpalloc(int size);
+extern int   m8xx_cpm_dpfree(void *addr);
+extern void *m8xx_cpm_dpalloc_fixed(void *addr, int size);
+extern void  m8xx_cpm_dpdump(void);
+extern int   m8xx_cpm_dpram_offset(void *addr);
+extern void *m8xx_cpm_dpram_addr(int offset);
 
+/* these must die! */
 extern uint m8xx_cpm_hostalloc(uint size);
 extern int  m8xx_cpm_hostfree(uint start);
 extern void m8xx_cpm_hostdump(void);
include/asm-ppc/rheap.h +92 -0

92 lines not on this page · raw message