aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/kernel/dma_64.c11
-rw-r--r--include/asm-powerpc/dma-mapping.h2
2 files changed, 10 insertions, 3 deletions
diff --git a/arch/powerpc/kernel/dma_64.c b/arch/powerpc/kernel/dma_64.c
index 4e6551199782..1d1dc76606ac 100644
--- a/arch/powerpc/kernel/dma_64.c
+++ b/arch/powerpc/kernel/dma_64.c
@@ -111,7 +111,11 @@ EXPORT_SYMBOL(dma_iommu_ops);
111 111
112/* 112/*
113 * Generic direct DMA implementation 113 * Generic direct DMA implementation
114 *
115 * This implementation supports a global offset that can be applied if
116 * the address at which memory is visible to devices is not 0.
114 */ 117 */
118unsigned long dma_direct_offset;
115 119
116static void *dma_direct_alloc_coherent(struct device *dev, size_t size, 120static void *dma_direct_alloc_coherent(struct device *dev, size_t size,
117 dma_addr_t *dma_handle, gfp_t flag) 121 dma_addr_t *dma_handle, gfp_t flag)
@@ -122,7 +126,7 @@ static void *dma_direct_alloc_coherent(struct device *dev, size_t size,
122 ret = (void *)__get_free_pages(flag, get_order(size)); 126 ret = (void *)__get_free_pages(flag, get_order(size));
123 if (ret != NULL) { 127 if (ret != NULL) {
124 memset(ret, 0, size); 128 memset(ret, 0, size);
125 *dma_handle = virt_to_abs(ret); 129 *dma_handle = virt_to_abs(ret) | dma_direct_offset;
126 } 130 }
127 return ret; 131 return ret;
128} 132}
@@ -137,7 +141,7 @@ static dma_addr_t dma_direct_map_single(struct device *dev, void *ptr,
137 size_t size, 141 size_t size,
138 enum dma_data_direction direction) 142 enum dma_data_direction direction)
139{ 143{
140 return virt_to_abs(ptr); 144 return virt_to_abs(ptr) | dma_direct_offset;
141} 145}
142 146
143static void dma_direct_unmap_single(struct device *dev, dma_addr_t dma_addr, 147static void dma_direct_unmap_single(struct device *dev, dma_addr_t dma_addr,
@@ -152,7 +156,8 @@ static int dma_direct_map_sg(struct device *dev, struct scatterlist *sg,
152 int i; 156 int i;
153 157
154 for (i = 0; i < nents; i++, sg++) { 158 for (i = 0; i < nents; i++, sg++) {
155 sg->dma_address = page_to_phys(sg->page) + sg->offset; 159 sg->dma_address = (page_to_phys(sg->page) + sg->offset) |
160 dma_direct_offset;
156 sg->dma_length = sg->length; 161 sg->dma_length = sg->length;
157 } 162 }
158 163
diff --git a/include/asm-powerpc/dma-mapping.h b/include/asm-powerpc/dma-mapping.h
index 8367810c994c..7e38b5fddada 100644
--- a/include/asm-powerpc/dma-mapping.h
+++ b/include/asm-powerpc/dma-mapping.h
@@ -187,6 +187,8 @@ static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
187extern struct dma_mapping_ops dma_iommu_ops; 187extern struct dma_mapping_ops dma_iommu_ops;
188extern struct dma_mapping_ops dma_direct_ops; 188extern struct dma_mapping_ops dma_direct_ops;
189 189
190extern unsigned long dma_direct_offset;
191
190#else /* CONFIG_PPC64 */ 192#else /* CONFIG_PPC64 */
191 193
192#define dma_supported(dev, mask) (1) 194#define dma_supported(dev, mask) (1)