• Home
  • Raw
  • Download

Lines Matching +full:riscv +full:- +full:v +full:- +full:spec

1 // SPDX-License-Identifier: GPL-2.0
24 * This driver implements a version of the RISC-V PLIC with the actual layout
27 * https://static.dev.sifive.com/U54-MC-RVCoreIP.pdf
29 * The largest number supported by devices marked as 'sifive,plic-1.0.0', is
30 * 1024, of which device 0 is defined as non-existent by the RISC-V Privileged
31 * Spec.
106 raw_spin_lock(&handler->enable_lock); in plic_toggle()
107 __plic_toggle(handler->enable_base, hwirq, enable); in plic_toggle()
108 raw_spin_unlock(&handler->enable_lock); in plic_toggle()
119 plic_toggle(handler, d->hwirq, enable); in plic_irq_toggle()
127 writel(1, priv->regs + PRIORITY_BASE + d->hwirq * PRIORITY_PER_ID); in plic_irq_unmask()
134 writel(0, priv->regs + PRIORITY_BASE + d->hwirq * PRIORITY_PER_ID); in plic_irq_mask()
153 plic_toggle(handler, d->hwirq, 1); in plic_irq_eoi()
154 writel(d->hwirq, handler->hart_base + CONTEXT_CLAIM); in plic_irq_eoi()
155 plic_toggle(handler, d->hwirq, 0); in plic_irq_eoi()
157 writel(d->hwirq, handler->hart_base + CONTEXT_CLAIM); in plic_irq_eoi()
169 cpumask_and(&amask, &priv->lmask, mask_val); in plic_set_affinity()
177 return -EINVAL; in plic_set_affinity()
224 if (!test_bit(PLIC_QUIRK_EDGE_INTERRUPT, &priv->plic_quirks)) in plic_irq_set_type()
237 return -EINVAL; in plic_irq_set_type()
249 priv = per_cpu_ptr(&plic_handlers, smp_processor_id())->priv; in plic_irq_suspend()
251 for (i = 0; i < priv->nr_irqs; i++) in plic_irq_suspend()
252 if (readl(priv->regs + PRIORITY_BASE + i * PRIORITY_PER_ID)) in plic_irq_suspend()
253 __set_bit(i, priv->prio_save); in plic_irq_suspend()
255 __clear_bit(i, priv->prio_save); in plic_irq_suspend()
260 if (!handler->present) in plic_irq_suspend()
263 raw_spin_lock(&handler->enable_lock); in plic_irq_suspend()
264 for (i = 0; i < DIV_ROUND_UP(priv->nr_irqs, 32); i++) { in plic_irq_suspend()
265 reg = handler->enable_base + i * sizeof(u32); in plic_irq_suspend()
266 handler->enable_save[i] = readl(reg); in plic_irq_suspend()
268 raw_spin_unlock(&handler->enable_lock); in plic_irq_suspend()
280 priv = per_cpu_ptr(&plic_handlers, smp_processor_id())->priv; in plic_irq_resume()
282 for (i = 0; i < priv->nr_irqs; i++) { in plic_irq_resume()
284 writel((priv->prio_save[index] & BIT_MASK(i)) ? 1 : 0, in plic_irq_resume()
285 priv->regs + PRIORITY_BASE + i * PRIORITY_PER_ID); in plic_irq_resume()
291 if (!handler->present) in plic_irq_resume()
294 raw_spin_lock(&handler->enable_lock); in plic_irq_resume()
295 for (i = 0; i < DIV_ROUND_UP(priv->nr_irqs, 32); i++) { in plic_irq_resume()
296 reg = handler->enable_base + i * sizeof(u32); in plic_irq_resume()
297 writel(handler->enable_save[i], reg); in plic_irq_resume()
299 raw_spin_unlock(&handler->enable_lock); in plic_irq_resume()
311 struct plic_priv *priv = d->host_data; in plic_irqdomain_map()
313 irq_domain_set_info(d, irq, hwirq, &plic_chip, d->host_data, in plic_irqdomain_map()
316 irq_set_affinity(irq, &priv->lmask); in plic_irqdomain_map()
325 struct plic_priv *priv = d->host_data; in plic_irq_domain_translate()
327 if (test_bit(PLIC_QUIRK_EDGE_INTERRUPT, &priv->plic_quirks)) in plic_irq_domain_translate()
361 * Handling an interrupt is a two-step process: first you claim the interrupt
370 void __iomem *claim = handler->hart_base + CONTEXT_CLAIM; in plic_handle_irq()
373 WARN_ON_ONCE(!handler->present); in plic_handle_irq()
378 int err = generic_handle_domain_irq(handler->priv->irqdomain, in plic_handle_irq()
391 writel(threshold, handler->hart_base + CONTEXT_THRESHOLD); in plic_set_threshold()
428 return -ENOMEM; in __plic_init()
430 priv->plic_quirks = plic_quirks; in __plic_init()
432 priv->regs = of_iomap(node, 0); in __plic_init()
433 if (WARN_ON(!priv->regs)) { in __plic_init()
434 error = -EIO; in __plic_init()
438 error = -EINVAL; in __plic_init()
439 of_property_read_u32(node, "riscv,ndev", &nr_irqs); in __plic_init()
443 priv->nr_irqs = nr_irqs; in __plic_init()
445 priv->prio_save = bitmap_alloc(nr_irqs, GFP_KERNEL); in __plic_init()
446 if (!priv->prio_save) in __plic_init()
453 error = -ENOMEM; in __plic_init()
454 priv->irqdomain = irq_domain_add_linear(node, nr_irqs + 1, in __plic_init()
456 if (WARN_ON(!priv->irqdomain)) in __plic_init()
475 /* Disable S-mode enable bits if running in M-mode. */ in __plic_init()
477 void __iomem *enable_base = priv->regs + in __plic_init()
508 * When running in M-mode we need to ignore the S-mode handler. in __plic_init()
513 if (handler->present) { in __plic_init()
519 cpumask_set_cpu(cpu, &priv->lmask); in __plic_init()
520 handler->present = true; in __plic_init()
521 handler->hart_base = priv->regs + CONTEXT_BASE + in __plic_init()
523 raw_spin_lock_init(&handler->enable_lock); in __plic_init()
524 handler->enable_base = priv->regs + CONTEXT_ENABLE_BASE + in __plic_init()
526 handler->priv = priv; in __plic_init()
528 handler->enable_save = kcalloc(DIV_ROUND_UP(nr_irqs, 32), in __plic_init()
529 sizeof(*handler->enable_save), GFP_KERNEL); in __plic_init()
530 if (!handler->enable_save) in __plic_init()
535 writel(1, priv->regs + PRIORITY_BASE + in __plic_init()
547 if (handler->present && !plic_cpuhp_setup_done) { in __plic_init()
562 kfree(handler->enable_save); in __plic_init()
565 kfree(priv->prio_save); in __plic_init()
567 iounmap(priv->regs); in __plic_init()
579 IRQCHIP_DECLARE(sifive_plic, "sifive,plic-1.0.0", plic_init);
580 IRQCHIP_DECLARE(riscv_plic0, "riscv,plic0", plic_init); /* for legacy systems */
589 IRQCHIP_DECLARE(thead_c900_plic, "thead,c900-plic", plic_edge_init);