aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/configs/ps3_defconfig49
-rw-r--r--arch/powerpc/kernel/crash.c101
-rw-r--r--arch/powerpc/kernel/dma_64.c19
-rw-r--r--arch/powerpc/kernel/ibmebus.c7
-rw-r--r--arch/powerpc/kernel/misc.S65
-rw-r--r--arch/powerpc/kernel/pci_64.c11
-rw-r--r--arch/powerpc/kernel/ppc_ksyms.c1
-rw-r--r--arch/powerpc/kernel/smp.c49
-rw-r--r--arch/powerpc/kernel/systbl_chk.c2
-rw-r--r--arch/powerpc/kernel/systbl_chk.sh2
-rw-r--r--arch/powerpc/mm/fault.c6
-rw-r--r--arch/powerpc/platforms/cell/iommu.c23
-rw-r--r--arch/powerpc/platforms/celleb/iommu.c18
-rw-r--r--arch/powerpc/platforms/chrp/pci.c4
-rw-r--r--arch/powerpc/platforms/chrp/setup.c52
-rw-r--r--arch/powerpc/platforms/ps3/Kconfig24
-rw-r--r--arch/powerpc/platforms/ps3/device-init.c531
-rw-r--r--arch/powerpc/platforms/ps3/mm.c24
-rw-r--r--arch/powerpc/platforms/ps3/platform.h34
-rw-r--r--arch/powerpc/platforms/ps3/repository.c320
-rw-r--r--arch/powerpc/platforms/ps3/system-bus.c19
-rw-r--r--arch/powerpc/xmon/setjmp.S61
-rw-r--r--arch/powerpc/xmon/xmon.c6
23 files changed, 929 insertions, 499 deletions
diff --git a/arch/powerpc/configs/ps3_defconfig b/arch/powerpc/configs/ps3_defconfig
index 0b5469fb6e0f..7994955c29d3 100644
--- a/arch/powerpc/configs/ps3_defconfig
+++ b/arch/powerpc/configs/ps3_defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.24-rc4 3# Linux kernel version: 2.6.24-rc8
4# Tue Dec 4 22:49:57 2007 4# Wed Jan 16 14:31:21 2008
5# 5#
6CONFIG_PPC64=y 6CONFIG_PPC64=y
7 7
@@ -103,6 +103,7 @@ CONFIG_VM_EVENT_COUNTERS=y
103CONFIG_SLAB=y 103CONFIG_SLAB=y
104# CONFIG_SLUB is not set 104# CONFIG_SLUB is not set
105# CONFIG_SLOB is not set 105# CONFIG_SLOB is not set
106CONFIG_SLABINFO=y
106CONFIG_RT_MUTEXES=y 107CONFIG_RT_MUTEXES=y
107# CONFIG_TINY_SHMEM is not set 108# CONFIG_TINY_SHMEM is not set
108CONFIG_BASE_SMALL=0 109CONFIG_BASE_SMALL=0
@@ -154,7 +155,6 @@ CONFIG_PPC_PS3=y
154# CONFIG_PS3_ADVANCED is not set 155# CONFIG_PS3_ADVANCED is not set
155CONFIG_PS3_HTAB_SIZE=20 156CONFIG_PS3_HTAB_SIZE=20
156# CONFIG_PS3_DYNAMIC_DMA is not set 157# CONFIG_PS3_DYNAMIC_DMA is not set
157CONFIG_PS3_USE_LPAR_ADDR=y
158CONFIG_PS3_VUART=y 158CONFIG_PS3_VUART=y
159CONFIG_PS3_PS3AV=y 159CONFIG_PS3_PS3AV=y
160CONFIG_PS3_SYS_MANAGER=y 160CONFIG_PS3_SYS_MANAGER=y
@@ -162,6 +162,7 @@ CONFIG_PS3_STORAGE=y
162CONFIG_PS3_DISK=y 162CONFIG_PS3_DISK=y
163CONFIG_PS3_ROM=y 163CONFIG_PS3_ROM=y
164CONFIG_PS3_FLASH=y 164CONFIG_PS3_FLASH=y
165CONFIG_PS3_LPM=m
165CONFIG_PPC_CELL=y 166CONFIG_PPC_CELL=y
166# CONFIG_PPC_CELL_NATIVE is not set 167# CONFIG_PPC_CELL_NATIVE is not set
167# CONFIG_PPC_IBM_CELL_BLADE is not set 168# CONFIG_PPC_IBM_CELL_BLADE is not set
@@ -225,7 +226,7 @@ CONFIG_HAVE_MEMORY_PRESENT=y
225# CONFIG_SPARSEMEM_STATIC is not set 226# CONFIG_SPARSEMEM_STATIC is not set
226CONFIG_SPARSEMEM_EXTREME=y 227CONFIG_SPARSEMEM_EXTREME=y
227CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y 228CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
228CONFIG_SPARSEMEM_VMEMMAP=y 229# CONFIG_SPARSEMEM_VMEMMAP is not set
229CONFIG_MEMORY_HOTPLUG=y 230CONFIG_MEMORY_HOTPLUG=y
230CONFIG_MEMORY_HOTPLUG_SPARSE=y 231CONFIG_MEMORY_HOTPLUG_SPARSE=y
231CONFIG_SPLIT_PTLOCK_CPUS=4 232CONFIG_SPLIT_PTLOCK_CPUS=4
@@ -338,7 +339,26 @@ CONFIG_IPV6_SIT=y
338# CONFIG_NET_PKTGEN is not set 339# CONFIG_NET_PKTGEN is not set
339# CONFIG_HAMRADIO is not set 340# CONFIG_HAMRADIO is not set
340# CONFIG_IRDA is not set 341# CONFIG_IRDA is not set
341# CONFIG_BT is not set 342CONFIG_BT=m
343CONFIG_BT_L2CAP=m
344CONFIG_BT_SCO=m
345CONFIG_BT_RFCOMM=m
346CONFIG_BT_RFCOMM_TTY=y
347CONFIG_BT_BNEP=m
348CONFIG_BT_BNEP_MC_FILTER=y
349CONFIG_BT_BNEP_PROTO_FILTER=y
350CONFIG_BT_HIDP=m
351
352#
353# Bluetooth device drivers
354#
355CONFIG_BT_HCIUSB=m
356CONFIG_BT_HCIUSB_SCO=y
357# CONFIG_BT_HCIUART is not set
358# CONFIG_BT_HCIBCM203X is not set
359# CONFIG_BT_HCIBPA10X is not set
360# CONFIG_BT_HCIBFUSB is not set
361# CONFIG_BT_HCIVHCI is not set
342# CONFIG_AF_RXRPC is not set 362# CONFIG_AF_RXRPC is not set
343 363
344# 364#
@@ -666,14 +686,14 @@ CONFIG_LOGO_LINUX_CLUT224=y
666# 686#
667# Sound 687# Sound
668# 688#
669CONFIG_SOUND=y 689CONFIG_SOUND=m
670 690
671# 691#
672# Advanced Linux Sound Architecture 692# Advanced Linux Sound Architecture
673# 693#
674CONFIG_SND=y 694CONFIG_SND=m
675CONFIG_SND_TIMER=y 695CONFIG_SND_TIMER=m
676CONFIG_SND_PCM=y 696CONFIG_SND_PCM=m
677# CONFIG_SND_SEQUENCER is not set 697# CONFIG_SND_SEQUENCER is not set
678# CONFIG_SND_MIXER_OSS is not set 698# CONFIG_SND_MIXER_OSS is not set
679# CONFIG_SND_PCM_OSS is not set 699# CONFIG_SND_PCM_OSS is not set
@@ -702,7 +722,7 @@ CONFIG_SND_VERBOSE_PROCFS=y
702# 722#
703# ALSA PowerPC devices 723# ALSA PowerPC devices
704# 724#
705CONFIG_SND_PS3=y 725CONFIG_SND_PS3=m
706CONFIG_SND_PS3_DEFAULT_START_DELAY=2000 726CONFIG_SND_PS3_DEFAULT_START_DELAY=2000
707 727
708# 728#
@@ -747,7 +767,7 @@ CONFIG_USB_SUPPORT=y
747CONFIG_USB_ARCH_HAS_HCD=y 767CONFIG_USB_ARCH_HAS_HCD=y
748CONFIG_USB_ARCH_HAS_OHCI=y 768CONFIG_USB_ARCH_HAS_OHCI=y
749CONFIG_USB_ARCH_HAS_EHCI=y 769CONFIG_USB_ARCH_HAS_EHCI=y
750CONFIG_USB=y 770CONFIG_USB=m
751# CONFIG_USB_DEBUG is not set 771# CONFIG_USB_DEBUG is not set
752 772
753# 773#
@@ -761,13 +781,13 @@ CONFIG_USB_DEVICEFS=y
761# 781#
762# USB Host Controller Drivers 782# USB Host Controller Drivers
763# 783#
764CONFIG_USB_EHCI_HCD=y 784CONFIG_USB_EHCI_HCD=m
765# CONFIG_USB_EHCI_SPLIT_ISO is not set 785# CONFIG_USB_EHCI_SPLIT_ISO is not set
766# CONFIG_USB_EHCI_ROOT_HUB_TT is not set 786# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
767# CONFIG_USB_EHCI_TT_NEWSCHED is not set 787# CONFIG_USB_EHCI_TT_NEWSCHED is not set
768CONFIG_USB_EHCI_BIG_ENDIAN_MMIO=y 788CONFIG_USB_EHCI_BIG_ENDIAN_MMIO=y
769# CONFIG_USB_ISP116X_HCD is not set 789# CONFIG_USB_ISP116X_HCD is not set
770CONFIG_USB_OHCI_HCD=y 790CONFIG_USB_OHCI_HCD=m
771# CONFIG_USB_OHCI_HCD_PPC_OF is not set 791# CONFIG_USB_OHCI_HCD_PPC_OF is not set
772# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set 792# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
773CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y 793CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y
@@ -1033,7 +1053,8 @@ CONFIG_HAS_IOMEM=y
1033CONFIG_HAS_IOPORT=y 1053CONFIG_HAS_IOPORT=y
1034CONFIG_HAS_DMA=y 1054CONFIG_HAS_DMA=y
1035CONFIG_INSTRUMENTATION=y 1055CONFIG_INSTRUMENTATION=y
1036# CONFIG_PROFILING is not set 1056CONFIG_PROFILING=y
1057CONFIG_OPROFILE=m
1037# CONFIG_KPROBES is not set 1058# CONFIG_KPROBES is not set
1038# CONFIG_MARKERS is not set 1059# CONFIG_MARKERS is not set
1039 1060
diff --git a/arch/powerpc/kernel/crash.c b/arch/powerpc/kernel/crash.c
index 77c749a13378..571132ed12c1 100644
--- a/arch/powerpc/kernel/crash.c
+++ b/arch/powerpc/kernel/crash.c
@@ -32,6 +32,8 @@
32#include <asm/lmb.h> 32#include <asm/lmb.h>
33#include <asm/firmware.h> 33#include <asm/firmware.h>
34#include <asm/smp.h> 34#include <asm/smp.h>
35#include <asm/system.h>
36#include <asm/setjmp.h>
35 37
36#ifdef DEBUG 38#ifdef DEBUG
37#include <asm/udbg.h> 39#include <asm/udbg.h>
@@ -45,6 +47,11 @@ int crashing_cpu = -1;
45static cpumask_t cpus_in_crash = CPU_MASK_NONE; 47static cpumask_t cpus_in_crash = CPU_MASK_NONE;
46cpumask_t cpus_in_sr = CPU_MASK_NONE; 48cpumask_t cpus_in_sr = CPU_MASK_NONE;
47 49
50#define CRASH_HANDLER_MAX 1
51/* NULL terminated list of shutdown handles */
52static crash_shutdown_t crash_shutdown_handles[CRASH_HANDLER_MAX+1];
53static DEFINE_SPINLOCK(crash_handlers_lock);
54
48#ifdef CONFIG_SMP 55#ifdef CONFIG_SMP
49static atomic_t enter_on_soft_reset = ATOMIC_INIT(0); 56static atomic_t enter_on_soft_reset = ATOMIC_INIT(0);
50 57
@@ -285,9 +292,72 @@ static inline void crash_kexec_stop_spus(void)
285} 292}
286#endif /* CONFIG_SPU_BASE */ 293#endif /* CONFIG_SPU_BASE */
287 294
295/*
296 * Register a function to be called on shutdown. Only use this if you
297 * can't reset your device in the second kernel.
298 */
299int crash_shutdown_register(crash_shutdown_t handler)
300{
301 unsigned int i, rc;
302
303 spin_lock(&crash_handlers_lock);
304 for (i = 0 ; i < CRASH_HANDLER_MAX; i++)
305 if (!crash_shutdown_handles[i]) {
306 /* Insert handle at first empty entry */
307 crash_shutdown_handles[i] = handler;
308 rc = 0;
309 break;
310 }
311
312 if (i == CRASH_HANDLER_MAX) {
313 printk(KERN_ERR "Crash shutdown handles full, "
314 "not registered.\n");
315 rc = 1;
316 }
317
318 spin_unlock(&crash_handlers_lock);
319 return rc;
320}
321EXPORT_SYMBOL(crash_shutdown_register);
322
323int crash_shutdown_unregister(crash_shutdown_t handler)
324{
325 unsigned int i, rc;
326
327 spin_lock(&crash_handlers_lock);
328 for (i = 0 ; i < CRASH_HANDLER_MAX; i++)
329 if (crash_shutdown_handles[i] == handler)
330 break;
331
332 if (i == CRASH_HANDLER_MAX) {
333 printk(KERN_ERR "Crash shutdown handle not found\n");
334 rc = 1;
335 } else {
336 /* Shift handles down */
337 for (; crash_shutdown_handles[i]; i++)
338 crash_shutdown_handles[i] =
339 crash_shutdown_handles[i+1];
340 rc = 0;
341 }
342
343 spin_unlock(&crash_handlers_lock);
344 return rc;
345}
346EXPORT_SYMBOL(crash_shutdown_unregister);
347
348static unsigned long crash_shutdown_buf[JMP_BUF_LEN];
349
350static int handle_fault(struct pt_regs *regs)
351{
352 longjmp(crash_shutdown_buf, 1);
353 return 0;
354}
355
288void default_machine_crash_shutdown(struct pt_regs *regs) 356void default_machine_crash_shutdown(struct pt_regs *regs)
289{ 357{
290 unsigned int irq; 358 unsigned int i;
359 int (*old_handler)(struct pt_regs *regs);
360
291 361
292 /* 362 /*
293 * This function is only called after the system 363 * This function is only called after the system
@@ -301,15 +371,36 @@ void default_machine_crash_shutdown(struct pt_regs *regs)
301 */ 371 */
302 hard_irq_disable(); 372 hard_irq_disable();
303 373
304 for_each_irq(irq) { 374 for_each_irq(i) {
305 struct irq_desc *desc = irq_desc + irq; 375 struct irq_desc *desc = irq_desc + i;
306 376
307 if (desc->status & IRQ_INPROGRESS) 377 if (desc->status & IRQ_INPROGRESS)
308 desc->chip->eoi(irq); 378 desc->chip->eoi(i);
309 379
310 if (!(desc->status & IRQ_DISABLED)) 380 if (!(desc->status & IRQ_DISABLED))
311 desc->chip->disable(irq); 381 desc->chip->disable(i);
382 }
383
384 /*
385 * Call registered shutdown routines savely. Swap out
386 * __debugger_fault_handler, and replace on exit.
387 */
388 old_handler = __debugger_fault_handler;
389 __debugger_fault_handler = handle_fault;
390 for (i = 0; crash_shutdown_handles[i]; i++) {
391 if (setjmp(crash_shutdown_buf) == 0) {
392 /*
393 * Insert syncs and delay to ensure
394 * instructions in the dangerous region don't
395 * leak away from this protected region.
396 */
397 asm volatile("sync; isync");
398 /* dangerous region */
399 crash_shutdown_handles[i]();
400 asm volatile("sync; isync");
401 }
312 } 402 }
403 __debugger_fault_handler = old_handler;
313 404
314 /* 405 /*
315 * Make a note of crashing cpu. Will be used in machine_kexec 406 * Make a note of crashing cpu. Will be used in machine_kexec
diff --git a/arch/powerpc/kernel/dma_64.c b/arch/powerpc/kernel/dma_64.c
index 14206e3f0819..84239076a5b8 100644
--- a/arch/powerpc/kernel/dma_64.c
+++ b/arch/powerpc/kernel/dma_64.c
@@ -112,10 +112,16 @@ EXPORT_SYMBOL(dma_iommu_ops);
112/* 112/*
113 * Generic direct DMA implementation 113 * Generic direct DMA implementation
114 * 114 *
115 * This implementation supports a global offset that can be applied if 115 * This implementation supports a per-device offset that can be applied if
116 * the address at which memory is visible to devices is not 0. 116 * the address at which memory is visible to devices is not 0. Platform code
117 * can set archdata.dma_data to an unsigned long holding the offset. By
118 * default the offset is zero.
117 */ 119 */
118unsigned long dma_direct_offset; 120
121static unsigned long get_dma_direct_offset(struct device *dev)
122{
123 return (unsigned long)dev->archdata.dma_data;
124}
119 125
120static void *dma_direct_alloc_coherent(struct device *dev, size_t size, 126static void *dma_direct_alloc_coherent(struct device *dev, size_t size,
121 dma_addr_t *dma_handle, gfp_t flag) 127 dma_addr_t *dma_handle, gfp_t flag)
@@ -124,13 +130,12 @@ static void *dma_direct_alloc_coherent(struct device *dev, size_t size,
124 void *ret; 130 void *ret;
125 int node = dev->archdata.numa_node; 131 int node = dev->archdata.numa_node;
126 132
127 /* TODO: Maybe use the numa node here too ? */
128 page = alloc_pages_node(node, flag, get_order(size)); 133 page = alloc_pages_node(node, flag, get_order(size));
129 if (page == NULL) 134 if (page == NULL)
130 return NULL; 135 return NULL;
131 ret = page_address(page); 136 ret = page_address(page);
132 memset(ret, 0, size); 137 memset(ret, 0, size);
133 *dma_handle = virt_to_abs(ret) | dma_direct_offset; 138 *dma_handle = virt_to_abs(ret) + get_dma_direct_offset(dev);
134 139
135 return ret; 140 return ret;
136} 141}
@@ -145,7 +150,7 @@ static dma_addr_t dma_direct_map_single(struct device *dev, void *ptr,
145 size_t size, 150 size_t size,
146 enum dma_data_direction direction) 151 enum dma_data_direction direction)
147{ 152{
148 return virt_to_abs(ptr) | dma_direct_offset; 153 return virt_to_abs(ptr) + get_dma_direct_offset(dev);
149} 154}
150 155
151static void dma_direct_unmap_single(struct device *dev, dma_addr_t dma_addr, 156static void dma_direct_unmap_single(struct device *dev, dma_addr_t dma_addr,
@@ -161,7 +166,7 @@ static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl,
161 int i; 166 int i;
162 167
163 for_each_sg(sgl, sg, nents, i) { 168 for_each_sg(sgl, sg, nents, i) {
164 sg->dma_address = sg_phys(sg) | dma_direct_offset; 169 sg->dma_address = sg_phys(sg) + get_dma_direct_offset(dev);
165 sg->dma_length = sg->length; 170 sg->dma_length = sg->length;
166 } 171 }
167 172
diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c
index fd5ae8d17c96..2f50bb5d00f9 100644
--- a/arch/powerpc/kernel/ibmebus.c
+++ b/arch/powerpc/kernel/ibmebus.c
@@ -198,16 +198,13 @@ int ibmebus_register_driver(struct of_platform_driver *drv)
198 /* If the driver uses devices that ibmebus doesn't know, add them */ 198 /* If the driver uses devices that ibmebus doesn't know, add them */
199 ibmebus_create_devices(drv->match_table); 199 ibmebus_create_devices(drv->match_table);
200 200
201 drv->driver.name = drv->name; 201 return of_register_driver(drv, &ibmebus_bus_type);
202 drv->driver.bus = &ibmebus_bus_type;
203
204 return driver_register(&drv->driver);
205} 202}
206EXPORT_SYMBOL(ibmebus_register_driver); 203EXPORT_SYMBOL(ibmebus_register_driver);
207 204
208void ibmebus_unregister_driver(struct of_platform_driver *drv) 205void ibmebus_unregister_driver(struct of_platform_driver *drv)
209{ 206{
210 driver_unregister(&drv->driver); 207 of_unregister_driver(drv);
211} 208}
212EXPORT_SYMBOL(ibmebus_unregister_driver); 209EXPORT_SYMBOL(ibmebus_unregister_driver);
213 210
diff --git a/arch/powerpc/kernel/misc.S b/arch/powerpc/kernel/misc.S
index 74ce0c7a7b1e..7b9160220698 100644
--- a/arch/powerpc/kernel/misc.S
+++ b/arch/powerpc/kernel/misc.S
@@ -8,6 +8,8 @@
8 * Adapted for iSeries by Mike Corrigan (mikejc@us.ibm.com) 8 * Adapted for iSeries by Mike Corrigan (mikejc@us.ibm.com)
9 * PPC64 updates by Dave Engebretsen (engebret@us.ibm.com) 9 * PPC64 updates by Dave Engebretsen (engebret@us.ibm.com)
10 * 10 *
11 * setjmp/longjmp code by Paul Mackerras.
12 *
11 * This program is free software; you can redistribute it and/or 13 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License 14 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 15 * as published by the Free Software Foundation; either version
@@ -15,6 +17,8 @@
15 */ 17 */
16#include <asm/ppc_asm.h> 18#include <asm/ppc_asm.h>
17#include <asm/unistd.h> 19#include <asm/unistd.h>
20#include <asm/asm-compat.h>
21#include <asm/asm-offsets.h>
18 22
19 .text 23 .text
20 24
@@ -51,3 +55,64 @@ _GLOBAL(kernel_execve)
51 bnslr 55 bnslr
52 neg r3,r3 56 neg r3,r3
53 blr 57 blr
58
59_GLOBAL(setjmp)
60 mflr r0
61 PPC_STL r0,0(r3)
62 PPC_STL r1,SZL(r3)
63 PPC_STL r2,2*SZL(r3)
64 mfcr r0
65 PPC_STL r0,3*SZL(r3)
66 PPC_STL r13,4*SZL(r3)
67 PPC_STL r14,5*SZL(r3)
68 PPC_STL r15,6*SZL(r3)
69 PPC_STL r16,7*SZL(r3)
70 PPC_STL r17,8*SZL(r3)
71 PPC_STL r18,9*SZL(r3)
72 PPC_STL r19,10*SZL(r3)
73 PPC_STL r20,11*SZL(r3)
74 PPC_STL r21,12*SZL(r3)
75 PPC_STL r22,13*SZL(r3)
76 PPC_STL r23,14*SZL(r3)
77 PPC_STL r24,15*SZL(r3)
78 PPC_STL r25,16*SZL(r3)
79 PPC_STL r26,17*SZL(r3)
80 PPC_STL r27,18*SZL(r3)
81 PPC_STL r28,19*SZL(r3)
82 PPC_STL r29,20*SZL(r3)
83 PPC_STL r30,21*SZL(r3)
84 PPC_STL r31,22*SZL(r3)
85 li r3,0
86 blr
87
88_GLOBAL(longjmp)
89 PPC_LCMPI r4,0
90 bne 1f
91 li r4,1
921: PPC_LL r13,4*SZL(r3)
93 PPC_LL r14,5*SZL(r3)
94 PPC_LL r15,6*SZL(r3)
95 PPC_LL r16,7*SZL(r3)
96 PPC_LL r17,8*SZL(r3)
97 PPC_LL r18,9*SZL(r3)
98 PPC_LL r19,10*SZL(r3)
99 PPC_LL r20,11*SZL(r3)
100 PPC_LL r21,12*SZL(r3)
101 PPC_LL r22,13*SZL(r3)
102 PPC_LL r23,14*SZL(r3)
103 PPC_LL r24,15*SZL(r3)
104 PPC_LL r25,16*SZL(r3)
105 PPC_LL r26,17*SZL(r3)
106 PPC_LL r27,18*SZL(r3)
107 PPC_LL r28,19*SZL(r3)
108 PPC_LL r29,20*SZL(r3)
109 PPC_LL r30,21*SZL(r3)
110 PPC_LL r31,22*SZL(r3)
111 PPC_LL r0,3*SZL(r3)
112 mtcrf 0x38,r0
113 PPC_LL r0,0(r3)
114 PPC_LL r1,SZL(r3)
115 PPC_LL r2,2*SZL(r3)
116 mtlr r0
117 mr r3,r4
118 blr
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index 1930f393d01c..52750745edfd 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -357,7 +357,6 @@ void __devinit scan_phb(struct pci_controller *hose)
357 struct pci_bus *bus; 357 struct pci_bus *bus;
358 struct device_node *node = hose->dn; 358 struct device_node *node = hose->dn;
359 int i, mode; 359 int i, mode;
360 struct resource *res;
361 360
362 DBG("PCI: Scanning PHB %s\n", node ? node->full_name : "<NO NAME>"); 361 DBG("PCI: Scanning PHB %s\n", node ? node->full_name : "<NO NAME>");
363 362
@@ -375,12 +374,10 @@ void __devinit scan_phb(struct pci_controller *hose)
375 pcibios_map_io_space(bus); 374 pcibios_map_io_space(bus);
376 375
377 /* Wire up PHB bus resources */ 376 /* Wire up PHB bus resources */
378 if (hose->io_resource.flags) { 377 DBG("PCI: PHB IO resource = %016lx-%016lx [%lx]\n",
379 DBG("PCI: PHB IO resource = %016lx-%016lx [%lx]\n", 378 hose->io_resource.start, hose->io_resource.end,
380 hose->io_resource.start, hose->io_resource.end, 379 hose->io_resource.flags);
381 hose->io_resource.flags); 380 bus->resource[0] = &hose->io_resource;
382 bus->resource[0] = res = &hose->io_resource;
383 }
384 for (i = 0; i < 3; ++i) { 381 for (i = 0; i < 3; ++i) {
385 DBG("PCI: PHB MEM resource %d = %016lx-%016lx [%lx]\n", i, 382 DBG("PCI: PHB MEM resource %d = %016lx-%016lx [%lx]\n", i,
386 hose->mem_resources[i].start, 383 hose->mem_resources[i].start,
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c
index 13ebeb2d71e6..aa9ff35b0e63 100644
--- a/arch/powerpc/kernel/ppc_ksyms.c
+++ b/arch/powerpc/kernel/ppc_ksyms.c
@@ -59,6 +59,7 @@ extern void single_step_exception(struct pt_regs *regs);
59extern int sys_sigreturn(struct pt_regs *regs); 59extern int sys_sigreturn(struct pt_regs *regs);
60 60
61EXPORT_SYMBOL(clear_pages); 61EXPORT_SYMBOL(clear_pages);
62EXPORT_SYMBOL(copy_page);
62EXPORT_SYMBOL(ISA_DMA_THRESHOLD); 63EXPORT_SYMBOL(ISA_DMA_THRESHOLD);
63EXPORT_SYMBOL(DMA_MODE_READ); 64EXPORT_SYMBOL(DMA_MODE_READ);
64EXPORT_SYMBOL(DMA_MODE_WRITE); 65EXPORT_SYMBOL(DMA_MODE_WRITE);
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index 338950aeb6f6..be35ffae10f0 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -76,6 +76,8 @@ void smp_call_function_interrupt(void);
76 76
77int smt_enabled_at_boot = 1; 77int smt_enabled_at_boot = 1;
78 78
79static int ipi_fail_ok;
80
79static void (*crash_ipi_function_ptr)(struct pt_regs *) = NULL; 81static void (*crash_ipi_function_ptr)(struct pt_regs *) = NULL;
80 82
81#ifdef CONFIG_PPC64 83#ifdef CONFIG_PPC64
@@ -181,12 +183,13 @@ static struct call_data_struct {
181 * <wait> If true, wait (atomically) until function has completed on other CPUs. 183 * <wait> If true, wait (atomically) until function has completed on other CPUs.
182 * [RETURNS] 0 on success, else a negative status code. Does not return until 184 * [RETURNS] 0 on success, else a negative status code. Does not return until
183 * remote CPUs are nearly ready to execute <<func>> or are or have executed. 185 * remote CPUs are nearly ready to execute <<func>> or are or have executed.
186 * <map> is a cpu map of the cpus to send IPI to.
184 * 187 *
185 * You must not call this function with disabled interrupts or from a 188 * You must not call this function with disabled interrupts or from a
186 * hardware interrupt handler or from a bottom half handler. 189 * hardware interrupt handler or from a bottom half handler.
187 */ 190 */
188int smp_call_function_map(void (*func) (void *info), void *info, int nonatomic, 191static int __smp_call_function_map(void (*func) (void *info), void *info,
189 int wait, cpumask_t map) 192 int nonatomic, int wait, cpumask_t map)
190{ 193{
191 struct call_data_struct data; 194 struct call_data_struct data;
192 int ret = -1, num_cpus; 195 int ret = -1, num_cpus;
@@ -203,8 +206,6 @@ int smp_call_function_map(void (*func) (void *info), void *info, int nonatomic,
203 if (wait) 206 if (wait)
204 atomic_set(&data.finished, 0); 207 atomic_set(&data.finished, 0);
205 208
206 spin_lock(&call_lock);
207
208 /* remove 'self' from the map */ 209 /* remove 'self' from the map */
209 if (cpu_isset(smp_processor_id(), map)) 210 if (cpu_isset(smp_processor_id(), map))
210 cpu_clear(smp_processor_id(), map); 211 cpu_clear(smp_processor_id(), map);
@@ -231,7 +232,8 @@ int smp_call_function_map(void (*func) (void *info), void *info, int nonatomic,
231 printk("smp_call_function on cpu %d: other cpus not " 232 printk("smp_call_function on cpu %d: other cpus not "
232 "responding (%d)\n", smp_processor_id(), 233 "responding (%d)\n", smp_processor_id(),
233 atomic_read(&data.started)); 234 atomic_read(&data.started));
234 debugger(NULL); 235 if (!ipi_fail_ok)
236 debugger(NULL);
235 goto out; 237 goto out;
236 } 238 }
237 } 239 }
@@ -258,14 +260,18 @@ int smp_call_function_map(void (*func) (void *info), void *info, int nonatomic,
258 out: 260 out:
259 call_data = NULL; 261 call_data = NULL;
260 HMT_medium(); 262 HMT_medium();
261 spin_unlock(&call_lock);
262 return ret; 263 return ret;
263} 264}
264 265
265static int __smp_call_function(void (*func)(void *info), void *info, 266static int __smp_call_function(void (*func)(void *info), void *info,
266 int nonatomic, int wait) 267 int nonatomic, int wait)
267{ 268{
268 return smp_call_function_map(func,info,nonatomic,wait,cpu_online_map); 269 int ret;
270 spin_lock(&call_lock);
271 ret =__smp_call_function_map(func, info, nonatomic, wait,
272 cpu_online_map);
273 spin_unlock(&call_lock);
274 return ret;
269} 275}
270 276
271int smp_call_function(void (*func) (void *info), void *info, int nonatomic, 277int smp_call_function(void (*func) (void *info), void *info, int nonatomic,
@@ -278,8 +284,8 @@ int smp_call_function(void (*func) (void *info), void *info, int nonatomic,
278} 284}
279EXPORT_SYMBOL(smp_call_function); 285EXPORT_SYMBOL(smp_call_function);
280 286
281int smp_call_function_single(int cpu, void (*func) (void *info), void *info, int nonatomic, 287int smp_call_function_single(int cpu, void (*func) (void *info), void *info,
282 int wait) 288 int nonatomic, int wait)
283{ 289{
284 cpumask_t map = CPU_MASK_NONE; 290 cpumask_t map = CPU_MASK_NONE;
285 int ret = 0; 291 int ret = 0;
@@ -291,9 +297,11 @@ int smp_call_function_single(int cpu, void (*func) (void *info), void *info, int
291 return -EINVAL; 297 return -EINVAL;
292 298
293 cpu_set(cpu, map); 299 cpu_set(cpu, map);
294 if (cpu != get_cpu()) 300 if (cpu != get_cpu()) {
295 ret = smp_call_function_map(func,info,nonatomic,wait,map); 301 spin_lock(&call_lock);
296 else { 302 ret = __smp_call_function_map(func, info, nonatomic, wait, map);
303 spin_unlock(&call_lock);
304 } else {
297 local_irq_disable(); 305 local_irq_disable();
298 func(info); 306 func(info);
299 local_irq_enable(); 307 local_irq_enable();
@@ -305,7 +313,22 @@ EXPORT_SYMBOL(smp_call_function_single);
305 313
306void smp_send_stop(void) 314void smp_send_stop(void)
307{ 315{
308 __smp_call_function(stop_this_cpu, NULL, 1, 0); 316 int nolock;
317
318 /* It's OK to fail sending the IPI, since the alternative is to
319 * be stuck forever waiting on the other CPU to take the interrupt.
320 *
321 * It's better to at least continue and go through reboot, since this
322 * function is usually called at panic or reboot time in the first
323 * place.
324 */
325 ipi_fail_ok = 1;
326
327 /* Don't deadlock in case we got called through panic */
328 nolock = !spin_trylock(&call_lock);
329 __smp_call_function_map(stop_this_cpu, NULL, 1, 0, cpu_online_map);
330 if (!nolock)
331 spin_unlock(&call_lock);
309} 332}
310 333
311void smp_call_function_interrupt(void) 334void smp_call_function_interrupt(void)
diff --git a/arch/powerpc/kernel/systbl_chk.c b/arch/powerpc/kernel/systbl_chk.c
index 77824d1cb150..238aa63ced8f 100644
--- a/arch/powerpc/kernel/systbl_chk.c
+++ b/arch/powerpc/kernel/systbl_chk.c
@@ -6,7 +6,7 @@
6 * Unfortunately, we cannot check for the correct ordering of entries 6 * Unfortunately, we cannot check for the correct ordering of entries
7 * using SYSX(). 7 * using SYSX().
8 * 8 *
9 * Copyright © IBM Corporation 9 * Copyright © IBM Corporation
10 * 10 *
11 * This program is free software; you can redistribute it and/or 11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License 12 * modify it under the terms of the GNU General Public License
diff --git a/arch/powerpc/kernel/systbl_chk.sh b/arch/powerpc/kernel/systbl_chk.sh
index 367d208301d2..19415e7674a5 100644
--- a/arch/powerpc/kernel/systbl_chk.sh
+++ b/arch/powerpc/kernel/systbl_chk.sh
@@ -3,7 +3,7 @@
3# Just process the CPP output from systbl_chk.c and complain 3# Just process the CPP output from systbl_chk.c and complain
4# if anything is out of order. 4# if anything is out of order.
5# 5#
6# Copyright © 2008 IBM Corporation 6# Copyright © 2008 IBM Corporation
7# 7#
8# This program is free software; you can redistribute it and/or 8# This program is free software; you can redistribute it and/or
9# modify it under the terms of the GNU General Public License 9# modify it under the terms of the GNU General Public License
diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c
index 10dda224a361..7b2510799266 100644
--- a/arch/powerpc/mm/fault.c
+++ b/arch/powerpc/mm/fault.c
@@ -167,10 +167,8 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address,
167 if (notify_page_fault(regs)) 167 if (notify_page_fault(regs))
168 return 0; 168 return 0;
169 169
170 if (trap == 0x300) { 170 if (unlikely(debugger_fault_handler(regs)))
171 if (debugger_fault_handler(regs)) 171 return 0;
172 return 0;
173 }
174 172
175 /* On a kernel SLB miss we can only check for a valid exception entry */ 173 /* On a kernel SLB miss we can only check for a valid exception entry */
176 if (!user_mode(regs) && (address >= TASK_SIZE)) 174 if (!user_mode(regs) && (address >= TASK_SIZE))
diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c
index bceb5e13da5c..eb2a94b0dc4c 100644
--- a/arch/powerpc/platforms/cell/iommu.c
+++ b/arch/powerpc/platforms/cell/iommu.c
@@ -310,8 +310,8 @@ static void cell_iommu_setup_hardware(struct cbe_iommu *iommu, unsigned long siz
310{ 310{
311 struct page *page; 311 struct page *page;
312 int ret, i; 312 int ret, i;
313 unsigned long reg, segments, pages_per_segment, ptab_size, n_pte_pages; 313 unsigned long reg, segments, pages_per_segment, ptab_size, stab_size,
314 unsigned long xlate_base; 314 n_pte_pages, xlate_base;
315 unsigned int virq; 315 unsigned int virq;
316 316
317 if (cell_iommu_find_ioc(iommu->nid, &xlate_base)) 317 if (cell_iommu_find_ioc(iommu->nid, &xlate_base))
@@ -328,7 +328,8 @@ static void cell_iommu_setup_hardware(struct cbe_iommu *iommu, unsigned long siz
328 __FUNCTION__, iommu->nid, segments, pages_per_segment); 328 __FUNCTION__, iommu->nid, segments, pages_per_segment);
329 329
330 /* set up the segment table */ 330 /* set up the segment table */
331 page = alloc_pages_node(iommu->nid, GFP_KERNEL, 0); 331 stab_size = segments * sizeof(unsigned long);
332 page = alloc_pages_node(iommu->nid, GFP_KERNEL, get_order(stab_size));
332 BUG_ON(!page); 333 BUG_ON(!page);
333 iommu->stab = page_address(page); 334 iommu->stab = page_address(page);
334 clear_page(iommu->stab); 335 clear_page(iommu->stab);
@@ -490,15 +491,18 @@ static struct cbe_iommu *cell_iommu_for_node(int nid)
490 return NULL; 491 return NULL;
491} 492}
492 493
494static unsigned long cell_dma_direct_offset;
495
493static void cell_dma_dev_setup(struct device *dev) 496static void cell_dma_dev_setup(struct device *dev)
494{ 497{
495 struct iommu_window *window; 498 struct iommu_window *window;
496 struct cbe_iommu *iommu; 499 struct cbe_iommu *iommu;
497 struct dev_archdata *archdata = &dev->archdata; 500 struct dev_archdata *archdata = &dev->archdata;
498 501
499 /* If we run without iommu, no need to do anything */ 502 if (get_pci_dma_ops() == &dma_direct_ops) {
500 if (get_pci_dma_ops() == &dma_direct_ops) 503 archdata->dma_data = (void *)cell_dma_direct_offset;
501 return; 504 return;
505 }
502 506
503 /* Current implementation uses the first window available in that 507 /* Current implementation uses the first window available in that
504 * node's iommu. We -might- do something smarter later though it may 508 * node's iommu. We -might- do something smarter later though it may
@@ -654,7 +658,7 @@ static int __init cell_iommu_init_disabled(void)
654 658
655 /* If we have no Axon, we set up the spider DMA magic offset */ 659 /* If we have no Axon, we set up the spider DMA magic offset */
656 if (of_find_node_by_name(NULL, "axon") == NULL) 660 if (of_find_node_by_name(NULL, "axon") == NULL)
657 dma_direct_offset = SPIDER_DMA_OFFSET; 661 cell_dma_direct_offset = SPIDER_DMA_OFFSET;
658 662
659 /* Now we need to check to see where the memory is mapped 663 /* Now we need to check to see where the memory is mapped
660 * in PCI space. We assume that all busses use the same dma 664 * in PCI space. We assume that all busses use the same dma
@@ -688,10 +692,13 @@ static int __init cell_iommu_init_disabled(void)
688 return -ENODEV; 692 return -ENODEV;
689 } 693 }
690 694
691 dma_direct_offset += base; 695 cell_dma_direct_offset += base;
696
697 if (cell_dma_direct_offset != 0)
698 ppc_md.pci_dma_dev_setup = cell_pci_dma_dev_setup;
692 699
693 printk("iommu: disabled, direct DMA offset is 0x%lx\n", 700 printk("iommu: disabled, direct DMA offset is 0x%lx\n",
694 dma_direct_offset); 701 cell_dma_direct_offset);
695 702
696 return 0; 703 return 0;
697} 704}
diff --git a/arch/powerpc/platforms/celleb/iommu.c b/arch/powerpc/platforms/celleb/iommu.c
index 41e1e6f8e059..93b0efddd658 100644
--- a/arch/powerpc/platforms/celleb/iommu.c
+++ b/arch/powerpc/platforms/celleb/iommu.c
@@ -52,6 +52,8 @@ static int __init find_dma_window(u64 *io_space_id, u64 *ioid,
52 return 0; 52 return 0;
53} 53}
54 54
55static unsigned long celleb_dma_direct_offset;
56
55static void __init celleb_init_direct_mapping(void) 57static void __init celleb_init_direct_mapping(void)
56{ 58{
57 u64 lpar_addr, io_addr; 59 u64 lpar_addr, io_addr;
@@ -69,7 +71,18 @@ static void __init celleb_init_direct_mapping(void)
69 ioid, DMA_FLAGS); 71 ioid, DMA_FLAGS);
70 } 72 }
71 73
72 dma_direct_offset = dma_base; 74 celleb_dma_direct_offset = dma_base;
75}
76
77static void celleb_dma_dev_setup(struct device *dev)
78{
79 dev->archdata.dma_ops = get_pci_dma_ops();
80 dev->archdata.dma_data = (void *)celleb_dma_direct_offset;
81}
82
83static void celleb_pci_dma_dev_setup(struct pci_dev *pdev)
84{
85 celleb_dma_dev_setup(&pdev->dev);
73} 86}
74 87
75static int celleb_of_bus_notify(struct notifier_block *nb, 88static int celleb_of_bus_notify(struct notifier_block *nb,
@@ -81,7 +94,7 @@ static int celleb_of_bus_notify(struct notifier_block *nb,
81 if (action != BUS_NOTIFY_ADD_DEVICE) 94 if (action != BUS_NOTIFY_ADD_DEVICE)
82 return 0; 95 return 0;
83 96
84 dev->archdata.dma_ops = get_pci_dma_ops(); 97 celleb_dma_dev_setup(dev);
85 98
86 return 0; 99 return 0;
87} 100}
@@ -94,6 +107,7 @@ static int __init celleb_init_iommu(void)
94{ 107{
95 celleb_init_direct_mapping(); 108 celleb_init_direct_mapping();
96 set_pci_dma_ops(&dma_direct_ops); 109 set_pci_dma_ops(&dma_direct_ops);
110 ppc_md.pci_dma_dev_setup = celleb_pci_dma_dev_setup;
97 bus_register_notifier(&of_platform_bus_type, &celleb_of_bus_notifier); 111 bus_register_notifier(&of_platform_bus_type, &celleb_of_bus_notifier);
98 112
99 return 0; 113 return 0;
diff --git a/arch/powerpc/platforms/chrp/pci.c b/arch/powerpc/platforms/chrp/pci.c
index d51f83aeef7f..609c46db4a1b 100644
--- a/arch/powerpc/platforms/chrp/pci.c
+++ b/arch/powerpc/platforms/chrp/pci.c
@@ -354,7 +354,7 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105,
354 * mode as well. The same fixup must be done to the class-code property in 354 * mode as well. The same fixup must be done to the class-code property in
355 * the IDE node /pci@80000000/ide@C,1 355 * the IDE node /pci@80000000/ide@C,1
356 */ 356 */
357static void __devinit chrp_pci_fixup_vt8231_ata(struct pci_dev *viaide) 357static void chrp_pci_fixup_vt8231_ata(struct pci_dev *viaide)
358{ 358{
359 u8 progif; 359 u8 progif;
360 struct pci_dev *viaisa; 360 struct pci_dev *viaisa;
@@ -375,4 +375,4 @@ static void __devinit chrp_pci_fixup_vt8231_ata(struct pci_dev *viaide)
375 375
376 pci_dev_put(viaisa); 376 pci_dev_put(viaisa);
377} 377}
378DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, chrp_pci_fixup_vt8231_ata); 378DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, chrp_pci_fixup_vt8231_ata);
diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c
index 42a21bab76c8..116babbaaf81 100644
--- a/arch/powerpc/platforms/chrp/setup.c
+++ b/arch/powerpc/platforms/chrp/setup.c
@@ -256,6 +256,57 @@ static void briq_restart(char *cmd)
256 for(;;); 256 for(;;);
257} 257}
258 258
259/*
260 * Per default, input/output-device points to the keyboard/screen
261 * If no card is installed, the built-in serial port is used as a fallback.
262 * But unfortunately, the firmware does not connect /chosen/{stdin,stdout}
263 * the the built-in serial node. Instead, a /failsafe node is created.
264 */
265static void chrp_init_early(void)
266{
267 struct device_node *node;
268 const char *property;
269
270 if (strstr(cmd_line, "console="))
271 return;
272 /* find the boot console from /chosen/stdout */
273 if (!of_chosen)
274 return;
275 node = of_find_node_by_path("/");
276 if (!node)
277 return;
278 property = of_get_property(node, "model", NULL);
279 if (!property)
280 goto out_put;
281 if (strcmp(property, "Pegasos2"))
282 goto out_put;
283 /* this is a Pegasos2 */
284 property = of_get_property(of_chosen, "linux,stdout-path", NULL);
285 if (!property)
286 goto out_put;
287 of_node_put(node);
288 node = of_find_node_by_path(property);
289 if (!node)
290 return;
291 property = of_get_property(node, "device_type", NULL);
292 if (!property)
293 goto out_put;
294 if (strcmp(property, "serial"))
295 goto out_put;
296 /*
297 * The 9pin connector is either /failsafe
298 * or /pci@80000000/isa@C/serial@i2F8
299 * The optional graphics card has also type 'serial' in VGA mode.
300 */
301 property = of_get_property(node, "name", NULL);
302 if (!property)
303 goto out_put;
304 if (!strcmp(property, "failsafe") || !strcmp(property, "serial"))
305 add_preferred_console("ttyS", 0, NULL);
306out_put:
307 of_node_put(node);
308}
309
259void __init chrp_setup_arch(void) 310void __init chrp_setup_arch(void)
260{ 311{
261 struct device_node *root = of_find_node_by_path("/"); 312 struct device_node *root = of_find_node_by_path("/");
@@ -599,6 +650,7 @@ define_machine(chrp) {
599 .probe = chrp_probe, 650 .probe = chrp_probe,
600 .setup_arch = chrp_setup_arch, 651 .setup_arch = chrp_setup_arch,
601 .init = chrp_init2, 652 .init = chrp_init2,
653 .init_early = chrp_init_early,
602 .show_cpuinfo = chrp_show_cpuinfo, 654 .show_cpuinfo = chrp_show_cpuinfo,
603 .init_IRQ = chrp_init_IRQ, 655 .init_IRQ = chrp_init_IRQ,
604 .restart = rtas_restart, 656 .restart = rtas_restart,
diff --git a/arch/powerpc/platforms/ps3/Kconfig b/arch/powerpc/platforms/ps3/Kconfig
index 298f1c9679fb..a5f4e95dfc3d 100644
--- a/arch/powerpc/platforms/ps3/Kconfig
+++ b/arch/powerpc/platforms/ps3/Kconfig
@@ -61,17 +61,6 @@ config PS3_DYNAMIC_DMA
61 This support is mainly for Linux kernel development. If unsure, 61 This support is mainly for Linux kernel development. If unsure,
62 say N. 62 say N.
63 63
64config PS3_USE_LPAR_ADDR
65 depends on PPC_PS3 && EXPERIMENTAL
66 bool "PS3 use lpar address space"
67 default y
68 help
69 This option is solely for experimentation by experts. Disables
70 translation of lpar addresses. SPE support currently won't work
71 without this set to y.
72
73 If you have any doubt, choose the default y.
74
75config PS3_VUART 64config PS3_VUART
76 depends on PPC_PS3 65 depends on PPC_PS3
77 tristate 66 tristate
@@ -138,4 +127,17 @@ config PS3_FLASH
138 be disabled on the kernel command line using "ps3flash=off", to 127 be disabled on the kernel command line using "ps3flash=off", to
139 not allocate this fixed buffer. 128 not allocate this fixed buffer.
140 129
130config PS3_LPM
131 tristate "PS3 Logical Performance Monitor support"
132 depends on PPC_PS3
133 help
134 Include support for the PS3 Logical Performance Monitor.
135
136 This support is required to use the logical performance monitor
137 of the PS3's LV1 hypervisor.
138
139 If you intend to use the advanced performance monitoring and
140 profiling support of the Cell processor with programs like
141 oprofile and perfmon2, then say Y or M, otherwise say N.
142
141endmenu 143endmenu
diff --git a/arch/powerpc/platforms/ps3/device-init.c b/arch/powerpc/platforms/ps3/device-init.c
index fd063fe0c9b3..9d251d0ca8c6 100644
--- a/arch/powerpc/platforms/ps3/device-init.c
+++ b/arch/powerpc/platforms/ps3/device-init.c
@@ -23,6 +23,7 @@
23#include <linux/kernel.h> 23#include <linux/kernel.h>
24#include <linux/kthread.h> 24#include <linux/kthread.h>
25#include <linux/init.h> 25#include <linux/init.h>
26#include <linux/reboot.h>
26 27
27#include <asm/firmware.h> 28#include <asm/firmware.h>
28#include <asm/lv1call.h> 29#include <asm/lv1call.h>
@@ -30,6 +31,89 @@
30 31
31#include "platform.h" 32#include "platform.h"
32 33
34static int __init ps3_register_lpm_devices(void)
35{
36 int result;
37 u64 tmp1;
38 u64 tmp2;
39 struct ps3_system_bus_device *dev;
40
41 pr_debug(" -> %s:%d\n", __func__, __LINE__);
42
43 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
44 if (!dev)
45 return -ENOMEM;
46
47 dev->match_id = PS3_MATCH_ID_LPM;
48 dev->dev_type = PS3_DEVICE_TYPE_LPM;
49
50 /* The current lpm driver only supports a single BE processor. */
51
52 result = ps3_repository_read_be_node_id(0, &dev->lpm.node_id);
53
54 if (result) {
55 pr_debug("%s:%d: ps3_repository_read_be_node_id failed \n",
56 __func__, __LINE__);
57 goto fail_read_repo;
58 }
59
60 result = ps3_repository_read_lpm_privileges(dev->lpm.node_id, &tmp1,
61 &dev->lpm.rights);
62
63 if (result) {
64 pr_debug("%s:%d: ps3_repository_read_lpm_privleges failed \n",
65 __func__, __LINE__);
66 goto fail_read_repo;
67 }
68
69 lv1_get_logical_partition_id(&tmp2);
70
71 if (tmp1 != tmp2) {
72 pr_debug("%s:%d: wrong lpar\n",
73 __func__, __LINE__);
74 result = -ENODEV;
75 goto fail_rights;
76 }
77
78 if (!(dev->lpm.rights & PS3_LPM_RIGHTS_USE_LPM)) {
79 pr_debug("%s:%d: don't have rights to use lpm\n",
80 __func__, __LINE__);
81 result = -EPERM;
82 goto fail_rights;
83 }
84
85 pr_debug("%s:%d: pu_id %lu, rights %lu(%lxh)\n",
86 __func__, __LINE__, dev->lpm.pu_id, dev->lpm.rights,
87 dev->lpm.rights);
88
89 result = ps3_repository_read_pu_id(0, &dev->lpm.pu_id);
90
91 if (result) {
92 pr_debug("%s:%d: ps3_repository_read_pu_id failed \n",
93 __func__, __LINE__);
94 goto fail_read_repo;
95 }
96
97 result = ps3_system_bus_device_register(dev);
98
99 if (result) {
100 pr_debug("%s:%d ps3_system_bus_device_register failed\n",
101 __func__, __LINE__);
102 goto fail_register;
103 }
104
105 pr_debug(" <- %s:%d\n", __func__, __LINE__);
106 return 0;
107
108
109fail_register:
110fail_rights:
111fail_read_repo:
112 kfree(dev);
113 pr_debug(" <- %s:%d: failed\n", __func__, __LINE__);
114 return result;
115}
116
33/** 117/**
34 * ps3_setup_gelic_device - Setup and register a gelic device instance. 118 * ps3_setup_gelic_device - Setup and register a gelic device instance.
35 * 119 *
@@ -238,166 +322,6 @@ static int __init ps3_setup_vuart_device(enum ps3_match_id match_id,
238 return result; 322 return result;
239} 323}
240 324
241static int ps3stor_wait_for_completion(u64 dev_id, u64 tag,
242 unsigned int timeout)
243{
244 int result = -1;
245 unsigned int retries = 0;
246 u64 status;
247
248 for (retries = 0; retries < timeout; retries++) {
249 result = lv1_storage_check_async_status(dev_id, tag, &status);
250 if (!result)
251 break;
252
253 msleep(1);
254 }
255
256 if (result)
257 pr_debug("%s:%u: check_async_status: %s, status %lx\n",
258 __func__, __LINE__, ps3_result(result), status);
259
260 return result;
261}
262
263/**
264 * ps3_storage_wait_for_device - Wait for a storage device to become ready.
265 * @repo: The repository device to wait for.
266 *
267 * Uses the hypervisor's storage device notification mechanism to wait until
268 * a storage device is ready. The device notification mechanism uses a
269 * psuedo device (id = -1) to asynchronously notify the guest when storage
270 * devices become ready. The notification device has a block size of 512
271 * bytes.
272 */
273
274static int ps3_storage_wait_for_device(const struct ps3_repository_device *repo)
275{
276 int error = -ENODEV;
277 int result;
278 const u64 notification_dev_id = (u64)-1LL;
279 const unsigned int timeout = HZ;
280 u64 lpar;
281 u64 tag;
282 void *buf;
283 enum ps3_notify_type {
284 notify_device_ready = 0,
285 notify_region_probe = 1,
286 notify_region_update = 2,
287 };
288 struct {
289 u64 operation_code; /* must be zero */
290 u64 event_mask; /* OR of 1UL << enum ps3_notify_type */
291 } *notify_cmd;
292 struct {
293 u64 event_type; /* enum ps3_notify_type */
294 u64 bus_id;
295 u64 dev_id;
296 u64 dev_type;
297 u64 dev_port;
298 } *notify_event;
299
300 pr_debug(" -> %s:%u: (%u:%u:%u)\n", __func__, __LINE__, repo->bus_id,
301 repo->dev_id, repo->dev_type);
302
303 buf = kzalloc(512, GFP_KERNEL);
304 if (!buf)
305 return -ENOMEM;
306
307 lpar = ps3_mm_phys_to_lpar(__pa(buf));
308 notify_cmd = buf;
309 notify_event = buf;
310
311 result = lv1_open_device(repo->bus_id, notification_dev_id, 0);
312 if (result) {
313 printk(KERN_ERR "%s:%u: lv1_open_device %s\n", __func__,
314 __LINE__, ps3_result(result));
315 goto fail_free;
316 }
317
318 /* Setup and write the request for device notification. */
319
320 notify_cmd->operation_code = 0; /* must be zero */
321 notify_cmd->event_mask = 1UL << notify_region_probe;
322
323 result = lv1_storage_write(notification_dev_id, 0, 0, 1, 0, lpar,
324 &tag);
325 if (result) {
326 printk(KERN_ERR "%s:%u: write failed %s\n", __func__, __LINE__,
327 ps3_result(result));
328 goto fail_close;
329 }
330
331 /* Wait for the write completion */
332
333 result = ps3stor_wait_for_completion(notification_dev_id, tag,
334 timeout);
335 if (result) {
336 printk(KERN_ERR "%s:%u: write not completed %s\n", __func__,
337 __LINE__, ps3_result(result));
338 goto fail_close;
339 }
340
341 /* Loop here processing the requested notification events. */
342
343 while (1) {
344 memset(notify_event, 0, sizeof(*notify_event));
345
346 result = lv1_storage_read(notification_dev_id, 0, 0, 1, 0,
347 lpar, &tag);
348 if (result) {
349 printk(KERN_ERR "%s:%u: write failed %s\n", __func__,
350 __LINE__, ps3_result(result));
351 break;
352 }
353
354 result = ps3stor_wait_for_completion(notification_dev_id, tag,
355 timeout);
356 if (result) {
357 printk(KERN_ERR "%s:%u: read not completed %s\n",
358 __func__, __LINE__, ps3_result(result));
359 break;
360 }
361
362 pr_debug("%s:%d: notify event (%u:%u:%u): event_type 0x%lx, "
363 "port %lu\n", __func__, __LINE__, repo->bus_index,
364 repo->dev_index, repo->dev_type,
365 notify_event->event_type, notify_event->dev_port);
366
367 if (notify_event->event_type != notify_region_probe ||
368 notify_event->bus_id != repo->bus_id) {
369 pr_debug("%s:%u: bad notify_event: event %lu, "
370 "dev_id %lu, dev_type %lu\n",
371 __func__, __LINE__, notify_event->event_type,
372 notify_event->dev_id, notify_event->dev_type);
373 break;
374 }
375
376 if (notify_event->dev_id == repo->dev_id &&
377 notify_event->dev_type == repo->dev_type) {
378 pr_debug("%s:%u: device ready (%u:%u:%u)\n", __func__,
379 __LINE__, repo->bus_index, repo->dev_index,
380 repo->dev_type);
381 error = 0;
382 break;
383 }
384
385 if (notify_event->dev_id == repo->dev_id &&
386 notify_event->dev_type == PS3_DEV_TYPE_NOACCESS) {
387 pr_debug("%s:%u: no access: dev_id %u\n", __func__,
388 __LINE__, repo->dev_id);
389 break;
390 }
391 }
392
393fail_close:
394 lv1_close_device(repo->bus_id, notification_dev_id);
395fail_free:
396 kfree(buf);
397 pr_debug(" <- %s:%u\n", __func__, __LINE__);
398 return error;
399}
400
401static int ps3_setup_storage_dev(const struct ps3_repository_device *repo, 325static int ps3_setup_storage_dev(const struct ps3_repository_device *repo,
402 enum ps3_match_id match_id) 326 enum ps3_match_id match_id)
403{ 327{
@@ -449,16 +373,6 @@ static int ps3_setup_storage_dev(const struct ps3_repository_device *repo,
449 goto fail_find_interrupt; 373 goto fail_find_interrupt;
450 } 374 }
451 375
452 /* FIXME: Arrange to only do this on a 'cold' boot */
453
454 result = ps3_storage_wait_for_device(repo);
455 if (result) {
456 printk(KERN_ERR "%s:%u: storage_notification failed %d\n",
457 __func__, __LINE__, result);
458 result = -ENODEV;
459 goto fail_probe_notification;
460 }
461
462 for (i = 0; i < num_regions; i++) { 376 for (i = 0; i < num_regions; i++) {
463 unsigned int id; 377 unsigned int id;
464 u64 start, size; 378 u64 start, size;
@@ -494,7 +408,6 @@ static int ps3_setup_storage_dev(const struct ps3_repository_device *repo,
494 408
495fail_device_register: 409fail_device_register:
496fail_read_region: 410fail_read_region:
497fail_probe_notification:
498fail_find_interrupt: 411fail_find_interrupt:
499 kfree(p); 412 kfree(p);
500fail_malloc: 413fail_malloc:
@@ -659,62 +572,268 @@ static int ps3_register_repository_device(
659 return result; 572 return result;
660} 573}
661 574
575static void ps3_find_and_add_device(u64 bus_id, u64 dev_id)
576{
577 struct ps3_repository_device repo;
578 int res;
579 unsigned int retries;
580 unsigned long rem;
581
582 /*
583 * On some firmware versions (e.g. 1.90), the device may not show up
584 * in the repository immediately
585 */
586 for (retries = 0; retries < 10; retries++) {
587 res = ps3_repository_find_device_by_id(&repo, bus_id, dev_id);
588 if (!res)
589 goto found;
590
591 rem = msleep_interruptible(100);
592 if (rem)
593 break;
594 }
595 pr_warning("%s:%u: device %lu:%lu not found\n", __func__, __LINE__,
596 bus_id, dev_id);
597 return;
598
599found:
600 if (retries)
601 pr_debug("%s:%u: device %lu:%lu found after %u retries\n",
602 __func__, __LINE__, bus_id, dev_id, retries);
603
604 ps3_register_repository_device(&repo);
605 return;
606}
607
608#define PS3_NOTIFICATION_DEV_ID ULONG_MAX
609#define PS3_NOTIFICATION_INTERRUPT_ID 0
610
611struct ps3_notification_device {
612 struct ps3_system_bus_device sbd;
613 spinlock_t lock;
614 u64 tag;
615 u64 lv1_status;
616 struct completion done;
617};
618
619enum ps3_notify_type {
620 notify_device_ready = 0,
621 notify_region_probe = 1,
622 notify_region_update = 2,
623};
624
625struct ps3_notify_cmd {
626 u64 operation_code; /* must be zero */
627 u64 event_mask; /* OR of 1UL << enum ps3_notify_type */
628};
629
630struct ps3_notify_event {
631 u64 event_type; /* enum ps3_notify_type */
632 u64 bus_id;
633 u64 dev_id;
634 u64 dev_type;
635 u64 dev_port;
636};
637
638static irqreturn_t ps3_notification_interrupt(int irq, void *data)
639{
640 struct ps3_notification_device *dev = data;
641 int res;
642 u64 tag, status;
643
644 spin_lock(&dev->lock);
645 res = lv1_storage_get_async_status(PS3_NOTIFICATION_DEV_ID, &tag,
646 &status);
647 if (tag != dev->tag)
648 pr_err("%s:%u: tag mismatch, got %lx, expected %lx\n",
649 __func__, __LINE__, tag, dev->tag);
650
651 if (res) {
652 pr_err("%s:%u: res %d status 0x%lx\n", __func__, __LINE__, res,
653 status);
654 } else {
655 pr_debug("%s:%u: completed, status 0x%lx\n", __func__,
656 __LINE__, status);
657 dev->lv1_status = status;
658 complete(&dev->done);
659 }
660 spin_unlock(&dev->lock);
661 return IRQ_HANDLED;
662}
663
664static int ps3_notification_read_write(struct ps3_notification_device *dev,
665 u64 lpar, int write)
666{
667 const char *op = write ? "write" : "read";
668 unsigned long flags;
669 int res;
670
671 init_completion(&dev->done);
672 spin_lock_irqsave(&dev->lock, flags);
673 res = write ? lv1_storage_write(dev->sbd.dev_id, 0, 0, 1, 0, lpar,
674 &dev->tag)
675 : lv1_storage_read(dev->sbd.dev_id, 0, 0, 1, 0, lpar,
676 &dev->tag);
677 spin_unlock_irqrestore(&dev->lock, flags);
678 if (res) {
679 pr_err("%s:%u: %s failed %d\n", __func__, __LINE__, op, res);
680 return -EPERM;
681 }
682 pr_debug("%s:%u: notification %s issued\n", __func__, __LINE__, op);
683
684 res = wait_event_interruptible(dev->done.wait,
685 dev->done.done || kthread_should_stop());
686 if (kthread_should_stop())
687 res = -EINTR;
688 if (res) {
689 pr_debug("%s:%u: interrupted %s\n", __func__, __LINE__, op);
690 return res;
691 }
692
693 if (dev->lv1_status) {
694 pr_err("%s:%u: %s not completed, status 0x%lx\n", __func__,
695 __LINE__, op, dev->lv1_status);
696 return -EIO;
697 }
698 pr_debug("%s:%u: notification %s completed\n", __func__, __LINE__, op);
699
700 return 0;
701}
702
703static struct task_struct *probe_task;
704
662/** 705/**
663 * ps3_probe_thread - Background repository probing at system startup. 706 * ps3_probe_thread - Background repository probing at system startup.
664 * 707 *
665 * This implementation only supports background probing on a single bus. 708 * This implementation only supports background probing on a single bus.
709 * It uses the hypervisor's storage device notification mechanism to wait until
710 * a storage device is ready. The device notification mechanism uses a
711 * pseudo device to asynchronously notify the guest when storage devices become
712 * ready. The notification device has a block size of 512 bytes.
666 */ 713 */
667 714
668static int ps3_probe_thread(void *data) 715static int ps3_probe_thread(void *data)
669{ 716{
670 struct ps3_repository_device *repo = data; 717 struct ps3_notification_device dev;
671 int result; 718 int res;
672 unsigned int ms = 250; 719 unsigned int irq;
720 u64 lpar;
721 void *buf;
722 struct ps3_notify_cmd *notify_cmd;
723 struct ps3_notify_event *notify_event;
673 724
674 pr_debug(" -> %s:%u: kthread started\n", __func__, __LINE__); 725 pr_debug(" -> %s:%u: kthread started\n", __func__, __LINE__);
675 726
727 buf = kzalloc(512, GFP_KERNEL);
728 if (!buf)
729 return -ENOMEM;
730
731 lpar = ps3_mm_phys_to_lpar(__pa(buf));
732 notify_cmd = buf;
733 notify_event = buf;
734
735 /* dummy system bus device */
736 dev.sbd.bus_id = (u64)data;
737 dev.sbd.dev_id = PS3_NOTIFICATION_DEV_ID;
738 dev.sbd.interrupt_id = PS3_NOTIFICATION_INTERRUPT_ID;
739
740 res = lv1_open_device(dev.sbd.bus_id, dev.sbd.dev_id, 0);
741 if (res) {
742 pr_err("%s:%u: lv1_open_device failed %s\n", __func__,
743 __LINE__, ps3_result(res));
744 goto fail_free;
745 }
746
747 res = ps3_sb_event_receive_port_setup(&dev.sbd, PS3_BINDING_CPU_ANY,
748 &irq);
749 if (res) {
750 pr_err("%s:%u: ps3_sb_event_receive_port_setup failed %d\n",
751 __func__, __LINE__, res);
752 goto fail_close_device;
753 }
754
755 spin_lock_init(&dev.lock);
756
757 res = request_irq(irq, ps3_notification_interrupt, IRQF_DISABLED,
758 "ps3_notification", &dev);
759 if (res) {
760 pr_err("%s:%u: request_irq failed %d\n", __func__, __LINE__,
761 res);
762 goto fail_sb_event_receive_port_destroy;
763 }
764
765 /* Setup and write the request for device notification. */
766 notify_cmd->operation_code = 0; /* must be zero */
767 notify_cmd->event_mask = 1UL << notify_region_probe;
768
769 res = ps3_notification_read_write(&dev, lpar, 1);
770 if (res)
771 goto fail_free_irq;
772
773 /* Loop here processing the requested notification events. */
676 do { 774 do {
677 try_to_freeze(); 775 try_to_freeze();
678 776
679 pr_debug("%s:%u: probing...\n", __func__, __LINE__); 777 memset(notify_event, 0, sizeof(*notify_event));
680 778
681 do { 779 res = ps3_notification_read_write(&dev, lpar, 0);
682 result = ps3_repository_find_device(repo); 780 if (res)
683
684 if (result == -ENODEV)
685 pr_debug("%s:%u: nothing new\n", __func__,
686 __LINE__);
687 else if (result)
688 pr_debug("%s:%u: find device error.\n",
689 __func__, __LINE__);
690 else {
691 pr_debug("%s:%u: found device (%u:%u:%u)\n",
692 __func__, __LINE__, repo->bus_index,
693 repo->dev_index, repo->dev_type);
694 ps3_register_repository_device(repo);
695 ps3_repository_bump_device(repo);
696 ms = 250;
697 }
698 } while (!result);
699
700 pr_debug("%s:%u: ms %u\n", __func__, __LINE__, ms);
701
702 if ( ms > 60000)
703 break; 781 break;
704 782
705 msleep_interruptible(ms); 783 pr_debug("%s:%u: notify event type 0x%lx bus id %lu dev id %lu"
784 " type %lu port %lu\n", __func__, __LINE__,
785 notify_event->event_type, notify_event->bus_id,
786 notify_event->dev_id, notify_event->dev_type,
787 notify_event->dev_port);
706 788
707 /* An exponential backoff. */ 789 if (notify_event->event_type != notify_region_probe ||
708 ms <<= 1; 790 notify_event->bus_id != dev.sbd.bus_id) {
791 pr_warning("%s:%u: bad notify_event: event %lu, "
792 "dev_id %lu, dev_type %lu\n",
793 __func__, __LINE__, notify_event->event_type,
794 notify_event->dev_id,
795 notify_event->dev_type);
796 continue;
797 }
798
799 ps3_find_and_add_device(dev.sbd.bus_id, notify_event->dev_id);
709 800
710 } while (!kthread_should_stop()); 801 } while (!kthread_should_stop());
711 802
803fail_free_irq:
804 free_irq(irq, &dev);
805fail_sb_event_receive_port_destroy:
806 ps3_sb_event_receive_port_destroy(&dev.sbd, irq);
807fail_close_device:
808 lv1_close_device(dev.sbd.bus_id, dev.sbd.dev_id);
809fail_free:
810 kfree(buf);
811
812 probe_task = NULL;
813
712 pr_debug(" <- %s:%u: kthread finished\n", __func__, __LINE__); 814 pr_debug(" <- %s:%u: kthread finished\n", __func__, __LINE__);
713 815
714 return 0; 816 return 0;
715} 817}
716 818
717/** 819/**
820 * ps3_stop_probe_thread - Stops the background probe thread.
821 *
822 */
823
824static int ps3_stop_probe_thread(struct notifier_block *nb, unsigned long code,
825 void *data)
826{
827 if (probe_task)
828 kthread_stop(probe_task);
829 return 0;
830}
831
832static struct notifier_block nb = {
833 .notifier_call = ps3_stop_probe_thread
834};
835
836/**
718 * ps3_start_probe_thread - Starts the background probe thread. 837 * ps3_start_probe_thread - Starts the background probe thread.
719 * 838 *
720 */ 839 */
@@ -723,7 +842,7 @@ static int __init ps3_start_probe_thread(enum ps3_bus_type bus_type)
723{ 842{
724 int result; 843 int result;
725 struct task_struct *task; 844 struct task_struct *task;
726 static struct ps3_repository_device repo; /* must be static */ 845 struct ps3_repository_device repo;
727 846
728 pr_debug(" -> %s:%d\n", __func__, __LINE__); 847 pr_debug(" -> %s:%d\n", __func__, __LINE__);
729 848
@@ -746,7 +865,8 @@ static int __init ps3_start_probe_thread(enum ps3_bus_type bus_type)
746 return -ENODEV; 865 return -ENODEV;
747 } 866 }
748 867
749 task = kthread_run(ps3_probe_thread, &repo, "ps3-probe-%u", bus_type); 868 task = kthread_run(ps3_probe_thread, (void *)repo.bus_id,
869 "ps3-probe-%u", bus_type);
750 870
751 if (IS_ERR(task)) { 871 if (IS_ERR(task)) {
752 result = PTR_ERR(task); 872 result = PTR_ERR(task);
@@ -755,6 +875,9 @@ static int __init ps3_start_probe_thread(enum ps3_bus_type bus_type)
755 return result; 875 return result;
756 } 876 }
757 877
878 probe_task = task;
879 register_reboot_notifier(&nb);
880
758 pr_debug(" <- %s:%d\n", __func__, __LINE__); 881 pr_debug(" <- %s:%d\n", __func__, __LINE__);
759 return 0; 882 return 0;
760} 883}
@@ -787,6 +910,8 @@ static int __init ps3_register_devices(void)
787 910
788 ps3_register_sound_devices(); 911 ps3_register_sound_devices();
789 912
913 ps3_register_lpm_devices();
914
790 pr_debug(" <- %s:%d\n", __func__, __LINE__); 915 pr_debug(" <- %s:%d\n", __func__, __LINE__);
791 return 0; 916 return 0;
792} 917}
diff --git a/arch/powerpc/platforms/ps3/mm.c b/arch/powerpc/platforms/ps3/mm.c
index 7bb3e1620974..68900476c842 100644
--- a/arch/powerpc/platforms/ps3/mm.c
+++ b/arch/powerpc/platforms/ps3/mm.c
@@ -36,11 +36,6 @@
36#endif 36#endif
37 37
38enum { 38enum {
39#if defined(CONFIG_PS3_USE_LPAR_ADDR)
40 USE_LPAR_ADDR = 1,
41#else
42 USE_LPAR_ADDR = 0,
43#endif
44#if defined(CONFIG_PS3_DYNAMIC_DMA) 39#if defined(CONFIG_PS3_DYNAMIC_DMA)
45 USE_DYNAMIC_DMA = 1, 40 USE_DYNAMIC_DMA = 1,
46#else 41#else
@@ -137,11 +132,8 @@ static struct map map;
137unsigned long ps3_mm_phys_to_lpar(unsigned long phys_addr) 132unsigned long ps3_mm_phys_to_lpar(unsigned long phys_addr)
138{ 133{
139 BUG_ON(is_kernel_addr(phys_addr)); 134 BUG_ON(is_kernel_addr(phys_addr));
140 if (USE_LPAR_ADDR) 135 return (phys_addr < map.rm.size || phys_addr >= map.total)
141 return phys_addr; 136 ? phys_addr : phys_addr + map.r1.offset;
142 else
143 return (phys_addr < map.rm.size || phys_addr >= map.total)
144 ? phys_addr : phys_addr + map.r1.offset;
145} 137}
146 138
147EXPORT_SYMBOL(ps3_mm_phys_to_lpar); 139EXPORT_SYMBOL(ps3_mm_phys_to_lpar);
@@ -309,7 +301,7 @@ static int __init ps3_mm_add_memory(void)
309 301
310 BUG_ON(!mem_init_done); 302 BUG_ON(!mem_init_done);
311 303
312 start_addr = USE_LPAR_ADDR ? map.r1.base : map.rm.size; 304 start_addr = map.rm.size;
313 start_pfn = start_addr >> PAGE_SHIFT; 305 start_pfn = start_addr >> PAGE_SHIFT;
314 nr_pages = (map.r1.size + PAGE_SIZE - 1) >> PAGE_SHIFT; 306 nr_pages = (map.r1.size + PAGE_SIZE - 1) >> PAGE_SHIFT;
315 307
@@ -359,7 +351,7 @@ static unsigned long dma_sb_lpar_to_bus(struct ps3_dma_region *r,
359static void __maybe_unused _dma_dump_region(const struct ps3_dma_region *r, 351static void __maybe_unused _dma_dump_region(const struct ps3_dma_region *r,
360 const char *func, int line) 352 const char *func, int line)
361{ 353{
362 DBG("%s:%d: dev %u:%u\n", func, line, r->dev->bus_id, 354 DBG("%s:%d: dev %lu:%lu\n", func, line, r->dev->bus_id,
363 r->dev->dev_id); 355 r->dev->dev_id);
364 DBG("%s:%d: page_size %u\n", func, line, r->page_size); 356 DBG("%s:%d: page_size %u\n", func, line, r->page_size);
365 DBG("%s:%d: bus_addr %lxh\n", func, line, r->bus_addr); 357 DBG("%s:%d: bus_addr %lxh\n", func, line, r->bus_addr);
@@ -394,7 +386,7 @@ struct dma_chunk {
394static void _dma_dump_chunk (const struct dma_chunk* c, const char* func, 386static void _dma_dump_chunk (const struct dma_chunk* c, const char* func,
395 int line) 387 int line)
396{ 388{
397 DBG("%s:%d: r.dev %u:%u\n", func, line, 389 DBG("%s:%d: r.dev %lu:%lu\n", func, line,
398 c->region->dev->bus_id, c->region->dev->dev_id); 390 c->region->dev->bus_id, c->region->dev->dev_id);
399 DBG("%s:%d: r.bus_addr %lxh\n", func, line, c->region->bus_addr); 391 DBG("%s:%d: r.bus_addr %lxh\n", func, line, c->region->bus_addr);
400 DBG("%s:%d: r.page_size %u\n", func, line, c->region->page_size); 392 DBG("%s:%d: r.page_size %u\n", func, line, c->region->page_size);
@@ -658,7 +650,7 @@ static int dma_sb_region_create(struct ps3_dma_region *r)
658 BUG_ON(!r); 650 BUG_ON(!r);
659 651
660 if (!r->dev->bus_id) { 652 if (!r->dev->bus_id) {
661 pr_info("%s:%d: %u:%u no dma\n", __func__, __LINE__, 653 pr_info("%s:%d: %lu:%lu no dma\n", __func__, __LINE__,
662 r->dev->bus_id, r->dev->dev_id); 654 r->dev->bus_id, r->dev->dev_id);
663 return 0; 655 return 0;
664 } 656 }
@@ -724,7 +716,7 @@ static int dma_sb_region_free(struct ps3_dma_region *r)
724 BUG_ON(!r); 716 BUG_ON(!r);
725 717
726 if (!r->dev->bus_id) { 718 if (!r->dev->bus_id) {
727 pr_info("%s:%d: %u:%u no dma\n", __func__, __LINE__, 719 pr_info("%s:%d: %lu:%lu no dma\n", __func__, __LINE__,
728 r->dev->bus_id, r->dev->dev_id); 720 r->dev->bus_id, r->dev->dev_id);
729 return 0; 721 return 0;
730 } 722 }
@@ -1007,7 +999,7 @@ static int dma_sb_region_create_linear(struct ps3_dma_region *r)
1007 999
1008 if (r->offset + r->len > map.rm.size) { 1000 if (r->offset + r->len > map.rm.size) {
1009 /* Map (part of) 2nd RAM chunk */ 1001 /* Map (part of) 2nd RAM chunk */
1010 virt_addr = USE_LPAR_ADDR ? map.r1.base : map.rm.size; 1002 virt_addr = map.rm.size;
1011 len = r->len; 1003 len = r->len;
1012 if (r->offset >= map.rm.size) 1004 if (r->offset >= map.rm.size)
1013 virt_addr += r->offset - map.rm.size; 1005 virt_addr += r->offset - map.rm.size;
diff --git a/arch/powerpc/platforms/ps3/platform.h b/arch/powerpc/platforms/ps3/platform.h
index 01f0c9506e11..235c13ebacd9 100644
--- a/arch/powerpc/platforms/ps3/platform.h
+++ b/arch/powerpc/platforms/ps3/platform.h
@@ -89,13 +89,11 @@ enum ps3_dev_type {
89 PS3_DEV_TYPE_STOR_ROM = TYPE_ROM, /* 5 */ 89 PS3_DEV_TYPE_STOR_ROM = TYPE_ROM, /* 5 */
90 PS3_DEV_TYPE_SB_GPIO = 6, 90 PS3_DEV_TYPE_SB_GPIO = 6,
91 PS3_DEV_TYPE_STOR_FLASH = TYPE_RBC, /* 14 */ 91 PS3_DEV_TYPE_STOR_FLASH = TYPE_RBC, /* 14 */
92 PS3_DEV_TYPE_STOR_DUMMY = 32,
93 PS3_DEV_TYPE_NOACCESS = 255,
94}; 92};
95 93
96int ps3_repository_read_bus_str(unsigned int bus_index, const char *bus_str, 94int ps3_repository_read_bus_str(unsigned int bus_index, const char *bus_str,
97 u64 *value); 95 u64 *value);
98int ps3_repository_read_bus_id(unsigned int bus_index, unsigned int *bus_id); 96int ps3_repository_read_bus_id(unsigned int bus_index, u64 *bus_id);
99int ps3_repository_read_bus_type(unsigned int bus_index, 97int ps3_repository_read_bus_type(unsigned int bus_index,
100 enum ps3_bus_type *bus_type); 98 enum ps3_bus_type *bus_type);
101int ps3_repository_read_bus_num_dev(unsigned int bus_index, 99int ps3_repository_read_bus_num_dev(unsigned int bus_index,
@@ -119,7 +117,7 @@ enum ps3_reg_type {
119int ps3_repository_read_dev_str(unsigned int bus_index, 117int ps3_repository_read_dev_str(unsigned int bus_index,
120 unsigned int dev_index, const char *dev_str, u64 *value); 118 unsigned int dev_index, const char *dev_str, u64 *value);
121int ps3_repository_read_dev_id(unsigned int bus_index, unsigned int dev_index, 119int ps3_repository_read_dev_id(unsigned int bus_index, unsigned int dev_index,
122 unsigned int *dev_id); 120 u64 *dev_id);
123int ps3_repository_read_dev_type(unsigned int bus_index, 121int ps3_repository_read_dev_type(unsigned int bus_index,
124 unsigned int dev_index, enum ps3_dev_type *dev_type); 122 unsigned int dev_index, enum ps3_dev_type *dev_type);
125int ps3_repository_read_dev_intr(unsigned int bus_index, 123int ps3_repository_read_dev_intr(unsigned int bus_index,
@@ -138,21 +136,17 @@ int ps3_repository_read_dev_reg(unsigned int bus_index,
138/* repository bus enumerators */ 136/* repository bus enumerators */
139 137
140struct ps3_repository_device { 138struct ps3_repository_device {
141 enum ps3_bus_type bus_type;
142 unsigned int bus_index; 139 unsigned int bus_index;
143 unsigned int bus_id;
144 enum ps3_dev_type dev_type;
145 unsigned int dev_index; 140 unsigned int dev_index;
146 unsigned int dev_id; 141 enum ps3_bus_type bus_type;
142 enum ps3_dev_type dev_type;
143 u64 bus_id;
144 u64 dev_id;
147}; 145};
148 146
149static inline struct ps3_repository_device *ps3_repository_bump_device(
150 struct ps3_repository_device *repo)
151{
152 repo->dev_index++;
153 return repo;
154}
155int ps3_repository_find_device(struct ps3_repository_device *repo); 147int ps3_repository_find_device(struct ps3_repository_device *repo);
148int ps3_repository_find_device_by_id(struct ps3_repository_device *repo,
149 u64 bus_id, u64 dev_id);
156int ps3_repository_find_devices(enum ps3_bus_type bus_type, 150int ps3_repository_find_devices(enum ps3_bus_type bus_type,
157 int (*callback)(const struct ps3_repository_device *repo)); 151 int (*callback)(const struct ps3_repository_device *repo));
158int ps3_repository_find_bus(enum ps3_bus_type bus_type, unsigned int from, 152int ps3_repository_find_bus(enum ps3_bus_type bus_type, unsigned int from,
@@ -186,10 +180,10 @@ int ps3_repository_read_stor_dev_region(unsigned int bus_index,
186 unsigned int dev_index, unsigned int region_index, 180 unsigned int dev_index, unsigned int region_index,
187 unsigned int *region_id, u64 *region_start, u64 *region_size); 181 unsigned int *region_id, u64 *region_start, u64 *region_size);
188 182
189/* repository pu and memory info */ 183/* repository logical pu and memory info */
190 184
191int ps3_repository_read_num_pu(unsigned int *num_pu); 185int ps3_repository_read_num_pu(u64 *num_pu);
192int ps3_repository_read_ppe_id(unsigned int *pu_index, unsigned int *ppe_id); 186int ps3_repository_read_pu_id(unsigned int pu_index, u64 *pu_id);
193int ps3_repository_read_rm_base(unsigned int ppe_id, u64 *rm_base); 187int ps3_repository_read_rm_base(unsigned int ppe_id, u64 *rm_base);
194int ps3_repository_read_rm_size(unsigned int ppe_id, u64 *rm_size); 188int ps3_repository_read_rm_size(unsigned int ppe_id, u64 *rm_size);
195int ps3_repository_read_region_total(u64 *region_total); 189int ps3_repository_read_region_total(u64 *region_total);
@@ -200,9 +194,15 @@ int ps3_repository_read_mm_info(u64 *rm_base, u64 *rm_size,
200 194
201int ps3_repository_read_num_be(unsigned int *num_be); 195int ps3_repository_read_num_be(unsigned int *num_be);
202int ps3_repository_read_be_node_id(unsigned int be_index, u64 *node_id); 196int ps3_repository_read_be_node_id(unsigned int be_index, u64 *node_id);
197int ps3_repository_read_be_id(u64 node_id, u64 *be_id);
203int ps3_repository_read_tb_freq(u64 node_id, u64 *tb_freq); 198int ps3_repository_read_tb_freq(u64 node_id, u64 *tb_freq);
204int ps3_repository_read_be_tb_freq(unsigned int be_index, u64 *tb_freq); 199int ps3_repository_read_be_tb_freq(unsigned int be_index, u64 *tb_freq);
205 200
201/* repository performance monitor info */
202
203int ps3_repository_read_lpm_privileges(unsigned int be_index, u64 *lpar,
204 u64 *rights);
205
206/* repository 'Other OS' area */ 206/* repository 'Other OS' area */
207 207
208int ps3_repository_read_boot_dat_addr(u64 *lpar_addr); 208int ps3_repository_read_boot_dat_addr(u64 *lpar_addr);
diff --git a/arch/powerpc/platforms/ps3/repository.c b/arch/powerpc/platforms/ps3/repository.c
index 1c94824f7b63..22063adeb38b 100644
--- a/arch/powerpc/platforms/ps3/repository.c
+++ b/arch/powerpc/platforms/ps3/repository.c
@@ -33,7 +33,7 @@ enum ps3_lpar_id {
33}; 33};
34 34
35#define dump_field(_a, _b) _dump_field(_a, _b, __func__, __LINE__) 35#define dump_field(_a, _b) _dump_field(_a, _b, __func__, __LINE__)
36static void _dump_field(const char *hdr, u64 n, const char* func, int line) 36static void _dump_field(const char *hdr, u64 n, const char *func, int line)
37{ 37{
38#if defined(DEBUG) 38#if defined(DEBUG)
39 char s[16]; 39 char s[16];
@@ -50,8 +50,8 @@ static void _dump_field(const char *hdr, u64 n, const char* func, int line)
50 50
51#define dump_node_name(_a, _b, _c, _d, _e) \ 51#define dump_node_name(_a, _b, _c, _d, _e) \
52 _dump_node_name(_a, _b, _c, _d, _e, __func__, __LINE__) 52 _dump_node_name(_a, _b, _c, _d, _e, __func__, __LINE__)
53static void _dump_node_name (unsigned int lpar_id, u64 n1, u64 n2, u64 n3, 53static void _dump_node_name(unsigned int lpar_id, u64 n1, u64 n2, u64 n3,
54 u64 n4, const char* func, int line) 54 u64 n4, const char *func, int line)
55{ 55{
56 pr_debug("%s:%d: lpar: %u\n", func, line, lpar_id); 56 pr_debug("%s:%d: lpar: %u\n", func, line, lpar_id);
57 _dump_field("n1: ", n1, func, line); 57 _dump_field("n1: ", n1, func, line);
@@ -63,7 +63,7 @@ static void _dump_node_name (unsigned int lpar_id, u64 n1, u64 n2, u64 n3,
63#define dump_node(_a, _b, _c, _d, _e, _f, _g) \ 63#define dump_node(_a, _b, _c, _d, _e, _f, _g) \
64 _dump_node(_a, _b, _c, _d, _e, _f, _g, __func__, __LINE__) 64 _dump_node(_a, _b, _c, _d, _e, _f, _g, __func__, __LINE__)
65static void _dump_node(unsigned int lpar_id, u64 n1, u64 n2, u64 n3, u64 n4, 65static void _dump_node(unsigned int lpar_id, u64 n1, u64 n2, u64 n3, u64 n4,
66 u64 v1, u64 v2, const char* func, int line) 66 u64 v1, u64 v2, const char *func, int line)
67{ 67{
68 pr_debug("%s:%d: lpar: %u\n", func, line, lpar_id); 68 pr_debug("%s:%d: lpar: %u\n", func, line, lpar_id);
69 _dump_field("n1: ", n1, func, line); 69 _dump_field("n1: ", n1, func, line);
@@ -165,21 +165,18 @@ int ps3_repository_read_bus_str(unsigned int bus_index, const char *bus_str,
165 make_first_field("bus", bus_index), 165 make_first_field("bus", bus_index),
166 make_field(bus_str, 0), 166 make_field(bus_str, 0),
167 0, 0, 167 0, 0,
168 value, 0); 168 value, NULL);
169} 169}
170 170
171int ps3_repository_read_bus_id(unsigned int bus_index, unsigned int *bus_id) 171int ps3_repository_read_bus_id(unsigned int bus_index, u64 *bus_id)
172{ 172{
173 int result; 173 int result;
174 u64 v1;
175 u64 v2; /* unused */
176 174
177 result = read_node(PS3_LPAR_ID_PME, 175 result = read_node(PS3_LPAR_ID_PME,
178 make_first_field("bus", bus_index), 176 make_first_field("bus", bus_index),
179 make_field("id", 0), 177 make_field("id", 0),
180 0, 0, 178 0, 0,
181 &v1, &v2); 179 bus_id, NULL);
182 *bus_id = v1;
183 return result; 180 return result;
184} 181}
185 182
@@ -193,7 +190,7 @@ int ps3_repository_read_bus_type(unsigned int bus_index,
193 make_first_field("bus", bus_index), 190 make_first_field("bus", bus_index),
194 make_field("type", 0), 191 make_field("type", 0),
195 0, 0, 192 0, 0,
196 &v1, 0); 193 &v1, NULL);
197 *bus_type = v1; 194 *bus_type = v1;
198 return result; 195 return result;
199} 196}
@@ -208,7 +205,7 @@ int ps3_repository_read_bus_num_dev(unsigned int bus_index,
208 make_first_field("bus", bus_index), 205 make_first_field("bus", bus_index),
209 make_field("num_dev", 0), 206 make_field("num_dev", 0),
210 0, 0, 207 0, 0,
211 &v1, 0); 208 &v1, NULL);
212 *num_dev = v1; 209 *num_dev = v1;
213 return result; 210 return result;
214} 211}
@@ -221,22 +218,20 @@ int ps3_repository_read_dev_str(unsigned int bus_index,
221 make_field("dev", dev_index), 218 make_field("dev", dev_index),
222 make_field(dev_str, 0), 219 make_field(dev_str, 0),
223 0, 220 0,
224 value, 0); 221 value, NULL);
225} 222}
226 223
227int ps3_repository_read_dev_id(unsigned int bus_index, unsigned int dev_index, 224int ps3_repository_read_dev_id(unsigned int bus_index, unsigned int dev_index,
228 unsigned int *dev_id) 225 u64 *dev_id)
229{ 226{
230 int result; 227 int result;
231 u64 v1;
232 228
233 result = read_node(PS3_LPAR_ID_PME, 229 result = read_node(PS3_LPAR_ID_PME,
234 make_first_field("bus", bus_index), 230 make_first_field("bus", bus_index),
235 make_field("dev", dev_index), 231 make_field("dev", dev_index),
236 make_field("id", 0), 232 make_field("id", 0),
237 0, 233 0,
238 &v1, 0); 234 dev_id, NULL);
239 *dev_id = v1;
240 return result; 235 return result;
241} 236}
242 237
@@ -251,14 +246,14 @@ int ps3_repository_read_dev_type(unsigned int bus_index,
251 make_field("dev", dev_index), 246 make_field("dev", dev_index),
252 make_field("type", 0), 247 make_field("type", 0),
253 0, 248 0,
254 &v1, 0); 249 &v1, NULL);
255 *dev_type = v1; 250 *dev_type = v1;
256 return result; 251 return result;
257} 252}
258 253
259int ps3_repository_read_dev_intr(unsigned int bus_index, 254int ps3_repository_read_dev_intr(unsigned int bus_index,
260 unsigned int dev_index, unsigned int intr_index, 255 unsigned int dev_index, unsigned int intr_index,
261 enum ps3_interrupt_type *intr_type, unsigned int* interrupt_id) 256 enum ps3_interrupt_type *intr_type, unsigned int *interrupt_id)
262{ 257{
263 int result; 258 int result;
264 u64 v1; 259 u64 v1;
@@ -287,7 +282,7 @@ int ps3_repository_read_dev_reg_type(unsigned int bus_index,
287 make_field("dev", dev_index), 282 make_field("dev", dev_index),
288 make_field("reg", reg_index), 283 make_field("reg", reg_index),
289 make_field("type", 0), 284 make_field("type", 0),
290 &v1, 0); 285 &v1, NULL);
291 *reg_type = v1; 286 *reg_type = v1;
292 return result; 287 return result;
293} 288}
@@ -332,7 +327,7 @@ int ps3_repository_find_device(struct ps3_repository_device *repo)
332 return result; 327 return result;
333 } 328 }
334 329
335 pr_debug("%s:%d: bus_type %u, bus_index %u, bus_id %u, num_dev %u\n", 330 pr_debug("%s:%d: bus_type %u, bus_index %u, bus_id %lu, num_dev %u\n",
336 __func__, __LINE__, tmp.bus_type, tmp.bus_index, tmp.bus_id, 331 __func__, __LINE__, tmp.bus_type, tmp.bus_index, tmp.bus_id,
337 num_dev); 332 num_dev);
338 333
@@ -349,47 +344,95 @@ int ps3_repository_find_device(struct ps3_repository_device *repo)
349 return result; 344 return result;
350 } 345 }
351 346
352 if (tmp.bus_type == PS3_BUS_TYPE_STORAGE) { 347 result = ps3_repository_read_dev_id(tmp.bus_index, tmp.dev_index,
353 /* 348 &tmp.dev_id);
354 * A storage device may show up in the repository before the
355 * hypervisor has finished probing its type and regions
356 */
357 unsigned int num_regions;
358
359 if (tmp.dev_type == PS3_DEV_TYPE_STOR_DUMMY) {
360 pr_debug("%s:%u storage device not ready\n", __func__,
361 __LINE__);
362 return -ENODEV;
363 }
364 349
365 result = ps3_repository_read_stor_dev_num_regions(tmp.bus_index, 350 if (result) {
366 tmp.dev_index, 351 pr_debug("%s:%d ps3_repository_read_dev_id failed\n", __func__,
367 &num_regions); 352 __LINE__);
353 return result;
354 }
355
356 pr_debug("%s:%d: found: dev_type %u, dev_index %u, dev_id %lu\n",
357 __func__, __LINE__, tmp.dev_type, tmp.dev_index, tmp.dev_id);
358
359 *repo = tmp;
360 return 0;
361}
362
363int ps3_repository_find_device_by_id(struct ps3_repository_device *repo,
364 u64 bus_id, u64 dev_id)
365{
366 int result = -ENODEV;
367 struct ps3_repository_device tmp;
368 unsigned int num_dev;
369
370 pr_debug(" -> %s:%u: find device by id %lu:%lu\n", __func__, __LINE__,
371 bus_id, dev_id);
372
373 for (tmp.bus_index = 0; tmp.bus_index < 10; tmp.bus_index++) {
374 result = ps3_repository_read_bus_id(tmp.bus_index,
375 &tmp.bus_id);
368 if (result) { 376 if (result) {
369 pr_debug("%s:%d read_stor_dev_num_regions failed\n", 377 pr_debug("%s:%u read_bus_id(%u) failed\n", __func__,
370 __func__, __LINE__); 378 __LINE__, tmp.bus_index);
371 return result; 379 return result;
372 } 380 }
373 381
374 if (!num_regions) { 382 if (tmp.bus_id == bus_id)
375 pr_debug("%s:%u storage device has no regions yet\n", 383 goto found_bus;
376 __func__, __LINE__); 384
377 return -ENODEV; 385 pr_debug("%s:%u: skip, bus_id %lu\n", __func__, __LINE__,
378 } 386 tmp.bus_id);
379 } 387 }
388 pr_debug(" <- %s:%u: bus not found\n", __func__, __LINE__);
389 return result;
380 390
381 result = ps3_repository_read_dev_id(tmp.bus_index, tmp.dev_index, 391found_bus:
382 &tmp.dev_id); 392 result = ps3_repository_read_bus_type(tmp.bus_index, &tmp.bus_type);
393 if (result) {
394 pr_debug("%s:%u read_bus_type(%u) failed\n", __func__,
395 __LINE__, tmp.bus_index);
396 return result;
397 }
383 398
399 result = ps3_repository_read_bus_num_dev(tmp.bus_index, &num_dev);
384 if (result) { 400 if (result) {
385 pr_debug("%s:%d ps3_repository_read_dev_id failed\n", __func__, 401 pr_debug("%s:%u read_bus_num_dev failed\n", __func__,
386 __LINE__); 402 __LINE__);
387 return result; 403 return result;
388 } 404 }
389 405
390 pr_debug("%s:%d: found: dev_type %u, dev_index %u, dev_id %u\n", 406 for (tmp.dev_index = 0; tmp.dev_index < num_dev; tmp.dev_index++) {
391 __func__, __LINE__, tmp.dev_type, tmp.dev_index, tmp.dev_id); 407 result = ps3_repository_read_dev_id(tmp.bus_index,
408 tmp.dev_index,
409 &tmp.dev_id);
410 if (result) {
411 pr_debug("%s:%u read_dev_id(%u:%u) failed\n", __func__,
412 __LINE__, tmp.bus_index, tmp.dev_index);
413 return result;
414 }
392 415
416 if (tmp.dev_id == dev_id)
417 goto found_dev;
418
419 pr_debug("%s:%u: skip, dev_id %lu\n", __func__, __LINE__,
420 tmp.dev_id);
421 }
422 pr_debug(" <- %s:%u: dev not found\n", __func__, __LINE__);
423 return result;
424
425found_dev:
426 result = ps3_repository_read_dev_type(tmp.bus_index, tmp.dev_index,
427 &tmp.dev_type);
428 if (result) {
429 pr_debug("%s:%u read_dev_type failed\n", __func__, __LINE__);
430 return result;
431 }
432
433 pr_debug(" <- %s:%u: found: type (%u:%u) index (%u:%u) id (%lu:%lu)\n",
434 __func__, __LINE__, tmp.bus_type, tmp.dev_type, tmp.bus_index,
435 tmp.dev_index, tmp.bus_id, tmp.dev_id);
393 *repo = tmp; 436 *repo = tmp;
394 return 0; 437 return 0;
395} 438}
@@ -402,50 +445,34 @@ int __devinit ps3_repository_find_devices(enum ps3_bus_type bus_type,
402 445
403 pr_debug(" -> %s:%d: find bus_type %u\n", __func__, __LINE__, bus_type); 446 pr_debug(" -> %s:%d: find bus_type %u\n", __func__, __LINE__, bus_type);
404 447
405 for (repo.bus_index = 0; repo.bus_index < 10; repo.bus_index++) { 448 repo.bus_type = bus_type;
449 result = ps3_repository_find_bus(repo.bus_type, 0, &repo.bus_index);
450 if (result) {
451 pr_debug(" <- %s:%u: bus not found\n", __func__, __LINE__);
452 return result;
453 }
406 454
407 result = ps3_repository_read_bus_type(repo.bus_index, 455 result = ps3_repository_read_bus_id(repo.bus_index, &repo.bus_id);
408 &repo.bus_type); 456 if (result) {
457 pr_debug("%s:%d read_bus_id(%u) failed\n", __func__, __LINE__,
458 repo.bus_index);
459 return result;
460 }
409 461
410 if (result) { 462 for (repo.dev_index = 0; ; repo.dev_index++) {
411 pr_debug("%s:%d read_bus_type(%u) failed\n", 463 result = ps3_repository_find_device(&repo);
412 __func__, __LINE__, repo.bus_index); 464 if (result == -ENODEV) {
465 result = 0;
466 break;
467 } else if (result)
413 break; 468 break;
414 }
415
416 if (repo.bus_type != bus_type) {
417 pr_debug("%s:%d: skip, bus_type %u\n", __func__,
418 __LINE__, repo.bus_type);
419 continue;
420 }
421
422 result = ps3_repository_read_bus_id(repo.bus_index,
423 &repo.bus_id);
424 469
470 result = callback(&repo);
425 if (result) { 471 if (result) {
426 pr_debug("%s:%d read_bus_id(%u) failed\n", 472 pr_debug("%s:%d: abort at callback\n", __func__,
427 __func__, __LINE__, repo.bus_index); 473 __LINE__);
428 continue; 474 break;
429 }
430
431 for (repo.dev_index = 0; ; repo.dev_index++) {
432 result = ps3_repository_find_device(&repo);
433
434 if (result == -ENODEV) {
435 result = 0;
436 break;
437 } else if (result)
438 break;
439
440 result = callback(&repo);
441
442 if (result) {
443 pr_debug("%s:%d: abort at callback\n", __func__,
444 __LINE__);
445 break;
446 }
447 } 475 }
448 break;
449 } 476 }
450 477
451 pr_debug(" <- %s:%d\n", __func__, __LINE__); 478 pr_debug(" <- %s:%d\n", __func__, __LINE__);
@@ -561,7 +588,7 @@ int ps3_repository_read_stor_dev_port(unsigned int bus_index,
561 make_first_field("bus", bus_index), 588 make_first_field("bus", bus_index),
562 make_field("dev", dev_index), 589 make_field("dev", dev_index),
563 make_field("port", 0), 590 make_field("port", 0),
564 0, port, 0); 591 0, port, NULL);
565} 592}
566 593
567int ps3_repository_read_stor_dev_blk_size(unsigned int bus_index, 594int ps3_repository_read_stor_dev_blk_size(unsigned int bus_index,
@@ -571,7 +598,7 @@ int ps3_repository_read_stor_dev_blk_size(unsigned int bus_index,
571 make_first_field("bus", bus_index), 598 make_first_field("bus", bus_index),
572 make_field("dev", dev_index), 599 make_field("dev", dev_index),
573 make_field("blk_size", 0), 600 make_field("blk_size", 0),
574 0, blk_size, 0); 601 0, blk_size, NULL);
575} 602}
576 603
577int ps3_repository_read_stor_dev_num_blocks(unsigned int bus_index, 604int ps3_repository_read_stor_dev_num_blocks(unsigned int bus_index,
@@ -581,7 +608,7 @@ int ps3_repository_read_stor_dev_num_blocks(unsigned int bus_index,
581 make_first_field("bus", bus_index), 608 make_first_field("bus", bus_index),
582 make_field("dev", dev_index), 609 make_field("dev", dev_index),
583 make_field("n_blocks", 0), 610 make_field("n_blocks", 0),
584 0, num_blocks, 0); 611 0, num_blocks, NULL);
585} 612}
586 613
587int ps3_repository_read_stor_dev_num_regions(unsigned int bus_index, 614int ps3_repository_read_stor_dev_num_regions(unsigned int bus_index,
@@ -594,7 +621,7 @@ int ps3_repository_read_stor_dev_num_regions(unsigned int bus_index,
594 make_first_field("bus", bus_index), 621 make_first_field("bus", bus_index),
595 make_field("dev", dev_index), 622 make_field("dev", dev_index),
596 make_field("n_regs", 0), 623 make_field("n_regs", 0),
597 0, &v1, 0); 624 0, &v1, NULL);
598 *num_regions = v1; 625 *num_regions = v1;
599 return result; 626 return result;
600} 627}
@@ -611,7 +638,7 @@ int ps3_repository_read_stor_dev_region_id(unsigned int bus_index,
611 make_field("dev", dev_index), 638 make_field("dev", dev_index),
612 make_field("region", region_index), 639 make_field("region", region_index),
613 make_field("id", 0), 640 make_field("id", 0),
614 &v1, 0); 641 &v1, NULL);
615 *region_id = v1; 642 *region_id = v1;
616 return result; 643 return result;
617} 644}
@@ -624,7 +651,7 @@ int ps3_repository_read_stor_dev_region_size(unsigned int bus_index,
624 make_field("dev", dev_index), 651 make_field("dev", dev_index),
625 make_field("region", region_index), 652 make_field("region", region_index),
626 make_field("size", 0), 653 make_field("size", 0),
627 region_size, 0); 654 region_size, NULL);
628} 655}
629 656
630int ps3_repository_read_stor_dev_region_start(unsigned int bus_index, 657int ps3_repository_read_stor_dev_region_start(unsigned int bus_index,
@@ -635,7 +662,7 @@ int ps3_repository_read_stor_dev_region_start(unsigned int bus_index,
635 make_field("dev", dev_index), 662 make_field("dev", dev_index),
636 make_field("region", region_index), 663 make_field("region", region_index),
637 make_field("start", 0), 664 make_field("start", 0),
638 region_start, 0); 665 region_start, NULL);
639} 666}
640 667
641int ps3_repository_read_stor_dev_info(unsigned int bus_index, 668int ps3_repository_read_stor_dev_info(unsigned int bus_index,
@@ -684,6 +711,35 @@ int ps3_repository_read_stor_dev_region(unsigned int bus_index,
684 return result; 711 return result;
685} 712}
686 713
714/**
715 * ps3_repository_read_num_pu - Number of logical PU processors for this lpar.
716 */
717
718int ps3_repository_read_num_pu(u64 *num_pu)
719{
720 *num_pu = 0;
721 return read_node(PS3_LPAR_ID_CURRENT,
722 make_first_field("bi", 0),
723 make_field("pun", 0),
724 0, 0,
725 num_pu, NULL);
726}
727
728/**
729 * ps3_repository_read_pu_id - Read the logical PU id.
730 * @pu_index: Zero based index.
731 * @pu_id: The logical PU id.
732 */
733
734int ps3_repository_read_pu_id(unsigned int pu_index, u64 *pu_id)
735{
736 return read_node(PS3_LPAR_ID_CURRENT,
737 make_first_field("bi", 0),
738 make_field("pu", pu_index),
739 0, 0,
740 pu_id, NULL);
741}
742
687int ps3_repository_read_rm_size(unsigned int ppe_id, u64 *rm_size) 743int ps3_repository_read_rm_size(unsigned int ppe_id, u64 *rm_size)
688{ 744{
689 return read_node(PS3_LPAR_ID_CURRENT, 745 return read_node(PS3_LPAR_ID_CURRENT,
@@ -691,7 +747,7 @@ int ps3_repository_read_rm_size(unsigned int ppe_id, u64 *rm_size)
691 make_field("pu", 0), 747 make_field("pu", 0),
692 ppe_id, 748 ppe_id,
693 make_field("rm_size", 0), 749 make_field("rm_size", 0),
694 rm_size, 0); 750 rm_size, NULL);
695} 751}
696 752
697int ps3_repository_read_region_total(u64 *region_total) 753int ps3_repository_read_region_total(u64 *region_total)
@@ -700,7 +756,7 @@ int ps3_repository_read_region_total(u64 *region_total)
700 make_first_field("bi", 0), 756 make_first_field("bi", 0),
701 make_field("rgntotal", 0), 757 make_field("rgntotal", 0),
702 0, 0, 758 0, 0,
703 region_total, 0); 759 region_total, NULL);
704} 760}
705 761
706/** 762/**
@@ -736,7 +792,7 @@ int ps3_repository_read_num_spu_reserved(unsigned int *num_spu_reserved)
736 make_first_field("bi", 0), 792 make_first_field("bi", 0),
737 make_field("spun", 0), 793 make_field("spun", 0),
738 0, 0, 794 0, 0,
739 &v1, 0); 795 &v1, NULL);
740 *num_spu_reserved = v1; 796 *num_spu_reserved = v1;
741 return result; 797 return result;
742} 798}
@@ -755,7 +811,7 @@ int ps3_repository_read_num_spu_resource_id(unsigned int *num_resource_id)
755 make_first_field("bi", 0), 811 make_first_field("bi", 0),
756 make_field("spursvn", 0), 812 make_field("spursvn", 0),
757 0, 0, 813 0, 0,
758 &v1, 0); 814 &v1, NULL);
759 *num_resource_id = v1; 815 *num_resource_id = v1;
760 return result; 816 return result;
761} 817}
@@ -768,7 +824,7 @@ int ps3_repository_read_num_spu_resource_id(unsigned int *num_resource_id)
768 */ 824 */
769 825
770int ps3_repository_read_spu_resource_id(unsigned int res_index, 826int ps3_repository_read_spu_resource_id(unsigned int res_index,
771 enum ps3_spu_resource_type* resource_type, unsigned int *resource_id) 827 enum ps3_spu_resource_type *resource_type, unsigned int *resource_id)
772{ 828{
773 int result; 829 int result;
774 u64 v1; 830 u64 v1;
@@ -785,14 +841,14 @@ int ps3_repository_read_spu_resource_id(unsigned int res_index,
785 return result; 841 return result;
786} 842}
787 843
788int ps3_repository_read_boot_dat_address(u64 *address) 844static int ps3_repository_read_boot_dat_address(u64 *address)
789{ 845{
790 return read_node(PS3_LPAR_ID_CURRENT, 846 return read_node(PS3_LPAR_ID_CURRENT,
791 make_first_field("bi", 0), 847 make_first_field("bi", 0),
792 make_field("boot_dat", 0), 848 make_field("boot_dat", 0),
793 make_field("address", 0), 849 make_field("address", 0),
794 0, 850 0,
795 address, 0); 851 address, NULL);
796} 852}
797 853
798int ps3_repository_read_boot_dat_size(unsigned int *size) 854int ps3_repository_read_boot_dat_size(unsigned int *size)
@@ -805,7 +861,7 @@ int ps3_repository_read_boot_dat_size(unsigned int *size)
805 make_field("boot_dat", 0), 861 make_field("boot_dat", 0),
806 make_field("size", 0), 862 make_field("size", 0),
807 0, 863 0,
808 &v1, 0); 864 &v1, NULL);
809 *size = v1; 865 *size = v1;
810 return result; 866 return result;
811} 867}
@@ -820,7 +876,7 @@ int ps3_repository_read_vuart_av_port(unsigned int *port)
820 make_field("vir_uart", 0), 876 make_field("vir_uart", 0),
821 make_field("port", 0), 877 make_field("port", 0),
822 make_field("avset", 0), 878 make_field("avset", 0),
823 &v1, 0); 879 &v1, NULL);
824 *port = v1; 880 *port = v1;
825 return result; 881 return result;
826} 882}
@@ -835,7 +891,7 @@ int ps3_repository_read_vuart_sysmgr_port(unsigned int *port)
835 make_field("vir_uart", 0), 891 make_field("vir_uart", 0),
836 make_field("port", 0), 892 make_field("port", 0),
837 make_field("sysmgr", 0), 893 make_field("sysmgr", 0),
838 &v1, 0); 894 &v1, NULL);
839 *port = v1; 895 *port = v1;
840 return result; 896 return result;
841} 897}
@@ -856,6 +912,10 @@ int ps3_repository_read_boot_dat_info(u64 *lpar_addr, unsigned int *size)
856 : ps3_repository_read_boot_dat_size(size); 912 : ps3_repository_read_boot_dat_size(size);
857} 913}
858 914
915/**
916 * ps3_repository_read_num_be - Number of physical BE processors in the system.
917 */
918
859int ps3_repository_read_num_be(unsigned int *num_be) 919int ps3_repository_read_num_be(unsigned int *num_be)
860{ 920{
861 int result; 921 int result;
@@ -866,11 +926,17 @@ int ps3_repository_read_num_be(unsigned int *num_be)
866 0, 926 0,
867 0, 927 0,
868 0, 928 0,
869 &v1, 0); 929 &v1, NULL);
870 *num_be = v1; 930 *num_be = v1;
871 return result; 931 return result;
872} 932}
873 933
934/**
935 * ps3_repository_read_be_node_id - Read the physical BE processor node id.
936 * @be_index: Zero based index.
937 * @node_id: The BE processor node id.
938 */
939
874int ps3_repository_read_be_node_id(unsigned int be_index, u64 *node_id) 940int ps3_repository_read_be_node_id(unsigned int be_index, u64 *node_id)
875{ 941{
876 return read_node(PS3_LPAR_ID_PME, 942 return read_node(PS3_LPAR_ID_PME,
@@ -878,7 +944,23 @@ int ps3_repository_read_be_node_id(unsigned int be_index, u64 *node_id)
878 0, 944 0,
879 0, 945 0,
880 0, 946 0,
881 node_id, 0); 947 node_id, NULL);
948}
949
950/**
951 * ps3_repository_read_be_id - Read the physical BE processor id.
952 * @node_id: The BE processor node id.
953 * @be_id: The BE processor id.
954 */
955
956int ps3_repository_read_be_id(u64 node_id, u64 *be_id)
957{
958 return read_node(PS3_LPAR_ID_PME,
959 make_first_field("be", 0),
960 node_id,
961 0,
962 0,
963 be_id, NULL);
882} 964}
883 965
884int ps3_repository_read_tb_freq(u64 node_id, u64 *tb_freq) 966int ps3_repository_read_tb_freq(u64 node_id, u64 *tb_freq)
@@ -888,7 +970,7 @@ int ps3_repository_read_tb_freq(u64 node_id, u64 *tb_freq)
888 node_id, 970 node_id,
889 make_field("clock", 0), 971 make_field("clock", 0),
890 0, 972 0,
891 tb_freq, 0); 973 tb_freq, NULL);
892} 974}
893 975
894int ps3_repository_read_be_tb_freq(unsigned int be_index, u64 *tb_freq) 976int ps3_repository_read_be_tb_freq(unsigned int be_index, u64 *tb_freq)
@@ -897,11 +979,29 @@ int ps3_repository_read_be_tb_freq(unsigned int be_index, u64 *tb_freq)
897 u64 node_id; 979 u64 node_id;
898 980
899 *tb_freq = 0; 981 *tb_freq = 0;
900 result = ps3_repository_read_be_node_id(0, &node_id); 982 result = ps3_repository_read_be_node_id(be_index, &node_id);
901 return result ? result 983 return result ? result
902 : ps3_repository_read_tb_freq(node_id, tb_freq); 984 : ps3_repository_read_tb_freq(node_id, tb_freq);
903} 985}
904 986
987int ps3_repository_read_lpm_privileges(unsigned int be_index, u64 *lpar,
988 u64 *rights)
989{
990 int result;
991 u64 node_id;
992
993 *lpar = 0;
994 *rights = 0;
995 result = ps3_repository_read_be_node_id(be_index, &node_id);
996 return result ? result
997 : read_node(PS3_LPAR_ID_PME,
998 make_first_field("be", 0),
999 node_id,
1000 make_field("lpm", 0),
1001 make_field("priv", 0),
1002 lpar, rights);
1003}
1004
905#if defined(DEBUG) 1005#if defined(DEBUG)
906 1006
907int ps3_repository_dump_resource_info(const struct ps3_repository_device *repo) 1007int ps3_repository_dump_resource_info(const struct ps3_repository_device *repo)
@@ -1034,7 +1134,7 @@ static int dump_device_info(struct ps3_repository_device *repo,
1034 continue; 1134 continue;
1035 } 1135 }
1036 1136
1037 pr_debug("%s:%d (%u:%u): dev_type %u, dev_id %u\n", __func__, 1137 pr_debug("%s:%d (%u:%u): dev_type %u, dev_id %lu\n", __func__,
1038 __LINE__, repo->bus_index, repo->dev_index, 1138 __LINE__, repo->bus_index, repo->dev_index,
1039 repo->dev_type, repo->dev_id); 1139 repo->dev_type, repo->dev_id);
1040 1140
@@ -1091,7 +1191,7 @@ int ps3_repository_dump_bus_info(void)
1091 continue; 1191 continue;
1092 } 1192 }
1093 1193
1094 pr_debug("%s:%d bus_%u: bus_type %u, bus_id %u, num_dev %u\n", 1194 pr_debug("%s:%d bus_%u: bus_type %u, bus_id %lu, num_dev %u\n",
1095 __func__, __LINE__, repo.bus_index, repo.bus_type, 1195 __func__, __LINE__, repo.bus_index, repo.bus_type,
1096 repo.bus_id, num_dev); 1196 repo.bus_id, num_dev);
1097 1197
diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c
index 6405f4a36763..43c493fca2d0 100644
--- a/arch/powerpc/platforms/ps3/system-bus.c
+++ b/arch/powerpc/platforms/ps3/system-bus.c
@@ -42,8 +42,8 @@ struct {
42 int gpu; 42 int gpu;
43} static usage_hack; 43} static usage_hack;
44 44
45static int ps3_is_device(struct ps3_system_bus_device *dev, 45static int ps3_is_device(struct ps3_system_bus_device *dev, u64 bus_id,
46 unsigned int bus_id, unsigned int dev_id) 46 u64 dev_id)
47{ 47{
48 return dev->bus_id == bus_id && dev->dev_id == dev_id; 48 return dev->bus_id == bus_id && dev->dev_id == dev_id;
49} 49}
@@ -182,8 +182,8 @@ int ps3_open_hv_device(struct ps3_system_bus_device *dev)
182 case PS3_MATCH_ID_SYSTEM_MANAGER: 182 case PS3_MATCH_ID_SYSTEM_MANAGER:
183 pr_debug("%s:%d: unsupported match_id: %u\n", __func__, 183 pr_debug("%s:%d: unsupported match_id: %u\n", __func__,
184 __LINE__, dev->match_id); 184 __LINE__, dev->match_id);
185 pr_debug("%s:%d: bus_id: %u\n", __func__, 185 pr_debug("%s:%d: bus_id: %lu\n", __func__, __LINE__,
186 __LINE__, dev->bus_id); 186 dev->bus_id);
187 BUG(); 187 BUG();
188 return -EINVAL; 188 return -EINVAL;
189 189
@@ -220,8 +220,8 @@ int ps3_close_hv_device(struct ps3_system_bus_device *dev)
220 case PS3_MATCH_ID_SYSTEM_MANAGER: 220 case PS3_MATCH_ID_SYSTEM_MANAGER:
221 pr_debug("%s:%d: unsupported match_id: %u\n", __func__, 221 pr_debug("%s:%d: unsupported match_id: %u\n", __func__,
222 __LINE__, dev->match_id); 222 __LINE__, dev->match_id);
223 pr_debug("%s:%d: bus_id: %u\n", __func__, 223 pr_debug("%s:%d: bus_id: %lu\n", __func__, __LINE__,
224 __LINE__, dev->bus_id); 224 dev->bus_id);
225 BUG(); 225 BUG();
226 return -EINVAL; 226 return -EINVAL;
227 227
@@ -240,7 +240,7 @@ EXPORT_SYMBOL_GPL(ps3_close_hv_device);
240static void _dump_mmio_region(const struct ps3_mmio_region* r, 240static void _dump_mmio_region(const struct ps3_mmio_region* r,
241 const char* func, int line) 241 const char* func, int line)
242{ 242{
243 pr_debug("%s:%d: dev %u:%u\n", func, line, r->dev->bus_id, 243 pr_debug("%s:%d: dev %lu:%lu\n", func, line, r->dev->bus_id,
244 r->dev->dev_id); 244 r->dev->dev_id);
245 pr_debug("%s:%d: bus_addr %lxh\n", func, line, r->bus_addr); 245 pr_debug("%s:%d: bus_addr %lxh\n", func, line, r->bus_addr);
246 pr_debug("%s:%d: len %lxh\n", func, line, r->len); 246 pr_debug("%s:%d: len %lxh\n", func, line, r->len);
@@ -715,6 +715,7 @@ int ps3_system_bus_device_register(struct ps3_system_bus_device *dev)
715 static unsigned int dev_ioc0_count; 715 static unsigned int dev_ioc0_count;
716 static unsigned int dev_sb_count; 716 static unsigned int dev_sb_count;
717 static unsigned int dev_vuart_count; 717 static unsigned int dev_vuart_count;
718 static unsigned int dev_lpm_count;
718 719
719 if (!dev->core.parent) 720 if (!dev->core.parent)
720 dev->core.parent = &ps3_system_bus; 721 dev->core.parent = &ps3_system_bus;
@@ -737,6 +738,10 @@ int ps3_system_bus_device_register(struct ps3_system_bus_device *dev)
737 snprintf(dev->core.bus_id, sizeof(dev->core.bus_id), 738 snprintf(dev->core.bus_id, sizeof(dev->core.bus_id),
738 "vuart_%02x", ++dev_vuart_count); 739 "vuart_%02x", ++dev_vuart_count);
739 break; 740 break;
741 case PS3_DEVICE_TYPE_LPM:
742 snprintf(dev->core.bus_id, sizeof(dev->core.bus_id),
743 "lpm_%02x", ++dev_lpm_count);
744 break;
740 default: 745 default:
741 BUG(); 746 BUG();
742 }; 747 };
diff --git a/arch/powerpc/xmon/setjmp.S b/arch/powerpc/xmon/setjmp.S
index 96a91f10e2ec..04c0b305ad4a 100644
--- a/arch/powerpc/xmon/setjmp.S
+++ b/arch/powerpc/xmon/setjmp.S
@@ -12,67 +12,6 @@
12#include <asm/ppc_asm.h> 12#include <asm/ppc_asm.h>
13#include <asm/asm-offsets.h> 13#include <asm/asm-offsets.h>
14 14
15_GLOBAL(xmon_setjmp)
16 mflr r0
17 PPC_STL r0,0(r3)
18 PPC_STL r1,SZL(r3)
19 PPC_STL r2,2*SZL(r3)
20 mfcr r0
21 PPC_STL r0,3*SZL(r3)
22 PPC_STL r13,4*SZL(r3)
23 PPC_STL r14,5*SZL(r3)
24 PPC_STL r15,6*SZL(r3)
25 PPC_STL r16,7*SZL(r3)
26 PPC_STL r17,8*SZL(r3)
27 PPC_STL r18,9*SZL(r3)
28 PPC_STL r19,10*SZL(r3)
29 PPC_STL r20,11*SZL(r3)
30 PPC_STL r21,12*SZL(r3)
31 PPC_STL r22,13*SZL(r3)
32 PPC_STL r23,14*SZL(r3)
33 PPC_STL r24,15*SZL(r3)
34 PPC_STL r25,16*SZL(r3)
35 PPC_STL r26,17*SZL(r3)
36 PPC_STL r27,18*SZL(r3)
37 PPC_STL r28,19*SZL(r3)
38 PPC_STL r29,20*SZL(r3)
39 PPC_STL r30,21*SZL(r3)
40 PPC_STL r31,22*SZL(r3)
41 li r3,0
42 blr
43
44_GLOBAL(xmon_longjmp)
45 PPC_LCMPI r4,0
46 bne 1f
47 li r4,1
481: PPC_LL r13,4*SZL(r3)
49 PPC_LL r14,5*SZL(r3)
50 PPC_LL r15,6*SZL(r3)
51 PPC_LL r16,7*SZL(r3)
52 PPC_LL r17,8*SZL(r3)
53 PPC_LL r18,9*SZL(r3)
54 PPC_LL r19,10*SZL(r3)
55 PPC_LL r20,11*SZL(r3)
56 PPC_LL r21,12*SZL(r3)
57 PPC_LL r22,13*SZL(r3)
58 PPC_LL r23,14*SZL(r3)
59 PPC_LL r24,15*SZL(r3)
60 PPC_LL r25,16*SZL(r3)
61 PPC_LL r26,17*SZL(r3)
62 PPC_LL r27,18*SZL(r3)
63 PPC_LL r28,19*SZL(r3)
64 PPC_LL r29,20*SZL(r3)
65 PPC_LL r30,21*SZL(r3)
66 PPC_LL r31,22*SZL(r3)
67 PPC_LL r0,3*SZL(r3)
68 mtcrf 0x38,r0
69 PPC_LL r0,0(r3)
70 PPC_LL r1,SZL(r3)
71 PPC_LL r2,2*SZL(r3)
72 mtlr r0
73 mr r3,r4
74 blr
75
76/* 15/*
77 * Grab the register values as they are now. 16 * Grab the register values as they are now.
78 * This won't do a particularily good job because we really 17 * This won't do a particularily good job because we really
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index 865e36751f21..a34172ddc468 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -40,6 +40,7 @@
40#include <asm/spu.h> 40#include <asm/spu.h>
41#include <asm/spu_priv1.h> 41#include <asm/spu_priv1.h>
42#include <asm/firmware.h> 42#include <asm/firmware.h>
43#include <asm/setjmp.h>
43 44
44#ifdef CONFIG_PPC64 45#ifdef CONFIG_PPC64
45#include <asm/hvcall.h> 46#include <asm/hvcall.h>
@@ -71,12 +72,9 @@ static unsigned long ncsum = 4096;
71static int termch; 72static int termch;
72static char tmpstr[128]; 73static char tmpstr[128];
73 74
74#define JMP_BUF_LEN 23
75static long bus_error_jmp[JMP_BUF_LEN]; 75static long bus_error_jmp[JMP_BUF_LEN];
76static int catch_memory_errors; 76static int catch_memory_errors;
77static long *xmon_fault_jmp[NR_CPUS]; 77static long *xmon_fault_jmp[NR_CPUS];
78#define setjmp xmon_setjmp
79#define longjmp xmon_longjmp
80 78
81/* Breakpoint stuff */ 79/* Breakpoint stuff */
82struct bpt { 80struct bpt {
@@ -162,8 +160,6 @@ int xmon_no_auto_backtrace;
162extern void xmon_enter(void); 160extern void xmon_enter(void);
163extern void xmon_leave(void); 161extern void xmon_leave(void);
164 162
165extern long setjmp(long *);
166extern void longjmp(long *, long);
167extern void xmon_save_regs(struct pt_regs *); 163extern void xmon_save_regs(struct pt_regs *);
168 164
169#ifdef CONFIG_PPC64 165#ifdef CONFIG_PPC64