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 |
