Merge master.kernel.org:/pub/scm/linux/kernel/git/davej/cpufreq
[pandora-kernel.git] / arch / powerpc / platforms / pseries / xics.c
index 7564210..253972e 100644 (file)
@@ -34,6 +34,7 @@
 #include <asm/i8259.h>
 
 #include "xics.h"
+#include "plpar_wrappers.h"
 
 #define XICS_IPI               2
 #define XICS_IRQ_SPURIOUS      0
@@ -110,27 +111,6 @@ static inline void direct_qirr_info(int n_cpu, u8 value)
 /* LPAR low level accessors */
 
 
-static inline long plpar_eoi(unsigned long xirr)
-{
-       return plpar_hcall_norets(H_EOI, xirr);
-}
-
-static inline long plpar_cppr(unsigned long cppr)
-{
-       return plpar_hcall_norets(H_CPPR, cppr);
-}
-
-static inline long plpar_ipi(unsigned long servernum, unsigned long mfrr)
-{
-       return plpar_hcall_norets(H_IPI, servernum, mfrr);
-}
-
-static inline long plpar_xirr(unsigned long *xirr_ret)
-{
-       unsigned long dummy;
-       return plpar_hcall(H_XIRR, 0, 0, 0, 0, xirr_ret, &dummy, &dummy);
-}
-
 static inline unsigned int lpar_xirr_info_get(int n_cpu)
 {
        unsigned long lpar_rc;
@@ -467,7 +447,7 @@ void xics_setup_cpu(void)
         *
         * XXX: undo of teardown on kexec needs this too, as may hotplug
         */
-       rtas_set_indicator(GLOBAL_INTERRUPT_QUEUE,
+       rtas_set_indicator_fast(GLOBAL_INTERRUPT_QUEUE,
                (1UL << interrupt_server_size) - 1 - default_distrib_server, 1);
 }
 
@@ -502,16 +482,9 @@ static int xics_host_match(struct irq_host *h, struct device_node *node)
 }
 
 static int xics_host_map_direct(struct irq_host *h, unsigned int virq,
-                               irq_hw_number_t hw, unsigned int flags)
+                               irq_hw_number_t hw)
 {
-       unsigned int sense = flags & IRQ_TYPE_SENSE_MASK;
-
-       pr_debug("xics: map_direct virq %d, hwirq 0x%lx, flags: 0x%x\n",
-                virq, hw, flags);
-
-       if (sense && sense != IRQ_TYPE_LEVEL_LOW)
-               printk(KERN_WARNING "xics: using unsupported sense 0x%x"
-                      " for irq %d (h: 0x%lx)\n", flags, virq, hw);
+       pr_debug("xics: map_direct virq %d, hwirq 0x%lx\n", virq, hw);
 
        get_irq_desc(virq)->status |= IRQ_LEVEL;
        set_irq_chip_and_handler(virq, &xics_pic_direct, handle_fasteoi_irq);
@@ -519,16 +492,9 @@ static int xics_host_map_direct(struct irq_host *h, unsigned int virq,
 }
 
 static int xics_host_map_lpar(struct irq_host *h, unsigned int virq,
-                             irq_hw_number_t hw, unsigned int flags)
+                             irq_hw_number_t hw)
 {
-       unsigned int sense = flags & IRQ_TYPE_SENSE_MASK;
-
-       pr_debug("xics: map_lpar virq %d, hwirq 0x%lx, flags: 0x%x\n",
-                virq, hw, flags);
-
-       if (sense && sense != IRQ_TYPE_LEVEL_LOW)
-               printk(KERN_WARNING "xics: using unsupported sense 0x%x"
-                      " for irq %d (h: 0x%lx)\n", flags, virq, hw);
+       pr_debug("xics: map_direct virq %d, hwirq 0x%lx\n", virq, hw);
 
        get_irq_desc(virq)->status |= IRQ_LEVEL;
        set_irq_chip_and_handler(virq, &xics_pic_lpar, handle_fasteoi_irq);
@@ -757,7 +723,7 @@ void xics_request_IPIs(void)
 {
        unsigned int ipi;
 
-       ipi = irq_create_mapping(xics_host, XICS_IPI, 0);
+       ipi = irq_create_mapping(xics_host, XICS_IPI);
        BUG_ON(ipi == NO_IRQ);
 
        /*
@@ -782,6 +748,14 @@ void xics_teardown_cpu(int secondary)
 
        xics_set_cpu_priority(cpu, 0);
 
+       /*
+        * Clear IPI
+        */
+       if (firmware_has_feature(FW_FEATURE_LPAR))
+               lpar_qirr_info(cpu, 0xff);
+       else
+               direct_qirr_info(cpu, 0xff);
+
        /*
         * we need to EOI the IPI if we got here from kexec down IPI
         *
@@ -795,14 +769,14 @@ void xics_teardown_cpu(int secondary)
                return;
        desc = get_irq_desc(ipi);
        if (desc->chip && desc->chip->eoi)
-               desc->chip->eoi(XICS_IPI);
+               desc->chip->eoi(ipi);
 
        /*
         * Some machines need to have at least one cpu in the GIQ,
         * so leave the master cpu in the group.
         */
        if (secondary)
-               rtas_set_indicator(GLOBAL_INTERRUPT_QUEUE,
+               rtas_set_indicator_fast(GLOBAL_INTERRUPT_QUEUE,
                                   (1UL << interrupt_server_size) - 1 -
                                   default_distrib_server, 0);
 }
@@ -819,7 +793,7 @@ void xics_migrate_irqs_away(void)
        xics_set_cpu_priority(cpu, 0);
 
        /* remove ourselves from the global interrupt queue */
-       status = rtas_set_indicator(GLOBAL_INTERRUPT_QUEUE,
+       status = rtas_set_indicator_fast(GLOBAL_INTERRUPT_QUEUE,
                (1UL << interrupt_server_size) - 1 - default_distrib_server, 0);
        WARN_ON(status < 0);