1 // SPDX-License-Identifier: GPL-2.0 !! 1 /* 2 // Copyright (C) 2018 Hangzhou C-SKY Microsyst !! 2 * This file is subject to the terms and conditions of the GNU General Public 3 !! 3 * License. See the file "COPYING" in the main directory of this archive >> 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 >> 10 */ >> 11 #include <linux/kernel.h> >> 12 #include <linux/delay.h> 4 #include <linux/init.h> 13 #include <linux/init.h> 5 #include <linux/interrupt.h> 14 #include <linux/interrupt.h> 6 #include <linux/irq.h> !! 15 #include <linux/kernel_stat.h> 7 #include <linux/irqchip.h> !! 16 #include <linux/module.h> 8 #include <asm/traps.h> !! 17 #include <linux/proc_fs.h> 9 #include <asm/smp.h> !! 18 #include <linux/slab.h> >> 19 #include <linux/mm.h> >> 20 #include <linux/random.h> >> 21 #include <linux/sched.h> >> 22 #include <linux/seq_file.h> >> 23 #include <linux/kallsyms.h> >> 24 #include <linux/kgdb.h> >> 25 >> 26 #include <asm/atomic.h> >> 27 #include <asm/system.h> >> 28 #include <asm/uaccess.h> >> 29 >> 30 #ifdef CONFIG_KGDB >> 31 int kgdb_early_setup; >> 32 #endif >> 33 >> 34 static unsigned long irq_map[NR_IRQS / BITS_PER_LONG]; >> 35 >> 36 int allocate_irqno(void) >> 37 { >> 38 int irq; >> 39 >> 40 again: >> 41 irq = find_first_zero_bit(irq_map, NR_IRQS); >> 42 >> 43 if (irq >= NR_IRQS) >> 44 return -ENOSPC; >> 45 >> 46 if (test_and_set_bit(irq, irq_map)) >> 47 goto again; >> 48 >> 49 return irq; >> 50 } >> 51 >> 52 /* >> 53 * Allocate the 16 legacy interrupts for i8259 devices. This happens early >> 54 * in the kernel initialization so treating allocation failure as BUG() is >> 55 * ok. >> 56 */ >> 57 void __init alloc_legacy_irqno(void) >> 58 { >> 59 int i; >> 60 >> 61 for (i = 0; i <= 16; i++) >> 62 BUG_ON(test_and_set_bit(i, irq_map)); >> 63 } >> 64 >> 65 void free_irqno(unsigned int irq) >> 66 { >> 67 smp_mb__before_clear_bit(); >> 68 clear_bit(irq, irq_map); >> 69 smp_mb__after_clear_bit(); >> 70 } >> 71 >> 72 /* >> 73 * 'what should we do if we get a hw irq event on an illegal vector'. >> 74 * each architecture has to answer this themselves. >> 75 */ >> 76 void ack_bad_irq(unsigned int irq) >> 77 { >> 78 smtc_im_ack_irq(irq); >> 79 printk("unexpected IRQ # %d\n", irq); >> 80 } >> 81 >> 82 atomic_t irq_err_count; >> 83 >> 84 /* >> 85 * Generic, controller-independent functions: >> 86 */ >> 87 >> 88 int show_interrupts(struct seq_file *p, void *v) >> 89 { >> 90 int i = *(loff_t *) v, j; >> 91 struct irqaction * action; >> 92 unsigned long flags; >> 93 >> 94 if (i == 0) { >> 95 seq_printf(p, " "); >> 96 for_each_online_cpu(j) >> 97 seq_printf(p, "CPU%d ", j); >> 98 seq_putc(p, '\n'); >> 99 } >> 100 >> 101 if (i < NR_IRQS) { >> 102 spin_lock_irqsave(&irq_desc[i].lock, flags); >> 103 action = irq_desc[i].action; >> 104 if (!action) >> 105 goto skip; >> 106 seq_printf(p, "%3d: ", i); >> 107 #ifndef CONFIG_SMP >> 108 seq_printf(p, "%10u ", kstat_irqs(i)); >> 109 #else >> 110 for_each_online_cpu(j) >> 111 seq_printf(p, "%10u ", kstat_irqs_cpu(i, j)); >> 112 #endif >> 113 seq_printf(p, " %14s", irq_desc[i].chip->name); >> 114 seq_printf(p, " %s", action->name); >> 115 >> 116 for (action=action->next; action; action = action->next) >> 117 seq_printf(p, ", %s", action->name); >> 118 >> 119 seq_putc(p, '\n'); >> 120 skip: >> 121 spin_unlock_irqrestore(&irq_desc[i].lock, flags); >> 122 } else if (i == NR_IRQS) { >> 123 seq_putc(p, '\n'); >> 124 seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count)); >> 125 } >> 126 return 0; >> 127 } >> 128 >> 129 asmlinkage void spurious_interrupt(void) >> 130 { >> 131 atomic_inc(&irq_err_count); >> 132 } 10 133 11 void __init init_IRQ(void) 134 void __init init_IRQ(void) 12 { 135 { 13 irqchip_init(); !! 136 int i; 14 #ifdef CONFIG_SMP !! 137 15 setup_smp_ipi(); !! 138 #ifdef CONFIG_KGDB >> 139 if (kgdb_early_setup) >> 140 return; >> 141 #endif >> 142 >> 143 for (i = 0; i < NR_IRQS; i++) >> 144 set_irq_noprobe(i); >> 145 >> 146 arch_init_irq(); >> 147 >> 148 #ifdef CONFIG_KGDB >> 149 if (!kgdb_early_setup) >> 150 kgdb_early_setup = 1; 16 #endif 151 #endif 17 } 152 } 18 153
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.