serial: sirf: add support for new SiRFmarco SMP SoC

CSR SiRFmarco's UART IP is same with SiRFprimaII except that
it has two more uart ports.
this patch makes the old driver support new SiRFmarco as well:
1. add .compatible = "sirf,marco-uart" to OF match table
2. add two ports in the port table
3. take spin_lock in isr to avoid the conflict of threads opening
uart on CPU1 and isr running on CPU0.
For 3, we did see some problems on SiRFmarco as SiRFmarco is a
SMP SoC but the old SiRFprimaII is UP.

Signed-off-by: Barry Song <Baohua.Song@csr.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
diff --git a/drivers/tty/serial/sirfsoc_uart.c b/drivers/tty/serial/sirfsoc_uart.c
index 5da5cb9..142217c 100644
--- a/drivers/tty/serial/sirfsoc_uart.c
+++ b/drivers/tty/serial/sirfsoc_uart.c
@@ -75,6 +75,20 @@
 			.line		= 2,
 		},
 	},
+	[3] = {
+		.port = {
+			.iotype		= UPIO_MEM,
+			.flags		= UPF_BOOT_AUTOCONF,
+			.line		= 3,
+		},
+	},
+	[4] = {
+		.port = {
+			.iotype		= UPIO_MEM,
+			.flags		= UPF_BOOT_AUTOCONF,
+			.line		= 4,
+		},
+	},
 };
 
 static inline struct sirfsoc_uart_port *to_sirfport(struct uart_port *port)
@@ -245,6 +259,7 @@
 	struct uart_port *port = &sirfport->port;
 	struct uart_state *state = port->state;
 	struct circ_buf *xmit = &port->state->xmit;
+	spin_lock(&port->lock);
 	intr_status = rd_regl(port, SIRFUART_INT_STATUS);
 	wr_regl(port, SIRFUART_INT_STATUS, intr_status);
 	intr_status &= rd_regl(port, SIRFUART_INT_EN);
@@ -254,6 +269,7 @@
 				goto recv_char;
 			uart_insert_char(port, intr_status,
 					SIRFUART_RX_OFLOW, 0, TTY_BREAK);
+			spin_unlock(&port->lock);
 			return IRQ_HANDLED;
 		}
 		if (intr_status & SIRFUART_RX_OFLOW)
@@ -286,6 +302,7 @@
 		sirfsoc_uart_pio_rx_chars(port, SIRFSOC_UART_IO_RX_MAX_CNT);
 	if (intr_status & SIRFUART_TX_INT_EN) {
 		if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
+			spin_unlock(&port->lock);
 			return IRQ_HANDLED;
 		} else {
 			sirfsoc_uart_pio_tx_chars(sirfport,
@@ -296,6 +313,7 @@
 				sirfsoc_uart_stop_tx(port);
 		}
 	}
+	spin_unlock(&port->lock);
 	return IRQ_HANDLED;
 }
 
@@ -729,6 +747,7 @@
 
 static struct of_device_id sirfsoc_uart_ids[] = {
 	{ .compatible = "sirf,prima2-uart", },
+	{ .compatible = "sirf,marco-uart", },
 	{}
 };
 MODULE_DEVICE_TABLE(of, sirfsoc_serial_of_match);