Skip to content

Commit 2717a33

Browse files
ozbenhmpe
authored andcommitted
powerpc/opal-irqchip: Use interrupt names if present
Recent versions of OPAL can provide names for the various OPAL interrupts, so let's use them. This also modernises the code that fetches the interrupt array to use the helpers provided by the generic code instead of hand-parsing the property. Signed-off-by: Benjamin Herrenschmidt <[email protected]> [mpe: Free irqs on error, check allocation of names, consolidate error handling, whitespace.] Signed-off-by: Michael Ellerman <[email protected]>
1 parent 470a36a commit 2717a33

File tree

1 file changed

+42
-13
lines changed

1 file changed

+42
-13
lines changed

arch/powerpc/platforms/powernv/opal-irqchip.c

Lines changed: 42 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -183,8 +183,9 @@ void opal_event_shutdown(void)
183183
int __init opal_event_init(void)
184184
{
185185
struct device_node *dn, *opal_node;
186-
const __be32 *irqs;
187-
int i, irqlen, rc = 0;
186+
const char **names;
187+
u32 *irqs;
188+
int i, rc;
188189

189190
opal_node = of_find_node_by_path("/ibm,opal");
190191
if (!opal_node) {
@@ -209,38 +210,66 @@ int __init opal_event_init(void)
209210
goto out;
210211
}
211212

212-
/* Get interrupt property */
213-
irqs = of_get_property(opal_node, "opal-interrupts", &irqlen);
214-
opal_irq_count = irqs ? (irqlen / 4) : 0;
213+
/* Get opal-interrupts property and names if present */
214+
rc = of_property_count_u32_elems(opal_node, "opal-interrupts");
215+
if (rc < 0)
216+
goto out;
217+
218+
opal_irq_count = rc;
215219
pr_debug("Found %d interrupts reserved for OPAL\n", opal_irq_count);
216220

217-
/* Install interrupt handlers */
221+
irqs = kcalloc(opal_irq_count, sizeof(*irqs), GFP_KERNEL);
222+
names = kcalloc(opal_irq_count, sizeof(*names), GFP_KERNEL);
218223
opal_irqs = kcalloc(opal_irq_count, sizeof(*opal_irqs), GFP_KERNEL);
219-
for (i = 0; irqs && i < opal_irq_count; i++, irqs++) {
220-
unsigned int irq, virq;
224+
225+
if (WARN_ON(!irqs || !names || !opal_irqs))
226+
goto out_free;
227+
228+
rc = of_property_read_u32_array(opal_node, "opal-interrupts",
229+
irqs, opal_irq_count);
230+
if (rc < 0) {
231+
pr_err("Error %d reading opal-interrupts array\n", rc);
232+
goto out_free;
233+
}
234+
235+
/* It's not an error for the names to be missing */
236+
of_property_read_string_array(opal_node, "opal-interrupts-names",
237+
names, opal_irq_count);
238+
239+
/* Install interrupt handlers */
240+
for (i = 0; i < opal_irq_count; i++) {
241+
unsigned int virq;
242+
char *name;
221243

222244
/* Get hardware and virtual IRQ */
223-
irq = be32_to_cpup(irqs);
224-
virq = irq_create_mapping(NULL, irq);
245+
virq = irq_create_mapping(NULL, irqs[i]);
225246
if (!virq) {
226-
pr_warn("Failed to map irq 0x%x\n", irq);
247+
pr_warn("Failed to map irq 0x%x\n", irqs[i]);
227248
continue;
228249
}
229250

251+
if (names[i] && strlen(names[i]))
252+
name = kasprintf(GFP_KERNEL, "opal-%s", names[i]);
253+
else
254+
name = kasprintf(GFP_KERNEL, "opal");
255+
230256
/* Install interrupt handler */
231257
rc = request_irq(virq, opal_interrupt, IRQF_TRIGGER_LOW,
232-
"opal", NULL);
258+
name, NULL);
233259
if (rc) {
234260
irq_dispose_mapping(virq);
235261
pr_warn("Error %d requesting irq %d (0x%x)\n",
236-
rc, virq, irq);
262+
rc, virq, irqs[i]);
237263
continue;
238264
}
239265

240266
/* Cache IRQ */
241267
opal_irqs[i] = virq;
242268
}
243269

270+
out_free:
271+
kfree(irqs);
272+
kfree(names);
244273
out:
245274
of_node_put(opal_node);
246275
return rc;

0 commit comments

Comments
 (0)