Skip to content

Commit

Permalink
core/pci: Use proper phandle during hotplug for PHB slots
Browse files Browse the repository at this point in the history
PHB slots don't have an associated device (slot->pd = NULL). They were
not used by the PCI hotplug framework so far, but with opencapi
virtual PHBs, that's changing. With opencapi, devices are directly
under the PHB (no root complex or intermediate bridge) and the slot
used for hotplug is the PHB slot.

This patch uses the proper phandle when replying asynchronously to the
OS when using a PHB slot.

Reviewed-by: Christophe Lombard <clombard@linux.vnet.ibm.com>
Reviewed-by: Andrew Donnellan <ajd@linux.ibm.com>
Signed-off-by: Frederic Barrat <fbarrat@linux.ibm.com>
Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
  • Loading branch information
fbarrat authored and oohal committed Oct 22, 2019
1 parent 38e51a3 commit 8bae237
Showing 1 changed file with 15 additions and 6 deletions.
21 changes: 15 additions & 6 deletions core/pci-opal.c
Expand Up @@ -647,6 +647,17 @@ static int64_t opal_pci_get_power_state(uint64_t id, uint64_t data)
}
opal_call(OPAL_PCI_GET_POWER_STATE, opal_pci_get_power_state, 2);

static u32 get_slot_phandle(struct pci_slot *slot)
{
struct phb *phb = slot->phb;
struct pci_device *pd = slot->pd;

if (pd)
return pd->dn->phandle;
else
return phb->dt_node->phandle;
}

static void rescan_slot_devices(struct pci_slot *slot)
{
struct phb *phb = slot->phb;
Expand All @@ -671,8 +682,6 @@ static void set_power_timer(struct timer *t __unused, void *data,
uint64_t now __unused)
{
struct pci_slot *slot = data;
struct pci_device *pd = slot->pd;
struct dt_node *dn = pd->dn;
uint8_t link;
struct phb *phb = slot->phb;

Expand All @@ -686,7 +695,7 @@ static void set_power_timer(struct timer *t __unused, void *data,
if (slot->retries-- == 0) {
pci_slot_set_state(slot, PCI_SLOT_STATE_NORMAL);
opal_queue_msg(OPAL_MSG_ASYNC_COMP, NULL, NULL,
slot->async_token, dn->phandle,
slot->async_token, get_slot_phandle(slot),
slot->power_state, OPAL_BUSY);
} else {
schedule_timer(&slot->timer, msecs_to_tb(10));
Expand All @@ -698,7 +707,7 @@ static void set_power_timer(struct timer *t __unused, void *data,
remove_slot_devices(slot);
pci_slot_set_state(slot, PCI_SLOT_STATE_NORMAL);
opal_queue_msg(OPAL_MSG_ASYNC_COMP, NULL, NULL,
slot->async_token, dn->phandle,
slot->async_token, get_slot_phandle(slot),
OPAL_PCI_SLOT_POWER_OFF, OPAL_SUCCESS);
break;
}
Expand All @@ -710,12 +719,12 @@ static void set_power_timer(struct timer *t __unused, void *data,
rescan_slot_devices(slot);
pci_slot_set_state(slot, PCI_SLOT_STATE_NORMAL);
opal_queue_msg(OPAL_MSG_ASYNC_COMP, NULL, NULL,
slot->async_token, dn->phandle,
slot->async_token, get_slot_phandle(slot),
OPAL_PCI_SLOT_POWER_ON, OPAL_SUCCESS);
} else if (slot->retries-- == 0) {
pci_slot_set_state(slot, PCI_SLOT_STATE_NORMAL);
opal_queue_msg(OPAL_MSG_ASYNC_COMP, NULL, NULL,
slot->async_token, dn->phandle,
slot->async_token, get_slot_phandle(slot),
OPAL_PCI_SLOT_POWER_ON, OPAL_BUSY);
} else {
schedule_timer(&slot->timer, msecs_to_tb(10));
Expand Down

0 comments on commit 8bae237

Please sign in to comment.