aboutsummaryrefslogtreecommitdiffstats
path: root/arch/hexagon/kernel
diff options
context:
space:
mode:
authorRichard Kuo <rkuo@codeaurora.org>2013-04-08 19:30:12 -0400
committerRichard Kuo <rkuo@codeaurora.org>2013-04-30 20:40:28 -0400
commit5e1150542fd1d75fe2b6c3491415c860cdc06be2 (patch)
tree04b129c2eb46c1d370c7647eb307465bffec45dd /arch/hexagon/kernel
parentc710f5908768e18d8e8081e917fda362089cb13f (diff)
Hexagon: use correct translations for DMA mappings
With physical offsets, pa<->va translations aren't just based on PAGE_OFFSET anymore. Signed-off-by: Richard Kuo <rkuo@codeaurora.org>
Diffstat (limited to 'arch/hexagon/kernel')
-rw-r--r--arch/hexagon/kernel/dma.c27
1 files changed, 17 insertions, 10 deletions
diff --git a/arch/hexagon/kernel/dma.c b/arch/hexagon/kernel/dma.c
index 65c7bdcf565e..b74f9bae31a3 100644
--- a/arch/hexagon/kernel/dma.c
+++ b/arch/hexagon/kernel/dma.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * DMA implementation for Hexagon 2 * DMA implementation for Hexagon
3 * 3 *
4 * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. 4 * Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 and 7 * it under the terms of the GNU General Public License version 2 and
@@ -23,12 +23,18 @@
23#include <linux/genalloc.h> 23#include <linux/genalloc.h>
24#include <asm/dma-mapping.h> 24#include <asm/dma-mapping.h>
25#include <linux/module.h> 25#include <linux/module.h>
26#include <asm/page.h>
26 27
27struct dma_map_ops *dma_ops; 28struct dma_map_ops *dma_ops;
28EXPORT_SYMBOL(dma_ops); 29EXPORT_SYMBOL(dma_ops);
29 30
30int bad_dma_address; /* globals are automatically initialized to zero */ 31int bad_dma_address; /* globals are automatically initialized to zero */
31 32
33static inline void *dma_addr_to_virt(dma_addr_t dma_addr)
34{
35 return phys_to_virt((unsigned long) dma_addr);
36}
37
32int dma_supported(struct device *dev, u64 mask) 38int dma_supported(struct device *dev, u64 mask)
33{ 39{
34 if (mask == DMA_BIT_MASK(32)) 40 if (mask == DMA_BIT_MASK(32))
@@ -60,6 +66,12 @@ static void *hexagon_dma_alloc_coherent(struct device *dev, size_t size,
60{ 66{
61 void *ret; 67 void *ret;
62 68
69 /*
70 * Our max_low_pfn should have been backed off by 16MB in
71 * mm/init.c to create DMA coherent space. Use that as the VA
72 * for the pool.
73 */
74
63 if (coherent_pool == NULL) { 75 if (coherent_pool == NULL) {
64 coherent_pool = gen_pool_create(PAGE_SHIFT, -1); 76 coherent_pool = gen_pool_create(PAGE_SHIFT, -1);
65 77
@@ -67,7 +79,7 @@ static void *hexagon_dma_alloc_coherent(struct device *dev, size_t size,
67 panic("Can't create %s() memory pool!", __func__); 79 panic("Can't create %s() memory pool!", __func__);
68 else 80 else
69 gen_pool_add(coherent_pool, 81 gen_pool_add(coherent_pool,
70 (PAGE_OFFSET + (max_low_pfn << PAGE_SHIFT)), 82 pfn_to_virt(max_low_pfn),
71 hexagon_coherent_pool_size, -1); 83 hexagon_coherent_pool_size, -1);
72 } 84 }
73 85
@@ -75,7 +87,7 @@ static void *hexagon_dma_alloc_coherent(struct device *dev, size_t size,
75 87
76 if (ret) { 88 if (ret) {
77 memset(ret, 0, size); 89 memset(ret, 0, size);
78 *dma_addr = (dma_addr_t) (ret - PAGE_OFFSET); 90 *dma_addr = (dma_addr_t) virt_to_phys(ret);
79 } else 91 } else
80 *dma_addr = ~0; 92 *dma_addr = ~0;
81 93
@@ -118,8 +130,8 @@ static int hexagon_map_sg(struct device *hwdev, struct scatterlist *sg,
118 130
119 s->dma_length = s->length; 131 s->dma_length = s->length;
120 132
121 flush_dcache_range(PAGE_OFFSET + s->dma_address, 133 flush_dcache_range(dma_addr_to_virt(s->dma_address),
122 PAGE_OFFSET + s->dma_address + s->length); 134 dma_addr_to_virt(s->dma_address + s->length));
123 } 135 }
124 136
125 return nents; 137 return nents;
@@ -149,11 +161,6 @@ static inline void dma_sync(void *addr, size_t size,
149 } 161 }
150} 162}
151 163
152static inline void *dma_addr_to_virt(dma_addr_t dma_addr)
153{
154 return phys_to_virt((unsigned long) dma_addr);
155}
156
157/** 164/**
158 * hexagon_map_page() - maps an address for device DMA 165 * hexagon_map_page() - maps an address for device DMA
159 * @dev: pointer to DMA device 166 * @dev: pointer to DMA device