diff mbox

[01/16] psi: Add DT option to disable LPC interrupts

Message ID 1478763292-23238-1-git-send-email-benh@kernel.crashing.org
State Superseded
Headers show

Commit Message

Benjamin Herrenschmidt Nov. 10, 2016, 7:34 a.m. UTC
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(+)

Comments

Ananth N Mavinakayanahalli Nov. 10, 2016, 9:15 a.m. UTC | #1
On Thu, Nov 10, 2016 at 06:34:37PM +1100, Benjamin Herrenschmidt wrote:
> 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(+)
> 
> diff --git a/hw/psi.c b/hw/psi.c
> index 900886a..63a64d0 100644
> --- a/hw/psi.c
> +++ b/hw/psi.c
> @@ -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)

Not __unused anymore?

>  {
> +	struct psi *psi = is->data;
> +	unsigned int idx = isn & 0xf;

Ananth
diff mbox

Patch

diff --git a/hw/psi.c b/hw/psi.c
index 900886a..63a64d0 100644
--- a/hw/psi.c
+++ b/hw/psi.c
@@ -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);
diff --git a/include/psi.h b/include/psi.h
index 24d4206..5982adc 100644
--- a/include/psi.h
+++ b/include/psi.h
@@ -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);