X-Git-Url: https://git.openpandora.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=Documentation%2FDocBook%2Fuio-howto.tmpl;h=df87d1b93605ac54cf400bd7b8d44b0866d0789a;hb=eda3d8f5604860aae1bb9996bb5efc4213778369;hp=e3bb29a8d8dd89f60f6bd2f83771a06111ea64cd;hpb=d9ff963801e4f7648c55a27413a1b1de59480a30;p=pandora-kernel.git
diff --git a/Documentation/DocBook/uio-howto.tmpl b/Documentation/DocBook/uio-howto.tmpl
index e3bb29a8d8dd..df87d1b93605 100644
--- a/Documentation/DocBook/uio-howto.tmpl
+++ b/Documentation/DocBook/uio-howto.tmpl
@@ -21,6 +21,18 @@
+
+ 2006-2008
+ Hans-Jürgen Koch.
+
+
+
+
+This documentation is Free Software licensed under the terms of the
+GPL version 2.
+
+
+
2006-12-11
@@ -29,6 +41,18 @@
+
+ 0.5
+ 2008-05-22
+ hjk
+ Added description of write() function.
+
+
+ 0.4
+ 2007-11-26
+ hjk
+ Removed section about uio_dummy.
+
0.3
2007-04-29
@@ -51,20 +75,9 @@
-
+
About this document
-
-
-Copyright and License
-
- Copyright (c) 2006 by Hans-Jürgen Koch.
-
-This documentation is Free Software licensed under the terms of the
-GPL version 2.
-
-
-
Translations
@@ -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.
+
+ 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:
+
+
+
+ The device has memory that can be mapped. The device can be
+ controlled completely by writing to this memory.
+
+
+ The device usually generates interrupts.
+
+
+ The device does not fit into one of the standard kernel
+ subsystems.
+
+
@@ -133,10 +166,6 @@ interested in translating it, please email me
updates of your driver can take place without recompiling
the kernel.
-
- if you need to keep some parts of your driver closed source,
- you can do so without violating the GPL license on the kernel.
-
@@ -167,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.
+
+ 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.
+
+
+ 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 /dev/uioX
+ will call the irqcontrol() 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
+ irqcontrol(), write() will
+ return with -ENOSYS.
+
To handle interrupts properly, your custom kernel module can
@@ -178,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.
- See drivers/uio/uio_dummy.c for an
- example of this technique.
+ This interrupt simulation is done by calling
+ uio_event_notify()
+ from the timer's event handler.
@@ -267,63 +321,11 @@ offset = N * getpagesize();
-
-
-Using uio_dummy
-
- 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.
-
-
-
-What uio_dummy does
-
- The kernel module uio_dummy.ko 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, count
- and freq, that appear under
- /sys/devices/platform/uio_dummy/.
-
-
-
- The attribute count can be read and
- written. The associated file
- /sys/devices/platform/uio_dummy/count
- appears as a normal text file and contains the total number of
- timer interrupts. If you look at it (e.g. using
- cat), you'll notice it is slowly counting
- up.
-
-
-
- The attribute freq can be read and written.
- The content of
- /sys/devices/platform/uio_dummy/freq
- represents the number of system timer ticks between two timer
- interrupts. The default value of freq is
- the value of the kernel variable HZ, which
- gives you an interval of one second. Lower values will
- increase the frequency. Try the following:
-
-
-cd /sys/devices/platform/uio_dummy/
-echo 100 > freq
-
-
- Use cat count to see how the interrupt
- frequency changes.
-
-
-
-
Writing your own kernel module
- Please have a look at uio_dummy.c as an
+ Please have a look at uio_cif.c as an
example. The following paragraphs explain the different
sections of this file.
@@ -358,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
-irq to UIO_IRQ_CUSTOM. 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
+irq to UIO_IRQ_CUSTOM.
+If you had no interrupt at all, you could set
irq to UIO_IRQ_NONE, though this
rarely makes sense.
@@ -392,6 +393,14 @@ device is actually used.
open(), you will probably also want a custom
release() function.
+
+
+int (*irqcontrol)(struct uio_info *info, s32 irq_on)
+: Optional. If you need to be able to enable or disable
+interrupts from userspace by writing to /dev/uioX,
+you can implement this function. The parameter irq_on
+will be 0 to disable interrupts and 1 to enable them.
+