]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blobdiff - arch/arm64/mm/dma-mapping.c
Merge branches 'arm/exynos', 'arm/omap', 'arm/rockchip', 'arm/mediatek', 'arm/smmu...
[mirror_ubuntu-artful-kernel.git] / arch / arm64 / mm / dma-mapping.c
index 81cdb2e844ed9fe80e4192315647ccc9245b8003..9a667a1ac6a6ac95645028fafe6cb6f7ce897179 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/dma-contiguous.h>
 #include <linux/vmalloc.h>
 #include <linux/swiotlb.h>
+#include <linux/pci.h>
 
 #include <asm/cacheflush.h>
 
@@ -813,34 +814,26 @@ static const struct dma_map_ops iommu_dma_ops = {
        .mapping_error = iommu_dma_mapping_error,
 };
 
-/*
- * TODO: Right now __iommu_setup_dma_ops() gets called too early to do
- * everything it needs to - the device is only partially created and the
- * IOMMU driver hasn't seen it yet, so it can't have a group. Thus we
- * need this delayed attachment dance. Once IOMMU probe ordering is sorted
- * to move the arch_setup_dma_ops() call later, all the notifier bits below
- * become unnecessary, and will go away.
- */
-struct iommu_dma_notifier_data {
-       struct list_head list;
-       struct device *dev;
-       const struct iommu_ops *ops;
-       u64 dma_base;
-       u64 size;
-};
-static LIST_HEAD(iommu_dma_masters);
-static DEFINE_MUTEX(iommu_dma_notifier_lock);
+static int __init __iommu_dma_init(void)
+{
+       return iommu_dma_init();
+}
+arch_initcall(__iommu_dma_init);
 
-static bool do_iommu_attach(struct device *dev, const struct iommu_ops *ops,
-                          u64 dma_base, u64 size)
+static void __iommu_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
+                                 const struct iommu_ops *ops)
 {
-       struct iommu_domain *domain = iommu_get_domain_for_dev(dev);
+       struct iommu_domain *domain;
+
+       if (!ops)
+               return;
 
        /*
-        * If the IOMMU driver has the DMA domain support that we require,
-        * then the IOMMU core will have already configured a group for this
-        * device, and allocated the default domain for that group.
+        * The IOMMU core code allocates the default DMA domain, which the
+        * underlying IOMMU driver needs to support via the dma-iommu layer.
         */
+       domain = iommu_get_domain_for_dev(dev);
+
        if (!domain)
                goto out_err;
 
@@ -851,109 +844,11 @@ static bool do_iommu_attach(struct device *dev, const struct iommu_ops *ops,
                dev->dma_ops = &iommu_dma_ops;
        }
 
-       return true;
+       return;
+
 out_err:
-       pr_warn("Failed to set up IOMMU for device %s; retaining platform DMA ops\n",
+        pr_warn("Failed to set up IOMMU for device %s; retaining platform DMA ops\n",
                 dev_name(dev));
-       return false;
-}
-
-static void queue_iommu_attach(struct device *dev, const struct iommu_ops *ops,
-                             u64 dma_base, u64 size)
-{
-       struct iommu_dma_notifier_data *iommudata;
-
-       iommudata = kzalloc(sizeof(*iommudata), GFP_KERNEL);
-       if (!iommudata)
-               return;
-
-       iommudata->dev = dev;
-       iommudata->ops = ops;
-       iommudata->dma_base = dma_base;
-       iommudata->size = size;
-
-       mutex_lock(&iommu_dma_notifier_lock);
-       list_add(&iommudata->list, &iommu_dma_masters);
-       mutex_unlock(&iommu_dma_notifier_lock);
-}
-
-static int __iommu_attach_notifier(struct notifier_block *nb,
-                                  unsigned long action, void *data)
-{
-       struct iommu_dma_notifier_data *master, *tmp;
-
-       if (action != BUS_NOTIFY_BIND_DRIVER)
-               return 0;
-
-       mutex_lock(&iommu_dma_notifier_lock);
-       list_for_each_entry_safe(master, tmp, &iommu_dma_masters, list) {
-               if (data == master->dev && do_iommu_attach(master->dev,
-                               master->ops, master->dma_base, master->size)) {
-                       list_del(&master->list);
-                       kfree(master);
-                       break;
-               }
-       }
-       mutex_unlock(&iommu_dma_notifier_lock);
-       return 0;
-}
-
-static int __init register_iommu_dma_ops_notifier(struct bus_type *bus)
-{
-       struct notifier_block *nb = kzalloc(sizeof(*nb), GFP_KERNEL);
-       int ret;
-
-       if (!nb)
-               return -ENOMEM;
-
-       nb->notifier_call = __iommu_attach_notifier;
-
-       ret = bus_register_notifier(bus, nb);
-       if (ret) {
-               pr_warn("Failed to register DMA domain notifier; IOMMU DMA ops unavailable on bus '%s'\n",
-                       bus->name);
-               kfree(nb);
-       }
-       return ret;
-}
-
-static int __init __iommu_dma_init(void)
-{
-       int ret;
-
-       ret = iommu_dma_init();
-       if (!ret)
-               ret = register_iommu_dma_ops_notifier(&platform_bus_type);
-       if (!ret)
-               ret = register_iommu_dma_ops_notifier(&amba_bustype);
-#ifdef CONFIG_PCI
-       if (!ret)
-               ret = register_iommu_dma_ops_notifier(&pci_bus_type);
-#endif
-       return ret;
-}
-arch_initcall(__iommu_dma_init);
-
-static void __iommu_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
-                                 const struct iommu_ops *ops)
-{
-       struct iommu_group *group;
-
-       if (!ops)
-               return;
-       /*
-        * TODO: As a concession to the future, we're ready to handle being
-        * called both early and late (i.e. after bus_add_device). Once all
-        * the platform bus code is reworked to call us late and the notifier
-        * junk above goes away, move the body of do_iommu_attach here.
-        */
-       group = iommu_group_get(dev);
-       if (group) {
-               do_iommu_attach(dev, ops, dma_base, size);
-               iommu_group_put(group);
-       } else {
-               queue_iommu_attach(dev, ops, dma_base, size);
-       }
 }
 
 void arch_teardown_dma_ops(struct device *dev)