aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/kernel/eeh_driver.c19
1 files changed, 16 insertions, 3 deletions
diff --git a/arch/powerpc/kernel/eeh_driver.c b/arch/powerpc/kernel/eeh_driver.c
index 36bed5a12750..c17f90d0f73c 100644
--- a/arch/powerpc/kernel/eeh_driver.c
+++ b/arch/powerpc/kernel/eeh_driver.c
@@ -369,7 +369,9 @@ static void *eeh_rmv_device(void *data, void *userdata)
369 edev->mode |= EEH_DEV_DISCONNECTED; 369 edev->mode |= EEH_DEV_DISCONNECTED;
370 (*removed)++; 370 (*removed)++;
371 371
372 pci_lock_rescan_remove();
372 pci_stop_and_remove_bus_device(dev); 373 pci_stop_and_remove_bus_device(dev);
374 pci_unlock_rescan_remove();
373 375
374 return NULL; 376 return NULL;
375} 377}
@@ -416,10 +418,13 @@ static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus)
416 * into pcibios_add_pci_devices(). 418 * into pcibios_add_pci_devices().
417 */ 419 */
418 eeh_pe_state_mark(pe, EEH_PE_KEEP); 420 eeh_pe_state_mark(pe, EEH_PE_KEEP);
419 if (bus) 421 if (bus) {
422 pci_lock_rescan_remove();
420 pcibios_remove_pci_devices(bus); 423 pcibios_remove_pci_devices(bus);
421 else if (frozen_bus) 424 pci_unlock_rescan_remove();
425 } else if (frozen_bus) {
422 eeh_pe_dev_traverse(pe, eeh_rmv_device, &removed); 426 eeh_pe_dev_traverse(pe, eeh_rmv_device, &removed);
427 }
423 428
424 /* Reset the pci controller. (Asserts RST#; resets config space). 429 /* Reset the pci controller. (Asserts RST#; resets config space).
425 * Reconfigure bridges and devices. Don't try to bring the system 430 * Reconfigure bridges and devices. Don't try to bring the system
@@ -429,6 +434,8 @@ static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus)
429 if (rc) 434 if (rc)
430 return rc; 435 return rc;
431 436
437 pci_lock_rescan_remove();
438
432 /* Restore PE */ 439 /* Restore PE */
433 eeh_ops->configure_bridge(pe); 440 eeh_ops->configure_bridge(pe);
434 eeh_pe_restore_bars(pe); 441 eeh_pe_restore_bars(pe);
@@ -462,6 +469,7 @@ static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus)
462 pe->tstamp = tstamp; 469 pe->tstamp = tstamp;
463 pe->freeze_count = cnt; 470 pe->freeze_count = cnt;
464 471
472 pci_unlock_rescan_remove();
465 return 0; 473 return 0;
466} 474}
467 475
@@ -618,8 +626,11 @@ perm_error:
618 eeh_pe_dev_traverse(pe, eeh_report_failure, NULL); 626 eeh_pe_dev_traverse(pe, eeh_report_failure, NULL);
619 627
620 /* Shut down the device drivers for good. */ 628 /* Shut down the device drivers for good. */
621 if (frozen_bus) 629 if (frozen_bus) {
630 pci_lock_rescan_remove();
622 pcibios_remove_pci_devices(frozen_bus); 631 pcibios_remove_pci_devices(frozen_bus);
632 pci_unlock_rescan_remove();
633 }
623} 634}
624 635
625static void eeh_handle_special_event(void) 636static void eeh_handle_special_event(void)
@@ -692,6 +703,7 @@ static void eeh_handle_special_event(void)
692 if (rc == 2 || rc == 1) 703 if (rc == 2 || rc == 1)
693 eeh_handle_normal_event(pe); 704 eeh_handle_normal_event(pe);
694 else { 705 else {
706 pci_lock_rescan_remove();
695 list_for_each_entry_safe(hose, tmp, 707 list_for_each_entry_safe(hose, tmp,
696 &hose_list, list_node) { 708 &hose_list, list_node) {
697 phb_pe = eeh_phb_pe_get(hose); 709 phb_pe = eeh_phb_pe_get(hose);
@@ -703,6 +715,7 @@ static void eeh_handle_special_event(void)
703 eeh_pe_dev_traverse(pe, eeh_report_failure, NULL); 715 eeh_pe_dev_traverse(pe, eeh_report_failure, NULL);
704 pcibios_remove_pci_devices(bus); 716 pcibios_remove_pci_devices(bus);
705 } 717 }
718 pci_unlock_rescan_remove();
706 } 719 }
707} 720}
708 721