diff options
Diffstat (limited to 'arch')
| -rw-r--r-- | arch/powerpc/kernel/eeh_driver.c | 19 | 
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)  	edev->mode |= EEH_DEV_DISCONNECTED;  	(*removed)++; +	pci_lock_rescan_remove();  	pci_stop_and_remove_bus_device(dev); +	pci_unlock_rescan_remove();  	return NULL;  } @@ -416,10 +418,13 @@ static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus)  	 * into pcibios_add_pci_devices().  	 */  	eeh_pe_state_mark(pe, EEH_PE_KEEP); -	if (bus) +	if (bus) { +		pci_lock_rescan_remove();  		pcibios_remove_pci_devices(bus); -	else if (frozen_bus) +		pci_unlock_rescan_remove(); +	} else if (frozen_bus) {  		eeh_pe_dev_traverse(pe, eeh_rmv_device, &removed); +	}  	/* Reset the pci controller. (Asserts RST#; resets config space).  	 * 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)  	if (rc)  		return rc; +	pci_lock_rescan_remove(); +  	/* Restore PE */  	eeh_ops->configure_bridge(pe);  	eeh_pe_restore_bars(pe); @@ -462,6 +469,7 @@ static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus)  	pe->tstamp = tstamp;  	pe->freeze_count = cnt; +	pci_unlock_rescan_remove();  	return 0;  } @@ -618,8 +626,11 @@ perm_error:  	eeh_pe_dev_traverse(pe, eeh_report_failure, NULL);  	/* Shut down the device drivers for good. */ -	if (frozen_bus) +	if (frozen_bus) { +		pci_lock_rescan_remove();  		pcibios_remove_pci_devices(frozen_bus); +		pci_unlock_rescan_remove(); +	}  }  static void eeh_handle_special_event(void) @@ -692,6 +703,7 @@ static void eeh_handle_special_event(void)  	if (rc == 2 || rc == 1)  		eeh_handle_normal_event(pe);  	else { +		pci_lock_rescan_remove();  		list_for_each_entry_safe(hose, tmp,  			&hose_list, list_node) {  			phb_pe = eeh_phb_pe_get(hose); @@ -703,6 +715,7 @@ static void eeh_handle_special_event(void)  			eeh_pe_dev_traverse(pe, eeh_report_failure, NULL);  			pcibios_remove_pci_devices(bus);  		} +		pci_unlock_rescan_remove();  	}  }  | 
