diff options
Diffstat (limited to 'arch')
50 files changed, 778 insertions, 647 deletions
diff --git a/arch/arm/mach-imx/mach-cpuimx27.c b/arch/arm/mach-imx/mach-cpuimx27.c index 575ff1ae85a7..339150ab0ea5 100644 --- a/arch/arm/mach-imx/mach-cpuimx27.c +++ b/arch/arm/mach-imx/mach-cpuimx27.c | |||
@@ -279,13 +279,13 @@ static void __init eukrea_cpuimx27_init(void) | |||
279 | #if defined(CONFIG_USB_ULPI) | 279 | #if defined(CONFIG_USB_ULPI) |
280 | if (otg_mode_host) { | 280 | if (otg_mode_host) { |
281 | otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, | 281 | otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, |
282 | USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT); | 282 | ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT); |
283 | 283 | ||
284 | mxc_register_device(&mxc_otg_host, &otg_pdata); | 284 | mxc_register_device(&mxc_otg_host, &otg_pdata); |
285 | } | 285 | } |
286 | 286 | ||
287 | usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, | 287 | usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, |
288 | USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT); | 288 | ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT); |
289 | 289 | ||
290 | mxc_register_device(&mxc_usbh2, &usbh2_pdata); | 290 | mxc_register_device(&mxc_usbh2, &usbh2_pdata); |
291 | #endif | 291 | #endif |
diff --git a/arch/arm/mach-imx/mach-pca100.c b/arch/arm/mach-imx/mach-pca100.c index a389d1148f18..23c9e1f37b9c 100644 --- a/arch/arm/mach-imx/mach-pca100.c +++ b/arch/arm/mach-imx/mach-pca100.c | |||
@@ -419,13 +419,13 @@ static void __init pca100_init(void) | |||
419 | #if defined(CONFIG_USB_ULPI) | 419 | #if defined(CONFIG_USB_ULPI) |
420 | if (otg_mode_host) { | 420 | if (otg_mode_host) { |
421 | otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, | 421 | otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, |
422 | USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT); | 422 | ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT); |
423 | 423 | ||
424 | mxc_register_device(&mxc_otg_host, &otg_pdata); | 424 | mxc_register_device(&mxc_otg_host, &otg_pdata); |
425 | } | 425 | } |
426 | 426 | ||
427 | usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, | 427 | usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, |
428 | USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT); | 428 | ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT); |
429 | 429 | ||
430 | mxc_register_device(&mxc_usbh2, &usbh2_pdata); | 430 | mxc_register_device(&mxc_usbh2, &usbh2_pdata); |
431 | #endif | 431 | #endif |
diff --git a/arch/arm/mach-mx25/mach-cpuimx25.c b/arch/arm/mach-mx25/mach-cpuimx25.c index 56b2e26d23b4..a5f0174290b4 100644 --- a/arch/arm/mach-mx25/mach-cpuimx25.c +++ b/arch/arm/mach-mx25/mach-cpuimx25.c | |||
@@ -138,7 +138,7 @@ static void __init eukrea_cpuimx25_init(void) | |||
138 | #if defined(CONFIG_USB_ULPI) | 138 | #if defined(CONFIG_USB_ULPI) |
139 | if (otg_mode_host) { | 139 | if (otg_mode_host) { |
140 | otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, | 140 | otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, |
141 | USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT); | 141 | ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT); |
142 | 142 | ||
143 | mxc_register_device(&mxc_otg, &otg_pdata); | 143 | mxc_register_device(&mxc_otg, &otg_pdata); |
144 | } | 144 | } |
diff --git a/arch/arm/mach-mx3/mach-cpuimx35.c b/arch/arm/mach-mx3/mach-cpuimx35.c index 63f970f340a2..9770a6a973be 100644 --- a/arch/arm/mach-mx3/mach-cpuimx35.c +++ b/arch/arm/mach-mx3/mach-cpuimx35.c | |||
@@ -192,7 +192,7 @@ static void __init mxc_board_init(void) | |||
192 | #if defined(CONFIG_USB_ULPI) | 192 | #if defined(CONFIG_USB_ULPI) |
193 | if (otg_mode_host) { | 193 | if (otg_mode_host) { |
194 | otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, | 194 | otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, |
195 | USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT); | 195 | ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT); |
196 | 196 | ||
197 | mxc_register_device(&mxc_otg_host, &otg_pdata); | 197 | mxc_register_device(&mxc_otg_host, &otg_pdata); |
198 | } | 198 | } |
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index e3ea151c9597..b7212b619c52 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile | |||
@@ -164,7 +164,7 @@ drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/ | |||
164 | all: zImage | 164 | all: zImage |
165 | 165 | ||
166 | # With make 3.82 we cannot mix normal and wildcard targets | 166 | # With make 3.82 we cannot mix normal and wildcard targets |
167 | BOOT_TARGETS1 := zImage zImage.initrd uImaged | 167 | BOOT_TARGETS1 := zImage zImage.initrd uImage |
168 | BOOT_TARGETS2 := zImage% dtbImage% treeImage.% cuImage.% simpleImage.% | 168 | BOOT_TARGETS2 := zImage% dtbImage% treeImage.% cuImage.% simpleImage.% |
169 | 169 | ||
170 | PHONY += $(BOOT_TARGETS1) $(BOOT_TARGETS2) | 170 | PHONY += $(BOOT_TARGETS1) $(BOOT_TARGETS2) |
diff --git a/arch/powerpc/boot/dts/canyonlands.dts b/arch/powerpc/boot/dts/canyonlands.dts index 5806ef0b860b..a30370396250 100644 --- a/arch/powerpc/boot/dts/canyonlands.dts +++ b/arch/powerpc/boot/dts/canyonlands.dts | |||
@@ -163,6 +163,14 @@ | |||
163 | interrupts = <0x1e 4>; | 163 | interrupts = <0x1e 4>; |
164 | }; | 164 | }; |
165 | 165 | ||
166 | SATA0: sata@bffd1000 { | ||
167 | compatible = "amcc,sata-460ex"; | ||
168 | reg = <4 0xbffd1000 0x800 4 0xbffd0800 0x400>; | ||
169 | interrupt-parent = <&UIC3>; | ||
170 | interrupts = <0x0 0x4 /* SATA */ | ||
171 | 0x5 0x4>; /* AHBDMA */ | ||
172 | }; | ||
173 | |||
166 | POB0: opb { | 174 | POB0: opb { |
167 | compatible = "ibm,opb-460ex", "ibm,opb"; | 175 | compatible = "ibm,opb-460ex", "ibm,opb"; |
168 | #address-cells = <1>; | 176 | #address-cells = <1>; |
diff --git a/arch/powerpc/include/asm/mmu-hash64.h b/arch/powerpc/include/asm/mmu-hash64.h index 0e398cfee2c8..acac35d5b382 100644 --- a/arch/powerpc/include/asm/mmu-hash64.h +++ b/arch/powerpc/include/asm/mmu-hash64.h | |||
@@ -433,7 +433,7 @@ typedef struct { | |||
433 | * with. However gcc is not clever enough to compute the | 433 | * with. However gcc is not clever enough to compute the |
434 | * modulus (2^n-1) without a second multiply. | 434 | * modulus (2^n-1) without a second multiply. |
435 | */ | 435 | */ |
436 | #define vsid_scrample(protovsid, size) \ | 436 | #define vsid_scramble(protovsid, size) \ |
437 | ((((protovsid) * VSID_MULTIPLIER_##size) % VSID_MODULUS_##size)) | 437 | ((((protovsid) * VSID_MULTIPLIER_##size) % VSID_MODULUS_##size)) |
438 | 438 | ||
439 | #else /* 1 */ | 439 | #else /* 1 */ |
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h index d8be016d2ede..ff0005eec7dd 100644 --- a/arch/powerpc/include/asm/reg.h +++ b/arch/powerpc/include/asm/reg.h | |||
@@ -951,7 +951,14 @@ | |||
951 | #ifdef CONFIG_PPC64 | 951 | #ifdef CONFIG_PPC64 |
952 | 952 | ||
953 | extern void ppc64_runlatch_on(void); | 953 | extern void ppc64_runlatch_on(void); |
954 | extern void ppc64_runlatch_off(void); | 954 | extern void __ppc64_runlatch_off(void); |
955 | |||
956 | #define ppc64_runlatch_off() \ | ||
957 | do { \ | ||
958 | if (cpu_has_feature(CPU_FTR_CTRL) && \ | ||
959 | test_thread_flag(TIF_RUNLATCH)) \ | ||
960 | __ppc64_runlatch_off(); \ | ||
961 | } while (0) | ||
955 | 962 | ||
956 | extern unsigned long scom970_read(unsigned int address); | 963 | extern unsigned long scom970_read(unsigned int address); |
957 | extern void scom970_write(unsigned int address, unsigned long value); | 964 | extern void scom970_write(unsigned int address, unsigned long value); |
diff --git a/arch/powerpc/include/asm/rwsem.h b/arch/powerpc/include/asm/rwsem.h index 24cd9281ec37..8447d89fbe72 100644 --- a/arch/powerpc/include/asm/rwsem.h +++ b/arch/powerpc/include/asm/rwsem.h | |||
@@ -21,15 +21,20 @@ | |||
21 | /* | 21 | /* |
22 | * the semaphore definition | 22 | * the semaphore definition |
23 | */ | 23 | */ |
24 | struct rw_semaphore { | 24 | #ifdef CONFIG_PPC64 |
25 | /* XXX this should be able to be an atomic_t -- paulus */ | 25 | # define RWSEM_ACTIVE_MASK 0xffffffffL |
26 | signed int count; | 26 | #else |
27 | #define RWSEM_UNLOCKED_VALUE 0x00000000 | 27 | # define RWSEM_ACTIVE_MASK 0x0000ffffL |
28 | #define RWSEM_ACTIVE_BIAS 0x00000001 | 28 | #endif |
29 | #define RWSEM_ACTIVE_MASK 0x0000ffff | 29 | |
30 | #define RWSEM_WAITING_BIAS (-0x00010000) | 30 | #define RWSEM_UNLOCKED_VALUE 0x00000000L |
31 | #define RWSEM_ACTIVE_BIAS 0x00000001L | ||
32 | #define RWSEM_WAITING_BIAS (-RWSEM_ACTIVE_MASK-1) | ||
31 | #define RWSEM_ACTIVE_READ_BIAS RWSEM_ACTIVE_BIAS | 33 | #define RWSEM_ACTIVE_READ_BIAS RWSEM_ACTIVE_BIAS |
32 | #define RWSEM_ACTIVE_WRITE_BIAS (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS) | 34 | #define RWSEM_ACTIVE_WRITE_BIAS (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS) |
35 | |||
36 | struct rw_semaphore { | ||
37 | long count; | ||
33 | spinlock_t wait_lock; | 38 | spinlock_t wait_lock; |
34 | struct list_head wait_list; | 39 | struct list_head wait_list; |
35 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | 40 | #ifdef CONFIG_DEBUG_LOCK_ALLOC |
@@ -43,9 +48,13 @@ struct rw_semaphore { | |||
43 | # define __RWSEM_DEP_MAP_INIT(lockname) | 48 | # define __RWSEM_DEP_MAP_INIT(lockname) |
44 | #endif | 49 | #endif |
45 | 50 | ||
46 | #define __RWSEM_INITIALIZER(name) \ | 51 | #define __RWSEM_INITIALIZER(name) \ |
47 | { RWSEM_UNLOCKED_VALUE, __SPIN_LOCK_UNLOCKED((name).wait_lock), \ | 52 | { \ |
48 | LIST_HEAD_INIT((name).wait_list) __RWSEM_DEP_MAP_INIT(name) } | 53 | RWSEM_UNLOCKED_VALUE, \ |
54 | __SPIN_LOCK_UNLOCKED((name).wait_lock), \ | ||
55 | LIST_HEAD_INIT((name).wait_list) \ | ||
56 | __RWSEM_DEP_MAP_INIT(name) \ | ||
57 | } | ||
49 | 58 | ||
50 | #define DECLARE_RWSEM(name) \ | 59 | #define DECLARE_RWSEM(name) \ |
51 | struct rw_semaphore name = __RWSEM_INITIALIZER(name) | 60 | struct rw_semaphore name = __RWSEM_INITIALIZER(name) |
@@ -70,13 +79,13 @@ extern void __init_rwsem(struct rw_semaphore *sem, const char *name, | |||
70 | */ | 79 | */ |
71 | static inline void __down_read(struct rw_semaphore *sem) | 80 | static inline void __down_read(struct rw_semaphore *sem) |
72 | { | 81 | { |
73 | if (unlikely(atomic_inc_return((atomic_t *)(&sem->count)) <= 0)) | 82 | if (unlikely(atomic_long_inc_return((atomic_long_t *)&sem->count) <= 0)) |
74 | rwsem_down_read_failed(sem); | 83 | rwsem_down_read_failed(sem); |
75 | } | 84 | } |
76 | 85 | ||
77 | static inline int __down_read_trylock(struct rw_semaphore *sem) | 86 | static inline int __down_read_trylock(struct rw_semaphore *sem) |
78 | { | 87 | { |
79 | int tmp; | 88 | long tmp; |
80 | 89 | ||
81 | while ((tmp = sem->count) >= 0) { | 90 | while ((tmp = sem->count) >= 0) { |
82 | if (tmp == cmpxchg(&sem->count, tmp, | 91 | if (tmp == cmpxchg(&sem->count, tmp, |
@@ -92,10 +101,10 @@ static inline int __down_read_trylock(struct rw_semaphore *sem) | |||
92 | */ | 101 | */ |
93 | static inline void __down_write_nested(struct rw_semaphore *sem, int subclass) | 102 | static inline void __down_write_nested(struct rw_semaphore *sem, int subclass) |
94 | { | 103 | { |
95 | int tmp; | 104 | long tmp; |
96 | 105 | ||
97 | tmp = atomic_add_return(RWSEM_ACTIVE_WRITE_BIAS, | 106 | tmp = atomic_long_add_return(RWSEM_ACTIVE_WRITE_BIAS, |
98 | (atomic_t *)(&sem->count)); | 107 | (atomic_long_t *)&sem->count); |
99 | if (unlikely(tmp != RWSEM_ACTIVE_WRITE_BIAS)) | 108 | if (unlikely(tmp != RWSEM_ACTIVE_WRITE_BIAS)) |
100 | rwsem_down_write_failed(sem); | 109 | rwsem_down_write_failed(sem); |
101 | } | 110 | } |
@@ -107,7 +116,7 @@ static inline void __down_write(struct rw_semaphore *sem) | |||
107 | 116 | ||
108 | static inline int __down_write_trylock(struct rw_semaphore *sem) | 117 | static inline int __down_write_trylock(struct rw_semaphore *sem) |
109 | { | 118 | { |
110 | int tmp; | 119 | long tmp; |
111 | 120 | ||
112 | tmp = cmpxchg(&sem->count, RWSEM_UNLOCKED_VALUE, | 121 | tmp = cmpxchg(&sem->count, RWSEM_UNLOCKED_VALUE, |
113 | RWSEM_ACTIVE_WRITE_BIAS); | 122 | RWSEM_ACTIVE_WRITE_BIAS); |
@@ -119,9 +128,9 @@ static inline int __down_write_trylock(struct rw_semaphore *sem) | |||
119 | */ | 128 | */ |
120 | static inline void __up_read(struct rw_semaphore *sem) | 129 | static inline void __up_read(struct rw_semaphore *sem) |
121 | { | 130 | { |
122 | int tmp; | 131 | long tmp; |
123 | 132 | ||
124 | tmp = atomic_dec_return((atomic_t *)(&sem->count)); | 133 | tmp = atomic_long_dec_return((atomic_long_t *)&sem->count); |
125 | if (unlikely(tmp < -1 && (tmp & RWSEM_ACTIVE_MASK) == 0)) | 134 | if (unlikely(tmp < -1 && (tmp & RWSEM_ACTIVE_MASK) == 0)) |
126 | rwsem_wake(sem); | 135 | rwsem_wake(sem); |
127 | } | 136 | } |
@@ -131,17 +140,17 @@ static inline void __up_read(struct rw_semaphore *sem) | |||
131 | */ | 140 | */ |
132 | static inline void __up_write(struct rw_semaphore *sem) | 141 | static inline void __up_write(struct rw_semaphore *sem) |
133 | { | 142 | { |
134 | if (unlikely(atomic_sub_return(RWSEM_ACTIVE_WRITE_BIAS, | 143 | if (unlikely(atomic_long_sub_return(RWSEM_ACTIVE_WRITE_BIAS, |
135 | (atomic_t *)(&sem->count)) < 0)) | 144 | (atomic_long_t *)&sem->count) < 0)) |
136 | rwsem_wake(sem); | 145 | rwsem_wake(sem); |
137 | } | 146 | } |
138 | 147 | ||
139 | /* | 148 | /* |
140 | * implement atomic add functionality | 149 | * implement atomic add functionality |
141 | */ | 150 | */ |
142 | static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem) | 151 | static inline void rwsem_atomic_add(long delta, struct rw_semaphore *sem) |
143 | { | 152 | { |
144 | atomic_add(delta, (atomic_t *)(&sem->count)); | 153 | atomic_long_add(delta, (atomic_long_t *)&sem->count); |
145 | } | 154 | } |
146 | 155 | ||
147 | /* | 156 | /* |
@@ -149,9 +158,10 @@ static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem) | |||
149 | */ | 158 | */ |
150 | static inline void __downgrade_write(struct rw_semaphore *sem) | 159 | static inline void __downgrade_write(struct rw_semaphore *sem) |
151 | { | 160 | { |
152 | int tmp; | 161 | long tmp; |
153 | 162 | ||
154 | tmp = atomic_add_return(-RWSEM_WAITING_BIAS, (atomic_t *)(&sem->count)); | 163 | tmp = atomic_long_add_return(-RWSEM_WAITING_BIAS, |
164 | (atomic_long_t *)&sem->count); | ||
155 | if (tmp < 0) | 165 | if (tmp < 0) |
156 | rwsem_downgrade_wake(sem); | 166 | rwsem_downgrade_wake(sem); |
157 | } | 167 | } |
@@ -159,14 +169,14 @@ static inline void __downgrade_write(struct rw_semaphore *sem) | |||
159 | /* | 169 | /* |
160 | * implement exchange and add functionality | 170 | * implement exchange and add functionality |
161 | */ | 171 | */ |
162 | static inline int rwsem_atomic_update(int delta, struct rw_semaphore *sem) | 172 | static inline long rwsem_atomic_update(long delta, struct rw_semaphore *sem) |
163 | { | 173 | { |
164 | return atomic_add_return(delta, (atomic_t *)(&sem->count)); | 174 | return atomic_long_add_return(delta, (atomic_long_t *)&sem->count); |
165 | } | 175 | } |
166 | 176 | ||
167 | static inline int rwsem_is_locked(struct rw_semaphore *sem) | 177 | static inline int rwsem_is_locked(struct rw_semaphore *sem) |
168 | { | 178 | { |
169 | return (sem->count != 0); | 179 | return sem->count != 0; |
170 | } | 180 | } |
171 | 181 | ||
172 | #endif /* __KERNEL__ */ | 182 | #endif /* __KERNEL__ */ |
diff --git a/arch/powerpc/include/asm/systbl.h b/arch/powerpc/include/asm/systbl.h index a5ee345b6a5c..3d212669a130 100644 --- a/arch/powerpc/include/asm/systbl.h +++ b/arch/powerpc/include/asm/systbl.h | |||
@@ -326,3 +326,6 @@ SYSCALL_SPU(perf_event_open) | |||
326 | COMPAT_SYS_SPU(preadv) | 326 | COMPAT_SYS_SPU(preadv) |
327 | COMPAT_SYS_SPU(pwritev) | 327 | COMPAT_SYS_SPU(pwritev) |
328 | COMPAT_SYS(rt_tgsigqueueinfo) | 328 | COMPAT_SYS(rt_tgsigqueueinfo) |
329 | SYSCALL(fanotify_init) | ||
330 | COMPAT_SYS(fanotify_mark) | ||
331 | SYSCALL_SPU(prlimit64) | ||
diff --git a/arch/powerpc/include/asm/unistd.h b/arch/powerpc/include/asm/unistd.h index f0a10266e7f7..597e6f9d094a 100644 --- a/arch/powerpc/include/asm/unistd.h +++ b/arch/powerpc/include/asm/unistd.h | |||
@@ -345,10 +345,13 @@ | |||
345 | #define __NR_preadv 320 | 345 | #define __NR_preadv 320 |
346 | #define __NR_pwritev 321 | 346 | #define __NR_pwritev 321 |
347 | #define __NR_rt_tgsigqueueinfo 322 | 347 | #define __NR_rt_tgsigqueueinfo 322 |
348 | #define __NR_fanotify_init 323 | ||
349 | #define __NR_fanotify_mark 324 | ||
350 | #define __NR_prlimit64 325 | ||
348 | 351 | ||
349 | #ifdef __KERNEL__ | 352 | #ifdef __KERNEL__ |
350 | 353 | ||
351 | #define __NR_syscalls 323 | 354 | #define __NR_syscalls 326 |
352 | 355 | ||
353 | #define __NR__exit __NR_exit | 356 | #define __NR__exit __NR_exit |
354 | #define NR_syscalls __NR_syscalls | 357 | #define NR_syscalls __NR_syscalls |
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index 65e2b4e10f97..1f9123f412ec 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c | |||
@@ -1826,7 +1826,6 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
1826 | .cpu_features = CPU_FTRS_47X, | 1826 | .cpu_features = CPU_FTRS_47X, |
1827 | .cpu_user_features = COMMON_USER_BOOKE | | 1827 | .cpu_user_features = COMMON_USER_BOOKE | |
1828 | PPC_FEATURE_HAS_FPU, | 1828 | PPC_FEATURE_HAS_FPU, |
1829 | .cpu_user_features = COMMON_USER_BOOKE, | ||
1830 | .mmu_features = MMU_FTR_TYPE_47x | | 1829 | .mmu_features = MMU_FTR_TYPE_47x | |
1831 | MMU_FTR_USE_TLBIVAX_BCAST | MMU_FTR_LOCK_BCAST_INVAL, | 1830 | MMU_FTR_USE_TLBIVAX_BCAST | MMU_FTR_LOCK_BCAST_INVAL, |
1832 | .icache_bsize = 32, | 1831 | .icache_bsize = 32, |
diff --git a/arch/powerpc/kernel/crash.c b/arch/powerpc/kernel/crash.c index 417f7b05a9ce..4457382f8667 100644 --- a/arch/powerpc/kernel/crash.c +++ b/arch/powerpc/kernel/crash.c | |||
@@ -402,6 +402,18 @@ void default_machine_crash_shutdown(struct pt_regs *regs) | |||
402 | */ | 402 | */ |
403 | hard_irq_disable(); | 403 | hard_irq_disable(); |
404 | 404 | ||
405 | /* | ||
406 | * Make a note of crashing cpu. Will be used in machine_kexec | ||
407 | * such that another IPI will not be sent. | ||
408 | */ | ||
409 | crashing_cpu = smp_processor_id(); | ||
410 | crash_save_cpu(regs, crashing_cpu); | ||
411 | crash_kexec_prepare_cpus(crashing_cpu); | ||
412 | cpu_set(crashing_cpu, cpus_in_crash); | ||
413 | #if defined(CONFIG_PPC_STD_MMU_64) && defined(CONFIG_SMP) | ||
414 | crash_kexec_wait_realmode(crashing_cpu); | ||
415 | #endif | ||
416 | |||
405 | for_each_irq(i) { | 417 | for_each_irq(i) { |
406 | struct irq_desc *desc = irq_to_desc(i); | 418 | struct irq_desc *desc = irq_to_desc(i); |
407 | 419 | ||
@@ -438,18 +450,8 @@ void default_machine_crash_shutdown(struct pt_regs *regs) | |||
438 | crash_shutdown_cpu = -1; | 450 | crash_shutdown_cpu = -1; |
439 | __debugger_fault_handler = old_handler; | 451 | __debugger_fault_handler = old_handler; |
440 | 452 | ||
441 | /* | ||
442 | * Make a note of crashing cpu. Will be used in machine_kexec | ||
443 | * such that another IPI will not be sent. | ||
444 | */ | ||
445 | crashing_cpu = smp_processor_id(); | ||
446 | crash_save_cpu(regs, crashing_cpu); | ||
447 | crash_kexec_prepare_cpus(crashing_cpu); | ||
448 | cpu_set(crashing_cpu, cpus_in_crash); | ||
449 | crash_kexec_stop_spus(); | 453 | crash_kexec_stop_spus(); |
450 | #if defined(CONFIG_PPC_STD_MMU_64) && defined(CONFIG_SMP) | 454 | |
451 | crash_kexec_wait_realmode(crashing_cpu); | ||
452 | #endif | ||
453 | if (ppc_md.kexec_cpu_down) | 455 | if (ppc_md.kexec_cpu_down) |
454 | ppc_md.kexec_cpu_down(1, 0); | 456 | ppc_md.kexec_cpu_down(1, 0); |
455 | } | 457 | } |
diff --git a/arch/powerpc/kernel/head_44x.S b/arch/powerpc/kernel/head_44x.S index 5ab484ef06a7..562305b40a8e 100644 --- a/arch/powerpc/kernel/head_44x.S +++ b/arch/powerpc/kernel/head_44x.S | |||
@@ -113,6 +113,10 @@ _ENTRY(_start); | |||
113 | stw r5, 0(r4) /* Save abatron_pteptrs at a fixed location */ | 113 | stw r5, 0(r4) /* Save abatron_pteptrs at a fixed location */ |
114 | stw r6, 0(r5) | 114 | stw r6, 0(r5) |
115 | 115 | ||
116 | /* Clear the Machine Check Syndrome Register */ | ||
117 | li r0,0 | ||
118 | mtspr SPRN_MCSR,r0 | ||
119 | |||
116 | /* Let's move on */ | 120 | /* Let's move on */ |
117 | lis r4,start_kernel@h | 121 | lis r4,start_kernel@h |
118 | ori r4,r4,start_kernel@l | 122 | ori r4,r4,start_kernel@l |
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index 844a44b64472..4d6681dce816 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S | |||
@@ -572,9 +572,6 @@ __secondary_start: | |||
572 | /* Set thread priority to MEDIUM */ | 572 | /* Set thread priority to MEDIUM */ |
573 | HMT_MEDIUM | 573 | HMT_MEDIUM |
574 | 574 | ||
575 | /* Do early setup for that CPU (stab, slb, hash table pointer) */ | ||
576 | bl .early_setup_secondary | ||
577 | |||
578 | /* Initialize the kernel stack. Just a repeat for iSeries. */ | 575 | /* Initialize the kernel stack. Just a repeat for iSeries. */ |
579 | LOAD_REG_ADDR(r3, current_set) | 576 | LOAD_REG_ADDR(r3, current_set) |
580 | sldi r28,r24,3 /* get current_set[cpu#] */ | 577 | sldi r28,r24,3 /* get current_set[cpu#] */ |
@@ -582,6 +579,9 @@ __secondary_start: | |||
582 | addi r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD | 579 | addi r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD |
583 | std r1,PACAKSAVE(r13) | 580 | std r1,PACAKSAVE(r13) |
584 | 581 | ||
582 | /* Do early setup for that CPU (stab, slb, hash table pointer) */ | ||
583 | bl .early_setup_secondary | ||
584 | |||
585 | /* Clear backchain so we get nice backtraces */ | 585 | /* Clear backchain so we get nice backtraces */ |
586 | li r7,0 | 586 | li r7,0 |
587 | mtlr r7 | 587 | mtlr r7 |
diff --git a/arch/powerpc/kernel/idle.c b/arch/powerpc/kernel/idle.c index 049dda60e475..39a2baa6ad58 100644 --- a/arch/powerpc/kernel/idle.c +++ b/arch/powerpc/kernel/idle.c | |||
@@ -94,9 +94,9 @@ void cpu_idle(void) | |||
94 | HMT_medium(); | 94 | HMT_medium(); |
95 | ppc64_runlatch_on(); | 95 | ppc64_runlatch_on(); |
96 | tick_nohz_restart_sched_tick(); | 96 | tick_nohz_restart_sched_tick(); |
97 | preempt_enable_no_resched(); | ||
97 | if (cpu_should_die()) | 98 | if (cpu_should_die()) |
98 | cpu_die(); | 99 | cpu_die(); |
99 | preempt_enable_no_resched(); | ||
100 | schedule(); | 100 | schedule(); |
101 | preempt_disable(); | 101 | preempt_disable(); |
102 | } | 102 | } |
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index d3ce67cf03be..4a65386995d7 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c | |||
@@ -67,6 +67,7 @@ | |||
67 | #include <asm/machdep.h> | 67 | #include <asm/machdep.h> |
68 | #include <asm/udbg.h> | 68 | #include <asm/udbg.h> |
69 | #include <asm/dbell.h> | 69 | #include <asm/dbell.h> |
70 | #include <asm/smp.h> | ||
70 | 71 | ||
71 | #ifdef CONFIG_PPC64 | 72 | #ifdef CONFIG_PPC64 |
72 | #include <asm/paca.h> | 73 | #include <asm/paca.h> |
@@ -446,22 +447,23 @@ struct thread_info *mcheckirq_ctx[NR_CPUS] __read_mostly; | |||
446 | void exc_lvl_ctx_init(void) | 447 | void exc_lvl_ctx_init(void) |
447 | { | 448 | { |
448 | struct thread_info *tp; | 449 | struct thread_info *tp; |
449 | int i; | 450 | int i, hw_cpu; |
450 | 451 | ||
451 | for_each_possible_cpu(i) { | 452 | for_each_possible_cpu(i) { |
452 | memset((void *)critirq_ctx[i], 0, THREAD_SIZE); | 453 | hw_cpu = get_hard_smp_processor_id(i); |
453 | tp = critirq_ctx[i]; | 454 | memset((void *)critirq_ctx[hw_cpu], 0, THREAD_SIZE); |
455 | tp = critirq_ctx[hw_cpu]; | ||
454 | tp->cpu = i; | 456 | tp->cpu = i; |
455 | tp->preempt_count = 0; | 457 | tp->preempt_count = 0; |
456 | 458 | ||
457 | #ifdef CONFIG_BOOKE | 459 | #ifdef CONFIG_BOOKE |
458 | memset((void *)dbgirq_ctx[i], 0, THREAD_SIZE); | 460 | memset((void *)dbgirq_ctx[hw_cpu], 0, THREAD_SIZE); |
459 | tp = dbgirq_ctx[i]; | 461 | tp = dbgirq_ctx[hw_cpu]; |
460 | tp->cpu = i; | 462 | tp->cpu = i; |
461 | tp->preempt_count = 0; | 463 | tp->preempt_count = 0; |
462 | 464 | ||
463 | memset((void *)mcheckirq_ctx[i], 0, THREAD_SIZE); | 465 | memset((void *)mcheckirq_ctx[hw_cpu], 0, THREAD_SIZE); |
464 | tp = mcheckirq_ctx[i]; | 466 | tp = mcheckirq_ctx[hw_cpu]; |
465 | tp->cpu = i; | 467 | tp->cpu = i; |
466 | tp->preempt_count = HARDIRQ_OFFSET; | 468 | tp->preempt_count = HARDIRQ_OFFSET; |
467 | #endif | 469 | #endif |
diff --git a/arch/powerpc/kernel/pci_of_scan.c b/arch/powerpc/kernel/pci_of_scan.c index 6ddb795f83e8..e751506323b4 100644 --- a/arch/powerpc/kernel/pci_of_scan.c +++ b/arch/powerpc/kernel/pci_of_scan.c | |||
@@ -336,7 +336,7 @@ static void __devinit __of_scan_bus(struct device_node *node, | |||
336 | if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || | 336 | if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || |
337 | dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) { | 337 | dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) { |
338 | struct device_node *child = pci_device_to_OF_node(dev); | 338 | struct device_node *child = pci_device_to_OF_node(dev); |
339 | if (dev) | 339 | if (child) |
340 | of_scan_pci_bridge(child, dev); | 340 | of_scan_pci_bridge(child, dev); |
341 | } | 341 | } |
342 | } | 342 | } |
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 91356ffda2ca..b1c648a36b03 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c | |||
@@ -728,7 +728,7 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, | |||
728 | p->thread.regs = childregs; | 728 | p->thread.regs = childregs; |
729 | if (clone_flags & CLONE_SETTLS) { | 729 | if (clone_flags & CLONE_SETTLS) { |
730 | #ifdef CONFIG_PPC64 | 730 | #ifdef CONFIG_PPC64 |
731 | if (!test_thread_flag(TIF_32BIT)) | 731 | if (!is_32bit_task()) |
732 | childregs->gpr[13] = childregs->gpr[6]; | 732 | childregs->gpr[13] = childregs->gpr[6]; |
733 | else | 733 | else |
734 | #endif | 734 | #endif |
@@ -823,7 +823,7 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp) | |||
823 | regs->nip = start; | 823 | regs->nip = start; |
824 | regs->msr = MSR_USER; | 824 | regs->msr = MSR_USER; |
825 | #else | 825 | #else |
826 | if (!test_thread_flag(TIF_32BIT)) { | 826 | if (!is_32bit_task()) { |
827 | unsigned long entry, toc; | 827 | unsigned long entry, toc; |
828 | 828 | ||
829 | /* start is a relocated pointer to the function descriptor for | 829 | /* start is a relocated pointer to the function descriptor for |
@@ -995,7 +995,7 @@ int sys_clone(unsigned long clone_flags, unsigned long usp, | |||
995 | if (usp == 0) | 995 | if (usp == 0) |
996 | usp = regs->gpr[1]; /* stack pointer for child */ | 996 | usp = regs->gpr[1]; /* stack pointer for child */ |
997 | #ifdef CONFIG_PPC64 | 997 | #ifdef CONFIG_PPC64 |
998 | if (test_thread_flag(TIF_32BIT)) { | 998 | if (is_32bit_task()) { |
999 | parent_tidp = TRUNC_PTR(parent_tidp); | 999 | parent_tidp = TRUNC_PTR(parent_tidp); |
1000 | child_tidp = TRUNC_PTR(child_tidp); | 1000 | child_tidp = TRUNC_PTR(child_tidp); |
1001 | } | 1001 | } |
@@ -1199,19 +1199,17 @@ void ppc64_runlatch_on(void) | |||
1199 | } | 1199 | } |
1200 | } | 1200 | } |
1201 | 1201 | ||
1202 | void ppc64_runlatch_off(void) | 1202 | void __ppc64_runlatch_off(void) |
1203 | { | 1203 | { |
1204 | unsigned long ctrl; | 1204 | unsigned long ctrl; |
1205 | 1205 | ||
1206 | if (cpu_has_feature(CPU_FTR_CTRL) && test_thread_flag(TIF_RUNLATCH)) { | 1206 | HMT_medium(); |
1207 | HMT_medium(); | ||
1208 | 1207 | ||
1209 | clear_thread_flag(TIF_RUNLATCH); | 1208 | clear_thread_flag(TIF_RUNLATCH); |
1210 | 1209 | ||
1211 | ctrl = mfspr(SPRN_CTRLF); | 1210 | ctrl = mfspr(SPRN_CTRLF); |
1212 | ctrl &= ~CTRL_RUNLATCH; | 1211 | ctrl &= ~CTRL_RUNLATCH; |
1213 | mtspr(SPRN_CTRLT, ctrl); | 1212 | mtspr(SPRN_CTRLT, ctrl); |
1214 | } | ||
1215 | } | 1213 | } |
1216 | #endif | 1214 | #endif |
1217 | 1215 | ||
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index a10ffc85ada7..93666f9cabf1 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c | |||
@@ -258,17 +258,18 @@ static void __init irqstack_early_init(void) | |||
258 | #if defined(CONFIG_BOOKE) || defined(CONFIG_40x) | 258 | #if defined(CONFIG_BOOKE) || defined(CONFIG_40x) |
259 | static void __init exc_lvl_early_init(void) | 259 | static void __init exc_lvl_early_init(void) |
260 | { | 260 | { |
261 | unsigned int i; | 261 | unsigned int i, hw_cpu; |
262 | 262 | ||
263 | /* interrupt stacks must be in lowmem, we get that for free on ppc32 | 263 | /* interrupt stacks must be in lowmem, we get that for free on ppc32 |
264 | * as the memblock is limited to lowmem by MEMBLOCK_REAL_LIMIT */ | 264 | * as the memblock is limited to lowmem by MEMBLOCK_REAL_LIMIT */ |
265 | for_each_possible_cpu(i) { | 265 | for_each_possible_cpu(i) { |
266 | critirq_ctx[i] = (struct thread_info *) | 266 | hw_cpu = get_hard_smp_processor_id(i); |
267 | critirq_ctx[hw_cpu] = (struct thread_info *) | ||
267 | __va(memblock_alloc(THREAD_SIZE, THREAD_SIZE)); | 268 | __va(memblock_alloc(THREAD_SIZE, THREAD_SIZE)); |
268 | #ifdef CONFIG_BOOKE | 269 | #ifdef CONFIG_BOOKE |
269 | dbgirq_ctx[i] = (struct thread_info *) | 270 | dbgirq_ctx[hw_cpu] = (struct thread_info *) |
270 | __va(memblock_alloc(THREAD_SIZE, THREAD_SIZE)); | 271 | __va(memblock_alloc(THREAD_SIZE, THREAD_SIZE)); |
271 | mcheckirq_ctx[i] = (struct thread_info *) | 272 | mcheckirq_ctx[hw_cpu] = (struct thread_info *) |
272 | __va(memblock_alloc(THREAD_SIZE, THREAD_SIZE)); | 273 | __va(memblock_alloc(THREAD_SIZE, THREAD_SIZE)); |
273 | #endif | 274 | #endif |
274 | } | 275 | } |
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index 1bee4b68fa45..e72690ec9b87 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c | |||
@@ -95,7 +95,7 @@ int ucache_bsize; | |||
95 | 95 | ||
96 | #ifdef CONFIG_SMP | 96 | #ifdef CONFIG_SMP |
97 | 97 | ||
98 | static int smt_enabled_cmdline; | 98 | static char *smt_enabled_cmdline; |
99 | 99 | ||
100 | /* Look for ibm,smt-enabled OF option */ | 100 | /* Look for ibm,smt-enabled OF option */ |
101 | static void check_smt_enabled(void) | 101 | static void check_smt_enabled(void) |
@@ -103,37 +103,46 @@ static void check_smt_enabled(void) | |||
103 | struct device_node *dn; | 103 | struct device_node *dn; |
104 | const char *smt_option; | 104 | const char *smt_option; |
105 | 105 | ||
106 | /* Allow the command line to overrule the OF option */ | 106 | /* Default to enabling all threads */ |
107 | if (smt_enabled_cmdline) | 107 | smt_enabled_at_boot = threads_per_core; |
108 | return; | ||
109 | |||
110 | dn = of_find_node_by_path("/options"); | ||
111 | |||
112 | if (dn) { | ||
113 | smt_option = of_get_property(dn, "ibm,smt-enabled", NULL); | ||
114 | 108 | ||
115 | if (smt_option) { | 109 | /* Allow the command line to overrule the OF option */ |
116 | if (!strcmp(smt_option, "on")) | 110 | if (smt_enabled_cmdline) { |
117 | smt_enabled_at_boot = 1; | 111 | if (!strcmp(smt_enabled_cmdline, "on")) |
118 | else if (!strcmp(smt_option, "off")) | 112 | smt_enabled_at_boot = threads_per_core; |
119 | smt_enabled_at_boot = 0; | 113 | else if (!strcmp(smt_enabled_cmdline, "off")) |
120 | } | 114 | smt_enabled_at_boot = 0; |
121 | } | 115 | else { |
116 | long smt; | ||
117 | int rc; | ||
118 | |||
119 | rc = strict_strtol(smt_enabled_cmdline, 10, &smt); | ||
120 | if (!rc) | ||
121 | smt_enabled_at_boot = | ||
122 | min(threads_per_core, (int)smt); | ||
123 | } | ||
124 | } else { | ||
125 | dn = of_find_node_by_path("/options"); | ||
126 | if (dn) { | ||
127 | smt_option = of_get_property(dn, "ibm,smt-enabled", | ||
128 | NULL); | ||
129 | |||
130 | if (smt_option) { | ||
131 | if (!strcmp(smt_option, "on")) | ||
132 | smt_enabled_at_boot = threads_per_core; | ||
133 | else if (!strcmp(smt_option, "off")) | ||
134 | smt_enabled_at_boot = 0; | ||
135 | } | ||
136 | |||
137 | of_node_put(dn); | ||
138 | } | ||
139 | } | ||
122 | } | 140 | } |
123 | 141 | ||
124 | /* Look for smt-enabled= cmdline option */ | 142 | /* Look for smt-enabled= cmdline option */ |
125 | static int __init early_smt_enabled(char *p) | 143 | static int __init early_smt_enabled(char *p) |
126 | { | 144 | { |
127 | smt_enabled_cmdline = 1; | 145 | smt_enabled_cmdline = p; |
128 | |||
129 | if (!p) | ||
130 | return 0; | ||
131 | |||
132 | if (!strcmp(p, "on") || !strcmp(p, "1")) | ||
133 | smt_enabled_at_boot = 1; | ||
134 | else if (!strcmp(p, "off") || !strcmp(p, "0")) | ||
135 | smt_enabled_at_boot = 0; | ||
136 | |||
137 | return 0; | 146 | return 0; |
138 | } | 147 | } |
139 | early_param("smt-enabled", early_smt_enabled); | 148 | early_param("smt-enabled", early_smt_enabled); |
@@ -380,8 +389,8 @@ void __init setup_system(void) | |||
380 | */ | 389 | */ |
381 | xmon_setup(); | 390 | xmon_setup(); |
382 | 391 | ||
383 | check_smt_enabled(); | ||
384 | smp_setup_cpu_maps(); | 392 | smp_setup_cpu_maps(); |
393 | check_smt_enabled(); | ||
385 | 394 | ||
386 | #ifdef CONFIG_SMP | 395 | #ifdef CONFIG_SMP |
387 | /* Release secondary cpus out of their spinloops at 0x60 now that | 396 | /* Release secondary cpus out of their spinloops at 0x60 now that |
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index a61b3ddd7bb3..0008bc58e826 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c | |||
@@ -427,11 +427,11 @@ int __cpuinit __cpu_up(unsigned int cpu) | |||
427 | #endif | 427 | #endif |
428 | 428 | ||
429 | if (!cpu_callin_map[cpu]) { | 429 | if (!cpu_callin_map[cpu]) { |
430 | printk("Processor %u is stuck.\n", cpu); | 430 | printk(KERN_ERR "Processor %u is stuck.\n", cpu); |
431 | return -ENOENT; | 431 | return -ENOENT; |
432 | } | 432 | } |
433 | 433 | ||
434 | printk("Processor %u found.\n", cpu); | 434 | DBG("Processor %u found.\n", cpu); |
435 | 435 | ||
436 | if (smp_ops->give_timebase) | 436 | if (smp_ops->give_timebase) |
437 | smp_ops->give_timebase(); | 437 | smp_ops->give_timebase(); |
diff --git a/arch/powerpc/kernel/sys_ppc32.c b/arch/powerpc/kernel/sys_ppc32.c index 20fd701a686a..b1b6043a56c4 100644 --- a/arch/powerpc/kernel/sys_ppc32.c +++ b/arch/powerpc/kernel/sys_ppc32.c | |||
@@ -616,3 +616,11 @@ asmlinkage long compat_sys_sync_file_range2(int fd, unsigned int flags, | |||
616 | 616 | ||
617 | return sys_sync_file_range(fd, offset, nbytes, flags); | 617 | return sys_sync_file_range(fd, offset, nbytes, flags); |
618 | } | 618 | } |
619 | |||
620 | asmlinkage long compat_sys_fanotify_mark(int fanotify_fd, unsigned int flags, | ||
621 | unsigned mask_hi, unsigned mask_lo, | ||
622 | int dfd, const char __user *pathname) | ||
623 | { | ||
624 | u64 mask = ((u64)mask_hi << 32) | mask_lo; | ||
625 | return sys_fanotify_mark(fanotify_fd, flags, mask, dfd, pathname); | ||
626 | } | ||
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c index 00b9436f7652..fa3469ddaef8 100644 --- a/arch/powerpc/kernel/vio.c +++ b/arch/powerpc/kernel/vio.c | |||
@@ -1059,7 +1059,7 @@ static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev) | |||
1059 | if (!dma_window) | 1059 | if (!dma_window) |
1060 | return NULL; | 1060 | return NULL; |
1061 | 1061 | ||
1062 | tbl = kmalloc(sizeof(*tbl), GFP_KERNEL); | 1062 | tbl = kzalloc(sizeof(*tbl), GFP_KERNEL); |
1063 | if (tbl == NULL) | 1063 | if (tbl == NULL) |
1064 | return NULL; | 1064 | return NULL; |
1065 | 1065 | ||
@@ -1072,6 +1072,7 @@ static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev) | |||
1072 | tbl->it_offset = offset >> IOMMU_PAGE_SHIFT; | 1072 | tbl->it_offset = offset >> IOMMU_PAGE_SHIFT; |
1073 | tbl->it_busno = 0; | 1073 | tbl->it_busno = 0; |
1074 | tbl->it_type = TCE_VB; | 1074 | tbl->it_type = TCE_VB; |
1075 | tbl->it_blocksize = 16; | ||
1075 | 1076 | ||
1076 | return iommu_init_table(tbl, -1); | 1077 | return iommu_init_table(tbl, -1); |
1077 | } | 1078 | } |
diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c index 71f1415e2472..ace85fa74b29 100644 --- a/arch/powerpc/mm/init_64.c +++ b/arch/powerpc/mm/init_64.c | |||
@@ -79,7 +79,9 @@ | |||
79 | #endif /* CONFIG_PPC_STD_MMU_64 */ | 79 | #endif /* CONFIG_PPC_STD_MMU_64 */ |
80 | 80 | ||
81 | phys_addr_t memstart_addr = ~0; | 81 | phys_addr_t memstart_addr = ~0; |
82 | EXPORT_SYMBOL_GPL(memstart_addr); | ||
82 | phys_addr_t kernstart_addr; | 83 | phys_addr_t kernstart_addr; |
84 | EXPORT_SYMBOL_GPL(kernstart_addr); | ||
83 | 85 | ||
84 | void free_initmem(void) | 86 | void free_initmem(void) |
85 | { | 87 | { |
diff --git a/arch/powerpc/mm/tlb_nohash_low.S b/arch/powerpc/mm/tlb_nohash_low.S index cfa768203d08..b9d9fed8f36e 100644 --- a/arch/powerpc/mm/tlb_nohash_low.S +++ b/arch/powerpc/mm/tlb_nohash_low.S | |||
@@ -200,6 +200,7 @@ _GLOBAL(_tlbivax_bcast) | |||
200 | rlwimi r5,r4,0,16,31 | 200 | rlwimi r5,r4,0,16,31 |
201 | wrteei 0 | 201 | wrteei 0 |
202 | mtspr SPRN_MMUCR,r5 | 202 | mtspr SPRN_MMUCR,r5 |
203 | isync | ||
203 | /* tlbivax 0,r3 - use .long to avoid binutils deps */ | 204 | /* tlbivax 0,r3 - use .long to avoid binutils deps */ |
204 | .long 0x7c000624 | (r3 << 11) | 205 | .long 0x7c000624 | (r3 << 11) |
205 | isync | 206 | isync |
diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig index d1663db7810f..81c9208025fa 100644 --- a/arch/powerpc/platforms/Kconfig +++ b/arch/powerpc/platforms/Kconfig | |||
@@ -106,8 +106,7 @@ config MMIO_NVRAM | |||
106 | 106 | ||
107 | config MPIC_U3_HT_IRQS | 107 | config MPIC_U3_HT_IRQS |
108 | bool | 108 | bool |
109 | depends on PPC_MAPLE | 109 | default n |
110 | default y | ||
111 | 110 | ||
112 | config MPIC_BROKEN_REGREAD | 111 | config MPIC_BROKEN_REGREAD |
113 | bool | 112 | bool |
diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c index 58b13ce3847e..26a067122a54 100644 --- a/arch/powerpc/platforms/cell/iommu.c +++ b/arch/powerpc/platforms/cell/iommu.c | |||
@@ -477,7 +477,7 @@ cell_iommu_setup_window(struct cbe_iommu *iommu, struct device_node *np, | |||
477 | 477 | ||
478 | ioid = cell_iommu_get_ioid(np); | 478 | ioid = cell_iommu_get_ioid(np); |
479 | 479 | ||
480 | window = kmalloc_node(sizeof(*window), GFP_KERNEL, iommu->nid); | 480 | window = kzalloc_node(sizeof(*window), GFP_KERNEL, iommu->nid); |
481 | BUG_ON(window == NULL); | 481 | BUG_ON(window == NULL); |
482 | 482 | ||
483 | window->offset = offset; | 483 | window->offset = offset; |
diff --git a/arch/powerpc/platforms/iseries/iommu.c b/arch/powerpc/platforms/iseries/iommu.c index ce61cea0afb5..d8b76335bd13 100644 --- a/arch/powerpc/platforms/iseries/iommu.c +++ b/arch/powerpc/platforms/iseries/iommu.c | |||
@@ -184,7 +184,7 @@ static void pci_dma_dev_setup_iseries(struct pci_dev *pdev) | |||
184 | 184 | ||
185 | BUG_ON(lsn == NULL); | 185 | BUG_ON(lsn == NULL); |
186 | 186 | ||
187 | tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL); | 187 | tbl = kzalloc(sizeof(struct iommu_table), GFP_KERNEL); |
188 | 188 | ||
189 | iommu_table_getparms_iSeries(pdn->busno, *lsn, 0, tbl); | 189 | iommu_table_getparms_iSeries(pdn->busno, *lsn, 0, tbl); |
190 | 190 | ||
diff --git a/arch/powerpc/platforms/powermac/feature.c b/arch/powerpc/platforms/powermac/feature.c index 39df6ab1735a..df423993f175 100644 --- a/arch/powerpc/platforms/powermac/feature.c +++ b/arch/powerpc/platforms/powermac/feature.c | |||
@@ -2873,12 +2873,11 @@ set_initial_features(void) | |||
2873 | 2873 | ||
2874 | /* Switch airport off */ | 2874 | /* Switch airport off */ |
2875 | for_each_node_by_name(np, "radio") { | 2875 | for_each_node_by_name(np, "radio") { |
2876 | if (np && np->parent == macio_chips[0].of_node) { | 2876 | if (np->parent == macio_chips[0].of_node) { |
2877 | macio_chips[0].flags |= MACIO_FLAG_AIRPORT_ON; | 2877 | macio_chips[0].flags |= MACIO_FLAG_AIRPORT_ON; |
2878 | core99_airport_enable(np, 0, 0); | 2878 | core99_airport_enable(np, 0, 0); |
2879 | } | 2879 | } |
2880 | } | 2880 | } |
2881 | of_node_put(np); | ||
2882 | } | 2881 | } |
2883 | 2882 | ||
2884 | /* On all machines that support sound PM, switch sound off */ | 2883 | /* On all machines that support sound PM, switch sound off */ |
diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c index ab2027cdf893..3bc075c788ef 100644 --- a/arch/powerpc/platforms/powermac/pci.c +++ b/arch/powerpc/platforms/powermac/pci.c | |||
@@ -1155,13 +1155,11 @@ void __init pmac_pcibios_after_init(void) | |||
1155 | pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, nd, 0, 0); | 1155 | pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, nd, 0, 0); |
1156 | } | 1156 | } |
1157 | } | 1157 | } |
1158 | of_node_put(nd); | ||
1159 | for_each_node_by_name(nd, "ethernet") { | 1158 | for_each_node_by_name(nd, "ethernet") { |
1160 | if (nd->parent && of_device_is_compatible(nd, "gmac") | 1159 | if (nd->parent && of_device_is_compatible(nd, "gmac") |
1161 | && of_device_is_compatible(nd->parent, "uni-north")) | 1160 | && of_device_is_compatible(nd->parent, "uni-north")) |
1162 | pmac_call_feature(PMAC_FTR_GMAC_ENABLE, nd, 0, 0); | 1161 | pmac_call_feature(PMAC_FTR_GMAC_ENABLE, nd, 0, 0); |
1163 | } | 1162 | } |
1164 | of_node_put(nd); | ||
1165 | } | 1163 | } |
1166 | 1164 | ||
1167 | void pmac_pci_fixup_cardbus(struct pci_dev* dev) | 1165 | void pmac_pci_fixup_cardbus(struct pci_dev* dev) |
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index 395848e30c52..a77bcaed80af 100644 --- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c | |||
@@ -403,7 +403,7 @@ static void pci_dma_bus_setup_pSeries(struct pci_bus *bus) | |||
403 | pci->phb->dma_window_size = 0x8000000ul; | 403 | pci->phb->dma_window_size = 0x8000000ul; |
404 | pci->phb->dma_window_base_cur = 0x8000000ul; | 404 | pci->phb->dma_window_base_cur = 0x8000000ul; |
405 | 405 | ||
406 | tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL, | 406 | tbl = kzalloc_node(sizeof(struct iommu_table), GFP_KERNEL, |
407 | pci->phb->node); | 407 | pci->phb->node); |
408 | 408 | ||
409 | iommu_table_setparms(pci->phb, dn, tbl); | 409 | iommu_table_setparms(pci->phb, dn, tbl); |
@@ -448,7 +448,7 @@ static void pci_dma_bus_setup_pSeriesLP(struct pci_bus *bus) | |||
448 | pdn->full_name, ppci->iommu_table); | 448 | pdn->full_name, ppci->iommu_table); |
449 | 449 | ||
450 | if (!ppci->iommu_table) { | 450 | if (!ppci->iommu_table) { |
451 | tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL, | 451 | tbl = kzalloc_node(sizeof(struct iommu_table), GFP_KERNEL, |
452 | ppci->phb->node); | 452 | ppci->phb->node); |
453 | iommu_table_setparms_lpar(ppci->phb, pdn, tbl, dma_window, | 453 | iommu_table_setparms_lpar(ppci->phb, pdn, tbl, dma_window, |
454 | bus->number); | 454 | bus->number); |
@@ -478,7 +478,7 @@ static void pci_dma_dev_setup_pSeries(struct pci_dev *dev) | |||
478 | struct pci_controller *phb = PCI_DN(dn)->phb; | 478 | struct pci_controller *phb = PCI_DN(dn)->phb; |
479 | 479 | ||
480 | pr_debug(" --> first child, no bridge. Allocating iommu table.\n"); | 480 | pr_debug(" --> first child, no bridge. Allocating iommu table.\n"); |
481 | tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL, | 481 | tbl = kzalloc_node(sizeof(struct iommu_table), GFP_KERNEL, |
482 | phb->node); | 482 | phb->node); |
483 | iommu_table_setparms(phb, dn, tbl); | 483 | iommu_table_setparms(phb, dn, tbl); |
484 | PCI_DN(dn)->iommu_table = iommu_init_table(tbl, phb->node); | 484 | PCI_DN(dn)->iommu_table = iommu_init_table(tbl, phb->node); |
@@ -544,7 +544,7 @@ static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev) | |||
544 | 544 | ||
545 | pci = PCI_DN(pdn); | 545 | pci = PCI_DN(pdn); |
546 | if (!pci->iommu_table) { | 546 | if (!pci->iommu_table) { |
547 | tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL, | 547 | tbl = kzalloc_node(sizeof(struct iommu_table), GFP_KERNEL, |
548 | pci->phb->node); | 548 | pci->phb->node); |
549 | iommu_table_setparms_lpar(pci->phb, pdn, tbl, dma_window, | 549 | iommu_table_setparms_lpar(pci->phb, pdn, tbl, dma_window, |
550 | pci->phb->bus->number); | 550 | pci->phb->bus->number); |
diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c index 3b1bf61c45be..0317cce877c6 100644 --- a/arch/powerpc/platforms/pseries/smp.c +++ b/arch/powerpc/platforms/pseries/smp.c | |||
@@ -182,10 +182,13 @@ static int smp_pSeries_cpu_bootable(unsigned int nr) | |||
182 | /* Special case - we inhibit secondary thread startup | 182 | /* Special case - we inhibit secondary thread startup |
183 | * during boot if the user requests it. | 183 | * during boot if the user requests it. |
184 | */ | 184 | */ |
185 | if (system_state < SYSTEM_RUNNING && | 185 | if (system_state < SYSTEM_RUNNING && cpu_has_feature(CPU_FTR_SMT)) { |
186 | cpu_has_feature(CPU_FTR_SMT) && | 186 | if (!smt_enabled_at_boot && cpu_thread_in_core(nr) != 0) |
187 | !smt_enabled_at_boot && cpu_thread_in_core(nr) != 0) | 187 | return 0; |
188 | return 0; | 188 | if (smt_enabled_at_boot |
189 | && cpu_thread_in_core(nr) >= smt_enabled_at_boot) | ||
190 | return 0; | ||
191 | } | ||
189 | 192 | ||
190 | return 1; | 193 | return 1; |
191 | } | 194 | } |
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c index 5b22b07c8f67..93834b0d8272 100644 --- a/arch/powerpc/platforms/pseries/xics.c +++ b/arch/powerpc/platforms/pseries/xics.c | |||
@@ -928,8 +928,10 @@ void xics_migrate_irqs_away(void) | |||
928 | if (xics_status[0] != hw_cpu) | 928 | if (xics_status[0] != hw_cpu) |
929 | goto unlock; | 929 | goto unlock; |
930 | 930 | ||
931 | printk(KERN_WARNING "IRQ %u affinity broken off cpu %u\n", | 931 | /* This is expected during cpu offline. */ |
932 | virq, cpu); | 932 | if (cpu_online(cpu)) |
933 | printk(KERN_WARNING "IRQ %u affinity broken off cpu %u\n", | ||
934 | virq, cpu); | ||
933 | 935 | ||
934 | /* Reset affinity to all cpus */ | 936 | /* Reset affinity to all cpus */ |
935 | cpumask_setall(irq_to_desc(virq)->affinity); | 937 | cpumask_setall(irq_to_desc(virq)->affinity); |
diff --git a/arch/sparc/include/asm/atomic_64.h b/arch/sparc/include/asm/atomic_64.h index f0c74227c737..bdb2ff880bdd 100644 --- a/arch/sparc/include/asm/atomic_64.h +++ b/arch/sparc/include/asm/atomic_64.h | |||
@@ -20,14 +20,14 @@ | |||
20 | #define atomic64_set(v, i) (((v)->counter) = i) | 20 | #define atomic64_set(v, i) (((v)->counter) = i) |
21 | 21 | ||
22 | extern void atomic_add(int, atomic_t *); | 22 | extern void atomic_add(int, atomic_t *); |
23 | extern void atomic64_add(int, atomic64_t *); | 23 | extern void atomic64_add(long, atomic64_t *); |
24 | extern void atomic_sub(int, atomic_t *); | 24 | extern void atomic_sub(int, atomic_t *); |
25 | extern void atomic64_sub(int, atomic64_t *); | 25 | extern void atomic64_sub(long, atomic64_t *); |
26 | 26 | ||
27 | extern int atomic_add_ret(int, atomic_t *); | 27 | extern int atomic_add_ret(int, atomic_t *); |
28 | extern long atomic64_add_ret(int, atomic64_t *); | 28 | extern long atomic64_add_ret(long, atomic64_t *); |
29 | extern int atomic_sub_ret(int, atomic_t *); | 29 | extern int atomic_sub_ret(int, atomic_t *); |
30 | extern long atomic64_sub_ret(int, atomic64_t *); | 30 | extern long atomic64_sub_ret(long, atomic64_t *); |
31 | 31 | ||
32 | #define atomic_dec_return(v) atomic_sub_ret(1, v) | 32 | #define atomic_dec_return(v) atomic_sub_ret(1, v) |
33 | #define atomic64_dec_return(v) atomic64_sub_ret(1, v) | 33 | #define atomic64_dec_return(v) atomic64_sub_ret(1, v) |
diff --git a/arch/sparc/include/asm/backoff.h b/arch/sparc/include/asm/backoff.h index fa1fdf67e350..db3af0d30fb1 100644 --- a/arch/sparc/include/asm/backoff.h +++ b/arch/sparc/include/asm/backoff.h | |||
@@ -8,6 +8,9 @@ | |||
8 | #define BACKOFF_SETUP(reg) \ | 8 | #define BACKOFF_SETUP(reg) \ |
9 | mov 1, reg | 9 | mov 1, reg |
10 | 10 | ||
11 | #define BACKOFF_LABEL(spin_label, continue_label) \ | ||
12 | spin_label | ||
13 | |||
11 | #define BACKOFF_SPIN(reg, tmp, label) \ | 14 | #define BACKOFF_SPIN(reg, tmp, label) \ |
12 | mov reg, tmp; \ | 15 | mov reg, tmp; \ |
13 | 88: brnz,pt tmp, 88b; \ | 16 | 88: brnz,pt tmp, 88b; \ |
@@ -22,9 +25,11 @@ | |||
22 | #else | 25 | #else |
23 | 26 | ||
24 | #define BACKOFF_SETUP(reg) | 27 | #define BACKOFF_SETUP(reg) |
25 | #define BACKOFF_SPIN(reg, tmp, label) \ | 28 | |
26 | ba,pt %xcc, label; \ | 29 | #define BACKOFF_LABEL(spin_label, continue_label) \ |
27 | nop; | 30 | continue_label |
31 | |||
32 | #define BACKOFF_SPIN(reg, tmp, label) | ||
28 | 33 | ||
29 | #endif | 34 | #endif |
30 | 35 | ||
diff --git a/arch/sparc/include/asm/oplib_64.h b/arch/sparc/include/asm/oplib_64.h index a5db0317b5fb..3e0b2d62303d 100644 --- a/arch/sparc/include/asm/oplib_64.h +++ b/arch/sparc/include/asm/oplib_64.h | |||
@@ -185,9 +185,8 @@ extern int prom_getunumber(int syndrome_code, | |||
185 | char *buf, int buflen); | 185 | char *buf, int buflen); |
186 | 186 | ||
187 | /* Retain physical memory to the caller across soft resets. */ | 187 | /* Retain physical memory to the caller across soft resets. */ |
188 | extern unsigned long prom_retain(const char *name, | 188 | extern int prom_retain(const char *name, unsigned long size, |
189 | unsigned long pa_low, unsigned long pa_high, | 189 | unsigned long align, unsigned long *paddr); |
190 | long size, long align); | ||
191 | 190 | ||
192 | /* Load explicit I/D TLB entries into the calling processor. */ | 191 | /* Load explicit I/D TLB entries into the calling processor. */ |
193 | extern long prom_itlb_load(unsigned long index, | 192 | extern long prom_itlb_load(unsigned long index, |
@@ -287,26 +286,6 @@ extern void prom_sun4v_guest_soft_state(void); | |||
287 | extern int prom_ihandle2path(int handle, char *buffer, int bufsize); | 286 | extern int prom_ihandle2path(int handle, char *buffer, int bufsize); |
288 | 287 | ||
289 | /* Client interface level routines. */ | 288 | /* Client interface level routines. */ |
290 | extern long p1275_cmd(const char *, long, ...); | 289 | extern void p1275_cmd_direct(unsigned long *); |
291 | |||
292 | #if 0 | ||
293 | #define P1275_SIZE(x) ((((long)((x) / 32)) << 32) | (x)) | ||
294 | #else | ||
295 | #define P1275_SIZE(x) x | ||
296 | #endif | ||
297 | |||
298 | /* We support at most 16 input and 1 output argument */ | ||
299 | #define P1275_ARG_NUMBER 0 | ||
300 | #define P1275_ARG_IN_STRING 1 | ||
301 | #define P1275_ARG_OUT_BUF 2 | ||
302 | #define P1275_ARG_OUT_32B 3 | ||
303 | #define P1275_ARG_IN_FUNCTION 4 | ||
304 | #define P1275_ARG_IN_BUF 5 | ||
305 | #define P1275_ARG_IN_64B 6 | ||
306 | |||
307 | #define P1275_IN(x) ((x) & 0xf) | ||
308 | #define P1275_OUT(x) (((x) << 4) & 0xf0) | ||
309 | #define P1275_INOUT(i,o) (P1275_IN(i)|P1275_OUT(o)) | ||
310 | #define P1275_ARG(n,x) ((x) << ((n)*3 + 8)) | ||
311 | 290 | ||
312 | #endif /* !(__SPARC64_OPLIB_H) */ | 291 | #endif /* !(__SPARC64_OPLIB_H) */ |
diff --git a/arch/sparc/include/asm/rwsem-const.h b/arch/sparc/include/asm/rwsem-const.h deleted file mode 100644 index e4c61a18bb28..000000000000 --- a/arch/sparc/include/asm/rwsem-const.h +++ /dev/null | |||
@@ -1,12 +0,0 @@ | |||
1 | /* rwsem-const.h: RW semaphore counter constants. */ | ||
2 | #ifndef _SPARC64_RWSEM_CONST_H | ||
3 | #define _SPARC64_RWSEM_CONST_H | ||
4 | |||
5 | #define RWSEM_UNLOCKED_VALUE 0x00000000 | ||
6 | #define RWSEM_ACTIVE_BIAS 0x00000001 | ||
7 | #define RWSEM_ACTIVE_MASK 0x0000ffff | ||
8 | #define RWSEM_WAITING_BIAS (-0x00010000) | ||
9 | #define RWSEM_ACTIVE_READ_BIAS RWSEM_ACTIVE_BIAS | ||
10 | #define RWSEM_ACTIVE_WRITE_BIAS (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS) | ||
11 | |||
12 | #endif /* _SPARC64_RWSEM_CONST_H */ | ||
diff --git a/arch/sparc/include/asm/rwsem.h b/arch/sparc/include/asm/rwsem.h index 6e5621006f85..a2b4302869bc 100644 --- a/arch/sparc/include/asm/rwsem.h +++ b/arch/sparc/include/asm/rwsem.h | |||
@@ -15,16 +15,21 @@ | |||
15 | 15 | ||
16 | #include <linux/list.h> | 16 | #include <linux/list.h> |
17 | #include <linux/spinlock.h> | 17 | #include <linux/spinlock.h> |
18 | #include <asm/rwsem-const.h> | ||
19 | 18 | ||
20 | struct rwsem_waiter; | 19 | struct rwsem_waiter; |
21 | 20 | ||
22 | struct rw_semaphore { | 21 | struct rw_semaphore { |
23 | signed int count; | 22 | signed long count; |
24 | spinlock_t wait_lock; | 23 | #define RWSEM_UNLOCKED_VALUE 0x00000000L |
25 | struct list_head wait_list; | 24 | #define RWSEM_ACTIVE_BIAS 0x00000001L |
25 | #define RWSEM_ACTIVE_MASK 0xffffffffL | ||
26 | #define RWSEM_WAITING_BIAS (-RWSEM_ACTIVE_MASK-1) | ||
27 | #define RWSEM_ACTIVE_READ_BIAS RWSEM_ACTIVE_BIAS | ||
28 | #define RWSEM_ACTIVE_WRITE_BIAS (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS) | ||
29 | spinlock_t wait_lock; | ||
30 | struct list_head wait_list; | ||
26 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | 31 | #ifdef CONFIG_DEBUG_LOCK_ALLOC |
27 | struct lockdep_map dep_map; | 32 | struct lockdep_map dep_map; |
28 | #endif | 33 | #endif |
29 | }; | 34 | }; |
30 | 35 | ||
@@ -41,6 +46,11 @@ struct rw_semaphore { | |||
41 | #define DECLARE_RWSEM(name) \ | 46 | #define DECLARE_RWSEM(name) \ |
42 | struct rw_semaphore name = __RWSEM_INITIALIZER(name) | 47 | struct rw_semaphore name = __RWSEM_INITIALIZER(name) |
43 | 48 | ||
49 | extern struct rw_semaphore *rwsem_down_read_failed(struct rw_semaphore *sem); | ||
50 | extern struct rw_semaphore *rwsem_down_write_failed(struct rw_semaphore *sem); | ||
51 | extern struct rw_semaphore *rwsem_wake(struct rw_semaphore *sem); | ||
52 | extern struct rw_semaphore *rwsem_downgrade_wake(struct rw_semaphore *sem); | ||
53 | |||
44 | extern void __init_rwsem(struct rw_semaphore *sem, const char *name, | 54 | extern void __init_rwsem(struct rw_semaphore *sem, const char *name, |
45 | struct lock_class_key *key); | 55 | struct lock_class_key *key); |
46 | 56 | ||
@@ -51,27 +61,103 @@ do { \ | |||
51 | __init_rwsem((sem), #sem, &__key); \ | 61 | __init_rwsem((sem), #sem, &__key); \ |
52 | } while (0) | 62 | } while (0) |
53 | 63 | ||
54 | extern void __down_read(struct rw_semaphore *sem); | 64 | /* |
55 | extern int __down_read_trylock(struct rw_semaphore *sem); | 65 | * lock for reading |
56 | extern void __down_write(struct rw_semaphore *sem); | 66 | */ |
57 | extern int __down_write_trylock(struct rw_semaphore *sem); | 67 | static inline void __down_read(struct rw_semaphore *sem) |
58 | extern void __up_read(struct rw_semaphore *sem); | 68 | { |
59 | extern void __up_write(struct rw_semaphore *sem); | 69 | if (unlikely(atomic64_inc_return((atomic64_t *)(&sem->count)) <= 0L)) |
60 | extern void __downgrade_write(struct rw_semaphore *sem); | 70 | rwsem_down_read_failed(sem); |
71 | } | ||
72 | |||
73 | static inline int __down_read_trylock(struct rw_semaphore *sem) | ||
74 | { | ||
75 | long tmp; | ||
76 | |||
77 | while ((tmp = sem->count) >= 0L) { | ||
78 | if (tmp == cmpxchg(&sem->count, tmp, | ||
79 | tmp + RWSEM_ACTIVE_READ_BIAS)) { | ||
80 | return 1; | ||
81 | } | ||
82 | } | ||
83 | return 0; | ||
84 | } | ||
61 | 85 | ||
86 | /* | ||
87 | * lock for writing | ||
88 | */ | ||
62 | static inline void __down_write_nested(struct rw_semaphore *sem, int subclass) | 89 | static inline void __down_write_nested(struct rw_semaphore *sem, int subclass) |
63 | { | 90 | { |
64 | __down_write(sem); | 91 | long tmp; |
92 | |||
93 | tmp = atomic64_add_return(RWSEM_ACTIVE_WRITE_BIAS, | ||
94 | (atomic64_t *)(&sem->count)); | ||
95 | if (unlikely(tmp != RWSEM_ACTIVE_WRITE_BIAS)) | ||
96 | rwsem_down_write_failed(sem); | ||
65 | } | 97 | } |
66 | 98 | ||
67 | static inline int rwsem_atomic_update(int delta, struct rw_semaphore *sem) | 99 | static inline void __down_write(struct rw_semaphore *sem) |
68 | { | 100 | { |
69 | return atomic_add_return(delta, (atomic_t *)(&sem->count)); | 101 | __down_write_nested(sem, 0); |
102 | } | ||
103 | |||
104 | static inline int __down_write_trylock(struct rw_semaphore *sem) | ||
105 | { | ||
106 | long tmp; | ||
107 | |||
108 | tmp = cmpxchg(&sem->count, RWSEM_UNLOCKED_VALUE, | ||
109 | RWSEM_ACTIVE_WRITE_BIAS); | ||
110 | return tmp == RWSEM_UNLOCKED_VALUE; | ||
70 | } | 111 | } |
71 | 112 | ||
72 | static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem) | 113 | /* |
114 | * unlock after reading | ||
115 | */ | ||
116 | static inline void __up_read(struct rw_semaphore *sem) | ||
117 | { | ||
118 | long tmp; | ||
119 | |||
120 | tmp = atomic64_dec_return((atomic64_t *)(&sem->count)); | ||
121 | if (unlikely(tmp < -1L && (tmp & RWSEM_ACTIVE_MASK) == 0L)) | ||
122 | rwsem_wake(sem); | ||
123 | } | ||
124 | |||
125 | /* | ||
126 | * unlock after writing | ||
127 | */ | ||
128 | static inline void __up_write(struct rw_semaphore *sem) | ||
129 | { | ||
130 | if (unlikely(atomic64_sub_return(RWSEM_ACTIVE_WRITE_BIAS, | ||
131 | (atomic64_t *)(&sem->count)) < 0L)) | ||
132 | rwsem_wake(sem); | ||
133 | } | ||
134 | |||
135 | /* | ||
136 | * implement atomic add functionality | ||
137 | */ | ||
138 | static inline void rwsem_atomic_add(long delta, struct rw_semaphore *sem) | ||
139 | { | ||
140 | atomic64_add(delta, (atomic64_t *)(&sem->count)); | ||
141 | } | ||
142 | |||
143 | /* | ||
144 | * downgrade write lock to read lock | ||
145 | */ | ||
146 | static inline void __downgrade_write(struct rw_semaphore *sem) | ||
147 | { | ||
148 | long tmp; | ||
149 | |||
150 | tmp = atomic64_add_return(-RWSEM_WAITING_BIAS, (atomic64_t *)(&sem->count)); | ||
151 | if (tmp < 0L) | ||
152 | rwsem_downgrade_wake(sem); | ||
153 | } | ||
154 | |||
155 | /* | ||
156 | * implement exchange and add functionality | ||
157 | */ | ||
158 | static inline long rwsem_atomic_update(long delta, struct rw_semaphore *sem) | ||
73 | { | 159 | { |
74 | atomic_add(delta, (atomic_t *)(&sem->count)); | 160 | return atomic64_add_return(delta, (atomic64_t *)(&sem->count)); |
75 | } | 161 | } |
76 | 162 | ||
77 | static inline int rwsem_is_locked(struct rw_semaphore *sem) | 163 | static inline int rwsem_is_locked(struct rw_semaphore *sem) |
diff --git a/arch/sparc/include/asm/system_64.h b/arch/sparc/include/asm/system_64.h index d24cfe16afc1..e3b65d8cf41b 100644 --- a/arch/sparc/include/asm/system_64.h +++ b/arch/sparc/include/asm/system_64.h | |||
@@ -106,6 +106,7 @@ do { __asm__ __volatile__("ba,pt %%xcc, 1f\n\t" \ | |||
106 | */ | 106 | */ |
107 | #define write_pic(__p) \ | 107 | #define write_pic(__p) \ |
108 | __asm__ __volatile__("ba,pt %%xcc, 99f\n\t" \ | 108 | __asm__ __volatile__("ba,pt %%xcc, 99f\n\t" \ |
109 | " nop\n\t" \ | ||
109 | ".align 64\n" \ | 110 | ".align 64\n" \ |
110 | "99:wr %0, 0x0, %%pic\n\t" \ | 111 | "99:wr %0, 0x0, %%pic\n\t" \ |
111 | "rd %%pic, %%g0" : : "r" (__p)) | 112 | "rd %%pic, %%g0" : : "r" (__p)) |
diff --git a/arch/sparc/lib/Makefile b/arch/sparc/lib/Makefile index c4b5e03af115..846d1c4374ea 100644 --- a/arch/sparc/lib/Makefile +++ b/arch/sparc/lib/Makefile | |||
@@ -15,7 +15,7 @@ lib-$(CONFIG_SPARC32) += divdi3.o udivdi3.o | |||
15 | lib-$(CONFIG_SPARC32) += copy_user.o locks.o | 15 | lib-$(CONFIG_SPARC32) += copy_user.o locks.o |
16 | lib-y += atomic_$(BITS).o | 16 | lib-y += atomic_$(BITS).o |
17 | lib-$(CONFIG_SPARC32) += lshrdi3.o ashldi3.o | 17 | lib-$(CONFIG_SPARC32) += lshrdi3.o ashldi3.o |
18 | lib-y += rwsem_$(BITS).o | 18 | lib-$(CONFIG_SPARC32) += rwsem_32.o |
19 | lib-$(CONFIG_SPARC32) += muldi3.o bitext.o cmpdi2.o | 19 | lib-$(CONFIG_SPARC32) += muldi3.o bitext.o cmpdi2.o |
20 | 20 | ||
21 | lib-$(CONFIG_SPARC64) += copy_page.o clear_page.o bzero.o | 21 | lib-$(CONFIG_SPARC64) += copy_page.o clear_page.o bzero.o |
diff --git a/arch/sparc/lib/atomic_64.S b/arch/sparc/lib/atomic_64.S index 0268210ca168..59186e0fcf39 100644 --- a/arch/sparc/lib/atomic_64.S +++ b/arch/sparc/lib/atomic_64.S | |||
@@ -21,7 +21,7 @@ atomic_add: /* %o0 = increment, %o1 = atomic_ptr */ | |||
21 | add %g1, %o0, %g7 | 21 | add %g1, %o0, %g7 |
22 | cas [%o1], %g1, %g7 | 22 | cas [%o1], %g1, %g7 |
23 | cmp %g1, %g7 | 23 | cmp %g1, %g7 |
24 | bne,pn %icc, 2f | 24 | bne,pn %icc, BACKOFF_LABEL(2f, 1b) |
25 | nop | 25 | nop |
26 | retl | 26 | retl |
27 | nop | 27 | nop |
@@ -36,7 +36,7 @@ atomic_sub: /* %o0 = decrement, %o1 = atomic_ptr */ | |||
36 | sub %g1, %o0, %g7 | 36 | sub %g1, %o0, %g7 |
37 | cas [%o1], %g1, %g7 | 37 | cas [%o1], %g1, %g7 |
38 | cmp %g1, %g7 | 38 | cmp %g1, %g7 |
39 | bne,pn %icc, 2f | 39 | bne,pn %icc, BACKOFF_LABEL(2f, 1b) |
40 | nop | 40 | nop |
41 | retl | 41 | retl |
42 | nop | 42 | nop |
@@ -51,11 +51,10 @@ atomic_add_ret: /* %o0 = increment, %o1 = atomic_ptr */ | |||
51 | add %g1, %o0, %g7 | 51 | add %g1, %o0, %g7 |
52 | cas [%o1], %g1, %g7 | 52 | cas [%o1], %g1, %g7 |
53 | cmp %g1, %g7 | 53 | cmp %g1, %g7 |
54 | bne,pn %icc, 2f | 54 | bne,pn %icc, BACKOFF_LABEL(2f, 1b) |
55 | add %g7, %o0, %g7 | 55 | add %g1, %o0, %g1 |
56 | sra %g7, 0, %o0 | ||
57 | retl | 56 | retl |
58 | nop | 57 | sra %g1, 0, %o0 |
59 | 2: BACKOFF_SPIN(%o2, %o3, 1b) | 58 | 2: BACKOFF_SPIN(%o2, %o3, 1b) |
60 | .size atomic_add_ret, .-atomic_add_ret | 59 | .size atomic_add_ret, .-atomic_add_ret |
61 | 60 | ||
@@ -67,11 +66,10 @@ atomic_sub_ret: /* %o0 = decrement, %o1 = atomic_ptr */ | |||
67 | sub %g1, %o0, %g7 | 66 | sub %g1, %o0, %g7 |
68 | cas [%o1], %g1, %g7 | 67 | cas [%o1], %g1, %g7 |
69 | cmp %g1, %g7 | 68 | cmp %g1, %g7 |
70 | bne,pn %icc, 2f | 69 | bne,pn %icc, BACKOFF_LABEL(2f, 1b) |
71 | sub %g7, %o0, %g7 | 70 | sub %g1, %o0, %g1 |
72 | sra %g7, 0, %o0 | ||
73 | retl | 71 | retl |
74 | nop | 72 | sra %g1, 0, %o0 |
75 | 2: BACKOFF_SPIN(%o2, %o3, 1b) | 73 | 2: BACKOFF_SPIN(%o2, %o3, 1b) |
76 | .size atomic_sub_ret, .-atomic_sub_ret | 74 | .size atomic_sub_ret, .-atomic_sub_ret |
77 | 75 | ||
@@ -83,7 +81,7 @@ atomic64_add: /* %o0 = increment, %o1 = atomic_ptr */ | |||
83 | add %g1, %o0, %g7 | 81 | add %g1, %o0, %g7 |
84 | casx [%o1], %g1, %g7 | 82 | casx [%o1], %g1, %g7 |
85 | cmp %g1, %g7 | 83 | cmp %g1, %g7 |
86 | bne,pn %xcc, 2f | 84 | bne,pn %xcc, BACKOFF_LABEL(2f, 1b) |
87 | nop | 85 | nop |
88 | retl | 86 | retl |
89 | nop | 87 | nop |
@@ -98,7 +96,7 @@ atomic64_sub: /* %o0 = decrement, %o1 = atomic_ptr */ | |||
98 | sub %g1, %o0, %g7 | 96 | sub %g1, %o0, %g7 |
99 | casx [%o1], %g1, %g7 | 97 | casx [%o1], %g1, %g7 |
100 | cmp %g1, %g7 | 98 | cmp %g1, %g7 |
101 | bne,pn %xcc, 2f | 99 | bne,pn %xcc, BACKOFF_LABEL(2f, 1b) |
102 | nop | 100 | nop |
103 | retl | 101 | retl |
104 | nop | 102 | nop |
@@ -113,11 +111,10 @@ atomic64_add_ret: /* %o0 = increment, %o1 = atomic_ptr */ | |||
113 | add %g1, %o0, %g7 | 111 | add %g1, %o0, %g7 |
114 | casx [%o1], %g1, %g7 | 112 | casx [%o1], %g1, %g7 |
115 | cmp %g1, %g7 | 113 | cmp %g1, %g7 |
116 | bne,pn %xcc, 2f | 114 | bne,pn %xcc, BACKOFF_LABEL(2f, 1b) |
117 | add %g7, %o0, %g7 | ||
118 | mov %g7, %o0 | ||
119 | retl | ||
120 | nop | 115 | nop |
116 | retl | ||
117 | add %g1, %o0, %o0 | ||
121 | 2: BACKOFF_SPIN(%o2, %o3, 1b) | 118 | 2: BACKOFF_SPIN(%o2, %o3, 1b) |
122 | .size atomic64_add_ret, .-atomic64_add_ret | 119 | .size atomic64_add_ret, .-atomic64_add_ret |
123 | 120 | ||
@@ -129,10 +126,9 @@ atomic64_sub_ret: /* %o0 = decrement, %o1 = atomic_ptr */ | |||
129 | sub %g1, %o0, %g7 | 126 | sub %g1, %o0, %g7 |
130 | casx [%o1], %g1, %g7 | 127 | casx [%o1], %g1, %g7 |
131 | cmp %g1, %g7 | 128 | cmp %g1, %g7 |
132 | bne,pn %xcc, 2f | 129 | bne,pn %xcc, BACKOFF_LABEL(2f, 1b) |
133 | sub %g7, %o0, %g7 | ||
134 | mov %g7, %o0 | ||
135 | retl | ||
136 | nop | 130 | nop |
131 | retl | ||
132 | sub %g1, %o0, %o0 | ||
137 | 2: BACKOFF_SPIN(%o2, %o3, 1b) | 133 | 2: BACKOFF_SPIN(%o2, %o3, 1b) |
138 | .size atomic64_sub_ret, .-atomic64_sub_ret | 134 | .size atomic64_sub_ret, .-atomic64_sub_ret |
diff --git a/arch/sparc/lib/bitops.S b/arch/sparc/lib/bitops.S index 2b7228cb8c22..3dc61d5537c0 100644 --- a/arch/sparc/lib/bitops.S +++ b/arch/sparc/lib/bitops.S | |||
@@ -22,7 +22,7 @@ test_and_set_bit: /* %o0=nr, %o1=addr */ | |||
22 | or %g7, %o2, %g1 | 22 | or %g7, %o2, %g1 |
23 | casx [%o1], %g7, %g1 | 23 | casx [%o1], %g7, %g1 |
24 | cmp %g7, %g1 | 24 | cmp %g7, %g1 |
25 | bne,pn %xcc, 2f | 25 | bne,pn %xcc, BACKOFF_LABEL(2f, 1b) |
26 | and %g7, %o2, %g2 | 26 | and %g7, %o2, %g2 |
27 | clr %o0 | 27 | clr %o0 |
28 | movrne %g2, 1, %o0 | 28 | movrne %g2, 1, %o0 |
@@ -45,7 +45,7 @@ test_and_clear_bit: /* %o0=nr, %o1=addr */ | |||
45 | andn %g7, %o2, %g1 | 45 | andn %g7, %o2, %g1 |
46 | casx [%o1], %g7, %g1 | 46 | casx [%o1], %g7, %g1 |
47 | cmp %g7, %g1 | 47 | cmp %g7, %g1 |
48 | bne,pn %xcc, 2f | 48 | bne,pn %xcc, BACKOFF_LABEL(2f, 1b) |
49 | and %g7, %o2, %g2 | 49 | and %g7, %o2, %g2 |
50 | clr %o0 | 50 | clr %o0 |
51 | movrne %g2, 1, %o0 | 51 | movrne %g2, 1, %o0 |
@@ -68,7 +68,7 @@ test_and_change_bit: /* %o0=nr, %o1=addr */ | |||
68 | xor %g7, %o2, %g1 | 68 | xor %g7, %o2, %g1 |
69 | casx [%o1], %g7, %g1 | 69 | casx [%o1], %g7, %g1 |
70 | cmp %g7, %g1 | 70 | cmp %g7, %g1 |
71 | bne,pn %xcc, 2f | 71 | bne,pn %xcc, BACKOFF_LABEL(2f, 1b) |
72 | and %g7, %o2, %g2 | 72 | and %g7, %o2, %g2 |
73 | clr %o0 | 73 | clr %o0 |
74 | movrne %g2, 1, %o0 | 74 | movrne %g2, 1, %o0 |
@@ -91,7 +91,7 @@ set_bit: /* %o0=nr, %o1=addr */ | |||
91 | or %g7, %o2, %g1 | 91 | or %g7, %o2, %g1 |
92 | casx [%o1], %g7, %g1 | 92 | casx [%o1], %g7, %g1 |
93 | cmp %g7, %g1 | 93 | cmp %g7, %g1 |
94 | bne,pn %xcc, 2f | 94 | bne,pn %xcc, BACKOFF_LABEL(2f, 1b) |
95 | nop | 95 | nop |
96 | retl | 96 | retl |
97 | nop | 97 | nop |
@@ -112,7 +112,7 @@ clear_bit: /* %o0=nr, %o1=addr */ | |||
112 | andn %g7, %o2, %g1 | 112 | andn %g7, %o2, %g1 |
113 | casx [%o1], %g7, %g1 | 113 | casx [%o1], %g7, %g1 |
114 | cmp %g7, %g1 | 114 | cmp %g7, %g1 |
115 | bne,pn %xcc, 2f | 115 | bne,pn %xcc, BACKOFF_LABEL(2f, 1b) |
116 | nop | 116 | nop |
117 | retl | 117 | retl |
118 | nop | 118 | nop |
@@ -133,7 +133,7 @@ change_bit: /* %o0=nr, %o1=addr */ | |||
133 | xor %g7, %o2, %g1 | 133 | xor %g7, %o2, %g1 |
134 | casx [%o1], %g7, %g1 | 134 | casx [%o1], %g7, %g1 |
135 | cmp %g7, %g1 | 135 | cmp %g7, %g1 |
136 | bne,pn %xcc, 2f | 136 | bne,pn %xcc, BACKOFF_LABEL(2f, 1b) |
137 | nop | 137 | nop |
138 | retl | 138 | retl |
139 | nop | 139 | nop |
diff --git a/arch/sparc/lib/rwsem_64.S b/arch/sparc/lib/rwsem_64.S deleted file mode 100644 index 91a7d29a79d5..000000000000 --- a/arch/sparc/lib/rwsem_64.S +++ /dev/null | |||
@@ -1,163 +0,0 @@ | |||
1 | /* rwsem.S: RW semaphore assembler. | ||
2 | * | ||
3 | * Written by David S. Miller (davem@redhat.com), 2001. | ||
4 | * Derived from asm-i386/rwsem.h | ||
5 | */ | ||
6 | |||
7 | #include <asm/rwsem-const.h> | ||
8 | |||
9 | .section .sched.text, "ax" | ||
10 | |||
11 | .globl __down_read | ||
12 | __down_read: | ||
13 | 1: lduw [%o0], %g1 | ||
14 | add %g1, 1, %g7 | ||
15 | cas [%o0], %g1, %g7 | ||
16 | cmp %g1, %g7 | ||
17 | bne,pn %icc, 1b | ||
18 | add %g7, 1, %g7 | ||
19 | cmp %g7, 0 | ||
20 | bl,pn %icc, 3f | ||
21 | nop | ||
22 | 2: | ||
23 | retl | ||
24 | nop | ||
25 | 3: | ||
26 | save %sp, -192, %sp | ||
27 | call rwsem_down_read_failed | ||
28 | mov %i0, %o0 | ||
29 | ret | ||
30 | restore | ||
31 | .size __down_read, .-__down_read | ||
32 | |||
33 | .globl __down_read_trylock | ||
34 | __down_read_trylock: | ||
35 | 1: lduw [%o0], %g1 | ||
36 | add %g1, 1, %g7 | ||
37 | cmp %g7, 0 | ||
38 | bl,pn %icc, 2f | ||
39 | mov 0, %o1 | ||
40 | cas [%o0], %g1, %g7 | ||
41 | cmp %g1, %g7 | ||
42 | bne,pn %icc, 1b | ||
43 | mov 1, %o1 | ||
44 | 2: retl | ||
45 | mov %o1, %o0 | ||
46 | .size __down_read_trylock, .-__down_read_trylock | ||
47 | |||
48 | .globl __down_write | ||
49 | __down_write: | ||
50 | sethi %hi(RWSEM_ACTIVE_WRITE_BIAS), %g1 | ||
51 | or %g1, %lo(RWSEM_ACTIVE_WRITE_BIAS), %g1 | ||
52 | 1: | ||
53 | lduw [%o0], %g3 | ||
54 | add %g3, %g1, %g7 | ||
55 | cas [%o0], %g3, %g7 | ||
56 | cmp %g3, %g7 | ||
57 | bne,pn %icc, 1b | ||
58 | cmp %g7, 0 | ||
59 | bne,pn %icc, 3f | ||
60 | nop | ||
61 | 2: retl | ||
62 | nop | ||
63 | 3: | ||
64 | save %sp, -192, %sp | ||
65 | call rwsem_down_write_failed | ||
66 | mov %i0, %o0 | ||
67 | ret | ||
68 | restore | ||
69 | .size __down_write, .-__down_write | ||
70 | |||
71 | .globl __down_write_trylock | ||
72 | __down_write_trylock: | ||
73 | sethi %hi(RWSEM_ACTIVE_WRITE_BIAS), %g1 | ||
74 | or %g1, %lo(RWSEM_ACTIVE_WRITE_BIAS), %g1 | ||
75 | 1: | ||
76 | lduw [%o0], %g3 | ||
77 | cmp %g3, 0 | ||
78 | bne,pn %icc, 2f | ||
79 | mov 0, %o1 | ||
80 | add %g3, %g1, %g7 | ||
81 | cas [%o0], %g3, %g7 | ||
82 | cmp %g3, %g7 | ||
83 | bne,pn %icc, 1b | ||
84 | mov 1, %o1 | ||
85 | 2: retl | ||
86 | mov %o1, %o0 | ||
87 | .size __down_write_trylock, .-__down_write_trylock | ||
88 | |||
89 | .globl __up_read | ||
90 | __up_read: | ||
91 | 1: | ||
92 | lduw [%o0], %g1 | ||
93 | sub %g1, 1, %g7 | ||
94 | cas [%o0], %g1, %g7 | ||
95 | cmp %g1, %g7 | ||
96 | bne,pn %icc, 1b | ||
97 | cmp %g7, 0 | ||
98 | bl,pn %icc, 3f | ||
99 | nop | ||
100 | 2: retl | ||
101 | nop | ||
102 | 3: sethi %hi(RWSEM_ACTIVE_MASK), %g1 | ||
103 | sub %g7, 1, %g7 | ||
104 | or %g1, %lo(RWSEM_ACTIVE_MASK), %g1 | ||
105 | andcc %g7, %g1, %g0 | ||
106 | bne,pn %icc, 2b | ||
107 | nop | ||
108 | save %sp, -192, %sp | ||
109 | call rwsem_wake | ||
110 | mov %i0, %o0 | ||
111 | ret | ||
112 | restore | ||
113 | .size __up_read, .-__up_read | ||
114 | |||
115 | .globl __up_write | ||
116 | __up_write: | ||
117 | sethi %hi(RWSEM_ACTIVE_WRITE_BIAS), %g1 | ||
118 | or %g1, %lo(RWSEM_ACTIVE_WRITE_BIAS), %g1 | ||
119 | 1: | ||
120 | lduw [%o0], %g3 | ||
121 | sub %g3, %g1, %g7 | ||
122 | cas [%o0], %g3, %g7 | ||
123 | cmp %g3, %g7 | ||
124 | bne,pn %icc, 1b | ||
125 | sub %g7, %g1, %g7 | ||
126 | cmp %g7, 0 | ||
127 | bl,pn %icc, 3f | ||
128 | nop | ||
129 | 2: | ||
130 | retl | ||
131 | nop | ||
132 | 3: | ||
133 | save %sp, -192, %sp | ||
134 | call rwsem_wake | ||
135 | mov %i0, %o0 | ||
136 | ret | ||
137 | restore | ||
138 | .size __up_write, .-__up_write | ||
139 | |||
140 | .globl __downgrade_write | ||
141 | __downgrade_write: | ||
142 | sethi %hi(RWSEM_WAITING_BIAS), %g1 | ||
143 | or %g1, %lo(RWSEM_WAITING_BIAS), %g1 | ||
144 | 1: | ||
145 | lduw [%o0], %g3 | ||
146 | sub %g3, %g1, %g7 | ||
147 | cas [%o0], %g3, %g7 | ||
148 | cmp %g3, %g7 | ||
149 | bne,pn %icc, 1b | ||
150 | sub %g7, %g1, %g7 | ||
151 | cmp %g7, 0 | ||
152 | bl,pn %icc, 3f | ||
153 | nop | ||
154 | 2: | ||
155 | retl | ||
156 | nop | ||
157 | 3: | ||
158 | save %sp, -192, %sp | ||
159 | call rwsem_downgrade_wake | ||
160 | mov %i0, %o0 | ||
161 | ret | ||
162 | restore | ||
163 | .size __downgrade_write, .-__downgrade_write | ||
diff --git a/arch/sparc/prom/cif.S b/arch/sparc/prom/cif.S index 5f27ad779c0c..9c86b4b7d429 100644 --- a/arch/sparc/prom/cif.S +++ b/arch/sparc/prom/cif.S | |||
@@ -9,18 +9,18 @@ | |||
9 | #include <asm/thread_info.h> | 9 | #include <asm/thread_info.h> |
10 | 10 | ||
11 | .text | 11 | .text |
12 | .globl prom_cif_interface | 12 | .globl prom_cif_direct |
13 | prom_cif_interface: | 13 | prom_cif_direct: |
14 | sethi %hi(p1275buf), %o0 | 14 | sethi %hi(p1275buf), %o1 |
15 | or %o0, %lo(p1275buf), %o0 | 15 | or %o1, %lo(p1275buf), %o1 |
16 | ldx [%o0 + 0x010], %o1 ! prom_cif_stack | 16 | ldx [%o1 + 0x0010], %o2 ! prom_cif_stack |
17 | save %o1, -192, %sp | 17 | save %o2, -192, %sp |
18 | ldx [%i0 + 0x008], %l2 ! prom_cif_handler | 18 | ldx [%i1 + 0x0008], %l2 ! prom_cif_handler |
19 | mov %g4, %l0 | 19 | mov %g4, %l0 |
20 | mov %g5, %l1 | 20 | mov %g5, %l1 |
21 | mov %g6, %l3 | 21 | mov %g6, %l3 |
22 | call %l2 | 22 | call %l2 |
23 | add %i0, 0x018, %o0 ! prom_args | 23 | mov %i0, %o0 ! prom_args |
24 | mov %l0, %g4 | 24 | mov %l0, %g4 |
25 | mov %l1, %g5 | 25 | mov %l1, %g5 |
26 | mov %l3, %g6 | 26 | mov %l3, %g6 |
diff --git a/arch/sparc/prom/console_64.c b/arch/sparc/prom/console_64.c index f55d58a8a156..10322dc2f557 100644 --- a/arch/sparc/prom/console_64.c +++ b/arch/sparc/prom/console_64.c | |||
@@ -21,14 +21,22 @@ extern int prom_stdin, prom_stdout; | |||
21 | inline int | 21 | inline int |
22 | prom_nbgetchar(void) | 22 | prom_nbgetchar(void) |
23 | { | 23 | { |
24 | unsigned long args[7]; | ||
24 | char inc; | 25 | char inc; |
25 | 26 | ||
26 | if (p1275_cmd("read", P1275_ARG(1,P1275_ARG_OUT_BUF)| | 27 | args[0] = (unsigned long) "read"; |
27 | P1275_INOUT(3,1), | 28 | args[1] = 3; |
28 | prom_stdin, &inc, P1275_SIZE(1)) == 1) | 29 | args[2] = 1; |
30 | args[3] = (unsigned int) prom_stdin; | ||
31 | args[4] = (unsigned long) &inc; | ||
32 | args[5] = 1; | ||
33 | args[6] = (unsigned long) -1; | ||
34 | |||
35 | p1275_cmd_direct(args); | ||
36 | |||
37 | if (args[6] == 1) | ||
29 | return inc; | 38 | return inc; |
30 | else | 39 | return -1; |
31 | return -1; | ||
32 | } | 40 | } |
33 | 41 | ||
34 | /* Non blocking put character to console device, returns -1 if | 42 | /* Non blocking put character to console device, returns -1 if |
@@ -37,12 +45,22 @@ prom_nbgetchar(void) | |||
37 | inline int | 45 | inline int |
38 | prom_nbputchar(char c) | 46 | prom_nbputchar(char c) |
39 | { | 47 | { |
48 | unsigned long args[7]; | ||
40 | char outc; | 49 | char outc; |
41 | 50 | ||
42 | outc = c; | 51 | outc = c; |
43 | if (p1275_cmd("write", P1275_ARG(1,P1275_ARG_IN_BUF)| | 52 | |
44 | P1275_INOUT(3,1), | 53 | args[0] = (unsigned long) "write"; |
45 | prom_stdout, &outc, P1275_SIZE(1)) == 1) | 54 | args[1] = 3; |
55 | args[2] = 1; | ||
56 | args[3] = (unsigned int) prom_stdout; | ||
57 | args[4] = (unsigned long) &outc; | ||
58 | args[5] = 1; | ||
59 | args[6] = (unsigned long) -1; | ||
60 | |||
61 | p1275_cmd_direct(args); | ||
62 | |||
63 | if (args[6] == 1) | ||
46 | return 0; | 64 | return 0; |
47 | else | 65 | else |
48 | return -1; | 66 | return -1; |
@@ -67,7 +85,15 @@ prom_putchar(char c) | |||
67 | void | 85 | void |
68 | prom_puts(const char *s, int len) | 86 | prom_puts(const char *s, int len) |
69 | { | 87 | { |
70 | p1275_cmd("write", P1275_ARG(1,P1275_ARG_IN_BUF)| | 88 | unsigned long args[7]; |
71 | P1275_INOUT(3,1), | 89 | |
72 | prom_stdout, s, P1275_SIZE(len)); | 90 | args[0] = (unsigned long) "write"; |
91 | args[1] = 3; | ||
92 | args[2] = 1; | ||
93 | args[3] = (unsigned int) prom_stdout; | ||
94 | args[4] = (unsigned long) s; | ||
95 | args[5] = len; | ||
96 | args[6] = (unsigned long) -1; | ||
97 | |||
98 | p1275_cmd_direct(args); | ||
73 | } | 99 | } |
diff --git a/arch/sparc/prom/devops_64.c b/arch/sparc/prom/devops_64.c index 9dbd803e46e1..a017119e7ef1 100644 --- a/arch/sparc/prom/devops_64.c +++ b/arch/sparc/prom/devops_64.c | |||
@@ -18,16 +18,32 @@ | |||
18 | int | 18 | int |
19 | prom_devopen(const char *dstr) | 19 | prom_devopen(const char *dstr) |
20 | { | 20 | { |
21 | return p1275_cmd ("open", P1275_ARG(0,P1275_ARG_IN_STRING)| | 21 | unsigned long args[5]; |
22 | P1275_INOUT(1,1), | 22 | |
23 | dstr); | 23 | args[0] = (unsigned long) "open"; |
24 | args[1] = 1; | ||
25 | args[2] = 1; | ||
26 | args[3] = (unsigned long) dstr; | ||
27 | args[4] = (unsigned long) -1; | ||
28 | |||
29 | p1275_cmd_direct(args); | ||
30 | |||
31 | return (int) args[4]; | ||
24 | } | 32 | } |
25 | 33 | ||
26 | /* Close the device described by device handle 'dhandle'. */ | 34 | /* Close the device described by device handle 'dhandle'. */ |
27 | int | 35 | int |
28 | prom_devclose(int dhandle) | 36 | prom_devclose(int dhandle) |
29 | { | 37 | { |
30 | p1275_cmd ("close", P1275_INOUT(1,0), dhandle); | 38 | unsigned long args[4]; |
39 | |||
40 | args[0] = (unsigned long) "close"; | ||
41 | args[1] = 1; | ||
42 | args[2] = 0; | ||
43 | args[3] = (unsigned int) dhandle; | ||
44 | |||
45 | p1275_cmd_direct(args); | ||
46 | |||
31 | return 0; | 47 | return 0; |
32 | } | 48 | } |
33 | 49 | ||
@@ -37,5 +53,15 @@ prom_devclose(int dhandle) | |||
37 | void | 53 | void |
38 | prom_seek(int dhandle, unsigned int seekhi, unsigned int seeklo) | 54 | prom_seek(int dhandle, unsigned int seekhi, unsigned int seeklo) |
39 | { | 55 | { |
40 | p1275_cmd ("seek", P1275_INOUT(3,1), dhandle, seekhi, seeklo); | 56 | unsigned long args[7]; |
57 | |||
58 | args[0] = (unsigned long) "seek"; | ||
59 | args[1] = 3; | ||
60 | args[2] = 1; | ||
61 | args[3] = (unsigned int) dhandle; | ||
62 | args[4] = seekhi; | ||
63 | args[5] = seeklo; | ||
64 | args[6] = (unsigned long) -1; | ||
65 | |||
66 | p1275_cmd_direct(args); | ||
41 | } | 67 | } |
diff --git a/arch/sparc/prom/misc_64.c b/arch/sparc/prom/misc_64.c index 39fc6af21b7c..6cb1581d6aef 100644 --- a/arch/sparc/prom/misc_64.c +++ b/arch/sparc/prom/misc_64.c | |||
@@ -20,10 +20,17 @@ | |||
20 | 20 | ||
21 | int prom_service_exists(const char *service_name) | 21 | int prom_service_exists(const char *service_name) |
22 | { | 22 | { |
23 | int err = p1275_cmd("test", P1275_ARG(0, P1275_ARG_IN_STRING) | | 23 | unsigned long args[5]; |
24 | P1275_INOUT(1, 1), service_name); | ||
25 | 24 | ||
26 | if (err) | 25 | args[0] = (unsigned long) "test"; |
26 | args[1] = 1; | ||
27 | args[2] = 1; | ||
28 | args[3] = (unsigned long) service_name; | ||
29 | args[4] = (unsigned long) -1; | ||
30 | |||
31 | p1275_cmd_direct(args); | ||
32 | |||
33 | if (args[4]) | ||
27 | return 0; | 34 | return 0; |
28 | return 1; | 35 | return 1; |
29 | } | 36 | } |
@@ -31,30 +38,47 @@ int prom_service_exists(const char *service_name) | |||
31 | void prom_sun4v_guest_soft_state(void) | 38 | void prom_sun4v_guest_soft_state(void) |
32 | { | 39 | { |
33 | const char *svc = "SUNW,soft-state-supported"; | 40 | const char *svc = "SUNW,soft-state-supported"; |
41 | unsigned long args[3]; | ||
34 | 42 | ||
35 | if (!prom_service_exists(svc)) | 43 | if (!prom_service_exists(svc)) |
36 | return; | 44 | return; |
37 | p1275_cmd(svc, P1275_INOUT(0, 0)); | 45 | args[0] = (unsigned long) svc; |
46 | args[1] = 0; | ||
47 | args[2] = 0; | ||
48 | p1275_cmd_direct(args); | ||
38 | } | 49 | } |
39 | 50 | ||
40 | /* Reset and reboot the machine with the command 'bcommand'. */ | 51 | /* Reset and reboot the machine with the command 'bcommand'. */ |
41 | void prom_reboot(const char *bcommand) | 52 | void prom_reboot(const char *bcommand) |
42 | { | 53 | { |
54 | unsigned long args[4]; | ||
55 | |||
43 | #ifdef CONFIG_SUN_LDOMS | 56 | #ifdef CONFIG_SUN_LDOMS |
44 | if (ldom_domaining_enabled) | 57 | if (ldom_domaining_enabled) |
45 | ldom_reboot(bcommand); | 58 | ldom_reboot(bcommand); |
46 | #endif | 59 | #endif |
47 | p1275_cmd("boot", P1275_ARG(0, P1275_ARG_IN_STRING) | | 60 | args[0] = (unsigned long) "boot"; |
48 | P1275_INOUT(1, 0), bcommand); | 61 | args[1] = 1; |
62 | args[2] = 0; | ||
63 | args[3] = (unsigned long) bcommand; | ||
64 | |||
65 | p1275_cmd_direct(args); | ||
49 | } | 66 | } |
50 | 67 | ||
51 | /* Forth evaluate the expression contained in 'fstring'. */ | 68 | /* Forth evaluate the expression contained in 'fstring'. */ |
52 | void prom_feval(const char *fstring) | 69 | void prom_feval(const char *fstring) |
53 | { | 70 | { |
71 | unsigned long args[5]; | ||
72 | |||
54 | if (!fstring || fstring[0] == 0) | 73 | if (!fstring || fstring[0] == 0) |
55 | return; | 74 | return; |
56 | p1275_cmd("interpret", P1275_ARG(0, P1275_ARG_IN_STRING) | | 75 | args[0] = (unsigned long) "interpret"; |
57 | P1275_INOUT(1, 1), fstring); | 76 | args[1] = 1; |
77 | args[2] = 1; | ||
78 | args[3] = (unsigned long) fstring; | ||
79 | args[4] = (unsigned long) -1; | ||
80 | |||
81 | p1275_cmd_direct(args); | ||
58 | } | 82 | } |
59 | EXPORT_SYMBOL(prom_feval); | 83 | EXPORT_SYMBOL(prom_feval); |
60 | 84 | ||
@@ -68,6 +92,7 @@ extern void smp_release(void); | |||
68 | */ | 92 | */ |
69 | void prom_cmdline(void) | 93 | void prom_cmdline(void) |
70 | { | 94 | { |
95 | unsigned long args[3]; | ||
71 | unsigned long flags; | 96 | unsigned long flags; |
72 | 97 | ||
73 | local_irq_save(flags); | 98 | local_irq_save(flags); |
@@ -76,7 +101,11 @@ void prom_cmdline(void) | |||
76 | smp_capture(); | 101 | smp_capture(); |
77 | #endif | 102 | #endif |
78 | 103 | ||
79 | p1275_cmd("enter", P1275_INOUT(0, 0)); | 104 | args[0] = (unsigned long) "enter"; |
105 | args[1] = 0; | ||
106 | args[2] = 0; | ||
107 | |||
108 | p1275_cmd_direct(args); | ||
80 | 109 | ||
81 | #ifdef CONFIG_SMP | 110 | #ifdef CONFIG_SMP |
82 | smp_release(); | 111 | smp_release(); |
@@ -90,22 +119,32 @@ void prom_cmdline(void) | |||
90 | */ | 119 | */ |
91 | void notrace prom_halt(void) | 120 | void notrace prom_halt(void) |
92 | { | 121 | { |
122 | unsigned long args[3]; | ||
123 | |||
93 | #ifdef CONFIG_SUN_LDOMS | 124 | #ifdef CONFIG_SUN_LDOMS |
94 | if (ldom_domaining_enabled) | 125 | if (ldom_domaining_enabled) |
95 | ldom_power_off(); | 126 | ldom_power_off(); |
96 | #endif | 127 | #endif |
97 | again: | 128 | again: |
98 | p1275_cmd("exit", P1275_INOUT(0, 0)); | 129 | args[0] = (unsigned long) "exit"; |
130 | args[1] = 0; | ||
131 | args[2] = 0; | ||
132 | p1275_cmd_direct(args); | ||
99 | goto again; /* PROM is out to get me -DaveM */ | 133 | goto again; /* PROM is out to get me -DaveM */ |
100 | } | 134 | } |
101 | 135 | ||
102 | void prom_halt_power_off(void) | 136 | void prom_halt_power_off(void) |
103 | { | 137 | { |
138 | unsigned long args[3]; | ||
139 | |||
104 | #ifdef CONFIG_SUN_LDOMS | 140 | #ifdef CONFIG_SUN_LDOMS |
105 | if (ldom_domaining_enabled) | 141 | if (ldom_domaining_enabled) |
106 | ldom_power_off(); | 142 | ldom_power_off(); |
107 | #endif | 143 | #endif |
108 | p1275_cmd("SUNW,power-off", P1275_INOUT(0, 0)); | 144 | args[0] = (unsigned long) "SUNW,power-off"; |
145 | args[1] = 0; | ||
146 | args[2] = 0; | ||
147 | p1275_cmd_direct(args); | ||
109 | 148 | ||
110 | /* if nothing else helps, we just halt */ | 149 | /* if nothing else helps, we just halt */ |
111 | prom_halt(); | 150 | prom_halt(); |
@@ -114,10 +153,15 @@ void prom_halt_power_off(void) | |||
114 | /* Set prom sync handler to call function 'funcp'. */ | 153 | /* Set prom sync handler to call function 'funcp'. */ |
115 | void prom_setcallback(callback_func_t funcp) | 154 | void prom_setcallback(callback_func_t funcp) |
116 | { | 155 | { |
156 | unsigned long args[5]; | ||
117 | if (!funcp) | 157 | if (!funcp) |
118 | return; | 158 | return; |
119 | p1275_cmd("set-callback", P1275_ARG(0, P1275_ARG_IN_FUNCTION) | | 159 | args[0] = (unsigned long) "set-callback"; |
120 | P1275_INOUT(1, 1), funcp); | 160 | args[1] = 1; |
161 | args[2] = 1; | ||
162 | args[3] = (unsigned long) funcp; | ||
163 | args[4] = (unsigned long) -1; | ||
164 | p1275_cmd_direct(args); | ||
121 | } | 165 | } |
122 | 166 | ||
123 | /* Get the idprom and stuff it into buffer 'idbuf'. Returns the | 167 | /* Get the idprom and stuff it into buffer 'idbuf'. Returns the |
@@ -173,57 +217,61 @@ static int prom_get_memory_ihandle(void) | |||
173 | } | 217 | } |
174 | 218 | ||
175 | /* Load explicit I/D TLB entries. */ | 219 | /* Load explicit I/D TLB entries. */ |
220 | static long tlb_load(const char *type, unsigned long index, | ||
221 | unsigned long tte_data, unsigned long vaddr) | ||
222 | { | ||
223 | unsigned long args[9]; | ||
224 | |||
225 | args[0] = (unsigned long) prom_callmethod_name; | ||
226 | args[1] = 5; | ||
227 | args[2] = 1; | ||
228 | args[3] = (unsigned long) type; | ||
229 | args[4] = (unsigned int) prom_get_mmu_ihandle(); | ||
230 | args[5] = vaddr; | ||
231 | args[6] = tte_data; | ||
232 | args[7] = index; | ||
233 | args[8] = (unsigned long) -1; | ||
234 | |||
235 | p1275_cmd_direct(args); | ||
236 | |||
237 | return (long) args[8]; | ||
238 | } | ||
239 | |||
176 | long prom_itlb_load(unsigned long index, | 240 | long prom_itlb_load(unsigned long index, |
177 | unsigned long tte_data, | 241 | unsigned long tte_data, |
178 | unsigned long vaddr) | 242 | unsigned long vaddr) |
179 | { | 243 | { |
180 | return p1275_cmd(prom_callmethod_name, | 244 | return tlb_load("SUNW,itlb-load", index, tte_data, vaddr); |
181 | (P1275_ARG(0, P1275_ARG_IN_STRING) | | ||
182 | P1275_ARG(2, P1275_ARG_IN_64B) | | ||
183 | P1275_ARG(3, P1275_ARG_IN_64B) | | ||
184 | P1275_INOUT(5, 1)), | ||
185 | "SUNW,itlb-load", | ||
186 | prom_get_mmu_ihandle(), | ||
187 | /* And then our actual args are pushed backwards. */ | ||
188 | vaddr, | ||
189 | tte_data, | ||
190 | index); | ||
191 | } | 245 | } |
192 | 246 | ||
193 | long prom_dtlb_load(unsigned long index, | 247 | long prom_dtlb_load(unsigned long index, |
194 | unsigned long tte_data, | 248 | unsigned long tte_data, |
195 | unsigned long vaddr) | 249 | unsigned long vaddr) |
196 | { | 250 | { |
197 | return p1275_cmd(prom_callmethod_name, | 251 | return tlb_load("SUNW,dtlb-load", index, tte_data, vaddr); |
198 | (P1275_ARG(0, P1275_ARG_IN_STRING) | | ||
199 | P1275_ARG(2, P1275_ARG_IN_64B) | | ||
200 | P1275_ARG(3, P1275_ARG_IN_64B) | | ||
201 | P1275_INOUT(5, 1)), | ||
202 | "SUNW,dtlb-load", | ||
203 | prom_get_mmu_ihandle(), | ||
204 | /* And then our actual args are pushed backwards. */ | ||
205 | vaddr, | ||
206 | tte_data, | ||
207 | index); | ||
208 | } | 252 | } |
209 | 253 | ||
210 | int prom_map(int mode, unsigned long size, | 254 | int prom_map(int mode, unsigned long size, |
211 | unsigned long vaddr, unsigned long paddr) | 255 | unsigned long vaddr, unsigned long paddr) |
212 | { | 256 | { |
213 | int ret = p1275_cmd(prom_callmethod_name, | 257 | unsigned long args[11]; |
214 | (P1275_ARG(0, P1275_ARG_IN_STRING) | | 258 | int ret; |
215 | P1275_ARG(3, P1275_ARG_IN_64B) | | 259 | |
216 | P1275_ARG(4, P1275_ARG_IN_64B) | | 260 | args[0] = (unsigned long) prom_callmethod_name; |
217 | P1275_ARG(6, P1275_ARG_IN_64B) | | 261 | args[1] = 7; |
218 | P1275_INOUT(7, 1)), | 262 | args[2] = 1; |
219 | prom_map_name, | 263 | args[3] = (unsigned long) prom_map_name; |
220 | prom_get_mmu_ihandle(), | 264 | args[4] = (unsigned int) prom_get_mmu_ihandle(); |
221 | mode, | 265 | args[5] = (unsigned int) mode; |
222 | size, | 266 | args[6] = size; |
223 | vaddr, | 267 | args[7] = vaddr; |
224 | 0, | 268 | args[8] = 0; |
225 | paddr); | 269 | args[9] = paddr; |
226 | 270 | args[10] = (unsigned long) -1; | |
271 | |||
272 | p1275_cmd_direct(args); | ||
273 | |||
274 | ret = (int) args[10]; | ||
227 | if (ret == 0) | 275 | if (ret == 0) |
228 | ret = -1; | 276 | ret = -1; |
229 | return ret; | 277 | return ret; |
@@ -231,40 +279,51 @@ int prom_map(int mode, unsigned long size, | |||
231 | 279 | ||
232 | void prom_unmap(unsigned long size, unsigned long vaddr) | 280 | void prom_unmap(unsigned long size, unsigned long vaddr) |
233 | { | 281 | { |
234 | p1275_cmd(prom_callmethod_name, | 282 | unsigned long args[7]; |
235 | (P1275_ARG(0, P1275_ARG_IN_STRING) | | 283 | |
236 | P1275_ARG(2, P1275_ARG_IN_64B) | | 284 | args[0] = (unsigned long) prom_callmethod_name; |
237 | P1275_ARG(3, P1275_ARG_IN_64B) | | 285 | args[1] = 4; |
238 | P1275_INOUT(4, 0)), | 286 | args[2] = 0; |
239 | prom_unmap_name, | 287 | args[3] = (unsigned long) prom_unmap_name; |
240 | prom_get_mmu_ihandle(), | 288 | args[4] = (unsigned int) prom_get_mmu_ihandle(); |
241 | size, | 289 | args[5] = size; |
242 | vaddr); | 290 | args[6] = vaddr; |
291 | |||
292 | p1275_cmd_direct(args); | ||
243 | } | 293 | } |
244 | 294 | ||
245 | /* Set aside physical memory which is not touched or modified | 295 | /* Set aside physical memory which is not touched or modified |
246 | * across soft resets. | 296 | * across soft resets. |
247 | */ | 297 | */ |
248 | unsigned long prom_retain(const char *name, | 298 | int prom_retain(const char *name, unsigned long size, |
249 | unsigned long pa_low, unsigned long pa_high, | 299 | unsigned long align, unsigned long *paddr) |
250 | long size, long align) | ||
251 | { | 300 | { |
252 | /* XXX I don't think we return multiple values correctly. | 301 | unsigned long args[11]; |
253 | * XXX OBP supposedly returns pa_low/pa_high here, how does | 302 | |
254 | * XXX it work? | 303 | args[0] = (unsigned long) prom_callmethod_name; |
304 | args[1] = 5; | ||
305 | args[2] = 3; | ||
306 | args[3] = (unsigned long) "SUNW,retain"; | ||
307 | args[4] = (unsigned int) prom_get_memory_ihandle(); | ||
308 | args[5] = align; | ||
309 | args[6] = size; | ||
310 | args[7] = (unsigned long) name; | ||
311 | args[8] = (unsigned long) -1; | ||
312 | args[9] = (unsigned long) -1; | ||
313 | args[10] = (unsigned long) -1; | ||
314 | |||
315 | p1275_cmd_direct(args); | ||
316 | |||
317 | if (args[8]) | ||
318 | return (int) args[8]; | ||
319 | |||
320 | /* Next we get "phys_high" then "phys_low". On 64-bit | ||
321 | * the phys_high cell is don't care since the phys_low | ||
322 | * cell has the full value. | ||
255 | */ | 323 | */ |
324 | *paddr = args[10]; | ||
256 | 325 | ||
257 | /* If align is zero, the pa_low/pa_high args are passed, | 326 | return 0; |
258 | * else they are not. | ||
259 | */ | ||
260 | if (align == 0) | ||
261 | return p1275_cmd("SUNW,retain", | ||
262 | (P1275_ARG(0, P1275_ARG_IN_BUF) | P1275_INOUT(5, 2)), | ||
263 | name, pa_low, pa_high, size, align); | ||
264 | else | ||
265 | return p1275_cmd("SUNW,retain", | ||
266 | (P1275_ARG(0, P1275_ARG_IN_BUF) | P1275_INOUT(3, 2)), | ||
267 | name, size, align); | ||
268 | } | 327 | } |
269 | 328 | ||
270 | /* Get "Unumber" string for the SIMM at the given | 329 | /* Get "Unumber" string for the SIMM at the given |
@@ -277,62 +336,129 @@ int prom_getunumber(int syndrome_code, | |||
277 | unsigned long phys_addr, | 336 | unsigned long phys_addr, |
278 | char *buf, int buflen) | 337 | char *buf, int buflen) |
279 | { | 338 | { |
280 | return p1275_cmd(prom_callmethod_name, | 339 | unsigned long args[12]; |
281 | (P1275_ARG(0, P1275_ARG_IN_STRING) | | 340 | |
282 | P1275_ARG(3, P1275_ARG_OUT_BUF) | | 341 | args[0] = (unsigned long) prom_callmethod_name; |
283 | P1275_ARG(6, P1275_ARG_IN_64B) | | 342 | args[1] = 7; |
284 | P1275_INOUT(8, 2)), | 343 | args[2] = 2; |
285 | "SUNW,get-unumber", prom_get_memory_ihandle(), | 344 | args[3] = (unsigned long) "SUNW,get-unumber"; |
286 | buflen, buf, P1275_SIZE(buflen), | 345 | args[4] = (unsigned int) prom_get_memory_ihandle(); |
287 | 0, phys_addr, syndrome_code); | 346 | args[5] = buflen; |
347 | args[6] = (unsigned long) buf; | ||
348 | args[7] = 0; | ||
349 | args[8] = phys_addr; | ||
350 | args[9] = (unsigned int) syndrome_code; | ||
351 | args[10] = (unsigned long) -1; | ||
352 | args[11] = (unsigned long) -1; | ||
353 | |||
354 | p1275_cmd_direct(args); | ||
355 | |||
356 | return (int) args[10]; | ||
288 | } | 357 | } |
289 | 358 | ||
290 | /* Power management extensions. */ | 359 | /* Power management extensions. */ |
291 | void prom_sleepself(void) | 360 | void prom_sleepself(void) |
292 | { | 361 | { |
293 | p1275_cmd("SUNW,sleep-self", P1275_INOUT(0, 0)); | 362 | unsigned long args[3]; |
363 | |||
364 | args[0] = (unsigned long) "SUNW,sleep-self"; | ||
365 | args[1] = 0; | ||
366 | args[2] = 0; | ||
367 | p1275_cmd_direct(args); | ||
294 | } | 368 | } |
295 | 369 | ||
296 | int prom_sleepsystem(void) | 370 | int prom_sleepsystem(void) |
297 | { | 371 | { |
298 | return p1275_cmd("SUNW,sleep-system", P1275_INOUT(0, 1)); | 372 | unsigned long args[4]; |
373 | |||
374 | args[0] = (unsigned long) "SUNW,sleep-system"; | ||
375 | args[1] = 0; | ||
376 | args[2] = 1; | ||
377 | args[3] = (unsigned long) -1; | ||
378 | p1275_cmd_direct(args); | ||
379 | |||
380 | return (int) args[3]; | ||
299 | } | 381 | } |
300 | 382 | ||
301 | int prom_wakeupsystem(void) | 383 | int prom_wakeupsystem(void) |
302 | { | 384 | { |
303 | return p1275_cmd("SUNW,wakeup-system", P1275_INOUT(0, 1)); | 385 | unsigned long args[4]; |
386 | |||
387 | args[0] = (unsigned long) "SUNW,wakeup-system"; | ||
388 | args[1] = 0; | ||
389 | args[2] = 1; | ||
390 | args[3] = (unsigned long) -1; | ||
391 | p1275_cmd_direct(args); | ||
392 | |||
393 | return (int) args[3]; | ||
304 | } | 394 | } |
305 | 395 | ||
306 | #ifdef CONFIG_SMP | 396 | #ifdef CONFIG_SMP |
307 | void prom_startcpu(int cpunode, unsigned long pc, unsigned long arg) | 397 | void prom_startcpu(int cpunode, unsigned long pc, unsigned long arg) |
308 | { | 398 | { |
309 | p1275_cmd("SUNW,start-cpu", P1275_INOUT(3, 0), cpunode, pc, arg); | 399 | unsigned long args[6]; |
400 | |||
401 | args[0] = (unsigned long) "SUNW,start-cpu"; | ||
402 | args[1] = 3; | ||
403 | args[2] = 0; | ||
404 | args[3] = (unsigned int) cpunode; | ||
405 | args[4] = pc; | ||
406 | args[5] = arg; | ||
407 | p1275_cmd_direct(args); | ||
310 | } | 408 | } |
311 | 409 | ||
312 | void prom_startcpu_cpuid(int cpuid, unsigned long pc, unsigned long arg) | 410 | void prom_startcpu_cpuid(int cpuid, unsigned long pc, unsigned long arg) |
313 | { | 411 | { |
314 | p1275_cmd("SUNW,start-cpu-by-cpuid", P1275_INOUT(3, 0), | 412 | unsigned long args[6]; |
315 | cpuid, pc, arg); | 413 | |
414 | args[0] = (unsigned long) "SUNW,start-cpu-by-cpuid"; | ||
415 | args[1] = 3; | ||
416 | args[2] = 0; | ||
417 | args[3] = (unsigned int) cpuid; | ||
418 | args[4] = pc; | ||
419 | args[5] = arg; | ||
420 | p1275_cmd_direct(args); | ||
316 | } | 421 | } |
317 | 422 | ||
318 | void prom_stopcpu_cpuid(int cpuid) | 423 | void prom_stopcpu_cpuid(int cpuid) |
319 | { | 424 | { |
320 | p1275_cmd("SUNW,stop-cpu-by-cpuid", P1275_INOUT(1, 0), | 425 | unsigned long args[4]; |
321 | cpuid); | 426 | |
427 | args[0] = (unsigned long) "SUNW,stop-cpu-by-cpuid"; | ||
428 | args[1] = 1; | ||
429 | args[2] = 0; | ||
430 | args[3] = (unsigned int) cpuid; | ||
431 | p1275_cmd_direct(args); | ||
322 | } | 432 | } |
323 | 433 | ||
324 | void prom_stopself(void) | 434 | void prom_stopself(void) |
325 | { | 435 | { |
326 | p1275_cmd("SUNW,stop-self", P1275_INOUT(0, 0)); | 436 | unsigned long args[3]; |
437 | |||
438 | args[0] = (unsigned long) "SUNW,stop-self"; | ||
439 | args[1] = 0; | ||
440 | args[2] = 0; | ||
441 | p1275_cmd_direct(args); | ||
327 | } | 442 | } |
328 | 443 | ||
329 | void prom_idleself(void) | 444 | void prom_idleself(void) |
330 | { | 445 | { |
331 | p1275_cmd("SUNW,idle-self", P1275_INOUT(0, 0)); | 446 | unsigned long args[3]; |
447 | |||
448 | args[0] = (unsigned long) "SUNW,idle-self"; | ||
449 | args[1] = 0; | ||
450 | args[2] = 0; | ||
451 | p1275_cmd_direct(args); | ||
332 | } | 452 | } |
333 | 453 | ||
334 | void prom_resumecpu(int cpunode) | 454 | void prom_resumecpu(int cpunode) |
335 | { | 455 | { |
336 | p1275_cmd("SUNW,resume-cpu", P1275_INOUT(1, 0), cpunode); | 456 | unsigned long args[4]; |
457 | |||
458 | args[0] = (unsigned long) "SUNW,resume-cpu"; | ||
459 | args[1] = 1; | ||
460 | args[2] = 0; | ||
461 | args[3] = (unsigned int) cpunode; | ||
462 | p1275_cmd_direct(args); | ||
337 | } | 463 | } |
338 | #endif | 464 | #endif |
diff --git a/arch/sparc/prom/p1275.c b/arch/sparc/prom/p1275.c index 2d8b70d397f1..fa6e4e219b9c 100644 --- a/arch/sparc/prom/p1275.c +++ b/arch/sparc/prom/p1275.c | |||
@@ -22,13 +22,11 @@ struct { | |||
22 | long prom_callback; /* 0x00 */ | 22 | long prom_callback; /* 0x00 */ |
23 | void (*prom_cif_handler)(long *); /* 0x08 */ | 23 | void (*prom_cif_handler)(long *); /* 0x08 */ |
24 | unsigned long prom_cif_stack; /* 0x10 */ | 24 | unsigned long prom_cif_stack; /* 0x10 */ |
25 | unsigned long prom_args [23]; /* 0x18 */ | ||
26 | char prom_buffer [3000]; | ||
27 | } p1275buf; | 25 | } p1275buf; |
28 | 26 | ||
29 | extern void prom_world(int); | 27 | extern void prom_world(int); |
30 | 28 | ||
31 | extern void prom_cif_interface(void); | 29 | extern void prom_cif_direct(unsigned long *args); |
32 | extern void prom_cif_callback(void); | 30 | extern void prom_cif_callback(void); |
33 | 31 | ||
34 | /* | 32 | /* |
@@ -36,114 +34,20 @@ extern void prom_cif_callback(void); | |||
36 | */ | 34 | */ |
37 | DEFINE_RAW_SPINLOCK(prom_entry_lock); | 35 | DEFINE_RAW_SPINLOCK(prom_entry_lock); |
38 | 36 | ||
39 | long p1275_cmd(const char *service, long fmt, ...) | 37 | void p1275_cmd_direct(unsigned long *args) |
40 | { | 38 | { |
41 | char *p, *q; | ||
42 | unsigned long flags; | 39 | unsigned long flags; |
43 | int nargs, nrets, i; | ||
44 | va_list list; | ||
45 | long attrs, x; | ||
46 | |||
47 | p = p1275buf.prom_buffer; | ||
48 | 40 | ||
49 | raw_local_save_flags(flags); | 41 | raw_local_save_flags(flags); |
50 | raw_local_irq_restore(PIL_NMI); | 42 | raw_local_irq_restore(PIL_NMI); |
51 | raw_spin_lock(&prom_entry_lock); | 43 | raw_spin_lock(&prom_entry_lock); |
52 | 44 | ||
53 | p1275buf.prom_args[0] = (unsigned long)p; /* service */ | ||
54 | strcpy (p, service); | ||
55 | p = (char *)(((long)(strchr (p, 0) + 8)) & ~7); | ||
56 | p1275buf.prom_args[1] = nargs = (fmt & 0x0f); /* nargs */ | ||
57 | p1275buf.prom_args[2] = nrets = ((fmt & 0xf0) >> 4); /* nrets */ | ||
58 | attrs = fmt >> 8; | ||
59 | va_start(list, fmt); | ||
60 | for (i = 0; i < nargs; i++, attrs >>= 3) { | ||
61 | switch (attrs & 0x7) { | ||
62 | case P1275_ARG_NUMBER: | ||
63 | p1275buf.prom_args[i + 3] = | ||
64 | (unsigned)va_arg(list, long); | ||
65 | break; | ||
66 | case P1275_ARG_IN_64B: | ||
67 | p1275buf.prom_args[i + 3] = | ||
68 | va_arg(list, unsigned long); | ||
69 | break; | ||
70 | case P1275_ARG_IN_STRING: | ||
71 | strcpy (p, va_arg(list, char *)); | ||
72 | p1275buf.prom_args[i + 3] = (unsigned long)p; | ||
73 | p = (char *)(((long)(strchr (p, 0) + 8)) & ~7); | ||
74 | break; | ||
75 | case P1275_ARG_OUT_BUF: | ||
76 | (void) va_arg(list, char *); | ||
77 | p1275buf.prom_args[i + 3] = (unsigned long)p; | ||
78 | x = va_arg(list, long); | ||
79 | i++; attrs >>= 3; | ||
80 | p = (char *)(((long)(p + (int)x + 7)) & ~7); | ||
81 | p1275buf.prom_args[i + 3] = x; | ||
82 | break; | ||
83 | case P1275_ARG_IN_BUF: | ||
84 | q = va_arg(list, char *); | ||
85 | p1275buf.prom_args[i + 3] = (unsigned long)p; | ||
86 | x = va_arg(list, long); | ||
87 | i++; attrs >>= 3; | ||
88 | memcpy (p, q, (int)x); | ||
89 | p = (char *)(((long)(p + (int)x + 7)) & ~7); | ||
90 | p1275buf.prom_args[i + 3] = x; | ||
91 | break; | ||
92 | case P1275_ARG_OUT_32B: | ||
93 | (void) va_arg(list, char *); | ||
94 | p1275buf.prom_args[i + 3] = (unsigned long)p; | ||
95 | p += 32; | ||
96 | break; | ||
97 | case P1275_ARG_IN_FUNCTION: | ||
98 | p1275buf.prom_args[i + 3] = | ||
99 | (unsigned long)prom_cif_callback; | ||
100 | p1275buf.prom_callback = va_arg(list, long); | ||
101 | break; | ||
102 | } | ||
103 | } | ||
104 | va_end(list); | ||
105 | |||
106 | prom_world(1); | 45 | prom_world(1); |
107 | prom_cif_interface(); | 46 | prom_cif_direct(args); |
108 | prom_world(0); | 47 | prom_world(0); |
109 | 48 | ||
110 | attrs = fmt >> 8; | ||
111 | va_start(list, fmt); | ||
112 | for (i = 0; i < nargs; i++, attrs >>= 3) { | ||
113 | switch (attrs & 0x7) { | ||
114 | case P1275_ARG_NUMBER: | ||
115 | (void) va_arg(list, long); | ||
116 | break; | ||
117 | case P1275_ARG_IN_STRING: | ||
118 | (void) va_arg(list, char *); | ||
119 | break; | ||
120 | case P1275_ARG_IN_FUNCTION: | ||
121 | (void) va_arg(list, long); | ||
122 | break; | ||
123 | case P1275_ARG_IN_BUF: | ||
124 | (void) va_arg(list, char *); | ||
125 | (void) va_arg(list, long); | ||
126 | i++; attrs >>= 3; | ||
127 | break; | ||
128 | case P1275_ARG_OUT_BUF: | ||
129 | p = va_arg(list, char *); | ||
130 | x = va_arg(list, long); | ||
131 | memcpy (p, (char *)(p1275buf.prom_args[i + 3]), (int)x); | ||
132 | i++; attrs >>= 3; | ||
133 | break; | ||
134 | case P1275_ARG_OUT_32B: | ||
135 | p = va_arg(list, char *); | ||
136 | memcpy (p, (char *)(p1275buf.prom_args[i + 3]), 32); | ||
137 | break; | ||
138 | } | ||
139 | } | ||
140 | va_end(list); | ||
141 | x = p1275buf.prom_args [nargs + 3]; | ||
142 | |||
143 | raw_spin_unlock(&prom_entry_lock); | 49 | raw_spin_unlock(&prom_entry_lock); |
144 | raw_local_irq_restore(flags); | 50 | raw_local_irq_restore(flags); |
145 | |||
146 | return x; | ||
147 | } | 51 | } |
148 | 52 | ||
149 | void prom_cif_init(void *cif_handler, void *cif_stack) | 53 | void prom_cif_init(void *cif_handler, void *cif_stack) |
diff --git a/arch/sparc/prom/tree_64.c b/arch/sparc/prom/tree_64.c index 3c0d2dd9f693..9d3f9137a43a 100644 --- a/arch/sparc/prom/tree_64.c +++ b/arch/sparc/prom/tree_64.c | |||
@@ -16,22 +16,39 @@ | |||
16 | #include <asm/oplib.h> | 16 | #include <asm/oplib.h> |
17 | #include <asm/ldc.h> | 17 | #include <asm/ldc.h> |
18 | 18 | ||
19 | static int prom_node_to_node(const char *type, int node) | ||
20 | { | ||
21 | unsigned long args[5]; | ||
22 | |||
23 | args[0] = (unsigned long) type; | ||
24 | args[1] = 1; | ||
25 | args[2] = 1; | ||
26 | args[3] = (unsigned int) node; | ||
27 | args[4] = (unsigned long) -1; | ||
28 | |||
29 | p1275_cmd_direct(args); | ||
30 | |||
31 | return (int) args[4]; | ||
32 | } | ||
33 | |||
19 | /* Return the child of node 'node' or zero if no this node has no | 34 | /* Return the child of node 'node' or zero if no this node has no |
20 | * direct descendent. | 35 | * direct descendent. |
21 | */ | 36 | */ |
22 | inline int __prom_getchild(int node) | 37 | inline int __prom_getchild(int node) |
23 | { | 38 | { |
24 | return p1275_cmd ("child", P1275_INOUT(1, 1), node); | 39 | return prom_node_to_node("child", node); |
25 | } | 40 | } |
26 | 41 | ||
27 | inline int prom_getchild(int node) | 42 | inline int prom_getchild(int node) |
28 | { | 43 | { |
29 | int cnode; | 44 | int cnode; |
30 | 45 | ||
31 | if(node == -1) return 0; | 46 | if (node == -1) |
47 | return 0; | ||
32 | cnode = __prom_getchild(node); | 48 | cnode = __prom_getchild(node); |
33 | if(cnode == -1) return 0; | 49 | if (cnode == -1) |
34 | return (int)cnode; | 50 | return 0; |
51 | return cnode; | ||
35 | } | 52 | } |
36 | EXPORT_SYMBOL(prom_getchild); | 53 | EXPORT_SYMBOL(prom_getchild); |
37 | 54 | ||
@@ -39,10 +56,12 @@ inline int prom_getparent(int node) | |||
39 | { | 56 | { |
40 | int cnode; | 57 | int cnode; |
41 | 58 | ||
42 | if(node == -1) return 0; | 59 | if (node == -1) |
43 | cnode = p1275_cmd ("parent", P1275_INOUT(1, 1), node); | 60 | return 0; |
44 | if(cnode == -1) return 0; | 61 | cnode = prom_node_to_node("parent", node); |
45 | return (int)cnode; | 62 | if (cnode == -1) |
63 | return 0; | ||
64 | return cnode; | ||
46 | } | 65 | } |
47 | 66 | ||
48 | /* Return the next sibling of node 'node' or zero if no more siblings | 67 | /* Return the next sibling of node 'node' or zero if no more siblings |
@@ -50,7 +69,7 @@ inline int prom_getparent(int node) | |||
50 | */ | 69 | */ |
51 | inline int __prom_getsibling(int node) | 70 | inline int __prom_getsibling(int node) |
52 | { | 71 | { |
53 | return p1275_cmd(prom_peer_name, P1275_INOUT(1, 1), node); | 72 | return prom_node_to_node(prom_peer_name, node); |
54 | } | 73 | } |
55 | 74 | ||
56 | inline int prom_getsibling(int node) | 75 | inline int prom_getsibling(int node) |
@@ -72,11 +91,21 @@ EXPORT_SYMBOL(prom_getsibling); | |||
72 | */ | 91 | */ |
73 | inline int prom_getproplen(int node, const char *prop) | 92 | inline int prom_getproplen(int node, const char *prop) |
74 | { | 93 | { |
75 | if((!node) || (!prop)) return -1; | 94 | unsigned long args[6]; |
76 | return p1275_cmd ("getproplen", | 95 | |
77 | P1275_ARG(1,P1275_ARG_IN_STRING)| | 96 | if (!node || !prop) |
78 | P1275_INOUT(2, 1), | 97 | return -1; |
79 | node, prop); | 98 | |
99 | args[0] = (unsigned long) "getproplen"; | ||
100 | args[1] = 2; | ||
101 | args[2] = 1; | ||
102 | args[3] = (unsigned int) node; | ||
103 | args[4] = (unsigned long) prop; | ||
104 | args[5] = (unsigned long) -1; | ||
105 | |||
106 | p1275_cmd_direct(args); | ||
107 | |||
108 | return (int) args[5]; | ||
80 | } | 109 | } |
81 | EXPORT_SYMBOL(prom_getproplen); | 110 | EXPORT_SYMBOL(prom_getproplen); |
82 | 111 | ||
@@ -87,19 +116,25 @@ EXPORT_SYMBOL(prom_getproplen); | |||
87 | inline int prom_getproperty(int node, const char *prop, | 116 | inline int prom_getproperty(int node, const char *prop, |
88 | char *buffer, int bufsize) | 117 | char *buffer, int bufsize) |
89 | { | 118 | { |
119 | unsigned long args[8]; | ||
90 | int plen; | 120 | int plen; |
91 | 121 | ||
92 | plen = prom_getproplen(node, prop); | 122 | plen = prom_getproplen(node, prop); |
93 | if ((plen > bufsize) || (plen == 0) || (plen == -1)) { | 123 | if ((plen > bufsize) || (plen == 0) || (plen == -1)) |
94 | return -1; | 124 | return -1; |
95 | } else { | 125 | |
96 | /* Ok, things seem all right. */ | 126 | args[0] = (unsigned long) prom_getprop_name; |
97 | return p1275_cmd(prom_getprop_name, | 127 | args[1] = 4; |
98 | P1275_ARG(1,P1275_ARG_IN_STRING)| | 128 | args[2] = 1; |
99 | P1275_ARG(2,P1275_ARG_OUT_BUF)| | 129 | args[3] = (unsigned int) node; |
100 | P1275_INOUT(4, 1), | 130 | args[4] = (unsigned long) prop; |
101 | node, prop, buffer, P1275_SIZE(plen)); | 131 | args[5] = (unsigned long) buffer; |
102 | } | 132 | args[6] = bufsize; |
133 | args[7] = (unsigned long) -1; | ||
134 | |||
135 | p1275_cmd_direct(args); | ||
136 | |||
137 | return (int) args[7]; | ||
103 | } | 138 | } |
104 | EXPORT_SYMBOL(prom_getproperty); | 139 | EXPORT_SYMBOL(prom_getproperty); |
105 | 140 | ||
@@ -110,7 +145,7 @@ inline int prom_getint(int node, const char *prop) | |||
110 | { | 145 | { |
111 | int intprop; | 146 | int intprop; |
112 | 147 | ||
113 | if(prom_getproperty(node, prop, (char *) &intprop, sizeof(int)) != -1) | 148 | if (prom_getproperty(node, prop, (char *) &intprop, sizeof(int)) != -1) |
114 | return intprop; | 149 | return intprop; |
115 | 150 | ||
116 | return -1; | 151 | return -1; |
@@ -126,7 +161,8 @@ int prom_getintdefault(int node, const char *property, int deflt) | |||
126 | int retval; | 161 | int retval; |
127 | 162 | ||
128 | retval = prom_getint(node, property); | 163 | retval = prom_getint(node, property); |
129 | if(retval == -1) return deflt; | 164 | if (retval == -1) |
165 | return deflt; | ||
130 | 166 | ||
131 | return retval; | 167 | return retval; |
132 | } | 168 | } |
@@ -138,7 +174,8 @@ int prom_getbool(int node, const char *prop) | |||
138 | int retval; | 174 | int retval; |
139 | 175 | ||
140 | retval = prom_getproplen(node, prop); | 176 | retval = prom_getproplen(node, prop); |
141 | if(retval == -1) return 0; | 177 | if (retval == -1) |
178 | return 0; | ||
142 | return 1; | 179 | return 1; |
143 | } | 180 | } |
144 | EXPORT_SYMBOL(prom_getbool); | 181 | EXPORT_SYMBOL(prom_getbool); |
@@ -152,7 +189,8 @@ void prom_getstring(int node, const char *prop, char *user_buf, int ubuf_size) | |||
152 | int len; | 189 | int len; |
153 | 190 | ||
154 | len = prom_getproperty(node, prop, user_buf, ubuf_size); | 191 | len = prom_getproperty(node, prop, user_buf, ubuf_size); |
155 | if(len != -1) return; | 192 | if (len != -1) |
193 | return; | ||
156 | user_buf[0] = 0; | 194 | user_buf[0] = 0; |
157 | } | 195 | } |
158 | EXPORT_SYMBOL(prom_getstring); | 196 | EXPORT_SYMBOL(prom_getstring); |
@@ -164,7 +202,8 @@ int prom_nodematch(int node, const char *name) | |||
164 | { | 202 | { |
165 | char namebuf[128]; | 203 | char namebuf[128]; |
166 | prom_getproperty(node, "name", namebuf, sizeof(namebuf)); | 204 | prom_getproperty(node, "name", namebuf, sizeof(namebuf)); |
167 | if(strcmp(namebuf, name) == 0) return 1; | 205 | if (strcmp(namebuf, name) == 0) |
206 | return 1; | ||
168 | return 0; | 207 | return 0; |
169 | } | 208 | } |
170 | 209 | ||
@@ -190,16 +229,29 @@ int prom_searchsiblings(int node_start, const char *nodename) | |||
190 | } | 229 | } |
191 | EXPORT_SYMBOL(prom_searchsiblings); | 230 | EXPORT_SYMBOL(prom_searchsiblings); |
192 | 231 | ||
232 | static const char *prom_nextprop_name = "nextprop"; | ||
233 | |||
193 | /* Return the first property type for node 'node'. | 234 | /* Return the first property type for node 'node'. |
194 | * buffer should be at least 32B in length | 235 | * buffer should be at least 32B in length |
195 | */ | 236 | */ |
196 | inline char *prom_firstprop(int node, char *buffer) | 237 | inline char *prom_firstprop(int node, char *buffer) |
197 | { | 238 | { |
239 | unsigned long args[7]; | ||
240 | |||
198 | *buffer = 0; | 241 | *buffer = 0; |
199 | if(node == -1) return buffer; | 242 | if (node == -1) |
200 | p1275_cmd ("nextprop", P1275_ARG(2,P1275_ARG_OUT_32B)| | 243 | return buffer; |
201 | P1275_INOUT(3, 0), | 244 | |
202 | node, (char *) 0x0, buffer); | 245 | args[0] = (unsigned long) prom_nextprop_name; |
246 | args[1] = 3; | ||
247 | args[2] = 1; | ||
248 | args[3] = (unsigned int) node; | ||
249 | args[4] = 0; | ||
250 | args[5] = (unsigned long) buffer; | ||
251 | args[6] = (unsigned long) -1; | ||
252 | |||
253 | p1275_cmd_direct(args); | ||
254 | |||
203 | return buffer; | 255 | return buffer; |
204 | } | 256 | } |
205 | EXPORT_SYMBOL(prom_firstprop); | 257 | EXPORT_SYMBOL(prom_firstprop); |
@@ -210,9 +262,10 @@ EXPORT_SYMBOL(prom_firstprop); | |||
210 | */ | 262 | */ |
211 | inline char *prom_nextprop(int node, const char *oprop, char *buffer) | 263 | inline char *prom_nextprop(int node, const char *oprop, char *buffer) |
212 | { | 264 | { |
265 | unsigned long args[7]; | ||
213 | char buf[32]; | 266 | char buf[32]; |
214 | 267 | ||
215 | if(node == -1) { | 268 | if (node == -1) { |
216 | *buffer = 0; | 269 | *buffer = 0; |
217 | return buffer; | 270 | return buffer; |
218 | } | 271 | } |
@@ -220,10 +273,17 @@ inline char *prom_nextprop(int node, const char *oprop, char *buffer) | |||
220 | strcpy (buf, oprop); | 273 | strcpy (buf, oprop); |
221 | oprop = buf; | 274 | oprop = buf; |
222 | } | 275 | } |
223 | p1275_cmd ("nextprop", P1275_ARG(1,P1275_ARG_IN_STRING)| | 276 | |
224 | P1275_ARG(2,P1275_ARG_OUT_32B)| | 277 | args[0] = (unsigned long) prom_nextprop_name; |
225 | P1275_INOUT(3, 0), | 278 | args[1] = 3; |
226 | node, oprop, buffer); | 279 | args[2] = 1; |
280 | args[3] = (unsigned int) node; | ||
281 | args[4] = (unsigned long) oprop; | ||
282 | args[5] = (unsigned long) buffer; | ||
283 | args[6] = (unsigned long) -1; | ||
284 | |||
285 | p1275_cmd_direct(args); | ||
286 | |||
227 | return buffer; | 287 | return buffer; |
228 | } | 288 | } |
229 | EXPORT_SYMBOL(prom_nextprop); | 289 | EXPORT_SYMBOL(prom_nextprop); |
@@ -231,12 +291,19 @@ EXPORT_SYMBOL(prom_nextprop); | |||
231 | int | 291 | int |
232 | prom_finddevice(const char *name) | 292 | prom_finddevice(const char *name) |
233 | { | 293 | { |
294 | unsigned long args[5]; | ||
295 | |||
234 | if (!name) | 296 | if (!name) |
235 | return 0; | 297 | return 0; |
236 | return p1275_cmd(prom_finddev_name, | 298 | args[0] = (unsigned long) "finddevice"; |
237 | P1275_ARG(0,P1275_ARG_IN_STRING)| | 299 | args[1] = 1; |
238 | P1275_INOUT(1, 1), | 300 | args[2] = 1; |
239 | name); | 301 | args[3] = (unsigned long) name; |
302 | args[4] = (unsigned long) -1; | ||
303 | |||
304 | p1275_cmd_direct(args); | ||
305 | |||
306 | return (int) args[4]; | ||
240 | } | 307 | } |
241 | EXPORT_SYMBOL(prom_finddevice); | 308 | EXPORT_SYMBOL(prom_finddevice); |
242 | 309 | ||
@@ -247,7 +314,7 @@ int prom_node_has_property(int node, const char *prop) | |||
247 | *buf = 0; | 314 | *buf = 0; |
248 | do { | 315 | do { |
249 | prom_nextprop(node, buf, buf); | 316 | prom_nextprop(node, buf, buf); |
250 | if(!strcmp(buf, prop)) | 317 | if (!strcmp(buf, prop)) |
251 | return 1; | 318 | return 1; |
252 | } while (*buf); | 319 | } while (*buf); |
253 | return 0; | 320 | return 0; |
@@ -260,6 +327,8 @@ EXPORT_SYMBOL(prom_node_has_property); | |||
260 | int | 327 | int |
261 | prom_setprop(int node, const char *pname, char *value, int size) | 328 | prom_setprop(int node, const char *pname, char *value, int size) |
262 | { | 329 | { |
330 | unsigned long args[8]; | ||
331 | |||
263 | if (size == 0) | 332 | if (size == 0) |
264 | return 0; | 333 | return 0; |
265 | if ((pname == 0) || (value == 0)) | 334 | if ((pname == 0) || (value == 0)) |
@@ -271,19 +340,37 @@ prom_setprop(int node, const char *pname, char *value, int size) | |||
271 | return 0; | 340 | return 0; |
272 | } | 341 | } |
273 | #endif | 342 | #endif |
274 | return p1275_cmd ("setprop", P1275_ARG(1,P1275_ARG_IN_STRING)| | 343 | args[0] = (unsigned long) "setprop"; |
275 | P1275_ARG(2,P1275_ARG_IN_BUF)| | 344 | args[1] = 4; |
276 | P1275_INOUT(4, 1), | 345 | args[2] = 1; |
277 | node, pname, value, P1275_SIZE(size)); | 346 | args[3] = (unsigned int) node; |
347 | args[4] = (unsigned long) pname; | ||
348 | args[5] = (unsigned long) value; | ||
349 | args[6] = size; | ||
350 | args[7] = (unsigned long) -1; | ||
351 | |||
352 | p1275_cmd_direct(args); | ||
353 | |||
354 | return (int) args[7]; | ||
278 | } | 355 | } |
279 | EXPORT_SYMBOL(prom_setprop); | 356 | EXPORT_SYMBOL(prom_setprop); |
280 | 357 | ||
281 | inline int prom_inst2pkg(int inst) | 358 | inline int prom_inst2pkg(int inst) |
282 | { | 359 | { |
360 | unsigned long args[5]; | ||
283 | int node; | 361 | int node; |
284 | 362 | ||
285 | node = p1275_cmd ("instance-to-package", P1275_INOUT(1, 1), inst); | 363 | args[0] = (unsigned long) "instance-to-package"; |
286 | if (node == -1) return 0; | 364 | args[1] = 1; |
365 | args[2] = 1; | ||
366 | args[3] = (unsigned int) inst; | ||
367 | args[4] = (unsigned long) -1; | ||
368 | |||
369 | p1275_cmd_direct(args); | ||
370 | |||
371 | node = (int) args[4]; | ||
372 | if (node == -1) | ||
373 | return 0; | ||
287 | return node; | 374 | return node; |
288 | } | 375 | } |
289 | 376 | ||
@@ -296,17 +383,28 @@ prom_pathtoinode(const char *path) | |||
296 | int node, inst; | 383 | int node, inst; |
297 | 384 | ||
298 | inst = prom_devopen (path); | 385 | inst = prom_devopen (path); |
299 | if (inst == 0) return 0; | 386 | if (inst == 0) |
300 | node = prom_inst2pkg (inst); | 387 | return 0; |
301 | prom_devclose (inst); | 388 | node = prom_inst2pkg(inst); |
302 | if (node == -1) return 0; | 389 | prom_devclose(inst); |
390 | if (node == -1) | ||
391 | return 0; | ||
303 | return node; | 392 | return node; |
304 | } | 393 | } |
305 | 394 | ||
306 | int prom_ihandle2path(int handle, char *buffer, int bufsize) | 395 | int prom_ihandle2path(int handle, char *buffer, int bufsize) |
307 | { | 396 | { |
308 | return p1275_cmd("instance-to-path", | 397 | unsigned long args[7]; |
309 | P1275_ARG(1,P1275_ARG_OUT_BUF)| | 398 | |
310 | P1275_INOUT(3, 1), | 399 | args[0] = (unsigned long) "instance-to-path"; |
311 | handle, buffer, P1275_SIZE(bufsize)); | 400 | args[1] = 3; |
401 | args[2] = 1; | ||
402 | args[3] = (unsigned int) handle; | ||
403 | args[4] = (unsigned long) buffer; | ||
404 | args[5] = bufsize; | ||
405 | args[6] = (unsigned long) -1; | ||
406 | |||
407 | p1275_cmd_direct(args); | ||
408 | |||
409 | return (int) args[6]; | ||
312 | } | 410 | } |