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