diff -ur linux-2.4.29-uc1-cvs20050515.working/arch/armnommu/mach-cx821xx/gpioisr.c linux-2.4.29-uc1-cvs20050515/arch/armnommu/mach-cx821xx/gpioisr.c
--- linux-2.4.29-uc1-cvs20050515.working/arch/armnommu/mach-cx821xx/gpioisr.c	2005-05-06 08:50:30.000000000 +0200
+++ linux-2.4.29-uc1-cvs20050515/arch/armnommu/mach-cx821xx/gpioisr.c	2005-07-04 20:30:09.000000000 +0200
@@ -295,12 +295,24 @@
 {
       //Linux Console
    #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
-	   void rs_interrupt(int irq, void * dev_id, struct pt_regs * regs) ;
-	   rs_interrupt( GPIOINT_UART1, NULL, NULL ) ;
+	   void rs_interrupt(int irq, void * dev_id, struct pt_regs * regs, int line) ;
+	   rs_interrupt( GPIOINT_UART1, NULL, NULL, 0 ) ;
    #endif
    ClearGPIOIntStatus(GPIOINT_UART1);  
 }
 
+#ifdef CONFIG_BD_TIBURON
+void GPIOB5_Handler(int gpio_num)
+{
+      //Linux Console
+   #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
+	   void rs_interrupt(int irq, void * dev_id, struct pt_regs * regs, int line) ;
+	   rs_interrupt( GPIOINT_UART2, NULL, NULL, 1 ) ;
+   #endif
+   ClearGPIOIntStatus(GPIOINT_UART2);  
+}
+#endif
+
 void GPIOB30_Handler( int gpio_num )
 {
 	#ifdef CONFIG_BD_MACKINAC
diff -ur linux-2.4.29-uc1-cvs20050515.working/drivers/char/cnxtserial.c linux-2.4.29-uc1-cvs20050515/drivers/char/cnxtserial.c
--- linux-2.4.29-uc1-cvs20050515.working/drivers/char/cnxtserial.c	2005-06-13 18:56:00.000000000 +0200
+++ linux-2.4.29-uc1-cvs20050515/drivers/char/cnxtserial.c	2005-07-11 23:09:05.000000000 +0200
@@ -59,7 +59,9 @@
 #include <asm/arch/cnxtbsp.h>
 #include <asm/arch/gpio.h>
 
-static struct cnxt_serial uart_info;
+#define NR_PORTS 2
+
+static struct cnxt_serial uart_info[NR_PORTS];
 
 static int console_initialized = 0;
 
@@ -68,9 +70,9 @@
 struct tty_driver serial_driver, callout_driver;
 static int serial_refcount;
 
-static struct tty_struct *serial_table[2];
-static struct termios *serial_termios[2];
-static struct termios *serial_termios_locked[2];
+static struct tty_struct *serial_table[NR_PORTS];
+static struct termios *serial_termios[NR_PORTS];
+static struct termios *serial_termios_locked[NR_PORTS];
 
 static int baud_table[] = {
 	0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
@@ -134,12 +136,12 @@
 }
 
 
-static void start_rx(void)
+static void start_rx(struct cnxt_serial *info)
 {
-	struct uart_regs *uart = uart_info.uart;
+	struct uart_regs *uart = info->uart;
 
 #if 0
-	if(uart_info.use_ints)
+	if(info->use_ints)
 #endif
 	{
 		/* enable IRQs */
@@ -152,14 +154,21 @@
 {
   volatile struct uart_regs* puart;
   unsigned long timeout = 10000;
+  unsigned short modem_ctrl;
   puart = (volatile struct uart_regs*)uart;
   while(1){
     if(timeout-- == 0) {
       printk("eot timeout\n");
       break;
     }
-    if(puart->line_status_reg & LSR_Tx_Fifo_Empty)
+    if(puart->line_status_reg & LSR_Tx_Fifo_Empty) {
       break;
+    } else {
+      modem_ctrl=puart->modem_ctrl;
+      if(!(puart->msr & 0x80)) {
+        return;
+      }
+    }
   }
 }
 
@@ -171,20 +180,20 @@
 }
 
 
-static void cnxt_put_char(char ch)
+static void cnxt_put_char(struct cnxt_serial *info, char ch)
 {
 	int flags = 0;
 
-	if(uart_info.use_ints)
+	if(info->use_ints)
 	{
-		uart_info.uart->fifo=ch;
+		info->uart->fifo=ch;
 	}
 	else
 	{
 		save_flags(flags);
 		cli();
-		wait_EOT(uart_info.uart);
-		uart_info.uart->fifo=ch; 
+		wait_EOT(info->uart);
+		info->uart->fifo=ch; 
 		restore_flags(flags);
 	}
 }
@@ -199,23 +208,27 @@
 		return;
 	}
 
-	cnxt_put_char(ch);
+	cnxt_put_char(info, ch);
 }	
 
 
