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