diff options
Diffstat (limited to 'arch/mips/mm/c-r4k.c')
-rw-r--r-- | arch/mips/mm/c-r4k.c | 48 |
1 files changed, 32 insertions, 16 deletions
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index f749f687ee87..627883bc6d5f 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/highmem.h> | 12 | #include <linux/highmem.h> |
13 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
14 | #include <linux/linkage.h> | 14 | #include <linux/linkage.h> |
15 | #include <linux/preempt.h> | ||
15 | #include <linux/sched.h> | 16 | #include <linux/sched.h> |
16 | #include <linux/smp.h> | 17 | #include <linux/smp.h> |
17 | #include <linux/mm.h> | 18 | #include <linux/mm.h> |
@@ -24,6 +25,7 @@ | |||
24 | #include <asm/cacheops.h> | 25 | #include <asm/cacheops.h> |
25 | #include <asm/cpu.h> | 26 | #include <asm/cpu.h> |
26 | #include <asm/cpu-features.h> | 27 | #include <asm/cpu-features.h> |
28 | #include <asm/cpu-type.h> | ||
27 | #include <asm/io.h> | 29 | #include <asm/io.h> |
28 | #include <asm/page.h> | 30 | #include <asm/page.h> |
29 | #include <asm/pgtable.h> | 31 | #include <asm/pgtable.h> |
@@ -601,6 +603,7 @@ static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size) | |||
601 | /* Catch bad driver code */ | 603 | /* Catch bad driver code */ |
602 | BUG_ON(size == 0); | 604 | BUG_ON(size == 0); |
603 | 605 | ||
606 | preempt_disable(); | ||
604 | if (cpu_has_inclusive_pcaches) { | 607 | if (cpu_has_inclusive_pcaches) { |
605 | if (size >= scache_size) | 608 | if (size >= scache_size) |
606 | r4k_blast_scache(); | 609 | r4k_blast_scache(); |
@@ -621,6 +624,7 @@ static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size) | |||
621 | R4600_HIT_CACHEOP_WAR_IMPL; | 624 | R4600_HIT_CACHEOP_WAR_IMPL; |
622 | blast_dcache_range(addr, addr + size); | 625 | blast_dcache_range(addr, addr + size); |
623 | } | 626 | } |
627 | preempt_enable(); | ||
624 | 628 | ||
625 | bc_wback_inv(addr, size); | 629 | bc_wback_inv(addr, size); |
626 | __sync(); | 630 | __sync(); |
@@ -631,6 +635,7 @@ static void r4k_dma_cache_inv(unsigned long addr, unsigned long size) | |||
631 | /* Catch bad driver code */ | 635 | /* Catch bad driver code */ |
632 | BUG_ON(size == 0); | 636 | BUG_ON(size == 0); |
633 | 637 | ||
638 | preempt_disable(); | ||
634 | if (cpu_has_inclusive_pcaches) { | 639 | if (cpu_has_inclusive_pcaches) { |
635 | if (size >= scache_size) | 640 | if (size >= scache_size) |
636 | r4k_blast_scache(); | 641 | r4k_blast_scache(); |
@@ -655,6 +660,7 @@ static void r4k_dma_cache_inv(unsigned long addr, unsigned long size) | |||
655 | R4600_HIT_CACHEOP_WAR_IMPL; | 660 | R4600_HIT_CACHEOP_WAR_IMPL; |
656 | blast_inv_dcache_range(addr, addr + size); | 661 | blast_inv_dcache_range(addr, addr + size); |
657 | } | 662 | } |
663 | preempt_enable(); | ||
658 | 664 | ||
659 | bc_inv(addr, size); | 665 | bc_inv(addr, size); |
660 | __sync(); | 666 | __sync(); |
@@ -780,20 +786,30 @@ static inline void rm7k_erratum31(void) | |||
780 | 786 | ||
781 | static inline void alias_74k_erratum(struct cpuinfo_mips *c) | 787 | static inline void alias_74k_erratum(struct cpuinfo_mips *c) |
782 | { | 788 | { |
789 | unsigned int imp = c->processor_id & PRID_IMP_MASK; | ||
790 | unsigned int rev = c->processor_id & PRID_REV_MASK; | ||
791 | |||
783 | /* | 792 | /* |
784 | * Early versions of the 74K do not update the cache tags on a | 793 | * Early versions of the 74K do not update the cache tags on a |
785 | * vtag miss/ptag hit which can occur in the case of KSEG0/KUSEG | 794 | * vtag miss/ptag hit which can occur in the case of KSEG0/KUSEG |
786 | * aliases. In this case it is better to treat the cache as always | 795 | * aliases. In this case it is better to treat the cache as always |
787 | * having aliases. | 796 | * having aliases. |
788 | */ | 797 | */ |
789 | if ((c->processor_id & 0xff) <= PRID_REV_ENCODE_332(2, 4, 0)) | 798 | switch (imp) { |
790 | c->dcache.flags |= MIPS_CACHE_VTAG; | 799 | case PRID_IMP_74K: |
791 | if ((c->processor_id & 0xff) == PRID_REV_ENCODE_332(2, 4, 0)) | 800 | if (rev <= PRID_REV_ENCODE_332(2, 4, 0)) |
792 | write_c0_config6(read_c0_config6() | MIPS_CONF6_SYND); | 801 | c->dcache.flags |= MIPS_CACHE_VTAG; |
793 | if (((c->processor_id & 0xff00) == PRID_IMP_1074K) && | 802 | if (rev == PRID_REV_ENCODE_332(2, 4, 0)) |
794 | ((c->processor_id & 0xff) <= PRID_REV_ENCODE_332(1, 1, 0))) { | 803 | write_c0_config6(read_c0_config6() | MIPS_CONF6_SYND); |
795 | c->dcache.flags |= MIPS_CACHE_VTAG; | 804 | break; |
796 | write_c0_config6(read_c0_config6() | MIPS_CONF6_SYND); | 805 | case PRID_IMP_1074K: |
806 | if (rev <= PRID_REV_ENCODE_332(1, 1, 0)) { | ||
807 | c->dcache.flags |= MIPS_CACHE_VTAG; | ||
808 | write_c0_config6(read_c0_config6() | MIPS_CONF6_SYND); | ||
809 | } | ||
810 | break; | ||
811 | default: | ||
812 | BUG(); | ||
797 | } | 813 | } |
798 | } | 814 | } |
799 | 815 | ||
@@ -809,7 +825,7 @@ static void probe_pcache(void) | |||
809 | unsigned long config1; | 825 | unsigned long config1; |
810 | unsigned int lsize; | 826 | unsigned int lsize; |
811 | 827 | ||
812 | switch (c->cputype) { | 828 | switch (current_cpu_type()) { |
813 | case CPU_R4600: /* QED style two way caches? */ | 829 | case CPU_R4600: /* QED style two way caches? */ |
814 | case CPU_R4700: | 830 | case CPU_R4700: |
815 | case CPU_R5000: | 831 | case CPU_R5000: |
@@ -1025,7 +1041,8 @@ static void probe_pcache(void) | |||
1025 | * presumably no vendor is shipping his hardware in the "bad" | 1041 | * presumably no vendor is shipping his hardware in the "bad" |
1026 | * configuration. | 1042 | * configuration. |
1027 | */ | 1043 | */ |
1028 | if ((prid & 0xff00) == PRID_IMP_R4000 && (prid & 0xff) < 0x40 && | 1044 | if ((prid & PRID_IMP_MASK) == PRID_IMP_R4000 && |
1045 | (prid & PRID_REV_MASK) < PRID_REV_R4400 && | ||
1029 | !(config & CONF_SC) && c->icache.linesz != 16 && | 1046 | !(config & CONF_SC) && c->icache.linesz != 16 && |
1030 | PAGE_SIZE <= 0x8000) | 1047 | PAGE_SIZE <= 0x8000) |
1031 | panic("Improper R4000SC processor configuration detected"); | 1048 | panic("Improper R4000SC processor configuration detected"); |
@@ -1045,7 +1062,7 @@ static void probe_pcache(void) | |||
1045 | * normally they'd suffer from aliases but magic in the hardware deals | 1062 | * normally they'd suffer from aliases but magic in the hardware deals |
1046 | * with that for us so we don't need to take care ourselves. | 1063 | * with that for us so we don't need to take care ourselves. |
1047 | */ | 1064 | */ |
1048 | switch (c->cputype) { | 1065 | switch (current_cpu_type()) { |
1049 | case CPU_20KC: | 1066 | case CPU_20KC: |
1050 | case CPU_25KF: | 1067 | case CPU_25KF: |
1051 | case CPU_SB1: | 1068 | case CPU_SB1: |
@@ -1065,7 +1082,7 @@ static void probe_pcache(void) | |||
1065 | case CPU_34K: | 1082 | case CPU_34K: |
1066 | case CPU_74K: | 1083 | case CPU_74K: |
1067 | case CPU_1004K: | 1084 | case CPU_1004K: |
1068 | if (c->cputype == CPU_74K) | 1085 | if (current_cpu_type() == CPU_74K) |
1069 | alias_74k_erratum(c); | 1086 | alias_74k_erratum(c); |
1070 | if ((read_c0_config7() & (1 << 16))) { | 1087 | if ((read_c0_config7() & (1 << 16))) { |
1071 | /* effectively physically indexed dcache, | 1088 | /* effectively physically indexed dcache, |
@@ -1078,7 +1095,7 @@ static void probe_pcache(void) | |||
1078 | c->dcache.flags |= MIPS_CACHE_ALIASES; | 1095 | c->dcache.flags |= MIPS_CACHE_ALIASES; |
1079 | } | 1096 | } |
1080 | 1097 | ||
1081 | switch (c->cputype) { | 1098 | switch (current_cpu_type()) { |
1082 | case CPU_20KC: | 1099 | case CPU_20KC: |
1083 | /* | 1100 | /* |
1084 | * Some older 20Kc chips doesn't have the 'VI' bit in | 1101 | * Some older 20Kc chips doesn't have the 'VI' bit in |
@@ -1207,7 +1224,7 @@ static void setup_scache(void) | |||
1207 | * processors don't have a S-cache that would be relevant to the | 1224 | * processors don't have a S-cache that would be relevant to the |
1208 | * Linux memory management. | 1225 | * Linux memory management. |
1209 | */ | 1226 | */ |
1210 | switch (c->cputype) { | 1227 | switch (current_cpu_type()) { |
1211 | case CPU_R4000SC: | 1228 | case CPU_R4000SC: |
1212 | case CPU_R4000MC: | 1229 | case CPU_R4000MC: |
1213 | case CPU_R4400SC: | 1230 | case CPU_R4400SC: |
@@ -1384,9 +1401,8 @@ static void r4k_cache_error_setup(void) | |||
1384 | { | 1401 | { |
1385 | extern char __weak except_vec2_generic; | 1402 | extern char __weak except_vec2_generic; |
1386 | extern char __weak except_vec2_sb1; | 1403 | extern char __weak except_vec2_sb1; |
1387 | struct cpuinfo_mips *c = ¤t_cpu_data; | ||
1388 | 1404 | ||
1389 | switch (c->cputype) { | 1405 | switch (current_cpu_type()) { |
1390 | case CPU_SB1: | 1406 | case CPU_SB1: |
1391 | case CPU_SB1A: | 1407 | case CPU_SB1A: |
1392 | set_uncached_handler(0x100, &except_vec2_sb1, 0x80); | 1408 | set_uncached_handler(0x100, &except_vec2_sb1, 0x80); |