Lines Matching +full:pci +full:- +full:domain

1 // SPDX-License-Identifier: GPL-2.0-only
3 * Xen PCI - handle PCI (INTx) and MSI infrastructure calls for PV, HVM and
4 * initial domain support. We also handle the DSDT _PRT callbacks for GSI's
5 * used in HVM and initial domain mode (PV does not parse ACPI, so it has no
7 * 0xcf8 PCI configuration read/write.
15 #include <linux/pci.h>
26 #include <xen/pci.h>
27 #include <asm/xen/pci.h>
42 dev_warn(&dev->dev, "Xen PCI: failed to read interrupt line: %d\n", in xen_pcifront_enable_irq()
46 /* In PV DomU the Xen PCI backend puts the PIRQ in the interrupt line.*/ in xen_pcifront_enable_irq()
54 dev_warn(&dev->dev, "Xen PCI: failed to bind GSI%d (PIRQ%d) to IRQ: %d\n", in xen_pcifront_enable_irq()
59 dev->irq = rc; in xen_pcifront_enable_irq()
60 dev_info(&dev->dev, "Xen PCI mapped GSI%d to IRQ%d\n", gsi, dev->irq); in xen_pcifront_enable_irq()
67 int rc, pirq = -1, irq; in xen_register_pirq()
87 return -1; in xen_register_pirq()
92 name = "ioapic-edge"; in xen_register_pirq()
95 name = "ioapic-level"; in xen_register_pirq()
102 printk(KERN_DEBUG "xen: --> pirq=%d -> irq=%d (gsi=%d)\n", map_irq.pirq, irq, gsi); in xen_register_pirq()
111 return -1; in acpi_register_gsi_xen_hvm()
124 return -1; in xen_register_gsi()
136 if (rc == -EEXIST) in xen_register_gsi()
178 return -ENOMEM; in xen_setup_msi_irqs()
187 msi_for_each_desc(msidesc, &dev->dev, MSI_DESC_NOTASSOCIATED) { in xen_setup_msi_irqs()
191 "pcifront-msi-x" : in xen_setup_msi_irqs()
192 "pcifront-msi", in xen_setup_msi_irqs()
201 return msi_device_populate_sysfs(&dev->dev); in xen_setup_msi_irqs()
204 if (ret == -ENOSYS) in xen_setup_msi_irqs()
205 dev_err(&dev->dev, "Xen PCI frontend has not registered MSI/MSI-X support!\n"); in xen_setup_msi_irqs()
207 dev_err(&dev->dev, "Xen PCI frontend error: %d!\n", ret); in xen_setup_msi_irqs()
222 msg->address_hi = X86_MSI_BASE_ADDRESS_HIGH; in xen_msi_compose_msg()
223 msg->arch_addr_hi.destid_8_31 = pirq >> 8; in xen_msi_compose_msg()
224 msg->arch_addr_lo.destid_0_7 = pirq & 0xFF; in xen_msi_compose_msg()
225 msg->arch_addr_lo.base_address = X86_MSI_BASE_ADDRESS_LOW; in xen_msi_compose_msg()
226 msg->arch_data.delivery_mode = APIC_DELIVERY_MODE_EXTINT; in xen_msi_compose_msg()
238 msi_for_each_desc(msidesc, &dev->dev, MSI_DESC_NOTASSOCIATED) { in xen_hvm_setup_msi_irqs()
241 irq = -ENODEV; in xen_hvm_setup_msi_irqs()
246 dev_dbg(&dev->dev, "xen: msi bound to pirq=%d\n", pirq); in xen_hvm_setup_msi_irqs()
250 "msi-x" : "msi", in xen_hvm_setup_msi_irqs()
254 dev_dbg(&dev->dev, in xen_hvm_setup_msi_irqs()
255 "xen: msi --> pirq=%d --> irq=%d\n", pirq, irq); in xen_hvm_setup_msi_irqs()
257 return msi_device_populate_sysfs(&dev->dev); in xen_hvm_setup_msi_irqs()
260 dev_err(&dev->dev, "Failed to create MSI%s! ret=%d!\n", in xen_hvm_setup_msi_irqs()
261 type == PCI_CAP_ID_MSI ? "" : "-X", irq); in xen_hvm_setup_msi_irqs()
273 msi_for_each_desc(msidesc, &dev->dev, MSI_DESC_NOTASSOCIATED) { in xen_initdom_setup_msi_irqs()
278 /* N.B. Casting int's -ENODEV to uint16_t results in 0xFFED, in xen_initdom_setup_msi_irqs()
286 map_irq.index = -1; in xen_initdom_setup_msi_irqs()
287 map_irq.pirq = -1; in xen_initdom_setup_msi_irqs()
288 map_irq.bus = dev->bus->number | in xen_initdom_setup_msi_irqs()
289 (pci_domain_nr(dev->bus) << 16); in xen_initdom_setup_msi_irqs()
290 map_irq.devfn = dev->devfn; in xen_initdom_setup_msi_irqs()
300 pos = dev->msix_cap; in xen_initdom_setup_msi_irqs()
306 return -EINVAL; in xen_initdom_setup_msi_irqs()
309 map_irq.entry_nr = msidesc->msi_index; in xen_initdom_setup_msi_irqs()
312 ret = -EINVAL; in xen_initdom_setup_msi_irqs()
326 if (ret == -EINVAL && !pci_domain_nr(dev->bus)) { in xen_initdom_setup_msi_irqs()
328 map_irq.index = -1; in xen_initdom_setup_msi_irqs()
329 map_irq.pirq = -1; in xen_initdom_setup_msi_irqs()
330 map_irq.bus = dev->bus->number; in xen_initdom_setup_msi_irqs()
333 if (ret != -EINVAL) in xen_initdom_setup_msi_irqs()
337 dev_warn(&dev->dev, "xen map irq failed %d for %d domain\n", in xen_initdom_setup_msi_irqs()
344 (type == PCI_CAP_ID_MSIX) ? "msi-x" : "msi", in xen_initdom_setup_msi_irqs()
349 ret = msi_device_populate_sysfs(&dev->dev); in xen_initdom_setup_msi_irqs()
364 restore_ext.seg = pci_domain_nr(dev->bus); in xen_initdom_restore_msi()
365 restore_ext.bus = dev->bus->number; in xen_initdom_restore_msi()
366 restore_ext.devfn = dev->devfn; in xen_initdom_restore_msi()
369 if (ret == -ENOSYS) in xen_initdom_restore_msi()
371 WARN(ret && ret != -ENOSYS, "restore_msi_ext -> %d\n", ret); in xen_initdom_restore_msi()
376 restore.bus = dev->bus->number; in xen_initdom_restore_msi()
377 restore.devfn = dev->devfn; in xen_initdom_restore_msi()
379 WARN(ret && ret != -ENOSYS, "restore_msi -> %d\n", ret); in xen_initdom_restore_msi()
392 msi_for_each_desc(msidesc, &dev->dev, MSI_DESC_ASSOCIATED) { in xen_teardown_msi_irqs()
393 for (i = 0; i < msidesc->nvec_used; i++) in xen_teardown_msi_irqs()
394 xen_destroy_irq(msidesc->irq + i); in xen_teardown_msi_irqs()
395 msidesc->irq = 0; in xen_teardown_msi_irqs()
398 msi_device_destroy_sysfs(&dev->dev); in xen_teardown_msi_irqs()
403 if (dev->msix_enabled) in xen_pv_teardown_msi_irqs()
411 static int xen_msi_domain_alloc_irqs(struct irq_domain *domain, in xen_msi_domain_alloc_irqs() argument
417 return -EINVAL; in xen_msi_domain_alloc_irqs()
419 type = to_pci_dev(dev)->msix_enabled ? PCI_CAP_ID_MSIX : PCI_CAP_ID_MSI; in xen_msi_domain_alloc_irqs()
424 static void xen_msi_domain_free_irqs(struct irq_domain *domain, in xen_msi_domain_free_irqs() argument
444 * This irq domain is a blatant violation of the irq domain design, but
448 * domain pointer in struct device. This irq domain wrappery allows to do
456 fn = irq_domain_alloc_named_fwnode("XEN-MSI"); in xen_create_pci_msi_domain()
483 * Override the PCI/MSI irq domain init function. No point in xen_setup_pci_msi()
484 * in allocating the native domain and never use it. in xen_setup_pci_msi()
488 * With XEN PIRQ/Eventchannels in use PCI/MSI[-X] masking is solely in xen_setup_pci_msi()
501 return -ENODEV; in pci_xen_init()
503 printk(KERN_INFO "PCI: setting up Xen PCI frontend stub\n"); in pci_xen_init()
570 * Pre-allocate the legacy IRQs. Use NR_LEGACY_IRQS here in pci_xen_initial_domain()
576 if (acpi_get_override_irq(irq, &trigger, &polarity) == -1) in pci_xen_initial_domain()
585 xen_bind_pirq_gsi_to_irq(irq, irq, 0, "xt-pic"); in pci_xen_initial_domain()