[media] DVB API: Mention the dvbM device
[linux-2.6.git] / Documentation / DocBook / genericirq.tmpl
index 3a882d9..b342234 100644 (file)
@@ -28,7 +28,7 @@
   </authorgroup>
 
   <copyright>
-   <year>2005-2006</year>
+   <year>2005-2010</year>
    <holder>Thomas Gleixner</holder>
   </copyright>
   <copyright>
          <listitem><para>Edge type</para></listitem>
          <listitem><para>Simple type</para></listitem>
        </itemizedlist>
+       During the implementation we identified another type:
+       <itemizedlist>
+         <listitem><para>Fast EOI type</para></listitem>
+       </itemizedlist>
        In the SMP world of the __do_IRQ() super-handler another type
        was identified:
        <itemizedlist>
        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.
        </para>
   </chapter>
   <chapter id="bugs">
        <para>
        Whenever an interrupt triggers, the lowlevel arch code calls into
        the generic interrupt code by calling desc->handle_irq().
-       This highlevel IRQ handling function only uses desc->chip primitives
-       referenced by the assigned chip descriptor structure.
+       This highlevel IRQ handling function only uses desc->irq_data.chip
+       primitives referenced by the assigned chip descriptor structure.
        </para>
     </sect1>
     <sect1 id="Highlevel_Driver_API">
          <listitem><para>enable_irq()</para></listitem>
          <listitem><para>disable_irq_nosync() (SMP only)</para></listitem>
          <listitem><para>synchronize_irq() (SMP only)</para></listitem>
-         <listitem><para>set_irq_type()</para></listitem>
-         <listitem><para>set_irq_wake()</para></listitem>
-         <listitem><para>set_irq_data()</para></listitem>
-         <listitem><para>set_irq_chip()</para></listitem>
-         <listitem><para>set_irq_chip_data()</para></listitem>
+         <listitem><para>irq_set_irq_type()</para></listitem>
+         <listitem><para>irq_set_irq_wake()</para></listitem>
+         <listitem><para>irq_set_handler_data()</para></listitem>
+         <listitem><para>irq_set_chip()</para></listitem>
+         <listitem><para>irq_set_chip_data()</para></listitem>
           </itemizedlist>
          See the autogenerated function documentation for details.
        </para>
          <itemizedlist>
          <listitem><para>handle_level_irq</para></listitem>
          <listitem><para>handle_edge_irq</para></listitem>
+         <listitem><para>handle_fasteoi_irq</para></listitem>
          <listitem><para>handle_simple_irq</para></listitem>
          <listitem><para>handle_percpu_irq</para></listitem>
+         <listitem><para>handle_edge_eoi_irq</para></listitem>
+         <listitem><para>handle_bad_irq</para></listitem>
          </itemizedlist>
          The interrupt flow handlers (either predefined or architecture
          specific) are assigned to specific interrupts by the architecture
                are used by the default flow implementations.
                The following helper functions are implemented (simplified excerpt):
                <programlisting>
-default_enable(irq)
+default_enable(struct irq_data *data)
 {
-       desc->chip->unmask(irq);
+       desc->irq_data.chip->irq_unmask(data);
 }
 
-default_disable(irq)
+default_disable(struct irq_data *data)
 {
-       if (!delay_disable(irq))
-               desc->chip->mask(irq);
+       if (!delay_disable(data))
+               desc->irq_data.chip->irq_mask(data);
 }
 
-default_ack(irq)
+default_ack(struct irq_data *data)
 {
-       chip->ack(irq);
+       chip->irq_ack(data);
 }
 
-default_mask_ack(irq)
+default_mask_ack(struct irq_data *data)
 {
-       if (chip->mask_ack) {
-               chip->mask_ack(irq);
+       if (chip->irq_mask_ack) {
+               chip->irq_mask_ack(data);
        } else {
-               chip->mask(irq);
-               chip->ack(irq);
+               chip->irq_mask(data);
+               chip->irq_ack(data);
        }
 }
 
-noop(irq)
+noop(struct irq_data *data))
 {
 }
 
@@ -278,12 +286,27 @@ noop(irq)
                <para>
                The following control flow is implemented (simplified excerpt):
                <programlisting>
-desc->chip->start();
-handle_IRQ_event(desc->action);
-desc->chip->end();
+desc->irq_data.chip->irq_mask_ack();
+handle_irq_event(desc->action);
+desc->irq_data.chip->irq_unmask();
                </programlisting>
                </para>
-           </sect3>
+           </sect3>
+           <sect3 id="Default_FASTEOI_IRQ_flow_handler">
+               <title>Default Fast EOI IRQ flow handler</title>
+               <para>
+               handle_fasteoi_irq provides a generic implementation
+               for interrupts, which only need an EOI at the end of
+               the handler
+               </para>
+               <para>
+               The following control flow is implemented (simplified excerpt):
+               <programlisting>
+handle_irq_event(desc->action);
+desc->irq_data.chip->irq_eoi();
+               </programlisting>
+               </para>
+           </sect3>
            <sect3 id="Default_Edge_IRQ_flow_handler">
                <title>Default Edge IRQ flow handler</title>
                <para>
@@ -294,20 +317,19 @@ desc->chip->end();
                The following control flow is implemented (simplified excerpt):
                <programlisting>
 if (desc->status &amp; running) {
-       desc->chip->hold();
+       desc->irq_data.chip->irq_mask_ack();
        desc->status |= pending | masked;
        return;
 }
-desc->chip->start();
+desc->irq_data.chip->irq_ack();
 desc->status |= running;
 do {
        if (desc->status &amp; masked)
-               desc->chip->enable();
+               desc->irq_data.chip->irq_unmask();
        desc->status &amp;= ~pending;
-       handle_IRQ_event(desc->action);
+       handle_irq_event(desc->action);
 } while (status &amp; pending);
 desc->status &amp;= ~running;
-desc->chip->end();
                </programlisting>
                </para>
            </sect3>
@@ -324,7 +346,7 @@ desc->chip->end();
                <para>
                The following control flow is implemented (simplified excerpt):
                <programlisting>
-handle_IRQ_event(desc->action);
+handle_irq_event(desc->action);
                </programlisting>
                </para>
            </sect3>
@@ -342,12 +364,29 @@ handle_IRQ_event(desc->action);
                <para>
                The following control flow is implemented (simplified excerpt):
                <programlisting>
-desc->chip->start();
-handle_IRQ_event(desc->action);
-desc->chip->end();
+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>
                </para>
            </sect3>
+           <sect3 id="EOI_Edge_IRQ_flow_handler">
+               <title>EOI Edge IRQ flow handler</title>
+               <para>
+               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.
+               </para>
+           </sect3>
+           <sect3 id="BAD_IRQ_flow_handler">
+               <title>Bad IRQ flow handler</title>
+               <para>
+               handle_bad_irq is used for spurious interrupts which
+               have no real handler assigned..
+               </para>
+           </sect3>
        </sect2>
        <sect2 id="Quirks_and_optimizations">
        <title>Quirks and optimizations</title>
@@ -375,8 +414,7 @@ desc->chip->end();
        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 can be runtime enabled, per interrupt,
-       by setting the IRQ_DELAYED_DISABLE flag in the irq_desc status field.
+       The delayed interrupt disable is not configurable.
        </para>
        </sect2>
     </sect1>
@@ -387,13 +425,14 @@ desc->chip->end();
        contains all the direct chip relevant functions, which
        can be utilized by the irq flow implementations.
          <itemizedlist>
-         <listitem><para>ack()</para></listitem>
-         <listitem><para>mask_ack() - Optional, recommended for performance</para></listitem>
-         <listitem><para>mask()</para></listitem>
-         <listitem><para>unmask()</para></listitem>
-         <listitem><para>retrigger() - Optional</para></listitem>
-         <listitem><para>set_type() - Optional</para></listitem>
-         <listitem><para>set_wake() - Optional</para></listitem>
+         <listitem><para>irq_ack()</para></listitem>
+         <listitem><para>irq_mask_ack() - Optional, recommended for performance</para></listitem>
+         <listitem><para>irq_mask()</para></listitem>
+         <listitem><para>irq_unmask()</para></listitem>
+         <listitem><para>irq_eoi() - Optional, required for eoi flow handlers</para></listitem>
+         <listitem><para>irq_retrigger() - Optional</para></listitem>
+         <listitem><para>irq_set_type() - Optional</para></listitem>
+         <listitem><para>irq_set_wake() - Optional</para></listitem>
          </itemizedlist>
        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
@@ -405,32 +444,24 @@ desc->chip->end();
   <chapter id="doirq">
      <title>__do_IRQ entry point</title>
      <para>
-       The original implementation __do_IRQ() is an alternative entry
-       point for all types of interrupts.
+       The original implementation __do_IRQ() was an alternative entry
+       point for all types of interrupts. It not longer exists.
      </para>
      <para>
        This handler turned out to be not suitable for all
        interrupt hardware and was therefore reimplemented with split
-       functionality for egde/level/simple/percpu interrupts. This is not
+       functionality for edge/level/simple/percpu interrupts. This is not
        only a functional optimization. It also shortens code paths for
        interrupts.
       </para>
-      <para>
-       To make use of the split implementation, replace the call to
-       __do_IRQ by a call to desc->chip->handle_irq() and associate
-        the appropriate handler function to desc->chip->handle_irq().
-       In most cases the generic handler implementations should
-       be sufficient.
-     </para>
   </chapter>
 
   <chapter id="locking">
      <title>Locking on SMP</title>
      <para>
        The locking of chip registers is up to the architecture that
-       defines the chip primitives. There is a chip->lock field that can be used
-       for serialization, but the generic layer does not touch it. The per-irq
-       structure is protected via desc->lock, by the generic layer.
+       defines the chip primitives. The per-irq structure is
+       protected via desc->lock, by the generic layer.
      </para>
   </chapter>
   <chapter id="structs">
@@ -440,6 +471,7 @@ desc->chip->end();
      used in the generic IRQ layer.
      </para>
 !Iinclude/linux/irq.h
+!Iinclude/linux/interrupt.h
   </chapter>
 
   <chapter id="pubfunctions">
@@ -457,6 +489,7 @@ desc->chip->end();
      <para>
      This chapter contains the autogenerated documentation of the internal functions.
      </para>
+!Ikernel/irq/irqdesc.c
 !Ikernel/irq/handle.c
 !Ikernel/irq/chip.c
   </chapter>