diff options
author | David S. Miller <davem@sunset.davemloft.net> | 2007-07-14 05:23:37 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-07-16 07:05:02 -0400 |
commit | 8b99cfb8cc51adae7f5294c8962a026c63100959 (patch) | |
tree | 349cebcae3eda608f1ed52fa3afcf661fca075a9 | |
parent | 27a2ef382c7935a4dd02bff9fd361ce118df98c6 (diff) |
[SPARC64]: More sensible udelay implementation.
Take a page from the powerpc folks and just calculate the
delay factor directly.
Since frequency scaling chips use a system-tick register,
the value is going to be the same system-wide.
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | arch/sparc64/kernel/setup.c | 3 | ||||
-rw-r--r-- | arch/sparc64/kernel/smp.c | 24 | ||||
-rw-r--r-- | arch/sparc64/kernel/sparc64_ksyms.c | 12 | ||||
-rw-r--r-- | arch/sparc64/kernel/sysfs.c | 2 | ||||
-rw-r--r-- | arch/sparc64/kernel/time.c | 28 | ||||
-rw-r--r-- | arch/sparc64/lib/Makefile | 2 | ||||
-rw-r--r-- | arch/sparc64/lib/delay.c | 46 | ||||
-rw-r--r-- | include/asm-sparc64/bugs.h | 5 | ||||
-rw-r--r-- | include/asm-sparc64/cpudata.h | 2 | ||||
-rw-r--r-- | include/asm-sparc64/delay.h | 32 |
10 files changed, 31 insertions, 125 deletions
diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c index 7490cc670a53..55db632999fc 100644 --- a/arch/sparc64/kernel/setup.c +++ b/arch/sparc64/kernel/setup.c | |||
@@ -442,7 +442,6 @@ static int show_cpuinfo(struct seq_file *m, void *__unused) | |||
442 | "D$ parity tl1\t: %u\n" | 442 | "D$ parity tl1\t: %u\n" |
443 | "I$ parity tl1\t: %u\n" | 443 | "I$ parity tl1\t: %u\n" |
444 | #ifndef CONFIG_SMP | 444 | #ifndef CONFIG_SMP |
445 | "Cpu0Bogo\t: %lu.%02lu\n" | ||
446 | "Cpu0ClkTck\t: %016lx\n" | 445 | "Cpu0ClkTck\t: %016lx\n" |
447 | #endif | 446 | #endif |
448 | , | 447 | , |
@@ -457,8 +456,6 @@ static int show_cpuinfo(struct seq_file *m, void *__unused) | |||
457 | dcache_parity_tl1_occurred, | 456 | dcache_parity_tl1_occurred, |
458 | icache_parity_tl1_occurred | 457 | icache_parity_tl1_occurred |
459 | #ifndef CONFIG_SMP | 458 | #ifndef CONFIG_SMP |
460 | , cpu_data(0).udelay_val/(500000/HZ), | ||
461 | (cpu_data(0).udelay_val/(5000/HZ)) % 100, | ||
462 | cpu_data(0).clock_tick | 459 | cpu_data(0).clock_tick |
463 | #endif | 460 | #endif |
464 | ); | 461 | ); |
diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c index 9d02b3a9bb85..69a1183c622d 100644 --- a/arch/sparc64/kernel/smp.c +++ b/arch/sparc64/kernel/smp.c | |||
@@ -49,9 +49,6 @@ extern void calibrate_delay(void); | |||
49 | 49 | ||
50 | int sparc64_multi_core __read_mostly; | 50 | int sparc64_multi_core __read_mostly; |
51 | 51 | ||
52 | /* Please don't make this stuff initdata!!! --DaveM */ | ||
53 | unsigned char boot_cpu_id; | ||
54 | |||
55 | cpumask_t cpu_possible_map __read_mostly = CPU_MASK_NONE; | 52 | cpumask_t cpu_possible_map __read_mostly = CPU_MASK_NONE; |
56 | cpumask_t cpu_online_map __read_mostly = CPU_MASK_NONE; | 53 | cpumask_t cpu_online_map __read_mostly = CPU_MASK_NONE; |
57 | cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly = | 54 | cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly = |
@@ -82,10 +79,7 @@ void smp_bogo(struct seq_file *m) | |||
82 | 79 | ||
83 | for_each_online_cpu(i) | 80 | for_each_online_cpu(i) |
84 | seq_printf(m, | 81 | seq_printf(m, |
85 | "Cpu%dBogo\t: %lu.%02lu\n" | ||
86 | "Cpu%dClkTck\t: %016lx\n", | 82 | "Cpu%dClkTck\t: %016lx\n", |
87 | i, cpu_data(i).udelay_val / (500000/HZ), | ||
88 | (cpu_data(i).udelay_val / (5000/HZ)) % 100, | ||
89 | i, cpu_data(i).clock_tick); | 83 | i, cpu_data(i).clock_tick); |
90 | } | 84 | } |
91 | 85 | ||
@@ -112,8 +106,6 @@ void __devinit smp_callin(void) | |||
112 | 106 | ||
113 | local_irq_enable(); | 107 | local_irq_enable(); |
114 | 108 | ||
115 | calibrate_delay(); | ||
116 | cpu_data(cpuid).udelay_val = loops_per_jiffy; | ||
117 | callin_flag = 1; | 109 | callin_flag = 1; |
118 | __asm__ __volatile__("membar #Sync\n\t" | 110 | __asm__ __volatile__("membar #Sync\n\t" |
119 | "flush %%g6" : : : "memory"); | 111 | "flush %%g6" : : : "memory"); |
@@ -1231,11 +1223,6 @@ void smp_penguin_jailcell(int irq, struct pt_regs *regs) | |||
1231 | preempt_enable(); | 1223 | preempt_enable(); |
1232 | } | 1224 | } |
1233 | 1225 | ||
1234 | void __init smp_tick_init(void) | ||
1235 | { | ||
1236 | boot_cpu_id = hard_smp_processor_id(); | ||
1237 | } | ||
1238 | |||
1239 | /* /proc/profile writes can call this, don't __init it please. */ | 1226 | /* /proc/profile writes can call this, don't __init it please. */ |
1240 | int setup_profiling_timer(unsigned int multiplier) | 1227 | int setup_profiling_timer(unsigned int multiplier) |
1241 | { | 1228 | { |
@@ -1244,7 +1231,6 @@ int setup_profiling_timer(unsigned int multiplier) | |||
1244 | 1231 | ||
1245 | void __init smp_prepare_cpus(unsigned int max_cpus) | 1232 | void __init smp_prepare_cpus(unsigned int max_cpus) |
1246 | { | 1233 | { |
1247 | cpu_data(boot_cpu_id).udelay_val = loops_per_jiffy; | ||
1248 | } | 1234 | } |
1249 | 1235 | ||
1250 | void __devinit smp_prepare_boot_cpu(void) | 1236 | void __devinit smp_prepare_boot_cpu(void) |
@@ -1323,16 +1309,6 @@ void __cpu_die(unsigned int cpu) | |||
1323 | 1309 | ||
1324 | void __init smp_cpus_done(unsigned int max_cpus) | 1310 | void __init smp_cpus_done(unsigned int max_cpus) |
1325 | { | 1311 | { |
1326 | unsigned long bogosum = 0; | ||
1327 | int i; | ||
1328 | |||
1329 | for_each_online_cpu(i) | ||
1330 | bogosum += cpu_data(i).udelay_val; | ||
1331 | printk("Total of %ld processors activated " | ||
1332 | "(%lu.%02lu BogoMIPS).\n", | ||
1333 | (long) num_online_cpus(), | ||
1334 | bogosum/(500000/HZ), | ||
1335 | (bogosum/(5000/HZ))%100); | ||
1336 | } | 1312 | } |
1337 | 1313 | ||
1338 | void smp_send_reschedule(int cpu) | 1314 | void smp_send_reschedule(int cpu) |
diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c index 51e059e36d47..719d676c2ddc 100644 --- a/arch/sparc64/kernel/sparc64_ksyms.c +++ b/arch/sparc64/kernel/sparc64_ksyms.c | |||
@@ -1,7 +1,6 @@ | |||
1 | /* $Id: sparc64_ksyms.c,v 1.121 2002/02/09 19:49:31 davem Exp $ | 1 | /* arch/sparc64/kernel/sparc64_ksyms.c: Sparc64 specific ksyms support. |
2 | * arch/sparc64/kernel/sparc64_ksyms.c: Sparc64 specific ksyms support. | ||
3 | * | 2 | * |
4 | * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) | 3 | * Copyright (C) 1996, 2007 David S. Miller (davem@davemloft.net) |
5 | * Copyright (C) 1996 Eddie C. Dost (ecd@skynet.be) | 4 | * Copyright (C) 1996 Eddie C. Dost (ecd@skynet.be) |
6 | * Copyright (C) 1999 Jakub Jelinek (jj@ultra.linux.cz) | 5 | * Copyright (C) 1999 Jakub Jelinek (jj@ultra.linux.cz) |
7 | */ | 6 | */ |
@@ -28,7 +27,6 @@ | |||
28 | #include <net/compat.h> | 27 | #include <net/compat.h> |
29 | 28 | ||
30 | #include <asm/oplib.h> | 29 | #include <asm/oplib.h> |
31 | #include <asm/delay.h> | ||
32 | #include <asm/system.h> | 30 | #include <asm/system.h> |
33 | #include <asm/auxio.h> | 31 | #include <asm/auxio.h> |
34 | #include <asm/pgtable.h> | 32 | #include <asm/pgtable.h> |
@@ -326,12 +324,6 @@ EXPORT_SYMBOL(memset); | |||
326 | EXPORT_SYMBOL(memmove); | 324 | EXPORT_SYMBOL(memmove); |
327 | EXPORT_SYMBOL(strncmp); | 325 | EXPORT_SYMBOL(strncmp); |
328 | 326 | ||
329 | /* Delay routines. */ | ||
330 | EXPORT_SYMBOL(__udelay); | ||
331 | EXPORT_SYMBOL(__ndelay); | ||
332 | EXPORT_SYMBOL(__const_udelay); | ||
333 | EXPORT_SYMBOL(__delay); | ||
334 | |||
335 | void VISenter(void); | 327 | void VISenter(void); |
336 | /* RAID code needs this */ | 328 | /* RAID code needs this */ |
337 | EXPORT_SYMBOL(VISenter); | 329 | EXPORT_SYMBOL(VISenter); |
diff --git a/arch/sparc64/kernel/sysfs.c b/arch/sparc64/kernel/sysfs.c index cdb1477af89f..52816c7be0b9 100644 --- a/arch/sparc64/kernel/sysfs.c +++ b/arch/sparc64/kernel/sysfs.c | |||
@@ -193,7 +193,6 @@ static ssize_t show_##NAME(struct sys_device *dev, char *buf) \ | |||
193 | } | 193 | } |
194 | 194 | ||
195 | SHOW_CPUDATA_ULONG_NAME(clock_tick, clock_tick); | 195 | SHOW_CPUDATA_ULONG_NAME(clock_tick, clock_tick); |
196 | SHOW_CPUDATA_ULONG_NAME(udelay_val, udelay_val); | ||
197 | SHOW_CPUDATA_UINT_NAME(l1_dcache_size, dcache_size); | 196 | SHOW_CPUDATA_UINT_NAME(l1_dcache_size, dcache_size); |
198 | SHOW_CPUDATA_UINT_NAME(l1_dcache_line_size, dcache_line_size); | 197 | SHOW_CPUDATA_UINT_NAME(l1_dcache_line_size, dcache_line_size); |
199 | SHOW_CPUDATA_UINT_NAME(l1_icache_size, icache_size); | 198 | SHOW_CPUDATA_UINT_NAME(l1_icache_size, icache_size); |
@@ -203,7 +202,6 @@ SHOW_CPUDATA_UINT_NAME(l2_cache_line_size, ecache_line_size); | |||
203 | 202 | ||
204 | static struct sysdev_attribute cpu_core_attrs[] = { | 203 | static struct sysdev_attribute cpu_core_attrs[] = { |
205 | _SYSDEV_ATTR(clock_tick, 0444, show_clock_tick, NULL), | 204 | _SYSDEV_ATTR(clock_tick, 0444, show_clock_tick, NULL), |
206 | _SYSDEV_ATTR(udelay_val, 0444, show_udelay_val, NULL), | ||
207 | _SYSDEV_ATTR(l1_dcache_size, 0444, show_l1_dcache_size, NULL), | 205 | _SYSDEV_ATTR(l1_dcache_size, 0444, show_l1_dcache_size, NULL), |
208 | _SYSDEV_ATTR(l1_dcache_line_size, 0444, show_l1_dcache_line_size, NULL), | 206 | _SYSDEV_ATTR(l1_dcache_line_size, 0444, show_l1_dcache_line_size, NULL), |
209 | _SYSDEV_ATTR(l1_icache_size, 0444, show_l1_icache_size, NULL), | 207 | _SYSDEV_ATTR(l1_icache_size, 0444, show_l1_icache_size, NULL), |
diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c index a31a0439244f..62e316ab1339 100644 --- a/arch/sparc64/kernel/time.c +++ b/arch/sparc64/kernel/time.c | |||
@@ -849,9 +849,6 @@ static unsigned long sparc64_init_timers(void) | |||
849 | { | 849 | { |
850 | struct device_node *dp; | 850 | struct device_node *dp; |
851 | unsigned long clock; | 851 | unsigned long clock; |
852 | #ifdef CONFIG_SMP | ||
853 | extern void smp_tick_init(void); | ||
854 | #endif | ||
855 | 852 | ||
856 | dp = of_find_node_by_path("/"); | 853 | dp = of_find_node_by_path("/"); |
857 | if (tlb_type == spitfire) { | 854 | if (tlb_type == spitfire) { |
@@ -874,10 +871,6 @@ static unsigned long sparc64_init_timers(void) | |||
874 | clock = of_getintprop_default(dp, "stick-frequency", 0); | 871 | clock = of_getintprop_default(dp, "stick-frequency", 0); |
875 | } | 872 | } |
876 | 873 | ||
877 | #ifdef CONFIG_SMP | ||
878 | smp_tick_init(); | ||
879 | #endif | ||
880 | |||
881 | return clock; | 874 | return clock; |
882 | } | 875 | } |
883 | 876 | ||
@@ -1038,10 +1031,31 @@ static void __init setup_clockevent_multiplier(unsigned long hz) | |||
1038 | sparc64_clockevent.mult = mult; | 1031 | sparc64_clockevent.mult = mult; |
1039 | } | 1032 | } |
1040 | 1033 | ||
1034 | static unsigned long tb_ticks_per_usec __read_mostly; | ||
1035 | |||
1036 | void __delay(unsigned long loops) | ||
1037 | { | ||
1038 | unsigned long bclock, now; | ||
1039 | |||
1040 | bclock = tick_ops->get_tick(); | ||
1041 | do { | ||
1042 | now = tick_ops->get_tick(); | ||
1043 | } while ((now-bclock) < loops); | ||
1044 | } | ||
1045 | EXPORT_SYMBOL(__delay); | ||
1046 | |||
1047 | void udelay(unsigned long usecs) | ||
1048 | { | ||
1049 | __delay(tb_ticks_per_usec * usecs); | ||
1050 | } | ||
1051 | EXPORT_SYMBOL(udelay); | ||
1052 | |||
1041 | void __init time_init(void) | 1053 | void __init time_init(void) |
1042 | { | 1054 | { |
1043 | unsigned long clock = sparc64_init_timers(); | 1055 | unsigned long clock = sparc64_init_timers(); |
1044 | 1056 | ||
1057 | tb_ticks_per_usec = clock / USEC_PER_SEC; | ||
1058 | |||
1045 | timer_ticks_per_nsec_quotient = | 1059 | timer_ticks_per_nsec_quotient = |
1046 | clocksource_hz2mult(clock, SPARC64_NSEC_PER_CYC_SHIFT); | 1060 | clocksource_hz2mult(clock, SPARC64_NSEC_PER_CYC_SHIFT); |
1047 | 1061 | ||
diff --git a/arch/sparc64/lib/Makefile b/arch/sparc64/lib/Makefile index 4a725d8985f1..c4a6d6e7d03c 100644 --- a/arch/sparc64/lib/Makefile +++ b/arch/sparc64/lib/Makefile | |||
@@ -14,6 +14,6 @@ lib-y := PeeCeeI.o copy_page.o clear_page.o strlen.o strncmp.o \ | |||
14 | NGmemcpy.o NGcopy_from_user.o NGcopy_to_user.o NGpatch.o \ | 14 | NGmemcpy.o NGcopy_from_user.o NGcopy_to_user.o NGpatch.o \ |
15 | NGpage.o NGbzero.o \ | 15 | NGpage.o NGbzero.o \ |
16 | copy_in_user.o user_fixup.o memmove.o \ | 16 | copy_in_user.o user_fixup.o memmove.o \ |
17 | mcount.o ipcsum.o rwsem.o xor.o delay.o | 17 | mcount.o ipcsum.o rwsem.o xor.o |
18 | 18 | ||
19 | obj-y += iomap.o | 19 | obj-y += iomap.o |
diff --git a/arch/sparc64/lib/delay.c b/arch/sparc64/lib/delay.c deleted file mode 100644 index fb27e54a03ee..000000000000 --- a/arch/sparc64/lib/delay.c +++ /dev/null | |||
@@ -1,46 +0,0 @@ | |||
1 | /* delay.c: Delay loops for sparc64 | ||
2 | * | ||
3 | * Copyright (C) 2004, 2006 David S. Miller <davem@davemloft.net> | ||
4 | * | ||
5 | * Based heavily upon x86 variant which is: | ||
6 | * Copyright (C) 1993 Linus Torvalds | ||
7 | * Copyright (C) 1997 Martin Mares <mj@atrey.karlin.mff.cuni.cz> | ||
8 | */ | ||
9 | |||
10 | #include <linux/delay.h> | ||
11 | #include <asm/timer.h> | ||
12 | |||
13 | void __delay(unsigned long loops) | ||
14 | { | ||
15 | unsigned long bclock, now; | ||
16 | |||
17 | bclock = tick_ops->get_tick(); | ||
18 | do { | ||
19 | now = tick_ops->get_tick(); | ||
20 | } while ((now-bclock) < loops); | ||
21 | } | ||
22 | |||
23 | /* We used to multiply by HZ after shifting down by 32 bits | ||
24 | * but that runs into problems for higher values of HZ and | ||
25 | * slow cpus. | ||
26 | */ | ||
27 | void __const_udelay(unsigned long n) | ||
28 | { | ||
29 | n *= 4; | ||
30 | |||
31 | n *= (cpu_data(raw_smp_processor_id()).udelay_val * (HZ/4)); | ||
32 | n >>= 32; | ||
33 | |||
34 | __delay(n + 1); | ||
35 | } | ||
36 | |||
37 | void __udelay(unsigned long n) | ||
38 | { | ||
39 | __const_udelay(n * 0x10c7UL); | ||
40 | } | ||
41 | |||
42 | |||
43 | void __ndelay(unsigned long n) | ||
44 | { | ||
45 | __const_udelay(n * 0x5UL); | ||
46 | } | ||
diff --git a/include/asm-sparc64/bugs.h b/include/asm-sparc64/bugs.h index bf39d86c0c9e..11ade6841971 100644 --- a/include/asm-sparc64/bugs.h +++ b/include/asm-sparc64/bugs.h | |||
@@ -4,12 +4,7 @@ | |||
4 | */ | 4 | */ |
5 | #include <asm/sstate.h> | 5 | #include <asm/sstate.h> |
6 | 6 | ||
7 | extern unsigned long loops_per_jiffy; | ||
8 | |||
9 | static void __init check_bugs(void) | 7 | static void __init check_bugs(void) |
10 | { | 8 | { |
11 | #ifndef CONFIG_SMP | ||
12 | cpu_data(0).udelay_val = loops_per_jiffy; | ||
13 | #endif | ||
14 | sstate_running(); | 9 | sstate_running(); |
15 | } | 10 | } |
diff --git a/include/asm-sparc64/cpudata.h b/include/asm-sparc64/cpudata.h index 0016d8b4531c..98a6e609163e 100644 --- a/include/asm-sparc64/cpudata.h +++ b/include/asm-sparc64/cpudata.h | |||
@@ -19,7 +19,7 @@ typedef struct { | |||
19 | unsigned int __softirq_pending; /* must be 1st, see rtrap.S */ | 19 | unsigned int __softirq_pending; /* must be 1st, see rtrap.S */ |
20 | unsigned int __pad0; | 20 | unsigned int __pad0; |
21 | unsigned long clock_tick; /* %tick's per second */ | 21 | unsigned long clock_tick; /* %tick's per second */ |
22 | unsigned long udelay_val; | 22 | unsigned long __pad; |
23 | unsigned int __pad1; | 23 | unsigned int __pad1; |
24 | unsigned int __pad2; | 24 | unsigned int __pad2; |
25 | 25 | ||
diff --git a/include/asm-sparc64/delay.h b/include/asm-sparc64/delay.h index a4aae6f80627..a77aa622d762 100644 --- a/include/asm-sparc64/delay.h +++ b/include/asm-sparc64/delay.h | |||
@@ -1,37 +1,17 @@ | |||
1 | /* delay.h: Linux delay routines on sparc64. | 1 | /* delay.h: Linux delay routines on sparc64. |
2 | * | 2 | * |
3 | * Copyright (C) 1996, 2004 David S. Miller (davem@davemloft.net). | 3 | * Copyright (C) 1996, 2004, 2007 David S. Miller (davem@davemloft.net). |
4 | * | ||
5 | * Based heavily upon x86 variant which is: | ||
6 | * Copyright (C) 1993 Linus Torvalds | ||
7 | * | ||
8 | * Delay routines calling functions in arch/sparc64/lib/delay.c | ||
9 | */ | 4 | */ |
10 | 5 | ||
11 | #ifndef __SPARC64_DELAY_H | 6 | #ifndef _SPARC64_DELAY_H |
12 | #define __SPARC64_DELAY_H | 7 | #define _SPARC64_DELAY_H |
13 | |||
14 | #include <linux/param.h> | ||
15 | #include <asm/cpudata.h> | ||
16 | 8 | ||
17 | #ifndef __ASSEMBLY__ | 9 | #ifndef __ASSEMBLY__ |
18 | 10 | ||
19 | extern void __bad_udelay(void); | ||
20 | extern void __bad_ndelay(void); | ||
21 | |||
22 | extern void __udelay(unsigned long usecs); | ||
23 | extern void __ndelay(unsigned long nsecs); | ||
24 | extern void __const_udelay(unsigned long usecs); | ||
25 | extern void __delay(unsigned long loops); | 11 | extern void __delay(unsigned long loops); |
26 | 12 | extern void udelay(unsigned long usecs); | |
27 | #define udelay(n) (__builtin_constant_p(n) ? \ | 13 | #define mdelay(n) udelay((n) * 1000) |
28 | ((n) > 20000 ? __bad_udelay() : __const_udelay((n) * 0x10c7ul)) : \ | ||
29 | __udelay(n)) | ||
30 | |||
31 | #define ndelay(n) (__builtin_constant_p(n) ? \ | ||
32 | ((n) > 20000 ? __bad_ndelay() : __const_udelay((n) * 5ul)) : \ | ||
33 | __ndelay(n)) | ||
34 | 14 | ||
35 | #endif /* !__ASSEMBLY__ */ | 15 | #endif /* !__ASSEMBLY__ */ |
36 | 16 | ||
37 | #endif /* defined(__SPARC64_DELAY_H) */ | 17 | #endif /* _SPARC64_DELAY_H */ |