diff options
author | Paul Mackerras <paulus@samba.org> | 2005-11-03 21:28:58 -0500 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2005-11-03 21:28:58 -0500 |
commit | 8ad200d7b7c8fac77cf705831e90e889360d7030 (patch) | |
tree | c954352ca3cd8c64e913ceb4a5a082ce7e98f8cd | |
parent | d3ab57ebdc6457543b346255fa47b0ecd7671136 (diff) |
powerpc: Merge smp-tbsync.c (the generic timebase sync routine)
Signed-off-by: Paul Mackerras <paulus@samba.org>
-rw-r--r-- | arch/powerpc/Kconfig | 7 | ||||
-rw-r--r-- | arch/powerpc/kernel/Makefile | 1 | ||||
-rw-r--r-- | arch/powerpc/kernel/smp-tbsync.c (renamed from arch/ppc64/kernel/smp-tbsync.c) | 112 | ||||
-rw-r--r-- | arch/ppc64/Kconfig | 5 | ||||
-rw-r--r-- | arch/ppc64/kernel/Makefile | 5 |
5 files changed, 65 insertions, 65 deletions
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 3cf03ab46113..f4e25c648fbb 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig | |||
@@ -300,6 +300,7 @@ config PPC_PMAC64 | |||
300 | bool | 300 | bool |
301 | depends on PPC_PMAC && POWER4 | 301 | depends on PPC_PMAC && POWER4 |
302 | select U3_DART | 302 | select U3_DART |
303 | select GENERIC_TBSYNC | ||
303 | default y | 304 | default y |
304 | 305 | ||
305 | config PPC_PREP | 306 | config PPC_PREP |
@@ -314,6 +315,7 @@ config PPC_MAPLE | |||
314 | bool " Maple 970FX Evaluation Board" | 315 | bool " Maple 970FX Evaluation Board" |
315 | select U3_DART | 316 | select U3_DART |
316 | select MPIC_BROKEN_U3 | 317 | select MPIC_BROKEN_U3 |
318 | select GENERIC_TBSYNC | ||
317 | default n | 319 | default n |
318 | help | 320 | help |
319 | This option enables support for the Maple 970FX Evaluation Board. | 321 | This option enables support for the Maple 970FX Evaluation Board. |
@@ -386,6 +388,11 @@ config PPC_MPC106 | |||
386 | bool | 388 | bool |
387 | default n | 389 | default n |
388 | 390 | ||
391 | config GENERIC_TBSYNC | ||
392 | bool | ||
393 | default y if CONFIG_PPC32 && CONFIG_SMP | ||
394 | default n | ||
395 | |||
389 | source "drivers/cpufreq/Kconfig" | 396 | source "drivers/cpufreq/Kconfig" |
390 | 397 | ||
391 | config CPU_FREQ_PMAC | 398 | config CPU_FREQ_PMAC |
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 7a3e1155ac9a..631149ea93db 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile | |||
@@ -21,6 +21,7 @@ obj-$(CONFIG_PPC_RTAS) += rtas.o | |||
21 | obj-$(CONFIG_RTAS_FLASH) += rtas_flash.o | 21 | obj-$(CONFIG_RTAS_FLASH) += rtas_flash.o |
22 | obj-$(CONFIG_RTAS_PROC) += rtas-proc.o | 22 | obj-$(CONFIG_RTAS_PROC) += rtas-proc.o |
23 | obj-$(CONFIG_IBMVIO) += vio.o | 23 | obj-$(CONFIG_IBMVIO) += vio.o |
24 | obj-$(CONFIG_GENERIC_TBSYNC) += smp-tbsync.o | ||
24 | 25 | ||
25 | ifeq ($(CONFIG_PPC_MERGE),y) | 26 | ifeq ($(CONFIG_PPC_MERGE),y) |
26 | 27 | ||
diff --git a/arch/ppc64/kernel/smp-tbsync.c b/arch/powerpc/kernel/smp-tbsync.c index 7d8ec9996b3e..9adef3bddad4 100644 --- a/arch/ppc64/kernel/smp-tbsync.c +++ b/arch/powerpc/kernel/smp-tbsync.c | |||
@@ -22,11 +22,11 @@ enum { | |||
22 | }; | 22 | }; |
23 | 23 | ||
24 | static struct { | 24 | static struct { |
25 | volatile long tb; | 25 | volatile u64 tb; |
26 | volatile long mark; | 26 | volatile u64 mark; |
27 | volatile int cmd; | 27 | volatile int cmd; |
28 | volatile int handshake; | 28 | volatile int handshake; |
29 | int filler[3]; | 29 | int filler[2]; |
30 | 30 | ||
31 | volatile int ack; | 31 | volatile int ack; |
32 | int filler2[7]; | 32 | int filler2[7]; |
@@ -36,89 +36,80 @@ static struct { | |||
36 | 36 | ||
37 | static volatile int running; | 37 | static volatile int running; |
38 | 38 | ||
39 | static void __devinit | 39 | static void __devinit enter_contest(u64 mark, long add) |
40 | enter_contest( long mark, long add ) | ||
41 | { | 40 | { |
42 | while( (long)(mftb() - mark) < 0 ) | 41 | while (get_tb() < mark) |
43 | tbsync->race_result = add; | 42 | tbsync->race_result = add; |
44 | } | 43 | } |
45 | 44 | ||
46 | void __devinit | 45 | void __devinit smp_generic_take_timebase(void) |
47 | smp_generic_take_timebase( void ) | ||
48 | { | 46 | { |
49 | int cmd; | 47 | int cmd; |
50 | long tb; | 48 | u64 tb; |
51 | 49 | ||
52 | local_irq_disable(); | 50 | local_irq_disable(); |
53 | while( !running ) | 51 | while (!running) |
54 | ; | 52 | barrier(); |
55 | rmb(); | 53 | rmb(); |
56 | 54 | ||
57 | for( ;; ) { | 55 | for (;;) { |
58 | tbsync->ack = 1; | 56 | tbsync->ack = 1; |
59 | while( !tbsync->handshake ) | 57 | while (!tbsync->handshake) |
60 | ; | 58 | barrier(); |
61 | rmb(); | 59 | rmb(); |
62 | 60 | ||
63 | cmd = tbsync->cmd; | 61 | cmd = tbsync->cmd; |
64 | tb = tbsync->tb; | 62 | tb = tbsync->tb; |
63 | mb(); | ||
65 | tbsync->ack = 0; | 64 | tbsync->ack = 0; |
66 | if( cmd == kExit ) | 65 | if (cmd == kExit) |
67 | return; | 66 | break; |
68 | 67 | ||
69 | if( cmd == kSetAndTest ) { | 68 | while (tbsync->handshake) |
70 | while( tbsync->handshake ) | 69 | barrier(); |
71 | ; | 70 | if (cmd == kSetAndTest) |
72 | asm volatile ("mttbl %0" :: "r" (tb & 0xfffffffful) ); | 71 | set_tb(tb >> 32, tb & 0xfffffffful); |
73 | asm volatile ("mttbu %0" :: "r" (tb >> 32) ); | 72 | enter_contest(tbsync->mark, -1); |
74 | } else { | ||
75 | while( tbsync->handshake ) | ||
76 | ; | ||
77 | } | ||
78 | enter_contest( tbsync->mark, -1 ); | ||
79 | } | 73 | } |
80 | local_irq_enable(); | 74 | local_irq_enable(); |
81 | } | 75 | } |
82 | 76 | ||
83 | static int __devinit | 77 | static int __devinit start_contest(int cmd, long offset, int num) |
84 | start_contest( int cmd, long offset, long num ) | ||
85 | { | 78 | { |
86 | int i, score=0; | 79 | int i, score=0; |
87 | long tb, mark; | 80 | u64 tb; |
81 | long mark; | ||
88 | 82 | ||
89 | tbsync->cmd = cmd; | 83 | tbsync->cmd = cmd; |
90 | 84 | ||
91 | local_irq_disable(); | 85 | local_irq_disable(); |
92 | for( i=-3; i<num; ) { | 86 | for (i = -3; i < num; ) { |
93 | tb = (long)mftb() + 400; | 87 | tb = get_tb() + 400; |
94 | tbsync->tb = tb + offset; | 88 | tbsync->tb = tb + offset; |
95 | tbsync->mark = mark = tb + 400; | 89 | tbsync->mark = mark = tb + 400; |
96 | 90 | ||
97 | wmb(); | 91 | wmb(); |
98 | 92 | ||
99 | tbsync->handshake = 1; | 93 | tbsync->handshake = 1; |
100 | while( tbsync->ack ) | 94 | while (tbsync->ack) |
101 | ; | 95 | barrier(); |
102 | 96 | ||
103 | while( (long)(mftb() - tb) <= 0 ) | 97 | while (get_tb() <= tb) |
104 | ; | 98 | barrier(); |
105 | tbsync->handshake = 0; | 99 | tbsync->handshake = 0; |
106 | enter_contest( mark, 1 ); | 100 | enter_contest(mark, 1); |
107 | 101 | ||
108 | while( !tbsync->ack ) | 102 | while (!tbsync->ack) |
109 | ; | 103 | barrier(); |
110 | 104 | ||
111 | if ((tbsync->tb ^ (long)mftb()) & 0x8000000000000000ul) | 105 | if (i++ > 0) |
112 | continue; | ||
113 | if( i++ > 0 ) | ||
114 | score += tbsync->race_result; | 106 | score += tbsync->race_result; |
115 | } | 107 | } |
116 | local_irq_enable(); | 108 | local_irq_enable(); |
117 | return score; | 109 | return score; |
118 | } | 110 | } |
119 | 111 | ||
120 | void __devinit | 112 | void __devinit smp_generic_give_timebase(void) |
121 | smp_generic_give_timebase( void ) | ||
122 | { | 113 | { |
123 | int i, score, score2, old, min=0, max=5000, offset=1000; | 114 | int i, score, score2, old, min=0, max=5000, offset=1000; |
124 | 115 | ||
@@ -130,14 +121,14 @@ smp_generic_give_timebase( void ) | |||
130 | mb(); | 121 | mb(); |
131 | running = 1; | 122 | running = 1; |
132 | 123 | ||
133 | while( !tbsync->ack ) | 124 | while (!tbsync->ack) |
134 | ; | 125 | barrier(); |
135 | 126 | ||
136 | printk("Got ack\n"); | 127 | printk("Got ack\n"); |
137 | 128 | ||
138 | /* binary search */ | 129 | /* binary search */ |
139 | for( old=-1 ; old != offset ; offset=(min+max)/2 ) { | 130 | for (old = -1; old != offset ; offset = (min+max) / 2) { |
140 | score = start_contest( kSetAndTest, offset, NUM_ITER ); | 131 | score = start_contest(kSetAndTest, offset, NUM_ITER); |
141 | 132 | ||
142 | printk("score %d, offset %d\n", score, offset ); | 133 | printk("score %d, offset %d\n", score, offset ); |
143 | 134 | ||
@@ -147,21 +138,22 @@ smp_generic_give_timebase( void ) | |||
147 | min = offset; | 138 | min = offset; |
148 | old = offset; | 139 | old = offset; |
149 | } | 140 | } |
150 | score = start_contest( kSetAndTest, min, NUM_ITER ); | 141 | score = start_contest(kSetAndTest, min, NUM_ITER); |
151 | score2 = start_contest( kSetAndTest, max, NUM_ITER ); | 142 | score2 = start_contest(kSetAndTest, max, NUM_ITER); |
152 | 143 | ||
153 | printk( "Min %d (score %d), Max %d (score %d)\n", min, score, max, score2 ); | 144 | printk("Min %d (score %d), Max %d (score %d)\n", |
154 | score = abs( score ); | 145 | min, score, max, score2); |
155 | score2 = abs( score2 ); | 146 | score = abs(score); |
147 | score2 = abs(score2); | ||
156 | offset = (score < score2) ? min : max; | 148 | offset = (score < score2) ? min : max; |
157 | 149 | ||
158 | /* guard against inaccurate mttb */ | 150 | /* guard against inaccurate mttb */ |
159 | for( i=0; i<10; i++ ) { | 151 | for (i = 0; i < 10; i++) { |
160 | start_contest( kSetAndTest, offset, NUM_ITER/10 ); | 152 | start_contest(kSetAndTest, offset, NUM_ITER/10); |
161 | 153 | ||
162 | if( (score2=start_contest(kTest, offset, NUM_ITER)) < 0 ) | 154 | if ((score2 = start_contest(kTest, offset, NUM_ITER)) < 0) |
163 | score2 = -score2; | 155 | score2 = -score2; |
164 | if( score2 <= score || score2 < 20 ) | 156 | if (score2 <= score || score2 < 20) |
165 | break; | 157 | break; |
166 | } | 158 | } |
167 | printk("Final offset: %d (%d/%d)\n", offset, score2, NUM_ITER ); | 159 | printk("Final offset: %d (%d/%d)\n", offset, score2, NUM_ITER ); |
@@ -170,10 +162,10 @@ smp_generic_give_timebase( void ) | |||
170 | tbsync->cmd = kExit; | 162 | tbsync->cmd = kExit; |
171 | wmb(); | 163 | wmb(); |
172 | tbsync->handshake = 1; | 164 | tbsync->handshake = 1; |
173 | while( tbsync->ack ) | 165 | while (tbsync->ack) |
174 | ; | 166 | barrier(); |
175 | tbsync->handshake = 0; | 167 | tbsync->handshake = 0; |
176 | kfree( tbsync ); | 168 | kfree(tbsync); |
177 | tbsync = NULL; | 169 | tbsync = NULL; |
178 | running = 0; | 170 | running = 0; |
179 | } | 171 | } |
diff --git a/arch/ppc64/Kconfig b/arch/ppc64/Kconfig index 42677cc96508..b987164fca4c 100644 --- a/arch/ppc64/Kconfig +++ b/arch/ppc64/Kconfig | |||
@@ -89,12 +89,14 @@ config PPC_PMAC | |||
89 | bool " Apple G5 based machines" | 89 | bool " Apple G5 based machines" |
90 | default y | 90 | default y |
91 | select U3_DART | 91 | select U3_DART |
92 | select GENERIC_TBSYNC | ||
92 | 93 | ||
93 | config PPC_MAPLE | 94 | config PPC_MAPLE |
94 | depends on PPC_MULTIPLATFORM | 95 | depends on PPC_MULTIPLATFORM |
95 | bool " Maple 970FX Evaluation Board" | 96 | bool " Maple 970FX Evaluation Board" |
96 | select U3_DART | 97 | select U3_DART |
97 | select MPIC_BROKEN_U3 | 98 | select MPIC_BROKEN_U3 |
99 | select GENERIC_TBSYNC | ||
98 | default n | 100 | default n |
99 | help | 101 | help |
100 | This option enables support for the Maple 970FX Evaluation Board. | 102 | This option enables support for the Maple 970FX Evaluation Board. |
@@ -182,6 +184,9 @@ config MPIC_BROKEN_U3 | |||
182 | depends on PPC_MAPLE | 184 | depends on PPC_MAPLE |
183 | default y | 185 | default y |
184 | 186 | ||
187 | config GENERIC_TBSYNC | ||
188 | def_bool n | ||
189 | |||
185 | config PPC_PMAC64 | 190 | config PPC_PMAC64 |
186 | bool | 191 | bool |
187 | depends on PPC_PMAC | 192 | depends on PPC_PMAC |
diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile index 430cb3900a07..f597c2954b71 100644 --- a/arch/ppc64/kernel/Makefile +++ b/arch/ppc64/kernel/Makefile | |||
@@ -51,11 +51,6 @@ obj-$(CONFIG_PPC_PMAC) += udbg_scc.o | |||
51 | 51 | ||
52 | obj-$(CONFIG_PPC_MAPLE) += udbg_16550.o | 52 | obj-$(CONFIG_PPC_MAPLE) += udbg_16550.o |
53 | 53 | ||
54 | ifdef CONFIG_SMP | ||
55 | obj-$(CONFIG_PPC_PMAC) += smp-tbsync.o | ||
56 | obj-$(CONFIG_PPC_MAPLE) += smp-tbsync.o | ||
57 | endif | ||
58 | |||
59 | obj-$(CONFIG_KPROBES) += kprobes.o | 54 | obj-$(CONFIG_KPROBES) += kprobes.o |
60 | 55 | ||
61 | CFLAGS_ioctl32.o += -Ifs/ | 56 | CFLAGS_ioctl32.o += -Ifs/ |