powerpc/powernv: Fix IOMMU group lost
[cascardo/linux.git] / arch / powerpc / kernel / iommu.c
index f84f799..a10642a 100644 (file)
@@ -1120,37 +1120,41 @@ EXPORT_SYMBOL_GPL(iommu_release_ownership);
 int iommu_add_device(struct device *dev)
 {
        struct iommu_table *tbl;
-       int ret = 0;
 
-       if (WARN_ON(dev->iommu_group)) {
-               pr_warn("iommu_tce: device %s is already in iommu group %d, skipping\n",
-                               dev_name(dev),
-                               iommu_group_id(dev->iommu_group));
+       /*
+        * The sysfs entries should be populated before
+        * binding IOMMU group. If sysfs entries isn't
+        * ready, we simply bail.
+        */
+       if (!device_is_registered(dev))
+               return -ENOENT;
+
+       if (dev->iommu_group) {
+               pr_debug("%s: Skipping device %s with iommu group %d\n",
+                        __func__, dev_name(dev),
+                        iommu_group_id(dev->iommu_group));
                return -EBUSY;
        }
 
        tbl = get_iommu_table_base(dev);
        if (!tbl || !tbl->it_group) {
-               pr_debug("iommu_tce: skipping device %s with no tbl\n",
-                               dev_name(dev));
+               pr_debug("%s: Skipping device %s with no tbl\n",
+                        __func__, dev_name(dev));
                return 0;
        }
 
-       pr_debug("iommu_tce: adding %s to iommu group %d\n",
-                       dev_name(dev), iommu_group_id(tbl->it_group));
+       pr_debug("%s: Adding %s to iommu group %d\n",
+                __func__, dev_name(dev),
+                iommu_group_id(tbl->it_group));
 
        if (PAGE_SIZE < IOMMU_PAGE_SIZE(tbl)) {
-               pr_err("iommu_tce: unsupported iommu page size.");
-               pr_err("%s has not been added\n", dev_name(dev));
+               pr_err("%s: Invalid IOMMU page size %lx (%lx) on %s\n",
+                      __func__, IOMMU_PAGE_SIZE(tbl),
+                      PAGE_SIZE, dev_name(dev));
                return -EINVAL;
        }
 
-       ret = iommu_group_add_device(tbl->it_group, dev);
-       if (ret < 0)
-               pr_err("iommu_tce: %s has not been added, ret=%d\n",
-                               dev_name(dev), ret);
-
-       return ret;
+       return iommu_group_add_device(tbl->it_group, dev);
 }
 EXPORT_SYMBOL_GPL(iommu_add_device);