Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 358820
b: refs/heads/master
c: 9848e48
h: refs/heads/master
v: v3
  • Loading branch information
Marek Szyprowski committed Feb 25, 2013
1 parent 1bf1536 commit e71c5b6
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 16 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 18177d12c0cee5646c7c2045ea90ddf882011c97
refs/heads/master: 9848e48f4c316ccb64d6f29ff0ed85f11d7bf532
57 changes: 42 additions & 15 deletions trunk/arch/arm/mm/dma-mapping.c
Original file line number Diff line number Diff line change
Expand Up @@ -186,13 +186,24 @@ static u64 get_coherent_dma_mask(struct device *dev)

static void __dma_clear_buffer(struct page *page, size_t size)
{
void *ptr;
/*
* Ensure that the allocated pages are zeroed, and that any data
* lurking in the kernel direct-mapped region is invalidated.
*/
ptr = page_address(page);
if (ptr) {
if (PageHighMem(page)) {
phys_addr_t base = __pfn_to_phys(page_to_pfn(page));
phys_addr_t end = base + size;
while (size > 0) {
void *ptr = kmap_atomic(page);
memset(ptr, 0, PAGE_SIZE);
dmac_flush_range(ptr, ptr + PAGE_SIZE);
kunmap_atomic(ptr);
page++;
size -= PAGE_SIZE;
}
outer_flush_range(base, end);
} else {
void *ptr = page_address(page);
memset(ptr, 0, size);
dmac_flush_range(ptr, ptr + size);
outer_flush_range(__pa(ptr), __pa(ptr) + size);
Expand Down Expand Up @@ -243,7 +254,8 @@ static void __dma_free_buffer(struct page *page, size_t size)
#endif

static void *__alloc_from_contiguous(struct device *dev, size_t size,
pgprot_t prot, struct page **ret_page);
pgprot_t prot, struct page **ret_page,
const void *caller);

static void *__alloc_remap_buffer(struct device *dev, size_t size, gfp_t gfp,
pgprot_t prot, struct page **ret_page,
Expand Down Expand Up @@ -346,10 +358,11 @@ static int __init atomic_pool_init(void)
goto no_pages;

if (IS_ENABLED(CONFIG_CMA))
ptr = __alloc_from_contiguous(NULL, pool->size, prot, &page);
ptr = __alloc_from_contiguous(NULL, pool->size, prot, &page,
atomic_pool_init);
else
ptr = __alloc_remap_buffer(NULL, pool->size, GFP_KERNEL, prot,
&page, NULL);
&page, atomic_pool_init);
if (ptr) {
int i;

Expand Down Expand Up @@ -542,27 +555,41 @@ static int __free_from_pool(void *start, size_t size)
}

static void *__alloc_from_contiguous(struct device *dev, size_t size,
pgprot_t prot, struct page **ret_page)
pgprot_t prot, struct page **ret_page,
const void *caller)
{
unsigned long order = get_order(size);
size_t count = size >> PAGE_SHIFT;
struct page *page;
void *ptr;

page = dma_alloc_from_contiguous(dev, count, order);
if (!page)
return NULL;

__dma_clear_buffer(page, size);
__dma_remap(page, size, prot);

if (PageHighMem(page)) {
ptr = __dma_alloc_remap(page, size, GFP_KERNEL, prot, caller);
if (!ptr) {
dma_release_from_contiguous(dev, page, count);
return NULL;
}
} else {
__dma_remap(page, size, prot);
ptr = page_address(page);
}
*ret_page = page;
return page_address(page);
return ptr;
}

static void __free_from_contiguous(struct device *dev, struct page *page,
size_t size)
void *cpu_addr, size_t size)
{
__dma_remap(page, size, pgprot_kernel);
if (PageHighMem(page))
__dma_free_remap(cpu_addr, size);
else
__dma_remap(page, size, pgprot_kernel);
dma_release_from_contiguous(dev, page, size >> PAGE_SHIFT);
}

Expand All @@ -583,9 +610,9 @@ static inline pgprot_t __get_dma_pgprot(struct dma_attrs *attrs, pgprot_t prot)
#define __get_dma_pgprot(attrs, prot) __pgprot(0)
#define __alloc_remap_buffer(dev, size, gfp, prot, ret, c) NULL
#define __alloc_from_pool(size, ret_page) NULL
#define __alloc_from_contiguous(dev, size, prot, ret) NULL
#define __alloc_from_contiguous(dev, size, prot, ret, c) NULL
#define __free_from_pool(cpu_addr, size) 0
#define __free_from_contiguous(dev, page, size) do { } while (0)
#define __free_from_contiguous(dev, page, cpu_addr, size) do { } while (0)
#define __dma_free_remap(cpu_addr, size) do { } while (0)

#endif /* CONFIG_MMU */
Expand Down Expand Up @@ -645,7 +672,7 @@ static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
else if (!IS_ENABLED(CONFIG_CMA))
addr = __alloc_remap_buffer(dev, size, gfp, prot, &page, caller);
else
addr = __alloc_from_contiguous(dev, size, prot, &page);
addr = __alloc_from_contiguous(dev, size, prot, &page, caller);

if (addr)
*handle = pfn_to_dma(dev, page_to_pfn(page));
Expand Down Expand Up @@ -739,7 +766,7 @@ static void __arm_dma_free(struct device *dev, size_t size, void *cpu_addr,
* Non-atomic allocations cannot be freed with IRQs disabled
*/
WARN_ON(irqs_disabled());
__free_from_contiguous(dev, page, size);
__free_from_contiguous(dev, page, cpu_addr, size);
}
}

Expand Down

0 comments on commit e71c5b6

Please sign in to comment.