@@ -539,6 +539,9 @@ static uint64_t psi_p8_irq_attributes(struct irq_source *is, uint32_t isn)
uint32_t idx = isn - psi->interrupt;
uint64_t attr;
+ if (psi->no_lpc_irqs && idx == P8_IRQ_PSI_LPC)
+ return IRQ_ATTR_TARGET_LINUX;
+
if (idx == P8_IRQ_PSI_EXTERNAL &&
psi_ext_irq_policy == EXTERNAL_IRQ_POLICY_LINUX)
return IRQ_ATTR_TARGET_LINUX;
@@ -606,6 +609,21 @@ static void psihb_p9_interrupt(struct irq_source *is, uint32_t isn)
static uint64_t psi_p9_irq_attributes(struct irq_source *is __unused,
uint32_t isn __unused)
{
+ struct psi *psi = is->data;
+ unsigned int idx = isn & 0xf;
+
+ /* If LPC interrupts are disabled, route them to Linux
+ * (who will not request them since they aren't referenced
+ * in the device tree)
+ */
+ if (psi->no_lpc_irqs &&
+ (idx == P9_PSI_IRQ_LPC_SIRQ0 ||
+ idx == P9_PSI_IRQ_LPC_SIRQ1 ||
+ idx == P9_PSI_IRQ_LPC_SIRQ2 ||
+ idx == P9_PSI_IRQ_LPC_SIRQ3 ||
+ idx == P9_PSI_IRQ_LPCHC))
+ return IRQ_ATTR_TARGET_LINUX;
+
/* XXX For now, all go to OPAL, this will change */
return IRQ_ATTR_TARGET_OPAL | IRQ_ATTR_TARGET_FREQUENT;
}
@@ -1020,6 +1038,9 @@ static bool psi_init_psihb(struct dt_node *psihb)
}
chip->psi = psi;
+ if (dt_has_node_property(psihb, "no-lpc-interrupts", NULL))
+ psi->no_lpc_irqs = true;
+
psi_activate_phb(psi);
psi_init_interrupts(psi);
psi_create_mm_dtnode(psi);
@@ -245,6 +245,7 @@ struct psi {
unsigned int chip_id;
unsigned int interrupt;
bool active;
+ bool no_lpc_irqs;
};
extern void psi_set_link_polling(bool active);
Some sim models have the LPC interrupts stuck asserted on secondary chips so we add a device-tree option that makes us set the policy for these to "Linux" instead of "OPAL". Since they aren't referenced in the device-tree this will de-facto prevent them from being enabled Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> --- hw/psi.c | 21 +++++++++++++++++++++ include/psi.h | 1 + 2 files changed, 22 insertions(+)