diff mbox

[RFC,17/29] xen/arm: New callback in uart_driver to get device tree interrupt structure

Message ID 019572ab35c0212bbcfee16002738f9e5c8d1aa5.1367188423.git.julien.grall@linaro.org
State Changes Requested, archived
Headers show

Commit Message

Julien Grall April 28, 2013, 11:02 p.m. UTC
The existing function serial_irq doesn't allow to retrieve if the interrupt
is edge or level trigger.

Use this function to route all serial IRQs to xen.

Signed-off-by: Julien Grall <julien.grall@linaro.org>
---
 xen/arch/arm/gic.c        |   12 ++++++++++++
 xen/drivers/char/serial.c |   10 ++++++++++
 xen/include/xen/serial.h  |    5 +++++
 3 files changed, 27 insertions(+)

Comments

Ian Campbell April 29, 2013, 3:46 p.m. UTC | #1
On Mon, 2013-04-29 at 00:02 +0100, Julien Grall wrote:
> The existing function serial_irq doesn't allow to retrieve if the interrupt
> is edge or level trigger.
> 
> Use this function to route all serial IRQs to xen.

All of them? At most we want the one Xen is using, don't we?

> Signed-off-by: Julien Grall <julien.grall@linaro.org>
> ---
>  xen/arch/arm/gic.c        |   12 ++++++++++++
>  xen/drivers/char/serial.c |   10 ++++++++++
>  xen/include/xen/serial.h  |    5 +++++
>  3 files changed, 27 insertions(+)
> 
> diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c
> index bf0c1fd..8085b6e 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>
> @@ -497,9 +498,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);

Did you intend to remove this line?

> +    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 a3d2b26..0ae7e4d 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 b932ed4..5de5171 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);
Julien Grall April 29, 2013, 5:09 p.m. UTC | #2
On 04/29/2013 04:46 PM, Ian Campbell wrote:

> On Mon, 2013-04-29 at 00:02 +0100, Julien Grall wrote:
>> The existing function serial_irq doesn't allow to retrieve if the interrupt
>> is edge or level trigger.
>>
>> Use this function to route all serial IRQs to xen.
> 
> All of them? At most we want the one Xen is using, don't we?

My comment is a bit confusing. "all serial IRQs" means all IRQs of UART
registered via serial_register_uart.

Currently Xen on Arm can register zero one one UART (com1).

>> Signed-off-by: Julien Grall <julien.grall@linaro.org>
>> ---
>>  xen/arch/arm/gic.c        |   12 ++++++++++++
>>  xen/drivers/char/serial.c |   10 ++++++++++
>>  xen/include/xen/serial.h  |    5 +++++
>>  3 files changed, 27 insertions(+)
>>
>> diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c
>> index bf0c1fd..8085b6e 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>
>> @@ -497,9 +498,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);
> 
> Did you intend to remove this line?

Yes, I let this line to avoid to break xen boot on versatile express.
Ian Campbell April 30, 2013, 9:05 a.m. UTC | #3
On Mon, 2013-04-29 at 18:09 +0100, Julien Grall wrote:
> On 04/29/2013 04:46 PM, Ian Campbell wrote:
> 
> > On Mon, 2013-04-29 at 00:02 +0100, Julien Grall wrote:
> >> The existing function serial_irq doesn't allow to retrieve if the interrupt
> >> is edge or level trigger.
> >>
> >> Use this function to route all serial IRQs to xen.
> > 
> > All of them? At most we want the one Xen is using, don't we?
> 
> My comment is a bit confusing. "all serial IRQs" means all IRQs of UART
> registered via serial_register_uart.
> 
> Currently Xen on Arm can register zero one one UART (com1).

Ah, OK, thanks.

"Use this function to route 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>

> >>      gic_route_irq(37, 0, 1u << smp_processor_id(), 0xa0);
> > 
> > Did you intend to remove this line?
> 
> Yes, I let this line to avoid to break xen boot on versatile express.

I think I saw it get removed in a later patch dealing with vexpress, so
that's ok.

Ian.
diff mbox

Patch

diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c
index bf0c1fd..8085b6e 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>
@@ -497,9 +498,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 a3d2b26..0ae7e4d 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 b932ed4..5de5171 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);