diff options
author | Julien Grall <julien.grall@linaro.org> | 2013-04-26 20:36:35 +0100 |
---|---|---|
committer | Ian Campbell <ian.campbell@citrix.com> | 2013-05-13 11:59:59 +0100 |
commit | 2be37b2cda31fc1b5f11deb912249bc54803f055 (patch) | |
tree | 267c28970649cc3d0bbeee4de78c18b4015edac0 | |
parent | 23045cfe5099a0ff211b31b69073d907f2f221fd (diff) | |
download | xen-2be37b2cda31fc1b5f11deb912249bc54803f055.tar.gz xen-2be37b2cda31fc1b5f11deb912249bc54803f055.tar.bz2 xen-2be37b2cda31fc1b5f11deb912249bc54803f055.zip |
xen/arm: New callback in uart_driver to get device tree interrupt structure
The existing function serial_irq doesn't allow to retrieve if the interrupt
is edge or level trigger.
Use this function to routes IRQs for all serial ports which Xen is using
to Xen.
Signed-off-by: Julien Grall <julien.grall@linaro.org>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
-rw-r--r-- | xen/arch/arm/gic.c | 12 | ||||
-rw-r--r-- | xen/drivers/char/serial.c | 10 | ||||
-rw-r--r-- | xen/include/xen/serial.h | 5 |
3 files changed, 27 insertions, 0 deletions
diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c index 821f6836bf..761f570aa8 100644 --- a/xen/arch/arm/gic.c +++ b/xen/arch/arm/gic.c @@ -24,6 +24,7 @@ #include <xen/irq.h> #include <xen/sched.h> #include <xen/errno.h> +#include <xen/serial.h> #include <xen/softirq.h> #include <xen/list.h> #include <xen/device_tree.h> @@ -501,9 +502,20 @@ void gic_route_ppis(void) 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 ) + continue; + + gic_route_dt_irq(irq, 1u << smp_processor_id(), 0xa0); + } } void __init release_irq(unsigned int irq) diff --git a/xen/drivers/char/serial.c b/xen/drivers/char/serial.c index a3d2b26cd9..0ae7e4daeb 100644 --- a/xen/drivers/char/serial.c +++ b/xen/drivers/char/serial.c @@ -482,6 +482,16 @@ int __init serial_irq(int idx) return -1; } +const struct dt_irq __init *serial_dt_irq(int idx) +{ + if ( (idx >= 0) && (idx < ARRAY_SIZE(com)) && + com[idx].driver && com[idx].driver->dt_irq_get ) + return com[idx].driver->dt_irq_get(&com[idx]); + + return NULL; +} + + void serial_suspend(void) { int i; diff --git a/xen/include/xen/serial.h b/xen/include/xen/serial.h index b932ed4eb4..5de517136b 100644 --- a/xen/include/xen/serial.h +++ b/xen/include/xen/serial.h @@ -71,6 +71,8 @@ struct uart_driver { int (*getc)(struct serial_port *, char *); /* Get IRQ number for this port's serial line: returns -1 if none. */ int (*irq)(struct serial_port *); + /* Get IRQ device node for this port's serial line: returns NULL if none. */ + const struct dt_irq *(*dt_irq_get)(struct serial_port *); }; /* 'Serial handles' are composed from the following fields. */ @@ -120,6 +122,9 @@ void serial_end_log_everything(int handle); /* Return irq number for specified serial port (identified by index). */ int serial_irq(int idx); +/* Return irq device node for specified serial port (identified by index). */ +const struct dt_irq *serial_dt_irq(int idx); + /* Serial suspend/resume. */ void serial_suspend(void); void serial_resume(void); |