summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMilton Miller <miltonm@bga.com>2011-03-21 11:38:02 +0000
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2011-03-30 10:44:13 +1100
commit4f1fc48a73a49a60b3e03e6d8fb363d1b328bd4e (patch)
tree63dc74c40f516c5f993fe5ff1da8a62f7c54e545
parent834796a8493809ae6667b65c4c044066f41d32c7 (diff)
downloadlinux-4f1fc48a73a49a60b3e03e6d8fb363d1b328bd4e.tar.gz
linux-4f1fc48a73a49a60b3e03e6d8fb363d1b328bd4e.tar.bz2
linux-4f1fc48a73a49a60b3e03e6d8fb363d1b328bd4e.zip
powerpc/xics: Fix numberspace mismatch from irq_desc conversion
commit 79f26c268ebad29bd75d078cfc09d3d82b30ccbd (powerpc: platforms/pseries irq_data conversion) pushed irq_desc down into many functions, dererencing the descriptor irq field as late as possible. But it incorrectly passed a linix virtural irq number to RTAS, resulting in the interrupt not being disabled and possibly other bad things, such as another interrupt being disabled and/or a checkstop. In addition this missed the point of xics_mask_unknown_vec and the seperation of xics_mask_real_irq from xics_mask_irq. When xics_mask_unknown_vec is called it's because the hardware delivered an irq source for which we have no linux irq allocated, and thefore we can not have an irq_desc allocated. Revert xics_mask_real_irq to its prior version, naming the argument hwirq to highlight the difference. Signed-off-by: Milton Miller <miltonm@bga.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
-rw-r--r--arch/powerpc/platforms/pseries/xics.c16
1 files changed, 8 insertions, 8 deletions
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c
index 6c1e638f0ce9..9e7ff87a5950 100644
--- a/arch/powerpc/platforms/pseries/xics.c
+++ b/arch/powerpc/platforms/pseries/xics.c
@@ -250,26 +250,26 @@ static unsigned int xics_startup(struct irq_data *d)
return 0;
}
-static void xics_mask_real_irq(struct irq_data *d)
+static void xics_mask_real_irq(unsigned int hwirq)
{
int call_status;
- if (d->irq == XICS_IPI)
+ if (hwirq == XICS_IPI)
return;
- call_status = rtas_call(ibm_int_off, 1, 1, NULL, d->irq);
+ call_status = rtas_call(ibm_int_off, 1, 1, NULL, hwirq);
if (call_status != 0) {
printk(KERN_ERR "%s: ibm_int_off irq=%u returned %d\n",
- __func__, d->irq, call_status);
+ __func__, hwirq, call_status);
return;
}
/* Have to set XIVE to 0xff to be able to remove a slot */
- call_status = rtas_call(ibm_set_xive, 3, 1, NULL, d->irq,
+ call_status = rtas_call(ibm_set_xive, 3, 1, NULL, hwirq,
default_server, 0xff);
if (call_status != 0) {
printk(KERN_ERR "%s: ibm_set_xive(0xff) irq=%u returned %d\n",
- __func__, d->irq, call_status);
+ __func__, hwirq, call_status);
return;
}
}
@@ -283,13 +283,13 @@ static void xics_mask_irq(struct irq_data *d)
irq = (unsigned int)irq_map[d->irq].hwirq;
if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS)
return;
- xics_mask_real_irq(d);
+ xics_mask_real_irq(irq);
}
static void xics_mask_unknown_vec(unsigned int vec)
{
printk(KERN_ERR "Interrupt %u (real) is invalid, disabling it.\n", vec);
- xics_mask_real_irq(irq_get_irq_data(vec));
+ xics_mask_real_irq(vec);
}
static inline unsigned int xics_xirr_vector(unsigned int xirr)