aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/occ.c22
-rw-r--r--hw/psi.c7
2 files changed, 26 insertions, 3 deletions
diff --git a/hw/occ.c b/hw/occ.c
index 34d6de5..fe513cb 100644
--- a/hw/occ.c
+++ b/hw/occ.c
@@ -625,12 +625,28 @@ static struct fsp_client fsp_occ_client = {
void occ_send_dummy_interrupt(void)
{
+ struct psi *psi;
+ struct proc_chip *chip = get_chip(this_cpu()->chip_id);
+
/* Emulators and P7 doesn't do this */
if (proc_gen != proc_gen_p8 || chip_quirk(QUIRK_NO_OCC_IRQ))
return;
- xscom_writeme(OCB_OCI_OCCMISC_OR,
- OCB_OCI_OCIMISC_IRQ |
- OCB_OCI_OCIMISC_IRQ_OPAL_DUMMY);
+
+ /* Find a functional PSI. This ensures an interrupt even if
+ * the psihb on the current chip is not configured */
+ if (chip->psi)
+ psi = chip->psi;
+ else
+ psi = psi_find_functional_chip();
+
+ if (!psi) {
+ prlog_once(PR_WARNING, "PSI: no functional PSI HB found, "
+ "no self interrupts delivered\n");
+ return;
+ }
+
+ xscom_write(psi->chip_id, OCB_OCI_OCCMISC_OR,
+ OCB_OCI_OCIMISC_IRQ | OCB_OCI_OCIMISC_IRQ_OPAL_DUMMY);
}
void occ_interrupt(uint32_t chip_id)
diff --git a/hw/psi.c b/hw/psi.c
index c0692a1..0a013b5 100644
--- a/hw/psi.c
+++ b/hw/psi.c
@@ -885,6 +885,8 @@ static bool psi_init_psihb(struct dt_node *psihb)
psi->chip_id = chip->id;
psi->interrupt = get_psi_interrupt(chip->id);
+ chip->psi = psi;
+
psi_create_mm_dtnode(psi);
psi_register_interrupts(psi);
psi_activate_phb(psi);
@@ -905,6 +907,11 @@ void psi_fsp_link_in_use(struct psi *psi __unused)
}
}
+struct psi *psi_find_functional_chip(void)
+{
+ return list_top(&psis, struct psi, list);
+}
+
void psi_init(void)
{
struct dt_node *np;