aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hw/occ.c22
-rw-r--r--hw/psi.c7
-rw-r--r--include/chip.h3
-rw-r--r--include/psi.h1
4 files changed, 30 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;
diff --git a/include/chip.h b/include/chip.h
index 0547902..1b4f4c4 100644
--- a/include/chip.h
+++ b/include/chip.h
@@ -157,6 +157,9 @@ struct proc_chip {
/* Used by hw/p8-i2c.c */
struct list_head i2cms;
+
+ /* Used by hw/psi.c */
+ struct psi *psi;
};
extern uint32_t pir_to_chip_id(uint32_t pir);
diff --git a/include/psi.h b/include/psi.h
index 4127242..62643aa 100644
--- a/include/psi.h
+++ b/include/psi.h
@@ -217,6 +217,7 @@ extern void psi_disable_link(struct psi *psi);
extern void psi_reset_fsp(struct psi *psi);
extern bool psi_check_link_active(struct psi *psi);
extern bool psi_poll_fsp_interrupt(struct psi *psi);
+extern struct psi *psi_find_functional_chip(void);
/* Interrupts */
extern void psi_irq_reset(void);