Hi, Bibo, This patch is correct in theory, but since we use a hard-coded method in the first place, there may be buggy BIOS, especially for multi-bridge machines. So I hope someone can help me to test as many machines as possible, and then give feedback to this mail. Huacai On Fri, Dec 13, 2024 at 11:50 AM Bibo Mao <maobibo@xxxxxxxxxxx> wrote: > > Interrupt controller eiointc routes irq to cpu interface IP0 - IP7, > now it is hard-coded that eiointc routes irq to CPU started from IP1, > however with function irq_create_mapping() parameter parent hwirq > uses irq parsed from ACPI or DTS table. > > Routed interrupt pin need be the consistent with parent hwirq. > > Signed-off-by: Bibo Mao <maobibo@xxxxxxxxxxx> > --- > drivers/irqchip/irq-loongson-eiointc.c | 19 ++++++++++++++++--- > 1 file changed, 16 insertions(+), 3 deletions(-) > > diff --git a/drivers/irqchip/irq-loongson-eiointc.c b/drivers/irqchip/irq-loongson-eiointc.c > index bb79e19dfb59..72979f9f0e05 100644 > --- a/drivers/irqchip/irq-loongson-eiointc.c > +++ b/drivers/irqchip/irq-loongson-eiointc.c > @@ -68,6 +68,7 @@ struct eiointc_priv { > struct fwnode_handle *domain_handle; > struct irq_domain *eiointc_domain; > int flags; > + irq_hw_number_t parent_hwirq; > }; > > static struct eiointc_priv *eiointc_priv[MAX_IO_PICS]; > @@ -211,7 +212,12 @@ static int eiointc_router_init(unsigned int cpu) > } > > for (i = 0; i < eiointc_priv[0]->vec_count / 32 / 4; i++) { > - bit = BIT(1 + index); /* Route to IP[1 + index] */ > + /* > + * Route to interrupt pin, relative offset used here > + * Offset 0 means routing to IP0 and so on > + * Every 32 vector routing to one interrupt pin > + */ > + bit = BIT(eiointc_priv[index]->parent_hwirq - INT_HWI0); > data = bit | (bit << 8) | (bit << 16) | (bit << 24); > iocsr_write32(data, EIOINTC_REG_IPMAP + i * 4); > } > @@ -495,7 +501,7 @@ int __init eiointc_acpi_init(struct irq_domain *parent, > > priv->vec_count = VEC_COUNT; > priv->node = acpi_eiointc->node; > - > + priv->parent_hwirq = acpi_eiointc->cascade; > parent_irq = irq_create_mapping(parent, acpi_eiointc->cascade); > > ret = eiointc_init(priv, parent_irq, acpi_eiointc->node_map); > @@ -529,6 +535,7 @@ static int __init eiointc_of_init(struct device_node *of_node, > { > int parent_irq, ret; > struct eiointc_priv *priv; > + struct irq_data *irq_data; > > priv = kzalloc(sizeof(*priv), GFP_KERNEL); > if (!priv) > @@ -544,6 +551,12 @@ static int __init eiointc_of_init(struct device_node *of_node, > if (ret < 0) > goto out_free_priv; > > + irq_data = irq_get_irq_data(parent_irq); > + if (!irq_data) { > + ret = -ENODEV; > + goto out_free_priv; > + } > + > /* > * In particular, the number of devices supported by the LS2K0500 > * extended I/O interrupt vector is 128. > @@ -555,7 +568,7 @@ static int __init eiointc_of_init(struct device_node *of_node, > > priv->node = 0; > priv->domain_handle = of_node_to_fwnode(of_node); > - > + priv->parent_hwirq = irqd_to_hwirq(irq_data); > ret = eiointc_init(priv, parent_irq, 0); > if (ret < 0) > goto out_free_priv; > -- > 2.39.3 >