1
Fix return value checking of eiointc_index where int type
1
Fix return value checking of eiointc_index where int type
2
is converted uint32_t and check smaller than 0.
2
is converted uint32_t and check smaller than 0.
3
3
4
Add simple irq route support on system with only one eioi node,
4
Add simple irq route support on system with only one eiointc node,
5
rather than use anysend method.
5
rather than use anysend method.
6
6
7
---
7
---
8
Changes in v5:
9
Modify typo issue.
10
11
Changes in v4:
12
Modify some spell checking problems.
13
Add Fixes tag.
14
15
Changes in v3:
16
Modify some spell checking problems.
17
8
Changes in v2:
18
Changes in v2:
9
Use the simple irq routing on embeded board like 2K0500 and 2K2000
19
Use the simple irq routing on embeded board like 2K0500 and 2K2000
10
board, since there is only one eio node.
20
board, since there is only one eio node.
11
21
12
---
22
---
13
Bibo Mao (2):
23
Bibo Mao (2):
14
irqchip/loongson-eiointc: fix return value checking of eiointc_index
24
irqchip/loongson-eiointc: Fix return value checking of eiointc_index
15
irqchip/loongson-eiointc: simplify irq route on one eioi-node system
25
irqchip/loongson-eiointc: Simplify irq routing on some platforms
16
26
17
drivers/irqchip/irq-loongson-eiointc.c | 91 ++++++++++++++++++++++----
27
drivers/irqchip/irq-loongson-eiointc.c | 93 +++++++++++++++++++++++---
18
1 file changed, 80 insertions(+), 11 deletions(-)
28
1 file changed, 82 insertions(+), 11 deletions(-)
19
29
20
base-commit: d528014517f2b0531862c02865b9d4c908019dc4
21
--
30
--
22
2.27.0
31
2.27.0
diff view generated by jsdifflib
1
return value of function eiointc_index is int, however it is
1
Return value of function eiointc_index is int, however it is converted
2
converted uint32_t when used. This causes logic problem when
2
into uint32_t and then compared smaller than zero. This causes logic
3
checking return value. There is eioi initial problem on qemu
3
problem. There is eiointc initialization problem on qemu virt-machine
4
virt-machine where there is only one eioi node and more than 4
4
where there is only one eiointc node and more than 4 vcpus. Nodemap of
5
vcpus, external device intr can only be routed to vcpu 0-3.
5
eiointc is 1, and external device intr can only be routed to vcpu 0-3, the
6
other vcpus can not response any external device interrupts and only local
7
processor interrupts like ipi/timer can work.
6
8
9
Fixes: dd281e1a1a93 ("irqchip: Add Loongson Extended I/O interrupt controller support")
7
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
10
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
---
12
---
9
drivers/irqchip/irq-loongson-eiointc.c | 12 +++++++-----
13
drivers/irqchip/irq-loongson-eiointc.c | 13 ++++++++-----
10
1 file changed, 7 insertions(+), 5 deletions(-)
14
1 file changed, 8 insertions(+), 5 deletions(-)
11
15
12
diff --git a/drivers/irqchip/irq-loongson-eiointc.c b/drivers/irqchip/irq-loongson-eiointc.c
16
diff --git a/drivers/irqchip/irq-loongson-eiointc.c b/drivers/irqchip/irq-loongson-eiointc.c
13
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
14
--- a/drivers/irqchip/irq-loongson-eiointc.c
18
--- a/drivers/irqchip/irq-loongson-eiointc.c
15
+++ b/drivers/irqchip/irq-loongson-eiointc.c
19
+++ b/drivers/irqchip/irq-loongson-eiointc.c
...
...
23
-    if (index < 0) {
27
-    if (index < 0) {
24
-        pr_err("Error: invalid nodemap!\n");
28
-        pr_err("Error: invalid nodemap!\n");
25
-        return -1;
29
-        return -1;
26
-    }
30
-    }
27
+    /*
31
+    /*
28
+     * qemu virt-machine has only one eio intc and more than four cpus
32
+     * Qemu virt-machine has only one eiointc and more than four cpus.
29
+     * irq from eio can only be routed to cpu 0-3 on virt machine
33
+     * Irq from eiointc can only be routed to cpu 0-3, cpus except 0-3
34
+     * need not initialize eiointc on virt-machine
30
+     */
35
+     */
31
+    if (index < 0)
36
+    if (index < 0)
32
+        return 0;
37
+        return 0;
33
38
34
    if ((cpu_logical_map(cpu) % CORES_PER_EIO_NODE) == 0) {
39
    if ((cpu_logical_map(cpu) % CORES_PER_EIO_NODE) == 0) {
35
        eiointc_enable();
40
        eiointc_enable();
36
--
41
--
37
2.27.0
42
2.27.0
43
diff view generated by jsdifflib
1
Some LoongArch systems has only one eioi node such as 3A5000/2K2000
1
Some LoongArch systems have only one eiointc node such as 3A5000/2K2000
2
and qemu virt machine. If there is only one eioi node, all cpus can
2
and qemu virt-machine. If there is only one eiointc node, all cpus can
3
access eioi register directly; if there is multiple eioi nodes, cpus
3
access eiointc registers directly; if there is multiple eiointc nodes, each
4
can only access specified eioi node, so anysend or ipi need be used
4
cpu can only access eiointc belonging to specified node group, so anysend
5
to configure irq routing. IRQ routing is simple on such system with
5
or ipi needs to be used to configure irq routing. IRQ routing is simple on
6
one node, hacking method like anysend is not necessary.
6
such systems with one node, method like anysend is not necessary.
7
7
8
This patch is tested on 3A5000 board and qemu virt machine.
8
This patch provides simpile IRQ routing method for systems with one eiointc
9
node, and is tested on 3A5000 board and qemu virt-machine.
9
10
10
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
11
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
11
---
12
---
12
drivers/irqchip/irq-loongson-eiointc.c | 79 ++++++++++++++++++++++++--
13
drivers/irqchip/irq-loongson-eiointc.c | 80 ++++++++++++++++++++++++--
13
1 file changed, 73 insertions(+), 6 deletions(-)
14
1 file changed, 74 insertions(+), 6 deletions(-)
14
15
15
diff --git a/drivers/irqchip/irq-loongson-eiointc.c b/drivers/irqchip/irq-loongson-eiointc.c
16
diff --git a/drivers/irqchip/irq-loongson-eiointc.c b/drivers/irqchip/irq-loongson-eiointc.c
16
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
17
--- a/drivers/irqchip/irq-loongson-eiointc.c
18
--- a/drivers/irqchip/irq-loongson-eiointc.c
18
+++ b/drivers/irqchip/irq-loongson-eiointc.c
19
+++ b/drivers/irqchip/irq-loongson-eiointc.c
...
...
39
+    regaddr = EIOINTC_REG_ENABLE + ((vector >> 5) << 2);
40
+    regaddr = EIOINTC_REG_ENABLE + ((vector >> 5) << 2);
40
+    data = ~BIT(vector & 0x1F);
41
+    data = ~BIT(vector & 0x1F);
41
+    coremap = BIT(cpu_logical_map(cpu) % CORES_PER_EIO_NODE);
42
+    coremap = BIT(cpu_logical_map(cpu) % CORES_PER_EIO_NODE);
42
+
43
+
43
+    /*
44
+    /*
44
+     * simplify for only one eio node
45
+     * simplify for platform with only one eiointc node
45
+     * access eio registers directly rather than
46
+     * access eiointc registers directly rather than
46
+     * use any_send hack method here
47
+     * use any_send method here
47
+     */
48
+     */
48
+    raw_spin_lock_irqsave(&affinity_lock, flags);
49
+    raw_spin_lock_irqsave(&affinity_lock, flags);
49
+    iocsr_write32(EIOINTC_ALL_ENABLE & data, regaddr);
50
+    iocsr_write32(EIOINTC_ALL_ENABLE & data, regaddr);
50
+    /*
51
+    /*
51
+     * get irq route info for continuous 4 vectors
52
+     * get irq route info for continuous 4 vectors
...
...
67
    int i;
68
    int i;
68
@@ -XXX,XX +XXX,XX @@ static struct irq_chip eiointc_irq_chip = {
69
@@ -XXX,XX +XXX,XX @@ static struct irq_chip eiointc_irq_chip = {
69
    .irq_set_affinity    = eiointc_set_irq_affinity,
70
    .irq_set_affinity    = eiointc_set_irq_affinity,
70
};
71
};
71
72
72
+static struct irq_chip eiointc_irq_chipi_single = {
73
+static struct irq_chip eiointc_irq_chip_single = {
73
+    .name            = "EIOINTC-S",
74
+    .name            = "EIOINTC-S",
74
+    .irq_ack        = eiointc_ack_irq,
75
+    .irq_ack        = eiointc_ack_irq,
75
+    .irq_mask        = eiointc_mask_irq,
76
+    .irq_mask        = eiointc_mask_irq,
76
+    .irq_unmask        = eiointc_unmask_irq,
77
+    .irq_unmask        = eiointc_unmask_irq,
77
+#ifdef CONFIG_SMP
78
+#ifdef CONFIG_SMP
...
...
94
        return ret;
95
        return ret;
95
96
96
-    for (i = 0; i < nr_irqs; i++) {
97
-    for (i = 0; i < nr_irqs; i++) {
97
-        irq_domain_set_info(domain, virq + i, hwirq + i, &eiointc_irq_chip,
98
-        irq_domain_set_info(domain, virq + i, hwirq + i, &eiointc_irq_chip,
98
+    /*
99
+    /*
99
+     * use simple irq route method for single node eiointc
100
+     * use simple irq routing method on single eiointc node
100
+     */
101
+     */
101
+    if ((nr_pics == 1) && (nodes_weight(priv->node_map) == 1))
102
+    if ((nr_pics == 1) && (nodes_weight(priv->node_map) == 1))
102
+        chip = &eiointc_irq_chipi_single;
103
+        chip = &eiointc_irq_chip_single;
103
+    else
104
+    else
104
+        chip = &eiointc_irq_chip;
105
+        chip = &eiointc_irq_chip;
105
+    for (i = 0; i < nr_irqs; i++)
106
+    for (i = 0; i < nr_irqs; i++)
106
+        irq_domain_set_info(domain, virq + i, hwirq + i, chip,
107
+        irq_domain_set_info(domain, virq + i, hwirq + i, chip,
107
                    priv, handle_edge_irq, NULL, NULL);
108
                    priv, handle_edge_irq, NULL, NULL);
...
...
131
    priv->node = 0;
132
    priv->node = 0;
132
    priv->domain_handle = of_node_to_fwnode(of_node);
133
    priv->domain_handle = of_node_to_fwnode(of_node);
133
134
134
-    ret = eiointc_init(priv, parent_irq, 0);
135
-    ret = eiointc_init(priv, parent_irq, 0);
135
+    /*
136
+    /*
136
+     * 2k0500 and 2k2000 has only one eio node
137
+     * 2k0500 and 2k2000 has only one eiointc node
137
+     * set nodemap as 1 for simple irq routing
138
+     * set nodemap as 1 for simple irq routing
138
+     * what about for future embedded board more than 4 cpus??
139
+     *
140
+     * Fixme: what about future embedded boards with more than 4 cpus?
139
+     * nodemap and node need be added in dts like acpi table
141
+     * nodemap and node need be added in dts like acpi table
140
+     */
142
+     */
141
+    ret = eiointc_init(priv, parent_irq, 1);
143
+    ret = eiointc_init(priv, parent_irq, 1);
142
    if (ret < 0)
144
    if (ret < 0)
143
        goto out_free_priv;
145
        goto out_free_priv;
144
146
145
--
147
--
146
2.27.0
148
2.27.0
diff view generated by jsdifflib