Commit c9b59181 authored by Thomas Gleixner's avatar Thomas Gleixner

Merge tag 'irqchip-fixes-5.4-1' of...

Merge tag 'irqchip-fixes-5.4-1' of git://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms into irq/urgent

Pull irqchip fixes from Marc Zyngier:

 - Add retrigger support to Amazon's al-fic driver
 - Add SAM9X60 support to Atmel's AIC5 irqchip
 - Fix GICv3 maximum interrupt calculation
 - Convert SiFive's PLIC to the fasteoi IRQ flow
parents 4f5cafb5 bb0fed1c
* Advanced Interrupt Controller (AIC) * Advanced Interrupt Controller (AIC)
Required properties: Required properties:
- compatible: Should be "atmel,<chip>-aic" - compatible: Should be:
<chip> can be "at91rm9200", "sama5d2", "sama5d3" or "sama5d4" - "atmel,<chip>-aic" where <chip> can be "at91rm9200", "sama5d2",
"sama5d3" or "sama5d4"
- "microchip,<chip>-aic" where <chip> can be "sam9x60"
- interrupt-controller: Identifies the node as an interrupt controller. - interrupt-controller: Identifies the node as an interrupt controller.
- #interrupt-cells: The number of cells to define the interrupts. It should be 3. - #interrupt-cells: The number of cells to define the interrupts. It should be 3.
The first cell is the IRQ number (aka "Peripheral IDentifier" on datasheet). The first cell is the IRQ number (aka "Peripheral IDentifier" on datasheet).
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
/* FIC Registers */ /* FIC Registers */
#define AL_FIC_CAUSE 0x00 #define AL_FIC_CAUSE 0x00
#define AL_FIC_SET_CAUSE 0x08
#define AL_FIC_MASK 0x10 #define AL_FIC_MASK 0x10
#define AL_FIC_CONTROL 0x28 #define AL_FIC_CONTROL 0x28
...@@ -126,6 +127,16 @@ static void al_fic_irq_handler(struct irq_desc *desc) ...@@ -126,6 +127,16 @@ static void al_fic_irq_handler(struct irq_desc *desc)
chained_irq_exit(irqchip, desc); chained_irq_exit(irqchip, desc);
} }
static int al_fic_irq_retrigger(struct irq_data *data)
{
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(data);
struct al_fic *fic = gc->private;
writel_relaxed(BIT(data->hwirq), fic->base + AL_FIC_SET_CAUSE);
return 1;
}
static int al_fic_register(struct device_node *node, static int al_fic_register(struct device_node *node,
struct al_fic *fic) struct al_fic *fic)
{ {
...@@ -159,6 +170,7 @@ static int al_fic_register(struct device_node *node, ...@@ -159,6 +170,7 @@ static int al_fic_register(struct device_node *node,
gc->chip_types->chip.irq_unmask = irq_gc_mask_clr_bit; gc->chip_types->chip.irq_unmask = irq_gc_mask_clr_bit;
gc->chip_types->chip.irq_ack = irq_gc_ack_clr_bit; gc->chip_types->chip.irq_ack = irq_gc_ack_clr_bit;
gc->chip_types->chip.irq_set_type = al_fic_irq_set_type; gc->chip_types->chip.irq_set_type = al_fic_irq_set_type;
gc->chip_types->chip.irq_retrigger = al_fic_irq_retrigger;
gc->chip_types->chip.flags = IRQCHIP_SKIP_SET_WAKE; gc->chip_types->chip.flags = IRQCHIP_SKIP_SET_WAKE;
gc->private = fic; gc->private = fic;
......
...@@ -313,6 +313,7 @@ static void __init sama5d3_aic_irq_fixup(void) ...@@ -313,6 +313,7 @@ static void __init sama5d3_aic_irq_fixup(void)
static const struct of_device_id aic5_irq_fixups[] __initconst = { static const struct of_device_id aic5_irq_fixups[] __initconst = {
{ .compatible = "atmel,sama5d3", .data = sama5d3_aic_irq_fixup }, { .compatible = "atmel,sama5d3", .data = sama5d3_aic_irq_fixup },
{ .compatible = "atmel,sama5d4", .data = sama5d3_aic_irq_fixup }, { .compatible = "atmel,sama5d4", .data = sama5d3_aic_irq_fixup },
{ .compatible = "microchip,sam9x60", .data = sama5d3_aic_irq_fixup },
{ /* sentinel */ }, { /* sentinel */ },
}; };
...@@ -390,3 +391,12 @@ static int __init sama5d4_aic5_of_init(struct device_node *node, ...@@ -390,3 +391,12 @@ static int __init sama5d4_aic5_of_init(struct device_node *node,
return aic5_of_init(node, parent, NR_SAMA5D4_IRQS); return aic5_of_init(node, parent, NR_SAMA5D4_IRQS);
} }
IRQCHIP_DECLARE(sama5d4_aic5, "atmel,sama5d4-aic", sama5d4_aic5_of_init); IRQCHIP_DECLARE(sama5d4_aic5, "atmel,sama5d4-aic", sama5d4_aic5_of_init);
#define NR_SAM9X60_IRQS 50
static int __init sam9x60_aic5_of_init(struct device_node *node,
struct device_node *parent)
{
return aic5_of_init(node, parent, NR_SAM9X60_IRQS);
}
IRQCHIP_DECLARE(sam9x60_aic5, "microchip,sam9x60-aic", sam9x60_aic5_of_init);
...@@ -59,7 +59,7 @@ static struct gic_chip_data gic_data __read_mostly; ...@@ -59,7 +59,7 @@ static struct gic_chip_data gic_data __read_mostly;
static DEFINE_STATIC_KEY_TRUE(supports_deactivate_key); static DEFINE_STATIC_KEY_TRUE(supports_deactivate_key);
#define GIC_ID_NR (1U << GICD_TYPER_ID_BITS(gic_data.rdists.gicd_typer)) #define GIC_ID_NR (1U << GICD_TYPER_ID_BITS(gic_data.rdists.gicd_typer))
#define GIC_LINE_NR max(GICD_TYPER_SPIS(gic_data.rdists.gicd_typer), 1020U) #define GIC_LINE_NR min(GICD_TYPER_SPIS(gic_data.rdists.gicd_typer), 1020U)
#define GIC_ESPI_NR GICD_TYPER_ESPIS(gic_data.rdists.gicd_typer) #define GIC_ESPI_NR GICD_TYPER_ESPIS(gic_data.rdists.gicd_typer)
/* /*
......
...@@ -97,7 +97,7 @@ static inline void plic_irq_toggle(const struct cpumask *mask, ...@@ -97,7 +97,7 @@ static inline void plic_irq_toggle(const struct cpumask *mask,
} }
} }
static void plic_irq_enable(struct irq_data *d) static void plic_irq_unmask(struct irq_data *d)
{ {
unsigned int cpu = cpumask_any_and(irq_data_get_affinity_mask(d), unsigned int cpu = cpumask_any_and(irq_data_get_affinity_mask(d),
cpu_online_mask); cpu_online_mask);
...@@ -106,7 +106,7 @@ static void plic_irq_enable(struct irq_data *d) ...@@ -106,7 +106,7 @@ static void plic_irq_enable(struct irq_data *d)
plic_irq_toggle(cpumask_of(cpu), d->hwirq, 1); plic_irq_toggle(cpumask_of(cpu), d->hwirq, 1);
} }
static void plic_irq_disable(struct irq_data *d) static void plic_irq_mask(struct irq_data *d)
{ {
plic_irq_toggle(cpu_possible_mask, d->hwirq, 0); plic_irq_toggle(cpu_possible_mask, d->hwirq, 0);
} }
...@@ -125,10 +125,8 @@ static int plic_set_affinity(struct irq_data *d, ...@@ -125,10 +125,8 @@ static int plic_set_affinity(struct irq_data *d,
if (cpu >= nr_cpu_ids) if (cpu >= nr_cpu_ids)
return -EINVAL; return -EINVAL;
if (!irqd_irq_disabled(d)) { plic_irq_toggle(cpu_possible_mask, d->hwirq, 0);
plic_irq_toggle(cpu_possible_mask, d->hwirq, 0); plic_irq_toggle(cpumask_of(cpu), d->hwirq, 1);
plic_irq_toggle(cpumask_of(cpu), d->hwirq, 1);
}
irq_data_update_effective_affinity(d, cpumask_of(cpu)); irq_data_update_effective_affinity(d, cpumask_of(cpu));
...@@ -136,14 +134,18 @@ static int plic_set_affinity(struct irq_data *d, ...@@ -136,14 +134,18 @@ static int plic_set_affinity(struct irq_data *d,
} }
#endif #endif
static void plic_irq_eoi(struct irq_data *d)
{
struct plic_handler *handler = this_cpu_ptr(&plic_handlers);
writel(d->hwirq, handler->hart_base + CONTEXT_CLAIM);
}
static struct irq_chip plic_chip = { static struct irq_chip plic_chip = {
.name = "SiFive PLIC", .name = "SiFive PLIC",
/* .irq_mask = plic_irq_mask,
* There is no need to mask/unmask PLIC interrupts. They are "masked" .irq_unmask = plic_irq_unmask,
* by reading claim and "unmasked" when writing it back. .irq_eoi = plic_irq_eoi,
*/
.irq_enable = plic_irq_enable,
.irq_disable = plic_irq_disable,
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
.irq_set_affinity = plic_set_affinity, .irq_set_affinity = plic_set_affinity,
#endif #endif
...@@ -152,7 +154,7 @@ static struct irq_chip plic_chip = { ...@@ -152,7 +154,7 @@ static struct irq_chip plic_chip = {
static int plic_irqdomain_map(struct irq_domain *d, unsigned int irq, static int plic_irqdomain_map(struct irq_domain *d, unsigned int irq,
irq_hw_number_t hwirq) irq_hw_number_t hwirq)
{ {
irq_set_chip_and_handler(irq, &plic_chip, handle_simple_irq); irq_set_chip_and_handler(irq, &plic_chip, handle_fasteoi_irq);
irq_set_chip_data(irq, NULL); irq_set_chip_data(irq, NULL);
irq_set_noprobe(irq); irq_set_noprobe(irq);
return 0; return 0;
...@@ -188,7 +190,6 @@ static void plic_handle_irq(struct pt_regs *regs) ...@@ -188,7 +190,6 @@ static void plic_handle_irq(struct pt_regs *regs)
hwirq); hwirq);
else else
generic_handle_irq(irq); generic_handle_irq(irq);
writel(hwirq, claim);
} }
csr_set(sie, SIE_SEIE); csr_set(sie, SIE_SEIE);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment