aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Williamson <alex.williamson@redhat.com>2014-07-03 11:51:49 -0400
committerJoerg Roedel <jroedel@suse.de>2014-07-04 06:35:58 -0400
commit7319eded2ebadcc5af8776f767e517278e9daf4e (patch)
treefdb78b4d0390de5a9c65f6ca05299ee56ff036c3
parent579305f75d34429d11e7eeeee9d9e45000a988d3 (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.c66
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
897static struct iommu_group *get_device_iommu_group(struct device *dev) 894static 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
1018root_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.