aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/pcie-slot.c13
-rw-r--r--include/pci-slot.h1
-rw-r--r--platforms/astbmc/slots.c13
3 files changed, 24 insertions, 3 deletions
diff --git a/core/pcie-slot.c b/core/pcie-slot.c
index 72068ba..e92aa8d 100644
--- a/core/pcie-slot.c
+++ b/core/pcie-slot.c
@@ -227,15 +227,22 @@ static int64_t pcie_slot_set_power_state_ext(struct pci_slot *slot, uint8_t val,
* only concerned in surprise hotplug path. In managed hot-add path,
* the PCIe link should have been ready before we power on the slot.
* However, it's not harmful to do so in managed hot-add path.
+ *
+ * When flag PCI_SLOT_FLAG_FORCE_POWERON is set for the PCI slot, we
+ * should turn on the slot's power supply on hardware on user's request
+ * because that might have been lost. Otherwise, the PCIe link behind
+ * the slot won't become ready for ever and PCI adapter behind the slot
+ * can't be probed successfully.
*/
if (surprise_check && slot->surprise_pluggable) {
slot->power_state = val;
- if (val == PCI_SLOT_POWER_ON) {
+ if (val == PCI_SLOT_POWER_OFF)
+ return OPAL_SUCCESS;
+
+ if (!pci_slot_has_flags(slot, PCI_SLOT_FLAG_FORCE_POWERON)) {
pci_slot_set_state(slot, PCI_SLOT_STATE_SPOWER_DONE);
return OPAL_ASYNC_COMPLETION;
}
-
- return OPAL_SUCCESS;
}
pci_slot_set_state(slot, PCI_SLOT_STATE_SPOWER_START);
diff --git a/include/pci-slot.h b/include/pci-slot.h
index ce3e8dd..7f16ddd 100644
--- a/include/pci-slot.h
+++ b/include/pci-slot.h
@@ -146,6 +146,7 @@ struct pci_slot_ops {
struct pci_slot {
uint32_t flags;
#define PCI_SLOT_FLAG_BOOTUP 0x1
+#define PCI_SLOT_FLAG_FORCE_POWERON 0x2
struct phb *phb;
struct pci_device *pd;
diff --git a/platforms/astbmc/slots.c b/platforms/astbmc/slots.c
index aeca007..f28ad7d 100644
--- a/platforms/astbmc/slots.c
+++ b/platforms/astbmc/slots.c
@@ -166,6 +166,19 @@ static void create_dynamic_slot(struct phb *phb, struct pci_device *pd)
slot = pcie_slot_create(phb, pd);
assert(slot);
init_slot_info(slot, true, NULL);
+
+ /* On superMicro's "p8dnu" platform, we create dynamic PCI slots
+ * for all downstream ports of PEX9733 that is connected to PHB
+ * direct slot. The power supply to the PCI slot is lost after
+ * PCI adapter is removed from it. The power supply can't be
+ * turned on when the slot is in empty state. The power supply
+ * isn't turned on automatically when inserting PCI adapter to
+ * the slot at later point. We set a flag to the slot here, to
+ * turn on the power supply in (suprise or managed) hot-add path.
+ */
+ if (dt_node_is_compatible(dt_root, "supermicro,p8dnu") &&
+ slot->pd && slot->pd->vdid == 0x973310b5)
+ pci_slot_add_flags(slot, PCI_SLOT_FLAG_FORCE_POWERON);
}
void slot_table_get_slot_info(struct phb *phb, struct pci_device *pd)