Message ID | 1368198723-24639-7-git-send-email-julien.grall@linaro.org |
---|---|
State | Accepted, archived |
Headers | show |
On 10/05/2013 16:11, "Julien Grall" <julien.grall@linaro.org> wrote: > This generic UART will find the right UART via xen command line > with dtuart=myserial. > > "myserial" is the alias of the UART in the device tree. Xen will retrieve > the information via the device tree and call the initialization function for > this specific UART thanks to the device API. > > Signed-off-by: Julien Grall <julien.grall@linaro.org> > Acked-by: Ian Campbell <ian.campbell@citrix.com> > CC: keir@xen.org Acked-by: Keir Fraser <keir@xen.org> > > Changes in v3: > - Rename arm-uart.c (resp. arm_uart_init) to dt-uart.c (resp. > dt_uart_init) > - Remove serial_arm_defaults and replace by a string options > - Let the specific UART driver to get its base address in the DT > - Add SERHND_DTUART. The value is stolen to SERHND_COM1. Bump the > value would needs some rework... > > Changes in v2: > - Use dtuart parameter instead of com1. The first one is more arm > while the latter is more x86 > --- > xen/arch/arm/setup.c | 3 +- > xen/drivers/char/Makefile | 1 + > xen/drivers/char/dt-uart.c | 69 > ++++++++++++++++++++++++++++++++++++++++++ > xen/drivers/char/serial.c | 6 ++++ > xen/include/asm-arm/config.h | 2 +- > xen/include/xen/serial.h | 5 ++- > 6 files changed, 83 insertions(+), 3 deletions(-) > create mode 100644 xen/drivers/char/dt-uart.c > > diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c > index fc53117..2e331d3 100644 > --- a/xen/arch/arm/setup.c > +++ b/xen/arch/arm/setup.c > @@ -436,8 +436,9 @@ void __init start_xen(unsigned long boot_phys_offset, > #ifdef EARLY_UART_ADDRESS > /* TODO Need to get device tree or command line for UART address */ > pl011_init(0, FIXMAP_ADDR(FIXMAP_CONSOLE)); > - console_init_preirq(); > #endif > + dt_uart_init(); > + console_init_preirq(); > > system_state = SYS_STATE_boot; > > diff --git a/xen/drivers/char/Makefile b/xen/drivers/char/Makefile > index ab2246d..9c067f9 100644 > --- a/xen/drivers/char/Makefile > +++ b/xen/drivers/char/Makefile > @@ -2,4 +2,5 @@ obj-y += console.o > obj-$(HAS_NS16550) += ns16550.o > obj-$(HAS_PL011) += pl011.o > obj-$(HAS_EHCI) += ehci-dbgp.o > +obj-$(CONFIG_ARM) += dt-uart.o > obj-y += serial.o > diff --git a/xen/drivers/char/dt-uart.c b/xen/drivers/char/dt-uart.c > new file mode 100644 > index 0000000..93bb0f5 > --- /dev/null > +++ b/xen/drivers/char/dt-uart.c > @@ -0,0 +1,69 @@ > +/* > + * xen/drivers/char/dt-uart.c > + * > + * Generic uart retrieved via the device tree > + * > + * Julien Grall <julien.grall@linaro.org> > + * Copyright (c) 2013 Linaro Limited. > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License as published by > + * the Free Software Foundation; either version 2 of the License, or > + * (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + */ > + > +#include <asm/device.h> > +#include <asm/early_printk.h> > +#include <asm/types.h> > +#include <xen/console.h> > +#include <xen/device_tree.h> > +#include <xen/serial.h> > + > +/* > + * Configure UART port with a string: > + * alias,options > + * > + * @alias: alias used in the device tree for the UART > + * @options: UART speficic options (see in each UART driver) > + */ > +static char __initdata opt_dtuart[30] = ""; > +string_param("dtuart", opt_dtuart); > + > +void __init dt_uart_init(void) > +{ > + struct dt_device_node *dev; > + int ret; > + const char *devalias = opt_dtuart; > + char *options; > + > + if ( !console_has("dtuart") || !strcmp(opt_dtuart, "") ) > + { > + early_printk("No console\n"); > + return; > + } > + > + options = strchr(opt_dtuart, ','); > + if ( options != NULL ) > + *(options++) = '\0'; > + else > + options = ""; > + > + early_printk("Looking for UART console %s\n", devalias); > + dev = dt_find_node_by_alias(devalias); > + > + if ( !dev ) > + { > + early_printk("Unable to find device \"%s\"\n", devalias); > + return; > + } > + > + ret = device_init(dev, DEVICE_SERIAL, options); > + > + if ( ret ) > + early_printk("Unable to initialize serial: %d\n", ret); > +} > diff --git a/xen/drivers/char/serial.c b/xen/drivers/char/serial.c > index 0ae7e4d..e1c3f47 100644 > --- a/xen/drivers/char/serial.c > +++ b/xen/drivers/char/serial.c > @@ -271,6 +271,12 @@ int __init serial_parse_handle(char *conf) > goto common; > } > > + if ( !strncmp(conf, "dtuart", 5) ) > + { > + handle = SERHND_DTUART; > + goto common; > + } > + > if ( strncmp(conf, "com", 3) ) > goto fail; > > diff --git a/xen/include/asm-arm/config.h b/xen/include/asm-arm/config.h > index 98a3a43..8ed72f5 100644 > --- a/xen/include/asm-arm/config.h > +++ b/xen/include/asm-arm/config.h > @@ -39,7 +39,7 @@ > > #define CONFIG_VIDEO 1 > > -#define OPT_CONSOLE_STR "com1" > +#define OPT_CONSOLE_STR "dtuart" > > #ifdef MAX_PHYS_CPUS > #define NR_CPUS MAX_PHYS_CPUS > diff --git a/xen/include/xen/serial.h b/xen/include/xen/serial.h > index 5de5171..8af3bc4 100644 > --- a/xen/include/xen/serial.h > +++ b/xen/include/xen/serial.h > @@ -9,6 +9,7 @@ > #ifndef __XEN_SERIAL_H__ > #define __XEN_SERIAL_H__ > > +#include <xen/init.h> > #include <xen/spinlock.h> > > struct cpu_user_regs; > @@ -76,10 +77,11 @@ struct uart_driver { > }; > > /* 'Serial handles' are composed from the following fields. */ > -#define SERHND_IDX (3<<0) /* COM1, COM2, or DBGP? */ > +#define SERHND_IDX (3<<0) /* COM1, COM2, DBGP, DTUART? */ > # define SERHND_COM1 (0<<0) > # define SERHND_COM2 (1<<0) > # define SERHND_DBGP (2<<0) > +# define SERHND_DTUART (0<<0) /* Steal SERHND_COM1 value */ > #define SERHND_HI (1<<2) /* Mux/demux each transferred char by MSB. */ > #define SERHND_LO (1<<3) /* Ditto, except that the MSB is cleared. */ > #define SERHND_COOKED (1<<4) /* Newline/carriage-return translation? */ > @@ -156,6 +158,7 @@ void ns16550_init(int index, struct ns16550_defaults > *defaults); > void ehci_dbgp_init(void); > > void pl011_init(int index, unsigned long register_base_address); > +void __init dt_uart_init(void); > > struct physdev_dbgp_op; > int dbgp_op(const struct physdev_dbgp_op *);
diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c index fc53117..2e331d3 100644 --- a/xen/arch/arm/setup.c +++ b/xen/arch/arm/setup.c @@ -436,8 +436,9 @@ void __init start_xen(unsigned long boot_phys_offset, #ifdef EARLY_UART_ADDRESS /* TODO Need to get device tree or command line for UART address */ pl011_init(0, FIXMAP_ADDR(FIXMAP_CONSOLE)); - console_init_preirq(); #endif + dt_uart_init(); + console_init_preirq(); system_state = SYS_STATE_boot; diff --git a/xen/drivers/char/Makefile b/xen/drivers/char/Makefile index ab2246d..9c067f9 100644 --- a/xen/drivers/char/Makefile +++ b/xen/drivers/char/Makefile @@ -2,4 +2,5 @@ obj-y += console.o obj-$(HAS_NS16550) += ns16550.o obj-$(HAS_PL011) += pl011.o obj-$(HAS_EHCI) += ehci-dbgp.o +obj-$(CONFIG_ARM) += dt-uart.o obj-y += serial.o diff --git a/xen/drivers/char/dt-uart.c b/xen/drivers/char/dt-uart.c new file mode 100644 index 0000000..93bb0f5 --- /dev/null +++ b/xen/drivers/char/dt-uart.c @@ -0,0 +1,69 @@ +/* + * xen/drivers/char/dt-uart.c + * + * Generic uart retrieved via the device tree + * + * Julien Grall <julien.grall@linaro.org> + * Copyright (c) 2013 Linaro Limited. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <asm/device.h> +#include <asm/early_printk.h> +#include <asm/types.h> +#include <xen/console.h> +#include <xen/device_tree.h> +#include <xen/serial.h> + +/* + * Configure UART port with a string: + * alias,options + * + * @alias: alias used in the device tree for the UART + * @options: UART speficic options (see in each UART driver) + */ +static char __initdata opt_dtuart[30] = ""; +string_param("dtuart", opt_dtuart); + +void __init dt_uart_init(void) +{ + struct dt_device_node *dev; + int ret; + const char *devalias = opt_dtuart; + char *options; + + if ( !console_has("dtuart") || !strcmp(opt_dtuart, "") ) + { + early_printk("No console\n"); + return; + } + + options = strchr(opt_dtuart, ','); + if ( options != NULL ) + *(options++) = '\0'; + else + options = ""; + + early_printk("Looking for UART console %s\n", devalias); + dev = dt_find_node_by_alias(devalias); + + if ( !dev ) + { + early_printk("Unable to find device \"%s\"\n", devalias); + return; + } + + ret = device_init(dev, DEVICE_SERIAL, options); + + if ( ret ) + early_printk("Unable to initialize serial: %d\n", ret); +} diff --git a/xen/drivers/char/serial.c b/xen/drivers/char/serial.c index 0ae7e4d..e1c3f47 100644 --- a/xen/drivers/char/serial.c +++ b/xen/drivers/char/serial.c @@ -271,6 +271,12 @@ int __init serial_parse_handle(char *conf) goto common; } + if ( !strncmp(conf, "dtuart", 5) ) + { + handle = SERHND_DTUART; + goto common; + } + if ( strncmp(conf, "com", 3) ) goto fail; diff --git a/xen/include/asm-arm/config.h b/xen/include/asm-arm/config.h index 98a3a43..8ed72f5 100644 --- a/xen/include/asm-arm/config.h +++ b/xen/include/asm-arm/config.h @@ -39,7 +39,7 @@ #define CONFIG_VIDEO 1 -#define OPT_CONSOLE_STR "com1" +#define OPT_CONSOLE_STR "dtuart" #ifdef MAX_PHYS_CPUS #define NR_CPUS MAX_PHYS_CPUS diff --git a/xen/include/xen/serial.h b/xen/include/xen/serial.h index 5de5171..8af3bc4 100644 --- a/xen/include/xen/serial.h +++ b/xen/include/xen/serial.h @@ -9,6 +9,7 @@ #ifndef __XEN_SERIAL_H__ #define __XEN_SERIAL_H__ +#include <xen/init.h> #include <xen/spinlock.h> struct cpu_user_regs; @@ -76,10 +77,11 @@ struct uart_driver { }; /* 'Serial handles' are composed from the following fields. */ -#define SERHND_IDX (3<<0) /* COM1, COM2, or DBGP? */ +#define SERHND_IDX (3<<0) /* COM1, COM2, DBGP, DTUART? */ # define SERHND_COM1 (0<<0) # define SERHND_COM2 (1<<0) # define SERHND_DBGP (2<<0) +# define SERHND_DTUART (0<<0) /* Steal SERHND_COM1 value */ #define SERHND_HI (1<<2) /* Mux/demux each transferred char by MSB. */ #define SERHND_LO (1<<3) /* Ditto, except that the MSB is cleared. */ #define SERHND_COOKED (1<<4) /* Newline/carriage-return translation? */ @@ -156,6 +158,7 @@ void ns16550_init(int index, struct ns16550_defaults *defaults); void ehci_dbgp_init(void); void pl011_init(int index, unsigned long register_base_address); +void __init dt_uart_init(void); struct physdev_dbgp_op; int dbgp_op(const struct physdev_dbgp_op *);