#include <asm/mach/map.h>
 
 #include <asm/arch/regs-gpio.h>
+#include <asm/arch/regs-serial.h>
 
 #include "cpu.h"
+#include "devs.h"
 #include "clock.h"
 #include "s3c2400.h"
 #include "s3c2410.h"
                (cpu->init_clocks)(xtal);
 }
 
+/* uart management */
+
+static int nr_uarts __initdata = 0;
+
+static struct s3c2410_uartcfg uart_cfgs[3];
+
+/* s3c24xx_init_uartdevs
+ *
+ * copy the specified platform data and configuration into our central
+ * set of devices, before the data is thrown away after the init process.
+ *
+ * This also fills in the array passed to the serial driver for the
+ * early initialisation of the console.
+*/
+
+void __init s3c24xx_init_uartdevs(char *name,
+                                 struct s3c24xx_uart_resources *res,
+                                 struct s3c2410_uartcfg *cfg, int no)
+{
+       struct platform_device *platdev;
+       struct s3c2410_uartcfg *cfgptr = uart_cfgs;
+       struct s3c24xx_uart_resources *resp;
+       int uart;
+
+       memcpy(cfgptr, cfg, sizeof(struct s3c2410_uartcfg) * no);
+
+       for (uart = 0; uart < no; uart++, cfg++, cfgptr++) {
+               platdev = s3c24xx_uart_src[cfgptr->hwport];
+
+               resp = res + cfgptr->hwport;
+
+               s3c24xx_uart_devs[uart] = platdev;
+
+               platdev->name = name;
+               platdev->resource = resp->resources;
+               platdev->num_resources = resp->nr_resources;
+
+               platdev->dev.platform_data = cfgptr;
+       }
+
+       nr_uarts = no;
+}
+
 void __init s3c24xx_init_uarts(struct s3c2410_uartcfg *cfg, int no)
 {
        if (cpu == NULL)
        if (ret != 0)
                return ret;
 
+       ret = platform_add_devices(s3c24xx_uart_devs, nr_uarts);
+       if (ret != 0)
+               return ret;
+
        if (board != NULL) {
                struct platform_device **ptr = board->devices;
                int i;
 
 #define print_mhz(m) ((m) / MHZ), ((m / 1000) % 1000)
 
 /* forward declaration */
+struct s3c24xx_uart_resources;
+struct platform_device;
 struct s3c2410_uartcfg;
 struct map_desc;
 
 
 extern void s3c24xx_init_clocks(int xtal);
 
+extern void s3c24xx_init_uartdevs(char *name,
+                                 struct s3c24xx_uart_resources *res,
+                                 struct s3c2410_uartcfg *cfg, int no);
+
 /* the board structure is used at first initialsation time
  * to get info such as the devices to register for this
  * board. This is done because platfrom_add_devices() cannot
 
 #include <asm/arch/regs-serial.h>
 
 #include "devs.h"
+#include "cpu.h"
 
 /* Serial port registrations */
 
-struct platform_device *s3c24xx_uart_devs[3];
+static struct resource s3c2410_uart0_resource[] = {
+       [0] = {
+               .start = S3C2410_PA_UART0,
+               .end   = S3C2410_PA_UART0 + 0x3fff,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = IRQ_S3CUART_RX0,
+               .end   = IRQ_S3CUART_ERR0,
+               .flags = IORESOURCE_IRQ,
+       }
+};
+
+static struct resource s3c2410_uart1_resource[] = {
+       [0] = {
+               .start = S3C2410_PA_UART1,
+               .end   = S3C2410_PA_UART1 + 0x3fff,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = IRQ_S3CUART_RX1,
+               .end   = IRQ_S3CUART_ERR1,
+               .flags = IORESOURCE_IRQ,
+       }
+};
+
+static struct resource s3c2410_uart2_resource[] = {
+       [0] = {
+               .start = S3C2410_PA_UART2,
+               .end   = S3C2410_PA_UART2 + 0x3fff,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = IRQ_S3CUART_RX2,
+               .end   = IRQ_S3CUART_ERR2,
+               .flags = IORESOURCE_IRQ,
+       }
+};
+
+struct s3c24xx_uart_resources s3c2410_uart_resources[] __initdata = {
+       [0] = {
+               .resources      = s3c2410_uart0_resource,
+               .nr_resources   = ARRAY_SIZE(s3c2410_uart0_resource),
+       },
+       [1] = {
+               .resources      = s3c2410_uart1_resource,
+               .nr_resources   = ARRAY_SIZE(s3c2410_uart1_resource),
+       },
+       [2] = {
+               .resources      = s3c2410_uart2_resource,
+               .nr_resources   = ARRAY_SIZE(s3c2410_uart2_resource),
+       },
+};
+
+/* yart devices */
+
+static struct platform_device s3c24xx_uart_device0 = {
+       .id             = 0,
+};
+
+static struct platform_device s3c24xx_uart_device1 = {
+       .id             = 1,
+};
+
+static struct platform_device s3c24xx_uart_device2 = {
+       .id             = 2,
+};
+
+struct platform_device *s3c24xx_uart_src[3] = {
+       &s3c24xx_uart_device0,
+       &s3c24xx_uart_device1,
+       &s3c24xx_uart_device2,
+};
+
+struct platform_device *s3c24xx_uart_devs[3] = {
+};
 
 /* USB Host Controller */
 
 
 #include <linux/config.h>
 #include <linux/platform_device.h>
 
+struct s3c24xx_uart_resources {
+       struct resource         *resources;
+       unsigned long            nr_resources;
+};
+
+extern struct s3c24xx_uart_resources s3c2410_uart_resources[];
+
 extern struct platform_device *s3c24xx_uart_devs[];
+extern struct platform_device *s3c24xx_uart_src[];
 
 extern struct platform_device s3c_device_usb;
 extern struct platform_device s3c_device_lcd;
 
 };
 
 
-static struct s3c2410_uartcfg anubis_uartcfgs[] = {
+static struct s3c2410_uartcfg anubis_uartcfgs[] __initdata = {
        [0] = {
                .hwport      = 0,
                .flags       = 0,
 
 };
 
 
-static struct s3c2410_uartcfg bast_uartcfgs[] = {
+static struct s3c2410_uartcfg bast_uartcfgs[] __initdata = {
        [0] = {
                .hwport      = 0,
                .flags       = 0,
 
 #define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
 #define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
 
-static struct s3c2410_uartcfg h1940_uartcfgs[] = {
+static struct s3c2410_uartcfg h1940_uartcfgs[] __initdata = {
        [0] = {
                .hwport      = 0,
                .flags       = 0,
 
 #define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
 #define UFCON S3C2410_UFCON_RXTRIG12 | S3C2410_UFCON_FIFOMODE
 
-static struct s3c2410_uartcfg nexcoder_uartcfgs[] = {
+static struct s3c2410_uartcfg nexcoder_uartcfgs[] __initdata = {
        [0] = {
                .hwport      = 0,
                .flags       = 0,
 
        }
 };
 
-
-static struct s3c2410_uartcfg osiris_uartcfgs[] = {
+static struct s3c2410_uartcfg osiris_uartcfgs[] __initdata = {
        [0] = {
                .hwport      = 0,
                .flags       = 0,
 
 #define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
 #define UFCON S3C2410_UFCON_RXTRIG12 | S3C2410_UFCON_FIFOMODE
 
-static struct s3c2410_uartcfg otom11_uartcfgs[] = {
+static struct s3c2410_uartcfg otom11_uartcfgs[] __initdata = {
        [0] = {
                .hwport      = 0,
                .flags       = 0,
 
 #define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
 #define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
 
-static struct s3c2410_uartcfg smdk2410_uartcfgs[] = {
+static struct s3c2410_uartcfg smdk2410_uartcfgs[] __initdata = {
        [0] = {
                .hwport      = 0,
                .flags       = 0,
 
 #define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
 #define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
 
-static struct s3c2410_uartcfg smdk2440_uartcfgs[] = {
+static struct s3c2410_uartcfg smdk2440_uartcfgs[] __initdata = {
        [0] = {
                .hwport      = 0,
                .flags       = 0,
 
        }
 };
 
-static struct s3c2410_uartcfg vr1000_uartcfgs[] = {
+static struct s3c2410_uartcfg vr1000_uartcfgs[] __initdata = {
        [0] = {
                .hwport      = 0,
                .flags       = 0,
 
 
 #include "s3c2410.h"
 #include "cpu.h"
+#include "devs.h"
 #include "clock.h"
 
 /* Initial IO mappings */
        IODESC_ENT(WATCHDOG),
 };
 
-static struct resource s3c_uart0_resource[] = {
-       [0] = {
-               .start = S3C2410_PA_UART0,
-               .end   = S3C2410_PA_UART0 + 0x3fff,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_S3CUART_RX0,
-               .end   = IRQ_S3CUART_ERR0,
-               .flags = IORESOURCE_IRQ,
-       }
-
-};
-
-static struct resource s3c_uart1_resource[] = {
-       [0] = {
-               .start = S3C2410_PA_UART1,
-               .end   = S3C2410_PA_UART1 + 0x3fff,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_S3CUART_RX1,
-               .end   = IRQ_S3CUART_ERR1,
-               .flags = IORESOURCE_IRQ,
-       }
-};
-
-static struct resource s3c_uart2_resource[] = {
-       [0] = {
-               .start = S3C2410_PA_UART2,
-               .end   = S3C2410_PA_UART2 + 0x3fff,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_S3CUART_RX2,
-               .end   = IRQ_S3CUART_ERR2,
-               .flags = IORESOURCE_IRQ,
-       }
-};
-
 /* our uart devices */
 
-static struct platform_device s3c_uart0 = {
-       .name             = "s3c2410-uart",
-       .id               = 0,
-       .num_resources    = ARRAY_SIZE(s3c_uart0_resource),
-       .resource         = s3c_uart0_resource,
-};
-
-
-static struct platform_device s3c_uart1 = {
-       .name             = "s3c2410-uart",
-       .id               = 1,
-       .num_resources    = ARRAY_SIZE(s3c_uart1_resource),
-       .resource         = s3c_uart1_resource,
-};
-
-static struct platform_device s3c_uart2 = {
-       .name             = "s3c2410-uart",
-       .id               = 2,
-       .num_resources    = ARRAY_SIZE(s3c_uart2_resource),
-       .resource         = s3c_uart2_resource,
-};
-
-static struct platform_device *uart_devices[] __initdata = {
-       &s3c_uart0,
-       &s3c_uart1,
-       &s3c_uart2
-};
-
-static int s3c2410_uart_count = 0;
-
 /* uart registration process */
 
 void __init s3c2410_init_uarts(struct s3c2410_uartcfg *cfg, int no)
 {
-       struct platform_device *platdev;
-       int uart;
-
-       for (uart = 0; uart < no; uart++, cfg++) {
-               platdev = uart_devices[cfg->hwport];
-
-               s3c24xx_uart_devs[uart] = platdev;
-               platdev->dev.platform_data = cfg;
-       }
-
-       s3c2410_uart_count = uart;
+       s3c24xx_init_uartdevs("s3c2410-uart", s3c2410_uart_resources, cfg, no);
 }
 
 /* s3c2410_map_io
 {
        printk("S3C2410: Initialising architecture\n");
 
-       return platform_add_devices(s3c24xx_uart_devs, s3c2410_uart_count);
+       return 0;
 }
 
        IODESC_ENT(WATCHDOG),
 };
 
-static struct resource s3c_uart0_resource[] = {
-       [0] = {
-               .start = S3C2410_PA_UART0,
-               .end   = S3C2410_PA_UART0 + 0x3fff,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_S3CUART_RX0,
-               .end   = IRQ_S3CUART_ERR0,
-               .flags = IORESOURCE_IRQ,
-       }
-
-};
-
-static struct resource s3c_uart1_resource[] = {
-       [0] = {
-               .start = S3C2410_PA_UART1,
-               .end   = S3C2410_PA_UART1 + 0x3fff,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_S3CUART_RX1,
-               .end   = IRQ_S3CUART_ERR1,
-               .flags = IORESOURCE_IRQ,
-       }
-};
-
-static struct resource s3c_uart2_resource[] = {
-       [0] = {
-               .start = S3C2410_PA_UART2,
-               .end   = S3C2410_PA_UART2 + 0x3fff,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_S3CUART_RX2,
-               .end   = IRQ_S3CUART_ERR2,
-               .flags = IORESOURCE_IRQ,
-       }
-};
-
-/* our uart devices */
-
-static struct platform_device s3c_uart0 = {
-       .name             = "s3c2440-uart",
-       .id               = 0,
-       .num_resources    = ARRAY_SIZE(s3c_uart0_resource),
-       .resource         = s3c_uart0_resource,
-};
-
-static struct platform_device s3c_uart1 = {
-       .name             = "s3c2440-uart",
-       .id               = 1,
-       .num_resources    = ARRAY_SIZE(s3c_uart1_resource),
-       .resource         = s3c_uart1_resource,
-};
-
-static struct platform_device s3c_uart2 = {
-       .name             = "s3c2440-uart",
-       .id               = 2,
-       .num_resources    = ARRAY_SIZE(s3c_uart2_resource),
-       .resource         = s3c_uart2_resource,
-};
-
-static struct platform_device *uart_devices[] __initdata = {
-       &s3c_uart0,
-       &s3c_uart1,
-       &s3c_uart2
-};
-
 /* uart initialisation */
 
-static int __initdata s3c2440_uart_count;
-
 void __init s3c2440_init_uarts(struct s3c2410_uartcfg *cfg, int no)
 {
-       struct platform_device *platdev;
-       int uart;
-
-       for (uart = 0; uart < no; uart++, cfg++) {
-               platdev = uart_devices[cfg->hwport];
-
-               s3c24xx_uart_devs[uart] = platdev;
-               platdev->dev.platform_data = cfg;
-       }
-
-       s3c2440_uart_count = uart;
+       s3c24xx_init_uartdevs("s3c2440-uart", s3c2410_uart_resources, cfg, no);
 }
 
-
 #ifdef CONFIG_PM
 
 static struct sleep_save s3c2440_sleep[] = {
 
 int __init s3c2440_init(void)
 {
-       int ret;
-
        printk("S3C2440: Initialising architecture\n");
 
-       ret = sysdev_register(&s3c2440_sysdev);
-       if (ret != 0)
-               printk(KERN_ERR "failed to register sysdev for s3c2440\n");
-       else
-               ret = platform_add_devices(s3c24xx_uart_devs, s3c2440_uart_count);
-
-       return ret;
+       return sysdev_register(&s3c2440_sysdev);
 }