aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/platforms')
-rw-r--r--arch/powerpc/platforms/powernv/eeh-ioda.c2
-rw-r--r--arch/powerpc/platforms/powernv/eeh-powernv.c57
-rw-r--r--arch/powerpc/platforms/powernv/opal.c21
-rw-r--r--arch/powerpc/platforms/powernv/pci.c2
-rw-r--r--arch/powerpc/platforms/pseries/dlpar.c22
-rw-r--r--arch/powerpc/platforms/pseries/hotplug-cpu.c4
-rw-r--r--arch/powerpc/platforms/pseries/iommu.c11
-rw-r--r--arch/powerpc/platforms/pseries/pseries.h3
8 files changed, 98 insertions, 24 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
406static 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
419static 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
430static 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.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..6ad83bd11fe2 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
27struct cc_workarea { 27struct 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
35void dlpar_free_cc_property(struct property *prop) 35void 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
129struct device_node *dlpar_configure_connector(u32 drc_index, 129struct 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;
@@ -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
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;
299out_unlock: 299out_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/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 */
57extern void dlpar_free_cc_nodes(struct device_node *); 57extern void dlpar_free_cc_nodes(struct device_node *);
58extern void dlpar_free_cc_property(struct property *); 58extern void dlpar_free_cc_property(struct property *);
59extern struct device_node *dlpar_configure_connector(u32, struct device_node *); 59extern struct device_node *dlpar_configure_connector(__be32,
60 struct device_node *);
60extern int dlpar_attach_node(struct device_node *); 61extern int dlpar_attach_node(struct device_node *);
61extern int dlpar_detach_node(struct device_node *); 62extern int dlpar_detach_node(struct device_node *);
62 63