aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mm/dma-mapping.c15
-rw-r--r--arch/arm/mm/vmregion.c5
-rw-r--r--arch/arm/mm/vmregion.h2
3 files changed, 18 insertions, 4 deletions
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 9e7742f0a102..c704eed63c5d 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -183,6 +183,8 @@ static void *
183__dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot) 183__dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot)
184{ 184{
185 struct arm_vmregion *c; 185 struct arm_vmregion *c;
186 size_t align;
187 int bit;
186 188
187 if (!consistent_pte[0]) { 189 if (!consistent_pte[0]) {
188 printk(KERN_ERR "%s: not initialised\n", __func__); 190 printk(KERN_ERR "%s: not initialised\n", __func__);
@@ -191,9 +193,20 @@ __dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot)
191 } 193 }
192 194
193 /* 195 /*
196 * Align the virtual region allocation - maximum alignment is
197 * a section size, minimum is a page size. This helps reduce
198 * fragmentation of the DMA space, and also prevents allocations
199 * smaller than a section from crossing a section boundary.
200 */
201 bit = fls(size - 1) + 1;
202 if (bit > SECTION_SHIFT)
203 bit = SECTION_SHIFT;
204 align = 1 << bit;
205
206 /*
194 * Allocate a virtual address in the consistent mapping region. 207 * Allocate a virtual address in the consistent mapping region.
195 */ 208 */
196 c = arm_vmregion_alloc(&consistent_head, size, 209 c = arm_vmregion_alloc(&consistent_head, align, size,
197 gfp & ~(__GFP_DMA | __GFP_HIGHMEM)); 210 gfp & ~(__GFP_DMA | __GFP_HIGHMEM));
198 if (c) { 211 if (c) {
199 pte_t *pte; 212 pte_t *pte;
diff --git a/arch/arm/mm/vmregion.c b/arch/arm/mm/vmregion.c
index 19e09bdb1b8a..935993e1b1ef 100644
--- a/arch/arm/mm/vmregion.c
+++ b/arch/arm/mm/vmregion.c
@@ -35,7 +35,8 @@
35 */ 35 */
36 36
37struct arm_vmregion * 37struct arm_vmregion *
38arm_vmregion_alloc(struct arm_vmregion_head *head, size_t size, gfp_t gfp) 38arm_vmregion_alloc(struct arm_vmregion_head *head, size_t align,
39 size_t size, gfp_t gfp)
39{ 40{
40 unsigned long addr = head->vm_start, end = head->vm_end - size; 41 unsigned long addr = head->vm_start, end = head->vm_end - size;
41 unsigned long flags; 42 unsigned long flags;
@@ -58,7 +59,7 @@ arm_vmregion_alloc(struct arm_vmregion_head *head, size_t size, gfp_t gfp)
58 goto nospc; 59 goto nospc;
59 if ((addr + size) <= c->vm_start) 60 if ((addr + size) <= c->vm_start)
60 goto found; 61 goto found;
61 addr = c->vm_end; 62 addr = ALIGN(c->vm_end, align);
62 if (addr > end) 63 if (addr > end)
63 goto nospc; 64 goto nospc;
64 } 65 }
diff --git a/arch/arm/mm/vmregion.h b/arch/arm/mm/vmregion.h
index 6b2cdbdf3a85..15e9f044db9f 100644
--- a/arch/arm/mm/vmregion.h
+++ b/arch/arm/mm/vmregion.h
@@ -21,7 +21,7 @@ struct arm_vmregion {
21 int vm_active; 21 int vm_active;
22}; 22};
23 23
24struct arm_vmregion *arm_vmregion_alloc(struct arm_vmregion_head *, size_t, gfp_t); 24struct arm_vmregion *arm_vmregion_alloc(struct arm_vmregion_head *, size_t, size_t, gfp_t);
25struct arm_vmregion *arm_vmregion_find(struct arm_vmregion_head *, unsigned long); 25struct arm_vmregion *arm_vmregion_find(struct arm_vmregion_head *, unsigned long);
26struct arm_vmregion *arm_vmregion_find_remove(struct arm_vmregion_head *, unsigned long); 26struct arm_vmregion *arm_vmregion_find_remove(struct arm_vmregion_head *, unsigned long);
27void arm_vmregion_free(struct arm_vmregion_head *, struct arm_vmregion *); 27void arm_vmregion_free(struct arm_vmregion_head *, struct arm_vmregion *);