-static void uart_speed(void)
+static void uart_speed(struct cnxt_serial *info)
 {
-  struct uart_regs *uart = uart_info.uart;
-  
+  struct uart_regs *uart = info->uart;
+
   uart->line_ctrl = LCR_Divisor_Latch;
-  uart->fifo = (char)UART_115200;  /* lower baud rate div */
-  uart->irqe = (char)(UART_115200>>8);  /* upper baud rate div */
+// FIXME: DPCM?
+//  uart->fifo=(char)(uart_info.baud);  /* lower baud rate div */
+//  uart->irqe=(char)(uart_info.baud>>8);  /* upper baud rate div */
+  uart->fifo=(char)UART_115200;  /* lower baud rate div */
+  uart->irqe=(char)(UART_115200>>8);  /* upper baud rate div */
   uart->line_ctrl = 0;
   uart->line_ctrl =  LCR_8_Bit_Word_1;
   uart->iir =  (FCR_Fifo_Enable | FCR_Rx_Fifo_Reset | FCR_Tx_Fifo_Reset ); /* fifo ctrl */
   uart->irqe = IER_Rx_Holding_Reg;  /* enable rx intr */
-  tx_start(uart, uart_info.use_ints);
-  start_rx();
+  tx_start(uart, info->use_ints);
+  start_rx(info);
+  uart->modem_ctrl=15; /* FIXME: Only for DPCM internal modem? */
 }
 
 
@@ -225,15 +238,20 @@
  
 static void cnxt_init_console(void)
 {
-	memset(&uart_info, 0, sizeof(struct cnxt_serial));
-	
-	uart_info.uart          = (struct uart_regs*)UART0_Base_Addr;
-	uart_info.tty	        = 0;
-	uart_info.irqmask	= BIT24;
-	uart_info.irq	        = CNXT_INT_LVL_GPIO;
-	uart_info.port	        = 1;
-	uart_info.use_ints	= 0;
-	uart_info.is_cons	= 1;
+
+/* *** FIXME *** Init ALL ports like this! */
+
+	struct cnxt_serial *info=&(uart_info[0]);  /* TODO: Is it ok to always use the first uart? */
+
+	memset(info, 0, sizeof(struct cnxt_serial));
+
+	info->uart          = (struct uart_regs*)UART0_Base_Addr;
+	info->tty	        = 0;
+	info->irqmask	= BIT24;
+	info->irq	        = CNXT_INT_LVL_GPIO;
+	info->port	        = 1;
+	info->use_ints	= 0;
+	info->is_cons	= 1;
 
 	console_initialized = 1;
 }
@@ -244,7 +262,7 @@
 	if (!cp)
 		return(-1);
 	cnxt_init_console();
-	uart_speed();
+	uart_speed(&(uart_info[0])); /* TODO: Is it ok to always use the first uart? */
 	return(0);
 }
 
