diff options
author | Grygorii Strashko <grygorii.strashko@ti.com> | 2014-04-24 11:30:05 -0400 |
---|---|---|
committer | Santosh Shilimkar <santosh.shilimkar@ti.com> | 2014-05-07 09:21:43 -0400 |
commit | 6ce0d20016925d031f1e24d64302e4c976d7cec6 (patch) | |
tree | 2f02186f806c757e7e85f7a31d0210e5f4ef498a /arch/arm/include/asm | |
parent | 591c1ee465ce5372385dbc41e7d3e36cbb477bd8 (diff) | |
download | linux-stable-6ce0d20016925d031f1e24d64302e4c976d7cec6.tar.gz linux-stable-6ce0d20016925d031f1e24d64302e4c976d7cec6.tar.bz2 linux-stable-6ce0d20016925d031f1e24d64302e4c976d7cec6.zip |
ARM: dma: Use dma_pfn_offset for dma address translation
In most of cases DMA addresses can be performed using offset value of
Bus address space relatively to physical address space as following:
PFN->DMA:
__pfn_to_phys(pfn + [-]dma_pfn_offset)
DMA->PFN:
__phys_to_pfn(dma_addr) + [-]dma_pfn_offset
Thanks to Russell King for suggesting the optimised macro's for
conversion.
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Russell King <linux@arm.linux.org.uk>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Olof Johansson <olof@lixom.net>
Cc: Grant Likely <grant.likely@linaro.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Linus Walleij <linus.walleij@linaro.org>
Reviewed-by: Rob Herring <robh@kernel.org>
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Diffstat (limited to 'arch/arm/include/asm')
-rw-r--r-- | arch/arm/include/asm/dma-mapping.h | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h index e701a4d9aa59..b0c79fdd9375 100644 --- a/arch/arm/include/asm/dma-mapping.h +++ b/arch/arm/include/asm/dma-mapping.h @@ -58,21 +58,37 @@ static inline int dma_set_mask(struct device *dev, u64 mask) #ifndef __arch_pfn_to_dma static inline dma_addr_t pfn_to_dma(struct device *dev, unsigned long pfn) { + if (dev) + pfn -= dev->dma_pfn_offset; return (dma_addr_t)__pfn_to_bus(pfn); } static inline unsigned long dma_to_pfn(struct device *dev, dma_addr_t addr) { - return __bus_to_pfn(addr); + unsigned long pfn = __bus_to_pfn(addr); + + if (dev) + pfn += dev->dma_pfn_offset; + + return pfn; } static inline void *dma_to_virt(struct device *dev, dma_addr_t addr) { + if (dev) { + unsigned long pfn = dma_to_pfn(dev, addr); + + return phys_to_virt(__pfn_to_phys(pfn)); + } + return (void *)__bus_to_virt((unsigned long)addr); } static inline dma_addr_t virt_to_dma(struct device *dev, void *addr) { + if (dev) + return pfn_to_dma(dev, virt_to_pfn(addr)); + return (dma_addr_t)__virt_to_bus((unsigned long)(addr)); } |