MIPS: BCM63xx: Add support for second uart.

The BCm63xx SOC has two uarts.  Some boards use the second one for
bluetooth.  This patch changes platform device registration code to
handle this.  Changes to the UART driver were already merged in
6a2c7eabfd09ca7986bf96b8958a87ca041a19d8.

Signed-off-by: Maxime Bizon <mbizon@freebox.fr>
To: linux-mips@linux-mips.org
Cc: Maxime Bizon <mbizon@freebox.fr>
Patchwork: http://patchwork.linux-mips.org/patch/900/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
diff --git a/arch/mips/bcm63xx/boards/board_bcm963xx.c b/arch/mips/bcm63xx/boards/board_bcm963xx.c
index a690afb..8b0abcb 100644
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -18,6 +18,7 @@
 #include <asm/addrspace.h>
 #include <bcm63xx_board.h>
 #include <bcm63xx_cpu.h>
+#include <bcm63xx_dev_uart.h>
 #include <bcm63xx_regs.h>
 #include <bcm63xx_io.h>
 #include <bcm63xx_dev_pci.h>
@@ -40,6 +41,7 @@
 	.name				= "96338GW",
 	.expected_cpu_id		= 0x6338,
 
+	.has_uart0			= 1,
 	.has_enet0			= 1,
 	.enet0 = {
 		.force_speed_100	= 1,
@@ -82,6 +84,7 @@
 	.name				= "96338W",
 	.expected_cpu_id		= 0x6338,
 
+	.has_uart0			= 1,
 	.has_enet0			= 1,
 	.enet0 = {
 		.force_speed_100	= 1,
@@ -126,6 +129,8 @@
 static struct board_info __initdata board_96345gw2 = {
 	.name				= "96345GW2",
 	.expected_cpu_id		= 0x6345,
+
+	.has_uart0			= 1,
 };
 #endif
 
@@ -137,6 +142,7 @@
 	.name				= "96348R",
 	.expected_cpu_id		= 0x6348,
 
+	.has_uart0			= 1,
 	.has_enet0			= 1,
 	.has_pci			= 1,
 
@@ -180,6 +186,7 @@
 	.name				= "96348GW-10",
 	.expected_cpu_id		= 0x6348,
 
+	.has_uart0			= 1,
 	.has_enet0			= 1,
 	.has_enet1			= 1,
 	.has_pci			= 1,
@@ -239,6 +246,7 @@
 	.name				= "96348GW-11",
 	.expected_cpu_id		= 0x6348,
 
+	.has_uart0			= 1,
 	.has_enet0			= 1,
 	.has_enet1			= 1,
 	.has_pci			= 1,
@@ -292,6 +300,7 @@
 	.name				= "96348GW",
 	.expected_cpu_id		= 0x6348,
 
+	.has_uart0			= 1,
 	.has_enet0			= 1,
 	.has_enet1			= 1,
 	.has_pci			= 1,
@@ -349,9 +358,10 @@
 	.name				= "F@ST2404",
 	.expected_cpu_id		= 0x6348,
 
-	.has_enet0			= 1,
-	.has_enet1			= 1,
-	.has_pci			= 1,
+	.has_uart0			= 1,
+        .has_enet0			= 1,
+        .has_enet1			= 1,
+        .has_pci			= 1,
 
 	.enet0 = {
 		.has_phy		= 1,
@@ -391,6 +401,7 @@
 	.name				= "DV201AMR",
 	.expected_cpu_id		= 0x6348,
 
+	.has_uart0			= 1,
 	.has_pci			= 1,
 	.has_ohci0			= 1,
 
@@ -410,6 +421,7 @@
 	.name				= "96348GW-A",
 	.expected_cpu_id		= 0x6348,
 
+	.has_uart0			= 1,
 	.has_enet0			= 1,
 	.has_enet1			= 1,
 	.has_pci			= 1,
@@ -435,6 +447,7 @@
 	.name				= "96358VW",
 	.expected_cpu_id		= 0x6358,
 
+	.has_uart0			= 1,
 	.has_enet0			= 1,
 	.has_enet1			= 1,
 	.has_pci			= 1,
@@ -486,6 +499,7 @@
 	.name				= "96358VW2",
 	.expected_cpu_id		= 0x6358,
 
+	.has_uart0			= 1,
 	.has_enet0			= 1,
 	.has_enet1			= 1,
 	.has_pci			= 1,
@@ -533,6 +547,7 @@
 	.name                           = "AGPF-S0",
 	.expected_cpu_id                = 0x6358,
 
+	.has_uart0			= 1,
 	.has_enet0                      = 1,
 	.has_enet1                      = 1,
 	.has_pci                        = 1,
@@ -834,6 +849,12 @@
 {
 	u32 val;
 
+	if (board.has_uart0)
+		bcm63xx_uart_register(0);
+
+	if (board.has_uart1)
+		bcm63xx_uart_register(1);
+
 	if (board.has_pccard)
 		bcm63xx_pcmcia_register();
 
diff --git a/arch/mips/bcm63xx/cpu.c b/arch/mips/bcm63xx/cpu.c
index 70378bb..cbb7caf 100644
--- a/arch/mips/bcm63xx/cpu.c
+++ b/arch/mips/bcm63xx/cpu.c
@@ -36,6 +36,7 @@
 	[RSET_TIMER]		= BCM_6338_TIMER_BASE,
 	[RSET_WDT]		= BCM_6338_WDT_BASE,
 	[RSET_UART0]		= BCM_6338_UART0_BASE,
+	[RSET_UART1]		= BCM_6338_UART1_BASE,
 	[RSET_GPIO]		= BCM_6338_GPIO_BASE,
 	[RSET_SPI]		= BCM_6338_SPI_BASE,
 	[RSET_OHCI0]		= BCM_6338_OHCI0_BASE,
@@ -72,6 +73,7 @@
 	[RSET_TIMER]		= BCM_6345_TIMER_BASE,
 	[RSET_WDT]		= BCM_6345_WDT_BASE,
 	[RSET_UART0]		= BCM_6345_UART0_BASE,
+	[RSET_UART1]		= BCM_6345_UART1_BASE,
 	[RSET_GPIO]		= BCM_6345_GPIO_BASE,
 	[RSET_SPI]		= BCM_6345_SPI_BASE,
 	[RSET_UDC0]		= BCM_6345_UDC0_BASE,
@@ -109,6 +111,7 @@
 	[RSET_TIMER]		= BCM_6348_TIMER_BASE,
 	[RSET_WDT]		= BCM_6348_WDT_BASE,
 	[RSET_UART0]		= BCM_6348_UART0_BASE,
+	[RSET_UART1]		= BCM_6348_UART1_BASE,
 	[RSET_GPIO]		= BCM_6348_GPIO_BASE,
 	[RSET_SPI]		= BCM_6348_SPI_BASE,
 	[RSET_OHCI0]		= BCM_6348_OHCI0_BASE,
@@ -150,6 +153,7 @@
 	[RSET_TIMER]		= BCM_6358_TIMER_BASE,
 	[RSET_WDT]		= BCM_6358_WDT_BASE,
 	[RSET_UART0]		= BCM_6358_UART0_BASE,
+	[RSET_UART1]		= BCM_6358_UART1_BASE,
 	[RSET_GPIO]		= BCM_6358_GPIO_BASE,
 	[RSET_SPI]		= BCM_6358_SPI_BASE,
 	[RSET_OHCI0]		= BCM_6358_OHCI0_BASE,
@@ -170,6 +174,7 @@
 static const int bcm96358_irqs[] = {
 	[IRQ_TIMER]		= BCM_6358_TIMER_IRQ,
 	[IRQ_UART0]		= BCM_6358_UART0_IRQ,
+	[IRQ_UART1]		= BCM_6358_UART1_IRQ,
 	[IRQ_DSL]		= BCM_6358_DSL_IRQ,
 	[IRQ_ENET0]		= BCM_6358_ENET0_IRQ,
 	[IRQ_ENET1]		= BCM_6358_ENET1_IRQ,
diff --git a/arch/mips/bcm63xx/dev-uart.c b/arch/mips/bcm63xx/dev-uart.c
index b051946..c2963da 100644
--- a/arch/mips/bcm63xx/dev-uart.c
+++ b/arch/mips/bcm63xx/dev-uart.c
@@ -11,31 +11,65 @@
 #include <linux/platform_device.h>
 #include <bcm63xx_cpu.h>
 
-static struct resource uart_resources[] = {
+static struct resource uart0_resources[] = {
 	{
-		.start		= -1, /* filled at runtime */
-		.end		= -1, /* filled at runtime */
+		/* start & end filled at runtime */
 		.flags		= IORESOURCE_MEM,
 	},
 	{
-		.start		= -1, /* filled at runtime */
+		/* start filled at runtime */
 		.flags		= IORESOURCE_IRQ,
 	},
 };
 
-static struct platform_device bcm63xx_uart_device = {
-	.name		= "bcm63xx_uart",
-	.id		= 0,
-	.num_resources	= ARRAY_SIZE(uart_resources),
-	.resource	= uart_resources,
+static struct resource uart1_resources[] = {
+	{
+		/* start & end filled at runtime */
+		.flags		= IORESOURCE_MEM,
+	},
+	{
+		/* start filled at runtime */
+		.flags		= IORESOURCE_IRQ,
+	},
 };
 
-int __init bcm63xx_uart_register(void)
+static struct platform_device bcm63xx_uart_devices[] = {
+	{
+		.name		= "bcm63xx_uart",
+		.id		= 0,
+		.num_resources	= ARRAY_SIZE(uart0_resources),
+		.resource	= uart0_resources,
+	},
+
+	{
+		.name		= "bcm63xx_uart",
+		.id		= 1,
+		.num_resources	= ARRAY_SIZE(uart1_resources),
+		.resource	= uart1_resources,
+	}
+};
+
+int __init bcm63xx_uart_register(unsigned int id)
 {
-	uart_resources[0].start = bcm63xx_regset_address(RSET_UART0);
-	uart_resources[0].end = uart_resources[0].start;
-	uart_resources[0].end += RSET_UART_SIZE - 1;
-	uart_resources[1].start = bcm63xx_get_irq_number(IRQ_UART0);
-	return platform_device_register(&bcm63xx_uart_device);
+	if (id >= ARRAY_SIZE(bcm63xx_uart_devices))
+		return -ENODEV;
+
+	if (id == 1 && !BCMCPU_IS_6358())
+		return -ENODEV;
+
+	if (id == 0) {
+		uart0_resources[0].start = bcm63xx_regset_address(RSET_UART0);
+		uart0_resources[0].end = uart0_resources[0].start +
+			RSET_UART_SIZE - 1;
+		uart0_resources[1].start = bcm63xx_get_irq_number(IRQ_UART0);
+	}
+
+	if (id == 1) {
+		uart1_resources[0].start = bcm63xx_regset_address(RSET_UART1);
+		uart1_resources[0].end = uart1_resources[0].start +
+			RSET_UART_SIZE - 1;
+		uart1_resources[1].start = bcm63xx_get_irq_number(IRQ_UART1);
+	}
+
+	return platform_device_register(&bcm63xx_uart_devices[id]);
 }
-arch_initcall(bcm63xx_uart_register);