diff options
author | Stefano Stabellini <stefano.stabellini@eu.citrix.com> | 2013-10-15 17:47:14 +0200 |
---|---|---|
committer | Stefano Stabellini <stefano.stabellini@eu.citrix.com> | 2013-10-15 17:47:14 +0200 |
commit | 06e6295bcecefea9dc29fc84b5fd6848061365a0 (patch) | |
tree | ed978998c49f5bade8571675968a939dc830dd42 /arch/arm/include | |
parent | Linux 3.12-rc5 (diff) | |
download | linux-06e6295bcecefea9dc29fc84b5fd6848061365a0.tar.xz linux-06e6295bcecefea9dc29fc84b5fd6848061365a0.zip |
arm: make SWIOTLB available
IOMMU_HELPER is needed because SWIOTLB calls iommu_is_span_boundary,
provided by lib/iommu_helper.c.
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
CC: will.deacon@arm.com
CC: linux@arm.linux.org.uk
Changes in v8:
- use __phys_to_pfn and __pfn_to_phys.
Changes in v7:
- dma_mark_clean: empty implementation;
- in dma_capable use coherent_dma_mask if dma_mask hasn't been
allocated.
Changes in v6:
- check for dev->dma_mask being NULL in dma_capable.
Changes in v5:
- implement dma_mark_clean using dmac_flush_range.
Changes in v3:
- dma_capable: do not treat dma_mask as a limit;
- remove SWIOTLB dependency on NEED_SG_DMA_LENGTH.
Diffstat (limited to 'arch/arm/include')
-rw-r--r-- | arch/arm/include/asm/dma-mapping.h | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h index 5b579b951503..01b5a3d92197 100644 --- a/arch/arm/include/asm/dma-mapping.h +++ b/arch/arm/include/asm/dma-mapping.h @@ -10,6 +10,7 @@ #include <asm-generic/dma-coherent.h> #include <asm/memory.h> +#include <asm/cacheflush.h> #define DMA_ERROR_CODE (~0) extern struct dma_map_ops arm_dma_ops; @@ -86,6 +87,42 @@ static inline dma_addr_t virt_to_dma(struct device *dev, void *addr) } #endif +static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr) +{ + unsigned int offset = paddr & ~PAGE_MASK; + return pfn_to_dma(dev, __phys_to_pfn(paddr)) + offset; +} + +static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t dev_addr) +{ + unsigned int offset = dev_addr & ~PAGE_MASK; + return __pfn_to_phys(dma_to_pfn(dev, dev_addr)) + offset; +} + +static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size) +{ + u64 limit, mask; + + if (dev->dma_mask) + mask = *dev->dma_mask; + else + mask = dev->coherent_dma_mask; + + if (mask == 0) + return 0; + + limit = (mask + 1) & ~mask; + if (limit && size > limit) + return 0; + + if ((addr | (addr + size - 1)) & ~mask) + return 0; + + return 1; +} + +static inline void dma_mark_clean(void *addr, size_t size) { } + /* * DMA errors are defined by all-bits-set in the DMA address. */ |