diff options
author | Scott Wood <scottwood@freescale.com> | 2014-08-09 03:40:42 +0400 |
---|---|---|
committer | Scott Wood <scottwood@freescale.com> | 2014-09-04 02:58:21 +0400 |
commit | 1c98025c6c95bc057a25e2c6596de23288c68160 (patch) | |
tree | 37475259871168c9835b78ecd3d233f870945fa1 /arch/powerpc/kernel/dma.c | |
parent | 78eb9094ca08a40b8f9d3e113a2b88e0b7dbad1d (diff) | |
download | linux-1c98025c6c95bc057a25e2c6596de23288c68160.tar.xz |
powerpc: Dynamic DMA zone limits
Platform code can call limit_zone_pfn() to set appropriate limits
for ZONE_DMA and ZONE_DMA32, and dma_direct_alloc_coherent() will
select a suitable zone based on a device's mask and the pfn limits that
platform code has configured.
Signed-off-by: Scott Wood <scottwood@freescale.com>
Cc: Shaohui Xie <Shaohui.Xie@freescale.com>
Diffstat (limited to 'arch/powerpc/kernel/dma.c')
-rw-r--r-- | arch/powerpc/kernel/dma.c | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/arch/powerpc/kernel/dma.c b/arch/powerpc/kernel/dma.c index ee78f6e49d64..dfd99ef8c63d 100644 --- a/arch/powerpc/kernel/dma.c +++ b/arch/powerpc/kernel/dma.c @@ -40,6 +40,26 @@ void *dma_direct_alloc_coherent(struct device *dev, size_t size, #else struct page *page; int node = dev_to_node(dev); + u64 pfn = (dev->coherent_dma_mask >> PAGE_SHIFT) + 1; + int zone; + + zone = dma_pfn_limit_to_zone(pfn); + if (zone < 0) { + dev_err(dev, "%s: No suitable zone for pfn %#llx\n", + __func__, pfn); + return NULL; + } + + switch (zone) { + case ZONE_DMA: + flag |= GFP_DMA; + break; +#ifdef CONFIG_ZONE_DMA32 + case ZONE_DMA32: + flag |= GFP_DMA32; + break; +#endif + }; /* ignore region specifiers */ flag &= ~(__GFP_HIGHMEM); |