Commit b63c592f authored by Mark A. Greer's avatar Mark A. Greer Committed by Kevin Hilman

davinci: Move serial platform_device into SoC-specific files

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: default avatarMark A. Greer <mgreer@mvista.com>
Signed-off-by: default avatarKevin Hilman <khilman@deeprootsystems.com>
parent 33b18aab
......@@ -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)
......
......@@ -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)
......
......@@ -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)
......
......@@ -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);
......
......@@ -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 */
......@@ -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);
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment