[Skiboot] [PATCH 10/16] core/pci: Update PCI topology after power change

Gavin Shan gwshan at linux.vnet.ibm.com
Fri Sep 16 15:05:17 AEST 2016


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 or
not supported in hardware.

Signed-off-by: Gavin Shan <gwshan at linux.vnet.ibm.com>
---
 core/pci-opal.c | 20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)

diff --git a/core/pci-opal.c b/core/pci-opal.c
index ba7a261..7ba64f5 100644
--- a/core/pci-opal.c
+++ b/core/pci-opal.c
@@ -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);
-- 
2.1.0



More information about the Skiboot mailing list