Skip to content

Commit

Permalink
Merge branch 'irq-urgent-for-linus' of git://git.kernel.org/pub/scm/l…
Browse files Browse the repository at this point in the history
…inux/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
  • Loading branch information
Linus Torvalds committed Oct 20, 2019
2 parents 188768f + c9b5918 commit 81c4bc3
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 17 deletions.
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
* Advanced Interrupt Controller (AIC)

Required properties:
- compatible: Should be "atmel,<chip>-aic"
<chip> can be "at91rm9200", "sama5d2", "sama5d3" or "sama5d4"
- compatible: Should be:
- "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-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).
Expand Down
12 changes: 12 additions & 0 deletions drivers/irqchip/irq-al-fic.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

/* FIC Registers */
#define AL_FIC_CAUSE 0x00
#define AL_FIC_SET_CAUSE 0x08
#define AL_FIC_MASK 0x10
#define AL_FIC_CONTROL 0x28

Expand Down Expand Up @@ -126,6 +127,16 @@ static void al_fic_irq_handler(struct irq_desc *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,
struct al_fic *fic)
{
Expand Down Expand Up @@ -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_ack = irq_gc_ack_clr_bit;
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->private = fic;

Expand Down
10 changes: 10 additions & 0 deletions drivers/irqchip/irq-atmel-aic5.c
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,7 @@ static void __init sama5d3_aic_irq_fixup(void)
static const struct of_device_id aic5_irq_fixups[] __initconst = {
{ .compatible = "atmel,sama5d3", .data = sama5d3_aic_irq_fixup },
{ .compatible = "atmel,sama5d4", .data = sama5d3_aic_irq_fixup },
{ .compatible = "microchip,sam9x60", .data = sama5d3_aic_irq_fixup },
{ /* sentinel */ },
};

Expand Down Expand Up @@ -390,3 +391,12 @@ static int __init sama5d4_aic5_of_init(struct device_node *node,
return aic5_of_init(node, parent, NR_SAMA5D4_IRQS);
}
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);
2 changes: 1 addition & 1 deletion drivers/irqchip/irq-gic-v3.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ static struct gic_chip_data gic_data __read_mostly;
static DEFINE_STATIC_KEY_TRUE(supports_deactivate_key);

#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)

/*
Expand Down
29 changes: 15 additions & 14 deletions drivers/irqchip/irq-sifive-plic.c
Original file line number Diff line number Diff line change
Expand Up @@ -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),
cpu_online_mask);
Expand All @@ -106,7 +106,7 @@ static void plic_irq_enable(struct irq_data *d)
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);
}
Expand All @@ -125,25 +125,27 @@ static int plic_set_affinity(struct irq_data *d,
if (cpu >= nr_cpu_ids)
return -EINVAL;

if (!irqd_irq_disabled(d)) {
plic_irq_toggle(cpu_possible_mask, d->hwirq, 0);
plic_irq_toggle(cpumask_of(cpu), d->hwirq, 1);
}
plic_irq_toggle(cpu_possible_mask, d->hwirq, 0);
plic_irq_toggle(cpumask_of(cpu), d->hwirq, 1);

irq_data_update_effective_affinity(d, cpumask_of(cpu));

return IRQ_SET_MASK_OK_DONE;
}
#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 = {
.name = "SiFive PLIC",
/*
* There is no need to mask/unmask PLIC interrupts. They are "masked"
* by reading claim and "unmasked" when writing it back.
*/
.irq_enable = plic_irq_enable,
.irq_disable = plic_irq_disable,
.irq_mask = plic_irq_mask,
.irq_unmask = plic_irq_unmask,
.irq_eoi = plic_irq_eoi,
#ifdef CONFIG_SMP
.irq_set_affinity = plic_set_affinity,
#endif
Expand All @@ -152,7 +154,7 @@ static struct irq_chip plic_chip = {
static int plic_irqdomain_map(struct irq_domain *d, unsigned int irq,
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_noprobe(irq);
return 0;
Expand Down Expand Up @@ -188,7 +190,6 @@ static void plic_handle_irq(struct pt_regs *regs)
hwirq);
else
generic_handle_irq(irq);
writel(hwirq, claim);
}
csr_set(sie, SIE_SEIE);
}
Expand Down

0 comments on commit 81c4bc3

Please sign in to comment.