From: Mark A. Greer <mgr...@mvista.com>

Currently, there is one set of platform_device and platform_data
structures for all DaVinci SoCs.  The differences in the data
between the various SoCs is handled by davinci_serial_init()
by checking the SoC type.  However, as new SoCs appear, this
routine will become more & more cluttered.

To clean up the routine and make it easier to add support for new
SoCs, move the platform_device and platform_data structures into the
SoC-specific code and use the SoC infrastructure to provide access
to the data.

In the process, fix a bug where the wrong irq is used for uart2
of the dm646x.

Signed-off-by: Mark A. Greer <mgr...@mvista.com>
---
 arch/arm/mach-davinci/dm355.c               |   41 +++++++++++++++++
 arch/arm/mach-davinci/dm644x.c              |   41 +++++++++++++++++
 arch/arm/mach-davinci/dm646x.c              |   41 +++++++++++++++++
 arch/arm/mach-davinci/include/mach/common.h |    1 +
 arch/arm/mach-davinci/include/mach/serial.h |    2 +-
 arch/arm/mach-davinci/serial.c              |   66 +++-----------------------
 6 files changed, 133 insertions(+), 59 deletions(-)

diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c
index 11132f2..83c455e 100644
--- a/arch/arm/mach-davinci/dm355.c
+++ b/arch/arm/mach-davinci/dm355.c
@@ -11,6 +11,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/clk.h>
+#include <linux/serial_8250.h>
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
 
@@ -27,6 +28,7 @@
 #include <mach/irqs.h>
 #include <mach/time.h>
 #include <mach/gpio.h>
+#include <mach/serial.h>
 #include <mach/common.h>
 
 #include "clock.h"
@@ -630,6 +632,44 @@ struct davinci_timer_info dm355_timer_info = {
        .clocksource_id = T0_TOP,
 };
 
