Merge tag 'pwm/for-6.7-rc5-fixes' of https://git.pengutronix.de/git/ukl/linux
[linux-2.6-block.git] / drivers / iommu / of_iommu.c
index 157b286e36bf3a1ee1b312138c761d6e8dc97911..35ba090f3b5e24e615e7a604f18fb0d532706a6a 100644 (file)
@@ -112,16 +112,20 @@ const struct iommu_ops *of_iommu_configure(struct device *dev,
                                           const u32 *id)
 {
        const struct iommu_ops *ops = NULL;
-       struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
+       struct iommu_fwspec *fwspec;
        int err = NO_IOMMU;
 
        if (!master_np)
                return NULL;
 
+       /* Serialise to make dev->iommu stable under our potential fwspec */
+       mutex_lock(&iommu_probe_device_lock);
+       fwspec = dev_iommu_fwspec_get(dev);
        if (fwspec) {
-               if (fwspec->ops)
+               if (fwspec->ops) {
+                       mutex_unlock(&iommu_probe_device_lock);
                        return fwspec->ops;
-
+               }
                /* In the deferred case, start again from scratch */
                iommu_fwspec_free(dev);
        }
@@ -155,6 +159,8 @@ const struct iommu_ops *of_iommu_configure(struct device *dev,
                fwspec = dev_iommu_fwspec_get(dev);
                ops    = fwspec->ops;
        }
+       mutex_unlock(&iommu_probe_device_lock);
+
        /*
         * If we have reason to believe the IOMMU driver missed the initial
         * probe for dev, replay it to get things in order.
@@ -191,7 +197,7 @@ iommu_resv_region_get_type(struct device *dev,
        if (start == phys->start && end == phys->end)
                return IOMMU_RESV_DIRECT;
 
-       dev_warn(dev, "treating non-direct mapping [%pr] -> [%pap-%pap] as reservation\n", &phys,
+       dev_warn(dev, "treating non-direct mapping [%pr] -> [%pap-%pap] as reservation\n", phys,
                 &start, &end);
        return IOMMU_RESV_RESERVED;
 }