]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - Documentation/DocBook/uio-howto.tmpl
drivers/mmc/card/block.c: fix refcount leak in mmc_block_open()
[linux-2.6-omap-h63xx.git] / Documentation / DocBook / uio-howto.tmpl
index c119484258b8428d59b07b3046a5c5d48def9519..df87d1b93605ac54cf400bd7b8d44b0866d0789a 100644 (file)
     </affiliation>
 </author>
 
     </affiliation>
 </author>
 
+<copyright>
+       <year>2006-2008</year>
+       <holder>Hans-Jürgen Koch.</holder>
+</copyright>
+
+<legalnotice>
+<para>
+This documentation is Free Software licensed under the terms of the
+GPL version 2.
+</para>
+</legalnotice>
+
 <pubdate>2006-12-11</pubdate>
 
 <abstract>
 <pubdate>2006-12-11</pubdate>
 
 <abstract>
 </abstract>
 
 <revhistory>
 </abstract>
 
 <revhistory>
+       <revision>
+       <revnumber>0.5</revnumber>
+       <date>2008-05-22</date>
+       <authorinitials>hjk</authorinitials>
+       <revremark>Added description of write() function.</revremark>
+       </revision>
+       <revision>
+       <revnumber>0.4</revnumber>
+       <date>2007-11-26</date>
+       <authorinitials>hjk</authorinitials>
+       <revremark>Removed section about uio_dummy.</revremark>
+       </revision>
        <revision>
        <revnumber>0.3</revnumber>
        <date>2007-04-29</date>
        <revision>
        <revnumber>0.3</revnumber>
        <date>2007-04-29</date>
 </bookinfo>
 
 <chapter id="aboutthisdoc">
 </bookinfo>
 
 <chapter id="aboutthisdoc">
-<?dbhtml filename="about.html"?>
+<?dbhtml filename="aboutthis.html"?>
 <title>About this document</title>
 
 <title>About this document</title>
 
-<sect1 id="copyright">
-<?dbhtml filename="copyright.html"?>
-<title>Copyright and License</title>
-<para>
-      Copyright (c) 2006 by Hans-Jürgen Koch.</para>
-<para>
-This documentation is Free Software licensed under the terms of the
-GPL version 2.
-</para>
-</sect1>
-
 <sect1 id="translations">
 <?dbhtml filename="translations.html"?>
 <title>Translations</title>
 <sect1 id="translations">
 <?dbhtml filename="translations.html"?>
 <title>Translations</title>
@@ -94,6 +107,26 @@ interested in translating it, please email me
        user space. This simplifies development and reduces the risk of
        serious bugs within a kernel module.
        </para>
        user space. This simplifies development and reduces the risk of
        serious bugs within a kernel module.
        </para>
+       <para>
+       Please note that UIO is not an universal driver interface. Devices
+       that are already handled well by other kernel subsystems (like
+       networking or serial or USB) are no candidates for an UIO driver.
+       Hardware that is ideally suited for an UIO driver fulfills all of
+       the following:
+       </para>
+<itemizedlist>
+<listitem>
+       <para>The device has memory that can be mapped. The device can be
+       controlled completely by writing to this memory.</para>
+</listitem>
+<listitem>
+       <para>The device usually generates interrupts.</para>
+</listitem>
+<listitem>
+       <para>The device does not fit into one of the standard kernel
+       subsystems.</para>
+</listitem>
+</itemizedlist>
 </sect1>
 
 <sect1 id="thanks">
 </sect1>
 
 <sect1 id="thanks">
@@ -163,6 +196,30 @@ interested in translating it, please email me
        represents the total interrupt count. You can use this number
        to figure out if you missed some interrupts.
        </para>
        represents the total interrupt count. You can use this number
        to figure out if you missed some interrupts.
        </para>
+       <para>
+       For some hardware that has more than one interrupt source internally,
+       but not separate IRQ mask and status registers, there might be
+       situations where userspace cannot determine what the interrupt source
+       was if the kernel handler disables them by writing to the chip's IRQ
+       register. In such a case, the kernel has to disable the IRQ completely
+       to leave the chip's register untouched. Now the userspace part can
+       determine the cause of the interrupt, but it cannot re-enable
+       interrupts. Another cornercase is chips where re-enabling interrupts
+       is a read-modify-write operation to a combined IRQ status/acknowledge
+       register. This would be racy if a new interrupt occurred
+       simultaneously.
+       </para>
+       <para>
+       To address these problems, UIO also implements a write() function. It
+       is normally not used and can be ignored for hardware that has only a
+       single interrupt source or has separate IRQ mask and status registers.
+       If you need it, however, a write to <filename>/dev/uioX</filename>
+       will call the <function>irqcontrol()</function> function implemented
+       by the driver. You have to write a 32-bit value that is usually either
+       0 or 1 to disable or enable interrupts. If a driver does not implement
+       <function>irqcontrol()</function>, <function>write()</function> will
+       return with <varname>-ENOSYS</varname>.
+       </para>
 
        <para>
        To handle interrupts properly, your custom kernel module can
 
        <para>
        To handle interrupts properly, your custom kernel module can
