diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index b3692e6..896042b 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -1526,6 +1526,18 @@ config SERIAL_GRLIB_GAISLER_APBUART_CONSOLE
 	help
 	Support for running a console on the GRLIB APBUART
 
+config SERIAL_GRLIB_GAISLER_APBUART_GRMON_VIRTUAL
+	bool "Virtual channel created by GRMON to communicate with KGDB"
+	depends on SERIAL_GRLIB_GAISLER_APBUART=y
+	default y
+	help
+	Add support for a virtual GRMON<->KGDB channel that
+	is created using share memory polling by GRMON. Start
+	GRMON with the option "-vchannel" to enable polling. This
+	feature enables connecting to KGDB without having an hardware
+	serial connection, but using GRMON as an tunnel. Also
+	enable KGDB_SERIAL_CONSOLE to use this feature.
+
 config SERIAL_ALTERA_JTAGUART
 	tristate "Altera JTAG UART support"
 	select SERIAL_CORE
diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile
index cb2628f..ea3fc05 100644
--- a/drivers/tty/serial/Makefile
+++ b/drivers/tty/serial/Makefile
@@ -81,10 +81,10 @@ obj-$(CONFIG_SERIAL_OF_PLATFORM) += of_serial.o
 obj-$(CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL) += nwpserial.o
 obj-$(CONFIG_SERIAL_KS8695) += serial_ks8695.o
 obj-$(CONFIG_SERIAL_OMAP) += omap-serial.o
+obj-$(CONFIG_SERIAL_GRLIB_GAISLER_APBUART) += apbuart.o
 obj-$(CONFIG_KGDB_SERIAL_CONSOLE) += kgdboc.o
 obj-$(CONFIG_SERIAL_QE) += ucc_uart.o
 obj-$(CONFIG_SERIAL_TIMBERDALE)	+= timbuart.o
-obj-$(CONFIG_SERIAL_GRLIB_GAISLER_APBUART) += apbuart.o
 obj-$(CONFIG_SERIAL_ALTERA_JTAGUART) += altera_jtaguart.o
 obj-$(CONFIG_SERIAL_ALTERA_UART) += altera_uart.o
 obj-$(CONFIG_SERIAL_VT8500) += vt8500_serial.o
diff --git a/drivers/tty/serial/apbuart.c b/drivers/tty/serial/apbuart.c
index 5f40f42..38eb8cc 100644
--- a/drivers/tty/serial/apbuart.c
+++ b/drivers/tty/serial/apbuart.c
@@ -124,7 +124,6 @@ static void apbuart_rx_chars(struct uart_port *port)
 
 		uart_insert_char(port, rsr, UART_STATUS_OE, ch, flag);
 
-
 	      ignore_char:
 		status = UART_GET_STATUS(port);
 	}
