sh: intc: Handle early lookups of subgroup IRQs.
[pandora-kernel.git] / drivers / sh / intc.c
index c81fe23..d4325c7 100644 (file)
@@ -927,19 +927,35 @@ static unsigned int __init intc_sense_data(struct intc_desc *desc,
        return 0;
 }
 
-unsigned int intc_irq_lookup(const char *chipname, intc_enum enum_id)
+#define INTC_TAG_VIRQ_NEEDS_ALLOC      0
+
+int intc_irq_lookup(const char *chipname, intc_enum enum_id)
 {
        struct intc_map_entry *ptr;
        struct intc_desc_int *d;
-       unsigned int irq = 0;
+       int irq = -1;
 
        list_for_each_entry(d, &intc_list, list) {
-               if (strcmp(d->chip.name, chipname) == 0) {
-                       ptr = radix_tree_lookup(&d->tree, enum_id);
-                       if (ptr) {
-                               irq = ptr - intc_irq_xlate;
-                               break;
-                       }
+               int tagged;
+
+               if (strcmp(d->chip.name, chipname) != 0)
+                       continue;
+
+               /*
+                * Catch early lookups for subgroup VIRQs that have not
+                * yet been allocated an IRQ. This already includes a
+                * fast-path out if the tree is untagged, so there is no
+                * need to explicitly test the root tree.
+                */
+               tagged = radix_tree_tag_get(&d->tree, enum_id,
+                                           INTC_TAG_VIRQ_NEEDS_ALLOC);
+               if (unlikely(tagged))
+                       break;
+
+               ptr = radix_tree_lookup(&d->tree, enum_id);
+               if (ptr) {
+                       irq = ptr - intc_irq_xlate;
+                       break;
                }
        }
 
@@ -1003,8 +1019,6 @@ static unsigned long __init intc_subgroup_data(struct intc_subgroup *subgroup,
                        0, 1, (subgroup->reg_width - 1) - index);
 }
 
-#define INTC_TAG_VIRQ_NEEDS_ALLOC      0
-
 static void __init intc_subgroup_init_one(struct intc_desc *desc,
                                          struct intc_desc_int *d,
                                          struct intc_subgroup *subgroup)