aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2007-07-14 05:23:37 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-07-16 07:05:02 -0400
commit8b99cfb8cc51adae7f5294c8962a026c63100959 (patch)
tree349cebcae3eda608f1ed52fa3afcf661fca075a9
parent27a2ef382c7935a4dd02bff9fd361ce118df98c6 (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.c3
-rw-r--r--arch/sparc64/kernel/smp.c24
-rw-r--r--arch/sparc64/kernel/sparc64_ksyms.c12
-rw-r--r--arch/sparc64/kernel/sysfs.c2
-rw-r--r--arch/sparc64/kernel/time.c28
-rw-r--r--arch/sparc64/lib/Makefile2
-rw-r--r--arch/sparc64/lib/delay.c46
-rw-r--r--include/asm-sparc64/bugs.h5
-rw-r--r--include/asm-sparc64/cpudata.h2
-rw-r--r--include/asm-sparc64/delay.h32
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
50int sparc64_multi_core __read_mostly; 50int sparc64_multi_core __read_mostly;
51 51
52/* Please don't make this stuff initdata!!! --DaveM */
53unsigned char boot_cpu_id;
54
55cpumask_t cpu_possible_map __read_mostly = CPU_MASK_NONE; 52cpumask_t cpu_possible_map __read_mostly = CPU_MASK_NONE;
56cpumask_t cpu_online_map __read_mostly = CPU_MASK_NONE; 53cpumask_t cpu_online_map __read_mostly = CPU_MASK_NONE;
57cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly = 54cpumask_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
1234void __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. */
1240int setup_profiling_timer(unsigned int multiplier) 1227int setup_profiling_timer(unsigned int multiplier)
1241{ 1228{
@@ -1244,7 +1231,6 @@ int setup_profiling_timer(unsigned int multiplier)
1244 1231
1245void __init smp_prepare_cpus(unsigned int max_cpus) 1232void __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
1250void __devinit smp_prepare_boot_cpu(void) 1236void __devinit smp_prepare_boot_cpu(void)
@@ -1323,16 +1309,6 @@ void __cpu_die(unsigned int cpu)
1323 1309
1324void __init smp_cpus_done(unsigned int max_cpus) 1310void __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
1338void smp_send_reschedule(int cpu) 1314void 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);
326EXPORT_SYMBOL(memmove); 324EXPORT_SYMBOL(memmove);
327EXPORT_SYMBOL(strncmp); 325EXPORT_SYMBOL(strncmp);
328 326
329/* Delay routines. */
330EXPORT_SYMBOL(__udelay);
331EXPORT_SYMBOL(__ndelay);
332EXPORT_SYMBOL(__const_udelay);
333EXPORT_SYMBOL(__delay);
334
335void VISenter(void); 327void VISenter(void);
336/* RAID code needs this */ 328/* RAID code needs this */
337EXPORT_SYMBOL(VISenter); 329EXPORT_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
195SHOW_CPUDATA_ULONG_NAME(clock_tick, clock_tick); 195SHOW_CPUDATA_ULONG_NAME(clock_tick, clock_tick);
196SHOW_CPUDATA_ULONG_NAME(udelay_val, udelay_val);
197SHOW_CPUDATA_UINT_NAME(l1_dcache_size, dcache_size); 196SHOW_CPUDATA_UINT_NAME(l1_dcache_size, dcache_size);
198SHOW_CPUDATA_UINT_NAME(l1_dcache_line_size, dcache_line_size); 197SHOW_CPUDATA_UINT_NAME(l1_dcache_line_size, dcache_line_size);
199SHOW_CPUDATA_UINT_NAME(l1_icache_size, icache_size); 198SHOW_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
204static struct sysdev_attribute cpu_core_attrs[] = { 203static 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
1034static unsigned long tb_ticks_per_usec __read_mostly;
1035
1036void __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}
1045EXPORT_SYMBOL(__delay);
1046
1047void udelay(unsigned long usecs)
1048{
1049 __delay(tb_ticks_per_usec * usecs);
1050}
1051EXPORT_SYMBOL(udelay);
1052
1041void __init time_init(void) 1053void __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
19obj-y += iomap.o 19obj-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
13void __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 */
27void __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
37void __udelay(unsigned long n)
38{
39 __const_udelay(n * 0x10c7UL);
40}
41
42
43void __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
7extern unsigned long loops_per_jiffy;
8
9static void __init check_bugs(void) 7static 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
19extern void __bad_udelay(void);
20extern void __bad_ndelay(void);
21
22extern void __udelay(unsigned long usecs);
23extern void __ndelay(unsigned long nsecs);
24extern void __const_udelay(unsigned long usecs);
25extern void __delay(unsigned long loops); 11extern void __delay(unsigned long loops);
26 12extern 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 */