@@ -350,11 +349,88 @@ static struct uart_ops grlib_apbuart_ops = {
 	.config_port = apbuart_config_port,
 	.verify_port = apbuart_verify_port,
 #ifdef CONFIG_CONSOLE_POLL
-	.poll_get_char	= apbuart_poll_get_char,
-	.poll_put_char	= apbuart_poll_put_char,
-#endif		
+	.poll_get_char = apbuart_poll_get_char,
+	.poll_put_char = apbuart_poll_put_char,
+#endif
+};
+
+#undef CONFIG_SERIAL_GRLIB_GAISLER_APBUART_GRMON_VIRTUAL_HAS
+#if defined(CONFIG_SERIAL_GRLIB_GAISLER_APBUART_GRMON_VIRTUAL) && defined(CONFIG_SPARC_LEON) && defined(CONFIG_CONSOLE_POLL)
+#define CONFIG_SERIAL_GRLIB_GAISLER_APBUART_GRMON_VIRTUAL_HAS
+#include <asm/leon.h>
+
+/*
+ * Use a memory array that is continuously read/written by GRMON
+ * as a communication channel. GRMON will test for the existence
+ * of symbol apbuart_grmon_vchannel. If present the "shared memory"
+ * of apbuart_grmon_vchannel will be used to comunicate with linux.
+ * apbuart_grmon_vchannel is only used for KGDB polling communication.
+ */
+unsigned int apbuart_grmon_vchannel[4] = { 0, 0, 0, 0 };
+
+EXPORT_SYMBOL(apbuart_grmon_vchannel);
+
+static void apbuart_set_termios_v(struct uart_port *port,
+				  struct ktermios *termios,
+				  struct ktermios *old)
+{
+	return;
+}
+
+unsigned char apbuart_poll_get_char_v_b[4];
+unsigned char apbuart_poll_get_char_v_c = 0;
+static int apbuart_poll_get_char_v(struct uart_port *port)
+{
+	int c = NO_POLL_CHAR, cnt, i;
+	if (apbuart_poll_get_char_v_c) {
+		apbuart_poll_get_char_v_c--;
+		c = apbuart_poll_get_char_v_b[0] & 0xff;
+		for (i = 0; i < apbuart_poll_get_char_v_c; i++) {
+			apbuart_poll_get_char_v_b[i] =
+			    apbuart_poll_get_char_v_b[i + 1];
+		}
+	}
+
+	/*
+	 * poll for new char GRMON from. When grmon has a new char it
+	 * will set write it into apbuart_grmon_vchannel[0] and then
+	 * set apbuart_grmon_vchannel[1]
+	 */
+	else if ((cnt = LEON3_BYPASS_LOAD_PA(__pa(&apbuart_grmon_vchannel[1])))) {
+		unsigned int ar =
+		    LEON3_BYPASS_LOAD_PA(__pa(&apbuart_grmon_vchannel[0]));
+		LEON_BYPASS_STORE_PA(__pa(&apbuart_grmon_vchannel[1]), 0);
+		c = ar & 0xff;
+		for (i = 1; i < cnt; i++) {
+			apbuart_poll_get_char_v_b[apbuart_poll_get_char_v_c++] =
+			    (ar >> (8 * i)) & 0xff;
+		}
+	}
+
+	return c;
+}
+static void apbuart_console_putchar_v(struct uart_port *port, unsigned char ch)
+{
+	/*
+	 * poll for GRMON readout. When grmon has read apbuart_grmon_vchannel[3]
+	 * it will clear apbuart_grmon_vchannel[2]
+	 */
+	while (LEON3_BYPASS_LOAD_PA(__pa(&apbuart_grmon_vchannel[2]))) {
+	}
+	LEON_BYPASS_STORE_PA(__pa(&apbuart_grmon_vchannel[3]), ch & 0xff);
+	LEON_BYPASS_STORE_PA(__pa(&apbuart_grmon_vchannel[2]), 1);
+	return;
+}
+
+static struct uart_ops grlib_apbuart_v_ops = {
+	.set_termios = apbuart_set_termios_v,
+	.poll_get_char = apbuart_poll_get_char_v,
+	.poll_put_char = apbuart_console_putchar_v,
 };
 
+static struct uart_port grlib_apbuart_vport;
+#endif
+
 static struct uart_port grlib_apbuart_ports[UART_NR];
 static struct device_node *grlib_apbuart_nodes[UART_NR];
 
@@ -423,7 +499,6 @@ static void apbuart_flush_fifo(struct uart_port *port)
 		UART_GET_CHAR(port);
 }
 
-
 /* ======================================================================== */
 /* Console driver, if enabled                                               */
 /* ======================================================================== */
@@ -551,7 +626,6 @@ static struct console grlib_apbuart_console = {
 	.data = &grlib_apbuart_driver,
 };
 
-
 static int grlib_apbuart_configure(void);
 
 static int __init apbuart_console_init(void)
@@ -579,7 +653,6 @@ static struct uart_driver grlib_apbuart_driver = {
 	.cons = APBUART_CONSOLE,
 };
 
-
 /* ======================================================================== */
 /* OF Platform Driver                                                       */
 /* ======================================================================== */
@@ -598,12 +671,12 @@ static int __devinit apbuart_probe(struct platform_device *op)
 	port->dev = &op->dev;
 	port->irq = op->archdata.irqs[0];
 
-	uart_add_one_port(&grlib_apbuart_driver, (struct uart_port *) port);
+	uart_add_one_port(&grlib_apbuart_driver, (struct uart_port *)port);
 
