On Thu, 09 Dec 2021 04:32:48 +0000, Hector Martin <marcan@xxxxxxxxx> wrote: > > Multi-die support in AICv2 uses several sets of IRQ registers. Introduce > a die count and compute the register group offset based on the die ID > field of the hwirq number, as reported by the hardware. > > Signed-off-by: Hector Martin <marcan@xxxxxxxxx> > --- > drivers/irqchip/irq-apple-aic.c | 75 +++++++++++++++++++++++---------- > 1 file changed, 53 insertions(+), 22 deletions(-) > > diff --git a/drivers/irqchip/irq-apple-aic.c b/drivers/irqchip/irq-apple-aic.c > index d03caed51d56..46b7750548a0 100644 > --- a/drivers/irqchip/irq-apple-aic.c > +++ b/drivers/irqchip/irq-apple-aic.c [...] > @@ -535,28 +545,41 @@ static int aic_irq_domain_translate(struct irq_domain *id, > unsigned int *type) > { > struct aic_irq_chip *ic = id->host_data; > + u32 *args; > + u32 die = 0; > > - if (fwspec->param_count != 3 || !is_of_node(fwspec->fwnode)) > + if (fwspec->param_count < 3 || fwspec->param_count > 4 || > + !is_of_node(fwspec->fwnode)) > return -EINVAL; > > + args = &fwspec->param[1]; > + > + if (fwspec->param_count == 4) { > + die = args[0]; > + args++; > + } > + > switch (fwspec->param[0]) { > case AIC_IRQ: > - if (fwspec->param[1] >= ic->nr_irq) > + if (die >= ic->nr_die) > + return -EINVAL; > + if (args[0] >= ic->nr_irq) > return -EINVAL; > - *hwirq = (FIELD_PREP(AIC_EVENT_TYPE, AIC_EVENT_TYPE_HW) | > - FIELD_PREP(AIC_EVENT_NUM, fwspec->param[1])); > + *hwirq = AIC_IRQ_HWIRQ(die, args[0]); > break; A side issue with this is that it breaks MSIs, due to the way we construct the intspec (I did hit that when upgrading the M1 intspec to 4 cells for the PMU). I have the following hack locally: diff --git a/drivers/pci/controller/pcie-apple.c b/drivers/pci/controller/pcie-apple.c index b090924b41fe..f7b4a67b13cf 100644 --- a/drivers/pci/controller/pcie-apple.c +++ b/drivers/pci/controller/pcie-apple.c @@ -218,7 +218,7 @@ static int apple_msi_domain_alloc(struct irq_domain *domain, unsigned int virq, if (hwirq < 0) return -ENOSPC; - fwspec.param[1] += hwirq; + fwspec.param[1 + (fwspec.param_count == 4)] += hwirq; ret = irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, &fwspec); if (ret) Thanks, M. -- Without deviation from the norm, progress is not possible.