[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [RFC PATCH 2/2] xen/device-tree: Add ability to handle nodes with interrupts-extended prop



From: Oleksandr Tyshchenko <oleksandr_tyshchenko@xxxxxxxx>

Xen expects to see "interrupts" property when parsing host
device-tree. But, there are cases when some device nodes contain
"interrupts-extended" property instead.

The good example here is arch timer node for R-Car Gen3/Gen2 family,
which is mandatory device for Xen usage on ARM. And without ability
to handle such nodes, Xen fails to operate:

(XEN) ****************************************
(XEN) Panic on CPU 0:
(XEN) Timer: Unable to retrieve IRQ 0 from the device tree
(XEN) ****************************************

Signed-off-by: Oleksandr Tyshchenko <oleksandr_tyshchenko@xxxxxxxx>
---
 xen/common/device_tree.c | 32 +++++++++++++++++++++++++++++---
 1 file changed, 29 insertions(+), 3 deletions(-)

diff --git a/xen/common/device_tree.c b/xen/common/device_tree.c
index 65862b5..00ada6e 100644
--- a/xen/common/device_tree.c
+++ b/xen/common/device_tree.c
@@ -987,9 +987,19 @@ unsigned int dt_number_of_irq(const struct dt_device_node 
*device)
     const struct dt_device_node *p;
     const __be32 *intspec, *tmp;
     u32 intsize, intlen;
+    int intnum;
 
     dt_dprintk("dt_irq_number: dev=%s\n", device->full_name);
 
+    /* Try the new-style interrupts-extended first */
+    intnum = dt_count_phandle_with_args(device, "interrupts-extended",
+                                        "#interrupt-cells");
+    if ( intnum > 0 )
+    {
+        dt_dprintk(" intnum=%d\n", intnum);
+        return intnum;
+    }
+
     /* Get the interrupts property */
     intspec = dt_get_property(device, "interrupts", &intlen);
     if ( intspec == NULL )
@@ -1420,10 +1430,29 @@ int dt_device_get_raw_irq(const struct dt_device_node 
*device,
     const __be32 *intspec, *tmp, *addr;
     u32 intsize, intlen;
     int res = -EINVAL;
+    struct dt_phandle_args args;
+    int i;
 
     dt_dprintk("dt_device_get_raw_irq: dev=%s, index=%u\n",
                device->full_name, index);
 
+    /* Get the reg property (if any) */
+    addr = dt_get_property(device, "reg", NULL);
+
+    /* Try the new-style interrupts-extended first */
+    res = dt_parse_phandle_with_args(device, "interrupts-extended",
+                                     "#interrupt-cells", index, &args);
+    if ( !res )
+    {
+        dt_dprintk(" intspec=%d intsize=%d\n", args.args[0], args.args_count);
+
+        for ( i = 0; i < args.args_count; i++ )
+            args.args[i] = cpu_to_be32(args.args[i]);
+
+        return dt_irq_map_raw(args.np, args.args, args.args_count,
+                              addr, out_irq);
+    }
+
     /* Get the interrupts property */
     intspec = dt_get_property(device, "interrupts", &intlen);
     if ( intspec == NULL )
@@ -1432,9 +1461,6 @@ int dt_device_get_raw_irq(const struct dt_device_node 
*device,
 
     dt_dprintk(" intspec=%d intlen=%d\n", be32_to_cpup(intspec), intlen);
 
-    /* Get the reg property (if any) */
-    addr = dt_get_property(device, "reg", NULL);
-
     /* Look for the interrupt parent. */
     p = dt_irq_find_parent(device);
     if ( p == NULL )
-- 
2.7.4


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.