diff options
author | Sricharan R <sricharan@codeaurora.org> | 2017-04-10 07:21:01 -0400 |
---|---|---|
committer | Joerg Roedel <jroedel@suse.de> | 2017-04-20 10:31:06 -0400 |
commit | 09515ef5ddad71c7820e5e428da418b709feeb26 (patch) | |
tree | 3786792035e575e806a629cbf02ac3c96f5ebe53 /drivers/base/dma-mapping.c | |
parent | efc8551a276faab19d85079da02c5fb602b0dcbe (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.c | 40 |
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 | |||
352 | int 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 | |||
379 | void dma_deconfigure(struct device *dev) | ||
380 | { | ||
381 | of_dma_deconfigure(dev); | ||
382 | acpi_dma_deconfigure(dev); | ||
383 | } | ||