@@ -805,8 +805,8 @@ static int64_t opal_pci_set_power_state(uint64_t async_token,
return OPAL_PARAMETER;
pci_remove_bus(phb, &pd->children);
- rc = OPAL_SUCCESS;
- break;
+ phb_unlock(phb);
+ return OPAL_SUCCESS;
case OPAL_PCI_SLOT_ONLINE:
if (!pd)
return OPAL_PARAMETER;
@@ -814,19 +814,29 @@ static int64_t opal_pci_set_power_state(uint64_t async_token,
&pd->children, pd, true);
pci_add_device_nodes(phb, &pd->children, pd->dn,
&phb->lstate, 0);
- rc = OPAL_SUCCESS;
- break;
+ phb_unlock(phb);
+ return OPAL_SUCCESS;
default:
rc = OPAL_PARAMETER;
}
- phb_unlock(phb);
if (rc == OPAL_ASYNC_COMPLETION) {
slot->retries = 500;
init_timer(&slot->timer, set_power_timer, slot);
schedule_timer(&slot->timer, msecs_to_tb(10));
+ } else if (rc == OPAL_SUCCESS) {
+ if (*state == OPAL_PCI_SLOT_POWER_OFF) {
+ pci_remove_bus(phb, &pd->children);
+ } else {
+ slot->ops.prepare_link_change(slot, true);
+ pci_scan_bus(phb, pd->secondary_bus,
+ pd->subordinate_bus, &pd->children, pd, true);
+ pci_add_device_nodes(phb, &pd->children, pd->dn,
+ &phb->lstate, 0);
+ }
}
+ phb_unlock(phb);
return rc;
}
opal_call(OPAL_PCI_SET_POWER_STATE, opal_pci_set_power_state, 3);
When OPAL_SUCCESS is returned from slot->ops.set_power_state(), we need update the PCI toplogy accordingly. This scenario can happen when builtin power control functionality is ignored to accomodate PCI surprise hotplug or not supported at all by the hardware. Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com> --- core/pci-opal.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-)