diff options
| -rw-r--r-- | drivers/iommu/fsl_pamu_domain.c | 66 |
1 files changed, 1 insertions, 65 deletions
diff --git a/drivers/iommu/fsl_pamu_domain.c b/drivers/iommu/fsl_pamu_domain.c index 93072ba44b1d..d02d668c6ab1 100644 --- a/drivers/iommu/fsl_pamu_domain.c +++ b/drivers/iommu/fsl_pamu_domain.c | |||
| @@ -38,7 +38,6 @@ | |||
| 38 | #include <sysdev/fsl_pci.h> | 38 | #include <sysdev/fsl_pci.h> |
| 39 | 39 | ||
| 40 | #include "fsl_pamu_domain.h" | 40 | #include "fsl_pamu_domain.h" |
| 41 | #include "pci.h" | ||
| 42 | 41 | ||
| 43 | /* | 42 | /* |
| 44 | * Global spinlock that needs to be held while | 43 | * Global spinlock that needs to be held while |
| @@ -892,8 +891,6 @@ static int fsl_pamu_get_domain_attr(struct iommu_domain *domain, | |||
| 892 | return ret; | 891 | return ret; |
| 893 | } | 892 | } |
| 894 | 893 | ||
| 895 | #define REQ_ACS_FLAGS (PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF) | ||
| 896 | |||
| 897 | static struct iommu_group *get_device_iommu_group(struct device *dev) | 894 | static struct iommu_group *get_device_iommu_group(struct device *dev) |
| 898 | { | 895 | { |
| 899 | struct iommu_group *group; | 896 | struct iommu_group *group; |
| @@ -950,74 +947,13 @@ static struct iommu_group *get_pci_device_group(struct pci_dev *pdev) | |||
| 950 | struct pci_controller *pci_ctl; | 947 | struct pci_controller *pci_ctl; |
| 951 | bool pci_endpt_partioning; | 948 | bool pci_endpt_partioning; |
| 952 | struct iommu_group *group = NULL; | 949 | struct iommu_group *group = NULL; |
| 953 | struct pci_dev *bridge, *dma_pdev = NULL; | ||
| 954 | 950 | ||
| 955 | pci_ctl = pci_bus_to_host(pdev->bus); | 951 | pci_ctl = pci_bus_to_host(pdev->bus); |
| 956 | pci_endpt_partioning = check_pci_ctl_endpt_part(pci_ctl); | 952 | pci_endpt_partioning = check_pci_ctl_endpt_part(pci_ctl); |
| 957 | /* We can partition PCIe devices so assign device group to the device */ | 953 | /* We can partition PCIe devices so assign device group to the device */ |
| 958 | if (pci_endpt_partioning) { | 954 | if (pci_endpt_partioning) { |
| 959 | bridge = pci_find_upstream_pcie_bridge(pdev); | 955 | group = iommu_group_get_for_dev(&pdev->dev); |
| 960 | if (bridge) { | ||
| 961 | if (pci_is_pcie(bridge)) | ||
| 962 | dma_pdev = pci_get_domain_bus_and_slot( | ||
| 963 | pci_domain_nr(pdev->bus), | ||
| 964 | bridge->subordinate->number, 0); | ||
| 965 | if (!dma_pdev) | ||
| 966 | dma_pdev = pci_dev_get(bridge); | ||
| 967 | } else | ||
| 968 | dma_pdev = pci_dev_get(pdev); | ||
| 969 | |||
| 970 | /* Account for quirked devices */ | ||
| 971 | swap_pci_ref(&dma_pdev, pci_get_dma_source(dma_pdev)); | ||
| 972 | |||
| 973 | /* | ||
| 974 | * If it's a multifunction device that does not support our | ||
| 975 | * required ACS flags, add to the same group as lowest numbered | ||
| 976 | * function that also does not suport the required ACS flags. | ||
| 977 | */ | ||
| 978 | if (dma_pdev->multifunction && | ||
| 979 | !pci_acs_enabled(dma_pdev, REQ_ACS_FLAGS)) { | ||
| 980 | u8 i, slot = PCI_SLOT(dma_pdev->devfn); | ||
| 981 | |||
| 982 | for (i = 0; i < 8; i++) { | ||
| 983 | struct pci_dev *tmp; | ||
| 984 | |||
| 985 | tmp = pci_get_slot(dma_pdev->bus, PCI_DEVFN(slot, i)); | ||
| 986 | if (!tmp) | ||
| 987 | continue; | ||
| 988 | |||
| 989 | if (!pci_acs_enabled(tmp, REQ_ACS_FLAGS)) { | ||
| 990 | swap_pci_ref(&dma_pdev, tmp); | ||
| 991 | break; | ||
| 992 | } | ||
| 993 | pci_dev_put(tmp); | ||
| 994 | } | ||
| 995 | } | ||
| 996 | |||
| 997 | /* | ||
| 998 | * Devices on the root bus go through the iommu. If that's not us, | ||
| 999 | * find the next upstream device and test ACS up to the root bus. | ||
| 1000 | * Finding the next device may require skipping virtual buses. | ||
| 1001 | */ | ||
| 1002 | while (!pci_is_root_bus(dma_pdev->bus)) { | ||
| 1003 | struct pci_bus *bus = dma_pdev->bus; | ||
| 1004 | |||
| 1005 | while (!bus->self) { | ||
| 1006 | if (!pci_is_root_bus(bus)) | ||
| 1007 | bus = bus->parent; | ||
| 1008 | else | ||
| 1009 | goto root_bus; | ||
| 1010 | } | ||
| 1011 | |||
| 1012 | if (pci_acs_path_enabled(bus->self, NULL, REQ_ACS_FLAGS)) | ||
| 1013 | break; | ||
| 1014 | |||
| 1015 | swap_pci_ref(&dma_pdev, pci_dev_get(bus->self)); | ||
| 1016 | } | ||
| 1017 | 956 | ||
| 1018 | root_bus: | ||
| 1019 | group = get_device_iommu_group(&dma_pdev->dev); | ||
| 1020 | pci_dev_put(dma_pdev); | ||
| 1021 | /* | 957 | /* |
| 1022 | * PCIe controller is not a paritionable entity | 958 | * PCIe controller is not a paritionable entity |
| 1023 | * free the controller device iommu_group. | 959 | * free the controller device iommu_group. |
