| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Low-Level PCI Support for PC |
|---|
| 3 | 4 | * |
|---|
| .. | .. |
|---|
| 18 | 19 | #include <asm/smp.h> |
|---|
| 19 | 20 | #include <asm/pci_x86.h> |
|---|
| 20 | 21 | #include <asm/setup.h> |
|---|
| 22 | +#include <asm/irqdomain.h> |
|---|
| 21 | 23 | |
|---|
| 22 | 24 | unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2 | |
|---|
| 23 | 25 | PCI_PROBE_MMCONF; |
|---|
| .. | .. |
|---|
| 134 | 136 | * resource so the kernel doesn't attempt to assign |
|---|
| 135 | 137 | * it later on in pci_assign_unassigned_resources |
|---|
| 136 | 138 | */ |
|---|
| 137 | | - for (bar = 0; bar <= PCI_STD_RESOURCE_END; bar++) { |
|---|
| 139 | + for (bar = 0; bar < PCI_STD_NUM_BARS; bar++) { |
|---|
| 138 | 140 | bar_r = &dev->resource[bar]; |
|---|
| 139 | 141 | if (bar_r->start == 0 && bar_r->end != 0) { |
|---|
| 140 | 142 | bar_r->flags = 0; |
|---|
| .. | .. |
|---|
| 624 | 626 | return (pci_probe & PCI_ASSIGN_ALL_BUSSES) ? 1 : 0; |
|---|
| 625 | 627 | } |
|---|
| 626 | 628 | |
|---|
| 627 | | -#if defined(CONFIG_X86_DEV_DMA_OPS) && defined(CONFIG_PCI_DOMAINS) |
|---|
| 628 | | -static LIST_HEAD(dma_domain_list); |
|---|
| 629 | | -static DEFINE_SPINLOCK(dma_domain_list_lock); |
|---|
| 630 | | - |
|---|
| 631 | | -void add_dma_domain(struct dma_domain *domain) |
|---|
| 632 | | -{ |
|---|
| 633 | | - spin_lock(&dma_domain_list_lock); |
|---|
| 634 | | - list_add(&domain->node, &dma_domain_list); |
|---|
| 635 | | - spin_unlock(&dma_domain_list_lock); |
|---|
| 636 | | -} |
|---|
| 637 | | -EXPORT_SYMBOL_GPL(add_dma_domain); |
|---|
| 638 | | - |
|---|
| 639 | | -void del_dma_domain(struct dma_domain *domain) |
|---|
| 640 | | -{ |
|---|
| 641 | | - spin_lock(&dma_domain_list_lock); |
|---|
| 642 | | - list_del(&domain->node); |
|---|
| 643 | | - spin_unlock(&dma_domain_list_lock); |
|---|
| 644 | | -} |
|---|
| 645 | | -EXPORT_SYMBOL_GPL(del_dma_domain); |
|---|
| 646 | | - |
|---|
| 647 | | -static void set_dma_domain_ops(struct pci_dev *pdev) |
|---|
| 648 | | -{ |
|---|
| 649 | | - struct dma_domain *domain; |
|---|
| 650 | | - |
|---|
| 651 | | - spin_lock(&dma_domain_list_lock); |
|---|
| 652 | | - list_for_each_entry(domain, &dma_domain_list, node) { |
|---|
| 653 | | - if (pci_domain_nr(pdev->bus) == domain->domain_nr) { |
|---|
| 654 | | - pdev->dev.dma_ops = domain->dma_ops; |
|---|
| 655 | | - break; |
|---|
| 656 | | - } |
|---|
| 657 | | - } |
|---|
| 658 | | - spin_unlock(&dma_domain_list_lock); |
|---|
| 659 | | -} |
|---|
| 660 | | -#else |
|---|
| 661 | | -static void set_dma_domain_ops(struct pci_dev *pdev) {} |
|---|
| 662 | | -#endif |
|---|
| 663 | | - |
|---|
| 664 | 629 | static void set_dev_domain_options(struct pci_dev *pdev) |
|---|
| 665 | 630 | { |
|---|
| 666 | 631 | if (is_vmd(pdev->bus)) |
|---|
| .. | .. |
|---|
| 669 | 634 | |
|---|
| 670 | 635 | int pcibios_add_device(struct pci_dev *dev) |
|---|
| 671 | 636 | { |
|---|
| 672 | | - struct setup_data *data; |
|---|
| 673 | 637 | struct pci_setup_rom *rom; |
|---|
| 638 | + struct irq_domain *msidom; |
|---|
| 639 | + struct setup_data *data; |
|---|
| 674 | 640 | u64 pa_data; |
|---|
| 675 | 641 | |
|---|
| 676 | 642 | pa_data = boot_params.hdr.setup_data; |
|---|
| .. | .. |
|---|
| 696 | 662 | pa_data = data->next; |
|---|
| 697 | 663 | memunmap(data); |
|---|
| 698 | 664 | } |
|---|
| 699 | | - set_dma_domain_ops(dev); |
|---|
| 700 | 665 | set_dev_domain_options(dev); |
|---|
| 666 | + |
|---|
| 667 | + /* |
|---|
| 668 | + * Setup the initial MSI domain of the device. If the underlying |
|---|
| 669 | + * bus has a PCI/MSI irqdomain associated use the bus domain, |
|---|
| 670 | + * otherwise set the default domain. This ensures that special irq |
|---|
| 671 | + * domains e.g. VMD are preserved. The default ensures initial |
|---|
| 672 | + * operation if irq remapping is not active. If irq remapping is |
|---|
| 673 | + * active it will overwrite the domain pointer when the device is |
|---|
| 674 | + * associated to a remapping domain. |
|---|
| 675 | + */ |
|---|
| 676 | + msidom = dev_get_msi_domain(&dev->bus->dev); |
|---|
| 677 | + if (!msidom) |
|---|
| 678 | + msidom = x86_pci_msi_default_domain; |
|---|
| 679 | + dev_set_msi_domain(&dev->dev, msidom); |
|---|
| 701 | 680 | return 0; |
|---|
| 702 | 681 | } |
|---|
| 703 | 682 | |
|---|
| .. | .. |
|---|
| 735 | 714 | else |
|---|
| 736 | 715 | return 0; |
|---|
| 737 | 716 | } |
|---|
| 717 | + |
|---|
| 718 | +#if IS_ENABLED(CONFIG_VMD) |
|---|
| 719 | +struct pci_dev *pci_real_dma_dev(struct pci_dev *dev) |
|---|
| 720 | +{ |
|---|
| 721 | + if (is_vmd(dev->bus)) |
|---|
| 722 | + return to_pci_sysdata(dev->bus)->vmd_dev; |
|---|
| 723 | + |
|---|
| 724 | + return dev; |
|---|
| 725 | +} |
|---|
| 726 | +#endif |
|---|