aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/Kconfig7
-rw-r--r--arch/powerpc/kernel/Makefile1
-rw-r--r--arch/powerpc/kernel/smp-tbsync.c (renamed from arch/ppc64/kernel/smp-tbsync.c)112
-rw-r--r--arch/ppc64/Kconfig5
-rw-r--r--arch/ppc64/kernel/Makefile5
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
305config PPC_PREP 306config 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
391config GENERIC_TBSYNC
392 bool
393 default y if CONFIG_PPC32 && CONFIG_SMP
394 default n
395
389source "drivers/cpufreq/Kconfig" 396source "drivers/cpufreq/Kconfig"
390 397
391config CPU_FREQ_PMAC 398config 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
21obj-$(CONFIG_RTAS_FLASH) += rtas_flash.o 21obj-$(CONFIG_RTAS_FLASH) += rtas_flash.o
22obj-$(CONFIG_RTAS_PROC) += rtas-proc.o 22obj-$(CONFIG_RTAS_PROC) += rtas-proc.o
23obj-$(CONFIG_IBMVIO) += vio.o 23obj-$(CONFIG_IBMVIO) += vio.o
24obj-$(CONFIG_GENERIC_TBSYNC) += smp-tbsync.o
24 25
25ifeq ($(CONFIG_PPC_MERGE),y) 26ifeq ($(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
24static struct { 24static 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
37static volatile int running; 37static volatile int running;
38 38
39static void __devinit 39static void __devinit enter_contest(u64 mark, long add)
40enter_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
46void __devinit 45void __devinit smp_generic_take_timebase(void)
47smp_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
83static int __devinit 77static int __devinit start_contest(int cmd, long offset, int num)
84start_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
120void __devinit 112void __devinit smp_generic_give_timebase(void)
121smp_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
93config PPC_MAPLE 94config 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
187config GENERIC_TBSYNC
188 def_bool n
189
185config PPC_PMAC64 190config 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
52obj-$(CONFIG_PPC_MAPLE) += udbg_16550.o 52obj-$(CONFIG_PPC_MAPLE) += udbg_16550.o
53 53
54ifdef CONFIG_SMP
55obj-$(CONFIG_PPC_PMAC) += smp-tbsync.o
56obj-$(CONFIG_PPC_MAPLE) += smp-tbsync.o
57endif
58
59obj-$(CONFIG_KPROBES) += kprobes.o 54obj-$(CONFIG_KPROBES) += kprobes.o
60 55
61CFLAGS_ioctl32.o += -Ifs/ 56CFLAGS_ioctl32.o += -Ifs/