diff options
Diffstat (limited to 'drivers/sh/intc/virq.c')
| -rw-r--r-- | drivers/sh/intc/virq.c | 24 |
1 files changed, 16 insertions, 8 deletions
diff --git a/drivers/sh/intc/virq.c b/drivers/sh/intc/virq.c index 4e0ff718116..f30ac9354ff 100644 --- a/drivers/sh/intc/virq.c +++ b/drivers/sh/intc/virq.c @@ -14,9 +14,10 @@ #include <linux/list.h> #include <linux/radix-tree.h> #include <linux/spinlock.h> +#include <linux/export.h> #include "internals.h" -static struct intc_map_entry intc_irq_xlate[NR_IRQS]; +static struct intc_map_entry intc_irq_xlate[INTC_NR_IRQS]; struct intc_virq_list { unsigned int irq; @@ -110,7 +111,7 @@ static void intc_virq_handler(unsigned int irq, struct irq_desc *desc) { struct irq_data *data = irq_get_irq_data(irq); struct irq_chip *chip = irq_data_get_irq_chip(data); - struct intc_virq_list *entry, *vlist = irq_data_get_irq_data(data); + struct intc_virq_list *entry, *vlist = irq_data_get_irq_handler_data(data); struct intc_desc_int *d = get_intc_desc(irq); chip->irq_mask_ack(data); @@ -118,7 +119,7 @@ static void intc_virq_handler(unsigned int irq, struct irq_desc *desc) for_each_virq(entry, vlist) { unsigned long addr, handle; - handle = (unsigned long)get_irq_data(entry->irq); + handle = (unsigned long)irq_get_handler_data(entry->irq); addr = INTC_REG(d, _INTC_ADDR_E(handle), 0); if (intc_reg_fns[_INTC_FN(handle)](addr, handle, 0)) @@ -218,24 +219,31 @@ restart: if (radix_tree_deref_retry(entry)) goto restart; - irq = create_irq(); + irq = irq_alloc_desc(numa_node_id()); if (unlikely(irq < 0)) { pr_err("no more free IRQs, bailing..\n"); break; } + activate_irq(irq); + pr_info("Setting up a chained VIRQ from %d -> %d\n", irq, entry->pirq); intc_irq_xlate_set(irq, entry->enum_id, d); - set_irq_chip_and_handler_name(irq, get_irq_chip(entry->pirq), + irq_set_chip_and_handler_name(irq, irq_get_chip(entry->pirq), handle_simple_irq, "virq"); - set_irq_chip_data(irq, get_irq_chip_data(entry->pirq)); + irq_set_chip_data(irq, irq_get_chip_data(entry->pirq)); + + irq_set_handler_data(irq, (void *)entry->handle); - set_irq_data(irq, (void *)entry->handle); + /* + * Set the virtual IRQ as non-threadable. + */ + irq_set_nothread(irq); - set_irq_chained_handler(entry->pirq, intc_virq_handler); + irq_set_chained_handler(entry->pirq, intc_virq_handler); add_virq_to_pirq(entry->pirq, irq); radix_tree_tag_clear(&d->tree, entry->enum_id, |