@@ -174,8 +231,9 @@ interested in translating it, please email me
        For cards that don't generate interrupts but need to be
        polled, there is the possibility to set up a timer that
        triggers the interrupt handler at configurable time intervals.
        For cards that don't generate interrupts but need to be
        polled, there is the possibility to set up a timer that
        triggers the interrupt handler at configurable time intervals.
-       See <filename>drivers/uio/uio_dummy.c</filename> for an
-       example of this technique.
+       This interrupt simulation is done by calling
+       <function>uio_event_notify()</function>
+       from the timer's event handler.
        </para>
 
        <para>
        </para>
 
        <para>
@@ -263,63 +321,11 @@ offset = N * getpagesize();
 </sect1>
 </chapter>
 
 </sect1>
 </chapter>
 
-<chapter id="using-uio_dummy" xreflabel="Using uio_dummy">
-<?dbhtml filename="using-uio_dummy.html"?>
-<title>Using uio_dummy</title>
-       <para>
-       Well, there is no real use for uio_dummy. Its only purpose is
-       to test most parts of the UIO system (everything except
-       hardware interrupts), and to serve as an example for the
-       kernel module that you will have to write yourself.
-       </para>
-
-<sect1 id="what_uio_dummy_does">
-<title>What uio_dummy does</title>
-       <para>
-       The kernel module <filename>uio_dummy.ko</filename> creates a
-       device that uses a timer to generate periodic interrupts. The
-       interrupt handler does nothing but increment a counter. The
-       driver adds two custom attributes, <varname>count</varname>
-       and <varname>freq</varname>, that appear under
-       <filename>/sys/devices/platform/uio_dummy/</filename>.
-       </para>
-
-       <para>
-       The attribute <varname>count</varname> can be read and
-       written.  The associated file
-       <filename>/sys/devices/platform/uio_dummy/count</filename>
-       appears as a normal text file and contains the total number of
-       timer interrupts. If you look at it (e.g. using
-       <function>cat</function>), you'll notice it is slowly counting
-       up.
-       </para>
-
-       <para>
-       The attribute <varname>freq</varname> can be read and written.
-       The content of
-       <filename>/sys/devices/platform/uio_dummy/freq</filename>
-       represents the number of system timer ticks between two timer
-       interrupts. The default value of <varname>freq</varname> is
-       the value of the kernel variable <varname>HZ</varname>, which
-       gives you an interval of one second. Lower values will
-       increase the frequency. Try the following:
-       </para>
-<programlisting format="linespecific">
-cd /sys/devices/platform/uio_dummy/
-echo 100 > freq
-</programlisting>
-       <para>
-       Use <function>cat count</function> to see how the interrupt
-       frequency changes.
-       </para>
-</sect1>
-</chapter>
-
 <chapter id="custom_kernel_module" xreflabel="Writing your own kernel module">
 <?dbhtml filename="custom_kernel_module.html"?>
 <title>Writing your own kernel module</title>
        <para>
 <chapter id="custom_kernel_module" xreflabel="Writing your own kernel module">
 <?dbhtml filename="custom_kernel_module.html"?>
 <title>Writing your own kernel module</title>
        <para>
-       Please have a look at <filename>uio_dummy.c</filename> as an
+       Please have a look at <filename>uio_cif.c</filename> as an
        example. The following paragraphs explain the different
        sections of this file.
        </para>
        example. The following paragraphs explain the different
        sections of this file.
        </para>
@@ -354,9 +360,8 @@ See the description below for details.
 interrupt, it's your modules task to determine the irq number during
 initialization. If you don't have a hardware generated interrupt but
 want to trigger the interrupt handler in some other way, set
 interrupt, it's your modules task to determine the irq number during
 initialization. If you don't have a hardware generated interrupt but
 want to trigger the interrupt handler in some other way, set
-<varname>irq</varname> to <varname>UIO_IRQ_CUSTOM</varname>. The
-uio_dummy module does this as it triggers the event mechanism in a timer
-routine. If you had no interrupt at all, you could set
+<varname>irq</varname> to <varname>UIO_IRQ_CUSTOM</varname>.
+If you had no interrupt at all, you could set
 <varname>irq</varname> to <varname>UIO_IRQ_NONE</varname>, though this
 rarely makes sense.
 </para></listitem>
 <varname>irq</varname> to <varname>UIO_IRQ_NONE</varname>, though this
 rarely makes sense.
 </para></listitem>
@@ -388,6 +393,14 @@ device is actually used.
 <function>open()</function>, you will probably also want a custom
 <function>release()</function> function.
 </para></listitem>
 <function>open()</function>, you will probably also want a custom
 <function>release()</function> function.
 </para></listitem>
+
+<listitem><para>
+<varname>int (*irqcontrol)(struct uio_info *info, s32 irq_on)
+</varname>: Optional. If you need to be able to enable or disable
+interrupts from userspace by writing to <filename>/dev/uioX</filename>,
+you can implement this function. The parameter <varname>irq_on</varname>
+will be 0 to disable interrupts and 1 to enable them.
+</para></listitem>
 </itemizedlist>
 
 <para>
 </itemizedlist>
 
 <para>