diff options
author | Paul Mackerras <paulus@samba.org> | 2006-12-03 23:59:07 -0500 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2006-12-03 23:59:07 -0500 |
commit | 79acbb3ff2d8095b692e1502b9eb2ccec348de26 (patch) | |
tree | 6ab773e5a8f9de2cd6443362b21d0d6fffe3b35e /arch/powerpc | |
parent | 19a79859e168640f8e16d7b216d211c1c52b687a (diff) | |
parent | 2b5f6dcce5bf94b9b119e9ed8d537098ec61c3d2 (diff) |
Merge branch 'linux-2.6' into for-linus
Diffstat (limited to 'arch/powerpc')
56 files changed, 650 insertions, 756 deletions
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index a41d191bf1b..96316c86610 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig | |||
@@ -433,7 +433,7 @@ config PPC_MAPLE | |||
433 | default n | 433 | default n |
434 | help | 434 | help |
435 | This option enables support for the Maple 970FX Evaluation Board. | 435 | This option enables support for the Maple 970FX Evaluation Board. |
436 | For more informations, refer to <http://www.970eval.com> | 436 | For more information, refer to <http://www.970eval.com> |
437 | 437 | ||
438 | config PPC_PASEMI | 438 | config PPC_PASEMI |
439 | depends on PPC_MULTIPLATFORM && PPC64 | 439 | depends on PPC_MULTIPLATFORM && PPC64 |
@@ -742,7 +742,7 @@ config ARCH_SPARSEMEM_ENABLE | |||
742 | 742 | ||
743 | config ARCH_SPARSEMEM_DEFAULT | 743 | config ARCH_SPARSEMEM_DEFAULT |
744 | def_bool y | 744 | def_bool y |
745 | depends on SMP && PPC_PSERIES | 745 | depends on (SMP && PPC_PSERIES) || PPC_CELL |
746 | 746 | ||
747 | config ARCH_POPULATES_NODE_MAP | 747 | config ARCH_POPULATES_NODE_MAP |
748 | def_bool y | 748 | def_bool y |
@@ -753,6 +753,15 @@ config ARCH_MEMORY_PROBE | |||
753 | def_bool y | 753 | def_bool y |
754 | depends on MEMORY_HOTPLUG | 754 | depends on MEMORY_HOTPLUG |
755 | 755 | ||
756 | # Some NUMA nodes have memory ranges that span | ||
757 | # other nodes. Even though a pfn is valid and | ||
758 | # between a node's start and end pfns, it may not | ||
759 | # reside on that node. See memmap_init_zone() | ||
760 | # for details. | ||
761 | config NODES_SPAN_OTHER_NODES | ||
762 | def_bool y | ||
763 | depends on NEED_MULTIPLE_NODES | ||
764 | |||
756 | config PPC_64K_PAGES | 765 | config PPC_64K_PAGES |
757 | bool "64k page size" | 766 | bool "64k page size" |
758 | depends on PPC64 | 767 | depends on PPC64 |
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile index 042bac319be..4a6f0f054b7 100644 --- a/arch/powerpc/boot/Makefile +++ b/arch/powerpc/boot/Makefile | |||
@@ -116,7 +116,7 @@ endif | |||
116 | quiet_cmd_wrap = WRAP $@ | 116 | quiet_cmd_wrap = WRAP $@ |
117 | cmd_wrap =$(CONFIG_SHELL) $(wrapper) -c -o $@ -p $2 $(CROSSWRAP) vmlinux | 117 | cmd_wrap =$(CONFIG_SHELL) $(wrapper) -c -o $@ -p $2 $(CROSSWRAP) vmlinux |
118 | quiet_cmd_wrap_initrd = WRAP $@ | 118 | quiet_cmd_wrap_initrd = WRAP $@ |
119 | cmd_wrap_initrd =$(wrapper) -c -o $@ -p $2 $(CROSSWRAP) \ | 119 | cmd_wrap_initrd =$(CONFIG_SHELL) $(wrapper) -c -o $@ -p $2 $(CROSSWRAP) \ |
120 | -i $(obj)/ramdisk.image.gz vmlinux | 120 | -i $(obj)/ramdisk.image.gz vmlinux |
121 | 121 | ||
122 | $(obj)/zImage.chrp: vmlinux $(wrapperbits) | 122 | $(obj)/zImage.chrp: vmlinux $(wrapperbits) |
diff --git a/arch/powerpc/configs/cell_defconfig b/arch/powerpc/configs/cell_defconfig index c5c54f49ae5..dbcd4e3329d 100644 --- a/arch/powerpc/configs/cell_defconfig +++ b/arch/powerpc/configs/cell_defconfig | |||
@@ -268,6 +268,7 @@ CONFIG_SYN_COOKIES=y | |||
268 | CONFIG_INET_TUNNEL=y | 268 | CONFIG_INET_TUNNEL=y |
269 | CONFIG_INET_XFRM_MODE_TRANSPORT=y | 269 | CONFIG_INET_XFRM_MODE_TRANSPORT=y |
270 | CONFIG_INET_XFRM_MODE_TUNNEL=y | 270 | CONFIG_INET_XFRM_MODE_TUNNEL=y |
271 | # CONFIG_INET_XFRM_MODE_BEET is not set | ||
271 | CONFIG_INET_DIAG=y | 272 | CONFIG_INET_DIAG=y |
272 | CONFIG_INET_TCP_DIAG=y | 273 | CONFIG_INET_TCP_DIAG=y |
273 | # CONFIG_TCP_CONG_ADVANCED is not set | 274 | # CONFIG_TCP_CONG_ADVANCED is not set |
@@ -289,7 +290,9 @@ CONFIG_INET6_XFRM_TUNNEL=m | |||
289 | CONFIG_INET6_TUNNEL=m | 290 | CONFIG_INET6_TUNNEL=m |
290 | CONFIG_INET6_XFRM_MODE_TRANSPORT=y | 291 | CONFIG_INET6_XFRM_MODE_TRANSPORT=y |
291 | CONFIG_INET6_XFRM_MODE_TUNNEL=y | 292 | CONFIG_INET6_XFRM_MODE_TUNNEL=y |
293 | # CONFIG_INET6_XFRM_MODE_BEET is not set | ||
292 | # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set | 294 | # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set |
295 | # CONFIG_IPV6_SIT is not set | ||
293 | CONFIG_IPV6_TUNNEL=m | 296 | CONFIG_IPV6_TUNNEL=m |
294 | # CONFIG_IPV6_SUBTREES is not set | 297 | # CONFIG_IPV6_SUBTREES is not set |
295 | # CONFIG_IPV6_MULTIPLE_TABLES is not set | 298 | # CONFIG_IPV6_MULTIPLE_TABLES is not set |
@@ -420,6 +423,12 @@ CONFIG_BLK_DEV_INITRD=y | |||
420 | # CONFIG_ATA_OVER_ETH is not set | 423 | # CONFIG_ATA_OVER_ETH is not set |
421 | 424 | ||
422 | # | 425 | # |
426 | # Misc devices | ||
427 | # | ||
428 | # CONFIG_SGI_IOC4 is not set | ||
429 | # CONFIG_TIFM_CORE is not set | ||
430 | |||
431 | # | ||
423 | # ATA/ATAPI/MFM/RLL support | 432 | # ATA/ATAPI/MFM/RLL support |
424 | # | 433 | # |
425 | CONFIG_IDE=y | 434 | CONFIG_IDE=y |
@@ -752,7 +761,6 @@ CONFIG_GEN_RTC=y | |||
752 | # TPM devices | 761 | # TPM devices |
753 | # | 762 | # |
754 | # CONFIG_TCG_TPM is not set | 763 | # CONFIG_TCG_TPM is not set |
755 | # CONFIG_TELCLOCK is not set | ||
756 | 764 | ||
757 | # | 765 | # |
758 | # I2C support | 766 | # I2C support |
@@ -816,6 +824,7 @@ CONFIG_I2C_ALGOBIT=y | |||
816 | # | 824 | # |
817 | # Dallas's 1-wire bus | 825 | # Dallas's 1-wire bus |
818 | # | 826 | # |
827 | # CONFIG_W1 is not set | ||
819 | 828 | ||
820 | # | 829 | # |
821 | # Hardware Monitoring support | 830 | # Hardware Monitoring support |
@@ -824,14 +833,9 @@ CONFIG_I2C_ALGOBIT=y | |||
824 | # CONFIG_HWMON_VID is not set | 833 | # CONFIG_HWMON_VID is not set |
825 | 834 | ||
826 | # | 835 | # |
827 | # Misc devices | ||
828 | # | ||
829 | |||
830 | # | ||
831 | # Multimedia devices | 836 | # Multimedia devices |
832 | # | 837 | # |
833 | # CONFIG_VIDEO_DEV is not set | 838 | # CONFIG_VIDEO_DEV is not set |
834 | CONFIG_VIDEO_V4L2=y | ||
835 | 839 | ||
836 | # | 840 | # |
837 | # Digital Video Broadcasting Devices | 841 | # Digital Video Broadcasting Devices |
@@ -937,6 +941,7 @@ CONFIG_EXT3_FS=y | |||
937 | CONFIG_EXT3_FS_XATTR=y | 941 | CONFIG_EXT3_FS_XATTR=y |
938 | # CONFIG_EXT3_FS_POSIX_ACL is not set | 942 | # CONFIG_EXT3_FS_POSIX_ACL is not set |
939 | # CONFIG_EXT3_FS_SECURITY is not set | 943 | # CONFIG_EXT3_FS_SECURITY is not set |
944 | # CONFIG_EXT4DEV_FS is not set | ||
940 | CONFIG_JBD=y | 945 | CONFIG_JBD=y |
941 | # CONFIG_JBD_DEBUG is not set | 946 | # CONFIG_JBD_DEBUG is not set |
942 | CONFIG_FS_MBCACHE=y | 947 | CONFIG_FS_MBCACHE=y |
@@ -944,6 +949,7 @@ CONFIG_FS_MBCACHE=y | |||
944 | # CONFIG_JFS_FS is not set | 949 | # CONFIG_JFS_FS is not set |
945 | CONFIG_FS_POSIX_ACL=y | 950 | CONFIG_FS_POSIX_ACL=y |
946 | # CONFIG_XFS_FS is not set | 951 | # CONFIG_XFS_FS is not set |
952 | # CONFIG_GFS2_FS is not set | ||
947 | # CONFIG_OCFS2_FS is not set | 953 | # CONFIG_OCFS2_FS is not set |
948 | # CONFIG_MINIX_FS is not set | 954 | # CONFIG_MINIX_FS is not set |
949 | # CONFIG_ROMFS_FS is not set | 955 | # CONFIG_ROMFS_FS is not set |
@@ -1143,6 +1149,7 @@ CONFIG_DEBUG_FS=y | |||
1143 | # CONFIG_DEBUG_VM is not set | 1149 | # CONFIG_DEBUG_VM is not set |
1144 | # CONFIG_DEBUG_LIST is not set | 1150 | # CONFIG_DEBUG_LIST is not set |
1145 | # CONFIG_FORCED_INLINING is not set | 1151 | # CONFIG_FORCED_INLINING is not set |
1152 | # CONFIG_HEADERS_CHECK is not set | ||
1146 | # CONFIG_RCU_TORTURE_TEST is not set | 1153 | # CONFIG_RCU_TORTURE_TEST is not set |
1147 | # CONFIG_DEBUG_STACKOVERFLOW is not set | 1154 | # CONFIG_DEBUG_STACKOVERFLOW is not set |
1148 | # CONFIG_DEBUG_STACK_USAGE is not set | 1155 | # CONFIG_DEBUG_STACK_USAGE is not set |
diff --git a/arch/powerpc/configs/pseries_defconfig b/arch/powerpc/configs/pseries_defconfig index 9828663652e..d2833c1a1f3 100644 --- a/arch/powerpc/configs/pseries_defconfig +++ b/arch/powerpc/configs/pseries_defconfig | |||
@@ -184,6 +184,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 | |||
184 | CONFIG_MIGRATION=y | 184 | CONFIG_MIGRATION=y |
185 | CONFIG_RESOURCES_64BIT=y | 185 | CONFIG_RESOURCES_64BIT=y |
186 | CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y | 186 | CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y |
187 | CONFIG_NODES_SPAN_OTHER_NODES=y | ||
187 | # CONFIG_PPC_64K_PAGES is not set | 188 | # CONFIG_PPC_64K_PAGES is not set |
188 | CONFIG_SCHED_SMT=y | 189 | CONFIG_SCHED_SMT=y |
189 | CONFIG_PROC_DEVICETREE=y | 190 | CONFIG_PROC_DEVICETREE=y |
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 82c223852e6..d8240ce2212 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile | |||
@@ -37,7 +37,6 @@ obj-$(CONFIG_6xx) += idle_6xx.o l2cr_6xx.o cpu_setup_6xx.o | |||
37 | obj-$(CONFIG_TAU) += tau_6xx.o | 37 | obj-$(CONFIG_TAU) += tau_6xx.o |
38 | obj32-$(CONFIG_SOFTWARE_SUSPEND) += swsusp_32.o | 38 | obj32-$(CONFIG_SOFTWARE_SUSPEND) += swsusp_32.o |
39 | obj32-$(CONFIG_MODULES) += module_32.o | 39 | obj32-$(CONFIG_MODULES) += module_32.o |
40 | obj-$(CONFIG_E500) += perfmon_fsl_booke.o | ||
41 | 40 | ||
42 | ifeq ($(CONFIG_PPC_MERGE),y) | 41 | ifeq ($(CONFIG_PPC_MERGE),y) |
43 | 42 | ||
diff --git a/arch/powerpc/kernel/btext.c b/arch/powerpc/kernel/btext.c index 995fcef156f..93f21aaf7c8 100644 --- a/arch/powerpc/kernel/btext.c +++ b/arch/powerpc/kernel/btext.c | |||
@@ -182,7 +182,7 @@ int btext_initialize(struct device_node *np) | |||
182 | prop = get_property(np, "linux,bootx-linebytes", NULL); | 182 | prop = get_property(np, "linux,bootx-linebytes", NULL); |
183 | if (prop == NULL) | 183 | if (prop == NULL) |
184 | prop = get_property(np, "linebytes", NULL); | 184 | prop = get_property(np, "linebytes", NULL); |
185 | if (prop) | 185 | if (prop && *prop != 0xffffffffu) |
186 | pitch = *prop; | 186 | pitch = *prop; |
187 | if (pitch == 1) | 187 | if (pitch == 1) |
188 | pitch = 0x1000; | 188 | pitch = 0x1000; |
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index f02b402c66d..1e4ed0731d1 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c | |||
@@ -18,6 +18,7 @@ | |||
18 | 18 | ||
19 | #include <asm/oprofile_impl.h> | 19 | #include <asm/oprofile_impl.h> |
20 | #include <asm/cputable.h> | 20 | #include <asm/cputable.h> |
21 | #include <asm/prom.h> /* for PTRRELOC on ARCH=ppc */ | ||
21 | 22 | ||
22 | struct cpu_spec* cur_cpu_spec = NULL; | 23 | struct cpu_spec* cur_cpu_spec = NULL; |
23 | EXPORT_SYMBOL(cur_cpu_spec); | 24 | EXPORT_SYMBOL(cur_cpu_spec); |
@@ -74,7 +75,7 @@ extern void __restore_cpu_ppc970(void); | |||
74 | #define PPC_FEATURE_SPE_COMP 0 | 75 | #define PPC_FEATURE_SPE_COMP 0 |
75 | #endif | 76 | #endif |
76 | 77 | ||
77 | struct cpu_spec cpu_specs[] = { | 78 | static struct cpu_spec cpu_specs[] = { |
78 | #ifdef CONFIG_PPC64 | 79 | #ifdef CONFIG_PPC64 |
79 | { /* Power3 */ | 80 | { /* Power3 */ |
80 | .pvr_mask = 0xffff0000, | 81 | .pvr_mask = 0xffff0000, |
@@ -228,6 +229,21 @@ struct cpu_spec cpu_specs[] = { | |||
228 | .oprofile_type = PPC_OPROFILE_POWER4, | 229 | .oprofile_type = PPC_OPROFILE_POWER4, |
229 | .platform = "ppc970", | 230 | .platform = "ppc970", |
230 | }, | 231 | }, |
232 | { /* PPC970GX */ | ||
233 | .pvr_mask = 0xffff0000, | ||
234 | .pvr_value = 0x00450000, | ||
235 | .cpu_name = "PPC970GX", | ||
236 | .cpu_features = CPU_FTRS_PPC970, | ||
237 | .cpu_user_features = COMMON_USER_POWER4 | | ||
238 | PPC_FEATURE_HAS_ALTIVEC_COMP, | ||
239 | .icache_bsize = 128, | ||
240 | .dcache_bsize = 128, | ||
241 | .num_pmcs = 8, | ||
242 | .cpu_setup = __setup_cpu_ppc970, | ||
243 | .oprofile_cpu_type = "ppc64/970", | ||
244 | .oprofile_type = PPC_OPROFILE_POWER4, | ||
245 | .platform = "ppc970", | ||
246 | }, | ||
231 | { /* Power5 GR */ | 247 | { /* Power5 GR */ |
232 | .pvr_mask = 0xffff0000, | 248 | .pvr_mask = 0xffff0000, |
233 | .pvr_value = 0x003a0000, | 249 | .pvr_value = 0x003a0000, |
@@ -1153,3 +1169,71 @@ struct cpu_spec cpu_specs[] = { | |||
1153 | #endif /* !CLASSIC_PPC */ | 1169 | #endif /* !CLASSIC_PPC */ |
1154 | #endif /* CONFIG_PPC32 */ | 1170 | #endif /* CONFIG_PPC32 */ |
1155 | }; | 1171 | }; |
1172 | |||
1173 | struct cpu_spec *identify_cpu(unsigned long offset) | ||
1174 | { | ||
1175 | struct cpu_spec *s = cpu_specs; | ||
1176 | struct cpu_spec **cur = &cur_cpu_spec; | ||
1177 | unsigned int pvr = mfspr(SPRN_PVR); | ||
1178 | int i; | ||
1179 | |||
1180 | s = PTRRELOC(s); | ||
1181 | cur = PTRRELOC(cur); | ||
1182 | |||
1183 | if (*cur != NULL) | ||
1184 | return PTRRELOC(*cur); | ||
1185 | |||
1186 | for (i = 0; i < ARRAY_SIZE(cpu_specs); i++,s++) | ||
1187 | if ((pvr & s->pvr_mask) == s->pvr_value) { | ||
1188 | *cur = cpu_specs + i; | ||
1189 | #ifdef CONFIG_PPC64 | ||
1190 | /* ppc64 expects identify_cpu to also call setup_cpu | ||
1191 | * for that processor. I will consolidate that at a | ||
1192 | * later time, for now, just use our friend #ifdef. | ||
1193 | * we also don't need to PTRRELOC the function pointer | ||
1194 | * on ppc64 as we are running at 0 in real mode. | ||
1195 | */ | ||
1196 | if (s->cpu_setup) { | ||
1197 | s->cpu_setup(offset, s); | ||
1198 | } | ||
1199 | #endif /* CONFIG_PPC64 */ | ||
1200 | return s; | ||
1201 | } | ||
1202 | BUG(); | ||
1203 | return NULL; | ||
1204 | } | ||
1205 | |||
1206 | void do_feature_fixups(unsigned long value, void *fixup_start, void *fixup_end) | ||
1207 | { | ||
1208 | struct fixup_entry { | ||
1209 | unsigned long mask; | ||
1210 | unsigned long value; | ||
1211 | long start_off; | ||
1212 | long end_off; | ||
1213 | } *fcur, *fend; | ||
1214 | |||
1215 | fcur = fixup_start; | ||
1216 | fend = fixup_end; | ||
1217 | |||
1218 | for (; fcur < fend; fcur++) { | ||
1219 | unsigned int *pstart, *pend, *p; | ||
1220 | |||
1221 | if ((value & fcur->mask) == fcur->value) | ||
1222 | continue; | ||
1223 | |||
1224 | /* These PTRRELOCs will disappear once the new scheme for | ||
1225 | * modules and vdso is implemented | ||
1226 | */ | ||
1227 | pstart = ((unsigned int *)fcur) + (fcur->start_off / 4); | ||
1228 | pend = ((unsigned int *)fcur) + (fcur->end_off / 4); | ||
1229 | |||
1230 | for (p = pstart; p < pend; p++) { | ||
1231 | *p = 0x60000000u; | ||
1232 | asm volatile ("dcbst 0, %0" : : "r" (p)); | ||
1233 | } | ||
1234 | asm volatile ("sync" : : : "memory"); | ||
1235 | for (p = pstart; p < pend; p++) | ||
1236 | asm volatile ("icbi 0,%0" : : "r" (p)); | ||
1237 | asm volatile ("sync; isync" : : : "memory"); | ||
1238 | } | ||
1239 | } | ||
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index 76d1c81afe5..8cdff5a1f3e 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S | |||
@@ -503,7 +503,7 @@ BEGIN_FTR_SECTION | |||
503 | rlwimi r13,r12,16,0x20 | 503 | rlwimi r13,r12,16,0x20 |
504 | mfcr r12 | 504 | mfcr r12 |
505 | cmpwi r13,0x2c | 505 | cmpwi r13,0x2c |
506 | beq .do_stab_bolted_pSeries | 506 | beq do_stab_bolted_pSeries |
507 | mtcrf 0x80,r12 | 507 | mtcrf 0x80,r12 |
508 | mfspr r12,SPRN_SPRG2 | 508 | mfspr r12,SPRN_SPRG2 |
509 | END_FTR_SECTION_IFCLR(CPU_FTR_SLB) | 509 | END_FTR_SECTION_IFCLR(CPU_FTR_SLB) |
@@ -633,7 +633,7 @@ masked_interrupt: | |||
633 | b . | 633 | b . |
634 | 634 | ||
635 | .align 7 | 635 | .align 7 |
636 | _GLOBAL(do_stab_bolted_pSeries) | 636 | do_stab_bolted_pSeries: |
637 | mtcrf 0x80,r12 | 637 | mtcrf 0x80,r12 |
638 | mfspr r12,SPRN_SPRG2 | 638 | mfspr r12,SPRN_SPRG2 |
639 | EXCEPTION_PROLOG_PSERIES(PACA_EXSLB, .do_stab_bolted) | 639 | EXCEPTION_PROLOG_PSERIES(PACA_EXSLB, .do_stab_bolted) |
@@ -1088,7 +1088,7 @@ slb_miss_fault: | |||
1088 | li r5,0 | 1088 | li r5,0 |
1089 | std r4,_DAR(r1) | 1089 | std r4,_DAR(r1) |
1090 | std r5,_DSISR(r1) | 1090 | std r5,_DSISR(r1) |
1091 | b .handle_page_fault | 1091 | b handle_page_fault |
1092 | 1092 | ||
1093 | unrecov_user_slb: | 1093 | unrecov_user_slb: |
1094 | EXCEPTION_PROLOG_COMMON(0x4200, PACA_EXGEN) | 1094 | EXCEPTION_PROLOG_COMMON(0x4200, PACA_EXGEN) |
@@ -1216,12 +1216,13 @@ program_check_common: | |||
1216 | .globl fp_unavailable_common | 1216 | .globl fp_unavailable_common |
1217 | fp_unavailable_common: | 1217 | fp_unavailable_common: |
1218 | EXCEPTION_PROLOG_COMMON(0x800, PACA_EXGEN) | 1218 | EXCEPTION_PROLOG_COMMON(0x800, PACA_EXGEN) |
1219 | bne .load_up_fpu /* if from user, just load it up */ | 1219 | bne 1f /* if from user, just load it up */ |
1220 | bl .save_nvgprs | 1220 | bl .save_nvgprs |
1221 | addi r3,r1,STACK_FRAME_OVERHEAD | 1221 | addi r3,r1,STACK_FRAME_OVERHEAD |
1222 | ENABLE_INTS | 1222 | ENABLE_INTS |
1223 | bl .kernel_fp_unavailable_exception | 1223 | bl .kernel_fp_unavailable_exception |
1224 | BUG_OPCODE | 1224 | BUG_OPCODE |
1225 | 1: b .load_up_fpu | ||
1225 | 1226 | ||
1226 | .align 7 | 1227 | .align 7 |
1227 | .globl altivec_unavailable_common | 1228 | .globl altivec_unavailable_common |
@@ -1321,10 +1322,10 @@ _GLOBAL(do_hash_page) | |||
1321 | std r4,_DSISR(r1) | 1322 | std r4,_DSISR(r1) |
1322 | 1323 | ||
1323 | andis. r0,r4,0xa450 /* weird error? */ | 1324 | andis. r0,r4,0xa450 /* weird error? */ |
1324 | bne- .handle_page_fault /* if not, try to insert a HPTE */ | 1325 | bne- handle_page_fault /* if not, try to insert a HPTE */ |
1325 | BEGIN_FTR_SECTION | 1326 | BEGIN_FTR_SECTION |
1326 | andis. r0,r4,0x0020 /* Is it a segment table fault? */ | 1327 | andis. r0,r4,0x0020 /* Is it a segment table fault? */ |
1327 | bne- .do_ste_alloc /* If so handle it */ | 1328 | bne- do_ste_alloc /* If so handle it */ |
1328 | END_FTR_SECTION_IFCLR(CPU_FTR_SLB) | 1329 | END_FTR_SECTION_IFCLR(CPU_FTR_SLB) |
1329 | 1330 | ||
1330 | /* | 1331 | /* |
@@ -1366,7 +1367,7 @@ BEGIN_FW_FTR_SECTION | |||
1366 | * because ret_from_except_lite will check for and handle pending | 1367 | * because ret_from_except_lite will check for and handle pending |
1367 | * interrupts if necessary. | 1368 | * interrupts if necessary. |
1368 | */ | 1369 | */ |
1369 | beq .ret_from_except_lite | 1370 | beq 13f |
1370 | END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) | 1371 | END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) |
1371 | #endif | 1372 | #endif |
1372 | BEGIN_FW_FTR_SECTION | 1373 | BEGIN_FW_FTR_SECTION |
@@ -1390,14 +1391,14 @@ END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES) | |||
1390 | b 11f | 1391 | b 11f |
1391 | 1392 | ||
1392 | /* Here we have a page fault that hash_page can't handle. */ | 1393 | /* Here we have a page fault that hash_page can't handle. */ |
1393 | _GLOBAL(handle_page_fault) | 1394 | handle_page_fault: |
1394 | ENABLE_INTS | 1395 | ENABLE_INTS |
1395 | 11: ld r4,_DAR(r1) | 1396 | 11: ld r4,_DAR(r1) |
1396 | ld r5,_DSISR(r1) | 1397 | ld r5,_DSISR(r1) |
1397 | addi r3,r1,STACK_FRAME_OVERHEAD | 1398 | addi r3,r1,STACK_FRAME_OVERHEAD |
1398 | bl .do_page_fault | 1399 | bl .do_page_fault |
1399 | cmpdi r3,0 | 1400 | cmpdi r3,0 |
1400 | beq+ .ret_from_except_lite | 1401 | beq+ 13f |
1401 | bl .save_nvgprs | 1402 | bl .save_nvgprs |
1402 | mr r5,r3 | 1403 | mr r5,r3 |
1403 | addi r3,r1,STACK_FRAME_OVERHEAD | 1404 | addi r3,r1,STACK_FRAME_OVERHEAD |
@@ -1405,6 +1406,8 @@ _GLOBAL(handle_page_fault) | |||
1405 | bl .bad_page_fault | 1406 | bl .bad_page_fault |
1406 | b .ret_from_except | 1407 | b .ret_from_except |
1407 | 1408 | ||
1409 | 13: b .ret_from_except_lite | ||
1410 | |||
1408 | /* We have a page fault that hash_page could handle but HV refused | 1411 | /* We have a page fault that hash_page could handle but HV refused |
1409 | * the PTE insertion | 1412 | * the PTE insertion |
1410 | */ | 1413 | */ |
@@ -1415,11 +1418,11 @@ _GLOBAL(handle_page_fault) | |||
1415 | b .ret_from_except | 1418 | b .ret_from_except |
1416 | 1419 | ||
1417 | /* here we have a segment miss */ | 1420 | /* here we have a segment miss */ |
1418 | _GLOBAL(do_ste_alloc) | 1421 | do_ste_alloc: |
1419 | bl .ste_allocate /* try to insert stab entry */ | 1422 | bl .ste_allocate /* try to insert stab entry */ |
1420 | cmpdi r3,0 | 1423 | cmpdi r3,0 |
1421 | beq+ fast_exception_return | 1424 | bne- handle_page_fault |
1422 | b .handle_page_fault | 1425 | b fast_exception_return |
1423 | 1426 | ||
1424 | /* | 1427 | /* |
1425 | * r13 points to the PACA, r9 contains the saved CR, | 1428 | * r13 points to the PACA, r9 contains the saved CR, |
@@ -1624,11 +1627,6 @@ _STATIC(__start_initialization_iSeries) | |||
1624 | li r0,0 | 1627 | li r0,0 |
1625 | stdu r0,-STACK_FRAME_OVERHEAD(r1) | 1628 | stdu r0,-STACK_FRAME_OVERHEAD(r1) |
1626 | 1629 | ||
1627 | LOAD_REG_IMMEDIATE(r3,cpu_specs) | ||
1628 | LOAD_REG_IMMEDIATE(r4,cur_cpu_spec) | ||
1629 | li r5,0 | ||
1630 | bl .identify_cpu | ||
1631 | |||
1632 | LOAD_REG_IMMEDIATE(r2,__toc_start) | 1630 | LOAD_REG_IMMEDIATE(r2,__toc_start) |
1633 | addi r2,r2,0x4000 | 1631 | addi r2,r2,0x4000 |
1634 | addi r2,r2,0x4000 | 1632 | addi r2,r2,0x4000 |
@@ -1687,6 +1685,8 @@ _GLOBAL(__start_initialization_multiplatform) | |||
1687 | cmpwi r0,0x3c /* 970FX */ | 1685 | cmpwi r0,0x3c /* 970FX */ |
1688 | beq 1f | 1686 | beq 1f |
1689 | cmpwi r0,0x44 /* 970MP */ | 1687 | cmpwi r0,0x44 /* 970MP */ |
1688 | beq 1f | ||
1689 | cmpwi r0,0x45 /* 970GX */ | ||
1690 | bne 2f | 1690 | bne 2f |
1691 | 1: bl .__cpu_preinit_ppc970 | 1691 | 1: bl .__cpu_preinit_ppc970 |
1692 | 2: | 1692 | 2: |
@@ -2005,13 +2005,6 @@ _STATIC(start_here_multiplatform) | |||
2005 | addi r2,r2,0x4000 | 2005 | addi r2,r2,0x4000 |
2006 | add r2,r2,r26 | 2006 | add r2,r2,r26 |
2007 | 2007 | ||
2008 | LOAD_REG_IMMEDIATE(r3, cpu_specs) | ||
2009 | add r3,r3,r26 | ||
2010 | LOAD_REG_IMMEDIATE(r4,cur_cpu_spec) | ||
2011 | add r4,r4,r26 | ||
2012 | mr r5,r26 | ||
2013 | bl .identify_cpu | ||
2014 | |||
2015 | /* Do very early kernel initializations, including initial hash table, | 2008 | /* Do very early kernel initializations, including initial hash table, |
2016 | * stab and slb setup before we turn on relocation. */ | 2009 | * stab and slb setup before we turn on relocation. */ |
2017 | 2010 | ||
@@ -2040,13 +2033,6 @@ _STATIC(start_here_common) | |||
2040 | li r0,0 | 2033 | li r0,0 |
2041 | stdu r0,-STACK_FRAME_OVERHEAD(r1) | 2034 | stdu r0,-STACK_FRAME_OVERHEAD(r1) |
2042 | 2035 | ||
2043 | /* Apply the CPUs-specific fixups (nop out sections not relevant | ||
2044 | * to this CPU | ||
2045 | */ | ||
2046 | li r3,0 | ||
2047 | bl .do_cpu_ftr_fixups | ||
2048 | bl .do_fw_ftr_fixups | ||
2049 | |||
2050 | /* ptr to current */ | 2036 | /* ptr to current */ |
2051 | LOAD_REG_IMMEDIATE(r4, init_task) | 2037 | LOAD_REG_IMMEDIATE(r4, init_task) |
2052 | std r4,PACACURRENT(r13) | 2038 | std r4,PACACURRENT(r13) |
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c index f88a2a675d9..ba6b7256084 100644 --- a/arch/powerpc/kernel/iommu.c +++ b/arch/powerpc/kernel/iommu.c | |||
@@ -47,6 +47,17 @@ static int novmerge = 0; | |||
47 | static int novmerge = 1; | 47 | static int novmerge = 1; |
48 | #endif | 48 | #endif |
49 | 49 | ||
50 | static inline unsigned long iommu_num_pages(unsigned long vaddr, | ||
51 | unsigned long slen) | ||
52 | { | ||
53 | unsigned long npages; | ||
54 | |||
55 | npages = IOMMU_PAGE_ALIGN(vaddr + slen) - (vaddr & IOMMU_PAGE_MASK); | ||
56 | npages >>= IOMMU_PAGE_SHIFT; | ||
57 | |||
58 | return npages; | ||
59 | } | ||
60 | |||
50 | static int __init setup_iommu(char *str) | 61 | static int __init setup_iommu(char *str) |
51 | { | 62 | { |
52 | if (!strcmp(str, "novmerge")) | 63 | if (!strcmp(str, "novmerge")) |
@@ -178,10 +189,10 @@ static dma_addr_t iommu_alloc(struct iommu_table *tbl, void *page, | |||
178 | } | 189 | } |
179 | 190 | ||
180 | entry += tbl->it_offset; /* Offset into real TCE table */ | 191 | entry += tbl->it_offset; /* Offset into real TCE table */ |
181 | ret = entry << PAGE_SHIFT; /* Set the return dma address */ | 192 | ret = entry << IOMMU_PAGE_SHIFT; /* Set the return dma address */ |
182 | 193 | ||
183 | /* Put the TCEs in the HW table */ | 194 | /* Put the TCEs in the HW table */ |
184 | ppc_md.tce_build(tbl, entry, npages, (unsigned long)page & PAGE_MASK, | 195 | ppc_md.tce_build(tbl, entry, npages, (unsigned long)page & IOMMU_PAGE_MASK, |
185 | direction); | 196 | direction); |
186 | 197 | ||
187 | 198 | ||
@@ -203,7 +214,7 @@ static void __iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr, | |||
203 | unsigned long entry, free_entry; | 214 | unsigned long entry, free_entry; |
204 | unsigned long i; | 215 | unsigned long i; |
205 | 216 | ||
206 | entry = dma_addr >> PAGE_SHIFT; | 217 | entry = dma_addr >> IOMMU_PAGE_SHIFT; |
207 | free_entry = entry - tbl->it_offset; | 218 | free_entry = entry - tbl->it_offset; |
208 | 219 | ||
209 | if (((free_entry + npages) > tbl->it_size) || | 220 | if (((free_entry + npages) > tbl->it_size) || |
@@ -270,7 +281,7 @@ int iommu_map_sg(struct device *dev, struct iommu_table *tbl, | |||
270 | /* Init first segment length for backout at failure */ | 281 | /* Init first segment length for backout at failure */ |
271 | outs->dma_length = 0; | 282 | outs->dma_length = 0; |
272 | 283 | ||
273 | DBG("mapping %d elements:\n", nelems); | 284 | DBG("sg mapping %d elements:\n", nelems); |
274 | 285 | ||
275 | spin_lock_irqsave(&(tbl->it_lock), flags); | 286 | spin_lock_irqsave(&(tbl->it_lock), flags); |
276 | 287 | ||
@@ -285,9 +296,8 @@ int iommu_map_sg(struct device *dev, struct iommu_table *tbl, | |||
285 | } | 296 | } |
286 | /* Allocate iommu entries for that segment */ | 297 | /* Allocate iommu entries for that segment */ |
287 | vaddr = (unsigned long)page_address(s->page) + s->offset; | 298 | vaddr = (unsigned long)page_address(s->page) + s->offset; |
288 | npages = PAGE_ALIGN(vaddr + slen) - (vaddr & PAGE_MASK); | 299 | npages = iommu_num_pages(vaddr, slen); |
289 | npages >>= PAGE_SHIFT; | 300 | entry = iommu_range_alloc(tbl, npages, &handle, mask >> IOMMU_PAGE_SHIFT, 0); |
290 | entry = iommu_range_alloc(tbl, npages, &handle, mask >> PAGE_SHIFT, 0); | ||
291 | 301 | ||
292 | DBG(" - vaddr: %lx, size: %lx\n", vaddr, slen); | 302 | DBG(" - vaddr: %lx, size: %lx\n", vaddr, slen); |
293 | 303 | ||
@@ -301,14 +311,14 @@ int iommu_map_sg(struct device *dev, struct iommu_table *tbl, | |||
301 | 311 | ||
302 | /* Convert entry to a dma_addr_t */ | 312 | /* Convert entry to a dma_addr_t */ |
303 | entry += tbl->it_offset; | 313 | entry += tbl->it_offset; |
304 | dma_addr = entry << PAGE_SHIFT; | 314 | dma_addr = entry << IOMMU_PAGE_SHIFT; |
305 | dma_addr |= s->offset; | 315 | dma_addr |= (s->offset & ~IOMMU_PAGE_MASK); |
306 | 316 | ||
307 | DBG(" - %lx pages, entry: %lx, dma_addr: %lx\n", | 317 | DBG(" - %lu pages, entry: %lx, dma_addr: %lx\n", |
308 | npages, entry, dma_addr); | 318 | npages, entry, dma_addr); |
309 | 319 | ||
310 | /* Insert into HW table */ | 320 | /* Insert into HW table */ |
311 | ppc_md.tce_build(tbl, entry, npages, vaddr & PAGE_MASK, direction); | 321 | ppc_md.tce_build(tbl, entry, npages, vaddr & IOMMU_PAGE_MASK, direction); |
312 | 322 | ||
313 | /* If we are in an open segment, try merging */ | 323 | /* If we are in an open segment, try merging */ |
314 | if (segstart != s) { | 324 | if (segstart != s) { |
@@ -323,7 +333,7 @@ int iommu_map_sg(struct device *dev, struct iommu_table *tbl, | |||
323 | DBG(" can't merge, new segment.\n"); | 333 | DBG(" can't merge, new segment.\n"); |
324 | } else { | 334 | } else { |
325 | outs->dma_length += s->length; | 335 | outs->dma_length += s->length; |
326 | DBG(" merged, new len: %lx\n", outs->dma_length); | 336 | DBG(" merged, new len: %ux\n", outs->dma_length); |
327 | } | 337 | } |
328 | } | 338 | } |
329 | 339 | ||
@@ -367,9 +377,8 @@ int iommu_map_sg(struct device *dev, struct iommu_table *tbl, | |||
367 | if (s->dma_length != 0) { | 377 | if (s->dma_length != 0) { |
368 | unsigned long vaddr, npages; | 378 | unsigned long vaddr, npages; |
369 | 379 | ||
370 | vaddr = s->dma_address & PAGE_MASK; | 380 | vaddr = s->dma_address & IOMMU_PAGE_MASK; |
371 | npages = (PAGE_ALIGN(s->dma_address + s->dma_length) - vaddr) | 381 | npages = iommu_num_pages(s->dma_address, s->dma_length); |
372 | >> PAGE_SHIFT; | ||
373 | __iommu_free(tbl, vaddr, npages); | 382 | __iommu_free(tbl, vaddr, npages); |
374 | s->dma_address = DMA_ERROR_CODE; | 383 | s->dma_address = DMA_ERROR_CODE; |
375 | s->dma_length = 0; | 384 | s->dma_length = 0; |
@@ -398,8 +407,7 @@ void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist, | |||
398 | 407 | ||
399 | if (sglist->dma_length == 0) | 408 | if (sglist->dma_length == 0) |
400 | break; | 409 | break; |
401 | npages = (PAGE_ALIGN(dma_handle + sglist->dma_length) | 410 | npages = iommu_num_pages(dma_handle,sglist->dma_length); |
402 | - (dma_handle & PAGE_MASK)) >> PAGE_SHIFT; | ||
403 | __iommu_free(tbl, dma_handle, npages); | 411 | __iommu_free(tbl, dma_handle, npages); |
404 | sglist++; | 412 | sglist++; |
405 | } | 413 | } |
@@ -532,12 +540,11 @@ dma_addr_t iommu_map_single(struct iommu_table *tbl, void *vaddr, | |||
532 | BUG_ON(direction == DMA_NONE); | 540 | BUG_ON(direction == DMA_NONE); |
533 | 541 | ||
534 | uaddr = (unsigned long)vaddr; | 542 | uaddr = (unsigned long)vaddr; |
535 | npages = PAGE_ALIGN(uaddr + size) - (uaddr & PAGE_MASK); | 543 | npages = iommu_num_pages(uaddr, size); |
536 | npages >>= PAGE_SHIFT; | ||
537 | 544 | ||
538 | if (tbl) { | 545 | if (tbl) { |
539 | dma_handle = iommu_alloc(tbl, vaddr, npages, direction, | 546 | dma_handle = iommu_alloc(tbl, vaddr, npages, direction, |
540 | mask >> PAGE_SHIFT, 0); | 547 | mask >> IOMMU_PAGE_SHIFT, 0); |
541 | if (dma_handle == DMA_ERROR_CODE) { | 548 | if (dma_handle == DMA_ERROR_CODE) { |
542 | if (printk_ratelimit()) { | 549 | if (printk_ratelimit()) { |
543 | printk(KERN_INFO "iommu_alloc failed, " | 550 | printk(KERN_INFO "iommu_alloc failed, " |
@@ -545,7 +552,7 @@ dma_addr_t iommu_map_single(struct iommu_table *tbl, void *vaddr, | |||
545 | tbl, vaddr, npages); | 552 | tbl, vaddr, npages); |
546 | } | 553 | } |
547 | } else | 554 | } else |
548 | dma_handle |= (uaddr & ~PAGE_MASK); | 555 | dma_handle |= (uaddr & ~IOMMU_PAGE_MASK); |
549 | } | 556 | } |
550 | 557 | ||
551 | return dma_handle; | 558 | return dma_handle; |
@@ -554,11 +561,14 @@ dma_addr_t iommu_map_single(struct iommu_table *tbl, void *vaddr, | |||
554 | void iommu_unmap_single(struct iommu_table *tbl, dma_addr_t dma_handle, | 561 | void iommu_unmap_single(struct iommu_table *tbl, dma_addr_t dma_handle, |
555 | size_t size, enum dma_data_direction direction) | 562 | size_t size, enum dma_data_direction direction) |
556 | { | 563 | { |
564 | unsigned int npages; | ||
565 | |||
557 | BUG_ON(direction == DMA_NONE); | 566 | BUG_ON(direction == DMA_NONE); |
558 | 567 | ||
559 | if (tbl) | 568 | if (tbl) { |
560 | iommu_free(tbl, dma_handle, (PAGE_ALIGN(dma_handle + size) - | 569 | npages = iommu_num_pages(dma_handle, size); |
561 | (dma_handle & PAGE_MASK)) >> PAGE_SHIFT); | 570 | iommu_free(tbl, dma_handle, npages); |
571 | } | ||
562 | } | 572 | } |
563 | 573 | ||
564 | /* Allocates a contiguous real buffer and creates mappings over it. | 574 | /* Allocates a contiguous real buffer and creates mappings over it. |
@@ -570,11 +580,11 @@ void *iommu_alloc_coherent(struct iommu_table *tbl, size_t size, | |||
570 | { | 580 | { |
571 | void *ret = NULL; | 581 | void *ret = NULL; |
572 | dma_addr_t mapping; | 582 | dma_addr_t mapping; |
573 | unsigned int npages, order; | 583 | unsigned int order; |
584 | unsigned int nio_pages, io_order; | ||
574 | struct page *page; | 585 | struct page *page; |
575 | 586 | ||
576 | size = PAGE_ALIGN(size); | 587 | size = PAGE_ALIGN(size); |
577 | npages = size >> PAGE_SHIFT; | ||
578 | order = get_order(size); | 588 | order = get_order(size); |
579 | 589 | ||
580 | /* | 590 | /* |
@@ -598,8 +608,10 @@ void *iommu_alloc_coherent(struct iommu_table *tbl, size_t size, | |||
598 | memset(ret, 0, size); | 608 | memset(ret, 0, size); |
599 | 609 | ||
600 | /* Set up tces to cover the allocated range */ | 610 | /* Set up tces to cover the allocated range */ |
601 | mapping = iommu_alloc(tbl, ret, npages, DMA_BIDIRECTIONAL, | 611 | nio_pages = size >> IOMMU_PAGE_SHIFT; |
602 | mask >> PAGE_SHIFT, order); | 612 | io_order = get_iommu_order(size); |
613 | mapping = iommu_alloc(tbl, ret, nio_pages, DMA_BIDIRECTIONAL, | ||
614 | mask >> IOMMU_PAGE_SHIFT, io_order); | ||
603 | if (mapping == DMA_ERROR_CODE) { | 615 | if (mapping == DMA_ERROR_CODE) { |
604 | free_pages((unsigned long)ret, order); | 616 | free_pages((unsigned long)ret, order); |
605 | return NULL; | 617 | return NULL; |
@@ -611,12 +623,13 @@ void *iommu_alloc_coherent(struct iommu_table *tbl, size_t size, | |||
611 | void iommu_free_coherent(struct iommu_table *tbl, size_t size, | 623 | void iommu_free_coherent(struct iommu_table *tbl, size_t size, |
612 | void *vaddr, dma_addr_t dma_handle) | 624 | void *vaddr, dma_addr_t dma_handle) |
613 | { | 625 | { |
614 | unsigned int npages; | ||
615 | |||
616 | if (tbl) { | 626 | if (tbl) { |
627 | unsigned int nio_pages; | ||
628 | |||
629 | size = PAGE_ALIGN(size); | ||
630 | nio_pages = size >> IOMMU_PAGE_SHIFT; | ||
631 | iommu_free(tbl, dma_handle, nio_pages); | ||
617 | size = PAGE_ALIGN(size); | 632 | size = PAGE_ALIGN(size); |
618 | npages = size >> PAGE_SHIFT; | ||
619 | iommu_free(tbl, dma_handle, npages); | ||
620 | free_pages((unsigned long)vaddr, get_order(size)); | 633 | free_pages((unsigned long)vaddr, get_order(size)); |
621 | } | 634 | } |
622 | } | 635 | } |
diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S index 88fd73fdf04..412bea3cf81 100644 --- a/arch/powerpc/kernel/misc_32.S +++ b/arch/powerpc/kernel/misc_32.S | |||
@@ -102,80 +102,6 @@ _GLOBAL(reloc_got2) | |||
102 | blr | 102 | blr |
103 | 103 | ||
104 | /* | 104 | /* |
105 | * identify_cpu, | ||
106 | * called with r3 = data offset and r4 = CPU number | ||
107 | * doesn't change r3 | ||
108 | */ | ||
109 | _GLOBAL(identify_cpu) | ||
110 | addis r8,r3,cpu_specs@ha | ||
111 | addi r8,r8,cpu_specs@l | ||
112 | mfpvr r7 | ||
113 | 1: | ||
114 | lwz r5,CPU_SPEC_PVR_MASK(r8) | ||
115 | and r5,r5,r7 | ||
116 | lwz r6,CPU_SPEC_PVR_VALUE(r8) | ||
117 | cmplw 0,r6,r5 | ||
118 | beq 1f | ||
119 | addi r8,r8,CPU_SPEC_ENTRY_SIZE | ||
120 | b 1b | ||
121 | 1: | ||
122 | addis r6,r3,cur_cpu_spec@ha | ||
123 | addi r6,r6,cur_cpu_spec@l | ||
124 | sub r8,r8,r3 | ||
125 | stw r8,0(r6) | ||
126 | blr | ||
127 | |||
128 | /* | ||
129 | * do_cpu_ftr_fixups - goes through the list of CPU feature fixups | ||
130 | * and writes nop's over sections of code that don't apply for this cpu. | ||
131 | * r3 = data offset (not changed) | ||
132 | */ | ||
133 | _GLOBAL(do_cpu_ftr_fixups) | ||
134 | /* Get CPU 0 features */ | ||
135 | addis r6,r3,cur_cpu_spec@ha | ||
136 | addi r6,r6,cur_cpu_spec@l | ||
137 | lwz r4,0(r6) | ||
138 | add r4,r4,r3 | ||
139 | lwz r4,CPU_SPEC_FEATURES(r4) | ||
140 | |||
141 | /* Get the fixup table */ | ||
142 | addis r6,r3,__start___ftr_fixup@ha | ||
143 | addi r6,r6,__start___ftr_fixup@l | ||
144 | addis r7,r3,__stop___ftr_fixup@ha | ||
145 | addi r7,r7,__stop___ftr_fixup@l | ||
146 | |||
147 | /* Do the fixup */ | ||
148 | 1: cmplw 0,r6,r7 | ||
149 | bgelr | ||
150 | addi r6,r6,16 | ||
151 | lwz r8,-16(r6) /* mask */ | ||
152 | and r8,r8,r4 | ||
153 | lwz r9,-12(r6) /* value */ | ||
154 | cmplw 0,r8,r9 | ||
155 | beq 1b | ||
156 | lwz r8,-8(r6) /* section begin */ | ||
157 | lwz r9,-4(r6) /* section end */ | ||
158 | subf. r9,r8,r9 | ||
159 | beq 1b | ||
160 | /* write nops over the section of code */ | ||
161 | /* todo: if large section, add a branch at the start of it */ | ||
162 | srwi r9,r9,2 | ||
163 | mtctr r9 | ||
164 | add r8,r8,r3 | ||
165 | lis r0,0x60000000@h /* nop */ | ||
166 | 3: stw r0,0(r8) | ||
167 | andi. r10,r4,CPU_FTR_SPLIT_ID_CACHE@l | ||
168 | beq 2f | ||
169 | dcbst 0,r8 /* suboptimal, but simpler */ | ||
170 | sync | ||
171 | icbi 0,r8 | ||
172 | 2: addi r8,r8,4 | ||
173 | bdnz 3b | ||
174 | sync /* additional sync needed on g4 */ | ||
175 | isync | ||
176 | b 1b | ||
177 | |||
178 | /* | ||
179 | * call_setup_cpu - call the setup_cpu function for this cpu | 105 | * call_setup_cpu - call the setup_cpu function for this cpu |
180 | * r3 = data offset, r24 = cpu number | 106 | * r3 = data offset, r24 = cpu number |
181 | * | 107 | * |
diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S index c70e20708a1..21fd2c662a9 100644 --- a/arch/powerpc/kernel/misc_64.S +++ b/arch/powerpc/kernel/misc_64.S | |||
@@ -246,130 +246,6 @@ _GLOBAL(__flush_dcache_icache) | |||
246 | isync | 246 | isync |
247 | blr | 247 | blr |
248 | 248 | ||
249 | /* | ||
250 | * identify_cpu and calls setup_cpu | ||
251 | * In: r3 = base of the cpu_specs array | ||
252 | * r4 = address of cur_cpu_spec | ||
253 | * r5 = relocation offset | ||
254 | */ | ||
255 | _GLOBAL(identify_cpu) | ||
256 | mfpvr r7 | ||
257 | 1: | ||
258 | lwz r8,CPU_SPEC_PVR_MASK(r3) | ||
259 | and r8,r8,r7 | ||
260 | lwz r9,CPU_SPEC_PVR_VALUE(r3) | ||
261 | cmplw 0,r9,r8 | ||
262 | beq 1f | ||
263 | addi r3,r3,CPU_SPEC_ENTRY_SIZE | ||
264 | b 1b | ||
265 | 1: | ||
266 | sub r0,r3,r5 | ||
267 | std r0,0(r4) | ||
268 | ld r4,CPU_SPEC_SETUP(r3) | ||
269 | cmpdi 0,r4,0 | ||
270 | add r4,r4,r5 | ||
271 | beqlr | ||
272 | ld r4,0(r4) | ||
273 | add r4,r4,r5 | ||
274 | mtctr r4 | ||
275 | /* Calling convention for cpu setup is r3=offset, r4=cur_cpu_spec */ | ||
276 | mr r4,r3 | ||
277 | mr r3,r5 | ||
278 | bctr | ||
279 | |||
280 | /* | ||
281 | * do_cpu_ftr_fixups - goes through the list of CPU feature fixups | ||
282 | * and writes nop's over sections of code that don't apply for this cpu. | ||
283 | * r3 = data offset (not changed) | ||
284 | */ | ||
285 | _GLOBAL(do_cpu_ftr_fixups) | ||
286 | /* Get CPU 0 features */ | ||
287 | LOAD_REG_IMMEDIATE(r6,cur_cpu_spec) | ||
288 | sub r6,r6,r3 | ||
289 | ld r4,0(r6) | ||
290 | sub r4,r4,r3 | ||
291 | ld r4,CPU_SPEC_FEATURES(r4) | ||
292 | /* Get the fixup table */ | ||
293 | LOAD_REG_IMMEDIATE(r6,__start___ftr_fixup) | ||
294 | sub r6,r6,r3 | ||
295 | LOAD_REG_IMMEDIATE(r7,__stop___ftr_fixup) | ||
296 | sub r7,r7,r3 | ||
297 | /* Do the fixup */ | ||
298 | 1: cmpld r6,r7 | ||
299 | bgelr | ||
300 | addi r6,r6,32 | ||
301 | ld r8,-32(r6) /* mask */ | ||
302 | and r8,r8,r4 | ||
303 | ld r9,-24(r6) /* value */ | ||
304 | cmpld r8,r9 | ||
305 | beq 1b | ||
306 | ld r8,-16(r6) /* section begin */ | ||
307 | ld r9,-8(r6) /* section end */ | ||
308 | subf. r9,r8,r9 | ||
309 | beq 1b | ||
310 | /* write nops over the section of code */ | ||
311 | /* todo: if large section, add a branch at the start of it */ | ||
312 | srwi r9,r9,2 | ||
313 | mtctr r9 | ||
314 | sub r8,r8,r3 | ||
315 | lis r0,0x60000000@h /* nop */ | ||
316 | 3: stw r0,0(r8) | ||
317 | andi. r10,r4,CPU_FTR_SPLIT_ID_CACHE@l | ||
318 | beq 2f | ||
319 | dcbst 0,r8 /* suboptimal, but simpler */ | ||
320 | sync | ||
321 | icbi 0,r8 | ||
322 | 2: addi r8,r8,4 | ||
323 | bdnz 3b | ||
324 | sync /* additional sync needed on g4 */ | ||
325 | isync | ||
326 | b 1b | ||
327 | |||
328 | /* | ||
329 | * do_fw_ftr_fixups - goes through the list of firmware feature fixups | ||
330 | * and writes nop's over sections of code that don't apply for this firmware. | ||
331 | * r3 = data offset (not changed) | ||
332 | */ | ||
333 | _GLOBAL(do_fw_ftr_fixups) | ||
334 | /* Get firmware features */ | ||
335 | LOAD_REG_IMMEDIATE(r6,powerpc_firmware_features) | ||
336 | sub r6,r6,r3 | ||
337 | ld r4,0(r6) | ||
338 | /* Get the fixup table */ | ||
339 | LOAD_REG_IMMEDIATE(r6,__start___fw_ftr_fixup) | ||
340 | sub r6,r6,r3 | ||
341 | LOAD_REG_IMMEDIATE(r7,__stop___fw_ftr_fixup) | ||
342 | sub r7,r7,r3 | ||
343 | /* Do the fixup */ | ||
344 | 1: cmpld r6,r7 | ||
345 | bgelr | ||
346 | addi r6,r6,32 | ||
347 | ld r8,-32(r6) /* mask */ | ||
348 | and r8,r8,r4 | ||
349 | ld r9,-24(r6) /* value */ | ||
350 | cmpld r8,r9 | ||
351 | beq 1b | ||
352 | ld r8,-16(r6) /* section begin */ | ||
353 | ld r9,-8(r6) /* section end */ | ||
354 | subf. r9,r8,r9 | ||
355 | beq 1b | ||
356 | /* write nops over the section of code */ | ||
357 | /* todo: if large section, add a branch at the start of it */ | ||
358 | srwi r9,r9,2 | ||
359 | mtctr r9 | ||
360 | sub r8,r8,r3 | ||
361 | lis r0,0x60000000@h /* nop */ | ||
362 | 3: stw r0,0(r8) | ||
363 | BEGIN_FTR_SECTION | ||
364 | dcbst 0,r8 /* suboptimal, but simpler */ | ||
365 | sync | ||
366 | icbi 0,r8 | ||
367 | END_FTR_SECTION_IFSET(CPU_FTR_SPLIT_ID_CACHE) | ||
368 | addi r8,r8,4 | ||
369 | bdnz 3b | ||
370 | sync /* additional sync needed on g4 */ | ||
371 | isync | ||
372 | b 1b | ||
373 | 249 | ||
374 | #if defined(CONFIG_PPC_PMAC) || defined(CONFIG_PPC_MAPLE) | 250 | #if defined(CONFIG_PPC_PMAC) || defined(CONFIG_PPC_MAPLE) |
375 | /* | 251 | /* |
diff --git a/arch/powerpc/kernel/module_32.c b/arch/powerpc/kernel/module_32.c index 92f4e5f64f0..e2c3c6a85f3 100644 --- a/arch/powerpc/kernel/module_32.c +++ b/arch/powerpc/kernel/module_32.c | |||
@@ -24,6 +24,8 @@ | |||
24 | #include <linux/kernel.h> | 24 | #include <linux/kernel.h> |
25 | #include <linux/cache.h> | 25 | #include <linux/cache.h> |
26 | 26 | ||
27 | #include "setup.h" | ||
28 | |||
27 | #if 0 | 29 | #if 0 |
28 | #define DEBUGP printk | 30 | #define DEBUGP printk |
29 | #else | 31 | #else |
@@ -269,33 +271,50 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, | |||
269 | return 0; | 271 | return 0; |
270 | } | 272 | } |
271 | 273 | ||
274 | static const Elf_Shdr *find_section(const Elf_Ehdr *hdr, | ||
275 | const Elf_Shdr *sechdrs, | ||
276 | const char *name) | ||
277 | { | ||
278 | char *secstrings; | ||
279 | unsigned int i; | ||
280 | |||
281 | secstrings = (char *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; | ||
282 | for (i = 1; i < hdr->e_shnum; i++) | ||
283 | if (strcmp(secstrings+sechdrs[i].sh_name, name) == 0) | ||
284 | return &sechdrs[i]; | ||
285 | return NULL; | ||
286 | } | ||
287 | |||
272 | int module_finalize(const Elf_Ehdr *hdr, | 288 | int module_finalize(const Elf_Ehdr *hdr, |
273 | const Elf_Shdr *sechdrs, | 289 | const Elf_Shdr *sechdrs, |
274 | struct module *me) | 290 | struct module *me) |
275 | { | 291 | { |
276 | char *secstrings; | 292 | const Elf_Shdr *sect; |
277 | unsigned int i; | ||
278 | 293 | ||
279 | me->arch.bug_table = NULL; | 294 | me->arch.bug_table = NULL; |
280 | me->arch.num_bugs = 0; | 295 | me->arch.num_bugs = 0; |
281 | 296 | ||
282 | /* Find the __bug_table section, if present */ | 297 | /* Find the __bug_table section, if present */ |
283 | secstrings = (char *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; | 298 | sect = find_section(hdr, sechdrs, "__bug_table"); |
284 | for (i = 1; i < hdr->e_shnum; i++) { | 299 | if (sect != NULL) { |
285 | if (strcmp(secstrings+sechdrs[i].sh_name, "__bug_table")) | 300 | me->arch.bug_table = (void *) sect->sh_addr; |
286 | continue; | 301 | me->arch.num_bugs = sect->sh_size / sizeof(struct bug_entry); |
287 | me->arch.bug_table = (void *) sechdrs[i].sh_addr; | ||
288 | me->arch.num_bugs = sechdrs[i].sh_size / sizeof(struct bug_entry); | ||
289 | break; | ||
290 | } | 302 | } |
291 | 303 | ||
292 | /* | 304 | /* |
293 | * Strictly speaking this should have a spinlock to protect against | 305 | * Strictly speaking this should have a spinlock to protect against |
294 | * traversals, but since we only traverse on BUG()s, a spinlock | 306 | * traversals, but since we only traverse on BUG()s, a spinlock |
295 | * could potentially lead to deadlock and thus be counter-productive. | 307 | * could potentially lead to deadlock and thus be counter-productive. |
296 | */ | 308 | */ |
297 | list_add(&me->arch.bug_list, &module_bug_list); | 309 | list_add(&me->arch.bug_list, &module_bug_list); |
298 | 310 | ||
311 | /* Apply feature fixups */ | ||
312 | sect = find_section(hdr, sechdrs, "__ftr_fixup"); | ||
313 | if (sect != NULL) | ||
314 | do_feature_fixups(cur_cpu_spec->cpu_features, | ||
315 | (void *)sect->sh_addr, | ||
316 | (void *)sect->sh_addr + sect->sh_size); | ||
317 | |||
299 | return 0; | 318 | return 0; |
300 | } | 319 | } |
301 | 320 | ||
diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c index ba34001fca8..8dd1f0aae5d 100644 --- a/arch/powerpc/kernel/module_64.c +++ b/arch/powerpc/kernel/module_64.c | |||
@@ -22,6 +22,9 @@ | |||
22 | #include <linux/vmalloc.h> | 22 | #include <linux/vmalloc.h> |
23 | #include <asm/module.h> | 23 | #include <asm/module.h> |
24 | #include <asm/uaccess.h> | 24 | #include <asm/uaccess.h> |
25 | #include <asm/firmware.h> | ||
26 | |||
27 | #include "setup.h" | ||
25 | 28 | ||
26 | /* FIXME: We don't do .init separately. To do this, we'd need to have | 29 | /* FIXME: We don't do .init separately. To do this, we'd need to have |
27 | a separate r2 value in the init and core section, and stub between | 30 | a separate r2 value in the init and core section, and stub between |
@@ -400,6 +403,11 @@ int apply_relocate_add(Elf64_Shdr *sechdrs, | |||
400 | | (value & 0x03fffffc); | 403 | | (value & 0x03fffffc); |
401 | break; | 404 | break; |
402 | 405 | ||
406 | case R_PPC64_REL64: | ||
407 | /* 64 bits relative (used by features fixups) */ | ||
408 | *location = value - (unsigned long)location; | ||
409 | break; | ||
410 | |||
403 | default: | 411 | default: |
404 | printk("%s: Unknown ADD relocation: %lu\n", | 412 | printk("%s: Unknown ADD relocation: %lu\n", |
405 | me->name, | 413 | me->name, |
@@ -413,23 +421,33 @@ int apply_relocate_add(Elf64_Shdr *sechdrs, | |||
413 | 421 | ||
414 | LIST_HEAD(module_bug_list); | 422 | LIST_HEAD(module_bug_list); |
415 | 423 | ||
416 | int module_finalize(const Elf_Ehdr *hdr, | 424 | static const Elf_Shdr *find_section(const Elf_Ehdr *hdr, |
417 | const Elf_Shdr *sechdrs, struct module *me) | 425 | const Elf_Shdr *sechdrs, |
426 | const char *name) | ||
418 | { | 427 | { |
419 | char *secstrings; | 428 | char *secstrings; |
420 | unsigned int i; | 429 | unsigned int i; |
421 | 430 | ||
431 | secstrings = (char *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; | ||
432 | for (i = 1; i < hdr->e_shnum; i++) | ||
433 | if (strcmp(secstrings+sechdrs[i].sh_name, name) == 0) | ||
434 | return &sechdrs[i]; | ||
435 | return NULL; | ||
436 | } | ||
437 | |||
438 | int module_finalize(const Elf_Ehdr *hdr, | ||
439 | const Elf_Shdr *sechdrs, struct module *me) | ||
440 | { | ||
441 | const Elf_Shdr *sect; | ||
442 | |||
422 | me->arch.bug_table = NULL; | 443 | me->arch.bug_table = NULL; |
423 | me->arch.num_bugs = 0; | 444 | me->arch.num_bugs = 0; |
424 | 445 | ||
425 | /* Find the __bug_table section, if present */ | 446 | /* Find the __bug_table section, if present */ |
426 | secstrings = (char *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; | 447 | sect = find_section(hdr, sechdrs, "__bug_table"); |
427 | for (i = 1; i < hdr->e_shnum; i++) { | 448 | if (sect != NULL) { |
428 | if (strcmp(secstrings+sechdrs[i].sh_name, "__bug_table")) | 449 | me->arch.bug_table = (void *) sect->sh_addr; |
429 | continue; | 450 | me->arch.num_bugs = sect->sh_size / sizeof(struct bug_entry); |
430 | me->arch.bug_table = (void *) sechdrs[i].sh_addr; | ||
431 | me->arch.num_bugs = sechdrs[i].sh_size / sizeof(struct bug_entry); | ||
432 | break; | ||
433 | } | 451 | } |
434 | 452 | ||
435 | /* | 453 | /* |
@@ -439,6 +457,19 @@ int module_finalize(const Elf_Ehdr *hdr, | |||
439 | */ | 457 | */ |
440 | list_add(&me->arch.bug_list, &module_bug_list); | 458 | list_add(&me->arch.bug_list, &module_bug_list); |
441 | 459 | ||
460 | /* Apply feature fixups */ | ||
461 | sect = find_section(hdr, sechdrs, "__ftr_fixup"); | ||
462 | if (sect != NULL) | ||
463 | do_feature_fixups(cur_cpu_spec->cpu_features, | ||
464 | (void *)sect->sh_addr, | ||
465 | (void *)sect->sh_addr + sect->sh_size); | ||
466 | |||
467 | sect = find_section(hdr, sechdrs, "__fw_ftr_fixup"); | ||
468 | if (sect != NULL) | ||
469 | do_feature_fixups(powerpc_firmware_features, | ||
470 | (void *)sect->sh_addr, | ||
471 | (void *)sect->sh_addr + sect->sh_size); | ||
472 | |||
442 | return 0; | 473 | return 0; |
443 | } | 474 | } |
444 | 475 | ||
diff --git a/arch/powerpc/kernel/perfmon_fsl_booke.c b/arch/powerpc/kernel/perfmon_fsl_booke.c deleted file mode 100644 index e0dcf2b41fb..00000000000 --- a/arch/powerpc/kernel/perfmon_fsl_booke.c +++ /dev/null | |||
@@ -1,221 +0,0 @@ | |||
1 | /* arch/powerpc/kernel/perfmon_fsl_booke.c | ||
2 | * Freescale Book-E Performance Monitor code | ||
3 | * | ||
4 | * Author: Andy Fleming | ||
5 | * Copyright (c) 2004 Freescale Semiconductor, Inc | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License | ||
9 | * as published by the Free Software Foundation; either version | ||
10 | * 2 of the License, or (at your option) any later version. | ||
11 | */ | ||
12 | |||
13 | #include <linux/errno.h> | ||
14 | #include <linux/sched.h> | ||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/mm.h> | ||
17 | #include <linux/stddef.h> | ||
18 | #include <linux/unistd.h> | ||
19 | #include <linux/ptrace.h> | ||
20 | #include <linux/slab.h> | ||
21 | #include <linux/user.h> | ||
22 | #include <linux/a.out.h> | ||
23 | #include <linux/interrupt.h> | ||
24 | #include <linux/init.h> | ||
25 | #include <linux/module.h> | ||
26 | #include <linux/prctl.h> | ||
27 | |||
28 | #include <asm/pgtable.h> | ||
29 | #include <asm/uaccess.h> | ||
30 | #include <asm/system.h> | ||
31 | #include <asm/io.h> | ||
32 | #include <asm/reg.h> | ||
33 | #include <asm/xmon.h> | ||
34 | #include <asm/pmc.h> | ||
35 | |||
36 | static inline u32 get_pmlca(int ctr); | ||
37 | static inline void set_pmlca(int ctr, u32 pmlca); | ||
38 | |||
39 | static inline u32 get_pmlca(int ctr) | ||
40 | { | ||
41 | u32 pmlca; | ||
42 | |||
43 | switch (ctr) { | ||
44 | case 0: | ||
45 | pmlca = mfpmr(PMRN_PMLCA0); | ||
46 | break; | ||
47 | case 1: | ||
48 | pmlca = mfpmr(PMRN_PMLCA1); | ||
49 | break; | ||
50 | case 2: | ||
51 | pmlca = mfpmr(PMRN_PMLCA2); | ||
52 | break; | ||
53 | case 3: | ||
54 | pmlca = mfpmr(PMRN_PMLCA3); | ||
55 | break; | ||
56 | default: | ||
57 | panic("Bad ctr number\n"); | ||
58 | } | ||
59 | |||
60 | return pmlca; | ||
61 | } | ||
62 | |||
63 | static inline void set_pmlca(int ctr, u32 pmlca) | ||
64 | { | ||
65 | switch (ctr) { | ||
66 | case 0: | ||
67 | mtpmr(PMRN_PMLCA0, pmlca); | ||
68 | break; | ||
69 | case 1: | ||
70 | mtpmr(PMRN_PMLCA1, pmlca); | ||
71 | break; | ||
72 | case 2: | ||
73 | mtpmr(PMRN_PMLCA2, pmlca); | ||
74 | break; | ||
75 | case 3: | ||
76 | mtpmr(PMRN_PMLCA3, pmlca); | ||
77 | break; | ||
78 | default: | ||
79 | panic("Bad ctr number\n"); | ||
80 | } | ||
81 | } | ||
82 | |||
83 | void init_pmc_stop(int ctr) | ||
84 | { | ||
85 | u32 pmlca = (PMLCA_FC | PMLCA_FCS | PMLCA_FCU | | ||
86 | PMLCA_FCM1 | PMLCA_FCM0); | ||
87 | u32 pmlcb = 0; | ||
88 | |||
89 | switch (ctr) { | ||
90 | case 0: | ||
91 | mtpmr(PMRN_PMLCA0, pmlca); | ||
92 | mtpmr(PMRN_PMLCB0, pmlcb); | ||
93 | break; | ||
94 | case 1: | ||
95 | mtpmr(PMRN_PMLCA1, pmlca); | ||
96 | mtpmr(PMRN_PMLCB1, pmlcb); | ||
97 | break; | ||
98 | case 2: | ||
99 | mtpmr(PMRN_PMLCA2, pmlca); | ||
100 | mtpmr(PMRN_PMLCB2, pmlcb); | ||
101 | break; | ||
102 | case 3: | ||
103 | mtpmr(PMRN_PMLCA3, pmlca); | ||
104 | mtpmr(PMRN_PMLCB3, pmlcb); | ||
105 | break; | ||
106 | default: | ||
107 | panic("Bad ctr number!\n"); | ||
108 | } | ||
109 | } | ||
110 | |||
111 | void set_pmc_event(int ctr, int event) | ||
112 | { | ||
113 | u32 pmlca; | ||
114 | |||
115 | pmlca = get_pmlca(ctr); | ||
116 | |||
117 | pmlca = (pmlca & ~PMLCA_EVENT_MASK) | | ||
118 | ((event << PMLCA_EVENT_SHIFT) & | ||
119 | PMLCA_EVENT_MASK); | ||
120 | |||
121 | set_pmlca(ctr, pmlca); | ||
122 | } | ||
123 | |||
124 | void set_pmc_user_kernel(int ctr, int user, int kernel) | ||
125 | { | ||
126 | u32 pmlca; | ||
127 | |||
128 | pmlca = get_pmlca(ctr); | ||
129 | |||
130 | if(user) | ||
131 | pmlca &= ~PMLCA_FCU; | ||
132 | else | ||
133 | pmlca |= PMLCA_FCU; | ||
134 | |||
135 | if(kernel) | ||
136 | pmlca &= ~PMLCA_FCS; | ||
137 | else | ||
138 | pmlca |= PMLCA_FCS; | ||
139 | |||
140 | set_pmlca(ctr, pmlca); | ||
141 | } | ||
142 | |||
143 | void set_pmc_marked(int ctr, int mark0, int mark1) | ||
144 | { | ||
145 | u32 pmlca = get_pmlca(ctr); | ||
146 | |||
147 | if(mark0) | ||
148 | pmlca &= ~PMLCA_FCM0; | ||
149 | else | ||
150 | pmlca |= PMLCA_FCM0; | ||
151 | |||
152 | if(mark1) | ||
153 | pmlca &= ~PMLCA_FCM1; | ||
154 | else | ||
155 | pmlca |= PMLCA_FCM1; | ||
156 | |||
157 | set_pmlca(ctr, pmlca); | ||
158 | } | ||
159 | |||
160 | void pmc_start_ctr(int ctr, int enable) | ||
161 | { | ||
162 | u32 pmlca = get_pmlca(ctr); | ||
163 | |||
164 | pmlca &= ~PMLCA_FC; | ||
165 | |||
166 | if (enable) | ||
167 | pmlca |= PMLCA_CE; | ||
168 | else | ||
169 | pmlca &= ~PMLCA_CE; | ||
170 | |||
171 | set_pmlca(ctr, pmlca); | ||
172 | } | ||
173 | |||
174 | void pmc_start_ctrs(int enable) | ||
175 | { | ||
176 | u32 pmgc0 = mfpmr(PMRN_PMGC0); | ||
177 | |||
178 | pmgc0 &= ~PMGC0_FAC; | ||
179 | pmgc0 |= PMGC0_FCECE; | ||
180 | |||
181 | if (enable) | ||
182 | pmgc0 |= PMGC0_PMIE; | ||
183 | else | ||
184 | pmgc0 &= ~PMGC0_PMIE; | ||
185 | |||
186 | mtpmr(PMRN_PMGC0, pmgc0); | ||
187 | } | ||
188 | |||
189 | void pmc_stop_ctrs(void) | ||
190 | { | ||
191 | u32 pmgc0 = mfpmr(PMRN_PMGC0); | ||
192 | |||
193 | pmgc0 |= PMGC0_FAC; | ||
194 | |||
195 | pmgc0 &= ~(PMGC0_PMIE | PMGC0_FCECE); | ||
196 | |||
197 | mtpmr(PMRN_PMGC0, pmgc0); | ||
198 | } | ||
199 | |||
200 | void dump_pmcs(void) | ||
201 | { | ||
202 | printk("pmgc0: %x\n", mfpmr(PMRN_PMGC0)); | ||
203 | printk("pmc\t\tpmlca\t\tpmlcb\n"); | ||
204 | printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC0), | ||
205 | mfpmr(PMRN_PMLCA0), mfpmr(PMRN_PMLCB0)); | ||
206 | printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC1), | ||
207 | mfpmr(PMRN_PMLCA1), mfpmr(PMRN_PMLCB1)); | ||
208 | printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC2), | ||
209 | mfpmr(PMRN_PMLCA2), mfpmr(PMRN_PMLCB2)); | ||
210 | printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC3), | ||
211 | mfpmr(PMRN_PMLCA3), mfpmr(PMRN_PMLCB3)); | ||
212 | } | ||
213 | |||
214 | EXPORT_SYMBOL(init_pmc_stop); | ||
215 | EXPORT_SYMBOL(set_pmc_event); | ||
216 | EXPORT_SYMBOL(set_pmc_user_kernel); | ||
217 | EXPORT_SYMBOL(set_pmc_marked); | ||
218 | EXPORT_SYMBOL(pmc_start_ctr); | ||
219 | EXPORT_SYMBOL(pmc_start_ctrs); | ||
220 | EXPORT_SYMBOL(pmc_stop_ctrs); | ||
221 | EXPORT_SYMBOL(dump_pmcs); | ||
diff --git a/arch/powerpc/kernel/pmc.c b/arch/powerpc/kernel/pmc.c index a0a2efadeab..3d8f6f44641 100644 --- a/arch/powerpc/kernel/pmc.c +++ b/arch/powerpc/kernel/pmc.c | |||
@@ -71,7 +71,7 @@ int reserve_pmc_hardware(perf_irq_t new_perf_irq) | |||
71 | } | 71 | } |
72 | 72 | ||
73 | pmc_owner_caller = __builtin_return_address(0); | 73 | pmc_owner_caller = __builtin_return_address(0); |
74 | perf_irq = new_perf_irq ? : dummy_perf; | 74 | perf_irq = new_perf_irq ? new_perf_irq : dummy_perf; |
75 | 75 | ||
76 | out: | 76 | out: |
77 | spin_unlock(&pmc_owner_lock); | 77 | spin_unlock(&pmc_owner_lock); |
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index f8e44c029d9..16d29d16b96 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c | |||
@@ -1014,7 +1014,7 @@ EXPORT_SYMBOL(find_all_nodes); | |||
1014 | /** Checks if the given "compat" string matches one of the strings in | 1014 | /** Checks if the given "compat" string matches one of the strings in |
1015 | * the device's "compatible" property | 1015 | * the device's "compatible" property |
1016 | */ | 1016 | */ |
1017 | int device_is_compatible(struct device_node *device, const char *compat) | 1017 | int device_is_compatible(const struct device_node *device, const char *compat) |
1018 | { | 1018 | { |
1019 | const char* cp; | 1019 | const char* cp; |
1020 | int cplen, l; | 1020 | int cplen, l; |
@@ -1491,7 +1491,8 @@ static int __init prom_reconfig_setup(void) | |||
1491 | __initcall(prom_reconfig_setup); | 1491 | __initcall(prom_reconfig_setup); |
1492 | #endif | 1492 | #endif |
1493 | 1493 | ||
1494 | struct property *of_find_property(struct device_node *np, const char *name, | 1494 | struct property *of_find_property(const struct device_node *np, |
1495 | const char *name, | ||
1495 | int *lenp) | 1496 | int *lenp) |
1496 | { | 1497 | { |
1497 | struct property *pp; | 1498 | struct property *pp; |
@@ -1512,7 +1513,8 @@ struct property *of_find_property(struct device_node *np, const char *name, | |||
1512 | * Find a property with a given name for a given node | 1513 | * Find a property with a given name for a given node |
1513 | * and return the value. | 1514 | * and return the value. |
1514 | */ | 1515 | */ |
1515 | const void *get_property(struct device_node *np, const char *name, int *lenp) | 1516 | const void *get_property(const struct device_node *np, const char *name, |
1517 | int *lenp) | ||
1516 | { | 1518 | { |
1517 | struct property *pp = of_find_property(np,name,lenp); | 1519 | struct property *pp = of_find_property(np,name,lenp); |
1518 | return pp ? pp->value : NULL; | 1520 | return pp ? pp->value : NULL; |
diff --git a/arch/powerpc/kernel/rtas_flash.c b/arch/powerpc/kernel/rtas_flash.c index 1442b63a75d..6f6fc977cb3 100644 --- a/arch/powerpc/kernel/rtas_flash.c +++ b/arch/powerpc/kernel/rtas_flash.c | |||
@@ -72,6 +72,10 @@ | |||
72 | #define VALIDATE_BUF_SIZE 4096 | 72 | #define VALIDATE_BUF_SIZE 4096 |
73 | #define RTAS_MSG_MAXLEN 64 | 73 | #define RTAS_MSG_MAXLEN 64 |
74 | 74 | ||
75 | /* Quirk - RTAS requires 4k list length and block size */ | ||
76 | #define RTAS_BLKLIST_LENGTH 4096 | ||
77 | #define RTAS_BLK_SIZE 4096 | ||
78 | |||
75 | struct flash_block { | 79 | struct flash_block { |
76 | char *data; | 80 | char *data; |
77 | unsigned long length; | 81 | unsigned long length; |
@@ -83,7 +87,7 @@ struct flash_block { | |||
83 | * into a version/length and translate the pointers | 87 | * into a version/length and translate the pointers |
84 | * to absolute. | 88 | * to absolute. |
85 | */ | 89 | */ |
86 | #define FLASH_BLOCKS_PER_NODE ((PAGE_SIZE - 16) / sizeof(struct flash_block)) | 90 | #define FLASH_BLOCKS_PER_NODE ((RTAS_BLKLIST_LENGTH - 16) / sizeof(struct flash_block)) |
87 | struct flash_block_list { | 91 | struct flash_block_list { |
88 | unsigned long num_blocks; | 92 | unsigned long num_blocks; |
89 | struct flash_block_list *next; | 93 | struct flash_block_list *next; |
@@ -96,6 +100,9 @@ struct flash_block_list_header { /* just the header of flash_block_list */ | |||
96 | 100 | ||
97 | static struct flash_block_list_header rtas_firmware_flash_list = {0, NULL}; | 101 | static struct flash_block_list_header rtas_firmware_flash_list = {0, NULL}; |
98 | 102 | ||
103 | /* Use slab cache to guarantee 4k alignment */ | ||
104 | static kmem_cache_t *flash_block_cache = NULL; | ||
105 | |||
99 | #define FLASH_BLOCK_LIST_VERSION (1UL) | 106 | #define FLASH_BLOCK_LIST_VERSION (1UL) |
100 | 107 | ||
101 | /* Local copy of the flash block list. | 108 | /* Local copy of the flash block list. |
@@ -153,7 +160,7 @@ static int flash_list_valid(struct flash_block_list *flist) | |||
153 | return FLASH_IMG_NULL_DATA; | 160 | return FLASH_IMG_NULL_DATA; |
154 | } | 161 | } |
155 | block_size = f->blocks[i].length; | 162 | block_size = f->blocks[i].length; |
156 | if (block_size <= 0 || block_size > PAGE_SIZE) { | 163 | if (block_size <= 0 || block_size > RTAS_BLK_SIZE) { |
157 | return FLASH_IMG_BAD_LEN; | 164 | return FLASH_IMG_BAD_LEN; |
158 | } | 165 | } |
159 | image_size += block_size; | 166 | image_size += block_size; |
@@ -177,9 +184,9 @@ static void free_flash_list(struct flash_block_list *f) | |||
177 | 184 | ||
178 | while (f) { | 185 | while (f) { |
179 | for (i = 0; i < f->num_blocks; i++) | 186 | for (i = 0; i < f->num_blocks; i++) |
180 | free_page((unsigned long)(f->blocks[i].data)); | 187 | kmem_cache_free(flash_block_cache, f->blocks[i].data); |
181 | next = f->next; | 188 | next = f->next; |
182 | free_page((unsigned long)f); | 189 | kmem_cache_free(flash_block_cache, f); |
183 | f = next; | 190 | f = next; |
184 | } | 191 | } |
185 | } | 192 | } |
@@ -278,6 +285,12 @@ static ssize_t rtas_flash_read(struct file *file, char __user *buf, | |||
278 | return msglen; | 285 | return msglen; |
279 | } | 286 | } |
280 | 287 | ||
288 | /* constructor for flash_block_cache */ | ||
289 | void rtas_block_ctor(void *ptr, kmem_cache_t *cache, unsigned long flags) | ||
290 | { | ||
291 | memset(ptr, 0, RTAS_BLK_SIZE); | ||
292 | } | ||
293 | |||
281 | /* We could be much more efficient here. But to keep this function | 294 | /* We could be much more efficient here. But to keep this function |
282 | * simple we allocate a page to the block list no matter how small the | 295 | * simple we allocate a page to the block list no matter how small the |
283 | * count is. If the system is low on memory it will be just as well | 296 | * count is. If the system is low on memory it will be just as well |
@@ -302,7 +315,7 @@ static ssize_t rtas_flash_write(struct file *file, const char __user *buffer, | |||
302 | * proc file | 315 | * proc file |
303 | */ | 316 | */ |
304 | if (uf->flist == NULL) { | 317 | if (uf->flist == NULL) { |
305 | uf->flist = (struct flash_block_list *) get_zeroed_page(GFP_KERNEL); | 318 | uf->flist = kmem_cache_alloc(flash_block_cache, GFP_KERNEL); |
306 | if (!uf->flist) | 319 | if (!uf->flist) |
307 | return -ENOMEM; | 320 | return -ENOMEM; |
308 | } | 321 | } |
@@ -313,21 +326,21 @@ static ssize_t rtas_flash_write(struct file *file, const char __user *buffer, | |||
313 | next_free = fl->num_blocks; | 326 | next_free = fl->num_blocks; |
314 | if (next_free == FLASH_BLOCKS_PER_NODE) { | 327 | if (next_free == FLASH_BLOCKS_PER_NODE) { |
315 | /* Need to allocate another block_list */ | 328 | /* Need to allocate another block_list */ |
316 | fl->next = (struct flash_block_list *)get_zeroed_page(GFP_KERNEL); | 329 | fl->next = kmem_cache_alloc(flash_block_cache, GFP_KERNEL); |
317 | if (!fl->next) | 330 | if (!fl->next) |
318 | return -ENOMEM; | 331 | return -ENOMEM; |
319 | fl = fl->next; | 332 | fl = fl->next; |
320 | next_free = 0; | 333 | next_free = 0; |
321 | } | 334 | } |
322 | 335 | ||
323 | if (count > PAGE_SIZE) | 336 | if (count > RTAS_BLK_SIZE) |
324 | count = PAGE_SIZE; | 337 | count = RTAS_BLK_SIZE; |
325 | p = (char *)get_zeroed_page(GFP_KERNEL); | 338 | p = kmem_cache_alloc(flash_block_cache, GFP_KERNEL); |
326 | if (!p) | 339 | if (!p) |
327 | return -ENOMEM; | 340 | return -ENOMEM; |
328 | 341 | ||
329 | if(copy_from_user(p, buffer, count)) { | 342 | if(copy_from_user(p, buffer, count)) { |
330 | free_page((unsigned long)p); | 343 | kmem_cache_free(flash_block_cache, p); |
331 | return -EFAULT; | 344 | return -EFAULT; |
332 | } | 345 | } |
333 | fl->blocks[next_free].data = p; | 346 | fl->blocks[next_free].data = p; |
@@ -791,6 +804,16 @@ int __init rtas_flash_init(void) | |||
791 | goto cleanup; | 804 | goto cleanup; |
792 | 805 | ||
793 | rtas_flash_term_hook = rtas_flash_firmware; | 806 | rtas_flash_term_hook = rtas_flash_firmware; |
807 | |||
808 | flash_block_cache = kmem_cache_create("rtas_flash_cache", | ||
809 | RTAS_BLK_SIZE, RTAS_BLK_SIZE, 0, | ||
810 | rtas_block_ctor, NULL); | ||
811 | if (!flash_block_cache) { | ||
812 | printk(KERN_ERR "%s: failed to create block cache\n", | ||
813 | __FUNCTION__); | ||
814 | rc = -ENOMEM; | ||
815 | goto cleanup; | ||
816 | } | ||
794 | return 0; | 817 | return 0; |
795 | 818 | ||
796 | cleanup: | 819 | cleanup: |
@@ -805,6 +828,10 @@ cleanup: | |||
805 | void __exit rtas_flash_cleanup(void) | 828 | void __exit rtas_flash_cleanup(void) |
806 | { | 829 | { |
807 | rtas_flash_term_hook = NULL; | 830 | rtas_flash_term_hook = NULL; |
831 | |||
832 | if (flash_block_cache) | ||
833 | kmem_cache_destroy(flash_block_cache); | ||
834 | |||
808 | remove_flash_pde(firmware_flash_pde); | 835 | remove_flash_pde(firmware_flash_pde); |
809 | remove_flash_pde(firmware_update_pde); | 836 | remove_flash_pde(firmware_update_pde); |
810 | remove_flash_pde(validate_pde); | 837 | remove_flash_pde(validate_pde); |
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index 517ed1b1b16..04df53a3c86 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c | |||
@@ -87,6 +87,7 @@ int ucache_bsize; | |||
87 | unsigned long __init early_init(unsigned long dt_ptr) | 87 | unsigned long __init early_init(unsigned long dt_ptr) |
88 | { | 88 | { |
89 | unsigned long offset = reloc_offset(); | 89 | unsigned long offset = reloc_offset(); |
90 | struct cpu_spec *spec; | ||
90 | 91 | ||
91 | /* First zero the BSS -- use memset_io, some platforms don't have | 92 | /* First zero the BSS -- use memset_io, some platforms don't have |
92 | * caches on yet */ | 93 | * caches on yet */ |
@@ -96,8 +97,11 @@ unsigned long __init early_init(unsigned long dt_ptr) | |||
96 | * Identify the CPU type and fix up code sections | 97 | * Identify the CPU type and fix up code sections |
97 | * that depend on which cpu we have. | 98 | * that depend on which cpu we have. |
98 | */ | 99 | */ |
99 | identify_cpu(offset, 0); | 100 | spec = identify_cpu(offset); |
100 | do_cpu_ftr_fixups(offset); | 101 | |
102 | do_feature_fixups(spec->cpu_features, | ||
103 | PTRRELOC(&__start___ftr_fixup), | ||
104 | PTRRELOC(&__stop___ftr_fixup)); | ||
101 | 105 | ||
102 | return KERNELBASE + offset; | 106 | return KERNELBASE + offset; |
103 | } | 107 | } |
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index 2fef772edfc..b0f1c82df99 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c | |||
@@ -169,6 +169,9 @@ void __init setup_paca(int cpu) | |||
169 | 169 | ||
170 | void __init early_setup(unsigned long dt_ptr) | 170 | void __init early_setup(unsigned long dt_ptr) |
171 | { | 171 | { |
172 | /* Identify CPU type */ | ||
173 | identify_cpu(0); | ||
174 | |||
172 | /* Assume we're on cpu 0 for now. Don't write to the paca yet! */ | 175 | /* Assume we're on cpu 0 for now. Don't write to the paca yet! */ |
173 | setup_paca(0); | 176 | setup_paca(0); |
174 | 177 | ||
@@ -347,6 +350,14 @@ void __init setup_system(void) | |||
347 | { | 350 | { |
348 | DBG(" -> setup_system()\n"); | 351 | DBG(" -> setup_system()\n"); |
349 | 352 | ||
353 | /* Apply the CPUs-specific and firmware specific fixups to kernel | ||
354 | * text (nop out sections not relevant to this CPU or this firmware) | ||
355 | */ | ||
356 | do_feature_fixups(cur_cpu_spec->cpu_features, | ||
357 | &__start___ftr_fixup, &__stop___ftr_fixup); | ||
358 | do_feature_fixups(powerpc_firmware_features, | ||
359 | &__start___fw_ftr_fixup, &__stop___fw_ftr_fixup); | ||
360 | |||
350 | /* | 361 | /* |
351 | * Unflatten the device-tree passed by prom_init or kexec | 362 | * Unflatten the device-tree passed by prom_init or kexec |
352 | */ | 363 | */ |
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index 5b59bc18dfe..46a24de36fe 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c | |||
@@ -220,11 +220,8 @@ static void account_process_time(struct pt_regs *regs) | |||
220 | */ | 220 | */ |
221 | struct cpu_purr_data { | 221 | struct cpu_purr_data { |
222 | int initialized; /* thread is running */ | 222 | int initialized; /* thread is running */ |
223 | u64 tb0; /* timebase at origin time */ | ||
224 | u64 purr0; /* PURR at origin time */ | ||
225 | u64 tb; /* last TB value read */ | 223 | u64 tb; /* last TB value read */ |
226 | u64 purr; /* last PURR value read */ | 224 | u64 purr; /* last PURR value read */ |
227 | u64 stolen; /* stolen time so far */ | ||
228 | spinlock_t lock; | 225 | spinlock_t lock; |
229 | }; | 226 | }; |
230 | 227 | ||
@@ -234,10 +231,8 @@ static void snapshot_tb_and_purr(void *data) | |||
234 | { | 231 | { |
235 | struct cpu_purr_data *p = &__get_cpu_var(cpu_purr_data); | 232 | struct cpu_purr_data *p = &__get_cpu_var(cpu_purr_data); |
236 | 233 | ||
237 | p->tb0 = mftb(); | 234 | p->tb = mftb(); |
238 | p->purr0 = mfspr(SPRN_PURR); | 235 | p->purr = mfspr(SPRN_PURR); |
239 | p->tb = p->tb0; | ||
240 | p->purr = 0; | ||
241 | wmb(); | 236 | wmb(); |
242 | p->initialized = 1; | 237 | p->initialized = 1; |
243 | } | 238 | } |
@@ -258,37 +253,24 @@ void snapshot_timebases(void) | |||
258 | 253 | ||
259 | void calculate_steal_time(void) | 254 | void calculate_steal_time(void) |
260 | { | 255 | { |
261 | u64 tb, purr, t0; | 256 | u64 tb, purr; |
262 | s64 stolen; | 257 | s64 stolen; |
263 | struct cpu_purr_data *p0, *pme, *phim; | 258 | struct cpu_purr_data *pme; |
264 | int cpu; | ||
265 | 259 | ||
266 | if (!cpu_has_feature(CPU_FTR_PURR)) | 260 | if (!cpu_has_feature(CPU_FTR_PURR)) |
267 | return; | 261 | return; |
268 | cpu = smp_processor_id(); | 262 | pme = &per_cpu(cpu_purr_data, smp_processor_id()); |
269 | pme = &per_cpu(cpu_purr_data, cpu); | ||
270 | if (!pme->initialized) | 263 | if (!pme->initialized) |
271 | return; /* this can happen in early boot */ | 264 | return; /* this can happen in early boot */ |
272 | p0 = &per_cpu(cpu_purr_data, cpu & ~1); | 265 | spin_lock(&pme->lock); |
273 | phim = &per_cpu(cpu_purr_data, cpu ^ 1); | ||
274 | spin_lock(&p0->lock); | ||
275 | tb = mftb(); | 266 | tb = mftb(); |
276 | purr = mfspr(SPRN_PURR) - pme->purr0; | 267 | purr = mfspr(SPRN_PURR); |
277 | if (!phim->initialized || !cpu_online(cpu ^ 1)) { | 268 | stolen = (tb - pme->tb) - (purr - pme->purr); |
278 | stolen = (tb - pme->tb) - (purr - pme->purr); | 269 | if (stolen > 0) |
279 | } else { | ||
280 | t0 = pme->tb0; | ||
281 | if (phim->tb0 < t0) | ||
282 | t0 = phim->tb0; | ||
283 | stolen = phim->tb - t0 - phim->purr - purr - p0->stolen; | ||
284 | } | ||
285 | if (stolen > 0) { | ||
286 | account_steal_time(current, stolen); | 270 | account_steal_time(current, stolen); |
287 | p0->stolen += stolen; | ||
288 | } | ||
289 | pme->tb = tb; | 271 | pme->tb = tb; |
290 | pme->purr = purr; | 272 | pme->purr = purr; |
291 | spin_unlock(&p0->lock); | 273 | spin_unlock(&pme->lock); |
292 | } | 274 | } |
293 | 275 | ||
294 | /* | 276 | /* |
@@ -297,30 +279,17 @@ void calculate_steal_time(void) | |||
297 | */ | 279 | */ |
298 | static void snapshot_purr(void) | 280 | static void snapshot_purr(void) |
299 | { | 281 | { |
300 | int cpu; | 282 | struct cpu_purr_data *pme; |
301 | u64 purr; | ||
302 | struct cpu_purr_data *p0, *pme, *phim; | ||
303 | unsigned long flags; | 283 | unsigned long flags; |
304 | 284 | ||
305 | if (!cpu_has_feature(CPU_FTR_PURR)) | 285 | if (!cpu_has_feature(CPU_FTR_PURR)) |
306 | return; | 286 | return; |
307 | cpu = smp_processor_id(); | 287 | pme = &per_cpu(cpu_purr_data, smp_processor_id()); |
308 | pme = &per_cpu(cpu_purr_data, cpu); | 288 | spin_lock_irqsave(&pme->lock, flags); |
309 | p0 = &per_cpu(cpu_purr_data, cpu & ~1); | 289 | pme->tb = mftb(); |
310 | phim = &per_cpu(cpu_purr_data, cpu ^ 1); | 290 | pme->purr = mfspr(SPRN_PURR); |
311 | spin_lock_irqsave(&p0->lock, flags); | ||
312 | pme->tb = pme->tb0 = mftb(); | ||
313 | purr = mfspr(SPRN_PURR); | ||
314 | if (!phim->initialized) { | ||
315 | pme->purr = 0; | ||
316 | pme->purr0 = purr; | ||
317 | } else { | ||
318 | /* set p->purr and p->purr0 for no change in p0->stolen */ | ||
319 | pme->purr = phim->tb - phim->tb0 - phim->purr - p0->stolen; | ||
320 | pme->purr0 = purr - pme->purr; | ||
321 | } | ||
322 | pme->initialized = 1; | 291 | pme->initialized = 1; |
323 | spin_unlock_irqrestore(&p0->lock, flags); | 292 | spin_unlock_irqrestore(&pme->lock, flags); |
324 | } | 293 | } |
325 | 294 | ||
326 | #endif /* CONFIG_PPC_SPLPAR */ | 295 | #endif /* CONFIG_PPC_SPLPAR */ |
@@ -1045,48 +1014,6 @@ void __init time_init(void) | |||
1045 | set_dec(tb_ticks_per_jiffy); | 1014 | set_dec(tb_ticks_per_jiffy); |
1046 | } | 1015 | } |
1047 | 1016 | ||
1048 | #ifdef CONFIG_RTC_CLASS | ||
1049 | static int set_rtc_class_time(struct rtc_time *tm) | ||
1050 | { | ||
1051 | int err; | ||
1052 | struct class_device *class_dev = | ||
1053 | rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE); | ||
1054 | |||
1055 | if (class_dev == NULL) | ||
1056 | return -ENODEV; | ||
1057 | |||
1058 | err = rtc_set_time(class_dev, tm); | ||
1059 | |||
1060 | rtc_class_close(class_dev); | ||
1061 | |||
1062 | return 0; | ||
1063 | } | ||
1064 | |||
1065 | static void get_rtc_class_time(struct rtc_time *tm) | ||
1066 | { | ||
1067 | int err; | ||
1068 | struct class_device *class_dev = | ||
1069 | rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE); | ||
1070 | |||
1071 | if (class_dev == NULL) | ||
1072 | return; | ||
1073 | |||
1074 | err = rtc_read_time(class_dev, tm); | ||
1075 | |||
1076 | rtc_class_close(class_dev); | ||
1077 | |||
1078 | return; | ||
1079 | } | ||
1080 | |||
1081 | int __init rtc_class_hookup(void) | ||
1082 | { | ||
1083 | ppc_md.get_rtc_time = get_rtc_class_time; | ||
1084 | ppc_md.set_rtc_time = set_rtc_class_time; | ||
1085 | |||
1086 | return 0; | ||
1087 | } | ||
1088 | #endif /* CONFIG_RTC_CLASS */ | ||
1089 | |||
1090 | 1017 | ||
1091 | #define FEBRUARY 2 | 1018 | #define FEBRUARY 2 |
1092 | #define STARTOFTIME 1970 | 1019 | #define STARTOFTIME 1970 |
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index 5ed4c2ceb5c..c66b4771ef4 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c | |||
@@ -843,7 +843,7 @@ void __kprobes program_check_exception(struct pt_regs *regs) | |||
843 | 843 | ||
844 | void alignment_exception(struct pt_regs *regs) | 844 | void alignment_exception(struct pt_regs *regs) |
845 | { | 845 | { |
846 | int fixed = 0; | 846 | int sig, code, fixed = 0; |
847 | 847 | ||
848 | /* we don't implement logging of alignment exceptions */ | 848 | /* we don't implement logging of alignment exceptions */ |
849 | if (!(current->thread.align_ctl & PR_UNALIGN_SIGBUS)) | 849 | if (!(current->thread.align_ctl & PR_UNALIGN_SIGBUS)) |
@@ -857,14 +857,16 @@ void alignment_exception(struct pt_regs *regs) | |||
857 | 857 | ||
858 | /* Operand address was bad */ | 858 | /* Operand address was bad */ |
859 | if (fixed == -EFAULT) { | 859 | if (fixed == -EFAULT) { |
860 | if (user_mode(regs)) | 860 | sig = SIGSEGV; |
861 | _exception(SIGSEGV, regs, SEGV_ACCERR, regs->dar); | 861 | code = SEGV_ACCERR; |
862 | else | 862 | } else { |
863 | /* Search exception table */ | 863 | sig = SIGBUS; |
864 | bad_page_fault(regs, regs->dar, SIGSEGV); | 864 | code = BUS_ADRALN; |
865 | return; | ||
866 | } | 865 | } |
867 | _exception(SIGBUS, regs, BUS_ADRALN, regs->dar); | 866 | if (user_mode(regs)) |
867 | _exception(sig, regs, code, regs->dar); | ||
868 | else | ||
869 | bad_page_fault(regs, regs->dar, sig); | ||
868 | } | 870 | } |
869 | 871 | ||
870 | void StackOverflow(struct pt_regs *regs) | 872 | void StackOverflow(struct pt_regs *regs) |
diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c index 1a7e19cdab3..c913ad5cad2 100644 --- a/arch/powerpc/kernel/vdso.c +++ b/arch/powerpc/kernel/vdso.c | |||
@@ -36,6 +36,8 @@ | |||
36 | #include <asm/vdso.h> | 36 | #include <asm/vdso.h> |
37 | #include <asm/vdso_datapage.h> | 37 | #include <asm/vdso_datapage.h> |
38 | 38 | ||
39 | #include "setup.h" | ||
40 | |||
39 | #undef DEBUG | 41 | #undef DEBUG |
40 | 42 | ||
41 | #ifdef DEBUG | 43 | #ifdef DEBUG |
@@ -586,6 +588,43 @@ static __init int vdso_fixup_datapage(struct lib32_elfinfo *v32, | |||
586 | return 0; | 588 | return 0; |
587 | } | 589 | } |
588 | 590 | ||
591 | |||
592 | static __init int vdso_fixup_features(struct lib32_elfinfo *v32, | ||
593 | struct lib64_elfinfo *v64) | ||
594 | { | ||
595 | void *start32; | ||
596 | unsigned long size32; | ||
597 | |||
598 | #ifdef CONFIG_PPC64 | ||
599 | void *start64; | ||
600 | unsigned long size64; | ||
601 | |||
602 | start64 = find_section64(v64->hdr, "__ftr_fixup", &size64); | ||
603 | if (start64) | ||
604 | do_feature_fixups(cur_cpu_spec->cpu_features, | ||
605 | start64, start64 + size64); | ||
606 | |||
607 | start64 = find_section64(v64->hdr, "__fw_ftr_fixup", &size64); | ||
608 | if (start64) | ||
609 | do_feature_fixups(powerpc_firmware_features, | ||
610 | start64, start64 + size64); | ||
611 | #endif /* CONFIG_PPC64 */ | ||
612 | |||
613 | start32 = find_section32(v32->hdr, "__ftr_fixup", &size32); | ||
614 | if (start32) | ||
615 | do_feature_fixups(cur_cpu_spec->cpu_features, | ||
616 | start32, start32 + size32); | ||
617 | |||
618 | #ifdef CONFIG_PPC64 | ||
619 | start32 = find_section32(v32->hdr, "__fw_ftr_fixup", &size32); | ||
620 | if (start32) | ||
621 | do_feature_fixups(powerpc_firmware_features, | ||
622 | start32, start32 + size32); | ||
623 | #endif /* CONFIG_PPC64 */ | ||
624 | |||
625 | return 0; | ||
626 | } | ||
627 | |||
589 | static __init int vdso_fixup_alt_funcs(struct lib32_elfinfo *v32, | 628 | static __init int vdso_fixup_alt_funcs(struct lib32_elfinfo *v32, |
590 | struct lib64_elfinfo *v64) | 629 | struct lib64_elfinfo *v64) |
591 | { | 630 | { |
@@ -634,6 +673,9 @@ static __init int vdso_setup(void) | |||
634 | if (vdso_fixup_datapage(&v32, &v64)) | 673 | if (vdso_fixup_datapage(&v32, &v64)) |
635 | return -1; | 674 | return -1; |
636 | 675 | ||
676 | if (vdso_fixup_features(&v32, &v64)) | ||
677 | return -1; | ||
678 | |||
637 | if (vdso_fixup_alt_funcs(&v32, &v64)) | 679 | if (vdso_fixup_alt_funcs(&v32, &v64)) |
638 | return -1; | 680 | return -1; |
639 | 681 | ||
@@ -714,6 +756,7 @@ void __init vdso_init(void) | |||
714 | * Setup the syscall map in the vDOS | 756 | * Setup the syscall map in the vDOS |
715 | */ | 757 | */ |
716 | vdso_setup_syscall_map(); | 758 | vdso_setup_syscall_map(); |
759 | |||
717 | /* | 760 | /* |
718 | * Initialize the vDSO images in memory, that is do necessary | 761 | * Initialize the vDSO images in memory, that is do necessary |
719 | * fixups of vDSO symbols, locate trampolines, etc... | 762 | * fixups of vDSO symbols, locate trampolines, etc... |
diff --git a/arch/powerpc/kernel/vdso32/vdso32.lds.S b/arch/powerpc/kernel/vdso32/vdso32.lds.S index 6187af2d54c..26e138c4ce1 100644 --- a/arch/powerpc/kernel/vdso32/vdso32.lds.S +++ b/arch/powerpc/kernel/vdso32/vdso32.lds.S | |||
@@ -32,6 +32,18 @@ SECTIONS | |||
32 | PROVIDE (_etext = .); | 32 | PROVIDE (_etext = .); |
33 | PROVIDE (etext = .); | 33 | PROVIDE (etext = .); |
34 | 34 | ||
35 | . = ALIGN(8); | ||
36 | __ftr_fixup : { | ||
37 | *(__ftr_fixup) | ||
38 | } | ||
39 | |||
40 | #ifdef CONFIG_PPC64 | ||
41 | . = ALIGN(8); | ||
42 | __fw_ftr_fixup : { | ||
43 | *(__fw_ftr_fixup) | ||
44 | } | ||
45 | #endif | ||
46 | |||
35 | /* Other stuff is appended to the text segment: */ | 47 | /* Other stuff is appended to the text segment: */ |
36 | .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } | 48 | .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } |
37 | .rodata1 : { *(.rodata1) } | 49 | .rodata1 : { *(.rodata1) } |
diff --git a/arch/powerpc/kernel/vdso64/gettimeofday.S b/arch/powerpc/kernel/vdso64/gettimeofday.S index 56e76ff5498..40ffd9b6cef 100644 --- a/arch/powerpc/kernel/vdso64/gettimeofday.S +++ b/arch/powerpc/kernel/vdso64/gettimeofday.S | |||
@@ -229,8 +229,10 @@ V_FUNCTION_BEGIN(__do_get_xsec) | |||
229 | xor r0,r8,r8 /* create dependency */ | 229 | xor r0,r8,r8 /* create dependency */ |
230 | add r3,r3,r0 | 230 | add r3,r3,r0 |
231 | 231 | ||
232 | /* Get TB & offset it */ | 232 | /* Get TB & offset it. We use the MFTB macro which will generate |
233 | mftb r7 | 233 | * workaround code for Cell. |
234 | */ | ||
235 | MFTB(r7) | ||
234 | ld r9,CFG_TB_ORIG_STAMP(r3) | 236 | ld r9,CFG_TB_ORIG_STAMP(r3) |
235 | subf r7,r9,r7 | 237 | subf r7,r9,r7 |
236 | 238 | ||
diff --git a/arch/powerpc/kernel/vdso64/vdso64.lds.S b/arch/powerpc/kernel/vdso64/vdso64.lds.S index 4a2b6dc0960..2d70f35d50b 100644 --- a/arch/powerpc/kernel/vdso64/vdso64.lds.S +++ b/arch/powerpc/kernel/vdso64/vdso64.lds.S | |||
@@ -31,6 +31,16 @@ SECTIONS | |||
31 | PROVIDE (_etext = .); | 31 | PROVIDE (_etext = .); |
32 | PROVIDE (etext = .); | 32 | PROVIDE (etext = .); |
33 | 33 | ||
34 | . = ALIGN(8); | ||
35 | __ftr_fixup : { | ||
36 | *(__ftr_fixup) | ||
37 | } | ||
38 | |||
39 | . = ALIGN(8); | ||
40 | __fw_ftr_fixup : { | ||
41 | *(__fw_ftr_fixup) | ||
42 | } | ||
43 | |||
34 | /* Other stuff is appended to the text segment: */ | 44 | /* Other stuff is appended to the text segment: */ |
35 | .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } | 45 | .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } |
36 | .rodata1 : { *(.rodata1) } | 46 | .rodata1 : { *(.rodata1) } |
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c index cb87e71eec6..ed007878d1b 100644 --- a/arch/powerpc/kernel/vio.c +++ b/arch/powerpc/kernel/vio.c | |||
@@ -92,9 +92,9 @@ static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev) | |||
92 | &tbl->it_index, &offset, &size); | 92 | &tbl->it_index, &offset, &size); |
93 | 93 | ||
94 | /* TCE table size - measured in tce entries */ | 94 | /* TCE table size - measured in tce entries */ |
95 | tbl->it_size = size >> PAGE_SHIFT; | 95 | tbl->it_size = size >> IOMMU_PAGE_SHIFT; |
96 | /* offset for VIO should always be 0 */ | 96 | /* offset for VIO should always be 0 */ |
97 | tbl->it_offset = offset >> PAGE_SHIFT; | 97 | tbl->it_offset = offset >> IOMMU_PAGE_SHIFT; |
98 | tbl->it_busno = 0; | 98 | tbl->it_busno = 0; |
99 | tbl->it_type = TCE_VB; | 99 | tbl->it_type = TCE_VB; |
100 | 100 | ||
diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S index cb0e8d46c3e..e8342d86753 100644 --- a/arch/powerpc/kernel/vmlinux.lds.S +++ b/arch/powerpc/kernel/vmlinux.lds.S | |||
@@ -108,13 +108,7 @@ SECTIONS | |||
108 | 108 | ||
109 | .initcall.init : { | 109 | .initcall.init : { |
110 | __initcall_start = .; | 110 | __initcall_start = .; |
111 | *(.initcall1.init) | 111 | INITCALLS |
112 | *(.initcall2.init) | ||
113 | *(.initcall3.init) | ||
114 | *(.initcall4.init) | ||
115 | *(.initcall5.init) | ||
116 | *(.initcall6.init) | ||
117 | *(.initcall7.init) | ||
118 | __initcall_end = .; | 112 | __initcall_end = .; |
119 | } | 113 | } |
120 | 114 | ||
diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c index 9590ba780b9..7e8ded051b5 100644 --- a/arch/powerpc/lib/sstep.c +++ b/arch/powerpc/lib/sstep.c | |||
@@ -9,6 +9,7 @@ | |||
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 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
12 | #include <linux/kprobes.h> | ||
12 | #include <linux/ptrace.h> | 13 | #include <linux/ptrace.h> |
13 | #include <asm/sstep.h> | 14 | #include <asm/sstep.h> |
14 | #include <asm/processor.h> | 15 | #include <asm/processor.h> |
@@ -25,7 +26,7 @@ extern char system_call_common[]; | |||
25 | /* | 26 | /* |
26 | * Determine whether a conditional branch instruction would branch. | 27 | * Determine whether a conditional branch instruction would branch. |
27 | */ | 28 | */ |
28 | static int branch_taken(unsigned int instr, struct pt_regs *regs) | 29 | static int __kprobes branch_taken(unsigned int instr, struct pt_regs *regs) |
29 | { | 30 | { |
30 | unsigned int bo = (instr >> 21) & 0x1f; | 31 | unsigned int bo = (instr >> 21) & 0x1f; |
31 | unsigned int bi; | 32 | unsigned int bi; |
@@ -51,7 +52,7 @@ static int branch_taken(unsigned int instr, struct pt_regs *regs) | |||
51 | * or -1 if the instruction is one that should not be stepped, | 52 | * or -1 if the instruction is one that should not be stepped, |
52 | * such as an rfid, or a mtmsrd that would clear MSR_RI. | 53 | * such as an rfid, or a mtmsrd that would clear MSR_RI. |
53 | */ | 54 | */ |
54 | int emulate_step(struct pt_regs *regs, unsigned int instr) | 55 | int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr) |
55 | { | 56 | { |
56 | unsigned int opcode, rd; | 57 | unsigned int opcode, rd; |
57 | unsigned long int imm; | 58 | unsigned long int imm; |
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c index 5615acc2952..506d89768d4 100644 --- a/arch/powerpc/mm/hugetlbpage.c +++ b/arch/powerpc/mm/hugetlbpage.c | |||
@@ -480,9 +480,6 @@ static int open_high_hpage_areas(struct mm_struct *mm, u16 newareas) | |||
480 | 480 | ||
481 | mm->context.high_htlb_areas |= newareas; | 481 | mm->context.high_htlb_areas |= newareas; |
482 | 482 | ||
483 | /* update the paca copy of the context struct */ | ||
484 | get_paca()->context = mm->context; | ||
485 | |||
486 | /* the context change must make it to memory before the flush, | 483 | /* the context change must make it to memory before the flush, |
487 | * so that further SLB misses do the right thing. */ | 484 | * so that further SLB misses do the right thing. */ |
488 | mb(); | 485 | mb(); |
@@ -494,11 +491,15 @@ static int open_high_hpage_areas(struct mm_struct *mm, u16 newareas) | |||
494 | return 0; | 491 | return 0; |
495 | } | 492 | } |
496 | 493 | ||
497 | int prepare_hugepage_range(unsigned long addr, unsigned long len) | 494 | int prepare_hugepage_range(unsigned long addr, unsigned long len, pgoff_t pgoff) |
498 | { | 495 | { |
499 | int err = 0; | 496 | int err = 0; |
500 | 497 | ||
501 | if ( (addr+len) < addr ) | 498 | if (pgoff & (~HPAGE_MASK >> PAGE_SHIFT)) |
499 | return -EINVAL; | ||
500 | if (len & ~HPAGE_MASK) | ||
501 | return -EINVAL; | ||
502 | if (addr & ~HPAGE_MASK) | ||
502 | return -EINVAL; | 503 | return -EINVAL; |
503 | 504 | ||
504 | if (addr < 0x100000000UL) | 505 | if (addr < 0x100000000UL) |
diff --git a/arch/powerpc/oprofile/Makefile b/arch/powerpc/oprofile/Makefile index 3145d610b5b..0b5df9c96ae 100644 --- a/arch/powerpc/oprofile/Makefile +++ b/arch/powerpc/oprofile/Makefile | |||
@@ -13,4 +13,4 @@ DRIVER_OBJS := $(addprefix ../../../drivers/oprofile/, \ | |||
13 | oprofile-y := $(DRIVER_OBJS) common.o backtrace.o | 13 | oprofile-y := $(DRIVER_OBJS) common.o backtrace.o |
14 | oprofile-$(CONFIG_PPC64) += op_model_rs64.o op_model_power4.o | 14 | oprofile-$(CONFIG_PPC64) += op_model_rs64.o op_model_power4.o |
15 | oprofile-$(CONFIG_FSL_BOOKE) += op_model_fsl_booke.o | 15 | oprofile-$(CONFIG_FSL_BOOKE) += op_model_fsl_booke.o |
16 | oprofile-$(CONFIG_PPC32) += op_model_7450.o | 16 | oprofile-$(CONFIG_6xx) += op_model_7450.o |
diff --git a/arch/powerpc/oprofile/common.c b/arch/powerpc/oprofile/common.c index fd0bbbe7a4d..63bbef3b63f 100644 --- a/arch/powerpc/oprofile/common.c +++ b/arch/powerpc/oprofile/common.c | |||
@@ -34,6 +34,11 @@ static void op_handle_interrupt(struct pt_regs *regs) | |||
34 | model->handle_interrupt(regs, ctr); | 34 | model->handle_interrupt(regs, ctr); |
35 | } | 35 | } |
36 | 36 | ||
37 | static void op_powerpc_cpu_setup(void *dummy) | ||
38 | { | ||
39 | model->cpu_setup(ctr); | ||
40 | } | ||
41 | |||
37 | static int op_powerpc_setup(void) | 42 | static int op_powerpc_setup(void) |
38 | { | 43 | { |
39 | int err; | 44 | int err; |
@@ -47,7 +52,7 @@ static int op_powerpc_setup(void) | |||
47 | model->reg_setup(ctr, &sys, model->num_counters); | 52 | model->reg_setup(ctr, &sys, model->num_counters); |
48 | 53 | ||
49 | /* Configure the registers on all cpus. */ | 54 | /* Configure the registers on all cpus. */ |
50 | on_each_cpu(model->cpu_setup, NULL, 0, 1); | 55 | on_each_cpu(op_powerpc_cpu_setup, NULL, 0, 1); |
51 | 56 | ||
52 | return 0; | 57 | return 0; |
53 | } | 58 | } |
@@ -142,7 +147,8 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) | |||
142 | case PPC_OPROFILE_POWER4: | 147 | case PPC_OPROFILE_POWER4: |
143 | model = &op_model_power4; | 148 | model = &op_model_power4; |
144 | break; | 149 | break; |
145 | #else | 150 | #endif |
151 | #ifdef CONFIG_6xx | ||
146 | case PPC_OPROFILE_G4: | 152 | case PPC_OPROFILE_G4: |
147 | model = &op_model_7450; | 153 | model = &op_model_7450; |
148 | break; | 154 | break; |
diff --git a/arch/powerpc/oprofile/op_model_7450.c b/arch/powerpc/oprofile/op_model_7450.c index d8ee3aea83f..f481c0ed5e6 100644 --- a/arch/powerpc/oprofile/op_model_7450.c +++ b/arch/powerpc/oprofile/op_model_7450.c | |||
@@ -81,7 +81,7 @@ static void pmc_stop_ctrs(void) | |||
81 | 81 | ||
82 | /* Configures the counters on this CPU based on the global | 82 | /* Configures the counters on this CPU based on the global |
83 | * settings */ | 83 | * settings */ |
84 | static void fsl7450_cpu_setup(void *unused) | 84 | static void fsl7450_cpu_setup(struct op_counter_config *ctr) |
85 | { | 85 | { |
86 | /* freeze all counters */ | 86 | /* freeze all counters */ |
87 | pmc_stop_ctrs(); | 87 | pmc_stop_ctrs(); |
diff --git a/arch/powerpc/oprofile/op_model_fsl_booke.c b/arch/powerpc/oprofile/op_model_fsl_booke.c index e29dede3142..0b3c31f5209 100644 --- a/arch/powerpc/oprofile/op_model_fsl_booke.c +++ b/arch/powerpc/oprofile/op_model_fsl_booke.c | |||
@@ -32,42 +32,152 @@ static unsigned long reset_value[OP_MAX_COUNTER]; | |||
32 | static int num_counters; | 32 | static int num_counters; |
33 | static int oprofile_running; | 33 | static int oprofile_running; |
34 | 34 | ||
35 | static inline unsigned int ctr_read(unsigned int i) | 35 | static void init_pmc_stop(int ctr) |
36 | { | 36 | { |
37 | switch(i) { | 37 | u32 pmlca = (PMLCA_FC | PMLCA_FCS | PMLCA_FCU | |
38 | case 0: | 38 | PMLCA_FCM1 | PMLCA_FCM0); |
39 | return mfpmr(PMRN_PMC0); | 39 | u32 pmlcb = 0; |
40 | case 1: | ||
41 | return mfpmr(PMRN_PMC1); | ||
42 | case 2: | ||
43 | return mfpmr(PMRN_PMC2); | ||
44 | case 3: | ||
45 | return mfpmr(PMRN_PMC3); | ||
46 | default: | ||
47 | return 0; | ||
48 | } | ||
49 | } | ||
50 | 40 | ||
51 | static inline void ctr_write(unsigned int i, unsigned int val) | 41 | switch (ctr) { |
52 | { | ||
53 | switch(i) { | ||
54 | case 0: | 42 | case 0: |
55 | mtpmr(PMRN_PMC0, val); | 43 | mtpmr(PMRN_PMLCA0, pmlca); |
44 | mtpmr(PMRN_PMLCB0, pmlcb); | ||
56 | break; | 45 | break; |
57 | case 1: | 46 | case 1: |
58 | mtpmr(PMRN_PMC1, val); | 47 | mtpmr(PMRN_PMLCA1, pmlca); |
48 | mtpmr(PMRN_PMLCB1, pmlcb); | ||
59 | break; | 49 | break; |
60 | case 2: | 50 | case 2: |
61 | mtpmr(PMRN_PMC2, val); | 51 | mtpmr(PMRN_PMLCA2, pmlca); |
52 | mtpmr(PMRN_PMLCB2, pmlcb); | ||
62 | break; | 53 | break; |
63 | case 3: | 54 | case 3: |
64 | mtpmr(PMRN_PMC3, val); | 55 | mtpmr(PMRN_PMLCA3, pmlca); |
56 | mtpmr(PMRN_PMLCB3, pmlcb); | ||
65 | break; | 57 | break; |
66 | default: | 58 | default: |
67 | break; | 59 | panic("Bad ctr number!\n"); |
68 | } | 60 | } |
69 | } | 61 | } |
70 | 62 | ||
63 | static void set_pmc_event(int ctr, int event) | ||
64 | { | ||
65 | u32 pmlca; | ||
66 | |||
67 | pmlca = get_pmlca(ctr); | ||
68 | |||
69 | pmlca = (pmlca & ~PMLCA_EVENT_MASK) | | ||
70 | ((event << PMLCA_EVENT_SHIFT) & | ||
71 | PMLCA_EVENT_MASK); | ||
72 | |||
73 | set_pmlca(ctr, pmlca); | ||
74 | } | ||
75 | |||
76 | static void set_pmc_user_kernel(int ctr, int user, int kernel) | ||
77 | { | ||
78 | u32 pmlca; | ||
79 | |||
80 | pmlca = get_pmlca(ctr); | ||
81 | |||
82 | if(user) | ||
83 | pmlca &= ~PMLCA_FCU; | ||
84 | else | ||
85 | pmlca |= PMLCA_FCU; | ||
86 | |||
87 | if(kernel) | ||
88 | pmlca &= ~PMLCA_FCS; | ||
89 | else | ||
90 | pmlca |= PMLCA_FCS; | ||
91 | |||
92 | set_pmlca(ctr, pmlca); | ||
93 | } | ||
94 | |||
95 | static void set_pmc_marked(int ctr, int mark0, int mark1) | ||
96 | { | ||
97 | u32 pmlca = get_pmlca(ctr); | ||
98 | |||
99 | if(mark0) | ||
100 | pmlca &= ~PMLCA_FCM0; | ||
101 | else | ||
102 | pmlca |= PMLCA_FCM0; | ||
103 | |||
104 | if(mark1) | ||
105 | pmlca &= ~PMLCA_FCM1; | ||
106 | else | ||
107 | pmlca |= PMLCA_FCM1; | ||
108 | |||
109 | set_pmlca(ctr, pmlca); | ||
110 | } | ||
111 | |||
112 | static void pmc_start_ctr(int ctr, int enable) | ||
113 | { | ||
114 | u32 pmlca = get_pmlca(ctr); | ||
115 | |||
116 | pmlca &= ~PMLCA_FC; | ||
117 | |||
118 | if (enable) | ||
119 | pmlca |= PMLCA_CE; | ||
120 | else | ||
121 | pmlca &= ~PMLCA_CE; | ||
122 | |||
123 | set_pmlca(ctr, pmlca); | ||
124 | } | ||
125 | |||
126 | static void pmc_start_ctrs(int enable) | ||
127 | { | ||
128 | u32 pmgc0 = mfpmr(PMRN_PMGC0); | ||
129 | |||
130 | pmgc0 &= ~PMGC0_FAC; | ||
131 | pmgc0 |= PMGC0_FCECE; | ||
132 | |||
133 | if (enable) | ||
134 | pmgc0 |= PMGC0_PMIE; | ||
135 | else | ||
136 | pmgc0 &= ~PMGC0_PMIE; | ||
137 | |||
138 | mtpmr(PMRN_PMGC0, pmgc0); | ||
139 | } | ||
140 | |||
141 | static void pmc_stop_ctrs(void) | ||
142 | { | ||
143 | u32 pmgc0 = mfpmr(PMRN_PMGC0); | ||
144 | |||
145 | pmgc0 |= PMGC0_FAC; | ||
146 | |||
147 | pmgc0 &= ~(PMGC0_PMIE | PMGC0_FCECE); | ||
148 | |||
149 | mtpmr(PMRN_PMGC0, pmgc0); | ||
150 | } | ||
151 | |||
152 | static void dump_pmcs(void) | ||
153 | { | ||
154 | printk("pmgc0: %x\n", mfpmr(PMRN_PMGC0)); | ||
155 | printk("pmc\t\tpmlca\t\tpmlcb\n"); | ||
156 | printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC0), | ||
157 | mfpmr(PMRN_PMLCA0), mfpmr(PMRN_PMLCB0)); | ||
158 | printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC1), | ||
159 | mfpmr(PMRN_PMLCA1), mfpmr(PMRN_PMLCB1)); | ||
160 | printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC2), | ||
161 | mfpmr(PMRN_PMLCA2), mfpmr(PMRN_PMLCB2)); | ||
162 | printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC3), | ||
163 | mfpmr(PMRN_PMLCA3), mfpmr(PMRN_PMLCB3)); | ||
164 | } | ||
165 | |||
166 | static void fsl_booke_cpu_setup(struct op_counter_config *ctr) | ||
167 | { | ||
168 | int i; | ||
169 | |||
170 | /* freeze all counters */ | ||
171 | pmc_stop_ctrs(); | ||
172 | |||
173 | for (i = 0;i < num_counters;i++) { | ||
174 | init_pmc_stop(i); | ||
175 | |||
176 | set_pmc_event(i, ctr[i].event); | ||
177 | |||
178 | set_pmc_user_kernel(i, ctr[i].user, ctr[i].kernel); | ||
179 | } | ||
180 | } | ||
71 | 181 | ||
72 | static void fsl_booke_reg_setup(struct op_counter_config *ctr, | 182 | static void fsl_booke_reg_setup(struct op_counter_config *ctr, |
73 | struct op_system_config *sys, | 183 | struct op_system_config *sys, |
@@ -77,23 +187,14 @@ static void fsl_booke_reg_setup(struct op_counter_config *ctr, | |||
77 | 187 | ||
78 | num_counters = num_ctrs; | 188 | num_counters = num_ctrs; |
79 | 189 | ||
80 | /* freeze all counters */ | ||
81 | pmc_stop_ctrs(); | ||
82 | |||
83 | /* Our counters count up, and "count" refers to | 190 | /* Our counters count up, and "count" refers to |
84 | * how much before the next interrupt, and we interrupt | 191 | * how much before the next interrupt, and we interrupt |
85 | * on overflow. So we calculate the starting value | 192 | * on overflow. So we calculate the starting value |
86 | * which will give us "count" until overflow. | 193 | * which will give us "count" until overflow. |
87 | * Then we set the events on the enabled counters */ | 194 | * Then we set the events on the enabled counters */ |
88 | for (i = 0; i < num_counters; ++i) { | 195 | for (i = 0; i < num_counters; ++i) |
89 | reset_value[i] = 0x80000000UL - ctr[i].count; | 196 | reset_value[i] = 0x80000000UL - ctr[i].count; |
90 | 197 | ||
91 | init_pmc_stop(i); | ||
92 | |||
93 | set_pmc_event(i, ctr[i].event); | ||
94 | |||
95 | set_pmc_user_kernel(i, ctr[i].user, ctr[i].kernel); | ||
96 | } | ||
97 | } | 198 | } |
98 | 199 | ||
99 | static void fsl_booke_start(struct op_counter_config *ctr) | 200 | static void fsl_booke_start(struct op_counter_config *ctr) |
@@ -105,8 +206,8 @@ static void fsl_booke_start(struct op_counter_config *ctr) | |||
105 | for (i = 0; i < num_counters; ++i) { | 206 | for (i = 0; i < num_counters; ++i) { |
106 | if (ctr[i].enabled) { | 207 | if (ctr[i].enabled) { |
107 | ctr_write(i, reset_value[i]); | 208 | ctr_write(i, reset_value[i]); |
108 | /* Set Each enabled counterd to only | 209 | /* Set each enabled counter to only |
109 | * count when the Mark bit is not set */ | 210 | * count when the Mark bit is *not* set */ |
110 | set_pmc_marked(i, 1, 0); | 211 | set_pmc_marked(i, 1, 0); |
111 | pmc_start_ctr(i, 1); | 212 | pmc_start_ctr(i, 1); |
112 | } else { | 213 | } else { |
@@ -177,6 +278,7 @@ static void fsl_booke_handle_interrupt(struct pt_regs *regs, | |||
177 | 278 | ||
178 | struct op_powerpc_model op_model_fsl_booke = { | 279 | struct op_powerpc_model op_model_fsl_booke = { |
179 | .reg_setup = fsl_booke_reg_setup, | 280 | .reg_setup = fsl_booke_reg_setup, |
281 | .cpu_setup = fsl_booke_cpu_setup, | ||
180 | .start = fsl_booke_start, | 282 | .start = fsl_booke_start, |
181 | .stop = fsl_booke_stop, | 283 | .stop = fsl_booke_stop, |
182 | .handle_interrupt = fsl_booke_handle_interrupt, | 284 | .handle_interrupt = fsl_booke_handle_interrupt, |
diff --git a/arch/powerpc/oprofile/op_model_power4.c b/arch/powerpc/oprofile/op_model_power4.c index 506f6b79f89..356709d515b 100644 --- a/arch/powerpc/oprofile/op_model_power4.c +++ b/arch/powerpc/oprofile/op_model_power4.c | |||
@@ -76,13 +76,13 @@ static inline int mmcra_must_set_sample(void) | |||
76 | { | 76 | { |
77 | if (__is_processor(PV_POWER4) || __is_processor(PV_POWER4p) || | 77 | if (__is_processor(PV_POWER4) || __is_processor(PV_POWER4p) || |
78 | __is_processor(PV_970) || __is_processor(PV_970FX) || | 78 | __is_processor(PV_970) || __is_processor(PV_970FX) || |
79 | __is_processor(PV_970MP)) | 79 | __is_processor(PV_970MP) || __is_processor(PV_970GX)) |
80 | return 1; | 80 | return 1; |
81 | 81 | ||
82 | return 0; | 82 | return 0; |
83 | } | 83 | } |
84 | 84 | ||
85 | static void power4_cpu_setup(void *unused) | 85 | static void power4_cpu_setup(struct op_counter_config *ctr) |
86 | { | 86 | { |
87 | unsigned int mmcr0 = mmcr0_val; | 87 | unsigned int mmcr0 = mmcr0_val; |
88 | unsigned long mmcra = mmcra_val; | 88 | unsigned long mmcra = mmcra_val; |
diff --git a/arch/powerpc/oprofile/op_model_rs64.c b/arch/powerpc/oprofile/op_model_rs64.c index 042f8f4867a..19c5ee089bc 100644 --- a/arch/powerpc/oprofile/op_model_rs64.c +++ b/arch/powerpc/oprofile/op_model_rs64.c | |||
@@ -102,7 +102,7 @@ static void rs64_reg_setup(struct op_counter_config *ctr, | |||
102 | /* XXX setup user and kernel profiling */ | 102 | /* XXX setup user and kernel profiling */ |
103 | } | 103 | } |
104 | 104 | ||
105 | static void rs64_cpu_setup(void *unused) | 105 | static void rs64_cpu_setup(struct op_counter_config *ctr) |
106 | { | 106 | { |
107 | unsigned int mmcr0; | 107 | unsigned int mmcr0; |
108 | 108 | ||
diff --git a/arch/powerpc/platforms/83xx/Kconfig b/arch/powerpc/platforms/83xx/Kconfig index 7edb6b46138..edcd5b875b6 100644 --- a/arch/powerpc/platforms/83xx/Kconfig +++ b/arch/powerpc/platforms/83xx/Kconfig | |||
@@ -21,7 +21,7 @@ config MPC834x_SYS | |||
21 | Be aware that PCI buses can only function when SYS board is plugged | 21 | Be aware that PCI buses can only function when SYS board is plugged |
22 | into the PIB (Platform IO Board) board from Freescale which provide | 22 | into the PIB (Platform IO Board) board from Freescale which provide |
23 | 3 PCI slots. The PIBs PCI initialization is the bootloader's | 23 | 3 PCI slots. The PIBs PCI initialization is the bootloader's |
24 | responsiblilty. | 24 | responsibility. |
25 | 25 | ||
26 | config MPC834x_ITX | 26 | config MPC834x_ITX |
27 | bool "Freescale MPC834x ITX" | 27 | bool "Freescale MPC834x ITX" |
@@ -30,7 +30,7 @@ config MPC834x_ITX | |||
30 | This option enables support for the MPC 834x ITX evaluation board. | 30 | This option enables support for the MPC 834x ITX evaluation board. |
31 | 31 | ||
32 | Be aware that PCI initialization is the bootloader's | 32 | Be aware that PCI initialization is the bootloader's |
33 | responsiblilty. | 33 | responsibility. |
34 | 34 | ||
35 | config MPC8360E_PB | 35 | config MPC8360E_PB |
36 | bool "Freescale MPC8360E PB" | 36 | bool "Freescale MPC8360E PB" |
diff --git a/arch/powerpc/platforms/83xx/mpc832x_mds.c b/arch/powerpc/platforms/83xx/mpc832x_mds.c index 54dea9d42dc..a43ac71ab74 100644 --- a/arch/powerpc/platforms/83xx/mpc832x_mds.c +++ b/arch/powerpc/platforms/83xx/mpc832x_mds.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/root_dev.h> | 24 | #include <linux/root_dev.h> |
25 | #include <linux/initrd.h> | 25 | #include <linux/initrd.h> |
26 | 26 | ||
27 | #include <asm/of_device.h> | ||
27 | #include <asm/system.h> | 28 | #include <asm/system.h> |
28 | #include <asm/atomic.h> | 29 | #include <asm/atomic.h> |
29 | #include <asm/time.h> | 30 | #include <asm/time.h> |
@@ -136,6 +137,24 @@ static void __init mpc832x_sys_setup_arch(void) | |||
136 | #endif | 137 | #endif |
137 | } | 138 | } |
138 | 139 | ||
140 | static int __init mpc832x_declare_of_platform_devices(void) | ||
141 | { | ||
142 | struct device_node *np; | ||
143 | |||
144 | for (np = NULL; (np = of_find_compatible_node(np, "network", | ||
145 | "ucc_geth")) != NULL;) { | ||
146 | int ucc_num; | ||
147 | char bus_id[BUS_ID_SIZE]; | ||
148 | |||
149 | ucc_num = *((uint *) get_property(np, "device-id", NULL)) - 1; | ||
150 | snprintf(bus_id, BUS_ID_SIZE, "ucc_geth.%u", ucc_num); | ||
151 | of_platform_device_create(np, bus_id, NULL); | ||
152 | } | ||
153 | |||
154 | return 0; | ||
155 | } | ||
156 | device_initcall(mpc832x_declare_of_platform_devices); | ||
157 | |||
139 | void __init mpc832x_sys_init_IRQ(void) | 158 | void __init mpc832x_sys_init_IRQ(void) |
140 | { | 159 | { |
141 | 160 | ||
diff --git a/arch/powerpc/platforms/83xx/mpc834x_itx.c b/arch/powerpc/platforms/83xx/mpc834x_itx.c index 5446bab08ec..e2bcaaf6b32 100644 --- a/arch/powerpc/platforms/83xx/mpc834x_itx.c +++ b/arch/powerpc/platforms/83xx/mpc834x_itx.c | |||
@@ -108,10 +108,6 @@ static int __init mpc834x_itx_probe(void) | |||
108 | return 1; | 108 | return 1; |
109 | } | 109 | } |
110 | 110 | ||
111 | #ifdef CONFIG_RTC_CLASS | ||
112 | late_initcall(rtc_class_hookup); | ||
113 | #endif | ||
114 | |||
115 | define_machine(mpc834x_itx) { | 111 | define_machine(mpc834x_itx) { |
116 | .name = "MPC834x ITX", | 112 | .name = "MPC834x ITX", |
117 | .probe = mpc834x_itx_probe, | 113 | .probe = mpc834x_itx_probe, |
diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c index 032bc923342..d5aeb3c6dd4 100644 --- a/arch/powerpc/platforms/cell/spu_base.c +++ b/arch/powerpc/platforms/cell/spu_base.c | |||
@@ -668,14 +668,19 @@ static int __init spu_map_interrupts(struct spu *spu, struct device_node *np) | |||
668 | 668 | ||
669 | for (i=0; i < 3; i++) { | 669 | for (i=0; i < 3; i++) { |
670 | ret = of_irq_map_one(np, i, &oirq); | 670 | ret = of_irq_map_one(np, i, &oirq); |
671 | if (ret) | 671 | if (ret) { |
672 | pr_debug("spu_new: failed to get irq %d\n", i); | ||
672 | goto err; | 673 | goto err; |
673 | 674 | } | |
674 | ret = -EINVAL; | 675 | ret = -EINVAL; |
676 | pr_debug(" irq %d no 0x%x on %s\n", i, oirq.specifier[0], | ||
677 | oirq.controller->full_name); | ||
675 | spu->irqs[i] = irq_create_of_mapping(oirq.controller, | 678 | spu->irqs[i] = irq_create_of_mapping(oirq.controller, |
676 | oirq.specifier, oirq.size); | 679 | oirq.specifier, oirq.size); |
677 | if (spu->irqs[i] == NO_IRQ) | 680 | if (spu->irqs[i] == NO_IRQ) { |
681 | pr_debug("spu_new: failed to map it !\n"); | ||
678 | goto err; | 682 | goto err; |
683 | } | ||
679 | } | 684 | } |
680 | return 0; | 685 | return 0; |
681 | 686 | ||
@@ -694,7 +699,7 @@ static int spu_map_resource(struct device_node *node, int nr, | |||
694 | struct resource resource = { }; | 699 | struct resource resource = { }; |
695 | int ret; | 700 | int ret; |
696 | 701 | ||
697 | ret = of_address_to_resource(node, 0, &resource); | 702 | ret = of_address_to_resource(node, nr, &resource); |
698 | if (ret) | 703 | if (ret) |
699 | goto out; | 704 | goto out; |
700 | 705 | ||
@@ -717,22 +722,42 @@ static int __init spu_map_device(struct spu *spu, struct device_node *node) | |||
717 | 722 | ||
718 | ret = spu_map_resource(node, 0, (void __iomem**)&spu->local_store, | 723 | ret = spu_map_resource(node, 0, (void __iomem**)&spu->local_store, |
719 | &spu->local_store_phys); | 724 | &spu->local_store_phys); |
720 | if (ret) | 725 | if (ret) { |
726 | pr_debug("spu_new: failed to map %s resource 0\n", | ||
727 | node->full_name); | ||
721 | goto out; | 728 | goto out; |
729 | } | ||
722 | ret = spu_map_resource(node, 1, (void __iomem**)&spu->problem, | 730 | ret = spu_map_resource(node, 1, (void __iomem**)&spu->problem, |
723 | &spu->problem_phys); | 731 | &spu->problem_phys); |
724 | if (ret) | 732 | if (ret) { |
733 | pr_debug("spu_new: failed to map %s resource 1\n", | ||
734 | node->full_name); | ||
725 | goto out_unmap; | 735 | goto out_unmap; |
736 | } | ||
726 | ret = spu_map_resource(node, 2, (void __iomem**)&spu->priv2, | 737 | ret = spu_map_resource(node, 2, (void __iomem**)&spu->priv2, |
727 | NULL); | 738 | NULL); |
728 | if (ret) | 739 | if (ret) { |
740 | pr_debug("spu_new: failed to map %s resource 2\n", | ||
741 | node->full_name); | ||
729 | goto out_unmap; | 742 | goto out_unmap; |
743 | } | ||
730 | 744 | ||
731 | if (!firmware_has_feature(FW_FEATURE_LPAR)) | 745 | if (!firmware_has_feature(FW_FEATURE_LPAR)) |
732 | ret = spu_map_resource(node, 3, (void __iomem**)&spu->priv1, | 746 | ret = spu_map_resource(node, 3, (void __iomem**)&spu->priv1, |
733 | NULL); | 747 | NULL); |
734 | if (ret) | 748 | if (ret) { |
749 | pr_debug("spu_new: failed to map %s resource 3\n", | ||
750 | node->full_name); | ||
735 | goto out_unmap; | 751 | goto out_unmap; |
752 | } | ||
753 | pr_debug("spu_new: %s maps:\n", node->full_name); | ||
754 | pr_debug(" local store : 0x%016lx -> 0x%p\n", | ||
755 | spu->local_store_phys, spu->local_store); | ||
756 | pr_debug(" problem state : 0x%016lx -> 0x%p\n", | ||
757 | spu->problem_phys, spu->problem); | ||
758 | pr_debug(" priv2 : 0x%p\n", spu->priv2); | ||
759 | pr_debug(" priv1 : 0x%p\n", spu->priv1); | ||
760 | |||
736 | return 0; | 761 | return 0; |
737 | 762 | ||
738 | out_unmap: | 763 | out_unmap: |
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index 5b8ba6c3aa3..0ea2361865a 100644 --- a/arch/powerpc/platforms/cell/spufs/file.c +++ b/arch/powerpc/platforms/cell/spufs/file.c | |||
@@ -385,7 +385,7 @@ static ssize_t spufs_mbox_read(struct file *file, char __user *buf, | |||
385 | udata = (void __user *)buf; | 385 | udata = (void __user *)buf; |
386 | 386 | ||
387 | spu_acquire(ctx); | 387 | spu_acquire(ctx); |
388 | for (count = 0; count <= len; count += 4, udata++) { | 388 | for (count = 0; (count + 4) <= len; count += 4, udata++) { |
389 | int ret; | 389 | int ret; |
390 | ret = ctx->ops->mbox_read(ctx, &mbox_data); | 390 | ret = ctx->ops->mbox_read(ctx, &mbox_data); |
391 | if (ret == 0) | 391 | if (ret == 0) |
diff --git a/arch/powerpc/platforms/cell/spufs/hw_ops.c b/arch/powerpc/platforms/cell/spufs/hw_ops.c index 2ad534a04be..59c87f12da5 100644 --- a/arch/powerpc/platforms/cell/spufs/hw_ops.c +++ b/arch/powerpc/platforms/cell/spufs/hw_ops.c | |||
@@ -147,7 +147,7 @@ static void spu_hw_signal1_write(struct spu_context *ctx, u32 data) | |||
147 | 147 | ||
148 | static u32 spu_hw_signal2_read(struct spu_context *ctx) | 148 | static u32 spu_hw_signal2_read(struct spu_context *ctx) |
149 | { | 149 | { |
150 | return in_be32(&ctx->spu->problem->signal_notify1); | 150 | return in_be32(&ctx->spu->problem->signal_notify2); |
151 | } | 151 | } |
152 | 152 | ||
153 | static void spu_hw_signal2_write(struct spu_context *ctx, u32 data) | 153 | static void spu_hw_signal2_write(struct spu_context *ctx, u32 data) |
diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c index cae3d13229b..49b8dabcbc9 100644 --- a/arch/powerpc/platforms/chrp/setup.c +++ b/arch/powerpc/platforms/chrp/setup.c | |||
@@ -477,8 +477,10 @@ static void __init chrp_find_8259(void) | |||
477 | " address, polling\n"); | 477 | " address, polling\n"); |
478 | 478 | ||
479 | i8259_init(pic, chrp_int_ack); | 479 | i8259_init(pic, chrp_int_ack); |
480 | if (ppc_md.get_irq == NULL) | 480 | if (ppc_md.get_irq == NULL) { |
481 | ppc_md.get_irq = i8259_irq; | 481 | ppc_md.get_irq = i8259_irq; |
482 | irq_set_default_host(i8259_get_host()); | ||
483 | } | ||
482 | if (chrp_mpic != NULL) { | 484 | if (chrp_mpic != NULL) { |
483 | cascade_irq = irq_of_parse_and_map(pic, 0); | 485 | cascade_irq = irq_of_parse_and_map(pic, 0); |
484 | if (cascade_irq == NO_IRQ) | 486 | if (cascade_irq == NO_IRQ) |
diff --git a/arch/powerpc/platforms/iseries/iommu.c b/arch/powerpc/platforms/iseries/iommu.c index f4cbbcf8773..218817d13c5 100644 --- a/arch/powerpc/platforms/iseries/iommu.c +++ b/arch/powerpc/platforms/iseries/iommu.c | |||
@@ -43,9 +43,6 @@ static void tce_build_iSeries(struct iommu_table *tbl, long index, long npages, | |||
43 | u64 rc; | 43 | u64 rc; |
44 | u64 tce, rpn; | 44 | u64 tce, rpn; |
45 | 45 | ||
46 | index <<= TCE_PAGE_FACTOR; | ||
47 | npages <<= TCE_PAGE_FACTOR; | ||
48 | |||
49 | while (npages--) { | 46 | while (npages--) { |
50 | rpn = virt_to_abs(uaddr) >> TCE_SHIFT; | 47 | rpn = virt_to_abs(uaddr) >> TCE_SHIFT; |
51 | tce = (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT; | 48 | tce = (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT; |
@@ -75,9 +72,6 @@ static void tce_free_iSeries(struct iommu_table *tbl, long index, long npages) | |||
75 | { | 72 | { |
76 | u64 rc; | 73 | u64 rc; |
77 | 74 | ||
78 | npages <<= TCE_PAGE_FACTOR; | ||
79 | index <<= TCE_PAGE_FACTOR; | ||
80 | |||
81 | while (npages--) { | 75 | while (npages--) { |
82 | rc = HvCallXm_setTce((u64)tbl->it_index, (u64)index, 0); | 76 | rc = HvCallXm_setTce((u64)tbl->it_index, (u64)index, 0); |
83 | if (rc) | 77 | if (rc) |
@@ -136,10 +130,9 @@ void iommu_table_getparms_iSeries(unsigned long busno, | |||
136 | panic("PCI_DMA: parms->size is zero, parms is 0x%p", parms); | 130 | panic("PCI_DMA: parms->size is zero, parms is 0x%p", parms); |
137 | 131 | ||
138 | /* itc_size is in pages worth of table, it_size is in # of entries */ | 132 | /* itc_size is in pages worth of table, it_size is in # of entries */ |
139 | tbl->it_size = ((parms->itc_size * TCE_PAGE_SIZE) / | 133 | tbl->it_size = (parms->itc_size * TCE_PAGE_SIZE) / TCE_ENTRY_SIZE; |
140 | TCE_ENTRY_SIZE) >> TCE_PAGE_FACTOR; | ||
141 | tbl->it_busno = parms->itc_busno; | 134 | tbl->it_busno = parms->itc_busno; |
142 | tbl->it_offset = parms->itc_offset >> TCE_PAGE_FACTOR; | 135 | tbl->it_offset = parms->itc_offset; |
143 | tbl->it_index = parms->itc_index; | 136 | tbl->it_index = parms->itc_index; |
144 | tbl->it_blocksize = 1; | 137 | tbl->it_blocksize = 1; |
145 | tbl->it_type = virtbus ? TCE_VB : TCE_PCI; | 138 | tbl->it_type = virtbus ? TCE_VB : TCE_PCI; |
diff --git a/arch/powerpc/platforms/iseries/setup.c b/arch/powerpc/platforms/iseries/setup.c index 08d14734617..cd8965ec9dd 100644 --- a/arch/powerpc/platforms/iseries/setup.c +++ b/arch/powerpc/platforms/iseries/setup.c | |||
@@ -662,6 +662,11 @@ void * __init iSeries_early_setup(void) | |||
662 | { | 662 | { |
663 | unsigned long phys_mem_size; | 663 | unsigned long phys_mem_size; |
664 | 664 | ||
665 | /* Identify CPU type. This is done again by the common code later | ||
666 | * on but calling this function multiple times is fine. | ||
667 | */ | ||
668 | identify_cpu(0); | ||
669 | |||
665 | powerpc_firmware_features |= FW_FEATURE_ISERIES; | 670 | powerpc_firmware_features |= FW_FEATURE_ISERIES; |
666 | powerpc_firmware_features |= FW_FEATURE_LPAR; | 671 | powerpc_firmware_features |= FW_FEATURE_LPAR; |
667 | 672 | ||
diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c index 9923adc5248..257dc906846 100644 --- a/arch/powerpc/platforms/powermac/pci.c +++ b/arch/powerpc/platforms/powermac/pci.c | |||
@@ -48,7 +48,6 @@ static struct pci_controller *u3_ht; | |||
48 | static int has_second_ohare; | 48 | static int has_second_ohare; |
49 | #endif /* CONFIG_PPC64 */ | 49 | #endif /* CONFIG_PPC64 */ |
50 | 50 | ||
51 | extern u8 pci_cache_line_size; | ||
52 | extern int pcibios_assign_bus_offset; | 51 | extern int pcibios_assign_bus_offset; |
53 | 52 | ||
54 | struct device_node *k2_skiplist[2]; | 53 | struct device_node *k2_skiplist[2]; |
diff --git a/arch/powerpc/platforms/powermac/sleep.S b/arch/powerpc/platforms/powermac/sleep.S index 1174ca128ef..adee28da353 100644 --- a/arch/powerpc/platforms/powermac/sleep.S +++ b/arch/powerpc/platforms/powermac/sleep.S | |||
@@ -45,7 +45,8 @@ | |||
45 | .section .text | 45 | .section .text |
46 | .align 5 | 46 | .align 5 |
47 | 47 | ||
48 | #if defined(CONFIG_PM) || defined(CONFIG_CPU_FREQ_PMAC) | 48 | #if defined(CONFIG_PM) || defined(CONFIG_CPU_FREQ_PMAC) || \ |
49 | (defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC32)) | ||
49 | 50 | ||
50 | /* This gets called by via-pmu.c late during the sleep process. | 51 | /* This gets called by via-pmu.c late during the sleep process. |
51 | * The PMU was already send the sleep command and will shut us down | 52 | * The PMU was already send the sleep command and will shut us down |
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index d24ba547e53..556c279a789 100644 --- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c | |||
@@ -57,9 +57,6 @@ static void tce_build_pSeries(struct iommu_table *tbl, long index, | |||
57 | u64 *tcep; | 57 | u64 *tcep; |
58 | u64 rpn; | 58 | u64 rpn; |
59 | 59 | ||
60 | index <<= TCE_PAGE_FACTOR; | ||
61 | npages <<= TCE_PAGE_FACTOR; | ||
62 | |||
63 | proto_tce = TCE_PCI_READ; // Read allowed | 60 | proto_tce = TCE_PCI_READ; // Read allowed |
64 | 61 | ||
65 | if (direction != DMA_TO_DEVICE) | 62 | if (direction != DMA_TO_DEVICE) |
@@ -82,9 +79,6 @@ static void tce_free_pSeries(struct iommu_table *tbl, long index, long npages) | |||
82 | { | 79 | { |
83 | u64 *tcep; | 80 | u64 *tcep; |
84 | 81 | ||
85 | npages <<= TCE_PAGE_FACTOR; | ||
86 | index <<= TCE_PAGE_FACTOR; | ||
87 | |||
88 | tcep = ((u64 *)tbl->it_base) + index; | 82 | tcep = ((u64 *)tbl->it_base) + index; |
89 | 83 | ||
90 | while (npages--) | 84 | while (npages--) |
@@ -95,7 +89,6 @@ static unsigned long tce_get_pseries(struct iommu_table *tbl, long index) | |||
95 | { | 89 | { |
96 | u64 *tcep; | 90 | u64 *tcep; |
97 | 91 | ||
98 | index <<= TCE_PAGE_FACTOR; | ||
99 | tcep = ((u64 *)tbl->it_base) + index; | 92 | tcep = ((u64 *)tbl->it_base) + index; |
100 | 93 | ||
101 | return *tcep; | 94 | return *tcep; |
@@ -109,9 +102,6 @@ static void tce_build_pSeriesLP(struct iommu_table *tbl, long tcenum, | |||
109 | u64 proto_tce, tce; | 102 | u64 proto_tce, tce; |
110 | u64 rpn; | 103 | u64 rpn; |
111 | 104 | ||
112 | tcenum <<= TCE_PAGE_FACTOR; | ||
113 | npages <<= TCE_PAGE_FACTOR; | ||
114 | |||
115 | rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT; | 105 | rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT; |
116 | proto_tce = TCE_PCI_READ; | 106 | proto_tce = TCE_PCI_READ; |
117 | if (direction != DMA_TO_DEVICE) | 107 | if (direction != DMA_TO_DEVICE) |
@@ -146,7 +136,7 @@ static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum, | |||
146 | u64 rpn; | 136 | u64 rpn; |
147 | long l, limit; | 137 | long l, limit; |
148 | 138 | ||
149 | if (TCE_PAGE_FACTOR == 0 && npages == 1) | 139 | if (npages == 1) |
150 | return tce_build_pSeriesLP(tbl, tcenum, npages, uaddr, | 140 | return tce_build_pSeriesLP(tbl, tcenum, npages, uaddr, |
151 | direction); | 141 | direction); |
152 | 142 | ||
@@ -164,9 +154,6 @@ static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum, | |||
164 | __get_cpu_var(tce_page) = tcep; | 154 | __get_cpu_var(tce_page) = tcep; |
165 | } | 155 | } |
166 | 156 | ||
167 | tcenum <<= TCE_PAGE_FACTOR; | ||
168 | npages <<= TCE_PAGE_FACTOR; | ||
169 | |||
170 | rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT; | 157 | rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT; |
171 | proto_tce = TCE_PCI_READ; | 158 | proto_tce = TCE_PCI_READ; |
172 | if (direction != DMA_TO_DEVICE) | 159 | if (direction != DMA_TO_DEVICE) |
@@ -207,9 +194,6 @@ static void tce_free_pSeriesLP(struct iommu_table *tbl, long tcenum, long npages | |||
207 | { | 194 | { |
208 | u64 rc; | 195 | u64 rc; |
209 | 196 | ||
210 | tcenum <<= TCE_PAGE_FACTOR; | ||
211 | npages <<= TCE_PAGE_FACTOR; | ||
212 | |||
213 | while (npages--) { | 197 | while (npages--) { |
214 | rc = plpar_tce_put((u64)tbl->it_index, (u64)tcenum << 12, 0); | 198 | rc = plpar_tce_put((u64)tbl->it_index, (u64)tcenum << 12, 0); |
215 | 199 | ||
@@ -229,9 +213,6 @@ static void tce_freemulti_pSeriesLP(struct iommu_table *tbl, long tcenum, long n | |||
229 | { | 213 | { |
230 | u64 rc; | 214 | u64 rc; |
231 | 215 | ||
232 | tcenum <<= TCE_PAGE_FACTOR; | ||
233 | npages <<= TCE_PAGE_FACTOR; | ||
234 | |||
235 | rc = plpar_tce_stuff((u64)tbl->it_index, (u64)tcenum << 12, 0, npages); | 216 | rc = plpar_tce_stuff((u64)tbl->it_index, (u64)tcenum << 12, 0, npages); |
236 | 217 | ||
237 | if (rc && printk_ratelimit()) { | 218 | if (rc && printk_ratelimit()) { |
@@ -248,7 +229,6 @@ static unsigned long tce_get_pSeriesLP(struct iommu_table *tbl, long tcenum) | |||
248 | u64 rc; | 229 | u64 rc; |
249 | unsigned long tce_ret; | 230 | unsigned long tce_ret; |
250 | 231 | ||
251 | tcenum <<= TCE_PAGE_FACTOR; | ||
252 | rc = plpar_tce_get((u64)tbl->it_index, (u64)tcenum << 12, &tce_ret); | 232 | rc = plpar_tce_get((u64)tbl->it_index, (u64)tcenum << 12, &tce_ret); |
253 | 233 | ||
254 | if (rc && printk_ratelimit()) { | 234 | if (rc && printk_ratelimit()) { |
@@ -289,7 +269,7 @@ static void iommu_table_setparms(struct pci_controller *phb, | |||
289 | tbl->it_busno = phb->bus->number; | 269 | tbl->it_busno = phb->bus->number; |
290 | 270 | ||
291 | /* Units of tce entries */ | 271 | /* Units of tce entries */ |
292 | tbl->it_offset = phb->dma_window_base_cur >> PAGE_SHIFT; | 272 | tbl->it_offset = phb->dma_window_base_cur >> IOMMU_PAGE_SHIFT; |
293 | 273 | ||
294 | /* Test if we are going over 2GB of DMA space */ | 274 | /* Test if we are going over 2GB of DMA space */ |
295 | if (phb->dma_window_base_cur + phb->dma_window_size > 0x80000000ul) { | 275 | if (phb->dma_window_base_cur + phb->dma_window_size > 0x80000000ul) { |
@@ -300,7 +280,7 @@ static void iommu_table_setparms(struct pci_controller *phb, | |||
300 | phb->dma_window_base_cur += phb->dma_window_size; | 280 | phb->dma_window_base_cur += phb->dma_window_size; |
301 | 281 | ||
302 | /* Set the tce table size - measured in entries */ | 282 | /* Set the tce table size - measured in entries */ |
303 | tbl->it_size = phb->dma_window_size >> PAGE_SHIFT; | 283 | tbl->it_size = phb->dma_window_size >> IOMMU_PAGE_SHIFT; |
304 | 284 | ||
305 | tbl->it_index = 0; | 285 | tbl->it_index = 0; |
306 | tbl->it_blocksize = 16; | 286 | tbl->it_blocksize = 16; |
@@ -325,8 +305,8 @@ static void iommu_table_setparms_lpar(struct pci_controller *phb, | |||
325 | tbl->it_base = 0; | 305 | tbl->it_base = 0; |
326 | tbl->it_blocksize = 16; | 306 | tbl->it_blocksize = 16; |
327 | tbl->it_type = TCE_PCI; | 307 | tbl->it_type = TCE_PCI; |
328 | tbl->it_offset = offset >> PAGE_SHIFT; | 308 | tbl->it_offset = offset >> IOMMU_PAGE_SHIFT; |
329 | tbl->it_size = size >> PAGE_SHIFT; | 309 | tbl->it_size = size >> IOMMU_PAGE_SHIFT; |
330 | } | 310 | } |
331 | 311 | ||
332 | static void iommu_bus_setup_pSeries(struct pci_bus *bus) | 312 | static void iommu_bus_setup_pSeries(struct pci_bus *bus) |
@@ -522,8 +502,6 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev) | |||
522 | const void *dma_window = NULL; | 502 | const void *dma_window = NULL; |
523 | struct pci_dn *pci; | 503 | struct pci_dn *pci; |
524 | 504 | ||
525 | DBG("iommu_dev_setup_pSeriesLP, dev %p (%s)\n", dev, pci_name(dev)); | ||
526 | |||
527 | /* dev setup for LPAR is a little tricky, since the device tree might | 505 | /* dev setup for LPAR is a little tricky, since the device tree might |
528 | * contain the dma-window properties per-device and not neccesarily | 506 | * contain the dma-window properties per-device and not neccesarily |
529 | * for the bus. So we need to search upwards in the tree until we | 507 | * for the bus. So we need to search upwards in the tree until we |
@@ -532,6 +510,9 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev) | |||
532 | */ | 510 | */ |
533 | dn = pci_device_to_OF_node(dev); | 511 | dn = pci_device_to_OF_node(dev); |
534 | 512 | ||
513 | DBG("iommu_dev_setup_pSeriesLP, dev %p (%s) %s\n", | ||
514 | dev, pci_name(dev), dn->full_name); | ||
515 | |||
535 | for (pdn = dn; pdn && PCI_DN(pdn) && !PCI_DN(pdn)->iommu_table; | 516 | for (pdn = dn; pdn && PCI_DN(pdn) && !PCI_DN(pdn)->iommu_table; |
536 | pdn = pdn->parent) { | 517 | pdn = pdn->parent) { |
537 | dma_window = get_property(pdn, "ibm,dma-window", NULL); | 518 | dma_window = get_property(pdn, "ibm,dma-window", NULL); |
diff --git a/arch/powerpc/sysdev/dart.h b/arch/powerpc/sysdev/dart.h index 1c8817c4835..ff202edb059 100644 --- a/arch/powerpc/sysdev/dart.h +++ b/arch/powerpc/sysdev/dart.h | |||
@@ -72,7 +72,6 @@ | |||
72 | 72 | ||
73 | #define DART_PAGE_SHIFT 12 | 73 | #define DART_PAGE_SHIFT 12 |
74 | #define DART_PAGE_SIZE (1 << DART_PAGE_SHIFT) | 74 | #define DART_PAGE_SIZE (1 << DART_PAGE_SHIFT) |
75 | #define DART_PAGE_FACTOR (PAGE_SHIFT - DART_PAGE_SHIFT) | ||
76 | 75 | ||
77 | 76 | ||
78 | #endif /* _POWERPC_SYSDEV_DART_H */ | 77 | #endif /* _POWERPC_SYSDEV_DART_H */ |
diff --git a/arch/powerpc/sysdev/dart_iommu.c b/arch/powerpc/sysdev/dart_iommu.c index 03b4477dd7f..572b7846cc7 100644 --- a/arch/powerpc/sysdev/dart_iommu.c +++ b/arch/powerpc/sysdev/dart_iommu.c | |||
@@ -156,9 +156,6 @@ static void dart_build(struct iommu_table *tbl, long index, | |||
156 | 156 | ||
157 | DBG("dart: build at: %lx, %lx, addr: %x\n", index, npages, uaddr); | 157 | DBG("dart: build at: %lx, %lx, addr: %x\n", index, npages, uaddr); |
158 | 158 | ||
159 | index <<= DART_PAGE_FACTOR; | ||
160 | npages <<= DART_PAGE_FACTOR; | ||
161 | |||
162 | dp = ((unsigned int*)tbl->it_base) + index; | 159 | dp = ((unsigned int*)tbl->it_base) + index; |
163 | 160 | ||
164 | /* On U3, all memory is contigous, so we can move this | 161 | /* On U3, all memory is contigous, so we can move this |
@@ -199,9 +196,6 @@ static void dart_free(struct iommu_table *tbl, long index, long npages) | |||
199 | 196 | ||
200 | DBG("dart: free at: %lx, %lx\n", index, npages); | 197 | DBG("dart: free at: %lx, %lx\n", index, npages); |
201 | 198 | ||
202 | index <<= DART_PAGE_FACTOR; | ||
203 | npages <<= DART_PAGE_FACTOR; | ||
204 | |||
205 | dp = ((unsigned int *)tbl->it_base) + index; | 199 | dp = ((unsigned int *)tbl->it_base) + index; |
206 | 200 | ||
207 | while (npages--) | 201 | while (npages--) |
@@ -281,7 +275,7 @@ static void iommu_table_dart_setup(void) | |||
281 | iommu_table_dart.it_busno = 0; | 275 | iommu_table_dart.it_busno = 0; |
282 | iommu_table_dart.it_offset = 0; | 276 | iommu_table_dart.it_offset = 0; |
283 | /* it_size is in number of entries */ | 277 | /* it_size is in number of entries */ |
284 | iommu_table_dart.it_size = (dart_tablesize / sizeof(u32)) >> DART_PAGE_FACTOR; | 278 | iommu_table_dart.it_size = dart_tablesize / sizeof(u32); |
285 | 279 | ||
286 | /* Initialize the common IOMMU code */ | 280 | /* Initialize the common IOMMU code */ |
287 | iommu_table_dart.it_base = (unsigned long)dart_vbase; | 281 | iommu_table_dart.it_base = (unsigned long)dart_vbase; |
diff --git a/arch/powerpc/sysdev/i8259.c b/arch/powerpc/sysdev/i8259.c index 0450265d73b..ad87adc975b 100644 --- a/arch/powerpc/sysdev/i8259.c +++ b/arch/powerpc/sysdev/i8259.c | |||
@@ -224,6 +224,11 @@ static struct irq_host_ops i8259_host_ops = { | |||
224 | .xlate = i8259_host_xlate, | 224 | .xlate = i8259_host_xlate, |
225 | }; | 225 | }; |
226 | 226 | ||
227 | struct irq_host *i8259_get_host(void) | ||
228 | { | ||
229 | return i8259_host; | ||
230 | } | ||
231 | |||
227 | /** | 232 | /** |
228 | * i8259_init - Initialize the legacy controller | 233 | * i8259_init - Initialize the legacy controller |
229 | * @node: device node of the legacy PIC (can be NULL, but then, it will match | 234 | * @node: device node of the legacy PIC (can be NULL, but then, it will match |
diff --git a/arch/powerpc/sysdev/ipic.c b/arch/powerpc/sysdev/ipic.c index bc4d4a7f965..746f78c1537 100644 --- a/arch/powerpc/sysdev/ipic.c +++ b/arch/powerpc/sysdev/ipic.c | |||
@@ -473,9 +473,9 @@ static int ipic_set_irq_type(unsigned int virq, unsigned int flow_type) | |||
473 | desc->status |= flow_type & IRQ_TYPE_SENSE_MASK; | 473 | desc->status |= flow_type & IRQ_TYPE_SENSE_MASK; |
474 | if (flow_type & IRQ_TYPE_LEVEL_LOW) { | 474 | if (flow_type & IRQ_TYPE_LEVEL_LOW) { |
475 | desc->status |= IRQ_LEVEL; | 475 | desc->status |= IRQ_LEVEL; |
476 | set_irq_handler(virq, handle_level_irq); | 476 | desc->handle_irq = handle_level_irq; |
477 | } else { | 477 | } else { |
478 | set_irq_handler(virq, handle_edge_irq); | 478 | desc->handle_irq = handle_edge_irq; |
479 | } | 479 | } |
480 | 480 | ||
481 | /* only EXT IRQ senses are programmable on ipic | 481 | /* only EXT IRQ senses are programmable on ipic |
diff --git a/arch/powerpc/sysdev/qe_lib/qe.c b/arch/powerpc/sysdev/qe_lib/qe.c index 812c87c73bb..e3d71e083f3 100644 --- a/arch/powerpc/sysdev/qe_lib/qe.c +++ b/arch/powerpc/sysdev/qe_lib/qe.c | |||
@@ -122,8 +122,7 @@ int qe_issue_cmd(u32 cmd, u32 device, u8 mcn_protocol, u32 cmd_input) | |||
122 | mcn_shift = QE_CR_MCN_NORMAL_SHIFT; | 122 | mcn_shift = QE_CR_MCN_NORMAL_SHIFT; |
123 | } | 123 | } |
124 | 124 | ||
125 | out_be32(&qe_immr->cp.cecdr, | 125 | out_be32(&qe_immr->cp.cecdr, cmd_input); |
126 | immrbar_virt_to_phys((void *)cmd_input)); | ||
127 | out_be32(&qe_immr->cp.cecr, | 126 | out_be32(&qe_immr->cp.cecr, |
128 | (cmd | QE_CR_FLG | ((u32) device << dev_shift) | (u32) | 127 | (cmd | QE_CR_FLG | ((u32) device << dev_shift) | (u32) |
129 | mcn_protocol << mcn_shift)); | 128 | mcn_protocol << mcn_shift)); |
diff --git a/arch/powerpc/sysdev/qe_lib/ucc.c b/arch/powerpc/sysdev/qe_lib/ucc.c index 916c9e5df57..ac12a44d516 100644 --- a/arch/powerpc/sysdev/qe_lib/ucc.c +++ b/arch/powerpc/sysdev/qe_lib/ucc.c | |||
@@ -207,6 +207,7 @@ int ucc_set_qe_mux_rxtx(int ucc_num, enum qe_clock clock, enum comm_dir mode) | |||
207 | case QE_CLK18: source = 8; break; | 207 | case QE_CLK18: source = 8; break; |
208 | case QE_CLK7: source = 9; break; | 208 | case QE_CLK7: source = 9; break; |
209 | case QE_CLK8: source = 10; break; | 209 | case QE_CLK8: source = 10; break; |
210 | case QE_CLK16: source = 11; break; | ||
210 | default: source = -1; break; | 211 | default: source = -1; break; |
211 | } | 212 | } |
212 | break; | 213 | break; |
@@ -222,6 +223,7 @@ int ucc_set_qe_mux_rxtx(int ucc_num, enum qe_clock clock, enum comm_dir mode) | |||
222 | case QE_CLK22: source = 8; break; | 223 | case QE_CLK22: source = 8; break; |
223 | case QE_CLK7: source = 9; break; | 224 | case QE_CLK7: source = 9; break; |
224 | case QE_CLK8: source = 10; break; | 225 | case QE_CLK8: source = 10; break; |
226 | case QE_CLK16: source = 11; break; | ||
225 | default: source = -1; break; | 227 | default: source = -1; break; |
226 | } | 228 | } |
227 | break; | 229 | break; |
diff --git a/arch/powerpc/sysdev/qe_lib/ucc_fast.c b/arch/powerpc/sysdev/qe_lib/ucc_fast.c index c2be7348fcb..75fa3104a43 100644 --- a/arch/powerpc/sysdev/qe_lib/ucc_fast.c +++ b/arch/powerpc/sysdev/qe_lib/ucc_fast.c | |||
@@ -163,7 +163,7 @@ int ucc_fast_init(struct ucc_fast_info * uf_info, struct ucc_fast_private ** ucc | |||
163 | 163 | ||
164 | /* check if the UCC port number is in range. */ | 164 | /* check if the UCC port number is in range. */ |
165 | if ((uf_info->ucc_num < 0) || (uf_info->ucc_num > UCC_MAX_NUM - 1)) { | 165 | if ((uf_info->ucc_num < 0) || (uf_info->ucc_num > UCC_MAX_NUM - 1)) { |
166 | uccf_err("ucc_fast_init: Illagal UCC number!"); | 166 | uccf_err("ucc_fast_init: Illegal UCC number!"); |
167 | return -EINVAL; | 167 | return -EINVAL; |
168 | } | 168 | } |
169 | 169 | ||
diff --git a/arch/powerpc/sysdev/qe_lib/ucc_slow.c b/arch/powerpc/sysdev/qe_lib/ucc_slow.c index 1fb88ef7cf0..a49da6b73ec 100644 --- a/arch/powerpc/sysdev/qe_lib/ucc_slow.c +++ b/arch/powerpc/sysdev/qe_lib/ucc_slow.c | |||
@@ -152,7 +152,7 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc | |||
152 | 152 | ||
153 | /* check if the UCC port number is in range. */ | 153 | /* check if the UCC port number is in range. */ |
154 | if ((us_info->ucc_num < 0) || (us_info->ucc_num > UCC_MAX_NUM - 1)) { | 154 | if ((us_info->ucc_num < 0) || (us_info->ucc_num > UCC_MAX_NUM - 1)) { |
155 | uccs_err("ucc_slow_init: Illagal UCC number!"); | 155 | uccs_err("ucc_slow_init: Illegal UCC number!"); |
156 | return -EINVAL; | 156 | return -EINVAL; |
157 | } | 157 | } |
158 | 158 | ||
diff --git a/arch/powerpc/sysdev/tsi108_dev.c b/arch/powerpc/sysdev/tsi108_dev.c index 11de090eb90..97f37ef4bbb 100644 --- a/arch/powerpc/sysdev/tsi108_dev.c +++ b/arch/powerpc/sysdev/tsi108_dev.c | |||
@@ -48,7 +48,7 @@ phys_addr_t get_csrbase(void) | |||
48 | tsi = of_find_node_by_type(NULL, "tsi-bridge"); | 48 | tsi = of_find_node_by_type(NULL, "tsi-bridge"); |
49 | if (tsi) { | 49 | if (tsi) { |
50 | unsigned int size; | 50 | unsigned int size; |
51 | void *prop = get_property(tsi, "reg", &size); | 51 | const void *prop = get_property(tsi, "reg", &size); |
52 | tsi108_csr_base = of_translate_address(tsi, prop); | 52 | tsi108_csr_base = of_translate_address(tsi, prop); |
53 | of_node_put(tsi); | 53 | of_node_put(tsi); |
54 | }; | 54 | }; |
@@ -79,7 +79,7 @@ static int __init tsi108_eth_of_init(void) | |||
79 | hw_info tsi_eth_data; | 79 | hw_info tsi_eth_data; |
80 | unsigned int *id; | 80 | unsigned int *id; |
81 | unsigned int *phy_id; | 81 | unsigned int *phy_id; |
82 | void *mac_addr; | 82 | const void *mac_addr; |
83 | phandle *ph; | 83 | phandle *ph; |
84 | 84 | ||
85 | memset(r, 0, sizeof(r)); | 85 | memset(r, 0, sizeof(r)); |