Lines Matching +full:hart +full:- +full:compatible
1 // SPDX-License-Identifier: GPL-2.0
7 #define pr_fmt(fmt) "riscv-imsic: " fmt
23 #include "irq-riscv-imsic-state.h"
31 global = &imsic->global; in imsic_cpu_page_phys()
32 local = per_cpu_ptr(global->local, cpu); in imsic_cpu_page_phys()
34 if (BIT(global->guest_index_bits) <= guest_index) in imsic_cpu_page_phys()
38 *out_msi_pa = local->msi_pa + (guest_index * IMSIC_MMIO_PAGE_SZ); in imsic_cpu_page_phys()
59 return -ENOENT; in imsic_irq_retrigger()
61 local = per_cpu_ptr(imsic->global.local, vec->cpu); in imsic_irq_retrigger()
62 writel_relaxed(vec->local_id, local->msi_va); in imsic_irq_retrigger()
73 if (WARN_ON(!imsic_cpu_page_phys(vec->cpu, 0, &msi_addr))) in imsic_irq_compose_vector_msg()
76 msg->address_hi = upper_32_bits(msi_addr); in imsic_irq_compose_vector_msg()
77 msg->address_lo = lower_32_bits(msi_addr); in imsic_irq_compose_vector_msg()
78 msg->data = vec->local_id; in imsic_irq_compose_vector_msg()
92 irq_data_get_irq_chip(d)->irq_write_msi_msg(d, &msg); in imsic_msi_update_msg()
99 struct irq_data *pd = d->parent_data; in imsic_irq_set_affinity()
103 return -ENOENT; in imsic_irq_set_affinity()
106 if (cpumask_test_cpu(old_vec->cpu, mask_val)) in imsic_irq_set_affinity()
109 /* If move is already in-flight then return failure */ in imsic_irq_set_affinity()
111 return -EBUSY; in imsic_irq_set_affinity()
114 new_vec = imsic_vector_alloc(old_vec->hwirq, mask_val); in imsic_irq_set_affinity()
116 return -ENOSPC; in imsic_irq_set_affinity()
122 pd->chip_data = new_vec; in imsic_irq_set_affinity()
125 irq_data_update_effective_affinity(pd, cpumask_of(new_vec->cpu)); in imsic_irq_set_affinity()
149 /* Multi-MSI is not supported yet. */ in imsic_irq_domain_alloc()
151 return -EOPNOTSUPP; in imsic_irq_domain_alloc()
155 return -ENOSPC; in imsic_irq_domain_alloc()
161 irq_data_update_effective_affinity(irq_get_irq_data(virq), cpumask_of(vec->cpu)); in imsic_irq_domain_alloc()
178 const struct msi_parent_ops *ops = domain->msi_parent_ops; in imsic_irq_domain_select()
181 if (fwspec->fwnode != domain->fwnode || fwspec->param_count != 0) in imsic_irq_domain_select()
185 if (bus_token == ops->bus_select_token) in imsic_irq_domain_select()
188 return !!(ops->bus_select_mask & busmask); in imsic_irq_domain_select()
240 const struct msi_parent_ops *pops = real_parent->msi_parent_ops; in imsic_init_dev_msi_info()
243 switch (real_parent->bus_token) { in imsic_init_dev_msi_info()
248 info->chip->irq_set_affinity = imsic_irq_set_affinity; in imsic_init_dev_msi_info()
257 switch (info->bus_token) { in imsic_init_dev_msi_info()
261 info->chip->irq_mask = imsic_pci_mask_irq; in imsic_init_dev_msi_info()
262 info->chip->irq_unmask = imsic_pci_unmask_irq; in imsic_init_dev_msi_info()
267 * Per-device MSI should never have any MSI feature bits in imsic_init_dev_msi_info()
272 if (WARN_ON_ONCE(info->flags)) in imsic_init_dev_msi_info()
276 info->flags |= MSI_FLAG_ALLOC_SIMPLE_MSI_DESCS | in imsic_init_dev_msi_info()
286 /* Use hierarchial chip operations re-trigger */ in imsic_init_dev_msi_info()
287 info->chip->irq_retrigger = irq_chip_retrigger_hierarchy; in imsic_init_dev_msi_info()
293 info->flags &= pops->supported_flags; in imsic_init_dev_msi_info()
296 info->flags |= pops->required_flags; in imsic_init_dev_msi_info()
317 if (!imsic || !imsic->fwnode) { in imsic_irqdomain_init()
319 return -ENODEV; in imsic_irqdomain_init()
322 if (imsic->base_domain) { in imsic_irqdomain_init()
323 pr_err("%pfwP: irq domain already created\n", imsic->fwnode); in imsic_irqdomain_init()
324 return -ENODEV; in imsic_irqdomain_init()
328 imsic->base_domain = irq_domain_create_tree(imsic->fwnode, in imsic_irqdomain_init()
330 if (!imsic->base_domain) { in imsic_irqdomain_init()
331 pr_err("%pfwP: failed to create IMSIC base domain\n", imsic->fwnode); in imsic_irqdomain_init()
332 return -ENOMEM; in imsic_irqdomain_init()
334 imsic->base_domain->flags |= IRQ_DOMAIN_FLAG_MSI_PARENT; in imsic_irqdomain_init()
335 imsic->base_domain->msi_parent_ops = &imsic_msi_parent_ops; in imsic_irqdomain_init()
337 irq_domain_update_bus_token(imsic->base_domain, DOMAIN_BUS_NEXUS); in imsic_irqdomain_init()
339 global = &imsic->global; in imsic_irqdomain_init()
340 pr_info("%pfwP: hart-index-bits: %d, guest-index-bits: %d\n", in imsic_irqdomain_init()
341 imsic->fwnode, global->hart_index_bits, global->guest_index_bits); in imsic_irqdomain_init()
342 pr_info("%pfwP: group-index-bits: %d, group-index-shift: %d\n", in imsic_irqdomain_init()
343 imsic->fwnode, global->group_index_bits, global->group_index_shift); in imsic_irqdomain_init()
344 pr_info("%pfwP: per-CPU IDs %d at base address %pa\n", in imsic_irqdomain_init()
345 imsic->fwnode, global->nr_ids, &global->base_addr); in imsic_irqdomain_init()
347 imsic->fwnode, num_possible_cpus() * (global->nr_ids - 1)); in imsic_irqdomain_init()
354 if (imsic && imsic->fwnode != fwnode) { in imsic_platform_probe_common()
356 return -ENODEV; in imsic_platform_probe_common()
364 return imsic_platform_probe_common(pdev->dev.fwnode); in imsic_platform_dt_probe()
373 * imsic-platform drive probe happens late during boot, ACPI based
384 { .compatible = "riscv,imsics" },
390 .name = "riscv-imsic",