[uClinux-dev] [patch] linux-2.4.27-uc1 (dist 20041512) Additional uart for Signal MCP751

Luca Cussolotto luca at signal-elettronica.it
Wed Aug 31 05:42:51 EDT 2005


Hi all,

Attached is a patch for additional uart support for the Signal MCP751 board
(based on Coldfire 5272).

It includes some generic fixes for Coldfire and other specific for the Signal
board.

Luca Cussolotto


--- linux-2.4.x/include/asm-m68knommu/serial.h.orig	2004-12-15
05:57:29.000000000 +0100
+++ linux-2.4.x/include/asm-m68knommu/serial.h	2005-08-30 13:53:12.000000000
+0200
@@ -78,7 +78,41 @@
 #define RS_TABLE_SIZE	2
 #undef CONFIG_SERIAL_MULTIPORT

-#else /* !CONFIG_SERIAL_CDB4 */
+#elif defined(CONFIG_SIGNAL_MCP751)
+
+#define BASE_BAUD ( (1843200*3*4) / 16 )
+
+#define CONFIG_SERIAL_SHARE_IRQ
+
+#define MCP751_COM_BASE		((u8 *)0x44000000)
+#define MCP751_COM_IRQ		91	/* external IRQ6 */
+#define MCP751_COM_IRQPRI	5	/* interrupt priority */
+#define STD_COM_FLAGS		ASYNC_BOOT_AUTOCONF
+
+#define SERIAL_PORT_DFNS				\
+	{						\
+		.baud_base	= BASE_BAUD,		\
+		.iomem_base	= MCP751_COM_BASE + 0x0,	\
+		.io_type	= SERIAL_IO_MEM,	\
+		.irq		= MCP751_COM_IRQ,		\
+		.flags		= STD_COM_FLAGS		\
+	},						\
+	{						\
+		.baud_base	= BASE_BAUD,		\
+		.iomem_base	= MCP751_COM_BASE + 0x8,	\
+		.io_type	= SERIAL_IO_MEM,	\
+		.irq		= MCP751_COM_IRQ,		\
+		.flags		= STD_COM_FLAGS		\
+	},						\
+
+#define RS_TABLE_SIZE  2
+
+#define CS3_BASE	   		 	(0x43000000)
+#define EN_INT_UART_ON(line)    *((volatile unsigned short *)(CS3_BASE+0x18))
|= (0x4000 << line)
+#define EN_INT_UART_OFF(line)   *((volatile unsigned short *)(CS3_BASE+0x18))
&= ~(0x4000 << line)
+#define TEST_INT_UART(line)     (*((volatile unsigned short *)(CS3_BASE+0x18))
& (0x0010 << line))
+
+#else
 #error serial port not supported on this board
-#endif /* !CONFIG_SERIAL_CDB4 */
+#endif



--- linux-2.4.x/drivers/char/serial.c.orig	2004-12-15 05:55:52.000000000 +0100
+++ linux-2.4.x/drivers/char/serial.c	2005-08-30 13:17:35.000000000 +0200
@@ -448,7 +448,24 @@
 	irq = (7 - (irq % 8)) * 4;

 	*icrp = (*icrp & ((7 << irq) ^ 0x77777777)) | ((8 + pri) << irq);
+
+#if defined(CONFIG_SIGNAL_MCP751)
+	*( (volatile unsigned long *)(MCF_MBAR + MCFSIM_PITR)) |= 0x00000020;
+#endif
+}
+static inline void mcf_free_irq(int irq)
+{
+	volatile unsigned long *icrp;
+
+	irq -= 65;
+	if(irq < 0 || irq >= 32)
+		return;
+
+	icrp = (volatile unsigned long *)(MCF_MBAR + MCFSIM_ICR1) + irq / 8;
+	irq = (7 - (irq % 8)) * 4;
+	*icrp = (*icrp & ((7 << irq) ^ 0x77777777)) | (8 << irq);
 }
+
 #else /* !CONFIG_COLDFIRE */
 # define mcf_reset_irq(irq) do {} while(0)
 # define mcf_manage_sim(irq,pri) do {} while(0)
@@ -1568,9 +1585,9 @@
 			}
 			goto errout;
 		}
-#ifdef CONFIG_COLDFIRE
+#if defined(CONFIG_SIGNAL_MCP751)
 		else if(handler == rs_interrupt_single)
-			mcf_manage_sim(state->irq, CDB4_COM_IRQPRI);
+			mcf_manage_sim(state->irq, MCP751_COM_IRQPRI);
 #endif /* CONFIG_COLDFIRE */
 #ifdef CONFIG_IXP425_DCD0
 		if (info->port == 0) {
@@ -1620,6 +1637,11 @@
 		info->IER |= UART_IER_UUE | UART_IER_RTOIE;
 	serial_outp(info, UART_IER, info->IER);	/* enable interrupts */

+#ifdef CONFIG_SIGNAL_MCP751
+	/* Enable FPGA UART interrupts */
+	EN_INT_UART_ON(info->line);
+#endif
+
 #ifdef CONFIG_SERIAL_MANY_PORTS
 	if (info->flags & ASYNC_FOURPORT) {
 		/* Enable interrupts on the AST Fourport board */
@@ -1720,6 +1742,11 @@
 	 */
 	if (state->irq && (!IRQ_ports[state->irq] ||
 			  !IRQ_ports[state->irq]->next_port)) {
+
+#ifdef CONFIG_COLDFIRE
+		mcf_free_irq(state->irq);
+#endif
+
 		if (IRQ_ports[state->irq]) {
 			free_irq(state->irq, &IRQ_ports[state->irq]);
 #if defined(CONFIG_HYPERSTONE)
@@ -1751,6 +1778,11 @@
 		free_page(pg);
 	}

+#ifdef CONFIG_SIGNAL_MCP751
+	/* Disable FPGA UART interrupts */
+	EN_INT_UART_OFF(info->line);
+#endif
+
 	info->IER = 0;
 	serial_outp(info, UART_IER, 0x00);	/* disable all intrs */
 #ifdef CONFIG_SERIAL_MANY_PORTS
@@ -3746,6 +3778,7 @@
 	serial_outp(info, UART_LCR, 0x03);
 	for (count = 0; count < 256; count++)
 		serial_outp(info, UART_TX, count);
+	while (!(serial_inp(info, UART_LSR) & UART_LSR_TEMT))
 	mdelay(20);
 	for (count = 0; (serial_inp(info, UART_LSR) & UART_LSR_DR) &&
 	     (count < 256); count++)





More information about the uClinux-dev mailing list