/* #define DEBUG */
-
-static void request_ras_irqs(struct device_node *np,
+static void request_ras_irqs(struct device_node *np, char *propname,
irqreturn_t (*handler)(int, void *, struct pt_regs *),
const char *name)
{
- int i, index, count = 0;
- struct of_irq oirq;
- u32 *opicprop;
- unsigned int opicplen;
- unsigned int virqs[16];
-
- /* Check for obsolete "open-pic-interrupt" property. If present, then
- * map those interrupts using the default interrupt host and default
- * trigger
- */
- opicprop = (u32 *)get_property(np, "open-pic-interrupt", &opicplen);
- if (opicprop) {
- opicplen /= sizeof(u32);
- for (i = 0; i < opicplen; i++) {
- if (count > 15)
- break;
- virqs[count] = irq_create_mapping(NULL, *(opicprop++));
- if (virqs[count] == NO_IRQ)
- printk(KERN_ERR "Unable to allocate interrupt "
- "number for %s\n", np->full_name);
- else
- count++;
-
- }
- }
- /* Else use normal interrupt tree parsing */
- else {
- /* First try to do a proper OF tree parsing */
- for (index = 0; of_irq_map_one(np, index, &oirq) == 0;
- index++) {
- if (count > 15)
- break;
- virqs[count] = irq_create_of_mapping(oirq.controller,
- oirq.specifier,
- oirq.size);
- if (virqs[count] == NO_IRQ)
- printk(KERN_ERR "Unable to allocate interrupt "
- "number for %s\n", np->full_name);
- else
- count++;
+ unsigned int *ireg, len, i;
+ int virq, n_intr;
+
+ ireg = (unsigned int *)get_property(np, propname, &len);
+ if (ireg == NULL)
+ return;
+ n_intr = prom_n_intr_cells(np);
+ len /= n_intr * sizeof(*ireg);
+
+ for (i = 0; i < len; i++) {
+ virq = virt_irq_create_mapping(*ireg);
+ if (virq == NO_IRQ) {
+ printk(KERN_ERR "Unable to allocate interrupt "
+ "number for %s\n", np->full_name);
+ return;
}
- }
-
- /* Now request them */
- for (i = 0; i < count; i++) {
- if (request_irq(virqs[i], handler, 0, name, NULL)) {
+ if (request_irq(irq_offset_up(virq), handler, 0, name, NULL)) {
printk(KERN_ERR "Unable to request interrupt %d for "
- "%s\n", virqs[i], np->full_name);
+ "%s\n", irq_offset_up(virq), np->full_name);
return;
}
+ ireg += n_intr;
}
}
/* Internal Errors */
np = of_find_node_by_path("/event-sources/internal-errors");
if (np != NULL) {
- request_ras_irqs(np, ras_error_interrupt, "RAS_ERROR");
+ request_ras_irqs(np, "open-pic-interrupt", ras_error_interrupt,
+ "RAS_ERROR");
+ request_ras_irqs(np, "interrupts", ras_error_interrupt,
+ "RAS_ERROR");
of_node_put(np);
}
/* EPOW Events */
np = of_find_node_by_path("/event-sources/epow-events");
if (np != NULL) {
- request_ras_irqs(np, ras_epow_interrupt, "RAS_EPOW");
+ request_ras_irqs(np, "open-pic-interrupt", ras_epow_interrupt,
+ "RAS_EPOW");
+ request_ras_irqs(np, "interrupts", ras_epow_interrupt,
+ "RAS_EPOW");
of_node_put(np);
}
- return 0;
+ return 1;
}
__initcall(init_ras_IRQ);
status = rtas_call(ras_check_exception_token, 6, 1, NULL,
RAS_VECTOR_OFFSET,
- irq_map[irq].hwirq,
+ virt_irq_to_real(irq_offset_down(irq)),
RTAS_EPOW_WARNING | RTAS_POWERMGM_EVENTS,
critical, __pa(&ras_log_buf),
rtas_get_error_log_max());
status = rtas_call(ras_check_exception_token, 6, 1, NULL,
RAS_VECTOR_OFFSET,
- irq_map[irq].hwirq,
+ virt_irq_to_real(irq_offset_down(irq)),
RTAS_INTERNAL_ERROR, 1 /*Time Critical */,
__pa(&ras_log_buf),
rtas_get_error_log_max());