Lines Matching full:msi
3 * APM X-Gene MSI Driver
13 #include <linux/msi.h>
27 struct xgene_msi *msi; member
48 .name = "X-Gene1 MSI",
62 * X-Gene v1 has 16 groups of MSI termination registers MSInIRx, where
85 * Each index register supports 16 MSI vectors (0..15) to generate interrupt.
86 * There are total 16 GIC IRQs assigned for these 16 groups of MSI termination
89 * Each MSI termination group has 1 MSIINTn register (n is 0..15) to indicate
90 * the MSI pending status caused by 1 of its 8 index registers.
94 static u32 xgene_msi_ir_read(struct xgene_msi *msi, in xgene_msi_ir_read() argument
97 return readl_relaxed(msi->msi_regs + MSI_IR0 + in xgene_msi_ir_read()
102 static u32 xgene_msi_int_read(struct xgene_msi *msi, u32 msi_grp) in xgene_msi_int_read() argument
104 return readl_relaxed(msi->msi_regs + MSI_INT0 + (msi_grp << 16)); in xgene_msi_int_read()
108 * With 2048 MSI vectors supported, the MSI message can be constructed using
122 * - The termination address of MSI vector in 256-vector group n and 16-vector
124 * - The data for MSI vector in 16-vector group x is x
143 struct xgene_msi *msi = irq_data_get_irq_chip_data(data); in xgene_compose_msi_msg() local
146 u64 target_addr = msi->msi_addr + (((8 * group) + reg_set) << 16); in xgene_compose_msi_msg()
154 * X-Gene v1 only has 16 MSI GIC IRQs for 2048 MSI vectors. To maintain
155 * the expected behaviour of .set_affinity for each MSI interrupt, the 16
156 * MSI GIC IRQs are statically allocated to 8 X-Gene v1 cores (2 GIC IRQs
157 * for each core). The MSI vector is moved fom 1 MSI GIC IRQ to another
158 * MSI GIC IRQ to steer its MSI interrupt to correct X-Gene v1 core. As a
159 * consequence, the total MSI vectors that X-Gene v1 supports will be
182 /* Update MSI number to target the new CPU */ in xgene_msi_set_affinity()
189 .name = "MSI",
197 struct xgene_msi *msi = domain->host_data; in xgene_irq_domain_alloc() local
200 mutex_lock(&msi->bitmap_lock); in xgene_irq_domain_alloc()
202 msi_irq = bitmap_find_next_zero_area(msi->bitmap, NR_MSI_VEC, 0, in xgene_irq_domain_alloc()
203 msi->num_cpus, 0); in xgene_irq_domain_alloc()
205 bitmap_set(msi->bitmap, msi_irq, msi->num_cpus); in xgene_irq_domain_alloc()
209 mutex_unlock(&msi->bitmap_lock); in xgene_irq_domain_alloc()
225 struct xgene_msi *msi = irq_data_get_irq_chip_data(d); in xgene_irq_domain_free() local
228 mutex_lock(&msi->bitmap_lock); in xgene_irq_domain_free()
231 bitmap_clear(msi->bitmap, hwirq, msi->num_cpus); in xgene_irq_domain_free()
233 mutex_unlock(&msi->bitmap_lock); in xgene_irq_domain_free()
243 static int xgene_allocate_domains(struct xgene_msi *msi) in xgene_allocate_domains() argument
245 msi->inner_domain = irq_domain_add_linear(NULL, NR_MSI_VEC, in xgene_allocate_domains()
246 &msi_domain_ops, msi); in xgene_allocate_domains()
247 if (!msi->inner_domain) in xgene_allocate_domains()
250 msi->msi_domain = pci_msi_create_irq_domain(of_node_to_fwnode(msi->node), in xgene_allocate_domains()
252 msi->inner_domain); in xgene_allocate_domains()
254 if (!msi->msi_domain) { in xgene_allocate_domains()
255 irq_domain_remove(msi->inner_domain); in xgene_allocate_domains()
262 static void xgene_free_domains(struct xgene_msi *msi) in xgene_free_domains() argument
264 if (msi->msi_domain) in xgene_free_domains()
265 irq_domain_remove(msi->msi_domain); in xgene_free_domains()
266 if (msi->inner_domain) in xgene_free_domains()
267 irq_domain_remove(msi->inner_domain); in xgene_free_domains()
298 xgene_msi = msi_groups->msi; in xgene_msi_isr()
302 * MSIINTn (n is 0..F) indicates if there is a pending MSI interrupt in xgene_msi_isr()
318 * Calculate MSI vector number (refer to the termination in xgene_msi_isr()
325 * As we have multiple hw_irq that maps to single MSI, in xgene_msi_isr()
353 struct xgene_msi *msi = platform_get_drvdata(pdev); in xgene_msi_remove() local
359 kfree(msi->msi_groups); in xgene_msi_remove()
361 bitmap_free(msi->bitmap); in xgene_msi_remove()
362 msi->bitmap = NULL; in xgene_msi_remove()
364 xgene_free_domains(msi); in xgene_msi_remove()
369 struct xgene_msi *msi = &xgene_msi_ctrl; in xgene_msi_hwirq_alloc() local
375 for (i = cpu; i < NR_HW_IRQS; i += msi->num_cpus) { in xgene_msi_hwirq_alloc()
376 msi_group = &msi->msi_groups[i]; in xgene_msi_hwirq_alloc()
384 * Statically allocate MSI GIC IRQs to each CPU core. in xgene_msi_hwirq_alloc()
385 * With 8-core X-Gene v1, 2 MSI GIC IRQs are allocated in xgene_msi_hwirq_alloc()
412 struct xgene_msi *msi = &xgene_msi_ctrl; in xgene_msi_hwirq_free() local
416 for (i = cpu; i < NR_HW_IRQS; i += msi->num_cpus) { in xgene_msi_hwirq_free()
417 msi_group = &msi->msi_groups[i]; in xgene_msi_hwirq_free()
428 {.compatible = "apm,xgene1-msi"},
455 dev_err(&pdev->dev, "Error allocating MSI bitmap\n"); in xgene_msi_probe()
461 dev_err(&pdev->dev, "Failed to allocate MSI domain\n"); in xgene_msi_probe()
473 xgene_msi->msi_groups[irq_index].msi = xgene_msi; in xgene_msi_probe()
504 dev_info(&pdev->dev, "APM X-Gene PCIe MSI driver loaded\n"); in xgene_msi_probe()
509 dev_err(&pdev->dev, "failed to add CPU MSI notifier\n"); in xgene_msi_probe()
517 .name = "xgene-msi",