Loading arch/arm/mm/dma-mapping.c +41 −8 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ * * DMA uncached mapping support. */ #include <linux/bootmem.h> #include <linux/module.h> #include <linux/mm.h> #include <linux/gfp.h> Loading Loading @@ -157,6 +158,44 @@ struct dma_map_ops arm_coherent_dma_ops = { }; EXPORT_SYMBOL(arm_coherent_dma_ops); static int __dma_supported(struct device *dev, u64 mask, bool warn) { unsigned long max_dma_pfn; /* * If the mask allows for more memory than we can address, * and we actually have that much memory, then we must * indicate that DMA to this device is not supported. */ if (sizeof(mask) != sizeof(dma_addr_t) && mask > (dma_addr_t)~0 && dma_to_pfn(dev, ~0) < max_pfn) { if (warn) { dev_warn(dev, "Coherent DMA mask %#llx is larger than dma_addr_t allows\n", mask); dev_warn(dev, "Driver did not use or check the return value from dma_set_coherent_mask()?\n"); } return 0; } max_dma_pfn = min(max_pfn, arm_dma_pfn_limit); /* * Translate the device's DMA mask to a PFN limit. This * PFN number includes the page which we can DMA to. */ if (dma_to_pfn(dev, mask) < max_dma_pfn) { if (warn) 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", mask, dma_to_pfn(dev, 0), dma_to_pfn(dev, mask) + 1, max_dma_pfn + 1); return 0; } return 1; } static u64 get_coherent_dma_mask(struct device *dev) { u64 mask = (u64)arm_dma_limit; Loading @@ -173,13 +212,9 @@ static u64 get_coherent_dma_mask(struct device *dev) return 0; } if ((~mask) & (u64)arm_dma_limit) { dev_warn(dev, "coherent DMA mask %#llx is smaller " "than system GFP_DMA mask %#llx\n", mask, (u64)arm_dma_limit); if (!__dma_supported(dev, mask, true)) return 0; } } return mask; } Loading Loading @@ -1037,9 +1072,7 @@ void arm_dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, */ int dma_supported(struct device *dev, u64 mask) { if (mask < (u64)arm_dma_limit) return 0; return 1; return __dma_supported(dev, mask, false); } EXPORT_SYMBOL(dma_supported); Loading arch/arm/mm/mm.h +2 −0 Original line number Diff line number Diff line Loading @@ -81,8 +81,10 @@ extern __init void add_static_vm_early(struct static_vm *svm); #ifdef CONFIG_ZONE_DMA extern phys_addr_t arm_dma_limit; extern unsigned long arm_dma_pfn_limit; #else #define arm_dma_limit ((phys_addr_t)~0) #define arm_dma_pfn_limit (~0ul >> PAGE_SHIFT) #endif extern phys_addr_t arm_lowmem_limit; Loading Loading
arch/arm/mm/dma-mapping.c +41 −8 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ * * DMA uncached mapping support. */ #include <linux/bootmem.h> #include <linux/module.h> #include <linux/mm.h> #include <linux/gfp.h> Loading Loading @@ -157,6 +158,44 @@ struct dma_map_ops arm_coherent_dma_ops = { }; EXPORT_SYMBOL(arm_coherent_dma_ops); static int __dma_supported(struct device *dev, u64 mask, bool warn) { unsigned long max_dma_pfn; /* * If the mask allows for more memory than we can address, * and we actually have that much memory, then we must * indicate that DMA to this device is not supported. */ if (sizeof(mask) != sizeof(dma_addr_t) && mask > (dma_addr_t)~0 && dma_to_pfn(dev, ~0) < max_pfn) { if (warn) { dev_warn(dev, "Coherent DMA mask %#llx is larger than dma_addr_t allows\n", mask); dev_warn(dev, "Driver did not use or check the return value from dma_set_coherent_mask()?\n"); } return 0; } max_dma_pfn = min(max_pfn, arm_dma_pfn_limit); /* * Translate the device's DMA mask to a PFN limit. This * PFN number includes the page which we can DMA to. */ if (dma_to_pfn(dev, mask) < max_dma_pfn) { if (warn) 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", mask, dma_to_pfn(dev, 0), dma_to_pfn(dev, mask) + 1, max_dma_pfn + 1); return 0; } return 1; } static u64 get_coherent_dma_mask(struct device *dev) { u64 mask = (u64)arm_dma_limit; Loading @@ -173,13 +212,9 @@ static u64 get_coherent_dma_mask(struct device *dev) return 0; } if ((~mask) & (u64)arm_dma_limit) { dev_warn(dev, "coherent DMA mask %#llx is smaller " "than system GFP_DMA mask %#llx\n", mask, (u64)arm_dma_limit); if (!__dma_supported(dev, mask, true)) return 0; } } return mask; } Loading Loading @@ -1037,9 +1072,7 @@ void arm_dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, */ int dma_supported(struct device *dev, u64 mask) { if (mask < (u64)arm_dma_limit) return 0; return 1; return __dma_supported(dev, mask, false); } EXPORT_SYMBOL(dma_supported); Loading
arch/arm/mm/mm.h +2 −0 Original line number Diff line number Diff line Loading @@ -81,8 +81,10 @@ extern __init void add_static_vm_early(struct static_vm *svm); #ifdef CONFIG_ZONE_DMA extern phys_addr_t arm_dma_limit; extern unsigned long arm_dma_pfn_limit; #else #define arm_dma_limit ((phys_addr_t)~0) #define arm_dma_pfn_limit (~0ul >> PAGE_SHIFT) #endif extern phys_addr_t arm_lowmem_limit; Loading