[PATCH 2/2] drivers: irqchip: irq-ti-sci-intr: Allow parsing interrupt-types per-line

Aniket Limaye posted 2 patches 3 weeks, 3 days ago
There is a newer version of this series
[PATCH 2/2] drivers: irqchip: irq-ti-sci-intr: Allow parsing interrupt-types per-line
Posted by Aniket Limaye 3 weeks, 3 days ago
Some INTR router instances act as simple passthroughs that preserve the
source interrupt type unchanged at the output line, rather than converting
all interrupts to a fixed type.

When interrupt sources are not homogeneous with respect to trigger type,
the driver needs to read each source's interrupt type from DT and pass it
unchanged to its interrupt parent

Previously, the interrupt type for all output lines was set globally using
the "ti,intr-trigger-type" property (values 1 or 4).

Add support for "ti,intr-trigger-type" = 15 (IRQ_TYPE_DEFAULT) to indicate
passthrough mode:
- When set to 15: Parse interrupt type per-line from DT
- When set to 1 or 4: Use global setting (maintains backward compatibility)

Signed-off-by: Aniket Limaye <a-limaye@ti.com>
---
 drivers/irqchip/irq-ti-sci-intr.c | 50 ++++++++++++++++++++++++++++++---------
 1 file changed, 39 insertions(+), 11 deletions(-)

diff --git a/drivers/irqchip/irq-ti-sci-intr.c b/drivers/irqchip/irq-ti-sci-intr.c
index 354613e74ad0..56028a33a41e 100644
--- a/drivers/irqchip/irq-ti-sci-intr.c
+++ b/drivers/irqchip/irq-ti-sci-intr.c
@@ -61,11 +61,22 @@ static int ti_sci_intr_irq_domain_translate(struct irq_domain *domain,
 {
 	struct ti_sci_intr_irq_domain *intr = domain->host_data;
 
-	if (fwspec->param_count != 1)
-		return -EINVAL;
 
-	*hwirq = fwspec->param[0];
-	*type = intr->type;
+	if (intr->type != IRQ_TYPE_DEFAULT) {
+		/* Global interrupt-type */
+		if (fwspec->param_count != 1)
+			return -EINVAL;
+
+		*hwirq = fwspec->param[0];
+		*type = intr->type;
+	} else {
+		/* Per-Line interrupt-type */
+		if (fwspec->param_count != 2)
+			return -EINVAL;
+
+		*hwirq = fwspec->param[0];
+		*type = fwspec->param[1];
+	}
 
 	return 0;
 }
@@ -128,11 +139,12 @@ static void ti_sci_intr_irq_domain_free(struct irq_domain *domain,
  * @domain:	Pointer to the interrupt router IRQ domain
  * @virq:	Corresponding Linux virtual IRQ number
  * @hwirq:	Corresponding hwirq for the IRQ within this IRQ domain
+ * @hwirq_type:	Corresponding hwirq trigger type for the IRQ within this IRQ domain
  *
  * Returns intr output irq if all went well else appropriate error pointer.
  */
 static int ti_sci_intr_alloc_parent_irq(struct irq_domain *domain,
-					unsigned int virq, u32 hwirq)
+					unsigned int virq, u32 hwirq, u32 hwirq_type)
 {
 	struct ti_sci_intr_irq_domain *intr = domain->host_data;
 	struct device_node *parent_node;
@@ -156,11 +168,27 @@ static int ti_sci_intr_alloc_parent_irq(struct irq_domain *domain,
 		fwspec.param_count = 3;
 		fwspec.param[0] = 0;	/* SPI */
 		fwspec.param[1] = p_hwirq - 32; /* SPI offset */
-		fwspec.param[2] = intr->type;
+		fwspec.param[2] = hwirq_type;
 	} else {
 		/* Parent is Interrupt Router */
-		fwspec.param_count = 1;
-		fwspec.param[0] = p_hwirq;
+		u32 parent_trigger_type;
+
+		err = of_property_read_u32(parent_node,
+					  "ti,intr-trigger-type",
+					  &parent_trigger_type);
+		if (err)
+			goto err_irqs;
+
+		if (parent_trigger_type != IRQ_TYPE_DEFAULT) {
+			/* Parent has global trigger type */
+			fwspec.param_count = 1;
+			fwspec.param[0] = p_hwirq;
+		} else {
+			/* Parent supports per-line trigger types */
+			fwspec.param_count = 2;
+			fwspec.param[0] = p_hwirq;
+			fwspec.param[1] = hwirq_type;
+		}
 	}
 
 	err = irq_domain_alloc_irqs_parent(domain, virq, 1, &fwspec);
@@ -197,14 +225,14 @@ static int ti_sci_intr_irq_domain_alloc(struct irq_domain *domain,
 {
 	struct irq_fwspec *fwspec = data;
 	unsigned long hwirq;
-	unsigned int flags;
+	unsigned int hwirq_type;
 	int err, out_irq;
 
-	err = ti_sci_intr_irq_domain_translate(domain, fwspec, &hwirq, &flags);
+	err = ti_sci_intr_irq_domain_translate(domain, fwspec, &hwirq, &hwirq_type);
 	if (err)
 		return err;
 
-	out_irq = ti_sci_intr_alloc_parent_irq(domain, virq, hwirq);
+	out_irq = ti_sci_intr_alloc_parent_irq(domain, virq, hwirq, hwirq_type);
 	if (out_irq < 0)
 		return out_irq;
 

-- 
2.52.0
Re: [PATCH 2/2] drivers: irqchip: irq-ti-sci-intr: Allow parsing interrupt-types per-line
Posted by Thomas Gleixner 3 weeks, 1 day ago
On Fri, Jan 16 2026 at 18:38, Aniket Limaye wrote:

The subject line prefix is made up. Please follow the documented
conventions:

https://www.kernel.org/doc/html/latest/process/maintainer-tip.html#patch-submission-notes

> Some INTR router instances act as simple passthroughs that preserve the
> source interrupt type unchanged at the output line, rather than converting
> all interrupts to a fixed type.
>
> When interrupt sources are not homogeneous with respect to trigger type,
> the driver needs to read each source's interrupt type from DT and pass it
> unchanged to its interrupt parent
>
> Previously, the interrupt type for all output lines was set globally using
> the "ti,intr-trigger-type" property (values 1 or 4).

What means 'previously'?

You want to describe the current state and not something which might be
in the past after applying the change.

> Add support for "ti,intr-trigger-type" = 15 (IRQ_TYPE_DEFAULT) to indicate
> passthrough mode:
> - When set to 15: Parse interrupt type per-line from DT
> - When set to 1 or 4: Use global setting (maintains backward compatibility)

> @@ -156,11 +168,27 @@ static int ti_sci_intr_alloc_parent_irq(struct irq_domain *domain,
>  		fwspec.param_count = 3;
>  		fwspec.param[0] = 0;	/* SPI */
>  		fwspec.param[1] = p_hwirq - 32; /* SPI offset */
> -		fwspec.param[2] = intr->type;
> +		fwspec.param[2] = hwirq_type;
>  	} else {
>  		/* Parent is Interrupt Router */
> -		fwspec.param_count = 1;
> -		fwspec.param[0] = p_hwirq;
> +		u32 parent_trigger_type;
> +
> +		err = of_property_read_u32(parent_node,
> +					  "ti,intr-trigger-type",
> +					  &parent_trigger_type);

You have 100 characters and if you need a line break align the second
line argument with the first line argument and not with the bracket.
See documentation.

> +		if (err)
> +			goto err_irqs;
> +
> +		if (parent_trigger_type != IRQ_TYPE_DEFAULT) {
> +			/* Parent has global trigger type */
> +			fwspec.param_count = 1;
> +			fwspec.param[0] = p_hwirq;
> +		} else {
> +			/* Parent supports per-line trigger types */
> +			fwspec.param_count = 2;
> +			fwspec.param[0] = p_hwirq;
> +			fwspec.param[1] = hwirq_type;
> +		}
>  	}
>  
>  	err = irq_domain_alloc_irqs_parent(domain, virq, 1, &fwspec);
> @@ -197,14 +225,14 @@ static int ti_sci_intr_irq_domain_alloc(struct irq_domain *domain,
>  {
>  	struct irq_fwspec *fwspec = data;
>  	unsigned long hwirq;
> -	unsigned int flags;
> +	unsigned int hwirq_type;

https://www.kernel.org/doc/html/latest/process/maintainer-tip.html#variable-declarations

>  	int err, out_irq;
>  
> -	err = ti_sci_intr_irq_domain_translate(domain, fwspec, &hwirq, &flags);
> +	err = ti_sci_intr_irq_domain_translate(domain, fwspec, &hwirq, &hwirq_type);
>  	if (err)
>  		return err;
>  
> -	out_irq = ti_sci_intr_alloc_parent_irq(domain, virq, hwirq);
> +	out_irq = ti_sci_intr_alloc_parent_irq(domain, virq, hwirq, hwirq_type);
>  	if (out_irq < 0)
>  		return out_irq;

Thanks,

        tglx
Re: [PATCH 2/2] drivers: irqchip: irq-ti-sci-intr: Allow parsing interrupt-types per-line
Posted by Aniket Limaye 3 weeks ago

On 18/01/26 15:19, Thomas Gleixner wrote:
> On Fri, Jan 16 2026 at 18:38, Aniket Limaye wrote:
> 
> The subject line prefix is made up. Please follow the documented
> conventions:
> 
> https://www.kernel.org/doc/html/latest/process/maintainer-tip.html#patch-submission-notes
> 
>> Some INTR router instances act as simple passthroughs that preserve the
>> source interrupt type unchanged at the output line, rather than converting
>> all interrupts to a fixed type.
>>
>> When interrupt sources are not homogeneous with respect to trigger type,
>> the driver needs to read each source's interrupt type from DT and pass it
>> unchanged to its interrupt parent
>>
>> Previously, the interrupt type for all output lines was set globally using
>> the "ti,intr-trigger-type" property (values 1 or 4).
> 
> What means 'previously'?
> 
> You want to describe the current state and not something which might be
> in the past after applying the change.
> 

Sure, makes sense... will update this in v2.

>> Add support for "ti,intr-trigger-type" = 15 (IRQ_TYPE_DEFAULT) to indicate
>> passthrough mode:
>> - When set to 15: Parse interrupt type per-line from DT
>> - When set to 1 or 4: Use global setting (maintains backward compatibility)
> 
>> @@ -156,11 +168,27 @@ static int ti_sci_intr_alloc_parent_irq(struct irq_domain *domain,
>>   		fwspec.param_count = 3;
>>   		fwspec.param[0] = 0;	/* SPI */
>>   		fwspec.param[1] = p_hwirq - 32; /* SPI offset */
>> -		fwspec.param[2] = intr->type;
>> +		fwspec.param[2] = hwirq_type;
>>   	} else {
>>   		/* Parent is Interrupt Router */
>> -		fwspec.param_count = 1;
>> -		fwspec.param[0] = p_hwirq;
>> +		u32 parent_trigger_type;
>> +
>> +		err = of_property_read_u32(parent_node,
>> +					  "ti,intr-trigger-type",
>> +					  &parent_trigger_type);
> 
> You have 100 characters and if you need a line break align the second
> line argument with the first line argument and not with the bracket.
> See documentation.
> 
>> +		if (err)
>> +			goto err_irqs;
>> +
>> +		if (parent_trigger_type != IRQ_TYPE_DEFAULT) {
>> +			/* Parent has global trigger type */
>> +			fwspec.param_count = 1;
>> +			fwspec.param[0] = p_hwirq;
>> +		} else {
>> +			/* Parent supports per-line trigger types */
>> +			fwspec.param_count = 2;
>> +			fwspec.param[0] = p_hwirq;
>> +			fwspec.param[1] = hwirq_type;
>> +		}
>>   	}
>>   
>>   	err = irq_domain_alloc_irqs_parent(domain, virq, 1, &fwspec);
>> @@ -197,14 +225,14 @@ static int ti_sci_intr_irq_domain_alloc(struct irq_domain *domain,
>>   {
>>   	struct irq_fwspec *fwspec = data;
>>   	unsigned long hwirq;
>> -	unsigned int flags;
>> +	unsigned int hwirq_type;
> 
> https://www.kernel.org/doc/html/latest/process/maintainer-tip.html#variable-declarations
> 
>>   	int err, out_irq;
>>   
>> -	err = ti_sci_intr_irq_domain_translate(domain, fwspec, &hwirq, &flags);
>> +	err = ti_sci_intr_irq_domain_translate(domain, fwspec, &hwirq, &hwirq_type);
>>   	if (err)
>>   		return err;
>>   
>> -	out_irq = ti_sci_intr_alloc_parent_irq(domain, virq, hwirq);
>> +	out_irq = ti_sci_intr_alloc_parent_irq(domain, virq, hwirq, hwirq_type);
>>   	if (out_irq < 0)
>>   		return out_irq;
> 
> Thanks,
> 
>          tglx


Thanks for reviewing the patch.

Will send a v2 addressing all of your feedback and will note all 
recommendations for future patches too.

Regards,
Aniket