aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/pseries
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-06-10 21:54:22 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-06-10 21:54:22 -0400
commitc5aec4c76af1a2d89ee2f2d4d5463b2ad2d85de5 (patch)
tree628ae2d9370a6739fd98d8d2f055b46c87ab9316 /arch/powerpc/platforms/pseries
parent2937f5efa5754754daf46de745f67350f7f06ec2 (diff)
parent0c0a3e5a100bbc4aaedd140e82b429227a76701b (diff)
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
Pull powerpc updates from Ben Herrenschmidt: "Here is the bulk of the powerpc changes for this merge window. It got a bit delayed in part because I wasn't paying attention, and in part because I discovered I had a core PCI change without a PCI maintainer ack in it. Bjorn eventually agreed it was ok to merge it though we'll probably improve it later and I didn't want to rebase to add his ack. There is going to be a bit more next week, essentially fixes that I still want to sort through and test. The biggest item this time is the support to build the ppc64 LE kernel with our new v2 ABI. We previously supported v2 userspace but the kernel itself was a tougher nut to crack. This is now sorted mostly thanks to Anton and Rusty. We also have a fairly big series from Cedric that add support for 64-bit LE zImage boot wrapper. This was made harder by the fact that traditionally our zImage wrapper was always 32-bit, but our new LE toolchains don't really support 32-bit anymore (it's somewhat there but not really "supported") so we didn't want to rely on it. This meant more churn that just endian fixes. This brings some more LE bits as well, such as the ability to run in LE mode without a hypervisor (ie. under OPAL firmware) by doing the right OPAL call to reinitialize the CPU to take HV interrupts in the right mode and the usual pile of endian fixes. There's another series from Gavin adding EEH improvements (one day we *will* have a release with less than 20 EEH patches, I promise!). Another highlight is the support for the "Split core" functionality on P8 by Michael. This allows a P8 core to be split into "sub cores" of 4 threads which allows the subcores to run different guests under KVM (the HW still doesn't support a partition per thread). And then the usual misc bits and fixes ..." [ Further delayed by gmail deciding that BenH is a dirty spammer. Google knows. ] * 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc: (155 commits) powerpc/powernv: Add missing include to LPC code selftests/powerpc: Test the THP bug we fixed in the previous commit powerpc/mm: Check paca psize is up to date for huge mappings powerpc/powernv: Pass buffer size to OPAL validate flash call powerpc/pseries: hcall functions are exported to modules, need _GLOBAL_TOC() powerpc: Exported functions __clear_user and copy_page use r2 so need _GLOBAL_TOC() powerpc/powernv: Set memory_block_size_bytes to 256MB powerpc: Allow ppc_md platform hook to override memory_block_size_bytes powerpc/powernv: Fix endian issues in memory error handling code powerpc/eeh: Skip eeh sysfs when eeh is disabled powerpc: 64bit sendfile is capped at 2GB powerpc/powernv: Provide debugfs access to the LPC bus via OPAL powerpc/serial: Use saner flags when creating legacy ports powerpc: Add cpu family documentation powerpc/xmon: Fix up xmon format strings powerpc/powernv: Add calls to support little endian host powerpc: Document sysfs DSCR interface powerpc: Fix regression of per-CPU DSCR setting powerpc: Split __SYSFS_SPRSETUP macro arch: powerpc/fadump: Cleaning up inconsistent NULL checks ...
Diffstat (limited to 'arch/powerpc/platforms/pseries')
-rw-r--r--arch/powerpc/platforms/pseries/eeh_pseries.c43
-rw-r--r--arch/powerpc/platforms/pseries/hotplug-memory.c17
-rw-r--r--arch/powerpc/platforms/pseries/hvCall.S10
-rw-r--r--arch/powerpc/platforms/pseries/pseries.h2
-rw-r--r--arch/powerpc/platforms/pseries/setup.c7
-rw-r--r--arch/powerpc/platforms/pseries/smp.c5
6 files changed, 62 insertions, 22 deletions
diff --git a/arch/powerpc/platforms/pseries/eeh_pseries.c b/arch/powerpc/platforms/pseries/eeh_pseries.c
index 8a8f0472d98f..0bec0c02c5e7 100644
--- a/arch/powerpc/platforms/pseries/eeh_pseries.c
+++ b/arch/powerpc/platforms/pseries/eeh_pseries.c
@@ -175,6 +175,36 @@ static int pseries_eeh_find_cap(struct device_node *dn, int cap)
175 return 0; 175 return 0;
176} 176}
177 177
178static int pseries_eeh_find_ecap(struct device_node *dn, int cap)
179{
180 struct pci_dn *pdn = PCI_DN(dn);
181 struct eeh_dev *edev = of_node_to_eeh_dev(dn);
182 u32 header;
183 int pos = 256;
184 int ttl = (4096 - 256) / 8;
185
186 if (!edev || !edev->pcie_cap)
187 return 0;
188 if (rtas_read_config(pdn, pos, 4, &header) != PCIBIOS_SUCCESSFUL)
189 return 0;
190 else if (!header)
191 return 0;
192
193 while (ttl-- > 0) {
194 if (PCI_EXT_CAP_ID(header) == cap && pos)
195 return pos;
196
197 pos = PCI_EXT_CAP_NEXT(header);
198 if (pos < 256)
199 break;
200
201 if (rtas_read_config(pdn, pos, 4, &header) != PCIBIOS_SUCCESSFUL)
202 break;
203 }
204
205 return 0;
206}
207
178/** 208/**
179 * pseries_eeh_of_probe - EEH probe on the given device 209 * pseries_eeh_of_probe - EEH probe on the given device
180 * @dn: OF node 210 * @dn: OF node
@@ -220,7 +250,9 @@ static void *pseries_eeh_of_probe(struct device_node *dn, void *flag)
220 * or PCIe switch downstream port. 250 * or PCIe switch downstream port.
221 */ 251 */
222 edev->class_code = class_code; 252 edev->class_code = class_code;
253 edev->pcix_cap = pseries_eeh_find_cap(dn, PCI_CAP_ID_PCIX);
223 edev->pcie_cap = pseries_eeh_find_cap(dn, PCI_CAP_ID_EXP); 254 edev->pcie_cap = pseries_eeh_find_cap(dn, PCI_CAP_ID_EXP);
255 edev->aer_cap = pseries_eeh_find_ecap(dn, PCI_EXT_CAP_ID_ERR);
224 edev->mode &= 0xFFFFFF00; 256 edev->mode &= 0xFFFFFF00;
225 if ((edev->class_code >> 8) == PCI_CLASS_BRIDGE_PCI) { 257 if ((edev->class_code >> 8) == PCI_CLASS_BRIDGE_PCI) {
226 edev->mode |= EEH_DEV_BRIDGE; 258 edev->mode |= EEH_DEV_BRIDGE;
@@ -464,6 +496,7 @@ static int pseries_eeh_get_state(struct eeh_pe *pe, int *state)
464 } else { 496 } else {
465 result = EEH_STATE_NOT_SUPPORT; 497 result = EEH_STATE_NOT_SUPPORT;
466 } 498 }
499 break;
467 default: 500 default:
468 result = EEH_STATE_NOT_SUPPORT; 501 result = EEH_STATE_NOT_SUPPORT;
469 } 502 }
@@ -499,11 +532,19 @@ static int pseries_eeh_reset(struct eeh_pe *pe, int option)
499 /* If fundamental-reset not supported, try hot-reset */ 532 /* If fundamental-reset not supported, try hot-reset */
500 if (option == EEH_RESET_FUNDAMENTAL && 533 if (option == EEH_RESET_FUNDAMENTAL &&
501 ret == -8) { 534 ret == -8) {
535 option = EEH_RESET_HOT;
502 ret = rtas_call(ibm_set_slot_reset, 4, 1, NULL, 536 ret = rtas_call(ibm_set_slot_reset, 4, 1, NULL,
503 config_addr, BUID_HI(pe->phb->buid), 537 config_addr, BUID_HI(pe->phb->buid),
504 BUID_LO(pe->phb->buid), EEH_RESET_HOT); 538 BUID_LO(pe->phb->buid), option);
505 } 539 }
506 540
541 /* We need reset hold or settlement delay */
542 if (option == EEH_RESET_FUNDAMENTAL ||
543 option == EEH_RESET_HOT)
544 msleep(EEH_PE_RST_HOLD_TIME);
545 else
546 msleep(EEH_PE_RST_SETTLE_TIME);
547
507 return ret; 548 return ret;
508} 549}
509 550
diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c
index 7f75c94af822..7995135170a3 100644
--- a/arch/powerpc/platforms/pseries/hotplug-memory.c
+++ b/arch/powerpc/platforms/pseries/hotplug-memory.c
@@ -21,7 +21,7 @@
21#include <asm/prom.h> 21#include <asm/prom.h>
22#include <asm/sparsemem.h> 22#include <asm/sparsemem.h>
23 23
24static unsigned long get_memblock_size(void) 24unsigned long pseries_memory_block_size(void)
25{ 25{
26 struct device_node *np; 26 struct device_node *np;
27 unsigned int memblock_size = MIN_MEMORY_BLOCK_SIZE; 27 unsigned int memblock_size = MIN_MEMORY_BLOCK_SIZE;
@@ -64,17 +64,6 @@ static unsigned long get_memblock_size(void)
64 return memblock_size; 64 return memblock_size;
65} 65}
66 66
67/* WARNING: This is going to override the generic definition whenever
68 * pseries is built-in regardless of what platform is active at boot
69 * time. This is fine for now as this is the only "option" and it
70 * should work everywhere. If not, we'll have to turn this into a
71 * ppc_md. callback
72 */
73unsigned long memory_block_size_bytes(void)
74{
75 return get_memblock_size();
76}
77
78#ifdef CONFIG_MEMORY_HOTREMOVE 67#ifdef CONFIG_MEMORY_HOTREMOVE
79static int pseries_remove_memory(u64 start, u64 size) 68static int pseries_remove_memory(u64 start, u64 size)
80{ 69{
@@ -105,7 +94,7 @@ static int pseries_remove_memblock(unsigned long base, unsigned int memblock_siz
105 if (!pfn_valid(start_pfn)) 94 if (!pfn_valid(start_pfn))
106 goto out; 95 goto out;
107 96
108 block_sz = memory_block_size_bytes(); 97 block_sz = pseries_memory_block_size();
109 sections_per_block = block_sz / MIN_MEMORY_BLOCK_SIZE; 98 sections_per_block = block_sz / MIN_MEMORY_BLOCK_SIZE;
110 nid = memory_add_physaddr_to_nid(base); 99 nid = memory_add_physaddr_to_nid(base);
111 100
@@ -201,7 +190,7 @@ static int pseries_update_drconf_memory(struct of_prop_reconfig *pr)
201 u32 *p; 190 u32 *p;
202 int i, rc = -EINVAL; 191 int i, rc = -EINVAL;
203 192
204 memblock_size = get_memblock_size(); 193 memblock_size = pseries_memory_block_size();
205 if (!memblock_size) 194 if (!memblock_size)
206 return -EINVAL; 195 return -EINVAL;
207 196
diff --git a/arch/powerpc/platforms/pseries/hvCall.S b/arch/powerpc/platforms/pseries/hvCall.S
index 444fe7759e55..99ecf0a5a929 100644
--- a/arch/powerpc/platforms/pseries/hvCall.S
+++ b/arch/powerpc/platforms/pseries/hvCall.S
@@ -49,7 +49,7 @@ END_FTR_SECTION(0, 1); \
49 std r0,16(r1); \ 49 std r0,16(r1); \
50 addi r4,r1,STK_PARAM(FIRST_REG); \ 50 addi r4,r1,STK_PARAM(FIRST_REG); \
51 stdu r1,-STACK_FRAME_OVERHEAD(r1); \ 51 stdu r1,-STACK_FRAME_OVERHEAD(r1); \
52 bl .__trace_hcall_entry; \ 52 bl __trace_hcall_entry; \
53 addi r1,r1,STACK_FRAME_OVERHEAD; \ 53 addi r1,r1,STACK_FRAME_OVERHEAD; \
54 ld r0,16(r1); \ 54 ld r0,16(r1); \
55 ld r3,STK_PARAM(R3)(r1); \ 55 ld r3,STK_PARAM(R3)(r1); \
@@ -83,7 +83,7 @@ END_FTR_SECTION(0, 1); \
83 mr r3,r6; \ 83 mr r3,r6; \
84 std r0,16(r1); \ 84 std r0,16(r1); \
85 stdu r1,-STACK_FRAME_OVERHEAD(r1); \ 85 stdu r1,-STACK_FRAME_OVERHEAD(r1); \
86 bl .__trace_hcall_exit; \ 86 bl __trace_hcall_exit; \
87 addi r1,r1,STACK_FRAME_OVERHEAD; \ 87 addi r1,r1,STACK_FRAME_OVERHEAD; \
88 ld r0,16(r1); \ 88 ld r0,16(r1); \
89 ld r3,STK_PARAM(R3)(r1); \ 89 ld r3,STK_PARAM(R3)(r1); \
@@ -106,7 +106,7 @@ END_FTR_SECTION(0, 1); \
106 106
107 .text 107 .text
108 108
109_GLOBAL(plpar_hcall_norets) 109_GLOBAL_TOC(plpar_hcall_norets)
110 HMT_MEDIUM 110 HMT_MEDIUM
111 111
112 mfcr r0 112 mfcr r0
@@ -122,7 +122,7 @@ _GLOBAL(plpar_hcall_norets)
122 mtcrf 0xff,r0 122 mtcrf 0xff,r0
123 blr /* return r3 = status */ 123 blr /* return r3 = status */
124 124
125_GLOBAL(plpar_hcall) 125_GLOBAL_TOC(plpar_hcall)
126 HMT_MEDIUM 126 HMT_MEDIUM
127 127
128 mfcr r0 128 mfcr r0
@@ -188,7 +188,7 @@ _GLOBAL(plpar_hcall_raw)
188 188
189 blr /* return r3 = status */ 189 blr /* return r3 = status */
190 190
191_GLOBAL(plpar_hcall9) 191_GLOBAL_TOC(plpar_hcall9)
192 HMT_MEDIUM 192 HMT_MEDIUM
193 193
194 mfcr r0 194 mfcr r0
diff --git a/arch/powerpc/platforms/pseries/pseries.h b/arch/powerpc/platforms/pseries/pseries.h
index 99219530ea4a..361add62abf1 100644
--- a/arch/powerpc/platforms/pseries/pseries.h
+++ b/arch/powerpc/platforms/pseries/pseries.h
@@ -64,4 +64,6 @@ extern int dlpar_detach_node(struct device_node *);
64struct pci_host_bridge; 64struct pci_host_bridge;
65int pseries_root_bridge_prepare(struct pci_host_bridge *bridge); 65int pseries_root_bridge_prepare(struct pci_host_bridge *bridge);
66 66
67unsigned long pseries_memory_block_size(void);
68
67#endif /* _PSERIES_PSERIES_H */ 69#endif /* _PSERIES_PSERIES_H */
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index 099d2df976a2..f2f40e64658f 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -510,7 +510,11 @@ static void __init pSeries_setup_arch(void)
510static int __init pSeries_init_panel(void) 510static int __init pSeries_init_panel(void)
511{ 511{
512 /* Manually leave the kernel version on the panel. */ 512 /* Manually leave the kernel version on the panel. */
513#ifdef __BIG_ENDIAN__
513 ppc_md.progress("Linux ppc64\n", 0); 514 ppc_md.progress("Linux ppc64\n", 0);
515#else
516 ppc_md.progress("Linux ppc64le\n", 0);
517#endif
514 ppc_md.progress(init_utsname()->version, 0); 518 ppc_md.progress(init_utsname()->version, 0);
515 519
516 return 0; 520 return 0;
@@ -806,4 +810,7 @@ define_machine(pseries) {
806#ifdef CONFIG_KEXEC 810#ifdef CONFIG_KEXEC
807 .machine_kexec = pSeries_machine_kexec, 811 .machine_kexec = pSeries_machine_kexec,
808#endif 812#endif
813#ifdef CONFIG_MEMORY_HOTPLUG_SPARSE
814 .memory_block_size = pseries_memory_block_size,
815#endif
809}; 816};
diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c
index 24f58cb0a543..a3555b10c1a5 100644
--- a/arch/powerpc/platforms/pseries/smp.c
+++ b/arch/powerpc/platforms/pseries/smp.c
@@ -44,6 +44,7 @@
44#include <asm/xics.h> 44#include <asm/xics.h>
45#include <asm/dbell.h> 45#include <asm/dbell.h>
46#include <asm/plpar_wrappers.h> 46#include <asm/plpar_wrappers.h>
47#include <asm/code-patching.h>
47 48
48#include "pseries.h" 49#include "pseries.h"
49#include "offline_states.h" 50#include "offline_states.h"
@@ -96,8 +97,8 @@ int smp_query_cpu_stopped(unsigned int pcpu)
96static inline int smp_startup_cpu(unsigned int lcpu) 97static inline int smp_startup_cpu(unsigned int lcpu)
97{ 98{
98 int status; 99 int status;
99 unsigned long start_here = __pa((u32)*((unsigned long *) 100 unsigned long start_here =
100 generic_secondary_smp_init)); 101 __pa(ppc_function_entry(generic_secondary_smp_init));
101 unsigned int pcpu; 102 unsigned int pcpu;
102 int start_cpu; 103 int start_cpu;
103 104