diff options
-rw-r--r-- | arch/powerpc/platforms/powernv/opal.c | 31 |
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 | ||
139 | static 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 | |||
138 | static int __init opal_init(void) | 150 | static 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 | } |
161 | subsys_initcall(opal_init); | 192 | subsys_initcall(opal_init); |