diff mbox

[06/12] lpc: Add P9 LPC interrupts support

Message ID 877fbr66wf.fsf@linux.vnet.ibm.com
State Rejected
Headers show

Commit Message

Stewart Smith Aug. 8, 2016, 7:45 a.m. UTC
Michael Neuling <mikey@neuling.org> writes:
> From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
>
> We currently don't exploit the new MUX that allow to spread them
> around different PSI interrupts, they all go to LPC#0
>
> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Signed-off-by: Michael Neuling <mikey@neuling.org>

Okay, so this patch fairly solidly broke most P8 platforms in some
way. I think my patch (below) ends up fixing Tuleta, but Garrison is
still broken.

> diff --git a/hw/psi.c b/hw/psi.c
> index 08dc589..16f88c2 100644
> --- a/hw/psi.c
> +++ b/hw/psi.c
> @@ -38,7 +38,7 @@ static LIST_HEAD(psis);
>  static u64 psi_link_timer;
>  static u64 psi_link_timeout;
>  static bool psi_link_poll_active;
> -static bool psi_ext_irq_policy = EXTERNAL_IRQ_POLICY_LINUX;
> +static bool psi_ext_irq_policy = EXTERNAL_IRQ_POLICY_SKIBOOT;
>
>  static void psi_activate_phb(struct psi *psi);
>

Is this change intentional?

Reverting this hunk fixes tuleta, while garrison is still rather broken.


The following patch also helped fix Tuleta, or at least seems to harden
things up a bit - I'm not sure we want to be depending on uninitialized
data being zero, and extra asserts seem to be useful.

Comments

Benjamin Herrenschmidt Aug. 8, 2016, 12:51 p.m. UTC | #1
On Mon, 2016-08-08 at 17:45 +1000, Stewart Smith wrote:

> > 
> > diff --git a/hw/psi.c b/hw/psi.c
> > index 08dc589..16f88c2 100644
> > --- a/hw/psi.c
> > +++ b/hw/psi.c
> > @@ -38,7 +38,7 @@ static LIST_HEAD(psis);
> >  static u64 psi_link_timer;
> >  static u64 psi_link_timeout;
> >  static bool psi_link_poll_active;
> > -static bool psi_ext_irq_policy = EXTERNAL_IRQ_POLICY_LINUX;
> > +static bool psi_ext_irq_policy = EXTERNAL_IRQ_POLICY_SKIBOOT;
> > 
> >  static void psi_activate_phb(struct psi *psi);
> > 
> 
> Is this change intentional?
> 
> Reverting this hunk fixes tuleta, while garrison is still rather
> broken.

Weird... that could mean that something on Tuleta is whacking the
external interrupt ... or maybe it's dangling ?

> The following patch also helped fix Tuleta, or at least seems to
> harden things up a bit - I'm not sure we want to be depending on
> uninitialized data being zero, and extra asserts seem to be useful.

Ugh ?

I have a hard dependency on BSS being 0 all over the place...

> 
> diff --git a/hw/lpc.c b/hw/lpc.c
> index e92d35627ab1..e94caff8c5dc 100644
> --- a/hw/lpc.c
> +++ b/hw/lpc.c
> @@ -547,6 +547,8 @@ static void lpc_setup_serirq(struct proc_chip
> *chip)
>  	uint32_t mask = LPC_HC_IRQ_BASE_IRQS;
>  	int rc;
>  
> +	assert(lock_held_by_me(&chip->lpc_lock));
> +
>  	if (!lpc_irqs_ready)
>  		return;
>  
> @@ -871,6 +875,7 @@ static void lpc_init_chip_p8(struct dt_node *xn)
>  	assert(chip);
>  
>  	chip->lpc_xbase = dt_get_address(xn, 0, NULL);
> +	chip->lpc_mbase = NULL;
>  	chip->lpc_fw_idsel = 0xff;
>  	chip->lpc_fw_rdsz = 0xff;
>  	init_lock(&chip->lpc_lock);
> @@ -905,6 +910,7 @@ static void lpc_init_chip_p9(struct dt_node
> *opb_node)
>  	addr <<= 32;
>  	addr |= dt_prop_get_cell(opb_node, "ranges", 2);
>  
> +	chip->lpc_xbase = 0;
>  	chip->lpc_mbase = (void *)addr;
>  	chip->lpc_fw_idsel = 0xff;
>  	chip->lpc_fw_rdsz = 0xff;
> @@ -947,6 +953,8 @@ void lpc_init(void)
>  		prlog(PR_NOTICE, "Default bus on chip %d\n",
>  					lpc_default_chip_id);
>  
> +	assert((has_lpc && lpc_default_chip_id >= 0) || (!has_lpc &&
> lpc_default_chip_id == -1));
> +
>  	if (has_lpc) {
>  		opal_register(OPAL_LPC_WRITE, opal_lpc_write, 5);
>  		opal_register(OPAL_LPC_READ, opal_lpc_read, 5);
>
Stewart Smith Aug. 9, 2016, 12:29 a.m. UTC | #2
Benjamin Herrenschmidt <benh@kernel.crashing.org> writes:
> On Mon, 2016-08-08 at 17:45 +1000, Stewart Smith wrote:
>> 
>> > 
>> > diff --git a/hw/psi.c b/hw/psi.c
>> > index 08dc589..16f88c2 100644
>> > --- a/hw/psi.c
>> > +++ b/hw/psi.c
>> > @@ -38,7 +38,7 @@ static LIST_HEAD(psis);
>> >  static u64 psi_link_timer;
>> >  static u64 psi_link_timeout;
>> >  static bool psi_link_poll_active;
>> > -static bool psi_ext_irq_policy = EXTERNAL_IRQ_POLICY_LINUX;
>> > +static bool psi_ext_irq_policy = EXTERNAL_IRQ_POLICY_SKIBOOT;
>> > 
>> >  static void psi_activate_phb(struct psi *psi);
>> > 
>> 
>> Is this change intentional?
>> 
>> Reverting this hunk fixes tuleta, while garrison is still rather
>> broken.
>
> Weird... that could mean that something on Tuleta is whacking the
> external interrupt ... or maybe it's dangling ?
>
>> The following patch also helped fix Tuleta, or at least seems to
>> harden things up a bit - I'm not sure we want to be depending on
>> uninitialized data being zero, and extra asserts seem to be useful.
>
> Ugh ?
>
> I have a hard dependency on BSS being 0 all over the place...

On a second look, all chip structures ar zalloc()d, so they should all
be zero no matter what anyway 

So, I'm wrong and I have no idea why.
diff mbox

Patch

diff --git a/hw/lpc.c b/hw/lpc.c
index e92d35627ab1..e94caff8c5dc 100644
--- a/hw/lpc.c
+++ b/hw/lpc.c
@@ -547,6 +547,8 @@  static void lpc_setup_serirq(struct proc_chip *chip)
 	uint32_t mask = LPC_HC_IRQ_BASE_IRQS;
 	int rc;
 
+	assert(lock_held_by_me(&chip->lpc_lock));
+
 	if (!lpc_irqs_ready)
 		return;
 
@@ -871,6 +875,7 @@  static void lpc_init_chip_p8(struct dt_node *xn)
 	assert(chip);
 
 	chip->lpc_xbase = dt_get_address(xn, 0, NULL);
+	chip->lpc_mbase = NULL;
 	chip->lpc_fw_idsel = 0xff;
 	chip->lpc_fw_rdsz = 0xff;
 	init_lock(&chip->lpc_lock);
@@ -905,6 +910,7 @@  static void lpc_init_chip_p9(struct dt_node *opb_node)
 	addr <<= 32;
 	addr |= dt_prop_get_cell(opb_node, "ranges", 2);
 
+	chip->lpc_xbase = 0;
 	chip->lpc_mbase = (void *)addr;
 	chip->lpc_fw_idsel = 0xff;
 	chip->lpc_fw_rdsz = 0xff;
@@ -947,6 +953,8 @@  void lpc_init(void)
 		prlog(PR_NOTICE, "Default bus on chip %d\n",
 					lpc_default_chip_id);
 
+	assert((has_lpc && lpc_default_chip_id >= 0) || (!has_lpc && lpc_default_chip_id == -1));
+
 	if (has_lpc) {
 		opal_register(OPAL_LPC_WRITE, opal_lpc_write, 5);
 		opal_register(OPAL_LPC_READ, opal_lpc_read, 5);