@@ -264,15 +282,15 @@
 	if (!console_initialized)
 	{
 		cnxt_init_console();
-		uart_speed();
+		uart_speed(&(uart_info[0])); /* TODO: Is it ok to always use the first uart? */
 	}
 	while (len-- > 0)
 	{
 		if (*p == '\n')
 		{
-			cnxt_put_char('\r');
+			cnxt_put_char(&(uart_info[0]), '\r');  /* TODO: Is it ok to always use the first uart? */
 		}
-		cnxt_put_char(*p++);
+		cnxt_put_char(&(uart_info[0]), *p++); /* TODO: Is it ok to always use the first uart? */
 	}
 }
 
@@ -316,8 +334,8 @@
 	i = cflag & CBAUD;
 
 	info->baud = baud_table[i];
-	uart_speed();
-	start_rx();
+	uart_speed(info);
+	start_rx(info);
 	tx_start(info->uart, info->use_ints);
 	return;
 }
@@ -524,11 +542,18 @@
 
 	line = MINOR(tty->device) - tty->driver.minor_start;
 
-	
-	if (line != 0) /* we have exactly one */
-		return -ENODEV;
+#ifdef CONFIG_BD_TIBURON
+	/* On the Tiburon (Actiontec Dual PC Modem) ttyS1 is connected
+           to the internal modem; we should not echo back anything
+           that it sends to us, because we would get caught in a loop
+           otherwise... */
+	if (line == 1) {
+		tty->termios->c_lflag &= ~ECHO;
+	}
+#endif
 
-	info = &uart_info;
+//JH orig	info = &uart_info;
+	info = &(uart_info[line]);
 
 	if (serial_paranoia_check(info, tty->device, "rs_open"))
 		return -ENODEV;
@@ -552,7 +577,9 @@
 		return retval;
 	}
 
-	if ((info->count == 1) && (info->flags & S_SPLIT_TERMIOS)) {
+// FIXME: Different only for DPCM?
+//orig:	if ((info->count == 1) && (info->flags & S_SPLIT_TERMIOS)) {
+	if (info->count == 1) {
 		if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
 			*tty->termios = info->normal_termios;
 		else 
@@ -564,7 +591,7 @@
 	info->pgrp = current->pgrp;
 
 	// Enable GPIO interrupt line for console uart 
-	SetGPIOIntEnable(GPIOINT_UART1, IRQ_ON);
+//FIXME: required? :	SetGPIOIntEnable(GPIOINT_UART1, IRQ_ON);
 	return 0;
 }
 
@@ -1110,7 +1137,7 @@
 	save_flags(flags);
 	cli();
 	tx_start(info->uart, info->use_ints);
-	start_rx();
+	start_rx(info);
 	restore_flags(flags);
 }
 
@@ -1118,6 +1145,22 @@
 {
 	struct cnxt_serial *info = (struct cnxt_serial *)tty->driver_data;
 
+printk("OLD: %d %d %d %d %d\n",
+  old_termios->c_iflag,
+  old_termios->c_oflag,
+  old_termios->c_cflag,
+  old_termios->c_lflag,
+  old_termios->c_line
+);
+
+printk("NEW: %d %d %d %d %d\n",
+  tty->termios->c_iflag,
+  tty->termios->c_oflag,
+  tty->termios->c_cflag,
+  tty->termios->c_lflag,
+  tty->termios->c_line
+);
+
 	if (tty->termios->c_cflag == old_termios->c_cflag)
 		return;
 
@@ -1169,8 +1212,9 @@
 		return;
 #else
 	struct tty_struct *tty = info->tty;
-	if (!(info->flags & S_INITIALIZED))
-		return;
+// FIXME: required?
+//	if (!(info->flags & S_INITIALIZED))
+//		return;
 #endif	
 	
 	ch = (unsigned char)uart->fifo;
@@ -1269,12 +1313,12 @@
 
 
 
-void rs_interrupt(int irq, void * dev_id, struct pt_regs * regs)
+void rs_interrupt(int irq, void * dev_id, struct pt_regs * regs, int line)
 {
 	char status;
 
-	struct cnxt_serial * info = &uart_info;
-  	struct uart_regs *uart = uart_info.uart;
+	struct cnxt_serial * info = &(uart_info[line]); /* FIXME */
+  	struct uart_regs *uart = info->uart;
   	
 	status = (uart->iir & 0x0f); /* only concerned w/ lower nibble */
 	
@@ -1302,7 +1346,8 @@
 {
 	int flags;
 	struct cnxt_serial *info;
-		
+	int i;
+
 	/* Setup base handler, and timer table. */
 	init_bh(SERIAL_BH, do_serial_bh);
 	
@@ -1313,10 +1358,11 @@
 	serial_driver.name = "ttyS";
 	serial_driver.major = TTY_MAJOR;
 	serial_driver.minor_start = 64;
-	serial_driver.num = 1;
+	serial_driver.num = 2;
 	serial_driver.type = TTY_DRIVER_TYPE_SERIAL;
 	serial_driver.subtype = SERIAL_TYPE_NORMAL;
 	serial_driver.init_termios = tty_std_termios;
+printk("*** tty_std_termios.c_lflag=%d ***\n", tty_std_termios.c_lflag);
 	serial_driver.init_termios.c_cflag = 
 			B57600 | CS8 | CREAD | HUPCL | CLOCAL;
 	serial_driver.flags = TTY_DRIVER_REAL_RAW;
@@ -1355,39 +1401,47 @@
 		panic("Couldn't register serial driver\n");
 	if (tty_register_driver(&callout_driver))
 		panic("Couldn't register callout driver\n");
-	
+
+
+
+
+
+
 	save_flags(flags); cli();
 
+	//struct cnxt_serial *info;
+	//static struct cnxt_serial uart_info;
+
+	for (i = 0, info = uart_info; i < NR_PORTS; i++, info++) {
+		info->magic = SERIAL_MAGIC;
+		info->uart = (struct uart_regs*)(i == 0 ? UART0_Base_Addr : UART1_Base_Addr); /* FIXME */
+		info->port = (i == 0 ? UART0_Base_Addr : UART1_Base_Addr); /* FIXME */
+		info->tty = 0;
+		info->irq = (i == 0 ? GPIOINT_UART1 : GPIOINT_UART2);
+		info->custom_divisor = 16;
+		info->close_delay = 50;
+		info->closing_wait = 3000;
+		info->x_char = 0;
+		info->event = 0;
+		info->count = 0;
+		info->blocked_open = 0;
+		info->tqueue.routine = do_softint;
+		info->tqueue.data = info;
+		info->tqueue_hangup.routine = do_serial_hangup;
+		info->tqueue_hangup.data = info;
+		info->callout_termios =callout_driver.init_termios;
+		info->normal_termios = serial_driver.init_termios;
+		init_waitqueue_head(&info->open_wait);
+		init_waitqueue_head(&info->close_wait);
+		info->line = i;
+		info->is_cons = 1; /* Means shortcuts work */
+
+		printk("%s%d at 0x%08x (irq = %d)", serial_driver.name, info->line, 
+		       info->port, info->irq);
+		printk(" is a 16c550 UART\n");
+		/* DEBUG: printk("info = %08x\n",info); */
+	}
 
-	info = &uart_info;
-	info->magic = SERIAL_MAGIC;
-	info->uart = (struct uart_regs*)UART0_Base_Addr;
-	info->port = UART0_Base_Addr;
-	info->tty = 0;
-	info->irq = CNXT_INT_LVL_GPIO;
-	info->custom_divisor = 16;
-	info->close_delay = 50;
-	info->closing_wait = 3000;
-	info->x_char = 0;
-	info->event = 0;
-	info->count = 0;
-	info->blocked_open = 0;
-	info->tqueue.routine = do_softint;
-	info->tqueue.data = info;
-	info->tqueue_hangup.routine = do_serial_hangup;
-	info->tqueue_hangup.data = info;
-	info->callout_termios =callout_driver.init_termios;
-	info->normal_termios = serial_driver.init_termios;
-	init_waitqueue_head(&info->open_wait);
-	init_waitqueue_head(&info->close_wait);
-	info->line = 0;
-	info->is_cons = 1; /* Means shortcuts work */
-
-	printk("%s%d at 0x%08x (irq = %d)", serial_driver.name, info->line, 
-	       info->port, info->irq);
-       printk(" is a 16c550 UART\n");
-       printk("info = %08x\n",info);
-       
 #if DEBUG_CONSOLE_ON_UART_2
 	SetGPIOIntEnable( GPIO25, IRQ_OFF );
 	SetGPIOInputEnable( GPIO25, GP_INPUTOFF );
@@ -1401,6 +1455,16 @@
 	GPIO_SetGPIOIRQRoutine(GPIOINT_UART1, GPIOB25_Handler);
 	SetGPIOIntEnable(GPIOINT_UART1, IRQ_ON);
 	
+/* new ---> */
+	SetGPIOIntEnable(GPIOINT_UART2, IRQ_OFF);
+	SetGPIODir( GPIOINT_UART2, GP_INPUT );
+	SetGPIOIntPolarity (GPIOINT_UART2, GP_IRQ_POL_POSITIVE);
+	SetGPIOInputEnable( GPIOINT_UART2, GP_INPUTON );
+
+	GPIO_SetGPIOIRQRoutine(GPIOINT_UART2, GPIOB5_Handler);
+	SetGPIOIntEnable(GPIOINT_UART2, IRQ_ON);
+/* <--- new */
+
 	restore_flags(flags);
 
 	return 0;
diff -ur linux-2.4.29-uc1-cvs20050515.working/drivers/char/cnxtserial.h linux-2.4.29-uc1-cvs20050515/drivers/char/cnxtserial.h
--- linux-2.4.29-uc1-cvs20050515.working/drivers/char/cnxtserial.h	2005-06-05 15:53:56.000000000 +0200
+++ linux-2.4.29-uc1-cvs20050515/drivers/char/cnxtserial.h	2005-07-11 23:10:28.000000000 +0200
@@ -131,6 +131,10 @@
 	#endif
 #endif
 
+#ifdef CONFIG_BD_TIBURON
+	#define	UART1_Base_Addr	0x002C8000
+#endif
+
 /*  We use a 1.8432Mhz clk */
 #define UART_CLK    1843200
 #define UART_2400   ((UART_CLK)/(16*2400))
diff -ur linux-2.4.29-uc1-cvs20050515.working/include/asm-armnommu/arch-cx821xx/gpio.h linux-2.4.29-uc1-cvs20050515/include/asm-armnommu/arch-cx821xx/gpio.h
--- linux-2.4.29-uc1-cvs20050515.working/include/asm-armnommu/arch-cx821xx/gpio.h	2005-06-05 15:53:56.000000000 +0200
+++ linux-2.4.29-uc1-cvs20050515/include/asm-armnommu/arch-cx821xx/gpio.h	2005-07-11 23:10:28.000000000 +0200
@@ -259,6 +259,9 @@
 #ifdef CONFIG_BD_MACKINAC
 	#define GPIOINT_UART2   GPIO30
 #endif
+#ifdef CONFIG_BD_TIBURON
+	#define GPIOINT_UART2   GPIO5
+#endif
 
 #if !defined(BUILD_BOOTROM) && defined(INCLUDE_SOFTWARE_WLAN)
 
@@ -457,6 +460,7 @@
 extern void GPIOB30_Handler(int gpio_num);
 #ifdef CONFIG_BD_TIBURON
 extern void GPIOB27_Handler(int gpio_num);
+extern void GPIOB5_Handler(int gpio_num);
 #endif
 
 #define MISC_BASE       ((UINT32)0x00350000)

