Skip to content

Commit

Permalink
When CONFIG_PM is enabled, it uses the TOY_MATCH2 interrupt as the sy…
Browse files Browse the repository at this point in the history
…stem

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>
  • Loading branch information
Pete Popov authored and Ralf Baechle committed Oct 29, 2005
1 parent 90a67b5 commit a3701ca
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 15 deletions.
36 changes: 24 additions & 12 deletions arch/mips/au1000/common/irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -293,8 +293,30 @@ static struct hw_interrupt_type level_irq_type = {
};

#ifdef CONFIG_PM
void startup_match20_interrupt(void)
void startup_match20_interrupt(void (*handler)(int, void *, struct pt_regs *))
{
static struct irqaction action;
/* This is a big problem.... since we didn't use request_irq
when kernel/irq.c calls probe_irq_xxx this interrupt will
be probed for usage. This will end up disabling the device :(
Give it a bogus "action" pointer -- this will keep it from
getting auto-probed!
By setting the status to match that of request_irq() we
can avoid it. --cgray
*/
action.dev_id = handler;
action.flags = 0;
action.mask = 0;
action.name = "Au1xxx TOY";
action.handler = handler;
action.next = NULL;

irq_desc[AU1000_TOY_MATCH2_INT].action = &action;
irq_desc[AU1000_TOY_MATCH2_INT].status
&= ~(IRQ_DISABLED | IRQ_AUTODETECT | IRQ_WAITING | IRQ_INPROGRESS);

local_enable_irq(AU1000_TOY_MATCH2_INT);
}
#endif
Expand Down Expand Up @@ -517,17 +539,7 @@ void intc0_req1_irqdispatch(struct pt_regs *regs)

irq = au_ffs(intc0_req1) - 1;
intc0_req1 &= ~(1<<irq);
#ifdef CONFIG_PM
if (irq == AU1000_TOY_MATCH2_INT) {
mask_and_ack_rise_edge_irq(irq);
counter0_irq(irq, NULL, regs);
local_enable_irq(irq);
}
else
#endif
{
do_IRQ(irq, regs);
}
do_IRQ(irq, regs);
}


Expand Down
5 changes: 2 additions & 3 deletions arch/mips/au1000/common/time.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@
#include <linux/mc146818rtc.h>
#include <linux/timex.h>

extern void startup_match20_interrupt(void);
extern void do_softirq(void);
extern volatile unsigned long wall_jiffies;
unsigned long missed_heart_beats = 0;
Expand All @@ -65,7 +64,7 @@ static unsigned int timerhi = 0, timerlo = 0;

#ifdef CONFIG_PM
#define MATCH20_INC 328
extern void startup_match20_interrupt(void);
extern void startup_match20_interrupt(void (*handler)(int, void *, struct pt_regs *));
static unsigned long last_pc0, last_match20;
#endif

Expand Down Expand Up @@ -446,7 +445,7 @@ void au1xxx_timer_setup(struct irqaction *irq)
au_writel(last_match20 + MATCH20_INC, SYS_TOYMATCH2);
au_sync();
while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20);
startup_match20_interrupt();
startup_match20_interrupt(counter0_irq);

do_gettimeoffset = do_fast_pm_gettimeoffset;

Expand Down

0 comments on commit a3701ca

Please sign in to comment.