Message ID | 20230713032243.2046205-3-maobibo@loongson.cn |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:a6b2:0:b0:3e4:2afc:c1 with SMTP id c18csp1568755vqm; Wed, 12 Jul 2023 20:45:02 -0700 (PDT) X-Google-Smtp-Source: APBJJlEgy4RD3tH7JaYXeM2CHzsR8AC3TxPcPCSYFmZcRqDap9kGMPgNzJ86mLs30AxdXhsTG6LM X-Received: by 2002:a17:906:1009:b0:974:1d8b:ca5f with SMTP id 9-20020a170906100900b009741d8bca5fmr306758ejm.9.1689219902124; Wed, 12 Jul 2023 20:45:02 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1689219902; cv=none; d=google.com; s=arc-20160816; b=BrdDHHAycn8SaPq8L6JeUUIjy/gVZv0Gonv/8BAUcVfuAQeO46sygqyQcOeUzzS4bn 7AzefZgYlYi0n6s56onM9l9NiDIJxzndVAoiwLxv1lFIJDu4km3hvWpGoiKxN4jD7Y7h HYxcXp2RuAeAzjDRcmsqBnWMR6uYV9UQXq//qcB395lUeDrSSvSZSOxRNkSgVAT9UAn9 KqyIAV18F01tniwdTv1DupuWGDYMTOB1K9PNePNZ5z6T1zKsVRTvUTz2tXG9bGWFcTty TJ7mPC8o6woxK1O0H3HbJTeDmkvqD9S2Wq424rWFsu9Fi/jFKwVGl4irMqCKNhgZTS9M RZaQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=TkBviVDwSihd9LtyWgVaEbV4f+rzp93u2Y5XnBFeocw=; fh=qZLgqBrA0TDTemqgHICeSNHVLsTK7kq22SqPqkiag9M=; b=XIyuhNc9PNkJvNIgSLzQX8QP9zB0zJB98C0RK0swSdnHrla36JFD21OsX7o7yYh6o8 UEYJtCRqMVLUzeEGJ1bEYNR7Db+pRsFNyMVpmXh+rwlX1zN6wyNZtWtRUYnzCwGMeLw0 VaGOq7PSKN2qIBqHjtJi1sWDoK6sk87AzAe1HgUW/N2lhwUBDFNGZY6bxKO2T7wBrSE4 5ttC27SOvN3mIP/5O+n0/3PPgP8wPW1TPhaCreX0AroLY5xnX9zd2JGVVPqye8lToLLn oLOIbEwoKQOqOjxPqN9sG0YN8ylJOop9kLJNI0a2uJxpSUZhxIxADj9mSVoa2Wp+5sb+ HPZQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id gy8-20020a170906f24800b00992be132d85si6387027ejb.853.2023.07.12.20.44.37; Wed, 12 Jul 2023 20:45:02 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233615AbjGMDXR (ORCPT <rfc822;ybw1215001957@gmail.com> + 99 others); Wed, 12 Jul 2023 23:23:17 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43292 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233606AbjGMDXL (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Wed, 12 Jul 2023 23:23:11 -0400 Received: from mail.loongson.cn (mail.loongson.cn [114.242.206.163]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 28DE91FD8; Wed, 12 Jul 2023 20:22:54 -0700 (PDT) Received: from loongson.cn (unknown [10.2.9.158]) by gateway (Coremail) with SMTP id _____8Dx_+sMbq9kaEQEAA--.10908S3; Thu, 13 Jul 2023 11:22:52 +0800 (CST) Received: from kvm-1-158.loongson.cn (unknown [10.2.9.158]) by localhost.localdomain (Coremail) with SMTP id AQAAf8CxbSMDbq9kz6MrAA--.8174S4; Thu, 13 Jul 2023 11:22:51 +0800 (CST) From: Bibo Mao <maobibo@loongson.cn> To: Huacai Chen <chenhuacai@kernel.org>, Jiaxun Yang <jiaxun.yang@flygoat.com>, Marc Zyngier <maz@kernel.org> Cc: Jianmin Lv <lvjianmin@loongson.cn>, linux-mips@vger.kernel.org, linux-kernel@vger.kernel.org, =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= <philmd@linaro.org> Subject: [PATCH v4 2/2] irqchip/loongson-eiointc: Simplify irq routing on some platforms Date: Thu, 13 Jul 2023 11:22:43 +0800 Message-Id: <20230713032243.2046205-3-maobibo@loongson.cn> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20230713032243.2046205-1-maobibo@loongson.cn> References: <20230713032243.2046205-1-maobibo@loongson.cn> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-CM-TRANSID: AQAAf8CxbSMDbq9kz6MrAA--.8174S4 X-CM-SenderInfo: xpdruxter6z05rqj20fqof0/ X-Coremail-Antispam: 1Uk129KBj93XoWxKFykCr15Gr4xtF1fXFW3CFX_yoW7GFyxpF WUGas0qr48XFW5WrZakw4DZFyayr93X3yDtF4fWa97AFW5uw4UKF1FyFnrZF1jk34UJF1Y yF45XFy8uFn8AagCm3ZEXasCq-sJn29KB7ZKAUJUUUUr529EdanIXcx71UUUUU7KY7ZEXa sCq-sGcSsGvfJ3Ic02F40EFcxC0VAKzVAqx4xG6I80ebIjqfuFe4nvWSU5nxnvy29KBjDU 0xBIdaVrnRJUUU9Fb4IE77IF4wAFF20E14v26r1j6r4UM7CY07I20VC2zVCF04k26cxKx2 IYs7xG6rWj6s0DM7CIcVAFz4kK6r1Y6r17M28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48v e4kI8wA2z4x0Y4vE2Ix0cI8IcVAFwI0_Xr0_Ar1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI 0_Gr0_Cr1l84ACjcxK6I8E87Iv67AKxVW8Jr0_Cr1UM28EF7xvwVC2z280aVCY1x0267AK xVW8Jr0_Cr1UM2kKe7AKxVWUXVWUAwAS0I0E0xvYzxvE52x082IY62kv0487Mc804VCY07 AIYIkI8VC2zVCFFI0UMc02F40EFcxC0VAKzVAqx4xG6I80ewAv7VC0I7IYx2IY67AKxVWU tVWrXwAv7VC2z280aVAFwI0_Gr0_Cr1lOx8S6xCaFVCjc4AY6r1j6r4UM4x0Y48IcxkI7V AKI48JMxAIw28IcxkI7VAKI48JMxC20s026xCaFVCjc4AY6r1j6r4UMxCIbckI1I0E14v2 6r1Y6r17MI8I3I0E5I8CrVAFwI0_Jr0_Jr4lx2IqxVCjr7xvwVAFwI0_JrI_JrWlx4CE17 CEb7AF67AKxVWUAVWUtwCIc40Y0x0EwIxGrwCI42IY6xIIjxv20xvE14v26r4j6ryUMIIF 0xvE2Ix0cI8IcVCY1x0267AKxVW8JVWxJwCI42IY6xAIw20EY4v20xvaj40_Jr0_JF4lIx AIcVC2z280aVAFwI0_Gr0_Cr1lIxAIcVC2z280aVCY1x0267AKxVW8JVW8JrUvcSsGvfC2 KfnxnUUI43ZEXa7IU8EeHDUUUUU== X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_BLOCKED,SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1771275447980390226 X-GMAIL-MSGID: 1771275447980390226 |
Series |
irqchip/loongson-eiointc: Add simple irq routing method
|
|
Commit Message
maobibo
July 13, 2023, 3:22 a.m. UTC
Some LoongArch systems have only one eiointc node such as 3A5000/2K2000
and qemu virt-machine. If there is only one eiointc node, all cpus can
access eiointc registers directly; if there is multiple eiointc nodes, each
cpu can only access eiointc belonging to specified node group, so anysend
or ipi needs to be used to configure irq routing. IRQ routing is simple on
such systems with one node, hacking method like anysend is not necessary.
This patch provides simpile IRQ routing method for systems with one eiointc
node, and is tested on 3A5000 board and qemu virt-machine.
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
---
drivers/irqchip/irq-loongson-eiointc.c | 80 ++++++++++++++++++++++++--
1 file changed, 74 insertions(+), 6 deletions(-)
Comments
Hi, Bibo, On Thu, Jul 13, 2023 at 11:23 AM Bibo Mao <maobibo@loongson.cn> wrote: > > Some LoongArch systems have only one eiointc node such as 3A5000/2K2000 > and qemu virt-machine. If there is only one eiointc node, all cpus can > access eiointc registers directly; if there is multiple eiointc nodes, each > cpu can only access eiointc belonging to specified node group, so anysend > or ipi needs to be used to configure irq routing. IRQ routing is simple on > such systems with one node, hacking method like anysend is not necessary. > > This patch provides simpile IRQ routing method for systems with one eiointc > node, and is tested on 3A5000 board and qemu virt-machine. > > Signed-off-by: Bibo Mao <maobibo@loongson.cn> > --- > drivers/irqchip/irq-loongson-eiointc.c | 80 ++++++++++++++++++++++++-- > 1 file changed, 74 insertions(+), 6 deletions(-) > > diff --git a/drivers/irqchip/irq-loongson-eiointc.c b/drivers/irqchip/irq-loongson-eiointc.c > index 603d323b8f8b..e6be9d6a18c8 100644 > --- a/drivers/irqchip/irq-loongson-eiointc.c > +++ b/drivers/irqchip/irq-loongson-eiointc.c > @@ -127,6 +127,48 @@ static int eiointc_set_irq_affinity(struct irq_data *d, const struct cpumask *af > return IRQ_SET_MASK_OK; > } > > +static int eiointc_single_set_irq_affinity(struct irq_data *d, > + const struct cpumask *affinity, bool force) > +{ > + unsigned int cpu; > + unsigned long flags; > + uint32_t vector, regaddr, data, coremap; > + struct cpumask mask; > + struct eiointc_priv *priv = d->domain->host_data; > + > + cpumask_and(&mask, affinity, cpu_online_mask); > + cpumask_and(&mask, &mask, &priv->cpuspan_map); > + if (cpumask_empty(&mask)) > + return -EINVAL; > + > + cpu = cpumask_first(&mask); > + vector = d->hwirq; > + regaddr = EIOINTC_REG_ENABLE + ((vector >> 5) << 2); > + data = ~BIT(vector & 0x1F); > + coremap = BIT(cpu_logical_map(cpu) % CORES_PER_EIO_NODE); > + > + /* > + * simplify for platform with only one eiointc node > + * access eiointc registers directly rather than > + * use any_send method here > + */ > + raw_spin_lock_irqsave(&affinity_lock, flags); > + iocsr_write32(EIOINTC_ALL_ENABLE & data, regaddr); > + /* > + * get irq route info for continuous 4 vectors > + * and set affinity for specified vector > + */ > + data = iocsr_read32(EIOINTC_REG_ROUTE + (vector & ~3)); > + data &= ~(0xff << ((vector & 3) * 8)); > + data |= coremap << ((vector & 3) * 8); > + iocsr_write32(data, EIOINTC_REG_ROUTE + (vector & ~3)); > + iocsr_write32(EIOINTC_ALL_ENABLE, regaddr); > + raw_spin_unlock_irqrestore(&affinity_lock, flags); > + > + irq_data_update_effective_affinity(d, cpumask_of(cpu)); > + return IRQ_SET_MASK_OK; > +} > + > static int eiointc_index(int node) > { > int i; > @@ -238,22 +280,39 @@ static struct irq_chip eiointc_irq_chip = { > .irq_set_affinity = eiointc_set_irq_affinity, > }; > > +static struct irq_chip eiointc_irq_chipi_single = { What does "chipi" mean? Maybe "chip"? And from my point of view, the main goal of this patch is to add "virtual eiointc" support which is different from "real eiointc". So I think it is better to not touch the "real eiointc" logic, but add a variant for "virtual eiointc", and then, the name should be "EIOINTC-V", not "EIOINTC-S". Huacai > + .name = "EIOINTC-S", > + .irq_ack = eiointc_ack_irq, > + .irq_mask = eiointc_mask_irq, > + .irq_unmask = eiointc_unmask_irq, > +#ifdef CONFIG_SMP > + .irq_set_affinity = eiointc_single_set_irq_affinity, > +#endif > +}; > + > static int eiointc_domain_alloc(struct irq_domain *domain, unsigned int virq, > unsigned int nr_irqs, void *arg) > { > int ret; > unsigned int i, type; > unsigned long hwirq = 0; > - struct eiointc *priv = domain->host_data; > + struct eiointc_priv *priv = domain->host_data; > + struct irq_chip *chip; > > ret = irq_domain_translate_onecell(domain, arg, &hwirq, &type); > if (ret) > return ret; > > - for (i = 0; i < nr_irqs; i++) { > - irq_domain_set_info(domain, virq + i, hwirq + i, &eiointc_irq_chip, > + /* > + * use simple irq routing method on single eiointc node > + */ > + if ((nr_pics == 1) && (nodes_weight(priv->node_map) == 1)) > + chip = &eiointc_irq_chipi_single; > + else > + chip = &eiointc_irq_chip; > + for (i = 0; i < nr_irqs; i++) > + irq_domain_set_info(domain, virq + i, hwirq + i, chip, > priv, handle_edge_irq, NULL, NULL); > - } > > return 0; > } > @@ -310,6 +369,7 @@ static void eiointc_resume(void) > int i, j; > struct irq_desc *desc; > struct irq_data *irq_data; > + struct irq_chip *chip; > > eiointc_router_init(0); > > @@ -319,7 +379,8 @@ static void eiointc_resume(void) > if (desc && desc->handle_irq && desc->handle_irq != handle_bad_irq) { > raw_spin_lock(&desc->lock); > irq_data = irq_domain_get_irq_data(eiointc_priv[i]->eiointc_domain, irq_desc_get_irq(desc)); > - eiointc_set_irq_affinity(irq_data, irq_data->common->affinity, 0); > + chip = irq_data_get_irq_chip(irq_data); > + chip->irq_set_affinity(irq_data, irq_data->common->affinity, 0); > raw_spin_unlock(&desc->lock); > } > } > @@ -497,7 +558,14 @@ static int __init eiointc_of_init(struct device_node *of_node, > priv->node = 0; > priv->domain_handle = of_node_to_fwnode(of_node); > > - ret = eiointc_init(priv, parent_irq, 0); > + /* > + * 2k0500 and 2k2000 has only one eiointc node > + * set nodemap as 1 for simple irq routing > + * > + * Fixme: what about future embedded boards with more than 4 cpus? > + * nodemap and node need be added in dts like acpi table > + */ > + ret = eiointc_init(priv, parent_irq, 1); > if (ret < 0) > goto out_free_priv; > > -- > 2.27.0 >
在 2023/7/14 11:01, Huacai Chen 写道: > Hi, Bibo, > > On Thu, Jul 13, 2023 at 11:23 AM Bibo Mao <maobibo@loongson.cn> wrote: >> >> Some LoongArch systems have only one eiointc node such as 3A5000/2K2000 >> and qemu virt-machine. If there is only one eiointc node, all cpus can >> access eiointc registers directly; if there is multiple eiointc nodes, each >> cpu can only access eiointc belonging to specified node group, so anysend >> or ipi needs to be used to configure irq routing. IRQ routing is simple on >> such systems with one node, hacking method like anysend is not necessary. >> >> This patch provides simpile IRQ routing method for systems with one eiointc >> node, and is tested on 3A5000 board and qemu virt-machine. >> >> Signed-off-by: Bibo Mao <maobibo@loongson.cn> >> --- >> drivers/irqchip/irq-loongson-eiointc.c | 80 ++++++++++++++++++++++++-- >> 1 file changed, 74 insertions(+), 6 deletions(-) >> >> diff --git a/drivers/irqchip/irq-loongson-eiointc.c b/drivers/irqchip/irq-loongson-eiointc.c >> index 603d323b8f8b..e6be9d6a18c8 100644 >> --- a/drivers/irqchip/irq-loongson-eiointc.c >> +++ b/drivers/irqchip/irq-loongson-eiointc.c >> @@ -127,6 +127,48 @@ static int eiointc_set_irq_affinity(struct irq_data *d, const struct cpumask *af >> return IRQ_SET_MASK_OK; >> } >> >> +static int eiointc_single_set_irq_affinity(struct irq_data *d, >> + const struct cpumask *affinity, bool force) >> +{ >> + unsigned int cpu; >> + unsigned long flags; >> + uint32_t vector, regaddr, data, coremap; >> + struct cpumask mask; >> + struct eiointc_priv *priv = d->domain->host_data; >> + >> + cpumask_and(&mask, affinity, cpu_online_mask); >> + cpumask_and(&mask, &mask, &priv->cpuspan_map); >> + if (cpumask_empty(&mask)) >> + return -EINVAL; >> + >> + cpu = cpumask_first(&mask); >> + vector = d->hwirq; >> + regaddr = EIOINTC_REG_ENABLE + ((vector >> 5) << 2); >> + data = ~BIT(vector & 0x1F); >> + coremap = BIT(cpu_logical_map(cpu) % CORES_PER_EIO_NODE); >> + >> + /* >> + * simplify for platform with only one eiointc node >> + * access eiointc registers directly rather than >> + * use any_send method here >> + */ >> + raw_spin_lock_irqsave(&affinity_lock, flags); >> + iocsr_write32(EIOINTC_ALL_ENABLE & data, regaddr); >> + /* >> + * get irq route info for continuous 4 vectors >> + * and set affinity for specified vector >> + */ >> + data = iocsr_read32(EIOINTC_REG_ROUTE + (vector & ~3)); >> + data &= ~(0xff << ((vector & 3) * 8)); >> + data |= coremap << ((vector & 3) * 8); >> + iocsr_write32(data, EIOINTC_REG_ROUTE + (vector & ~3)); >> + iocsr_write32(EIOINTC_ALL_ENABLE, regaddr); >> + raw_spin_unlock_irqrestore(&affinity_lock, flags); >> + >> + irq_data_update_effective_affinity(d, cpumask_of(cpu)); >> + return IRQ_SET_MASK_OK; >> +} >> + >> static int eiointc_index(int node) >> { >> int i; >> @@ -238,22 +280,39 @@ static struct irq_chip eiointc_irq_chip = { >> .irq_set_affinity = eiointc_set_irq_affinity, >> }; >> >> +static struct irq_chip eiointc_irq_chipi_single = { > What does "chipi" mean? Maybe "chip"? it is a typo, it should chip. > > And from my point of view, the main goal of this patch is to add > "virtual eiointc" support which is different from "real eiointc". So I > think it is better to not touch the "real eiointc" logic, but add a > variant for "virtual eiointc", and then, the name should be > "EIOINTC-V", not "EIOINTC-S". it is not for virt-machine only, it is ok for 3A5000 and embedded boards also. If it is possible to add special eiointc for virt-machine, irq should be routed to all vcpus rather than only vcpu 0-3 for virt eiointc model. Regards Bibo Mao Only server h > > Huacai > >> + .name = "EIOINTC-S", >> + .irq_ack = eiointc_ack_irq, >> + .irq_mask = eiointc_mask_irq, >> + .irq_unmask = eiointc_unmask_irq, >> +#ifdef CONFIG_SMP >> + .irq_set_affinity = eiointc_single_set_irq_affinity, >> +#endif >> +}; >> + >> static int eiointc_domain_alloc(struct irq_domain *domain, unsigned int virq, >> unsigned int nr_irqs, void *arg) >> { >> int ret; >> unsigned int i, type; >> unsigned long hwirq = 0; >> - struct eiointc *priv = domain->host_data; >> + struct eiointc_priv *priv = domain->host_data; >> + struct irq_chip *chip; >> >> ret = irq_domain_translate_onecell(domain, arg, &hwirq, &type); >> if (ret) >> return ret; >> >> - for (i = 0; i < nr_irqs; i++) { >> - irq_domain_set_info(domain, virq + i, hwirq + i, &eiointc_irq_chip, >> + /* >> + * use simple irq routing method on single eiointc node >> + */ >> + if ((nr_pics == 1) && (nodes_weight(priv->node_map) == 1)) >> + chip = &eiointc_irq_chipi_single; >> + else >> + chip = &eiointc_irq_chip; >> + for (i = 0; i < nr_irqs; i++) >> + irq_domain_set_info(domain, virq + i, hwirq + i, chip, >> priv, handle_edge_irq, NULL, NULL); >> - } >> >> return 0; >> } >> @@ -310,6 +369,7 @@ static void eiointc_resume(void) >> int i, j; >> struct irq_desc *desc; >> struct irq_data *irq_data; >> + struct irq_chip *chip; >> >> eiointc_router_init(0); >> >> @@ -319,7 +379,8 @@ static void eiointc_resume(void) >> if (desc && desc->handle_irq && desc->handle_irq != handle_bad_irq) { >> raw_spin_lock(&desc->lock); >> irq_data = irq_domain_get_irq_data(eiointc_priv[i]->eiointc_domain, irq_desc_get_irq(desc)); >> - eiointc_set_irq_affinity(irq_data, irq_data->common->affinity, 0); >> + chip = irq_data_get_irq_chip(irq_data); >> + chip->irq_set_affinity(irq_data, irq_data->common->affinity, 0); >> raw_spin_unlock(&desc->lock); >> } >> } >> @@ -497,7 +558,14 @@ static int __init eiointc_of_init(struct device_node *of_node, >> priv->node = 0; >> priv->domain_handle = of_node_to_fwnode(of_node); >> >> - ret = eiointc_init(priv, parent_irq, 0); >> + /* >> + * 2k0500 and 2k2000 has only one eiointc node >> + * set nodemap as 1 for simple irq routing >> + * >> + * Fixme: what about future embedded boards with more than 4 cpus? >> + * nodemap and node need be added in dts like acpi table >> + */ >> + ret = eiointc_init(priv, parent_irq, 1); >> if (ret < 0) >> goto out_free_priv; >> >> -- >> 2.27.0 >>
Jianmin, Do you have any comments so that I can update in the next version together? since you are original author of eiointc driver. Is it possible to add extra specific version in eiointc acpi table for virt-machine in future? For specific eiointc, irq can be routed to all cpus rather cpu 0-3, I do not know whether it is deserved for qemu virt-machine alone. Regards Bibo Mao 在 2023/7/13 11:22, Bibo Mao 写道: > Some LoongArch systems have only one eiointc node such as 3A5000/2K2000 > and qemu virt-machine. If there is only one eiointc node, all cpus can > access eiointc registers directly; if there is multiple eiointc nodes, each > cpu can only access eiointc belonging to specified node group, so anysend > or ipi needs to be used to configure irq routing. IRQ routing is simple on > such systems with one node, hacking method like anysend is not necessary. > > This patch provides simpile IRQ routing method for systems with one eiointc > node, and is tested on 3A5000 board and qemu virt-machine. > > Signed-off-by: Bibo Mao <maobibo@loongson.cn> > --- > drivers/irqchip/irq-loongson-eiointc.c | 80 ++++++++++++++++++++++++-- > 1 file changed, 74 insertions(+), 6 deletions(-) > > diff --git a/drivers/irqchip/irq-loongson-eiointc.c b/drivers/irqchip/irq-loongson-eiointc.c > index 603d323b8f8b..e6be9d6a18c8 100644 > --- a/drivers/irqchip/irq-loongson-eiointc.c > +++ b/drivers/irqchip/irq-loongson-eiointc.c > @@ -127,6 +127,48 @@ static int eiointc_set_irq_affinity(struct irq_data *d, const struct cpumask *af > return IRQ_SET_MASK_OK; > } > > +static int eiointc_single_set_irq_affinity(struct irq_data *d, > + const struct cpumask *affinity, bool force) > +{ > + unsigned int cpu; > + unsigned long flags; > + uint32_t vector, regaddr, data, coremap; > + struct cpumask mask; > + struct eiointc_priv *priv = d->domain->host_data; > + > + cpumask_and(&mask, affinity, cpu_online_mask); > + cpumask_and(&mask, &mask, &priv->cpuspan_map); > + if (cpumask_empty(&mask)) > + return -EINVAL; > + > + cpu = cpumask_first(&mask); > + vector = d->hwirq; > + regaddr = EIOINTC_REG_ENABLE + ((vector >> 5) << 2); > + data = ~BIT(vector & 0x1F); > + coremap = BIT(cpu_logical_map(cpu) % CORES_PER_EIO_NODE); > + > + /* > + * simplify for platform with only one eiointc node > + * access eiointc registers directly rather than > + * use any_send method here > + */ > + raw_spin_lock_irqsave(&affinity_lock, flags); > + iocsr_write32(EIOINTC_ALL_ENABLE & data, regaddr); > + /* > + * get irq route info for continuous 4 vectors > + * and set affinity for specified vector > + */ > + data = iocsr_read32(EIOINTC_REG_ROUTE + (vector & ~3)); > + data &= ~(0xff << ((vector & 3) * 8)); > + data |= coremap << ((vector & 3) * 8); > + iocsr_write32(data, EIOINTC_REG_ROUTE + (vector & ~3)); > + iocsr_write32(EIOINTC_ALL_ENABLE, regaddr); > + raw_spin_unlock_irqrestore(&affinity_lock, flags); > + > + irq_data_update_effective_affinity(d, cpumask_of(cpu)); > + return IRQ_SET_MASK_OK; > +} > + > static int eiointc_index(int node) > { > int i; > @@ -238,22 +280,39 @@ static struct irq_chip eiointc_irq_chip = { > .irq_set_affinity = eiointc_set_irq_affinity, > }; > > +static struct irq_chip eiointc_irq_chipi_single = { > + .name = "EIOINTC-S", > + .irq_ack = eiointc_ack_irq, > + .irq_mask = eiointc_mask_irq, > + .irq_unmask = eiointc_unmask_irq, > +#ifdef CONFIG_SMP > + .irq_set_affinity = eiointc_single_set_irq_affinity, > +#endif > +}; > + > static int eiointc_domain_alloc(struct irq_domain *domain, unsigned int virq, > unsigned int nr_irqs, void *arg) > { > int ret; > unsigned int i, type; > unsigned long hwirq = 0; > - struct eiointc *priv = domain->host_data; > + struct eiointc_priv *priv = domain->host_data; > + struct irq_chip *chip; > > ret = irq_domain_translate_onecell(domain, arg, &hwirq, &type); > if (ret) > return ret; > > - for (i = 0; i < nr_irqs; i++) { > - irq_domain_set_info(domain, virq + i, hwirq + i, &eiointc_irq_chip, > + /* > + * use simple irq routing method on single eiointc node > + */ > + if ((nr_pics == 1) && (nodes_weight(priv->node_map) == 1)) > + chip = &eiointc_irq_chipi_single; > + else > + chip = &eiointc_irq_chip; > + for (i = 0; i < nr_irqs; i++) > + irq_domain_set_info(domain, virq + i, hwirq + i, chip, > priv, handle_edge_irq, NULL, NULL); > - } > > return 0; > } > @@ -310,6 +369,7 @@ static void eiointc_resume(void) > int i, j; > struct irq_desc *desc; > struct irq_data *irq_data; > + struct irq_chip *chip; > > eiointc_router_init(0); > > @@ -319,7 +379,8 @@ static void eiointc_resume(void) > if (desc && desc->handle_irq && desc->handle_irq != handle_bad_irq) { > raw_spin_lock(&desc->lock); > irq_data = irq_domain_get_irq_data(eiointc_priv[i]->eiointc_domain, irq_desc_get_irq(desc)); > - eiointc_set_irq_affinity(irq_data, irq_data->common->affinity, 0); > + chip = irq_data_get_irq_chip(irq_data); > + chip->irq_set_affinity(irq_data, irq_data->common->affinity, 0); > raw_spin_unlock(&desc->lock); > } > } > @@ -497,7 +558,14 @@ static int __init eiointc_of_init(struct device_node *of_node, > priv->node = 0; > priv->domain_handle = of_node_to_fwnode(of_node); > > - ret = eiointc_init(priv, parent_irq, 0); > + /* > + * 2k0500 and 2k2000 has only one eiointc node > + * set nodemap as 1 for simple irq routing > + * > + * Fixme: what about future embedded boards with more than 4 cpus? > + * nodemap and node need be added in dts like acpi table > + */ > + ret = eiointc_init(priv, parent_irq, 1); > if (ret < 0) > goto out_free_priv; >
Hi, bibo I think the patch has been it as we discussed offline, I have no further comments. And there's no plan to update EIOPIC structure in ACPI table since new advanced feature for LoongArch irq chip will be available in future. Thanks, Jianmin. On 2023/7/18 下午3:01, bibo mao wrote: > Jianmin, > > Do you have any comments so that I can update in the next version together? > since you are original author of eiointc driver. > > Is it possible to add extra specific version in eiointc acpi table for > virt-machine in future? For specific eiointc, irq can be routed to all > cpus rather cpu 0-3, I do not know whether it is deserved for qemu > virt-machine alone. > > Regards > Bibo Mao > > 在 2023/7/13 11:22, Bibo Mao 写道: >> Some LoongArch systems have only one eiointc node such as 3A5000/2K2000 >> and qemu virt-machine. If there is only one eiointc node, all cpus can >> access eiointc registers directly; if there is multiple eiointc nodes, each >> cpu can only access eiointc belonging to specified node group, so anysend >> or ipi needs to be used to configure irq routing. IRQ routing is simple on >> such systems with one node, hacking method like anysend is not necessary. >> >> This patch provides simpile IRQ routing method for systems with one eiointc >> node, and is tested on 3A5000 board and qemu virt-machine. >> >> Signed-off-by: Bibo Mao <maobibo@loongson.cn> >> --- >> drivers/irqchip/irq-loongson-eiointc.c | 80 ++++++++++++++++++++++++-- >> 1 file changed, 74 insertions(+), 6 deletions(-) >> >> diff --git a/drivers/irqchip/irq-loongson-eiointc.c b/drivers/irqchip/irq-loongson-eiointc.c >> index 603d323b8f8b..e6be9d6a18c8 100644 >> --- a/drivers/irqchip/irq-loongson-eiointc.c >> +++ b/drivers/irqchip/irq-loongson-eiointc.c >> @@ -127,6 +127,48 @@ static int eiointc_set_irq_affinity(struct irq_data *d, const struct cpumask *af >> return IRQ_SET_MASK_OK; >> } >> >> +static int eiointc_single_set_irq_affinity(struct irq_data *d, >> + const struct cpumask *affinity, bool force) >> +{ >> + unsigned int cpu; >> + unsigned long flags; >> + uint32_t vector, regaddr, data, coremap; >> + struct cpumask mask; >> + struct eiointc_priv *priv = d->domain->host_data; >> + >> + cpumask_and(&mask, affinity, cpu_online_mask); >> + cpumask_and(&mask, &mask, &priv->cpuspan_map); >> + if (cpumask_empty(&mask)) >> + return -EINVAL; >> + >> + cpu = cpumask_first(&mask); >> + vector = d->hwirq; >> + regaddr = EIOINTC_REG_ENABLE + ((vector >> 5) << 2); >> + data = ~BIT(vector & 0x1F); >> + coremap = BIT(cpu_logical_map(cpu) % CORES_PER_EIO_NODE); >> + >> + /* >> + * simplify for platform with only one eiointc node >> + * access eiointc registers directly rather than >> + * use any_send method here >> + */ >> + raw_spin_lock_irqsave(&affinity_lock, flags); >> + iocsr_write32(EIOINTC_ALL_ENABLE & data, regaddr); >> + /* >> + * get irq route info for continuous 4 vectors >> + * and set affinity for specified vector >> + */ >> + data = iocsr_read32(EIOINTC_REG_ROUTE + (vector & ~3)); >> + data &= ~(0xff << ((vector & 3) * 8)); >> + data |= coremap << ((vector & 3) * 8); >> + iocsr_write32(data, EIOINTC_REG_ROUTE + (vector & ~3)); >> + iocsr_write32(EIOINTC_ALL_ENABLE, regaddr); >> + raw_spin_unlock_irqrestore(&affinity_lock, flags); >> + >> + irq_data_update_effective_affinity(d, cpumask_of(cpu)); >> + return IRQ_SET_MASK_OK; >> +} >> + >> static int eiointc_index(int node) >> { >> int i; >> @@ -238,22 +280,39 @@ static struct irq_chip eiointc_irq_chip = { >> .irq_set_affinity = eiointc_set_irq_affinity, >> }; >> >> +static struct irq_chip eiointc_irq_chipi_single = { >> + .name = "EIOINTC-S", >> + .irq_ack = eiointc_ack_irq, >> + .irq_mask = eiointc_mask_irq, >> + .irq_unmask = eiointc_unmask_irq, >> +#ifdef CONFIG_SMP >> + .irq_set_affinity = eiointc_single_set_irq_affinity, >> +#endif >> +}; >> + >> static int eiointc_domain_alloc(struct irq_domain *domain, unsigned int virq, >> unsigned int nr_irqs, void *arg) >> { >> int ret; >> unsigned int i, type; >> unsigned long hwirq = 0; >> - struct eiointc *priv = domain->host_data; >> + struct eiointc_priv *priv = domain->host_data; >> + struct irq_chip *chip; >> >> ret = irq_domain_translate_onecell(domain, arg, &hwirq, &type); >> if (ret) >> return ret; >> >> - for (i = 0; i < nr_irqs; i++) { >> - irq_domain_set_info(domain, virq + i, hwirq + i, &eiointc_irq_chip, >> + /* >> + * use simple irq routing method on single eiointc node >> + */ >> + if ((nr_pics == 1) && (nodes_weight(priv->node_map) == 1)) >> + chip = &eiointc_irq_chipi_single; >> + else >> + chip = &eiointc_irq_chip; >> + for (i = 0; i < nr_irqs; i++) >> + irq_domain_set_info(domain, virq + i, hwirq + i, chip, >> priv, handle_edge_irq, NULL, NULL); >> - } >> >> return 0; >> } >> @@ -310,6 +369,7 @@ static void eiointc_resume(void) >> int i, j; >> struct irq_desc *desc; >> struct irq_data *irq_data; >> + struct irq_chip *chip; >> >> eiointc_router_init(0); >> >> @@ -319,7 +379,8 @@ static void eiointc_resume(void) >> if (desc && desc->handle_irq && desc->handle_irq != handle_bad_irq) { >> raw_spin_lock(&desc->lock); >> irq_data = irq_domain_get_irq_data(eiointc_priv[i]->eiointc_domain, irq_desc_get_irq(desc)); >> - eiointc_set_irq_affinity(irq_data, irq_data->common->affinity, 0); >> + chip = irq_data_get_irq_chip(irq_data); >> + chip->irq_set_affinity(irq_data, irq_data->common->affinity, 0); >> raw_spin_unlock(&desc->lock); >> } >> } >> @@ -497,7 +558,14 @@ static int __init eiointc_of_init(struct device_node *of_node, >> priv->node = 0; >> priv->domain_handle = of_node_to_fwnode(of_node); >> >> - ret = eiointc_init(priv, parent_irq, 0); >> + /* >> + * 2k0500 and 2k2000 has only one eiointc node >> + * set nodemap as 1 for simple irq routing >> + * >> + * Fixme: what about future embedded boards with more than 4 cpus? >> + * nodemap and node need be added in dts like acpi table >> + */ >> + ret = eiointc_init(priv, parent_irq, 1); >> if (ret < 0) >> goto out_free_priv; >>
Jianmin, Thank for your reply. OK, qemu virt-machine eiointc model will be consistent with physical machine. And let's wait for new LoongArch irqchip in future. Regards Bibo Mao 在 2023/7/19 11:33, Jianmin Lv 写道: > Hi, bibo > > I think the patch has been it as we discussed offline, I have no further comments. And there's no plan to update EIOPIC structure in ACPI table since new advanced feature for LoongArch irq chip will be available in future. > > Thanks, > Jianmin. > > On 2023/7/18 下午3:01, bibo mao wrote: >> Jianmin, >> >> Do you have any comments so that I can update in the next version together? >> since you are original author of eiointc driver. >> >> Is it possible to add extra specific version in eiointc acpi table for >> virt-machine in future? For specific eiointc, irq can be routed to all >> cpus rather cpu 0-3, I do not know whether it is deserved for qemu >> virt-machine alone. >> >> Regards >> Bibo Mao >> >> 在 2023/7/13 11:22, Bibo Mao 写道: >>> Some LoongArch systems have only one eiointc node such as 3A5000/2K2000 >>> and qemu virt-machine. If there is only one eiointc node, all cpus can >>> access eiointc registers directly; if there is multiple eiointc nodes, each >>> cpu can only access eiointc belonging to specified node group, so anysend >>> or ipi needs to be used to configure irq routing. IRQ routing is simple on >>> such systems with one node, hacking method like anysend is not necessary. >>> >>> This patch provides simpile IRQ routing method for systems with one eiointc >>> node, and is tested on 3A5000 board and qemu virt-machine. >>> >>> Signed-off-by: Bibo Mao <maobibo@loongson.cn> >>> --- >>> drivers/irqchip/irq-loongson-eiointc.c | 80 ++++++++++++++++++++++++-- >>> 1 file changed, 74 insertions(+), 6 deletions(-) >>> >>> diff --git a/drivers/irqchip/irq-loongson-eiointc.c b/drivers/irqchip/irq-loongson-eiointc.c >>> index 603d323b8f8b..e6be9d6a18c8 100644 >>> --- a/drivers/irqchip/irq-loongson-eiointc.c >>> +++ b/drivers/irqchip/irq-loongson-eiointc.c >>> @@ -127,6 +127,48 @@ static int eiointc_set_irq_affinity(struct irq_data *d, const struct cpumask *af >>> return IRQ_SET_MASK_OK; >>> } >>> +static int eiointc_single_set_irq_affinity(struct irq_data *d, >>> + const struct cpumask *affinity, bool force) >>> +{ >>> + unsigned int cpu; >>> + unsigned long flags; >>> + uint32_t vector, regaddr, data, coremap; >>> + struct cpumask mask; >>> + struct eiointc_priv *priv = d->domain->host_data; >>> + >>> + cpumask_and(&mask, affinity, cpu_online_mask); >>> + cpumask_and(&mask, &mask, &priv->cpuspan_map); >>> + if (cpumask_empty(&mask)) >>> + return -EINVAL; >>> + >>> + cpu = cpumask_first(&mask); >>> + vector = d->hwirq; >>> + regaddr = EIOINTC_REG_ENABLE + ((vector >> 5) << 2); >>> + data = ~BIT(vector & 0x1F); >>> + coremap = BIT(cpu_logical_map(cpu) % CORES_PER_EIO_NODE); >>> + >>> + /* >>> + * simplify for platform with only one eiointc node >>> + * access eiointc registers directly rather than >>> + * use any_send method here >>> + */ >>> + raw_spin_lock_irqsave(&affinity_lock, flags); >>> + iocsr_write32(EIOINTC_ALL_ENABLE & data, regaddr); >>> + /* >>> + * get irq route info for continuous 4 vectors >>> + * and set affinity for specified vector >>> + */ >>> + data = iocsr_read32(EIOINTC_REG_ROUTE + (vector & ~3)); >>> + data &= ~(0xff << ((vector & 3) * 8)); >>> + data |= coremap << ((vector & 3) * 8); >>> + iocsr_write32(data, EIOINTC_REG_ROUTE + (vector & ~3)); >>> + iocsr_write32(EIOINTC_ALL_ENABLE, regaddr); >>> + raw_spin_unlock_irqrestore(&affinity_lock, flags); >>> + >>> + irq_data_update_effective_affinity(d, cpumask_of(cpu)); >>> + return IRQ_SET_MASK_OK; >>> +} >>> + >>> static int eiointc_index(int node) >>> { >>> int i; >>> @@ -238,22 +280,39 @@ static struct irq_chip eiointc_irq_chip = { >>> .irq_set_affinity = eiointc_set_irq_affinity, >>> }; >>> +static struct irq_chip eiointc_irq_chipi_single = { >>> + .name = "EIOINTC-S", >>> + .irq_ack = eiointc_ack_irq, >>> + .irq_mask = eiointc_mask_irq, >>> + .irq_unmask = eiointc_unmask_irq, >>> +#ifdef CONFIG_SMP >>> + .irq_set_affinity = eiointc_single_set_irq_affinity, >>> +#endif >>> +}; >>> + >>> static int eiointc_domain_alloc(struct irq_domain *domain, unsigned int virq, >>> unsigned int nr_irqs, void *arg) >>> { >>> int ret; >>> unsigned int i, type; >>> unsigned long hwirq = 0; >>> - struct eiointc *priv = domain->host_data; >>> + struct eiointc_priv *priv = domain->host_data; >>> + struct irq_chip *chip; >>> ret = irq_domain_translate_onecell(domain, arg, &hwirq, &type); >>> if (ret) >>> return ret; >>> - for (i = 0; i < nr_irqs; i++) { >>> - irq_domain_set_info(domain, virq + i, hwirq + i, &eiointc_irq_chip, >>> + /* >>> + * use simple irq routing method on single eiointc node >>> + */ >>> + if ((nr_pics == 1) && (nodes_weight(priv->node_map) == 1)) >>> + chip = &eiointc_irq_chipi_single; >>> + else >>> + chip = &eiointc_irq_chip; >>> + for (i = 0; i < nr_irqs; i++) >>> + irq_domain_set_info(domain, virq + i, hwirq + i, chip, >>> priv, handle_edge_irq, NULL, NULL); >>> - } >>> return 0; >>> } >>> @@ -310,6 +369,7 @@ static void eiointc_resume(void) >>> int i, j; >>> struct irq_desc *desc; >>> struct irq_data *irq_data; >>> + struct irq_chip *chip; >>> eiointc_router_init(0); >>> @@ -319,7 +379,8 @@ static void eiointc_resume(void) >>> if (desc && desc->handle_irq && desc->handle_irq != handle_bad_irq) { >>> raw_spin_lock(&desc->lock); >>> irq_data = irq_domain_get_irq_data(eiointc_priv[i]->eiointc_domain, irq_desc_get_irq(desc)); >>> - eiointc_set_irq_affinity(irq_data, irq_data->common->affinity, 0); >>> + chip = irq_data_get_irq_chip(irq_data); >>> + chip->irq_set_affinity(irq_data, irq_data->common->affinity, 0); >>> raw_spin_unlock(&desc->lock); >>> } >>> } >>> @@ -497,7 +558,14 @@ static int __init eiointc_of_init(struct device_node *of_node, >>> priv->node = 0; >>> priv->domain_handle = of_node_to_fwnode(of_node); >>> - ret = eiointc_init(priv, parent_irq, 0); >>> + /* >>> + * 2k0500 and 2k2000 has only one eiointc node >>> + * set nodemap as 1 for simple irq routing >>> + * >>> + * Fixme: what about future embedded boards with more than 4 cpus? >>> + * nodemap and node need be added in dts like acpi table >>> + */ >>> + ret = eiointc_init(priv, parent_irq, 1); >>> if (ret < 0) >>> goto out_free_priv; >>> >
diff --git a/drivers/irqchip/irq-loongson-eiointc.c b/drivers/irqchip/irq-loongson-eiointc.c index 603d323b8f8b..e6be9d6a18c8 100644 --- a/drivers/irqchip/irq-loongson-eiointc.c +++ b/drivers/irqchip/irq-loongson-eiointc.c @@ -127,6 +127,48 @@ static int eiointc_set_irq_affinity(struct irq_data *d, const struct cpumask *af return IRQ_SET_MASK_OK; } +static int eiointc_single_set_irq_affinity(struct irq_data *d, + const struct cpumask *affinity, bool force) +{ + unsigned int cpu; + unsigned long flags; + uint32_t vector, regaddr, data, coremap; + struct cpumask mask; + struct eiointc_priv *priv = d->domain->host_data; + + cpumask_and(&mask, affinity, cpu_online_mask); + cpumask_and(&mask, &mask, &priv->cpuspan_map); + if (cpumask_empty(&mask)) + return -EINVAL; + + cpu = cpumask_first(&mask); + vector = d->hwirq; + regaddr = EIOINTC_REG_ENABLE + ((vector >> 5) << 2); + data = ~BIT(vector & 0x1F); + coremap = BIT(cpu_logical_map(cpu) % CORES_PER_EIO_NODE); + + /* + * simplify for platform with only one eiointc node + * access eiointc registers directly rather than + * use any_send method here + */ + raw_spin_lock_irqsave(&affinity_lock, flags); + iocsr_write32(EIOINTC_ALL_ENABLE & data, regaddr); + /* + * get irq route info for continuous 4 vectors + * and set affinity for specified vector + */ + data = iocsr_read32(EIOINTC_REG_ROUTE + (vector & ~3)); + data &= ~(0xff << ((vector & 3) * 8)); + data |= coremap << ((vector & 3) * 8); + iocsr_write32(data, EIOINTC_REG_ROUTE + (vector & ~3)); + iocsr_write32(EIOINTC_ALL_ENABLE, regaddr); + raw_spin_unlock_irqrestore(&affinity_lock, flags); + + irq_data_update_effective_affinity(d, cpumask_of(cpu)); + return IRQ_SET_MASK_OK; +} + static int eiointc_index(int node) { int i; @@ -238,22 +280,39 @@ static struct irq_chip eiointc_irq_chip = { .irq_set_affinity = eiointc_set_irq_affinity, }; +static struct irq_chip eiointc_irq_chipi_single = { + .name = "EIOINTC-S", + .irq_ack = eiointc_ack_irq, + .irq_mask = eiointc_mask_irq, + .irq_unmask = eiointc_unmask_irq, +#ifdef CONFIG_SMP + .irq_set_affinity = eiointc_single_set_irq_affinity, +#endif +}; + static int eiointc_domain_alloc(struct irq_domain *domain, unsigned int virq, unsigned int nr_irqs, void *arg) { int ret; unsigned int i, type; unsigned long hwirq = 0; - struct eiointc *priv = domain->host_data; + struct eiointc_priv *priv = domain->host_data; + struct irq_chip *chip; ret = irq_domain_translate_onecell(domain, arg, &hwirq, &type); if (ret) return ret; - for (i = 0; i < nr_irqs; i++) { - irq_domain_set_info(domain, virq + i, hwirq + i, &eiointc_irq_chip, + /* + * use simple irq routing method on single eiointc node + */ + if ((nr_pics == 1) && (nodes_weight(priv->node_map) == 1)) + chip = &eiointc_irq_chipi_single; + else + chip = &eiointc_irq_chip; + for (i = 0; i < nr_irqs; i++) + irq_domain_set_info(domain, virq + i, hwirq + i, chip, priv, handle_edge_irq, NULL, NULL); - } return 0; } @@ -310,6 +369,7 @@ static void eiointc_resume(void) int i, j; struct irq_desc *desc; struct irq_data *irq_data; + struct irq_chip *chip; eiointc_router_init(0); @@ -319,7 +379,8 @@ static void eiointc_resume(void) if (desc && desc->handle_irq && desc->handle_irq != handle_bad_irq) { raw_spin_lock(&desc->lock); irq_data = irq_domain_get_irq_data(eiointc_priv[i]->eiointc_domain, irq_desc_get_irq(desc)); - eiointc_set_irq_affinity(irq_data, irq_data->common->affinity, 0); + chip = irq_data_get_irq_chip(irq_data); + chip->irq_set_affinity(irq_data, irq_data->common->affinity, 0); raw_spin_unlock(&desc->lock); } } @@ -497,7 +558,14 @@ static int __init eiointc_of_init(struct device_node *of_node, priv->node = 0; priv->domain_handle = of_node_to_fwnode(of_node); - ret = eiointc_init(priv, parent_irq, 0); + /* + * 2k0500 and 2k2000 has only one eiointc node + * set nodemap as 1 for simple irq routing + * + * Fixme: what about future embedded boards with more than 4 cpus? + * nodemap and node need be added in dts like acpi table + */ + ret = eiointc_init(priv, parent_irq, 1); if (ret < 0) goto out_free_priv;