Lines Matching +full:msi +full:- +full:1
1 // SPDX-License-Identifier: GPL-2.0
9 #include <linux/msi.h>
20 * FLOATING - summary bit per function
21 * DIRECTED - summary bit per cpu (only used in fallback path)
27 * FLOATING - interrupt bit vector per function
28 * DIRECTED - interrupt bit vector per cpu
35 u64 req = ZPCI_CREATE_REQ(zdev->fh, 0, ZPCI_MOD_FC_REG_INT); in zpci_set_airq()
40 fib.fmt0.sum = 1; /* enable summary notifications */ in zpci_set_airq()
41 fib.fmt0.noi = airq_iv_end(zdev->aibv); in zpci_set_airq()
42 fib.fmt0.aibv = virt_to_phys(zdev->aibv->vector); in zpci_set_airq()
44 fib.fmt0.aisb = virt_to_phys(zpci_sbv->vector) + (zdev->aisb / 64) * 8; in zpci_set_airq()
45 fib.fmt0.aisbo = zdev->aisb & 63; in zpci_set_airq()
46 fib.gd = zdev->gisa; in zpci_set_airq()
48 return zpci_mod_fc(req, &fib, &status) ? -EIO : 0; in zpci_set_airq()
54 u64 req = ZPCI_CREATE_REQ(zdev->fh, 0, ZPCI_MOD_FC_DEREG_INT); in zpci_clear_airq()
58 fib.gd = zdev->gisa; in zpci_clear_airq()
61 if (cc == 3 || (cc == 1 && status == 24)) in zpci_clear_airq()
65 return cc ? -EIO : 0; in zpci_clear_airq()
71 u64 req = ZPCI_CREATE_REQ(zdev->fh, 0, ZPCI_MOD_FC_REG_INT_D); in zpci_set_directed_irq()
75 fib.fmt = 1; in zpci_set_directed_irq()
76 fib.fmt1.noi = zdev->msi_nr_irqs; in zpci_set_directed_irq()
77 fib.fmt1.dibvo = zdev->msi_first_bit; in zpci_set_directed_irq()
78 fib.gd = zdev->gisa; in zpci_set_directed_irq()
80 return zpci_mod_fc(req, &fib, &status) ? -EIO : 0; in zpci_set_directed_irq()
86 u64 req = ZPCI_CREATE_REQ(zdev->fh, 0, ZPCI_MOD_FC_DEREG_INT_D); in zpci_clear_directed_irq()
90 fib.fmt = 1; in zpci_clear_directed_irq()
91 fib.gd = zdev->gisa; in zpci_clear_directed_irq()
93 if (cc == 3 || (cc == 1 && status == 24)) in zpci_clear_directed_irq()
97 return cc ? -EIO : 0; in zpci_clear_directed_irq()
111 zdev->irqs_registered = 1; in zpci_set_irq()
127 zdev->irqs_registered = 0; in zpci_clear_irq()
136 struct msi_msg msg = entry->msg; in zpci_set_irq_affinity()
141 pci_write_msi_msg(data->irq, &msg); in zpci_set_irq_affinity()
147 .name = "PCI-MSI",
162 if (bit == -1UL) { in zpci_handle_cpu_local_irq()
166 /* First scan complete, re-enable interrupts. */ in zpci_handle_cpu_local_irq()
201 if (cpu == -1UL) { in zpci_handle_fallback_irq()
205 /* First scan complete, re-enable interrupts. */ in zpci_handle_fallback_irq()
212 if (atomic_inc_return(&cpu_data->scheduled) > 1) in zpci_handle_fallback_irq()
215 INIT_CSD(&cpu_data->csd, zpci_handle_remote_irq, &cpu_data->scheduled); in zpci_handle_fallback_irq()
216 smp_call_function_single_async(cpu, &cpu_data->csd); in zpci_handle_fallback_irq()
223 bool floating = !tpi_info->directed_irq; in zpci_directed_irq_handler()
246 if (si == -1UL) { in zpci_floating_irq_handler()
250 /* First scan complete, re-enable interrupts. */ in zpci_floating_irq_handler()
261 if (ai == -1UL) in zpci_floating_irq_handler()
277 if (*bit == -1UL) in __alloc_airq()
278 return -EIO; in __alloc_airq()
282 if (*bit == -1UL) in __alloc_airq()
283 return -EIO; in __alloc_airq()
284 zdev->aisb = *bit; in __alloc_airq()
287 zdev->aibv = airq_iv_create(msi_vecs, AIRQ_IV_DATA | AIRQ_IV_BITLOCK, NULL); in __alloc_airq()
288 if (!zdev->aibv) in __alloc_airq()
289 return -ENOMEM; in __alloc_airq()
292 zpci_ibv[*bit] = zdev->aibv; in __alloc_airq()
303 struct msi_desc *msi; in arch_setup_msi_irqs() local
309 zdev->aisb = -1UL; in arch_setup_msi_irqs()
310 zdev->msi_first_bit = -1U; in arch_setup_msi_irqs()
312 msi_vecs = min_t(unsigned int, nvec, zdev->max_msi); in arch_setup_msi_irqs()
315 pci_name(pdev), nvec, zdev->max_msi); in arch_setup_msi_irqs()
323 * Request MSI interrupts: in arch_setup_msi_irqs()
324 * When using MSI, nvec_used interrupt sources and their irq in arch_setup_msi_irqs()
325 * descriptors are controlled through one msi descriptor. in arch_setup_msi_irqs()
326 * Thus the outer loop over msi descriptors shall run only once, in arch_setup_msi_irqs()
328 * When using MSI-X, each interrupt vector/irq descriptor in arch_setup_msi_irqs()
329 * is bound to exactly one msi descriptor (nvec_used is one). in arch_setup_msi_irqs()
331 * over the MSI-X descriptors. in arch_setup_msi_irqs()
334 msi_for_each_desc(msi, &pdev->dev, MSI_DESC_NOTASSOCIATED) { in arch_setup_msi_irqs()
335 if (hwirq - bit >= msi_vecs) in arch_setup_msi_irqs()
337 irqs_per_msi = min_t(unsigned int, msi_vecs, msi->nvec_used); in arch_setup_msi_irqs()
338 irq = __irq_alloc_descs(-1, 0, irqs_per_msi, 0, THIS_MODULE, in arch_setup_msi_irqs()
340 msi->affinity : NULL); in arch_setup_msi_irqs()
342 return -ENOMEM; in arch_setup_msi_irqs()
345 rc = irq_set_msi_desc_off(irq, i, msi); in arch_setup_msi_irqs()
352 msg.data = hwirq - bit; in arch_setup_msi_irqs()
354 if (msi->affinity) in arch_setup_msi_irqs()
355 cpu = cpumask_first(&msi->affinity->mask); in arch_setup_msi_irqs()
360 msg.address_lo = zdev->msi_addr & 0xff0000ff; in arch_setup_msi_irqs()
369 msg.address_lo = zdev->msi_addr & 0xffffffff; in arch_setup_msi_irqs()
371 airq_iv_set_data(zdev->aibv, hwirq + i, irq + i); in arch_setup_msi_irqs()
373 msg.address_hi = zdev->msi_addr >> 32; in arch_setup_msi_irqs()
378 zdev->msi_first_bit = bit; in arch_setup_msi_irqs()
379 zdev->msi_nr_irqs = hwirq - bit; in arch_setup_msi_irqs()
385 return (zdev->msi_nr_irqs == nvec) ? 0 : zdev->msi_nr_irqs; in arch_setup_msi_irqs()
391 struct msi_desc *msi; in arch_teardown_msi_irqs() local
400 /* Release MSI interrupts */ in arch_teardown_msi_irqs()
401 msi_for_each_desc(msi, &pdev->dev, MSI_DESC_ASSOCIATED) { in arch_teardown_msi_irqs()
402 for (i = 0; i < msi->nvec_used; i++) { in arch_teardown_msi_irqs()
403 irq_set_msi_desc(msi->irq + i, NULL); in arch_teardown_msi_irqs()
404 irq_free_desc(msi->irq + i); in arch_teardown_msi_irqs()
406 msi->msg.address_lo = 0; in arch_teardown_msi_irqs()
407 msi->msg.address_hi = 0; in arch_teardown_msi_irqs()
408 msi->msg.data = 0; in arch_teardown_msi_irqs()
409 msi->irq = 0; in arch_teardown_msi_irqs()
412 if (zdev->aisb != -1UL) { in arch_teardown_msi_irqs()
413 zpci_ibv[zdev->aisb] = NULL; in arch_teardown_msi_irqs()
414 airq_iv_free_bit(zpci_sbv, zdev->aisb); in arch_teardown_msi_irqs()
415 zdev->aisb = -1UL; in arch_teardown_msi_irqs()
417 if (zdev->aibv) { in arch_teardown_msi_irqs()
418 airq_iv_release(zdev->aibv); in arch_teardown_msi_irqs()
419 zdev->aibv = NULL; in arch_teardown_msi_irqs()
422 if ((irq_delivery == DIRECTED) && zdev->msi_first_bit != -1U) in arch_teardown_msi_irqs()
423 airq_iv_free(zpci_ibv[0], zdev->msi_first_bit, zdev->msi_nr_irqs); in arch_teardown_msi_irqs()
430 if (!zdev->irqs_registered) in arch_restore_msi_irqs()
445 iib.cdiib.dibv_addr = virt_to_phys(zpci_ibv[smp_processor_id()]->vector); in cpu_enable_directed_irq()
458 return -ENOMEM; in zpci_directed_irq_init()
462 iib.diib.disb_addr = virt_to_phys(zpci_sbv->vector); in zpci_directed_irq_init()
468 return -ENOMEM; in zpci_directed_irq_init()
472 * Per CPU IRQ vectors look the same but bit-allocation in zpci_directed_irq_init()
480 return -ENOMEM; in zpci_directed_irq_init()
482 on_each_cpu(cpu_enable_directed_irq, NULL, 1); in zpci_directed_irq_init()
493 return -ENOMEM; in zpci_floating_irq_init()
503 return -ENOMEM; in zpci_floating_irq_init()
521 /* Set summary to 1 to be called every time for the ISC. */ in zpci_irq_init()
522 *zpci_airq.lsi_ptr = 1; in zpci_irq_init()