summaryrefslogtreecommitdiff
path: root/arch/powerpc/kernel/dma.c
diff options
context:
space:
mode:
authorScott Wood <scottwood@freescale.com>2014-08-09 03:40:42 +0400
committerScott Wood <scottwood@freescale.com>2014-09-04 02:58:21 +0400
commit1c98025c6c95bc057a25e2c6596de23288c68160 (patch)
tree37475259871168c9835b78ecd3d233f870945fa1 /arch/powerpc/kernel/dma.c
parent78eb9094ca08a40b8f9d3e113a2b88e0b7dbad1d (diff)
downloadlinux-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.c20
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);