Fix return value checking of eiointc_index where int type
is converted uint32_t and check smaller than 0.
Add simple irq route support on system with only one eiointc node,
rather than use anysend method.
---
Changes in v5:
Modify typo issue.
Changes in v4:
Modify some spell checking problems.
Add Fixes tag.
Changes in v3:
Modify some spell checking problems.
Changes in v2:
Use the simple irq routing on embeded board like 2K0500 and 2K2000
board, since there is only one eio node.
---
Bibo Mao (2):
irqchip/loongson-eiointc: Fix return value checking of eiointc_index
irqchip/loongson-eiointc: Simplify irq routing on some platforms
drivers/irqchip/irq-loongson-eiointc.c | 93 +++++++++++++++++++++++---
1 file changed, 82 insertions(+), 11 deletions(-)
--
2.27.0
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, 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 <[email protected]>
---
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..8f3470e1f9bc 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_chip_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_chip_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
Return value of function eiointc_index is int, however it is converted
into uint32_t and then compared smaller than zero. This causes logic
problem. There is eiointc initialization problem on qemu virt-machine
where there is only one eiointc node and more than 4 vcpus. Nodemap of
eiointc is 1, and external device intr can only be routed to vcpu 0-3, the
other vcpus can not response any external device interrupts and only local
processor interrupts like ipi/timer can work.
Fixes: dd281e1a1a93 ("irqchip: Add Loongson Extended I/O interrupt controller support")
Signed-off-by: Bibo Mao <[email protected]>
Reviewed-by: Philippe Mathieu-Daudé <[email protected]>
---
drivers/irqchip/irq-loongson-eiointc.c | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/drivers/irqchip/irq-loongson-eiointc.c b/drivers/irqchip/irq-loongson-eiointc.c
index 92d8aa28bdf5..603d323b8f8b 100644
--- a/drivers/irqchip/irq-loongson-eiointc.c
+++ b/drivers/irqchip/irq-loongson-eiointc.c
@@ -144,12 +144,15 @@ static int eiointc_router_init(unsigned int cpu)
int i, bit;
uint32_t data;
uint32_t node = cpu_to_eio_node(cpu);
- uint32_t index = eiointc_index(node);
+ int index = eiointc_index(node);
- if (index < 0) {
- pr_err("Error: invalid nodemap!\n");
- return -1;
- }
+ /*
+ * Qemu virt-machine has only one eiointc and more than four cpus.
+ * Irq from eiointc can only be routed to cpu 0-3, cpus except 0-3
+ * need not initialize eiointc on virt-machine
+ */
+ if (index < 0)
+ return 0;
if ((cpu_logical_map(cpu) % CORES_PER_EIO_NODE) == 0) {
eiointc_enable();
--
2.27.0
slight ping :)
在 2023/7/19 14:35, Bibo Mao 写道:
> Fix return value checking of eiointc_index where int type
> is converted uint32_t and check smaller than 0.
>
> Add simple irq route support on system with only one eiointc node,
> rather than use anysend method.
>
> ---
> Changes in v5:
> Modify typo issue.
>
> Changes in v4:
> Modify some spell checking problems.
> Add Fixes tag.
>
> Changes in v3:
> Modify some spell checking problems.
>
> Changes in v2:
> Use the simple irq routing on embeded board like 2K0500 and 2K2000
> board, since there is only one eio node.
>
> ---
> Bibo Mao (2):
> irqchip/loongson-eiointc: Fix return value checking of eiointc_index
> irqchip/loongson-eiointc: Simplify irq routing on some platforms
>
> drivers/irqchip/irq-loongson-eiointc.c | 93 +++++++++++++++++++++++---
> 1 file changed, 82 insertions(+), 11 deletions(-)
>
On Wed, 26 Jul 2023 10:45:51 +0100,
bibo mao <[email protected]> wrote:
>
> slight ping :)
Given that you have sent this series 5 times in two weeks, I don't
think anyone is in a hurry to review it again. Just give it time.
Thanks,
M.
>
> 在 2023/7/19 14:35, Bibo Mao 写道:
> > Fix return value checking of eiointc_index where int type
> > is converted uint32_t and check smaller than 0.
> >
> > Add simple irq route support on system with only one eiointc node,
> > rather than use anysend method.
> >
> > ---
> > Changes in v5:
> > Modify typo issue.
> >
> > Changes in v4:
> > Modify some spell checking problems.
> > Add Fixes tag.
> >
> > Changes in v3:
> > Modify some spell checking problems.
> >
> > Changes in v2:
> > Use the simple irq routing on embeded board like 2K0500 and 2K2000
> > board, since there is only one eio node.
> >
> > ---
> > Bibo Mao (2):
> > irqchip/loongson-eiointc: Fix return value checking of eiointc_index
> > irqchip/loongson-eiointc: Simplify irq routing on some platforms
> >
> > drivers/irqchip/irq-loongson-eiointc.c | 93 +++++++++++++++++++++++---
> > 1 file changed, 82 insertions(+), 11 deletions(-)
> >
>
>
--
Without deviation from the norm, progress is not possible.
在 2023/7/26 17:53, Marc Zyngier 写道:
> On Wed, 26 Jul 2023 10:45:51 +0100,
> bibo mao <[email protected]> wrote:
>>
>> slight ping :)
>
> Given that you have sent this series 5 times in two weeks, I don't
> think anyone is in a hurry to review it again. Just give it time.
Ok, I see.
Sorry to bring out some noise and thanks for your response.
Regards
Bibo Mao
>
> Thanks,
>
> M.
>
>>
>> 在 2023/7/19 14:35, Bibo Mao 写道:
>>> Fix return value checking of eiointc_index where int type
>>> is converted uint32_t and check smaller than 0.
>>>
>>> Add simple irq route support on system with only one eiointc node,
>>> rather than use anysend method.
>>>
>>> ---
>>> Changes in v5:
>>> Modify typo issue.
>>>
>>> Changes in v4:
>>> Modify some spell checking problems.
>>> Add Fixes tag.
>>>
>>> Changes in v3:
>>> Modify some spell checking problems.
>>>
>>> Changes in v2:
>>> Use the simple irq routing on embeded board like 2K0500 and 2K2000
>>> board, since there is only one eio node.
>>>
>>> ---
>>> Bibo Mao (2):
>>> irqchip/loongson-eiointc: Fix return value checking of eiointc_index
>>> irqchip/loongson-eiointc: Simplify irq routing on some platforms
>>>
>>> drivers/irqchip/irq-loongson-eiointc.c | 93 +++++++++++++++++++++++---
>>> 1 file changed, 82 insertions(+), 11 deletions(-)
>>>
>>
>>
>
On Wed, Jul 26, 2023 at 6:08 PM bibo mao <[email protected]> wrote:
>
>
>
> 在 2023/7/26 17:53, Marc Zyngier 写道:
> > On Wed, 26 Jul 2023 10:45:51 +0100,
> > bibo mao <[email protected]> wrote:
> >>
> >> slight ping :)
> >
> > Given that you have sent this series 5 times in two weeks, I don't
> > think anyone is in a hurry to review it again. Just give it time.
> Ok, I see.
> Sorry to bring out some noise and thanks for your response.
1, If we really need a "virtual eiointc" variant, please document it
in Documentation/loongarch/irq-chip-model.rst and
Documentation/translations/zh_CN/loongarch/irq-chip-model.rst.
2, Then, I think it is better to only modify the type of 'index' in
Patch-1, and move the 'if (index < 0) ...' modifications to Patch-2.
Because all "virtual eiointc" code should be in a single patch.
Huacai
>
> Regards
> Bibo Mao
> >
> > Thanks,
> >
> > M.
> >
> >>
> >> 在 2023/7/19 14:35, Bibo Mao 写道:
> >>> Fix return value checking of eiointc_index where int type
> >>> is converted uint32_t and check smaller than 0.
> >>>
> >>> Add simple irq route support on system with only one eiointc node,
> >>> rather than use anysend method.
> >>>
> >>> ---
> >>> Changes in v5:
> >>> Modify typo issue.
> >>>
> >>> Changes in v4:
> >>> Modify some spell checking problems.
> >>> Add Fixes tag.
> >>>
> >>> Changes in v3:
> >>> Modify some spell checking problems.
> >>>
> >>> Changes in v2:
> >>> Use the simple irq routing on embeded board like 2K0500 and 2K2000
> >>> board, since there is only one eio node.
> >>>
> >>> ---
> >>> Bibo Mao (2):
> >>> irqchip/loongson-eiointc: Fix return value checking of eiointc_index
> >>> irqchip/loongson-eiointc: Simplify irq routing on some platforms
> >>>
> >>> drivers/irqchip/irq-loongson-eiointc.c | 93 +++++++++++++++++++++++---
> >>> 1 file changed, 82 insertions(+), 11 deletions(-)
> >>>
> >>
> >>
> >
>
在 2023/7/31 22:16, Huacai Chen 写道:
> On Wed, Jul 26, 2023 at 6:08 PM bibo mao <[email protected]> wrote:
>>
>>
>>
>> 在 2023/7/26 17:53, Marc Zyngier 写道:
>>> On Wed, 26 Jul 2023 10:45:51 +0100,
>>> bibo mao <[email protected]> wrote:
>>>>
>>>> slight ping :)
>>>
>>> Given that you have sent this series 5 times in two weeks, I don't
>>> think anyone is in a hurry to review it again. Just give it time.
>> Ok, I see.
>> Sorry to bring out some noise and thanks for your response.
> 1, If we really need a "virtual eiointc" variant, please document it
> in Documentation/loongarch/irq-chip-model.rst and
> Documentation/translations/zh_CN/loongarch/irq-chip-model.rst.
> 2, Then, I think it is better to only modify the type of 'index' in
> Patch-1, and move the 'if (index < 0) ...' modifications to Patch-2.
> Because all "virtual eiointc" code should be in a single patch.
sure, will do in this way.
Regards
Bibo Mao
>
>
> Huacai
>>
>> Regards
>> Bibo Mao
>>>
>>> Thanks,
>>>
>>> M.
>>>
>>>>
>>>> 在 2023/7/19 14:35, Bibo Mao 写道:
>>>>> Fix return value checking of eiointc_index where int type
>>>>> is converted uint32_t and check smaller than 0.
>>>>>
>>>>> Add simple irq route support on system with only one eiointc node,
>>>>> rather than use anysend method.
>>>>>
>>>>> ---
>>>>> Changes in v5:
>>>>> Modify typo issue.
>>>>>
>>>>> Changes in v4:
>>>>> Modify some spell checking problems.
>>>>> Add Fixes tag.
>>>>>
>>>>> Changes in v3:
>>>>> Modify some spell checking problems.
>>>>>
>>>>> Changes in v2:
>>>>> Use the simple irq routing on embeded board like 2K0500 and 2K2000
>>>>> board, since there is only one eio node.
>>>>>
>>>>> ---
>>>>> Bibo Mao (2):
>>>>> irqchip/loongson-eiointc: Fix return value checking of eiointc_index
>>>>> irqchip/loongson-eiointc: Simplify irq routing on some platforms
>>>>>
>>>>> drivers/irqchip/irq-loongson-eiointc.c | 93 +++++++++++++++++++++++---
>>>>> 1 file changed, 82 insertions(+), 11 deletions(-)
>>>>>
>>>>
>>>>
>>>
>>