aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/Kconfig83
-rw-r--r--arch/powerpc/boot/.gitignore1
-rw-r--r--arch/powerpc/boot/Makefile2
-rw-r--r--arch/powerpc/boot/dts/canyonlands.dts37
-rw-r--r--arch/powerpc/boot/dts/glacier.dts37
-rw-r--r--arch/powerpc/boot/ns16550.c5
-rw-r--r--arch/powerpc/kernel/Makefile9
-rw-r--r--arch/powerpc/kernel/asm-offsets.c11
-rw-r--r--arch/powerpc/kernel/cpu_setup_44x.S1
-rw-r--r--arch/powerpc/kernel/cpu_setup_6xx.S8
-rw-r--r--arch/powerpc/kernel/cputable.c4
-rw-r--r--arch/powerpc/kernel/head_fsl_booke.S11
-rw-r--r--arch/powerpc/kernel/misc_32.S6
-rw-r--r--arch/powerpc/kernel/misc_64.S20
-rw-r--r--arch/powerpc/kernel/of_platform.c2
-rw-r--r--arch/powerpc/kernel/paca.c87
-rw-r--r--arch/powerpc/kernel/ppc32.h2
-rw-r--r--arch/powerpc/kernel/process.c31
-rw-r--r--arch/powerpc/kernel/prom.c4
-rw-r--r--arch/powerpc/kernel/prom_init_check.sh58
-rw-r--r--arch/powerpc/kernel/ptrace32.c27
-rw-r--r--arch/powerpc/kernel/setup_64.c5
-rw-r--r--arch/powerpc/kernel/stacktrace.c1
-rw-r--r--arch/powerpc/kernel/udbg.c4
-rw-r--r--arch/powerpc/mm/fsl_booke_mmu.c2
-rw-r--r--arch/powerpc/mm/hash_low_32.S4
-rw-r--r--arch/powerpc/mm/init_32.c13
-rw-r--r--arch/powerpc/mm/init_64.c3
-rw-r--r--arch/powerpc/mm/mem.c37
-rw-r--r--arch/powerpc/mm/numa.c1
-rw-r--r--arch/powerpc/mm/pgtable_32.c23
-rw-r--r--arch/powerpc/platforms/Kconfig1
-rw-r--r--arch/powerpc/platforms/Kconfig.cputype4
-rw-r--r--arch/powerpc/platforms/Makefile1
-rw-r--r--arch/powerpc/platforms/cell/Kconfig13
-rw-r--r--arch/powerpc/platforms/cell/Makefile20
-rw-r--r--arch/powerpc/platforms/cell/axon_msi.c6
-rw-r--r--arch/powerpc/platforms/cell/beat.c (renamed from arch/powerpc/platforms/celleb/beat.c)2
-rw-r--r--arch/powerpc/platforms/cell/beat.h (renamed from arch/powerpc/platforms/celleb/beat.h)0
-rw-r--r--arch/powerpc/platforms/cell/beat_htab.c (renamed from arch/powerpc/platforms/celleb/htab.c)0
-rw-r--r--arch/powerpc/platforms/cell/beat_hvCall.S (renamed from arch/powerpc/platforms/celleb/hvCall.S)0
-rw-r--r--arch/powerpc/platforms/cell/beat_interrupt.c (renamed from arch/powerpc/platforms/celleb/interrupt.c)2
-rw-r--r--arch/powerpc/platforms/cell/beat_interrupt.h (renamed from arch/powerpc/platforms/celleb/interrupt.h)0
-rw-r--r--arch/powerpc/platforms/cell/beat_iommu.c (renamed from arch/powerpc/platforms/celleb/iommu.c)0
-rw-r--r--arch/powerpc/platforms/cell/beat_smp.c (renamed from arch/powerpc/platforms/celleb/smp.c)2
-rw-r--r--arch/powerpc/platforms/cell/beat_spu_priv1.c (renamed from arch/powerpc/platforms/celleb/spu_priv1.c)0
-rw-r--r--arch/powerpc/platforms/cell/beat_syscall.h (renamed from arch/powerpc/platforms/celleb/beat_syscall.h)0
-rw-r--r--arch/powerpc/platforms/cell/beat_udbg.c (renamed from arch/powerpc/platforms/celleb/udbg_beat.c)0
-rw-r--r--arch/powerpc/platforms/cell/beat_wrapper.h (renamed from arch/powerpc/platforms/celleb/beat_wrapper.h)0
-rw-r--r--arch/powerpc/platforms/cell/celleb_pci.c (renamed from arch/powerpc/platforms/celleb/pci.c)50
-rw-r--r--arch/powerpc/platforms/cell/celleb_pci.h (renamed from arch/powerpc/platforms/celleb/pci.h)19
-rw-r--r--arch/powerpc/platforms/cell/celleb_scc.h (renamed from arch/powerpc/platforms/celleb/scc.h)87
-rw-r--r--arch/powerpc/platforms/cell/celleb_scc_epci.c (renamed from arch/powerpc/platforms/celleb/scc_epci.c)77
-rw-r--r--arch/powerpc/platforms/cell/celleb_scc_pciex.c547
-rw-r--r--arch/powerpc/platforms/cell/celleb_scc_sio.c (renamed from arch/powerpc/platforms/celleb/scc_sio.c)0
-rw-r--r--arch/powerpc/platforms/cell/celleb_scc_uhc.c (renamed from arch/powerpc/platforms/celleb/scc_uhc.c)2
-rw-r--r--arch/powerpc/platforms/cell/celleb_setup.c (renamed from arch/powerpc/platforms/celleb/setup.c)12
-rw-r--r--arch/powerpc/platforms/cell/io-workarounds.c358
-rw-r--r--arch/powerpc/platforms/cell/io-workarounds.h49
-rw-r--r--arch/powerpc/platforms/cell/setup.c43
-rw-r--r--arch/powerpc/platforms/cell/spider-pci.c184
-rw-r--r--arch/powerpc/platforms/celleb/Kconfig12
-rw-r--r--arch/powerpc/platforms/celleb/Makefile9
-rw-r--r--arch/powerpc/platforms/celleb/io-workarounds.c280
-rw-r--r--arch/powerpc/platforms/iseries/exception.S27
-rw-r--r--arch/powerpc/platforms/ps3/os-area.c1
-rw-r--r--arch/powerpc/platforms/pseries/Kconfig5
-rw-r--r--arch/powerpc/platforms/pseries/Makefile4
-rw-r--r--arch/powerpc/platforms/pseries/eeh.c1
-rw-r--r--arch/powerpc/platforms/pseries/eeh_cache.c1
-rw-r--r--arch/powerpc/platforms/pseries/firmware.c10
-rw-r--r--arch/powerpc/platforms/pseries/iommu.c39
-rw-r--r--arch/powerpc/platforms/pseries/lpar.c36
-rw-r--r--arch/powerpc/platforms/pseries/ras.c4
-rw-r--r--arch/powerpc/platforms/pseries/rtasd.c14
-rw-r--r--arch/powerpc/platforms/pseries/scanlog.c23
-rw-r--r--arch/powerpc/platforms/pseries/setup.c17
-rw-r--r--arch/powerpc/platforms/pseries/smp.c11
-rw-r--r--arch/powerpc/platforms/pseries/xics.c1
-rw-r--r--arch/powerpc/sysdev/mv64x60_dev.c52
-rw-r--r--arch/powerpc/sysdev/mv64x60_udbg.c2
81 files changed, 1609 insertions, 958 deletions
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 4bb2e9310a56..20f45a8b87e3 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -626,20 +626,6 @@ config ADVANCED_OPTIONS
626comment "Default settings for advanced configuration options are used" 626comment "Default settings for advanced configuration options are used"
627 depends on !ADVANCED_OPTIONS 627 depends on !ADVANCED_OPTIONS
628 628
629config HIGHMEM_START_BOOL
630 bool "Set high memory pool address"
631 depends on ADVANCED_OPTIONS && HIGHMEM
632 help
633 This option allows you to set the base address of the kernel virtual
634 area used to map high memory pages. This can be useful in
635 optimizing the layout of kernel virtual memory.
636
637 Say N here unless you know what you are doing.
638
639config HIGHMEM_START
640 hex "Virtual start address of high memory pool" if HIGHMEM_START_BOOL
641 default "0xfe000000"
642
643config LOWMEM_SIZE_BOOL 629config LOWMEM_SIZE_BOOL
644 bool "Set maximum low memory" 630 bool "Set maximum low memory"
645 depends on ADVANCED_OPTIONS 631 depends on ADVANCED_OPTIONS
@@ -656,21 +642,76 @@ config LOWMEM_SIZE
656 hex "Maximum low memory size (in bytes)" if LOWMEM_SIZE_BOOL 642 hex "Maximum low memory size (in bytes)" if LOWMEM_SIZE_BOOL
657 default "0x30000000" 643 default "0x30000000"
658 644
645config RELOCATABLE
646 bool "Build a relocatable kernel (EXPERIMENTAL)"
647 depends on EXPERIMENTAL && ADVANCED_OPTIONS && FLATMEM && FSL_BOOKE
648 help
649 This builds a kernel image that is capable of running at the
650 location the kernel is loaded at (some alignment restrictions may
651 exist).
652
653 One use is for the kexec on panic case where the recovery kernel
654 must live at a different physical address than the primary
655 kernel.
656
657 Note: If CONFIG_RELOCATABLE=y, then the kernel runs from the address
658 it has been loaded at and the compile time physical addresses
659 CONFIG_PHYSICAL_START is ignored. However CONFIG_PHYSICAL_START
660 setting can still be useful to bootwrappers that need to know the
661 load location of the kernel (eg. u-boot/mkimage).
662
663config PAGE_OFFSET_BOOL
664 bool "Set custom page offset address"
665 depends on ADVANCED_OPTIONS
666 help
667 This option allows you to set the kernel virtual address at which
668 the kernel will map low memory. This can be useful in optimizing
669 the virtual memory layout of the system.
670
671 Say N here unless you know what you are doing.
672
673config PAGE_OFFSET
674 hex "Virtual address of memory base" if PAGE_OFFSET_BOOL
675 default "0xc0000000"
676
659config KERNEL_START_BOOL 677config KERNEL_START_BOOL
660 bool "Set custom kernel base address" 678 bool "Set custom kernel base address"
661 depends on ADVANCED_OPTIONS 679 depends on ADVANCED_OPTIONS
662 help 680 help
663 This option allows you to set the kernel virtual address at which 681 This option allows you to set the kernel virtual address at which
664 the kernel will map low memory (the kernel image will be linked at 682 the kernel will be loaded. Normally this should match PAGE_OFFSET
665 this address). This can be useful in optimizing the virtual memory 683 however there are times (like kdump) that one might not want them
666 layout of the system. 684 to be the same.
667 685
668 Say N here unless you know what you are doing. 686 Say N here unless you know what you are doing.
669 687
670config KERNEL_START 688config KERNEL_START
671 hex "Virtual address of kernel base" if KERNEL_START_BOOL 689 hex "Virtual address of kernel base" if KERNEL_START_BOOL
690 default PAGE_OFFSET if PAGE_OFFSET_BOOL
691 default "0xc2000000" if CRASH_DUMP
672 default "0xc0000000" 692 default "0xc0000000"
673 693
694config PHYSICAL_START_BOOL
695 bool "Set physical address where the kernel is loaded"
696 depends on ADVANCED_OPTIONS && FLATMEM && FSL_BOOKE
697 help
698 This gives the physical address where the kernel is loaded.
699
700 Say N here unless you know what you are doing.
701
702config PHYSICAL_START
703 hex "Physical address where the kernel is loaded" if PHYSICAL_START_BOOL
704 default "0x02000000" if PPC_STD_MMU && CRASH_DUMP
705 default "0x00000000"
706
707config PHYSICAL_ALIGN
708 hex
709 default "0x10000000" if FSL_BOOKE
710 help
711 This value puts the alignment restrictions on physical address
712 where kernel is loaded and run from. Kernel is compiled for an
713 address which meets above alignment restriction.
714
674config TASK_SIZE_BOOL 715config TASK_SIZE_BOOL
675 bool "Set custom user task size" 716 bool "Set custom user task size"
676 depends on ADVANCED_OPTIONS 717 depends on ADVANCED_OPTIONS
@@ -717,9 +758,17 @@ config PIN_TLB
717endmenu 758endmenu
718 759
719if PPC64 760if PPC64
761config PAGE_OFFSET
762 hex
763 default "0xc000000000000000"
720config KERNEL_START 764config KERNEL_START
721 hex 765 hex
766 default "0xc000000002000000" if CRASH_DUMP
722 default "0xc000000000000000" 767 default "0xc000000000000000"
768config PHYSICAL_START
769 hex
770 default "0x02000000" if CRASH_DUMP
771 default "0x00000000"
723endif 772endif
724 773
725source "net/Kconfig" 774source "net/Kconfig"
diff --git a/arch/powerpc/boot/.gitignore b/arch/powerpc/boot/.gitignore
index 5ef2bdf8d189..2347294ff35b 100644
--- a/arch/powerpc/boot/.gitignore
+++ b/arch/powerpc/boot/.gitignore
@@ -27,6 +27,7 @@ zImage.chrp
27zImage.coff 27zImage.coff
28zImage.coff.lds 28zImage.coff.lds
29zImage.ep* 29zImage.ep*
30zImage.iseries
30zImage.*lds 31zImage.*lds
31zImage.miboot 32zImage.miboot
32zImage.pmac 33zImage.pmac
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index 5ba50c673390..7822d25c9d31 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -40,7 +40,7 @@ $(obj)/ebony.o: BOOTCFLAGS += -mcpu=405
40$(obj)/cuboot-taishan.o: BOOTCFLAGS += -mcpu=405 40$(obj)/cuboot-taishan.o: BOOTCFLAGS += -mcpu=405
41$(obj)/cuboot-katmai.o: BOOTCFLAGS += -mcpu=405 41$(obj)/cuboot-katmai.o: BOOTCFLAGS += -mcpu=405
42$(obj)/treeboot-walnut.o: BOOTCFLAGS += -mcpu=405 42$(obj)/treeboot-walnut.o: BOOTCFLAGS += -mcpu=405
43$(obj)/virtex405-head.o: BOOTCFLAGS += -mcpu=405 43$(obj)/virtex405-head.o: BOOTAFLAGS += -mcpu=405
44 44
45 45
46zlib := inffast.c inflate.c inftrees.c 46zlib := inffast.c inflate.c inftrees.c
diff --git a/arch/powerpc/boot/dts/canyonlands.dts b/arch/powerpc/boot/dts/canyonlands.dts
index 6f3d38a1554f..39634124929b 100644
--- a/arch/powerpc/boot/dts/canyonlands.dts
+++ b/arch/powerpc/boot/dts/canyonlands.dts
@@ -142,8 +142,45 @@
142 #address-cells = <2>; 142 #address-cells = <2>;
143 #size-cells = <1>; 143 #size-cells = <1>;
144 clock-frequency = <0>; /* Filled in by U-Boot */ 144 clock-frequency = <0>; /* Filled in by U-Boot */
145 /* ranges property is supplied by U-Boot */
145 interrupts = <6 4>; 146 interrupts = <6 4>;
146 interrupt-parent = <&UIC1>; 147 interrupt-parent = <&UIC1>;
148
149 nor_flash@0,0 {
150 compatible = "amd,s29gl512n", "cfi-flash";
151 bank-width = <2>;
152 reg = <0 000000 4000000>;
153 #address-cells = <1>;
154 #size-cells = <1>;
155 partition@0 {
156 label = "kernel";
157 reg = <0 1e0000>;
158 };
159 partition@1e0000 {
160 label = "dtb";
161 reg = <1e0000 20000>;
162 };
163 partition@200000 {
164 label = "ramdisk";
165 reg = <200000 1400000>;
166 };
167 partition@1600000 {
168 label = "jffs2";
169 reg = <1600000 400000>;
170 };
171 partition@1a00000 {
172 label = "user";
173 reg = <1a00000 2560000>;
174 };
175 partition@3f60000 {
176 label = "env";
177 reg = <3f60000 40000>;
178 };
179 partition@3fa0000 {
180 label = "u-boot";
181 reg = <3fa0000 60000>;
182 };
183 };
147 }; 184 };
148 185
149 UART0: serial@ef600300 { 186 UART0: serial@ef600300 {
diff --git a/arch/powerpc/boot/dts/glacier.dts b/arch/powerpc/boot/dts/glacier.dts
index 958a5ca53d35..0f2fc077d8db 100644
--- a/arch/powerpc/boot/dts/glacier.dts
+++ b/arch/powerpc/boot/dts/glacier.dts
@@ -145,8 +145,45 @@
145 #address-cells = <2>; 145 #address-cells = <2>;
146 #size-cells = <1>; 146 #size-cells = <1>;
147 clock-frequency = <0>; /* Filled in by U-Boot */ 147 clock-frequency = <0>; /* Filled in by U-Boot */
148 /* ranges property is supplied by U-Boot */
148 interrupts = <6 4>; 149 interrupts = <6 4>;
149 interrupt-parent = <&UIC1>; 150 interrupt-parent = <&UIC1>;
151
152 nor_flash@0,0 {
153 compatible = "amd,s29gl512n", "cfi-flash";
154 bank-width = <2>;
155 reg = <0 000000 4000000>;
156 #address-cells = <1>;
157 #size-cells = <1>;
158 partition@0 {
159 label = "kernel";
160 reg = <0 1e0000>;
161 };
162 partition@1e0000 {
163 label = "dtb";
164 reg = <1e0000 20000>;
165 };
166 partition@200000 {
167 label = "ramdisk";
168 reg = <200000 1400000>;
169 };
170 partition@1600000 {
171 label = "jffs2";
172 reg = <1600000 400000>;
173 };
174 partition@1a00000 {
175 label = "user";
176 reg = <1a00000 2560000>;
177 };
178 partition@3f60000 {
179 label = "env";
180 reg = <3f60000 40000>;
181 };
182 partition@3fa0000 {
183 label = "u-boot";
184 reg = <3fa0000 60000>;
185 };
186 };
150 }; 187 };
151 188
152 UART0: serial@ef600300 { 189 UART0: serial@ef600300 {
diff --git a/arch/powerpc/boot/ns16550.c b/arch/powerpc/boot/ns16550.c
index aef3bdc89160..8c9ead94be06 100644
--- a/arch/powerpc/boot/ns16550.c
+++ b/arch/powerpc/boot/ns16550.c
@@ -55,10 +55,15 @@ static u8 ns16550_tstc(void)
55int ns16550_console_init(void *devp, struct serial_console_data *scdp) 55int ns16550_console_init(void *devp, struct serial_console_data *scdp)
56{ 56{
57 int n; 57 int n;
58 u32 reg_offset;
58 59
59 if (dt_get_virtual_reg(devp, (void **)&reg_base, 1) < 1) 60 if (dt_get_virtual_reg(devp, (void **)&reg_base, 1) < 1)
60 return -1; 61 return -1;
61 62
63 n = getprop(devp, "reg-offset", &reg_offset, sizeof(reg_offset));
64 if (n == sizeof(reg_offset))
65 reg_base += reg_offset;
66
62 n = getprop(devp, "reg-shift", &reg_shift, sizeof(reg_shift)); 67 n = getprop(devp, "reg-shift", &reg_shift, sizeof(reg_shift));
63 if (n != sizeof(reg_shift)) 68 if (n != sizeof(reg_shift))
64 reg_shift = 0; 69 reg_shift = 0;
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index ce1e8d24e747..9177b21b1a95 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -106,4 +106,13 @@ PHONY += systbl_chk
106systbl_chk: $(src)/systbl_chk.sh $(obj)/systbl_chk.i 106systbl_chk: $(src)/systbl_chk.sh $(obj)/systbl_chk.i
107 $(call cmd,systbl_chk) 107 $(call cmd,systbl_chk)
108 108
109$(obj)/built-in.o: prom_init_check
110
111quiet_cmd_prom_init_check = CALL $<
112 cmd_prom_init_check = $(CONFIG_SHELL) $< "$(NM)" "$(obj)/prom_init.o"
113
114PHONY += prom_init_check
115prom_init_check: $(src)/prom_init_check.sh $(obj)/prom_init.o
116 $(call cmd,prom_init_check)
117
109clean-files := vmlinux.lds 118clean-files := vmlinux.lds
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 292c6d8db0e1..adf1d09d726f 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -93,10 +93,7 @@ int main(void)
93 DEFINE(TI_LOCAL_FLAGS, offsetof(struct thread_info, local_flags)); 93 DEFINE(TI_LOCAL_FLAGS, offsetof(struct thread_info, local_flags));
94 DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count)); 94 DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count));
95 DEFINE(TI_TASK, offsetof(struct thread_info, task)); 95 DEFINE(TI_TASK, offsetof(struct thread_info, task));
96#ifdef CONFIG_PPC32
97 DEFINE(TI_EXECDOMAIN, offsetof(struct thread_info, exec_domain));
98 DEFINE(TI_CPU, offsetof(struct thread_info, cpu)); 96 DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
99#endif /* CONFIG_PPC32 */
100 97
101#ifdef CONFIG_PPC64 98#ifdef CONFIG_PPC64
102 DEFINE(DCACHEL1LINESIZE, offsetof(struct ppc64_caches, dline_size)); 99 DEFINE(DCACHEL1LINESIZE, offsetof(struct ppc64_caches, dline_size));
@@ -165,13 +162,9 @@ int main(void)
165 162
166 /* Interrupt register frame */ 163 /* Interrupt register frame */
167 DEFINE(STACK_FRAME_OVERHEAD, STACK_FRAME_OVERHEAD); 164 DEFINE(STACK_FRAME_OVERHEAD, STACK_FRAME_OVERHEAD);
168#ifndef CONFIG_PPC64 165 DEFINE(INT_FRAME_SIZE, STACK_INT_FRAME_SIZE);
169 DEFINE(INT_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs)); 166#ifdef CONFIG_PPC64
170#else /* CONFIG_PPC64 */
171 DEFINE(SWITCH_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs)); 167 DEFINE(SWITCH_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs));
172 /* 288 = # of volatile regs, int & fp, for leaf routines */
173 /* which do not stack a frame. See the PPC64 ABI. */
174 DEFINE(INT_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs) + 288);
175 /* Create extra stack space for SRR0 and SRR1 when calling prom/rtas. */ 168 /* Create extra stack space for SRR0 and SRR1 when calling prom/rtas. */
176 DEFINE(PROM_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs) + 16); 169 DEFINE(PROM_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs) + 16);
177 DEFINE(RTAS_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs) + 16); 170 DEFINE(RTAS_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs) + 16);
diff --git a/arch/powerpc/kernel/cpu_setup_44x.S b/arch/powerpc/kernel/cpu_setup_44x.S
index 5465e8de0e61..e3623e3e3451 100644
--- a/arch/powerpc/kernel/cpu_setup_44x.S
+++ b/arch/powerpc/kernel/cpu_setup_44x.S
@@ -33,7 +33,6 @@ _GLOBAL(__setup_cpu_440grx)
33 mtlr r4 33 mtlr r4
34 blr 34 blr
35_GLOBAL(__setup_cpu_460ex) 35_GLOBAL(__setup_cpu_460ex)
36_GLOBAL(__setup_cpu_460gt)
37 b __init_fpu_44x 36 b __init_fpu_44x
38_GLOBAL(__setup_cpu_440gx) 37_GLOBAL(__setup_cpu_440gx)
39_GLOBAL(__setup_cpu_440spe) 38_GLOBAL(__setup_cpu_440spe)
diff --git a/arch/powerpc/kernel/cpu_setup_6xx.S b/arch/powerpc/kernel/cpu_setup_6xx.S
index f1ee0b3f78f2..72d1d7395254 100644
--- a/arch/powerpc/kernel/cpu_setup_6xx.S
+++ b/arch/powerpc/kernel/cpu_setup_6xx.S
@@ -17,7 +17,13 @@
17#include <asm/cache.h> 17#include <asm/cache.h>
18 18
19_GLOBAL(__setup_cpu_603) 19_GLOBAL(__setup_cpu_603)
20 b setup_common_caches 20 mflr r4
21BEGIN_FTR_SECTION
22 bl __init_fpu_registers
23END_FTR_SECTION_IFCLR(CPU_FTR_FPU_UNAVAILABLE)
24 bl setup_common_caches
25 mtlr r4
26 blr
21_GLOBAL(__setup_cpu_604) 27_GLOBAL(__setup_cpu_604)
22 mflr r4 28 mflr r4
23 bl setup_common_caches 29 bl setup_common_caches
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index 26ffb44e2701..36080d4d1922 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -37,7 +37,6 @@ extern void __setup_cpu_440gx(unsigned long offset, struct cpu_spec* spec);
37extern void __setup_cpu_440grx(unsigned long offset, struct cpu_spec* spec); 37extern void __setup_cpu_440grx(unsigned long offset, struct cpu_spec* spec);
38extern void __setup_cpu_440spe(unsigned long offset, struct cpu_spec* spec); 38extern void __setup_cpu_440spe(unsigned long offset, struct cpu_spec* spec);
39extern void __setup_cpu_460ex(unsigned long offset, struct cpu_spec* spec); 39extern void __setup_cpu_460ex(unsigned long offset, struct cpu_spec* spec);
40extern void __setup_cpu_460gt(unsigned long offset, struct cpu_spec* spec);
41extern void __setup_cpu_603(unsigned long offset, struct cpu_spec* spec); 40extern void __setup_cpu_603(unsigned long offset, struct cpu_spec* spec);
42extern void __setup_cpu_604(unsigned long offset, struct cpu_spec* spec); 41extern void __setup_cpu_604(unsigned long offset, struct cpu_spec* spec);
43extern void __setup_cpu_750(unsigned long offset, struct cpu_spec* spec); 42extern void __setup_cpu_750(unsigned long offset, struct cpu_spec* spec);
@@ -1416,10 +1415,9 @@ static struct cpu_spec __initdata cpu_specs[] = {
1416 .pvr_value = 0x13020000, 1415 .pvr_value = 0x13020000,
1417 .cpu_name = "460GT", 1416 .cpu_name = "460GT",
1418 .cpu_features = CPU_FTRS_44X, 1417 .cpu_features = CPU_FTRS_44X,
1419 .cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU, 1418 .cpu_user_features = COMMON_USER_BOOKE,
1420 .icache_bsize = 32, 1419 .icache_bsize = 32,
1421 .dcache_bsize = 32, 1420 .dcache_bsize = 32,
1422 .cpu_setup = __setup_cpu_460gt,
1423 .machine_check = machine_check_440A, 1421 .machine_check = machine_check_440A,
1424 .platform = "ppc440", 1422 .platform = "ppc440",
1425 }, 1423 },
diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S
index 4ff744143566..e581524d85bc 100644
--- a/arch/powerpc/kernel/head_fsl_booke.S
+++ b/arch/powerpc/kernel/head_fsl_booke.S
@@ -371,6 +371,17 @@ skpinv: addi r6,r6,1 /* Increment */
371 371
372 bl early_init 372 bl early_init
373 373
374#ifdef CONFIG_RELOCATABLE
375 lis r3,kernstart_addr@ha
376 la r3,kernstart_addr@l(r3)
377#ifdef CONFIG_PHYS_64BIT
378 stw r23,0(r3)
379 stw r25,4(r3)
380#else
381 stw r25,0(r3)
382#endif
383#endif
384
374 mfspr r3,SPRN_TLB1CFG 385 mfspr r3,SPRN_TLB1CFG
375 andi. r3,r3,0xfff 386 andi. r3,r3,0xfff
376 lis r4,num_tlbcam_entries@ha 387 lis r4,num_tlbcam_entries@ha
diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S
index 9d2c56621f1e..92ccc6fcc5b0 100644
--- a/arch/powerpc/kernel/misc_32.S
+++ b/arch/powerpc/kernel/misc_32.S
@@ -152,7 +152,7 @@ _GLOBAL(low_choose_750fx_pll)
152 mtspr SPRN_HID1,r4 152 mtspr SPRN_HID1,r4
153 153
154 /* Store new HID1 image */ 154 /* Store new HID1 image */
155 rlwinm r6,r1,0,0,18 155 rlwinm r6,r1,0,0,(31-THREAD_SHIFT)
156 lwz r6,TI_CPU(r6) 156 lwz r6,TI_CPU(r6)
157 slwi r6,r6,2 157 slwi r6,r6,2
158 addis r6,r6,nap_save_hid1@ha 158 addis r6,r6,nap_save_hid1@ha
@@ -281,7 +281,7 @@ _GLOBAL(_tlbia)
281#endif /* CONFIG_SMP */ 281#endif /* CONFIG_SMP */
282#else /* !(CONFIG_40x || CONFIG_44x || CONFIG_FSL_BOOKE) */ 282#else /* !(CONFIG_40x || CONFIG_44x || CONFIG_FSL_BOOKE) */
283#if defined(CONFIG_SMP) 283#if defined(CONFIG_SMP)
284 rlwinm r8,r1,0,0,18 284 rlwinm r8,r1,0,0,(31-THREAD_SHIFT)
285 lwz r8,TI_CPU(r8) 285 lwz r8,TI_CPU(r8)
286 oris r8,r8,10 286 oris r8,r8,10
287 mfmsr r10 287 mfmsr r10
@@ -377,7 +377,7 @@ _GLOBAL(_tlbie)
377#endif /* CONFIG_SMP */ 377#endif /* CONFIG_SMP */
378#else /* !(CONFIG_40x || CONFIG_44x || CONFIG_FSL_BOOKE) */ 378#else /* !(CONFIG_40x || CONFIG_44x || CONFIG_FSL_BOOKE) */
379#if defined(CONFIG_SMP) 379#if defined(CONFIG_SMP)
380 rlwinm r8,r1,0,0,18 380 rlwinm r8,r1,0,0,(31-THREAD_SHIFT)
381 lwz r8,TI_CPU(r8) 381 lwz r8,TI_CPU(r8)
382 oris r8,r8,11 382 oris r8,r8,11
383 mfmsr r10 383 mfmsr r10
diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S
index a3c491e88a72..942951e76586 100644
--- a/arch/powerpc/kernel/misc_64.S
+++ b/arch/powerpc/kernel/misc_64.S
@@ -27,23 +27,11 @@
27 27
28 .text 28 .text
29 29
30_GLOBAL(get_msr)
31 mfmsr r3
32 blr
33
34_GLOBAL(get_srr0)
35 mfsrr0 r3
36 blr
37
38_GLOBAL(get_srr1)
39 mfsrr1 r3
40 blr
41
42#ifdef CONFIG_IRQSTACKS 30#ifdef CONFIG_IRQSTACKS
43_GLOBAL(call_do_softirq) 31_GLOBAL(call_do_softirq)
44 mflr r0 32 mflr r0
45 std r0,16(r1) 33 std r0,16(r1)
46 stdu r1,THREAD_SIZE-112(r3) 34 stdu r1,THREAD_SIZE-STACK_FRAME_OVERHEAD(r3)
47 mr r1,r3 35 mr r1,r3
48 bl .__do_softirq 36 bl .__do_softirq
49 ld r1,0(r1) 37 ld r1,0(r1)
@@ -56,7 +44,7 @@ _GLOBAL(call_handle_irq)
56 mflr r0 44 mflr r0
57 std r0,16(r1) 45 std r0,16(r1)
58 mtctr r8 46 mtctr r8
59 stdu r1,THREAD_SIZE-112(r5) 47 stdu r1,THREAD_SIZE-STACK_FRAME_OVERHEAD(r5)
60 mr r1,r5 48 mr r1,r5
61 bctrl 49 bctrl
62 ld r1,0(r1) 50 ld r1,0(r1)
@@ -599,7 +587,7 @@ _GLOBAL(kexec_sequence)
599 std r0,16(r1) 587 std r0,16(r1)
600 588
601 /* switch stacks to newstack -- &kexec_stack.stack */ 589 /* switch stacks to newstack -- &kexec_stack.stack */
602 stdu r1,THREAD_SIZE-112(r3) 590 stdu r1,THREAD_SIZE-STACK_FRAME_OVERHEAD(r3)
603 mr r1,r3 591 mr r1,r3
604 592
605 li r0,0 593 li r0,0
@@ -616,7 +604,7 @@ _GLOBAL(kexec_sequence)
616 std r26,-48(r1) 604 std r26,-48(r1)
617 std r25,-56(r1) 605 std r25,-56(r1)
618 606
619 stdu r1,-112-64(r1) 607 stdu r1,-STACK_FRAME_OVERHEAD-64(r1)
620 608
621 /* save args into preserved regs */ 609 /* save args into preserved regs */
622 mr r31,r3 /* newstack (both) */ 610 mr r31,r3 /* newstack (both) */
diff --git a/arch/powerpc/kernel/of_platform.c b/arch/powerpc/kernel/of_platform.c
index fb698d47082d..e79ad8afda07 100644
--- a/arch/powerpc/kernel/of_platform.c
+++ b/arch/powerpc/kernel/of_platform.c
@@ -275,6 +275,8 @@ static int __devinit of_pci_phb_probe(struct of_device *dev,
275 275
276 /* Scan the bus */ 276 /* Scan the bus */
277 scan_phb(phb); 277 scan_phb(phb);
278 if (phb->bus == NULL)
279 return -ENXIO;
278 280
279 /* Claim resources. This might need some rework as well depending 281 /* Claim resources. This might need some rework as well depending
280 * wether we are doing probe-only or not, like assigning unassigned 282 * wether we are doing probe-only or not, like assigning unassigned
diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c
index ac163bd46cfd..c9bf17eec31b 100644
--- a/arch/powerpc/kernel/paca.c
+++ b/arch/powerpc/kernel/paca.c
@@ -7,17 +7,11 @@
7 * 2 of the License, or (at your option) any later version. 7 * 2 of the License, or (at your option) any later version.
8 */ 8 */
9 9
10#include <linux/types.h>
11#include <linux/threads.h> 10#include <linux/threads.h>
12#include <linux/module.h> 11#include <linux/module.h>
13 12
14#include <asm/processor.h>
15#include <asm/ptrace.h>
16#include <asm/page.h>
17#include <asm/lppaca.h> 13#include <asm/lppaca.h>
18#include <asm/paca.h> 14#include <asm/paca.h>
19#include <asm/mmu.h>
20
21 15
22/* This symbol is provided by the linker - let it fill in the paca 16/* This symbol is provided by the linker - let it fill in the paca
23 * field correctly */ 17 * field correctly */
@@ -65,60 +59,29 @@ struct slb_shadow slb_shadow[] __cacheline_aligned = {
65 * processors. The processor VPD array needs one entry per physical 59 * processors. The processor VPD array needs one entry per physical
66 * processor (not thread). 60 * processor (not thread).
67 */ 61 */
68#define PACA_INIT(number) \ 62struct paca_struct paca[NR_CPUS];
69{ \
70 .lppaca_ptr = &lppaca[number], \
71 .lock_token = 0x8000, \
72 .paca_index = (number), /* Paca Index */ \
73 .kernel_toc = (unsigned long)(&__toc_start) + 0x8000UL, \
74 .hw_cpu_id = 0xffff, \
75 .slb_shadow_ptr = &slb_shadow[number], \
76 .__current = &init_task, \
77}
78
79struct paca_struct paca[] = {
80 PACA_INIT(0),
81#if NR_CPUS > 1
82 PACA_INIT( 1), PACA_INIT( 2), PACA_INIT( 3),
83#if NR_CPUS > 4
84 PACA_INIT( 4), PACA_INIT( 5), PACA_INIT( 6), PACA_INIT( 7),
85#if NR_CPUS > 8
86 PACA_INIT( 8), PACA_INIT( 9), PACA_INIT( 10), PACA_INIT( 11),
87 PACA_INIT( 12), PACA_INIT( 13), PACA_INIT( 14), PACA_INIT( 15),
88 PACA_INIT( 16), PACA_INIT( 17), PACA_INIT( 18), PACA_INIT( 19),
89 PACA_INIT( 20), PACA_INIT( 21), PACA_INIT( 22), PACA_INIT( 23),
90 PACA_INIT( 24), PACA_INIT( 25), PACA_INIT( 26), PACA_INIT( 27),
91 PACA_INIT( 28), PACA_INIT( 29), PACA_INIT( 30), PACA_INIT( 31),
92#if NR_CPUS > 32
93 PACA_INIT( 32), PACA_INIT( 33), PACA_INIT( 34), PACA_INIT( 35),
94 PACA_INIT( 36), PACA_INIT( 37), PACA_INIT( 38), PACA_INIT( 39),
95 PACA_INIT( 40), PACA_INIT( 41), PACA_INIT( 42), PACA_INIT( 43),
96 PACA_INIT( 44), PACA_INIT( 45), PACA_INIT( 46), PACA_INIT( 47),
97 PACA_INIT( 48), PACA_INIT( 49), PACA_INIT( 50), PACA_INIT( 51),
98 PACA_INIT( 52), PACA_INIT( 53), PACA_INIT( 54), PACA_INIT( 55),
99 PACA_INIT( 56), PACA_INIT( 57), PACA_INIT( 58), PACA_INIT( 59),
100 PACA_INIT( 60), PACA_INIT( 61), PACA_INIT( 62), PACA_INIT( 63),
101#if NR_CPUS > 64
102 PACA_INIT( 64), PACA_INIT( 65), PACA_INIT( 66), PACA_INIT( 67),
103 PACA_INIT( 68), PACA_INIT( 69), PACA_INIT( 70), PACA_INIT( 71),
104 PACA_INIT( 72), PACA_INIT( 73), PACA_INIT( 74), PACA_INIT( 75),
105 PACA_INIT( 76), PACA_INIT( 77), PACA_INIT( 78), PACA_INIT( 79),
106 PACA_INIT( 80), PACA_INIT( 81), PACA_INIT( 82), PACA_INIT( 83),
107 PACA_INIT( 84), PACA_INIT( 85), PACA_INIT( 86), PACA_INIT( 87),
108 PACA_INIT( 88), PACA_INIT( 89), PACA_INIT( 90), PACA_INIT( 91),
109 PACA_INIT( 92), PACA_INIT( 93), PACA_INIT( 94), PACA_INIT( 95),
110 PACA_INIT( 96), PACA_INIT( 97), PACA_INIT( 98), PACA_INIT( 99),
111 PACA_INIT(100), PACA_INIT(101), PACA_INIT(102), PACA_INIT(103),
112 PACA_INIT(104), PACA_INIT(105), PACA_INIT(106), PACA_INIT(107),
113 PACA_INIT(108), PACA_INIT(109), PACA_INIT(110), PACA_INIT(111),
114 PACA_INIT(112), PACA_INIT(113), PACA_INIT(114), PACA_INIT(115),
115 PACA_INIT(116), PACA_INIT(117), PACA_INIT(118), PACA_INIT(119),
116 PACA_INIT(120), PACA_INIT(121), PACA_INIT(122), PACA_INIT(123),
117 PACA_INIT(124), PACA_INIT(125), PACA_INIT(126), PACA_INIT(127),
118#endif
119#endif
120#endif
121#endif
122#endif
123};
124EXPORT_SYMBOL(paca); 63EXPORT_SYMBOL(paca);
64
65void __init initialise_pacas(void)
66{
67 int cpu;
68
69 /* The TOC register (GPR2) points 32kB into the TOC, so that 64kB
70 * of the TOC can be addressed using a single machine instruction.
71 */
72 unsigned long kernel_toc = (unsigned long)(&__toc_start) + 0x8000UL;
73
74 /* Can't use for_each_*_cpu, as they aren't functional yet */
75 for (cpu = 0; cpu < NR_CPUS; cpu++) {
76 struct paca_struct *new_paca = &paca[cpu];
77
78 new_paca->lppaca_ptr = &lppaca[cpu];
79 new_paca->lock_token = 0x8000;
80 new_paca->paca_index = cpu;
81 new_paca->kernel_toc = kernel_toc;
82 new_paca->hw_cpu_id = 0xffff;
83 new_paca->slb_shadow_ptr = &slb_shadow[cpu];
84 new_paca->__current = &init_task;
85
86 }
87}
diff --git a/arch/powerpc/kernel/ppc32.h b/arch/powerpc/kernel/ppc32.h
index fda05e2211d6..90e562771791 100644
--- a/arch/powerpc/kernel/ppc32.h
+++ b/arch/powerpc/kernel/ppc32.h
@@ -135,6 +135,4 @@ struct ucontext32 {
135 struct mcontext32 uc_mcontext; 135 struct mcontext32 uc_mcontext;
136}; 136};
137 137
138extern int copy_siginfo_to_user32(struct compat_siginfo __user *d, siginfo_t *s);
139
140#endif /* _PPC64_PPC32_H */ 138#endif /* _PPC64_PPC32_H */
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 703100d5e458..6caad17ea72e 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -1033,3 +1033,34 @@ void ppc64_runlatch_off(void)
1033 } 1033 }
1034} 1034}
1035#endif 1035#endif
1036
1037#if THREAD_SHIFT < PAGE_SHIFT
1038
1039static struct kmem_cache *thread_info_cache;
1040
1041struct thread_info *alloc_thread_info(struct task_struct *tsk)
1042{
1043 struct thread_info *ti;
1044
1045 ti = kmem_cache_alloc(thread_info_cache, GFP_KERNEL);
1046 if (unlikely(ti == NULL))
1047 return NULL;
1048#ifdef CONFIG_DEBUG_STACK_USAGE
1049 memset(ti, 0, THREAD_SIZE);
1050#endif
1051 return ti;
1052}
1053
1054void free_thread_info(struct thread_info *ti)
1055{
1056 kmem_cache_free(thread_info_cache, ti);
1057}
1058
1059void thread_info_cache_init(void)
1060{
1061 thread_info_cache = kmem_cache_create("thread_info", THREAD_SIZE,
1062 THREAD_SIZE, 0, NULL);
1063 BUG_ON(thread_info_cache == NULL);
1064}
1065
1066#endif /* THREAD_SHIFT < PAGE_SHIFT */
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index 3bfe7837e820..2aefe2a4129a 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -53,6 +53,7 @@
53#include <asm/pci-bridge.h> 53#include <asm/pci-bridge.h>
54#include <asm/phyp_dump.h> 54#include <asm/phyp_dump.h>
55#include <asm/kexec.h> 55#include <asm/kexec.h>
56#include <mm/mmu_decl.h>
56 57
57#ifdef DEBUG 58#ifdef DEBUG
58#define DBG(fmt...) printk(KERN_ERR fmt) 59#define DBG(fmt...) printk(KERN_ERR fmt)
@@ -978,7 +979,10 @@ static int __init early_init_dt_scan_memory(unsigned long node,
978 } 979 }
979#endif 980#endif
980 lmb_add(base, size); 981 lmb_add(base, size);
982
983 memstart_addr = min((u64)memstart_addr, base);
981 } 984 }
985
982 return 0; 986 return 0;
983} 987}
984 988
diff --git a/arch/powerpc/kernel/prom_init_check.sh b/arch/powerpc/kernel/prom_init_check.sh
new file mode 100644
index 000000000000..8e24fc1821e8
--- /dev/null
+++ b/arch/powerpc/kernel/prom_init_check.sh
@@ -0,0 +1,58 @@
1#!/bin/sh
2#
3# Copyright © 2008 IBM Corporation
4#
5# This program is free software; you can redistribute it and/or
6# modify it under the terms of the GNU General Public License
7# as published by the Free Software Foundation; either version
8# 2 of the License, or (at your option) any later version.
9
10# This script checks prom_init.o to see what external symbols it
11# is using, if it finds symbols not in the whitelist it returns
12# an error. The point of this is to discourage people from
13# intentionally or accidentally adding new code to prom_init.c
14# which has side effects on other parts of the kernel.
15
16# If you really need to reference something from prom_init.o add
17# it to the list below:
18
19WHITELIST="add_reloc_offset __bss_start __bss_stop copy_and_flush
20_end enter_prom memcpy memset reloc_offset __secondary_hold
21__secondary_hold_acknowledge __secondary_hold_spinloop __start
22strcmp strcpy strlcpy strlen strncmp strstr logo_linux_clut224
23reloc_got2"
24
25NM="$1"
26OBJ="$2"
27
28ERROR=0
29
30for UNDEF in $($NM -u $OBJ | awk '{print $2}')
31do
32 # On 64-bit nm gives us the function descriptors, which have
33 # a leading . on the name, so strip it off here.
34 UNDEF="${UNDEF#.}"
35
36 if [ $KBUILD_VERBOSE ]; then
37 if [ $KBUILD_VERBOSE -ne 0 ]; then
38 echo "Checking prom_init.o symbol '$UNDEF'"
39 fi
40 fi
41
42 OK=0
43 for WHITE in $WHITELIST
44 do
45 if [ "$UNDEF" = "$WHITE" ]; then
46 OK=1
47 break
48 fi
49 done
50
51 if [ $OK -eq 0 ]; then
52 ERROR=1
53 echo "Error: External symbol '$UNDEF' referenced" \
54 "from prom_init.c" >&2
55 fi
56done
57
58exit $ERROR
diff --git a/arch/powerpc/kernel/ptrace32.c b/arch/powerpc/kernel/ptrace32.c
index 9d30e10970ac..4c1de6af4c09 100644
--- a/arch/powerpc/kernel/ptrace32.c
+++ b/arch/powerpc/kernel/ptrace32.c
@@ -29,15 +29,12 @@
29#include <linux/security.h> 29#include <linux/security.h>
30#include <linux/signal.h> 30#include <linux/signal.h>
31#include <linux/compat.h> 31#include <linux/compat.h>
32#include <linux/elf.h>
33 32
34#include <asm/uaccess.h> 33#include <asm/uaccess.h>
35#include <asm/page.h> 34#include <asm/page.h>
36#include <asm/pgtable.h> 35#include <asm/pgtable.h>
37#include <asm/system.h> 36#include <asm/system.h>
38 37
39#include "ppc32.h"
40
41/* 38/*
42 * does not yet catch signals sent when the child dies. 39 * does not yet catch signals sent when the child dies.
43 * in exit.c or in signal.c. 40 * in exit.c or in signal.c.
@@ -67,27 +64,6 @@ static long compat_ptrace_old(struct task_struct *child, long request,
67 return -EPERM; 64 return -EPERM;
68} 65}
69 66
70static int compat_ptrace_getsiginfo(struct task_struct *child, compat_siginfo_t __user *data)
71{
72 siginfo_t lastinfo;
73 int error = -ESRCH;
74
75 read_lock(&tasklist_lock);
76 if (likely(child->sighand != NULL)) {
77 error = -EINVAL;
78 spin_lock_irq(&child->sighand->siglock);
79 if (likely(child->last_siginfo != NULL)) {
80 lastinfo = *child->last_siginfo;
81 error = 0;
82 }
83 spin_unlock_irq(&child->sighand->siglock);
84 }
85 read_unlock(&tasklist_lock);
86 if (!error)
87 return copy_siginfo_to_user32(data, &lastinfo);
88 return error;
89}
90
91long compat_arch_ptrace(struct task_struct *child, compat_long_t request, 67long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
92 compat_ulong_t caddr, compat_ulong_t cdata) 68 compat_ulong_t caddr, compat_ulong_t cdata)
93{ 69{
@@ -306,9 +282,6 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
306 0, PT_REGS_COUNT * sizeof(compat_long_t), 282 0, PT_REGS_COUNT * sizeof(compat_long_t),
307 compat_ptr(data)); 283 compat_ptr(data));
308 284
309 case PTRACE_GETSIGINFO:
310 return compat_ptrace_getsiginfo(child, compat_ptr(data));
311
312 case PTRACE_GETFPREGS: 285 case PTRACE_GETFPREGS:
313 case PTRACE_SETFPREGS: 286 case PTRACE_SETFPREGS:
314 case PTRACE_GETVRREGS: 287 case PTRACE_GETVRREGS:
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index 31ada9fdfc5c..dff6308d1b5e 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -170,6 +170,9 @@ void __init setup_paca(int cpu)
170 170
171void __init early_setup(unsigned long dt_ptr) 171void __init early_setup(unsigned long dt_ptr)
172{ 172{
173 /* Fill in any unititialised pacas */
174 initialise_pacas();
175
173 /* Identify CPU type */ 176 /* Identify CPU type */
174 identify_cpu(0, mfspr(SPRN_PVR)); 177 identify_cpu(0, mfspr(SPRN_PVR));
175 178
@@ -435,7 +438,7 @@ void __init setup_system(void)
435 printk("htab_address = 0x%p\n", htab_address); 438 printk("htab_address = 0x%p\n", htab_address);
436 printk("htab_hash_mask = 0x%lx\n", htab_hash_mask); 439 printk("htab_hash_mask = 0x%lx\n", htab_hash_mask);
437#if PHYSICAL_START > 0 440#if PHYSICAL_START > 0
438 printk("physical_start = 0x%x\n", PHYSICAL_START); 441 printk("physical_start = 0x%lx\n", PHYSICAL_START);
439#endif 442#endif
440 printk("-----------------------------------------------------\n"); 443 printk("-----------------------------------------------------\n");
441 444
diff --git a/arch/powerpc/kernel/stacktrace.c b/arch/powerpc/kernel/stacktrace.c
index e3638eeaaae7..962944038430 100644
--- a/arch/powerpc/kernel/stacktrace.c
+++ b/arch/powerpc/kernel/stacktrace.c
@@ -13,7 +13,6 @@
13#include <linux/sched.h> 13#include <linux/sched.h>
14#include <linux/stacktrace.h> 14#include <linux/stacktrace.h>
15#include <asm/ptrace.h> 15#include <asm/ptrace.h>
16#include <asm/asm-offsets.h>
17 16
18/* 17/*
19 * Save stack-backtrace addresses into a stack_trace buffer. 18 * Save stack-backtrace addresses into a stack_trace buffer.
diff --git a/arch/powerpc/kernel/udbg.c b/arch/powerpc/kernel/udbg.c
index 7aad6203e411..7d6c9bb8c77f 100644
--- a/arch/powerpc/kernel/udbg.c
+++ b/arch/powerpc/kernel/udbg.c
@@ -154,8 +154,8 @@ static void udbg_console_write(struct console *con, const char *s,
154static struct console udbg_console = { 154static struct console udbg_console = {
155 .name = "udbg", 155 .name = "udbg",
156 .write = udbg_console_write, 156 .write = udbg_console_write,
157 .flags = CON_PRINTBUFFER | CON_ENABLED | CON_BOOT, 157 .flags = CON_PRINTBUFFER | CON_ENABLED | CON_BOOT | CON_ANYTIME,
158 .index = -1, 158 .index = 0,
159}; 159};
160 160
161static int early_console_initialized; 161static int early_console_initialized;
diff --git a/arch/powerpc/mm/fsl_booke_mmu.c b/arch/powerpc/mm/fsl_booke_mmu.c
index ada249bf9779..ce10e2b1b902 100644
--- a/arch/powerpc/mm/fsl_booke_mmu.c
+++ b/arch/powerpc/mm/fsl_booke_mmu.c
@@ -202,7 +202,7 @@ adjust_total_lowmem(void)
202 cam_max_size = max_lowmem_size; 202 cam_max_size = max_lowmem_size;
203 203
204 /* adjust lowmem size to max_lowmem_size */ 204 /* adjust lowmem size to max_lowmem_size */
205 ram = min(max_lowmem_size, total_lowmem); 205 ram = min(max_lowmem_size, (phys_addr_t)total_lowmem);
206 206
207 /* Calculate CAM values */ 207 /* Calculate CAM values */
208 __cam0 = 1UL << 2 * (__ilog2(ram) / 2); 208 __cam0 = 1UL << 2 * (__ilog2(ram) / 2);
diff --git a/arch/powerpc/mm/hash_low_32.S b/arch/powerpc/mm/hash_low_32.S
index e10d76a860d3..ddeaf9e38ad5 100644
--- a/arch/powerpc/mm/hash_low_32.S
+++ b/arch/powerpc/mm/hash_low_32.S
@@ -191,7 +191,7 @@ _GLOBAL(add_hash_page)
191 add r3,r3,r0 /* note create_hpte trims to 24 bits */ 191 add r3,r3,r0 /* note create_hpte trims to 24 bits */
192 192
193#ifdef CONFIG_SMP 193#ifdef CONFIG_SMP
194 rlwinm r8,r1,0,0,18 /* use cpu number to make tag */ 194 rlwinm r8,r1,0,0,(31-THREAD_SHIFT) /* use cpu number to make tag */
195 lwz r8,TI_CPU(r8) /* to go in mmu_hash_lock */ 195 lwz r8,TI_CPU(r8) /* to go in mmu_hash_lock */
196 oris r8,r8,12 196 oris r8,r8,12
197#endif /* CONFIG_SMP */ 197#endif /* CONFIG_SMP */
@@ -526,7 +526,7 @@ _GLOBAL(flush_hash_pages)
526#ifdef CONFIG_SMP 526#ifdef CONFIG_SMP
527 addis r9,r7,mmu_hash_lock@ha 527 addis r9,r7,mmu_hash_lock@ha
528 addi r9,r9,mmu_hash_lock@l 528 addi r9,r9,mmu_hash_lock@l
529 rlwinm r8,r1,0,0,18 529 rlwinm r8,r1,0,0,(31-THREAD_SHIFT)
530 add r8,r8,r7 530 add r8,r8,r7
531 lwz r8,TI_CPU(r8) 531 lwz r8,TI_CPU(r8)
532 oris r8,r8,9 532 oris r8,r8,9
diff --git a/arch/powerpc/mm/init_32.c b/arch/powerpc/mm/init_32.c
index 47325f23c51f..1952b4d3fa7f 100644
--- a/arch/powerpc/mm/init_32.c
+++ b/arch/powerpc/mm/init_32.c
@@ -59,7 +59,10 @@ DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
59unsigned long total_memory; 59unsigned long total_memory;
60unsigned long total_lowmem; 60unsigned long total_lowmem;
61 61
62phys_addr_t memstart_addr; 62phys_addr_t memstart_addr = (phys_addr_t)~0ull;
63EXPORT_SYMBOL(memstart_addr);
64phys_addr_t kernstart_addr;
65EXPORT_SYMBOL(kernstart_addr);
63phys_addr_t lowmem_end_addr; 66phys_addr_t lowmem_end_addr;
64 67
65int boot_mapsize; 68int boot_mapsize;
@@ -68,14 +71,6 @@ unsigned long agp_special_page;
68EXPORT_SYMBOL(agp_special_page); 71EXPORT_SYMBOL(agp_special_page);
69#endif 72#endif
70 73
71#ifdef CONFIG_HIGHMEM
72pte_t *kmap_pte;
73pgprot_t kmap_prot;
74
75EXPORT_SYMBOL(kmap_prot);
76EXPORT_SYMBOL(kmap_pte);
77#endif
78
79void MMU_init(void); 74void MMU_init(void);
80 75
81/* XXX should be in current.h -- paulus */ 76/* XXX should be in current.h -- paulus */
diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c
index 698bd000f98b..c5ac532a0161 100644
--- a/arch/powerpc/mm/init_64.c
+++ b/arch/powerpc/mm/init_64.c
@@ -72,7 +72,8 @@
72#warning TASK_SIZE is smaller than it needs to be. 72#warning TASK_SIZE is smaller than it needs to be.
73#endif 73#endif
74 74
75phys_addr_t memstart_addr; 75phys_addr_t memstart_addr = ~0;
76phys_addr_t kernstart_addr;
76 77
77void free_initmem(void) 78void free_initmem(void)
78{ 79{
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index 16def4dcff6d..5ccb579b81e4 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -45,6 +45,7 @@
45#include <asm/tlb.h> 45#include <asm/tlb.h>
46#include <asm/sections.h> 46#include <asm/sections.h>
47#include <asm/vdso.h> 47#include <asm/vdso.h>
48#include <asm/fixmap.h>
48 49
49#include "mmu_decl.h" 50#include "mmu_decl.h"
50 51
@@ -57,6 +58,20 @@ int init_bootmem_done;
57int mem_init_done; 58int mem_init_done;
58unsigned long memory_limit; 59unsigned long memory_limit;
59 60
61#ifdef CONFIG_HIGHMEM
62pte_t *kmap_pte;
63pgprot_t kmap_prot;
64
65EXPORT_SYMBOL(kmap_prot);
66EXPORT_SYMBOL(kmap_pte);
67
68static inline pte_t *virt_to_kpte(unsigned long vaddr)
69{
70 return pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr),
71 vaddr), vaddr), vaddr);
72}
73#endif
74
60int page_is_ram(unsigned long pfn) 75int page_is_ram(unsigned long pfn)
61{ 76{
62 unsigned long paddr = (pfn << PAGE_SHIFT); 77 unsigned long paddr = (pfn << PAGE_SHIFT);
@@ -216,7 +231,7 @@ void __init do_init_bootmem(void)
216 unsigned long total_pages; 231 unsigned long total_pages;
217 int boot_mapsize; 232 int boot_mapsize;
218 233
219 max_pfn = lmb_end_of_DRAM() >> PAGE_SHIFT; 234 max_low_pfn = max_pfn = lmb_end_of_DRAM() >> PAGE_SHIFT;
220 total_pages = (lmb_end_of_DRAM() - memstart_addr) >> PAGE_SHIFT; 235 total_pages = (lmb_end_of_DRAM() - memstart_addr) >> PAGE_SHIFT;
221#ifdef CONFIG_HIGHMEM 236#ifdef CONFIG_HIGHMEM
222 total_pages = total_lowmem >> PAGE_SHIFT; 237 total_pages = total_lowmem >> PAGE_SHIFT;
@@ -232,7 +247,8 @@ void __init do_init_bootmem(void)
232 247
233 start = lmb_alloc(bootmap_pages << PAGE_SHIFT, PAGE_SIZE); 248 start = lmb_alloc(bootmap_pages << PAGE_SHIFT, PAGE_SIZE);
234 249
235 boot_mapsize = init_bootmem(start >> PAGE_SHIFT, total_pages); 250 min_low_pfn = MEMORY_START >> PAGE_SHIFT;
251 boot_mapsize = init_bootmem_node(NODE_DATA(0), start >> PAGE_SHIFT, min_low_pfn, max_low_pfn);
236 252
237 /* Add active regions with valid PFNs */ 253 /* Add active regions with valid PFNs */
238 for (i = 0; i < lmb.memory.cnt; i++) { 254 for (i = 0; i < lmb.memory.cnt; i++) {
@@ -310,14 +326,19 @@ void __init paging_init(void)
310 unsigned long top_of_ram = lmb_end_of_DRAM(); 326 unsigned long top_of_ram = lmb_end_of_DRAM();
311 unsigned long max_zone_pfns[MAX_NR_ZONES]; 327 unsigned long max_zone_pfns[MAX_NR_ZONES];
312 328
329#ifdef CONFIG_PPC32
330 unsigned long v = __fix_to_virt(__end_of_fixed_addresses - 1);
331 unsigned long end = __fix_to_virt(FIX_HOLE);
332
333 for (; v < end; v += PAGE_SIZE)
334 map_page(v, 0, 0); /* XXX gross */
335#endif
336
313#ifdef CONFIG_HIGHMEM 337#ifdef CONFIG_HIGHMEM
314 map_page(PKMAP_BASE, 0, 0); /* XXX gross */ 338 map_page(PKMAP_BASE, 0, 0); /* XXX gross */
315 pkmap_page_table = pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k 339 pkmap_page_table = virt_to_kpte(PKMAP_BASE);
316 (PKMAP_BASE), PKMAP_BASE), PKMAP_BASE), PKMAP_BASE); 340
317 map_page(KMAP_FIX_BEGIN, 0, 0); /* XXX gross */ 341 kmap_pte = virt_to_kpte(__fix_to_virt(FIX_KMAP_BEGIN));
318 kmap_pte = pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k
319 (KMAP_FIX_BEGIN), KMAP_FIX_BEGIN), KMAP_FIX_BEGIN),
320 KMAP_FIX_BEGIN);
321 kmap_prot = PAGE_KERNEL; 342 kmap_prot = PAGE_KERNEL;
322#endif /* CONFIG_HIGHMEM */ 343#endif /* CONFIG_HIGHMEM */
323 344
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index 1efd631211ef..dc704da363eb 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -18,6 +18,7 @@
18#include <linux/cpu.h> 18#include <linux/cpu.h>
19#include <linux/notifier.h> 19#include <linux/notifier.h>
20#include <linux/lmb.h> 20#include <linux/lmb.h>
21#include <linux/of.h>
21#include <asm/sparsemem.h> 22#include <asm/sparsemem.h>
22#include <asm/prom.h> 23#include <asm/prom.h>
23#include <asm/system.h> 24#include <asm/system.h>
diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
index 64c44bcc68de..80d1babb230d 100644
--- a/arch/powerpc/mm/pgtable_32.c
+++ b/arch/powerpc/mm/pgtable_32.c
@@ -29,6 +29,7 @@
29 29
30#include <asm/pgtable.h> 30#include <asm/pgtable.h>
31#include <asm/pgalloc.h> 31#include <asm/pgalloc.h>
32#include <asm/fixmap.h>
32#include <asm/io.h> 33#include <asm/io.h>
33 34
34#include "mmu_decl.h" 35#include "mmu_decl.h"
@@ -387,3 +388,25 @@ void kernel_map_pages(struct page *page, int numpages, int enable)
387 change_page_attr(page, numpages, enable ? PAGE_KERNEL : __pgprot(0)); 388 change_page_attr(page, numpages, enable ? PAGE_KERNEL : __pgprot(0));
388} 389}
389#endif /* CONFIG_DEBUG_PAGEALLOC */ 390#endif /* CONFIG_DEBUG_PAGEALLOC */
391
392static int fixmaps;
393unsigned long FIXADDR_TOP = 0xfffff000;
394EXPORT_SYMBOL(FIXADDR_TOP);
395
396void __set_fixmap (enum fixed_addresses idx, phys_addr_t phys, pgprot_t flags)
397{
398 unsigned long address = __fix_to_virt(idx);
399
400 if (idx >= __end_of_fixed_addresses) {
401 BUG();
402 return;
403 }
404
405 map_page(address, phys, flags);
406 fixmaps++;
407}
408
409void __this_fixmap_does_not_exist(void)
410{
411 WARN_ON(1);
412}
diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig
index f38c50b4ce56..87454c526973 100644
--- a/arch/powerpc/platforms/Kconfig
+++ b/arch/powerpc/platforms/Kconfig
@@ -45,7 +45,6 @@ source "arch/powerpc/platforms/powermac/Kconfig"
45source "arch/powerpc/platforms/prep/Kconfig" 45source "arch/powerpc/platforms/prep/Kconfig"
46source "arch/powerpc/platforms/maple/Kconfig" 46source "arch/powerpc/platforms/maple/Kconfig"
47source "arch/powerpc/platforms/pasemi/Kconfig" 47source "arch/powerpc/platforms/pasemi/Kconfig"
48source "arch/powerpc/platforms/celleb/Kconfig"
49source "arch/powerpc/platforms/ps3/Kconfig" 48source "arch/powerpc/platforms/ps3/Kconfig"
50source "arch/powerpc/platforms/cell/Kconfig" 49source "arch/powerpc/platforms/cell/Kconfig"
51source "arch/powerpc/platforms/8xx/Kconfig" 50source "arch/powerpc/platforms/8xx/Kconfig"
diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype
index 5fc7fac10e93..f7efaa925a13 100644
--- a/arch/powerpc/platforms/Kconfig.cputype
+++ b/arch/powerpc/platforms/Kconfig.cputype
@@ -220,8 +220,8 @@ config SMP
220 If you don't know what to do here, say N. 220 If you don't know what to do here, say N.
221 221
222config NR_CPUS 222config NR_CPUS
223 int "Maximum number of CPUs (2-128)" 223 int "Maximum number of CPUs (2-1024)"
224 range 2 128 224 range 2 1024
225 depends on SMP 225 depends on SMP
226 default "32" if PPC64 226 default "32" if PPC64
227 default "4" 227 default "4"
diff --git a/arch/powerpc/platforms/Makefile b/arch/powerpc/platforms/Makefile
index a984894466d9..423a0234dc31 100644
--- a/arch/powerpc/platforms/Makefile
+++ b/arch/powerpc/platforms/Makefile
@@ -24,5 +24,4 @@ obj-$(CONFIG_PPC_MAPLE) += maple/
24obj-$(CONFIG_PPC_PASEMI) += pasemi/ 24obj-$(CONFIG_PPC_PASEMI) += pasemi/
25obj-$(CONFIG_PPC_CELL) += cell/ 25obj-$(CONFIG_PPC_CELL) += cell/
26obj-$(CONFIG_PPC_PS3) += ps3/ 26obj-$(CONFIG_PPC_PS3) += ps3/
27obj-$(CONFIG_PPC_CELLEB) += celleb/
28obj-$(CONFIG_EMBEDDED6xx) += embedded6xx/ 27obj-$(CONFIG_EMBEDDED6xx) += embedded6xx/
diff --git a/arch/powerpc/platforms/cell/Kconfig b/arch/powerpc/platforms/cell/Kconfig
index 2f169991896d..3959fcfe731c 100644
--- a/arch/powerpc/platforms/cell/Kconfig
+++ b/arch/powerpc/platforms/cell/Kconfig
@@ -25,6 +25,19 @@ config PPC_IBM_CELL_BLADE
25 select PPC_UDBG_16550 25 select PPC_UDBG_16550
26 select UDBG_RTAS_CONSOLE 26 select UDBG_RTAS_CONSOLE
27 27
28config PPC_CELLEB
29 bool "Toshiba's Cell Reference Set 'Celleb' Architecture"
30 depends on PPC_MULTIPLATFORM && PPC64
31 select PPC_CELL
32 select PPC_CELL_NATIVE
33 select PPC_RTAS
34 select PPC_INDIRECT_IO
35 select PPC_OF_PLATFORM_PCI
36 select HAS_TXX9_SERIAL
37 select PPC_UDBG_BEAT
38 select USB_OHCI_BIG_ENDIAN_MMIO
39 select USB_EHCI_BIG_ENDIAN_MMIO
40
28menu "Cell Broadband Engine options" 41menu "Cell Broadband Engine options"
29 depends on PPC_CELL 42 depends on PPC_CELL
30 43
diff --git a/arch/powerpc/platforms/cell/Makefile b/arch/powerpc/platforms/cell/Makefile
index c89964c6fb1f..c2a7e4e5ddf9 100644
--- a/arch/powerpc/platforms/cell/Makefile
+++ b/arch/powerpc/platforms/cell/Makefile
@@ -1,6 +1,7 @@
1obj-$(CONFIG_PPC_CELL_NATIVE) += interrupt.o iommu.o setup.o \ 1obj-$(CONFIG_PPC_CELL_NATIVE) += interrupt.o iommu.o setup.o \
2 cbe_regs.o spider-pic.o \ 2 cbe_regs.o spider-pic.o \
3 pervasive.o pmu.o io-workarounds.o 3 pervasive.o pmu.o io-workarounds.o \
4 spider-pci.o
4obj-$(CONFIG_CBE_RAS) += ras.o 5obj-$(CONFIG_CBE_RAS) += ras.o
5 6
6obj-$(CONFIG_CBE_THERM) += cbe_thermal.o 7obj-$(CONFIG_CBE_THERM) += cbe_thermal.o
@@ -26,3 +27,20 @@ obj-$(CONFIG_SPU_BASE) += spu_callbacks.o spu_base.o \
26 spufs/ 27 spufs/
27 28
28obj-$(CONFIG_PCI_MSI) += axon_msi.o 29obj-$(CONFIG_PCI_MSI) += axon_msi.o
30
31
32# celleb stuff
33ifeq ($(CONFIG_PPC_CELLEB),y)
34obj-y += celleb_setup.o \
35 celleb_pci.o celleb_scc_epci.o \
36 celleb_scc_pciex.o \
37 celleb_scc_uhc.o \
38 io-workarounds.o spider-pci.o \
39 beat.o beat_htab.o beat_hvCall.o \
40 beat_interrupt.o beat_iommu.o
41
42obj-$(CONFIG_SMP) += beat_smp.o
43obj-$(CONFIG_PPC_UDBG_BEAT) += beat_udbg.o
44obj-$(CONFIG_SERIAL_TXX9) += celleb_scc_sio.o
45obj-$(CONFIG_SPU_BASE) += beat_spu_priv1.o
46endif
diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c
index d95e71dee91f..c39f5c225f2e 100644
--- a/arch/powerpc/platforms/cell/axon_msi.c
+++ b/arch/powerpc/platforms/cell/axon_msi.c
@@ -123,7 +123,7 @@ static struct axon_msic *find_msi_translator(struct pci_dev *dev)
123 return NULL; 123 return NULL;
124 } 124 }
125 125
126 for (; dn; tmp = of_get_parent(dn), of_node_put(dn), dn = tmp) { 126 for (; dn; dn = of_get_next_parent(dn)) {
127 ph = of_get_property(dn, "msi-translator", NULL); 127 ph = of_get_property(dn, "msi-translator", NULL);
128 if (ph) 128 if (ph)
129 break; 129 break;
@@ -169,7 +169,7 @@ static int axon_msi_check_device(struct pci_dev *dev, int nvec, int type)
169 169
170static int setup_msi_msg_address(struct pci_dev *dev, struct msi_msg *msg) 170static int setup_msi_msg_address(struct pci_dev *dev, struct msi_msg *msg)
171{ 171{
172 struct device_node *dn, *tmp; 172 struct device_node *dn;
173 struct msi_desc *entry; 173 struct msi_desc *entry;
174 int len; 174 int len;
175 const u32 *prop; 175 const u32 *prop;
@@ -182,7 +182,7 @@ static int setup_msi_msg_address(struct pci_dev *dev, struct msi_msg *msg)
182 182
183 entry = list_first_entry(&dev->msi_list, struct msi_desc, list); 183 entry = list_first_entry(&dev->msi_list, struct msi_desc, list);
184 184
185 for (; dn; tmp = of_get_parent(dn), of_node_put(dn), dn = tmp) { 185 for (; dn; dn = of_get_next_parent(dn)) {
186 if (entry->msi_attrib.is_64) { 186 if (entry->msi_attrib.is_64) {
187 prop = of_get_property(dn, "msi-address-64", &len); 187 prop = of_get_property(dn, "msi-address-64", &len);
188 if (prop) 188 if (prop)
diff --git a/arch/powerpc/platforms/celleb/beat.c b/arch/powerpc/platforms/cell/beat.c
index b64b171f245b..48c690ea65da 100644
--- a/arch/powerpc/platforms/celleb/beat.c
+++ b/arch/powerpc/platforms/cell/beat.c
@@ -33,7 +33,7 @@
33 33
34#include "beat_wrapper.h" 34#include "beat_wrapper.h"
35#include "beat.h" 35#include "beat.h"
36#include "interrupt.h" 36#include "beat_interrupt.h"
37 37
38static int beat_pm_poweroff_flag; 38static int beat_pm_poweroff_flag;
39 39
diff --git a/arch/powerpc/platforms/celleb/beat.h b/arch/powerpc/platforms/cell/beat.h
index 32c8efcedc80..32c8efcedc80 100644
--- a/arch/powerpc/platforms/celleb/beat.h
+++ b/arch/powerpc/platforms/cell/beat.h
diff --git a/arch/powerpc/platforms/celleb/htab.c b/arch/powerpc/platforms/cell/beat_htab.c
index 81467ff055c8..81467ff055c8 100644
--- a/arch/powerpc/platforms/celleb/htab.c
+++ b/arch/powerpc/platforms/cell/beat_htab.c
diff --git a/arch/powerpc/platforms/celleb/hvCall.S b/arch/powerpc/platforms/cell/beat_hvCall.S
index 74c817448948..74c817448948 100644
--- a/arch/powerpc/platforms/celleb/hvCall.S
+++ b/arch/powerpc/platforms/cell/beat_hvCall.S
diff --git a/arch/powerpc/platforms/celleb/interrupt.c b/arch/powerpc/platforms/cell/beat_interrupt.c
index 69562a867876..192a93509372 100644
--- a/arch/powerpc/platforms/celleb/interrupt.c
+++ b/arch/powerpc/platforms/cell/beat_interrupt.c
@@ -26,7 +26,7 @@
26 26
27#include <asm/machdep.h> 27#include <asm/machdep.h>
28 28
29#include "interrupt.h" 29#include "beat_interrupt.h"
30#include "beat_wrapper.h" 30#include "beat_wrapper.h"
31 31
32#define MAX_IRQS NR_IRQS 32#define MAX_IRQS NR_IRQS
diff --git a/arch/powerpc/platforms/celleb/interrupt.h b/arch/powerpc/platforms/cell/beat_interrupt.h
index b470fd0051f1..b470fd0051f1 100644
--- a/arch/powerpc/platforms/celleb/interrupt.h
+++ b/arch/powerpc/platforms/cell/beat_interrupt.h
diff --git a/arch/powerpc/platforms/celleb/iommu.c b/arch/powerpc/platforms/cell/beat_iommu.c
index 93b0efddd658..93b0efddd658 100644
--- a/arch/powerpc/platforms/celleb/iommu.c
+++ b/arch/powerpc/platforms/cell/beat_iommu.c
diff --git a/arch/powerpc/platforms/celleb/smp.c b/arch/powerpc/platforms/cell/beat_smp.c
index a7631250aeb4..26efc204c47f 100644
--- a/arch/powerpc/platforms/celleb/smp.c
+++ b/arch/powerpc/platforms/cell/beat_smp.c
@@ -37,7 +37,7 @@
37#include <asm/machdep.h> 37#include <asm/machdep.h>
38#include <asm/udbg.h> 38#include <asm/udbg.h>
39 39
40#include "interrupt.h" 40#include "beat_interrupt.h"
41 41
42#ifdef DEBUG 42#ifdef DEBUG
43#define DBG(fmt...) udbg_printf(fmt) 43#define DBG(fmt...) udbg_printf(fmt)
diff --git a/arch/powerpc/platforms/celleb/spu_priv1.c b/arch/powerpc/platforms/cell/beat_spu_priv1.c
index bcc17f7fe8ad..bcc17f7fe8ad 100644
--- a/arch/powerpc/platforms/celleb/spu_priv1.c
+++ b/arch/powerpc/platforms/cell/beat_spu_priv1.c
diff --git a/arch/powerpc/platforms/celleb/beat_syscall.h b/arch/powerpc/platforms/cell/beat_syscall.h
index 8580dc7e1798..8580dc7e1798 100644
--- a/arch/powerpc/platforms/celleb/beat_syscall.h
+++ b/arch/powerpc/platforms/cell/beat_syscall.h
diff --git a/arch/powerpc/platforms/celleb/udbg_beat.c b/arch/powerpc/platforms/cell/beat_udbg.c
index 6b418f6b6175..6b418f6b6175 100644
--- a/arch/powerpc/platforms/celleb/udbg_beat.c
+++ b/arch/powerpc/platforms/cell/beat_udbg.c
diff --git a/arch/powerpc/platforms/celleb/beat_wrapper.h b/arch/powerpc/platforms/cell/beat_wrapper.h
index b47dfda48d06..b47dfda48d06 100644
--- a/arch/powerpc/platforms/celleb/beat_wrapper.h
+++ b/arch/powerpc/platforms/cell/beat_wrapper.h
diff --git a/arch/powerpc/platforms/celleb/pci.c b/arch/powerpc/platforms/cell/celleb_pci.c
index 51b390d34e4d..f39a3b2a1667 100644
--- a/arch/powerpc/platforms/celleb/pci.c
+++ b/arch/powerpc/platforms/cell/celleb_pci.c
@@ -37,12 +37,11 @@
37#include <asm/io.h> 37#include <asm/io.h>
38#include <asm/irq.h> 38#include <asm/irq.h>
39#include <asm/prom.h> 39#include <asm/prom.h>
40#include <asm/machdep.h>
41#include <asm/pci-bridge.h> 40#include <asm/pci-bridge.h>
42#include <asm/ppc-pci.h> 41#include <asm/ppc-pci.h>
43 42
44#include "pci.h" 43#include "io-workarounds.h"
45#include "interrupt.h" 44#include "celleb_pci.h"
46 45
47#define MAX_PCI_DEVICES 32 46#define MAX_PCI_DEVICES 32
48#define MAX_PCI_FUNCTIONS 8 47#define MAX_PCI_FUNCTIONS 8
@@ -190,7 +189,7 @@ static int celleb_fake_pci_read_config(struct pci_bus *bus,
190 189
191 190
192static int celleb_fake_pci_write_config(struct pci_bus *bus, 191static int celleb_fake_pci_write_config(struct pci_bus *bus,
193 unsigned int devfn, int where, int size, u32 val) 192 unsigned int devfn, int where, int size, u32 val)
194{ 193{
195 char *config; 194 char *config;
196 struct device_node *node; 195 struct device_node *node;
@@ -457,33 +456,42 @@ static int __init celleb_setup_fake_pci(struct device_node *dev,
457 return 0; 456 return 0;
458} 457}
459 458
460void __init fake_pci_workaround_init(struct pci_controller *phb) 459static struct celleb_phb_spec celleb_fake_pci_spec __initdata = {
461{ 460 .setup = celleb_setup_fake_pci,
462 /** 461};
463 * We will add fake pci bus to scc_pci_bus for the purpose to improve
464 * I/O Macro performance. But device-tree and device drivers
465 * are not ready to use address with a token.
466 */
467
468 /* celleb_pci_add_one(phb, NULL); */
469}
470 462
471static struct of_device_id celleb_phb_match[] __initdata = { 463static struct of_device_id celleb_phb_match[] __initdata = {
472 { 464 {
473 .name = "pci-pseudo", 465 .name = "pci-pseudo",
474 .data = celleb_setup_fake_pci, 466 .data = &celleb_fake_pci_spec,
475 }, { 467 }, {
476 .name = "epci", 468 .name = "epci",
477 .data = celleb_setup_epci, 469 .data = &celleb_epci_spec,
470 }, {
471 .name = "pcie",
472 .data = &celleb_pciex_spec,
478 }, { 473 }, {
479 }, 474 },
480}; 475};
481 476
477static int __init celleb_io_workaround_init(struct pci_controller *phb,
478 struct celleb_phb_spec *phb_spec)
479{
480 if (phb_spec->ops) {
481 iowa_register_bus(phb, phb_spec->ops, phb_spec->iowa_init,
482 phb_spec->iowa_data);
483 io_workaround_init();
484 }
485
486 return 0;
487}
488
482int __init celleb_setup_phb(struct pci_controller *phb) 489int __init celleb_setup_phb(struct pci_controller *phb)
483{ 490{
484 struct device_node *dev = phb->dn; 491 struct device_node *dev = phb->dn;
485 const struct of_device_id *match; 492 const struct of_device_id *match;
486 int (*setup_func)(struct device_node *, struct pci_controller *); 493 struct celleb_phb_spec *phb_spec;
494 int rc;
487 495
488 match = of_match_node(celleb_phb_match, dev); 496 match = of_match_node(celleb_phb_match, dev);
489 if (!match) 497 if (!match)
@@ -492,8 +500,12 @@ int __init celleb_setup_phb(struct pci_controller *phb)
492 phb_set_bus_ranges(dev, phb); 500 phb_set_bus_ranges(dev, phb);
493 phb->buid = 1; 501 phb->buid = 1;
494 502
495 setup_func = match->data; 503 phb_spec = match->data;
496 return (*setup_func)(dev, phb); 504 rc = (*phb_spec->setup)(dev, phb);
505 if (rc)
506 return 1;
507
508 return celleb_io_workaround_init(phb, phb_spec);
497} 509}
498 510
499int celleb_pci_probe_mode(struct pci_bus *bus) 511int celleb_pci_probe_mode(struct pci_bus *bus)
diff --git a/arch/powerpc/platforms/celleb/pci.h b/arch/powerpc/platforms/cell/celleb_pci.h
index 5d5544ffeddb..4cba1523ec50 100644
--- a/arch/powerpc/platforms/celleb/pci.h
+++ b/arch/powerpc/platforms/cell/celleb_pci.h
@@ -27,16 +27,19 @@
27#include <asm/prom.h> 27#include <asm/prom.h>
28#include <asm/ppc-pci.h> 28#include <asm/ppc-pci.h>
29 29
30#include "io-workarounds.h"
31
32struct celleb_phb_spec {
33 int (*setup)(struct device_node *, struct pci_controller *);
34 struct ppc_pci_io *ops;
35 int (*iowa_init)(struct iowa_bus *, void *);
36 void *iowa_data;
37};
38
30extern int celleb_setup_phb(struct pci_controller *); 39extern int celleb_setup_phb(struct pci_controller *);
31extern int celleb_pci_probe_mode(struct pci_bus *); 40extern int celleb_pci_probe_mode(struct pci_bus *);
32 41
33extern int celleb_setup_epci(struct device_node *, struct pci_controller *); 42extern struct celleb_phb_spec celleb_epci_spec;
34 43extern struct celleb_phb_spec celleb_pciex_spec;
35extern void *celleb_dummy_page_va;
36extern int __init celleb_pci_workaround_init(void);
37extern void __init celleb_pci_add_one(struct pci_controller *,
38 void (*)(struct pci_controller *));
39extern void fake_pci_workaround_init(struct pci_controller *);
40extern void epci_workaround_init(struct pci_controller *);
41 44
42#endif /* _CELLEB_PCI_H */ 45#endif /* _CELLEB_PCI_H */
diff --git a/arch/powerpc/platforms/celleb/scc.h b/arch/powerpc/platforms/cell/celleb_scc.h
index 6be1542a6e66..b596a711c348 100644
--- a/arch/powerpc/platforms/celleb/scc.h
+++ b/arch/powerpc/platforms/cell/celleb_scc.h
@@ -125,6 +125,93 @@
125/* bits for SCC_EPCI_CNTOPT */ 125/* bits for SCC_EPCI_CNTOPT */
126#define SCC_EPCI_CNTOPT_O2PMB 0x00000002 126#define SCC_EPCI_CNTOPT_O2PMB 0x00000002
127 127
128/* SCC PCIEXC SMMIO registers */
129#define PEXCADRS 0x000
130#define PEXCWDATA 0x004
131#define PEXCRDATA 0x008
132#define PEXDADRS 0x010
133#define PEXDCMND 0x014
134#define PEXDWDATA 0x018
135#define PEXDRDATA 0x01c
136#define PEXREQID 0x020
137#define PEXTIDMAP 0x024
138#define PEXINTMASK 0x028
139#define PEXINTSTS 0x02c
140#define PEXAERRMASK 0x030
141#define PEXAERRSTS 0x034
142#define PEXPRERRMASK 0x040
143#define PEXPRERRSTS 0x044
144#define PEXPRERRID01 0x048
145#define PEXPRERRID23 0x04c
146#define PEXVDMASK 0x050
147#define PEXVDSTS 0x054
148#define PEXRCVCPLIDA 0x060
149#define PEXLENERRIDA 0x068
150#define PEXPHYPLLST 0x070
151#define PEXDMRDEN0 0x100
152#define PEXDMRDADR0 0x104
153#define PEXDMRDENX 0x110
154#define PEXDMRDADRX 0x114
155#define PEXECMODE 0xf00
156#define PEXMAEA(n) (0xf50 + (8 * n))
157#define PEXMAEC(n) (0xf54 + (8 * n))
158#define PEXCCRCTRL 0xff0
159
160/* SCC PCIEXC bits and shifts for PEXCADRS */
161#define PEXCADRS_BYTE_EN_SHIFT 20
162#define PEXCADRS_CMD_SHIFT 16
163#define PEXCADRS_CMD_READ (0xa << PEXCADRS_CMD_SHIFT)
164#define PEXCADRS_CMD_WRITE (0xb << PEXCADRS_CMD_SHIFT)
165
166/* SCC PCIEXC shifts for PEXDADRS */
167#define PEXDADRS_BUSNO_SHIFT 20
168#define PEXDADRS_DEVNO_SHIFT 15
169#define PEXDADRS_FUNCNO_SHIFT 12
170
171/* SCC PCIEXC bits and shifts for PEXDCMND */
172#define PEXDCMND_BYTE_EN_SHIFT 4
173#define PEXDCMND_IO_READ 0x2
174#define PEXDCMND_IO_WRITE 0x3
175#define PEXDCMND_CONFIG_READ 0xa
176#define PEXDCMND_CONFIG_WRITE 0xb
177
178/* SCC PCIEXC bits for PEXPHYPLLST */
179#define PEXPHYPLLST_PEXPHYAPLLST 0x00000001
180
181/* SCC PCIEXC bits for PEXECMODE */
182#define PEXECMODE_ALL_THROUGH 0x00000000
183#define PEXECMODE_ALL_8BIT 0x00550155
184#define PEXECMODE_ALL_16BIT 0x00aa02aa
185
186/* SCC PCIEXC bits for PEXCCRCTRL */
187#define PEXCCRCTRL_PEXIPCOREEN 0x00040000
188#define PEXCCRCTRL_PEXIPCONTEN 0x00020000
189#define PEXCCRCTRL_PEXPHYPLLEN 0x00010000
190#define PEXCCRCTRL_PCIEXCAOCKEN 0x00000100
191
192/* SCC PCIEXC port configuration registers */
193#define PEXTCERRCHK 0x21c
194#define PEXTAMAPB0 0x220
195#define PEXTAMAPL0 0x224
196#define PEXTAMAPB(n) (PEXTAMAPB0 + 8 * (n))
197#define PEXTAMAPL(n) (PEXTAMAPL0 + 8 * (n))
198#define PEXCHVC0P 0x500
199#define PEXCHVC0NP 0x504
200#define PEXCHVC0C 0x508
201#define PEXCDVC0P 0x50c
202#define PEXCDVC0NP 0x510
203#define PEXCDVC0C 0x514
204#define PEXCHVCXP 0x518
205#define PEXCHVCXNP 0x51c
206#define PEXCHVCXC 0x520
207#define PEXCDVCXP 0x524
208#define PEXCDVCXNP 0x528
209#define PEXCDVCXC 0x52c
210#define PEXCTTRG 0x530
211#define PEXTSCTRL 0x700
212#define PEXTSSTS 0x704
213#define PEXSKPCTRL 0x708
214
128/* UHC registers */ 215/* UHC registers */
129#define SCC_UHC_CKRCTRL 0xff0 216#define SCC_UHC_CKRCTRL 0xff0
130#define SCC_UHC_ECMODE 0xf00 217#define SCC_UHC_ECMODE 0xf00
diff --git a/arch/powerpc/platforms/celleb/scc_epci.c b/arch/powerpc/platforms/cell/celleb_scc_epci.c
index a999b393f6f6..08c285b10e30 100644
--- a/arch/powerpc/platforms/celleb/scc_epci.c
+++ b/arch/powerpc/platforms/cell/celleb_scc_epci.c
@@ -30,23 +30,17 @@
30#include <asm/io.h> 30#include <asm/io.h>
31#include <asm/irq.h> 31#include <asm/irq.h>
32#include <asm/prom.h> 32#include <asm/prom.h>
33#include <asm/machdep.h>
34#include <asm/pci-bridge.h> 33#include <asm/pci-bridge.h>
35#include <asm/ppc-pci.h> 34#include <asm/ppc-pci.h>
36 35
37#include "scc.h" 36#include "celleb_scc.h"
38#include "pci.h" 37#include "celleb_pci.h"
39#include "interrupt.h"
40 38
41#define MAX_PCI_DEVICES 32 39#define MAX_PCI_DEVICES 32
42#define MAX_PCI_FUNCTIONS 8 40#define MAX_PCI_FUNCTIONS 8
43 41
44#define iob() __asm__ __volatile__("eieio; sync":::"memory") 42#define iob() __asm__ __volatile__("eieio; sync":::"memory")
45 43
46struct epci_private {
47 dma_addr_t dummy_page_da;
48};
49
50static inline PCI_IO_ADDR celleb_epci_get_epci_base( 44static inline PCI_IO_ADDR celleb_epci_get_epci_base(
51 struct pci_controller *hose) 45 struct pci_controller *hose)
52{ 46{
@@ -71,42 +65,6 @@ static inline PCI_IO_ADDR celleb_epci_get_epci_cfg(
71 return hose->cfg_data; 65 return hose->cfg_data;
72} 66}
73 67
74static void scc_epci_dummy_read(struct pci_controller *hose)
75{
76 PCI_IO_ADDR epci_base;
77 u32 val;
78
79 epci_base = celleb_epci_get_epci_base(hose);
80
81 val = in_be32(epci_base + SCC_EPCI_WATRP);
82 iosync();
83
84 return;
85}
86
87void __init epci_workaround_init(struct pci_controller *hose)
88{
89 PCI_IO_ADDR epci_base;
90 PCI_IO_ADDR reg;
91 struct epci_private *private = hose->private_data;
92
93 BUG_ON(!private);
94
95 private->dummy_page_da = dma_map_single(hose->parent,
96 celleb_dummy_page_va, PAGE_SIZE, DMA_FROM_DEVICE);
97 if (private->dummy_page_da == DMA_ERROR_CODE) {
98 printk(KERN_ERR "EPCI: dummy read disabled. "
99 "Map dummy page failed.\n");
100 return;
101 }
102
103 celleb_pci_add_one(hose, scc_epci_dummy_read);
104 epci_base = celleb_epci_get_epci_base(hose);
105
106 reg = epci_base + SCC_EPCI_DUMYRADR;
107 out_be32(reg, private->dummy_page_da);
108}
109
110static inline void clear_and_disable_master_abort_interrupt( 68static inline void clear_and_disable_master_abort_interrupt(
111 struct pci_controller *hose) 69 struct pci_controller *hose)
112{ 70{
@@ -151,10 +109,8 @@ static int celleb_epci_check_abort(struct pci_controller *hose,
151 return PCIBIOS_SUCCESSFUL; 109 return PCIBIOS_SUCCESSFUL;
152} 110}
153 111
154static PCI_IO_ADDR celleb_epci_make_config_addr( 112static PCI_IO_ADDR celleb_epci_make_config_addr(struct pci_bus *bus,
155 struct pci_bus *bus, 113 struct pci_controller *hose, unsigned int devfn, int where)
156 struct pci_controller *hose,
157 unsigned int devfn, int where)
158{ 114{
159 PCI_IO_ADDR addr; 115 PCI_IO_ADDR addr;
160 116
@@ -425,8 +381,8 @@ static int __init celleb_epci_init(struct pci_controller *hose)
425 return 0; 381 return 0;
426} 382}
427 383
428int __init celleb_setup_epci(struct device_node *node, 384static int __init celleb_setup_epci(struct device_node *node,
429 struct pci_controller *hose) 385 struct pci_controller *hose)
430{ 386{
431 struct resource r; 387 struct resource r;
432 388
@@ -450,8 +406,7 @@ int __init celleb_setup_epci(struct device_node *node,
450 if (!hose->cfg_addr) 406 if (!hose->cfg_addr)
451 goto error; 407 goto error;
452 pr_debug("EPCI: cfg_addr map 0x%016lx->0x%016lx + 0x%016lx\n", 408 pr_debug("EPCI: cfg_addr map 0x%016lx->0x%016lx + 0x%016lx\n",
453 r.start, (unsigned long)hose->cfg_addr, 409 r.start, (unsigned long)hose->cfg_addr, (r.end - r.start + 1));
454 (r.end - r.start + 1));
455 410
456 if (of_address_to_resource(node, 2, &r)) 411 if (of_address_to_resource(node, 2, &r))
457 goto error; 412 goto error;
@@ -459,14 +414,7 @@ int __init celleb_setup_epci(struct device_node *node,
459 if (!hose->cfg_data) 414 if (!hose->cfg_data)
460 goto error; 415 goto error;
461 pr_debug("EPCI: cfg_data map 0x%016lx->0x%016lx + 0x%016lx\n", 416 pr_debug("EPCI: cfg_data map 0x%016lx->0x%016lx + 0x%016lx\n",
462 r.start, (unsigned long)hose->cfg_data, 417 r.start, (unsigned long)hose->cfg_data, (r.end - r.start + 1));
463 (r.end - r.start + 1));
464
465 hose->private_data = kzalloc(sizeof(struct epci_private), GFP_KERNEL);
466 if (hose->private_data == NULL) {
467 printk(KERN_ERR "EPCI: no memory for private data.\n");
468 goto error;
469 }
470 418
471 hose->ops = &celleb_epci_ops; 419 hose->ops = &celleb_epci_ops;
472 celleb_epci_init(hose); 420 celleb_epci_init(hose);
@@ -474,8 +422,6 @@ int __init celleb_setup_epci(struct device_node *node,
474 return 0; 422 return 0;
475 423
476error: 424error:
477 kfree(hose->private_data);
478
479 if (hose->cfg_addr) 425 if (hose->cfg_addr)
480 iounmap(hose->cfg_addr); 426 iounmap(hose->cfg_addr);
481 427
@@ -483,3 +429,10 @@ error:
483 iounmap(hose->cfg_data); 429 iounmap(hose->cfg_data);
484 return 1; 430 return 1;
485} 431}
432
433struct celleb_phb_spec celleb_epci_spec __initdata = {
434 .setup = celleb_setup_epci,
435 .ops = &spiderpci_ops,
436 .iowa_init = &spiderpci_iowa_init,
437 .iowa_data = (void *)0,
438};
diff --git a/arch/powerpc/platforms/cell/celleb_scc_pciex.c b/arch/powerpc/platforms/cell/celleb_scc_pciex.c
new file mode 100644
index 000000000000..ab24d94baab6
--- /dev/null
+++ b/arch/powerpc/platforms/cell/celleb_scc_pciex.c
@@ -0,0 +1,547 @@
1/*
2 * Support for Celleb PCI-Express.
3 *
4 * (C) Copyright 2007-2008 TOSHIBA CORPORATION
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 as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
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 along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21#undef DEBUG
22
23#include <linux/kernel.h>
24#include <linux/pci.h>
25#include <linux/string.h>
26#include <linux/init.h>
27#include <linux/bootmem.h>
28#include <linux/delay.h>
29#include <linux/interrupt.h>
30
31#include <asm/io.h>
32#include <asm/irq.h>
33#include <asm/iommu.h>
34#include <asm/byteorder.h>
35
36#include "celleb_scc.h"
37#include "celleb_pci.h"
38
39#define PEX_IN(base, off) in_be32((void *)(base) + (off))
40#define PEX_OUT(base, off, data) out_be32((void *)(base) + (off), (data))
41
42static void scc_pciex_io_flush(struct iowa_bus *bus)
43{
44 (void)PEX_IN(bus->phb->cfg_addr, PEXDMRDEN0);
45}
46
47/*
48 * Memory space access to device on PCIEX
49 */
50#define PCIEX_MMIO_READ(name, ret) \
51static ret scc_pciex_##name(const PCI_IO_ADDR addr) \
52{ \
53 ret val = __do_##name(addr); \
54 scc_pciex_io_flush(iowa_mem_find_bus(addr)); \
55 return val; \
56}
57
58#define PCIEX_MMIO_READ_STR(name) \
59static void scc_pciex_##name(const PCI_IO_ADDR addr, void *buf, \
60 unsigned long count) \
61{ \
62 __do_##name(addr, buf, count); \
63 scc_pciex_io_flush(iowa_mem_find_bus(addr)); \
64}
65
66PCIEX_MMIO_READ(readb, u8)
67PCIEX_MMIO_READ(readw, u16)
68PCIEX_MMIO_READ(readl, u32)
69PCIEX_MMIO_READ(readq, u64)
70PCIEX_MMIO_READ(readw_be, u16)
71PCIEX_MMIO_READ(readl_be, u32)
72PCIEX_MMIO_READ(readq_be, u64)
73PCIEX_MMIO_READ_STR(readsb)
74PCIEX_MMIO_READ_STR(readsw)
75PCIEX_MMIO_READ_STR(readsl)
76
77static void scc_pciex_memcpy_fromio(void *dest, const PCI_IO_ADDR src,
78 unsigned long n)
79{
80 __do_memcpy_fromio(dest, src, n);
81 scc_pciex_io_flush(iowa_mem_find_bus(src));
82}
83
84/*
85 * I/O port access to devices on PCIEX.
86 */
87
88static inline unsigned long get_bus_address(struct pci_controller *phb,
89 unsigned long port)
90{
91 return port - ((unsigned long)(phb->io_base_virt) - _IO_BASE);
92}
93
94static u32 scc_pciex_read_port(struct pci_controller *phb,
95 unsigned long port, int size)
96{
97 unsigned int byte_enable;
98 unsigned int cmd, shift;
99 unsigned long addr;
100 u32 data, ret;
101
102 BUG_ON(((port & 0x3ul) + size) > 4);
103
104 addr = get_bus_address(phb, port);
105 shift = addr & 0x3ul;
106 byte_enable = ((1 << size) - 1) << shift;
107 cmd = PEXDCMND_IO_READ | (byte_enable << PEXDCMND_BYTE_EN_SHIFT);
108 PEX_OUT(phb->cfg_addr, PEXDADRS, (addr & ~0x3ul));
109 PEX_OUT(phb->cfg_addr, PEXDCMND, cmd);
110 data = PEX_IN(phb->cfg_addr, PEXDRDATA);
111 ret = (data >> (shift * 8)) & (0xFFFFFFFF >> ((4 - size) * 8));
112
113 pr_debug("PCIEX:PIO READ:port=0x%lx, addr=0x%lx, size=%d, be=%x,"
114 " cmd=%x, data=%x, ret=%x\n", port, addr, size, byte_enable,
115 cmd, data, ret);
116
117 return ret;
118}
119
120static void scc_pciex_write_port(struct pci_controller *phb,
121 unsigned long port, int size, u32 val)
122{
123 unsigned int byte_enable;
124 unsigned int cmd, shift;
125 unsigned long addr;
126 u32 data;
127
128 BUG_ON(((port & 0x3ul) + size) > 4);
129
130 addr = get_bus_address(phb, port);
131 shift = addr & 0x3ul;
132 byte_enable = ((1 << size) - 1) << shift;
133 cmd = PEXDCMND_IO_WRITE | (byte_enable << PEXDCMND_BYTE_EN_SHIFT);
134 data = (val & (0xFFFFFFFF >> (4 - size) * 8)) << (shift * 8);
135 PEX_OUT(phb->cfg_addr, PEXDADRS, (addr & ~0x3ul));
136 PEX_OUT(phb->cfg_addr, PEXDCMND, cmd);
137 PEX_OUT(phb->cfg_addr, PEXDWDATA, data);
138
139 pr_debug("PCIEX:PIO WRITE:port=0x%lx, addr=%lx, size=%d, val=%x,"
140 " be=%x, cmd=%x, data=%x\n", port, addr, size, val,
141 byte_enable, cmd, data);
142}
143
144static u8 __scc_pciex_inb(struct pci_controller *phb, unsigned long port)
145{
146 return (u8)scc_pciex_read_port(phb, port, 1);
147}
148
149static u16 __scc_pciex_inw(struct pci_controller *phb, unsigned long port)
150{
151 u32 data;
152 if ((port & 0x3ul) < 3)
153 data = scc_pciex_read_port(phb, port, 2);
154 else {
155 u32 d1 = scc_pciex_read_port(phb, port, 1);
156 u32 d2 = scc_pciex_read_port(phb, port + 1, 1);
157 data = d1 | (d2 << 8);
158 }
159 return (u16)data;
160}
161
162static u32 __scc_pciex_inl(struct pci_controller *phb, unsigned long port)
163{
164 unsigned int mod = port & 0x3ul;
165 u32 data;
166 if (mod == 0)
167 data = scc_pciex_read_port(phb, port, 4);
168 else {
169 u32 d1 = scc_pciex_read_port(phb, port, 4 - mod);
170 u32 d2 = scc_pciex_read_port(phb, port + 1, mod);
171 data = d1 | (d2 << (mod * 8));
172 }
173 return data;
174}
175
176static void __scc_pciex_outb(struct pci_controller *phb,
177 u8 val, unsigned long port)
178{
179 scc_pciex_write_port(phb, port, 1, (u32)val);
180}
181
182static void __scc_pciex_outw(struct pci_controller *phb,
183 u16 val, unsigned long port)
184{
185 if ((port & 0x3ul) < 3)
186 scc_pciex_write_port(phb, port, 2, (u32)val);
187 else {
188 u32 d1 = val & 0x000000FF;
189 u32 d2 = (val & 0x0000FF00) >> 8;
190 scc_pciex_write_port(phb, port, 1, d1);
191 scc_pciex_write_port(phb, port + 1, 1, d2);
192 }
193}
194
195static void __scc_pciex_outl(struct pci_controller *phb,
196 u32 val, unsigned long port)
197{
198 unsigned int mod = port & 0x3ul;
199 if (mod == 0)
200 scc_pciex_write_port(phb, port, 4, val);
201 else {
202 u32 d1 = val & (0xFFFFFFFFul >> (mod * 8));
203 u32 d2 = val >> ((4 - mod) * 8);
204 scc_pciex_write_port(phb, port, 4 - mod, d1);
205 scc_pciex_write_port(phb, port + 1, mod, d2);
206 }
207}
208
209#define PCIEX_PIO_FUNC(size, name) \
210static u##size scc_pciex_in##name(unsigned long port) \
211{ \
212 struct iowa_bus *bus = iowa_pio_find_bus(port); \
213 u##size data = __scc_pciex_in##name(bus->phb, port); \
214 scc_pciex_io_flush(bus); \
215 return data; \
216} \
217static void scc_pciex_ins##name(unsigned long p, void *b, unsigned long c) \
218{ \
219 struct iowa_bus *bus = iowa_pio_find_bus(p); \
220 u##size *dst = b; \
221 for (; c != 0; c--, dst++) \
222 *dst = cpu_to_le##size(__scc_pciex_in##name(bus->phb, p)); \
223 scc_pciex_io_flush(bus); \
224} \
225static void scc_pciex_out##name(u##size val, unsigned long port) \
226{ \
227 struct iowa_bus *bus = iowa_pio_find_bus(port); \
228 __scc_pciex_out##name(bus->phb, val, port); \
229} \
230static void scc_pciex_outs##name(unsigned long p, const void *b, \
231 unsigned long c) \
232{ \
233 struct iowa_bus *bus = iowa_pio_find_bus(p); \
234 const u##size *src = b; \
235 for (; c != 0; c--, src++) \
236 __scc_pciex_out##name(bus->phb, le##size##_to_cpu(*src), p); \
237}
238#define cpu_to_le8(x) (x)
239#define le8_to_cpu(x) (x)
240PCIEX_PIO_FUNC(8, b)
241PCIEX_PIO_FUNC(16, w)
242PCIEX_PIO_FUNC(32, l)
243
244static struct ppc_pci_io scc_pciex_ops = {
245 .readb = scc_pciex_readb,
246 .readw = scc_pciex_readw,
247 .readl = scc_pciex_readl,
248 .readq = scc_pciex_readq,
249 .readw_be = scc_pciex_readw_be,
250 .readl_be = scc_pciex_readl_be,
251 .readq_be = scc_pciex_readq_be,
252 .readsb = scc_pciex_readsb,
253 .readsw = scc_pciex_readsw,
254 .readsl = scc_pciex_readsl,
255 .memcpy_fromio = scc_pciex_memcpy_fromio,
256 .inb = scc_pciex_inb,
257 .inw = scc_pciex_inw,
258 .inl = scc_pciex_inl,
259 .outb = scc_pciex_outb,
260 .outw = scc_pciex_outw,
261 .outl = scc_pciex_outl,
262 .insb = scc_pciex_insb,
263 .insw = scc_pciex_insw,
264 .insl = scc_pciex_insl,
265 .outsb = scc_pciex_outsb,
266 .outsw = scc_pciex_outsw,
267 .outsl = scc_pciex_outsl,
268};
269
270static int __init scc_pciex_iowa_init(struct iowa_bus *bus, void *data)
271{
272 dma_addr_t dummy_page_da;
273 void *dummy_page_va;
274
275 dummy_page_va = kmalloc(PAGE_SIZE, GFP_KERNEL);
276 if (!dummy_page_va) {
277 pr_err("PCIEX:Alloc dummy_page_va failed\n");
278 return -1;
279 }
280
281 dummy_page_da = dma_map_single(bus->phb->parent, dummy_page_va,
282 PAGE_SIZE, DMA_FROM_DEVICE);
283 if (dma_mapping_error(dummy_page_da)) {
284 pr_err("PCIEX:Map dummy page failed.\n");
285 kfree(dummy_page_va);
286 return -1;
287 }
288
289 PEX_OUT(bus->phb->cfg_addr, PEXDMRDADR0, dummy_page_da);
290
291 return 0;
292}
293
294/*
295 * config space access
296 */
297#define MK_PEXDADRS(bus_no, dev_no, func_no, addr) \
298 ((uint32_t)(((addr) & ~0x3UL) | \
299 ((bus_no) << PEXDADRS_BUSNO_SHIFT) | \
300 ((dev_no) << PEXDADRS_DEVNO_SHIFT) | \
301 ((func_no) << PEXDADRS_FUNCNO_SHIFT)))
302
303#define MK_PEXDCMND_BYTE_EN(addr, size) \
304 ((((0x1 << (size))-1) << ((addr) & 0x3)) << PEXDCMND_BYTE_EN_SHIFT)
305#define MK_PEXDCMND(cmd, addr, size) ((cmd) | MK_PEXDCMND_BYTE_EN(addr, size))
306
307static uint32_t config_read_pciex_dev(unsigned int *base,
308 uint64_t bus_no, uint64_t dev_no, uint64_t func_no,
309 uint64_t off, uint64_t size)
310{
311 uint32_t ret;
312 uint32_t addr, cmd;
313
314 addr = MK_PEXDADRS(bus_no, dev_no, func_no, off);
315 cmd = MK_PEXDCMND(PEXDCMND_CONFIG_READ, off, size);
316 PEX_OUT(base, PEXDADRS, addr);
317 PEX_OUT(base, PEXDCMND, cmd);
318 ret = (PEX_IN(base, PEXDRDATA)
319 >> ((off & (4-size)) * 8)) & ((0x1 << (size * 8)) - 1);
320 return ret;
321}
322
323static void config_write_pciex_dev(unsigned int *base, uint64_t bus_no,
324 uint64_t dev_no, uint64_t func_no, uint64_t off, uint64_t size,
325 uint32_t data)
326{
327 uint32_t addr, cmd;
328
329 addr = MK_PEXDADRS(bus_no, dev_no, func_no, off);
330 cmd = MK_PEXDCMND(PEXDCMND_CONFIG_WRITE, off, size);
331 PEX_OUT(base, PEXDADRS, addr);
332 PEX_OUT(base, PEXDCMND, cmd);
333 PEX_OUT(base, PEXDWDATA,
334 (data & ((0x1 << (size * 8)) - 1)) << ((off & (4-size)) * 8));
335}
336
337#define MK_PEXCADRS_BYTE_EN(off, len) \
338 ((((0x1 << (len)) - 1) << ((off) & 0x3)) << PEXCADRS_BYTE_EN_SHIFT)
339#define MK_PEXCADRS(cmd, addr, size) \
340 ((cmd) | MK_PEXCADRS_BYTE_EN(addr, size) | ((addr) & ~0x3))
341static uint32_t config_read_pciex_rc(unsigned int *base,
342 uint32_t where, uint32_t size)
343{
344 PEX_OUT(base, PEXCADRS, MK_PEXCADRS(PEXCADRS_CMD_READ, where, size));
345 return (PEX_IN(base, PEXCRDATA)
346 >> ((where & (4 - size)) * 8)) & ((0x1 << (size * 8)) - 1);
347}
348
349static void config_write_pciex_rc(unsigned int *base, uint32_t where,
350 uint32_t size, uint32_t val)
351{
352 uint32_t data;
353
354 data = (val & ((0x1 << (size * 8)) - 1)) << ((where & (4 - size)) * 8);
355 PEX_OUT(base, PEXCADRS, MK_PEXCADRS(PEXCADRS_CMD_WRITE, where, size));
356 PEX_OUT(base, PEXCWDATA, data);
357}
358
359/* Interfaces */
360/* Note: Work-around
361 * On SCC PCIEXC, one device is seen on all 32 dev_no.
362 * As SCC PCIEXC can have only one device on the bus, we look only one dev_no.
363 * (dev_no = 1)
364 */
365static int scc_pciex_read_config(struct pci_bus *bus, unsigned int devfn,
366 int where, int size, unsigned int *val)
367{
368 struct device_node *dn;
369 struct pci_controller *phb;
370
371 dn = bus->sysdata;
372 phb = pci_find_hose_for_OF_device(dn);
373
374 if (bus->number == phb->first_busno && PCI_SLOT(devfn) != 1) {
375 *val = ~0;
376 return PCIBIOS_DEVICE_NOT_FOUND;
377 }
378
379 if (bus->number == 0 && PCI_SLOT(devfn) == 0)
380 *val = config_read_pciex_rc(phb->cfg_addr, where, size);
381 else
382 *val = config_read_pciex_dev(phb->cfg_addr, bus->number,
383 PCI_SLOT(devfn), PCI_FUNC(devfn), where, size);
384
385 return PCIBIOS_SUCCESSFUL;
386}
387
388static int scc_pciex_write_config(struct pci_bus *bus, unsigned int devfn,
389 int where, int size, unsigned int val)
390{
391 struct device_node *dn;
392 struct pci_controller *phb;
393
394 dn = bus->sysdata;
395 phb = pci_find_hose_for_OF_device(dn);
396
397 if (bus->number == phb->first_busno && PCI_SLOT(devfn) != 1)
398 return PCIBIOS_DEVICE_NOT_FOUND;
399
400 if (bus->number == 0 && PCI_SLOT(devfn) == 0)
401 config_write_pciex_rc(phb->cfg_addr, where, size, val);
402 else
403 config_write_pciex_dev(phb->cfg_addr, bus->number,
404 PCI_SLOT(devfn), PCI_FUNC(devfn), where, size, val);
405 return PCIBIOS_SUCCESSFUL;
406}
407
408static struct pci_ops scc_pciex_pci_ops = {
409 scc_pciex_read_config,
410 scc_pciex_write_config,
411};
412
413static void pciex_clear_intr_all(unsigned int *base)
414{
415 PEX_OUT(base, PEXAERRSTS, 0xffffffff);
416 PEX_OUT(base, PEXPRERRSTS, 0xffffffff);
417 PEX_OUT(base, PEXINTSTS, 0xffffffff);
418}
419
420#if 0
421static void pciex_disable_intr_all(unsigned int *base)
422{
423 PEX_OUT(base, PEXINTMASK, 0x0);
424 PEX_OUT(base, PEXAERRMASK, 0x0);
425 PEX_OUT(base, PEXPRERRMASK, 0x0);
426 PEX_OUT(base, PEXVDMASK, 0x0);
427}
428#endif
429
430static void pciex_enable_intr_all(unsigned int *base)
431{
432 PEX_OUT(base, PEXINTMASK, 0x0000e7f1);
433 PEX_OUT(base, PEXAERRMASK, 0x03ff01ff);
434 PEX_OUT(base, PEXPRERRMASK, 0x0001010f);
435 PEX_OUT(base, PEXVDMASK, 0x00000001);
436}
437
438static void pciex_check_status(unsigned int *base)
439{
440 uint32_t err = 0;
441 uint32_t intsts, aerr, prerr, rcvcp, lenerr;
442 uint32_t maea, maec;
443
444 intsts = PEX_IN(base, PEXINTSTS);
445 aerr = PEX_IN(base, PEXAERRSTS);
446 prerr = PEX_IN(base, PEXPRERRSTS);
447 rcvcp = PEX_IN(base, PEXRCVCPLIDA);
448 lenerr = PEX_IN(base, PEXLENERRIDA);
449
450 if (intsts || aerr || prerr || rcvcp || lenerr)
451 err = 1;
452
453 pr_info("PCEXC interrupt!!\n");
454 pr_info("PEXINTSTS :0x%08x\n", intsts);
455 pr_info("PEXAERRSTS :0x%08x\n", aerr);
456 pr_info("PEXPRERRSTS :0x%08x\n", prerr);
457 pr_info("PEXRCVCPLIDA :0x%08x\n", rcvcp);
458 pr_info("PEXLENERRIDA :0x%08x\n", lenerr);
459
460 /* print detail of Protection Error */
461 if (intsts & 0x00004000) {
462 uint32_t i, n;
463 for (i = 0; i < 4; i++) {
464 n = 1 << i;
465 if (prerr & n) {
466 maea = PEX_IN(base, PEXMAEA(i));
467 maec = PEX_IN(base, PEXMAEC(i));
468 pr_info("PEXMAEC%d :0x%08x\n", i, maec);
469 pr_info("PEXMAEA%d :0x%08x\n", i, maea);
470 }
471 }
472 }
473
474 if (err)
475 pciex_clear_intr_all(base);
476}
477
478static irqreturn_t pciex_handle_internal_irq(int irq, void *dev_id)
479{
480 struct pci_controller *phb = dev_id;
481
482 pr_debug("PCIEX:pciex_handle_internal_irq(irq=%d)\n", irq);
483
484 BUG_ON(phb->cfg_addr == NULL);
485
486 pciex_check_status(phb->cfg_addr);
487
488 return IRQ_HANDLED;
489}
490
491static __init int celleb_setup_pciex(struct device_node *node,
492 struct pci_controller *phb)
493{
494 struct resource r;
495 struct of_irq oirq;
496 int virq;
497
498 /* SMMIO registers; used inside this file */
499 if (of_address_to_resource(node, 0, &r)) {
500 pr_err("PCIEXC:Failed to get config resource.\n");
501 return 1;
502 }
503 phb->cfg_addr = ioremap(r.start, r.end - r.start + 1);
504 if (!phb->cfg_addr) {
505 pr_err("PCIEXC:Failed to remap SMMIO region.\n");
506 return 1;
507 }
508
509 /* Not use cfg_data, cmd and data regs are near address reg */
510 phb->cfg_data = NULL;
511
512 /* set pci_ops */
513 phb->ops = &scc_pciex_pci_ops;
514
515 /* internal interrupt handler */
516 if (of_irq_map_one(node, 1, &oirq)) {
517 pr_err("PCIEXC:Failed to map irq\n");
518 goto error;
519 }
520 virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
521 oirq.size);
522 if (request_irq(virq, pciex_handle_internal_irq,
523 IRQF_DISABLED, "pciex", (void *)phb)) {
524 pr_err("PCIEXC:Failed to request irq\n");
525 goto error;
526 }
527
528 /* enable all interrupts */
529 pciex_clear_intr_all(phb->cfg_addr);
530 pciex_enable_intr_all(phb->cfg_addr);
531 /* MSI: TBD */
532
533 return 0;
534
535error:
536 phb->cfg_data = NULL;
537 if (phb->cfg_addr)
538 iounmap(phb->cfg_addr);
539 phb->cfg_addr = NULL;
540 return 1;
541}
542
543struct celleb_phb_spec celleb_pciex_spec __initdata = {
544 .setup = celleb_setup_pciex,
545 .ops = &scc_pciex_ops,
546 .iowa_init = &scc_pciex_iowa_init,
547};
diff --git a/arch/powerpc/platforms/celleb/scc_sio.c b/arch/powerpc/platforms/cell/celleb_scc_sio.c
index 3a16c5b3c464..3a16c5b3c464 100644
--- a/arch/powerpc/platforms/celleb/scc_sio.c
+++ b/arch/powerpc/platforms/cell/celleb_scc_sio.c
diff --git a/arch/powerpc/platforms/celleb/scc_uhc.c b/arch/powerpc/platforms/cell/celleb_scc_uhc.c
index cb4307994087..d63b720bfe3a 100644
--- a/arch/powerpc/platforms/celleb/scc_uhc.c
+++ b/arch/powerpc/platforms/cell/celleb_scc_uhc.c
@@ -25,7 +25,7 @@
25#include <asm/io.h> 25#include <asm/io.h>
26#include <asm/machdep.h> 26#include <asm/machdep.h>
27 27
28#include "scc.h" 28#include "celleb_scc.h"
29 29
30#define UHC_RESET_WAIT_MAX 10000 30#define UHC_RESET_WAIT_MAX 10000
31 31
diff --git a/arch/powerpc/platforms/celleb/setup.c b/arch/powerpc/platforms/cell/celleb_setup.c
index f27ae1e3fb58..b11cb30decb2 100644
--- a/arch/powerpc/platforms/celleb/setup.c
+++ b/arch/powerpc/platforms/cell/celleb_setup.c
@@ -56,13 +56,13 @@
56#include <asm/rtas.h> 56#include <asm/rtas.h>
57#include <asm/cell-regs.h> 57#include <asm/cell-regs.h>
58 58
59#include "interrupt.h" 59#include "beat_interrupt.h"
60#include "beat_wrapper.h" 60#include "beat_wrapper.h"
61#include "beat.h" 61#include "beat.h"
62#include "pci.h" 62#include "celleb_pci.h"
63#include "../cell/interrupt.h" 63#include "interrupt.h"
64#include "../cell/pervasive.h" 64#include "pervasive.h"
65#include "../cell/ras.h" 65#include "ras.h"
66 66
67static char celleb_machine_type[128] = "Celleb"; 67static char celleb_machine_type[128] = "Celleb";
68 68
@@ -114,8 +114,6 @@ static int __init celleb_publish_devices(void)
114 /* Publish OF platform devices for southbridge IOs */ 114 /* Publish OF platform devices for southbridge IOs */
115 of_platform_bus_probe(NULL, celleb_bus_ids, NULL); 115 of_platform_bus_probe(NULL, celleb_bus_ids, NULL);
116 116
117 celleb_pci_workaround_init();
118
119 return 0; 117 return 0;
120} 118}
121machine_device_initcall(celleb_beat, celleb_publish_devices); 119machine_device_initcall(celleb_beat, celleb_publish_devices);
diff --git a/arch/powerpc/platforms/cell/io-workarounds.c b/arch/powerpc/platforms/cell/io-workarounds.c
index 979d4b67efb4..3b84e8be314c 100644
--- a/arch/powerpc/platforms/cell/io-workarounds.c
+++ b/arch/powerpc/platforms/cell/io-workarounds.c
@@ -1,6 +1,9 @@
1/* 1/*
2 * Support PCI IO workaround
3 *
2 * Copyright (C) 2006 Benjamin Herrenschmidt <benh@kernel.crashing.org> 4 * Copyright (C) 2006 Benjamin Herrenschmidt <benh@kernel.crashing.org>
3 * IBM, Corp. 5 * IBM, Corp.
6 * (C) Copyright 2007-2008 TOSHIBA CORPORATION
4 * 7 *
5 * 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
6 * it under the terms of the GNU General Public License version 2 as 9 * it under the terms of the GNU General Public License version 2 as
@@ -9,335 +12,174 @@
9#undef DEBUG 12#undef DEBUG
10 13
11#include <linux/kernel.h> 14#include <linux/kernel.h>
12#include <linux/mm.h> 15
13#include <linux/pci.h>
14#include <asm/io.h> 16#include <asm/io.h>
15#include <asm/machdep.h> 17#include <asm/machdep.h>
16#include <asm/pci-bridge.h> 18#include <asm/pgtable.h>
17#include <asm/ppc-pci.h> 19#include <asm/ppc-pci.h>
18 20
21#include "io-workarounds.h"
19 22
20#define SPIDER_PCI_REG_BASE 0xd000 23#define IOWA_MAX_BUS 8
21#define SPIDER_PCI_VCI_CNTL_STAT 0x0110
22#define SPIDER_PCI_DUMMY_READ 0x0810
23#define SPIDER_PCI_DUMMY_READ_BASE 0x0814
24 24
25/* Undefine that to re-enable bogus prefetch 25static struct iowa_bus iowa_busses[IOWA_MAX_BUS];
26 * 26static unsigned int iowa_bus_count;
27 * Without that workaround, the chip will do bogus prefetch past
28 * page boundary from system memory. This setting will disable that,
29 * though the documentation is unclear as to the consequences of doing
30 * so, either purely performances, or possible misbehaviour... It's not
31 * clear wether the chip can handle unaligned accesses at all without
32 * prefetching enabled.
33 *
34 * For now, things appear to be behaving properly with that prefetching
35 * disabled and IDE, possibly because IDE isn't doing any unaligned
36 * access.
37 */
38#define SPIDER_DISABLE_PREFETCH
39 27
40#define MAX_SPIDERS 3 28static struct iowa_bus *iowa_pci_find(unsigned long vaddr, unsigned long paddr)
29{
30 int i, j;
31 struct resource *res;
32 unsigned long vstart, vend;
41 33
42static struct spider_pci_bus { 34 for (i = 0; i < iowa_bus_count; i++) {
43 void __iomem *regs; 35 struct iowa_bus *bus = &iowa_busses[i];
44 unsigned long mmio_start; 36 struct pci_controller *phb = bus->phb;
45 unsigned long mmio_end;
46 unsigned long pio_vstart;
47 unsigned long pio_vend;
48} spider_pci_busses[MAX_SPIDERS];
49static int spider_pci_count;
50 37
51static struct spider_pci_bus *spider_pci_find(unsigned long vaddr, 38 if (vaddr) {
52 unsigned long paddr) 39 vstart = (unsigned long)phb->io_base_virt;
53{ 40 vend = vstart + phb->pci_io_size - 1;
54 int i; 41 if ((vaddr >= vstart) && (vaddr <= vend))
55 42 return bus;
56 for (i = 0; i < spider_pci_count; i++) { 43 }
57 struct spider_pci_bus *bus = &spider_pci_busses[i]; 44
58 if (paddr && paddr >= bus->mmio_start && paddr < bus->mmio_end) 45 if (paddr)
59 return bus; 46 for (j = 0; j < 3; j++) {
60 if (vaddr && vaddr >= bus->pio_vstart && vaddr < bus->pio_vend) 47 res = &phb->mem_resources[j];
61 return bus; 48 if (paddr >= res->start && paddr <= res->end)
49 return bus;
50 }
62 } 51 }
52
63 return NULL; 53 return NULL;
64} 54}
65 55
66static void spider_io_flush(const volatile void __iomem *addr) 56struct iowa_bus *iowa_mem_find_bus(const PCI_IO_ADDR addr)
67{ 57{
68 struct spider_pci_bus *bus; 58 struct iowa_bus *bus;
69 int token; 59 int token;
70 60
71 /* Get platform token (set by ioremap) from address */
72 token = PCI_GET_ADDR_TOKEN(addr); 61 token = PCI_GET_ADDR_TOKEN(addr);
73 62
74 /* Fast path if we have a non-0 token, it indicates which bus we 63 if (token && token <= iowa_bus_count)
75 * are on. 64 bus = &iowa_busses[token - 1];
76 *
77 * If the token is 0, that means either that the ioremap was done
78 * before we initialized this layer, or it's a PIO operation. We
79 * fallback to a low path in this case. Hopefully, internal devices
80 * which are ioremap'ed early should use in_XX/out_XX functions
81 * instead of the PCI ones and thus not suffer from the slowdown.
82 *
83 * Also note that currently, the workaround will not work for areas
84 * that are not mapped with PTEs (bolted in the hash table). This
85 * is the case for ioremaps done very early at boot (before
86 * mem_init_done) and includes the mapping of the ISA IO space.
87 *
88 * Fortunately, none of the affected devices is expected to do DMA
89 * and thus there should be no problem in practice.
90 *
91 * In order to improve performances, we only do the PTE search for
92 * addresses falling in the PHB IO space area. That means it will
93 * not work for hotplug'ed PHBs but those don't exist with Spider.
94 */
95 if (token && token <= spider_pci_count)
96 bus = &spider_pci_busses[token - 1];
97 else { 65 else {
98 unsigned long vaddr, paddr; 66 unsigned long vaddr, paddr;
99 pte_t *ptep; 67 pte_t *ptep;
100 68
101 /* Fixup physical address */
102 vaddr = (unsigned long)PCI_FIX_ADDR(addr); 69 vaddr = (unsigned long)PCI_FIX_ADDR(addr);
70 if (vaddr < PHB_IO_BASE || vaddr >= PHB_IO_END)
71 return NULL;
103 72
104 /* Check if it's in allowed range for PIO */
105 if (vaddr < PHB_IO_BASE || vaddr > PHB_IO_END)
106 return;
107
108 /* Try to find a PTE. If not, clear the paddr, we'll do
109 * a vaddr only lookup (PIO only)
110 */
111 ptep = find_linux_pte(init_mm.pgd, vaddr); 73 ptep = find_linux_pte(init_mm.pgd, vaddr);
112 if (ptep == NULL) 74 if (ptep == NULL)
113 paddr = 0; 75 paddr = 0;
114 else 76 else
115 paddr = pte_pfn(*ptep) << PAGE_SHIFT; 77 paddr = pte_pfn(*ptep) << PAGE_SHIFT;
78 bus = iowa_pci_find(vaddr, paddr);
116 79
117 bus = spider_pci_find(vaddr, paddr);
118 if (bus == NULL) 80 if (bus == NULL)
119 return; 81 return NULL;
120 } 82 }
121 83
122 /* Now do the workaround 84 return bus;
123 */
124 (void)in_be32(bus->regs + SPIDER_PCI_DUMMY_READ);
125} 85}
126 86
127static u8 spider_readb(const volatile void __iomem *addr) 87struct iowa_bus *iowa_pio_find_bus(unsigned long port)
128{ 88{
129 u8 val = __do_readb(addr); 89 unsigned long vaddr = (unsigned long)pci_io_base + port;
130 spider_io_flush(addr); 90 return iowa_pci_find(vaddr, 0);
131 return val;
132} 91}
133 92
134static u16 spider_readw(const volatile void __iomem *addr)
135{
136 u16 val = __do_readw(addr);
137 spider_io_flush(addr);
138 return val;
139}
140 93
141static u32 spider_readl(const volatile void __iomem *addr) 94#define DEF_PCI_AC_RET(name, ret, at, al, space, aa) \
142{ 95static ret iowa_##name at \
143 u32 val = __do_readl(addr); 96{ \
144 spider_io_flush(addr); 97 struct iowa_bus *bus; \
145 return val; 98 bus = iowa_##space##_find_bus(aa); \
99 if (bus && bus->ops && bus->ops->name) \
100 return bus->ops->name al; \
101 return __do_##name al; \
146} 102}
147 103
148static u64 spider_readq(const volatile void __iomem *addr) 104#define DEF_PCI_AC_NORET(name, at, al, space, aa) \
149{ 105static void iowa_##name at \
150 u64 val = __do_readq(addr); 106{ \
151 spider_io_flush(addr); 107 struct iowa_bus *bus; \
152 return val; 108 bus = iowa_##space##_find_bus(aa); \
109 if (bus && bus->ops && bus->ops->name) { \
110 bus->ops->name al; \
111 return; \
112 } \
113 __do_##name al; \
153} 114}
154 115
155static u16 spider_readw_be(const volatile void __iomem *addr) 116#include <asm/io-defs.h>
156{
157 u16 val = __do_readw_be(addr);
158 spider_io_flush(addr);
159 return val;
160}
161 117
162static u32 spider_readl_be(const volatile void __iomem *addr) 118#undef DEF_PCI_AC_RET
163{ 119#undef DEF_PCI_AC_NORET
164 u32 val = __do_readl_be(addr);
165 spider_io_flush(addr);
166 return val;
167}
168 120
169static u64 spider_readq_be(const volatile void __iomem *addr) 121static struct ppc_pci_io __initdata iowa_pci_io = {
170{
171 u64 val = __do_readq_be(addr);
172 spider_io_flush(addr);
173 return val;
174}
175 122
176static void spider_readsb(const volatile void __iomem *addr, void *buf, 123#define DEF_PCI_AC_RET(name, ret, at, al, space, aa) .name = iowa_##name,
177 unsigned long count) 124#define DEF_PCI_AC_NORET(name, at, al, space, aa) .name = iowa_##name,
178{
179 __do_readsb(addr, buf, count);
180 spider_io_flush(addr);
181}
182 125
183static void spider_readsw(const volatile void __iomem *addr, void *buf, 126#include <asm/io-defs.h>
184 unsigned long count)
185{
186 __do_readsw(addr, buf, count);
187 spider_io_flush(addr);
188}
189 127
190static void spider_readsl(const volatile void __iomem *addr, void *buf, 128#undef DEF_PCI_AC_RET
191 unsigned long count) 129#undef DEF_PCI_AC_NORET
192{
193 __do_readsl(addr, buf, count);
194 spider_io_flush(addr);
195}
196
197static void spider_memcpy_fromio(void *dest, const volatile void __iomem *src,
198 unsigned long n)
199{
200 __do_memcpy_fromio(dest, src, n);
201 spider_io_flush(src);
202}
203 130
131};
204 132
205static void __iomem * spider_ioremap(unsigned long addr, unsigned long size, 133static void __iomem *iowa_ioremap(unsigned long addr, unsigned long size,
206 unsigned long flags) 134 unsigned long flags)
207{ 135{
208 struct spider_pci_bus *bus; 136 struct iowa_bus *bus;
209 void __iomem *res = __ioremap(addr, size, flags); 137 void __iomem *res = __ioremap(addr, size, flags);
210 int busno; 138 int busno;
211 139
212 pr_debug("spider_ioremap(0x%lx, 0x%lx, 0x%lx) -> 0x%p\n", 140 bus = iowa_pci_find(0, addr);
213 addr, size, flags, res);
214
215 bus = spider_pci_find(0, addr);
216 if (bus != NULL) { 141 if (bus != NULL) {
217 busno = bus - spider_pci_busses; 142 busno = bus - iowa_busses;
218 pr_debug(" found bus %d, setting token\n", busno);
219 PCI_SET_ADDR_TOKEN(res, busno + 1); 143 PCI_SET_ADDR_TOKEN(res, busno + 1);
220 } 144 }
221 pr_debug(" result=0x%p\n", res);
222
223 return res; 145 return res;
224} 146}
225 147
226static void __init spider_pci_setup_chip(struct spider_pci_bus *bus) 148/* Regist new bus to support workaround */
227{ 149void __init iowa_register_bus(struct pci_controller *phb,
228#ifdef SPIDER_DISABLE_PREFETCH 150 struct ppc_pci_io *ops,
229 u32 val = in_be32(bus->regs + SPIDER_PCI_VCI_CNTL_STAT); 151 int (*initfunc)(struct iowa_bus *, void *), void *data)
230 pr_debug(" PVCI_Control_Status was 0x%08x\n", val);
231 out_be32(bus->regs + SPIDER_PCI_VCI_CNTL_STAT, val | 0x8);
232#endif
233
234 /* Configure the dummy address for the workaround */
235 out_be32(bus->regs + SPIDER_PCI_DUMMY_READ_BASE, 0x80000000);
236}
237
238static void __init spider_pci_add_one(struct pci_controller *phb)
239{ 152{
240 struct spider_pci_bus *bus = &spider_pci_busses[spider_pci_count]; 153 struct iowa_bus *bus;
241 struct device_node *np = phb->dn; 154 struct device_node *np = phb->dn;
242 struct resource rsrc;
243 void __iomem *regs;
244 155
245 if (spider_pci_count >= MAX_SPIDERS) { 156 if (iowa_bus_count >= IOWA_MAX_BUS) {
246 printk(KERN_ERR "Too many spider bridges, workarounds" 157 pr_err("IOWA:Too many pci bridges, "
247 " disabled for %s\n", np->full_name); 158 "workarounds disabled for %s\n", np->full_name);
248 return; 159 return;
249 } 160 }
250 161
251 /* Get the registers for the beast */ 162 bus = &iowa_busses[iowa_bus_count];
252 if (of_address_to_resource(np, 0, &rsrc)) { 163 bus->phb = phb;
253 printk(KERN_ERR "Failed to get registers for spider %s" 164 bus->ops = ops;
254 " workarounds disabled\n", np->full_name);
255 return;
256 }
257 165
258 /* Mask out some useless bits in there to get to the base of the 166 if (initfunc)
259 * spider chip 167 if ((*initfunc)(bus, data))
260 */ 168 return;
261 rsrc.start &= ~0xfffffffful;
262
263 /* Map them */
264 regs = ioremap(rsrc.start + SPIDER_PCI_REG_BASE, 0x1000);
265 if (regs == NULL) {
266 printk(KERN_ERR "Failed to map registers for spider %s"
267 " workarounds disabled\n", np->full_name);
268 return;
269 }
270
271 spider_pci_count++;
272
273 /* We assume spiders only have one MMIO resource */
274 bus->mmio_start = phb->mem_resources[0].start;
275 bus->mmio_end = phb->mem_resources[0].end + 1;
276
277 bus->pio_vstart = (unsigned long)phb->io_base_virt;
278 bus->pio_vend = bus->pio_vstart + phb->pci_io_size;
279
280 bus->regs = regs;
281
282 printk(KERN_INFO "PCI: Spider MMIO workaround for %s\n",np->full_name);
283 169
284 pr_debug(" mmio (P) = 0x%016lx..0x%016lx\n", 170 iowa_bus_count++;
285 bus->mmio_start, bus->mmio_end);
286 pr_debug(" pio (V) = 0x%016lx..0x%016lx\n",
287 bus->pio_vstart, bus->pio_vend);
288 pr_debug(" regs (P) = 0x%016lx (V) = 0x%p\n",
289 rsrc.start + SPIDER_PCI_REG_BASE, bus->regs);
290 171
291 spider_pci_setup_chip(bus); 172 pr_debug("IOWA:[%d]Add bus, %s.\n", iowa_bus_count-1, np->full_name);
292} 173}
293 174
294static struct ppc_pci_io __initdata spider_pci_io = { 175/* enable IO workaround */
295 .readb = spider_readb, 176void __init io_workaround_init(void)
296 .readw = spider_readw,
297 .readl = spider_readl,
298 .readq = spider_readq,
299 .readw_be = spider_readw_be,
300 .readl_be = spider_readl_be,
301 .readq_be = spider_readq_be,
302 .readsb = spider_readsb,
303 .readsw = spider_readsw,
304 .readsl = spider_readsl,
305 .memcpy_fromio = spider_memcpy_fromio,
306};
307
308static int __init spider_pci_workaround_init(void)
309{ 177{
310 struct pci_controller *phb; 178 static int io_workaround_inited;
311
312 /* Find spider bridges. We assume they have been all probed
313 * in setup_arch(). If that was to change, we would need to
314 * update this code to cope with dynamically added busses
315 */
316 list_for_each_entry(phb, &hose_list, list_node) {
317 struct device_node *np = phb->dn;
318 const char *model = of_get_property(np, "model", NULL);
319
320 /* If no model property or name isn't exactly "pci", skip */
321 if (model == NULL || strcmp(np->name, "pci"))
322 continue;
323 /* If model is not "Spider", skip */
324 if (strcmp(model, "Spider"))
325 continue;
326 spider_pci_add_one(phb);
327 }
328
329 /* No Spider PCI found, exit */
330 if (spider_pci_count == 0)
331 return 0;
332 179
333 /* Setup IO callbacks. We only setup MMIO reads. PIO reads will 180 if (io_workaround_inited)
334 * fallback to MMIO reads (though without a token, thus slower) 181 return;
335 */ 182 ppc_pci_io = iowa_pci_io;
336 ppc_pci_io = spider_pci_io; 183 ppc_md.ioremap = iowa_ioremap;
337 184 io_workaround_inited = 1;
338 /* Setup ioremap callback */
339 ppc_md.ioremap = spider_ioremap;
340
341 return 0;
342} 185}
343machine_arch_initcall(cell, spider_pci_workaround_init);
diff --git a/arch/powerpc/platforms/cell/io-workarounds.h b/arch/powerpc/platforms/cell/io-workarounds.h
new file mode 100644
index 000000000000..79d8ed3d510f
--- /dev/null
+++ b/arch/powerpc/platforms/cell/io-workarounds.h
@@ -0,0 +1,49 @@
1/*
2 * Support PCI IO workaround
3 *
4 * (C) Copyright 2007-2008 TOSHIBA CORPORATION
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 as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
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 along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21#ifndef _IO_WORKAROUNDS_H
22#define _IO_WORKAROUNDS_H
23
24#include <linux/io.h>
25#include <asm/pci-bridge.h>
26
27/* Bus info */
28struct iowa_bus {
29 struct pci_controller *phb;
30 struct ppc_pci_io *ops;
31 void *private;
32};
33
34void __init io_workaround_init(void);
35void __init iowa_register_bus(struct pci_controller *, struct ppc_pci_io *,
36 int (*)(struct iowa_bus *, void *), void *);
37struct iowa_bus *iowa_mem_find_bus(const PCI_IO_ADDR);
38struct iowa_bus *iowa_pio_find_bus(unsigned long);
39
40extern struct ppc_pci_io spiderpci_ops;
41extern int spiderpci_iowa_init(struct iowa_bus *, void *);
42
43#define SPIDER_PCI_REG_BASE 0xd000
44#define SPIDER_PCI_REG_SIZE 0x1000
45#define SPIDER_PCI_VCI_CNTL_STAT 0x0110
46#define SPIDER_PCI_DUMMY_READ 0x0810
47#define SPIDER_PCI_DUMMY_READ_BASE 0x0814
48
49#endif /* _IO_WORKAROUNDS_H */
diff --git a/arch/powerpc/platforms/cell/setup.c b/arch/powerpc/platforms/cell/setup.c
index 5c531e8f9f6f..ab721b50fbba 100644
--- a/arch/powerpc/platforms/cell/setup.c
+++ b/arch/powerpc/platforms/cell/setup.c
@@ -57,6 +57,7 @@
57#include "interrupt.h" 57#include "interrupt.h"
58#include "pervasive.h" 58#include "pervasive.h"
59#include "ras.h" 59#include "ras.h"
60#include "io-workarounds.h"
60 61
61#ifdef DEBUG 62#ifdef DEBUG
62#define DBG(fmt...) udbg_printf(fmt) 63#define DBG(fmt...) udbg_printf(fmt)
@@ -117,13 +118,50 @@ static void cell_fixup_pcie_rootcomplex(struct pci_dev *dev)
117} 118}
118DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, cell_fixup_pcie_rootcomplex); 119DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, cell_fixup_pcie_rootcomplex);
119 120
121static int __devinit cell_setup_phb(struct pci_controller *phb)
122{
123 const char *model;
124 struct device_node *np;
125
126 int rc = rtas_setup_phb(phb);
127 if (rc)
128 return rc;
129
130 np = phb->dn;
131 model = of_get_property(np, "model", NULL);
132 if (model == NULL || strcmp(np->name, "pci"))
133 return 0;
134
135 /* Setup workarounds for spider */
136 if (strcmp(model, "Spider"))
137 return 0;
138
139 iowa_register_bus(phb, &spiderpci_ops, &spiderpci_iowa_init,
140 (void *)SPIDER_PCI_REG_BASE);
141 io_workaround_init();
142
143 return 0;
144}
145
120static int __init cell_publish_devices(void) 146static int __init cell_publish_devices(void)
121{ 147{
148 struct device_node *root = of_find_node_by_path("/");
149 struct device_node *np;
122 int node; 150 int node;
123 151
124 /* Publish OF platform devices for southbridge IOs */ 152 /* Publish OF platform devices for southbridge IOs */
125 of_platform_bus_probe(NULL, NULL, NULL); 153 of_platform_bus_probe(NULL, NULL, NULL);
126 154
155 /* On spider based blades, we need to manually create the OF
156 * platform devices for the PCI host bridges
157 */
158 for_each_child_of_node(root, np) {
159 if (np->type == NULL || (strcmp(np->type, "pci") != 0 &&
160 strcmp(np->type, "pciex") != 0))
161 continue;
162 of_platform_device_create(np, NULL, NULL);
163 }
164
127 /* There is no device for the MIC memory controller, thus we create 165 /* There is no device for the MIC memory controller, thus we create
128 * a platform device for it to attach the EDAC driver to. 166 * a platform device for it to attach the EDAC driver to.
129 */ 167 */
@@ -132,6 +170,7 @@ static int __init cell_publish_devices(void)
132 continue; 170 continue;
133 platform_device_register_simple("cbe-mic", node, NULL, 0); 171 platform_device_register_simple("cbe-mic", node, NULL, 0);
134 } 172 }
173
135 return 0; 174 return 0;
136} 175}
137machine_subsys_initcall(cell, cell_publish_devices); 176machine_subsys_initcall(cell, cell_publish_devices);
@@ -213,7 +252,7 @@ static void __init cell_setup_arch(void)
213 252
214 /* Find and initialize PCI host bridges */ 253 /* Find and initialize PCI host bridges */
215 init_pci_config_tokens(); 254 init_pci_config_tokens();
216 find_and_init_phbs(); 255
217 cbe_pervasive_init(); 256 cbe_pervasive_init();
218#ifdef CONFIG_DUMMY_CONSOLE 257#ifdef CONFIG_DUMMY_CONSOLE
219 conswitchp = &dummy_con; 258 conswitchp = &dummy_con;
@@ -249,7 +288,7 @@ define_machine(cell) {
249 .calibrate_decr = generic_calibrate_decr, 288 .calibrate_decr = generic_calibrate_decr,
250 .progress = cell_progress, 289 .progress = cell_progress,
251 .init_IRQ = cell_init_irq, 290 .init_IRQ = cell_init_irq,
252 .pci_setup_phb = rtas_setup_phb, 291 .pci_setup_phb = cell_setup_phb,
253#ifdef CONFIG_KEXEC 292#ifdef CONFIG_KEXEC
254 .machine_kexec = default_machine_kexec, 293 .machine_kexec = default_machine_kexec,
255 .machine_kexec_prepare = default_machine_kexec_prepare, 294 .machine_kexec_prepare = default_machine_kexec_prepare,
diff --git a/arch/powerpc/platforms/cell/spider-pci.c b/arch/powerpc/platforms/cell/spider-pci.c
new file mode 100644
index 000000000000..418b605ac35a
--- /dev/null
+++ b/arch/powerpc/platforms/cell/spider-pci.c
@@ -0,0 +1,184 @@
1/*
2 * IO workarounds for PCI on Celleb/Cell platform
3 *
4 * (C) Copyright 2006-2007 TOSHIBA CORPORATION
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 as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
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 along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21#undef DEBUG
22
23#include <linux/kernel.h>
24#include <linux/of_platform.h>
25#include <linux/io.h>
26
27#include <asm/ppc-pci.h>
28#include <asm/pci-bridge.h>
29
30#include "io-workarounds.h"
31
32#define SPIDER_PCI_DISABLE_PREFETCH
33
34struct spiderpci_iowa_private {
35 void __iomem *regs;
36};
37
38static void spiderpci_io_flush(struct iowa_bus *bus)
39{
40 struct spiderpci_iowa_private *priv;
41 u32 val;
42
43 priv = bus->private;
44 val = in_be32(priv->regs + SPIDER_PCI_DUMMY_READ);
45 iosync();
46}
47
48#define SPIDER_PCI_MMIO_READ(name, ret) \
49static ret spiderpci_##name(const PCI_IO_ADDR addr) \
50{ \
51 ret val = __do_##name(addr); \
52 spiderpci_io_flush(iowa_mem_find_bus(addr)); \
53 return val; \
54}
55
56#define SPIDER_PCI_MMIO_READ_STR(name) \
57static void spiderpci_##name(const PCI_IO_ADDR addr, void *buf, \
58 unsigned long count) \
59{ \
60 __do_##name(addr, buf, count); \
61 spiderpci_io_flush(iowa_mem_find_bus(addr)); \
62}
63
64SPIDER_PCI_MMIO_READ(readb, u8)
65SPIDER_PCI_MMIO_READ(readw, u16)
66SPIDER_PCI_MMIO_READ(readl, u32)
67SPIDER_PCI_MMIO_READ(readq, u64)
68SPIDER_PCI_MMIO_READ(readw_be, u16)
69SPIDER_PCI_MMIO_READ(readl_be, u32)
70SPIDER_PCI_MMIO_READ(readq_be, u64)
71SPIDER_PCI_MMIO_READ_STR(readsb)
72SPIDER_PCI_MMIO_READ_STR(readsw)
73SPIDER_PCI_MMIO_READ_STR(readsl)
74
75static void spiderpci_memcpy_fromio(void *dest, const PCI_IO_ADDR src,
76 unsigned long n)
77{
78 __do_memcpy_fromio(dest, src, n);
79 spiderpci_io_flush(iowa_mem_find_bus(src));
80}
81
82static int __init spiderpci_pci_setup_chip(struct pci_controller *phb,
83 void __iomem *regs)
84{
85 void *dummy_page_va;
86 dma_addr_t dummy_page_da;
87
88#ifdef SPIDER_PCI_DISABLE_PREFETCH
89 u32 val = in_be32(regs + SPIDER_PCI_VCI_CNTL_STAT);
90 pr_debug("SPIDER_IOWA:PVCI_Control_Status was 0x%08x\n", val);
91 out_be32(regs + SPIDER_PCI_VCI_CNTL_STAT, val | 0x8);
92#endif /* SPIDER_PCI_DISABLE_PREFETCH */
93
94 /* setup dummy read */
95 /*
96 * On CellBlade, we can't know that which XDR memory is used by
97 * kmalloc() to allocate dummy_page_va.
98 * In order to imporve the performance, the XDR which is used to
99 * allocate dummy_page_va is the nearest the spider-pci.
100 * We have to select the CBE which is the nearest the spider-pci
101 * to allocate memory from the best XDR, but I don't know that
102 * how to do.
103 *
104 * Celleb does not have this problem, because it has only one XDR.
105 */
106 dummy_page_va = kmalloc(PAGE_SIZE, GFP_KERNEL);
107 if (!dummy_page_va) {
108 pr_err("SPIDERPCI-IOWA:Alloc dummy_page_va failed.\n");
109 return -1;
110 }
111
112 dummy_page_da = dma_map_single(phb->parent, dummy_page_va,
113 PAGE_SIZE, DMA_FROM_DEVICE);
114 if (dma_mapping_error(dummy_page_da)) {
115 pr_err("SPIDER-IOWA:Map dummy page filed.\n");
116 kfree(dummy_page_va);
117 return -1;
118 }
119
120 out_be32(regs + SPIDER_PCI_DUMMY_READ_BASE, dummy_page_da);
121
122 return 0;
123}
124
125int __init spiderpci_iowa_init(struct iowa_bus *bus, void *data)
126{
127 void __iomem *regs = NULL;
128 struct spiderpci_iowa_private *priv;
129 struct device_node *np = bus->phb->dn;
130 struct resource r;
131 unsigned long offset = (unsigned long)data;
132
133 pr_debug("SPIDERPCI-IOWA:Bus initialize for spider(%s)\n",
134 np->full_name);
135
136 priv = kzalloc(sizeof(struct spiderpci_iowa_private), GFP_KERNEL);
137 if (!priv) {
138 pr_err("SPIDERPCI-IOWA:"
139 "Can't allocate struct spiderpci_iowa_private");
140 return -1;
141 }
142
143 if (of_address_to_resource(np, 0, &r)) {
144 pr_err("SPIDERPCI-IOWA:Can't get resource.\n");
145 goto error;
146 }
147
148 regs = ioremap(r.start + offset, SPIDER_PCI_REG_SIZE);
149 if (!regs) {
150 pr_err("SPIDERPCI-IOWA:ioremap failed.\n");
151 goto error;
152 }
153 priv->regs = regs;
154 bus->private = priv;
155
156 if (spiderpci_pci_setup_chip(bus->phb, regs))
157 goto error;
158
159 return 0;
160
161error:
162 kfree(priv);
163 bus->private = NULL;
164
165 if (regs)
166 iounmap(regs);
167
168 return -1;
169}
170
171struct ppc_pci_io spiderpci_ops = {
172 .readb = spiderpci_readb,
173 .readw = spiderpci_readw,
174 .readl = spiderpci_readl,
175 .readq = spiderpci_readq,
176 .readw_be = spiderpci_readw_be,
177 .readl_be = spiderpci_readl_be,
178 .readq_be = spiderpci_readq_be,
179 .readsb = spiderpci_readsb,
180 .readsw = spiderpci_readsw,
181 .readsl = spiderpci_readsl,
182 .memcpy_fromio = spiderpci_memcpy_fromio,
183};
184
diff --git a/arch/powerpc/platforms/celleb/Kconfig b/arch/powerpc/platforms/celleb/Kconfig
deleted file mode 100644
index 372891edcdd2..000000000000
--- a/arch/powerpc/platforms/celleb/Kconfig
+++ /dev/null
@@ -1,12 +0,0 @@
1config PPC_CELLEB
2 bool "Toshiba's Cell Reference Set 'Celleb' Architecture"
3 depends on PPC_MULTIPLATFORM && PPC64
4 select PPC_CELL
5 select PPC_CELL_NATIVE
6 select PPC_RTAS
7 select PPC_INDIRECT_IO
8 select PPC_OF_PLATFORM_PCI
9 select HAS_TXX9_SERIAL
10 select PPC_UDBG_BEAT
11 select USB_OHCI_BIG_ENDIAN_MMIO
12 select USB_EHCI_BIG_ENDIAN_MMIO
diff --git a/arch/powerpc/platforms/celleb/Makefile b/arch/powerpc/platforms/celleb/Makefile
deleted file mode 100644
index 889d43f715ea..000000000000
--- a/arch/powerpc/platforms/celleb/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
1obj-y += interrupt.o iommu.o setup.o \
2 htab.o beat.o hvCall.o pci.o \
3 scc_epci.o scc_uhc.o \
4 io-workarounds.o
5
6obj-$(CONFIG_SMP) += smp.o
7obj-$(CONFIG_PPC_UDBG_BEAT) += udbg_beat.o
8obj-$(CONFIG_SERIAL_TXX9) += scc_sio.o
9obj-$(CONFIG_SPU_BASE) += spu_priv1.o
diff --git a/arch/powerpc/platforms/celleb/io-workarounds.c b/arch/powerpc/platforms/celleb/io-workarounds.c
deleted file mode 100644
index 423339be1bac..000000000000
--- a/arch/powerpc/platforms/celleb/io-workarounds.c
+++ /dev/null
@@ -1,280 +0,0 @@
1/*
2 * Support for Celleb io workarounds
3 *
4 * (C) Copyright 2006-2007 TOSHIBA CORPORATION
5 *
6 * This file is based to arch/powerpc/platform/cell/io-workarounds.c
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
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
22
23#undef DEBUG
24
25#include <linux/of.h>
26#include <linux/of_device.h>
27#include <linux/irq.h>
28
29#include <asm/io.h>
30#include <asm/prom.h>
31#include <asm/machdep.h>
32#include <asm/pci-bridge.h>
33#include <asm/ppc-pci.h>
34
35#include "pci.h"
36
37#define MAX_CELLEB_PCI_BUS 4
38
39void *celleb_dummy_page_va;
40
41static struct celleb_pci_bus {
42 struct pci_controller *phb;
43 void (*dummy_read)(struct pci_controller *);
44} celleb_pci_busses[MAX_CELLEB_PCI_BUS];
45
46static int celleb_pci_count = 0;
47
48static struct celleb_pci_bus *celleb_pci_find(unsigned long vaddr,
49 unsigned long paddr)
50{
51 int i, j;
52 struct resource *res;
53
54 for (i = 0; i < celleb_pci_count; i++) {
55 struct celleb_pci_bus *bus = &celleb_pci_busses[i];
56 struct pci_controller *phb = bus->phb;
57 if (paddr)
58 for (j = 0; j < 3; j++) {
59 res = &phb->mem_resources[j];
60 if (paddr >= res->start && paddr <= res->end)
61 return bus;
62 }
63 res = &phb->io_resource;
64 if (vaddr && vaddr >= res->start && vaddr <= res->end)
65 return bus;
66 }
67 return NULL;
68}
69
70static void celleb_io_flush(const PCI_IO_ADDR addr)
71{
72 struct celleb_pci_bus *bus;
73 int token;
74
75 token = PCI_GET_ADDR_TOKEN(addr);
76
77 if (token && token <= celleb_pci_count)
78 bus = &celleb_pci_busses[token - 1];
79 else {
80 unsigned long vaddr, paddr;
81 pte_t *ptep;
82
83 vaddr = (unsigned long)PCI_FIX_ADDR(addr);
84 if (vaddr < PHB_IO_BASE || vaddr >= PHB_IO_END)
85 return;
86
87 ptep = find_linux_pte(init_mm.pgd, vaddr);
88 if (ptep == NULL)
89 paddr = 0;
90 else
91 paddr = pte_pfn(*ptep) << PAGE_SHIFT;
92 bus = celleb_pci_find(vaddr, paddr);
93
94 if (bus == NULL)
95 return;
96 }
97
98 if (bus->dummy_read)
99 bus->dummy_read(bus->phb);
100}
101
102static u8 celleb_readb(const PCI_IO_ADDR addr)
103{
104 u8 val;
105 val = __do_readb(addr);
106 celleb_io_flush(addr);
107 return val;
108}
109
110static u16 celleb_readw(const PCI_IO_ADDR addr)
111{
112 u16 val;
113 val = __do_readw(addr);
114 celleb_io_flush(addr);
115 return val;
116}
117
118static u32 celleb_readl(const PCI_IO_ADDR addr)
119{
120 u32 val;
121 val = __do_readl(addr);
122 celleb_io_flush(addr);
123 return val;
124}
125
126static u64 celleb_readq(const PCI_IO_ADDR addr)
127{
128 u64 val;
129 val = __do_readq(addr);
130 celleb_io_flush(addr);
131 return val;
132}
133
134static u16 celleb_readw_be(const PCI_IO_ADDR addr)
135{
136 u16 val;
137 val = __do_readw_be(addr);
138 celleb_io_flush(addr);
139 return val;
140}
141
142static u32 celleb_readl_be(const PCI_IO_ADDR addr)
143{
144 u32 val;
145 val = __do_readl_be(addr);
146 celleb_io_flush(addr);
147 return val;
148}
149
150static u64 celleb_readq_be(const PCI_IO_ADDR addr)
151{
152 u64 val;
153 val = __do_readq_be(addr);
154 celleb_io_flush(addr);
155 return val;
156}
157
158static void celleb_readsb(const PCI_IO_ADDR addr,
159 void *buf, unsigned long count)
160{
161 __do_readsb(addr, buf, count);
162 celleb_io_flush(addr);
163}
164
165static void celleb_readsw(const PCI_IO_ADDR addr,
166 void *buf, unsigned long count)
167{
168 __do_readsw(addr, buf, count);
169 celleb_io_flush(addr);
170}
171
172static void celleb_readsl(const PCI_IO_ADDR addr,
173 void *buf, unsigned long count)
174{
175 __do_readsl(addr, buf, count);
176 celleb_io_flush(addr);
177}
178
179static void celleb_memcpy_fromio(void *dest,
180 const PCI_IO_ADDR src,
181 unsigned long n)
182{
183 __do_memcpy_fromio(dest, src, n);
184 celleb_io_flush(src);
185}
186
187static void __iomem *celleb_ioremap(unsigned long addr,
188 unsigned long size,
189 unsigned long flags)
190{
191 struct celleb_pci_bus *bus;
192 void __iomem *res = __ioremap(addr, size, flags);
193 int busno;
194
195 bus = celleb_pci_find(0, addr);
196 if (bus != NULL) {
197 busno = bus - celleb_pci_busses;
198 PCI_SET_ADDR_TOKEN(res, busno + 1);
199 }
200 return res;
201}
202
203static void celleb_iounmap(volatile void __iomem *addr)
204{
205 return __iounmap(PCI_FIX_ADDR(addr));
206}
207
208static struct ppc_pci_io celleb_pci_io __initdata = {
209 .readb = celleb_readb,
210 .readw = celleb_readw,
211 .readl = celleb_readl,
212 .readq = celleb_readq,
213 .readw_be = celleb_readw_be,
214 .readl_be = celleb_readl_be,
215 .readq_be = celleb_readq_be,
216 .readsb = celleb_readsb,
217 .readsw = celleb_readsw,
218 .readsl = celleb_readsl,
219 .memcpy_fromio = celleb_memcpy_fromio,
220};
221
222void __init celleb_pci_add_one(struct pci_controller *phb,
223 void (*dummy_read)(struct pci_controller *))
224{
225 struct celleb_pci_bus *bus = &celleb_pci_busses[celleb_pci_count];
226 struct device_node *np = phb->dn;
227
228 if (celleb_pci_count >= MAX_CELLEB_PCI_BUS) {
229 printk(KERN_ERR "Too many pci bridges, workarounds"
230 " disabled for %s\n", np->full_name);
231 return;
232 }
233
234 celleb_pci_count++;
235
236 bus->phb = phb;
237 bus->dummy_read = dummy_read;
238}
239
240static struct of_device_id celleb_pci_workaround_match[] __initdata = {
241 {
242 .name = "pci-pseudo",
243 .data = fake_pci_workaround_init,
244 }, {
245 .name = "epci",
246 .data = epci_workaround_init,
247 }, {
248 },
249};
250
251int __init celleb_pci_workaround_init(void)
252{
253 struct pci_controller *phb;
254 struct device_node *node;
255 const struct of_device_id *match;
256 void (*init_func)(struct pci_controller *);
257
258 celleb_dummy_page_va = kmalloc(PAGE_SIZE, GFP_KERNEL);
259 if (!celleb_dummy_page_va) {
260 printk(KERN_ERR "Celleb: dummy read disabled. "
261 "Alloc celleb_dummy_page_va failed\n");
262 return 1;
263 }
264
265 list_for_each_entry(phb, &hose_list, list_node) {
266 node = phb->dn;
267 match = of_match_node(celleb_pci_workaround_match, node);
268
269 if (match) {
270 init_func = match->data;
271 (*init_func)(phb);
272 }
273 }
274
275 ppc_pci_io = celleb_pci_io;
276 ppc_md.ioremap = celleb_ioremap;
277 ppc_md.iounmap = celleb_iounmap;
278
279 return 0;
280}
diff --git a/arch/powerpc/platforms/iseries/exception.S b/arch/powerpc/platforms/iseries/exception.S
index c775cd4b3d6e..8ff330d026ca 100644
--- a/arch/powerpc/platforms/iseries/exception.S
+++ b/arch/powerpc/platforms/iseries/exception.S
@@ -59,8 +59,33 @@ system_reset_iSeries:
59 andc r4,r4,r5 59 andc r4,r4,r5
60 mtspr SPRN_CTRLT,r4 60 mtspr SPRN_CTRLT,r4
61 61
62/* Spin on __secondary_hold_spinloop until it is updated by the boot cpu. */
63/* In the UP case we'll yeild() later, and we will not access the paca anyway */
64#ifdef CONFIG_SMP
621: 651:
63 HMT_LOW 66 HMT_LOW
67 LOAD_REG_IMMEDIATE(r23, __secondary_hold_spinloop)
68 ld r23,0(r23)
69 sync
70 LOAD_REG_IMMEDIATE(r3,current_set)
71 sldi r28,r24,3 /* get current_set[cpu#] */
72 ldx r3,r3,r28
73 addi r1,r3,THREAD_SIZE
74 subi r1,r1,STACK_FRAME_OVERHEAD
75
76 cmpwi 0,r23,0 /* Keep poking the Hypervisor until */
77 bne 2f /* we're released */
78 /* Let the Hypervisor know we are alive */
79 /* 8002 is a call to HvCallCfg::getLps, a harmless Hypervisor function */
80 lis r3,0x8002
81 rldicr r3,r3,32,15 /* r0 = (r3 << 32) & 0xffff000000000000 */
82 li r0,-1 /* r0=-1 indicates a Hypervisor call */
83 sc /* Invoke the hypervisor via a system call */
84 b 1b
85#endif
86
872:
88 HMT_LOW
64#ifdef CONFIG_SMP 89#ifdef CONFIG_SMP
65 lbz r23,PACAPROCSTART(r13) /* Test if this processor 90 lbz r23,PACAPROCSTART(r13) /* Test if this processor
66 * should start */ 91 * should start */
@@ -91,7 +116,7 @@ iSeries_secondary_smp_loop:
91 li r0,-1 /* r0=-1 indicates a Hypervisor call */ 116 li r0,-1 /* r0=-1 indicates a Hypervisor call */
92 sc /* Invoke the hypervisor via a system call */ 117 sc /* Invoke the hypervisor via a system call */
93 mfspr r13,SPRN_SPRG3 /* Put r13 back ???? */ 118 mfspr r13,SPRN_SPRG3 /* Put r13 back ???? */
94 b 1b /* If SMP not configured, secondaries 119 b 2b /* If SMP not configured, secondaries
95 * loop forever */ 120 * loop forever */
96 121
97/*** ISeries-LPAR interrupt handlers ***/ 122/*** ISeries-LPAR interrupt handlers ***/
diff --git a/arch/powerpc/platforms/ps3/os-area.c b/arch/powerpc/platforms/ps3/os-area.c
index c73379ec9141..1d201782d4e5 100644
--- a/arch/powerpc/platforms/ps3/os-area.c
+++ b/arch/powerpc/platforms/ps3/os-area.c
@@ -25,6 +25,7 @@
25#include <linux/syscalls.h> 25#include <linux/syscalls.h>
26#include <linux/ctype.h> 26#include <linux/ctype.h>
27#include <linux/lmb.h> 27#include <linux/lmb.h>
28#include <linux/of.h>
28 29
29#include <asm/prom.h> 30#include <asm/prom.h>
30 31
diff --git a/arch/powerpc/platforms/pseries/Kconfig b/arch/powerpc/platforms/pseries/Kconfig
index 306a9d07491d..07fe5b69b9e2 100644
--- a/arch/powerpc/platforms/pseries/Kconfig
+++ b/arch/powerpc/platforms/pseries/Kconfig
@@ -34,3 +34,8 @@ config LPARCFG
34 help 34 help
35 Provide system capacity information via human readable 35 Provide system capacity information via human readable
36 <key word>=<value> pairs through a /proc/ppc64/lparcfg interface. 36 <key word>=<value> pairs through a /proc/ppc64/lparcfg interface.
37
38config PPC_PSERIES_DEBUG
39 depends on PPC_PSERIES && PPC_EARLY_DEBUG
40 bool "Enable extra debug logging in platforms/pseries"
41 default y
diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile
index bdae04bb7a01..bd2593ed28dd 100644
--- a/arch/powerpc/platforms/pseries/Makefile
+++ b/arch/powerpc/platforms/pseries/Makefile
@@ -2,6 +2,10 @@ ifeq ($(CONFIG_PPC64),y)
2EXTRA_CFLAGS += -mno-minimal-toc 2EXTRA_CFLAGS += -mno-minimal-toc
3endif 3endif
4 4
5ifeq ($(CONFIG_PPC_PSERIES_DEBUG),y)
6EXTRA_CFLAGS += -DDEBUG
7endif
8
5obj-y := lpar.o hvCall.o nvram.o reconfig.o \ 9obj-y := lpar.o hvCall.o nvram.o reconfig.o \
6 setup.o iommu.o ras.o rtasd.o \ 10 setup.o iommu.o ras.o rtasd.o \
7 firmware.o power.o 11 firmware.o power.o
diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c
index 550b2f7d2cc1..a3fd56b186e6 100644
--- a/arch/powerpc/platforms/pseries/eeh.c
+++ b/arch/powerpc/platforms/pseries/eeh.c
@@ -39,7 +39,6 @@
39#include <asm/ppc-pci.h> 39#include <asm/ppc-pci.h>
40#include <asm/rtas.h> 40#include <asm/rtas.h>
41 41
42#undef DEBUG
43 42
44/** Overview: 43/** Overview:
45 * EEH, or "Extended Error Handling" is a PCI bridge technology for 44 * EEH, or "Extended Error Handling" is a PCI bridge technology for
diff --git a/arch/powerpc/platforms/pseries/eeh_cache.c b/arch/powerpc/platforms/pseries/eeh_cache.c
index 1e83fcd0df31..ce37040af870 100644
--- a/arch/powerpc/platforms/pseries/eeh_cache.c
+++ b/arch/powerpc/platforms/pseries/eeh_cache.c
@@ -28,7 +28,6 @@
28#include <asm/pci-bridge.h> 28#include <asm/pci-bridge.h>
29#include <asm/ppc-pci.h> 29#include <asm/ppc-pci.h>
30 30
31#undef DEBUG
32 31
33/** 32/**
34 * The pci address cache subsystem. This subsystem places 33 * The pci address cache subsystem. This subsystem places
diff --git a/arch/powerpc/platforms/pseries/firmware.c b/arch/powerpc/platforms/pseries/firmware.c
index b765b7c77b65..9d3a40f45974 100644
--- a/arch/powerpc/platforms/pseries/firmware.c
+++ b/arch/powerpc/platforms/pseries/firmware.c
@@ -21,17 +21,11 @@
21 * 2 of the License, or (at your option) any later version. 21 * 2 of the License, or (at your option) any later version.
22 */ 22 */
23 23
24#undef DEBUG
25 24
26#include <asm/firmware.h> 25#include <asm/firmware.h>
27#include <asm/prom.h> 26#include <asm/prom.h>
28#include <asm/udbg.h> 27#include <asm/udbg.h>
29 28
30#ifdef DEBUG
31#define DBG(fmt...) udbg_printf(fmt)
32#else
33#define DBG(fmt...)
34#endif
35 29
36typedef struct { 30typedef struct {
37 unsigned long val; 31 unsigned long val;
@@ -72,7 +66,7 @@ void __init fw_feature_init(const char *hypertas, unsigned long len)
72 const char *s; 66 const char *s;
73 int i; 67 int i;
74 68
75 DBG(" -> fw_feature_init()\n"); 69 pr_debug(" -> fw_feature_init()\n");
76 70
77 for (s = hypertas; s < hypertas + len; s += strlen(s) + 1) { 71 for (s = hypertas; s < hypertas + len; s += strlen(s) + 1) {
78 for (i = 0; i < FIRMWARE_MAX_FEATURES; i++) { 72 for (i = 0; i < FIRMWARE_MAX_FEATURES; i++) {
@@ -88,5 +82,5 @@ void __init fw_feature_init(const char *hypertas, unsigned long len)
88 } 82 }
89 } 83 }
90 84
91 DBG(" <- fw_feature_init()\n"); 85 pr_debug(" <- fw_feature_init()\n");
92} 86}
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index a65c76308201..176f1f39d2d5 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -47,7 +47,6 @@
47 47
48#include "plpar_wrappers.h" 48#include "plpar_wrappers.h"
49 49
50#define DBG(fmt...)
51 50
52static void tce_build_pSeries(struct iommu_table *tbl, long index, 51static void tce_build_pSeries(struct iommu_table *tbl, long index,
53 long npages, unsigned long uaddr, 52 long npages, unsigned long uaddr,
@@ -322,7 +321,7 @@ static void pci_dma_bus_setup_pSeries(struct pci_bus *bus)
322 321
323 dn = pci_bus_to_OF_node(bus); 322 dn = pci_bus_to_OF_node(bus);
324 323
325 DBG("pci_dma_bus_setup_pSeries: setting up bus %s\n", dn->full_name); 324 pr_debug("pci_dma_bus_setup_pSeries: setting up bus %s\n", dn->full_name);
326 325
327 if (bus->self) { 326 if (bus->self) {
328 /* This is not a root bus, any setup will be done for the 327 /* This is not a root bus, any setup will be done for the
@@ -347,7 +346,7 @@ static void pci_dma_bus_setup_pSeries(struct pci_bus *bus)
347 for (children = 0, tmp = dn->child; tmp; tmp = tmp->sibling) 346 for (children = 0, tmp = dn->child; tmp; tmp = tmp->sibling)
348 children++; 347 children++;
349 348
350 DBG("Children: %d\n", children); 349 pr_debug("Children: %d\n", children);
351 350
352 /* Calculate amount of DMA window per slot. Each window must be 351 /* Calculate amount of DMA window per slot. Each window must be
353 * a power of two (due to pci_alloc_consistent requirements). 352 * a power of two (due to pci_alloc_consistent requirements).
@@ -361,8 +360,8 @@ static void pci_dma_bus_setup_pSeries(struct pci_bus *bus)
361 360
362 while (pci->phb->dma_window_size * children > 0x80000000ul) 361 while (pci->phb->dma_window_size * children > 0x80000000ul)
363 pci->phb->dma_window_size >>= 1; 362 pci->phb->dma_window_size >>= 1;
364 DBG("No ISA/IDE, window size is 0x%lx\n", 363 pr_debug("No ISA/IDE, window size is 0x%lx\n",
365 pci->phb->dma_window_size); 364 pci->phb->dma_window_size);
366 pci->phb->dma_window_base_cur = 0; 365 pci->phb->dma_window_base_cur = 0;
367 366
368 return; 367 return;
@@ -387,8 +386,7 @@ static void pci_dma_bus_setup_pSeries(struct pci_bus *bus)
387 while (pci->phb->dma_window_size * children > 0x70000000ul) 386 while (pci->phb->dma_window_size * children > 0x70000000ul)
388 pci->phb->dma_window_size >>= 1; 387 pci->phb->dma_window_size >>= 1;
389 388
390 DBG("ISA/IDE, window size is 0x%lx\n", pci->phb->dma_window_size); 389 pr_debug("ISA/IDE, window size is 0x%lx\n", pci->phb->dma_window_size);
391
392} 390}
393 391
394 392
@@ -401,7 +399,8 @@ static void pci_dma_bus_setup_pSeriesLP(struct pci_bus *bus)
401 399
402 dn = pci_bus_to_OF_node(bus); 400 dn = pci_bus_to_OF_node(bus);
403 401
404 DBG("pci_dma_bus_setup_pSeriesLP: setting up bus %s\n", dn->full_name); 402 pr_debug("pci_dma_bus_setup_pSeriesLP: setting up bus %s\n",
403 dn->full_name);
405 404
406 /* Find nearest ibm,dma-window, walking up the device tree */ 405 /* Find nearest ibm,dma-window, walking up the device tree */
407 for (pdn = dn; pdn != NULL; pdn = pdn->parent) { 406 for (pdn = dn; pdn != NULL; pdn = pdn->parent) {
@@ -411,14 +410,14 @@ static void pci_dma_bus_setup_pSeriesLP(struct pci_bus *bus)
411 } 410 }
412 411
413 if (dma_window == NULL) { 412 if (dma_window == NULL) {
414 DBG(" no ibm,dma-window property !\n"); 413 pr_debug(" no ibm,dma-window property !\n");
415 return; 414 return;
416 } 415 }
417 416
418 ppci = PCI_DN(pdn); 417 ppci = PCI_DN(pdn);
419 418
420 DBG(" parent is %s, iommu_table: 0x%p\n", 419 pr_debug(" parent is %s, iommu_table: 0x%p\n",
421 pdn->full_name, ppci->iommu_table); 420 pdn->full_name, ppci->iommu_table);
422 421
423 if (!ppci->iommu_table) { 422 if (!ppci->iommu_table) {
424 tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL, 423 tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL,
@@ -426,7 +425,7 @@ static void pci_dma_bus_setup_pSeriesLP(struct pci_bus *bus)
426 iommu_table_setparms_lpar(ppci->phb, pdn, tbl, dma_window, 425 iommu_table_setparms_lpar(ppci->phb, pdn, tbl, dma_window,
427 bus->number); 426 bus->number);
428 ppci->iommu_table = iommu_init_table(tbl, ppci->phb->node); 427 ppci->iommu_table = iommu_init_table(tbl, ppci->phb->node);
429 DBG(" created table: %p\n", ppci->iommu_table); 428 pr_debug(" created table: %p\n", ppci->iommu_table);
430 } 429 }
431 430
432 if (pdn != dn) 431 if (pdn != dn)
@@ -439,7 +438,7 @@ static void pci_dma_dev_setup_pSeries(struct pci_dev *dev)
439 struct device_node *dn; 438 struct device_node *dn;
440 struct iommu_table *tbl; 439 struct iommu_table *tbl;
441 440
442 DBG("pci_dma_dev_setup_pSeries: %s\n", pci_name(dev)); 441 pr_debug("pci_dma_dev_setup_pSeries: %s\n", pci_name(dev));
443 442
444 dn = dev->dev.archdata.of_node; 443 dn = dev->dev.archdata.of_node;
445 444
@@ -450,7 +449,7 @@ static void pci_dma_dev_setup_pSeries(struct pci_dev *dev)
450 if (!dev->bus->self) { 449 if (!dev->bus->self) {
451 struct pci_controller *phb = PCI_DN(dn)->phb; 450 struct pci_controller *phb = PCI_DN(dn)->phb;
452 451
453 DBG(" --> first child, no bridge. Allocating iommu table.\n"); 452 pr_debug(" --> first child, no bridge. Allocating iommu table.\n");
454 tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL, 453 tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL,
455 phb->node); 454 phb->node);
456 iommu_table_setparms(phb, dn, tbl); 455 iommu_table_setparms(phb, dn, tbl);
@@ -480,7 +479,7 @@ static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev)
480 const void *dma_window = NULL; 479 const void *dma_window = NULL;
481 struct pci_dn *pci; 480 struct pci_dn *pci;
482 481
483 DBG("pci_dma_dev_setup_pSeriesLP: %s\n", pci_name(dev)); 482 pr_debug("pci_dma_dev_setup_pSeriesLP: %s\n", pci_name(dev));
484 483
485 /* dev setup for LPAR is a little tricky, since the device tree might 484 /* dev setup for LPAR is a little tricky, since the device tree might
486 * contain the dma-window properties per-device and not neccesarily 485 * contain the dma-window properties per-device and not neccesarily
@@ -489,7 +488,7 @@ static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev)
489 * already allocated. 488 * already allocated.
490 */ 489 */
491 dn = pci_device_to_OF_node(dev); 490 dn = pci_device_to_OF_node(dev);
492 DBG(" node is %s\n", dn->full_name); 491 pr_debug(" node is %s\n", dn->full_name);
493 492
494 for (pdn = dn; pdn && PCI_DN(pdn) && !PCI_DN(pdn)->iommu_table; 493 for (pdn = dn; pdn && PCI_DN(pdn) && !PCI_DN(pdn)->iommu_table;
495 pdn = pdn->parent) { 494 pdn = pdn->parent) {
@@ -504,13 +503,13 @@ static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev)
504 pci_name(dev), dn? dn->full_name : "<null>"); 503 pci_name(dev), dn? dn->full_name : "<null>");
505 return; 504 return;
506 } 505 }
507 DBG(" parent is %s\n", pdn->full_name); 506 pr_debug(" parent is %s\n", pdn->full_name);
508 507
509 /* Check for parent == NULL so we don't try to setup the empty EADS 508 /* Check for parent == NULL so we don't try to setup the empty EADS
510 * slots on POWER4 machines. 509 * slots on POWER4 machines.
511 */ 510 */
512 if (dma_window == NULL || pdn->parent == NULL) { 511 if (dma_window == NULL || pdn->parent == NULL) {
513 DBG(" no dma window for device, linking to parent\n"); 512 pr_debug(" no dma window for device, linking to parent\n");
514 dev->dev.archdata.dma_data = PCI_DN(pdn)->iommu_table; 513 dev->dev.archdata.dma_data = PCI_DN(pdn)->iommu_table;
515 return; 514 return;
516 } 515 }
@@ -522,9 +521,9 @@ static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev)
522 iommu_table_setparms_lpar(pci->phb, pdn, tbl, dma_window, 521 iommu_table_setparms_lpar(pci->phb, pdn, tbl, dma_window,
523 pci->phb->bus->number); 522 pci->phb->bus->number);
524 pci->iommu_table = iommu_init_table(tbl, pci->phb->node); 523 pci->iommu_table = iommu_init_table(tbl, pci->phb->node);
525 DBG(" created table: %p\n", pci->iommu_table); 524 pr_debug(" created table: %p\n", pci->iommu_table);
526 } else { 525 } else {
527 DBG(" found DMA window, table: %p\n", pci->iommu_table); 526 pr_debug(" found DMA window, table: %p\n", pci->iommu_table);
528 } 527 }
529 528
530 dev->dev.archdata.dma_data = pci->iommu_table; 529 dev->dev.archdata.dma_data = pci->iommu_table;
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
index 9235c469449e..2cbaedb17f3e 100644
--- a/arch/powerpc/platforms/pseries/lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -19,7 +19,8 @@
19 * 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 */ 20 */
21 21
22#undef DEBUG_LOW 22/* Enables debugging of low-level hash table routines - careful! */
23#undef DEBUG
23 24
24#include <linux/kernel.h> 25#include <linux/kernel.h>
25#include <linux/dma-mapping.h> 26#include <linux/dma-mapping.h>
@@ -42,11 +43,6 @@
42#include "plpar_wrappers.h" 43#include "plpar_wrappers.h"
43#include "pseries.h" 44#include "pseries.h"
44 45
45#ifdef DEBUG_LOW
46#define DBG_LOW(fmt...) do { udbg_printf(fmt); } while(0)
47#else
48#define DBG_LOW(fmt...) do { } while(0)
49#endif
50 46
51/* in hvCall.S */ 47/* in hvCall.S */
52EXPORT_SYMBOL(plpar_hcall); 48EXPORT_SYMBOL(plpar_hcall);
@@ -196,6 +192,8 @@ void __init udbg_init_debug_lpar(void)
196 udbg_putc = udbg_putcLP; 192 udbg_putc = udbg_putcLP;
197 udbg_getc = udbg_getcLP; 193 udbg_getc = udbg_getcLP;
198 udbg_getc_poll = udbg_getc_pollLP; 194 udbg_getc_poll = udbg_getc_pollLP;
195
196 register_early_udbg_console();
199} 197}
200 198
201/* returns 0 if couldn't find or use /chosen/stdout as console */ 199/* returns 0 if couldn't find or use /chosen/stdout as console */
@@ -288,15 +286,15 @@ static long pSeries_lpar_hpte_insert(unsigned long hpte_group,
288 unsigned long hpte_v, hpte_r; 286 unsigned long hpte_v, hpte_r;
289 287
290 if (!(vflags & HPTE_V_BOLTED)) 288 if (!(vflags & HPTE_V_BOLTED))
291 DBG_LOW("hpte_insert(group=%lx, va=%016lx, pa=%016lx, " 289 pr_debug("hpte_insert(group=%lx, va=%016lx, pa=%016lx, "
292 "rflags=%lx, vflags=%lx, psize=%d)\n", 290 "rflags=%lx, vflags=%lx, psize=%d)\n",
293 hpte_group, va, pa, rflags, vflags, psize); 291 hpte_group, va, pa, rflags, vflags, psize);
294 292
295 hpte_v = hpte_encode_v(va, psize, ssize) | vflags | HPTE_V_VALID; 293 hpte_v = hpte_encode_v(va, psize, ssize) | vflags | HPTE_V_VALID;
296 hpte_r = hpte_encode_r(pa, psize) | rflags; 294 hpte_r = hpte_encode_r(pa, psize) | rflags;
297 295
298 if (!(vflags & HPTE_V_BOLTED)) 296 if (!(vflags & HPTE_V_BOLTED))
299 DBG_LOW(" hpte_v=%016lx, hpte_r=%016lx\n", hpte_v, hpte_r); 297 pr_debug(" hpte_v=%016lx, hpte_r=%016lx\n", hpte_v, hpte_r);
300 298
301 /* Now fill in the actual HPTE */ 299 /* Now fill in the actual HPTE */
302 /* Set CEC cookie to 0 */ 300 /* Set CEC cookie to 0 */
@@ -313,7 +311,7 @@ static long pSeries_lpar_hpte_insert(unsigned long hpte_group,
313 lpar_rc = plpar_pte_enter(flags, hpte_group, hpte_v, hpte_r, &slot); 311 lpar_rc = plpar_pte_enter(flags, hpte_group, hpte_v, hpte_r, &slot);
314 if (unlikely(lpar_rc == H_PTEG_FULL)) { 312 if (unlikely(lpar_rc == H_PTEG_FULL)) {
315 if (!(vflags & HPTE_V_BOLTED)) 313 if (!(vflags & HPTE_V_BOLTED))
316 DBG_LOW(" full\n"); 314 pr_debug(" full\n");
317 return -1; 315 return -1;
318 } 316 }
319 317
@@ -324,11 +322,11 @@ static long pSeries_lpar_hpte_insert(unsigned long hpte_group,
324 */ 322 */
325 if (unlikely(lpar_rc != H_SUCCESS)) { 323 if (unlikely(lpar_rc != H_SUCCESS)) {
326 if (!(vflags & HPTE_V_BOLTED)) 324 if (!(vflags & HPTE_V_BOLTED))
327 DBG_LOW(" lpar err %d\n", lpar_rc); 325 pr_debug(" lpar err %lu\n", lpar_rc);
328 return -2; 326 return -2;
329 } 327 }
330 if (!(vflags & HPTE_V_BOLTED)) 328 if (!(vflags & HPTE_V_BOLTED))
331 DBG_LOW(" -> slot: %d\n", slot & 7); 329 pr_debug(" -> slot: %lu\n", slot & 7);
332 330
333 /* Because of iSeries, we have to pass down the secondary 331 /* Because of iSeries, we have to pass down the secondary
334 * bucket bit here as well 332 * bucket bit here as well
@@ -420,17 +418,17 @@ static long pSeries_lpar_hpte_updatepp(unsigned long slot,
420 418
421 want_v = hpte_encode_avpn(va, psize, ssize); 419 want_v = hpte_encode_avpn(va, psize, ssize);
422 420
423 DBG_LOW(" update: avpnv=%016lx, hash=%016lx, f=%x, psize: %d ... ", 421 pr_debug(" update: avpnv=%016lx, hash=%016lx, f=%lx, psize: %d ...",
424 want_v, slot, flags, psize); 422 want_v, slot, flags, psize);
425 423
426 lpar_rc = plpar_pte_protect(flags, slot, want_v); 424 lpar_rc = plpar_pte_protect(flags, slot, want_v);
427 425
428 if (lpar_rc == H_NOT_FOUND) { 426 if (lpar_rc == H_NOT_FOUND) {
429 DBG_LOW("not found !\n"); 427 pr_debug("not found !\n");
430 return -1; 428 return -1;
431 } 429 }
432 430
433 DBG_LOW("ok\n"); 431 pr_debug("ok\n");
434 432
435 BUG_ON(lpar_rc != H_SUCCESS); 433 BUG_ON(lpar_rc != H_SUCCESS);
436 434
@@ -505,8 +503,8 @@ static void pSeries_lpar_hpte_invalidate(unsigned long slot, unsigned long va,
505 unsigned long lpar_rc; 503 unsigned long lpar_rc;
506 unsigned long dummy1, dummy2; 504 unsigned long dummy1, dummy2;
507 505
508 DBG_LOW(" inval : slot=%lx, va=%016lx, psize: %d, local: %d", 506 pr_debug(" inval : slot=%lx, va=%016lx, psize: %d, local: %d\n",
509 slot, va, psize, local); 507 slot, va, psize, local);
510 508
511 want_v = hpte_encode_avpn(va, psize, ssize); 509 want_v = hpte_encode_avpn(va, psize, ssize);
512 lpar_rc = plpar_pte_remove(H_AVPN, slot, want_v, &dummy1, &dummy2); 510 lpar_rc = plpar_pte_remove(H_AVPN, slot, want_v, &dummy1, &dummy2);
diff --git a/arch/powerpc/platforms/pseries/ras.c b/arch/powerpc/platforms/pseries/ras.c
index a1ab25c7082f..2b548afd1003 100644
--- a/arch/powerpc/platforms/pseries/ras.c
+++ b/arch/powerpc/platforms/pseries/ras.c
@@ -67,8 +67,6 @@ static int ras_check_exception_token;
67static irqreturn_t ras_epow_interrupt(int irq, void *dev_id); 67static irqreturn_t ras_epow_interrupt(int irq, void *dev_id);
68static irqreturn_t ras_error_interrupt(int irq, void *dev_id); 68static irqreturn_t ras_error_interrupt(int irq, void *dev_id);
69 69
70/* #define DEBUG */
71
72 70
73static void request_ras_irqs(struct device_node *np, 71static void request_ras_irqs(struct device_node *np,
74 irq_handler_t handler, 72 irq_handler_t handler,
@@ -237,7 +235,7 @@ static irqreturn_t ras_error_interrupt(int irq, void *dev_id)
237 printk(KERN_EMERG "Error: Fatal hardware error <0x%lx 0x%x>\n", 235 printk(KERN_EMERG "Error: Fatal hardware error <0x%lx 0x%x>\n",
238 *((unsigned long *)&ras_log_buf), status); 236 *((unsigned long *)&ras_log_buf), status);
239 237
240#ifndef DEBUG 238#ifndef DEBUG_RTAS_POWER_OFF
241 /* Don't actually power off when debugging so we can test 239 /* Don't actually power off when debugging so we can test
242 * without actually failing while injecting errors. 240 * without actually failing while injecting errors.
243 * Error data will not be logged to syslog. 241 * Error data will not be logged to syslog.
diff --git a/arch/powerpc/platforms/pseries/rtasd.c b/arch/powerpc/platforms/pseries/rtasd.c
index e3078ce41518..befadd4f9524 100644
--- a/arch/powerpc/platforms/pseries/rtasd.c
+++ b/arch/powerpc/platforms/pseries/rtasd.c
@@ -29,11 +29,6 @@
29#include <asm/atomic.h> 29#include <asm/atomic.h>
30#include <asm/machdep.h> 30#include <asm/machdep.h>
31 31
32#if 0
33#define DEBUG(A...) printk(KERN_ERR A)
34#else
35#define DEBUG(A...)
36#endif
37 32
38static DEFINE_SPINLOCK(rtasd_log_lock); 33static DEFINE_SPINLOCK(rtasd_log_lock);
39 34
@@ -198,7 +193,7 @@ void pSeries_log_error(char *buf, unsigned int err_type, int fatal)
198 unsigned long s; 193 unsigned long s;
199 int len = 0; 194 int len = 0;
200 195
201 DEBUG("logging event\n"); 196 pr_debug("rtasd: logging event\n");
202 if (buf == NULL) 197 if (buf == NULL)
203 return; 198 return;
204 199
@@ -409,7 +404,8 @@ static int rtasd(void *unused)
409 daemonize("rtasd"); 404 daemonize("rtasd");
410 405
411 printk(KERN_DEBUG "RTAS daemon started\n"); 406 printk(KERN_DEBUG "RTAS daemon started\n");
412 DEBUG("will sleep for %d milliseconds\n", (30000/rtas_event_scan_rate)); 407 pr_debug("rtasd: will sleep for %d milliseconds\n",
408 (30000 / rtas_event_scan_rate));
413 409
414 /* See if we have any error stored in NVRAM */ 410 /* See if we have any error stored in NVRAM */
415 memset(logdata, 0, rtas_error_log_max); 411 memset(logdata, 0, rtas_error_log_max);
@@ -428,9 +424,9 @@ static int rtasd(void *unused)
428 do_event_scan_all_cpus(1000); 424 do_event_scan_all_cpus(1000);
429 425
430 if (surveillance_timeout != -1) { 426 if (surveillance_timeout != -1) {
431 DEBUG("enabling surveillance\n"); 427 pr_debug("rtasd: enabling surveillance\n");
432 enable_surveillance(surveillance_timeout); 428 enable_surveillance(surveillance_timeout);
433 DEBUG("surveillance enabled\n"); 429 pr_debug("rtasd: surveillance enabled\n");
434 } 430 }
435 431
436 /* Delay should be at least one second since some 432 /* Delay should be at least one second since some
diff --git a/arch/powerpc/platforms/pseries/scanlog.c b/arch/powerpc/platforms/pseries/scanlog.c
index e5b0ea870164..bec3803f0618 100644
--- a/arch/powerpc/platforms/pseries/scanlog.c
+++ b/arch/powerpc/platforms/pseries/scanlog.c
@@ -38,9 +38,7 @@
38#define SCANLOG_HWERROR -1 38#define SCANLOG_HWERROR -1
39#define SCANLOG_CONTINUE 1 39#define SCANLOG_CONTINUE 1
40 40
41#define DEBUG(A...) do { if (scanlog_debug) printk(KERN_ERR "scanlog: " A); } while (0)
42 41
43static int scanlog_debug;
44static unsigned int ibm_scan_log_dump; /* RTAS token */ 42static unsigned int ibm_scan_log_dump; /* RTAS token */
45static struct proc_dir_entry *proc_ppc64_scan_log_dump; /* The proc file */ 43static struct proc_dir_entry *proc_ppc64_scan_log_dump; /* The proc file */
46 44
@@ -86,14 +84,14 @@ static ssize_t scanlog_read(struct file *file, char __user *buf,
86 memcpy(data, rtas_data_buf, RTAS_DATA_BUF_SIZE); 84 memcpy(data, rtas_data_buf, RTAS_DATA_BUF_SIZE);
87 spin_unlock(&rtas_data_buf_lock); 85 spin_unlock(&rtas_data_buf_lock);
88 86
89 DEBUG("status=%d, data[0]=%x, data[1]=%x, data[2]=%x\n", 87 pr_debug("scanlog: status=%d, data[0]=%x, data[1]=%x, " \
90 status, data[0], data[1], data[2]); 88 "data[2]=%x\n", status, data[0], data[1], data[2]);
91 switch (status) { 89 switch (status) {
92 case SCANLOG_COMPLETE: 90 case SCANLOG_COMPLETE:
93 DEBUG("hit eof\n"); 91 pr_debug("scanlog: hit eof\n");
94 return 0; 92 return 0;
95 case SCANLOG_HWERROR: 93 case SCANLOG_HWERROR:
96 DEBUG("hardware error reading scan log data\n"); 94 pr_debug("scanlog: hardware error reading data\n");
97 return -EIO; 95 return -EIO;
98 case SCANLOG_CONTINUE: 96 case SCANLOG_CONTINUE:
99 /* We may or may not have data yet */ 97 /* We may or may not have data yet */
@@ -110,7 +108,8 @@ static ssize_t scanlog_read(struct file *file, char __user *buf,
110 /* Assume extended busy */ 108 /* Assume extended busy */
111 wait_time = rtas_busy_delay_time(status); 109 wait_time = rtas_busy_delay_time(status);
112 if (!wait_time) { 110 if (!wait_time) {
113 printk(KERN_ERR "scanlog: unknown error from rtas: %d\n", status); 111 printk(KERN_ERR "scanlog: unknown error " \
112 "from rtas: %d\n", status);
114 return -EIO; 113 return -EIO;
115 } 114 }
116 } 115 }
@@ -134,15 +133,9 @@ static ssize_t scanlog_write(struct file * file, const char __user * buf,
134 133
135 if (buf) { 134 if (buf) {
136 if (strncmp(stkbuf, "reset", 5) == 0) { 135 if (strncmp(stkbuf, "reset", 5) == 0) {
137 DEBUG("reset scanlog\n"); 136 pr_debug("scanlog: reset scanlog\n");
138 status = rtas_call(ibm_scan_log_dump, 2, 1, NULL, 0, 0); 137 status = rtas_call(ibm_scan_log_dump, 2, 1, NULL, 0, 0);
139 DEBUG("rtas returns %d\n", status); 138 pr_debug("scanlog: rtas returns %d\n", status);
140 } else if (strncmp(stkbuf, "debugon", 7) == 0) {
141 printk(KERN_ERR "scanlog: debug on\n");
142 scanlog_debug = 1;
143 } else if (strncmp(stkbuf, "debugoff", 8) == 0) {
144 printk(KERN_ERR "scanlog: debug off\n");
145 scanlog_debug = 0;
146 } 139 }
147 } 140 }
148 return count; 141 return count;
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index f66aa9c3b135..f5d29f5b13c1 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -16,8 +16,6 @@
16 * bootup setup stuff.. 16 * bootup setup stuff..
17 */ 17 */
18 18
19#undef DEBUG
20
21#include <linux/cpu.h> 19#include <linux/cpu.h>
22#include <linux/errno.h> 20#include <linux/errno.h>
23#include <linux/sched.h> 21#include <linux/sched.h>
@@ -70,11 +68,6 @@
70#include "plpar_wrappers.h" 68#include "plpar_wrappers.h"
71#include "pseries.h" 69#include "pseries.h"
72 70
73#ifdef DEBUG
74#define DBG(fmt...) udbg_printf(fmt)
75#else
76#define DBG(fmt...)
77#endif
78 71
79int fwnmi_active; /* TRUE if an FWNMI handler is present */ 72int fwnmi_active; /* TRUE if an FWNMI handler is present */
80 73
@@ -326,7 +319,7 @@ static int pseries_set_xdabr(unsigned long dabr)
326 */ 319 */
327static void __init pSeries_init_early(void) 320static void __init pSeries_init_early(void)
328{ 321{
329 DBG(" -> pSeries_init_early()\n"); 322 pr_debug(" -> pSeries_init_early()\n");
330 323
331 if (firmware_has_feature(FW_FEATURE_LPAR)) 324 if (firmware_has_feature(FW_FEATURE_LPAR))
332 find_udbg_vterm(); 325 find_udbg_vterm();
@@ -338,7 +331,7 @@ static void __init pSeries_init_early(void)
338 331
339 iommu_init_early_pSeries(); 332 iommu_init_early_pSeries();
340 333
341 DBG(" <- pSeries_init_early()\n"); 334 pr_debug(" <- pSeries_init_early()\n");
342} 335}
343 336
344/* 337/*
@@ -383,7 +376,7 @@ static int __init pSeries_probe(void)
383 of_flat_dt_is_compatible(root, "IBM,CBEA")) 376 of_flat_dt_is_compatible(root, "IBM,CBEA"))
384 return 0; 377 return 0;
385 378
386 DBG("pSeries detected, looking for LPAR capability...\n"); 379 pr_debug("pSeries detected, looking for LPAR capability...\n");
387 380
388 /* Now try to figure out if we are running on LPAR */ 381 /* Now try to figure out if we are running on LPAR */
389 of_scan_flat_dt(pSeries_probe_hypertas, NULL); 382 of_scan_flat_dt(pSeries_probe_hypertas, NULL);
@@ -393,8 +386,8 @@ static int __init pSeries_probe(void)
393 else 386 else
394 hpte_init_native(); 387 hpte_init_native();
395 388
396 DBG("Machine is%s LPAR !\n", 389 pr_debug("Machine is%s LPAR !\n",
397 (powerpc_firmware_features & FW_FEATURE_LPAR) ? "" : " not"); 390 (powerpc_firmware_features & FW_FEATURE_LPAR) ? "" : " not");
398 391
399 return 1; 392 return 1;
400} 393}
diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c
index ea4c65917a64..9d8f8c84ab89 100644
--- a/arch/powerpc/platforms/pseries/smp.c
+++ b/arch/powerpc/platforms/pseries/smp.c
@@ -12,7 +12,6 @@
12 * 2 of the License, or (at your option) any later version. 12 * 2 of the License, or (at your option) any later version.
13 */ 13 */
14 14
15#undef DEBUG
16 15
17#include <linux/kernel.h> 16#include <linux/kernel.h>
18#include <linux/module.h> 17#include <linux/module.h>
@@ -51,12 +50,6 @@
51#include "plpar_wrappers.h" 50#include "plpar_wrappers.h"
52#include "pseries.h" 51#include "pseries.h"
53 52
54#ifdef DEBUG
55#include <asm/udbg.h>
56#define DBG(fmt...) udbg_printf(fmt)
57#else
58#define DBG(fmt...)
59#endif
60 53
61/* 54/*
62 * The primary thread of each non-boot processor is recorded here before 55 * The primary thread of each non-boot processor is recorded here before
@@ -231,7 +224,7 @@ static void __init smp_init_pseries(void)
231{ 224{
232 int i; 225 int i;
233 226
234 DBG(" -> smp_init_pSeries()\n"); 227 pr_debug(" -> smp_init_pSeries()\n");
235 228
236 /* Mark threads which are still spinning in hold loops. */ 229 /* Mark threads which are still spinning in hold loops. */
237 if (cpu_has_feature(CPU_FTR_SMT)) { 230 if (cpu_has_feature(CPU_FTR_SMT)) {
@@ -255,7 +248,7 @@ static void __init smp_init_pseries(void)
255 smp_ops->take_timebase = pSeries_take_timebase; 248 smp_ops->take_timebase = pSeries_take_timebase;
256 } 249 }
257 250
258 DBG(" <- smp_init_pSeries()\n"); 251 pr_debug(" <- smp_init_pSeries()\n");
259} 252}
260 253
261#ifdef CONFIG_MPIC 254#ifdef CONFIG_MPIC
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c
index 43df53c30aa0..ebebc28fe895 100644
--- a/arch/powerpc/platforms/pseries/xics.c
+++ b/arch/powerpc/platforms/pseries/xics.c
@@ -9,7 +9,6 @@
9 * 2 of the License, or (at your option) any later version. 9 * 2 of the License, or (at your option) any later version.
10 */ 10 */
11 11
12#undef DEBUG
13 12
14#include <linux/types.h> 13#include <linux/types.h>
15#include <linux/threads.h> 14#include <linux/threads.h>
diff --git a/arch/powerpc/sysdev/mv64x60_dev.c b/arch/powerpc/sysdev/mv64x60_dev.c
index 047b31027fa6..41af1223e2a0 100644
--- a/arch/powerpc/sysdev/mv64x60_dev.c
+++ b/arch/powerpc/sysdev/mv64x60_dev.c
@@ -338,15 +338,13 @@ static int __init mv64x60_i2c_device_setup(struct device_node *np, int id)
338 338
339 pdata.freq_m = 8; /* default */ 339 pdata.freq_m = 8; /* default */
340 prop = of_get_property(np, "freq_m", NULL); 340 prop = of_get_property(np, "freq_m", NULL);
341 if (!prop) 341 if (prop)
342 return -ENODEV; 342 pdata.freq_m = *prop;
343 pdata.freq_m = *prop;
344 343
345 pdata.freq_m = 3; /* default */ 344 pdata.freq_m = 3; /* default */
346 prop = of_get_property(np, "freq_n", NULL); 345 prop = of_get_property(np, "freq_n", NULL);
347 if (!prop) 346 if (prop)
348 return -ENODEV; 347 pdata.freq_n = *prop;
349 pdata.freq_n = *prop;
350 348
351 pdata.timeout = 1000; /* default: 1 second */ 349 pdata.timeout = 1000; /* default: 1 second */
352 350
@@ -433,9 +431,13 @@ static int __init mv64x60_device_setup(void)
433 int err; 431 int err;
434 432
435 id = 0; 433 id = 0;
436 for_each_compatible_node(np, "serial", "marvell,mv64360-mpsc") 434 for_each_compatible_node(np, "serial", "marvell,mv64360-mpsc") {
437 if ((err = mv64x60_mpsc_device_setup(np, id++))) 435 err = mv64x60_mpsc_device_setup(np, id++);
438 goto error; 436 if (err)
437 printk(KERN_ERR "Failed to initialize MV64x60 "
438 "serial device %s: error %d.\n",
439 np->full_name, err);
440 }
439 441
440 id = 0; 442 id = 0;
441 id2 = 0; 443 id2 = 0;
@@ -443,38 +445,44 @@ static int __init mv64x60_device_setup(void)
443 pdev = mv64x60_eth_register_shared_pdev(np, id++); 445 pdev = mv64x60_eth_register_shared_pdev(np, id++);
444 if (IS_ERR(pdev)) { 446 if (IS_ERR(pdev)) {
445 err = PTR_ERR(pdev); 447 err = PTR_ERR(pdev);
446 goto error; 448 printk(KERN_ERR "Failed to initialize MV64x60 "
449 "network block %s: error %d.\n",
450 np->full_name, err);
451 continue;
447 } 452 }
448 for_each_child_of_node(np, np2) { 453 for_each_child_of_node(np, np2) {
449 if (!of_device_is_compatible(np2, 454 if (!of_device_is_compatible(np2,
450 "marvell,mv64360-eth")) 455 "marvell,mv64360-eth"))
451 continue; 456 continue;
452 err = mv64x60_eth_device_setup(np2, id2++, pdev); 457 err = mv64x60_eth_device_setup(np2, id2++, pdev);
453 if (err) { 458 if (err)
454 of_node_put(np2); 459 printk(KERN_ERR "Failed to initialize "
455 goto error; 460 "MV64x60 network device %s: "
456 } 461 "error %d.\n",
462 np2->full_name, err);
457 } 463 }
458 } 464 }
459 465
460 id = 0; 466 id = 0;
461 for_each_compatible_node(np, "i2c", "marvell,mv64360-i2c") 467 for_each_compatible_node(np, "i2c", "marvell,mv64360-i2c") {
462 if ((err = mv64x60_i2c_device_setup(np, id++))) 468 err = mv64x60_i2c_device_setup(np, id++);
463 goto error; 469 if (err)
470 printk(KERN_ERR "Failed to initialize MV64x60 I2C "
471 "bus %s: error %d.\n",
472 np->full_name, err);
473 }
464 474
465 /* support up to one watchdog timer */ 475 /* support up to one watchdog timer */
466 np = of_find_compatible_node(np, NULL, "marvell,mv64360-wdt"); 476 np = of_find_compatible_node(np, NULL, "marvell,mv64360-wdt");
467 if (np) { 477 if (np) {
468 if ((err = mv64x60_wdt_device_setup(np, id))) 478 if ((err = mv64x60_wdt_device_setup(np, id)))
469 goto error; 479 printk(KERN_ERR "Failed to initialize MV64x60 "
480 "Watchdog %s: error %d.\n",
481 np->full_name, err);
470 of_node_put(np); 482 of_node_put(np);
471 } 483 }
472 484
473 return 0; 485 return 0;
474
475error:
476 of_node_put(np);
477 return err;
478} 486}
479arch_initcall(mv64x60_device_setup); 487arch_initcall(mv64x60_device_setup);
480 488
diff --git a/arch/powerpc/sysdev/mv64x60_udbg.c b/arch/powerpc/sysdev/mv64x60_udbg.c
index ccdb3b0418fc..2792dc8b038c 100644
--- a/arch/powerpc/sysdev/mv64x60_udbg.c
+++ b/arch/powerpc/sysdev/mv64x60_udbg.c
@@ -94,7 +94,7 @@ static void mv64x60_udbg_init(void)
94 if (!np) 94 if (!np)
95 return; 95 return;
96 96
97 block_index = of_get_property(np, "block-index", NULL); 97 block_index = of_get_property(np, "cell-index", NULL);
98 if (!block_index) 98 if (!block_index)
99 goto error; 99 goto error;
100 100