aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-16 20:58:08 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-16 20:58:08 -0400
commit489de30259e667d7bc47da9da44a0270b050cd97 (patch)
tree6807814f443fe2c5d041c3bc3fe3ca8d22a955ca /arch
parent1f1c2881f673671539b25686df463518d69c4649 (diff)
parentbf22f6fe2d72b4d7e9035be8ceb340414cf490e3 (diff)
Merge branch 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc
* 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc: (209 commits) [POWERPC] Create add_rtc() function to enable the RTC CMOS driver [POWERPC] Add H_ILLAN_ATTRIBUTES hcall number [POWERPC] xilinxfb: Parameterize xilinxfb platform device registration [POWERPC] Oprofile support for Power 5++ [POWERPC] Enable arbitary speed tty ioctls and split input/output speed [POWERPC] Make drivers/char/hvc_console.c:khvcd() static [POWERPC] Remove dead code for preventing pread() and pwrite() calls [POWERPC] Remove unnecessary #undef printk from prom.c [POWERPC] Fix typo in Ebony default DTS [POWERPC] Check for NULL ppc_md.init_IRQ() before calling [POWERPC] Remove extra return statement [POWERPC] pasemi: Don't auto-select CONFIG_EMBEDDED [POWERPC] pasemi: Rename platform [POWERPC] arch/powerpc/kernel/sysfs.c: Move NUMA exports [POWERPC] Add __read_mostly support for powerpc [POWERPC] Modify sched_clock() to make CONFIG_PRINTK_TIME more sane [POWERPC] Create a dummy zImage if no valid platform has been selected [POWERPC] PS3: Bootwrapper support. [POWERPC] powermac i2c: Use mutex [POWERPC] Schedule removal of arch/ppc ... Fixed up conflicts manually in: Documentation/feature-removal-schedule.txt arch/powerpc/kernel/pci_32.c arch/powerpc/kernel/pci_64.c include/asm-powerpc/pci.h and asked the powerpc people to double-check the result..
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/Kconfig267
-rw-r--r--arch/powerpc/Makefile2
-rw-r--r--arch/powerpc/boot/44x.c45
-rw-r--r--arch/powerpc/boot/44x.h3
-rw-r--r--arch/powerpc/boot/Makefile81
-rw-r--r--arch/powerpc/boot/cuboot-83xx.c13
-rw-r--r--arch/powerpc/boot/cuboot-85xx.c13
-rw-r--r--arch/powerpc/boot/cuboot-ebony.c16
-rw-r--r--arch/powerpc/boot/cuboot.c35
-rw-r--r--arch/powerpc/boot/cuboot.h14
-rw-r--r--arch/powerpc/boot/dcr.h37
-rw-r--r--arch/powerpc/boot/dts/ebony.dts12
-rw-r--r--arch/powerpc/boot/dts/holly.dts52
-rw-r--r--arch/powerpc/boot/dts/mpc7448hpc2.dts33
-rw-r--r--arch/powerpc/boot/dts/mpc8272ads.dts42
-rw-r--r--arch/powerpc/boot/dts/mpc832x_mds.dts16
-rw-r--r--arch/powerpc/boot/dts/mpc832x_rdb.dts16
-rw-r--r--arch/powerpc/boot/dts/mpc8349emitx.dts10
-rw-r--r--arch/powerpc/boot/dts/mpc834x_mds.dts10
-rw-r--r--arch/powerpc/boot/dts/mpc836x_mds.dts16
-rw-r--r--arch/powerpc/boot/dts/mpc8540ads.dts147
-rw-r--r--arch/powerpc/boot/dts/mpc8541cds.dts90
-rw-r--r--arch/powerpc/boot/dts/mpc8544ds.dts18
-rw-r--r--arch/powerpc/boot/dts/mpc8548cds.dts108
-rw-r--r--arch/powerpc/boot/dts/mpc8555cds.dts90
-rw-r--r--arch/powerpc/boot/dts/mpc8560ads.dts148
-rw-r--r--arch/powerpc/boot/dts/mpc8568mds.dts66
-rw-r--r--arch/powerpc/boot/dts/mpc8641_hpcn.dts147
-rw-r--r--arch/powerpc/boot/dts/mpc866ads.dts31
-rw-r--r--arch/powerpc/boot/dts/mpc885ads.dts54
-rw-r--r--arch/powerpc/boot/dts/prpmc2800.dts2
-rw-r--r--arch/powerpc/boot/dts/ps3.dts68
-rw-r--r--arch/powerpc/boot/ebony.c19
-rw-r--r--arch/powerpc/boot/main.c2
-rw-r--r--arch/powerpc/boot/of.c212
-rw-r--r--arch/powerpc/boot/of.h21
-rw-r--r--arch/powerpc/boot/ofconsole.c45
-rw-r--r--arch/powerpc/boot/oflib.c202
-rw-r--r--arch/powerpc/boot/ops.h4
-rw-r--r--arch/powerpc/boot/ps3-head.S80
-rw-r--r--arch/powerpc/boot/ps3-hvcall.S184
-rw-r--r--arch/powerpc/boot/ps3.c161
-rw-r--r--arch/powerpc/boot/serial.c2
-rw-r--r--arch/powerpc/boot/stdio.c10
-rw-r--r--arch/powerpc/boot/types.h4
-rwxr-xr-xarch/powerpc/boot/wrapper55
-rw-r--r--arch/powerpc/boot/zImage.ps3.lds.S50
-rw-r--r--arch/powerpc/configs/holly_defconfig6
-rw-r--r--arch/powerpc/configs/ps3_defconfig52
-rw-r--r--arch/powerpc/kernel/Makefile7
-rw-r--r--arch/powerpc/kernel/cputable.c35
-rw-r--r--arch/powerpc/kernel/head_32.S122
-rw-r--r--arch/powerpc/kernel/head_64.S4
-rw-r--r--arch/powerpc/kernel/io.c12
-rw-r--r--arch/powerpc/kernel/irq.c60
-rw-r--r--arch/powerpc/kernel/isa-bridge.c271
-rw-r--r--arch/powerpc/kernel/misc_32.S10
-rw-r--r--arch/powerpc/kernel/misc_64.S26
-rw-r--r--arch/powerpc/kernel/of_platform.c8
-rw-r--r--arch/powerpc/kernel/pci-common.c454
-rw-r--r--arch/powerpc/kernel/pci_32.c510
-rw-r--r--arch/powerpc/kernel/pci_64.c750
-rw-r--r--arch/powerpc/kernel/ppc_ksyms.c5
-rw-r--r--arch/powerpc/kernel/process.c14
-rw-r--r--arch/powerpc/kernel/prom.c29
-rw-r--r--arch/powerpc/kernel/prom_init.c4
-rw-r--r--arch/powerpc/kernel/ptrace-common.h161
-rw-r--r--arch/powerpc/kernel/ptrace.c325
-rw-r--r--arch/powerpc/kernel/ptrace32.c239
-rw-r--r--arch/powerpc/kernel/rtas_pci.c7
-rw-r--r--arch/powerpc/kernel/setup-common.c21
-rw-r--r--arch/powerpc/kernel/setup_32.c12
-rw-r--r--arch/powerpc/kernel/setup_64.c12
-rw-r--r--arch/powerpc/kernel/signal.c180
-rw-r--r--arch/powerpc/kernel/signal.h55
-rw-r--r--arch/powerpc/kernel/signal_32.c191
-rw-r--r--arch/powerpc/kernel/signal_64.c182
-rw-r--r--arch/powerpc/kernel/sysfs.c5
-rw-r--r--arch/powerpc/kernel/time.c65
-rw-r--r--arch/powerpc/kernel/vdso.c2
-rw-r--r--arch/powerpc/kernel/vmlinux.lds.S6
-rw-r--r--arch/powerpc/mm/44x_mmu.c1
-rw-r--r--arch/powerpc/mm/4xx_mmu.c1
-rw-r--r--arch/powerpc/mm/Makefile3
-rw-r--r--arch/powerpc/mm/fault.c2
-rw-r--r--arch/powerpc/mm/fsl_booke_mmu.c1
-rw-r--r--arch/powerpc/mm/hash_native_64.c27
-rw-r--r--arch/powerpc/mm/hash_utils_64.c2
-rw-r--r--arch/powerpc/mm/imalloc.c313
-rw-r--r--arch/powerpc/mm/init_32.c1
-rw-r--r--arch/powerpc/mm/init_64.c1
-rw-r--r--arch/powerpc/mm/mem.c3
-rw-r--r--arch/powerpc/mm/mmu_context_32.c1
-rw-r--r--arch/powerpc/mm/mmu_decl.h17
-rw-r--r--arch/powerpc/mm/pgtable_32.c123
-rw-r--r--arch/powerpc/mm/pgtable_64.c206
-rw-r--r--arch/powerpc/mm/ppc_mmu_32.c7
-rw-r--r--arch/powerpc/mm/stab.c4
-rw-r--r--arch/powerpc/mm/tlb_32.c1
-rw-r--r--arch/powerpc/mm/tlb_64.c57
-rw-r--r--arch/powerpc/oprofile/op_model_power4.c14
-rw-r--r--arch/powerpc/platforms/52xx/efika.c13
-rw-r--r--arch/powerpc/platforms/52xx/lite5200.c2
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_pci.c18
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_pm.c8
-rw-r--r--arch/powerpc/platforms/82xx/Kconfig2
-rw-r--r--arch/powerpc/platforms/82xx/mpc82xx_ads.c17
-rw-r--r--arch/powerpc/platforms/83xx/Kconfig2
-rw-r--r--arch/powerpc/platforms/83xx/Makefile2
-rw-r--r--arch/powerpc/platforms/83xx/mpc8313_rdb.c8
-rw-r--r--arch/powerpc/platforms/83xx/mpc832x_mds.c7
-rw-r--r--arch/powerpc/platforms/83xx/mpc832x_rdb.c7
-rw-r--r--arch/powerpc/platforms/83xx/mpc834x_itx.c9
-rw-r--r--arch/powerpc/platforms/83xx/mpc834x_mds.c56
-rw-r--r--arch/powerpc/platforms/83xx/mpc836x_mds.c7
-rw-r--r--arch/powerpc/platforms/83xx/mpc83xx.h34
-rw-r--r--arch/powerpc/platforms/83xx/pci.c18
-rw-r--r--arch/powerpc/platforms/83xx/usb.c181
-rw-r--r--arch/powerpc/platforms/85xx/misc.c32
-rw-r--r--arch/powerpc/platforms/85xx/mpc8544_ds.c15
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx.h2
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_ads.c32
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_cds.c116
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_mds.c28
-rw-r--r--arch/powerpc/platforms/85xx/pci.c11
-rw-r--r--arch/powerpc/platforms/86xx/Kconfig2
-rw-r--r--arch/powerpc/platforms/86xx/mpc86xx.h11
-rw-r--r--arch/powerpc/platforms/86xx/mpc86xx_hpcn.c27
-rw-r--r--arch/powerpc/platforms/86xx/pci.c67
-rw-r--r--arch/powerpc/platforms/8xx/m8xx_setup.c5
-rw-r--r--arch/powerpc/platforms/8xx/mpc885ads_setup.c71
-rw-r--r--arch/powerpc/platforms/Kconfig29
-rw-r--r--arch/powerpc/platforms/Kconfig.cputype221
-rw-r--r--arch/powerpc/platforms/apus/Kconfig130
-rw-r--r--arch/powerpc/platforms/cell/io-workarounds.c2
-rw-r--r--arch/powerpc/platforms/cell/spu_base.c59
-rw-r--r--arch/powerpc/platforms/cell/spufs/backing_ops.c6
-rw-r--r--arch/powerpc/platforms/cell/spufs/context.c15
-rw-r--r--arch/powerpc/platforms/cell/spufs/fault.c29
-rw-r--r--arch/powerpc/platforms/cell/spufs/file.c149
-rw-r--r--arch/powerpc/platforms/cell/spufs/inode.c10
-rw-r--r--arch/powerpc/platforms/cell/spufs/run.c45
-rw-r--r--arch/powerpc/platforms/cell/spufs/sched.c476
-rw-r--r--arch/powerpc/platforms/cell/spufs/spu_restore.c2
-rw-r--r--arch/powerpc/platforms/cell/spufs/spu_save.c2
-rw-r--r--arch/powerpc/platforms/cell/spufs/spufs.h84
-rw-r--r--arch/powerpc/platforms/cell/spufs/switch.c18
-rw-r--r--arch/powerpc/platforms/chrp/Kconfig1
-rw-r--r--arch/powerpc/platforms/chrp/Makefile3
-rw-r--r--arch/powerpc/platforms/chrp/pci.c7
-rw-r--r--arch/powerpc/platforms/embedded6xx/Kconfig2
-rw-r--r--arch/powerpc/platforms/embedded6xx/holly.c2
-rw-r--r--arch/powerpc/platforms/embedded6xx/linkstation.c10
-rw-r--r--arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c9
-rw-r--r--arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.h5
-rw-r--r--arch/powerpc/platforms/iseries/call_hpt.h9
-rw-r--r--arch/powerpc/platforms/iseries/htab.c8
-rw-r--r--arch/powerpc/platforms/iseries/pci.c7
-rw-r--r--arch/powerpc/platforms/iseries/setup.c6
-rw-r--r--arch/powerpc/platforms/maple/pci.c41
-rw-r--r--arch/powerpc/platforms/pasemi/Kconfig9
-rw-r--r--arch/powerpc/platforms/pasemi/Makefile1
-rw-r--r--arch/powerpc/platforms/pasemi/electra_ide.c96
-rw-r--r--arch/powerpc/platforms/pasemi/pci.c24
-rw-r--r--arch/powerpc/platforms/pasemi/setup.c2
-rw-r--r--arch/powerpc/platforms/powermac/Kconfig1
-rw-r--r--arch/powerpc/platforms/powermac/low_i2c.c23
-rw-r--r--arch/powerpc/platforms/powermac/pci.c46
-rw-r--r--arch/powerpc/platforms/ps3/Kconfig26
-rw-r--r--arch/powerpc/platforms/ps3/Makefile1
-rw-r--r--arch/powerpc/platforms/ps3/device-init.c785
-rw-r--r--arch/powerpc/platforms/ps3/htab.c31
-rw-r--r--arch/powerpc/platforms/ps3/interrupt.c272
-rw-r--r--arch/powerpc/platforms/ps3/mm.c632
-rw-r--r--arch/powerpc/platforms/ps3/os-area.c4
-rw-r--r--arch/powerpc/platforms/ps3/platform.h43
-rw-r--r--arch/powerpc/platforms/ps3/repository.c586
-rw-r--r--arch/powerpc/platforms/ps3/setup.c105
-rw-r--r--arch/powerpc/platforms/ps3/smp.c18
-rw-r--r--arch/powerpc/platforms/ps3/spu.c13
-rw-r--r--arch/powerpc/platforms/ps3/system-bus.c562
-rw-r--r--arch/powerpc/platforms/ps3/time.c2
-rw-r--r--arch/powerpc/platforms/pseries/Makefile2
-rw-r--r--arch/powerpc/platforms/pseries/eeh.c19
-rw-r--r--arch/powerpc/platforms/pseries/eeh_cache.c5
-rw-r--r--arch/powerpc/platforms/pseries/eeh_driver.c6
-rw-r--r--arch/powerpc/platforms/pseries/eeh_sysfs.c87
-rw-r--r--arch/powerpc/platforms/pseries/lpar.c17
-rw-r--r--arch/powerpc/platforms/pseries/pci_dlpar.c9
-rw-r--r--arch/powerpc/platforms/pseries/plpar_wrappers.h15
-rw-r--r--arch/powerpc/platforms/pseries/pseries.h2
-rw-r--r--arch/powerpc/platforms/pseries/reconfig.c2
-rw-r--r--arch/powerpc/platforms/pseries/setup.c2
-rw-r--r--arch/powerpc/platforms/pseries/xics.c53
-rw-r--r--arch/powerpc/sysdev/Makefile6
-rw-r--r--arch/powerpc/sysdev/fsl_pcie.c171
-rw-r--r--arch/powerpc/sysdev/fsl_soc.c13
-rw-r--r--arch/powerpc/sysdev/indirect_pci.c44
-rw-r--r--arch/powerpc/sysdev/mpc8xx_pic.h11
-rw-r--r--arch/powerpc/sysdev/mv64x60_dev.c28
-rw-r--r--arch/powerpc/sysdev/mv64x60_pci.c7
-rw-r--r--arch/powerpc/sysdev/qe_lib/ucc.c2
-rw-r--r--arch/powerpc/sysdev/qe_lib/ucc_fast.c8
-rw-r--r--arch/powerpc/sysdev/rtc_cmos_setup.c49
-rw-r--r--arch/powerpc/sysdev/timer.c14
-rw-r--r--arch/powerpc/sysdev/tsi108_dev.c33
-rw-r--r--arch/powerpc/sysdev/tsi108_pci.c10
-rw-r--r--arch/powerpc/xmon/xmon.c2
-rw-r--r--arch/ppc/kernel/misc.S8
-rw-r--r--arch/ppc/kernel/ppc_ksyms.c1
-rw-r--r--arch/ppc/kernel/setup.c2
-rw-r--r--arch/ppc/mm/tlb.c1
-rw-r--r--arch/ppc/platforms/prep_setup.c3
-rw-r--r--arch/ppc/syslib/Makefile1
-rw-r--r--arch/ppc/syslib/indirect_pci.c134
-rw-r--r--arch/ppc/syslib/virtex_devices.c38
216 files changed, 8153 insertions, 5511 deletions
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 6b8b83ebca75..e641bb68d871 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -4,17 +4,7 @@
4 4
5mainmenu "Linux/PowerPC Kernel Configuration" 5mainmenu "Linux/PowerPC Kernel Configuration"
6 6
7config PPC64 7source "arch/powerpc/platforms/Kconfig.cputype"
8 bool "64-bit kernel"
9 default n
10 help
11 This option selects whether a 32-bit or a 64-bit kernel
12 will be built.
13
14config PPC_PM_NEEDS_RTC_LIB
15 bool
16 select RTC_LIB
17 default y if PM
18 8
19config PPC32 9config PPC32
20 bool 10 bool
@@ -135,123 +125,6 @@ config PPC64_SWSUSP
135 depends on PPC64 && (BROKEN || (PPC_PMAC64 && EXPERIMENTAL)) 125 depends on PPC64 && (BROKEN || (PPC_PMAC64 && EXPERIMENTAL))
136 default y 126 default y
137 127
138menu "Processor support"
139choice
140 prompt "Processor Type"
141 depends on PPC32
142 default 6xx
143
144config CLASSIC32
145 bool "52xx/6xx/7xx/74xx"
146 select PPC_FPU
147 select 6xx
148 help
149 There are four families of PowerPC chips supported. The more common
150 types (601, 603, 604, 740, 750, 7400), the Motorola embedded
151 versions (821, 823, 850, 855, 860, 52xx, 82xx, 83xx), the AMCC
152 embedded versions (403 and 405) and the high end 64 bit Power
153 processors (POWER 3, POWER4, and IBM PPC970 also known as G5).
154
155 This option is the catch-all for 6xx types, including some of the
156 embedded versions. Unless there is see an option for the specific
157 chip family you are using, you want this option.
158
159 You do not want this if you are building a kernel for a 64 bit
160 IBM RS/6000 or an Apple G5, choose 6xx.
161
162 If unsure, select this option
163
164 Note that the kernel runs in 32-bit mode even on 64-bit chips.
165
166config PPC_82xx
167 bool "Freescale 82xx"
168 select 6xx
169 select PPC_FPU
170
171config PPC_83xx
172 bool "Freescale 83xx"
173 select 6xx
174 select FSL_SOC
175 select 83xx
176 select PPC_FPU
177 select WANT_DEVICE_TREE
178
179config PPC_85xx
180 bool "Freescale 85xx"
181 select E500
182 select FSL_SOC
183 select 85xx
184 select WANT_DEVICE_TREE
185
186config PPC_86xx
187 bool "Freescale 86xx"
188 select 6xx
189 select FSL_SOC
190 select FSL_PCIE
191 select PPC_FPU
192 select ALTIVEC
193 help
194 The Freescale E600 SoCs have 74xx cores.
195
196config PPC_8xx
197 bool "Freescale 8xx"
198 select FSL_SOC
199 select 8xx
200
201config 40x
202 bool "AMCC 40x"
203 select PPC_DCR_NATIVE
204
205config 44x
206 bool "AMCC 44x"
207 select PPC_DCR_NATIVE
208 select WANT_DEVICE_TREE
209
210config E200
211 bool "Freescale e200"
212
213endchoice
214
215config POWER4_ONLY
216 bool "Optimize for POWER4"
217 depends on PPC64
218 default n
219 ---help---
220 Cause the compiler to optimize for POWER4/POWER5/PPC970 processors.
221 The resulting binary will not work on POWER3 or RS64 processors
222 when compiled with binutils 2.15 or later.
223
224config POWER3
225 bool
226 depends on PPC64
227 default y if !POWER4_ONLY
228
229config POWER4
230 depends on PPC64
231 def_bool y
232
233config 6xx
234 bool
235
236# this is temp to handle compat with arch=ppc
237config 8xx
238 bool
239
240# this is temp to handle compat with arch=ppc
241config 83xx
242 bool
243
244# this is temp to handle compat with arch=ppc
245config 85xx
246 bool
247
248config E500
249 bool
250
251config PPC_FPU
252 bool
253 default y if PPC64
254
255config PPC_DCR_NATIVE 128config PPC_DCR_NATIVE
256 bool 129 bool
257 default n 130 default n
@@ -270,134 +143,6 @@ config PPC_OF_PLATFORM_PCI
270 depends on PPC64 # not supported on 32 bits yet 143 depends on PPC64 # not supported on 32 bits yet
271 default n 144 default n
272 145
273config 4xx
274 bool
275 depends on 40x || 44x
276 default y
277
278config BOOKE
279 bool
280 depends on E200 || E500 || 44x
281 default y
282
283config FSL_BOOKE
284 bool
285 depends on E200 || E500
286 default y
287
288config PTE_64BIT
289 bool
290 depends on 44x || E500
291 default y if 44x
292 default y if E500 && PHYS_64BIT
293
294config PHYS_64BIT
295 bool 'Large physical address support' if E500
296 depends on 44x || E500
297 select RESOURCES_64BIT
298 default y if 44x
299 ---help---
300 This option enables kernel support for larger than 32-bit physical
301 addresses. This features is not be available on all e500 cores.
302
303 If in doubt, say N here.
304
305config ALTIVEC
306 bool "AltiVec Support"
307 depends on CLASSIC32 || POWER4
308 ---help---
309 This option enables kernel support for the Altivec extensions to the
310 PowerPC processor. The kernel currently supports saving and restoring
311 altivec registers, and turning on the 'altivec enable' bit so user
312 processes can execute altivec instructions.
313
314 This option is only usefully if you have a processor that supports
315 altivec (G4, otherwise known as 74xx series), but does not have
316 any affect on a non-altivec cpu (it does, however add code to the
317 kernel).
318
319 If in doubt, say Y here.
320
321config SPE
322 bool "SPE Support"
323 depends on E200 || E500
324 default y
325 ---help---
326 This option enables kernel support for the Signal Processing
327 Extensions (SPE) to the PowerPC processor. The kernel currently
328 supports saving and restoring SPE registers, and turning on the
329 'spe enable' bit so user processes can execute SPE instructions.
330
331 This option is only useful if you have a processor that supports
332 SPE (e500, otherwise known as 85xx series), but does not have any
333 effect on a non-spe cpu (it does, however add code to the kernel).
334
335 If in doubt, say Y here.
336
337config PPC_STD_MMU
338 bool
339 depends on 6xx || POWER3 || POWER4 || PPC64
340 default y
341
342config PPC_STD_MMU_32
343 def_bool y
344 depends on PPC_STD_MMU && PPC32
345
346config PPC_MM_SLICES
347 bool
348 default y if HUGETLB_PAGE
349 default n
350
351config VIRT_CPU_ACCOUNTING
352 bool "Deterministic task and CPU time accounting"
353 depends on PPC64
354 default y
355 help
356 Select this option to enable more accurate task and CPU time
357 accounting. This is done by reading a CPU counter on each
358 kernel entry and exit and on transitions within the kernel
359 between system, softirq and hardirq state, so there is a
360 small performance impact. This also enables accounting of
361 stolen time on logically-partitioned systems running on
362 IBM POWER5-based machines.
363
364 If in doubt, say Y here.
365
366config SMP
367 depends on PPC_STD_MMU
368 bool "Symmetric multi-processing support"
369 ---help---
370 This enables support for systems with more than one CPU. If you have
371 a system with only one CPU, say N. If you have a system with more
372 than one CPU, say Y. Note that the kernel does not currently
373 support SMP machines with 603/603e/603ev or PPC750 ("G3") processors
374 since they have inadequate hardware support for multiprocessor
375 operation.
376
377 If you say N here, the kernel will run on single and multiprocessor
378 machines, but will use only one CPU of a multiprocessor machine. If
379 you say Y here, the kernel will run on single-processor machines.
380 On a single-processor machine, the kernel will run faster if you say
381 N here.
382
383 If you don't know what to do here, say N.
384
385config NR_CPUS
386 int "Maximum number of CPUs (2-128)"
387 range 2 128
388 depends on SMP
389 default "32" if PPC64
390 default "4"
391
392config NOT_COHERENT_CACHE
393 bool
394 depends on 4xx || 8xx || E200
395 default y
396
397config CONFIG_CHECK_CACHE_COHERENCY
398 bool
399endmenu
400
401source "init/Kconfig" 146source "init/Kconfig"
402 147
403source "arch/powerpc/platforms/Kconfig" 148source "arch/powerpc/platforms/Kconfig"
@@ -677,10 +422,6 @@ config SBUS
677config FSL_SOC 422config FSL_SOC
678 bool 423 bool
679 424
680config FSL_PCIE
681 bool
682 depends on PPC_86xx
683
684# Yes MCA RS/6000s exist but Linux-PPC does not currently support any 425# Yes MCA RS/6000s exist but Linux-PPC does not currently support any
685config MCA 426config MCA
686 bool 427 bool
@@ -688,10 +429,10 @@ config MCA
688config PCI 429config PCI
689 bool "PCI support" if 40x || CPM2 || PPC_83xx || PPC_85xx || PPC_86xx \ 430 bool "PCI support" if 40x || CPM2 || PPC_83xx || PPC_85xx || PPC_86xx \
690 || PPC_MPC52xx || (EMBEDDED && (PPC_PSERIES || PPC_ISERIES)) \ 431 || PPC_MPC52xx || (EMBEDDED && (PPC_PSERIES || PPC_ISERIES)) \
691 || MPC7448HPC2 || PPC_PS3 || PPC_HOLLY 432 || PPC_PS3
692 default y if !40x && !CPM2 && !8xx && !APUS && !PPC_83xx \ 433 default y if !40x && !CPM2 && !8xx && !PPC_83xx \
693 && !PPC_85xx && !PPC_86xx 434 && !PPC_85xx && !PPC_86xx
694 default PCI_PERMEDIA if !4xx && !CPM2 && !8xx && APUS 435 default PCI_PERMEDIA if !4xx && !CPM2 && !8xx
695 default PCI_QSPAN if !4xx && !CPM2 && 8xx 436 default PCI_QSPAN if !4xx && !CPM2 && 8xx
696 select ARCH_SUPPORTS_MSI 437 select ARCH_SUPPORTS_MSI
697 help 438 help
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
index fbafd965dcd2..187a39af3e1c 100644
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -148,7 +148,7 @@ all: $(KBUILD_IMAGE)
148 148
149CPPFLAGS_vmlinux.lds := -Upowerpc 149CPPFLAGS_vmlinux.lds := -Upowerpc
150 150
151BOOT_TARGETS = zImage zImage.initrd zImage.dts zImage.dts_initrd uImage 151BOOT_TARGETS = zImage zImage.initrd uImage
152 152
153PHONY += $(BOOT_TARGETS) 153PHONY += $(BOOT_TARGETS)
154 154
diff --git a/arch/powerpc/boot/44x.c b/arch/powerpc/boot/44x.c
index d51377d9024f..9f64e840bef6 100644
--- a/arch/powerpc/boot/44x.c
+++ b/arch/powerpc/boot/44x.c
@@ -38,3 +38,48 @@ void ibm44x_fixup_memsize(void)
38 38
39 dt_fixup_memory(0, memsize); 39 dt_fixup_memory(0, memsize);
40} 40}
41
42#define SPRN_DBCR0 0x134
43#define DBCR0_RST_SYSTEM 0x30000000
44
45void ibm44x_dbcr_reset(void)
46{
47 unsigned long tmp;
48
49 asm volatile (
50 "mfspr %0,%1\n"
51 "oris %0,%0,%2@h\n"
52 "mtspr %1,%0"
53 : "=&r"(tmp) : "i"(SPRN_DBCR0), "i"(DBCR0_RST_SYSTEM)
54 );
55
56}
57
58/* Read 4xx EBC bus bridge registers to get mappings of the peripheral
59 * banks into the OPB address space */
60void ibm4xx_fixup_ebc_ranges(const char *ebc)
61{
62 void *devp;
63 u32 bxcr;
64 u32 ranges[EBC_NUM_BANKS*4];
65 u32 *p = ranges;
66 int i;
67
68 for (i = 0; i < EBC_NUM_BANKS; i++) {
69 mtdcr(DCRN_EBC0_CFGADDR, EBC_BXCR(i));
70 bxcr = mfdcr(DCRN_EBC0_CFGDATA);
71
72 if ((bxcr & EBC_BXCR_BU) != EBC_BXCR_BU_OFF) {
73 *p++ = i;
74 *p++ = 0;
75 *p++ = bxcr & EBC_BXCR_BAS;
76 *p++ = EBC_BXCR_BANK_SIZE(bxcr);
77 }
78 }
79
80 devp = finddevice(ebc);
81 if (! devp)
82 fatal("Couldn't locate EBC node %s\n\r", ebc);
83
84 setprop(devp, "ranges", ranges, (p - ranges) * sizeof(u32));
85}
diff --git a/arch/powerpc/boot/44x.h b/arch/powerpc/boot/44x.h
index 7b129ad043e1..577982c9a3cd 100644
--- a/arch/powerpc/boot/44x.h
+++ b/arch/powerpc/boot/44x.h
@@ -11,6 +11,9 @@
11#define _PPC_BOOT_44X_H_ 11#define _PPC_BOOT_44X_H_
12 12
13void ibm44x_fixup_memsize(void); 13void ibm44x_fixup_memsize(void);
14void ibm4xx_fixup_ebc_ranges(const char *ebc);
15
16void ibm44x_dbcr_reset(void);
14void ebony_init(void *mac0, void *mac1); 17void ebony_init(void *mac0, void *mac1);
15 18
16#endif /* _PPC_BOOT_44X_H_ */ 19#endif /* _PPC_BOOT_44X_H_ */
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index ff2701949ee1..61a6f34ca5ed 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -43,10 +43,11 @@ $(addprefix $(obj)/,$(zlib) gunzip_util.o main.o): \
43 43
44src-wlib := string.S crt0.S stdio.c main.c flatdevtree.c flatdevtree_misc.c \ 44src-wlib := string.S crt0.S stdio.c main.c flatdevtree.c flatdevtree_misc.c \
45 ns16550.c serial.c simple_alloc.c div64.S util.S \ 45 ns16550.c serial.c simple_alloc.c div64.S util.S \
46 gunzip_util.c elf_util.c $(zlib) devtree.c \ 46 gunzip_util.c elf_util.c $(zlib) devtree.c oflib.c ofconsole.c \
47 44x.c ebony.c mv64x60.c mpsc.c mv64x60_i2c.c 47 44x.c ebony.c mv64x60.c mpsc.c mv64x60_i2c.c cuboot.c
48src-plat := of.c cuboot-83xx.c cuboot-85xx.c holly.c \ 48src-plat := of.c cuboot-83xx.c cuboot-85xx.c holly.c \
49 cuboot-ebony.c treeboot-ebony.c prpmc2800.c 49 cuboot-ebony.c treeboot-ebony.c prpmc2800.c \
50 ps3-head.S ps3-hvcall.S ps3.c
50src-boot := $(src-wlib) $(src-plat) empty.c 51src-boot := $(src-wlib) $(src-plat) empty.c
51 52
52src-boot := $(addprefix $(obj)/, $(src-boot)) 53src-boot := $(addprefix $(obj)/, $(src-boot))
@@ -75,11 +76,11 @@ $(addprefix $(obj)/,$(zliblinuxheader)): $(obj)/%: $(srctree)/include/linux/%
75$(obj)/empty.c: 76$(obj)/empty.c:
76 @touch $@ 77 @touch $@
77 78
78$(obj)/zImage.lds $(obj)/zImage.coff.lds: $(obj)/%: $(srctree)/$(src)/%.S 79$(obj)/zImage.lds $(obj)/zImage.coff.lds $(obj)/zImage.ps3.lds: $(obj)/%: $(srctree)/$(src)/%.S
79 @cp $< $@ 80 @cp $< $@
80 81
81clean-files := $(zlib) $(zlibheader) $(zliblinuxheader) \ 82clean-files := $(zlib) $(zlibheader) $(zliblinuxheader) \
82 empty.c zImage.coff.lds zImage.lds 83 empty.c zImage zImage.coff.lds zImage.ps3.lds zImage.lds
83 84
84quiet_cmd_bootcc = BOOTCC $@ 85quiet_cmd_bootcc = BOOTCC $@
85 cmd_bootcc = $(CROSS32CC) -Wp,-MD,$(depfile) $(BOOTCFLAGS) -c -o $@ $< 86 cmd_bootcc = $(CROSS32CC) -Wp,-MD,$(depfile) $(BOOTCFLAGS) -c -o $@ $<
@@ -102,7 +103,7 @@ hostprogs-y := addnote addRamDisk hack-coff mktree
102 103
103targets += $(patsubst $(obj)/%,%,$(obj-boot) wrapper.a) 104targets += $(patsubst $(obj)/%,%,$(obj-boot) wrapper.a)
104extra-y := $(obj)/wrapper.a $(obj-plat) $(obj)/empty.o \ 105extra-y := $(obj)/wrapper.a $(obj-plat) $(obj)/empty.o \
105 $(obj)/zImage.lds $(obj)/zImage.coff.lds 106 $(obj)/zImage.lds $(obj)/zImage.coff.lds $(obj)/zImage.ps3.lds
106 107
107wrapper :=$(srctree)/$(src)/wrapper 108wrapper :=$(srctree)/$(src)/wrapper
108wrapperbits := $(extra-y) $(addprefix $(obj)/,addnote hack-coff mktree) \ 109wrapperbits := $(extra-y) $(addprefix $(obj)/,addnote hack-coff mktree) \
@@ -132,7 +133,7 @@ image-$(CONFIG_PPC_CELLEB) += zImage.pseries
132image-$(CONFIG_PPC_CHRP) += zImage.chrp 133image-$(CONFIG_PPC_CHRP) += zImage.chrp
133image-$(CONFIG_PPC_EFIKA) += zImage.chrp 134image-$(CONFIG_PPC_EFIKA) += zImage.chrp
134image-$(CONFIG_PPC_PMAC) += zImage.pmac 135image-$(CONFIG_PPC_PMAC) += zImage.pmac
135image-$(CONFIG_PPC_HOLLY) += zImage.holly-elf 136image-$(CONFIG_PPC_HOLLY) += zImage.holly
136image-$(CONFIG_PPC_PRPMC2800) += zImage.prpmc2800 137image-$(CONFIG_PPC_PRPMC2800) += zImage.prpmc2800
137image-$(CONFIG_PPC_ISERIES) += zImage.iseries 138image-$(CONFIG_PPC_ISERIES) += zImage.iseries
138image-$(CONFIG_DEFAULT_UIMAGE) += uImage 139image-$(CONFIG_DEFAULT_UIMAGE) += uImage
@@ -157,55 +158,43 @@ targets += $(image-y) $(initrd-y)
157 158
158$(addprefix $(obj)/, $(initrd-y)): $(obj)/ramdisk.image.gz 159$(addprefix $(obj)/, $(initrd-y)): $(obj)/ramdisk.image.gz
159 160
160dts- := $(patsubst zImage%, zImage.dts%, $(image-n) $(image-)) 161# If CONFIG_WANT_DEVICE_TREE is set and CONFIG_DEVICE_TREE isn't an
161dts-y := $(patsubst zImage%, zImage.dts%, $(image-y)) 162# empty string, define 'dts' to be path to the dts
162dts-y := $(filter-out $(image-y), $(dts-y)) 163# CONFIG_DEVICE_TREE will have "" around it, make sure to strip them
163targets += $(image-y) $(dts-y) 164ifeq ($(CONFIG_WANT_DEVICE_TREE),y)
164 165ifneq ($(CONFIG_DEVICE_TREE),"")
165dts_initrd- := $(patsubst zImage%, zImage.dts_initrd%, $(image-n) $(image-)) 166dts = $(if $(shell echo $(CONFIG_DEVICE_TREE) | grep '^/'),\
166dts_initrd-y := $(patsubst zImage%, zImage.dts_initrd%, $(image-y)) 167 ,$(srctree)/$(src)/dts/)$(CONFIG_DEVICE_TREE:"%"=%)
167dts_initrd-y := $(filter-out $(image-y), $(dts_initrd-y)) 168endif
168targets += $(image-y) $(dts_initrd-y) 169endif
169
170$(addprefix $(obj)/, $(dts_initrd-y)): $(obj)/ramdisk.image.gz
171 170
172# Don't put the ramdisk on the pattern rule; when its missing make will try 171# Don't put the ramdisk on the pattern rule; when its missing make will try
173# the pattern rule with less dependencies that also matches (even with the 172# the pattern rule with less dependencies that also matches (even with the
174# hard dependency listed). 173# hard dependency listed).
175$(obj)/zImage.dts_initrd.%: vmlinux $(wrapperbits) $(dts) $(obj)/ramdisk.image.gz 174$(obj)/zImage.initrd.%: vmlinux $(wrapperbits) $(dts)
176 $(call if_changed,wrap,$*,$(dts),,$(obj)/ramdisk.image.gz) 175 $(call if_changed,wrap,$*,$(dts),,$(obj)/ramdisk.image.gz)
177 176
178$(obj)/zImage.dts.%: vmlinux $(wrapperbits) $(dts) 177$(obj)/zImage.%: vmlinux $(wrapperbits) $(dts)
179 $(call if_changed,wrap,$*,$(dts)) 178 $(call if_changed,wrap,$*,$(dts))
180 179
181$(obj)/zImage.initrd.%: vmlinux $(wrapperbits) 180# This cannot be in the root of $(src) as the zImage rule always adds a $(obj)
182 $(call if_changed,wrap,$*,,,$(obj)/ramdisk.image.gz) 181# prefix
183 182$(obj)/vmlinux.strip: vmlinux
184$(obj)/zImage.%: vmlinux $(wrapperbits)
185 $(call if_changed,wrap,$*)
186
187$(obj)/zImage.iseries: vmlinux
188 $(STRIP) -s -R .comment $< -o $@ 183 $(STRIP) -s -R .comment $< -o $@
189 184
190$(obj)/zImage.ps3: vmlinux 185$(obj)/zImage.iseries: vmlinux
191 $(STRIP) -s -R .comment $< -o $@ 186 $(STRIP) -s -R .comment $< -o $@
192 187
193$(obj)/zImage.initrd.ps3: vmlinux 188$(obj)/zImage.ps3: vmlinux $(wrapper) $(wrapperbits) $(srctree)/$(src)/dts/ps3.dts
194 @echo " WARNING zImage.initrd.ps3 not supported (yet)" 189 $(STRIP) -s -R .comment $< -o vmlinux.strip
195 190 $(call cmd,wrap,ps3,$(srctree)/$(src)/dts/ps3.dts,,)
196$(obj)/zImage.holly-elf: vmlinux $(wrapperbits)
197 $(call if_changed,wrap,holly,$(obj)/dts/holly.dts,,)
198 191
199$(obj)/zImage.initrd.holly-elf: vmlinux $(wrapperbits) $(obj)/ramdisk.image.gz 192$(obj)/zImage.initrd.ps3: vmlinux $(wrapper) $(wrapperbits) $(srctree)/$(src)/dts/ps3.dts $(obj)/ramdisk.image.gz
200 $(call if_changed,wrap,holly,$(obj)/dts/holly.dts,,$(obj)/ramdisk.image.gz) 193 $(call cmd,wrap,ps3,$(srctree)/$(src)/dts/ps3.dts,,$(obj)/ramdisk.image.gz)
201 194
202$(obj)/uImage: vmlinux $(wrapperbits) 195$(obj)/uImage: vmlinux $(wrapperbits)
203 $(call if_changed,wrap,uboot) 196 $(call if_changed,wrap,uboot)
204 197
205# CONFIG_DEVICE_TREE will have "" around it, make sure to strip them
206dts = $(if $(shell echo $(CONFIG_DEVICE_TREE) | grep '^/'),\
207 ,$(srctree)/$(src)/dts/)$(CONFIG_DEVICE_TREE:"%"=%)
208
209$(obj)/cuImage.%: vmlinux $(dts) $(wrapperbits) 198$(obj)/cuImage.%: vmlinux $(dts) $(wrapperbits)
210 $(call if_changed,wrap,cuboot-$*,$(dts)) 199 $(call if_changed,wrap,cuboot-$*,$(dts))
211 200
@@ -215,22 +204,22 @@ $(obj)/treeImage.initrd.%: vmlinux $(dts) $(wrapperbits)
215$(obj)/treeImage.%: vmlinux $(dts) $(wrapperbits) 204$(obj)/treeImage.%: vmlinux $(dts) $(wrapperbits)
216 $(call if_changed,wrap,treeboot-$*,$(dts)) 205 $(call if_changed,wrap,treeboot-$*,$(dts))
217 206
207# If there isn't a platform selected then just strip the vmlinux.
208ifeq (,$(image-y))
209image-y := vmlinux.strip
210endif
211
218$(obj)/zImage: $(addprefix $(obj)/, $(image-y)) 212$(obj)/zImage: $(addprefix $(obj)/, $(image-y))
219 @rm -f $@; ln $< $@ 213 @rm -f $@; ln $< $@
220$(obj)/zImage.initrd: $(addprefix $(obj)/, $(initrd-y)) 214$(obj)/zImage.initrd: $(addprefix $(obj)/, $(initrd-y))
221 @rm -f $@; ln $< $@ 215 @rm -f $@; ln $< $@
222$(obj)/zImage.dts: $(addprefix $(obj)/, $(dts-y))
223 @rm -f $@; ln $< $@
224$(obj)/zImage.dts_initrd: $(addprefix $(obj)/, $(dts_initrd-y))
225 @rm -f $@; ln $< $@
226
227 216
228install: $(CONFIGURE) $(addprefix $(obj)/, $(image-y)) 217install: $(CONFIGURE) $(addprefix $(obj)/, $(image-y))
229 sh -x $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" vmlinux System.map "$(INSTALL_PATH)" $< 218 sh -x $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" vmlinux System.map "$(INSTALL_PATH)" $<
230 219
231# anything not in $(targets) 220# anything not in $(targets)
232clean-files += $(image-) $(initrd-) zImage zImage.initrd cuImage.* \ 221clean-files += $(image-) $(initrd-) zImage zImage.initrd cuImage.* treeImage.* \
233 treeImage.* zImage.dts zImage.dts_initrd 222 otheros.bld
234 223
235# clean up files cached by wrapper 224# clean up files cached by wrapper
236clean-kernel := vmlinux.strip vmlinux.bin 225clean-kernel := vmlinux.strip vmlinux.bin
diff --git a/arch/powerpc/boot/cuboot-83xx.c b/arch/powerpc/boot/cuboot-83xx.c
index 9af554eea54b..296025d8b295 100644
--- a/arch/powerpc/boot/cuboot-83xx.c
+++ b/arch/powerpc/boot/cuboot-83xx.c
@@ -12,12 +12,12 @@
12 12
13#include "ops.h" 13#include "ops.h"
14#include "stdio.h" 14#include "stdio.h"
15#include "cuboot.h"
15 16
16#define TARGET_83xx 17#define TARGET_83xx
17#include "ppcboot.h" 18#include "ppcboot.h"
18 19
19static bd_t bd; 20static bd_t bd;
20extern char _end[];
21extern char _dtb_start[], _dtb_end[]; 21extern char _dtb_start[], _dtb_end[];
22 22
23static void platform_fixups(void) 23static void platform_fixups(void)
@@ -52,16 +52,7 @@ static void platform_fixups(void)
52void platform_init(unsigned long r3, unsigned long r4, unsigned long r5, 52void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
53 unsigned long r6, unsigned long r7) 53 unsigned long r6, unsigned long r7)
54{ 54{
55 unsigned long end_of_ram = bd.bi_memstart + bd.bi_memsize; 55 CUBOOT_INIT();
56 unsigned long avail_ram = end_of_ram - (unsigned long)_end;
57
58 memcpy(&bd, (bd_t *)r3, sizeof(bd));
59 loader_info.initrd_addr = r4;
60 loader_info.initrd_size = r4 ? r5 - r4 : 0;
61 loader_info.cmdline = (char *)r6;
62 loader_info.cmdline_len = r7 - r6;
63
64 simple_alloc_init(_end, avail_ram - 1024*1024, 32, 64);
65 ft_init(_dtb_start, _dtb_end - _dtb_start, 32); 56 ft_init(_dtb_start, _dtb_end - _dtb_start, 32);
66 serial_console_init(); 57 serial_console_init();
67 platform_ops.fixups = platform_fixups; 58 platform_ops.fixups = platform_fixups;
diff --git a/arch/powerpc/boot/cuboot-85xx.c b/arch/powerpc/boot/cuboot-85xx.c
index e2560317f278..10f0f697c935 100644
--- a/arch/powerpc/boot/cuboot-85xx.c
+++ b/arch/powerpc/boot/cuboot-85xx.c
@@ -12,12 +12,12 @@
12 12
13#include "ops.h" 13#include "ops.h"
14#include "stdio.h" 14#include "stdio.h"
15#include "cuboot.h"
15 16
16#define TARGET_85xx 17#define TARGET_85xx
17#include "ppcboot.h" 18#include "ppcboot.h"
18 19
19static bd_t bd; 20static bd_t bd;
20extern char _end[];
21extern char _dtb_start[], _dtb_end[]; 21extern char _dtb_start[], _dtb_end[];
22 22
23static void platform_fixups(void) 23static void platform_fixups(void)
@@ -53,16 +53,7 @@ static void platform_fixups(void)
53void platform_init(unsigned long r3, unsigned long r4, unsigned long r5, 53void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
54 unsigned long r6, unsigned long r7) 54 unsigned long r6, unsigned long r7)
55{ 55{
56 unsigned long end_of_ram = bd.bi_memstart + bd.bi_memsize; 56 CUBOOT_INIT();
57 unsigned long avail_ram = end_of_ram - (unsigned long)_end;
58
59 memcpy(&bd, (bd_t *)r3, sizeof(bd));
60 loader_info.initrd_addr = r4;
61 loader_info.initrd_size = r4 ? r5 - r4 : 0;
62 loader_info.cmdline = (char *)r6;
63 loader_info.cmdline_len = r7 - r6;
64
65 simple_alloc_init(_end, avail_ram - 1024*1024, 32, 64);
66 ft_init(_dtb_start, _dtb_end - _dtb_start, 32); 57 ft_init(_dtb_start, _dtb_end - _dtb_start, 32);
67 serial_console_init(); 58 serial_console_init();
68 platform_ops.fixups = platform_fixups; 59 platform_ops.fixups = platform_fixups;
diff --git a/arch/powerpc/boot/cuboot-ebony.c b/arch/powerpc/boot/cuboot-ebony.c
index 4464c5f67acb..c5f37ce172ea 100644
--- a/arch/powerpc/boot/cuboot-ebony.c
+++ b/arch/powerpc/boot/cuboot-ebony.c
@@ -15,28 +15,16 @@
15#include "ops.h" 15#include "ops.h"
16#include "stdio.h" 16#include "stdio.h"
17#include "44x.h" 17#include "44x.h"
18#include "cuboot.h"
18 19
19#define TARGET_44x 20#define TARGET_44x
20#include "ppcboot.h" 21#include "ppcboot.h"
21 22
22static bd_t bd; 23static bd_t bd;
23extern char _end[];
24
25BSS_STACK(4096);
26 24
27void platform_init(unsigned long r3, unsigned long r4, unsigned long r5, 25void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
28 unsigned long r6, unsigned long r7) 26 unsigned long r6, unsigned long r7)
29{ 27{
30 unsigned long end_of_ram = bd.bi_memstart + bd.bi_memsize; 28 CUBOOT_INIT();
31 unsigned long avail_ram = end_of_ram - (unsigned long)_end;
32
33 memcpy(&bd, (bd_t *)r3, sizeof(bd));
34 loader_info.initrd_addr = r4;
35 loader_info.initrd_size = r4 ? r5 : 0;
36 loader_info.cmdline = (char *)r6;
37 loader_info.cmdline_len = r7 - r6;
38
39 simple_alloc_init(_end, avail_ram, 32, 64);
40
41 ebony_init(&bd.bi_enetaddr, &bd.bi_enet1addr); 29 ebony_init(&bd.bi_enetaddr, &bd.bi_enet1addr);
42} 30}
diff --git a/arch/powerpc/boot/cuboot.c b/arch/powerpc/boot/cuboot.c
new file mode 100644
index 000000000000..65795468ad6f
--- /dev/null
+++ b/arch/powerpc/boot/cuboot.c
@@ -0,0 +1,35 @@
1/*
2 * Compatibility for old (not device tree aware) U-Boot versions
3 *
4 * Author: Scott Wood <scottwood@freescale.com>
5 * Consolidated using macros by David Gibson <david@gibson.dropbear.id.au>
6 *
7 * Copyright 2007 David Gibson, IBM Corporation.
8 * Copyright (c) 2007 Freescale Semiconductor, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License version 2 as published
12 * by the Free Software Foundation.
13 */
14
15#include "ops.h"
16#include "stdio.h"
17
18#include "ppcboot.h"
19
20extern char _end[];
21extern char _dtb_start[], _dtb_end[];
22
23void cuboot_init(unsigned long r4, unsigned long r5,
24 unsigned long r6, unsigned long r7,
25 unsigned long end_of_ram)
26{
27 unsigned long avail_ram = end_of_ram - (unsigned long)_end;
28
29 loader_info.initrd_addr = r4;
30 loader_info.initrd_size = r4 ? r5 - r4 : 0;
31 loader_info.cmdline = (char *)r6;
32 loader_info.cmdline_len = r7 - r6;
33
34 simple_alloc_init(_end, avail_ram - 1024*1024, 32, 64);
35}
diff --git a/arch/powerpc/boot/cuboot.h b/arch/powerpc/boot/cuboot.h
new file mode 100644
index 000000000000..cd2aa7f348f3
--- /dev/null
+++ b/arch/powerpc/boot/cuboot.h
@@ -0,0 +1,14 @@
1#ifndef _PPC_BOOT_CUBOOT_H_
2#define _PPC_BOOT_CUBOOT_H_
3
4void cuboot_init(unsigned long r4, unsigned long r5,
5 unsigned long r6, unsigned long r7,
6 unsigned long end_of_ram);
7
8#define CUBOOT_INIT() \
9 do { \
10 memcpy(&bd, (bd_t *)r3, sizeof(bd)); \
11 cuboot_init(r4, r5, r6, r7, bd.bi_memstart + bd.bi_memsize); \
12 } while (0)
13
14#endif /* _PPC_BOOT_CUBOOT_H_ */
diff --git a/arch/powerpc/boot/dcr.h b/arch/powerpc/boot/dcr.h
index 877bc97b1e97..14b44aa96fea 100644
--- a/arch/powerpc/boot/dcr.h
+++ b/arch/powerpc/boot/dcr.h
@@ -26,6 +26,43 @@ static const unsigned long sdram_bxcr[] = { SDRAM0_B0CR, SDRAM0_B1CR, SDRAM0_B2C
26#define SDRAM_CONFIG_BANK_SIZE(reg) \ 26#define SDRAM_CONFIG_BANK_SIZE(reg) \
27 (0x00400000 << ((reg & SDRAM_CONFIG_SIZE_MASK) >> 17)) 27 (0x00400000 << ((reg & SDRAM_CONFIG_SIZE_MASK) >> 17))
28 28
29/* 440GP External Bus Controller (EBC) */
30#define DCRN_EBC0_CFGADDR 0x012
31#define DCRN_EBC0_CFGDATA 0x013
32#define EBC_NUM_BANKS 8
33#define EBC_B0CR 0x00
34#define EBC_B1CR 0x01
35#define EBC_B2CR 0x02
36#define EBC_B3CR 0x03
37#define EBC_B4CR 0x04
38#define EBC_B5CR 0x05
39#define EBC_B6CR 0x06
40#define EBC_B7CR 0x07
41#define EBC_BXCR(n) (n)
42#define EBC_BXCR_BAS 0xfff00000
43#define EBC_BXCR_BS 0x000e0000
44#define EBC_BXCR_BANK_SIZE(reg) \
45 (0x100000 << (((reg) & EBC_BXCR_BS) >> 17))
46#define EBC_BXCR_BU 0x00018000
47#define EBC_BXCR_BU_OFF 0x00000000
48#define EBC_BXCR_BU_RO 0x00008000
49#define EBC_BXCR_BU_WO 0x00010000
50#define EBC_BXCR_BU_RW 0x00018000
51#define EBC_BXCR_BW 0x00006000
52#define EBC_B0AP 0x10
53#define EBC_B1AP 0x11
54#define EBC_B2AP 0x12
55#define EBC_B3AP 0x13
56#define EBC_B4AP 0x14
57#define EBC_B5AP 0x15
58#define EBC_B6AP 0x16
59#define EBC_B7AP 0x17
60#define EBC_BXAP(n) (0x10+(n))
61#define EBC_BEAR 0x20
62#define EBC_BESR 0x21
63#define EBC_CFG 0x23
64#define EBC_CID 0x24
65
29/* 440GP Clock, PM, chip control */ 66/* 440GP Clock, PM, chip control */
30#define DCRN_CPC0_SR 0x0b0 67#define DCRN_CPC0_SR 0x0b0
31#define DCRN_CPC0_ER 0x0b1 68#define DCRN_CPC0_ER 0x0b1
diff --git a/arch/powerpc/boot/dts/ebony.dts b/arch/powerpc/boot/dts/ebony.dts
index 0ec02f4726b5..c5f99613fc7b 100644
--- a/arch/powerpc/boot/dts/ebony.dts
+++ b/arch/powerpc/boot/dts/ebony.dts
@@ -31,8 +31,8 @@
31 reg = <0>; 31 reg = <0>;
32 clock-frequency = <0>; // Filled in by zImage 32 clock-frequency = <0>; // Filled in by zImage
33 timebase-frequency = <0>; // Filled in by zImage 33 timebase-frequency = <0>; // Filled in by zImage
34 i-cache-line-size = <32>; 34 i-cache-line-size = <20>;
35 d-cache-line-size = <32>; 35 d-cache-line-size = <20>;
36 i-cache-size = <8000>; /* 32 kB */ 36 i-cache-size = <8000>; /* 32 kB */
37 d-cache-size = <8000>; /* 32 kB */ 37 d-cache-size = <8000>; /* 32 kB */
38 dcr-controller; 38 dcr-controller;
@@ -135,11 +135,9 @@
135 #address-cells = <2>; 135 #address-cells = <2>;
136 #size-cells = <1>; 136 #size-cells = <1>;
137 clock-frequency = <0>; // Filled in by zImage 137 clock-frequency = <0>; // Filled in by zImage
138 ranges = <0 00000000 fff00000 100000 138 // ranges property is supplied by zImage
139 1 00000000 48000000 100000 139 // based on firmware's configuration of the
140 2 00000000 ff800000 400000 140 // EBC bridge
141 3 00000000 48200000 100000
142 7 00000000 48300000 100000>;
143 interrupts = <5 4>; 141 interrupts = <5 4>;
144 interrupt-parent = <&UIC1>; 142 interrupt-parent = <&UIC1>;
145 143
diff --git a/arch/powerpc/boot/dts/holly.dts b/arch/powerpc/boot/dts/holly.dts
index 254499b107f4..80a4fab8ee37 100644
--- a/arch/powerpc/boot/dts/holly.dts
+++ b/arch/powerpc/boot/dts/holly.dts
@@ -46,7 +46,7 @@
46 46
47 tsi109@c0000000 { 47 tsi109@c0000000 {
48 device_type = "tsi-bridge"; 48 device_type = "tsi-bridge";
49 compatible = "tsi-bridge"; 49 compatible = "tsi109-bridge", "tsi108-bridge";
50 #address-cells = <1>; 50 #address-cells = <1>;
51 #size-cells = <1>; 51 #size-cells = <1>;
52 ranges = <00000000 c0000000 00010000>; 52 ranges = <00000000 c0000000 00010000>;
@@ -54,52 +54,55 @@
54 54
55 i2c@7000 { 55 i2c@7000 {
56 device_type = "i2c"; 56 device_type = "i2c";
57 compatible = "tsi-i2c"; 57 compatible = "tsi109-i2c", "tsi108-i2c";
58 interrupt-parent = < &/tsi109@c0000000/pic@7400 >; 58 interrupt-parent = <&MPIC>;
59 interrupts = <e 2>; 59 interrupts = <e 2>;
60 reg = <7000 400>; 60 reg = <7000 400>;
61 }; 61 };
62 62
63 mdio@6000 { 63 MDIO: mdio@6000 {
64 device_type = "mdio"; 64 device_type = "mdio";
65 compatible = "tsi-ethernet"; 65 compatible = "tsi109-mdio", "tsi108-mdio";
66 reg = <6000 50>;
67 #address-cells = <1>;
68 #size-cells = <0>;
66 69
67 PHY1: ethernet-phy@6000 { 70 PHY1: ethernet-phy@1 {
68 device_type = "ethernet-phy"; 71 compatible = "bcm5461a";
69 compatible = "bcm54xx"; 72 reg = <1>;
70 reg = <6000 50>; 73 txc-rxc-delay-disable;
71 phy-id = <1>;
72 }; 74 };
73 75
74 PHY2: ethernet-phy@6400 { 76 PHY2: ethernet-phy@2 {
75 device_type = "ethernet-phy"; 77 compatible = "bcm5461a";
76 compatible = "bcm54xx"; 78 reg = <2>;
77 reg = <6000 50>; 79 txc-rxc-delay-disable;
78 phy-id = <2>;
79 }; 80 };
80 }; 81 };
81 82
82 ethernet@6200 { 83 ethernet@6200 {
83 device_type = "network"; 84 device_type = "network";
84 compatible = "tsi-ethernet"; 85 compatible = "tsi109-ethernet", "tsi108-ethernet";
85 #address-cells = <1>; 86 #address-cells = <1>;
86 #size-cells = <0>; 87 #size-cells = <0>;
87 reg = <6000 200>; 88 reg = <6000 200>;
88 local-mac-address = [ 00 00 00 00 00 00 ]; 89 local-mac-address = [ 00 00 00 00 00 00 ];
89 interrupt-parent = < &/tsi109@c0000000/pic@7400 >; 90 interrupt-parent = <&MPIC>;
90 interrupts = <10 2>; 91 interrupts = <10 2>;
92 mdio-handle = <&MDIO>;
91 phy-handle = <&PHY1>; 93 phy-handle = <&PHY1>;
92 }; 94 };
93 95
94 ethernet@6600 { 96 ethernet@6600 {
95 device_type = "network"; 97 device_type = "network";
96 compatible = "tsi-ethernet"; 98 compatible = "tsi109-ethernet", "tsi108-ethernet";
97 #address-cells = <1>; 99 #address-cells = <1>;
98 #size-cells = <0>; 100 #size-cells = <0>;
99 reg = <6400 200>; 101 reg = <6400 200>;
100 local-mac-address = [ 00 00 00 00 00 00 ]; 102 local-mac-address = [ 00 00 00 00 00 00 ];
101 interrupt-parent = < &/tsi109@c0000000/pic@7400 >; 103 interrupt-parent = <&MPIC>;
102 interrupts = <11 2>; 104 interrupts = <11 2>;
105 mdio-handle = <&MDIO>;
103 phy-handle = <&PHY2>; 106 phy-handle = <&PHY2>;
104 }; 107 };
105 108
@@ -110,7 +113,7 @@
110 virtual-reg = <c0007808>; 113 virtual-reg = <c0007808>;
111 clock-frequency = <3F9C6000>; 114 clock-frequency = <3F9C6000>;
112 current-speed = <1c200>; 115 current-speed = <1c200>;
113 interrupt-parent = < &/tsi109@c0000000/pic@7400 >; 116 interrupt-parent = <&MPIC>;
114 interrupts = <c 2>; 117 interrupts = <c 2>;
115 }; 118 };
116 119
@@ -121,7 +124,7 @@
121 virtual-reg = <c0007c08>; 124 virtual-reg = <c0007c08>;
122 clock-frequency = <3F9C6000>; 125 clock-frequency = <3F9C6000>;
123 current-speed = <1c200>; 126 current-speed = <1c200>;
124 interrupt-parent = < &/tsi109@c0000000/pic@7400 >; 127 interrupt-parent = <&MPIC>;
125 interrupts = <d 2>; 128 interrupts = <d 2>;
126 }; 129 };
127 130
@@ -136,7 +139,7 @@
136 139
137 pci@1000 { 140 pci@1000 {
138 device_type = "pci"; 141 device_type = "pci";
139 compatible = "tsi109"; 142 compatible = "tsi109-pci", "tsi108-pci";
140 #interrupt-cells = <1>; 143 #interrupt-cells = <1>;
141 #size-cells = <2>; 144 #size-cells = <2>;
142 #address-cells = <3>; 145 #address-cells = <3>;
@@ -150,7 +153,7 @@
150 ranges = <02000000 0 40000000 40000000 0 10000000 153 ranges = <02000000 0 40000000 40000000 0 10000000
151 01000000 0 00000000 7e000000 0 00010000>; 154 01000000 0 00000000 7e000000 0 00010000>;
152 clock-frequency = <7f28154>; 155 clock-frequency = <7f28154>;
153 interrupt-parent = < &/tsi109@c0000000/pic@7400 >; 156 interrupt-parent = <&MPIC>;
154 interrupts = <17 2>; 157 interrupts = <17 2>;
155 interrupt-map-mask = <f800 0 0 7>; 158 interrupt-map-mask = <f800 0 0 7>;
156 /*----------------------------------------------------+ 159 /*----------------------------------------------------+
@@ -186,13 +189,12 @@
186 #address-cells = <0>; 189 #address-cells = <0>;
187 #interrupt-cells = <2>; 190 #interrupt-cells = <2>;
188 interrupts = <17 2>; 191 interrupts = <17 2>;
189 interrupt-parent = < &/tsi109@c0000000/pic@7400 >; 192 interrupt-parent = <&MPIC>;
190 }; 193 };
191 }; 194 };
192 }; 195 };
193 196
194 chosen { 197 chosen {
195 linux,stdout-path = "/tsi109@c0000000/serial@7808"; 198 linux,stdout-path = "/tsi109@c0000000/serial@7808";
196 bootargs = "console=ttyS0,115200";
197 }; 199 };
198}; 200};
diff --git a/arch/powerpc/boot/dts/mpc7448hpc2.dts b/arch/powerpc/boot/dts/mpc7448hpc2.dts
index 765c306ecf80..0e3d314a7158 100644
--- a/arch/powerpc/boot/dts/mpc7448hpc2.dts
+++ b/arch/powerpc/boot/dts/mpc7448hpc2.dts
@@ -45,7 +45,7 @@
45 #address-cells = <1>; 45 #address-cells = <1>;
46 #size-cells = <1>; 46 #size-cells = <1>;
47 #interrupt-cells = <2>; 47 #interrupt-cells = <2>;
48 device_type = "tsi-bridge"; 48 device_type = "tsi108-bridge";
49 ranges = <00000000 c0000000 00010000>; 49 ranges = <00000000 c0000000 00010000>;
50 reg = <c0000000 00010000>; 50 reg = <c0000000 00010000>;
51 bus-frequency = <0>; 51 bus-frequency = <0>;
@@ -55,27 +55,26 @@
55 interrupts = <E 0>; 55 interrupts = <E 0>;
56 reg = <7000 400>; 56 reg = <7000 400>;
57 device_type = "i2c"; 57 device_type = "i2c";
58 compatible = "tsi-i2c"; 58 compatible = "tsi108-i2c";
59 }; 59 };
60 60
61 mdio@6000 { 61 MDIO: mdio@6000 {
62 device_type = "mdio"; 62 device_type = "mdio";
63 compatible = "tsi-ethernet"; 63 compatible = "tsi108-mdio";
64 reg = <6000 50>;
65 #address-cells = <1>;
66 #size-cells = <0>;
64 67
65 phy8: ethernet-phy@6000 { 68 phy8: ethernet-phy@8 {
66 interrupt-parent = <&mpic>; 69 interrupt-parent = <&mpic>;
67 interrupts = <2 1>; 70 interrupts = <2 1>;
68 reg = <6000 50>; 71 reg = <8>;
69 phy-id = <8>;
70 device_type = "ethernet-phy";
71 }; 72 };
72 73
73 phy9: ethernet-phy@6400 { 74 phy9: ethernet-phy@9 {
74 interrupt-parent = <&mpic>; 75 interrupt-parent = <&mpic>;
75 interrupts = <2 1>; 76 interrupts = <2 1>;
76 reg = <6000 50>; 77 reg = <9>;
77 phy-id = <9>;
78 device_type = "ethernet-phy";
79 }; 78 };
80 79
81 }; 80 };
@@ -83,12 +82,12 @@
83 ethernet@6200 { 82 ethernet@6200 {
84 #size-cells = <0>; 83 #size-cells = <0>;
85 device_type = "network"; 84 device_type = "network";
86 model = "TSI-ETH"; 85 compatible = "tsi108-ethernet";
87 compatible = "tsi-ethernet";
88 reg = <6000 200>; 86 reg = <6000 200>;
89 address = [ 00 06 D2 00 00 01 ]; 87 address = [ 00 06 D2 00 00 01 ];
90 interrupts = <10 2>; 88 interrupts = <10 2>;
91 interrupt-parent = <&mpic>; 89 interrupt-parent = <&mpic>;
90 mdio-handle = <&MDIO>;
92 phy-handle = <&phy8>; 91 phy-handle = <&phy8>;
93 }; 92 };
94 93
@@ -96,12 +95,12 @@
96 #address-cells = <1>; 95 #address-cells = <1>;
97 #size-cells = <0>; 96 #size-cells = <0>;
98 device_type = "network"; 97 device_type = "network";
99 model = "TSI-ETH"; 98 compatible = "tsi108-ethernet";
100 compatible = "tsi-ethernet";
101 reg = <6400 200>; 99 reg = <6400 200>;
102 address = [ 00 06 D2 00 00 02 ]; 100 address = [ 00 06 D2 00 00 02 ];
103 interrupts = <11 2>; 101 interrupts = <11 2>;
104 interrupt-parent = <&mpic>; 102 interrupt-parent = <&mpic>;
103 mdio-handle = <&MDIO>;
105 phy-handle = <&phy9>; 104 phy-handle = <&phy9>;
106 }; 105 };
107 106
@@ -135,7 +134,7 @@
135 big-endian; 134 big-endian;
136 }; 135 };
137 pci@1000 { 136 pci@1000 {
138 compatible = "tsi10x"; 137 compatible = "tsi108-pci";
139 device_type = "pci"; 138 device_type = "pci";
140 #interrupt-cells = <1>; 139 #interrupt-cells = <1>;
141 #size-cells = <2>; 140 #size-cells = <2>;
diff --git a/arch/powerpc/boot/dts/mpc8272ads.dts b/arch/powerpc/boot/dts/mpc8272ads.dts
index 423eedcf634f..1934b800278e 100644
--- a/arch/powerpc/boot/dts/mpc8272ads.dts
+++ b/arch/powerpc/boot/dts/mpc8272ads.dts
@@ -14,12 +14,10 @@
14 compatible = "MPC8260ADS"; 14 compatible = "MPC8260ADS";
15 #address-cells = <1>; 15 #address-cells = <1>;
16 #size-cells = <1>; 16 #size-cells = <1>;
17 linux,phandle = <100>;
18 17
19 cpus { 18 cpus {
20 #address-cells = <1>; 19 #address-cells = <1>;
21 #size-cells = <0>; 20 #size-cells = <0>;
22 linux,phandle = <200>;
23 21
24 PowerPC,8272@0 { 22 PowerPC,8272@0 {
25 device_type = "cpu"; 23 device_type = "cpu";
@@ -32,12 +30,10 @@
32 bus-frequency = <0>; 30 bus-frequency = <0>;
33 clock-frequency = <0>; 31 clock-frequency = <0>;
34 32-bit; 32 32-bit;
35 linux,phandle = <201>;
36 }; 33 };
37 }; 34 };
38 35
39 interrupt-controller@f8200000 { 36 pci_pic: interrupt-controller@f8200000 {
40 linux,phandle = <f8200000>;
41 #address-cells = <0>; 37 #address-cells = <0>;
42 #interrupt-cells = <2>; 38 #interrupt-cells = <2>;
43 interrupt-controller; 39 interrupt-controller;
@@ -47,15 +43,13 @@
47 }; 43 };
48 memory { 44 memory {
49 device_type = "memory"; 45 device_type = "memory";
50 linux,phandle = <300>;
51 reg = <00000000 4000000 f4500000 00000020>; 46 reg = <00000000 4000000 f4500000 00000020>;
52 }; 47 };
53 48
54 chosen { 49 chosen {
55 name = "chosen"; 50 name = "chosen";
56 linux,platform = <0>; 51 linux,platform = <0>;
57 interrupt-controller = <10c00>; 52 interrupt-controller = <&Cpm_pic>;
58 linux,phandle = <400>;
59 }; 53 };
60 54
61 soc8272@f0000000 { 55 soc8272@f0000000 {
@@ -70,20 +64,17 @@
70 device_type = "mdio"; 64 device_type = "mdio";
71 compatible = "fs_enet"; 65 compatible = "fs_enet";
72 reg = <0 0>; 66 reg = <0 0>;
73 linux,phandle = <24520>;
74 #address-cells = <1>; 67 #address-cells = <1>;
75 #size-cells = <0>; 68 #size-cells = <0>;
76 ethernet-phy@0 { 69 phy0:ethernet-phy@0 {
77 linux,phandle = <2452000>; 70 interrupt-parent = <&Cpm_pic>;
78 interrupt-parent = <10c00>;
79 interrupts = <17 4>; 71 interrupts = <17 4>;
80 reg = <0>; 72 reg = <0>;
81 bitbang = [ 12 12 13 02 02 01 ]; 73 bitbang = [ 12 12 13 02 02 01 ];
82 device_type = "ethernet-phy"; 74 device_type = "ethernet-phy";
83 }; 75 };
84 ethernet-phy@1 { 76 phy1:ethernet-phy@1 {
85 linux,phandle = <2452001>; 77 interrupt-parent = <&Cpm_pic>;
86 interrupt-parent = <10c00>;
87 interrupts = <17 4>; 78 interrupts = <17 4>;
88 bitbang = [ 12 12 13 02 02 01 ]; 79 bitbang = [ 12 12 13 02 02 01 ];
89 reg = <3>; 80 reg = <3>;
@@ -101,8 +92,8 @@
101 reg = <11300 20 8400 100 11380 30>; 92 reg = <11300 20 8400 100 11380 30>;
102 mac-address = [ 00 11 2F 99 43 54 ]; 93 mac-address = [ 00 11 2F 99 43 54 ];
103 interrupts = <20 2>; 94 interrupts = <20 2>;
104 interrupt-parent = <10c00>; 95 interrupt-parent = <&Cpm_pic>;
105 phy-handle = <2452000>; 96 phy-handle = <&Phy0>;
106 rx-clock = <13>; 97 rx-clock = <13>;
107 tx-clock = <12>; 98 tx-clock = <12>;
108 }; 99 };
@@ -115,14 +106,13 @@
115 reg = <11320 20 8500 100 113b0 30>; 106 reg = <11320 20 8500 100 113b0 30>;
116 mac-address = [ 00 11 2F 99 44 54 ]; 107 mac-address = [ 00 11 2F 99 44 54 ];
117 interrupts = <21 2>; 108 interrupts = <21 2>;
118 interrupt-parent = <10c00>; 109 interrupt-parent = <&Cpm_pic>;
119 phy-handle = <2452001>; 110 phy-handle = <&Phy1>;
120 rx-clock = <17>; 111 rx-clock = <17>;
121 tx-clock = <18>; 112 tx-clock = <18>;
122 }; 113 };
123 114
124 cpm@f0000000 { 115 cpm@f0000000 {
125 linux,phandle = <f0000000>;
126 #address-cells = <1>; 116 #address-cells = <1>;
127 #size-cells = <1>; 117 #size-cells = <1>;
128 #interrupt-cells = <2>; 118 #interrupt-cells = <2>;
@@ -142,7 +132,7 @@
142 reg = <11a00 20 8000 100>; 132 reg = <11a00 20 8000 100>;
143 current-speed = <1c200>; 133 current-speed = <1c200>;
144 interrupts = <28 2>; 134 interrupts = <28 2>;
145 interrupt-parent = <10c00>; 135 interrupt-parent = <&Cpm_pic>;
146 clock-setup = <0 00ffffff>; 136 clock-setup = <0 00ffffff>;
147 rx-clock = <1>; 137 rx-clock = <1>;
148 tx-clock = <1>; 138 tx-clock = <1>;
@@ -156,15 +146,14 @@
156 reg = <11a60 20 8300 100>; 146 reg = <11a60 20 8300 100>;
157 current-speed = <1c200>; 147 current-speed = <1c200>;
158 interrupts = <2b 2>; 148 interrupts = <2b 2>;
159 interrupt-parent = <10c00>; 149 interrupt-parent = <&Cpm_pic>;
160 clock-setup = <1b ffffff00>; 150 clock-setup = <1b ffffff00>;
161 rx-clock = <4>; 151 rx-clock = <4>;
162 tx-clock = <4>; 152 tx-clock = <4>;
163 }; 153 };
164 154
165 }; 155 };
166 interrupt-controller@10c00 { 156 cpm_pic:interrupt-controller@10c00 {
167 linux,phandle = <10c00>;
168 #address-cells = <0>; 157 #address-cells = <0>;
169 #interrupt-cells = <2>; 158 #interrupt-cells = <2>;
170 interrupt-controller; 159 interrupt-controller;
@@ -174,7 +163,6 @@
174 compatible = "CPM2"; 163 compatible = "CPM2";
175 }; 164 };
176 pci@0500 { 165 pci@0500 {
177 linux,phandle = <0500>;
178 #interrupt-cells = <1>; 166 #interrupt-cells = <1>;
179 #size-cells = <2>; 167 #size-cells = <2>;
180 #address-cells = <3>; 168 #address-cells = <3>;
@@ -202,7 +190,7 @@
202 c000 0 0 2 f8200000 43 8 190 c000 0 0 2 f8200000 43 8
203 c000 0 0 3 f8200000 40 8 191 c000 0 0 3 f8200000 40 8
204 c000 0 0 4 f8200000 41 8>; 192 c000 0 0 4 f8200000 41 8>;
205 interrupt-parent = <10c00>; 193 interrupt-parent = <&Cpm_pic>;
206 interrupts = <14 8>; 194 interrupts = <14 8>;
207 bus-range = <0 0>; 195 bus-range = <0 0>;
208 ranges = <02000000 0 80000000 80000000 0 40000000 196 ranges = <02000000 0 80000000 80000000 0 40000000
@@ -216,7 +204,7 @@
216 compatible = "talitos"; 204 compatible = "talitos";
217 reg = <30000 10000>; 205 reg = <30000 10000>;
218 interrupts = <b 2>; 206 interrupts = <b 2>;
219 interrupt-parent = <10c00>; 207 interrupt-parent = <&Cpm_pic>;
220 num-channels = <4>; 208 num-channels = <4>;
221 channel-fifo-len = <18>; 209 channel-fifo-len = <18>;
222 exec-units-mask = <0000007e>; 210 exec-units-mask = <0000007e>;
diff --git a/arch/powerpc/boot/dts/mpc832x_mds.dts b/arch/powerpc/boot/dts/mpc832x_mds.dts
index 112dd5198fe2..4fc0c4d34aa8 100644
--- a/arch/powerpc/boot/dts/mpc832x_mds.dts
+++ b/arch/powerpc/boot/dts/mpc832x_mds.dts
@@ -272,7 +272,13 @@
272 reg = <2200 200>; 272 reg = <2200 200>;
273 interrupts = <22>; 273 interrupts = <22>;
274 interrupt-parent = < &qeic >; 274 interrupt-parent = < &qeic >;
275 mac-address = [ 00 04 9f 00 23 23 ]; 275 /*
276 * mac-address is deprecated and will be removed
277 * in 2.6.25. Only recent versions of
278 * U-Boot support local-mac-address, however.
279 */
280 mac-address = [ 00 00 00 00 00 00 ];
281 local-mac-address = [ 00 00 00 00 00 00 ];
276 rx-clock = <19>; 282 rx-clock = <19>;
277 tx-clock = <1a>; 283 tx-clock = <1a>;
278 phy-handle = < &phy3 >; 284 phy-handle = < &phy3 >;
@@ -287,7 +293,13 @@
287 reg = <3000 200>; 293 reg = <3000 200>;
288 interrupts = <23>; 294 interrupts = <23>;
289 interrupt-parent = < &qeic >; 295 interrupt-parent = < &qeic >;
290 mac-address = [ 00 11 22 33 44 55 ]; 296 /*
297 * mac-address is deprecated and will be removed
298 * in 2.6.25. Only recent versions of
299 * U-Boot support local-mac-address, however.
300 */
301 mac-address = [ 00 00 00 00 00 00 ];
302 local-mac-address = [ 00 00 00 00 00 00 ];
291 rx-clock = <17>; 303 rx-clock = <17>;
292 tx-clock = <18>; 304 tx-clock = <18>;
293 phy-handle = < &phy4 >; 305 phy-handle = < &phy4 >;
diff --git a/arch/powerpc/boot/dts/mpc832x_rdb.dts b/arch/powerpc/boot/dts/mpc832x_rdb.dts
index be4c35784e49..447c03ffabbc 100644
--- a/arch/powerpc/boot/dts/mpc832x_rdb.dts
+++ b/arch/powerpc/boot/dts/mpc832x_rdb.dts
@@ -231,7 +231,13 @@
231 reg = <3000 200>; 231 reg = <3000 200>;
232 interrupts = <21>; 232 interrupts = <21>;
233 interrupt-parent = <&qeic>; 233 interrupt-parent = <&qeic>;
234 mac-address = [ 00 04 9f ef 03 02 ]; 234 /*
235 * mac-address is deprecated and will be removed
236 * in 2.6.25. Only recent versions of
237 * U-Boot support local-mac-address, however.
238 */
239 mac-address = [ 00 00 00 00 00 00 ];
240 local-mac-address = [ 00 00 00 00 00 00 ];
235 rx-clock = <20>; 241 rx-clock = <20>;
236 tx-clock = <13>; 242 tx-clock = <13>;
237 phy-handle = <&phy00>; 243 phy-handle = <&phy00>;
@@ -246,7 +252,13 @@
246 reg = <2200 200>; 252 reg = <2200 200>;
247 interrupts = <22>; 253 interrupts = <22>;
248 interrupt-parent = <&qeic>; 254 interrupt-parent = <&qeic>;
249 mac-address = [ 00 04 9f ef 03 01 ]; 255 /*
256 * mac-address is deprecated and will be removed
257 * in 2.6.25. Only recent versions of
258 * U-Boot support local-mac-address, however.
259 */
260 mac-address = [ 00 00 00 00 00 00 ];
261 local-mac-address = [ 00 00 00 00 00 00 ];
250 rx-clock = <19>; 262 rx-clock = <19>;
251 tx-clock = <1a>; 263 tx-clock = <1a>;
252 phy-handle = <&phy04>; 264 phy-handle = <&phy04>;
diff --git a/arch/powerpc/boot/dts/mpc8349emitx.dts b/arch/powerpc/boot/dts/mpc8349emitx.dts
index db0d00303275..ae9bca575453 100644
--- a/arch/powerpc/boot/dts/mpc8349emitx.dts
+++ b/arch/powerpc/boot/dts/mpc8349emitx.dts
@@ -131,6 +131,11 @@
131 model = "TSEC"; 131 model = "TSEC";
132 compatible = "gianfar"; 132 compatible = "gianfar";
133 reg = <24000 1000>; 133 reg = <24000 1000>;
134 /*
135 * address is deprecated and will be removed
136 * in 2.6.25. Only recent versions of
137 * U-Boot support local-mac-address, however.
138 */
134 address = [ 00 00 00 00 00 00 ]; 139 address = [ 00 00 00 00 00 00 ];
135 local-mac-address = [ 00 00 00 00 00 00 ]; 140 local-mac-address = [ 00 00 00 00 00 00 ];
136 interrupts = <20 8 21 8 22 8>; 141 interrupts = <20 8 21 8 22 8>;
@@ -145,6 +150,11 @@
145 model = "TSEC"; 150 model = "TSEC";
146 compatible = "gianfar"; 151 compatible = "gianfar";
147 reg = <25000 1000>; 152 reg = <25000 1000>;
153 /*
154 * address is deprecated and will be removed
155 * in 2.6.25. Only recent versions of
156 * U-Boot support local-mac-address, however.
157 */
148 address = [ 00 00 00 00 00 00 ]; 158 address = [ 00 00 00 00 00 00 ];
149 local-mac-address = [ 00 00 00 00 00 00 ]; 159 local-mac-address = [ 00 00 00 00 00 00 ];
150 interrupts = <23 8 24 8 25 8>; 160 interrupts = <23 8 24 8 25 8>;
diff --git a/arch/powerpc/boot/dts/mpc834x_mds.dts b/arch/powerpc/boot/dts/mpc834x_mds.dts
index df773fafe9d1..310e877826b4 100644
--- a/arch/powerpc/boot/dts/mpc834x_mds.dts
+++ b/arch/powerpc/boot/dts/mpc834x_mds.dts
@@ -136,6 +136,11 @@
136 model = "TSEC"; 136 model = "TSEC";
137 compatible = "gianfar"; 137 compatible = "gianfar";
138 reg = <24000 1000>; 138 reg = <24000 1000>;
139 /*
140 * address is deprecated and will be removed
141 * in 2.6.25. Only recent versions of
142 * U-Boot support local-mac-address, however.
143 */
139 address = [ 00 00 00 00 00 00 ]; 144 address = [ 00 00 00 00 00 00 ];
140 local-mac-address = [ 00 00 00 00 00 00 ]; 145 local-mac-address = [ 00 00 00 00 00 00 ];
141 interrupts = <20 8 21 8 22 8>; 146 interrupts = <20 8 21 8 22 8>;
@@ -150,6 +155,11 @@
150 model = "TSEC"; 155 model = "TSEC";
151 compatible = "gianfar"; 156 compatible = "gianfar";
152 reg = <25000 1000>; 157 reg = <25000 1000>;
158 /*
159 * address is deprecated and will be removed
160 * in 2.6.25. Only recent versions of
161 * U-Boot support local-mac-address, however.
162 */
153 address = [ 00 00 00 00 00 00 ]; 163 address = [ 00 00 00 00 00 00 ];
154 local-mac-address = [ 00 00 00 00 00 00 ]; 164 local-mac-address = [ 00 00 00 00 00 00 ];
155 interrupts = <23 8 24 8 25 8>; 165 interrupts = <23 8 24 8 25 8>;
diff --git a/arch/powerpc/boot/dts/mpc836x_mds.dts b/arch/powerpc/boot/dts/mpc836x_mds.dts
index 38c8594df3a4..1e914f31dd92 100644
--- a/arch/powerpc/boot/dts/mpc836x_mds.dts
+++ b/arch/powerpc/boot/dts/mpc836x_mds.dts
@@ -301,7 +301,13 @@
301 reg = <2000 200>; 301 reg = <2000 200>;
302 interrupts = <20>; 302 interrupts = <20>;
303 interrupt-parent = < &qeic >; 303 interrupt-parent = < &qeic >;
304 mac-address = [ 00 04 9f 00 23 23 ]; 304 /*
305 * mac-address is deprecated and will be removed
306 * in 2.6.25. Only recent versions of
307 * U-Boot support local-mac-address, however.
308 */
309 mac-address = [ 00 00 00 00 00 00 ];
310 local-mac-address = [ 00 00 00 00 00 00 ];
305 rx-clock = <0>; 311 rx-clock = <0>;
306 tx-clock = <19>; 312 tx-clock = <19>;
307 phy-handle = < &phy0 >; 313 phy-handle = < &phy0 >;
@@ -317,7 +323,13 @@
317 reg = <3000 200>; 323 reg = <3000 200>;
318 interrupts = <21>; 324 interrupts = <21>;
319 interrupt-parent = < &qeic >; 325 interrupt-parent = < &qeic >;
320 mac-address = [ 00 11 22 33 44 55 ]; 326 /*
327 * mac-address is deprecated and will be removed
328 * in 2.6.25. Only recent versions of
329 * U-Boot support local-mac-address, however.
330 */
331 mac-address = [ 00 00 00 00 00 00 ];
332 local-mac-address = [ 00 00 00 00 00 00 ];
321 rx-clock = <0>; 333 rx-clock = <0>;
322 tx-clock = <14>; 334 tx-clock = <14>;
323 phy-handle = < &phy1 >; 335 phy-handle = < &phy1 >;
diff --git a/arch/powerpc/boot/dts/mpc8540ads.dts b/arch/powerpc/boot/dts/mpc8540ads.dts
index d91e81c009f5..364a969f5c2f 100644
--- a/arch/powerpc/boot/dts/mpc8540ads.dts
+++ b/arch/powerpc/boot/dts/mpc8540ads.dts
@@ -52,7 +52,7 @@
52 compatible = "fsl,8540-memory-controller"; 52 compatible = "fsl,8540-memory-controller";
53 reg = <2000 1000>; 53 reg = <2000 1000>;
54 interrupt-parent = <&mpic>; 54 interrupt-parent = <&mpic>;
55 interrupts = <2 2>; 55 interrupts = <12 2>;
56 }; 56 };
57 57
58 l2-cache-controller@20000 { 58 l2-cache-controller@20000 {
@@ -61,14 +61,14 @@
61 cache-line-size = <20>; // 32 bytes 61 cache-line-size = <20>; // 32 bytes
62 cache-size = <40000>; // L2, 256K 62 cache-size = <40000>; // L2, 256K
63 interrupt-parent = <&mpic>; 63 interrupt-parent = <&mpic>;
64 interrupts = <0 2>; 64 interrupts = <10 2>;
65 }; 65 };
66 66
67 i2c@3000 { 67 i2c@3000 {
68 device_type = "i2c"; 68 device_type = "i2c";
69 compatible = "fsl-i2c"; 69 compatible = "fsl-i2c";
70 reg = <3000 100>; 70 reg = <3000 100>;
71 interrupts = <1b 2>; 71 interrupts = <2b 2>;
72 interrupt-parent = <&mpic>; 72 interrupt-parent = <&mpic>;
73 dfsrr; 73 dfsrr;
74 }; 74 };
@@ -81,19 +81,19 @@
81 reg = <24520 20>; 81 reg = <24520 20>;
82 phy0: ethernet-phy@0 { 82 phy0: ethernet-phy@0 {
83 interrupt-parent = <&mpic>; 83 interrupt-parent = <&mpic>;
84 interrupts = <35 1>; 84 interrupts = <5 1>;
85 reg = <0>; 85 reg = <0>;
86 device_type = "ethernet-phy"; 86 device_type = "ethernet-phy";
87 }; 87 };
88 phy1: ethernet-phy@1 { 88 phy1: ethernet-phy@1 {
89 interrupt-parent = <&mpic>; 89 interrupt-parent = <&mpic>;
90 interrupts = <35 1>; 90 interrupts = <5 1>;
91 reg = <1>; 91 reg = <1>;
92 device_type = "ethernet-phy"; 92 device_type = "ethernet-phy";
93 }; 93 };
94 phy3: ethernet-phy@3 { 94 phy3: ethernet-phy@3 {
95 interrupt-parent = <&mpic>; 95 interrupt-parent = <&mpic>;
96 interrupts = <37 1>; 96 interrupts = <7 1>;
97 reg = <3>; 97 reg = <3>;
98 device_type = "ethernet-phy"; 98 device_type = "ethernet-phy";
99 }; 99 };
@@ -106,9 +106,14 @@
106 model = "TSEC"; 106 model = "TSEC";
107 compatible = "gianfar"; 107 compatible = "gianfar";
108 reg = <24000 1000>; 108 reg = <24000 1000>;
109 address = [ 00 E0 0C 00 73 00 ]; 109 /*
110 local-mac-address = [ 00 E0 0C 00 73 00 ]; 110 * address is deprecated and will be removed
111 interrupts = <d 2 e 2 12 2>; 111 * in 2.6.25. Only recent versions of
112 * U-Boot support local-mac-address, however.
113 */
114 address = [ 00 00 00 00 00 00 ];
115 local-mac-address = [ 00 00 00 00 00 00 ];
116 interrupts = <1d 2 1e 2 22 2>;
112 interrupt-parent = <&mpic>; 117 interrupt-parent = <&mpic>;
113 phy-handle = <&phy0>; 118 phy-handle = <&phy0>;
114 }; 119 };
@@ -120,9 +125,14 @@
120 model = "TSEC"; 125 model = "TSEC";
121 compatible = "gianfar"; 126 compatible = "gianfar";
122 reg = <25000 1000>; 127 reg = <25000 1000>;
123 address = [ 00 E0 0C 00 73 01 ]; 128 /*
124 local-mac-address = [ 00 E0 0C 00 73 01 ]; 129 * address is deprecated and will be removed
125 interrupts = <13 2 14 2 18 2>; 130 * in 2.6.25. Only recent versions of
131 * U-Boot support local-mac-address, however.
132 */
133 address = [ 00 00 00 00 00 00 ];
134 local-mac-address = [ 00 00 00 00 00 00 ];
135 interrupts = <23 2 24 2 28 2>;
126 interrupt-parent = <&mpic>; 136 interrupt-parent = <&mpic>;
127 phy-handle = <&phy1>; 137 phy-handle = <&phy1>;
128 }; 138 };
@@ -134,9 +144,14 @@
134 model = "FEC"; 144 model = "FEC";
135 compatible = "gianfar"; 145 compatible = "gianfar";
136 reg = <26000 1000>; 146 reg = <26000 1000>;
137 address = [ 00 E0 0C 00 73 02 ]; 147 /*
138 local-mac-address = [ 00 E0 0C 00 73 02 ]; 148 * address is deprecated and will be removed
139 interrupts = <19 2>; 149 * in 2.6.25. Only recent versions of
150 * U-Boot support local-mac-address, however.
151 */
152 address = [ 00 00 00 00 00 00 ];
153 local-mac-address = [ 00 00 00 00 00 00 ];
154 interrupts = <29 2>;
140 interrupt-parent = <&mpic>; 155 interrupt-parent = <&mpic>;
141 phy-handle = <&phy3>; 156 phy-handle = <&phy3>;
142 }; 157 };
@@ -146,7 +161,7 @@
146 compatible = "ns16550"; 161 compatible = "ns16550";
147 reg = <4500 100>; // reg base, size 162 reg = <4500 100>; // reg base, size
148 clock-frequency = <0>; // should we fill in in uboot? 163 clock-frequency = <0>; // should we fill in in uboot?
149 interrupts = <1a 2>; 164 interrupts = <2a 2>;
150 interrupt-parent = <&mpic>; 165 interrupt-parent = <&mpic>;
151 }; 166 };
152 167
@@ -155,7 +170,7 @@
155 compatible = "ns16550"; 170 compatible = "ns16550";
156 reg = <4600 100>; // reg base, size 171 reg = <4600 100>; // reg base, size
157 clock-frequency = <0>; // should we fill in in uboot? 172 clock-frequency = <0>; // should we fill in in uboot?
158 interrupts = <1a 2>; 173 interrupts = <2a 2>;
159 interrupt-parent = <&mpic>; 174 interrupt-parent = <&mpic>;
160 }; 175 };
161 pci@8000 { 176 pci@8000 {
@@ -163,78 +178,78 @@
163 interrupt-map = < 178 interrupt-map = <
164 179
165 /* IDSEL 0x02 */ 180 /* IDSEL 0x02 */
166 1000 0 0 1 &mpic 31 1 181 1000 0 0 1 &mpic 1 1
167 1000 0 0 2 &mpic 32 1 182 1000 0 0 2 &mpic 2 1
168 1000 0 0 3 &mpic 33 1 183 1000 0 0 3 &mpic 3 1
169 1000 0 0 4 &mpic 34 1 184 1000 0 0 4 &mpic 4 1
170 185
171 /* IDSEL 0x03 */ 186 /* IDSEL 0x03 */
172 1800 0 0 1 &mpic 34 1 187 1800 0 0 1 &mpic 4 1
173 1800 0 0 2 &mpic 31 1 188 1800 0 0 2 &mpic 1 1
174 1800 0 0 3 &mpic 32 1 189 1800 0 0 3 &mpic 2 1
175 1800 0 0 4 &mpic 33 1 190 1800 0 0 4 &mpic 3 1
176 191
177 /* IDSEL 0x04 */ 192 /* IDSEL 0x04 */
178 2000 0 0 1 &mpic 33 1 193 2000 0 0 1 &mpic 3 1
179 2000 0 0 2 &mpic 34 1 194 2000 0 0 2 &mpic 4 1
180 2000 0 0 3 &mpic 31 1 195 2000 0 0 3 &mpic 1 1
181 2000 0 0 4 &mpic 32 1 196 2000 0 0 4 &mpic 2 1
182 197
183 /* IDSEL 0x05 */ 198 /* IDSEL 0x05 */
184 2800 0 0 1 &mpic 32 1 199 2800 0 0 1 &mpic 2 1
185 2800 0 0 2 &mpic 33 1 200 2800 0 0 2 &mpic 3 1
186 2800 0 0 3 &mpic 34 1 201 2800 0 0 3 &mpic 4 1
187 2800 0 0 4 &mpic 31 1 202 2800 0 0 4 &mpic 1 1
188 203
189 /* IDSEL 0x0c */ 204 /* IDSEL 0x0c */
190 6000 0 0 1 &mpic 31 1 205 6000 0 0 1 &mpic 1 1
191 6000 0 0 2 &mpic 32 1 206 6000 0 0 2 &mpic 2 1
192 6000 0 0 3 &mpic 33 1 207 6000 0 0 3 &mpic 3 1
193 6000 0 0 4 &mpic 34 1 208 6000 0 0 4 &mpic 4 1
194 209
195 /* IDSEL 0x0d */ 210 /* IDSEL 0x0d */
196 6800 0 0 1 &mpic 34 1 211 6800 0 0 1 &mpic 4 1
197 6800 0 0 2 &mpic 31 1 212 6800 0 0 2 &mpic 1 1
198 6800 0 0 3 &mpic 32 1 213 6800 0 0 3 &mpic 2 1
199 6800 0 0 4 &mpic 33 1 214 6800 0 0 4 &mpic 3 1
200 215
201 /* IDSEL 0x0e */ 216 /* IDSEL 0x0e */
202 7000 0 0 1 &mpic 33 1 217 7000 0 0 1 &mpic 3 1
203 7000 0 0 2 &mpic 34 1 218 7000 0 0 2 &mpic 4 1
204 7000 0 0 3 &mpic 31 1 219 7000 0 0 3 &mpic 1 1
205 7000 0 0 4 &mpic 32 1 220 7000 0 0 4 &mpic 2 1
206 221
207 /* IDSEL 0x0f */ 222 /* IDSEL 0x0f */
208 7800 0 0 1 &mpic 32 1 223 7800 0 0 1 &mpic 2 1
209 7800 0 0 2 &mpic 33 1 224 7800 0 0 2 &mpic 3 1
210 7800 0 0 3 &mpic 34 1 225 7800 0 0 3 &mpic 4 1
211 7800 0 0 4 &mpic 31 1 226 7800 0 0 4 &mpic 1 1
212 227
213 /* IDSEL 0x12 */ 228 /* IDSEL 0x12 */
214 9000 0 0 1 &mpic 31 1 229 9000 0 0 1 &mpic 1 1
215 9000 0 0 2 &mpic 32 1 230 9000 0 0 2 &mpic 2 1
216 9000 0 0 3 &mpic 33 1 231 9000 0 0 3 &mpic 3 1
217 9000 0 0 4 &mpic 34 1 232 9000 0 0 4 &mpic 4 1
218 233
219 /* IDSEL 0x13 */ 234 /* IDSEL 0x13 */
220 9800 0 0 1 &mpic 34 1 235 9800 0 0 1 &mpic 4 1
221 9800 0 0 2 &mpic 31 1 236 9800 0 0 2 &mpic 1 1
222 9800 0 0 3 &mpic 32 1 237 9800 0 0 3 &mpic 2 1
223 9800 0 0 4 &mpic 33 1 238 9800 0 0 4 &mpic 3 1
224 239
225 /* IDSEL 0x14 */ 240 /* IDSEL 0x14 */
226 a000 0 0 1 &mpic 33 1 241 a000 0 0 1 &mpic 3 1
227 a000 0 0 2 &mpic 34 1 242 a000 0 0 2 &mpic 4 1
228 a000 0 0 3 &mpic 31 1 243 a000 0 0 3 &mpic 1 1
229 a000 0 0 4 &mpic 32 1 244 a000 0 0 4 &mpic 2 1
230 245
231 /* IDSEL 0x15 */ 246 /* IDSEL 0x15 */
232 a800 0 0 1 &mpic 32 1 247 a800 0 0 1 &mpic 2 1
233 a800 0 0 2 &mpic 33 1 248 a800 0 0 2 &mpic 3 1
234 a800 0 0 3 &mpic 34 1 249 a800 0 0 3 &mpic 4 1
235 a800 0 0 4 &mpic 31 1>; 250 a800 0 0 4 &mpic 1 1>;
236 interrupt-parent = <&mpic>; 251 interrupt-parent = <&mpic>;
237 interrupts = <08 2>; 252 interrupts = <18 2>;
238 bus-range = <0 0>; 253 bus-range = <0 0>;
239 ranges = <02000000 0 80000000 80000000 0 20000000 254 ranges = <02000000 0 80000000 80000000 0 20000000
240 01000000 0 00000000 e2000000 0 00100000>; 255 01000000 0 00000000 e2000000 0 00100000>;
diff --git a/arch/powerpc/boot/dts/mpc8541cds.dts b/arch/powerpc/boot/dts/mpc8541cds.dts
index 4f2c3af2e052..070206fffe88 100644
--- a/arch/powerpc/boot/dts/mpc8541cds.dts
+++ b/arch/powerpc/boot/dts/mpc8541cds.dts
@@ -52,7 +52,7 @@
52 compatible = "fsl,8541-memory-controller"; 52 compatible = "fsl,8541-memory-controller";
53 reg = <2000 1000>; 53 reg = <2000 1000>;
54 interrupt-parent = <&mpic>; 54 interrupt-parent = <&mpic>;
55 interrupts = <2 2>; 55 interrupts = <12 2>;
56 }; 56 };
57 57
58 l2-cache-controller@20000 { 58 l2-cache-controller@20000 {
@@ -61,14 +61,14 @@
61 cache-line-size = <20>; // 32 bytes 61 cache-line-size = <20>; // 32 bytes
62 cache-size = <40000>; // L2, 256K 62 cache-size = <40000>; // L2, 256K
63 interrupt-parent = <&mpic>; 63 interrupt-parent = <&mpic>;
64 interrupts = <0 2>; 64 interrupts = <10 2>;
65 }; 65 };
66 66
67 i2c@3000 { 67 i2c@3000 {
68 device_type = "i2c"; 68 device_type = "i2c";
69 compatible = "fsl-i2c"; 69 compatible = "fsl-i2c";
70 reg = <3000 100>; 70 reg = <3000 100>;
71 interrupts = <1b 2>; 71 interrupts = <2b 2>;
72 interrupt-parent = <&mpic>; 72 interrupt-parent = <&mpic>;
73 dfsrr; 73 dfsrr;
74 }; 74 };
@@ -81,13 +81,13 @@
81 reg = <24520 20>; 81 reg = <24520 20>;
82 phy0: ethernet-phy@0 { 82 phy0: ethernet-phy@0 {
83 interrupt-parent = <&mpic>; 83 interrupt-parent = <&mpic>;
84 interrupts = <35 0>; 84 interrupts = <5 1>;
85 reg = <0>; 85 reg = <0>;
86 device_type = "ethernet-phy"; 86 device_type = "ethernet-phy";
87 }; 87 };
88 phy1: ethernet-phy@1 { 88 phy1: ethernet-phy@1 {
89 interrupt-parent = <&mpic>; 89 interrupt-parent = <&mpic>;
90 interrupts = <35 0>; 90 interrupts = <5 1>;
91 reg = <1>; 91 reg = <1>;
92 device_type = "ethernet-phy"; 92 device_type = "ethernet-phy";
93 }; 93 };
@@ -100,8 +100,8 @@
100 model = "TSEC"; 100 model = "TSEC";
101 compatible = "gianfar"; 101 compatible = "gianfar";
102 reg = <24000 1000>; 102 reg = <24000 1000>;
103 local-mac-address = [ 00 E0 0C 00 73 00 ]; 103 local-mac-address = [ 00 00 00 00 00 00 ];
104 interrupts = <d 2 e 2 12 2>; 104 interrupts = <1d 2 1e 2 22 2>;
105 interrupt-parent = <&mpic>; 105 interrupt-parent = <&mpic>;
106 phy-handle = <&phy0>; 106 phy-handle = <&phy0>;
107 }; 107 };
@@ -113,8 +113,8 @@
113 model = "TSEC"; 113 model = "TSEC";
114 compatible = "gianfar"; 114 compatible = "gianfar";
115 reg = <25000 1000>; 115 reg = <25000 1000>;
116 local-mac-address = [ 00 E0 0C 00 73 01 ]; 116 local-mac-address = [ 00 00 00 00 00 00 ];
117 interrupts = <13 2 14 2 18 2>; 117 interrupts = <23 2 24 2 28 2>;
118 interrupt-parent = <&mpic>; 118 interrupt-parent = <&mpic>;
119 phy-handle = <&phy1>; 119 phy-handle = <&phy1>;
120 }; 120 };
@@ -124,7 +124,7 @@
124 compatible = "ns16550"; 124 compatible = "ns16550";
125 reg = <4500 100>; // reg base, size 125 reg = <4500 100>; // reg base, size
126 clock-frequency = <0>; // should we fill in in uboot? 126 clock-frequency = <0>; // should we fill in in uboot?
127 interrupts = <1a 2>; 127 interrupts = <2a 2>;
128 interrupt-parent = <&mpic>; 128 interrupt-parent = <&mpic>;
129 }; 129 };
130 130
@@ -133,7 +133,7 @@
133 compatible = "ns16550"; 133 compatible = "ns16550";
134 reg = <4600 100>; // reg base, size 134 reg = <4600 100>; // reg base, size
135 clock-frequency = <0>; // should we fill in in uboot? 135 clock-frequency = <0>; // should we fill in in uboot?
136 interrupts = <1a 2>; 136 interrupts = <2a 2>;
137 interrupt-parent = <&mpic>; 137 interrupt-parent = <&mpic>;
138 }; 138 };
139 139
@@ -142,49 +142,49 @@
142 interrupt-map = < 142 interrupt-map = <
143 143
144 /* IDSEL 0x10 */ 144 /* IDSEL 0x10 */
145 08000 0 0 1 &mpic 30 1 145 08000 0 0 1 &mpic 0 1
146 08000 0 0 2 &mpic 31 1 146 08000 0 0 2 &mpic 1 1
147 08000 0 0 3 &mpic 32 1 147 08000 0 0 3 &mpic 2 1
148 08000 0 0 4 &mpic 33 1 148 08000 0 0 4 &mpic 3 1
149 149
150 /* IDSEL 0x11 */ 150 /* IDSEL 0x11 */
151 08800 0 0 1 &mpic 30 1 151 08800 0 0 1 &mpic 0 1
152 08800 0 0 2 &mpic 31 1 152 08800 0 0 2 &mpic 1 1
153 08800 0 0 3 &mpic 32 1 153 08800 0 0 3 &mpic 2 1
154 08800 0 0 4 &mpic 33 1 154 08800 0 0 4 &mpic 3 1
155 155
156 /* IDSEL 0x12 (Slot 1) */ 156 /* IDSEL 0x12 (Slot 1) */
157 09000 0 0 1 &mpic 30 1 157 09000 0 0 1 &mpic 0 1
158 09000 0 0 2 &mpic 31 1 158 09000 0 0 2 &mpic 1 1
159 09000 0 0 3 &mpic 32 1 159 09000 0 0 3 &mpic 2 1
160 09000 0 0 4 &mpic 33 1 160 09000 0 0 4 &mpic 3 1
161 161
162 /* IDSEL 0x13 (Slot 2) */ 162 /* IDSEL 0x13 (Slot 2) */
163 09800 0 0 1 &mpic 31 1 163 09800 0 0 1 &mpic 1 1
164 09800 0 0 2 &mpic 32 1 164 09800 0 0 2 &mpic 2 1
165 09800 0 0 3 &mpic 33 1 165 09800 0 0 3 &mpic 3 1
166 09800 0 0 4 &mpic 30 1 166 09800 0 0 4 &mpic 0 1
167 167
168 /* IDSEL 0x14 (Slot 3) */ 168 /* IDSEL 0x14 (Slot 3) */
169 0a000 0 0 1 &mpic 32 1 169 0a000 0 0 1 &mpic 2 1
170 0a000 0 0 2 &mpic 33 1 170 0a000 0 0 2 &mpic 3 1
171 0a000 0 0 3 &mpic 30 1 171 0a000 0 0 3 &mpic 0 1
172 0a000 0 0 4 &mpic 31 1 172 0a000 0 0 4 &mpic 1 1
173 173
174 /* IDSEL 0x15 (Slot 4) */ 174 /* IDSEL 0x15 (Slot 4) */
175 0a800 0 0 1 &mpic 33 1 175 0a800 0 0 1 &mpic 3 1
176 0a800 0 0 2 &mpic 30 1 176 0a800 0 0 2 &mpic 0 1
177 0a800 0 0 3 &mpic 31 1 177 0a800 0 0 3 &mpic 1 1
178 0a800 0 0 4 &mpic 32 1 178 0a800 0 0 4 &mpic 2 1
179 179
180 /* Bus 1 (Tundra Bridge) */ 180 /* Bus 1 (Tundra Bridge) */
181 /* IDSEL 0x12 (ISA bridge) */ 181 /* IDSEL 0x12 (ISA bridge) */
182 19000 0 0 1 &mpic 30 1 182 19000 0 0 1 &mpic 0 1
183 19000 0 0 2 &mpic 31 1 183 19000 0 0 2 &mpic 1 1
184 19000 0 0 3 &mpic 32 1 184 19000 0 0 3 &mpic 2 1
185 19000 0 0 4 &mpic 33 1>; 185 19000 0 0 4 &mpic 3 1>;
186 interrupt-parent = <&mpic>; 186 interrupt-parent = <&mpic>;
187 interrupts = <08 2>; 187 interrupts = <18 2>;
188 bus-range = <0 0>; 188 bus-range = <0 0>;
189 ranges = <02000000 0 80000000 80000000 0 20000000 189 ranges = <02000000 0 80000000 80000000 0 20000000
190 01000000 0 00000000 e2000000 0 00100000>; 190 01000000 0 00000000 e2000000 0 00100000>;
@@ -216,12 +216,12 @@
216 interrupt-map = < 216 interrupt-map = <
217 217
218 /* IDSEL 0x15 */ 218 /* IDSEL 0x15 */
219 a800 0 0 1 &mpic 3b 1 219 a800 0 0 1 &mpic b 1
220 a800 0 0 2 &mpic 3b 1 220 a800 0 0 2 &mpic b 1
221 a800 0 0 3 &mpic 3b 1 221 a800 0 0 3 &mpic b 1
222 a800 0 0 4 &mpic 3b 1>; 222 a800 0 0 4 &mpic b 1>;
223 interrupt-parent = <&mpic>; 223 interrupt-parent = <&mpic>;
224 interrupts = <09 2>; 224 interrupts = <19 2>;
225 bus-range = <0 0>; 225 bus-range = <0 0>;
226 ranges = <02000000 0 a0000000 a0000000 0 20000000 226 ranges = <02000000 0 a0000000 a0000000 0 20000000
227 01000000 0 00000000 e3000000 0 00100000>; 227 01000000 0 00000000 e3000000 0 00100000>;
diff --git a/arch/powerpc/boot/dts/mpc8544ds.dts b/arch/powerpc/boot/dts/mpc8544ds.dts
index 3033599e74e8..828592592460 100644
--- a/arch/powerpc/boot/dts/mpc8544ds.dts
+++ b/arch/powerpc/boot/dts/mpc8544ds.dts
@@ -52,7 +52,7 @@
52 compatible = "fsl,8544-memory-controller"; 52 compatible = "fsl,8544-memory-controller";
53 reg = <2000 1000>; 53 reg = <2000 1000>;
54 interrupt-parent = <&mpic>; 54 interrupt-parent = <&mpic>;
55 interrupts = <2 2>; 55 interrupts = <12 2>;
56 }; 56 };
57 57
58 l2-cache-controller@20000 { 58 l2-cache-controller@20000 {
@@ -61,14 +61,14 @@
61 cache-line-size = <20>; // 32 bytes 61 cache-line-size = <20>; // 32 bytes
62 cache-size = <40000>; // L2, 256K 62 cache-size = <40000>; // L2, 256K
63 interrupt-parent = <&mpic>; 63 interrupt-parent = <&mpic>;
64 interrupts = <0 2>; 64 interrupts = <10 2>;
65 }; 65 };
66 66
67 i2c@3000 { 67 i2c@3000 {
68 device_type = "i2c"; 68 device_type = "i2c";
69 compatible = "fsl-i2c"; 69 compatible = "fsl-i2c";
70 reg = <3000 100>; 70 reg = <3000 100>;
71 interrupts = <1b 2>; 71 interrupts = <2b 2>;
72 interrupt-parent = <&mpic>; 72 interrupt-parent = <&mpic>;
73 dfsrr; 73 dfsrr;
74 }; 74 };
@@ -81,13 +81,13 @@
81 reg = <24520 20>; 81 reg = <24520 20>;
82 phy0: ethernet-phy@0 { 82 phy0: ethernet-phy@0 {
83 interrupt-parent = <&mpic>; 83 interrupt-parent = <&mpic>;
84 interrupts = <3a 1>; 84 interrupts = <a 1>;
85 reg = <0>; 85 reg = <0>;
86 device_type = "ethernet-phy"; 86 device_type = "ethernet-phy";
87 }; 87 };
88 phy1: ethernet-phy@1 { 88 phy1: ethernet-phy@1 {
89 interrupt-parent = <&mpic>; 89 interrupt-parent = <&mpic>;
90 interrupts = <3a 1>; 90 interrupts = <a 1>;
91 reg = <1>; 91 reg = <1>;
92 device_type = "ethernet-phy"; 92 device_type = "ethernet-phy";
93 }; 93 };
@@ -101,7 +101,7 @@
101 compatible = "gianfar"; 101 compatible = "gianfar";
102 reg = <24000 1000>; 102 reg = <24000 1000>;
103 local-mac-address = [ 00 00 00 00 00 00 ]; 103 local-mac-address = [ 00 00 00 00 00 00 ];
104 interrupts = <d 2 e 2 12 2>; 104 interrupts = <1d 2 1e 2 22 2>;
105 interrupt-parent = <&mpic>; 105 interrupt-parent = <&mpic>;
106 phy-handle = <&phy0>; 106 phy-handle = <&phy0>;
107 }; 107 };
@@ -114,7 +114,7 @@
114 compatible = "gianfar"; 114 compatible = "gianfar";
115 reg = <26000 1000>; 115 reg = <26000 1000>;
116 local-mac-address = [ 00 00 00 00 00 00 ]; 116 local-mac-address = [ 00 00 00 00 00 00 ];
117 interrupts = <f 2 10 2 11 2>; 117 interrupts = <1f 2 20 2 21 2>;
118 interrupt-parent = <&mpic>; 118 interrupt-parent = <&mpic>;
119 phy-handle = <&phy1>; 119 phy-handle = <&phy1>;
120 }; 120 };
@@ -124,7 +124,7 @@
124 compatible = "ns16550"; 124 compatible = "ns16550";
125 reg = <4500 100>; 125 reg = <4500 100>;
126 clock-frequency = <0>; 126 clock-frequency = <0>;
127 interrupts = <1a 2>; 127 interrupts = <2a 2>;
128 interrupt-parent = <&mpic>; 128 interrupt-parent = <&mpic>;
129 }; 129 };
130 130
@@ -133,7 +133,7 @@
133 compatible = "ns16550"; 133 compatible = "ns16550";
134 reg = <4600 100>; 134 reg = <4600 100>;
135 clock-frequency = <0>; 135 clock-frequency = <0>;
136 interrupts = <1a 2>; 136 interrupts = <2a 2>;
137 interrupt-parent = <&mpic>; 137 interrupt-parent = <&mpic>;
138 }; 138 };
139 139
diff --git a/arch/powerpc/boot/dts/mpc8548cds.dts b/arch/powerpc/boot/dts/mpc8548cds.dts
index ad96381033c0..9d0b84b66cd4 100644
--- a/arch/powerpc/boot/dts/mpc8548cds.dts
+++ b/arch/powerpc/boot/dts/mpc8548cds.dts
@@ -52,7 +52,7 @@
52 compatible = "fsl,8548-memory-controller"; 52 compatible = "fsl,8548-memory-controller";
53 reg = <2000 1000>; 53 reg = <2000 1000>;
54 interrupt-parent = <&mpic>; 54 interrupt-parent = <&mpic>;
55 interrupts = <2 2>; 55 interrupts = <12 2>;
56 }; 56 };
57 57
58 l2-cache-controller@20000 { 58 l2-cache-controller@20000 {
@@ -61,14 +61,14 @@
61 cache-line-size = <20>; // 32 bytes 61 cache-line-size = <20>; // 32 bytes
62 cache-size = <80000>; // L2, 512K 62 cache-size = <80000>; // L2, 512K
63 interrupt-parent = <&mpic>; 63 interrupt-parent = <&mpic>;
64 interrupts = <0 2>; 64 interrupts = <10 2>;
65 }; 65 };
66 66
67 i2c@3000 { 67 i2c@3000 {
68 device_type = "i2c"; 68 device_type = "i2c";
69 compatible = "fsl-i2c"; 69 compatible = "fsl-i2c";
70 reg = <3000 100>; 70 reg = <3000 100>;
71 interrupts = <1b 2>; 71 interrupts = <2b 2>;
72 interrupt-parent = <&mpic>; 72 interrupt-parent = <&mpic>;
73 dfsrr; 73 dfsrr;
74 }; 74 };
@@ -81,25 +81,25 @@
81 reg = <24520 20>; 81 reg = <24520 20>;
82 phy0: ethernet-phy@0 { 82 phy0: ethernet-phy@0 {
83 interrupt-parent = <&mpic>; 83 interrupt-parent = <&mpic>;
84 interrupts = <35 0>; 84 interrupts = <5 1>;
85 reg = <0>; 85 reg = <0>;
86 device_type = "ethernet-phy"; 86 device_type = "ethernet-phy";
87 }; 87 };
88 phy1: ethernet-phy@1 { 88 phy1: ethernet-phy@1 {
89 interrupt-parent = <&mpic>; 89 interrupt-parent = <&mpic>;
90 interrupts = <35 0>; 90 interrupts = <5 1>;
91 reg = <1>; 91 reg = <1>;
92 device_type = "ethernet-phy"; 92 device_type = "ethernet-phy";
93 }; 93 };
94 phy2: ethernet-phy@2 { 94 phy2: ethernet-phy@2 {
95 interrupt-parent = <&mpic>; 95 interrupt-parent = <&mpic>;
96 interrupts = <35 0>; 96 interrupts = <5 1>;
97 reg = <2>; 97 reg = <2>;
98 device_type = "ethernet-phy"; 98 device_type = "ethernet-phy";
99 }; 99 };
100 phy3: ethernet-phy@3 { 100 phy3: ethernet-phy@3 {
101 interrupt-parent = <&mpic>; 101 interrupt-parent = <&mpic>;
102 interrupts = <35 0>; 102 interrupts = <5 1>;
103 reg = <3>; 103 reg = <3>;
104 device_type = "ethernet-phy"; 104 device_type = "ethernet-phy";
105 }; 105 };
@@ -112,8 +112,8 @@
112 model = "eTSEC"; 112 model = "eTSEC";
113 compatible = "gianfar"; 113 compatible = "gianfar";
114 reg = <24000 1000>; 114 reg = <24000 1000>;
115 local-mac-address = [ 00 E0 0C 00 73 00 ]; 115 local-mac-address = [ 00 00 00 00 00 00 ];
116 interrupts = <d 2 e 2 12 2>; 116 interrupts = <1d 2 1e 2 22 2>;
117 interrupt-parent = <&mpic>; 117 interrupt-parent = <&mpic>;
118 phy-handle = <&phy0>; 118 phy-handle = <&phy0>;
119 }; 119 };
@@ -125,8 +125,8 @@
125 model = "eTSEC"; 125 model = "eTSEC";
126 compatible = "gianfar"; 126 compatible = "gianfar";
127 reg = <25000 1000>; 127 reg = <25000 1000>;
128 local-mac-address = [ 00 E0 0C 00 73 01 ]; 128 local-mac-address = [ 00 00 00 00 00 00 ];
129 interrupts = <13 2 14 2 18 2>; 129 interrupts = <23 2 24 2 28 2>;
130 interrupt-parent = <&mpic>; 130 interrupt-parent = <&mpic>;
131 phy-handle = <&phy1>; 131 phy-handle = <&phy1>;
132 }; 132 };
@@ -139,8 +139,8 @@
139 model = "eTSEC"; 139 model = "eTSEC";
140 compatible = "gianfar"; 140 compatible = "gianfar";
141 reg = <26000 1000>; 141 reg = <26000 1000>;
142 local-mac-address = [ 00 E0 0C 00 73 02 ]; 142 local-mac-address = [ 00 00 00 00 00 00 ];
143 interrupts = <f 2 10 2 11 2>; 143 interrupts = <1f 2 20 2 21 2>;
144 interrupt-parent = <&mpic>; 144 interrupt-parent = <&mpic>;
145 phy-handle = <&phy2>; 145 phy-handle = <&phy2>;
146 }; 146 };
@@ -152,8 +152,8 @@
152 model = "eTSEC"; 152 model = "eTSEC";
153 compatible = "gianfar"; 153 compatible = "gianfar";
154 reg = <27000 1000>; 154 reg = <27000 1000>;
155 local-mac-address = [ 00 E0 0C 00 73 03 ]; 155 local-mac-address = [ 00 00 00 00 00 00 ];
156 interrupts = <15 2 16 2 17 2>; 156 interrupts = <25 2 26 2 27 2>;
157 interrupt-parent = <&mpic>; 157 interrupt-parent = <&mpic>;
158 phy-handle = <&phy3>; 158 phy-handle = <&phy3>;
159 }; 159 };
@@ -164,7 +164,7 @@
164 compatible = "ns16550"; 164 compatible = "ns16550";
165 reg = <4500 100>; // reg base, size 165 reg = <4500 100>; // reg base, size
166 clock-frequency = <0>; // should we fill in in uboot? 166 clock-frequency = <0>; // should we fill in in uboot?
167 interrupts = <1a 2>; 167 interrupts = <2a 2>;
168 interrupt-parent = <&mpic>; 168 interrupt-parent = <&mpic>;
169 }; 169 };
170 170
@@ -173,58 +173,64 @@
173 compatible = "ns16550"; 173 compatible = "ns16550";
174 reg = <4600 100>; // reg base, size 174 reg = <4600 100>; // reg base, size
175 clock-frequency = <0>; // should we fill in in uboot? 175 clock-frequency = <0>; // should we fill in in uboot?
176 interrupts = <1a 2>; 176 interrupts = <2a 2>;
177 interrupt-parent = <&mpic>; 177 interrupt-parent = <&mpic>;
178 }; 178 };
179 179
180 global-utilities@e0000 { //global utilities reg
181 compatible = "fsl,mpc8548-guts";
182 reg = <e0000 1000>;
183 fsl,has-rstcr;
184 };
185
180 pci1: pci@8000 { 186 pci1: pci@8000 {
181 interrupt-map-mask = <1f800 0 0 7>; 187 interrupt-map-mask = <1f800 0 0 7>;
182 interrupt-map = < 188 interrupt-map = <
183 189
184 /* IDSEL 0x10 */ 190 /* IDSEL 0x10 */
185 08000 0 0 1 &mpic 30 1 191 08000 0 0 1 &mpic 0 1
186 08000 0 0 2 &mpic 31 1 192 08000 0 0 2 &mpic 1 1
187 08000 0 0 3 &mpic 32 1 193 08000 0 0 3 &mpic 2 1
188 08000 0 0 4 &mpic 33 1 194 08000 0 0 4 &mpic 3 1
189 195
190 /* IDSEL 0x11 */ 196 /* IDSEL 0x11 */
191 08800 0 0 1 &mpic 30 1 197 08800 0 0 1 &mpic 0 1
192 08800 0 0 2 &mpic 31 1 198 08800 0 0 2 &mpic 1 1
193 08800 0 0 3 &mpic 32 1 199 08800 0 0 3 &mpic 2 1
194 08800 0 0 4 &mpic 33 1 200 08800 0 0 4 &mpic 3 1
195 201
196 /* IDSEL 0x12 (Slot 1) */ 202 /* IDSEL 0x12 (Slot 1) */
197 09000 0 0 1 &mpic 30 1 203 09000 0 0 1 &mpic 0 1
198 09000 0 0 2 &mpic 31 1 204 09000 0 0 2 &mpic 1 1
199 09000 0 0 3 &mpic 32 1 205 09000 0 0 3 &mpic 2 1
200 09000 0 0 4 &mpic 33 1 206 09000 0 0 4 &mpic 3 1
201 207
202 /* IDSEL 0x13 (Slot 2) */ 208 /* IDSEL 0x13 (Slot 2) */
203 09800 0 0 1 &mpic 31 1 209 09800 0 0 1 &mpic 1 1
204 09800 0 0 2 &mpic 32 1 210 09800 0 0 2 &mpic 2 1
205 09800 0 0 3 &mpic 33 1 211 09800 0 0 3 &mpic 3 1
206 09800 0 0 4 &mpic 30 1 212 09800 0 0 4 &mpic 0 1
207 213
208 /* IDSEL 0x14 (Slot 3) */ 214 /* IDSEL 0x14 (Slot 3) */
209 0a000 0 0 1 &mpic 32 1 215 0a000 0 0 1 &mpic 2 1
210 0a000 0 0 2 &mpic 33 1 216 0a000 0 0 2 &mpic 3 1
211 0a000 0 0 3 &mpic 30 1 217 0a000 0 0 3 &mpic 0 1
212 0a000 0 0 4 &mpic 31 1 218 0a000 0 0 4 &mpic 1 1
213 219
214 /* IDSEL 0x15 (Slot 4) */ 220 /* IDSEL 0x15 (Slot 4) */
215 0a800 0 0 1 &mpic 33 1 221 0a800 0 0 1 &mpic 3 1
216 0a800 0 0 2 &mpic 30 1 222 0a800 0 0 2 &mpic 0 1
217 0a800 0 0 3 &mpic 31 1 223 0a800 0 0 3 &mpic 1 1
218 0a800 0 0 4 &mpic 32 1 224 0a800 0 0 4 &mpic 2 1
219 225
220 /* Bus 1 (Tundra Bridge) */ 226 /* Bus 1 (Tundra Bridge) */
221 /* IDSEL 0x12 (ISA bridge) */ 227 /* IDSEL 0x12 (ISA bridge) */
222 19000 0 0 1 &mpic 30 1 228 19000 0 0 1 &mpic 0 1
223 19000 0 0 2 &mpic 31 1 229 19000 0 0 2 &mpic 1 1
224 19000 0 0 3 &mpic 32 1 230 19000 0 0 3 &mpic 2 1
225 19000 0 0 4 &mpic 33 1>; 231 19000 0 0 4 &mpic 3 1>;
226 interrupt-parent = <&mpic>; 232 interrupt-parent = <&mpic>;
227 interrupts = <08 2>; 233 interrupts = <18 2>;
228 bus-range = <0 0>; 234 bus-range = <0 0>;
229 ranges = <02000000 0 80000000 80000000 0 20000000 235 ranges = <02000000 0 80000000 80000000 0 20000000
230 01000000 0 00000000 e2000000 0 00100000>; 236 01000000 0 00000000 e2000000 0 00100000>;
@@ -256,12 +262,12 @@
256 interrupt-map = < 262 interrupt-map = <
257 263
258 /* IDSEL 0x15 */ 264 /* IDSEL 0x15 */
259 a800 0 0 1 &mpic 3b 1 265 a800 0 0 1 &mpic b 1
260 a800 0 0 2 &mpic 3b 1 266 a800 0 0 2 &mpic b 1
261 a800 0 0 3 &mpic 3b 1 267 a800 0 0 3 &mpic b 1
262 a800 0 0 4 &mpic 3b 1>; 268 a800 0 0 4 &mpic b 1>;
263 interrupt-parent = <&mpic>; 269 interrupt-parent = <&mpic>;
264 interrupts = <09 2>; 270 interrupts = <19 2>;
265 bus-range = <0 0>; 271 bus-range = <0 0>;
266 ranges = <02000000 0 a0000000 a0000000 0 20000000 272 ranges = <02000000 0 a0000000 a0000000 0 20000000
267 01000000 0 00000000 e3000000 0 00100000>; 273 01000000 0 00000000 e3000000 0 00100000>;
diff --git a/arch/powerpc/boot/dts/mpc8555cds.dts b/arch/powerpc/boot/dts/mpc8555cds.dts
index 951ed92f1154..17e45d9a382a 100644
--- a/arch/powerpc/boot/dts/mpc8555cds.dts
+++ b/arch/powerpc/boot/dts/mpc8555cds.dts
@@ -52,7 +52,7 @@
52 compatible = "fsl,8555-memory-controller"; 52 compatible = "fsl,8555-memory-controller";
53 reg = <2000 1000>; 53 reg = <2000 1000>;
54 interrupt-parent = <&mpic>; 54 interrupt-parent = <&mpic>;
55 interrupts = <2 2>; 55 interrupts = <12 2>;
56 }; 56 };
57 57
58 l2-cache-controller@20000 { 58 l2-cache-controller@20000 {
@@ -61,14 +61,14 @@
61 cache-line-size = <20>; // 32 bytes 61 cache-line-size = <20>; // 32 bytes
62 cache-size = <40000>; // L2, 256K 62 cache-size = <40000>; // L2, 256K
63 interrupt-parent = <&mpic>; 63 interrupt-parent = <&mpic>;
64 interrupts = <0 2>; 64 interrupts = <10 2>;
65 }; 65 };
66 66
67 i2c@3000 { 67 i2c@3000 {
68 device_type = "i2c"; 68 device_type = "i2c";
69 compatible = "fsl-i2c"; 69 compatible = "fsl-i2c";
70 reg = <3000 100>; 70 reg = <3000 100>;
71 interrupts = <1b 2>; 71 interrupts = <2b 2>;
72 interrupt-parent = <&mpic>; 72 interrupt-parent = <&mpic>;
73 dfsrr; 73 dfsrr;
74 }; 74 };
@@ -81,13 +81,13 @@
81 reg = <24520 20>; 81 reg = <24520 20>;
82 phy0: ethernet-phy@0 { 82 phy0: ethernet-phy@0 {
83 interrupt-parent = <&mpic>; 83 interrupt-parent = <&mpic>;
84 interrupts = <35 0>; 84 interrupts = <5 1>;
85 reg = <0>; 85 reg = <0>;
86 device_type = "ethernet-phy"; 86 device_type = "ethernet-phy";
87 }; 87 };
88 phy1: ethernet-phy@1 { 88 phy1: ethernet-phy@1 {
89 interrupt-parent = <&mpic>; 89 interrupt-parent = <&mpic>;
90 interrupts = <35 0>; 90 interrupts = <5 1>;
91 reg = <1>; 91 reg = <1>;
92 device_type = "ethernet-phy"; 92 device_type = "ethernet-phy";
93 }; 93 };
@@ -100,8 +100,8 @@
100 model = "TSEC"; 100 model = "TSEC";
101 compatible = "gianfar"; 101 compatible = "gianfar";
102 reg = <24000 1000>; 102 reg = <24000 1000>;
103 local-mac-address = [ 00 E0 0C 00 73 00 ]; 103 local-mac-address = [ 00 00 00 00 00 00 ];
104 interrupts = <0d 2 0e 2 12 2>; 104 interrupts = <1d 2 1e 2 22 2>;
105 interrupt-parent = <&mpic>; 105 interrupt-parent = <&mpic>;
106 phy-handle = <&phy0>; 106 phy-handle = <&phy0>;
107 }; 107 };
@@ -113,8 +113,8 @@
113 model = "TSEC"; 113 model = "TSEC";
114 compatible = "gianfar"; 114 compatible = "gianfar";
115 reg = <25000 1000>; 115 reg = <25000 1000>;
116 local-mac-address = [ 00 E0 0C 00 73 01 ]; 116 local-mac-address = [ 00 00 00 00 00 00 ];
117 interrupts = <13 2 14 2 18 2>; 117 interrupts = <23 2 24 2 28 2>;
118 interrupt-parent = <&mpic>; 118 interrupt-parent = <&mpic>;
119 phy-handle = <&phy1>; 119 phy-handle = <&phy1>;
120 }; 120 };
@@ -124,7 +124,7 @@
124 compatible = "ns16550"; 124 compatible = "ns16550";
125 reg = <4500 100>; // reg base, size 125 reg = <4500 100>; // reg base, size
126 clock-frequency = <0>; // should we fill in in uboot? 126 clock-frequency = <0>; // should we fill in in uboot?
127 interrupts = <1a 2>; 127 interrupts = <2a 2>;
128 interrupt-parent = <&mpic>; 128 interrupt-parent = <&mpic>;
129 }; 129 };
130 130
@@ -133,7 +133,7 @@
133 compatible = "ns16550"; 133 compatible = "ns16550";
134 reg = <4600 100>; // reg base, size 134 reg = <4600 100>; // reg base, size
135 clock-frequency = <0>; // should we fill in in uboot? 135 clock-frequency = <0>; // should we fill in in uboot?
136 interrupts = <1a 2>; 136 interrupts = <2a 2>;
137 interrupt-parent = <&mpic>; 137 interrupt-parent = <&mpic>;
138 }; 138 };
139 139
@@ -142,49 +142,49 @@
142 interrupt-map = < 142 interrupt-map = <
143 143
144 /* IDSEL 0x10 */ 144 /* IDSEL 0x10 */
145 08000 0 0 1 &mpic 30 1 145 08000 0 0 1 &mpic 0 1
146 08000 0 0 2 &mpic 31 1 146 08000 0 0 2 &mpic 1 1
147 08000 0 0 3 &mpic 32 1 147 08000 0 0 3 &mpic 2 1
148 08000 0 0 4 &mpic 33 1 148 08000 0 0 4 &mpic 3 1
149 149
150 /* IDSEL 0x11 */ 150 /* IDSEL 0x11 */
151 08800 0 0 1 &mpic 30 1 151 08800 0 0 1 &mpic 0 1
152 08800 0 0 2 &mpic 31 1 152 08800 0 0 2 &mpic 1 1
153 08800 0 0 3 &mpic 32 1 153 08800 0 0 3 &mpic 2 1
154 08800 0 0 4 &mpic 33 1 154 08800 0 0 4 &mpic 3 1
155 155
156 /* IDSEL 0x12 (Slot 1) */ 156 /* IDSEL 0x12 (Slot 1) */
157 09000 0 0 1 &mpic 30 1 157 09000 0 0 1 &mpic 0 1
158 09000 0 0 2 &mpic 31 1 158 09000 0 0 2 &mpic 1 1
159 09000 0 0 3 &mpic 32 1 159 09000 0 0 3 &mpic 2 1
160 09000 0 0 4 &mpic 33 1 160 09000 0 0 4 &mpic 3 1
161 161
162 /* IDSEL 0x13 (Slot 2) */ 162 /* IDSEL 0x13 (Slot 2) */
163 09800 0 0 1 &mpic 31 1 163 09800 0 0 1 &mpic 1 1
164 09800 0 0 2 &mpic 32 1 164 09800 0 0 2 &mpic 2 1
165 09800 0 0 3 &mpic 33 1 165 09800 0 0 3 &mpic 3 1
166 09800 0 0 4 &mpic 30 1 166 09800 0 0 4 &mpic 0 1
167 167
168 /* IDSEL 0x14 (Slot 3) */ 168 /* IDSEL 0x14 (Slot 3) */
169 0a000 0 0 1 &mpic 32 1 169 0a000 0 0 1 &mpic 2 1
170 0a000 0 0 2 &mpic 33 1 170 0a000 0 0 2 &mpic 3 1
171 0a000 0 0 3 &mpic 30 1 171 0a000 0 0 3 &mpic 0 1
172 0a000 0 0 4 &mpic 31 1 172 0a000 0 0 4 &mpic 1 1
173 173
174 /* IDSEL 0x15 (Slot 4) */ 174 /* IDSEL 0x15 (Slot 4) */
175 0a800 0 0 1 &mpic 33 1 175 0a800 0 0 1 &mpic 3 1
176 0a800 0 0 2 &mpic 30 1 176 0a800 0 0 2 &mpic 0 1
177 0a800 0 0 3 &mpic 31 1 177 0a800 0 0 3 &mpic 1 1
178 0a800 0 0 4 &mpic 32 1 178 0a800 0 0 4 &mpic 2 1
179 179
180 /* Bus 1 (Tundra Bridge) */ 180 /* Bus 1 (Tundra Bridge) */
181 /* IDSEL 0x12 (ISA bridge) */ 181 /* IDSEL 0x12 (ISA bridge) */
182 19000 0 0 1 &mpic 30 1 182 19000 0 0 1 &mpic 0 1
183 19000 0 0 2 &mpic 31 1 183 19000 0 0 2 &mpic 1 1
184 19000 0 0 3 &mpic 32 1 184 19000 0 0 3 &mpic 2 1
185 19000 0 0 4 &mpic 33 1>; 185 19000 0 0 4 &mpic 3 1>;
186 interrupt-parent = <&mpic>; 186 interrupt-parent = <&mpic>;
187 interrupts = <08 2>; 187 interrupts = <18 2>;
188 bus-range = <0 0>; 188 bus-range = <0 0>;
189 ranges = <02000000 0 80000000 80000000 0 20000000 189 ranges = <02000000 0 80000000 80000000 0 20000000
190 01000000 0 00000000 e2000000 0 00100000>; 190 01000000 0 00000000 e2000000 0 00100000>;
@@ -216,12 +216,12 @@
216 interrupt-map = < 216 interrupt-map = <
217 217
218 /* IDSEL 0x15 */ 218 /* IDSEL 0x15 */
219 a800 0 0 1 &mpic 3b 1 219 a800 0 0 1 &mpic b 1
220 a800 0 0 2 &mpic 3b 1 220 a800 0 0 2 &mpic b 1
221 a800 0 0 3 &mpic 3b 1 221 a800 0 0 3 &mpic b 1
222 a800 0 0 4 &mpic 3b 1>; 222 a800 0 0 4 &mpic b 1>;
223 interrupt-parent = <&mpic>; 223 interrupt-parent = <&mpic>;
224 interrupts = <09 2>; 224 interrupts = <19 2>;
225 bus-range = <0 0>; 225 bus-range = <0 0>;
226 ranges = <02000000 0 a0000000 a0000000 0 20000000 226 ranges = <02000000 0 a0000000 a0000000 0 20000000
227 01000000 0 00000000 e3000000 0 00100000>; 227 01000000 0 00000000 e3000000 0 00100000>;
diff --git a/arch/powerpc/boot/dts/mpc8560ads.dts b/arch/powerpc/boot/dts/mpc8560ads.dts
index 80682152b0cf..21ccaaa27993 100644
--- a/arch/powerpc/boot/dts/mpc8560ads.dts
+++ b/arch/powerpc/boot/dts/mpc8560ads.dts
@@ -52,7 +52,7 @@
52 compatible = "fsl,8540-memory-controller"; 52 compatible = "fsl,8540-memory-controller";
53 reg = <2000 1000>; 53 reg = <2000 1000>;
54 interrupt-parent = <&mpic>; 54 interrupt-parent = <&mpic>;
55 interrupts = <2 2>; 55 interrupts = <12 2>;
56 }; 56 };
57 57
58 l2-cache-controller@20000 { 58 l2-cache-controller@20000 {
@@ -61,7 +61,7 @@
61 cache-line-size = <20>; // 32 bytes 61 cache-line-size = <20>; // 32 bytes
62 cache-size = <40000>; // L2, 256K 62 cache-size = <40000>; // L2, 256K
63 interrupt-parent = <&mpic>; 63 interrupt-parent = <&mpic>;
64 interrupts = <0 2>; 64 interrupts = <10 2>;
65 }; 65 };
66 66
67 mdio@24520 { 67 mdio@24520 {
@@ -72,25 +72,25 @@
72 #size-cells = <0>; 72 #size-cells = <0>;
73 phy0: ethernet-phy@0 { 73 phy0: ethernet-phy@0 {
74 interrupt-parent = <&mpic>; 74 interrupt-parent = <&mpic>;
75 interrupts = <35 1>; 75 interrupts = <5 1>;
76 reg = <0>; 76 reg = <0>;
77 device_type = "ethernet-phy"; 77 device_type = "ethernet-phy";
78 }; 78 };
79 phy1: ethernet-phy@1 { 79 phy1: ethernet-phy@1 {
80 interrupt-parent = <&mpic>; 80 interrupt-parent = <&mpic>;
81 interrupts = <35 1>; 81 interrupts = <5 1>;
82 reg = <1>; 82 reg = <1>;
83 device_type = "ethernet-phy"; 83 device_type = "ethernet-phy";
84 }; 84 };
85 phy2: ethernet-phy@2 { 85 phy2: ethernet-phy@2 {
86 interrupt-parent = <&mpic>; 86 interrupt-parent = <&mpic>;
87 interrupts = <37 1>; 87 interrupts = <7 1>;
88 reg = <2>; 88 reg = <2>;
89 device_type = "ethernet-phy"; 89 device_type = "ethernet-phy";
90 }; 90 };
91 phy3: ethernet-phy@3 { 91 phy3: ethernet-phy@3 {
92 interrupt-parent = <&mpic>; 92 interrupt-parent = <&mpic>;
93 interrupts = <37 1>; 93 interrupts = <7 1>;
94 reg = <3>; 94 reg = <3>;
95 device_type = "ethernet-phy"; 95 device_type = "ethernet-phy";
96 }; 96 };
@@ -101,8 +101,14 @@
101 model = "TSEC"; 101 model = "TSEC";
102 compatible = "gianfar"; 102 compatible = "gianfar";
103 reg = <24000 1000>; 103 reg = <24000 1000>;
104 address = [ 00 00 0C 00 00 FD ]; 104 /*
105 interrupts = <d 2 e 2 12 2>; 105 * address is deprecated and will be removed
106 * in 2.6.25. Only recent versions of
107 * U-Boot support local-mac-address, however.
108 */
109 address = [ 00 00 00 00 00 00 ];
110 local-mac-address = [ 00 00 00 00 00 00 ];
111 interrupts = <1d 2 1e 2 22 2>;
106 interrupt-parent = <&mpic>; 112 interrupt-parent = <&mpic>;
107 phy-handle = <&phy0>; 113 phy-handle = <&phy0>;
108 }; 114 };
@@ -114,8 +120,14 @@
114 model = "TSEC"; 120 model = "TSEC";
115 compatible = "gianfar"; 121 compatible = "gianfar";
116 reg = <25000 1000>; 122 reg = <25000 1000>;
117 address = [ 00 00 0C 00 01 FD ]; 123 /*
118 interrupts = <13 2 14 2 18 2>; 124 * address is deprecated and will be removed
125 * in 2.6.25. Only recent versions of
126 * U-Boot support local-mac-address, however.
127 */
128 address = [ 00 00 00 00 00 00 ];
129 local-mac-address = [ 00 00 00 00 00 00 ];
130 interrupts = <23 2 24 2 28 2>;
119 interrupt-parent = <&mpic>; 131 interrupt-parent = <&mpic>;
120 phy-handle = <&phy1>; 132 phy-handle = <&phy1>;
121 }; 133 };
@@ -132,79 +144,79 @@
132 interrupt-map = < 144 interrupt-map = <
133 145
134 /* IDSEL 0x2 */ 146 /* IDSEL 0x2 */
135 1000 0 0 1 &mpic 31 1 147 1000 0 0 1 &mpic 1 1
136 1000 0 0 2 &mpic 32 1 148 1000 0 0 2 &mpic 2 1
137 1000 0 0 3 &mpic 33 1 149 1000 0 0 3 &mpic 3 1
138 1000 0 0 4 &mpic 34 1 150 1000 0 0 4 &mpic 4 1
139 151
140 /* IDSEL 0x3 */ 152 /* IDSEL 0x3 */
141 1800 0 0 1 &mpic 34 1 153 1800 0 0 1 &mpic 4 1
142 1800 0 0 2 &mpic 31 1 154 1800 0 0 2 &mpic 1 1
143 1800 0 0 3 &mpic 32 1 155 1800 0 0 3 &mpic 2 1
144 1800 0 0 4 &mpic 33 1 156 1800 0 0 4 &mpic 3 1
145 157
146 /* IDSEL 0x4 */ 158 /* IDSEL 0x4 */
147 2000 0 0 1 &mpic 33 1 159 2000 0 0 1 &mpic 3 1
148 2000 0 0 2 &mpic 34 1 160 2000 0 0 2 &mpic 4 1
149 2000 0 0 3 &mpic 31 1 161 2000 0 0 3 &mpic 1 1
150 2000 0 0 4 &mpic 32 1 162 2000 0 0 4 &mpic 2 1
151 163
152 /* IDSEL 0x5 */ 164 /* IDSEL 0x5 */
153 2800 0 0 1 &mpic 32 1 165 2800 0 0 1 &mpic 2 1
154 2800 0 0 2 &mpic 33 1 166 2800 0 0 2 &mpic 3 1
155 2800 0 0 3 &mpic 34 1 167 2800 0 0 3 &mpic 4 1
156 2800 0 0 4 &mpic 31 1 168 2800 0 0 4 &mpic 1 1
157 169
158 /* IDSEL 12 */ 170 /* IDSEL 12 */
159 6000 0 0 1 &mpic 31 1 171 6000 0 0 1 &mpic 1 1
160 6000 0 0 2 &mpic 32 1 172 6000 0 0 2 &mpic 2 1
161 6000 0 0 3 &mpic 33 1 173 6000 0 0 3 &mpic 3 1
162 6000 0 0 4 &mpic 34 1 174 6000 0 0 4 &mpic 4 1
163 175
164 /* IDSEL 13 */ 176 /* IDSEL 13 */
165 6800 0 0 1 &mpic 34 1 177 6800 0 0 1 &mpic 4 1
166 6800 0 0 2 &mpic 31 1 178 6800 0 0 2 &mpic 1 1
167 6800 0 0 3 &mpic 32 1 179 6800 0 0 3 &mpic 2 1
168 6800 0 0 4 &mpic 33 1 180 6800 0 0 4 &mpic 3 1
169 181
170 /* IDSEL 14*/ 182 /* IDSEL 14*/
171 7000 0 0 1 &mpic 33 1 183 7000 0 0 1 &mpic 3 1
172 7000 0 0 2 &mpic 34 1 184 7000 0 0 2 &mpic 4 1
173 7000 0 0 3 &mpic 31 1 185 7000 0 0 3 &mpic 1 1
174 7000 0 0 4 &mpic 32 1 186 7000 0 0 4 &mpic 2 1
175 187
176 /* IDSEL 15 */ 188 /* IDSEL 15 */
177 7800 0 0 1 &mpic 32 1 189 7800 0 0 1 &mpic 2 1
178 7800 0 0 2 &mpic 33 1 190 7800 0 0 2 &mpic 3 1
179 7800 0 0 3 &mpic 34 1 191 7800 0 0 3 &mpic 4 1
180 7800 0 0 4 &mpic 31 1 192 7800 0 0 4 &mpic 1 1
181 193
182 /* IDSEL 18 */ 194 /* IDSEL 18 */
183 9000 0 0 1 &mpic 31 1 195 9000 0 0 1 &mpic 1 1
184 9000 0 0 2 &mpic 32 1 196 9000 0 0 2 &mpic 2 1
185 9000 0 0 3 &mpic 33 1 197 9000 0 0 3 &mpic 3 1
186 9000 0 0 4 &mpic 34 1 198 9000 0 0 4 &mpic 4 1
187 199
188 /* IDSEL 19 */ 200 /* IDSEL 19 */
189 9800 0 0 1 &mpic 34 1 201 9800 0 0 1 &mpic 4 1
190 9800 0 0 2 &mpic 31 1 202 9800 0 0 2 &mpic 1 1
191 9800 0 0 3 &mpic 32 1 203 9800 0 0 3 &mpic 2 1
192 9800 0 0 4 &mpic 33 1 204 9800 0 0 4 &mpic 3 1
193 205
194 /* IDSEL 20 */ 206 /* IDSEL 20 */
195 a000 0 0 1 &mpic 33 1 207 a000 0 0 1 &mpic 3 1
196 a000 0 0 2 &mpic 34 1 208 a000 0 0 2 &mpic 4 1
197 a000 0 0 3 &mpic 31 1 209 a000 0 0 3 &mpic 1 1
198 a000 0 0 4 &mpic 32 1 210 a000 0 0 4 &mpic 2 1
199 211
200 /* IDSEL 21 */ 212 /* IDSEL 21 */
201 a800 0 0 1 &mpic 32 1 213 a800 0 0 1 &mpic 2 1
202 a800 0 0 2 &mpic 33 1 214 a800 0 0 2 &mpic 3 1
203 a800 0 0 3 &mpic 34 1 215 a800 0 0 3 &mpic 4 1
204 a800 0 0 4 &mpic 31 1>; 216 a800 0 0 4 &mpic 1 1>;
205 217
206 interrupt-parent = <&mpic>; 218 interrupt-parent = <&mpic>;
207 interrupts = <8 0>; 219 interrupts = <18 2>;
208 bus-range = <0 0>; 220 bus-range = <0 0>;
209 ranges = <02000000 0 80000000 80000000 0 20000000 221 ranges = <02000000 0 80000000 80000000 0 20000000
210 01000000 0 00000000 e2000000 0 01000000>; 222 01000000 0 00000000 e2000000 0 01000000>;
@@ -234,7 +246,7 @@
234 interrupt-controller; 246 interrupt-controller;
235 #address-cells = <0>; 247 #address-cells = <0>;
236 #interrupt-cells = <2>; 248 #interrupt-cells = <2>;
237 interrupts = <1e 0>; 249 interrupts = <2e 2>;
238 interrupt-parent = <&mpic>; 250 interrupt-parent = <&mpic>;
239 reg = <90c00 80>; 251 reg = <90c00 80>;
240 built-in; 252 built-in;
@@ -275,7 +287,13 @@
275 model = "FCC"; 287 model = "FCC";
276 device-id = <2>; 288 device-id = <2>;
277 reg = <91320 20 88500 100 913a0 30>; 289 reg = <91320 20 88500 100 913a0 30>;
278 mac-address = [ 00 00 0C 00 02 FD ]; 290 /*
291 * mac-address is deprecated and will be removed
292 * in 2.6.25. Only recent versions of
293 * U-Boot support local-mac-address, however.
294 */
295 mac-address = [ 00 00 00 00 00 00 ];
296 local-mac-address = [ 00 00 00 00 00 00 ];
279 clock-setup = <ff00ffff 250000>; 297 clock-setup = <ff00ffff 250000>;
280 rx-clock = <15>; 298 rx-clock = <15>;
281 tx-clock = <16>; 299 tx-clock = <16>;
@@ -290,7 +308,13 @@
290 model = "FCC"; 308 model = "FCC";
291 device-id = <3>; 309 device-id = <3>;
292 reg = <91340 20 88600 100 913d0 30>; 310 reg = <91340 20 88600 100 913d0 30>;
293 mac-address = [ 00 00 0C 00 03 FD ]; 311 /*
312 * mac-address is deprecated and will be removed
313 * in 2.6.25. Only recent versions of
314 * U-Boot support local-mac-address, however.
315 */
316 mac-address = [ 00 00 00 00 00 00 ];
317 local-mac-address = [ 00 00 00 00 00 00 ];
294 clock-setup = <ffff00ff 3700>; 318 clock-setup = <ffff00ff 3700>;
295 rx-clock = <17>; 319 rx-clock = <17>;
296 tx-clock = <18>; 320 tx-clock = <18>;
diff --git a/arch/powerpc/boot/dts/mpc8568mds.dts b/arch/powerpc/boot/dts/mpc8568mds.dts
index a123ec9456bc..6bb18f2807a8 100644
--- a/arch/powerpc/boot/dts/mpc8568mds.dts
+++ b/arch/powerpc/boot/dts/mpc8568mds.dts
@@ -61,7 +61,7 @@
61 compatible = "fsl,8568-memory-controller"; 61 compatible = "fsl,8568-memory-controller";
62 reg = <2000 1000>; 62 reg = <2000 1000>;
63 interrupt-parent = <&mpic>; 63 interrupt-parent = <&mpic>;
64 interrupts = <2 2>; 64 interrupts = <12 2>;
65 }; 65 };
66 66
67 l2-cache-controller@20000 { 67 l2-cache-controller@20000 {
@@ -70,14 +70,14 @@
70 cache-line-size = <20>; // 32 bytes 70 cache-line-size = <20>; // 32 bytes
71 cache-size = <80000>; // L2, 512K 71 cache-size = <80000>; // L2, 512K
72 interrupt-parent = <&mpic>; 72 interrupt-parent = <&mpic>;
73 interrupts = <0 2>; 73 interrupts = <10 2>;
74 }; 74 };
75 75
76 i2c@3000 { 76 i2c@3000 {
77 device_type = "i2c"; 77 device_type = "i2c";
78 compatible = "fsl-i2c"; 78 compatible = "fsl-i2c";
79 reg = <3000 100>; 79 reg = <3000 100>;
80 interrupts = <1b 2>; 80 interrupts = <2b 2>;
81 interrupt-parent = <&mpic>; 81 interrupt-parent = <&mpic>;
82 dfsrr; 82 dfsrr;
83 }; 83 };
@@ -86,7 +86,7 @@
86 device_type = "i2c"; 86 device_type = "i2c";
87 compatible = "fsl-i2c"; 87 compatible = "fsl-i2c";
88 reg = <3100 100>; 88 reg = <3100 100>;
89 interrupts = <1b 2>; 89 interrupts = <2b 2>;
90 interrupt-parent = <&mpic>; 90 interrupt-parent = <&mpic>;
91 dfsrr; 91 dfsrr;
92 }; 92 };
@@ -99,25 +99,25 @@
99 reg = <24520 20>; 99 reg = <24520 20>;
100 phy0: ethernet-phy@0 { 100 phy0: ethernet-phy@0 {
101 interrupt-parent = <&mpic>; 101 interrupt-parent = <&mpic>;
102 interrupts = <31 1>; 102 interrupts = <1 1>;
103 reg = <0>; 103 reg = <0>;
104 device_type = "ethernet-phy"; 104 device_type = "ethernet-phy";
105 }; 105 };
106 phy1: ethernet-phy@1 { 106 phy1: ethernet-phy@1 {
107 interrupt-parent = <&mpic>; 107 interrupt-parent = <&mpic>;
108 interrupts = <32 1>; 108 interrupts = <2 1>;
109 reg = <1>; 109 reg = <1>;
110 device_type = "ethernet-phy"; 110 device_type = "ethernet-phy";
111 }; 111 };
112 phy2: ethernet-phy@2 { 112 phy2: ethernet-phy@2 {
113 interrupt-parent = <&mpic>; 113 interrupt-parent = <&mpic>;
114 interrupts = <31 1>; 114 interrupts = <1 1>;
115 reg = <2>; 115 reg = <2>;
116 device_type = "ethernet-phy"; 116 device_type = "ethernet-phy";
117 }; 117 };
118 phy3: ethernet-phy@3 { 118 phy3: ethernet-phy@3 {
119 interrupt-parent = <&mpic>; 119 interrupt-parent = <&mpic>;
120 interrupts = <32 1>; 120 interrupts = <2 1>;
121 reg = <3>; 121 reg = <3>;
122 device_type = "ethernet-phy"; 122 device_type = "ethernet-phy";
123 }; 123 };
@@ -130,8 +130,14 @@
130 model = "eTSEC"; 130 model = "eTSEC";
131 compatible = "gianfar"; 131 compatible = "gianfar";
132 reg = <24000 1000>; 132 reg = <24000 1000>;
133 /*
134 * mac-address is deprecated and will be removed
135 * in 2.6.25. Only recent versions of
136 * U-Boot support local-mac-address, however.
137 */
133 mac-address = [ 00 00 00 00 00 00 ]; 138 mac-address = [ 00 00 00 00 00 00 ];
134 interrupts = <d 2 e 2 12 2>; 139 local-mac-address = [ 00 00 00 00 00 00 ];
140 interrupts = <1d 2 1e 2 22 2>;
135 interrupt-parent = <&mpic>; 141 interrupt-parent = <&mpic>;
136 phy-handle = <&phy2>; 142 phy-handle = <&phy2>;
137 }; 143 };
@@ -143,8 +149,14 @@
143 model = "eTSEC"; 149 model = "eTSEC";
144 compatible = "gianfar"; 150 compatible = "gianfar";
145 reg = <25000 1000>; 151 reg = <25000 1000>;
146 mac-address = [ 00 00 00 00 00 00]; 152 /*
147 interrupts = <13 2 14 2 18 2>; 153 * mac-address is deprecated and will be removed
154 * in 2.6.25. Only recent versions of
155 * U-Boot support local-mac-address, however.
156 */
157 mac-address = [ 00 00 00 00 00 00 ];
158 local-mac-address = [ 00 00 00 00 00 00 ];
159 interrupts = <23 2 24 2 28 2>;
148 interrupt-parent = <&mpic>; 160 interrupt-parent = <&mpic>;
149 phy-handle = <&phy3>; 161 phy-handle = <&phy3>;
150 }; 162 };
@@ -154,7 +166,7 @@
154 compatible = "ns16550"; 166 compatible = "ns16550";
155 reg = <4500 100>; 167 reg = <4500 100>;
156 clock-frequency = <0>; 168 clock-frequency = <0>;
157 interrupts = <1a 2>; 169 interrupts = <2a 2>;
158 interrupt-parent = <&mpic>; 170 interrupt-parent = <&mpic>;
159 }; 171 };
160 172
@@ -163,7 +175,7 @@
163 compatible = "ns16550"; 175 compatible = "ns16550";
164 reg = <4600 100>; 176 reg = <4600 100>;
165 clock-frequency = <0>; 177 clock-frequency = <0>;
166 interrupts = <1a 2>; 178 interrupts = <2a 2>;
167 interrupt-parent = <&mpic>; 179 interrupt-parent = <&mpic>;
168 }; 180 };
169 181
@@ -172,7 +184,7 @@
172 model = "SEC2"; 184 model = "SEC2";
173 compatible = "talitos"; 185 compatible = "talitos";
174 reg = <30000 f000>; 186 reg = <30000 f000>;
175 interrupts = <1d 2>; 187 interrupts = <2d 2>;
176 interrupt-parent = <&mpic>; 188 interrupt-parent = <&mpic>;
177 num-channels = <4>; 189 num-channels = <4>;
178 channel-fifo-len = <18>; 190 channel-fifo-len = <18>;
@@ -300,7 +312,13 @@
300 reg = <2000 200>; 312 reg = <2000 200>;
301 interrupts = <20>; 313 interrupts = <20>;
302 interrupt-parent = <&qeic>; 314 interrupt-parent = <&qeic>;
303 mac-address = [ 00 04 9f 00 23 23 ]; 315 /*
316 * mac-address is deprecated and will be removed
317 * in 2.6.25. Only recent versions of
318 * U-Boot support local-mac-address, however.
319 */
320 mac-address = [ 00 00 00 00 00 00 ];
321 local-mac-address = [ 00 00 00 00 00 00 ];
304 rx-clock = <0>; 322 rx-clock = <0>;
305 tx-clock = <19>; 323 tx-clock = <19>;
306 phy-handle = <&qe_phy0>; 324 phy-handle = <&qe_phy0>;
@@ -316,7 +334,13 @@
316 reg = <3000 200>; 334 reg = <3000 200>;
317 interrupts = <21>; 335 interrupts = <21>;
318 interrupt-parent = <&qeic>; 336 interrupt-parent = <&qeic>;
319 mac-address = [ 00 11 22 33 44 55 ]; 337 /*
338 * mac-address is deprecated and will be removed
339 * in 2.6.25. Only recent versions of
340 * U-Boot support local-mac-address, however.
341 */
342 mac-address = [ 00 00 00 00 00 00 ];
343 local-mac-address = [ 00 00 00 00 00 00 ];
320 rx-clock = <0>; 344 rx-clock = <0>;
321 tx-clock = <14>; 345 tx-clock = <14>;
322 phy-handle = <&qe_phy1>; 346 phy-handle = <&qe_phy1>;
@@ -335,25 +359,25 @@
335 * gianfar's MDIO bus */ 359 * gianfar's MDIO bus */
336 qe_phy0: ethernet-phy@00 { 360 qe_phy0: ethernet-phy@00 {
337 interrupt-parent = <&mpic>; 361 interrupt-parent = <&mpic>;
338 interrupts = <31 1>; 362 interrupts = <1 1>;
339 reg = <0>; 363 reg = <0>;
340 device_type = "ethernet-phy"; 364 device_type = "ethernet-phy";
341 }; 365 };
342 qe_phy1: ethernet-phy@01 { 366 qe_phy1: ethernet-phy@01 {
343 interrupt-parent = <&mpic>; 367 interrupt-parent = <&mpic>;
344 interrupts = <32 1>; 368 interrupts = <2 1>;
345 reg = <1>; 369 reg = <1>;
346 device_type = "ethernet-phy"; 370 device_type = "ethernet-phy";
347 }; 371 };
348 qe_phy2: ethernet-phy@02 { 372 qe_phy2: ethernet-phy@02 {
349 interrupt-parent = <&mpic>; 373 interrupt-parent = <&mpic>;
350 interrupts = <31 1>; 374 interrupts = <1 1>;
351 reg = <2>; 375 reg = <2>;
352 device_type = "ethernet-phy"; 376 device_type = "ethernet-phy";
353 }; 377 };
354 qe_phy3: ethernet-phy@03 { 378 qe_phy3: ethernet-phy@03 {
355 interrupt-parent = <&mpic>; 379 interrupt-parent = <&mpic>;
356 interrupts = <32 1>; 380 interrupts = <2 1>;
357 reg = <3>; 381 reg = <3>;
358 device_type = "ethernet-phy"; 382 device_type = "ethernet-phy";
359 }; 383 };
@@ -367,7 +391,7 @@
367 reg = <80 80>; 391 reg = <80 80>;
368 built-in; 392 built-in;
369 big-endian; 393 big-endian;
370 interrupts = <1e 2 1e 2>; //high:30 low:30 394 interrupts = <2e 2 2e 2>; //high:30 low:30
371 interrupt-parent = <&mpic>; 395 interrupt-parent = <&mpic>;
372 }; 396 };
373 397
diff --git a/arch/powerpc/boot/dts/mpc8641_hpcn.dts b/arch/powerpc/boot/dts/mpc8641_hpcn.dts
index 260b264c869e..db56a02b748f 100644
--- a/arch/powerpc/boot/dts/mpc8641_hpcn.dts
+++ b/arch/powerpc/boot/dts/mpc8641_hpcn.dts
@@ -56,8 +56,12 @@
56 #size-cells = <1>; 56 #size-cells = <1>;
57 #interrupt-cells = <2>; 57 #interrupt-cells = <2>;
58 device_type = "soc"; 58 device_type = "soc";
59 ranges = <0 f8000000 00100000>; 59 ranges = <00001000 f8001000 000ff000
60 reg = <f8000000 00100000>; // CCSRBAR 1M 60 80000000 80000000 20000000
61 e2000000 e2000000 00100000
62 a0000000 a0000000 20000000
63 e3000000 e3000000 00100000>;
64 reg = <f8000000 00001000>; // CCSRBAR
61 bus-frequency = <0>; 65 bus-frequency = <0>;
62 66
63 i2c@3000 { 67 i2c@3000 {
@@ -86,25 +90,25 @@
86 reg = <24520 20>; 90 reg = <24520 20>;
87 phy0: ethernet-phy@0 { 91 phy0: ethernet-phy@0 {
88 interrupt-parent = <&mpic>; 92 interrupt-parent = <&mpic>;
89 interrupts = <4a 1>; 93 interrupts = <a 1>;
90 reg = <0>; 94 reg = <0>;
91 device_type = "ethernet-phy"; 95 device_type = "ethernet-phy";
92 }; 96 };
93 phy1: ethernet-phy@1 { 97 phy1: ethernet-phy@1 {
94 interrupt-parent = <&mpic>; 98 interrupt-parent = <&mpic>;
95 interrupts = <4a 1>; 99 interrupts = <a 1>;
96 reg = <1>; 100 reg = <1>;
97 device_type = "ethernet-phy"; 101 device_type = "ethernet-phy";
98 }; 102 };
99 phy2: ethernet-phy@2 { 103 phy2: ethernet-phy@2 {
100 interrupt-parent = <&mpic>; 104 interrupt-parent = <&mpic>;
101 interrupts = <4a 1>; 105 interrupts = <a 1>;
102 reg = <2>; 106 reg = <2>;
103 device_type = "ethernet-phy"; 107 device_type = "ethernet-phy";
104 }; 108 };
105 phy3: ethernet-phy@3 { 109 phy3: ethernet-phy@3 {
106 interrupt-parent = <&mpic>; 110 interrupt-parent = <&mpic>;
107 interrupts = <4a 1>; 111 interrupts = <a 1>;
108 reg = <3>; 112 reg = <3>;
109 device_type = "ethernet-phy"; 113 device_type = "ethernet-phy";
110 }; 114 };
@@ -117,7 +121,13 @@
117 model = "TSEC"; 121 model = "TSEC";
118 compatible = "gianfar"; 122 compatible = "gianfar";
119 reg = <24000 1000>; 123 reg = <24000 1000>;
120 mac-address = [ 00 E0 0C 00 73 00 ]; 124 /*
125 * mac-address is deprecated and will be removed
126 * in 2.6.25. Only recent versions of
127 * U-Boot support local-mac-address, however.
128 */
129 mac-address = [ 00 00 00 00 00 00 ];
130 local-mac-address = [ 00 00 00 00 00 00 ];
121 interrupts = <1d 2 1e 2 22 2>; 131 interrupts = <1d 2 1e 2 22 2>;
122 interrupt-parent = <&mpic>; 132 interrupt-parent = <&mpic>;
123 phy-handle = <&phy0>; 133 phy-handle = <&phy0>;
@@ -130,7 +140,13 @@
130 model = "TSEC"; 140 model = "TSEC";
131 compatible = "gianfar"; 141 compatible = "gianfar";
132 reg = <25000 1000>; 142 reg = <25000 1000>;
133 mac-address = [ 00 E0 0C 00 73 01 ]; 143 /*
144 * mac-address is deprecated and will be removed
145 * in 2.6.25. Only recent versions of
146 * U-Boot support local-mac-address, however.
147 */
148 mac-address = [ 00 00 00 00 00 00 ];
149 local-mac-address = [ 00 00 00 00 00 00 ];
134 interrupts = <23 2 24 2 28 2>; 150 interrupts = <23 2 24 2 28 2>;
135 interrupt-parent = <&mpic>; 151 interrupt-parent = <&mpic>;
136 phy-handle = <&phy1>; 152 phy-handle = <&phy1>;
@@ -143,7 +159,13 @@
143 model = "TSEC"; 159 model = "TSEC";
144 compatible = "gianfar"; 160 compatible = "gianfar";
145 reg = <26000 1000>; 161 reg = <26000 1000>;
146 mac-address = [ 00 E0 0C 00 02 FD ]; 162 /*
163 * mac-address is deprecated and will be removed
164 * in 2.6.25. Only recent versions of
165 * U-Boot support local-mac-address, however.
166 */
167 mac-address = [ 00 00 00 00 00 00 ];
168 local-mac-address = [ 00 00 00 00 00 00 ];
147 interrupts = <1F 2 20 2 21 2>; 169 interrupts = <1F 2 20 2 21 2>;
148 interrupt-parent = <&mpic>; 170 interrupt-parent = <&mpic>;
149 phy-handle = <&phy2>; 171 phy-handle = <&phy2>;
@@ -156,7 +178,13 @@
156 model = "TSEC"; 178 model = "TSEC";
157 compatible = "gianfar"; 179 compatible = "gianfar";
158 reg = <27000 1000>; 180 reg = <27000 1000>;
159 mac-address = [ 00 E0 0C 00 03 FD ]; 181 /*
182 * mac-address is deprecated and will be removed
183 * in 2.6.25. Only recent versions of
184 * U-Boot support local-mac-address, however.
185 */
186 mac-address = [ 00 00 00 00 00 00 ];
187 local-mac-address = [ 00 00 00 00 00 00 ];
160 interrupts = <25 2 26 2 27 2>; 188 interrupts = <25 2 26 2 27 2>;
161 interrupt-parent = <&mpic>; 189 interrupt-parent = <&mpic>;
162 phy-handle = <&phy3>; 190 phy-handle = <&phy3>;
@@ -186,7 +214,7 @@
186 #size-cells = <2>; 214 #size-cells = <2>;
187 #address-cells = <3>; 215 #address-cells = <3>;
188 reg = <8000 1000>; 216 reg = <8000 1000>;
189 bus-range = <0 fe>; 217 bus-range = <0 ff>;
190 ranges = <02000000 0 80000000 80000000 0 20000000 218 ranges = <02000000 0 80000000 80000000 0 20000000
191 01000000 0 00000000 e2000000 0 00100000>; 219 01000000 0 00000000 e2000000 0 00100000>;
192 clock-frequency = <1fca055>; 220 clock-frequency = <1fca055>;
@@ -285,17 +313,84 @@
285 f800 0 0 3 &i8259 0 0 313 f800 0 0 3 &i8259 0 0
286 f800 0 0 4 &i8259 0 0 314 f800 0 0 4 &i8259 0 0
287 >; 315 >;
288 i8259: i8259@4d0 { 316 uli1575@0 {
289 clock-frequency = <0>; 317 reg = <0 0 0 0 0>;
290 interrupt-controller; 318 #size-cells = <2>;
291 device_type = "interrupt-controller"; 319 #address-cells = <3>;
292 #address-cells = <0>; 320 ranges = <02000000 0 80000000
293 #interrupt-cells = <2>; 321 02000000 0 80000000
294 built-in; 322 0 20000000
295 compatible = "chrp,iic"; 323 01000000 0 00000000
296 big-endian; 324 01000000 0 00000000
297 interrupts = <49 2>; 325 0 00100000>;
298 interrupt-parent = <&mpic>; 326
327 pci_bridge@0 {
328 reg = <0 0 0 0 0>;
329 #size-cells = <2>;
330 #address-cells = <3>;
331 ranges = <02000000 0 80000000
332 02000000 0 80000000
333 0 20000000
334 01000000 0 00000000
335 01000000 0 00000000
336 0 00100000>;
337
338 isa@1e {
339 device_type = "isa";
340 #interrupt-cells = <2>;
341 #size-cells = <1>;
342 #address-cells = <2>;
343 reg = <f000 0 0 0 0>;
344 ranges = <1 0 01000000 0 0
345 00001000>;
346 interrupt-parent = <&i8259>;
347
348 i8259: interrupt-controller@20 {
349 reg = <1 20 2
350 1 a0 2
351 1 4d0 2>;
352 clock-frequency = <0>;
353 interrupt-controller;
354 device_type = "interrupt-controller";
355 #address-cells = <0>;
356 #interrupt-cells = <2>;
357 built-in;
358 compatible = "chrp,iic";
359 interrupts = <9 2>;
360 interrupt-parent =
361 <&mpic>;
362 };
363
364 i8042@60 {
365 #size-cells = <0>;
366 #address-cells = <1>;
367 reg = <1 60 1 1 64 1>;
368 interrupts = <1 3 c 3>;
369 interrupt-parent =
370 <&i8259>;
371
372 keyboard@0 {
373 reg = <0>;
374 compatible = "pnpPNP,303";
375 };
376
377 mouse@1 {
378 reg = <1>;
379 compatible = "pnpPNP,f03";
380 };
381 };
382
383 rtc@70 {
384 compatible =
385 "pnpPNP,b00";
386 reg = <1 70 2>;
387 };
388
389 gpio@400 {
390 reg = <1 400 80>;
391 };
392 };
393 };
299 }; 394 };
300 395
301 }; 396 };
@@ -316,10 +411,10 @@
316 interrupt-map-mask = <f800 0 0 7>; 411 interrupt-map-mask = <f800 0 0 7>;
317 interrupt-map = < 412 interrupt-map = <
318 /* IDSEL 0x0 */ 413 /* IDSEL 0x0 */
319 0000 0 0 1 &mpic 44 1 414 0000 0 0 1 &mpic 4 1
320 0000 0 0 2 &mpic 45 1 415 0000 0 0 2 &mpic 5 1
321 0000 0 0 3 &mpic 46 1 416 0000 0 0 3 &mpic 6 1
322 0000 0 0 4 &mpic 47 1 417 0000 0 0 4 &mpic 7 1
323 >; 418 >;
324 }; 419 };
325 420
diff --git a/arch/powerpc/boot/dts/mpc866ads.dts b/arch/powerpc/boot/dts/mpc866ads.dts
index c0d06fd12927..e5e7726ddb03 100644
--- a/arch/powerpc/boot/dts/mpc866ads.dts
+++ b/arch/powerpc/boot/dts/mpc866ads.dts
@@ -15,12 +15,10 @@
15 compatible = "mpc8xx"; 15 compatible = "mpc8xx";
16 #address-cells = <1>; 16 #address-cells = <1>;
17 #size-cells = <1>; 17 #size-cells = <1>;
18 linux,phandle = <100>;
19 18
20 cpus { 19 cpus {
21 #address-cells = <1>; 20 #address-cells = <1>;
22 #size-cells = <0>; 21 #size-cells = <0>;
23 linux,phandle = <200>;
24 22
25 PowerPC,866@0 { 23 PowerPC,866@0 {
26 device_type = "cpu"; 24 device_type = "cpu";
@@ -34,14 +32,12 @@
34 clock-frequency = <0>; 32 clock-frequency = <0>;
35 32-bit; 33 32-bit;
36 interrupts = <f 2>; // decrementer interrupt 34 interrupts = <f 2>; // decrementer interrupt
37 interrupt-parent = <ff000000>; 35 interrupt-parent = <&Mpc8xx_pic>;
38 linux,phandle = <201>;
39 }; 36 };
40 }; 37 };
41 38
42 memory { 39 memory {
43 device_type = "memory"; 40 device_type = "memory";
44 linux,phandle = <300>;
45 reg = <00000000 800000>; 41 reg = <00000000 800000>;
46 }; 42 };
47 43
@@ -57,11 +53,9 @@
57 device_type = "mdio"; 53 device_type = "mdio";
58 compatible = "fs_enet"; 54 compatible = "fs_enet";
59 reg = <e80 8>; 55 reg = <e80 8>;
60 linux,phandle = <e80>;
61 #address-cells = <1>; 56 #address-cells = <1>;
62 #size-cells = <0>; 57 #size-cells = <0>;
63 ethernet-phy@f { 58 phy: ethernet-phy@f {
64 linux,phandle = <e800f>;
65 reg = <f>; 59 reg = <f>;
66 device_type = "ethernet-phy"; 60 device_type = "ethernet-phy";
67 }; 61 };
@@ -75,12 +69,11 @@
75 reg = <e00 188>; 69 reg = <e00 188>;
76 mac-address = [ 00 00 0C 00 01 FD ]; 70 mac-address = [ 00 00 0C 00 01 FD ];
77 interrupts = <3 1>; 71 interrupts = <3 1>;
78 interrupt-parent = <ff000000>; 72 interrupt-parent = <&Mpc8xx_pic>;
79 phy-handle = <e800f>; 73 phy-handle = <&Phy>;
80 }; 74 };
81 75
82 pic@ff000000 { 76 mpc8xx_pic: pic@ff000000 {
83 linux,phandle = <ff000000>;
84 interrupt-controller; 77 interrupt-controller;
85 #address-cells = <0>; 78 #address-cells = <0>;
86 #interrupt-cells = <2>; 79 #interrupt-cells = <2>;
@@ -91,7 +84,6 @@
91 }; 84 };
92 85
93 cpm@ff000000 { 86 cpm@ff000000 {
94 linux,phandle = <ff000000>;
95 #address-cells = <1>; 87 #address-cells = <1>;
96 #size-cells = <1>; 88 #size-cells = <1>;
97 #interrupt-cells = <2>; 89 #interrupt-cells = <2>;
@@ -102,15 +94,14 @@
102 command-proc = <9c0>; 94 command-proc = <9c0>;
103 brg-frequency = <0>; 95 brg-frequency = <0>;
104 interrupts = <0 2>; // cpm error interrupt 96 interrupts = <0 2>; // cpm error interrupt
105 interrupt-parent = <930>; 97 interrupt-parent = <&Cpm_pic>;
106 98
107 pic@930 { 99 cpm_pic: pic@930 {
108 linux,phandle = <930>;
109 interrupt-controller; 100 interrupt-controller;
110 #address-cells = <0>; 101 #address-cells = <0>;
111 #interrupt-cells = <2>; 102 #interrupt-cells = <2>;
112 interrupts = <5 2 0 2>; 103 interrupts = <5 2 0 2>;
113 interrupt-parent = <ff000000>; 104 interrupt-parent = <&Mpc8xx_pic>;
114 reg = <930 20>; 105 reg = <930 20>;
115 built-in; 106 built-in;
116 device_type = "cpm-pic"; 107 device_type = "cpm-pic";
@@ -128,7 +119,7 @@
128 tx-clock = <1>; 119 tx-clock = <1>;
129 current-speed = <0>; 120 current-speed = <0>;
130 interrupts = <4 3>; 121 interrupts = <4 3>;
131 interrupt-parent = <930>; 122 interrupt-parent = <&Cpm_pic>;
132 }; 123 };
133 124
134 smc@a90 { 125 smc@a90 {
@@ -142,7 +133,7 @@
142 tx-clock = <2>; 133 tx-clock = <2>;
143 current-speed = <0>; 134 current-speed = <0>;
144 interrupts = <3 3>; 135 interrupts = <3 3>;
145 interrupt-parent = <930>; 136 interrupt-parent = <&Cpm_pic>;
146 }; 137 };
147 138
148 scc@a00 { 139 scc@a00 {
@@ -153,7 +144,7 @@
153 reg = <a00 18 3c00 80>; 144 reg = <a00 18 3c00 80>;
154 mac-address = [ 00 00 0C 00 03 FD ]; 145 mac-address = [ 00 00 0C 00 03 FD ];
155 interrupts = <1e 3>; 146 interrupts = <1e 3>;
156 interrupt-parent = <930>; 147 interrupt-parent = <&Cpm_pic>;
157 }; 148 };
158 }; 149 };
159 }; 150 };
diff --git a/arch/powerpc/boot/dts/mpc885ads.dts b/arch/powerpc/boot/dts/mpc885ads.dts
index 110bf6170603..dc7ab9c80611 100644
--- a/arch/powerpc/boot/dts/mpc885ads.dts
+++ b/arch/powerpc/boot/dts/mpc885ads.dts
@@ -15,12 +15,10 @@
15 compatible = "mpc8xx"; 15 compatible = "mpc8xx";
16 #address-cells = <1>; 16 #address-cells = <1>;
17 #size-cells = <1>; 17 #size-cells = <1>;
18 linux,phandle = <100>;
19 18
20 cpus { 19 cpus {
21 #address-cells = <1>; 20 #address-cells = <1>;
22 #size-cells = <0>; 21 #size-cells = <0>;
23 linux,phandle = <200>;
24 22
25 PowerPC,885@0 { 23 PowerPC,885@0 {
26 device_type = "cpu"; 24 device_type = "cpu";
@@ -34,14 +32,12 @@
34 clock-frequency = <0>; 32 clock-frequency = <0>;
35 32-bit; 33 32-bit;
36 interrupts = <f 2>; // decrementer interrupt 34 interrupts = <f 2>; // decrementer interrupt
37 interrupt-parent = <ff000000>; 35 interrupt-parent = <&Mpc8xx_pic>;
38 linux,phandle = <201>;
39 }; 36 };
40 }; 37 };
41 38
42 memory { 39 memory {
43 device_type = "memory"; 40 device_type = "memory";
44 linux,phandle = <300>;
45 reg = <00000000 800000>; 41 reg = <00000000 800000>;
46 }; 42 };
47 43
@@ -57,21 +53,17 @@
57 device_type = "mdio"; 53 device_type = "mdio";
58 compatible = "fs_enet"; 54 compatible = "fs_enet";
59 reg = <e80 8>; 55 reg = <e80 8>;
60 linux,phandle = <e80>;
61 #address-cells = <1>; 56 #address-cells = <1>;
62 #size-cells = <0>; 57 #size-cells = <0>;
63 ethernet-phy@0 { 58 Phy0: ethernet-phy@0 {
64 linux,phandle = <e8000>;
65 reg = <0>; 59 reg = <0>;
66 device_type = "ethernet-phy"; 60 device_type = "ethernet-phy";
67 }; 61 };
68 ethernet-phy@1 { 62 Phy1: ethernet-phy@1 {
69 linux,phandle = <e8001>;
70 reg = <1>; 63 reg = <1>;
71 device_type = "ethernet-phy"; 64 device_type = "ethernet-phy";
72 }; 65 };
73 ethernet-phy@2 { 66 Phy2: ethernet-phy@2 {
74 linux,phandle = <e8002>;
75 reg = <2>; 67 reg = <2>;
76 device_type = "ethernet-phy"; 68 device_type = "ethernet-phy";
77 }; 69 };
@@ -85,8 +77,8 @@
85 reg = <e00 188>; 77 reg = <e00 188>;
86 mac-address = [ 00 00 0C 00 01 FD ]; 78 mac-address = [ 00 00 0C 00 01 FD ];
87 interrupts = <3 1>; 79 interrupts = <3 1>;
88 interrupt-parent = <ff000000>; 80 interrupt-parent = <&Mpc8xx_pic>;
89 phy-handle = <e8000>; 81 phy-handle = <&Phy1>;
90 }; 82 };
91 83
92 fec@1e00 { 84 fec@1e00 {
@@ -97,12 +89,11 @@
97 reg = <1e00 188>; 89 reg = <1e00 188>;
98 mac-address = [ 00 00 0C 00 02 FD ]; 90 mac-address = [ 00 00 0C 00 02 FD ];
99 interrupts = <7 1>; 91 interrupts = <7 1>;
100 interrupt-parent = <ff000000>; 92 interrupt-parent = <&Mpc8xx_pic>;
101 phy-handle = <e8001>; 93 phy-handle = <&Phy2>;
102 }; 94 };
103 95
104 pic@ff000000 { 96 Mpc8xx_pic: pic@ff000000 {
105 linux,phandle = <ff000000>;
106 interrupt-controller; 97 interrupt-controller;
107 #address-cells = <0>; 98 #address-cells = <0>;
108 #interrupt-cells = <2>; 99 #interrupt-cells = <2>;
@@ -112,8 +103,18 @@
112 compatible = "CPM"; 103 compatible = "CPM";
113 }; 104 };
114 105
106 pcmcia@0080 {
107 #address-cells = <3>;
108 #interrupt-cells = <1>;
109 #size-cells = <2>;
110 compatible = "fsl,pq-pcmcia";
111 device_type = "pcmcia";
112 reg = <80 80>;
113 interrupt-parent = <&Mpc8xx_pic>;
114 interrupts = <d 1>;
115 };
116
115 cpm@ff000000 { 117 cpm@ff000000 {
116 linux,phandle = <ff000000>;
117 #address-cells = <1>; 118 #address-cells = <1>;
118 #size-cells = <1>; 119 #size-cells = <1>;
119 #interrupt-cells = <2>; 120 #interrupt-cells = <2>;
@@ -124,15 +125,14 @@
124 command-proc = <9c0>; 125 command-proc = <9c0>;
125 brg-frequency = <0>; 126 brg-frequency = <0>;
126 interrupts = <0 2>; // cpm error interrupt 127 interrupts = <0 2>; // cpm error interrupt
127 interrupt-parent = <930>; 128 interrupt-parent = <&Cpm_pic>;
128 129
129 pic@930 { 130 Cpm_pic: pic@930 {
130 linux,phandle = <930>;
131 interrupt-controller; 131 interrupt-controller;
132 #address-cells = <0>; 132 #address-cells = <0>;
133 #interrupt-cells = <2>; 133 #interrupt-cells = <2>;
134 interrupts = <5 2 0 2>; 134 interrupts = <5 2 0 2>;
135 interrupt-parent = <ff000000>; 135 interrupt-parent = <&Mpc8xx_pic>;
136 reg = <930 20>; 136 reg = <930 20>;
137 built-in; 137 built-in;
138 device_type = "cpm-pic"; 138 device_type = "cpm-pic";
@@ -150,7 +150,7 @@
150 tx-clock = <1>; 150 tx-clock = <1>;
151 current-speed = <0>; 151 current-speed = <0>;
152 interrupts = <4 3>; 152 interrupts = <4 3>;
153 interrupt-parent = <930>; 153 interrupt-parent = <&Cpm_pic>;
154 }; 154 };
155 155
156 smc@a90 { 156 smc@a90 {
@@ -164,7 +164,7 @@
164 tx-clock = <2>; 164 tx-clock = <2>;
165 current-speed = <0>; 165 current-speed = <0>;
166 interrupts = <3 3>; 166 interrupts = <3 3>;
167 interrupt-parent = <930>; 167 interrupt-parent = <&Cpm_pic>;
168 }; 168 };
169 169
170 scc@a40 { 170 scc@a40 {
@@ -175,8 +175,8 @@
175 reg = <a40 18 3e00 80>; 175 reg = <a40 18 3e00 80>;
176 mac-address = [ 00 00 0C 00 03 FD ]; 176 mac-address = [ 00 00 0C 00 03 FD ];
177 interrupts = <1c 3>; 177 interrupts = <1c 3>;
178 interrupt-parent = <930>; 178 interrupt-parent = <&Cpm_pic>;
179 phy-handle = <e8002>; 179 phy-handle = <&Phy2>;
180 }; 180 };
181 }; 181 };
182 }; 182 };
diff --git a/arch/powerpc/boot/dts/prpmc2800.dts b/arch/powerpc/boot/dts/prpmc2800.dts
index 568965a022b9..699d0df574d5 100644
--- a/arch/powerpc/boot/dts/prpmc2800.dts
+++ b/arch/powerpc/boot/dts/prpmc2800.dts
@@ -309,7 +309,7 @@
309 }; 309 };
310 310
311 chosen { 311 chosen {
312 bootargs = "ip=on console=ttyMM0"; 312 bootargs = "ip=on";
313 linux,stdout-path = "/mv64x60@f1000000/mpsc@8000"; 313 linux,stdout-path = "/mv64x60@f1000000/mpsc@8000";
314 }; 314 };
315}; 315};
diff --git a/arch/powerpc/boot/dts/ps3.dts b/arch/powerpc/boot/dts/ps3.dts
new file mode 100644
index 000000000000..379ded282d5e
--- /dev/null
+++ b/arch/powerpc/boot/dts/ps3.dts
@@ -0,0 +1,68 @@
1/*
2 * PS3 Game Console device tree.
3 *
4 * Copyright (C) 2007 Sony Computer Entertainment Inc.
5 * Copyright 2007 Sony Corp.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21/ {
22 model = "SonyPS3";
23 compatible = "sony,ps3";
24 #size-cells = <2>;
25 #address-cells = <2>;
26
27 chosen {
28 };
29
30 /*
31 * We'll get the size of the bootmem block from lv1 after startup,
32 * so we'll put a null entry here.
33 */
34
35 memory {
36 device_type = "memory";
37 reg = <0 0 0 0>;
38 };
39
40 /*
41 * The boot cpu is always zero for PS3.
42 *
43 * dtc expects a clock-frequency and timebase-frequency entries, so
44 * we'll put a null entries here. These will be initialized after
45 * startup with data from lv1.
46 *
47 * Seems the only way currently to indicate a processor has multiple
48 * threads is with an ibm,ppc-interrupt-server#s entry. We'll put one
49 * here so we can bring up both of ours. See smp_setup_cpu_maps().
50 */
51
52 cpus {
53 #size-cells = <0>;
54 #address-cells = <1>;
55
56 cpu@0 {
57 device_type = "cpu";
58 reg = <0>;
59 ibm,ppc-interrupt-server#s = <0 1>;
60 clock-frequency = <0>;
61 timebase-frequency = <0>;
62 i-cache-size = <8000>;
63 d-cache-size = <8000>;
64 i-cache-line-size = <80>;
65 d-cache-line-size = <80>;
66 };
67 };
68};
diff --git a/arch/powerpc/boot/ebony.c b/arch/powerpc/boot/ebony.c
index b1251ee7a102..75daedafd0a4 100644
--- a/arch/powerpc/boot/ebony.c
+++ b/arch/powerpc/boot/ebony.c
@@ -100,28 +100,13 @@ static void ebony_fixups(void)
100 ibm440gp_fixup_clocks(sysclk, 6 * 1843200); 100 ibm440gp_fixup_clocks(sysclk, 6 * 1843200);
101 ibm44x_fixup_memsize(); 101 ibm44x_fixup_memsize();
102 dt_fixup_mac_addresses(ebony_mac0, ebony_mac1); 102 dt_fixup_mac_addresses(ebony_mac0, ebony_mac1);
103} 103 ibm4xx_fixup_ebc_ranges("/plb/opb/ebc");
104
105#define SPRN_DBCR0 0x134
106#define DBCR0_RST_SYSTEM 0x30000000
107
108static void ebony_exit(void)
109{
110 unsigned long tmp;
111
112 asm volatile (
113 "mfspr %0,%1\n"
114 "oris %0,%0,%2@h\n"
115 "mtspr %1,%0"
116 : "=&r"(tmp) : "i"(SPRN_DBCR0), "i"(DBCR0_RST_SYSTEM)
117 );
118
119} 104}
120 105
121void ebony_init(void *mac0, void *mac1) 106void ebony_init(void *mac0, void *mac1)
122{ 107{
123 platform_ops.fixups = ebony_fixups; 108 platform_ops.fixups = ebony_fixups;
124 platform_ops.exit = ebony_exit; 109 platform_ops.exit = ibm44x_dbcr_reset;
125 ebony_mac0 = mac0; 110 ebony_mac0 = mac0;
126 ebony_mac1 = mac1; 111 ebony_mac1 = mac1;
127 ft_init(_dtb_start, _dtb_end - _dtb_start, 32); 112 ft_init(_dtb_start, _dtb_end - _dtb_start, 32);
diff --git a/arch/powerpc/boot/main.c b/arch/powerpc/boot/main.c
index 56b56a8d4b23..416dc3857bfe 100644
--- a/arch/powerpc/boot/main.c
+++ b/arch/powerpc/boot/main.c
@@ -36,8 +36,6 @@ struct addr_range {
36 unsigned long size; 36 unsigned long size;
37}; 37};
38 38
39typedef void (*kernel_entry_t)(unsigned long, unsigned long, void *);
40
41#undef DEBUG 39#undef DEBUG
42 40
43static struct addr_range prep_kernel(void) 41static struct addr_range prep_kernel(void)
diff --git a/arch/powerpc/boot/of.c b/arch/powerpc/boot/of.c
index d16ee3e3f868..385e08b83b7e 100644
--- a/arch/powerpc/boot/of.c
+++ b/arch/powerpc/boot/of.c
@@ -15,8 +15,7 @@
15#include "page.h" 15#include "page.h"
16#include "ops.h" 16#include "ops.h"
17 17
18typedef void *ihandle; 18#include "of.h"
19typedef void *phandle;
20 19
21extern char _end[]; 20extern char _end[];
22 21
@@ -25,154 +24,10 @@ extern char _end[];
25#define RAM_END (512<<20) /* Fixme: use OF */ 24#define RAM_END (512<<20) /* Fixme: use OF */
26#define ONE_MB 0x100000 25#define ONE_MB 0x100000
27 26
28int (*prom) (void *);
29 27
30 28
31static unsigned long claim_base; 29static unsigned long claim_base;
32 30
33static int call_prom(const char *service, int nargs, int nret, ...)
34{
35 int i;
36 struct prom_args {
37 const char *service;
38 int nargs;
39 int nret;
40 unsigned int args[12];
41 } args;
42 va_list list;
43
44 args.service = service;
45 args.nargs = nargs;
46 args.nret = nret;
47
48 va_start(list, nret);
49 for (i = 0; i < nargs; i++)
50 args.args[i] = va_arg(list, unsigned int);
51 va_end(list);
52
53 for (i = 0; i < nret; i++)
54 args.args[nargs+i] = 0;
55
56 if (prom(&args) < 0)
57 return -1;
58
59 return (nret > 0)? args.args[nargs]: 0;
60}
61
62static int call_prom_ret(const char *service, int nargs, int nret,
63 unsigned int *rets, ...)
64{
65 int i;
66 struct prom_args {
67 const char *service;
68 int nargs;
69 int nret;
70 unsigned int args[12];
71 } args;
72 va_list list;
73
74 args.service = service;
75 args.nargs = nargs;
76 args.nret = nret;
77
78 va_start(list, rets);
79 for (i = 0; i < nargs; i++)
80 args.args[i] = va_arg(list, unsigned int);
81 va_end(list);
82
83 for (i = 0; i < nret; i++)
84 args.args[nargs+i] = 0;
85
86 if (prom(&args) < 0)
87 return -1;
88
89 if (rets != (void *) 0)
90 for (i = 1; i < nret; ++i)
91 rets[i-1] = args.args[nargs+i];
92
93 return (nret > 0)? args.args[nargs]: 0;
94}
95
96/*
97 * Older OF's require that when claiming a specific range of addresses,
98 * we claim the physical space in the /memory node and the virtual
99 * space in the chosen mmu node, and then do a map operation to
100 * map virtual to physical.
101 */
102static int need_map = -1;
103static ihandle chosen_mmu;
104static phandle memory;
105
106/* returns true if s2 is a prefix of s1 */
107static int string_match(const char *s1, const char *s2)
108{
109 for (; *s2; ++s2)
110 if (*s1++ != *s2)
111 return 0;
112 return 1;
113}
114
115static int check_of_version(void)
116{
117 phandle oprom, chosen;
118 char version[64];
119
120 oprom = finddevice("/openprom");
121 if (oprom == (phandle) -1)
122 return 0;
123 if (getprop(oprom, "model", version, sizeof(version)) <= 0)
124 return 0;
125 version[sizeof(version)-1] = 0;
126 printf("OF version = '%s'\r\n", version);
127 if (!string_match(version, "Open Firmware, 1.")
128 && !string_match(version, "FirmWorks,3."))
129 return 0;
130 chosen = finddevice("/chosen");
131 if (chosen == (phandle) -1) {
132 chosen = finddevice("/chosen@0");
133 if (chosen == (phandle) -1) {
134 printf("no chosen\n");
135 return 0;
136 }
137 }
138 if (getprop(chosen, "mmu", &chosen_mmu, sizeof(chosen_mmu)) <= 0) {
139 printf("no mmu\n");
140 return 0;
141 }
142 memory = (ihandle) call_prom("open", 1, 1, "/memory");
143 if (memory == (ihandle) -1) {
144 memory = (ihandle) call_prom("open", 1, 1, "/memory@0");
145 if (memory == (ihandle) -1) {
146 printf("no memory node\n");
147 return 0;
148 }
149 }
150 printf("old OF detected\r\n");
151 return 1;
152}
153
154static void *claim(unsigned long virt, unsigned long size, unsigned long align)
155{
156 int ret;
157 unsigned int result;
158
159 if (need_map < 0)
160 need_map = check_of_version();
161 if (align || !need_map)
162 return (void *) call_prom("claim", 3, 1, virt, size, align);
163
164 ret = call_prom_ret("call-method", 5, 2, &result, "claim", memory,
165 align, size, virt);
166 if (ret != 0 || result == -1)
167 return (void *) -1;
168 ret = call_prom_ret("call-method", 5, 2, &result, "claim", chosen_mmu,
169 align, size, virt);
170 /* 0x12 == coherent + read/write */
171 ret = call_prom("call-method", 6, 1, "map", chosen_mmu,
172 0x12, size, virt, virt);
173 return (void *) virt;
174}
175
176static void *of_try_claim(unsigned long size) 31static void *of_try_claim(unsigned long size)
177{ 32{
178 unsigned long addr = 0; 33 unsigned long addr = 0;
@@ -184,7 +39,7 @@ static void *of_try_claim(unsigned long size)
184#ifdef DEBUG 39#ifdef DEBUG
185 printf(" trying: 0x%08lx\n\r", claim_base); 40 printf(" trying: 0x%08lx\n\r", claim_base);
186#endif 41#endif
187 addr = (unsigned long)claim(claim_base, size, 0); 42 addr = (unsigned long)of_claim(claim_base, size, 0);
188 if ((void *)addr != (void *)-1) 43 if ((void *)addr != (void *)-1)
189 break; 44 break;
190 } 45 }
@@ -208,64 +63,6 @@ static void of_image_hdr(const void *hdr)
208 } 63 }
209} 64}
210 65
211static void *of_vmlinux_alloc(unsigned long size)
212{
213 void *p = malloc(size);
214
215 if (!p)
216 fatal("Can't allocate memory for kernel image!\n\r");
217
218 return p;
219}
220
221static void of_exit(void)
222{
223 call_prom("exit", 0, 0);
224}
225
226/*
227 * OF device tree routines
228 */
229static void *of_finddevice(const char *name)
230{
231 return (phandle) call_prom("finddevice", 1, 1, name);
232}
233
234static int of_getprop(const void *phandle, const char *name, void *buf,
235 const int buflen)
236{
237 return call_prom("getprop", 4, 1, phandle, name, buf, buflen);
238}
239
240static int of_setprop(const void *phandle, const char *name, const void *buf,
241 const int buflen)
242{
243 return call_prom("setprop", 4, 1, phandle, name, buf, buflen);
244}
245
246/*
247 * OF console routines
248 */
249static void *of_stdout_handle;
250
251static int of_console_open(void)
252{
253 void *devp;
254
255 if (((devp = finddevice("/chosen")) != NULL)
256 && (getprop(devp, "stdout", &of_stdout_handle,
257 sizeof(of_stdout_handle))
258 == sizeof(of_stdout_handle)))
259 return 0;
260
261 return -1;
262}
263
264static void of_console_write(char *buf, int len)
265{
266 call_prom("write", 3, 1, of_stdout_handle, buf, len);
267}
268
269void platform_init(unsigned long a1, unsigned long a2, void *promptr) 66void platform_init(unsigned long a1, unsigned long a2, void *promptr)
270{ 67{
271 platform_ops.image_hdr = of_image_hdr; 68 platform_ops.image_hdr = of_image_hdr;
@@ -277,10 +74,9 @@ void platform_init(unsigned long a1, unsigned long a2, void *promptr)
277 dt_ops.getprop = of_getprop; 74 dt_ops.getprop = of_getprop;
278 dt_ops.setprop = of_setprop; 75 dt_ops.setprop = of_setprop;
279 76
280 console_ops.open = of_console_open; 77 of_console_init();
281 console_ops.write = of_console_write;
282 78
283 prom = (int (*)(void *))promptr; 79 of_init(promptr);
284 loader_info.promptr = promptr; 80 loader_info.promptr = promptr;
285 if (a1 && a2 && a2 != 0xdeadbeef) { 81 if (a1 && a2 && a2 != 0xdeadbeef) {
286 loader_info.initrd_addr = a1; 82 loader_info.initrd_addr = a1;
diff --git a/arch/powerpc/boot/of.h b/arch/powerpc/boot/of.h
new file mode 100644
index 000000000000..e4c68f7391c5
--- /dev/null
+++ b/arch/powerpc/boot/of.h
@@ -0,0 +1,21 @@
1#ifndef _PPC_BOOT_OF_H_
2#define _PPC_BOOT_OF_H_
3
4typedef void *phandle;
5typedef void *ihandle;
6
7void of_init(void *promptr);
8int of_call_prom(const char *service, int nargs, int nret, ...);
9void *of_claim(unsigned long virt, unsigned long size, unsigned long align);
10void *of_vmlinux_alloc(unsigned long size);
11void of_exit(void);
12void *of_finddevice(const char *name);
13int of_getprop(const void *phandle, const char *name, void *buf,
14 const int buflen);
15int of_setprop(const void *phandle, const char *name, const void *buf,
16 const int buflen);
17
18/* Console functions */
19void of_console_init(void);
20
21#endif /* _PPC_BOOT_OF_H_ */
diff --git a/arch/powerpc/boot/ofconsole.c b/arch/powerpc/boot/ofconsole.c
new file mode 100644
index 000000000000..ce0e02424453
--- /dev/null
+++ b/arch/powerpc/boot/ofconsole.c
@@ -0,0 +1,45 @@
1/*
2 * OF console routines
3 *
4 * Copyright (C) Paul Mackerras 1997.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11#include <stddef.h>
12#include "types.h"
13#include "elf.h"
14#include "string.h"
15#include "stdio.h"
16#include "page.h"
17#include "ops.h"
18
19#include "of.h"
20
21static void *of_stdout_handle;
22
23static int of_console_open(void)
24{
25 void *devp;
26
27 if (((devp = of_finddevice("/chosen")) != NULL)
28 && (of_getprop(devp, "stdout", &of_stdout_handle,
29 sizeof(of_stdout_handle))
30 == sizeof(of_stdout_handle)))
31 return 0;
32
33 return -1;
34}
35
36static void of_console_write(const char *buf, int len)
37{
38 of_call_prom("write", 3, 1, of_stdout_handle, buf, len);
39}
40
41void of_console_init(void)
42{
43 console_ops.open = of_console_open;
44 console_ops.write = of_console_write;
45}
diff --git a/arch/powerpc/boot/oflib.c b/arch/powerpc/boot/oflib.c
new file mode 100644
index 000000000000..95b8fd69a403
--- /dev/null
+++ b/arch/powerpc/boot/oflib.c
@@ -0,0 +1,202 @@
1/*
2 * Copyright (C) Paul Mackerras 1997.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 */
9#include <stddef.h>
10#include "types.h"
11#include "elf.h"
12#include "string.h"
13#include "stdio.h"
14#include "page.h"
15#include "ops.h"
16
17#include "of.h"
18
19static int (*prom) (void *);
20
21void of_init(void *promptr)
22{
23 prom = (int (*)(void *))promptr;
24}
25
26int of_call_prom(const char *service, int nargs, int nret, ...)
27{
28 int i;
29 struct prom_args {
30 const char *service;
31 int nargs;
32 int nret;
33 unsigned int args[12];
34 } args;
35 va_list list;
36
37 args.service = service;
38 args.nargs = nargs;
39 args.nret = nret;
40
41 va_start(list, nret);
42 for (i = 0; i < nargs; i++)
43 args.args[i] = va_arg(list, unsigned int);
44 va_end(list);
45
46 for (i = 0; i < nret; i++)
47 args.args[nargs+i] = 0;
48
49 if (prom(&args) < 0)
50 return -1;
51
52 return (nret > 0)? args.args[nargs]: 0;
53}
54
55static int of_call_prom_ret(const char *service, int nargs, int nret,
56 unsigned int *rets, ...)
57{
58 int i;
59 struct prom_args {
60 const char *service;
61 int nargs;
62 int nret;
63 unsigned int args[12];
64 } args;
65 va_list list;
66
67 args.service = service;
68 args.nargs = nargs;
69 args.nret = nret;
70
71 va_start(list, rets);
72 for (i = 0; i < nargs; i++)
73 args.args[i] = va_arg(list, unsigned int);
74 va_end(list);
75
76 for (i = 0; i < nret; i++)
77 args.args[nargs+i] = 0;
78
79 if (prom(&args) < 0)
80 return -1;
81
82 if (rets != (void *) 0)
83 for (i = 1; i < nret; ++i)
84 rets[i-1] = args.args[nargs+i];
85
86 return (nret > 0)? args.args[nargs]: 0;
87}
88
89/* returns true if s2 is a prefix of s1 */
90static int string_match(const char *s1, const char *s2)
91{
92 for (; *s2; ++s2)
93 if (*s1++ != *s2)
94 return 0;
95 return 1;
96}
97
98/*
99 * Older OF's require that when claiming a specific range of addresses,
100 * we claim the physical space in the /memory node and the virtual
101 * space in the chosen mmu node, and then do a map operation to
102 * map virtual to physical.
103 */
104static int need_map = -1;
105static ihandle chosen_mmu;
106static phandle memory;
107
108static int check_of_version(void)
109{
110 phandle oprom, chosen;
111 char version[64];
112
113 oprom = of_finddevice("/openprom");
114 if (oprom == (phandle) -1)
115 return 0;
116 if (of_getprop(oprom, "model", version, sizeof(version)) <= 0)
117 return 0;
118 version[sizeof(version)-1] = 0;
119 printf("OF version = '%s'\r\n", version);
120 if (!string_match(version, "Open Firmware, 1.")
121 && !string_match(version, "FirmWorks,3."))
122 return 0;
123 chosen = of_finddevice("/chosen");
124 if (chosen == (phandle) -1) {
125 chosen = of_finddevice("/chosen@0");
126 if (chosen == (phandle) -1) {
127 printf("no chosen\n");
128 return 0;
129 }
130 }
131 if (of_getprop(chosen, "mmu", &chosen_mmu, sizeof(chosen_mmu)) <= 0) {
132 printf("no mmu\n");
133 return 0;
134 }
135 memory = (ihandle) of_call_prom("open", 1, 1, "/memory");
136 if (memory == (ihandle) -1) {
137 memory = (ihandle) of_call_prom("open", 1, 1, "/memory@0");
138 if (memory == (ihandle) -1) {
139 printf("no memory node\n");
140 return 0;
141 }
142 }
143 printf("old OF detected\r\n");
144 return 1;
145}
146
147void *of_claim(unsigned long virt, unsigned long size, unsigned long align)
148{
149 int ret;
150 unsigned int result;
151
152 if (need_map < 0)
153 need_map = check_of_version();
154 if (align || !need_map)
155 return (void *) of_call_prom("claim", 3, 1, virt, size, align);
156
157 ret = of_call_prom_ret("call-method", 5, 2, &result, "claim", memory,
158 align, size, virt);
159 if (ret != 0 || result == -1)
160 return (void *) -1;
161 ret = of_call_prom_ret("call-method", 5, 2, &result, "claim", chosen_mmu,
162 align, size, virt);
163 /* 0x12 == coherent + read/write */
164 ret = of_call_prom("call-method", 6, 1, "map", chosen_mmu,
165 0x12, size, virt, virt);
166 return (void *) virt;
167}
168
169void *of_vmlinux_alloc(unsigned long size)
170{
171 void *p = malloc(size);
172
173 if (!p)
174 fatal("Can't allocate memory for kernel image!\n\r");
175
176 return p;
177}
178
179void of_exit(void)
180{
181 of_call_prom("exit", 0, 0);
182}
183
184/*
185 * OF device tree routines
186 */
187void *of_finddevice(const char *name)
188{
189 return (phandle) of_call_prom("finddevice", 1, 1, name);
190}
191
192int of_getprop(const void *phandle, const char *name, void *buf,
193 const int buflen)
194{
195 return of_call_prom("getprop", 4, 1, phandle, name, buf, buflen);
196}
197
198int of_setprop(const void *phandle, const char *name, const void *buf,
199 const int buflen)
200{
201 return of_call_prom("setprop", 4, 1, phandle, name, buf, buflen);
202}
diff --git a/arch/powerpc/boot/ops.h b/arch/powerpc/boot/ops.h
index 959124f3f9af..86077066cd7c 100644
--- a/arch/powerpc/boot/ops.h
+++ b/arch/powerpc/boot/ops.h
@@ -19,6 +19,8 @@
19#define MAX_PATH_LEN 256 19#define MAX_PATH_LEN 256
20#define MAX_PROP_LEN 256 /* What should this be? */ 20#define MAX_PROP_LEN 256 /* What should this be? */
21 21
22typedef void (*kernel_entry_t)(unsigned long r3, unsigned long r4, void *r5);
23
22/* Platform specific operations */ 24/* Platform specific operations */
23struct platform_ops { 25struct platform_ops {
24 void (*fixups)(void); 26 void (*fixups)(void);
@@ -51,7 +53,7 @@ extern struct dt_ops dt_ops;
51/* Console operations */ 53/* Console operations */
52struct console_ops { 54struct console_ops {
53 int (*open)(void); 55 int (*open)(void);
54 void (*write)(char *buf, int len); 56 void (*write)(const char *buf, int len);
55 void (*edit_cmdline)(char *buf, int len); 57 void (*edit_cmdline)(char *buf, int len);
56 void (*close)(void); 58 void (*close)(void);
57 void *data; 59 void *data;
diff --git a/arch/powerpc/boot/ps3-head.S b/arch/powerpc/boot/ps3-head.S
new file mode 100644
index 000000000000..1a6d64a68df5
--- /dev/null
+++ b/arch/powerpc/boot/ps3-head.S
@@ -0,0 +1,80 @@
1/*
2 * PS3 bootwrapper entry.
3 *
4 * Copyright (C) 2007 Sony Computer Entertainment Inc.
5 * Copyright 2007 Sony Corp.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include "ppc_asm.h"
22
23 .text
24
25/*
26 * __system_reset_overlay - The PS3 first stage entry.
27 *
28 * The bootwraper build script copies the 0x100 bytes at symbol
29 * __system_reset_overlay to offset 0x100 of the rom image.
30 *
31 * The PS3 has a single processor with two threads.
32 */
33
34 .globl __system_reset_overlay
35__system_reset_overlay:
36
37 /* Switch to 32-bit mode. */
38
39 mfmsr r9
40 clrldi r9,r9,1
41 mtmsrd r9
42 nop
43
44 /* Get thread number in r3 and branch. */
45
46 mfspr r3, 0x88
47 cntlzw. r3, r3
48 li r4, 0
49 li r5, 0
50 beq 1f
51
52 /* Secondary goes to __secondary_hold in kernel. */
53
54 li r4, 0x60
55 mtctr r4
56 bctr
57
58 /* Primary delays then goes to _zimage_start in wrapper. */
591:
60 or 31, 31, 31 /* db16cyc */
61 or 31, 31, 31 /* db16cyc */
62
63 lis r4, _zimage_start@ha
64 addi r4, r4, _zimage_start@l
65 mtctr r4
66 bctr
67
68/*
69 * __system_reset_kernel - Place holder for the kernel reset vector.
70 *
71 * The bootwrapper build script copies 0x100 bytes from offset 0x100
72 * of the rom image to the symbol __system_reset_kernel. At runtime
73 * the bootwrapper program copies the 0x100 bytes at __system_reset_kernel
74 * to ram address 0x100. This symbol must occupy 0x100 bytes.
75 */
76
77 .globl __system_reset_kernel
78__system_reset_kernel:
79
80 . = __system_reset_kernel + 0x100
diff --git a/arch/powerpc/boot/ps3-hvcall.S b/arch/powerpc/boot/ps3-hvcall.S
new file mode 100644
index 000000000000..c8b7df3210d1
--- /dev/null
+++ b/arch/powerpc/boot/ps3-hvcall.S
@@ -0,0 +1,184 @@
1/*
2 * PS3 bootwrapper hvcalls.
3 *
4 * Copyright (C) 2007 Sony Computer Entertainment Inc.
5 * Copyright 2007 Sony Corp.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include "ppc_asm.h"
22
23/*
24 * The PS3 hypervisor uses a 64 bit "C" language calling convention.
25 * The routines here marshal arguments between the 32 bit wrapper
26 * program and the 64 bit hvcalls.
27 *
28 * wrapper lv1
29 * 32-bit (h,l) 64-bit
30 *
31 * 1: r3,r4 <-> r3
32 * 2: r5,r6 <-> r4
33 * 3: r7,r8 <-> r5
34 * 4: r9,r10 <-> r6
35 * 5: 8(r1),12(r1) <-> r7
36 * 6: 16(r1),20(r1) <-> r8
37 * 7: 24(r1),28(r1) <-> r9
38 * 8: 32(r1),36(r1) <-> r10
39 *
40 */
41
42.macro GLOBAL name
43 .section ".text"
44 .balign 4
45 .globl \name
46\name:
47.endm
48
49.macro NO_SUPPORT name
50 GLOBAL \name
51 b ps3_no_support
52.endm
53
54.macro HVCALL num
55 li r11, \num
56 .long 0x44000022
57 extsw r3, r3
58.endm
59
60.macro SAVE_LR offset=4
61 mflr r0
62 stw r0, \offset(r1)
63.endm
64
65.macro LOAD_LR offset=4
66 lwz r0, \offset(r1)
67 mtlr r0
68.endm
69
70.macro LOAD_64_REG target,high,low
71 sldi r11, \high, 32
72 or \target, r11, \low
73.endm
74
75.macro LOAD_64_STACK target,offset
76 ld \target, \offset(r1)
77.endm
78
79.macro LOAD_R3
80 LOAD_64_REG r3,r3,r4
81.endm
82
83.macro LOAD_R4
84 LOAD_64_REG r4,r5,r6
85.endm
86
87.macro LOAD_R5
88 LOAD_64_REG r5,r7,r8
89.endm
90
91.macro LOAD_R6
92 LOAD_64_REG r6,r9,r10
93.endm
94
95.macro LOAD_R7
96 LOAD_64_STACK r7,8
97.endm
98
99.macro LOAD_R8
100 LOAD_64_STACK r8,16
101.endm
102
103.macro LOAD_R9
104 LOAD_64_STACK r9,24
105.endm
106
107.macro LOAD_R10
108 LOAD_64_STACK r10,32
109.endm
110
111.macro LOAD_REGS_0
112 stwu 1,-16(1)
113 stw 3, 8(1)
114.endm
115
116.macro LOAD_REGS_5
117 LOAD_R3
118 LOAD_R4
119 LOAD_R5
120 LOAD_R6
121 LOAD_R7
122.endm
123
124.macro LOAD_REGS_6
125 LOAD_REGS_5
126 LOAD_R8
127.endm
128
129.macro LOAD_REGS_8
130 LOAD_REGS_6
131 LOAD_R9
132 LOAD_R10
133.endm
134
135.macro STORE_REGS_0_1
136 lwz r11, 8(r1)
137 std r4, 0(r11)
138 mr r4, r3
139 li r3, 0
140 addi r1,r1,16
141.endm
142
143.macro STORE_REGS_5_2
144 lwz r11, 16(r1)
145 std r4, 0(r11)
146 lwz r11, 24(r1)
147 std r5, 0(r11)
148.endm
149
150.macro STORE_REGS_6_1
151 lwz r11, 24(r1)
152 std r4, 0(r11)
153.endm
154
155GLOBAL lv1_get_logical_ppe_id
156 SAVE_LR
157 LOAD_REGS_0
158 HVCALL 69
159 STORE_REGS_0_1
160 LOAD_LR
161 blr
162
163GLOBAL lv1_get_logical_partition_id
164 SAVE_LR
165 LOAD_REGS_0
166 HVCALL 74
167 STORE_REGS_0_1
168 LOAD_LR
169 blr
170
171GLOBAL lv1_get_repository_node_value
172 SAVE_LR
173 LOAD_REGS_5
174 HVCALL 91
175 STORE_REGS_5_2
176 LOAD_LR
177 blr
178
179GLOBAL lv1_panic
180 SAVE_LR
181 LOAD_REGS_8
182 HVCALL 255
183 LOAD_LR
184 blr
diff --git a/arch/powerpc/boot/ps3.c b/arch/powerpc/boot/ps3.c
new file mode 100644
index 000000000000..893d59339c26
--- /dev/null
+++ b/arch/powerpc/boot/ps3.c
@@ -0,0 +1,161 @@
1/*
2 * PS3 bootwrapper support.
3 *
4 * Copyright (C) 2007 Sony Computer Entertainment Inc.
5 * Copyright 2007 Sony Corp.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include <stdarg.h>
22#include <stddef.h>
23#include "types.h"
24#include "elf.h"
25#include "string.h"
26#include "stdio.h"
27#include "page.h"
28#include "ops.h"
29
30extern s64 lv1_panic(u64 in_1);
31extern s64 lv1_get_logical_partition_id(u64 *out_1);
32extern s64 lv1_get_logical_ppe_id(u64 *out_1);
33extern s64 lv1_get_repository_node_value(u64 in_1, u64 in_2, u64 in_3,
34 u64 in_4, u64 in_5, u64 *out_1, u64 *out_2);
35
36#ifdef DEBUG
37#define DBG(fmt...) printf(fmt)
38#else
39static inline int __attribute__ ((format (printf, 1, 2))) DBG(
40 const char *fmt, ...) {return 0;}
41#endif
42
43BSS_STACK(4096);
44
45/* A buffer that may be edited by tools operating on a zImage binary so as to
46 * edit the command line passed to vmlinux (by setting /chosen/bootargs).
47 * The buffer is put in it's own section so that tools may locate it easier.
48 */
49static char cmdline[COMMAND_LINE_SIZE]
50 __attribute__((__section__("__builtin_cmdline")));
51
52static void prep_cmdline(void *chosen)
53{
54 if (cmdline[0] == '\0')
55 getprop(chosen, "bootargs", cmdline, COMMAND_LINE_SIZE-1);
56 else
57 setprop_str(chosen, "bootargs", cmdline);
58
59 printf("cmdline: '%s'\n", cmdline);
60}
61
62static void ps3_console_write(const char *buf, int len)
63{
64}
65
66static void ps3_exit(void)
67{
68 printf("ps3_exit\n");
69
70 /* lv1_panic will shutdown the lpar. */
71
72 lv1_panic(0); /* zero = do not reboot */
73 while (1);
74}
75
76static int ps3_repository_read_rm_size(u64 *rm_size)
77{
78 s64 result;
79 u64 lpar_id;
80 u64 ppe_id;
81 u64 v2;
82
83 result = lv1_get_logical_partition_id(&lpar_id);
84
85 if (result)
86 return -1;
87
88 result = lv1_get_logical_ppe_id(&ppe_id);
89
90 if (result)
91 return -1;
92
93 /*
94 * n1: 0000000062690000 : ....bi..
95 * n2: 7075000000000000 : pu......
96 * n3: 0000000000000001 : ........
97 * n4: 726d5f73697a6500 : rm_size.
98 */
99
100 result = lv1_get_repository_node_value(lpar_id, 0x0000000062690000ULL,
101 0x7075000000000000ULL, ppe_id, 0x726d5f73697a6500ULL, rm_size,
102 &v2);
103
104 printf("%s:%d: ppe_id %lu \n", __func__, __LINE__,
105 (unsigned long)ppe_id);
106 printf("%s:%d: lpar_id %lu \n", __func__, __LINE__,
107 (unsigned long)lpar_id);
108 printf("%s:%d: rm_size %llxh \n", __func__, __LINE__, *rm_size);
109
110 return result ? -1 : 0;
111}
112
113void ps3_copy_vectors(void)
114{
115 extern char __system_reset_kernel[];
116
117 memcpy((void *)0x100, __system_reset_kernel, 0x100);
118 flush_cache((void *)0x100, 0x100);
119}
120
121void platform_init(void)
122{
123 extern char _end[];
124 extern char _dtb_start[];
125 extern char _initrd_start[];
126 extern char _initrd_end[];
127 const u32 heapsize = 0x1000000 - (u32)_end; /* 16MiB */
128 void *chosen;
129 unsigned long ft_addr;
130 u64 rm_size;
131
132 console_ops.write = ps3_console_write;
133 platform_ops.exit = ps3_exit;
134
135 printf("\n-- PS3 bootwrapper --\n");
136
137 simple_alloc_init(_end, heapsize, 32, 64);
138 ft_init(_dtb_start, 0, 4);
139
140 chosen = finddevice("/chosen");
141
142 ps3_repository_read_rm_size(&rm_size);
143 dt_fixup_memory(0, rm_size);
144
145 if (_initrd_end > _initrd_start) {
146 setprop_val(chosen, "linux,initrd-start", (u32)(_initrd_start));
147 setprop_val(chosen, "linux,initrd-end", (u32)(_initrd_end));
148 }
149
150 prep_cmdline(chosen);
151
152 ft_addr = dt_ops.finalize();
153
154 ps3_copy_vectors();
155
156 printf(" flat tree at 0x%lx\n\r", ft_addr);
157
158 ((kernel_entry_t)0)(ft_addr, 0, NULL);
159
160 ps3_exit();
161}
diff --git a/arch/powerpc/boot/serial.c b/arch/powerpc/boot/serial.c
index 7fd32330a9a5..eaa0d3ae3518 100644
--- a/arch/powerpc/boot/serial.c
+++ b/arch/powerpc/boot/serial.c
@@ -27,7 +27,7 @@ static int serial_open(void)
27 return scdp->open(); 27 return scdp->open();
28} 28}
29 29
30static void serial_write(char *buf, int len) 30static void serial_write(const char *buf, int len)
31{ 31{
32 struct serial_console_data *scdp = console_ops.data; 32 struct serial_console_data *scdp = console_ops.data;
33 33
diff --git a/arch/powerpc/boot/stdio.c b/arch/powerpc/boot/stdio.c
index 0a9feeb98342..5b57800bbc67 100644
--- a/arch/powerpc/boot/stdio.c
+++ b/arch/powerpc/boot/stdio.c
@@ -190,7 +190,11 @@ int vsprintf(char *buf, const char *fmt, va_list args)
190 190
191 /* get the conversion qualifier */ 191 /* get the conversion qualifier */
192 qualifier = -1; 192 qualifier = -1;
193 if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt =='Z') { 193 if (*fmt == 'l' && *(fmt + 1) == 'l') {
194 qualifier = 'q';
195 fmt += 2;
196 } else if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L'
197 || *fmt == 'Z') {
194 qualifier = *fmt; 198 qualifier = *fmt;
195 ++fmt; 199 ++fmt;
196 } 200 }
@@ -281,6 +285,10 @@ int vsprintf(char *buf, const char *fmt, va_list args)
281 num = va_arg(args, unsigned long); 285 num = va_arg(args, unsigned long);
282 if (flags & SIGN) 286 if (flags & SIGN)
283 num = (signed long) num; 287 num = (signed long) num;
288 } else if (qualifier == 'q') {
289 num = va_arg(args, unsigned long long);
290 if (flags & SIGN)
291 num = (signed long long) num;
284 } else if (qualifier == 'Z') { 292 } else if (qualifier == 'Z') {
285 num = va_arg(args, size_t); 293 num = va_arg(args, size_t);
286 } else if (qualifier == 'h') { 294 } else if (qualifier == 'h') {
diff --git a/arch/powerpc/boot/types.h b/arch/powerpc/boot/types.h
index 79d26e708677..31393d17a9c1 100644
--- a/arch/powerpc/boot/types.h
+++ b/arch/powerpc/boot/types.h
@@ -7,6 +7,10 @@ typedef unsigned char u8;
7typedef unsigned short u16; 7typedef unsigned short u16;
8typedef unsigned int u32; 8typedef unsigned int u32;
9typedef unsigned long long u64; 9typedef unsigned long long u64;
10typedef signed char s8;
11typedef short s16;
12typedef int s32;
13typedef long long s64;
10 14
11#define min(x,y) ({ \ 15#define min(x,y) ({ \
12 typeof(x) _x = (x); \ 16 typeof(x) _x = (x); \
diff --git a/arch/powerpc/boot/wrapper b/arch/powerpc/boot/wrapper
index da77adc73078..65f685479175 100755
--- a/arch/powerpc/boot/wrapper
+++ b/arch/powerpc/boot/wrapper
@@ -144,6 +144,15 @@ miboot|uboot)
144cuboot*) 144cuboot*)
145 gzip= 145 gzip=
146 ;; 146 ;;
147ps3)
148 platformo="$object/ps3-head.o $object/ps3-hvcall.o $object/ps3.o"
149 lds=$object/zImage.ps3.lds
150 gzip=
151 ext=bin
152 objflags="-O binary --set-section-flags=.bss=contents,alloc,load,data"
153 ksection=.kernel:vmlinux.bin
154 isection=.kernel:initrd
155 ;;
147esac 156esac
148 157
149vmz="$tmpdir/`basename \"$kernel\"`.$ext" 158vmz="$tmpdir/`basename \"$kernel\"`.$ext"
@@ -239,4 +248,50 @@ treeboot*)
239 fi 248 fi
240 exit 0 249 exit 0
241 ;; 250 ;;
251ps3)
252 # The ps3's loader supports loading gzipped binary images from flash
253 # rom to addr zero. The loader enters the image at addr 0x100. A
254 # bootwrapper overlay is use to arrange for the kernel to be loaded
255 # to addr zero and to have a suitable bootwrapper entry at 0x100.
256 # To construct the rom image, 0x100 bytes from offset 0x100 in the
257 # kernel is copied to the bootwrapper symbol __system_reset_kernel.
258 # The 0x100 bytes at the bootwrapper symbol __system_reset_overlay is
259 # then copied to offset 0x100. At runtime the bootwrapper program
260 # copies the 0x100 bytes at __system_reset_kernel to addr 0x100.
261
262 system_reset_overlay=0x`${CROSS}nm "$ofile" \
263 | grep ' __system_reset_overlay$' \
264 | cut -d' ' -f1`
265 system_reset_overlay=`printf "%d" $system_reset_overlay`
266 system_reset_kernel=0x`${CROSS}nm "$ofile" \
267 | grep ' __system_reset_kernel$' \
268 | cut -d' ' -f1`
269 system_reset_kernel=`printf "%d" $system_reset_kernel`
270 overlay_dest="256"
271 overlay_size="256"
272
273 rm -f "$object/otheros.bld"
274
275 ${CROSS}objcopy -O binary "$ofile" "$ofile.bin"
276
277 msg=$(dd if="$ofile.bin" of="$ofile.bin" conv=notrunc \
278 skip=$overlay_dest seek=$system_reset_kernel \
279 count=$overlay_size bs=1 2>&1)
280
281 if [ $? -ne "0" ]; then
282 echo $msg
283 exit 1
284 fi
285
286 msg=$(dd if="$ofile.bin" of="$ofile.bin" conv=notrunc \
287 skip=$system_reset_overlay seek=$overlay_dest \
288 count=$overlay_size bs=1 2>&1)
289
290 if [ $? -ne "0" ]; then
291 echo $msg
292 exit 2
293 fi
294
295 gzip --force -9 --stdout "$ofile.bin" > "$object/otheros.bld"
296 ;;
242esac 297esac
diff --git a/arch/powerpc/boot/zImage.ps3.lds.S b/arch/powerpc/boot/zImage.ps3.lds.S
new file mode 100644
index 000000000000..aaa469c1e60d
--- /dev/null
+++ b/arch/powerpc/boot/zImage.ps3.lds.S
@@ -0,0 +1,50 @@
1OUTPUT_ARCH(powerpc:common)
2ENTRY(_zimage_start)
3EXTERN(_zimage_start)
4SECTIONS
5{
6 _vmlinux_start = .;
7 .kernel:vmlinux.bin : { *(.kernel:vmlinux.bin) }
8 _vmlinux_end = .;
9
10 . = ALIGN(4096);
11 _dtb_start = .;
12 .kernel:dtb : { *(.kernel:dtb) }
13 _dtb_end = .;
14
15 . = ALIGN(4096);
16 _initrd_start = .;
17 .kernel:initrd : { *(.kernel:initrd) }
18 _initrd_end = .;
19
20 _start = .;
21 .text :
22 {
23 *(.text)
24 *(.fixup)
25 }
26 _etext = .;
27 . = ALIGN(4096);
28 .data :
29 {
30 *(.rodata*)
31 *(.data*)
32 *(.sdata*)
33 __got2_start = .;
34 *(.got2)
35 __got2_end = .;
36 }
37
38 . = ALIGN(4096);
39 _edata = .;
40
41 . = ALIGN(4096);
42 __bss_start = .;
43 .bss :
44 {
45 *(.sbss)
46 *(.bss)
47 }
48 . = ALIGN(4096);
49 _end = . ;
50}
diff --git a/arch/powerpc/configs/holly_defconfig b/arch/powerpc/configs/holly_defconfig
index 32781849ad4c..04b94f884aae 100644
--- a/arch/powerpc/configs/holly_defconfig
+++ b/arch/powerpc/configs/holly_defconfig
@@ -190,10 +190,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
190# CONFIG_RESOURCES_64BIT is not set 190# CONFIG_RESOURCES_64BIT is not set
191CONFIG_ZONE_DMA_FLAG=1 191CONFIG_ZONE_DMA_FLAG=1
192CONFIG_PROC_DEVICETREE=y 192CONFIG_PROC_DEVICETREE=y
193# CONFIG_CMDLINE_BOOL is not set 193CONFIG_CMDLINE_BOOL=y
194CONFIG_CMDLINE="console=ttyS0,115200"
194# CONFIG_PM is not set 195# CONFIG_PM is not set
195# CONFIG_SECCOMP is not set 196# CONFIG_SECCOMP is not set
196# CONFIG_WANT_DEVICE_TREE is not set 197CONFIG_WANT_DEVICE_TREE=y
198CONFIG_DEVICE_TREE="holly.dts"
197CONFIG_ISA_DMA_API=y 199CONFIG_ISA_DMA_API=y
198 200
199# 201#
diff --git a/arch/powerpc/configs/ps3_defconfig b/arch/powerpc/configs/ps3_defconfig
index 956d1df61e0f..d0b43df44426 100644
--- a/arch/powerpc/configs/ps3_defconfig
+++ b/arch/powerpc/configs/ps3_defconfig
@@ -156,7 +156,11 @@ CONFIG_PS3_HTAB_SIZE=20
156CONFIG_PS3_USE_LPAR_ADDR=y 156CONFIG_PS3_USE_LPAR_ADDR=y
157CONFIG_PS3_VUART=y 157CONFIG_PS3_VUART=y
158CONFIG_PS3_PS3AV=y 158CONFIG_PS3_PS3AV=y
159CONFIG_PS3_SYS_MANAGER=y 159CONFIG_PS3_SYS_MANAGER=m
160CONFIG_PS3_STORAGE=y
161CONFIG_PS3_DISK=y
162CONFIG_PS3_ROM=y
163CONFIG_PS3_FLASH=y
160CONFIG_PPC_CELL=y 164CONFIG_PPC_CELL=y
161# CONFIG_PPC_CELL_NATIVE is not set 165# CONFIG_PPC_CELL_NATIVE is not set
162# CONFIG_PPC_IBM_CELL_BLADE is not set 166# CONFIG_PPC_IBM_CELL_BLADE is not set
@@ -335,7 +339,7 @@ CONFIG_BT=m
335CONFIG_BT_L2CAP=m 339CONFIG_BT_L2CAP=m
336CONFIG_BT_SCO=m 340CONFIG_BT_SCO=m
337CONFIG_BT_RFCOMM=m 341CONFIG_BT_RFCOMM=m
338# CONFIG_BT_RFCOMM_TTY is not set 342CONFIG_BT_RFCOMM_TTY=y
339# CONFIG_BT_BNEP is not set 343# CONFIG_BT_BNEP is not set
340CONFIG_BT_HIDP=m 344CONFIG_BT_HIDP=m
341 345
@@ -344,7 +348,9 @@ CONFIG_BT_HIDP=m
344# 348#
345CONFIG_BT_HCIUSB=m 349CONFIG_BT_HCIUSB=m
346CONFIG_BT_HCIUSB_SCO=y 350CONFIG_BT_HCIUSB_SCO=y
347# CONFIG_BT_HCIUART is not set 351CONFIG_BT_HCIUART=m
352CONFIG_BT_HCIUART_H4=y
353CONFIG_BT_HCIUART_BCSP=y
348# CONFIG_BT_HCIBCM203X is not set 354# CONFIG_BT_HCIBCM203X is not set
349# CONFIG_BT_HCIBPA10X is not set 355# CONFIG_BT_HCIBPA10X is not set
350# CONFIG_BT_HCIBFUSB is not set 356# CONFIG_BT_HCIBFUSB is not set
@@ -435,7 +441,7 @@ CONFIG_CHR_DEV_SG=m
435# 441#
436# Some SCSI devices (e.g. CD jukebox) support multiple LUNs 442# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
437# 443#
438# CONFIG_SCSI_MULTI_LUN is not set 444CONFIG_SCSI_MULTI_LUN=y
439# CONFIG_SCSI_CONSTANTS is not set 445# CONFIG_SCSI_CONSTANTS is not set
440# CONFIG_SCSI_LOGGING is not set 446# CONFIG_SCSI_LOGGING is not set
441# CONFIG_SCSI_SCAN_ASYNC is not set 447# CONFIG_SCSI_SCAN_ASYNC is not set
@@ -479,6 +485,7 @@ CONFIG_NETDEVICES=y
479CONFIG_MII=m 485CONFIG_MII=m
480CONFIG_NETDEV_1000=y 486CONFIG_NETDEV_1000=y
481CONFIG_NETDEV_10000=y 487CONFIG_NETDEV_10000=y
488CONFIG_GELIC_NET=y
482 489
483# 490#
484# Wireless LAN 491# Wireless LAN
@@ -546,7 +553,27 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
546# 553#
547# CONFIG_INPUT_KEYBOARD is not set 554# CONFIG_INPUT_KEYBOARD is not set
548# CONFIG_INPUT_MOUSE is not set 555# CONFIG_INPUT_MOUSE is not set
549# CONFIG_INPUT_JOYSTICK is not set 556CONFIG_INPUT_JOYSTICK=y
557# CONFIG_JOYSTICK_ANALOG is not set
558# CONFIG_JOYSTICK_A3D is not set
559# CONFIG_JOYSTICK_ADI is not set
560# CONFIG_JOYSTICK_COBRA is not set
561# CONFIG_JOYSTICK_GF2K is not set
562# CONFIG_JOYSTICK_GRIP is not set
563# CONFIG_JOYSTICK_GRIP_MP is not set
564# CONFIG_JOYSTICK_GUILLEMOT is not set
565# CONFIG_JOYSTICK_INTERACT is not set
566# CONFIG_JOYSTICK_SIDEWINDER is not set
567# CONFIG_JOYSTICK_TMDC is not set
568# CONFIG_JOYSTICK_IFORCE is not set
569# CONFIG_JOYSTICK_WARRIOR is not set
570# CONFIG_JOYSTICK_MAGELLAN is not set
571# CONFIG_JOYSTICK_SPACEORB is not set
572# CONFIG_JOYSTICK_SPACEBALL is not set
573# CONFIG_JOYSTICK_STINGER is not set
574# CONFIG_JOYSTICK_TWIDJOY is not set
575# CONFIG_JOYSTICK_JOYDUMP is not set
576# CONFIG_JOYSTICK_XPAD is not set
550# CONFIG_INPUT_TABLET is not set 577# CONFIG_INPUT_TABLET is not set
551# CONFIG_INPUT_TOUCHSCREEN is not set 578# CONFIG_INPUT_TOUCHSCREEN is not set
552# CONFIG_INPUT_MISC is not set 579# CONFIG_INPUT_MISC is not set
@@ -563,7 +590,7 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
563CONFIG_VT=y 590CONFIG_VT=y
564CONFIG_VT_CONSOLE=y 591CONFIG_VT_CONSOLE=y
565CONFIG_HW_CONSOLE=y 592CONFIG_HW_CONSOLE=y
566# CONFIG_VT_HW_CONSOLE_BINDING is not set 593CONFIG_VT_HW_CONSOLE_BINDING=y
567# CONFIG_SERIAL_NONSTANDARD is not set 594# CONFIG_SERIAL_NONSTANDARD is not set
568 595
569# 596#
@@ -1086,7 +1113,7 @@ CONFIG_HAS_DMA=y
1086# 1113#
1087# CONFIG_PRINTK_TIME is not set 1114# CONFIG_PRINTK_TIME is not set
1088CONFIG_ENABLE_MUST_CHECK=y 1115CONFIG_ENABLE_MUST_CHECK=y
1089# CONFIG_MAGIC_SYSRQ is not set 1116CONFIG_MAGIC_SYSRQ=y
1090# CONFIG_UNUSED_SYMBOLS is not set 1117# CONFIG_UNUSED_SYMBOLS is not set
1091# CONFIG_DEBUG_FS is not set 1118# CONFIG_DEBUG_FS is not set
1092# CONFIG_HEADERS_CHECK is not set 1119# CONFIG_HEADERS_CHECK is not set
@@ -1116,16 +1143,7 @@ CONFIG_DEBUG_STACKOVERFLOW=y
1116# CONFIG_DEBUGGER is not set 1143# CONFIG_DEBUGGER is not set
1117CONFIG_IRQSTACKS=y 1144CONFIG_IRQSTACKS=y
1118# CONFIG_BOOTX_TEXT is not set 1145# CONFIG_BOOTX_TEXT is not set
1119CONFIG_PPC_EARLY_DEBUG=y 1146# CONFIG_PPC_EARLY_DEBUG is not set
1120# CONFIG_PPC_EARLY_DEBUG_LPAR is not set
1121# CONFIG_PPC_EARLY_DEBUG_G5 is not set
1122# CONFIG_PPC_EARLY_DEBUG_RTAS_PANEL is not set
1123# CONFIG_PPC_EARLY_DEBUG_RTAS_CONSOLE is not set
1124# CONFIG_PPC_EARLY_DEBUG_MAPLE is not set
1125# CONFIG_PPC_EARLY_DEBUG_ISERIES is not set
1126# CONFIG_PPC_EARLY_DEBUG_PAS_REALMODE is not set
1127# CONFIG_PPC_EARLY_DEBUG_BEAT is not set
1128# CONFIG_PPC_EARLY_DEBUG_44x is not set
1129 1147
1130# 1148#
1131# Security options 1149# Security options
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 3e779f07f21b..42c42ecad00c 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -12,7 +12,8 @@ endif
12 12
13obj-y := semaphore.o cputable.o ptrace.o syscalls.o \ 13obj-y := semaphore.o cputable.o ptrace.o syscalls.o \
14 irq.o align.o signal_32.o pmc.o vdso.o \ 14 irq.o align.o signal_32.o pmc.o vdso.o \
15 init_task.o process.o systbl.o idle.o 15 init_task.o process.o systbl.o idle.o \
16 signal.o
16obj-y += vdso32/ 17obj-y += vdso32/
17obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \ 18obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \
18 signal_64.o ptrace32.o \ 19 signal_64.o ptrace32.o \
@@ -65,9 +66,9 @@ obj-$(CONFIG_PPC_UDBG_16550) += legacy_serial.o udbg_16550.o
65module-$(CONFIG_PPC64) += module_64.o 66module-$(CONFIG_PPC64) += module_64.o
66obj-$(CONFIG_MODULES) += $(module-y) 67obj-$(CONFIG_MODULES) += $(module-y)
67 68
68pci64-$(CONFIG_PPC64) += pci_64.o pci_dn.o 69pci64-$(CONFIG_PPC64) += pci_64.o pci_dn.o isa-bridge.o
69pci32-$(CONFIG_PPC32) := pci_32.o 70pci32-$(CONFIG_PPC32) := pci_32.o
70obj-$(CONFIG_PCI) += $(pci64-y) $(pci32-y) 71obj-$(CONFIG_PCI) += $(pci64-y) $(pci32-y) pci-common.o
71obj-$(CONFIG_PCI_MSI) += msi.o 72obj-$(CONFIG_PCI_MSI) += msi.o
72kexec-$(CONFIG_PPC64) := machine_kexec_64.o 73kexec-$(CONFIG_PPC64) := machine_kexec_64.o
73kexec-$(CONFIG_PPC32) := machine_kexec_32.o 74kexec-$(CONFIG_PPC32) := machine_kexec_32.o
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index b2b5d664d328..b1f8000952f3 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -294,6 +294,21 @@ static struct cpu_spec cpu_specs[] = {
294 .oprofile_mmcra_sipr = MMCRA_SIPR, 294 .oprofile_mmcra_sipr = MMCRA_SIPR,
295 .platform = "power5", 295 .platform = "power5",
296 }, 296 },
297 { /* Power5++ */
298 .pvr_mask = 0xffffff00,
299 .pvr_value = 0x003b0300,
300 .cpu_name = "POWER5+ (gs)",
301 .cpu_features = CPU_FTRS_POWER5,
302 .cpu_user_features = COMMON_USER_POWER5_PLUS,
303 .icache_bsize = 128,
304 .dcache_bsize = 128,
305 .num_pmcs = 6,
306 .oprofile_cpu_type = "ppc64/power5++",
307 .oprofile_type = PPC_OPROFILE_POWER4,
308 .oprofile_mmcra_sihv = MMCRA_SIHV,
309 .oprofile_mmcra_sipr = MMCRA_SIPR,
310 .platform = "power5+",
311 },
297 { /* Power5 GS */ 312 { /* Power5 GS */
298 .pvr_mask = 0xffff0000, 313 .pvr_mask = 0xffff0000,
299 .pvr_value = 0x003b0000, 314 .pvr_value = 0x003b0000,
@@ -1178,8 +1193,8 @@ static struct cpu_spec cpu_specs[] = {
1178 .platform = "ppc440", 1193 .platform = "ppc440",
1179 }, 1194 },
1180 { /* 440SP Rev. A */ 1195 { /* 440SP Rev. A */
1181 .pvr_mask = 0xff000fff, 1196 .pvr_mask = 0xfff00fff,
1182 .pvr_value = 0x53000891, 1197 .pvr_value = 0x53200891,
1183 .cpu_name = "440SP Rev. A", 1198 .cpu_name = "440SP Rev. A",
1184 .cpu_features = CPU_FTRS_44X, 1199 .cpu_features = CPU_FTRS_44X,
1185 .cpu_user_features = COMMON_USER_BOOKE, 1200 .cpu_user_features = COMMON_USER_BOOKE,
@@ -1188,9 +1203,19 @@ static struct cpu_spec cpu_specs[] = {
1188 .platform = "ppc440", 1203 .platform = "ppc440",
1189 }, 1204 },
1190 { /* 440SPe Rev. A */ 1205 { /* 440SPe Rev. A */
1191 .pvr_mask = 0xff000fff, 1206 .pvr_mask = 0xfff00fff,
1192 .pvr_value = 0x53000890, 1207 .pvr_value = 0x53400890,
1193 .cpu_name = "440SPe Rev. A", 1208 .cpu_name = "440SPe Rev. A",
1209 .cpu_features = CPU_FTRS_44X,
1210 .cpu_user_features = COMMON_USER_BOOKE,
1211 .icache_bsize = 32,
1212 .dcache_bsize = 32,
1213 .platform = "ppc440",
1214 },
1215 { /* 440SPe Rev. B */
1216 .pvr_mask = 0xfff00fff,
1217 .pvr_value = 0x53400891,
1218 .cpu_name = "440SPe Rev. B",
1194 .cpu_features = CPU_FTRS_44X, 1219 .cpu_features = CPU_FTRS_44X,
1195 .cpu_user_features = COMMON_USER_BOOKE, 1220 .cpu_user_features = COMMON_USER_BOOKE,
1196 .icache_bsize = 32, 1221 .icache_bsize = 32,
diff --git a/arch/powerpc/kernel/head_32.S b/arch/powerpc/kernel/head_32.S
index c897203198b1..7d73a13450b0 100644
--- a/arch/powerpc/kernel/head_32.S
+++ b/arch/powerpc/kernel/head_32.S
@@ -9,7 +9,6 @@
9 * rewritten by Paul Mackerras. 9 * rewritten by Paul Mackerras.
10 * Copyright (C) 1996 Paul Mackerras. 10 * Copyright (C) 1996 Paul Mackerras.
11 * MPC8xx modifications Copyright (C) 1997 Dan Malek (dmalek@jlc.net). 11 * MPC8xx modifications Copyright (C) 1997 Dan Malek (dmalek@jlc.net).
12 * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
13 * 12 *
14 * This file contains the low-level support and setup for the 13 * This file contains the low-level support and setup for the
15 * PowerPC platform, including trap and interrupt dispatch. 14 * PowerPC platform, including trap and interrupt dispatch.
@@ -32,10 +31,6 @@
32#include <asm/ppc_asm.h> 31#include <asm/ppc_asm.h>
33#include <asm/asm-offsets.h> 32#include <asm/asm-offsets.h>
34 33
35#ifdef CONFIG_APUS
36#include <asm/amigappc.h>
37#endif
38
39/* 601 only have IBAT; cr0.eq is set on 601 when using this macro */ 34/* 601 only have IBAT; cr0.eq is set on 601 when using this macro */
40#define LOAD_BAT(n, reg, RA, RB) \ 35#define LOAD_BAT(n, reg, RA, RB) \
41 /* see the comment for clear_bats() -- Cort */ \ 36 /* see the comment for clear_bats() -- Cort */ \
@@ -92,11 +87,6 @@ _start:
92 * r4: virtual address of boot_infos_t 87 * r4: virtual address of boot_infos_t
93 * r5: 0 88 * r5: 0
94 * 89 *
95 * APUS
96 * r3: 'APUS'
97 * r4: physical address of memory base
98 * Linux/m68k style BootInfo structure at &_end.
99 *
100 * PREP 90 * PREP
101 * This is jumped to on prep systems right after the kernel is relocated 91 * This is jumped to on prep systems right after the kernel is relocated
102 * to its proper place in memory by the boot loader. The expected layout 92 * to its proper place in memory by the boot loader. The expected layout
@@ -150,14 +140,6 @@ __start:
150 */ 140 */
151 bl early_init 141 bl early_init
152 142
153#ifdef CONFIG_APUS
154/* On APUS the __va/__pa constants need to be set to the correct
155 * values before continuing.
156 */
157 mr r4,r30
158 bl fix_mem_constants
159#endif /* CONFIG_APUS */
160
161/* Switch MMU off, clear BATs and flush TLB. At this point, r3 contains 143/* Switch MMU off, clear BATs and flush TLB. At this point, r3 contains
162 * the physical address we are running at, returned by early_init() 144 * the physical address we are running at, returned by early_init()
163 */ 145 */
@@ -167,7 +149,7 @@ __after_mmu_off:
167 bl flush_tlbs 149 bl flush_tlbs
168 150
169 bl initial_bats 151 bl initial_bats
170#if !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT) 152#if defined(CONFIG_BOOTX_TEXT)
171 bl setup_disp_bat 153 bl setup_disp_bat
172#endif 154#endif
173 155
@@ -183,7 +165,6 @@ __after_mmu_off:
183#endif /* CONFIG_6xx */ 165#endif /* CONFIG_6xx */
184 166
185 167
186#ifndef CONFIG_APUS
187/* 168/*
188 * We need to run with _start at physical address 0. 169 * We need to run with _start at physical address 0.
189 * On CHRP, we are loaded at 0x10000 since OF on CHRP uses 170 * On CHRP, we are loaded at 0x10000 since OF on CHRP uses
@@ -196,7 +177,6 @@ __after_mmu_off:
196 addis r4,r3,KERNELBASE@h /* current address of _start */ 177 addis r4,r3,KERNELBASE@h /* current address of _start */
197 cmpwi 0,r4,0 /* are we already running at 0? */ 178 cmpwi 0,r4,0 /* are we already running at 0? */
198 bne relocate_kernel 179 bne relocate_kernel
199#endif /* CONFIG_APUS */
200/* 180/*
201 * we now have the 1st 16M of ram mapped with the bats. 181 * we now have the 1st 16M of ram mapped with the bats.
202 * prep needs the mmu to be turned on here, but pmac already has it on. 182 * prep needs the mmu to be turned on here, but pmac already has it on.
@@ -881,85 +861,6 @@ _GLOBAL(copy_and_flush)
881 addi r6,r6,4 861 addi r6,r6,4
882 blr 862 blr
883 863
884#ifdef CONFIG_APUS
885/*
886 * On APUS the physical base address of the kernel is not known at compile
887 * time, which means the __pa/__va constants used are incorrect. In the
888 * __init section is recorded the virtual addresses of instructions using
889 * these constants, so all that has to be done is fix these before
890 * continuing the kernel boot.
891 *
892 * r4 = The physical address of the kernel base.
893 */
894fix_mem_constants:
895 mr r10,r4
896 addis r10,r10,-KERNELBASE@h /* virt_to_phys constant */
897 neg r11,r10 /* phys_to_virt constant */
898
899 lis r12,__vtop_table_begin@h
900 ori r12,r12,__vtop_table_begin@l
901 add r12,r12,r10 /* table begin phys address */
902 lis r13,__vtop_table_end@h
903 ori r13,r13,__vtop_table_end@l
904 add r13,r13,r10 /* table end phys address */
905 subi r12,r12,4
906 subi r13,r13,4
9071: lwzu r14,4(r12) /* virt address of instruction */
908 add r14,r14,r10 /* phys address of instruction */
909 lwz r15,0(r14) /* instruction, now insert top */
910 rlwimi r15,r10,16,16,31 /* half of vp const in low half */
911 stw r15,0(r14) /* of instruction and restore. */
912 dcbst r0,r14 /* write it to memory */
913 sync
914 icbi r0,r14 /* flush the icache line */
915 cmpw r12,r13
916 bne 1b
917 sync /* additional sync needed on g4 */
918 isync
919
920/*
921 * Map the memory where the exception handlers will
922 * be copied to when hash constants have been patched.
923 */
924#ifdef CONFIG_APUS_FAST_EXCEPT
925 lis r8,0xfff0
926#else
927 lis r8,0
928#endif
929 ori r8,r8,0x2 /* 128KB, supervisor */
930 mtspr SPRN_DBAT3U,r8
931 mtspr SPRN_DBAT3L,r8
932
933 lis r12,__ptov_table_begin@h
934 ori r12,r12,__ptov_table_begin@l
935 add r12,r12,r10 /* table begin phys address */
936 lis r13,__ptov_table_end@h
937 ori r13,r13,__ptov_table_end@l
938 add r13,r13,r10 /* table end phys address */
939 subi r12,r12,4
940 subi r13,r13,4
9411: lwzu r14,4(r12) /* virt address of instruction */
942 add r14,r14,r10 /* phys address of instruction */
943 lwz r15,0(r14) /* instruction, now insert top */
944 rlwimi r15,r11,16,16,31 /* half of pv const in low half*/
945 stw r15,0(r14) /* of instruction and restore. */
946 dcbst r0,r14 /* write it to memory */
947 sync
948 icbi r0,r14 /* flush the icache line */
949 cmpw r12,r13
950 bne 1b
951
952 sync /* additional sync needed on g4 */
953 isync /* No speculative loading until now */
954 blr
955
956/***********************************************************************
957 * Please note that on APUS the exception handlers are located at the
958 * physical address 0xfff0000. For this reason, the exception handlers
959 * cannot use relative branches to access the code below.
960 ***********************************************************************/
961#endif /* CONFIG_APUS */
962
963#ifdef CONFIG_SMP 864#ifdef CONFIG_SMP
964#ifdef CONFIG_GEMINI 865#ifdef CONFIG_GEMINI
965 .globl __secondary_start_gemini 866 .globl __secondary_start_gemini
@@ -1135,19 +1036,6 @@ start_here:
1135 bl __save_cpu_setup 1036 bl __save_cpu_setup
1136 bl MMU_init 1037 bl MMU_init
1137 1038
1138#ifdef CONFIG_APUS
1139 /* Copy exception code to exception vector base on APUS. */
1140 lis r4,KERNELBASE@h
1141#ifdef CONFIG_APUS_FAST_EXCEPT
1142 lis r3,0xfff0 /* Copy to 0xfff00000 */
1143#else
1144 lis r3,0 /* Copy to 0x00000000 */
1145#endif
1146 li r5,0x4000 /* # bytes of memory to copy */
1147 li r6,0
1148 bl copy_and_flush /* copy the first 0x4000 bytes */
1149#endif /* CONFIG_APUS */
1150
1151/* 1039/*
1152 * Go back to running unmapped so we can load up new values 1040 * Go back to running unmapped so we can load up new values
1153 * for SDR1 (hash table pointer) and the segment registers 1041 * for SDR1 (hash table pointer) and the segment registers
@@ -1324,11 +1212,7 @@ initial_bats:
1324#else 1212#else
1325 ori r8,r8,2 /* R/W access */ 1213 ori r8,r8,2 /* R/W access */
1326#endif /* CONFIG_SMP */ 1214#endif /* CONFIG_SMP */
1327#ifdef CONFIG_APUS
1328 ori r11,r11,BL_8M<<2|0x2 /* set up 8MB BAT registers for 604 */
1329#else
1330 ori r11,r11,BL_256M<<2|0x2 /* set up BAT registers for 604 */ 1215 ori r11,r11,BL_256M<<2|0x2 /* set up BAT registers for 604 */
1331#endif /* CONFIG_APUS */
1332 1216
1333 mtspr SPRN_DBAT0L,r8 /* N.B. 6xx (not 601) have valid */ 1217 mtspr SPRN_DBAT0L,r8 /* N.B. 6xx (not 601) have valid */
1334 mtspr SPRN_DBAT0U,r11 /* bit in upper BAT register */ 1218 mtspr SPRN_DBAT0U,r11 /* bit in upper BAT register */
@@ -1338,7 +1222,7 @@ initial_bats:
1338 blr 1222 blr
1339 1223
1340 1224
1341#if !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT) 1225#ifdef CONFIG_BOOTX_TEXT
1342setup_disp_bat: 1226setup_disp_bat:
1343 /* 1227 /*
1344 * setup the display bat prepared for us in prom.c 1228 * setup the display bat prepared for us in prom.c
@@ -1362,7 +1246,7 @@ setup_disp_bat:
13621: mtspr SPRN_IBAT3L,r8 12461: mtspr SPRN_IBAT3L,r8
1363 mtspr SPRN_IBAT3U,r11 1247 mtspr SPRN_IBAT3U,r11
1364 blr 1248 blr
1365#endif /* !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT) */ 1249#endif /* CONFIG_BOOTX_TEXT */
1366 1250
1367#ifdef CONFIG_8260 1251#ifdef CONFIG_8260
1368/* Jump into the system reset for the rom. 1252/* Jump into the system reset for the rom.
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index 1111fcec7673..8cdd48ea4391 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -103,8 +103,8 @@ __secondary_hold_acknowledge:
103 103
104 . = 0x60 104 . = 0x60
105/* 105/*
106 * The following code is used on pSeries to hold secondary processors 106 * The following code is used to hold secondary processors
107 * in a spin loop after they have been freed from OpenFirmware, but 107 * in a spin loop after they have entered the kernel, but
108 * before the bulk of the kernel has been relocated. This code 108 * before the bulk of the kernel has been relocated. This code
109 * is relocated to physical address 0x60 before prom_init is run. 109 * is relocated to physical address 0x60 before prom_init is run.
110 * All of it must fit below the first exception vector at 0x100. 110 * All of it must fit below the first exception vector at 0x100.
diff --git a/arch/powerpc/kernel/io.c b/arch/powerpc/kernel/io.c
index 34ae11494ddc..e31aca9208eb 100644
--- a/arch/powerpc/kernel/io.c
+++ b/arch/powerpc/kernel/io.c
@@ -35,7 +35,7 @@ void _insb(const volatile u8 __iomem *port, void *buf, long count)
35 asm volatile("sync"); 35 asm volatile("sync");
36 do { 36 do {
37 tmp = *port; 37 tmp = *port;
38 asm volatile("eieio"); 38 eieio();
39 *tbuf++ = tmp; 39 *tbuf++ = tmp;
40 } while (--count != 0); 40 } while (--count != 0);
41 asm volatile("twi 0,%0,0; isync" : : "r" (tmp)); 41 asm volatile("twi 0,%0,0; isync" : : "r" (tmp));
@@ -66,7 +66,7 @@ void _insw_ns(const volatile u16 __iomem *port, void *buf, long count)
66 asm volatile("sync"); 66 asm volatile("sync");
67 do { 67 do {
68 tmp = *port; 68 tmp = *port;
69 asm volatile("eieio"); 69 eieio();
70 *tbuf++ = tmp; 70 *tbuf++ = tmp;
71 } while (--count != 0); 71 } while (--count != 0);
72 asm volatile("twi 0,%0,0; isync" : : "r" (tmp)); 72 asm volatile("twi 0,%0,0; isync" : : "r" (tmp));
@@ -97,7 +97,7 @@ void _insl_ns(const volatile u32 __iomem *port, void *buf, long count)
97 asm volatile("sync"); 97 asm volatile("sync");
98 do { 98 do {
99 tmp = *port; 99 tmp = *port;
100 asm volatile("eieio"); 100 eieio();
101 *tbuf++ = tmp; 101 *tbuf++ = tmp;
102 } while (--count != 0); 102 } while (--count != 0);
103 asm volatile("twi 0,%0,0; isync" : : "r" (tmp)); 103 asm volatile("twi 0,%0,0; isync" : : "r" (tmp));
@@ -155,21 +155,21 @@ void _memcpy_fromio(void *dest, const volatile void __iomem *src,
155 __asm__ __volatile__ ("sync" : : : "memory"); 155 __asm__ __volatile__ ("sync" : : : "memory");
156 while(n && (!IO_CHECK_ALIGN(vsrc, 4) || !IO_CHECK_ALIGN(dest, 4))) { 156 while(n && (!IO_CHECK_ALIGN(vsrc, 4) || !IO_CHECK_ALIGN(dest, 4))) {
157 *((u8 *)dest) = *((volatile u8 *)vsrc); 157 *((u8 *)dest) = *((volatile u8 *)vsrc);
158 __asm__ __volatile__ ("eieio" : : : "memory"); 158 eieio();
159 vsrc++; 159 vsrc++;
160 dest++; 160 dest++;
161 n--; 161 n--;
162 } 162 }
163 while(n > 4) { 163 while(n > 4) {
164 *((u32 *)dest) = *((volatile u32 *)vsrc); 164 *((u32 *)dest) = *((volatile u32 *)vsrc);
165 __asm__ __volatile__ ("eieio" : : : "memory"); 165 eieio();
166 vsrc += 4; 166 vsrc += 4;
167 dest += 4; 167 dest += 4;
168 n -= 4; 168 n -= 4;
169 } 169 }
170 while(n) { 170 while(n) {
171 *((u8 *)dest) = *((volatile u8 *)vsrc); 171 *((u8 *)dest) = *((volatile u8 *)vsrc);
172 __asm__ __volatile__ ("eieio" : : : "memory"); 172 eieio();
173 vsrc++; 173 vsrc++;
174 dest++; 174 dest++;
175 n--; 175 n--;
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index c2b84c64db20..2fc87862146c 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -7,7 +7,6 @@
7 * Copyright (C) 1996-2001 Cort Dougan 7 * Copyright (C) 1996-2001 Cort Dougan
8 * Adapted for Power Macintosh by Paul Mackerras 8 * Adapted for Power Macintosh by Paul Mackerras
9 * Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au) 9 * Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au)
10 * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
11 * 10 *
12 * This program is free software; you can redistribute it and/or 11 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License 12 * modify it under the terms of the GNU General Public License
@@ -337,7 +336,8 @@ void do_IRQ(struct pt_regs *regs)
337 336
338void __init init_IRQ(void) 337void __init init_IRQ(void)
339{ 338{
340 ppc_md.init_IRQ(); 339 if (ppc_md.init_IRQ)
340 ppc_md.init_IRQ();
341#ifdef CONFIG_PPC64 341#ifdef CONFIG_PPC64
342 irq_ctx_init(); 342 irq_ctx_init();
343#endif 343#endif
@@ -597,6 +597,49 @@ static void irq_radix_rdunlock(unsigned long flags)
597 local_irq_restore(flags); 597 local_irq_restore(flags);
598} 598}
599 599
600static int irq_setup_virq(struct irq_host *host, unsigned int virq,
601 irq_hw_number_t hwirq)
602{
603 /* Clear IRQ_NOREQUEST flag */
604 get_irq_desc(virq)->status &= ~IRQ_NOREQUEST;
605
606 /* map it */
607 smp_wmb();
608 irq_map[virq].hwirq = hwirq;
609 smp_mb();
610
611 if (host->ops->map(host, virq, hwirq)) {
612 pr_debug("irq: -> mapping failed, freeing\n");
613 irq_free_virt(virq, 1);
614 return -1;
615 }
616
617 return 0;
618}
619
620unsigned int irq_create_direct_mapping(struct irq_host *host)
621{
622 unsigned int virq;
623
624 if (host == NULL)
625 host = irq_default_host;
626
627 BUG_ON(host == NULL);
628 WARN_ON(host->revmap_type != IRQ_HOST_MAP_NOMAP);
629
630 virq = irq_alloc_virt(host, 1, 0);
631 if (virq == NO_IRQ) {
632 pr_debug("irq: create_direct virq allocation failed\n");
633 return NO_IRQ;
634 }
635
636 pr_debug("irq: create_direct obtained virq %d\n", virq);
637
638 if (irq_setup_virq(host, virq, virq))
639 return NO_IRQ;
640
641 return virq;
642}
600 643
601unsigned int irq_create_mapping(struct irq_host *host, 644unsigned int irq_create_mapping(struct irq_host *host,
602 irq_hw_number_t hwirq) 645 irq_hw_number_t hwirq)
@@ -645,18 +688,9 @@ unsigned int irq_create_mapping(struct irq_host *host,
645 } 688 }
646 pr_debug("irq: -> obtained virq %d\n", virq); 689 pr_debug("irq: -> obtained virq %d\n", virq);
647 690
648 /* Clear IRQ_NOREQUEST flag */ 691 if (irq_setup_virq(host, virq, hwirq))
649 get_irq_desc(virq)->status &= ~IRQ_NOREQUEST;
650
651 /* map it */
652 smp_wmb();
653 irq_map[virq].hwirq = hwirq;
654 smp_mb();
655 if (host->ops->map(host, virq, hwirq)) {
656 pr_debug("irq: -> mapping failed, freeing\n");
657 irq_free_virt(virq, 1);
658 return NO_IRQ; 692 return NO_IRQ;
659 } 693
660 return virq; 694 return virq;
661} 695}
662EXPORT_SYMBOL_GPL(irq_create_mapping); 696EXPORT_SYMBOL_GPL(irq_create_mapping);
diff --git a/arch/powerpc/kernel/isa-bridge.c b/arch/powerpc/kernel/isa-bridge.c
new file mode 100644
index 000000000000..f0f49d1be3d5
--- /dev/null
+++ b/arch/powerpc/kernel/isa-bridge.c
@@ -0,0 +1,271 @@
1/*
2 * Routines for tracking a legacy ISA bridge
3 *
4 * Copyrigh 2007 Benjamin Herrenschmidt <benh@kernel.crashing.org>, IBM Corp.
5 *
6 * Some bits and pieces moved over from pci_64.c
7 *
8 * Copyrigh 2003 Anton Blanchard <anton@au.ibm.com>, IBM Corp.
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version
13 * 2 of the License, or (at your option) any later version.
14 */
15
16#define DEBUG
17
18#include <linux/kernel.h>
19#include <linux/pci.h>
20#include <linux/string.h>
21#include <linux/init.h>
22#include <linux/mm.h>
23#include <linux/notifier.h>
24
25#include <asm/processor.h>
26#include <asm/io.h>
27#include <asm/prom.h>
28#include <asm/pci-bridge.h>
29#include <asm/machdep.h>
30#include <asm/ppc-pci.h>
31#include <asm/firmware.h>
32
33unsigned long isa_io_base; /* NULL if no ISA bus */
34EXPORT_SYMBOL(isa_io_base);
35
36/* Cached ISA bridge dev. */
37static struct device_node *isa_bridge_devnode;
38struct pci_dev *isa_bridge_pcidev;
39EXPORT_SYMBOL_GPL(isa_bridge_pcidev);
40
41#define ISA_SPACE_MASK 0x1
42#define ISA_SPACE_IO 0x1
43
44static void __devinit pci_process_ISA_OF_ranges(struct device_node *isa_node,
45 unsigned long phb_io_base_phys)
46{
47 /* We should get some saner parsing here and remove these structs */
48 struct pci_address {
49 u32 a_hi;
50 u32 a_mid;
51 u32 a_lo;
52 };
53
54 struct isa_address {
55 u32 a_hi;
56 u32 a_lo;
57 };
58
59 struct isa_range {
60 struct isa_address isa_addr;
61 struct pci_address pci_addr;
62 unsigned int size;
63 };
64
65 const struct isa_range *range;
66 unsigned long pci_addr;
67 unsigned int isa_addr;
68 unsigned int size;
69 int rlen = 0;
70
71 range = of_get_property(isa_node, "ranges", &rlen);
72 if (range == NULL || (rlen < sizeof(struct isa_range)))
73 goto inval_range;
74
75 /* From "ISA Binding to 1275"
76 * The ranges property is laid out as an array of elements,
77 * each of which comprises:
78 * cells 0 - 1: an ISA address
79 * cells 2 - 4: a PCI address
80 * (size depending on dev->n_addr_cells)
81 * cell 5: the size of the range
82 */
83 if ((range->isa_addr.a_hi && ISA_SPACE_MASK) != ISA_SPACE_IO) {
84 range++;
85 rlen -= sizeof(struct isa_range);
86 if (rlen < sizeof(struct isa_range))
87 goto inval_range;
88 }
89 if ((range->isa_addr.a_hi && ISA_SPACE_MASK) != ISA_SPACE_IO)
90 goto inval_range;
91
92 isa_addr = range->isa_addr.a_lo;
93 pci_addr = (unsigned long) range->pci_addr.a_mid << 32 |
94 range->pci_addr.a_lo;
95
96 /* Assume these are both zero. Note: We could fix that and
97 * do a proper parsing instead ... oh well, that will do for
98 * now as nobody uses fancy mappings for ISA bridges
99 */
100 if ((pci_addr != 0) || (isa_addr != 0)) {
101 printk(KERN_ERR "unexpected isa to pci mapping: %s\n",
102 __FUNCTION__);
103 return;
104 }
105
106 /* Align size and make sure it's cropped to 64K */
107 size = PAGE_ALIGN(range->size);
108 if (size > 0x10000)
109 size = 0x10000;
110
111 printk(KERN_ERR "no ISA IO ranges or unexpected isa range,"
112 "mapping 64k\n");
113
114 __ioremap_at(phb_io_base_phys, (void *)ISA_IO_BASE,
115 size, _PAGE_NO_CACHE|_PAGE_GUARDED);
116 return;
117
118inval_range:
119 printk(KERN_ERR "no ISA IO ranges or unexpected isa range,"
120 "mapping 64k\n");
121 __ioremap_at(phb_io_base_phys, (void *)ISA_IO_BASE,
122 0x10000, _PAGE_NO_CACHE|_PAGE_GUARDED);
123}
124
125
126/**
127 * isa_bridge_find_early - Find and map the ISA IO space early before
128 * main PCI discovery. This is optionally called by
129 * the arch code when adding PCI PHBs to get early
130 * access to ISA IO ports
131 */
132void __init isa_bridge_find_early(struct pci_controller *hose)
133{
134 struct device_node *np, *parent = NULL, *tmp;
135
136 /* If we already have an ISA bridge, bail off */
137 if (isa_bridge_devnode != NULL)
138 return;
139
140 /* For each "isa" node in the system. Note : we do a search by
141 * type and not by name. It might be better to do by name but that's
142 * what the code used to do and I don't want to break too much at
143 * once. We can look into changing that separately
144 */
145 for_each_node_by_type(np, "isa") {
146 /* Look for our hose being a parent */
147 for (parent = of_get_parent(np); parent;) {
148 if (parent == hose->arch_data) {
149 of_node_put(parent);
150 break;
151 }
152 tmp = parent;
153 parent = of_get_parent(parent);
154 of_node_put(tmp);
155 }
156 if (parent != NULL)
157 break;
158 }
159 if (np == NULL)
160 return;
161 isa_bridge_devnode = np;
162
163 /* Now parse the "ranges" property and setup the ISA mapping */
164 pci_process_ISA_OF_ranges(np, hose->io_base_phys);
165
166 /* Set the global ISA io base to indicate we have an ISA bridge */
167 isa_io_base = ISA_IO_BASE;
168
169 pr_debug("ISA bridge (early) is %s\n", np->full_name);
170}
171
172/**
173 * isa_bridge_find_late - Find and map the ISA IO space upon discovery of
174 * a new ISA bridge
175 */
176static void __devinit isa_bridge_find_late(struct pci_dev *pdev,
177 struct device_node *devnode)
178{
179 struct pci_controller *hose = pci_bus_to_host(pdev->bus);
180
181 /* Store ISA device node and PCI device */
182 isa_bridge_devnode = of_node_get(devnode);
183 isa_bridge_pcidev = pdev;
184
185 /* Now parse the "ranges" property and setup the ISA mapping */
186 pci_process_ISA_OF_ranges(devnode, hose->io_base_phys);
187
188 /* Set the global ISA io base to indicate we have an ISA bridge */
189 isa_io_base = ISA_IO_BASE;
190
191 pr_debug("ISA bridge (late) is %s on %s\n",
192 devnode->full_name, pci_name(pdev));
193}
194
195/**
196 * isa_bridge_remove - Remove/unmap an ISA bridge
197 */
198static void isa_bridge_remove(void)
199{
200 pr_debug("ISA bridge removed !\n");
201
202 /* Clear the global ISA io base to indicate that we have no more
203 * ISA bridge. Note that drivers don't quite handle that, though
204 * we should probably do something about it. But do we ever really
205 * have ISA bridges being removed on machines using legacy devices ?
206 */
207 isa_io_base = ISA_IO_BASE;
208
209 /* Clear references to the bridge */
210 of_node_put(isa_bridge_devnode);
211 isa_bridge_devnode = NULL;
212 isa_bridge_pcidev = NULL;
213
214 /* Unmap the ISA area */
215 __iounmap_at((void *)ISA_IO_BASE, 0x10000);
216}
217
218/**
219 * isa_bridge_notify - Get notified of PCI devices addition/removal
220 */
221static int __devinit isa_bridge_notify(struct notifier_block *nb,
222 unsigned long action, void *data)
223{
224 struct device *dev = data;
225 struct pci_dev *pdev = to_pci_dev(dev);
226 struct device_node *devnode = pci_device_to_OF_node(pdev);
227
228 switch(action) {
229 case BUS_NOTIFY_ADD_DEVICE:
230 /* Check if we have an early ISA device, without PCI dev */
231 if (isa_bridge_devnode && isa_bridge_devnode == devnode &&
232 !isa_bridge_pcidev) {
233 pr_debug("ISA bridge PCI attached: %s\n",
234 pci_name(pdev));
235 isa_bridge_pcidev = pdev;
236 }
237
238 /* Check if we have no ISA device, and this happens to be one,
239 * register it as such if it has an OF device
240 */
241 if (!isa_bridge_devnode && devnode && devnode->type &&
242 !strcmp(devnode->type, "isa"))
243 isa_bridge_find_late(pdev, devnode);
244
245 return 0;
246 case BUS_NOTIFY_DEL_DEVICE:
247 /* Check if this our existing ISA device */
248 if (pdev == isa_bridge_pcidev ||
249 (devnode && devnode == isa_bridge_devnode))
250 isa_bridge_remove();
251 return 0;
252 }
253 return 0;
254}
255
256static struct notifier_block isa_bridge_notifier = {
257 .notifier_call = isa_bridge_notify
258};
259
260/**
261 * isa_bridge_init - register to be notified of ISA bridge addition/removal
262 *
263 */
264static int __init isa_bridge_init(void)
265{
266 if (firmware_has_feature(FW_FEATURE_ISERIES))
267 return 0;
268 bus_register_notifier(&pci_bus_type, &isa_bridge_notifier);
269 return 0;
270}
271arch_initcall(isa_bridge_init);
diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S
index 98decf8ebff4..e708ab7ca9e8 100644
--- a/arch/powerpc/kernel/misc_32.S
+++ b/arch/powerpc/kernel/misc_32.S
@@ -392,7 +392,7 @@ BEGIN_FTR_SECTION
392 mtspr SPRN_L1CSR0,r3 392 mtspr SPRN_L1CSR0,r3
393 isync 393 isync
394 blr 394 blr
395END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE) 395END_FTR_SECTION_IFSET(CPU_FTR_UNIFIED_ID_CACHE)
396 mfspr r3,SPRN_L1CSR1 396 mfspr r3,SPRN_L1CSR1
397 ori r3,r3,L1CSR1_ICFI|L1CSR1_ICLFR 397 ori r3,r3,L1CSR1_ICFI|L1CSR1_ICLFR
398 mtspr SPRN_L1CSR1,r3 398 mtspr SPRN_L1CSR1,r3
@@ -419,7 +419,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
419_GLOBAL(__flush_icache_range) 419_GLOBAL(__flush_icache_range)
420BEGIN_FTR_SECTION 420BEGIN_FTR_SECTION
421 blr /* for 601, do nothing */ 421 blr /* for 601, do nothing */
422END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE) 422END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
423 li r5,L1_CACHE_BYTES-1 423 li r5,L1_CACHE_BYTES-1
424 andc r3,r3,r5 424 andc r3,r3,r5
425 subf r4,r3,r4 425 subf r4,r3,r4
@@ -514,8 +514,8 @@ _GLOBAL(invalidate_dcache_range)
514 */ 514 */
515_GLOBAL(__flush_dcache_icache) 515_GLOBAL(__flush_dcache_icache)
516BEGIN_FTR_SECTION 516BEGIN_FTR_SECTION
517 blr /* for 601, do nothing */ 517 blr
518END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE) 518END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
519 rlwinm r3,r3,0,0,19 /* Get page base address */ 519 rlwinm r3,r3,0,0,19 /* Get page base address */
520 li r4,4096/L1_CACHE_BYTES /* Number of lines in a page */ 520 li r4,4096/L1_CACHE_BYTES /* Number of lines in a page */
521 mtctr r4 521 mtctr r4
@@ -543,7 +543,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
543_GLOBAL(__flush_dcache_icache_phys) 543_GLOBAL(__flush_dcache_icache_phys)
544BEGIN_FTR_SECTION 544BEGIN_FTR_SECTION
545 blr /* for 601, do nothing */ 545 blr /* for 601, do nothing */
546END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE) 546END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
547 mfmsr r10 547 mfmsr r10
548 rlwinm r0,r10,0,28,26 /* clear DR */ 548 rlwinm r0,r10,0,28,26 /* clear DR */
549 mtmsr r0 549 mtmsr r0
diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S
index 519861da0423..bbb3ba54c51c 100644
--- a/arch/powerpc/kernel/misc_64.S
+++ b/arch/powerpc/kernel/misc_64.S
@@ -646,6 +646,19 @@ _GLOBAL(kexec_sequence)
646 /* turn off mmu */ 646 /* turn off mmu */
647 bl real_mode 647 bl real_mode
648 648
649 /* copy 0x100 bytes starting at start to 0 */
650 li r3,0
651 mr r4,r30 /* start, aka phys mem offset */
652 li r5,0x100
653 li r6,0
654 bl .copy_and_flush /* (dest, src, copy limit, start offset) */
6551: /* assume normal blr return */
656
657 /* release other cpus to the new kernel secondary start at 0x60 */
658 mflr r5
659 li r6,1
660 stw r6,kexec_flag-1b(5)
661
649 /* clear out hardware hash page table and tlb */ 662 /* clear out hardware hash page table and tlb */
650 ld r5,0(r27) /* deref function descriptor */ 663 ld r5,0(r27) /* deref function descriptor */
651 mtctr r5 664 mtctr r5
@@ -676,19 +689,6 @@ _GLOBAL(kexec_sequence)
676 * are the boot cpu ????? 689 * are the boot cpu ?????
677 * other device tree differences (prop sizes, va vs pa, etc)... 690 * other device tree differences (prop sizes, va vs pa, etc)...
678 */ 691 */
679
680 /* copy 0x100 bytes starting at start to 0 */
681 li r3,0
682 mr r4,r30
683 li r5,0x100
684 li r6,0
685 bl .copy_and_flush /* (dest, src, copy limit, start offset) */
6861: /* assume normal blr return */
687
688 /* release other cpus to the new kernel secondary start at 0x60 */
689 mflr r5
690 li r6,1
691 stw r6,kexec_flag-1b(5)
692 mr r3,r25 # my phys cpu 692 mr r3,r25 # my phys cpu
693 mr r4,r30 # start, aka phys mem offset 693 mr r4,r30 # start, aka phys mem offset
694 mtlr 4 694 mtlr 4
diff --git a/arch/powerpc/kernel/of_platform.c b/arch/powerpc/kernel/of_platform.c
index d454f61c9c7c..9536ed7f247c 100644
--- a/arch/powerpc/kernel/of_platform.c
+++ b/arch/powerpc/kernel/of_platform.c
@@ -427,14 +427,6 @@ static int __devinit of_pci_phb_probe(struct of_device *dev,
427 /* Process "ranges" property */ 427 /* Process "ranges" property */
428 pci_process_bridge_OF_ranges(phb, dev->node, 0); 428 pci_process_bridge_OF_ranges(phb, dev->node, 0);
429 429
430 /* Setup IO space. We use the non-dynamic version of that code here,
431 * which doesn't quite support unplugging. Next kernel release will
432 * have a better fix for this.
433 * Note also that we don't do ISA, this will also be fixed with a
434 * more massive rework.
435 */
436 pci_setup_phb_io(phb, pci_io_base == 0);
437
438 /* Init pci_dn data structures */ 430 /* Init pci_dn data structures */
439 pci_devs_phb_init_dynamic(phb); 431 pci_devs_phb_init_dynamic(phb);
440 432
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
new file mode 100644
index 000000000000..faf5ef3e90d0
--- /dev/null
+++ b/arch/powerpc/kernel/pci-common.c
@@ -0,0 +1,454 @@
1/*
2 * Contains common pci routines for ALL ppc platform
3 * (based on pci_32.c and pci_64.c)
4 *
5 * Port for PPC64 David Engebretsen, IBM Corp.
6 * Contains common pci routines for ppc64 platform, pSeries and iSeries brands.
7 *
8 * Copyright (C) 2003 Anton Blanchard <anton@au.ibm.com>, IBM
9 * Rework, based on alpha PCI code.
10 *
11 * Common pmac/prep/chrp pci routines. -- Cort
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version
16 * 2 of the License, or (at your option) any later version.
17 */
18
19#undef DEBUG
20
21#include <linux/kernel.h>
22#include <linux/pci.h>
23#include <linux/string.h>
24#include <linux/init.h>
25#include <linux/bootmem.h>
26#include <linux/mm.h>
27#include <linux/list.h>
28#include <linux/syscalls.h>
29#include <linux/irq.h>
30#include <linux/vmalloc.h>
31
32#include <asm/processor.h>
33#include <asm/io.h>
34#include <asm/prom.h>
35#include <asm/pci-bridge.h>
36#include <asm/byteorder.h>
37#include <asm/machdep.h>
38#include <asm/ppc-pci.h>
39#include <asm/firmware.h>
40
41#ifdef DEBUG
42#include <asm/udbg.h>
43#define DBG(fmt...) printk(fmt)
44#else
45#define DBG(fmt...)
46#endif
47
48static DEFINE_SPINLOCK(hose_spinlock);
49
50/* XXX kill that some day ... */
51int global_phb_number; /* Global phb counter */
52
53extern struct list_head hose_list;
54
55/*
56 * pci_controller(phb) initialized common variables.
57 */
58static void __devinit pci_setup_pci_controller(struct pci_controller *hose)
59{
60 memset(hose, 0, sizeof(struct pci_controller));
61
62 spin_lock(&hose_spinlock);
63 hose->global_number = global_phb_number++;
64 list_add_tail(&hose->list_node, &hose_list);
65 spin_unlock(&hose_spinlock);
66}
67
68struct pci_controller * pcibios_alloc_controller(struct device_node *dev)
69{
70 struct pci_controller *phb;
71
72 if (mem_init_done)
73 phb = kmalloc(sizeof(struct pci_controller), GFP_KERNEL);
74 else
75 phb = alloc_bootmem(sizeof (struct pci_controller));
76 if (phb == NULL)
77 return NULL;
78 pci_setup_pci_controller(phb);
79 phb->arch_data = dev;
80 phb->is_dynamic = mem_init_done;
81#ifdef CONFIG_PPC64
82 if (dev) {
83 int nid = of_node_to_nid(dev);
84
85 if (nid < 0 || !node_online(nid))
86 nid = -1;
87
88 PHB_SET_NODE(phb, nid);
89 }
90#endif
91 return phb;
92}
93
94void pcibios_free_controller(struct pci_controller *phb)
95{
96 spin_lock(&hose_spinlock);
97 list_del(&phb->list_node);
98 spin_unlock(&hose_spinlock);
99
100 if (phb->is_dynamic)
101 kfree(phb);
102}
103
104/*
105 * Return the domain number for this bus.
106 */
107int pci_domain_nr(struct pci_bus *bus)
108{
109 if (firmware_has_feature(FW_FEATURE_ISERIES))
110 return 0;
111 else {
112 struct pci_controller *hose = pci_bus_to_host(bus);
113
114 return hose->global_number;
115 }
116}
117
118EXPORT_SYMBOL(pci_domain_nr);
119
120#ifdef CONFIG_PPC_OF
121
122/* This routine is meant to be used early during boot, when the
123 * PCI bus numbers have not yet been assigned, and you need to
124 * issue PCI config cycles to an OF device.
125 * It could also be used to "fix" RTAS config cycles if you want
126 * to set pci_assign_all_buses to 1 and still use RTAS for PCI
127 * config cycles.
128 */
129struct pci_controller* pci_find_hose_for_OF_device(struct device_node* node)
130{
131 if (!have_of)
132 return NULL;
133 while(node) {
134 struct pci_controller *hose, *tmp;
135 list_for_each_entry_safe(hose, tmp, &hose_list, list_node)
136 if (hose->arch_data == node)
137 return hose;
138 node = node->parent;
139 }
140 return NULL;
141}
142
143static ssize_t pci_show_devspec(struct device *dev,
144 struct device_attribute *attr, char *buf)
145{
146 struct pci_dev *pdev;
147 struct device_node *np;
148
149 pdev = to_pci_dev (dev);
150 np = pci_device_to_OF_node(pdev);
151 if (np == NULL || np->full_name == NULL)
152 return 0;
153 return sprintf(buf, "%s", np->full_name);
154}
155static DEVICE_ATTR(devspec, S_IRUGO, pci_show_devspec, NULL);
156#endif /* CONFIG_PPC_OF */
157
158/* Add sysfs properties */
159void pcibios_add_platform_entries(struct pci_dev *pdev)
160{
161#ifdef CONFIG_PPC_OF
162 device_create_file(&pdev->dev, &dev_attr_devspec);
163#endif /* CONFIG_PPC_OF */
164}
165
166char __init *pcibios_setup(char *str)
167{
168 return str;
169}
170
171/*
172 * Reads the interrupt pin to determine if interrupt is use by card.
173 * If the interrupt is used, then gets the interrupt line from the
174 * openfirmware and sets it in the pci_dev and pci_config line.
175 */
176int pci_read_irq_line(struct pci_dev *pci_dev)
177{
178 struct of_irq oirq;
179 unsigned int virq;
180
181 DBG("Try to map irq for %s...\n", pci_name(pci_dev));
182
183#ifdef DEBUG
184 memset(&oirq, 0xff, sizeof(oirq));
185#endif
186 /* Try to get a mapping from the device-tree */
187 if (of_irq_map_pci(pci_dev, &oirq)) {
188 u8 line, pin;
189
190 /* If that fails, lets fallback to what is in the config
191 * space and map that through the default controller. We
192 * also set the type to level low since that's what PCI
193 * interrupts are. If your platform does differently, then
194 * either provide a proper interrupt tree or don't use this
195 * function.
196 */
197 if (pci_read_config_byte(pci_dev, PCI_INTERRUPT_PIN, &pin))
198 return -1;
199 if (pin == 0)
200 return -1;
201 if (pci_read_config_byte(pci_dev, PCI_INTERRUPT_LINE, &line) ||
202 line == 0xff) {
203 return -1;
204 }
205 DBG(" -> no map ! Using irq line %d from PCI config\n", line);
206
207 virq = irq_create_mapping(NULL, line);
208 if (virq != NO_IRQ)
209 set_irq_type(virq, IRQ_TYPE_LEVEL_LOW);
210 } else {
211 DBG(" -> got one, spec %d cells (0x%08x 0x%08x...) on %s\n",
212 oirq.size, oirq.specifier[0], oirq.specifier[1],
213 oirq.controller->full_name);
214
215 virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
216 oirq.size);
217 }
218 if(virq == NO_IRQ) {
219 DBG(" -> failed to map !\n");
220 return -1;
221 }
222
223 DBG(" -> mapped to linux irq %d\n", virq);
224
225 pci_dev->irq = virq;
226
227 return 0;
228}
229EXPORT_SYMBOL(pci_read_irq_line);
230
231/*
232 * Platform support for /proc/bus/pci/X/Y mmap()s,
233 * modelled on the sparc64 implementation by Dave Miller.
234 * -- paulus.
235 */
236
237/*
238 * Adjust vm_pgoff of VMA such that it is the physical page offset
239 * corresponding to the 32-bit pci bus offset for DEV requested by the user.
240 *
241 * Basically, the user finds the base address for his device which he wishes
242 * to mmap. They read the 32-bit value from the config space base register,
243 * add whatever PAGE_SIZE multiple offset they wish, and feed this into the
244 * offset parameter of mmap on /proc/bus/pci/XXX for that device.
245 *
246 * Returns negative error code on failure, zero on success.
247 */
248static struct resource *__pci_mmap_make_offset(struct pci_dev *dev,
249 resource_size_t *offset,
250 enum pci_mmap_state mmap_state)
251{
252 struct pci_controller *hose = pci_bus_to_host(dev->bus);
253 unsigned long io_offset = 0;
254 int i, res_bit;
255
256 if (hose == 0)
257 return NULL; /* should never happen */
258
259 /* If memory, add on the PCI bridge address offset */
260 if (mmap_state == pci_mmap_mem) {
261#if 0 /* See comment in pci_resource_to_user() for why this is disabled */
262 *offset += hose->pci_mem_offset;
263#endif
264 res_bit = IORESOURCE_MEM;
265 } else {
266 io_offset = (unsigned long)hose->io_base_virt - _IO_BASE;
267 *offset += io_offset;
268 res_bit = IORESOURCE_IO;
269 }
270
271 /*
272 * Check that the offset requested corresponds to one of the
273 * resources of the device.
274 */
275 for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
276 struct resource *rp = &dev->resource[i];
277 int flags = rp->flags;
278
279 /* treat ROM as memory (should be already) */
280 if (i == PCI_ROM_RESOURCE)
281 flags |= IORESOURCE_MEM;
282
283 /* Active and same type? */
284 if ((flags & res_bit) == 0)
285 continue;
286
287 /* In the range of this resource? */
288 if (*offset < (rp->start & PAGE_MASK) || *offset > rp->end)
289 continue;
290
291 /* found it! construct the final physical address */
292 if (mmap_state == pci_mmap_io)
293 *offset += hose->io_base_phys - io_offset;
294 return rp;
295 }
296
297 return NULL;
298}
299
300/*
301 * Set vm_page_prot of VMA, as appropriate for this architecture, for a pci
302 * device mapping.
303 */
304static pgprot_t __pci_mmap_set_pgprot(struct pci_dev *dev, struct resource *rp,
305 pgprot_t protection,
306 enum pci_mmap_state mmap_state,
307 int write_combine)
308{
309 unsigned long prot = pgprot_val(protection);
310
311 /* Write combine is always 0 on non-memory space mappings. On
312 * memory space, if the user didn't pass 1, we check for a
313 * "prefetchable" resource. This is a bit hackish, but we use
314 * this to workaround the inability of /sysfs to provide a write
315 * combine bit
316 */
317 if (mmap_state != pci_mmap_mem)
318 write_combine = 0;
319 else if (write_combine == 0) {
320 if (rp->flags & IORESOURCE_PREFETCH)
321 write_combine = 1;
322 }
323
324 /* XXX would be nice to have a way to ask for write-through */
325 prot |= _PAGE_NO_CACHE;
326 if (write_combine)
327 prot &= ~_PAGE_GUARDED;
328 else
329 prot |= _PAGE_GUARDED;
330
331 return __pgprot(prot);
332}
333
334/*
335 * This one is used by /dev/mem and fbdev who have no clue about the
336 * PCI device, it tries to find the PCI device first and calls the
337 * above routine
338 */
339pgprot_t pci_phys_mem_access_prot(struct file *file,
340 unsigned long pfn,
341 unsigned long size,
342 pgprot_t protection)
343{
344 struct pci_dev *pdev = NULL;
345 struct resource *found = NULL;
346 unsigned long prot = pgprot_val(protection);
347 unsigned long offset = pfn << PAGE_SHIFT;
348 int i;
349
350 if (page_is_ram(pfn))
351 return __pgprot(prot);
352
353 prot |= _PAGE_NO_CACHE | _PAGE_GUARDED;
354
355 for_each_pci_dev(pdev) {
356 for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
357 struct resource *rp = &pdev->resource[i];
358 int flags = rp->flags;
359
360 /* Active and same type? */
361 if ((flags & IORESOURCE_MEM) == 0)
362 continue;
363 /* In the range of this resource? */
364 if (offset < (rp->start & PAGE_MASK) ||
365 offset > rp->end)
366 continue;
367 found = rp;
368 break;
369 }
370 if (found)
371 break;
372 }
373 if (found) {
374 if (found->flags & IORESOURCE_PREFETCH)
375 prot &= ~_PAGE_GUARDED;
376 pci_dev_put(pdev);
377 }
378
379 DBG("non-PCI map for %lx, prot: %lx\n", offset, prot);
380
381 return __pgprot(prot);
382}
383
384
385/*
386 * Perform the actual remap of the pages for a PCI device mapping, as
387 * appropriate for this architecture. The region in the process to map
388 * is described by vm_start and vm_end members of VMA, the base physical
389 * address is found in vm_pgoff.
390 * The pci device structure is provided so that architectures may make mapping
391 * decisions on a per-device or per-bus basis.
392 *
393 * Returns a negative error code on failure, zero on success.
394 */
395int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
396 enum pci_mmap_state mmap_state, int write_combine)
397{
398 resource_size_t offset = vma->vm_pgoff << PAGE_SHIFT;
399 struct resource *rp;
400 int ret;
401
402 rp = __pci_mmap_make_offset(dev, &offset, mmap_state);
403 if (rp == NULL)
404 return -EINVAL;
405
406 vma->vm_pgoff = offset >> PAGE_SHIFT;
407 vma->vm_page_prot = __pci_mmap_set_pgprot(dev, rp,
408 vma->vm_page_prot,
409 mmap_state, write_combine);
410
411 ret = remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
412 vma->vm_end - vma->vm_start, vma->vm_page_prot);
413
414 return ret;
415}
416
417void pci_resource_to_user(const struct pci_dev *dev, int bar,
418 const struct resource *rsrc,
419 resource_size_t *start, resource_size_t *end)
420{
421 struct pci_controller *hose = pci_bus_to_host(dev->bus);
422 resource_size_t offset = 0;
423
424 if (hose == NULL)
425 return;
426
427 if (rsrc->flags & IORESOURCE_IO)
428 offset = (unsigned long)hose->io_base_virt - _IO_BASE;
429
430 /* We pass a fully fixed up address to userland for MMIO instead of
431 * a BAR value because X is lame and expects to be able to use that
432 * to pass to /dev/mem !
433 *
434 * That means that we'll have potentially 64 bits values where some
435 * userland apps only expect 32 (like X itself since it thinks only
436 * Sparc has 64 bits MMIO) but if we don't do that, we break it on
437 * 32 bits CHRPs :-(
438 *
439 * Hopefully, the sysfs insterface is immune to that gunk. Once X
440 * has been fixed (and the fix spread enough), we can re-enable the
441 * 2 lines below and pass down a BAR value to userland. In that case
442 * we'll also have to re-enable the matching code in
443 * __pci_mmap_make_offset().
444 *
445 * BenH.
446 */
447#if 0
448 else if (rsrc->flags & IORESOURCE_MEM)
449 offset = hose->pci_mem_offset;
450#endif
451
452 *start = rsrc->start - offset;
453 *end = rsrc->end - offset;
454}
diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c
index 86982112b0dd..0adf077f3f3a 100644
--- a/arch/powerpc/kernel/pci_32.c
+++ b/arch/powerpc/kernel/pci_32.c
@@ -55,8 +55,7 @@ static u8* pci_to_OF_bus_map;
55 */ 55 */
56int pci_assign_all_buses; 56int pci_assign_all_buses;
57 57
58struct pci_controller* hose_head; 58LIST_HEAD(hose_list);
59struct pci_controller** hose_tail = &hose_head;
60 59
61static int pci_bus_count; 60static int pci_bus_count;
62 61
@@ -573,58 +572,6 @@ pcibios_assign_resources(void)
573 } 572 }
574} 573}
575 574
576
577int
578pcibios_enable_resources(struct pci_dev *dev, int mask)
579{
580 u16 cmd, old_cmd;
581 int idx;
582 struct resource *r;
583
584 pci_read_config_word(dev, PCI_COMMAND, &cmd);
585 old_cmd = cmd;
586 for (idx=0; idx<6; idx++) {
587 /* Only set up the requested stuff */
588 if (!(mask & (1<<idx)))
589 continue;
590
591 r = &dev->resource[idx];
592 if (r->flags & IORESOURCE_UNSET) {
593 printk(KERN_ERR "PCI: Device %s not available because of resource collisions\n", pci_name(dev));
594 return -EINVAL;
595 }
596 if (r->flags & IORESOURCE_IO)
597 cmd |= PCI_COMMAND_IO;
598 if (r->flags & IORESOURCE_MEM)
599 cmd |= PCI_COMMAND_MEMORY;
600 }
601 if (dev->resource[PCI_ROM_RESOURCE].start)
602 cmd |= PCI_COMMAND_MEMORY;
603 if (cmd != old_cmd) {
604 printk("PCI: Enabling device %s (%04x -> %04x)\n", pci_name(dev), old_cmd, cmd);
605 pci_write_config_word(dev, PCI_COMMAND, cmd);
606 }
607 return 0;
608}
609
610static int next_controller_index;
611
612struct pci_controller * __init
613pcibios_alloc_controller(void)
614{
615 struct pci_controller *hose;
616
617 hose = (struct pci_controller *)alloc_bootmem(sizeof(*hose));
618 memset(hose, 0, sizeof(struct pci_controller));
619
620 *hose_tail = hose;
621 hose_tail = &hose->next;
622
623 hose->index = next_controller_index++;
624
625 return hose;
626}
627
628#ifdef CONFIG_PPC_OF 575#ifdef CONFIG_PPC_OF
629/* 576/*
630 * Functions below are used on OpenFirmware machines. 577 * Functions below are used on OpenFirmware machines.
@@ -670,7 +617,7 @@ void
670pcibios_make_OF_bus_map(void) 617pcibios_make_OF_bus_map(void)
671{ 618{
672 int i; 619 int i;
673 struct pci_controller* hose; 620 struct pci_controller *hose, *tmp;
674 struct property *map_prop; 621 struct property *map_prop;
675 struct device_node *dn; 622 struct device_node *dn;
676 623
@@ -687,7 +634,7 @@ pcibios_make_OF_bus_map(void)
687 pci_to_OF_bus_map[i] = 0xff; 634 pci_to_OF_bus_map[i] = 0xff;
688 635
689 /* For each hose, we begin searching bridges */ 636 /* For each hose, we begin searching bridges */
690 for(hose=hose_head; hose; hose=hose->next) { 637 list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
691 struct device_node* node; 638 struct device_node* node;
692 node = (struct device_node *)hose->arch_data; 639 node = (struct device_node *)hose->arch_data;
693 if (!node) 640 if (!node)
@@ -765,7 +712,7 @@ static struct device_node *scan_OF_for_pci_bus(struct pci_bus *bus)
765 712
766 /* Are we a root bus ? */ 713 /* Are we a root bus ? */
767 if (bus->self == NULL || bus->parent == NULL) { 714 if (bus->self == NULL || bus->parent == NULL) {
768 struct pci_controller *hose = pci_bus_to_hose(bus->number); 715 struct pci_controller *hose = pci_bus_to_host(bus);
769 if (hose == NULL) 716 if (hose == NULL)
770 return NULL; 717 return NULL;
771 return of_node_get(hose->arch_data); 718 return of_node_get(hose->arch_data);
@@ -818,27 +765,6 @@ pci_device_to_OF_node(struct pci_dev *dev)
818} 765}
819EXPORT_SYMBOL(pci_device_to_OF_node); 766EXPORT_SYMBOL(pci_device_to_OF_node);
820 767
821/* This routine is meant to be used early during boot, when the
822 * PCI bus numbers have not yet been assigned, and you need to
823 * issue PCI config cycles to an OF device.
824 * It could also be used to "fix" RTAS config cycles if you want
825 * to set pci_assign_all_buses to 1 and still use RTAS for PCI
826 * config cycles.
827 */
828struct pci_controller* pci_find_hose_for_OF_device(struct device_node* node)
829{
830 if (!have_of)
831 return NULL;
832 while(node) {
833 struct pci_controller* hose;
834 for (hose=hose_head;hose;hose=hose->next)
835 if (hose->arch_data == node)
836 return hose;
837 node=node->parent;
838 }
839 return NULL;
840}
841
842static int 768static int
843find_OF_pci_device_filter(struct device_node* node, void* data) 769find_OF_pci_device_filter(struct device_node* node, void* data)
844{ 770{
@@ -1027,34 +953,12 @@ pci_create_OF_bus_map(void)
1027 } 953 }
1028} 954}
1029 955
1030static ssize_t pci_show_devspec(struct device *dev, struct device_attribute *attr, char *buf)
1031{
1032 struct pci_dev *pdev;
1033 struct device_node *np;
1034
1035 pdev = to_pci_dev (dev);
1036 np = pci_device_to_OF_node(pdev);
1037 if (np == NULL || np->full_name == NULL)
1038 return 0;
1039 return sprintf(buf, "%s", np->full_name);
1040}
1041static DEVICE_ATTR(devspec, S_IRUGO, pci_show_devspec, NULL);
1042
1043#else /* CONFIG_PPC_OF */ 956#else /* CONFIG_PPC_OF */
1044void pcibios_make_OF_bus_map(void) 957void pcibios_make_OF_bus_map(void)
1045{ 958{
1046} 959}
1047#endif /* CONFIG_PPC_OF */ 960#endif /* CONFIG_PPC_OF */
1048 961
1049/* Add sysfs properties */
1050int pcibios_add_platform_entries(struct pci_dev *pdev)
1051{
1052#ifdef CONFIG_PPC_OF
1053 return device_create_file(&pdev->dev, &dev_attr_devspec);
1054#endif /* CONFIG_PPC_OF */
1055}
1056
1057
1058#ifdef CONFIG_PPC_PMAC 962#ifdef CONFIG_PPC_PMAC
1059/* 963/*
1060 * This set of routines checks for PCI<->PCI bridges that have closed 964 * This set of routines checks for PCI<->PCI bridges that have closed
@@ -1269,14 +1173,14 @@ pcibios_fixup_p2p_bridges(void)
1269static int __init 1173static int __init
1270pcibios_init(void) 1174pcibios_init(void)
1271{ 1175{
1272 struct pci_controller *hose; 1176 struct pci_controller *hose, *tmp;
1273 struct pci_bus *bus; 1177 struct pci_bus *bus;
1274 int next_busno; 1178 int next_busno = 0;
1275 1179
1276 printk(KERN_INFO "PCI: Probing PCI hardware\n"); 1180 printk(KERN_INFO "PCI: Probing PCI hardware\n");
1277 1181
1278 /* Scan all of the recorded PCI controllers. */ 1182 /* Scan all of the recorded PCI controllers. */
1279 for (next_busno = 0, hose = hose_head; hose; hose = hose->next) { 1183 list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
1280 if (pci_assign_all_buses) 1184 if (pci_assign_all_buses)
1281 hose->first_busno = next_busno; 1185 hose->first_busno = next_busno;
1282 hose->last_busno = 0xff; 1186 hose->last_busno = 0xff;
@@ -1319,12 +1223,6 @@ pcibios_init(void)
1319 1223
1320subsys_initcall(pcibios_init); 1224subsys_initcall(pcibios_init);
1321 1225
1322unsigned long resource_fixup(struct pci_dev * dev, struct resource * res,
1323 unsigned long start, unsigned long size)
1324{
1325 return start;
1326}
1327
1328void __init pcibios_fixup_bus(struct pci_bus *bus) 1226void __init pcibios_fixup_bus(struct pci_bus *bus)
1329{ 1227{
1330 struct pci_controller *hose = (struct pci_controller *) bus->sysdata; 1228 struct pci_controller *hose = (struct pci_controller *) bus->sysdata;
@@ -1342,7 +1240,7 @@ void __init pcibios_fixup_bus(struct pci_bus *bus)
1342 if (!res->flags) { 1240 if (!res->flags) {
1343 if (io_offset) 1241 if (io_offset)
1344 printk(KERN_ERR "I/O resource not set for host" 1242 printk(KERN_ERR "I/O resource not set for host"
1345 " bridge %d\n", hose->index); 1243 " bridge %d\n", hose->global_number);
1346 res->start = 0; 1244 res->start = 0;
1347 res->end = IO_SPACE_LIMIT; 1245 res->end = IO_SPACE_LIMIT;
1348 res->flags = IORESOURCE_IO; 1246 res->flags = IORESOURCE_IO;
@@ -1356,7 +1254,7 @@ void __init pcibios_fixup_bus(struct pci_bus *bus)
1356 if (i > 0) 1254 if (i > 0)
1357 continue; 1255 continue;
1358 printk(KERN_ERR "Memory resource not set for " 1256 printk(KERN_ERR "Memory resource not set for "
1359 "host bridge %d\n", hose->index); 1257 "host bridge %d\n", hose->global_number);
1360 res->start = hose->pci_mem_offset; 1258 res->start = hose->pci_mem_offset;
1361 res->end = ~0U; 1259 res->end = ~0U;
1362 res->flags = IORESOURCE_MEM; 1260 res->flags = IORESOURCE_MEM;
@@ -1370,7 +1268,7 @@ void __init pcibios_fixup_bus(struct pci_bus *bus)
1370 for (i = 0; i < 4; ++i) { 1268 for (i = 0; i < 4; ++i) {
1371 if ((res = bus->resource[i]) == NULL) 1269 if ((res = bus->resource[i]) == NULL)
1372 continue; 1270 continue;
1373 if (!res->flags) 1271 if (!res->flags || bus->self->transparent)
1374 continue; 1272 continue;
1375 if (io_offset && (res->flags & IORESOURCE_IO)) { 1273 if (io_offset && (res->flags & IORESOURCE_IO)) {
1376 res->start += io_offset; 1274 res->start += io_offset;
@@ -1395,11 +1293,6 @@ void __init pcibios_fixup_bus(struct pci_bus *bus)
1395 } 1293 }
1396} 1294}
1397 1295
1398char __init *pcibios_setup(char *str)
1399{
1400 return str;
1401}
1402
1403/* the next one is stolen from the alpha port... */ 1296/* the next one is stolen from the alpha port... */
1404void __init 1297void __init
1405pcibios_update_irq(struct pci_dev *dev, int irq) 1298pcibios_update_irq(struct pci_dev *dev, int irq)
@@ -1408,64 +1301,6 @@ pcibios_update_irq(struct pci_dev *dev, int irq)
1408 /* XXX FIXME - update OF device tree node interrupt property */ 1301 /* XXX FIXME - update OF device tree node interrupt property */
1409} 1302}
1410 1303
1411#ifdef CONFIG_PPC_MERGE
1412/* XXX This is a copy of the ppc64 version. This is temporary until we start
1413 * merging the 2 PCI layers
1414 */
1415/*
1416 * Reads the interrupt pin to determine if interrupt is use by card.
1417 * If the interrupt is used, then gets the interrupt line from the
1418 * openfirmware and sets it in the pci_dev and pci_config line.
1419 */
1420int pci_read_irq_line(struct pci_dev *pci_dev)
1421{
1422 struct of_irq oirq;
1423 unsigned int virq;
1424
1425 DBG("Try to map irq for %s...\n", pci_name(pci_dev));
1426
1427 /* Try to get a mapping from the device-tree */
1428 if (of_irq_map_pci(pci_dev, &oirq)) {
1429 u8 line, pin;
1430
1431 /* If that fails, lets fallback to what is in the config
1432 * space and map that through the default controller. We
1433 * also set the type to level low since that's what PCI
1434 * interrupts are. If your platform does differently, then
1435 * either provide a proper interrupt tree or don't use this
1436 * function.
1437 */
1438 if (pci_read_config_byte(pci_dev, PCI_INTERRUPT_PIN, &pin))
1439 return -1;
1440 if (pin == 0)
1441 return -1;
1442 if (pci_read_config_byte(pci_dev, PCI_INTERRUPT_LINE, &line) ||
1443 line == 0xff) {
1444 return -1;
1445 }
1446 DBG(" -> no map ! Using irq line %d from PCI config\n", line);
1447
1448 virq = irq_create_mapping(NULL, line);
1449 if (virq != NO_IRQ)
1450 set_irq_type(virq, IRQ_TYPE_LEVEL_LOW);
1451 } else {
1452 DBG(" -> got one, spec %d cells (0x%08x...) on %s\n",
1453 oirq.size, oirq.specifier[0], oirq.controller->full_name);
1454
1455 virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
1456 oirq.size);
1457 }
1458 if(virq == NO_IRQ) {
1459 DBG(" -> failed to map !\n");
1460 return -1;
1461 }
1462 pci_dev->irq = virq;
1463
1464 return 0;
1465}
1466EXPORT_SYMBOL(pci_read_irq_line);
1467#endif /* CONFIG_PPC_MERGE */
1468
1469int pcibios_enable_device(struct pci_dev *dev, int mask) 1304int pcibios_enable_device(struct pci_dev *dev, int mask)
1470{ 1305{
1471 u16 cmd, old_cmd; 1306 u16 cmd, old_cmd;
@@ -1497,281 +1332,17 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
1497 return 0; 1332 return 0;
1498} 1333}
1499 1334
1500struct pci_controller* 1335static struct pci_controller*
1501pci_bus_to_hose(int bus) 1336pci_bus_to_hose(int bus)
1502{ 1337{
1503 struct pci_controller* hose = hose_head; 1338 struct pci_controller *hose, *tmp;
1504 1339
1505 for (; hose; hose = hose->next) 1340 list_for_each_entry_safe(hose, tmp, &hose_list, list_node)
1506 if (bus >= hose->first_busno && bus <= hose->last_busno) 1341 if (bus >= hose->first_busno && bus <= hose->last_busno)
1507 return hose; 1342 return hose;
1508 return NULL; 1343 return NULL;
1509} 1344}
1510 1345
1511void __iomem *
1512pci_bus_io_base(unsigned int bus)
1513{
1514 struct pci_controller *hose;
1515
1516 hose = pci_bus_to_hose(bus);
1517 if (!hose)
1518 return NULL;
1519 return hose->io_base_virt;
1520}
1521
1522unsigned long
1523pci_bus_io_base_phys(unsigned int bus)
1524{
1525 struct pci_controller *hose;
1526
1527 hose = pci_bus_to_hose(bus);
1528 if (!hose)
1529 return 0;
1530 return hose->io_base_phys;
1531}
1532
1533unsigned long
1534pci_bus_mem_base_phys(unsigned int bus)
1535{
1536 struct pci_controller *hose;
1537
1538 hose = pci_bus_to_hose(bus);
1539 if (!hose)
1540 return 0;
1541 return hose->pci_mem_offset;
1542}
1543
1544unsigned long
1545pci_resource_to_bus(struct pci_dev *pdev, struct resource *res)
1546{
1547 /* Hack alert again ! See comments in chrp_pci.c
1548 */
1549 struct pci_controller* hose =
1550 (struct pci_controller *)pdev->sysdata;
1551 if (hose && res->flags & IORESOURCE_MEM)
1552 return res->start - hose->pci_mem_offset;
1553 /* We may want to do something with IOs here... */
1554 return res->start;
1555}
1556
1557
1558static struct resource *__pci_mmap_make_offset(struct pci_dev *dev,
1559 resource_size_t *offset,
1560 enum pci_mmap_state mmap_state)
1561{
1562 struct pci_controller *hose = pci_bus_to_hose(dev->bus->number);
1563 unsigned long io_offset = 0;
1564 int i, res_bit;
1565
1566 if (hose == 0)
1567 return NULL; /* should never happen */
1568
1569 /* If memory, add on the PCI bridge address offset */
1570 if (mmap_state == pci_mmap_mem) {
1571#if 0 /* See comment in pci_resource_to_user() for why this is disabled */
1572 *offset += hose->pci_mem_offset;
1573#endif
1574 res_bit = IORESOURCE_MEM;
1575 } else {
1576 io_offset = hose->io_base_virt - (void __iomem *)_IO_BASE;
1577 *offset += io_offset;
1578 res_bit = IORESOURCE_IO;
1579 }
1580
1581 /*
1582 * Check that the offset requested corresponds to one of the
1583 * resources of the device.
1584 */
1585 for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
1586 struct resource *rp = &dev->resource[i];
1587 int flags = rp->flags;
1588
1589 /* treat ROM as memory (should be already) */
1590 if (i == PCI_ROM_RESOURCE)
1591 flags |= IORESOURCE_MEM;
1592
1593 /* Active and same type? */
1594 if ((flags & res_bit) == 0)
1595 continue;
1596
1597 /* In the range of this resource? */
1598 if (*offset < (rp->start & PAGE_MASK) || *offset > rp->end)
1599 continue;
1600
1601 /* found it! construct the final physical address */
1602 if (mmap_state == pci_mmap_io)
1603 *offset += hose->io_base_phys - io_offset;
1604 return rp;
1605 }
1606
1607 return NULL;
1608}
1609
1610/*
1611 * Set vm_page_prot of VMA, as appropriate for this architecture, for a pci
1612 * device mapping.
1613 */
1614static pgprot_t __pci_mmap_set_pgprot(struct pci_dev *dev, struct resource *rp,
1615 pgprot_t protection,
1616 enum pci_mmap_state mmap_state,
1617 int write_combine)
1618{
1619 unsigned long prot = pgprot_val(protection);
1620
1621 /* Write combine is always 0 on non-memory space mappings. On
1622 * memory space, if the user didn't pass 1, we check for a
1623 * "prefetchable" resource. This is a bit hackish, but we use
1624 * this to workaround the inability of /sysfs to provide a write
1625 * combine bit
1626 */
1627 if (mmap_state != pci_mmap_mem)
1628 write_combine = 0;
1629 else if (write_combine == 0) {
1630 if (rp->flags & IORESOURCE_PREFETCH)
1631 write_combine = 1;
1632 }
1633
1634 /* XXX would be nice to have a way to ask for write-through */
1635 prot |= _PAGE_NO_CACHE;
1636 if (write_combine)
1637 prot &= ~_PAGE_GUARDED;
1638 else
1639 prot |= _PAGE_GUARDED;
1640
1641 return __pgprot(prot);
1642}
1643
1644/*
1645 * This one is used by /dev/mem and fbdev who have no clue about the
1646 * PCI device, it tries to find the PCI device first and calls the
1647 * above routine
1648 */
1649pgprot_t pci_phys_mem_access_prot(struct file *file,
1650 unsigned long pfn,
1651 unsigned long size,
1652 pgprot_t protection)
1653{
1654 struct pci_dev *pdev = NULL;
1655 struct resource *found = NULL;
1656 unsigned long prot = pgprot_val(protection);
1657 unsigned long offset = pfn << PAGE_SHIFT;
1658 int i;
1659
1660 if (page_is_ram(pfn))
1661 return __pgprot(prot);
1662
1663 prot |= _PAGE_NO_CACHE | _PAGE_GUARDED;
1664
1665 for_each_pci_dev(pdev) {
1666 for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
1667 struct resource *rp = &pdev->resource[i];
1668 int flags = rp->flags;
1669
1670 /* Active and same type? */
1671 if ((flags & IORESOURCE_MEM) == 0)
1672 continue;
1673 /* In the range of this resource? */
1674 if (offset < (rp->start & PAGE_MASK) ||
1675 offset > rp->end)
1676 continue;
1677 found = rp;
1678 break;
1679 }
1680 if (found)
1681 break;
1682 }
1683 if (found) {
1684 if (found->flags & IORESOURCE_PREFETCH)
1685 prot &= ~_PAGE_GUARDED;
1686 pci_dev_put(pdev);
1687 }
1688
1689 DBG("non-PCI map for %lx, prot: %lx\n", offset, prot);
1690
1691 return __pgprot(prot);
1692}
1693
1694
1695/*
1696 * Perform the actual remap of the pages for a PCI device mapping, as
1697 * appropriate for this architecture. The region in the process to map
1698 * is described by vm_start and vm_end members of VMA, the base physical
1699 * address is found in vm_pgoff.
1700 * The pci device structure is provided so that architectures may make mapping
1701 * decisions on a per-device or per-bus basis.
1702 *
1703 * Returns a negative error code on failure, zero on success.
1704 */
1705int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
1706 enum pci_mmap_state mmap_state,
1707 int write_combine)
1708{
1709 resource_size_t offset = vma->vm_pgoff << PAGE_SHIFT;
1710 struct resource *rp;
1711 int ret;
1712
1713 rp = __pci_mmap_make_offset(dev, &offset, mmap_state);
1714 if (rp == NULL)
1715 return -EINVAL;
1716
1717 vma->vm_pgoff = offset >> PAGE_SHIFT;
1718 vma->vm_page_prot = __pci_mmap_set_pgprot(dev, rp,
1719 vma->vm_page_prot,
1720 mmap_state, write_combine);
1721
1722 ret = remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
1723 vma->vm_end - vma->vm_start, vma->vm_page_prot);
1724
1725 return ret;
1726}
1727
1728/* Obsolete functions. Should be removed once the symbios driver
1729 * is fixed
1730 */
1731unsigned long
1732phys_to_bus(unsigned long pa)
1733{
1734 struct pci_controller *hose;
1735 int i;
1736
1737 for (hose = hose_head; hose; hose = hose->next) {
1738 for (i = 0; i < 3; ++i) {
1739 if (pa >= hose->mem_resources[i].start
1740 && pa <= hose->mem_resources[i].end) {
1741 /*
1742 * XXX the hose->pci_mem_offset really
1743 * only applies to mem_resources[0].
1744 * We need a way to store an offset for
1745 * the others. -- paulus
1746 */
1747 if (i == 0)
1748 pa -= hose->pci_mem_offset;
1749 return pa;
1750 }
1751 }
1752 }
1753 /* hmmm, didn't find it */
1754 return 0;
1755}
1756
1757unsigned long
1758pci_phys_to_bus(unsigned long pa, int busnr)
1759{
1760 struct pci_controller* hose = pci_bus_to_hose(busnr);
1761 if (!hose)
1762 return pa;
1763 return pa - hose->pci_mem_offset;
1764}
1765
1766unsigned long
1767pci_bus_to_phys(unsigned int ba, int busnr)
1768{
1769 struct pci_controller* hose = pci_bus_to_hose(busnr);
1770 if (!hose)
1771 return ba;
1772 return ba + hose->pci_mem_offset;
1773}
1774
1775/* Provide information on locations of various I/O regions in physical 1346/* Provide information on locations of various I/O regions in physical
1776 * memory. Do this on a per-card basis so that we choose the right 1347 * memory. Do this on a per-card basis so that we choose the right
1777 * root bridge. 1348 * root bridge.
@@ -1814,62 +1385,11 @@ long sys_pciconfig_iobase(long which, unsigned long bus, unsigned long devfn)
1814 return result; 1385 return result;
1815} 1386}
1816 1387
1817void pci_resource_to_user(const struct pci_dev *dev, int bar,
1818 const struct resource *rsrc,
1819 resource_size_t *start, resource_size_t *end)
1820{
1821 struct pci_controller *hose = pci_bus_to_hose(dev->bus->number);
1822 resource_size_t offset = 0;
1823
1824 if (hose == NULL)
1825 return;
1826
1827 if (rsrc->flags & IORESOURCE_IO)
1828 offset = (unsigned long)hose->io_base_virt - _IO_BASE;
1829
1830 /* We pass a fully fixed up address to userland for MMIO instead of
1831 * a BAR value because X is lame and expects to be able to use that
1832 * to pass to /dev/mem !
1833 *
1834 * That means that we'll have potentially 64 bits values where some
1835 * userland apps only expect 32 (like X itself since it thinks only
1836 * Sparc has 64 bits MMIO) but if we don't do that, we break it on
1837 * 32 bits CHRPs :-(
1838 *
1839 * Hopefully, the sysfs insterface is immune to that gunk. Once X
1840 * has been fixed (and the fix spread enough), we can re-enable the
1841 * 2 lines below and pass down a BAR value to userland. In that case
1842 * we'll also have to re-enable the matching code in
1843 * __pci_mmap_make_offset().
1844 *
1845 * BenH.
1846 */
1847#if 0
1848 else if (rsrc->flags & IORESOURCE_MEM)
1849 offset = hose->pci_mem_offset;
1850#endif
1851
1852 *start = rsrc->start - offset;
1853 *end = rsrc->end - offset;
1854}
1855
1856void __init pci_init_resource(struct resource *res, resource_size_t start,
1857 resource_size_t end, int flags, char *name)
1858{
1859 res->start = start;
1860 res->end = end;
1861 res->flags = flags;
1862 res->name = name;
1863 res->parent = NULL;
1864 res->sibling = NULL;
1865 res->child = NULL;
1866}
1867
1868unsigned long pci_address_to_pio(phys_addr_t address) 1388unsigned long pci_address_to_pio(phys_addr_t address)
1869{ 1389{
1870 struct pci_controller* hose = hose_head; 1390 struct pci_controller *hose, *tmp;
1871 1391
1872 for (; hose; hose = hose->next) { 1392 list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
1873 unsigned int size = hose->io_resource.end - 1393 unsigned int size = hose->io_resource.end -
1874 hose->io_resource.start + 1; 1394 hose->io_resource.start + 1;
1875 if (address >= hose->io_base_phys && 1395 if (address >= hose->io_base_phys &&
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index e3009a43ac56..a97e23ac1976 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -22,6 +22,7 @@
22#include <linux/list.h> 22#include <linux/list.h>
23#include <linux/syscalls.h> 23#include <linux/syscalls.h>
24#include <linux/irq.h> 24#include <linux/irq.h>
25#include <linux/vmalloc.h>
25 26
26#include <asm/processor.h> 27#include <asm/processor.h>
27#include <asm/io.h> 28#include <asm/io.h>
@@ -41,35 +42,23 @@
41 42
42unsigned long pci_probe_only = 1; 43unsigned long pci_probe_only = 1;
43int pci_assign_all_buses = 0; 44int pci_assign_all_buses = 0;
44static int pci_initial_scan_done;
45 45
46static void fixup_resource(struct resource *res, struct pci_dev *dev); 46static void fixup_resource(struct resource *res, struct pci_dev *dev);
47static void do_bus_setup(struct pci_bus *bus); 47static void do_bus_setup(struct pci_bus *bus);
48static void phbs_remap_io(void);
49 48
50/* pci_io_base -- the base address from which io bars are offsets. 49/* pci_io_base -- the base address from which io bars are offsets.
51 * This is the lowest I/O base address (so bar values are always positive), 50 * This is the lowest I/O base address (so bar values are always positive),
52 * and it *must* be the start of ISA space if an ISA bus exists because 51 * and it *must* be the start of ISA space if an ISA bus exists because
53 * ISA drivers use hard coded offsets. If no ISA bus exists a dummy 52 * ISA drivers use hard coded offsets. If no ISA bus exists nothing
54 * page is mapped and isa_io_limit prevents access to it. 53 * is mapped on the first 64K of IO space
55 */ 54 */
56unsigned long isa_io_base; /* NULL if no ISA bus */ 55unsigned long pci_io_base = ISA_IO_BASE;
57EXPORT_SYMBOL(isa_io_base);
58unsigned long pci_io_base;
59EXPORT_SYMBOL(pci_io_base); 56EXPORT_SYMBOL(pci_io_base);
60 57
61void iSeries_pcibios_init(void);
62
63LIST_HEAD(hose_list); 58LIST_HEAD(hose_list);
64 59
65static struct dma_mapping_ops *pci_dma_ops; 60static struct dma_mapping_ops *pci_dma_ops;
66 61
67int global_phb_number; /* Global phb counter */
68
69/* Cached ISA bridge dev. */
70struct pci_dev *ppc64_isabridge_dev = NULL;
71EXPORT_SYMBOL_GPL(ppc64_isabridge_dev);
72
73void set_pci_dma_ops(struct dma_mapping_ops *dma_ops) 62void set_pci_dma_ops(struct dma_mapping_ops *dma_ops)
74{ 63{
75 pci_dma_ops = dma_ops; 64 pci_dma_ops = dma_ops;
@@ -100,7 +89,7 @@ void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region
100 return; 89 return;
101 90
102 if (res->flags & IORESOURCE_IO) 91 if (res->flags & IORESOURCE_IO)
103 offset = (unsigned long)hose->io_base_virt - pci_io_base; 92 offset = (unsigned long)hose->io_base_virt - _IO_BASE;
104 93
105 if (res->flags & IORESOURCE_MEM) 94 if (res->flags & IORESOURCE_MEM)
106 offset = hose->pci_mem_offset; 95 offset = hose->pci_mem_offset;
@@ -119,7 +108,7 @@ void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
119 return; 108 return;
120 109
121 if (res->flags & IORESOURCE_IO) 110 if (res->flags & IORESOURCE_IO)
122 offset = (unsigned long)hose->io_base_virt - pci_io_base; 111 offset = (unsigned long)hose->io_base_virt - _IO_BASE;
123 112
124 if (res->flags & IORESOURCE_MEM) 113 if (res->flags & IORESOURCE_MEM)
125 offset = hose->pci_mem_offset; 114 offset = hose->pci_mem_offset;
@@ -156,7 +145,7 @@ void pcibios_align_resource(void *data, struct resource *res,
156 145
157 if (res->flags & IORESOURCE_IO) { 146 if (res->flags & IORESOURCE_IO) {
158 unsigned long offset = (unsigned long)hose->io_base_virt - 147 unsigned long offset = (unsigned long)hose->io_base_virt -
159 pci_io_base; 148 _IO_BASE;
160 /* Make sure we start at our min on all hoses */ 149 /* Make sure we start at our min on all hoses */
161 if (start - offset < PCIBIOS_MIN_IO) 150 if (start - offset < PCIBIOS_MIN_IO)
162 start = PCIBIOS_MIN_IO + offset; 151 start = PCIBIOS_MIN_IO + offset;
@@ -180,55 +169,6 @@ void pcibios_align_resource(void *data, struct resource *res,
180 res->start = start; 169 res->start = start;
181} 170}
182 171
183static DEFINE_SPINLOCK(hose_spinlock);
184
185/*
186 * pci_controller(phb) initialized common variables.
187 */
188static void __devinit pci_setup_pci_controller(struct pci_controller *hose)
189{
190 memset(hose, 0, sizeof(struct pci_controller));
191
192 spin_lock(&hose_spinlock);
193 hose->global_number = global_phb_number++;
194 list_add_tail(&hose->list_node, &hose_list);
195 spin_unlock(&hose_spinlock);
196}
197
198struct pci_controller * pcibios_alloc_controller(struct device_node *dev)
199{
200 struct pci_controller *phb;
201
202 if (mem_init_done)
203 phb = kmalloc(sizeof(struct pci_controller), GFP_KERNEL);
204 else
205 phb = alloc_bootmem(sizeof (struct pci_controller));
206 if (phb == NULL)
207 return NULL;
208 pci_setup_pci_controller(phb);
209 phb->arch_data = dev;
210 phb->is_dynamic = mem_init_done;
211 if (dev) {
212 int nid = of_node_to_nid(dev);
213
214 if (nid < 0 || !node_online(nid))
215 nid = -1;
216
217 PHB_SET_NODE(phb, nid);
218 }
219 return phb;
220}
221
222void pcibios_free_controller(struct pci_controller *phb)
223{
224 spin_lock(&hose_spinlock);
225 list_del(&phb->list_node);
226 spin_unlock(&hose_spinlock);
227
228 if (phb->is_dynamic)
229 kfree(phb);
230}
231
232void __devinit pcibios_claim_one_bus(struct pci_bus *b) 172void __devinit pcibios_claim_one_bus(struct pci_bus *b)
233{ 173{
234 struct pci_dev *dev; 174 struct pci_dev *dev;
@@ -291,7 +231,6 @@ static unsigned int pci_parse_of_flags(u32 addr0)
291 return flags; 231 return flags;
292} 232}
293 233
294#define GET_64BIT(prop, i) ((((u64) (prop)[(i)]) << 32) | (prop)[(i)+1])
295 234
296static void pci_parse_of_addrs(struct device_node *node, struct pci_dev *dev) 235static void pci_parse_of_addrs(struct device_node *node, struct pci_dev *dev)
297{ 236{
@@ -310,8 +249,8 @@ static void pci_parse_of_addrs(struct device_node *node, struct pci_dev *dev)
310 flags = pci_parse_of_flags(addrs[0]); 249 flags = pci_parse_of_flags(addrs[0]);
311 if (!flags) 250 if (!flags)
312 continue; 251 continue;
313 base = GET_64BIT(addrs, 1); 252 base = of_read_number(&addrs[1], 2);
314 size = GET_64BIT(addrs, 3); 253 size = of_read_number(&addrs[3], 2);
315 if (!size) 254 if (!size)
316 continue; 255 continue;
317 i = addrs[0] & 0xff; 256 i = addrs[0] & 0xff;
@@ -479,7 +418,7 @@ void __devinit of_scan_pci_bridge(struct device_node *node,
479 i = 1; 418 i = 1;
480 for (; len >= 32; len -= 32, ranges += 8) { 419 for (; len >= 32; len -= 32, ranges += 8) {
481 flags = pci_parse_of_flags(ranges[0]); 420 flags = pci_parse_of_flags(ranges[0]);
482 size = GET_64BIT(ranges, 6); 421 size = of_read_number(&ranges[6], 2);
483 if (flags == 0 || size == 0) 422 if (flags == 0 || size == 0)
484 continue; 423 continue;
485 if (flags & IORESOURCE_IO) { 424 if (flags & IORESOURCE_IO) {
@@ -498,7 +437,7 @@ void __devinit of_scan_pci_bridge(struct device_node *node,
498 res = bus->resource[i]; 437 res = bus->resource[i];
499 ++i; 438 ++i;
500 } 439 }
501 res->start = GET_64BIT(ranges, 1); 440 res->start = of_read_number(&ranges[1], 2);
502 res->end = res->start + size - 1; 441 res->end = res->start + size - 1;
503 res->flags = flags; 442 res->flags = flags;
504 fixup_resource(res, dev); 443 fixup_resource(res, dev);
@@ -537,10 +476,16 @@ void __devinit scan_phb(struct pci_controller *hose)
537 bus->secondary = hose->first_busno; 476 bus->secondary = hose->first_busno;
538 hose->bus = bus; 477 hose->bus = bus;
539 478
479 if (!firmware_has_feature(FW_FEATURE_ISERIES))
480 pcibios_map_io_space(bus);
481
540 bus->resource[0] = res = &hose->io_resource; 482 bus->resource[0] = res = &hose->io_resource;
541 if (res->flags && request_resource(&ioport_resource, res)) 483 if (res->flags && request_resource(&ioport_resource, res)) {
542 printk(KERN_ERR "Failed to request PCI IO region " 484 printk(KERN_ERR "Failed to request PCI IO region "
543 "on PCI domain %04x\n", hose->global_number); 485 "on PCI domain %04x\n", hose->global_number);
486 DBG("res->start = 0x%016lx, res->end = 0x%016lx\n",
487 res->start, res->end);
488 }
544 489
545 for (i = 0; i < 3; ++i) { 490 for (i = 0; i < 3; ++i) {
546 res = &hose->mem_resources[i]; 491 res = &hose->mem_resources[i];
@@ -598,17 +543,6 @@ static int __init pcibios_init(void)
598 if (ppc_md.pcibios_fixup) 543 if (ppc_md.pcibios_fixup)
599 ppc_md.pcibios_fixup(); 544 ppc_md.pcibios_fixup();
600 545
601 /* Cache the location of the ISA bridge (if we have one) */
602 ppc64_isabridge_dev = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, NULL);
603 if (ppc64_isabridge_dev != NULL)
604 printk(KERN_DEBUG "ISA bridge at %s\n", pci_name(ppc64_isabridge_dev));
605
606 if (!firmware_has_feature(FW_FEATURE_ISERIES))
607 /* map in PCI I/O space */
608 phbs_remap_io();
609
610 pci_initial_scan_done = 1;
611
612 printk(KERN_DEBUG "PCI: Probing PCI hardware done\n"); 546 printk(KERN_DEBUG "PCI: Probing PCI hardware done\n");
613 547
614 return 0; 548 return 0;
@@ -616,11 +550,6 @@ static int __init pcibios_init(void)
616 550
617subsys_initcall(pcibios_init); 551subsys_initcall(pcibios_init);
618 552
619char __init *pcibios_setup(char *str)
620{
621 return str;
622}
623
624int pcibios_enable_device(struct pci_dev *dev, int mask) 553int pcibios_enable_device(struct pci_dev *dev, int mask)
625{ 554{
626 u16 cmd, oldcmd; 555 u16 cmd, oldcmd;
@@ -651,22 +580,6 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
651 return 0; 580 return 0;
652} 581}
653 582
654/*
655 * Return the domain number for this bus.
656 */
657int pci_domain_nr(struct pci_bus *bus)
658{
659 if (firmware_has_feature(FW_FEATURE_ISERIES))
660 return 0;
661 else {
662 struct pci_controller *hose = pci_bus_to_host(bus);
663
664 return hose->global_number;
665 }
666}
667
668EXPORT_SYMBOL(pci_domain_nr);
669
670/* Decide whether to display the domain number in /proc */ 583/* Decide whether to display the domain number in /proc */
671int pci_proc_domain(struct pci_bus *bus) 584int pci_proc_domain(struct pci_bus *bus)
672{ 585{
@@ -678,281 +591,6 @@ int pci_proc_domain(struct pci_bus *bus)
678 } 591 }
679} 592}
680 593
681/*
682 * Platform support for /proc/bus/pci/X/Y mmap()s,
683 * modelled on the sparc64 implementation by Dave Miller.
684 * -- paulus.
685 */
686
687/*
688 * Adjust vm_pgoff of VMA such that it is the physical page offset
689 * corresponding to the 32-bit pci bus offset for DEV requested by the user.
690 *
691 * Basically, the user finds the base address for his device which he wishes
692 * to mmap. They read the 32-bit value from the config space base register,
693 * add whatever PAGE_SIZE multiple offset they wish, and feed this into the
694 * offset parameter of mmap on /proc/bus/pci/XXX for that device.
695 *
696 * Returns negative error code on failure, zero on success.
697 */
698static struct resource *__pci_mmap_make_offset(struct pci_dev *dev,
699 resource_size_t *offset,
700 enum pci_mmap_state mmap_state)
701{
702 struct pci_controller *hose = pci_bus_to_host(dev->bus);
703 unsigned long io_offset = 0;
704 int i, res_bit;
705
706 if (hose == 0)
707 return NULL; /* should never happen */
708
709 /* If memory, add on the PCI bridge address offset */
710 if (mmap_state == pci_mmap_mem) {
711#if 0 /* See comment in pci_resource_to_user() for why this is disabled */
712 *offset += hose->pci_mem_offset;
713#endif
714 res_bit = IORESOURCE_MEM;
715 } else {
716 io_offset = (unsigned long)hose->io_base_virt - pci_io_base;
717 *offset += io_offset;
718 res_bit = IORESOURCE_IO;
719 }
720
721 /*
722 * Check that the offset requested corresponds to one of the
723 * resources of the device.
724 */
725 for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
726 struct resource *rp = &dev->resource[i];
727 int flags = rp->flags;
728
729 /* treat ROM as memory (should be already) */
730 if (i == PCI_ROM_RESOURCE)
731 flags |= IORESOURCE_MEM;
732
733 /* Active and same type? */
734 if ((flags & res_bit) == 0)
735 continue;
736
737 /* In the range of this resource? */
738 if (*offset < (rp->start & PAGE_MASK) || *offset > rp->end)
739 continue;
740
741 /* found it! construct the final physical address */
742 if (mmap_state == pci_mmap_io)
743 *offset += hose->io_base_phys - io_offset;
744 return rp;
745 }
746
747 return NULL;
748}
749
750/*
751 * Set vm_page_prot of VMA, as appropriate for this architecture, for a pci
752 * device mapping.
753 */
754static pgprot_t __pci_mmap_set_pgprot(struct pci_dev *dev, struct resource *rp,
755 pgprot_t protection,
756 enum pci_mmap_state mmap_state,
757 int write_combine)
758{
759 unsigned long prot = pgprot_val(protection);
760
761 /* Write combine is always 0 on non-memory space mappings. On
762 * memory space, if the user didn't pass 1, we check for a
763 * "prefetchable" resource. This is a bit hackish, but we use
764 * this to workaround the inability of /sysfs to provide a write
765 * combine bit
766 */
767 if (mmap_state != pci_mmap_mem)
768 write_combine = 0;
769 else if (write_combine == 0) {
770 if (rp->flags & IORESOURCE_PREFETCH)
771 write_combine = 1;
772 }
773
774 /* XXX would be nice to have a way to ask for write-through */
775 prot |= _PAGE_NO_CACHE;
776 if (write_combine)
777 prot &= ~_PAGE_GUARDED;
778 else
779 prot |= _PAGE_GUARDED;
780
781 return __pgprot(prot);
782}
783
784/*
785 * This one is used by /dev/mem and fbdev who have no clue about the
786 * PCI device, it tries to find the PCI device first and calls the
787 * above routine
788 */
789pgprot_t pci_phys_mem_access_prot(struct file *file,
790 unsigned long pfn,
791 unsigned long size,
792 pgprot_t protection)
793{
794 struct pci_dev *pdev = NULL;
795 struct resource *found = NULL;
796 unsigned long prot = pgprot_val(protection);
797 unsigned long offset = pfn << PAGE_SHIFT;
798 int i;
799
800 if (page_is_ram(pfn))
801 return __pgprot(prot);
802
803 prot |= _PAGE_NO_CACHE | _PAGE_GUARDED;
804
805 for_each_pci_dev(pdev) {
806 for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
807 struct resource *rp = &pdev->resource[i];
808 int flags = rp->flags;
809
810 /* Active and same type? */
811 if ((flags & IORESOURCE_MEM) == 0)
812 continue;
813 /* In the range of this resource? */
814 if (offset < (rp->start & PAGE_MASK) ||
815 offset > rp->end)
816 continue;
817 found = rp;
818 break;
819 }
820 if (found)
821 break;
822 }
823 if (found) {
824 if (found->flags & IORESOURCE_PREFETCH)
825 prot &= ~_PAGE_GUARDED;
826 pci_dev_put(pdev);
827 }
828
829 DBG("non-PCI map for %lx, prot: %lx\n", offset, prot);
830
831 return __pgprot(prot);
832}
833
834
835/*
836 * Perform the actual remap of the pages for a PCI device mapping, as
837 * appropriate for this architecture. The region in the process to map
838 * is described by vm_start and vm_end members of VMA, the base physical
839 * address is found in vm_pgoff.
840 * The pci device structure is provided so that architectures may make mapping
841 * decisions on a per-device or per-bus basis.
842 *
843 * Returns a negative error code on failure, zero on success.
844 */
845int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
846 enum pci_mmap_state mmap_state, int write_combine)
847{
848 resource_size_t offset = vma->vm_pgoff << PAGE_SHIFT;
849 struct resource *rp;
850 int ret;
851
852 rp = __pci_mmap_make_offset(dev, &offset, mmap_state);
853 if (rp == NULL)
854 return -EINVAL;
855
856 vma->vm_pgoff = offset >> PAGE_SHIFT;
857 vma->vm_page_prot = __pci_mmap_set_pgprot(dev, rp,
858 vma->vm_page_prot,
859 mmap_state, write_combine);
860
861 ret = remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
862 vma->vm_end - vma->vm_start, vma->vm_page_prot);
863
864 return ret;
865}
866
867static ssize_t pci_show_devspec(struct device *dev,
868 struct device_attribute *attr, char *buf)
869{
870 struct pci_dev *pdev;
871 struct device_node *np;
872
873 pdev = to_pci_dev (dev);
874 np = pci_device_to_OF_node(pdev);
875 if (np == NULL || np->full_name == NULL)
876 return 0;
877 return sprintf(buf, "%s", np->full_name);
878}
879static DEVICE_ATTR(devspec, S_IRUGO, pci_show_devspec, NULL);
880
881int pcibios_add_platform_entries(struct pci_dev *pdev)
882{
883 return device_create_file(&pdev->dev, &dev_attr_devspec);
884}
885
886#define ISA_SPACE_MASK 0x1
887#define ISA_SPACE_IO 0x1
888
889static void __devinit pci_process_ISA_OF_ranges(struct device_node *isa_node,
890 unsigned long phb_io_base_phys,
891 void __iomem * phb_io_base_virt)
892{
893 /* Remove these asap */
894
895 struct pci_address {
896 u32 a_hi;
897 u32 a_mid;
898 u32 a_lo;
899 };
900
901 struct isa_address {
902 u32 a_hi;
903 u32 a_lo;
904 };
905
906 struct isa_range {
907 struct isa_address isa_addr;
908 struct pci_address pci_addr;
909 unsigned int size;
910 };
911
912 const struct isa_range *range;
913 unsigned long pci_addr;
914 unsigned int isa_addr;
915 unsigned int size;
916 int rlen = 0;
917
918 range = of_get_property(isa_node, "ranges", &rlen);
919 if (range == NULL || (rlen < sizeof(struct isa_range))) {
920 printk(KERN_ERR "no ISA ranges or unexpected isa range size,"
921 "mapping 64k\n");
922 __ioremap_explicit(phb_io_base_phys,
923 (unsigned long)phb_io_base_virt,
924 0x10000, _PAGE_NO_CACHE | _PAGE_GUARDED);
925 return;
926 }
927
928 /* From "ISA Binding to 1275"
929 * The ranges property is laid out as an array of elements,
930 * each of which comprises:
931 * cells 0 - 1: an ISA address
932 * cells 2 - 4: a PCI address
933 * (size depending on dev->n_addr_cells)
934 * cell 5: the size of the range
935 */
936 if ((range->isa_addr.a_hi && ISA_SPACE_MASK) == ISA_SPACE_IO) {
937 isa_addr = range->isa_addr.a_lo;
938 pci_addr = (unsigned long) range->pci_addr.a_mid << 32 |
939 range->pci_addr.a_lo;
940
941 /* Assume these are both zero */
942 if ((pci_addr != 0) || (isa_addr != 0)) {
943 printk(KERN_ERR "unexpected isa to pci mapping: %s\n",
944 __FUNCTION__);
945 return;
946 }
947
948 size = PAGE_ALIGN(range->size);
949
950 __ioremap_explicit(phb_io_base_phys,
951 (unsigned long) phb_io_base_virt,
952 size, _PAGE_NO_CACHE | _PAGE_GUARDED);
953 }
954}
955
956void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose, 594void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
957 struct device_node *dev, int prim) 595 struct device_node *dev, int prim)
958{ 596{
@@ -1047,155 +685,122 @@ void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
1047 } 685 }
1048} 686}
1049 687
1050void __devinit pci_setup_phb_io(struct pci_controller *hose, int primary) 688#ifdef CONFIG_HOTPLUG
689
690int pcibios_unmap_io_space(struct pci_bus *bus)
1051{ 691{
1052 unsigned long size = hose->pci_io_size; 692 struct pci_controller *hose;
1053 unsigned long io_virt_offset;
1054 struct resource *res;
1055 struct device_node *isa_dn;
1056 693
1057 if (size == 0) 694 WARN_ON(bus == NULL);
1058 return;
1059 695
1060 hose->io_base_virt = reserve_phb_iospace(size); 696 /* If this is not a PHB, we only flush the hash table over
1061 DBG("phb%d io_base_phys 0x%lx io_base_virt 0x%lx\n", 697 * the area mapped by this bridge. We don't play with the PTE
1062 hose->global_number, hose->io_base_phys, 698 * mappings since we might have to deal with sub-page alignemnts
1063 (unsigned long) hose->io_base_virt); 699 * so flushing the hash table is the only sane way to make sure
1064 700 * that no hash entries are covering that removed bridge area
1065 if (primary) { 701 * while still allowing other busses overlapping those pages
1066 pci_io_base = (unsigned long)hose->io_base_virt; 702 */
1067 isa_dn = of_find_node_by_type(NULL, "isa"); 703 if (bus->self) {
1068 if (isa_dn) { 704 struct resource *res = bus->resource[0];
1069 isa_io_base = pci_io_base;
1070 pci_process_ISA_OF_ranges(isa_dn, hose->io_base_phys,
1071 hose->io_base_virt);
1072 of_node_put(isa_dn);
1073 }
1074 }
1075 705
1076 io_virt_offset = (unsigned long)hose->io_base_virt - pci_io_base; 706 DBG("IO unmapping for PCI-PCI bridge %s\n",
1077 res = &hose->io_resource; 707 pci_name(bus->self));
1078 res->start += io_virt_offset;
1079 res->end += io_virt_offset;
1080 708
1081 /* If this is called after the initial PCI scan, then we need to 709 __flush_hash_table_range(&init_mm, res->start + _IO_BASE,
1082 * proceed to IO mappings now 710 res->end - res->start + 1);
1083 */ 711 return 0;
1084 if (pci_initial_scan_done) 712 }
1085 __ioremap_explicit(hose->io_base_phys,
1086 (unsigned long)hose->io_base_virt,
1087 hose->pci_io_size,
1088 _PAGE_NO_CACHE | _PAGE_GUARDED);
1089}
1090 713
1091void __devinit pci_setup_phb_io_dynamic(struct pci_controller *hose, 714 /* Get the host bridge */
1092 int primary) 715 hose = pci_bus_to_host(bus);
1093{
1094 unsigned long size = hose->pci_io_size;
1095 unsigned long io_virt_offset;
1096 struct resource *res;
1097 716
1098 if (size == 0) 717 /* Check if we have IOs allocated */
1099 return; 718 if (hose->io_base_alloc == 0)
719 return 0;
1100 720
1101 hose->io_base_virt = __ioremap(hose->io_base_phys, size, 721 DBG("IO unmapping for PHB %s\n",
1102 _PAGE_NO_CACHE | _PAGE_GUARDED); 722 ((struct device_node *)hose->arch_data)->full_name);
1103 DBG("phb%d io_base_phys 0x%lx io_base_virt 0x%lx\n", 723 DBG(" alloc=0x%p\n", hose->io_base_alloc);
1104 hose->global_number, hose->io_base_phys,
1105 (unsigned long) hose->io_base_virt);
1106 724
1107 if (primary) 725 /* This is a PHB, we fully unmap the IO area */
1108 pci_io_base = (unsigned long)hose->io_base_virt; 726 vunmap(hose->io_base_alloc);
1109 727
1110 io_virt_offset = (unsigned long)hose->io_base_virt - pci_io_base; 728 return 0;
1111 res = &hose->io_resource;
1112 res->start += io_virt_offset;
1113 res->end += io_virt_offset;
1114} 729}
730EXPORT_SYMBOL_GPL(pcibios_unmap_io_space);
1115 731
732#endif /* CONFIG_HOTPLUG */
1116 733
1117static int get_bus_io_range(struct pci_bus *bus, unsigned long *start_phys, 734int __devinit pcibios_map_io_space(struct pci_bus *bus)
1118 unsigned long *start_virt, unsigned long *size)
1119{ 735{
1120 struct pci_controller *hose = pci_bus_to_host(bus); 736 struct vm_struct *area;
1121 struct resource *res; 737 unsigned long phys_page;
1122 738 unsigned long size_page;
1123 if (bus->self) 739 unsigned long io_virt_offset;
1124 res = bus->resource[0]; 740 struct pci_controller *hose;
1125 else
1126 /* Root Bus */
1127 res = &hose->io_resource;
1128
1129 if (res->end == 0 && res->start == 0)
1130 return 1;
1131 741
1132 *start_virt = pci_io_base + res->start; 742 WARN_ON(bus == NULL);
1133 *start_phys = *start_virt + hose->io_base_phys
1134 - (unsigned long) hose->io_base_virt;
1135 743
1136 if (res->end > res->start) 744 /* If this not a PHB, nothing to do, page tables still exist and
1137 *size = res->end - res->start + 1; 745 * thus HPTEs will be faulted in when needed
1138 else { 746 */
1139 printk("%s(): unexpected region 0x%lx->0x%lx\n", 747 if (bus->self) {
1140 __FUNCTION__, res->start, res->end); 748 DBG("IO mapping for PCI-PCI bridge %s\n",
1141 return 1; 749 pci_name(bus->self));
750 DBG(" virt=0x%016lx...0x%016lx\n",
751 bus->resource[0]->start + _IO_BASE,
752 bus->resource[0]->end + _IO_BASE);
753 return 0;
1142 } 754 }
1143 755
1144 return 0; 756 /* Get the host bridge */
1145} 757 hose = pci_bus_to_host(bus);
1146 758 phys_page = _ALIGN_DOWN(hose->io_base_phys, PAGE_SIZE);
1147int unmap_bus_range(struct pci_bus *bus) 759 size_page = _ALIGN_UP(hose->pci_io_size, PAGE_SIZE);
1148{
1149 unsigned long start_phys;
1150 unsigned long start_virt;
1151 unsigned long size;
1152 760
1153 if (!bus) { 761 /* Make sure IO area address is clear */
1154 printk(KERN_ERR "%s() expected bus\n", __FUNCTION__); 762 hose->io_base_alloc = NULL;
1155 return 1;
1156 }
1157
1158 if (get_bus_io_range(bus, &start_phys, &start_virt, &size))
1159 return 1;
1160 if (__iounmap_explicit((void __iomem *) start_virt, size))
1161 return 1;
1162
1163 return 0;
1164}
1165EXPORT_SYMBOL(unmap_bus_range);
1166 763
1167int remap_bus_range(struct pci_bus *bus) 764 /* If there's no IO to map on that bus, get away too */
1168{ 765 if (hose->pci_io_size == 0 || hose->io_base_phys == 0)
1169 unsigned long start_phys; 766 return 0;
1170 unsigned long start_virt;
1171 unsigned long size;
1172 767
1173 if (!bus) { 768 /* Let's allocate some IO space for that guy. We don't pass
1174 printk(KERN_ERR "%s() expected bus\n", __FUNCTION__); 769 * VM_IOREMAP because we don't care about alignment tricks that
1175 return 1; 770 * the core does in that case. Maybe we should due to stupid card
1176 } 771 * with incomplete address decoding but I'd rather not deal with
1177 772 * those outside of the reserved 64K legacy region.
1178 773 */
1179 if (get_bus_io_range(bus, &start_phys, &start_virt, &size)) 774 area = __get_vm_area(size_page, 0, PHB_IO_BASE, PHB_IO_END);
1180 return 1; 775 if (area == NULL)
1181 if (start_phys == 0) 776 return -ENOMEM;
1182 return 1; 777 hose->io_base_alloc = area->addr;
1183 printk(KERN_DEBUG "mapping IO %lx -> %lx, size: %lx\n", start_phys, start_virt, size); 778 hose->io_base_virt = (void __iomem *)(area->addr +
1184 if (__ioremap_explicit(start_phys, start_virt, size, 779 hose->io_base_phys - phys_page);
1185 _PAGE_NO_CACHE | _PAGE_GUARDED)) 780
1186 return 1; 781 DBG("IO mapping for PHB %s\n",
782 ((struct device_node *)hose->arch_data)->full_name);
783 DBG(" phys=0x%016lx, virt=0x%p (alloc=0x%p)\n",
784 hose->io_base_phys, hose->io_base_virt, hose->io_base_alloc);
785 DBG(" size=0x%016lx (alloc=0x%016lx)\n",
786 hose->pci_io_size, size_page);
787
788 /* Establish the mapping */
789 if (__ioremap_at(phys_page, area->addr, size_page,
790 _PAGE_NO_CACHE | _PAGE_GUARDED) == NULL)
791 return -ENOMEM;
792
793 /* Fixup hose IO resource */
794 io_virt_offset = (unsigned long)hose->io_base_virt - _IO_BASE;
795 hose->io_resource.start += io_virt_offset;
796 hose->io_resource.end += io_virt_offset;
797
798 DBG(" hose->io_resource=0x%016lx...0x%016lx\n",
799 hose->io_resource.start, hose->io_resource.end);
1187 800
1188 return 0; 801 return 0;
1189} 802}
1190EXPORT_SYMBOL(remap_bus_range); 803EXPORT_SYMBOL_GPL(pcibios_map_io_space);
1191
1192static void phbs_remap_io(void)
1193{
1194 struct pci_controller *hose, *tmp;
1195
1196 list_for_each_entry_safe(hose, tmp, &hose_list, list_node)
1197 remap_bus_range(hose->bus);
1198}
1199 804
1200static void __devinit fixup_resource(struct resource *res, struct pci_dev *dev) 805static void __devinit fixup_resource(struct resource *res, struct pci_dev *dev)
1201{ 806{
@@ -1203,8 +808,7 @@ static void __devinit fixup_resource(struct resource *res, struct pci_dev *dev)
1203 unsigned long offset; 808 unsigned long offset;
1204 809
1205 if (res->flags & IORESOURCE_IO) { 810 if (res->flags & IORESOURCE_IO) {
1206 offset = (unsigned long)hose->io_base_virt - pci_io_base; 811 offset = (unsigned long)hose->io_base_virt - _IO_BASE;
1207
1208 res->start += offset; 812 res->start += offset;
1209 res->end += offset; 813 res->end += offset;
1210 } else if (res->flags & IORESOURCE_MEM) { 814 } else if (res->flags & IORESOURCE_MEM) {
@@ -1219,9 +823,20 @@ void __devinit pcibios_fixup_device_resources(struct pci_dev *dev,
1219 /* Update device resources. */ 823 /* Update device resources. */
1220 int i; 824 int i;
1221 825
1222 for (i = 0; i < PCI_NUM_RESOURCES; i++) 826 DBG("%s: Fixup resources:\n", pci_name(dev));
1223 if (dev->resource[i].flags) 827 for (i = 0; i < PCI_NUM_RESOURCES; i++) {
1224 fixup_resource(&dev->resource[i], dev); 828 struct resource *res = &dev->resource[i];
829 if (!res->flags)
830 continue;
831
832 DBG(" 0x%02x < %08lx:0x%016lx...0x%016lx\n",
833 i, res->flags, res->start, res->end);
834
835 fixup_resource(res, dev);
836
837 DBG(" > %08lx:0x%016lx...0x%016lx\n",
838 res->flags, res->start, res->end);
839 }
1225} 840}
1226EXPORT_SYMBOL(pcibios_fixup_device_resources); 841EXPORT_SYMBOL(pcibios_fixup_device_resources);
1227 842
@@ -1291,119 +906,6 @@ void __devinit pcibios_fixup_bus(struct pci_bus *bus)
1291} 906}
1292EXPORT_SYMBOL(pcibios_fixup_bus); 907EXPORT_SYMBOL(pcibios_fixup_bus);
1293 908
1294/*
1295 * Reads the interrupt pin to determine if interrupt is use by card.
1296 * If the interrupt is used, then gets the interrupt line from the
1297 * openfirmware and sets it in the pci_dev and pci_config line.
1298 */
1299int pci_read_irq_line(struct pci_dev *pci_dev)
1300{
1301 struct of_irq oirq;
1302 unsigned int virq;
1303
1304 DBG("Try to map irq for %s...\n", pci_name(pci_dev));
1305
1306#ifdef DEBUG
1307 memset(&oirq, 0xff, sizeof(oirq));
1308#endif
1309 /* Try to get a mapping from the device-tree */
1310 if (of_irq_map_pci(pci_dev, &oirq)) {
1311 u8 line, pin;
1312
1313 /* If that fails, lets fallback to what is in the config
1314 * space and map that through the default controller. We
1315 * also set the type to level low since that's what PCI
1316 * interrupts are. If your platform does differently, then
1317 * either provide a proper interrupt tree or don't use this
1318 * function.
1319 */
1320 if (pci_read_config_byte(pci_dev, PCI_INTERRUPT_PIN, &pin))
1321 return -1;
1322 if (pin == 0)
1323 return -1;
1324 if (pci_read_config_byte(pci_dev, PCI_INTERRUPT_LINE, &line) ||
1325 line == 0xff) {
1326 return -1;
1327 }
1328 DBG(" -> no map ! Using irq line %d from PCI config\n", line);
1329
1330 virq = irq_create_mapping(NULL, line);
1331 if (virq != NO_IRQ)
1332 set_irq_type(virq, IRQ_TYPE_LEVEL_LOW);
1333 } else {
1334 DBG(" -> got one, spec %d cells (0x%08x 0x%08x...) on %s\n",
1335 oirq.size, oirq.specifier[0], oirq.specifier[1],
1336 oirq.controller->full_name);
1337
1338 virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
1339 oirq.size);
1340 }
1341 if(virq == NO_IRQ) {
1342 DBG(" -> failed to map !\n");
1343 return -1;
1344 }
1345
1346 DBG(" -> mapped to linux irq %d\n", virq);
1347
1348 pci_dev->irq = virq;
1349
1350 return 0;
1351}
1352EXPORT_SYMBOL(pci_read_irq_line);
1353
1354void pci_resource_to_user(const struct pci_dev *dev, int bar,
1355 const struct resource *rsrc,
1356 resource_size_t *start, resource_size_t *end)
1357{
1358 struct pci_controller *hose = pci_bus_to_host(dev->bus);
1359 resource_size_t offset = 0;
1360
1361 if (hose == NULL)
1362 return;
1363
1364 if (rsrc->flags & IORESOURCE_IO)
1365 offset = (unsigned long)hose->io_base_virt - pci_io_base;
1366
1367 /* We pass a fully fixed up address to userland for MMIO instead of
1368 * a BAR value because X is lame and expects to be able to use that
1369 * to pass to /dev/mem !
1370 *
1371 * That means that we'll have potentially 64 bits values where some
1372 * userland apps only expect 32 (like X itself since it thinks only
1373 * Sparc has 64 bits MMIO) but if we don't do that, we break it on
1374 * 32 bits CHRPs :-(
1375 *
1376 * Hopefully, the sysfs insterface is immune to that gunk. Once X
1377 * has been fixed (and the fix spread enough), we can re-enable the
1378 * 2 lines below and pass down a BAR value to userland. In that case
1379 * we'll also have to re-enable the matching code in
1380 * __pci_mmap_make_offset().
1381 *
1382 * BenH.
1383 */
1384#if 0
1385 else if (rsrc->flags & IORESOURCE_MEM)
1386 offset = hose->pci_mem_offset;
1387#endif
1388
1389 *start = rsrc->start - offset;
1390 *end = rsrc->end - offset;
1391}
1392
1393struct pci_controller* pci_find_hose_for_OF_device(struct device_node* node)
1394{
1395 if (!have_of)
1396 return NULL;
1397 while(node) {
1398 struct pci_controller *hose, *tmp;
1399 list_for_each_entry_safe(hose, tmp, &hose_list, list_node)
1400 if (hose->arch_data == node)
1401 return hose;
1402 node = node->parent;
1403 }
1404 return NULL;
1405}
1406
1407unsigned long pci_address_to_pio(phys_addr_t address) 909unsigned long pci_address_to_pio(phys_addr_t address)
1408{ 910{
1409 struct pci_controller *hose, *tmp; 911 struct pci_controller *hose, *tmp;
@@ -1412,7 +914,7 @@ unsigned long pci_address_to_pio(phys_addr_t address)
1412 if (address >= hose->io_base_phys && 914 if (address >= hose->io_base_phys &&
1413 address < (hose->io_base_phys + hose->pci_io_size)) { 915 address < (hose->io_base_phys + hose->pci_io_size)) {
1414 unsigned long base = 916 unsigned long base =
1415 (unsigned long)hose->io_base_virt - pci_io_base; 917 (unsigned long)hose->io_base_virt - _IO_BASE;
1416 return base + (address - hose->io_base_phys); 918 return base + (address - hose->io_base_phys);
1417 } 919 }
1418 } 920 }
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c
index c96fa9bd35a4..a20f1951a5ce 100644
--- a/arch/powerpc/kernel/ppc_ksyms.c
+++ b/arch/powerpc/kernel/ppc_ksyms.c
@@ -67,7 +67,6 @@ EXPORT_SYMBOL(ISA_DMA_THRESHOLD);
67EXPORT_SYMBOL(DMA_MODE_READ); 67EXPORT_SYMBOL(DMA_MODE_READ);
68EXPORT_SYMBOL(DMA_MODE_WRITE); 68EXPORT_SYMBOL(DMA_MODE_WRITE);
69 69
70EXPORT_SYMBOL(do_signal);
71EXPORT_SYMBOL(transfer_to_handler); 70EXPORT_SYMBOL(transfer_to_handler);
72EXPORT_SYMBOL(do_IRQ); 71EXPORT_SYMBOL(do_IRQ);
73EXPORT_SYMBOL(machine_check_exception); 72EXPORT_SYMBOL(machine_check_exception);
@@ -106,10 +105,6 @@ EXPORT_SYMBOL(isa_mem_base);
106EXPORT_SYMBOL(pci_dram_offset); 105EXPORT_SYMBOL(pci_dram_offset);
107EXPORT_SYMBOL(pci_alloc_consistent); 106EXPORT_SYMBOL(pci_alloc_consistent);
108EXPORT_SYMBOL(pci_free_consistent); 107EXPORT_SYMBOL(pci_free_consistent);
109EXPORT_SYMBOL(pci_bus_io_base);
110EXPORT_SYMBOL(pci_bus_io_base_phys);
111EXPORT_SYMBOL(pci_bus_mem_base_phys);
112EXPORT_SYMBOL(pci_bus_to_hose);
113#endif /* CONFIG_PCI */ 108#endif /* CONFIG_PCI */
114 109
115EXPORT_SYMBOL(start_thread); 110EXPORT_SYMBOL(start_thread);
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 6e2f03566b0d..84f000a45e36 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -219,22 +219,26 @@ void discard_lazy_cpu_state(void)
219} 219}
220#endif /* CONFIG_SMP */ 220#endif /* CONFIG_SMP */
221 221
222#ifdef CONFIG_PPC_MERGE /* XXX for now */
223int set_dabr(unsigned long dabr) 222int set_dabr(unsigned long dabr)
224{ 223{
224#ifdef CONFIG_PPC_MERGE /* XXX for now */
225 if (ppc_md.set_dabr) 225 if (ppc_md.set_dabr)
226 return ppc_md.set_dabr(dabr); 226 return ppc_md.set_dabr(dabr);
227#endif
227 228
229 /* XXX should we have a CPU_FTR_HAS_DABR ? */
230#if defined(CONFIG_PPC64) || defined(CONFIG_6xx)
228 mtspr(SPRN_DABR, dabr); 231 mtspr(SPRN_DABR, dabr);
232#endif
229 return 0; 233 return 0;
230} 234}
231#endif
232 235
233#ifdef CONFIG_PPC64 236#ifdef CONFIG_PPC64
234DEFINE_PER_CPU(struct cpu_usage, cpu_usage_array); 237DEFINE_PER_CPU(struct cpu_usage, cpu_usage_array);
235static DEFINE_PER_CPU(unsigned long, current_dabr);
236#endif 238#endif
237 239
240static DEFINE_PER_CPU(unsigned long, current_dabr);
241
238struct task_struct *__switch_to(struct task_struct *prev, 242struct task_struct *__switch_to(struct task_struct *prev,
239 struct task_struct *new) 243 struct task_struct *new)
240{ 244{
@@ -299,12 +303,10 @@ struct task_struct *__switch_to(struct task_struct *prev,
299 303
300#endif /* CONFIG_SMP */ 304#endif /* CONFIG_SMP */
301 305
302#ifdef CONFIG_PPC64 /* for now */
303 if (unlikely(__get_cpu_var(current_dabr) != new->thread.dabr)) { 306 if (unlikely(__get_cpu_var(current_dabr) != new->thread.dabr)) {
304 set_dabr(new->thread.dabr); 307 set_dabr(new->thread.dabr);
305 __get_cpu_var(current_dabr) = new->thread.dabr; 308 __get_cpu_var(current_dabr) = new->thread.dabr;
306 } 309 }
307#endif /* CONFIG_PPC64 */
308 310
309 new_thread = &new->thread; 311 new_thread = &new->thread;
310 old_thread = &current->thread; 312 old_thread = &current->thread;
@@ -473,12 +475,10 @@ void flush_thread(void)
473 475
474 discard_lazy_cpu_state(); 476 discard_lazy_cpu_state();
475 477
476#ifdef CONFIG_PPC64 /* for now */
477 if (current->thread.dabr) { 478 if (current->thread.dabr) {
478 current->thread.dabr = 0; 479 current->thread.dabr = 0;
479 set_dabr(0); 480 set_dabr(0);
480 } 481 }
481#endif
482} 482}
483 483
484void 484void
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index af42ddab3ab4..37ff99bd98b4 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -52,6 +52,7 @@
52#include <asm/pSeries_reconfig.h> 52#include <asm/pSeries_reconfig.h>
53#include <asm/pci-bridge.h> 53#include <asm/pci-bridge.h>
54#include <asm/kexec.h> 54#include <asm/kexec.h>
55#include <asm/system.h>
55 56
56#ifdef DEBUG 57#ifdef DEBUG
57#define DBG(fmt...) printk(KERN_ERR fmt) 58#define DBG(fmt...) printk(KERN_ERR fmt)
@@ -1005,7 +1006,7 @@ static void __init early_reserve_mem(void)
1005 1006
1006void __init early_init_devtree(void *params) 1007void __init early_init_devtree(void *params)
1007{ 1008{
1008 DBG(" -> early_init_devtree()\n"); 1009 DBG(" -> early_init_devtree(%p)\n", params);
1009 1010
1010 /* Setup flat device-tree pointer */ 1011 /* Setup flat device-tree pointer */
1011 initial_boot_params = params; 1012 initial_boot_params = params;
@@ -1055,8 +1056,6 @@ void __init early_init_devtree(void *params)
1055 DBG(" <- early_init_devtree()\n"); 1056 DBG(" <- early_init_devtree()\n");
1056} 1057}
1057 1058
1058#undef printk
1059
1060int of_n_addr_cells(struct device_node* np) 1059int of_n_addr_cells(struct device_node* np)
1061{ 1060{
1062 const int *ip; 1061 const int *ip;
@@ -1375,8 +1374,17 @@ static void of_node_release(struct kref *kref)
1375 struct device_node *node = kref_to_device_node(kref); 1374 struct device_node *node = kref_to_device_node(kref);
1376 struct property *prop = node->properties; 1375 struct property *prop = node->properties;
1377 1376
1378 if (!OF_IS_DYNAMIC(node)) 1377 /* We should never be releasing nodes that haven't been detached. */
1378 if (!of_node_check_flag(node, OF_DETACHED)) {
1379 printk("WARNING: Bad of_node_put() on %s\n", node->full_name);
1380 dump_stack();
1381 kref_init(&node->kref);
1382 return;
1383 }
1384
1385 if (!of_node_check_flag(node, OF_DYNAMIC))
1379 return; 1386 return;
1387
1380 while (prop) { 1388 while (prop) {
1381 struct property *next = prop->next; 1389 struct property *next = prop->next;
1382 kfree(prop->name); 1390 kfree(prop->name);
@@ -1432,6 +1440,8 @@ void of_detach_node(const struct device_node *np)
1432 write_lock(&devtree_lock); 1440 write_lock(&devtree_lock);
1433 1441
1434 parent = np->parent; 1442 parent = np->parent;
1443 if (!parent)
1444 goto out_unlock;
1435 1445
1436 if (allnodes == np) 1446 if (allnodes == np)
1437 allnodes = np->allnext; 1447 allnodes = np->allnext;
@@ -1455,6 +1465,9 @@ void of_detach_node(const struct device_node *np)
1455 prevsib->sibling = np->sibling; 1465 prevsib->sibling = np->sibling;
1456 } 1466 }
1457 1467
1468 of_node_set_flag(np, OF_DETACHED);
1469
1470out_unlock:
1458 write_unlock(&devtree_lock); 1471 write_unlock(&devtree_lock);
1459} 1472}
1460 1473
@@ -1716,22 +1729,18 @@ struct device_node *of_get_cpu_node(int cpu, unsigned int *thread)
1716} 1729}
1717EXPORT_SYMBOL(of_get_cpu_node); 1730EXPORT_SYMBOL(of_get_cpu_node);
1718 1731
1719#ifdef DEBUG 1732#if defined(CONFIG_DEBUG_FS) && defined(DEBUG)
1720static struct debugfs_blob_wrapper flat_dt_blob; 1733static struct debugfs_blob_wrapper flat_dt_blob;
1721 1734
1722static int __init export_flat_device_tree(void) 1735static int __init export_flat_device_tree(void)
1723{ 1736{
1724 struct dentry *d; 1737 struct dentry *d;
1725 1738
1726 d = debugfs_create_dir("powerpc", NULL);
1727 if (!d)
1728 return 1;
1729
1730 flat_dt_blob.data = initial_boot_params; 1739 flat_dt_blob.data = initial_boot_params;
1731 flat_dt_blob.size = initial_boot_params->totalsize; 1740 flat_dt_blob.size = initial_boot_params->totalsize;
1732 1741
1733 d = debugfs_create_blob("flat-device-tree", S_IFREG | S_IRUSR, 1742 d = debugfs_create_blob("flat-device-tree", S_IFREG | S_IRUSR,
1734 d, &flat_dt_blob); 1743 powerpc_debugfs_root, &flat_dt_blob);
1735 if (!d) 1744 if (!d)
1736 return 1; 1745 return 1;
1737 1746
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index d6047c441034..a1d582e38627 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -635,6 +635,7 @@ static void __init early_cmdline_parse(void)
635/* ibm,dynamic-reconfiguration-memory property supported */ 635/* ibm,dynamic-reconfiguration-memory property supported */
636#define OV5_DRCONF_MEMORY 0x20 636#define OV5_DRCONF_MEMORY 0x20
637#define OV5_LARGE_PAGES 0x10 /* large pages supported */ 637#define OV5_LARGE_PAGES 0x10 /* large pages supported */
638#define OV5_DONATE_DEDICATE_CPU 0x02 /* donate dedicated CPU support */
638/* PCIe/MSI support. Without MSI full PCIe is not supported */ 639/* PCIe/MSI support. Without MSI full PCIe is not supported */
639#ifdef CONFIG_PCI_MSI 640#ifdef CONFIG_PCI_MSI
640#define OV5_MSI 0x01 /* PCIe/MSI support */ 641#define OV5_MSI 0x01 /* PCIe/MSI support */
@@ -685,7 +686,8 @@ static unsigned char ibm_architecture_vec[] = {
685 /* option vector 5: PAPR/OF options */ 686 /* option vector 5: PAPR/OF options */
686 3 - 2, /* length */ 687 3 - 2, /* length */
687 0, /* don't ignore, don't halt */ 688 0, /* don't ignore, don't halt */
688 OV5_LPAR | OV5_SPLPAR | OV5_LARGE_PAGES | OV5_DRCONF_MEMORY | OV5_MSI, 689 OV5_LPAR | OV5_SPLPAR | OV5_LARGE_PAGES | OV5_DRCONF_MEMORY |
690 OV5_DONATE_DEDICATE_CPU | OV5_MSI,
689}; 691};
690 692
691/* Old method - ELF header with PT_NOTE sections */ 693/* Old method - ELF header with PT_NOTE sections */
diff --git a/arch/powerpc/kernel/ptrace-common.h b/arch/powerpc/kernel/ptrace-common.h
deleted file mode 100644
index 8797ae737a7b..000000000000
--- a/arch/powerpc/kernel/ptrace-common.h
+++ /dev/null
@@ -1,161 +0,0 @@
1/*
2 * Copyright (c) 2002 Stephen Rothwell, IBM Coproration
3 * Extracted from ptrace.c and ptrace32.c
4 *
5 * This file is subject to the terms and conditions of the GNU General
6 * Public License. See the file README.legal in the main directory of
7 * this archive for more details.
8 */
9
10#ifndef _PPC64_PTRACE_COMMON_H
11#define _PPC64_PTRACE_COMMON_H
12
13#include <asm/system.h>
14
15/*
16 * Set of msr bits that gdb can change on behalf of a process.
17 */
18#define MSR_DEBUGCHANGE (MSR_FE0 | MSR_SE | MSR_BE | MSR_FE1)
19
20/*
21 * Get contents of register REGNO in task TASK.
22 */
23static inline unsigned long get_reg(struct task_struct *task, int regno)
24{
25 unsigned long tmp = 0;
26
27 /*
28 * Put the correct FP bits in, they might be wrong as a result
29 * of our lazy FP restore.
30 */
31 if (regno == PT_MSR) {
32 tmp = ((unsigned long *)task->thread.regs)[PT_MSR];
33 tmp |= task->thread.fpexc_mode;
34 } else if (regno < (sizeof(struct pt_regs) / sizeof(unsigned long))) {
35 tmp = ((unsigned long *)task->thread.regs)[regno];
36 }
37
38 return tmp;
39}
40
41/*
42 * Write contents of register REGNO in task TASK.
43 */
44static inline int put_reg(struct task_struct *task, int regno,
45 unsigned long data)
46{
47 if (regno < PT_SOFTE) {
48 if (regno == PT_MSR)
49 data = (data & MSR_DEBUGCHANGE)
50 | (task->thread.regs->msr & ~MSR_DEBUGCHANGE);
51 ((unsigned long *)task->thread.regs)[regno] = data;
52 return 0;
53 }
54 return -EIO;
55}
56
57static inline void set_single_step(struct task_struct *task)
58{
59 struct pt_regs *regs = task->thread.regs;
60 if (regs != NULL)
61 regs->msr |= MSR_SE;
62 set_tsk_thread_flag(task, TIF_SINGLESTEP);
63}
64
65static inline void clear_single_step(struct task_struct *task)
66{
67 struct pt_regs *regs = task->thread.regs;
68 if (regs != NULL)
69 regs->msr &= ~MSR_SE;
70 clear_tsk_thread_flag(task, TIF_SINGLESTEP);
71}
72
73#ifdef CONFIG_ALTIVEC
74/*
75 * Get/set all the altivec registers vr0..vr31, vscr, vrsave, in one go.
76 * The transfer totals 34 quadword. Quadwords 0-31 contain the
77 * corresponding vector registers. Quadword 32 contains the vscr as the
78 * last word (offset 12) within that quadword. Quadword 33 contains the
79 * vrsave as the first word (offset 0) within the quadword.
80 *
81 * This definition of the VMX state is compatible with the current PPC32
82 * ptrace interface. This allows signal handling and ptrace to use the
83 * same structures. This also simplifies the implementation of a bi-arch
84 * (combined (32- and 64-bit) gdb.
85 */
86
87/*
88 * Get contents of AltiVec register state in task TASK
89 */
90static inline int get_vrregs(unsigned long __user *data,
91 struct task_struct *task)
92{
93 unsigned long regsize;
94
95 /* copy AltiVec registers VR[0] .. VR[31] */
96 regsize = 32 * sizeof(vector128);
97 if (copy_to_user(data, task->thread.vr, regsize))
98 return -EFAULT;
99 data += (regsize / sizeof(unsigned long));
100
101 /* copy VSCR */
102 regsize = 1 * sizeof(vector128);
103 if (copy_to_user(data, &task->thread.vscr, regsize))
104 return -EFAULT;
105 data += (regsize / sizeof(unsigned long));
106
107 /* copy VRSAVE */
108 if (put_user(task->thread.vrsave, (u32 __user *)data))
109 return -EFAULT;
110
111 return 0;
112}
113
114/*
115 * Write contents of AltiVec register state into task TASK.
116 */
117static inline int set_vrregs(struct task_struct *task,
118 unsigned long __user *data)
119{
120 unsigned long regsize;
121
122 /* copy AltiVec registers VR[0] .. VR[31] */
123 regsize = 32 * sizeof(vector128);
124 if (copy_from_user(task->thread.vr, data, regsize))
125 return -EFAULT;
126 data += (regsize / sizeof(unsigned long));
127
128 /* copy VSCR */
129 regsize = 1 * sizeof(vector128);
130 if (copy_from_user(&task->thread.vscr, data, regsize))
131 return -EFAULT;
132 data += (regsize / sizeof(unsigned long));
133
134 /* copy VRSAVE */
135 if (get_user(task->thread.vrsave, (u32 __user *)data))
136 return -EFAULT;
137
138 return 0;
139}
140#endif
141
142static inline int ptrace_set_debugreg(struct task_struct *task,
143 unsigned long addr, unsigned long data)
144{
145 /* We only support one DABR and no IABRS at the moment */
146 if (addr > 0)
147 return -EINVAL;
148
149 /* The bottom 3 bits are flags */
150 if ((data & ~0x7UL) >= TASK_SIZE)
151 return -EIO;
152
153 /* Ensure translation is on */
154 if (data && !(data & DABR_TRANSLATION))
155 return -EIO;
156
157 task->thread.dabr = data;
158 return 0;
159}
160
161#endif /* _PPC64_PTRACE_COMMON_H */
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index bf76562167c3..0fb53950da43 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -35,11 +35,11 @@
35#include <asm/pgtable.h> 35#include <asm/pgtable.h>
36#include <asm/system.h> 36#include <asm/system.h>
37 37
38#ifdef CONFIG_PPC64 38/*
39#include "ptrace-common.h" 39 * does not yet catch signals sent when the child dies.
40#endif 40 * in exit.c or in signal.c.
41 */
41 42
42#ifdef CONFIG_PPC32
43/* 43/*
44 * Set of msr bits that gdb can change on behalf of a process. 44 * Set of msr bits that gdb can change on behalf of a process.
45 */ 45 */
@@ -48,65 +48,117 @@
48#else 48#else
49#define MSR_DEBUGCHANGE (MSR_SE | MSR_BE) 49#define MSR_DEBUGCHANGE (MSR_SE | MSR_BE)
50#endif 50#endif
51#endif /* CONFIG_PPC32 */
52 51
53/* 52/*
54 * does not yet catch signals sent when the child dies. 53 * Max register writeable via put_reg
55 * in exit.c or in signal.c.
56 */ 54 */
57
58#ifdef CONFIG_PPC32 55#ifdef CONFIG_PPC32
56#define PT_MAX_PUT_REG PT_MQ
57#else
58#define PT_MAX_PUT_REG PT_CCR
59#endif
60
59/* 61/*
60 * Get contents of register REGNO in task TASK. 62 * Get contents of register REGNO in task TASK.
61 */ 63 */
62static inline unsigned long get_reg(struct task_struct *task, int regno) 64unsigned long ptrace_get_reg(struct task_struct *task, int regno)
63{ 65{
64 if (regno < sizeof(struct pt_regs) / sizeof(unsigned long) 66 unsigned long tmp = 0;
65 && task->thread.regs != NULL) 67
68 if (task->thread.regs == NULL)
69 return -EIO;
70
71 if (regno == PT_MSR) {
72 tmp = ((unsigned long *)task->thread.regs)[PT_MSR];
73 return tmp | task->thread.fpexc_mode;
74 }
75
76 if (regno < (sizeof(struct pt_regs) / sizeof(unsigned long)))
66 return ((unsigned long *)task->thread.regs)[regno]; 77 return ((unsigned long *)task->thread.regs)[regno];
67 return (0); 78
79 return -EIO;
68} 80}
69 81
70/* 82/*
71 * Write contents of register REGNO in task TASK. 83 * Write contents of register REGNO in task TASK.
72 */ 84 */
73static inline int put_reg(struct task_struct *task, int regno, 85int ptrace_put_reg(struct task_struct *task, int regno, unsigned long data)
74 unsigned long data)
75{ 86{
76 if (regno <= PT_MQ && task->thread.regs != NULL) { 87 if (task->thread.regs == NULL)
88 return -EIO;
89
90 if (regno <= PT_MAX_PUT_REG || regno == PT_TRAP) {
77 if (regno == PT_MSR) 91 if (regno == PT_MSR)
78 data = (data & MSR_DEBUGCHANGE) 92 data = (data & MSR_DEBUGCHANGE)
79 | (task->thread.regs->msr & ~MSR_DEBUGCHANGE); 93 | (task->thread.regs->msr & ~MSR_DEBUGCHANGE);
94 /* We prevent mucking around with the reserved area of trap
95 * which are used internally by the kernel
96 */
97 if (regno == PT_TRAP)
98 data &= 0xfff0;
80 ((unsigned long *)task->thread.regs)[regno] = data; 99 ((unsigned long *)task->thread.regs)[regno] = data;
81 return 0; 100 return 0;
82 } 101 }
83 return -EIO; 102 return -EIO;
84} 103}
85 104
105
106static int get_fpregs(void __user *data, struct task_struct *task,
107 int has_fpscr)
108{
109 unsigned int count = has_fpscr ? 33 : 32;
110
111 if (copy_to_user(data, task->thread.fpr, count * sizeof(double)))
112 return -EFAULT;
113 return 0;
114}
115
116static int set_fpregs(void __user *data, struct task_struct *task,
117 int has_fpscr)
118{
119 unsigned int count = has_fpscr ? 33 : 32;
120
121 if (copy_from_user(task->thread.fpr, data, count * sizeof(double)))
122 return -EFAULT;
123 return 0;
124}
125
126
86#ifdef CONFIG_ALTIVEC 127#ifdef CONFIG_ALTIVEC
87/* 128/*
129 * Get/set all the altivec registers vr0..vr31, vscr, vrsave, in one go.
130 * The transfer totals 34 quadword. Quadwords 0-31 contain the
131 * corresponding vector registers. Quadword 32 contains the vscr as the
132 * last word (offset 12) within that quadword. Quadword 33 contains the
133 * vrsave as the first word (offset 0) within the quadword.
134 *
135 * This definition of the VMX state is compatible with the current PPC32
136 * ptrace interface. This allows signal handling and ptrace to use the
137 * same structures. This also simplifies the implementation of a bi-arch
138 * (combined (32- and 64-bit) gdb.
139 */
140
141/*
88 * Get contents of AltiVec register state in task TASK 142 * Get contents of AltiVec register state in task TASK
89 */ 143 */
90static inline int get_vrregs(unsigned long __user *data, struct task_struct *task) 144static int get_vrregs(unsigned long __user *data, struct task_struct *task)
91{ 145{
92 int i, j; 146 unsigned long regsize;
93
94 if (!access_ok(VERIFY_WRITE, data, 133 * sizeof(unsigned long)))
95 return -EFAULT;
96 147
97 /* copy AltiVec registers VR[0] .. VR[31] */ 148 /* copy AltiVec registers VR[0] .. VR[31] */
98 for (i = 0; i < 32; i++) 149 regsize = 32 * sizeof(vector128);
99 for (j = 0; j < 4; j++, data++) 150 if (copy_to_user(data, task->thread.vr, regsize))
100 if (__put_user(task->thread.vr[i].u[j], data)) 151 return -EFAULT;
101 return -EFAULT; 152 data += (regsize / sizeof(unsigned long));
102 153
103 /* copy VSCR */ 154 /* copy VSCR */
104 for (i = 0; i < 4; i++, data++) 155 regsize = 1 * sizeof(vector128);
105 if (__put_user(task->thread.vscr.u[i], data)) 156 if (copy_to_user(data, &task->thread.vscr, regsize))
106 return -EFAULT; 157 return -EFAULT;
158 data += (regsize / sizeof(unsigned long));
107 159
108 /* copy VRSAVE */ 160 /* copy VRSAVE */
109 if (__put_user(task->thread.vrsave, data)) 161 if (put_user(task->thread.vrsave, (u32 __user *)data))
110 return -EFAULT; 162 return -EFAULT;
111 163
112 return 0; 164 return 0;
@@ -115,31 +167,29 @@ static inline int get_vrregs(unsigned long __user *data, struct task_struct *tas
115/* 167/*
116 * Write contents of AltiVec register state into task TASK. 168 * Write contents of AltiVec register state into task TASK.
117 */ 169 */
118static inline int set_vrregs(struct task_struct *task, unsigned long __user *data) 170static int set_vrregs(struct task_struct *task, unsigned long __user *data)
119{ 171{
120 int i, j; 172 unsigned long regsize;
121
122 if (!access_ok(VERIFY_READ, data, 133 * sizeof(unsigned long)))
123 return -EFAULT;
124 173
125 /* copy AltiVec registers VR[0] .. VR[31] */ 174 /* copy AltiVec registers VR[0] .. VR[31] */
126 for (i = 0; i < 32; i++) 175 regsize = 32 * sizeof(vector128);
127 for (j = 0; j < 4; j++, data++) 176 if (copy_from_user(task->thread.vr, data, regsize))
128 if (__get_user(task->thread.vr[i].u[j], data)) 177 return -EFAULT;
129 return -EFAULT; 178 data += (regsize / sizeof(unsigned long));
130 179
131 /* copy VSCR */ 180 /* copy VSCR */
132 for (i = 0; i < 4; i++, data++) 181 regsize = 1 * sizeof(vector128);
133 if (__get_user(task->thread.vscr.u[i], data)) 182 if (copy_from_user(&task->thread.vscr, data, regsize))
134 return -EFAULT; 183 return -EFAULT;
184 data += (regsize / sizeof(unsigned long));
135 185
136 /* copy VRSAVE */ 186 /* copy VRSAVE */
137 if (__get_user(task->thread.vrsave, data)) 187 if (get_user(task->thread.vrsave, (u32 __user *)data))
138 return -EFAULT; 188 return -EFAULT;
139 189
140 return 0; 190 return 0;
141} 191}
142#endif 192#endif /* CONFIG_ALTIVEC */
143 193
144#ifdef CONFIG_SPE 194#ifdef CONFIG_SPE
145 195
@@ -156,7 +206,7 @@ static inline int set_vrregs(struct task_struct *task, unsigned long __user *dat
156/* 206/*
157 * Get contents of SPE register state in task TASK. 207 * Get contents of SPE register state in task TASK.
158 */ 208 */
159static inline int get_evrregs(unsigned long *data, struct task_struct *task) 209static int get_evrregs(unsigned long *data, struct task_struct *task)
160{ 210{
161 int i; 211 int i;
162 212
@@ -182,7 +232,7 @@ static inline int get_evrregs(unsigned long *data, struct task_struct *task)
182/* 232/*
183 * Write contents of SPE register state into task TASK. 233 * Write contents of SPE register state into task TASK.
184 */ 234 */
185static inline int set_evrregs(struct task_struct *task, unsigned long *data) 235static int set_evrregs(struct task_struct *task, unsigned long *data)
186{ 236{
187 int i; 237 int i;
188 238
@@ -205,8 +255,8 @@ static inline int set_evrregs(struct task_struct *task, unsigned long *data)
205} 255}
206#endif /* CONFIG_SPE */ 256#endif /* CONFIG_SPE */
207 257
208static inline void 258
209set_single_step(struct task_struct *task) 259static void set_single_step(struct task_struct *task)
210{ 260{
211 struct pt_regs *regs = task->thread.regs; 261 struct pt_regs *regs = task->thread.regs;
212 262
@@ -221,8 +271,7 @@ set_single_step(struct task_struct *task)
221 set_tsk_thread_flag(task, TIF_SINGLESTEP); 271 set_tsk_thread_flag(task, TIF_SINGLESTEP);
222} 272}
223 273
224static inline void 274static void clear_single_step(struct task_struct *task)
225clear_single_step(struct task_struct *task)
226{ 275{
227 struct pt_regs *regs = task->thread.regs; 276 struct pt_regs *regs = task->thread.regs;
228 277
@@ -236,7 +285,25 @@ clear_single_step(struct task_struct *task)
236 } 285 }
237 clear_tsk_thread_flag(task, TIF_SINGLESTEP); 286 clear_tsk_thread_flag(task, TIF_SINGLESTEP);
238} 287}
239#endif /* CONFIG_PPC32 */ 288
289static int ptrace_set_debugreg(struct task_struct *task, unsigned long addr,
290 unsigned long data)
291{
292 /* We only support one DABR and no IABRS at the moment */
293 if (addr > 0)
294 return -EINVAL;
295
296 /* The bottom 3 bits are flags */
297 if ((data & ~0x7UL) >= TASK_SIZE)
298 return -EIO;
299
300 /* Ensure translation is on */
301 if (data && !(data & DABR_TRANSLATION))
302 return -EIO;
303
304 task->thread.dabr = data;
305 return 0;
306}
240 307
241/* 308/*
242 * Called by kernel/ptrace.c when detaching.. 309 * Called by kernel/ptrace.c when detaching..
@@ -249,6 +316,62 @@ void ptrace_disable(struct task_struct *child)
249 clear_single_step(child); 316 clear_single_step(child);
250} 317}
251 318
319/*
320 * Here are the old "legacy" powerpc specific getregs/setregs ptrace calls,
321 * we mark them as obsolete now, they will be removed in a future version
322 */
323static long arch_ptrace_old(struct task_struct *child, long request, long addr,
324 long data)
325{
326 int ret = -EPERM;
327
328 switch(request) {
329 case PPC_PTRACE_GETREGS: { /* Get GPRs 0 - 31. */
330 int i;
331 unsigned long *reg = &((unsigned long *)child->thread.regs)[0];
332 unsigned long __user *tmp = (unsigned long __user *)addr;
333
334 for (i = 0; i < 32; i++) {
335 ret = put_user(*reg, tmp);
336 if (ret)
337 break;
338 reg++;
339 tmp++;
340 }
341 break;
342 }
343
344 case PPC_PTRACE_SETREGS: { /* Set GPRs 0 - 31. */
345 int i;
346 unsigned long *reg = &((unsigned long *)child->thread.regs)[0];
347 unsigned long __user *tmp = (unsigned long __user *)addr;
348
349 for (i = 0; i < 32; i++) {
350 ret = get_user(*reg, tmp);
351 if (ret)
352 break;
353 reg++;
354 tmp++;
355 }
356 break;
357 }
358
359 case PPC_PTRACE_GETFPREGS: { /* Get FPRs 0 - 31. */
360 flush_fp_to_thread(child);
361 ret = get_fpregs((void __user *)addr, child, 0);
362 break;
363 }
364
365 case PPC_PTRACE_SETFPREGS: { /* Get FPRs 0 - 31. */
366 flush_fp_to_thread(child);
367 ret = set_fpregs((void __user *)addr, child, 0);
368 break;
369 }
370
371 }
372 return ret;
373}
374
252long arch_ptrace(struct task_struct *child, long request, long addr, long data) 375long arch_ptrace(struct task_struct *child, long request, long addr, long data)
253{ 376{
254 int ret = -EPERM; 377 int ret = -EPERM;
@@ -284,11 +407,9 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
284#endif 407#endif
285 break; 408 break;
286 409
287#ifdef CONFIG_PPC32
288 CHECK_FULL_REGS(child->thread.regs); 410 CHECK_FULL_REGS(child->thread.regs);
289#endif
290 if (index < PT_FPR0) { 411 if (index < PT_FPR0) {
291 tmp = get_reg(child, (int) index); 412 tmp = ptrace_get_reg(child, (int) index);
292 } else { 413 } else {
293 flush_fp_to_thread(child); 414 flush_fp_to_thread(child);
294 tmp = ((unsigned long *)child->thread.fpr)[index - PT_FPR0]; 415 tmp = ((unsigned long *)child->thread.fpr)[index - PT_FPR0];
@@ -323,13 +444,9 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
323#endif 444#endif
324 break; 445 break;
325 446
326#ifdef CONFIG_PPC32
327 CHECK_FULL_REGS(child->thread.regs); 447 CHECK_FULL_REGS(child->thread.regs);
328#endif
329 if (index == PT_ORIG_R3)
330 break;
331 if (index < PT_FPR0) { 448 if (index < PT_FPR0) {
332 ret = put_reg(child, index, data); 449 ret = ptrace_put_reg(child, index, data);
333 } else { 450 } else {
334 flush_fp_to_thread(child); 451 flush_fp_to_thread(child);
335 ((unsigned long *)child->thread.fpr)[index - PT_FPR0] = data; 452 ((unsigned long *)child->thread.fpr)[index - PT_FPR0] = data;
@@ -384,7 +501,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
384 break; 501 break;
385 } 502 }
386 503
387#ifdef CONFIG_PPC64
388 case PTRACE_GET_DEBUGREG: { 504 case PTRACE_GET_DEBUGREG: {
389 ret = -EINVAL; 505 ret = -EINVAL;
390 /* We only support one DABR and no IABRS at the moment */ 506 /* We only support one DABR and no IABRS at the moment */
@@ -398,73 +514,61 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
398 case PTRACE_SET_DEBUGREG: 514 case PTRACE_SET_DEBUGREG:
399 ret = ptrace_set_debugreg(child, addr, data); 515 ret = ptrace_set_debugreg(child, addr, data);
400 break; 516 break;
401#endif
402 517
403 case PTRACE_DETACH: 518 case PTRACE_DETACH:
404 ret = ptrace_detach(child, data); 519 ret = ptrace_detach(child, data);
405 break; 520 break;
406 521
407 case PPC_PTRACE_GETREGS: { /* Get GPRs 0 - 31. */ 522#ifdef CONFIG_PPC64
408 int i; 523 case PTRACE_GETREGS64:
409 unsigned long *reg = &((unsigned long *)child->thread.regs)[0]; 524#endif
410 unsigned long __user *tmp = (unsigned long __user *)addr; 525 case PTRACE_GETREGS: { /* Get all pt_regs from the child. */
411 526 int ui;
412 for (i = 0; i < 32; i++) { 527 if (!access_ok(VERIFY_WRITE, (void __user *)data,
413 ret = put_user(*reg, tmp); 528 sizeof(struct pt_regs))) {
414 if (ret) 529 ret = -EIO;
415 break; 530 break;
416 reg++; 531 }
417 tmp++; 532 ret = 0;
533 for (ui = 0; ui < PT_REGS_COUNT; ui ++) {
534 ret |= __put_user(ptrace_get_reg(child, ui),
535 (unsigned long __user *) data);
536 data += sizeof(long);
418 } 537 }
419 break; 538 break;
420 } 539 }
421 540
422 case PPC_PTRACE_SETREGS: { /* Set GPRs 0 - 31. */ 541#ifdef CONFIG_PPC64
423 int i; 542 case PTRACE_SETREGS64:
424 unsigned long *reg = &((unsigned long *)child->thread.regs)[0]; 543#endif
425 unsigned long __user *tmp = (unsigned long __user *)addr; 544 case PTRACE_SETREGS: { /* Set all gp regs in the child. */
426 545 unsigned long tmp;
427 for (i = 0; i < 32; i++) { 546 int ui;
428 ret = get_user(*reg, tmp); 547 if (!access_ok(VERIFY_READ, (void __user *)data,
548 sizeof(struct pt_regs))) {
549 ret = -EIO;
550 break;
551 }
552 ret = 0;
553 for (ui = 0; ui < PT_REGS_COUNT; ui ++) {
554 ret = __get_user(tmp, (unsigned long __user *) data);
429 if (ret) 555 if (ret)
430 break; 556 break;
431 reg++; 557 ptrace_put_reg(child, ui, tmp);
432 tmp++; 558 data += sizeof(long);
433 } 559 }
434 break; 560 break;
435 } 561 }
436 562
437 case PPC_PTRACE_GETFPREGS: { /* Get FPRs 0 - 31. */ 563 case PTRACE_GETFPREGS: { /* Get the child FPU state (FPR0...31 + FPSCR) */
438 int i;
439 unsigned long *reg = &((unsigned long *)child->thread.fpr)[0];
440 unsigned long __user *tmp = (unsigned long __user *)addr;
441
442 flush_fp_to_thread(child); 564 flush_fp_to_thread(child);
443 565 ret = get_fpregs((void __user *)data, child, 1);
444 for (i = 0; i < 32; i++) {
445 ret = put_user(*reg, tmp);
446 if (ret)
447 break;
448 reg++;
449 tmp++;
450 }
451 break; 566 break;
452 } 567 }
453 568
454 case PPC_PTRACE_SETFPREGS: { /* Get FPRs 0 - 31. */ 569 case PTRACE_SETFPREGS: { /* Set the child FPU state (FPR0...31 + FPSCR) */
455 int i;
456 unsigned long *reg = &((unsigned long *)child->thread.fpr)[0];
457 unsigned long __user *tmp = (unsigned long __user *)addr;
458
459 flush_fp_to_thread(child); 570 flush_fp_to_thread(child);
460 571 ret = set_fpregs((void __user *)data, child, 1);
461 for (i = 0; i < 32; i++) {
462 ret = get_user(*reg, tmp);
463 if (ret)
464 break;
465 reg++;
466 tmp++;
467 }
468 break; 572 break;
469 } 573 }
470 574
@@ -499,11 +603,18 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
499 break; 603 break;
500#endif 604#endif
501 605
606 /* Old reverse args ptrace callss */
607 case PPC_PTRACE_GETREGS: /* Get GPRs 0 - 31. */
608 case PPC_PTRACE_SETREGS: /* Set GPRs 0 - 31. */
609 case PPC_PTRACE_GETFPREGS: /* Get FPRs 0 - 31. */
610 case PPC_PTRACE_SETFPREGS: /* Get FPRs 0 - 31. */
611 ret = arch_ptrace_old(child, request, addr, data);
612 break;
613
502 default: 614 default:
503 ret = ptrace_request(child, request, addr, data); 615 ret = ptrace_request(child, request, addr, data);
504 break; 616 break;
505 } 617 }
506
507 return ret; 618 return ret;
508} 619}
509 620
diff --git a/arch/powerpc/kernel/ptrace32.c b/arch/powerpc/kernel/ptrace32.c
index 9b9a230349bc..9e6baeac0fb1 100644
--- a/arch/powerpc/kernel/ptrace32.c
+++ b/arch/powerpc/kernel/ptrace32.c
@@ -33,13 +33,55 @@
33#include <asm/pgtable.h> 33#include <asm/pgtable.h>
34#include <asm/system.h> 34#include <asm/system.h>
35 35
36#include "ptrace-common.h"
37
38/* 36/*
39 * does not yet catch signals sent when the child dies. 37 * does not yet catch signals sent when the child dies.
40 * in exit.c or in signal.c. 38 * in exit.c or in signal.c.
41 */ 39 */
42 40
41/*
42 * Here are the old "legacy" powerpc specific getregs/setregs ptrace calls,
43 * we mark them as obsolete now, they will be removed in a future version
44 */
45static long compat_ptrace_old(struct task_struct *child, long request,
46 long addr, long data)
47{
48 int ret = -EPERM;
49
50 switch(request) {
51 case PPC_PTRACE_GETREGS: { /* Get GPRs 0 - 31. */
52 int i;
53 unsigned long *reg = &((unsigned long *)child->thread.regs)[0];
54 unsigned int __user *tmp = (unsigned int __user *)addr;
55
56 for (i = 0; i < 32; i++) {
57 ret = put_user(*reg, tmp);
58 if (ret)
59 break;
60 reg++;
61 tmp++;
62 }
63 break;
64 }
65
66 case PPC_PTRACE_SETREGS: { /* Set GPRs 0 - 31. */
67 int i;
68 unsigned long *reg = &((unsigned long *)child->thread.regs)[0];
69 unsigned int __user *tmp = (unsigned int __user *)addr;
70
71 for (i = 0; i < 32; i++) {
72 ret = get_user(*reg, tmp);
73 if (ret)
74 break;
75 reg++;
76 tmp++;
77 }
78 break;
79 }
80
81 }
82 return ret;
83}
84
43long compat_sys_ptrace(int request, int pid, unsigned long addr, 85long compat_sys_ptrace(int request, int pid, unsigned long addr,
44 unsigned long data) 86 unsigned long data)
45{ 87{
@@ -123,7 +165,7 @@ long compat_sys_ptrace(int request, int pid, unsigned long addr,
123 break; 165 break;
124 166
125 if (index < PT_FPR0) { 167 if (index < PT_FPR0) {
126 tmp = get_reg(child, index); 168 tmp = ptrace_get_reg(child, index);
127 } else { 169 } else {
128 flush_fp_to_thread(child); 170 flush_fp_to_thread(child);
129 /* 171 /*
@@ -162,7 +204,9 @@ long compat_sys_ptrace(int request, int pid, unsigned long addr,
162 else 204 else
163 part = 0; /* want the 1st half of the register (left-most). */ 205 part = 0; /* want the 1st half of the register (left-most). */
164 206
165 /* Validate the input - check to see if address is on the wrong boundary or beyond the end of the user area */ 207 /* Validate the input - check to see if address is on the wrong boundary
208 * or beyond the end of the user area
209 */
166 if ((addr & 3) || numReg > PT_FPSCR) 210 if ((addr & 3) || numReg > PT_FPSCR)
167 break; 211 break;
168 212
@@ -170,7 +214,7 @@ long compat_sys_ptrace(int request, int pid, unsigned long addr,
170 flush_fp_to_thread(child); 214 flush_fp_to_thread(child);
171 tmp = ((unsigned long int *)child->thread.fpr)[numReg - PT_FPR0]; 215 tmp = ((unsigned long int *)child->thread.fpr)[numReg - PT_FPR0];
172 } else { /* register within PT_REGS struct */ 216 } else { /* register within PT_REGS struct */
173 tmp = get_reg(child, numReg); 217 tmp = ptrace_get_reg(child, numReg);
174 } 218 }
175 reg32bits = ((u32*)&tmp)[part]; 219 reg32bits = ((u32*)&tmp)[part];
176 ret = put_user(reg32bits, (u32 __user *)data); 220 ret = put_user(reg32bits, (u32 __user *)data);
@@ -226,10 +270,8 @@ long compat_sys_ptrace(int request, int pid, unsigned long addr,
226 if ((addr & 3) || (index > PT_FPSCR32)) 270 if ((addr & 3) || (index > PT_FPSCR32))
227 break; 271 break;
228 272
229 if (index == PT_ORIG_R3)
230 break;
231 if (index < PT_FPR0) { 273 if (index < PT_FPR0) {
232 ret = put_reg(child, index, data); 274 ret = ptrace_put_reg(child, index, data);
233 } else { 275 } else {
234 flush_fp_to_thread(child); 276 flush_fp_to_thread(child);
235 /* 277 /*
@@ -258,70 +300,25 @@ long compat_sys_ptrace(int request, int pid, unsigned long addr,
258 /* Determine which register the user wants */ 300 /* Determine which register the user wants */
259 index = (u64)addr >> 2; 301 index = (u64)addr >> 2;
260 numReg = index / 2; 302 numReg = index / 2;
303
261 /* 304 /*
262 * Validate the input - check to see if address is on the 305 * Validate the input - check to see if address is on the
263 * wrong boundary or beyond the end of the user area 306 * wrong boundary or beyond the end of the user area
264 */ 307 */
265 if ((addr & 3) || (numReg > PT_FPSCR)) 308 if ((addr & 3) || (numReg > PT_FPSCR))
266 break; 309 break;
267 /* Insure it is a register we let them change */ 310 if (numReg < PT_FPR0) {
268 if ((numReg == PT_ORIG_R3) 311 unsigned long freg = ptrace_get_reg(child, numReg);
269 || ((numReg > PT_CCR) && (numReg < PT_FPR0))) 312 if (index % 2)
270 break; 313 freg = (freg & ~0xfffffffful) | (data & 0xfffffffful);
271 if (numReg >= PT_FPR0) { 314 else
315 freg = (freg & 0xfffffffful) | (data << 32);
316 ret = ptrace_put_reg(child, numReg, freg);
317 } else {
272 flush_fp_to_thread(child); 318 flush_fp_to_thread(child);
319 ((unsigned int *)child->thread.regs)[index] = data;
320 ret = 0;
273 } 321 }
274 if (numReg == PT_MSR)
275 data = (data & MSR_DEBUGCHANGE)
276 | (child->thread.regs->msr & ~MSR_DEBUGCHANGE);
277 ((u32*)child->thread.regs)[index] = data;
278 ret = 0;
279 break;
280 }
281
282 case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
283 case PTRACE_CONT: { /* restart after signal. */
284 ret = -EIO;
285 if (!valid_signal(data))
286 break;
287 if (request == PTRACE_SYSCALL)
288 set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
289 else
290 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
291 child->exit_code = data;
292 /* make sure the single step bit is not set. */
293 clear_single_step(child);
294 wake_up_process(child);
295 ret = 0;
296 break;
297 }
298
299 /*
300 * make the child exit. Best I can do is send it a sigkill.
301 * perhaps it should be put in the status that it wants to
302 * exit.
303 */
304 case PTRACE_KILL: {
305 ret = 0;
306 if (child->exit_state == EXIT_ZOMBIE) /* already dead */
307 break;
308 child->exit_code = SIGKILL;
309 /* make sure the single step bit is not set. */
310 clear_single_step(child);
311 wake_up_process(child);
312 break;
313 }
314
315 case PTRACE_SINGLESTEP: { /* set the trap flag. */
316 ret = -EIO;
317 if (!valid_signal(data))
318 break;
319 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
320 set_single_step(child);
321 child->exit_code = data;
322 /* give it a chance to run. */
323 wake_up_process(child);
324 ret = 0;
325 break; 322 break;
326 } 323 }
327 324
@@ -334,95 +331,67 @@ long compat_sys_ptrace(int request, int pid, unsigned long addr,
334 break; 331 break;
335 } 332 }
336 333
337 case PTRACE_SET_DEBUGREG: 334 case PTRACE_GETEVENTMSG:
338 ret = ptrace_set_debugreg(child, addr, data); 335 ret = put_user(child->ptrace_message, (unsigned int __user *) data);
339 break;
340
341 case PTRACE_DETACH:
342 ret = ptrace_detach(child, data);
343 break; 336 break;
344 337
345 case PPC_PTRACE_GETREGS: { /* Get GPRs 0 - 31. */ 338 case PTRACE_GETREGS: { /* Get all pt_regs from the child. */
346 int i; 339 int ui;
347 unsigned long *reg = &((unsigned long *)child->thread.regs)[0]; 340 if (!access_ok(VERIFY_WRITE, (void __user *)data,
348 unsigned int __user *tmp = (unsigned int __user *)addr; 341 PT_REGS_COUNT * sizeof(int))) {
349 342 ret = -EIO;
350 for (i = 0; i < 32; i++) { 343 break;
351 ret = put_user(*reg, tmp);
352 if (ret)
353 break;
354 reg++;
355 tmp++;
356 } 344 }
357 break; 345 ret = 0;
358 } 346 for (ui = 0; ui < PT_REGS_COUNT; ui ++) {
359 347 ret |= __put_user(ptrace_get_reg(child, ui),
360 case PPC_PTRACE_SETREGS: { /* Set GPRs 0 - 31. */ 348 (unsigned int __user *) data);
361 int i; 349 data += sizeof(int);
362 unsigned long *reg = &((unsigned long *)child->thread.regs)[0];
363 unsigned int __user *tmp = (unsigned int __user *)addr;
364
365 for (i = 0; i < 32; i++) {
366 ret = get_user(*reg, tmp);
367 if (ret)
368 break;
369 reg++;
370 tmp++;
371 } 350 }
372 break; 351 break;
373 } 352 }
374 353
375 case PPC_PTRACE_GETFPREGS: { /* Get FPRs 0 - 31. */ 354 case PTRACE_SETREGS: { /* Set all gp regs in the child. */
376 int i; 355 unsigned long tmp;
377 unsigned long *reg = &((unsigned long *)child->thread.fpr)[0]; 356 int ui;
378 unsigned int __user *tmp = (unsigned int __user *)addr; 357 if (!access_ok(VERIFY_READ, (void __user *)data,
379 358 PT_REGS_COUNT * sizeof(int))) {
380 flush_fp_to_thread(child); 359 ret = -EIO;
381 360 break;
382 for (i = 0; i < 32; i++) {
383 ret = put_user(*reg, tmp);
384 if (ret)
385 break;
386 reg++;
387 tmp++;
388 } 361 }
389 break; 362 ret = 0;
390 } 363 for (ui = 0; ui < PT_REGS_COUNT; ui ++) {
391 364 ret = __get_user(tmp, (unsigned int __user *) data);
392 case PPC_PTRACE_SETFPREGS: { /* Get FPRs 0 - 31. */
393 int i;
394 unsigned long *reg = &((unsigned long *)child->thread.fpr)[0];
395 unsigned int __user *tmp = (unsigned int __user *)addr;
396
397 flush_fp_to_thread(child);
398
399 for (i = 0; i < 32; i++) {
400 ret = get_user(*reg, tmp);
401 if (ret) 365 if (ret)
402 break; 366 break;
403 reg++; 367 ptrace_put_reg(child, ui, tmp);
404 tmp++; 368 data += sizeof(int);
405 } 369 }
406 break; 370 break;
407 } 371 }
408 372
409 case PTRACE_GETEVENTMSG: 373 case PTRACE_GETFPREGS:
410 ret = put_user(child->ptrace_message, (unsigned int __user *) data); 374 case PTRACE_SETFPREGS:
411 break;
412
413#ifdef CONFIG_ALTIVEC
414 case PTRACE_GETVRREGS: 375 case PTRACE_GETVRREGS:
415 /* Get the child altivec register state. */ 376 case PTRACE_SETVRREGS:
416 flush_altivec_to_thread(child); 377 case PTRACE_GETREGS64:
417 ret = get_vrregs((unsigned long __user *)data, child); 378 case PTRACE_SETREGS64:
379 case PPC_PTRACE_GETFPREGS:
380 case PPC_PTRACE_SETFPREGS:
381 case PTRACE_KILL:
382 case PTRACE_SINGLESTEP:
383 case PTRACE_DETACH:
384 case PTRACE_SET_DEBUGREG:
385 case PTRACE_SYSCALL:
386 case PTRACE_CONT:
387 ret = arch_ptrace(child, request, addr, data);
418 break; 388 break;
419 389
420 case PTRACE_SETVRREGS: 390 /* Old reverse args ptrace callss */
421 /* Set the child altivec register state. */ 391 case PPC_PTRACE_GETREGS: /* Get GPRs 0 - 31. */
422 flush_altivec_to_thread(child); 392 case PPC_PTRACE_SETREGS: /* Set GPRs 0 - 31. */
423 ret = set_vrregs(child, (unsigned long __user *)data); 393 ret = compat_ptrace_old(child, request, addr, data);
424 break; 394 break;
425#endif
426 395
427 default: 396 default:
428 ret = ptrace_request(child, request, addr, data); 397 ret = ptrace_request(child, request, addr, data);
diff --git a/arch/powerpc/kernel/rtas_pci.c b/arch/powerpc/kernel/rtas_pci.c
index f2286822be09..a5de6211b97a 100644
--- a/arch/powerpc/kernel/rtas_pci.c
+++ b/arch/powerpc/kernel/rtas_pci.c
@@ -278,10 +278,8 @@ void __init find_and_init_phbs(void)
278{ 278{
279 struct device_node *node; 279 struct device_node *node;
280 struct pci_controller *phb; 280 struct pci_controller *phb;
281 unsigned int index;
282 struct device_node *root = of_find_node_by_path("/"); 281 struct device_node *root = of_find_node_by_path("/");
283 282
284 index = 0;
285 for (node = of_get_next_child(root, NULL); 283 for (node = of_get_next_child(root, NULL);
286 node != NULL; 284 node != NULL;
287 node = of_get_next_child(root, node)) { 285 node = of_get_next_child(root, node)) {
@@ -295,8 +293,7 @@ void __init find_and_init_phbs(void)
295 continue; 293 continue;
296 rtas_setup_phb(phb); 294 rtas_setup_phb(phb);
297 pci_process_bridge_OF_ranges(phb, node, 0); 295 pci_process_bridge_OF_ranges(phb, node, 0);
298 pci_setup_phb_io(phb, index == 0); 296 isa_bridge_find_early(phb);
299 index++;
300 } 297 }
301 298
302 of_node_put(root); 299 of_node_put(root);
@@ -335,7 +332,7 @@ int pcibios_remove_root_bus(struct pci_controller *phb)
335 return 1; 332 return 1;
336 } 333 }
337 334
338 rc = unmap_bus_range(b); 335 rc = pcibios_unmap_io_space(b);
339 if (rc) { 336 if (rc) {
340 printk(KERN_ERR "%s: failed to unmap IO on bus %s\n", 337 printk(KERN_ERR "%s: failed to unmap IO on bus %s\n",
341 __FUNCTION__, b->name); 338 __FUNCTION__, b->name);
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
index ed07a198f8d6..4924c48cb1ff 100644
--- a/arch/powerpc/kernel/setup-common.c
+++ b/arch/powerpc/kernel/setup-common.c
@@ -32,6 +32,7 @@
32#include <linux/unistd.h> 32#include <linux/unistd.h>
33#include <linux/serial.h> 33#include <linux/serial.h>
34#include <linux/serial_8250.h> 34#include <linux/serial_8250.h>
35#include <linux/debugfs.h>
35#include <asm/io.h> 36#include <asm/io.h>
36#include <asm/prom.h> 37#include <asm/prom.h>
37#include <asm/processor.h> 38#include <asm/processor.h>
@@ -486,6 +487,14 @@ int check_legacy_ioport(unsigned long base_port)
486 487
487 switch(base_port) { 488 switch(base_port) {
488 case I8042_DATA_REG: 489 case I8042_DATA_REG:
490 if (!(np = of_find_compatible_node(NULL, NULL, "pnpPNP,303")))
491 np = of_find_compatible_node(NULL, NULL, "pnpPNP,f03");
492 if (np) {
493 parent = of_get_parent(np);
494 of_node_put(np);
495 np = parent;
496 break;
497 }
489 np = of_find_node_by_type(NULL, "8042"); 498 np = of_find_node_by_type(NULL, "8042");
490 break; 499 break;
491 case FDC_BASE: /* FDC1 */ 500 case FDC_BASE: /* FDC1 */
@@ -571,3 +580,15 @@ static int __init check_cache_coherency(void)
571 580
572late_initcall(check_cache_coherency); 581late_initcall(check_cache_coherency);
573#endif /* CONFIG_CHECK_CACHE_COHERENCY */ 582#endif /* CONFIG_CHECK_CACHE_COHERENCY */
583
584#ifdef CONFIG_DEBUG_FS
585struct dentry *powerpc_debugfs_root;
586
587static int powerpc_debugfs_init(void)
588{
589 powerpc_debugfs_root = debugfs_create_dir("powerpc", NULL);
590
591 return powerpc_debugfs_root == NULL;
592}
593arch_initcall(powerpc_debugfs_init);
594#endif
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
index 35f8f443c14f..7ec6ba56d83d 100644
--- a/arch/powerpc/kernel/setup_32.c
+++ b/arch/powerpc/kernel/setup_32.c
@@ -262,13 +262,11 @@ void __init setup_arch(char **cmdline_p)
262 * Systems with OF can look in the properties on the cpu node(s) 262 * Systems with OF can look in the properties on the cpu node(s)
263 * for a possibly more accurate value. 263 * for a possibly more accurate value.
264 */ 264 */
265 if (cpu_has_feature(CPU_FTR_SPLIT_ID_CACHE)) { 265 dcache_bsize = cur_cpu_spec->dcache_bsize;
266 dcache_bsize = cur_cpu_spec->dcache_bsize; 266 icache_bsize = cur_cpu_spec->icache_bsize;
267 icache_bsize = cur_cpu_spec->icache_bsize; 267 ucache_bsize = 0;
268 ucache_bsize = 0; 268 if (cpu_has_feature(CPU_FTR_UNIFIED_ID_CACHE))
269 } else 269 ucache_bsize = icache_bsize = dcache_bsize;
270 ucache_bsize = dcache_bsize = icache_bsize
271 = cur_cpu_spec->dcache_bsize;
272 270
273 /* reboot on panic */ 271 /* reboot on panic */
274 panic_timeout = 180; 272 panic_timeout = 180;
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index 6018178708a5..bc43bba05cf8 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -350,13 +350,11 @@ void __init setup_system(void)
350{ 350{
351 DBG(" -> setup_system()\n"); 351 DBG(" -> setup_system()\n");
352 352
353 /* Apply the CPUs-specific and firmware specific fixups to kernel 353 /* Apply CPUs-specific fixups to kernel text (nop out sections
354 * text (nop out sections not relevant to this CPU or this firmware) 354 * not relevant to this CPU)
355 */ 355 */
356 do_feature_fixups(cur_cpu_spec->cpu_features, 356 do_feature_fixups(cur_cpu_spec->cpu_features,
357 &__start___ftr_fixup, &__stop___ftr_fixup); 357 &__start___ftr_fixup, &__stop___ftr_fixup);
358 do_feature_fixups(powerpc_firmware_features,
359 &__start___fw_ftr_fixup, &__stop___fw_ftr_fixup);
360 358
361 /* 359 /*
362 * Unflatten the device-tree passed by prom_init or kexec 360 * Unflatten the device-tree passed by prom_init or kexec
@@ -394,6 +392,12 @@ void __init setup_system(void)
394 if (ppc_md.init_early) 392 if (ppc_md.init_early)
395 ppc_md.init_early(); 393 ppc_md.init_early();
396 394
395 /* Apply firmware specific fixups to kernel text (nop out
396 * sections not relevant to this firmware)
397 */
398 do_feature_fixups(powerpc_firmware_features,
399 &__start___fw_ftr_fixup, &__stop___fw_ftr_fixup);
400
397 /* 401 /*
398 * We can discover serial ports now since the above did setup the 402 * We can discover serial ports now since the above did setup the
399 * hash table management for us, thus ioremap works. We do that early 403 * hash table management for us, thus ioremap works. We do that early
diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c
new file mode 100644
index 000000000000..c434d6c4e4e6
--- /dev/null
+++ b/arch/powerpc/kernel/signal.c
@@ -0,0 +1,180 @@
1/*
2 * Common signal handling code for both 32 and 64 bits
3 *
4 * Copyright (c) 2007 Benjamin Herrenschmidt, IBM Coproration
5 * Extracted from signal_32.c and signal_64.c
6 *
7 * This file is subject to the terms and conditions of the GNU General
8 * Public License. See the file README.legal in the main directory of
9 * this archive for more details.
10 */
11
12#include <linux/ptrace.h>
13#include <linux/signal.h>
14#include <asm/uaccess.h>
15#include <asm/unistd.h>
16
17#include "signal.h"
18
19/*
20 * Allocate space for the signal frame
21 */
22void __user * get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
23 size_t frame_size)
24{
25 unsigned long oldsp, newsp;
26
27 /* Default to using normal stack */
28 oldsp = regs->gpr[1];
29
30 /* Check for alt stack */
31 if ((ka->sa.sa_flags & SA_ONSTACK) &&
32 current->sas_ss_size && !on_sig_stack(oldsp))
33 oldsp = (current->sas_ss_sp + current->sas_ss_size);
34
35 /* Get aligned frame */
36 newsp = (oldsp - frame_size) & ~0xFUL;
37
38 /* Check access */
39 if (!access_ok(VERIFY_WRITE, (void __user *)newsp, oldsp - newsp))
40 return NULL;
41
42 return (void __user *)newsp;
43}
44
45
46/*
47 * Restore the user process's signal mask
48 */
49void restore_sigmask(sigset_t *set)
50{
51 sigdelsetmask(set, ~_BLOCKABLE);
52 spin_lock_irq(&current->sighand->siglock);
53 current->blocked = *set;
54 recalc_sigpending();
55 spin_unlock_irq(&current->sighand->siglock);
56}
57
58static void check_syscall_restart(struct pt_regs *regs, struct k_sigaction *ka,
59 int has_handler)
60{
61 unsigned long ret = regs->gpr[3];
62 int restart = 1;
63
64 /* syscall ? */
65 if (TRAP(regs) != 0x0C00)
66 return;
67
68 /* error signalled ? */
69 if (!(regs->ccr & 0x10000000))
70 return;
71
72 switch (ret) {
73 case ERESTART_RESTARTBLOCK:
74 case ERESTARTNOHAND:
75 /* ERESTARTNOHAND means that the syscall should only be
76 * restarted if there was no handler for the signal, and since
77 * we only get here if there is a handler, we dont restart.
78 */
79 restart = !has_handler;
80 break;
81 case ERESTARTSYS:
82 /* ERESTARTSYS means to restart the syscall if there is no
83 * handler or the handler was registered with SA_RESTART
84 */
85 restart = !has_handler || (ka->sa.sa_flags & SA_RESTART) != 0;
86 break;
87 case ERESTARTNOINTR:
88 /* ERESTARTNOINTR means that the syscall should be
89 * called again after the signal handler returns.
90 */
91 break;
92 default:
93 return;
94 }
95 if (restart) {
96 if (ret == ERESTART_RESTARTBLOCK)
97 regs->gpr[0] = __NR_restart_syscall;
98 else
99 regs->gpr[3] = regs->orig_gpr3;
100 regs->nip -= 4;
101 regs->result = 0;
102 } else {
103 regs->result = -EINTR;
104 regs->gpr[3] = EINTR;
105 regs->ccr |= 0x10000000;
106 }
107}
108
109int do_signal(sigset_t *oldset, struct pt_regs *regs)
110{
111 siginfo_t info;
112 int signr;
113 struct k_sigaction ka;
114 int ret;
115 int is32 = is_32bit_task();
116
117 if (test_thread_flag(TIF_RESTORE_SIGMASK))
118 oldset = &current->saved_sigmask;
119 else if (!oldset)
120 oldset = &current->blocked;
121
122 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
123
124 /* Is there any syscall restart business here ? */
125 check_syscall_restart(regs, &ka, signr > 0);
126
127 if (signr <= 0) {
128 /* No signal to deliver -- put the saved sigmask back */
129 if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
130 clear_thread_flag(TIF_RESTORE_SIGMASK);
131 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
132 }
133 return 0; /* no signals delivered */
134 }
135
136 /*
137 * Reenable the DABR before delivering the signal to
138 * user space. The DABR will have been cleared if it
139 * triggered inside the kernel.
140 */
141 if (current->thread.dabr)
142 set_dabr(current->thread.dabr);
143
144 if (is32) {
145 if (ka.sa.sa_flags & SA_SIGINFO)
146 ret = handle_rt_signal32(signr, &ka, &info, oldset,
147 regs);
148 else
149 ret = handle_signal32(signr, &ka, &info, oldset,
150 regs);
151 } else {
152 ret = handle_rt_signal64(signr, &ka, &info, oldset, regs);
153 }
154
155 if (ret) {
156 spin_lock_irq(&current->sighand->siglock);
157 sigorsets(&current->blocked, &current->blocked,
158 &ka.sa.sa_mask);
159 if (!(ka.sa.sa_flags & SA_NODEFER))
160 sigaddset(&current->blocked, signr);
161 recalc_sigpending();
162 spin_unlock_irq(&current->sighand->siglock);
163
164 /*
165 * A signal was successfully delivered; the saved sigmask is in
166 * its frame, and we can clear the TIF_RESTORE_SIGMASK flag.
167 */
168 if (test_thread_flag(TIF_RESTORE_SIGMASK))
169 clear_thread_flag(TIF_RESTORE_SIGMASK);
170 }
171
172 return ret;
173}
174
175long sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
176 unsigned long r5, unsigned long r6, unsigned long r7,
177 unsigned long r8, struct pt_regs *regs)
178{
179 return do_sigaltstack(uss, uoss, regs->gpr[1]);
180}
diff --git a/arch/powerpc/kernel/signal.h b/arch/powerpc/kernel/signal.h
new file mode 100644
index 000000000000..77efb3d5465a
--- /dev/null
+++ b/arch/powerpc/kernel/signal.h
@@ -0,0 +1,55 @@
1/*
2 * Copyright (c) 2007 Benjamin Herrenschmidt, IBM Coproration
3 * Extracted from signal_32.c and signal_64.c
4 *
5 * This file is subject to the terms and conditions of the GNU General
6 * Public License. See the file README.legal in the main directory of
7 * this archive for more details.
8 */
9
10#ifndef _POWERPC_ARCH_SIGNAL_H
11#define _POWERPC_ARCH_SIGNAL_H
12
13#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
14
15extern void __user * get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
16 size_t frame_size);
17extern void restore_sigmask(sigset_t *set);
18
19extern int handle_signal32(unsigned long sig, struct k_sigaction *ka,
20 siginfo_t *info, sigset_t *oldset,
21 struct pt_regs *regs);
22
23extern int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka,
24 siginfo_t *info, sigset_t *oldset,
25 struct pt_regs *regs);
26
27
28#ifdef CONFIG_PPC64
29
30static inline int is_32bit_task(void)
31{
32 return test_thread_flag(TIF_32BIT);
33}
34
35extern int handle_rt_signal64(int signr, struct k_sigaction *ka,
36 siginfo_t *info, sigset_t *set,
37 struct pt_regs *regs);
38
39#else /* CONFIG_PPC64 */
40
41static inline int is_32bit_task(void)
42{
43 return 1;
44}
45
46static inline int handle_rt_signal64(int signr, struct k_sigaction *ka,
47 siginfo_t *info, sigset_t *set,
48 struct pt_regs *regs)
49{
50 return -EFAULT;
51}
52
53#endif /* !defined(CONFIG_PPC64) */
54
55#endif /* _POWERPC_ARCH_SIGNAL_H */
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index dd1dca5bfa81..590057e9e987 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -51,12 +51,11 @@
51#include <asm/pgtable.h> 51#include <asm/pgtable.h>
52#endif 52#endif
53 53
54#undef DEBUG_SIG 54#include "signal.h"
55 55
56#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) 56#undef DEBUG_SIG
57 57
58#ifdef CONFIG_PPC64 58#ifdef CONFIG_PPC64
59#define do_signal do_signal32
60#define sys_sigsuspend compat_sys_sigsuspend 59#define sys_sigsuspend compat_sys_sigsuspend
61#define sys_rt_sigsuspend compat_sys_rt_sigsuspend 60#define sys_rt_sigsuspend compat_sys_rt_sigsuspend
62#define sys_rt_sigreturn compat_sys_rt_sigreturn 61#define sys_rt_sigreturn compat_sys_rt_sigreturn
@@ -231,8 +230,6 @@ static inline int restore_general_regs(struct pt_regs *regs,
231 230
232#endif /* CONFIG_PPC64 */ 231#endif /* CONFIG_PPC64 */
233 232
234int do_signal(sigset_t *oldset, struct pt_regs *regs);
235
236/* 233/*
237 * Atomically swap in the new signal mask, and wait for a signal. 234 * Atomically swap in the new signal mask, and wait for a signal.
238 */ 235 */
@@ -251,14 +248,6 @@ long sys_sigsuspend(old_sigset_t mask)
251 return -ERESTARTNOHAND; 248 return -ERESTARTNOHAND;
252} 249}
253 250
254#ifdef CONFIG_PPC32
255long sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, int r5,
256 int r6, int r7, int r8, struct pt_regs *regs)
257{
258 return do_sigaltstack(uss, uoss, regs->gpr[1]);
259}
260#endif
261
262long sys_sigaction(int sig, struct old_sigaction __user *act, 251long sys_sigaction(int sig, struct old_sigaction __user *act,
263 struct old_sigaction __user *oact) 252 struct old_sigaction __user *oact)
264{ 253{
@@ -293,14 +282,17 @@ long sys_sigaction(int sig, struct old_sigaction __user *act,
293/* 282/*
294 * When we have signals to deliver, we set up on the 283 * When we have signals to deliver, we set up on the
295 * user stack, going down from the original stack pointer: 284 * user stack, going down from the original stack pointer:
296 * a sigregs struct 285 * an ABI gap of 56 words
286 * an mcontext struct
297 * a sigcontext struct 287 * a sigcontext struct
298 * a gap of __SIGNAL_FRAMESIZE bytes 288 * a gap of __SIGNAL_FRAMESIZE bytes
299 * 289 *
300 * Each of these things must be a multiple of 16 bytes in size. 290 * Each of these things must be a multiple of 16 bytes in size. The following
291 * structure represent all of this except the __SIGNAL_FRAMESIZE gap
301 * 292 *
302 */ 293 */
303struct sigregs { 294struct sigframe {
295 struct sigcontext sctx; /* the sigcontext */
304 struct mcontext mctx; /* all the register values */ 296 struct mcontext mctx; /* all the register values */
305 /* 297 /*
306 * Programs using the rs6000/xcoff abi can save up to 19 gp 298 * Programs using the rs6000/xcoff abi can save up to 19 gp
@@ -703,44 +695,22 @@ int compat_sys_sigaltstack(u32 __new, u32 __old, int r5,
703} 695}
704#endif /* CONFIG_PPC64 */ 696#endif /* CONFIG_PPC64 */
705 697
706
707/*
708 * Restore the user process's signal mask
709 */
710#ifdef CONFIG_PPC64
711extern void restore_sigmask(sigset_t *set);
712#else /* CONFIG_PPC64 */
713static void restore_sigmask(sigset_t *set)
714{
715 sigdelsetmask(set, ~_BLOCKABLE);
716 spin_lock_irq(&current->sighand->siglock);
717 current->blocked = *set;
718 recalc_sigpending();
719 spin_unlock_irq(&current->sighand->siglock);
720}
721#endif
722
723/* 698/*
724 * Set up a signal frame for a "real-time" signal handler 699 * Set up a signal frame for a "real-time" signal handler
725 * (one which gets siginfo). 700 * (one which gets siginfo).
726 */ 701 */
727static int handle_rt_signal(unsigned long sig, struct k_sigaction *ka, 702int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka,
728 siginfo_t *info, sigset_t *oldset, 703 siginfo_t *info, sigset_t *oldset,
729 struct pt_regs *regs, unsigned long newsp) 704 struct pt_regs *regs)
730{ 705{
731 struct rt_sigframe __user *rt_sf; 706 struct rt_sigframe __user *rt_sf;
732 struct mcontext __user *frame; 707 struct mcontext __user *frame;
733 unsigned long origsp = newsp; 708 unsigned long newsp = 0;
734 709
735 /* Set up Signal Frame */ 710 /* Set up Signal Frame */
736 /* Put a Real Time Context onto stack */ 711 /* Put a Real Time Context onto stack */
737 newsp -= sizeof(*rt_sf); 712 rt_sf = get_sigframe(ka, regs, sizeof(*rt_sf));
738 rt_sf = (struct rt_sigframe __user *)newsp; 713 if (unlikely(rt_sf == NULL))
739
740 /* create a stack frame for the caller of the handler */
741 newsp -= __SIGNAL_FRAMESIZE + 16;
742
743 if (!access_ok(VERIFY_WRITE, (void __user *)newsp, origsp - newsp))
744 goto badframe; 714 goto badframe;
745 715
746 /* Put the siginfo & fill in most of the ucontext */ 716 /* Put the siginfo & fill in most of the ucontext */
@@ -770,8 +740,12 @@ static int handle_rt_signal(unsigned long sig, struct k_sigaction *ka,
770 740
771 current->thread.fpscr.val = 0; /* turn off all fp exceptions */ 741 current->thread.fpscr.val = 0; /* turn off all fp exceptions */
772 742
743 /* create a stack frame for the caller of the handler */
744 newsp = ((unsigned long)rt_sf) - (__SIGNAL_FRAMESIZE + 16);
773 if (put_user(regs->gpr[1], (u32 __user *)newsp)) 745 if (put_user(regs->gpr[1], (u32 __user *)newsp))
774 goto badframe; 746 goto badframe;
747
748 /* Fill registers for signal handler */
775 regs->gpr[1] = newsp; 749 regs->gpr[1] = newsp;
776 regs->gpr[3] = sig; 750 regs->gpr[3] = sig;
777 regs->gpr[4] = (unsigned long) &rt_sf->info; 751 regs->gpr[4] = (unsigned long) &rt_sf->info;
@@ -1015,27 +989,18 @@ int sys_debug_setcontext(struct ucontext __user *ctx,
1015/* 989/*
1016 * OK, we're invoking a handler 990 * OK, we're invoking a handler
1017 */ 991 */
1018static int handle_signal(unsigned long sig, struct k_sigaction *ka, 992int handle_signal32(unsigned long sig, struct k_sigaction *ka,
1019 siginfo_t *info, sigset_t *oldset, struct pt_regs *regs, 993 siginfo_t *info, sigset_t *oldset, struct pt_regs *regs)
1020 unsigned long newsp)
1021{ 994{
1022 struct sigcontext __user *sc; 995 struct sigcontext __user *sc;
1023 struct sigregs __user *frame; 996 struct sigframe __user *frame;
1024 unsigned long origsp = newsp; 997 unsigned long newsp = 0;
1025 998
1026 /* Set up Signal Frame */ 999 /* Set up Signal Frame */
1027 newsp -= sizeof(struct sigregs); 1000 frame = get_sigframe(ka, regs, sizeof(*frame));
1028 frame = (struct sigregs __user *) newsp; 1001 if (unlikely(frame == NULL))
1029
1030 /* Put a sigcontext on the stack */
1031 newsp -= sizeof(*sc);
1032 sc = (struct sigcontext __user *) newsp;
1033
1034 /* create a stack frame for the caller of the handler */
1035 newsp -= __SIGNAL_FRAMESIZE;
1036
1037 if (!access_ok(VERIFY_WRITE, (void __user *) newsp, origsp - newsp))
1038 goto badframe; 1002 goto badframe;
1003 sc = (struct sigcontext __user *) &frame->sctx;
1039 1004
1040#if _NSIG != 64 1005#if _NSIG != 64
1041#error "Please adjust handle_signal()" 1006#error "Please adjust handle_signal()"
@@ -1047,7 +1012,7 @@ static int handle_signal(unsigned long sig, struct k_sigaction *ka,
1047#else 1012#else
1048 || __put_user(oldset->sig[1], &sc->_unused[3]) 1013 || __put_user(oldset->sig[1], &sc->_unused[3])
1049#endif 1014#endif
1050 || __put_user(to_user_ptr(frame), &sc->regs) 1015 || __put_user(to_user_ptr(&frame->mctx), &sc->regs)
1051 || __put_user(sig, &sc->signal)) 1016 || __put_user(sig, &sc->signal))
1052 goto badframe; 1017 goto badframe;
1053 1018
@@ -1063,8 +1028,11 @@ static int handle_signal(unsigned long sig, struct k_sigaction *ka,
1063 1028
1064 current->thread.fpscr.val = 0; /* turn off all fp exceptions */ 1029 current->thread.fpscr.val = 0; /* turn off all fp exceptions */
1065 1030
1031 /* create a stack frame for the caller of the handler */
1032 newsp = ((unsigned long)frame) - __SIGNAL_FRAMESIZE;
1066 if (put_user(regs->gpr[1], (u32 __user *)newsp)) 1033 if (put_user(regs->gpr[1], (u32 __user *)newsp))
1067 goto badframe; 1034 goto badframe;
1035
1068 regs->gpr[1] = newsp; 1036 regs->gpr[1] = newsp;
1069 regs->gpr[3] = sig; 1037 regs->gpr[3] = sig;
1070 regs->gpr[4] = (unsigned long) sc; 1038 regs->gpr[4] = (unsigned long) sc;
@@ -1126,106 +1094,3 @@ badframe:
1126 force_sig(SIGSEGV, current); 1094 force_sig(SIGSEGV, current);
1127 return 0; 1095 return 0;
1128} 1096}
1129
1130/*
1131 * Note that 'init' is a special process: it doesn't get signals it doesn't
1132 * want to handle. Thus you cannot kill init even with a SIGKILL even by
1133 * mistake.
1134 */
1135int do_signal(sigset_t *oldset, struct pt_regs *regs)
1136{
1137 siginfo_t info;
1138 struct k_sigaction ka;
1139 unsigned int newsp;
1140 int signr, ret;
1141
1142#ifdef CONFIG_PPC32
1143 if (try_to_freeze()) {
1144 signr = 0;
1145 if (!signal_pending(current))
1146 goto no_signal;
1147 }
1148#endif
1149
1150 if (test_thread_flag(TIF_RESTORE_SIGMASK))
1151 oldset = &current->saved_sigmask;
1152 else if (!oldset)
1153 oldset = &current->blocked;
1154
1155 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
1156#ifdef CONFIG_PPC32
1157no_signal:
1158#endif
1159 if (TRAP(regs) == 0x0C00 /* System Call! */
1160 && regs->ccr & 0x10000000 /* error signalled */
1161 && ((ret = regs->gpr[3]) == ERESTARTSYS
1162 || ret == ERESTARTNOHAND || ret == ERESTARTNOINTR
1163 || ret == ERESTART_RESTARTBLOCK)) {
1164
1165 if (signr > 0
1166 && (ret == ERESTARTNOHAND || ret == ERESTART_RESTARTBLOCK
1167 || (ret == ERESTARTSYS
1168 && !(ka.sa.sa_flags & SA_RESTART)))) {
1169 /* make the system call return an EINTR error */
1170 regs->result = -EINTR;
1171 regs->gpr[3] = EINTR;
1172 /* note that the cr0.SO bit is already set */
1173 } else {
1174 regs->nip -= 4; /* Back up & retry system call */
1175 regs->result = 0;
1176 regs->trap = 0;
1177 if (ret == ERESTART_RESTARTBLOCK)
1178 regs->gpr[0] = __NR_restart_syscall;
1179 else
1180 regs->gpr[3] = regs->orig_gpr3;
1181 }
1182 }
1183
1184 if (signr == 0) {
1185 /* No signal to deliver -- put the saved sigmask back */
1186 if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
1187 clear_thread_flag(TIF_RESTORE_SIGMASK);
1188 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
1189 }
1190 return 0; /* no signals delivered */
1191 }
1192
1193 if ((ka.sa.sa_flags & SA_ONSTACK) && current->sas_ss_size
1194 && !on_sig_stack(regs->gpr[1]))
1195 newsp = current->sas_ss_sp + current->sas_ss_size;
1196 else
1197 newsp = regs->gpr[1];
1198 newsp &= ~0xfUL;
1199
1200#ifdef CONFIG_PPC64
1201 /*
1202 * Reenable the DABR before delivering the signal to
1203 * user space. The DABR will have been cleared if it
1204 * triggered inside the kernel.
1205 */
1206 if (current->thread.dabr)
1207 set_dabr(current->thread.dabr);
1208#endif
1209
1210 /* Whee! Actually deliver the signal. */
1211 if (ka.sa.sa_flags & SA_SIGINFO)
1212 ret = handle_rt_signal(signr, &ka, &info, oldset, regs, newsp);
1213 else
1214 ret = handle_signal(signr, &ka, &info, oldset, regs, newsp);
1215
1216 if (ret) {
1217 spin_lock_irq(&current->sighand->siglock);
1218 sigorsets(&current->blocked, &current->blocked,
1219 &ka.sa.sa_mask);
1220 if (!(ka.sa.sa_flags & SA_NODEFER))
1221 sigaddset(&current->blocked, signr);
1222 recalc_sigpending();
1223 spin_unlock_irq(&current->sighand->siglock);
1224 /* A signal was successfully delivered; the saved sigmask is in
1225 its frame, and we can clear the TIF_RESTORE_SIGMASK flag */
1226 if (test_thread_flag(TIF_RESTORE_SIGMASK))
1227 clear_thread_flag(TIF_RESTORE_SIGMASK);
1228 }
1229
1230 return ret;
1231}
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c
index b27e26852fdb..de895e6d8c62 100644
--- a/arch/powerpc/kernel/signal_64.c
+++ b/arch/powerpc/kernel/signal_64.c
@@ -34,9 +34,9 @@
34#include <asm/syscalls.h> 34#include <asm/syscalls.h>
35#include <asm/vdso.h> 35#include <asm/vdso.h>
36 36
37#define DEBUG_SIG 0 37#include "signal.h"
38 38
39#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) 39#define DEBUG_SIG 0
40 40
41#define GP_REGS_SIZE min(sizeof(elf_gregset_t), sizeof(struct pt_regs)) 41#define GP_REGS_SIZE min(sizeof(elf_gregset_t), sizeof(struct pt_regs))
42#define FP_REGS_SIZE sizeof(elf_fpregset_t) 42#define FP_REGS_SIZE sizeof(elf_fpregset_t)
@@ -64,14 +64,6 @@ struct rt_sigframe {
64 char abigap[288]; 64 char abigap[288];
65} __attribute__ ((aligned (16))); 65} __attribute__ ((aligned (16)));
66 66
67long sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, unsigned long r5,
68 unsigned long r6, unsigned long r7, unsigned long r8,
69 struct pt_regs *regs)
70{
71 return do_sigaltstack(uss, uoss, regs->gpr[1]);
72}
73
74
75/* 67/*
76 * Set up the sigcontext for the signal frame. 68 * Set up the sigcontext for the signal frame.
77 */ 69 */
@@ -208,25 +200,6 @@ static long restore_sigcontext(struct pt_regs *regs, sigset_t *set, int sig,
208} 200}
209 201
210/* 202/*
211 * Allocate space for the signal frame
212 */
213static inline void __user * get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
214 size_t frame_size)
215{
216 unsigned long newsp;
217
218 /* Default to using normal stack */
219 newsp = regs->gpr[1];
220
221 if ((ka->sa.sa_flags & SA_ONSTACK) && current->sas_ss_size) {
222 if (! on_sig_stack(regs->gpr[1]))
223 newsp = (current->sas_ss_sp + current->sas_ss_size);
224 }
225
226 return (void __user *)((newsp - frame_size) & -16ul);
227}
228
229/*
230 * Setup the trampoline code on the stack 203 * Setup the trampoline code on the stack
231 */ 204 */
232static long setup_trampoline(unsigned int syscall, unsigned int __user *tramp) 205static long setup_trampoline(unsigned int syscall, unsigned int __user *tramp)
@@ -253,19 +226,6 @@ static long setup_trampoline(unsigned int syscall, unsigned int __user *tramp)
253} 226}
254 227
255/* 228/*
256 * Restore the user process's signal mask (also used by signal32.c)
257 */
258void restore_sigmask(sigset_t *set)
259{
260 sigdelsetmask(set, ~_BLOCKABLE);
261 spin_lock_irq(&current->sighand->siglock);
262 current->blocked = *set;
263 recalc_sigpending();
264 spin_unlock_irq(&current->sighand->siglock);
265}
266
267
268/*
269 * Handle {get,set,swap}_context operations 229 * Handle {get,set,swap}_context operations
270 */ 230 */
271int sys_swapcontext(struct ucontext __user *old_ctx, 231int sys_swapcontext(struct ucontext __user *old_ctx,
@@ -359,7 +319,7 @@ badframe:
359 return 0; 319 return 0;
360} 320}
361 321
362static int setup_rt_frame(int signr, struct k_sigaction *ka, siginfo_t *info, 322int handle_rt_signal64(int signr, struct k_sigaction *ka, siginfo_t *info,
363 sigset_t *set, struct pt_regs *regs) 323 sigset_t *set, struct pt_regs *regs)
364{ 324{
365 /* Handler is *really* a pointer to the function descriptor for 325 /* Handler is *really* a pointer to the function descriptor for
@@ -373,8 +333,7 @@ static int setup_rt_frame(int signr, struct k_sigaction *ka, siginfo_t *info,
373 long err = 0; 333 long err = 0;
374 334
375 frame = get_sigframe(ka, regs, sizeof(*frame)); 335 frame = get_sigframe(ka, regs, sizeof(*frame));
376 336 if (unlikely(frame == NULL))
377 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
378 goto badframe; 337 goto badframe;
379 338
380 err |= __put_user(&frame->info, &frame->pinfo); 339 err |= __put_user(&frame->info, &frame->pinfo);
@@ -411,7 +370,7 @@ static int setup_rt_frame(int signr, struct k_sigaction *ka, siginfo_t *info,
411 funct_desc_ptr = (func_descr_t __user *) ka->sa.sa_handler; 370 funct_desc_ptr = (func_descr_t __user *) ka->sa.sa_handler;
412 371
413 /* Allocate a dummy caller frame for the signal handler. */ 372 /* Allocate a dummy caller frame for the signal handler. */
414 newsp = (unsigned long)frame - __SIGNAL_FRAMESIZE; 373 newsp = ((unsigned long)frame) - __SIGNAL_FRAMESIZE;
415 err |= put_user(regs->gpr[1], (unsigned long __user *)newsp); 374 err |= put_user(regs->gpr[1], (unsigned long __user *)newsp);
416 375
417 /* Set up "regs" so we "return" to the signal handler. */ 376 /* Set up "regs" so we "return" to the signal handler. */
@@ -442,134 +401,3 @@ badframe:
442 force_sigsegv(signr, current); 401 force_sigsegv(signr, current);
443 return 0; 402 return 0;
444} 403}
445
446
447/*
448 * OK, we're invoking a handler
449 */
450static int handle_signal(unsigned long sig, struct k_sigaction *ka,
451 siginfo_t *info, sigset_t *oldset, struct pt_regs *regs)
452{
453 int ret;
454
455 /* Set up Signal Frame */
456 ret = setup_rt_frame(sig, ka, info, oldset, regs);
457
458 if (ret) {
459 spin_lock_irq(&current->sighand->siglock);
460 sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask);
461 if (!(ka->sa.sa_flags & SA_NODEFER))
462 sigaddset(&current->blocked,sig);
463 recalc_sigpending();
464 spin_unlock_irq(&current->sighand->siglock);
465 }
466
467 return ret;
468}
469
470static inline void syscall_restart(struct pt_regs *regs, struct k_sigaction *ka)
471{
472 switch ((int)regs->result) {
473 case -ERESTART_RESTARTBLOCK:
474 case -ERESTARTNOHAND:
475 /* ERESTARTNOHAND means that the syscall should only be
476 * restarted if there was no handler for the signal, and since
477 * we only get here if there is a handler, we dont restart.
478 */
479 regs->result = -EINTR;
480 regs->gpr[3] = EINTR;
481 regs->ccr |= 0x10000000;
482 break;
483 case -ERESTARTSYS:
484 /* ERESTARTSYS means to restart the syscall if there is no
485 * handler or the handler was registered with SA_RESTART
486 */
487 if (!(ka->sa.sa_flags & SA_RESTART)) {
488 regs->result = -EINTR;
489 regs->gpr[3] = EINTR;
490 regs->ccr |= 0x10000000;
491 break;
492 }
493 /* fallthrough */
494 case -ERESTARTNOINTR:
495 /* ERESTARTNOINTR means that the syscall should be
496 * called again after the signal handler returns.
497 */
498 regs->gpr[3] = regs->orig_gpr3;
499 regs->nip -= 4;
500 regs->result = 0;
501 break;
502 }
503}
504
505/*
506 * Note that 'init' is a special process: it doesn't get signals it doesn't
507 * want to handle. Thus you cannot kill init even with a SIGKILL even by
508 * mistake.
509 */
510int do_signal(sigset_t *oldset, struct pt_regs *regs)
511{
512 siginfo_t info;
513 int signr;
514 struct k_sigaction ka;
515
516 /*
517 * If the current thread is 32 bit - invoke the
518 * 32 bit signal handling code
519 */
520 if (test_thread_flag(TIF_32BIT))
521 return do_signal32(oldset, regs);
522
523 if (test_thread_flag(TIF_RESTORE_SIGMASK))
524 oldset = &current->saved_sigmask;
525 else if (!oldset)
526 oldset = &current->blocked;
527
528 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
529 if (signr > 0) {
530 int ret;
531
532 /* Whee! Actually deliver the signal. */
533 if (TRAP(regs) == 0x0C00)
534 syscall_restart(regs, &ka);
535
536 /*
537 * Reenable the DABR before delivering the signal to
538 * user space. The DABR will have been cleared if it
539 * triggered inside the kernel.
540 */
541 if (current->thread.dabr)
542 set_dabr(current->thread.dabr);
543
544 ret = handle_signal(signr, &ka, &info, oldset, regs);
545
546 /* If a signal was successfully delivered, the saved sigmask is in
547 its frame, and we can clear the TIF_RESTORE_SIGMASK flag */
548 if (ret && test_thread_flag(TIF_RESTORE_SIGMASK))
549 clear_thread_flag(TIF_RESTORE_SIGMASK);
550
551 return ret;
552 }
553
554 if (TRAP(regs) == 0x0C00) { /* System Call! */
555 if ((int)regs->result == -ERESTARTNOHAND ||
556 (int)regs->result == -ERESTARTSYS ||
557 (int)regs->result == -ERESTARTNOINTR) {
558 regs->gpr[3] = regs->orig_gpr3;
559 regs->nip -= 4; /* Back up & retry system call */
560 regs->result = 0;
561 } else if ((int)regs->result == -ERESTART_RESTARTBLOCK) {
562 regs->gpr[0] = __NR_restart_syscall;
563 regs->nip -= 4;
564 regs->result = 0;
565 }
566 }
567 /* No signal to deliver -- put the saved sigmask back */
568 if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
569 clear_thread_flag(TIF_RESTORE_SIGMASK);
570 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
571 }
572
573 return 0;
574}
575EXPORT_SYMBOL(do_signal);
diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c
index 68991c2d4a1b..55d29ed4b7a0 100644
--- a/arch/powerpc/kernel/sysfs.c
+++ b/arch/powerpc/kernel/sysfs.c
@@ -442,12 +442,14 @@ int sysfs_add_device_to_node(struct sys_device *dev, int nid)
442 return sysfs_create_link(&node->sysdev.kobj, &dev->kobj, 442 return sysfs_create_link(&node->sysdev.kobj, &dev->kobj,
443 kobject_name(&dev->kobj)); 443 kobject_name(&dev->kobj));
444} 444}
445EXPORT_SYMBOL_GPL(sysfs_add_device_to_node);
445 446
446void sysfs_remove_device_from_node(struct sys_device *dev, int nid) 447void sysfs_remove_device_from_node(struct sys_device *dev, int nid)
447{ 448{
448 struct node *node = &node_devices[nid]; 449 struct node *node = &node_devices[nid];
449 sysfs_remove_link(&node->sysdev.kobj, kobject_name(&dev->kobj)); 450 sysfs_remove_link(&node->sysdev.kobj, kobject_name(&dev->kobj));
450} 451}
452EXPORT_SYMBOL_GPL(sysfs_remove_device_from_node);
451 453
452#else 454#else
453static void register_nodes(void) 455static void register_nodes(void)
@@ -457,9 +459,6 @@ static void register_nodes(void)
457 459
458#endif 460#endif
459 461
460EXPORT_SYMBOL_GPL(sysfs_add_device_to_node);
461EXPORT_SYMBOL_GPL(sysfs_remove_device_from_node);
462
463/* Only valid if CPU is present. */ 462/* Only valid if CPU is present. */
464static ssize_t show_physical_id(struct sys_device *dev, char *buf) 463static ssize_t show_physical_id(struct sys_device *dev, char *buf)
465{ 464{
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index 2c8564d54e4d..e5df167f7824 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -77,9 +77,8 @@
77/* keep track of when we need to update the rtc */ 77/* keep track of when we need to update the rtc */
78time_t last_rtc_update; 78time_t last_rtc_update;
79#ifdef CONFIG_PPC_ISERIES 79#ifdef CONFIG_PPC_ISERIES
80unsigned long iSeries_recal_titan = 0; 80static unsigned long __initdata iSeries_recal_titan;
81unsigned long iSeries_recal_tb = 0; 81static signed long __initdata iSeries_recal_tb;
82static unsigned long first_settimeofday = 1;
83#endif 82#endif
84 83
85/* The decrementer counts down by 128 every 128ns on a 601. */ 84/* The decrementer counts down by 128 every 128ns on a 601. */
@@ -113,8 +112,9 @@ u64 ticklen_to_xs; /* 0.64 fraction */
113DEFINE_SPINLOCK(rtc_lock); 112DEFINE_SPINLOCK(rtc_lock);
114EXPORT_SYMBOL_GPL(rtc_lock); 113EXPORT_SYMBOL_GPL(rtc_lock);
115 114
116u64 tb_to_ns_scale; 115static u64 tb_to_ns_scale __read_mostly;
117unsigned tb_to_ns_shift; 116static unsigned tb_to_ns_shift __read_mostly;
117static unsigned long boot_tb __read_mostly;
118 118
119struct gettimeofday_struct do_gtod; 119struct gettimeofday_struct do_gtod;
120 120
@@ -214,7 +214,6 @@ static void account_process_time(struct pt_regs *regs)
214 run_posix_cpu_timers(current); 214 run_posix_cpu_timers(current);
215} 215}
216 216
217#ifdef CONFIG_PPC_SPLPAR
218/* 217/*
219 * Stuff for accounting stolen time. 218 * Stuff for accounting stolen time.
220 */ 219 */
@@ -222,19 +221,28 @@ struct cpu_purr_data {
222 int initialized; /* thread is running */ 221 int initialized; /* thread is running */
223 u64 tb; /* last TB value read */ 222 u64 tb; /* last TB value read */
224 u64 purr; /* last PURR value read */ 223 u64 purr; /* last PURR value read */
225 spinlock_t lock;
226}; 224};
227 225
226/*
227 * Each entry in the cpu_purr_data array is manipulated only by its
228 * "owner" cpu -- usually in the timer interrupt but also occasionally
229 * in process context for cpu online. As long as cpus do not touch
230 * each others' cpu_purr_data, disabling local interrupts is
231 * sufficient to serialize accesses.
232 */
228static DEFINE_PER_CPU(struct cpu_purr_data, cpu_purr_data); 233static DEFINE_PER_CPU(struct cpu_purr_data, cpu_purr_data);
229 234
230static void snapshot_tb_and_purr(void *data) 235static void snapshot_tb_and_purr(void *data)
231{ 236{
237 unsigned long flags;
232 struct cpu_purr_data *p = &__get_cpu_var(cpu_purr_data); 238 struct cpu_purr_data *p = &__get_cpu_var(cpu_purr_data);
233 239
240 local_irq_save(flags);
234 p->tb = mftb(); 241 p->tb = mftb();
235 p->purr = mfspr(SPRN_PURR); 242 p->purr = mfspr(SPRN_PURR);
236 wmb(); 243 wmb();
237 p->initialized = 1; 244 p->initialized = 1;
245 local_irq_restore(flags);
238} 246}
239 247
240/* 248/*
@@ -242,15 +250,14 @@ static void snapshot_tb_and_purr(void *data)
242 */ 250 */
243void snapshot_timebases(void) 251void snapshot_timebases(void)
244{ 252{
245 int cpu;
246
247 if (!cpu_has_feature(CPU_FTR_PURR)) 253 if (!cpu_has_feature(CPU_FTR_PURR))
248 return; 254 return;
249 for_each_possible_cpu(cpu)
250 spin_lock_init(&per_cpu(cpu_purr_data, cpu).lock);
251 on_each_cpu(snapshot_tb_and_purr, NULL, 0, 1); 255 on_each_cpu(snapshot_tb_and_purr, NULL, 0, 1);
252} 256}
253 257
258/*
259 * Must be called with interrupts disabled.
260 */
254void calculate_steal_time(void) 261void calculate_steal_time(void)
255{ 262{
256 u64 tb, purr; 263 u64 tb, purr;
@@ -262,7 +269,6 @@ void calculate_steal_time(void)
262 pme = &per_cpu(cpu_purr_data, smp_processor_id()); 269 pme = &per_cpu(cpu_purr_data, smp_processor_id());
263 if (!pme->initialized) 270 if (!pme->initialized)
264 return; /* this can happen in early boot */ 271 return; /* this can happen in early boot */
265 spin_lock(&pme->lock);
266 tb = mftb(); 272 tb = mftb();
267 purr = mfspr(SPRN_PURR); 273 purr = mfspr(SPRN_PURR);
268 stolen = (tb - pme->tb) - (purr - pme->purr); 274 stolen = (tb - pme->tb) - (purr - pme->purr);
@@ -270,9 +276,9 @@ void calculate_steal_time(void)
270 account_steal_time(current, stolen); 276 account_steal_time(current, stolen);
271 pme->tb = tb; 277 pme->tb = tb;
272 pme->purr = purr; 278 pme->purr = purr;
273 spin_unlock(&pme->lock);
274} 279}
275 280
281#ifdef CONFIG_PPC_SPLPAR
276/* 282/*
277 * Must be called before the cpu is added to the online map when 283 * Must be called before the cpu is added to the online map when
278 * a cpu is being brought up at runtime. 284 * a cpu is being brought up at runtime.
@@ -284,12 +290,12 @@ static void snapshot_purr(void)
284 290
285 if (!cpu_has_feature(CPU_FTR_PURR)) 291 if (!cpu_has_feature(CPU_FTR_PURR))
286 return; 292 return;
293 local_irq_save(flags);
287 pme = &per_cpu(cpu_purr_data, smp_processor_id()); 294 pme = &per_cpu(cpu_purr_data, smp_processor_id());
288 spin_lock_irqsave(&pme->lock, flags);
289 pme->tb = mftb(); 295 pme->tb = mftb();
290 pme->purr = mfspr(SPRN_PURR); 296 pme->purr = mfspr(SPRN_PURR);
291 pme->initialized = 1; 297 pme->initialized = 1;
292 spin_unlock_irqrestore(&pme->lock, flags); 298 local_irq_restore(flags);
293} 299}
294 300
295#endif /* CONFIG_PPC_SPLPAR */ 301#endif /* CONFIG_PPC_SPLPAR */
@@ -550,10 +556,15 @@ EXPORT_SYMBOL(profile_pc);
550 * returned by the service processor for the timebase frequency. 556 * returned by the service processor for the timebase frequency.
551 */ 557 */
552 558
553static void iSeries_tb_recal(void) 559static int __init iSeries_tb_recal(void)
554{ 560{
555 struct div_result divres; 561 struct div_result divres;
556 unsigned long titan, tb; 562 unsigned long titan, tb;
563
564 /* Make sure we only run on iSeries */
565 if (!firmware_has_feature(FW_FEATURE_ISERIES))
566 return -ENODEV;
567
557 tb = get_tb(); 568 tb = get_tb();
558 titan = HvCallXm_loadTod(); 569 titan = HvCallXm_loadTod();
559 if ( iSeries_recal_titan ) { 570 if ( iSeries_recal_titan ) {
@@ -594,8 +605,18 @@ static void iSeries_tb_recal(void)
594 } 605 }
595 iSeries_recal_titan = titan; 606 iSeries_recal_titan = titan;
596 iSeries_recal_tb = tb; 607 iSeries_recal_tb = tb;
608
609 return 0;
597} 610}
598#endif 611late_initcall(iSeries_tb_recal);
612
613/* Called from platform early init */
614void __init iSeries_time_init_early(void)
615{
616 iSeries_recal_tb = get_tb();
617 iSeries_recal_titan = HvCallXm_loadTod();
618}
619#endif /* CONFIG_PPC_ISERIES */
599 620
600/* 621/*
601 * For iSeries shared processors, we have to let the hypervisor 622 * For iSeries shared processors, we have to let the hypervisor
@@ -735,7 +756,7 @@ unsigned long long sched_clock(void)
735{ 756{
736 if (__USE_RTC()) 757 if (__USE_RTC())
737 return get_rtc(); 758 return get_rtc();
738 return mulhdu(get_tb(), tb_to_ns_scale) << tb_to_ns_shift; 759 return mulhdu(get_tb() - boot_tb, tb_to_ns_scale) << tb_to_ns_shift;
739} 760}
740 761
741int do_settimeofday(struct timespec *tv) 762int do_settimeofday(struct timespec *tv)
@@ -759,12 +780,6 @@ int do_settimeofday(struct timespec *tv)
759 * to the RTC again, or write to the RTC but then they don't call 780 * to the RTC again, or write to the RTC but then they don't call
760 * settimeofday to perform this operation. 781 * settimeofday to perform this operation.
761 */ 782 */
762#ifdef CONFIG_PPC_ISERIES
763 if (firmware_has_feature(FW_FEATURE_ISERIES) && first_settimeofday) {
764 iSeries_tb_recal();
765 first_settimeofday = 0;
766 }
767#endif
768 783
769 /* Make userspace gettimeofday spin until we're done. */ 784 /* Make userspace gettimeofday spin until we're done. */
770 ++vdso_data->tb_update_count; 785 ++vdso_data->tb_update_count;
@@ -960,6 +975,8 @@ void __init time_init(void)
960 } 975 }
961 tb_to_ns_scale = scale; 976 tb_to_ns_scale = scale;
962 tb_to_ns_shift = shift; 977 tb_to_ns_shift = shift;
978 /* Save the current timebase to pretty up CONFIG_PRINTK_TIME */
979 boot_tb = get_tb();
963 980
964 tm = get_boot_time(); 981 tm = get_boot_time();
965 982
diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c
index 4245579edb4e..cef01e4e8989 100644
--- a/arch/powerpc/kernel/vdso.c
+++ b/arch/powerpc/kernel/vdso.c
@@ -670,7 +670,7 @@ static int __init vdso_init(void)
670 /* 670 /*
671 * Fill up the "systemcfg" stuff for backward compatiblity 671 * Fill up the "systemcfg" stuff for backward compatiblity
672 */ 672 */
673 strcpy(vdso_data->eye_catcher, "SYSTEMCFG:PPC64"); 673 strcpy((char *)vdso_data->eye_catcher, "SYSTEMCFG:PPC64");
674 vdso_data->version.major = SYSTEMCFG_MAJOR; 674 vdso_data->version.major = SYSTEMCFG_MAJOR;
675 vdso_data->version.minor = SYSTEMCFG_MINOR; 675 vdso_data->version.minor = SYSTEMCFG_MINOR;
676 vdso_data->processor = mfspr(SPRN_PVR); 676 vdso_data->processor = mfspr(SPRN_PVR);
diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S
index 21c39ff2dc39..ae4acd84143d 100644
--- a/arch/powerpc/kernel/vmlinux.lds.S
+++ b/arch/powerpc/kernel/vmlinux.lds.S
@@ -7,6 +7,7 @@
7#define PROVIDE32(x) PROVIDE(x) 7#define PROVIDE32(x) PROVIDE(x)
8#endif 8#endif
9#include <asm-generic/vmlinux.lds.h> 9#include <asm-generic/vmlinux.lds.h>
10#include <asm/cache.h>
10 11
11ENTRY(_stext) 12ENTRY(_stext)
12 13
@@ -211,6 +212,11 @@ SECTIONS
211 *(.data.cacheline_aligned) 212 *(.data.cacheline_aligned)
212 } 213 }
213 214
215 . = ALIGN(L1_CACHE_BYTES);
216 .data.read_mostly : {
217 *(.data.read_mostly)
218 }
219
214 . = ALIGN(PAGE_SIZE); 220 . = ALIGN(PAGE_SIZE);
215 __data_nosave : { 221 __data_nosave : {
216 __nosave_begin = .; 222 __nosave_begin = .;
diff --git a/arch/powerpc/mm/44x_mmu.c b/arch/powerpc/mm/44x_mmu.c
index ca4dcb07a939..c3df50476539 100644
--- a/arch/powerpc/mm/44x_mmu.c
+++ b/arch/powerpc/mm/44x_mmu.c
@@ -12,7 +12,6 @@
12 * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au) 12 * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
13 * and Cort Dougan (PReP) (cort@cs.nmt.edu) 13 * and Cort Dougan (PReP) (cort@cs.nmt.edu)
14 * Copyright (C) 1996 Paul Mackerras 14 * Copyright (C) 1996 Paul Mackerras
15 * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
16 * 15 *
17 * Derived from "arch/i386/mm/init.c" 16 * Derived from "arch/i386/mm/init.c"
18 * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds 17 * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
diff --git a/arch/powerpc/mm/4xx_mmu.c b/arch/powerpc/mm/4xx_mmu.c
index 838e09db71d9..7ff2609b64d1 100644
--- a/arch/powerpc/mm/4xx_mmu.c
+++ b/arch/powerpc/mm/4xx_mmu.c
@@ -9,7 +9,6 @@
9 * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au) 9 * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
10 * and Cort Dougan (PReP) (cort@cs.nmt.edu) 10 * and Cort Dougan (PReP) (cort@cs.nmt.edu)
11 * Copyright (C) 1996 Paul Mackerras 11 * Copyright (C) 1996 Paul Mackerras
12 * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
13 * 12 *
14 * Derived from "arch/i386/mm/init.c" 13 * Derived from "arch/i386/mm/init.c"
15 * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds 14 * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile
index 4f839c6a9768..7e4d27ad3dee 100644
--- a/arch/powerpc/mm/Makefile
+++ b/arch/powerpc/mm/Makefile
@@ -11,8 +11,7 @@ obj-$(CONFIG_PPC32) += init_32.o pgtable_32.o mmu_context_32.o
11hash-$(CONFIG_PPC_NATIVE) := hash_native_64.o 11hash-$(CONFIG_PPC_NATIVE) := hash_native_64.o
12obj-$(CONFIG_PPC64) += init_64.o pgtable_64.o mmu_context_64.o \ 12obj-$(CONFIG_PPC64) += init_64.o pgtable_64.o mmu_context_64.o \
13 hash_utils_64.o hash_low_64.o tlb_64.o \ 13 hash_utils_64.o hash_low_64.o tlb_64.o \
14 slb_low.o slb.o stab.o mmap.o imalloc.o \ 14 slb_low.o slb.o stab.o mmap.o $(hash-y)
15 $(hash-y)
16obj-$(CONFIG_PPC_STD_MMU_32) += ppc_mmu_32.o hash_low_32.o tlb_32.o 15obj-$(CONFIG_PPC_STD_MMU_32) += ppc_mmu_32.o hash_low_32.o tlb_32.o
17obj-$(CONFIG_40x) += 4xx_mmu.o 16obj-$(CONFIG_40x) += 4xx_mmu.o
18obj-$(CONFIG_44x) += 44x_mmu.o 17obj-$(CONFIG_44x) += 44x_mmu.o
diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c
index 115b25f50bf8..0ece51310bfe 100644
--- a/arch/powerpc/mm/fault.c
+++ b/arch/powerpc/mm/fault.c
@@ -380,7 +380,7 @@ out_of_memory:
380 } 380 }
381 printk("VM: killing process %s\n", current->comm); 381 printk("VM: killing process %s\n", current->comm);
382 if (user_mode(regs)) 382 if (user_mode(regs))
383 do_exit(SIGKILL); 383 do_group_exit(SIGKILL);
384 return SIGKILL; 384 return SIGKILL;
385 385
386do_sigbus: 386do_sigbus:
diff --git a/arch/powerpc/mm/fsl_booke_mmu.c b/arch/powerpc/mm/fsl_booke_mmu.c
index 123da03ab118..afab247d472f 100644
--- a/arch/powerpc/mm/fsl_booke_mmu.c
+++ b/arch/powerpc/mm/fsl_booke_mmu.c
@@ -14,7 +14,6 @@
14 * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au) 14 * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
15 * and Cort Dougan (PReP) (cort@cs.nmt.edu) 15 * and Cort Dougan (PReP) (cort@cs.nmt.edu)
16 * Copyright (C) 1996 Paul Mackerras 16 * Copyright (C) 1996 Paul Mackerras
17 * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
18 * 17 *
19 * Derived from "arch/i386/mm/init.c" 18 * Derived from "arch/i386/mm/init.c"
20 * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds 19 * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
diff --git a/arch/powerpc/mm/hash_native_64.c b/arch/powerpc/mm/hash_native_64.c
index 4a20d890e2f4..6ba9b47e55af 100644
--- a/arch/powerpc/mm/hash_native_64.c
+++ b/arch/powerpc/mm/hash_native_64.c
@@ -104,7 +104,7 @@ static inline void tlbie(unsigned long va, int psize, int local)
104 spin_unlock(&native_tlbie_lock); 104 spin_unlock(&native_tlbie_lock);
105} 105}
106 106
107static inline void native_lock_hpte(hpte_t *hptep) 107static inline void native_lock_hpte(struct hash_pte *hptep)
108{ 108{
109 unsigned long *word = &hptep->v; 109 unsigned long *word = &hptep->v;
110 110
@@ -116,7 +116,7 @@ static inline void native_lock_hpte(hpte_t *hptep)
116 } 116 }
117} 117}
118 118
119static inline void native_unlock_hpte(hpte_t *hptep) 119static inline void native_unlock_hpte(struct hash_pte *hptep)
120{ 120{
121 unsigned long *word = &hptep->v; 121 unsigned long *word = &hptep->v;
122 122
@@ -128,7 +128,7 @@ static long native_hpte_insert(unsigned long hpte_group, unsigned long va,
128 unsigned long pa, unsigned long rflags, 128 unsigned long pa, unsigned long rflags,
129 unsigned long vflags, int psize) 129 unsigned long vflags, int psize)
130{ 130{
131 hpte_t *hptep = htab_address + hpte_group; 131 struct hash_pte *hptep = htab_address + hpte_group;
132 unsigned long hpte_v, hpte_r; 132 unsigned long hpte_v, hpte_r;
133 int i; 133 int i;
134 134
@@ -163,7 +163,7 @@ static long native_hpte_insert(unsigned long hpte_group, unsigned long va,
163 163
164 hptep->r = hpte_r; 164 hptep->r = hpte_r;
165 /* Guarantee the second dword is visible before the valid bit */ 165 /* Guarantee the second dword is visible before the valid bit */
166 __asm__ __volatile__ ("eieio" : : : "memory"); 166 eieio();
167 /* 167 /*
168 * Now set the first dword including the valid bit 168 * Now set the first dword including the valid bit
169 * NOTE: this also unlocks the hpte 169 * NOTE: this also unlocks the hpte
@@ -177,7 +177,7 @@ static long native_hpte_insert(unsigned long hpte_group, unsigned long va,
177 177
178static long native_hpte_remove(unsigned long hpte_group) 178static long native_hpte_remove(unsigned long hpte_group)
179{ 179{
180 hpte_t *hptep; 180 struct hash_pte *hptep;
181 int i; 181 int i;
182 int slot_offset; 182 int slot_offset;
183 unsigned long hpte_v; 183 unsigned long hpte_v;
@@ -217,7 +217,7 @@ static long native_hpte_remove(unsigned long hpte_group)
217static long native_hpte_updatepp(unsigned long slot, unsigned long newpp, 217static long native_hpte_updatepp(unsigned long slot, unsigned long newpp,
218 unsigned long va, int psize, int local) 218 unsigned long va, int psize, int local)
219{ 219{
220 hpte_t *hptep = htab_address + slot; 220 struct hash_pte *hptep = htab_address + slot;
221 unsigned long hpte_v, want_v; 221 unsigned long hpte_v, want_v;
222 int ret = 0; 222 int ret = 0;
223 223
@@ -233,15 +233,14 @@ static long native_hpte_updatepp(unsigned long slot, unsigned long newpp,
233 /* Even if we miss, we need to invalidate the TLB */ 233 /* Even if we miss, we need to invalidate the TLB */
234 if (!HPTE_V_COMPARE(hpte_v, want_v) || !(hpte_v & HPTE_V_VALID)) { 234 if (!HPTE_V_COMPARE(hpte_v, want_v) || !(hpte_v & HPTE_V_VALID)) {
235 DBG_LOW(" -> miss\n"); 235 DBG_LOW(" -> miss\n");
236 native_unlock_hpte(hptep);
237 ret = -1; 236 ret = -1;
238 } else { 237 } else {
239 DBG_LOW(" -> hit\n"); 238 DBG_LOW(" -> hit\n");
240 /* Update the HPTE */ 239 /* Update the HPTE */
241 hptep->r = (hptep->r & ~(HPTE_R_PP | HPTE_R_N)) | 240 hptep->r = (hptep->r & ~(HPTE_R_PP | HPTE_R_N)) |
242 (newpp & (HPTE_R_PP | HPTE_R_N | HPTE_R_C)); 241 (newpp & (HPTE_R_PP | HPTE_R_N | HPTE_R_C));
243 native_unlock_hpte(hptep);
244 } 242 }
243 native_unlock_hpte(hptep);
245 244
246 /* Ensure it is out of the tlb too. */ 245 /* Ensure it is out of the tlb too. */
247 tlbie(va, psize, local); 246 tlbie(va, psize, local);
@@ -251,7 +250,7 @@ static long native_hpte_updatepp(unsigned long slot, unsigned long newpp,
251 250
252static long native_hpte_find(unsigned long va, int psize) 251static long native_hpte_find(unsigned long va, int psize)
253{ 252{
254 hpte_t *hptep; 253 struct hash_pte *hptep;
255 unsigned long hash; 254 unsigned long hash;
256 unsigned long i, j; 255 unsigned long i, j;
257 long slot; 256 long slot;
@@ -294,7 +293,7 @@ static void native_hpte_updateboltedpp(unsigned long newpp, unsigned long ea,
294{ 293{
295 unsigned long vsid, va; 294 unsigned long vsid, va;
296 long slot; 295 long slot;
297 hpte_t *hptep; 296 struct hash_pte *hptep;
298 297
299 vsid = get_kernel_vsid(ea); 298 vsid = get_kernel_vsid(ea);
300 va = (vsid << 28) | (ea & 0x0fffffff); 299 va = (vsid << 28) | (ea & 0x0fffffff);
@@ -315,7 +314,7 @@ static void native_hpte_updateboltedpp(unsigned long newpp, unsigned long ea,
315static void native_hpte_invalidate(unsigned long slot, unsigned long va, 314static void native_hpte_invalidate(unsigned long slot, unsigned long va,
316 int psize, int local) 315 int psize, int local)
317{ 316{
318 hpte_t *hptep = htab_address + slot; 317 struct hash_pte *hptep = htab_address + slot;
319 unsigned long hpte_v; 318 unsigned long hpte_v;
320 unsigned long want_v; 319 unsigned long want_v;
321 unsigned long flags; 320 unsigned long flags;
@@ -345,7 +344,7 @@ static void native_hpte_invalidate(unsigned long slot, unsigned long va,
345#define LP_BITS 8 344#define LP_BITS 8
346#define LP_MASK(i) ((0xFF >> (i)) << LP_SHIFT) 345#define LP_MASK(i) ((0xFF >> (i)) << LP_SHIFT)
347 346
348static void hpte_decode(hpte_t *hpte, unsigned long slot, 347static void hpte_decode(struct hash_pte *hpte, unsigned long slot,
349 int *psize, unsigned long *va) 348 int *psize, unsigned long *va)
350{ 349{
351 unsigned long hpte_r = hpte->r; 350 unsigned long hpte_r = hpte->r;
@@ -415,7 +414,7 @@ static void hpte_decode(hpte_t *hpte, unsigned long slot,
415static void native_hpte_clear(void) 414static void native_hpte_clear(void)
416{ 415{
417 unsigned long slot, slots, flags; 416 unsigned long slot, slots, flags;
418 hpte_t *hptep = htab_address; 417 struct hash_pte *hptep = htab_address;
419 unsigned long hpte_v, va; 418 unsigned long hpte_v, va;
420 unsigned long pteg_count; 419 unsigned long pteg_count;
421 int psize; 420 int psize;
@@ -462,7 +461,7 @@ static void native_hpte_clear(void)
462static void native_flush_hash_range(unsigned long number, int local) 461static void native_flush_hash_range(unsigned long number, int local)
463{ 462{
464 unsigned long va, hash, index, hidx, shift, slot; 463 unsigned long va, hash, index, hidx, shift, slot;
465 hpte_t *hptep; 464 struct hash_pte *hptep;
466 unsigned long hpte_v; 465 unsigned long hpte_v;
467 unsigned long want_v; 466 unsigned long want_v;
468 unsigned long flags; 467 unsigned long flags;
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
index 4f2f4534a9d8..2ce9491b48d4 100644
--- a/arch/powerpc/mm/hash_utils_64.c
+++ b/arch/powerpc/mm/hash_utils_64.c
@@ -87,7 +87,7 @@ extern unsigned long dart_tablebase;
87static unsigned long _SDR1; 87static unsigned long _SDR1;
88struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT]; 88struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT];
89 89
90hpte_t *htab_address; 90struct hash_pte *htab_address;
91unsigned long htab_size_bytes; 91unsigned long htab_size_bytes;
92unsigned long htab_hash_mask; 92unsigned long htab_hash_mask;
93int mmu_linear_psize = MMU_PAGE_4K; 93int mmu_linear_psize = MMU_PAGE_4K;
diff --git a/arch/powerpc/mm/imalloc.c b/arch/powerpc/mm/imalloc.c
deleted file mode 100644
index c831815c31f0..000000000000
--- a/arch/powerpc/mm/imalloc.c
+++ /dev/null
@@ -1,313 +0,0 @@
1/*
2 * c 2001 PPC 64 Team, IBM Corp
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 */
9
10#include <linux/slab.h>
11#include <linux/vmalloc.h>
12
13#include <asm/uaccess.h>
14#include <asm/pgalloc.h>
15#include <asm/pgtable.h>
16#include <linux/mutex.h>
17#include <asm/cacheflush.h>
18
19#include "mmu_decl.h"
20
21static DEFINE_MUTEX(imlist_mutex);
22struct vm_struct * imlist = NULL;
23
24static int get_free_im_addr(unsigned long size, unsigned long *im_addr)
25{
26 unsigned long addr;
27 struct vm_struct **p, *tmp;
28
29 addr = ioremap_bot;
30 for (p = &imlist; (tmp = *p) ; p = &tmp->next) {
31 if (size + addr < (unsigned long) tmp->addr)
32 break;
33 if ((unsigned long)tmp->addr >= ioremap_bot)
34 addr = tmp->size + (unsigned long) tmp->addr;
35 if (addr >= IMALLOC_END-size)
36 return 1;
37 }
38 *im_addr = addr;
39
40 return 0;
41}
42
43/* Return whether the region described by v_addr and size is a subset
44 * of the region described by parent
45 */
46static inline int im_region_is_subset(unsigned long v_addr, unsigned long size,
47 struct vm_struct *parent)
48{
49 return (int) (v_addr >= (unsigned long) parent->addr &&
50 v_addr < (unsigned long) parent->addr + parent->size &&
51 size < parent->size);
52}
53
54/* Return whether the region described by v_addr and size is a superset
55 * of the region described by child
56 */
57static int im_region_is_superset(unsigned long v_addr, unsigned long size,
58 struct vm_struct *child)
59{
60 struct vm_struct parent;
61
62 parent.addr = (void *) v_addr;
63 parent.size = size;
64
65 return im_region_is_subset((unsigned long) child->addr, child->size,
66 &parent);
67}
68
69/* Return whether the region described by v_addr and size overlaps
70 * the region described by vm. Overlapping regions meet the
71 * following conditions:
72 * 1) The regions share some part of the address space
73 * 2) The regions aren't identical
74 * 3) Neither region is a subset of the other
75 */
76static int im_region_overlaps(unsigned long v_addr, unsigned long size,
77 struct vm_struct *vm)
78{
79 if (im_region_is_superset(v_addr, size, vm))
80 return 0;
81
82 return (v_addr + size > (unsigned long) vm->addr + vm->size &&
83 v_addr < (unsigned long) vm->addr + vm->size) ||
84 (v_addr < (unsigned long) vm->addr &&
85 v_addr + size > (unsigned long) vm->addr);
86}
87
88/* Determine imalloc status of region described by v_addr and size.
89 * Can return one of the following:
90 * IM_REGION_UNUSED - Entire region is unallocated in imalloc space.
91 * IM_REGION_SUBSET - Region is a subset of a region that is already
92 * allocated in imalloc space.
93 * vm will be assigned to a ptr to the parent region.
94 * IM_REGION_EXISTS - Exact region already allocated in imalloc space.
95 * vm will be assigned to a ptr to the existing imlist
96 * member.
97 * IM_REGION_OVERLAPS - Region overlaps an allocated region in imalloc space.
98 * IM_REGION_SUPERSET - Region is a superset of a region that is already
99 * allocated in imalloc space.
100 */
101static int im_region_status(unsigned long v_addr, unsigned long size,
102 struct vm_struct **vm)
103{
104 struct vm_struct *tmp;
105
106 for (tmp = imlist; tmp; tmp = tmp->next)
107 if (v_addr < (unsigned long) tmp->addr + tmp->size)
108 break;
109
110 *vm = NULL;
111 if (tmp) {
112 if (im_region_overlaps(v_addr, size, tmp))
113 return IM_REGION_OVERLAP;
114
115 *vm = tmp;
116 if (im_region_is_subset(v_addr, size, tmp)) {
117 /* Return with tmp pointing to superset */
118 return IM_REGION_SUBSET;
119 }
120 if (im_region_is_superset(v_addr, size, tmp)) {
121 /* Return with tmp pointing to first subset */
122 return IM_REGION_SUPERSET;
123 }
124 else if (v_addr == (unsigned long) tmp->addr &&
125 size == tmp->size) {
126 /* Return with tmp pointing to exact region */
127 return IM_REGION_EXISTS;
128 }
129 }
130
131 return IM_REGION_UNUSED;
132}
133
134static struct vm_struct * split_im_region(unsigned long v_addr,
135 unsigned long size, struct vm_struct *parent)
136{
137 struct vm_struct *vm1 = NULL;
138 struct vm_struct *vm2 = NULL;
139 struct vm_struct *new_vm = NULL;
140
141 vm1 = kmalloc(sizeof(*vm1), GFP_KERNEL);
142 if (vm1 == NULL) {
143 printk(KERN_ERR "%s() out of memory\n", __FUNCTION__);
144 return NULL;
145 }
146
147 if (v_addr == (unsigned long) parent->addr) {
148 /* Use existing parent vm_struct to represent child, allocate
149 * new one for the remainder of parent range
150 */
151 vm1->size = parent->size - size;
152 vm1->addr = (void *) (v_addr + size);
153 vm1->next = parent->next;
154
155 parent->size = size;
156 parent->next = vm1;
157 new_vm = parent;
158 } else if (v_addr + size == (unsigned long) parent->addr +
159 parent->size) {
160 /* Allocate new vm_struct to represent child, use existing
161 * parent one for remainder of parent range
162 */
163 vm1->size = size;
164 vm1->addr = (void *) v_addr;
165 vm1->next = parent->next;
166 new_vm = vm1;
167
168 parent->size -= size;
169 parent->next = vm1;
170 } else {
171 /* Allocate two new vm_structs for the new child and
172 * uppermost remainder, and use existing parent one for the
173 * lower remainder of parent range
174 */
175 vm2 = kmalloc(sizeof(*vm2), GFP_KERNEL);
176 if (vm2 == NULL) {
177 printk(KERN_ERR "%s() out of memory\n", __FUNCTION__);
178 kfree(vm1);
179 return NULL;
180 }
181
182 vm1->size = size;
183 vm1->addr = (void *) v_addr;
184 vm1->next = vm2;
185 new_vm = vm1;
186
187 vm2->size = ((unsigned long) parent->addr + parent->size) -
188 (v_addr + size);
189 vm2->addr = (void *) v_addr + size;
190 vm2->next = parent->next;
191
192 parent->size = v_addr - (unsigned long) parent->addr;
193 parent->next = vm1;
194 }
195
196 return new_vm;
197}
198
199static struct vm_struct * __add_new_im_area(unsigned long req_addr,
200 unsigned long size)
201{
202 struct vm_struct **p, *tmp, *area;
203
204 for (p = &imlist; (tmp = *p) ; p = &tmp->next) {
205 if (req_addr + size <= (unsigned long)tmp->addr)
206 break;
207 }
208
209 area = kmalloc(sizeof(*area), GFP_KERNEL);
210 if (!area)
211 return NULL;
212 area->flags = 0;
213 area->addr = (void *)req_addr;
214 area->size = size;
215 area->next = *p;
216 *p = area;
217
218 return area;
219}
220
221static struct vm_struct * __im_get_area(unsigned long req_addr,
222 unsigned long size,
223 int criteria)
224{
225 struct vm_struct *tmp;
226 int status;
227
228 status = im_region_status(req_addr, size, &tmp);
229 if ((criteria & status) == 0) {
230 return NULL;
231 }
232
233 switch (status) {
234 case IM_REGION_UNUSED:
235 tmp = __add_new_im_area(req_addr, size);
236 break;
237 case IM_REGION_SUBSET:
238 tmp = split_im_region(req_addr, size, tmp);
239 break;
240 case IM_REGION_EXISTS:
241 /* Return requested region */
242 break;
243 case IM_REGION_SUPERSET:
244 /* Return first existing subset of requested region */
245 break;
246 default:
247 printk(KERN_ERR "%s() unexpected imalloc region status\n",
248 __FUNCTION__);
249 tmp = NULL;
250 }
251
252 return tmp;
253}
254
255struct vm_struct * im_get_free_area(unsigned long size)
256{
257 struct vm_struct *area;
258 unsigned long addr;
259
260 mutex_lock(&imlist_mutex);
261 if (get_free_im_addr(size, &addr)) {
262 printk(KERN_ERR "%s() cannot obtain addr for size 0x%lx\n",
263 __FUNCTION__, size);
264 area = NULL;
265 goto next_im_done;
266 }
267
268 area = __im_get_area(addr, size, IM_REGION_UNUSED);
269 if (area == NULL) {
270 printk(KERN_ERR
271 "%s() cannot obtain area for addr 0x%lx size 0x%lx\n",
272 __FUNCTION__, addr, size);
273 }
274next_im_done:
275 mutex_unlock(&imlist_mutex);
276 return area;
277}
278
279struct vm_struct * im_get_area(unsigned long v_addr, unsigned long size,
280 int criteria)
281{
282 struct vm_struct *area;
283
284 mutex_lock(&imlist_mutex);
285 area = __im_get_area(v_addr, size, criteria);
286 mutex_unlock(&imlist_mutex);
287 return area;
288}
289
290void im_free(void * addr)
291{
292 struct vm_struct **p, *tmp;
293
294 if (!addr)
295 return;
296 if ((unsigned long) addr & ~PAGE_MASK) {
297 printk(KERN_ERR "Trying to %s bad address (%p)\n", __FUNCTION__, addr);
298 return;
299 }
300 mutex_lock(&imlist_mutex);
301 for (p = &imlist ; (tmp = *p) ; p = &tmp->next) {
302 if (tmp->addr == addr) {
303 *p = tmp->next;
304 unmap_vm_area(tmp);
305 kfree(tmp);
306 mutex_unlock(&imlist_mutex);
307 return;
308 }
309 }
310 mutex_unlock(&imlist_mutex);
311 printk(KERN_ERR "Trying to %s nonexistent area (%p)\n", __FUNCTION__,
312 addr);
313}
diff --git a/arch/powerpc/mm/init_32.c b/arch/powerpc/mm/init_32.c
index 5fce6ccecb8d..e1f5ded851f6 100644
--- a/arch/powerpc/mm/init_32.c
+++ b/arch/powerpc/mm/init_32.c
@@ -5,7 +5,6 @@
5 * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au) 5 * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
6 * and Cort Dougan (PReP) (cort@cs.nmt.edu) 6 * and Cort Dougan (PReP) (cort@cs.nmt.edu)
7 * Copyright (C) 1996 Paul Mackerras 7 * Copyright (C) 1996 Paul Mackerras
8 * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
9 * PPC44x/36-bit changes by Matt Porter (mporter@mvista.com) 8 * PPC44x/36-bit changes by Matt Porter (mporter@mvista.com)
10 * 9 *
11 * Derived from "arch/i386/mm/init.c" 10 * Derived from "arch/i386/mm/init.c"
diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c
index 7312a265545f..1d6edf724c85 100644
--- a/arch/powerpc/mm/init_64.c
+++ b/arch/powerpc/mm/init_64.c
@@ -5,7 +5,6 @@
5 * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au) 5 * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
6 * and Cort Dougan (PReP) (cort@cs.nmt.edu) 6 * and Cort Dougan (PReP) (cort@cs.nmt.edu)
7 * Copyright (C) 1996 Paul Mackerras 7 * Copyright (C) 1996 Paul Mackerras
8 * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
9 * 8 *
10 * Derived from "arch/i386/mm/init.c" 9 * Derived from "arch/i386/mm/init.c"
11 * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds 10 * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index 0266a94d83b6..f0e7eedb1ba3 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -5,7 +5,6 @@
5 * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au) 5 * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
6 * and Cort Dougan (PReP) (cort@cs.nmt.edu) 6 * and Cort Dougan (PReP) (cort@cs.nmt.edu)
7 * Copyright (C) 1996 Paul Mackerras 7 * Copyright (C) 1996 Paul Mackerras
8 * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
9 * PPC44x/36-bit changes by Matt Porter (mporter@mvista.com) 8 * PPC44x/36-bit changes by Matt Porter (mporter@mvista.com)
10 * 9 *
11 * Derived from "arch/i386/mm/init.c" 10 * Derived from "arch/i386/mm/init.c"
@@ -129,8 +128,6 @@ int __devinit arch_add_memory(int nid, u64 start, u64 size)
129 zone = pgdata->node_zones; 128 zone = pgdata->node_zones;
130 129
131 return __add_pages(zone, start_pfn, nr_pages); 130 return __add_pages(zone, start_pfn, nr_pages);
132
133 return 0;
134} 131}
135 132
136/* 133/*
diff --git a/arch/powerpc/mm/mmu_context_32.c b/arch/powerpc/mm/mmu_context_32.c
index 792086b01000..cc32ba41d900 100644
--- a/arch/powerpc/mm/mmu_context_32.c
+++ b/arch/powerpc/mm/mmu_context_32.c
@@ -11,7 +11,6 @@
11 * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au) 11 * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
12 * and Cort Dougan (PReP) (cort@cs.nmt.edu) 12 * and Cort Dougan (PReP) (cort@cs.nmt.edu)
13 * Copyright (C) 1996 Paul Mackerras 13 * Copyright (C) 1996 Paul Mackerras
14 * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
15 * 14 *
16 * Derived from "arch/i386/mm/init.c" 15 * Derived from "arch/i386/mm/init.c"
17 * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds 16 * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h
index 2558c34eedaa..c94a64fd3c01 100644
--- a/arch/powerpc/mm/mmu_decl.h
+++ b/arch/powerpc/mm/mmu_decl.h
@@ -8,7 +8,6 @@
8 * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au) 8 * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
9 * and Cort Dougan (PReP) (cort@cs.nmt.edu) 9 * and Cort Dougan (PReP) (cort@cs.nmt.edu)
10 * Copyright (C) 1996 Paul Mackerras 10 * Copyright (C) 1996 Paul Mackerras
11 * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
12 * 11 *
13 * Derived from "arch/i386/mm/init.c" 12 * Derived from "arch/i386/mm/init.c"
14 * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds 13 * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
@@ -40,8 +39,8 @@ extern int __map_without_bats;
40extern unsigned long ioremap_base; 39extern unsigned long ioremap_base;
41extern unsigned int rtas_data, rtas_size; 40extern unsigned int rtas_data, rtas_size;
42 41
43struct _PTE; 42struct hash_pte;
44extern struct _PTE *Hash, *Hash_end; 43extern struct hash_pte *Hash, *Hash_end;
45extern unsigned long Hash_size, Hash_mask; 44extern unsigned long Hash_size, Hash_mask;
46 45
47extern unsigned int num_tlbcam_entries; 46extern unsigned int num_tlbcam_entries;
@@ -90,16 +89,4 @@ static inline void flush_HPTE(unsigned context, unsigned long va,
90 else 89 else
91 _tlbie(va); 90 _tlbie(va);
92} 91}
93#else /* CONFIG_PPC64 */
94/* imalloc region types */
95#define IM_REGION_UNUSED 0x1
96#define IM_REGION_SUBSET 0x2
97#define IM_REGION_EXISTS 0x4
98#define IM_REGION_OVERLAP 0x8
99#define IM_REGION_SUPERSET 0x10
100
101extern struct vm_struct * im_get_free_area(unsigned long size);
102extern struct vm_struct * im_get_area(unsigned long v_addr, unsigned long size,
103 int region_type);
104extern void im_free(void *addr);
105#endif 92#endif
diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
index f6ae1a57d652..64488723162a 100644
--- a/arch/powerpc/mm/pgtable_32.c
+++ b/arch/powerpc/mm/pgtable_32.c
@@ -8,7 +8,6 @@
8 * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au) 8 * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
9 * and Cort Dougan (PReP) (cort@cs.nmt.edu) 9 * and Cort Dougan (PReP) (cort@cs.nmt.edu)
10 * Copyright (C) 1996 Paul Mackerras 10 * Copyright (C) 1996 Paul Mackerras
11 * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
12 * 11 *
13 * Derived from "arch/i386/mm/init.c" 12 * Derived from "arch/i386/mm/init.c"
14 * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds 13 * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
@@ -37,7 +36,6 @@
37unsigned long ioremap_base; 36unsigned long ioremap_base;
38unsigned long ioremap_bot; 37unsigned long ioremap_bot;
39EXPORT_SYMBOL(ioremap_bot); /* aka VMALLOC_END */ 38EXPORT_SYMBOL(ioremap_bot); /* aka VMALLOC_END */
40int io_bat_index;
41 39
42#if defined(CONFIG_6xx) || defined(CONFIG_POWER3) 40#if defined(CONFIG_6xx) || defined(CONFIG_POWER3)
43#define HAVE_BATS 1 41#define HAVE_BATS 1
@@ -300,51 +298,6 @@ void __init mapin_ram(void)
300 } 298 }
301} 299}
302 300
303/* is x a power of 4? */
304#define is_power_of_4(x) is_power_of_2(x) && (ffs(x) & 1)
305
306/*
307 * Set up a mapping for a block of I/O.
308 * virt, phys, size must all be page-aligned.
309 * This should only be called before ioremap is called.
310 */
311void __init io_block_mapping(unsigned long virt, phys_addr_t phys,
312 unsigned int size, int flags)
313{
314 int i;
315
316 if (virt > KERNELBASE && virt < ioremap_bot)
317 ioremap_bot = ioremap_base = virt;
318
319#ifdef HAVE_BATS
320 /*
321 * Use a BAT for this if possible...
322 */
323 if (io_bat_index < 2 && is_power_of_2(size)
324 && (virt & (size - 1)) == 0 && (phys & (size - 1)) == 0) {
325 setbat(io_bat_index, virt, phys, size, flags);
326 ++io_bat_index;
327 return;
328 }
329#endif /* HAVE_BATS */
330
331#ifdef HAVE_TLBCAM
332 /*
333 * Use a CAM for this if possible...
334 */
335 if (tlbcam_index < num_tlbcam_entries && is_power_of_4(size)
336 && (virt & (size - 1)) == 0 && (phys & (size - 1)) == 0) {
337 settlbcam(tlbcam_index, virt, phys, size, flags, 0);
338 ++tlbcam_index;
339 return;
340 }
341#endif /* HAVE_TLBCAM */
342
343 /* No BATs available, put it in the page tables. */
344 for (i = 0; i < size; i += PAGE_SIZE)
345 map_page(virt + i, phys + i, flags);
346}
347
348/* Scan the real Linux page tables and return a PTE pointer for 301/* Scan the real Linux page tables and return a PTE pointer for
349 * a virtual address in a context. 302 * a virtual address in a context.
350 * Returns true (1) if PTE was found, zero otherwise. The pointer to 303 * Returns true (1) if PTE was found, zero otherwise. The pointer to
@@ -379,82 +332,6 @@ get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep, pmd_t **pmdp)
379 return(retval); 332 return(retval);
380} 333}
381 334
382/* Find physical address for this virtual address. Normally used by
383 * I/O functions, but anyone can call it.
384 */
385unsigned long iopa(unsigned long addr)
386{
387 unsigned long pa;
388
389 /* I don't know why this won't work on PMacs or CHRP. It
390 * appears there is some bug, or there is some implicit
391 * mapping done not properly represented by BATs or in page
392 * tables.......I am actively working on resolving this, but
393 * can't hold up other stuff. -- Dan
394 */
395 pte_t *pte;
396 struct mm_struct *mm;
397
398 /* Check the BATs */
399 pa = v_mapped_by_bats(addr);
400 if (pa)
401 return pa;
402
403 /* Allow mapping of user addresses (within the thread)
404 * for DMA if necessary.
405 */
406 if (addr < TASK_SIZE)
407 mm = current->mm;
408 else
409 mm = &init_mm;
410
411 pa = 0;
412 if (get_pteptr(mm, addr, &pte, NULL)) {
413 pa = (pte_val(*pte) & PAGE_MASK) | (addr & ~PAGE_MASK);
414 pte_unmap(pte);
415 }
416
417 return(pa);
418}
419
420/* This is will find the virtual address for a physical one....
421 * Swiped from APUS, could be dangerous :-).
422 * This is only a placeholder until I really find a way to make this
423 * work. -- Dan
424 */
425unsigned long
426mm_ptov (unsigned long paddr)
427{
428 unsigned long ret;
429#if 0
430 if (paddr < 16*1024*1024)
431 ret = ZTWO_VADDR(paddr);
432 else {
433 int i;
434
435 for (i = 0; i < kmap_chunk_count;){
436 unsigned long phys = kmap_chunks[i++];
437 unsigned long size = kmap_chunks[i++];
438 unsigned long virt = kmap_chunks[i++];
439 if (paddr >= phys
440 && paddr < (phys + size)){
441 ret = virt + paddr - phys;
442 goto exit;
443 }
444 }
445
446 ret = (unsigned long) __va(paddr);
447 }
448exit:
449#ifdef DEBUGPV
450 printk ("PTOV(%lx)=%lx\n", paddr, ret);
451#endif
452#else
453 ret = (unsigned long)paddr + KERNELBASE;
454#endif
455 return ret;
456}
457
458#ifdef CONFIG_DEBUG_PAGEALLOC 335#ifdef CONFIG_DEBUG_PAGEALLOC
459 336
460static int __change_page_attr(struct page *page, pgprot_t prot) 337static int __change_page_attr(struct page *page, pgprot_t prot)
diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c
index ad6e135bf212..3dfd10db931a 100644
--- a/arch/powerpc/mm/pgtable_64.c
+++ b/arch/powerpc/mm/pgtable_64.c
@@ -7,7 +7,6 @@
7 * Modifications by Paul Mackerras (PowerMac) (paulus@samba.org) 7 * Modifications by Paul Mackerras (PowerMac) (paulus@samba.org)
8 * and Cort Dougan (PReP) (cort@cs.nmt.edu) 8 * and Cort Dougan (PReP) (cort@cs.nmt.edu)
9 * Copyright (C) 1996 Paul Mackerras 9 * Copyright (C) 1996 Paul Mackerras
10 * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
11 * 10 *
12 * Derived from "arch/i386/mm/init.c" 11 * Derived from "arch/i386/mm/init.c"
13 * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds 12 * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
@@ -34,41 +33,27 @@
34#include <linux/stddef.h> 33#include <linux/stddef.h>
35#include <linux/vmalloc.h> 34#include <linux/vmalloc.h>
36#include <linux/init.h> 35#include <linux/init.h>
37#include <linux/delay.h>
38#include <linux/bootmem.h>
39#include <linux/highmem.h>
40#include <linux/idr.h>
41#include <linux/nodemask.h>
42#include <linux/module.h>
43 36
44#include <asm/pgalloc.h> 37#include <asm/pgalloc.h>
45#include <asm/page.h> 38#include <asm/page.h>
46#include <asm/prom.h> 39#include <asm/prom.h>
47#include <asm/lmb.h>
48#include <asm/rtas.h>
49#include <asm/io.h> 40#include <asm/io.h>
50#include <asm/mmu_context.h> 41#include <asm/mmu_context.h>
51#include <asm/pgtable.h> 42#include <asm/pgtable.h>
52#include <asm/mmu.h> 43#include <asm/mmu.h>
53#include <asm/uaccess.h>
54#include <asm/smp.h> 44#include <asm/smp.h>
55#include <asm/machdep.h> 45#include <asm/machdep.h>
56#include <asm/tlb.h> 46#include <asm/tlb.h>
57#include <asm/eeh.h>
58#include <asm/processor.h> 47#include <asm/processor.h>
59#include <asm/mmzone.h>
60#include <asm/cputable.h> 48#include <asm/cputable.h>
61#include <asm/sections.h> 49#include <asm/sections.h>
62#include <asm/system.h> 50#include <asm/system.h>
63#include <asm/iommu.h>
64#include <asm/abs_addr.h> 51#include <asm/abs_addr.h>
65#include <asm/vdso.h>
66#include <asm/firmware.h> 52#include <asm/firmware.h>
67 53
68#include "mmu_decl.h" 54#include "mmu_decl.h"
69 55
70unsigned long ioremap_bot = IMALLOC_BASE; 56unsigned long ioremap_bot = IOREMAP_BASE;
71static unsigned long phbs_io_bot = PHBS_IO_BASE;
72 57
73/* 58/*
74 * map_io_page currently only called by __ioremap 59 * map_io_page currently only called by __ioremap
@@ -102,8 +87,8 @@ static int map_io_page(unsigned long ea, unsigned long pa, int flags)
102 * entry in the hardware page table. 87 * entry in the hardware page table.
103 * 88 *
104 */ 89 */
105 if (htab_bolt_mapping(ea, ea + PAGE_SIZE, pa, flags, 90 if (htab_bolt_mapping(ea, (unsigned long)ea + PAGE_SIZE,
106 mmu_io_psize)) { 91 pa, flags, mmu_io_psize)) {
107 printk(KERN_ERR "Failed to do bolted mapping IO " 92 printk(KERN_ERR "Failed to do bolted mapping IO "
108 "memory at %016lx !\n", pa); 93 "memory at %016lx !\n", pa);
109 return -ENOMEM; 94 return -ENOMEM;
@@ -113,8 +98,11 @@ static int map_io_page(unsigned long ea, unsigned long pa, int flags)
113} 98}
114 99
115 100
116static void __iomem * __ioremap_com(phys_addr_t addr, unsigned long pa, 101/**
117 unsigned long ea, unsigned long size, 102 * __ioremap_at - Low level function to establish the page tables
103 * for an IO mapping
104 */
105void __iomem * __ioremap_at(phys_addr_t pa, void *ea, unsigned long size,
118 unsigned long flags) 106 unsigned long flags)
119{ 107{
120 unsigned long i; 108 unsigned long i;
@@ -122,17 +110,35 @@ static void __iomem * __ioremap_com(phys_addr_t addr, unsigned long pa,
122 if ((flags & _PAGE_PRESENT) == 0) 110 if ((flags & _PAGE_PRESENT) == 0)
123 flags |= pgprot_val(PAGE_KERNEL); 111 flags |= pgprot_val(PAGE_KERNEL);
124 112
113 WARN_ON(pa & ~PAGE_MASK);
114 WARN_ON(((unsigned long)ea) & ~PAGE_MASK);
115 WARN_ON(size & ~PAGE_MASK);
116
125 for (i = 0; i < size; i += PAGE_SIZE) 117 for (i = 0; i < size; i += PAGE_SIZE)
126 if (map_io_page(ea+i, pa+i, flags)) 118 if (map_io_page((unsigned long)ea+i, pa+i, flags))
127 return NULL; 119 return NULL;
128 120
129 return (void __iomem *) (ea + (addr & ~PAGE_MASK)); 121 return (void __iomem *)ea;
122}
123
124/**
125 * __iounmap_from - Low level function to tear down the page tables
126 * for an IO mapping. This is used for mappings that
127 * are manipulated manually, like partial unmapping of
128 * PCI IOs or ISA space.
129 */
130void __iounmap_at(void *ea, unsigned long size)
131{
132 WARN_ON(((unsigned long)ea) & ~PAGE_MASK);
133 WARN_ON(size & ~PAGE_MASK);
134
135 unmap_kernel_range((unsigned long)ea, size);
130} 136}
131 137
132void __iomem * __ioremap(phys_addr_t addr, unsigned long size, 138void __iomem * __ioremap(phys_addr_t addr, unsigned long size,
133 unsigned long flags) 139 unsigned long flags)
134{ 140{
135 unsigned long pa, ea; 141 phys_addr_t paligned;
136 void __iomem *ret; 142 void __iomem *ret;
137 143
138 /* 144 /*
@@ -144,27 +150,30 @@ void __iomem * __ioremap(phys_addr_t addr, unsigned long size,
144 * IMALLOC_END 150 * IMALLOC_END
145 * 151 *
146 */ 152 */
147 pa = addr & PAGE_MASK; 153 paligned = addr & PAGE_MASK;
148 size = PAGE_ALIGN(addr + size) - pa; 154 size = PAGE_ALIGN(addr + size) - paligned;
149 155
150 if ((size == 0) || (pa == 0)) 156 if ((size == 0) || (paligned == 0))
151 return NULL; 157 return NULL;
152 158
153 if (mem_init_done) { 159 if (mem_init_done) {
154 struct vm_struct *area; 160 struct vm_struct *area;
155 area = im_get_free_area(size); 161
162 area = __get_vm_area(size, VM_IOREMAP,
163 ioremap_bot, IOREMAP_END);
156 if (area == NULL) 164 if (area == NULL)
157 return NULL; 165 return NULL;
158 ea = (unsigned long)(area->addr); 166 ret = __ioremap_at(paligned, area->addr, size, flags);
159 ret = __ioremap_com(addr, pa, ea, size, flags);
160 if (!ret) 167 if (!ret)
161 im_free(area->addr); 168 vunmap(area->addr);
162 } else { 169 } else {
163 ea = ioremap_bot; 170 ret = __ioremap_at(paligned, (void *)ioremap_bot, size, flags);
164 ret = __ioremap_com(addr, pa, ea, size, flags);
165 if (ret) 171 if (ret)
166 ioremap_bot += size; 172 ioremap_bot += size;
167 } 173 }
174
175 if (ret)
176 ret += addr & ~PAGE_MASK;
168 return ret; 177 return ret;
169} 178}
170 179
@@ -187,62 +196,9 @@ void __iomem * ioremap_flags(phys_addr_t addr, unsigned long size,
187} 196}
188 197
189 198
190#define IS_PAGE_ALIGNED(_val) ((_val) == ((_val) & PAGE_MASK))
191
192int __ioremap_explicit(phys_addr_t pa, unsigned long ea,
193 unsigned long size, unsigned long flags)
194{
195 struct vm_struct *area;
196 void __iomem *ret;
197
198 /* For now, require page-aligned values for pa, ea, and size */
199 if (!IS_PAGE_ALIGNED(pa) || !IS_PAGE_ALIGNED(ea) ||
200 !IS_PAGE_ALIGNED(size)) {
201 printk(KERN_ERR "unaligned value in %s\n", __FUNCTION__);
202 return 1;
203 }
204
205 if (!mem_init_done) {
206 /* Two things to consider in this case:
207 * 1) No records will be kept (imalloc, etc) that the region
208 * has been remapped
209 * 2) It won't be easy to iounmap() the region later (because
210 * of 1)
211 */
212 ;
213 } else {
214 area = im_get_area(ea, size,
215 IM_REGION_UNUSED|IM_REGION_SUBSET|IM_REGION_EXISTS);
216 if (area == NULL) {
217 /* Expected when PHB-dlpar is in play */
218 return 1;
219 }
220 if (ea != (unsigned long) area->addr) {
221 printk(KERN_ERR "unexpected addr return from "
222 "im_get_area\n");
223 return 1;
224 }
225 }
226
227 ret = __ioremap_com(pa, pa, ea, size, flags);
228 if (ret == NULL) {
229 printk(KERN_ERR "ioremap_explicit() allocation failure !\n");
230 return 1;
231 }
232 if (ret != (void *) ea) {
233 printk(KERN_ERR "__ioremap_com() returned unexpected addr\n");
234 return 1;
235 }
236
237 return 0;
238}
239
240/* 199/*
241 * Unmap an IO region and remove it from imalloc'd list. 200 * Unmap an IO region and remove it from imalloc'd list.
242 * Access to IO memory should be serialized by driver. 201 * Access to IO memory should be serialized by driver.
243 * This code is modeled after vmalloc code - unmap_vm_area()
244 *
245 * XXX what about calls before mem_init_done (ie python_countermeasures())
246 */ 202 */
247void __iounmap(volatile void __iomem *token) 203void __iounmap(volatile void __iomem *token)
248{ 204{
@@ -251,9 +207,14 @@ void __iounmap(volatile void __iomem *token)
251 if (!mem_init_done) 207 if (!mem_init_done)
252 return; 208 return;
253 209
254 addr = (void *) ((unsigned long __force) token & PAGE_MASK); 210 addr = (void *) ((unsigned long __force)
255 211 PCI_FIX_ADDR(token) & PAGE_MASK);
256 im_free(addr); 212 if ((unsigned long)addr < ioremap_bot) {
213 printk(KERN_WARNING "Attempt to iounmap early bolted mapping"
214 " at 0x%p\n", addr);
215 return;
216 }
217 vunmap(addr);
257} 218}
258 219
259void iounmap(volatile void __iomem *token) 220void iounmap(volatile void __iomem *token)
@@ -264,77 +225,8 @@ void iounmap(volatile void __iomem *token)
264 __iounmap(token); 225 __iounmap(token);
265} 226}
266 227
267static int iounmap_subset_regions(unsigned long addr, unsigned long size)
268{
269 struct vm_struct *area;
270
271 /* Check whether subsets of this region exist */
272 area = im_get_area(addr, size, IM_REGION_SUPERSET);
273 if (area == NULL)
274 return 1;
275
276 while (area) {
277 iounmap((void __iomem *) area->addr);
278 area = im_get_area(addr, size,
279 IM_REGION_SUPERSET);
280 }
281
282 return 0;
283}
284
285int __iounmap_explicit(volatile void __iomem *start, unsigned long size)
286{
287 struct vm_struct *area;
288 unsigned long addr;
289 int rc;
290
291 addr = (unsigned long __force) start & PAGE_MASK;
292
293 /* Verify that the region either exists or is a subset of an existing
294 * region. In the latter case, split the parent region to create
295 * the exact region
296 */
297 area = im_get_area(addr, size,
298 IM_REGION_EXISTS | IM_REGION_SUBSET);
299 if (area == NULL) {
300 /* Determine whether subset regions exist. If so, unmap */
301 rc = iounmap_subset_regions(addr, size);
302 if (rc) {
303 printk(KERN_ERR
304 "%s() cannot unmap nonexistent range 0x%lx\n",
305 __FUNCTION__, addr);
306 return 1;
307 }
308 } else {
309 iounmap((void __iomem *) area->addr);
310 }
311 /*
312 * FIXME! This can't be right:
313 iounmap(area->addr);
314 * Maybe it should be "iounmap(area);"
315 */
316 return 0;
317}
318
319EXPORT_SYMBOL(ioremap); 228EXPORT_SYMBOL(ioremap);
320EXPORT_SYMBOL(ioremap_flags); 229EXPORT_SYMBOL(ioremap_flags);
321EXPORT_SYMBOL(__ioremap); 230EXPORT_SYMBOL(__ioremap);
322EXPORT_SYMBOL(iounmap); 231EXPORT_SYMBOL(iounmap);
323EXPORT_SYMBOL(__iounmap); 232EXPORT_SYMBOL(__iounmap);
324
325static DEFINE_SPINLOCK(phb_io_lock);
326
327void __iomem * reserve_phb_iospace(unsigned long size)
328{
329 void __iomem *virt_addr;
330
331 if (phbs_io_bot >= IMALLOC_BASE)
332 panic("reserve_phb_iospace(): phb io space overflow\n");
333
334 spin_lock(&phb_io_lock);
335 virt_addr = (void __iomem *) phbs_io_bot;
336 phbs_io_bot += size;
337 spin_unlock(&phb_io_lock);
338
339 return virt_addr;
340}
diff --git a/arch/powerpc/mm/ppc_mmu_32.c b/arch/powerpc/mm/ppc_mmu_32.c
index ec1421a20aaa..5c45d474cfcc 100644
--- a/arch/powerpc/mm/ppc_mmu_32.c
+++ b/arch/powerpc/mm/ppc_mmu_32.c
@@ -11,7 +11,6 @@
11 * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au) 11 * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
12 * and Cort Dougan (PReP) (cort@cs.nmt.edu) 12 * and Cort Dougan (PReP) (cort@cs.nmt.edu)
13 * Copyright (C) 1996 Paul Mackerras 13 * Copyright (C) 1996 Paul Mackerras
14 * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
15 * 14 *
16 * Derived from "arch/i386/mm/init.c" 15 * Derived from "arch/i386/mm/init.c"
17 * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds 16 * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
@@ -35,12 +34,12 @@
35 34
36#include "mmu_decl.h" 35#include "mmu_decl.h"
37 36
38PTE *Hash, *Hash_end; 37struct hash_pte *Hash, *Hash_end;
39unsigned long Hash_size, Hash_mask; 38unsigned long Hash_size, Hash_mask;
40unsigned long _SDR1; 39unsigned long _SDR1;
41 40
42union ubat { /* BAT register values to be loaded */ 41union ubat { /* BAT register values to be loaded */
43 BAT bat; 42 struct ppc_bat bat;
44 u32 word[2]; 43 u32 word[2];
45} BATS[8][2]; /* 8 pairs of IBAT, DBAT */ 44} BATS[8][2]; /* 8 pairs of IBAT, DBAT */
46 45
@@ -245,7 +244,7 @@ void __init MMU_init_hw(void)
245 cacheable_memzero(Hash, Hash_size); 244 cacheable_memzero(Hash, Hash_size);
246 _SDR1 = __pa(Hash) | SDR1_LOW_BITS; 245 _SDR1 = __pa(Hash) | SDR1_LOW_BITS;
247 246
248 Hash_end = (PTE *) ((unsigned long)Hash + Hash_size); 247 Hash_end = (struct hash_pte *) ((unsigned long)Hash + Hash_size);
249 248
250 printk("Total memory = %ldMB; using %ldkB for hash table (at %p)\n", 249 printk("Total memory = %ldMB; using %ldkB for hash table (at %p)\n",
251 total_memory >> 20, Hash_size >> 10, Hash); 250 total_memory >> 20, Hash_size >> 10, Hash);
diff --git a/arch/powerpc/mm/stab.c b/arch/powerpc/mm/stab.c
index 132c6bc66ce1..28492bbdee8e 100644
--- a/arch/powerpc/mm/stab.c
+++ b/arch/powerpc/mm/stab.c
@@ -55,7 +55,7 @@ static int make_ste(unsigned long stab, unsigned long esid, unsigned long vsid)
55 for (entry = 0; entry < 8; entry++, ste++) { 55 for (entry = 0; entry < 8; entry++, ste++) {
56 if (!(ste->esid_data & STE_ESID_V)) { 56 if (!(ste->esid_data & STE_ESID_V)) {
57 ste->vsid_data = vsid_data; 57 ste->vsid_data = vsid_data;
58 asm volatile("eieio":::"memory"); 58 eieio();
59 ste->esid_data = esid_data; 59 ste->esid_data = esid_data;
60 return (global_entry | entry); 60 return (global_entry | entry);
61 } 61 }
@@ -101,7 +101,7 @@ static int make_ste(unsigned long stab, unsigned long esid, unsigned long vsid)
101 asm volatile("sync" : : : "memory"); /* Order update */ 101 asm volatile("sync" : : : "memory"); /* Order update */
102 102
103 castout_ste->vsid_data = vsid_data; 103 castout_ste->vsid_data = vsid_data;
104 asm volatile("eieio" : : : "memory"); /* Order update */ 104 eieio(); /* Order update */
105 castout_ste->esid_data = esid_data; 105 castout_ste->esid_data = esid_data;
106 106
107 asm volatile("slbie %0" : : "r" (old_esid << SID_SHIFT)); 107 asm volatile("slbie %0" : : "r" (old_esid << SID_SHIFT));
diff --git a/arch/powerpc/mm/tlb_32.c b/arch/powerpc/mm/tlb_32.c
index 6a69417cbc0e..06c7e77e097a 100644
--- a/arch/powerpc/mm/tlb_32.c
+++ b/arch/powerpc/mm/tlb_32.c
@@ -11,7 +11,6 @@
11 * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au) 11 * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
12 * and Cort Dougan (PReP) (cort@cs.nmt.edu) 12 * and Cort Dougan (PReP) (cort@cs.nmt.edu)
13 * Copyright (C) 1996 Paul Mackerras 13 * Copyright (C) 1996 Paul Mackerras
14 * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
15 * 14 *
16 * Derived from "arch/i386/mm/init.c" 15 * Derived from "arch/i386/mm/init.c"
17 * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds 16 * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
diff --git a/arch/powerpc/mm/tlb_64.c b/arch/powerpc/mm/tlb_64.c
index 2bfc4d7e1aa2..cbd34fc813ee 100644
--- a/arch/powerpc/mm/tlb_64.c
+++ b/arch/powerpc/mm/tlb_64.c
@@ -8,7 +8,6 @@
8 * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au) 8 * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
9 * and Cort Dougan (PReP) (cort@cs.nmt.edu) 9 * and Cort Dougan (PReP) (cort@cs.nmt.edu)
10 * Copyright (C) 1996 Paul Mackerras 10 * Copyright (C) 1996 Paul Mackerras
11 * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
12 * 11 *
13 * Derived from "arch/i386/mm/init.c" 12 * Derived from "arch/i386/mm/init.c"
14 * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds 13 * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
@@ -239,3 +238,59 @@ void pte_free_finish(void)
239 pte_free_submit(*batchp); 238 pte_free_submit(*batchp);
240 *batchp = NULL; 239 *batchp = NULL;
241} 240}
241
242/**
243 * __flush_hash_table_range - Flush all HPTEs for a given address range
244 * from the hash table (and the TLB). But keeps
245 * the linux PTEs intact.
246 *
247 * @mm : mm_struct of the target address space (generally init_mm)
248 * @start : starting address
249 * @end : ending address (not included in the flush)
250 *
251 * This function is mostly to be used by some IO hotplug code in order
252 * to remove all hash entries from a given address range used to map IO
253 * space on a removed PCI-PCI bidge without tearing down the full mapping
254 * since 64K pages may overlap with other bridges when using 64K pages
255 * with 4K HW pages on IO space.
256 *
257 * Because of that usage pattern, it's only available with CONFIG_HOTPLUG
258 * and is implemented for small size rather than speed.
259 */
260#ifdef CONFIG_HOTPLUG
261
262void __flush_hash_table_range(struct mm_struct *mm, unsigned long start,
263 unsigned long end)
264{
265 unsigned long flags;
266
267 start = _ALIGN_DOWN(start, PAGE_SIZE);
268 end = _ALIGN_UP(end, PAGE_SIZE);
269
270 BUG_ON(!mm->pgd);
271
272 /* Note: Normally, we should only ever use a batch within a
273 * PTE locked section. This violates the rule, but will work
274 * since we don't actually modify the PTEs, we just flush the
275 * hash while leaving the PTEs intact (including their reference
276 * to being hashed). This is not the most performance oriented
277 * way to do things but is fine for our needs here.
278 */
279 local_irq_save(flags);
280 arch_enter_lazy_mmu_mode();
281 for (; start < end; start += PAGE_SIZE) {
282 pte_t *ptep = find_linux_pte(mm->pgd, start);
283 unsigned long pte;
284
285 if (ptep == NULL)
286 continue;
287 pte = pte_val(*ptep);
288 if (!(pte & _PAGE_HASHPTE))
289 continue;
290 hpte_need_flush(mm, start, ptep, pte, 0);
291 }
292 arch_leave_lazy_mmu_mode();
293 local_irq_restore(flags);
294}
295
296#endif /* CONFIG_HOTPLUG */
diff --git a/arch/powerpc/oprofile/op_model_power4.c b/arch/powerpc/oprofile/op_model_power4.c
index fe597a154d4f..a7c206b665af 100644
--- a/arch/powerpc/oprofile/op_model_power4.c
+++ b/arch/powerpc/oprofile/op_model_power4.c
@@ -1,5 +1,7 @@
1/* 1/*
2 * Copyright (C) 2004 Anton Blanchard <anton@au.ibm.com>, IBM 2 * Copyright (C) 2004 Anton Blanchard <anton@au.ibm.com>, IBM
3 * Added mmcra[slot] support:
4 * Copyright (C) 2006-2007 Will Schmidt <willschm@us.ibm.com>, IBM
3 * 5 *
4 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License 7 * modify it under the terms of the GNU General Public License
@@ -181,11 +183,17 @@ static void __attribute_used__ kernel_unknown_bucket(void)
181 * On GQ and newer the MMCRA stores the HV and PR bits at the time 183 * On GQ and newer the MMCRA stores the HV and PR bits at the time
182 * the SIAR was sampled. We use that to work out if the SIAR was sampled in 184 * the SIAR was sampled. We use that to work out if the SIAR was sampled in
183 * the hypervisor, our exception vectors or RTAS. 185 * the hypervisor, our exception vectors or RTAS.
186 * If the MMCRA_SAMPLE_ENABLE bit is set, we can use the MMCRA[slot] bits
187 * to more accurately identify the address of the sampled instruction. The
188 * mmcra[slot] bits represent the slot number of a sampled instruction
189 * within an instruction group. The slot will contain a value between 1
190 * and 5 if MMCRA_SAMPLE_ENABLE is set, otherwise 0.
184 */ 191 */
185static unsigned long get_pc(struct pt_regs *regs) 192static unsigned long get_pc(struct pt_regs *regs)
186{ 193{
187 unsigned long pc = mfspr(SPRN_SIAR); 194 unsigned long pc = mfspr(SPRN_SIAR);
188 unsigned long mmcra; 195 unsigned long mmcra;
196 unsigned long slot;
189 197
190 /* Cant do much about it */ 198 /* Cant do much about it */
191 if (!cur_cpu_spec->oprofile_mmcra_sihv) 199 if (!cur_cpu_spec->oprofile_mmcra_sihv)
@@ -193,6 +201,12 @@ static unsigned long get_pc(struct pt_regs *regs)
193 201
194 mmcra = mfspr(SPRN_MMCRA); 202 mmcra = mfspr(SPRN_MMCRA);
195 203
204 if (mmcra & MMCRA_SAMPLE_ENABLE) {
205 slot = ((mmcra & MMCRA_SLOT) >> MMCRA_SLOT_SHIFT);
206 if (slot > 1)
207 pc += 4 * (slot - 1);
208 }
209
196 /* Were we in the hypervisor? */ 210 /* Were we in the hypervisor? */
197 if (firmware_has_feature(FW_FEATURE_LPAR) && 211 if (firmware_has_feature(FW_FEATURE_LPAR) &&
198 (mmcra & cur_cpu_spec->oprofile_mmcra_sihv)) 212 (mmcra & cur_cpu_spec->oprofile_mmcra_sihv))
diff --git a/arch/powerpc/platforms/52xx/efika.c b/arch/powerpc/platforms/52xx/efika.c
index f591a9fc19b9..4be6e7a17b66 100644
--- a/arch/powerpc/platforms/52xx/efika.c
+++ b/arch/powerpc/platforms/52xx/efika.c
@@ -54,7 +54,7 @@ static int rtas_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
54 struct pci_controller *hose = bus->sysdata; 54 struct pci_controller *hose = bus->sysdata;
55 unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8) 55 unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8)
56 | (((bus->number - hose->first_busno) & 0xff) << 16) 56 | (((bus->number - hose->first_busno) & 0xff) << 16)
57 | (hose->index << 24); 57 | (hose->global_number << 24);
58 int ret = -1; 58 int ret = -1;
59 int rval; 59 int rval;
60 60
@@ -69,7 +69,7 @@ static int rtas_write_config(struct pci_bus *bus, unsigned int devfn,
69 struct pci_controller *hose = bus->sysdata; 69 struct pci_controller *hose = bus->sysdata;
70 unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8) 70 unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8)
71 | (((bus->number - hose->first_busno) & 0xff) << 16) 71 | (((bus->number - hose->first_busno) & 0xff) << 16)
72 | (hose->index << 24); 72 | (hose->global_number << 24);
73 int rval; 73 int rval;
74 74
75 rval = rtas_call(rtas_token("write-pci-config"), 3, 1, NULL, 75 rval = rtas_call(rtas_token("write-pci-config"), 3, 1, NULL,
@@ -83,7 +83,7 @@ static struct pci_ops rtas_pci_ops = {
83}; 83};
84 84
85 85
86void __init efika_pcisetup(void) 86static void __init efika_pcisetup(void)
87{ 87{
88 const int *bus_range; 88 const int *bus_range;
89 int len; 89 int len;
@@ -128,7 +128,7 @@ void __init efika_pcisetup(void)
128 printk(" controlled by %s\n", pcictrl->full_name); 128 printk(" controlled by %s\n", pcictrl->full_name);
129 printk("\n"); 129 printk("\n");
130 130
131 hose = pcibios_alloc_controller(); 131 hose = pcibios_alloc_controller(of_node_get(pcictrl));
132 if (!hose) { 132 if (!hose) {
133 printk(KERN_WARNING EFIKA_PLATFORM_NAME 133 printk(KERN_WARNING EFIKA_PLATFORM_NAME
134 ": Can't allocate PCI controller structure for %s\n", 134 ": Can't allocate PCI controller structure for %s\n",
@@ -136,7 +136,6 @@ void __init efika_pcisetup(void)
136 return; 136 return;
137 } 137 }
138 138
139 hose->arch_data = of_node_get(pcictrl);
140 hose->first_busno = bus_range[0]; 139 hose->first_busno = bus_range[0];
141 hose->last_busno = bus_range[1]; 140 hose->last_busno = bus_range[1];
142 hose->ops = &rtas_pci_ops; 141 hose->ops = &rtas_pci_ops;
@@ -145,7 +144,7 @@ void __init efika_pcisetup(void)
145} 144}
146 145
147#else 146#else
148void __init efika_pcisetup(void) 147static void __init efika_pcisetup(void)
149{} 148{}
150#endif 149#endif
151 150
@@ -252,6 +251,8 @@ define_machine(efika)
252 .progress = rtas_progress, 251 .progress = rtas_progress,
253 .get_boot_time = rtas_get_boot_time, 252 .get_boot_time = rtas_get_boot_time,
254 .calibrate_decr = generic_calibrate_decr, 253 .calibrate_decr = generic_calibrate_decr,
254#ifdef CONFIG_PCI
255 .phys_mem_access_prot = pci_phys_mem_access_prot, 255 .phys_mem_access_prot = pci_phys_mem_access_prot,
256#endif
256}; 257};
257 258
diff --git a/arch/powerpc/platforms/52xx/lite5200.c b/arch/powerpc/platforms/52xx/lite5200.c
index 1cfc00dfb99a..5c46e898fd45 100644
--- a/arch/powerpc/platforms/52xx/lite5200.c
+++ b/arch/powerpc/platforms/52xx/lite5200.c
@@ -156,7 +156,7 @@ static void __init lite5200_setup_arch(void)
156 156
157} 157}
158 158
159void lite5200_show_cpuinfo(struct seq_file *m) 159static void lite5200_show_cpuinfo(struct seq_file *m)
160{ 160{
161 struct device_node* np = of_find_all_nodes(NULL); 161 struct device_node* np = of_find_all_nodes(NULL);
162 const char *model = NULL; 162 const char *model = NULL;
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pci.c b/arch/powerpc/platforms/52xx/mpc52xx_pci.c
index 34d34a26d305..4c6c82a684b1 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_pci.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_pci.c
@@ -112,18 +112,18 @@ mpc52xx_pci_read_config(struct pci_bus *bus, unsigned int devfn,
112 u32 value; 112 u32 value;
113 113
114 if (ppc_md.pci_exclude_device) 114 if (ppc_md.pci_exclude_device)
115 if (ppc_md.pci_exclude_device(bus->number, devfn)) 115 if (ppc_md.pci_exclude_device(hose, bus->number, devfn))
116 return PCIBIOS_DEVICE_NOT_FOUND; 116 return PCIBIOS_DEVICE_NOT_FOUND;
117 117
118 out_be32(hose->cfg_addr, 118 out_be32(hose->cfg_addr,
119 (1 << 31) | 119 (1 << 31) |
120 ((bus->number - hose->bus_offset) << 16) | 120 (bus->number << 16) |
121 (devfn << 8) | 121 (devfn << 8) |
122 (offset & 0xfc)); 122 (offset & 0xfc));
123 mb(); 123 mb();
124 124
125#if defined(CONFIG_PPC_MPC5200_BUGFIX) 125#if defined(CONFIG_PPC_MPC5200_BUGFIX)
126 if (bus->number != hose->bus_offset) { 126 if (bus->number) {
127 /* workaround for the bug 435 of the MPC5200 (L25R); 127 /* workaround for the bug 435 of the MPC5200 (L25R);
128 * Don't do 32 bits config access during type-1 cycles */ 128 * Don't do 32 bits config access during type-1 cycles */
129 switch (len) { 129 switch (len) {
@@ -169,18 +169,18 @@ mpc52xx_pci_write_config(struct pci_bus *bus, unsigned int devfn,
169 u32 value, mask; 169 u32 value, mask;
170 170
171 if (ppc_md.pci_exclude_device) 171 if (ppc_md.pci_exclude_device)
172 if (ppc_md.pci_exclude_device(bus->number, devfn)) 172 if (ppc_md.pci_exclude_device(hose, bus->number, devfn))
173 return PCIBIOS_DEVICE_NOT_FOUND; 173 return PCIBIOS_DEVICE_NOT_FOUND;
174 174
175 out_be32(hose->cfg_addr, 175 out_be32(hose->cfg_addr,
176 (1 << 31) | 176 (1 << 31) |
177 ((bus->number - hose->bus_offset) << 16) | 177 (bus->number << 16) |
178 (devfn << 8) | 178 (devfn << 8) |
179 (offset & 0xfc)); 179 (offset & 0xfc));
180 mb(); 180 mb();
181 181
182#if defined(CONFIG_PPC_MPC5200_BUGFIX) 182#if defined(CONFIG_PPC_MPC5200_BUGFIX)
183 if (bus->number != hose->bus_offset) { 183 if (bus->number) {
184 /* workaround for the bug 435 of the MPC5200 (L25R); 184 /* workaround for the bug 435 of the MPC5200 (L25R);
185 * Don't do 32 bits config access during type-1 cycles */ 185 * Don't do 32 bits config access during type-1 cycles */
186 switch (len) { 186 switch (len) {
@@ -385,17 +385,13 @@ mpc52xx_add_bridge(struct device_node *node)
385 * tree are needed to configure the 52xx PCI controller. Rather 385 * tree are needed to configure the 52xx PCI controller. Rather
386 * than parse the tree here, let pci_process_bridge_OF_ranges() 386 * than parse the tree here, let pci_process_bridge_OF_ranges()
387 * do it for us and extract the values after the fact */ 387 * do it for us and extract the values after the fact */
388 hose = pcibios_alloc_controller(); 388 hose = pcibios_alloc_controller(node);
389 if (!hose) 389 if (!hose)
390 return -ENOMEM; 390 return -ENOMEM;
391 391
392 hose->arch_data = node;
393 hose->set_cfg_type = 1;
394
395 hose->first_busno = bus_range ? bus_range[0] : 0; 392 hose->first_busno = bus_range ? bus_range[0] : 0;
396 hose->last_busno = bus_range ? bus_range[1] : 0xff; 393 hose->last_busno = bus_range ? bus_range[1] : 0xff;
397 394
398 hose->bus_offset = 0;
399 hose->ops = &mpc52xx_pci_ops; 395 hose->ops = &mpc52xx_pci_ops;
400 396
401 pci_regs = ioremap(rsrc.start, rsrc.end - rsrc.start + 1); 397 pci_regs = ioremap(rsrc.start, rsrc.end - rsrc.start + 1);
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pm.c b/arch/powerpc/platforms/52xx/mpc52xx_pm.c
index fd40044d16cd..ee2e7639c63e 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_pm.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_pm.c
@@ -9,8 +9,8 @@
9 9
10 10
11/* these are defined in mpc52xx_sleep.S, and only used here */ 11/* these are defined in mpc52xx_sleep.S, and only used here */
12extern void mpc52xx_deep_sleep(void *sram, void *sdram_regs, 12extern void mpc52xx_deep_sleep(void __iomem *sram, void __iomem *sdram_regs,
13 struct mpc52xx_cdm *, struct mpc52xx_intr *); 13 struct mpc52xx_cdm __iomem *, struct mpc52xx_intr __iomem*);
14extern void mpc52xx_ds_sram(void); 14extern void mpc52xx_ds_sram(void);
15extern const long mpc52xx_ds_sram_size; 15extern const long mpc52xx_ds_sram_size;
16extern void mpc52xx_ds_cached(void); 16extern void mpc52xx_ds_cached(void);
@@ -21,7 +21,7 @@ static void __iomem *sdram;
21static struct mpc52xx_cdm __iomem *cdm; 21static struct mpc52xx_cdm __iomem *cdm;
22static struct mpc52xx_intr __iomem *intr; 22static struct mpc52xx_intr __iomem *intr;
23static struct mpc52xx_gpio_wkup __iomem *gpiow; 23static struct mpc52xx_gpio_wkup __iomem *gpiow;
24static void *sram; 24static void __iomem *sram;
25static int sram_size; 25static int sram_size;
26 26
27struct mpc52xx_suspend mpc52xx_suspend; 27struct mpc52xx_suspend mpc52xx_suspend;
@@ -100,7 +100,7 @@ int mpc52xx_pm_enter(suspend_state_t state)
100 u32 clk_enables; 100 u32 clk_enables;
101 u32 msr, hid0; 101 u32 msr, hid0;
102 u32 intr_main_mask; 102 u32 intr_main_mask;
103 void __iomem * irq_0x500 = (void *)CONFIG_KERNEL_START + 0x500; 103 void __iomem * irq_0x500 = (void __iomem *)CONFIG_KERNEL_START + 0x500;
104 unsigned long irq_0x500_stop = (unsigned long)irq_0x500 + mpc52xx_ds_cached_size; 104 unsigned long irq_0x500_stop = (unsigned long)irq_0x500 + mpc52xx_ds_cached_size;
105 char saved_0x500[mpc52xx_ds_cached_size]; 105 char saved_0x500[mpc52xx_ds_cached_size];
106 106
diff --git a/arch/powerpc/platforms/82xx/Kconfig b/arch/powerpc/platforms/82xx/Kconfig
index de7fce9cb6eb..89fde43895c5 100644
--- a/arch/powerpc/platforms/82xx/Kconfig
+++ b/arch/powerpc/platforms/82xx/Kconfig
@@ -1,5 +1,5 @@
1choice 1choice
2 prompt "Machine Type" 2 prompt "82xx Board Type"
3 depends on PPC_82xx 3 depends on PPC_82xx
4 default MPC82xx_ADS 4 default MPC82xx_ADS
5 5
diff --git a/arch/powerpc/platforms/82xx/mpc82xx_ads.c b/arch/powerpc/platforms/82xx/mpc82xx_ads.c
index 47cb09f08052..da20832b27f1 100644
--- a/arch/powerpc/platforms/82xx/mpc82xx_ads.c
+++ b/arch/powerpc/platforms/82xx/mpc82xx_ads.c
@@ -49,7 +49,7 @@
49#include <linux/fs_enet_pd.h> 49#include <linux/fs_enet_pd.h>
50 50
51#include <sysdev/fsl_soc.h> 51#include <sysdev/fsl_soc.h>
52#include <../sysdev/cpm2_pic.h> 52#include <sysdev/cpm2_pic.h>
53 53
54#include "pq2ads.h" 54#include "pq2ads.h"
55 55
@@ -507,7 +507,8 @@ void m82xx_pci_init_irq(void)
507 return; 507 return;
508} 508}
509 509
510static int m82xx_pci_exclude_device(u_char bus, u_char devfn) 510static int m82xx_pci_exclude_device(struct pci_controller *hose,
511 u_char bus, u_char devfn)
511{ 512{
512 if (bus == 0 && PCI_SLOT(devfn) == 0) 513 if (bus == 0 && PCI_SLOT(devfn) == 0)
513 return PCIBIOS_DEVICE_NOT_FOUND; 514 return PCIBIOS_DEVICE_NOT_FOUND;
@@ -515,7 +516,7 @@ static int m82xx_pci_exclude_device(u_char bus, u_char devfn)
515 return PCIBIOS_SUCCESSFUL; 516 return PCIBIOS_SUCCESSFUL;
516} 517}
517 518
518void __init add_bridge(struct device_node *np) 519static void __init mpc82xx_add_bridge(struct device_node *np)
519{ 520{
520 int len; 521 int len;
521 struct pci_controller *hose; 522 struct pci_controller *hose;
@@ -542,19 +543,13 @@ void __init add_bridge(struct device_node *np)
542 543
543 pci_assign_all_buses = 1; 544 pci_assign_all_buses = 1;
544 545
545 hose = pcibios_alloc_controller(); 546 hose = pcibios_alloc_controller(np);
546 547
547 if (!hose) 548 if (!hose)
548 return; 549 return;
549 550
550 hose->arch_data = np;
551 hose->set_cfg_type = 1;
552
553 hose->first_busno = bus_range ? bus_range[0] : 0; 551 hose->first_busno = bus_range ? bus_range[0] : 0;
554 hose->last_busno = bus_range ? bus_range[1] : 0xff; 552 hose->last_busno = bus_range ? bus_range[1] : 0xff;
555 hose->bus_offset = 0;
556
557 hose->set_cfg_type = 1;
558 553
559 setup_indirect_pci(hose, 554 setup_indirect_pci(hose,
560 r.start + offsetof(pci_cpm2_t, pci_cfg_addr), 555 r.start + offsetof(pci_cpm2_t, pci_cfg_addr),
@@ -584,7 +579,7 @@ static void __init mpc82xx_ads_setup_arch(void)
584#ifdef CONFIG_PCI 579#ifdef CONFIG_PCI
585 ppc_md.pci_exclude_device = m82xx_pci_exclude_device; 580 ppc_md.pci_exclude_device = m82xx_pci_exclude_device;
586 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) 581 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
587 add_bridge(np); 582 mpc82xx_add_bridge(np);
588 583
589 of_node_put(np); 584 of_node_put(np);
590#endif 585#endif
diff --git a/arch/powerpc/platforms/83xx/Kconfig b/arch/powerpc/platforms/83xx/Kconfig
index 19cafdf6df93..ec305f18abd8 100644
--- a/arch/powerpc/platforms/83xx/Kconfig
+++ b/arch/powerpc/platforms/83xx/Kconfig
@@ -1,5 +1,5 @@
1choice 1choice
2 prompt "Machine Type" 2 prompt "83xx Board Type"
3 depends on PPC_83xx 3 depends on PPC_83xx
4 default MPC834x_MDS 4 default MPC834x_MDS
5 5
diff --git a/arch/powerpc/platforms/83xx/Makefile b/arch/powerpc/platforms/83xx/Makefile
index 31a91b53f528..5a98f885779f 100644
--- a/arch/powerpc/platforms/83xx/Makefile
+++ b/arch/powerpc/platforms/83xx/Makefile
@@ -1,7 +1,7 @@
1# 1#
2# Makefile for the PowerPC 83xx linux kernel. 2# Makefile for the PowerPC 83xx linux kernel.
3# 3#
4obj-y := misc.o 4obj-y := misc.o usb.o
5obj-$(CONFIG_PCI) += pci.o 5obj-$(CONFIG_PCI) += pci.o
6obj-$(CONFIG_MPC8313_RDB) += mpc8313_rdb.o 6obj-$(CONFIG_MPC8313_RDB) += mpc8313_rdb.o
7obj-$(CONFIG_MPC832x_RDB) += mpc832x_rdb.o 7obj-$(CONFIG_MPC832x_RDB) += mpc832x_rdb.o
diff --git a/arch/powerpc/platforms/83xx/mpc8313_rdb.c b/arch/powerpc/platforms/83xx/mpc8313_rdb.c
index 96970ac887ee..3edfe170a03b 100644
--- a/arch/powerpc/platforms/83xx/mpc8313_rdb.c
+++ b/arch/powerpc/platforms/83xx/mpc8313_rdb.c
@@ -28,11 +28,6 @@
28#define DBG(fmt...) 28#define DBG(fmt...)
29#endif 29#endif
30 30
31#ifndef CONFIG_PCI
32unsigned long isa_io_base = 0;
33unsigned long isa_mem_base = 0;
34#endif
35
36/* ************************************************************************ 31/* ************************************************************************
37 * 32 *
38 * Setup the architecture 33 * Setup the architecture
@@ -49,10 +44,11 @@ static void __init mpc8313_rdb_setup_arch(void)
49 44
50#ifdef CONFIG_PCI 45#ifdef CONFIG_PCI
51 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) 46 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
52 add_bridge(np); 47 mpc83xx_add_bridge(np);
53 48
54 ppc_md.pci_exclude_device = mpc83xx_exclude_device; 49 ppc_md.pci_exclude_device = mpc83xx_exclude_device;
55#endif 50#endif
51 mpc831x_usb_cfg();
56} 52}
57 53
58void __init mpc8313_rdb_init_IRQ(void) 54void __init mpc8313_rdb_init_IRQ(void)
diff --git a/arch/powerpc/platforms/83xx/mpc832x_mds.c b/arch/powerpc/platforms/83xx/mpc832x_mds.c
index 94843ed52a93..b39cb52c6fb9 100644
--- a/arch/powerpc/platforms/83xx/mpc832x_mds.c
+++ b/arch/powerpc/platforms/83xx/mpc832x_mds.c
@@ -49,11 +49,6 @@
49#define DBG(fmt...) 49#define DBG(fmt...)
50#endif 50#endif
51 51
52#ifndef CONFIG_PCI
53unsigned long isa_io_base = 0;
54unsigned long isa_mem_base = 0;
55#endif
56
57static u8 *bcsr_regs = NULL; 52static u8 *bcsr_regs = NULL;
58 53
59/* ************************************************************************ 54/* ************************************************************************
@@ -80,7 +75,7 @@ static void __init mpc832x_sys_setup_arch(void)
80 75
81#ifdef CONFIG_PCI 76#ifdef CONFIG_PCI
82 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) 77 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
83 add_bridge(np); 78 mpc83xx_add_bridge(np);
84 ppc_md.pci_exclude_device = mpc83xx_exclude_device; 79 ppc_md.pci_exclude_device = mpc83xx_exclude_device;
85#endif 80#endif
86 81
diff --git a/arch/powerpc/platforms/83xx/mpc832x_rdb.c b/arch/powerpc/platforms/83xx/mpc832x_rdb.c
index 3db68b73fc32..b2b28a44738c 100644
--- a/arch/powerpc/platforms/83xx/mpc832x_rdb.c
+++ b/arch/powerpc/platforms/83xx/mpc832x_rdb.c
@@ -32,11 +32,6 @@
32#define DBG(fmt...) 32#define DBG(fmt...)
33#endif 33#endif
34 34
35#ifndef CONFIG_PCI
36unsigned long isa_io_base = 0;
37unsigned long isa_mem_base = 0;
38#endif
39
40/* ************************************************************************ 35/* ************************************************************************
41 * 36 *
42 * Setup the architecture 37 * Setup the architecture
@@ -53,7 +48,7 @@ static void __init mpc832x_rdb_setup_arch(void)
53 48
54#ifdef CONFIG_PCI 49#ifdef CONFIG_PCI
55 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) 50 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
56 add_bridge(np); 51 mpc83xx_add_bridge(np);
57 52
58 ppc_md.pci_exclude_device = mpc83xx_exclude_device; 53 ppc_md.pci_exclude_device = mpc83xx_exclude_device;
59#endif 54#endif
diff --git a/arch/powerpc/platforms/83xx/mpc834x_itx.c b/arch/powerpc/platforms/83xx/mpc834x_itx.c
index 40a01947d684..47ba5446f63c 100644
--- a/arch/powerpc/platforms/83xx/mpc834x_itx.c
+++ b/arch/powerpc/platforms/83xx/mpc834x_itx.c
@@ -38,11 +38,6 @@
38 38
39#include "mpc83xx.h" 39#include "mpc83xx.h"
40 40
41#ifndef CONFIG_PCI
42unsigned long isa_io_base = 0;
43unsigned long isa_mem_base = 0;
44#endif
45
46/* ************************************************************************ 41/* ************************************************************************
47 * 42 *
48 * Setup the architecture 43 * Setup the architecture
@@ -59,10 +54,12 @@ static void __init mpc834x_itx_setup_arch(void)
59 54
60#ifdef CONFIG_PCI 55#ifdef CONFIG_PCI
61 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) 56 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
62 add_bridge(np); 57 mpc83xx_add_bridge(np);
63 58
64 ppc_md.pci_exclude_device = mpc83xx_exclude_device; 59 ppc_md.pci_exclude_device = mpc83xx_exclude_device;
65#endif 60#endif
61
62 mpc834x_usb_cfg();
66} 63}
67 64
68static void __init mpc834x_itx_init_IRQ(void) 65static void __init mpc834x_itx_init_IRQ(void)
diff --git a/arch/powerpc/platforms/83xx/mpc834x_mds.c b/arch/powerpc/platforms/83xx/mpc834x_mds.c
index 10394b2d7e7a..4c9ff9cadfe4 100644
--- a/arch/powerpc/platforms/83xx/mpc834x_mds.c
+++ b/arch/powerpc/platforms/83xx/mpc834x_mds.c
@@ -38,61 +38,17 @@
38 38
39#include "mpc83xx.h" 39#include "mpc83xx.h"
40 40
41#ifndef CONFIG_PCI
42unsigned long isa_io_base = 0;
43unsigned long isa_mem_base = 0;
44#endif
45
46#define BCSR5_INT_USB 0x02 41#define BCSR5_INT_USB 0x02
47/* Note: This is only for PB, not for PB+PIB 42static int mpc834xemds_usb_cfg(void)
48 * On PB only port0 is connected using ULPI */
49static int mpc834x_usb_cfg(void)
50{ 43{
51 unsigned long sccr, sicrl; 44 struct device_node *np;
52 void __iomem *immap;
53 void __iomem *bcsr_regs = NULL; 45 void __iomem *bcsr_regs = NULL;
54 u8 bcsr5; 46 u8 bcsr5;
55 struct device_node *np = NULL;
56 int port0_is_dr = 0;
57
58 if ((np = of_find_compatible_node(NULL, "usb", "fsl-usb2-dr")) != NULL)
59 port0_is_dr = 1;
60 if ((np = of_find_compatible_node(NULL, "usb", "fsl-usb2-mph")) != NULL){
61 if (port0_is_dr) {
62 printk(KERN_WARNING
63 "There is only one USB port on PB board! \n");
64 return -1;
65 } else if (!port0_is_dr)
66 /* No usb port enabled */
67 return -1;
68 }
69
70 immap = ioremap(get_immrbase(), 0x1000);
71 if (!immap)
72 return -1;
73
74 /* Configure clock */
75 sccr = in_be32(immap + MPC83XX_SCCR_OFFS);
76 if (port0_is_dr)
77 sccr |= MPC83XX_SCCR_USB_DRCM_11; /* 1:3 */
78 else
79 sccr |= MPC83XX_SCCR_USB_MPHCM_11; /* 1:3 */
80 out_be32(immap + MPC83XX_SCCR_OFFS, sccr);
81
82 /* Configure Pin */
83 sicrl = in_be32(immap + MPC83XX_SICRL_OFFS);
84 /* set port0 only */
85 if (port0_is_dr)
86 sicrl |= MPC83XX_SICRL_USB0;
87 else
88 sicrl &= ~(MPC83XX_SICRL_USB0);
89 out_be32(immap + MPC83XX_SICRL_OFFS, sicrl);
90
91 iounmap(immap);
92 47
48 mpc834x_usb_cfg();
93 /* Map BCSR area */ 49 /* Map BCSR area */
94 np = of_find_node_by_name(NULL, "bcsr"); 50 np = of_find_node_by_name(NULL, "bcsr");
95 if (np != 0) { 51 if (np) {
96 struct resource res; 52 struct resource res;
97 53
98 of_address_to_resource(np, 0, &res); 54 of_address_to_resource(np, 0, &res);
@@ -129,12 +85,12 @@ static void __init mpc834x_mds_setup_arch(void)
129 85
130#ifdef CONFIG_PCI 86#ifdef CONFIG_PCI
131 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) 87 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
132 add_bridge(np); 88 mpc83xx_add_bridge(np);
133 89
134 ppc_md.pci_exclude_device = mpc83xx_exclude_device; 90 ppc_md.pci_exclude_device = mpc83xx_exclude_device;
135#endif 91#endif
136 92
137 mpc834x_usb_cfg(); 93 mpc834xemds_usb_cfg();
138} 94}
139 95
140static void __init mpc834x_mds_init_IRQ(void) 96static void __init mpc834x_mds_init_IRQ(void)
diff --git a/arch/powerpc/platforms/83xx/mpc836x_mds.c b/arch/powerpc/platforms/83xx/mpc836x_mds.c
index bceeff8bbfd2..0e615fd65c1f 100644
--- a/arch/powerpc/platforms/83xx/mpc836x_mds.c
+++ b/arch/powerpc/platforms/83xx/mpc836x_mds.c
@@ -55,11 +55,6 @@
55#define DBG(fmt...) 55#define DBG(fmt...)
56#endif 56#endif
57 57
58#ifndef CONFIG_PCI
59unsigned long isa_io_base = 0;
60unsigned long isa_mem_base = 0;
61#endif
62
63static u8 *bcsr_regs = NULL; 58static u8 *bcsr_regs = NULL;
64 59
65/* ************************************************************************ 60/* ************************************************************************
@@ -86,7 +81,7 @@ static void __init mpc836x_mds_setup_arch(void)
86 81
87#ifdef CONFIG_PCI 82#ifdef CONFIG_PCI
88 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) 83 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
89 add_bridge(np); 84 mpc83xx_add_bridge(np);
90 ppc_md.pci_exclude_device = mpc83xx_exclude_device; 85 ppc_md.pci_exclude_device = mpc83xx_exclude_device;
91#endif 86#endif
92 87
diff --git a/arch/powerpc/platforms/83xx/mpc83xx.h b/arch/powerpc/platforms/83xx/mpc83xx.h
index 9cd03b59c8f4..589ee55730f3 100644
--- a/arch/powerpc/platforms/83xx/mpc83xx.h
+++ b/arch/powerpc/platforms/83xx/mpc83xx.h
@@ -3,9 +3,11 @@
3 3
4#include <linux/init.h> 4#include <linux/init.h>
5#include <linux/device.h> 5#include <linux/device.h>
6#include <asm/pci-bridge.h>
6 7
7/* System Clock Control Register */ 8/* System Clock Control Register */
8#define MPC83XX_SCCR_OFFS 0xA08 9#define MPC83XX_SCCR_OFFS 0xA08
10#define MPC83XX_SCCR_USB_MASK 0x00f00000
9#define MPC83XX_SCCR_USB_MPHCM_11 0x00c00000 11#define MPC83XX_SCCR_USB_MPHCM_11 0x00c00000
10#define MPC83XX_SCCR_USB_MPHCM_01 0x00400000 12#define MPC83XX_SCCR_USB_MPHCM_01 0x00400000
11#define MPC83XX_SCCR_USB_MPHCM_10 0x00800000 13#define MPC83XX_SCCR_USB_MPHCM_10 0x00800000
@@ -15,21 +17,43 @@
15 17
16/* system i/o configuration register low */ 18/* system i/o configuration register low */
17#define MPC83XX_SICRL_OFFS 0x114 19#define MPC83XX_SICRL_OFFS 0x114
18#define MPC83XX_SICRL_USB0 0x40000000 20#define MPC834X_SICRL_USB_MASK 0x60000000
19#define MPC83XX_SICRL_USB1 0x20000000 21#define MPC834X_SICRL_USB0 0x40000000
22#define MPC834X_SICRL_USB1 0x20000000
23#define MPC831X_SICRL_USB_MASK 0x00000c00
24#define MPC831X_SICRL_USB_ULPI 0x00000800
20 25
21/* system i/o configuration register high */ 26/* system i/o configuration register high */
22#define MPC83XX_SICRH_OFFS 0x118 27#define MPC83XX_SICRH_OFFS 0x118
23#define MPC83XX_SICRH_USB_UTMI 0x00020000 28#define MPC834X_SICRH_USB_UTMI 0x00020000
29#define MPC831X_SICRH_USB_MASK 0x000000e0
30#define MPC831X_SICRH_USB_ULPI 0x000000a0
31
32/* USB Control Register */
33#define FSL_USB2_CONTROL_OFFS 0x500
34#define CONTROL_UTMI_PHY_EN 0x00000200
35#define CONTROL_REFSEL_48MHZ 0x00000080
36#define CONTROL_PHY_CLK_SEL_ULPI 0x00000400
37#define CONTROL_OTG_PORT 0x00000020
38
39/* USB PORTSC Registers */
40#define FSL_USB2_PORTSC1_OFFS 0x184
41#define FSL_USB2_PORTSC2_OFFS 0x188
42#define PORTSCX_PTW_16BIT 0x10000000
43#define PORTSCX_PTS_UTMI 0x00000000
44#define PORTSCX_PTS_ULPI 0x80000000
24 45
25/* 46/*
26 * Declaration for the various functions exported by the 47 * Declaration for the various functions exported by the
27 * mpc83xx_* files. Mostly for use by mpc83xx_setup 48 * mpc83xx_* files. Mostly for use by mpc83xx_setup
28 */ 49 */
29 50
30extern int add_bridge(struct device_node *dev); 51extern int mpc83xx_add_bridge(struct device_node *dev);
31extern int mpc83xx_exclude_device(u_char bus, u_char devfn); 52extern int mpc83xx_exclude_device(struct pci_controller *hose,
53 u_char bus, u_char devfn);
32extern void mpc83xx_restart(char *cmd); 54extern void mpc83xx_restart(char *cmd);
33extern long mpc83xx_time_init(void); 55extern long mpc83xx_time_init(void);
56extern int mpc834x_usb_cfg(void);
57extern int mpc831x_usb_cfg(void);
34 58
35#endif /* __MPC83XX_H__ */ 59#endif /* __MPC83XX_H__ */
diff --git a/arch/powerpc/platforms/83xx/pci.c b/arch/powerpc/platforms/83xx/pci.c
index 774457d09e94..c0e2b89154e5 100644
--- a/arch/powerpc/platforms/83xx/pci.c
+++ b/arch/powerpc/platforms/83xx/pci.c
@@ -33,19 +33,14 @@
33#define DBG(x...) 33#define DBG(x...)
34#endif 34#endif
35 35
36int mpc83xx_pci2_busno; 36int mpc83xx_exclude_device(struct pci_controller *hose, u_char bus, u_char devfn)
37
38int mpc83xx_exclude_device(u_char bus, u_char devfn)
39{ 37{
40 if (bus == 0 && PCI_SLOT(devfn) == 0) 38 if ((bus == hose->first_busno) && PCI_SLOT(devfn) == 0)
41 return PCIBIOS_DEVICE_NOT_FOUND; 39 return PCIBIOS_DEVICE_NOT_FOUND;
42 if (mpc83xx_pci2_busno)
43 if (bus == (mpc83xx_pci2_busno) && PCI_SLOT(devfn) == 0)
44 return PCIBIOS_DEVICE_NOT_FOUND;
45 return PCIBIOS_SUCCESSFUL; 40 return PCIBIOS_SUCCESSFUL;
46} 41}
47 42
48int __init add_bridge(struct device_node *dev) 43int __init mpc83xx_add_bridge(struct device_node *dev)
49{ 44{
50 int len; 45 int len;
51 struct pci_controller *hose; 46 struct pci_controller *hose;
@@ -66,11 +61,10 @@ int __init add_bridge(struct device_node *dev)
66 " bus 0\n", dev->full_name); 61 " bus 0\n", dev->full_name);
67 } 62 }
68 63
69 hose = pcibios_alloc_controller(); 64 pci_assign_all_buses = 1;
65 hose = pcibios_alloc_controller(dev);
70 if (!hose) 66 if (!hose)
71 return -ENOMEM; 67 return -ENOMEM;
72 hose->arch_data = dev;
73 hose->set_cfg_type = 1;
74 68
75 hose->first_busno = bus_range ? bus_range[0] : 0; 69 hose->first_busno = bus_range ? bus_range[0] : 0;
76 hose->last_busno = bus_range ? bus_range[1] : 0xff; 70 hose->last_busno = bus_range ? bus_range[1] : 0xff;
@@ -86,8 +80,6 @@ int __init add_bridge(struct device_node *dev)
86 if ((rsrc.start & 0xfffff) == 0x8600) { 80 if ((rsrc.start & 0xfffff) == 0x8600) {
87 setup_indirect_pci(hose, immr + 0x8380, immr + 0x8384); 81 setup_indirect_pci(hose, immr + 0x8380, immr + 0x8384);
88 primary = 0; 82 primary = 0;
89 hose->bus_offset = hose->first_busno;
90 mpc83xx_pci2_busno = hose->first_busno;
91 } 83 }
92 84
93 printk(KERN_INFO "Found MPC83xx PCI host bridge at 0x%016llx. " 85 printk(KERN_INFO "Found MPC83xx PCI host bridge at 0x%016llx. "
diff --git a/arch/powerpc/platforms/83xx/usb.c b/arch/powerpc/platforms/83xx/usb.c
new file mode 100644
index 000000000000..e7fdf013cd39
--- /dev/null
+++ b/arch/powerpc/platforms/83xx/usb.c
@@ -0,0 +1,181 @@
1/*
2 * Freescale 83xx USB SOC setup code
3 *
4 * Copyright (C) 2007 Freescale Semiconductor, Inc.
5 * Author: Li Yang
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13
14#include <linux/stddef.h>
15#include <linux/kernel.h>
16#include <linux/errno.h>
17
18#include <asm/io.h>
19#include <asm/prom.h>
20#include <sysdev/fsl_soc.h>
21
22#include "mpc83xx.h"
23
24
25#ifdef CONFIG_MPC834x
26int mpc834x_usb_cfg(void)
27{
28 unsigned long sccr, sicrl, sicrh;
29 void __iomem *immap;
30 struct device_node *np = NULL;
31 int port0_is_dr = 0, port1_is_dr = 0;
32 const void *prop, *dr_mode;
33
34 immap = ioremap(get_immrbase(), 0x1000);
35 if (!immap)
36 return -ENOMEM;
37
38 /* Read registers */
39 /* Note: DR and MPH must use the same clock setting in SCCR */
40 sccr = in_be32(immap + MPC83XX_SCCR_OFFS) & ~MPC83XX_SCCR_USB_MASK;
41 sicrl = in_be32(immap + MPC83XX_SICRL_OFFS) & ~MPC834X_SICRL_USB_MASK;
42 sicrh = in_be32(immap + MPC83XX_SICRH_OFFS) & ~MPC834X_SICRH_USB_UTMI;
43
44 np = of_find_compatible_node(NULL, "usb", "fsl-usb2-dr");
45 if (np) {
46 sccr |= MPC83XX_SCCR_USB_DRCM_11; /* 1:3 */
47
48 prop = of_get_property(np, "phy_type", NULL);
49 if (prop && (!strcmp(prop, "utmi") ||
50 !strcmp(prop, "utmi_wide"))) {
51 sicrl |= MPC834X_SICRL_USB0 | MPC834X_SICRL_USB1;
52 sicrh |= MPC834X_SICRH_USB_UTMI;
53 port1_is_dr = 1;
54 } else if (prop && !strcmp(prop, "serial")) {
55 dr_mode = of_get_property(np, "dr_mode", NULL);
56 if (dr_mode && !strcmp(dr_mode, "otg")) {
57 sicrl |= MPC834X_SICRL_USB0 | MPC834X_SICRL_USB1;
58 port1_is_dr = 1;
59 } else {
60 sicrl |= MPC834X_SICRL_USB0;
61 }
62 } else if (prop && !strcmp(prop, "ulpi")) {
63 sicrl |= MPC834X_SICRL_USB0;
64 } else {
65 printk(KERN_WARNING "834x USB PHY type not supported\n");
66 }
67 port0_is_dr = 1;
68 of_node_put(np);
69 }
70 np = of_find_compatible_node(NULL, "usb", "fsl-usb2-mph");
71 if (np) {
72 sccr |= MPC83XX_SCCR_USB_MPHCM_11; /* 1:3 */
73
74 prop = of_get_property(np, "port0", NULL);
75 if (prop) {
76 if (port0_is_dr)
77 printk(KERN_WARNING
78 "834x USB port0 can't be used by both DR and MPH!\n");
79 sicrl |= MPC834X_SICRL_USB0;
80 }
81 prop = of_get_property(np, "port1", NULL);
82 if (prop) {
83 if (port1_is_dr)
84 printk(KERN_WARNING
85 "834x USB port1 can't be used by both DR and MPH!\n");
86 sicrl |= MPC834X_SICRL_USB1;
87 }
88 of_node_put(np);
89 }
90
91 /* Write back */
92 out_be32(immap + MPC83XX_SCCR_OFFS, sccr);
93 out_be32(immap + MPC83XX_SICRL_OFFS, sicrl);
94 out_be32(immap + MPC83XX_SICRH_OFFS, sicrh);
95
96 iounmap(immap);
97 return 0;
98}
99#endif /* CONFIG_MPC834x */
100
101#ifdef CONFIG_PPC_MPC831x
102int mpc831x_usb_cfg(void)
103{
104 u32 temp;
105 void __iomem *immap, *usb_regs;
106 struct device_node *np = NULL;
107 const void *prop;
108 struct resource res;
109 int ret = 0;
110#ifdef CONFIG_USB_OTG
111 const void *dr_mode;
112#endif
113
114 np = of_find_compatible_node(NULL, "usb", "fsl-usb2-dr");
115 if (!np)
116 return -ENODEV;
117 prop = of_get_property(np, "phy_type", NULL);
118
119 /* Map IMMR space for pin and clock settings */
120 immap = ioremap(get_immrbase(), 0x1000);
121 if (!immap) {
122 of_node_put(np);
123 return -ENOMEM;
124 }
125
126 /* Configure clock */
127 temp = in_be32(immap + MPC83XX_SCCR_OFFS);
128 temp &= ~MPC83XX_SCCR_USB_MASK;
129 temp |= MPC83XX_SCCR_USB_DRCM_11; /* 1:3 */
130 out_be32(immap + MPC83XX_SCCR_OFFS, temp);
131
132 /* Configure pin mux for ULPI. There is no pin mux for UTMI */
133 if (!strcmp(prop, "ulpi")) {
134 temp = in_be32(immap + MPC83XX_SICRL_OFFS);
135 temp &= ~MPC831X_SICRL_USB_MASK;
136 temp |= MPC831X_SICRL_USB_ULPI;
137 out_be32(immap + MPC83XX_SICRL_OFFS, temp);
138
139 temp = in_be32(immap + MPC83XX_SICRH_OFFS);
140 temp &= ~MPC831X_SICRH_USB_MASK;
141 temp |= MPC831X_SICRH_USB_ULPI;
142 out_be32(immap + MPC83XX_SICRH_OFFS, temp);
143 }
144
145 iounmap(immap);
146
147 /* Map USB SOC space */
148 ret = of_address_to_resource(np, 0, &res);
149 if (ret) {
150 of_node_put(np);
151 return ret;
152 }
153 usb_regs = ioremap(res.start, res.end - res.start + 1);
154
155 /* Using on-chip PHY */
156 if (!strcmp(prop, "utmi_wide") ||
157 !strcmp(prop, "utmi")) {
158 /* Set UTMI_PHY_EN, REFSEL to 48MHZ */
159 out_be32(usb_regs + FSL_USB2_CONTROL_OFFS,
160 CONTROL_UTMI_PHY_EN | CONTROL_REFSEL_48MHZ);
161 /* Using external UPLI PHY */
162 } else if (!strcmp(prop, "ulpi")) {
163 /* Set PHY_CLK_SEL to ULPI */
164 temp = CONTROL_PHY_CLK_SEL_ULPI;
165#ifdef CONFIG_USB_OTG
166 /* Set OTG_PORT */
167 dr_mode = of_get_property(np, "dr_mode", NULL);
168 if (dr_mode && !strcmp(dr_mode, "otg"))
169 temp |= CONTROL_OTG_PORT;
170#endif /* CONFIG_USB_OTG */
171 out_be32(usb_regs + FSL_USB2_CONTROL_OFFS, temp);
172 } else {
173 printk(KERN_WARNING "831x USB PHY type not supported\n");
174 ret = -EINVAL;
175 }
176
177 iounmap(usb_regs);
178 of_node_put(np);
179 return ret;
180}
181#endif /* CONFIG_PPC_MPC831x */
diff --git a/arch/powerpc/platforms/85xx/misc.c b/arch/powerpc/platforms/85xx/misc.c
index 3e62fcb04c1c..4fe376e9c3b6 100644
--- a/arch/powerpc/platforms/85xx/misc.c
+++ b/arch/powerpc/platforms/85xx/misc.c
@@ -13,11 +13,43 @@
13#include <linux/irq.h> 13#include <linux/irq.h>
14#include <linux/module.h> 14#include <linux/module.h>
15#include <asm/irq.h> 15#include <asm/irq.h>
16#include <asm/io.h>
17#include <asm/prom.h>
18#include <sysdev/fsl_soc.h>
19
20static __be32 __iomem *rstcr;
16 21
17extern void abort(void); 22extern void abort(void);
18 23
24static int __init mpc85xx_rstcr(void)
25{
26 struct device_node *np;
27 np = of_find_node_by_name(NULL, "global-utilities");
28 if ((np && of_get_property(np, "fsl,has-rstcr", NULL))) {
29 const u32 *prop = of_get_property(np, "reg", NULL);
30 if (prop) {
31 /* map reset control register
32 * 0xE00B0 is offset of reset control register
33 */
34 rstcr = ioremap(get_immrbase() + *prop + 0xB0, 0xff);
35 if (!rstcr)
36 printk (KERN_EMERG "Error: reset control "
37 "register not mapped!\n");
38 }
39 } else
40 printk (KERN_INFO "rstcr compatible register does not exist!\n");
41 if (np)
42 of_node_put(np);
43 return 0;
44}
45
46arch_initcall(mpc85xx_rstcr);
47
19void mpc85xx_restart(char *cmd) 48void mpc85xx_restart(char *cmd)
20{ 49{
21 local_irq_disable(); 50 local_irq_disable();
51 if (rstcr)
52 /* set reset control register */
53 out_be32(rstcr, 0x2); /* HRESET_REQ */
22 abort(); 54 abort();
23} 55}
diff --git a/arch/powerpc/platforms/85xx/mpc8544_ds.c b/arch/powerpc/platforms/85xx/mpc8544_ds.c
index bec84ffe708e..6fb90aab879f 100644
--- a/arch/powerpc/platforms/85xx/mpc8544_ds.c
+++ b/arch/powerpc/platforms/85xx/mpc8544_ds.c
@@ -61,24 +61,11 @@ void __init mpc8544_ds_pic_init(void)
61 return; 61 return;
62 } 62 }
63 63
64 /* Alloc mpic structure and per isu has 16 INT entries. */
65 mpic = mpic_alloc(np, r.start, 64 mpic = mpic_alloc(np, r.start,
66 MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, 65 MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN,
67 16, 64, " OPENPIC "); 66 0, 256, " OpenPIC ");
68 BUG_ON(mpic == NULL); 67 BUG_ON(mpic == NULL);
69 68
70 /*
71 * 48 Internal Interrupts
72 */
73 mpic_assign_isu(mpic, 0, r.start + 0x10200);
74 mpic_assign_isu(mpic, 1, r.start + 0x10400);
75 mpic_assign_isu(mpic, 2, r.start + 0x10600);
76
77 /*
78 * 16 External interrupts
79 */
80 mpic_assign_isu(mpic, 3, r.start + 0x10000);
81
82 mpic_init(mpic); 69 mpic_init(mpic);
83 70
84#ifdef CONFIG_PPC_I8259 71#ifdef CONFIG_PPC_I8259
diff --git a/arch/powerpc/platforms/85xx/mpc85xx.h b/arch/powerpc/platforms/85xx/mpc85xx.h
index 83415db33378..7286ffac2c1d 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx.h
+++ b/arch/powerpc/platforms/85xx/mpc85xx.h
@@ -15,4 +15,4 @@
15 */ 15 */
16 16
17extern void mpc85xx_restart(char *); 17extern void mpc85xx_restart(char *);
18extern int add_bridge(struct device_node *dev); 18extern int mpc85xx_add_bridge(struct device_node *dev);
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ads.c b/arch/powerpc/platforms/85xx/mpc85xx_ads.c
index 5d27621f0927..7235f702394c 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_ads.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_ads.c
@@ -38,13 +38,9 @@
38#include <asm/fs_pd.h> 38#include <asm/fs_pd.h>
39#endif 39#endif
40 40
41#ifndef CONFIG_PCI
42unsigned long isa_io_base = 0;
43unsigned long isa_mem_base = 0;
44#endif
45
46#ifdef CONFIG_PCI 41#ifdef CONFIG_PCI
47static int mpc85xx_exclude_device(u_char bus, u_char devfn) 42static int mpc85xx_exclude_device(struct pci_controller *hose,
43 u_char bus, u_char devfn)
48{ 44{
49 if (bus == 0 && PCI_SLOT(devfn) == 0) 45 if (bus == 0 && PCI_SLOT(devfn) == 0)
50 return PCIBIOS_DEVICE_NOT_FOUND; 46 return PCIBIOS_DEVICE_NOT_FOUND;
@@ -91,30 +87,10 @@ static void __init mpc85xx_ads_pic_init(void)
91 87
92 mpic = mpic_alloc(np, r.start, 88 mpic = mpic_alloc(np, r.start,
93 MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, 89 MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN,
94 4, 0, " OpenPIC "); 90 0, 256, " OpenPIC ");
95 BUG_ON(mpic == NULL); 91 BUG_ON(mpic == NULL);
96 of_node_put(np); 92 of_node_put(np);
97 93
98 mpic_assign_isu(mpic, 0, r.start + 0x10200);
99 mpic_assign_isu(mpic, 1, r.start + 0x10280);
100 mpic_assign_isu(mpic, 2, r.start + 0x10300);
101 mpic_assign_isu(mpic, 3, r.start + 0x10380);
102 mpic_assign_isu(mpic, 4, r.start + 0x10400);
103 mpic_assign_isu(mpic, 5, r.start + 0x10480);
104 mpic_assign_isu(mpic, 6, r.start + 0x10500);
105 mpic_assign_isu(mpic, 7, r.start + 0x10580);
106
107 /* Unused on this platform (leave room for 8548) */
108 mpic_assign_isu(mpic, 8, r.start + 0x10600);
109 mpic_assign_isu(mpic, 9, r.start + 0x10680);
110 mpic_assign_isu(mpic, 10, r.start + 0x10700);
111 mpic_assign_isu(mpic, 11, r.start + 0x10780);
112
113 /* External Interrupts */
114 mpic_assign_isu(mpic, 12, r.start + 0x10000);
115 mpic_assign_isu(mpic, 13, r.start + 0x10080);
116 mpic_assign_isu(mpic, 14, r.start + 0x10100);
117
118 mpic_init(mpic); 94 mpic_init(mpic);
119 95
120#ifdef CONFIG_CPM2 96#ifdef CONFIG_CPM2
@@ -241,7 +217,7 @@ static void __init mpc85xx_ads_setup_arch(void)
241 217
242#ifdef CONFIG_PCI 218#ifdef CONFIG_PCI
243 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) 219 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
244 add_bridge(np); 220 mpc85xx_add_bridge(np);
245 ppc_md.pci_exclude_device = mpc85xx_exclude_device; 221 ppc_md.pci_exclude_device = mpc85xx_exclude_device;
246#endif 222#endif
247} 223}
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_cds.c b/arch/powerpc/platforms/85xx/mpc85xx_cds.c
index 1490eb3ce0d3..50c8d6458362 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_cds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_cds.c
@@ -47,11 +47,6 @@
47#include <sysdev/fsl_soc.h> 47#include <sysdev/fsl_soc.h>
48#include "mpc85xx.h" 48#include "mpc85xx.h"
49 49
50#ifndef CONFIG_PCI
51unsigned long isa_io_base = 0;
52unsigned long isa_mem_base = 0;
53#endif
54
55static int cds_pci_slot = 2; 50static int cds_pci_slot = 2;
56static volatile u8 *cadmus; 51static volatile u8 *cadmus;
57 52
@@ -60,15 +55,11 @@ static volatile u8 *cadmus;
60#define ARCADIA_HOST_BRIDGE_IDSEL 17 55#define ARCADIA_HOST_BRIDGE_IDSEL 17
61#define ARCADIA_2ND_BRIDGE_IDSEL 3 56#define ARCADIA_2ND_BRIDGE_IDSEL 3
62 57
63extern int mpc85xx_pci2_busno; 58static int mpc85xx_exclude_device(struct pci_controller *hose,
64 59 u_char bus, u_char devfn)
65static int mpc85xx_exclude_device(u_char bus, u_char devfn)
66{ 60{
67 if (bus == 0 && PCI_SLOT(devfn) == 0) 61 if ((bus == hose->first_busno) && PCI_SLOT(devfn) == 0)
68 return PCIBIOS_DEVICE_NOT_FOUND; 62 return PCIBIOS_DEVICE_NOT_FOUND;
69 if (mpc85xx_pci2_busno)
70 if (bus == (mpc85xx_pci2_busno) && PCI_SLOT(devfn) == 0)
71 return PCIBIOS_DEVICE_NOT_FOUND;
72 /* We explicitly do not go past the Tundra 320 Bridge */ 63 /* We explicitly do not go past the Tundra 320 Bridge */
73 if ((bus == 1) && (PCI_SLOT(devfn) == ARCADIA_2ND_BRIDGE_IDSEL)) 64 if ((bus == 1) && (PCI_SLOT(devfn) == ARCADIA_2ND_BRIDGE_IDSEL))
74 return PCIBIOS_DEVICE_NOT_FOUND; 65 return PCIBIOS_DEVICE_NOT_FOUND;
@@ -78,52 +69,44 @@ static int mpc85xx_exclude_device(u_char bus, u_char devfn)
78 return PCIBIOS_SUCCESSFUL; 69 return PCIBIOS_SUCCESSFUL;
79} 70}
80 71
81static void __init mpc85xx_cds_pcibios_fixup(void) 72static void __init mpc85xx_cds_pci_irq_fixup(struct pci_dev *dev)
82{ 73{
83 struct pci_dev *dev; 74 u_char c;
84 u_char c; 75 if (dev->vendor == PCI_VENDOR_ID_VIA) {
85 76 switch (dev->device) {
86 if ((dev = pci_get_device(PCI_VENDOR_ID_VIA, 77 case PCI_DEVICE_ID_VIA_82C586_1:
87 PCI_DEVICE_ID_VIA_82C586_1, NULL))) { 78 /*
79 * U-Boot does not set the enable bits
80 * for the IDE device. Force them on here.
81 */
82 pci_read_config_byte(dev, 0x40, &c);
83 c |= 0x03; /* IDE: Chip Enable Bits */
84 pci_write_config_byte(dev, 0x40, c);
85
86 /*
87 * Since only primary interface works, force the
88 * IDE function to standard primary IDE interrupt
89 * w/ 8259 offset
90 */
91 dev->irq = 14;
92 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
93 break;
88 /* 94 /*
89 * U-Boot does not set the enable bits 95 * Force legacy USB interrupt routing
90 * for the IDE device. Force them on here.
91 */ 96 */
92 pci_read_config_byte(dev, 0x40, &c); 97 case PCI_DEVICE_ID_VIA_82C586_2:
93 c |= 0x03; /* IDE: Chip Enable Bits */ 98 /* There are two USB controllers.
94 pci_write_config_byte(dev, 0x40, c); 99 * Identify them by functon number
95
96 /*
97 * Since only primary interface works, force the
98 * IDE function to standard primary IDE interrupt
99 * w/ 8259 offset
100 */ 100 */
101 dev->irq = 14; 101 if (PCI_FUNC(dev->devfn))
102 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); 102 dev->irq = 11;
103 pci_dev_put(dev); 103 else
104 } 104 dev->irq = 10;
105 105 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
106 /* 106 default:
107 * Force legacy USB interrupt routing 107 break;
108 */ 108 }
109 if ((dev = pci_get_device(PCI_VENDOR_ID_VIA,
110 PCI_DEVICE_ID_VIA_82C586_2, NULL))) {
111 dev->irq = 10;
112 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 10);
113 pci_dev_put(dev);
114 }
115
116 if ((dev = pci_get_device(PCI_VENDOR_ID_VIA,
117 PCI_DEVICE_ID_VIA_82C586_2, dev))) {
118 dev->irq = 11;
119 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 11);
120 pci_dev_put(dev);
121 } 109 }
122
123 /* Now map all the PCI irqs */
124 dev = NULL;
125 for_each_pci_dev(dev)
126 pci_read_irq_line(dev);
127} 110}
128 111
129#ifdef CONFIG_PPC_I8259 112#ifdef CONFIG_PPC_I8259
@@ -165,33 +148,12 @@ static void __init mpc85xx_cds_pic_init(void)
165 148
166 mpic = mpic_alloc(np, r.start, 149 mpic = mpic_alloc(np, r.start,
167 MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, 150 MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN,
168 4, 0, " OpenPIC "); 151 0, 256, " OpenPIC ");
169 BUG_ON(mpic == NULL); 152 BUG_ON(mpic == NULL);
170 153
171 /* Return the mpic node */ 154 /* Return the mpic node */
172 of_node_put(np); 155 of_node_put(np);
173 156
174 mpic_assign_isu(mpic, 0, r.start + 0x10200);
175 mpic_assign_isu(mpic, 1, r.start + 0x10280);
176 mpic_assign_isu(mpic, 2, r.start + 0x10300);
177 mpic_assign_isu(mpic, 3, r.start + 0x10380);
178 mpic_assign_isu(mpic, 4, r.start + 0x10400);
179 mpic_assign_isu(mpic, 5, r.start + 0x10480);
180 mpic_assign_isu(mpic, 6, r.start + 0x10500);
181 mpic_assign_isu(mpic, 7, r.start + 0x10580);
182
183 /* Used only for 8548 so far, but no harm in
184 * allocating them for everyone */
185 mpic_assign_isu(mpic, 8, r.start + 0x10600);
186 mpic_assign_isu(mpic, 9, r.start + 0x10680);
187 mpic_assign_isu(mpic, 10, r.start + 0x10700);
188 mpic_assign_isu(mpic, 11, r.start + 0x10780);
189
190 /* External Interrupts */
191 mpic_assign_isu(mpic, 12, r.start + 0x10000);
192 mpic_assign_isu(mpic, 13, r.start + 0x10080);
193 mpic_assign_isu(mpic, 14, r.start + 0x10100);
194
195 mpic_init(mpic); 157 mpic_init(mpic);
196 158
197#ifdef CONFIG_PPC_I8259 159#ifdef CONFIG_PPC_I8259
@@ -257,9 +219,9 @@ static void __init mpc85xx_cds_setup_arch(void)
257 219
258#ifdef CONFIG_PCI 220#ifdef CONFIG_PCI
259 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) 221 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
260 add_bridge(np); 222 mpc85xx_add_bridge(np);
261 223
262 ppc_md.pcibios_fixup = mpc85xx_cds_pcibios_fixup; 224 ppc_md.pci_irq_fixup = mpc85xx_cds_pci_irq_fixup;
263 ppc_md.pci_exclude_device = mpc85xx_exclude_device; 225 ppc_md.pci_exclude_device = mpc85xx_exclude_device;
264#endif 226#endif
265} 227}
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
index e3dddbfe66ff..004b80bd0b84 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
@@ -59,11 +59,6 @@
59#define DBG(fmt...) 59#define DBG(fmt...)
60#endif 60#endif
61 61
62#ifndef CONFIG_PCI
63unsigned long isa_io_base = 0;
64unsigned long isa_mem_base = 0;
65#endif
66
67/* ************************************************************************ 62/* ************************************************************************
68 * 63 *
69 * Setup the architecture 64 * Setup the architecture
@@ -100,7 +95,7 @@ static void __init mpc85xx_mds_setup_arch(void)
100 95
101#ifdef CONFIG_PCI 96#ifdef CONFIG_PCI
102 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) { 97 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) {
103 add_bridge(np); 98 mpc85xx_add_bridge(np);
104 } 99 }
105 of_node_put(np); 100 of_node_put(np);
106#endif 101#endif
@@ -181,29 +176,10 @@ static void __init mpc85xx_mds_pic_init(void)
181 176
182 mpic = mpic_alloc(np, r.start, 177 mpic = mpic_alloc(np, r.start,
183 MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, 178 MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN,
184 4, 0, " OpenPIC "); 179 0, 256, " OpenPIC ");
185 BUG_ON(mpic == NULL); 180 BUG_ON(mpic == NULL);
186 of_node_put(np); 181 of_node_put(np);
187 182
188 /* Internal Interrupts */
189 mpic_assign_isu(mpic, 0, r.start + 0x10200);
190 mpic_assign_isu(mpic, 1, r.start + 0x10280);
191 mpic_assign_isu(mpic, 2, r.start + 0x10300);
192 mpic_assign_isu(mpic, 3, r.start + 0x10380);
193 mpic_assign_isu(mpic, 4, r.start + 0x10400);
194 mpic_assign_isu(mpic, 5, r.start + 0x10480);
195 mpic_assign_isu(mpic, 6, r.start + 0x10500);
196 mpic_assign_isu(mpic, 7, r.start + 0x10580);
197 mpic_assign_isu(mpic, 8, r.start + 0x10600);
198 mpic_assign_isu(mpic, 9, r.start + 0x10680);
199 mpic_assign_isu(mpic, 10, r.start + 0x10700);
200 mpic_assign_isu(mpic, 11, r.start + 0x10780);
201
202 /* External Interrupts */
203 mpic_assign_isu(mpic, 12, r.start + 0x10000);
204 mpic_assign_isu(mpic, 13, r.start + 0x10080);
205 mpic_assign_isu(mpic, 14, r.start + 0x10100);
206
207 mpic_init(mpic); 183 mpic_init(mpic);
208 184
209#ifdef CONFIG_QUICC_ENGINE 185#ifdef CONFIG_QUICC_ENGINE
diff --git a/arch/powerpc/platforms/85xx/pci.c b/arch/powerpc/platforms/85xx/pci.c
index 48f17e23d771..8118417b7364 100644
--- a/arch/powerpc/platforms/85xx/pci.c
+++ b/arch/powerpc/platforms/85xx/pci.c
@@ -33,10 +33,8 @@
33#define DBG(x...) 33#define DBG(x...)
34#endif 34#endif
35 35
36int mpc85xx_pci2_busno = 0;
37
38#ifdef CONFIG_PCI 36#ifdef CONFIG_PCI
39int __init add_bridge(struct device_node *dev) 37int __init mpc85xx_add_bridge(struct device_node *dev)
40{ 38{
41 int len; 39 int len;
42 struct pci_controller *hose; 40 struct pci_controller *hose;
@@ -57,11 +55,10 @@ int __init add_bridge(struct device_node *dev)
57 " bus 0\n", dev->full_name); 55 " bus 0\n", dev->full_name);
58 } 56 }
59 57
60 hose = pcibios_alloc_controller(); 58 pci_assign_all_buses = 1;
59 hose = pcibios_alloc_controller(dev);
61 if (!hose) 60 if (!hose)
62 return -ENOMEM; 61 return -ENOMEM;
63 hose->arch_data = dev;
64 hose->set_cfg_type = 1;
65 62
66 hose->first_busno = bus_range ? bus_range[0] : 0; 63 hose->first_busno = bus_range ? bus_range[0] : 0;
67 hose->last_busno = bus_range ? bus_range[1] : 0xff; 64 hose->last_busno = bus_range ? bus_range[1] : 0xff;
@@ -74,8 +71,6 @@ int __init add_bridge(struct device_node *dev)
74 if ((rsrc.start & 0xfffff) == 0x9000) { 71 if ((rsrc.start & 0xfffff) == 0x9000) {
75 setup_indirect_pci(hose, immr + 0x9000, immr + 0x9004); 72 setup_indirect_pci(hose, immr + 0x9000, immr + 0x9004);
76 primary = 0; 73 primary = 0;
77 hose->bus_offset = hose->first_busno;
78 mpc85xx_pci2_busno = hose->first_busno;
79 } 74 }
80 75
81 printk(KERN_INFO "Found MPC85xx PCI host bridge at 0x%016llx. " 76 printk(KERN_INFO "Found MPC85xx PCI host bridge at 0x%016llx. "
diff --git a/arch/powerpc/platforms/86xx/Kconfig b/arch/powerpc/platforms/86xx/Kconfig
index d1bcff500464..0faebfdc1596 100644
--- a/arch/powerpc/platforms/86xx/Kconfig
+++ b/arch/powerpc/platforms/86xx/Kconfig
@@ -1,5 +1,5 @@
1choice 1choice
2 prompt "Machine Type" 2 prompt "86xx Board Type"
3 depends on PPC_86xx 3 depends on PPC_86xx
4 default MPC8641_HPCN 4 default MPC8641_HPCN
5 5
diff --git a/arch/powerpc/platforms/86xx/mpc86xx.h b/arch/powerpc/platforms/86xx/mpc86xx.h
index 2834462590b8..23f7ed2a7f88 100644
--- a/arch/powerpc/platforms/86xx/mpc86xx.h
+++ b/arch/powerpc/platforms/86xx/mpc86xx.h
@@ -15,15 +15,10 @@
15 * mpc86xx_* files. Mostly for use by mpc86xx_setup(). 15 * mpc86xx_* files. Mostly for use by mpc86xx_setup().
16 */ 16 */
17 17
18extern int add_bridge(struct device_node *dev); 18extern int mpc86xx_add_bridge(struct device_node *dev);
19 19
20extern int mpc86xx_exclude_device(u_char bus, u_char devfn); 20extern int mpc86xx_exclude_device(struct pci_controller *hose,
21 21 u_char bus, u_char devfn);
22extern void setup_indirect_pcie(struct pci_controller *hose,
23 u32 cfg_addr, u32 cfg_data);
24extern void setup_indirect_pcie_nomap(struct pci_controller *hose,
25 void __iomem *cfg_addr,
26 void __iomem *cfg_data);
27 22
28extern void __init mpc86xx_smp_init(void); 23extern void __init mpc86xx_smp_init(void);
29 24
diff --git a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
index 1051702c8d4f..5b01ec7c13dc 100644
--- a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
+++ b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
@@ -44,13 +44,6 @@
44#define DBG(fmt...) do { } while(0) 44#define DBG(fmt...) do { } while(0)
45#endif 45#endif
46 46
47#ifndef CONFIG_PCI
48unsigned long isa_io_base = 0;
49unsigned long isa_mem_base = 0;
50unsigned long pci_dram_offset = 0;
51#endif
52
53
54#ifdef CONFIG_PCI 47#ifdef CONFIG_PCI
55static void mpc86xx_8259_cascade(unsigned int irq, struct irq_desc *desc) 48static void mpc86xx_8259_cascade(unsigned int irq, struct irq_desc *desc)
56{ 49{
@@ -81,22 +74,9 @@ mpc86xx_hpcn_init_irq(void)
81 /* Alloc mpic structure and per isu has 16 INT entries. */ 74 /* Alloc mpic structure and per isu has 16 INT entries. */
82 mpic1 = mpic_alloc(np, res.start, 75 mpic1 = mpic_alloc(np, res.start,
83 MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, 76 MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN,
84 16, NR_IRQS - 4, 77 0, 256, " MPIC ");
85 " MPIC ");
86 BUG_ON(mpic1 == NULL); 78 BUG_ON(mpic1 == NULL);
87 79
88 mpic_assign_isu(mpic1, 0, res.start + 0x10000);
89
90 /* 48 Internal Interrupts */
91 mpic_assign_isu(mpic1, 1, res.start + 0x10200);
92 mpic_assign_isu(mpic1, 2, res.start + 0x10400);
93 mpic_assign_isu(mpic1, 3, res.start + 0x10600);
94
95 /* 16 External interrupts
96 * Moving them from [0 - 15] to [64 - 79]
97 */
98 mpic_assign_isu(mpic1, 4, res.start + 0x10000);
99
100 mpic_init(mpic1); 80 mpic_init(mpic1);
101 81
102#ifdef CONFIG_PCI 82#ifdef CONFIG_PCI
@@ -319,6 +299,7 @@ static void __devinit quirk_uli5229(struct pci_dev *dev)
319{ 299{
320 unsigned short temp; 300 unsigned short temp;
321 pci_write_config_word(dev, 0x04, 0x0405); 301 pci_write_config_word(dev, 0x04, 0x0405);
302 dev->class &= ~0x5;
322 pci_read_config_word(dev, 0x4a, &temp); 303 pci_read_config_word(dev, 0x4a, &temp);
323 temp |= 0x1000; 304 temp |= 0x1000;
324 pci_write_config_word(dev, 0x4a, temp); 305 pci_write_config_word(dev, 0x4a, temp);
@@ -364,9 +345,7 @@ mpc86xx_hpcn_setup_arch(void)
364 345
365#ifdef CONFIG_PCI 346#ifdef CONFIG_PCI
366 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) 347 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
367 add_bridge(np); 348 mpc86xx_add_bridge(np);
368
369 ppc_md.pci_exclude_device = mpc86xx_exclude_device;
370#endif 349#endif
371 350
372 printk("MPC86xx HPCN board from Freescale Semiconductor\n"); 351 printk("MPC86xx HPCN board from Freescale Semiconductor\n");
diff --git a/arch/powerpc/platforms/86xx/pci.c b/arch/powerpc/platforms/86xx/pci.c
index 8235c562661f..73cd5b05a84e 100644
--- a/arch/powerpc/platforms/86xx/pci.c
+++ b/arch/powerpc/platforms/86xx/pci.c
@@ -122,7 +122,6 @@ static void __init
122mpc86xx_setup_pcie(struct pci_controller *hose, u32 pcie_offset, u32 pcie_size) 122mpc86xx_setup_pcie(struct pci_controller *hose, u32 pcie_offset, u32 pcie_size)
123{ 123{
124 u16 cmd; 124 u16 cmd;
125 unsigned int temps;
126 125
127 DBG("PCIE host controller register offset 0x%08x, size 0x%08x.\n", 126 DBG("PCIE host controller register offset 0x%08x, size 0x%08x.\n",
128 pcie_offset, pcie_size); 127 pcie_offset, pcie_size);
@@ -133,22 +132,49 @@ mpc86xx_setup_pcie(struct pci_controller *hose, u32 pcie_offset, u32 pcie_size)
133 early_write_config_word(hose, 0, 0, PCI_COMMAND, cmd); 132 early_write_config_word(hose, 0, 0, PCI_COMMAND, cmd);
134 133
135 early_write_config_byte(hose, 0, 0, PCI_LATENCY_TIMER, 0x80); 134 early_write_config_byte(hose, 0, 0, PCI_LATENCY_TIMER, 0x80);
136
137 /* PCIE Bus, Fix the MPC8641D host bridge's location to bus 0xFF. */
138 early_read_config_dword(hose, 0, 0, PCI_PRIMARY_BUS, &temps);
139 temps = (temps & 0xff000000) | (0xff) | (0x0 << 8) | (0xfe << 16);
140 early_write_config_dword(hose, 0, 0, PCI_PRIMARY_BUS, temps);
141} 135}
142 136
143int mpc86xx_exclude_device(u_char bus, u_char devfn) 137static void __devinit quirk_fsl_pcie_transparent(struct pci_dev *dev)
144{ 138{
145 if (bus == 0 && PCI_SLOT(devfn) == 0) 139 struct resource *res;
146 return PCIBIOS_DEVICE_NOT_FOUND; 140 int i, res_idx = PCI_BRIDGE_RESOURCES;
141 struct pci_controller *hose;
147 142
148 return PCIBIOS_SUCCESSFUL; 143 /*
144 * Make the bridge be transparent.
145 */
146 dev->transparent = 1;
147
148 hose = pci_bus_to_host(dev->bus);
149 if (!hose) {
150 printk(KERN_ERR "Can't find hose for bus %d\n",
151 dev->bus->number);
152 return;
153 }
154
155 if (hose->io_resource.flags) {
156 res = &dev->resource[res_idx++];
157 res->start = hose->io_resource.start;
158 res->end = hose->io_resource.end;
159 res->flags = hose->io_resource.flags;
160 }
161
162 for (i = 0; i < 3; i++) {
163 res = &dev->resource[res_idx + i];
164 res->start = hose->mem_resources[i].start;
165 res->end = hose->mem_resources[i].end;
166 res->flags = hose->mem_resources[i].flags;
167 }
149} 168}
150 169
151int __init add_bridge(struct device_node *dev) 170
171DECLARE_PCI_FIXUP_EARLY(0x1957, 0x7010, quirk_fsl_pcie_transparent);
172DECLARE_PCI_FIXUP_EARLY(0x1957, 0x7011, quirk_fsl_pcie_transparent);
173
174#define PCIE_LTSSM 0x404 /* PCIe Link Training and Status */
175#define PCIE_LTSSM_L0 0x16 /* L0 state */
176
177int __init mpc86xx_add_bridge(struct device_node *dev)
152{ 178{
153 int len; 179 int len;
154 struct pci_controller *hose; 180 struct pci_controller *hose;
@@ -156,6 +182,7 @@ int __init add_bridge(struct device_node *dev)
156 const int *bus_range; 182 const int *bus_range;
157 int has_address = 0; 183 int has_address = 0;
158 int primary = 0; 184 int primary = 0;
185 u16 val;
159 186
160 DBG("Adding PCIE host bridge %s\n", dev->full_name); 187 DBG("Adding PCIE host bridge %s\n", dev->full_name);
161 188
@@ -168,17 +195,23 @@ int __init add_bridge(struct device_node *dev)
168 printk(KERN_WARNING "Can't get bus-range for %s, assume" 195 printk(KERN_WARNING "Can't get bus-range for %s, assume"
169 " bus 0\n", dev->full_name); 196 " bus 0\n", dev->full_name);
170 197
171 hose = pcibios_alloc_controller(); 198 pci_assign_all_buses = 1;
199 hose = pcibios_alloc_controller(dev);
172 if (!hose) 200 if (!hose)
173 return -ENOMEM; 201 return -ENOMEM;
174 hose->arch_data = dev;
175 hose->set_cfg_type = 1;
176 202
177 /* last_busno = 0xfe cause by MPC8641 PCIE bug */ 203 hose->indirect_type = PPC_INDIRECT_TYPE_EXT_REG |
204 PPC_INDIRECT_TYPE_SURPRESS_PRIMARY_BUS;
205
178 hose->first_busno = bus_range ? bus_range[0] : 0x0; 206 hose->first_busno = bus_range ? bus_range[0] : 0x0;
179 hose->last_busno = bus_range ? bus_range[1] : 0xfe; 207 hose->last_busno = bus_range ? bus_range[1] : 0xff;
208
209 setup_indirect_pci(hose, rsrc.start, rsrc.start + 0x4);
180 210
181 setup_indirect_pcie(hose, rsrc.start, rsrc.start + 0x4); 211 /* Probe the hose link training status */
212 early_read_config_word(hose, 0, 0, PCIE_LTSSM, &val);
213 if (val < PCIE_LTSSM_L0)
214 return -ENXIO;
182 215
183 /* Setup the PCIE host controller. */ 216 /* Setup the PCIE host controller. */
184 mpc86xx_setup_pcie(hose, rsrc.start, rsrc.end - rsrc.start + 1); 217 mpc86xx_setup_pcie(hose, rsrc.start, rsrc.end - rsrc.start + 1);
diff --git a/arch/powerpc/platforms/8xx/m8xx_setup.c b/arch/powerpc/platforms/8xx/m8xx_setup.c
index 0901dbada350..f1693550c70c 100644
--- a/arch/powerpc/platforms/8xx/m8xx_setup.c
+++ b/arch/powerpc/platforms/8xx/m8xx_setup.c
@@ -32,6 +32,7 @@
32#include <linux/root_dev.h> 32#include <linux/root_dev.h>
33#include <linux/time.h> 33#include <linux/time.h>
34#include <linux/rtc.h> 34#include <linux/rtc.h>
35#include <linux/fsl_devices.h>
35 36
36#include <asm/mmu.h> 37#include <asm/mmu.h>
37#include <asm/reg.h> 38#include <asm/reg.h>
@@ -49,6 +50,10 @@
49 50
50#include "sysdev/mpc8xx_pic.h" 51#include "sysdev/mpc8xx_pic.h"
51 52
53#ifdef CONFIG_PCMCIA_M8XX
54struct mpc8xx_pcmcia_ops m8xx_pcmcia_ops;
55#endif
56
52void m8xx_calibrate_decr(void); 57void m8xx_calibrate_decr(void);
53extern void m8xx_wdt_handler_install(bd_t *bp); 58extern void m8xx_wdt_handler_install(bd_t *bp);
54extern int cpm_pic_init(void); 59extern int cpm_pic_init(void);
diff --git a/arch/powerpc/platforms/8xx/mpc885ads_setup.c b/arch/powerpc/platforms/8xx/mpc885ads_setup.c
index c36e475d93dc..dc27dab48df0 100644
--- a/arch/powerpc/platforms/8xx/mpc885ads_setup.c
+++ b/arch/powerpc/platforms/8xx/mpc885ads_setup.c
@@ -22,6 +22,7 @@
22 22
23#include <linux/fs_enet_pd.h> 23#include <linux/fs_enet_pd.h>
24#include <linux/fs_uart_pd.h> 24#include <linux/fs_uart_pd.h>
25#include <linux/fsl_devices.h>
25#include <linux/mii.h> 26#include <linux/mii.h>
26 27
27#include <asm/delay.h> 28#include <asm/delay.h>
@@ -51,6 +52,70 @@ static void init_smc1_uart_ioports(struct fs_uart_platform_info* fpi);
51static void init_smc2_uart_ioports(struct fs_uart_platform_info* fpi); 52static void init_smc2_uart_ioports(struct fs_uart_platform_info* fpi);
52static void init_scc3_ioports(struct fs_platform_info* ptr); 53static void init_scc3_ioports(struct fs_platform_info* ptr);
53 54
55#ifdef CONFIG_PCMCIA_M8XX
56static void pcmcia_hw_setup(int slot, int enable)
57{
58 unsigned *bcsr_io;
59
60 bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
61 if (enable)
62 clrbits32(bcsr_io, BCSR1_PCCEN);
63 else
64 setbits32(bcsr_io, BCSR1_PCCEN);
65
66 iounmap(bcsr_io);
67}
68
69static int pcmcia_set_voltage(int slot, int vcc, int vpp)
70{
71 u32 reg = 0;
72 unsigned *bcsr_io;
73
74 bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
75
76 switch(vcc) {
77 case 0:
78 break;
79 case 33:
80 reg |= BCSR1_PCCVCC0;
81 break;
82 case 50:
83 reg |= BCSR1_PCCVCC1;
84 break;
85 default:
86 return 1;
87 }
88
89 switch(vpp) {
90 case 0:
91 break;
92 case 33:
93 case 50:
94 if(vcc == vpp)
95 reg |= BCSR1_PCCVPP1;
96 else
97 return 1;
98 break;
99 case 120:
100 if ((vcc == 33) || (vcc == 50))
101 reg |= BCSR1_PCCVPP0;
102 else
103 return 1;
104 default:
105 return 1;
106 }
107
108 /* first, turn off all power */
109 clrbits32(bcsr_io, 0x00610000);
110
111 /* enable new powersettings */
112 setbits32(bcsr_io, reg);
113
114 iounmap(bcsr_io);
115 return 0;
116}
117#endif
118
54void __init mpc885ads_board_setup(void) 119void __init mpc885ads_board_setup(void)
55{ 120{
56 cpm8xx_t *cp; 121 cpm8xx_t *cp;
@@ -115,6 +180,12 @@ void __init mpc885ads_board_setup(void)
115 immr_unmap(io_port); 180 immr_unmap(io_port);
116 181
117#endif 182#endif
183
184#ifdef CONFIG_PCMCIA_M8XX
185 /*Set up board specific hook-ups*/
186 m8xx_pcmcia_ops.hw_ctrl = pcmcia_hw_setup;
187 m8xx_pcmcia_ops.voltage_set = pcmcia_set_voltage;
188#endif
118} 189}
119 190
120 191
diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig
index 361acfa2894c..33545d352e92 100644
--- a/arch/powerpc/platforms/Kconfig
+++ b/arch/powerpc/platforms/Kconfig
@@ -2,7 +2,7 @@ menu "Platform support"
2 2
3choice 3choice
4 prompt "Machine type" 4 prompt "Machine type"
5 depends on PPC64 || CLASSIC32 5 depends on PPC64 || 6xx
6 default PPC_MULTIPLATFORM 6 default PPC_MULTIPLATFORM
7 7
8config PPC_MULTIPLATFORM 8config PPC_MULTIPLATFORM
@@ -16,15 +16,30 @@ config EMBEDDED6xx
16 bool "Embedded 6xx/7xx/7xxx-based board" 16 bool "Embedded 6xx/7xx/7xxx-based board"
17 depends on PPC32 && (BROKEN||BROKEN_ON_SMP) 17 depends on PPC32 && (BROKEN||BROKEN_ON_SMP)
18 18
19config APUS 19config PPC_82xx
20 bool "Amiga-APUS" 20 bool "Freescale 82xx"
21 depends on PPC32 && BROKEN 21 depends on 6xx
22
23config PPC_83xx
24 bool "Freescale 83xx"
25 depends on 6xx
26 select FSL_SOC
27 select 83xx
28 select WANT_DEVICE_TREE
29
30config PPC_86xx
31 bool "Freescale 86xx"
32 depends on 6xx
33 select FSL_SOC
34 select ALTIVEC
22 help 35 help
23 Select APUS if configuring for a PowerUP Amiga. 36 The Freescale E600 SoCs have 74xx cores.
24 More information is available at:
25 <http://linux-apus.sourceforge.net/>.
26endchoice 37endchoice
27 38
39config CLASSIC32
40 def_bool y
41 depends on 6xx && PPC_MULTIPLATFORM
42
28source "arch/powerpc/platforms/pseries/Kconfig" 43source "arch/powerpc/platforms/pseries/Kconfig"
29source "arch/powerpc/platforms/iseries/Kconfig" 44source "arch/powerpc/platforms/iseries/Kconfig"
30source "arch/powerpc/platforms/chrp/Kconfig" 45source "arch/powerpc/platforms/chrp/Kconfig"
diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype
new file mode 100644
index 000000000000..b8b5fde94668
--- /dev/null
+++ b/arch/powerpc/platforms/Kconfig.cputype
@@ -0,0 +1,221 @@
1config PPC64
2 bool "64-bit kernel"
3 default n
4 help
5 This option selects whether a 32-bit or a 64-bit kernel
6 will be built.
7
8menu "Processor support"
9choice
10 prompt "Processor Type"
11 depends on PPC32
12 default 6xx
13 help
14 There are five families of 32 bit PowerPC chips supported.
15 The most common ones are the desktop and server CPUs (601, 603,
16 604, 740, 750, 74xx) CPUs from Freescale and IBM, with their
17 embedded 52xx/82xx/83xx/86xx counterparts.
18 The other embeeded parts, namely 4xx, 8xx, e200 (55xx) and e500
19 (85xx) each form a family of their own that is not compatible
20 with the others.
21
22 If unsure, select 52xx/6xx/7xx/74xx/82xx/83xx/86xx.
23
24config 6xx
25 bool "52xx/6xx/7xx/74xx/82xx/83xx/86xx"
26 select PPC_FPU
27
28config PPC_85xx
29 bool "Freescale 85xx"
30 select E500
31 select FSL_SOC
32 select 85xx
33 select WANT_DEVICE_TREE
34
35config PPC_8xx
36 bool "Freescale 8xx"
37 select FSL_SOC
38 select 8xx
39
40config 40x
41 bool "AMCC 40x"
42 select PPC_DCR_NATIVE
43
44config 44x
45 bool "AMCC 44x"
46 select PPC_DCR_NATIVE
47 select WANT_DEVICE_TREE
48
49config E200
50 bool "Freescale e200"
51
52endchoice
53
54config POWER4_ONLY
55 bool "Optimize for POWER4"
56 depends on PPC64
57 default n
58 ---help---
59 Cause the compiler to optimize for POWER4/POWER5/PPC970 processors.
60 The resulting binary will not work on POWER3 or RS64 processors
61 when compiled with binutils 2.15 or later.
62
63config POWER3
64 bool
65 depends on PPC64
66 default y if !POWER4_ONLY
67
68config POWER4
69 depends on PPC64
70 def_bool y
71
72config 6xx
73 bool
74
75# this is temp to handle compat with arch=ppc
76config 8xx
77 bool
78
79# this is temp to handle compat with arch=ppc
80config 83xx
81 bool
82
83# this is temp to handle compat with arch=ppc
84config 85xx
85 bool
86
87config E500
88 bool
89
90config PPC_FPU
91 bool
92 default y if PPC64
93
94config 4xx
95 bool
96 depends on 40x || 44x
97 default y
98
99config BOOKE
100 bool
101 depends on E200 || E500 || 44x
102 default y
103
104config FSL_BOOKE
105 bool
106 depends on E200 || E500
107 default y
108
109config PTE_64BIT
110 bool
111 depends on 44x || E500
112 default y if 44x
113 default y if E500 && PHYS_64BIT
114
115config PHYS_64BIT
116 bool 'Large physical address support' if E500
117 depends on 44x || E500
118 select RESOURCES_64BIT
119 default y if 44x
120 ---help---
121 This option enables kernel support for larger than 32-bit physical
122 addresses. This features is not be available on all e500 cores.
123
124 If in doubt, say N here.
125
126config ALTIVEC
127 bool "AltiVec Support"
128 depends on CLASSIC32 || POWER4
129 ---help---
130 This option enables kernel support for the Altivec extensions to the
131 PowerPC processor. The kernel currently supports saving and restoring
132 altivec registers, and turning on the 'altivec enable' bit so user
133 processes can execute altivec instructions.
134
135 This option is only usefully if you have a processor that supports
136 altivec (G4, otherwise known as 74xx series), but does not have
137 any affect on a non-altivec cpu (it does, however add code to the
138 kernel).
139
140 If in doubt, say Y here.
141
142config SPE
143 bool "SPE Support"
144 depends on E200 || E500
145 default y
146 ---help---
147 This option enables kernel support for the Signal Processing
148 Extensions (SPE) to the PowerPC processor. The kernel currently
149 supports saving and restoring SPE registers, and turning on the
150 'spe enable' bit so user processes can execute SPE instructions.
151
152 This option is only useful if you have a processor that supports
153 SPE (e500, otherwise known as 85xx series), but does not have any
154 effect on a non-spe cpu (it does, however add code to the kernel).
155
156 If in doubt, say Y here.
157
158config PPC_STD_MMU
159 bool
160 depends on 6xx || POWER3 || POWER4 || PPC64
161 default y
162
163config PPC_STD_MMU_32
164 def_bool y
165 depends on PPC_STD_MMU && PPC32
166
167config PPC_MM_SLICES
168 bool
169 default y if HUGETLB_PAGE
170 default n
171
172config VIRT_CPU_ACCOUNTING
173 bool "Deterministic task and CPU time accounting"
174 depends on PPC64
175 default y
176 help
177 Select this option to enable more accurate task and CPU time
178 accounting. This is done by reading a CPU counter on each
179 kernel entry and exit and on transitions within the kernel
180 between system, softirq and hardirq state, so there is a
181 small performance impact. This also enables accounting of
182 stolen time on logically-partitioned systems running on
183 IBM POWER5-based machines.
184
185 If in doubt, say Y here.
186
187config SMP
188 depends on PPC_STD_MMU
189 bool "Symmetric multi-processing support"
190 ---help---
191 This enables support for systems with more than one CPU. If you have
192 a system with only one CPU, say N. If you have a system with more
193 than one CPU, say Y. Note that the kernel does not currently
194 support SMP machines with 603/603e/603ev or PPC750 ("G3") processors
195 since they have inadequate hardware support for multiprocessor
196 operation.
197
198 If you say N here, the kernel will run on single and multiprocessor
199 machines, but will use only one CPU of a multiprocessor machine. If
200 you say Y here, the kernel will run on single-processor machines.
201 On a single-processor machine, the kernel will run faster if you say
202 N here.
203
204 If you don't know what to do here, say N.
205
206config NR_CPUS
207 int "Maximum number of CPUs (2-128)"
208 range 2 128
209 depends on SMP
210 default "32" if PPC64
211 default "4"
212
213config NOT_COHERENT_CACHE
214 bool
215 depends on 4xx || 8xx || E200
216 default y
217
218config CONFIG_CHECK_CACHE_COHERENCY
219 bool
220
221endmenu
diff --git a/arch/powerpc/platforms/apus/Kconfig b/arch/powerpc/platforms/apus/Kconfig
deleted file mode 100644
index 6bde3bffed86..000000000000
--- a/arch/powerpc/platforms/apus/Kconfig
+++ /dev/null
@@ -1,130 +0,0 @@
1
2config AMIGA
3 bool
4 depends on APUS
5 default y
6 help
7 This option enables support for the Amiga series of computers.
8
9config ZORRO
10 bool
11 depends on APUS
12 default y
13 help
14 This enables support for the Zorro bus in the Amiga. If you have
15 expansion cards in your Amiga that conform to the Amiga
16 AutoConfig(tm) specification, say Y, otherwise N. Note that even
17 expansion cards that do not fit in the Zorro slots but fit in e.g.
18 the CPU slot may fall in this category, so you have to say Y to let
19 Linux use these.
20
21config ABSTRACT_CONSOLE
22 bool
23 depends on APUS
24 default y
25
26config APUS_FAST_EXCEPT
27 bool
28 depends on APUS
29 default y
30
31config AMIGA_PCMCIA
32 bool "Amiga 1200/600 PCMCIA support"
33 depends on APUS && EXPERIMENTAL
34 help
35 Include support in the kernel for pcmcia on Amiga 1200 and Amiga
36 600. If you intend to use pcmcia cards say Y; otherwise say N.
37
38config AMIGA_BUILTIN_SERIAL
39 tristate "Amiga builtin serial support"
40 depends on APUS
41 help
42 If you want to use your Amiga's built-in serial port in Linux,
43 answer Y.
44
45 To compile this driver as a module, choose M here.
46
47config GVPIOEXT
48 tristate "GVP IO-Extender support"
49 depends on APUS
50 help
51 If you want to use a GVP IO-Extender serial card in Linux, say Y.
52 Otherwise, say N.
53
54config GVPIOEXT_LP
55 tristate "GVP IO-Extender parallel printer support"
56 depends on GVPIOEXT
57 help
58 Say Y to enable driving a printer from the parallel port on your
59 GVP IO-Extender card, N otherwise.
60
61config GVPIOEXT_PLIP
62 tristate "GVP IO-Extender PLIP support"
63 depends on GVPIOEXT
64 help
65 Say Y to enable doing IP over the parallel port on your GVP
66 IO-Extender card, N otherwise.
67
68config MULTIFACE_III_TTY
69 tristate "Multiface Card III serial support"
70 depends on APUS
71 help
72 If you want to use a Multiface III card's serial port in Linux,
73 answer Y.
74
75 To compile this driver as a module, choose M here.
76
77config A2232
78 tristate "Commodore A2232 serial support (EXPERIMENTAL)"
79 depends on EXPERIMENTAL && APUS
80 ---help---
81 This option supports the 2232 7-port serial card shipped with the
82 Amiga 2000 and other Zorro-bus machines, dating from 1989. At
83 a max of 19,200 bps, the ports are served by a 6551 ACIA UART chip
84 each, plus a 8520 CIA, and a master 6502 CPU and buffer as well. The
85 ports were connected with 8 pin DIN connectors on the card bracket,
86 for which 8 pin to DB25 adapters were supplied. The card also had
87 jumpers internally to toggle various pinning configurations.
88
89 This driver can be built as a module; but then "generic_serial"
90 will also be built as a module. This has to be loaded before
91 "ser_a2232". If you want to do this, answer M here.
92
93config WHIPPET_SERIAL
94 tristate "Hisoft Whippet PCMCIA serial support"
95 depends on AMIGA_PCMCIA
96 help
97 HiSoft has a web page at <http://www.hisoft.co.uk/>, but there
98 is no listing for the Whippet in their Amiga section.
99
100config APNE
101 tristate "PCMCIA NE2000 support"
102 depends on AMIGA_PCMCIA
103 help
104 If you have a PCMCIA NE2000 compatible adapter, say Y. Otherwise,
105 say N.
106
107 To compile this driver as a module, choose M here: the
108 module will be called apne.
109
110config SERIAL_CONSOLE
111 bool "Support for serial port console"
112 depends on APUS && (AMIGA_BUILTIN_SERIAL=y || GVPIOEXT=y || MULTIFACE_III_TTY=y)
113
114config HEARTBEAT
115 bool "Use power LED as a heartbeat"
116 depends on APUS
117 help
118 Use the power-on LED on your machine as a load meter. The exact
119 behavior is platform-dependent, but normally the flash frequency is
120 a hyperbolic function of the 5-minute load average.
121
122config PROC_HARDWARE
123 bool "/proc/hardware support"
124 depends on APUS
125
126source "drivers/zorro/Kconfig"
127
128config PCI_PERMEDIA
129 bool "PCI for Permedia2"
130 depends on !4xx && !8xx && APUS
diff --git a/arch/powerpc/platforms/cell/io-workarounds.c b/arch/powerpc/platforms/cell/io-workarounds.c
index 7fb92f23f380..9d7c2ef940a8 100644
--- a/arch/powerpc/platforms/cell/io-workarounds.c
+++ b/arch/powerpc/platforms/cell/io-workarounds.c
@@ -102,7 +102,7 @@ static void spider_io_flush(const volatile void __iomem *addr)
102 vaddr = (unsigned long)PCI_FIX_ADDR(addr); 102 vaddr = (unsigned long)PCI_FIX_ADDR(addr);
103 103
104 /* Check if it's in allowed range for PIO */ 104 /* Check if it's in allowed range for PIO */
105 if (vaddr < PHBS_IO_BASE || vaddr >= IMALLOC_BASE) 105 if (vaddr < PHB_IO_BASE || vaddr > PHB_IO_END)
106 return; 106 return;
107 107
108 /* Try to find a PTE. If not, clear the paddr, we'll do 108 /* Try to find a PTE. If not, clear the paddr, we'll do
diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c
index a7f5a7653c62..e4d0c9f42abd 100644
--- a/arch/powerpc/platforms/cell/spu_base.c
+++ b/arch/powerpc/platforms/cell/spu_base.c
@@ -183,7 +183,7 @@ static int __spu_trap_data_seg(struct spu *spu, unsigned long ea)
183 spu->slb_replace = 0; 183 spu->slb_replace = 0;
184 184
185 spu_restart_dma(spu); 185 spu_restart_dma(spu);
186 186 spu->stats.slb_flt++;
187 return 0; 187 return 0;
188} 188}
189 189
@@ -332,6 +332,7 @@ spu_irq_class_2(int irq, void *data)
332 if (stat & 0x10) /* SPU mailbox threshold */ 332 if (stat & 0x10) /* SPU mailbox threshold */
333 spu->wbox_callback(spu); 333 spu->wbox_callback(spu);
334 334
335 spu->stats.class2_intr++;
335 return stat ? IRQ_HANDLED : IRQ_NONE; 336 return stat ? IRQ_HANDLED : IRQ_NONE;
336} 337}
337 338
@@ -462,8 +463,18 @@ void spu_free(struct spu *spu)
462} 463}
463EXPORT_SYMBOL_GPL(spu_free); 464EXPORT_SYMBOL_GPL(spu_free);
464 465
466static int spu_shutdown(struct sys_device *sysdev)
467{
468 struct spu *spu = container_of(sysdev, struct spu, sysdev);
469
470 spu_free_irqs(spu);
471 spu_destroy_spu(spu);
472 return 0;
473}
474
465struct sysdev_class spu_sysdev_class = { 475struct sysdev_class spu_sysdev_class = {
466 set_kset_name("spu") 476 set_kset_name("spu"),
477 .shutdown = spu_shutdown,
467}; 478};
468 479
469int spu_add_sysdev_attr(struct sysdev_attribute *attr) 480int spu_add_sysdev_attr(struct sysdev_attribute *attr)
@@ -574,6 +585,9 @@ static int __init create_spu(void *data)
574 spin_unlock_irqrestore(&spu_list_lock, flags); 585 spin_unlock_irqrestore(&spu_list_lock, flags);
575 mutex_unlock(&spu_mutex); 586 mutex_unlock(&spu_mutex);
576 587
588 spu->stats.utilization_state = SPU_UTIL_IDLE;
589 spu->stats.tstamp = jiffies;
590
577 goto out; 591 goto out;
578 592
579out_free_irqs: 593out_free_irqs:
@@ -586,6 +600,45 @@ out:
586 return ret; 600 return ret;
587} 601}
588 602
603static const char *spu_state_names[] = {
604 "user", "system", "iowait", "idle"
605};
606
607static unsigned long long spu_acct_time(struct spu *spu,
608 enum spu_utilization_state state)
609{
610 unsigned long long time = spu->stats.times[state];
611
612 if (spu->stats.utilization_state == state)
613 time += jiffies - spu->stats.tstamp;
614
615 return jiffies_to_msecs(time);
616}
617
618
619static ssize_t spu_stat_show(struct sys_device *sysdev, char *buf)
620{
621 struct spu *spu = container_of(sysdev, struct spu, sysdev);
622
623 return sprintf(buf, "%s %llu %llu %llu %llu "
624 "%llu %llu %llu %llu %llu %llu %llu %llu\n",
625 spu_state_names[spu->stats.utilization_state],
626 spu_acct_time(spu, SPU_UTIL_USER),
627 spu_acct_time(spu, SPU_UTIL_SYSTEM),
628 spu_acct_time(spu, SPU_UTIL_IOWAIT),
629 spu_acct_time(spu, SPU_UTIL_IDLE),
630 spu->stats.vol_ctx_switch,
631 spu->stats.invol_ctx_switch,
632 spu->stats.slb_flt,
633 spu->stats.hash_flt,
634 spu->stats.min_flt,
635 spu->stats.maj_flt,
636 spu->stats.class2_intr,
637 spu->stats.libassist);
638}
639
640static SYSDEV_ATTR(stat, 0644, spu_stat_show, NULL);
641
589static int __init init_spu_base(void) 642static int __init init_spu_base(void)
590{ 643{
591 int i, ret = 0; 644 int i, ret = 0;
@@ -611,6 +664,8 @@ static int __init init_spu_base(void)
611 664
612 xmon_register_spus(&spu_full_list); 665 xmon_register_spus(&spu_full_list);
613 666
667 spu_add_sysdev_attr(&attr_stat);
668
614 return 0; 669 return 0;
615 670
616 out_unregister_sysdev_class: 671 out_unregister_sysdev_class:
diff --git a/arch/powerpc/platforms/cell/spufs/backing_ops.c b/arch/powerpc/platforms/cell/spufs/backing_ops.c
index d32db9ffc6eb..07a0e815abf5 100644
--- a/arch/powerpc/platforms/cell/spufs/backing_ops.c
+++ b/arch/powerpc/platforms/cell/spufs/backing_ops.c
@@ -320,6 +320,12 @@ static int spu_backing_set_mfc_query(struct spu_context * ctx, u32 mask,
320 /* FIXME: what are the side-effects of this? */ 320 /* FIXME: what are the side-effects of this? */
321 prob->dma_querymask_RW = mask; 321 prob->dma_querymask_RW = mask;
322 prob->dma_querytype_RW = mode; 322 prob->dma_querytype_RW = mode;
323 /* In the current implementation, the SPU context is always
324 * acquired in runnable state when new bits are added to the
325 * mask (tagwait), so it's sufficient just to mask
326 * dma_tagstatus_R with the 'mask' parameter here.
327 */
328 ctx->csa.prob.dma_tagstatus_R &= mask;
323out: 329out:
324 spin_unlock(&ctx->csa.register_lock); 330 spin_unlock(&ctx->csa.register_lock);
325 331
diff --git a/arch/powerpc/platforms/cell/spufs/context.c b/arch/powerpc/platforms/cell/spufs/context.c
index 7c51cb54bca1..6d7bd60f5380 100644
--- a/arch/powerpc/platforms/cell/spufs/context.c
+++ b/arch/powerpc/platforms/cell/spufs/context.c
@@ -23,10 +23,14 @@
23#include <linux/fs.h> 23#include <linux/fs.h>
24#include <linux/mm.h> 24#include <linux/mm.h>
25#include <linux/slab.h> 25#include <linux/slab.h>
26#include <asm/atomic.h>
26#include <asm/spu.h> 27#include <asm/spu.h>
27#include <asm/spu_csa.h> 28#include <asm/spu_csa.h>
28#include "spufs.h" 29#include "spufs.h"
29 30
31
32atomic_t nr_spu_contexts = ATOMIC_INIT(0);
33
30struct spu_context *alloc_spu_context(struct spu_gang *gang) 34struct spu_context *alloc_spu_context(struct spu_gang *gang)
31{ 35{
32 struct spu_context *ctx; 36 struct spu_context *ctx;
@@ -53,10 +57,12 @@ struct spu_context *alloc_spu_context(struct spu_gang *gang)
53 INIT_LIST_HEAD(&ctx->rq); 57 INIT_LIST_HEAD(&ctx->rq);
54 if (gang) 58 if (gang)
55 spu_gang_add_ctx(gang, ctx); 59 spu_gang_add_ctx(gang, ctx);
56 ctx->rt_priority = current->rt_priority; 60 ctx->cpus_allowed = current->cpus_allowed;
57 ctx->policy = current->policy; 61 spu_set_timeslice(ctx);
58 ctx->prio = current->prio; 62 ctx->stats.execution_state = SPUCTX_UTIL_USER;
59 INIT_DELAYED_WORK(&ctx->sched_work, spu_sched_tick); 63 ctx->stats.tstamp = jiffies;
64
65 atomic_inc(&nr_spu_contexts);
60 goto out; 66 goto out;
61out_free: 67out_free:
62 kfree(ctx); 68 kfree(ctx);
@@ -76,6 +82,7 @@ void destroy_spu_context(struct kref *kref)
76 if (ctx->gang) 82 if (ctx->gang)
77 spu_gang_remove_ctx(ctx->gang, ctx); 83 spu_gang_remove_ctx(ctx->gang, ctx);
78 BUG_ON(!list_empty(&ctx->rq)); 84 BUG_ON(!list_empty(&ctx->rq));
85 atomic_dec(&nr_spu_contexts);
79 kfree(ctx); 86 kfree(ctx);
80} 87}
81 88
diff --git a/arch/powerpc/platforms/cell/spufs/fault.c b/arch/powerpc/platforms/cell/spufs/fault.c
index 0f75c07e29d8..e064d0c0d80e 100644
--- a/arch/powerpc/platforms/cell/spufs/fault.c
+++ b/arch/powerpc/platforms/cell/spufs/fault.c
@@ -33,7 +33,8 @@
33 * function. Currently, there are a few corner cases that we haven't had 33 * function. Currently, there are a few corner cases that we haven't had
34 * to handle fortunately. 34 * to handle fortunately.
35 */ 35 */
36static int spu_handle_mm_fault(struct mm_struct *mm, unsigned long ea, unsigned long dsisr) 36static int spu_handle_mm_fault(struct mm_struct *mm, unsigned long ea,
37 unsigned long dsisr, unsigned *flt)
37{ 38{
38 struct vm_area_struct *vma; 39 struct vm_area_struct *vma;
39 unsigned long is_write; 40 unsigned long is_write;
@@ -73,7 +74,8 @@ good_area:
73 goto bad_area; 74 goto bad_area;
74 } 75 }
75 ret = 0; 76 ret = 0;
76 switch (handle_mm_fault(mm, vma, ea, is_write)) { 77 *flt = handle_mm_fault(mm, vma, ea, is_write);
78 switch (*flt) {
77 case VM_FAULT_MINOR: 79 case VM_FAULT_MINOR:
78 current->min_flt++; 80 current->min_flt++;
79 break; 81 break;
@@ -153,6 +155,7 @@ int spufs_handle_class1(struct spu_context *ctx)
153{ 155{
154 u64 ea, dsisr, access; 156 u64 ea, dsisr, access;
155 unsigned long flags; 157 unsigned long flags;
158 unsigned flt = 0;
156 int ret; 159 int ret;
157 160
158 /* 161 /*
@@ -178,9 +181,17 @@ int spufs_handle_class1(struct spu_context *ctx)
178 if (!(dsisr & (MFC_DSISR_PTE_NOT_FOUND | MFC_DSISR_ACCESS_DENIED))) 181 if (!(dsisr & (MFC_DSISR_PTE_NOT_FOUND | MFC_DSISR_ACCESS_DENIED)))
179 return 0; 182 return 0;
180 183
184 spuctx_switch_state(ctx, SPUCTX_UTIL_IOWAIT);
185
181 pr_debug("ctx %p: ea %016lx, dsisr %016lx state %d\n", ctx, ea, 186 pr_debug("ctx %p: ea %016lx, dsisr %016lx state %d\n", ctx, ea,
182 dsisr, ctx->state); 187 dsisr, ctx->state);
183 188
189 ctx->stats.hash_flt++;
190 if (ctx->state == SPU_STATE_RUNNABLE) {
191 ctx->spu->stats.hash_flt++;
192 spu_switch_state(ctx->spu, SPU_UTIL_IOWAIT);
193 }
194
184 /* we must not hold the lock when entering spu_handle_mm_fault */ 195 /* we must not hold the lock when entering spu_handle_mm_fault */
185 spu_release(ctx); 196 spu_release(ctx);
186 197
@@ -192,7 +203,7 @@ int spufs_handle_class1(struct spu_context *ctx)
192 203
193 /* hashing failed, so try the actual fault handler */ 204 /* hashing failed, so try the actual fault handler */
194 if (ret) 205 if (ret)
195 ret = spu_handle_mm_fault(current->mm, ea, dsisr); 206 ret = spu_handle_mm_fault(current->mm, ea, dsisr, &flt);
196 207
197 spu_acquire(ctx); 208 spu_acquire(ctx);
198 /* 209 /*
@@ -201,11 +212,23 @@ int spufs_handle_class1(struct spu_context *ctx)
201 * In case of unhandled error report the problem to user space. 212 * In case of unhandled error report the problem to user space.
202 */ 213 */
203 if (!ret) { 214 if (!ret) {
215 if (flt == VM_FAULT_MINOR)
216 ctx->stats.min_flt++;
217 else
218 ctx->stats.maj_flt++;
219 if (ctx->state == SPU_STATE_RUNNABLE) {
220 if (flt == VM_FAULT_MINOR)
221 ctx->spu->stats.min_flt++;
222 else
223 ctx->spu->stats.maj_flt++;
224 }
225
204 if (ctx->spu) 226 if (ctx->spu)
205 ctx->ops->restart_dma(ctx); 227 ctx->ops->restart_dma(ctx);
206 } else 228 } else
207 spufs_handle_dma_error(ctx, ea, SPE_EVENT_SPE_DATA_STORAGE); 229 spufs_handle_dma_error(ctx, ea, SPE_EVENT_SPE_DATA_STORAGE);
208 230
231 spuctx_switch_state(ctx, SPUCTX_UTIL_SYSTEM);
209 return ret; 232 return ret;
210} 233}
211EXPORT_SYMBOL_GPL(spufs_handle_class1); 234EXPORT_SYMBOL_GPL(spufs_handle_class1);
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c
index b1e7e2f8a2e9..c2814ea96af2 100644
--- a/arch/powerpc/platforms/cell/spufs/file.c
+++ b/arch/powerpc/platforms/cell/spufs/file.c
@@ -28,6 +28,7 @@
28#include <linux/pagemap.h> 28#include <linux/pagemap.h>
29#include <linux/poll.h> 29#include <linux/poll.h>
30#include <linux/ptrace.h> 30#include <linux/ptrace.h>
31#include <linux/seq_file.h>
31 32
32#include <asm/io.h> 33#include <asm/io.h>
33#include <asm/semaphore.h> 34#include <asm/semaphore.h>
@@ -39,6 +40,7 @@
39 40
40#define SPUFS_MMAP_4K (PAGE_SIZE == 0x1000) 41#define SPUFS_MMAP_4K (PAGE_SIZE == 0x1000)
41 42
43
42static int 44static int
43spufs_mem_open(struct inode *inode, struct file *file) 45spufs_mem_open(struct inode *inode, struct file *file)
44{ 46{
@@ -216,12 +218,12 @@ unsigned long spufs_get_unmapped_area(struct file *file, unsigned long addr,
216#endif /* CONFIG_SPU_FS_64K_LS */ 218#endif /* CONFIG_SPU_FS_64K_LS */
217 219
218static const struct file_operations spufs_mem_fops = { 220static const struct file_operations spufs_mem_fops = {
219 .open = spufs_mem_open, 221 .open = spufs_mem_open,
220 .release = spufs_mem_release, 222 .release = spufs_mem_release,
221 .read = spufs_mem_read, 223 .read = spufs_mem_read,
222 .write = spufs_mem_write, 224 .write = spufs_mem_write,
223 .llseek = generic_file_llseek, 225 .llseek = generic_file_llseek,
224 .mmap = spufs_mem_mmap, 226 .mmap = spufs_mem_mmap,
225#ifdef CONFIG_SPU_FS_64K_LS 227#ifdef CONFIG_SPU_FS_64K_LS
226 .get_unmapped_area = spufs_get_unmapped_area, 228 .get_unmapped_area = spufs_get_unmapped_area,
227#endif 229#endif
@@ -1497,14 +1499,15 @@ static ssize_t spufs_mfc_write(struct file *file, const char __user *buffer,
1497 if (status) 1499 if (status)
1498 ret = status; 1500 ret = status;
1499 } 1501 }
1500 spu_release(ctx);
1501 1502
1502 if (ret) 1503 if (ret)
1503 goto out; 1504 goto out_unlock;
1504 1505
1505 ctx->tagwait |= 1 << cmd.tag; 1506 ctx->tagwait |= 1 << cmd.tag;
1506 ret = size; 1507 ret = size;
1507 1508
1509out_unlock:
1510 spu_release(ctx);
1508out: 1511out:
1509 return ret; 1512 return ret;
1510} 1513}
@@ -1515,14 +1518,14 @@ static unsigned int spufs_mfc_poll(struct file *file,poll_table *wait)
1515 u32 free_elements, tagstatus; 1518 u32 free_elements, tagstatus;
1516 unsigned int mask; 1519 unsigned int mask;
1517 1520
1521 poll_wait(file, &ctx->mfc_wq, wait);
1522
1518 spu_acquire(ctx); 1523 spu_acquire(ctx);
1519 ctx->ops->set_mfc_query(ctx, ctx->tagwait, 2); 1524 ctx->ops->set_mfc_query(ctx, ctx->tagwait, 2);
1520 free_elements = ctx->ops->get_mfc_free_elements(ctx); 1525 free_elements = ctx->ops->get_mfc_free_elements(ctx);
1521 tagstatus = ctx->ops->read_mfc_tagstatus(ctx); 1526 tagstatus = ctx->ops->read_mfc_tagstatus(ctx);
1522 spu_release(ctx); 1527 spu_release(ctx);
1523 1528
1524 poll_wait(file, &ctx->mfc_wq, wait);
1525
1526 mask = 0; 1529 mask = 0;
1527 if (free_elements & 0xffff) 1530 if (free_elements & 0xffff)
1528 mask |= POLLOUT | POLLWRNORM; 1531 mask |= POLLOUT | POLLWRNORM;
@@ -1797,6 +1800,29 @@ static int spufs_info_open(struct inode *inode, struct file *file)
1797 return 0; 1800 return 0;
1798} 1801}
1799 1802
1803static int spufs_caps_show(struct seq_file *s, void *private)
1804{
1805 struct spu_context *ctx = s->private;
1806
1807 if (!(ctx->flags & SPU_CREATE_NOSCHED))
1808 seq_puts(s, "sched\n");
1809 if (!(ctx->flags & SPU_CREATE_ISOLATE))
1810 seq_puts(s, "step\n");
1811 return 0;
1812}
1813
1814static int spufs_caps_open(struct inode *inode, struct file *file)
1815{
1816 return single_open(file, spufs_caps_show, SPUFS_I(inode)->i_ctx);
1817}
1818
1819static const struct file_operations spufs_caps_fops = {
1820 .open = spufs_caps_open,
1821 .read = seq_read,
1822 .llseek = seq_lseek,
1823 .release = single_release,
1824};
1825
1800static ssize_t __spufs_mbox_info_read(struct spu_context *ctx, 1826static ssize_t __spufs_mbox_info_read(struct spu_context *ctx,
1801 char __user *buf, size_t len, loff_t *pos) 1827 char __user *buf, size_t len, loff_t *pos)
1802{ 1828{
@@ -2014,7 +2040,105 @@ static const struct file_operations spufs_proxydma_info_fops = {
2014 .read = spufs_proxydma_info_read, 2040 .read = spufs_proxydma_info_read,
2015}; 2041};
2016 2042
2043static int spufs_show_tid(struct seq_file *s, void *private)
2044{
2045 struct spu_context *ctx = s->private;
2046
2047 seq_printf(s, "%d\n", ctx->tid);
2048 return 0;
2049}
2050
2051static int spufs_tid_open(struct inode *inode, struct file *file)
2052{
2053 return single_open(file, spufs_show_tid, SPUFS_I(inode)->i_ctx);
2054}
2055
2056static const struct file_operations spufs_tid_fops = {
2057 .open = spufs_tid_open,
2058 .read = seq_read,
2059 .llseek = seq_lseek,
2060 .release = single_release,
2061};
2062
2063static const char *ctx_state_names[] = {
2064 "user", "system", "iowait", "loaded"
2065};
2066
2067static unsigned long long spufs_acct_time(struct spu_context *ctx,
2068 enum spuctx_execution_state state)
2069{
2070 unsigned long time = ctx->stats.times[state];
2071
2072 if (ctx->stats.execution_state == state)
2073 time += jiffies - ctx->stats.tstamp;
2074
2075 return jiffies_to_msecs(time);
2076}
2077
2078static unsigned long long spufs_slb_flts(struct spu_context *ctx)
2079{
2080 unsigned long long slb_flts = ctx->stats.slb_flt;
2081
2082 if (ctx->state == SPU_STATE_RUNNABLE) {
2083 slb_flts += (ctx->spu->stats.slb_flt -
2084 ctx->stats.slb_flt_base);
2085 }
2086
2087 return slb_flts;
2088}
2089
2090static unsigned long long spufs_class2_intrs(struct spu_context *ctx)
2091{
2092 unsigned long long class2_intrs = ctx->stats.class2_intr;
2093
2094 if (ctx->state == SPU_STATE_RUNNABLE) {
2095 class2_intrs += (ctx->spu->stats.class2_intr -
2096 ctx->stats.class2_intr_base);
2097 }
2098
2099 return class2_intrs;
2100}
2101
2102
2103static int spufs_show_stat(struct seq_file *s, void *private)
2104{
2105 struct spu_context *ctx = s->private;
2106
2107 spu_acquire(ctx);
2108 seq_printf(s, "%s %llu %llu %llu %llu "
2109 "%llu %llu %llu %llu %llu %llu %llu %llu\n",
2110 ctx_state_names[ctx->stats.execution_state],
2111 spufs_acct_time(ctx, SPUCTX_UTIL_USER),
2112 spufs_acct_time(ctx, SPUCTX_UTIL_SYSTEM),
2113 spufs_acct_time(ctx, SPUCTX_UTIL_IOWAIT),
2114 spufs_acct_time(ctx, SPUCTX_UTIL_LOADED),
2115 ctx->stats.vol_ctx_switch,
2116 ctx->stats.invol_ctx_switch,
2117 spufs_slb_flts(ctx),
2118 ctx->stats.hash_flt,
2119 ctx->stats.min_flt,
2120 ctx->stats.maj_flt,
2121 spufs_class2_intrs(ctx),
2122 ctx->stats.libassist);
2123 spu_release(ctx);
2124 return 0;
2125}
2126
2127static int spufs_stat_open(struct inode *inode, struct file *file)
2128{
2129 return single_open(file, spufs_show_stat, SPUFS_I(inode)->i_ctx);
2130}
2131
2132static const struct file_operations spufs_stat_fops = {
2133 .open = spufs_stat_open,
2134 .read = seq_read,
2135 .llseek = seq_lseek,
2136 .release = single_release,
2137};
2138
2139
2017struct tree_descr spufs_dir_contents[] = { 2140struct tree_descr spufs_dir_contents[] = {
2141 { "capabilities", &spufs_caps_fops, 0444, },
2018 { "mem", &spufs_mem_fops, 0666, }, 2142 { "mem", &spufs_mem_fops, 0666, },
2019 { "regs", &spufs_regs_fops, 0666, }, 2143 { "regs", &spufs_regs_fops, 0666, },
2020 { "mbox", &spufs_mbox_fops, 0444, }, 2144 { "mbox", &spufs_mbox_fops, 0444, },
@@ -2046,10 +2170,13 @@ struct tree_descr spufs_dir_contents[] = {
2046 { "wbox_info", &spufs_wbox_info_fops, 0444, }, 2170 { "wbox_info", &spufs_wbox_info_fops, 0444, },
2047 { "dma_info", &spufs_dma_info_fops, 0444, }, 2171 { "dma_info", &spufs_dma_info_fops, 0444, },
2048 { "proxydma_info", &spufs_proxydma_info_fops, 0444, }, 2172 { "proxydma_info", &spufs_proxydma_info_fops, 0444, },
2173 { "tid", &spufs_tid_fops, 0444, },
2174 { "stat", &spufs_stat_fops, 0444, },
2049 {}, 2175 {},
2050}; 2176};
2051 2177
2052struct tree_descr spufs_dir_nosched_contents[] = { 2178struct tree_descr spufs_dir_nosched_contents[] = {
2179 { "capabilities", &spufs_caps_fops, 0444, },
2053 { "mem", &spufs_mem_fops, 0666, }, 2180 { "mem", &spufs_mem_fops, 0666, },
2054 { "mbox", &spufs_mbox_fops, 0444, }, 2181 { "mbox", &spufs_mbox_fops, 0444, },
2055 { "ibox", &spufs_ibox_fops, 0444, }, 2182 { "ibox", &spufs_ibox_fops, 0444, },
@@ -2068,6 +2195,8 @@ struct tree_descr spufs_dir_nosched_contents[] = {
2068 { "psmap", &spufs_psmap_fops, 0666, }, 2195 { "psmap", &spufs_psmap_fops, 0666, },
2069 { "phys-id", &spufs_id_ops, 0666, }, 2196 { "phys-id", &spufs_id_ops, 0666, },
2070 { "object-id", &spufs_object_id_ops, 0666, }, 2197 { "object-id", &spufs_object_id_ops, 0666, },
2198 { "tid", &spufs_tid_fops, 0444, },
2199 { "stat", &spufs_stat_fops, 0444, },
2071 {}, 2200 {},
2072}; 2201};
2073 2202
diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c
index 9807206e0219..f37460e5bfd2 100644
--- a/arch/powerpc/platforms/cell/spufs/inode.c
+++ b/arch/powerpc/platforms/cell/spufs/inode.c
@@ -232,10 +232,6 @@ static int spufs_dir_close(struct inode *inode, struct file *file)
232 return dcache_dir_close(inode, file); 232 return dcache_dir_close(inode, file);
233} 233}
234 234
235const struct inode_operations spufs_dir_inode_operations = {
236 .lookup = simple_lookup,
237};
238
239const struct file_operations spufs_context_fops = { 235const struct file_operations spufs_context_fops = {
240 .open = dcache_dir_open, 236 .open = dcache_dir_open,
241 .release = spufs_dir_close, 237 .release = spufs_dir_close,
@@ -269,7 +265,7 @@ spufs_mkdir(struct inode *dir, struct dentry *dentry, unsigned int flags,
269 goto out_iput; 265 goto out_iput;
270 266
271 ctx->flags = flags; 267 ctx->flags = flags;
272 inode->i_op = &spufs_dir_inode_operations; 268 inode->i_op = &simple_dir_inode_operations;
273 inode->i_fop = &simple_dir_operations; 269 inode->i_fop = &simple_dir_operations;
274 if (flags & SPU_CREATE_NOSCHED) 270 if (flags & SPU_CREATE_NOSCHED)
275 ret = spufs_fill_dir(dentry, spufs_dir_nosched_contents, 271 ret = spufs_fill_dir(dentry, spufs_dir_nosched_contents,
@@ -386,7 +382,7 @@ spufs_mkgang(struct inode *dir, struct dentry *dentry, int mode)
386 if (!gang) 382 if (!gang)
387 goto out_iput; 383 goto out_iput;
388 384
389 inode->i_op = &spufs_dir_inode_operations; 385 inode->i_op = &simple_dir_inode_operations;
390 inode->i_fop = &simple_dir_operations; 386 inode->i_fop = &simple_dir_operations;
391 387
392 d_instantiate(dentry, inode); 388 d_instantiate(dentry, inode);
@@ -593,7 +589,7 @@ spufs_create_root(struct super_block *sb, void *data)
593 if (!inode) 589 if (!inode)
594 goto out; 590 goto out;
595 591
596 inode->i_op = &spufs_dir_inode_operations; 592 inode->i_op = &simple_dir_inode_operations;
597 inode->i_fop = &simple_dir_operations; 593 inode->i_fop = &simple_dir_operations;
598 SPUFS_I(inode)->i_ctx = NULL; 594 SPUFS_I(inode)->i_ctx = NULL;
599 595
diff --git a/arch/powerpc/platforms/cell/spufs/run.c b/arch/powerpc/platforms/cell/spufs/run.c
index 57626600b1a4..58ae13b7de84 100644
--- a/arch/powerpc/platforms/cell/spufs/run.c
+++ b/arch/powerpc/platforms/cell/spufs/run.c
@@ -29,7 +29,8 @@ static inline int spu_stopped(struct spu_context *ctx, u32 * stat)
29 spu = ctx->spu; 29 spu = ctx->spu;
30 pte_fault = spu->dsisr & 30 pte_fault = spu->dsisr &
31 (MFC_DSISR_PTE_NOT_FOUND | MFC_DSISR_ACCESS_DENIED); 31 (MFC_DSISR_PTE_NOT_FOUND | MFC_DSISR_ACCESS_DENIED);
32 return (!(*stat & 0x1) || pte_fault || spu->class_0_pending) ? 1 : 0; 32 return (!(*stat & SPU_STATUS_RUNNING) || pte_fault || spu->class_0_pending) ?
33 1 : 0;
33} 34}
34 35
35static int spu_setup_isolated(struct spu_context *ctx) 36static int spu_setup_isolated(struct spu_context *ctx)
@@ -142,8 +143,11 @@ static int spu_run_init(struct spu_context *ctx, u32 * npc)
142 runcntl = SPU_RUNCNTL_RUNNABLE; 143 runcntl = SPU_RUNCNTL_RUNNABLE;
143 ctx->ops->runcntl_write(ctx, runcntl); 144 ctx->ops->runcntl_write(ctx, runcntl);
144 } else { 145 } else {
145 spu_start_tick(ctx); 146 unsigned long mode = SPU_PRIVCNTL_MODE_NORMAL;
146 ctx->ops->npc_write(ctx, *npc); 147 ctx->ops->npc_write(ctx, *npc);
148 if (test_thread_flag(TIF_SINGLESTEP))
149 mode = SPU_PRIVCNTL_MODE_SINGLE_STEP;
150 out_be64(&ctx->spu->priv2->spu_privcntl_RW, mode);
147 ctx->ops->runcntl_write(ctx, SPU_RUNCNTL_RUNNABLE); 151 ctx->ops->runcntl_write(ctx, SPU_RUNCNTL_RUNNABLE);
148 } 152 }
149 153
@@ -155,7 +159,6 @@ static int spu_run_fini(struct spu_context *ctx, u32 * npc,
155{ 159{
156 int ret = 0; 160 int ret = 0;
157 161
158 spu_stop_tick(ctx);
159 *status = ctx->ops->status_read(ctx); 162 *status = ctx->ops->status_read(ctx);
160 *npc = ctx->ops->npc_read(ctx); 163 *npc = ctx->ops->npc_read(ctx);
161 spu_release(ctx); 164 spu_release(ctx);
@@ -298,9 +301,22 @@ long spufs_run_spu(struct file *file, struct spu_context *ctx,
298 ctx->ops->master_start(ctx); 301 ctx->ops->master_start(ctx);
299 ctx->event_return = 0; 302 ctx->event_return = 0;
300 303
301 ret = spu_acquire_runnable(ctx, 0); 304 spu_acquire(ctx);
302 if (ret) 305 if (ctx->state == SPU_STATE_SAVED) {
303 return ret; 306 __spu_update_sched_info(ctx);
307
308 ret = spu_activate(ctx, 0);
309 if (ret) {
310 spu_release(ctx);
311 goto out;
312 }
313 } else {
314 /*
315 * We have to update the scheduling priority under active_mutex
316 * to protect against find_victim().
317 */
318 spu_update_sched_info(ctx);
319 }
304 320
305 ret = spu_run_init(ctx, npc); 321 ret = spu_run_init(ctx, npc);
306 if (ret) { 322 if (ret) {
@@ -325,16 +341,20 @@ long spufs_run_spu(struct file *file, struct spu_context *ctx,
325 341
326 if (unlikely(ctx->state != SPU_STATE_RUNNABLE)) { 342 if (unlikely(ctx->state != SPU_STATE_RUNNABLE)) {
327 ret = spu_reacquire_runnable(ctx, npc, &status); 343 ret = spu_reacquire_runnable(ctx, npc, &status);
328 if (ret) { 344 if (ret)
329 spu_stop_tick(ctx);
330 goto out2; 345 goto out2;
331 }
332 continue; 346 continue;
333 } 347 }
334 ret = spu_process_events(ctx); 348 ret = spu_process_events(ctx);
335 349
336 } while (!ret && !(status & (SPU_STATUS_STOPPED_BY_STOP | 350 } while (!ret && !(status & (SPU_STATUS_STOPPED_BY_STOP |
337 SPU_STATUS_STOPPED_BY_HALT))); 351 SPU_STATUS_STOPPED_BY_HALT |
352 SPU_STATUS_SINGLE_STEP)));
353
354 if ((status & SPU_STATUS_STOPPED_BY_STOP) &&
355 (((status >> SPU_STOP_STATUS_SHIFT) & 0x3f00) == 0x2100) &&
356 (ctx->state == SPU_STATE_RUNNABLE))
357 ctx->stats.libassist++;
338 358
339 ctx->ops->master_stop(ctx); 359 ctx->ops->master_stop(ctx);
340 ret = spu_run_fini(ctx, npc, &status); 360 ret = spu_run_fini(ctx, npc, &status);
@@ -344,10 +364,15 @@ out2:
344 if ((ret == 0) || 364 if ((ret == 0) ||
345 ((ret == -ERESTARTSYS) && 365 ((ret == -ERESTARTSYS) &&
346 ((status & SPU_STATUS_STOPPED_BY_HALT) || 366 ((status & SPU_STATUS_STOPPED_BY_HALT) ||
367 (status & SPU_STATUS_SINGLE_STEP) ||
347 ((status & SPU_STATUS_STOPPED_BY_STOP) && 368 ((status & SPU_STATUS_STOPPED_BY_STOP) &&
348 (status >> SPU_STOP_STATUS_SHIFT != 0x2104))))) 369 (status >> SPU_STOP_STATUS_SHIFT != 0x2104)))))
349 ret = status; 370 ret = status;
350 371
372 /* Note: we don't need to force_sig SIGTRAP on single-step
373 * since we have TIF_SINGLESTEP set, thus the kernel will do
374 * it upon return from the syscall anyawy
375 */
351 if ((status & SPU_STATUS_STOPPED_BY_STOP) 376 if ((status & SPU_STATUS_STOPPED_BY_STOP)
352 && (status >> SPU_STOP_STATUS_SHIFT) == 0x3fff) { 377 && (status >> SPU_STOP_STATUS_SHIFT) == 0x3fff) {
353 force_sig(SIGTRAP, current); 378 force_sig(SIGTRAP, current);
diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c
index 3b831e07f1ed..e5b4dd1db286 100644
--- a/arch/powerpc/platforms/cell/spufs/sched.c
+++ b/arch/powerpc/platforms/cell/spufs/sched.c
@@ -35,6 +35,10 @@
35#include <linux/numa.h> 35#include <linux/numa.h>
36#include <linux/mutex.h> 36#include <linux/mutex.h>
37#include <linux/notifier.h> 37#include <linux/notifier.h>
38#include <linux/kthread.h>
39#include <linux/pid_namespace.h>
40#include <linux/proc_fs.h>
41#include <linux/seq_file.h>
38 42
39#include <asm/io.h> 43#include <asm/io.h>
40#include <asm/mmu_context.h> 44#include <asm/mmu_context.h>
@@ -43,54 +47,126 @@
43#include <asm/spu_priv1.h> 47#include <asm/spu_priv1.h>
44#include "spufs.h" 48#include "spufs.h"
45 49
46#define SPU_TIMESLICE (HZ)
47
48struct spu_prio_array { 50struct spu_prio_array {
49 DECLARE_BITMAP(bitmap, MAX_PRIO); 51 DECLARE_BITMAP(bitmap, MAX_PRIO);
50 struct list_head runq[MAX_PRIO]; 52 struct list_head runq[MAX_PRIO];
51 spinlock_t runq_lock; 53 spinlock_t runq_lock;
52 struct list_head active_list[MAX_NUMNODES]; 54 struct list_head active_list[MAX_NUMNODES];
53 struct mutex active_mutex[MAX_NUMNODES]; 55 struct mutex active_mutex[MAX_NUMNODES];
56 int nr_active[MAX_NUMNODES];
57 int nr_waiting;
54}; 58};
55 59
60static unsigned long spu_avenrun[3];
56static struct spu_prio_array *spu_prio; 61static struct spu_prio_array *spu_prio;
57static struct workqueue_struct *spu_sched_wq; 62static struct task_struct *spusched_task;
63static struct timer_list spusched_timer;
64
65/*
66 * Priority of a normal, non-rt, non-niced'd process (aka nice level 0).
67 */
68#define NORMAL_PRIO 120
69
70/*
71 * Frequency of the spu scheduler tick. By default we do one SPU scheduler
72 * tick for every 10 CPU scheduler ticks.
73 */
74#define SPUSCHED_TICK (10)
58 75
59static inline int node_allowed(int node) 76/*
77 * These are the 'tuning knobs' of the scheduler:
78 *
79 * Minimum timeslice is 5 msecs (or 1 spu scheduler tick, whichever is
80 * larger), default timeslice is 100 msecs, maximum timeslice is 800 msecs.
81 */
82#define MIN_SPU_TIMESLICE max(5 * HZ / (1000 * SPUSCHED_TICK), 1)
83#define DEF_SPU_TIMESLICE (100 * HZ / (1000 * SPUSCHED_TICK))
84
85#define MAX_USER_PRIO (MAX_PRIO - MAX_RT_PRIO)
86#define SCALE_PRIO(x, prio) \
87 max(x * (MAX_PRIO - prio) / (MAX_USER_PRIO / 2), MIN_SPU_TIMESLICE)
88
89/*
90 * scale user-nice values [ -20 ... 0 ... 19 ] to time slice values:
91 * [800ms ... 100ms ... 5ms]
92 *
93 * The higher a thread's priority, the bigger timeslices
94 * it gets during one round of execution. But even the lowest
95 * priority thread gets MIN_TIMESLICE worth of execution time.
96 */
97void spu_set_timeslice(struct spu_context *ctx)
60{ 98{
61 cpumask_t mask; 99 if (ctx->prio < NORMAL_PRIO)
100 ctx->time_slice = SCALE_PRIO(DEF_SPU_TIMESLICE * 4, ctx->prio);
101 else
102 ctx->time_slice = SCALE_PRIO(DEF_SPU_TIMESLICE, ctx->prio);
103}
62 104
63 if (!nr_cpus_node(node)) 105/*
64 return 0; 106 * Update scheduling information from the owning thread.
65 mask = node_to_cpumask(node); 107 */
66 if (!cpus_intersects(mask, current->cpus_allowed)) 108void __spu_update_sched_info(struct spu_context *ctx)
67 return 0; 109{
68 return 1; 110 /*
111 * 32-Bit assignment are atomic on powerpc, and we don't care about
112 * memory ordering here because retriving the controlling thread is
113 * per defintion racy.
114 */
115 ctx->tid = current->pid;
116
117 /*
118 * We do our own priority calculations, so we normally want
119 * ->static_prio to start with. Unfortunately thies field
120 * contains junk for threads with a realtime scheduling
121 * policy so we have to look at ->prio in this case.
122 */
123 if (rt_prio(current->prio))
124 ctx->prio = current->prio;
125 else
126 ctx->prio = current->static_prio;
127 ctx->policy = current->policy;
128
129 /*
130 * A lot of places that don't hold active_mutex poke into
131 * cpus_allowed, including grab_runnable_context which
132 * already holds the runq_lock. So abuse runq_lock
133 * to protect this field aswell.
134 */
135 spin_lock(&spu_prio->runq_lock);
136 ctx->cpus_allowed = current->cpus_allowed;
137 spin_unlock(&spu_prio->runq_lock);
69} 138}
70 139
71void spu_start_tick(struct spu_context *ctx) 140void spu_update_sched_info(struct spu_context *ctx)
72{ 141{
73 if (ctx->policy == SCHED_RR) { 142 int node = ctx->spu->node;
74 /* 143
75 * Make sure the exiting bit is cleared. 144 mutex_lock(&spu_prio->active_mutex[node]);
76 */ 145 __spu_update_sched_info(ctx);
77 clear_bit(SPU_SCHED_EXITING, &ctx->sched_flags); 146 mutex_unlock(&spu_prio->active_mutex[node]);
78 mb();
79 queue_delayed_work(spu_sched_wq, &ctx->sched_work, SPU_TIMESLICE);
80 }
81} 147}
82 148
83void spu_stop_tick(struct spu_context *ctx) 149static int __node_allowed(struct spu_context *ctx, int node)
84{ 150{
85 if (ctx->policy == SCHED_RR) { 151 if (nr_cpus_node(node)) {
86 /* 152 cpumask_t mask = node_to_cpumask(node);
87 * While the work can be rearming normally setting this flag 153
88 * makes sure it does not rearm itself anymore. 154 if (cpus_intersects(mask, ctx->cpus_allowed))
89 */ 155 return 1;
90 set_bit(SPU_SCHED_EXITING, &ctx->sched_flags);
91 mb();
92 cancel_delayed_work(&ctx->sched_work);
93 } 156 }
157
158 return 0;
159}
160
161static int node_allowed(struct spu_context *ctx, int node)
162{
163 int rval;
164
165 spin_lock(&spu_prio->runq_lock);
166 rval = __node_allowed(ctx, node);
167 spin_unlock(&spu_prio->runq_lock);
168
169 return rval;
94} 170}
95 171
96/** 172/**
@@ -99,9 +175,18 @@ void spu_stop_tick(struct spu_context *ctx)
99 */ 175 */
100static void spu_add_to_active_list(struct spu *spu) 176static void spu_add_to_active_list(struct spu *spu)
101{ 177{
102 mutex_lock(&spu_prio->active_mutex[spu->node]); 178 int node = spu->node;
103 list_add_tail(&spu->list, &spu_prio->active_list[spu->node]); 179
104 mutex_unlock(&spu_prio->active_mutex[spu->node]); 180 mutex_lock(&spu_prio->active_mutex[node]);
181 spu_prio->nr_active[node]++;
182 list_add_tail(&spu->list, &spu_prio->active_list[node]);
183 mutex_unlock(&spu_prio->active_mutex[node]);
184}
185
186static void __spu_remove_from_active_list(struct spu *spu)
187{
188 list_del_init(&spu->list);
189 spu_prio->nr_active[spu->node]--;
105} 190}
106 191
107/** 192/**
@@ -113,7 +198,7 @@ static void spu_remove_from_active_list(struct spu *spu)
113 int node = spu->node; 198 int node = spu->node;
114 199
115 mutex_lock(&spu_prio->active_mutex[node]); 200 mutex_lock(&spu_prio->active_mutex[node]);
116 list_del_init(&spu->list); 201 __spu_remove_from_active_list(spu);
117 mutex_unlock(&spu_prio->active_mutex[node]); 202 mutex_unlock(&spu_prio->active_mutex[node]);
118} 203}
119 204
@@ -144,6 +229,10 @@ static void spu_bind_context(struct spu *spu, struct spu_context *ctx)
144{ 229{
145 pr_debug("%s: pid=%d SPU=%d NODE=%d\n", __FUNCTION__, current->pid, 230 pr_debug("%s: pid=%d SPU=%d NODE=%d\n", __FUNCTION__, current->pid,
146 spu->number, spu->node); 231 spu->number, spu->node);
232
233 ctx->stats.slb_flt_base = spu->stats.slb_flt;
234 ctx->stats.class2_intr_base = spu->stats.class2_intr;
235
147 spu->ctx = ctx; 236 spu->ctx = ctx;
148 spu->flags = 0; 237 spu->flags = 0;
149 ctx->spu = spu; 238 ctx->spu = spu;
@@ -161,8 +250,8 @@ static void spu_bind_context(struct spu *spu, struct spu_context *ctx)
161 spu->timestamp = jiffies; 250 spu->timestamp = jiffies;
162 spu_cpu_affinity_set(spu, raw_smp_processor_id()); 251 spu_cpu_affinity_set(spu, raw_smp_processor_id());
163 spu_switch_notify(spu, ctx); 252 spu_switch_notify(spu, ctx);
164 spu_add_to_active_list(spu);
165 ctx->state = SPU_STATE_RUNNABLE; 253 ctx->state = SPU_STATE_RUNNABLE;
254 spu_switch_state(spu, SPU_UTIL_SYSTEM);
166} 255}
167 256
168/** 257/**
@@ -175,7 +264,8 @@ static void spu_unbind_context(struct spu *spu, struct spu_context *ctx)
175 pr_debug("%s: unbind pid=%d SPU=%d NODE=%d\n", __FUNCTION__, 264 pr_debug("%s: unbind pid=%d SPU=%d NODE=%d\n", __FUNCTION__,
176 spu->pid, spu->number, spu->node); 265 spu->pid, spu->number, spu->node);
177 266
178 spu_remove_from_active_list(spu); 267 spu_switch_state(spu, SPU_UTIL_IDLE);
268
179 spu_switch_notify(spu, NULL); 269 spu_switch_notify(spu, NULL);
180 spu_unmap_mappings(ctx); 270 spu_unmap_mappings(ctx);
181 spu_save(&ctx->csa, spu); 271 spu_save(&ctx->csa, spu);
@@ -192,6 +282,11 @@ static void spu_unbind_context(struct spu *spu, struct spu_context *ctx)
192 ctx->spu = NULL; 282 ctx->spu = NULL;
193 spu->flags = 0; 283 spu->flags = 0;
194 spu->ctx = NULL; 284 spu->ctx = NULL;
285
286 ctx->stats.slb_flt +=
287 (spu->stats.slb_flt - ctx->stats.slb_flt_base);
288 ctx->stats.class2_intr +=
289 (spu->stats.class2_intr - ctx->stats.class2_intr_base);
195} 290}
196 291
197/** 292/**
@@ -200,20 +295,39 @@ static void spu_unbind_context(struct spu *spu, struct spu_context *ctx)
200 */ 295 */
201static void __spu_add_to_rq(struct spu_context *ctx) 296static void __spu_add_to_rq(struct spu_context *ctx)
202{ 297{
203 int prio = ctx->prio; 298 /*
204 299 * Unfortunately this code path can be called from multiple threads
205 list_add_tail(&ctx->rq, &spu_prio->runq[prio]); 300 * on behalf of a single context due to the way the problem state
206 set_bit(prio, spu_prio->bitmap); 301 * mmap support works.
302 *
303 * Fortunately we need to wake up all these threads at the same time
304 * and can simply skip the runqueue addition for every but the first
305 * thread getting into this codepath.
306 *
307 * It's still quite hacky, and long-term we should proxy all other
308 * threads through the owner thread so that spu_run is in control
309 * of all the scheduling activity for a given context.
310 */
311 if (list_empty(&ctx->rq)) {
312 list_add_tail(&ctx->rq, &spu_prio->runq[ctx->prio]);
313 set_bit(ctx->prio, spu_prio->bitmap);
314 if (!spu_prio->nr_waiting++)
315 __mod_timer(&spusched_timer, jiffies + SPUSCHED_TICK);
316 }
207} 317}
208 318
209static void __spu_del_from_rq(struct spu_context *ctx) 319static void __spu_del_from_rq(struct spu_context *ctx)
210{ 320{
211 int prio = ctx->prio; 321 int prio = ctx->prio;
212 322
213 if (!list_empty(&ctx->rq)) 323 if (!list_empty(&ctx->rq)) {
324 if (!--spu_prio->nr_waiting)
325 del_timer(&spusched_timer);
214 list_del_init(&ctx->rq); 326 list_del_init(&ctx->rq);
215 if (list_empty(&spu_prio->runq[prio])) 327
216 clear_bit(prio, spu_prio->bitmap); 328 if (list_empty(&spu_prio->runq[prio]))
329 clear_bit(prio, spu_prio->bitmap);
330 }
217} 331}
218 332
219static void spu_prio_wait(struct spu_context *ctx) 333static void spu_prio_wait(struct spu_context *ctx)
@@ -244,7 +358,7 @@ static struct spu *spu_get_idle(struct spu_context *ctx)
244 358
245 for (n = 0; n < MAX_NUMNODES; n++, node++) { 359 for (n = 0; n < MAX_NUMNODES; n++, node++) {
246 node = (node < MAX_NUMNODES) ? node : 0; 360 node = (node < MAX_NUMNODES) ? node : 0;
247 if (!node_allowed(node)) 361 if (!node_allowed(ctx, node))
248 continue; 362 continue;
249 spu = spu_alloc_node(node); 363 spu = spu_alloc_node(node);
250 if (spu) 364 if (spu)
@@ -276,15 +390,15 @@ static struct spu *find_victim(struct spu_context *ctx)
276 node = cpu_to_node(raw_smp_processor_id()); 390 node = cpu_to_node(raw_smp_processor_id());
277 for (n = 0; n < MAX_NUMNODES; n++, node++) { 391 for (n = 0; n < MAX_NUMNODES; n++, node++) {
278 node = (node < MAX_NUMNODES) ? node : 0; 392 node = (node < MAX_NUMNODES) ? node : 0;
279 if (!node_allowed(node)) 393 if (!node_allowed(ctx, node))
280 continue; 394 continue;
281 395
282 mutex_lock(&spu_prio->active_mutex[node]); 396 mutex_lock(&spu_prio->active_mutex[node]);
283 list_for_each_entry(spu, &spu_prio->active_list[node], list) { 397 list_for_each_entry(spu, &spu_prio->active_list[node], list) {
284 struct spu_context *tmp = spu->ctx; 398 struct spu_context *tmp = spu->ctx;
285 399
286 if (tmp->rt_priority < ctx->rt_priority && 400 if (tmp->prio > ctx->prio &&
287 (!victim || tmp->rt_priority < victim->rt_priority)) 401 (!victim || tmp->prio > victim->prio))
288 victim = spu->ctx; 402 victim = spu->ctx;
289 } 403 }
290 mutex_unlock(&spu_prio->active_mutex[node]); 404 mutex_unlock(&spu_prio->active_mutex[node]);
@@ -312,7 +426,10 @@ static struct spu *find_victim(struct spu_context *ctx)
312 victim = NULL; 426 victim = NULL;
313 goto restart; 427 goto restart;
314 } 428 }
429 spu_remove_from_active_list(spu);
315 spu_unbind_context(spu, victim); 430 spu_unbind_context(spu, victim);
431 victim->stats.invol_ctx_switch++;
432 spu->stats.invol_ctx_switch++;
316 mutex_unlock(&victim->state_mutex); 433 mutex_unlock(&victim->state_mutex);
317 /* 434 /*
318 * We need to break out of the wait loop in spu_run 435 * We need to break out of the wait loop in spu_run
@@ -338,22 +455,30 @@ static struct spu *find_victim(struct spu_context *ctx)
338 */ 455 */
339int spu_activate(struct spu_context *ctx, unsigned long flags) 456int spu_activate(struct spu_context *ctx, unsigned long flags)
340{ 457{
341 458 spuctx_switch_state(ctx, SPUCTX_UTIL_SYSTEM);
342 if (ctx->spu)
343 return 0;
344 459
345 do { 460 do {
346 struct spu *spu; 461 struct spu *spu;
347 462
463 /*
464 * If there are multiple threads waiting for a single context
465 * only one actually binds the context while the others will
466 * only be able to acquire the state_mutex once the context
467 * already is in runnable state.
468 */
469 if (ctx->spu)
470 return 0;
471
348 spu = spu_get_idle(ctx); 472 spu = spu_get_idle(ctx);
349 /* 473 /*
350 * If this is a realtime thread we try to get it running by 474 * If this is a realtime thread we try to get it running by
351 * preempting a lower priority thread. 475 * preempting a lower priority thread.
352 */ 476 */
353 if (!spu && ctx->rt_priority) 477 if (!spu && rt_prio(ctx->prio))
354 spu = find_victim(ctx); 478 spu = find_victim(ctx);
355 if (spu) { 479 if (spu) {
356 spu_bind_context(spu, ctx); 480 spu_bind_context(spu, ctx);
481 spu_add_to_active_list(spu);
357 return 0; 482 return 0;
358 } 483 }
359 484
@@ -369,23 +494,28 @@ int spu_activate(struct spu_context *ctx, unsigned long flags)
369 * Remove the highest priority context on the runqueue and return it 494 * Remove the highest priority context on the runqueue and return it
370 * to the caller. Returns %NULL if no runnable context was found. 495 * to the caller. Returns %NULL if no runnable context was found.
371 */ 496 */
372static struct spu_context *grab_runnable_context(int prio) 497static struct spu_context *grab_runnable_context(int prio, int node)
373{ 498{
374 struct spu_context *ctx = NULL; 499 struct spu_context *ctx;
375 int best; 500 int best;
376 501
377 spin_lock(&spu_prio->runq_lock); 502 spin_lock(&spu_prio->runq_lock);
378 best = sched_find_first_bit(spu_prio->bitmap); 503 best = sched_find_first_bit(spu_prio->bitmap);
379 if (best < prio) { 504 while (best < prio) {
380 struct list_head *rq = &spu_prio->runq[best]; 505 struct list_head *rq = &spu_prio->runq[best];
381 506
382 BUG_ON(list_empty(rq)); 507 list_for_each_entry(ctx, rq, rq) {
383 508 /* XXX(hch): check for affinity here aswell */
384 ctx = list_entry(rq->next, struct spu_context, rq); 509 if (__node_allowed(ctx, node)) {
385 __spu_del_from_rq(ctx); 510 __spu_del_from_rq(ctx);
511 goto found;
512 }
513 }
514 best++;
386 } 515 }
516 ctx = NULL;
517 found:
387 spin_unlock(&spu_prio->runq_lock); 518 spin_unlock(&spu_prio->runq_lock);
388
389 return ctx; 519 return ctx;
390} 520}
391 521
@@ -395,9 +525,12 @@ static int __spu_deactivate(struct spu_context *ctx, int force, int max_prio)
395 struct spu_context *new = NULL; 525 struct spu_context *new = NULL;
396 526
397 if (spu) { 527 if (spu) {
398 new = grab_runnable_context(max_prio); 528 new = grab_runnable_context(max_prio, spu->node);
399 if (new || force) { 529 if (new || force) {
530 spu_remove_from_active_list(spu);
400 spu_unbind_context(spu, ctx); 531 spu_unbind_context(spu, ctx);
532 ctx->stats.vol_ctx_switch++;
533 spu->stats.vol_ctx_switch++;
401 spu_free(spu); 534 spu_free(spu);
402 if (new) 535 if (new)
403 wake_up(&new->stop_wq); 536 wake_up(&new->stop_wq);
@@ -417,7 +550,17 @@ static int __spu_deactivate(struct spu_context *ctx, int force, int max_prio)
417 */ 550 */
418void spu_deactivate(struct spu_context *ctx) 551void spu_deactivate(struct spu_context *ctx)
419{ 552{
553 /*
554 * We must never reach this for a nosched context,
555 * but handle the case gracefull instead of panicing.
556 */
557 if (ctx->flags & SPU_CREATE_NOSCHED) {
558 WARN_ON(1);
559 return;
560 }
561
420 __spu_deactivate(ctx, 1, MAX_PRIO); 562 __spu_deactivate(ctx, 1, MAX_PRIO);
563 spuctx_switch_state(ctx, SPUCTX_UTIL_USER);
421} 564}
422 565
423/** 566/**
@@ -432,56 +575,178 @@ void spu_yield(struct spu_context *ctx)
432{ 575{
433 if (!(ctx->flags & SPU_CREATE_NOSCHED)) { 576 if (!(ctx->flags & SPU_CREATE_NOSCHED)) {
434 mutex_lock(&ctx->state_mutex); 577 mutex_lock(&ctx->state_mutex);
435 __spu_deactivate(ctx, 0, MAX_PRIO); 578 if (__spu_deactivate(ctx, 0, MAX_PRIO))
579 spuctx_switch_state(ctx, SPUCTX_UTIL_USER);
580 else {
581 spuctx_switch_state(ctx, SPUCTX_UTIL_LOADED);
582 spu_switch_state(ctx->spu, SPU_UTIL_USER);
583 }
436 mutex_unlock(&ctx->state_mutex); 584 mutex_unlock(&ctx->state_mutex);
437 } 585 }
438} 586}
439 587
440void spu_sched_tick(struct work_struct *work) 588static void spusched_tick(struct spu_context *ctx)
441{ 589{
442 struct spu_context *ctx = 590 if (ctx->flags & SPU_CREATE_NOSCHED)
443 container_of(work, struct spu_context, sched_work.work); 591 return;
444 int preempted; 592 if (ctx->policy == SCHED_FIFO)
593 return;
594
595 if (--ctx->time_slice)
596 return;
445 597
446 /* 598 /*
447 * If this context is being stopped avoid rescheduling from the 599 * Unfortunately active_mutex ranks outside of state_mutex, so
448 * scheduler tick because we would block on the state_mutex. 600 * we have to trylock here. If we fail give the context another
449 * The caller will yield the spu later on anyway. 601 * tick and try again.
450 */ 602 */
451 if (test_bit(SPU_SCHED_EXITING, &ctx->sched_flags)) 603 if (mutex_trylock(&ctx->state_mutex)) {
452 return; 604 struct spu *spu = ctx->spu;
605 struct spu_context *new;
453 606
454 mutex_lock(&ctx->state_mutex); 607 new = grab_runnable_context(ctx->prio + 1, spu->node);
455 preempted = __spu_deactivate(ctx, 0, ctx->prio + 1); 608 if (new) {
456 mutex_unlock(&ctx->state_mutex);
457 609
458 if (preempted) { 610 __spu_remove_from_active_list(spu);
459 /* 611 spu_unbind_context(spu, ctx);
460 * We need to break out of the wait loop in spu_run manually 612 ctx->stats.invol_ctx_switch++;
461 * to ensure this context gets put on the runqueue again 613 spu->stats.invol_ctx_switch++;
462 * ASAP. 614 spu_free(spu);
463 */ 615 wake_up(&new->stop_wq);
464 wake_up(&ctx->stop_wq); 616 /*
617 * We need to break out of the wait loop in
618 * spu_run manually to ensure this context
619 * gets put on the runqueue again ASAP.
620 */
621 wake_up(&ctx->stop_wq);
622 }
623 spu_set_timeslice(ctx);
624 mutex_unlock(&ctx->state_mutex);
465 } else { 625 } else {
466 spu_start_tick(ctx); 626 ctx->time_slice++;
467 } 627 }
468} 628}
469 629
470int __init spu_sched_init(void) 630/**
631 * count_active_contexts - count nr of active tasks
632 *
633 * Return the number of tasks currently running or waiting to run.
634 *
635 * Note that we don't take runq_lock / active_mutex here. Reading
636 * a single 32bit value is atomic on powerpc, and we don't care
637 * about memory ordering issues here.
638 */
639static unsigned long count_active_contexts(void)
471{ 640{
472 int i; 641 int nr_active = 0, node;
473 642
474 spu_sched_wq = create_singlethread_workqueue("spusched"); 643 for (node = 0; node < MAX_NUMNODES; node++)
475 if (!spu_sched_wq) 644 nr_active += spu_prio->nr_active[node];
476 return 1; 645 nr_active += spu_prio->nr_waiting;
477 646
478 spu_prio = kzalloc(sizeof(struct spu_prio_array), GFP_KERNEL); 647 return nr_active;
479 if (!spu_prio) { 648}
480 printk(KERN_WARNING "%s: Unable to allocate priority queue.\n", 649
481 __FUNCTION__); 650/**
482 destroy_workqueue(spu_sched_wq); 651 * spu_calc_load - given tick count, update the avenrun load estimates.
483 return 1; 652 * @tick: tick count
653 *
654 * No locking against reading these values from userspace, as for
655 * the CPU loadavg code.
656 */
657static void spu_calc_load(unsigned long ticks)
658{
659 unsigned long active_tasks; /* fixed-point */
660 static int count = LOAD_FREQ;
661
662 count -= ticks;
663
664 if (unlikely(count < 0)) {
665 active_tasks = count_active_contexts() * FIXED_1;
666 do {
667 CALC_LOAD(spu_avenrun[0], EXP_1, active_tasks);
668 CALC_LOAD(spu_avenrun[1], EXP_5, active_tasks);
669 CALC_LOAD(spu_avenrun[2], EXP_15, active_tasks);
670 count += LOAD_FREQ;
671 } while (count < 0);
484 } 672 }
673}
674
675static void spusched_wake(unsigned long data)
676{
677 mod_timer(&spusched_timer, jiffies + SPUSCHED_TICK);
678 wake_up_process(spusched_task);
679 spu_calc_load(SPUSCHED_TICK);
680}
681
682static int spusched_thread(void *unused)
683{
684 struct spu *spu, *next;
685 int node;
686
687 while (!kthread_should_stop()) {
688 set_current_state(TASK_INTERRUPTIBLE);
689 schedule();
690 for (node = 0; node < MAX_NUMNODES; node++) {
691 mutex_lock(&spu_prio->active_mutex[node]);
692 list_for_each_entry_safe(spu, next,
693 &spu_prio->active_list[node],
694 list)
695 spusched_tick(spu->ctx);
696 mutex_unlock(&spu_prio->active_mutex[node]);
697 }
698 }
699
700 return 0;
701}
702
703#define LOAD_INT(x) ((x) >> FSHIFT)
704#define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100)
705
706static int show_spu_loadavg(struct seq_file *s, void *private)
707{
708 int a, b, c;
709
710 a = spu_avenrun[0] + (FIXED_1/200);
711 b = spu_avenrun[1] + (FIXED_1/200);
712 c = spu_avenrun[2] + (FIXED_1/200);
713
714 /*
715 * Note that last_pid doesn't really make much sense for the
716 * SPU loadavg (it even seems very odd on the CPU side..),
717 * but we include it here to have a 100% compatible interface.
718 */
719 seq_printf(s, "%d.%02d %d.%02d %d.%02d %ld/%d %d\n",
720 LOAD_INT(a), LOAD_FRAC(a),
721 LOAD_INT(b), LOAD_FRAC(b),
722 LOAD_INT(c), LOAD_FRAC(c),
723 count_active_contexts(),
724 atomic_read(&nr_spu_contexts),
725 current->nsproxy->pid_ns->last_pid);
726 return 0;
727}
728
729static int spu_loadavg_open(struct inode *inode, struct file *file)
730{
731 return single_open(file, show_spu_loadavg, NULL);
732}
733
734static const struct file_operations spu_loadavg_fops = {
735 .open = spu_loadavg_open,
736 .read = seq_read,
737 .llseek = seq_lseek,
738 .release = single_release,
739};
740
741int __init spu_sched_init(void)
742{
743 struct proc_dir_entry *entry;
744 int err = -ENOMEM, i;
745
746 spu_prio = kzalloc(sizeof(struct spu_prio_array), GFP_KERNEL);
747 if (!spu_prio)
748 goto out;
749
485 for (i = 0; i < MAX_PRIO; i++) { 750 for (i = 0; i < MAX_PRIO; i++) {
486 INIT_LIST_HEAD(&spu_prio->runq[i]); 751 INIT_LIST_HEAD(&spu_prio->runq[i]);
487 __clear_bit(i, spu_prio->bitmap); 752 __clear_bit(i, spu_prio->bitmap);
@@ -492,7 +757,30 @@ int __init spu_sched_init(void)
492 INIT_LIST_HEAD(&spu_prio->active_list[i]); 757 INIT_LIST_HEAD(&spu_prio->active_list[i]);
493 } 758 }
494 spin_lock_init(&spu_prio->runq_lock); 759 spin_lock_init(&spu_prio->runq_lock);
760
761 setup_timer(&spusched_timer, spusched_wake, 0);
762
763 spusched_task = kthread_run(spusched_thread, NULL, "spusched");
764 if (IS_ERR(spusched_task)) {
765 err = PTR_ERR(spusched_task);
766 goto out_free_spu_prio;
767 }
768
769 entry = create_proc_entry("spu_loadavg", 0, NULL);
770 if (!entry)
771 goto out_stop_kthread;
772 entry->proc_fops = &spu_loadavg_fops;
773
774 pr_debug("spusched: tick: %d, min ticks: %d, default ticks: %d\n",
775 SPUSCHED_TICK, MIN_SPU_TIMESLICE, DEF_SPU_TIMESLICE);
495 return 0; 776 return 0;
777
778 out_stop_kthread:
779 kthread_stop(spusched_task);
780 out_free_spu_prio:
781 kfree(spu_prio);
782 out:
783 return err;
496} 784}
497 785
498void __exit spu_sched_exit(void) 786void __exit spu_sched_exit(void)
@@ -500,6 +788,11 @@ void __exit spu_sched_exit(void)
500 struct spu *spu, *tmp; 788 struct spu *spu, *tmp;
501 int node; 789 int node;
502 790
791 remove_proc_entry("spu_loadavg", NULL);
792
793 del_timer_sync(&spusched_timer);
794 kthread_stop(spusched_task);
795
503 for (node = 0; node < MAX_NUMNODES; node++) { 796 for (node = 0; node < MAX_NUMNODES; node++) {
504 mutex_lock(&spu_prio->active_mutex[node]); 797 mutex_lock(&spu_prio->active_mutex[node]);
505 list_for_each_entry_safe(spu, tmp, &spu_prio->active_list[node], 798 list_for_each_entry_safe(spu, tmp, &spu_prio->active_list[node],
@@ -510,5 +803,4 @@ void __exit spu_sched_exit(void)
510 mutex_unlock(&spu_prio->active_mutex[node]); 803 mutex_unlock(&spu_prio->active_mutex[node]);
511 } 804 }
512 kfree(spu_prio); 805 kfree(spu_prio);
513 destroy_workqueue(spu_sched_wq);
514} 806}
diff --git a/arch/powerpc/platforms/cell/spufs/spu_restore.c b/arch/powerpc/platforms/cell/spufs/spu_restore.c
index 0bf723dcd677..4e19ed7a0756 100644
--- a/arch/powerpc/platforms/cell/spufs/spu_restore.c
+++ b/arch/powerpc/platforms/cell/spufs/spu_restore.c
@@ -296,7 +296,7 @@ static inline void restore_complete(void)
296 * This code deviates from the documented sequence in the 296 * This code deviates from the documented sequence in the
297 * following aspects: 297 * following aspects:
298 * 298 *
299 * 1. The EA for LSCSA is passed from PPE in the 299 * 1. The EA for LSCSA is passed from PPE in the
300 * signal notification channels. 300 * signal notification channels.
301 * 2. The register spill area is pulled by SPU 301 * 2. The register spill area is pulled by SPU
302 * into LS, rather than pushed by PPE. 302 * into LS, rather than pushed by PPE.
diff --git a/arch/powerpc/platforms/cell/spufs/spu_save.c b/arch/powerpc/platforms/cell/spufs/spu_save.c
index 196033b8a579..ae95cc1701e9 100644
--- a/arch/powerpc/platforms/cell/spufs/spu_save.c
+++ b/arch/powerpc/platforms/cell/spufs/spu_save.c
@@ -44,7 +44,7 @@ static inline void save_event_mask(void)
44 * Read the SPU_RdEventMsk channel and save to the LSCSA. 44 * Read the SPU_RdEventMsk channel and save to the LSCSA.
45 */ 45 */
46 offset = LSCSA_QW_OFFSET(event_mask); 46 offset = LSCSA_QW_OFFSET(event_mask);
47 regs_spill[offset].slot[0] = spu_readch(SPU_RdEventStatMask); 47 regs_spill[offset].slot[0] = spu_readch(SPU_RdEventMask);
48} 48}
49 49
50static inline void save_tag_mask(void) 50static inline void save_tag_mask(void)
diff --git a/arch/powerpc/platforms/cell/spufs/spufs.h b/arch/powerpc/platforms/cell/spufs/spufs.h
index 47617e8014a5..08b3530288ac 100644
--- a/arch/powerpc/platforms/cell/spufs/spufs.h
+++ b/arch/powerpc/platforms/cell/spufs/spufs.h
@@ -26,6 +26,7 @@
26#include <linux/mutex.h> 26#include <linux/mutex.h>
27#include <linux/spinlock.h> 27#include <linux/spinlock.h>
28#include <linux/fs.h> 28#include <linux/fs.h>
29#include <linux/cpumask.h>
29 30
30#include <asm/spu.h> 31#include <asm/spu.h>
31#include <asm/spu_csa.h> 32#include <asm/spu_csa.h>
@@ -39,9 +40,17 @@ enum {
39struct spu_context_ops; 40struct spu_context_ops;
40struct spu_gang; 41struct spu_gang;
41 42
42/* ctx->sched_flags */ 43/*
43enum { 44 * This is the state for spu utilization reporting to userspace.
44 SPU_SCHED_EXITING = 0, 45 * Because this state is visible to userspace it must never change and needs
46 * to be kept strictly separate from any internal state kept by the kernel.
47 */
48enum spuctx_execution_state {
49 SPUCTX_UTIL_USER = 0,
50 SPUCTX_UTIL_SYSTEM,
51 SPUCTX_UTIL_IOWAIT,
52 SPUCTX_UTIL_LOADED,
53 SPUCTX_UTIL_MAX
45}; 54};
46 55
47struct spu_context { 56struct spu_context {
@@ -81,13 +90,34 @@ struct spu_context {
81 struct list_head gang_list; 90 struct list_head gang_list;
82 struct spu_gang *gang; 91 struct spu_gang *gang;
83 92
93 /* owner thread */
94 pid_t tid;
95
84 /* scheduler fields */ 96 /* scheduler fields */
85 struct list_head rq; 97 struct list_head rq;
86 struct delayed_work sched_work; 98 unsigned int time_slice;
87 unsigned long sched_flags; 99 unsigned long sched_flags;
88 unsigned long rt_priority; 100 cpumask_t cpus_allowed;
89 int policy; 101 int policy;
90 int prio; 102 int prio;
103
104 /* statistics */
105 struct {
106 /* updates protected by ctx->state_mutex */
107 enum spuctx_execution_state execution_state;
108 unsigned long tstamp; /* time of last ctx switch */
109 unsigned long times[SPUCTX_UTIL_MAX];
110 unsigned long long vol_ctx_switch;
111 unsigned long long invol_ctx_switch;
112 unsigned long long min_flt;
113 unsigned long long maj_flt;
114 unsigned long long hash_flt;
115 unsigned long long slb_flt;
116 unsigned long long slb_flt_base; /* # at last ctx switch */
117 unsigned long long class2_intr;
118 unsigned long long class2_intr_base; /* # at last ctx switch */
119 unsigned long long libassist;
120 } stats;
91}; 121};
92 122
93struct spu_gang { 123struct spu_gang {
@@ -177,6 +207,7 @@ void spu_gang_add_ctx(struct spu_gang *gang, struct spu_context *ctx);
177int spufs_handle_class1(struct spu_context *ctx); 207int spufs_handle_class1(struct spu_context *ctx);
178 208
179/* context management */ 209/* context management */
210extern atomic_t nr_spu_contexts;
180static inline void spu_acquire(struct spu_context *ctx) 211static inline void spu_acquire(struct spu_context *ctx)
181{ 212{
182 mutex_lock(&ctx->state_mutex); 213 mutex_lock(&ctx->state_mutex);
@@ -200,9 +231,9 @@ void spu_acquire_saved(struct spu_context *ctx);
200int spu_activate(struct spu_context *ctx, unsigned long flags); 231int spu_activate(struct spu_context *ctx, unsigned long flags);
201void spu_deactivate(struct spu_context *ctx); 232void spu_deactivate(struct spu_context *ctx);
202void spu_yield(struct spu_context *ctx); 233void spu_yield(struct spu_context *ctx);
203void spu_start_tick(struct spu_context *ctx); 234void spu_set_timeslice(struct spu_context *ctx);
204void spu_stop_tick(struct spu_context *ctx); 235void spu_update_sched_info(struct spu_context *ctx);
205void spu_sched_tick(struct work_struct *work); 236void __spu_update_sched_info(struct spu_context *ctx);
206int __init spu_sched_init(void); 237int __init spu_sched_init(void);
207void __exit spu_sched_exit(void); 238void __exit spu_sched_exit(void);
208 239
@@ -210,7 +241,7 @@ extern char *isolated_loader;
210 241
211/* 242/*
212 * spufs_wait 243 * spufs_wait
213 * Same as wait_event_interruptible(), except that here 244 * Same as wait_event_interruptible(), except that here
214 * we need to call spu_release(ctx) before sleeping, and 245 * we need to call spu_release(ctx) before sleeping, and
215 * then spu_acquire(ctx) when awoken. 246 * then spu_acquire(ctx) when awoken.
216 */ 247 */
@@ -256,4 +287,37 @@ struct spufs_coredump_reader {
256extern struct spufs_coredump_reader spufs_coredump_read[]; 287extern struct spufs_coredump_reader spufs_coredump_read[];
257extern int spufs_coredump_num_notes; 288extern int spufs_coredump_num_notes;
258 289
290/*
291 * This function is a little bit too large for an inline, but
292 * as fault.c is built into the kernel we can't move it out of
293 * line.
294 */
295static inline void spuctx_switch_state(struct spu_context *ctx,
296 enum spuctx_execution_state new_state)
297{
298 WARN_ON(!mutex_is_locked(&ctx->state_mutex));
299
300 if (ctx->stats.execution_state != new_state) {
301 unsigned long curtime = jiffies;
302
303 ctx->stats.times[ctx->stats.execution_state] +=
304 curtime - ctx->stats.tstamp;
305 ctx->stats.tstamp = curtime;
306 ctx->stats.execution_state = new_state;
307 }
308}
309
310static inline void spu_switch_state(struct spu *spu,
311 enum spuctx_execution_state new_state)
312{
313 if (spu->stats.utilization_state != new_state) {
314 unsigned long curtime = jiffies;
315
316 spu->stats.times[spu->stats.utilization_state] +=
317 curtime - spu->stats.tstamp;
318 spu->stats.tstamp = curtime;
319 spu->stats.utilization_state = new_state;
320 }
321}
322
259#endif 323#endif
diff --git a/arch/powerpc/platforms/cell/spufs/switch.c b/arch/powerpc/platforms/cell/spufs/switch.c
index 71a0b41adb8c..9c506ba08cdc 100644
--- a/arch/powerpc/platforms/cell/spufs/switch.c
+++ b/arch/powerpc/platforms/cell/spufs/switch.c
@@ -70,7 +70,7 @@
70 } 70 }
71#endif /* debug */ 71#endif /* debug */
72 72
73#define POLL_WHILE_FALSE(_c) POLL_WHILE_TRUE(!(_c)) 73#define POLL_WHILE_FALSE(_c) POLL_WHILE_TRUE(!(_c))
74 74
75static inline void acquire_spu_lock(struct spu *spu) 75static inline void acquire_spu_lock(struct spu *spu)
76{ 76{
@@ -387,6 +387,19 @@ static inline void save_ppu_querytype(struct spu_state *csa, struct spu *spu)
387 csa->prob.dma_querytype_RW = in_be32(&prob->dma_querytype_RW); 387 csa->prob.dma_querytype_RW = in_be32(&prob->dma_querytype_RW);
388} 388}
389 389
390static inline void save_ppu_tagstatus(struct spu_state *csa, struct spu *spu)
391{
392 struct spu_problem __iomem *prob = spu->problem;
393
394 /* Save the Prxy_TagStatus register in the CSA.
395 *
396 * It is unnecessary to restore dma_tagstatus_R, however,
397 * dma_tagstatus_R in the CSA is accessed via backing_ops, so
398 * we must save it.
399 */
400 csa->prob.dma_tagstatus_R = in_be32(&prob->dma_tagstatus_R);
401}
402
390static inline void save_mfc_csr_tsq(struct spu_state *csa, struct spu *spu) 403static inline void save_mfc_csr_tsq(struct spu_state *csa, struct spu *spu)
391{ 404{
392 struct spu_priv2 __iomem *priv2 = spu->priv2; 405 struct spu_priv2 __iomem *priv2 = spu->priv2;
@@ -1812,6 +1825,7 @@ static void save_csa(struct spu_state *prev, struct spu *spu)
1812 save_mfc_queues(prev, spu); /* Step 19. */ 1825 save_mfc_queues(prev, spu); /* Step 19. */
1813 save_ppu_querymask(prev, spu); /* Step 20. */ 1826 save_ppu_querymask(prev, spu); /* Step 20. */
1814 save_ppu_querytype(prev, spu); /* Step 21. */ 1827 save_ppu_querytype(prev, spu); /* Step 21. */
1828 save_ppu_tagstatus(prev, spu); /* NEW. */
1815 save_mfc_csr_tsq(prev, spu); /* Step 22. */ 1829 save_mfc_csr_tsq(prev, spu); /* Step 22. */
1816 save_mfc_csr_cmd(prev, spu); /* Step 23. */ 1830 save_mfc_csr_cmd(prev, spu); /* Step 23. */
1817 save_mfc_csr_ato(prev, spu); /* Step 24. */ 1831 save_mfc_csr_ato(prev, spu); /* Step 24. */
@@ -1930,7 +1944,7 @@ static void harvest(struct spu_state *prev, struct spu *spu)
1930 reset_spu_privcntl(prev, spu); /* Step 16. */ 1944 reset_spu_privcntl(prev, spu); /* Step 16. */
1931 reset_spu_lslr(prev, spu); /* Step 17. */ 1945 reset_spu_lslr(prev, spu); /* Step 17. */
1932 setup_mfc_sr1(prev, spu); /* Step 18. */ 1946 setup_mfc_sr1(prev, spu); /* Step 18. */
1933 spu_invalidate_slbs(spu); /* Step 19. */ 1947 spu_invalidate_slbs(spu); /* Step 19. */
1934 reset_ch_part1(prev, spu); /* Step 20. */ 1948 reset_ch_part1(prev, spu); /* Step 20. */
1935 reset_ch_part2(prev, spu); /* Step 21. */ 1949 reset_ch_part2(prev, spu); /* Step 21. */
1936 enable_interrupts(prev, spu); /* Step 22. */ 1950 enable_interrupts(prev, spu); /* Step 22. */
diff --git a/arch/powerpc/platforms/chrp/Kconfig b/arch/powerpc/platforms/chrp/Kconfig
index d2c690531963..22b4b4e3b6f0 100644
--- a/arch/powerpc/platforms/chrp/Kconfig
+++ b/arch/powerpc/platforms/chrp/Kconfig
@@ -8,4 +8,5 @@ config PPC_CHRP
8 select PPC_MPC106 8 select PPC_MPC106
9 select PPC_UDBG_16550 9 select PPC_UDBG_16550
10 select PPC_NATIVE 10 select PPC_NATIVE
11 select PCI
11 default y 12 default y
diff --git a/arch/powerpc/platforms/chrp/Makefile b/arch/powerpc/platforms/chrp/Makefile
index 902feb1ac431..4b3bfadc70fa 100644
--- a/arch/powerpc/platforms/chrp/Makefile
+++ b/arch/powerpc/platforms/chrp/Makefile
@@ -1,4 +1,3 @@
1obj-y += setup.o time.o pegasos_eth.o 1obj-y += setup.o time.o pegasos_eth.o pci.o
2obj-$(CONFIG_PCI) += pci.o
3obj-$(CONFIG_SMP) += smp.o 2obj-$(CONFIG_SMP) += smp.o
4obj-$(CONFIG_NVRAM) += nvram.o 3obj-$(CONFIG_NVRAM) += nvram.o
diff --git a/arch/powerpc/platforms/chrp/pci.c b/arch/powerpc/platforms/chrp/pci.c
index d32fedc991d3..3690624e49d4 100644
--- a/arch/powerpc/platforms/chrp/pci.c
+++ b/arch/powerpc/platforms/chrp/pci.c
@@ -99,7 +99,7 @@ int rtas_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
99 struct pci_controller *hose = bus->sysdata; 99 struct pci_controller *hose = bus->sysdata;
100 unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8) 100 unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8)
101 | (((bus->number - hose->first_busno) & 0xff) << 16) 101 | (((bus->number - hose->first_busno) & 0xff) << 16)
102 | (hose->index << 24); 102 | (hose->global_number << 24);
103 int ret = -1; 103 int ret = -1;
104 int rval; 104 int rval;
105 105
@@ -114,7 +114,7 @@ int rtas_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
114 struct pci_controller *hose = bus->sysdata; 114 struct pci_controller *hose = bus->sysdata;
115 unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8) 115 unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8)
116 | (((bus->number - hose->first_busno) & 0xff) << 16) 116 | (((bus->number - hose->first_busno) & 0xff) << 16)
117 | (hose->index << 24); 117 | (hose->global_number << 24);
118 int rval; 118 int rval;
119 119
120 rval = rtas_call(rtas_token("write-pci-config"), 3, 1, NULL, 120 rval = rtas_call(rtas_token("write-pci-config"), 3, 1, NULL,
@@ -254,13 +254,12 @@ chrp_find_bridges(void)
254 printk(" at %llx", (unsigned long long)r.start); 254 printk(" at %llx", (unsigned long long)r.start);
255 printk("\n"); 255 printk("\n");
256 256
257 hose = pcibios_alloc_controller(); 257 hose = pcibios_alloc_controller(dev);
258 if (!hose) { 258 if (!hose) {
259 printk("Can't allocate PCI controller structure for %s\n", 259 printk("Can't allocate PCI controller structure for %s\n",
260 dev->full_name); 260 dev->full_name);
261 continue; 261 continue;
262 } 262 }
263 hose->arch_data = dev;
264 hose->first_busno = bus_range[0]; 263 hose->first_busno = bus_range[0];
265 hose->last_busno = bus_range[1]; 264 hose->last_busno = bus_range[1];
266 265
diff --git a/arch/powerpc/platforms/embedded6xx/Kconfig b/arch/powerpc/platforms/embedded6xx/Kconfig
index f2d26268ca6f..bec772674e40 100644
--- a/arch/powerpc/platforms/embedded6xx/Kconfig
+++ b/arch/powerpc/platforms/embedded6xx/Kconfig
@@ -28,6 +28,7 @@ config PPC_HOLLY
28 bool "PPC750GX/CL with TSI10x bridge (Hickory/Holly)" 28 bool "PPC750GX/CL with TSI10x bridge (Hickory/Holly)"
29 select TSI108_BRIDGE 29 select TSI108_BRIDGE
30 select PPC_UDBG_16550 30 select PPC_UDBG_16550
31 select WANT_DEVICE_TREE
31 help 32 help
32 Select PPC_HOLLY if configuring for an IBM 750GX/CL Eval 33 Select PPC_HOLLY if configuring for an IBM 750GX/CL Eval
33 Board with TSI108/9 bridge (Hickory/Holly) 34 Board with TSI108/9 bridge (Hickory/Holly)
@@ -44,6 +45,7 @@ endchoice
44config TSI108_BRIDGE 45config TSI108_BRIDGE
45 bool 46 bool
46 depends on MPC7448HPC2 || PPC_HOLLY 47 depends on MPC7448HPC2 || PPC_HOLLY
48 select PCI
47 select MPIC 49 select MPIC
48 select MPIC_WEIRD 50 select MPIC_WEIRD
49 default y 51 default y
diff --git a/arch/powerpc/platforms/embedded6xx/holly.c b/arch/powerpc/platforms/embedded6xx/holly.c
index 3a0b4a01401c..6292e36dc577 100644
--- a/arch/powerpc/platforms/embedded6xx/holly.c
+++ b/arch/powerpc/platforms/embedded6xx/holly.c
@@ -45,7 +45,7 @@
45 45
46#define HOLLY_PCI_CFG_PHYS 0x7c000000 46#define HOLLY_PCI_CFG_PHYS 0x7c000000
47 47
48int holly_exclude_device(u_char bus, u_char devfn) 48int holly_exclude_device(struct pci_controller *hose, u_char bus, u_char devfn)
49{ 49{
50 if (bus == 0 && PCI_SLOT(devfn) == 0) 50 if (bus == 0 && PCI_SLOT(devfn) == 0)
51 return PCIBIOS_DEVICE_NOT_FOUND; 51 return PCIBIOS_DEVICE_NOT_FOUND;
diff --git a/arch/powerpc/platforms/embedded6xx/linkstation.c b/arch/powerpc/platforms/embedded6xx/linkstation.c
index b412f006a9c5..f4d0a7a603f5 100644
--- a/arch/powerpc/platforms/embedded6xx/linkstation.c
+++ b/arch/powerpc/platforms/embedded6xx/linkstation.c
@@ -54,8 +54,9 @@ static struct mtd_partition linkstation_physmap_partitions[] = {
54 }, 54 },
55}; 55};
56 56
57static int __init add_bridge(struct device_node *dev) 57static int __init linkstation_add_bridge(struct device_node *dev)
58{ 58{
59#ifdef CONFIG_PCI
59 int len; 60 int len;
60 struct pci_controller *hose; 61 struct pci_controller *hose;
61 const int *bus_range; 62 const int *bus_range;
@@ -67,18 +68,17 @@ static int __init add_bridge(struct device_node *dev)
67 printk(KERN_WARNING "Can't get bus-range for %s, assume" 68 printk(KERN_WARNING "Can't get bus-range for %s, assume"
68 " bus 0\n", dev->full_name); 69 " bus 0\n", dev->full_name);
69 70
70 hose = pcibios_alloc_controller(); 71 hose = pcibios_alloc_controller(dev);
71 if (hose == NULL) 72 if (hose == NULL)
72 return -ENOMEM; 73 return -ENOMEM;
73 hose->first_busno = bus_range ? bus_range[0] : 0; 74 hose->first_busno = bus_range ? bus_range[0] : 0;
74 hose->last_busno = bus_range ? bus_range[1] : 0xff; 75 hose->last_busno = bus_range ? bus_range[1] : 0xff;
75 hose->arch_data = dev;
76 setup_indirect_pci(hose, 0xfec00000, 0xfee00000); 76 setup_indirect_pci(hose, 0xfec00000, 0xfee00000);
77 77
78 /* Interpret the "ranges" property */ 78 /* Interpret the "ranges" property */
79 /* This also maps the I/O region and sets isa_io/mem_base */ 79 /* This also maps the I/O region and sets isa_io/mem_base */
80 pci_process_bridge_OF_ranges(hose, dev, 1); 80 pci_process_bridge_OF_ranges(hose, dev, 1);
81 81#endif
82 return 0; 82 return 0;
83} 83}
84 84
@@ -92,7 +92,7 @@ static void __init linkstation_setup_arch(void)
92 92
93 /* Lookup PCI host bridges */ 93 /* Lookup PCI host bridges */
94 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) 94 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
95 add_bridge(np); 95 linkstation_add_bridge(np);
96 96
97 printk(KERN_INFO "BUFFALO Network Attached Storage Series\n"); 97 printk(KERN_INFO "BUFFALO Network Attached Storage Series\n");
98 printk(KERN_INFO "(C) 2002-2005 BUFFALO INC.\n"); 98 printk(KERN_INFO "(C) 2002-2005 BUFFALO INC.\n");
diff --git a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c
index 4542e0c837c0..1e3cc69487b5 100644
--- a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c
+++ b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c
@@ -54,15 +54,10 @@
54 54
55#define MPC7448HPC2_PCI_CFG_PHYS 0xfb000000 55#define MPC7448HPC2_PCI_CFG_PHYS 0xfb000000
56 56
57#ifndef CONFIG_PCI
58isa_io_base = MPC7448_HPC2_ISA_IO_BASE;
59isa_mem_base = MPC7448_HPC2_ISA_MEM_BASE;
60pci_dram_offset = MPC7448_HPC2_PCI_MEM_OFFSET;
61#endif
62
63extern void _nmask_and_or_msr(unsigned long nmask, unsigned long or_val); 57extern void _nmask_and_or_msr(unsigned long nmask, unsigned long or_val);
64 58
65int mpc7448_hpc2_exclude_device(u_char bus, u_char devfn) 59int mpc7448_hpc2_exclude_device(struct pci_controller *hose,
60 u_char bus, u_char devfn)
66{ 61{
67 if (bus == 0 && PCI_SLOT(devfn) == 0) 62 if (bus == 0 && PCI_SLOT(devfn) == 0)
68 return PCIBIOS_DEVICE_NOT_FOUND; 63 return PCIBIOS_DEVICE_NOT_FOUND;
diff --git a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.h b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.h
index a543a5242e34..f7e0e0c7f8d8 100644
--- a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.h
+++ b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.h
@@ -18,9 +18,4 @@
18 18
19#include <asm/ppcboot.h> 19#include <asm/ppcboot.h>
20 20
21/* Base Addresses for the PCI bus
22 */
23#define MPC7448_HPC2_PCI_MEM_OFFSET (0x00000000)
24#define MPC7448_HPC2_ISA_IO_BASE (0x00000000)
25#define MPC7448_HPC2_ISA_MEM_BASE (0x00000000)
26#endif /* __PPC_PLATFORMS_MPC7448_HPC2_H */ 21#endif /* __PPC_PLATFORMS_MPC7448_HPC2_H */
diff --git a/arch/powerpc/platforms/iseries/call_hpt.h b/arch/powerpc/platforms/iseries/call_hpt.h
index a843b0f87b72..8d95fe4b554e 100644
--- a/arch/powerpc/platforms/iseries/call_hpt.h
+++ b/arch/powerpc/platforms/iseries/call_hpt.h
@@ -76,24 +76,25 @@ static inline u64 HvCallHpt_invalidateSetSwBitsGet(u32 hpteIndex, u8 bitson,
76 return compressedStatus; 76 return compressedStatus;
77} 77}
78 78
79static inline u64 HvCallHpt_findValid(hpte_t *hpte, u64 vpn) 79static inline u64 HvCallHpt_findValid(struct hash_pte *hpte, u64 vpn)
80{ 80{
81 return HvCall3Ret16(HvCallHptFindValid, hpte, vpn, 0, 0); 81 return HvCall3Ret16(HvCallHptFindValid, hpte, vpn, 0, 0);
82} 82}
83 83
84static inline u64 HvCallHpt_findNextValid(hpte_t *hpte, u32 hpteIndex, 84static inline u64 HvCallHpt_findNextValid(struct hash_pte *hpte, u32 hpteIndex,
85 u8 bitson, u8 bitsoff) 85 u8 bitson, u8 bitsoff)
86{ 86{
87 return HvCall3Ret16(HvCallHptFindNextValid, hpte, hpteIndex, 87 return HvCall3Ret16(HvCallHptFindNextValid, hpte, hpteIndex,
88 bitson, bitsoff); 88 bitson, bitsoff);
89} 89}
90 90
91static inline void HvCallHpt_get(hpte_t *hpte, u32 hpteIndex) 91static inline void HvCallHpt_get(struct hash_pte *hpte, u32 hpteIndex)
92{ 92{
93 HvCall2Ret16(HvCallHptGet, hpte, hpteIndex, 0); 93 HvCall2Ret16(HvCallHptGet, hpte, hpteIndex, 0);
94} 94}
95 95
96static inline void HvCallHpt_addValidate(u32 hpteIndex, u32 hBit, hpte_t *hpte) 96static inline void HvCallHpt_addValidate(u32 hpteIndex, u32 hBit,
97 struct hash_pte *hpte)
97{ 98{
98 HvCall4(HvCallHptAddValidate, hpteIndex, hBit, hpte->v, hpte->r); 99 HvCall4(HvCallHptAddValidate, hpteIndex, hBit, hpte->v, hpte->r);
99} 100}
diff --git a/arch/powerpc/platforms/iseries/htab.c b/arch/powerpc/platforms/iseries/htab.c
index ed44dfceaa45..b4e2c7a038e1 100644
--- a/arch/powerpc/platforms/iseries/htab.c
+++ b/arch/powerpc/platforms/iseries/htab.c
@@ -44,7 +44,7 @@ long iSeries_hpte_insert(unsigned long hpte_group, unsigned long va,
44 unsigned long vflags, int psize) 44 unsigned long vflags, int psize)
45{ 45{
46 long slot; 46 long slot;
47 hpte_t lhpte; 47 struct hash_pte lhpte;
48 int secondary = 0; 48 int secondary = 0;
49 49
50 BUG_ON(psize != MMU_PAGE_4K); 50 BUG_ON(psize != MMU_PAGE_4K);
@@ -99,7 +99,7 @@ long iSeries_hpte_insert(unsigned long hpte_group, unsigned long va,
99 99
100static unsigned long iSeries_hpte_getword0(unsigned long slot) 100static unsigned long iSeries_hpte_getword0(unsigned long slot)
101{ 101{
102 hpte_t hpte; 102 struct hash_pte hpte;
103 103
104 HvCallHpt_get(&hpte, slot); 104 HvCallHpt_get(&hpte, slot);
105 return hpte.v; 105 return hpte.v;
@@ -144,7 +144,7 @@ static long iSeries_hpte_remove(unsigned long hpte_group)
144static long iSeries_hpte_updatepp(unsigned long slot, unsigned long newpp, 144static long iSeries_hpte_updatepp(unsigned long slot, unsigned long newpp,
145 unsigned long va, int psize, int local) 145 unsigned long va, int psize, int local)
146{ 146{
147 hpte_t hpte; 147 struct hash_pte hpte;
148 unsigned long want_v; 148 unsigned long want_v;
149 149
150 iSeries_hlock(slot); 150 iSeries_hlock(slot);
@@ -176,7 +176,7 @@ static long iSeries_hpte_updatepp(unsigned long slot, unsigned long newpp,
176 */ 176 */
177static long iSeries_hpte_find(unsigned long vpn) 177static long iSeries_hpte_find(unsigned long vpn)
178{ 178{
179 hpte_t hpte; 179 struct hash_pte hpte;
180 long slot; 180 long slot;
181 181
182 /* 182 /*
diff --git a/arch/powerpc/platforms/iseries/pci.c b/arch/powerpc/platforms/iseries/pci.c
index 9c974227155e..da87162000f0 100644
--- a/arch/powerpc/platforms/iseries/pci.c
+++ b/arch/powerpc/platforms/iseries/pci.c
@@ -742,6 +742,11 @@ void __init iSeries_pcibios_init(void)
742 /* Install IO hooks */ 742 /* Install IO hooks */
743 ppc_pci_io = iseries_pci_io; 743 ppc_pci_io = iseries_pci_io;
744 744
745 /* iSeries has no IO space in the common sense, it needs to set
746 * the IO base to 0
747 */
748 pci_io_base = 0;
749
745 if (root == NULL) { 750 if (root == NULL) {
746 printk(KERN_CRIT "iSeries_pcibios_init: can't find root " 751 printk(KERN_CRIT "iSeries_pcibios_init: can't find root "
747 "of device tree\n"); 752 "of device tree\n");
@@ -763,7 +768,7 @@ void __init iSeries_pcibios_init(void)
763 if (phb == NULL) 768 if (phb == NULL)
764 continue; 769 continue;
765 770
766 phb->pci_mem_offset = phb->local_number = bus; 771 phb->pci_mem_offset = bus;
767 phb->first_busno = bus; 772 phb->first_busno = bus;
768 phb->last_busno = bus; 773 phb->last_busno = bus;
769 phb->ops = &iSeries_pci_ops; 774 phb->ops = &iSeries_pci_ops;
diff --git a/arch/powerpc/platforms/iseries/setup.c b/arch/powerpc/platforms/iseries/setup.c
index 7f5dcee814d4..13a8b1908ded 100644
--- a/arch/powerpc/platforms/iseries/setup.c
+++ b/arch/powerpc/platforms/iseries/setup.c
@@ -79,8 +79,6 @@ extern void iSeries_pci_final_fixup(void);
79static void iSeries_pci_final_fixup(void) { } 79static void iSeries_pci_final_fixup(void) { }
80#endif 80#endif
81 81
82extern unsigned long iSeries_recal_tb;
83extern unsigned long iSeries_recal_titan;
84 82
85struct MemoryBlock { 83struct MemoryBlock {
86 unsigned long absStart; 84 unsigned long absStart;
@@ -292,8 +290,8 @@ static void __init iSeries_init_early(void)
292{ 290{
293 DBG(" -> iSeries_init_early()\n"); 291 DBG(" -> iSeries_init_early()\n");
294 292
295 iSeries_recal_tb = get_tb(); 293 /* Snapshot the timebase, for use in later recalibration */
296 iSeries_recal_titan = HvCallXm_loadTod(); 294 iSeries_time_init_early();
297 295
298 /* 296 /*
299 * Initialize the DMA/TCE management 297 * Initialize the DMA/TCE management
diff --git a/arch/powerpc/platforms/maple/pci.c b/arch/powerpc/platforms/maple/pci.c
index 7aaa5bbc9363..fceaae40fe70 100644
--- a/arch/powerpc/platforms/maple/pci.c
+++ b/arch/powerpc/platforms/maple/pci.c
@@ -444,7 +444,7 @@ static void __init setup_u3_ht(struct pci_controller* hose)
444 u3_ht = hose; 444 u3_ht = hose;
445} 445}
446 446
447static int __init add_bridge(struct device_node *dev) 447static int __init maple_add_bridge(struct device_node *dev)
448{ 448{
449 int len; 449 int len;
450 struct pci_controller *hose; 450 struct pci_controller *hose;
@@ -519,23 +519,6 @@ void __devinit maple_pci_irq_fixup(struct pci_dev *dev)
519 DBG(" <- maple_pci_irq_fixup\n"); 519 DBG(" <- maple_pci_irq_fixup\n");
520} 520}
521 521
522static void __init maple_fixup_phb_resources(void)
523{
524 struct pci_controller *hose, *tmp;
525
526 list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
527 unsigned long offset = (unsigned long)hose->io_base_virt - pci_io_base;
528
529 hose->io_resource.start += offset;
530 hose->io_resource.end += offset;
531
532 printk(KERN_INFO "PCI Host %d, io start: %llx; io end: %llx\n",
533 hose->global_number,
534 (unsigned long long)hose->io_resource.start,
535 (unsigned long long)hose->io_resource.end);
536 }
537}
538
539void __init maple_pci_init(void) 522void __init maple_pci_init(void)
540{ 523{
541 struct device_node *np, *root; 524 struct device_node *np, *root;
@@ -558,7 +541,7 @@ void __init maple_pci_init(void)
558 continue; 541 continue;
559 if ((of_device_is_compatible(np, "u4-pcie") || 542 if ((of_device_is_compatible(np, "u4-pcie") ||
560 of_device_is_compatible(np, "u3-agp")) && 543 of_device_is_compatible(np, "u3-agp")) &&
561 add_bridge(np) == 0) 544 maple_add_bridge(np) == 0)
562 of_node_get(np); 545 of_node_get(np);
563 546
564 if (of_device_is_compatible(np, "u3-ht")) { 547 if (of_device_is_compatible(np, "u3-ht")) {
@@ -570,27 +553,9 @@ void __init maple_pci_init(void)
570 553
571 /* Now setup the HyperTransport host if we found any 554 /* Now setup the HyperTransport host if we found any
572 */ 555 */
573 if (ht && add_bridge(ht) != 0) 556 if (ht && maple_add_bridge(ht) != 0)
574 of_node_put(ht); 557 of_node_put(ht);
575 558
576 /*
577 * We need to call pci_setup_phb_io for the HT bridge first
578 * so it gets the I/O port numbers starting at 0, and we
579 * need to call it for the AGP bridge after that so it gets
580 * small positive I/O port numbers.
581 */
582 if (u3_ht)
583 pci_setup_phb_io(u3_ht, 1);
584 if (u3_agp)
585 pci_setup_phb_io(u3_agp, 0);
586 if (u4_pcie)
587 pci_setup_phb_io(u4_pcie, 0);
588
589 /* Fixup the IO resources on our host bridges as the common code
590 * does it only for childs of the host bridges
591 */
592 maple_fixup_phb_resources();
593
594 /* Setup the linkage between OF nodes and PHBs */ 559 /* Setup the linkage between OF nodes and PHBs */
595 pci_devs_phb_init(); 560 pci_devs_phb_init();
596 561
diff --git a/arch/powerpc/platforms/pasemi/Kconfig b/arch/powerpc/platforms/pasemi/Kconfig
index 7c5076e38ea1..95cd90fd81c7 100644
--- a/arch/powerpc/platforms/pasemi/Kconfig
+++ b/arch/powerpc/platforms/pasemi/Kconfig
@@ -25,4 +25,13 @@ config PPC_PASEMI_MDIO
25 help 25 help
26 Driver for MDIO via GPIO on PWRficient platforms 26 Driver for MDIO via GPIO on PWRficient platforms
27 27
28config ELECTRA_IDE
29 tristate "Electra IDE driver"
30 default y
31 depends on PPC_PASEMI && ATA
32 select PATA_PLATFORM
33 help
34 This includes driver support for the Electra on-board IDE
35 interface.
36
28endmenu 37endmenu
diff --git a/arch/powerpc/platforms/pasemi/Makefile b/arch/powerpc/platforms/pasemi/Makefile
index 2cd2a4f26a48..f47fcac7e581 100644
--- a/arch/powerpc/platforms/pasemi/Makefile
+++ b/arch/powerpc/platforms/pasemi/Makefile
@@ -1,3 +1,4 @@
1obj-y += setup.o pci.o time.o idle.o powersave.o iommu.o 1obj-y += setup.o pci.o time.o idle.o powersave.o iommu.o
2obj-$(CONFIG_PPC_PASEMI_MDIO) += gpio_mdio.o 2obj-$(CONFIG_PPC_PASEMI_MDIO) += gpio_mdio.o
3obj-$(CONFIG_ELECTRA_IDE) += electra_ide.o
3obj-$(CONFIG_PPC_PASEMI_CPUFREQ) += cpufreq.o 4obj-$(CONFIG_PPC_PASEMI_CPUFREQ) += cpufreq.o
diff --git a/arch/powerpc/platforms/pasemi/electra_ide.c b/arch/powerpc/platforms/pasemi/electra_ide.c
new file mode 100644
index 000000000000..12fb0c949263
--- /dev/null
+++ b/arch/powerpc/platforms/pasemi/electra_ide.c
@@ -0,0 +1,96 @@
1/*
2 * Copyright (C) 2007 PA Semi, Inc
3 *
4 * Maintained by: Olof Johansson <olof@lixom.net>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20#include <linux/platform_device.h>
21
22#include <asm/prom.h>
23#include <asm/system.h>
24
25/* The electra IDE interface is incredibly simple: Just a device on the localbus
26 * with interrupts hooked up to one of the GPIOs. The device tree contains the
27 * address window and interrupt mappings already, and the pata_platform driver handles
28 * the rest. We just need to hook the two up.
29 */
30
31#define MAX_IFS 4 /* really, we have only one */
32
33static struct platform_device *pdevs[MAX_IFS];
34
35static int __devinit electra_ide_init(void)
36{
37 struct device_node *np;
38 struct resource r[3];
39 int ret = 0;
40 int i;
41
42 np = of_find_compatible_node(NULL, "ide", "electra-ide");
43 i = 0;
44
45 while (np && i < MAX_IFS) {
46 memset(r, 0, sizeof(r));
47
48 /* pata_platform wants two address ranges: one for the base registers,
49 * another for the control (altstatus). It's located at offset 0x3f6 in
50 * the window, but the device tree only has one large register window
51 * that covers both ranges. So we need to split it up by hand here:
52 */
53
54 ret = of_address_to_resource(np, 0, &r[0]);
55 if (ret)
56 goto out;
57 ret = of_address_to_resource(np, 0, &r[1]);
58 if (ret)
59 goto out;
60
61 r[1].start += 0x3f6;
62 r[0].end = r[1].start-1;
63
64 r[2].start = irq_of_parse_and_map(np, 0);
65 r[2].end = irq_of_parse_and_map(np, 0);
66 r[2].flags = IORESOURCE_IRQ;
67
68 pr_debug("registering platform device at 0x%lx/0x%lx, irq is %ld\n",
69 r[0].start, r[1].start, r[2].start);
70 pdevs[i] = platform_device_register_simple("pata_platform", i, r, 3);
71 if (IS_ERR(pdevs[i])) {
72 ret = PTR_ERR(pdevs[i]);
73 pdevs[i] = NULL;
74 goto out;
75 }
76 np = of_find_compatible_node(np, "ide", "electra-ide");
77 }
78out:
79 return ret;
80}
81module_init(electra_ide_init);
82
83static void __devexit electra_ide_exit(void)
84{
85 int i;
86
87 for (i = 0; i < MAX_IFS; i++)
88 if (pdevs[i])
89 platform_device_unregister(pdevs[i]);
90}
91module_exit(electra_ide_exit);
92
93
94MODULE_LICENSE("GPL");
95MODULE_AUTHOR ("Olof Johansson <olof@lixom.net>");
96MODULE_DESCRIPTION("PA Semi Electra IDE driver");
diff --git a/arch/powerpc/platforms/pasemi/pci.c b/arch/powerpc/platforms/pasemi/pci.c
index bbc6dfcfaa91..ab1f5f62bcd8 100644
--- a/arch/powerpc/platforms/pasemi/pci.c
+++ b/arch/powerpc/platforms/pasemi/pci.c
@@ -132,7 +132,7 @@ static void __init setup_pa_pxp(struct pci_controller *hose)
132 hose->cfg_data = ioremap(0xe0000000, 0x10000000); 132 hose->cfg_data = ioremap(0xe0000000, 0x10000000);
133} 133}
134 134
135static int __init add_bridge(struct device_node *dev) 135static int __init pas_add_bridge(struct device_node *dev)
136{ 136{
137 struct pci_controller *hose; 137 struct pci_controller *hose;
138 138
@@ -150,29 +150,11 @@ static int __init add_bridge(struct device_node *dev)
150 printk(KERN_INFO "Found PA-PXP PCI host bridge.\n"); 150 printk(KERN_INFO "Found PA-PXP PCI host bridge.\n");
151 151
152 /* Interpret the "ranges" property */ 152 /* Interpret the "ranges" property */
153 /* This also maps the I/O region and sets isa_io/mem_base */
154 pci_process_bridge_OF_ranges(hose, dev, 1); 153 pci_process_bridge_OF_ranges(hose, dev, 1);
155 pci_setup_phb_io(hose, 1);
156 154
157 return 0; 155 return 0;
158} 156}
159 157
160
161static void __init pas_fixup_phb_resources(void)
162{
163 struct pci_controller *hose, *tmp;
164
165 list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
166 unsigned long offset = (unsigned long)hose->io_base_virt - pci_io_base;
167 hose->io_resource.start += offset;
168 hose->io_resource.end += offset;
169 printk(KERN_INFO "PCI Host %d, io start: %lx; io end: %lx\n",
170 hose->global_number,
171 hose->io_resource.start, hose->io_resource.end);
172 }
173}
174
175
176void __init pas_pci_init(void) 158void __init pas_pci_init(void)
177{ 159{
178 struct device_node *np, *root; 160 struct device_node *np, *root;
@@ -185,13 +167,11 @@ void __init pas_pci_init(void)
185 } 167 }
186 168
187 for (np = NULL; (np = of_get_next_child(root, np)) != NULL;) 169 for (np = NULL; (np = of_get_next_child(root, np)) != NULL;)
188 if (np->name && !strcmp(np->name, "pxp") && !add_bridge(np)) 170 if (np->name && !strcmp(np->name, "pxp") && !pas_add_bridge(np))
189 of_node_get(np); 171 of_node_get(np);
190 172
191 of_node_put(root); 173 of_node_put(root);
192 174
193 pas_fixup_phb_resources();
194
195 /* Setup the linkage between OF nodes and PHBs */ 175 /* Setup the linkage between OF nodes and PHBs */
196 pci_devs_phb_init(); 176 pci_devs_phb_init();
197 177
diff --git a/arch/powerpc/platforms/pasemi/setup.c b/arch/powerpc/platforms/pasemi/setup.c
index c5a3f61f8d85..ffe6528048b5 100644
--- a/arch/powerpc/platforms/pasemi/setup.c
+++ b/arch/powerpc/platforms/pasemi/setup.c
@@ -239,7 +239,7 @@ static int __init pas_probe(void)
239 return 1; 239 return 1;
240} 240}
241 241
242define_machine(pas) { 242define_machine(pasemi) {
243 .name = "PA Semi PA6T-1682M", 243 .name = "PA Semi PA6T-1682M",
244 .probe = pas_probe, 244 .probe = pas_probe,
245 .setup_arch = pas_setup_arch, 245 .setup_arch = pas_setup_arch,
diff --git a/arch/powerpc/platforms/powermac/Kconfig b/arch/powerpc/platforms/powermac/Kconfig
index 5b7afe50039a..055990ca8ce6 100644
--- a/arch/powerpc/platforms/powermac/Kconfig
+++ b/arch/powerpc/platforms/powermac/Kconfig
@@ -2,6 +2,7 @@ config PPC_PMAC
2 bool "Apple PowerMac based machines" 2 bool "Apple PowerMac based machines"
3 depends on PPC_MULTIPLATFORM 3 depends on PPC_MULTIPLATFORM
4 select MPIC 4 select MPIC
5 select PCI
5 select PPC_INDIRECT_PCI if PPC32 6 select PPC_INDIRECT_PCI if PPC32
6 select PPC_MPC106 if PPC32 7 select PPC_MPC106 if PPC32
7 select PPC_NATIVE 8 select PPC_NATIVE
diff --git a/arch/powerpc/platforms/powermac/low_i2c.c b/arch/powerpc/platforms/powermac/low_i2c.c
index 3f507ab9c5e5..efdf5eb81ecc 100644
--- a/arch/powerpc/platforms/powermac/low_i2c.c
+++ b/arch/powerpc/platforms/powermac/low_i2c.c
@@ -42,6 +42,7 @@
42#include <linux/interrupt.h> 42#include <linux/interrupt.h>
43#include <linux/completion.h> 43#include <linux/completion.h>
44#include <linux/timer.h> 44#include <linux/timer.h>
45#include <linux/mutex.h>
45#include <asm/keylargo.h> 46#include <asm/keylargo.h>
46#include <asm/uninorth.h> 47#include <asm/uninorth.h>
47#include <asm/io.h> 48#include <asm/io.h>
@@ -84,7 +85,7 @@ struct pmac_i2c_bus
84 void *hostdata; 85 void *hostdata;
85 int channel; /* some hosts have multiple */ 86 int channel; /* some hosts have multiple */
86 int mode; /* current mode */ 87 int mode; /* current mode */
87 struct semaphore sem; 88 struct mutex mutex;
88 int opened; 89 int opened;
89 int polled; /* open mode */ 90 int polled; /* open mode */
90 struct platform_device *platform_dev; 91 struct platform_device *platform_dev;
@@ -104,7 +105,7 @@ static LIST_HEAD(pmac_i2c_busses);
104 105
105struct pmac_i2c_host_kw 106struct pmac_i2c_host_kw
106{ 107{
107 struct semaphore mutex; /* Access mutex for use by 108 struct mutex mutex; /* Access mutex for use by
108 * i2c-keywest */ 109 * i2c-keywest */
109 void __iomem *base; /* register base address */ 110 void __iomem *base; /* register base address */
110 int bsteps; /* register stepping */ 111 int bsteps; /* register stepping */
@@ -375,14 +376,14 @@ static void kw_i2c_timeout(unsigned long data)
375static int kw_i2c_open(struct pmac_i2c_bus *bus) 376static int kw_i2c_open(struct pmac_i2c_bus *bus)
376{ 377{
377 struct pmac_i2c_host_kw *host = bus->hostdata; 378 struct pmac_i2c_host_kw *host = bus->hostdata;
378 down(&host->mutex); 379 mutex_lock(&host->mutex);
379 return 0; 380 return 0;
380} 381}
381 382
382static void kw_i2c_close(struct pmac_i2c_bus *bus) 383static void kw_i2c_close(struct pmac_i2c_bus *bus)
383{ 384{
384 struct pmac_i2c_host_kw *host = bus->hostdata; 385 struct pmac_i2c_host_kw *host = bus->hostdata;
385 up(&host->mutex); 386 mutex_unlock(&host->mutex);
386} 387}
387 388
388static int kw_i2c_xfer(struct pmac_i2c_bus *bus, u8 addrdir, int subsize, 389static int kw_i2c_xfer(struct pmac_i2c_bus *bus, u8 addrdir, int subsize,
@@ -498,7 +499,7 @@ static struct pmac_i2c_host_kw *__init kw_i2c_host_init(struct device_node *np)
498 kfree(host); 499 kfree(host);
499 return NULL; 500 return NULL;
500 } 501 }
501 init_MUTEX(&host->mutex); 502 mutex_init(&host->mutex);
502 init_completion(&host->complete); 503 init_completion(&host->complete);
503 spin_lock_init(&host->lock); 504 spin_lock_init(&host->lock);
504 init_timer(&host->timeout_timer); 505 init_timer(&host->timeout_timer);
@@ -571,7 +572,7 @@ static void __init kw_i2c_add(struct pmac_i2c_host_kw *host,
571 bus->open = kw_i2c_open; 572 bus->open = kw_i2c_open;
572 bus->close = kw_i2c_close; 573 bus->close = kw_i2c_close;
573 bus->xfer = kw_i2c_xfer; 574 bus->xfer = kw_i2c_xfer;
574 init_MUTEX(&bus->sem); 575 mutex_init(&bus->mutex);
575 if (controller == busnode) 576 if (controller == busnode)
576 bus->flags = pmac_i2c_multibus; 577 bus->flags = pmac_i2c_multibus;
577 list_add(&bus->link, &pmac_i2c_busses); 578 list_add(&bus->link, &pmac_i2c_busses);
@@ -798,7 +799,7 @@ static void __init pmu_i2c_probe(void)
798 bus->mode = pmac_i2c_mode_std; 799 bus->mode = pmac_i2c_mode_std;
799 bus->hostdata = bus + 1; 800 bus->hostdata = bus + 1;
800 bus->xfer = pmu_i2c_xfer; 801 bus->xfer = pmu_i2c_xfer;
801 init_MUTEX(&bus->sem); 802 mutex_init(&bus->mutex);
802 bus->flags = pmac_i2c_multibus; 803 bus->flags = pmac_i2c_multibus;
803 list_add(&bus->link, &pmac_i2c_busses); 804 list_add(&bus->link, &pmac_i2c_busses);
804 805
@@ -921,7 +922,7 @@ static void __init smu_i2c_probe(void)
921 bus->mode = pmac_i2c_mode_std; 922 bus->mode = pmac_i2c_mode_std;
922 bus->hostdata = bus + 1; 923 bus->hostdata = bus + 1;
923 bus->xfer = smu_i2c_xfer; 924 bus->xfer = smu_i2c_xfer;
924 init_MUTEX(&bus->sem); 925 mutex_init(&bus->mutex);
925 bus->flags = 0; 926 bus->flags = 0;
926 list_add(&bus->link, &pmac_i2c_busses); 927 list_add(&bus->link, &pmac_i2c_busses);
927 928
@@ -1093,13 +1094,13 @@ int pmac_i2c_open(struct pmac_i2c_bus *bus, int polled)
1093{ 1094{
1094 int rc; 1095 int rc;
1095 1096
1096 down(&bus->sem); 1097 mutex_lock(&bus->mutex);
1097 bus->polled = polled || pmac_i2c_force_poll; 1098 bus->polled = polled || pmac_i2c_force_poll;
1098 bus->opened = 1; 1099 bus->opened = 1;
1099 bus->mode = pmac_i2c_mode_std; 1100 bus->mode = pmac_i2c_mode_std;
1100 if (bus->open && (rc = bus->open(bus)) != 0) { 1101 if (bus->open && (rc = bus->open(bus)) != 0) {
1101 bus->opened = 0; 1102 bus->opened = 0;
1102 up(&bus->sem); 1103 mutex_unlock(&bus->mutex);
1103 return rc; 1104 return rc;
1104 } 1105 }
1105 return 0; 1106 return 0;
@@ -1112,7 +1113,7 @@ void pmac_i2c_close(struct pmac_i2c_bus *bus)
1112 if (bus->close) 1113 if (bus->close)
1113 bus->close(bus); 1114 bus->close(bus);
1114 bus->opened = 0; 1115 bus->opened = 0;
1115 up(&bus->sem); 1116 mutex_unlock(&bus->mutex);
1116} 1117}
1117EXPORT_SYMBOL_GPL(pmac_i2c_close); 1118EXPORT_SYMBOL_GPL(pmac_i2c_close);
1118 1119
diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c
index c4af9e21ac93..92586db19754 100644
--- a/arch/powerpc/platforms/powermac/pci.c
+++ b/arch/powerpc/platforms/powermac/pci.c
@@ -35,8 +35,6 @@
35#define DBG(x...) 35#define DBG(x...)
36#endif 36#endif
37 37
38static int add_bridge(struct device_node *dev);
39
40/* XXX Could be per-controller, but I don't think we risk anything by 38/* XXX Could be per-controller, but I don't think we risk anything by
41 * assuming we won't have both UniNorth and Bandit */ 39 * assuming we won't have both UniNorth and Bandit */
42static int has_uninorth; 40static int has_uninorth;
@@ -897,7 +895,7 @@ static void __init setup_u3_ht(struct pci_controller* hose)
897 * "pci" (a MPC106) and no bandit or chaos bridges, and contrariwise, 895 * "pci" (a MPC106) and no bandit or chaos bridges, and contrariwise,
898 * if we have one or more bandit or chaos bridges, we don't have a MPC106. 896 * if we have one or more bandit or chaos bridges, we don't have a MPC106.
899 */ 897 */
900static int __init add_bridge(struct device_node *dev) 898static int __init pmac_add_bridge(struct device_node *dev)
901{ 899{
902 int len; 900 int len;
903 struct pci_controller *hose; 901 struct pci_controller *hose;
@@ -918,15 +916,9 @@ static int __init add_bridge(struct device_node *dev)
918 " bus 0\n", dev->full_name); 916 " bus 0\n", dev->full_name);
919 } 917 }
920 918
921 /* XXX Different prototypes, to be merged */
922#ifdef CONFIG_PPC64
923 hose = pcibios_alloc_controller(dev); 919 hose = pcibios_alloc_controller(dev);
924#else
925 hose = pcibios_alloc_controller();
926#endif
927 if (!hose) 920 if (!hose)
928 return -ENOMEM; 921 return -ENOMEM;
929 hose->arch_data = dev;
930 hose->first_busno = bus_range ? bus_range[0] : 0; 922 hose->first_busno = bus_range ? bus_range[0] : 0;
931 hose->last_busno = bus_range ? bus_range[1] : 0xff; 923 hose->last_busno = bus_range ? bus_range[1] : 0xff;
932 924
@@ -1006,19 +998,6 @@ void __devinit pmac_pci_irq_fixup(struct pci_dev *dev)
1006#endif /* CONFIG_PPC32 */ 998#endif /* CONFIG_PPC32 */
1007} 999}
1008 1000
1009#ifdef CONFIG_PPC64
1010static void __init pmac_fixup_phb_resources(void)
1011{
1012 struct pci_controller *hose, *tmp;
1013
1014 list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
1015 printk(KERN_INFO "PCI Host %d, io start: %lx; io end: %lx\n",
1016 hose->global_number,
1017 hose->io_resource.start, hose->io_resource.end);
1018 }
1019}
1020#endif
1021
1022void __init pmac_pci_init(void) 1001void __init pmac_pci_init(void)
1023{ 1002{
1024 struct device_node *np, *root; 1003 struct device_node *np, *root;
@@ -1036,7 +1015,7 @@ void __init pmac_pci_init(void)
1036 if (strcmp(np->name, "bandit") == 0 1015 if (strcmp(np->name, "bandit") == 0
1037 || strcmp(np->name, "chaos") == 0 1016 || strcmp(np->name, "chaos") == 0
1038 || strcmp(np->name, "pci") == 0) { 1017 || strcmp(np->name, "pci") == 0) {
1039 if (add_bridge(np) == 0) 1018 if (pmac_add_bridge(np) == 0)
1040 of_node_get(np); 1019 of_node_get(np);
1041 } 1020 }
1042 if (strcmp(np->name, "ht") == 0) { 1021 if (strcmp(np->name, "ht") == 0) {
@@ -1050,28 +1029,9 @@ void __init pmac_pci_init(void)
1050 /* Probe HT last as it relies on the agp resources to be already 1029 /* Probe HT last as it relies on the agp resources to be already
1051 * setup 1030 * setup
1052 */ 1031 */
1053 if (ht && add_bridge(ht) != 0) 1032 if (ht && pmac_add_bridge(ht) != 0)
1054 of_node_put(ht); 1033 of_node_put(ht);
1055 1034
1056 /*
1057 * We need to call pci_setup_phb_io for the HT bridge first
1058 * so it gets the I/O port numbers starting at 0, and we
1059 * need to call it for the AGP bridge after that so it gets
1060 * small positive I/O port numbers.
1061 */
1062 if (u3_ht)
1063 pci_setup_phb_io(u3_ht, 1);
1064 if (u3_agp)
1065 pci_setup_phb_io(u3_agp, 0);
1066 if (u4_pcie)
1067 pci_setup_phb_io(u4_pcie, 0);
1068
1069 /*
1070 * On ppc64, fixup the IO resources on our host bridges as
1071 * the common code does it only for children of the host bridges
1072 */
1073 pmac_fixup_phb_resources();
1074
1075 /* Setup the linkage between OF nodes and PHBs */ 1035 /* Setup the linkage between OF nodes and PHBs */
1076 pci_devs_phb_init(); 1036 pci_devs_phb_init();
1077 1037
diff --git a/arch/powerpc/platforms/ps3/Kconfig b/arch/powerpc/platforms/ps3/Kconfig
index 40f0008af4d1..a05079b07696 100644
--- a/arch/powerpc/platforms/ps3/Kconfig
+++ b/arch/powerpc/platforms/ps3/Kconfig
@@ -7,6 +7,7 @@ config PPC_PS3
7 select USB_OHCI_BIG_ENDIAN_MMIO 7 select USB_OHCI_BIG_ENDIAN_MMIO
8 select USB_ARCH_HAS_EHCI 8 select USB_ARCH_HAS_EHCI
9 select USB_EHCI_BIG_ENDIAN_MMIO 9 select USB_EHCI_BIG_ENDIAN_MMIO
10 select MEMORY_HOTPLUG
10 help 11 help
11 This option enables support for the Sony PS3 game console 12 This option enables support for the Sony PS3 game console
12 and other platforms using the PS3 hypervisor. 13 and other platforms using the PS3 hypervisor.
@@ -73,18 +74,12 @@ config PS3_USE_LPAR_ADDR
73 74
74config PS3_VUART 75config PS3_VUART
75 depends on PPC_PS3 76 depends on PPC_PS3
76 bool "PS3 Virtual UART support" if PS3_ADVANCED 77 tristate
77 default y
78 help
79 Include support for the PS3 Virtual UART.
80
81 This support is required for several system services
82 including the System Manager and AV Settings. In
83 general, all users will say Y.
84 78
85config PS3_PS3AV 79config PS3_PS3AV
80 depends on PPC_PS3
86 tristate "PS3 AV settings driver" if PS3_ADVANCED 81 tristate "PS3 AV settings driver" if PS3_ADVANCED
87 depends on PS3_VUART 82 select PS3_VUART
88 default y 83 default y
89 help 84 help
90 Include support for the PS3 AV Settings driver. 85 Include support for the PS3 AV Settings driver.
@@ -93,13 +88,18 @@ config PS3_PS3AV
93 general, all users will say Y or M. 88 general, all users will say Y or M.
94 89
95config PS3_SYS_MANAGER 90config PS3_SYS_MANAGER
96 bool "PS3 System Manager driver" if PS3_ADVANCED 91 depends on PPC_PS3
97 depends on PS3_VUART 92 tristate "PS3 System Manager driver" if PS3_ADVANCED
98 default y 93 select PS3_VUART
94 default m
99 help 95 help
100 Include support for the PS3 System Manager. 96 Include support for the PS3 System Manager.
101 97
102 This support is required for system control. In 98 This support is required for system control. In
103 general, all users will say Y. 99 general, all users will say Y or M.
100
101config PS3_STORAGE
102 depends on PPC_PS3
103 tristate
104 104
105endmenu 105endmenu
diff --git a/arch/powerpc/platforms/ps3/Makefile b/arch/powerpc/platforms/ps3/Makefile
index a0048fcf0866..ac1bdf844eca 100644
--- a/arch/powerpc/platforms/ps3/Makefile
+++ b/arch/powerpc/platforms/ps3/Makefile
@@ -4,3 +4,4 @@ obj-y += system-bus.o
4 4
5obj-$(CONFIG_SMP) += smp.o 5obj-$(CONFIG_SMP) += smp.o
6obj-$(CONFIG_SPU_BASE) += spu.o 6obj-$(CONFIG_SPU_BASE) += spu.o
7obj-y += device-init.o
diff --git a/arch/powerpc/platforms/ps3/device-init.c b/arch/powerpc/platforms/ps3/device-init.c
new file mode 100644
index 000000000000..825ebb2cbc2a
--- /dev/null
+++ b/arch/powerpc/platforms/ps3/device-init.c
@@ -0,0 +1,785 @@
1/*
2 * PS3 device registration routines.
3 *
4 * Copyright (C) 2007 Sony Computer Entertainment Inc.
5 * Copyright 2007 Sony Corp.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include <linux/delay.h>
22#include <linux/freezer.h>
23#include <linux/kernel.h>
24#include <linux/kthread.h>
25#include <linux/init.h>
26
27#include <asm/firmware.h>
28#include <asm/lv1call.h>
29#include <asm/ps3stor.h>
30
31#include "platform.h"
32
33/**
34 * ps3_setup_gelic_device - Setup and register a gelic device instance.
35 *
36 * Allocates memory for a struct ps3_system_bus_device instance, initialises the
37 * structure members, and registers the device instance with the system bus.
38 */
39
40static int __init ps3_setup_gelic_device(
41 const struct ps3_repository_device *repo)
42{
43 int result;
44 struct layout {
45 struct ps3_system_bus_device dev;
46 struct ps3_dma_region d_region;
47 } *p;
48
49 pr_debug(" -> %s:%d\n", __func__, __LINE__);
50
51 BUG_ON(repo->bus_type != PS3_BUS_TYPE_SB);
52 BUG_ON(repo->dev_type != PS3_DEV_TYPE_SB_GELIC);
53
54 p = kzalloc(sizeof(struct layout), GFP_KERNEL);
55
56 if (!p) {
57 result = -ENOMEM;
58 goto fail_malloc;
59 }
60
61 p->dev.match_id = PS3_MATCH_ID_GELIC;
62 p->dev.dev_type = PS3_DEVICE_TYPE_SB;
63 p->dev.bus_id = repo->bus_id;
64 p->dev.dev_id = repo->dev_id;
65 p->dev.d_region = &p->d_region;
66
67 result = ps3_repository_find_interrupt(repo,
68 PS3_INTERRUPT_TYPE_EVENT_PORT, &p->dev.interrupt_id);
69
70 if (result) {
71 pr_debug("%s:%d ps3_repository_find_interrupt failed\n",
72 __func__, __LINE__);
73 goto fail_find_interrupt;
74 }
75
76 BUG_ON(p->dev.interrupt_id != 0);
77
78 result = ps3_dma_region_init(&p->dev, p->dev.d_region, PS3_DMA_64K,
79 PS3_DMA_OTHER, NULL, 0);
80
81 if (result) {
82 pr_debug("%s:%d ps3_dma_region_init failed\n",
83 __func__, __LINE__);
84 goto fail_dma_init;
85 }
86
87 result = ps3_system_bus_device_register(&p->dev);
88
89 if (result) {
90 pr_debug("%s:%d ps3_system_bus_device_register failed\n",
91 __func__, __LINE__);
92 goto fail_device_register;
93 }
94
95 pr_debug(" <- %s:%d\n", __func__, __LINE__);
96 return result;
97
98fail_device_register:
99fail_dma_init:
100fail_find_interrupt:
101 kfree(p);
102fail_malloc:
103 pr_debug(" <- %s:%d: fail.\n", __func__, __LINE__);
104 return result;
105}
106
107static int __init_refok ps3_setup_uhc_device(
108 const struct ps3_repository_device *repo, enum ps3_match_id match_id,
109 enum ps3_interrupt_type interrupt_type, enum ps3_reg_type reg_type)
110{
111 int result;
112 struct layout {
113 struct ps3_system_bus_device dev;
114 struct ps3_dma_region d_region;
115 struct ps3_mmio_region m_region;
116 } *p;
117 u64 bus_addr;
118 u64 len;
119
120 pr_debug(" -> %s:%d\n", __func__, __LINE__);
121
122 BUG_ON(repo->bus_type != PS3_BUS_TYPE_SB);
123 BUG_ON(repo->dev_type != PS3_DEV_TYPE_SB_USB);
124
125 p = kzalloc(sizeof(struct layout), GFP_KERNEL);
126
127 if (!p) {
128 result = -ENOMEM;
129 goto fail_malloc;
130 }
131
132 p->dev.match_id = match_id;
133 p->dev.dev_type = PS3_DEVICE_TYPE_SB;
134 p->dev.bus_id = repo->bus_id;
135 p->dev.dev_id = repo->dev_id;
136 p->dev.d_region = &p->d_region;
137 p->dev.m_region = &p->m_region;
138
139 result = ps3_repository_find_interrupt(repo,
140 interrupt_type, &p->dev.interrupt_id);
141
142 if (result) {
143 pr_debug("%s:%d ps3_repository_find_interrupt failed\n",
144 __func__, __LINE__);
145 goto fail_find_interrupt;
146 }
147
148 result = ps3_repository_find_reg(repo, reg_type,
149 &bus_addr, &len);
150
151 if (result) {
152 pr_debug("%s:%d ps3_repository_find_reg failed\n",
153 __func__, __LINE__);
154 goto fail_find_reg;
155 }
156
157 result = ps3_dma_region_init(&p->dev, p->dev.d_region, PS3_DMA_64K,
158 PS3_DMA_INTERNAL, NULL, 0);
159
160 if (result) {
161 pr_debug("%s:%d ps3_dma_region_init failed\n",
162 __func__, __LINE__);
163 goto fail_dma_init;
164 }
165
166 result = ps3_mmio_region_init(&p->dev, p->dev.m_region, bus_addr, len,
167 PS3_MMIO_4K);
168
169 if (result) {
170 pr_debug("%s:%d ps3_mmio_region_init failed\n",
171 __func__, __LINE__);
172 goto fail_mmio_init;
173 }
174
175 result = ps3_system_bus_device_register(&p->dev);
176
177 if (result) {
178 pr_debug("%s:%d ps3_system_bus_device_register failed\n",
179 __func__, __LINE__);
180 goto fail_device_register;
181 }
182
183 pr_debug(" <- %s:%d\n", __func__, __LINE__);
184 return result;
185
186fail_device_register:
187fail_mmio_init:
188fail_dma_init:
189fail_find_reg:
190fail_find_interrupt:
191 kfree(p);
192fail_malloc:
193 pr_debug(" <- %s:%d: fail.\n", __func__, __LINE__);
194 return result;
195}
196
197static int __init ps3_setup_ehci_device(
198 const struct ps3_repository_device *repo)
199{
200 return ps3_setup_uhc_device(repo, PS3_MATCH_ID_EHCI,
201 PS3_INTERRUPT_TYPE_SB_EHCI, PS3_REG_TYPE_SB_EHCI);
202}
203
204static int __init ps3_setup_ohci_device(
205 const struct ps3_repository_device *repo)
206{
207 return ps3_setup_uhc_device(repo, PS3_MATCH_ID_OHCI,
208 PS3_INTERRUPT_TYPE_SB_OHCI, PS3_REG_TYPE_SB_OHCI);
209}
210
211static int __init ps3_setup_vuart_device(enum ps3_match_id match_id,
212 unsigned int port_number)
213{
214 int result;
215 struct layout {
216 struct ps3_system_bus_device dev;
217 } *p;
218
219 pr_debug(" -> %s:%d: match_id %u, port %u\n", __func__, __LINE__,
220 match_id, port_number);
221
222 p = kzalloc(sizeof(struct layout), GFP_KERNEL);
223
224 if (!p)
225 return -ENOMEM;
226
227 p->dev.match_id = match_id;
228 p->dev.dev_type = PS3_DEVICE_TYPE_VUART;
229 p->dev.port_number = port_number;
230
231 result = ps3_system_bus_device_register(&p->dev);
232
233 if (result)
234 pr_debug("%s:%d ps3_system_bus_device_register failed\n",
235 __func__, __LINE__);
236
237 pr_debug(" <- %s:%d\n", __func__, __LINE__);
238 return result;
239}
240
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 result;
277 const u64 notification_dev_id = (u64)-1LL;
278 const unsigned int timeout = HZ;
279 u64 lpar;
280 u64 tag;
281 struct {
282 u64 operation_code; /* must be zero */
283 u64 event_mask; /* 1 = device ready */
284 } *notify_cmd;
285 struct {
286 u64 event_type; /* notify_device_ready */
287 u64 bus_id;
288 u64 dev_id;
289 u64 dev_type;
290 u64 dev_port;
291 } *notify_event;
292 enum {
293 notify_device_ready = 1
294 };
295
296 pr_debug(" -> %s:%u: bus_id %u, dev_id %u, dev_type %u\n", __func__,
297 __LINE__, repo->bus_id, repo->dev_id, repo->dev_type);
298
299 notify_cmd = kzalloc(512, GFP_KERNEL);
300 notify_event = (void *)notify_cmd;
301 if (!notify_cmd)
302 return -ENOMEM;
303
304 lpar = ps3_mm_phys_to_lpar(__pa(notify_cmd));
305
306 result = lv1_open_device(repo->bus_id, notification_dev_id, 0);
307 if (result) {
308 printk(KERN_ERR "%s:%u: lv1_open_device %s\n", __func__,
309 __LINE__, ps3_result(result));
310 result = -ENODEV;
311 goto fail_free;
312 }
313
314 /* Setup and write the request for device notification. */
315
316 notify_cmd->operation_code = 0; /* must be zero */
317 notify_cmd->event_mask = 0x01; /* device ready */
318
319 result = lv1_storage_write(notification_dev_id, 0, 0, 1, 0, lpar,
320 &tag);
321 if (result) {
322 printk(KERN_ERR "%s:%u: write failed %s\n", __func__, __LINE__,
323 ps3_result(result));
324 result = -ENODEV;
325 goto fail_close;
326 }
327
328 /* Wait for the write completion */
329
330 result = ps3stor_wait_for_completion(notification_dev_id, tag,
331 timeout);
332 if (result) {
333 printk(KERN_ERR "%s:%u: write not completed %s\n", __func__,
334 __LINE__, ps3_result(result));
335 result = -ENODEV;
336 goto fail_close;
337 }
338
339 /* Loop here processing the requested notification events. */
340
341 result = -ENODEV;
342 while (1) {
343 memset(notify_event, 0, sizeof(*notify_event));
344
345 result = lv1_storage_read(notification_dev_id, 0, 0, 1, 0,
346 lpar, &tag);
347 if (result) {
348 printk(KERN_ERR "%s:%u: write failed %s\n", __func__,
349 __LINE__, ps3_result(result));
350 break;
351 }
352
353 result = ps3stor_wait_for_completion(notification_dev_id, tag,
354 timeout);
355 if (result) {
356 printk(KERN_ERR "%s:%u: read not completed %s\n",
357 __func__, __LINE__, ps3_result(result));
358 break;
359 }
360
361 if (notify_event->event_type != notify_device_ready ||
362 notify_event->bus_id != repo->bus_id) {
363 pr_debug("%s:%u: bad notify_event: event %lu, "
364 "dev_id %lu, dev_type %lu\n",
365 __func__, __LINE__, notify_event->event_type,
366 notify_event->dev_id, notify_event->dev_type);
367 break;
368 }
369
370 if (notify_event->dev_id == repo->dev_id &&
371 notify_event->dev_type == repo->dev_type) {
372 pr_debug("%s:%u: device ready: dev_id %u\n", __func__,
373 __LINE__, repo->dev_id);
374 result = 0;
375 break;
376 }
377
378 if (notify_event->dev_id == repo->dev_id &&
379 notify_event->dev_type == PS3_DEV_TYPE_NOACCESS) {
380 pr_debug("%s:%u: no access: dev_id %u\n", __func__,
381 __LINE__, repo->dev_id);
382 break;
383 }
384 }
385
386fail_close:
387 lv1_close_device(repo->bus_id, notification_dev_id);
388fail_free:
389 kfree(notify_cmd);
390 pr_debug(" <- %s:%u\n", __func__, __LINE__);
391 return result;
392}
393
394static int ps3_setup_storage_dev(const struct ps3_repository_device *repo,
395 enum ps3_match_id match_id)
396{
397 int result;
398 struct ps3_storage_device *p;
399 u64 port, blk_size, num_blocks;
400 unsigned int num_regions, i;
401
402 pr_debug(" -> %s:%u: match_id %u\n", __func__, __LINE__, match_id);
403
404 result = ps3_repository_read_stor_dev_info(repo->bus_index,
405 repo->dev_index, &port,
406 &blk_size, &num_blocks,
407 &num_regions);
408 if (result) {
409 printk(KERN_ERR "%s:%u: _read_stor_dev_info failed %d\n",
410 __func__, __LINE__, result);
411 return -ENODEV;
412 }
413
414 pr_debug("%s:%u: index %u:%u: port %lu blk_size %lu num_blocks %lu "
415 "num_regions %u\n", __func__, __LINE__, repo->bus_index,
416 repo->dev_index, port, blk_size, num_blocks, num_regions);
417
418 p = kzalloc(sizeof(struct ps3_storage_device) +
419 num_regions * sizeof(struct ps3_storage_region),
420 GFP_KERNEL);
421 if (!p) {
422 result = -ENOMEM;
423 goto fail_malloc;
424 }
425
426 p->sbd.match_id = match_id;
427 p->sbd.dev_type = PS3_DEVICE_TYPE_SB;
428 p->sbd.bus_id = repo->bus_id;
429 p->sbd.dev_id = repo->dev_id;
430 p->sbd.d_region = &p->dma_region;
431 p->blk_size = blk_size;
432 p->num_regions = num_regions;
433
434 result = ps3_repository_find_interrupt(repo,
435 PS3_INTERRUPT_TYPE_EVENT_PORT,
436 &p->sbd.interrupt_id);
437 if (result) {
438 printk(KERN_ERR "%s:%u: find_interrupt failed %d\n", __func__,
439 __LINE__, result);
440 result = -ENODEV;
441 goto fail_find_interrupt;
442 }
443
444 /* FIXME: Arrange to only do this on a 'cold' boot */
445
446 result = ps3_storage_wait_for_device(repo);
447 if (result) {
448 printk(KERN_ERR "%s:%u: storage_notification failed %d\n",
449 __func__, __LINE__, result);
450 result = -ENODEV;
451 goto fail_probe_notification;
452 }
453
454 for (i = 0; i < num_regions; i++) {
455 unsigned int id;
456 u64 start, size;
457
458 result = ps3_repository_read_stor_dev_region(repo->bus_index,
459 repo->dev_index,
460 i, &id, &start,
461 &size);
462 if (result) {
463 printk(KERN_ERR
464 "%s:%u: read_stor_dev_region failed %d\n",
465 __func__, __LINE__, result);
466 result = -ENODEV;
467 goto fail_read_region;
468 }
469 pr_debug("%s:%u: region %u: id %u start %lu size %lu\n",
470 __func__, __LINE__, i, id, start, size);
471
472 p->regions[i].id = id;
473 p->regions[i].start = start;
474 p->regions[i].size = size;
475 }
476
477 result = ps3_system_bus_device_register(&p->sbd);
478 if (result) {
479 pr_debug("%s:%u ps3_system_bus_device_register failed\n",
480 __func__, __LINE__);
481 goto fail_device_register;
482 }
483
484 pr_debug(" <- %s:%u\n", __func__, __LINE__);
485 return 0;
486
487fail_device_register:
488fail_read_region:
489fail_probe_notification:
490fail_find_interrupt:
491 kfree(p);
492fail_malloc:
493 pr_debug(" <- %s:%u: fail.\n", __func__, __LINE__);
494 return result;
495}
496
497static int __init ps3_register_vuart_devices(void)
498{
499 int result;
500 unsigned int port_number;
501
502 pr_debug(" -> %s:%d\n", __func__, __LINE__);
503
504 result = ps3_repository_read_vuart_av_port(&port_number);
505 if (result)
506 port_number = 0; /* av default */
507
508 result = ps3_setup_vuart_device(PS3_MATCH_ID_AV_SETTINGS, port_number);
509 WARN_ON(result);
510
511 result = ps3_repository_read_vuart_sysmgr_port(&port_number);
512 if (result)
513 port_number = 2; /* sysmgr default */
514
515 result = ps3_setup_vuart_device(PS3_MATCH_ID_SYSTEM_MANAGER,
516 port_number);
517 WARN_ON(result);
518
519 pr_debug(" <- %s:%d\n", __func__, __LINE__);
520 return result;
521}
522
523static int __init ps3_register_sound_devices(void)
524{
525 int result;
526 struct layout {
527 struct ps3_system_bus_device dev;
528 struct ps3_dma_region d_region;
529 struct ps3_mmio_region m_region;
530 } *p;
531
532 pr_debug(" -> %s:%d\n", __func__, __LINE__);
533
534 p = kzalloc(sizeof(*p), GFP_KERNEL);
535 if (!p)
536 return -ENOMEM;
537
538 p->dev.match_id = PS3_MATCH_ID_SOUND;
539 p->dev.dev_type = PS3_DEVICE_TYPE_IOC0;
540 p->dev.d_region = &p->d_region;
541 p->dev.m_region = &p->m_region;
542
543 result = ps3_system_bus_device_register(&p->dev);
544
545 if (result)
546 pr_debug("%s:%d ps3_system_bus_device_register failed\n",
547 __func__, __LINE__);
548
549 pr_debug(" <- %s:%d\n", __func__, __LINE__);
550 return result;
551}
552
553static int __init ps3_register_graphics_devices(void)
554{
555 int result;
556 struct layout {
557 struct ps3_system_bus_device dev;
558 } *p;
559
560 pr_debug(" -> %s:%d\n", __func__, __LINE__);
561
562 p = kzalloc(sizeof(struct layout), GFP_KERNEL);
563
564 if (!p)
565 return -ENOMEM;
566
567 p->dev.match_id = PS3_MATCH_ID_GRAPHICS;
568 p->dev.dev_type = PS3_DEVICE_TYPE_IOC0;
569
570 result = ps3_system_bus_device_register(&p->dev);
571
572 if (result)
573 pr_debug("%s:%d ps3_system_bus_device_register failed\n",
574 __func__, __LINE__);
575
576 pr_debug(" <- %s:%d\n", __func__, __LINE__);
577 return result;
578}
579
580/**
581 * ps3_register_repository_device - Register a device from the repositiory info.
582 *
583 */
584
585static int ps3_register_repository_device(
586 const struct ps3_repository_device *repo)
587{
588 int result;
589
590 switch (repo->dev_type) {
591 case PS3_DEV_TYPE_SB_GELIC:
592 result = ps3_setup_gelic_device(repo);
593 if (result) {
594 pr_debug("%s:%d ps3_setup_gelic_device failed\n",
595 __func__, __LINE__);
596 }
597 break;
598 case PS3_DEV_TYPE_SB_USB:
599
600 /* Each USB device has both an EHCI and an OHCI HC */
601
602 result = ps3_setup_ehci_device(repo);
603
604 if (result) {
605 pr_debug("%s:%d ps3_setup_ehci_device failed\n",
606 __func__, __LINE__);
607 }
608
609 result = ps3_setup_ohci_device(repo);
610
611 if (result) {
612 pr_debug("%s:%d ps3_setup_ohci_device failed\n",
613 __func__, __LINE__);
614 }
615 break;
616 case PS3_DEV_TYPE_STOR_DISK:
617 result = ps3_setup_storage_dev(repo, PS3_MATCH_ID_STOR_DISK);
618
619 /* Some devices are not accessable from the Other OS lpar. */
620 if (result == -ENODEV) {
621 result = 0;
622 pr_debug("%s:%u: not accessable\n", __func__,
623 __LINE__);
624 }
625
626 if (result)
627 pr_debug("%s:%u ps3_setup_storage_dev failed\n",
628 __func__, __LINE__);
629 break;
630
631 case PS3_DEV_TYPE_STOR_ROM:
632 result = ps3_setup_storage_dev(repo, PS3_MATCH_ID_STOR_ROM);
633 if (result)
634 pr_debug("%s:%u ps3_setup_storage_dev failed\n",
635 __func__, __LINE__);
636 break;
637
638 case PS3_DEV_TYPE_STOR_FLASH:
639 result = ps3_setup_storage_dev(repo, PS3_MATCH_ID_STOR_FLASH);
640 if (result)
641 pr_debug("%s:%u ps3_setup_storage_dev failed\n",
642 __func__, __LINE__);
643 break;
644
645 default:
646 result = 0;
647 pr_debug("%s:%u: unsupported dev_type %u\n", __func__, __LINE__,
648 repo->dev_type);
649 }
650
651 return result;
652}
653
654/**
655 * ps3_probe_thread - Background repository probing at system startup.
656 *
657 * This implementation only supports background probing on a single bus.
658 */
659
660static int ps3_probe_thread(void *data)
661{
662 struct ps3_repository_device *repo = data;
663 int result;
664 unsigned int ms = 250;
665
666 pr_debug(" -> %s:%u: kthread started\n", __func__, __LINE__);
667
668 do {
669 try_to_freeze();
670
671 pr_debug("%s:%u: probing...\n", __func__, __LINE__);
672
673 do {
674 result = ps3_repository_find_device(repo);
675
676 if (result == -ENODEV)
677 pr_debug("%s:%u: nothing new\n", __func__,
678 __LINE__);
679 else if (result)
680 pr_debug("%s:%u: find device error.\n",
681 __func__, __LINE__);
682 else {
683 pr_debug("%s:%u: found device\n", __func__,
684 __LINE__);
685 ps3_register_repository_device(repo);
686 ps3_repository_bump_device(repo);
687 ms = 250;
688 }
689 } while (!result);
690
691 pr_debug("%s:%u: ms %u\n", __func__, __LINE__, ms);
692
693 if ( ms > 60000)
694 break;
695
696 msleep_interruptible(ms);
697
698 /* An exponential backoff. */
699 ms <<= 1;
700
701 } while (!kthread_should_stop());
702
703 pr_debug(" <- %s:%u: kthread finished\n", __func__, __LINE__);
704
705 return 0;
706}
707
708/**
709 * ps3_start_probe_thread - Starts the background probe thread.
710 *
711 */
712
713static int __init ps3_start_probe_thread(enum ps3_bus_type bus_type)
714{
715 int result;
716 struct task_struct *task;
717 static struct ps3_repository_device repo; /* must be static */
718
719 pr_debug(" -> %s:%d\n", __func__, __LINE__);
720
721 memset(&repo, 0, sizeof(repo));
722
723 repo.bus_type = bus_type;
724
725 result = ps3_repository_find_bus(repo.bus_type, 0, &repo.bus_index);
726
727 if (result) {
728 printk(KERN_ERR "%s: Cannot find bus (%d)\n", __func__, result);
729 return -ENODEV;
730 }
731
732 result = ps3_repository_read_bus_id(repo.bus_index, &repo.bus_id);
733
734 if (result) {
735 printk(KERN_ERR "%s: read_bus_id failed %d\n", __func__,
736 result);
737 return -ENODEV;
738 }
739
740 task = kthread_run(ps3_probe_thread, &repo, "ps3-probe-%u", bus_type);
741
742 if (IS_ERR(task)) {
743 result = PTR_ERR(task);
744 printk(KERN_ERR "%s: kthread_run failed %d\n", __func__,
745 result);
746 return result;
747 }
748
749 pr_debug(" <- %s:%d\n", __func__, __LINE__);
750 return 0;
751}
752
753/**
754 * ps3_register_devices - Probe the system and register devices found.
755 *
756 * A device_initcall() routine.
757 */
758
759static int __init ps3_register_devices(void)
760{
761 int result;
762
763 if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
764 return -ENODEV;
765
766 pr_debug(" -> %s:%d\n", __func__, __LINE__);
767
768 /* ps3_repository_dump_bus_info(); */
769
770 result = ps3_start_probe_thread(PS3_BUS_TYPE_STORAGE);
771
772 ps3_register_vuart_devices();
773
774 ps3_register_graphics_devices();
775
776 ps3_repository_find_devices(PS3_BUS_TYPE_SB,
777 ps3_register_repository_device);
778
779 ps3_register_sound_devices();
780
781 pr_debug(" <- %s:%d\n", __func__, __LINE__);
782 return 0;
783}
784
785device_initcall(ps3_register_devices);
diff --git a/arch/powerpc/platforms/ps3/htab.c b/arch/powerpc/platforms/ps3/htab.c
index a1409e450c70..5d2e176a1b18 100644
--- a/arch/powerpc/platforms/ps3/htab.c
+++ b/arch/powerpc/platforms/ps3/htab.c
@@ -29,12 +29,12 @@
29#include "platform.h" 29#include "platform.h"
30 30
31#if defined(DEBUG) 31#if defined(DEBUG)
32#define DBG(fmt...) udbg_printf(fmt) 32#define DBG udbg_printf
33#else 33#else
34#define DBG(fmt...) do{if(0)printk(fmt);}while(0) 34#define DBG pr_debug
35#endif 35#endif
36 36
37static hpte_t *htab; 37static struct hash_pte *htab;
38static unsigned long htab_addr; 38static unsigned long htab_addr;
39static unsigned char *bolttab; 39static unsigned char *bolttab;
40static unsigned char *inusetab; 40static unsigned char *inusetab;
@@ -44,8 +44,8 @@ static DEFINE_SPINLOCK(ps3_bolttab_lock);
44#define debug_dump_hpte(_a, _b, _c, _d, _e, _f, _g) \ 44#define debug_dump_hpte(_a, _b, _c, _d, _e, _f, _g) \
45 _debug_dump_hpte(_a, _b, _c, _d, _e, _f, _g, __func__, __LINE__) 45 _debug_dump_hpte(_a, _b, _c, _d, _e, _f, _g, __func__, __LINE__)
46static void _debug_dump_hpte(unsigned long pa, unsigned long va, 46static void _debug_dump_hpte(unsigned long pa, unsigned long va,
47 unsigned long group, unsigned long bitmap, hpte_t lhpte, int psize, 47 unsigned long group, unsigned long bitmap, struct hash_pte lhpte,
48 unsigned long slot, const char* func, int line) 48 int psize, unsigned long slot, const char* func, int line)
49{ 49{
50 DBG("%s:%d: pa = %lxh\n", func, line, pa); 50 DBG("%s:%d: pa = %lxh\n", func, line, pa);
51 DBG("%s:%d: lpar = %lxh\n", func, line, 51 DBG("%s:%d: lpar = %lxh\n", func, line,
@@ -63,7 +63,7 @@ static long ps3_hpte_insert(unsigned long hpte_group, unsigned long va,
63 unsigned long pa, unsigned long rflags, unsigned long vflags, int psize) 63 unsigned long pa, unsigned long rflags, unsigned long vflags, int psize)
64{ 64{
65 unsigned long slot; 65 unsigned long slot;
66 hpte_t lhpte; 66 struct hash_pte lhpte;
67 int secondary = 0; 67 int secondary = 0;
68 unsigned long result; 68 unsigned long result;
69 unsigned long bitmap; 69 unsigned long bitmap;
@@ -234,10 +234,17 @@ static void ps3_hpte_invalidate(unsigned long slot, unsigned long va,
234 234
235static void ps3_hpte_clear(void) 235static void ps3_hpte_clear(void)
236{ 236{
237 /* Make sure to clean up the frame buffer device first */ 237 int result;
238 ps3fb_cleanup();
239 238
240 lv1_unmap_htab(htab_addr); 239 DBG(" -> %s:%d\n", __func__, __LINE__);
240
241 result = lv1_unmap_htab(htab_addr);
242 BUG_ON(result);
243
244 ps3_mm_shutdown();
245 ps3_mm_vas_destroy();
246
247 DBG(" <- %s:%d\n", __func__, __LINE__);
241} 248}
242 249
243void __init ps3_hpte_init(unsigned long htab_size) 250void __init ps3_hpte_init(unsigned long htab_size)
@@ -255,7 +262,7 @@ void __init ps3_hpte_init(unsigned long htab_size)
255 262
256 ppc64_pft_size = __ilog2(htab_size); 263 ppc64_pft_size = __ilog2(htab_size);
257 264
258 bitmap_size = htab_size / sizeof(hpte_t) / 8; 265 bitmap_size = htab_size / sizeof(struct hash_pte) / 8;
259 266
260 bolttab = __va(lmb_alloc(bitmap_size, 1)); 267 bolttab = __va(lmb_alloc(bitmap_size, 1));
261 inusetab = __va(lmb_alloc(bitmap_size, 1)); 268 inusetab = __va(lmb_alloc(bitmap_size, 1));
@@ -273,8 +280,8 @@ void __init ps3_map_htab(void)
273 280
274 result = lv1_map_htab(0, &htab_addr); 281 result = lv1_map_htab(0, &htab_addr);
275 282
276 htab = (hpte_t *)__ioremap(htab_addr, htab_size, 283 htab = (__force struct hash_pte *)ioremap_flags(htab_addr, htab_size,
277 pgprot_val(PAGE_READONLY_X)); 284 pgprot_val(PAGE_READONLY_X));
278 285
279 DBG("%s:%d: lpar %016lxh, virt %016lxh\n", __func__, __LINE__, 286 DBG("%s:%d: lpar %016lxh, virt %016lxh\n", __func__, __LINE__,
280 htab_addr, (unsigned long)htab); 287 htab_addr, (unsigned long)htab);
diff --git a/arch/powerpc/platforms/ps3/interrupt.c b/arch/powerpc/platforms/ps3/interrupt.c
index ec9030dbb5f1..67e32ec9b37e 100644
--- a/arch/powerpc/platforms/ps3/interrupt.c
+++ b/arch/powerpc/platforms/ps3/interrupt.c
@@ -30,9 +30,9 @@
30#include "platform.h" 30#include "platform.h"
31 31
32#if defined(DEBUG) 32#if defined(DEBUG)
33#define DBG(fmt...) udbg_printf(fmt) 33#define DBG udbg_printf
34#else 34#else
35#define DBG(fmt...) do{if(0)printk(fmt);}while(0) 35#define DBG pr_debug
36#endif 36#endif
37 37
38/** 38/**
@@ -78,19 +78,85 @@ struct ps3_bmp {
78/** 78/**
79 * struct ps3_private - a per cpu data structure 79 * struct ps3_private - a per cpu data structure
80 * @bmp: ps3_bmp structure 80 * @bmp: ps3_bmp structure
81 * @node: HV logical_ppe_id 81 * @ppe_id: HV logical_ppe_id
82 * @cpu: HV thread_id 82 * @thread_id: HV thread_id
83 */ 83 */
84 84
85struct ps3_private { 85struct ps3_private {
86 struct ps3_bmp bmp __attribute__ ((aligned (PS3_BMP_MINALIGN))); 86 struct ps3_bmp bmp __attribute__ ((aligned (PS3_BMP_MINALIGN)));
87 u64 node; 87 u64 ppe_id;
88 unsigned int cpu; 88 u64 thread_id;
89}; 89};
90 90
91static DEFINE_PER_CPU(struct ps3_private, ps3_private); 91static DEFINE_PER_CPU(struct ps3_private, ps3_private);
92 92
93/** 93/**
94 * ps3_chip_mask - Set an interrupt mask bit in ps3_bmp.
95 * @virq: The assigned Linux virq.
96 *
97 * Sets ps3_bmp.mask and calls lv1_did_update_interrupt_mask().
98 */
99
100static void ps3_chip_mask(unsigned int virq)
101{
102 struct ps3_private *pd = get_irq_chip_data(virq);
103 unsigned long flags;
104
105 pr_debug("%s:%d: thread_id %lu, virq %d\n", __func__, __LINE__,
106 pd->thread_id, virq);
107
108 local_irq_save(flags);
109 clear_bit(63 - virq, &pd->bmp.mask);
110 lv1_did_update_interrupt_mask(pd->ppe_id, pd->thread_id);
111 local_irq_restore(flags);
112}
113
114/**
115 * ps3_chip_unmask - Clear an interrupt mask bit in ps3_bmp.
116 * @virq: The assigned Linux virq.
117 *
118 * Clears ps3_bmp.mask and calls lv1_did_update_interrupt_mask().
119 */
120
121static void ps3_chip_unmask(unsigned int virq)
122{
123 struct ps3_private *pd = get_irq_chip_data(virq);
124 unsigned long flags;
125
126 pr_debug("%s:%d: thread_id %lu, virq %d\n", __func__, __LINE__,
127 pd->thread_id, virq);
128
129 local_irq_save(flags);
130 set_bit(63 - virq, &pd->bmp.mask);
131 lv1_did_update_interrupt_mask(pd->ppe_id, pd->thread_id);
132 local_irq_restore(flags);
133}
134
135/**
136 * ps3_chip_eoi - HV end-of-interrupt.
137 * @virq: The assigned Linux virq.
138 *
139 * Calls lv1_end_of_interrupt_ext().
140 */
141
142static void ps3_chip_eoi(unsigned int virq)
143{
144 const struct ps3_private *pd = get_irq_chip_data(virq);
145 lv1_end_of_interrupt_ext(pd->ppe_id, pd->thread_id, virq);
146}
147
148/**
149 * ps3_irq_chip - Represents the ps3_bmp as a Linux struct irq_chip.
150 */
151
152static struct irq_chip ps3_irq_chip = {
153 .typename = "ps3",
154 .mask = ps3_chip_mask,
155 .unmask = ps3_chip_unmask,
156 .eoi = ps3_chip_eoi,
157};
158
159/**
94 * ps3_virq_setup - virq related setup. 160 * ps3_virq_setup - virq related setup.
95 * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be 161 * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be
96 * serviced on. 162 * serviced on.
@@ -134,6 +200,8 @@ int ps3_virq_setup(enum ps3_cpu_binding cpu, unsigned long outlet,
134 goto fail_set; 200 goto fail_set;
135 } 201 }
136 202
203 ps3_chip_mask(*virq);
204
137 return result; 205 return result;
138 206
139fail_set: 207fail_set:
@@ -153,8 +221,8 @@ int ps3_virq_destroy(unsigned int virq)
153{ 221{
154 const struct ps3_private *pd = get_irq_chip_data(virq); 222 const struct ps3_private *pd = get_irq_chip_data(virq);
155 223
156 pr_debug("%s:%d: node %lu, cpu %d, virq %u\n", __func__, __LINE__, 224 pr_debug("%s:%d: ppe_id %lu, thread_id %lu, virq %u\n", __func__,
157 pd->node, pd->cpu, virq); 225 __LINE__, pd->ppe_id, pd->thread_id, virq);
158 226
159 set_irq_chip_data(virq, NULL); 227 set_irq_chip_data(virq, NULL);
160 irq_dispose_mapping(virq); 228 irq_dispose_mapping(virq);
@@ -190,7 +258,8 @@ int ps3_irq_plug_setup(enum ps3_cpu_binding cpu, unsigned long outlet,
190 258
191 /* Binds outlet to cpu + virq. */ 259 /* Binds outlet to cpu + virq. */
192 260
193 result = lv1_connect_irq_plug_ext(pd->node, pd->cpu, *virq, outlet, 0); 261 result = lv1_connect_irq_plug_ext(pd->ppe_id, pd->thread_id, *virq,
262 outlet, 0);
194 263
195 if (result) { 264 if (result) {
196 pr_info("%s:%d: lv1_connect_irq_plug_ext failed: %s\n", 265 pr_info("%s:%d: lv1_connect_irq_plug_ext failed: %s\n",
@@ -222,10 +291,12 @@ int ps3_irq_plug_destroy(unsigned int virq)
222 int result; 291 int result;
223 const struct ps3_private *pd = get_irq_chip_data(virq); 292 const struct ps3_private *pd = get_irq_chip_data(virq);
224 293
225 pr_debug("%s:%d: node %lu, cpu %d, virq %u\n", __func__, __LINE__, 294 pr_debug("%s:%d: ppe_id %lu, thread_id %lu, virq %u\n", __func__,
226 pd->node, pd->cpu, virq); 295 __LINE__, pd->ppe_id, pd->thread_id, virq);
296
297 ps3_chip_mask(virq);
227 298
228 result = lv1_disconnect_irq_plug_ext(pd->node, pd->cpu, virq); 299 result = lv1_disconnect_irq_plug_ext(pd->ppe_id, pd->thread_id, virq);
229 300
230 if (result) 301 if (result)
231 pr_info("%s:%d: lv1_disconnect_irq_plug_ext failed: %s\n", 302 pr_info("%s:%d: lv1_disconnect_irq_plug_ext failed: %s\n",
@@ -282,7 +353,9 @@ int ps3_event_receive_port_destroy(unsigned int virq)
282{ 353{
283 int result; 354 int result;
284 355
285 pr_debug(" -> %s:%d virq: %u\n", __func__, __LINE__, virq); 356 pr_debug(" -> %s:%d virq %u\n", __func__, __LINE__, virq);
357
358 ps3_chip_mask(virq);
286 359
287 result = lv1_destruct_event_receive_port(virq_to_hw(virq)); 360 result = lv1_destruct_event_receive_port(virq_to_hw(virq));
288 361
@@ -290,17 +363,14 @@ int ps3_event_receive_port_destroy(unsigned int virq)
290 pr_debug("%s:%d: lv1_destruct_event_receive_port failed: %s\n", 363 pr_debug("%s:%d: lv1_destruct_event_receive_port failed: %s\n",
291 __func__, __LINE__, ps3_result(result)); 364 __func__, __LINE__, ps3_result(result));
292 365
293 /* lv1_destruct_event_receive_port() destroys the IRQ plug, 366 /*
294 * so don't call ps3_irq_plug_destroy() here. 367 * Don't call ps3_virq_destroy() here since ps3_smp_cleanup_cpu()
368 * calls from interrupt context (smp_call_function) when kexecing.
295 */ 369 */
296 370
297 result = ps3_virq_destroy(virq);
298 BUG_ON(result);
299
300 pr_debug(" <- %s:%d\n", __func__, __LINE__); 371 pr_debug(" <- %s:%d\n", __func__, __LINE__);
301 return result; 372 return result;
302} 373}
303EXPORT_SYMBOL_GPL(ps3_event_receive_port_destroy);
304 374
305int ps3_send_event_locally(unsigned int virq) 375int ps3_send_event_locally(unsigned int virq)
306{ 376{
@@ -311,17 +381,15 @@ int ps3_send_event_locally(unsigned int virq)
311 * ps3_sb_event_receive_port_setup - Setup a system bus event receive port. 381 * ps3_sb_event_receive_port_setup - Setup a system bus event receive port.
312 * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be 382 * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be
313 * serviced on. 383 * serviced on.
314 * @did: The HV device identifier read from the system repository. 384 * @dev: The system bus device instance.
315 * @interrupt_id: The device interrupt id read from the system repository.
316 * @virq: The assigned Linux virq. 385 * @virq: The assigned Linux virq.
317 * 386 *
318 * An event irq represents a virtual device interrupt. The interrupt_id 387 * An event irq represents a virtual device interrupt. The interrupt_id
319 * coresponds to the software interrupt number. 388 * coresponds to the software interrupt number.
320 */ 389 */
321 390
322int ps3_sb_event_receive_port_setup(enum ps3_cpu_binding cpu, 391int ps3_sb_event_receive_port_setup(struct ps3_system_bus_device *dev,
323 const struct ps3_device_id *did, unsigned int interrupt_id, 392 enum ps3_cpu_binding cpu, unsigned int *virq)
324 unsigned int *virq)
325{ 393{
326 /* this should go in system-bus.c */ 394 /* this should go in system-bus.c */
327 395
@@ -332,8 +400,8 @@ int ps3_sb_event_receive_port_setup(enum ps3_cpu_binding cpu,
332 if (result) 400 if (result)
333 return result; 401 return result;
334 402
335 result = lv1_connect_interrupt_event_receive_port(did->bus_id, 403 result = lv1_connect_interrupt_event_receive_port(dev->bus_id,
336 did->dev_id, virq_to_hw(*virq), interrupt_id); 404 dev->dev_id, virq_to_hw(*virq), dev->interrupt_id);
337 405
338 if (result) { 406 if (result) {
339 pr_debug("%s:%d: lv1_connect_interrupt_event_receive_port" 407 pr_debug("%s:%d: lv1_connect_interrupt_event_receive_port"
@@ -345,24 +413,24 @@ int ps3_sb_event_receive_port_setup(enum ps3_cpu_binding cpu,
345 } 413 }
346 414
347 pr_debug("%s:%d: interrupt_id %u, virq %u\n", __func__, __LINE__, 415 pr_debug("%s:%d: interrupt_id %u, virq %u\n", __func__, __LINE__,
348 interrupt_id, *virq); 416 dev->interrupt_id, *virq);
349 417
350 return 0; 418 return 0;
351} 419}
352EXPORT_SYMBOL(ps3_sb_event_receive_port_setup); 420EXPORT_SYMBOL(ps3_sb_event_receive_port_setup);
353 421
354int ps3_sb_event_receive_port_destroy(const struct ps3_device_id *did, 422int ps3_sb_event_receive_port_destroy(struct ps3_system_bus_device *dev,
355 unsigned int interrupt_id, unsigned int virq) 423 unsigned int virq)
356{ 424{
357 /* this should go in system-bus.c */ 425 /* this should go in system-bus.c */
358 426
359 int result; 427 int result;
360 428
361 pr_debug(" -> %s:%d: interrupt_id %u, virq %u\n", __func__, __LINE__, 429 pr_debug(" -> %s:%d: interrupt_id %u, virq %u\n", __func__, __LINE__,
362 interrupt_id, virq); 430 dev->interrupt_id, virq);
363 431
364 result = lv1_disconnect_interrupt_event_receive_port(did->bus_id, 432 result = lv1_disconnect_interrupt_event_receive_port(dev->bus_id,
365 did->dev_id, virq_to_hw(virq), interrupt_id); 433 dev->dev_id, virq_to_hw(virq), dev->interrupt_id);
366 434
367 if (result) 435 if (result)
368 pr_debug("%s:%d: lv1_disconnect_interrupt_event_receive_port" 436 pr_debug("%s:%d: lv1_disconnect_interrupt_event_receive_port"
@@ -372,6 +440,14 @@ int ps3_sb_event_receive_port_destroy(const struct ps3_device_id *did,
372 result = ps3_event_receive_port_destroy(virq); 440 result = ps3_event_receive_port_destroy(virq);
373 BUG_ON(result); 441 BUG_ON(result);
374 442
443 /*
444 * ps3_event_receive_port_destroy() destroys the IRQ plug,
445 * so don't call ps3_irq_plug_destroy() here.
446 */
447
448 result = ps3_virq_destroy(virq);
449 BUG_ON(result);
450
375 pr_debug(" <- %s:%d\n", __func__, __LINE__); 451 pr_debug(" <- %s:%d\n", __func__, __LINE__);
376 return result; 452 return result;
377} 453}
@@ -412,16 +488,24 @@ EXPORT_SYMBOL_GPL(ps3_io_irq_setup);
412int ps3_io_irq_destroy(unsigned int virq) 488int ps3_io_irq_destroy(unsigned int virq)
413{ 489{
414 int result; 490 int result;
491 unsigned long outlet = virq_to_hw(virq);
415 492
416 result = lv1_destruct_io_irq_outlet(virq_to_hw(virq)); 493 ps3_chip_mask(virq);
417 494
418 if (result) 495 /*
419 pr_debug("%s:%d: lv1_destruct_io_irq_outlet failed: %s\n", 496 * lv1_destruct_io_irq_outlet() will destroy the IRQ plug,
420 __func__, __LINE__, ps3_result(result)); 497 * so call ps3_irq_plug_destroy() first.
498 */
421 499
422 result = ps3_irq_plug_destroy(virq); 500 result = ps3_irq_plug_destroy(virq);
423 BUG_ON(result); 501 BUG_ON(result);
424 502
503 result = lv1_destruct_io_irq_outlet(outlet);
504
505 if (result)
506 pr_debug("%s:%d: lv1_destruct_io_irq_outlet failed: %s\n",
507 __func__, __LINE__, ps3_result(result));
508
425 return result; 509 return result;
426} 510}
427EXPORT_SYMBOL_GPL(ps3_io_irq_destroy); 511EXPORT_SYMBOL_GPL(ps3_io_irq_destroy);
@@ -461,11 +545,13 @@ int ps3_vuart_irq_setup(enum ps3_cpu_binding cpu, void* virt_addr_bmp,
461 545
462 return result; 546 return result;
463} 547}
548EXPORT_SYMBOL_GPL(ps3_vuart_irq_setup);
464 549
465int ps3_vuart_irq_destroy(unsigned int virq) 550int ps3_vuart_irq_destroy(unsigned int virq)
466{ 551{
467 int result; 552 int result;
468 553
554 ps3_chip_mask(virq);
469 result = lv1_deconfigure_virtual_uart_irq(); 555 result = lv1_deconfigure_virtual_uart_irq();
470 556
471 if (result) { 557 if (result) {
@@ -479,6 +565,7 @@ int ps3_vuart_irq_destroy(unsigned int virq)
479 565
480 return result; 566 return result;
481} 567}
568EXPORT_SYMBOL_GPL(ps3_vuart_irq_destroy);
482 569
483/** 570/**
484 * ps3_spe_irq_setup - Setup an spe virq. 571 * ps3_spe_irq_setup - Setup an spe virq.
@@ -514,9 +601,14 @@ int ps3_spe_irq_setup(enum ps3_cpu_binding cpu, unsigned long spe_id,
514 601
515int ps3_spe_irq_destroy(unsigned int virq) 602int ps3_spe_irq_destroy(unsigned int virq)
516{ 603{
517 int result = ps3_irq_plug_destroy(virq); 604 int result;
605
606 ps3_chip_mask(virq);
607
608 result = ps3_irq_plug_destroy(virq);
518 BUG_ON(result); 609 BUG_ON(result);
519 return 0; 610
611 return result;
520} 612}
521 613
522 614
@@ -533,7 +625,7 @@ static void _dump_64_bmp(const char *header, const u64 *p, unsigned cpu,
533 *p & 0xffff); 625 *p & 0xffff);
534} 626}
535 627
536static void __attribute__ ((unused)) _dump_256_bmp(const char *header, 628static void __maybe_unused _dump_256_bmp(const char *header,
537 const u64 *p, unsigned cpu, const char* func, int line) 629 const u64 *p, unsigned cpu, const char* func, int line)
538{ 630{
539 pr_debug("%s:%d: %s %u {%016lx:%016lx:%016lx:%016lx}\n", 631 pr_debug("%s:%d: %s %u {%016lx:%016lx:%016lx:%016lx}\n",
@@ -546,86 +638,25 @@ static void _dump_bmp(struct ps3_private* pd, const char* func, int line)
546 unsigned long flags; 638 unsigned long flags;
547 639
548 spin_lock_irqsave(&pd->bmp.lock, flags); 640 spin_lock_irqsave(&pd->bmp.lock, flags);
549 _dump_64_bmp("stat", &pd->bmp.status, pd->cpu, func, line); 641 _dump_64_bmp("stat", &pd->bmp.status, pd->thread_id, func, line);
550 _dump_64_bmp("mask", &pd->bmp.mask, pd->cpu, func, line); 642 _dump_64_bmp("mask", &pd->bmp.mask, pd->thread_id, func, line);
551 spin_unlock_irqrestore(&pd->bmp.lock, flags); 643 spin_unlock_irqrestore(&pd->bmp.lock, flags);
552} 644}
553 645
554#define dump_mask(_x) _dump_mask(_x, __func__, __LINE__) 646#define dump_mask(_x) _dump_mask(_x, __func__, __LINE__)
555static void __attribute__ ((unused)) _dump_mask(struct ps3_private* pd, 647static void __maybe_unused _dump_mask(struct ps3_private *pd,
556 const char* func, int line) 648 const char* func, int line)
557{ 649{
558 unsigned long flags; 650 unsigned long flags;
559 651
560 spin_lock_irqsave(&pd->bmp.lock, flags); 652 spin_lock_irqsave(&pd->bmp.lock, flags);
561 _dump_64_bmp("mask", &pd->bmp.mask, pd->cpu, func, line); 653 _dump_64_bmp("mask", &pd->bmp.mask, pd->thread_id, func, line);
562 spin_unlock_irqrestore(&pd->bmp.lock, flags); 654 spin_unlock_irqrestore(&pd->bmp.lock, flags);
563} 655}
564#else 656#else
565static void dump_bmp(struct ps3_private* pd) {}; 657static void dump_bmp(struct ps3_private* pd) {};
566#endif /* defined(DEBUG) */ 658#endif /* defined(DEBUG) */
567 659
568static void ps3_chip_mask(unsigned int virq)
569{
570 struct ps3_private *pd = get_irq_chip_data(virq);
571 u64 bit = 0x8000000000000000UL >> virq;
572 u64 *p = &pd->bmp.mask;
573 u64 old;
574 unsigned long flags;
575
576 pr_debug("%s:%d: cpu %u, virq %d\n", __func__, __LINE__, pd->cpu, virq);
577
578 local_irq_save(flags);
579 asm volatile(
580 "1: ldarx %0,0,%3\n"
581 "andc %0,%0,%2\n"
582 "stdcx. %0,0,%3\n"
583 "bne- 1b"
584 : "=&r" (old), "+m" (*p)
585 : "r" (bit), "r" (p)
586 : "cc" );
587
588 lv1_did_update_interrupt_mask(pd->node, pd->cpu);
589 local_irq_restore(flags);
590}
591
592static void ps3_chip_unmask(unsigned int virq)
593{
594 struct ps3_private *pd = get_irq_chip_data(virq);
595 u64 bit = 0x8000000000000000UL >> virq;
596 u64 *p = &pd->bmp.mask;
597 u64 old;
598 unsigned long flags;
599
600 pr_debug("%s:%d: cpu %u, virq %d\n", __func__, __LINE__, pd->cpu, virq);
601
602 local_irq_save(flags);
603 asm volatile(
604 "1: ldarx %0,0,%3\n"
605 "or %0,%0,%2\n"
606 "stdcx. %0,0,%3\n"
607 "bne- 1b"
608 : "=&r" (old), "+m" (*p)
609 : "r" (bit), "r" (p)
610 : "cc" );
611
612 lv1_did_update_interrupt_mask(pd->node, pd->cpu);
613 local_irq_restore(flags);
614}
615
616static void ps3_chip_eoi(unsigned int virq)
617{
618 const struct ps3_private *pd = get_irq_chip_data(virq);
619 lv1_end_of_interrupt_ext(pd->node, pd->cpu, virq);
620}
621
622static struct irq_chip irq_chip = {
623 .typename = "ps3",
624 .mask = ps3_chip_mask,
625 .unmask = ps3_chip_unmask,
626 .eoi = ps3_chip_eoi,
627};
628
629static void ps3_host_unmap(struct irq_host *h, unsigned int virq) 660static void ps3_host_unmap(struct irq_host *h, unsigned int virq)
630{ 661{
631 set_irq_chip_data(virq, NULL); 662 set_irq_chip_data(virq, NULL);
@@ -637,7 +668,7 @@ static int ps3_host_map(struct irq_host *h, unsigned int virq,
637 pr_debug("%s:%d: hwirq %lu, virq %u\n", __func__, __LINE__, hwirq, 668 pr_debug("%s:%d: hwirq %lu, virq %u\n", __func__, __LINE__, hwirq,
638 virq); 669 virq);
639 670
640 set_irq_chip_and_handler(virq, &irq_chip, handle_fasteoi_irq); 671 set_irq_chip_and_handler(virq, &ps3_irq_chip, handle_fasteoi_irq);
641 672
642 return 0; 673 return 0;
643} 674}
@@ -657,7 +688,7 @@ void __init ps3_register_ipi_debug_brk(unsigned int cpu, unsigned int virq)
657 cpu, virq, pd->bmp.ipi_debug_brk_mask); 688 cpu, virq, pd->bmp.ipi_debug_brk_mask);
658} 689}
659 690
660unsigned int ps3_get_irq(void) 691static unsigned int ps3_get_irq(void)
661{ 692{
662 struct ps3_private *pd = &__get_cpu_var(ps3_private); 693 struct ps3_private *pd = &__get_cpu_var(ps3_private);
663 u64 x = (pd->bmp.status & pd->bmp.mask); 694 u64 x = (pd->bmp.status & pd->bmp.mask);
@@ -672,8 +703,8 @@ unsigned int ps3_get_irq(void)
672 plug &= 0x3f; 703 plug &= 0x3f;
673 704
674 if (unlikely(plug) == NO_IRQ) { 705 if (unlikely(plug) == NO_IRQ) {
675 pr_debug("%s:%d: no plug found: cpu %u\n", __func__, __LINE__, 706 pr_debug("%s:%d: no plug found: thread_id %lu\n", __func__,
676 pd->cpu); 707 __LINE__, pd->thread_id);
677 dump_bmp(&per_cpu(ps3_private, 0)); 708 dump_bmp(&per_cpu(ps3_private, 0));
678 dump_bmp(&per_cpu(ps3_private, 1)); 709 dump_bmp(&per_cpu(ps3_private, 1));
679 return NO_IRQ; 710 return NO_IRQ;
@@ -703,16 +734,16 @@ void __init ps3_init_IRQ(void)
703 for_each_possible_cpu(cpu) { 734 for_each_possible_cpu(cpu) {
704 struct ps3_private *pd = &per_cpu(ps3_private, cpu); 735 struct ps3_private *pd = &per_cpu(ps3_private, cpu);
705 736
706 lv1_get_logical_ppe_id(&pd->node); 737 lv1_get_logical_ppe_id(&pd->ppe_id);
707 pd->cpu = get_hard_smp_processor_id(cpu); 738 pd->thread_id = get_hard_smp_processor_id(cpu);
708 spin_lock_init(&pd->bmp.lock); 739 spin_lock_init(&pd->bmp.lock);
709 740
710 pr_debug("%s:%d: node %lu, cpu %d, bmp %lxh\n", __func__, 741 pr_debug("%s:%d: ppe_id %lu, thread_id %lu, bmp %lxh\n",
711 __LINE__, pd->node, pd->cpu, 742 __func__, __LINE__, pd->ppe_id, pd->thread_id,
712 ps3_mm_phys_to_lpar(__pa(&pd->bmp))); 743 ps3_mm_phys_to_lpar(__pa(&pd->bmp)));
713 744
714 result = lv1_configure_irq_state_bitmap(pd->node, pd->cpu, 745 result = lv1_configure_irq_state_bitmap(pd->ppe_id,
715 ps3_mm_phys_to_lpar(__pa(&pd->bmp))); 746 pd->thread_id, ps3_mm_phys_to_lpar(__pa(&pd->bmp)));
716 747
717 if (result) 748 if (result)
718 pr_debug("%s:%d: lv1_configure_irq_state_bitmap failed:" 749 pr_debug("%s:%d: lv1_configure_irq_state_bitmap failed:"
@@ -722,3 +753,16 @@ void __init ps3_init_IRQ(void)
722 753
723 ppc_md.get_irq = ps3_get_irq; 754 ppc_md.get_irq = ps3_get_irq;
724} 755}
756
757void ps3_shutdown_IRQ(int cpu)
758{
759 int result;
760 u64 ppe_id;
761 u64 thread_id = get_hard_smp_processor_id(cpu);
762
763 lv1_get_logical_ppe_id(&ppe_id);
764 result = lv1_configure_irq_state_bitmap(ppe_id, thread_id, 0);
765
766 DBG("%s:%d: lv1_configure_irq_state_bitmap (%lu:%lu/%d) %s\n", __func__,
767 __LINE__, ppe_id, thread_id, cpu, ps3_result(result));
768}
diff --git a/arch/powerpc/platforms/ps3/mm.c b/arch/powerpc/platforms/ps3/mm.c
index f8a3e206c584..7bb3e1620974 100644
--- a/arch/powerpc/platforms/ps3/mm.c
+++ b/arch/powerpc/platforms/ps3/mm.c
@@ -30,9 +30,9 @@
30#include "platform.h" 30#include "platform.h"
31 31
32#if defined(DEBUG) 32#if defined(DEBUG)
33#define DBG(fmt...) udbg_printf(fmt) 33#define DBG udbg_printf
34#else 34#else
35#define DBG(fmt...) do{if(0)printk(fmt);}while(0) 35#define DBG pr_debug
36#endif 36#endif
37 37
38enum { 38enum {
@@ -115,7 +115,8 @@ struct map {
115}; 115};
116 116
117#define debug_dump_map(x) _debug_dump_map(x, __func__, __LINE__) 117#define debug_dump_map(x) _debug_dump_map(x, __func__, __LINE__)
118static void _debug_dump_map(const struct map* m, const char* func, int line) 118static void __maybe_unused _debug_dump_map(const struct map *m,
119 const char *func, int line)
119{ 120{
120 DBG("%s:%d: map.total = %lxh\n", func, line, m->total); 121 DBG("%s:%d: map.total = %lxh\n", func, line, m->total);
121 DBG("%s:%d: map.rm.size = %lxh\n", func, line, m->rm.size); 122 DBG("%s:%d: map.rm.size = %lxh\n", func, line, m->rm.size);
@@ -212,9 +213,15 @@ fail:
212 213
213void ps3_mm_vas_destroy(void) 214void ps3_mm_vas_destroy(void)
214{ 215{
216 int result;
217
218 DBG("%s:%d: map.vas_id = %lu\n", __func__, __LINE__, map.vas_id);
219
215 if (map.vas_id) { 220 if (map.vas_id) {
216 lv1_select_virtual_address_space(0); 221 result = lv1_select_virtual_address_space(0);
217 lv1_destruct_virtual_address_space(map.vas_id); 222 BUG_ON(result);
223 result = lv1_destruct_virtual_address_space(map.vas_id);
224 BUG_ON(result);
218 map.vas_id = 0; 225 map.vas_id = 0;
219 } 226 }
220} 227}
@@ -232,7 +239,7 @@ void ps3_mm_vas_destroy(void)
232 * @size is rounded down to a multiple of the vas large page size. 239 * @size is rounded down to a multiple of the vas large page size.
233 */ 240 */
234 241
235int ps3_mm_region_create(struct mem_region *r, unsigned long size) 242static int ps3_mm_region_create(struct mem_region *r, unsigned long size)
236{ 243{
237 int result; 244 int result;
238 unsigned long muid; 245 unsigned long muid;
@@ -273,10 +280,14 @@ zero_region:
273 * @r: pointer to struct mem_region 280 * @r: pointer to struct mem_region
274 */ 281 */
275 282
276void ps3_mm_region_destroy(struct mem_region *r) 283static void ps3_mm_region_destroy(struct mem_region *r)
277{ 284{
285 int result;
286
287 DBG("%s:%d: r->base = %lxh\n", __func__, __LINE__, r->base);
278 if (r->base) { 288 if (r->base) {
279 lv1_release_memory(r->base); 289 result = lv1_release_memory(r->base);
290 BUG_ON(result);
280 r->size = r->base = r->offset = 0; 291 r->size = r->base = r->offset = 0;
281 map.total = map.rm.size; 292 map.total = map.rm.size;
282 } 293 }
@@ -329,31 +340,34 @@ core_initcall(ps3_mm_add_memory);
329/*============================================================================*/ 340/*============================================================================*/
330 341
331/** 342/**
332 * dma_lpar_to_bus - Translate an lpar address to ioc mapped bus address. 343 * dma_sb_lpar_to_bus - Translate an lpar address to ioc mapped bus address.
333 * @r: pointer to dma region structure 344 * @r: pointer to dma region structure
334 * @lpar_addr: HV lpar address 345 * @lpar_addr: HV lpar address
335 */ 346 */
336 347
337static unsigned long dma_lpar_to_bus(struct ps3_dma_region *r, 348static unsigned long dma_sb_lpar_to_bus(struct ps3_dma_region *r,
338 unsigned long lpar_addr) 349 unsigned long lpar_addr)
339{ 350{
340 BUG_ON(lpar_addr >= map.r1.base + map.r1.size); 351 if (lpar_addr >= map.rm.size)
341 return r->bus_addr + (lpar_addr <= map.rm.size ? lpar_addr 352 lpar_addr -= map.r1.offset;
342 : lpar_addr - map.r1.offset); 353 BUG_ON(lpar_addr < r->offset);
354 BUG_ON(lpar_addr >= r->offset + r->len);
355 return r->bus_addr + lpar_addr - r->offset;
343} 356}
344 357
345#define dma_dump_region(_a) _dma_dump_region(_a, __func__, __LINE__) 358#define dma_dump_region(_a) _dma_dump_region(_a, __func__, __LINE__)
346static void _dma_dump_region(const struct ps3_dma_region *r, const char* func, 359static void __maybe_unused _dma_dump_region(const struct ps3_dma_region *r,
347 int line) 360 const char *func, int line)
348{ 361{
349 DBG("%s:%d: dev %u:%u\n", func, line, r->did.bus_id, 362 DBG("%s:%d: dev %u:%u\n", func, line, r->dev->bus_id,
350 r->did.dev_id); 363 r->dev->dev_id);
351 DBG("%s:%d: page_size %u\n", func, line, r->page_size); 364 DBG("%s:%d: page_size %u\n", func, line, r->page_size);
352 DBG("%s:%d: bus_addr %lxh\n", func, line, r->bus_addr); 365 DBG("%s:%d: bus_addr %lxh\n", func, line, r->bus_addr);
353 DBG("%s:%d: len %lxh\n", func, line, r->len); 366 DBG("%s:%d: len %lxh\n", func, line, r->len);
367 DBG("%s:%d: offset %lxh\n", func, line, r->offset);
354} 368}
355 369
356/** 370 /**
357 * dma_chunk - A chunk of dma pages mapped by the io controller. 371 * dma_chunk - A chunk of dma pages mapped by the io controller.
358 * @region - The dma region that owns this chunk. 372 * @region - The dma region that owns this chunk.
359 * @lpar_addr: Starting lpar address of the area to map. 373 * @lpar_addr: Starting lpar address of the area to map.
@@ -381,10 +395,11 @@ static void _dma_dump_chunk (const struct dma_chunk* c, const char* func,
381 int line) 395 int line)
382{ 396{
383 DBG("%s:%d: r.dev %u:%u\n", func, line, 397 DBG("%s:%d: r.dev %u:%u\n", func, line,
384 c->region->did.bus_id, c->region->did.dev_id); 398 c->region->dev->bus_id, c->region->dev->dev_id);
385 DBG("%s:%d: r.bus_addr %lxh\n", func, line, c->region->bus_addr); 399 DBG("%s:%d: r.bus_addr %lxh\n", func, line, c->region->bus_addr);
386 DBG("%s:%d: r.page_size %u\n", func, line, c->region->page_size); 400 DBG("%s:%d: r.page_size %u\n", func, line, c->region->page_size);
387 DBG("%s:%d: r.len %lxh\n", func, line, c->region->len); 401 DBG("%s:%d: r.len %lxh\n", func, line, c->region->len);
402 DBG("%s:%d: r.offset %lxh\n", func, line, c->region->offset);
388 DBG("%s:%d: c.lpar_addr %lxh\n", func, line, c->lpar_addr); 403 DBG("%s:%d: c.lpar_addr %lxh\n", func, line, c->lpar_addr);
389 DBG("%s:%d: c.bus_addr %lxh\n", func, line, c->bus_addr); 404 DBG("%s:%d: c.bus_addr %lxh\n", func, line, c->bus_addr);
390 DBG("%s:%d: c.len %lxh\n", func, line, c->len); 405 DBG("%s:%d: c.len %lxh\n", func, line, c->len);
@@ -395,39 +410,68 @@ static struct dma_chunk * dma_find_chunk(struct ps3_dma_region *r,
395{ 410{
396 struct dma_chunk *c; 411 struct dma_chunk *c;
397 unsigned long aligned_bus = _ALIGN_DOWN(bus_addr, 1 << r->page_size); 412 unsigned long aligned_bus = _ALIGN_DOWN(bus_addr, 1 << r->page_size);
398 unsigned long aligned_len = _ALIGN_UP(len, 1 << r->page_size); 413 unsigned long aligned_len = _ALIGN_UP(len+bus_addr-aligned_bus,
414 1 << r->page_size);
399 415
400 list_for_each_entry(c, &r->chunk_list.head, link) { 416 list_for_each_entry(c, &r->chunk_list.head, link) {
401 /* intersection */ 417 /* intersection */
402 if (aligned_bus >= c->bus_addr 418 if (aligned_bus >= c->bus_addr &&
403 && aligned_bus < c->bus_addr + c->len 419 aligned_bus + aligned_len <= c->bus_addr + c->len)
404 && aligned_bus + aligned_len <= c->bus_addr + c->len) {
405 return c; 420 return c;
406 } 421
407 /* below */ 422 /* below */
408 if (aligned_bus + aligned_len <= c->bus_addr) { 423 if (aligned_bus + aligned_len <= c->bus_addr)
409 continue; 424 continue;
410 } 425
411 /* above */ 426 /* above */
412 if (aligned_bus >= c->bus_addr + c->len) { 427 if (aligned_bus >= c->bus_addr + c->len)
413 continue; 428 continue;
414 }
415 429
416 /* we don't handle the multi-chunk case for now */ 430 /* we don't handle the multi-chunk case for now */
417
418 dma_dump_chunk(c); 431 dma_dump_chunk(c);
419 BUG(); 432 BUG();
420 } 433 }
421 return NULL; 434 return NULL;
422} 435}
423 436
424static int dma_free_chunk(struct dma_chunk *c) 437static struct dma_chunk *dma_find_chunk_lpar(struct ps3_dma_region *r,
438 unsigned long lpar_addr, unsigned long len)
439{
440 struct dma_chunk *c;
441 unsigned long aligned_lpar = _ALIGN_DOWN(lpar_addr, 1 << r->page_size);
442 unsigned long aligned_len = _ALIGN_UP(len + lpar_addr - aligned_lpar,
443 1 << r->page_size);
444
445 list_for_each_entry(c, &r->chunk_list.head, link) {
446 /* intersection */
447 if (c->lpar_addr <= aligned_lpar &&
448 aligned_lpar < c->lpar_addr + c->len) {
449 if (aligned_lpar + aligned_len <= c->lpar_addr + c->len)
450 return c;
451 else {
452 dma_dump_chunk(c);
453 BUG();
454 }
455 }
456 /* below */
457 if (aligned_lpar + aligned_len <= c->lpar_addr) {
458 continue;
459 }
460 /* above */
461 if (c->lpar_addr + c->len <= aligned_lpar) {
462 continue;
463 }
464 }
465 return NULL;
466}
467
468static int dma_sb_free_chunk(struct dma_chunk *c)
425{ 469{
426 int result = 0; 470 int result = 0;
427 471
428 if (c->bus_addr) { 472 if (c->bus_addr) {
429 result = lv1_unmap_device_dma_region(c->region->did.bus_id, 473 result = lv1_unmap_device_dma_region(c->region->dev->bus_id,
430 c->region->did.dev_id, c->bus_addr, c->len); 474 c->region->dev->dev_id, c->bus_addr, c->len);
431 BUG_ON(result); 475 BUG_ON(result);
432 } 476 }
433 477
@@ -435,8 +479,39 @@ static int dma_free_chunk(struct dma_chunk *c)
435 return result; 479 return result;
436} 480}
437 481
482static int dma_ioc0_free_chunk(struct dma_chunk *c)
483{
484 int result = 0;
485 int iopage;
486 unsigned long offset;
487 struct ps3_dma_region *r = c->region;
488
489 DBG("%s:start\n", __func__);
490 for (iopage = 0; iopage < (c->len >> r->page_size); iopage++) {
491 offset = (1 << r->page_size) * iopage;
492 /* put INVALID entry */
493 result = lv1_put_iopte(0,
494 c->bus_addr + offset,
495 c->lpar_addr + offset,
496 r->ioid,
497 0);
498 DBG("%s: bus=%#lx, lpar=%#lx, ioid=%d\n", __func__,
499 c->bus_addr + offset,
500 c->lpar_addr + offset,
501 r->ioid);
502
503 if (result) {
504 DBG("%s:%d: lv1_put_iopte failed: %s\n", __func__,
505 __LINE__, ps3_result(result));
506 }
507 }
508 kfree(c);
509 DBG("%s:end\n", __func__);
510 return result;
511}
512
438/** 513/**
439 * dma_map_pages - Maps dma pages into the io controller bus address space. 514 * dma_sb_map_pages - Maps dma pages into the io controller bus address space.
440 * @r: Pointer to a struct ps3_dma_region. 515 * @r: Pointer to a struct ps3_dma_region.
441 * @phys_addr: Starting physical address of the area to map. 516 * @phys_addr: Starting physical address of the area to map.
442 * @len: Length in bytes of the area to map. 517 * @len: Length in bytes of the area to map.
@@ -446,8 +521,8 @@ static int dma_free_chunk(struct dma_chunk *c)
446 * make the HV call to add the pages into the io controller address space. 521 * make the HV call to add the pages into the io controller address space.
447 */ 522 */
448 523
449static int dma_map_pages(struct ps3_dma_region *r, unsigned long phys_addr, 524static int dma_sb_map_pages(struct ps3_dma_region *r, unsigned long phys_addr,
450 unsigned long len, struct dma_chunk **c_out) 525 unsigned long len, struct dma_chunk **c_out, u64 iopte_flag)
451{ 526{
452 int result; 527 int result;
453 struct dma_chunk *c; 528 struct dma_chunk *c;
@@ -461,13 +536,13 @@ static int dma_map_pages(struct ps3_dma_region *r, unsigned long phys_addr,
461 536
462 c->region = r; 537 c->region = r;
463 c->lpar_addr = ps3_mm_phys_to_lpar(phys_addr); 538 c->lpar_addr = ps3_mm_phys_to_lpar(phys_addr);
464 c->bus_addr = dma_lpar_to_bus(r, c->lpar_addr); 539 c->bus_addr = dma_sb_lpar_to_bus(r, c->lpar_addr);
465 c->len = len; 540 c->len = len;
466 541
467 result = lv1_map_device_dma_region(c->region->did.bus_id, 542 BUG_ON(iopte_flag != 0xf800000000000000UL);
468 c->region->did.dev_id, c->lpar_addr, c->bus_addr, c->len, 543 result = lv1_map_device_dma_region(c->region->dev->bus_id,
469 0xf800000000000000UL); 544 c->region->dev->dev_id, c->lpar_addr,
470 545 c->bus_addr, c->len, iopte_flag);
471 if (result) { 546 if (result) {
472 DBG("%s:%d: lv1_map_device_dma_region failed: %s\n", 547 DBG("%s:%d: lv1_map_device_dma_region failed: %s\n",
473 __func__, __LINE__, ps3_result(result)); 548 __func__, __LINE__, ps3_result(result));
@@ -487,26 +562,120 @@ fail_alloc:
487 return result; 562 return result;
488} 563}
489 564
565static int dma_ioc0_map_pages(struct ps3_dma_region *r, unsigned long phys_addr,
566 unsigned long len, struct dma_chunk **c_out,
567 u64 iopte_flag)
568{
569 int result;
570 struct dma_chunk *c, *last;
571 int iopage, pages;
572 unsigned long offset;
573
574 DBG(KERN_ERR "%s: phy=%#lx, lpar%#lx, len=%#lx\n", __func__,
575 phys_addr, ps3_mm_phys_to_lpar(phys_addr), len);
576 c = kzalloc(sizeof(struct dma_chunk), GFP_ATOMIC);
577
578 if (!c) {
579 result = -ENOMEM;
580 goto fail_alloc;
581 }
582
583 c->region = r;
584 c->len = len;
585 c->lpar_addr = ps3_mm_phys_to_lpar(phys_addr);
586 /* allocate IO address */
587 if (list_empty(&r->chunk_list.head)) {
588 /* first one */
589 c->bus_addr = r->bus_addr;
590 } else {
591 /* derive from last bus addr*/
592 last = list_entry(r->chunk_list.head.next,
593 struct dma_chunk, link);
594 c->bus_addr = last->bus_addr + last->len;
595 DBG("%s: last bus=%#lx, len=%#lx\n", __func__,
596 last->bus_addr, last->len);
597 }
598
599 /* FIXME: check whether length exceeds region size */
600
601 /* build ioptes for the area */
602 pages = len >> r->page_size;
603 DBG("%s: pgsize=%#x len=%#lx pages=%#x iopteflag=%#lx\n", __func__,
604 r->page_size, r->len, pages, iopte_flag);
605 for (iopage = 0; iopage < pages; iopage++) {
606 offset = (1 << r->page_size) * iopage;
607 result = lv1_put_iopte(0,
608 c->bus_addr + offset,
609 c->lpar_addr + offset,
610 r->ioid,
611 iopte_flag);
612 if (result) {
613 printk(KERN_WARNING "%s:%d: lv1_map_device_dma_region "
614 "failed: %s\n", __func__, __LINE__,
615 ps3_result(result));
616 goto fail_map;
617 }
618 DBG("%s: pg=%d bus=%#lx, lpar=%#lx, ioid=%#x\n", __func__,
619 iopage, c->bus_addr + offset, c->lpar_addr + offset,
620 r->ioid);
621 }
622
623 /* be sure that last allocated one is inserted at head */
624 list_add(&c->link, &r->chunk_list.head);
625
626 *c_out = c;
627 DBG("%s: end\n", __func__);
628 return 0;
629
630fail_map:
631 for (iopage--; 0 <= iopage; iopage--) {
632 lv1_put_iopte(0,
633 c->bus_addr + offset,
634 c->lpar_addr + offset,
635 r->ioid,
636 0);
637 }
638 kfree(c);
639fail_alloc:
640 *c_out = NULL;
641 return result;
642}
643
490/** 644/**
491 * dma_region_create - Create a device dma region. 645 * dma_sb_region_create - Create a device dma region.
492 * @r: Pointer to a struct ps3_dma_region. 646 * @r: Pointer to a struct ps3_dma_region.
493 * 647 *
494 * This is the lowest level dma region create routine, and is the one that 648 * This is the lowest level dma region create routine, and is the one that
495 * will make the HV call to create the region. 649 * will make the HV call to create the region.
496 */ 650 */
497 651
498static int dma_region_create(struct ps3_dma_region* r) 652static int dma_sb_region_create(struct ps3_dma_region *r)
499{ 653{
500 int result; 654 int result;
501 655
502 r->len = _ALIGN_UP(map.total, 1 << r->page_size); 656 pr_info(" -> %s:%d:\n", __func__, __LINE__);
657
658 BUG_ON(!r);
659
660 if (!r->dev->bus_id) {
661 pr_info("%s:%d: %u:%u no dma\n", __func__, __LINE__,
662 r->dev->bus_id, r->dev->dev_id);
663 return 0;
664 }
665
666 DBG("%s:%u: len = 0x%lx, page_size = %u, offset = 0x%lx\n", __func__,
667 __LINE__, r->len, r->page_size, r->offset);
668
669 BUG_ON(!r->len);
670 BUG_ON(!r->page_size);
671 BUG_ON(!r->region_ops);
672
503 INIT_LIST_HEAD(&r->chunk_list.head); 673 INIT_LIST_HEAD(&r->chunk_list.head);
504 spin_lock_init(&r->chunk_list.lock); 674 spin_lock_init(&r->chunk_list.lock);
505 675
506 result = lv1_allocate_device_dma_region(r->did.bus_id, r->did.dev_id, 676 result = lv1_allocate_device_dma_region(r->dev->bus_id, r->dev->dev_id,
507 r->len, r->page_size, r->region_type, &r->bus_addr); 677 roundup_pow_of_two(r->len), r->page_size, r->region_type,
508 678 &r->bus_addr);
509 dma_dump_region(r);
510 679
511 if (result) { 680 if (result) {
512 DBG("%s:%d: lv1_allocate_device_dma_region failed: %s\n", 681 DBG("%s:%d: lv1_allocate_device_dma_region failed: %s\n",
@@ -517,6 +686,27 @@ static int dma_region_create(struct ps3_dma_region* r)
517 return result; 686 return result;
518} 687}
519 688
689static int dma_ioc0_region_create(struct ps3_dma_region *r)
690{
691 int result;
692
693 INIT_LIST_HEAD(&r->chunk_list.head);
694 spin_lock_init(&r->chunk_list.lock);
695
696 result = lv1_allocate_io_segment(0,
697 r->len,
698 r->page_size,
699 &r->bus_addr);
700 if (result) {
701 DBG("%s:%d: lv1_allocate_io_segment failed: %s\n",
702 __func__, __LINE__, ps3_result(result));
703 r->len = r->bus_addr = 0;
704 }
705 DBG("%s: len=%#lx, pg=%d, bus=%#lx\n", __func__,
706 r->len, r->page_size, r->bus_addr);
707 return result;
708}
709
520/** 710/**
521 * dma_region_free - Free a device dma region. 711 * dma_region_free - Free a device dma region.
522 * @r: Pointer to a struct ps3_dma_region. 712 * @r: Pointer to a struct ps3_dma_region.
@@ -525,31 +715,62 @@ static int dma_region_create(struct ps3_dma_region* r)
525 * will make the HV call to free the region. 715 * will make the HV call to free the region.
526 */ 716 */
527 717
528static int dma_region_free(struct ps3_dma_region* r) 718static int dma_sb_region_free(struct ps3_dma_region *r)
529{ 719{
530 int result; 720 int result;
531 struct dma_chunk *c; 721 struct dma_chunk *c;
532 struct dma_chunk *tmp; 722 struct dma_chunk *tmp;
533 723
724 BUG_ON(!r);
725
726 if (!r->dev->bus_id) {
727 pr_info("%s:%d: %u:%u no dma\n", __func__, __LINE__,
728 r->dev->bus_id, r->dev->dev_id);
729 return 0;
730 }
731
534 list_for_each_entry_safe(c, tmp, &r->chunk_list.head, link) { 732 list_for_each_entry_safe(c, tmp, &r->chunk_list.head, link) {
535 list_del(&c->link); 733 list_del(&c->link);
536 dma_free_chunk(c); 734 dma_sb_free_chunk(c);
537 } 735 }
538 736
539 result = lv1_free_device_dma_region(r->did.bus_id, r->did.dev_id, 737 result = lv1_free_device_dma_region(r->dev->bus_id, r->dev->dev_id,
540 r->bus_addr); 738 r->bus_addr);
541 739
542 if (result) 740 if (result)
543 DBG("%s:%d: lv1_free_device_dma_region failed: %s\n", 741 DBG("%s:%d: lv1_free_device_dma_region failed: %s\n",
544 __func__, __LINE__, ps3_result(result)); 742 __func__, __LINE__, ps3_result(result));
545 743
546 r->len = r->bus_addr = 0; 744 r->bus_addr = 0;
745
746 return result;
747}
748
749static int dma_ioc0_region_free(struct ps3_dma_region *r)
750{
751 int result;
752 struct dma_chunk *c, *n;
753
754 DBG("%s: start\n", __func__);
755 list_for_each_entry_safe(c, n, &r->chunk_list.head, link) {
756 list_del(&c->link);
757 dma_ioc0_free_chunk(c);
758 }
759
760 result = lv1_release_io_segment(0, r->bus_addr);
761
762 if (result)
763 DBG("%s:%d: lv1_free_device_dma_region failed: %s\n",
764 __func__, __LINE__, ps3_result(result));
765
766 r->bus_addr = 0;
767 DBG("%s: end\n", __func__);
547 768
548 return result; 769 return result;
549} 770}
550 771
551/** 772/**
552 * dma_map_area - Map an area of memory into a device dma region. 773 * dma_sb_map_area - Map an area of memory into a device dma region.
553 * @r: Pointer to a struct ps3_dma_region. 774 * @r: Pointer to a struct ps3_dma_region.
554 * @virt_addr: Starting virtual address of the area to map. 775 * @virt_addr: Starting virtual address of the area to map.
555 * @len: Length in bytes of the area to map. 776 * @len: Length in bytes of the area to map.
@@ -559,16 +780,19 @@ static int dma_region_free(struct ps3_dma_region* r)
559 * This is the common dma mapping routine. 780 * This is the common dma mapping routine.
560 */ 781 */
561 782
562static int dma_map_area(struct ps3_dma_region *r, unsigned long virt_addr, 783static int dma_sb_map_area(struct ps3_dma_region *r, unsigned long virt_addr,
563 unsigned long len, unsigned long *bus_addr) 784 unsigned long len, unsigned long *bus_addr,
785 u64 iopte_flag)
564{ 786{
565 int result; 787 int result;
566 unsigned long flags; 788 unsigned long flags;
567 struct dma_chunk *c; 789 struct dma_chunk *c;
568 unsigned long phys_addr = is_kernel_addr(virt_addr) ? __pa(virt_addr) 790 unsigned long phys_addr = is_kernel_addr(virt_addr) ? __pa(virt_addr)
569 : virt_addr; 791 : virt_addr;
570 792 unsigned long aligned_phys = _ALIGN_DOWN(phys_addr, 1 << r->page_size);
571 *bus_addr = dma_lpar_to_bus(r, ps3_mm_phys_to_lpar(phys_addr)); 793 unsigned long aligned_len = _ALIGN_UP(len + phys_addr - aligned_phys,
794 1 << r->page_size);
795 *bus_addr = dma_sb_lpar_to_bus(r, ps3_mm_phys_to_lpar(phys_addr));
572 796
573 if (!USE_DYNAMIC_DMA) { 797 if (!USE_DYNAMIC_DMA) {
574 unsigned long lpar_addr = ps3_mm_phys_to_lpar(phys_addr); 798 unsigned long lpar_addr = ps3_mm_phys_to_lpar(phys_addr);
@@ -588,17 +812,18 @@ static int dma_map_area(struct ps3_dma_region *r, unsigned long virt_addr,
588 c = dma_find_chunk(r, *bus_addr, len); 812 c = dma_find_chunk(r, *bus_addr, len);
589 813
590 if (c) { 814 if (c) {
815 DBG("%s:%d: reusing mapped chunk", __func__, __LINE__);
816 dma_dump_chunk(c);
591 c->usage_count++; 817 c->usage_count++;
592 spin_unlock_irqrestore(&r->chunk_list.lock, flags); 818 spin_unlock_irqrestore(&r->chunk_list.lock, flags);
593 return 0; 819 return 0;
594 } 820 }
595 821
596 result = dma_map_pages(r, _ALIGN_DOWN(phys_addr, 1 << r->page_size), 822 result = dma_sb_map_pages(r, aligned_phys, aligned_len, &c, iopte_flag);
597 _ALIGN_UP(len, 1 << r->page_size), &c);
598 823
599 if (result) { 824 if (result) {
600 *bus_addr = 0; 825 *bus_addr = 0;
601 DBG("%s:%d: dma_map_pages failed (%d)\n", 826 DBG("%s:%d: dma_sb_map_pages failed (%d)\n",
602 __func__, __LINE__, result); 827 __func__, __LINE__, result);
603 spin_unlock_irqrestore(&r->chunk_list.lock, flags); 828 spin_unlock_irqrestore(&r->chunk_list.lock, flags);
604 return result; 829 return result;
@@ -610,8 +835,57 @@ static int dma_map_area(struct ps3_dma_region *r, unsigned long virt_addr,
610 return result; 835 return result;
611} 836}
612 837
838static int dma_ioc0_map_area(struct ps3_dma_region *r, unsigned long virt_addr,
839 unsigned long len, unsigned long *bus_addr,
840 u64 iopte_flag)
841{
842 int result;
843 unsigned long flags;
844 struct dma_chunk *c;
845 unsigned long phys_addr = is_kernel_addr(virt_addr) ? __pa(virt_addr)
846 : virt_addr;
847 unsigned long aligned_phys = _ALIGN_DOWN(phys_addr, 1 << r->page_size);
848 unsigned long aligned_len = _ALIGN_UP(len + phys_addr - aligned_phys,
849 1 << r->page_size);
850
851 DBG(KERN_ERR "%s: vaddr=%#lx, len=%#lx\n", __func__,
852 virt_addr, len);
853 DBG(KERN_ERR "%s: ph=%#lx a_ph=%#lx a_l=%#lx\n", __func__,
854 phys_addr, aligned_phys, aligned_len);
855
856 spin_lock_irqsave(&r->chunk_list.lock, flags);
857 c = dma_find_chunk_lpar(r, ps3_mm_phys_to_lpar(phys_addr), len);
858
859 if (c) {
860 /* FIXME */
861 BUG();
862 *bus_addr = c->bus_addr + phys_addr - aligned_phys;
863 c->usage_count++;
864 spin_unlock_irqrestore(&r->chunk_list.lock, flags);
865 return 0;
866 }
867
868 result = dma_ioc0_map_pages(r, aligned_phys, aligned_len, &c,
869 iopte_flag);
870
871 if (result) {
872 *bus_addr = 0;
873 DBG("%s:%d: dma_ioc0_map_pages failed (%d)\n",
874 __func__, __LINE__, result);
875 spin_unlock_irqrestore(&r->chunk_list.lock, flags);
876 return result;
877 }
878 *bus_addr = c->bus_addr + phys_addr - aligned_phys;
879 DBG("%s: va=%#lx pa=%#lx a_pa=%#lx bus=%#lx\n", __func__,
880 virt_addr, phys_addr, aligned_phys, *bus_addr);
881 c->usage_count = 1;
882
883 spin_unlock_irqrestore(&r->chunk_list.lock, flags);
884 return result;
885}
886
613/** 887/**
614 * dma_unmap_area - Unmap an area of memory from a device dma region. 888 * dma_sb_unmap_area - Unmap an area of memory from a device dma region.
615 * @r: Pointer to a struct ps3_dma_region. 889 * @r: Pointer to a struct ps3_dma_region.
616 * @bus_addr: The starting ioc bus address of the area to unmap. 890 * @bus_addr: The starting ioc bus address of the area to unmap.
617 * @len: Length in bytes of the area to unmap. 891 * @len: Length in bytes of the area to unmap.
@@ -619,7 +893,7 @@ static int dma_map_area(struct ps3_dma_region *r, unsigned long virt_addr,
619 * This is the common dma unmap routine. 893 * This is the common dma unmap routine.
620 */ 894 */
621 895
622int dma_unmap_area(struct ps3_dma_region *r, unsigned long bus_addr, 896static int dma_sb_unmap_area(struct ps3_dma_region *r, unsigned long bus_addr,
623 unsigned long len) 897 unsigned long len)
624{ 898{
625 unsigned long flags; 899 unsigned long flags;
@@ -631,7 +905,8 @@ int dma_unmap_area(struct ps3_dma_region *r, unsigned long bus_addr,
631 if (!c) { 905 if (!c) {
632 unsigned long aligned_bus = _ALIGN_DOWN(bus_addr, 906 unsigned long aligned_bus = _ALIGN_DOWN(bus_addr,
633 1 << r->page_size); 907 1 << r->page_size);
634 unsigned long aligned_len = _ALIGN_UP(len, 1 << r->page_size); 908 unsigned long aligned_len = _ALIGN_UP(len + bus_addr
909 - aligned_bus, 1 << r->page_size);
635 DBG("%s:%d: not found: bus_addr %lxh\n", 910 DBG("%s:%d: not found: bus_addr %lxh\n",
636 __func__, __LINE__, bus_addr); 911 __func__, __LINE__, bus_addr);
637 DBG("%s:%d: not found: len %lxh\n", 912 DBG("%s:%d: not found: len %lxh\n",
@@ -647,94 +922,166 @@ int dma_unmap_area(struct ps3_dma_region *r, unsigned long bus_addr,
647 922
648 if (!c->usage_count) { 923 if (!c->usage_count) {
649 list_del(&c->link); 924 list_del(&c->link);
650 dma_free_chunk(c); 925 dma_sb_free_chunk(c);
651 } 926 }
652 927
653 spin_unlock_irqrestore(&r->chunk_list.lock, flags); 928 spin_unlock_irqrestore(&r->chunk_list.lock, flags);
654 return 0; 929 return 0;
655} 930}
656 931
932static int dma_ioc0_unmap_area(struct ps3_dma_region *r,
933 unsigned long bus_addr, unsigned long len)
934{
935 unsigned long flags;
936 struct dma_chunk *c;
937
938 DBG("%s: start a=%#lx l=%#lx\n", __func__, bus_addr, len);
939 spin_lock_irqsave(&r->chunk_list.lock, flags);
940 c = dma_find_chunk(r, bus_addr, len);
941
942 if (!c) {
943 unsigned long aligned_bus = _ALIGN_DOWN(bus_addr,
944 1 << r->page_size);
945 unsigned long aligned_len = _ALIGN_UP(len + bus_addr
946 - aligned_bus,
947 1 << r->page_size);
948 DBG("%s:%d: not found: bus_addr %lxh\n",
949 __func__, __LINE__, bus_addr);
950 DBG("%s:%d: not found: len %lxh\n",
951 __func__, __LINE__, len);
952 DBG("%s:%d: not found: aligned_bus %lxh\n",
953 __func__, __LINE__, aligned_bus);
954 DBG("%s:%d: not found: aligned_len %lxh\n",
955 __func__, __LINE__, aligned_len);
956 BUG();
957 }
958
959 c->usage_count--;
960
961 if (!c->usage_count) {
962 list_del(&c->link);
963 dma_ioc0_free_chunk(c);
964 }
965
966 spin_unlock_irqrestore(&r->chunk_list.lock, flags);
967 DBG("%s: end\n", __func__);
968 return 0;
969}
970
657/** 971/**
658 * dma_region_create_linear - Setup a linear dma maping for a device. 972 * dma_sb_region_create_linear - Setup a linear dma mapping for a device.
659 * @r: Pointer to a struct ps3_dma_region. 973 * @r: Pointer to a struct ps3_dma_region.
660 * 974 *
661 * This routine creates an HV dma region for the device and maps all available 975 * This routine creates an HV dma region for the device and maps all available
662 * ram into the io controller bus address space. 976 * ram into the io controller bus address space.
663 */ 977 */
664 978
665static int dma_region_create_linear(struct ps3_dma_region *r) 979static int dma_sb_region_create_linear(struct ps3_dma_region *r)
666{ 980{
667 int result; 981 int result;
668 unsigned long tmp; 982 unsigned long virt_addr, len, tmp;
669 983
670 /* force 16M dma pages for linear mapping */ 984 if (r->len > 16*1024*1024) { /* FIXME: need proper fix */
671 985 /* force 16M dma pages for linear mapping */
672 if (r->page_size != PS3_DMA_16M) { 986 if (r->page_size != PS3_DMA_16M) {
673 pr_info("%s:%d: forcing 16M pages for linear map\n", 987 pr_info("%s:%d: forcing 16M pages for linear map\n",
674 __func__, __LINE__); 988 __func__, __LINE__);
675 r->page_size = PS3_DMA_16M; 989 r->page_size = PS3_DMA_16M;
990 r->len = _ALIGN_UP(r->len, 1 << r->page_size);
991 }
676 } 992 }
677 993
678 result = dma_region_create(r); 994 result = dma_sb_region_create(r);
679 BUG_ON(result); 995 BUG_ON(result);
680 996
681 result = dma_map_area(r, map.rm.base, map.rm.size, &tmp); 997 if (r->offset < map.rm.size) {
682 BUG_ON(result); 998 /* Map (part of) 1st RAM chunk */
683 999 virt_addr = map.rm.base + r->offset;
684 if (USE_LPAR_ADDR) 1000 len = map.rm.size - r->offset;
685 result = dma_map_area(r, map.r1.base, map.r1.size, 1001 if (len > r->len)
686 &tmp); 1002 len = r->len;
687 else 1003 result = dma_sb_map_area(r, virt_addr, len, &tmp,
688 result = dma_map_area(r, map.rm.size, map.r1.size, 1004 IOPTE_PP_W | IOPTE_PP_R | IOPTE_SO_RW | IOPTE_M);
689 &tmp); 1005 BUG_ON(result);
1006 }
690 1007
691 BUG_ON(result); 1008 if (r->offset + r->len > map.rm.size) {
1009 /* Map (part of) 2nd RAM chunk */
1010 virt_addr = USE_LPAR_ADDR ? map.r1.base : map.rm.size;
1011 len = r->len;
1012 if (r->offset >= map.rm.size)
1013 virt_addr += r->offset - map.rm.size;
1014 else
1015 len -= map.rm.size - r->offset;
1016 result = dma_sb_map_area(r, virt_addr, len, &tmp,
1017 IOPTE_PP_W | IOPTE_PP_R | IOPTE_SO_RW | IOPTE_M);
1018 BUG_ON(result);
1019 }
692 1020
693 return result; 1021 return result;
694} 1022}
695 1023
696/** 1024/**
697 * dma_region_free_linear - Free a linear dma mapping for a device. 1025 * dma_sb_region_free_linear - Free a linear dma mapping for a device.
698 * @r: Pointer to a struct ps3_dma_region. 1026 * @r: Pointer to a struct ps3_dma_region.
699 * 1027 *
700 * This routine will unmap all mapped areas and free the HV dma region. 1028 * This routine will unmap all mapped areas and free the HV dma region.
701 */ 1029 */
702 1030
703static int dma_region_free_linear(struct ps3_dma_region *r) 1031static int dma_sb_region_free_linear(struct ps3_dma_region *r)
704{ 1032{
705 int result; 1033 int result;
1034 unsigned long bus_addr, len, lpar_addr;
1035
1036 if (r->offset < map.rm.size) {
1037 /* Unmap (part of) 1st RAM chunk */
1038 lpar_addr = map.rm.base + r->offset;
1039 len = map.rm.size - r->offset;
1040 if (len > r->len)
1041 len = r->len;
1042 bus_addr = dma_sb_lpar_to_bus(r, lpar_addr);
1043 result = dma_sb_unmap_area(r, bus_addr, len);
1044 BUG_ON(result);
1045 }
706 1046
707 result = dma_unmap_area(r, dma_lpar_to_bus(r, 0), map.rm.size); 1047 if (r->offset + r->len > map.rm.size) {
708 BUG_ON(result); 1048 /* Unmap (part of) 2nd RAM chunk */
709 1049 lpar_addr = map.r1.base;
710 result = dma_unmap_area(r, dma_lpar_to_bus(r, map.r1.base), 1050 len = r->len;
711 map.r1.size); 1051 if (r->offset >= map.rm.size)
712 BUG_ON(result); 1052 lpar_addr += r->offset - map.rm.size;
1053 else
1054 len -= map.rm.size - r->offset;
1055 bus_addr = dma_sb_lpar_to_bus(r, lpar_addr);
1056 result = dma_sb_unmap_area(r, bus_addr, len);
1057 BUG_ON(result);
1058 }
713 1059
714 result = dma_region_free(r); 1060 result = dma_sb_region_free(r);
715 BUG_ON(result); 1061 BUG_ON(result);
716 1062
717 return result; 1063 return result;
718} 1064}
719 1065
720/** 1066/**
721 * dma_map_area_linear - Map an area of memory into a device dma region. 1067 * dma_sb_map_area_linear - Map an area of memory into a device dma region.
722 * @r: Pointer to a struct ps3_dma_region. 1068 * @r: Pointer to a struct ps3_dma_region.
723 * @virt_addr: Starting virtual address of the area to map. 1069 * @virt_addr: Starting virtual address of the area to map.
724 * @len: Length in bytes of the area to map. 1070 * @len: Length in bytes of the area to map.
725 * @bus_addr: A pointer to return the starting ioc bus address of the area to 1071 * @bus_addr: A pointer to return the starting ioc bus address of the area to
726 * map. 1072 * map.
727 * 1073 *
728 * This routine just returns the coresponding bus address. Actual mapping 1074 * This routine just returns the corresponding bus address. Actual mapping
729 * occurs in dma_region_create_linear(). 1075 * occurs in dma_region_create_linear().
730 */ 1076 */
731 1077
732static int dma_map_area_linear(struct ps3_dma_region *r, 1078static int dma_sb_map_area_linear(struct ps3_dma_region *r,
733 unsigned long virt_addr, unsigned long len, unsigned long *bus_addr) 1079 unsigned long virt_addr, unsigned long len, unsigned long *bus_addr,
1080 u64 iopte_flag)
734{ 1081{
735 unsigned long phys_addr = is_kernel_addr(virt_addr) ? __pa(virt_addr) 1082 unsigned long phys_addr = is_kernel_addr(virt_addr) ? __pa(virt_addr)
736 : virt_addr; 1083 : virt_addr;
737 *bus_addr = dma_lpar_to_bus(r, ps3_mm_phys_to_lpar(phys_addr)); 1084 *bus_addr = dma_sb_lpar_to_bus(r, ps3_mm_phys_to_lpar(phys_addr));
738 return 0; 1085 return 0;
739} 1086}
740 1087
@@ -744,42 +1091,98 @@ static int dma_map_area_linear(struct ps3_dma_region *r,
744 * @bus_addr: The starting ioc bus address of the area to unmap. 1091 * @bus_addr: The starting ioc bus address of the area to unmap.
745 * @len: Length in bytes of the area to unmap. 1092 * @len: Length in bytes of the area to unmap.
746 * 1093 *
747 * This routine does nothing. Unmapping occurs in dma_region_free_linear(). 1094 * This routine does nothing. Unmapping occurs in dma_sb_region_free_linear().
748 */ 1095 */
749 1096
750static int dma_unmap_area_linear(struct ps3_dma_region *r, 1097static int dma_sb_unmap_area_linear(struct ps3_dma_region *r,
751 unsigned long bus_addr, unsigned long len) 1098 unsigned long bus_addr, unsigned long len)
752{ 1099{
753 return 0; 1100 return 0;
1101};
1102
1103static const struct ps3_dma_region_ops ps3_dma_sb_region_ops = {
1104 .create = dma_sb_region_create,
1105 .free = dma_sb_region_free,
1106 .map = dma_sb_map_area,
1107 .unmap = dma_sb_unmap_area
1108};
1109
1110static const struct ps3_dma_region_ops ps3_dma_sb_region_linear_ops = {
1111 .create = dma_sb_region_create_linear,
1112 .free = dma_sb_region_free_linear,
1113 .map = dma_sb_map_area_linear,
1114 .unmap = dma_sb_unmap_area_linear
1115};
1116
1117static const struct ps3_dma_region_ops ps3_dma_ioc0_region_ops = {
1118 .create = dma_ioc0_region_create,
1119 .free = dma_ioc0_region_free,
1120 .map = dma_ioc0_map_area,
1121 .unmap = dma_ioc0_unmap_area
1122};
1123
1124int ps3_dma_region_init(struct ps3_system_bus_device *dev,
1125 struct ps3_dma_region *r, enum ps3_dma_page_size page_size,
1126 enum ps3_dma_region_type region_type, void *addr, unsigned long len)
1127{
1128 unsigned long lpar_addr;
1129
1130 lpar_addr = addr ? ps3_mm_phys_to_lpar(__pa(addr)) : 0;
1131
1132 r->dev = dev;
1133 r->page_size = page_size;
1134 r->region_type = region_type;
1135 r->offset = lpar_addr;
1136 if (r->offset >= map.rm.size)
1137 r->offset -= map.r1.offset;
1138 r->len = len ? len : _ALIGN_UP(map.total, 1 << r->page_size);
1139
1140 switch (dev->dev_type) {
1141 case PS3_DEVICE_TYPE_SB:
1142 r->region_ops = (USE_DYNAMIC_DMA)
1143 ? &ps3_dma_sb_region_ops
1144 : &ps3_dma_sb_region_linear_ops;
1145 break;
1146 case PS3_DEVICE_TYPE_IOC0:
1147 r->region_ops = &ps3_dma_ioc0_region_ops;
1148 break;
1149 default:
1150 BUG();
1151 return -EINVAL;
1152 }
1153 return 0;
754} 1154}
1155EXPORT_SYMBOL(ps3_dma_region_init);
755 1156
756int ps3_dma_region_create(struct ps3_dma_region *r) 1157int ps3_dma_region_create(struct ps3_dma_region *r)
757{ 1158{
758 return (USE_DYNAMIC_DMA) 1159 BUG_ON(!r);
759 ? dma_region_create(r) 1160 BUG_ON(!r->region_ops);
760 : dma_region_create_linear(r); 1161 BUG_ON(!r->region_ops->create);
1162 return r->region_ops->create(r);
761} 1163}
1164EXPORT_SYMBOL(ps3_dma_region_create);
762 1165
763int ps3_dma_region_free(struct ps3_dma_region *r) 1166int ps3_dma_region_free(struct ps3_dma_region *r)
764{ 1167{
765 return (USE_DYNAMIC_DMA) 1168 BUG_ON(!r);
766 ? dma_region_free(r) 1169 BUG_ON(!r->region_ops);
767 : dma_region_free_linear(r); 1170 BUG_ON(!r->region_ops->free);
1171 return r->region_ops->free(r);
768} 1172}
1173EXPORT_SYMBOL(ps3_dma_region_free);
769 1174
770int ps3_dma_map(struct ps3_dma_region *r, unsigned long virt_addr, 1175int ps3_dma_map(struct ps3_dma_region *r, unsigned long virt_addr,
771 unsigned long len, unsigned long *bus_addr) 1176 unsigned long len, unsigned long *bus_addr,
1177 u64 iopte_flag)
772{ 1178{
773 return (USE_DYNAMIC_DMA) 1179 return r->region_ops->map(r, virt_addr, len, bus_addr, iopte_flag);
774 ? dma_map_area(r, virt_addr, len, bus_addr)
775 : dma_map_area_linear(r, virt_addr, len, bus_addr);
776} 1180}
777 1181
778int ps3_dma_unmap(struct ps3_dma_region *r, unsigned long bus_addr, 1182int ps3_dma_unmap(struct ps3_dma_region *r, unsigned long bus_addr,
779 unsigned long len) 1183 unsigned long len)
780{ 1184{
781 return (USE_DYNAMIC_DMA) ? dma_unmap_area(r, bus_addr, len) 1185 return r->region_ops->unmap(r, bus_addr, len);
782 : dma_unmap_area_linear(r, bus_addr, len);
783} 1186}
784 1187
785/*============================================================================*/ 1188/*============================================================================*/
@@ -810,12 +1213,13 @@ void __init ps3_mm_init(void)
810 BUG_ON(map.rm.base); 1213 BUG_ON(map.rm.base);
811 BUG_ON(!map.rm.size); 1214 BUG_ON(!map.rm.size);
812 1215
813 lmb_add(map.rm.base, map.rm.size);
814 lmb_analyze();
815 1216
816 /* arrange to do this in ps3_mm_add_memory */ 1217 /* arrange to do this in ps3_mm_add_memory */
817 ps3_mm_region_create(&map.r1, map.total - map.rm.size); 1218 ps3_mm_region_create(&map.r1, map.total - map.rm.size);
818 1219
1220 /* correct map.total for the real total amount of memory we use */
1221 map.total = map.rm.size + map.r1.size;
1222
819 DBG(" <- %s:%d\n", __func__, __LINE__); 1223 DBG(" <- %s:%d\n", __func__, __LINE__);
820} 1224}
821 1225
diff --git a/arch/powerpc/platforms/ps3/os-area.c b/arch/powerpc/platforms/ps3/os-area.c
index 5c3da08bc0c4..b70e474014f0 100644
--- a/arch/powerpc/platforms/ps3/os-area.c
+++ b/arch/powerpc/platforms/ps3/os-area.c
@@ -133,7 +133,7 @@ struct saved_params {
133} static saved_params; 133} static saved_params;
134 134
135#define dump_header(_a) _dump_header(_a, __func__, __LINE__) 135#define dump_header(_a) _dump_header(_a, __func__, __LINE__)
136static void _dump_header(const struct os_area_header __iomem *h, const char* func, 136static void _dump_header(const struct os_area_header *h, const char *func,
137 int line) 137 int line)
138{ 138{
139 pr_debug("%s:%d: h.magic_num: '%s'\n", func, line, 139 pr_debug("%s:%d: h.magic_num: '%s'\n", func, line,
@@ -151,7 +151,7 @@ static void _dump_header(const struct os_area_header __iomem *h, const char* fun
151} 151}
152 152
153#define dump_params(_a) _dump_params(_a, __func__, __LINE__) 153#define dump_params(_a) _dump_params(_a, __func__, __LINE__)
154static void _dump_params(const struct os_area_params __iomem *p, const char* func, 154static void _dump_params(const struct os_area_params *p, const char *func,
155 int line) 155 int line)
156{ 156{
157 pr_debug("%s:%d: p.boot_flag: %u\n", func, line, p->boot_flag); 157 pr_debug("%s:%d: p.boot_flag: %u\n", func, line, p->boot_flag);
diff --git a/arch/powerpc/platforms/ps3/platform.h b/arch/powerpc/platforms/ps3/platform.h
index ca04f03305c7..87d52060fec0 100644
--- a/arch/powerpc/platforms/ps3/platform.h
+++ b/arch/powerpc/platforms/ps3/platform.h
@@ -41,6 +41,7 @@ void ps3_mm_shutdown(void);
41/* irq */ 41/* irq */
42 42
43void ps3_init_IRQ(void); 43void ps3_init_IRQ(void);
44void ps3_shutdown_IRQ(int cpu);
44void __init ps3_register_ipi_debug_brk(unsigned int cpu, unsigned int virq); 45void __init ps3_register_ipi_debug_brk(unsigned int cpu, unsigned int virq);
45 46
46/* smp */ 47/* smp */
@@ -82,6 +83,7 @@ enum ps3_dev_type {
82 PS3_DEV_TYPE_STOR_ROM = TYPE_ROM, /* 5 */ 83 PS3_DEV_TYPE_STOR_ROM = TYPE_ROM, /* 5 */
83 PS3_DEV_TYPE_SB_GPIO = 6, 84 PS3_DEV_TYPE_SB_GPIO = 6,
84 PS3_DEV_TYPE_STOR_FLASH = TYPE_RBC, /* 14 */ 85 PS3_DEV_TYPE_STOR_FLASH = TYPE_RBC, /* 14 */
86 PS3_DEV_TYPE_NOACCESS = 255,
85}; 87};
86 88
87int ps3_repository_read_bus_str(unsigned int bus_index, const char *bus_str, 89int ps3_repository_read_bus_str(unsigned int bus_index, const char *bus_str,
@@ -129,24 +131,28 @@ int ps3_repository_read_dev_reg(unsigned int bus_index,
129/* repository bus enumerators */ 131/* repository bus enumerators */
130 132
131struct ps3_repository_device { 133struct ps3_repository_device {
134 enum ps3_bus_type bus_type;
132 unsigned int bus_index; 135 unsigned int bus_index;
136 unsigned int bus_id;
137 enum ps3_dev_type dev_type;
133 unsigned int dev_index; 138 unsigned int dev_index;
134 struct ps3_device_id did; 139 unsigned int dev_id;
135}; 140};
136 141
137int ps3_repository_find_device(enum ps3_bus_type bus_type, 142static inline struct ps3_repository_device *ps3_repository_bump_device(
138 enum ps3_dev_type dev_type, 143 struct ps3_repository_device *repo)
139 const struct ps3_repository_device *start_dev,
140 struct ps3_repository_device *dev);
141static inline int ps3_repository_find_first_device(
142 enum ps3_bus_type bus_type, enum ps3_dev_type dev_type,
143 struct ps3_repository_device *dev)
144{ 144{
145 return ps3_repository_find_device(bus_type, dev_type, NULL, dev); 145 repo->dev_index++;
146 return repo;
146} 147}
147int ps3_repository_find_interrupt(const struct ps3_repository_device *dev, 148int ps3_repository_find_device(struct ps3_repository_device *repo);
149int ps3_repository_find_devices(enum ps3_bus_type bus_type,
150 int (*callback)(const struct ps3_repository_device *repo));
151int ps3_repository_find_bus(enum ps3_bus_type bus_type, unsigned int from,
152 unsigned int *bus_index);
153int ps3_repository_find_interrupt(const struct ps3_repository_device *repo,
148 enum ps3_interrupt_type intr_type, unsigned int *interrupt_id); 154 enum ps3_interrupt_type intr_type, unsigned int *interrupt_id);
149int ps3_repository_find_reg(const struct ps3_repository_device *dev, 155int ps3_repository_find_reg(const struct ps3_repository_device *repo,
150 enum ps3_reg_type reg_type, u64 *bus_addr, u64 *len); 156 enum ps3_reg_type reg_type, u64 *bus_addr, u64 *len);
151 157
152/* repository block device info */ 158/* repository block device info */
@@ -216,4 +222,19 @@ int ps3_repository_read_num_spu_resource_id(unsigned int *num_resource_id);
216int ps3_repository_read_spu_resource_id(unsigned int res_index, 222int ps3_repository_read_spu_resource_id(unsigned int res_index,
217 enum ps3_spu_resource_type* resource_type, unsigned int *resource_id); 223 enum ps3_spu_resource_type* resource_type, unsigned int *resource_id);
218 224
225/* repository vuart info */
226
227int ps3_repository_read_vuart_av_port(unsigned int *port);
228int ps3_repository_read_vuart_sysmgr_port(unsigned int *port);
229
230/* Page table entries */
231#define IOPTE_PP_W 0x8000000000000000ul /* protection: write */
232#define IOPTE_PP_R 0x4000000000000000ul /* protection: read */
233#define IOPTE_M 0x2000000000000000ul /* coherency required */
234#define IOPTE_SO_R 0x1000000000000000ul /* ordering: writes */
235#define IOPTE_SO_RW 0x1800000000000000ul /* ordering: r & w */
236#define IOPTE_RPN_Mask 0x07fffffffffff000ul /* RPN */
237#define IOPTE_H 0x0000000000000800ul /* cache hint */
238#define IOPTE_IOID_Mask 0x00000000000007fful /* ioid */
239
219#endif 240#endif
diff --git a/arch/powerpc/platforms/ps3/repository.c b/arch/powerpc/platforms/ps3/repository.c
index ae586a0e5d3f..8cc37cfea0f2 100644
--- a/arch/powerpc/platforms/ps3/repository.c
+++ b/arch/powerpc/platforms/ps3/repository.c
@@ -138,7 +138,7 @@ static int read_node(unsigned int lpar_id, u64 n1, u64 n2, u64 n3, u64 n4,
138 pr_debug("%s:%d: lv1_get_repository_node_value failed: %s\n", 138 pr_debug("%s:%d: lv1_get_repository_node_value failed: %s\n",
139 __func__, __LINE__, ps3_result(result)); 139 __func__, __LINE__, ps3_result(result));
140 dump_node_name(lpar_id, n1, n2, n3, n4); 140 dump_node_name(lpar_id, n1, n2, n3, n4);
141 return result; 141 return -ENOENT;
142 } 142 }
143 143
144 dump_node(lpar_id, n1, n2, n3, n4, v1, v2); 144 dump_node(lpar_id, n1, n2, n3, n4, v1, v2);
@@ -155,7 +155,7 @@ static int read_node(unsigned int lpar_id, u64 n1, u64 n2, u64 n3, u64 n4,
155 pr_debug("%s:%d: warning: discarding non-zero v2: %016lx\n", 155 pr_debug("%s:%d: warning: discarding non-zero v2: %016lx\n",
156 __func__, __LINE__, v2); 156 __func__, __LINE__, v2);
157 157
158 return result; 158 return 0;
159} 159}
160 160
161int ps3_repository_read_bus_str(unsigned int bus_index, const char *bus_str, 161int ps3_repository_read_bus_str(unsigned int bus_index, const char *bus_str,
@@ -314,324 +314,140 @@ int ps3_repository_read_dev_reg(unsigned int bus_index,
314 reg_index, bus_addr, len); 314 reg_index, bus_addr, len);
315} 315}
316 316
317#if defined(DEBUG)
318int ps3_repository_dump_resource_info(unsigned int bus_index,
319 unsigned int dev_index)
320{
321 int result = 0;
322 unsigned int res_index;
323 317
324 pr_debug(" -> %s:%d: (%u:%u)\n", __func__, __LINE__,
325 bus_index, dev_index);
326 318
327 for (res_index = 0; res_index < 10; res_index++) { 319int ps3_repository_find_device(struct ps3_repository_device *repo)
328 enum ps3_interrupt_type intr_type; 320{
329 unsigned int interrupt_id; 321 int result;
322 struct ps3_repository_device tmp = *repo;
323 unsigned int num_dev;
330 324
331 result = ps3_repository_read_dev_intr(bus_index, dev_index, 325 BUG_ON(repo->bus_index > 10);
332 res_index, &intr_type, &interrupt_id); 326 BUG_ON(repo->dev_index > 10);
333 327
334 if (result) { 328 result = ps3_repository_read_bus_num_dev(tmp.bus_index, &num_dev);
335 if (result != LV1_NO_ENTRY)
336 pr_debug("%s:%d ps3_repository_read_dev_intr"
337 " (%u:%u) failed\n", __func__, __LINE__,
338 bus_index, dev_index);
339 break;
340 }
341 329
342 pr_debug("%s:%d (%u:%u) intr_type %u, interrupt_id %u\n", 330 if (result) {
343 __func__, __LINE__, bus_index, dev_index, intr_type, 331 pr_debug("%s:%d read_bus_num_dev failed\n", __func__, __LINE__);
344 interrupt_id); 332 return result;
345 } 333 }
346 334
347 for (res_index = 0; res_index < 10; res_index++) { 335 pr_debug("%s:%d: bus_type %u, bus_index %u, bus_id %u, num_dev %u\n",
348 enum ps3_reg_type reg_type; 336 __func__, __LINE__, tmp.bus_type, tmp.bus_index, tmp.bus_id,
349 u64 bus_addr; 337 num_dev);
350 u64 len;
351
352 result = ps3_repository_read_dev_reg(bus_index, dev_index,
353 res_index, &reg_type, &bus_addr, &len);
354 338
355 if (result) { 339 if (tmp.dev_index >= num_dev) {
356 if (result != LV1_NO_ENTRY) 340 pr_debug("%s:%d: no device found\n", __func__, __LINE__);
357 pr_debug("%s:%d ps3_repository_read_dev_reg" 341 return -ENODEV;
358 " (%u:%u) failed\n", __func__, __LINE__,
359 bus_index, dev_index);
360 break;
361 }
362
363 pr_debug("%s:%d (%u:%u) reg_type %u, bus_addr %lxh, len %lxh\n",
364 __func__, __LINE__, bus_index, dev_index, reg_type,
365 bus_addr, len);
366 } 342 }
367 343
368 pr_debug(" <- %s:%d\n", __func__, __LINE__); 344 result = ps3_repository_read_dev_type(tmp.bus_index, tmp.dev_index,
369 return result; 345 &tmp.dev_type);
370}
371
372static int dump_stor_dev_info(unsigned int bus_index, unsigned int dev_index)
373{
374 int result = 0;
375 unsigned int num_regions, region_index;
376 u64 port, blk_size, num_blocks;
377
378 pr_debug(" -> %s:%d: (%u:%u)\n", __func__, __LINE__,
379 bus_index, dev_index);
380 346
381 result = ps3_repository_read_stor_dev_info(bus_index, dev_index, &port,
382 &blk_size, &num_blocks, &num_regions);
383 if (result) { 347 if (result) {
384 pr_debug("%s:%d ps3_repository_read_stor_dev_info" 348 pr_debug("%s:%d read_dev_type failed\n", __func__, __LINE__);
385 " (%u:%u) failed\n", __func__, __LINE__, 349 return result;
386 bus_index, dev_index);
387 goto out;
388 } 350 }
389 351
390 pr_debug("%s:%d (%u:%u): port %lu, blk_size %lu, num_blocks " 352 result = ps3_repository_read_dev_id(tmp.bus_index, tmp.dev_index,
391 "%lu, num_regions %u\n", 353 &tmp.dev_id);
392 __func__, __LINE__, bus_index, dev_index, port,
393 blk_size, num_blocks, num_regions);
394
395 for (region_index = 0; region_index < num_regions; region_index++) {
396 unsigned int region_id;
397 u64 region_start, region_size;
398
399 result = ps3_repository_read_stor_dev_region(bus_index,
400 dev_index, region_index, &region_id, &region_start,
401 &region_size);
402 if (result) {
403 pr_debug("%s:%d ps3_repository_read_stor_dev_region"
404 " (%u:%u) failed\n", __func__, __LINE__,
405 bus_index, dev_index);
406 break;
407 }
408 354
409 pr_debug("%s:%d (%u:%u) region_id %u, start %lxh, size %lxh\n", 355 if (result) {
410 __func__, __LINE__, bus_index, dev_index, region_id, 356 pr_debug("%s:%d ps3_repository_read_dev_id failed\n", __func__,
411 region_start, region_size); 357 __LINE__);
358 return result;
412 } 359 }
413 360
414out: 361 pr_debug("%s:%d: found: dev_type %u, dev_index %u, dev_id %u\n",
415 pr_debug(" <- %s:%d\n", __func__, __LINE__); 362 __func__, __LINE__, tmp.dev_type, tmp.dev_index, tmp.dev_id);
416 return result;
417}
418
419static int dump_device_info(unsigned int bus_index, enum ps3_bus_type bus_type,
420 unsigned int num_dev)
421{
422 int result = 0;
423 unsigned int dev_index;
424
425 pr_debug(" -> %s:%d: bus_%u\n", __func__, __LINE__, bus_index);
426
427 for (dev_index = 0; dev_index < num_dev; dev_index++) {
428 enum ps3_dev_type dev_type;
429 unsigned int dev_id;
430
431 result = ps3_repository_read_dev_type(bus_index, dev_index,
432 &dev_type);
433
434 if (result) {
435 pr_debug("%s:%d ps3_repository_read_dev_type"
436 " (%u:%u) failed\n", __func__, __LINE__,
437 bus_index, dev_index);
438 break;
439 }
440
441 result = ps3_repository_read_dev_id(bus_index, dev_index,
442 &dev_id);
443
444 if (result) {
445 pr_debug("%s:%d ps3_repository_read_dev_id"
446 " (%u:%u) failed\n", __func__, __LINE__,
447 bus_index, dev_index);
448 continue;
449 }
450 363
451 pr_debug("%s:%d (%u:%u): dev_type %u, dev_id %u\n", __func__, 364 *repo = tmp;
452 __LINE__, bus_index, dev_index, dev_type, dev_id); 365 return 0;
453
454 ps3_repository_dump_resource_info(bus_index, dev_index);
455
456 if (bus_type == PS3_BUS_TYPE_STORAGE)
457 dump_stor_dev_info(bus_index, dev_index);
458 }
459
460 pr_debug(" <- %s:%d\n", __func__, __LINE__);
461 return result;
462} 366}
463 367
464int ps3_repository_dump_bus_info(void) 368int __devinit ps3_repository_find_devices(enum ps3_bus_type bus_type,
369 int (*callback)(const struct ps3_repository_device *repo))
465{ 370{
466 int result = 0; 371 int result = 0;
467 unsigned int bus_index; 372 struct ps3_repository_device repo;
468 373
469 pr_debug(" -> %s:%d\n", __func__, __LINE__); 374 pr_debug(" -> %s:%d: find bus_type %u\n", __func__, __LINE__, bus_type);
470 375
471 for (bus_index = 0; bus_index < 10; bus_index++) { 376 for (repo.bus_index = 0; repo.bus_index < 10; repo.bus_index++) {
472 enum ps3_bus_type bus_type;
473 unsigned int bus_id;
474 unsigned int num_dev;
475 377
476 result = ps3_repository_read_bus_type(bus_index, &bus_type); 378 result = ps3_repository_read_bus_type(repo.bus_index,
379 &repo.bus_type);
477 380
478 if (result) { 381 if (result) {
479 pr_debug("%s:%d read_bus_type(%u) failed\n", 382 pr_debug("%s:%d read_bus_type(%u) failed\n",
480 __func__, __LINE__, bus_index); 383 __func__, __LINE__, repo.bus_index);
481 break; 384 break;
482 } 385 }
483 386
484 result = ps3_repository_read_bus_id(bus_index, &bus_id); 387 if (repo.bus_type != bus_type) {
485 388 pr_debug("%s:%d: skip, bus_type %u\n", __func__,
486 if (result) { 389 __LINE__, repo.bus_type);
487 pr_debug("%s:%d read_bus_id(%u) failed\n",
488 __func__, __LINE__, bus_index);
489 continue; 390 continue;
490 } 391 }
491 392
492 if (bus_index != bus_id) 393 result = ps3_repository_read_bus_id(repo.bus_index,
493 pr_debug("%s:%d bus_index != bus_id\n", 394 &repo.bus_id);
494 __func__, __LINE__);
495
496 result = ps3_repository_read_bus_num_dev(bus_index, &num_dev);
497 395
498 if (result) { 396 if (result) {
499 pr_debug("%s:%d read_bus_num_dev(%u) failed\n", 397 pr_debug("%s:%d read_bus_id(%u) failed\n",
500 __func__, __LINE__, bus_index); 398 __func__, __LINE__, repo.bus_index);
501 continue; 399 continue;
502 } 400 }
503 401
504 pr_debug("%s:%d bus_%u: bus_type %u, bus_id %u, num_dev %u\n", 402 for (repo.dev_index = 0; ; repo.dev_index++) {
505 __func__, __LINE__, bus_index, bus_type, bus_id, 403 result = ps3_repository_find_device(&repo);
506 num_dev);
507 404
508 dump_device_info(bus_index, bus_type, num_dev); 405 if (result == -ENODEV) {
509 } 406 result = 0;
407 break;
408 } else if (result)
409 break;
510 410
511 pr_debug(" <- %s:%d\n", __func__, __LINE__); 411 result = callback(&repo);
512 return result;
513}
514#endif /* defined(DEBUG) */
515
516static int find_device(unsigned int bus_index, unsigned int num_dev,
517 unsigned int start_dev_index, enum ps3_dev_type dev_type,
518 struct ps3_repository_device *dev)
519{
520 int result = 0;
521 unsigned int dev_index;
522 412
523 pr_debug("%s:%d: find dev_type %u\n", __func__, __LINE__, dev_type); 413 if (result) {
524 414 pr_debug("%s:%d: abort at callback\n", __func__,
525 dev->dev_index = UINT_MAX; 415 __LINE__);
526 416 break;
527 for (dev_index = start_dev_index; dev_index < num_dev; dev_index++) { 417 }
528 enum ps3_dev_type x;
529
530 result = ps3_repository_read_dev_type(bus_index, dev_index,
531 &x);
532
533 if (result) {
534 pr_debug("%s:%d read_dev_type failed\n",
535 __func__, __LINE__);
536 return result;
537 } 418 }
538 419 break;
539 if (x == dev_type)
540 break;
541 }
542
543 if (dev_index == num_dev)
544 return -1;
545
546 pr_debug("%s:%d: found dev_type %u at dev_index %u\n",
547 __func__, __LINE__, dev_type, dev_index);
548
549 result = ps3_repository_read_dev_id(bus_index, dev_index,
550 &dev->did.dev_id);
551
552 if (result) {
553 pr_debug("%s:%d read_dev_id failed\n",
554 __func__, __LINE__);
555 return result;
556 } 420 }
557 421
558 dev->dev_index = dev_index; 422 pr_debug(" <- %s:%d\n", __func__, __LINE__);
559
560 pr_debug("%s:%d found: dev_id %u\n", __func__, __LINE__,
561 dev->did.dev_id);
562
563 return result; 423 return result;
564} 424}
565 425
566int ps3_repository_find_device (enum ps3_bus_type bus_type, 426int ps3_repository_find_bus(enum ps3_bus_type bus_type, unsigned int from,
567 enum ps3_dev_type dev_type, 427 unsigned int *bus_index)
568 const struct ps3_repository_device *start_dev,
569 struct ps3_repository_device *dev)
570{ 428{
571 int result = 0; 429 unsigned int i;
572 unsigned int bus_index; 430 enum ps3_bus_type type;
573 unsigned int num_dev; 431 int error;
574
575 pr_debug("%s:%d: find bus_type %u, dev_type %u\n", __func__, __LINE__,
576 bus_type, dev_type);
577
578 BUG_ON(start_dev && start_dev->bus_index > 10);
579
580 for (bus_index = start_dev ? start_dev->bus_index : 0; bus_index < 10;
581 bus_index++) {
582 enum ps3_bus_type x;
583
584 result = ps3_repository_read_bus_type(bus_index, &x);
585 432
586 if (result) { 433 for (i = from; i < 10; i++) {
434 error = ps3_repository_read_bus_type(i, &type);
435 if (error) {
587 pr_debug("%s:%d read_bus_type failed\n", 436 pr_debug("%s:%d read_bus_type failed\n",
588 __func__, __LINE__); 437 __func__, __LINE__);
589 dev->bus_index = UINT_MAX; 438 *bus_index = UINT_MAX;
590 return result; 439 return error;
440 }
441 if (type == bus_type) {
442 *bus_index = i;
443 return 0;
591 } 444 }
592 if (x == bus_type)
593 break;
594 }
595
596 if (bus_index >= 10)
597 return -ENODEV;
598
599 pr_debug("%s:%d: found bus_type %u at bus_index %u\n",
600 __func__, __LINE__, bus_type, bus_index);
601
602 result = ps3_repository_read_bus_num_dev(bus_index, &num_dev);
603
604 if (result) {
605 pr_debug("%s:%d read_bus_num_dev failed\n",
606 __func__, __LINE__);
607 return result;
608 }
609
610 result = find_device(bus_index, num_dev, start_dev
611 ? start_dev->dev_index + 1 : 0, dev_type, dev);
612
613 if (result) {
614 pr_debug("%s:%d get_did failed\n", __func__, __LINE__);
615 return result;
616 }
617
618 result = ps3_repository_read_bus_id(bus_index, &dev->did.bus_id);
619
620 if (result) {
621 pr_debug("%s:%d read_bus_id failed\n",
622 __func__, __LINE__);
623 return result;
624 } 445 }
625 446 *bus_index = UINT_MAX;
626 dev->bus_index = bus_index; 447 return -ENODEV;
627
628 pr_debug("%s:%d found: bus_id %u, dev_id %u\n",
629 __func__, __LINE__, dev->did.bus_id, dev->did.dev_id);
630
631 return result;
632} 448}
633 449
634int ps3_repository_find_interrupt(const struct ps3_repository_device *dev, 450int ps3_repository_find_interrupt(const struct ps3_repository_device *repo,
635 enum ps3_interrupt_type intr_type, unsigned int *interrupt_id) 451 enum ps3_interrupt_type intr_type, unsigned int *interrupt_id)
636{ 452{
637 int result = 0; 453 int result = 0;
@@ -645,8 +461,8 @@ int ps3_repository_find_interrupt(const struct ps3_repository_device *dev,
645 enum ps3_interrupt_type t; 461 enum ps3_interrupt_type t;
646 unsigned int id; 462 unsigned int id;
647 463
648 result = ps3_repository_read_dev_intr(dev->bus_index, 464 result = ps3_repository_read_dev_intr(repo->bus_index,
649 dev->dev_index, res_index, &t, &id); 465 repo->dev_index, res_index, &t, &id);
650 466
651 if (result) { 467 if (result) {
652 pr_debug("%s:%d read_dev_intr failed\n", 468 pr_debug("%s:%d read_dev_intr failed\n",
@@ -669,7 +485,7 @@ int ps3_repository_find_interrupt(const struct ps3_repository_device *dev,
669 return result; 485 return result;
670} 486}
671 487
672int ps3_repository_find_reg(const struct ps3_repository_device *dev, 488int ps3_repository_find_reg(const struct ps3_repository_device *repo,
673 enum ps3_reg_type reg_type, u64 *bus_addr, u64 *len) 489 enum ps3_reg_type reg_type, u64 *bus_addr, u64 *len)
674{ 490{
675 int result = 0; 491 int result = 0;
@@ -684,8 +500,8 @@ int ps3_repository_find_reg(const struct ps3_repository_device *dev,
684 u64 a; 500 u64 a;
685 u64 l; 501 u64 l;
686 502
687 result = ps3_repository_read_dev_reg(dev->bus_index, 503 result = ps3_repository_read_dev_reg(repo->bus_index,
688 dev->dev_index, res_index, &t, &a, &l); 504 repo->dev_index, res_index, &t, &a, &l);
689 505
690 if (result) { 506 if (result) {
691 pr_debug("%s:%d read_dev_reg failed\n", 507 pr_debug("%s:%d read_dev_reg failed\n",
@@ -965,6 +781,36 @@ int ps3_repository_read_boot_dat_size(unsigned int *size)
965 return result; 781 return result;
966} 782}
967 783
784int ps3_repository_read_vuart_av_port(unsigned int *port)
785{
786 int result;
787 u64 v1;
788
789 result = read_node(PS3_LPAR_ID_CURRENT,
790 make_first_field("bi", 0),
791 make_field("vir_uart", 0),
792 make_field("port", 0),
793 make_field("avset", 0),
794 &v1, 0);
795 *port = v1;
796 return result;
797}
798
799int ps3_repository_read_vuart_sysmgr_port(unsigned int *port)
800{
801 int result;
802 u64 v1;
803
804 result = read_node(PS3_LPAR_ID_CURRENT,
805 make_first_field("bi", 0),
806 make_field("vir_uart", 0),
807 make_field("port", 0),
808 make_field("sysmgr", 0),
809 &v1, 0);
810 *port = v1;
811 return result;
812}
813
968/** 814/**
969 * ps3_repository_read_boot_dat_info - Get address and size of cell_ext_os_area. 815 * ps3_repository_read_boot_dat_info - Get address and size of cell_ext_os_area.
970 * address: lpar address of cell_ext_os_area 816 * address: lpar address of cell_ext_os_area
@@ -1026,3 +872,205 @@ int ps3_repository_read_be_tb_freq(unsigned int be_index, u64 *tb_freq)
1026 return result ? result 872 return result ? result
1027 : ps3_repository_read_tb_freq(node_id, tb_freq); 873 : ps3_repository_read_tb_freq(node_id, tb_freq);
1028} 874}
875
876#if defined(DEBUG)
877
878int ps3_repository_dump_resource_info(const struct ps3_repository_device *repo)
879{
880 int result = 0;
881 unsigned int res_index;
882
883 pr_debug(" -> %s:%d: (%u:%u)\n", __func__, __LINE__,
884 repo->bus_index, repo->dev_index);
885
886 for (res_index = 0; res_index < 10; res_index++) {
887 enum ps3_interrupt_type intr_type;
888 unsigned int interrupt_id;
889
890 result = ps3_repository_read_dev_intr(repo->bus_index,
891 repo->dev_index, res_index, &intr_type, &interrupt_id);
892
893 if (result) {
894 if (result != LV1_NO_ENTRY)
895 pr_debug("%s:%d ps3_repository_read_dev_intr"
896 " (%u:%u) failed\n", __func__, __LINE__,
897 repo->bus_index, repo->dev_index);
898 break;
899 }
900
901 pr_debug("%s:%d (%u:%u) intr_type %u, interrupt_id %u\n",
902 __func__, __LINE__, repo->bus_index, repo->dev_index,
903 intr_type, interrupt_id);
904 }
905
906 for (res_index = 0; res_index < 10; res_index++) {
907 enum ps3_reg_type reg_type;
908 u64 bus_addr;
909 u64 len;
910
911 result = ps3_repository_read_dev_reg(repo->bus_index,
912 repo->dev_index, res_index, &reg_type, &bus_addr, &len);
913
914 if (result) {
915 if (result != LV1_NO_ENTRY)
916 pr_debug("%s:%d ps3_repository_read_dev_reg"
917 " (%u:%u) failed\n", __func__, __LINE__,
918 repo->bus_index, repo->dev_index);
919 break;
920 }
921
922 pr_debug("%s:%d (%u:%u) reg_type %u, bus_addr %lxh, len %lxh\n",
923 __func__, __LINE__, repo->bus_index, repo->dev_index,
924 reg_type, bus_addr, len);
925 }
926
927 pr_debug(" <- %s:%d\n", __func__, __LINE__);
928 return result;
929}
930
931static int dump_stor_dev_info(struct ps3_repository_device *repo)
932{
933 int result = 0;
934 unsigned int num_regions, region_index;
935 u64 port, blk_size, num_blocks;
936
937 pr_debug(" -> %s:%d: (%u:%u)\n", __func__, __LINE__,
938 repo->bus_index, repo->dev_index);
939
940 result = ps3_repository_read_stor_dev_info(repo->bus_index,
941 repo->dev_index, &port, &blk_size, &num_blocks, &num_regions);
942 if (result) {
943 pr_debug("%s:%d ps3_repository_read_stor_dev_info"
944 " (%u:%u) failed\n", __func__, __LINE__,
945 repo->bus_index, repo->dev_index);
946 goto out;
947 }
948
949 pr_debug("%s:%d (%u:%u): port %lu, blk_size %lu, num_blocks "
950 "%lu, num_regions %u\n",
951 __func__, __LINE__, repo->bus_index, repo->dev_index, port,
952 blk_size, num_blocks, num_regions);
953
954 for (region_index = 0; region_index < num_regions; region_index++) {
955 unsigned int region_id;
956 u64 region_start, region_size;
957
958 result = ps3_repository_read_stor_dev_region(repo->bus_index,
959 repo->dev_index, region_index, &region_id,
960 &region_start, &region_size);
961 if (result) {
962 pr_debug("%s:%d ps3_repository_read_stor_dev_region"
963 " (%u:%u) failed\n", __func__, __LINE__,
964 repo->bus_index, repo->dev_index);
965 break;
966 }
967
968 pr_debug("%s:%d (%u:%u) region_id %u, start %lxh, size %lxh\n",
969 __func__, __LINE__, repo->bus_index, repo->dev_index,
970 region_id, region_start, region_size);
971 }
972
973out:
974 pr_debug(" <- %s:%d\n", __func__, __LINE__);
975 return result;
976}
977
978static int dump_device_info(struct ps3_repository_device *repo,
979 unsigned int num_dev)
980{
981 int result = 0;
982
983 pr_debug(" -> %s:%d: bus_%u\n", __func__, __LINE__, repo->bus_index);
984
985 for (repo->dev_index = 0; repo->dev_index < num_dev;
986 repo->dev_index++) {
987
988 result = ps3_repository_read_dev_type(repo->bus_index,
989 repo->dev_index, &repo->dev_type);
990
991 if (result) {
992 pr_debug("%s:%d ps3_repository_read_dev_type"
993 " (%u:%u) failed\n", __func__, __LINE__,
994 repo->bus_index, repo->dev_index);
995 break;
996 }
997
998 result = ps3_repository_read_dev_id(repo->bus_index,
999 repo->dev_index, &repo->dev_id);
1000
1001 if (result) {
1002 pr_debug("%s:%d ps3_repository_read_dev_id"
1003 " (%u:%u) failed\n", __func__, __LINE__,
1004 repo->bus_index, repo->dev_index);
1005 continue;
1006 }
1007
1008 pr_debug("%s:%d (%u:%u): dev_type %u, dev_id %u\n", __func__,
1009 __LINE__, repo->bus_index, repo->dev_index,
1010 repo->dev_type, repo->dev_id);
1011
1012 ps3_repository_dump_resource_info(repo);
1013
1014 if (repo->bus_type == PS3_BUS_TYPE_STORAGE)
1015 dump_stor_dev_info(repo);
1016 }
1017
1018 pr_debug(" <- %s:%d\n", __func__, __LINE__);
1019 return result;
1020}
1021
1022int ps3_repository_dump_bus_info(void)
1023{
1024 int result = 0;
1025 struct ps3_repository_device repo;
1026
1027 pr_debug(" -> %s:%d\n", __func__, __LINE__);
1028
1029 memset(&repo, 0, sizeof(repo));
1030
1031 for (repo.bus_index = 0; repo.bus_index < 10; repo.bus_index++) {
1032 unsigned int num_dev;
1033
1034 result = ps3_repository_read_bus_type(repo.bus_index,
1035 &repo.bus_type);
1036
1037 if (result) {
1038 pr_debug("%s:%d read_bus_type(%u) failed\n",
1039 __func__, __LINE__, repo.bus_index);
1040 break;
1041 }
1042
1043 result = ps3_repository_read_bus_id(repo.bus_index,
1044 &repo.bus_id);
1045
1046 if (result) {
1047 pr_debug("%s:%d read_bus_id(%u) failed\n",
1048 __func__, __LINE__, repo.bus_index);
1049 continue;
1050 }
1051
1052 if (repo.bus_index != repo.bus_id)
1053 pr_debug("%s:%d bus_index != bus_id\n",
1054 __func__, __LINE__);
1055
1056 result = ps3_repository_read_bus_num_dev(repo.bus_index,
1057 &num_dev);
1058
1059 if (result) {
1060 pr_debug("%s:%d read_bus_num_dev(%u) failed\n",
1061 __func__, __LINE__, repo.bus_index);
1062 continue;
1063 }
1064
1065 pr_debug("%s:%d bus_%u: bus_type %u, bus_id %u, num_dev %u\n",
1066 __func__, __LINE__, repo.bus_index, repo.bus_type,
1067 repo.bus_id, num_dev);
1068
1069 dump_device_info(&repo, num_dev);
1070 }
1071
1072 pr_debug(" <- %s:%d\n", __func__, __LINE__);
1073 return result;
1074}
1075
1076#endif /* defined(DEBUG) */
diff --git a/arch/powerpc/platforms/ps3/setup.c b/arch/powerpc/platforms/ps3/setup.c
index 935396766621..aa05288de64e 100644
--- a/arch/powerpc/platforms/ps3/setup.c
+++ b/arch/powerpc/platforms/ps3/setup.c
@@ -37,27 +37,35 @@
37#include "platform.h" 37#include "platform.h"
38 38
39#if defined(DEBUG) 39#if defined(DEBUG)
40#define DBG(fmt...) udbg_printf(fmt) 40#define DBG udbg_printf
41#else 41#else
42#define DBG(fmt...) do{if(0)printk(fmt);}while(0) 42#define DBG pr_debug
43#endif 43#endif
44 44
45#if !defined(CONFIG_SMP) 45#if !defined(CONFIG_SMP)
46static void smp_send_stop(void) {} 46static void smp_send_stop(void) {}
47#endif 47#endif
48 48
49int ps3_get_firmware_version(union ps3_firmware_version *v) 49static union ps3_firmware_version ps3_firmware_version;
50
51void ps3_get_firmware_version(union ps3_firmware_version *v)
50{ 52{
51 int result = lv1_get_version_info(&v->raw); 53 *v = ps3_firmware_version;
54}
55EXPORT_SYMBOL_GPL(ps3_get_firmware_version);
52 56
53 if (result) { 57int ps3_compare_firmware_version(u16 major, u16 minor, u16 rev)
54 v->raw = 0; 58{
55 return -1; 59 union ps3_firmware_version x;
56 } 60
61 x.pad = 0;
62 x.major = major;
63 x.minor = minor;
64 x.rev = rev;
57 65
58 return result; 66 return (ps3_firmware_version.raw - x.raw);
59} 67}
60EXPORT_SYMBOL_GPL(ps3_get_firmware_version); 68EXPORT_SYMBOL_GPL(ps3_compare_firmware_version);
61 69
62static void ps3_power_save(void) 70static void ps3_power_save(void)
63{ 71{
@@ -99,7 +107,8 @@ static void ps3_panic(char *str)
99 while(1); 107 while(1);
100} 108}
101 109
102#ifdef CONFIG_FB_PS3 110#if defined(CONFIG_FB_PS3) || defined(CONFIG_FB_PS3_MODULE) || \
111 defined(CONFIG_PS3_FLASH) || defined(CONFIG_PS3_FLASH_MODULE)
103static void prealloc(struct ps3_prealloc *p) 112static void prealloc(struct ps3_prealloc *p)
104{ 113{
105 if (!p->size) 114 if (!p->size)
@@ -115,12 +124,15 @@ static void prealloc(struct ps3_prealloc *p)
115 printk(KERN_INFO "%s: %lu bytes at %p\n", p->name, p->size, 124 printk(KERN_INFO "%s: %lu bytes at %p\n", p->name, p->size,
116 p->address); 125 p->address);
117} 126}
127#endif
118 128
129#if defined(CONFIG_FB_PS3) || defined(CONFIG_FB_PS3_MODULE)
119struct ps3_prealloc ps3fb_videomemory = { 130struct ps3_prealloc ps3fb_videomemory = {
120 .name = "ps3fb videomemory", 131 .name = "ps3fb videomemory",
121 .size = CONFIG_FB_PS3_DEFAULT_SIZE_M*1024*1024, 132 .size = CONFIG_FB_PS3_DEFAULT_SIZE_M*1024*1024,
122 .align = 1024*1024 /* the GPU requires 1 MiB alignment */ 133 .align = 1024*1024 /* the GPU requires 1 MiB alignment */
123}; 134};
135EXPORT_SYMBOL_GPL(ps3fb_videomemory);
124#define prealloc_ps3fb_videomemory() prealloc(&ps3fb_videomemory) 136#define prealloc_ps3fb_videomemory() prealloc(&ps3fb_videomemory)
125 137
126static int __init early_parse_ps3fb(char *p) 138static int __init early_parse_ps3fb(char *p)
@@ -137,6 +149,30 @@ early_param("ps3fb", early_parse_ps3fb);
137#define prealloc_ps3fb_videomemory() do { } while (0) 149#define prealloc_ps3fb_videomemory() do { } while (0)
138#endif 150#endif
139 151
152#if defined(CONFIG_PS3_FLASH) || defined(CONFIG_PS3_FLASH_MODULE)
153struct ps3_prealloc ps3flash_bounce_buffer = {
154 .name = "ps3flash bounce buffer",
155 .size = 256*1024,
156 .align = 256*1024
157};
158EXPORT_SYMBOL_GPL(ps3flash_bounce_buffer);
159#define prealloc_ps3flash_bounce_buffer() prealloc(&ps3flash_bounce_buffer)
160
161static int __init early_parse_ps3flash(char *p)
162{
163 if (!p)
164 return 1;
165
166 if (!strcmp(p, "off"))
167 ps3flash_bounce_buffer.size = 0;
168
169 return 0;
170}
171early_param("ps3flash", early_parse_ps3flash);
172#else
173#define prealloc_ps3flash_bounce_buffer() do { } while (0)
174#endif
175
140static int ps3_set_dabr(u64 dabr) 176static int ps3_set_dabr(u64 dabr)
141{ 177{
142 enum {DABR_USER = 1, DABR_KERNEL = 2,}; 178 enum {DABR_USER = 1, DABR_KERNEL = 2,};
@@ -146,13 +182,13 @@ static int ps3_set_dabr(u64 dabr)
146 182
147static void __init ps3_setup_arch(void) 183static void __init ps3_setup_arch(void)
148{ 184{
149 union ps3_firmware_version v;
150 185
151 DBG(" -> %s:%d\n", __func__, __LINE__); 186 DBG(" -> %s:%d\n", __func__, __LINE__);
152 187
153 ps3_get_firmware_version(&v); 188 lv1_get_version_info(&ps3_firmware_version.raw);
154 printk(KERN_INFO "PS3 firmware version %u.%u.%u\n", v.major, v.minor, 189 printk(KERN_INFO "PS3 firmware version %u.%u.%u\n",
155 v.rev); 190 ps3_firmware_version.major, ps3_firmware_version.minor,
191 ps3_firmware_version.rev);
156 192
157 ps3_spu_set_platform(); 193 ps3_spu_set_platform();
158 ps3_map_htab(); 194 ps3_map_htab();
@@ -166,6 +202,8 @@ static void __init ps3_setup_arch(void)
166#endif 202#endif
167 203
168 prealloc_ps3fb_videomemory(); 204 prealloc_ps3fb_videomemory();
205 prealloc_ps3flash_bounce_buffer();
206
169 ppc_md.power_save = ps3_power_save; 207 ppc_md.power_save = ps3_power_save;
170 208
171 DBG(" <- %s:%d\n", __func__, __LINE__); 209 DBG(" <- %s:%d\n", __func__, __LINE__);
@@ -184,7 +222,7 @@ static int __init ps3_probe(void)
184 DBG(" -> %s:%d\n", __func__, __LINE__); 222 DBG(" -> %s:%d\n", __func__, __LINE__);
185 223
186 dt_root = of_get_flat_dt_root(); 224 dt_root = of_get_flat_dt_root();
187 if (!of_flat_dt_is_compatible(dt_root, "PS3")) 225 if (!of_flat_dt_is_compatible(dt_root, "sony,ps3"))
188 return 0; 226 return 0;
189 227
190 powerpc_firmware_features |= FW_FEATURE_PS3_POSSIBLE; 228 powerpc_firmware_features |= FW_FEATURE_PS3_POSSIBLE;
@@ -201,31 +239,12 @@ static int __init ps3_probe(void)
201#if defined(CONFIG_KEXEC) 239#if defined(CONFIG_KEXEC)
202static void ps3_kexec_cpu_down(int crash_shutdown, int secondary) 240static void ps3_kexec_cpu_down(int crash_shutdown, int secondary)
203{ 241{
204 DBG(" -> %s:%d\n", __func__, __LINE__); 242 int cpu = smp_processor_id();
205
206 if (secondary) {
207 int cpu;
208 for_each_online_cpu(cpu)
209 if (cpu)
210 ps3_smp_cleanup_cpu(cpu);
211 } else
212 ps3_smp_cleanup_cpu(0);
213
214 DBG(" <- %s:%d\n", __func__, __LINE__);
215}
216
217static void ps3_machine_kexec(struct kimage *image)
218{
219 unsigned long ppe_id;
220
221 DBG(" -> %s:%d\n", __func__, __LINE__);
222 243
223 lv1_get_logical_ppe_id(&ppe_id); 244 DBG(" -> %s:%d: (%d)\n", __func__, __LINE__, cpu);
224 lv1_configure_irq_state_bitmap(ppe_id, 0, 0);
225 ps3_mm_shutdown();
226 ps3_mm_vas_destroy();
227 245
228 default_machine_kexec(image); 246 ps3_smp_cleanup_cpu(cpu);
247 ps3_shutdown_IRQ(cpu);
229 248
230 DBG(" <- %s:%d\n", __func__, __LINE__); 249 DBG(" <- %s:%d\n", __func__, __LINE__);
231} 250}
@@ -247,7 +266,7 @@ define_machine(ps3) {
247 .power_off = ps3_power_off, 266 .power_off = ps3_power_off,
248#if defined(CONFIG_KEXEC) 267#if defined(CONFIG_KEXEC)
249 .kexec_cpu_down = ps3_kexec_cpu_down, 268 .kexec_cpu_down = ps3_kexec_cpu_down,
250 .machine_kexec = ps3_machine_kexec, 269 .machine_kexec = default_machine_kexec,
251 .machine_kexec_prepare = default_machine_kexec_prepare, 270 .machine_kexec_prepare = default_machine_kexec_prepare,
252 .machine_crash_shutdown = default_machine_crash_shutdown, 271 .machine_crash_shutdown = default_machine_crash_shutdown,
253#endif 272#endif
diff --git a/arch/powerpc/platforms/ps3/smp.c b/arch/powerpc/platforms/ps3/smp.c
index 53416ec5198b..f0b12f212363 100644
--- a/arch/powerpc/platforms/ps3/smp.c
+++ b/arch/powerpc/platforms/ps3/smp.c
@@ -27,9 +27,9 @@
27#include "platform.h" 27#include "platform.h"
28 28
29#if defined(DEBUG) 29#if defined(DEBUG)
30#define DBG(fmt...) udbg_printf(fmt) 30#define DBG udbg_printf
31#else 31#else
32#define DBG(fmt...) do{if(0)printk(fmt);}while(0) 32#define DBG pr_debug
33#endif 33#endif
34 34
35static irqreturn_t ipi_function_handler(int irq, void *msg) 35static irqreturn_t ipi_function_handler(int irq, void *msg)
@@ -39,11 +39,11 @@ static irqreturn_t ipi_function_handler(int irq, void *msg)
39} 39}
40 40
41/** 41/**
42 * virqs - a per cpu array of virqs for ipi use 42 * ps3_ipi_virqs - a per cpu array of virqs for ipi use
43 */ 43 */
44 44
45#define MSG_COUNT 4 45#define MSG_COUNT 4
46static DEFINE_PER_CPU(unsigned int, virqs[MSG_COUNT]); 46static DEFINE_PER_CPU(unsigned int, ps3_ipi_virqs[MSG_COUNT]);
47 47
48static const char *names[MSG_COUNT] = { 48static const char *names[MSG_COUNT] = {
49 "ipi call", 49 "ipi call",
@@ -62,7 +62,7 @@ static void do_message_pass(int target, int msg)
62 return; 62 return;
63 } 63 }
64 64
65 virq = per_cpu(virqs, target)[msg]; 65 virq = per_cpu(ps3_ipi_virqs, target)[msg];
66 result = ps3_send_event_locally(virq); 66 result = ps3_send_event_locally(virq);
67 67
68 if (result) 68 if (result)
@@ -94,13 +94,13 @@ static int ps3_smp_probe(void)
94static void __init ps3_smp_setup_cpu(int cpu) 94static void __init ps3_smp_setup_cpu(int cpu)
95{ 95{
96 int result; 96 int result;
97 unsigned int *virqs = per_cpu(virqs, cpu); 97 unsigned int *virqs = per_cpu(ps3_ipi_virqs, cpu);
98 int i; 98 int i;
99 99
100 DBG(" -> %s:%d: (%d)\n", __func__, __LINE__, cpu); 100 DBG(" -> %s:%d: (%d)\n", __func__, __LINE__, cpu);
101 101
102 /* 102 /*
103 * Check assumptions on virqs[] indexing. If this 103 * Check assumptions on ps3_ipi_virqs[] indexing. If this
104 * check fails, then a different mapping of PPC_MSG_ 104 * check fails, then a different mapping of PPC_MSG_
105 * to index needs to be setup. 105 * to index needs to be setup.
106 */ 106 */
@@ -132,13 +132,13 @@ static void __init ps3_smp_setup_cpu(int cpu)
132 132
133void ps3_smp_cleanup_cpu(int cpu) 133void ps3_smp_cleanup_cpu(int cpu)
134{ 134{
135 unsigned int *virqs = per_cpu(virqs, cpu); 135 unsigned int *virqs = per_cpu(ps3_ipi_virqs, cpu);
136 int i; 136 int i;
137 137
138 DBG(" -> %s:%d: (%d)\n", __func__, __LINE__, cpu); 138 DBG(" -> %s:%d: (%d)\n", __func__, __LINE__, cpu);
139 139
140 for (i = 0; i < MSG_COUNT; i++) { 140 for (i = 0; i < MSG_COUNT; i++) {
141 free_irq(virqs[i], (void*)(long)i); 141 /* Can't call free_irq from interrupt context. */
142 ps3_event_receive_port_destroy(virqs[i]); 142 ps3_event_receive_port_destroy(virqs[i]);
143 virqs[i] = NO_IRQ; 143 virqs[i] = NO_IRQ;
144 } 144 }
diff --git a/arch/powerpc/platforms/ps3/spu.c b/arch/powerpc/platforms/ps3/spu.c
index 651437cb2c18..c7f734c89462 100644
--- a/arch/powerpc/platforms/ps3/spu.c
+++ b/arch/powerpc/platforms/ps3/spu.c
@@ -182,15 +182,18 @@ static int __init setup_areas(struct spu *spu)
182{ 182{
183 struct table {char* name; unsigned long addr; unsigned long size;}; 183 struct table {char* name; unsigned long addr; unsigned long size;};
184 184
185 spu_pdata(spu)->shadow = __ioremap( 185 spu_pdata(spu)->shadow = ioremap_flags(spu_pdata(spu)->shadow_addr,
186 spu_pdata(spu)->shadow_addr, sizeof(struct spe_shadow), 186 sizeof(struct spe_shadow),
187 pgprot_val(PAGE_READONLY) | _PAGE_NO_CACHE | _PAGE_GUARDED); 187 pgprot_val(PAGE_READONLY) |
188 _PAGE_NO_CACHE);
188 if (!spu_pdata(spu)->shadow) { 189 if (!spu_pdata(spu)->shadow) {
189 pr_debug("%s:%d: ioremap shadow failed\n", __func__, __LINE__); 190 pr_debug("%s:%d: ioremap shadow failed\n", __func__, __LINE__);
190 goto fail_ioremap; 191 goto fail_ioremap;
191 } 192 }
192 193
193 spu->local_store = ioremap(spu->local_store_phys, LS_SIZE); 194 spu->local_store = (__force void *)ioremap_flags(spu->local_store_phys,
195 LS_SIZE, _PAGE_NO_CACHE);
196
194 if (!spu->local_store) { 197 if (!spu->local_store) {
195 pr_debug("%s:%d: ioremap local_store failed\n", 198 pr_debug("%s:%d: ioremap local_store failed\n",
196 __func__, __LINE__); 199 __func__, __LINE__);
@@ -199,6 +202,7 @@ static int __init setup_areas(struct spu *spu)
199 202
200 spu->problem = ioremap(spu->problem_phys, 203 spu->problem = ioremap(spu->problem_phys,
201 sizeof(struct spu_problem)); 204 sizeof(struct spu_problem));
205
202 if (!spu->problem) { 206 if (!spu->problem) {
203 pr_debug("%s:%d: ioremap problem failed\n", __func__, __LINE__); 207 pr_debug("%s:%d: ioremap problem failed\n", __func__, __LINE__);
204 goto fail_ioremap; 208 goto fail_ioremap;
@@ -206,6 +210,7 @@ static int __init setup_areas(struct spu *spu)
206 210
207 spu->priv2 = ioremap(spu_pdata(spu)->priv2_addr, 211 spu->priv2 = ioremap(spu_pdata(spu)->priv2_addr,
208 sizeof(struct spu_priv2)); 212 sizeof(struct spu_priv2));
213
209 if (!spu->priv2) { 214 if (!spu->priv2) {
210 pr_debug("%s:%d: ioremap priv2 failed\n", __func__, __LINE__); 215 pr_debug("%s:%d: ioremap priv2 failed\n", __func__, __LINE__);
211 goto fail_ioremap; 216 goto fail_ioremap;
diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c
index 6bda51027cc6..4bb634a17e43 100644
--- a/arch/powerpc/platforms/ps3/system-bus.c
+++ b/arch/powerpc/platforms/ps3/system-bus.c
@@ -30,22 +30,228 @@
30 30
31#include "platform.h" 31#include "platform.h"
32 32
33static struct device ps3_system_bus = {
34 .bus_id = "ps3_system",
35};
36
37/* FIXME: need device usage counters! */
38struct {
39 struct mutex mutex;
40 int sb_11; /* usb 0 */
41 int sb_12; /* usb 0 */
42 int gpu;
43} static usage_hack;
44
45static int ps3_is_device(struct ps3_system_bus_device *dev,
46 unsigned int bus_id, unsigned int dev_id)
47{
48 return dev->bus_id == bus_id && dev->dev_id == dev_id;
49}
50
51static int ps3_open_hv_device_sb(struct ps3_system_bus_device *dev)
52{
53 int result;
54
55 BUG_ON(!dev->bus_id);
56 mutex_lock(&usage_hack.mutex);
57
58 if (ps3_is_device(dev, 1, 1)) {
59 usage_hack.sb_11++;
60 if (usage_hack.sb_11 > 1) {
61 result = 0;
62 goto done;
63 }
64 }
65
66 if (ps3_is_device(dev, 1, 2)) {
67 usage_hack.sb_12++;
68 if (usage_hack.sb_12 > 1) {
69 result = 0;
70 goto done;
71 }
72 }
73
74 result = lv1_open_device(dev->bus_id, dev->dev_id, 0);
75
76 if (result) {
77 pr_debug("%s:%d: lv1_open_device failed: %s\n", __func__,
78 __LINE__, ps3_result(result));
79 result = -EPERM;
80 }
81
82done:
83 mutex_unlock(&usage_hack.mutex);
84 return result;
85}
86
87static int ps3_close_hv_device_sb(struct ps3_system_bus_device *dev)
88{
89 int result;
90
91 BUG_ON(!dev->bus_id);
92 mutex_lock(&usage_hack.mutex);
93
94 if (ps3_is_device(dev, 1, 1)) {
95 usage_hack.sb_11--;
96 if (usage_hack.sb_11) {
97 result = 0;
98 goto done;
99 }
100 }
101
102 if (ps3_is_device(dev, 1, 2)) {
103 usage_hack.sb_12--;
104 if (usage_hack.sb_12) {
105 result = 0;
106 goto done;
107 }
108 }
109
110 result = lv1_close_device(dev->bus_id, dev->dev_id);
111 BUG_ON(result);
112
113done:
114 mutex_unlock(&usage_hack.mutex);
115 return result;
116}
117
118static int ps3_open_hv_device_gpu(struct ps3_system_bus_device *dev)
119{
120 int result;
121
122 mutex_lock(&usage_hack.mutex);
123
124 usage_hack.gpu++;
125 if (usage_hack.gpu > 1) {
126 result = 0;
127 goto done;
128 }
129
130 result = lv1_gpu_open(0);
131
132 if (result) {
133 pr_debug("%s:%d: lv1_gpu_open failed: %s\n", __func__,
134 __LINE__, ps3_result(result));
135 result = -EPERM;
136 }
137
138done:
139 mutex_unlock(&usage_hack.mutex);
140 return result;
141}
142
143static int ps3_close_hv_device_gpu(struct ps3_system_bus_device *dev)
144{
145 int result;
146
147 mutex_lock(&usage_hack.mutex);
148
149 usage_hack.gpu--;
150 if (usage_hack.gpu) {
151 result = 0;
152 goto done;
153 }
154
155 result = lv1_gpu_close();
156 BUG_ON(result);
157
158done:
159 mutex_unlock(&usage_hack.mutex);
160 return result;
161}
162
163int ps3_open_hv_device(struct ps3_system_bus_device *dev)
164{
165 BUG_ON(!dev);
166 pr_debug("%s:%d: match_id: %u\n", __func__, __LINE__, dev->match_id);
167
168 switch (dev->match_id) {
169 case PS3_MATCH_ID_EHCI:
170 case PS3_MATCH_ID_OHCI:
171 case PS3_MATCH_ID_GELIC:
172 case PS3_MATCH_ID_STOR_DISK:
173 case PS3_MATCH_ID_STOR_ROM:
174 case PS3_MATCH_ID_STOR_FLASH:
175 return ps3_open_hv_device_sb(dev);
176
177 case PS3_MATCH_ID_SOUND:
178 case PS3_MATCH_ID_GRAPHICS:
179 return ps3_open_hv_device_gpu(dev);
180
181 case PS3_MATCH_ID_AV_SETTINGS:
182 case PS3_MATCH_ID_SYSTEM_MANAGER:
183 pr_debug("%s:%d: unsupported match_id: %u\n", __func__,
184 __LINE__, dev->match_id);
185 pr_debug("%s:%d: bus_id: %u\n", __func__,
186 __LINE__, dev->bus_id);
187 BUG();
188 return -EINVAL;
189
190 default:
191 break;
192 }
193
194 pr_debug("%s:%d: unknown match_id: %u\n", __func__, __LINE__,
195 dev->match_id);
196 BUG();
197 return -ENODEV;
198}
199EXPORT_SYMBOL_GPL(ps3_open_hv_device);
200
201int ps3_close_hv_device(struct ps3_system_bus_device *dev)
202{
203 BUG_ON(!dev);
204 pr_debug("%s:%d: match_id: %u\n", __func__, __LINE__, dev->match_id);
205
206 switch (dev->match_id) {
207 case PS3_MATCH_ID_EHCI:
208 case PS3_MATCH_ID_OHCI:
209 case PS3_MATCH_ID_GELIC:
210 case PS3_MATCH_ID_STOR_DISK:
211 case PS3_MATCH_ID_STOR_ROM:
212 case PS3_MATCH_ID_STOR_FLASH:
213 return ps3_close_hv_device_sb(dev);
214
215 case PS3_MATCH_ID_SOUND:
216 case PS3_MATCH_ID_GRAPHICS:
217 return ps3_close_hv_device_gpu(dev);
218
219 case PS3_MATCH_ID_AV_SETTINGS:
220 case PS3_MATCH_ID_SYSTEM_MANAGER:
221 pr_debug("%s:%d: unsupported match_id: %u\n", __func__,
222 __LINE__, dev->match_id);
223 pr_debug("%s:%d: bus_id: %u\n", __func__,
224 __LINE__, dev->bus_id);
225 BUG();
226 return -EINVAL;
227
228 default:
229 break;
230 }
231
232 pr_debug("%s:%d: unknown match_id: %u\n", __func__, __LINE__,
233 dev->match_id);
234 BUG();
235 return -ENODEV;
236}
237EXPORT_SYMBOL_GPL(ps3_close_hv_device);
238
33#define dump_mmio_region(_a) _dump_mmio_region(_a, __func__, __LINE__) 239#define dump_mmio_region(_a) _dump_mmio_region(_a, __func__, __LINE__)
34static void _dump_mmio_region(const struct ps3_mmio_region* r, 240static void _dump_mmio_region(const struct ps3_mmio_region* r,
35 const char* func, int line) 241 const char* func, int line)
36{ 242{
37 pr_debug("%s:%d: dev %u:%u\n", func, line, r->did.bus_id, 243 pr_debug("%s:%d: dev %u:%u\n", func, line, r->dev->bus_id,
38 r->did.dev_id); 244 r->dev->dev_id);
39 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);
40 pr_debug("%s:%d: len %lxh\n", func, line, r->len); 246 pr_debug("%s:%d: len %lxh\n", func, line, r->len);
41 pr_debug("%s:%d: lpar_addr %lxh\n", func, line, r->lpar_addr); 247 pr_debug("%s:%d: lpar_addr %lxh\n", func, line, r->lpar_addr);
42} 248}
43 249
44int ps3_mmio_region_create(struct ps3_mmio_region *r) 250static int ps3_sb_mmio_region_create(struct ps3_mmio_region *r)
45{ 251{
46 int result; 252 int result;
47 253
48 result = lv1_map_device_mmio_region(r->did.bus_id, r->did.dev_id, 254 result = lv1_map_device_mmio_region(r->dev->bus_id, r->dev->dev_id,
49 r->bus_addr, r->len, r->page_size, &r->lpar_addr); 255 r->bus_addr, r->len, r->page_size, &r->lpar_addr);
50 256
51 if (result) { 257 if (result) {
@@ -57,13 +263,26 @@ int ps3_mmio_region_create(struct ps3_mmio_region *r)
57 dump_mmio_region(r); 263 dump_mmio_region(r);
58 return result; 264 return result;
59} 265}
266
267static int ps3_ioc0_mmio_region_create(struct ps3_mmio_region *r)
268{
269 /* device specific; do nothing currently */
270 return 0;
271}
272
273int ps3_mmio_region_create(struct ps3_mmio_region *r)
274{
275 return r->mmio_ops->create(r);
276}
60EXPORT_SYMBOL_GPL(ps3_mmio_region_create); 277EXPORT_SYMBOL_GPL(ps3_mmio_region_create);
61 278
62int ps3_free_mmio_region(struct ps3_mmio_region *r) 279static int ps3_sb_free_mmio_region(struct ps3_mmio_region *r)
63{ 280{
64 int result; 281 int result;
65 282
66 result = lv1_unmap_device_mmio_region(r->did.bus_id, r->did.dev_id, 283 dump_mmio_region(r);
284;
285 result = lv1_unmap_device_mmio_region(r->dev->bus_id, r->dev->dev_id,
67 r->lpar_addr); 286 r->lpar_addr);
68 287
69 if (result) 288 if (result)
@@ -73,14 +292,60 @@ int ps3_free_mmio_region(struct ps3_mmio_region *r)
73 r->lpar_addr = 0; 292 r->lpar_addr = 0;
74 return result; 293 return result;
75} 294}
295
296static int ps3_ioc0_free_mmio_region(struct ps3_mmio_region *r)
297{
298 /* device specific; do nothing currently */
299 return 0;
300}
301
302
303int ps3_free_mmio_region(struct ps3_mmio_region *r)
304{
305 return r->mmio_ops->free(r);
306}
307
76EXPORT_SYMBOL_GPL(ps3_free_mmio_region); 308EXPORT_SYMBOL_GPL(ps3_free_mmio_region);
77 309
310static const struct ps3_mmio_region_ops ps3_mmio_sb_region_ops = {
311 .create = ps3_sb_mmio_region_create,
312 .free = ps3_sb_free_mmio_region
313};
314
315static const struct ps3_mmio_region_ops ps3_mmio_ioc0_region_ops = {
316 .create = ps3_ioc0_mmio_region_create,
317 .free = ps3_ioc0_free_mmio_region
318};
319
320int ps3_mmio_region_init(struct ps3_system_bus_device *dev,
321 struct ps3_mmio_region *r, unsigned long bus_addr, unsigned long len,
322 enum ps3_mmio_page_size page_size)
323{
324 r->dev = dev;
325 r->bus_addr = bus_addr;
326 r->len = len;
327 r->page_size = page_size;
328 switch (dev->dev_type) {
329 case PS3_DEVICE_TYPE_SB:
330 r->mmio_ops = &ps3_mmio_sb_region_ops;
331 break;
332 case PS3_DEVICE_TYPE_IOC0:
333 r->mmio_ops = &ps3_mmio_ioc0_region_ops;
334 break;
335 default:
336 BUG();
337 return -EINVAL;
338 }
339 return 0;
340}
341EXPORT_SYMBOL_GPL(ps3_mmio_region_init);
342
78static int ps3_system_bus_match(struct device *_dev, 343static int ps3_system_bus_match(struct device *_dev,
79 struct device_driver *_drv) 344 struct device_driver *_drv)
80{ 345{
81 int result; 346 int result;
82 struct ps3_system_bus_driver *drv = to_ps3_system_bus_driver(_drv); 347 struct ps3_system_bus_driver *drv = ps3_drv_to_system_bus_drv(_drv);
83 struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev); 348 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
84 349
85 result = dev->match_id == drv->match_id; 350 result = dev->match_id == drv->match_id;
86 351
@@ -92,32 +357,14 @@ static int ps3_system_bus_match(struct device *_dev,
92 357
93static int ps3_system_bus_probe(struct device *_dev) 358static int ps3_system_bus_probe(struct device *_dev)
94{ 359{
95 int result; 360 int result = 0;
96 struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev); 361 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
97 struct ps3_system_bus_driver *drv = 362 struct ps3_system_bus_driver *drv;
98 to_ps3_system_bus_driver(_dev->driver);
99
100 result = lv1_open_device(dev->did.bus_id, dev->did.dev_id, 0);
101
102 if (result) {
103 pr_debug("%s:%d: lv1_open_device failed (%d)\n",
104 __func__, __LINE__, result);
105 result = -EACCES;
106 goto clean_none;
107 }
108
109 if (dev->d_region->did.bus_id) {
110 result = ps3_dma_region_create(dev->d_region);
111 363
112 if (result) { 364 BUG_ON(!dev);
113 pr_debug("%s:%d: ps3_dma_region_create failed (%d)\n", 365 pr_info(" -> %s:%d: %s\n", __func__, __LINE__, _dev->bus_id);
114 __func__, __LINE__, result);
115 BUG_ON("check region type");
116 result = -EINVAL;
117 goto clean_device;
118 }
119 }
120 366
367 drv = ps3_system_bus_dev_to_system_bus_drv(dev);
121 BUG_ON(!drv); 368 BUG_ON(!drv);
122 369
123 if (drv->probe) 370 if (drv->probe)
@@ -126,56 +373,127 @@ static int ps3_system_bus_probe(struct device *_dev)
126 pr_info("%s:%d: %s no probe method\n", __func__, __LINE__, 373 pr_info("%s:%d: %s no probe method\n", __func__, __LINE__,
127 dev->core.bus_id); 374 dev->core.bus_id);
128 375
129 if (result) { 376 pr_info(" <- %s:%d: %s\n", __func__, __LINE__, dev->core.bus_id);
130 pr_debug("%s:%d: drv->probe failed\n", __func__, __LINE__);
131 goto clean_dma;
132 }
133
134 return result;
135
136clean_dma:
137 ps3_dma_region_free(dev->d_region);
138clean_device:
139 lv1_close_device(dev->did.bus_id, dev->did.dev_id);
140clean_none:
141 return result; 377 return result;
142} 378}
143 379
144static int ps3_system_bus_remove(struct device *_dev) 380static int ps3_system_bus_remove(struct device *_dev)
145{ 381{
146 struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev); 382 int result = 0;
147 struct ps3_system_bus_driver *drv = 383 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
148 to_ps3_system_bus_driver(_dev->driver); 384 struct ps3_system_bus_driver *drv;
385
386 BUG_ON(!dev);
387 pr_info(" -> %s:%d: %s\n", __func__, __LINE__, _dev->bus_id);
388
389 drv = ps3_system_bus_dev_to_system_bus_drv(dev);
390 BUG_ON(!drv);
149 391
150 if (drv->remove) 392 if (drv->remove)
151 drv->remove(dev); 393 result = drv->remove(dev);
152 else 394 else
153 pr_info("%s:%d: %s no remove method\n", __func__, __LINE__, 395 dev_dbg(&dev->core, "%s:%d %s: no remove method\n",
154 dev->core.bus_id); 396 __func__, __LINE__, drv->core.name);
397
398 pr_info(" <- %s:%d: %s\n", __func__, __LINE__, dev->core.bus_id);
399 return result;
400}
401
402static void ps3_system_bus_shutdown(struct device *_dev)
403{
404 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
405 struct ps3_system_bus_driver *drv;
406
407 BUG_ON(!dev);
408
409 dev_dbg(&dev->core, " -> %s:%d: match_id %d\n", __func__, __LINE__,
410 dev->match_id);
411
412 if (!dev->core.driver) {
413 dev_dbg(&dev->core, "%s:%d: no driver bound\n", __func__,
414 __LINE__);
415 return;
416 }
417
418 drv = ps3_system_bus_dev_to_system_bus_drv(dev);
419
420 BUG_ON(!drv);
421
422 dev_dbg(&dev->core, "%s:%d: %s -> %s\n", __func__, __LINE__,
423 dev->core.bus_id, drv->core.name);
424
425 if (drv->shutdown)
426 drv->shutdown(dev);
427 else if (drv->remove) {
428 dev_dbg(&dev->core, "%s:%d %s: no shutdown, calling remove\n",
429 __func__, __LINE__, drv->core.name);
430 drv->remove(dev);
431 } else {
432 dev_dbg(&dev->core, "%s:%d %s: no shutdown method\n",
433 __func__, __LINE__, drv->core.name);
434 BUG();
435 }
436
437 dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__);
438}
439
440static int ps3_system_bus_uevent(struct device *_dev, char **envp,
441 int num_envp, char *buffer, int buffer_size)
442{
443 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
444 int i = 0, length = 0;
155 445
156 ps3_dma_region_free(dev->d_region); 446 if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size,
157 ps3_free_mmio_region(dev->m_region); 447 &length, "MODALIAS=ps3:%d",
158 lv1_close_device(dev->did.bus_id, dev->did.dev_id); 448 dev->match_id))
449 return -ENOMEM;
159 450
451 envp[i] = NULL;
160 return 0; 452 return 0;
161} 453}
162 454
455static ssize_t modalias_show(struct device *_dev, struct device_attribute *a,
456 char *buf)
457{
458 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
459 int len = snprintf(buf, PAGE_SIZE, "ps3:%d\n", dev->match_id);
460
461 return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len;
462}
463
464static struct device_attribute ps3_system_bus_dev_attrs[] = {
465 __ATTR_RO(modalias),
466 __ATTR_NULL,
467};
468
163struct bus_type ps3_system_bus_type = { 469struct bus_type ps3_system_bus_type = {
164 .name = "ps3_system_bus", 470 .name = "ps3_system_bus",
165 .match = ps3_system_bus_match, 471 .match = ps3_system_bus_match,
472 .uevent = ps3_system_bus_uevent,
166 .probe = ps3_system_bus_probe, 473 .probe = ps3_system_bus_probe,
167 .remove = ps3_system_bus_remove, 474 .remove = ps3_system_bus_remove,
475 .shutdown = ps3_system_bus_shutdown,
476 .dev_attrs = ps3_system_bus_dev_attrs,
168}; 477};
169 478
170int __init ps3_system_bus_init(void) 479static int __init ps3_system_bus_init(void)
171{ 480{
172 int result; 481 int result;
173 482
174 if (!firmware_has_feature(FW_FEATURE_PS3_LV1)) 483 if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
175 return -ENODEV; 484 return -ENODEV;
176 485
486 pr_debug(" -> %s:%d\n", __func__, __LINE__);
487
488 mutex_init(&usage_hack.mutex);
489
490 result = device_register(&ps3_system_bus);
491 BUG_ON(result);
492
177 result = bus_register(&ps3_system_bus_type); 493 result = bus_register(&ps3_system_bus_type);
178 BUG_ON(result); 494 BUG_ON(result);
495
496 pr_debug(" <- %s:%d\n", __func__, __LINE__);
179 return result; 497 return result;
180} 498}
181 499
@@ -185,16 +503,13 @@ core_initcall(ps3_system_bus_init);
185 * Returns the virtual address of the buffer and sets dma_handle 503 * Returns the virtual address of the buffer and sets dma_handle
186 * to the dma address (mapping) of the first page. 504 * to the dma address (mapping) of the first page.
187 */ 505 */
188
189static void * ps3_alloc_coherent(struct device *_dev, size_t size, 506static void * ps3_alloc_coherent(struct device *_dev, size_t size,
190 dma_addr_t *dma_handle, gfp_t flag) 507 dma_addr_t *dma_handle, gfp_t flag)
191{ 508{
192 int result; 509 int result;
193 struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev); 510 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
194 unsigned long virt_addr; 511 unsigned long virt_addr;
195 512
196 BUG_ON(!dev->d_region->bus_addr);
197
198 flag &= ~(__GFP_DMA | __GFP_HIGHMEM); 513 flag &= ~(__GFP_DMA | __GFP_HIGHMEM);
199 flag |= __GFP_ZERO; 514 flag |= __GFP_ZERO;
200 515
@@ -205,7 +520,8 @@ static void * ps3_alloc_coherent(struct device *_dev, size_t size,
205 goto clean_none; 520 goto clean_none;
206 } 521 }
207 522
208 result = ps3_dma_map(dev->d_region, virt_addr, size, dma_handle); 523 result = ps3_dma_map(dev->d_region, virt_addr, size, dma_handle,
524 IOPTE_PP_W | IOPTE_PP_R | IOPTE_SO_RW | IOPTE_M);
209 525
210 if (result) { 526 if (result) {
211 pr_debug("%s:%d: ps3_dma_map failed (%d)\n", 527 pr_debug("%s:%d: ps3_dma_map failed (%d)\n",
@@ -226,7 +542,7 @@ clean_none:
226static void ps3_free_coherent(struct device *_dev, size_t size, void *vaddr, 542static void ps3_free_coherent(struct device *_dev, size_t size, void *vaddr,
227 dma_addr_t dma_handle) 543 dma_addr_t dma_handle)
228{ 544{
229 struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev); 545 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
230 546
231 ps3_dma_unmap(dev->d_region, dma_handle, size); 547 ps3_dma_unmap(dev->d_region, dma_handle, size);
232 free_pages((unsigned long)vaddr, get_order(size)); 548 free_pages((unsigned long)vaddr, get_order(size));
@@ -239,15 +555,16 @@ static void ps3_free_coherent(struct device *_dev, size_t size, void *vaddr,
239 * byte within the page as vaddr. 555 * byte within the page as vaddr.
240 */ 556 */
241 557
242static dma_addr_t ps3_map_single(struct device *_dev, void *ptr, size_t size, 558static dma_addr_t ps3_sb_map_single(struct device *_dev, void *ptr, size_t size,
243 enum dma_data_direction direction) 559 enum dma_data_direction direction)
244{ 560{
245 struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev); 561 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
246 int result; 562 int result;
247 unsigned long bus_addr; 563 unsigned long bus_addr;
248 564
249 result = ps3_dma_map(dev->d_region, (unsigned long)ptr, size, 565 result = ps3_dma_map(dev->d_region, (unsigned long)ptr, size,
250 &bus_addr); 566 &bus_addr,
567 IOPTE_PP_R | IOPTE_PP_W | IOPTE_SO_RW | IOPTE_M);
251 568
252 if (result) { 569 if (result) {
253 pr_debug("%s:%d: ps3_dma_map failed (%d)\n", 570 pr_debug("%s:%d: ps3_dma_map failed (%d)\n",
@@ -257,10 +574,44 @@ static dma_addr_t ps3_map_single(struct device *_dev, void *ptr, size_t size,
257 return bus_addr; 574 return bus_addr;
258} 575}
259 576
577static dma_addr_t ps3_ioc0_map_single(struct device *_dev, void *ptr,
578 size_t size,
579 enum dma_data_direction direction)
580{
581 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
582 int result;
583 unsigned long bus_addr;
584 u64 iopte_flag;
585
586 iopte_flag = IOPTE_M;
587 switch (direction) {
588 case DMA_BIDIRECTIONAL:
589 iopte_flag |= IOPTE_PP_R | IOPTE_PP_W | IOPTE_SO_RW;
590 break;
591 case DMA_TO_DEVICE:
592 iopte_flag |= IOPTE_PP_R | IOPTE_SO_R;
593 break;
594 case DMA_FROM_DEVICE:
595 iopte_flag |= IOPTE_PP_W | IOPTE_SO_RW;
596 break;
597 default:
598 /* not happned */
599 BUG();
600 };
601 result = ps3_dma_map(dev->d_region, (unsigned long)ptr, size,
602 &bus_addr, iopte_flag);
603
604 if (result) {
605 pr_debug("%s:%d: ps3_dma_map failed (%d)\n",
606 __func__, __LINE__, result);
607 }
608 return bus_addr;
609}
610
260static void ps3_unmap_single(struct device *_dev, dma_addr_t dma_addr, 611static void ps3_unmap_single(struct device *_dev, dma_addr_t dma_addr,
261 size_t size, enum dma_data_direction direction) 612 size_t size, enum dma_data_direction direction)
262{ 613{
263 struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev); 614 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
264 int result; 615 int result;
265 616
266 result = ps3_dma_unmap(dev->d_region, dma_addr, size); 617 result = ps3_dma_unmap(dev->d_region, dma_addr, size);
@@ -271,20 +622,20 @@ static void ps3_unmap_single(struct device *_dev, dma_addr_t dma_addr,
271 } 622 }
272} 623}
273 624
274static int ps3_map_sg(struct device *_dev, struct scatterlist *sg, int nents, 625static int ps3_sb_map_sg(struct device *_dev, struct scatterlist *sg, int nents,
275 enum dma_data_direction direction) 626 enum dma_data_direction direction)
276{ 627{
277#if defined(CONFIG_PS3_DYNAMIC_DMA) 628#if defined(CONFIG_PS3_DYNAMIC_DMA)
278 BUG_ON("do"); 629 BUG_ON("do");
279 return -EPERM; 630 return -EPERM;
280#else 631#else
281 struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev); 632 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
282 int i; 633 int i;
283 634
284 for (i = 0; i < nents; i++, sg++) { 635 for (i = 0; i < nents; i++, sg++) {
285 int result = ps3_dma_map(dev->d_region, 636 int result = ps3_dma_map(dev->d_region,
286 page_to_phys(sg->page) + sg->offset, sg->length, 637 page_to_phys(sg->page) + sg->offset, sg->length,
287 &sg->dma_address); 638 &sg->dma_address, 0);
288 639
289 if (result) { 640 if (result) {
290 pr_debug("%s:%d: ps3_dma_map failed (%d)\n", 641 pr_debug("%s:%d: ps3_dma_map failed (%d)\n",
@@ -299,7 +650,15 @@ static int ps3_map_sg(struct device *_dev, struct scatterlist *sg, int nents,
299#endif 650#endif
300} 651}
301 652
302static void ps3_unmap_sg(struct device *_dev, struct scatterlist *sg, 653static int ps3_ioc0_map_sg(struct device *_dev, struct scatterlist *sg,
654 int nents,
655 enum dma_data_direction direction)
656{
657 BUG();
658 return 0;
659}
660
661static void ps3_sb_unmap_sg(struct device *_dev, struct scatterlist *sg,
303 int nents, enum dma_data_direction direction) 662 int nents, enum dma_data_direction direction)
304{ 663{
305#if defined(CONFIG_PS3_DYNAMIC_DMA) 664#if defined(CONFIG_PS3_DYNAMIC_DMA)
@@ -307,18 +666,34 @@ static void ps3_unmap_sg(struct device *_dev, struct scatterlist *sg,
307#endif 666#endif
308} 667}
309 668
669static void ps3_ioc0_unmap_sg(struct device *_dev, struct scatterlist *sg,
670 int nents, enum dma_data_direction direction)
671{
672 BUG();
673}
674
310static int ps3_dma_supported(struct device *_dev, u64 mask) 675static int ps3_dma_supported(struct device *_dev, u64 mask)
311{ 676{
312 return mask >= DMA_32BIT_MASK; 677 return mask >= DMA_32BIT_MASK;
313} 678}
314 679
315static struct dma_mapping_ops ps3_dma_ops = { 680static struct dma_mapping_ops ps3_sb_dma_ops = {
316 .alloc_coherent = ps3_alloc_coherent, 681 .alloc_coherent = ps3_alloc_coherent,
317 .free_coherent = ps3_free_coherent, 682 .free_coherent = ps3_free_coherent,
318 .map_single = ps3_map_single, 683 .map_single = ps3_sb_map_single,
319 .unmap_single = ps3_unmap_single, 684 .unmap_single = ps3_unmap_single,
320 .map_sg = ps3_map_sg, 685 .map_sg = ps3_sb_map_sg,
321 .unmap_sg = ps3_unmap_sg, 686 .unmap_sg = ps3_sb_unmap_sg,
687 .dma_supported = ps3_dma_supported
688};
689
690static struct dma_mapping_ops ps3_ioc0_dma_ops = {
691 .alloc_coherent = ps3_alloc_coherent,
692 .free_coherent = ps3_free_coherent,
693 .map_single = ps3_ioc0_map_single,
694 .unmap_single = ps3_unmap_single,
695 .map_sg = ps3_ioc0_map_sg,
696 .unmap_sg = ps3_ioc0_unmap_sg,
322 .dma_supported = ps3_dma_supported 697 .dma_supported = ps3_dma_supported
323}; 698};
324 699
@@ -328,7 +703,7 @@ static struct dma_mapping_ops ps3_dma_ops = {
328 703
329static void ps3_system_bus_release_device(struct device *_dev) 704static void ps3_system_bus_release_device(struct device *_dev)
330{ 705{
331 struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev); 706 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
332 kfree(dev); 707 kfree(dev);
333} 708}
334 709
@@ -343,19 +718,38 @@ static void ps3_system_bus_release_device(struct device *_dev)
343int ps3_system_bus_device_register(struct ps3_system_bus_device *dev) 718int ps3_system_bus_device_register(struct ps3_system_bus_device *dev)
344{ 719{
345 int result; 720 int result;
346 static unsigned int dev_count = 1; 721 static unsigned int dev_ioc0_count;
722 static unsigned int dev_sb_count;
723 static unsigned int dev_vuart_count;
347 724
348 dev->core.parent = NULL; 725 if (!dev->core.parent)
726 dev->core.parent = &ps3_system_bus;
349 dev->core.bus = &ps3_system_bus_type; 727 dev->core.bus = &ps3_system_bus_type;
350 dev->core.release = ps3_system_bus_release_device; 728 dev->core.release = ps3_system_bus_release_device;
351 729
730 switch (dev->dev_type) {
731 case PS3_DEVICE_TYPE_IOC0:
732 dev->core.archdata.dma_ops = &ps3_ioc0_dma_ops;
733 snprintf(dev->core.bus_id, sizeof(dev->core.bus_id),
734 "ioc0_%02x", ++dev_ioc0_count);
735 break;
736 case PS3_DEVICE_TYPE_SB:
737 dev->core.archdata.dma_ops = &ps3_sb_dma_ops;
738 snprintf(dev->core.bus_id, sizeof(dev->core.bus_id),
739 "sb_%02x", ++dev_sb_count);
740
741 break;
742 case PS3_DEVICE_TYPE_VUART:
743 snprintf(dev->core.bus_id, sizeof(dev->core.bus_id),
744 "vuart_%02x", ++dev_vuart_count);
745 break;
746 default:
747 BUG();
748 };
749
352 dev->core.archdata.of_node = NULL; 750 dev->core.archdata.of_node = NULL;
353 dev->core.archdata.dma_ops = &ps3_dma_ops;
354 dev->core.archdata.numa_node = 0; 751 dev->core.archdata.numa_node = 0;
355 752
356 snprintf(dev->core.bus_id, sizeof(dev->core.bus_id), "sb_%02x",
357 dev_count++);
358
359 pr_debug("%s:%d add %s\n", __func__, __LINE__, dev->core.bus_id); 753 pr_debug("%s:%d add %s\n", __func__, __LINE__, dev->core.bus_id);
360 754
361 result = device_register(&dev->core); 755 result = device_register(&dev->core);
@@ -368,9 +762,15 @@ int ps3_system_bus_driver_register(struct ps3_system_bus_driver *drv)
368{ 762{
369 int result; 763 int result;
370 764
765 pr_debug(" -> %s:%d: %s\n", __func__, __LINE__, drv->core.name);
766
767 if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
768 return -ENODEV;
769
371 drv->core.bus = &ps3_system_bus_type; 770 drv->core.bus = &ps3_system_bus_type;
372 771
373 result = driver_register(&drv->core); 772 result = driver_register(&drv->core);
773 pr_debug(" <- %s:%d: %s\n", __func__, __LINE__, drv->core.name);
374 return result; 774 return result;
375} 775}
376 776
@@ -378,7 +778,9 @@ EXPORT_SYMBOL_GPL(ps3_system_bus_driver_register);
378 778
379void ps3_system_bus_driver_unregister(struct ps3_system_bus_driver *drv) 779void ps3_system_bus_driver_unregister(struct ps3_system_bus_driver *drv)
380{ 780{
781 pr_debug(" -> %s:%d: %s\n", __func__, __LINE__, drv->core.name);
381 driver_unregister(&drv->core); 782 driver_unregister(&drv->core);
783 pr_debug(" <- %s:%d: %s\n", __func__, __LINE__, drv->core.name);
382} 784}
383 785
384EXPORT_SYMBOL_GPL(ps3_system_bus_driver_unregister); 786EXPORT_SYMBOL_GPL(ps3_system_bus_driver_unregister);
diff --git a/arch/powerpc/platforms/ps3/time.c b/arch/powerpc/platforms/ps3/time.c
index 1bae8b19b363..802a9ccacb5e 100644
--- a/arch/powerpc/platforms/ps3/time.c
+++ b/arch/powerpc/platforms/ps3/time.c
@@ -39,7 +39,7 @@ static void _dump_tm(const struct rtc_time *tm, const char* func, int line)
39} 39}
40 40
41#define dump_time(_a) _dump_time(_a, __func__, __LINE__) 41#define dump_time(_a) _dump_time(_a, __func__, __LINE__)
42static void __attribute__ ((unused)) _dump_time(int time, const char* func, 42static void __maybe_unused _dump_time(int time, const char *func,
43 int line) 43 int line)
44{ 44{
45 struct rtc_time tm; 45 struct rtc_time tm;
diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile
index ae1fc92dc1c9..992ba6753cf2 100644
--- a/arch/powerpc/platforms/pseries/Makefile
+++ b/arch/powerpc/platforms/pseries/Makefile
@@ -8,7 +8,7 @@ obj-y := lpar.o hvCall.o nvram.o reconfig.o \
8obj-$(CONFIG_SMP) += smp.o 8obj-$(CONFIG_SMP) += smp.o
9obj-$(CONFIG_XICS) += xics.o 9obj-$(CONFIG_XICS) += xics.o
10obj-$(CONFIG_SCANLOG) += scanlog.o 10obj-$(CONFIG_SCANLOG) += scanlog.o
11obj-$(CONFIG_EEH) += eeh.o eeh_cache.o eeh_driver.o eeh_event.o 11obj-$(CONFIG_EEH) += eeh.o eeh_cache.o eeh_driver.o eeh_event.o eeh_sysfs.o
12obj-$(CONFIG_KEXEC) += kexec.o 12obj-$(CONFIG_KEXEC) += kexec.o
13obj-$(CONFIG_PCI) += pci.o pci_dlpar.o 13obj-$(CONFIG_PCI) += pci.o pci_dlpar.o
14obj-$(CONFIG_PCI_MSI) += msi.o 14obj-$(CONFIG_PCI_MSI) += msi.o
diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c
index 5f3e6d8659fe..b8770395013d 100644
--- a/arch/powerpc/platforms/pseries/eeh.c
+++ b/arch/powerpc/platforms/pseries/eeh.c
@@ -1,6 +1,8 @@
1/* 1/*
2 * eeh.c 2 * eeh.c
3 * Copyright (C) 2001 Dave Engebretsen & Todd Inglett IBM Corporation 3 * Copyright IBM Corporation 2001, 2005, 2006
4 * Copyright Dave Engebretsen & Todd Inglett 2001
5 * Copyright Linas Vepstas 2005, 2006
4 * 6 *
5 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by 8 * it under the terms of the GNU General Public License as published by
@@ -15,6 +17,8 @@
15 * You should have received a copy of the GNU General Public License 17 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software 18 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 * Please address comments and feedback to Linas Vepstas <linas@austin.ibm.com>
18 */ 22 */
19 23
20#include <linux/delay.h> 24#include <linux/delay.h>
@@ -117,7 +121,6 @@ static unsigned long no_cfg_addr;
117static unsigned long ignored_check; 121static unsigned long ignored_check;
118static unsigned long total_mmio_ffs; 122static unsigned long total_mmio_ffs;
119static unsigned long false_positives; 123static unsigned long false_positives;
120static unsigned long ignored_failures;
121static unsigned long slot_resets; 124static unsigned long slot_resets;
122 125
123#define IS_BRIDGE(class_code) (((class_code)<<16) == PCI_BASE_CLASS_BRIDGE) 126#define IS_BRIDGE(class_code) (((class_code)<<16) == PCI_BASE_CLASS_BRIDGE)
@@ -505,6 +508,7 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
505 printk(KERN_WARNING "EEH: read_slot_reset_state() failed; rc=%d dn=%s\n", 508 printk(KERN_WARNING "EEH: read_slot_reset_state() failed; rc=%d dn=%s\n",
506 ret, dn->full_name); 509 ret, dn->full_name);
507 false_positives++; 510 false_positives++;
511 pdn->eeh_false_positives ++;
508 rc = 0; 512 rc = 0;
509 goto dn_unlock; 513 goto dn_unlock;
510 } 514 }
@@ -513,6 +517,7 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
513 * they are empty when they don't have children. */ 517 * they are empty when they don't have children. */
514 if ((rets[0] == 5) && (dn->child == NULL)) { 518 if ((rets[0] == 5) && (dn->child == NULL)) {
515 false_positives++; 519 false_positives++;
520 pdn->eeh_false_positives ++;
516 rc = 0; 521 rc = 0;
517 goto dn_unlock; 522 goto dn_unlock;
518 } 523 }
@@ -522,6 +527,7 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
522 printk(KERN_WARNING "EEH: event on unsupported device, rc=%d dn=%s\n", 527 printk(KERN_WARNING "EEH: event on unsupported device, rc=%d dn=%s\n",
523 ret, dn->full_name); 528 ret, dn->full_name);
524 false_positives++; 529 false_positives++;
530 pdn->eeh_false_positives ++;
525 rc = 0; 531 rc = 0;
526 goto dn_unlock; 532 goto dn_unlock;
527 } 533 }
@@ -529,6 +535,7 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
529 /* If not the kind of error we know about, punt. */ 535 /* If not the kind of error we know about, punt. */
530 if (rets[0] != 1 && rets[0] != 2 && rets[0] != 4 && rets[0] != 5) { 536 if (rets[0] != 1 && rets[0] != 2 && rets[0] != 4 && rets[0] != 5) {
531 false_positives++; 537 false_positives++;
538 pdn->eeh_false_positives ++;
532 rc = 0; 539 rc = 0;
533 goto dn_unlock; 540 goto dn_unlock;
534 } 541 }
@@ -921,6 +928,7 @@ static void *early_enable_eeh(struct device_node *dn, void *data)
921 pdn->eeh_mode = 0; 928 pdn->eeh_mode = 0;
922 pdn->eeh_check_count = 0; 929 pdn->eeh_check_count = 0;
923 pdn->eeh_freeze_count = 0; 930 pdn->eeh_freeze_count = 0;
931 pdn->eeh_false_positives = 0;
924 932
925 if (status && strcmp(status, "ok") != 0) 933 if (status && strcmp(status, "ok") != 0)
926 return NULL; /* ignore devices with bad status */ 934 return NULL; /* ignore devices with bad status */
@@ -1139,7 +1147,8 @@ static void eeh_add_device_late(struct pci_dev *dev)
1139 pdn = PCI_DN(dn); 1147 pdn = PCI_DN(dn);
1140 pdn->pcidev = dev; 1148 pdn->pcidev = dev;
1141 1149
1142 pci_addr_cache_insert_device (dev); 1150 pci_addr_cache_insert_device(dev);
1151 eeh_sysfs_add_device(dev);
1143} 1152}
1144 1153
1145void eeh_add_device_tree_late(struct pci_bus *bus) 1154void eeh_add_device_tree_late(struct pci_bus *bus)
@@ -1178,6 +1187,7 @@ static void eeh_remove_device(struct pci_dev *dev)
1178 printk(KERN_DEBUG "EEH: remove device %s\n", pci_name(dev)); 1187 printk(KERN_DEBUG "EEH: remove device %s\n", pci_name(dev));
1179#endif 1188#endif
1180 pci_addr_cache_remove_device(dev); 1189 pci_addr_cache_remove_device(dev);
1190 eeh_sysfs_remove_device(dev);
1181 1191
1182 dn = pci_device_to_OF_node(dev); 1192 dn = pci_device_to_OF_node(dev);
1183 if (PCI_DN(dn)->pcidev) { 1193 if (PCI_DN(dn)->pcidev) {
@@ -1214,11 +1224,10 @@ static int proc_eeh_show(struct seq_file *m, void *v)
1214 "check not wanted=%ld\n" 1224 "check not wanted=%ld\n"
1215 "eeh_total_mmio_ffs=%ld\n" 1225 "eeh_total_mmio_ffs=%ld\n"
1216 "eeh_false_positives=%ld\n" 1226 "eeh_false_positives=%ld\n"
1217 "eeh_ignored_failures=%ld\n"
1218 "eeh_slot_resets=%ld\n", 1227 "eeh_slot_resets=%ld\n",
1219 no_device, no_dn, no_cfg_addr, 1228 no_device, no_dn, no_cfg_addr,
1220 ignored_check, total_mmio_ffs, 1229 ignored_check, total_mmio_ffs,
1221 false_positives, ignored_failures, 1230 false_positives,
1222 slot_resets); 1231 slot_resets);
1223 } 1232 }
1224 1233
diff --git a/arch/powerpc/platforms/pseries/eeh_cache.c b/arch/powerpc/platforms/pseries/eeh_cache.c
index f2bae04424f8..e49c815eae23 100644
--- a/arch/powerpc/platforms/pseries/eeh_cache.c
+++ b/arch/powerpc/platforms/pseries/eeh_cache.c
@@ -2,7 +2,8 @@
2 * eeh_cache.c 2 * eeh_cache.c
3 * PCI address cache; allows the lookup of PCI devices based on I/O address 3 * PCI address cache; allows the lookup of PCI devices based on I/O address
4 * 4 *
5 * Copyright (C) 2004 Linas Vepstas <linas@austin.ibm.com> IBM Corporation 5 * Copyright IBM Corporation 2004
6 * Copyright Linas Vepstas <linas@austin.ibm.com> 2004
6 * 7 *
7 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by 9 * it under the terms of the GNU General Public License as published by
@@ -295,6 +296,8 @@ void __init pci_addr_cache_build(void)
295 continue; 296 continue;
296 pci_dev_get (dev); /* matching put is in eeh_remove_device() */ 297 pci_dev_get (dev); /* matching put is in eeh_remove_device() */
297 PCI_DN(dn)->pcidev = dev; 298 PCI_DN(dn)->pcidev = dev;
299
300 eeh_sysfs_add_device(dev);
298 } 301 }
299 302
300#ifdef DEBUG 303#ifdef DEBUG
diff --git a/arch/powerpc/platforms/pseries/eeh_driver.c b/arch/powerpc/platforms/pseries/eeh_driver.c
index 161a5844ab6c..15e015ef6865 100644
--- a/arch/powerpc/platforms/pseries/eeh_driver.c
+++ b/arch/powerpc/platforms/pseries/eeh_driver.c
@@ -1,6 +1,7 @@
1/* 1/*
2 * PCI Error Recovery Driver for RPA-compliant PPC64 platform. 2 * PCI Error Recovery Driver for RPA-compliant PPC64 platform.
3 * Copyright (C) 2004, 2005 Linas Vepstas <linas@linas.org> 3 * Copyright IBM Corp. 2004 2005
4 * Copyright Linas Vepstas <linas@linas.org> 2004, 2005
4 * 5 *
5 * All rights reserved. 6 * All rights reserved.
6 * 7 *
@@ -19,8 +20,7 @@
19 * along with this program; if not, write to the Free Software 20 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 * 22 *
22 * Send feedback to <linas@us.ibm.com> 23 * Send comments and feedback to Linas Vepstas <linas@austin.ibm.com>
23 *
24 */ 24 */
25#include <linux/delay.h> 25#include <linux/delay.h>
26#include <linux/interrupt.h> 26#include <linux/interrupt.h>
diff --git a/arch/powerpc/platforms/pseries/eeh_sysfs.c b/arch/powerpc/platforms/pseries/eeh_sysfs.c
new file mode 100644
index 000000000000..15e13b568904
--- /dev/null
+++ b/arch/powerpc/platforms/pseries/eeh_sysfs.c
@@ -0,0 +1,87 @@
1/*
2 * Sysfs entries for PCI Error Recovery for PAPR-compliant platform.
3 * Copyright IBM Corporation 2007
4 * Copyright Linas Vepstas <linas@austin.ibm.com> 2007
5 *
6 * All rights reserved.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or (at
11 * your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
16 * NON INFRINGEMENT. See the GNU General Public License for more
17 * details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 *
23 * Send comments and feedback to Linas Vepstas <linas@austin.ibm.com>
24 */
25#include <linux/pci.h>
26#include <asm/ppc-pci.h>
27#include <asm/pci-bridge.h>
28#include <linux/kobject.h>
29
30/**
31 * EEH_SHOW_ATTR -- create sysfs entry for eeh statistic
32 * @_name: name of file in sysfs directory
33 * @_memb: name of member in struct pci_dn to access
34 * @_format: printf format for display
35 *
36 * All of the attributes look very similar, so just
37 * auto-gen a cut-n-paste routine to display them.
38 */
39#define EEH_SHOW_ATTR(_name,_memb,_format) \
40static ssize_t eeh_show_##_name(struct device *dev, \
41 struct device_attribute *attr, char *buf) \
42{ \
43 struct pci_dev *pdev = to_pci_dev(dev); \
44 struct device_node *dn = pci_device_to_OF_node(pdev); \
45 struct pci_dn *pdn; \
46 \
47 if (!dn || PCI_DN(dn) == NULL) \
48 return 0; \
49 \
50 pdn = PCI_DN(dn); \
51 return sprintf(buf, _format "\n", pdn->_memb); \
52} \
53static DEVICE_ATTR(_name, S_IRUGO, eeh_show_##_name, NULL);
54
55
56EEH_SHOW_ATTR(eeh_mode, eeh_mode, "0x%x");
57EEH_SHOW_ATTR(eeh_config_addr, eeh_config_addr, "0x%x");
58EEH_SHOW_ATTR(eeh_pe_config_addr, eeh_pe_config_addr, "0x%x");
59EEH_SHOW_ATTR(eeh_check_count, eeh_check_count, "%d");
60EEH_SHOW_ATTR(eeh_freeze_count, eeh_freeze_count, "%d");
61EEH_SHOW_ATTR(eeh_false_positives, eeh_false_positives, "%d");
62
63void eeh_sysfs_add_device(struct pci_dev *pdev)
64{
65 int rc=0;
66
67 rc += device_create_file(&pdev->dev, &dev_attr_eeh_mode);
68 rc += device_create_file(&pdev->dev, &dev_attr_eeh_config_addr);
69 rc += device_create_file(&pdev->dev, &dev_attr_eeh_pe_config_addr);
70 rc += device_create_file(&pdev->dev, &dev_attr_eeh_check_count);
71 rc += device_create_file(&pdev->dev, &dev_attr_eeh_false_positives);
72 rc += device_create_file(&pdev->dev, &dev_attr_eeh_freeze_count);
73
74 if (rc)
75 printk(KERN_WARNING "EEH: Unable to create sysfs entries\n");
76}
77
78void eeh_sysfs_remove_device(struct pci_dev *pdev)
79{
80 device_remove_file(&pdev->dev, &dev_attr_eeh_mode);
81 device_remove_file(&pdev->dev, &dev_attr_eeh_config_addr);
82 device_remove_file(&pdev->dev, &dev_attr_eeh_pe_config_addr);
83 device_remove_file(&pdev->dev, &dev_attr_eeh_check_count);
84 device_remove_file(&pdev->dev, &dev_attr_eeh_false_positives);
85 device_remove_file(&pdev->dev, &dev_attr_eeh_freeze_count);
86}
87
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
index 362dfbc260a6..8cc6eeeaae2f 100644
--- a/arch/powerpc/platforms/pseries/lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -373,12 +373,23 @@ static void pSeries_lpar_hptab_clear(void)
373{ 373{
374 unsigned long size_bytes = 1UL << ppc64_pft_size; 374 unsigned long size_bytes = 1UL << ppc64_pft_size;
375 unsigned long hpte_count = size_bytes >> 4; 375 unsigned long hpte_count = size_bytes >> 4;
376 unsigned long dummy1, dummy2; 376 unsigned long dummy1, dummy2, dword0;
377 long lpar_rc;
377 int i; 378 int i;
378 379
379 /* TODO: Use bulk call */ 380 /* TODO: Use bulk call */
380 for (i = 0; i < hpte_count; i++) 381 for (i = 0; i < hpte_count; i++) {
381 plpar_pte_remove_raw(0, i, 0, &dummy1, &dummy2); 382 /* dont remove HPTEs with VRMA mappings */
383 lpar_rc = plpar_pte_remove_raw(H_ANDCOND, i, HPTE_V_1TB_SEG,
384 &dummy1, &dummy2);
385 if (lpar_rc == H_NOT_FOUND) {
386 lpar_rc = plpar_pte_read_raw(0, i, &dword0, &dummy1);
387 if (!lpar_rc && ((dword0 & HPTE_V_VRMA_MASK)
388 != HPTE_V_VRMA_MASK))
389 /* Can be hpte for 1TB Seg. So remove it */
390 plpar_pte_remove_raw(0, i, 0, &dummy1, &dummy2);
391 }
392 }
382} 393}
383 394
384/* 395/*
diff --git a/arch/powerpc/platforms/pseries/pci_dlpar.c b/arch/powerpc/platforms/pseries/pci_dlpar.c
index ffaf6c5c517b..47f0e0857f0e 100644
--- a/arch/powerpc/platforms/pseries/pci_dlpar.c
+++ b/arch/powerpc/platforms/pseries/pci_dlpar.c
@@ -110,8 +110,6 @@ pcibios_fixup_new_pci_devices(struct pci_bus *bus, int fix_bus)
110 } 110 }
111 } 111 }
112 } 112 }
113
114 eeh_add_device_tree_late(bus);
115} 113}
116EXPORT_SYMBOL_GPL(pcibios_fixup_new_pci_devices); 114EXPORT_SYMBOL_GPL(pcibios_fixup_new_pci_devices);
117 115
@@ -139,6 +137,8 @@ pcibios_pci_config_bridge(struct pci_dev *dev)
139 137
140 /* Make the discovered devices available */ 138 /* Make the discovered devices available */
141 pci_bus_add_devices(child_bus); 139 pci_bus_add_devices(child_bus);
140
141 eeh_add_device_tree_late(child_bus);
142 return 0; 142 return 0;
143} 143}
144 144
@@ -171,6 +171,7 @@ pcibios_add_pci_devices(struct pci_bus * bus)
171 if (!list_empty(&bus->devices)) { 171 if (!list_empty(&bus->devices)) {
172 pcibios_fixup_new_pci_devices(bus, 0); 172 pcibios_fixup_new_pci_devices(bus, 0);
173 pci_bus_add_devices(bus); 173 pci_bus_add_devices(bus);
174 eeh_add_device_tree_late(bus);
174 } 175 }
175 } else if (mode == PCI_PROBE_NORMAL) { 176 } else if (mode == PCI_PROBE_NORMAL) {
176 /* use legacy probe */ 177 /* use legacy probe */
@@ -179,6 +180,7 @@ pcibios_add_pci_devices(struct pci_bus * bus)
179 if (num) { 180 if (num) {
180 pcibios_fixup_new_pci_devices(bus, 1); 181 pcibios_fixup_new_pci_devices(bus, 1);
181 pci_bus_add_devices(bus); 182 pci_bus_add_devices(bus);
183 eeh_add_device_tree_late(bus);
182 } 184 }
183 185
184 list_for_each_entry(dev, &bus->devices, bus_list) 186 list_for_each_entry(dev, &bus->devices, bus_list)
@@ -200,8 +202,6 @@ struct pci_controller * __devinit init_phb_dynamic(struct device_node *dn)
200 rtas_setup_phb(phb); 202 rtas_setup_phb(phb);
201 pci_process_bridge_OF_ranges(phb, dn, 0); 203 pci_process_bridge_OF_ranges(phb, dn, 0);
202 204
203 pci_setup_phb_io_dynamic(phb, primary);
204
205 pci_devs_phb_init_dynamic(phb); 205 pci_devs_phb_init_dynamic(phb);
206 206
207 if (dn->child) 207 if (dn->child)
@@ -210,6 +210,7 @@ struct pci_controller * __devinit init_phb_dynamic(struct device_node *dn)
210 scan_phb(phb); 210 scan_phb(phb);
211 pcibios_fixup_new_pci_devices(phb->bus, 0); 211 pcibios_fixup_new_pci_devices(phb->bus, 0);
212 pci_bus_add_devices(phb->bus); 212 pci_bus_add_devices(phb->bus);
213 eeh_add_device_tree_late(phb->bus);
213 214
214 return phb; 215 return phb;
215} 216}
diff --git a/arch/powerpc/platforms/pseries/plpar_wrappers.h b/arch/powerpc/platforms/pseries/plpar_wrappers.h
index 2e4d10c9eea8..d003c80fa31d 100644
--- a/arch/powerpc/platforms/pseries/plpar_wrappers.h
+++ b/arch/powerpc/platforms/pseries/plpar_wrappers.h
@@ -108,6 +108,21 @@ static inline long plpar_pte_read(unsigned long flags, unsigned long ptex,
108 return rc; 108 return rc;
109} 109}
110 110
111/* plpar_pte_read_raw can be called in real mode. It calls plpar_hcall_raw */
112static inline long plpar_pte_read_raw(unsigned long flags, unsigned long ptex,
113 unsigned long *old_pteh_ret, unsigned long *old_ptel_ret)
114{
115 long rc;
116 unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
117
118 rc = plpar_hcall_raw(H_READ, retbuf, flags, ptex);
119
120 *old_pteh_ret = retbuf[0];
121 *old_ptel_ret = retbuf[1];
122
123 return rc;
124}
125
111static inline long plpar_pte_protect(unsigned long flags, unsigned long ptex, 126static inline long plpar_pte_protect(unsigned long flags, unsigned long ptex,
112 unsigned long avpn) 127 unsigned long avpn)
113{ 128{
diff --git a/arch/powerpc/platforms/pseries/pseries.h b/arch/powerpc/platforms/pseries/pseries.h
index 2729d559fd91..61e19f78b923 100644
--- a/arch/powerpc/platforms/pseries/pseries.h
+++ b/arch/powerpc/platforms/pseries/pseries.h
@@ -33,6 +33,8 @@ static inline void setup_kexec_cpu_down_xics(void) { }
33static inline void setup_kexec_cpu_down_mpic(void) { } 33static inline void setup_kexec_cpu_down_mpic(void) { }
34#endif 34#endif
35 35
36extern void pSeries_final_fixup(void);
37
36/* Poweron flag used for enabling auto ups restart */ 38/* Poweron flag used for enabling auto ups restart */
37extern unsigned long rtas_poweron_auto; 39extern unsigned long rtas_poweron_auto;
38 40
diff --git a/arch/powerpc/platforms/pseries/reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c
index 5aa97aff3391..c02f8742c54d 100644
--- a/arch/powerpc/platforms/pseries/reconfig.c
+++ b/arch/powerpc/platforms/pseries/reconfig.c
@@ -123,7 +123,7 @@ static int pSeries_reconfig_add_node(const char *path, struct property *proplist
123 strcpy(np->full_name, path); 123 strcpy(np->full_name, path);
124 124
125 np->properties = proplist; 125 np->properties = proplist;
126 OF_MARK_DYNAMIC(np); 126 of_node_set_flag(np, OF_DYNAMIC);
127 kref_init(&np->kref); 127 kref_init(&np->kref);
128 128
129 np->parent = derive_parent(path); 129 np->parent = derive_parent(path);
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index a031d99becb7..59e69f085cb4 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -399,6 +399,7 @@ static void pseries_dedicated_idle_sleep(void)
399 * a good time to find other work to dispatch. 399 * a good time to find other work to dispatch.
400 */ 400 */
401 get_lppaca()->idle = 1; 401 get_lppaca()->idle = 1;
402 get_lppaca()->donate_dedicated_cpu = 1;
402 403
403 /* 404 /*
404 * We come in with interrupts disabled, and need_resched() 405 * We come in with interrupts disabled, and need_resched()
@@ -431,6 +432,7 @@ static void pseries_dedicated_idle_sleep(void)
431 432
432out: 433out:
433 HMT_medium(); 434 HMT_medium();
435 get_lppaca()->donate_dedicated_cpu = 0;
434 get_lppaca()->idle = 0; 436 get_lppaca()->idle = 0;
435} 437}
436 438
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c
index f1df942072bb..5bd90a7eb763 100644
--- a/arch/powerpc/platforms/pseries/xics.c
+++ b/arch/powerpc/platforms/pseries/xics.c
@@ -156,9 +156,9 @@ static inline void lpar_qirr_info(int n_cpu , u8 value)
156 156
157 157
158#ifdef CONFIG_SMP 158#ifdef CONFIG_SMP
159static int get_irq_server(unsigned int virq) 159static int get_irq_server(unsigned int virq, unsigned int strict_check)
160{ 160{
161 unsigned int server; 161 int server;
162 /* For the moment only implement delivery to all cpus or one cpu */ 162 /* For the moment only implement delivery to all cpus or one cpu */
163 cpumask_t cpumask = irq_desc[virq].affinity; 163 cpumask_t cpumask = irq_desc[virq].affinity;
164 cpumask_t tmp = CPU_MASK_NONE; 164 cpumask_t tmp = CPU_MASK_NONE;
@@ -166,22 +166,25 @@ static int get_irq_server(unsigned int virq)
166 if (!distribute_irqs) 166 if (!distribute_irqs)
167 return default_server; 167 return default_server;
168 168
169 if (cpus_equal(cpumask, CPU_MASK_ALL)) { 169 if (!cpus_equal(cpumask, CPU_MASK_ALL)) {
170 server = default_distrib_server;
171 } else {
172 cpus_and(tmp, cpu_online_map, cpumask); 170 cpus_and(tmp, cpu_online_map, cpumask);
173 171
174 if (cpus_empty(tmp)) 172 server = first_cpu(tmp);
175 server = default_distrib_server; 173
176 else 174 if (server < NR_CPUS)
177 server = get_hard_smp_processor_id(first_cpu(tmp)); 175 return get_hard_smp_processor_id(server);
176
177 if (strict_check)
178 return -1;
178 } 179 }
179 180
180 return server; 181 if (cpus_equal(cpu_online_map, cpu_present_map))
182 return default_distrib_server;
181 183
184 return default_server;
182} 185}
183#else 186#else
184static int get_irq_server(unsigned int virq) 187static int get_irq_server(unsigned int virq, unsigned int strict_check)
185{ 188{
186 return default_server; 189 return default_server;
187} 190}
@@ -192,7 +195,7 @@ static void xics_unmask_irq(unsigned int virq)
192{ 195{
193 unsigned int irq; 196 unsigned int irq;
194 int call_status; 197 int call_status;
195 unsigned int server; 198 int server;
196 199
197 pr_debug("xics: unmask virq %d\n", virq); 200 pr_debug("xics: unmask virq %d\n", virq);
198 201
@@ -201,7 +204,7 @@ static void xics_unmask_irq(unsigned int virq)
201 if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS) 204 if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS)
202 return; 205 return;
203 206
204 server = get_irq_server(virq); 207 server = get_irq_server(virq, 0);
205 208
206 call_status = rtas_call(ibm_set_xive, 3, 1, NULL, irq, server, 209 call_status = rtas_call(ibm_set_xive, 3, 1, NULL, irq, server,
207 DEFAULT_PRIORITY); 210 DEFAULT_PRIORITY);
@@ -398,8 +401,7 @@ static void xics_set_affinity(unsigned int virq, cpumask_t cpumask)
398 unsigned int irq; 401 unsigned int irq;
399 int status; 402 int status;
400 int xics_status[2]; 403 int xics_status[2];
401 unsigned long newmask; 404 int irq_server;
402 cpumask_t tmp = CPU_MASK_NONE;
403 405
404 irq = (unsigned int)irq_map[virq].hwirq; 406 irq = (unsigned int)irq_map[virq].hwirq;
405 if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS) 407 if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS)
@@ -413,18 +415,21 @@ static void xics_set_affinity(unsigned int virq, cpumask_t cpumask)
413 return; 415 return;
414 } 416 }
415 417
416 /* For the moment only implement delivery to all cpus or one cpu */ 418 /*
417 if (cpus_equal(cpumask, CPU_MASK_ALL)) { 419 * For the moment only implement delivery to all cpus or one cpu.
418 newmask = default_distrib_server; 420 * Get current irq_server for the given irq
419 } else { 421 */
420 cpus_and(tmp, cpu_online_map, cpumask); 422 irq_server = get_irq_server(irq, 1);
421 if (cpus_empty(tmp)) 423 if (irq_server == -1) {
422 return; 424 char cpulist[128];
423 newmask = get_hard_smp_processor_id(first_cpu(tmp)); 425 cpumask_scnprintf(cpulist, sizeof(cpulist), cpumask);
426 printk(KERN_WARNING "xics_set_affinity: No online cpus in "
427 "the mask %s for irq %d\n", cpulist, virq);
428 return;
424 } 429 }
425 430
426 status = rtas_call(ibm_set_xive, 3, 1, NULL, 431 status = rtas_call(ibm_set_xive, 3, 1, NULL,
427 irq, newmask, xics_status[1]); 432 irq, irq_server, xics_status[1]);
428 433
429 if (status) { 434 if (status) {
430 printk(KERN_ERR "xics_set_affinity: irq=%u ibm,set-xive " 435 printk(KERN_ERR "xics_set_affinity: irq=%u ibm,set-xive "
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
index c3ce0bd12c0b..f65078c3d3b3 100644
--- a/arch/powerpc/sysdev/Makefile
+++ b/arch/powerpc/sysdev/Makefile
@@ -5,7 +5,6 @@ endif
5mpic-msi-obj-$(CONFIG_PCI_MSI) += mpic_msi.o mpic_u3msi.o 5mpic-msi-obj-$(CONFIG_PCI_MSI) += mpic_msi.o mpic_u3msi.o
6obj-$(CONFIG_MPIC) += mpic.o $(mpic-msi-obj-y) 6obj-$(CONFIG_MPIC) += mpic.o $(mpic-msi-obj-y)
7 7
8obj-$(CONFIG_PPC_INDIRECT_PCI) += indirect_pci.o
9obj-$(CONFIG_PPC_MPC106) += grackle.o 8obj-$(CONFIG_PPC_MPC106) += grackle.o
10obj-$(CONFIG_PPC_DCR) += dcr.o 9obj-$(CONFIG_PPC_DCR) += dcr.o
11obj-$(CONFIG_PPC_DCR_NATIVE) += dcr-low.o 10obj-$(CONFIG_PPC_DCR_NATIVE) += dcr-low.o
@@ -13,16 +12,19 @@ obj-$(CONFIG_PPC_PMI) += pmi.o
13obj-$(CONFIG_U3_DART) += dart_iommu.o 12obj-$(CONFIG_U3_DART) += dart_iommu.o
14obj-$(CONFIG_MMIO_NVRAM) += mmio_nvram.o 13obj-$(CONFIG_MMIO_NVRAM) += mmio_nvram.o
15obj-$(CONFIG_FSL_SOC) += fsl_soc.o 14obj-$(CONFIG_FSL_SOC) += fsl_soc.o
16obj-$(CONFIG_FSL_PCIE) += fsl_pcie.o
17obj-$(CONFIG_TSI108_BRIDGE) += tsi108_pci.o tsi108_dev.o 15obj-$(CONFIG_TSI108_BRIDGE) += tsi108_pci.o tsi108_dev.o
18obj-$(CONFIG_QUICC_ENGINE) += qe_lib/ 16obj-$(CONFIG_QUICC_ENGINE) += qe_lib/
19mv64x60-$(CONFIG_PCI) += mv64x60_pci.o 17mv64x60-$(CONFIG_PCI) += mv64x60_pci.o
20obj-$(CONFIG_MV64X60) += $(mv64x60-y) mv64x60_pic.o mv64x60_dev.o 18obj-$(CONFIG_MV64X60) += $(mv64x60-y) mv64x60_pic.o mv64x60_dev.o
19obj-$(CONFIG_RTC_DRV_CMOS) += rtc_cmos_setup.o
21 20
22# contains only the suspend handler for time 21# contains only the suspend handler for time
22ifeq ($(CONFIG_RTC_CLASS),)
23obj-$(CONFIG_PM) += timer.o 23obj-$(CONFIG_PM) += timer.o
24endif
24 25
25ifeq ($(CONFIG_PPC_MERGE),y) 26ifeq ($(CONFIG_PPC_MERGE),y)
27obj-$(CONFIG_PPC_INDIRECT_PCI) += indirect_pci.o
26obj-$(CONFIG_PPC_I8259) += i8259.o 28obj-$(CONFIG_PPC_I8259) += i8259.o
27obj-$(CONFIG_PPC_83xx) += ipic.o 29obj-$(CONFIG_PPC_83xx) += ipic.o
28obj-$(CONFIG_4xx) += uic.o 30obj-$(CONFIG_4xx) += uic.o
diff --git a/arch/powerpc/sysdev/fsl_pcie.c b/arch/powerpc/sysdev/fsl_pcie.c
deleted file mode 100644
index 041c07e8b665..000000000000
--- a/arch/powerpc/sysdev/fsl_pcie.c
+++ /dev/null
@@ -1,171 +0,0 @@
1/*
2 * Support for indirect PCI bridges.
3 *
4 * Copyright (C) 1998 Gabriel Paubert.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 *
11 * "Temporary" MPC8548 Errata file -
12 * The standard indirect_pci code should work with future silicon versions.
13 */
14
15#include <linux/kernel.h>
16#include <linux/pci.h>
17#include <linux/delay.h>
18#include <linux/string.h>
19#include <linux/init.h>
20#include <linux/bootmem.h>
21
22#include <asm/io.h>
23#include <asm/prom.h>
24#include <asm/pci-bridge.h>
25#include <asm/machdep.h>
26
27#define PCI_CFG_OUT out_be32
28
29/* ERRATA PCI-Ex 14 PCIE Controller timeout */
30#define PCIE_FIX out_be32(hose->cfg_addr+0x4, 0x0400ffff)
31
32
33static int
34indirect_read_config_pcie(struct pci_bus *bus, unsigned int devfn, int offset,
35 int len, u32 *val)
36{
37 struct pci_controller *hose = bus->sysdata;
38 volatile void __iomem *cfg_data;
39 u32 temp;
40
41 if (ppc_md.pci_exclude_device)
42 if (ppc_md.pci_exclude_device(bus->number, devfn))
43 return PCIBIOS_DEVICE_NOT_FOUND;
44
45 /* Possible artifact of CDCpp50937 needs further investigation */
46 if (devfn != 0x0 && bus->number == 0xff)
47 return PCIBIOS_DEVICE_NOT_FOUND;
48
49 PCIE_FIX;
50 if (bus->number == 0xff) {
51 PCI_CFG_OUT(hose->cfg_addr,
52 (0x80000000 | ((offset & 0xf00) << 16) |
53 ((bus->number - hose->bus_offset) << 16)
54 | (devfn << 8) | ((offset & 0xfc) )));
55 } else {
56 PCI_CFG_OUT(hose->cfg_addr,
57 (0x80000001 | ((offset & 0xf00) << 16) |
58 ((bus->number - hose->bus_offset) << 16)
59 | (devfn << 8) | ((offset & 0xfc) )));
60 }
61
62 /*
63 * Note: the caller has already checked that offset is
64 * suitably aligned and that len is 1, 2 or 4.
65 */
66 /* ERRATA PCI-Ex 12 - Configuration Address/Data Alignment */
67 cfg_data = hose->cfg_data;
68 PCIE_FIX;
69 temp = in_le32(cfg_data);
70 switch (len) {
71 case 1:
72 *val = (temp >> (((offset & 3))*8)) & 0xff;
73 break;
74 case 2:
75 *val = (temp >> (((offset & 3))*8)) & 0xffff;
76 break;
77 default:
78 *val = temp;
79 break;
80 }
81 return PCIBIOS_SUCCESSFUL;
82}
83
84static int
85indirect_write_config_pcie(struct pci_bus *bus, unsigned int devfn, int offset,
86 int len, u32 val)
87{
88 struct pci_controller *hose = bus->sysdata;
89 volatile void __iomem *cfg_data;
90 u32 temp;
91
92 if (ppc_md.pci_exclude_device)
93 if (ppc_md.pci_exclude_device(bus->number, devfn))
94 return PCIBIOS_DEVICE_NOT_FOUND;
95
96 /* Possible artifact of CDCpp50937 needs further investigation */
97 if (devfn != 0x0 && bus->number == 0xff)
98 return PCIBIOS_DEVICE_NOT_FOUND;
99
100 PCIE_FIX;
101 if (bus->number == 0xff) {
102 PCI_CFG_OUT(hose->cfg_addr,
103 (0x80000000 | ((offset & 0xf00) << 16) |
104 ((bus->number - hose->bus_offset) << 16)
105 | (devfn << 8) | ((offset & 0xfc) )));
106 } else {
107 PCI_CFG_OUT(hose->cfg_addr,
108 (0x80000001 | ((offset & 0xf00) << 16) |
109 ((bus->number - hose->bus_offset) << 16)
110 | (devfn << 8) | ((offset & 0xfc) )));
111 }
112
113 /*
114 * Note: the caller has already checked that offset is
115 * suitably aligned and that len is 1, 2 or 4.
116 */
117 /* ERRATA PCI-Ex 12 - Configuration Address/Data Alignment */
118 cfg_data = hose->cfg_data;
119 switch (len) {
120 case 1:
121 PCIE_FIX;
122 temp = in_le32(cfg_data);
123 temp = (temp & ~(0xff << ((offset & 3) * 8))) |
124 (val << ((offset & 3) * 8));
125 PCIE_FIX;
126 out_le32(cfg_data, temp);
127 break;
128 case 2:
129 PCIE_FIX;
130 temp = in_le32(cfg_data);
131 temp = (temp & ~(0xffff << ((offset & 3) * 8)));
132 temp |= (val << ((offset & 3) * 8)) ;
133 PCIE_FIX;
134 out_le32(cfg_data, temp);
135 break;
136 default:
137 PCIE_FIX;
138 out_le32(cfg_data, val);
139 break;
140 }
141 PCIE_FIX;
142 return PCIBIOS_SUCCESSFUL;
143}
144
145static struct pci_ops indirect_pcie_ops = {
146 indirect_read_config_pcie,
147 indirect_write_config_pcie
148};
149
150void __init
151setup_indirect_pcie_nomap(struct pci_controller* hose, void __iomem * cfg_addr,
152 void __iomem * cfg_data)
153{
154 hose->cfg_addr = cfg_addr;
155 hose->cfg_data = cfg_data;
156 hose->ops = &indirect_pcie_ops;
157}
158
159void __init
160setup_indirect_pcie(struct pci_controller* hose, u32 cfg_addr, u32 cfg_data)
161{
162 unsigned long base = cfg_addr & PAGE_MASK;
163 void __iomem *mbase, *addr, *data;
164
165 mbase = ioremap(base, PAGE_SIZE);
166 addr = mbase + (cfg_addr & ~PAGE_MASK);
167 if ((cfg_data & PAGE_MASK) != base)
168 mbase = ioremap(cfg_data & PAGE_MASK, PAGE_SIZE);
169 data = mbase + (cfg_data & ~PAGE_MASK);
170 setup_indirect_pcie_nomap(hose, addr, data);
171}
diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index cad175724359..c0ddc80d8160 100644
--- a/arch/powerpc/sysdev/fsl_soc.c
+++ b/arch/powerpc/sysdev/fsl_soc.c
@@ -1028,6 +1028,19 @@ err:
1028 1028
1029arch_initcall(fs_enet_of_init); 1029arch_initcall(fs_enet_of_init);
1030 1030
1031static int __init fsl_pcmcia_of_init(void)
1032{
1033 struct device_node *np = NULL;
1034 /*
1035 * Register all the devices which type is "pcmcia"
1036 */
1037 while ((np = of_find_compatible_node(np,
1038 "pcmcia", "fsl,pq-pcmcia")) != NULL)
1039 of_platform_device_create(np, "m8xx-pcmcia", NULL);
1040 return 0;
1041}
1042
1043arch_initcall(fsl_pcmcia_of_init);
1031 1044
1032static const char *smc_regs = "regs"; 1045static const char *smc_regs = "regs";
1033static const char *smc_pram = "pram"; 1046static const char *smc_pram = "pram";
diff --git a/arch/powerpc/sysdev/indirect_pci.c b/arch/powerpc/sysdev/indirect_pci.c
index e71488469704..c7e6e859b393 100644
--- a/arch/powerpc/sysdev/indirect_pci.c
+++ b/arch/powerpc/sysdev/indirect_pci.c
@@ -33,18 +33,27 @@ indirect_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
33 struct pci_controller *hose = bus->sysdata; 33 struct pci_controller *hose = bus->sysdata;
34 volatile void __iomem *cfg_data; 34 volatile void __iomem *cfg_data;
35 u8 cfg_type = 0; 35 u8 cfg_type = 0;
36 u32 bus_no, reg;
36 37
37 if (ppc_md.pci_exclude_device) 38 if (ppc_md.pci_exclude_device)
38 if (ppc_md.pci_exclude_device(bus->number, devfn)) 39 if (ppc_md.pci_exclude_device(hose, bus->number, devfn))
39 return PCIBIOS_DEVICE_NOT_FOUND; 40 return PCIBIOS_DEVICE_NOT_FOUND;
40 41
41 if (hose->set_cfg_type) 42 if (hose->indirect_type & PPC_INDIRECT_TYPE_SET_CFG_TYPE)
42 if (bus->number != hose->first_busno) 43 if (bus->number != hose->first_busno)
43 cfg_type = 1; 44 cfg_type = 1;
44 45
45 PCI_CFG_OUT(hose->cfg_addr, 46 bus_no = (bus->number == hose->first_busno) ?
46 (0x80000000 | ((bus->number - hose->bus_offset) << 16) 47 hose->self_busno : bus->number;
47 | (devfn << 8) | ((offset & 0xfc) | cfg_type))); 48
49 if (hose->indirect_type & PPC_INDIRECT_TYPE_EXT_REG)
50 reg = ((offset & 0xf00) << 16) | (offset & 0xfc);
51 else
52 reg = offset & 0xfc;
53
54 PCI_CFG_OUT(hose->cfg_addr,
55 (0x80000000 | (bus_no << 16)
56 | (devfn << 8) | reg | cfg_type));
48 57
49 /* 58 /*
50 * Note: the caller has already checked that offset is 59 * Note: the caller has already checked that offset is
@@ -72,18 +81,33 @@ indirect_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
72 struct pci_controller *hose = bus->sysdata; 81 struct pci_controller *hose = bus->sysdata;
73 volatile void __iomem *cfg_data; 82 volatile void __iomem *cfg_data;
74 u8 cfg_type = 0; 83 u8 cfg_type = 0;
84 u32 bus_no, reg;
75 85
76 if (ppc_md.pci_exclude_device) 86 if (ppc_md.pci_exclude_device)
77 if (ppc_md.pci_exclude_device(bus->number, devfn)) 87 if (ppc_md.pci_exclude_device(hose, bus->number, devfn))
78 return PCIBIOS_DEVICE_NOT_FOUND; 88 return PCIBIOS_DEVICE_NOT_FOUND;
79 89
80 if (hose->set_cfg_type) 90 if (hose->indirect_type & PPC_INDIRECT_TYPE_SET_CFG_TYPE)
81 if (bus->number != hose->first_busno) 91 if (bus->number != hose->first_busno)
82 cfg_type = 1; 92 cfg_type = 1;
83 93
84 PCI_CFG_OUT(hose->cfg_addr, 94 bus_no = (bus->number == hose->first_busno) ?
85 (0x80000000 | ((bus->number - hose->bus_offset) << 16) 95 hose->self_busno : bus->number;
86 | (devfn << 8) | ((offset & 0xfc) | cfg_type))); 96
97 if (hose->indirect_type & PPC_INDIRECT_TYPE_EXT_REG)
98 reg = ((offset & 0xf00) << 16) | (offset & 0xfc);
99 else
100 reg = offset & 0xfc;
101
102 PCI_CFG_OUT(hose->cfg_addr,
103 (0x80000000 | (bus_no << 16)
104 | (devfn << 8) | reg | cfg_type));
105
106 /* surpress setting of PCI_PRIMARY_BUS */
107 if (hose->indirect_type & PPC_INDIRECT_TYPE_SURPRESS_PRIMARY_BUS)
108 if ((offset == PCI_PRIMARY_BUS) &&
109 (bus->number == hose->first_busno))
110 val &= 0xffffff00;
87 111
88 /* 112 /*
89 * Note: the caller has already checked that offset is 113 * Note: the caller has already checked that offset is
diff --git a/arch/powerpc/sysdev/mpc8xx_pic.h b/arch/powerpc/sysdev/mpc8xx_pic.h
index afa2ee6717c1..9fe00eebdc8b 100644
--- a/arch/powerpc/sysdev/mpc8xx_pic.h
+++ b/arch/powerpc/sysdev/mpc8xx_pic.h
@@ -4,9 +4,16 @@
4#include <linux/irq.h> 4#include <linux/irq.h>
5#include <linux/interrupt.h> 5#include <linux/interrupt.h>
6 6
7extern struct hw_interrupt_type mpc8xx_pic;
8
9int mpc8xx_pic_init(void); 7int mpc8xx_pic_init(void);
10unsigned int mpc8xx_get_irq(void); 8unsigned int mpc8xx_get_irq(void);
11 9
10/*
11 * Some internal interrupt registers use an 8-bit mask for the interrupt
12 * level instead of a number.
13 */
14static inline uint mk_int_int_mask(uint mask)
15{
16 return (1 << (7 - (mask/2)));
17}
18
12#endif /* _PPC_KERNEL_PPC8xx_H */ 19#endif /* _PPC_KERNEL_PPC8xx_H */
diff --git a/arch/powerpc/sysdev/mv64x60_dev.c b/arch/powerpc/sysdev/mv64x60_dev.c
index 4b0a9c88eeb3..b618fa60aef3 100644
--- a/arch/powerpc/sysdev/mv64x60_dev.c
+++ b/arch/powerpc/sysdev/mv64x60_dev.c
@@ -12,6 +12,7 @@
12#include <linux/stddef.h> 12#include <linux/stddef.h>
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/console.h>
15#include <linux/mv643xx.h> 16#include <linux/mv643xx.h>
16#include <linux/platform_device.h> 17#include <linux/platform_device.h>
17 18
@@ -420,3 +421,30 @@ error:
420 return err; 421 return err;
421} 422}
422arch_initcall(mv64x60_device_setup); 423arch_initcall(mv64x60_device_setup);
424
425static int __init mv64x60_add_mpsc_console(void)
426{
427 struct device_node *np = NULL;
428 const char *prop;
429
430 prop = of_get_property(of_chosen, "linux,stdout-path", NULL);
431 if (prop == NULL)
432 goto not_mpsc;
433
434 np = of_find_node_by_path(prop);
435 if (!np)
436 goto not_mpsc;
437
438 if (!of_device_is_compatible(np, "marvell,mpsc"))
439 goto not_mpsc;
440
441 prop = of_get_property(np, "block-index", NULL);
442 if (!prop)
443 goto not_mpsc;
444
445 add_preferred_console("ttyMM", *(int *)prop, NULL);
446
447not_mpsc:
448 return 0;
449}
450console_initcall(mv64x60_add_mpsc_console);
diff --git a/arch/powerpc/sysdev/mv64x60_pci.c b/arch/powerpc/sysdev/mv64x60_pci.c
index b5aef4cbc8d2..45db86c2363c 100644
--- a/arch/powerpc/sysdev/mv64x60_pci.c
+++ b/arch/powerpc/sysdev/mv64x60_pci.c
@@ -137,18 +137,15 @@ static int __init mv64x60_add_bridge(struct device_node *dev)
137 printk(KERN_WARNING "Can't get bus-range for %s, assume" 137 printk(KERN_WARNING "Can't get bus-range for %s, assume"
138 " bus 0\n", dev->full_name); 138 " bus 0\n", dev->full_name);
139 139
140 hose = pcibios_alloc_controller(); 140 hose = pcibios_alloc_controller(dev);
141 if (!hose) 141 if (!hose)
142 return -ENOMEM; 142 return -ENOMEM;
143 143
144 hose->arch_data = dev;
145 hose->set_cfg_type = 1;
146
147 hose->first_busno = bus_range ? bus_range[0] : 0; 144 hose->first_busno = bus_range ? bus_range[0] : 0;
148 hose->last_busno = bus_range ? bus_range[1] : 0xff; 145 hose->last_busno = bus_range ? bus_range[1] : 0xff;
149 146
150 setup_indirect_pci(hose, rsrc.start, rsrc.start + 4); 147 setup_indirect_pci(hose, rsrc.start, rsrc.start + 4);
151 hose->bus_offset = hose->first_busno; 148 hose->self_busno = hose->first_busno;
152 149
153 printk(KERN_INFO "Found MV64x60 PCI host bridge at 0x%016llx. " 150 printk(KERN_INFO "Found MV64x60 PCI host bridge at 0x%016llx. "
154 "Firmware bus number: %d->%d\n", 151 "Firmware bus number: %d->%d\n",
diff --git a/arch/powerpc/sysdev/qe_lib/ucc.c b/arch/powerpc/sysdev/qe_lib/ucc.c
index ac12a44d516f..f970e5415ac0 100644
--- a/arch/powerpc/sysdev/qe_lib/ucc.c
+++ b/arch/powerpc/sysdev/qe_lib/ucc.c
@@ -18,6 +18,7 @@
18#include <linux/errno.h> 18#include <linux/errno.h>
19#include <linux/slab.h> 19#include <linux/slab.h>
20#include <linux/stddef.h> 20#include <linux/stddef.h>
21#include <linux/module.h>
21 22
22#include <asm/irq.h> 23#include <asm/irq.h>
23#include <asm/io.h> 24#include <asm/io.h>
@@ -40,6 +41,7 @@ int ucc_set_qe_mux_mii_mng(int ucc_num)
40 41
41 return 0; 42 return 0;
42} 43}
44EXPORT_SYMBOL(ucc_set_qe_mux_mii_mng);
43 45
44int ucc_set_type(int ucc_num, struct ucc_common *regs, 46int ucc_set_type(int ucc_num, struct ucc_common *regs,
45 enum ucc_speed_type speed) 47 enum ucc_speed_type speed)
diff --git a/arch/powerpc/sysdev/qe_lib/ucc_fast.c b/arch/powerpc/sysdev/qe_lib/ucc_fast.c
index 9143236853fc..3df202e8d332 100644
--- a/arch/powerpc/sysdev/qe_lib/ucc_fast.c
+++ b/arch/powerpc/sysdev/qe_lib/ucc_fast.c
@@ -19,6 +19,7 @@
19#include <linux/stddef.h> 19#include <linux/stddef.h>
20#include <linux/interrupt.h> 20#include <linux/interrupt.h>
21#include <linux/err.h> 21#include <linux/err.h>
22#include <linux/module.h>
22 23
23#include <asm/io.h> 24#include <asm/io.h>
24#include <asm/immap_qe.h> 25#include <asm/immap_qe.h>
@@ -70,6 +71,7 @@ void ucc_fast_dump_regs(struct ucc_fast_private * uccf)
70 printk(KERN_INFO "guemr : addr - 0x%08x, val - 0x%02x", 71 printk(KERN_INFO "guemr : addr - 0x%08x, val - 0x%02x",
71 (u32) & uccf->uf_regs->guemr, uccf->uf_regs->guemr); 72 (u32) & uccf->uf_regs->guemr, uccf->uf_regs->guemr);
72} 73}
74EXPORT_SYMBOL(ucc_fast_dump_regs);
73 75
74u32 ucc_fast_get_qe_cr_subblock(int uccf_num) 76u32 ucc_fast_get_qe_cr_subblock(int uccf_num)
75{ 77{
@@ -85,11 +87,13 @@ u32 ucc_fast_get_qe_cr_subblock(int uccf_num)
85 default: return QE_CR_SUBBLOCK_INVALID; 87 default: return QE_CR_SUBBLOCK_INVALID;
86 } 88 }
87} 89}
90EXPORT_SYMBOL(ucc_fast_get_qe_cr_subblock);
88 91
89void ucc_fast_transmit_on_demand(struct ucc_fast_private * uccf) 92void ucc_fast_transmit_on_demand(struct ucc_fast_private * uccf)
90{ 93{
91 out_be16(&uccf->uf_regs->utodr, UCC_FAST_TOD); 94 out_be16(&uccf->uf_regs->utodr, UCC_FAST_TOD);
92} 95}
96EXPORT_SYMBOL(ucc_fast_transmit_on_demand);
93 97
94void ucc_fast_enable(struct ucc_fast_private * uccf, enum comm_dir mode) 98void ucc_fast_enable(struct ucc_fast_private * uccf, enum comm_dir mode)
95{ 99{
@@ -110,6 +114,7 @@ void ucc_fast_enable(struct ucc_fast_private * uccf, enum comm_dir mode)
110 } 114 }
111 out_be32(&uf_regs->gumr, gumr); 115 out_be32(&uf_regs->gumr, gumr);
112} 116}
117EXPORT_SYMBOL(ucc_fast_enable);
113 118
114void ucc_fast_disable(struct ucc_fast_private * uccf, enum comm_dir mode) 119void ucc_fast_disable(struct ucc_fast_private * uccf, enum comm_dir mode)
115{ 120{
@@ -130,6 +135,7 @@ void ucc_fast_disable(struct ucc_fast_private * uccf, enum comm_dir mode)
130 } 135 }
131 out_be32(&uf_regs->gumr, gumr); 136 out_be32(&uf_regs->gumr, gumr);
132} 137}
138EXPORT_SYMBOL(ucc_fast_disable);
133 139
134int ucc_fast_init(struct ucc_fast_info * uf_info, struct ucc_fast_private ** uccf_ret) 140int ucc_fast_init(struct ucc_fast_info * uf_info, struct ucc_fast_private ** uccf_ret)
135{ 141{
@@ -341,6 +347,7 @@ int ucc_fast_init(struct ucc_fast_info * uf_info, struct ucc_fast_private ** ucc
341 *uccf_ret = uccf; 347 *uccf_ret = uccf;
342 return 0; 348 return 0;
343} 349}
350EXPORT_SYMBOL(ucc_fast_init);
344 351
345void ucc_fast_free(struct ucc_fast_private * uccf) 352void ucc_fast_free(struct ucc_fast_private * uccf)
346{ 353{
@@ -355,3 +362,4 @@ void ucc_fast_free(struct ucc_fast_private * uccf)
355 362
356 kfree(uccf); 363 kfree(uccf);
357} 364}
365EXPORT_SYMBOL(ucc_fast_free);
diff --git a/arch/powerpc/sysdev/rtc_cmos_setup.c b/arch/powerpc/sysdev/rtc_cmos_setup.c
new file mode 100644
index 000000000000..e276048b8c5f
--- /dev/null
+++ b/arch/powerpc/sysdev/rtc_cmos_setup.c
@@ -0,0 +1,49 @@
1/*
2 * Setup code for PC-style Real-Time Clock.
3 *
4 * Author: Wade Farnsworth <wfarnsworth@mvista.com>
5 *
6 * 2007 (c) MontaVista Software, Inc. This file is licensed under
7 * the terms of the GNU General Public License version 2. This program
8 * is licensed "as is" without any warranty of any kind, whether express
9 * or implied.
10 */
11
12#include <linux/platform_device.h>
13#include <linux/err.h>
14#include <linux/init.h>
15#include <linux/mc146818rtc.h>
16
17#include <asm/prom.h>
18
19static int __init add_rtc(void)
20{
21 struct device_node *np;
22 struct platform_device *pd;
23 struct resource res;
24 int ret;
25
26 np = of_find_compatible_node(NULL, NULL, "pnpPNP,b00");
27 if (!np)
28 return -ENODEV;
29
30 ret = of_address_to_resource(np, 0, &res);
31 of_node_put(np);
32 if (ret)
33 return ret;
34
35 /*
36 * RTC_PORT(x) is hardcoded in asm/mc146818rtc.h. Verify that the
37 * address provided by the device node matches.
38 */
39 if (res.start != RTC_PORT(0))
40 return -EINVAL;
41
42 pd = platform_device_register_simple("rtc_cmos", -1,
43 &res, 1);
44 if (IS_ERR(pd))
45 return PTR_ERR(pd);
46
47 return 0;
48}
49fs_initcall(add_rtc);
diff --git a/arch/powerpc/sysdev/timer.c b/arch/powerpc/sysdev/timer.c
index 4a01748b4217..e81e7ec2e799 100644
--- a/arch/powerpc/sysdev/timer.c
+++ b/arch/powerpc/sysdev/timer.c
@@ -24,7 +24,12 @@ static int timer_resume(struct sys_device *dev)
24 24
25 /* get current RTC time and convert to seconds */ 25 /* get current RTC time and convert to seconds */
26 get_rtc_time(&cur_rtc_tm); 26 get_rtc_time(&cur_rtc_tm);
27 rtc_tm_to_time(&cur_rtc_tm, &cur_rtc_time); 27 cur_rtc_time = mktime(cur_rtc_tm.tm_year + 1900,
28 cur_rtc_tm.tm_mon + 1,
29 cur_rtc_tm.tm_mday,
30 cur_rtc_tm.tm_hour,
31 cur_rtc_tm.tm_min,
32 cur_rtc_tm.tm_sec);
28 33
29 diff = cur_rtc_time - suspend_rtc_time; 34 diff = cur_rtc_time - suspend_rtc_time;
30 35
@@ -44,7 +49,12 @@ static int timer_suspend(struct sys_device *dev, pm_message_t state)
44 WARN_ON(!ppc_md.get_rtc_time); 49 WARN_ON(!ppc_md.get_rtc_time);
45 50
46 get_rtc_time(&suspend_rtc_tm); 51 get_rtc_time(&suspend_rtc_tm);
47 rtc_tm_to_time(&suspend_rtc_tm, &suspend_rtc_time); 52 suspend_rtc_time = mktime(suspend_rtc_tm.tm_year + 1900,
53 suspend_rtc_tm.tm_mon + 1,
54 suspend_rtc_tm.tm_mday,
55 suspend_rtc_tm.tm_hour,
56 suspend_rtc_tm.tm_min,
57 suspend_rtc_tm.tm_sec);
48 58
49 return 0; 59 return 0;
50} 60}
diff --git a/arch/powerpc/sysdev/tsi108_dev.c b/arch/powerpc/sysdev/tsi108_dev.c
index 7d3b09b7d544..a113d800cbf0 100644
--- a/arch/powerpc/sysdev/tsi108_dev.c
+++ b/arch/powerpc/sysdev/tsi108_dev.c
@@ -72,12 +72,11 @@ static int __init tsi108_eth_of_init(void)
72 int ret; 72 int ret;
73 73
74 for (np = NULL, i = 0; 74 for (np = NULL, i = 0;
75 (np = of_find_compatible_node(np, "network", "tsi-ethernet")) != NULL; 75 (np = of_find_compatible_node(np, "network", "tsi108-ethernet")) != NULL;
76 i++) { 76 i++) {
77 struct resource r[2]; 77 struct resource r[2];
78 struct device_node *phy; 78 struct device_node *phy, *mdio;
79 hw_info tsi_eth_data; 79 hw_info tsi_eth_data;
80 const unsigned int *id;
81 const unsigned int *phy_id; 80 const unsigned int *phy_id;
82 const void *mac_addr; 81 const void *mac_addr;
83 const phandle *ph; 82 const phandle *ph;
@@ -111,6 +110,13 @@ static int __init tsi108_eth_of_init(void)
111 if (mac_addr) 110 if (mac_addr)
112 memcpy(tsi_eth_data.mac_addr, mac_addr, 6); 111 memcpy(tsi_eth_data.mac_addr, mac_addr, 6);
113 112
113 ph = of_get_property(np, "mdio-handle", NULL);
114 mdio = of_find_node_by_phandle(*ph);
115 ret = of_address_to_resource(mdio, 0, &res);
116 of_node_put(mdio);
117 if (ret)
118 goto unreg;
119
114 ph = of_get_property(np, "phy-handle", NULL); 120 ph = of_get_property(np, "phy-handle", NULL);
115 phy = of_find_node_by_phandle(*ph); 121 phy = of_find_node_by_phandle(*ph);
116 122
@@ -119,20 +125,25 @@ static int __init tsi108_eth_of_init(void)
119 goto unreg; 125 goto unreg;
120 } 126 }
121 127
122 id = of_get_property(phy, "reg", NULL); 128 phy_id = of_get_property(phy, "reg", NULL);
123 phy_id = of_get_property(phy, "phy-id", NULL); 129
124 ret = of_address_to_resource(phy, 0, &res);
125 if (ret) {
126 of_node_put(phy);
127 goto unreg;
128 }
129 tsi_eth_data.regs = r[0].start; 130 tsi_eth_data.regs = r[0].start;
130 tsi_eth_data.phyregs = res.start; 131 tsi_eth_data.phyregs = res.start;
131 tsi_eth_data.phy = *phy_id; 132 tsi_eth_data.phy = *phy_id;
132 tsi_eth_data.irq_num = irq_of_parse_and_map(np, 0); 133 tsi_eth_data.irq_num = irq_of_parse_and_map(np, 0);
133 if (of_device_is_compatible(phy, "bcm54xx")) 134
135 /* Some boards with the TSI108 bridge (e.g. Holly)
136 * have a miswiring of the ethernet PHYs which
137 * requires a workaround. The special
138 * "txc-rxc-delay-disable" property enables this
139 * workaround. FIXME: Need to port the tsi108_eth
140 * driver itself to phylib and use a non-misleading
141 * name for the workaround flag - it's not actually to
142 * do with the model of PHY in use */
143 if (of_get_property(phy, "txc-rxc-delay-disable", NULL))
134 tsi_eth_data.phy_type = TSI108_PHY_BCM54XX; 144 tsi_eth_data.phy_type = TSI108_PHY_BCM54XX;
135 of_node_put(phy); 145 of_node_put(phy);
146
136 ret = 147 ret =
137 platform_device_add_data(tsi_eth_dev, &tsi_eth_data, 148 platform_device_add_data(tsi_eth_dev, &tsi_eth_data,
138 sizeof(hw_info)); 149 sizeof(hw_info));
diff --git a/arch/powerpc/sysdev/tsi108_pci.c b/arch/powerpc/sysdev/tsi108_pci.c
index 2153163fa593..90db8a720fed 100644
--- a/arch/powerpc/sysdev/tsi108_pci.c
+++ b/arch/powerpc/sysdev/tsi108_pci.c
@@ -64,9 +64,10 @@ tsi108_direct_write_config(struct pci_bus *bus, unsigned int devfunc,
64 int offset, int len, u32 val) 64 int offset, int len, u32 val)
65{ 65{
66 volatile unsigned char *cfg_addr; 66 volatile unsigned char *cfg_addr;
67 struct pci_controller *hose = bus->sysdata;
67 68
68 if (ppc_md.pci_exclude_device) 69 if (ppc_md.pci_exclude_device)
69 if (ppc_md.pci_exclude_device(bus->number, devfunc)) 70 if (ppc_md.pci_exclude_device(hose, bus->number, devfunc))
70 return PCIBIOS_DEVICE_NOT_FOUND; 71 return PCIBIOS_DEVICE_NOT_FOUND;
71 72
72 cfg_addr = (unsigned char *)(tsi_mk_config_addr(bus->number, 73 cfg_addr = (unsigned char *)(tsi_mk_config_addr(bus->number,
@@ -149,10 +150,11 @@ tsi108_direct_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
149 int len, u32 * val) 150 int len, u32 * val)
150{ 151{
151 volatile unsigned char *cfg_addr; 152 volatile unsigned char *cfg_addr;
153 struct pci_controller *hose = bus->sysdata;
152 u32 temp; 154 u32 temp;
153 155
154 if (ppc_md.pci_exclude_device) 156 if (ppc_md.pci_exclude_device)
155 if (ppc_md.pci_exclude_device(bus->number, devfn)) 157 if (ppc_md.pci_exclude_device(hose, bus->number, devfn))
156 return PCIBIOS_DEVICE_NOT_FOUND; 158 return PCIBIOS_DEVICE_NOT_FOUND;
157 159
158 cfg_addr = (unsigned char *)(tsi_mk_config_addr(bus->number, 160 cfg_addr = (unsigned char *)(tsi_mk_config_addr(bus->number,
@@ -219,14 +221,12 @@ int __init tsi108_setup_pci(struct device_node *dev, u32 cfg_phys, int primary)
219 " bus 0\n", dev->full_name); 221 " bus 0\n", dev->full_name);
220 } 222 }
221 223
222 hose = pcibios_alloc_controller(); 224 hose = pcibios_alloc_controller(dev);
223 225
224 if (!hose) { 226 if (!hose) {
225 printk("PCI Host bridge init failed\n"); 227 printk("PCI Host bridge init failed\n");
226 return -ENOMEM; 228 return -ENOMEM;
227 } 229 }
228 hose->arch_data = dev;
229 hose->set_cfg_type = 1;
230 230
231 hose->first_busno = bus_range ? bus_range[0] : 0; 231 hose->first_busno = bus_range ? bus_range[0] : 0;
232 hose->last_busno = bus_range ? bus_range[1] : 0xff; 232 hose->last_busno = bus_range ? bus_range[1] : 0xff;
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index 28fdf4f50c27..669e6566ad70 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -2634,7 +2634,7 @@ static int __init setup_xmon_sysrq(void)
2634__initcall(setup_xmon_sysrq); 2634__initcall(setup_xmon_sysrq);
2635#endif /* CONFIG_MAGIC_SYSRQ */ 2635#endif /* CONFIG_MAGIC_SYSRQ */
2636 2636
2637int __initdata xmon_early, xmon_off; 2637static int __initdata xmon_early, xmon_off;
2638 2638
2639static int __init early_parse_xmon(char *p) 2639static int __init early_parse_xmon(char *p)
2640{ 2640{
diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S
index d319f9ba2379..0da55368655c 100644
--- a/arch/ppc/kernel/misc.S
+++ b/arch/ppc/kernel/misc.S
@@ -328,7 +328,7 @@ BEGIN_FTR_SECTION
328 mtspr SPRN_L1CSR0,r3 328 mtspr SPRN_L1CSR0,r3
329 isync 329 isync
330 blr 330 blr
331END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE) 331END_FTR_SECTION_IFSET(CPU_FTR_UNIFIED_ID_CACHE)
332 mfspr r3,SPRN_L1CSR1 332 mfspr r3,SPRN_L1CSR1
333 ori r3,r3,L1CSR1_ICFI|L1CSR1_ICLFR 333 ori r3,r3,L1CSR1_ICFI|L1CSR1_ICLFR
334 mtspr SPRN_L1CSR1,r3 334 mtspr SPRN_L1CSR1,r3
@@ -355,7 +355,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
355_GLOBAL(__flush_icache_range) 355_GLOBAL(__flush_icache_range)
356BEGIN_FTR_SECTION 356BEGIN_FTR_SECTION
357 blr /* for 601, do nothing */ 357 blr /* for 601, do nothing */
358END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE) 358END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
359 li r5,L1_CACHE_BYTES-1 359 li r5,L1_CACHE_BYTES-1
360 andc r3,r3,r5 360 andc r3,r3,r5
361 subf r4,r3,r4 361 subf r4,r3,r4
@@ -472,7 +472,7 @@ _GLOBAL(flush_dcache_all)
472_GLOBAL(__flush_dcache_icache) 472_GLOBAL(__flush_dcache_icache)
473BEGIN_FTR_SECTION 473BEGIN_FTR_SECTION
474 blr /* for 601, do nothing */ 474 blr /* for 601, do nothing */
475END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE) 475END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
476 rlwinm r3,r3,0,0,19 /* Get page base address */ 476 rlwinm r3,r3,0,0,19 /* Get page base address */
477 li r4,4096/L1_CACHE_BYTES /* Number of lines in a page */ 477 li r4,4096/L1_CACHE_BYTES /* Number of lines in a page */
478 mtctr r4 478 mtctr r4
@@ -500,7 +500,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
500_GLOBAL(__flush_dcache_icache_phys) 500_GLOBAL(__flush_dcache_icache_phys)
501BEGIN_FTR_SECTION 501BEGIN_FTR_SECTION
502 blr /* for 601, do nothing */ 502 blr /* for 601, do nothing */
503END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE) 503END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
504 mfmsr r10 504 mfmsr r10
505 rlwinm r0,r10,0,28,26 /* clear DR */ 505 rlwinm r0,r10,0,28,26 /* clear DR */
506 mtmsr r0 506 mtmsr r0
diff --git a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c
index a4165209ac7c..63f0a987139b 100644
--- a/arch/ppc/kernel/ppc_ksyms.c
+++ b/arch/ppc/kernel/ppc_ksyms.c
@@ -64,7 +64,6 @@ extern unsigned long mm_ptov (unsigned long paddr);
64 64
65EXPORT_SYMBOL(clear_pages); 65EXPORT_SYMBOL(clear_pages);
66EXPORT_SYMBOL(clear_user_page); 66EXPORT_SYMBOL(clear_user_page);
67EXPORT_SYMBOL(do_signal);
68EXPORT_SYMBOL(transfer_to_handler); 67EXPORT_SYMBOL(transfer_to_handler);
69EXPORT_SYMBOL(do_IRQ); 68EXPORT_SYMBOL(do_IRQ);
70EXPORT_SYMBOL(machine_check_exception); 69EXPORT_SYMBOL(machine_check_exception);
diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c
index c79704f5409c..967c1ef59a6b 100644
--- a/arch/ppc/kernel/setup.c
+++ b/arch/ppc/kernel/setup.c
@@ -526,7 +526,7 @@ void __init setup_arch(char **cmdline_p)
526 * Systems with OF can look in the properties on the cpu node(s) 526 * Systems with OF can look in the properties on the cpu node(s)
527 * for a possibly more accurate value. 527 * for a possibly more accurate value.
528 */ 528 */
529 if (cpu_has_feature(CPU_FTR_SPLIT_ID_CACHE)) { 529 if (! cpu_has_feature(CPU_FTR_UNIFIED_ID_CACHE)) {
530 dcache_bsize = cur_cpu_spec->dcache_bsize; 530 dcache_bsize = cur_cpu_spec->dcache_bsize;
531 icache_bsize = cur_cpu_spec->icache_bsize; 531 icache_bsize = cur_cpu_spec->icache_bsize;
532 ucache_bsize = 0; 532 ucache_bsize = 0;
diff --git a/arch/ppc/mm/tlb.c b/arch/ppc/mm/tlb.c
index fa29740a28f5..4ff260bc9dd1 100644
--- a/arch/ppc/mm/tlb.c
+++ b/arch/ppc/mm/tlb.c
@@ -27,6 +27,7 @@
27#include <linux/mm.h> 27#include <linux/mm.h>
28#include <linux/init.h> 28#include <linux/init.h>
29#include <linux/highmem.h> 29#include <linux/highmem.h>
30#include <linux/pagemap.h>
30#include <asm/tlbflush.h> 31#include <asm/tlbflush.h>
31#include <asm/tlb.h> 32#include <asm/tlb.h>
32 33
diff --git a/arch/ppc/platforms/prep_setup.c b/arch/ppc/platforms/prep_setup.c
index 6f21110a9747..3c56654bfc6f 100644
--- a/arch/ppc/platforms/prep_setup.c
+++ b/arch/ppc/platforms/prep_setup.c
@@ -69,9 +69,6 @@
69 69
70TODC_ALLOC(); 70TODC_ALLOC();
71 71
72unsigned char ucBoardRev;
73unsigned char ucBoardRevMaj, ucBoardRevMin;
74
75extern unsigned char prep_nvram_read_val(int addr); 72extern unsigned char prep_nvram_read_val(int addr);
76extern void prep_nvram_write_val(int addr, 73extern void prep_nvram_write_val(int addr,
77 unsigned char val); 74 unsigned char val);
diff --git a/arch/ppc/syslib/Makefile b/arch/ppc/syslib/Makefile
index 95694159b226..543795be58c8 100644
--- a/arch/ppc/syslib/Makefile
+++ b/arch/ppc/syslib/Makefile
@@ -7,6 +7,7 @@ CFLAGS_btext.o += -fPIC
7 7
8wdt-mpc8xx-$(CONFIG_8xx_WDT) += m8xx_wdt.o 8wdt-mpc8xx-$(CONFIG_8xx_WDT) += m8xx_wdt.o
9 9
10obj-$(CONFIG_PPC_INDIRECT_PCI) += indirect_pci.o
10obj-$(CONFIG_PPCBUG_NVRAM) += prep_nvram.o 11obj-$(CONFIG_PPCBUG_NVRAM) += prep_nvram.o
11obj-$(CONFIG_PPC_OCP) += ocp.o 12obj-$(CONFIG_PPC_OCP) += ocp.o
12obj-$(CONFIG_IBM_OCP) += ibm_ocp.o 13obj-$(CONFIG_IBM_OCP) += ibm_ocp.o
diff --git a/arch/ppc/syslib/indirect_pci.c b/arch/ppc/syslib/indirect_pci.c
new file mode 100644
index 000000000000..83b323a7d029
--- /dev/null
+++ b/arch/ppc/syslib/indirect_pci.c
@@ -0,0 +1,134 @@
1/*
2 * Support for indirect PCI bridges.
3 *
4 * Copyright (C) 1998 Gabriel Paubert.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12#include <linux/kernel.h>
13#include <linux/pci.h>
14#include <linux/delay.h>
15#include <linux/string.h>
16#include <linux/init.h>
17
18#include <asm/io.h>
19#include <asm/prom.h>
20#include <asm/pci-bridge.h>
21#include <asm/machdep.h>
22
23#ifdef CONFIG_PPC_INDIRECT_PCI_BE
24#define PCI_CFG_OUT out_be32
25#else
26#define PCI_CFG_OUT out_le32
27#endif
28
29static int
30indirect_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
31 int len, u32 *val)
32{
33 struct pci_controller *hose = bus->sysdata;
34 volatile void __iomem *cfg_data;
35 u8 cfg_type = 0;
36
37 if (ppc_md.pci_exclude_device)
38 if (ppc_md.pci_exclude_device(bus->number, devfn))
39 return PCIBIOS_DEVICE_NOT_FOUND;
40
41 if (hose->set_cfg_type)
42 if (bus->number != hose->first_busno)
43 cfg_type = 1;
44
45 PCI_CFG_OUT(hose->cfg_addr,
46 (0x80000000 | ((bus->number - hose->bus_offset) << 16)
47 | (devfn << 8) | ((offset & 0xfc) | cfg_type)));
48
49 /*
50 * Note: the caller has already checked that offset is
51 * suitably aligned and that len is 1, 2 or 4.
52 */
53 cfg_data = hose->cfg_data + (offset & 3);
54 switch (len) {
55 case 1:
56 *val = in_8(cfg_data);
57 break;
58 case 2:
59 *val = in_le16(cfg_data);
60 break;
61 default:
62 *val = in_le32(cfg_data);
63 break;
64 }
65 return PCIBIOS_SUCCESSFUL;
66}
67
68static int
69indirect_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
70 int len, u32 val)
71{
72 struct pci_controller *hose = bus->sysdata;
73 volatile void __iomem *cfg_data;
74 u8 cfg_type = 0;
75
76 if (ppc_md.pci_exclude_device)
77 if (ppc_md.pci_exclude_device(bus->number, devfn))
78 return PCIBIOS_DEVICE_NOT_FOUND;
79
80 if (hose->set_cfg_type)
81 if (bus->number != hose->first_busno)
82 cfg_type = 1;
83
84 PCI_CFG_OUT(hose->cfg_addr,
85 (0x80000000 | ((bus->number - hose->bus_offset) << 16)
86 | (devfn << 8) | ((offset & 0xfc) | cfg_type)));
87
88 /*
89 * Note: the caller has already checked that offset is
90 * suitably aligned and that len is 1, 2 or 4.
91 */
92 cfg_data = hose->cfg_data + (offset & 3);
93 switch (len) {
94 case 1:
95 out_8(cfg_data, val);
96 break;
97 case 2:
98 out_le16(cfg_data, val);
99 break;
100 default:
101 out_le32(cfg_data, val);
102 break;
103 }
104 return PCIBIOS_SUCCESSFUL;
105}
106
107static struct pci_ops indirect_pci_ops =
108{
109 indirect_read_config,
110 indirect_write_config
111};
112
113void __init
114setup_indirect_pci_nomap(struct pci_controller* hose, void __iomem * cfg_addr,
115 void __iomem * cfg_data)
116{
117 hose->cfg_addr = cfg_addr;
118 hose->cfg_data = cfg_data;
119 hose->ops = &indirect_pci_ops;
120}
121
122void __init
123setup_indirect_pci(struct pci_controller* hose, u32 cfg_addr, u32 cfg_data)
124{
125 unsigned long base = cfg_addr & PAGE_MASK;
126 void __iomem *mbase, *addr, *data;
127
128 mbase = ioremap(base, PAGE_SIZE);
129 addr = mbase + (cfg_addr & ~PAGE_MASK);
130 if ((cfg_data & PAGE_MASK) != base)
131 mbase = ioremap(cfg_data & PAGE_MASK, PAGE_SIZE);
132 data = mbase + (cfg_data & ~PAGE_MASK);
133 setup_indirect_pci_nomap(hose, addr, data);
134}
diff --git a/arch/ppc/syslib/virtex_devices.c b/arch/ppc/syslib/virtex_devices.c
index 16546788e23b..ace4ec08de51 100644
--- a/arch/ppc/syslib/virtex_devices.c
+++ b/arch/ppc/syslib/virtex_devices.c
@@ -71,6 +71,21 @@
71 }, \ 71 }, \
72} 72}
73 73
74/*
75 * ML300/ML403 Video Device: shortcut macro for single instance
76 */
77#define XPAR_TFT(num) { \
78 .name = "xilinxfb", \
79 .id = num, \
80 .num_resources = 1, \
81 .resource = (struct resource[]) { \
82 { \
83 .start = XPAR_TFT_##num##_BASEADDR, \
84 .end = XPAR_TFT_##num##_BASEADDR+7, \
85 .flags = IORESOURCE_IO, \
86 }, \
87 }, \
88}
74 89
75/* UART 8250 driver platform data table */ 90/* UART 8250 driver platform data table */
76struct plat_serial8250_port virtex_serial_platform_data[] = { 91struct plat_serial8250_port virtex_serial_platform_data[] = {
@@ -146,20 +161,17 @@ struct platform_device virtex_platform_devices[] = {
146 XPAR_SYSACE(1), 161 XPAR_SYSACE(1),
147#endif 162#endif
148 163
149 /* ML300/403 reference design framebuffer */
150#if defined(XPAR_TFT_0_BASEADDR) 164#if defined(XPAR_TFT_0_BASEADDR)
151 { 165 XPAR_TFT(0),
152 .name = "xilinxfb", 166#endif
153 .id = 0, 167#if defined(XPAR_TFT_1_BASEADDR)
154 .num_resources = 1, 168 XPAR_TFT(1),
155 .resource = (struct resource[]) { 169#endif
156 { 170#if defined(XPAR_TFT_2_BASEADDR)
157 .start = XPAR_TFT_0_BASEADDR, 171 XPAR_TFT(2),
158 .end = XPAR_TFT_0_BASEADDR+7, 172#endif
159 .flags = IORESOURCE_IO, 173#if defined(XPAR_TFT_3_BASEADDR)
160 }, 174 XPAR_TFT(3),
161 },
162 },
163#endif 175#endif
164}; 176};
165 177