diff options
author | Marek Szyprowski <m.szyprowski@samsung.com> | 2011-12-29 07:09:51 -0500 |
---|---|---|
committer | Marek Szyprowski <m.szyprowski@samsung.com> | 2012-05-21 09:09:38 -0400 |
commit | 0a2b9a6ea93650b8a00f9fd5ee8fdd25671e2df6 (patch) | |
tree | c930063ff30882db67e110774bf8b46497d23f15 /arch/x86/kernel/pci-dma.c | |
parent | c64be2bb1c6eb43c838b2c6d57b074078be208dd (diff) |
X86: integrate CMA with DMA-mapping subsystem
This patch adds support for CMA to dma-mapping subsystem for x86
architecture that uses common pci-dma/pci-nommu implementation. This
allows to test CMA on KVM/QEMU and a lot of common x86 boxes.
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
CC: Michal Nazarewicz <mina86@mina86.com>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'arch/x86/kernel/pci-dma.c')
-rw-r--r-- | arch/x86/kernel/pci-dma.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c index 3003250ac51d..62c9457ccd2f 100644 --- a/arch/x86/kernel/pci-dma.c +++ b/arch/x86/kernel/pci-dma.c | |||
@@ -100,14 +100,18 @@ void *dma_generic_alloc_coherent(struct device *dev, size_t size, | |||
100 | struct dma_attrs *attrs) | 100 | struct dma_attrs *attrs) |
101 | { | 101 | { |
102 | unsigned long dma_mask; | 102 | unsigned long dma_mask; |
103 | struct page *page; | 103 | struct page *page = NULL; |
104 | unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT; | ||
104 | dma_addr_t addr; | 105 | dma_addr_t addr; |
105 | 106 | ||
106 | dma_mask = dma_alloc_coherent_mask(dev, flag); | 107 | dma_mask = dma_alloc_coherent_mask(dev, flag); |
107 | 108 | ||
108 | flag |= __GFP_ZERO; | 109 | flag |= __GFP_ZERO; |
109 | again: | 110 | again: |
110 | page = alloc_pages_node(dev_to_node(dev), flag, get_order(size)); | 111 | if (!(flag & GFP_ATOMIC)) |
112 | page = dma_alloc_from_contiguous(dev, count, get_order(size)); | ||
113 | if (!page) | ||
114 | page = alloc_pages_node(dev_to_node(dev), flag, get_order(size)); | ||
111 | if (!page) | 115 | if (!page) |
112 | return NULL; | 116 | return NULL; |
113 | 117 | ||
@@ -127,6 +131,16 @@ again: | |||
127 | return page_address(page); | 131 | return page_address(page); |
128 | } | 132 | } |
129 | 133 | ||
134 | void dma_generic_free_coherent(struct device *dev, size_t size, void *vaddr, | ||
135 | dma_addr_t dma_addr, struct dma_attrs *attrs) | ||
136 | { | ||
137 | unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT; | ||
138 | struct page *page = virt_to_page(vaddr); | ||
139 | |||
140 | if (!dma_release_from_contiguous(dev, page, count)) | ||
141 | free_pages((unsigned long)vaddr, get_order(size)); | ||
142 | } | ||
143 | |||
130 | /* | 144 | /* |
131 | * See <Documentation/x86/x86_64/boot-options.txt> for the iommu kernel | 145 | * See <Documentation/x86/x86_64/boot-options.txt> for the iommu kernel |
132 | * parameter documentation. | 146 | * parameter documentation. |