ns9xxx: move registration of serial8250 to a dedicated file

Now the needed structs are allocated dynamically from __init code reducing
memory usage if the kernel runs on a board different from a9m9750dev.

Signed-off-by: Uwe Kleine-König <Uwe.Kleine-Koenig@digi.com>
diff --git a/arch/arm/mach-ns9xxx/Kconfig b/arch/arm/mach-ns9xxx/Kconfig
index 8584ed1..83c0efa 100644
--- a/arch/arm/mach-ns9xxx/Kconfig
+++ b/arch/arm/mach-ns9xxx/Kconfig
@@ -2,6 +2,9 @@
 
 menu "NS9xxx Implementations"
 
+config NS9XXX_HAVE_SERIAL8250
+	bool
+
 config MACH_CC9P9360DEV
 	bool "ConnectCore 9P 9360 on an A9M9750 Devboard"
 	select PROCESSOR_NS9360
@@ -23,6 +26,7 @@
 
 config BOARD_A9M9750DEV
 	bool
+	select NS9XXX_HAVE_SERIAL8250
 
 config BOARD_JSCC9P9360
 	bool
diff --git a/arch/arm/mach-ns9xxx/Makefile b/arch/arm/mach-ns9xxx/Makefile
index 6fb82b8..ca2c68d 100644
--- a/arch/arm/mach-ns9xxx/Makefile
+++ b/arch/arm/mach-ns9xxx/Makefile
@@ -5,3 +5,6 @@
 
 obj-$(CONFIG_BOARD_A9M9750DEV) += board-a9m9750dev.o
 obj-$(CONFIG_BOARD_JSCC9P9360) += board-jscc9p9360.o
+
+# platform devices
+obj-$(CONFIG_NS9XXX_HAVE_SERIAL8250) += plat-serial8250.o
diff --git a/arch/arm/mach-ns9xxx/board-a9m9750dev.c b/arch/arm/mach-ns9xxx/board-a9m9750dev.c
index 0f65177..14a06da 100644
--- a/arch/arm/mach-ns9xxx/board-a9m9750dev.c
+++ b/arch/arm/mach-ns9xxx/board-a9m9750dev.c
@@ -8,8 +8,6 @@
  * under the terms of the GNU General Public License version 2 as published by
  * the Free Software Foundation.
  */
-#include <linux/platform_device.h>
-#include <linux/serial_8250.h>
 #include <linux/irq.h>
 
 #include <asm/mach/map.h>
@@ -126,59 +124,6 @@
 			a9m9750dev_fpga_demux_handler);
 }
 
-static struct plat_serial8250_port board_a9m9750dev_serial8250_port[] = {
-	{
-		.iobase         = FPGA_UARTA_BASE,
-		.membase        = (unsigned char*)FPGA_UARTA_BASE,
-		.mapbase        = FPGA_UARTA_BASE,
-		.irq            = IRQ_FPGA_UARTA,
-		.iotype         = UPIO_MEM,
-		.uartclk        = 18432000,
-		.regshift       = 0,
-		.flags          = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ,
-	}, {
-		.iobase         = FPGA_UARTB_BASE,
-		.membase        = (unsigned char*)FPGA_UARTB_BASE,
-		.mapbase        = FPGA_UARTB_BASE,
-		.irq            = IRQ_FPGA_UARTB,
-		.iotype         = UPIO_MEM,
-		.uartclk        = 18432000,
-		.regshift       = 0,
-		.flags          = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ,
-	}, {
-		.iobase         = FPGA_UARTC_BASE,
-		.membase        = (unsigned char*)FPGA_UARTC_BASE,
-		.mapbase        = FPGA_UARTC_BASE,
-		.irq            = IRQ_FPGA_UARTC,
-		.iotype         = UPIO_MEM,
-		.uartclk        = 18432000,
-		.regshift       = 0,
-		.flags          = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ,
-	}, {
-		.iobase         = FPGA_UARTD_BASE,
-		.membase        = (unsigned char*)FPGA_UARTD_BASE,
-		.mapbase        = FPGA_UARTD_BASE,
-		.irq            = IRQ_FPGA_UARTD,
-		.iotype         = UPIO_MEM,
-		.uartclk        = 18432000,
-		.regshift       = 0,
-		.flags          = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ,
-	}, {
-		/* end marker */
-	},
-};
-
-static struct platform_device board_a9m9750dev_serial_device = {
-	.name = "serial8250",
-	.dev = {
-		.platform_data = board_a9m9750dev_serial8250_port,
-	},
-};
-
-static struct platform_device *board_a9m9750dev_devices[] __initdata = {
-	&board_a9m9750dev_serial_device,
-};
-
 void __init board_a9m9750dev_init_machine(void)
 {
 	u32 reg;
@@ -210,7 +155,4 @@
 	__raw_writel(0x2, MEM_SMOED(0));
 	__raw_writel(0x6, MEM_SMRD(0));
 	__raw_writel(0x6, MEM_SMWD(0));
-
-	platform_add_devices(board_a9m9750dev_devices,
-			ARRAY_SIZE(board_a9m9750dev_devices));
 }
diff --git a/arch/arm/mach-ns9xxx/plat-serial8250.c b/arch/arm/mach-ns9xxx/plat-serial8250.c
new file mode 100644
index 0000000..5aa5d9b
--- /dev/null
+++ b/arch/arm/mach-ns9xxx/plat-serial8250.c
@@ -0,0 +1,69 @@
+/*
+ * arch/arm/mach-ns9xxx/plat-serial8250.c
+ *
+ * Copyright (C) 2008 by Digi International Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+
+#include <asm/arch-ns9xxx/regs-board-a9m9750dev.h>
+#include <asm/arch-ns9xxx/board.h>
+
+#define DRIVER_NAME "serial8250"
+
+static int __init ns9xxx_plat_serial8250_init(void)
+{
+	struct plat_serial8250_port *pdata;
+	struct platform_device *pdev;
+	int ret = -ENOMEM;
+	int i;
+
+	if (!board_is_a9m9750dev())
+		return -ENODEV;
+
+	pdev = platform_device_alloc(DRIVER_NAME, 0);
+	if (!pdev)
+		goto err;
+
+	pdata = kzalloc(5 * sizeof(*pdata), GFP_KERNEL);
+	if (!pdata)
+		goto err;
+
+	pdev->dev.platform_data = pdata;
+
+	pdata[0].iobase = FPGA_UARTA_BASE;
+	pdata[1].iobase = FPGA_UARTB_BASE;
+	pdata[2].iobase = FPGA_UARTC_BASE;
+	pdata[3].iobase = FPGA_UARTD_BASE;
+
+	for (i = 0; i < 4; ++i) {
+		pdata[i].membase = (void __iomem *)pdata[i].iobase;
+		pdata[i].mapbase = pdata[i].iobase;
+		pdata[i].iotype = UPIO_MEM;
+		pdata[i].uartclk = 18432000;
+		pdata[i].flags = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ;
+	}
+
+	pdata[0].irq = IRQ_FPGA_UARTA;
+	pdata[1].irq = IRQ_FPGA_UARTB;
+	pdata[2].irq = IRQ_FPGA_UARTC;
+	pdata[3].irq = IRQ_FPGA_UARTD;
+
+	ret = platform_device_add(pdev);
+	if (ret) {
+err:
+		platform_device_put(pdev);
+
+		printk(KERN_WARNING "Could not add %s (errno=%d)\n",
+				DRIVER_NAME, ret);
+	}
+
+	return 0;
+}
+
+arch_initcall(ns9xxx_plat_serial8250_init);