10 #define pr_fmt(fmt) "intc: " fmt
12 #include <linux/slab.h>
14 #include <linux/list.h>
17 #include <linux/export.h>
27 #define for_each_virq(entry, head) \
28 for (entry = head; entry; entry = entry->next)
33 #define INTC_TAG_VIRQ_NEEDS_ALLOC 0
40 intc_irq_xlate[
irq].enum_id =
id;
41 intc_irq_xlate[
irq].desc =
d;
47 return intc_irq_xlate + irq;
75 irq = ptr - intc_irq_xlate;
84 static int add_virq_to_pirq(
unsigned int irq,
unsigned int virq)
92 if (entry->
irq == virq)
99 pr_err(
"can't allocate VIRQ mapping for %d\n", virq);
110 static void intc_virq_handler(
unsigned int irq,
struct irq_desc *
desc)
122 handle = (
unsigned long)irq_get_handler_data(entry->
irq);
139 0, 1, (subgroup->
reg_width - 1) - index);
157 pirq = mapped - intc_irq_xlate;
174 entry->
handle = intc_subgroup_data(subgroup, d, i);
191 if (!desc->
hw.subgroups)
194 for (i = 0; i < desc->
hw.nr_subgroups; i++)
195 intc_subgroup_init_one(desc, d, desc->
hw.subgroups + i);
202 unsigned int nr_found;
212 for (i = 0; i < nr_found; i++) {
216 entry = radix_tree_deref_slot((
void **)entries[i]);
219 if (radix_tree_deref_retry(entry))
224 pr_err(
"no more free IRQs, bailing..\n");
230 pr_info(
"Setting up a chained VIRQ from %d -> %d\n",
244 irq_set_nothread(irq);
246 irq_set_chained_handler(entry->
pirq, intc_virq_handler);
247 add_virq_to_pirq(entry->
pirq, irq);
251 radix_tree_replace_slot((
void **)entries[i],
252 &intc_irq_xlate[irq]);
264 intc_subgroup_map(d);