diff options
Diffstat (limited to 'arch/mips/mm/c-r4k.c')
-rw-r--r-- | arch/mips/mm/c-r4k.c | 50 |
1 files changed, 34 insertions, 16 deletions
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index f749f687ee87..bc6f96fcb529 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,11 +603,13 @@ 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(); |
607 | else | 610 | else |
608 | blast_scache_range(addr, addr + size); | 611 | blast_scache_range(addr, addr + size); |
612 | preempt_enable(); | ||
609 | __sync(); | 613 | __sync(); |
610 | return; | 614 | return; |
611 | } | 615 | } |
@@ -621,6 +625,7 @@ static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size) | |||
621 | R4600_HIT_CACHEOP_WAR_IMPL; | 625 | R4600_HIT_CACHEOP_WAR_IMPL; |
622 | blast_dcache_range(addr, addr + size); | 626 | blast_dcache_range(addr, addr + size); |
623 | } | 627 | } |
628 | preempt_enable(); | ||
624 | 629 | ||
625 | bc_wback_inv(addr, size); | 630 | bc_wback_inv(addr, size); |
626 | __sync(); | 631 | __sync(); |
@@ -631,6 +636,7 @@ static void r4k_dma_cache_inv(unsigned long addr, unsigned long size) | |||
631 | /* Catch bad driver code */ | 636 | /* Catch bad driver code */ |
632 | BUG_ON(size == 0); | 637 | BUG_ON(size == 0); |
633 | 638 | ||
639 | preempt_disable(); | ||
634 | if (cpu_has_inclusive_pcaches) { | 640 | if (cpu_has_inclusive_pcaches) { |
635 | if (size >= scache_size) | 641 | if (size >= scache_size) |
636 | r4k_blast_scache(); | 642 | r4k_blast_scache(); |
@@ -645,6 +651,7 @@ static void r4k_dma_cache_inv(unsigned long addr, unsigned long size) | |||
645 | */ | 651 | */ |
646 | blast_inv_scache_range(addr, addr + size); | 652 | blast_inv_scache_range(addr, addr + size); |
647 | } | 653 | } |
654 | preempt_enable(); | ||
648 | __sync(); | 655 | __sync(); |
649 | return; | 656 | return; |
650 | } | 657 | } |
@@ -655,6 +662,7 @@ static void r4k_dma_cache_inv(unsigned long addr, unsigned long size) | |||
655 | R4600_HIT_CACHEOP_WAR_IMPL; | 662 | R4600_HIT_CACHEOP_WAR_IMPL; |
656 | blast_inv_dcache_range(addr, addr + size); | 663 | blast_inv_dcache_range(addr, addr + size); |
657 | } | 664 | } |
665 | preempt_enable(); | ||
658 | 666 | ||
659 | bc_inv(addr, size); | 667 | bc_inv(addr, size); |
660 | __sync(); | 668 | __sync(); |
@@ -780,20 +788,30 @@ static inline void rm7k_erratum31(void) | |||
780 | 788 | ||
781 | static inline void alias_74k_erratum(struct cpuinfo_mips *c) | 789 | static inline void alias_74k_erratum(struct cpuinfo_mips *c) |
782 | { | 790 | { |
791 | unsigned int imp = c->processor_id & PRID_IMP_MASK; | ||
792 | unsigned int rev = c->processor_id & PRID_REV_MASK; | ||
793 | |||
783 | /* | 794 | /* |
784 | * Early versions of the 74K do not update the cache tags on a | 795 | * 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 | 796 | * 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 | 797 | * aliases. In this case it is better to treat the cache as always |
787 | * having aliases. | 798 | * having aliases. |
788 | */ | 799 | */ |
789 | if ((c->processor_id & 0xff) <= PRID_REV_ENCODE_332(2, 4, 0)) | 800 | switch (imp) { |
790 | c->dcache.flags |= MIPS_CACHE_VTAG; | 801 | case PRID_IMP_74K: |
791 | if ((c->processor_id & 0xff) == PRID_REV_ENCODE_332(2, 4, 0)) | 802 | if (rev <= PRID_REV_ENCODE_332(2, 4, 0)) |
792 | write_c0_config6(read_c0_config6() | MIPS_CONF6_SYND); | 803 | c->dcache.flags |= MIPS_CACHE_VTAG; |
793 | if (((c->processor_id & 0xff00) == PRID_IMP_1074K) && | 804 | if (rev == PRID_REV_ENCODE_332(2, 4, 0)) |
794 | ((c->processor_id & 0xff) <= PRID_REV_ENCODE_332(1, 1, 0))) { | 805 | write_c0_config6(read_c0_config6() | MIPS_CONF6_SYND); |
795 | c->dcache.flags |= MIPS_CACHE_VTAG; | 806 | break; |
796 | write_c0_config6(read_c0_config6() | MIPS_CONF6_SYND); | 807 | case PRID_IMP_1074K: |
808 | if (rev <= PRID_REV_ENCODE_332(1, 1, 0)) { | ||
809 | c->dcache.flags |= MIPS_CACHE_VTAG; | ||
810 | write_c0_config6(read_c0_config6() | MIPS_CONF6_SYND); | ||
811 | } | ||
812 | break; | ||
813 | default: | ||
814 | BUG(); | ||
797 | } | 815 | } |
798 | } | 816 | } |
799 | 817 | ||
@@ -809,7 +827,7 @@ static void probe_pcache(void) | |||
809 | unsigned long config1; | 827 | unsigned long config1; |
810 | unsigned int lsize; | 828 | unsigned int lsize; |
811 | 829 | ||
812 | switch (c->cputype) { | 830 | switch (current_cpu_type()) { |
813 | case CPU_R4600: /* QED style two way caches? */ | 831 | case CPU_R4600: /* QED style two way caches? */ |
814 | case CPU_R4700: | 832 | case CPU_R4700: |
815 | case CPU_R5000: | 833 | case CPU_R5000: |
@@ -1025,7 +1043,8 @@ static void probe_pcache(void) | |||
1025 | * presumably no vendor is shipping his hardware in the "bad" | 1043 | * presumably no vendor is shipping his hardware in the "bad" |
1026 | * configuration. | 1044 | * configuration. |
1027 | */ | 1045 | */ |
1028 | if ((prid & 0xff00) == PRID_IMP_R4000 && (prid & 0xff) < 0x40 && | 1046 | if ((prid & PRID_IMP_MASK) == PRID_IMP_R4000 && |
1047 | (prid & PRID_REV_MASK) < PRID_REV_R4400 && | ||
1029 | !(config & CONF_SC) && c->icache.linesz != 16 && | 1048 | !(config & CONF_SC) && c->icache.linesz != 16 && |
1030 | PAGE_SIZE <= 0x8000) | 1049 | PAGE_SIZE <= 0x8000) |
1031 | panic("Improper R4000SC processor configuration detected"); | 1050 | panic("Improper R4000SC processor configuration detected"); |
@@ -1045,7 +1064,7 @@ static void probe_pcache(void) | |||
1045 | * normally they'd suffer from aliases but magic in the hardware deals | 1064 | * 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. | 1065 | * with that for us so we don't need to take care ourselves. |
1047 | */ | 1066 | */ |
1048 | switch (c->cputype) { | 1067 | switch (current_cpu_type()) { |
1049 | case CPU_20KC: | 1068 | case CPU_20KC: |
1050 | case CPU_25KF: | 1069 | case CPU_25KF: |
1051 | case CPU_SB1: | 1070 | case CPU_SB1: |
@@ -1065,7 +1084,7 @@ static void probe_pcache(void) | |||
1065 | case CPU_34K: | 1084 | case CPU_34K: |
1066 | case CPU_74K: | 1085 | case CPU_74K: |
1067 | case CPU_1004K: | 1086 | case CPU_1004K: |
1068 | if (c->cputype == CPU_74K) | 1087 | if (current_cpu_type() == CPU_74K) |
1069 | alias_74k_erratum(c); | 1088 | alias_74k_erratum(c); |
1070 | if ((read_c0_config7() & (1 << 16))) { | 1089 | if ((read_c0_config7() & (1 << 16))) { |
1071 | /* effectively physically indexed dcache, | 1090 | /* effectively physically indexed dcache, |
@@ -1078,7 +1097,7 @@ static void probe_pcache(void) | |||
1078 | c->dcache.flags |= MIPS_CACHE_ALIASES; | 1097 | c->dcache.flags |= MIPS_CACHE_ALIASES; |
1079 | } | 1098 | } |
1080 | 1099 | ||
1081 | switch (c->cputype) { | 1100 | switch (current_cpu_type()) { |
1082 | case CPU_20KC: | 1101 | case CPU_20KC: |
1083 | /* | 1102 | /* |
1084 | * Some older 20Kc chips doesn't have the 'VI' bit in | 1103 | * Some older 20Kc chips doesn't have the 'VI' bit in |
@@ -1207,7 +1226,7 @@ static void setup_scache(void) | |||
1207 | * processors don't have a S-cache that would be relevant to the | 1226 | * processors don't have a S-cache that would be relevant to the |
1208 | * Linux memory management. | 1227 | * Linux memory management. |
1209 | */ | 1228 | */ |
1210 | switch (c->cputype) { | 1229 | switch (current_cpu_type()) { |
1211 | case CPU_R4000SC: | 1230 | case CPU_R4000SC: |
1212 | case CPU_R4000MC: | 1231 | case CPU_R4000MC: |
1213 | case CPU_R4400SC: | 1232 | case CPU_R4400SC: |
@@ -1384,9 +1403,8 @@ static void r4k_cache_error_setup(void) | |||
1384 | { | 1403 | { |
1385 | extern char __weak except_vec2_generic; | 1404 | extern char __weak except_vec2_generic; |
1386 | extern char __weak except_vec2_sb1; | 1405 | extern char __weak except_vec2_sb1; |
1387 | struct cpuinfo_mips *c = ¤t_cpu_data; | ||
1388 | 1406 | ||
1389 | switch (c->cputype) { | 1407 | switch (current_cpu_type()) { |
1390 | case CPU_SB1: | 1408 | case CPU_SB1: |
1391 | case CPU_SB1A: | 1409 | case CPU_SB1A: |
1392 | set_uncached_handler(0x100, &except_vec2_sb1, 0x80); | 1410 | set_uncached_handler(0x100, &except_vec2_sb1, 0x80); |