~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/Documentation/core-api/genericirq.rst

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php