[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [RFC 19/29] xen/arm: Use device tree API in pl011 UART driver
Allow UART driver to retrieve all its information in the device tree. It's possible to choose the pl011 driver via the Xen command line. Signed-off-by: Julien Grall <julien.grall@xxxxxxxxxx> --- xen/arch/arm/gic.c | 4 --- xen/arch/arm/setup.c | 4 --- xen/drivers/char/pl011.c | 63 +++++++++++++++++++++++++++++++++++----------- xen/include/xen/serial.h | 1 - 4 files changed, 49 insertions(+), 23 deletions(-) diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c index 8085b6e..8dba4b6 100644 --- a/xen/arch/arm/gic.c +++ b/xen/arch/arm/gic.c @@ -501,10 +501,6 @@ void gic_route_spis(void) int seridx; const struct dt_irq *irq; - /* XXX should get these from DT */ - /* UART */ - gic_route_irq(37, 0, 1u << smp_processor_id(), 0xa0); - for ( seridx = 0; seridx <= SERHND_IDX; seridx++ ) { if ( (irq = serial_dt_irq(seridx)) == NULL ) diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c index e5d8724..aee491d 100644 --- a/xen/arch/arm/setup.c +++ b/xen/arch/arm/setup.c @@ -431,10 +431,6 @@ void __init start_xen(unsigned long boot_phys_offset, dt_unflatten_host_device_tree(); dt_irq_xlate = gic_irq_xlate; -#ifdef EARLY_UART_ADDRESS - /* TODO Need to get device tree or command line for UART address */ - pl011_init(0, FIXMAP_ADDR(FIXMAP_CONSOLE)); -#endif arm_uart_init(); console_init_preirq(); diff --git a/xen/drivers/char/pl011.c b/xen/drivers/char/pl011.c index 8efd08e..411aea5 100644 --- a/xen/drivers/char/pl011.c +++ b/xen/drivers/char/pl011.c @@ -22,9 +22,14 @@ #include <xen/serial.h> #include <xen/init.h> #include <xen/irq.h> +#include <asm/early_printk.h> +#include <xen/device_tree.h> +#include <xen/errno.h> +#include <asm/device.h> static struct pl011 { - unsigned int baud, clock_hz, data_bits, parity, stop_bits, irq; + unsigned int baud, clock_hz, data_bits, parity, stop_bits; + struct dt_irq irq; volatile uint32_t *regs; /* UART with IRQ line: interrupt-driven I/O. */ struct irqaction irqaction; @@ -163,13 +168,13 @@ static void __init pl011_init_postirq(struct serial_port *port) struct pl011 *uart = port->uart; int rc; - if ( uart->irq > 0 ) + if ( uart->irq.irq > 0 ) { uart->irqaction.handler = pl011_interrupt; uart->irqaction.name = "pl011"; uart->irqaction.dev_id = port; - if ( (rc = setup_irq(uart->irq, &uart->irqaction)) != 0 ) - printk("ERROR: Failed to allocate pl011 IRQ %d\n", uart->irq); + if ( (rc = setup_irq(uart->irq.irq, &uart->irqaction)) != 0 ) + printk("ERROR: Failed to allocate pl011 IRQ %d\n", uart->irq.irq); } /* Clear pending error interrupts */ @@ -215,7 +220,14 @@ static int pl011_getc(struct serial_port *port, char *pc) static int __init pl011_irq(struct serial_port *port) { struct pl011 *uart = port->uart; - return ((uart->irq > 0) ? uart->irq : -1); + return ((uart->irq.irq > 0) ? uart->irq.irq : -1); +} + +static const struct dt_irq __init *pl011_dt_irq(struct serial_port *port) +{ + struct pl011 *uart = port->uart; + + return &uart->irq; } static struct uart_driver __read_mostly pl011_driver = { @@ -227,32 +239,55 @@ static struct uart_driver __read_mostly pl011_driver = { .tx_ready = pl011_tx_ready, .putc = pl011_putc, .getc = pl011_getc, - .irq = pl011_irq + .irq = pl011_irq, + .dt_irq_get = pl011_dt_irq, }; -/* TODO: Parse UART config from device-tree or command-line */ - -void __init pl011_init(int index, unsigned long register_base_address) +static int __init pl011_uart_init(struct dt_device_node *dev, + const void *data) { + const struct serial_arm_defaults *defaults = data; struct pl011 *uart; + int res; - if ( (index < 0) || (index > 1) ) - return; + if ( (defaults->index < 0) || (defaults->index > 1) ) + return -EINVAL; - uart = &pl011_com[index]; + uart = &pl011_com[defaults->index]; uart->clock_hz = 0x16e3600; uart->baud = 38400; uart->data_bits = 8; uart->parity = PARITY_NONE; uart->stop_bits = 1; - uart->irq = 37; /* TODO Need to find this from devicetree */ - uart->regs = (uint32_t *) register_base_address; + uart->regs = (uint32_t *) defaults->register_base_address; + + res = dt_device_get_irq(dev, 0, &uart->irq); + if ( res ) + { + early_printk("pl011: Unable to retrieve the IRQ\n"); + return res; + } /* Register with generic serial driver. */ serial_register_uart(uart - pl011_com, &pl011_driver, uart); + + dt_device_set_used_by(dev, DT_USED_BY_XEN); + + return 0; } +static const char const *pl011_dt_compat[] __initdata = +{ + "arm,pl011", + NULL +}; + +DT_DEVICE_START(pl011, "PL011 UART", DEVICE_SERIAL) + .compatible = pl011_dt_compat, + .init = pl011_uart_init, +DT_DEVICE_END + /* * Local variables: * mode: C diff --git a/xen/include/xen/serial.h b/xen/include/xen/serial.h index 2579ce8..a7d4c6d 100644 --- a/xen/include/xen/serial.h +++ b/xen/include/xen/serial.h @@ -156,7 +156,6 @@ struct ns16550_defaults { void ns16550_init(int index, struct ns16550_defaults *defaults); void ehci_dbgp_init(void); -void pl011_init(int index, unsigned long register_base_address); /* Default value for UART on ARM boards */ struct serial_arm_defaults { int index; /* Serial index */ -- Julien Grall _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |