Re: [PATCH 3/9] genericirq.tmpl: convert it to ReST

Jonathan Corbet
2017-03-31T14:57:15Z

On Thu, 30 Mar 2017 17:11:30 -0300
Mauro Carvalho Chehab <mchehab@s-opensource.com> wrote:

[Reordering things a bit]

> +==========================
> +Linux generic IRQ handling
> +==========================
> +
> +:Copyright: |copy| 2005-2010: Thomas Gleixner
> +:Copyright: |copy| 2005-2006: Ingo Molnar

It seems maybe they should have been CC'd on this one? Adding them now
(and leaving the full patch for their amusement).

> Brainless conversion of genericirq.tmpl book to ReST, via
> Documentation/sphinx/tmplcvt

In general this seems good, but I have to wonder how current this material
is at this point? The last substantive change was in 2013 (3.11), and I've
seen a certain amount of IRQ work going by since then. I'm not opposed to
this move at all, but perhaps if it's outdated we should add a note to that
effect?

Thanks,

jon

> Copyright information inserted manually.
>
> Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
> ---
> Documentation/DocBook/Makefile | 2 +-
> Documentation/DocBook/genericirq.tmpl | 520 ----------------------------------
> Documentation/core-api/genericirq.rst | 445 +++++++++++++++++++++++++++++
> Documentation/core-api/index.rst | 1 +
> 4 files changed, 447 insertions(+), 521 deletions(-)
> delete mode 100644 Documentation/DocBook/genericirq.tmpl
> create mode 100644 Documentation/core-api/genericirq.rst
>
> diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile
> index 7d94db2b53cd..e0c13655f770 100644
> --- a/Documentation/DocBook/Makefile
> +++ b/Documentation/DocBook/Makefile
> @@ -11,7 +11,7 @@ DOCBOOKS := z8530book.xml \
> networking.xml \
> kernel-api.xml filesystems.xml lsm.xml kgdb.xml \
> libata.xml mtdnand.xml librs.xml rapidio.xml \
> - genericirq.xml s390-drivers.xml scsi.xml \
> + s390-drivers.xml scsi.xml \
> sh.xml w1.xml
>
> ifeq ($(DOCBOOKS),)
> diff --git a/Documentation/DocBook/genericirq.tmpl b/Documentation/DocBook/genericirq.tmpl
> deleted file mode 100644
> index 59fb5c077541..000000000000
> --- a/Documentation/DocBook/genericirq.tmpl
> +++ /dev/null
> @@ -1,520 +0,0 @@
> -<?xml version="1.0" encoding="UTF-8"?>
> -<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
> - "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
> -
> -<book id="Generic-IRQ-Guide">
> - <bookinfo>
> - Linux generic IRQ handling
> -
> - <authorgroup>
> - <author>
> - <firstname>Thomas</firstname>
> - <surname>Gleixner</surname>
> - <affiliation>
> -
> - <email>tglx@linutronix.de</email>
> -
> - </affiliation>
> - </author>
> - <author>
> - <firstname>Ingo</firstname>
> - <surname>Molnar</surname>
> - <affiliation>
> -
> - <email>mingo@elte.hu</email>
> -
> - </affiliation>
> - </author>
> - </authorgroup>
> -
> - <copyright>
> - <year>2005-2010</year>
> - <holder>Thomas Gleixner</holder>
> - </copyright>
> - <copyright>
> - <year>2005-2006</year>
> - <holder>Ingo Molnar</holder>
> - </copyright>
> -
> - <legalnotice>
> -
> - This documentation is free software; you can redistribute
> - it and/or modify it under the terms of the GNU General Public
> - License version 2 as published by the Free Software Foundation.
> -
> -
> -
> - This program is distributed in the hope that it will be
> - useful, but WITHOUT ANY WARRANTY; without even the implied
> - warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
> - See the GNU General Public License for more details.
> -
> -
> -
> - You should have received a copy of the GNU General Public
> - License along with this program; if not, write to the Free
> - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> - MA 02111-1307 USA
> -
> -
> -
> - For more details see the file COPYING in the source
> - distribution of Linux.
> -
> - </legalnotice>
> - </bookinfo>
> -
> -<toc></toc>
> -
> - <chapter id="intro">
> - Introduction
> -
> - The generic interrupt handling layer is designed to provide a
> - complete abstraction of interrupt handling for device drivers.
> - It is able to handle all the different types of interrupt controller
> - hardware. Device drivers use generic API functions to request, enable,
> - disable and free interrupts. The drivers do not have to know anything
> - about interrupt hardware details, so they can be used on different
> - platforms without code changes.
> -
> -
> - This documentation is provided to developers who want to implement
> - an interrupt subsystem based for their architecture, with the help
> - of the generic IRQ handling layer.
> -
> - </chapter>
> -
> - <chapter id="rationale">
> - Rationale
> -
> - The original implementation of interrupt handling in Linux uses
> - the __do_IRQ() super-handler, which is able to deal with every
> - type of interrupt logic.
> -
> -
> - Originally, Russell King identified different types of handlers to
> - build a quite universal set for the ARM interrupt handler
> - implementation in Linux 2.5/2.6. He distinguished between:
> -
> - Level type
> - Edge type
> - Simple type
> -
> - During the implementation we identified another type:
> -
> - Fast EOI type
> -
> - In the SMP world of the __do_IRQ() super-handler another type
> - was identified:
> -
> - Per CPU type
> -
> -
> -
> - This split implementation of high-level IRQ handlers allows us to
> - optimize the flow of the interrupt handling for each specific
> - interrupt type. This reduces complexity in that particular code path
> - and allows the optimized handling of a given type.
> -
> -
> - The original general IRQ implementation used hw_interrupt_type
> - structures and their ->ack(), ->end() [etc.] callbacks to
> - differentiate the flow control in the super-handler. This leads to
> - a mix of flow logic and low-level hardware logic, and it also leads
> - to unnecessary code duplication: for example in i386, there is an
> - ioapic_level_irq and an ioapic_edge_irq IRQ-type which share many
> - of the low-level details but have different flow handling.
> -
> -
> - A more natural abstraction is the clean separation of the
> - 'irq flow' and the 'chip details'.
> -
> -
> - Analysing a couple of architecture's IRQ subsystem implementations
> - reveals that most of them can use a generic set of 'irq flow'
> - methods and only need to add the chip-level specific code.
> - The separation is also valuable for (sub)architectures
> - which need specific quirks in the IRQ flow itself but not in the
> - chip details - and thus provides a more transparent IRQ subsystem
> - design.
> -
> -
> - Each interrupt descriptor is assigned its own high-level flow
> - handler, which is normally one of the generic
> - implementations. (This high-level flow handler implementation also
> - makes it simple to provide demultiplexing handlers which can be
> - found in embedded platforms on various architectures.)
> -
> -
> - The separation makes the generic interrupt handling layer more
> - flexible and extensible. For example, an (sub)architecture can
> - use a generic IRQ-flow implementation for 'level type' interrupts
> - and add a (sub)architecture specific 'edge type' implementation.
> -
> -
> - To make the transition to the new model easier and prevent the
> - breakage of existing implementations, the __do_IRQ() super-handler
> - is still available. This leads to a kind of duality for the time
> - being. Over time the new model should be used in more and more
> - architectures, as it enables smaller and cleaner IRQ subsystems.
> - It's deprecated for three years now and about to be removed.
> -
> - </chapter>
> - <chapter id="bugs">
> - Known Bugs And Assumptions
> -
> - None (knock on wood).
> -
> - </chapter>
> -
> - <chapter id="Abstraction">
> - Abstraction layers
> -
> - There are three main levels of abstraction in the interrupt code:
> -
> - High-level driver API
> - High-level IRQ flow handlers
> - Chip-level hardware encapsulation
> -
> -
> - <sect1 id="Interrupt_control_flow">
> - Interrupt control flow
> -
> - Each interrupt is described by an interrupt descriptor structure
> - irq_desc. The interrupt is referenced by an 'unsigned int' numeric
> - value which selects the corresponding interrupt description structure
> - in the descriptor structures array.
> - The descriptor structure contains status information and pointers
> - to the interrupt flow method and the interrupt chip structure
> - which are assigned to this interrupt.
> -
> -
> - Whenever an interrupt triggers, the low-level architecture code calls
> - into the generic interrupt code by calling desc->handle_irq().
> - This high-level IRQ handling function only uses desc->irq_data.chip
> - primitives referenced by the assigned chip descriptor structure.
> -
> - </sect1>
> - <sect1 id="Highlevel_Driver_API">
> - High-level Driver API
> -
> - The high-level Driver API consists of following functions:
> -
> - request_irq()
> - free_irq()
> - disable_irq()
> - enable_irq()
> - disable_irq_nosync() (SMP only)
> - synchronize_irq() (SMP only)
> - irq_set_irq_type()
> - irq_set_irq_wake()
> - irq_set_handler_data()
> - irq_set_chip()
> - irq_set_chip_data()
> -
> - See the autogenerated function documentation for details.
> -
> - </sect1>
> - <sect1 id="Highlevel_IRQ_flow_handlers">
> - High-level IRQ flow handlers
> -
> - The generic layer provides a set of pre-defined irq-flow methods:
> -
> - handle_level_irq
> - handle_edge_irq
> - handle_fasteoi_irq
> - handle_simple_irq
> - handle_percpu_irq
> - handle_edge_eoi_irq
> - handle_bad_irq
> -
> - The interrupt flow handlers (either pre-defined or architecture
> - specific) are assigned to specific interrupts by the architecture
> - either during bootup or during device initialization.
> -
> - <sect2 id="Default_flow_implementations">
> - Default flow implementations
> - <sect3 id="Helper_functions">
> - Helper functions
> -
> - The helper functions call the chip primitives and
> - are used by the default flow implementations.
> - The following helper functions are implemented (simplified excerpt):
> - <programlisting>
> -default_enable(struct irq_data *data)
> -{
> - desc->irq_data.chip->irq_unmask(data);
> -}
> -
> -default_disable(struct irq_data *data)
> -{
> - if (!delay_disable(data))
> - desc->irq_data.chip->irq_mask(data);
> -}
> -
> -default_ack(struct irq_data *data)
> -{
> - chip->irq_ack(data);
> -}
> -
> -default_mask_ack(struct irq_data *data)
> -{
> - if (chip->irq_mask_ack) {
> - chip->irq_mask_ack(data);
> - } else {
> - chip->irq_mask(data);
> - chip->irq_ack(data);
> - }
> -}
> -
> -noop(struct irq_data *data))
> -{
> -}
> -
> - </programlisting>
> -
> - </sect3>
> - </sect2>
> - <sect2 id="Default_flow_handler_implementations">
> - Default flow handler implementations
> - <sect3 id="Default_Level_IRQ_flow_handler">
> - Default Level IRQ flow handler
> -
> - handle_level_irq provides a generic implementation
> - for level-triggered interrupts.
> -
> -
> - The following control flow is implemented (simplified excerpt):
> - <programlisting>
> -desc->irq_data.chip->irq_mask_ack();
> -handle_irq_event(desc->action);
> -desc->irq_data.chip->irq_unmask();
> - </programlisting>
> -
> - </sect3>
> - <sect3 id="Default_FASTEOI_IRQ_flow_handler">
> - Default Fast EOI IRQ flow handler
> -
> - handle_fasteoi_irq provides a generic implementation
> - for interrupts, which only need an EOI at the end of
> - the handler.
> -
> -
> - The following control flow is implemented (simplified excerpt):
> - <programlisting>
> -handle_irq_event(desc->action);
> -desc->irq_data.chip->irq_eoi();
> - </programlisting>
> -
> - </sect3>
> - <sect3 id="Default_Edge_IRQ_flow_handler">
> - Default Edge IRQ flow handler
> -
> - handle_edge_irq provides a generic implementation
> - for edge-triggered interrupts.
> -
> -
> - The following control flow is implemented (simplified excerpt):
> - <programlisting>
> -if (desc->status &amp; running) {
> - desc->irq_data.chip->irq_mask_ack();
> - desc->status |= pending | masked;
> - return;
> -}
> -desc->irq_data.chip->irq_ack();
> -desc->status |= running;
> -do {
> - if (desc->status &amp; masked)
> - desc->irq_data.chip->irq_unmask();
> - desc->status &amp;= ~pending;
> - handle_irq_event(desc->action);
> -} while (status &amp; pending);
> -desc->status &amp;= ~running;
> - </programlisting>
> -
> - </sect3>
> - <sect3 id="Default_simple_IRQ_flow_handler">
> - Default simple IRQ flow handler
> -
> - handle_simple_irq provides a generic implementation
> - for simple interrupts.
> -
> -
> - Note: The simple flow handler does not call any
> - handler/chip primitives.
> -
> -
> - The following control flow is implemented (simplified excerpt):
> - <programlisting>
> -handle_irq_event(desc->action);
> - </programlisting>
> -
> - </sect3>
> - <sect3 id="Default_per_CPU_flow_handler">
> - Default per CPU flow handler
> -
> - handle_percpu_irq provides a generic implementation
> - for per CPU interrupts.
> -
> -
> - Per CPU interrupts are only available on SMP and
> - the handler provides a simplified version without
> - locking.
> -
> -
> - The following control flow is implemented (simplified excerpt):
> - <programlisting>
> -if (desc->irq_data.chip->irq_ack)
> - desc->irq_data.chip->irq_ack();
> -handle_irq_event(desc->action);
> -if (desc->irq_data.chip->irq_eoi)
> - desc->irq_data.chip->irq_eoi();
> - </programlisting>
> -
> - </sect3>
> - <sect3 id="EOI_Edge_IRQ_flow_handler">
> - EOI Edge IRQ flow handler
> -
> - handle_edge_eoi_irq provides an abnomination of the edge
> - handler which is solely used to tame a badly wreckaged
> - irq controller on powerpc/cell.
> -
> - </sect3>
> - <sect3 id="BAD_IRQ_flow_handler">
> - Bad IRQ flow handler
> -
> - handle_bad_irq is used for spurious interrupts which
> - have no real handler assigned..
> -
> - </sect3>
> - </sect2>
> - <sect2 id="Quirks_and_optimizations">
> - Quirks and optimizations
> -
> - The generic functions are intended for 'clean' architectures and chips,
> - which have no platform-specific IRQ handling quirks. If an architecture
> - needs to implement quirks on the 'flow' level then it can do so by
> - overriding the high-level irq-flow handler.
> -
> - </sect2>
> - <sect2 id="Delayed_interrupt_disable">
> - Delayed interrupt disable
> -
> - This per interrupt selectable feature, which was introduced by Russell
> - King in the ARM interrupt implementation, does not mask an interrupt
> - at the hardware level when disable_irq() is called. The interrupt is
> - kept enabled and is masked in the flow handler when an interrupt event
> - happens. This prevents losing edge interrupts on hardware which does
> - not store an edge interrupt event while the interrupt is disabled at
> - the hardware level. When an interrupt arrives while the IRQ_DISABLED
> - flag is set, then the interrupt is masked at the hardware level and
> - the IRQ_PENDING bit is set. When the interrupt is re-enabled by
> - enable_irq() the pending bit is checked and if it is set, the
> - interrupt is resent either via hardware or by a software resend
> - mechanism. (It's necessary to enable CONFIG_HARDIRQS_SW_RESEND when
> - you want to use the delayed interrupt disable feature and your
> - hardware is not capable of retriggering an interrupt.)
> - The delayed interrupt disable is not configurable.
> -
> - </sect2>
> - </sect1>
> - <sect1 id="Chiplevel_hardware_encapsulation">
> - Chip-level hardware encapsulation
> -
> - The chip-level hardware descriptor structure irq_chip
> - contains all the direct chip relevant functions, which
> - can be utilized by the irq flow implementations.
> -
> - irq_ack()
> - irq_mask_ack() - Optional, recommended for performance
> - irq_mask()
> - irq_unmask()
> - irq_eoi() - Optional, required for EOI flow handlers
> - irq_retrigger() - Optional
> - irq_set_type() - Optional
> - irq_set_wake() - Optional
> -
> - These primitives are strictly intended to mean what they say: ack means
> - ACK, masking means masking of an IRQ line, etc. It is up to the flow
> - handler(s) to use these basic units of low-level functionality.
> -
> - </sect1>
> - </chapter>
> -
> - <chapter id="doirq">
> - __do_IRQ entry point
> -
> - The original implementation __do_IRQ() was an alternative entry
> - point for all types of interrupts. It no longer exists.
> -
> -
> - This handler turned out to be not suitable for all
> - interrupt hardware and was therefore reimplemented with split
> - functionality for edge/level/simple/percpu interrupts. This is not
> - only a functional optimization. It also shortens code paths for
> - interrupts.
> -
> - </chapter>
> -
> - <chapter id="locking">
> - Locking on SMP
> -
> - The locking of chip registers is up to the architecture that
> - defines the chip primitives. The per-irq structure is
> - protected via desc->lock, by the generic layer.
> -
> - </chapter>
> -
> - <chapter id="genericchip">
> - Generic interrupt chip
> -
> - To avoid copies of identical implementations of IRQ chips the
> - core provides a configurable generic interrupt chip
> - implementation. Developers should check carefully whether the
> - generic chip fits their needs before implementing the same
> - functionality slightly differently themselves.
> -
> -!Ekernel/irq/generic-chip.c
> - </chapter>
> -
> - <chapter id="structs">
> - Structures
> -
> - This chapter contains the autogenerated documentation of the structures which are
> - used in the generic IRQ layer.
> -
> -!Iinclude/linux/irq.h
> -!Iinclude/linux/interrupt.h
> - </chapter>
> -
> - <chapter id="pubfunctions">
> - Public Functions Provided
> -
> - This chapter contains the autogenerated documentation of the kernel API functions
> - which are exported.
> -
> -!Ekernel/irq/manage.c
> -!Ekernel/irq/chip.c
> - </chapter>
> -
> - <chapter id="intfunctions">
> - Internal Functions Provided
> -
> - This chapter contains the autogenerated documentation of the internal functions.
> -
> -!Ikernel/irq/irqdesc.c
> -!Ikernel/irq/handle.c
> -!Ikernel/irq/chip.c
> - </chapter>
> -
> - <chapter id="credits">
> - Credits
> -
> - The following people have contributed to this document:
> -
> - Thomas Gleixner<email>tglx@linutronix.de</email>
> - Ingo Molnar<email>mingo@elte.hu</email>
> -
> -
> - </chapter>
> -</book>
> diff --git a/Documentation/core-api/genericirq.rst b/Documentation/core-api/genericirq.rst
> new file mode 100644
> index 000000000000..65d023b26864
> --- /dev/null
> +++ b/Documentation/core-api/genericirq.rst
> @@ -0,0 +1,445 @@
> +.. include:: <isonum.txt>
> +
> +==========================
> +Linux generic IRQ handling
> +==========================
> +
> +:Copyright: |copy| 2005-2010: Thomas Gleixner
> +:Copyright: |copy| 2005-2006: Ingo Molnar
> +
> +Introduction
> +============
> +
> +The generic interrupt handling layer is designed to provide a complete
> +abstraction of interrupt handling for device drivers. It is able to
> +handle all the different types of interrupt controller hardware. Device
> +drivers use generic API functions to request, enable, disable and free
> +interrupts. The drivers do not have to know anything about interrupt
> +hardware details, so they can be used on different platforms without
> +code changes.
> +
> +This documentation is provided to developers who want to implement an
> +interrupt subsystem based for their architecture, with the help of the
> +generic IRQ handling layer.
> +
> +Rationale
> +=========
> +
> +The original implementation of interrupt handling in Linux uses the
> +__do_IRQ() super-handler, which is able to deal with every type of
> +interrupt logic.
> +
> +Originally, Russell King identified different types of handlers to build
> +a quite universal set for the ARM interrupt handler implementation in
> +Linux 2.5/2.6. He distinguished between:
> +
> +- Level type
> +
> +- Edge type
> +
> +- Simple type
> +
> +During the implementation we identified another type:
> +
> +- Fast EOI type
> +
> +In the SMP world of the __do_IRQ() super-handler another type was
> +identified:
> +
> +- Per CPU type
> +
> +This split implementation of high-level IRQ handlers allows us to
> +optimize the flow of the interrupt handling for each specific interrupt
> +type. This reduces complexity in that particular code path and allows
> +the optimized handling of a given type.
> +
> +The original general IRQ implementation used hw_interrupt_type
> +structures and their ->ack(), ->end() [etc.] callbacks to differentiate
> +the flow control in the super-handler. This leads to a mix of flow logic
> +and low-level hardware logic, and it also leads to unnecessary code
> +duplication: for example in i386, there is an ioapic_level_irq and an
> +ioapic_edge_irq IRQ-type which share many of the low-level details but
> +have different flow handling.
> +
> +A more natural abstraction is the clean separation of the 'irq flow' and
> +the 'chip details'.
> +
> +Analysing a couple of architecture's IRQ subsystem implementations
> +reveals that most of them can use a generic set of 'irq flow' methods
> +and only need to add the chip-level specific code. The separation is
> +also valuable for (sub)architectures which need specific quirks in the
> +IRQ flow itself but not in the chip details - and thus provides a more
> +transparent IRQ subsystem design.
> +
> +Each interrupt descriptor is assigned its own high-level flow handler,
> +which is normally one of the generic implementations. (This high-level
> +flow handler implementation also makes it simple to provide
> +demultiplexing handlers which can be found in embedded platforms on
> +various architectures.)
> +
> +The separation makes the generic interrupt handling layer more flexible
> +and extensible. For example, an (sub)architecture can use a generic
> +IRQ-flow implementation for 'level type' interrupts and add a
> +(sub)architecture specific 'edge type' implementation.
> +
> +To make the transition to the new model easier and prevent the breakage
> +of existing implementations, the __do_IRQ() super-handler is still
> +available. This leads to a kind of duality for the time being. Over time
> +the new model should be used in more and more architectures, as it
> +enables smaller and cleaner IRQ subsystems. It's deprecated for three
> +years now and about to be removed.
> +
> +Known Bugs And Assumptions
> +==========================
> +
> +None (knock on wood).
> +
> +Abstraction layers
> +==================
> +
> +There are three main levels of abstraction in the interrupt code:
> +
> +1. High-level driver API
> +
> +2. High-level IRQ flow handlers
> +
> +3. Chip-level hardware encapsulation
> +
> +Interrupt control flow
> +----------------------
> +
> +Each interrupt is described by an interrupt descriptor structure
> +irq_desc. The interrupt is referenced by an 'unsigned int' numeric
> +value which selects the corresponding interrupt description structure in
> +the descriptor structures array. The descriptor structure contains
> +status information and pointers to the interrupt flow method and the
> +interrupt chip structure which are assigned to this interrupt.
> +
> +Whenever an interrupt triggers, the low-level architecture code calls
> +into the generic interrupt code by calling desc->handle_irq(). This
> +high-level IRQ handling function only uses desc->irq_data.chip
> +primitives referenced by the assigned chip descriptor structure.
> +
> +High-level Driver API
> +---------------------
> +
> +The high-level Driver API consists of following functions:
> +
> +- request_irq()
> +
> +- free_irq()
> +
> +- disable_irq()
> +
> +- enable_irq()
> +
> +- disable_irq_nosync() (SMP only)
> +
> +- synchronize_irq() (SMP only)
> +
> +- irq_set_irq_type()
> +
> +- irq_set_irq_wake()
> +
> +- irq_set_handler_data()
> +
> +- irq_set_chip()
> +
> +- irq_set_chip_data()
> +
> +See the autogenerated function documentation for details.
> +
> +High-level IRQ flow handlers
> +----------------------------
> +
> +The generic layer provides a set of pre-defined irq-flow methods:
> +
> +- handle_level_irq
> +
> +- handle_edge_irq
> +
> +- handle_fasteoi_irq
> +
> +- handle_simple_irq
> +
> +- handle_percpu_irq
> +
> +- handle_edge_eoi_irq
> +
> +- handle_bad_irq
> +
> +The interrupt flow handlers (either pre-defined or architecture
> +specific) are assigned to specific interrupts by the architecture either
> +during bootup or during device initialization.
> +
> +Default flow implementations
> +~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> +
> +Helper functions
> +^^^^^^^^^^^^^^^^
> +
> +The helper functions call the chip primitives and are used by the
> +default flow implementations. The following helper functions are
> +implemented (simplified excerpt)::
> +
> + default_enable(struct irq_data *data)
> + {
> + desc->irq_data.chip->irq_unmask(data);
> + }
> +
> + default_disable(struct irq_data *data)
> + {
> + if (!delay_disable(data))
> + desc->irq_data.chip->irq_mask(data);
> + }
> +
> + default_ack(struct irq_data *data)
> + {
> + chip->irq_ack(data);
> + }
> +
> + default_mask_ack(struct irq_data *data)
> + {
> + if (chip->irq_mask_ack) {
> + chip->irq_mask_ack(data);
> + } else {
> + chip->irq_mask(data);
> + chip->irq_ack(data);
> + }
> + }
> +
> + noop(struct irq_data *data))
> + {
> + }
> +
> +
> +
> +Default flow handler implementations
> +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> +
> +Default Level IRQ flow handler
> +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> +
> +handle_level_irq provides a generic implementation for level-triggered
> +interrupts.
> +
> +The following control flow is implemented (simplified excerpt)::
> +
> + desc->irq_data.chip->irq_mask_ack();
> + handle_irq_event(desc->action);
> + desc->irq_data.chip->irq_unmask();
> +
> +
> +Default Fast EOI IRQ flow handler
> +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> +
> +handle_fasteoi_irq provides a generic implementation for interrupts,
> +which only need an EOI at the end of the handler.
> +
> +The following control flow is implemented (simplified excerpt)::
> +
> + handle_irq_event(desc->action);
> + desc->irq_data.chip->irq_eoi();
> +
> +
> +Default Edge IRQ flow handler
> +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> +
> +handle_edge_irq provides a generic implementation for edge-triggered
> +interrupts.
> +
> +The following control flow is implemented (simplified excerpt)::
> +
> + if (desc->status & running) {
> + desc->irq_data.chip->irq_mask_ack();
> + desc->status |= pending | masked;
> + return;
> + }
> + desc->irq_data.chip->irq_ack();
> + desc->status |= running;
> + do {
> + if (desc->status & masked)
> + desc->irq_data.chip->irq_unmask();
> + desc->status &= ~pending;
> + handle_irq_event(desc->action);
> + } while (status & pending);
> + desc->status &= ~running;
> +
> +
> +Default simple IRQ flow handler
> +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> +
> +handle_simple_irq provides a generic implementation for simple
> +interrupts.
> +
> +.. note::
> +
> + The simple flow handler does not call any handler/chip primitives.
> +
> +The following control flow is implemented (simplified excerpt)::
> +
> + handle_irq_event(desc->action);
> +
> +
> +Default per CPU flow handler
> +^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> +
> +handle_percpu_irq provides a generic implementation for per CPU
> +interrupts.
> +
> +Per CPU interrupts are only available on SMP and the handler provides a
> +simplified version without locking.
> +
> +The following control flow is implemented (simplified excerpt)::
> +
> + if (desc->irq_data.chip->irq_ack)
> + desc->irq_data.chip->irq_ack();
> + handle_irq_event(desc->action);
> + if (desc->irq_data.chip->irq_eoi)
> + desc->irq_data.chip->irq_eoi();
> +
> +
> +EOI Edge IRQ flow handler
> +^^^^^^^^^^^^^^^^^^^^^^^^^
> +
> +handle_edge_eoi_irq provides an abnomination of the edge handler
> +which is solely used to tame a badly wreckaged irq controller on
> +powerpc/cell.
> +
> +Bad IRQ flow handler
> +^^^^^^^^^^^^^^^^^^^^
> +
> +handle_bad_irq is used for spurious interrupts which have no real
> +handler assigned..
> +
> +Quirks and optimizations
> +~~~~~~~~~~~~~~~~~~~~~~~~
> +
> +The generic functions are intended for 'clean' architectures and chips,
> +which have no platform-specific IRQ handling quirks. If an architecture
> +needs to implement quirks on the 'flow' level then it can do so by
> +overriding the high-level irq-flow handler.
> +
> +Delayed interrupt disable
> +~~~~~~~~~~~~~~~~~~~~~~~~~
> +
> +This per interrupt selectable feature, which was introduced by Russell
> +King in the ARM interrupt implementation, does not mask an interrupt at
> +the hardware level when disable_irq() is called. The interrupt is kept
> +enabled and is masked in the flow handler when an interrupt event
> +happens. This prevents losing edge interrupts on hardware which does not
> +store an edge interrupt event while the interrupt is disabled at the
> +hardware level. When an interrupt arrives while the IRQ_DISABLED flag
> +is set, then the interrupt is masked at the hardware level and the
> +IRQ_PENDING bit is set. When the interrupt is re-enabled by
> +enable_irq() the pending bit is checked and if it is set, the interrupt
> +is resent either via hardware or by a software resend mechanism. (It's
> +necessary to enable CONFIG_HARDIRQS_SW_RESEND when you want to use
> +the delayed interrupt disable feature and your hardware is not capable
> +of retriggering an interrupt.) The delayed interrupt disable is not
> +configurable.
> +
> +Chip-level hardware encapsulation
> +---------------------------------
> +
> +The chip-level hardware descriptor structure irq_chip contains all the
> +direct chip relevant functions, which can be utilized by the irq flow
> +implementations.
> +
> +- irq_ack()
> +
> +- irq_mask_ack() - Optional, recommended for performance
> +
> +- irq_mask()
> +
> +- irq_unmask()
> +
> +- irq_eoi() - Optional, required for EOI flow handlers
> +
> +- irq_retrigger() - Optional
> +
> +- irq_set_type() - Optional
> +
> +- irq_set_wake() - Optional
> +
> +These primitives are strictly intended to mean what they say: ack means
> +ACK, masking means masking of an IRQ line, etc. It is up to the flow
> +handler(s) to use these basic units of low-level functionality.
> +
> +__do_IRQ entry point
> +====================
> +
> +The original implementation __do_IRQ() was an alternative entry point
> +for all types of interrupts. It no longer exists.
> +
> +This handler turned out to be not suitable for all interrupt hardware
> +and was therefore reimplemented with split functionality for
> +edge/level/simple/percpu interrupts. This is not only a functional
> +optimization. It also shortens code paths for interrupts.
> +
> +Locking on SMP
> +==============
> +
> +The locking of chip registers is up to the architecture that defines the
> +chip primitives. The per-irq structure is protected via desc->lock, by
> +the generic layer.
> +
> +Generic interrupt chip
> +======================
> +
> +To avoid copies of identical implementations of IRQ chips the core
> +provides a configurable generic interrupt chip implementation.
> +Developers should check carefully whether the generic chip fits their
> +needs before implementing the same functionality slightly differently
> +themselves.
> +
> +.. kernel-doc:: kernel/irq/generic-chip.c
> + :export:
> +
> +Structures
> +==========
> +
> +This chapter contains the autogenerated documentation of the structures
> +which are used in the generic IRQ layer.
> +
> +.. kernel-doc:: include/linux/irq.h
> + :internal:
> +
> +.. kernel-doc:: include/linux/interrupt.h
> + :internal:
> +
> +Public Functions Provided
> +=========================
> +
> +This chapter contains the autogenerated documentation of the kernel API
> +functions which are exported.
> +
> +.. kernel-doc:: kernel/irq/manage.c
> + :export:
> +
> +.. kernel-doc:: kernel/irq/chip.c
> + :export:
> +
> +Internal Functions Provided
> +===========================
> +
> +This chapter contains the autogenerated documentation of the internal
> +functions.
> +
> +.. kernel-doc:: kernel/irq/irqdesc.c
> + :internal:
> +
> +.. kernel-doc:: kernel/irq/handle.c
> + :internal:
> +
> +.. kernel-doc:: kernel/irq/chip.c
> + :internal:
> +
> +Credits
> +=======
> +
> +The following people have contributed to this document:
> +
> +1. Thomas Gleixner tglx@linutronix.de
> +
> +2. Ingo Molnar mingo@elte.hu
> diff --git a/Documentation/core-api/index.rst b/Documentation/core-api/index.rst
> index 0d93d8089136..c058febbd991 100644
> --- a/Documentation/core-api/index.rst
> +++ b/Documentation/core-api/index.rst
> @@ -16,6 +16,7 @@ Core utilities
> cpu_hotplug
> local_ops
> workqueue
> + genericirq
>
> Interfaces for kernel debugging
> ===============================