|
[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
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
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |