]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/base/dma-mapping.c
iommu: of: Handle IOMMU lookup failure with deferred probing or error
[karo-tx-linux.git] / drivers / base / dma-mapping.c
index efd71cf4fdead7c5f0b88dcdb3c7dee800b7cb65..82bd45ced7ff6803b582072f288969987e571d71 100644 (file)
@@ -7,9 +7,11 @@
  * This file is released under the GPLv2.
  */
 
+#include <linux/acpi.h>
 #include <linux/dma-mapping.h>
 #include <linux/export.h>
 #include <linux/gfp.h>
+#include <linux/of_device.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
 
@@ -341,3 +343,42 @@ void dma_common_free_remap(void *cpu_addr, size_t size, unsigned long vm_flags)
        vunmap(cpu_addr);
 }
 #endif
+
+/*
+ * Common configuration to enable DMA API use for a device
+ */
+#include <linux/pci.h>
+
+int dma_configure(struct device *dev)
+{
+       struct device *bridge = NULL, *dma_dev = dev;
+       enum dev_dma_attr attr;
+       int ret = 0;
+
+       if (dev_is_pci(dev)) {
+               bridge = pci_get_host_bridge_device(to_pci_dev(dev));
+               dma_dev = bridge;
+               if (IS_ENABLED(CONFIG_OF) && dma_dev->parent &&
+                   dma_dev->parent->of_node)
+                       dma_dev = dma_dev->parent;
+       }
+
+       if (dma_dev->of_node) {
+               ret = of_dma_configure(dev, dma_dev->of_node);
+       } else if (has_acpi_companion(dma_dev)) {
+               attr = acpi_get_dma_attr(to_acpi_device_node(dma_dev->fwnode));
+               if (attr != DEV_DMA_NOT_SUPPORTED)
+                       acpi_dma_configure(dev, attr);
+       }
+
+       if (bridge)
+               pci_put_host_bridge_device(bridge);
+
+       return ret;
+}
+
+void dma_deconfigure(struct device *dev)
+{
+       of_dma_deconfigure(dev);
+       acpi_dma_deconfigure(dev);
+}