Lines Matching +full:plic +full:- +full:1
1 // SPDX-License-Identifier: GPL-2.0
6 #define pr_fmt(fmt) "plic: " fmt
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
92 u32 hwirq_mask = 1 << (hwirq % 32); in __plic_toggle()
102 raw_spin_lock(&handler->enable_lock); in plic_toggle()
103 __plic_toggle(handler->enable_base, hwirq, enable); in plic_toggle()
104 raw_spin_unlock(&handler->enable_lock); in plic_toggle()
115 plic_toggle(handler, d->hwirq, enable); in plic_irq_toggle()
121 plic_irq_toggle(irq_data_get_effective_affinity_mask(d), d, 1); in plic_irq_enable()
133 writel(1, priv->regs + PRIORITY_BASE + d->hwirq * PRIORITY_PER_ID); in plic_irq_unmask()
140 writel(0, priv->regs + PRIORITY_BASE + d->hwirq * PRIORITY_PER_ID); in plic_irq_mask()
147 writel(d->hwirq, handler->hart_base + CONTEXT_CLAIM); in plic_irq_eoi()
158 cpumask_and(&amask, &priv->lmask, mask_val); in plic_set_affinity()
166 return -EINVAL; in plic_set_affinity()
180 .name = "SiFive PLIC",
194 .name = "SiFive PLIC",
211 if (!test_bit(PLIC_QUIRK_EDGE_INTERRUPT, &priv->plic_quirks)) in plic_irq_set_type()
224 return -EINVAL; in plic_irq_set_type()
233 struct plic_priv *priv = d->host_data; in plic_irqdomain_map()
235 irq_domain_set_info(d, irq, hwirq, &plic_chip, d->host_data, in plic_irqdomain_map()
238 irq_set_affinity(irq, &priv->lmask); in plic_irqdomain_map()
247 struct plic_priv *priv = d->host_data; in plic_irq_domain_translate()
249 if (test_bit(PLIC_QUIRK_EDGE_INTERRUPT, &priv->plic_quirks)) in plic_irq_domain_translate()
283 * Handling an interrupt is a two-step process: first you claim the interrupt
292 void __iomem *claim = handler->hart_base + CONTEXT_CLAIM; in plic_handle_irq()
295 WARN_ON_ONCE(!handler->present); in plic_handle_irq()
300 int err = generic_handle_domain_irq(handler->priv->irqdomain, in plic_handle_irq()
313 writel(threshold, handler->hart_base + CONTEXT_THRESHOLD); in plic_set_threshold()
349 return -ENOMEM; in __plic_init()
351 priv->plic_quirks = plic_quirks; in __plic_init()
353 priv->regs = of_iomap(node, 0); in __plic_init()
354 if (WARN_ON(!priv->regs)) { in __plic_init()
355 error = -EIO; in __plic_init()
359 error = -EINVAL; in __plic_init()
368 error = -ENOMEM; in __plic_init()
369 priv->irqdomain = irq_domain_add_linear(node, nr_irqs + 1, in __plic_init()
371 if (WARN_ON(!priv->irqdomain)) in __plic_init()
390 /* Disable S-mode enable bits if running in M-mode. */ in __plic_init()
392 void __iomem *enable_base = priv->regs + in __plic_init()
396 for (hwirq = 1; hwirq <= nr_irqs; hwirq++) in __plic_init()
423 * When running in M-mode we need to ignore the S-mode handler. in __plic_init()
428 if (handler->present) { in __plic_init()
434 cpumask_set_cpu(cpu, &priv->lmask); in __plic_init()
435 handler->present = true; in __plic_init()
436 handler->hart_base = priv->regs + CONTEXT_BASE + in __plic_init()
438 raw_spin_lock_init(&handler->enable_lock); in __plic_init()
439 handler->enable_base = priv->regs + CONTEXT_ENABLE_BASE + in __plic_init()
441 handler->priv = priv; in __plic_init()
443 for (hwirq = 1; hwirq <= nr_irqs; hwirq++) { in __plic_init()
445 writel(1, priv->regs + PRIORITY_BASE + in __plic_init()
452 * We can have multiple PLIC instances so setup cpuhp state only in __plic_init()
456 if (handler->present && !plic_cpuhp_setup_done) { in __plic_init()
458 "irqchip/sifive/plic:starting", in __plic_init()
468 iounmap(priv->regs); in __plic_init()
480 IRQCHIP_DECLARE(sifive_plic, "sifive,plic-1.0.0", plic_init);
490 IRQCHIP_DECLARE(thead_c900_plic, "thead,c900-plic", plic_edge_init);