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

Mark-PK Tsai
2020-08-19T13:31:51Z

From: Marc Zyngier <maz@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);
>