xref: /openbmc/linux/Documentation/core-api/genericirq.rst (revision 76d40fae13518e6c672cc7dcf78e66ca2cd3cb44)
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
29*76d40faeSMauro Carvalho Chehab:c:func:`__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
46*76d40faeSMauro Carvalho ChehabIn the SMP world of the :c:func:`__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
57*76d40faeSMauro 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
60*76d40faeSMauro Carvalho Chehabduplication: for example in i386, there is an ``ioapic_level_irq`` and an
61*76d40faeSMauro 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
86*76d40faeSMauro Carvalho Chehabof existing implementations, the :c:func:`__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
119*76d40faeSMauro Carvalho Chehabinto the generic interrupt code by calling :c:func:`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
128*76d40faeSMauro Carvalho Chehab-  :c:func:`request_irq`
1293bd3b99aSMauro Carvalho Chehab
130*76d40faeSMauro Carvalho Chehab-  :c:func:`free_irq`
1313bd3b99aSMauro Carvalho Chehab
132*76d40faeSMauro Carvalho Chehab-  :c:func:`disable_irq`
1333bd3b99aSMauro Carvalho Chehab
134*76d40faeSMauro Carvalho Chehab-  :c:func:`enable_irq`
1353bd3b99aSMauro Carvalho Chehab
136*76d40faeSMauro Carvalho Chehab-  :c:func:`disable_irq_nosync` (SMP only)
1373bd3b99aSMauro Carvalho Chehab
138*76d40faeSMauro Carvalho Chehab-  :c:func:`synchronize_irq` (SMP only)
1393bd3b99aSMauro Carvalho Chehab
140*76d40faeSMauro Carvalho Chehab-  :c:func:`irq_set_irq_type`
1413bd3b99aSMauro Carvalho Chehab
142*76d40faeSMauro Carvalho Chehab-  :c:func:`irq_set_irq_wake`
1433bd3b99aSMauro Carvalho Chehab
144*76d40faeSMauro Carvalho Chehab-  :c:func:`irq_set_handler_data`
1453bd3b99aSMauro Carvalho Chehab
146*76d40faeSMauro Carvalho Chehab-  :c:func:`irq_set_chip`
1473bd3b99aSMauro Carvalho Chehab
148*76d40faeSMauro Carvalho Chehab-  :c:func:`irq_set_chip_data`
1493bd3b99aSMauro Carvalho Chehab
1503bd3b99aSMauro Carvalho ChehabSee the autogenerated function documentation for details.
1513bd3b99aSMauro Carvalho Chehab
1523bd3b99aSMauro Carvalho ChehabHigh-level IRQ flow handlers
1533bd3b99aSMauro Carvalho Chehab----------------------------
1543bd3b99aSMauro Carvalho Chehab
1553bd3b99aSMauro Carvalho ChehabThe generic layer provides a set of pre-defined irq-flow methods:
1563bd3b99aSMauro Carvalho Chehab
157*76d40faeSMauro Carvalho Chehab-  :c:func:`handle_level_irq`
1583bd3b99aSMauro Carvalho Chehab
159*76d40faeSMauro Carvalho Chehab-  :c:func:`handle_edge_irq`
1603bd3b99aSMauro Carvalho Chehab
161*76d40faeSMauro Carvalho Chehab-  :c:func:`handle_fasteoi_irq`
1623bd3b99aSMauro Carvalho Chehab
163*76d40faeSMauro Carvalho Chehab-  :c:func:`handle_simple_irq`
1643bd3b99aSMauro Carvalho Chehab
165*76d40faeSMauro Carvalho Chehab-  :c:func:`handle_percpu_irq`
1663bd3b99aSMauro Carvalho Chehab
167*76d40faeSMauro Carvalho Chehab-  :c:func:`handle_edge_eoi_irq`
1683bd3b99aSMauro Carvalho Chehab
169*76d40faeSMauro Carvalho Chehab-  :c:func:`handle_bad_irq`
1703bd3b99aSMauro Carvalho Chehab
1713bd3b99aSMauro Carvalho ChehabThe interrupt flow handlers (either pre-defined or architecture
1723bd3b99aSMauro Carvalho Chehabspecific) are assigned to specific interrupts by the architecture either
1733bd3b99aSMauro Carvalho Chehabduring bootup or during device initialization.
1743bd3b99aSMauro Carvalho Chehab
1753bd3b99aSMauro Carvalho ChehabDefault flow implementations
1763bd3b99aSMauro Carvalho Chehab~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1773bd3b99aSMauro Carvalho Chehab
1783bd3b99aSMauro Carvalho ChehabHelper functions
1793bd3b99aSMauro Carvalho Chehab^^^^^^^^^^^^^^^^
1803bd3b99aSMauro Carvalho Chehab
1813bd3b99aSMauro Carvalho ChehabThe helper functions call the chip primitives and are used by the
1823bd3b99aSMauro Carvalho Chehabdefault flow implementations. The following helper functions are
1833bd3b99aSMauro Carvalho Chehabimplemented (simplified excerpt)::
1843bd3b99aSMauro Carvalho Chehab
1853bd3b99aSMauro Carvalho Chehab    default_enable(struct irq_data *data)
1863bd3b99aSMauro Carvalho Chehab    {
1873bd3b99aSMauro Carvalho Chehab        desc->irq_data.chip->irq_unmask(data);
1883bd3b99aSMauro Carvalho Chehab    }
1893bd3b99aSMauro Carvalho Chehab
1903bd3b99aSMauro Carvalho Chehab    default_disable(struct irq_data *data)
1913bd3b99aSMauro Carvalho Chehab    {
1923bd3b99aSMauro Carvalho Chehab        if (!delay_disable(data))
1933bd3b99aSMauro Carvalho Chehab            desc->irq_data.chip->irq_mask(data);
1943bd3b99aSMauro Carvalho Chehab    }
1953bd3b99aSMauro Carvalho Chehab
1963bd3b99aSMauro Carvalho Chehab    default_ack(struct irq_data *data)
1973bd3b99aSMauro Carvalho Chehab    {
1983bd3b99aSMauro Carvalho Chehab        chip->irq_ack(data);
1993bd3b99aSMauro Carvalho Chehab    }
2003bd3b99aSMauro Carvalho Chehab
2013bd3b99aSMauro Carvalho Chehab    default_mask_ack(struct irq_data *data)
2023bd3b99aSMauro Carvalho Chehab    {
2033bd3b99aSMauro Carvalho Chehab        if (chip->irq_mask_ack) {
2043bd3b99aSMauro Carvalho Chehab            chip->irq_mask_ack(data);
2053bd3b99aSMauro Carvalho Chehab        } else {
2063bd3b99aSMauro Carvalho Chehab            chip->irq_mask(data);
2073bd3b99aSMauro Carvalho Chehab            chip->irq_ack(data);
2083bd3b99aSMauro Carvalho Chehab        }
2093bd3b99aSMauro Carvalho Chehab    }
2103bd3b99aSMauro Carvalho Chehab
2113bd3b99aSMauro Carvalho Chehab    noop(struct irq_data *data))
2123bd3b99aSMauro Carvalho Chehab    {
2133bd3b99aSMauro Carvalho Chehab    }
2143bd3b99aSMauro Carvalho Chehab
2153bd3b99aSMauro Carvalho Chehab
2163bd3b99aSMauro Carvalho Chehab
2173bd3b99aSMauro Carvalho ChehabDefault flow handler implementations
2183bd3b99aSMauro Carvalho Chehab~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2193bd3b99aSMauro Carvalho Chehab
2203bd3b99aSMauro Carvalho ChehabDefault Level IRQ flow handler
2213bd3b99aSMauro Carvalho Chehab^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2223bd3b99aSMauro Carvalho Chehab
2233bd3b99aSMauro Carvalho Chehabhandle_level_irq provides a generic implementation for level-triggered
2243bd3b99aSMauro Carvalho Chehabinterrupts.
2253bd3b99aSMauro Carvalho Chehab
2263bd3b99aSMauro Carvalho ChehabThe following control flow is implemented (simplified excerpt)::
2273bd3b99aSMauro Carvalho Chehab
228*76d40faeSMauro Carvalho Chehab    :c:func:`desc->irq_data.chip->irq_mask_ack`;
2293bd3b99aSMauro Carvalho Chehab    handle_irq_event(desc->action);
230*76d40faeSMauro Carvalho Chehab    :c:func:`desc->irq_data.chip->irq_unmask`;
2313bd3b99aSMauro Carvalho Chehab
2323bd3b99aSMauro Carvalho Chehab
2333bd3b99aSMauro Carvalho ChehabDefault Fast EOI IRQ flow handler
2343bd3b99aSMauro Carvalho Chehab^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2353bd3b99aSMauro Carvalho Chehab
2363bd3b99aSMauro Carvalho Chehabhandle_fasteoi_irq provides a generic implementation for interrupts,
2373bd3b99aSMauro Carvalho Chehabwhich only need an EOI at the end of the handler.
2383bd3b99aSMauro Carvalho Chehab
2393bd3b99aSMauro Carvalho ChehabThe following control flow is implemented (simplified excerpt)::
2403bd3b99aSMauro Carvalho Chehab
2413bd3b99aSMauro Carvalho Chehab    handle_irq_event(desc->action);
242*76d40faeSMauro Carvalho Chehab    :c:func:`desc->irq_data.chip->irq_eoi`;
2433bd3b99aSMauro Carvalho Chehab
2443bd3b99aSMauro Carvalho Chehab
2453bd3b99aSMauro Carvalho ChehabDefault Edge IRQ flow handler
2463bd3b99aSMauro Carvalho Chehab^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2473bd3b99aSMauro Carvalho Chehab
2483bd3b99aSMauro Carvalho Chehabhandle_edge_irq provides a generic implementation for edge-triggered
2493bd3b99aSMauro Carvalho Chehabinterrupts.
2503bd3b99aSMauro Carvalho Chehab
2513bd3b99aSMauro Carvalho ChehabThe following control flow is implemented (simplified excerpt)::
2523bd3b99aSMauro Carvalho Chehab
2533bd3b99aSMauro Carvalho Chehab    if (desc->status & running) {
254*76d40faeSMauro Carvalho Chehab        :c:func:`desc->irq_data.chip->irq_mask_ack`;
2553bd3b99aSMauro Carvalho Chehab        desc->status |= pending | masked;
2563bd3b99aSMauro Carvalho Chehab        return;
2573bd3b99aSMauro Carvalho Chehab    }
258*76d40faeSMauro Carvalho Chehab    :c:func:`desc->irq_data.chip->irq_ack`;
2593bd3b99aSMauro Carvalho Chehab    desc->status |= running;
2603bd3b99aSMauro Carvalho Chehab    do {
2613bd3b99aSMauro Carvalho Chehab        if (desc->status & masked)
262*76d40faeSMauro Carvalho Chehab            :c:func:`desc->irq_data.chip->irq_unmask`;
2633bd3b99aSMauro Carvalho Chehab        desc->status &= ~pending;
2643bd3b99aSMauro Carvalho Chehab        handle_irq_event(desc->action);
2653bd3b99aSMauro Carvalho Chehab    } while (status & pending);
2663bd3b99aSMauro Carvalho Chehab    desc->status &= ~running;
2673bd3b99aSMauro Carvalho Chehab
2683bd3b99aSMauro Carvalho Chehab
2693bd3b99aSMauro Carvalho ChehabDefault simple IRQ flow handler
2703bd3b99aSMauro Carvalho Chehab^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2713bd3b99aSMauro Carvalho Chehab
2723bd3b99aSMauro Carvalho Chehabhandle_simple_irq provides a generic implementation for simple
2733bd3b99aSMauro Carvalho Chehabinterrupts.
2743bd3b99aSMauro Carvalho Chehab
2753bd3b99aSMauro Carvalho Chehab.. note::
2763bd3b99aSMauro Carvalho Chehab
2773bd3b99aSMauro Carvalho Chehab   The simple flow handler does not call any handler/chip primitives.
2783bd3b99aSMauro Carvalho Chehab
2793bd3b99aSMauro Carvalho ChehabThe following control flow is implemented (simplified excerpt)::
2803bd3b99aSMauro Carvalho Chehab
2813bd3b99aSMauro Carvalho Chehab    handle_irq_event(desc->action);
2823bd3b99aSMauro Carvalho Chehab
2833bd3b99aSMauro Carvalho Chehab
2843bd3b99aSMauro Carvalho ChehabDefault per CPU flow handler
2853bd3b99aSMauro Carvalho Chehab^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2863bd3b99aSMauro Carvalho Chehab
2873bd3b99aSMauro Carvalho Chehabhandle_percpu_irq provides a generic implementation for per CPU
2883bd3b99aSMauro Carvalho Chehabinterrupts.
2893bd3b99aSMauro Carvalho Chehab
2903bd3b99aSMauro Carvalho ChehabPer CPU interrupts are only available on SMP and the handler provides a
2913bd3b99aSMauro Carvalho Chehabsimplified version without locking.
2923bd3b99aSMauro Carvalho Chehab
2933bd3b99aSMauro Carvalho ChehabThe following control flow is implemented (simplified excerpt)::
2943bd3b99aSMauro Carvalho Chehab
2953bd3b99aSMauro Carvalho Chehab    if (desc->irq_data.chip->irq_ack)
296*76d40faeSMauro Carvalho Chehab        :c:func:`desc->irq_data.chip->irq_ack`;
2973bd3b99aSMauro Carvalho Chehab    handle_irq_event(desc->action);
2983bd3b99aSMauro Carvalho Chehab    if (desc->irq_data.chip->irq_eoi)
299*76d40faeSMauro Carvalho Chehab            :c:func:`desc->irq_data.chip->irq_eoi`;
3003bd3b99aSMauro Carvalho Chehab
3013bd3b99aSMauro Carvalho Chehab
3023bd3b99aSMauro Carvalho ChehabEOI Edge IRQ flow handler
3033bd3b99aSMauro Carvalho Chehab^^^^^^^^^^^^^^^^^^^^^^^^^
3043bd3b99aSMauro Carvalho Chehab
3053bd3b99aSMauro Carvalho Chehabhandle_edge_eoi_irq provides an abnomination of the edge handler
3063bd3b99aSMauro Carvalho Chehabwhich is solely used to tame a badly wreckaged irq controller on
3073bd3b99aSMauro Carvalho Chehabpowerpc/cell.
3083bd3b99aSMauro Carvalho Chehab
3093bd3b99aSMauro Carvalho ChehabBad IRQ flow handler
3103bd3b99aSMauro Carvalho Chehab^^^^^^^^^^^^^^^^^^^^
3113bd3b99aSMauro Carvalho Chehab
3123bd3b99aSMauro Carvalho Chehabhandle_bad_irq is used for spurious interrupts which have no real
3133bd3b99aSMauro Carvalho Chehabhandler assigned..
3143bd3b99aSMauro Carvalho Chehab
3153bd3b99aSMauro Carvalho ChehabQuirks and optimizations
3163bd3b99aSMauro Carvalho Chehab~~~~~~~~~~~~~~~~~~~~~~~~
3173bd3b99aSMauro Carvalho Chehab
3183bd3b99aSMauro Carvalho ChehabThe generic functions are intended for 'clean' architectures and chips,
3193bd3b99aSMauro Carvalho Chehabwhich have no platform-specific IRQ handling quirks. If an architecture
3203bd3b99aSMauro Carvalho Chehabneeds to implement quirks on the 'flow' level then it can do so by
3213bd3b99aSMauro Carvalho Chehaboverriding the high-level irq-flow handler.
3223bd3b99aSMauro Carvalho Chehab
3233bd3b99aSMauro Carvalho ChehabDelayed interrupt disable
3243bd3b99aSMauro Carvalho Chehab~~~~~~~~~~~~~~~~~~~~~~~~~
3253bd3b99aSMauro Carvalho Chehab
3263bd3b99aSMauro Carvalho ChehabThis per interrupt selectable feature, which was introduced by Russell
3273bd3b99aSMauro Carvalho ChehabKing in the ARM interrupt implementation, does not mask an interrupt at
328*76d40faeSMauro Carvalho Chehabthe hardware level when :c:func:`disable_irq` is called. The interrupt is kept
3293bd3b99aSMauro Carvalho Chehabenabled and is masked in the flow handler when an interrupt event
3303bd3b99aSMauro Carvalho Chehabhappens. This prevents losing edge interrupts on hardware which does not
3313bd3b99aSMauro Carvalho Chehabstore an edge interrupt event while the interrupt is disabled at the
3323bd3b99aSMauro Carvalho Chehabhardware level. When an interrupt arrives while the IRQ_DISABLED flag
3333bd3b99aSMauro Carvalho Chehabis set, then the interrupt is masked at the hardware level and the
3343bd3b99aSMauro Carvalho ChehabIRQ_PENDING bit is set. When the interrupt is re-enabled by
335*76d40faeSMauro Carvalho Chehab:c:func:`enable_irq` the pending bit is checked and if it is set, the interrupt
3363bd3b99aSMauro Carvalho Chehabis resent either via hardware or by a software resend mechanism. (It's
3373bd3b99aSMauro Carvalho Chehabnecessary to enable CONFIG_HARDIRQS_SW_RESEND when you want to use
3383bd3b99aSMauro Carvalho Chehabthe delayed interrupt disable feature and your hardware is not capable
3393bd3b99aSMauro Carvalho Chehabof retriggering an interrupt.) The delayed interrupt disable is not
3403bd3b99aSMauro Carvalho Chehabconfigurable.
3413bd3b99aSMauro Carvalho Chehab
3423bd3b99aSMauro Carvalho ChehabChip-level hardware encapsulation
3433bd3b99aSMauro Carvalho Chehab---------------------------------
3443bd3b99aSMauro Carvalho Chehab
345*76d40faeSMauro Carvalho ChehabThe chip-level hardware descriptor structure :c:type:`irq_chip` contains all
346*76d40faeSMauro Carvalho Chehabthe direct chip relevant functions, which can be utilized by the irq flow
3473bd3b99aSMauro Carvalho Chehabimplementations.
3483bd3b99aSMauro Carvalho Chehab
349*76d40faeSMauro Carvalho Chehab-  ``irq_ack``
3503bd3b99aSMauro Carvalho Chehab
351*76d40faeSMauro Carvalho Chehab-  ``irq_mask_ack`` - Optional, recommended for performance
3523bd3b99aSMauro Carvalho Chehab
353*76d40faeSMauro Carvalho Chehab-  ``irq_mask``
3543bd3b99aSMauro Carvalho Chehab
355*76d40faeSMauro Carvalho Chehab-  ``irq_unmask``
3563bd3b99aSMauro Carvalho Chehab
357*76d40faeSMauro Carvalho Chehab-  ``irq_eoi`` - Optional, required for EOI flow handlers
3583bd3b99aSMauro Carvalho Chehab
359*76d40faeSMauro Carvalho Chehab-  ``irq_retrigger`` - Optional
3603bd3b99aSMauro Carvalho Chehab
361*76d40faeSMauro Carvalho Chehab-  ``irq_set_type`` - Optional
3623bd3b99aSMauro Carvalho Chehab
363*76d40faeSMauro Carvalho Chehab-  ``irq_set_wake`` - Optional
3643bd3b99aSMauro Carvalho Chehab
3653bd3b99aSMauro Carvalho ChehabThese primitives are strictly intended to mean what they say: ack means
3663bd3b99aSMauro Carvalho ChehabACK, masking means masking of an IRQ line, etc. It is up to the flow
3673bd3b99aSMauro Carvalho Chehabhandler(s) to use these basic units of low-level functionality.
3683bd3b99aSMauro Carvalho Chehab
3693bd3b99aSMauro Carvalho Chehab__do_IRQ entry point
3703bd3b99aSMauro Carvalho Chehab====================
3713bd3b99aSMauro Carvalho Chehab
372*76d40faeSMauro Carvalho ChehabThe original implementation :c:func:`__do_IRQ` was an alternative entry point
3733bd3b99aSMauro Carvalho Chehabfor all types of interrupts. It no longer exists.
3743bd3b99aSMauro Carvalho Chehab
3753bd3b99aSMauro Carvalho ChehabThis handler turned out to be not suitable for all interrupt hardware
3763bd3b99aSMauro Carvalho Chehaband was therefore reimplemented with split functionality for
3773bd3b99aSMauro Carvalho Chehabedge/level/simple/percpu interrupts. This is not only a functional
3783bd3b99aSMauro Carvalho Chehaboptimization. It also shortens code paths for interrupts.
3793bd3b99aSMauro Carvalho Chehab
3803bd3b99aSMauro Carvalho ChehabLocking on SMP
3813bd3b99aSMauro Carvalho Chehab==============
3823bd3b99aSMauro Carvalho Chehab
3833bd3b99aSMauro Carvalho ChehabThe locking of chip registers is up to the architecture that defines the
3843bd3b99aSMauro Carvalho Chehabchip primitives. The per-irq structure is protected via desc->lock, by
3853bd3b99aSMauro Carvalho Chehabthe generic layer.
3863bd3b99aSMauro Carvalho Chehab
3873bd3b99aSMauro Carvalho ChehabGeneric interrupt chip
3883bd3b99aSMauro Carvalho Chehab======================
3893bd3b99aSMauro Carvalho Chehab
3903bd3b99aSMauro Carvalho ChehabTo avoid copies of identical implementations of IRQ chips the core
3913bd3b99aSMauro Carvalho Chehabprovides a configurable generic interrupt chip implementation.
3923bd3b99aSMauro Carvalho ChehabDevelopers should check carefully whether the generic chip fits their
3933bd3b99aSMauro Carvalho Chehabneeds before implementing the same functionality slightly differently
3943bd3b99aSMauro Carvalho Chehabthemselves.
3953bd3b99aSMauro Carvalho Chehab
3963bd3b99aSMauro Carvalho Chehab.. kernel-doc:: kernel/irq/generic-chip.c
3973bd3b99aSMauro Carvalho Chehab   :export:
3983bd3b99aSMauro Carvalho Chehab
3993bd3b99aSMauro Carvalho ChehabStructures
4003bd3b99aSMauro Carvalho Chehab==========
4013bd3b99aSMauro Carvalho Chehab
4023bd3b99aSMauro Carvalho ChehabThis chapter contains the autogenerated documentation of the structures
4033bd3b99aSMauro Carvalho Chehabwhich are used in the generic IRQ layer.
4043bd3b99aSMauro Carvalho Chehab
4053bd3b99aSMauro Carvalho Chehab.. kernel-doc:: include/linux/irq.h
4063bd3b99aSMauro Carvalho Chehab   :internal:
4073bd3b99aSMauro Carvalho Chehab
4083bd3b99aSMauro Carvalho Chehab.. kernel-doc:: include/linux/interrupt.h
4093bd3b99aSMauro Carvalho Chehab   :internal:
4103bd3b99aSMauro Carvalho Chehab
4113bd3b99aSMauro Carvalho ChehabPublic Functions Provided
4123bd3b99aSMauro Carvalho Chehab=========================
4133bd3b99aSMauro Carvalho Chehab
4143bd3b99aSMauro Carvalho ChehabThis chapter contains the autogenerated documentation of the kernel API
4153bd3b99aSMauro Carvalho Chehabfunctions which are exported.
4163bd3b99aSMauro Carvalho Chehab
4173bd3b99aSMauro Carvalho Chehab.. kernel-doc:: kernel/irq/manage.c
4183bd3b99aSMauro Carvalho Chehab
4193bd3b99aSMauro Carvalho Chehab.. kernel-doc:: kernel/irq/chip.c
4203bd3b99aSMauro Carvalho Chehab
4213bd3b99aSMauro Carvalho ChehabInternal Functions Provided
4223bd3b99aSMauro Carvalho Chehab===========================
4233bd3b99aSMauro Carvalho Chehab
4243bd3b99aSMauro Carvalho ChehabThis chapter contains the autogenerated documentation of the internal
4253bd3b99aSMauro Carvalho Chehabfunctions.
4263bd3b99aSMauro Carvalho Chehab
4273bd3b99aSMauro Carvalho Chehab.. kernel-doc:: kernel/irq/irqdesc.c
4283bd3b99aSMauro Carvalho Chehab
4293bd3b99aSMauro Carvalho Chehab.. kernel-doc:: kernel/irq/handle.c
4303bd3b99aSMauro Carvalho Chehab
4313bd3b99aSMauro Carvalho Chehab.. kernel-doc:: kernel/irq/chip.c
4323bd3b99aSMauro Carvalho Chehab
4333bd3b99aSMauro Carvalho ChehabCredits
4343bd3b99aSMauro Carvalho Chehab=======
4353bd3b99aSMauro Carvalho Chehab
4363bd3b99aSMauro Carvalho ChehabThe following people have contributed to this document:
4373bd3b99aSMauro Carvalho Chehab
4383bd3b99aSMauro Carvalho Chehab1. Thomas Gleixner tglx@linutronix.de
4393bd3b99aSMauro Carvalho Chehab
4403bd3b99aSMauro Carvalho Chehab2. Ingo Molnar mingo@elte.hu
441