Skip to content

Commit 81c4bc3

Browse files
committed
Merge branch 'irq-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull irq fixes from Thomas Gleixner: "A small set of irq chip driver fixes and updates: - Update the SIFIVE PLIC interrupt driver to use the fasteoi handler to address the shortcomings of the existing flow handling which was prone to lose interrupts - Use the proper limit for GIC interrupt line numbers - Add retrigger support for the recently merged Anapurna Labs Fabric interrupt controller to make it complete - Enable the ATMEL AIC5 interrupt controller driver on the new SAM9X60 SoC" * 'irq-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: irqchip/sifive-plic: Switch to fasteoi flow irqchip/gic-v3: Fix GIC_LINE_NR accessor irqchip/atmel-aic5: Add support for sam9x60 irqchip irqchip/al-fic: Add support for irq retrigger
2 parents 188768f + c9b5918 commit 81c4bc3

File tree

5 files changed

+43
-17
lines changed

5 files changed

+43
-17
lines changed

Documentation/devicetree/bindings/interrupt-controller/atmel,aic.txt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
* Advanced Interrupt Controller (AIC)
22

33
Required properties:
4-
- compatible: Should be "atmel,<chip>-aic"
5-
<chip> can be "at91rm9200", "sama5d2", "sama5d3" or "sama5d4"
4+
- compatible: Should be:
5+
- "atmel,<chip>-aic" where <chip> can be "at91rm9200", "sama5d2",
6+
"sama5d3" or "sama5d4"
7+
- "microchip,<chip>-aic" where <chip> can be "sam9x60"
8+
69
- interrupt-controller: Identifies the node as an interrupt controller.
710
- #interrupt-cells: The number of cells to define the interrupts. It should be 3.
811
The first cell is the IRQ number (aka "Peripheral IDentifier" on datasheet).

drivers/irqchip/irq-al-fic.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
/* FIC Registers */
1717
#define AL_FIC_CAUSE 0x00
18+
#define AL_FIC_SET_CAUSE 0x08
1819
#define AL_FIC_MASK 0x10
1920
#define AL_FIC_CONTROL 0x28
2021

@@ -126,6 +127,16 @@ static void al_fic_irq_handler(struct irq_desc *desc)
126127
chained_irq_exit(irqchip, desc);
127128
}
128129

130+
static int al_fic_irq_retrigger(struct irq_data *data)
131+
{
132+
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(data);
133+
struct al_fic *fic = gc->private;
134+
135+
writel_relaxed(BIT(data->hwirq), fic->base + AL_FIC_SET_CAUSE);
136+
137+
return 1;
138+
}
139+
129140
static int al_fic_register(struct device_node *node,
130141
struct al_fic *fic)
131142
{
@@ -159,6 +170,7 @@ static int al_fic_register(struct device_node *node,
159170
gc->chip_types->chip.irq_unmask = irq_gc_mask_clr_bit;
160171
gc->chip_types->chip.irq_ack = irq_gc_ack_clr_bit;
161172
gc->chip_types->chip.irq_set_type = al_fic_irq_set_type;
173+
gc->chip_types->chip.irq_retrigger = al_fic_irq_retrigger;
162174
gc->chip_types->chip.flags = IRQCHIP_SKIP_SET_WAKE;
163175
gc->private = fic;
164176

drivers/irqchip/irq-atmel-aic5.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,7 @@ static void __init sama5d3_aic_irq_fixup(void)
313313
static const struct of_device_id aic5_irq_fixups[] __initconst = {
314314
{ .compatible = "atmel,sama5d3", .data = sama5d3_aic_irq_fixup },
315315
{ .compatible = "atmel,sama5d4", .data = sama5d3_aic_irq_fixup },
316+
{ .compatible = "microchip,sam9x60", .data = sama5d3_aic_irq_fixup },
316317
{ /* sentinel */ },
317318
};
318319

@@ -390,3 +391,12 @@ static int __init sama5d4_aic5_of_init(struct device_node *node,
390391
return aic5_of_init(node, parent, NR_SAMA5D4_IRQS);
391392
}
392393
IRQCHIP_DECLARE(sama5d4_aic5, "atmel,sama5d4-aic", sama5d4_aic5_of_init);
394+
395+
#define NR_SAM9X60_IRQS 50
396+
397+
static int __init sam9x60_aic5_of_init(struct device_node *node,
398+
struct device_node *parent)
399+
{
400+
return aic5_of_init(node, parent, NR_SAM9X60_IRQS);
401+
}
402+
IRQCHIP_DECLARE(sam9x60_aic5, "microchip,sam9x60-aic", sam9x60_aic5_of_init);

drivers/irqchip/irq-gic-v3.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ static struct gic_chip_data gic_data __read_mostly;
5959
static DEFINE_STATIC_KEY_TRUE(supports_deactivate_key);
6060

6161
#define GIC_ID_NR (1U << GICD_TYPER_ID_BITS(gic_data.rdists.gicd_typer))
62-
#define GIC_LINE_NR max(GICD_TYPER_SPIS(gic_data.rdists.gicd_typer), 1020U)
62+
#define GIC_LINE_NR min(GICD_TYPER_SPIS(gic_data.rdists.gicd_typer), 1020U)
6363
#define GIC_ESPI_NR GICD_TYPER_ESPIS(gic_data.rdists.gicd_typer)
6464

6565
/*

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)