1 /* 2 * linux/kernel/irq/handle.c 3 * 4 * Copyright (C) 1992, 1998-2004 Linus Torvalds, Ingo Molnar 5 * 6 * This file contains the core interrupt handling code. 7 */ 8 9 #include <linux/irq.h> 10 #include <linux/module.h> 11 #include <linux/random.h> 12 #include <linux/interrupt.h> 13 #include <linux/kernel_stat.h> 14 15 #include "internals.h" 16 17 /* 18 * Linux has a controller-independent interrupt architecture. 19 * Every controller has a 'controller-template', that is used 20 * by the main code to do the right thing. Each driver-visible 21 * interrupt source is transparently wired to the apropriate 22 * controller. Thus drivers need not be aware of the 23 * interrupt-controller. 24 * 25 * The code is designed to be easily extended with new/different 26 * interrupt controllers, without having to do assembly magic or 27 * having to touch the generic code. 28 * 29 * Controller mappings for all interrupt sources: 30 */ 31 irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned = { 32 [0 ... NR_IRQS-1] = { 33 .status = IRQ_DISABLED, 34 .handler = &no_irq_type, 35 .lock = SPIN_LOCK_UNLOCKED 36 } 37 }; 38 39 /* 40 * Generic 'no controller' code 41 */ 42 static void end_none(unsigned int irq) { } 43 static void enable_none(unsigned int irq) { } 44 static void disable_none(unsigned int irq) { } 45 static void shutdown_none(unsigned int irq) { } 46 static unsigned int startup_none(unsigned int irq) { return 0; } 47 48 static void ack_none(unsigned int irq) 49 { 50 /* 51 * 'what should we do if we get a hw irq event on an illegal vector'. 52 * each architecture has to answer this themself. 53 */ 54 ack_bad_irq(irq); 55 } 56 57 struct hw_interrupt_type no_irq_type = { 58 .typename = "none", 59 .startup = startup_none, 60 .shutdown = shutdown_none, 61 .enable = enable_none, 62 .disable = disable_none, 63 .ack = ack_none, 64 .end = end_none, 65 .set_affinity = NULL 66 }; 67 68 /* 69 * Special, empty irq handler: 70 */ 71 irqreturn_t no_action(int cpl, void *dev_id, struct pt_regs *regs) 72 { 73 return IRQ_NONE; 74 } 75 76 /* 77 * Have got an event to handle: 78 */ 79 fastcall int handle_IRQ_event(unsigned int irq, struct pt_regs *regs, 80 struct irqaction *action) 81 { 82 int ret, retval = 0, status = 0; 83 84 if (!(action->flags & SA_INTERRUPT)) 85 local_irq_enable(); 86 87 do { 88 ret = action->handler(irq, action->dev_id, regs); 89 if (ret == IRQ_HANDLED) 90 status |= action->flags; 91 retval |= ret; 92 action = action->next; 93 } while (action); 94 95 if (status & SA_SAMPLE_RANDOM) 96 add_interrupt_randomness(irq); 97 local_irq_disable(); 98 99 return retval; 100 } 101 102 /* 103 * do_IRQ handles all normal device IRQ's (the special 104 * SMP cross-CPU interrupts have their own specific 105 * handlers). 106 */ 107 fastcall unsigned int __do_IRQ(unsigned int irq, struct pt_regs *regs) 108 { 109 irq_desc_t *desc = irq_desc + irq; 110 struct irqaction * action; 111 unsigned int status; 112 113 kstat_this_cpu.irqs[irq]++; 114 if (CHECK_IRQ_PER_CPU(desc->status)) { 115 irqreturn_t action_ret; 116 117 /* 118 * No locking required for CPU-local interrupts: 119 */ 120 if (desc->handler->ack) 121 desc->handler->ack(irq); 122 action_ret = handle_IRQ_event(irq, regs, desc->action); 123 desc->handler->end(irq); 124 return 1; 125 } 126 127 spin_lock(&desc->lock); 128 if (desc->handler->ack) 129 desc->handler->ack(irq); 130 /* 131 * REPLAY is when Linux resends an IRQ that was dropped earlier 132 * WAITING is used by probe to mark irqs that are being tested 133 */ 134 status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING); 135 status |= IRQ_PENDING; /* we _want_ to handle it */ 136 137 /* 138 * If the IRQ is disabled for whatever reason, we cannot 139 * use the action we have. 140 */ 141 action = NULL; 142 if (likely(!(status & (IRQ_DISABLED | IRQ_INPROGRESS)))) { 143 action = desc->action; 144 status &= ~IRQ_PENDING; /* we commit to handling */ 145 status |= IRQ_INPROGRESS; /* we are handling it */ 146 } 147 desc->status = status; 148 149 /* 150 * If there is no IRQ handler or it was disabled, exit early. 151 * Since we set PENDING, if another processor is handling 152 * a different instance of this same irq, the other processor 153 * will take care of it. 154 */ 155 if (unlikely(!action)) 156 goto out; 157 158 /* 159 * Edge triggered interrupts need to remember 160 * pending events. 161 * This applies to any hw interrupts that allow a second 162 * instance of the same irq to arrive while we are in do_IRQ 163 * or in the handler. But the code here only handles the _second_ 164 * instance of the irq, not the third or fourth. So it is mostly 165 * useful for irq hardware that does not mask cleanly in an 166 * SMP environment. 167 */ 168 for (;;) { 169 irqreturn_t action_ret; 170 171 spin_unlock(&desc->lock); 172 173 action_ret = handle_IRQ_event(irq, regs, action); 174 175 spin_lock(&desc->lock); 176 if (!noirqdebug) 177 note_interrupt(irq, desc, action_ret, regs); 178 if (likely(!(desc->status & IRQ_PENDING))) 179 break; 180 desc->status &= ~IRQ_PENDING; 181 } 182 desc->status &= ~IRQ_INPROGRESS; 183 184 out: 185 /* 186 * The ->end() handler has to deal with interrupts which got 187 * disabled while the handler was running. 188 */ 189 desc->handler->end(irq); 190 spin_unlock(&desc->lock); 191 192 return 1; 193 } 194 195