diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c index b7232c46b244..6daf620b63a4 100644 --- a/arch/powerpc/sysdev/fsl_pci.c +++ b/arch/powerpc/sysdev/fsl_pci.c @@ -1353,6 +1353,7 @@ static struct platform_driver fsl_pci_driver = { .of_match_table = pci_ids, }, .probe = fsl_pci_probe, + .driver_managed_dma = true, }; static int __init fsl_pci_init(void) diff --git a/drivers/iommu/fsl_pamu_domain.c b/drivers/iommu/fsl_pamu_domain.c index d0683daa900f..4ac0e247ec2b 100644 --- a/drivers/iommu/fsl_pamu_domain.c +++ b/drivers/iommu/fsl_pamu_domain.c @@ -334,17 +334,6 @@ int fsl_pamu_configure_l1_stash(struct iommu_domain *domain, u32 cpu) return ret; } -static struct iommu_group *get_device_iommu_group(struct device *dev) -{ - struct iommu_group *group; - - group = iommu_group_get(dev); - if (!group) - group = iommu_group_alloc(); - - return group; -} - static bool check_pci_ctl_endpt_part(struct pci_controller *pci_ctl) { u32 version; @@ -356,85 +345,38 @@ static bool check_pci_ctl_endpt_part(struct pci_controller *pci_ctl) return version >= 0x204; } -/* Get iommu group information from peer devices or devices on the parent bus */ -static struct iommu_group *get_shared_pci_device_group(struct pci_dev *pdev) -{ - struct pci_dev *tmp; - struct iommu_group *group; - struct pci_bus *bus = pdev->bus; - - /* - * Traverese the pci bus device list to get - * the shared iommu group. - */ - while (bus) { - list_for_each_entry(tmp, &bus->devices, bus_list) { - if (tmp == pdev) - continue; - group = iommu_group_get(&tmp->dev); - if (group) - return group; - } - - bus = bus->parent; - } - - return NULL; -} - -static struct iommu_group *get_pci_device_group(struct pci_dev *pdev) -{ - struct pci_controller *pci_ctl; - bool pci_endpt_partitioning; - struct iommu_group *group = NULL; - - pci_ctl = pci_bus_to_host(pdev->bus); - pci_endpt_partitioning = check_pci_ctl_endpt_part(pci_ctl); - /* We can partition PCIe devices so assign device group to the device */ - if (pci_endpt_partitioning) { - group = pci_device_group(&pdev->dev); - - /* - * PCIe controller is not a paritionable entity - * free the controller device iommu_group. - */ - if (pci_ctl->parent->iommu_group) - iommu_group_remove_device(pci_ctl->parent); - } else { - /* - * All devices connected to the controller will share the - * PCI controllers device group. If this is the first - * device to be probed for the pci controller, copy the - * device group information from the PCI controller device - * node and remove the PCI controller iommu group. - * For subsequent devices, the iommu group information can - * be obtained from sibling devices (i.e. from the bus_devices - * link list). - */ - if (pci_ctl->parent->iommu_group) { - group = get_device_iommu_group(pci_ctl->parent); - iommu_group_remove_device(pci_ctl->parent); - } else { - group = get_shared_pci_device_group(pdev); - } - } - - if (!group) - group = ERR_PTR(-ENODEV); - - return group; -} - static struct iommu_group *fsl_pamu_device_group(struct device *dev) { + struct iommu_group *group; + struct pci_dev *pdev; + /* - * For platform devices we allocate a separate group for - * each of the devices. + * For platform devices we allocate a separate group for each of the + * devices. */ if (!dev_is_pci(dev)) return generic_device_group(dev); - return get_pci_device_group(to_pci_dev(dev)); + /* + * We can partition PCIe devices so assign device group to the device + */ + pdev = to_pci_dev(dev); + if (check_pci_ctl_endpt_part(pci_bus_to_host(pdev->bus))) + return pci_device_group(&pdev->dev); + + /* + * All devices connected to the controller will share the same device + * group. + * + * Due to ordering between fsl_pamu_init() and fsl_pci_init() it is + * guaranteed that the pci_ctl->parent platform_device will have the + * iommu driver bound and will already have a group set. So we just + * re-use this group as the group for every device in the hose. + */ + group = iommu_group_get(pci_bus_to_host(pdev->bus)->parent); + if (WARN_ON(!group)) + return ERR_PTR(-EINVAL); + return group; } static struct iommu_device *fsl_pamu_probe_device(struct device *dev)