pinctrl: sirf: use only one irq_domain for the whole device node
authorBarry Song <Baohua.Song@csr.com>
Sat, 11 Jan 2014 08:48:42 +0000 (16:48 +0800)
committerLinus Walleij <linus.walleij@linaro.org>
Wed, 15 Jan 2014 08:07:56 +0000 (09:07 +0100)
commit8daeffb058f78deb0b0ef2cb67ef741c38788bf9
treed7725a9eb7d4d6127beccd1ff85e92614a74ec64
parentad5d25fef8f9459a9f67ec5fbae94287fdea3247
pinctrl: sirf: use only one irq_domain for the whole device node

in sirfsoc gpio probe(), we create 5 irq_domains for 5 gpio banks. but
in irq_create_of_mapping() of irqchip core level, irq_find_host() can
only return the 1st irq_domain attached the pinctrl dt device node as
we can see from the codes:

unsigned int irq_create_of_mapping(struct device_node *controller,
   const u32 *intspec, unsigned int intsize)
{
struct irq_domain *domain;
...
domain = controller ? irq_find_host(controller) : irq_default_domain;
}

struct irq_domain *irq_find_host(struct device_node *node)
{
struct irq_domain *h, *found = NULL;
int rc;

/* We might want to match the legacy controller last since
 * it might potentially be set to match all interrupts in
 * the absence of a device node. This isn't a problem so far
 * yet though...
 */
mutex_lock(&irq_domain_mutex);
list_for_each_entry(h, &irq_domain_list, link) {
if (h->ops->match)
rc = h->ops->match(h, node);
else
rc = (h->of_node != NULL) && (h->of_node == node);

if (rc) {
found = h;
break;
}
}
mutex_unlock(&irq_domain_mutex);
return found;
}

for sirfsoc, the 1st irq_domain attached to the device_node(controller) only
can do linear for the 1st 32 gpios. so for devices who use gpio hwirq above
32 and put the information in dt like:
                                tangoc-ts@5c{
                                        compatible = "pixcir,tangoc-ts";
+                                       interrupt-parent = <&gpio>;
+                                       interrupts = <34 0>;
                                };

we will fail to get the virq for these devices as hwirq will be bigger than
domain->revmap_data.linear.size in:
unsigned int irq_linear_revmap(struct irq_domain *domain,
       irq_hw_number_t hwirq)
{

/* Check revmap bounds; complain if exceeded */
if (WARN_ON(hwirq >= domain->revmap_data.linear.size))
return 0;

return domain->revmap_data.linear.revmap[hwirq];
}

this patch drops redundant irq_domain and keep only one to fix the problem.

Signed-off-by: Barry Song <Baohua.Song@csr.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
drivers/pinctrl/sirf/pinctrl-sirf.c