diff options
Diffstat (limited to 'arch/arm/mm')
-rw-r--r-- | arch/arm/mm/consistent.c | 17 | ||||
-rw-r--r-- | arch/arm/mm/mm-armv.c | 11 | ||||
-rw-r--r-- | arch/arm/mm/proc-xsc3.S | 2 |
3 files changed, 29 insertions, 1 deletions
diff --git a/arch/arm/mm/consistent.c b/arch/arm/mm/consistent.c index 8a1bfcd50087..50e6b6bfb2e2 100644 --- a/arch/arm/mm/consistent.c +++ b/arch/arm/mm/consistent.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/device.h> | 18 | #include <linux/device.h> |
19 | #include <linux/dma-mapping.h> | 19 | #include <linux/dma-mapping.h> |
20 | 20 | ||
21 | #include <asm/memory.h> | ||
21 | #include <asm/cacheflush.h> | 22 | #include <asm/cacheflush.h> |
22 | #include <asm/tlbflush.h> | 23 | #include <asm/tlbflush.h> |
23 | #include <asm/sizes.h> | 24 | #include <asm/sizes.h> |
@@ -272,6 +273,17 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp, | |||
272 | void * | 273 | void * |
273 | dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp) | 274 | dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp) |
274 | { | 275 | { |
276 | if (arch_is_coherent()) { | ||
277 | void *virt; | ||
278 | |||
279 | virt = kmalloc(size, gfp); | ||
280 | if (!virt) | ||
281 | return NULL; | ||
282 | *handle = virt_to_dma(dev, virt); | ||
283 | |||
284 | return virt; | ||
285 | } | ||
286 | |||
275 | return __dma_alloc(dev, size, handle, gfp, | 287 | return __dma_alloc(dev, size, handle, gfp, |
276 | pgprot_noncached(pgprot_kernel)); | 288 | pgprot_noncached(pgprot_kernel)); |
277 | } | 289 | } |
@@ -350,6 +362,11 @@ void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr | |||
350 | 362 | ||
351 | WARN_ON(irqs_disabled()); | 363 | WARN_ON(irqs_disabled()); |
352 | 364 | ||
365 | if (arch_is_coherent()) { | ||
366 | kfree(cpu_addr); | ||
367 | return; | ||
368 | } | ||
369 | |||
353 | size = PAGE_ALIGN(size); | 370 | size = PAGE_ALIGN(size); |
354 | 371 | ||
355 | spin_lock_irqsave(&consistent_lock, flags); | 372 | spin_lock_irqsave(&consistent_lock, flags); |
diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c index 5e5d05bcad50..f14b2d0f3690 100644 --- a/arch/arm/mm/mm-armv.c +++ b/arch/arm/mm/mm-armv.c | |||
@@ -389,6 +389,17 @@ void __init build_mem_type_table(void) | |||
389 | kern_pgprot = user_pgprot = cp->pte; | 389 | kern_pgprot = user_pgprot = cp->pte; |
390 | 390 | ||
391 | /* | 391 | /* |
392 | * Enable CPU-specific coherency if supported. | ||
393 | * (Only available on XSC3 at the moment.) | ||
394 | */ | ||
395 | if (arch_is_coherent()) { | ||
396 | if (cpu_is_xsc3()) { | ||
397 | mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S; | ||
398 | mem_types[MT_MEMORY].prot_pte |= L_PTE_COHERENT; | ||
399 | } | ||
400 | } | ||
401 | |||
402 | /* | ||
392 | * ARMv6 and above have extended page tables. | 403 | * ARMv6 and above have extended page tables. |
393 | */ | 404 | */ |
394 | if (cpu_arch >= CPU_ARCH_ARMv6 && (cr & CR_XP)) { | 405 | if (cpu_arch >= CPU_ARCH_ARMv6 && (cr & CR_XP)) { |
diff --git a/arch/arm/mm/proc-xsc3.S b/arch/arm/mm/proc-xsc3.S index b9dfce57c272..80873b36c3f7 100644 --- a/arch/arm/mm/proc-xsc3.S +++ b/arch/arm/mm/proc-xsc3.S | |||
@@ -371,7 +371,7 @@ ENTRY(cpu_xsc3_switch_mm) | |||
371 | ENTRY(cpu_xsc3_set_pte) | 371 | ENTRY(cpu_xsc3_set_pte) |
372 | str r1, [r0], #-2048 @ linux version | 372 | str r1, [r0], #-2048 @ linux version |
373 | 373 | ||
374 | bic r2, r1, #0xff0 | 374 | bic r2, r1, #0xdf0 @ Keep C, B, coherency bits |
375 | orr r2, r2, #PTE_TYPE_EXT @ extended page | 375 | orr r2, r2, #PTE_TYPE_EXT @ extended page |
376 | 376 | ||
377 | eor r3, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY | 377 | eor r3, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY |