diff options
author | Alex Williamson <alex.williamson@redhat.com> | 2014-07-03 11:51:49 -0400 |
---|---|---|
committer | Joerg Roedel <jroedel@suse.de> | 2014-07-04 06:35:58 -0400 |
commit | 7319eded2ebadcc5af8776f767e517278e9daf4e (patch) | |
tree | fdb78b4d0390de5a9c65f6ca05299ee56ff036c3 | |
parent | 579305f75d34429d11e7eeeee9d9e45000a988d3 (diff) |
iommu/fsl: Use iommu_group_get_for_dev() for IOMMU groups
Drop custom code and use IOMMU provided grouping support for PCI.
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
Acked-by: Varun Sethi <varun.sethi@freescale.com>
Signed-off-by: Joerg Roedel <jroedel@suse.de>
-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. |