X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fmips%2Fjmr3927%2Frbhma3100%2Firq.c;h=722174481467e96b31dd314a226f27b78bc70f54;hb=16c70f8c1b54b61c3b951b6fb220df250fe09b32;hp=4ab85b5b2b4d2e1e9f3318e59d1d05b96afeecbd;hpb=9bf4aaab3e101692164d49b7ca357651eb691cb6;p=linux-2.6.git diff --git a/arch/mips/jmr3927/rbhma3100/irq.c b/arch/mips/jmr3927/rbhma3100/irq.c index 4ab85b5b2..722174481 100644 --- a/arch/mips/jmr3927/rbhma3100/irq.c +++ b/arch/mips/jmr3927/rbhma3100/irq.c @@ -29,7 +29,6 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include #include #include @@ -45,8 +44,8 @@ #include #include #include +#include -#include #include #include #include @@ -77,8 +76,6 @@ static int jmr3927_gen_iack(void) } #endif -extern asmlinkage void jmr3927_IRQ(void); - #define irc_dlevel 0 #define irc_elevel 1 @@ -89,38 +86,10 @@ static unsigned char irc_level[TX3927_NUM_IR] = { 6, 6, 6 /* TMR */ }; -static inline void mask_irq(unsigned int irq_nr) -{ - struct tb_irq_space* sp; - for (sp = tb_irq_spaces; sp; sp = sp->next) { - if (sp->start_irqno <= irq_nr && - irq_nr < sp->start_irqno + sp->nr_irqs) { - if (sp->mask_func) - sp->mask_func(irq_nr - sp->start_irqno, - sp->space_id); - break; - } - } -} - -static inline void unmask_irq(unsigned int irq_nr) -{ - struct tb_irq_space* sp; - for (sp = tb_irq_spaces; sp; sp = sp->next) { - if (sp->start_irqno <= irq_nr && - irq_nr < sp->start_irqno + sp->nr_irqs) { - if (sp->unmask_func) - sp->unmask_func(irq_nr - sp->start_irqno, - sp->space_id); - break; - } - } -} - static void jmr3927_irq_disable(unsigned int irq_nr); static void jmr3927_irq_enable(unsigned int irq_nr); -static spinlock_t jmr3927_irq_lock = SPIN_LOCK_UNLOCKED; +static DEFINE_SPINLOCK(jmr3927_irq_lock); static unsigned int jmr3927_irq_startup(unsigned int irq) { @@ -133,34 +102,52 @@ static unsigned int jmr3927_irq_startup(unsigned int irq) static void jmr3927_irq_ack(unsigned int irq) { - if (irq == JMR3927_IRQ_IRC_TMR0) { + if (irq == JMR3927_IRQ_IRC_TMR0) jmr3927_tmrptr->tisr = 0; /* ack interrupt */ - } jmr3927_irq_disable(irq); } static void jmr3927_irq_end(unsigned int irq) { - jmr3927_irq_enable(irq); + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) + jmr3927_irq_enable(irq); } static void jmr3927_irq_disable(unsigned int irq_nr) { + struct tb_irq_space* sp; unsigned long flags; - spinlock_irqsave(&jmr3927_irq_lock, flags); - mask_irq(irq_nr); - spinlock_irqrestore(&jmr3927_irq_lock, flags); + spin_lock_irqsave(&jmr3927_irq_lock, flags); + for (sp = tb_irq_spaces; sp; sp = sp->next) { + if (sp->start_irqno <= irq_nr && + irq_nr < sp->start_irqno + sp->nr_irqs) { + if (sp->mask_func) + sp->mask_func(irq_nr - sp->start_irqno, + sp->space_id); + break; + } + } + spin_unlock_irqrestore(&jmr3927_irq_lock, flags); } static void jmr3927_irq_enable(unsigned int irq_nr) { + struct tb_irq_space* sp; unsigned long flags; - spinlock_irqsave(&jmr3927_irq_lock, flags); - unmask_irq(irq_nr); - spinlock_irqrestore(&jmr3927_irq_lock, flags); + spin_lock_irqsave(&jmr3927_irq_lock, flags); + for (sp = tb_irq_spaces; sp; sp = sp->next) { + if (sp->start_irqno <= irq_nr && + irq_nr < sp->start_irqno + sp->nr_irqs) { + if (sp->unmask_func) + sp->unmask_func(irq_nr - sp->start_irqno, + sp->space_id); + break; + } + } + spin_unlock_irqrestore(&jmr3927_irq_lock, flags); } /* @@ -216,7 +203,10 @@ static void mask_irq_irc(int irq_nr, int space_id) /* update IRCSR */ tx3927_ircptr->imr = 0; tx3927_ircptr->imr = irc_elevel; + /* flush write buffer */ + (void)tx3927_ircptr->ssr; } + static void unmask_irq_irc(int irq_nr, int space_id) { volatile unsigned long *ilrp = &tx3927_ircptr->ilr[irq_nr / 2]; @@ -269,7 +259,7 @@ void jmr3927_spurious(struct pt_regs *regs) regs->cp0_cause, regs->cp0_epc, regs->regs[31]); } -void jmr3927_irc_irqdispatch(struct pt_regs *regs) +asmlinkage void plat_irq_dispatch(struct pt_regs *regs) { int irq; @@ -287,7 +277,7 @@ void jmr3927_irc_irqdispatch(struct pt_regs *regs) do_IRQ(irq + JMR3927_IRQ_IRC, regs); } -static void jmr3927_ioc_interrupt(int irq, void *dev_id, struct pt_regs *regs) +static irqreturn_t jmr3927_ioc_interrupt(int irq, void *dev_id, struct pt_regs *regs) { unsigned char istat = jmr3927_ioc_reg_in(JMR3927_IOC_INTS2_ADDR); int i; @@ -298,13 +288,14 @@ static void jmr3927_ioc_interrupt(int irq, void *dev_id, struct pt_regs *regs) do_IRQ(irq, regs); } } + return IRQ_HANDLED; } static struct irqaction ioc_action = { jmr3927_ioc_interrupt, 0, CPU_MASK_NONE, "IOC", NULL, NULL, }; -static void jmr3927_isac_interrupt(int irq, void *dev_id, struct pt_regs *regs) +static irqreturn_t jmr3927_isac_interrupt(int irq, void *dev_id, struct pt_regs *regs) { unsigned char istat = jmr3927_isac_reg_in(JMR3927_ISAC_INTS2_ADDR); int i; @@ -315,6 +306,7 @@ static void jmr3927_isac_interrupt(int irq, void *dev_id, struct pt_regs *regs) do_IRQ(irq, regs); } } + return IRQ_HANDLED; } static struct irqaction isac_action = { @@ -322,19 +314,23 @@ static struct irqaction isac_action = { }; -static void jmr3927_isaerr_interrupt(int irq, void * dev_id, struct pt_regs * regs) +static irqreturn_t jmr3927_isaerr_interrupt(int irq, void * dev_id, struct pt_regs * regs) { printk(KERN_WARNING "ISA error interrupt (irq 0x%x).\n", irq); + + return IRQ_HANDLED; } static struct irqaction isaerr_action = { jmr3927_isaerr_interrupt, 0, CPU_MASK_NONE, "ISA error", NULL, NULL, }; -static void jmr3927_pcierr_interrupt(int irq, void * dev_id, struct pt_regs * regs) +static irqreturn_t jmr3927_pcierr_interrupt(int irq, void * dev_id, struct pt_regs * regs) { printk(KERN_WARNING "PCI error interrupt (irq 0x%x).\n", irq); printk(KERN_WARNING "pcistat:%02x, lbstat:%04lx\n", tx3927_pcicptr->pcistat, tx3927_pcicptr->lbstat); + + return IRQ_HANDLED; } static struct irqaction pcierr_action = { jmr3927_pcierr_interrupt, 0, CPU_MASK_NONE, "PCI error", NULL, NULL, @@ -343,7 +339,8 @@ static struct irqaction pcierr_action = { int jmr3927_ether1_irq = 0; void jmr3927_irq_init(u32 irq_base); -void jmr3927_irq_setup(void) + +void __init arch_init_irq(void) { /* look for io board's presence */ int have_isac = jmr3927_have_isac(); @@ -398,8 +395,6 @@ void jmr3927_irq_setup(void) jmr3927_irq_init(NR_ISA_IRQS); - set_except_vector(0, jmr3927_IRQ); - /* setup irq space */ add_tb_irq_space(&jmr3927_isac_irqspace); add_tb_irq_space(&jmr3927_ioc_irqspace); @@ -421,44 +416,25 @@ void jmr3927_irq_setup(void) set_c0_status(ST0_IM); /* IE bit is still 0. */ } -void (*irq_setup)(void); - -void __init init_IRQ(void) -{ - -#ifdef CONFIG_KGDB - extern void breakpoint(void); - extern void set_debug_traps(void); - - puts("Wait for gdb client connection ...\n"); - set_debug_traps(); - breakpoint(); -#endif - - /* invoke board-specific irq setup */ - irq_setup(); -} - -static hw_irq_controller jmr3927_irq_controller = { - "jmr3927_irq", - jmr3927_irq_startup, - jmr3927_irq_shutdown, - jmr3927_irq_enable, - jmr3927_irq_disable, - jmr3927_irq_ack, - jmr3927_irq_end, +static struct irq_chip jmr3927_irq_controller = { + .typename = "jmr3927_irq", + .startup = jmr3927_irq_startup, + .shutdown = jmr3927_irq_shutdown, + .enable = jmr3927_irq_enable, + .disable = jmr3927_irq_disable, + .ack = jmr3927_irq_ack, + .end = jmr3927_irq_end, }; void jmr3927_irq_init(u32 irq_base) { u32 i; - init_generic_irq(); for (i= irq_base; i< irq_base + JMR3927_NR_IRQ_IRC + JMR3927_NR_IRQ_IOC; i++) { irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = NULL; irq_desc[i].depth = 1; - irq_desc[i].handler = &jmr3927_irq_controller; + irq_desc[i].chip = &jmr3927_irq_controller; } jmr3927_irq_base = irq_base;