diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2018-04-10 17:01:54 +1000 |
---|---|---|
committer | Stewart Smith <stewart@linux.ibm.com> | 2018-04-11 17:59:57 -0500 |
commit | 9c21cae5aac4246ac4e438cac5a96a24907676c7 (patch) | |
tree | 2a68c58cc0adff8abc234105bb2a548885f9a995 /core/interrupts.c | |
parent | 379ec78e3da982cd1dff1533d50a9b29b025db5b (diff) | |
download | skiboot-9c21cae5aac4246ac4e438cac5a96a24907676c7.zip skiboot-9c21cae5aac4246ac4e438cac5a96a24907676c7.tar.gz skiboot-9c21cae5aac4246ac4e438cac5a96a24907676c7.tar.bz2 |
interrupts: Create an "interrupts" property in the OPAL node
Deprecate the old "opal-interrupts", it's still there, but the new
property follows the standard and allow us to specify whether an
interrupt is level or edge sensitive.
Similarly create "interrupt-names" whose content is identical to
"opal-interrupts-names".
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Stewart Smith <stewart@linux.ibm.com>
Diffstat (limited to 'core/interrupts.c')
-rw-r--r-- | core/interrupts.c | 33 |
1 files changed, 26 insertions, 7 deletions
diff --git a/core/interrupts.c b/core/interrupts.c index 9161960..50ff77a 100644 --- a/core/interrupts.c +++ b/core/interrupts.c @@ -224,14 +224,21 @@ void add_opal_interrupts(void) continue; for (isn = is->start; isn < is->end; isn++) { uint64_t attr = is->ops->attributes(is, isn); + uint32_t iflags; char *name; if (attr & IRQ_ATTR_TARGET_LINUX) continue; + if (attr & IRQ_ATTR_TYPE_MSI) + iflags = 0; + else + iflags = 1; name = is->ops->name ? is->ops->name(is, isn) : NULL; ns = name ? strlen(name) : 0; - prlog(PR_DEBUG, "irq %x name: %s (%d/%d)\n", - isn, name ? name : "<null>", ns, tns); + prlog(PR_DEBUG, "irq %x name: %s %s\n", + isn, + name ? name : "<null>", + iflags ? "[level]" : "[edge]"); names = realloc(names, tns + ns + 1); if (name) { strcpy(names + tns, name); @@ -240,20 +247,32 @@ void add_opal_interrupts(void) } else names[tns++] = 0; i = count++; - irqs = realloc(irqs, 4 * count); - irqs[i] = isn; + irqs = realloc(irqs, 8 * count); + irqs[i*2] = isn; + irqs[i*2+1] = iflags; } } unlock(&irq_lock); - /* The opal-interrupts property has one cell per interrupt, - * it is not a standard interrupt property. + /* First create the standard "interrupts" property and the + * corresponding names property + */ + dt_add_property_cells(opal_node, "interrupt-parent", get_ics_phandle()); + dt_add_property(opal_node, "interrupts", irqs, count * 8); + dt_add_property(opal_node, "opal-interrupts-names", names, tns); + dt_add_property(opal_node, "interrupt-names", names, tns); + + /* Now "reduce" it to the old style "opal-interrupts" property + * format by stripping out the flags. The "opal-interrupts" + * property has one cell per interrupt, it is not a standard + * "interrupt" property. * * Note: Even if empty, create it, otherwise some bogus error * handling in Linux can cause problems. */ + for (i = 1; i < count; i++) + irqs[i] = irqs[i * 2]; dt_add_property(opal_node, "opal-interrupts", irqs, count * 4); - dt_add_property(opal_node, "opal-interrupts-names", names, tns); free(irqs); free(names); |