#include <linux/sizes.h>
 #include <linux/limits.h>
 #include <linux/clk/clk-conf.h>
+#include <linux/platform_device.h>
 
 #include <asm/irq.h>
 
 /*
  * Primecells are part of the Advanced Microcontroller Bus Architecture,
  * so we call the bus "amba".
+ * DMA configuration for platform and AMBA bus is same. So here we reuse
+ * platform's DMA config routine.
  */
 struct bus_type amba_bustype = {
        .name           = "amba",
        .dev_groups     = amba_dev_groups,
        .match          = amba_match,
        .uevent         = amba_uevent,
+       .dma_configure  = platform_dma_configure,
        .pm             = &amba_pm,
        .force_dma      = true,
 };
 
 #endif
 
 /*
- * Common configuration to enable DMA API use for a device
+ * enables 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)
-                       ret = acpi_dma_configure(dev, attr);
-       }
-
-       if (bridge)
-               pci_put_host_bridge_device(bridge);
-
-       return ret;
+       if (dev->bus->dma_configure)
+               return dev->bus->dma_configure(dev);
+       return 0;
 }
 
 void dma_deconfigure(struct device *dev)
 
 
 #endif /* CONFIG_HIBERNATE_CALLBACKS */
 
+int platform_dma_configure(struct device *dev)
+{
+       enum dev_dma_attr attr;
+       int ret = 0;
+
+       if (dev->of_node) {
+               ret = of_dma_configure(dev, dev->of_node);
+       } else if (has_acpi_companion(dev)) {
+               attr = acpi_get_dma_attr(to_acpi_device_node(dev->fwnode));
+               if (attr != DEV_DMA_NOT_SUPPORTED)
+                       ret = acpi_dma_configure(dev, attr);
+       }
+
+       return ret;
+}
+
 static const struct dev_pm_ops platform_dev_pm_ops = {
        .runtime_suspend = pm_generic_runtime_suspend,
        .runtime_resume = pm_generic_runtime_resume,
        .dev_groups     = platform_dev_groups,
        .match          = platform_match,
        .uevent         = platform_uevent,
+       .dma_configure  = platform_dma_configure,
        .pm             = &platform_dev_pm_ops,
        .force_dma      = true,
 };
 
        return strcmp(dev_name(dev), drv->name) == 0;
 }
 
+static int host1x_dma_configure(struct device *dev)
+{
+       return of_dma_configure(dev, dev->of_node);
+}
+
 static const struct dev_pm_ops host1x_device_pm_ops = {
        .suspend = pm_generic_suspend,
        .resume = pm_generic_resume,
 struct bus_type host1x_bus_type = {
        .name = "host1x",
        .match = host1x_device_match,
+       .dma_configure  = host1x_dma_configure,
        .pm = &host1x_device_pm_ops,
        .force_dma = true,
 };
 
 #include <linux/pm_runtime.h>
 #include <linux/suspend.h>
 #include <linux/kexec.h>
+#include <linux/of_device.h>
+#include <linux/acpi.h>
 #include "pci.h"
 #include "pcie/portdrv.h"
 
        return pci_num_vf(to_pci_dev(dev));
 }
 
+/**
+ * pci_dma_configure - Setup DMA configuration
+ * @dev: ptr to dev structure
+ *
+ * Function to update PCI devices's DMA configuration using the same
+ * info from the OF node or ACPI node of host bridge's parent (if any).
+ */
+static int pci_dma_configure(struct device *dev)
+{
+       struct device *bridge;
+       int ret = 0;
+
+       bridge = pci_get_host_bridge_device(to_pci_dev(dev));
+
+       if (IS_ENABLED(CONFIG_OF) && bridge->parent &&
+           bridge->parent->of_node) {
+               ret = of_dma_configure(dev, bridge->parent->of_node);
+       } else if (has_acpi_companion(bridge)) {
+               struct acpi_device *adev = to_acpi_device_node(bridge->fwnode);
+               enum dev_dma_attr attr = acpi_get_dma_attr(adev);
+
+               if (attr != DEV_DMA_NOT_SUPPORTED)
+                       ret = acpi_dma_configure(dev, attr);
+       }
+
+       pci_put_host_bridge_device(bridge);
+       return ret;
+}
+
 struct bus_type pci_bus_type = {
        .name           = "pci",
        .match          = pci_bus_match,
        .drv_groups     = pci_drv_groups,
        .pm             = PCI_PM_OPS_PTR,
        .num_vf         = pci_bus_num_vf,
+       .dma_configure  = pci_dma_configure,
        .force_dma      = true,
 };
 EXPORT_SYMBOL(pci_bus_type);
 
  * @resume:    Called to bring a device on this bus out of sleep mode.
  * @num_vf:    Called to find out how many virtual functions a device on this
  *             bus supports.
+ * @dma_configure:     Called to setup DMA configuration on a device on
+                       this bus.
  * @pm:                Power management operations of this bus, callback the specific
  *             device driver's pm-ops.
  * @iommu_ops:  IOMMU specific operations for this bus, used to attach IOMMU
 
        int (*num_vf)(struct device *dev);
 
+       int (*dma_configure)(struct device *dev);
+
        const struct dev_pm_ops *pm;
 
        const struct iommu_ops *iommu_ops;
 
 #define platform_pm_restore            NULL
 #endif
 
+extern int platform_dma_configure(struct device *dev);
+
 #ifdef CONFIG_PM_SLEEP
 #define USE_PLATFORM_PM_SLEEP_OPS \
        .suspend = platform_pm_suspend, \