[Skiboot] [PATCH v2 5/8] capp/phb4: Force CAPP to PCIe mode during kernel shutdown
Vaibhav Jain
vaibhav at linux.ibm.com
Mon Dec 10 01:17:41 AEDT 2018
This patch introduces a new opal syncer for PHB4 named
phb4_host_sync_reset(). We register this opal syncer when CAPP is
activated successfully in phb4_set_capi_mode() so that it will be
called at kernel shutdown during fast-reset.
During kernel shutdown the function will then repeatedly call
phb->ops->set_capi_mode() to switch switch CAPP to PCIe mode. In case
set_capi_mode() indicates its OPAL_BUSY, which indicates that CAPP is
still transitioning to new state; it calls slot->ops.run_sm() to
ensure that Opal slot reset state machine makes forward progress.
Signed-off-by: Vaibhav Jain <vaibhav at linux.ibm.com>
---
hw/phb4.c | 39 +++++++++++++++++++++++++++++++++++++--
1 file changed, 37 insertions(+), 2 deletions(-)
diff --git a/hw/phb4.c b/hw/phb4.c
index df483e27..97c77a89 100644
--- a/hw/phb4.c
+++ b/hw/phb4.c
@@ -2768,6 +2768,37 @@ static void phb4_training_trace(struct phb4 *p)
}
}
+/*
+ * This helper is called repeatedly by the host sync notifier mechanism, which
+ * relies on the kernel to regularly poll the OPAL_SYNC_HOST_REBOOT call as it
+ * shuts down.
+ */
+static bool phb4_host_sync_reset(void *data)
+{
+ struct phb4 *p = (struct phb4 *)data;
+ struct phb *phb = &p->phb;
+ int64_t rc = 0;
+
+ /* Make sure no-one modifies the phb flags while we are active */
+ phb_lock(phb);
+
+ /* Make sure CAPP is attached to the PHB */
+ if (phb->capp)
+ /* Call phb ops to disable capi */
+ rc = phb->ops->set_capi_mode(phb, OPAL_PHB_CAPI_MODE_PCIE,
+ phb->capp->attached_pe);
+ else
+ rc = OPAL_SUCCESS;
+
+ /* Continue kicking state-machine if in middle of a mode transition */
+ if (rc == OPAL_BUSY)
+ rc = phb->slot->ops.run_sm(phb->slot);
+
+ phb_unlock(phb);
+
+ return rc <= OPAL_SUCCESS;
+}
+
static int64_t phb4_poll_link(struct pci_slot *slot)
{
struct phb4 *p = phb_to_phb4(slot->phb);
@@ -4419,7 +4450,7 @@ static int64_t phb4_init_capp(struct phb4 *p)
capp->capp_xscom_offset = CAPP1_REG_OFFSET;
}
- capp->attached_pe = phb4_get_reserved_pe_number(phb);
+ capp->attached_pe = phb4_get_reserved_pe_number(&p->phb);
/* Load capp microcode into the capp unit */
load_capp_ucode(p);
@@ -4462,7 +4493,8 @@ static int64_t phb4_set_capi_mode(struct phb *phb, uint64_t mode,
break;
}
- xscom_read(p->chip_id, CAPP_ERR_STATUS_CTRL + offset, ®);
+ xscom_read(p->chip_id, CAPP_ERR_STATUS_CTRL +
+ capp->capp_xscom_offset, ®);
if ((reg & PPC_BIT(5))) {
PHBERR(p, "CAPP: recovery failed (%016llx)\n", reg);
ret = OPAL_HARDWARE;
@@ -4492,6 +4524,9 @@ static int64_t phb4_set_capi_mode(struct phb *phb, uint64_t mode,
CAPP_MAX_STQ_ENGINES |
CAPP_MIN_DMA_READ_ENGINES);
if (ret == OPAL_SUCCESS) {
+ /* register notification on system shutdown */
+ opal_add_host_sync_notifier(&phb4_host_sync_reset, p);
+
/* Disable fast reboot for CAPP */
disable_fast_reboot("CAPP being enabled");
} else {
--
2.19.2
More information about the Skiboot
mailing list