aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/include/asm/dma-mapping.h8
-rw-r--r--arch/arm/mm/dma-mapping.c51
-rw-r--r--arch/arm/mm/init.c12
-rw-r--r--arch/arm/mm/mm.h2
-rw-r--r--arch/powerpc/kernel/vio.c3
5 files changed, 62 insertions, 14 deletions
diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h
index 5b579b951503..863cd84eb1a2 100644
--- a/arch/arm/include/asm/dma-mapping.h
+++ b/arch/arm/include/asm/dma-mapping.h
@@ -64,6 +64,7 @@ static inline dma_addr_t virt_to_dma(struct device *dev, void *addr)
64{ 64{
65 return (dma_addr_t)__virt_to_bus((unsigned long)(addr)); 65 return (dma_addr_t)__virt_to_bus((unsigned long)(addr));
66} 66}
67
67#else 68#else
68static inline dma_addr_t pfn_to_dma(struct device *dev, unsigned long pfn) 69static inline dma_addr_t pfn_to_dma(struct device *dev, unsigned long pfn)
69{ 70{
@@ -86,6 +87,13 @@ static inline dma_addr_t virt_to_dma(struct device *dev, void *addr)
86} 87}
87#endif 88#endif
88 89
90/* The ARM override for dma_max_pfn() */
91static inline unsigned long dma_max_pfn(struct device *dev)
92{
93 return PHYS_PFN_OFFSET + dma_to_pfn(dev, *dev->dma_mask);
94}
95#define dma_max_pfn(dev) dma_max_pfn(dev)
96
89/* 97/*
90 * DMA errors are defined by all-bits-set in the DMA address. 98 * DMA errors are defined by all-bits-set in the DMA address.
91 */ 99 */
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 1272ed202dde..644d91f73b00 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -159,7 +159,7 @@ EXPORT_SYMBOL(arm_coherent_dma_ops);
159 159
160static u64 get_coherent_dma_mask(struct device *dev) 160static u64 get_coherent_dma_mask(struct device *dev)
161{ 161{
162 u64 mask = (u64)arm_dma_limit; 162 u64 mask = (u64)DMA_BIT_MASK(32);
163 163
164 if (dev) { 164 if (dev) {
165 mask = dev->coherent_dma_mask; 165 mask = dev->coherent_dma_mask;
@@ -173,10 +173,30 @@ static u64 get_coherent_dma_mask(struct device *dev)
173 return 0; 173 return 0;
174 } 174 }
175 175
176 if ((~mask) & (u64)arm_dma_limit) { 176 /*
177 dev_warn(dev, "coherent DMA mask %#llx is smaller " 177 * If the mask allows for more memory than we can address,
178 "than system GFP_DMA mask %#llx\n", 178 * and we actually have that much memory, then fail the
179 mask, (u64)arm_dma_limit); 179 * allocation.
180 */
181 if (sizeof(mask) != sizeof(dma_addr_t) &&
182 mask > (dma_addr_t)~0 &&
183 dma_to_pfn(dev, ~0) > arm_dma_pfn_limit) {
184 dev_warn(dev, "Coherent DMA mask %#llx is larger than dma_addr_t allows\n",
185 mask);
186 dev_warn(dev, "Driver did not use or check the return value from dma_set_coherent_mask()?\n");
187 return 0;
188 }
189
190 /*
191 * Now check that the mask, when translated to a PFN,
192 * fits within the allowable addresses which we can
193 * allocate.
194 */
195 if (dma_to_pfn(dev, mask) < arm_dma_pfn_limit) {
196 dev_warn(dev, "Coherent DMA mask %#llx (pfn %#lx-%#lx) covers a smaller range of system memory than the DMA zone pfn 0x0-%#lx\n",
197 mask,
198 dma_to_pfn(dev, 0), dma_to_pfn(dev, mask) + 1,
199 arm_dma_pfn_limit + 1);
180 return 0; 200 return 0;
181 } 201 }
182 } 202 }
@@ -1007,8 +1027,27 @@ void arm_dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
1007 */ 1027 */
1008int dma_supported(struct device *dev, u64 mask) 1028int dma_supported(struct device *dev, u64 mask)
1009{ 1029{
1010 if (mask < (u64)arm_dma_limit) 1030 unsigned long limit;
1031
1032 /*
1033 * If the mask allows for more memory than we can address,
1034 * and we actually have that much memory, then we must
1035 * indicate that DMA to this device is not supported.
1036 */
1037 if (sizeof(mask) != sizeof(dma_addr_t) &&
1038 mask > (dma_addr_t)~0 &&
1039 dma_to_pfn(dev, ~0) > arm_dma_pfn_limit)
1040 return 0;
1041
1042 /*
1043 * Translate the device's DMA mask to a PFN limit. This
1044 * PFN number includes the page which we can DMA to.
1045 */
1046 limit = dma_to_pfn(dev, mask);
1047
1048 if (limit < arm_dma_pfn_limit)
1011 return 0; 1049 return 0;
1050
1012 return 1; 1051 return 1;
1013} 1052}
1014EXPORT_SYMBOL(dma_supported); 1053EXPORT_SYMBOL(dma_supported);
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index ca907f805c57..3e8f106ee5fe 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -209,6 +209,7 @@ EXPORT_SYMBOL(arm_dma_zone_size);
209 * so a successful GFP_DMA allocation will always satisfy this. 209 * so a successful GFP_DMA allocation will always satisfy this.
210 */ 210 */
211phys_addr_t arm_dma_limit; 211phys_addr_t arm_dma_limit;
212unsigned long arm_dma_pfn_limit;
212 213
213static void __init arm_adjust_dma_zone(unsigned long *size, unsigned long *hole, 214static void __init arm_adjust_dma_zone(unsigned long *size, unsigned long *hole,
214 unsigned long dma_size) 215 unsigned long dma_size)
@@ -231,6 +232,7 @@ void __init setup_dma_zone(const struct machine_desc *mdesc)
231 arm_dma_limit = PHYS_OFFSET + arm_dma_zone_size - 1; 232 arm_dma_limit = PHYS_OFFSET + arm_dma_zone_size - 1;
232 } else 233 } else
233 arm_dma_limit = 0xffffffff; 234 arm_dma_limit = 0xffffffff;
235 arm_dma_pfn_limit = arm_dma_limit >> PAGE_SHIFT;
234#endif 236#endif
235} 237}
236 238
@@ -418,12 +420,10 @@ void __init bootmem_init(void)
418 * This doesn't seem to be used by the Linux memory manager any 420 * This doesn't seem to be used by the Linux memory manager any
419 * more, but is used by ll_rw_block. If we can get rid of it, we 421 * more, but is used by ll_rw_block. If we can get rid of it, we
420 * also get rid of some of the stuff above as well. 422 * also get rid of some of the stuff above as well.
421 *
422 * Note: max_low_pfn and max_pfn reflect the number of _pages_ in
423 * the system, not the maximum PFN.
424 */ 423 */
425 max_low_pfn = max_low - PHYS_PFN_OFFSET; 424 min_low_pfn = min;
426 max_pfn = max_high - PHYS_PFN_OFFSET; 425 max_low_pfn = max_low;
426 max_pfn = max_high;
427} 427}
428 428
429/* 429/*
@@ -529,7 +529,7 @@ static inline void free_area_high(unsigned long pfn, unsigned long end)
529static void __init free_highpages(void) 529static void __init free_highpages(void)
530{ 530{
531#ifdef CONFIG_HIGHMEM 531#ifdef CONFIG_HIGHMEM
532 unsigned long max_low = max_low_pfn + PHYS_PFN_OFFSET; 532 unsigned long max_low = max_low_pfn;
533 struct memblock_region *mem, *res; 533 struct memblock_region *mem, *res;
534 534
535 /* set highmem page free */ 535 /* set highmem page free */
diff --git a/arch/arm/mm/mm.h b/arch/arm/mm/mm.h
index d5a4e9ad8f0f..d5a982d15a88 100644
--- a/arch/arm/mm/mm.h
+++ b/arch/arm/mm/mm.h
@@ -81,8 +81,10 @@ extern __init void add_static_vm_early(struct static_vm *svm);
81 81
82#ifdef CONFIG_ZONE_DMA 82#ifdef CONFIG_ZONE_DMA
83extern phys_addr_t arm_dma_limit; 83extern phys_addr_t arm_dma_limit;
84extern unsigned long arm_dma_pfn_limit;
84#else 85#else
85#define arm_dma_limit ((phys_addr_t)~0) 86#define arm_dma_limit ((phys_addr_t)~0)
87#define arm_dma_pfn_limit (~0ul >> PAGE_SHIFT)
86#endif 88#endif
87 89
88extern phys_addr_t arm_lowmem_limit; 90extern phys_addr_t arm_lowmem_limit;
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
index f99cefbd84e3..e7d0c88f621a 100644
--- a/arch/powerpc/kernel/vio.c
+++ b/arch/powerpc/kernel/vio.c
@@ -1419,8 +1419,7 @@ struct vio_dev *vio_register_device_node(struct device_node *of_node)
1419 1419
1420 /* needed to ensure proper operation of coherent allocations 1420 /* needed to ensure proper operation of coherent allocations
1421 * later, in case driver doesn't set it explicitly */ 1421 * later, in case driver doesn't set it explicitly */
1422 dma_set_mask(&viodev->dev, DMA_BIT_MASK(64)); 1422 dma_set_mask_and_coherent(&viodev->dev, DMA_BIT_MASK(64));
1423 dma_set_coherent_mask(&viodev->dev, DMA_BIT_MASK(64));
1424 } 1423 }
1425 1424
1426 /* register with generic device framework */ 1425 /* register with generic device framework */