-	apbuart_flush_fifo((struct uart_port *) port);
+	apbuart_flush_fifo((struct uart_port *)port);
 
 	printk(KERN_INFO "grlib-apbuart at 0x%llx, irq %d\n",
-	       (unsigned long long) port->mapbase, port->irq);
+	       (unsigned long long)port->mapbase, port->irq);
 	return 0;
 }
 
@@ -620,13 +693,12 @@ static struct of_device_id __initdata apbuart_match[] = {
 static struct platform_driver grlib_apbuart_of_driver = {
 	.probe = apbuart_probe,
 	.driver = {
-		.owner = THIS_MODULE,
-		.name = "grlib-apbuart",
-		.of_match_table = apbuart_match,
-	},
+		   .owner = THIS_MODULE,
+		   .name = "grlib-apbuart",
+		   .of_match_table = apbuart_match,
+		   },
 };
 
-
 static int grlib_apbuart_configure(void)
 {
 	struct device_node *np;
@@ -641,7 +713,7 @@ static int grlib_apbuart_configure(void)
 
 		ampopts = of_get_property(np, "ampopts", NULL);
 		if (ampopts && (*ampopts == 0))
-			continue; /* Ignore if used by another OS instance */
+			continue;	/* Ignore if used by another OS instance */
 		regs = of_get_property(np, "reg", NULL);
 		/* Frequency of APB Bus is frequency of UART */
 		freq_hz = of_get_property(np, "freq", NULL);
@@ -656,14 +728,16 @@ static int grlib_apbuart_configure(void)
 		port = &grlib_apbuart_ports[line];
 
 		port->mapbase = addr;
-		port->membase = ioremap(addr, sizeof(struct grlib_apbuart_regs_map));
+		port->membase =
+		    ioremap(addr, sizeof(struct grlib_apbuart_regs_map));
 		port->irq = 0;
 		port->iotype = UPIO_MEM;
 		port->ops = &grlib_apbuart_ops;
 		port->flags = UPF_BOOT_AUTOCONF;
 		port->line = line;
 		port->uartclk = *freq_hz;
-		port->fifosize = apbuart_scan_fifo_size((struct uart_port *) port, line);
+		port->fifosize =
+		    apbuart_scan_fifo_size((struct uart_port *)port, line);
 		line++;
 
 		/* We support maximum UART_NR uarts ... */
@@ -671,6 +745,18 @@ static int grlib_apbuart_configure(void)
 			break;
 	}
 
+#ifdef CONFIG_SERIAL_GRLIB_GAISLER_APBUART_GRMON_VIRTUAL_HAS
+	grlib_apbuart_vport.mapbase = 0;
+	grlib_apbuart_vport.membase = 0;
+	grlib_apbuart_vport.irq = 0;
+	grlib_apbuart_vport.iotype = UPIO_MEM;
+	grlib_apbuart_vport.ops = &grlib_apbuart_v_ops;
+	grlib_apbuart_vport.flags = UPF_BOOT_AUTOCONF;
+	grlib_apbuart_vport.line = line;
+	grlib_apbuart_vport.fifosize = 0;
+	line++;
+#endif
+
 	grlib_apbuart_driver.nr = grlib_apbuart_port_nr = line;
 	return line ? 0 : -ENODEV;
 }
@@ -702,6 +788,17 @@ static int __init grlib_apbuart_init(void)
 		uart_unregister_driver(&grlib_apbuart_driver);
 		return ret;
 	}
+#ifdef CONFIG_SERIAL_GRLIB_GAISLER_APBUART_GRMON_VIRTUAL_HAS
+
+	/* register an extra virtual port that is used for
+	 * GRMON<->KGDB communication */
+	uart_add_one_port(&grlib_apbuart_driver,
+			  (struct uart_port *)&grlib_apbuart_vport);
+	printk(KERN_INFO
+	       "apbuart: virtual KGDB channel for grmon, use cmdline arg \"kgdboc=kms,ttyS%d,38400\".\napbuart: Use option \"-vchannel\" when starting GRMON.\napbuart: apbuart_grmon_vchannel at pa:0x%x\n",
+	       grlib_apbuart_vport.line, (int)__pa(&apbuart_grmon_vchannel));
+
+#endif
 
 	return ret;
 }
