aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/pci-opal.c7
-rw-r--r--include/pci.h5
2 files changed, 12 insertions, 0 deletions
diff --git a/core/pci-opal.c b/core/pci-opal.c
index d520960..b63be61 100644
--- a/core/pci-opal.c
+++ b/core/pci-opal.c
@@ -674,6 +674,12 @@ static void set_power_timer(struct timer *t __unused, void *data,
struct pci_device *pd = slot->pd;
struct dt_node *dn = pd->dn;
uint8_t link;
+ struct phb *phb = slot->phb;
+
+ if (!phb_try_lock(phb)) {
+ schedule_timer(&slot->timer, msecs_to_tb(10));
+ return;
+ }
switch (slot->state) {
case PCI_SLOT_STATE_SPOWER_START:
@@ -720,6 +726,7 @@ static void set_power_timer(struct timer *t __unused, void *data,
prlog(PR_ERR, "PCI SLOT %016llx: Unexpected state 0x%08x\n",
slot->id, slot->state);
}
+ phb_unlock(phb);
}
static int64_t opal_pci_set_power_state(uint64_t async_token,
diff --git a/include/pci.h b/include/pci.h
index 220d6b1..3c9544b 100644
--- a/include/pci.h
+++ b/include/pci.h
@@ -387,6 +387,11 @@ static inline void phb_lock(struct phb *phb)
lock(&phb->lock);
}
+static inline bool phb_try_lock(struct phb *phb)
+{
+ return try_lock(&phb->lock);
+}
+
static inline void phb_unlock(struct phb *phb)
{
unlock(&phb->lock);