diff options
Diffstat (limited to 'arch/powerpc')
46 files changed, 1035 insertions, 437 deletions
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 8a01098eaaca..0a947bd9c076 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig | |||
@@ -350,7 +350,7 @@ config ARCH_ENABLE_MEMORY_HOTREMOVE | |||
350 | 350 | ||
351 | config KEXEC | 351 | config KEXEC |
352 | bool "kexec system call (EXPERIMENTAL)" | 352 | bool "kexec system call (EXPERIMENTAL)" |
353 | depends on (PPC_BOOK3S || FSL_BOOKE || (44x && !SMP && !PPC_47x)) && EXPERIMENTAL | 353 | depends on (PPC_BOOK3S || FSL_BOOKE || (44x && !SMP)) && EXPERIMENTAL |
354 | help | 354 | help |
355 | kexec is a system call that implements the ability to shutdown your | 355 | kexec is a system call that implements the ability to shutdown your |
356 | current kernel, and to start another kernel. It is like a reboot | 356 | current kernel, and to start another kernel. It is like a reboot |
@@ -367,7 +367,7 @@ config KEXEC | |||
367 | 367 | ||
368 | config CRASH_DUMP | 368 | config CRASH_DUMP |
369 | bool "Build a kdump crash kernel" | 369 | bool "Build a kdump crash kernel" |
370 | depends on PPC64 || 6xx || FSL_BOOKE || (44x && !SMP && !PPC_47x) | 370 | depends on PPC64 || 6xx || FSL_BOOKE || (44x && !SMP) |
371 | select RELOCATABLE if PPC64 || 44x | 371 | select RELOCATABLE if PPC64 || 44x |
372 | select DYNAMIC_MEMSTART if FSL_BOOKE | 372 | select DYNAMIC_MEMSTART if FSL_BOOKE |
373 | help | 373 | help |
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index 6524c6e21896..950d1f7a5a39 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile | |||
@@ -69,6 +69,16 @@ LDFLAGS_vmlinux := $(LDFLAGS_vmlinux-y) | |||
69 | 69 | ||
70 | CFLAGS-$(CONFIG_PPC64) := -mminimal-toc -mtraceback=no -mcall-aixdesc | 70 | CFLAGS-$(CONFIG_PPC64) := -mminimal-toc -mtraceback=no -mcall-aixdesc |
71 | CFLAGS-$(CONFIG_PPC32) := -ffixed-r2 -mmultiple | 71 | CFLAGS-$(CONFIG_PPC32) := -ffixed-r2 -mmultiple |
72 | |||
73 | CFLAGS-$(CONFIG_GENERIC_CPU) += $(call cc-option,-mtune=power7,-mtune=power4) | ||
74 | CFLAGS-$(CONFIG_CELL_CPU) += $(call cc-option,-mcpu=cell) | ||
75 | CFLAGS-$(CONFIG_POWER4_CPU) += $(call cc-option,-mcpu=power4) | ||
76 | CFLAGS-$(CONFIG_POWER5_CPU) += $(call cc-option,-mcpu=power5) | ||
77 | CFLAGS-$(CONFIG_POWER6_CPU) += $(call cc-option,-mcpu=power6) | ||
78 | CFLAGS-$(CONFIG_POWER7_CPU) += $(call cc-option,-mcpu=power7) | ||
79 | |||
80 | CFLAGS-$(CONFIG_TUNE_CELL) += $(call cc-option,-mtune=cell) | ||
81 | |||
72 | KBUILD_CPPFLAGS += -Iarch/$(ARCH) | 82 | KBUILD_CPPFLAGS += -Iarch/$(ARCH) |
73 | KBUILD_AFLAGS += -Iarch/$(ARCH) | 83 | KBUILD_AFLAGS += -Iarch/$(ARCH) |
74 | KBUILD_CFLAGS += -msoft-float -pipe -Iarch/$(ARCH) $(CFLAGS-y) | 84 | KBUILD_CFLAGS += -msoft-float -pipe -Iarch/$(ARCH) $(CFLAGS-y) |
@@ -76,32 +86,11 @@ CPP = $(CC) -E $(KBUILD_CFLAGS) | |||
76 | 86 | ||
77 | CHECKFLAGS += -m$(CONFIG_WORD_SIZE) -D__powerpc__ -D__powerpc$(CONFIG_WORD_SIZE)__ | 87 | CHECKFLAGS += -m$(CONFIG_WORD_SIZE) -D__powerpc__ -D__powerpc$(CONFIG_WORD_SIZE)__ |
78 | 88 | ||
79 | ifeq ($(CONFIG_PPC64),y) | ||
80 | GCC_BROKEN_VEC := $(call cc-ifversion, -lt, 0400, y) | ||
81 | |||
82 | ifeq ($(CONFIG_POWER4_ONLY),y) | ||
83 | ifeq ($(CONFIG_ALTIVEC),y) | ||
84 | ifeq ($(GCC_BROKEN_VEC),y) | ||
85 | KBUILD_CFLAGS += $(call cc-option,-mcpu=970) | ||
86 | else | ||
87 | KBUILD_CFLAGS += $(call cc-option,-mcpu=power4) | ||
88 | endif | ||
89 | else | ||
90 | KBUILD_CFLAGS += $(call cc-option,-mcpu=power4) | ||
91 | endif | ||
92 | else | ||
93 | KBUILD_CFLAGS += $(call cc-option,-mtune=power4) | ||
94 | endif | ||
95 | endif | ||
96 | |||
97 | KBUILD_LDFLAGS_MODULE += arch/powerpc/lib/crtsavres.o | 89 | KBUILD_LDFLAGS_MODULE += arch/powerpc/lib/crtsavres.o |
98 | 90 | ||
99 | ifeq ($(CONFIG_TUNE_CELL),y) | 91 | # No AltiVec or VSX instructions when building kernel |
100 | KBUILD_CFLAGS += $(call cc-option,-mtune=cell) | ||
101 | endif | ||
102 | |||
103 | # No AltiVec instruction when building kernel | ||
104 | KBUILD_CFLAGS += $(call cc-option,-mno-altivec) | 92 | KBUILD_CFLAGS += $(call cc-option,-mno-altivec) |
93 | KBUILD_CFLAGS += $(call cc-option,-mno-vsx) | ||
105 | 94 | ||
106 | # No SPE instruction when building kernel | 95 | # No SPE instruction when building kernel |
107 | # (We use all available options to help semi-broken compilers) | 96 | # (We use all available options to help semi-broken compilers) |
@@ -160,6 +149,7 @@ core-$(CONFIG_KVM) += arch/powerpc/kvm/ | |||
160 | core-$(CONFIG_PERF_EVENTS) += arch/powerpc/perf/ | 149 | core-$(CONFIG_PERF_EVENTS) += arch/powerpc/perf/ |
161 | 150 | ||
162 | drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/ | 151 | drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/ |
152 | drivers-$(CONFIG_CRYPTO_DEV_NX) += drivers/crypto/nx/ | ||
163 | 153 | ||
164 | # Default to zImage, override when needed | 154 | # Default to zImage, override when needed |
165 | all: zImage | 155 | all: zImage |
@@ -234,10 +224,11 @@ archprepare: checkbin | |||
234 | # Use the file '.tmp_gas_check' for binutils tests, as gas won't output | 224 | # Use the file '.tmp_gas_check' for binutils tests, as gas won't output |
235 | # to stdout and these checks are run even on install targets. | 225 | # to stdout and these checks are run even on install targets. |
236 | TOUT := .tmp_gas_check | 226 | TOUT := .tmp_gas_check |
237 | # Ensure this is binutils 2.12.1 (or 2.12.90.0.7) or later for altivec | ||
238 | # instructions. | ||
239 | # gcc-3.4 and binutils-2.14 are a fatal combination. | ||
240 | 227 | ||
228 | # Check gcc and binutils versions: | ||
229 | # - gcc-3.4 and binutils-2.14 are a fatal combination | ||
230 | # - Require gcc 4.0 or above on 64-bit | ||
231 | # - gcc-4.2.0 has issues compiling modules on 64-bit | ||
241 | checkbin: | 232 | checkbin: |
242 | @if test "$(call cc-version)" = "0304" ; then \ | 233 | @if test "$(call cc-version)" = "0304" ; then \ |
243 | if ! /bin/echo mftb 5 | $(AS) -v -mppc -many -o $(TOUT) >/dev/null 2>&1 ; then \ | 234 | if ! /bin/echo mftb 5 | $(AS) -v -mppc -many -o $(TOUT) >/dev/null 2>&1 ; then \ |
@@ -247,6 +238,12 @@ checkbin: | |||
247 | false; \ | 238 | false; \ |
248 | fi ; \ | 239 | fi ; \ |
249 | fi | 240 | fi |
241 | @if test "$(call cc-version)" -lt "0400" \ | ||
242 | && test "x${CONFIG_PPC64}" = "xy" ; then \ | ||
243 | echo -n "Sorry, GCC v4.0 or above is required to build " ; \ | ||
244 | echo "the 64-bit powerpc kernel." ; \ | ||
245 | false ; \ | ||
246 | fi | ||
250 | @if test "$(call cc-fullversion)" = "040200" \ | 247 | @if test "$(call cc-fullversion)" = "040200" \ |
251 | && test "x${CONFIG_MODULES}${CONFIG_PPC64}" = "xyy" ; then \ | 248 | && test "x${CONFIG_MODULES}${CONFIG_PPC64}" = "xyy" ; then \ |
252 | echo -n '*** GCC-4.2.0 cannot compile the 64-bit powerpc ' ; \ | 249 | echo -n '*** GCC-4.2.0 cannot compile the 64-bit powerpc ' ; \ |
diff --git a/arch/powerpc/boot/dts/bluestone.dts b/arch/powerpc/boot/dts/bluestone.dts index 7bda373f10ef..9d4917aebe6b 100644 --- a/arch/powerpc/boot/dts/bluestone.dts +++ b/arch/powerpc/boot/dts/bluestone.dts | |||
@@ -373,5 +373,30 @@ | |||
373 | 0x0 0x0 0x0 0x3 &UIC3 0xe 0x4 /* swizzled int C */ | 373 | 0x0 0x0 0x0 0x3 &UIC3 0xe 0x4 /* swizzled int C */ |
374 | 0x0 0x0 0x0 0x4 &UIC3 0xf 0x4 /* swizzled int D */>; | 374 | 0x0 0x0 0x0 0x4 &UIC3 0xf 0x4 /* swizzled int D */>; |
375 | }; | 375 | }; |
376 | |||
377 | MSI: ppc4xx-msi@C10000000 { | ||
378 | compatible = "amcc,ppc4xx-msi", "ppc4xx-msi"; | ||
379 | reg = < 0xC 0x10000000 0x100 | ||
380 | 0xC 0x10000000 0x100>; | ||
381 | sdr-base = <0x36C>; | ||
382 | msi-data = <0x00004440>; | ||
383 | msi-mask = <0x0000ffe0>; | ||
384 | interrupts =<0 1 2 3 4 5 6 7>; | ||
385 | interrupt-parent = <&MSI>; | ||
386 | #interrupt-cells = <1>; | ||
387 | #address-cells = <0>; | ||
388 | #size-cells = <0>; | ||
389 | msi-available-ranges = <0x0 0x100>; | ||
390 | interrupt-map = < | ||
391 | 0 &UIC3 0x18 1 | ||
392 | 1 &UIC3 0x19 1 | ||
393 | 2 &UIC3 0x1A 1 | ||
394 | 3 &UIC3 0x1B 1 | ||
395 | 4 &UIC3 0x1C 1 | ||
396 | 5 &UIC3 0x1D 1 | ||
397 | 6 &UIC3 0x1E 1 | ||
398 | 7 &UIC3 0x1F 1 | ||
399 | >; | ||
400 | }; | ||
376 | }; | 401 | }; |
377 | }; | 402 | }; |
diff --git a/arch/powerpc/configs/g5_defconfig b/arch/powerpc/configs/g5_defconfig index 1196c34163b7..07b7f2af2dca 100644 --- a/arch/powerpc/configs/g5_defconfig +++ b/arch/powerpc/configs/g5_defconfig | |||
@@ -1,5 +1,4 @@ | |||
1 | CONFIG_PPC64=y | 1 | CONFIG_PPC64=y |
2 | CONFIG_POWER4_ONLY=y | ||
3 | CONFIG_ALTIVEC=y | 2 | CONFIG_ALTIVEC=y |
4 | CONFIG_SMP=y | 3 | CONFIG_SMP=y |
5 | CONFIG_NR_CPUS=4 | 4 | CONFIG_NR_CPUS=4 |
diff --git a/arch/powerpc/configs/maple_defconfig b/arch/powerpc/configs/maple_defconfig index 2244d370f24d..02ac96b679b8 100644 --- a/arch/powerpc/configs/maple_defconfig +++ b/arch/powerpc/configs/maple_defconfig | |||
@@ -1,5 +1,4 @@ | |||
1 | CONFIG_PPC64=y | 1 | CONFIG_PPC64=y |
2 | CONFIG_POWER4_ONLY=y | ||
3 | CONFIG_SMP=y | 2 | CONFIG_SMP=y |
4 | CONFIG_NR_CPUS=4 | 3 | CONFIG_NR_CPUS=4 |
5 | CONFIG_EXPERIMENTAL=y | 4 | CONFIG_EXPERIMENTAL=y |
diff --git a/arch/powerpc/configs/pasemi_defconfig b/arch/powerpc/configs/pasemi_defconfig index f4deb0b78cf0..840a2c2d0430 100644 --- a/arch/powerpc/configs/pasemi_defconfig +++ b/arch/powerpc/configs/pasemi_defconfig | |||
@@ -1,5 +1,4 @@ | |||
1 | CONFIG_PPC64=y | 1 | CONFIG_PPC64=y |
2 | CONFIG_POWER4_ONLY=y | ||
3 | CONFIG_ALTIVEC=y | 2 | CONFIG_ALTIVEC=y |
4 | # CONFIG_VIRT_CPU_ACCOUNTING is not set | 3 | # CONFIG_VIRT_CPU_ACCOUNTING is not set |
5 | CONFIG_SMP=y | 4 | CONFIG_SMP=y |
diff --git a/arch/powerpc/configs/ps3_defconfig b/arch/powerpc/configs/ps3_defconfig index ded867871e97..c2f4b4a86ece 100644 --- a/arch/powerpc/configs/ps3_defconfig +++ b/arch/powerpc/configs/ps3_defconfig | |||
@@ -6,7 +6,6 @@ CONFIG_NR_CPUS=2 | |||
6 | CONFIG_EXPERIMENTAL=y | 6 | CONFIG_EXPERIMENTAL=y |
7 | CONFIG_SYSVIPC=y | 7 | CONFIG_SYSVIPC=y |
8 | CONFIG_POSIX_MQUEUE=y | 8 | CONFIG_POSIX_MQUEUE=y |
9 | CONFIG_SPARSE_IRQ=y | ||
10 | CONFIG_BLK_DEV_INITRD=y | 9 | CONFIG_BLK_DEV_INITRD=y |
11 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y | 10 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y |
12 | CONFIG_EMBEDDED=y | 11 | CONFIG_EMBEDDED=y |
@@ -25,7 +24,6 @@ CONFIG_PS3_DISK=y | |||
25 | CONFIG_PS3_ROM=y | 24 | CONFIG_PS3_ROM=y |
26 | CONFIG_PS3_FLASH=y | 25 | CONFIG_PS3_FLASH=y |
27 | CONFIG_PS3_VRAM=m | 26 | CONFIG_PS3_VRAM=m |
28 | CONFIG_PS3_LPM=m | ||
29 | # CONFIG_PPC_OF_BOOT_TRAMPOLINE is not set | 27 | # CONFIG_PPC_OF_BOOT_TRAMPOLINE is not set |
30 | CONFIG_HIGH_RES_TIMERS=y | 28 | CONFIG_HIGH_RES_TIMERS=y |
31 | # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set | 29 | # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set |
@@ -53,8 +51,6 @@ CONFIG_IP_PNP_DHCP=y | |||
53 | # CONFIG_INET_DIAG is not set | 51 | # CONFIG_INET_DIAG is not set |
54 | CONFIG_IPV6=y | 52 | CONFIG_IPV6=y |
55 | CONFIG_BT=m | 53 | CONFIG_BT=m |
56 | CONFIG_BT_L2CAP=y | ||
57 | CONFIG_BT_SCO=y | ||
58 | CONFIG_BT_RFCOMM=m | 54 | CONFIG_BT_RFCOMM=m |
59 | CONFIG_BT_RFCOMM_TTY=y | 55 | CONFIG_BT_RFCOMM_TTY=y |
60 | CONFIG_BT_BNEP=m | 56 | CONFIG_BT_BNEP=m |
@@ -63,7 +59,6 @@ CONFIG_BT_BNEP_PROTO_FILTER=y | |||
63 | CONFIG_BT_HIDP=m | 59 | CONFIG_BT_HIDP=m |
64 | CONFIG_BT_HCIBTUSB=m | 60 | CONFIG_BT_HCIBTUSB=m |
65 | CONFIG_CFG80211=m | 61 | CONFIG_CFG80211=m |
66 | # CONFIG_WIRELESS_EXT_SYSFS is not set | ||
67 | CONFIG_MAC80211=m | 62 | CONFIG_MAC80211=m |
68 | CONFIG_MAC80211_RC_PID=y | 63 | CONFIG_MAC80211_RC_PID=y |
69 | # CONFIG_MAC80211_RC_MINSTREL is not set | 64 | # CONFIG_MAC80211_RC_MINSTREL is not set |
@@ -181,7 +176,6 @@ CONFIG_DEBUG_INFO=y | |||
181 | CONFIG_DEBUG_WRITECOUNT=y | 176 | CONFIG_DEBUG_WRITECOUNT=y |
182 | CONFIG_DEBUG_MEMORY_INIT=y | 177 | CONFIG_DEBUG_MEMORY_INIT=y |
183 | CONFIG_DEBUG_LIST=y | 178 | CONFIG_DEBUG_LIST=y |
184 | CONFIG_SYSCTL_SYSCALL_CHECK=y | ||
185 | # CONFIG_FTRACE is not set | 179 | # CONFIG_FTRACE is not set |
186 | CONFIG_DEBUG_STACKOVERFLOW=y | 180 | CONFIG_DEBUG_STACKOVERFLOW=y |
187 | CONFIG_CRYPTO_CCM=m | 181 | CONFIG_CRYPTO_CCM=m |
diff --git a/arch/powerpc/include/asm/asm-compat.h b/arch/powerpc/include/asm/asm-compat.h index decad950f11a..5d7fbe1950f9 100644 --- a/arch/powerpc/include/asm/asm-compat.h +++ b/arch/powerpc/include/asm/asm-compat.h | |||
@@ -29,18 +29,9 @@ | |||
29 | #define PPC_LLARX(t, a, b, eh) PPC_LDARX(t, a, b, eh) | 29 | #define PPC_LLARX(t, a, b, eh) PPC_LDARX(t, a, b, eh) |
30 | #define PPC_STLCX stringify_in_c(stdcx.) | 30 | #define PPC_STLCX stringify_in_c(stdcx.) |
31 | #define PPC_CNTLZL stringify_in_c(cntlzd) | 31 | #define PPC_CNTLZL stringify_in_c(cntlzd) |
32 | #define PPC_MTOCRF(FXM, RS) MTOCRF((FXM), (RS)) | ||
32 | #define PPC_LR_STKOFF 16 | 33 | #define PPC_LR_STKOFF 16 |
33 | #define PPC_MIN_STKFRM 112 | 34 | #define PPC_MIN_STKFRM 112 |
34 | |||
35 | /* Move to CR, single-entry optimized version. Only available | ||
36 | * on POWER4 and later. | ||
37 | */ | ||
38 | #ifdef CONFIG_POWER4_ONLY | ||
39 | #define PPC_MTOCRF stringify_in_c(mtocrf) | ||
40 | #else | ||
41 | #define PPC_MTOCRF stringify_in_c(mtcrf) | ||
42 | #endif | ||
43 | |||
44 | #else /* 32-bit */ | 35 | #else /* 32-bit */ |
45 | 36 | ||
46 | /* operations for longs and pointers */ | 37 | /* operations for longs and pointers */ |
diff --git a/arch/powerpc/include/asm/cputhreads.h b/arch/powerpc/include/asm/cputhreads.h index ce516e5eb0d3..ac3eedb9b74a 100644 --- a/arch/powerpc/include/asm/cputhreads.h +++ b/arch/powerpc/include/asm/cputhreads.h | |||
@@ -9,7 +9,7 @@ | |||
9 | * Note: This implementation is limited to a power of 2 number of | 9 | * Note: This implementation is limited to a power of 2 number of |
10 | * threads per core and the same number for each core in the system | 10 | * threads per core and the same number for each core in the system |
11 | * (though it would work if some processors had less threads as long | 11 | * (though it would work if some processors had less threads as long |
12 | * as the CPU numbers are still allocated, just not brought offline). | 12 | * as the CPU numbers are still allocated, just not brought online). |
13 | * | 13 | * |
14 | * However, the API allows for a different implementation in the future | 14 | * However, the API allows for a different implementation in the future |
15 | * if needed, as long as you only use the functions and not the variables | 15 | * if needed, as long as you only use the functions and not the variables |
diff --git a/arch/powerpc/include/asm/hvcall.h b/arch/powerpc/include/asm/hvcall.h index 1c324ff55ea8..612252388190 100644 --- a/arch/powerpc/include/asm/hvcall.h +++ b/arch/powerpc/include/asm/hvcall.h | |||
@@ -77,8 +77,27 @@ | |||
77 | #define H_MR_CONDITION -43 | 77 | #define H_MR_CONDITION -43 |
78 | #define H_NOT_ENOUGH_RESOURCES -44 | 78 | #define H_NOT_ENOUGH_RESOURCES -44 |
79 | #define H_R_STATE -45 | 79 | #define H_R_STATE -45 |
80 | #define H_RESCINDEND -46 | 80 | #define H_RESCINDED -46 |
81 | #define H_MULTI_THREADS_ACTIVE -9005 | 81 | #define H_P2 -55 |
82 | #define H_P3 -56 | ||
83 | #define H_P4 -57 | ||
84 | #define H_P5 -58 | ||
85 | #define H_P6 -59 | ||
86 | #define H_P7 -60 | ||
87 | #define H_P8 -61 | ||
88 | #define H_P9 -62 | ||
89 | #define H_TOO_BIG -64 | ||
90 | #define H_OVERLAP -68 | ||
91 | #define H_INTERRUPT -69 | ||
92 | #define H_BAD_DATA -70 | ||
93 | #define H_NOT_ACTIVE -71 | ||
94 | #define H_SG_LIST -72 | ||
95 | #define H_OP_MODE -73 | ||
96 | #define H_COP_HW -74 | ||
97 | #define H_UNSUPPORTED_FLAG_START -256 | ||
98 | #define H_UNSUPPORTED_FLAG_END -511 | ||
99 | #define H_MULTI_THREADS_ACTIVE -9005 | ||
100 | #define H_OUTSTANDING_COP_OPS -9006 | ||
82 | 101 | ||
83 | 102 | ||
84 | /* Long Busy is a condition that can be returned by the firmware | 103 | /* Long Busy is a condition that can be returned by the firmware |
@@ -240,6 +259,8 @@ | |||
240 | #define H_GET_MPP 0x2D4 | 259 | #define H_GET_MPP 0x2D4 |
241 | #define H_HOME_NODE_ASSOCIATIVITY 0x2EC | 260 | #define H_HOME_NODE_ASSOCIATIVITY 0x2EC |
242 | #define H_BEST_ENERGY 0x2F4 | 261 | #define H_BEST_ENERGY 0x2F4 |
262 | #define H_RANDOM 0x300 | ||
263 | #define H_COP 0x304 | ||
243 | #define H_GET_MPP_X 0x314 | 264 | #define H_GET_MPP_X 0x314 |
244 | #define MAX_HCALL_OPCODE H_GET_MPP_X | 265 | #define MAX_HCALL_OPCODE H_GET_MPP_X |
245 | 266 | ||
diff --git a/arch/powerpc/include/asm/lppaca.h b/arch/powerpc/include/asm/lppaca.h index a76254af0aaa..531fe0c3108f 100644 --- a/arch/powerpc/include/asm/lppaca.h +++ b/arch/powerpc/include/asm/lppaca.h | |||
@@ -20,18 +20,16 @@ | |||
20 | #define _ASM_POWERPC_LPPACA_H | 20 | #define _ASM_POWERPC_LPPACA_H |
21 | #ifdef __KERNEL__ | 21 | #ifdef __KERNEL__ |
22 | 22 | ||
23 | /* These definitions relate to hypervisors that only exist when using | 23 | /* |
24 | * These definitions relate to hypervisors that only exist when using | ||
24 | * a server type processor | 25 | * a server type processor |
25 | */ | 26 | */ |
26 | #ifdef CONFIG_PPC_BOOK3S | 27 | #ifdef CONFIG_PPC_BOOK3S |
27 | 28 | ||
28 | //============================================================================= | 29 | /* |
29 | // | 30 | * This control block contains the data that is shared between the |
30 | // This control block contains the data that is shared between the | 31 | * hypervisor and the OS. |
31 | // hypervisor (PLIC) and the OS. | 32 | */ |
32 | // | ||
33 | // | ||
34 | //---------------------------------------------------------------------------- | ||
35 | #include <linux/cache.h> | 33 | #include <linux/cache.h> |
36 | #include <linux/threads.h> | 34 | #include <linux/threads.h> |
37 | #include <asm/types.h> | 35 | #include <asm/types.h> |
@@ -43,123 +41,65 @@ | |||
43 | */ | 41 | */ |
44 | #define NR_LPPACAS 1 | 42 | #define NR_LPPACAS 1 |
45 | 43 | ||
46 | 44 | /* | |
47 | /* The Hypervisor barfs if the lppaca crosses a page boundary. A 1k | 45 | * The Hypervisor barfs if the lppaca crosses a page boundary. A 1k |
48 | * alignment is sufficient to prevent this */ | 46 | * alignment is sufficient to prevent this |
47 | */ | ||
49 | struct lppaca { | 48 | struct lppaca { |
50 | //============================================================================= | 49 | /* cacheline 1 contains read-only data */ |
51 | // CACHE_LINE_1 0x0000 - 0x007F Contains read-only data | 50 | |
52 | // NOTE: The xDynXyz fields are fields that will be dynamically changed by | 51 | u32 desc; /* Eye catcher 0xD397D781 */ |
53 | // PLIC when preparing to bring a processor online or when dispatching a | 52 | u16 size; /* Size of this struct */ |
54 | // virtual processor! | 53 | u16 reserved1; |
55 | //============================================================================= | 54 | u16 reserved2:14; |
56 | u32 desc; // Eye catcher 0xD397D781 x00-x03 | 55 | u8 shared_proc:1; /* Shared processor indicator */ |
57 | u16 size; // Size of this struct x04-x05 | 56 | u8 secondary_thread:1; /* Secondary thread indicator */ |
58 | u16 reserved1; // Reserved x06-x07 | 57 | u8 reserved3[14]; |
59 | u16 reserved2:14; // Reserved x08-x09 | 58 | volatile u32 dyn_hw_node_id; /* Dynamic hardware node id */ |
60 | u8 shared_proc:1; // Shared processor indicator ... | 59 | volatile u32 dyn_hw_proc_id; /* Dynamic hardware proc id */ |
61 | u8 secondary_thread:1; // Secondary thread indicator ... | 60 | u8 reserved4[56]; |
62 | volatile u8 dyn_proc_status:8; // Dynamic Status of this proc x0A-x0A | 61 | volatile u8 vphn_assoc_counts[8]; /* Virtual processor home node */ |
63 | u8 secondary_thread_count; // Secondary thread count x0B-x0B | 62 | /* associativity change counters */ |
64 | volatile u16 dyn_hv_phys_proc_index;// Dynamic HV Physical Proc Index0C-x0D | 63 | u8 reserved5[32]; |
65 | volatile u16 dyn_hv_log_proc_index;// Dynamic HV Logical Proc Indexx0E-x0F | 64 | |
66 | u32 decr_val; // Value for Decr programming x10-x13 | 65 | /* cacheline 2 contains local read-write data */ |
67 | u32 pmc_val; // Value for PMC regs x14-x17 | 66 | |
68 | volatile u32 dyn_hw_node_id; // Dynamic Hardware Node id x18-x1B | 67 | u8 reserved6[48]; |
69 | volatile u32 dyn_hw_proc_id; // Dynamic Hardware Proc Id x1C-x1F | 68 | u8 cede_latency_hint; |
70 | volatile u32 dyn_pir; // Dynamic ProcIdReg value x20-x23 | 69 | u8 reserved7[7]; |
71 | u32 dsei_data; // DSEI data x24-x27 | 70 | u8 dtl_enable_mask; /* Dispatch Trace Log mask */ |
72 | u64 sprg3; // SPRG3 value x28-x2F | 71 | u8 donate_dedicated_cpu; /* Donate dedicated CPU cycles */ |
73 | u8 reserved3[40]; // Reserved x30-x57 | 72 | u8 fpregs_in_use; |
74 | volatile u8 vphn_assoc_counts[8]; // Virtual processor home node | 73 | u8 pmcregs_in_use; |
75 | // associativity change counters x58-x5F | 74 | u8 reserved8[28]; |
76 | u8 reserved4[32]; // Reserved x60-x7F | 75 | u64 wait_state_cycles; /* Wait cycles for this proc */ |
77 | 76 | u8 reserved9[28]; | |
78 | //============================================================================= | 77 | u16 slb_count; /* # of SLBs to maintain */ |
79 | // CACHE_LINE_2 0x0080 - 0x00FF Contains local read-write data | 78 | u8 idle; /* Indicate OS is idle */ |
80 | //============================================================================= | 79 | u8 vmxregs_in_use; |
81 | // This Dword contains a byte for each type of interrupt that can occur. | 80 | |
82 | // The IPI is a count while the others are just a binary 1 or 0. | 81 | /* cacheline 3 is shared with other processors */ |
83 | union { | 82 | |
84 | u64 any_int; | 83 | /* |
85 | struct { | 84 | * This is the yield_count. An "odd" value (low bit on) means that |
86 | u16 reserved; // Reserved - cleared by #mpasmbl | 85 | * the processor is yielded (either because of an OS yield or a |
87 | u8 xirr_int; // Indicates xXirrValue is valid or Immed IO | 86 | * hypervisor preempt). An even value implies that the processor is |
88 | u8 ipi_cnt; // IPI Count | 87 | * currently executing. |
89 | u8 decr_int; // DECR interrupt occurred | 88 | * NOTE: This value will ALWAYS be zero for dedicated processors and |
90 | u8 pdc_int; // PDC interrupt occurred | 89 | * will NEVER be zero for shared processors (ie, initialized to a 1). |
91 | u8 quantum_int; // Interrupt quantum reached | 90 | */ |
92 | u8 old_plic_deferred_ext_int; // Old PLIC has a deferred XIRR pending | 91 | volatile u32 yield_count; |
93 | } fields; | 92 | volatile u32 dispersion_count; /* dispatch changed physical cpu */ |
94 | } int_dword; | 93 | volatile u64 cmo_faults; /* CMO page fault count */ |
95 | 94 | volatile u64 cmo_fault_time; /* CMO page fault time */ | |
96 | // Whenever any fields in this Dword are set then PLIC will defer the | 95 | u8 reserved10[104]; |
97 | // processing of external interrupts. Note that PLIC will store the | 96 | |
98 | // XIRR directly into the xXirrValue field so that another XIRR will | 97 | /* cacheline 4-5 */ |
99 | // not be presented until this one clears. The layout of the low | 98 | |
100 | // 4-bytes of this Dword is up to SLIC - PLIC just checks whether the | 99 | u32 page_ins; /* CMO Hint - # page ins by OS */ |
101 | // entire Dword is zero or not. A non-zero value in the low order | 100 | u8 reserved11[148]; |
102 | // 2-bytes will result in SLIC being granted the highest thread | 101 | volatile u64 dtl_idx; /* Dispatch Trace Log head index */ |
103 | // priority upon return. A 0 will return to SLIC as medium priority. | 102 | u8 reserved12[96]; |
104 | u64 plic_defer_ints_area; // Entire Dword | ||
105 | |||
106 | // Used to pass the real SRR0/1 from PLIC to SLIC as well as to | ||
107 | // pass the target SRR0/1 from SLIC to PLIC on a SetAsrAndRfid. | ||
108 | u64 saved_srr0; // Saved SRR0 x10-x17 | ||
109 | u64 saved_srr1; // Saved SRR1 x18-x1F | ||
110 | |||
111 | // Used to pass parms from the OS to PLIC for SetAsrAndRfid | ||
112 | u64 saved_gpr3; // Saved GPR3 x20-x27 | ||
113 | u64 saved_gpr4; // Saved GPR4 x28-x2F | ||
114 | union { | ||
115 | u64 saved_gpr5; /* Saved GPR5 x30-x37 */ | ||
116 | struct { | ||
117 | u8 cede_latency_hint; /* x30 */ | ||
118 | u8 reserved[7]; /* x31-x36 */ | ||
119 | } fields; | ||
120 | } gpr5_dword; | ||
121 | |||
122 | |||
123 | u8 dtl_enable_mask; // Dispatch Trace Log mask x38-x38 | ||
124 | u8 donate_dedicated_cpu; // Donate dedicated CPU cycles x39-x39 | ||
125 | u8 fpregs_in_use; // FP regs in use x3A-x3A | ||
126 | u8 pmcregs_in_use; // PMC regs in use x3B-x3B | ||
127 | volatile u32 saved_decr; // Saved Decr Value x3C-x3F | ||
128 | volatile u64 emulated_time_base;// Emulated TB for this thread x40-x47 | ||
129 | volatile u64 cur_plic_latency; // Unaccounted PLIC latency x48-x4F | ||
130 | u64 tot_plic_latency; // Accumulated PLIC latency x50-x57 | ||
131 | u64 wait_state_cycles; // Wait cycles for this proc x58-x5F | ||
132 | u64 end_of_quantum; // TB at end of quantum x60-x67 | ||
133 | u64 pdc_saved_sprg1; // Saved SPRG1 for PMC int x68-x6F | ||
134 | u64 pdc_saved_srr0; // Saved SRR0 for PMC int x70-x77 | ||
135 | volatile u32 virtual_decr; // Virtual DECR for shared procsx78-x7B | ||
136 | u16 slb_count; // # of SLBs to maintain x7C-x7D | ||
137 | u8 idle; // Indicate OS is idle x7E | ||
138 | u8 vmxregs_in_use; // VMX registers in use x7F | ||
139 | |||
140 | |||
141 | //============================================================================= | ||
142 | // CACHE_LINE_3 0x0100 - 0x017F: This line is shared with other processors | ||
143 | //============================================================================= | ||
144 | // This is the yield_count. An "odd" value (low bit on) means that | ||
145 | // the processor is yielded (either because of an OS yield or a PLIC | ||
146 | // preempt). An even value implies that the processor is currently | ||
147 | // executing. | ||
148 | // NOTE: This value will ALWAYS be zero for dedicated processors and | ||
149 | // will NEVER be zero for shared processors (ie, initialized to a 1). | ||
150 | volatile u32 yield_count; // PLIC increments each dispatchx00-x03 | ||
151 | volatile u32 dispersion_count; // dispatch changed phys cpu x04-x07 | ||
152 | volatile u64 cmo_faults; // CMO page fault count x08-x0F | ||
153 | volatile u64 cmo_fault_time; // CMO page fault time x10-x17 | ||
154 | u8 reserved7[104]; // Reserved x18-x7F | ||
155 | |||
156 | //============================================================================= | ||
157 | // CACHE_LINE_4-5 0x0180 - 0x027F Contains PMC interrupt data | ||
158 | //============================================================================= | ||
159 | u32 page_ins; // CMO Hint - # page ins by OS x00-x03 | ||
160 | u8 reserved8[148]; // Reserved x04-x97 | ||
161 | volatile u64 dtl_idx; // Dispatch Trace Log head idx x98-x9F | ||
162 | u8 reserved9[96]; // Reserved xA0-xFF | ||
163 | } __attribute__((__aligned__(0x400))); | 103 | } __attribute__((__aligned__(0x400))); |
164 | 104 | ||
165 | extern struct lppaca lppaca[]; | 105 | extern struct lppaca lppaca[]; |
@@ -172,13 +112,13 @@ extern struct lppaca lppaca[]; | |||
172 | * ESID is stored in the lower 64bits, then the VSID. | 112 | * ESID is stored in the lower 64bits, then the VSID. |
173 | */ | 113 | */ |
174 | struct slb_shadow { | 114 | struct slb_shadow { |
175 | u32 persistent; // Number of persistent SLBs x00-x03 | 115 | u32 persistent; /* Number of persistent SLBs */ |
176 | u32 buffer_length; // Total shadow buffer length x04-x07 | 116 | u32 buffer_length; /* Total shadow buffer length */ |
177 | u64 reserved; // Alignment x08-x0f | 117 | u64 reserved; |
178 | struct { | 118 | struct { |
179 | u64 esid; | 119 | u64 esid; |
180 | u64 vsid; | 120 | u64 vsid; |
181 | } save_area[SLB_NUM_BOLTED]; // x10-x40 | 121 | } save_area[SLB_NUM_BOLTED]; |
182 | } ____cacheline_aligned; | 122 | } ____cacheline_aligned; |
183 | 123 | ||
184 | extern struct slb_shadow slb_shadow[]; | 124 | extern struct slb_shadow slb_shadow[]; |
diff --git a/arch/powerpc/include/asm/lv1call.h b/arch/powerpc/include/asm/lv1call.h index 233f9ecae761..f5117674bf92 100644 --- a/arch/powerpc/include/asm/lv1call.h +++ b/arch/powerpc/include/asm/lv1call.h | |||
@@ -265,8 +265,8 @@ LV1_CALL(get_spe_irq_outlet, 2, 1, 78 ) | |||
265 | LV1_CALL(set_spe_privilege_state_area_1_register, 3, 0, 79 ) | 265 | LV1_CALL(set_spe_privilege_state_area_1_register, 3, 0, 79 ) |
266 | LV1_CALL(create_repository_node, 6, 0, 90 ) | 266 | LV1_CALL(create_repository_node, 6, 0, 90 ) |
267 | LV1_CALL(read_repository_node, 5, 2, 91 ) | 267 | LV1_CALL(read_repository_node, 5, 2, 91 ) |
268 | LV1_CALL(modify_repository_node_value, 6, 0, 92 ) | 268 | LV1_CALL(write_repository_node, 6, 0, 92 ) |
269 | LV1_CALL(remove_repository_node, 4, 0, 93 ) | 269 | LV1_CALL(delete_repository_node, 4, 0, 93 ) |
270 | LV1_CALL(read_htab_entries, 2, 5, 95 ) | 270 | LV1_CALL(read_htab_entries, 2, 5, 95 ) |
271 | LV1_CALL(set_dabr, 2, 0, 96 ) | 271 | LV1_CALL(set_dabr, 2, 0, 96 ) |
272 | LV1_CALL(get_total_execution_time, 2, 1, 103 ) | 272 | LV1_CALL(get_total_execution_time, 2, 1, 103 ) |
diff --git a/arch/powerpc/include/asm/pSeries_reconfig.h b/arch/powerpc/include/asm/pSeries_reconfig.h index 23cd6cc30bcf..c07edfe98b98 100644 --- a/arch/powerpc/include/asm/pSeries_reconfig.h +++ b/arch/powerpc/include/asm/pSeries_reconfig.h | |||
@@ -13,6 +13,18 @@ | |||
13 | #define PSERIES_RECONFIG_REMOVE 0x0002 | 13 | #define PSERIES_RECONFIG_REMOVE 0x0002 |
14 | #define PSERIES_DRCONF_MEM_ADD 0x0003 | 14 | #define PSERIES_DRCONF_MEM_ADD 0x0003 |
15 | #define PSERIES_DRCONF_MEM_REMOVE 0x0004 | 15 | #define PSERIES_DRCONF_MEM_REMOVE 0x0004 |
16 | #define PSERIES_UPDATE_PROPERTY 0x0005 | ||
17 | |||
18 | /** | ||
19 | * pSeries_reconfig_notify - Notifier value structure for OFDT property updates | ||
20 | * | ||
21 | * @node: Device tree node which owns the property being updated | ||
22 | * @property: Updated property | ||
23 | */ | ||
24 | struct pSeries_reconfig_prop_update { | ||
25 | struct device_node *node; | ||
26 | struct property *property; | ||
27 | }; | ||
16 | 28 | ||
17 | #ifdef CONFIG_PPC_PSERIES | 29 | #ifdef CONFIG_PPC_PSERIES |
18 | extern int pSeries_reconfig_notifier_register(struct notifier_block *); | 30 | extern int pSeries_reconfig_notifier_register(struct notifier_block *); |
diff --git a/arch/powerpc/include/asm/ppc_asm.h b/arch/powerpc/include/asm/ppc_asm.h index 50f73aa2ba21..15444204a3a1 100644 --- a/arch/powerpc/include/asm/ppc_asm.h +++ b/arch/powerpc/include/asm/ppc_asm.h | |||
@@ -369,7 +369,15 @@ BEGIN_FTR_SECTION \ | |||
369 | END_FTR_SECTION_IFCLR(CPU_FTR_601) | 369 | END_FTR_SECTION_IFCLR(CPU_FTR_601) |
370 | #endif | 370 | #endif |
371 | 371 | ||
372 | 372 | #ifdef CONFIG_PPC64 | |
373 | #define MTOCRF(FXM, RS) \ | ||
374 | BEGIN_FTR_SECTION_NESTED(848); \ | ||
375 | mtcrf (FXM), (RS); \ | ||
376 | FTR_SECTION_ELSE_NESTED(848); \ | ||
377 | mtocrf (FXM), (RS); \ | ||
378 | ALT_FTR_SECTION_END_NESTED_IFCLR(CPU_FTR_NOEXECUTE, 848) | ||
379 | #endif | ||
380 | |||
373 | /* | 381 | /* |
374 | * This instruction is not implemented on the PPC 603 or 601; however, on | 382 | * This instruction is not implemented on the PPC 603 or 601; however, on |
375 | * the 403GCX and 405GP tlbia IS defined and tlbie is not. | 383 | * the 403GCX and 405GP tlbia IS defined and tlbie is not. |
diff --git a/arch/powerpc/include/asm/ptrace.h b/arch/powerpc/include/asm/ptrace.h index 84cc7840cd18..9c21ed42aba6 100644 --- a/arch/powerpc/include/asm/ptrace.h +++ b/arch/powerpc/include/asm/ptrace.h | |||
@@ -354,12 +354,6 @@ static inline unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, | |||
354 | #define PTRACE_GETREGS64 22 | 354 | #define PTRACE_GETREGS64 22 |
355 | #define PTRACE_SETREGS64 23 | 355 | #define PTRACE_SETREGS64 23 |
356 | 356 | ||
357 | /* (old) PTRACE requests with inverted arguments */ | ||
358 | #define PPC_PTRACE_GETREGS 0x99 /* Get GPRs 0 - 31 */ | ||
359 | #define PPC_PTRACE_SETREGS 0x98 /* Set GPRs 0 - 31 */ | ||
360 | #define PPC_PTRACE_GETFPREGS 0x97 /* Get FPRs 0 - 31 */ | ||
361 | #define PPC_PTRACE_SETFPREGS 0x96 /* Set FPRs 0 - 31 */ | ||
362 | |||
363 | /* Calls to trace a 64bit program from a 32bit program */ | 357 | /* Calls to trace a 64bit program from a 32bit program */ |
364 | #define PPC_PTRACE_PEEKTEXT_3264 0x95 | 358 | #define PPC_PTRACE_PEEKTEXT_3264 0x95 |
365 | #define PPC_PTRACE_PEEKDATA_3264 0x94 | 359 | #define PPC_PTRACE_PEEKDATA_3264 0x94 |
diff --git a/arch/powerpc/include/asm/switch_to.h b/arch/powerpc/include/asm/switch_to.h index caf82d0a00de..1a6320290d26 100644 --- a/arch/powerpc/include/asm/switch_to.h +++ b/arch/powerpc/include/asm/switch_to.h | |||
@@ -21,7 +21,6 @@ extern void disable_kernel_fp(void); | |||
21 | extern void enable_kernel_fp(void); | 21 | extern void enable_kernel_fp(void); |
22 | extern void flush_fp_to_thread(struct task_struct *); | 22 | extern void flush_fp_to_thread(struct task_struct *); |
23 | extern void enable_kernel_altivec(void); | 23 | extern void enable_kernel_altivec(void); |
24 | extern void giveup_altivec(struct task_struct *); | ||
25 | extern void load_up_altivec(struct task_struct *); | 24 | extern void load_up_altivec(struct task_struct *); |
26 | extern int emulate_altivec(struct pt_regs *); | 25 | extern int emulate_altivec(struct pt_regs *); |
27 | extern void __giveup_vsx(struct task_struct *); | 26 | extern void __giveup_vsx(struct task_struct *); |
@@ -40,10 +39,15 @@ static inline void discard_lazy_cpu_state(void) | |||
40 | 39 | ||
41 | #ifdef CONFIG_ALTIVEC | 40 | #ifdef CONFIG_ALTIVEC |
42 | extern void flush_altivec_to_thread(struct task_struct *); | 41 | extern void flush_altivec_to_thread(struct task_struct *); |
42 | extern void giveup_altivec(struct task_struct *); | ||
43 | extern void giveup_altivec_notask(void); | ||
43 | #else | 44 | #else |
44 | static inline void flush_altivec_to_thread(struct task_struct *t) | 45 | static inline void flush_altivec_to_thread(struct task_struct *t) |
45 | { | 46 | { |
46 | } | 47 | } |
48 | static inline void giveup_altivec(struct task_struct *t) | ||
49 | { | ||
50 | } | ||
47 | #endif | 51 | #endif |
48 | 52 | ||
49 | #ifdef CONFIG_VSX | 53 | #ifdef CONFIG_VSX |
diff --git a/arch/powerpc/include/asm/thread_info.h b/arch/powerpc/include/asm/thread_info.h index 1a1bb00f061a..a556ccc16b58 100644 --- a/arch/powerpc/include/asm/thread_info.h +++ b/arch/powerpc/include/asm/thread_info.h | |||
@@ -113,7 +113,6 @@ static inline struct thread_info *current_thread_info(void) | |||
113 | #define _TIF_NOERROR (1<<TIF_NOERROR) | 113 | #define _TIF_NOERROR (1<<TIF_NOERROR) |
114 | #define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME) | 114 | #define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME) |
115 | #define _TIF_SYSCALL_TRACEPOINT (1<<TIF_SYSCALL_TRACEPOINT) | 115 | #define _TIF_SYSCALL_TRACEPOINT (1<<TIF_SYSCALL_TRACEPOINT) |
116 | #define _TIF_RUNLATCH (1<<TIF_RUNLATCH) | ||
117 | #define _TIF_SYSCALL_T_OR_A (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \ | 116 | #define _TIF_SYSCALL_T_OR_A (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \ |
118 | _TIF_SECCOMP | _TIF_SYSCALL_TRACEPOINT) | 117 | _TIF_SECCOMP | _TIF_SYSCALL_TRACEPOINT) |
119 | 118 | ||
diff --git a/arch/powerpc/include/asm/vio.h b/arch/powerpc/include/asm/vio.h index 6bfd5ffe1d4f..b19adf751dd9 100644 --- a/arch/powerpc/include/asm/vio.h +++ b/arch/powerpc/include/asm/vio.h | |||
@@ -46,6 +46,48 @@ | |||
46 | 46 | ||
47 | struct iommu_table; | 47 | struct iommu_table; |
48 | 48 | ||
49 | /* | ||
50 | * Platform Facilities Option (PFO)-specific data | ||
51 | */ | ||
52 | |||
53 | /* Starting unit address for PFO devices on the VIO BUS */ | ||
54 | #define VIO_BASE_PFO_UA 0x50000000 | ||
55 | |||
56 | /** | ||
57 | * vio_pfo_op - PFO operation parameters | ||
58 | * | ||
59 | * @flags: h_call subfunctions and modifiers | ||
60 | * @in: Input data block logical real address | ||
61 | * @inlen: If non-negative, the length of the input data block. If negative, | ||
62 | * the length of the input data descriptor list in bytes. | ||
63 | * @out: Output data block logical real address | ||
64 | * @outlen: If non-negative, the length of the input data block. If negative, | ||
65 | * the length of the input data descriptor list in bytes. | ||
66 | * @csbcpb: Logical real address of the 4k naturally-aligned storage block | ||
67 | * containing the CSB & optional FC field specific CPB | ||
68 | * @timeout: # of milliseconds to retry h_call, 0 for no timeout. | ||
69 | * @hcall_err: pointer to return the h_call return value, else NULL | ||
70 | */ | ||
71 | struct vio_pfo_op { | ||
72 | u64 flags; | ||
73 | s64 in; | ||
74 | s64 inlen; | ||
75 | s64 out; | ||
76 | s64 outlen; | ||
77 | u64 csbcpb; | ||
78 | void *done; | ||
79 | unsigned long handle; | ||
80 | unsigned int timeout; | ||
81 | long hcall_err; | ||
82 | }; | ||
83 | |||
84 | /* End PFO specific data */ | ||
85 | |||
86 | enum vio_dev_family { | ||
87 | VDEVICE, /* The OF node is a child of /vdevice */ | ||
88 | PFO, /* The OF node is a child of /ibm,platform-facilities */ | ||
89 | }; | ||
90 | |||
49 | /** | 91 | /** |
50 | * vio_dev - This structure is used to describe virtual I/O devices. | 92 | * vio_dev - This structure is used to describe virtual I/O devices. |
51 | * | 93 | * |
@@ -58,6 +100,7 @@ struct vio_dev { | |||
58 | const char *name; | 100 | const char *name; |
59 | const char *type; | 101 | const char *type; |
60 | uint32_t unit_address; | 102 | uint32_t unit_address; |
103 | uint32_t resource_id; | ||
61 | unsigned int irq; | 104 | unsigned int irq; |
62 | struct { | 105 | struct { |
63 | size_t desired; | 106 | size_t desired; |
@@ -65,6 +108,7 @@ struct vio_dev { | |||
65 | size_t allocated; | 108 | size_t allocated; |
66 | atomic_t allocs_failed; | 109 | atomic_t allocs_failed; |
67 | } cmo; | 110 | } cmo; |
111 | enum vio_dev_family family; | ||
68 | struct device dev; | 112 | struct device dev; |
69 | }; | 113 | }; |
70 | 114 | ||
@@ -95,6 +139,8 @@ extern void vio_cmo_set_dev_desired(struct vio_dev *viodev, size_t desired); | |||
95 | 139 | ||
96 | extern void __devinit vio_unregister_device(struct vio_dev *dev); | 140 | extern void __devinit vio_unregister_device(struct vio_dev *dev); |
97 | 141 | ||
142 | extern int vio_h_cop_sync(struct vio_dev *vdev, struct vio_pfo_op *op); | ||
143 | |||
98 | struct device_node; | 144 | struct device_node; |
99 | 145 | ||
100 | extern struct vio_dev *vio_register_device_node( | 146 | extern struct vio_dev *vio_register_device_node( |
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 34b8afe94a50..4554dc2fe857 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c | |||
@@ -188,10 +188,6 @@ int main(void) | |||
188 | DEFINE(SLBSHADOW_STACKESID, | 188 | DEFINE(SLBSHADOW_STACKESID, |
189 | offsetof(struct slb_shadow, save_area[SLB_NUM_BOLTED - 1].esid)); | 189 | offsetof(struct slb_shadow, save_area[SLB_NUM_BOLTED - 1].esid)); |
190 | DEFINE(SLBSHADOW_SAVEAREA, offsetof(struct slb_shadow, save_area)); | 190 | DEFINE(SLBSHADOW_SAVEAREA, offsetof(struct slb_shadow, save_area)); |
191 | DEFINE(LPPACASRR0, offsetof(struct lppaca, saved_srr0)); | ||
192 | DEFINE(LPPACASRR1, offsetof(struct lppaca, saved_srr1)); | ||
193 | DEFINE(LPPACAANYINT, offsetof(struct lppaca, int_dword.any_int)); | ||
194 | DEFINE(LPPACADECRINT, offsetof(struct lppaca, int_dword.fields.decr_int)); | ||
195 | DEFINE(LPPACA_PMCINUSE, offsetof(struct lppaca, pmcregs_in_use)); | 191 | DEFINE(LPPACA_PMCINUSE, offsetof(struct lppaca, pmcregs_in_use)); |
196 | DEFINE(LPPACA_DTLIDX, offsetof(struct lppaca, dtl_idx)); | 192 | DEFINE(LPPACA_DTLIDX, offsetof(struct lppaca, dtl_idx)); |
197 | DEFINE(LPPACA_YIELDCOUNT, offsetof(struct lppaca, yield_count)); | 193 | DEFINE(LPPACA_YIELDCOUNT, offsetof(struct lppaca, yield_count)); |
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index ef2074c3e906..ed1718feb9d9 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S | |||
@@ -63,15 +63,9 @@ system_call_common: | |||
63 | std r0,GPR0(r1) | 63 | std r0,GPR0(r1) |
64 | std r10,GPR1(r1) | 64 | std r10,GPR1(r1) |
65 | ACCOUNT_CPU_USER_ENTRY(r10, r11) | 65 | ACCOUNT_CPU_USER_ENTRY(r10, r11) |
66 | /* | ||
67 | * This "crclr so" clears CR0.SO, which is the error indication on | ||
68 | * return from this system call. There must be no cmp instruction | ||
69 | * between it and the "mfcr r9" below, otherwise if XER.SO is set, | ||
70 | * CR0.SO will get set, causing all system calls to appear to fail. | ||
71 | */ | ||
72 | crclr so | ||
73 | std r2,GPR2(r1) | 66 | std r2,GPR2(r1) |
74 | std r3,GPR3(r1) | 67 | std r3,GPR3(r1) |
68 | mfcr r2 | ||
75 | std r4,GPR4(r1) | 69 | std r4,GPR4(r1) |
76 | std r5,GPR5(r1) | 70 | std r5,GPR5(r1) |
77 | std r6,GPR6(r1) | 71 | std r6,GPR6(r1) |
@@ -82,18 +76,20 @@ system_call_common: | |||
82 | std r11,GPR10(r1) | 76 | std r11,GPR10(r1) |
83 | std r11,GPR11(r1) | 77 | std r11,GPR11(r1) |
84 | std r11,GPR12(r1) | 78 | std r11,GPR12(r1) |
79 | std r11,_XER(r1) | ||
80 | std r11,_CTR(r1) | ||
85 | std r9,GPR13(r1) | 81 | std r9,GPR13(r1) |
86 | mfcr r9 | ||
87 | mflr r10 | 82 | mflr r10 |
83 | /* | ||
84 | * This clears CR0.SO (bit 28), which is the error indication on | ||
85 | * return from this system call. | ||
86 | */ | ||
87 | rldimi r2,r11,28,(63-28) | ||
88 | li r11,0xc01 | 88 | li r11,0xc01 |
89 | std r9,_CCR(r1) | ||
90 | std r10,_LINK(r1) | 89 | std r10,_LINK(r1) |
91 | std r11,_TRAP(r1) | 90 | std r11,_TRAP(r1) |
92 | mfxer r9 | ||
93 | mfctr r10 | ||
94 | std r9,_XER(r1) | ||
95 | std r10,_CTR(r1) | ||
96 | std r3,ORIG_GPR3(r1) | 91 | std r3,ORIG_GPR3(r1) |
92 | std r2,_CCR(r1) | ||
97 | ld r2,PACATOC(r13) | 93 | ld r2,PACATOC(r13) |
98 | addi r9,r1,STACK_FRAME_OVERHEAD | 94 | addi r9,r1,STACK_FRAME_OVERHEAD |
99 | ld r11,exception_marker@toc(r2) | 95 | ld r11,exception_marker@toc(r2) |
@@ -154,7 +150,7 @@ END_FW_FTR_SECTION_IFSET(FW_FEATURE_SPLPAR) | |||
154 | ld r10,TI_FLAGS(r11) | 150 | ld r10,TI_FLAGS(r11) |
155 | andi. r11,r10,_TIF_SYSCALL_T_OR_A | 151 | andi. r11,r10,_TIF_SYSCALL_T_OR_A |
156 | bne- syscall_dotrace | 152 | bne- syscall_dotrace |
157 | syscall_dotrace_cont: | 153 | .Lsyscall_dotrace_cont: |
158 | cmpldi 0,r0,NR_syscalls | 154 | cmpldi 0,r0,NR_syscalls |
159 | bge- syscall_enosys | 155 | bge- syscall_enosys |
160 | 156 | ||
@@ -211,7 +207,7 @@ syscall_exit: | |||
211 | cmpld r3,r11 | 207 | cmpld r3,r11 |
212 | ld r5,_CCR(r1) | 208 | ld r5,_CCR(r1) |
213 | bge- syscall_error | 209 | bge- syscall_error |
214 | syscall_error_cont: | 210 | .Lsyscall_error_cont: |
215 | ld r7,_NIP(r1) | 211 | ld r7,_NIP(r1) |
216 | BEGIN_FTR_SECTION | 212 | BEGIN_FTR_SECTION |
217 | stdcx. r0,0,r1 /* to clear the reservation */ | 213 | stdcx. r0,0,r1 /* to clear the reservation */ |
@@ -246,7 +242,7 @@ syscall_error: | |||
246 | oris r5,r5,0x1000 /* Set SO bit in CR */ | 242 | oris r5,r5,0x1000 /* Set SO bit in CR */ |
247 | neg r3,r3 | 243 | neg r3,r3 |
248 | std r5,_CCR(r1) | 244 | std r5,_CCR(r1) |
249 | b syscall_error_cont | 245 | b .Lsyscall_error_cont |
250 | 246 | ||
251 | /* Traced system call support */ | 247 | /* Traced system call support */ |
252 | syscall_dotrace: | 248 | syscall_dotrace: |
@@ -268,7 +264,7 @@ syscall_dotrace: | |||
268 | addi r9,r1,STACK_FRAME_OVERHEAD | 264 | addi r9,r1,STACK_FRAME_OVERHEAD |
269 | clrrdi r10,r1,THREAD_SHIFT | 265 | clrrdi r10,r1,THREAD_SHIFT |
270 | ld r10,TI_FLAGS(r10) | 266 | ld r10,TI_FLAGS(r10) |
271 | b syscall_dotrace_cont | 267 | b .Lsyscall_dotrace_cont |
272 | 268 | ||
273 | syscall_enosys: | 269 | syscall_enosys: |
274 | li r3,-ENOSYS | 270 | li r3,-ENOSYS |
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index 8f880bc77c56..f7bed44ee165 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S | |||
@@ -94,12 +94,10 @@ machine_check_pSeries_1: | |||
94 | data_access_pSeries: | 94 | data_access_pSeries: |
95 | HMT_MEDIUM | 95 | HMT_MEDIUM |
96 | SET_SCRATCH0(r13) | 96 | SET_SCRATCH0(r13) |
97 | #ifndef CONFIG_POWER4_ONLY | ||
98 | BEGIN_FTR_SECTION | 97 | BEGIN_FTR_SECTION |
99 | b data_access_check_stab | 98 | b data_access_check_stab |
100 | data_access_not_stab: | 99 | data_access_not_stab: |
101 | END_MMU_FTR_SECTION_IFCLR(MMU_FTR_SLB) | 100 | END_MMU_FTR_SECTION_IFCLR(MMU_FTR_SLB) |
102 | #endif | ||
103 | EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, data_access_common, EXC_STD, | 101 | EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, data_access_common, EXC_STD, |
104 | KVMTEST, 0x300) | 102 | KVMTEST, 0x300) |
105 | 103 | ||
@@ -301,7 +299,6 @@ machine_check_fwnmi: | |||
301 | EXC_STD, KVMTEST, 0x200) | 299 | EXC_STD, KVMTEST, 0x200) |
302 | KVM_HANDLER_SKIP(PACA_EXMC, EXC_STD, 0x200) | 300 | KVM_HANDLER_SKIP(PACA_EXMC, EXC_STD, 0x200) |
303 | 301 | ||
304 | #ifndef CONFIG_POWER4_ONLY | ||
305 | /* moved from 0x300 */ | 302 | /* moved from 0x300 */ |
306 | data_access_check_stab: | 303 | data_access_check_stab: |
307 | GET_PACA(r13) | 304 | GET_PACA(r13) |
@@ -328,7 +325,6 @@ do_stab_bolted_pSeries: | |||
328 | GET_SCRATCH0(r10) | 325 | GET_SCRATCH0(r10) |
329 | std r10,PACA_EXSLB+EX_R13(r13) | 326 | std r10,PACA_EXSLB+EX_R13(r13) |
330 | EXCEPTION_PROLOG_PSERIES_1(.do_stab_bolted, EXC_STD) | 327 | EXCEPTION_PROLOG_PSERIES_1(.do_stab_bolted, EXC_STD) |
331 | #endif /* CONFIG_POWER4_ONLY */ | ||
332 | 328 | ||
333 | KVM_HANDLER_SKIP(PACA_EXGEN, EXC_STD, 0x300) | 329 | KVM_HANDLER_SKIP(PACA_EXGEN, EXC_STD, 0x300) |
334 | KVM_HANDLER_SKIP(PACA_EXSLB, EXC_STD, 0x380) | 330 | KVM_HANDLER_SKIP(PACA_EXSLB, EXC_STD, 0x380) |
diff --git a/arch/powerpc/kernel/head_44x.S b/arch/powerpc/kernel/head_44x.S index 7dd2981bcc50..22d608e8bb7d 100644 --- a/arch/powerpc/kernel/head_44x.S +++ b/arch/powerpc/kernel/head_44x.S | |||
@@ -778,14 +778,6 @@ _GLOBAL(__fixup_440A_mcheck) | |||
778 | blr | 778 | blr |
779 | 779 | ||
780 | /* | 780 | /* |
781 | * extern void giveup_altivec(struct task_struct *prev) | ||
782 | * | ||
783 | * The 44x core does not have an AltiVec unit. | ||
784 | */ | ||
785 | _GLOBAL(giveup_altivec) | ||
786 | blr | ||
787 | |||
788 | /* | ||
789 | * extern void giveup_fpu(struct task_struct *prev) | 781 | * extern void giveup_fpu(struct task_struct *prev) |
790 | * | 782 | * |
791 | * The 44x core does not have an FPU. | 783 | * The 44x core does not have an FPU. |
diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S index 28e62598d0e8..de80e0f9a2bd 100644 --- a/arch/powerpc/kernel/head_fsl_booke.S +++ b/arch/powerpc/kernel/head_fsl_booke.S | |||
@@ -874,14 +874,6 @@ _GLOBAL(__setup_e500mc_ivors) | |||
874 | sync | 874 | sync |
875 | blr | 875 | blr |
876 | 876 | ||
877 | /* | ||
878 | * extern void giveup_altivec(struct task_struct *prev) | ||
879 | * | ||
880 | * The e500 core does not have an AltiVec unit. | ||
881 | */ | ||
882 | _GLOBAL(giveup_altivec) | ||
883 | blr | ||
884 | |||
885 | #ifdef CONFIG_SPE | 877 | #ifdef CONFIG_SPE |
886 | /* | 878 | /* |
887 | * extern void giveup_spe(struct task_struct *prev) | 879 | * extern void giveup_spe(struct task_struct *prev) |
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index 641da9e868ce..7835a5e1ea5f 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c | |||
@@ -587,7 +587,7 @@ int irq_choose_cpu(const struct cpumask *mask) | |||
587 | { | 587 | { |
588 | int cpuid; | 588 | int cpuid; |
589 | 589 | ||
590 | if (cpumask_equal(mask, cpu_all_mask)) { | 590 | if (cpumask_equal(mask, cpu_online_mask)) { |
591 | static int irq_rover; | 591 | static int irq_rover; |
592 | static DEFINE_RAW_SPINLOCK(irq_rover_lock); | 592 | static DEFINE_RAW_SPINLOCK(irq_rover_lock); |
593 | unsigned long flags; | 593 | unsigned long flags; |
diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S index 7cd07b42ca1a..386d57f66f28 100644 --- a/arch/powerpc/kernel/misc_32.S +++ b/arch/powerpc/kernel/misc_32.S | |||
@@ -738,8 +738,23 @@ relocate_new_kernel: | |||
738 | mr r5, r31 | 738 | mr r5, r31 |
739 | 739 | ||
740 | li r0, 0 | 740 | li r0, 0 |
741 | #elif defined(CONFIG_44x) && !defined(CONFIG_PPC_47x) | 741 | #elif defined(CONFIG_44x) |
742 | 742 | ||
743 | /* Save our parameters */ | ||
744 | mr r29, r3 | ||
745 | mr r30, r4 | ||
746 | mr r31, r5 | ||
747 | |||
748 | #ifdef CONFIG_PPC_47x | ||
749 | /* Check for 47x cores */ | ||
750 | mfspr r3,SPRN_PVR | ||
751 | srwi r3,r3,16 | ||
752 | cmplwi cr0,r3,PVR_476@h | ||
753 | beq setup_map_47x | ||
754 | cmplwi cr0,r3,PVR_476_ISS@h | ||
755 | beq setup_map_47x | ||
756 | #endif /* CONFIG_PPC_47x */ | ||
757 | |||
743 | /* | 758 | /* |
744 | * Code for setting up 1:1 mapping for PPC440x for KEXEC | 759 | * Code for setting up 1:1 mapping for PPC440x for KEXEC |
745 | * | 760 | * |
@@ -753,16 +768,15 @@ relocate_new_kernel: | |||
753 | * 5) Invalidate the tmp mapping. | 768 | * 5) Invalidate the tmp mapping. |
754 | * | 769 | * |
755 | * - Based on the kexec support code for FSL BookE | 770 | * - Based on the kexec support code for FSL BookE |
756 | * - Doesn't support 47x yet. | ||
757 | * | 771 | * |
758 | */ | 772 | */ |
759 | /* Save our parameters */ | ||
760 | mr r29, r3 | ||
761 | mr r30, r4 | ||
762 | mr r31, r5 | ||
763 | 773 | ||
764 | /* Load our MSR_IS and TID to MMUCR for TLB search */ | 774 | /* |
765 | mfspr r3,SPRN_PID | 775 | * Load the PID with kernel PID (0). |
776 | * Also load our MSR_IS and TID to MMUCR for TLB search. | ||
777 | */ | ||
778 | li r3, 0 | ||
779 | mtspr SPRN_PID, r3 | ||
766 | mfmsr r4 | 780 | mfmsr r4 |
767 | andi. r4,r4,MSR_IS@l | 781 | andi. r4,r4,MSR_IS@l |
768 | beq wmmucr | 782 | beq wmmucr |
@@ -900,6 +914,179 @@ next_tlb: | |||
900 | li r3, 0 | 914 | li r3, 0 |
901 | tlbwe r3, r24, PPC44x_TLB_PAGEID | 915 | tlbwe r3, r24, PPC44x_TLB_PAGEID |
902 | sync | 916 | sync |
917 | b ppc44x_map_done | ||
918 | |||
919 | #ifdef CONFIG_PPC_47x | ||
920 | |||
921 | /* 1:1 mapping for 47x */ | ||
922 | |||
923 | setup_map_47x: | ||
924 | |||
925 | /* | ||
926 | * Load the kernel pid (0) to PID and also to MMUCR[TID]. | ||
927 | * Also set the MSR IS->MMUCR STS | ||
928 | */ | ||
929 | li r3, 0 | ||
930 | mtspr SPRN_PID, r3 /* Set PID */ | ||
931 | mfmsr r4 /* Get MSR */ | ||
932 | andi. r4, r4, MSR_IS@l /* TS=1? */ | ||
933 | beq 1f /* If not, leave STS=0 */ | ||
934 | oris r3, r3, PPC47x_MMUCR_STS@h /* Set STS=1 */ | ||
935 | 1: mtspr SPRN_MMUCR, r3 /* Put MMUCR */ | ||
936 | sync | ||
937 | |||
938 | /* Find the entry we are running from */ | ||
939 | bl 2f | ||
940 | 2: mflr r23 | ||
941 | tlbsx r23, 0, r23 | ||
942 | tlbre r24, r23, 0 /* TLB Word 0 */ | ||
943 | tlbre r25, r23, 1 /* TLB Word 1 */ | ||
944 | tlbre r26, r23, 2 /* TLB Word 2 */ | ||
945 | |||
946 | |||
947 | /* | ||
948 | * Invalidates all the tlb entries by writing to 256 RPNs(r4) | ||
949 | * of 4k page size in all 4 ways (0-3 in r3). | ||
950 | * This would invalidate the entire UTLB including the one we are | ||
951 | * running from. However the shadow TLB entries would help us | ||
952 | * to continue the execution, until we flush them (rfi/isync). | ||
953 | */ | ||
954 | addis r3, 0, 0x8000 /* specify the way */ | ||
955 | addi r4, 0, 0 /* TLB Word0 = (EPN=0, VALID = 0) */ | ||
956 | addi r5, 0, 0 | ||
957 | b clear_utlb_entry | ||
958 | |||
959 | /* Align the loop to speed things up. from head_44x.S */ | ||
960 | .align 6 | ||
961 | |||
962 | clear_utlb_entry: | ||
963 | |||
964 | tlbwe r4, r3, 0 | ||
965 | tlbwe r5, r3, 1 | ||
966 | tlbwe r5, r3, 2 | ||
967 | addis r3, r3, 0x2000 /* Increment the way */ | ||
968 | cmpwi r3, 0 | ||
969 | bne clear_utlb_entry | ||
970 | addis r3, 0, 0x8000 | ||
971 | addis r4, r4, 0x100 /* Increment the EPN */ | ||
972 | cmpwi r4, 0 | ||
973 | bne clear_utlb_entry | ||
974 | |||
975 | /* Create the entries in the other address space */ | ||
976 | mfmsr r5 | ||
977 | rlwinm r7, r5, 27, 31, 31 /* Get the TS (Bit 26) from MSR */ | ||
978 | xori r7, r7, 1 /* r7 = !TS */ | ||
979 | |||
980 | insrwi r24, r7, 1, 21 /* Change the TS in the saved TLB word 0 */ | ||
981 | |||
982 | /* | ||
983 | * write out the TLB entries for the tmp mapping | ||
984 | * Use way '0' so that we could easily invalidate it later. | ||
985 | */ | ||
986 | lis r3, 0x8000 /* Way '0' */ | ||
987 | |||
988 | tlbwe r24, r3, 0 | ||
989 | tlbwe r25, r3, 1 | ||
990 | tlbwe r26, r3, 2 | ||
991 | |||
992 | /* Update the msr to the new TS */ | ||
993 | insrwi r5, r7, 1, 26 | ||
994 | |||
995 | bl 1f | ||
996 | 1: mflr r6 | ||
997 | addi r6, r6, (2f-1b) | ||
998 | |||
999 | mtspr SPRN_SRR0, r6 | ||
1000 | mtspr SPRN_SRR1, r5 | ||
1001 | rfi | ||
1002 | |||
1003 | /* | ||
1004 | * Now we are in the tmp address space. | ||
1005 | * Create a 1:1 mapping for 0-2GiB in the original TS. | ||
1006 | */ | ||
1007 | 2: | ||
1008 | li r3, 0 | ||
1009 | li r4, 0 /* TLB Word 0 */ | ||
1010 | li r5, 0 /* TLB Word 1 */ | ||
1011 | li r6, 0 | ||
1012 | ori r6, r6, PPC47x_TLB2_S_RWX /* TLB word 2 */ | ||
1013 | |||
1014 | li r8, 0 /* PageIndex */ | ||
1015 | |||
1016 | xori r7, r7, 1 /* revert back to original TS */ | ||
1017 | |||
1018 | write_utlb: | ||
1019 | rotlwi r5, r8, 28 /* RPN = PageIndex * 256M */ | ||
1020 | /* ERPN = 0 as we don't use memory above 2G */ | ||
1021 | |||
1022 | mr r4, r5 /* EPN = RPN */ | ||
1023 | ori r4, r4, (PPC47x_TLB0_VALID | PPC47x_TLB0_256M) | ||
1024 | insrwi r4, r7, 1, 21 /* Insert the TS to Word 0 */ | ||
1025 | |||
1026 | tlbwe r4, r3, 0 /* Write out the entries */ | ||
1027 | tlbwe r5, r3, 1 | ||
1028 | tlbwe r6, r3, 2 | ||
1029 | addi r8, r8, 1 | ||
1030 | cmpwi r8, 8 /* Have we completed ? */ | ||
1031 | bne write_utlb | ||
1032 | |||
1033 | /* make sure we complete the TLB write up */ | ||
1034 | isync | ||
1035 | |||
1036 | /* | ||
1037 | * Prepare to jump to the 1:1 mapping. | ||
1038 | * 1) Extract page size of the tmp mapping | ||
1039 | * DSIZ = TLB_Word0[22:27] | ||
1040 | * 2) Calculate the physical address of the address | ||
1041 | * to jump to. | ||
1042 | */ | ||
1043 | rlwinm r10, r24, 0, 22, 27 | ||
1044 | |||
1045 | cmpwi r10, PPC47x_TLB0_4K | ||
1046 | bne 0f | ||
1047 | li r10, 0x1000 /* r10 = 4k */ | ||
1048 | bl 1f | ||
1049 | |||
1050 | 0: | ||
1051 | /* Defaults to 256M */ | ||
1052 | lis r10, 0x1000 | ||
1053 | |||
1054 | bl 1f | ||
1055 | 1: mflr r4 | ||
1056 | addi r4, r4, (2f-1b) /* virtual address of 2f */ | ||
1057 | |||
1058 | subi r11, r10, 1 /* offsetmask = Pagesize - 1 */ | ||
1059 | not r10, r11 /* Pagemask = ~(offsetmask) */ | ||
1060 | |||
1061 | and r5, r25, r10 /* Physical page */ | ||
1062 | and r6, r4, r11 /* offset within the current page */ | ||
1063 | |||
1064 | or r5, r5, r6 /* Physical address for 2f */ | ||
1065 | |||
1066 | /* Switch the TS in MSR to the original one */ | ||
1067 | mfmsr r8 | ||
1068 | insrwi r8, r7, 1, 26 | ||
1069 | |||
1070 | mtspr SPRN_SRR1, r8 | ||
1071 | mtspr SPRN_SRR0, r5 | ||
1072 | rfi | ||
1073 | |||
1074 | 2: | ||
1075 | /* Invalidate the tmp mapping */ | ||
1076 | lis r3, 0x8000 /* Way '0' */ | ||
1077 | |||
1078 | clrrwi r24, r24, 12 /* Clear the valid bit */ | ||
1079 | tlbwe r24, r3, 0 | ||
1080 | tlbwe r25, r3, 1 | ||
1081 | tlbwe r26, r3, 2 | ||
1082 | |||
1083 | /* Make sure we complete the TLB write and flush the shadow TLB */ | ||
1084 | isync | ||
1085 | |||
1086 | #endif | ||
1087 | |||
1088 | ppc44x_map_done: | ||
1089 | |||
903 | 1090 | ||
904 | /* Restore the parameters */ | 1091 | /* Restore the parameters */ |
905 | mr r3, r29 | 1092 | mr r3, r29 |
diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c index 0bb1f98613ba..fbe1a12dc7f1 100644 --- a/arch/powerpc/kernel/paca.c +++ b/arch/powerpc/kernel/paca.c | |||
@@ -36,10 +36,7 @@ struct lppaca lppaca[] = { | |||
36 | [0 ... (NR_LPPACAS-1)] = { | 36 | [0 ... (NR_LPPACAS-1)] = { |
37 | .desc = 0xd397d781, /* "LpPa" */ | 37 | .desc = 0xd397d781, /* "LpPa" */ |
38 | .size = sizeof(struct lppaca), | 38 | .size = sizeof(struct lppaca), |
39 | .dyn_proc_status = 2, | ||
40 | .decr_val = 0x00ff0000, | ||
41 | .fpregs_in_use = 1, | 39 | .fpregs_in_use = 1, |
42 | .end_of_quantum = 0xfffffffffffffffful, | ||
43 | .slb_count = 64, | 40 | .slb_count = 64, |
44 | .vmxregs_in_use = 0, | 41 | .vmxregs_in_use = 0, |
45 | .page_ins = 0, | 42 | .page_ins = 0, |
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index aa05935b6947..7f8ec1de0ace 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c | |||
@@ -124,7 +124,7 @@ void enable_kernel_altivec(void) | |||
124 | if (current->thread.regs && (current->thread.regs->msr & MSR_VEC)) | 124 | if (current->thread.regs && (current->thread.regs->msr & MSR_VEC)) |
125 | giveup_altivec(current); | 125 | giveup_altivec(current); |
126 | else | 126 | else |
127 | giveup_altivec(NULL); /* just enable AltiVec for kernel - force */ | 127 | giveup_altivec_notask(); |
128 | #else | 128 | #else |
129 | giveup_altivec(last_task_used_altivec); | 129 | giveup_altivec(last_task_used_altivec); |
130 | #endif /* CONFIG_SMP */ | 130 | #endif /* CONFIG_SMP */ |
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index 99860273211b..1b488e5305c5 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c | |||
@@ -680,6 +680,9 @@ static void __init early_cmdline_parse(void) | |||
680 | #define OV3_VMX 0x40 /* VMX/Altivec */ | 680 | #define OV3_VMX 0x40 /* VMX/Altivec */ |
681 | #define OV3_DFP 0x20 /* decimal FP */ | 681 | #define OV3_DFP 0x20 /* decimal FP */ |
682 | 682 | ||
683 | /* Option vector 4: IBM PAPR implementation */ | ||
684 | #define OV4_MIN_ENT_CAP 0x01 /* minimum VP entitled capacity */ | ||
685 | |||
683 | /* Option vector 5: PAPR/OF options supported */ | 686 | /* Option vector 5: PAPR/OF options supported */ |
684 | #define OV5_LPAR 0x80 /* logical partitioning supported */ | 687 | #define OV5_LPAR 0x80 /* logical partitioning supported */ |
685 | #define OV5_SPLPAR 0x40 /* shared-processor LPAR supported */ | 688 | #define OV5_SPLPAR 0x40 /* shared-processor LPAR supported */ |
@@ -701,6 +704,8 @@ static void __init early_cmdline_parse(void) | |||
701 | #define OV5_XCMO 0x00 | 704 | #define OV5_XCMO 0x00 |
702 | #endif | 705 | #endif |
703 | #define OV5_TYPE1_AFFINITY 0x80 /* Type 1 NUMA affinity */ | 706 | #define OV5_TYPE1_AFFINITY 0x80 /* Type 1 NUMA affinity */ |
707 | #define OV5_PFO_HW_RNG 0x80 /* PFO Random Number Generator */ | ||
708 | #define OV5_PFO_HW_ENCR 0x20 /* PFO Encryption Accelerator */ | ||
704 | 709 | ||
705 | /* Option Vector 6: IBM PAPR hints */ | 710 | /* Option Vector 6: IBM PAPR hints */ |
706 | #define OV6_LINUX 0x02 /* Linux is our OS */ | 711 | #define OV6_LINUX 0x02 /* Linux is our OS */ |
@@ -744,11 +749,12 @@ static unsigned char ibm_architecture_vec[] = { | |||
744 | OV3_FP | OV3_VMX | OV3_DFP, | 749 | OV3_FP | OV3_VMX | OV3_DFP, |
745 | 750 | ||
746 | /* option vector 4: IBM PAPR implementation */ | 751 | /* option vector 4: IBM PAPR implementation */ |
747 | 2 - 2, /* length */ | 752 | 3 - 2, /* length */ |
748 | 0, /* don't halt */ | 753 | 0, /* don't halt */ |
754 | OV4_MIN_ENT_CAP, /* minimum VP entitled capacity */ | ||
749 | 755 | ||
750 | /* option vector 5: PAPR/OF options */ | 756 | /* option vector 5: PAPR/OF options */ |
751 | 13 - 2, /* length */ | 757 | 18 - 2, /* length */ |
752 | 0, /* don't ignore, don't halt */ | 758 | 0, /* don't ignore, don't halt */ |
753 | OV5_LPAR | OV5_SPLPAR | OV5_LARGE_PAGES | OV5_DRCONF_MEMORY | | 759 | OV5_LPAR | OV5_SPLPAR | OV5_LARGE_PAGES | OV5_DRCONF_MEMORY | |
754 | OV5_DONATE_DEDICATE_CPU | OV5_MSI, | 760 | OV5_DONATE_DEDICATE_CPU | OV5_MSI, |
@@ -762,8 +768,13 @@ static unsigned char ibm_architecture_vec[] = { | |||
762 | * must match by the macro below. Update the definition if | 768 | * must match by the macro below. Update the definition if |
763 | * the structure layout changes. | 769 | * the structure layout changes. |
764 | */ | 770 | */ |
765 | #define IBM_ARCH_VEC_NRCORES_OFFSET 100 | 771 | #define IBM_ARCH_VEC_NRCORES_OFFSET 101 |
766 | W(NR_CPUS), /* number of cores supported */ | 772 | W(NR_CPUS), /* number of cores supported */ |
773 | 0, | ||
774 | 0, | ||
775 | 0, | ||
776 | 0, | ||
777 | OV5_PFO_HW_RNG | OV5_PFO_HW_ENCR, | ||
767 | 778 | ||
768 | /* option vector 6: IBM PAPR hints */ | 779 | /* option vector 6: IBM PAPR hints */ |
769 | 4 - 2, /* length */ | 780 | 4 - 2, /* length */ |
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c index dd5e214cdf21..c10fc28b9092 100644 --- a/arch/powerpc/kernel/ptrace.c +++ b/arch/powerpc/kernel/ptrace.c | |||
@@ -1432,40 +1432,6 @@ static long ppc_del_hwdebug(struct task_struct *child, long addr, long data) | |||
1432 | #endif | 1432 | #endif |
1433 | } | 1433 | } |
1434 | 1434 | ||
1435 | /* | ||
1436 | * Here are the old "legacy" powerpc specific getregs/setregs ptrace calls, | ||
1437 | * we mark them as obsolete now, they will be removed in a future version | ||
1438 | */ | ||
1439 | static long arch_ptrace_old(struct task_struct *child, long request, | ||
1440 | unsigned long addr, unsigned long data) | ||
1441 | { | ||
1442 | void __user *datavp = (void __user *) data; | ||
1443 | |||
1444 | switch (request) { | ||
1445 | case PPC_PTRACE_GETREGS: /* Get GPRs 0 - 31. */ | ||
1446 | return copy_regset_to_user(child, &user_ppc_native_view, | ||
1447 | REGSET_GPR, 0, 32 * sizeof(long), | ||
1448 | datavp); | ||
1449 | |||
1450 | case PPC_PTRACE_SETREGS: /* Set GPRs 0 - 31. */ | ||
1451 | return copy_regset_from_user(child, &user_ppc_native_view, | ||
1452 | REGSET_GPR, 0, 32 * sizeof(long), | ||
1453 | datavp); | ||
1454 | |||
1455 | case PPC_PTRACE_GETFPREGS: /* Get FPRs 0 - 31. */ | ||
1456 | return copy_regset_to_user(child, &user_ppc_native_view, | ||
1457 | REGSET_FPR, 0, 32 * sizeof(double), | ||
1458 | datavp); | ||
1459 | |||
1460 | case PPC_PTRACE_SETFPREGS: /* Set FPRs 0 - 31. */ | ||
1461 | return copy_regset_from_user(child, &user_ppc_native_view, | ||
1462 | REGSET_FPR, 0, 32 * sizeof(double), | ||
1463 | datavp); | ||
1464 | } | ||
1465 | |||
1466 | return -EPERM; | ||
1467 | } | ||
1468 | |||
1469 | long arch_ptrace(struct task_struct *child, long request, | 1435 | long arch_ptrace(struct task_struct *child, long request, |
1470 | unsigned long addr, unsigned long data) | 1436 | unsigned long addr, unsigned long data) |
1471 | { | 1437 | { |
@@ -1687,14 +1653,6 @@ long arch_ptrace(struct task_struct *child, long request, | |||
1687 | datavp); | 1653 | datavp); |
1688 | #endif | 1654 | #endif |
1689 | 1655 | ||
1690 | /* Old reverse args ptrace callss */ | ||
1691 | case PPC_PTRACE_GETREGS: /* Get GPRs 0 - 31. */ | ||
1692 | case PPC_PTRACE_SETREGS: /* Set GPRs 0 - 31. */ | ||
1693 | case PPC_PTRACE_GETFPREGS: /* Get FPRs 0 - 31. */ | ||
1694 | case PPC_PTRACE_SETFPREGS: /* Get FPRs 0 - 31. */ | ||
1695 | ret = arch_ptrace_old(child, request, addr, data); | ||
1696 | break; | ||
1697 | |||
1698 | default: | 1656 | default: |
1699 | ret = ptrace_request(child, request, addr, data); | 1657 | ret = ptrace_request(child, request, addr, data); |
1700 | break; | 1658 | break; |
diff --git a/arch/powerpc/kernel/ptrace32.c b/arch/powerpc/kernel/ptrace32.c index 469349d14a97..8c21658719d9 100644 --- a/arch/powerpc/kernel/ptrace32.c +++ b/arch/powerpc/kernel/ptrace32.c | |||
@@ -39,30 +39,6 @@ | |||
39 | * in exit.c or in signal.c. | 39 | * in exit.c or in signal.c. |
40 | */ | 40 | */ |
41 | 41 | ||
42 | /* | ||
43 | * Here are the old "legacy" powerpc specific getregs/setregs ptrace calls, | ||
44 | * we mark them as obsolete now, they will be removed in a future version | ||
45 | */ | ||
46 | static long compat_ptrace_old(struct task_struct *child, long request, | ||
47 | long addr, long data) | ||
48 | { | ||
49 | switch (request) { | ||
50 | case PPC_PTRACE_GETREGS: /* Get GPRs 0 - 31. */ | ||
51 | return copy_regset_to_user(child, | ||
52 | task_user_regset_view(current), 0, | ||
53 | 0, 32 * sizeof(compat_long_t), | ||
54 | compat_ptr(data)); | ||
55 | |||
56 | case PPC_PTRACE_SETREGS: /* Set GPRs 0 - 31. */ | ||
57 | return copy_regset_from_user(child, | ||
58 | task_user_regset_view(current), 0, | ||
59 | 0, 32 * sizeof(compat_long_t), | ||
60 | compat_ptr(data)); | ||
61 | } | ||
62 | |||
63 | return -EPERM; | ||
64 | } | ||
65 | |||
66 | /* Macros to workout the correct index for the FPR in the thread struct */ | 42 | /* Macros to workout the correct index for the FPR in the thread struct */ |
67 | #define FPRNUMBER(i) (((i) - PT_FPR0) >> 1) | 43 | #define FPRNUMBER(i) (((i) - PT_FPR0) >> 1) |
68 | #define FPRHALF(i) (((i) - PT_FPR0) & 1) | 44 | #define FPRHALF(i) (((i) - PT_FPR0) & 1) |
@@ -308,8 +284,6 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request, | |||
308 | case PTRACE_SETVSRREGS: | 284 | case PTRACE_SETVSRREGS: |
309 | case PTRACE_GETREGS64: | 285 | case PTRACE_GETREGS64: |
310 | case PTRACE_SETREGS64: | 286 | case PTRACE_SETREGS64: |
311 | case PPC_PTRACE_GETFPREGS: | ||
312 | case PPC_PTRACE_SETFPREGS: | ||
313 | case PTRACE_KILL: | 287 | case PTRACE_KILL: |
314 | case PTRACE_SINGLESTEP: | 288 | case PTRACE_SINGLESTEP: |
315 | case PTRACE_DETACH: | 289 | case PTRACE_DETACH: |
@@ -322,12 +296,6 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request, | |||
322 | ret = arch_ptrace(child, request, addr, data); | 296 | ret = arch_ptrace(child, request, addr, data); |
323 | break; | 297 | break; |
324 | 298 | ||
325 | /* Old reverse args ptrace callss */ | ||
326 | case PPC_PTRACE_GETREGS: /* Get GPRs 0 - 31. */ | ||
327 | case PPC_PTRACE_SETREGS: /* Set GPRs 0 - 31. */ | ||
328 | ret = compat_ptrace_old(child, request, addr, data); | ||
329 | break; | ||
330 | |||
331 | default: | 299 | default: |
332 | ret = compat_ptrace_request(child, request, addr, data); | 300 | ret = compat_ptrace_request(child, request, addr, data); |
333 | break; | 301 | break; |
diff --git a/arch/powerpc/kernel/vector.S b/arch/powerpc/kernel/vector.S index 4d5a3edff49e..e830289d2e48 100644 --- a/arch/powerpc/kernel/vector.S +++ b/arch/powerpc/kernel/vector.S | |||
@@ -89,6 +89,16 @@ _GLOBAL(load_up_altivec) | |||
89 | /* restore registers and return */ | 89 | /* restore registers and return */ |
90 | blr | 90 | blr |
91 | 91 | ||
92 | _GLOBAL(giveup_altivec_notask) | ||
93 | mfmsr r3 | ||
94 | andis. r4,r3,MSR_VEC@h | ||
95 | bnelr /* Already enabled? */ | ||
96 | oris r3,r3,MSR_VEC@h | ||
97 | SYNC | ||
98 | MTMSRD(r3) /* enable use of VMX now */ | ||
99 | isync | ||
100 | blr | ||
101 | |||
92 | /* | 102 | /* |
93 | * giveup_altivec(tsk) | 103 | * giveup_altivec(tsk) |
94 | * Disable VMX for the task given as the argument, | 104 | * Disable VMX for the task given as the argument, |
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c index a3a99901c8ec..cb87301ccd55 100644 --- a/arch/powerpc/kernel/vio.c +++ b/arch/powerpc/kernel/vio.c | |||
@@ -14,7 +14,9 @@ | |||
14 | * 2 of the License, or (at your option) any later version. | 14 | * 2 of the License, or (at your option) any later version. |
15 | */ | 15 | */ |
16 | 16 | ||
17 | #include <linux/cpu.h> | ||
17 | #include <linux/types.h> | 18 | #include <linux/types.h> |
19 | #include <linux/delay.h> | ||
18 | #include <linux/stat.h> | 20 | #include <linux/stat.h> |
19 | #include <linux/device.h> | 21 | #include <linux/device.h> |
20 | #include <linux/init.h> | 22 | #include <linux/init.h> |
@@ -709,13 +711,26 @@ static int vio_cmo_bus_probe(struct vio_dev *viodev) | |||
709 | struct vio_driver *viodrv = to_vio_driver(dev->driver); | 711 | struct vio_driver *viodrv = to_vio_driver(dev->driver); |
710 | unsigned long flags; | 712 | unsigned long flags; |
711 | size_t size; | 713 | size_t size; |
714 | bool dma_capable = false; | ||
715 | |||
716 | /* A device requires entitlement if it has a DMA window property */ | ||
717 | switch (viodev->family) { | ||
718 | case VDEVICE: | ||
719 | if (of_get_property(viodev->dev.of_node, | ||
720 | "ibm,my-dma-window", NULL)) | ||
721 | dma_capable = true; | ||
722 | break; | ||
723 | case PFO: | ||
724 | dma_capable = false; | ||
725 | break; | ||
726 | default: | ||
727 | dev_warn(dev, "unknown device family: %d\n", viodev->family); | ||
728 | BUG(); | ||
729 | break; | ||
730 | } | ||
712 | 731 | ||
713 | /* | 732 | /* Configure entitlement for the device. */ |
714 | * Check to see that device has a DMA window and configure | 733 | if (dma_capable) { |
715 | * entitlement for the device. | ||
716 | */ | ||
717 | if (of_get_property(viodev->dev.of_node, | ||
718 | "ibm,my-dma-window", NULL)) { | ||
719 | /* Check that the driver is CMO enabled and get desired DMA */ | 734 | /* Check that the driver is CMO enabled and get desired DMA */ |
720 | if (!viodrv->get_desired_dma) { | 735 | if (!viodrv->get_desired_dma) { |
721 | dev_err(dev, "%s: device driver does not support CMO\n", | 736 | dev_err(dev, "%s: device driver does not support CMO\n", |
@@ -1050,6 +1065,94 @@ static void vio_cmo_sysfs_init(void) { } | |||
1050 | EXPORT_SYMBOL(vio_cmo_entitlement_update); | 1065 | EXPORT_SYMBOL(vio_cmo_entitlement_update); |
1051 | EXPORT_SYMBOL(vio_cmo_set_dev_desired); | 1066 | EXPORT_SYMBOL(vio_cmo_set_dev_desired); |
1052 | 1067 | ||
1068 | |||
1069 | /* | ||
1070 | * Platform Facilities Option (PFO) support | ||
1071 | */ | ||
1072 | |||
1073 | /** | ||
1074 | * vio_h_cop_sync - Perform a synchronous PFO co-processor operation | ||
1075 | * | ||
1076 | * @vdev - Pointer to a struct vio_dev for device | ||
1077 | * @op - Pointer to a struct vio_pfo_op for the operation parameters | ||
1078 | * | ||
1079 | * Calls the hypervisor to synchronously perform the PFO operation | ||
1080 | * described in @op. In the case of a busy response from the hypervisor, | ||
1081 | * the operation will be re-submitted indefinitely unless a non-zero timeout | ||
1082 | * is specified or an error occurs. The timeout places a limit on when to | ||
1083 | * stop re-submitting a operation, the total time can be exceeded if an | ||
1084 | * operation is in progress. | ||
1085 | * | ||
1086 | * If op->hcall_ret is not NULL, this will be set to the return from the | ||
1087 | * last h_cop_op call or it will be 0 if an error not involving the h_call | ||
1088 | * was encountered. | ||
1089 | * | ||
1090 | * Returns: | ||
1091 | * 0 on success, | ||
1092 | * -EINVAL if the h_call fails due to an invalid parameter, | ||
1093 | * -E2BIG if the h_call can not be performed synchronously, | ||
1094 | * -EBUSY if a timeout is specified and has elapsed, | ||
1095 | * -EACCES if the memory area for data/status has been rescinded, or | ||
1096 | * -EPERM if a hardware fault has been indicated | ||
1097 | */ | ||
1098 | int vio_h_cop_sync(struct vio_dev *vdev, struct vio_pfo_op *op) | ||
1099 | { | ||
1100 | struct device *dev = &vdev->dev; | ||
1101 | unsigned long deadline = 0; | ||
1102 | long hret = 0; | ||
1103 | int ret = 0; | ||
1104 | |||
1105 | if (op->timeout) | ||
1106 | deadline = jiffies + msecs_to_jiffies(op->timeout); | ||
1107 | |||
1108 | while (true) { | ||
1109 | hret = plpar_hcall_norets(H_COP, op->flags, | ||
1110 | vdev->resource_id, | ||
1111 | op->in, op->inlen, op->out, | ||
1112 | op->outlen, op->csbcpb); | ||
1113 | |||
1114 | if (hret == H_SUCCESS || | ||
1115 | (hret != H_NOT_ENOUGH_RESOURCES && | ||
1116 | hret != H_BUSY && hret != H_RESOURCE) || | ||
1117 | (op->timeout && time_after(deadline, jiffies))) | ||
1118 | break; | ||
1119 | |||
1120 | dev_dbg(dev, "%s: hcall ret(%ld), retrying.\n", __func__, hret); | ||
1121 | } | ||
1122 | |||
1123 | switch (hret) { | ||
1124 | case H_SUCCESS: | ||
1125 | ret = 0; | ||
1126 | break; | ||
1127 | case H_OP_MODE: | ||
1128 | case H_TOO_BIG: | ||
1129 | ret = -E2BIG; | ||
1130 | break; | ||
1131 | case H_RESCINDED: | ||
1132 | ret = -EACCES; | ||
1133 | break; | ||
1134 | case H_HARDWARE: | ||
1135 | ret = -EPERM; | ||
1136 | break; | ||
1137 | case H_NOT_ENOUGH_RESOURCES: | ||
1138 | case H_RESOURCE: | ||
1139 | case H_BUSY: | ||
1140 | ret = -EBUSY; | ||
1141 | break; | ||
1142 | default: | ||
1143 | ret = -EINVAL; | ||
1144 | break; | ||
1145 | } | ||
1146 | |||
1147 | if (ret) | ||
1148 | dev_dbg(dev, "%s: Sync h_cop_op failure (ret:%d) (hret:%ld)\n", | ||
1149 | __func__, ret, hret); | ||
1150 | |||
1151 | op->hcall_err = hret; | ||
1152 | return ret; | ||
1153 | } | ||
1154 | EXPORT_SYMBOL(vio_h_cop_sync); | ||
1155 | |||
1053 | static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev) | 1156 | static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev) |
1054 | { | 1157 | { |
1055 | const unsigned char *dma_window; | 1158 | const unsigned char *dma_window; |
@@ -1211,35 +1314,87 @@ static void __devinit vio_dev_release(struct device *dev) | |||
1211 | struct vio_dev *vio_register_device_node(struct device_node *of_node) | 1314 | struct vio_dev *vio_register_device_node(struct device_node *of_node) |
1212 | { | 1315 | { |
1213 | struct vio_dev *viodev; | 1316 | struct vio_dev *viodev; |
1317 | struct device_node *parent_node; | ||
1214 | const unsigned int *unit_address; | 1318 | const unsigned int *unit_address; |
1319 | const unsigned int *pfo_resid = NULL; | ||
1320 | enum vio_dev_family family; | ||
1321 | const char *of_node_name = of_node->name ? of_node->name : "<unknown>"; | ||
1215 | 1322 | ||
1216 | /* we need the 'device_type' property, in order to match with drivers */ | 1323 | /* |
1217 | if (of_node->type == NULL) { | 1324 | * Determine if this node is a under the /vdevice node or under the |
1218 | printk(KERN_WARNING "%s: node %s missing 'device_type'\n", | 1325 | * /ibm,platform-facilities node. This decides the device's family. |
1219 | __func__, | 1326 | */ |
1220 | of_node->name ? of_node->name : "<unknown>"); | 1327 | parent_node = of_get_parent(of_node); |
1328 | if (parent_node) { | ||
1329 | if (!strcmp(parent_node->full_name, "/ibm,platform-facilities")) | ||
1330 | family = PFO; | ||
1331 | else if (!strcmp(parent_node->full_name, "/vdevice")) | ||
1332 | family = VDEVICE; | ||
1333 | else { | ||
1334 | pr_warn("%s: parent(%s) of %s not recognized.\n", | ||
1335 | __func__, | ||
1336 | parent_node->full_name, | ||
1337 | of_node_name); | ||
1338 | of_node_put(parent_node); | ||
1339 | return NULL; | ||
1340 | } | ||
1341 | of_node_put(parent_node); | ||
1342 | } else { | ||
1343 | pr_warn("%s: could not determine the parent of node %s.\n", | ||
1344 | __func__, of_node_name); | ||
1221 | return NULL; | 1345 | return NULL; |
1222 | } | 1346 | } |
1223 | 1347 | ||
1224 | unit_address = of_get_property(of_node, "reg", NULL); | 1348 | if (family == PFO) { |
1225 | if (unit_address == NULL) { | 1349 | if (of_get_property(of_node, "interrupt-controller", NULL)) { |
1226 | printk(KERN_WARNING "%s: node %s missing 'reg'\n", | 1350 | pr_debug("%s: Skipping the interrupt controller %s.\n", |
1227 | __func__, | 1351 | __func__, of_node_name); |
1228 | of_node->name ? of_node->name : "<unknown>"); | 1352 | return NULL; |
1229 | return NULL; | 1353 | } |
1230 | } | 1354 | } |
1231 | 1355 | ||
1232 | /* allocate a vio_dev for this node */ | 1356 | /* allocate a vio_dev for this node */ |
1233 | viodev = kzalloc(sizeof(struct vio_dev), GFP_KERNEL); | 1357 | viodev = kzalloc(sizeof(struct vio_dev), GFP_KERNEL); |
1234 | if (viodev == NULL) | 1358 | if (viodev == NULL) { |
1359 | pr_warn("%s: allocation failure for VIO device.\n", __func__); | ||
1235 | return NULL; | 1360 | return NULL; |
1361 | } | ||
1236 | 1362 | ||
1237 | viodev->irq = irq_of_parse_and_map(of_node, 0); | 1363 | /* we need the 'device_type' property, in order to match with drivers */ |
1364 | viodev->family = family; | ||
1365 | if (viodev->family == VDEVICE) { | ||
1366 | if (of_node->type != NULL) | ||
1367 | viodev->type = of_node->type; | ||
1368 | else { | ||
1369 | pr_warn("%s: node %s is missing the 'device_type' " | ||
1370 | "property.\n", __func__, of_node_name); | ||
1371 | goto out; | ||
1372 | } | ||
1373 | |||
1374 | unit_address = of_get_property(of_node, "reg", NULL); | ||
1375 | if (unit_address == NULL) { | ||
1376 | pr_warn("%s: node %s missing 'reg'\n", | ||
1377 | __func__, of_node_name); | ||
1378 | goto out; | ||
1379 | } | ||
1380 | dev_set_name(&viodev->dev, "%x", *unit_address); | ||
1381 | viodev->irq = irq_of_parse_and_map(of_node, 0); | ||
1382 | viodev->unit_address = *unit_address; | ||
1383 | } else { | ||
1384 | /* PFO devices need their resource_id for submitting COP_OPs | ||
1385 | * This is an optional field for devices, but is required when | ||
1386 | * performing synchronous ops */ | ||
1387 | pfo_resid = of_get_property(of_node, "ibm,resource-id", NULL); | ||
1388 | if (pfo_resid != NULL) | ||
1389 | viodev->resource_id = *pfo_resid; | ||
1390 | |||
1391 | unit_address = NULL; | ||
1392 | dev_set_name(&viodev->dev, "%s", of_node_name); | ||
1393 | viodev->type = of_node_name; | ||
1394 | viodev->irq = 0; | ||
1395 | } | ||
1238 | 1396 | ||
1239 | dev_set_name(&viodev->dev, "%x", *unit_address); | ||
1240 | viodev->name = of_node->name; | 1397 | viodev->name = of_node->name; |
1241 | viodev->type = of_node->type; | ||
1242 | viodev->unit_address = *unit_address; | ||
1243 | viodev->dev.of_node = of_node_get(of_node); | 1398 | viodev->dev.of_node = of_node_get(of_node); |
1244 | 1399 | ||
1245 | if (firmware_has_feature(FW_FEATURE_CMO)) | 1400 | if (firmware_has_feature(FW_FEATURE_CMO)) |
@@ -1267,16 +1422,51 @@ struct vio_dev *vio_register_device_node(struct device_node *of_node) | |||
1267 | } | 1422 | } |
1268 | 1423 | ||
1269 | return viodev; | 1424 | return viodev; |
1425 | |||
1426 | out: /* Use this exit point for any return prior to device_register */ | ||
1427 | kfree(viodev); | ||
1428 | |||
1429 | return NULL; | ||
1270 | } | 1430 | } |
1271 | EXPORT_SYMBOL(vio_register_device_node); | 1431 | EXPORT_SYMBOL(vio_register_device_node); |
1272 | 1432 | ||
1433 | /* | ||
1434 | * vio_bus_scan_for_devices - Scan OF and register each child device | ||
1435 | * @root_name - OF node name for the root of the subtree to search. | ||
1436 | * This must be non-NULL | ||
1437 | * | ||
1438 | * Starting from the root node provide, register the device node for | ||
1439 | * each child beneath the root. | ||
1440 | */ | ||
1441 | static void vio_bus_scan_register_devices(char *root_name) | ||
1442 | { | ||
1443 | struct device_node *node_root, *node_child; | ||
1444 | |||
1445 | if (!root_name) | ||
1446 | return; | ||
1447 | |||
1448 | node_root = of_find_node_by_name(NULL, root_name); | ||
1449 | if (node_root) { | ||
1450 | |||
1451 | /* | ||
1452 | * Create struct vio_devices for each virtual device in | ||
1453 | * the device tree. Drivers will associate with them later. | ||
1454 | */ | ||
1455 | node_child = of_get_next_child(node_root, NULL); | ||
1456 | while (node_child) { | ||
1457 | vio_register_device_node(node_child); | ||
1458 | node_child = of_get_next_child(node_root, node_child); | ||
1459 | } | ||
1460 | of_node_put(node_root); | ||
1461 | } | ||
1462 | } | ||
1463 | |||
1273 | /** | 1464 | /** |
1274 | * vio_bus_init: - Initialize the virtual IO bus | 1465 | * vio_bus_init: - Initialize the virtual IO bus |
1275 | */ | 1466 | */ |
1276 | static int __init vio_bus_init(void) | 1467 | static int __init vio_bus_init(void) |
1277 | { | 1468 | { |
1278 | int err; | 1469 | int err; |
1279 | struct device_node *node_vroot; | ||
1280 | 1470 | ||
1281 | if (firmware_has_feature(FW_FEATURE_CMO)) | 1471 | if (firmware_has_feature(FW_FEATURE_CMO)) |
1282 | vio_cmo_sysfs_init(); | 1472 | vio_cmo_sysfs_init(); |
@@ -1301,19 +1491,8 @@ static int __init vio_bus_init(void) | |||
1301 | if (firmware_has_feature(FW_FEATURE_CMO)) | 1491 | if (firmware_has_feature(FW_FEATURE_CMO)) |
1302 | vio_cmo_bus_init(); | 1492 | vio_cmo_bus_init(); |
1303 | 1493 | ||
1304 | node_vroot = of_find_node_by_name(NULL, "vdevice"); | 1494 | vio_bus_scan_register_devices("vdevice"); |
1305 | if (node_vroot) { | 1495 | vio_bus_scan_register_devices("ibm,platform-facilities"); |
1306 | struct device_node *of_node; | ||
1307 | |||
1308 | /* | ||
1309 | * Create struct vio_devices for each virtual device in | ||
1310 | * the device tree. Drivers will associate with them later. | ||
1311 | */ | ||
1312 | for (of_node = node_vroot->child; of_node != NULL; | ||
1313 | of_node = of_node->sibling) | ||
1314 | vio_register_device_node(of_node); | ||
1315 | of_node_put(node_vroot); | ||
1316 | } | ||
1317 | 1496 | ||
1318 | return 0; | 1497 | return 0; |
1319 | } | 1498 | } |
@@ -1436,12 +1615,28 @@ struct vio_dev *vio_find_node(struct device_node *vnode) | |||
1436 | { | 1615 | { |
1437 | const uint32_t *unit_address; | 1616 | const uint32_t *unit_address; |
1438 | char kobj_name[20]; | 1617 | char kobj_name[20]; |
1618 | struct device_node *vnode_parent; | ||
1619 | const char *dev_type; | ||
1620 | |||
1621 | vnode_parent = of_get_parent(vnode); | ||
1622 | if (!vnode_parent) | ||
1623 | return NULL; | ||
1624 | |||
1625 | dev_type = of_get_property(vnode_parent, "device_type", NULL); | ||
1626 | of_node_put(vnode_parent); | ||
1627 | if (!dev_type) | ||
1628 | return NULL; | ||
1439 | 1629 | ||
1440 | /* construct the kobject name from the device node */ | 1630 | /* construct the kobject name from the device node */ |
1441 | unit_address = of_get_property(vnode, "reg", NULL); | 1631 | if (!strcmp(dev_type, "vdevice")) { |
1442 | if (!unit_address) | 1632 | unit_address = of_get_property(vnode, "reg", NULL); |
1633 | if (!unit_address) | ||
1634 | return NULL; | ||
1635 | snprintf(kobj_name, sizeof(kobj_name), "%x", *unit_address); | ||
1636 | } else if (!strcmp(dev_type, "ibm,platform-facilities")) | ||
1637 | snprintf(kobj_name, sizeof(kobj_name), "%s", vnode->name); | ||
1638 | else | ||
1443 | return NULL; | 1639 | return NULL; |
1444 | snprintf(kobj_name, sizeof(kobj_name), "%x", *unit_address); | ||
1445 | 1640 | ||
1446 | return vio_find_name(kobj_name); | 1641 | return vio_find_name(kobj_name); |
1447 | } | 1642 | } |
diff --git a/arch/powerpc/lib/copyuser_64.S b/arch/powerpc/lib/copyuser_64.S index 773d38f90aaa..d73a59014900 100644 --- a/arch/powerpc/lib/copyuser_64.S +++ b/arch/powerpc/lib/copyuser_64.S | |||
@@ -30,7 +30,7 @@ _GLOBAL(__copy_tofrom_user_base) | |||
30 | dcbt 0,r4 | 30 | dcbt 0,r4 |
31 | beq .Lcopy_page_4K | 31 | beq .Lcopy_page_4K |
32 | andi. r6,r6,7 | 32 | andi. r6,r6,7 |
33 | PPC_MTOCRF 0x01,r5 | 33 | PPC_MTOCRF(0x01,r5) |
34 | blt cr1,.Lshort_copy | 34 | blt cr1,.Lshort_copy |
35 | /* Below we want to nop out the bne if we're on a CPU that has the | 35 | /* Below we want to nop out the bne if we're on a CPU that has the |
36 | * CPU_FTR_UNALIGNED_LD_STD bit set and the CPU_FTR_CP_USE_DCBTZ bit | 36 | * CPU_FTR_UNALIGNED_LD_STD bit set and the CPU_FTR_CP_USE_DCBTZ bit |
@@ -186,7 +186,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD) | |||
186 | blr | 186 | blr |
187 | 187 | ||
188 | .Ldst_unaligned: | 188 | .Ldst_unaligned: |
189 | PPC_MTOCRF 0x01,r6 /* put #bytes to 8B bdry into cr7 */ | 189 | PPC_MTOCRF(0x01,r6) /* put #bytes to 8B bdry into cr7 */ |
190 | subf r5,r6,r5 | 190 | subf r5,r6,r5 |
191 | li r7,0 | 191 | li r7,0 |
192 | cmpldi cr1,r5,16 | 192 | cmpldi cr1,r5,16 |
@@ -201,7 +201,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD) | |||
201 | 2: bf cr7*4+1,3f | 201 | 2: bf cr7*4+1,3f |
202 | 37: lwzx r0,r7,r4 | 202 | 37: lwzx r0,r7,r4 |
203 | 83: stwx r0,r7,r3 | 203 | 83: stwx r0,r7,r3 |
204 | 3: PPC_MTOCRF 0x01,r5 | 204 | 3: PPC_MTOCRF(0x01,r5) |
205 | add r4,r6,r4 | 205 | add r4,r6,r4 |
206 | add r3,r6,r3 | 206 | add r3,r6,r3 |
207 | b .Ldst_aligned | 207 | b .Ldst_aligned |
diff --git a/arch/powerpc/lib/mem_64.S b/arch/powerpc/lib/mem_64.S index 11ce045e21fd..f4fcb0bc6563 100644 --- a/arch/powerpc/lib/mem_64.S +++ b/arch/powerpc/lib/mem_64.S | |||
@@ -19,7 +19,7 @@ _GLOBAL(memset) | |||
19 | rlwimi r4,r4,16,0,15 | 19 | rlwimi r4,r4,16,0,15 |
20 | cmplw cr1,r5,r0 /* do we get that far? */ | 20 | cmplw cr1,r5,r0 /* do we get that far? */ |
21 | rldimi r4,r4,32,0 | 21 | rldimi r4,r4,32,0 |
22 | PPC_MTOCRF 1,r0 | 22 | PPC_MTOCRF(1,r0) |
23 | mr r6,r3 | 23 | mr r6,r3 |
24 | blt cr1,8f | 24 | blt cr1,8f |
25 | beq+ 3f /* if already 8-byte aligned */ | 25 | beq+ 3f /* if already 8-byte aligned */ |
@@ -49,7 +49,7 @@ _GLOBAL(memset) | |||
49 | bdnz 4b | 49 | bdnz 4b |
50 | 5: srwi. r0,r5,3 | 50 | 5: srwi. r0,r5,3 |
51 | clrlwi r5,r5,29 | 51 | clrlwi r5,r5,29 |
52 | PPC_MTOCRF 1,r0 | 52 | PPC_MTOCRF(1,r0) |
53 | beq 8f | 53 | beq 8f |
54 | bf 29,6f | 54 | bf 29,6f |
55 | std r4,0(r6) | 55 | std r4,0(r6) |
@@ -65,7 +65,7 @@ _GLOBAL(memset) | |||
65 | std r4,0(r6) | 65 | std r4,0(r6) |
66 | addi r6,r6,8 | 66 | addi r6,r6,8 |
67 | 8: cmpwi r5,0 | 67 | 8: cmpwi r5,0 |
68 | PPC_MTOCRF 1,r5 | 68 | PPC_MTOCRF(1,r5) |
69 | beqlr+ | 69 | beqlr+ |
70 | bf 29,9f | 70 | bf 29,9f |
71 | stw r4,0(r6) | 71 | stw r4,0(r6) |
diff --git a/arch/powerpc/lib/memcpy_64.S b/arch/powerpc/lib/memcpy_64.S index e178922b2c21..82fea3963e15 100644 --- a/arch/powerpc/lib/memcpy_64.S +++ b/arch/powerpc/lib/memcpy_64.S | |||
@@ -12,7 +12,7 @@ | |||
12 | .align 7 | 12 | .align 7 |
13 | _GLOBAL(memcpy) | 13 | _GLOBAL(memcpy) |
14 | std r3,48(r1) /* save destination pointer for return value */ | 14 | std r3,48(r1) /* save destination pointer for return value */ |
15 | PPC_MTOCRF 0x01,r5 | 15 | PPC_MTOCRF(0x01,r5) |
16 | cmpldi cr1,r5,16 | 16 | cmpldi cr1,r5,16 |
17 | neg r6,r3 # LS 3 bits = # bytes to 8-byte dest bdry | 17 | neg r6,r3 # LS 3 bits = # bytes to 8-byte dest bdry |
18 | andi. r6,r6,7 | 18 | andi. r6,r6,7 |
@@ -154,7 +154,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD) | |||
154 | blr | 154 | blr |
155 | 155 | ||
156 | .Ldst_unaligned: | 156 | .Ldst_unaligned: |
157 | PPC_MTOCRF 0x01,r6 # put #bytes to 8B bdry into cr7 | 157 | PPC_MTOCRF(0x01,r6) # put #bytes to 8B bdry into cr7 |
158 | subf r5,r6,r5 | 158 | subf r5,r6,r5 |
159 | li r7,0 | 159 | li r7,0 |
160 | cmpldi cr1,r5,16 | 160 | cmpldi cr1,r5,16 |
@@ -169,7 +169,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD) | |||
169 | 2: bf cr7*4+1,3f | 169 | 2: bf cr7*4+1,3f |
170 | lwzx r0,r7,r4 | 170 | lwzx r0,r7,r4 |
171 | stwx r0,r7,r3 | 171 | stwx r0,r7,r3 |
172 | 3: PPC_MTOCRF 0x01,r5 | 172 | 3: PPC_MTOCRF(0x01,r5) |
173 | add r4,r6,r4 | 173 | add r4,r6,r4 |
174 | add r3,r6,r3 | 174 | add r3,r6,r3 |
175 | b .Ldst_aligned | 175 | b .Ldst_aligned |
diff --git a/arch/powerpc/platforms/44x/Kconfig b/arch/powerpc/platforms/44x/Kconfig index 2e4e64abfab4..8abf6fb8f410 100644 --- a/arch/powerpc/platforms/44x/Kconfig +++ b/arch/powerpc/platforms/44x/Kconfig | |||
@@ -23,6 +23,8 @@ config BLUESTONE | |||
23 | default n | 23 | default n |
24 | select PPC44x_SIMPLE | 24 | select PPC44x_SIMPLE |
25 | select APM821xx | 25 | select APM821xx |
26 | select PCI_MSI | ||
27 | select PPC4xx_MSI | ||
26 | select PPC4xx_PCI_EXPRESS | 28 | select PPC4xx_PCI_EXPRESS |
27 | select IBM_EMAC_RGMII | 29 | select IBM_EMAC_RGMII |
28 | help | 30 | help |
diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype index 9c80fc07384a..61c9550819a2 100644 --- a/arch/powerpc/platforms/Kconfig.cputype +++ b/arch/powerpc/platforms/Kconfig.cputype | |||
@@ -78,6 +78,36 @@ config PPC_BOOK3E_64 | |||
78 | 78 | ||
79 | endchoice | 79 | endchoice |
80 | 80 | ||
81 | choice | ||
82 | prompt "CPU selection" | ||
83 | depends on PPC64 | ||
84 | default GENERIC_CPU | ||
85 | help | ||
86 | This will create a kernel which is optimised for a particular CPU. | ||
87 | The resulting kernel may not run on other CPUs, so use this with care. | ||
88 | |||
89 | If unsure, select Generic. | ||
90 | |||
91 | config GENERIC_CPU | ||
92 | bool "Generic" | ||
93 | |||
94 | config CELL_CPU | ||
95 | bool "Cell Broadband Engine" | ||
96 | |||
97 | config POWER4_CPU | ||
98 | bool "POWER4" | ||
99 | |||
100 | config POWER5_CPU | ||
101 | bool "POWER5" | ||
102 | |||
103 | config POWER6_CPU | ||
104 | bool "POWER6" | ||
105 | |||
106 | config POWER7_CPU | ||
107 | bool "POWER7" | ||
108 | |||
109 | endchoice | ||
110 | |||
81 | config PPC_BOOK3S | 111 | config PPC_BOOK3S |
82 | def_bool y | 112 | def_bool y |
83 | depends on PPC_BOOK3S_32 || PPC_BOOK3S_64 | 113 | depends on PPC_BOOK3S_32 || PPC_BOOK3S_64 |
@@ -86,15 +116,6 @@ config PPC_BOOK3E | |||
86 | def_bool y | 116 | def_bool y |
87 | depends on PPC_BOOK3E_64 | 117 | depends on PPC_BOOK3E_64 |
88 | 118 | ||
89 | config POWER4_ONLY | ||
90 | bool "Optimize for POWER4" | ||
91 | depends on PPC64 && PPC_BOOK3S | ||
92 | default n | ||
93 | ---help--- | ||
94 | Cause the compiler to optimize for POWER4/POWER5/PPC970 processors. | ||
95 | The resulting binary will not work on POWER3 or RS64 processors | ||
96 | when compiled with binutils 2.15 or later. | ||
97 | |||
98 | config 6xx | 119 | config 6xx |
99 | def_bool y | 120 | def_bool y |
100 | depends on PPC32 && PPC_BOOK3S | 121 | depends on PPC32 && PPC_BOOK3S |
diff --git a/arch/powerpc/platforms/powermac/low_i2c.c b/arch/powerpc/platforms/powermac/low_i2c.c index 03685a329d7d..fc536f2971c0 100644 --- a/arch/powerpc/platforms/powermac/low_i2c.c +++ b/arch/powerpc/platforms/powermac/low_i2c.c | |||
@@ -1503,6 +1503,7 @@ static int __init pmac_i2c_create_platform_devices(void) | |||
1503 | if (bus->platform_dev == NULL) | 1503 | if (bus->platform_dev == NULL) |
1504 | return -ENOMEM; | 1504 | return -ENOMEM; |
1505 | bus->platform_dev->dev.platform_data = bus; | 1505 | bus->platform_dev->dev.platform_data = bus; |
1506 | bus->platform_dev->dev.of_node = bus->busnode; | ||
1506 | platform_device_add(bus->platform_dev); | 1507 | platform_device_add(bus->platform_dev); |
1507 | } | 1508 | } |
1508 | 1509 | ||
diff --git a/arch/powerpc/platforms/ps3/Kconfig b/arch/powerpc/platforms/ps3/Kconfig index 476d9d9b2405..46b7f0232523 100644 --- a/arch/powerpc/platforms/ps3/Kconfig +++ b/arch/powerpc/platforms/ps3/Kconfig | |||
@@ -7,7 +7,6 @@ config PPC_PS3 | |||
7 | select USB_OHCI_BIG_ENDIAN_MMIO | 7 | select USB_OHCI_BIG_ENDIAN_MMIO |
8 | select USB_ARCH_HAS_EHCI | 8 | select USB_ARCH_HAS_EHCI |
9 | select USB_EHCI_BIG_ENDIAN_MMIO | 9 | select USB_EHCI_BIG_ENDIAN_MMIO |
10 | select MEMORY_HOTPLUG | ||
11 | select PPC_PCI_CHOICE | 10 | select PPC_PCI_CHOICE |
12 | help | 11 | help |
13 | This option enables support for the Sony PS3 game console | 12 | This option enables support for the Sony PS3 game console |
@@ -74,7 +73,7 @@ config PS3_PS3AV | |||
74 | help | 73 | help |
75 | Include support for the PS3 AV Settings driver. | 74 | Include support for the PS3 AV Settings driver. |
76 | 75 | ||
77 | This support is required for graphics and sound. In | 76 | This support is required for PS3 graphics and sound. In |
78 | general, all users will say Y or M. | 77 | general, all users will say Y or M. |
79 | 78 | ||
80 | config PS3_SYS_MANAGER | 79 | config PS3_SYS_MANAGER |
@@ -85,9 +84,22 @@ config PS3_SYS_MANAGER | |||
85 | help | 84 | help |
86 | Include support for the PS3 System Manager. | 85 | Include support for the PS3 System Manager. |
87 | 86 | ||
88 | This support is required for system control. In | 87 | This support is required for PS3 system control. In |
89 | general, all users will say Y or M. | 88 | general, all users will say Y or M. |
90 | 89 | ||
90 | config PS3_REPOSITORY_WRITE | ||
91 | bool "PS3 Repository write support" if PS3_ADVANCED | ||
92 | depends on PPC_PS3 | ||
93 | default n | ||
94 | help | ||
95 | Enables support for writing to the PS3 System Repository. | ||
96 | |||
97 | This support is intended for bootloaders that need to store data | ||
98 | in the repository for later boot stages. | ||
99 | |||
100 | If in doubt, say N here and reduce the size of the kernel by a | ||
101 | small amount. | ||
102 | |||
91 | config PS3_STORAGE | 103 | config PS3_STORAGE |
92 | depends on PPC_PS3 | 104 | depends on PPC_PS3 |
93 | tristate | 105 | tristate |
@@ -122,7 +134,7 @@ config PS3_FLASH | |||
122 | 134 | ||
123 | This support is required to access the PS3 FLASH ROM, which | 135 | This support is required to access the PS3 FLASH ROM, which |
124 | contains the boot loader and some boot options. | 136 | contains the boot loader and some boot options. |
125 | In general, all users will say Y or M. | 137 | In general, PS3 OtherOS users will say Y or M. |
126 | 138 | ||
127 | As this driver needs a fixed buffer of 256 KiB of memory, it can | 139 | As this driver needs a fixed buffer of 256 KiB of memory, it can |
128 | be disabled on the kernel command line using "ps3flash=off", to | 140 | be disabled on the kernel command line using "ps3flash=off", to |
@@ -156,7 +168,7 @@ config PS3GELIC_UDBG | |||
156 | via the Ethernet port (UDP port number 18194). | 168 | via the Ethernet port (UDP port number 18194). |
157 | 169 | ||
158 | This driver uses a trivial implementation and is independent | 170 | This driver uses a trivial implementation and is independent |
159 | from the main network driver. | 171 | from the main PS3 gelic network driver. |
160 | 172 | ||
161 | If in doubt, say N here. | 173 | If in doubt, say N here. |
162 | 174 | ||
diff --git a/arch/powerpc/platforms/ps3/mm.c b/arch/powerpc/platforms/ps3/mm.c index de2aea421707..0c9f643d9e2a 100644 --- a/arch/powerpc/platforms/ps3/mm.c +++ b/arch/powerpc/platforms/ps3/mm.c | |||
@@ -20,7 +20,6 @@ | |||
20 | 20 | ||
21 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
22 | #include <linux/export.h> | 22 | #include <linux/export.h> |
23 | #include <linux/memory_hotplug.h> | ||
24 | #include <linux/memblock.h> | 23 | #include <linux/memblock.h> |
25 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
26 | 25 | ||
@@ -79,12 +78,14 @@ enum { | |||
79 | * @base: base address | 78 | * @base: base address |
80 | * @size: size in bytes | 79 | * @size: size in bytes |
81 | * @offset: difference between base and rm.size | 80 | * @offset: difference between base and rm.size |
81 | * @destroy: flag if region should be destroyed upon shutdown | ||
82 | */ | 82 | */ |
83 | 83 | ||
84 | struct mem_region { | 84 | struct mem_region { |
85 | u64 base; | 85 | u64 base; |
86 | u64 size; | 86 | u64 size; |
87 | unsigned long offset; | 87 | unsigned long offset; |
88 | int destroy; | ||
88 | }; | 89 | }; |
89 | 90 | ||
90 | /** | 91 | /** |
@@ -96,7 +97,7 @@ struct mem_region { | |||
96 | * The HV virtual address space (vas) allows for hotplug memory regions. | 97 | * The HV virtual address space (vas) allows for hotplug memory regions. |
97 | * Memory regions can be created and destroyed in the vas at runtime. | 98 | * Memory regions can be created and destroyed in the vas at runtime. |
98 | * @rm: real mode (bootmem) region | 99 | * @rm: real mode (bootmem) region |
99 | * @r1: hotplug memory region(s) | 100 | * @r1: highmem region(s) |
100 | * | 101 | * |
101 | * ps3 addresses | 102 | * ps3 addresses |
102 | * virt_addr: a cpu 'translated' effective address | 103 | * virt_addr: a cpu 'translated' effective address |
@@ -222,10 +223,6 @@ void ps3_mm_vas_destroy(void) | |||
222 | } | 223 | } |
223 | } | 224 | } |
224 | 225 | ||
225 | /*============================================================================*/ | ||
226 | /* memory hotplug routines */ | ||
227 | /*============================================================================*/ | ||
228 | |||
229 | /** | 226 | /** |
230 | * ps3_mm_region_create - create a memory region in the vas | 227 | * ps3_mm_region_create - create a memory region in the vas |
231 | * @r: pointer to a struct mem_region to accept initialized values | 228 | * @r: pointer to a struct mem_region to accept initialized values |
@@ -262,6 +259,7 @@ static int ps3_mm_region_create(struct mem_region *r, unsigned long size) | |||
262 | goto zero_region; | 259 | goto zero_region; |
263 | } | 260 | } |
264 | 261 | ||
262 | r->destroy = 1; | ||
265 | r->offset = r->base - map.rm.size; | 263 | r->offset = r->base - map.rm.size; |
266 | return result; | 264 | return result; |
267 | 265 | ||
@@ -279,7 +277,14 @@ static void ps3_mm_region_destroy(struct mem_region *r) | |||
279 | { | 277 | { |
280 | int result; | 278 | int result; |
281 | 279 | ||
280 | if (!r->destroy) { | ||
281 | pr_info("%s:%d: Not destroying high region: %llxh %llxh\n", | ||
282 | __func__, __LINE__, r->base, r->size); | ||
283 | return; | ||
284 | } | ||
285 | |||
282 | DBG("%s:%d: r->base = %llxh\n", __func__, __LINE__, r->base); | 286 | DBG("%s:%d: r->base = %llxh\n", __func__, __LINE__, r->base); |
287 | |||
283 | if (r->base) { | 288 | if (r->base) { |
284 | result = lv1_release_memory(r->base); | 289 | result = lv1_release_memory(r->base); |
285 | BUG_ON(result); | 290 | BUG_ON(result); |
@@ -288,50 +293,36 @@ static void ps3_mm_region_destroy(struct mem_region *r) | |||
288 | } | 293 | } |
289 | } | 294 | } |
290 | 295 | ||
291 | /** | 296 | static int ps3_mm_get_repository_highmem(struct mem_region *r) |
292 | * ps3_mm_add_memory - hot add memory | ||
293 | */ | ||
294 | |||
295 | static int __init ps3_mm_add_memory(void) | ||
296 | { | 297 | { |
297 | int result; | 298 | int result; |
298 | unsigned long start_addr; | ||
299 | unsigned long start_pfn; | ||
300 | unsigned long nr_pages; | ||
301 | |||
302 | if (!firmware_has_feature(FW_FEATURE_PS3_LV1)) | ||
303 | return -ENODEV; | ||
304 | 299 | ||
305 | BUG_ON(!mem_init_done); | 300 | /* Assume a single highmem region. */ |
306 | 301 | ||
307 | start_addr = map.rm.size; | 302 | result = ps3_repository_read_highmem_info(0, &r->base, &r->size); |
308 | start_pfn = start_addr >> PAGE_SHIFT; | ||
309 | nr_pages = (map.r1.size + PAGE_SIZE - 1) >> PAGE_SHIFT; | ||
310 | 303 | ||
311 | DBG("%s:%d: start_addr %lxh, start_pfn %lxh, nr_pages %lxh\n", | 304 | if (result) |
312 | __func__, __LINE__, start_addr, start_pfn, nr_pages); | 305 | goto zero_region; |
313 | |||
314 | result = add_memory(0, start_addr, map.r1.size); | ||
315 | 306 | ||
316 | if (result) { | 307 | if (!r->base || !r->size) { |
317 | pr_err("%s:%d: add_memory failed: (%d)\n", | 308 | result = -1; |
318 | __func__, __LINE__, result); | 309 | goto zero_region; |
319 | return result; | ||
320 | } | 310 | } |
321 | 311 | ||
322 | memblock_add(start_addr, map.r1.size); | 312 | r->offset = r->base - map.rm.size; |
323 | 313 | ||
324 | result = online_pages(start_pfn, nr_pages); | 314 | DBG("%s:%d: Found high region in repository: %llxh %llxh\n", |
315 | __func__, __LINE__, r->base, r->size); | ||
325 | 316 | ||
326 | if (result) | 317 | return 0; |
327 | pr_err("%s:%d: online_pages failed: (%d)\n", | ||
328 | __func__, __LINE__, result); | ||
329 | 318 | ||
319 | zero_region: | ||
320 | DBG("%s:%d: No high region in repository.\n", __func__, __LINE__); | ||
321 | |||
322 | r->size = r->base = r->offset = 0; | ||
330 | return result; | 323 | return result; |
331 | } | 324 | } |
332 | 325 | ||
333 | device_initcall(ps3_mm_add_memory); | ||
334 | |||
335 | /*============================================================================*/ | 326 | /*============================================================================*/ |
336 | /* dma routines */ | 327 | /* dma routines */ |
337 | /*============================================================================*/ | 328 | /*============================================================================*/ |
@@ -1217,13 +1208,23 @@ void __init ps3_mm_init(void) | |||
1217 | BUG_ON(map.rm.base); | 1208 | BUG_ON(map.rm.base); |
1218 | BUG_ON(!map.rm.size); | 1209 | BUG_ON(!map.rm.size); |
1219 | 1210 | ||
1211 | /* Check if we got the highmem region from an earlier boot step */ | ||
1220 | 1212 | ||
1221 | /* arrange to do this in ps3_mm_add_memory */ | 1213 | if (ps3_mm_get_repository_highmem(&map.r1)) |
1222 | ps3_mm_region_create(&map.r1, map.total - map.rm.size); | 1214 | ps3_mm_region_create(&map.r1, map.total - map.rm.size); |
1223 | 1215 | ||
1224 | /* correct map.total for the real total amount of memory we use */ | 1216 | /* correct map.total for the real total amount of memory we use */ |
1225 | map.total = map.rm.size + map.r1.size; | 1217 | map.total = map.rm.size + map.r1.size; |
1226 | 1218 | ||
1219 | if (!map.r1.size) { | ||
1220 | DBG("%s:%d: No highmem region found\n", __func__, __LINE__); | ||
1221 | } else { | ||
1222 | DBG("%s:%d: Adding highmem region: %llxh %llxh\n", | ||
1223 | __func__, __LINE__, map.rm.size, | ||
1224 | map.total - map.rm.size); | ||
1225 | memblock_add(map.rm.size, map.total - map.rm.size); | ||
1226 | } | ||
1227 | |||
1227 | DBG(" <- %s:%d\n", __func__, __LINE__); | 1228 | DBG(" <- %s:%d\n", __func__, __LINE__); |
1228 | } | 1229 | } |
1229 | 1230 | ||
diff --git a/arch/powerpc/platforms/ps3/platform.h b/arch/powerpc/platforms/ps3/platform.h index 1a633ed0fe98..d71329a8e325 100644 --- a/arch/powerpc/platforms/ps3/platform.h +++ b/arch/powerpc/platforms/ps3/platform.h | |||
@@ -188,6 +188,22 @@ int ps3_repository_read_rm_size(unsigned int ppe_id, u64 *rm_size); | |||
188 | int ps3_repository_read_region_total(u64 *region_total); | 188 | int ps3_repository_read_region_total(u64 *region_total); |
189 | int ps3_repository_read_mm_info(u64 *rm_base, u64 *rm_size, | 189 | int ps3_repository_read_mm_info(u64 *rm_base, u64 *rm_size, |
190 | u64 *region_total); | 190 | u64 *region_total); |
191 | int ps3_repository_read_highmem_region_count(unsigned int *region_count); | ||
192 | int ps3_repository_read_highmem_base(unsigned int region_index, | ||
193 | u64 *highmem_base); | ||
194 | int ps3_repository_read_highmem_size(unsigned int region_index, | ||
195 | u64 *highmem_size); | ||
196 | int ps3_repository_read_highmem_info(unsigned int region_index, | ||
197 | u64 *highmem_base, u64 *highmem_size); | ||
198 | |||
199 | int ps3_repository_write_highmem_region_count(unsigned int region_count); | ||
200 | int ps3_repository_write_highmem_base(unsigned int region_index, | ||
201 | u64 highmem_base); | ||
202 | int ps3_repository_write_highmem_size(unsigned int region_index, | ||
203 | u64 highmem_size); | ||
204 | int ps3_repository_write_highmem_info(unsigned int region_index, | ||
205 | u64 highmem_base, u64 highmem_size); | ||
206 | int ps3_repository_delete_highmem_info(unsigned int region_index); | ||
191 | 207 | ||
192 | /* repository pme info */ | 208 | /* repository pme info */ |
193 | 209 | ||
diff --git a/arch/powerpc/platforms/ps3/repository.c b/arch/powerpc/platforms/ps3/repository.c index 7bdfea336f5e..9b47ba7a5de7 100644 --- a/arch/powerpc/platforms/ps3/repository.c +++ b/arch/powerpc/platforms/ps3/repository.c | |||
@@ -779,6 +779,72 @@ int ps3_repository_read_mm_info(u64 *rm_base, u64 *rm_size, u64 *region_total) | |||
779 | } | 779 | } |
780 | 780 | ||
781 | /** | 781 | /** |
782 | * ps3_repository_read_highmem_region_count - Read the number of highmem regions | ||
783 | * | ||
784 | * Bootloaders must arrange the repository nodes such that regions are indexed | ||
785 | * with a region_index from 0 to region_count-1. | ||
786 | */ | ||
787 | |||
788 | int ps3_repository_read_highmem_region_count(unsigned int *region_count) | ||
789 | { | ||
790 | int result; | ||
791 | u64 v1 = 0; | ||
792 | |||
793 | result = read_node(PS3_LPAR_ID_CURRENT, | ||
794 | make_first_field("highmem", 0), | ||
795 | make_field("region", 0), | ||
796 | make_field("count", 0), | ||
797 | 0, | ||
798 | &v1, NULL); | ||
799 | *region_count = v1; | ||
800 | return result; | ||
801 | } | ||
802 | |||
803 | |||
804 | int ps3_repository_read_highmem_base(unsigned int region_index, | ||
805 | u64 *highmem_base) | ||
806 | { | ||
807 | return read_node(PS3_LPAR_ID_CURRENT, | ||
808 | make_first_field("highmem", 0), | ||
809 | make_field("region", region_index), | ||
810 | make_field("base", 0), | ||
811 | 0, | ||
812 | highmem_base, NULL); | ||
813 | } | ||
814 | |||
815 | int ps3_repository_read_highmem_size(unsigned int region_index, | ||
816 | u64 *highmem_size) | ||
817 | { | ||
818 | return read_node(PS3_LPAR_ID_CURRENT, | ||
819 | make_first_field("highmem", 0), | ||
820 | make_field("region", region_index), | ||
821 | make_field("size", 0), | ||
822 | 0, | ||
823 | highmem_size, NULL); | ||
824 | } | ||
825 | |||
826 | /** | ||
827 | * ps3_repository_read_highmem_info - Read high memory region info | ||
828 | * @region_index: Region index, {0,..,region_count-1}. | ||
829 | * @highmem_base: High memory base address. | ||
830 | * @highmem_size: High memory size. | ||
831 | * | ||
832 | * Bootloaders that preallocate highmem regions must place the | ||
833 | * region info into the repository at these well known nodes. | ||
834 | */ | ||
835 | |||
836 | int ps3_repository_read_highmem_info(unsigned int region_index, | ||
837 | u64 *highmem_base, u64 *highmem_size) | ||
838 | { | ||
839 | int result; | ||
840 | |||
841 | *highmem_base = 0; | ||
842 | result = ps3_repository_read_highmem_base(region_index, highmem_base); | ||
843 | return result ? result | ||
844 | : ps3_repository_read_highmem_size(region_index, highmem_size); | ||
845 | } | ||
846 | |||
847 | /** | ||
782 | * ps3_repository_read_num_spu_reserved - Number of physical spus reserved. | 848 | * ps3_repository_read_num_spu_reserved - Number of physical spus reserved. |
783 | * @num_spu: Number of physical spus. | 849 | * @num_spu: Number of physical spus. |
784 | */ | 850 | */ |
@@ -1002,6 +1068,138 @@ int ps3_repository_read_lpm_privileges(unsigned int be_index, u64 *lpar, | |||
1002 | lpar, rights); | 1068 | lpar, rights); |
1003 | } | 1069 | } |
1004 | 1070 | ||
1071 | #if defined(CONFIG_PS3_REPOSITORY_WRITE) | ||
1072 | |||
1073 | static int create_node(u64 n1, u64 n2, u64 n3, u64 n4, u64 v1, u64 v2) | ||
1074 | { | ||
1075 | int result; | ||
1076 | |||
1077 | dump_node(0, n1, n2, n3, n4, v1, v2); | ||
1078 | |||
1079 | result = lv1_create_repository_node(n1, n2, n3, n4, v1, v2); | ||
1080 | |||
1081 | if (result) { | ||
1082 | pr_devel("%s:%d: lv1_create_repository_node failed: %s\n", | ||
1083 | __func__, __LINE__, ps3_result(result)); | ||
1084 | return -ENOENT; | ||
1085 | } | ||
1086 | |||
1087 | return 0; | ||
1088 | } | ||
1089 | |||
1090 | static int delete_node(u64 n1, u64 n2, u64 n3, u64 n4) | ||
1091 | { | ||
1092 | int result; | ||
1093 | |||
1094 | dump_node(0, n1, n2, n3, n4, 0, 0); | ||
1095 | |||
1096 | result = lv1_delete_repository_node(n1, n2, n3, n4); | ||
1097 | |||
1098 | if (result) { | ||
1099 | pr_devel("%s:%d: lv1_delete_repository_node failed: %s\n", | ||
1100 | __func__, __LINE__, ps3_result(result)); | ||
1101 | return -ENOENT; | ||
1102 | } | ||
1103 | |||
1104 | return 0; | ||
1105 | } | ||
1106 | |||
1107 | static int write_node(u64 n1, u64 n2, u64 n3, u64 n4, u64 v1, u64 v2) | ||
1108 | { | ||
1109 | int result; | ||
1110 | |||
1111 | result = create_node(n1, n2, n3, n4, v1, v2); | ||
1112 | |||
1113 | if (!result) | ||
1114 | return 0; | ||
1115 | |||
1116 | result = lv1_write_repository_node(n1, n2, n3, n4, v1, v2); | ||
1117 | |||
1118 | if (result) { | ||
1119 | pr_devel("%s:%d: lv1_write_repository_node failed: %s\n", | ||
1120 | __func__, __LINE__, ps3_result(result)); | ||
1121 | return -ENOENT; | ||
1122 | } | ||
1123 | |||
1124 | return 0; | ||
1125 | } | ||
1126 | |||
1127 | int ps3_repository_write_highmem_region_count(unsigned int region_count) | ||
1128 | { | ||
1129 | int result; | ||
1130 | u64 v1 = (u64)region_count; | ||
1131 | |||
1132 | result = write_node( | ||
1133 | make_first_field("highmem", 0), | ||
1134 | make_field("region", 0), | ||
1135 | make_field("count", 0), | ||
1136 | 0, | ||
1137 | v1, 0); | ||
1138 | return result; | ||
1139 | } | ||
1140 | |||
1141 | int ps3_repository_write_highmem_base(unsigned int region_index, | ||
1142 | u64 highmem_base) | ||
1143 | { | ||
1144 | return write_node( | ||
1145 | make_first_field("highmem", 0), | ||
1146 | make_field("region", region_index), | ||
1147 | make_field("base", 0), | ||
1148 | 0, | ||
1149 | highmem_base, 0); | ||
1150 | } | ||
1151 | |||
1152 | int ps3_repository_write_highmem_size(unsigned int region_index, | ||
1153 | u64 highmem_size) | ||
1154 | { | ||
1155 | return write_node( | ||
1156 | make_first_field("highmem", 0), | ||
1157 | make_field("region", region_index), | ||
1158 | make_field("size", 0), | ||
1159 | 0, | ||
1160 | highmem_size, 0); | ||
1161 | } | ||
1162 | |||
1163 | int ps3_repository_write_highmem_info(unsigned int region_index, | ||
1164 | u64 highmem_base, u64 highmem_size) | ||
1165 | { | ||
1166 | int result; | ||
1167 | |||
1168 | result = ps3_repository_write_highmem_base(region_index, highmem_base); | ||
1169 | return result ? result | ||
1170 | : ps3_repository_write_highmem_size(region_index, highmem_size); | ||
1171 | } | ||
1172 | |||
1173 | static int ps3_repository_delete_highmem_base(unsigned int region_index) | ||
1174 | { | ||
1175 | return delete_node( | ||
1176 | make_first_field("highmem", 0), | ||
1177 | make_field("region", region_index), | ||
1178 | make_field("base", 0), | ||
1179 | 0); | ||
1180 | } | ||
1181 | |||
1182 | static int ps3_repository_delete_highmem_size(unsigned int region_index) | ||
1183 | { | ||
1184 | return delete_node( | ||
1185 | make_first_field("highmem", 0), | ||
1186 | make_field("region", region_index), | ||
1187 | make_field("size", 0), | ||
1188 | 0); | ||
1189 | } | ||
1190 | |||
1191 | int ps3_repository_delete_highmem_info(unsigned int region_index) | ||
1192 | { | ||
1193 | int result; | ||
1194 | |||
1195 | result = ps3_repository_delete_highmem_base(region_index); | ||
1196 | result += ps3_repository_delete_highmem_size(region_index); | ||
1197 | |||
1198 | return result ? -1 : 0; | ||
1199 | } | ||
1200 | |||
1201 | #endif /* defined(CONFIG_PS3_WRITE_REPOSITORY) */ | ||
1202 | |||
1005 | #if defined(DEBUG) | 1203 | #if defined(DEBUG) |
1006 | 1204 | ||
1007 | int ps3_repository_dump_resource_info(const struct ps3_repository_device *repo) | 1205 | int ps3_repository_dump_resource_info(const struct ps3_repository_device *repo) |
diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c index a75e37dc41aa..ecd394cf34e6 100644 --- a/arch/powerpc/platforms/pseries/eeh.c +++ b/arch/powerpc/platforms/pseries/eeh.c | |||
@@ -489,7 +489,7 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev) | |||
489 | * a stack trace will help the device-driver authors figure | 489 | * a stack trace will help the device-driver authors figure |
490 | * out what happened. So print that out. | 490 | * out what happened. So print that out. |
491 | */ | 491 | */ |
492 | dump_stack(); | 492 | WARN(1, "EEH: failure detected\n"); |
493 | return 1; | 493 | return 1; |
494 | 494 | ||
495 | dn_unlock: | 495 | dn_unlock: |
diff --git a/arch/powerpc/platforms/pseries/plpar_wrappers.h b/arch/powerpc/platforms/pseries/plpar_wrappers.h index 342797fc0f9c..13e8cc43adf7 100644 --- a/arch/powerpc/platforms/pseries/plpar_wrappers.h +++ b/arch/powerpc/platforms/pseries/plpar_wrappers.h | |||
@@ -22,12 +22,12 @@ static inline long poll_pending(void) | |||
22 | 22 | ||
23 | static inline u8 get_cede_latency_hint(void) | 23 | static inline u8 get_cede_latency_hint(void) |
24 | { | 24 | { |
25 | return get_lppaca()->gpr5_dword.fields.cede_latency_hint; | 25 | return get_lppaca()->cede_latency_hint; |
26 | } | 26 | } |
27 | 27 | ||
28 | static inline void set_cede_latency_hint(u8 latency_hint) | 28 | static inline void set_cede_latency_hint(u8 latency_hint) |
29 | { | 29 | { |
30 | get_lppaca()->gpr5_dword.fields.cede_latency_hint = latency_hint; | 30 | get_lppaca()->cede_latency_hint = latency_hint; |
31 | } | 31 | } |
32 | 32 | ||
33 | static inline long cede_processor(void) | 33 | static inline long cede_processor(void) |
diff --git a/arch/powerpc/platforms/pseries/reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c index 168651acdd83..7b3bf76ef834 100644 --- a/arch/powerpc/platforms/pseries/reconfig.c +++ b/arch/powerpc/platforms/pseries/reconfig.c | |||
@@ -103,11 +103,13 @@ int pSeries_reconfig_notifier_register(struct notifier_block *nb) | |||
103 | { | 103 | { |
104 | return blocking_notifier_chain_register(&pSeries_reconfig_chain, nb); | 104 | return blocking_notifier_chain_register(&pSeries_reconfig_chain, nb); |
105 | } | 105 | } |
106 | EXPORT_SYMBOL_GPL(pSeries_reconfig_notifier_register); | ||
106 | 107 | ||
107 | void pSeries_reconfig_notifier_unregister(struct notifier_block *nb) | 108 | void pSeries_reconfig_notifier_unregister(struct notifier_block *nb) |
108 | { | 109 | { |
109 | blocking_notifier_chain_unregister(&pSeries_reconfig_chain, nb); | 110 | blocking_notifier_chain_unregister(&pSeries_reconfig_chain, nb); |
110 | } | 111 | } |
112 | EXPORT_SYMBOL_GPL(pSeries_reconfig_notifier_unregister); | ||
111 | 113 | ||
112 | int pSeries_reconfig_notify(unsigned long action, void *p) | 114 | int pSeries_reconfig_notify(unsigned long action, void *p) |
113 | { | 115 | { |
@@ -426,6 +428,7 @@ static int do_remove_property(char *buf, size_t bufsize) | |||
426 | static int do_update_property(char *buf, size_t bufsize) | 428 | static int do_update_property(char *buf, size_t bufsize) |
427 | { | 429 | { |
428 | struct device_node *np; | 430 | struct device_node *np; |
431 | struct pSeries_reconfig_prop_update upd_value; | ||
429 | unsigned char *value; | 432 | unsigned char *value; |
430 | char *name, *end, *next_prop; | 433 | char *name, *end, *next_prop; |
431 | int rc, length; | 434 | int rc, length; |
@@ -454,6 +457,10 @@ static int do_update_property(char *buf, size_t bufsize) | |||
454 | return -ENODEV; | 457 | return -ENODEV; |
455 | } | 458 | } |
456 | 459 | ||
460 | upd_value.node = np; | ||
461 | upd_value.property = newprop; | ||
462 | pSeries_reconfig_notify(PSERIES_UPDATE_PROPERTY, &upd_value); | ||
463 | |||
457 | rc = prom_update_property(np, newprop, oldprop); | 464 | rc = prom_update_property(np, newprop, oldprop); |
458 | if (rc) | 465 | if (rc) |
459 | return rc; | 466 | return rc; |
diff --git a/arch/powerpc/sysdev/ppc4xx_msi.c b/arch/powerpc/sysdev/ppc4xx_msi.c index 1c2d7af17bbe..82c6702dcbab 100644 --- a/arch/powerpc/sysdev/ppc4xx_msi.c +++ b/arch/powerpc/sysdev/ppc4xx_msi.c | |||
@@ -28,10 +28,11 @@ | |||
28 | #include <linux/of_platform.h> | 28 | #include <linux/of_platform.h> |
29 | #include <linux/interrupt.h> | 29 | #include <linux/interrupt.h> |
30 | #include <linux/export.h> | 30 | #include <linux/export.h> |
31 | #include <linux/kernel.h> | ||
31 | #include <asm/prom.h> | 32 | #include <asm/prom.h> |
32 | #include <asm/hw_irq.h> | 33 | #include <asm/hw_irq.h> |
33 | #include <asm/ppc-pci.h> | 34 | #include <asm/ppc-pci.h> |
34 | #include <boot/dcr.h> | 35 | #include <asm/dcr.h> |
35 | #include <asm/dcr-regs.h> | 36 | #include <asm/dcr-regs.h> |
36 | #include <asm/msi_bitmap.h> | 37 | #include <asm/msi_bitmap.h> |
37 | 38 | ||
@@ -43,13 +44,14 @@ | |||
43 | #define PEIH_FLUSH0 0x30 | 44 | #define PEIH_FLUSH0 0x30 |
44 | #define PEIH_FLUSH1 0x38 | 45 | #define PEIH_FLUSH1 0x38 |
45 | #define PEIH_CNTRST 0x48 | 46 | #define PEIH_CNTRST 0x48 |
46 | #define NR_MSI_IRQS 4 | 47 | |
48 | static int msi_irqs; | ||
47 | 49 | ||
48 | struct ppc4xx_msi { | 50 | struct ppc4xx_msi { |
49 | u32 msi_addr_lo; | 51 | u32 msi_addr_lo; |
50 | u32 msi_addr_hi; | 52 | u32 msi_addr_hi; |
51 | void __iomem *msi_regs; | 53 | void __iomem *msi_regs; |
52 | int msi_virqs[NR_MSI_IRQS]; | 54 | int *msi_virqs; |
53 | struct msi_bitmap bitmap; | 55 | struct msi_bitmap bitmap; |
54 | struct device_node *msi_dev; | 56 | struct device_node *msi_dev; |
55 | }; | 57 | }; |
@@ -61,7 +63,7 @@ static int ppc4xx_msi_init_allocator(struct platform_device *dev, | |||
61 | { | 63 | { |
62 | int err; | 64 | int err; |
63 | 65 | ||
64 | err = msi_bitmap_alloc(&msi_data->bitmap, NR_MSI_IRQS, | 66 | err = msi_bitmap_alloc(&msi_data->bitmap, msi_irqs, |
65 | dev->dev.of_node); | 67 | dev->dev.of_node); |
66 | if (err) | 68 | if (err) |
67 | return err; | 69 | return err; |
@@ -83,6 +85,11 @@ static int ppc4xx_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) | |||
83 | struct msi_desc *entry; | 85 | struct msi_desc *entry; |
84 | struct ppc4xx_msi *msi_data = &ppc4xx_msi; | 86 | struct ppc4xx_msi *msi_data = &ppc4xx_msi; |
85 | 87 | ||
88 | msi_data->msi_virqs = kmalloc((msi_irqs) * sizeof(int), | ||
89 | GFP_KERNEL); | ||
90 | if (!msi_data->msi_virqs) | ||
91 | return -ENOMEM; | ||
92 | |||
86 | list_for_each_entry(entry, &dev->msi_list, list) { | 93 | list_for_each_entry(entry, &dev->msi_list, list) { |
87 | int_no = msi_bitmap_alloc_hwirqs(&msi_data->bitmap, 1); | 94 | int_no = msi_bitmap_alloc_hwirqs(&msi_data->bitmap, 1); |
88 | if (int_no >= 0) | 95 | if (int_no >= 0) |
@@ -150,12 +157,11 @@ static int ppc4xx_setup_pcieh_hw(struct platform_device *dev, | |||
150 | if (!sdr_addr) | 157 | if (!sdr_addr) |
151 | return -1; | 158 | return -1; |
152 | 159 | ||
153 | SDR0_WRITE(sdr_addr, (u64)res.start >> 32); /*HIGH addr */ | 160 | mtdcri(SDR0, *sdr_addr, upper_32_bits(res.start)); /*HIGH addr */ |
154 | SDR0_WRITE(sdr_addr + 1, res.start & 0xFFFFFFFF); /* Low addr */ | 161 | mtdcri(SDR0, *sdr_addr + 1, lower_32_bits(res.start)); /* Low addr */ |
155 | |||
156 | 162 | ||
157 | msi->msi_dev = of_find_node_by_name(NULL, "ppc4xx-msi"); | 163 | msi->msi_dev = of_find_node_by_name(NULL, "ppc4xx-msi"); |
158 | if (msi->msi_dev) | 164 | if (!msi->msi_dev) |
159 | return -ENODEV; | 165 | return -ENODEV; |
160 | 166 | ||
161 | msi->msi_regs = of_iomap(msi->msi_dev, 0); | 167 | msi->msi_regs = of_iomap(msi->msi_dev, 0); |
@@ -167,9 +173,12 @@ static int ppc4xx_setup_pcieh_hw(struct platform_device *dev, | |||
167 | (u32) (msi->msi_regs + PEIH_TERMADH), (u32) (msi->msi_regs)); | 173 | (u32) (msi->msi_regs + PEIH_TERMADH), (u32) (msi->msi_regs)); |
168 | 174 | ||
169 | msi_virt = dma_alloc_coherent(&dev->dev, 64, &msi_phys, GFP_KERNEL); | 175 | msi_virt = dma_alloc_coherent(&dev->dev, 64, &msi_phys, GFP_KERNEL); |
170 | msi->msi_addr_hi = 0x0; | 176 | if (!msi_virt) |
171 | msi->msi_addr_lo = (u32) msi_phys; | 177 | return -ENOMEM; |
172 | dev_dbg(&dev->dev, "PCIE-MSI: msi address 0x%x\n", msi->msi_addr_lo); | 178 | msi->msi_addr_hi = upper_32_bits(msi_phys); |
179 | msi->msi_addr_lo = lower_32_bits(msi_phys & 0xffffffff); | ||
180 | dev_dbg(&dev->dev, "PCIE-MSI: msi address high 0x%x, low 0x%x\n", | ||
181 | msi->msi_addr_hi, msi->msi_addr_lo); | ||
173 | 182 | ||
174 | /* Progam the Interrupt handler Termination addr registers */ | 183 | /* Progam the Interrupt handler Termination addr registers */ |
175 | out_be32(msi->msi_regs + PEIH_TERMADH, msi->msi_addr_hi); | 184 | out_be32(msi->msi_regs + PEIH_TERMADH, msi->msi_addr_hi); |
@@ -185,6 +194,8 @@ static int ppc4xx_setup_pcieh_hw(struct platform_device *dev, | |||
185 | out_be32(msi->msi_regs + PEIH_MSIED, *msi_data); | 194 | out_be32(msi->msi_regs + PEIH_MSIED, *msi_data); |
186 | out_be32(msi->msi_regs + PEIH_MSIMK, *msi_mask); | 195 | out_be32(msi->msi_regs + PEIH_MSIMK, *msi_mask); |
187 | 196 | ||
197 | dma_free_coherent(&dev->dev, 64, msi_virt, msi_phys); | ||
198 | |||
188 | return 0; | 199 | return 0; |
189 | } | 200 | } |
190 | 201 | ||
@@ -194,7 +205,7 @@ static int ppc4xx_of_msi_remove(struct platform_device *dev) | |||
194 | int i; | 205 | int i; |
195 | int virq; | 206 | int virq; |
196 | 207 | ||
197 | for (i = 0; i < NR_MSI_IRQS; i++) { | 208 | for (i = 0; i < msi_irqs; i++) { |
198 | virq = msi->msi_virqs[i]; | 209 | virq = msi->msi_virqs[i]; |
199 | if (virq != NO_IRQ) | 210 | if (virq != NO_IRQ) |
200 | irq_dispose_mapping(virq); | 211 | irq_dispose_mapping(virq); |
@@ -215,8 +226,6 @@ static int __devinit ppc4xx_msi_probe(struct platform_device *dev) | |||
215 | struct resource res; | 226 | struct resource res; |
216 | int err = 0; | 227 | int err = 0; |
217 | 228 | ||
218 | msi = &ppc4xx_msi;/*keep the msi data for further use*/ | ||
219 | |||
220 | dev_dbg(&dev->dev, "PCIE-MSI: Setting up MSI support...\n"); | 229 | dev_dbg(&dev->dev, "PCIE-MSI: Setting up MSI support...\n"); |
221 | 230 | ||
222 | msi = kzalloc(sizeof(struct ppc4xx_msi), GFP_KERNEL); | 231 | msi = kzalloc(sizeof(struct ppc4xx_msi), GFP_KERNEL); |
@@ -234,6 +243,10 @@ static int __devinit ppc4xx_msi_probe(struct platform_device *dev) | |||
234 | goto error_out; | 243 | goto error_out; |
235 | } | 244 | } |
236 | 245 | ||
246 | msi_irqs = of_irq_count(dev->dev.of_node); | ||
247 | if (!msi_irqs) | ||
248 | return -ENODEV; | ||
249 | |||
237 | if (ppc4xx_setup_pcieh_hw(dev, res, msi)) | 250 | if (ppc4xx_setup_pcieh_hw(dev, res, msi)) |
238 | goto error_out; | 251 | goto error_out; |
239 | 252 | ||
@@ -242,6 +255,7 @@ static int __devinit ppc4xx_msi_probe(struct platform_device *dev) | |||
242 | dev_err(&dev->dev, "Error allocating MSI bitmap\n"); | 255 | dev_err(&dev->dev, "Error allocating MSI bitmap\n"); |
243 | goto error_out; | 256 | goto error_out; |
244 | } | 257 | } |
258 | ppc4xx_msi = *msi; | ||
245 | 259 | ||
246 | ppc_md.setup_msi_irqs = ppc4xx_setup_msi_irqs; | 260 | ppc_md.setup_msi_irqs = ppc4xx_setup_msi_irqs; |
247 | ppc_md.teardown_msi_irqs = ppc4xx_teardown_msi_irqs; | 261 | ppc_md.teardown_msi_irqs = ppc4xx_teardown_msi_irqs; |