diff options
| -rw-r--r-- | arch/powerpc/include/asm/eeh.h | 11 | ||||
| -rw-r--r-- | arch/powerpc/kernel/eeh.c | 63 | ||||
| -rw-r--r-- | arch/powerpc/kernel/of_platform.c | 2 | ||||
| -rw-r--r-- | arch/powerpc/kernel/pci-hotplug.c | 2 | ||||
| -rw-r--r-- | arch/powerpc/platforms/powernv/eeh-powernv.c | 146 | ||||
| -rw-r--r-- | arch/powerpc/platforms/pseries/eeh_pseries.c | 82 | ||||
| -rw-r--r-- | arch/powerpc/platforms/pseries/pci_dlpar.c | 2 | ||||
| -rw-r--r-- | drivers/pci/hotplug/rpadlpar_core.c | 2 |
8 files changed, 172 insertions, 138 deletions
diff --git a/arch/powerpc/include/asm/eeh.h b/arch/powerpc/include/asm/eeh.h index 2106f83da2d5..87797811808f 100644 --- a/arch/powerpc/include/asm/eeh.h +++ b/arch/powerpc/include/asm/eeh.h | |||
| @@ -207,8 +207,7 @@ struct eeh_ops { | |||
| 207 | char *name; | 207 | char *name; |
| 208 | int (*init)(void); | 208 | int (*init)(void); |
| 209 | int (*post_init)(void); | 209 | int (*post_init)(void); |
| 210 | void* (*of_probe)(struct device_node *dn, void *flag); | 210 | void* (*probe)(struct pci_dn *pdn, void *data); |
| 211 | int (*dev_probe)(struct pci_dev *dev, void *flag); | ||
| 212 | int (*set_option)(struct eeh_pe *pe, int option); | 211 | int (*set_option)(struct eeh_pe *pe, int option); |
| 213 | int (*get_pe_addr)(struct eeh_pe *pe); | 212 | int (*get_pe_addr)(struct eeh_pe *pe); |
| 214 | int (*get_state)(struct eeh_pe *pe, int *state); | 213 | int (*get_state)(struct eeh_pe *pe, int *state); |
| @@ -287,8 +286,8 @@ int __exit eeh_ops_unregister(const char *name); | |||
| 287 | int eeh_check_failure(const volatile void __iomem *token); | 286 | int eeh_check_failure(const volatile void __iomem *token); |
| 288 | int eeh_dev_check_failure(struct eeh_dev *edev); | 287 | int eeh_dev_check_failure(struct eeh_dev *edev); |
| 289 | void eeh_addr_cache_build(void); | 288 | void eeh_addr_cache_build(void); |
| 290 | void eeh_add_device_early(struct device_node *); | 289 | void eeh_add_device_early(struct pci_dn *); |
| 291 | void eeh_add_device_tree_early(struct device_node *); | 290 | void eeh_add_device_tree_early(struct pci_dn *); |
| 292 | void eeh_add_device_late(struct pci_dev *); | 291 | void eeh_add_device_late(struct pci_dev *); |
| 293 | void eeh_add_device_tree_late(struct pci_bus *); | 292 | void eeh_add_device_tree_late(struct pci_bus *); |
| 294 | void eeh_add_sysfs_files(struct pci_bus *); | 293 | void eeh_add_sysfs_files(struct pci_bus *); |
| @@ -346,9 +345,9 @@ static inline int eeh_check_failure(const volatile void __iomem *token) | |||
| 346 | 345 | ||
| 347 | static inline void eeh_addr_cache_build(void) { } | 346 | static inline void eeh_addr_cache_build(void) { } |
| 348 | 347 | ||
| 349 | static inline void eeh_add_device_early(struct device_node *dn) { } | 348 | static inline void eeh_add_device_early(struct pci_dn *pdn) { } |
| 350 | 349 | ||
| 351 | static inline void eeh_add_device_tree_early(struct device_node *dn) { } | 350 | static inline void eeh_add_device_tree_early(struct pci_dn *pdn) { } |
| 352 | 351 | ||
| 353 | static inline void eeh_add_device_late(struct pci_dev *dev) { } | 352 | static inline void eeh_add_device_late(struct pci_dev *dev) { } |
| 354 | 353 | ||
diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c index 19a897c810be..9504c2f0bb54 100644 --- a/arch/powerpc/kernel/eeh.c +++ b/arch/powerpc/kernel/eeh.c | |||
| @@ -969,7 +969,7 @@ static struct notifier_block eeh_reboot_nb = { | |||
| 969 | int eeh_init(void) | 969 | int eeh_init(void) |
| 970 | { | 970 | { |
| 971 | struct pci_controller *hose, *tmp; | 971 | struct pci_controller *hose, *tmp; |
| 972 | struct device_node *phb; | 972 | struct pci_dn *pdn; |
| 973 | static int cnt = 0; | 973 | static int cnt = 0; |
| 974 | int ret = 0; | 974 | int ret = 0; |
| 975 | 975 | ||
| @@ -1004,20 +1004,9 @@ int eeh_init(void) | |||
| 1004 | return ret; | 1004 | return ret; |
| 1005 | 1005 | ||
| 1006 | /* Enable EEH for all adapters */ | 1006 | /* Enable EEH for all adapters */ |
| 1007 | if (eeh_has_flag(EEH_PROBE_MODE_DEVTREE)) { | 1007 | list_for_each_entry_safe(hose, tmp, &hose_list, list_node) { |
| 1008 | list_for_each_entry_safe(hose, tmp, | 1008 | pdn = hose->pci_data; |
| 1009 | &hose_list, list_node) { | 1009 | traverse_pci_dn(pdn, eeh_ops->probe, NULL); |
| 1010 | phb = hose->dn; | ||
| 1011 | traverse_pci_devices(phb, eeh_ops->of_probe, NULL); | ||
| 1012 | } | ||
| 1013 | } else if (eeh_has_flag(EEH_PROBE_MODE_DEV)) { | ||
| 1014 | list_for_each_entry_safe(hose, tmp, | ||
| 1015 | &hose_list, list_node) | ||
| 1016 | pci_walk_bus(hose->bus, eeh_ops->dev_probe, NULL); | ||
| 1017 | } else { | ||
| 1018 | pr_warn("%s: Invalid probe mode %x", | ||
| 1019 | __func__, eeh_subsystem_flags); | ||
| 1020 | return -EINVAL; | ||
| 1021 | } | 1010 | } |
| 1022 | 1011 | ||
| 1023 | /* | 1012 | /* |
| @@ -1043,7 +1032,7 @@ core_initcall_sync(eeh_init); | |||
| 1043 | 1032 | ||
| 1044 | /** | 1033 | /** |
| 1045 | * eeh_add_device_early - Enable EEH for the indicated device_node | 1034 | * eeh_add_device_early - Enable EEH for the indicated device_node |
| 1046 | * @dn: device node for which to set up EEH | 1035 | * @pdn: PCI device node for which to set up EEH |
| 1047 | * | 1036 | * |
| 1048 | * This routine must be used to perform EEH initialization for PCI | 1037 | * This routine must be used to perform EEH initialization for PCI |
| 1049 | * devices that were added after system boot (e.g. hotplug, dlpar). | 1038 | * devices that were added after system boot (e.g. hotplug, dlpar). |
| @@ -1053,44 +1042,41 @@ core_initcall_sync(eeh_init); | |||
| 1053 | * on the CEC architecture, type of the device, on earlier boot | 1042 | * on the CEC architecture, type of the device, on earlier boot |
| 1054 | * command-line arguments & etc. | 1043 | * command-line arguments & etc. |
| 1055 | */ | 1044 | */ |
| 1056 | void eeh_add_device_early(struct device_node *dn) | 1045 | void eeh_add_device_early(struct pci_dn *pdn) |
| 1057 | { | 1046 | { |
| 1058 | struct pci_controller *phb; | 1047 | struct pci_controller *phb; |
| 1048 | struct eeh_dev *edev = pdn_to_eeh_dev(pdn); | ||
| 1059 | 1049 | ||
| 1060 | /* | 1050 | if (!edev) |
| 1061 | * If we're doing EEH probe based on PCI device, we | ||
| 1062 | * would delay the probe until late stage because | ||
| 1063 | * the PCI device isn't available this moment. | ||
| 1064 | */ | ||
| 1065 | if (!eeh_has_flag(EEH_PROBE_MODE_DEVTREE)) | ||
| 1066 | return; | ||
| 1067 | |||
| 1068 | if (!of_node_to_eeh_dev(dn)) | ||
| 1069 | return; | 1051 | return; |
| 1070 | phb = of_node_to_eeh_dev(dn)->phb; | ||
| 1071 | 1052 | ||
| 1072 | /* USB Bus children of PCI devices will not have BUID's */ | 1053 | /* USB Bus children of PCI devices will not have BUID's */ |
| 1073 | if (NULL == phb || 0 == phb->buid) | 1054 | phb = edev->phb; |
| 1055 | if (NULL == phb || | ||
| 1056 | (eeh_has_flag(EEH_PROBE_MODE_DEVTREE) && 0 == phb->buid)) | ||
| 1074 | return; | 1057 | return; |
| 1075 | 1058 | ||
| 1076 | eeh_ops->of_probe(dn, NULL); | 1059 | eeh_ops->probe(pdn, NULL); |
| 1077 | } | 1060 | } |
| 1078 | 1061 | ||
| 1079 | /** | 1062 | /** |
| 1080 | * eeh_add_device_tree_early - Enable EEH for the indicated device | 1063 | * eeh_add_device_tree_early - Enable EEH for the indicated device |
| 1081 | * @dn: device node | 1064 | * @pdn: PCI device node |
| 1082 | * | 1065 | * |
| 1083 | * This routine must be used to perform EEH initialization for the | 1066 | * This routine must be used to perform EEH initialization for the |
| 1084 | * indicated PCI device that was added after system boot (e.g. | 1067 | * indicated PCI device that was added after system boot (e.g. |
| 1085 | * hotplug, dlpar). | 1068 | * hotplug, dlpar). |
| 1086 | */ | 1069 | */ |
| 1087 | void eeh_add_device_tree_early(struct device_node *dn) | 1070 | void eeh_add_device_tree_early(struct pci_dn *pdn) |
| 1088 | { | 1071 | { |
| 1089 | struct device_node *sib; | 1072 | struct pci_dn *n; |
| 1073 | |||
| 1074 | if (!pdn) | ||
| 1075 | return; | ||
| 1090 | 1076 | ||
| 1091 | for_each_child_of_node(dn, sib) | 1077 | list_for_each_entry(n, &pdn->child_list, list) |
| 1092 | eeh_add_device_tree_early(sib); | 1078 | eeh_add_device_tree_early(n); |
| 1093 | eeh_add_device_early(dn); | 1079 | eeh_add_device_early(pdn); |
| 1094 | } | 1080 | } |
| 1095 | EXPORT_SYMBOL_GPL(eeh_add_device_tree_early); | 1081 | EXPORT_SYMBOL_GPL(eeh_add_device_tree_early); |
| 1096 | 1082 | ||
| @@ -1144,13 +1130,6 @@ void eeh_add_device_late(struct pci_dev *dev) | |||
| 1144 | edev->pdev = dev; | 1130 | edev->pdev = dev; |
| 1145 | dev->dev.archdata.edev = edev; | 1131 | dev->dev.archdata.edev = edev; |
| 1146 | 1132 | ||
| 1147 | /* | ||
| 1148 | * We have to do the EEH probe here because the PCI device | ||
| 1149 | * hasn't been created yet in the early stage. | ||
| 1150 | */ | ||
| 1151 | if (eeh_has_flag(EEH_PROBE_MODE_DEV)) | ||
| 1152 | eeh_ops->dev_probe(dev, NULL); | ||
| 1153 | |||
| 1154 | eeh_addr_cache_insert_dev(dev); | 1133 | eeh_addr_cache_insert_dev(dev); |
| 1155 | } | 1134 | } |
| 1156 | 1135 | ||
diff --git a/arch/powerpc/kernel/of_platform.c b/arch/powerpc/kernel/of_platform.c index 2f35a72642c6..b60a67d92ebd 100644 --- a/arch/powerpc/kernel/of_platform.c +++ b/arch/powerpc/kernel/of_platform.c | |||
| @@ -72,7 +72,7 @@ static int of_pci_phb_probe(struct platform_device *dev) | |||
| 72 | 72 | ||
| 73 | /* Register devices with EEH */ | 73 | /* Register devices with EEH */ |
| 74 | if (dev->dev.of_node->child) | 74 | if (dev->dev.of_node->child) |
| 75 | eeh_add_device_tree_early(dev->dev.of_node); | 75 | eeh_add_device_tree_early(PCI_DN(dev->dev.of_node)); |
| 76 | 76 | ||
| 77 | /* Scan the bus */ | 77 | /* Scan the bus */ |
| 78 | pcibios_scan_phb(phb); | 78 | pcibios_scan_phb(phb); |
diff --git a/arch/powerpc/kernel/pci-hotplug.c b/arch/powerpc/kernel/pci-hotplug.c index 5b789177aa29..18d9575729a3 100644 --- a/arch/powerpc/kernel/pci-hotplug.c +++ b/arch/powerpc/kernel/pci-hotplug.c | |||
| @@ -75,7 +75,7 @@ void pcibios_add_pci_devices(struct pci_bus * bus) | |||
| 75 | struct pci_dev *dev; | 75 | struct pci_dev *dev; |
| 76 | struct device_node *dn = pci_bus_to_OF_node(bus); | 76 | struct device_node *dn = pci_bus_to_OF_node(bus); |
| 77 | 77 | ||
| 78 | eeh_add_device_tree_early(dn); | 78 | eeh_add_device_tree_early(PCI_DN(dn)); |
| 79 | 79 | ||
| 80 | mode = PCI_PROBE_NORMAL; | 80 | mode = PCI_PROBE_NORMAL; |
| 81 | if (ppc_md.pci_probe_mode) | 81 | if (ppc_md.pci_probe_mode) |
diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c b/arch/powerpc/platforms/powernv/eeh-powernv.c index 8eac8c57ee86..dcc524fe2a30 100644 --- a/arch/powerpc/platforms/powernv/eeh-powernv.c +++ b/arch/powerpc/platforms/powernv/eeh-powernv.c | |||
| @@ -286,10 +286,82 @@ static int pnv_eeh_post_init(void) | |||
| 286 | return ret; | 286 | return ret; |
| 287 | } | 287 | } |
| 288 | 288 | ||
| 289 | static int pnv_eeh_cap_start(struct pci_dn *pdn) | ||
| 290 | { | ||
| 291 | u32 status; | ||
| 292 | |||
| 293 | if (!pdn) | ||
| 294 | return 0; | ||
| 295 | |||
| 296 | pnv_pci_cfg_read(pdn, PCI_STATUS, 2, &status); | ||
| 297 | if (!(status & PCI_STATUS_CAP_LIST)) | ||
| 298 | return 0; | ||
| 299 | |||
| 300 | return PCI_CAPABILITY_LIST; | ||
| 301 | } | ||
| 302 | |||
| 303 | static int pnv_eeh_find_cap(struct pci_dn *pdn, int cap) | ||
| 304 | { | ||
| 305 | int pos = pnv_eeh_cap_start(pdn); | ||
| 306 | int cnt = 48; /* Maximal number of capabilities */ | ||
| 307 | u32 id; | ||
| 308 | |||
| 309 | if (!pos) | ||
| 310 | return 0; | ||
| 311 | |||
| 312 | while (cnt--) { | ||
| 313 | pnv_pci_cfg_read(pdn, pos, 1, &pos); | ||
| 314 | if (pos < 0x40) | ||
| 315 | break; | ||
| 316 | |||
| 317 | pos &= ~3; | ||
| 318 | pnv_pci_cfg_read(pdn, pos + PCI_CAP_LIST_ID, 1, &id); | ||
| 319 | if (id == 0xff) | ||
| 320 | break; | ||
| 321 | |||
| 322 | /* Found */ | ||
| 323 | if (id == cap) | ||
| 324 | return pos; | ||
| 325 | |||
| 326 | /* Next one */ | ||
| 327 | pos += PCI_CAP_LIST_NEXT; | ||
| 328 | } | ||
| 329 | |||
| 330 | return 0; | ||
| 331 | } | ||
| 332 | |||
| 333 | static int pnv_eeh_find_ecap(struct pci_dn *pdn, int cap) | ||
| 334 | { | ||
| 335 | struct eeh_dev *edev = pdn_to_eeh_dev(pdn); | ||
| 336 | u32 header; | ||
| 337 | int pos = 256, ttl = (4096 - 256) / 8; | ||
| 338 | |||
| 339 | if (!edev || !edev->pcie_cap) | ||
| 340 | return 0; | ||
| 341 | if (pnv_pci_cfg_read(pdn, pos, 4, &header) != PCIBIOS_SUCCESSFUL) | ||
| 342 | return 0; | ||
| 343 | else if (!header) | ||
| 344 | return 0; | ||
| 345 | |||
| 346 | while (ttl-- > 0) { | ||
| 347 | if (PCI_EXT_CAP_ID(header) == cap && pos) | ||
| 348 | return pos; | ||
| 349 | |||
| 350 | pos = PCI_EXT_CAP_NEXT(header); | ||
| 351 | if (pos < 256) | ||
| 352 | break; | ||
| 353 | |||
| 354 | if (pnv_pci_cfg_read(pdn, pos, 4, &header) != PCIBIOS_SUCCESSFUL) | ||
| 355 | break; | ||
| 356 | } | ||
| 357 | |||
| 358 | return 0; | ||
| 359 | } | ||
| 360 | |||
| 289 | /** | 361 | /** |
| 290 | * pnv_eeh_dev_probe - Do probe on PCI device | 362 | * pnv_eeh_probe - Do probe on PCI device |
| 291 | * @dev: PCI device | 363 | * @pdn: PCI device node |
| 292 | * @flag: unused | 364 | * @data: unused |
| 293 | * | 365 | * |
| 294 | * When EEH module is installed during system boot, all PCI devices | 366 | * When EEH module is installed during system boot, all PCI devices |
| 295 | * are checked one by one to see if it supports EEH. The function | 367 | * are checked one by one to see if it supports EEH. The function |
| @@ -303,12 +375,12 @@ static int pnv_eeh_post_init(void) | |||
| 303 | * was possiblly triggered by EEH core, the binding between EEH device | 375 | * was possiblly triggered by EEH core, the binding between EEH device |
| 304 | * and the PCI device isn't built yet. | 376 | * and the PCI device isn't built yet. |
| 305 | */ | 377 | */ |
| 306 | static int pnv_eeh_dev_probe(struct pci_dev *dev, void *flag) | 378 | static void *pnv_eeh_probe(struct pci_dn *pdn, void *data) |
| 307 | { | 379 | { |
| 308 | struct pci_controller *hose = pci_bus_to_host(dev->bus); | 380 | struct pci_controller *hose = pdn->phb; |
| 309 | struct pnv_phb *phb = hose->private_data; | 381 | struct pnv_phb *phb = hose->private_data; |
| 310 | struct device_node *dn = pci_device_to_OF_node(dev); | 382 | struct eeh_dev *edev = pdn_to_eeh_dev(pdn); |
| 311 | struct eeh_dev *edev = of_node_to_eeh_dev(dn); | 383 | uint32_t pcie_flags; |
| 312 | int ret; | 384 | int ret; |
| 313 | 385 | ||
| 314 | /* | 386 | /* |
| @@ -317,40 +389,42 @@ static int pnv_eeh_dev_probe(struct pci_dev *dev, void *flag) | |||
| 317 | * the root bridge. So it's not reasonable to continue | 389 | * the root bridge. So it's not reasonable to continue |
| 318 | * the probing. | 390 | * the probing. |
| 319 | */ | 391 | */ |
| 320 | if (!dn || !edev || edev->pe) | 392 | if (!edev || edev->pe) |
| 321 | return 0; | 393 | return NULL; |
| 322 | 394 | ||
| 323 | /* Skip for PCI-ISA bridge */ | 395 | /* Skip for PCI-ISA bridge */ |
| 324 | if ((dev->class >> 8) == PCI_CLASS_BRIDGE_ISA) | 396 | if ((pdn->class_code >> 8) == PCI_CLASS_BRIDGE_ISA) |
| 325 | return 0; | 397 | return NULL; |
| 326 | 398 | ||
| 327 | /* Initialize eeh device */ | 399 | /* Initialize eeh device */ |
| 328 | edev->class_code = dev->class; | 400 | edev->class_code = pdn->class_code; |
| 329 | edev->mode &= 0xFFFFFF00; | 401 | edev->mode &= 0xFFFFFF00; |
| 330 | if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) | 402 | edev->pcix_cap = pnv_eeh_find_cap(pdn, PCI_CAP_ID_PCIX); |
| 403 | edev->pcie_cap = pnv_eeh_find_cap(pdn, PCI_CAP_ID_EXP); | ||
| 404 | edev->aer_cap = pnv_eeh_find_ecap(pdn, PCI_EXT_CAP_ID_ERR); | ||
| 405 | if ((edev->class_code >> 8) == PCI_CLASS_BRIDGE_PCI) { | ||
| 331 | edev->mode |= EEH_DEV_BRIDGE; | 406 | edev->mode |= EEH_DEV_BRIDGE; |
| 332 | edev->pcix_cap = pci_find_capability(dev, PCI_CAP_ID_PCIX); | 407 | if (edev->pcie_cap) { |
| 333 | if (pci_is_pcie(dev)) { | 408 | pnv_pci_cfg_read(pdn, edev->pcie_cap + PCI_EXP_FLAGS, |
| 334 | edev->pcie_cap = pci_pcie_cap(dev); | 409 | 2, &pcie_flags); |
| 335 | 410 | pcie_flags = (pcie_flags & PCI_EXP_FLAGS_TYPE) >> 4; | |
| 336 | if (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT) | 411 | if (pcie_flags == PCI_EXP_TYPE_ROOT_PORT) |
| 337 | edev->mode |= EEH_DEV_ROOT_PORT; | 412 | edev->mode |= EEH_DEV_ROOT_PORT; |
| 338 | else if (pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM) | 413 | else if (pcie_flags == PCI_EXP_TYPE_DOWNSTREAM) |
| 339 | edev->mode |= EEH_DEV_DS_PORT; | 414 | edev->mode |= EEH_DEV_DS_PORT; |
| 340 | 415 | } | |
| 341 | edev->aer_cap = pci_find_ext_capability(dev, | ||
| 342 | PCI_EXT_CAP_ID_ERR); | ||
| 343 | } | 416 | } |
| 344 | 417 | ||
| 345 | edev->config_addr = ((dev->bus->number << 8) | dev->devfn); | 418 | edev->config_addr = (pdn->busno << 8) | (pdn->devfn); |
| 346 | edev->pe_config_addr = phb->bdfn_to_pe(phb, dev->bus, dev->devfn & 0xff); | 419 | edev->pe_config_addr = phb->ioda.pe_rmap[edev->config_addr]; |
| 347 | 420 | ||
| 348 | /* Create PE */ | 421 | /* Create PE */ |
| 349 | ret = eeh_add_to_parent_pe(edev); | 422 | ret = eeh_add_to_parent_pe(edev); |
| 350 | if (ret) { | 423 | if (ret) { |
| 351 | pr_warn("%s: Can't add PCI dev %s to parent PE (%d)\n", | 424 | pr_warn("%s: Can't add PCI dev %04x:%02x:%02x.%01x to parent PE (%d)\n", |
| 352 | __func__, pci_name(dev), ret); | 425 | __func__, hose->global_number, pdn->busno, |
| 353 | return ret; | 426 | PCI_SLOT(pdn->devfn), PCI_FUNC(pdn->devfn), ret); |
| 427 | return NULL; | ||
| 354 | } | 428 | } |
| 355 | 429 | ||
| 356 | /* | 430 | /* |
| @@ -369,8 +443,10 @@ static int pnv_eeh_dev_probe(struct pci_dev *dev, void *flag) | |||
| 369 | * Broadcom Austin 4-ports NICs (14e4:1657) | 443 | * Broadcom Austin 4-ports NICs (14e4:1657) |
| 370 | * Broadcom Shiner 2-ports 10G NICs (14e4:168e) | 444 | * Broadcom Shiner 2-ports 10G NICs (14e4:168e) |
| 371 | */ | 445 | */ |
| 372 | if ((dev->vendor == PCI_VENDOR_ID_BROADCOM && dev->device == 0x1657) || | 446 | if ((pdn->vendor_id == PCI_VENDOR_ID_BROADCOM && |
| 373 | (dev->vendor == PCI_VENDOR_ID_BROADCOM && dev->device == 0x168e)) | 447 | pdn->device_id == 0x1657) || |
| 448 | (pdn->vendor_id == PCI_VENDOR_ID_BROADCOM && | ||
| 449 | pdn->device_id == 0x168e)) | ||
| 374 | edev->pe->state |= EEH_PE_CFG_RESTRICTED; | 450 | edev->pe->state |= EEH_PE_CFG_RESTRICTED; |
| 375 | 451 | ||
| 376 | /* | 452 | /* |
| @@ -380,7 +456,8 @@ static int pnv_eeh_dev_probe(struct pci_dev *dev, void *flag) | |||
| 380 | * to PE reset. | 456 | * to PE reset. |
| 381 | */ | 457 | */ |
| 382 | if (!edev->pe->bus) | 458 | if (!edev->pe->bus) |
| 383 | edev->pe->bus = dev->bus; | 459 | edev->pe->bus = pci_find_bus(hose->global_number, |
| 460 | pdn->busno); | ||
| 384 | 461 | ||
| 385 | /* | 462 | /* |
| 386 | * Enable EEH explicitly so that we will do EEH check | 463 | * Enable EEH explicitly so that we will do EEH check |
| @@ -391,7 +468,7 @@ static int pnv_eeh_dev_probe(struct pci_dev *dev, void *flag) | |||
| 391 | /* Save memory bars */ | 468 | /* Save memory bars */ |
| 392 | eeh_save_bars(edev); | 469 | eeh_save_bars(edev); |
| 393 | 470 | ||
| 394 | return 0; | 471 | return NULL; |
| 395 | } | 472 | } |
| 396 | 473 | ||
| 397 | /** | 474 | /** |
| @@ -1432,8 +1509,7 @@ static struct eeh_ops pnv_eeh_ops = { | |||
| 1432 | .name = "powernv", | 1509 | .name = "powernv", |
| 1433 | .init = pnv_eeh_init, | 1510 | .init = pnv_eeh_init, |
| 1434 | .post_init = pnv_eeh_post_init, | 1511 | .post_init = pnv_eeh_post_init, |
| 1435 | .of_probe = NULL, | 1512 | .probe = pnv_eeh_probe, |
| 1436 | .dev_probe = pnv_eeh_dev_probe, | ||
| 1437 | .set_option = pnv_eeh_set_option, | 1513 | .set_option = pnv_eeh_set_option, |
| 1438 | .get_pe_addr = pnv_eeh_get_pe_addr, | 1514 | .get_pe_addr = pnv_eeh_get_pe_addr, |
| 1439 | .get_state = pnv_eeh_get_state, | 1515 | .get_state = pnv_eeh_get_state, |
diff --git a/arch/powerpc/platforms/pseries/eeh_pseries.c b/arch/powerpc/platforms/pseries/eeh_pseries.c index a6c7e19f5eb3..a2946f72d5e7 100644 --- a/arch/powerpc/platforms/pseries/eeh_pseries.c +++ b/arch/powerpc/platforms/pseries/eeh_pseries.c | |||
| @@ -118,9 +118,8 @@ static int pseries_eeh_init(void) | |||
| 118 | return 0; | 118 | return 0; |
| 119 | } | 119 | } |
| 120 | 120 | ||
| 121 | static int pseries_eeh_cap_start(struct device_node *dn) | 121 | static int pseries_eeh_cap_start(struct pci_dn *pdn) |
| 122 | { | 122 | { |
| 123 | struct pci_dn *pdn = PCI_DN(dn); | ||
| 124 | u32 status; | 123 | u32 status; |
| 125 | 124 | ||
| 126 | if (!pdn) | 125 | if (!pdn) |
| @@ -134,10 +133,9 @@ static int pseries_eeh_cap_start(struct device_node *dn) | |||
| 134 | } | 133 | } |
| 135 | 134 | ||
| 136 | 135 | ||
| 137 | static int pseries_eeh_find_cap(struct device_node *dn, int cap) | 136 | static int pseries_eeh_find_cap(struct pci_dn *pdn, int cap) |
| 138 | { | 137 | { |
| 139 | struct pci_dn *pdn = PCI_DN(dn); | 138 | int pos = pseries_eeh_cap_start(pdn); |
| 140 | int pos = pseries_eeh_cap_start(dn); | ||
| 141 | int cnt = 48; /* Maximal number of capabilities */ | 139 | int cnt = 48; /* Maximal number of capabilities */ |
| 142 | u32 id; | 140 | u32 id; |
| 143 | 141 | ||
| @@ -160,10 +158,9 @@ static int pseries_eeh_find_cap(struct device_node *dn, int cap) | |||
| 160 | return 0; | 158 | return 0; |
| 161 | } | 159 | } |
| 162 | 160 | ||
| 163 | static int pseries_eeh_find_ecap(struct device_node *dn, int cap) | 161 | static int pseries_eeh_find_ecap(struct pci_dn *pdn, int cap) |
| 164 | { | 162 | { |
| 165 | struct pci_dn *pdn = PCI_DN(dn); | 163 | struct eeh_dev *edev = pdn_to_eeh_dev(pdn); |
| 166 | struct eeh_dev *edev = of_node_to_eeh_dev(dn); | ||
| 167 | u32 header; | 164 | u32 header; |
| 168 | int pos = 256; | 165 | int pos = 256; |
| 169 | int ttl = (4096 - 256) / 8; | 166 | int ttl = (4096 - 256) / 8; |
| @@ -191,53 +188,44 @@ static int pseries_eeh_find_ecap(struct device_node *dn, int cap) | |||
| 191 | } | 188 | } |
| 192 | 189 | ||
| 193 | /** | 190 | /** |
| 194 | * pseries_eeh_of_probe - EEH probe on the given device | 191 | * pseries_eeh_probe - EEH probe on the given device |
| 195 | * @dn: OF node | 192 | * @pdn: PCI device node |
| 196 | * @flag: Unused | 193 | * @data: Unused |
| 197 | * | 194 | * |
| 198 | * When EEH module is installed during system boot, all PCI devices | 195 | * When EEH module is installed during system boot, all PCI devices |
| 199 | * are checked one by one to see if it supports EEH. The function | 196 | * are checked one by one to see if it supports EEH. The function |
| 200 | * is introduced for the purpose. | 197 | * is introduced for the purpose. |
| 201 | */ | 198 | */ |
| 202 | static void *pseries_eeh_of_probe(struct device_node *dn, void *flag) | 199 | static void *pseries_eeh_probe(struct pci_dn *pdn, void *data) |
| 203 | { | 200 | { |
| 204 | struct eeh_dev *edev; | 201 | struct eeh_dev *edev; |
| 205 | struct eeh_pe pe; | 202 | struct eeh_pe pe; |
| 206 | struct pci_dn *pdn = PCI_DN(dn); | ||
| 207 | const __be32 *classp, *vendorp, *devicep; | ||
| 208 | u32 class_code; | ||
| 209 | const __be32 *regs; | ||
| 210 | u32 pcie_flags; | 203 | u32 pcie_flags; |
| 211 | int enable = 0; | 204 | int enable = 0; |
| 212 | int ret; | 205 | int ret; |
| 213 | 206 | ||
| 214 | /* Retrieve OF node and eeh device */ | 207 | /* Retrieve OF node and eeh device */ |
| 215 | edev = of_node_to_eeh_dev(dn); | 208 | edev = pdn_to_eeh_dev(pdn); |
| 216 | if (edev->pe || !of_device_is_available(dn)) | 209 | if (!edev || edev->pe) |
| 217 | return NULL; | 210 | return NULL; |
| 218 | 211 | ||
| 219 | /* Retrieve class/vendor/device IDs */ | 212 | /* Check class/vendor/device IDs */ |
| 220 | classp = of_get_property(dn, "class-code", NULL); | 213 | if (!pdn->vendor_id || !pdn->device_id || !pdn->class_code) |
| 221 | vendorp = of_get_property(dn, "vendor-id", NULL); | ||
| 222 | devicep = of_get_property(dn, "device-id", NULL); | ||
| 223 | |||
| 224 | /* Skip for bad OF node or PCI-ISA bridge */ | ||
| 225 | if (!classp || !vendorp || !devicep) | ||
| 226 | return NULL; | ||
| 227 | if (dn->type && !strcmp(dn->type, "isa")) | ||
| 228 | return NULL; | 214 | return NULL; |
| 229 | 215 | ||
| 230 | class_code = of_read_number(classp, 1); | 216 | /* Skip for PCI-ISA bridge */ |
| 217 | if ((pdn->class_code >> 8) == PCI_CLASS_BRIDGE_ISA) | ||
| 218 | return NULL; | ||
| 231 | 219 | ||
| 232 | /* | 220 | /* |
| 233 | * Update class code and mode of eeh device. We need | 221 | * Update class code and mode of eeh device. We need |
| 234 | * correctly reflects that current device is root port | 222 | * correctly reflects that current device is root port |
| 235 | * or PCIe switch downstream port. | 223 | * or PCIe switch downstream port. |
| 236 | */ | 224 | */ |
| 237 | edev->class_code = class_code; | 225 | edev->class_code = pdn->class_code; |
| 238 | edev->pcix_cap = pseries_eeh_find_cap(dn, PCI_CAP_ID_PCIX); | 226 | edev->pcix_cap = pseries_eeh_find_cap(pdn, PCI_CAP_ID_PCIX); |
| 239 | edev->pcie_cap = pseries_eeh_find_cap(dn, PCI_CAP_ID_EXP); | 227 | edev->pcie_cap = pseries_eeh_find_cap(pdn, PCI_CAP_ID_EXP); |
| 240 | edev->aer_cap = pseries_eeh_find_ecap(dn, PCI_EXT_CAP_ID_ERR); | 228 | edev->aer_cap = pseries_eeh_find_ecap(pdn, PCI_EXT_CAP_ID_ERR); |
| 241 | edev->mode &= 0xFFFFFF00; | 229 | edev->mode &= 0xFFFFFF00; |
| 242 | if ((edev->class_code >> 8) == PCI_CLASS_BRIDGE_PCI) { | 230 | if ((edev->class_code >> 8) == PCI_CLASS_BRIDGE_PCI) { |
| 243 | edev->mode |= EEH_DEV_BRIDGE; | 231 | edev->mode |= EEH_DEV_BRIDGE; |
| @@ -252,24 +240,16 @@ static void *pseries_eeh_of_probe(struct device_node *dn, void *flag) | |||
| 252 | } | 240 | } |
| 253 | } | 241 | } |
| 254 | 242 | ||
| 255 | /* Retrieve the device address */ | ||
| 256 | regs = of_get_property(dn, "reg", NULL); | ||
| 257 | if (!regs) { | ||
| 258 | pr_warn("%s: OF node property %s::reg not found\n", | ||
| 259 | __func__, dn->full_name); | ||
| 260 | return NULL; | ||
| 261 | } | ||
| 262 | |||
| 263 | /* Initialize the fake PE */ | 243 | /* Initialize the fake PE */ |
| 264 | memset(&pe, 0, sizeof(struct eeh_pe)); | 244 | memset(&pe, 0, sizeof(struct eeh_pe)); |
| 265 | pe.phb = edev->phb; | 245 | pe.phb = edev->phb; |
| 266 | pe.config_addr = of_read_number(regs, 1); | 246 | pe.config_addr = (pdn->busno << 16) | (pdn->devfn << 8); |
| 267 | 247 | ||
| 268 | /* Enable EEH on the device */ | 248 | /* Enable EEH on the device */ |
| 269 | ret = eeh_ops->set_option(&pe, EEH_OPT_ENABLE); | 249 | ret = eeh_ops->set_option(&pe, EEH_OPT_ENABLE); |
| 270 | if (!ret) { | 250 | if (!ret) { |
| 271 | edev->config_addr = of_read_number(regs, 1); | ||
| 272 | /* Retrieve PE address */ | 251 | /* Retrieve PE address */ |
| 252 | edev->config_addr = (pdn->busno << 16) | (pdn->devfn << 8); | ||
| 273 | edev->pe_config_addr = eeh_ops->get_pe_addr(&pe); | 253 | edev->pe_config_addr = eeh_ops->get_pe_addr(&pe); |
| 274 | pe.addr = edev->pe_config_addr; | 254 | pe.addr = edev->pe_config_addr; |
| 275 | 255 | ||
| @@ -285,16 +265,17 @@ static void *pseries_eeh_of_probe(struct device_node *dn, void *flag) | |||
| 285 | eeh_add_flag(EEH_ENABLED); | 265 | eeh_add_flag(EEH_ENABLED); |
| 286 | eeh_add_to_parent_pe(edev); | 266 | eeh_add_to_parent_pe(edev); |
| 287 | 267 | ||
| 288 | pr_debug("%s: EEH enabled on %s PHB#%d-PE#%x, config addr#%x\n", | 268 | pr_debug("%s: EEH enabled on %02x:%02x.%01x PHB#%d-PE#%x\n", |
| 289 | __func__, dn->full_name, pe.phb->global_number, | 269 | __func__, pdn->busno, PCI_SLOT(pdn->devfn), |
| 290 | pe.addr, pe.config_addr); | 270 | PCI_FUNC(pdn->devfn), pe.phb->global_number, |
| 291 | } else if (dn->parent && of_node_to_eeh_dev(dn->parent) && | 271 | pe.addr); |
| 292 | (of_node_to_eeh_dev(dn->parent))->pe) { | 272 | } else if (pdn->parent && pdn_to_eeh_dev(pdn->parent) && |
| 273 | (pdn_to_eeh_dev(pdn->parent))->pe) { | ||
| 293 | /* This device doesn't support EEH, but it may have an | 274 | /* This device doesn't support EEH, but it may have an |
| 294 | * EEH parent, in which case we mark it as supported. | 275 | * EEH parent, in which case we mark it as supported. |
| 295 | */ | 276 | */ |
| 296 | edev->config_addr = of_node_to_eeh_dev(dn->parent)->config_addr; | 277 | edev->config_addr = pdn_to_eeh_dev(pdn->parent)->config_addr; |
| 297 | edev->pe_config_addr = of_node_to_eeh_dev(dn->parent)->pe_config_addr; | 278 | edev->pe_config_addr = pdn_to_eeh_dev(pdn->parent)->pe_config_addr; |
| 298 | eeh_add_to_parent_pe(edev); | 279 | eeh_add_to_parent_pe(edev); |
| 299 | } | 280 | } |
| 300 | } | 281 | } |
| @@ -707,8 +688,7 @@ static int pseries_eeh_write_config(struct device_node *dn, int where, int size, | |||
| 707 | static struct eeh_ops pseries_eeh_ops = { | 688 | static struct eeh_ops pseries_eeh_ops = { |
| 708 | .name = "pseries", | 689 | .name = "pseries", |
| 709 | .init = pseries_eeh_init, | 690 | .init = pseries_eeh_init, |
| 710 | .of_probe = pseries_eeh_of_probe, | 691 | .probe = pseries_eeh_probe, |
| 711 | .dev_probe = NULL, | ||
| 712 | .set_option = pseries_eeh_set_option, | 692 | .set_option = pseries_eeh_set_option, |
| 713 | .get_pe_addr = pseries_eeh_get_pe_addr, | 693 | .get_pe_addr = pseries_eeh_get_pe_addr, |
| 714 | .get_state = pseries_eeh_get_state, | 694 | .get_state = pseries_eeh_get_state, |
diff --git a/arch/powerpc/platforms/pseries/pci_dlpar.c b/arch/powerpc/platforms/pseries/pci_dlpar.c index 89e23811199c..f735f4fee48c 100644 --- a/arch/powerpc/platforms/pseries/pci_dlpar.c +++ b/arch/powerpc/platforms/pseries/pci_dlpar.c | |||
| @@ -82,7 +82,7 @@ struct pci_controller *init_phb_dynamic(struct device_node *dn) | |||
| 82 | eeh_dev_phb_init_dynamic(phb); | 82 | eeh_dev_phb_init_dynamic(phb); |
| 83 | 83 | ||
| 84 | if (dn->child) | 84 | if (dn->child) |
| 85 | eeh_add_device_tree_early(dn); | 85 | eeh_add_device_tree_early(PCI_DN(dn)); |
| 86 | 86 | ||
| 87 | pcibios_scan_phb(phb); | 87 | pcibios_scan_phb(phb); |
| 88 | pcibios_finish_adding_to_bus(phb->bus); | 88 | pcibios_finish_adding_to_bus(phb->bus); |
diff --git a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c index 7660232ef460..e12bafdc42e0 100644 --- a/drivers/pci/hotplug/rpadlpar_core.c +++ b/drivers/pci/hotplug/rpadlpar_core.c | |||
| @@ -146,7 +146,7 @@ static void dlpar_pci_add_bus(struct device_node *dn) | |||
| 146 | struct pci_controller *phb = pdn->phb; | 146 | struct pci_controller *phb = pdn->phb; |
| 147 | struct pci_dev *dev = NULL; | 147 | struct pci_dev *dev = NULL; |
| 148 | 148 | ||
| 149 | eeh_add_device_tree_early(dn); | 149 | eeh_add_device_tree_early(pdn); |
| 150 | 150 | ||
| 151 | /* Add EADS device to PHB bus, adding new entry to bus->devices */ | 151 | /* Add EADS device to PHB bus, adding new entry to bus->devices */ |
| 152 | dev = of_create_pci_dev(dn, phb->bus, pdn->devfn); | 152 | dev = of_create_pci_dev(dn, phb->bus, pdn->devfn); |
