aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2011-09-19 13:45:03 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2011-09-20 02:10:01 -0400
commita125e0928c736bc50cdd9a13151d4f4ee7821266 (patch)
treed7818f37855048e8214de79b3c322ff7a33406b5 /arch/powerpc
parent5c7c1e9444d8bfb721a27a35bba3eeb5236c75d8 (diff)
powerpc/powernv: Register and handle OPAL interrupts
We do the minimum which is to "pass" interrupts to HAL, which makes the console smoother and will allow us to implement interrupt based completion and console. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/platforms/powernv/opal.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c
index 7887733b9b31..5a598caefcba 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -14,6 +14,7 @@
14#include <linux/types.h> 14#include <linux/types.h>
15#include <linux/of.h> 15#include <linux/of.h>
16#include <linux/of_platform.h> 16#include <linux/of_platform.h>
17#include <linux/interrupt.h>
17#include <asm/opal.h> 18#include <asm/opal.h>
18#include <asm/firmware.h> 19#include <asm/firmware.h>
19 20
@@ -135,9 +136,22 @@ int opal_put_chars(uint32_t vtermno, const char *data, int total_len)
135 return written; 136 return written;
136} 137}
137 138
139static irqreturn_t opal_interrupt(int irq, void *data)
140{
141 uint64_t events;
142
143 opal_handle_interrupt(virq_to_hw(irq), &events);
144
145 /* XXX TODO: Do something with the events */
146
147 return IRQ_HANDLED;
148}
149
138static int __init opal_init(void) 150static int __init opal_init(void)
139{ 151{
140 struct device_node *np, *consoles; 152 struct device_node *np, *consoles;
153 const u32 *irqs;
154 int rc, i, irqlen;
141 155
142 opal_node = of_find_node_by_path("/ibm,opal"); 156 opal_node = of_find_node_by_path("/ibm,opal");
143 if (!opal_node) { 157 if (!opal_node) {
@@ -156,6 +170,23 @@ static int __init opal_init(void)
156 of_platform_device_create(np, NULL, NULL); 170 of_platform_device_create(np, NULL, NULL);
157 } 171 }
158 of_node_put(consoles); 172 of_node_put(consoles);
173
174 /* Find all OPAL interrupts and request them */
175 irqs = of_get_property(opal_node, "opal-interrupts", &irqlen);
176 pr_debug("opal: Found %d interrupts reserved for OPAL\n",
177 irqs ? (irqlen / 4) : 0);
178 for (i = 0; irqs && i < (irqlen / 4); i++, irqs++) {
179 unsigned int hwirq = be32_to_cpup(irqs);
180 unsigned int irq = irq_create_mapping(NULL, hwirq);
181 if (irq == NO_IRQ) {
182 pr_warning("opal: Failed to map irq 0x%x\n", hwirq);
183 continue;
184 }
185 rc = request_irq(irq, opal_interrupt, 0, "opal", NULL);
186 if (rc)
187 pr_warning("opal: Error %d requesting irq %d"
188 " (0x%x)\n", rc, irq, hwirq);
189 }
159 return 0; 190 return 0;
160} 191}
161subsys_initcall(opal_init); 192subsys_initcall(opal_init);