+static struct plat_serial8250_port dm355_serial_platform_data[] = {
+       {
+               .mapbase        = DAVINCI_UART0_BASE,
+               .irq            = IRQ_UARTINT0,
+               .flags          = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+                                 UPF_IOREMAP,
+               .iotype         = UPIO_MEM,
+               .regshift       = 2,
+       },
+       {
+               .mapbase        = DAVINCI_UART1_BASE,
+               .irq            = IRQ_UARTINT1,
+               .flags          = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+                                 UPF_IOREMAP,
+               .iotype         = UPIO_MEM,
+               .regshift       = 2,
+       },
+       {
+               .mapbase        = DM355_UART2_BASE,
+               .irq            = IRQ_DM355_UARTINT2,
+               .flags          = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+                                 UPF_IOREMAP,
+               .iotype         = UPIO_MEM,
+               .regshift       = 2,
+       },
+       {
+               .flags          = 0
+       },
+};
+
+static struct platform_device dm355_serial_device = {
+       .name                   = "serial8250",
+       .id                     = PLAT8250_DEV_PLATFORM,
+       .dev                    = {
+               .platform_data  = dm355_serial_platform_data,
+       },
+};
+
 static struct davinci_soc_info davinci_soc_info_dm355 = {
        .io_desc                = dm355_io_desc,
        .io_desc_num            = ARRAY_SIZE(dm355_io_desc),
@@ -651,6 +691,7 @@ static struct davinci_soc_info davinci_soc_info_dm355 = {
        .gpio_base              = IO_ADDRESS(DAVINCI_GPIO_BASE),
        .gpio_num               = 104,
        .gpio_irq               = IRQ_DM355_GPIOBNK0,
+       .serial_dev             = &dm355_serial_device,
 };
 
 void __init dm355_init(void)
diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c
index da75f19..23f5638 100644
--- a/arch/arm/mach-davinci/dm644x.c
+++ b/arch/arm/mach-davinci/dm644x.c
@@ -11,6 +11,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/clk.h>
+#include <linux/serial_8250.h>
 #include <linux/platform_device.h>
 
 #include <asm/mach/map.h>
@@ -24,6 +25,7 @@
 #include <mach/mux.h>
 #include <mach/time.h>
 #include <mach/gpio.h>
+#include <mach/serial.h>
 #include <mach/common.h>
 
 #include "clock.h"
@@ -573,6 +575,44 @@ struct davinci_timer_info dm644x_timer_info = {
        .clocksource_id = T0_TOP,
 };
 
+static struct plat_serial8250_port dm644x_serial_platform_data[] = {
+       {
+               .mapbase        = DAVINCI_UART0_BASE,
+               .irq            = IRQ_UARTINT0,
+               .flags          = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+                                 UPF_IOREMAP,
+               .iotype         = UPIO_MEM,
+               .regshift       = 2,
+       },
+       {
+               .mapbase        = DAVINCI_UART1_BASE,
+               .irq            = IRQ_UARTINT1,
+               .flags          = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+                                 UPF_IOREMAP,
+               .iotype         = UPIO_MEM,
+               .regshift       = 2,
+       },
+       {
+               .mapbase        = DAVINCI_UART2_BASE,
+               .irq            = IRQ_UARTINT2,
+               .flags          = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+                                 UPF_IOREMAP,
+               .iotype         = UPIO_MEM,
+               .regshift       = 2,
+       },
+       {
+               .flags          = 0
+       },
+};
+
+static struct platform_device dm644x_serial_device = {
+       .name                   = "serial8250",
+       .id                     = PLAT8250_DEV_PLATFORM,
+       .dev                    = {
+               .platform_data  = dm644x_serial_platform_data,
+       },
+};
+
 static struct davinci_soc_info davinci_soc_info_dm644x = {
        .io_desc                = dm644x_io_desc,
        .io_desc_num            = ARRAY_SIZE(dm644x_io_desc),
@@ -594,6 +634,7 @@ static struct davinci_soc_info davinci_soc_info_dm644x = {
        .gpio_base              = IO_ADDRESS(DAVINCI_GPIO_BASE),
        .gpio_num               = 71,
        .gpio_irq               = IRQ_GPIOBNK0,
+       .serial_dev             = &dm644x_serial_device,
 };
 
 void __init dm644x_init(void)
diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c
index 41951d5..a18e7e3 100644
--- a/arch/arm/mach-davinci/dm646x.c
+++ b/arch/arm/mach-davinci/dm646x.c
@@ -11,6 +11,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/clk.h>
+#include <linux/serial_8250.h>
 #include <linux/platform_device.h>
 
 #include <asm/mach/map.h>
@@ -24,6 +25,7 @@
 #include <mach/mux.h>
 #include <mach/time.h>
 #include <mach/gpio.h>
+#include <mach/serial.h>
 #include <mach/common.h>
 
 #include "clock.h"
@@ -552,6 +554,44 @@ struct davinci_timer_info dm646x_timer_info = {
        .clocksource_id = T0_TOP,
 };
 
+static struct plat_serial8250_port dm646x_serial_platform_data[] = {
+       {
+               .mapbase        = DAVINCI_UART0_BASE,
+               .irq            = IRQ_UARTINT0,
+               .flags          = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+                                 UPF_IOREMAP,
+               .iotype         = UPIO_MEM32,
+               .regshift       = 2,
+       },
+       {
+               .mapbase        = DAVINCI_UART1_BASE,
+               .irq            = IRQ_UARTINT1,
+               .flags          = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+                                 UPF_IOREMAP,
+               .iotype         = UPIO_MEM32,
+               .regshift       = 2,
+       },
+       {
+               .mapbase        = DAVINCI_UART2_BASE,
+               .irq            = IRQ_DM646X_UARTINT2,
+               .flags          = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+                                 UPF_IOREMAP,
+               .iotype         = UPIO_MEM32,
+               .regshift       = 2,
+       },
+       {
+               .flags          = 0
+       },
+};
+
+static struct platform_device dm646x_serial_device = {
+       .name                   = "serial8250",
+       .id                     = PLAT8250_DEV_PLATFORM,
+       .dev                    = {
+               .platform_data  = dm646x_serial_platform_data,
+       },
+};
+
 static struct davinci_soc_info davinci_soc_info_dm646x = {
        .io_desc                = dm646x_io_desc,
        .io_desc_num            = ARRAY_SIZE(dm646x_io_desc),
@@ -573,6 +613,7 @@ static struct davinci_soc_info davinci_soc_info_dm646x = {
        .gpio_base              = IO_ADDRESS(DAVINCI_GPIO_BASE),
        .gpio_num               = 43, /* Only 33 usable */
        .gpio_irq               = IRQ_DM646X_GPIOBNK0,
+       .serial_dev             = &dm646x_serial_device,
 };
 
 void __init dm646x_init(void)
diff --git a/arch/arm/mach-davinci/include/mach/common.h 
b/arch/arm/mach-davinci/include/mach/common.h
index 6810bc8..7c75557 100644
--- a/arch/arm/mach-davinci/include/mach/common.h
+++ b/arch/arm/mach-davinci/include/mach/common.h
@@ -61,6 +61,7 @@ struct davinci_soc_info {
        void __iomem                    *gpio_base;
        unsigned                        gpio_num;
        unsigned                        gpio_irq;
+       struct platform_device          *serial_dev;
 };
 
 extern struct davinci_soc_info *davinci_get_soc_info(void);
diff --git a/arch/arm/mach-davinci/include/mach/serial.h 
b/arch/arm/mach-davinci/include/mach/serial.h
index 632847d..a59b7de 100644
--- a/arch/arm/mach-davinci/include/mach/serial.h
+++ b/arch/arm/mach-davinci/include/mach/serial.h
@@ -30,6 +30,6 @@ struct davinci_uart_config {
        unsigned int enabled_uarts;
 };
 
-extern void davinci_serial_init(struct davinci_uart_config *);
+extern int davinci_serial_init(struct davinci_uart_config *);
 
 #endif /* __ASM_ARCH_SERIAL_H */
diff --git a/arch/arm/mach-davinci/serial.c b/arch/arm/mach-davinci/serial.c
index 99102ac..15769d4 100644
--- a/arch/arm/mach-davinci/serial.c
+++ b/arch/arm/mach-davinci/serial.c
@@ -33,6 +33,8 @@
 #include <mach/serial.h>
 #include <mach/irqs.h>
 #include <mach/cpu.h>
+#include <mach/common.h>
+
 #include "clock.h"
 
 static inline unsigned int serial_read_reg(struct plat_serial8250_port *up,
@@ -49,32 +51,6 @@ static inline void serial_write_reg(struct 
plat_serial8250_port *p, int offset,
        __raw_writel(value, IO_ADDRESS(p->mapbase) + offset);
 }
 
-static const resource_size_t serial_mapbase[] = {
-       DAVINCI_UART0_BASE,
-       DAVINCI_UART1_BASE,
-       DAVINCI_UART2_BASE,
-};
-
-static const unsigned int serial_irq[] = {
-       IRQ_UARTINT0,
-       IRQ_UARTINT1,
-       IRQ_UARTINT2,
-};
-
-/*
- * The additional entry is present because the list must be terminated with a
- * zero flags entry.
- */
-static struct plat_serial8250_port serial_platform_data[DAVINCI_MAX_NR_UARTS + 
1];
-
-static struct platform_device serial_device = {
-       .name                   = "serial8250",
-       .id                     = PLAT8250_DEV_PLATFORM,
-       .dev                    = {
-               .platform_data  = serial_platform_data,
-       },
-};
-
 static void __init davinci_serial_reset(struct plat_serial8250_port *p)
 {
        unsigned int pwremu = 0;
@@ -94,39 +70,23 @@ static void __init davinci_serial_reset(struct 
plat_serial8250_port *p)
                                 UART_DM646X_SCR_TX_WATERMARK);
 }
 
-void __init davinci_serial_init(struct davinci_uart_config *info)
+int __init davinci_serial_init(struct davinci_uart_config *info)
 {
        int i;
        char name[16];
        struct clk *uart_clk;
-       struct device *dev = &serial_device.dev;
-       struct plat_serial8250_port *p = serial_platform_data;
+       struct davinci_soc_info *soc_info = davinci_get_soc_info();
+       struct device *dev = &soc_info->serial_dev->dev;
+       struct plat_serial8250_port *p = dev->platform_data;
 
        /*
         * Make sure the serial ports are muxed on at this point.
         * You have to mux them off in device drivers later on if not needed.
         */
-       for (i = 0; i < DAVINCI_MAX_NR_UARTS; i++) {
+       for (i = 0; i < DAVINCI_MAX_NR_UARTS; i++, p++) {
                if (!(info->enabled_uarts & (1 << i)))
                        continue;
 
-               /* fill-in common members */
-               p->flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP;
-               p->regshift = 2;
-
-               if (cpu_is_davinci_dm646x())
-                       p->iotype = UPIO_MEM32;
-               else
-                       p->iotype = UPIO_MEM;
-
-               if (cpu_is_davinci_dm355() && (i == 2)) {
-                       p->mapbase = DM355_UART2_BASE;
-                       p->irq = IRQ_DM355_UARTINT2;
-               } else {
-                       p->mapbase = serial_mapbase[i];
-                       p->irq = serial_irq[i];
-               }
-
                sprintf(name, "uart%d", i);
                uart_clk = clk_get(dev, name);
                p->uartclk = clk_get_rate(uart_clk);
@@ -137,17 +97,7 @@ void __init davinci_serial_init(struct davinci_uart_config 
*info)
                        clk_enable(uart_clk);
                        davinci_serial_reset(p);
                }
-
-               p++; /* Point to next entry */
        }
 
-       /* Terminate the list with a zero flags entry */
-       p->flags = 0;
+       return platform_device_register(soc_info->serial_dev);
 }
-
-static int __init davinci_init(void)
-{
-       return platform_device_register(&serial_device);
-}
-
-arch_initcall(davinci_init);
-- 
1.6.0.3


_______________________________________________
Davinci-linux-open-source mailing list
Davinci-linux-open-source@linux.davincidsp.com
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source

Reply via email to