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

[RFC PATCH] xen/device-tree: Experimental support for TI K3 custom interrupt properties


  • To: xen-devel@xxxxxxxxxxxxxxxxxxxx
  • From: 정석용 <jed@xxxxxxxxxxxxxxxx>
  • Date: Tue, 20 Oct 2026 16:25:13 +0900 (KST)
  • Authentication-results: eu.smtp.expurgate.cloud; none
  • Delivery-date: Tue, 20 Oct 2026 10:55:46 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

Hello,

This RFC patch adds support for Texas Instruments (TI) K3 custom 
interrupt properties ('ti,interrupt-ranges' and 'ti,intr-trigger-type') 
in Xen's device tree parser.

On TI K3 platforms, certain devices use these custom properties instead 
of the standard 'interrupts' property due to the TI-SCI interrupt router 
architecture. Currently, Xen fails to parse these nodes, preventing 
proper interrupt configuration for those devices.

To address this, the attached experimental patch extends 
dt_number_of_irq() and dt_device_get_raw_irq() to parse 
'ti,interrupt-ranges' and calculate raw IRQs accordingly.

However, this implementation has several limitations and is far from ideal:
1. Vendor-specific properties are hardcoded into Xen's common 
   device tree parser.
2. Manual index calculations and magic numbers are used rather than 
   leveraging a proper abstraction layer.

We would greatly appreciate community feedback on the following points:
- Is there a preferred way to handle vendor-specific interrupt 
  bindings like this within Xen's DT framework?
- Would it be better to refactor this logic into a separate 
  architecture-specific or controller-specific layer, or is there 
  an existing mechanism we missed?

Any advice, suggestions, or architectural guidance is welcome.

Best regards,
Jed

---
 xen/common/device-tree/device-tree.c | 64 ++++++++++++++++++++++++++--
 1 file changed, 60 insertions(+), 4 deletions(-)

diff --git a/xen/common/device-tree/device-tree.c 
b/xen/common/device-tree/device-tree.c
index 0b5375f151..a084f03487 100644
--- a/xen/common/device-tree/device-tree.c
+++ b/xen/common/device-tree/device-tree.c
@@ -1123,8 +1123,23 @@ unsigned int dt_number_of_irq(const struct 
dt_device_node *device)
 
     /* Get the interrupts property */
     intspec = dt_get_property(device, "interrupts", &intlen);
-    if ( intspec == NULL )
-        return 0;
+    if ( intspec == NULL ) {
+        int i, retintnum = 0;
+        intspec = dt_get_property(device, "ti,interrupt-ranges", &intlen);
+        if(intspec == NULL) {
+            return 0;
+        }
+        intlen /= sizeof(*intspec);
+        dt_dprintk(" using 'ti,interrupt-ranges' property\n");
+
+        for( i = 2 ; i < intlen; i+=3){
+            retintnum += be32_to_cpu(intspec[i]);
+        }
+        dt_dprintk(" intspec=%d intlen=%d\n", be32_to_cpu(*intspec), 
retintnum);
+
+        return retintnum;
+    }
+
     intlen /= sizeof(*intspec);
 
     dt_dprintk(" using 'interrupts' property\n");
@@ -1578,8 +1593,49 @@ int dt_device_get_raw_irq(const struct dt_device_node 
*device,
 
     /* Get the interrupts property */
     intspec = dt_get_property(device, "interrupts", &intlen);
-    if ( intspec == NULL )
-        return -EINVAL;
+    if ( intspec == NULL ){
+        int i = 0, newidx = 0, curmax = 0, triggertype = 4;
+        u32 typelen;
+
+        intspec = dt_get_property(device, "ti,interrupt-ranges", &intlen);
+        if(intspec == NULL) {
+            return -EINVAL;
+        }
+        intlen /= sizeof(*intspec);
+        dt_dprintk(" using 'ti,interrupt-ranges' property\n");
+        dt_dprintk(" intspec=%d intlen=%d\n", be32_to_cpu(*intspec), intlen);
+
+        p = dt_irq_find_parent(device);
+        if ( p == NULL )
+            return -EINVAL;
+
+        i = 0;
+        newidx = index;
+        curmax = be32_to_cpu(intspec[i + 2]);
+        while(newidx >= curmax){
+            newidx -= curmax;
+
+            i += 3;
+            curmax = be32_to_cpu(intspec[i + 2]);
+        }
+
+        tmp = dt_get_property(device, "ti,intr-trigger-type", &typelen);
+        if(tmp != NULL) {
+            dt_dprintk(" using 'ti,intr-trigger-type' property\n");
+            dt_dprintk(" tmp=%d typelen=%d\n", be32_to_cpu(*tmp), typelen);
+
+            triggertype = be32_to_cpu(*tmp);
+        }
+
+        out_irq->specifier[0] = 0;
+        out_irq->specifier[1] = be32_to_cpu(intspec[i + 1]) + newidx - 32;
+        out_irq->specifier[2] = triggertype;
+        out_irq->size = 3;
+        out_irq->controller = p;
+
+        return 0;
+    }
+
     intlen /= sizeof(*intspec);
 
     dt_dprintk(" using 'interrupts' property\n");
-- 
2.43.0

 


Rackspace

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