aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrederic Barrat <fbarrat@linux.ibm.com>2019-10-09 21:37:58 +0200
committerVasant Hegde <hegdevasant@linux.vnet.ibm.com>2020-03-10 16:29:39 +0530
commit57f1e506859bb0b99299ae960bef26ff34fc3cf9 (patch)
treee17098b5a8db1b5411f1547a7f3bdfee45f1f85f
parente5bf92eb54e97f8e7c78cf235270ecf49f3a4b10 (diff)
downloadskiboot-57f1e506859bb0b99299ae960bef26ff34fc3cf9.zip
skiboot-57f1e506859bb0b99299ae960bef26ff34fc3cf9.tar.gz
skiboot-57f1e506859bb0b99299ae960bef26ff34fc3cf9.tar.bz2
core/pci: Use proper phandle during hotplug for PHB slots
[ Upstream commit 8bae237693b6e05cd979c28a22e8a8efef1cb2bc ] 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> Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
-rw-r--r--core/pci-opal.c21
1 files changed, 15 insertions, 6 deletions
diff --git a/core/pci-opal.c b/core/pci-opal.c
index b63be61..cbab2f4 100644
--- a/core/pci-opal.c
+++ b/core/pci-opal.c
@@ -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;
@@ -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;
@@ -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));
@@ -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;
}
@@ -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));