xref: /openbmc/linux/Documentation/core-api/genericirq.rst (revision c900529f3d9161bfde5cca0754f83b4d3c3e0220)
13bd3b99aSMauro Carvalho Chehab.. include:: <isonum.txt>
23bd3b99aSMauro Carvalho Chehab
33bd3b99aSMauro Carvalho Chehab==========================
43bd3b99aSMauro Carvalho ChehabLinux generic IRQ handling
53bd3b99aSMauro Carvalho Chehab==========================
63bd3b99aSMauro Carvalho Chehab
73bd3b99aSMauro Carvalho Chehab:Copyright: |copy| 2005-2010: Thomas Gleixner
83bd3b99aSMauro Carvalho Chehab:Copyright: |copy| 2005-2006:  Ingo Molnar
93bd3b99aSMauro Carvalho Chehab
103bd3b99aSMauro Carvalho ChehabIntroduction
113bd3b99aSMauro Carvalho Chehab============
123bd3b99aSMauro Carvalho Chehab
133bd3b99aSMauro Carvalho ChehabThe generic interrupt handling layer is designed to provide a complete
143bd3b99aSMauro Carvalho Chehababstraction of interrupt handling for device drivers. It is able to
153bd3b99aSMauro Carvalho Chehabhandle all the different types of interrupt controller hardware. Device
163bd3b99aSMauro Carvalho Chehabdrivers use generic API functions to request, enable, disable and free
173bd3b99aSMauro Carvalho Chehabinterrupts. The drivers do not have to know anything about interrupt
183bd3b99aSMauro Carvalho Chehabhardware details, so they can be used on different platforms without
193bd3b99aSMauro Carvalho Chehabcode changes.
203bd3b99aSMauro Carvalho Chehab
213bd3b99aSMauro Carvalho ChehabThis documentation is provided to developers who want to implement an
223bd3b99aSMauro Carvalho Chehabinterrupt subsystem based for their architecture, with the help of the
233bd3b99aSMauro Carvalho Chehabgeneric IRQ handling layer.
243bd3b99aSMauro Carvalho Chehab
253bd3b99aSMauro Carvalho ChehabRationale
263bd3b99aSMauro Carvalho Chehab=========
273bd3b99aSMauro Carvalho Chehab
283bd3b99aSMauro Carvalho ChehabThe original implementation of interrupt handling in Linux uses the
2985c2a0edSJonathan Corbet__do_IRQ() super-handler, which is able to deal with every type of
303bd3b99aSMauro Carvalho Chehabinterrupt logic.
313bd3b99aSMauro Carvalho Chehab
323bd3b99aSMauro Carvalho ChehabOriginally, Russell King identified different types of handlers to build
333bd3b99aSMauro Carvalho Chehaba quite universal set for the ARM interrupt handler implementation in
343bd3b99aSMauro Carvalho ChehabLinux 2.5/2.6. He distinguished between:
353bd3b99aSMauro Carvalho Chehab
363bd3b99aSMauro Carvalho Chehab-  Level type
373bd3b99aSMauro Carvalho Chehab
383bd3b99aSMauro Carvalho Chehab-  Edge type
393bd3b99aSMauro Carvalho Chehab
403bd3b99aSMauro Carvalho Chehab-  Simple type
413bd3b99aSMauro Carvalho Chehab
423bd3b99aSMauro Carvalho ChehabDuring the implementation we identified another type:
433bd3b99aSMauro Carvalho Chehab
443bd3b99aSMauro Carvalho Chehab-  Fast EOI type
453bd3b99aSMauro Carvalho Chehab
4685c2a0edSJonathan CorbetIn the SMP world of the __do_IRQ() super-handler another type was
473bd3b99aSMauro Carvalho Chehabidentified:
483bd3b99aSMauro Carvalho Chehab
493bd3b99aSMauro Carvalho Chehab-  Per CPU type
503bd3b99aSMauro Carvalho Chehab
513bd3b99aSMauro Carvalho ChehabThis split implementation of high-level IRQ handlers allows us to
523bd3b99aSMauro Carvalho Chehaboptimize the flow of the interrupt handling for each specific interrupt
533bd3b99aSMauro Carvalho Chehabtype. This reduces complexity in that particular code path and allows
543bd3b99aSMauro Carvalho Chehabthe optimized handling of a given type.
553bd3b99aSMauro Carvalho Chehab
563bd3b99aSMauro Carvalho ChehabThe original general IRQ implementation used hw_interrupt_type
5776d40faeSMauro Carvalho Chehabstructures and their ``->ack``, ``->end`` [etc.] callbacks to differentiate
583bd3b99aSMauro Carvalho Chehabthe flow control in the super-handler. This leads to a mix of flow logic
593bd3b99aSMauro Carvalho Chehaband low-level hardware logic, and it also leads to unnecessary code
6076d40faeSMauro Carvalho Chehabduplication: for example in i386, there is an ``ioapic_level_irq`` and an
6176d40faeSMauro Carvalho Chehab``ioapic_edge_irq`` IRQ-type which share many of the low-level details but
623bd3b99aSMauro Carvalho Chehabhave different flow handling.
633bd3b99aSMauro Carvalho Chehab
643bd3b99aSMauro Carvalho ChehabA more natural abstraction is the clean separation of the 'irq flow' and
653bd3b99aSMauro Carvalho Chehabthe 'chip details'.
663bd3b99aSMauro Carvalho Chehab
673bd3b99aSMauro Carvalho ChehabAnalysing a couple of architecture's IRQ subsystem implementations
683bd3b99aSMauro Carvalho Chehabreveals that most of them can use a generic set of 'irq flow' methods
693bd3b99aSMauro Carvalho Chehaband only need to add the chip-level specific code. The separation is
703bd3b99aSMauro Carvalho Chehabalso valuable for (sub)architectures which need specific quirks in the
713bd3b99aSMauro Carvalho ChehabIRQ flow itself but not in the chip details - and thus provides a more
723bd3b99aSMauro Carvalho Chehabtransparent IRQ subsystem design.
733bd3b99aSMauro Carvalho Chehab
743bd3b99aSMauro Carvalho ChehabEach interrupt descriptor is assigned its own high-level flow handler,
753bd3b99aSMauro Carvalho Chehabwhich is normally one of the generic implementations. (This high-level
763bd3b99aSMauro Carvalho Chehabflow handler implementation also makes it simple to provide
773bd3b99aSMauro Carvalho Chehabdemultiplexing handlers which can be found in embedded platforms on
783bd3b99aSMauro Carvalho Chehabvarious architectures.)
793bd3b99aSMauro Carvalho Chehab
803bd3b99aSMauro Carvalho ChehabThe separation makes the generic interrupt handling layer more flexible
813bd3b99aSMauro Carvalho Chehaband extensible. For example, an (sub)architecture can use a generic
823bd3b99aSMauro Carvalho ChehabIRQ-flow implementation for 'level type' interrupts and add a
833bd3b99aSMauro Carvalho Chehab(sub)architecture specific 'edge type' implementation.
843bd3b99aSMauro Carvalho Chehab
853bd3b99aSMauro Carvalho ChehabTo make the transition to the new model easier and prevent the breakage
8685c2a0edSJonathan Corbetof existing implementations, the __do_IRQ() super-handler is still
873bd3b99aSMauro Carvalho Chehabavailable. This leads to a kind of duality for the time being. Over time
883bd3b99aSMauro Carvalho Chehabthe new model should be used in more and more architectures, as it
893bd3b99aSMauro Carvalho Chehabenables smaller and cleaner IRQ subsystems. It's deprecated for three
903bd3b99aSMauro Carvalho Chehabyears now and about to be removed.
913bd3b99aSMauro Carvalho Chehab
923bd3b99aSMauro Carvalho ChehabKnown Bugs And Assumptions
933bd3b99aSMauro Carvalho Chehab==========================
943bd3b99aSMauro Carvalho Chehab
953bd3b99aSMauro Carvalho ChehabNone (knock on wood).
963bd3b99aSMauro Carvalho Chehab
973bd3b99aSMauro Carvalho ChehabAbstraction layers
983bd3b99aSMauro Carvalho Chehab==================
993bd3b99aSMauro Carvalho Chehab
1003bd3b99aSMauro Carvalho ChehabThere are three main levels of abstraction in the interrupt code:
1013bd3b99aSMauro Carvalho Chehab
1023bd3b99aSMauro Carvalho Chehab1. High-level driver API
1033bd3b99aSMauro Carvalho Chehab
1043bd3b99aSMauro Carvalho Chehab2. High-level IRQ flow handlers
1053bd3b99aSMauro Carvalho Chehab
1063bd3b99aSMauro Carvalho Chehab3. Chip-level hardware encapsulation
1073bd3b99aSMauro Carvalho Chehab
1083bd3b99aSMauro Carvalho ChehabInterrupt control flow
1093bd3b99aSMauro Carvalho Chehab----------------------
1103bd3b99aSMauro Carvalho Chehab
1113bd3b99aSMauro Carvalho ChehabEach interrupt is described by an interrupt descriptor structure
1123bd3b99aSMauro Carvalho Chehabirq_desc. The interrupt is referenced by an 'unsigned int' numeric
1133bd3b99aSMauro Carvalho Chehabvalue which selects the corresponding interrupt description structure in
1143bd3b99aSMauro Carvalho Chehabthe descriptor structures array. The descriptor structure contains
1153bd3b99aSMauro Carvalho Chehabstatus information and pointers to the interrupt flow method and the
1163bd3b99aSMauro Carvalho Chehabinterrupt chip structure which are assigned to this interrupt.
1173bd3b99aSMauro Carvalho Chehab
1183bd3b99aSMauro Carvalho ChehabWhenever an interrupt triggers, the low-level architecture code calls
11985c2a0edSJonathan Corbetinto the generic interrupt code by calling desc->handle_irq(). This
1203bd3b99aSMauro Carvalho Chehabhigh-level IRQ handling function only uses desc->irq_data.chip
1213bd3b99aSMauro Carvalho Chehabprimitives referenced by the assigned chip descriptor structure.
1223bd3b99aSMauro Carvalho Chehab
1233bd3b99aSMauro Carvalho ChehabHigh-level Driver API
1243bd3b99aSMauro Carvalho Chehab---------------------
1253bd3b99aSMauro Carvalho Chehab
1263bd3b99aSMauro Carvalho ChehabThe high-level Driver API consists of following functions:
1273bd3b99aSMauro Carvalho Chehab
12885c2a0edSJonathan Corbet-  request_irq()
1293bd3b99aSMauro Carvalho Chehab
1305ca470a0SJonathan Corbet-  request_threaded_irq()
1315ca470a0SJonathan Corbet
13285c2a0edSJonathan Corbet-  free_irq()
1333bd3b99aSMauro Carvalho Chehab
13485c2a0edSJonathan Corbet-  disable_irq()
1353bd3b99aSMauro Carvalho Chehab
13685c2a0edSJonathan Corbet-  enable_irq()
1373bd3b99aSMauro Carvalho Chehab
13885c2a0edSJonathan Corbet-  disable_irq_nosync() (SMP only)
1393bd3b99aSMauro Carvalho Chehab
14085c2a0edSJonathan Corbet-  synchronize_irq() (SMP only)
1413bd3b99aSMauro Carvalho Chehab
14285c2a0edSJonathan Corbet-  irq_set_irq_type()
1433bd3b99aSMauro Carvalho Chehab
14485c2a0edSJonathan Corbet-  irq_set_irq_wake()
1453bd3b99aSMauro Carvalho Chehab
14685c2a0edSJonathan Corbet-  irq_set_handler_data()
1473bd3b99aSMauro Carvalho Chehab
14885c2a0edSJonathan Corbet-  irq_set_chip()
1493bd3b99aSMauro Carvalho Chehab
15085c2a0edSJonathan Corbet-  irq_set_chip_data()
1513bd3b99aSMauro Carvalho Chehab
1523bd3b99aSMauro Carvalho ChehabSee the autogenerated function documentation for details.
1533bd3b99aSMauro Carvalho Chehab
1543bd3b99aSMauro Carvalho ChehabHigh-level IRQ flow handlers
1553bd3b99aSMauro Carvalho Chehab----------------------------
1563bd3b99aSMauro Carvalho Chehab
1573bd3b99aSMauro Carvalho ChehabThe generic layer provides a set of pre-defined irq-flow methods:
1583bd3b99aSMauro Carvalho Chehab
15985c2a0edSJonathan Corbet-  handle_level_irq()
1603bd3b99aSMauro Carvalho Chehab
16185c2a0edSJonathan Corbet-  handle_edge_irq()
1623bd3b99aSMauro Carvalho Chehab
16385c2a0edSJonathan Corbet-  handle_fasteoi_irq()
1643bd3b99aSMauro Carvalho Chehab
16585c2a0edSJonathan Corbet-  handle_simple_irq()
1663bd3b99aSMauro Carvalho Chehab
16785c2a0edSJonathan Corbet-  handle_percpu_irq()
1683bd3b99aSMauro Carvalho Chehab
16985c2a0edSJonathan Corbet-  handle_edge_eoi_irq()
1703bd3b99aSMauro Carvalho Chehab
17185c2a0edSJonathan Corbet-  handle_bad_irq()
1723bd3b99aSMauro Carvalho Chehab
1733bd3b99aSMauro Carvalho ChehabThe interrupt flow handlers (either pre-defined or architecture
1743bd3b99aSMauro Carvalho Chehabspecific) are assigned to specific interrupts by the architecture either
1753bd3b99aSMauro Carvalho Chehabduring bootup or during device initialization.
1763bd3b99aSMauro Carvalho Chehab
1773bd3b99aSMauro Carvalho ChehabDefault flow implementations
1783bd3b99aSMauro Carvalho Chehab~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1793bd3b99aSMauro Carvalho Chehab
1803bd3b99aSMauro Carvalho ChehabHelper functions
1813bd3b99aSMauro Carvalho Chehab^^^^^^^^^^^^^^^^
1823bd3b99aSMauro Carvalho Chehab
1833bd3b99aSMauro Carvalho ChehabThe helper functions call the chip primitives and are used by the
1843bd3b99aSMauro Carvalho Chehabdefault flow implementations. The following helper functions are
1853bd3b99aSMauro Carvalho Chehabimplemented (simplified excerpt)::
1863bd3b99aSMauro Carvalho Chehab
1873bd3b99aSMauro Carvalho Chehab    default_enable(struct irq_data *data)
1883bd3b99aSMauro Carvalho Chehab    {
1893bd3b99aSMauro Carvalho Chehab        desc->irq_data.chip->irq_unmask(data);
1903bd3b99aSMauro Carvalho Chehab    }
1913bd3b99aSMauro Carvalho Chehab
1923bd3b99aSMauro Carvalho Chehab    default_disable(struct irq_data *data)
1933bd3b99aSMauro Carvalho Chehab    {
1943bd3b99aSMauro Carvalho Chehab        if (!delay_disable(data))
1953bd3b99aSMauro Carvalho Chehab            desc->irq_data.chip->irq_mask(data);
1963bd3b99aSMauro Carvalho Chehab    }
1973bd3b99aSMauro Carvalho Chehab
1983bd3b99aSMauro Carvalho Chehab    default_ack(struct irq_data *data)
1993bd3b99aSMauro Carvalho Chehab    {
2003bd3b99aSMauro Carvalho Chehab        chip->irq_ack(data);
2013bd3b99aSMauro Carvalho Chehab    }
2023bd3b99aSMauro Carvalho Chehab
2033bd3b99aSMauro Carvalho Chehab    default_mask_ack(struct irq_data *data)
2043bd3b99aSMauro Carvalho Chehab    {
2053bd3b99aSMauro Carvalho Chehab        if (chip->irq_mask_ack) {
2063bd3b99aSMauro Carvalho Chehab            chip->irq_mask_ack(data);
2073bd3b99aSMauro Carvalho Chehab        } else {
2083bd3b99aSMauro Carvalho Chehab            chip->irq_mask(data);
2093bd3b99aSMauro Carvalho Chehab            chip->irq_ack(data);
2103bd3b99aSMauro Carvalho Chehab        }
2113bd3b99aSMauro Carvalho Chehab    }
2123bd3b99aSMauro Carvalho Chehab
2133bd3b99aSMauro Carvalho Chehab    noop(struct irq_data *data))
2143bd3b99aSMauro Carvalho Chehab    {
2153bd3b99aSMauro Carvalho Chehab    }
2163bd3b99aSMauro Carvalho Chehab
2173bd3b99aSMauro Carvalho Chehab
2183bd3b99aSMauro Carvalho Chehab
2193bd3b99aSMauro Carvalho ChehabDefault flow handler implementations
2203bd3b99aSMauro Carvalho Chehab~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2213bd3b99aSMauro Carvalho Chehab
2223bd3b99aSMauro Carvalho ChehabDefault Level IRQ flow handler
2233bd3b99aSMauro Carvalho Chehab^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2243bd3b99aSMauro Carvalho Chehab
2253bd3b99aSMauro Carvalho Chehabhandle_level_irq provides a generic implementation for level-triggered
2263bd3b99aSMauro Carvalho Chehabinterrupts.
2273bd3b99aSMauro Carvalho Chehab
2283bd3b99aSMauro Carvalho ChehabThe following control flow is implemented (simplified excerpt)::
2293bd3b99aSMauro Carvalho Chehab
2300f83aaa3SJonathan Neuschäfer    desc->irq_data.chip->irq_mask_ack();
2313bd3b99aSMauro Carvalho Chehab    handle_irq_event(desc->action);
2320f83aaa3SJonathan Neuschäfer    desc->irq_data.chip->irq_unmask();
2333bd3b99aSMauro Carvalho Chehab
2343bd3b99aSMauro Carvalho Chehab
2353bd3b99aSMauro Carvalho ChehabDefault Fast EOI IRQ flow handler
2363bd3b99aSMauro Carvalho Chehab^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2373bd3b99aSMauro Carvalho Chehab
2383bd3b99aSMauro Carvalho Chehabhandle_fasteoi_irq provides a generic implementation for interrupts,
2393bd3b99aSMauro Carvalho Chehabwhich only need an EOI at the end of the handler.
2403bd3b99aSMauro Carvalho Chehab
2413bd3b99aSMauro Carvalho ChehabThe following control flow is implemented (simplified excerpt)::
2423bd3b99aSMauro Carvalho Chehab
2433bd3b99aSMauro Carvalho Chehab    handle_irq_event(desc->action);
2440f83aaa3SJonathan Neuschäfer    desc->irq_data.chip->irq_eoi();
2453bd3b99aSMauro Carvalho Chehab
2463bd3b99aSMauro Carvalho Chehab
2473bd3b99aSMauro Carvalho ChehabDefault Edge IRQ flow handler
2483bd3b99aSMauro Carvalho Chehab^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2493bd3b99aSMauro Carvalho Chehab
2503bd3b99aSMauro Carvalho Chehabhandle_edge_irq provides a generic implementation for edge-triggered
2513bd3b99aSMauro Carvalho Chehabinterrupts.
2523bd3b99aSMauro Carvalho Chehab
2533bd3b99aSMauro Carvalho ChehabThe following control flow is implemented (simplified excerpt)::
2543bd3b99aSMauro Carvalho Chehab
2553bd3b99aSMauro Carvalho Chehab    if (desc->status & running) {
2560f83aaa3SJonathan Neuschäfer        desc->irq_data.chip->irq_mask_ack();
2573bd3b99aSMauro Carvalho Chehab        desc->status |= pending | masked;
2583bd3b99aSMauro Carvalho Chehab        return;
2593bd3b99aSMauro Carvalho Chehab    }
2600f83aaa3SJonathan Neuschäfer    desc->irq_data.chip->irq_ack();
2613bd3b99aSMauro Carvalho Chehab    desc->status |= running;
2623bd3b99aSMauro Carvalho Chehab    do {
2633bd3b99aSMauro Carvalho Chehab        if (desc->status & masked)
2640f83aaa3SJonathan Neuschäfer            desc->irq_data.chip->irq_unmask();
2653bd3b99aSMauro Carvalho Chehab        desc->status &= ~pending;
2663bd3b99aSMauro Carvalho Chehab        handle_irq_event(desc->action);
267*c63594f2SPhilipp Stanner    } while (desc->status & pending);
2683bd3b99aSMauro Carvalho Chehab    desc->status &= ~running;
2693bd3b99aSMauro Carvalho Chehab
2703bd3b99aSMauro Carvalho Chehab
2713bd3b99aSMauro Carvalho ChehabDefault simple IRQ flow handler
2723bd3b99aSMauro Carvalho Chehab^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2733bd3b99aSMauro Carvalho Chehab
2743bd3b99aSMauro Carvalho Chehabhandle_simple_irq provides a generic implementation for simple
2753bd3b99aSMauro Carvalho Chehabinterrupts.
2763bd3b99aSMauro Carvalho Chehab
2773bd3b99aSMauro Carvalho Chehab.. note::
2783bd3b99aSMauro Carvalho Chehab
2793bd3b99aSMauro Carvalho Chehab   The simple flow handler does not call any handler/chip primitives.
2803bd3b99aSMauro Carvalho Chehab
2813bd3b99aSMauro Carvalho ChehabThe following control flow is implemented (simplified excerpt)::
2823bd3b99aSMauro Carvalho Chehab
2833bd3b99aSMauro Carvalho Chehab    handle_irq_event(desc->action);
2843bd3b99aSMauro Carvalho Chehab
2853bd3b99aSMauro Carvalho Chehab
2863bd3b99aSMauro Carvalho ChehabDefault per CPU flow handler
2873bd3b99aSMauro Carvalho Chehab^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2883bd3b99aSMauro Carvalho Chehab
2893bd3b99aSMauro Carvalho Chehabhandle_percpu_irq provides a generic implementation for per CPU
2903bd3b99aSMauro Carvalho Chehabinterrupts.
2913bd3b99aSMauro Carvalho Chehab
2923bd3b99aSMauro Carvalho ChehabPer CPU interrupts are only available on SMP and the handler provides a
2933bd3b99aSMauro Carvalho Chehabsimplified version without locking.
2943bd3b99aSMauro Carvalho Chehab
2953bd3b99aSMauro Carvalho ChehabThe following control flow is implemented (simplified excerpt)::
2963bd3b99aSMauro Carvalho Chehab
2973bd3b99aSMauro Carvalho Chehab    if (desc->irq_data.chip->irq_ack)
2980f83aaa3SJonathan Neuschäfer        desc->irq_data.chip->irq_ack();
2993bd3b99aSMauro Carvalho Chehab    handle_irq_event(desc->action);
3003bd3b99aSMauro Carvalho Chehab    if (desc->irq_data.chip->irq_eoi)
3010f83aaa3SJonathan Neuschäfer        desc->irq_data.chip->irq_eoi();
3023bd3b99aSMauro Carvalho Chehab
3033bd3b99aSMauro Carvalho Chehab
3043bd3b99aSMauro Carvalho ChehabEOI Edge IRQ flow handler
3053bd3b99aSMauro Carvalho Chehab^^^^^^^^^^^^^^^^^^^^^^^^^
3063bd3b99aSMauro Carvalho Chehab
3073bd3b99aSMauro Carvalho Chehabhandle_edge_eoi_irq provides an abnomination of the edge handler
3083bd3b99aSMauro Carvalho Chehabwhich is solely used to tame a badly wreckaged irq controller on
3093bd3b99aSMauro Carvalho Chehabpowerpc/cell.
3103bd3b99aSMauro Carvalho Chehab
3113bd3b99aSMauro Carvalho ChehabBad IRQ flow handler
3123bd3b99aSMauro Carvalho Chehab^^^^^^^^^^^^^^^^^^^^
3133bd3b99aSMauro Carvalho Chehab
3143bd3b99aSMauro Carvalho Chehabhandle_bad_irq is used for spurious interrupts which have no real
3153bd3b99aSMauro Carvalho Chehabhandler assigned..
3163bd3b99aSMauro Carvalho Chehab
3173bd3b99aSMauro Carvalho ChehabQuirks and optimizations
3183bd3b99aSMauro Carvalho Chehab~~~~~~~~~~~~~~~~~~~~~~~~
3193bd3b99aSMauro Carvalho Chehab
3203bd3b99aSMauro Carvalho ChehabThe generic functions are intended for 'clean' architectures and chips,
3213bd3b99aSMauro Carvalho Chehabwhich have no platform-specific IRQ handling quirks. If an architecture
3223bd3b99aSMauro Carvalho Chehabneeds to implement quirks on the 'flow' level then it can do so by
3233bd3b99aSMauro Carvalho Chehaboverriding the high-level irq-flow handler.
3243bd3b99aSMauro Carvalho Chehab
3253bd3b99aSMauro Carvalho ChehabDelayed interrupt disable
3263bd3b99aSMauro Carvalho Chehab~~~~~~~~~~~~~~~~~~~~~~~~~
3273bd3b99aSMauro Carvalho Chehab
3283bd3b99aSMauro Carvalho ChehabThis per interrupt selectable feature, which was introduced by Russell
3293bd3b99aSMauro Carvalho ChehabKing in the ARM interrupt implementation, does not mask an interrupt at
33085c2a0edSJonathan Corbetthe hardware level when disable_irq() is called. The interrupt is kept
3313bd3b99aSMauro Carvalho Chehabenabled and is masked in the flow handler when an interrupt event
3323bd3b99aSMauro Carvalho Chehabhappens. This prevents losing edge interrupts on hardware which does not
3333bd3b99aSMauro Carvalho Chehabstore an edge interrupt event while the interrupt is disabled at the
3343bd3b99aSMauro Carvalho Chehabhardware level. When an interrupt arrives while the IRQ_DISABLED flag
3353bd3b99aSMauro Carvalho Chehabis set, then the interrupt is masked at the hardware level and the
3363bd3b99aSMauro Carvalho ChehabIRQ_PENDING bit is set. When the interrupt is re-enabled by
33785c2a0edSJonathan Corbetenable_irq() the pending bit is checked and if it is set, the interrupt
3383bd3b99aSMauro Carvalho Chehabis resent either via hardware or by a software resend mechanism. (It's
3393bd3b99aSMauro Carvalho Chehabnecessary to enable CONFIG_HARDIRQS_SW_RESEND when you want to use
3403bd3b99aSMauro Carvalho Chehabthe delayed interrupt disable feature and your hardware is not capable
3413bd3b99aSMauro Carvalho Chehabof retriggering an interrupt.) The delayed interrupt disable is not
3423bd3b99aSMauro Carvalho Chehabconfigurable.
3433bd3b99aSMauro Carvalho Chehab
3443bd3b99aSMauro Carvalho ChehabChip-level hardware encapsulation
3453bd3b99aSMauro Carvalho Chehab---------------------------------
3463bd3b99aSMauro Carvalho Chehab
34776d40faeSMauro Carvalho ChehabThe chip-level hardware descriptor structure :c:type:`irq_chip` contains all
34876d40faeSMauro Carvalho Chehabthe direct chip relevant functions, which can be utilized by the irq flow
3493bd3b99aSMauro Carvalho Chehabimplementations.
3503bd3b99aSMauro Carvalho Chehab
35176d40faeSMauro Carvalho Chehab-  ``irq_ack``
3523bd3b99aSMauro Carvalho Chehab
35376d40faeSMauro Carvalho Chehab-  ``irq_mask_ack`` - Optional, recommended for performance
3543bd3b99aSMauro Carvalho Chehab
35576d40faeSMauro Carvalho Chehab-  ``irq_mask``
3563bd3b99aSMauro Carvalho Chehab
35776d40faeSMauro Carvalho Chehab-  ``irq_unmask``
3583bd3b99aSMauro Carvalho Chehab
35976d40faeSMauro Carvalho Chehab-  ``irq_eoi`` - Optional, required for EOI flow handlers
3603bd3b99aSMauro Carvalho Chehab
36176d40faeSMauro Carvalho Chehab-  ``irq_retrigger`` - Optional
3623bd3b99aSMauro Carvalho Chehab
36376d40faeSMauro Carvalho Chehab-  ``irq_set_type`` - Optional
3643bd3b99aSMauro Carvalho Chehab
36576d40faeSMauro Carvalho Chehab-  ``irq_set_wake`` - Optional
3663bd3b99aSMauro Carvalho Chehab
3673bd3b99aSMauro Carvalho ChehabThese primitives are strictly intended to mean what they say: ack means
3683bd3b99aSMauro Carvalho ChehabACK, masking means masking of an IRQ line, etc. It is up to the flow
3693bd3b99aSMauro Carvalho Chehabhandler(s) to use these basic units of low-level functionality.
3703bd3b99aSMauro Carvalho Chehab
3713bd3b99aSMauro Carvalho Chehab__do_IRQ entry point
3723bd3b99aSMauro Carvalho Chehab====================
3733bd3b99aSMauro Carvalho Chehab
37485c2a0edSJonathan CorbetThe original implementation __do_IRQ() was an alternative entry point
3753bd3b99aSMauro Carvalho Chehabfor all types of interrupts. It no longer exists.
3763bd3b99aSMauro Carvalho Chehab
3773bd3b99aSMauro Carvalho ChehabThis handler turned out to be not suitable for all interrupt hardware
3783bd3b99aSMauro Carvalho Chehaband was therefore reimplemented with split functionality for
3793bd3b99aSMauro Carvalho Chehabedge/level/simple/percpu interrupts. This is not only a functional
3803bd3b99aSMauro Carvalho Chehaboptimization. It also shortens code paths for interrupts.
3813bd3b99aSMauro Carvalho Chehab
3823bd3b99aSMauro Carvalho ChehabLocking on SMP
3833bd3b99aSMauro Carvalho Chehab==============
3843bd3b99aSMauro Carvalho Chehab
3853bd3b99aSMauro Carvalho ChehabThe locking of chip registers is up to the architecture that defines the
3863bd3b99aSMauro Carvalho Chehabchip primitives. The per-irq structure is protected via desc->lock, by
3873bd3b99aSMauro Carvalho Chehabthe generic layer.
3883bd3b99aSMauro Carvalho Chehab
3893bd3b99aSMauro Carvalho ChehabGeneric interrupt chip
3903bd3b99aSMauro Carvalho Chehab======================
3913bd3b99aSMauro Carvalho Chehab
3923bd3b99aSMauro Carvalho ChehabTo avoid copies of identical implementations of IRQ chips the core
3933bd3b99aSMauro Carvalho Chehabprovides a configurable generic interrupt chip implementation.
3943bd3b99aSMauro Carvalho ChehabDevelopers should check carefully whether the generic chip fits their
3953bd3b99aSMauro Carvalho Chehabneeds before implementing the same functionality slightly differently
3963bd3b99aSMauro Carvalho Chehabthemselves.
3973bd3b99aSMauro Carvalho Chehab
3983bd3b99aSMauro Carvalho Chehab.. kernel-doc:: kernel/irq/generic-chip.c
3993bd3b99aSMauro Carvalho Chehab   :export:
4003bd3b99aSMauro Carvalho Chehab
4013bd3b99aSMauro Carvalho ChehabStructures
4023bd3b99aSMauro Carvalho Chehab==========
4033bd3b99aSMauro Carvalho Chehab
4043bd3b99aSMauro Carvalho ChehabThis chapter contains the autogenerated documentation of the structures
4053bd3b99aSMauro Carvalho Chehabwhich are used in the generic IRQ layer.
4063bd3b99aSMauro Carvalho Chehab
4073bd3b99aSMauro Carvalho Chehab.. kernel-doc:: include/linux/irq.h
4083bd3b99aSMauro Carvalho Chehab   :internal:
4093bd3b99aSMauro Carvalho Chehab
4103bd3b99aSMauro Carvalho Chehab.. kernel-doc:: include/linux/interrupt.h
4113bd3b99aSMauro Carvalho Chehab   :internal:
4123bd3b99aSMauro Carvalho Chehab
4133bd3b99aSMauro Carvalho ChehabPublic Functions Provided
4143bd3b99aSMauro Carvalho Chehab=========================
4153bd3b99aSMauro Carvalho Chehab
4163bd3b99aSMauro Carvalho ChehabThis chapter contains the autogenerated documentation of the kernel API
4173bd3b99aSMauro Carvalho Chehabfunctions which are exported.
4183bd3b99aSMauro Carvalho Chehab
4193bd3b99aSMauro Carvalho Chehab.. kernel-doc:: kernel/irq/manage.c
4203bd3b99aSMauro Carvalho Chehab
4213bd3b99aSMauro Carvalho Chehab.. kernel-doc:: kernel/irq/chip.c
4229b9b0bdaSMauro Carvalho Chehab   :export:
4233bd3b99aSMauro Carvalho Chehab
4243bd3b99aSMauro Carvalho ChehabInternal Functions Provided
4253bd3b99aSMauro Carvalho Chehab===========================
4263bd3b99aSMauro Carvalho Chehab
4273bd3b99aSMauro Carvalho ChehabThis chapter contains the autogenerated documentation of the internal
4283bd3b99aSMauro Carvalho Chehabfunctions.
4293bd3b99aSMauro Carvalho Chehab
4303bd3b99aSMauro Carvalho Chehab.. kernel-doc:: kernel/irq/irqdesc.c
4313bd3b99aSMauro Carvalho Chehab
4323bd3b99aSMauro Carvalho Chehab.. kernel-doc:: kernel/irq/handle.c
4333bd3b99aSMauro Carvalho Chehab
4343bd3b99aSMauro Carvalho Chehab.. kernel-doc:: kernel/irq/chip.c
4359b9b0bdaSMauro Carvalho Chehab   :internal:
4363bd3b99aSMauro Carvalho Chehab
4373bd3b99aSMauro Carvalho ChehabCredits
4383bd3b99aSMauro Carvalho Chehab=======
4393bd3b99aSMauro Carvalho Chehab
4403bd3b99aSMauro Carvalho ChehabThe following people have contributed to this document:
4413bd3b99aSMauro Carvalho Chehab
4423bd3b99aSMauro Carvalho Chehab1. Thomas Gleixner tglx@linutronix.de
4433bd3b99aSMauro Carvalho Chehab
4443bd3b99aSMauro Carvalho Chehab2. Ingo Molnar mingo@elte.hu
445