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

Andrew Donnellan ajd at linux.ibm.com
Wed Jun 26 14:34:13 AEST 2019


On 19/6/19 10:45 pm, Frederic Barrat wrote:
> 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.
>   	 */

Might want to update this comment

> -	*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);

Except the ->pluggable = 1, this isn't particularly hotplug specific is 
it? Could be named a bit better

> +}
> +
>   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;
>   }
>   
> 

-- 
Andrew Donnellan              OzLabs, ADL Canberra
ajd at linux.ibm.com             IBM Australia Limited



More information about the Skiboot mailing list