1*eedbdab9SMichal Simek /* 2*eedbdab9SMichal Simek * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu> 3*eedbdab9SMichal Simek * Copyright (C) 2007-2009 PetaLogix 4*eedbdab9SMichal Simek * Copyright (C) 2006 Atmark Techno, Inc. 5*eedbdab9SMichal Simek * 6*eedbdab9SMichal Simek * This file is subject to the terms and conditions of the GNU General Public 7*eedbdab9SMichal Simek * License. See the file "COPYING" in the main directory of this archive 8*eedbdab9SMichal Simek * for more details. 9*eedbdab9SMichal Simek */ 10*eedbdab9SMichal Simek 11*eedbdab9SMichal Simek #include <linux/init.h> 12*eedbdab9SMichal Simek #include <linux/kernel.h> 13*eedbdab9SMichal Simek #include <linux/hardirq.h> 14*eedbdab9SMichal Simek #include <linux/interrupt.h> 15*eedbdab9SMichal Simek #include <linux/irqflags.h> 16*eedbdab9SMichal Simek #include <linux/seq_file.h> 17*eedbdab9SMichal Simek #include <linux/kernel_stat.h> 18*eedbdab9SMichal Simek #include <linux/irq.h> 19*eedbdab9SMichal Simek 20*eedbdab9SMichal Simek #include <asm/prom.h> 21*eedbdab9SMichal Simek 22*eedbdab9SMichal Simek unsigned int irq_of_parse_and_map(struct device_node *dev, int index) 23*eedbdab9SMichal Simek { 24*eedbdab9SMichal Simek struct of_irq oirq; 25*eedbdab9SMichal Simek 26*eedbdab9SMichal Simek if (of_irq_map_one(dev, index, &oirq)) 27*eedbdab9SMichal Simek return NO_IRQ; 28*eedbdab9SMichal Simek 29*eedbdab9SMichal Simek return oirq.specifier[0]; 30*eedbdab9SMichal Simek } 31*eedbdab9SMichal Simek EXPORT_SYMBOL_GPL(irq_of_parse_and_map); 32*eedbdab9SMichal Simek 33*eedbdab9SMichal Simek /* 34*eedbdab9SMichal Simek * 'what should we do if we get a hw irq event on an illegal vector'. 35*eedbdab9SMichal Simek * each architecture has to answer this themselves. 36*eedbdab9SMichal Simek */ 37*eedbdab9SMichal Simek void ack_bad_irq(unsigned int irq) 38*eedbdab9SMichal Simek { 39*eedbdab9SMichal Simek printk(KERN_WARNING "unexpected IRQ trap at vector %02x\n", irq); 40*eedbdab9SMichal Simek } 41*eedbdab9SMichal Simek 42*eedbdab9SMichal Simek static u32 concurrent_irq; 43*eedbdab9SMichal Simek 44*eedbdab9SMichal Simek void do_IRQ(struct pt_regs *regs) 45*eedbdab9SMichal Simek { 46*eedbdab9SMichal Simek unsigned int irq; 47*eedbdab9SMichal Simek struct pt_regs *old_regs = set_irq_regs(regs); 48*eedbdab9SMichal Simek 49*eedbdab9SMichal Simek irq_enter(); 50*eedbdab9SMichal Simek irq = get_irq(regs); 51*eedbdab9SMichal Simek next_irq: 52*eedbdab9SMichal Simek BUG_ON(irq == -1U); 53*eedbdab9SMichal Simek generic_handle_irq(irq); 54*eedbdab9SMichal Simek 55*eedbdab9SMichal Simek irq = get_irq(regs); 56*eedbdab9SMichal Simek if (irq != -1U) { 57*eedbdab9SMichal Simek pr_debug("next irq: %d\n", irq); 58*eedbdab9SMichal Simek ++concurrent_irq; 59*eedbdab9SMichal Simek goto next_irq; 60*eedbdab9SMichal Simek } 61*eedbdab9SMichal Simek 62*eedbdab9SMichal Simek irq_exit(); 63*eedbdab9SMichal Simek set_irq_regs(old_regs); 64*eedbdab9SMichal Simek } 65*eedbdab9SMichal Simek 66*eedbdab9SMichal Simek int show_interrupts(struct seq_file *p, void *v) 67*eedbdab9SMichal Simek { 68*eedbdab9SMichal Simek int i = *(loff_t *) v, j; 69*eedbdab9SMichal Simek struct irqaction *action; 70*eedbdab9SMichal Simek unsigned long flags; 71*eedbdab9SMichal Simek 72*eedbdab9SMichal Simek if (i == 0) { 73*eedbdab9SMichal Simek seq_printf(p, " "); 74*eedbdab9SMichal Simek for_each_online_cpu(j) 75*eedbdab9SMichal Simek seq_printf(p, "CPU%-8d", j); 76*eedbdab9SMichal Simek seq_putc(p, '\n'); 77*eedbdab9SMichal Simek } 78*eedbdab9SMichal Simek 79*eedbdab9SMichal Simek if (i < nr_irq) { 80*eedbdab9SMichal Simek spin_lock_irqsave(&irq_desc[i].lock, flags); 81*eedbdab9SMichal Simek action = irq_desc[i].action; 82*eedbdab9SMichal Simek if (!action) 83*eedbdab9SMichal Simek goto skip; 84*eedbdab9SMichal Simek seq_printf(p, "%3d: ", i); 85*eedbdab9SMichal Simek #ifndef CONFIG_SMP 86*eedbdab9SMichal Simek seq_printf(p, "%10u ", kstat_irqs(i)); 87*eedbdab9SMichal Simek #else 88*eedbdab9SMichal Simek for_each_online_cpu(j) 89*eedbdab9SMichal Simek seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); 90*eedbdab9SMichal Simek #endif 91*eedbdab9SMichal Simek seq_printf(p, " %8s", irq_desc[i].status & 92*eedbdab9SMichal Simek IRQ_LEVEL ? "level" : "edge"); 93*eedbdab9SMichal Simek seq_printf(p, " %8s", irq_desc[i].chip->name); 94*eedbdab9SMichal Simek seq_printf(p, " %s", action->name); 95*eedbdab9SMichal Simek 96*eedbdab9SMichal Simek for (action = action->next; action; action = action->next) 97*eedbdab9SMichal Simek seq_printf(p, ", %s", action->name); 98*eedbdab9SMichal Simek 99*eedbdab9SMichal Simek seq_putc(p, '\n'); 100*eedbdab9SMichal Simek skip: 101*eedbdab9SMichal Simek spin_unlock_irqrestore(&irq_desc[i].lock, flags); 102*eedbdab9SMichal Simek } 103*eedbdab9SMichal Simek return 0; 104*eedbdab9SMichal Simek } 105