diff options
| author | Steven Whitehouse <swhiteho@redhat.com> | 2006-09-28 08:29:59 -0400 |
|---|---|---|
| committer | Steven Whitehouse <swhiteho@redhat.com> | 2006-09-28 08:29:59 -0400 |
| commit | 185a257f2f73bcd89050ad02da5bedbc28fc43fa (patch) | |
| tree | 5e32586114534ed3f2165614cba3d578f5d87307 /arch/mips/kernel/cpu-probe.c | |
| parent | 3f1a9aaeffd8d1cbc5ab9776c45cbd66af1c9699 (diff) | |
| parent | a77c64c1a641950626181b4857abb701d8f38ccc (diff) | |
Merge branch 'master' into gfs2
Diffstat (limited to 'arch/mips/kernel/cpu-probe.c')
| -rw-r--r-- | arch/mips/kernel/cpu-probe.c | 62 |
1 files changed, 45 insertions, 17 deletions
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index aa2caa67299a..9fbf8430c849 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c | |||
| @@ -38,15 +38,40 @@ static void r3081_wait(void) | |||
| 38 | 38 | ||
| 39 | static void r39xx_wait(void) | 39 | static void r39xx_wait(void) |
| 40 | { | 40 | { |
| 41 | unsigned long cfg = read_c0_conf(); | 41 | local_irq_disable(); |
| 42 | write_c0_conf(cfg | TX39_CONF_HALT); | 42 | if (!need_resched()) |
| 43 | write_c0_conf(read_c0_conf() | TX39_CONF_HALT); | ||
| 44 | local_irq_enable(); | ||
| 43 | } | 45 | } |
| 44 | 46 | ||
| 47 | /* | ||
| 48 | * There is a race when WAIT instruction executed with interrupt | ||
| 49 | * enabled. | ||
| 50 | * But it is implementation-dependent wheter the pipelie restarts when | ||
| 51 | * a non-enabled interrupt is requested. | ||
| 52 | */ | ||
| 45 | static void r4k_wait(void) | 53 | static void r4k_wait(void) |
| 46 | { | 54 | { |
| 47 | __asm__(".set\tmips3\n\t" | 55 | __asm__(" .set mips3 \n" |
| 48 | "wait\n\t" | 56 | " wait \n" |
| 49 | ".set\tmips0"); | 57 | " .set mips0 \n"); |
| 58 | } | ||
| 59 | |||
| 60 | /* | ||
| 61 | * This variant is preferable as it allows testing need_resched and going to | ||
| 62 | * sleep depending on the outcome atomically. Unfortunately the "It is | ||
| 63 | * implementation-dependent whether the pipeline restarts when a non-enabled | ||
| 64 | * interrupt is requested" restriction in the MIPS32/MIPS64 architecture makes | ||
| 65 | * using this version a gamble. | ||
| 66 | */ | ||
| 67 | static void r4k_wait_irqoff(void) | ||
| 68 | { | ||
| 69 | local_irq_disable(); | ||
| 70 | if (!need_resched()) | ||
| 71 | __asm__(" .set mips3 \n" | ||
| 72 | " wait \n" | ||
| 73 | " .set mips0 \n"); | ||
| 74 | local_irq_enable(); | ||
| 50 | } | 75 | } |
| 51 | 76 | ||
| 52 | /* The Au1xxx wait is available only if using 32khz counter or | 77 | /* The Au1xxx wait is available only if using 32khz counter or |
| @@ -56,17 +81,17 @@ int allow_au1k_wait; | |||
| 56 | static void au1k_wait(void) | 81 | static void au1k_wait(void) |
| 57 | { | 82 | { |
| 58 | /* using the wait instruction makes CP0 counter unusable */ | 83 | /* using the wait instruction makes CP0 counter unusable */ |
| 59 | __asm__(".set mips3\n\t" | 84 | __asm__(" .set mips3 \n" |
| 60 | "cache 0x14, 0(%0)\n\t" | 85 | " cache 0x14, 0(%0) \n" |
| 61 | "cache 0x14, 32(%0)\n\t" | 86 | " cache 0x14, 32(%0) \n" |
| 62 | "sync\n\t" | 87 | " sync \n" |
| 63 | "nop\n\t" | 88 | " nop \n" |
| 64 | "wait\n\t" | 89 | " wait \n" |
| 65 | "nop\n\t" | 90 | " nop \n" |
| 66 | "nop\n\t" | 91 | " nop \n" |
| 67 | "nop\n\t" | 92 | " nop \n" |
| 68 | "nop\n\t" | 93 | " nop \n" |
| 69 | ".set mips0\n\t" | 94 | " .set mips0 \n" |
| 70 | : : "r" (au1k_wait)); | 95 | : : "r" (au1k_wait)); |
| 71 | } | 96 | } |
| 72 | 97 | ||
| @@ -111,7 +136,6 @@ static inline void check_wait(void) | |||
| 111 | case CPU_NEVADA: | 136 | case CPU_NEVADA: |
| 112 | case CPU_RM7000: | 137 | case CPU_RM7000: |
| 113 | case CPU_RM9000: | 138 | case CPU_RM9000: |
| 114 | case CPU_TX49XX: | ||
| 115 | case CPU_4KC: | 139 | case CPU_4KC: |
| 116 | case CPU_4KEC: | 140 | case CPU_4KEC: |
| 117 | case CPU_4KSC: | 141 | case CPU_4KSC: |
| @@ -125,6 +149,10 @@ static inline void check_wait(void) | |||
| 125 | cpu_wait = r4k_wait; | 149 | cpu_wait = r4k_wait; |
| 126 | printk(" available.\n"); | 150 | printk(" available.\n"); |
| 127 | break; | 151 | break; |
| 152 | case CPU_TX49XX: | ||
| 153 | cpu_wait = r4k_wait_irqoff; | ||
| 154 | printk(" available.\n"); | ||
| 155 | break; | ||
| 128 | case CPU_AU1000: | 156 | case CPU_AU1000: |
| 129 | case CPU_AU1100: | 157 | case CPU_AU1100: |
| 130 | case CPU_AU1500: | 158 | case CPU_AU1500: |
