Commit 3b720a8b authored by Benjamin Herrenschmidt's avatar Benjamin Herrenschmidt Committed by Linus Torvalds

[PATCH] ppc32: Fix an IRQ issue with cpufreq

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: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 7b254f6b
...@@ -33,6 +33,8 @@ ...@@ -33,6 +33,8 @@
#include <asm/sections.h> #include <asm/sections.h>
#include <asm/cputable.h> #include <asm/cputable.h>
#include <asm/time.h> #include <asm/time.h>
#include <asm/system.h>
#include <asm/open_pic.h>
/* WARNING !!! This will cause calibrate_delay() to be called, /* WARNING !!! This will cause calibrate_delay() to be called,
* but this is an __init function ! So you MUST go edit * but this is an __init function ! So you MUST go edit
...@@ -51,10 +53,6 @@ ...@@ -51,10 +53,6 @@
extern void low_choose_7447a_dfs(int dfs); extern void low_choose_7447a_dfs(int dfs);
extern void low_choose_750fx_pll(int pll); extern void low_choose_750fx_pll(int pll);
extern void low_sleep_handler(void); 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 * Currently, PowerMac cpufreq supports only high & low frequencies
...@@ -208,7 +206,7 @@ static int __pmac pmu_set_cpu_speed(int low_speed) ...@@ -208,7 +206,7 @@ static int __pmac pmu_set_cpu_speed(int low_speed)
printk(KERN_DEBUG "HID1, before: %x\n", mfspr(SPRN_HID1)); printk(KERN_DEBUG "HID1, before: %x\n", mfspr(SPRN_HID1));
#endif #endif
/* Disable all interrupt sources on openpic */ /* Disable all interrupt sources on openpic */
openpic_suspend(NULL, 1); openpic_set_priority(0xf);
/* Make sure the decrementer won't interrupt us */ /* Make sure the decrementer won't interrupt us */
asm volatile("mtdec %0" : : "r" (0x7fffffff)); asm volatile("mtdec %0" : : "r" (0x7fffffff));
...@@ -275,7 +273,7 @@ static int __pmac pmu_set_cpu_speed(int low_speed) ...@@ -275,7 +273,7 @@ static int __pmac pmu_set_cpu_speed(int low_speed)
wakeup_decrementer(); wakeup_decrementer();
/* Restore interrupts */ /* Restore interrupts */
openpic_resume(NULL); openpic_set_priority(0);
/* Let interrupts flow again ... */ /* Let interrupts flow again ... */
local_irq_enable(); local_irq_enable();
......
...@@ -53,7 +53,6 @@ static int (*openpic_cascade_fn)(struct pt_regs *); ...@@ -53,7 +53,6 @@ static int (*openpic_cascade_fn)(struct pt_regs *);
/* Global Operations */ /* Global Operations */
static void openpic_disable_8259_pass_through(void); static void openpic_disable_8259_pass_through(void);
static void openpic_set_priority(u_int pri);
static void openpic_set_spurious(u_int vector); static void openpic_set_spurious(u_int vector);
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
...@@ -477,7 +476,7 @@ static u_int openpic_get_priority(void) ...@@ -477,7 +476,7 @@ static u_int openpic_get_priority(void)
} }
#endif /* notused */ #endif /* notused */
static void __init openpic_set_priority(u_int pri) void openpic_set_priority(u_int pri)
{ {
DECL_THIS_CPU; DECL_THIS_CPU;
...@@ -955,6 +954,8 @@ int openpic_suspend(struct sys_device *sysdev, u32 state) ...@@ -955,6 +954,8 @@ int openpic_suspend(struct sys_device *sysdev, u32 state)
return 0; return 0;
} }
openpic_set_priority(0xf);
open_pic.enable = openpic_cached_enable_irq; open_pic.enable = openpic_cached_enable_irq;
open_pic.disable = openpic_cached_disable_irq; open_pic.disable = openpic_cached_disable_irq;
...@@ -1028,6 +1029,8 @@ int openpic_resume(struct sys_device *sysdev) ...@@ -1028,6 +1029,8 @@ int openpic_resume(struct sys_device *sysdev)
open_pic.enable = openpic_enable_irq; open_pic.enable = openpic_enable_irq;
open_pic.disable = openpic_disable_irq; open_pic.disable = openpic_disable_irq;
openpic_set_priority(0);
spin_unlock_irqrestore(&openpic_setup_lock, flags); spin_unlock_irqrestore(&openpic_setup_lock, flags);
return 0; return 0;
......
...@@ -55,6 +55,7 @@ extern void openpic_cause_IPI(u_int ipi, cpumask_t cpumask); ...@@ -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, extern void smp_openpic_message_pass(int target, int msg, unsigned long data,
int wait); int wait);
extern void openpic_set_k2_cascade(int irq); extern void openpic_set_k2_cascade(int irq);
extern void openpic_set_priority(u_int pri);
extern inline int openpic_to_irq(int irq) extern inline int openpic_to_irq(int irq)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment