Skip to content

Commit 3d9617e

Browse files
aniket-lThomas Gleixner
authored andcommitted
irqchip/ti-sci-intr: Allow parsing interrupt-types per-line
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. Add support to check for absence of "ti,intr-trigger-type" to indicate passthrough mode. When this property is absent, parse interrupt type per-line from the DT fwspec provided by the interrupt source. Else, use the global setting for all interrupt lines. Signed-off-by: Aniket Limaye <a-limaye@ti.com> Signed-off-by: Thomas Gleixner <tglx@kernel.org> Link: https://patch.msgid.link/20260123-ul-driver-i2c-j722s-v4-2-b08625c487d5@ti.com
1 parent 7a30a7a commit 3d9617e

File tree

1 file changed

+36
-18
lines changed

1 file changed

+36
-18
lines changed

drivers/irqchip/irq-ti-sci-intr.c

Lines changed: 36 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,21 @@ static int ti_sci_intr_irq_domain_translate(struct irq_domain *domain,
6161
{
6262
struct ti_sci_intr_irq_domain *intr = domain->host_data;
6363

64-
if (fwspec->param_count != 1)
65-
return -EINVAL;
64+
if (intr->type) {
65+
/* Global interrupt-type */
66+
if (fwspec->param_count != 1)
67+
return -EINVAL;
6668

67-
*hwirq = fwspec->param[0];
68-
*type = intr->type;
69+
*hwirq = fwspec->param[0];
70+
*type = intr->type;
71+
} else {
72+
/* Per-Line interrupt-type */
73+
if (fwspec->param_count != 2)
74+
return -EINVAL;
6975

76+
*hwirq = fwspec->param[0];
77+
*type = fwspec->param[1];
78+
}
7079
return 0;
7180
}
7281

@@ -128,11 +137,12 @@ static void ti_sci_intr_irq_domain_free(struct irq_domain *domain,
128137
* @domain: Pointer to the interrupt router IRQ domain
129138
* @virq: Corresponding Linux virtual IRQ number
130139
* @hwirq: Corresponding hwirq for the IRQ within this IRQ domain
140+
* @hwirq_type: Corresponding hwirq trigger type for the IRQ within this IRQ domain
131141
*
132142
* Returns intr output irq if all went well else appropriate error pointer.
133143
*/
134-
static int ti_sci_intr_alloc_parent_irq(struct irq_domain *domain,
135-
unsigned int virq, u32 hwirq)
144+
static int ti_sci_intr_alloc_parent_irq(struct irq_domain *domain, unsigned int virq,
145+
u32 hwirq, u32 hwirq_type)
136146
{
137147
struct ti_sci_intr_irq_domain *intr = domain->host_data;
138148
struct device_node *parent_node;
@@ -156,11 +166,22 @@ static int ti_sci_intr_alloc_parent_irq(struct irq_domain *domain,
156166
fwspec.param_count = 3;
157167
fwspec.param[0] = 0; /* SPI */
158168
fwspec.param[1] = p_hwirq - 32; /* SPI offset */
159-
fwspec.param[2] = intr->type;
169+
fwspec.param[2] = hwirq_type;
160170
} else {
161171
/* Parent is Interrupt Router */
162-
fwspec.param_count = 1;
163-
fwspec.param[0] = p_hwirq;
172+
u32 parent_trigger_type;
173+
174+
if (!of_property_read_u32(parent_node, "ti,intr-trigger-type",
175+
&parent_trigger_type)) {
176+
/* Parent has global trigger type */
177+
fwspec.param_count = 1;
178+
fwspec.param[0] = p_hwirq;
179+
} else {
180+
/* Parent supports per-line trigger types */
181+
fwspec.param_count = 2;
182+
fwspec.param[0] = p_hwirq;
183+
fwspec.param[1] = hwirq_type;
184+
}
164185
}
165186

166187
err = irq_domain_alloc_irqs_parent(domain, virq, 1, &fwspec);
@@ -196,15 +217,15 @@ static int ti_sci_intr_irq_domain_alloc(struct irq_domain *domain,
196217
void *data)
197218
{
198219
struct irq_fwspec *fwspec = data;
220+
unsigned int hwirq_type;
199221
unsigned long hwirq;
200-
unsigned int flags;
201222
int err, out_irq;
202223

203-
err = ti_sci_intr_irq_domain_translate(domain, fwspec, &hwirq, &flags);
224+
err = ti_sci_intr_irq_domain_translate(domain, fwspec, &hwirq, &hwirq_type);
204225
if (err)
205226
return err;
206227

207-
out_irq = ti_sci_intr_alloc_parent_irq(domain, virq, hwirq);
228+
out_irq = ti_sci_intr_alloc_parent_irq(domain, virq, hwirq, hwirq_type);
208229
if (out_irq < 0)
209230
return out_irq;
210231

@@ -247,12 +268,9 @@ static int ti_sci_intr_irq_domain_probe(struct platform_device *pdev)
247268
return -ENOMEM;
248269

249270
intr->dev = dev;
250-
ret = of_property_read_u32(dev_of_node(dev), "ti,intr-trigger-type",
251-
&intr->type);
252-
if (ret) {
253-
dev_err(dev, "missing ti,intr-trigger-type property\n");
254-
return -EINVAL;
255-
}
271+
272+
if (of_property_read_u32(dev_of_node(dev), "ti,intr-trigger-type", &intr->type))
273+
intr->type = IRQ_TYPE_NONE;
256274

257275
intr->sci = devm_ti_sci_get_by_phandle(dev, "ti,sci");
258276
if (IS_ERR(intr->sci))

0 commit comments

Comments
 (0)