0001
0002
0003
0004
0005
0006 #define pr_fmt(fmt) "plic: " fmt
0007 #include <linux/cpu.h>
0008 #include <linux/interrupt.h>
0009 #include <linux/io.h>
0010 #include <linux/irq.h>
0011 #include <linux/irqchip.h>
0012 #include <linux/irqchip/chained_irq.h>
0013 #include <linux/irqdomain.h>
0014 #include <linux/module.h>
0015 #include <linux/of.h>
0016 #include <linux/of_address.h>
0017 #include <linux/of_irq.h>
0018 #include <linux/platform_device.h>
0019 #include <linux/spinlock.h>
0020 #include <asm/smp.h>
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033 #define MAX_DEVICES 1024
0034 #define MAX_CONTEXTS 15872
0035
0036
0037
0038
0039
0040 #define PRIORITY_BASE 0
0041 #define PRIORITY_PER_ID 4
0042
0043
0044
0045
0046
0047 #define CONTEXT_ENABLE_BASE 0x2000
0048 #define CONTEXT_ENABLE_SIZE 0x80
0049
0050
0051
0052
0053
0054
0055 #define CONTEXT_BASE 0x200000
0056 #define CONTEXT_SIZE 0x1000
0057 #define CONTEXT_THRESHOLD 0x00
0058 #define CONTEXT_CLAIM 0x04
0059
0060 #define PLIC_DISABLE_THRESHOLD 0x7
0061 #define PLIC_ENABLE_THRESHOLD 0
0062
0063 #define PLIC_QUIRK_EDGE_INTERRUPT 0
0064
0065 struct plic_priv {
0066 struct cpumask lmask;
0067 struct irq_domain *irqdomain;
0068 void __iomem *regs;
0069 unsigned long plic_quirks;
0070 };
0071
0072 struct plic_handler {
0073 bool present;
0074 void __iomem *hart_base;
0075
0076
0077
0078
0079 raw_spinlock_t enable_lock;
0080 void __iomem *enable_base;
0081 struct plic_priv *priv;
0082 };
0083 static int plic_parent_irq __ro_after_init;
0084 static bool plic_cpuhp_setup_done __ro_after_init;
0085 static DEFINE_PER_CPU(struct plic_handler, plic_handlers);
0086
0087 static int plic_irq_set_type(struct irq_data *d, unsigned int type);
0088
0089 static void __plic_toggle(void __iomem *enable_base, int hwirq, int enable)
0090 {
0091 u32 __iomem *reg = enable_base + (hwirq / 32) * sizeof(u32);
0092 u32 hwirq_mask = 1 << (hwirq % 32);
0093
0094 if (enable)
0095 writel(readl(reg) | hwirq_mask, reg);
0096 else
0097 writel(readl(reg) & ~hwirq_mask, reg);
0098 }
0099
0100 static void plic_toggle(struct plic_handler *handler, int hwirq, int enable)
0101 {
0102 raw_spin_lock(&handler->enable_lock);
0103 __plic_toggle(handler->enable_base, hwirq, enable);
0104 raw_spin_unlock(&handler->enable_lock);
0105 }
0106
0107 static inline void plic_irq_toggle(const struct cpumask *mask,
0108 struct irq_data *d, int enable)
0109 {
0110 int cpu;
0111
0112 for_each_cpu(cpu, mask) {
0113 struct plic_handler *handler = per_cpu_ptr(&plic_handlers, cpu);
0114
0115 plic_toggle(handler, d->hwirq, enable);
0116 }
0117 }
0118
0119 static void plic_irq_enable(struct irq_data *d)
0120 {
0121 plic_irq_toggle(irq_data_get_effective_affinity_mask(d), d, 1);
0122 }
0123
0124 static void plic_irq_disable(struct irq_data *d)
0125 {
0126 plic_irq_toggle(irq_data_get_effective_affinity_mask(d), d, 0);
0127 }
0128
0129 static void plic_irq_unmask(struct irq_data *d)
0130 {
0131 struct plic_priv *priv = irq_data_get_irq_chip_data(d);
0132
0133 writel(1, priv->regs + PRIORITY_BASE + d->hwirq * PRIORITY_PER_ID);
0134 }
0135
0136 static void plic_irq_mask(struct irq_data *d)
0137 {
0138 struct plic_priv *priv = irq_data_get_irq_chip_data(d);
0139
0140 writel(0, priv->regs + PRIORITY_BASE + d->hwirq * PRIORITY_PER_ID);
0141 }
0142
0143 static void plic_irq_eoi(struct irq_data *d)
0144 {
0145 struct plic_handler *handler = this_cpu_ptr(&plic_handlers);
0146
0147 writel(d->hwirq, handler->hart_base + CONTEXT_CLAIM);
0148 }
0149
0150 #ifdef CONFIG_SMP
0151 static int plic_set_affinity(struct irq_data *d,
0152 const struct cpumask *mask_val, bool force)
0153 {
0154 unsigned int cpu;
0155 struct cpumask amask;
0156 struct plic_priv *priv = irq_data_get_irq_chip_data(d);
0157
0158 cpumask_and(&amask, &priv->lmask, mask_val);
0159
0160 if (force)
0161 cpu = cpumask_first(&amask);
0162 else
0163 cpu = cpumask_any_and(&amask, cpu_online_mask);
0164
0165 if (cpu >= nr_cpu_ids)
0166 return -EINVAL;
0167
0168 plic_irq_disable(d);
0169
0170 irq_data_update_effective_affinity(d, cpumask_of(cpu));
0171
0172 if (!irqd_irq_disabled(d))
0173 plic_irq_enable(d);
0174
0175 return IRQ_SET_MASK_OK_DONE;
0176 }
0177 #endif
0178
0179 static struct irq_chip plic_edge_chip = {
0180 .name = "SiFive PLIC",
0181 .irq_enable = plic_irq_enable,
0182 .irq_disable = plic_irq_disable,
0183 .irq_ack = plic_irq_eoi,
0184 .irq_mask = plic_irq_mask,
0185 .irq_unmask = plic_irq_unmask,
0186 #ifdef CONFIG_SMP
0187 .irq_set_affinity = plic_set_affinity,
0188 #endif
0189 .irq_set_type = plic_irq_set_type,
0190 .flags = IRQCHIP_AFFINITY_PRE_STARTUP,
0191 };
0192
0193 static struct irq_chip plic_chip = {
0194 .name = "SiFive PLIC",
0195 .irq_enable = plic_irq_enable,
0196 .irq_disable = plic_irq_disable,
0197 .irq_mask = plic_irq_mask,
0198 .irq_unmask = plic_irq_unmask,
0199 .irq_eoi = plic_irq_eoi,
0200 #ifdef CONFIG_SMP
0201 .irq_set_affinity = plic_set_affinity,
0202 #endif
0203 .irq_set_type = plic_irq_set_type,
0204 .flags = IRQCHIP_AFFINITY_PRE_STARTUP,
0205 };
0206
0207 static int plic_irq_set_type(struct irq_data *d, unsigned int type)
0208 {
0209 struct plic_priv *priv = irq_data_get_irq_chip_data(d);
0210
0211 if (!test_bit(PLIC_QUIRK_EDGE_INTERRUPT, &priv->plic_quirks))
0212 return IRQ_SET_MASK_OK_NOCOPY;
0213
0214 switch (type) {
0215 case IRQ_TYPE_EDGE_RISING:
0216 irq_set_chip_handler_name_locked(d, &plic_edge_chip,
0217 handle_edge_irq, NULL);
0218 break;
0219 case IRQ_TYPE_LEVEL_HIGH:
0220 irq_set_chip_handler_name_locked(d, &plic_chip,
0221 handle_fasteoi_irq, NULL);
0222 break;
0223 default:
0224 return -EINVAL;
0225 }
0226
0227 return IRQ_SET_MASK_OK;
0228 }
0229
0230 static int plic_irqdomain_map(struct irq_domain *d, unsigned int irq,
0231 irq_hw_number_t hwirq)
0232 {
0233 struct plic_priv *priv = d->host_data;
0234
0235 irq_domain_set_info(d, irq, hwirq, &plic_chip, d->host_data,
0236 handle_fasteoi_irq, NULL, NULL);
0237 irq_set_noprobe(irq);
0238 irq_set_affinity(irq, &priv->lmask);
0239 return 0;
0240 }
0241
0242 static int plic_irq_domain_translate(struct irq_domain *d,
0243 struct irq_fwspec *fwspec,
0244 unsigned long *hwirq,
0245 unsigned int *type)
0246 {
0247 struct plic_priv *priv = d->host_data;
0248
0249 if (test_bit(PLIC_QUIRK_EDGE_INTERRUPT, &priv->plic_quirks))
0250 return irq_domain_translate_twocell(d, fwspec, hwirq, type);
0251
0252 return irq_domain_translate_onecell(d, fwspec, hwirq, type);
0253 }
0254
0255 static int plic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
0256 unsigned int nr_irqs, void *arg)
0257 {
0258 int i, ret;
0259 irq_hw_number_t hwirq;
0260 unsigned int type;
0261 struct irq_fwspec *fwspec = arg;
0262
0263 ret = plic_irq_domain_translate(domain, fwspec, &hwirq, &type);
0264 if (ret)
0265 return ret;
0266
0267 for (i = 0; i < nr_irqs; i++) {
0268 ret = plic_irqdomain_map(domain, virq + i, hwirq + i);
0269 if (ret)
0270 return ret;
0271 }
0272
0273 return 0;
0274 }
0275
0276 static const struct irq_domain_ops plic_irqdomain_ops = {
0277 .translate = plic_irq_domain_translate,
0278 .alloc = plic_irq_domain_alloc,
0279 .free = irq_domain_free_irqs_top,
0280 };
0281
0282
0283
0284
0285
0286
0287
0288 static void plic_handle_irq(struct irq_desc *desc)
0289 {
0290 struct plic_handler *handler = this_cpu_ptr(&plic_handlers);
0291 struct irq_chip *chip = irq_desc_get_chip(desc);
0292 void __iomem *claim = handler->hart_base + CONTEXT_CLAIM;
0293 irq_hw_number_t hwirq;
0294
0295 WARN_ON_ONCE(!handler->present);
0296
0297 chained_irq_enter(chip, desc);
0298
0299 while ((hwirq = readl(claim))) {
0300 int err = generic_handle_domain_irq(handler->priv->irqdomain,
0301 hwirq);
0302 if (unlikely(err))
0303 pr_warn_ratelimited("can't find mapping for hwirq %lu\n",
0304 hwirq);
0305 }
0306
0307 chained_irq_exit(chip, desc);
0308 }
0309
0310 static void plic_set_threshold(struct plic_handler *handler, u32 threshold)
0311 {
0312
0313 writel(threshold, handler->hart_base + CONTEXT_THRESHOLD);
0314 }
0315
0316 static int plic_dying_cpu(unsigned int cpu)
0317 {
0318 if (plic_parent_irq)
0319 disable_percpu_irq(plic_parent_irq);
0320
0321 return 0;
0322 }
0323
0324 static int plic_starting_cpu(unsigned int cpu)
0325 {
0326 struct plic_handler *handler = this_cpu_ptr(&plic_handlers);
0327
0328 if (plic_parent_irq)
0329 enable_percpu_irq(plic_parent_irq,
0330 irq_get_trigger_type(plic_parent_irq));
0331 else
0332 pr_warn("cpu%d: parent irq not available\n", cpu);
0333 plic_set_threshold(handler, PLIC_ENABLE_THRESHOLD);
0334
0335 return 0;
0336 }
0337
0338 static int __init __plic_init(struct device_node *node,
0339 struct device_node *parent,
0340 unsigned long plic_quirks)
0341 {
0342 int error = 0, nr_contexts, nr_handlers = 0, i;
0343 u32 nr_irqs;
0344 struct plic_priv *priv;
0345 struct plic_handler *handler;
0346
0347 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
0348 if (!priv)
0349 return -ENOMEM;
0350
0351 priv->plic_quirks = plic_quirks;
0352
0353 priv->regs = of_iomap(node, 0);
0354 if (WARN_ON(!priv->regs)) {
0355 error = -EIO;
0356 goto out_free_priv;
0357 }
0358
0359 error = -EINVAL;
0360 of_property_read_u32(node, "riscv,ndev", &nr_irqs);
0361 if (WARN_ON(!nr_irqs))
0362 goto out_iounmap;
0363
0364 nr_contexts = of_irq_count(node);
0365 if (WARN_ON(!nr_contexts))
0366 goto out_iounmap;
0367
0368 error = -ENOMEM;
0369 priv->irqdomain = irq_domain_add_linear(node, nr_irqs + 1,
0370 &plic_irqdomain_ops, priv);
0371 if (WARN_ON(!priv->irqdomain))
0372 goto out_iounmap;
0373
0374 for (i = 0; i < nr_contexts; i++) {
0375 struct of_phandle_args parent;
0376 irq_hw_number_t hwirq;
0377 int cpu;
0378 unsigned long hartid;
0379
0380 if (of_irq_parse_one(node, i, &parent)) {
0381 pr_err("failed to parse parent for context %d.\n", i);
0382 continue;
0383 }
0384
0385
0386
0387
0388
0389 if (parent.args[0] != RV_IRQ_EXT) {
0390
0391 if (IS_ENABLED(CONFIG_RISCV_M_MODE)) {
0392 void __iomem *enable_base = priv->regs +
0393 CONTEXT_ENABLE_BASE +
0394 i * CONTEXT_ENABLE_SIZE;
0395
0396 for (hwirq = 1; hwirq <= nr_irqs; hwirq++)
0397 __plic_toggle(enable_base, hwirq, 0);
0398 }
0399 continue;
0400 }
0401
0402 error = riscv_of_parent_hartid(parent.np, &hartid);
0403 if (error < 0) {
0404 pr_warn("failed to parse hart ID for context %d.\n", i);
0405 continue;
0406 }
0407
0408 cpu = riscv_hartid_to_cpuid(hartid);
0409 if (cpu < 0) {
0410 pr_warn("Invalid cpuid for context %d\n", i);
0411 continue;
0412 }
0413
0414
0415 if (!plic_parent_irq && irq_find_host(parent.np)) {
0416 plic_parent_irq = irq_of_parse_and_map(node, i);
0417 if (plic_parent_irq)
0418 irq_set_chained_handler(plic_parent_irq,
0419 plic_handle_irq);
0420 }
0421
0422
0423
0424
0425
0426
0427 handler = per_cpu_ptr(&plic_handlers, cpu);
0428 if (handler->present) {
0429 pr_warn("handler already present for context %d.\n", i);
0430 plic_set_threshold(handler, PLIC_DISABLE_THRESHOLD);
0431 goto done;
0432 }
0433
0434 cpumask_set_cpu(cpu, &priv->lmask);
0435 handler->present = true;
0436 handler->hart_base = priv->regs + CONTEXT_BASE +
0437 i * CONTEXT_SIZE;
0438 raw_spin_lock_init(&handler->enable_lock);
0439 handler->enable_base = priv->regs + CONTEXT_ENABLE_BASE +
0440 i * CONTEXT_ENABLE_SIZE;
0441 handler->priv = priv;
0442 done:
0443 for (hwirq = 1; hwirq <= nr_irqs; hwirq++) {
0444 plic_toggle(handler, hwirq, 0);
0445 writel(1, priv->regs + PRIORITY_BASE +
0446 hwirq * PRIORITY_PER_ID);
0447 }
0448 nr_handlers++;
0449 }
0450
0451
0452
0453
0454
0455 handler = this_cpu_ptr(&plic_handlers);
0456 if (handler->present && !plic_cpuhp_setup_done) {
0457 cpuhp_setup_state(CPUHP_AP_IRQ_SIFIVE_PLIC_STARTING,
0458 "irqchip/sifive/plic:starting",
0459 plic_starting_cpu, plic_dying_cpu);
0460 plic_cpuhp_setup_done = true;
0461 }
0462
0463 pr_info("%pOFP: mapped %d interrupts with %d handlers for"
0464 " %d contexts.\n", node, nr_irqs, nr_handlers, nr_contexts);
0465 return 0;
0466
0467 out_iounmap:
0468 iounmap(priv->regs);
0469 out_free_priv:
0470 kfree(priv);
0471 return error;
0472 }
0473
0474 static int __init plic_init(struct device_node *node,
0475 struct device_node *parent)
0476 {
0477 return __plic_init(node, parent, 0);
0478 }
0479
0480 IRQCHIP_DECLARE(sifive_plic, "sifive,plic-1.0.0", plic_init);
0481 IRQCHIP_DECLARE(riscv_plic0, "riscv,plic0", plic_init);
0482
0483 static int __init plic_edge_init(struct device_node *node,
0484 struct device_node *parent)
0485 {
0486 return __plic_init(node, parent, BIT(PLIC_QUIRK_EDGE_INTERRUPT));
0487 }
0488
0489 IRQCHIP_DECLARE(andestech_nceplic100, "andestech,nceplic100", plic_edge_init);
0490 IRQCHIP_DECLARE(thead_c900_plic, "thead,c900-plic", plic_edge_init);