[Skiboot] [RFC 10/12] npu2-opencapi: Activate PCI hotplug on opencapi slot

Frederic Barrat fbarrat at linux.ibm.com
Wed Jun 19 22:45:08 AEST 2019


Implement the get_power_state() and set_power_state() callbacks for
the opencapi PHB and add properties in the device tree to mark the
opencapi slot as hot-pluggable.

Signed-off-by: Frederic Barrat <fbarrat at linux.ibm.com>
---
 core/pci-slot.c    |  3 +++
 hw/npu2-opencapi.c | 51 +++++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 51 insertions(+), 3 deletions(-)

diff --git a/core/pci-slot.c b/core/pci-slot.c
index 8b0cc713..fd7b1168 100644
--- a/core/pci-slot.c
+++ b/core/pci-slot.c
@@ -32,6 +32,9 @@ static void pci_slot_prepare_link_change(struct pci_slot *slot, bool up)
 	struct pci_device *pd = slot->pd;
 	uint32_t aercap, mask;
 
+	if (!pd)
+		return;
+
 	/*
 	 * Mask the link down and receiver error before the link becomes
 	 * down. Otherwise, unmask the errors when the link is up.
diff --git a/hw/npu2-opencapi.c b/hw/npu2-opencapi.c
index c11c945f..c9a8410e 100644
--- a/hw/npu2-opencapi.c
+++ b/hw/npu2-opencapi.c
@@ -1047,7 +1047,7 @@ static int64_t npu2_opencapi_get_presence_state(struct pci_slot __unused *slot,
 	 *
 	 * This may change if we ever support hotplug down the track.
 	 */
-	*val = true;
+	*val = OPAL_PCI_SLOT_PRESENT;
 	return OPAL_SUCCESS;
 }
 
@@ -1105,6 +1105,38 @@ static int64_t npu2_opencapi_get_link_state(struct pci_slot *slot, uint8_t *val)
 	return OPAL_SUCCESS;
 }
 
+static int64_t npu2_opencapi_get_power_state(struct pci_slot *slot,
+					uint8_t *val)
+{
+	*val = slot->power_state;
+	return OPAL_SUCCESS;
+}
+
+static int64_t npu2_opencapi_set_power_state(struct pci_slot *slot, uint8_t val)
+{
+	struct npu2_dev *dev = phb_to_npu2_dev_ocapi(slot->phb);
+
+	switch (val) {
+	case PCI_SLOT_POWER_OFF:
+		OCAPIDBG(dev, "Setting the adapter in reset\n");
+		fence_brick(dev);
+		assert_adapter_reset(dev);
+		slot->power_state = PCI_SLOT_POWER_OFF;
+		return OPAL_SUCCESS;
+
+	case PCI_SLOT_POWER_ON:
+		if (slot->power_state != PCI_SLOT_POWER_OFF)
+			return OPAL_SUCCESS;
+		OCAPIDBG(dev, "Reactivating the adapter\n");
+		slot->power_state = PCI_SLOT_POWER_ON;
+		slot->state = OCAPI_SLOT_NORMAL;
+		return msecs_to_tb(1);
+
+	default:
+		return OPAL_UNSUPPORTED;
+	}
+}
+
 static void check_trained_link(struct npu2_dev *dev, uint64_t odl_status)
 {
 	if (get_link_width(odl_status) != OPAL_SHPC_LINK_UP_x8) {
@@ -1204,6 +1236,7 @@ static int64_t npu2_opencapi_freset(struct pci_slot *slot)
 
 	switch (slot->state) {
 	case OCAPI_SLOT_NORMAL:
+	case OCAPI_SLOT_FRESET:
 	case OCAPI_SLOT_FRESET_START:
 		OCAPIDBG(dev, "FRESET starts\n");
 
@@ -1272,6 +1305,17 @@ static int64_t npu2_opencapi_hreset(struct pci_slot *slot __unused)
 	return OPAL_UNSUPPORTED;
 }
 
+static void make_slot_hotpluggable(struct pci_slot *slot, struct phb *phb)
+{
+	char label[40];
+
+	slot->pluggable = 1;
+	pci_slot_add_dt_properties(slot, phb->dt_node);
+	snprintf(label, sizeof(label), "OPENCAPI-%04x",
+		(int) PCI_SLOT_PHB_INDEX(slot->id));
+	dt_add_property_string(phb->dt_node, "ibm,slot-label", label);
+}
+
 static struct pci_slot *npu2_opencapi_slot_create(struct phb *phb)
 {
 	struct pci_slot *slot;
@@ -1283,10 +1327,10 @@ static struct pci_slot *npu2_opencapi_slot_create(struct phb *phb)
 	/* TODO: Figure out other slot functions */
 	slot->ops.get_presence_state  = npu2_opencapi_get_presence_state;
 	slot->ops.get_link_state      = npu2_opencapi_get_link_state;
-	slot->ops.get_power_state     = NULL;
+	slot->ops.get_power_state     = npu2_opencapi_get_power_state;
 	slot->ops.get_attention_state = NULL;
 	slot->ops.get_latch_state     = NULL;
-	slot->ops.set_power_state     = NULL;
+	slot->ops.set_power_state     = npu2_opencapi_set_power_state;
 	slot->ops.set_attention_state = NULL;
 
 	slot->ops.poll_link           = npu2_opencapi_poll_link;
@@ -1294,6 +1338,7 @@ static struct pci_slot *npu2_opencapi_slot_create(struct phb *phb)
 	slot->ops.freset              = npu2_opencapi_freset;
 	slot->ops.hreset              = npu2_opencapi_hreset;
 
+	make_slot_hotpluggable(slot, phb);
 	return slot;
 }
 
-- 
2.21.0



More information about the Skiboot mailing list