Hi Marc,
On Thu, 6 Aug 2020 at 01:26, Marc Zyngier <maz@xxxxxxxxxx> wrote:
> +struct msc313_intc {
> + struct irq_domain *domain;
> + void __iomem *base;
> + struct irq_chip irqchip;
Why do you need to embed the irq_chip on a per-controller basis?
Current chips have 1 instance of each type of controller but some of the
newer ones seem to have an extra copy of the non-FIQ version with different
offset to the GIC.
> +};
> +
> +static void msc313_intc_maskunmask(struct msc313_intc *intc, int
> hwirq, bool mask)
> +{
> + int regoff = REGOFF(hwirq);
> + void __iomem *addr = intc->base + REGOFF_MASK + regoff;
> + u16 bit = IRQBIT(hwirq);
> + u16 reg = readw_relaxed(addr);
> +
> + if (mask)
> + reg |= bit;
> + else
> + reg &= ~bit;
> +
> + writew_relaxed(reg, addr);
RMW on a shared MMIO register. Not going to end well. This is valid
for all the callbacks, I believe.
Do you have any suggestions on how to resolve that? It seems usually
an interrupt controller has set and clear registers to get around this.
Would defining a spinlock at the top of the driver and using that around
the read and modify sequences be good enough?
> +
> + if (flow_type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_LEVEL_HIGH))
> + reg &= ~bit;
> + else
> + reg |= bit;
I don't follow grasp the logic here. What happens on EDGE_BOTH, for
example?
To be honest I don't quite remember. I'll check and rewrite this.
This driver has a massive feeling of déja-vu. It is almost
a copy of the one posted at [1], which I reviewed early
this week. The issues are the exact same, and I'm 98%
sure this is the same IP block used by two SoC vendors.
This would make a lot of sense considering MediaTek bought MStar
for their TV SoCs. The weirdness with only using 16 bits in a register
suggests they've inherited the shared ARM/8051 bus that the MStar
chips have. Thanks for the tip off.