Skip to content

Commit c47e388

Browse files
chenhuacaiMarc Zyngier
authored andcommitted
irqchip/loongson-htvec: Support 8 groups of HT vectors
The original version can only used by old Loongson-3 which only use 4 groups of HT vectors. Now Loongson-3A R4 can use 8 groups, so improve the driver to support all 8 groups. Fixes: 818e915 ("irqchip: Add Loongson HyperTransport Vector support") Signed-off-by: Huacai Chen <[email protected]> Signed-off-by: Marc Zyngier <[email protected]> Reviewed-by: Jiaxun Yang <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent c9c73a0 commit c47e388

File tree

1 file changed

+10
-12
lines changed

1 file changed

+10
-12
lines changed

drivers/irqchip/irq-loongson-htvec.c

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,14 @@
1919

2020
/* Registers */
2121
#define HTVEC_EN_OFF 0x20
22-
#define HTVEC_MAX_PARENT_IRQ 4
22+
#define HTVEC_MAX_PARENT_IRQ 8
2323

2424
#define VEC_COUNT_PER_REG 32
25-
#define VEC_REG_COUNT 4
26-
#define VEC_COUNT (VEC_COUNT_PER_REG * VEC_REG_COUNT)
2725
#define VEC_REG_IDX(irq_id) ((irq_id) / VEC_COUNT_PER_REG)
2826
#define VEC_REG_BIT(irq_id) ((irq_id) % VEC_COUNT_PER_REG)
2927

3028
struct htvec {
29+
int num_parents;
3130
void __iomem *base;
3231
struct irq_domain *htvec_domain;
3332
raw_spinlock_t htvec_lock;
@@ -43,7 +42,7 @@ static void htvec_irq_dispatch(struct irq_desc *desc)
4342

4443
chained_irq_enter(chip, desc);
4544

46-
for (i = 0; i < VEC_REG_COUNT; i++) {
45+
for (i = 0; i < priv->num_parents; i++) {
4746
pending = readl(priv->base + 4 * i);
4847
while (pending) {
4948
int bit = __ffs(pending);
@@ -150,7 +149,7 @@ static void htvec_reset(struct htvec *priv)
150149
u32 idx;
151150

152151
/* Clear IRQ cause registers, mask all interrupts */
153-
for (idx = 0; idx < VEC_REG_COUNT; idx++) {
152+
for (idx = 0; idx < priv->num_parents; idx++) {
154153
writel_relaxed(0x0, priv->base + HTVEC_EN_OFF + 4 * idx);
155154
writel_relaxed(0xFFFFFFFF, priv->base);
156155
}
@@ -160,7 +159,7 @@ static int htvec_of_init(struct device_node *node,
160159
struct device_node *parent)
161160
{
162161
struct htvec *priv;
163-
int err, parent_irq[4], num_parents = 0, i;
162+
int err, parent_irq[8], i;
164163

165164
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
166165
if (!priv)
@@ -179,19 +178,18 @@ static int htvec_of_init(struct device_node *node,
179178
if (parent_irq[i] <= 0)
180179
break;
181180

182-
num_parents++;
181+
priv->num_parents++;
183182
}
184183

185-
if (!num_parents) {
184+
if (!priv->num_parents) {
186185
pr_err("Failed to get parent irqs\n");
187186
err = -ENODEV;
188187
goto iounmap_base;
189188
}
190189

191190
priv->htvec_domain = irq_domain_create_linear(of_node_to_fwnode(node),
192-
VEC_COUNT,
193-
&htvec_domain_ops,
194-
priv);
191+
(VEC_COUNT_PER_REG * priv->num_parents),
192+
&htvec_domain_ops, priv);
195193
if (!priv->htvec_domain) {
196194
pr_err("Failed to create IRQ domain\n");
197195
err = -ENOMEM;
@@ -200,7 +198,7 @@ static int htvec_of_init(struct device_node *node,
200198

201199
htvec_reset(priv);
202200

203-
for (i = 0; i < num_parents; i++)
201+
for (i = 0; i < priv->num_parents; i++)
204202
irq_set_chained_handler_and_data(parent_irq[i],
205203
htvec_irq_dispatch, priv);
206204

0 commit comments

Comments
 (0)