• Home
  • Raw
  • Download

Lines Matching +full:interrupt +full:- +full:present

1 // SPDX-License-Identifier: GPL-2.0
8 #include <linux/interrupt.h>
23 * This driver implements a version of the RISC-V PLIC with the actual layout
26 * https://static.dev.sifive.com/U54-MC-RVCoreIP.pdf
28 * The largest number supported by devices marked as 'sifive,plic-1.0.0', is
29 * 1024, of which device 0 is defined as non-existent by the RISC-V Privileged
37 * Each interrupt source has a priority register associated with it.
44 * Each hart context has a vector of interrupt enable bits associated with it.
45 * There's one bit for each interrupt source.
53 * take an interrupt, and a register to claim interrupts.
70 bool present; member
87 u32 __iomem *reg = handler->enable_base + (hwirq / 32) * sizeof(u32); in plic_toggle()
90 raw_spin_lock(&handler->enable_lock); in plic_toggle()
95 raw_spin_unlock(&handler->enable_lock); in plic_toggle()
104 writel(enable, priv->regs + PRIORITY_BASE + d->hwirq * PRIORITY_PER_ID); in plic_irq_toggle()
108 if (handler->present && in plic_irq_toggle()
109 cpumask_test_cpu(cpu, &handler->priv->lmask)) in plic_irq_toggle()
110 plic_toggle(handler, d->hwirq, enable); in plic_irq_toggle()
120 cpumask_and(&amask, &priv->lmask, cpu_online_mask); in plic_irq_unmask()
132 plic_irq_toggle(&priv->lmask, d, 0); in plic_irq_mask()
143 cpumask_and(&amask, &priv->lmask, mask_val); in plic_set_affinity()
151 return -EINVAL; in plic_set_affinity()
153 plic_irq_toggle(&priv->lmask, d, 0); in plic_set_affinity()
168 writel(d->hwirq, handler->hart_base + CONTEXT_CLAIM); in plic_irq_eoi()
171 writel(d->hwirq, handler->hart_base + CONTEXT_CLAIM); in plic_irq_eoi()
188 struct plic_priv *priv = d->host_data; in plic_irqdomain_map()
190 irq_domain_set_info(d, irq, hwirq, &plic_chip, d->host_data, in plic_irqdomain_map()
193 irq_set_affinity(irq, &priv->lmask); in plic_irqdomain_map()
225 * Handling an interrupt is a two-step process: first you claim the interrupt
226 * by reading the claim register, then you complete the interrupt by writing
228 * and disables the interrupt, so there's nothing else to do.
234 void __iomem *claim = handler->hart_base + CONTEXT_CLAIM; in plic_handle_irq()
237 WARN_ON_ONCE(!handler->present); in plic_handle_irq()
242 int irq = irq_find_mapping(handler->priv->irqdomain, hwirq); in plic_handle_irq()
256 /* priority must be > threshold to trigger an interrupt */ in plic_set_threshold()
257 writel(threshold, handler->hart_base + CONTEXT_THRESHOLD); in plic_set_threshold()
292 return -ENOMEM; in plic_init()
294 priv->regs = of_iomap(node, 0); in plic_init()
295 if (WARN_ON(!priv->regs)) { in plic_init()
296 error = -EIO; in plic_init()
300 error = -EINVAL; in plic_init()
309 error = -ENOMEM; in plic_init()
310 priv->irqdomain = irq_domain_add_linear(node, nr_irqs + 1, in plic_init()
312 if (WARN_ON(!priv->irqdomain)) in plic_init()
353 * When running in M-mode we need to ignore the S-mode handler. in plic_init()
358 if (handler->present) { in plic_init()
359 pr_warn("handler already present for context %d.\n", i); in plic_init()
364 cpumask_set_cpu(cpu, &priv->lmask); in plic_init()
365 handler->present = true; in plic_init()
366 handler->hart_base = in plic_init()
367 priv->regs + CONTEXT_BASE + i * CONTEXT_PER_HART; in plic_init()
368 raw_spin_lock_init(&handler->enable_lock); in plic_init()
369 handler->enable_base = in plic_init()
370 priv->regs + ENABLE_BASE + i * ENABLE_PER_HART; in plic_init()
371 handler->priv = priv; in plic_init()
380 * when context handler for current/boot CPU is present. in plic_init()
383 if (handler->present && !plic_cpuhp_setup_done) { in plic_init()
395 iounmap(priv->regs); in plic_init()
401 IRQCHIP_DECLARE(sifive_plic, "sifive,plic-1.0.0", plic_init);
403 IRQCHIP_DECLARE(thead_c900_plic, "thead,c900-plic", plic_init); /* for firmware driver */