Add a check to the bus_iommu_probe() call-path to make sure it ignores devices which have already been successfully probed. Then export the bus_iommu_probe() function so it can be used by IOMMU drivers.
Unified · Split
| @@ -1610,11 +1610,19 @@ static int probe_iommu_group(struct device *dev, void *data) · 1609 unmodified lines | |||
| 1610 | { | 1610 | { |
| 1611 | const struct iommu_ops *ops = dev->bus->iommu_ops; | 1611 | const struct iommu_ops *ops = dev->bus->iommu_ops; |
| 1612 | struct list_head *group_list = data; | 1612 | struct list_head *group_list = data; |
| 1613 | struct iommu_group *group; | ||
| 1613 | int ret; | 1614 | int ret; |
| 1614 | 1615 | ||
| 1615 | if (!dev_iommu_get(dev)) | 1616 | if (!dev_iommu_get(dev)) |
| 1616 | return -ENOMEM; | 1617 | return -ENOMEM; |
| 1617 | 1618 | ||
| 1619 | /* Device is probed already if in a group */ | ||
| 1620 | group = iommu_group_get(dev); | ||
| 1621 | if (group) { | ||
| 1622 | iommu_group_put(group); | ||
| 1623 | return 0; | ||
| 1624 | } | ||
| 1625 | |||
| 1618 | if (!try_module_get(ops->owner)) { | 1626 | if (!try_module_get(ops->owner)) { |
| 1619 | ret = -EINVAL; | 1627 | ret = -EINVAL; |
| 1620 | goto err_free_dev_iommu; | 1628 | goto err_free_dev_iommu; |
| @@ -1783,7 +1791,7 @@ static int iommu_group_create_direct_mappings(struct iommu_group *group) · 162 unmodified lines | |||
| 1783 | iommu_do_create_direct_mappings); | 1791 | iommu_do_create_direct_mappings); |
| 1784 | } | 1792 | } |
| 1785 | 1793 | ||
| 1786 | static int bus_iommu_probe(struct bus_type *bus) | 1794 | int bus_iommu_probe(struct bus_type *bus) |
| 1787 | { | 1795 | { |
| 1788 | const struct iommu_ops *ops = bus->iommu_ops; | 1796 | const struct iommu_ops *ops = bus->iommu_ops; |
| 1789 | int ret; | 1797 | int ret; |
| @@ -445,6 +445,7 @@ static inline void iommu_iotlb_gather_init(struct iommu_iotlb_gather *gather) · 444 unmodified lines | |||
| 445 | #define IOMMU_GROUP_NOTIFY_UNBOUND_DRIVER 6 /* Post Driver unbind */ | 445 | #define IOMMU_GROUP_NOTIFY_UNBOUND_DRIVER 6 /* Post Driver unbind */ |
| 446 | 446 | ||
| 447 | extern int bus_set_iommu(struct bus_type *bus, const struct iommu_ops *ops); | 447 | extern int bus_set_iommu(struct bus_type *bus, const struct iommu_ops *ops); |
| 448 | extern int bus_iommu_probe(struct bus_type *bus); | ||
| 448 | extern bool iommu_present(struct bus_type *bus); | 449 | extern bool iommu_present(struct bus_type *bus); |
| 449 | extern bool iommu_capable(struct bus_type *bus, enum iommu_cap cap); | 450 | extern bool iommu_capable(struct bus_type *bus, enum iommu_cap cap); |
| 450 | extern struct iommu_domain *iommu_domain_alloc(struct bus_type *bus); | 451 | extern struct iommu_domain *iommu_domain_alloc(struct bus_type *bus); |