[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