aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJulien Grall <julien.grall@linaro.org>2013-04-26 20:36:35 +0100
committerIan Campbell <ian.campbell@citrix.com>2013-05-13 11:59:59 +0100
commit2be37b2cda31fc1b5f11deb912249bc54803f055 (patch)
tree267c28970649cc3d0bbeee4de78c18b4015edac0
parent23045cfe5099a0ff211b31b69073d907f2f221fd (diff)
downloadxen-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.c12
-rw-r--r--xen/drivers/char/serial.c10
-rw-r--r--xen/include/xen/serial.h5
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);