|
@@ -183,6 +183,8 @@ static void *
|
|
|
__dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot)
|
|
|
{
|
|
|
struct arm_vmregion *c;
|
|
|
+ size_t align;
|
|
|
+ int bit;
|
|
|
|
|
|
if (!consistent_pte[0]) {
|
|
|
printk(KERN_ERR "%s: not initialised\n", __func__);
|
|
@@ -190,10 +192,21 @@ __dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot)
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
+ /*
|
|
|
+ * Align the virtual region allocation - maximum alignment is
|
|
|
+ * a section size, minimum is a page size. This helps reduce
|
|
|
+ * fragmentation of the DMA space, and also prevents allocations
|
|
|
+ * smaller than a section from crossing a section boundary.
|
|
|
+ */
|
|
|
+ bit = fls(size - 1) + 1;
|
|
|
+ if (bit > SECTION_SHIFT)
|
|
|
+ bit = SECTION_SHIFT;
|
|
|
+ align = 1 << bit;
|
|
|
+
|
|
|
/*
|
|
|
* Allocate a virtual address in the consistent mapping region.
|
|
|
*/
|
|
|
- c = arm_vmregion_alloc(&consistent_head, size,
|
|
|
+ c = arm_vmregion_alloc(&consistent_head, align, size,
|
|
|
gfp & ~(__GFP_DMA | __GFP_HIGHMEM));
|
|
|
if (c) {
|
|
|
pte_t *pte;
|