• Barry Song's avatar
    pinctrl: sirf: use only one irq_domain for the whole device node · 8daeffb0
    Barry Song authored
    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: default avatarBarry Song <Baohua.Song@csr.com>
    Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
    8daeffb0
pinctrl-sirf.c 23.6 KB