diff options
author | Steven J. Hill <Steven.Hill@imgtec.com> | 2013-03-25 14:47:29 -0400 |
---|---|---|
committer | Steven J. Hill <Steven.Hill@imgtec.com> | 2013-05-01 17:32:49 -0400 |
commit | b6d92b4a6bdb880b39789c677b952c53a437028d (patch) | |
tree | f14d30f02314d75860aa1ed12449410e6659513b /arch/mips/mm | |
parent | c34c09c81d659e13e15947580198fa652af3ca1a (diff) |
MIPS: Add option to disable software I/O coherency.
Some MIPS controllers have hardware I/O coherency. This patch
detects those and turns off software coherency. A new kernel
command line option also allows the user to manually turn
software coherency on or off.
Signed-off-by: Steven J. Hill <Steven.Hill@imgtec.com>
Diffstat (limited to 'arch/mips/mm')
-rw-r--r-- | arch/mips/mm/c-r4k.c | 24 | ||||
-rw-r--r-- | arch/mips/mm/dma-default.c | 25 |
2 files changed, 31 insertions, 18 deletions
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index 2078915eacb9..f5943ab44987 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <asm/war.h> | 33 | #include <asm/war.h> |
34 | #include <asm/cacheflush.h> /* for run_uncached() */ | 34 | #include <asm/cacheflush.h> /* for run_uncached() */ |
35 | #include <asm/traps.h> | 35 | #include <asm/traps.h> |
36 | #include <asm/dma-coherence.h> | ||
36 | 37 | ||
37 | /* | 38 | /* |
38 | * Special Variant of smp_call_function for use by cache functions: | 39 | * Special Variant of smp_call_function for use by cache functions: |
@@ -1377,20 +1378,6 @@ static void __cpuinit coherency_setup(void) | |||
1377 | } | 1378 | } |
1378 | } | 1379 | } |
1379 | 1380 | ||
1380 | #if defined(CONFIG_DMA_NONCOHERENT) | ||
1381 | |||
1382 | static int __cpuinitdata coherentio; | ||
1383 | |||
1384 | static int __init setcoherentio(char *str) | ||
1385 | { | ||
1386 | coherentio = 1; | ||
1387 | |||
1388 | return 0; | ||
1389 | } | ||
1390 | |||
1391 | early_param("coherentio", setcoherentio); | ||
1392 | #endif | ||
1393 | |||
1394 | static void __cpuinit r4k_cache_error_setup(void) | 1381 | static void __cpuinit r4k_cache_error_setup(void) |
1395 | { | 1382 | { |
1396 | extern char __weak except_vec2_generic; | 1383 | extern char __weak except_vec2_generic; |
@@ -1472,9 +1459,14 @@ void __cpuinit r4k_cache_init(void) | |||
1472 | 1459 | ||
1473 | build_clear_page(); | 1460 | build_clear_page(); |
1474 | build_copy_page(); | 1461 | build_copy_page(); |
1475 | #if !defined(CONFIG_MIPS_CMP) | 1462 | |
1463 | /* | ||
1464 | * We want to run CMP kernels on core with and without coherent | ||
1465 | * caches. Therefore, do not use CONFIG_MIPS_CMP to decide whether | ||
1466 | * or not to flush caches. | ||
1467 | */ | ||
1476 | local_r4k___flush_cache_all(NULL); | 1468 | local_r4k___flush_cache_all(NULL); |
1477 | #endif | 1469 | |
1478 | coherency_setup(); | 1470 | coherency_setup(); |
1479 | board_cache_error_setup = r4k_cache_error_setup; | 1471 | board_cache_error_setup = r4k_cache_error_setup; |
1480 | } | 1472 | } |
diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c index f9ef83829a52..caf92ecb37d6 100644 --- a/arch/mips/mm/dma-default.c +++ b/arch/mips/mm/dma-default.c | |||
@@ -22,6 +22,26 @@ | |||
22 | 22 | ||
23 | #include <dma-coherence.h> | 23 | #include <dma-coherence.h> |
24 | 24 | ||
25 | int coherentio = 0; /* User defined DMA coherency from command line. */ | ||
26 | EXPORT_SYMBOL_GPL(coherentio); | ||
27 | int hw_coherentio = 0; /* Actual hardware supported DMA coherency setting. */ | ||
28 | |||
29 | static int __init setcoherentio(char *str) | ||
30 | { | ||
31 | coherentio = 1; | ||
32 | pr_info("Hardware DMA cache coherency (command line)\n"); | ||
33 | return 0; | ||
34 | } | ||
35 | early_param("coherentio", setcoherentio); | ||
36 | |||
37 | static int __init setnocoherentio(char *str) | ||
38 | { | ||
39 | coherentio = 0; | ||
40 | pr_info("Software DMA cache coherency (command line)\n"); | ||
41 | return 0; | ||
42 | } | ||
43 | early_param("nocoherentio", setnocoherentio); | ||
44 | |||
25 | static inline struct page *dma_addr_to_page(struct device *dev, | 45 | static inline struct page *dma_addr_to_page(struct device *dev, |
26 | dma_addr_t dma_addr) | 46 | dma_addr_t dma_addr) |
27 | { | 47 | { |
@@ -115,7 +135,8 @@ static void *mips_dma_alloc_coherent(struct device *dev, size_t size, | |||
115 | 135 | ||
116 | if (!plat_device_is_coherent(dev)) { | 136 | if (!plat_device_is_coherent(dev)) { |
117 | dma_cache_wback_inv((unsigned long) ret, size); | 137 | dma_cache_wback_inv((unsigned long) ret, size); |
118 | ret = UNCAC_ADDR(ret); | 138 | if (!hw_coherentio) |
139 | ret = UNCAC_ADDR(ret); | ||
119 | } | 140 | } |
120 | } | 141 | } |
121 | 142 | ||
@@ -142,7 +163,7 @@ static void mips_dma_free_coherent(struct device *dev, size_t size, void *vaddr, | |||
142 | 163 | ||
143 | plat_unmap_dma_mem(dev, dma_handle, size, DMA_BIDIRECTIONAL); | 164 | plat_unmap_dma_mem(dev, dma_handle, size, DMA_BIDIRECTIONAL); |
144 | 165 | ||
145 | if (!plat_device_is_coherent(dev)) | 166 | if (!plat_device_is_coherent(dev) && !hw_coherentio) |
146 | addr = CAC_ADDR(addr); | 167 | addr = CAC_ADDR(addr); |
147 | 168 | ||
148 | free_pages(addr, get_order(size)); | 169 | free_pages(addr, get_order(size)); |