From 573c54b1e3ca4c70eb6cbaa6b8b8a7eb6736dbbe Mon Sep 17 00:00:00 2001 From: Milton Miller Date: Fri, 10 Oct 2008 01:56:23 +0000 Subject: [PATCH] --- yaml --- r: 114609 b: refs/heads/master c: 8767e9badca7cdf0adc2564d7524092d47ababf3 h: refs/heads/master i: 114607: fffd78365b20c7cdc7995bcdfdecab96f09584a0 v: v3 --- [refs] | 2 +- trunk/arch/powerpc/platforms/pseries/xics.c | 53 ++++++++++++++++----- 2 files changed, 42 insertions(+), 13 deletions(-) diff --git a/[refs] b/[refs] index 2586c36c15ef..01ae7b89473b 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: bb3d55e2505d8de15b132a3f6a1d596c1e2a13ee +refs/heads/master: 8767e9badca7cdf0adc2564d7524092d47ababf3 diff --git a/trunk/arch/powerpc/platforms/pseries/xics.c b/trunk/arch/powerpc/platforms/pseries/xics.c index 6b1a005cc0cc..1bccd4a56b57 100644 --- a/trunk/arch/powerpc/platforms/pseries/xics.c +++ b/trunk/arch/powerpc/platforms/pseries/xics.c @@ -332,32 +332,61 @@ static void xics_eoi_lpar(unsigned int virq) lpar_xirr_info_set((0xff << 24) | irq); } -static inline unsigned int xics_remap_irq(unsigned int vec) +static inline unsigned int xics_xirr_vector(unsigned int xirr) { - unsigned int irq; + /* + * The top byte is the old cppr, to be restored on EOI. + * The remaining 24 bits are the vector. + */ + return xirr & 0x00ffffff; +} - vec &= 0x00ffffff; +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(vec); +} + +static unsigned int xics_get_irq_direct(void) +{ + unsigned int xirr = direct_xirr_info_get(); + unsigned int vec = xics_xirr_vector(xirr); + unsigned int irq; if (vec == XICS_IRQ_SPURIOUS) return NO_IRQ; + irq = irq_radix_revmap_lookup(xics_host, vec); if (likely(irq != NO_IRQ)) return irq; - printk(KERN_ERR "Interrupt %u (real) is invalid," - " disabling it.\n", vec); - xics_mask_real_irq(vec); - return NO_IRQ; -} + /* We don't have a linux mapping, so have rtas mask it. */ + xics_mask_unknown_vec(vec); -static unsigned int xics_get_irq_direct(void) -{ - return xics_remap_irq(direct_xirr_info_get()); + /* We might learn about it later, so EOI it */ + direct_xirr_info_set(xirr); + return NO_IRQ; } static unsigned int xics_get_irq_lpar(void) { - return xics_remap_irq(lpar_xirr_info_get()); + unsigned int xirr = lpar_xirr_info_get(); + unsigned int vec = xics_xirr_vector(xirr); + unsigned int irq; + + if (vec == XICS_IRQ_SPURIOUS) + return NO_IRQ; + + irq = irq_radix_revmap_lookup(xics_host, vec); + if (likely(irq != NO_IRQ)) + return irq; + + /* We don't have a linux mapping, so have RTAS mask it. */ + xics_mask_unknown_vec(vec); + + /* We might learn about it later, so EOI it */ + lpar_xirr_info_set(xirr); + return NO_IRQ; } #ifdef CONFIG_SMP