summaryrefslogtreecommitdiffstats
path: root/drivers/base/dma-mapping.c
diff options
context:
space:
mode:
authorSricharan R <sricharan@codeaurora.org>2017-04-10 07:21:01 -0400
committerJoerg Roedel <jroedel@suse.de>2017-04-20 10:31:06 -0400
commit09515ef5ddad71c7820e5e428da418b709feeb26 (patch)
tree3786792035e575e806a629cbf02ac3c96f5ebe53 /drivers/base/dma-mapping.c
parentefc8551a276faab19d85079da02c5fb602b0dcbe (diff)
of/acpi: Configure dma operations at probe time for platform/amba/pci bus devices
Configuring DMA ops at probe time will allow deferring device probe when the IOMMU isn't available yet. The dma_configure for the device is now called from the generic device_attach callback just before the bus/driver probe is called. This way, configuring the DMA ops for the device would be called at the same place for all bus_types, hence the deferred probing mechanism should work for all buses as well. pci_bus_add_devices (platform/amba)(_device_create/driver_register) | | pci_bus_add_device (device_add/driver_register) | | device_attach device_initial_probe | | __device_attach_driver __device_attach_driver | driver_probe_device | really_probe | dma_configure Similarly on the device/driver_unregister path __device_release_driver is called which inturn calls dma_deconfigure. This patch changes the dma ops configuration to probe time for both OF and ACPI based platform/amba/pci bus devices. Tested-by: Marek Szyprowski <m.szyprowski@samsung.com> Tested-by: Hanjun Guo <hanjun.guo@linaro.org> Reviewed-by: Robin Murphy <robin.murphy@arm.com> Acked-by: Rob Herring <robh@kernel.org> Acked-by: Bjorn Helgaas <bhelgaas@google.com> (drivers/pci part) Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Signed-off-by: Sricharan R <sricharan@codeaurora.org> Signed-off-by: Joerg Roedel <jroedel@suse.de>
Diffstat (limited to 'drivers/base/dma-mapping.c')
-rw-r--r--drivers/base/dma-mapping.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c
index efd71cf4fdea..449b948c7427 100644
--- a/drivers/base/dma-mapping.c
+++ b/drivers/base/dma-mapping.c
@@ -7,9 +7,11 @@
7 * This file is released under the GPLv2. 7 * This file is released under the GPLv2.
8 */ 8 */
9 9
10#include <linux/acpi.h>
10#include <linux/dma-mapping.h> 11#include <linux/dma-mapping.h>
11#include <linux/export.h> 12#include <linux/export.h>
12#include <linux/gfp.h> 13#include <linux/gfp.h>
14#include <linux/of_device.h>
13#include <linux/slab.h> 15#include <linux/slab.h>
14#include <linux/vmalloc.h> 16#include <linux/vmalloc.h>
15 17
@@ -341,3 +343,41 @@ void dma_common_free_remap(void *cpu_addr, size_t size, unsigned long vm_flags)
341 vunmap(cpu_addr); 343 vunmap(cpu_addr);
342} 344}
343#endif 345#endif
346
347/*
348 * Common configuration to enable DMA API use for a device
349 */
350#include <linux/pci.h>
351
352int dma_configure(struct device *dev)
353{
354 struct device *bridge = NULL, *dma_dev = dev;
355 enum dev_dma_attr attr;
356
357 if (dev_is_pci(dev)) {
358 bridge = pci_get_host_bridge_device(to_pci_dev(dev));
359 dma_dev = bridge;
360 if (IS_ENABLED(CONFIG_OF) && dma_dev->parent &&
361 dma_dev->parent->of_node)
362 dma_dev = dma_dev->parent;
363 }
364
365 if (dma_dev->of_node) {
366 of_dma_configure(dev, dma_dev->of_node);
367 } else if (has_acpi_companion(dma_dev)) {
368 attr = acpi_get_dma_attr(to_acpi_device_node(dma_dev->fwnode));
369 if (attr != DEV_DMA_NOT_SUPPORTED)
370 acpi_dma_configure(dev, attr);
371 }
372
373 if (bridge)
374 pci_put_host_bridge_device(bridge);
375
376 return 0;
377}
378
379void dma_deconfigure(struct device *dev)
380{
381 of_dma_deconfigure(dev);
382 acpi_dma_deconfigure(dev);
383}