diff options
Diffstat (limited to 'arch/powerpc/platforms')
-rw-r--r-- | arch/powerpc/platforms/powernv/eeh-ioda.c | 2 | ||||
-rw-r--r-- | arch/powerpc/platforms/powernv/eeh-powernv.c | 57 | ||||
-rw-r--r-- | arch/powerpc/platforms/powernv/opal-lpc.c | 63 | ||||
-rw-r--r-- | arch/powerpc/platforms/powernv/opal-wrappers.S | 2 | ||||
-rw-r--r-- | arch/powerpc/platforms/powernv/opal.c | 21 | ||||
-rw-r--r-- | arch/powerpc/platforms/powernv/pci.c | 2 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/dlpar.c | 26 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/hotplug-cpu.c | 4 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/iommu.c | 11 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/lpar.c | 14 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/pseries.h | 3 |
11 files changed, 173 insertions, 32 deletions
diff --git a/arch/powerpc/platforms/powernv/eeh-ioda.c b/arch/powerpc/platforms/powernv/eeh-ioda.c index 426814a2ede3..eba9cb10619c 100644 --- a/arch/powerpc/platforms/powernv/eeh-ioda.c +++ b/arch/powerpc/platforms/powernv/eeh-ioda.c | |||
@@ -373,7 +373,7 @@ static int ioda_eeh_get_pe_state(struct eeh_pe *pe) | |||
373 | * moving forward, we have to return operational | 373 | * moving forward, we have to return operational |
374 | * state during PE reset. | 374 | * state during PE reset. |
375 | */ | 375 | */ |
376 | if (pe->state & EEH_PE_RESET) { | 376 | if (pe->state & EEH_PE_CFG_BLOCKED) { |
377 | result = (EEH_STATE_MMIO_ACTIVE | | 377 | result = (EEH_STATE_MMIO_ACTIVE | |
378 | EEH_STATE_DMA_ACTIVE | | 378 | EEH_STATE_DMA_ACTIVE | |
379 | EEH_STATE_MMIO_ENABLED | | 379 | EEH_STATE_MMIO_ENABLED | |
diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c b/arch/powerpc/platforms/powernv/eeh-powernv.c index 3e89cbf55885..1d19e7917d7f 100644 --- a/arch/powerpc/platforms/powernv/eeh-powernv.c +++ b/arch/powerpc/platforms/powernv/eeh-powernv.c | |||
@@ -169,6 +169,26 @@ static int powernv_eeh_dev_probe(struct pci_dev *dev, void *flag) | |||
169 | } | 169 | } |
170 | 170 | ||
171 | /* | 171 | /* |
172 | * If the PE contains any one of following adapters, the | ||
173 | * PCI config space can't be accessed when dumping EEH log. | ||
174 | * Otherwise, we will run into fenced PHB caused by shortage | ||
175 | * of outbound credits in the adapter. The PCI config access | ||
176 | * should be blocked until PE reset. MMIO access is dropped | ||
177 | * by hardware certainly. In order to drop PCI config requests, | ||
178 | * one more flag (EEH_PE_CFG_RESTRICTED) is introduced, which | ||
179 | * will be checked in the backend for PE state retrival. If | ||
180 | * the PE becomes frozen for the first time and the flag has | ||
181 | * been set for the PE, we will set EEH_PE_CFG_BLOCKED for | ||
182 | * that PE to block its config space. | ||
183 | * | ||
184 | * Broadcom Austin 4-ports NICs (14e4:1657) | ||
185 | * Broadcom Shiner 2-ports 10G NICs (14e4:168e) | ||
186 | */ | ||
187 | if ((dev->vendor == PCI_VENDOR_ID_BROADCOM && dev->device == 0x1657) || | ||
188 | (dev->vendor == PCI_VENDOR_ID_BROADCOM && dev->device == 0x168e)) | ||
189 | edev->pe->state |= EEH_PE_CFG_RESTRICTED; | ||
190 | |||
191 | /* | ||
172 | * Cache the PE primary bus, which can't be fetched when | 192 | * Cache the PE primary bus, which can't be fetched when |
173 | * full hotplug is in progress. In that case, all child | 193 | * full hotplug is in progress. In that case, all child |
174 | * PCI devices of the PE are expected to be removed prior | 194 | * PCI devices of the PE are expected to be removed prior |
@@ -383,6 +403,39 @@ static int powernv_eeh_err_inject(struct eeh_pe *pe, int type, int func, | |||
383 | return ret; | 403 | return ret; |
384 | } | 404 | } |
385 | 405 | ||
406 | static inline bool powernv_eeh_cfg_blocked(struct device_node *dn) | ||
407 | { | ||
408 | struct eeh_dev *edev = of_node_to_eeh_dev(dn); | ||
409 | |||
410 | if (!edev || !edev->pe) | ||
411 | return false; | ||
412 | |||
413 | if (edev->pe->state & EEH_PE_CFG_BLOCKED) | ||
414 | return true; | ||
415 | |||
416 | return false; | ||
417 | } | ||
418 | |||
419 | static int powernv_eeh_read_config(struct device_node *dn, | ||
420 | int where, int size, u32 *val) | ||
421 | { | ||
422 | if (powernv_eeh_cfg_blocked(dn)) { | ||
423 | *val = 0xFFFFFFFF; | ||
424 | return PCIBIOS_SET_FAILED; | ||
425 | } | ||
426 | |||
427 | return pnv_pci_cfg_read(dn, where, size, val); | ||
428 | } | ||
429 | |||
430 | static int powernv_eeh_write_config(struct device_node *dn, | ||
431 | int where, int size, u32 val) | ||
432 | { | ||
433 | if (powernv_eeh_cfg_blocked(dn)) | ||
434 | return PCIBIOS_SET_FAILED; | ||
435 | |||
436 | return pnv_pci_cfg_write(dn, where, size, val); | ||
437 | } | ||
438 | |||
386 | /** | 439 | /** |
387 | * powernv_eeh_next_error - Retrieve next EEH error to handle | 440 | * powernv_eeh_next_error - Retrieve next EEH error to handle |
388 | * @pe: Affected PE | 441 | * @pe: Affected PE |
@@ -440,8 +493,8 @@ static struct eeh_ops powernv_eeh_ops = { | |||
440 | .get_log = powernv_eeh_get_log, | 493 | .get_log = powernv_eeh_get_log, |
441 | .configure_bridge = powernv_eeh_configure_bridge, | 494 | .configure_bridge = powernv_eeh_configure_bridge, |
442 | .err_inject = powernv_eeh_err_inject, | 495 | .err_inject = powernv_eeh_err_inject, |
443 | .read_config = pnv_pci_cfg_read, | 496 | .read_config = powernv_eeh_read_config, |
444 | .write_config = pnv_pci_cfg_write, | 497 | .write_config = powernv_eeh_write_config, |
445 | .next_error = powernv_eeh_next_error, | 498 | .next_error = powernv_eeh_next_error, |
446 | .restore_config = powernv_eeh_restore_config | 499 | .restore_config = powernv_eeh_restore_config |
447 | }; | 500 | }; |
diff --git a/arch/powerpc/platforms/powernv/opal-lpc.c b/arch/powerpc/platforms/powernv/opal-lpc.c index dd2c285ad170..e4169d68cb32 100644 --- a/arch/powerpc/platforms/powernv/opal-lpc.c +++ b/arch/powerpc/platforms/powernv/opal-lpc.c | |||
@@ -191,7 +191,6 @@ static ssize_t lpc_debug_read(struct file *filp, char __user *ubuf, | |||
191 | { | 191 | { |
192 | struct lpc_debugfs_entry *lpc = filp->private_data; | 192 | struct lpc_debugfs_entry *lpc = filp->private_data; |
193 | u32 data, pos, len, todo; | 193 | u32 data, pos, len, todo; |
194 | __be32 bedata; | ||
195 | int rc; | 194 | int rc; |
196 | 195 | ||
197 | if (!access_ok(VERIFY_WRITE, ubuf, count)) | 196 | if (!access_ok(VERIFY_WRITE, ubuf, count)) |
@@ -214,18 +213,57 @@ static ssize_t lpc_debug_read(struct file *filp, char __user *ubuf, | |||
214 | len = 2; | 213 | len = 2; |
215 | } | 214 | } |
216 | rc = opal_lpc_read(opal_lpc_chip_id, lpc->lpc_type, pos, | 215 | rc = opal_lpc_read(opal_lpc_chip_id, lpc->lpc_type, pos, |
217 | &bedata, len); | 216 | &data, len); |
218 | if (rc) | 217 | if (rc) |
219 | return -ENXIO; | 218 | return -ENXIO; |
220 | data = be32_to_cpu(bedata); | 219 | |
220 | /* | ||
221 | * Now there is some trickery with the data returned by OPAL | ||
222 | * as it's the desired data right justified in a 32-bit BE | ||
223 | * word. | ||
224 | * | ||
225 | * This is a very bad interface and I'm to blame for it :-( | ||
226 | * | ||
227 | * So we can't just apply a 32-bit swap to what comes from OPAL, | ||
228 | * because user space expects the *bytes* to be in their proper | ||
229 | * respective positions (ie, LPC position). | ||
230 | * | ||
231 | * So what we really want to do here is to shift data right | ||
232 | * appropriately on a LE kernel. | ||
233 | * | ||
234 | * IE. If the LPC transaction has bytes B0, B1, B2 and B3 in that | ||
235 | * order, we have in memory written to by OPAL at the "data" | ||
236 | * pointer: | ||
237 | * | ||
238 | * Bytes: OPAL "data" LE "data" | ||
239 | * 32-bit: B0 B1 B2 B3 B0B1B2B3 B3B2B1B0 | ||
240 | * 16-bit: B0 B1 0000B0B1 B1B00000 | ||
241 | * 8-bit: B0 000000B0 B0000000 | ||
242 | * | ||
243 | * So a BE kernel will have the leftmost of the above in the MSB | ||
244 | * and rightmost in the LSB and can just then "cast" the u32 "data" | ||
245 | * down to the appropriate quantity and write it. | ||
246 | * | ||
247 | * However, an LE kernel can't. It doesn't need to swap because a | ||
248 | * load from data followed by a store to user are going to preserve | ||
249 | * the byte ordering which is the wire byte order which is what the | ||
250 | * user wants, but in order to "crop" to the right size, we need to | ||
251 | * shift right first. | ||
252 | */ | ||
221 | switch(len) { | 253 | switch(len) { |
222 | case 4: | 254 | case 4: |
223 | rc = __put_user((u32)data, (u32 __user *)ubuf); | 255 | rc = __put_user((u32)data, (u32 __user *)ubuf); |
224 | break; | 256 | break; |
225 | case 2: | 257 | case 2: |
258 | #ifdef __LITTLE_ENDIAN__ | ||
259 | data >>= 16; | ||
260 | #endif | ||
226 | rc = __put_user((u16)data, (u16 __user *)ubuf); | 261 | rc = __put_user((u16)data, (u16 __user *)ubuf); |
227 | break; | 262 | break; |
228 | default: | 263 | default: |
264 | #ifdef __LITTLE_ENDIAN__ | ||
265 | data >>= 24; | ||
266 | #endif | ||
229 | rc = __put_user((u8)data, (u8 __user *)ubuf); | 267 | rc = __put_user((u8)data, (u8 __user *)ubuf); |
230 | break; | 268 | break; |
231 | } | 269 | } |
@@ -265,12 +303,31 @@ static ssize_t lpc_debug_write(struct file *filp, const char __user *ubuf, | |||
265 | else if (todo > 1 && (pos & 1) == 0) | 303 | else if (todo > 1 && (pos & 1) == 0) |
266 | len = 2; | 304 | len = 2; |
267 | } | 305 | } |
306 | |||
307 | /* | ||
308 | * Similarly to the read case, we have some trickery here but | ||
309 | * it's different to handle. We need to pass the value to OPAL in | ||
310 | * a register whose layout depends on the access size. We want | ||
311 | * to reproduce the memory layout of the user, however we aren't | ||
312 | * doing a load from user and a store to another memory location | ||
313 | * which would achieve that. Here we pass the value to OPAL via | ||
314 | * a register which is expected to contain the "BE" interpretation | ||
315 | * of the byte sequence. IE: for a 32-bit access, byte 0 should be | ||
316 | * in the MSB. So here we *do* need to byteswap on LE. | ||
317 | * | ||
318 | * User bytes: LE "data" OPAL "data" | ||
319 | * 32-bit: B0 B1 B2 B3 B3B2B1B0 B0B1B2B3 | ||
320 | * 16-bit: B0 B1 0000B1B0 0000B0B1 | ||
321 | * 8-bit: B0 000000B0 000000B0 | ||
322 | */ | ||
268 | switch(len) { | 323 | switch(len) { |
269 | case 4: | 324 | case 4: |
270 | rc = __get_user(data, (u32 __user *)ubuf); | 325 | rc = __get_user(data, (u32 __user *)ubuf); |
326 | data = cpu_to_be32(data); | ||
271 | break; | 327 | break; |
272 | case 2: | 328 | case 2: |
273 | rc = __get_user(data, (u16 __user *)ubuf); | 329 | rc = __get_user(data, (u16 __user *)ubuf); |
330 | data = cpu_to_be16(data); | ||
274 | break; | 331 | break; |
275 | default: | 332 | default: |
276 | rc = __get_user(data, (u8 __user *)ubuf); | 333 | rc = __get_user(data, (u8 __user *)ubuf); |
diff --git a/arch/powerpc/platforms/powernv/opal-wrappers.S b/arch/powerpc/platforms/powernv/opal-wrappers.S index e9e2450c1fdd..feb549aa3eea 100644 --- a/arch/powerpc/platforms/powernv/opal-wrappers.S +++ b/arch/powerpc/platforms/powernv/opal-wrappers.S | |||
@@ -58,7 +58,7 @@ END_FTR_SECTION(0, 1); \ | |||
58 | */ | 58 | */ |
59 | 59 | ||
60 | #define OPAL_CALL(name, token) \ | 60 | #define OPAL_CALL(name, token) \ |
61 | _GLOBAL(name); \ | 61 | _GLOBAL_TOC(name); \ |
62 | mflr r0; \ | 62 | mflr r0; \ |
63 | std r0,16(r1); \ | 63 | std r0,16(r1); \ |
64 | li r0,token; \ | 64 | li r0,token; \ |
diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c index b642b0562f5a..d019b081df9d 100644 --- a/arch/powerpc/platforms/powernv/opal.c +++ b/arch/powerpc/platforms/powernv/opal.c | |||
@@ -194,6 +194,27 @@ static int __init opal_register_exception_handlers(void) | |||
194 | * fwnmi area at 0x7000 to provide the glue space to OPAL | 194 | * fwnmi area at 0x7000 to provide the glue space to OPAL |
195 | */ | 195 | */ |
196 | glue = 0x7000; | 196 | glue = 0x7000; |
197 | |||
198 | /* | ||
199 | * Check if we are running on newer firmware that exports | ||
200 | * OPAL_HANDLE_HMI token. If yes, then don't ask OPAL to patch | ||
201 | * the HMI interrupt and we catch it directly in Linux. | ||
202 | * | ||
203 | * For older firmware (i.e currently released POWER8 System Firmware | ||
204 | * as of today <= SV810_087), we fallback to old behavior and let OPAL | ||
205 | * patch the HMI vector and handle it inside OPAL firmware. | ||
206 | * | ||
207 | * For newer firmware (in development/yet to be released) we will | ||
208 | * start catching/handling HMI directly in Linux. | ||
209 | */ | ||
210 | if (!opal_check_token(OPAL_HANDLE_HMI)) { | ||
211 | pr_info("opal: Old firmware detected, OPAL handles HMIs.\n"); | ||
212 | opal_register_exception_handler( | ||
213 | OPAL_HYPERVISOR_MAINTENANCE_HANDLER, | ||
214 | 0, glue); | ||
215 | glue += 128; | ||
216 | } | ||
217 | |||
197 | opal_register_exception_handler(OPAL_SOFTPATCH_HANDLER, 0, glue); | 218 | opal_register_exception_handler(OPAL_SOFTPATCH_HANDLER, 0, glue); |
198 | #endif | 219 | #endif |
199 | 220 | ||
diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c index b3ca77ddf36d..b2187d0068b8 100644 --- a/arch/powerpc/platforms/powernv/pci.c +++ b/arch/powerpc/platforms/powernv/pci.c | |||
@@ -505,7 +505,7 @@ static bool pnv_pci_cfg_check(struct pci_controller *hose, | |||
505 | edev = of_node_to_eeh_dev(dn); | 505 | edev = of_node_to_eeh_dev(dn); |
506 | if (edev) { | 506 | if (edev) { |
507 | if (edev->pe && | 507 | if (edev->pe && |
508 | (edev->pe->state & EEH_PE_RESET)) | 508 | (edev->pe->state & EEH_PE_CFG_BLOCKED)) |
509 | return false; | 509 | return false; |
510 | 510 | ||
511 | if (edev->mode & EEH_DEV_REMOVED) | 511 | if (edev->mode & EEH_DEV_REMOVED) |
diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c index fdf01b660d59..c22bb1b4beb8 100644 --- a/arch/powerpc/platforms/pseries/dlpar.c +++ b/arch/powerpc/platforms/pseries/dlpar.c | |||
@@ -25,11 +25,11 @@ | |||
25 | #include <asm/rtas.h> | 25 | #include <asm/rtas.h> |
26 | 26 | ||
27 | struct cc_workarea { | 27 | struct cc_workarea { |
28 | u32 drc_index; | 28 | __be32 drc_index; |
29 | u32 zero; | 29 | __be32 zero; |
30 | u32 name_offset; | 30 | __be32 name_offset; |
31 | u32 prop_length; | 31 | __be32 prop_length; |
32 | u32 prop_offset; | 32 | __be32 prop_offset; |
33 | }; | 33 | }; |
34 | 34 | ||
35 | void dlpar_free_cc_property(struct property *prop) | 35 | void dlpar_free_cc_property(struct property *prop) |
@@ -49,11 +49,11 @@ static struct property *dlpar_parse_cc_property(struct cc_workarea *ccwa) | |||
49 | if (!prop) | 49 | if (!prop) |
50 | return NULL; | 50 | return NULL; |
51 | 51 | ||
52 | name = (char *)ccwa + ccwa->name_offset; | 52 | name = (char *)ccwa + be32_to_cpu(ccwa->name_offset); |
53 | prop->name = kstrdup(name, GFP_KERNEL); | 53 | prop->name = kstrdup(name, GFP_KERNEL); |
54 | 54 | ||
55 | prop->length = ccwa->prop_length; | 55 | prop->length = be32_to_cpu(ccwa->prop_length); |
56 | value = (char *)ccwa + ccwa->prop_offset; | 56 | value = (char *)ccwa + be32_to_cpu(ccwa->prop_offset); |
57 | prop->value = kmemdup(value, prop->length, GFP_KERNEL); | 57 | prop->value = kmemdup(value, prop->length, GFP_KERNEL); |
58 | if (!prop->value) { | 58 | if (!prop->value) { |
59 | dlpar_free_cc_property(prop); | 59 | dlpar_free_cc_property(prop); |
@@ -79,7 +79,7 @@ static struct device_node *dlpar_parse_cc_node(struct cc_workarea *ccwa, | |||
79 | if (!dn) | 79 | if (!dn) |
80 | return NULL; | 80 | return NULL; |
81 | 81 | ||
82 | name = (char *)ccwa + ccwa->name_offset; | 82 | name = (char *)ccwa + be32_to_cpu(ccwa->name_offset); |
83 | dn->full_name = kasprintf(GFP_KERNEL, "%s/%s", path, name); | 83 | dn->full_name = kasprintf(GFP_KERNEL, "%s/%s", path, name); |
84 | if (!dn->full_name) { | 84 | if (!dn->full_name) { |
85 | kfree(dn); | 85 | kfree(dn); |
@@ -126,7 +126,7 @@ void dlpar_free_cc_nodes(struct device_node *dn) | |||
126 | #define CALL_AGAIN -2 | 126 | #define CALL_AGAIN -2 |
127 | #define ERR_CFG_USE -9003 | 127 | #define ERR_CFG_USE -9003 |
128 | 128 | ||
129 | struct device_node *dlpar_configure_connector(u32 drc_index, | 129 | struct device_node *dlpar_configure_connector(__be32 drc_index, |
130 | struct device_node *parent) | 130 | struct device_node *parent) |
131 | { | 131 | { |
132 | struct device_node *dn; | 132 | struct device_node *dn; |
@@ -382,7 +382,7 @@ static int dlpar_online_cpu(struct device_node *dn) | |||
382 | BUG_ON(get_cpu_current_state(cpu) | 382 | BUG_ON(get_cpu_current_state(cpu) |
383 | != CPU_STATE_OFFLINE); | 383 | != CPU_STATE_OFFLINE); |
384 | cpu_maps_update_done(); | 384 | cpu_maps_update_done(); |
385 | rc = cpu_up(cpu); | 385 | rc = device_online(get_cpu_device(cpu)); |
386 | if (rc) | 386 | if (rc) |
387 | goto out; | 387 | goto out; |
388 | cpu_maps_update_begin(); | 388 | cpu_maps_update_begin(); |
@@ -414,7 +414,7 @@ static ssize_t dlpar_cpu_probe(const char *buf, size_t count) | |||
414 | if (!parent) | 414 | if (!parent) |
415 | return -ENODEV; | 415 | return -ENODEV; |
416 | 416 | ||
417 | dn = dlpar_configure_connector(drc_index, parent); | 417 | dn = dlpar_configure_connector(cpu_to_be32(drc_index), parent); |
418 | if (!dn) | 418 | if (!dn) |
419 | return -EINVAL; | 419 | return -EINVAL; |
420 | 420 | ||
@@ -467,7 +467,7 @@ static int dlpar_offline_cpu(struct device_node *dn) | |||
467 | if (get_cpu_current_state(cpu) == CPU_STATE_ONLINE) { | 467 | if (get_cpu_current_state(cpu) == CPU_STATE_ONLINE) { |
468 | set_preferred_offline_state(cpu, CPU_STATE_OFFLINE); | 468 | set_preferred_offline_state(cpu, CPU_STATE_OFFLINE); |
469 | cpu_maps_update_done(); | 469 | cpu_maps_update_done(); |
470 | rc = cpu_down(cpu); | 470 | rc = device_offline(get_cpu_device(cpu)); |
471 | if (rc) | 471 | if (rc) |
472 | goto out; | 472 | goto out; |
473 | cpu_maps_update_begin(); | 473 | cpu_maps_update_begin(); |
diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c index b174fa751d26..5c375f93c669 100644 --- a/arch/powerpc/platforms/pseries/hotplug-cpu.c +++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c | |||
@@ -247,7 +247,7 @@ static int pseries_add_processor(struct device_node *np) | |||
247 | unsigned int cpu; | 247 | unsigned int cpu; |
248 | cpumask_var_t candidate_mask, tmp; | 248 | cpumask_var_t candidate_mask, tmp; |
249 | int err = -ENOSPC, len, nthreads, i; | 249 | int err = -ENOSPC, len, nthreads, i; |
250 | const u32 *intserv; | 250 | const __be32 *intserv; |
251 | 251 | ||
252 | intserv = of_get_property(np, "ibm,ppc-interrupt-server#s", &len); | 252 | intserv = of_get_property(np, "ibm,ppc-interrupt-server#s", &len); |
253 | if (!intserv) | 253 | if (!intserv) |
@@ -293,7 +293,7 @@ static int pseries_add_processor(struct device_node *np) | |||
293 | for_each_cpu(cpu, tmp) { | 293 | for_each_cpu(cpu, tmp) { |
294 | BUG_ON(cpu_present(cpu)); | 294 | BUG_ON(cpu_present(cpu)); |
295 | set_cpu_present(cpu, true); | 295 | set_cpu_present(cpu, true); |
296 | set_hard_smp_processor_id(cpu, *intserv++); | 296 | set_hard_smp_processor_id(cpu, be32_to_cpu(*intserv++)); |
297 | } | 297 | } |
298 | err = 0; | 298 | err = 0; |
299 | out_unlock: | 299 | out_unlock: |
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index de1ec54a2a57..e32e00976a94 100644 --- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c | |||
@@ -30,7 +30,6 @@ | |||
30 | #include <linux/mm.h> | 30 | #include <linux/mm.h> |
31 | #include <linux/memblock.h> | 31 | #include <linux/memblock.h> |
32 | #include <linux/spinlock.h> | 32 | #include <linux/spinlock.h> |
33 | #include <linux/sched.h> /* for show_stack */ | ||
34 | #include <linux/string.h> | 33 | #include <linux/string.h> |
35 | #include <linux/pci.h> | 34 | #include <linux/pci.h> |
36 | #include <linux/dma-mapping.h> | 35 | #include <linux/dma-mapping.h> |
@@ -168,7 +167,7 @@ static int tce_build_pSeriesLP(struct iommu_table *tbl, long tcenum, | |||
168 | printk("\tindex = 0x%llx\n", (u64)tbl->it_index); | 167 | printk("\tindex = 0x%llx\n", (u64)tbl->it_index); |
169 | printk("\ttcenum = 0x%llx\n", (u64)tcenum); | 168 | printk("\ttcenum = 0x%llx\n", (u64)tcenum); |
170 | printk("\ttce val = 0x%llx\n", tce ); | 169 | printk("\ttce val = 0x%llx\n", tce ); |
171 | show_stack(current, (unsigned long *)__get_SP()); | 170 | dump_stack(); |
172 | } | 171 | } |
173 | 172 | ||
174 | tcenum++; | 173 | tcenum++; |
@@ -257,7 +256,7 @@ static int tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum, | |||
257 | printk("\tindex = 0x%llx\n", (u64)tbl->it_index); | 256 | printk("\tindex = 0x%llx\n", (u64)tbl->it_index); |
258 | printk("\tnpages = 0x%llx\n", (u64)npages); | 257 | printk("\tnpages = 0x%llx\n", (u64)npages); |
259 | printk("\ttce[0] val = 0x%llx\n", tcep[0]); | 258 | printk("\ttce[0] val = 0x%llx\n", tcep[0]); |
260 | show_stack(current, (unsigned long *)__get_SP()); | 259 | dump_stack(); |
261 | } | 260 | } |
262 | return ret; | 261 | return ret; |
263 | } | 262 | } |
@@ -273,7 +272,7 @@ static void tce_free_pSeriesLP(struct iommu_table *tbl, long tcenum, long npages | |||
273 | printk("tce_free_pSeriesLP: plpar_tce_put failed. rc=%lld\n", rc); | 272 | printk("tce_free_pSeriesLP: plpar_tce_put failed. rc=%lld\n", rc); |
274 | printk("\tindex = 0x%llx\n", (u64)tbl->it_index); | 273 | printk("\tindex = 0x%llx\n", (u64)tbl->it_index); |
275 | printk("\ttcenum = 0x%llx\n", (u64)tcenum); | 274 | printk("\ttcenum = 0x%llx\n", (u64)tcenum); |
276 | show_stack(current, (unsigned long *)__get_SP()); | 275 | dump_stack(); |
277 | } | 276 | } |
278 | 277 | ||
279 | tcenum++; | 278 | tcenum++; |
@@ -292,7 +291,7 @@ static void tce_freemulti_pSeriesLP(struct iommu_table *tbl, long tcenum, long n | |||
292 | printk("\trc = %lld\n", rc); | 291 | printk("\trc = %lld\n", rc); |
293 | printk("\tindex = 0x%llx\n", (u64)tbl->it_index); | 292 | printk("\tindex = 0x%llx\n", (u64)tbl->it_index); |
294 | printk("\tnpages = 0x%llx\n", (u64)npages); | 293 | printk("\tnpages = 0x%llx\n", (u64)npages); |
295 | show_stack(current, (unsigned long *)__get_SP()); | 294 | dump_stack(); |
296 | } | 295 | } |
297 | } | 296 | } |
298 | 297 | ||
@@ -307,7 +306,7 @@ static unsigned long tce_get_pSeriesLP(struct iommu_table *tbl, long tcenum) | |||
307 | printk("tce_get_pSeriesLP: plpar_tce_get failed. rc=%lld\n", rc); | 306 | printk("tce_get_pSeriesLP: plpar_tce_get failed. rc=%lld\n", rc); |
308 | printk("\tindex = 0x%llx\n", (u64)tbl->it_index); | 307 | printk("\tindex = 0x%llx\n", (u64)tbl->it_index); |
309 | printk("\ttcenum = 0x%llx\n", (u64)tcenum); | 308 | printk("\ttcenum = 0x%llx\n", (u64)tcenum); |
310 | show_stack(current, (unsigned long *)__get_SP()); | 309 | dump_stack(); |
311 | } | 310 | } |
312 | 311 | ||
313 | return tce_ret; | 312 | return tce_ret; |
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c index 8c509d5397c6..f6880d2a40fb 100644 --- a/arch/powerpc/platforms/pseries/lpar.c +++ b/arch/powerpc/platforms/pseries/lpar.c | |||
@@ -43,6 +43,7 @@ | |||
43 | #include <asm/trace.h> | 43 | #include <asm/trace.h> |
44 | #include <asm/firmware.h> | 44 | #include <asm/firmware.h> |
45 | #include <asm/plpar_wrappers.h> | 45 | #include <asm/plpar_wrappers.h> |
46 | #include <asm/fadump.h> | ||
46 | 47 | ||
47 | #include "pseries.h" | 48 | #include "pseries.h" |
48 | 49 | ||
@@ -247,8 +248,17 @@ static void pSeries_lpar_hptab_clear(void) | |||
247 | } | 248 | } |
248 | 249 | ||
249 | #ifdef __LITTLE_ENDIAN__ | 250 | #ifdef __LITTLE_ENDIAN__ |
250 | /* Reset exceptions to big endian */ | 251 | /* |
251 | if (firmware_has_feature(FW_FEATURE_SET_MODE)) { | 252 | * Reset exceptions to big endian. |
253 | * | ||
254 | * FIXME this is a hack for kexec, we need to reset the exception | ||
255 | * endian before starting the new kernel and this is a convenient place | ||
256 | * to do it. | ||
257 | * | ||
258 | * This is also called on boot when a fadump happens. In that case we | ||
259 | * must not change the exception endian mode. | ||
260 | */ | ||
261 | if (firmware_has_feature(FW_FEATURE_SET_MODE) && !is_fadump_active()) { | ||
252 | long rc; | 262 | long rc; |
253 | 263 | ||
254 | rc = pseries_big_endian_exceptions(); | 264 | rc = pseries_big_endian_exceptions(); |
diff --git a/arch/powerpc/platforms/pseries/pseries.h b/arch/powerpc/platforms/pseries/pseries.h index 361add62abf1..1796c5438cc6 100644 --- a/arch/powerpc/platforms/pseries/pseries.h +++ b/arch/powerpc/platforms/pseries/pseries.h | |||
@@ -56,7 +56,8 @@ extern void hvc_vio_init_early(void); | |||
56 | /* Dynamic logical Partitioning/Mobility */ | 56 | /* Dynamic logical Partitioning/Mobility */ |
57 | extern void dlpar_free_cc_nodes(struct device_node *); | 57 | extern void dlpar_free_cc_nodes(struct device_node *); |
58 | extern void dlpar_free_cc_property(struct property *); | 58 | extern void dlpar_free_cc_property(struct property *); |
59 | extern struct device_node *dlpar_configure_connector(u32, struct device_node *); | 59 | extern struct device_node *dlpar_configure_connector(__be32, |
60 | struct device_node *); | ||
60 | extern int dlpar_attach_node(struct device_node *); | 61 | extern int dlpar_attach_node(struct device_node *); |
61 | extern int dlpar_detach_node(struct device_node *); | 62 | extern int dlpar_detach_node(struct device_node *); |
62 | 63 | ||