]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] ppc32: Fix an IRQ issue with cpufreq
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>
Thu, 25 Nov 2004 08:00:14 +0000 (00:00 -0800)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Thu, 25 Nov 2004 08:00:14 +0000 (00:00 -0800)
The ppc32 PowerMac cpufreq code, when using the PMU to switch the
frequency, would eventually lose interrupts.  The solution is to raise the
CPU priority at the controller level.  It's also unnecessary to call the
full PIC suspend/resume code in this case as the IO chip isn't reset,
unlike the sleep code.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
arch/ppc/platforms/pmac_cpufreq.c
arch/ppc/syslib/open_pic.c
include/asm-ppc/open_pic.h

index c50aa7fd195827b45adabac8cf9bab12cc153cb0..6c0b093c482baae176eca1dc53c4bd4bfe2a6d8f 100644 (file)
@@ -33,6 +33,8 @@
 #include <asm/sections.h>
 #include <asm/cputable.h>
 #include <asm/time.h>
+#include <asm/system.h>
+#include <asm/open_pic.h>
 
 /* WARNING !!! This will cause calibrate_delay() to be called,
  * but this is an __init function ! So you MUST go edit
 extern void low_choose_7447a_dfs(int dfs);
 extern void low_choose_750fx_pll(int pll);
 extern void low_sleep_handler(void);
-extern void openpic_suspend(struct sys_device *sysdev, u32 state);
-extern void openpic_resume(struct sys_device *sysdev);
-extern void enable_kernel_altivec(void);
-extern void enable_kernel_fp(void);
 
 /*
  * Currently, PowerMac cpufreq supports only high & low frequencies
@@ -208,7 +206,7 @@ static int __pmac pmu_set_cpu_speed(int low_speed)
        printk(KERN_DEBUG "HID1, before: %x\n", mfspr(SPRN_HID1));
 #endif
        /* Disable all interrupt sources on openpic */
-       openpic_suspend(NULL, 1);
+       openpic_set_priority(0xf);
 
        /* Make sure the decrementer won't interrupt us */
        asm volatile("mtdec %0" : : "r" (0x7fffffff));
@@ -275,7 +273,7 @@ static int __pmac pmu_set_cpu_speed(int low_speed)
        wakeup_decrementer();
 
        /* Restore interrupts */
-       openpic_resume(NULL);
+       openpic_set_priority(0);
 
        /* Let interrupts flow again ... */
        local_irq_enable();
index bc5c46a306406d0b3ea444f08c54abe34c52c10d..c900bf9d41a01691c51a1b3fb65a72a3095b9514 100644 (file)
@@ -53,7 +53,6 @@ static int (*openpic_cascade_fn)(struct pt_regs *);
 
 /* Global Operations */
 static void openpic_disable_8259_pass_through(void);
-static void openpic_set_priority(u_int pri);
 static void openpic_set_spurious(u_int vector);
 
 #ifdef CONFIG_SMP
@@ -477,7 +476,7 @@ static u_int openpic_get_priority(void)
 }
 #endif /* notused */
 
-static void __init openpic_set_priority(u_int pri)
+void openpic_set_priority(u_int pri)
 {
        DECL_THIS_CPU;
 
@@ -955,6 +954,8 @@ int openpic_suspend(struct sys_device *sysdev, u32 state)
                return 0;
        }
 
+       openpic_set_priority(0xf);
+
        open_pic.enable = openpic_cached_enable_irq;
        open_pic.disable = openpic_cached_disable_irq;
 
@@ -1028,6 +1029,8 @@ int openpic_resume(struct sys_device *sysdev)
        open_pic.enable = openpic_enable_irq;
        open_pic.disable = openpic_disable_irq;
 
+       openpic_set_priority(0);
+
        spin_unlock_irqrestore(&openpic_setup_lock, flags);
 
        return 0;
index 6d5130bbdbd5e5059a73a5f6a5ee836cc0bacf59..cc238f5b9e1eae4b77db47fd60e702e3b3e8e7ed 100644 (file)
@@ -55,6 +55,7 @@ extern void openpic_cause_IPI(u_int ipi, cpumask_t cpumask);
 extern void smp_openpic_message_pass(int target, int msg, unsigned long data,
                                     int wait);
 extern void openpic_set_k2_cascade(int irq);
+extern void openpic_set_priority(u_int pri);
 
 extern inline int openpic_to_irq(int irq)
 {