Skip to content

Commit

Permalink
dma-mapping: detect and configure IOMMU in of_dma_configure
Browse files Browse the repository at this point in the history
This patch extends of_dma_configure so that it sets up the IOMMU for a
device, as well as the coherent/non-coherent DMA mapping ops.

Acked-by: Arnd Bergmann <[email protected]>
Acked-by: Marek Szyprowski <[email protected]>
Tested-by: Robin Murphy <[email protected]>
Signed-off-by: Will Deacon <[email protected]>
  • Loading branch information
wildea01 committed Dec 1, 2014
1 parent 461bfb3 commit 97890ba
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 9 deletions.
4 changes: 3 additions & 1 deletion arch/arm/include/asm/dma-mapping.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,9 @@ static inline unsigned long dma_max_pfn(struct device *dev)
}
#define dma_max_pfn(dev) dma_max_pfn(dev)

static inline void arch_setup_dma_ops(struct device *dev, bool coherent)
static inline void arch_setup_dma_ops(struct device *dev, u64 dma_base,
u64 size, struct iommu_ops *iommu,
bool coherent)
{
if (coherent)
set_dma_ops(dev, &arm_coherent_dma_ops);
Expand Down
21 changes: 14 additions & 7 deletions drivers/of/platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <linux/slab.h>
#include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/of_iommu.h>
#include <linux/of_irq.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
Expand Down Expand Up @@ -166,6 +167,7 @@ static void of_dma_configure(struct device *dev)
int ret;
bool coherent;
unsigned long offset;
struct iommu_ops *iommu;

/*
* Set default dma-mask to 32 bit. Drivers are expected to setup
Expand Down Expand Up @@ -194,7 +196,16 @@ static void of_dma_configure(struct device *dev)
dev_dbg(dev, "device is%sdma coherent\n",
coherent ? " " : " not ");

arch_setup_dma_ops(dev, coherent);
iommu = of_iommu_configure(dev);
dev_dbg(dev, "device is%sbehind an iommu\n",
iommu ? " " : " not ");

arch_setup_dma_ops(dev, dma_addr, size, iommu, coherent);
}

static void of_dma_deconfigure(struct device *dev)
{
arch_teardown_dma_ops(dev);
}

/**
Expand Down Expand Up @@ -223,16 +234,12 @@ static struct platform_device *of_platform_device_create_pdata(
if (!dev)
goto err_clear_flag;

of_dma_configure(&dev->dev);
dev->dev.bus = &platform_bus_type;
dev->dev.platform_data = platform_data;

/* We do not fill the DMA ops for platform devices by default.
* This is currently the responsibility of the platform code
* to do such, possibly using a device notifier
*/
of_dma_configure(&dev->dev);

if (of_device_add(dev) != 0) {
of_dma_deconfigure(&dev->dev);
platform_device_put(dev);
goto err_clear_flag;
}
Expand Down
8 changes: 7 additions & 1 deletion include/linux/dma-mapping.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,13 @@ static inline int dma_coerce_mask_and_coherent(struct device *dev, u64 mask)
extern u64 dma_get_required_mask(struct device *dev);

#ifndef arch_setup_dma_ops
static inline void arch_setup_dma_ops(struct device *dev, bool coherent) { }
static inline void arch_setup_dma_ops(struct device *dev, u64 dma_base,
u64 size, struct iommu_ops *iommu,
bool coherent) { }
#endif

#ifndef arch_teardown_dma_ops
static inline void arch_teardown_dma_ops(struct device *dev) { }
#endif

static inline unsigned int dma_get_max_seg_size(struct device *dev)
Expand Down

0 comments on commit 97890ba

Please sign in to comment.