1 /* 1 /* 2 * Copyright (C) 2007-2009 Michal Simek <monst << 3 * Copyright (C) 2007-2009 PetaLogix << 4 * Copyright (C) 2006 Atmark Techno, Inc. << 5 * << 6 * This file is subject to the terms and condi 2 * This file is subject to the terms and conditions of the GNU General Public 7 * License. See the file "COPYING" in the main !! 3 * License. See the file "COPYING" in the main directory of this archive 8 * for more details. 4 * for more details. >> 5 * >> 6 * Code to handle x86 style IRQs plus some generic interrupt stuff. >> 7 * >> 8 * Copyright (C) 1992 Linus Torvalds >> 9 * Copyright (C) 1994 - 2000 Ralf Baechle 9 */ 10 */ 10 << 11 #include <linux/init.h> << 12 #include <linux/ftrace.h> << 13 #include <linux/kernel.h> 11 #include <linux/kernel.h> 14 #include <linux/hardirq.h> !! 12 #include <linux/delay.h> >> 13 #include <linux/init.h> 15 #include <linux/interrupt.h> 14 #include <linux/interrupt.h> 16 #include <linux/irqflags.h> << 17 #include <linux/seq_file.h> << 18 #include <linux/kernel_stat.h> 15 #include <linux/kernel_stat.h> 19 #include <linux/irq.h> !! 16 #include <linux/proc_fs.h> 20 #include <linux/irqchip.h> !! 17 #include <linux/mm.h> 21 #include <linux/of_irq.h> !! 18 #include <linux/random.h> >> 19 #include <linux/sched.h> >> 20 #include <linux/seq_file.h> >> 21 #include <linux/kallsyms.h> >> 22 #include <linux/kgdb.h> >> 23 #include <linux/ftrace.h> >> 24 #include <linux/irqdomain.h> >> 25 >> 26 #include <linux/atomic.h> >> 27 #include <linux/uaccess.h> 22 28 23 void __irq_entry do_IRQ(struct pt_regs *regs) !! 29 void *irq_stack[NR_CPUS]; >> 30 >> 31 /* >> 32 * 'what should we do if we get a hw irq event on an illegal vector'. >> 33 * each architecture has to answer this themselves. >> 34 */ >> 35 void ack_bad_irq(unsigned int irq) >> 36 { >> 37 printk("unexpected IRQ # %d\n", irq); >> 38 } >> 39 >> 40 atomic_t irq_err_count; >> 41 >> 42 int arch_show_interrupts(struct seq_file *p, int prec) 24 { 43 { 25 struct pt_regs *old_regs = set_irq_reg !! 44 seq_printf(p, "%*s: %10u\n", prec, "ERR", atomic_read(&irq_err_count)); 26 trace_hardirqs_off(); !! 45 return 0; >> 46 } >> 47 >> 48 asmlinkage void spurious_interrupt(void) >> 49 { >> 50 atomic_inc(&irq_err_count); >> 51 } 27 52 >> 53 void __init init_IRQ(void) >> 54 { >> 55 int i; >> 56 unsigned int order = get_order(IRQ_STACK_SIZE); >> 57 >> 58 for (i = 0; i < NR_IRQS; i++) >> 59 irq_set_noprobe(i); >> 60 >> 61 if (cpu_has_veic) >> 62 clear_c0_status(ST0_IM); >> 63 >> 64 arch_init_irq(); >> 65 >> 66 for_each_possible_cpu(i) { >> 67 void *s = (void *)__get_free_pages(GFP_KERNEL, order); >> 68 >> 69 irq_stack[i] = s; >> 70 pr_debug("CPU%d IRQ stack at 0x%p - 0x%p\n", i, >> 71 irq_stack[i], irq_stack[i] + IRQ_STACK_SIZE); >> 72 } >> 73 } >> 74 >> 75 #ifdef CONFIG_DEBUG_STACKOVERFLOW >> 76 static inline void check_stack_overflow(void) >> 77 { >> 78 unsigned long sp; >> 79 >> 80 __asm__ __volatile__("move %0, $sp" : "=r" (sp)); >> 81 sp &= THREAD_MASK; >> 82 >> 83 /* >> 84 * Check for stack overflow: is there less than STACK_WARN free? >> 85 * STACK_WARN is defined as 1/8 of THREAD_SIZE by default. >> 86 */ >> 87 if (unlikely(sp < (sizeof(struct thread_info) + STACK_WARN))) { >> 88 printk("do_IRQ: stack overflow: %ld\n", >> 89 sp - sizeof(struct thread_info)); >> 90 dump_stack(); >> 91 } >> 92 } >> 93 #else >> 94 static inline void check_stack_overflow(void) {} >> 95 #endif >> 96 >> 97 >> 98 /* >> 99 * do_IRQ handles all normal device IRQ's (the special >> 100 * SMP cross-CPU interrupts have their own specific >> 101 * handlers). >> 102 */ >> 103 void __irq_entry do_IRQ(unsigned int irq) >> 104 { 28 irq_enter(); 105 irq_enter(); 29 handle_arch_irq(regs); !! 106 check_stack_overflow(); >> 107 generic_handle_irq(irq); 30 irq_exit(); 108 irq_exit(); 31 set_irq_regs(old_regs); << 32 trace_hardirqs_on(); << 33 } 109 } 34 110 35 void __init init_IRQ(void) !! 111 #ifdef CONFIG_IRQ_DOMAIN >> 112 void __irq_entry do_domain_IRQ(struct irq_domain *domain, unsigned int hwirq) 36 { 113 { 37 /* process the entire interrupt tree i !! 114 irq_enter(); 38 irqchip_init(); !! 115 check_stack_overflow(); >> 116 generic_handle_domain_irq(domain, hwirq); >> 117 irq_exit(); 39 } 118 } >> 119 #endif 40 120
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.