Skip to content

Commit bb0fed1

Browse files
author
Marc Zyngier
committed
irqchip/sifive-plic: Switch to fasteoi flow
The SiFive PLIC interrupt controller seems to have all the HW features to support the fasteoi flow, but the driver seems to be stuck in a distant past. Bring it into the 21st century. Signed-off-by: Marc Zyngier <[email protected]> Tested-by: Palmer Dabbelt <[email protected]> (QEMU Boot) Tested-by: Darius Rad <[email protected]> (on 2 HW PLIC implementations) Tested-by: Paul Walmsley <[email protected]> (HiFive Unleashed) Reviewed-by: Palmer Dabbelt <[email protected]> Cc: [email protected] Link: https://lore.kernel.org/r/[email protected]
1 parent c107d61 commit bb0fed1

File tree

1 file changed

+15
-14
lines changed

1 file changed

+15
-14
lines changed

drivers/irqchip/irq-sifive-plic.c

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ static inline void plic_irq_toggle(const struct cpumask *mask,
9797
}
9898
}
9999

100-
static void plic_irq_enable(struct irq_data *d)
100+
static void plic_irq_unmask(struct irq_data *d)
101101
{
102102
unsigned int cpu = cpumask_any_and(irq_data_get_affinity_mask(d),
103103
cpu_online_mask);
@@ -106,7 +106,7 @@ static void plic_irq_enable(struct irq_data *d)
106106
plic_irq_toggle(cpumask_of(cpu), d->hwirq, 1);
107107
}
108108

109-
static void plic_irq_disable(struct irq_data *d)
109+
static void plic_irq_mask(struct irq_data *d)
110110
{
111111
plic_irq_toggle(cpu_possible_mask, d->hwirq, 0);
112112
}
@@ -125,25 +125,27 @@ static int plic_set_affinity(struct irq_data *d,
125125
if (cpu >= nr_cpu_ids)
126126
return -EINVAL;
127127

128-
if (!irqd_irq_disabled(d)) {
129-
plic_irq_toggle(cpu_possible_mask, d->hwirq, 0);
130-
plic_irq_toggle(cpumask_of(cpu), d->hwirq, 1);
131-
}
128+
plic_irq_toggle(cpu_possible_mask, d->hwirq, 0);
129+
plic_irq_toggle(cpumask_of(cpu), d->hwirq, 1);
132130

133131
irq_data_update_effective_affinity(d, cpumask_of(cpu));
134132

135133
return IRQ_SET_MASK_OK_DONE;
136134
}
137135
#endif
138136

137+
static void plic_irq_eoi(struct irq_data *d)
138+
{
139+
struct plic_handler *handler = this_cpu_ptr(&plic_handlers);
140+
141+
writel(d->hwirq, handler->hart_base + CONTEXT_CLAIM);
142+
}
143+
139144
static struct irq_chip plic_chip = {
140145
.name = "SiFive PLIC",
141-
/*
142-
* There is no need to mask/unmask PLIC interrupts. They are "masked"
143-
* by reading claim and "unmasked" when writing it back.
144-
*/
145-
.irq_enable = plic_irq_enable,
146-
.irq_disable = plic_irq_disable,
146+
.irq_mask = plic_irq_mask,
147+
.irq_unmask = plic_irq_unmask,
148+
.irq_eoi = plic_irq_eoi,
147149
#ifdef CONFIG_SMP
148150
.irq_set_affinity = plic_set_affinity,
149151
#endif
@@ -152,7 +154,7 @@ static struct irq_chip plic_chip = {
152154
static int plic_irqdomain_map(struct irq_domain *d, unsigned int irq,
153155
irq_hw_number_t hwirq)
154156
{
155-
irq_set_chip_and_handler(irq, &plic_chip, handle_simple_irq);
157+
irq_set_chip_and_handler(irq, &plic_chip, handle_fasteoi_irq);
156158
irq_set_chip_data(irq, NULL);
157159
irq_set_noprobe(irq);
158160
return 0;
@@ -188,7 +190,6 @@ static void plic_handle_irq(struct pt_regs *regs)
188190
hwirq);
189191
else
190192
generic_handle_irq(irq);
191-
writel(hwirq, claim);
192193
}
193194
csr_set(sie, SIE_SEIE);
194195
}

0 commit comments

Comments
 (0)