aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPete Popov <ppopov@embeddedalley.com>2005-03-13 03:19:05 -0500
committerRalf Baechle <ralf@linux-mips.org>2005-10-29 14:30:56 -0400
commita3701ca48763bbc681ee8db3d203827975849185 (patch)
tree9677ce80fb2dd3db49394665ddd1ca4f3bf8f2d5
parent90a67b5909ed39425fd2402b2b4c46ef1372b300 (diff)
When CONFIG_PM is enabled, it uses the TOY_MATCH2 interrupt as the system
timer tick. Prior to this patch, if IDE IRQ probing occured, then the TOY_MATCH2 interrupt would be permanently disabled, and no system timer tick occurs. This patch corrects this situation by correctly registering the TOY_MATCH2 interrupt so that IDE IRQ probing doesn't have adverse side effects. Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-rw-r--r--arch/mips/au1000/common/irq.c36
-rw-r--r--arch/mips/au1000/common/time.c5
2 files changed, 26 insertions, 15 deletions
diff --git a/arch/mips/au1000/common/irq.c b/arch/mips/au1000/common/irq.c
index ebf93bdbad14..6a25677bf3cb 100644
--- a/arch/mips/au1000/common/irq.c
+++ b/arch/mips/au1000/common/irq.c
@@ -293,8 +293,30 @@ static struct hw_interrupt_type level_irq_type = {
293}; 293};
294 294
295#ifdef CONFIG_PM 295#ifdef CONFIG_PM
296void startup_match20_interrupt(void) 296void startup_match20_interrupt(void (*handler)(int, void *, struct pt_regs *))
297{ 297{
298 static struct irqaction action;
299 /* This is a big problem.... since we didn't use request_irq
300 when kernel/irq.c calls probe_irq_xxx this interrupt will
301 be probed for usage. This will end up disabling the device :(
302
303 Give it a bogus "action" pointer -- this will keep it from
304 getting auto-probed!
305
306 By setting the status to match that of request_irq() we
307 can avoid it. --cgray
308 */
309 action.dev_id = handler;
310 action.flags = 0;
311 action.mask = 0;
312 action.name = "Au1xxx TOY";
313 action.handler = handler;
314 action.next = NULL;
315
316 irq_desc[AU1000_TOY_MATCH2_INT].action = &action;
317 irq_desc[AU1000_TOY_MATCH2_INT].status
318 &= ~(IRQ_DISABLED | IRQ_AUTODETECT | IRQ_WAITING | IRQ_INPROGRESS);
319
298 local_enable_irq(AU1000_TOY_MATCH2_INT); 320 local_enable_irq(AU1000_TOY_MATCH2_INT);
299} 321}
300#endif 322#endif
@@ -517,17 +539,7 @@ void intc0_req1_irqdispatch(struct pt_regs *regs)
517 539
518 irq = au_ffs(intc0_req1) - 1; 540 irq = au_ffs(intc0_req1) - 1;
519 intc0_req1 &= ~(1<<irq); 541 intc0_req1 &= ~(1<<irq);
520#ifdef CONFIG_PM 542 do_IRQ(irq, regs);
521 if (irq == AU1000_TOY_MATCH2_INT) {
522 mask_and_ack_rise_edge_irq(irq);
523 counter0_irq(irq, NULL, regs);
524 local_enable_irq(irq);
525 }
526 else
527#endif
528 {
529 do_IRQ(irq, regs);
530 }
531} 543}
532 544
533 545
diff --git a/arch/mips/au1000/common/time.c b/arch/mips/au1000/common/time.c
index 57675b41480e..90a0755c832b 100644
--- a/arch/mips/au1000/common/time.c
+++ b/arch/mips/au1000/common/time.c
@@ -50,7 +50,6 @@
50#include <linux/mc146818rtc.h> 50#include <linux/mc146818rtc.h>
51#include <linux/timex.h> 51#include <linux/timex.h>
52 52
53extern void startup_match20_interrupt(void);
54extern void do_softirq(void); 53extern void do_softirq(void);
55extern volatile unsigned long wall_jiffies; 54extern volatile unsigned long wall_jiffies;
56unsigned long missed_heart_beats = 0; 55unsigned long missed_heart_beats = 0;
@@ -65,7 +64,7 @@ static unsigned int timerhi = 0, timerlo = 0;
65 64
66#ifdef CONFIG_PM 65#ifdef CONFIG_PM
67#define MATCH20_INC 328 66#define MATCH20_INC 328
68extern void startup_match20_interrupt(void); 67extern void startup_match20_interrupt(void (*handler)(int, void *, struct pt_regs *));
69static unsigned long last_pc0, last_match20; 68static unsigned long last_pc0, last_match20;
70#endif 69#endif
71 70
@@ -446,7 +445,7 @@ void au1xxx_timer_setup(struct irqaction *irq)
446 au_writel(last_match20 + MATCH20_INC, SYS_TOYMATCH2); 445 au_writel(last_match20 + MATCH20_INC, SYS_TOYMATCH2);
447 au_sync(); 446 au_sync();
448 while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20); 447 while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20);
449 startup_match20_interrupt(); 448 startup_match20_interrupt(counter0_irq);
450 449
451 do_gettimeoffset = do_fast_pm_gettimeoffset; 450 do_gettimeoffset = do_fast_pm_gettimeoffset;
452 451