diff options
Diffstat (limited to 'arch')
57 files changed, 981 insertions, 764 deletions
diff --git a/arch/powerpc/boot/dts/kuroboxHD.dts b/arch/powerpc/boot/dts/kuroboxHD.dts index 2e5a1a1812b6..8d725d10882f 100644 --- a/arch/powerpc/boot/dts/kuroboxHD.dts +++ b/arch/powerpc/boot/dts/kuroboxHD.dts | |||
@@ -76,7 +76,6 @@ XXXX add flash parts, rtc, ?? | |||
76 | interrupt-parent = <&mpic>; | 76 | interrupt-parent = <&mpic>; |
77 | 77 | ||
78 | rtc@32 { | 78 | rtc@32 { |
79 | device_type = "rtc"; | ||
80 | compatible = "ricoh,rs5c372a"; | 79 | compatible = "ricoh,rs5c372a"; |
81 | reg = <0x32>; | 80 | reg = <0x32>; |
82 | }; | 81 | }; |
diff --git a/arch/powerpc/boot/dts/kuroboxHG.dts b/arch/powerpc/boot/dts/kuroboxHG.dts index e4916e69ad31..b13a11eb81b0 100644 --- a/arch/powerpc/boot/dts/kuroboxHG.dts +++ b/arch/powerpc/boot/dts/kuroboxHG.dts | |||
@@ -76,7 +76,6 @@ XXXX add flash parts, rtc, ?? | |||
76 | interrupt-parent = <&mpic>; | 76 | interrupt-parent = <&mpic>; |
77 | 77 | ||
78 | rtc@32 { | 78 | rtc@32 { |
79 | device_type = "rtc"; | ||
80 | compatible = "ricoh,rs5c372a"; | 79 | compatible = "ricoh,rs5c372a"; |
81 | reg = <0x32>; | 80 | reg = <0x32>; |
82 | }; | 81 | }; |
diff --git a/arch/powerpc/boot/dts/lite5200.dts b/arch/powerpc/boot/dts/lite5200.dts index 2cf9a8768f44..3f7a5dce8de0 100644 --- a/arch/powerpc/boot/dts/lite5200.dts +++ b/arch/powerpc/boot/dts/lite5200.dts | |||
@@ -130,7 +130,6 @@ | |||
130 | 130 | ||
131 | rtc@800 { // Real time clock | 131 | rtc@800 { // Real time clock |
132 | compatible = "fsl,mpc5200-rtc"; | 132 | compatible = "fsl,mpc5200-rtc"; |
133 | device_type = "rtc"; | ||
134 | reg = <0x800 0x100>; | 133 | reg = <0x800 0x100>; |
135 | interrupts = <1 5 0 1 6 0>; | 134 | interrupts = <1 5 0 1 6 0>; |
136 | interrupt-parent = <&mpc5200_pic>; | 135 | interrupt-parent = <&mpc5200_pic>; |
diff --git a/arch/powerpc/boot/dts/lite5200b.dts b/arch/powerpc/boot/dts/lite5200b.dts index 7bd5b9c399b8..63e3bb48e843 100644 --- a/arch/powerpc/boot/dts/lite5200b.dts +++ b/arch/powerpc/boot/dts/lite5200b.dts | |||
@@ -130,7 +130,6 @@ | |||
130 | 130 | ||
131 | rtc@800 { // Real time clock | 131 | rtc@800 { // Real time clock |
132 | compatible = "fsl,mpc5200b-rtc","fsl,mpc5200-rtc"; | 132 | compatible = "fsl,mpc5200b-rtc","fsl,mpc5200-rtc"; |
133 | device_type = "rtc"; | ||
134 | reg = <0x800 0x100>; | 133 | reg = <0x800 0x100>; |
135 | interrupts = <1 5 0 1 6 0>; | 134 | interrupts = <1 5 0 1 6 0>; |
136 | interrupt-parent = <&mpc5200_pic>; | 135 | interrupt-parent = <&mpc5200_pic>; |
diff --git a/arch/powerpc/boot/dts/motionpro.dts b/arch/powerpc/boot/dts/motionpro.dts index 9e3c921be164..52ba6f98b273 100644 --- a/arch/powerpc/boot/dts/motionpro.dts +++ b/arch/powerpc/boot/dts/motionpro.dts | |||
@@ -248,7 +248,6 @@ | |||
248 | fsl5200-clocking; | 248 | fsl5200-clocking; |
249 | 249 | ||
250 | rtc@68 { | 250 | rtc@68 { |
251 | device_type = "rtc"; | ||
252 | compatible = "dallas,ds1339"; | 251 | compatible = "dallas,ds1339"; |
253 | reg = <0x68>; | 252 | reg = <0x68>; |
254 | }; | 253 | }; |
diff --git a/arch/powerpc/boot/dts/mpc8315erdb.dts b/arch/powerpc/boot/dts/mpc8315erdb.dts index 6b850670de1d..d3d3097b873a 100644 --- a/arch/powerpc/boot/dts/mpc8315erdb.dts +++ b/arch/powerpc/boot/dts/mpc8315erdb.dts | |||
@@ -117,7 +117,6 @@ | |||
117 | interrupt-parent = <&ipic>; | 117 | interrupt-parent = <&ipic>; |
118 | dfsrr; | 118 | dfsrr; |
119 | rtc@68 { | 119 | rtc@68 { |
120 | device_type = "rtc"; | ||
121 | compatible = "dallas,ds1339"; | 120 | compatible = "dallas,ds1339"; |
122 | reg = <0x68>; | 121 | reg = <0x68>; |
123 | }; | 122 | }; |
diff --git a/arch/powerpc/boot/dts/mpc8349emitx.dts b/arch/powerpc/boot/dts/mpc8349emitx.dts index 2c9d54a35bc3..d86c6a3283ec 100644 --- a/arch/powerpc/boot/dts/mpc8349emitx.dts +++ b/arch/powerpc/boot/dts/mpc8349emitx.dts | |||
@@ -85,7 +85,6 @@ | |||
85 | dfsrr; | 85 | dfsrr; |
86 | 86 | ||
87 | rtc@68 { | 87 | rtc@68 { |
88 | device_type = "rtc"; | ||
89 | compatible = "dallas,ds1339"; | 88 | compatible = "dallas,ds1339"; |
90 | reg = <0x68>; | 89 | reg = <0x68>; |
91 | interrupts = <18 0x8>; | 90 | interrupts = <18 0x8>; |
diff --git a/arch/powerpc/boot/dts/mpc8349emitxgp.dts b/arch/powerpc/boot/dts/mpc8349emitxgp.dts index fa40647ee62e..fd4bbc4cbe30 100644 --- a/arch/powerpc/boot/dts/mpc8349emitxgp.dts +++ b/arch/powerpc/boot/dts/mpc8349emitxgp.dts | |||
@@ -83,7 +83,6 @@ | |||
83 | dfsrr; | 83 | dfsrr; |
84 | 84 | ||
85 | rtc@68 { | 85 | rtc@68 { |
86 | device_type = "rtc"; | ||
87 | compatible = "dallas,ds1339"; | 86 | compatible = "dallas,ds1339"; |
88 | reg = <0x68>; | 87 | reg = <0x68>; |
89 | interrupts = <18 0x8>; | 88 | interrupts = <18 0x8>; |
diff --git a/arch/powerpc/boot/dts/mpc8377_rdb.dts b/arch/powerpc/boot/dts/mpc8377_rdb.dts index 435ef3dd022d..9fe8e4c96b18 100644 --- a/arch/powerpc/boot/dts/mpc8377_rdb.dts +++ b/arch/powerpc/boot/dts/mpc8377_rdb.dts | |||
@@ -117,7 +117,6 @@ | |||
117 | interrupt-parent = <&ipic>; | 117 | interrupt-parent = <&ipic>; |
118 | dfsrr; | 118 | dfsrr; |
119 | rtc@68 { | 119 | rtc@68 { |
120 | device_type = "rtc"; | ||
121 | compatible = "dallas,ds1339"; | 120 | compatible = "dallas,ds1339"; |
122 | reg = <0x68>; | 121 | reg = <0x68>; |
123 | }; | 122 | }; |
diff --git a/arch/powerpc/boot/dts/mpc8378_rdb.dts b/arch/powerpc/boot/dts/mpc8378_rdb.dts index b11e68f56a06..3a6d5287539c 100644 --- a/arch/powerpc/boot/dts/mpc8378_rdb.dts +++ b/arch/powerpc/boot/dts/mpc8378_rdb.dts | |||
@@ -117,7 +117,6 @@ | |||
117 | interrupt-parent = <&ipic>; | 117 | interrupt-parent = <&ipic>; |
118 | dfsrr; | 118 | dfsrr; |
119 | rtc@68 { | 119 | rtc@68 { |
120 | device_type = "rtc"; | ||
121 | compatible = "dallas,ds1339"; | 120 | compatible = "dallas,ds1339"; |
122 | reg = <0x68>; | 121 | reg = <0x68>; |
123 | }; | 122 | }; |
diff --git a/arch/powerpc/boot/dts/mpc8379_rdb.dts b/arch/powerpc/boot/dts/mpc8379_rdb.dts index 337af6ea26d3..ee64def19210 100644 --- a/arch/powerpc/boot/dts/mpc8379_rdb.dts +++ b/arch/powerpc/boot/dts/mpc8379_rdb.dts | |||
@@ -117,7 +117,6 @@ | |||
117 | interrupt-parent = <&ipic>; | 117 | interrupt-parent = <&ipic>; |
118 | dfsrr; | 118 | dfsrr; |
119 | rtc@68 { | 119 | rtc@68 { |
120 | device_type = "rtc"; | ||
121 | compatible = "dallas,ds1339"; | 120 | compatible = "dallas,ds1339"; |
122 | reg = <0x68>; | 121 | reg = <0x68>; |
123 | }; | 122 | }; |
diff --git a/arch/powerpc/boot/dts/pcm030.dts b/arch/powerpc/boot/dts/pcm030.dts index 7c1bb952360c..be2c11ca0594 100644 --- a/arch/powerpc/boot/dts/pcm030.dts +++ b/arch/powerpc/boot/dts/pcm030.dts | |||
@@ -143,7 +143,6 @@ | |||
143 | 143 | ||
144 | rtc@800 { // Real time clock | 144 | rtc@800 { // Real time clock |
145 | compatible = "fsl,mpc5200b-rtc","fsl,mpc5200-rtc"; | 145 | compatible = "fsl,mpc5200b-rtc","fsl,mpc5200-rtc"; |
146 | device_type = "rtc"; | ||
147 | reg = <0x800 0x100>; | 146 | reg = <0x800 0x100>; |
148 | interrupts = <0x1 0x5 0x0 0x1 0x6 0x0>; | 147 | interrupts = <0x1 0x5 0x0 0x1 0x6 0x0>; |
149 | interrupt-parent = <&mpc5200_pic>; | 148 | interrupt-parent = <&mpc5200_pic>; |
@@ -301,7 +300,6 @@ | |||
301 | interrupt-parent = <&mpc5200_pic>; | 300 | interrupt-parent = <&mpc5200_pic>; |
302 | fsl5200-clocking; | 301 | fsl5200-clocking; |
303 | rtc@51 { | 302 | rtc@51 { |
304 | device_type = "rtc"; | ||
305 | compatible = "nxp,pcf8563"; | 303 | compatible = "nxp,pcf8563"; |
306 | reg = <0x51>; | 304 | reg = <0x51>; |
307 | }; | 305 | }; |
diff --git a/arch/powerpc/boot/dts/tqm5200.dts b/arch/powerpc/boot/dts/tqm5200.dts index 3008bf8830c1..906302e26a62 100644 --- a/arch/powerpc/boot/dts/tqm5200.dts +++ b/arch/powerpc/boot/dts/tqm5200.dts | |||
@@ -181,7 +181,6 @@ | |||
181 | fsl5200-clocking; | 181 | fsl5200-clocking; |
182 | 182 | ||
183 | rtc@68 { | 183 | rtc@68 { |
184 | device_type = "rtc"; | ||
185 | compatible = "dallas,ds1307"; | 184 | compatible = "dallas,ds1307"; |
186 | reg = <0x68>; | 185 | reg = <0x68>; |
187 | }; | 186 | }; |
diff --git a/arch/powerpc/boot/libfdt-wrapper.c b/arch/powerpc/boot/libfdt-wrapper.c index 9276327bc2bb..bb8b9b3505ee 100644 --- a/arch/powerpc/boot/libfdt-wrapper.c +++ b/arch/powerpc/boot/libfdt-wrapper.c | |||
@@ -185,7 +185,7 @@ void fdt_init(void *blob) | |||
185 | 185 | ||
186 | /* Make sure the dt blob is the right version and so forth */ | 186 | /* Make sure the dt blob is the right version and so forth */ |
187 | fdt = blob; | 187 | fdt = blob; |
188 | bufsize = fdt_totalsize(fdt) + 4; | 188 | bufsize = fdt_totalsize(fdt) + EXPAND_GRANULARITY; |
189 | buf = malloc(bufsize); | 189 | buf = malloc(bufsize); |
190 | if(!buf) | 190 | if(!buf) |
191 | fatal("malloc failed. can't relocate the device tree\n\r"); | 191 | fatal("malloc failed. can't relocate the device tree\n\r"); |
diff --git a/arch/powerpc/include/asm/atomic.h b/arch/powerpc/include/asm/atomic.h index f3fc733758f5..499be5bdd6fa 100644 --- a/arch/powerpc/include/asm/atomic.h +++ b/arch/powerpc/include/asm/atomic.h | |||
@@ -111,7 +111,7 @@ static __inline__ void atomic_inc(atomic_t *v) | |||
111 | bne- 1b" | 111 | bne- 1b" |
112 | : "=&r" (t), "+m" (v->counter) | 112 | : "=&r" (t), "+m" (v->counter) |
113 | : "r" (&v->counter) | 113 | : "r" (&v->counter) |
114 | : "cc"); | 114 | : "cc", "xer"); |
115 | } | 115 | } |
116 | 116 | ||
117 | static __inline__ int atomic_inc_return(atomic_t *v) | 117 | static __inline__ int atomic_inc_return(atomic_t *v) |
@@ -128,7 +128,7 @@ static __inline__ int atomic_inc_return(atomic_t *v) | |||
128 | ISYNC_ON_SMP | 128 | ISYNC_ON_SMP |
129 | : "=&r" (t) | 129 | : "=&r" (t) |
130 | : "r" (&v->counter) | 130 | : "r" (&v->counter) |
131 | : "cc", "memory"); | 131 | : "cc", "xer", "memory"); |
132 | 132 | ||
133 | return t; | 133 | return t; |
134 | } | 134 | } |
@@ -155,7 +155,7 @@ static __inline__ void atomic_dec(atomic_t *v) | |||
155 | bne- 1b" | 155 | bne- 1b" |
156 | : "=&r" (t), "+m" (v->counter) | 156 | : "=&r" (t), "+m" (v->counter) |
157 | : "r" (&v->counter) | 157 | : "r" (&v->counter) |
158 | : "cc"); | 158 | : "cc", "xer"); |
159 | } | 159 | } |
160 | 160 | ||
161 | static __inline__ int atomic_dec_return(atomic_t *v) | 161 | static __inline__ int atomic_dec_return(atomic_t *v) |
@@ -172,7 +172,7 @@ static __inline__ int atomic_dec_return(atomic_t *v) | |||
172 | ISYNC_ON_SMP | 172 | ISYNC_ON_SMP |
173 | : "=&r" (t) | 173 | : "=&r" (t) |
174 | : "r" (&v->counter) | 174 | : "r" (&v->counter) |
175 | : "cc", "memory"); | 175 | : "cc", "xer", "memory"); |
176 | 176 | ||
177 | return t; | 177 | return t; |
178 | } | 178 | } |
@@ -346,7 +346,7 @@ static __inline__ void atomic64_inc(atomic64_t *v) | |||
346 | bne- 1b" | 346 | bne- 1b" |
347 | : "=&r" (t), "+m" (v->counter) | 347 | : "=&r" (t), "+m" (v->counter) |
348 | : "r" (&v->counter) | 348 | : "r" (&v->counter) |
349 | : "cc"); | 349 | : "cc", "xer"); |
350 | } | 350 | } |
351 | 351 | ||
352 | static __inline__ long atomic64_inc_return(atomic64_t *v) | 352 | static __inline__ long atomic64_inc_return(atomic64_t *v) |
@@ -362,7 +362,7 @@ static __inline__ long atomic64_inc_return(atomic64_t *v) | |||
362 | ISYNC_ON_SMP | 362 | ISYNC_ON_SMP |
363 | : "=&r" (t) | 363 | : "=&r" (t) |
364 | : "r" (&v->counter) | 364 | : "r" (&v->counter) |
365 | : "cc", "memory"); | 365 | : "cc", "xer", "memory"); |
366 | 366 | ||
367 | return t; | 367 | return t; |
368 | } | 368 | } |
@@ -388,7 +388,7 @@ static __inline__ void atomic64_dec(atomic64_t *v) | |||
388 | bne- 1b" | 388 | bne- 1b" |
389 | : "=&r" (t), "+m" (v->counter) | 389 | : "=&r" (t), "+m" (v->counter) |
390 | : "r" (&v->counter) | 390 | : "r" (&v->counter) |
391 | : "cc"); | 391 | : "cc", "xer"); |
392 | } | 392 | } |
393 | 393 | ||
394 | static __inline__ long atomic64_dec_return(atomic64_t *v) | 394 | static __inline__ long atomic64_dec_return(atomic64_t *v) |
@@ -404,7 +404,7 @@ static __inline__ long atomic64_dec_return(atomic64_t *v) | |||
404 | ISYNC_ON_SMP | 404 | ISYNC_ON_SMP |
405 | : "=&r" (t) | 405 | : "=&r" (t) |
406 | : "r" (&v->counter) | 406 | : "r" (&v->counter) |
407 | : "cc", "memory"); | 407 | : "cc", "xer", "memory"); |
408 | 408 | ||
409 | return t; | 409 | return t; |
410 | } | 410 | } |
@@ -431,7 +431,7 @@ static __inline__ long atomic64_dec_if_positive(atomic64_t *v) | |||
431 | "\n\ | 431 | "\n\ |
432 | 2:" : "=&r" (t) | 432 | 2:" : "=&r" (t) |
433 | : "r" (&v->counter) | 433 | : "r" (&v->counter) |
434 | : "cc", "memory"); | 434 | : "cc", "xer", "memory"); |
435 | 435 | ||
436 | return t; | 436 | return t; |
437 | } | 437 | } |
diff --git a/arch/powerpc/include/asm/byteorder.h b/arch/powerpc/include/asm/byteorder.h index b37752214a16..d5de325472e9 100644 --- a/arch/powerpc/include/asm/byteorder.h +++ b/arch/powerpc/include/asm/byteorder.h | |||
@@ -11,6 +11,8 @@ | |||
11 | #include <asm/types.h> | 11 | #include <asm/types.h> |
12 | #include <linux/compiler.h> | 12 | #include <linux/compiler.h> |
13 | 13 | ||
14 | #define __BIG_ENDIAN | ||
15 | |||
14 | #ifdef __GNUC__ | 16 | #ifdef __GNUC__ |
15 | #ifdef __KERNEL__ | 17 | #ifdef __KERNEL__ |
16 | 18 | ||
@@ -21,12 +23,19 @@ static __inline__ __u16 ld_le16(const volatile __u16 *addr) | |||
21 | __asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (addr), "m" (*addr)); | 23 | __asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (addr), "m" (*addr)); |
22 | return val; | 24 | return val; |
23 | } | 25 | } |
26 | #define __arch_swab16p ld_le16 | ||
24 | 27 | ||
25 | static __inline__ void st_le16(volatile __u16 *addr, const __u16 val) | 28 | static __inline__ void st_le16(volatile __u16 *addr, const __u16 val) |
26 | { | 29 | { |
27 | __asm__ __volatile__ ("sthbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr)); | 30 | __asm__ __volatile__ ("sthbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr)); |
28 | } | 31 | } |
29 | 32 | ||
33 | static inline void __arch_swab16s(__u16 *addr) | ||
34 | { | ||
35 | st_le16(addr, *addr); | ||
36 | } | ||
37 | #define __arch_swab16s __arch_swab16s | ||
38 | |||
30 | static __inline__ __u32 ld_le32(const volatile __u32 *addr) | 39 | static __inline__ __u32 ld_le32(const volatile __u32 *addr) |
31 | { | 40 | { |
32 | __u32 val; | 41 | __u32 val; |
@@ -34,13 +43,20 @@ static __inline__ __u32 ld_le32(const volatile __u32 *addr) | |||
34 | __asm__ __volatile__ ("lwbrx %0,0,%1" : "=r" (val) : "r" (addr), "m" (*addr)); | 43 | __asm__ __volatile__ ("lwbrx %0,0,%1" : "=r" (val) : "r" (addr), "m" (*addr)); |
35 | return val; | 44 | return val; |
36 | } | 45 | } |
46 | #define __arch_swab32p ld_le32 | ||
37 | 47 | ||
38 | static __inline__ void st_le32(volatile __u32 *addr, const __u32 val) | 48 | static __inline__ void st_le32(volatile __u32 *addr, const __u32 val) |
39 | { | 49 | { |
40 | __asm__ __volatile__ ("stwbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr)); | 50 | __asm__ __volatile__ ("stwbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr)); |
41 | } | 51 | } |
42 | 52 | ||
43 | static __inline__ __attribute_const__ __u16 ___arch__swab16(__u16 value) | 53 | static inline void __arch_swab32s(__u32 *addr) |
54 | { | ||
55 | st_le32(addr, *addr); | ||
56 | } | ||
57 | #define __arch_swab32s __arch_swab32s | ||
58 | |||
59 | static inline __attribute_const__ __u16 __arch_swab16(__u16 value) | ||
44 | { | 60 | { |
45 | __u16 result; | 61 | __u16 result; |
46 | 62 | ||
@@ -49,8 +65,9 @@ static __inline__ __attribute_const__ __u16 ___arch__swab16(__u16 value) | |||
49 | : "r" (value), "0" (value >> 8)); | 65 | : "r" (value), "0" (value >> 8)); |
50 | return result; | 66 | return result; |
51 | } | 67 | } |
68 | #define __arch_swab16 __arch_swab16 | ||
52 | 69 | ||
53 | static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 value) | 70 | static inline __attribute_const__ __u32 __arch_swab32(__u32 value) |
54 | { | 71 | { |
55 | __u32 result; | 72 | __u32 result; |
56 | 73 | ||
@@ -61,29 +78,16 @@ static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 value) | |||
61 | : "r" (value), "0" (value >> 24)); | 78 | : "r" (value), "0" (value >> 24)); |
62 | return result; | 79 | return result; |
63 | } | 80 | } |
64 | 81 | #define __arch_swab32 __arch_swab32 | |
65 | #define __arch__swab16(x) ___arch__swab16(x) | ||
66 | #define __arch__swab32(x) ___arch__swab32(x) | ||
67 | |||
68 | /* The same, but returns converted value from the location pointer by addr. */ | ||
69 | #define __arch__swab16p(addr) ld_le16(addr) | ||
70 | #define __arch__swab32p(addr) ld_le32(addr) | ||
71 | |||
72 | /* The same, but do the conversion in situ, ie. put the value back to addr. */ | ||
73 | #define __arch__swab16s(addr) st_le16(addr,*addr) | ||
74 | #define __arch__swab32s(addr) st_le32(addr,*addr) | ||
75 | 82 | ||
76 | #endif /* __KERNEL__ */ | 83 | #endif /* __KERNEL__ */ |
77 | 84 | ||
78 | #ifndef __STRICT_ANSI__ | ||
79 | #define __BYTEORDER_HAS_U64__ | ||
80 | #ifndef __powerpc64__ | 85 | #ifndef __powerpc64__ |
81 | #define __SWAB_64_THRU_32__ | 86 | #define __SWAB_64_THRU_32__ |
82 | #endif /* __powerpc64__ */ | 87 | #endif /* __powerpc64__ */ |
83 | #endif /* __STRICT_ANSI__ */ | ||
84 | 88 | ||
85 | #endif /* __GNUC__ */ | 89 | #endif /* __GNUC__ */ |
86 | 90 | ||
87 | #include <linux/byteorder/big_endian.h> | 91 | #include <linux/byteorder.h> |
88 | 92 | ||
89 | #endif /* _ASM_POWERPC_BYTEORDER_H */ | 93 | #endif /* _ASM_POWERPC_BYTEORDER_H */ |
diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h index 1e94b07a020e..803d174dae29 100644 --- a/arch/powerpc/include/asm/cputable.h +++ b/arch/powerpc/include/asm/cputable.h | |||
@@ -194,6 +194,7 @@ extern const char *powerpc_base_platform; | |||
194 | #define CPU_FTR_VSX LONG_ASM_CONST(0x0010000000000000) | 194 | #define CPU_FTR_VSX LONG_ASM_CONST(0x0010000000000000) |
195 | #define CPU_FTR_SAO LONG_ASM_CONST(0x0020000000000000) | 195 | #define CPU_FTR_SAO LONG_ASM_CONST(0x0020000000000000) |
196 | #define CPU_FTR_CP_USE_DCBTZ LONG_ASM_CONST(0x0040000000000000) | 196 | #define CPU_FTR_CP_USE_DCBTZ LONG_ASM_CONST(0x0040000000000000) |
197 | #define CPU_FTR_UNALIGNED_LD_STD LONG_ASM_CONST(0x0080000000000000) | ||
197 | 198 | ||
198 | #ifndef __ASSEMBLY__ | 199 | #ifndef __ASSEMBLY__ |
199 | 200 | ||
@@ -404,7 +405,7 @@ extern const char *powerpc_base_platform; | |||
404 | CPU_FTR_MMCRA | CPU_FTR_SMT | \ | 405 | CPU_FTR_MMCRA | CPU_FTR_SMT | \ |
405 | CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | \ | 406 | CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | \ |
406 | CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \ | 407 | CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \ |
407 | CPU_FTR_DSCR) | 408 | CPU_FTR_DSCR | CPU_FTR_UNALIGNED_LD_STD) |
408 | #define CPU_FTRS_POWER7 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \ | 409 | #define CPU_FTRS_POWER7 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \ |
409 | CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \ | 410 | CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \ |
410 | CPU_FTR_MMCRA | CPU_FTR_SMT | \ | 411 | CPU_FTR_MMCRA | CPU_FTR_SMT | \ |
@@ -415,7 +416,8 @@ extern const char *powerpc_base_platform; | |||
415 | CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \ | 416 | CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \ |
416 | CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \ | 417 | CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \ |
417 | CPU_FTR_PAUSE_ZERO | CPU_FTR_CI_LARGE_PAGE | \ | 418 | CPU_FTR_PAUSE_ZERO | CPU_FTR_CI_LARGE_PAGE | \ |
418 | CPU_FTR_CELL_TB_BUG | CPU_FTR_CP_USE_DCBTZ) | 419 | CPU_FTR_CELL_TB_BUG | CPU_FTR_CP_USE_DCBTZ | \ |
420 | CPU_FTR_UNALIGNED_LD_STD) | ||
419 | #define CPU_FTRS_PA6T (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \ | 421 | #define CPU_FTRS_PA6T (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \ |
420 | CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | \ | 422 | CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | \ |
421 | CPU_FTR_ALTIVEC_COMP | CPU_FTR_CI_LARGE_PAGE | \ | 423 | CPU_FTR_ALTIVEC_COMP | CPU_FTR_CI_LARGE_PAGE | \ |
diff --git a/arch/powerpc/include/asm/dma-mapping.h b/arch/powerpc/include/asm/dma-mapping.h index fddb229bd74f..3c4a2c21d606 100644 --- a/arch/powerpc/include/asm/dma-mapping.h +++ b/arch/powerpc/include/asm/dma-mapping.h | |||
@@ -60,12 +60,6 @@ struct dma_mapping_ops { | |||
60 | dma_addr_t *dma_handle, gfp_t flag); | 60 | dma_addr_t *dma_handle, gfp_t flag); |
61 | void (*free_coherent)(struct device *dev, size_t size, | 61 | void (*free_coherent)(struct device *dev, size_t size, |
62 | void *vaddr, dma_addr_t dma_handle); | 62 | void *vaddr, dma_addr_t dma_handle); |
63 | dma_addr_t (*map_single)(struct device *dev, void *ptr, | ||
64 | size_t size, enum dma_data_direction direction, | ||
65 | struct dma_attrs *attrs); | ||
66 | void (*unmap_single)(struct device *dev, dma_addr_t dma_addr, | ||
67 | size_t size, enum dma_data_direction direction, | ||
68 | struct dma_attrs *attrs); | ||
69 | int (*map_sg)(struct device *dev, struct scatterlist *sg, | 63 | int (*map_sg)(struct device *dev, struct scatterlist *sg, |
70 | int nents, enum dma_data_direction direction, | 64 | int nents, enum dma_data_direction direction, |
71 | struct dma_attrs *attrs); | 65 | struct dma_attrs *attrs); |
@@ -149,10 +143,9 @@ static inline int dma_set_mask(struct device *dev, u64 dma_mask) | |||
149 | } | 143 | } |
150 | 144 | ||
151 | /* | 145 | /* |
152 | * TODO: map_/unmap_single will ideally go away, to be completely | 146 | * map_/unmap_single actually call through to map/unmap_page now that all the |
153 | * replaced by map/unmap_page. Until then, we allow dma_ops to have | 147 | * dma_mapping_ops have been converted over. We just have to get the page and |
154 | * one or the other, or both by checking to see if the specific | 148 | * offset to pass through to map_page |
155 | * function requested exists; and if not, falling back on the other set. | ||
156 | */ | 149 | */ |
157 | static inline dma_addr_t dma_map_single_attrs(struct device *dev, | 150 | static inline dma_addr_t dma_map_single_attrs(struct device *dev, |
158 | void *cpu_addr, | 151 | void *cpu_addr, |
@@ -164,10 +157,6 @@ static inline dma_addr_t dma_map_single_attrs(struct device *dev, | |||
164 | 157 | ||
165 | BUG_ON(!dma_ops); | 158 | BUG_ON(!dma_ops); |
166 | 159 | ||
167 | if (dma_ops->map_single) | ||
168 | return dma_ops->map_single(dev, cpu_addr, size, direction, | ||
169 | attrs); | ||
170 | |||
171 | return dma_ops->map_page(dev, virt_to_page(cpu_addr), | 160 | return dma_ops->map_page(dev, virt_to_page(cpu_addr), |
172 | (unsigned long)cpu_addr % PAGE_SIZE, size, | 161 | (unsigned long)cpu_addr % PAGE_SIZE, size, |
173 | direction, attrs); | 162 | direction, attrs); |
@@ -183,11 +172,6 @@ static inline void dma_unmap_single_attrs(struct device *dev, | |||
183 | 172 | ||
184 | BUG_ON(!dma_ops); | 173 | BUG_ON(!dma_ops); |
185 | 174 | ||
186 | if (dma_ops->unmap_single) { | ||
187 | dma_ops->unmap_single(dev, dma_addr, size, direction, attrs); | ||
188 | return; | ||
189 | } | ||
190 | |||
191 | dma_ops->unmap_page(dev, dma_addr, size, direction, attrs); | 175 | dma_ops->unmap_page(dev, dma_addr, size, direction, attrs); |
192 | } | 176 | } |
193 | 177 | ||
@@ -201,12 +185,7 @@ static inline dma_addr_t dma_map_page_attrs(struct device *dev, | |||
201 | 185 | ||
202 | BUG_ON(!dma_ops); | 186 | BUG_ON(!dma_ops); |
203 | 187 | ||
204 | if (dma_ops->map_page) | 188 | return dma_ops->map_page(dev, page, offset, size, direction, attrs); |
205 | return dma_ops->map_page(dev, page, offset, size, direction, | ||
206 | attrs); | ||
207 | |||
208 | return dma_ops->map_single(dev, page_address(page) + offset, size, | ||
209 | direction, attrs); | ||
210 | } | 189 | } |
211 | 190 | ||
212 | static inline void dma_unmap_page_attrs(struct device *dev, | 191 | static inline void dma_unmap_page_attrs(struct device *dev, |
@@ -219,12 +198,7 @@ static inline void dma_unmap_page_attrs(struct device *dev, | |||
219 | 198 | ||
220 | BUG_ON(!dma_ops); | 199 | BUG_ON(!dma_ops); |
221 | 200 | ||
222 | if (dma_ops->unmap_page) { | 201 | dma_ops->unmap_page(dev, dma_address, size, direction, attrs); |
223 | dma_ops->unmap_page(dev, dma_address, size, direction, attrs); | ||
224 | return; | ||
225 | } | ||
226 | |||
227 | dma_ops->unmap_single(dev, dma_address, size, direction, attrs); | ||
228 | } | 202 | } |
229 | 203 | ||
230 | static inline int dma_map_sg_attrs(struct device *dev, struct scatterlist *sg, | 204 | static inline int dma_map_sg_attrs(struct device *dev, struct scatterlist *sg, |
diff --git a/arch/powerpc/include/asm/eeh.h b/arch/powerpc/include/asm/eeh.h index b886bec67016..66ea9b8b95c5 100644 --- a/arch/powerpc/include/asm/eeh.h +++ b/arch/powerpc/include/asm/eeh.h | |||
@@ -17,8 +17,8 @@ | |||
17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
18 | */ | 18 | */ |
19 | 19 | ||
20 | #ifndef _PPC64_EEH_H | 20 | #ifndef _POWERPC_EEH_H |
21 | #define _PPC64_EEH_H | 21 | #define _POWERPC_EEH_H |
22 | #ifdef __KERNEL__ | 22 | #ifdef __KERNEL__ |
23 | 23 | ||
24 | #include <linux/init.h> | 24 | #include <linux/init.h> |
@@ -110,6 +110,7 @@ static inline void eeh_remove_bus_device(struct pci_dev *dev) { } | |||
110 | #define EEH_IO_ERROR_VALUE(size) (-1UL) | 110 | #define EEH_IO_ERROR_VALUE(size) (-1UL) |
111 | #endif /* CONFIG_EEH */ | 111 | #endif /* CONFIG_EEH */ |
112 | 112 | ||
113 | #ifdef CONFIG_PPC64 | ||
113 | /* | 114 | /* |
114 | * MMIO read/write operations with EEH support. | 115 | * MMIO read/write operations with EEH support. |
115 | */ | 116 | */ |
@@ -207,5 +208,6 @@ static inline void eeh_readsl(const volatile void __iomem *addr, void * buf, | |||
207 | eeh_check_failure(addr, *(u32*)buf); | 208 | eeh_check_failure(addr, *(u32*)buf); |
208 | } | 209 | } |
209 | 210 | ||
211 | #endif /* CONFIG_PPC64 */ | ||
210 | #endif /* __KERNEL__ */ | 212 | #endif /* __KERNEL__ */ |
211 | #endif /* _PPC64_EEH_H */ | 213 | #endif /* _POWERPC_EEH_H */ |
diff --git a/arch/powerpc/include/asm/local.h b/arch/powerpc/include/asm/local.h index 612d83276653..84b457a3c1bc 100644 --- a/arch/powerpc/include/asm/local.h +++ b/arch/powerpc/include/asm/local.h | |||
@@ -67,7 +67,7 @@ static __inline__ long local_inc_return(local_t *l) | |||
67 | bne- 1b" | 67 | bne- 1b" |
68 | : "=&r" (t) | 68 | : "=&r" (t) |
69 | : "r" (&(l->a.counter)) | 69 | : "r" (&(l->a.counter)) |
70 | : "cc", "memory"); | 70 | : "cc", "xer", "memory"); |
71 | 71 | ||
72 | return t; | 72 | return t; |
73 | } | 73 | } |
@@ -94,7 +94,7 @@ static __inline__ long local_dec_return(local_t *l) | |||
94 | bne- 1b" | 94 | bne- 1b" |
95 | : "=&r" (t) | 95 | : "=&r" (t) |
96 | : "r" (&(l->a.counter)) | 96 | : "r" (&(l->a.counter)) |
97 | : "cc", "memory"); | 97 | : "cc", "xer", "memory"); |
98 | 98 | ||
99 | return t; | 99 | return t; |
100 | } | 100 | } |
diff --git a/arch/powerpc/include/asm/lppaca.h b/arch/powerpc/include/asm/lppaca.h index 2fe268b10333..25aaa97facd8 100644 --- a/arch/powerpc/include/asm/lppaca.h +++ b/arch/powerpc/include/asm/lppaca.h | |||
@@ -133,7 +133,8 @@ struct lppaca { | |||
133 | //============================================================================= | 133 | //============================================================================= |
134 | // CACHE_LINE_4-5 0x0180 - 0x027F Contains PMC interrupt data | 134 | // CACHE_LINE_4-5 0x0180 - 0x027F Contains PMC interrupt data |
135 | //============================================================================= | 135 | //============================================================================= |
136 | u8 pmc_save_area[256]; // PMC interrupt Area x00-xFF | 136 | u32 page_ins; // CMO Hint - # page ins by OS x00-x04 |
137 | u8 pmc_save_area[252]; // PMC interrupt Area x04-xFF | ||
137 | } __attribute__((__aligned__(0x400))); | 138 | } __attribute__((__aligned__(0x400))); |
138 | 139 | ||
139 | extern struct lppaca lppaca[]; | 140 | extern struct lppaca lppaca[]; |
diff --git a/arch/powerpc/include/asm/mutex.h b/arch/powerpc/include/asm/mutex.h index 458c1f7fbc18..dabc01c727b8 100644 --- a/arch/powerpc/include/asm/mutex.h +++ b/arch/powerpc/include/asm/mutex.h | |||
@@ -1,9 +1,134 @@ | |||
1 | /* | 1 | /* |
2 | * Pull in the generic implementation for the mutex fastpath. | 2 | * Optimised mutex implementation of include/asm-generic/mutex-dec.h algorithm |
3 | */ | ||
4 | #ifndef _ASM_POWERPC_MUTEX_H | ||
5 | #define _ASM_POWERPC_MUTEX_H | ||
6 | |||
7 | static inline int __mutex_cmpxchg_lock(atomic_t *v, int old, int new) | ||
8 | { | ||
9 | int t; | ||
10 | |||
11 | __asm__ __volatile__ ( | ||
12 | "1: lwarx %0,0,%1 # mutex trylock\n\ | ||
13 | cmpw 0,%0,%2\n\ | ||
14 | bne- 2f\n" | ||
15 | PPC405_ERR77(0,%1) | ||
16 | " stwcx. %3,0,%1\n\ | ||
17 | bne- 1b" | ||
18 | ISYNC_ON_SMP | ||
19 | "\n\ | ||
20 | 2:" | ||
21 | : "=&r" (t) | ||
22 | : "r" (&v->counter), "r" (old), "r" (new) | ||
23 | : "cc", "memory"); | ||
24 | |||
25 | return t; | ||
26 | } | ||
27 | |||
28 | static inline int __mutex_dec_return_lock(atomic_t *v) | ||
29 | { | ||
30 | int t; | ||
31 | |||
32 | __asm__ __volatile__( | ||
33 | "1: lwarx %0,0,%1 # mutex lock\n\ | ||
34 | addic %0,%0,-1\n" | ||
35 | PPC405_ERR77(0,%1) | ||
36 | " stwcx. %0,0,%1\n\ | ||
37 | bne- 1b" | ||
38 | ISYNC_ON_SMP | ||
39 | : "=&r" (t) | ||
40 | : "r" (&v->counter) | ||
41 | : "cc", "memory"); | ||
42 | |||
43 | return t; | ||
44 | } | ||
45 | |||
46 | static inline int __mutex_inc_return_unlock(atomic_t *v) | ||
47 | { | ||
48 | int t; | ||
49 | |||
50 | __asm__ __volatile__( | ||
51 | LWSYNC_ON_SMP | ||
52 | "1: lwarx %0,0,%1 # mutex unlock\n\ | ||
53 | addic %0,%0,1\n" | ||
54 | PPC405_ERR77(0,%1) | ||
55 | " stwcx. %0,0,%1 \n\ | ||
56 | bne- 1b" | ||
57 | : "=&r" (t) | ||
58 | : "r" (&v->counter) | ||
59 | : "cc", "memory"); | ||
60 | |||
61 | return t; | ||
62 | } | ||
63 | |||
64 | /** | ||
65 | * __mutex_fastpath_lock - try to take the lock by moving the count | ||
66 | * from 1 to a 0 value | ||
67 | * @count: pointer of type atomic_t | ||
68 | * @fail_fn: function to call if the original value was not 1 | ||
69 | * | ||
70 | * Change the count from 1 to a value lower than 1, and call <fail_fn> if | ||
71 | * it wasn't 1 originally. This function MUST leave the value lower than | ||
72 | * 1 even when the "1" assertion wasn't true. | ||
73 | */ | ||
74 | static inline void | ||
75 | __mutex_fastpath_lock(atomic_t *count, void (*fail_fn)(atomic_t *)) | ||
76 | { | ||
77 | if (unlikely(__mutex_dec_return_lock(count) < 0)) | ||
78 | fail_fn(count); | ||
79 | } | ||
80 | |||
81 | /** | ||
82 | * __mutex_fastpath_lock_retval - try to take the lock by moving the count | ||
83 | * from 1 to a 0 value | ||
84 | * @count: pointer of type atomic_t | ||
85 | * @fail_fn: function to call if the original value was not 1 | ||
86 | * | ||
87 | * Change the count from 1 to a value lower than 1, and call <fail_fn> if | ||
88 | * it wasn't 1 originally. This function returns 0 if the fastpath succeeds, | ||
89 | * or anything the slow path function returns. | ||
90 | */ | ||
91 | static inline int | ||
92 | __mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *)) | ||
93 | { | ||
94 | if (unlikely(__mutex_dec_return_lock(count) < 0)) | ||
95 | return fail_fn(count); | ||
96 | return 0; | ||
97 | } | ||
98 | |||
99 | /** | ||
100 | * __mutex_fastpath_unlock - try to promote the count from 0 to 1 | ||
101 | * @count: pointer of type atomic_t | ||
102 | * @fail_fn: function to call if the original value was not 0 | ||
103 | * | ||
104 | * Try to promote the count from 0 to 1. If it wasn't 0, call <fail_fn>. | ||
105 | * In the failure case, this function is allowed to either set the value to | ||
106 | * 1, or to set it to a value lower than 1. | ||
107 | */ | ||
108 | static inline void | ||
109 | __mutex_fastpath_unlock(atomic_t *count, void (*fail_fn)(atomic_t *)) | ||
110 | { | ||
111 | if (unlikely(__mutex_inc_return_unlock(count) <= 0)) | ||
112 | fail_fn(count); | ||
113 | } | ||
114 | |||
115 | #define __mutex_slowpath_needs_to_unlock() 1 | ||
116 | |||
117 | /** | ||
118 | * __mutex_fastpath_trylock - try to acquire the mutex, without waiting | ||
119 | * | ||
120 | * @count: pointer of type atomic_t | ||
121 | * @fail_fn: fallback function | ||
3 | * | 122 | * |
4 | * TODO: implement optimized primitives instead, or leave the generic | 123 | * Change the count from 1 to 0, and return 1 (success), or if the count |
5 | * implementation in place, or pick the atomic_xchg() based generic | 124 | * was not 1, then return 0 (failure). |
6 | * implementation. (see asm-generic/mutex-xchg.h for details) | ||
7 | */ | 125 | */ |
126 | static inline int | ||
127 | __mutex_fastpath_trylock(atomic_t *count, int (*fail_fn)(atomic_t *)) | ||
128 | { | ||
129 | if (likely(__mutex_cmpxchg_lock(count, 1, 0) == 1)) | ||
130 | return 1; | ||
131 | return 0; | ||
132 | } | ||
8 | 133 | ||
9 | #include <asm-generic/mutex-dec.h> | 134 | #endif |
diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h index 9047af7baa69..fa8b3b724438 100644 --- a/arch/powerpc/include/asm/pci-bridge.h +++ b/arch/powerpc/include/asm/pci-bridge.h | |||
@@ -241,9 +241,6 @@ extern void pcibios_remove_pci_devices(struct pci_bus *bus); | |||
241 | 241 | ||
242 | /** Discover new pci devices under this bus, and add them */ | 242 | /** Discover new pci devices under this bus, and add them */ |
243 | extern void pcibios_add_pci_devices(struct pci_bus *bus); | 243 | extern void pcibios_add_pci_devices(struct pci_bus *bus); |
244 | extern void pcibios_fixup_new_pci_devices(struct pci_bus *bus); | ||
245 | |||
246 | extern int pcibios_remove_root_bus(struct pci_controller *phb); | ||
247 | 244 | ||
248 | static inline struct pci_controller *pci_bus_to_host(const struct pci_bus *bus) | 245 | static inline struct pci_controller *pci_bus_to_host(const struct pci_bus *bus) |
249 | { | 246 | { |
@@ -290,6 +287,7 @@ extern void pci_process_bridge_OF_ranges(struct pci_controller *hose, | |||
290 | /* Allocate & free a PCI host bridge structure */ | 287 | /* Allocate & free a PCI host bridge structure */ |
291 | extern struct pci_controller *pcibios_alloc_controller(struct device_node *dev); | 288 | extern struct pci_controller *pcibios_alloc_controller(struct device_node *dev); |
292 | extern void pcibios_free_controller(struct pci_controller *phb); | 289 | extern void pcibios_free_controller(struct pci_controller *phb); |
290 | extern void pcibios_setup_phb_resources(struct pci_controller *hose); | ||
293 | 291 | ||
294 | #ifdef CONFIG_PCI | 292 | #ifdef CONFIG_PCI |
295 | extern unsigned long pci_address_to_pio(phys_addr_t address); | 293 | extern unsigned long pci_address_to_pio(phys_addr_t address); |
diff --git a/arch/powerpc/include/asm/pci.h b/arch/powerpc/include/asm/pci.h index 57a2a494886b..1c721a632d8e 100644 --- a/arch/powerpc/include/asm/pci.h +++ b/arch/powerpc/include/asm/pci.h | |||
@@ -204,15 +204,14 @@ static inline struct resource *pcibios_select_root(struct pci_dev *pdev, | |||
204 | return root; | 204 | return root; |
205 | } | 205 | } |
206 | 206 | ||
207 | extern void pcibios_setup_new_device(struct pci_dev *dev); | ||
208 | |||
209 | extern void pcibios_claim_one_bus(struct pci_bus *b); | 207 | extern void pcibios_claim_one_bus(struct pci_bus *b); |
210 | 208 | ||
211 | extern void pcibios_allocate_bus_resources(struct pci_bus *bus); | 209 | extern void pcibios_finish_adding_to_bus(struct pci_bus *bus); |
212 | 210 | ||
213 | extern void pcibios_resource_survey(void); | 211 | extern void pcibios_resource_survey(void); |
214 | 212 | ||
215 | extern struct pci_controller *init_phb_dynamic(struct device_node *dn); | 213 | extern struct pci_controller *init_phb_dynamic(struct device_node *dn); |
214 | extern int remove_phb_dynamic(struct pci_controller *phb); | ||
216 | 215 | ||
217 | extern struct pci_dev *of_create_pci_dev(struct device_node *node, | 216 | extern struct pci_dev *of_create_pci_dev(struct device_node *node, |
218 | struct pci_bus *bus, int devfn); | 217 | struct pci_bus *bus, int devfn); |
@@ -221,6 +220,7 @@ extern void of_scan_pci_bridge(struct device_node *node, | |||
221 | struct pci_dev *dev); | 220 | struct pci_dev *dev); |
222 | 221 | ||
223 | extern void of_scan_bus(struct device_node *node, struct pci_bus *bus); | 222 | extern void of_scan_bus(struct device_node *node, struct pci_bus *bus); |
223 | extern void of_rescan_bus(struct device_node *node, struct pci_bus *bus); | ||
224 | 224 | ||
225 | extern int pci_read_irq_line(struct pci_dev *dev); | 225 | extern int pci_read_irq_line(struct pci_dev *dev); |
226 | 226 | ||
@@ -235,9 +235,8 @@ extern void pci_resource_to_user(const struct pci_dev *dev, int bar, | |||
235 | const struct resource *rsrc, | 235 | const struct resource *rsrc, |
236 | resource_size_t *start, resource_size_t *end); | 236 | resource_size_t *start, resource_size_t *end); |
237 | 237 | ||
238 | extern void pcibios_do_bus_setup(struct pci_bus *bus); | 238 | extern void pcibios_setup_bus_devices(struct pci_bus *bus); |
239 | extern void pcibios_fixup_of_probed_bus(struct pci_bus *bus); | 239 | extern void pcibios_setup_bus_self(struct pci_bus *bus); |
240 | |||
241 | 240 | ||
242 | #endif /* __KERNEL__ */ | 241 | #endif /* __KERNEL__ */ |
243 | #endif /* __ASM_POWERPC_PCI_H */ | 242 | #endif /* __ASM_POWERPC_PCI_H */ |
diff --git a/arch/powerpc/include/asm/ps3.h b/arch/powerpc/include/asm/ps3.h index f9e34c493cbb..4299365590d8 100644 --- a/arch/powerpc/include/asm/ps3.h +++ b/arch/powerpc/include/asm/ps3.h | |||
@@ -516,4 +516,7 @@ void ps3_sync_irq(int node); | |||
516 | u32 ps3_get_hw_thread_id(int cpu); | 516 | u32 ps3_get_hw_thread_id(int cpu); |
517 | u64 ps3_get_spe_id(void *arg); | 517 | u64 ps3_get_spe_id(void *arg); |
518 | 518 | ||
519 | /* mutex synchronizing GPU accesses and video mode changes */ | ||
520 | extern struct mutex ps3_gpu_mutex; | ||
521 | |||
519 | #endif | 522 | #endif |
diff --git a/arch/powerpc/include/asm/ps3av.h b/arch/powerpc/include/asm/ps3av.h index 5aa22cffdbd6..cd24ac16660a 100644 --- a/arch/powerpc/include/asm/ps3av.h +++ b/arch/powerpc/include/asm/ps3av.h | |||
@@ -740,8 +740,4 @@ extern int ps3av_audio_mute(int); | |||
740 | extern int ps3av_audio_mute_analog(int); | 740 | extern int ps3av_audio_mute_analog(int); |
741 | extern int ps3av_dev_open(void); | 741 | extern int ps3av_dev_open(void); |
742 | extern int ps3av_dev_close(void); | 742 | extern int ps3av_dev_close(void); |
743 | extern void ps3av_register_flip_ctl(void (*flip_ctl)(int on, void *data), | ||
744 | void *flip_data); | ||
745 | extern void ps3av_flip_ctl(int on); | ||
746 | |||
747 | #endif /* _ASM_POWERPC_PS3AV_H_ */ | 743 | #endif /* _ASM_POWERPC_PS3AV_H_ */ |
diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h index 1866cec4f967..c25f73d1d842 100644 --- a/arch/powerpc/include/asm/smp.h +++ b/arch/powerpc/include/asm/smp.h | |||
@@ -81,6 +81,13 @@ extern int cpu_to_core_id(int cpu); | |||
81 | #define PPC_MSG_CALL_FUNC_SINGLE 2 | 81 | #define PPC_MSG_CALL_FUNC_SINGLE 2 |
82 | #define PPC_MSG_DEBUGGER_BREAK 3 | 82 | #define PPC_MSG_DEBUGGER_BREAK 3 |
83 | 83 | ||
84 | /* | ||
85 | * irq controllers that have dedicated ipis per message and don't | ||
86 | * need additional code in the action handler may use this | ||
87 | */ | ||
88 | extern int smp_request_message_ipi(int virq, int message); | ||
89 | extern const char *smp_ipi_name[]; | ||
90 | |||
84 | void smp_init_iSeries(void); | 91 | void smp_init_iSeries(void); |
85 | void smp_init_pSeries(void); | 92 | void smp_init_pSeries(void); |
86 | void smp_init_cell(void); | 93 | void smp_init_cell(void); |
diff --git a/arch/powerpc/include/asm/spinlock.h b/arch/powerpc/include/asm/spinlock.h index f56a843f4705..36864364e601 100644 --- a/arch/powerpc/include/asm/spinlock.h +++ b/arch/powerpc/include/asm/spinlock.h | |||
@@ -277,7 +277,7 @@ static inline void __raw_read_unlock(raw_rwlock_t *rw) | |||
277 | bne- 1b" | 277 | bne- 1b" |
278 | : "=&r"(tmp) | 278 | : "=&r"(tmp) |
279 | : "r"(&rw->lock) | 279 | : "r"(&rw->lock) |
280 | : "cr0", "memory"); | 280 | : "cr0", "xer", "memory"); |
281 | } | 281 | } |
282 | 282 | ||
283 | static inline void __raw_write_unlock(raw_rwlock_t *rw) | 283 | static inline void __raw_write_unlock(raw_rwlock_t *rw) |
diff --git a/arch/powerpc/include/asm/synch.h b/arch/powerpc/include/asm/synch.h index 45963e80f557..28f6ddbff4cf 100644 --- a/arch/powerpc/include/asm/synch.h +++ b/arch/powerpc/include/asm/synch.h | |||
@@ -5,6 +5,10 @@ | |||
5 | #include <linux/stringify.h> | 5 | #include <linux/stringify.h> |
6 | #include <asm/feature-fixups.h> | 6 | #include <asm/feature-fixups.h> |
7 | 7 | ||
8 | #if defined(__powerpc64__) || defined(CONFIG_PPC_E500MC) | ||
9 | #define __SUBARCH_HAS_LWSYNC | ||
10 | #endif | ||
11 | |||
8 | #ifndef __ASSEMBLY__ | 12 | #ifndef __ASSEMBLY__ |
9 | extern unsigned int __start___lwsync_fixup, __stop___lwsync_fixup; | 13 | extern unsigned int __start___lwsync_fixup, __stop___lwsync_fixup; |
10 | extern void do_lwsync_fixups(unsigned long value, void *fixup_start, | 14 | extern void do_lwsync_fixups(unsigned long value, void *fixup_start, |
diff --git a/arch/powerpc/include/asm/system.h b/arch/powerpc/include/asm/system.h index d6648c143322..2a4be19a92c4 100644 --- a/arch/powerpc/include/asm/system.h +++ b/arch/powerpc/include/asm/system.h | |||
@@ -23,15 +23,17 @@ | |||
23 | * read_barrier_depends() prevents data-dependent loads being reordered | 23 | * read_barrier_depends() prevents data-dependent loads being reordered |
24 | * across this point (nop on PPC). | 24 | * across this point (nop on PPC). |
25 | * | 25 | * |
26 | * We have to use the sync instructions for mb(), since lwsync doesn't | 26 | * *mb() variants without smp_ prefix must order all types of memory |
27 | * order loads with respect to previous stores. Lwsync is fine for | 27 | * operations with one another. sync is the only instruction sufficient |
28 | * rmb(), though. Note that rmb() actually uses a sync on 32-bit | 28 | * to do this. |
29 | * architectures. | ||
30 | * | 29 | * |
31 | * For wmb(), we use sync since wmb is used in drivers to order | 30 | * For the smp_ barriers, ordering is for cacheable memory operations |
32 | * stores to system memory with respect to writes to the device. | 31 | * only. We have to use the sync instruction for smp_mb(), since lwsync |
33 | * However, smp_wmb() can be a lighter-weight lwsync or eieio barrier | 32 | * doesn't order loads with respect to previous stores. Lwsync can be |
34 | * on SMP since it is only used to order updates to system memory. | 33 | * used for smp_rmb() and smp_wmb(). |
34 | * | ||
35 | * However, on CPUs that don't support lwsync, lwsync actually maps to a | ||
36 | * heavy-weight sync, so smp_wmb() can be a lighter-weight eieio. | ||
35 | */ | 37 | */ |
36 | #define mb() __asm__ __volatile__ ("sync" : : : "memory") | 38 | #define mb() __asm__ __volatile__ ("sync" : : : "memory") |
37 | #define rmb() __asm__ __volatile__ ("sync" : : : "memory") | 39 | #define rmb() __asm__ __volatile__ ("sync" : : : "memory") |
@@ -45,14 +47,14 @@ | |||
45 | #ifdef CONFIG_SMP | 47 | #ifdef CONFIG_SMP |
46 | 48 | ||
47 | #ifdef __SUBARCH_HAS_LWSYNC | 49 | #ifdef __SUBARCH_HAS_LWSYNC |
48 | # define SMPWMB lwsync | 50 | # define SMPWMB LWSYNC |
49 | #else | 51 | #else |
50 | # define SMPWMB eieio | 52 | # define SMPWMB eieio |
51 | #endif | 53 | #endif |
52 | 54 | ||
53 | #define smp_mb() mb() | 55 | #define smp_mb() mb() |
54 | #define smp_rmb() rmb() | 56 | #define smp_rmb() __asm__ __volatile__ (stringify_in_c(LWSYNC) : : :"memory") |
55 | #define smp_wmb() __asm__ __volatile__ (__stringify(SMPWMB) : : :"memory") | 57 | #define smp_wmb() __asm__ __volatile__ (stringify_in_c(SMPWMB) : : :"memory") |
56 | #define smp_read_barrier_depends() read_barrier_depends() | 58 | #define smp_read_barrier_depends() read_barrier_depends() |
57 | #else | 59 | #else |
58 | #define smp_mb() barrier() | 60 | #define smp_mb() barrier() |
diff --git a/arch/powerpc/include/asm/time.h b/arch/powerpc/include/asm/time.h index febd581ec9b0..27ccb764fdab 100644 --- a/arch/powerpc/include/asm/time.h +++ b/arch/powerpc/include/asm/time.h | |||
@@ -48,26 +48,6 @@ extern unsigned long ppc_proc_freq; | |||
48 | extern unsigned long ppc_tb_freq; | 48 | extern unsigned long ppc_tb_freq; |
49 | #define DEFAULT_TB_FREQ 125000000UL | 49 | #define DEFAULT_TB_FREQ 125000000UL |
50 | 50 | ||
51 | /* | ||
52 | * By putting all of this stuff into a single struct we | ||
53 | * reduce the number of cache lines touched by do_gettimeofday. | ||
54 | * Both by collecting all of the data in one cache line and | ||
55 | * by touching only one TOC entry on ppc64. | ||
56 | */ | ||
57 | struct gettimeofday_vars { | ||
58 | u64 tb_to_xs; | ||
59 | u64 stamp_xsec; | ||
60 | u64 tb_orig_stamp; | ||
61 | }; | ||
62 | |||
63 | struct gettimeofday_struct { | ||
64 | unsigned long tb_ticks_per_sec; | ||
65 | struct gettimeofday_vars vars[2]; | ||
66 | struct gettimeofday_vars * volatile varp; | ||
67 | unsigned var_idx; | ||
68 | unsigned tb_to_us; | ||
69 | }; | ||
70 | |||
71 | struct div_result { | 51 | struct div_result { |
72 | u64 result_high; | 52 | u64 result_high; |
73 | u64 result_low; | 53 | u64 result_low; |
diff --git a/arch/powerpc/include/asm/vdso_datapage.h b/arch/powerpc/include/asm/vdso_datapage.h index f01393224b52..13c2c283e178 100644 --- a/arch/powerpc/include/asm/vdso_datapage.h +++ b/arch/powerpc/include/asm/vdso_datapage.h | |||
@@ -39,6 +39,7 @@ | |||
39 | #ifndef __ASSEMBLY__ | 39 | #ifndef __ASSEMBLY__ |
40 | 40 | ||
41 | #include <linux/unistd.h> | 41 | #include <linux/unistd.h> |
42 | #include <linux/time.h> | ||
42 | 43 | ||
43 | #define SYSCALL_MAP_SIZE ((__NR_syscalls + 31) / 32) | 44 | #define SYSCALL_MAP_SIZE ((__NR_syscalls + 31) / 32) |
44 | 45 | ||
@@ -83,6 +84,7 @@ struct vdso_data { | |||
83 | __u32 icache_log_block_size; /* L1 i-cache log block size */ | 84 | __u32 icache_log_block_size; /* L1 i-cache log block size */ |
84 | __s32 wtom_clock_sec; /* Wall to monotonic clock */ | 85 | __s32 wtom_clock_sec; /* Wall to monotonic clock */ |
85 | __s32 wtom_clock_nsec; | 86 | __s32 wtom_clock_nsec; |
87 | struct timespec stamp_xtime; /* xtime as at tb_orig_stamp */ | ||
86 | __u32 syscall_map_64[SYSCALL_MAP_SIZE]; /* map of syscalls */ | 88 | __u32 syscall_map_64[SYSCALL_MAP_SIZE]; /* map of syscalls */ |
87 | __u32 syscall_map_32[SYSCALL_MAP_SIZE]; /* map of syscalls */ | 89 | __u32 syscall_map_32[SYSCALL_MAP_SIZE]; /* map of syscalls */ |
88 | }; | 90 | }; |
@@ -102,6 +104,7 @@ struct vdso_data { | |||
102 | __u32 tz_dsttime; /* Type of dst correction 0x5C */ | 104 | __u32 tz_dsttime; /* Type of dst correction 0x5C */ |
103 | __s32 wtom_clock_sec; /* Wall to monotonic clock */ | 105 | __s32 wtom_clock_sec; /* Wall to monotonic clock */ |
104 | __s32 wtom_clock_nsec; | 106 | __s32 wtom_clock_nsec; |
107 | struct timespec stamp_xtime; /* xtime as at tb_orig_stamp */ | ||
105 | __u32 syscall_map_32[SYSCALL_MAP_SIZE]; /* map of syscalls */ | 108 | __u32 syscall_map_32[SYSCALL_MAP_SIZE]; /* map of syscalls */ |
106 | __u32 dcache_block_size; /* L1 d-cache block size */ | 109 | __u32 dcache_block_size; /* L1 d-cache block size */ |
107 | __u32 icache_block_size; /* L1 i-cache block size */ | 110 | __u32 icache_block_size; /* L1 i-cache block size */ |
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 75c5dd0138fd..050abfd5c17c 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c | |||
@@ -306,6 +306,7 @@ int main(void) | |||
306 | DEFINE(CFG_SYSCALL_MAP32, offsetof(struct vdso_data, syscall_map_32)); | 306 | DEFINE(CFG_SYSCALL_MAP32, offsetof(struct vdso_data, syscall_map_32)); |
307 | DEFINE(WTOM_CLOCK_SEC, offsetof(struct vdso_data, wtom_clock_sec)); | 307 | DEFINE(WTOM_CLOCK_SEC, offsetof(struct vdso_data, wtom_clock_sec)); |
308 | DEFINE(WTOM_CLOCK_NSEC, offsetof(struct vdso_data, wtom_clock_nsec)); | 308 | DEFINE(WTOM_CLOCK_NSEC, offsetof(struct vdso_data, wtom_clock_nsec)); |
309 | DEFINE(STAMP_XTIME, offsetof(struct vdso_data, stamp_xtime)); | ||
309 | DEFINE(CFG_ICACHE_BLOCKSZ, offsetof(struct vdso_data, icache_block_size)); | 310 | DEFINE(CFG_ICACHE_BLOCKSZ, offsetof(struct vdso_data, icache_block_size)); |
310 | DEFINE(CFG_DCACHE_BLOCKSZ, offsetof(struct vdso_data, dcache_block_size)); | 311 | DEFINE(CFG_DCACHE_BLOCKSZ, offsetof(struct vdso_data, dcache_block_size)); |
311 | DEFINE(CFG_ICACHE_LOGBLOCKSZ, offsetof(struct vdso_data, icache_log_block_size)); | 312 | DEFINE(CFG_ICACHE_LOGBLOCKSZ, offsetof(struct vdso_data, icache_log_block_size)); |
diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c index 48a347133f41..c744b327bcab 100644 --- a/arch/powerpc/kernel/paca.c +++ b/arch/powerpc/kernel/paca.c | |||
@@ -37,6 +37,7 @@ struct lppaca lppaca[] = { | |||
37 | .end_of_quantum = 0xfffffffffffffffful, | 37 | .end_of_quantum = 0xfffffffffffffffful, |
38 | .slb_count = 64, | 38 | .slb_count = 64, |
39 | .vmxregs_in_use = 0, | 39 | .vmxregs_in_use = 0, |
40 | .page_ins = 0, | ||
40 | }, | 41 | }, |
41 | }; | 42 | }; |
42 | 43 | ||
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index f36936d9fda3..91c3f52e33a8 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c | |||
@@ -37,13 +37,7 @@ | |||
37 | #include <asm/machdep.h> | 37 | #include <asm/machdep.h> |
38 | #include <asm/ppc-pci.h> | 38 | #include <asm/ppc-pci.h> |
39 | #include <asm/firmware.h> | 39 | #include <asm/firmware.h> |
40 | 40 | #include <asm/eeh.h> | |
41 | #ifdef DEBUG | ||
42 | #include <asm/udbg.h> | ||
43 | #define DBG(fmt...) printk(fmt) | ||
44 | #else | ||
45 | #define DBG(fmt...) | ||
46 | #endif | ||
47 | 41 | ||
48 | static DEFINE_SPINLOCK(hose_spinlock); | 42 | static DEFINE_SPINLOCK(hose_spinlock); |
49 | 43 | ||
@@ -53,8 +47,9 @@ static int global_phb_number; /* Global phb counter */ | |||
53 | /* ISA Memory physical address */ | 47 | /* ISA Memory physical address */ |
54 | resource_size_t isa_mem_base; | 48 | resource_size_t isa_mem_base; |
55 | 49 | ||
56 | /* Default PCI flags is 0 */ | 50 | /* Default PCI flags is 0 on ppc32, modified at boot on ppc64 */ |
57 | unsigned int ppc_pci_flags; | 51 | unsigned int ppc_pci_flags = 0; |
52 | |||
58 | 53 | ||
59 | static struct dma_mapping_ops *pci_dma_ops; | 54 | static struct dma_mapping_ops *pci_dma_ops; |
60 | 55 | ||
@@ -208,26 +203,6 @@ char __devinit *pcibios_setup(char *str) | |||
208 | return str; | 203 | return str; |
209 | } | 204 | } |
210 | 205 | ||
211 | void __devinit pcibios_setup_new_device(struct pci_dev *dev) | ||
212 | { | ||
213 | struct dev_archdata *sd = &dev->dev.archdata; | ||
214 | |||
215 | sd->of_node = pci_device_to_OF_node(dev); | ||
216 | |||
217 | DBG("PCI: device %s OF node: %s\n", pci_name(dev), | ||
218 | sd->of_node ? sd->of_node->full_name : "<none>"); | ||
219 | |||
220 | sd->dma_ops = pci_dma_ops; | ||
221 | #ifdef CONFIG_PPC32 | ||
222 | sd->dma_data = (void *)PCI_DRAM_OFFSET; | ||
223 | #endif | ||
224 | set_dev_node(&dev->dev, pcibus_to_node(dev->bus)); | ||
225 | |||
226 | if (ppc_md.pci_dma_dev_setup) | ||
227 | ppc_md.pci_dma_dev_setup(dev); | ||
228 | } | ||
229 | EXPORT_SYMBOL(pcibios_setup_new_device); | ||
230 | |||
231 | /* | 206 | /* |
232 | * Reads the interrupt pin to determine if interrupt is use by card. | 207 | * Reads the interrupt pin to determine if interrupt is use by card. |
233 | * If the interrupt is used, then gets the interrupt line from the | 208 | * If the interrupt is used, then gets the interrupt line from the |
@@ -252,7 +227,7 @@ int pci_read_irq_line(struct pci_dev *pci_dev) | |||
252 | return -1; | 227 | return -1; |
253 | #endif | 228 | #endif |
254 | 229 | ||
255 | DBG("Try to map irq for %s...\n", pci_name(pci_dev)); | 230 | pr_debug("PCI: Try to map irq for %s...\n", pci_name(pci_dev)); |
256 | 231 | ||
257 | #ifdef DEBUG | 232 | #ifdef DEBUG |
258 | memset(&oirq, 0xff, sizeof(oirq)); | 233 | memset(&oirq, 0xff, sizeof(oirq)); |
@@ -276,26 +251,26 @@ int pci_read_irq_line(struct pci_dev *pci_dev) | |||
276 | line == 0xff || line == 0) { | 251 | line == 0xff || line == 0) { |
277 | return -1; | 252 | return -1; |
278 | } | 253 | } |
279 | DBG(" -> no map ! Using line %d (pin %d) from PCI config\n", | 254 | pr_debug(" No map ! Using line %d (pin %d) from PCI config\n", |
280 | line, pin); | 255 | line, pin); |
281 | 256 | ||
282 | virq = irq_create_mapping(NULL, line); | 257 | virq = irq_create_mapping(NULL, line); |
283 | if (virq != NO_IRQ) | 258 | if (virq != NO_IRQ) |
284 | set_irq_type(virq, IRQ_TYPE_LEVEL_LOW); | 259 | set_irq_type(virq, IRQ_TYPE_LEVEL_LOW); |
285 | } else { | 260 | } else { |
286 | DBG(" -> got one, spec %d cells (0x%08x 0x%08x...) on %s\n", | 261 | pr_debug(" Got one, spec %d cells (0x%08x 0x%08x...) on %s\n", |
287 | oirq.size, oirq.specifier[0], oirq.specifier[1], | 262 | oirq.size, oirq.specifier[0], oirq.specifier[1], |
288 | oirq.controller->full_name); | 263 | oirq.controller->full_name); |
289 | 264 | ||
290 | virq = irq_create_of_mapping(oirq.controller, oirq.specifier, | 265 | virq = irq_create_of_mapping(oirq.controller, oirq.specifier, |
291 | oirq.size); | 266 | oirq.size); |
292 | } | 267 | } |
293 | if(virq == NO_IRQ) { | 268 | if(virq == NO_IRQ) { |
294 | DBG(" -> failed to map !\n"); | 269 | pr_debug(" Failed to map !\n"); |
295 | return -1; | 270 | return -1; |
296 | } | 271 | } |
297 | 272 | ||
298 | DBG(" -> mapped to linux irq %d\n", virq); | 273 | pr_debug(" Mapped to linux irq %d\n", virq); |
299 | 274 | ||
300 | pci_dev->irq = virq; | 275 | pci_dev->irq = virq; |
301 | 276 | ||
@@ -451,8 +426,8 @@ pgprot_t pci_phys_mem_access_prot(struct file *file, | |||
451 | pci_dev_put(pdev); | 426 | pci_dev_put(pdev); |
452 | } | 427 | } |
453 | 428 | ||
454 | DBG("non-PCI map for %llx, prot: %lx\n", | 429 | pr_debug("PCI: Non-PCI map for %llx, prot: %lx\n", |
455 | (unsigned long long)offset, prot); | 430 | (unsigned long long)offset, prot); |
456 | 431 | ||
457 | return __pgprot(prot); | 432 | return __pgprot(prot); |
458 | } | 433 | } |
@@ -853,15 +828,12 @@ void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose, | |||
853 | int pci_proc_domain(struct pci_bus *bus) | 828 | int pci_proc_domain(struct pci_bus *bus) |
854 | { | 829 | { |
855 | struct pci_controller *hose = pci_bus_to_host(bus); | 830 | struct pci_controller *hose = pci_bus_to_host(bus); |
856 | #ifdef CONFIG_PPC64 | 831 | |
857 | return hose->buid != 0; | ||
858 | #else | ||
859 | if (!(ppc_pci_flags & PPC_PCI_ENABLE_PROC_DOMAINS)) | 832 | if (!(ppc_pci_flags & PPC_PCI_ENABLE_PROC_DOMAINS)) |
860 | return 0; | 833 | return 0; |
861 | if (ppc_pci_flags & PPC_PCI_COMPAT_DOMAIN_0) | 834 | if (ppc_pci_flags & PPC_PCI_COMPAT_DOMAIN_0) |
862 | return hose->global_number != 0; | 835 | return hose->global_number != 0; |
863 | return 1; | 836 | return 1; |
864 | #endif | ||
865 | } | 837 | } |
866 | 838 | ||
867 | void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, | 839 | void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, |
@@ -1083,27 +1055,50 @@ static void __devinit pcibios_fixup_bridge(struct pci_bus *bus) | |||
1083 | } | 1055 | } |
1084 | } | 1056 | } |
1085 | 1057 | ||
1086 | static void __devinit __pcibios_fixup_bus(struct pci_bus *bus) | 1058 | void __devinit pcibios_setup_bus_self(struct pci_bus *bus) |
1087 | { | 1059 | { |
1088 | struct pci_dev *dev = bus->self; | 1060 | /* Fix up the bus resources for P2P bridges */ |
1089 | 1061 | if (bus->self != NULL) | |
1090 | pr_debug("PCI: Fixup bus %d (%s)\n", bus->number, dev ? pci_name(dev) : "PHB"); | ||
1091 | |||
1092 | /* Fixup PCI<->PCI bridges. Host bridges are handled separately, for | ||
1093 | * now differently between 32 and 64 bits. | ||
1094 | */ | ||
1095 | if (dev != NULL) | ||
1096 | pcibios_fixup_bridge(bus); | 1062 | pcibios_fixup_bridge(bus); |
1097 | 1063 | ||
1098 | /* Additional setup that is different between 32 and 64 bits for now */ | 1064 | /* Platform specific bus fixups. This is currently only used |
1099 | pcibios_do_bus_setup(bus); | 1065 | * by fsl_pci and I'm hoping to get rid of it at some point |
1100 | 1066 | */ | |
1101 | /* Platform specific bus fixups */ | ||
1102 | if (ppc_md.pcibios_fixup_bus) | 1067 | if (ppc_md.pcibios_fixup_bus) |
1103 | ppc_md.pcibios_fixup_bus(bus); | 1068 | ppc_md.pcibios_fixup_bus(bus); |
1104 | 1069 | ||
1105 | /* Read default IRQs and fixup if necessary */ | 1070 | /* Setup bus DMA mappings */ |
1071 | if (ppc_md.pci_dma_bus_setup) | ||
1072 | ppc_md.pci_dma_bus_setup(bus); | ||
1073 | } | ||
1074 | |||
1075 | void __devinit pcibios_setup_bus_devices(struct pci_bus *bus) | ||
1076 | { | ||
1077 | struct pci_dev *dev; | ||
1078 | |||
1079 | pr_debug("PCI: Fixup bus devices %d (%s)\n", | ||
1080 | bus->number, bus->self ? pci_name(bus->self) : "PHB"); | ||
1081 | |||
1106 | list_for_each_entry(dev, &bus->devices, bus_list) { | 1082 | list_for_each_entry(dev, &bus->devices, bus_list) { |
1083 | struct dev_archdata *sd = &dev->dev.archdata; | ||
1084 | |||
1085 | /* Setup OF node pointer in archdata */ | ||
1086 | sd->of_node = pci_device_to_OF_node(dev); | ||
1087 | |||
1088 | /* Fixup NUMA node as it may not be setup yet by the generic | ||
1089 | * code and is needed by the DMA init | ||
1090 | */ | ||
1091 | set_dev_node(&dev->dev, pcibus_to_node(dev->bus)); | ||
1092 | |||
1093 | /* Hook up default DMA ops */ | ||
1094 | sd->dma_ops = pci_dma_ops; | ||
1095 | sd->dma_data = (void *)PCI_DRAM_OFFSET; | ||
1096 | |||
1097 | /* Additional platform DMA/iommu setup */ | ||
1098 | if (ppc_md.pci_dma_dev_setup) | ||
1099 | ppc_md.pci_dma_dev_setup(dev); | ||
1100 | |||
1101 | /* Read default IRQs and fixup if necessary */ | ||
1107 | pci_read_irq_line(dev); | 1102 | pci_read_irq_line(dev); |
1108 | if (ppc_md.pci_irq_fixup) | 1103 | if (ppc_md.pci_irq_fixup) |
1109 | ppc_md.pci_irq_fixup(dev); | 1104 | ppc_md.pci_irq_fixup(dev); |
@@ -1113,22 +1108,19 @@ static void __devinit __pcibios_fixup_bus(struct pci_bus *bus) | |||
1113 | void __devinit pcibios_fixup_bus(struct pci_bus *bus) | 1108 | void __devinit pcibios_fixup_bus(struct pci_bus *bus) |
1114 | { | 1109 | { |
1115 | /* When called from the generic PCI probe, read PCI<->PCI bridge | 1110 | /* When called from the generic PCI probe, read PCI<->PCI bridge |
1116 | * bases before proceeding | 1111 | * bases. This is -not- called when generating the PCI tree from |
1112 | * the OF device-tree. | ||
1117 | */ | 1113 | */ |
1118 | if (bus->self != NULL) | 1114 | if (bus->self != NULL) |
1119 | pci_read_bridge_bases(bus); | 1115 | pci_read_bridge_bases(bus); |
1120 | __pcibios_fixup_bus(bus); | ||
1121 | } | ||
1122 | EXPORT_SYMBOL(pcibios_fixup_bus); | ||
1123 | 1116 | ||
1124 | /* When building a bus from the OF tree rather than probing, we need a | 1117 | /* Now fixup the bus bus */ |
1125 | * slightly different version of the fixup which doesn't read the | 1118 | pcibios_setup_bus_self(bus); |
1126 | * bridge bases using config space accesses | 1119 | |
1127 | */ | 1120 | /* Now fixup devices on that bus */ |
1128 | void __devinit pcibios_fixup_of_probed_bus(struct pci_bus *bus) | 1121 | pcibios_setup_bus_devices(bus); |
1129 | { | ||
1130 | __pcibios_fixup_bus(bus); | ||
1131 | } | 1122 | } |
1123 | EXPORT_SYMBOL(pcibios_fixup_bus); | ||
1132 | 1124 | ||
1133 | static int skip_isa_ioresource_align(struct pci_dev *dev) | 1125 | static int skip_isa_ioresource_align(struct pci_dev *dev) |
1134 | { | 1126 | { |
@@ -1198,10 +1190,10 @@ static int __init reparent_resources(struct resource *parent, | |||
1198 | *pp = NULL; | 1190 | *pp = NULL; |
1199 | for (p = res->child; p != NULL; p = p->sibling) { | 1191 | for (p = res->child; p != NULL; p = p->sibling) { |
1200 | p->parent = res; | 1192 | p->parent = res; |
1201 | DBG(KERN_INFO "PCI: reparented %s [%llx..%llx] under %s\n", | 1193 | pr_debug("PCI: Reparented %s [%llx..%llx] under %s\n", |
1202 | p->name, | 1194 | p->name, |
1203 | (unsigned long long)p->start, | 1195 | (unsigned long long)p->start, |
1204 | (unsigned long long)p->end, res->name); | 1196 | (unsigned long long)p->end, res->name); |
1205 | } | 1197 | } |
1206 | return 0; | 1198 | return 0; |
1207 | } | 1199 | } |
@@ -1245,9 +1237,12 @@ void pcibios_allocate_bus_resources(struct pci_bus *bus) | |||
1245 | int i; | 1237 | int i; |
1246 | struct resource *res, *pr; | 1238 | struct resource *res, *pr; |
1247 | 1239 | ||
1240 | pr_debug("PCI: Allocating bus resources for %04x:%02x...\n", | ||
1241 | pci_domain_nr(bus), bus->number); | ||
1242 | |||
1248 | for (i = 0; i < PCI_BUS_NUM_RESOURCES; ++i) { | 1243 | for (i = 0; i < PCI_BUS_NUM_RESOURCES; ++i) { |
1249 | if ((res = bus->resource[i]) == NULL || !res->flags | 1244 | if ((res = bus->resource[i]) == NULL || !res->flags |
1250 | || res->start > res->end) | 1245 | || res->start > res->end || res->parent) |
1251 | continue; | 1246 | continue; |
1252 | if (bus->parent == NULL) | 1247 | if (bus->parent == NULL) |
1253 | pr = (res->flags & IORESOURCE_IO) ? | 1248 | pr = (res->flags & IORESOURCE_IO) ? |
@@ -1271,14 +1266,14 @@ void pcibios_allocate_bus_resources(struct pci_bus *bus) | |||
1271 | } | 1266 | } |
1272 | } | 1267 | } |
1273 | 1268 | ||
1274 | DBG("PCI: %s (bus %d) bridge rsrc %d: %016llx-%016llx " | 1269 | pr_debug("PCI: %s (bus %d) bridge rsrc %d: %016llx-%016llx " |
1275 | "[0x%x], parent %p (%s)\n", | 1270 | "[0x%x], parent %p (%s)\n", |
1276 | bus->self ? pci_name(bus->self) : "PHB", | 1271 | bus->self ? pci_name(bus->self) : "PHB", |
1277 | bus->number, i, | 1272 | bus->number, i, |
1278 | (unsigned long long)res->start, | 1273 | (unsigned long long)res->start, |
1279 | (unsigned long long)res->end, | 1274 | (unsigned long long)res->end, |
1280 | (unsigned int)res->flags, | 1275 | (unsigned int)res->flags, |
1281 | pr, (pr && pr->name) ? pr->name : "nil"); | 1276 | pr, (pr && pr->name) ? pr->name : "nil"); |
1282 | 1277 | ||
1283 | if (pr && !(pr->flags & IORESOURCE_UNSET)) { | 1278 | if (pr && !(pr->flags & IORESOURCE_UNSET)) { |
1284 | if (request_resource(pr, res) == 0) | 1279 | if (request_resource(pr, res) == 0) |
@@ -1305,11 +1300,11 @@ static inline void __devinit alloc_resource(struct pci_dev *dev, int idx) | |||
1305 | { | 1300 | { |
1306 | struct resource *pr, *r = &dev->resource[idx]; | 1301 | struct resource *pr, *r = &dev->resource[idx]; |
1307 | 1302 | ||
1308 | DBG("PCI: Allocating %s: Resource %d: %016llx..%016llx [%x]\n", | 1303 | pr_debug("PCI: Allocating %s: Resource %d: %016llx..%016llx [%x]\n", |
1309 | pci_name(dev), idx, | 1304 | pci_name(dev), idx, |
1310 | (unsigned long long)r->start, | 1305 | (unsigned long long)r->start, |
1311 | (unsigned long long)r->end, | 1306 | (unsigned long long)r->end, |
1312 | (unsigned int)r->flags); | 1307 | (unsigned int)r->flags); |
1313 | 1308 | ||
1314 | pr = pci_find_parent_resource(dev, r); | 1309 | pr = pci_find_parent_resource(dev, r); |
1315 | if (!pr || (pr->flags & IORESOURCE_UNSET) || | 1310 | if (!pr || (pr->flags & IORESOURCE_UNSET) || |
@@ -1317,10 +1312,11 @@ static inline void __devinit alloc_resource(struct pci_dev *dev, int idx) | |||
1317 | printk(KERN_WARNING "PCI: Cannot allocate resource region %d" | 1312 | printk(KERN_WARNING "PCI: Cannot allocate resource region %d" |
1318 | " of device %s, will remap\n", idx, pci_name(dev)); | 1313 | " of device %s, will remap\n", idx, pci_name(dev)); |
1319 | if (pr) | 1314 | if (pr) |
1320 | DBG("PCI: parent is %p: %016llx-%016llx [%x]\n", pr, | 1315 | pr_debug("PCI: parent is %p: %016llx-%016llx [%x]\n", |
1321 | (unsigned long long)pr->start, | 1316 | pr, |
1322 | (unsigned long long)pr->end, | 1317 | (unsigned long long)pr->start, |
1323 | (unsigned int)pr->flags); | 1318 | (unsigned long long)pr->end, |
1319 | (unsigned int)pr->flags); | ||
1324 | /* We'll assign a new address later */ | 1320 | /* We'll assign a new address later */ |
1325 | r->flags |= IORESOURCE_UNSET; | 1321 | r->flags |= IORESOURCE_UNSET; |
1326 | r->end -= r->start; | 1322 | r->end -= r->start; |
@@ -1358,7 +1354,8 @@ static void __init pcibios_allocate_resources(int pass) | |||
1358 | * but keep it unregistered. | 1354 | * but keep it unregistered. |
1359 | */ | 1355 | */ |
1360 | u32 reg; | 1356 | u32 reg; |
1361 | DBG("PCI: Switching off ROM of %s\n", pci_name(dev)); | 1357 | pr_debug("PCI: Switching off ROM of %s\n", |
1358 | pci_name(dev)); | ||
1362 | r->flags &= ~IORESOURCE_ROM_ENABLE; | 1359 | r->flags &= ~IORESOURCE_ROM_ENABLE; |
1363 | pci_read_config_dword(dev, dev->rom_base_reg, ®); | 1360 | pci_read_config_dword(dev, dev->rom_base_reg, ®); |
1364 | pci_write_config_dword(dev, dev->rom_base_reg, | 1361 | pci_write_config_dword(dev, dev->rom_base_reg, |
@@ -1383,7 +1380,7 @@ void __init pcibios_resource_survey(void) | |||
1383 | } | 1380 | } |
1384 | 1381 | ||
1385 | if (!(ppc_pci_flags & PPC_PCI_PROBE_ONLY)) { | 1382 | if (!(ppc_pci_flags & PPC_PCI_PROBE_ONLY)) { |
1386 | DBG("PCI: Assigning unassigned resouces...\n"); | 1383 | pr_debug("PCI: Assigning unassigned resouces...\n"); |
1387 | pci_assign_unassigned_resources(); | 1384 | pci_assign_unassigned_resources(); |
1388 | } | 1385 | } |
1389 | 1386 | ||
@@ -1393,9 +1390,11 @@ void __init pcibios_resource_survey(void) | |||
1393 | } | 1390 | } |
1394 | 1391 | ||
1395 | #ifdef CONFIG_HOTPLUG | 1392 | #ifdef CONFIG_HOTPLUG |
1396 | /* This is used by the pSeries hotplug driver to allocate resource | 1393 | |
1394 | /* This is used by the PCI hotplug driver to allocate resource | ||
1397 | * of newly plugged busses. We can try to consolidate with the | 1395 | * of newly plugged busses. We can try to consolidate with the |
1398 | * rest of the code later, for now, keep it as-is | 1396 | * rest of the code later, for now, keep it as-is as our main |
1397 | * resource allocation function doesn't deal with sub-trees yet. | ||
1399 | */ | 1398 | */ |
1400 | void __devinit pcibios_claim_one_bus(struct pci_bus *bus) | 1399 | void __devinit pcibios_claim_one_bus(struct pci_bus *bus) |
1401 | { | 1400 | { |
@@ -1410,6 +1409,14 @@ void __devinit pcibios_claim_one_bus(struct pci_bus *bus) | |||
1410 | 1409 | ||
1411 | if (r->parent || !r->start || !r->flags) | 1410 | if (r->parent || !r->start || !r->flags) |
1412 | continue; | 1411 | continue; |
1412 | |||
1413 | pr_debug("PCI: Claiming %s: " | ||
1414 | "Resource %d: %016llx..%016llx [%x]\n", | ||
1415 | pci_name(dev), i, | ||
1416 | (unsigned long long)r->start, | ||
1417 | (unsigned long long)r->end, | ||
1418 | (unsigned int)r->flags); | ||
1419 | |||
1413 | pci_claim_resource(dev, i); | 1420 | pci_claim_resource(dev, i); |
1414 | } | 1421 | } |
1415 | } | 1422 | } |
@@ -1418,6 +1425,31 @@ void __devinit pcibios_claim_one_bus(struct pci_bus *bus) | |||
1418 | pcibios_claim_one_bus(child_bus); | 1425 | pcibios_claim_one_bus(child_bus); |
1419 | } | 1426 | } |
1420 | EXPORT_SYMBOL_GPL(pcibios_claim_one_bus); | 1427 | EXPORT_SYMBOL_GPL(pcibios_claim_one_bus); |
1428 | |||
1429 | |||
1430 | /* pcibios_finish_adding_to_bus | ||
1431 | * | ||
1432 | * This is to be called by the hotplug code after devices have been | ||
1433 | * added to a bus, this include calling it for a PHB that is just | ||
1434 | * being added | ||
1435 | */ | ||
1436 | void pcibios_finish_adding_to_bus(struct pci_bus *bus) | ||
1437 | { | ||
1438 | pr_debug("PCI: Finishing adding to hotplug bus %04x:%02x\n", | ||
1439 | pci_domain_nr(bus), bus->number); | ||
1440 | |||
1441 | /* Allocate bus and devices resources */ | ||
1442 | pcibios_allocate_bus_resources(bus); | ||
1443 | pcibios_claim_one_bus(bus); | ||
1444 | |||
1445 | /* Add new devices to global lists. Register in proc, sysfs. */ | ||
1446 | pci_bus_add_devices(bus); | ||
1447 | |||
1448 | /* Fixup EEH */ | ||
1449 | eeh_add_device_tree_late(bus); | ||
1450 | } | ||
1451 | EXPORT_SYMBOL_GPL(pcibios_finish_adding_to_bus); | ||
1452 | |||
1421 | #endif /* CONFIG_HOTPLUG */ | 1453 | #endif /* CONFIG_HOTPLUG */ |
1422 | 1454 | ||
1423 | int pcibios_enable_device(struct pci_dev *dev, int mask) | 1455 | int pcibios_enable_device(struct pci_dev *dev, int mask) |
@@ -1428,3 +1460,61 @@ int pcibios_enable_device(struct pci_dev *dev, int mask) | |||
1428 | 1460 | ||
1429 | return pci_enable_resources(dev, mask); | 1461 | return pci_enable_resources(dev, mask); |
1430 | } | 1462 | } |
1463 | |||
1464 | void __devinit pcibios_setup_phb_resources(struct pci_controller *hose) | ||
1465 | { | ||
1466 | struct pci_bus *bus = hose->bus; | ||
1467 | struct resource *res; | ||
1468 | int i; | ||
1469 | |||
1470 | /* Hookup PHB IO resource */ | ||
1471 | bus->resource[0] = res = &hose->io_resource; | ||
1472 | |||
1473 | if (!res->flags) { | ||
1474 | printk(KERN_WARNING "PCI: I/O resource not set for host" | ||
1475 | " bridge %s (domain %d)\n", | ||
1476 | hose->dn->full_name, hose->global_number); | ||
1477 | #ifdef CONFIG_PPC32 | ||
1478 | /* Workaround for lack of IO resource only on 32-bit */ | ||
1479 | res->start = (unsigned long)hose->io_base_virt - isa_io_base; | ||
1480 | res->end = res->start + IO_SPACE_LIMIT; | ||
1481 | res->flags = IORESOURCE_IO; | ||
1482 | #endif /* CONFIG_PPC32 */ | ||
1483 | } | ||
1484 | |||
1485 | pr_debug("PCI: PHB IO resource = %016llx-%016llx [%lx]\n", | ||
1486 | (unsigned long long)res->start, | ||
1487 | (unsigned long long)res->end, | ||
1488 | (unsigned long)res->flags); | ||
1489 | |||
1490 | /* Hookup PHB Memory resources */ | ||
1491 | for (i = 0; i < 3; ++i) { | ||
1492 | res = &hose->mem_resources[i]; | ||
1493 | if (!res->flags) { | ||
1494 | if (i > 0) | ||
1495 | continue; | ||
1496 | printk(KERN_ERR "PCI: Memory resource 0 not set for " | ||
1497 | "host bridge %s (domain %d)\n", | ||
1498 | hose->dn->full_name, hose->global_number); | ||
1499 | #ifdef CONFIG_PPC32 | ||
1500 | /* Workaround for lack of MEM resource only on 32-bit */ | ||
1501 | res->start = hose->pci_mem_offset; | ||
1502 | res->end = (resource_size_t)-1LL; | ||
1503 | res->flags = IORESOURCE_MEM; | ||
1504 | #endif /* CONFIG_PPC32 */ | ||
1505 | } | ||
1506 | bus->resource[i+1] = res; | ||
1507 | |||
1508 | pr_debug("PCI: PHB MEM resource %d = %016llx-%016llx [%lx]\n", i, | ||
1509 | (unsigned long long)res->start, | ||
1510 | (unsigned long long)res->end, | ||
1511 | (unsigned long)res->flags); | ||
1512 | } | ||
1513 | |||
1514 | pr_debug("PCI: PHB MEM offset = %016llx\n", | ||
1515 | (unsigned long long)hose->pci_mem_offset); | ||
1516 | pr_debug("PCI: PHB IO offset = %08lx\n", | ||
1517 | (unsigned long)hose->io_base_virt - _IO_BASE); | ||
1518 | |||
1519 | } | ||
1520 | |||
diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c index 131b1dfa68c6..7ad11e592f2b 100644 --- a/arch/powerpc/kernel/pci_32.c +++ b/arch/powerpc/kernel/pci_32.c | |||
@@ -26,12 +26,6 @@ | |||
26 | 26 | ||
27 | #undef DEBUG | 27 | #undef DEBUG |
28 | 28 | ||
29 | #ifdef DEBUG | ||
30 | #define DBG(x...) printk(x) | ||
31 | #else | ||
32 | #define DBG(x...) | ||
33 | #endif | ||
34 | |||
35 | unsigned long isa_io_base = 0; | 29 | unsigned long isa_io_base = 0; |
36 | unsigned long pci_dram_offset = 0; | 30 | unsigned long pci_dram_offset = 0; |
37 | int pcibios_assign_bus_offset = 1; | 31 | int pcibios_assign_bus_offset = 1; |
@@ -275,14 +269,14 @@ pci_busdev_to_OF_node(struct pci_bus *bus, int devfn) | |||
275 | if (!have_of) | 269 | if (!have_of) |
276 | return NULL; | 270 | return NULL; |
277 | 271 | ||
278 | DBG("pci_busdev_to_OF_node(%d,0x%x)\n", bus->number, devfn); | 272 | pr_debug("pci_busdev_to_OF_node(%d,0x%x)\n", bus->number, devfn); |
279 | parent = scan_OF_for_pci_bus(bus); | 273 | parent = scan_OF_for_pci_bus(bus); |
280 | if (parent == NULL) | 274 | if (parent == NULL) |
281 | return NULL; | 275 | return NULL; |
282 | DBG(" parent is %s\n", parent ? parent->full_name : "<NULL>"); | 276 | pr_debug(" parent is %s\n", parent ? parent->full_name : "<NULL>"); |
283 | np = scan_OF_for_pci_dev(parent, devfn); | 277 | np = scan_OF_for_pci_dev(parent, devfn); |
284 | of_node_put(parent); | 278 | of_node_put(parent); |
285 | DBG(" result is %s\n", np ? np->full_name : "<NULL>"); | 279 | pr_debug(" result is %s\n", np ? np->full_name : "<NULL>"); |
286 | 280 | ||
287 | /* XXX most callers don't release the returned node | 281 | /* XXX most callers don't release the returned node |
288 | * mostly because ppc64 doesn't increase the refcount, | 282 | * mostly because ppc64 doesn't increase the refcount, |
@@ -379,10 +373,41 @@ void pcibios_make_OF_bus_map(void) | |||
379 | } | 373 | } |
380 | #endif /* CONFIG_PPC_OF */ | 374 | #endif /* CONFIG_PPC_OF */ |
381 | 375 | ||
376 | static void __devinit pcibios_scan_phb(struct pci_controller *hose) | ||
377 | { | ||
378 | struct pci_bus *bus; | ||
379 | struct device_node *node = hose->dn; | ||
380 | unsigned long io_offset; | ||
381 | struct resource *res = &hose->io_resource; | ||
382 | |||
383 | pr_debug("PCI: Scanning PHB %s\n", | ||
384 | node ? node->full_name : "<NO NAME>"); | ||
385 | |||
386 | /* Create an empty bus for the toplevel */ | ||
387 | bus = pci_create_bus(hose->parent, hose->first_busno, hose->ops, hose); | ||
388 | if (bus == NULL) { | ||
389 | printk(KERN_ERR "Failed to create bus for PCI domain %04x\n", | ||
390 | hose->global_number); | ||
391 | return; | ||
392 | } | ||
393 | bus->secondary = hose->first_busno; | ||
394 | hose->bus = bus; | ||
395 | |||
396 | /* Fixup IO space offset */ | ||
397 | io_offset = (unsigned long)hose->io_base_virt - isa_io_base; | ||
398 | res->start = (res->start + io_offset) & 0xffffffffu; | ||
399 | res->end = (res->end + io_offset) & 0xffffffffu; | ||
400 | |||
401 | /* Wire up PHB bus resources */ | ||
402 | pcibios_setup_phb_resources(hose); | ||
403 | |||
404 | /* Scan children */ | ||
405 | hose->last_busno = bus->subordinate = pci_scan_child_bus(bus); | ||
406 | } | ||
407 | |||
382 | static int __init pcibios_init(void) | 408 | static int __init pcibios_init(void) |
383 | { | 409 | { |
384 | struct pci_controller *hose, *tmp; | 410 | struct pci_controller *hose, *tmp; |
385 | struct pci_bus *bus; | ||
386 | int next_busno = 0; | 411 | int next_busno = 0; |
387 | 412 | ||
388 | printk(KERN_INFO "PCI: Probing PCI hardware\n"); | 413 | printk(KERN_INFO "PCI: Probing PCI hardware\n"); |
@@ -395,12 +420,8 @@ static int __init pcibios_init(void) | |||
395 | if (pci_assign_all_buses) | 420 | if (pci_assign_all_buses) |
396 | hose->first_busno = next_busno; | 421 | hose->first_busno = next_busno; |
397 | hose->last_busno = 0xff; | 422 | hose->last_busno = 0xff; |
398 | bus = pci_scan_bus_parented(hose->parent, hose->first_busno, | 423 | pcibios_scan_phb(hose); |
399 | hose->ops, hose); | 424 | pci_bus_add_devices(hose->bus); |
400 | if (bus) { | ||
401 | pci_bus_add_devices(bus); | ||
402 | hose->last_busno = bus->subordinate; | ||
403 | } | ||
404 | if (pci_assign_all_buses || next_busno <= hose->last_busno) | 425 | if (pci_assign_all_buses || next_busno <= hose->last_busno) |
405 | next_busno = hose->last_busno + pcibios_assign_bus_offset; | 426 | next_busno = hose->last_busno + pcibios_assign_bus_offset; |
406 | } | 427 | } |
@@ -425,54 +446,6 @@ static int __init pcibios_init(void) | |||
425 | 446 | ||
426 | subsys_initcall(pcibios_init); | 447 | subsys_initcall(pcibios_init); |
427 | 448 | ||
428 | void __devinit pcibios_do_bus_setup(struct pci_bus *bus) | ||
429 | { | ||
430 | struct pci_controller *hose = (struct pci_controller *) bus->sysdata; | ||
431 | unsigned long io_offset; | ||
432 | struct resource *res; | ||
433 | int i; | ||
434 | struct pci_dev *dev; | ||
435 | |||
436 | /* Hookup PHB resources */ | ||
437 | io_offset = (unsigned long)hose->io_base_virt - isa_io_base; | ||
438 | if (bus->parent == NULL) { | ||
439 | /* This is a host bridge - fill in its resources */ | ||
440 | hose->bus = bus; | ||
441 | |||
442 | bus->resource[0] = res = &hose->io_resource; | ||
443 | if (!res->flags) { | ||
444 | if (io_offset) | ||
445 | printk(KERN_ERR "I/O resource not set for host" | ||
446 | " bridge %d\n", hose->global_number); | ||
447 | res->start = 0; | ||
448 | res->end = IO_SPACE_LIMIT; | ||
449 | res->flags = IORESOURCE_IO; | ||
450 | } | ||
451 | res->start = (res->start + io_offset) & 0xffffffffu; | ||
452 | res->end = (res->end + io_offset) & 0xffffffffu; | ||
453 | |||
454 | for (i = 0; i < 3; ++i) { | ||
455 | res = &hose->mem_resources[i]; | ||
456 | if (!res->flags) { | ||
457 | if (i > 0) | ||
458 | continue; | ||
459 | printk(KERN_ERR "Memory resource not set for " | ||
460 | "host bridge %d\n", hose->global_number); | ||
461 | res->start = hose->pci_mem_offset; | ||
462 | res->end = ~0U; | ||
463 | res->flags = IORESOURCE_MEM; | ||
464 | } | ||
465 | bus->resource[i+1] = res; | ||
466 | } | ||
467 | } | ||
468 | |||
469 | if (ppc_md.pci_dma_bus_setup) | ||
470 | ppc_md.pci_dma_bus_setup(bus); | ||
471 | |||
472 | list_for_each_entry(dev, &bus->devices, bus_list) | ||
473 | pcibios_setup_new_device(dev); | ||
474 | } | ||
475 | |||
476 | /* the next one is stolen from the alpha port... */ | 449 | /* the next one is stolen from the alpha port... */ |
477 | void __init | 450 | void __init |
478 | pcibios_update_irq(struct pci_dev *dev, int irq) | 451 | pcibios_update_irq(struct pci_dev *dev, int irq) |
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c index 3502b9101e6b..39fadc6e1492 100644 --- a/arch/powerpc/kernel/pci_64.c +++ b/arch/powerpc/kernel/pci_64.c | |||
@@ -32,13 +32,6 @@ | |||
32 | #include <asm/machdep.h> | 32 | #include <asm/machdep.h> |
33 | #include <asm/ppc-pci.h> | 33 | #include <asm/ppc-pci.h> |
34 | 34 | ||
35 | #ifdef DEBUG | ||
36 | #include <asm/udbg.h> | ||
37 | #define DBG(fmt...) printk(fmt) | ||
38 | #else | ||
39 | #define DBG(fmt...) | ||
40 | #endif | ||
41 | |||
42 | unsigned long pci_probe_only = 1; | 35 | unsigned long pci_probe_only = 1; |
43 | 36 | ||
44 | /* pci_io_base -- the base address from which io bars are offsets. | 37 | /* pci_io_base -- the base address from which io bars are offsets. |
@@ -102,7 +95,7 @@ static void pci_parse_of_addrs(struct device_node *node, struct pci_dev *dev) | |||
102 | addrs = of_get_property(node, "assigned-addresses", &proplen); | 95 | addrs = of_get_property(node, "assigned-addresses", &proplen); |
103 | if (!addrs) | 96 | if (!addrs) |
104 | return; | 97 | return; |
105 | DBG(" parse addresses (%d bytes) @ %p\n", proplen, addrs); | 98 | pr_debug(" parse addresses (%d bytes) @ %p\n", proplen, addrs); |
106 | for (; proplen >= 20; proplen -= 20, addrs += 5) { | 99 | for (; proplen >= 20; proplen -= 20, addrs += 5) { |
107 | flags = pci_parse_of_flags(addrs[0]); | 100 | flags = pci_parse_of_flags(addrs[0]); |
108 | if (!flags) | 101 | if (!flags) |
@@ -112,8 +105,9 @@ static void pci_parse_of_addrs(struct device_node *node, struct pci_dev *dev) | |||
112 | if (!size) | 105 | if (!size) |
113 | continue; | 106 | continue; |
114 | i = addrs[0] & 0xff; | 107 | i = addrs[0] & 0xff; |
115 | DBG(" base: %llx, size: %llx, i: %x\n", | 108 | pr_debug(" base: %llx, size: %llx, i: %x\n", |
116 | (unsigned long long)base, (unsigned long long)size, i); | 109 | (unsigned long long)base, |
110 | (unsigned long long)size, i); | ||
117 | 111 | ||
118 | if (PCI_BASE_ADDRESS_0 <= i && i <= PCI_BASE_ADDRESS_5) { | 112 | if (PCI_BASE_ADDRESS_0 <= i && i <= PCI_BASE_ADDRESS_5) { |
119 | res = &dev->resource[(i - PCI_BASE_ADDRESS_0) >> 2]; | 113 | res = &dev->resource[(i - PCI_BASE_ADDRESS_0) >> 2]; |
@@ -144,7 +138,7 @@ struct pci_dev *of_create_pci_dev(struct device_node *node, | |||
144 | if (type == NULL) | 138 | if (type == NULL) |
145 | type = ""; | 139 | type = ""; |
146 | 140 | ||
147 | DBG(" create device, devfn: %x, type: %s\n", devfn, type); | 141 | pr_debug(" create device, devfn: %x, type: %s\n", devfn, type); |
148 | 142 | ||
149 | dev->bus = bus; | 143 | dev->bus = bus; |
150 | dev->sysdata = node; | 144 | dev->sysdata = node; |
@@ -165,8 +159,8 @@ struct pci_dev *of_create_pci_dev(struct device_node *node, | |||
165 | dev->class = get_int_prop(node, "class-code", 0); | 159 | dev->class = get_int_prop(node, "class-code", 0); |
166 | dev->revision = get_int_prop(node, "revision-id", 0); | 160 | dev->revision = get_int_prop(node, "revision-id", 0); |
167 | 161 | ||
168 | DBG(" class: 0x%x\n", dev->class); | 162 | pr_debug(" class: 0x%x\n", dev->class); |
169 | DBG(" revision: 0x%x\n", dev->revision); | 163 | pr_debug(" revision: 0x%x\n", dev->revision); |
170 | 164 | ||
171 | dev->current_state = 4; /* unknown power state */ | 165 | dev->current_state = 4; /* unknown power state */ |
172 | dev->error_state = pci_channel_io_normal; | 166 | dev->error_state = pci_channel_io_normal; |
@@ -187,7 +181,7 @@ struct pci_dev *of_create_pci_dev(struct device_node *node, | |||
187 | 181 | ||
188 | pci_parse_of_addrs(node, dev); | 182 | pci_parse_of_addrs(node, dev); |
189 | 183 | ||
190 | DBG(" adding to system ...\n"); | 184 | pr_debug(" adding to system ...\n"); |
191 | 185 | ||
192 | pci_device_add(dev, bus); | 186 | pci_device_add(dev, bus); |
193 | 187 | ||
@@ -195,19 +189,20 @@ struct pci_dev *of_create_pci_dev(struct device_node *node, | |||
195 | } | 189 | } |
196 | EXPORT_SYMBOL(of_create_pci_dev); | 190 | EXPORT_SYMBOL(of_create_pci_dev); |
197 | 191 | ||
198 | void __devinit of_scan_bus(struct device_node *node, | 192 | static void __devinit __of_scan_bus(struct device_node *node, |
199 | struct pci_bus *bus) | 193 | struct pci_bus *bus, int rescan_existing) |
200 | { | 194 | { |
201 | struct device_node *child; | 195 | struct device_node *child; |
202 | const u32 *reg; | 196 | const u32 *reg; |
203 | int reglen, devfn; | 197 | int reglen, devfn; |
204 | struct pci_dev *dev; | 198 | struct pci_dev *dev; |
205 | 199 | ||
206 | DBG("of_scan_bus(%s) bus no %d... \n", node->full_name, bus->number); | 200 | pr_debug("of_scan_bus(%s) bus no %d... \n", |
201 | node->full_name, bus->number); | ||
207 | 202 | ||
208 | /* Scan direct children */ | 203 | /* Scan direct children */ |
209 | for_each_child_of_node(node, child) { | 204 | for_each_child_of_node(node, child) { |
210 | DBG(" * %s\n", child->full_name); | 205 | pr_debug(" * %s\n", child->full_name); |
211 | reg = of_get_property(child, "reg", ®len); | 206 | reg = of_get_property(child, "reg", ®len); |
212 | if (reg == NULL || reglen < 20) | 207 | if (reg == NULL || reglen < 20) |
213 | continue; | 208 | continue; |
@@ -217,11 +212,15 @@ void __devinit of_scan_bus(struct device_node *node, | |||
217 | dev = of_create_pci_dev(child, bus, devfn); | 212 | dev = of_create_pci_dev(child, bus, devfn); |
218 | if (!dev) | 213 | if (!dev) |
219 | continue; | 214 | continue; |
220 | DBG(" dev header type: %x\n", dev->hdr_type); | 215 | pr_debug(" dev header type: %x\n", dev->hdr_type); |
221 | } | 216 | } |
222 | 217 | ||
223 | /* Ally all fixups */ | 218 | /* Apply all fixups necessary. We don't fixup the bus "self" |
224 | pcibios_fixup_of_probed_bus(bus); | 219 | * for an existing bridge that is being rescanned |
220 | */ | ||
221 | if (!rescan_existing) | ||
222 | pcibios_setup_bus_self(bus); | ||
223 | pcibios_setup_bus_devices(bus); | ||
225 | 224 | ||
226 | /* Now scan child busses */ | 225 | /* Now scan child busses */ |
227 | list_for_each_entry(dev, &bus->devices, bus_list) { | 226 | list_for_each_entry(dev, &bus->devices, bus_list) { |
@@ -233,7 +232,20 @@ void __devinit of_scan_bus(struct device_node *node, | |||
233 | } | 232 | } |
234 | } | 233 | } |
235 | } | 234 | } |
236 | EXPORT_SYMBOL(of_scan_bus); | 235 | |
236 | void __devinit of_scan_bus(struct device_node *node, | ||
237 | struct pci_bus *bus) | ||
238 | { | ||
239 | __of_scan_bus(node, bus, 0); | ||
240 | } | ||
241 | EXPORT_SYMBOL_GPL(of_scan_bus); | ||
242 | |||
243 | void __devinit of_rescan_bus(struct device_node *node, | ||
244 | struct pci_bus *bus) | ||
245 | { | ||
246 | __of_scan_bus(node, bus, 1); | ||
247 | } | ||
248 | EXPORT_SYMBOL_GPL(of_rescan_bus); | ||
237 | 249 | ||
238 | void __devinit of_scan_pci_bridge(struct device_node *node, | 250 | void __devinit of_scan_pci_bridge(struct device_node *node, |
239 | struct pci_dev *dev) | 251 | struct pci_dev *dev) |
@@ -245,7 +257,7 @@ void __devinit of_scan_pci_bridge(struct device_node *node, | |||
245 | unsigned int flags; | 257 | unsigned int flags; |
246 | u64 size; | 258 | u64 size; |
247 | 259 | ||
248 | DBG("of_scan_pci_bridge(%s)\n", node->full_name); | 260 | pr_debug("of_scan_pci_bridge(%s)\n", node->full_name); |
249 | 261 | ||
250 | /* parse bus-range property */ | 262 | /* parse bus-range property */ |
251 | busrange = of_get_property(node, "bus-range", &len); | 263 | busrange = of_get_property(node, "bus-range", &len); |
@@ -309,12 +321,12 @@ void __devinit of_scan_pci_bridge(struct device_node *node, | |||
309 | } | 321 | } |
310 | sprintf(bus->name, "PCI Bus %04x:%02x", pci_domain_nr(bus), | 322 | sprintf(bus->name, "PCI Bus %04x:%02x", pci_domain_nr(bus), |
311 | bus->number); | 323 | bus->number); |
312 | DBG(" bus name: %s\n", bus->name); | 324 | pr_debug(" bus name: %s\n", bus->name); |
313 | 325 | ||
314 | mode = PCI_PROBE_NORMAL; | 326 | mode = PCI_PROBE_NORMAL; |
315 | if (ppc_md.pci_probe_mode) | 327 | if (ppc_md.pci_probe_mode) |
316 | mode = ppc_md.pci_probe_mode(bus); | 328 | mode = ppc_md.pci_probe_mode(bus); |
317 | DBG(" probe mode: %d\n", mode); | 329 | pr_debug(" probe mode: %d\n", mode); |
318 | 330 | ||
319 | if (mode == PCI_PROBE_DEVTREE) | 331 | if (mode == PCI_PROBE_DEVTREE) |
320 | of_scan_bus(node, bus); | 332 | of_scan_bus(node, bus); |
@@ -327,9 +339,10 @@ void __devinit scan_phb(struct pci_controller *hose) | |||
327 | { | 339 | { |
328 | struct pci_bus *bus; | 340 | struct pci_bus *bus; |
329 | struct device_node *node = hose->dn; | 341 | struct device_node *node = hose->dn; |
330 | int i, mode; | 342 | int mode; |
331 | 343 | ||
332 | DBG("PCI: Scanning PHB %s\n", node ? node->full_name : "<NO NAME>"); | 344 | pr_debug("PCI: Scanning PHB %s\n", |
345 | node ? node->full_name : "<NO NAME>"); | ||
333 | 346 | ||
334 | /* Create an empty bus for the toplevel */ | 347 | /* Create an empty bus for the toplevel */ |
335 | bus = pci_create_bus(hose->parent, hose->first_busno, hose->ops, node); | 348 | bus = pci_create_bus(hose->parent, hose->first_busno, hose->ops, node); |
@@ -345,26 +358,13 @@ void __devinit scan_phb(struct pci_controller *hose) | |||
345 | pcibios_map_io_space(bus); | 358 | pcibios_map_io_space(bus); |
346 | 359 | ||
347 | /* Wire up PHB bus resources */ | 360 | /* Wire up PHB bus resources */ |
348 | DBG("PCI: PHB IO resource = %016lx-%016lx [%lx]\n", | 361 | pcibios_setup_phb_resources(hose); |
349 | hose->io_resource.start, hose->io_resource.end, | ||
350 | hose->io_resource.flags); | ||
351 | bus->resource[0] = &hose->io_resource; | ||
352 | for (i = 0; i < 3; ++i) { | ||
353 | DBG("PCI: PHB MEM resource %d = %016lx-%016lx [%lx]\n", i, | ||
354 | hose->mem_resources[i].start, | ||
355 | hose->mem_resources[i].end, | ||
356 | hose->mem_resources[i].flags); | ||
357 | bus->resource[i+1] = &hose->mem_resources[i]; | ||
358 | } | ||
359 | DBG("PCI: PHB MEM offset = %016lx\n", hose->pci_mem_offset); | ||
360 | DBG("PCI: PHB IO offset = %08lx\n", | ||
361 | (unsigned long)hose->io_base_virt - _IO_BASE); | ||
362 | 362 | ||
363 | /* Get probe mode and perform scan */ | 363 | /* Get probe mode and perform scan */ |
364 | mode = PCI_PROBE_NORMAL; | 364 | mode = PCI_PROBE_NORMAL; |
365 | if (node && ppc_md.pci_probe_mode) | 365 | if (node && ppc_md.pci_probe_mode) |
366 | mode = ppc_md.pci_probe_mode(bus); | 366 | mode = ppc_md.pci_probe_mode(bus); |
367 | DBG(" probe mode: %d\n", mode); | 367 | pr_debug(" probe mode: %d\n", mode); |
368 | if (mode == PCI_PROBE_DEVTREE) { | 368 | if (mode == PCI_PROBE_DEVTREE) { |
369 | bus->subordinate = hose->last_busno; | 369 | bus->subordinate = hose->last_busno; |
370 | of_scan_bus(node, bus); | 370 | of_scan_bus(node, bus); |
@@ -380,7 +380,7 @@ static int __init pcibios_init(void) | |||
380 | 380 | ||
381 | printk(KERN_INFO "PCI: Probing PCI hardware\n"); | 381 | printk(KERN_INFO "PCI: Probing PCI hardware\n"); |
382 | 382 | ||
383 | /* For now, override phys_mem_access_prot. If we need it, | 383 | /* For now, override phys_mem_access_prot. If we need it,g |
384 | * later, we may move that initialization to each ppc_md | 384 | * later, we may move that initialization to each ppc_md |
385 | */ | 385 | */ |
386 | ppc_md.phys_mem_access_prot = pci_phys_mem_access_prot; | 386 | ppc_md.phys_mem_access_prot = pci_phys_mem_access_prot; |
@@ -388,6 +388,11 @@ static int __init pcibios_init(void) | |||
388 | if (pci_probe_only) | 388 | if (pci_probe_only) |
389 | ppc_pci_flags |= PPC_PCI_PROBE_ONLY; | 389 | ppc_pci_flags |= PPC_PCI_PROBE_ONLY; |
390 | 390 | ||
391 | /* On ppc64, we always enable PCI domains and we keep domain 0 | ||
392 | * backward compatible in /proc for video cards | ||
393 | */ | ||
394 | ppc_pci_flags |= PPC_PCI_ENABLE_PROC_DOMAINS | PPC_PCI_COMPAT_DOMAIN_0; | ||
395 | |||
391 | /* Scan all of the recorded PCI controllers. */ | 396 | /* Scan all of the recorded PCI controllers. */ |
392 | list_for_each_entry_safe(hose, tmp, &hose_list, list_node) { | 397 | list_for_each_entry_safe(hose, tmp, &hose_list, list_node) { |
393 | scan_phb(hose); | 398 | scan_phb(hose); |
@@ -422,8 +427,8 @@ int pcibios_unmap_io_space(struct pci_bus *bus) | |||
422 | if (bus->self) { | 427 | if (bus->self) { |
423 | struct resource *res = bus->resource[0]; | 428 | struct resource *res = bus->resource[0]; |
424 | 429 | ||
425 | DBG("IO unmapping for PCI-PCI bridge %s\n", | 430 | pr_debug("IO unmapping for PCI-PCI bridge %s\n", |
426 | pci_name(bus->self)); | 431 | pci_name(bus->self)); |
427 | 432 | ||
428 | __flush_hash_table_range(&init_mm, res->start + _IO_BASE, | 433 | __flush_hash_table_range(&init_mm, res->start + _IO_BASE, |
429 | res->end + _IO_BASE + 1); | 434 | res->end + _IO_BASE + 1); |
@@ -437,8 +442,8 @@ int pcibios_unmap_io_space(struct pci_bus *bus) | |||
437 | if (hose->io_base_alloc == 0) | 442 | if (hose->io_base_alloc == 0) |
438 | return 0; | 443 | return 0; |
439 | 444 | ||
440 | DBG("IO unmapping for PHB %s\n", hose->dn->full_name); | 445 | pr_debug("IO unmapping for PHB %s\n", hose->dn->full_name); |
441 | DBG(" alloc=0x%p\n", hose->io_base_alloc); | 446 | pr_debug(" alloc=0x%p\n", hose->io_base_alloc); |
442 | 447 | ||
443 | /* This is a PHB, we fully unmap the IO area */ | 448 | /* This is a PHB, we fully unmap the IO area */ |
444 | vunmap(hose->io_base_alloc); | 449 | vunmap(hose->io_base_alloc); |
@@ -463,11 +468,11 @@ int __devinit pcibios_map_io_space(struct pci_bus *bus) | |||
463 | * thus HPTEs will be faulted in when needed | 468 | * thus HPTEs will be faulted in when needed |
464 | */ | 469 | */ |
465 | if (bus->self) { | 470 | if (bus->self) { |
466 | DBG("IO mapping for PCI-PCI bridge %s\n", | 471 | pr_debug("IO mapping for PCI-PCI bridge %s\n", |
467 | pci_name(bus->self)); | 472 | pci_name(bus->self)); |
468 | DBG(" virt=0x%016lx...0x%016lx\n", | 473 | pr_debug(" virt=0x%016lx...0x%016lx\n", |
469 | bus->resource[0]->start + _IO_BASE, | 474 | bus->resource[0]->start + _IO_BASE, |
470 | bus->resource[0]->end + _IO_BASE); | 475 | bus->resource[0]->end + _IO_BASE); |
471 | return 0; | 476 | return 0; |
472 | } | 477 | } |
473 | 478 | ||
@@ -496,11 +501,11 @@ int __devinit pcibios_map_io_space(struct pci_bus *bus) | |||
496 | hose->io_base_virt = (void __iomem *)(area->addr + | 501 | hose->io_base_virt = (void __iomem *)(area->addr + |
497 | hose->io_base_phys - phys_page); | 502 | hose->io_base_phys - phys_page); |
498 | 503 | ||
499 | DBG("IO mapping for PHB %s\n", hose->dn->full_name); | 504 | pr_debug("IO mapping for PHB %s\n", hose->dn->full_name); |
500 | DBG(" phys=0x%016lx, virt=0x%p (alloc=0x%p)\n", | 505 | pr_debug(" phys=0x%016lx, virt=0x%p (alloc=0x%p)\n", |
501 | hose->io_base_phys, hose->io_base_virt, hose->io_base_alloc); | 506 | hose->io_base_phys, hose->io_base_virt, hose->io_base_alloc); |
502 | DBG(" size=0x%016lx (alloc=0x%016lx)\n", | 507 | pr_debug(" size=0x%016lx (alloc=0x%016lx)\n", |
503 | hose->pci_io_size, size_page); | 508 | hose->pci_io_size, size_page); |
504 | 509 | ||
505 | /* Establish the mapping */ | 510 | /* Establish the mapping */ |
506 | if (__ioremap_at(phys_page, area->addr, size_page, | 511 | if (__ioremap_at(phys_page, area->addr, size_page, |
@@ -512,24 +517,13 @@ int __devinit pcibios_map_io_space(struct pci_bus *bus) | |||
512 | hose->io_resource.start += io_virt_offset; | 517 | hose->io_resource.start += io_virt_offset; |
513 | hose->io_resource.end += io_virt_offset; | 518 | hose->io_resource.end += io_virt_offset; |
514 | 519 | ||
515 | DBG(" hose->io_resource=0x%016lx...0x%016lx\n", | 520 | pr_debug(" hose->io_resource=0x%016lx...0x%016lx\n", |
516 | hose->io_resource.start, hose->io_resource.end); | 521 | hose->io_resource.start, hose->io_resource.end); |
517 | 522 | ||
518 | return 0; | 523 | return 0; |
519 | } | 524 | } |
520 | EXPORT_SYMBOL_GPL(pcibios_map_io_space); | 525 | EXPORT_SYMBOL_GPL(pcibios_map_io_space); |
521 | 526 | ||
522 | void __devinit pcibios_do_bus_setup(struct pci_bus *bus) | ||
523 | { | ||
524 | struct pci_dev *dev; | ||
525 | |||
526 | if (ppc_md.pci_dma_bus_setup) | ||
527 | ppc_md.pci_dma_bus_setup(bus); | ||
528 | |||
529 | list_for_each_entry(dev, &bus->devices, bus_list) | ||
530 | pcibios_setup_new_device(dev); | ||
531 | } | ||
532 | |||
533 | unsigned long pci_address_to_pio(phys_addr_t address) | 527 | unsigned long pci_address_to_pio(phys_addr_t address) |
534 | { | 528 | { |
535 | struct pci_controller *hose, *tmp; | 529 | struct pci_controller *hose, *tmp; |
diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c index a11d68976dc8..8c1335566089 100644 --- a/arch/powerpc/kernel/prom_parse.c +++ b/arch/powerpc/kernel/prom_parse.c | |||
@@ -734,10 +734,7 @@ void of_irq_map_init(unsigned int flags) | |||
734 | if (flags & OF_IMAP_NO_PHANDLE) { | 734 | if (flags & OF_IMAP_NO_PHANDLE) { |
735 | struct device_node *np; | 735 | struct device_node *np; |
736 | 736 | ||
737 | for(np = NULL; (np = of_find_all_nodes(np)) != NULL;) { | 737 | for_each_node_with_property(np, "interrupt-controller") { |
738 | if (of_get_property(np, "interrupt-controller", NULL) | ||
739 | == NULL) | ||
740 | continue; | ||
741 | /* Skip /chosen/interrupt-controller */ | 738 | /* Skip /chosen/interrupt-controller */ |
742 | if (strcmp(np->name, "chosen") == 0) | 739 | if (strcmp(np->name, "chosen") == 0) |
743 | continue; | 740 | continue; |
diff --git a/arch/powerpc/kernel/rtas_pci.c b/arch/powerpc/kernel/rtas_pci.c index 589a2797eac2..8869001ab5d7 100644 --- a/arch/powerpc/kernel/rtas_pci.c +++ b/arch/powerpc/kernel/rtas_pci.c | |||
@@ -301,51 +301,3 @@ void __init find_and_init_phbs(void) | |||
301 | #endif /* CONFIG_PPC32 */ | 301 | #endif /* CONFIG_PPC32 */ |
302 | } | 302 | } |
303 | } | 303 | } |
304 | |||
305 | /* RPA-specific bits for removing PHBs */ | ||
306 | int pcibios_remove_root_bus(struct pci_controller *phb) | ||
307 | { | ||
308 | struct pci_bus *b = phb->bus; | ||
309 | struct resource *res; | ||
310 | int rc, i; | ||
311 | |||
312 | res = b->resource[0]; | ||
313 | if (!res->flags) { | ||
314 | printk(KERN_ERR "%s: no IO resource for PHB %s\n", __func__, | ||
315 | b->name); | ||
316 | return 1; | ||
317 | } | ||
318 | |||
319 | rc = pcibios_unmap_io_space(b); | ||
320 | if (rc) { | ||
321 | printk(KERN_ERR "%s: failed to unmap IO on bus %s\n", | ||
322 | __func__, b->name); | ||
323 | return 1; | ||
324 | } | ||
325 | |||
326 | if (release_resource(res)) { | ||
327 | printk(KERN_ERR "%s: failed to release IO on bus %s\n", | ||
328 | __func__, b->name); | ||
329 | return 1; | ||
330 | } | ||
331 | |||
332 | for (i = 1; i < 3; ++i) { | ||
333 | res = b->resource[i]; | ||
334 | if (!res->flags && i == 0) { | ||
335 | printk(KERN_ERR "%s: no MEM resource for PHB %s\n", | ||
336 | __func__, b->name); | ||
337 | return 1; | ||
338 | } | ||
339 | if (res->flags && release_resource(res)) { | ||
340 | printk(KERN_ERR | ||
341 | "%s: failed to release IO %d on bus %s\n", | ||
342 | __func__, i, b->name); | ||
343 | return 1; | ||
344 | } | ||
345 | } | ||
346 | |||
347 | pcibios_free_controller(phb); | ||
348 | |||
349 | return 0; | ||
350 | } | ||
351 | EXPORT_SYMBOL(pcibios_remove_root_bus); | ||
diff --git a/arch/powerpc/kernel/smp-tbsync.c b/arch/powerpc/kernel/smp-tbsync.c index bc892e69b4f7..a5e54526403d 100644 --- a/arch/powerpc/kernel/smp-tbsync.c +++ b/arch/powerpc/kernel/smp-tbsync.c | |||
@@ -113,7 +113,7 @@ void __devinit smp_generic_give_timebase(void) | |||
113 | { | 113 | { |
114 | int i, score, score2, old, min=0, max=5000, offset=1000; | 114 | int i, score, score2, old, min=0, max=5000, offset=1000; |
115 | 115 | ||
116 | printk("Synchronizing timebase\n"); | 116 | pr_debug("Software timebase sync\n"); |
117 | 117 | ||
118 | /* if this fails then this kernel won't work anyway... */ | 118 | /* if this fails then this kernel won't work anyway... */ |
119 | tbsync = kzalloc( sizeof(*tbsync), GFP_KERNEL ); | 119 | tbsync = kzalloc( sizeof(*tbsync), GFP_KERNEL ); |
@@ -123,13 +123,13 @@ void __devinit smp_generic_give_timebase(void) | |||
123 | while (!tbsync->ack) | 123 | while (!tbsync->ack) |
124 | barrier(); | 124 | barrier(); |
125 | 125 | ||
126 | printk("Got ack\n"); | 126 | pr_debug("Got ack\n"); |
127 | 127 | ||
128 | /* binary search */ | 128 | /* binary search */ |
129 | for (old = -1; old != offset ; offset = (min+max) / 2) { | 129 | for (old = -1; old != offset ; offset = (min+max) / 2) { |
130 | score = start_contest(kSetAndTest, offset, NUM_ITER); | 130 | score = start_contest(kSetAndTest, offset, NUM_ITER); |
131 | 131 | ||
132 | printk("score %d, offset %d\n", score, offset ); | 132 | pr_debug("score %d, offset %d\n", score, offset ); |
133 | 133 | ||
134 | if( score > 0 ) | 134 | if( score > 0 ) |
135 | max = offset; | 135 | max = offset; |
@@ -140,8 +140,8 @@ void __devinit smp_generic_give_timebase(void) | |||
140 | score = start_contest(kSetAndTest, min, NUM_ITER); | 140 | score = start_contest(kSetAndTest, min, NUM_ITER); |
141 | score2 = start_contest(kSetAndTest, max, NUM_ITER); | 141 | score2 = start_contest(kSetAndTest, max, NUM_ITER); |
142 | 142 | ||
143 | printk("Min %d (score %d), Max %d (score %d)\n", | 143 | pr_debug("Min %d (score %d), Max %d (score %d)\n", |
144 | min, score, max, score2); | 144 | min, score, max, score2); |
145 | score = abs(score); | 145 | score = abs(score); |
146 | score2 = abs(score2); | 146 | score2 = abs(score2); |
147 | offset = (score < score2) ? min : max; | 147 | offset = (score < score2) ? min : max; |
@@ -155,7 +155,7 @@ void __devinit smp_generic_give_timebase(void) | |||
155 | if (score2 <= score || score2 < 20) | 155 | if (score2 <= score || score2 < 20) |
156 | break; | 156 | break; |
157 | } | 157 | } |
158 | printk("Final offset: %d (%d/%d)\n", offset, score2, NUM_ITER ); | 158 | pr_debug("Final offset: %d (%d/%d)\n", offset, score2, NUM_ITER ); |
159 | 159 | ||
160 | /* exiting */ | 160 | /* exiting */ |
161 | tbsync->cmd = kExit; | 161 | tbsync->cmd = kExit; |
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index ff9f7010097d..a59d8d72bb97 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c | |||
@@ -123,6 +123,65 @@ void smp_message_recv(int msg) | |||
123 | } | 123 | } |
124 | } | 124 | } |
125 | 125 | ||
126 | static irqreturn_t call_function_action(int irq, void *data) | ||
127 | { | ||
128 | generic_smp_call_function_interrupt(); | ||
129 | return IRQ_HANDLED; | ||
130 | } | ||
131 | |||
132 | static irqreturn_t reschedule_action(int irq, void *data) | ||
133 | { | ||
134 | /* we just need the return path side effect of checking need_resched */ | ||
135 | return IRQ_HANDLED; | ||
136 | } | ||
137 | |||
138 | static irqreturn_t call_function_single_action(int irq, void *data) | ||
139 | { | ||
140 | generic_smp_call_function_single_interrupt(); | ||
141 | return IRQ_HANDLED; | ||
142 | } | ||
143 | |||
144 | static irqreturn_t debug_ipi_action(int irq, void *data) | ||
145 | { | ||
146 | smp_message_recv(PPC_MSG_DEBUGGER_BREAK); | ||
147 | return IRQ_HANDLED; | ||
148 | } | ||
149 | |||
150 | static irq_handler_t smp_ipi_action[] = { | ||
151 | [PPC_MSG_CALL_FUNCTION] = call_function_action, | ||
152 | [PPC_MSG_RESCHEDULE] = reschedule_action, | ||
153 | [PPC_MSG_CALL_FUNC_SINGLE] = call_function_single_action, | ||
154 | [PPC_MSG_DEBUGGER_BREAK] = debug_ipi_action, | ||
155 | }; | ||
156 | |||
157 | const char *smp_ipi_name[] = { | ||
158 | [PPC_MSG_CALL_FUNCTION] = "ipi call function", | ||
159 | [PPC_MSG_RESCHEDULE] = "ipi reschedule", | ||
160 | [PPC_MSG_CALL_FUNC_SINGLE] = "ipi call function single", | ||
161 | [PPC_MSG_DEBUGGER_BREAK] = "ipi debugger", | ||
162 | }; | ||
163 | |||
164 | /* optional function to request ipi, for controllers with >= 4 ipis */ | ||
165 | int smp_request_message_ipi(int virq, int msg) | ||
166 | { | ||
167 | int err; | ||
168 | |||
169 | if (msg < 0 || msg > PPC_MSG_DEBUGGER_BREAK) { | ||
170 | return -EINVAL; | ||
171 | } | ||
172 | #if !defined(CONFIG_DEBUGGER) && !defined(CONFIG_KEXEC) | ||
173 | if (msg == PPC_MSG_DEBUGGER_BREAK) { | ||
174 | return 1; | ||
175 | } | ||
176 | #endif | ||
177 | err = request_irq(virq, smp_ipi_action[msg], IRQF_DISABLED|IRQF_PERCPU, | ||
178 | smp_ipi_name[msg], 0); | ||
179 | WARN(err < 0, "unable to request_irq %d for %s (rc %d)\n", | ||
180 | virq, smp_ipi_name[msg], err); | ||
181 | |||
182 | return err; | ||
183 | } | ||
184 | |||
126 | void smp_send_reschedule(int cpu) | 185 | void smp_send_reschedule(int cpu) |
127 | { | 186 | { |
128 | if (likely(smp_ops)) | 187 | if (likely(smp_ops)) |
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index e2ee66b5831d..e1f3a5140429 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c | |||
@@ -164,8 +164,6 @@ static u64 tb_to_ns_scale __read_mostly; | |||
164 | static unsigned tb_to_ns_shift __read_mostly; | 164 | static unsigned tb_to_ns_shift __read_mostly; |
165 | static unsigned long boot_tb __read_mostly; | 165 | static unsigned long boot_tb __read_mostly; |
166 | 166 | ||
167 | static struct gettimeofday_struct do_gtod; | ||
168 | |||
169 | extern struct timezone sys_tz; | 167 | extern struct timezone sys_tz; |
170 | static long timezone_offset; | 168 | static long timezone_offset; |
171 | 169 | ||
@@ -415,31 +413,9 @@ void udelay(unsigned long usecs) | |||
415 | } | 413 | } |
416 | EXPORT_SYMBOL(udelay); | 414 | EXPORT_SYMBOL(udelay); |
417 | 415 | ||
418 | |||
419 | /* | ||
420 | * There are two copies of tb_to_xs and stamp_xsec so that no | ||
421 | * lock is needed to access and use these values in | ||
422 | * do_gettimeofday. We alternate the copies and as long as a | ||
423 | * reasonable time elapses between changes, there will never | ||
424 | * be inconsistent values. ntpd has a minimum of one minute | ||
425 | * between updates. | ||
426 | */ | ||
427 | static inline void update_gtod(u64 new_tb_stamp, u64 new_stamp_xsec, | 416 | static inline void update_gtod(u64 new_tb_stamp, u64 new_stamp_xsec, |
428 | u64 new_tb_to_xs) | 417 | u64 new_tb_to_xs) |
429 | { | 418 | { |
430 | unsigned temp_idx; | ||
431 | struct gettimeofday_vars *temp_varp; | ||
432 | |||
433 | temp_idx = (do_gtod.var_idx == 0); | ||
434 | temp_varp = &do_gtod.vars[temp_idx]; | ||
435 | |||
436 | temp_varp->tb_to_xs = new_tb_to_xs; | ||
437 | temp_varp->tb_orig_stamp = new_tb_stamp; | ||
438 | temp_varp->stamp_xsec = new_stamp_xsec; | ||
439 | smp_mb(); | ||
440 | do_gtod.varp = temp_varp; | ||
441 | do_gtod.var_idx = temp_idx; | ||
442 | |||
443 | /* | 419 | /* |
444 | * tb_update_count is used to allow the userspace gettimeofday code | 420 | * tb_update_count is used to allow the userspace gettimeofday code |
445 | * to assure itself that it sees a consistent view of the tb_to_xs and | 421 | * to assure itself that it sees a consistent view of the tb_to_xs and |
@@ -456,6 +432,7 @@ static inline void update_gtod(u64 new_tb_stamp, u64 new_stamp_xsec, | |||
456 | vdso_data->tb_to_xs = new_tb_to_xs; | 432 | vdso_data->tb_to_xs = new_tb_to_xs; |
457 | vdso_data->wtom_clock_sec = wall_to_monotonic.tv_sec; | 433 | vdso_data->wtom_clock_sec = wall_to_monotonic.tv_sec; |
458 | vdso_data->wtom_clock_nsec = wall_to_monotonic.tv_nsec; | 434 | vdso_data->wtom_clock_nsec = wall_to_monotonic.tv_nsec; |
435 | vdso_data->stamp_xtime = xtime; | ||
459 | smp_wmb(); | 436 | smp_wmb(); |
460 | ++(vdso_data->tb_update_count); | 437 | ++(vdso_data->tb_update_count); |
461 | } | 438 | } |
@@ -514,9 +491,7 @@ static int __init iSeries_tb_recal(void) | |||
514 | tb_ticks_per_sec = new_tb_ticks_per_sec; | 491 | tb_ticks_per_sec = new_tb_ticks_per_sec; |
515 | calc_cputime_factors(); | 492 | calc_cputime_factors(); |
516 | div128_by_32( XSEC_PER_SEC, 0, tb_ticks_per_sec, &divres ); | 493 | div128_by_32( XSEC_PER_SEC, 0, tb_ticks_per_sec, &divres ); |
517 | do_gtod.tb_ticks_per_sec = tb_ticks_per_sec; | ||
518 | tb_to_xs = divres.result_low; | 494 | tb_to_xs = divres.result_low; |
519 | do_gtod.varp->tb_to_xs = tb_to_xs; | ||
520 | vdso_data->tb_ticks_per_sec = tb_ticks_per_sec; | 495 | vdso_data->tb_ticks_per_sec = tb_ticks_per_sec; |
521 | vdso_data->tb_to_xs = tb_to_xs; | 496 | vdso_data->tb_to_xs = tb_to_xs; |
522 | } | 497 | } |
@@ -988,15 +963,6 @@ void __init time_init(void) | |||
988 | sys_tz.tz_dsttime = 0; | 963 | sys_tz.tz_dsttime = 0; |
989 | } | 964 | } |
990 | 965 | ||
991 | do_gtod.varp = &do_gtod.vars[0]; | ||
992 | do_gtod.var_idx = 0; | ||
993 | do_gtod.varp->tb_orig_stamp = tb_last_jiffy; | ||
994 | __get_cpu_var(last_jiffy) = tb_last_jiffy; | ||
995 | do_gtod.varp->stamp_xsec = (u64) xtime.tv_sec * XSEC_PER_SEC; | ||
996 | do_gtod.tb_ticks_per_sec = tb_ticks_per_sec; | ||
997 | do_gtod.varp->tb_to_xs = tb_to_xs; | ||
998 | do_gtod.tb_to_us = tb_to_us; | ||
999 | |||
1000 | vdso_data->tb_orig_stamp = tb_last_jiffy; | 966 | vdso_data->tb_orig_stamp = tb_last_jiffy; |
1001 | vdso_data->tb_update_count = 0; | 967 | vdso_data->tb_update_count = 0; |
1002 | vdso_data->tb_ticks_per_sec = tb_ticks_per_sec; | 968 | vdso_data->tb_ticks_per_sec = tb_ticks_per_sec; |
diff --git a/arch/powerpc/kernel/vdso32/gettimeofday.S b/arch/powerpc/kernel/vdso32/gettimeofday.S index 72ca26df457e..ee038d4bf252 100644 --- a/arch/powerpc/kernel/vdso32/gettimeofday.S +++ b/arch/powerpc/kernel/vdso32/gettimeofday.S | |||
@@ -16,6 +16,13 @@ | |||
16 | #include <asm/asm-offsets.h> | 16 | #include <asm/asm-offsets.h> |
17 | #include <asm/unistd.h> | 17 | #include <asm/unistd.h> |
18 | 18 | ||
19 | /* Offset for the low 32-bit part of a field of long type */ | ||
20 | #ifdef CONFIG_PPC64 | ||
21 | #define LOPART 4 | ||
22 | #else | ||
23 | #define LOPART 0 | ||
24 | #endif | ||
25 | |||
19 | .text | 26 | .text |
20 | /* | 27 | /* |
21 | * Exact prototype of gettimeofday | 28 | * Exact prototype of gettimeofday |
@@ -90,101 +97,53 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime) | |||
90 | 97 | ||
91 | mflr r12 /* r12 saves lr */ | 98 | mflr r12 /* r12 saves lr */ |
92 | .cfi_register lr,r12 | 99 | .cfi_register lr,r12 |
93 | mr r10,r3 /* r10 saves id */ | ||
94 | mr r11,r4 /* r11 saves tp */ | 100 | mr r11,r4 /* r11 saves tp */ |
95 | bl __get_datapage@local /* get data page */ | 101 | bl __get_datapage@local /* get data page */ |
96 | mr r9,r3 /* datapage ptr in r9 */ | 102 | mr r9,r3 /* datapage ptr in r9 */ |
97 | beq cr1,50f /* if monotonic -> jump there */ | ||
98 | |||
99 | /* | ||
100 | * CLOCK_REALTIME | ||
101 | */ | ||
102 | |||
103 | bl __do_get_xsec@local /* get xsec from tb & kernel */ | ||
104 | bne- 98f /* out of line -> do syscall */ | ||
105 | |||
106 | /* seconds are xsec >> 20 */ | ||
107 | rlwinm r5,r4,12,20,31 | ||
108 | rlwimi r5,r3,12,0,19 | ||
109 | stw r5,TSPC32_TV_SEC(r11) | ||
110 | 103 | ||
111 | /* get remaining xsec and convert to nsec. we scale | 104 | 50: bl __do_get_tspec@local /* get sec/nsec from tb & kernel */ |
112 | * up remaining xsec by 12 bits and get the top 32 bits | 105 | bne cr1,80f /* not monotonic -> all done */ |
113 | * of the multiplication, then we multiply by 1000 | ||
114 | */ | ||
115 | rlwinm r5,r4,12,0,19 | ||
116 | lis r6,1000000@h | ||
117 | ori r6,r6,1000000@l | ||
118 | mulhwu r5,r5,r6 | ||
119 | mulli r5,r5,1000 | ||
120 | stw r5,TSPC32_TV_NSEC(r11) | ||
121 | mtlr r12 | ||
122 | crclr cr0*4+so | ||
123 | li r3,0 | ||
124 | blr | ||
125 | 106 | ||
126 | /* | 107 | /* |
127 | * CLOCK_MONOTONIC | 108 | * CLOCK_MONOTONIC |
128 | */ | 109 | */ |
129 | 110 | ||
130 | 50: bl __do_get_xsec@local /* get xsec from tb & kernel */ | ||
131 | bne- 98f /* out of line -> do syscall */ | ||
132 | |||
133 | /* seconds are xsec >> 20 */ | ||
134 | rlwinm r6,r4,12,20,31 | ||
135 | rlwimi r6,r3,12,0,19 | ||
136 | |||
137 | /* get remaining xsec and convert to nsec. we scale | ||
138 | * up remaining xsec by 12 bits and get the top 32 bits | ||
139 | * of the multiplication, then we multiply by 1000 | ||
140 | */ | ||
141 | rlwinm r7,r4,12,0,19 | ||
142 | lis r5,1000000@h | ||
143 | ori r5,r5,1000000@l | ||
144 | mulhwu r7,r7,r5 | ||
145 | mulli r7,r7,1000 | ||
146 | |||
147 | /* now we must fixup using wall to monotonic. We need to snapshot | 111 | /* now we must fixup using wall to monotonic. We need to snapshot |
148 | * that value and do the counter trick again. Fortunately, we still | 112 | * that value and do the counter trick again. Fortunately, we still |
149 | * have the counter value in r8 that was returned by __do_get_xsec. | 113 | * have the counter value in r8 that was returned by __do_get_xsec. |
150 | * At this point, r6,r7 contain our sec/nsec values, r3,r4 and r5 | 114 | * At this point, r3,r4 contain our sec/nsec values, r5 and r6 |
151 | * can be used | 115 | * can be used, r7 contains NSEC_PER_SEC. |
152 | */ | 116 | */ |
153 | 117 | ||
154 | lwz r3,WTOM_CLOCK_SEC(r9) | 118 | lwz r5,WTOM_CLOCK_SEC(r9) |
155 | lwz r4,WTOM_CLOCK_NSEC(r9) | 119 | lwz r6,WTOM_CLOCK_NSEC(r9) |
156 | 120 | ||
157 | /* We now have our result in r3,r4. We create a fake dependency | 121 | /* We now have our offset in r5,r6. We create a fake dependency |
158 | * on that result and re-check the counter | 122 | * on that value and re-check the counter |
159 | */ | 123 | */ |
160 | or r5,r4,r3 | 124 | or r0,r6,r5 |
161 | xor r0,r5,r5 | 125 | xor r0,r0,r0 |
162 | add r9,r9,r0 | 126 | add r9,r9,r0 |
163 | #ifdef CONFIG_PPC64 | 127 | lwz r0,(CFG_TB_UPDATE_COUNT+LOPART)(r9) |
164 | lwz r0,(CFG_TB_UPDATE_COUNT+4)(r9) | ||
165 | #else | ||
166 | lwz r0,(CFG_TB_UPDATE_COUNT)(r9) | ||
167 | #endif | ||
168 | cmpl cr0,r8,r0 /* check if updated */ | 128 | cmpl cr0,r8,r0 /* check if updated */ |
169 | bne- 50b | 129 | bne- 50b |
170 | 130 | ||
171 | /* Calculate and store result. Note that this mimmics the C code, | 131 | /* Calculate and store result. Note that this mimics the C code, |
172 | * which may cause funny results if nsec goes negative... is that | 132 | * which may cause funny results if nsec goes negative... is that |
173 | * possible at all ? | 133 | * possible at all ? |
174 | */ | 134 | */ |
175 | add r3,r3,r6 | 135 | add r3,r3,r5 |
176 | add r4,r4,r7 | 136 | add r4,r4,r6 |
177 | lis r5,NSEC_PER_SEC@h | 137 | cmpw cr0,r4,r7 |
178 | ori r5,r5,NSEC_PER_SEC@l | 138 | cmpwi cr1,r4,0 |
179 | cmpl cr0,r4,r5 | ||
180 | cmpli cr1,r4,0 | ||
181 | blt 1f | 139 | blt 1f |
182 | subf r4,r5,r4 | 140 | subf r4,r7,r4 |
183 | addi r3,r3,1 | 141 | addi r3,r3,1 |
184 | 1: bge cr1,1f | 142 | 1: bge cr1,80f |
185 | addi r3,r3,-1 | 143 | addi r3,r3,-1 |
186 | add r4,r4,r5 | 144 | add r4,r4,r7 |
187 | 1: stw r3,TSPC32_TV_SEC(r11) | 145 | |
146 | 80: stw r3,TSPC32_TV_SEC(r11) | ||
188 | stw r4,TSPC32_TV_NSEC(r11) | 147 | stw r4,TSPC32_TV_NSEC(r11) |
189 | 148 | ||
190 | mtlr r12 | 149 | mtlr r12 |
@@ -195,10 +154,6 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime) | |||
195 | /* | 154 | /* |
196 | * syscall fallback | 155 | * syscall fallback |
197 | */ | 156 | */ |
198 | 98: | ||
199 | mtlr r12 | ||
200 | mr r3,r10 | ||
201 | mr r4,r11 | ||
202 | 99: | 157 | 99: |
203 | li r0,__NR_clock_gettime | 158 | li r0,__NR_clock_gettime |
204 | sc | 159 | sc |
@@ -254,11 +209,7 @@ __do_get_xsec: | |||
254 | /* Check for update count & load values. We use the low | 209 | /* Check for update count & load values. We use the low |
255 | * order 32 bits of the update count | 210 | * order 32 bits of the update count |
256 | */ | 211 | */ |
257 | #ifdef CONFIG_PPC64 | 212 | 1: lwz r8,(CFG_TB_UPDATE_COUNT+LOPART)(r9) |
258 | 1: lwz r8,(CFG_TB_UPDATE_COUNT+4)(r9) | ||
259 | #else | ||
260 | 1: lwz r8,(CFG_TB_UPDATE_COUNT)(r9) | ||
261 | #endif | ||
262 | andi. r0,r8,1 /* pending update ? loop */ | 213 | andi. r0,r8,1 /* pending update ? loop */ |
263 | bne- 1b | 214 | bne- 1b |
264 | xor r0,r8,r8 /* create dependency */ | 215 | xor r0,r8,r8 /* create dependency */ |
@@ -305,11 +256,7 @@ __do_get_xsec: | |||
305 | or r6,r4,r3 | 256 | or r6,r4,r3 |
306 | xor r0,r6,r6 | 257 | xor r0,r6,r6 |
307 | add r9,r9,r0 | 258 | add r9,r9,r0 |
308 | #ifdef CONFIG_PPC64 | 259 | lwz r0,(CFG_TB_UPDATE_COUNT+LOPART)(r9) |
309 | lwz r0,(CFG_TB_UPDATE_COUNT+4)(r9) | ||
310 | #else | ||
311 | lwz r0,(CFG_TB_UPDATE_COUNT)(r9) | ||
312 | #endif | ||
313 | cmpl cr0,r8,r0 /* check if updated */ | 260 | cmpl cr0,r8,r0 /* check if updated */ |
314 | bne- 1b | 261 | bne- 1b |
315 | 262 | ||
@@ -322,3 +269,98 @@ __do_get_xsec: | |||
322 | */ | 269 | */ |
323 | 3: blr | 270 | 3: blr |
324 | .cfi_endproc | 271 | .cfi_endproc |
272 | |||
273 | /* | ||
274 | * This is the core of clock_gettime(), it returns the current | ||
275 | * time in seconds and nanoseconds in r3 and r4. | ||
276 | * It expects the datapage ptr in r9 and doesn't clobber it. | ||
277 | * It clobbers r0, r5, r6, r10 and returns NSEC_PER_SEC in r7. | ||
278 | * On return, r8 contains the counter value that can be reused. | ||
279 | * This clobbers cr0 but not any other cr field. | ||
280 | */ | ||
281 | __do_get_tspec: | ||
282 | .cfi_startproc | ||
283 | /* Check for update count & load values. We use the low | ||
284 | * order 32 bits of the update count | ||
285 | */ | ||
286 | 1: lwz r8,(CFG_TB_UPDATE_COUNT+LOPART)(r9) | ||
287 | andi. r0,r8,1 /* pending update ? loop */ | ||
288 | bne- 1b | ||
289 | xor r0,r8,r8 /* create dependency */ | ||
290 | add r9,r9,r0 | ||
291 | |||
292 | /* Load orig stamp (offset to TB) */ | ||
293 | lwz r5,CFG_TB_ORIG_STAMP(r9) | ||
294 | lwz r6,(CFG_TB_ORIG_STAMP+4)(r9) | ||
295 | |||
296 | /* Get a stable TB value */ | ||
297 | 2: mftbu r3 | ||
298 | mftbl r4 | ||
299 | mftbu r0 | ||
300 | cmpl cr0,r3,r0 | ||
301 | bne- 2b | ||
302 | |||
303 | /* Subtract tb orig stamp and shift left 12 bits. | ||
304 | */ | ||
305 | subfc r7,r6,r4 | ||
306 | subfe r0,r5,r3 | ||
307 | slwi r0,r0,12 | ||
308 | rlwimi. r0,r7,12,20,31 | ||
309 | slwi r7,r7,12 | ||
310 | |||
311 | /* Load scale factor & do multiplication */ | ||
312 | lwz r5,CFG_TB_TO_XS(r9) /* load values */ | ||
313 | lwz r6,(CFG_TB_TO_XS+4)(r9) | ||
314 | mulhwu r3,r7,r6 | ||
315 | mullw r10,r7,r5 | ||
316 | mulhwu r4,r7,r5 | ||
317 | addc r10,r3,r10 | ||
318 | li r3,0 | ||
319 | |||
320 | beq+ 4f /* skip high part computation if 0 */ | ||
321 | mulhwu r3,r0,r5 | ||
322 | mullw r7,r0,r5 | ||
323 | mulhwu r5,r0,r6 | ||
324 | mullw r6,r0,r6 | ||
325 | adde r4,r4,r7 | ||
326 | addze r3,r3 | ||
327 | addc r4,r4,r5 | ||
328 | addze r3,r3 | ||
329 | addc r10,r10,r6 | ||
330 | |||
331 | 4: addze r4,r4 /* add in carry */ | ||
332 | lis r7,NSEC_PER_SEC@h | ||
333 | ori r7,r7,NSEC_PER_SEC@l | ||
334 | mulhwu r4,r4,r7 /* convert to nanoseconds */ | ||
335 | |||
336 | /* At this point, we have seconds & nanoseconds since the xtime | ||
337 | * stamp in r3+CA and r4. Load & add the xtime stamp. | ||
338 | */ | ||
339 | #ifdef CONFIG_PPC64 | ||
340 | lwz r5,STAMP_XTIME+TSPC64_TV_SEC+LOPART(r9) | ||
341 | lwz r6,STAMP_XTIME+TSPC64_TV_NSEC+LOPART(r9) | ||
342 | #else | ||
343 | lwz r5,STAMP_XTIME+TSPC32_TV_SEC(r9) | ||
344 | lwz r6,STAMP_XTIME+TSPC32_TV_NSEC(r9) | ||
345 | #endif | ||
346 | add r4,r4,r6 | ||
347 | adde r3,r3,r5 | ||
348 | |||
349 | /* We now have our result in r3,r4. We create a fake dependency | ||
350 | * on that result and re-check the counter | ||
351 | */ | ||
352 | or r6,r4,r3 | ||
353 | xor r0,r6,r6 | ||
354 | add r9,r9,r0 | ||
355 | lwz r0,(CFG_TB_UPDATE_COUNT+LOPART)(r9) | ||
356 | cmpl cr0,r8,r0 /* check if updated */ | ||
357 | bne- 1b | ||
358 | |||
359 | /* check for nanosecond overflow and adjust if necessary */ | ||
360 | cmpw r4,r7 | ||
361 | bltlr /* all done if no overflow */ | ||
362 | subf r4,r7,r4 /* adjust if overflow */ | ||
363 | addi r3,r3,1 | ||
364 | |||
365 | blr | ||
366 | .cfi_endproc | ||
diff --git a/arch/powerpc/kernel/vdso64/gettimeofday.S b/arch/powerpc/kernel/vdso64/gettimeofday.S index c6401f9e37f1..262cd5857a56 100644 --- a/arch/powerpc/kernel/vdso64/gettimeofday.S +++ b/arch/powerpc/kernel/vdso64/gettimeofday.S | |||
@@ -75,90 +75,49 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime) | |||
75 | 75 | ||
76 | mflr r12 /* r12 saves lr */ | 76 | mflr r12 /* r12 saves lr */ |
77 | .cfi_register lr,r12 | 77 | .cfi_register lr,r12 |
78 | mr r10,r3 /* r10 saves id */ | ||
79 | mr r11,r4 /* r11 saves tp */ | 78 | mr r11,r4 /* r11 saves tp */ |
80 | bl V_LOCAL_FUNC(__get_datapage) /* get data page */ | 79 | bl V_LOCAL_FUNC(__get_datapage) /* get data page */ |
81 | beq cr1,50f /* if monotonic -> jump there */ | 80 | 50: bl V_LOCAL_FUNC(__do_get_tspec) /* get time from tb & kernel */ |
82 | 81 | bne cr1,80f /* if not monotonic, all done */ | |
83 | /* | ||
84 | * CLOCK_REALTIME | ||
85 | */ | ||
86 | |||
87 | bl V_LOCAL_FUNC(__do_get_xsec) /* get xsec from tb & kernel */ | ||
88 | |||
89 | lis r7,15 /* r7 = 1000000 = USEC_PER_SEC */ | ||
90 | ori r7,r7,16960 | ||
91 | rldicl r5,r4,44,20 /* r5 = sec = xsec / XSEC_PER_SEC */ | ||
92 | rldicr r6,r5,20,43 /* r6 = sec * XSEC_PER_SEC */ | ||
93 | std r5,TSPC64_TV_SEC(r11) /* store sec in tv */ | ||
94 | subf r0,r6,r4 /* r0 = xsec = (xsec - r6) */ | ||
95 | mulld r0,r0,r7 /* usec = (xsec * USEC_PER_SEC) / | ||
96 | * XSEC_PER_SEC | ||
97 | */ | ||
98 | rldicl r0,r0,44,20 | ||
99 | mulli r0,r0,1000 /* nsec = usec * 1000 */ | ||
100 | std r0,TSPC64_TV_NSEC(r11) /* store nsec in tp */ | ||
101 | |||
102 | mtlr r12 | ||
103 | crclr cr0*4+so | ||
104 | li r3,0 | ||
105 | blr | ||
106 | 82 | ||
107 | /* | 83 | /* |
108 | * CLOCK_MONOTONIC | 84 | * CLOCK_MONOTONIC |
109 | */ | 85 | */ |
110 | 86 | ||
111 | 50: bl V_LOCAL_FUNC(__do_get_xsec) /* get xsec from tb & kernel */ | ||
112 | |||
113 | lis r7,15 /* r7 = 1000000 = USEC_PER_SEC */ | ||
114 | ori r7,r7,16960 | ||
115 | rldicl r5,r4,44,20 /* r5 = sec = xsec / XSEC_PER_SEC */ | ||
116 | rldicr r6,r5,20,43 /* r6 = sec * XSEC_PER_SEC */ | ||
117 | subf r0,r6,r4 /* r0 = xsec = (xsec - r6) */ | ||
118 | mulld r0,r0,r7 /* usec = (xsec * USEC_PER_SEC) / | ||
119 | * XSEC_PER_SEC | ||
120 | */ | ||
121 | rldicl r6,r0,44,20 | ||
122 | mulli r6,r6,1000 /* nsec = usec * 1000 */ | ||
123 | |||
124 | /* now we must fixup using wall to monotonic. We need to snapshot | 87 | /* now we must fixup using wall to monotonic. We need to snapshot |
125 | * that value and do the counter trick again. Fortunately, we still | 88 | * that value and do the counter trick again. Fortunately, we still |
126 | * have the counter value in r8 that was returned by __do_get_xsec. | 89 | * have the counter value in r8 that was returned by __do_get_tspec. |
127 | * At this point, r5,r6 contain our sec/nsec values. | 90 | * At this point, r4,r5 contain our sec/nsec values. |
128 | * can be used | ||
129 | */ | 91 | */ |
130 | 92 | ||
131 | lwa r4,WTOM_CLOCK_SEC(r3) | 93 | lwa r6,WTOM_CLOCK_SEC(r3) |
132 | lwa r7,WTOM_CLOCK_NSEC(r3) | 94 | lwa r9,WTOM_CLOCK_NSEC(r3) |
133 | 95 | ||
134 | /* We now have our result in r4,r7. We create a fake dependency | 96 | /* We now have our result in r6,r9. We create a fake dependency |
135 | * on that result and re-check the counter | 97 | * on that result and re-check the counter |
136 | */ | 98 | */ |
137 | or r9,r4,r7 | 99 | or r0,r6,r9 |
138 | xor r0,r9,r9 | 100 | xor r0,r0,r0 |
139 | add r3,r3,r0 | 101 | add r3,r3,r0 |
140 | ld r0,CFG_TB_UPDATE_COUNT(r3) | 102 | ld r0,CFG_TB_UPDATE_COUNT(r3) |
141 | cmpld cr0,r0,r8 /* check if updated */ | 103 | cmpld cr0,r0,r8 /* check if updated */ |
142 | bne- 50b | 104 | bne- 50b |
143 | 105 | ||
144 | /* Calculate and store result. Note that this mimmics the C code, | 106 | /* Add wall->monotonic offset and check for overflow or underflow. |
145 | * which may cause funny results if nsec goes negative... is that | ||
146 | * possible at all ? | ||
147 | */ | 107 | */ |
148 | add r4,r4,r5 | 108 | add r4,r4,r6 |
149 | add r7,r7,r6 | 109 | add r5,r5,r9 |
150 | lis r9,NSEC_PER_SEC@h | 110 | cmpd cr0,r5,r7 |
151 | ori r9,r9,NSEC_PER_SEC@l | 111 | cmpdi cr1,r5,0 |
152 | cmpl cr0,r7,r9 | ||
153 | cmpli cr1,r7,0 | ||
154 | blt 1f | 112 | blt 1f |
155 | subf r7,r9,r7 | 113 | subf r5,r7,r5 |
156 | addi r4,r4,1 | 114 | addi r4,r4,1 |
157 | 1: bge cr1,1f | 115 | 1: bge cr1,80f |
158 | addi r4,r4,-1 | 116 | addi r4,r4,-1 |
159 | add r7,r7,r9 | 117 | add r5,r5,r7 |
160 | 1: std r4,TSPC64_TV_SEC(r11) | 118 | |
161 | std r7,TSPC64_TV_NSEC(r11) | 119 | 80: std r4,TSPC64_TV_SEC(r11) |
120 | std r5,TSPC64_TV_NSEC(r11) | ||
162 | 121 | ||
163 | mtlr r12 | 122 | mtlr r12 |
164 | crclr cr0*4+so | 123 | crclr cr0*4+so |
@@ -168,10 +127,6 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime) | |||
168 | /* | 127 | /* |
169 | * syscall fallback | 128 | * syscall fallback |
170 | */ | 129 | */ |
171 | 98: | ||
172 | mtlr r12 | ||
173 | mr r3,r10 | ||
174 | mr r4,r11 | ||
175 | 99: | 130 | 99: |
176 | li r0,__NR_clock_gettime | 131 | li r0,__NR_clock_gettime |
177 | sc | 132 | sc |
@@ -253,3 +208,59 @@ V_FUNCTION_BEGIN(__do_get_xsec) | |||
253 | blr | 208 | blr |
254 | .cfi_endproc | 209 | .cfi_endproc |
255 | V_FUNCTION_END(__do_get_xsec) | 210 | V_FUNCTION_END(__do_get_xsec) |
211 | |||
212 | /* | ||
213 | * This is the core of clock_gettime(), it returns the current | ||
214 | * time in seconds and nanoseconds in r4 and r5. | ||
215 | * It expects the datapage ptr in r3 and doesn't clobber it. | ||
216 | * It clobbers r0 and r6 and returns NSEC_PER_SEC in r7. | ||
217 | * On return, r8 contains the counter value that can be reused. | ||
218 | * This clobbers cr0 but not any other cr field. | ||
219 | */ | ||
220 | V_FUNCTION_BEGIN(__do_get_tspec) | ||
221 | .cfi_startproc | ||
222 | /* check for update count & load values */ | ||
223 | 1: ld r8,CFG_TB_UPDATE_COUNT(r3) | ||
224 | andi. r0,r8,1 /* pending update ? loop */ | ||
225 | bne- 1b | ||
226 | xor r0,r8,r8 /* create dependency */ | ||
227 | add r3,r3,r0 | ||
228 | |||
229 | /* Get TB & offset it. We use the MFTB macro which will generate | ||
230 | * workaround code for Cell. | ||
231 | */ | ||
232 | MFTB(r7) | ||
233 | ld r9,CFG_TB_ORIG_STAMP(r3) | ||
234 | subf r7,r9,r7 | ||
235 | |||
236 | /* Scale result */ | ||
237 | ld r5,CFG_TB_TO_XS(r3) | ||
238 | sldi r7,r7,12 /* compute time since stamp_xtime */ | ||
239 | mulhdu r6,r7,r5 /* in units of 2^-32 seconds */ | ||
240 | |||
241 | /* Add stamp since epoch */ | ||
242 | ld r4,STAMP_XTIME+TSPC64_TV_SEC(r3) | ||
243 | ld r5,STAMP_XTIME+TSPC64_TV_NSEC(r3) | ||
244 | or r0,r4,r5 | ||
245 | or r0,r0,r6 | ||
246 | xor r0,r0,r0 | ||
247 | add r3,r3,r0 | ||
248 | ld r0,CFG_TB_UPDATE_COUNT(r3) | ||
249 | cmpld r0,r8 /* check if updated */ | ||
250 | bne- 1b /* reload if so */ | ||
251 | |||
252 | /* convert to seconds & nanoseconds and add to stamp */ | ||
253 | lis r7,NSEC_PER_SEC@h | ||
254 | ori r7,r7,NSEC_PER_SEC@l | ||
255 | mulhwu r0,r6,r7 /* compute nanoseconds and */ | ||
256 | srdi r6,r6,32 /* seconds since stamp_xtime */ | ||
257 | clrldi r0,r0,32 | ||
258 | add r5,r5,r0 /* add nanoseconds together */ | ||
259 | cmpd r5,r7 /* overflow? */ | ||
260 | add r4,r4,r6 | ||
261 | bltlr /* all done if no overflow */ | ||
262 | subf r5,r7,r5 /* if overflow, adjust */ | ||
263 | addi r4,r4,1 | ||
264 | blr | ||
265 | .cfi_endproc | ||
266 | V_FUNCTION_END(__do_get_tspec) | ||
diff --git a/arch/powerpc/lib/copyuser_64.S b/arch/powerpc/lib/copyuser_64.S index 25ec5378afa4..70693a5c12a1 100644 --- a/arch/powerpc/lib/copyuser_64.S +++ b/arch/powerpc/lib/copyuser_64.S | |||
@@ -26,11 +26,24 @@ _GLOBAL(__copy_tofrom_user) | |||
26 | andi. r6,r6,7 | 26 | andi. r6,r6,7 |
27 | PPC_MTOCRF 0x01,r5 | 27 | PPC_MTOCRF 0x01,r5 |
28 | blt cr1,.Lshort_copy | 28 | blt cr1,.Lshort_copy |
29 | /* Below we want to nop out the bne if we're on a CPU that has the | ||
30 | * CPU_FTR_UNALIGNED_LD_STD bit set and the CPU_FTR_CP_USE_DCBTZ bit | ||
31 | * cleared. | ||
32 | * At the time of writing the only CPU that has this combination of bits | ||
33 | * set is Power6. | ||
34 | */ | ||
35 | BEGIN_FTR_SECTION | ||
36 | nop | ||
37 | FTR_SECTION_ELSE | ||
29 | bne .Ldst_unaligned | 38 | bne .Ldst_unaligned |
39 | ALT_FTR_SECTION_END(CPU_FTR_UNALIGNED_LD_STD | CPU_FTR_CP_USE_DCBTZ, \ | ||
40 | CPU_FTR_UNALIGNED_LD_STD) | ||
30 | .Ldst_aligned: | 41 | .Ldst_aligned: |
31 | andi. r0,r4,7 | ||
32 | addi r3,r3,-16 | 42 | addi r3,r3,-16 |
43 | BEGIN_FTR_SECTION | ||
44 | andi. r0,r4,7 | ||
33 | bne .Lsrc_unaligned | 45 | bne .Lsrc_unaligned |
46 | END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD) | ||
34 | srdi r7,r5,4 | 47 | srdi r7,r5,4 |
35 | 20: ld r9,0(r4) | 48 | 20: ld r9,0(r4) |
36 | addi r4,r4,-8 | 49 | addi r4,r4,-8 |
@@ -138,7 +151,7 @@ _GLOBAL(__copy_tofrom_user) | |||
138 | PPC_MTOCRF 0x01,r6 /* put #bytes to 8B bdry into cr7 */ | 151 | PPC_MTOCRF 0x01,r6 /* put #bytes to 8B bdry into cr7 */ |
139 | subf r5,r6,r5 | 152 | subf r5,r6,r5 |
140 | li r7,0 | 153 | li r7,0 |
141 | cmpldi r1,r5,16 | 154 | cmpldi cr1,r5,16 |
142 | bf cr7*4+3,1f | 155 | bf cr7*4+3,1f |
143 | 35: lbz r0,0(r4) | 156 | 35: lbz r0,0(r4) |
144 | 81: stb r0,0(r3) | 157 | 81: stb r0,0(r3) |
diff --git a/arch/powerpc/lib/dma-noncoherent.c b/arch/powerpc/lib/dma-noncoherent.c index 31734c0969cd..2b1ce1849344 100644 --- a/arch/powerpc/lib/dma-noncoherent.c +++ b/arch/powerpc/lib/dma-noncoherent.c | |||
@@ -320,7 +320,6 @@ static int __init dma_alloc_init(void) | |||
320 | ret = -ENOMEM; | 320 | ret = -ENOMEM; |
321 | break; | 321 | break; |
322 | } | 322 | } |
323 | WARN_ON(!pmd_none(*pmd)); | ||
324 | 323 | ||
325 | pte = pte_alloc_kernel(pmd, CONSISTENT_BASE); | 324 | pte = pte_alloc_kernel(pmd, CONSISTENT_BASE); |
326 | if (!pte) { | 325 | if (!pte) { |
diff --git a/arch/powerpc/lib/memcpy_64.S b/arch/powerpc/lib/memcpy_64.S index 3f131129d1c1..fe2d34e5332d 100644 --- a/arch/powerpc/lib/memcpy_64.S +++ b/arch/powerpc/lib/memcpy_64.S | |||
@@ -18,11 +18,23 @@ _GLOBAL(memcpy) | |||
18 | andi. r6,r6,7 | 18 | andi. r6,r6,7 |
19 | dcbt 0,r4 | 19 | dcbt 0,r4 |
20 | blt cr1,.Lshort_copy | 20 | blt cr1,.Lshort_copy |
21 | /* Below we want to nop out the bne if we're on a CPU that has the | ||
22 | CPU_FTR_UNALIGNED_LD_STD bit set and the CPU_FTR_CP_USE_DCBTZ bit | ||
23 | cleared. | ||
24 | At the time of writing the only CPU that has this combination of bits | ||
25 | set is Power6. */ | ||
26 | BEGIN_FTR_SECTION | ||
27 | nop | ||
28 | FTR_SECTION_ELSE | ||
21 | bne .Ldst_unaligned | 29 | bne .Ldst_unaligned |
30 | ALT_FTR_SECTION_END(CPU_FTR_UNALIGNED_LD_STD | CPU_FTR_CP_USE_DCBTZ, \ | ||
31 | CPU_FTR_UNALIGNED_LD_STD) | ||
22 | .Ldst_aligned: | 32 | .Ldst_aligned: |
23 | andi. r0,r4,7 | ||
24 | addi r3,r3,-16 | 33 | addi r3,r3,-16 |
34 | BEGIN_FTR_SECTION | ||
35 | andi. r0,r4,7 | ||
25 | bne .Lsrc_unaligned | 36 | bne .Lsrc_unaligned |
37 | END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD) | ||
26 | srdi r7,r5,4 | 38 | srdi r7,r5,4 |
27 | ld r9,0(r4) | 39 | ld r9,0(r4) |
28 | addi r4,r4,-8 | 40 | addi r4,r4,-8 |
@@ -131,7 +143,7 @@ _GLOBAL(memcpy) | |||
131 | PPC_MTOCRF 0x01,r6 # put #bytes to 8B bdry into cr7 | 143 | PPC_MTOCRF 0x01,r6 # put #bytes to 8B bdry into cr7 |
132 | subf r5,r6,r5 | 144 | subf r5,r6,r5 |
133 | li r7,0 | 145 | li r7,0 |
134 | cmpldi r1,r5,16 | 146 | cmpldi cr1,r5,16 |
135 | bf cr7*4+3,1f | 147 | bf cr7*4+3,1f |
136 | lbz r0,0(r4) | 148 | lbz r0,0(r4) |
137 | stb r0,0(r3) | 149 | stb r0,0(r3) |
diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c index 565b7a237c84..7df0409107ad 100644 --- a/arch/powerpc/mm/fault.c +++ b/arch/powerpc/mm/fault.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/kprobes.h> | 30 | #include <linux/kprobes.h> |
31 | #include <linux/kdebug.h> | 31 | #include <linux/kdebug.h> |
32 | 32 | ||
33 | #include <asm/firmware.h> | ||
33 | #include <asm/page.h> | 34 | #include <asm/page.h> |
34 | #include <asm/pgtable.h> | 35 | #include <asm/pgtable.h> |
35 | #include <asm/mmu.h> | 36 | #include <asm/mmu.h> |
@@ -318,9 +319,16 @@ good_area: | |||
318 | goto do_sigbus; | 319 | goto do_sigbus; |
319 | BUG(); | 320 | BUG(); |
320 | } | 321 | } |
321 | if (ret & VM_FAULT_MAJOR) | 322 | if (ret & VM_FAULT_MAJOR) { |
322 | current->maj_flt++; | 323 | current->maj_flt++; |
323 | else | 324 | #ifdef CONFIG_PPC_SMLPAR |
325 | if (firmware_has_feature(FW_FEATURE_CMO)) { | ||
326 | preempt_disable(); | ||
327 | get_lppaca()->page_ins += (1 << PAGE_FACTOR); | ||
328 | preempt_enable(); | ||
329 | } | ||
330 | #endif | ||
331 | } else | ||
324 | current->min_flt++; | 332 | current->min_flt++; |
325 | up_read(&mm->mmap_sem); | 333 | up_read(&mm->mmap_sem); |
326 | return 0; | 334 | return 0; |
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c index 7bbf4e4ed430..deb494687a65 100644 --- a/arch/powerpc/mm/hugetlbpage.c +++ b/arch/powerpc/mm/hugetlbpage.c | |||
@@ -53,8 +53,7 @@ unsigned int mmu_huge_psizes[MMU_PAGE_COUNT] = { }; /* initialize all to 0 */ | |||
53 | 53 | ||
54 | /* Subtract one from array size because we don't need a cache for 4K since | 54 | /* Subtract one from array size because we don't need a cache for 4K since |
55 | * is not a huge page size */ | 55 | * is not a huge page size */ |
56 | #define huge_pgtable_cache(psize) (pgtable_cache[HUGEPTE_CACHE_NUM \ | 56 | #define HUGE_PGTABLE_INDEX(psize) (HUGEPTE_CACHE_NUM + psize - 1) |
57 | + psize-1]) | ||
58 | #define HUGEPTE_CACHE_NAME(psize) (huge_pgtable_cache_name[psize]) | 57 | #define HUGEPTE_CACHE_NAME(psize) (huge_pgtable_cache_name[psize]) |
59 | 58 | ||
60 | static const char *huge_pgtable_cache_name[MMU_PAGE_COUNT] = { | 59 | static const char *huge_pgtable_cache_name[MMU_PAGE_COUNT] = { |
@@ -113,7 +112,7 @@ static inline pte_t *hugepte_offset(hugepd_t *hpdp, unsigned long addr, | |||
113 | static int __hugepte_alloc(struct mm_struct *mm, hugepd_t *hpdp, | 112 | static int __hugepte_alloc(struct mm_struct *mm, hugepd_t *hpdp, |
114 | unsigned long address, unsigned int psize) | 113 | unsigned long address, unsigned int psize) |
115 | { | 114 | { |
116 | pte_t *new = kmem_cache_zalloc(huge_pgtable_cache(psize), | 115 | pte_t *new = kmem_cache_zalloc(pgtable_cache[HUGE_PGTABLE_INDEX(psize)], |
117 | GFP_KERNEL|__GFP_REPEAT); | 116 | GFP_KERNEL|__GFP_REPEAT); |
118 | 117 | ||
119 | if (! new) | 118 | if (! new) |
@@ -121,7 +120,7 @@ static int __hugepte_alloc(struct mm_struct *mm, hugepd_t *hpdp, | |||
121 | 120 | ||
122 | spin_lock(&mm->page_table_lock); | 121 | spin_lock(&mm->page_table_lock); |
123 | if (!hugepd_none(*hpdp)) | 122 | if (!hugepd_none(*hpdp)) |
124 | kmem_cache_free(huge_pgtable_cache(psize), new); | 123 | kmem_cache_free(pgtable_cache[HUGE_PGTABLE_INDEX(psize)], new); |
125 | else | 124 | else |
126 | hpdp->pd = (unsigned long)new | HUGEPD_OK; | 125 | hpdp->pd = (unsigned long)new | HUGEPD_OK; |
127 | spin_unlock(&mm->page_table_lock); | 126 | spin_unlock(&mm->page_table_lock); |
@@ -760,13 +759,14 @@ static int __init hugetlbpage_init(void) | |||
760 | 759 | ||
761 | for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) { | 760 | for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) { |
762 | if (mmu_huge_psizes[psize]) { | 761 | if (mmu_huge_psizes[psize]) { |
763 | huge_pgtable_cache(psize) = kmem_cache_create( | 762 | pgtable_cache[HUGE_PGTABLE_INDEX(psize)] = |
764 | HUGEPTE_CACHE_NAME(psize), | 763 | kmem_cache_create( |
765 | HUGEPTE_TABLE_SIZE(psize), | 764 | HUGEPTE_CACHE_NAME(psize), |
766 | HUGEPTE_TABLE_SIZE(psize), | 765 | HUGEPTE_TABLE_SIZE(psize), |
767 | 0, | 766 | HUGEPTE_TABLE_SIZE(psize), |
768 | NULL); | 767 | 0, |
769 | if (!huge_pgtable_cache(psize)) | 768 | NULL); |
769 | if (!pgtable_cache[HUGE_PGTABLE_INDEX(psize)]) | ||
770 | panic("hugetlbpage_init(): could not create %s"\ | 770 | panic("hugetlbpage_init(): could not create %s"\ |
771 | "\n", HUGEPTE_CACHE_NAME(psize)); | 771 | "\n", HUGEPTE_CACHE_NAME(psize)); |
772 | } | 772 | } |
diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c index 3168272ab0d7..86db4dd170a0 100644 --- a/arch/powerpc/platforms/cell/iommu.c +++ b/arch/powerpc/platforms/cell/iommu.c | |||
@@ -1053,10 +1053,7 @@ static int __init cell_iommu_fixed_mapping_init(void) | |||
1053 | } | 1053 | } |
1054 | 1054 | ||
1055 | /* We must have dma-ranges properties for fixed mapping to work */ | 1055 | /* We must have dma-ranges properties for fixed mapping to work */ |
1056 | for (np = NULL; (np = of_find_all_nodes(np));) { | 1056 | np = of_find_node_with_property(NULL, "dma-ranges"); |
1057 | if (of_find_property(np, "dma-ranges", NULL)) | ||
1058 | break; | ||
1059 | } | ||
1060 | of_node_put(np); | 1057 | of_node_put(np); |
1061 | 1058 | ||
1062 | if (!np) { | 1059 | if (!np) { |
diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c index 82c14d203d8b..12937725f869 100644 --- a/arch/powerpc/platforms/powermac/setup.c +++ b/arch/powerpc/platforms/powermac/setup.c | |||
@@ -310,9 +310,7 @@ static void __init pmac_setup_arch(void) | |||
310 | } | 310 | } |
311 | 311 | ||
312 | /* See if newworld or oldworld */ | 312 | /* See if newworld or oldworld */ |
313 | for (ic = NULL; (ic = of_find_all_nodes(ic)) != NULL; ) | 313 | ic = of_find_node_with_property(NULL, "interrupt-controller"); |
314 | if (of_get_property(ic, "interrupt-controller", NULL)) | ||
315 | break; | ||
316 | if (ic) { | 314 | if (ic) { |
317 | pmac_newworld = 1; | 315 | pmac_newworld = 1; |
318 | of_node_put(ic); | 316 | of_node_put(ic); |
diff --git a/arch/powerpc/platforms/ps3/device-init.c b/arch/powerpc/platforms/ps3/device-init.c index ffdd8e963fbd..43816da25ca6 100644 --- a/arch/powerpc/platforms/ps3/device-init.c +++ b/arch/powerpc/platforms/ps3/device-init.c | |||
@@ -314,11 +314,17 @@ static int __init ps3_setup_vuart_device(enum ps3_match_id match_id, | |||
314 | 314 | ||
315 | result = ps3_system_bus_device_register(&p->dev); | 315 | result = ps3_system_bus_device_register(&p->dev); |
316 | 316 | ||
317 | if (result) | 317 | if (result) { |
318 | pr_debug("%s:%d ps3_system_bus_device_register failed\n", | 318 | pr_debug("%s:%d ps3_system_bus_device_register failed\n", |
319 | __func__, __LINE__); | 319 | __func__, __LINE__); |
320 | 320 | goto fail_device_register; | |
321 | } | ||
321 | pr_debug(" <- %s:%d\n", __func__, __LINE__); | 322 | pr_debug(" <- %s:%d\n", __func__, __LINE__); |
323 | return 0; | ||
324 | |||
325 | fail_device_register: | ||
326 | kfree(p); | ||
327 | pr_debug(" <- %s:%d fail\n", __func__, __LINE__); | ||
322 | return result; | 328 | return result; |
323 | } | 329 | } |
324 | 330 | ||
@@ -463,11 +469,17 @@ static int __init ps3_register_sound_devices(void) | |||
463 | 469 | ||
464 | result = ps3_system_bus_device_register(&p->dev); | 470 | result = ps3_system_bus_device_register(&p->dev); |
465 | 471 | ||
466 | if (result) | 472 | if (result) { |
467 | pr_debug("%s:%d ps3_system_bus_device_register failed\n", | 473 | pr_debug("%s:%d ps3_system_bus_device_register failed\n", |
468 | __func__, __LINE__); | 474 | __func__, __LINE__); |
469 | 475 | goto fail_device_register; | |
476 | } | ||
470 | pr_debug(" <- %s:%d\n", __func__, __LINE__); | 477 | pr_debug(" <- %s:%d\n", __func__, __LINE__); |
478 | return 0; | ||
479 | |||
480 | fail_device_register: | ||
481 | kfree(p); | ||
482 | pr_debug(" <- %s:%d failed\n", __func__, __LINE__); | ||
471 | return result; | 483 | return result; |
472 | } | 484 | } |
473 | 485 | ||
@@ -491,11 +503,18 @@ static int __init ps3_register_graphics_devices(void) | |||
491 | 503 | ||
492 | result = ps3_system_bus_device_register(&p->dev); | 504 | result = ps3_system_bus_device_register(&p->dev); |
493 | 505 | ||
494 | if (result) | 506 | if (result) { |
495 | pr_debug("%s:%d ps3_system_bus_device_register failed\n", | 507 | pr_debug("%s:%d ps3_system_bus_device_register failed\n", |
496 | __func__, __LINE__); | 508 | __func__, __LINE__); |
509 | goto fail_device_register; | ||
510 | } | ||
497 | 511 | ||
498 | pr_debug(" <- %s:%d\n", __func__, __LINE__); | 512 | pr_debug(" <- %s:%d\n", __func__, __LINE__); |
513 | return 0; | ||
514 | |||
515 | fail_device_register: | ||
516 | kfree(p); | ||
517 | pr_debug(" <- %s:%d failed\n", __func__, __LINE__); | ||
499 | return result; | 518 | return result; |
500 | } | 519 | } |
501 | 520 | ||
diff --git a/arch/powerpc/platforms/ps3/setup.c b/arch/powerpc/platforms/ps3/setup.c index 77bc330263c4..bfc33fb2c7c4 100644 --- a/arch/powerpc/platforms/ps3/setup.c +++ b/arch/powerpc/platforms/ps3/setup.c | |||
@@ -42,6 +42,10 @@ | |||
42 | #define DBG pr_debug | 42 | #define DBG pr_debug |
43 | #endif | 43 | #endif |
44 | 44 | ||
45 | /* mutex synchronizing GPU accesses and video mode changes */ | ||
46 | DEFINE_MUTEX(ps3_gpu_mutex); | ||
47 | EXPORT_SYMBOL_GPL(ps3_gpu_mutex); | ||
48 | |||
45 | #if !defined(CONFIG_SMP) | 49 | #if !defined(CONFIG_SMP) |
46 | static void smp_send_stop(void) {} | 50 | static void smp_send_stop(void) {} |
47 | #endif | 51 | #endif |
diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c index 54816d75b578..989d6462c154 100644 --- a/arch/powerpc/platforms/pseries/eeh.c +++ b/arch/powerpc/platforms/pseries/eeh.c | |||
@@ -21,6 +21,8 @@ | |||
21 | * Please address comments and feedback to Linas Vepstas <linas@austin.ibm.com> | 21 | * Please address comments and feedback to Linas Vepstas <linas@austin.ibm.com> |
22 | */ | 22 | */ |
23 | 23 | ||
24 | #undef DEBUG | ||
25 | |||
24 | #include <linux/delay.h> | 26 | #include <linux/delay.h> |
25 | #include <linux/init.h> | 27 | #include <linux/init.h> |
26 | #include <linux/list.h> | 28 | #include <linux/list.h> |
@@ -488,10 +490,8 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev) | |||
488 | if (!(pdn->eeh_mode & EEH_MODE_SUPPORTED) || | 490 | if (!(pdn->eeh_mode & EEH_MODE_SUPPORTED) || |
489 | pdn->eeh_mode & EEH_MODE_NOCHECK) { | 491 | pdn->eeh_mode & EEH_MODE_NOCHECK) { |
490 | ignored_check++; | 492 | ignored_check++; |
491 | #ifdef DEBUG | 493 | pr_debug("EEH: Ignored check (%x) for %s %s\n", |
492 | printk ("EEH:ignored check (%x) for %s %s\n", | 494 | pdn->eeh_mode, pci_name (dev), dn->full_name); |
493 | pdn->eeh_mode, pci_name (dev), dn->full_name); | ||
494 | #endif | ||
495 | return 0; | 495 | return 0; |
496 | } | 496 | } |
497 | 497 | ||
@@ -1014,10 +1014,9 @@ static void *early_enable_eeh(struct device_node *dn, void *data) | |||
1014 | eeh_subsystem_enabled = 1; | 1014 | eeh_subsystem_enabled = 1; |
1015 | pdn->eeh_mode |= EEH_MODE_SUPPORTED; | 1015 | pdn->eeh_mode |= EEH_MODE_SUPPORTED; |
1016 | 1016 | ||
1017 | #ifdef DEBUG | 1017 | pr_debug("EEH: %s: eeh enabled, config=%x pe_config=%x\n", |
1018 | printk(KERN_DEBUG "EEH: %s: eeh enabled, config=%x pe_config=%x\n", | 1018 | dn->full_name, pdn->eeh_config_addr, |
1019 | dn->full_name, pdn->eeh_config_addr, pdn->eeh_pe_config_addr); | 1019 | pdn->eeh_pe_config_addr); |
1020 | #endif | ||
1021 | } else { | 1020 | } else { |
1022 | 1021 | ||
1023 | /* This device doesn't support EEH, but it may have an | 1022 | /* This device doesn't support EEH, but it may have an |
@@ -1161,13 +1160,17 @@ static void eeh_add_device_late(struct pci_dev *dev) | |||
1161 | if (!dev || !eeh_subsystem_enabled) | 1160 | if (!dev || !eeh_subsystem_enabled) |
1162 | return; | 1161 | return; |
1163 | 1162 | ||
1164 | #ifdef DEBUG | 1163 | pr_debug("EEH: Adding device %s\n", pci_name(dev)); |
1165 | printk(KERN_DEBUG "EEH: adding device %s\n", pci_name(dev)); | ||
1166 | #endif | ||
1167 | 1164 | ||
1168 | pci_dev_get (dev); | ||
1169 | dn = pci_device_to_OF_node(dev); | 1165 | dn = pci_device_to_OF_node(dev); |
1170 | pdn = PCI_DN(dn); | 1166 | pdn = PCI_DN(dn); |
1167 | if (pdn->pcidev == dev) { | ||
1168 | pr_debug("EEH: Already referenced !\n"); | ||
1169 | return; | ||
1170 | } | ||
1171 | WARN_ON(pdn->pcidev); | ||
1172 | |||
1173 | pci_dev_get (dev); | ||
1171 | pdn->pcidev = dev; | 1174 | pdn->pcidev = dev; |
1172 | 1175 | ||
1173 | pci_addr_cache_insert_device(dev); | 1176 | pci_addr_cache_insert_device(dev); |
@@ -1206,17 +1209,18 @@ static void eeh_remove_device(struct pci_dev *dev) | |||
1206 | return; | 1209 | return; |
1207 | 1210 | ||
1208 | /* Unregister the device with the EEH/PCI address search system */ | 1211 | /* Unregister the device with the EEH/PCI address search system */ |
1209 | #ifdef DEBUG | 1212 | pr_debug("EEH: Removing device %s\n", pci_name(dev)); |
1210 | printk(KERN_DEBUG "EEH: remove device %s\n", pci_name(dev)); | ||
1211 | #endif | ||
1212 | pci_addr_cache_remove_device(dev); | ||
1213 | eeh_sysfs_remove_device(dev); | ||
1214 | 1213 | ||
1215 | dn = pci_device_to_OF_node(dev); | 1214 | dn = pci_device_to_OF_node(dev); |
1216 | if (PCI_DN(dn)->pcidev) { | 1215 | if (PCI_DN(dn)->pcidev == NULL) { |
1217 | PCI_DN(dn)->pcidev = NULL; | 1216 | pr_debug("EEH: Not referenced !\n"); |
1218 | pci_dev_put (dev); | 1217 | return; |
1219 | } | 1218 | } |
1219 | PCI_DN(dn)->pcidev = NULL; | ||
1220 | pci_dev_put (dev); | ||
1221 | |||
1222 | pci_addr_cache_remove_device(dev); | ||
1223 | eeh_sysfs_remove_device(dev); | ||
1220 | } | 1224 | } |
1221 | 1225 | ||
1222 | void eeh_remove_bus_device(struct pci_dev *dev) | 1226 | void eeh_remove_bus_device(struct pci_dev *dev) |
diff --git a/arch/powerpc/platforms/pseries/pci_dlpar.c b/arch/powerpc/platforms/pseries/pci_dlpar.c index 7190493e9bdc..5e1ed3d60ee5 100644 --- a/arch/powerpc/platforms/pseries/pci_dlpar.c +++ b/arch/powerpc/platforms/pseries/pci_dlpar.c | |||
@@ -25,6 +25,8 @@ | |||
25 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 25 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | #undef DEBUG | ||
29 | |||
28 | #include <linux/pci.h> | 30 | #include <linux/pci.h> |
29 | #include <asm/pci-bridge.h> | 31 | #include <asm/pci-bridge.h> |
30 | #include <asm/ppc-pci.h> | 32 | #include <asm/ppc-pci.h> |
@@ -69,74 +71,25 @@ EXPORT_SYMBOL_GPL(pcibios_find_pci_bus); | |||
69 | * Remove all of the PCI devices under this bus both from the | 71 | * Remove all of the PCI devices under this bus both from the |
70 | * linux pci device tree, and from the powerpc EEH address cache. | 72 | * linux pci device tree, and from the powerpc EEH address cache. |
71 | */ | 73 | */ |
72 | void | 74 | void pcibios_remove_pci_devices(struct pci_bus *bus) |
73 | pcibios_remove_pci_devices(struct pci_bus *bus) | ||
74 | { | 75 | { |
75 | struct pci_dev *dev, *tmp; | 76 | struct pci_dev *dev, *tmp; |
77 | struct pci_bus *child_bus; | ||
78 | |||
79 | /* First go down child busses */ | ||
80 | list_for_each_entry(child_bus, &bus->children, node) | ||
81 | pcibios_remove_pci_devices(child_bus); | ||
76 | 82 | ||
83 | pr_debug("PCI: Removing devices on bus %04x:%02x\n", | ||
84 | pci_domain_nr(bus), bus->number); | ||
77 | list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) { | 85 | list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) { |
86 | pr_debug(" * Removing %s...\n", pci_name(dev)); | ||
78 | eeh_remove_bus_device(dev); | 87 | eeh_remove_bus_device(dev); |
79 | pci_remove_bus_device(dev); | 88 | pci_remove_bus_device(dev); |
80 | } | 89 | } |
81 | } | 90 | } |
82 | EXPORT_SYMBOL_GPL(pcibios_remove_pci_devices); | 91 | EXPORT_SYMBOL_GPL(pcibios_remove_pci_devices); |
83 | 92 | ||
84 | /* Must be called before pci_bus_add_devices */ | ||
85 | void | ||
86 | pcibios_fixup_new_pci_devices(struct pci_bus *bus) | ||
87 | { | ||
88 | struct pci_dev *dev; | ||
89 | |||
90 | list_for_each_entry(dev, &bus->devices, bus_list) { | ||
91 | /* Skip already-added devices */ | ||
92 | if (!dev->is_added) { | ||
93 | int i; | ||
94 | |||
95 | /* Fill device archdata and setup iommu table */ | ||
96 | pcibios_setup_new_device(dev); | ||
97 | |||
98 | pci_read_irq_line(dev); | ||
99 | for (i = 0; i < PCI_NUM_RESOURCES; i++) { | ||
100 | struct resource *r = &dev->resource[i]; | ||
101 | |||
102 | if (r->parent || !r->start || !r->flags) | ||
103 | continue; | ||
104 | pci_claim_resource(dev, i); | ||
105 | } | ||
106 | } | ||
107 | } | ||
108 | } | ||
109 | EXPORT_SYMBOL_GPL(pcibios_fixup_new_pci_devices); | ||
110 | |||
111 | static int | ||
112 | pcibios_pci_config_bridge(struct pci_dev *dev) | ||
113 | { | ||
114 | u8 sec_busno; | ||
115 | struct pci_bus *child_bus; | ||
116 | |||
117 | /* Get busno of downstream bus */ | ||
118 | pci_read_config_byte(dev, PCI_SECONDARY_BUS, &sec_busno); | ||
119 | |||
120 | /* Add to children of PCI bridge dev->bus */ | ||
121 | child_bus = pci_add_new_bus(dev->bus, dev, sec_busno); | ||
122 | if (!child_bus) { | ||
123 | printk (KERN_ERR "%s: could not add second bus\n", __func__); | ||
124 | return -EIO; | ||
125 | } | ||
126 | sprintf(child_bus->name, "PCI Bus #%02x", child_bus->number); | ||
127 | |||
128 | pci_scan_child_bus(child_bus); | ||
129 | |||
130 | /* Fixup new pci devices */ | ||
131 | pcibios_fixup_new_pci_devices(child_bus); | ||
132 | |||
133 | /* Make the discovered devices available */ | ||
134 | pci_bus_add_devices(child_bus); | ||
135 | |||
136 | eeh_add_device_tree_late(child_bus); | ||
137 | return 0; | ||
138 | } | ||
139 | |||
140 | /** | 93 | /** |
141 | * pcibios_add_pci_devices - adds new pci devices to bus | 94 | * pcibios_add_pci_devices - adds new pci devices to bus |
142 | * | 95 | * |
@@ -147,10 +100,9 @@ pcibios_pci_config_bridge(struct pci_dev *dev) | |||
147 | * is how this routine differs from other, similar pcibios | 100 | * is how this routine differs from other, similar pcibios |
148 | * routines.) | 101 | * routines.) |
149 | */ | 102 | */ |
150 | void | 103 | void pcibios_add_pci_devices(struct pci_bus * bus) |
151 | pcibios_add_pci_devices(struct pci_bus * bus) | ||
152 | { | 104 | { |
153 | int slotno, num, mode; | 105 | int slotno, num, mode, pass, max; |
154 | struct pci_dev *dev; | 106 | struct pci_dev *dev; |
155 | struct device_node *dn = pci_bus_to_OF_node(bus); | 107 | struct device_node *dn = pci_bus_to_OF_node(bus); |
156 | 108 | ||
@@ -162,26 +114,23 @@ pcibios_add_pci_devices(struct pci_bus * bus) | |||
162 | 114 | ||
163 | if (mode == PCI_PROBE_DEVTREE) { | 115 | if (mode == PCI_PROBE_DEVTREE) { |
164 | /* use ofdt-based probe */ | 116 | /* use ofdt-based probe */ |
165 | of_scan_bus(dn, bus); | 117 | of_rescan_bus(dn, bus); |
166 | if (!list_empty(&bus->devices)) { | ||
167 | pcibios_fixup_new_pci_devices(bus); | ||
168 | pci_bus_add_devices(bus); | ||
169 | eeh_add_device_tree_late(bus); | ||
170 | } | ||
171 | } else if (mode == PCI_PROBE_NORMAL) { | 118 | } else if (mode == PCI_PROBE_NORMAL) { |
172 | /* use legacy probe */ | 119 | /* use legacy probe */ |
173 | slotno = PCI_SLOT(PCI_DN(dn->child)->devfn); | 120 | slotno = PCI_SLOT(PCI_DN(dn->child)->devfn); |
174 | num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0)); | 121 | num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0)); |
175 | if (num) { | 122 | if (!num) |
176 | pcibios_fixup_new_pci_devices(bus); | 123 | return; |
177 | pci_bus_add_devices(bus); | 124 | pcibios_setup_bus_devices(bus); |
178 | eeh_add_device_tree_late(bus); | 125 | max = bus->secondary; |
126 | for (pass=0; pass < 2; pass++) | ||
127 | list_for_each_entry(dev, &bus->devices, bus_list) { | ||
128 | if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || | ||
129 | dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) | ||
130 | max = pci_scan_bridge(bus, dev, max, pass); | ||
179 | } | 131 | } |
180 | |||
181 | list_for_each_entry(dev, &bus->devices, bus_list) | ||
182 | if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) | ||
183 | pcibios_pci_config_bridge(dev); | ||
184 | } | 132 | } |
133 | pcibios_finish_adding_to_bus(bus); | ||
185 | } | 134 | } |
186 | EXPORT_SYMBOL_GPL(pcibios_add_pci_devices); | 135 | EXPORT_SYMBOL_GPL(pcibios_add_pci_devices); |
187 | 136 | ||
@@ -190,6 +139,8 @@ struct pci_controller * __devinit init_phb_dynamic(struct device_node *dn) | |||
190 | struct pci_controller *phb; | 139 | struct pci_controller *phb; |
191 | int primary; | 140 | int primary; |
192 | 141 | ||
142 | pr_debug("PCI: Initializing new hotplug PHB %s\n", dn->full_name); | ||
143 | |||
193 | primary = list_empty(&hose_list); | 144 | primary = list_empty(&hose_list); |
194 | phb = pcibios_alloc_controller(dn); | 145 | phb = pcibios_alloc_controller(dn); |
195 | if (!phb) | 146 | if (!phb) |
@@ -203,11 +154,59 @@ struct pci_controller * __devinit init_phb_dynamic(struct device_node *dn) | |||
203 | eeh_add_device_tree_early(dn); | 154 | eeh_add_device_tree_early(dn); |
204 | 155 | ||
205 | scan_phb(phb); | 156 | scan_phb(phb); |
206 | pcibios_allocate_bus_resources(phb->bus); | 157 | pcibios_finish_adding_to_bus(phb->bus); |
207 | pcibios_fixup_new_pci_devices(phb->bus); | ||
208 | pci_bus_add_devices(phb->bus); | ||
209 | eeh_add_device_tree_late(phb->bus); | ||
210 | 158 | ||
211 | return phb; | 159 | return phb; |
212 | } | 160 | } |
213 | EXPORT_SYMBOL_GPL(init_phb_dynamic); | 161 | EXPORT_SYMBOL_GPL(init_phb_dynamic); |
162 | |||
163 | /* RPA-specific bits for removing PHBs */ | ||
164 | int remove_phb_dynamic(struct pci_controller *phb) | ||
165 | { | ||
166 | struct pci_bus *b = phb->bus; | ||
167 | struct resource *res; | ||
168 | int rc, i; | ||
169 | |||
170 | pr_debug("PCI: Removing PHB %04x:%02x... \n", | ||
171 | pci_domain_nr(b), b->number); | ||
172 | |||
173 | /* We cannot to remove a root bus that has children */ | ||
174 | if (!(list_empty(&b->children) && list_empty(&b->devices))) | ||
175 | return -EBUSY; | ||
176 | |||
177 | /* We -know- there aren't any child devices anymore at this stage | ||
178 | * and thus, we can safely unmap the IO space as it's not in use | ||
179 | */ | ||
180 | res = &phb->io_resource; | ||
181 | if (res->flags & IORESOURCE_IO) { | ||
182 | rc = pcibios_unmap_io_space(b); | ||
183 | if (rc) { | ||
184 | printk(KERN_ERR "%s: failed to unmap IO on bus %s\n", | ||
185 | __func__, b->name); | ||
186 | return 1; | ||
187 | } | ||
188 | } | ||
189 | |||
190 | /* Unregister the bridge device from sysfs and remove the PCI bus */ | ||
191 | device_unregister(b->bridge); | ||
192 | phb->bus = NULL; | ||
193 | pci_remove_bus(b); | ||
194 | |||
195 | /* Now release the IO resource */ | ||
196 | if (res->flags & IORESOURCE_IO) | ||
197 | release_resource(res); | ||
198 | |||
199 | /* Release memory resources */ | ||
200 | for (i = 0; i < 3; ++i) { | ||
201 | res = &phb->mem_resources[i]; | ||
202 | if (!(res->flags & IORESOURCE_MEM)) | ||
203 | continue; | ||
204 | release_resource(res); | ||
205 | } | ||
206 | |||
207 | /* Free pci_controller data structure */ | ||
208 | pcibios_free_controller(phb); | ||
209 | |||
210 | return 0; | ||
211 | } | ||
212 | EXPORT_SYMBOL_GPL(remove_phb_dynamic); | ||
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c index e1904774a70f..75a289ba66b8 100644 --- a/arch/powerpc/platforms/pseries/xics.c +++ b/arch/powerpc/platforms/pseries/xics.c | |||
@@ -579,7 +579,7 @@ static void xics_update_irq_servers(void) | |||
579 | int i, j; | 579 | int i, j; |
580 | struct device_node *np; | 580 | struct device_node *np; |
581 | u32 ilen; | 581 | u32 ilen; |
582 | const u32 *ireg, *isize; | 582 | const u32 *ireg; |
583 | u32 hcpuid; | 583 | u32 hcpuid; |
584 | 584 | ||
585 | /* Find the server numbers for the boot cpu. */ | 585 | /* Find the server numbers for the boot cpu. */ |
@@ -607,11 +607,6 @@ static void xics_update_irq_servers(void) | |||
607 | } | 607 | } |
608 | } | 608 | } |
609 | 609 | ||
610 | /* get the bit size of server numbers */ | ||
611 | isize = of_get_property(np, "ibm,interrupt-server#-size", NULL); | ||
612 | if (isize) | ||
613 | interrupt_server_size = *isize; | ||
614 | |||
615 | of_node_put(np); | 610 | of_node_put(np); |
616 | } | 611 | } |
617 | 612 | ||
@@ -682,6 +677,7 @@ void __init xics_init_IRQ(void) | |||
682 | struct device_node *np; | 677 | struct device_node *np; |
683 | u32 indx = 0; | 678 | u32 indx = 0; |
684 | int found = 0; | 679 | int found = 0; |
680 | const u32 *isize; | ||
685 | 681 | ||
686 | ppc64_boot_msg(0x20, "XICS Init"); | 682 | ppc64_boot_msg(0x20, "XICS Init"); |
687 | 683 | ||
@@ -701,6 +697,26 @@ void __init xics_init_IRQ(void) | |||
701 | if (found == 0) | 697 | if (found == 0) |
702 | return; | 698 | return; |
703 | 699 | ||
700 | /* get the bit size of server numbers */ | ||
701 | found = 0; | ||
702 | |||
703 | for_each_compatible_node(np, NULL, "ibm,ppc-xics") { | ||
704 | isize = of_get_property(np, "ibm,interrupt-server#-size", NULL); | ||
705 | |||
706 | if (!isize) | ||
707 | continue; | ||
708 | |||
709 | if (!found) { | ||
710 | interrupt_server_size = *isize; | ||
711 | found = 1; | ||
712 | } else if (*isize != interrupt_server_size) { | ||
713 | printk(KERN_WARNING "XICS: " | ||
714 | "mismatched ibm,interrupt-server#-size\n"); | ||
715 | interrupt_server_size = max(*isize, | ||
716 | interrupt_server_size); | ||
717 | } | ||
718 | } | ||
719 | |||
704 | xics_update_irq_servers(); | 720 | xics_update_irq_servers(); |
705 | xics_init_host(); | 721 | xics_init_host(); |
706 | 722 | ||
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index 1890fb085cde..c82babb70074 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c | |||
@@ -661,17 +661,6 @@ static inline void mpic_eoi(struct mpic *mpic) | |||
661 | (void)mpic_cpu_read(MPIC_INFO(CPU_WHOAMI)); | 661 | (void)mpic_cpu_read(MPIC_INFO(CPU_WHOAMI)); |
662 | } | 662 | } |
663 | 663 | ||
664 | #ifdef CONFIG_SMP | ||
665 | static irqreturn_t mpic_ipi_action(int irq, void *data) | ||
666 | { | ||
667 | long ipi = (long)data; | ||
668 | |||
669 | smp_message_recv(ipi); | ||
670 | |||
671 | return IRQ_HANDLED; | ||
672 | } | ||
673 | #endif /* CONFIG_SMP */ | ||
674 | |||
675 | /* | 664 | /* |
676 | * Linux descriptor level callbacks | 665 | * Linux descriptor level callbacks |
677 | */ | 666 | */ |
@@ -1548,13 +1537,7 @@ unsigned int mpic_get_mcirq(void) | |||
1548 | void mpic_request_ipis(void) | 1537 | void mpic_request_ipis(void) |
1549 | { | 1538 | { |
1550 | struct mpic *mpic = mpic_primary; | 1539 | struct mpic *mpic = mpic_primary; |
1551 | long i, err; | 1540 | int i; |
1552 | static char *ipi_names[] = { | ||
1553 | "IPI0 (call function)", | ||
1554 | "IPI1 (reschedule)", | ||
1555 | "IPI2 (call function single)", | ||
1556 | "IPI3 (debugger break)", | ||
1557 | }; | ||
1558 | BUG_ON(mpic == NULL); | 1541 | BUG_ON(mpic == NULL); |
1559 | 1542 | ||
1560 | printk(KERN_INFO "mpic: requesting IPIs ... \n"); | 1543 | printk(KERN_INFO "mpic: requesting IPIs ... \n"); |
@@ -1563,17 +1546,10 @@ void mpic_request_ipis(void) | |||
1563 | unsigned int vipi = irq_create_mapping(mpic->irqhost, | 1546 | unsigned int vipi = irq_create_mapping(mpic->irqhost, |
1564 | mpic->ipi_vecs[0] + i); | 1547 | mpic->ipi_vecs[0] + i); |
1565 | if (vipi == NO_IRQ) { | 1548 | if (vipi == NO_IRQ) { |
1566 | printk(KERN_ERR "Failed to map IPI %ld\n", i); | 1549 | printk(KERN_ERR "Failed to map %s\n", smp_ipi_name[i]); |
1567 | break; | 1550 | continue; |
1568 | } | ||
1569 | err = request_irq(vipi, mpic_ipi_action, | ||
1570 | IRQF_DISABLED|IRQF_PERCPU, | ||
1571 | ipi_names[i], (void *)i); | ||
1572 | if (err) { | ||
1573 | printk(KERN_ERR "Request of irq %d for IPI %ld failed\n", | ||
1574 | vipi, i); | ||
1575 | break; | ||
1576 | } | 1551 | } |
1552 | smp_request_message_ipi(vipi, i); | ||
1577 | } | 1553 | } |
1578 | } | 1554 | } |
1579 | 1555 | ||