xref: /openbmc/linux/Documentation/core-api/genericirq.rst (revision 3bd3b99ab6ec0cf9d39bcf82ea05326c0aa0013e)
1*3bd3b99aSMauro Carvalho Chehab.. include:: <isonum.txt>
2*3bd3b99aSMauro Carvalho Chehab
3*3bd3b99aSMauro Carvalho Chehab==========================
4*3bd3b99aSMauro Carvalho ChehabLinux generic IRQ handling
5*3bd3b99aSMauro Carvalho Chehab==========================
6*3bd3b99aSMauro Carvalho Chehab
7*3bd3b99aSMauro Carvalho Chehab:Copyright: |copy| 2005-2010: Thomas Gleixner
8*3bd3b99aSMauro Carvalho Chehab:Copyright: |copy| 2005-2006:  Ingo Molnar
9*3bd3b99aSMauro Carvalho Chehab
10*3bd3b99aSMauro Carvalho ChehabIntroduction
11*3bd3b99aSMauro Carvalho Chehab============
12*3bd3b99aSMauro Carvalho Chehab
13*3bd3b99aSMauro Carvalho ChehabThe generic interrupt handling layer is designed to provide a complete
14*3bd3b99aSMauro Carvalho Chehababstraction of interrupt handling for device drivers. It is able to
15*3bd3b99aSMauro Carvalho Chehabhandle all the different types of interrupt controller hardware. Device
16*3bd3b99aSMauro Carvalho Chehabdrivers use generic API functions to request, enable, disable and free
17*3bd3b99aSMauro Carvalho Chehabinterrupts. The drivers do not have to know anything about interrupt
18*3bd3b99aSMauro Carvalho Chehabhardware details, so they can be used on different platforms without
19*3bd3b99aSMauro Carvalho Chehabcode changes.
20*3bd3b99aSMauro Carvalho Chehab
21*3bd3b99aSMauro Carvalho ChehabThis documentation is provided to developers who want to implement an
22*3bd3b99aSMauro Carvalho Chehabinterrupt subsystem based for their architecture, with the help of the
23*3bd3b99aSMauro Carvalho Chehabgeneric IRQ handling layer.
24*3bd3b99aSMauro Carvalho Chehab
25*3bd3b99aSMauro Carvalho ChehabRationale
26*3bd3b99aSMauro Carvalho Chehab=========
27*3bd3b99aSMauro Carvalho Chehab
28*3bd3b99aSMauro Carvalho ChehabThe original implementation of interrupt handling in Linux uses the
29*3bd3b99aSMauro Carvalho Chehab__do_IRQ() super-handler, which is able to deal with every type of
30*3bd3b99aSMauro Carvalho Chehabinterrupt logic.
31*3bd3b99aSMauro Carvalho Chehab
32*3bd3b99aSMauro Carvalho ChehabOriginally, Russell King identified different types of handlers to build
33*3bd3b99aSMauro Carvalho Chehaba quite universal set for the ARM interrupt handler implementation in
34*3bd3b99aSMauro Carvalho ChehabLinux 2.5/2.6. He distinguished between:
35*3bd3b99aSMauro Carvalho Chehab
36*3bd3b99aSMauro Carvalho Chehab-  Level type
37*3bd3b99aSMauro Carvalho Chehab
38*3bd3b99aSMauro Carvalho Chehab-  Edge type
39*3bd3b99aSMauro Carvalho Chehab
40*3bd3b99aSMauro Carvalho Chehab-  Simple type
41*3bd3b99aSMauro Carvalho Chehab
42*3bd3b99aSMauro Carvalho ChehabDuring the implementation we identified another type:
43*3bd3b99aSMauro Carvalho Chehab
44*3bd3b99aSMauro Carvalho Chehab-  Fast EOI type
45*3bd3b99aSMauro Carvalho Chehab
46*3bd3b99aSMauro Carvalho ChehabIn the SMP world of the __do_IRQ() super-handler another type was
47*3bd3b99aSMauro Carvalho Chehabidentified:
48*3bd3b99aSMauro Carvalho Chehab
49*3bd3b99aSMauro Carvalho Chehab-  Per CPU type
50*3bd3b99aSMauro Carvalho Chehab
51*3bd3b99aSMauro Carvalho ChehabThis split implementation of high-level IRQ handlers allows us to
52*3bd3b99aSMauro Carvalho Chehaboptimize the flow of the interrupt handling for each specific interrupt
53*3bd3b99aSMauro Carvalho Chehabtype. This reduces complexity in that particular code path and allows
54*3bd3b99aSMauro Carvalho Chehabthe optimized handling of a given type.
55*3bd3b99aSMauro Carvalho Chehab
56*3bd3b99aSMauro Carvalho ChehabThe original general IRQ implementation used hw_interrupt_type
57*3bd3b99aSMauro Carvalho Chehabstructures and their ->ack(), ->end() [etc.] callbacks to differentiate
58*3bd3b99aSMauro Carvalho Chehabthe flow control in the super-handler. This leads to a mix of flow logic
59*3bd3b99aSMauro Carvalho Chehaband low-level hardware logic, and it also leads to unnecessary code
60*3bd3b99aSMauro Carvalho Chehabduplication: for example in i386, there is an ioapic_level_irq and an
61*3bd3b99aSMauro Carvalho Chehabioapic_edge_irq IRQ-type which share many of the low-level details but
62*3bd3b99aSMauro Carvalho Chehabhave different flow handling.
63*3bd3b99aSMauro Carvalho Chehab
64*3bd3b99aSMauro Carvalho ChehabA more natural abstraction is the clean separation of the 'irq flow' and
65*3bd3b99aSMauro Carvalho Chehabthe 'chip details'.
66*3bd3b99aSMauro Carvalho Chehab
67*3bd3b99aSMauro Carvalho ChehabAnalysing a couple of architecture's IRQ subsystem implementations
68*3bd3b99aSMauro Carvalho Chehabreveals that most of them can use a generic set of 'irq flow' methods
69*3bd3b99aSMauro Carvalho Chehaband only need to add the chip-level specific code. The separation is
70*3bd3b99aSMauro Carvalho Chehabalso valuable for (sub)architectures which need specific quirks in the
71*3bd3b99aSMauro Carvalho ChehabIRQ flow itself but not in the chip details - and thus provides a more
72*3bd3b99aSMauro Carvalho Chehabtransparent IRQ subsystem design.
73*3bd3b99aSMauro Carvalho Chehab
74*3bd3b99aSMauro Carvalho ChehabEach interrupt descriptor is assigned its own high-level flow handler,
75*3bd3b99aSMauro Carvalho Chehabwhich is normally one of the generic implementations. (This high-level
76*3bd3b99aSMauro Carvalho Chehabflow handler implementation also makes it simple to provide
77*3bd3b99aSMauro Carvalho Chehabdemultiplexing handlers which can be found in embedded platforms on
78*3bd3b99aSMauro Carvalho Chehabvarious architectures.)
79*3bd3b99aSMauro Carvalho Chehab
80*3bd3b99aSMauro Carvalho ChehabThe separation makes the generic interrupt handling layer more flexible
81*3bd3b99aSMauro Carvalho Chehaband extensible. For example, an (sub)architecture can use a generic
82*3bd3b99aSMauro Carvalho ChehabIRQ-flow implementation for 'level type' interrupts and add a
83*3bd3b99aSMauro Carvalho Chehab(sub)architecture specific 'edge type' implementation.
84*3bd3b99aSMauro Carvalho Chehab
85*3bd3b99aSMauro Carvalho ChehabTo make the transition to the new model easier and prevent the breakage
86*3bd3b99aSMauro Carvalho Chehabof existing implementations, the __do_IRQ() super-handler is still
87*3bd3b99aSMauro Carvalho Chehabavailable. This leads to a kind of duality for the time being. Over time
88*3bd3b99aSMauro Carvalho Chehabthe new model should be used in more and more architectures, as it
89*3bd3b99aSMauro Carvalho Chehabenables smaller and cleaner IRQ subsystems. It's deprecated for three
90*3bd3b99aSMauro Carvalho Chehabyears now and about to be removed.
91*3bd3b99aSMauro Carvalho Chehab
92*3bd3b99aSMauro Carvalho ChehabKnown Bugs And Assumptions
93*3bd3b99aSMauro Carvalho Chehab==========================
94*3bd3b99aSMauro Carvalho Chehab
95*3bd3b99aSMauro Carvalho ChehabNone (knock on wood).
96*3bd3b99aSMauro Carvalho Chehab
97*3bd3b99aSMauro Carvalho ChehabAbstraction layers
98*3bd3b99aSMauro Carvalho Chehab==================
99*3bd3b99aSMauro Carvalho Chehab
100*3bd3b99aSMauro Carvalho ChehabThere are three main levels of abstraction in the interrupt code:
101*3bd3b99aSMauro Carvalho Chehab
102*3bd3b99aSMauro Carvalho Chehab1. High-level driver API
103*3bd3b99aSMauro Carvalho Chehab
104*3bd3b99aSMauro Carvalho Chehab2. High-level IRQ flow handlers
105*3bd3b99aSMauro Carvalho Chehab
106*3bd3b99aSMauro Carvalho Chehab3. Chip-level hardware encapsulation
107*3bd3b99aSMauro Carvalho Chehab
108*3bd3b99aSMauro Carvalho ChehabInterrupt control flow
109*3bd3b99aSMauro Carvalho Chehab----------------------
110*3bd3b99aSMauro Carvalho Chehab
111*3bd3b99aSMauro Carvalho ChehabEach interrupt is described by an interrupt descriptor structure
112*3bd3b99aSMauro Carvalho Chehabirq_desc. The interrupt is referenced by an 'unsigned int' numeric
113*3bd3b99aSMauro Carvalho Chehabvalue which selects the corresponding interrupt description structure in
114*3bd3b99aSMauro Carvalho Chehabthe descriptor structures array. The descriptor structure contains
115*3bd3b99aSMauro Carvalho Chehabstatus information and pointers to the interrupt flow method and the
116*3bd3b99aSMauro Carvalho Chehabinterrupt chip structure which are assigned to this interrupt.
117*3bd3b99aSMauro Carvalho Chehab
118*3bd3b99aSMauro Carvalho ChehabWhenever an interrupt triggers, the low-level architecture code calls
119*3bd3b99aSMauro Carvalho Chehabinto the generic interrupt code by calling desc->handle_irq(). This
120*3bd3b99aSMauro Carvalho Chehabhigh-level IRQ handling function only uses desc->irq_data.chip
121*3bd3b99aSMauro Carvalho Chehabprimitives referenced by the assigned chip descriptor structure.
122*3bd3b99aSMauro Carvalho Chehab
123*3bd3b99aSMauro Carvalho ChehabHigh-level Driver API
124*3bd3b99aSMauro Carvalho Chehab---------------------
125*3bd3b99aSMauro Carvalho Chehab
126*3bd3b99aSMauro Carvalho ChehabThe high-level Driver API consists of following functions:
127*3bd3b99aSMauro Carvalho Chehab
128*3bd3b99aSMauro Carvalho Chehab-  request_irq()
129*3bd3b99aSMauro Carvalho Chehab
130*3bd3b99aSMauro Carvalho Chehab-  free_irq()
131*3bd3b99aSMauro Carvalho Chehab
132*3bd3b99aSMauro Carvalho Chehab-  disable_irq()
133*3bd3b99aSMauro Carvalho Chehab
134*3bd3b99aSMauro Carvalho Chehab-  enable_irq()
135*3bd3b99aSMauro Carvalho Chehab
136*3bd3b99aSMauro Carvalho Chehab-  disable_irq_nosync() (SMP only)
137*3bd3b99aSMauro Carvalho Chehab
138*3bd3b99aSMauro Carvalho Chehab-  synchronize_irq() (SMP only)
139*3bd3b99aSMauro Carvalho Chehab
140*3bd3b99aSMauro Carvalho Chehab-  irq_set_irq_type()
141*3bd3b99aSMauro Carvalho Chehab
142*3bd3b99aSMauro Carvalho Chehab-  irq_set_irq_wake()
143*3bd3b99aSMauro Carvalho Chehab
144*3bd3b99aSMauro Carvalho Chehab-  irq_set_handler_data()
145*3bd3b99aSMauro Carvalho Chehab
146*3bd3b99aSMauro Carvalho Chehab-  irq_set_chip()
147*3bd3b99aSMauro Carvalho Chehab
148*3bd3b99aSMauro Carvalho Chehab-  irq_set_chip_data()
149*3bd3b99aSMauro Carvalho Chehab
150*3bd3b99aSMauro Carvalho ChehabSee the autogenerated function documentation for details.
151*3bd3b99aSMauro Carvalho Chehab
152*3bd3b99aSMauro Carvalho ChehabHigh-level IRQ flow handlers
153*3bd3b99aSMauro Carvalho Chehab----------------------------
154*3bd3b99aSMauro Carvalho Chehab
155*3bd3b99aSMauro Carvalho ChehabThe generic layer provides a set of pre-defined irq-flow methods:
156*3bd3b99aSMauro Carvalho Chehab
157*3bd3b99aSMauro Carvalho Chehab-  handle_level_irq
158*3bd3b99aSMauro Carvalho Chehab
159*3bd3b99aSMauro Carvalho Chehab-  handle_edge_irq
160*3bd3b99aSMauro Carvalho Chehab
161*3bd3b99aSMauro Carvalho Chehab-  handle_fasteoi_irq
162*3bd3b99aSMauro Carvalho Chehab
163*3bd3b99aSMauro Carvalho Chehab-  handle_simple_irq
164*3bd3b99aSMauro Carvalho Chehab
165*3bd3b99aSMauro Carvalho Chehab-  handle_percpu_irq
166*3bd3b99aSMauro Carvalho Chehab
167*3bd3b99aSMauro Carvalho Chehab-  handle_edge_eoi_irq
168*3bd3b99aSMauro Carvalho Chehab
169*3bd3b99aSMauro Carvalho Chehab-  handle_bad_irq
170*3bd3b99aSMauro Carvalho Chehab
171*3bd3b99aSMauro Carvalho ChehabThe interrupt flow handlers (either pre-defined or architecture
172*3bd3b99aSMauro Carvalho Chehabspecific) are assigned to specific interrupts by the architecture either
173*3bd3b99aSMauro Carvalho Chehabduring bootup or during device initialization.
174*3bd3b99aSMauro Carvalho Chehab
175*3bd3b99aSMauro Carvalho ChehabDefault flow implementations
176*3bd3b99aSMauro Carvalho Chehab~~~~~~~~~~~~~~~~~~~~~~~~~~~~
177*3bd3b99aSMauro Carvalho Chehab
178*3bd3b99aSMauro Carvalho ChehabHelper functions
179*3bd3b99aSMauro Carvalho Chehab^^^^^^^^^^^^^^^^
180*3bd3b99aSMauro Carvalho Chehab
181*3bd3b99aSMauro Carvalho ChehabThe helper functions call the chip primitives and are used by the
182*3bd3b99aSMauro Carvalho Chehabdefault flow implementations. The following helper functions are
183*3bd3b99aSMauro Carvalho Chehabimplemented (simplified excerpt)::
184*3bd3b99aSMauro Carvalho Chehab
185*3bd3b99aSMauro Carvalho Chehab    default_enable(struct irq_data *data)
186*3bd3b99aSMauro Carvalho Chehab    {
187*3bd3b99aSMauro Carvalho Chehab        desc->irq_data.chip->irq_unmask(data);
188*3bd3b99aSMauro Carvalho Chehab    }
189*3bd3b99aSMauro Carvalho Chehab
190*3bd3b99aSMauro Carvalho Chehab    default_disable(struct irq_data *data)
191*3bd3b99aSMauro Carvalho Chehab    {
192*3bd3b99aSMauro Carvalho Chehab        if (!delay_disable(data))
193*3bd3b99aSMauro Carvalho Chehab            desc->irq_data.chip->irq_mask(data);
194*3bd3b99aSMauro Carvalho Chehab    }
195*3bd3b99aSMauro Carvalho Chehab
196*3bd3b99aSMauro Carvalho Chehab    default_ack(struct irq_data *data)
197*3bd3b99aSMauro Carvalho Chehab    {
198*3bd3b99aSMauro Carvalho Chehab        chip->irq_ack(data);
199*3bd3b99aSMauro Carvalho Chehab    }
200*3bd3b99aSMauro Carvalho Chehab
201*3bd3b99aSMauro Carvalho Chehab    default_mask_ack(struct irq_data *data)
202*3bd3b99aSMauro Carvalho Chehab    {
203*3bd3b99aSMauro Carvalho Chehab        if (chip->irq_mask_ack) {
204*3bd3b99aSMauro Carvalho Chehab            chip->irq_mask_ack(data);
205*3bd3b99aSMauro Carvalho Chehab        } else {
206*3bd3b99aSMauro Carvalho Chehab            chip->irq_mask(data);
207*3bd3b99aSMauro Carvalho Chehab            chip->irq_ack(data);
208*3bd3b99aSMauro Carvalho Chehab        }
209*3bd3b99aSMauro Carvalho Chehab    }
210*3bd3b99aSMauro Carvalho Chehab
211*3bd3b99aSMauro Carvalho Chehab    noop(struct irq_data *data))
212*3bd3b99aSMauro Carvalho Chehab    {
213*3bd3b99aSMauro Carvalho Chehab    }
214*3bd3b99aSMauro Carvalho Chehab
215*3bd3b99aSMauro Carvalho Chehab
216*3bd3b99aSMauro Carvalho Chehab
217*3bd3b99aSMauro Carvalho ChehabDefault flow handler implementations
218*3bd3b99aSMauro Carvalho Chehab~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
219*3bd3b99aSMauro Carvalho Chehab
220*3bd3b99aSMauro Carvalho ChehabDefault Level IRQ flow handler
221*3bd3b99aSMauro Carvalho Chehab^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
222*3bd3b99aSMauro Carvalho Chehab
223*3bd3b99aSMauro Carvalho Chehabhandle_level_irq provides a generic implementation for level-triggered
224*3bd3b99aSMauro Carvalho Chehabinterrupts.
225*3bd3b99aSMauro Carvalho Chehab
226*3bd3b99aSMauro Carvalho ChehabThe following control flow is implemented (simplified excerpt)::
227*3bd3b99aSMauro Carvalho Chehab
228*3bd3b99aSMauro Carvalho Chehab    desc->irq_data.chip->irq_mask_ack();
229*3bd3b99aSMauro Carvalho Chehab    handle_irq_event(desc->action);
230*3bd3b99aSMauro Carvalho Chehab    desc->irq_data.chip->irq_unmask();
231*3bd3b99aSMauro Carvalho Chehab
232*3bd3b99aSMauro Carvalho Chehab
233*3bd3b99aSMauro Carvalho ChehabDefault Fast EOI IRQ flow handler
234*3bd3b99aSMauro Carvalho Chehab^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
235*3bd3b99aSMauro Carvalho Chehab
236*3bd3b99aSMauro Carvalho Chehabhandle_fasteoi_irq provides a generic implementation for interrupts,
237*3bd3b99aSMauro Carvalho Chehabwhich only need an EOI at the end of the handler.
238*3bd3b99aSMauro Carvalho Chehab
239*3bd3b99aSMauro Carvalho ChehabThe following control flow is implemented (simplified excerpt)::
240*3bd3b99aSMauro Carvalho Chehab
241*3bd3b99aSMauro Carvalho Chehab    handle_irq_event(desc->action);
242*3bd3b99aSMauro Carvalho Chehab    desc->irq_data.chip->irq_eoi();
243*3bd3b99aSMauro Carvalho Chehab
244*3bd3b99aSMauro Carvalho Chehab
245*3bd3b99aSMauro Carvalho ChehabDefault Edge IRQ flow handler
246*3bd3b99aSMauro Carvalho Chehab^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
247*3bd3b99aSMauro Carvalho Chehab
248*3bd3b99aSMauro Carvalho Chehabhandle_edge_irq provides a generic implementation for edge-triggered
249*3bd3b99aSMauro Carvalho Chehabinterrupts.
250*3bd3b99aSMauro Carvalho Chehab
251*3bd3b99aSMauro Carvalho ChehabThe following control flow is implemented (simplified excerpt)::
252*3bd3b99aSMauro Carvalho Chehab
253*3bd3b99aSMauro Carvalho Chehab    if (desc->status & running) {
254*3bd3b99aSMauro Carvalho Chehab        desc->irq_data.chip->irq_mask_ack();
255*3bd3b99aSMauro Carvalho Chehab        desc->status |= pending | masked;
256*3bd3b99aSMauro Carvalho Chehab        return;
257*3bd3b99aSMauro Carvalho Chehab    }
258*3bd3b99aSMauro Carvalho Chehab    desc->irq_data.chip->irq_ack();
259*3bd3b99aSMauro Carvalho Chehab    desc->status |= running;
260*3bd3b99aSMauro Carvalho Chehab    do {
261*3bd3b99aSMauro Carvalho Chehab        if (desc->status & masked)
262*3bd3b99aSMauro Carvalho Chehab            desc->irq_data.chip->irq_unmask();
263*3bd3b99aSMauro Carvalho Chehab        desc->status &= ~pending;
264*3bd3b99aSMauro Carvalho Chehab        handle_irq_event(desc->action);
265*3bd3b99aSMauro Carvalho Chehab    } while (status & pending);
266*3bd3b99aSMauro Carvalho Chehab    desc->status &= ~running;
267*3bd3b99aSMauro Carvalho Chehab
268*3bd3b99aSMauro Carvalho Chehab
269*3bd3b99aSMauro Carvalho ChehabDefault simple IRQ flow handler
270*3bd3b99aSMauro Carvalho Chehab^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
271*3bd3b99aSMauro Carvalho Chehab
272*3bd3b99aSMauro Carvalho Chehabhandle_simple_irq provides a generic implementation for simple
273*3bd3b99aSMauro Carvalho Chehabinterrupts.
274*3bd3b99aSMauro Carvalho Chehab
275*3bd3b99aSMauro Carvalho Chehab.. note::
276*3bd3b99aSMauro Carvalho Chehab
277*3bd3b99aSMauro Carvalho Chehab   The simple flow handler does not call any handler/chip primitives.
278*3bd3b99aSMauro Carvalho Chehab
279*3bd3b99aSMauro Carvalho ChehabThe following control flow is implemented (simplified excerpt)::
280*3bd3b99aSMauro Carvalho Chehab
281*3bd3b99aSMauro Carvalho Chehab    handle_irq_event(desc->action);
282*3bd3b99aSMauro Carvalho Chehab
283*3bd3b99aSMauro Carvalho Chehab
284*3bd3b99aSMauro Carvalho ChehabDefault per CPU flow handler
285*3bd3b99aSMauro Carvalho Chehab^^^^^^^^^^^^^^^^^^^^^^^^^^^^
286*3bd3b99aSMauro Carvalho Chehab
287*3bd3b99aSMauro Carvalho Chehabhandle_percpu_irq provides a generic implementation for per CPU
288*3bd3b99aSMauro Carvalho Chehabinterrupts.
289*3bd3b99aSMauro Carvalho Chehab
290*3bd3b99aSMauro Carvalho ChehabPer CPU interrupts are only available on SMP and the handler provides a
291*3bd3b99aSMauro Carvalho Chehabsimplified version without locking.
292*3bd3b99aSMauro Carvalho Chehab
293*3bd3b99aSMauro Carvalho ChehabThe following control flow is implemented (simplified excerpt)::
294*3bd3b99aSMauro Carvalho Chehab
295*3bd3b99aSMauro Carvalho Chehab    if (desc->irq_data.chip->irq_ack)
296*3bd3b99aSMauro Carvalho Chehab        desc->irq_data.chip->irq_ack();
297*3bd3b99aSMauro Carvalho Chehab    handle_irq_event(desc->action);
298*3bd3b99aSMauro Carvalho Chehab    if (desc->irq_data.chip->irq_eoi)
299*3bd3b99aSMauro Carvalho Chehab            desc->irq_data.chip->irq_eoi();
300*3bd3b99aSMauro Carvalho Chehab
301*3bd3b99aSMauro Carvalho Chehab
302*3bd3b99aSMauro Carvalho ChehabEOI Edge IRQ flow handler
303*3bd3b99aSMauro Carvalho Chehab^^^^^^^^^^^^^^^^^^^^^^^^^
304*3bd3b99aSMauro Carvalho Chehab
305*3bd3b99aSMauro Carvalho Chehabhandle_edge_eoi_irq provides an abnomination of the edge handler
306*3bd3b99aSMauro Carvalho Chehabwhich is solely used to tame a badly wreckaged irq controller on
307*3bd3b99aSMauro Carvalho Chehabpowerpc/cell.
308*3bd3b99aSMauro Carvalho Chehab
309*3bd3b99aSMauro Carvalho ChehabBad IRQ flow handler
310*3bd3b99aSMauro Carvalho Chehab^^^^^^^^^^^^^^^^^^^^
311*3bd3b99aSMauro Carvalho Chehab
312*3bd3b99aSMauro Carvalho Chehabhandle_bad_irq is used for spurious interrupts which have no real
313*3bd3b99aSMauro Carvalho Chehabhandler assigned..
314*3bd3b99aSMauro Carvalho Chehab
315*3bd3b99aSMauro Carvalho ChehabQuirks and optimizations
316*3bd3b99aSMauro Carvalho Chehab~~~~~~~~~~~~~~~~~~~~~~~~
317*3bd3b99aSMauro Carvalho Chehab
318*3bd3b99aSMauro Carvalho ChehabThe generic functions are intended for 'clean' architectures and chips,
319*3bd3b99aSMauro Carvalho Chehabwhich have no platform-specific IRQ handling quirks. If an architecture
320*3bd3b99aSMauro Carvalho Chehabneeds to implement quirks on the 'flow' level then it can do so by
321*3bd3b99aSMauro Carvalho Chehaboverriding the high-level irq-flow handler.
322*3bd3b99aSMauro Carvalho Chehab
323*3bd3b99aSMauro Carvalho ChehabDelayed interrupt disable
324*3bd3b99aSMauro Carvalho Chehab~~~~~~~~~~~~~~~~~~~~~~~~~
325*3bd3b99aSMauro Carvalho Chehab
326*3bd3b99aSMauro Carvalho ChehabThis per interrupt selectable feature, which was introduced by Russell
327*3bd3b99aSMauro Carvalho ChehabKing in the ARM interrupt implementation, does not mask an interrupt at
328*3bd3b99aSMauro Carvalho Chehabthe hardware level when disable_irq() is called. The interrupt is kept
329*3bd3b99aSMauro Carvalho Chehabenabled and is masked in the flow handler when an interrupt event
330*3bd3b99aSMauro Carvalho Chehabhappens. This prevents losing edge interrupts on hardware which does not
331*3bd3b99aSMauro Carvalho Chehabstore an edge interrupt event while the interrupt is disabled at the
332*3bd3b99aSMauro Carvalho Chehabhardware level. When an interrupt arrives while the IRQ_DISABLED flag
333*3bd3b99aSMauro Carvalho Chehabis set, then the interrupt is masked at the hardware level and the
334*3bd3b99aSMauro Carvalho ChehabIRQ_PENDING bit is set. When the interrupt is re-enabled by
335*3bd3b99aSMauro Carvalho Chehabenable_irq() the pending bit is checked and if it is set, the interrupt
336*3bd3b99aSMauro Carvalho Chehabis resent either via hardware or by a software resend mechanism. (It's
337*3bd3b99aSMauro Carvalho Chehabnecessary to enable CONFIG_HARDIRQS_SW_RESEND when you want to use
338*3bd3b99aSMauro Carvalho Chehabthe delayed interrupt disable feature and your hardware is not capable
339*3bd3b99aSMauro Carvalho Chehabof retriggering an interrupt.) The delayed interrupt disable is not
340*3bd3b99aSMauro Carvalho Chehabconfigurable.
341*3bd3b99aSMauro Carvalho Chehab
342*3bd3b99aSMauro Carvalho ChehabChip-level hardware encapsulation
343*3bd3b99aSMauro Carvalho Chehab---------------------------------
344*3bd3b99aSMauro Carvalho Chehab
345*3bd3b99aSMauro Carvalho ChehabThe chip-level hardware descriptor structure irq_chip contains all the
346*3bd3b99aSMauro Carvalho Chehabdirect chip relevant functions, which can be utilized by the irq flow
347*3bd3b99aSMauro Carvalho Chehabimplementations.
348*3bd3b99aSMauro Carvalho Chehab
349*3bd3b99aSMauro Carvalho Chehab-  irq_ack()
350*3bd3b99aSMauro Carvalho Chehab
351*3bd3b99aSMauro Carvalho Chehab-  irq_mask_ack() - Optional, recommended for performance
352*3bd3b99aSMauro Carvalho Chehab
353*3bd3b99aSMauro Carvalho Chehab-  irq_mask()
354*3bd3b99aSMauro Carvalho Chehab
355*3bd3b99aSMauro Carvalho Chehab-  irq_unmask()
356*3bd3b99aSMauro Carvalho Chehab
357*3bd3b99aSMauro Carvalho Chehab-  irq_eoi() - Optional, required for EOI flow handlers
358*3bd3b99aSMauro Carvalho Chehab
359*3bd3b99aSMauro Carvalho Chehab-  irq_retrigger() - Optional
360*3bd3b99aSMauro Carvalho Chehab
361*3bd3b99aSMauro Carvalho Chehab-  irq_set_type() - Optional
362*3bd3b99aSMauro Carvalho Chehab
363*3bd3b99aSMauro Carvalho Chehab-  irq_set_wake() - Optional
364*3bd3b99aSMauro Carvalho Chehab
365*3bd3b99aSMauro Carvalho ChehabThese primitives are strictly intended to mean what they say: ack means
366*3bd3b99aSMauro Carvalho ChehabACK, masking means masking of an IRQ line, etc. It is up to the flow
367*3bd3b99aSMauro Carvalho Chehabhandler(s) to use these basic units of low-level functionality.
368*3bd3b99aSMauro Carvalho Chehab
369*3bd3b99aSMauro Carvalho Chehab__do_IRQ entry point
370*3bd3b99aSMauro Carvalho Chehab====================
371*3bd3b99aSMauro Carvalho Chehab
372*3bd3b99aSMauro Carvalho ChehabThe original implementation __do_IRQ() was an alternative entry point
373*3bd3b99aSMauro Carvalho Chehabfor all types of interrupts. It no longer exists.
374*3bd3b99aSMauro Carvalho Chehab
375*3bd3b99aSMauro Carvalho ChehabThis handler turned out to be not suitable for all interrupt hardware
376*3bd3b99aSMauro Carvalho Chehaband was therefore reimplemented with split functionality for
377*3bd3b99aSMauro Carvalho Chehabedge/level/simple/percpu interrupts. This is not only a functional
378*3bd3b99aSMauro Carvalho Chehaboptimization. It also shortens code paths for interrupts.
379*3bd3b99aSMauro Carvalho Chehab
380*3bd3b99aSMauro Carvalho ChehabLocking on SMP
381*3bd3b99aSMauro Carvalho Chehab==============
382*3bd3b99aSMauro Carvalho Chehab
383*3bd3b99aSMauro Carvalho ChehabThe locking of chip registers is up to the architecture that defines the
384*3bd3b99aSMauro Carvalho Chehabchip primitives. The per-irq structure is protected via desc->lock, by
385*3bd3b99aSMauro Carvalho Chehabthe generic layer.
386*3bd3b99aSMauro Carvalho Chehab
387*3bd3b99aSMauro Carvalho ChehabGeneric interrupt chip
388*3bd3b99aSMauro Carvalho Chehab======================
389*3bd3b99aSMauro Carvalho Chehab
390*3bd3b99aSMauro Carvalho ChehabTo avoid copies of identical implementations of IRQ chips the core
391*3bd3b99aSMauro Carvalho Chehabprovides a configurable generic interrupt chip implementation.
392*3bd3b99aSMauro Carvalho ChehabDevelopers should check carefully whether the generic chip fits their
393*3bd3b99aSMauro Carvalho Chehabneeds before implementing the same functionality slightly differently
394*3bd3b99aSMauro Carvalho Chehabthemselves.
395*3bd3b99aSMauro Carvalho Chehab
396*3bd3b99aSMauro Carvalho Chehab.. kernel-doc:: kernel/irq/generic-chip.c
397*3bd3b99aSMauro Carvalho Chehab   :export:
398*3bd3b99aSMauro Carvalho Chehab
399*3bd3b99aSMauro Carvalho ChehabStructures
400*3bd3b99aSMauro Carvalho Chehab==========
401*3bd3b99aSMauro Carvalho Chehab
402*3bd3b99aSMauro Carvalho ChehabThis chapter contains the autogenerated documentation of the structures
403*3bd3b99aSMauro Carvalho Chehabwhich are used in the generic IRQ layer.
404*3bd3b99aSMauro Carvalho Chehab
405*3bd3b99aSMauro Carvalho Chehab.. kernel-doc:: include/linux/irq.h
406*3bd3b99aSMauro Carvalho Chehab   :internal:
407*3bd3b99aSMauro Carvalho Chehab
408*3bd3b99aSMauro Carvalho Chehab.. kernel-doc:: include/linux/interrupt.h
409*3bd3b99aSMauro Carvalho Chehab   :internal:
410*3bd3b99aSMauro Carvalho Chehab
411*3bd3b99aSMauro Carvalho ChehabPublic Functions Provided
412*3bd3b99aSMauro Carvalho Chehab=========================
413*3bd3b99aSMauro Carvalho Chehab
414*3bd3b99aSMauro Carvalho ChehabThis chapter contains the autogenerated documentation of the kernel API
415*3bd3b99aSMauro Carvalho Chehabfunctions which are exported.
416*3bd3b99aSMauro Carvalho Chehab
417*3bd3b99aSMauro Carvalho Chehab.. kernel-doc:: kernel/irq/manage.c
418*3bd3b99aSMauro Carvalho Chehab   :export:
419*3bd3b99aSMauro Carvalho Chehab
420*3bd3b99aSMauro Carvalho Chehab.. kernel-doc:: kernel/irq/chip.c
421*3bd3b99aSMauro Carvalho Chehab   :export:
422*3bd3b99aSMauro Carvalho Chehab
423*3bd3b99aSMauro Carvalho ChehabInternal Functions Provided
424*3bd3b99aSMauro Carvalho Chehab===========================
425*3bd3b99aSMauro Carvalho Chehab
426*3bd3b99aSMauro Carvalho ChehabThis chapter contains the autogenerated documentation of the internal
427*3bd3b99aSMauro Carvalho Chehabfunctions.
428*3bd3b99aSMauro Carvalho Chehab
429*3bd3b99aSMauro Carvalho Chehab.. kernel-doc:: kernel/irq/irqdesc.c
430*3bd3b99aSMauro Carvalho Chehab   :internal:
431*3bd3b99aSMauro Carvalho Chehab
432*3bd3b99aSMauro Carvalho Chehab.. kernel-doc:: kernel/irq/handle.c
433*3bd3b99aSMauro Carvalho Chehab   :internal:
434*3bd3b99aSMauro Carvalho Chehab
435*3bd3b99aSMauro Carvalho Chehab.. kernel-doc:: kernel/irq/chip.c
436*3bd3b99aSMauro Carvalho Chehab   :internal:
437*3bd3b99aSMauro Carvalho Chehab
438*3bd3b99aSMauro Carvalho ChehabCredits
439*3bd3b99aSMauro Carvalho Chehab=======
440*3bd3b99aSMauro Carvalho Chehab
441*3bd3b99aSMauro Carvalho ChehabThe following people have contributed to this document:
442*3bd3b99aSMauro Carvalho Chehab
443*3bd3b99aSMauro Carvalho Chehab1. Thomas Gleixner tglx@linutronix.de
444*3bd3b99aSMauro Carvalho Chehab
445*3bd3b99aSMauro Carvalho Chehab2. Ingo Molnar mingo@elte.hu
446