[PATCH 1/2] irqchip: irq-mst: Add MStar interrupt controller support

Mark-PK Tsai mark-pk.tsai at mediatek.com
Wed Aug 19 09:31:18 EDT 2020


From: Marc Zyngier <maz at kernel.org>

> > +
> > +static int mst_intc_domain_alloc(struct irq_domain *domain, unsigned 
> > int virq,
> > +				 unsigned int nr_irqs, void *data)
> > +{
> > +	int i;
> > +	irq_hw_number_t hwirq;
> > +	struct irq_fwspec parent_fwspec, *fwspec = data;
> > +	struct mst_intc_chip_data *cd = (struct mst_intc_chip_data
> > *)domain->host_data;
> 
> No cast necessary here.
> 
> > +
> > +	/* Not GIC compliant */
> > +	if (fwspec->param_count != 3)
> > +		return -EINVAL;
> > +
> > +	/* No PPI should point to this domain */
> > +	if (fwspec->param[0])
> > +		return -EINVAL;
> > +
> > +	if (fwspec->param[1] >= cd->nr_irqs)
> 
> This condition is bogus, as it doesn't take into account the nr_irqs
> parameter.
> 


The hwirq number need to be in the irq map range. (property: mstar,irqs-map-range)
If it's not, it must be incorrect configuration.
So how about use the condition as following?

if (hwirq >= cd->nr_irqs)
	return -EINVAL;

> > +		return -EINVAL;
> > +
> > +	hwirq = fwspec->param[1];
> > +	for (i = 0; i < nr_irqs; i++)
> > +		irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i,
> > +					      &mst_intc_chip,
> > +					      domain->host_data);
> > +
> > +	parent_fwspec = *fwspec;
> > +	parent_fwspec.fwnode = domain->parent->fwnode;
> > +	parent_fwspec.param[1] = cd->irq_start + hwirq;
> > +	return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, 
> > &parent_fwspec);
> > +}
> > +
> > +static const struct irq_domain_ops mst_intc_domain_ops = {
> > +	.translate	= mst_intc_domain_translate,
> > +	.alloc		= mst_intc_domain_alloc,
> > +	.free		= irq_domain_free_irqs_common,
> > +};
> > +
> > +int __init
> > +mst_intc_of_init(struct device_node *dn, struct device_node *parent)
> > +{
> > +	struct irq_domain *domain, *domain_parent;
> > +	struct mst_intc_chip_data *cd;
> > +	unsigned int irq_start, irq_end;
> 
> unsigned int != u32.
> 
> > +
> > +	domain_parent = irq_find_host(parent);
> > +	if (!domain_parent) {
> > +		pr_err("mst-intc: interrupt-parent not found\n");
> > +		return -EINVAL;
> > +	}
> > +
> > +	if (of_property_read_u32_index(dn, "mstar,irqs-map-range", 0, 
> > &irq_start) ||
> > +	    of_property_read_u32_index(dn, "mstar,irqs-map-range", 1, 
> > &irq_end))
> > +		return -EINVAL;
> > +
> > +	cd = kzalloc(sizeof(*cd), GFP_KERNEL);
> > +	if (!cd)
> > +		return -ENOMEM;
> > +
> > +	cd->base = of_iomap(dn, 0);
> > +	if (!cd->base) {
> > +		kfree(cd);
> > +		return -ENOMEM;
> > +	}
> > +
> > +	cd->no_eoi = of_property_read_bool(dn, "mstar,intc-no-eoi");
> > +	raw_spin_lock_init(&cd->lock);
> > +	cd->irq_start = irq_start;
> > +	cd->nr_irqs = irq_end - irq_start + 1;
> > +	domain = irq_domain_add_hierarchy(domain_parent, 0, cd->nr_irqs, dn,
> > +					  &mst_intc_domain_ops, cd);
> > +	if (!domain) {
> > +		iounmap(cd->base);
> > +		kfree(cd);
> > +		return -ENOMEM;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +IRQCHIP_DECLARE(mst_intc, "mstar,mst-intc", mst_intc_of_init);
> 


More information about the Linux-mediatek mailing list