summaryrefslogtreecommitdiff
path: root/Documentation/DocBook
diff options
context:
space:
mode:
Diffstat (limited to 'Documentation/DocBook')
-rw-r--r--Documentation/DocBook/Makefile7
-rw-r--r--Documentation/DocBook/deviceiobook.tmpl323
-rw-r--r--Documentation/DocBook/iio.tmpl697
-rw-r--r--Documentation/DocBook/kgdb.tmpl8
-rw-r--r--Documentation/DocBook/libata.tmpl2
-rw-r--r--Documentation/DocBook/regulator.tmpl304
-rw-r--r--Documentation/DocBook/uio-howto.tmpl1112
7 files changed, 9 insertions, 2444 deletions
diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile
index a6eb7dcd4dd5..60a17b7da834 100644
--- a/Documentation/DocBook/Makefile
+++ b/Documentation/DocBook/Makefile
@@ -11,9 +11,9 @@ DOCBOOKS := z8530book.xml \
writing_usb_driver.xml networking.xml \
kernel-api.xml filesystems.xml lsm.xml kgdb.xml \
gadget.xml libata.xml mtdnand.xml librs.xml rapidio.xml \
- genericirq.xml s390-drivers.xml uio-howto.xml scsi.xml \
+ genericirq.xml s390-drivers.xml scsi.xml \
sh.xml regulator.xml w1.xml \
- writing_musb_glue_layer.xml iio.xml
+ writing_musb_glue_layer.xml
ifeq ($(DOCBOOKS),)
@@ -71,6 +71,7 @@ installmandocs: mandocs
# no-op for the DocBook toolchain
epubdocs:
latexdocs:
+linkcheckdocs:
###
#External programs used
@@ -272,6 +273,6 @@ cleandocs:
$(Q)rm -rf $(call objectify, $(clean-dirs))
# Declare the contents of the .PHONY variable as phony. We keep that
-# information in a variable se we can use it in if_changed and friends.
+# information in a variable so we can use it in if_changed and friends.
.PHONY: $(PHONY)
diff --git a/Documentation/DocBook/deviceiobook.tmpl b/Documentation/DocBook/deviceiobook.tmpl
deleted file mode 100644
index 54199a0dcf9a..000000000000
--- a/Documentation/DocBook/deviceiobook.tmpl
+++ /dev/null
@@ -1,323 +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="DoingIO">
- <bookinfo>
- <title>Bus-Independent Device Accesses</title>
-
- <authorgroup>
- <author>
- <firstname>Matthew</firstname>
- <surname>Wilcox</surname>
- <affiliation>
- <address>
- <email>matthew@wil.cx</email>
- </address>
- </affiliation>
- </author>
- </authorgroup>
-
- <authorgroup>
- <author>
- <firstname>Alan</firstname>
- <surname>Cox</surname>
- <affiliation>
- <address>
- <email>alan@lxorguk.ukuu.org.uk</email>
- </address>
- </affiliation>
- </author>
- </authorgroup>
-
- <copyright>
- <year>2001</year>
- <holder>Matthew Wilcox</holder>
- </copyright>
-
- <legalnotice>
- <para>
- This documentation is free software; you can redistribute
- it and/or modify it under the terms of the GNU General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later
- version.
- </para>
-
- <para>
- 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.
- </para>
-
- <para>
- 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
- </para>
-
- <para>
- For more details see the file COPYING in the source
- distribution of Linux.
- </para>
- </legalnotice>
- </bookinfo>
-
-<toc></toc>
-
- <chapter id="intro">
- <title>Introduction</title>
- <para>
- Linux provides an API which abstracts performing IO across all busses
- and devices, allowing device drivers to be written independently of
- bus type.
- </para>
- </chapter>
-
- <chapter id="bugs">
- <title>Known Bugs And Assumptions</title>
- <para>
- None.
- </para>
- </chapter>
-
- <chapter id="mmio">
- <title>Memory Mapped IO</title>
- <sect1 id="getting_access_to_the_device">
- <title>Getting Access to the Device</title>
- <para>
- The most widely supported form of IO is memory mapped IO.
- That is, a part of the CPU's address space is interpreted
- not as accesses to memory, but as accesses to a device. Some
- architectures define devices to be at a fixed address, but most
- have some method of discovering devices. The PCI bus walk is a
- good example of such a scheme. This document does not cover how
- to receive such an address, but assumes you are starting with one.
- Physical addresses are of type unsigned long.
- </para>
-
- <para>
- This address should not be used directly. Instead, to get an
- address suitable for passing to the accessor functions described
- below, you should call <function>ioremap</function>.
- An address suitable for accessing the device will be returned to you.
- </para>
-
- <para>
- After you've finished using the device (say, in your module's
- exit routine), call <function>iounmap</function> in order to return
- the address space to the kernel. Most architectures allocate new
- address space each time you call <function>ioremap</function>, and
- they can run out unless you call <function>iounmap</function>.
- </para>
- </sect1>
-
- <sect1 id="accessing_the_device">
- <title>Accessing the device</title>
- <para>
- The part of the interface most used by drivers is reading and
- writing memory-mapped registers on the device. Linux provides
- interfaces to read and write 8-bit, 16-bit, 32-bit and 64-bit
- quantities. Due to a historical accident, these are named byte,
- word, long and quad accesses. Both read and write accesses are
- supported; there is no prefetch support at this time.
- </para>
-
- <para>
- The functions are named <function>readb</function>,
- <function>readw</function>, <function>readl</function>,
- <function>readq</function>, <function>readb_relaxed</function>,
- <function>readw_relaxed</function>, <function>readl_relaxed</function>,
- <function>readq_relaxed</function>, <function>writeb</function>,
- <function>writew</function>, <function>writel</function> and
- <function>writeq</function>.
- </para>
-
- <para>
- Some devices (such as framebuffers) would like to use larger
- transfers than 8 bytes at a time. For these devices, the
- <function>memcpy_toio</function>, <function>memcpy_fromio</function>
- and <function>memset_io</function> functions are provided.
- Do not use memset or memcpy on IO addresses; they
- are not guaranteed to copy data in order.
- </para>
-
- <para>
- The read and write functions are defined to be ordered. That is the
- compiler is not permitted to reorder the I/O sequence. When the
- ordering can be compiler optimised, you can use <function>
- __readb</function> and friends to indicate the relaxed ordering. Use
- this with care.
- </para>
-
- <para>
- While the basic functions are defined to be synchronous with respect
- to each other and ordered with respect to each other the busses the
- devices sit on may themselves have asynchronicity. In particular many
- authors are burned by the fact that PCI bus writes are posted
- asynchronously. A driver author must issue a read from the same
- device to ensure that writes have occurred in the specific cases the
- author cares. This kind of property cannot be hidden from driver
- writers in the API. In some cases, the read used to flush the device
- may be expected to fail (if the card is resetting, for example). In
- that case, the read should be done from config space, which is
- guaranteed to soft-fail if the card doesn't respond.
- </para>
-
- <para>
- The following is an example of flushing a write to a device when
- the driver would like to ensure the write's effects are visible prior
- to continuing execution.
- </para>
-
-<programlisting>
-static inline void
-qla1280_disable_intrs(struct scsi_qla_host *ha)
-{
- struct device_reg *reg;
-
- reg = ha->iobase;
- /* disable risc and host interrupts */
- WRT_REG_WORD(&amp;reg->ictrl, 0);
- /*
- * The following read will ensure that the above write
- * has been received by the device before we return from this
- * function.
- */
- RD_REG_WORD(&amp;reg->ictrl);
- ha->flags.ints_enabled = 0;
-}
-</programlisting>
-
- <para>
- In addition to write posting, on some large multiprocessing systems
- (e.g. SGI Challenge, Origin and Altix machines) posted writes won't
- be strongly ordered coming from different CPUs. Thus it's important
- to properly protect parts of your driver that do memory-mapped writes
- with locks and use the <function>mmiowb</function> to make sure they
- arrive in the order intended. Issuing a regular <function>readX
- </function> will also ensure write ordering, but should only be used
- when the driver has to be sure that the write has actually arrived
- at the device (not that it's simply ordered with respect to other
- writes), since a full <function>readX</function> is a relatively
- expensive operation.
- </para>
-
- <para>
- Generally, one should use <function>mmiowb</function> prior to
- releasing a spinlock that protects regions using <function>writeb
- </function> or similar functions that aren't surrounded by <function>
- readb</function> calls, which will ensure ordering and flushing. The
- following pseudocode illustrates what might occur if write ordering
- isn't guaranteed via <function>mmiowb</function> or one of the
- <function>readX</function> functions.
- </para>
-
-<programlisting>
-CPU A: spin_lock_irqsave(&amp;dev_lock, flags)
-CPU A: ...
-CPU A: writel(newval, ring_ptr);
-CPU A: spin_unlock_irqrestore(&amp;dev_lock, flags)
- ...
-CPU B: spin_lock_irqsave(&amp;dev_lock, flags)
-CPU B: writel(newval2, ring_ptr);
-CPU B: ...
-CPU B: spin_unlock_irqrestore(&amp;dev_lock, flags)
-</programlisting>
-
- <para>
- In the case above, newval2 could be written to ring_ptr before
- newval. Fixing it is easy though:
- </para>
-
-<programlisting>
-CPU A: spin_lock_irqsave(&amp;dev_lock, flags)
-CPU A: ...
-CPU A: writel(newval, ring_ptr);
-CPU A: mmiowb(); /* ensure no other writes beat us to the device */
-CPU A: spin_unlock_irqrestore(&amp;dev_lock, flags)
- ...
-CPU B: spin_lock_irqsave(&amp;dev_lock, flags)
-CPU B: writel(newval2, ring_ptr);
-CPU B: ...
-CPU B: mmiowb();
-CPU B: spin_unlock_irqrestore(&amp;dev_lock, flags)
-</programlisting>
-
- <para>
- See tg3.c for a real world example of how to use <function>mmiowb
- </function>
- </para>
-
- <para>
- PCI ordering rules also guarantee that PIO read responses arrive
- after any outstanding DMA writes from that bus, since for some devices
- the result of a <function>readb</function> call may signal to the
- driver that a DMA transaction is complete. In many cases, however,
- the driver may want to indicate that the next
- <function>readb</function> call has no relation to any previous DMA
- writes performed by the device. The driver can use
- <function>readb_relaxed</function> for these cases, although only
- some platforms will honor the relaxed semantics. Using the relaxed
- read functions will provide significant performance benefits on
- platforms that support it. The qla2xxx driver provides examples
- of how to use <function>readX_relaxed</function>. In many cases,
- a majority of the driver's <function>readX</function> calls can
- safely be converted to <function>readX_relaxed</function> calls, since
- only a few will indicate or depend on DMA completion.
- </para>
- </sect1>
-
- </chapter>
-
- <chapter id="port_space_accesses">
- <title>Port Space Accesses</title>
- <sect1 id="port_space_explained">
- <title>Port Space Explained</title>
-
- <para>
- Another form of IO commonly supported is Port Space. This is a
- range of addresses separate to the normal memory address space.
- Access to these addresses is generally not as fast as accesses
- to the memory mapped addresses, and it also has a potentially
- smaller address space.
- </para>
-
- <para>
- Unlike memory mapped IO, no preparation is required
- to access port space.
- </para>
-
- </sect1>
- <sect1 id="accessing_port_space">
- <title>Accessing Port Space</title>
- <para>
- Accesses to this space are provided through a set of functions
- which allow 8-bit, 16-bit and 32-bit accesses; also
- known as byte, word and long. These functions are
- <function>inb</function>, <function>inw</function>,
- <function>inl</function>, <function>outb</function>,
- <function>outw</function> and <function>outl</function>.
- </para>
-
- <para>
- Some variants are provided for these functions. Some devices
- require that accesses to their ports are slowed down. This
- functionality is provided by appending a <function>_p</function>
- to the end of the function. There are also equivalents to memcpy.
- The <function>ins</function> and <function>outs</function>
- functions copy bytes, words or longs to the given port.
- </para>
- </sect1>
-
- </chapter>
-
- <chapter id="pubfunctions">
- <title>Public Functions Provided</title>
-!Iarch/x86/include/asm/io.h
-!Elib/pci_iomap.c
- </chapter>
-
-</book>
diff --git a/Documentation/DocBook/iio.tmpl b/Documentation/DocBook/iio.tmpl
deleted file mode 100644
index e2ab6a1f223e..000000000000
--- a/Documentation/DocBook/iio.tmpl
+++ /dev/null
@@ -1,697 +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="iioid">
- <bookinfo>
- <title>Industrial I/O driver developer's guide </title>
-
- <authorgroup>
- <author>
- <firstname>Daniel</firstname>
- <surname>Baluta</surname>
- <affiliation>
- <address>
- <email>daniel.baluta@intel.com</email>
- </address>
- </affiliation>
- </author>
- </authorgroup>
-
- <copyright>
- <year>2015</year>
- <holder>Intel Corporation</holder>
- </copyright>
-
- <legalnotice>
- <para>
- This documentation is free software; you can redistribute
- it and/or modify it under the terms of the GNU General Public
- License version 2.
- </para>
- </legalnotice>
- </bookinfo>
-
- <toc></toc>
-
- <chapter id="intro">
- <title>Introduction</title>
- <para>
- The main purpose of the Industrial I/O subsystem (IIO) is to provide
- support for devices that in some sense perform either analog-to-digital
- conversion (ADC) or digital-to-analog conversion (DAC) or both. The aim
- is to fill the gap between the somewhat similar hwmon and input
- subsystems.
- Hwmon is directed at low sample rate sensors used to monitor and
- control the system itself, like fan speed control or temperature
- measurement. Input is, as its name suggests, focused on human interaction
- input devices (keyboard, mouse, touchscreen). In some cases there is
- considerable overlap between these and IIO.
- </para>
- <para>
- Devices that fall into this category include:
- <itemizedlist>
- <listitem>
- analog to digital converters (ADCs)
- </listitem>
- <listitem>
- accelerometers
- </listitem>
- <listitem>
- capacitance to digital converters (CDCs)
- </listitem>
- <listitem>
- digital to analog converters (DACs)
- </listitem>
- <listitem>
- gyroscopes
- </listitem>
- <listitem>
- inertial measurement units (IMUs)
- </listitem>
- <listitem>
- color and light sensors
- </listitem>
- <listitem>
- magnetometers
- </listitem>
- <listitem>
- pressure sensors
- </listitem>
- <listitem>
- proximity sensors
- </listitem>
- <listitem>
- temperature sensors
- </listitem>
- </itemizedlist>
- Usually these sensors are connected via SPI or I2C. A common use case of the
- sensors devices is to have combined functionality (e.g. light plus proximity
- sensor).
- </para>
- </chapter>
- <chapter id='iiosubsys'>
- <title>Industrial I/O core</title>
- <para>
- The Industrial I/O core offers:
- <itemizedlist>
- <listitem>
- a unified framework for writing drivers for many different types of
- embedded sensors.
- </listitem>
- <listitem>
- a standard interface to user space applications manipulating sensors.
- </listitem>
- </itemizedlist>
- The implementation can be found under <filename>
- drivers/iio/industrialio-*</filename>
- </para>
- <sect1 id="iiodevice">
- <title> Industrial I/O devices </title>
-
-!Finclude/linux/iio/iio.h iio_dev
-!Fdrivers/iio/industrialio-core.c iio_device_alloc
-!Fdrivers/iio/industrialio-core.c iio_device_free
-!Fdrivers/iio/industrialio-core.c iio_device_register
-!Fdrivers/iio/industrialio-core.c iio_device_unregister
-
- <para>
- An IIO device usually corresponds to a single hardware sensor and it
- provides all the information needed by a driver handling a device.
- Let's first have a look at the functionality embedded in an IIO
- device then we will show how a device driver makes use of an IIO
- device.
- </para>
- <para>
- There are two ways for a user space application to interact
- with an IIO driver.
- <itemizedlist>
- <listitem>
- <filename>/sys/bus/iio/iio:deviceX/</filename>, this
- represents a hardware sensor and groups together the data
- channels of the same chip.
- </listitem>
- <listitem>
- <filename>/dev/iio:deviceX</filename>, character device node
- interface used for buffered data transfer and for events information
- retrieval.
- </listitem>
- </itemizedlist>
- </para>
- A typical IIO driver will register itself as an I2C or SPI driver and will
- create two routines, <function> probe </function> and <function> remove
- </function>. At <function>probe</function>:
- <itemizedlist>
- <listitem>call <function>iio_device_alloc</function>, which allocates memory
- for an IIO device.
- </listitem>
- <listitem> initialize IIO device fields with driver specific information
- (e.g. device name, device channels).
- </listitem>
- <listitem>call <function> iio_device_register</function>, this registers the
- device with the IIO core. After this call the device is ready to accept
- requests from user space applications.
- </listitem>
- </itemizedlist>
- At <function>remove</function>, we free the resources allocated in
- <function>probe</function> in reverse order:
- <itemizedlist>
- <listitem><function>iio_device_unregister</function>, unregister the device
- from the IIO core.
- </listitem>
- <listitem><function>iio_device_free</function>, free the memory allocated
- for the IIO device.
- </listitem>
- </itemizedlist>
-
- <sect2 id="iioattr"> <title> IIO device sysfs interface </title>
- <para>
- Attributes are sysfs files used to expose chip info and also allowing
- applications to set various configuration parameters. For device
- with index X, attributes can be found under
- <filename>/sys/bus/iio/iio:deviceX/ </filename> directory.
- Common attributes are:
- <itemizedlist>
- <listitem><filename>name</filename>, description of the physical
- chip.
- </listitem>
- <listitem><filename>dev</filename>, shows the major:minor pair
- associated with <filename>/dev/iio:deviceX</filename> node.
- </listitem>
- <listitem><filename>sampling_frequency_available</filename>,
- available discrete set of sampling frequency values for
- device.
- </listitem>
- </itemizedlist>
- Available standard attributes for IIO devices are described in the
- <filename>Documentation/ABI/testing/sysfs-bus-iio </filename> file
- in the Linux kernel sources.
- </para>
- </sect2>
- <sect2 id="iiochannel"> <title> IIO device channels </title>
-!Finclude/linux/iio/iio.h iio_chan_spec structure.
- <para>
- An IIO device channel is a representation of a data channel. An
- IIO device can have one or multiple channels. For example:
- <itemizedlist>
- <listitem>
- a thermometer sensor has one channel representing the
- temperature measurement.
- </listitem>
- <listitem>
- a light sensor with two channels indicating the measurements in
- the visible and infrared spectrum.
- </listitem>
- <listitem>
- an accelerometer can have up to 3 channels representing
- acceleration on X, Y and Z axes.
- </listitem>
- </itemizedlist>
- An IIO channel is described by the <type> struct iio_chan_spec
- </type>. A thermometer driver for the temperature sensor in the
- example above would have to describe its channel as follows:
- <programlisting>
- static const struct iio_chan_spec temp_channel[] = {
- {
- .type = IIO_TEMP,
- .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
- },
- };
-
- </programlisting>
- Channel sysfs attributes exposed to userspace are specified in
- the form of <emphasis>bitmasks</emphasis>. Depending on their
- shared info, attributes can be set in one of the following masks:
- <itemizedlist>
- <listitem><emphasis>info_mask_separate</emphasis>, attributes will
- be specific to this channel</listitem>
- <listitem><emphasis>info_mask_shared_by_type</emphasis>,
- attributes are shared by all channels of the same type</listitem>
- <listitem><emphasis>info_mask_shared_by_dir</emphasis>, attributes
- are shared by all channels of the same direction </listitem>
- <listitem><emphasis>info_mask_shared_by_all</emphasis>,
- attributes are shared by all channels</listitem>
- </itemizedlist>
- When there are multiple data channels per channel type we have two
- ways to distinguish between them:
- <itemizedlist>
- <listitem> set <emphasis> .modified</emphasis> field of <type>
- iio_chan_spec</type> to 1. Modifiers are specified using
- <emphasis>.channel2</emphasis> field of the same
- <type>iio_chan_spec</type> structure and are used to indicate a
- physically unique characteristic of the channel such as its direction
- or spectral response. For example, a light sensor can have two channels,
- one for infrared light and one for both infrared and visible light.
- </listitem>
- <listitem> set <emphasis>.indexed </emphasis> field of
- <type>iio_chan_spec</type> to 1. In this case the channel is
- simply another instance with an index specified by the
- <emphasis>.channel</emphasis> field.
- </listitem>
- </itemizedlist>
- Here is how we can make use of the channel's modifiers:
- <programlisting>
- static const struct iio_chan_spec light_channels[] = {
- {
- .type = IIO_INTENSITY,
- .modified = 1,
- .channel2 = IIO_MOD_LIGHT_IR,
- .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
- .info_mask_shared = BIT(IIO_CHAN_INFO_SAMP_FREQ),
- },
- {
- .type = IIO_INTENSITY,
- .modified = 1,
- .channel2 = IIO_MOD_LIGHT_BOTH,
- .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
- .info_mask_shared = BIT(IIO_CHAN_INFO_SAMP_FREQ),
- },
- {
- .type = IIO_LIGHT,
- .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
- .info_mask_shared = BIT(IIO_CHAN_INFO_SAMP_FREQ),
- },
-
- }
- </programlisting>
- This channel's definition will generate two separate sysfs files
- for raw data retrieval:
- <itemizedlist>
- <listitem>
- <filename>/sys/bus/iio/iio:deviceX/in_intensity_ir_raw</filename>
- </listitem>
- <listitem>
- <filename>/sys/bus/iio/iio:deviceX/in_intensity_both_raw</filename>
- </listitem>
- </itemizedlist>
- one file for processed data:
- <itemizedlist>
- <listitem>
- <filename>/sys/bus/iio/iio:deviceX/in_illuminance_input
- </filename>
- </listitem>
- </itemizedlist>
- and one shared sysfs file for sampling frequency:
- <itemizedlist>
- <listitem>
- <filename>/sys/bus/iio/iio:deviceX/sampling_frequency.
- </filename>
- </listitem>
- </itemizedlist>
- </para>
- <para>
- Here is how we can make use of the channel's indexing:
- <programlisting>
- static const struct iio_chan_spec light_channels[] = {
- {
- .type = IIO_VOLTAGE,
- .indexed = 1,
- .channel = 0,
- .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
- },
- {
- .type = IIO_VOLTAGE,
- .indexed = 1,
- .channel = 1,
- .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
- },
- }
- </programlisting>
- This will generate two separate attributes files for raw data
- retrieval:
- <itemizedlist>
- <listitem>
- <filename>/sys/bus/iio/devices/iio:deviceX/in_voltage0_raw</filename>,
- representing voltage measurement for channel 0.
- </listitem>
- <listitem>
- <filename>/sys/bus/iio/devices/iio:deviceX/in_voltage1_raw</filename>,
- representing voltage measurement for channel 1.
- </listitem>
- </itemizedlist>
- </para>
- </sect2>
- </sect1>
-
- <sect1 id="iiobuffer"> <title> Industrial I/O buffers </title>
-!Finclude/linux/iio/buffer.h iio_buffer
-!Edrivers/iio/industrialio-buffer.c
-
- <para>
- The Industrial I/O core offers a way for continuous data capture
- based on a trigger source. Multiple data channels can be read at once
- from <filename>/dev/iio:deviceX</filename> character device node,
- thus reducing the CPU load.
- </para>
-
- <sect2 id="iiobuffersysfs">
- <title>IIO buffer sysfs interface </title>
- <para>
- An IIO buffer has an associated attributes directory under <filename>
- /sys/bus/iio/iio:deviceX/buffer/</filename>. Here are the existing
- attributes:
- <itemizedlist>
- <listitem>
- <emphasis>length</emphasis>, the total number of data samples
- (capacity) that can be stored by the buffer.
- </listitem>
- <listitem>
- <emphasis>enable</emphasis>, activate buffer capture.
- </listitem>
- </itemizedlist>
-
- </para>
- </sect2>
- <sect2 id="iiobuffersetup"> <title> IIO buffer setup </title>
- <para>The meta information associated with a channel reading
- placed in a buffer is called a <emphasis> scan element </emphasis>.
- The important bits configuring scan elements are exposed to
- userspace applications via the <filename>
- /sys/bus/iio/iio:deviceX/scan_elements/</filename> directory. This
- file contains attributes of the following form:
- <itemizedlist>
- <listitem><emphasis>enable</emphasis>, used for enabling a channel.
- If and only if its attribute is non zero, then a triggered capture
- will contain data samples for this channel.
- </listitem>
- <listitem><emphasis>type</emphasis>, description of the scan element
- data storage within the buffer and hence the form in which it is
- read from user space. Format is <emphasis>
- [be|le]:[s|u]bits/storagebitsXrepeat[>>shift] </emphasis>.
- <itemizedlist>
- <listitem> <emphasis>be</emphasis> or <emphasis>le</emphasis>, specifies
- big or little endian.
- </listitem>
- <listitem>
- <emphasis>s </emphasis>or <emphasis>u</emphasis>, specifies if
- signed (2's complement) or unsigned.
- </listitem>
- <listitem><emphasis>bits</emphasis>, is the number of valid data
- bits.
- </listitem>
- <listitem><emphasis>storagebits</emphasis>, is the number of bits
- (after padding) that it occupies in the buffer.
- </listitem>
- <listitem>
- <emphasis>shift</emphasis>, if specified, is the shift that needs
- to be applied prior to masking out unused bits.
- </listitem>
- <listitem>
- <emphasis>repeat</emphasis>, specifies the number of bits/storagebits
- repetitions. When the repeat element is 0 or 1, then the repeat
- value is omitted.
- </listitem>
- </itemizedlist>
- </listitem>
- </itemizedlist>
- For example, a driver for a 3-axis accelerometer with 12 bit
- resolution where data is stored in two 8-bits registers as
- follows:
- <programlisting>
- 7 6 5 4 3 2 1 0
- +---+---+---+---+---+---+---+---+
- |D3 |D2 |D1 |D0 | X | X | X | X | (LOW byte, address 0x06)
- +---+---+---+---+---+---+---+---+
-
- 7 6 5 4 3 2 1 0
- +---+---+---+---+---+---+---+---+
- |D11|D10|D9 |D8 |D7 |D6 |D5 |D4 | (HIGH byte, address 0x07)
- +---+---+---+---+---+---+---+---+
- </programlisting>
-
- will have the following scan element type for each axis:
- <programlisting>
- $ cat /sys/bus/iio/devices/iio:device0/scan_elements/in_accel_y_type
- le:s12/16>>4
- </programlisting>
- A user space application will interpret data samples read from the
- buffer as two byte little endian signed data, that needs a 4 bits
- right shift before masking out the 12 valid bits of data.
- </para>
- <para>
- For implementing buffer support a driver should initialize the following
- fields in <type>iio_chan_spec</type> definition:
- <programlisting>
- struct iio_chan_spec {
- /* other members */
- int scan_index
- struct {
- char sign;
- u8 realbits;
- u8 storagebits;
- u8 shift;
- u8 repeat;
- enum iio_endian endianness;
- } scan_type;
- };
- </programlisting>
- The driver implementing the accelerometer described above will
- have the following channel definition:
- <programlisting>
- struct struct iio_chan_spec accel_channels[] = {
- {
- .type = IIO_ACCEL,
- .modified = 1,
- .channel2 = IIO_MOD_X,
- /* other stuff here */
- .scan_index = 0,
- .scan_type = {
- .sign = 's',
- .realbits = 12,
- .storagebits = 16,
- .shift = 4,
- .endianness = IIO_LE,
- },
- }
- /* similar for Y (with channel2 = IIO_MOD_Y, scan_index = 1)
- * and Z (with channel2 = IIO_MOD_Z, scan_index = 2) axis
- */
- }
- </programlisting>
- </para>
- <para>
- Here <emphasis> scan_index </emphasis> defines the order in which
- the enabled channels are placed inside the buffer. Channels with a lower
- scan_index will be placed before channels with a higher index. Each
- channel needs to have a unique scan_index.
- </para>
- <para>
- Setting scan_index to -1 can be used to indicate that the specific
- channel does not support buffered capture. In this case no entries will
- be created for the channel in the scan_elements directory.
- </para>
- </sect2>
- </sect1>
-
- <sect1 id="iiotrigger"> <title> Industrial I/O triggers </title>
-!Finclude/linux/iio/trigger.h iio_trigger
-!Edrivers/iio/industrialio-trigger.c
- <para>
- In many situations it is useful for a driver to be able to
- capture data based on some external event (trigger) as opposed
- to periodically polling for data. An IIO trigger can be provided
- by a device driver that also has an IIO device based on hardware
- generated events (e.g. data ready or threshold exceeded) or
- provided by a separate driver from an independent interrupt
- source (e.g. GPIO line connected to some external system, timer
- interrupt or user space writing a specific file in sysfs). A
- trigger may initiate data capture for a number of sensors and
- also it may be completely unrelated to the sensor itself.
- </para>
-
- <sect2 id="iiotrigsysfs"> <title> IIO trigger sysfs interface </title>
- There are two locations in sysfs related to triggers:
- <itemizedlist>
- <listitem><filename>/sys/bus/iio/devices/triggerY</filename>,
- this file is created once an IIO trigger is registered with
- the IIO core and corresponds to trigger with index Y. Because
- triggers can be very different depending on type there are few
- standard attributes that we can describe here:
- <itemizedlist>
- <listitem>
- <emphasis>name</emphasis>, trigger name that can be later
- used for association with a device.
- </listitem>
- <listitem>
- <emphasis>sampling_frequency</emphasis>, some timer based
- triggers use this attribute to specify the frequency for
- trigger calls.
- </listitem>
- </itemizedlist>
- </listitem>
- <listitem>
- <filename>/sys/bus/iio/devices/iio:deviceX/trigger/</filename>, this
- directory is created once the device supports a triggered
- buffer. We can associate a trigger with our device by writing
- the trigger's name in the <filename>current_trigger</filename> file.
- </listitem>
- </itemizedlist>
- </sect2>
-
- <sect2 id="iiotrigattr"> <title> IIO trigger setup</title>
-
- <para>
- Let's see a simple example of how to setup a trigger to be used
- by a driver.
-
- <programlisting>
- struct iio_trigger_ops trigger_ops = {
- .set_trigger_state = sample_trigger_state,
- .validate_device = sample_validate_device,
- }
-
- struct iio_trigger *trig;
-
- /* first, allocate memory for our trigger */
- trig = iio_trigger_alloc(dev, "trig-%s-%d", name, idx);
-
- /* setup trigger operations field */
- trig->ops = &amp;trigger_ops;
-
- /* now register the trigger with the IIO core */
- iio_trigger_register(trig);
- </programlisting>
- </para>
- </sect2>
-
- <sect2 id="iiotrigsetup"> <title> IIO trigger ops</title>
-!Finclude/linux/iio/trigger.h iio_trigger_ops
- <para>
- Notice that a trigger has a set of operations attached:
- <itemizedlist>
- <listitem>
- <function>set_trigger_state</function>, switch the trigger on/off
- on demand.
- </listitem>
- <listitem>
- <function>validate_device</function>, function to validate the
- device when the current trigger gets changed.
- </listitem>
- </itemizedlist>
- </para>
- </sect2>
- </sect1>
- <sect1 id="iiotriggered_buffer">
- <title> Industrial I/O triggered buffers </title>
- <para>
- Now that we know what buffers and triggers are let's see how they
- work together.
- </para>
- <sect2 id="iiotrigbufsetup"> <title> IIO triggered buffer setup</title>
-!Edrivers/iio/buffer/industrialio-triggered-buffer.c
-!Finclude/linux/iio/iio.h iio_buffer_setup_ops
-
-
- <para>
- A typical triggered buffer setup looks like this:
- <programlisting>
- const struct iio_buffer_setup_ops sensor_buffer_setup_ops = {
- .preenable = sensor_buffer_preenable,
- .postenable = sensor_buffer_postenable,
- .postdisable = sensor_buffer_postdisable,
- .predisable = sensor_buffer_predisable,
- };
-
- irqreturn_t sensor_iio_pollfunc(int irq, void *p)
- {
- pf->timestamp = iio_get_time_ns((struct indio_dev *)p);
- return IRQ_WAKE_THREAD;
- }
-
- irqreturn_t sensor_trigger_handler(int irq, void *p)
- {
- u16 buf[8];
- int i = 0;
-
- /* read data for each active channel */
- for_each_set_bit(bit, active_scan_mask, masklength)
- buf[i++] = sensor_get_data(bit)
-
- iio_push_to_buffers_with_timestamp(indio_dev, buf, timestamp);
-
- iio_trigger_notify_done(trigger);
- return IRQ_HANDLED;
- }
-
- /* setup triggered buffer, usually in probe function */
- iio_triggered_buffer_setup(indio_dev, sensor_iio_polfunc,
- sensor_trigger_handler,
- sensor_buffer_setup_ops);
- </programlisting>
- </para>
- The important things to notice here are:
- <itemizedlist>
- <listitem><function> iio_buffer_setup_ops</function>, the buffer setup
- functions to be called at predefined points in the buffer configuration
- sequence (e.g. before enable, after disable). If not specified, the
- IIO core uses the default <type>iio_triggered_buffer_setup_ops</type>.
- </listitem>
- <listitem><function>sensor_iio_pollfunc</function>, the function that
- will be used as top half of poll function. It should do as little
- processing as possible, because it runs in interrupt context. The most
- common operation is recording of the current timestamp and for this reason
- one can use the IIO core defined <function>iio_pollfunc_store_time
- </function> function.
- </listitem>
- <listitem><function>sensor_trigger_handler</function>, the function that
- will be used as bottom half of the poll function. This runs in the
- context of a kernel thread and all the processing takes place here.
- It usually reads data from the device and stores it in the internal
- buffer together with the timestamp recorded in the top half.
- </listitem>
- </itemizedlist>
- </sect2>
- </sect1>
- </chapter>
- <chapter id='iioresources'>
- <title> Resources </title>
- IIO core may change during time so the best documentation to read is the
- source code. There are several locations where you should look:
- <itemizedlist>
- <listitem>
- <filename>drivers/iio/</filename>, contains the IIO core plus
- and directories for each sensor type (e.g. accel, magnetometer,
- etc.)
- </listitem>
- <listitem>
- <filename>include/linux/iio/</filename>, contains the header
- files, nice to read for the internal kernel interfaces.
- </listitem>
- <listitem>
- <filename>include/uapi/linux/iio/</filename>, contains files to be
- used by user space applications.
- </listitem>
- <listitem>
- <filename>tools/iio/</filename>, contains tools for rapidly
- testing buffers, events and device creation.
- </listitem>
- <listitem>
- <filename>drivers/staging/iio/</filename>, contains code for some
- drivers or experimental features that are not yet mature enough
- to be moved out.
- </listitem>
- </itemizedlist>
- <para>
- Besides the code, there are some good online documentation sources:
- <itemizedlist>
- <listitem>
- <ulink url="http://marc.info/?l=linux-iio"> Industrial I/O mailing
- list </ulink>
- </listitem>
- <listitem>
- <ulink url="http://wiki.analog.com/software/linux/docs/iio/iio">
- Analog Device IIO wiki page </ulink>
- </listitem>
- <listitem>
- <ulink url="https://fosdem.org/2015/schedule/event/iiosdr/">
- Using the Linux IIO framework for SDR, Lars-Peter Clausen's
- presentation at FOSDEM </ulink>
- </listitem>
- </itemizedlist>
- </para>
- </chapter>
-</book>
-
-<!--
-vim: softtabstop=2:shiftwidth=2:expandtab:textwidth=72
--->
diff --git a/Documentation/DocBook/kgdb.tmpl b/Documentation/DocBook/kgdb.tmpl
index f3abca7ec53d..856ac20bf367 100644
--- a/Documentation/DocBook/kgdb.tmpl
+++ b/Documentation/DocBook/kgdb.tmpl
@@ -115,12 +115,12 @@
</para>
<para>
If the architecture that you are using supports the kernel option
- CONFIG_DEBUG_RODATA, you should consider turning it off. This
+ CONFIG_STRICT_KERNEL_RWX, you should consider turning it off. This
option will prevent the use of software breakpoints because it
marks certain regions of the kernel's memory space as read-only.
If kgdb supports it for the architecture you are using, you can
use hardware breakpoints if you desire to run with the
- CONFIG_DEBUG_RODATA option turned on, else you need to turn off
+ CONFIG_STRICT_KERNEL_RWX option turned on, else you need to turn off
this option.
</para>
<para>
@@ -135,7 +135,7 @@
<para>Here is an example set of .config symbols to enable or
disable for kgdb:
<itemizedlist>
- <listitem><para># CONFIG_DEBUG_RODATA is not set</para></listitem>
+ <listitem><para># CONFIG_STRICT_KERNEL_RWX is not set</para></listitem>
<listitem><para>CONFIG_FRAME_POINTER=y</para></listitem>
<listitem><para>CONFIG_KGDB=y</para></listitem>
<listitem><para>CONFIG_KGDB_SERIAL_CONSOLE=y</para></listitem>
@@ -166,7 +166,7 @@
</para>
<para>Here is an example set of .config symbols to enable/disable kdb:
<itemizedlist>
- <listitem><para># CONFIG_DEBUG_RODATA is not set</para></listitem>
+ <listitem><para># CONFIG_STRICT_KERNEL_RWX is not set</para></listitem>
<listitem><para>CONFIG_FRAME_POINTER=y</para></listitem>
<listitem><para>CONFIG_KGDB=y</para></listitem>
<listitem><para>CONFIG_KGDB_SERIAL_CONSOLE=y</para></listitem>
diff --git a/Documentation/DocBook/libata.tmpl b/Documentation/DocBook/libata.tmpl
index d7fcdc5a4379..0320910b866d 100644
--- a/Documentation/DocBook/libata.tmpl
+++ b/Documentation/DocBook/libata.tmpl
@@ -1020,7 +1020,7 @@ and other resources, etc.
</itemizedlist>
<para>
- Of errors detected as above, the followings are not ATA/ATAPI
+ Of errors detected as above, the following are not ATA/ATAPI
device errors but ATA bus errors and should be handled
according to <xref linkend="excatATAbusErr"/>.
</para>
diff --git a/Documentation/DocBook/regulator.tmpl b/Documentation/DocBook/regulator.tmpl
deleted file mode 100644
index 3b08a085d2c7..000000000000
--- a/Documentation/DocBook/regulator.tmpl
+++ /dev/null
@@ -1,304 +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="regulator-api">
- <bookinfo>
- <title>Voltage and current regulator API</title>
-
- <authorgroup>
- <author>
- <firstname>Liam</firstname>
- <surname>Girdwood</surname>
- <affiliation>
- <address>
- <email>lrg@slimlogic.co.uk</email>
- </address>
- </affiliation>
- </author>
- <author>
- <firstname>Mark</firstname>
- <surname>Brown</surname>
- <affiliation>
- <orgname>Wolfson Microelectronics</orgname>
- <address>
- <email>broonie@opensource.wolfsonmicro.com</email>
- </address>
- </affiliation>
- </author>
- </authorgroup>
-
- <copyright>
- <year>2007-2008</year>
- <holder>Wolfson Microelectronics</holder>
- </copyright>
- <copyright>
- <year>2008</year>
- <holder>Liam Girdwood</holder>
- </copyright>
-
- <legalnotice>
- <para>
- 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.
- </para>
-
- <para>
- 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.
- </para>
-
- <para>
- 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
- </para>
-
- <para>
- For more details see the file COPYING in the source
- distribution of Linux.
- </para>
- </legalnotice>
- </bookinfo>
-
-<toc></toc>
-
- <chapter id="intro">
- <title>Introduction</title>
- <para>
- This framework is designed to provide a standard kernel
- interface to control voltage and current regulators.
- </para>
- <para>
- The intention is to allow systems to dynamically control
- regulator power output in order to save power and prolong
- battery life. This applies to both voltage regulators (where
- voltage output is controllable) and current sinks (where current
- limit is controllable).
- </para>
- <para>
- Note that additional (and currently more complete) documentation
- is available in the Linux kernel source under
- <filename>Documentation/power/regulator</filename>.
- </para>
-
- <sect1 id="glossary">
- <title>Glossary</title>
- <para>
- The regulator API uses a number of terms which may not be
- familiar:
- </para>
- <glossary>
-
- <glossentry>
- <glossterm>Regulator</glossterm>
- <glossdef>
- <para>
- Electronic device that supplies power to other devices. Most
- regulators can enable and disable their output and some can also
- control their output voltage or current.
- </para>
- </glossdef>
- </glossentry>
-
- <glossentry>
- <glossterm>Consumer</glossterm>
- <glossdef>
- <para>
- Electronic device which consumes power provided by a regulator.
- These may either be static, requiring only a fixed supply, or
- dynamic, requiring active management of the regulator at
- runtime.
- </para>
- </glossdef>
- </glossentry>
-
- <glossentry>
- <glossterm>Power Domain</glossterm>
- <glossdef>
- <para>
- The electronic circuit supplied by a given regulator, including
- the regulator and all consumer devices. The configuration of
- the regulator is shared between all the components in the
- circuit.
- </para>
- </glossdef>
- </glossentry>
-
- <glossentry>
- <glossterm>Power Management Integrated Circuit</glossterm>
- <acronym>PMIC</acronym>
- <glossdef>
- <para>
- An IC which contains numerous regulators and often also other
- subsystems. In an embedded system the primary PMIC is often
- equivalent to a combination of the PSU and southbridge in a
- desktop system.
- </para>
- </glossdef>
- </glossentry>
- </glossary>
- </sect1>
- </chapter>
-
- <chapter id="consumer">
- <title>Consumer driver interface</title>
- <para>
- This offers a similar API to the kernel clock framework.
- Consumer drivers use <link
- linkend='API-regulator-get'>get</link> and <link
- linkend='API-regulator-put'>put</link> operations to acquire and
- release regulators. Functions are
- provided to <link linkend='API-regulator-enable'>enable</link>
- and <link linkend='API-regulator-disable'>disable</link> the
- regulator and to get and set the runtime parameters of the
- regulator.
- </para>
- <para>
- When requesting regulators consumers use symbolic names for their
- supplies, such as "Vcc", which are mapped into actual regulator
- devices by the machine interface.
- </para>
- <para>
- A stub version of this API is provided when the regulator
- framework is not in use in order to minimise the need to use
- ifdefs.
- </para>
-
- <sect1 id="consumer-enable">
- <title>Enabling and disabling</title>
- <para>
- The regulator API provides reference counted enabling and
- disabling of regulators. Consumer devices use the <function><link
- linkend='API-regulator-enable'>regulator_enable</link></function>
- and <function><link
- linkend='API-regulator-disable'>regulator_disable</link>
- </function> functions to enable and disable regulators. Calls
- to the two functions must be balanced.
- </para>
- <para>
- Note that since multiple consumers may be using a regulator and
- machine constraints may not allow the regulator to be disabled
- there is no guarantee that calling
- <function>regulator_disable</function> will actually cause the
- supply provided by the regulator to be disabled. Consumer
- drivers should assume that the regulator may be enabled at all
- times.
- </para>
- </sect1>
-
- <sect1 id="consumer-config">
- <title>Configuration</title>
- <para>
- Some consumer devices may need to be able to dynamically
- configure their supplies. For example, MMC drivers may need to
- select the correct operating voltage for their cards. This may
- be done while the regulator is enabled or disabled.
- </para>
- <para>
- The <function><link
- linkend='API-regulator-set-voltage'>regulator_set_voltage</link>
- </function> and <function><link
- linkend='API-regulator-set-current-limit'
- >regulator_set_current_limit</link>
- </function> functions provide the primary interface for this.
- Both take ranges of voltages and currents, supporting drivers
- that do not require a specific value (eg, CPU frequency scaling
- normally permits the CPU to use a wider range of supply
- voltages at lower frequencies but does not require that the
- supply voltage be lowered). Where an exact value is required
- both minimum and maximum values should be identical.
- </para>
- </sect1>
-
- <sect1 id="consumer-callback">
- <title>Callbacks</title>
- <para>
- Callbacks may also be <link
- linkend='API-regulator-register-notifier'>registered</link>
- for events such as regulation failures.
- </para>
- </sect1>
- </chapter>
-
- <chapter id="driver">
- <title>Regulator driver interface</title>
- <para>
- Drivers for regulator chips <link
- linkend='API-regulator-register'>register</link> the regulators
- with the regulator core, providing operations structures to the
- core. A <link
- linkend='API-regulator-notifier-call-chain'>notifier</link> interface
- allows error conditions to be reported to the core.
- </para>
- <para>
- Registration should be triggered by explicit setup done by the
- platform, supplying a <link
- linkend='API-struct-regulator-init-data'>struct
- regulator_init_data</link> for the regulator containing
- <link linkend='machine-constraint'>constraint</link> and
- <link linkend='machine-supply'>supply</link> information.
- </para>
- </chapter>
-
- <chapter id="machine">
- <title>Machine interface</title>
- <para>
- This interface provides a way to define how regulators are
- connected to consumers on a given system and what the valid
- operating parameters are for the system.
- </para>
-
- <sect1 id="machine-supply">
- <title>Supplies</title>
- <para>
- Regulator supplies are specified using <link
- linkend='API-struct-regulator-consumer-supply'>struct
- regulator_consumer_supply</link>. This is done at
- <link linkend='driver'>driver registration
- time</link> as part of the machine constraints.
- </para>
- </sect1>
-
- <sect1 id="machine-constraint">
- <title>Constraints</title>
- <para>
- As well as defining the connections the machine interface
- also provides constraints defining the operations that
- clients are allowed to perform and the parameters that may be
- set. This is required since generally regulator devices will
- offer more flexibility than it is safe to use on a given
- system, for example supporting higher supply voltages than the
- consumers are rated for.
- </para>
- <para>
- This is done at <link linkend='driver'>driver
- registration time</link> by providing a <link
- linkend='API-struct-regulation-constraints'>struct
- regulation_constraints</link>.
- </para>
- <para>
- The constraints may also specify an initial configuration for the
- regulator in the constraints, which is particularly useful for
- use with static consumers.
- </para>
- </sect1>
- </chapter>
-
- <chapter id="api">
- <title>API reference</title>
- <para>
- Due to limitations of the kernel documentation framework and the
- existing layout of the source code the entire regulator API is
- documented here.
- </para>
-!Iinclude/linux/regulator/consumer.h
-!Iinclude/linux/regulator/machine.h
-!Iinclude/linux/regulator/driver.h
-!Edrivers/regulator/core.c
- </chapter>
-</book>
diff --git a/Documentation/DocBook/uio-howto.tmpl b/Documentation/DocBook/uio-howto.tmpl
deleted file mode 100644
index 5210f8a577c6..000000000000
--- a/Documentation/DocBook/uio-howto.tmpl
+++ /dev/null
@@ -1,1112 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
-"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" []>
-
-<book id="index">
-<bookinfo>
-<title>The Userspace I/O HOWTO</title>
-
-<author>
- <firstname>Hans-Jürgen</firstname>
- <surname>Koch</surname>
- <authorblurb><para>Linux developer, Linutronix</para></authorblurb>
- <affiliation>
- <orgname>
- <ulink url="http://www.linutronix.de">Linutronix</ulink>
- </orgname>
-
- <address>
- <email>hjk@hansjkoch.de</email>
- </address>
- </affiliation>
-</author>
-
-<copyright>
- <year>2006-2008</year>
- <holder>Hans-Jürgen Koch.</holder>
-</copyright>
-<copyright>
- <year>2009</year>
- <holder>Red Hat Inc, Michael S. Tsirkin (mst@redhat.com)</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>
- <para>This HOWTO describes concept and usage of Linux kernel's
- Userspace I/O system.</para>
-</abstract>
-
-<revhistory>
- <revision>
- <revnumber>0.10</revnumber>
- <date>2016-10-17</date>
- <authorinitials>sch</authorinitials>
- <revremark>Added generic hyperv driver
- </revremark>
- </revision>
- <revision>
- <revnumber>0.9</revnumber>
- <date>2009-07-16</date>
- <authorinitials>mst</authorinitials>
- <revremark>Added generic pci driver
- </revremark>
- </revision>
- <revision>
- <revnumber>0.8</revnumber>
- <date>2008-12-24</date>
- <authorinitials>hjk</authorinitials>
- <revremark>Added name attributes in mem and portio sysfs directories.
- </revremark>
- </revision>
- <revision>
- <revnumber>0.7</revnumber>
- <date>2008-12-23</date>
- <authorinitials>hjk</authorinitials>
- <revremark>Added generic platform drivers and offset attribute.</revremark>
- </revision>
- <revision>
- <revnumber>0.6</revnumber>
- <date>2008-12-05</date>
- <authorinitials>hjk</authorinitials>
- <revremark>Added description of portio sysfs attributes.</revremark>
- </revision>
- <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>
- <authorinitials>hjk</authorinitials>
- <revremark>Added section about userspace drivers.</revremark>
- </revision>
- <revision>
- <revnumber>0.2</revnumber>
- <date>2007-02-13</date>
- <authorinitials>hjk</authorinitials>
- <revremark>Update after multiple mappings were added.</revremark>
- </revision>
- <revision>
- <revnumber>0.1</revnumber>
- <date>2006-12-11</date>
- <authorinitials>hjk</authorinitials>
- <revremark>First draft.</revremark>
- </revision>
-</revhistory>
-</bookinfo>
-
-<chapter id="aboutthisdoc">
-<?dbhtml filename="aboutthis.html"?>
-<title>About this document</title>
-
-<sect1 id="translations">
-<?dbhtml filename="translations.html"?>
-<title>Translations</title>
-
-<para>If you know of any translations for this document, or you are
-interested in translating it, please email me
-<email>hjk@hansjkoch.de</email>.
-</para>
-</sect1>
-
-<sect1 id="preface">
-<title>Preface</title>
- <para>
- For many types of devices, creating a Linux kernel driver is
- overkill. All that is really needed is some way to handle an
- interrupt and provide access to the memory space of the
- device. The logic of controlling the device does not
- necessarily have to be within the kernel, as the device does
- not need to take advantage of any of other resources that the
- kernel provides. One such common class of devices that are
- like this are for industrial I/O cards.
- </para>
- <para>
- To address this situation, the userspace I/O system (UIO) was
- designed. For typical industrial I/O cards, only a very small
- kernel module is needed. The main part of the driver will run in
- 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">
-<title>Acknowledgments</title>
- <para>I'd like to thank Thomas Gleixner and Benedikt Spranger of
- Linutronix, who have not only written most of the UIO code, but also
- helped greatly writing this HOWTO by giving me all kinds of background
- information.</para>
-</sect1>
-
-<sect1 id="feedback">
-<title>Feedback</title>
- <para>Find something wrong with this document? (Or perhaps something
- right?) I would love to hear from you. Please email me at
- <email>hjk@hansjkoch.de</email>.</para>
-</sect1>
-</chapter>
-
-<chapter id="about">
-<?dbhtml filename="about.html"?>
-<title>About UIO</title>
-
-<para>If you use UIO for your card's driver, here's what you get:</para>
-
-<itemizedlist>
-<listitem>
- <para>only one small kernel module to write and maintain.</para>
-</listitem>
-<listitem>
- <para>develop the main part of your driver in user space,
- with all the tools and libraries you're used to.</para>
-</listitem>
-<listitem>
- <para>bugs in your driver won't crash the kernel.</para>
-</listitem>
-<listitem>
- <para>updates of your driver can take place without recompiling
- the kernel.</para>
-</listitem>
-</itemizedlist>
-
-<sect1 id="how_uio_works">
-<title>How UIO works</title>
- <para>
- Each UIO device is accessed through a device file and several
- sysfs attribute files. The device file will be called
- <filename>/dev/uio0</filename> for the first device, and
- <filename>/dev/uio1</filename>, <filename>/dev/uio2</filename>
- and so on for subsequent devices.
- </para>
-
- <para><filename>/dev/uioX</filename> is used to access the
- address space of the card. Just use
- <function>mmap()</function> to access registers or RAM
- locations of your card.
- </para>
-
- <para>
- Interrupts are handled by reading from
- <filename>/dev/uioX</filename>. A blocking
- <function>read()</function> from
- <filename>/dev/uioX</filename> will return as soon as an
- interrupt occurs. You can also use
- <function>select()</function> on
- <filename>/dev/uioX</filename> to wait for an interrupt. The
- integer value read from <filename>/dev/uioX</filename>
- 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
- provide its own interrupt handler. It will automatically be
- called by the built-in handler.
- </para>
-
- <para>
- 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.
- This interrupt simulation is done by calling
- <function>uio_event_notify()</function>
- from the timer's event handler.
- </para>
-
- <para>
- Each driver provides attributes that are used to read or write
- variables. These attributes are accessible through sysfs
- files. A custom kernel driver module can add its own
- attributes to the device owned by the uio driver, but not added
- to the UIO device itself at this time. This might change in the
- future if it would be found to be useful.
- </para>
-
- <para>
- The following standard attributes are provided by the UIO
- framework:
- </para>
-<itemizedlist>
-<listitem>
- <para>
- <filename>name</filename>: The name of your device. It is
- recommended to use the name of your kernel module for this.
- </para>
-</listitem>
-<listitem>
- <para>
- <filename>version</filename>: A version string defined by your
- driver. This allows the user space part of your driver to deal
- with different versions of the kernel module.
- </para>
-</listitem>
-<listitem>
- <para>
- <filename>event</filename>: The total number of interrupts
- handled by the driver since the last time the device node was
- read.
- </para>
-</listitem>
-</itemizedlist>
-<para>
- These attributes appear under the
- <filename>/sys/class/uio/uioX</filename> directory. Please
- note that this directory might be a symlink, and not a real
- directory. Any userspace code that accesses it must be able
- to handle this.
-</para>
-<para>
- Each UIO device can make one or more memory regions available for
- memory mapping. This is necessary because some industrial I/O cards
- require access to more than one PCI memory region in a driver.
-</para>
-<para>
- Each mapping has its own directory in sysfs, the first mapping
- appears as <filename>/sys/class/uio/uioX/maps/map0/</filename>.
- Subsequent mappings create directories <filename>map1/</filename>,
- <filename>map2/</filename>, and so on. These directories will only
- appear if the size of the mapping is not 0.
-</para>
-<para>
- Each <filename>mapX/</filename> directory contains four read-only files
- that show attributes of the memory:
-</para>
-<itemizedlist>
-<listitem>
- <para>
- <filename>name</filename>: A string identifier for this mapping. This
- is optional, the string can be empty. Drivers can set this to make it
- easier for userspace to find the correct mapping.
- </para>
-</listitem>
-<listitem>
- <para>
- <filename>addr</filename>: The address of memory that can be mapped.
- </para>
-</listitem>
-<listitem>
- <para>
- <filename>size</filename>: The size, in bytes, of the memory
- pointed to by addr.
- </para>
-</listitem>
-<listitem>
- <para>
- <filename>offset</filename>: The offset, in bytes, that has to be
- added to the pointer returned by <function>mmap()</function> to get
- to the actual device memory. This is important if the device's memory
- is not page aligned. Remember that pointers returned by
- <function>mmap()</function> are always page aligned, so it is good
- style to always add this offset.
- </para>
-</listitem>
-</itemizedlist>
-
-<para>
- From userspace, the different mappings are distinguished by adjusting
- the <varname>offset</varname> parameter of the
- <function>mmap()</function> call. To map the memory of mapping N, you
- have to use N times the page size as your offset:
-</para>
-<programlisting format="linespecific">
-offset = N * getpagesize();
-</programlisting>
-
-<para>
- Sometimes there is hardware with memory-like regions that can not be
- mapped with the technique described here, but there are still ways to
- access them from userspace. The most common example are x86 ioports.
- On x86 systems, userspace can access these ioports using
- <function>ioperm()</function>, <function>iopl()</function>,
- <function>inb()</function>, <function>outb()</function>, and similar
- functions.
-</para>
-<para>
- Since these ioport regions can not be mapped, they will not appear under
- <filename>/sys/class/uio/uioX/maps/</filename> like the normal memory
- described above. Without information about the port regions a hardware
- has to offer, it becomes difficult for the userspace part of the
- driver to find out which ports belong to which UIO device.
-</para>
-<para>
- To address this situation, the new directory
- <filename>/sys/class/uio/uioX/portio/</filename> was added. It only
- exists if the driver wants to pass information about one or more port
- regions to userspace. If that is the case, subdirectories named
- <filename>port0</filename>, <filename>port1</filename>, and so on,
- will appear underneath
- <filename>/sys/class/uio/uioX/portio/</filename>.
-</para>
-<para>
- Each <filename>portX/</filename> directory contains four read-only
- files that show name, start, size, and type of the port region:
-</para>
-<itemizedlist>
-<listitem>
- <para>
- <filename>name</filename>: A string identifier for this port region.
- The string is optional and can be empty. Drivers can set it to make it
- easier for userspace to find a certain port region.
- </para>
-</listitem>
-<listitem>
- <para>
- <filename>start</filename>: The first port of this region.
- </para>
-</listitem>
-<listitem>
- <para>
- <filename>size</filename>: The number of ports in this region.
- </para>
-</listitem>
-<listitem>
- <para>
- <filename>porttype</filename>: A string describing the type of port.
- </para>
-</listitem>
-</itemizedlist>
-
-
-</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>
- Please have a look at <filename>uio_cif.c</filename> as an
- example. The following paragraphs explain the different
- sections of this file.
- </para>
-
-<sect1 id="uio_info">
-<title>struct uio_info</title>
- <para>
- This structure tells the framework the details of your driver,
- Some of the members are required, others are optional.
- </para>
-
-<itemizedlist>
-<listitem><para>
-<varname>const char *name</varname>: Required. The name of your driver as
-it will appear in sysfs. I recommend using the name of your module for this.
-</para></listitem>
-
-<listitem><para>
-<varname>const char *version</varname>: Required. This string appears in
-<filename>/sys/class/uio/uioX/version</filename>.
-</para></listitem>
-
-<listitem><para>
-<varname>struct uio_mem mem[ MAX_UIO_MAPS ]</varname>: Required if you
-have memory that can be mapped with <function>mmap()</function>. For each
-mapping you need to fill one of the <varname>uio_mem</varname> structures.
-See the description below for details.
-</para></listitem>
-
-<listitem><para>
-<varname>struct uio_port port[ MAX_UIO_PORTS_REGIONS ]</varname>: Required
-if you want to pass information about ioports to userspace. For each port
-region you need to fill one of the <varname>uio_port</varname> structures.
-See the description below for details.
-</para></listitem>
-
-<listitem><para>
-<varname>long irq</varname>: Required. If your hardware generates an
-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>.
-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>
-
-<listitem><para>
-<varname>unsigned long irq_flags</varname>: Required if you've set
-<varname>irq</varname> to a hardware interrupt number. The flags given
-here will be used in the call to <function>request_irq()</function>.
-</para></listitem>
-
-<listitem><para>
-<varname>int (*mmap)(struct uio_info *info, struct vm_area_struct
-*vma)</varname>: Optional. If you need a special
-<function>mmap()</function> function, you can set it here. If this
-pointer is not NULL, your <function>mmap()</function> will be called
-instead of the built-in one.
-</para></listitem>
-
-<listitem><para>
-<varname>int (*open)(struct uio_info *info, struct inode *inode)
-</varname>: Optional. You might want to have your own
-<function>open()</function>, e.g. to enable interrupts only when your
-device is actually used.
-</para></listitem>
-
-<listitem><para>
-<varname>int (*release)(struct uio_info *info, struct inode *inode)
-</varname>: Optional. If you define your own
-<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>
-Usually, your device will have one or more memory regions that can be mapped
-to user space. For each region, you have to set up a
-<varname>struct uio_mem</varname> in the <varname>mem[]</varname> array.
-Here's a description of the fields of <varname>struct uio_mem</varname>:
-</para>
-
-<itemizedlist>
-<listitem><para>
-<varname>const char *name</varname>: Optional. Set this to help identify
-the memory region, it will show up in the corresponding sysfs node.
-</para></listitem>
-
-<listitem><para>
-<varname>int memtype</varname>: Required if the mapping is used. Set this to
-<varname>UIO_MEM_PHYS</varname> if you you have physical memory on your
-card to be mapped. Use <varname>UIO_MEM_LOGICAL</varname> for logical
-memory (e.g. allocated with <function>kmalloc()</function>). There's also
-<varname>UIO_MEM_VIRTUAL</varname> for virtual memory.
-</para></listitem>
-
-<listitem><para>
-<varname>phys_addr_t addr</varname>: Required if the mapping is used.
-Fill in the address of your memory block. This address is the one that
-appears in sysfs.
-</para></listitem>
-
-<listitem><para>
-<varname>resource_size_t size</varname>: Fill in the size of the
-memory block that <varname>addr</varname> points to. If <varname>size</varname>
-is zero, the mapping is considered unused. Note that you
-<emphasis>must</emphasis> initialize <varname>size</varname> with zero for
-all unused mappings.
-</para></listitem>
-
-<listitem><para>
-<varname>void *internal_addr</varname>: If you have to access this memory
-region from within your kernel module, you will want to map it internally by
-using something like <function>ioremap()</function>. Addresses
-returned by this function cannot be mapped to user space, so you must not
-store it in <varname>addr</varname>. Use <varname>internal_addr</varname>
-instead to remember such an address.
-</para></listitem>
-</itemizedlist>
-
-<para>
-Please do not touch the <varname>map</varname> element of
-<varname>struct uio_mem</varname>! It is used by the UIO framework
-to set up sysfs files for this mapping. Simply leave it alone.
-</para>
-
-<para>
-Sometimes, your device can have one or more port regions which can not be
-mapped to userspace. But if there are other possibilities for userspace to
-access these ports, it makes sense to make information about the ports
-available in sysfs. For each region, you have to set up a
-<varname>struct uio_port</varname> in the <varname>port[]</varname> array.
-Here's a description of the fields of <varname>struct uio_port</varname>:
-</para>
-
-<itemizedlist>
-<listitem><para>
-<varname>char *porttype</varname>: Required. Set this to one of the predefined
-constants. Use <varname>UIO_PORT_X86</varname> for the ioports found in x86
-architectures.
-</para></listitem>
-
-<listitem><para>
-<varname>unsigned long start</varname>: Required if the port region is used.
-Fill in the number of the first port of this region.
-</para></listitem>
-
-<listitem><para>
-<varname>unsigned long size</varname>: Fill in the number of ports in this
-region. If <varname>size</varname> is zero, the region is considered unused.
-Note that you <emphasis>must</emphasis> initialize <varname>size</varname>
-with zero for all unused regions.
-</para></listitem>
-</itemizedlist>
-
-<para>
-Please do not touch the <varname>portio</varname> element of
-<varname>struct uio_port</varname>! It is used internally by the UIO
-framework to set up sysfs files for this region. Simply leave it alone.
-</para>
-
-</sect1>
-
-<sect1 id="adding_irq_handler">
-<title>Adding an interrupt handler</title>
- <para>
- What you need to do in your interrupt handler depends on your
- hardware and on how you want to handle it. You should try to
- keep the amount of code in your kernel interrupt handler low.
- If your hardware requires no action that you
- <emphasis>have</emphasis> to perform after each interrupt,
- then your handler can be empty.</para> <para>If, on the other
- hand, your hardware <emphasis>needs</emphasis> some action to
- be performed after each interrupt, then you
- <emphasis>must</emphasis> do it in your kernel module. Note
- that you cannot rely on the userspace part of your driver. Your
- userspace program can terminate at any time, possibly leaving
- your hardware in a state where proper interrupt handling is
- still required.
- </para>
-
- <para>
- There might also be applications where you want to read data
- from your hardware at each interrupt and buffer it in a piece
- of kernel memory you've allocated for that purpose. With this
- technique you could avoid loss of data if your userspace
- program misses an interrupt.
- </para>
-
- <para>
- A note on shared interrupts: Your driver should support
- interrupt sharing whenever this is possible. It is possible if
- and only if your driver can detect whether your hardware has
- triggered the interrupt or not. This is usually done by looking
- at an interrupt status register. If your driver sees that the
- IRQ bit is actually set, it will perform its actions, and the
- handler returns IRQ_HANDLED. If the driver detects that it was
- not your hardware that caused the interrupt, it will do nothing
- and return IRQ_NONE, allowing the kernel to call the next
- possible interrupt handler.
- </para>
-
- <para>
- If you decide not to support shared interrupts, your card
- won't work in computers with no free interrupts. As this
- frequently happens on the PC platform, you can save yourself a
- lot of trouble by supporting interrupt sharing.
- </para>
-</sect1>
-
-<sect1 id="using_uio_pdrv">
-<title>Using uio_pdrv for platform devices</title>
- <para>
- In many cases, UIO drivers for platform devices can be handled in a
- generic way. In the same place where you define your
- <varname>struct platform_device</varname>, you simply also implement
- your interrupt handler and fill your
- <varname>struct uio_info</varname>. A pointer to this
- <varname>struct uio_info</varname> is then used as
- <varname>platform_data</varname> for your platform device.
- </para>
- <para>
- You also need to set up an array of <varname>struct resource</varname>
- containing addresses and sizes of your memory mappings. This
- information is passed to the driver using the
- <varname>.resource</varname> and <varname>.num_resources</varname>
- elements of <varname>struct platform_device</varname>.
- </para>
- <para>
- You now have to set the <varname>.name</varname> element of
- <varname>struct platform_device</varname> to
- <varname>"uio_pdrv"</varname> to use the generic UIO platform device
- driver. This driver will fill the <varname>mem[]</varname> array
- according to the resources given, and register the device.
- </para>
- <para>
- The advantage of this approach is that you only have to edit a file
- you need to edit anyway. You do not have to create an extra driver.
- </para>
-</sect1>
-
-<sect1 id="using_uio_pdrv_genirq">
-<title>Using uio_pdrv_genirq for platform devices</title>
- <para>
- Especially in embedded devices, you frequently find chips where the
- irq pin is tied to its own dedicated interrupt line. In such cases,
- where you can be really sure the interrupt is not shared, we can take
- the concept of <varname>uio_pdrv</varname> one step further and use a
- generic interrupt handler. That's what
- <varname>uio_pdrv_genirq</varname> does.
- </para>
- <para>
- The setup for this driver is the same as described above for
- <varname>uio_pdrv</varname>, except that you do not implement an
- interrupt handler. The <varname>.handler</varname> element of
- <varname>struct uio_info</varname> must remain
- <varname>NULL</varname>. The <varname>.irq_flags</varname> element
- must not contain <varname>IRQF_SHARED</varname>.
- </para>
- <para>
- You will set the <varname>.name</varname> element of
- <varname>struct platform_device</varname> to
- <varname>"uio_pdrv_genirq"</varname> to use this driver.
- </para>
- <para>
- The generic interrupt handler of <varname>uio_pdrv_genirq</varname>
- will simply disable the interrupt line using
- <function>disable_irq_nosync()</function>. After doing its work,
- userspace can reenable the interrupt by writing 0x00000001 to the UIO
- device file. The driver already implements an
- <function>irq_control()</function> to make this possible, you must not
- implement your own.
- </para>
- <para>
- Using <varname>uio_pdrv_genirq</varname> not only saves a few lines of
- interrupt handler code. You also do not need to know anything about
- the chip's internal registers to create the kernel part of the driver.
- All you need to know is the irq number of the pin the chip is
- connected to.
- </para>
-</sect1>
-
-<sect1 id="using-uio_dmem_genirq">
-<title>Using uio_dmem_genirq for platform devices</title>
- <para>
- In addition to statically allocated memory ranges, they may also be
- a desire to use dynamically allocated regions in a user space driver.
- In particular, being able to access memory made available through the
- dma-mapping API, may be particularly useful. The
- <varname>uio_dmem_genirq</varname> driver provides a way to accomplish
- this.
- </para>
- <para>
- This driver is used in a similar manner to the
- <varname>"uio_pdrv_genirq"</varname> driver with respect to interrupt
- configuration and handling.
- </para>
- <para>
- Set the <varname>.name</varname> element of
- <varname>struct platform_device</varname> to
- <varname>"uio_dmem_genirq"</varname> to use this driver.
- </para>
- <para>
- When using this driver, fill in the <varname>.platform_data</varname>
- element of <varname>struct platform_device</varname>, which is of type
- <varname>struct uio_dmem_genirq_pdata</varname> and which contains the
- following elements:
- </para>
- <itemizedlist>
- <listitem><para><varname>struct uio_info uioinfo</varname>: The same
- structure used as the <varname>uio_pdrv_genirq</varname> platform
- data</para></listitem>
- <listitem><para><varname>unsigned int *dynamic_region_sizes</varname>:
- Pointer to list of sizes of dynamic memory regions to be mapped into
- user space.
- </para></listitem>
- <listitem><para><varname>unsigned int num_dynamic_regions</varname>:
- Number of elements in <varname>dynamic_region_sizes</varname> array.
- </para></listitem>
- </itemizedlist>
- <para>
- The dynamic regions defined in the platform data will be appended to
- the <varname> mem[] </varname> array after the platform device
- resources, which implies that the total number of static and dynamic
- memory regions cannot exceed <varname>MAX_UIO_MAPS</varname>.
- </para>
- <para>
- The dynamic memory regions will be allocated when the UIO device file,
- <varname>/dev/uioX</varname> is opened.
- Similar to static memory resources, the memory region information for
- dynamic regions is then visible via sysfs at
- <varname>/sys/class/uio/uioX/maps/mapY/*</varname>.
- The dynamic memory regions will be freed when the UIO device file is
- closed. When no processes are holding the device file open, the address
- returned to userspace is ~0.
- </para>
-</sect1>
-
-</chapter>
-
-<chapter id="userspace_driver" xreflabel="Writing a driver in user space">
-<?dbhtml filename="userspace_driver.html"?>
-<title>Writing a driver in userspace</title>
- <para>
- Once you have a working kernel module for your hardware, you can
- write the userspace part of your driver. You don't need any special
- libraries, your driver can be written in any reasonable language,
- you can use floating point numbers and so on. In short, you can
- use all the tools and libraries you'd normally use for writing a
- userspace application.
- </para>
-
-<sect1 id="getting_uio_information">
-<title>Getting information about your UIO device</title>
- <para>
- Information about all UIO devices is available in sysfs. The
- first thing you should do in your driver is check
- <varname>name</varname> and <varname>version</varname> to
- make sure your talking to the right device and that its kernel
- driver has the version you expect.
- </para>
- <para>
- You should also make sure that the memory mapping you need
- exists and has the size you expect.
- </para>
- <para>
- There is a tool called <varname>lsuio</varname> that lists
- UIO devices and their attributes. It is available here:
- </para>
- <para>
- <ulink url="http://www.osadl.org/projects/downloads/UIO/user/">
- http://www.osadl.org/projects/downloads/UIO/user/</ulink>
- </para>
- <para>
- With <varname>lsuio</varname> you can quickly check if your
- kernel module is loaded and which attributes it exports.
- Have a look at the manpage for details.
- </para>
- <para>
- The source code of <varname>lsuio</varname> can serve as an
- example for getting information about an UIO device.
- The file <filename>uio_helper.c</filename> contains a lot of
- functions you could use in your userspace driver code.
- </para>
-</sect1>
-
-<sect1 id="mmap_device_memory">
-<title>mmap() device memory</title>
- <para>
- After you made sure you've got the right device with the
- memory mappings you need, all you have to do is to call
- <function>mmap()</function> to map the device's memory
- to userspace.
- </para>
- <para>
- The parameter <varname>offset</varname> of the
- <function>mmap()</function> call has a special meaning
- for UIO devices: It is used to select which mapping of
- your device you want to map. To map the memory of
- mapping N, you have to use N times the page size as
- your offset:
- </para>
-<programlisting format="linespecific">
- offset = N * getpagesize();
-</programlisting>
- <para>
- N starts from zero, so if you've got only one memory
- range to map, set <varname>offset = 0</varname>.
- A drawback of this technique is that memory is always
- mapped beginning with its start address.
- </para>
-</sect1>
-
-<sect1 id="wait_for_interrupts">
-<title>Waiting for interrupts</title>
- <para>
- After you successfully mapped your devices memory, you
- can access it like an ordinary array. Usually, you will
- perform some initialization. After that, your hardware
- starts working and will generate an interrupt as soon
- as it's finished, has some data available, or needs your
- attention because an error occurred.
- </para>
- <para>
- <filename>/dev/uioX</filename> is a read-only file. A
- <function>read()</function> will always block until an
- interrupt occurs. There is only one legal value for the
- <varname>count</varname> parameter of
- <function>read()</function>, and that is the size of a
- signed 32 bit integer (4). Any other value for
- <varname>count</varname> causes <function>read()</function>
- to fail. The signed 32 bit integer read is the interrupt
- count of your device. If the value is one more than the value
- you read the last time, everything is OK. If the difference
- is greater than one, you missed interrupts.
- </para>
- <para>
- You can also use <function>select()</function> on
- <filename>/dev/uioX</filename>.
- </para>
-</sect1>
-
-</chapter>
-
-<chapter id="uio_pci_generic" xreflabel="Using Generic driver for PCI cards">
-<?dbhtml filename="uio_pci_generic.html"?>
-<title>Generic PCI UIO driver</title>
- <para>
- The generic driver is a kernel module named uio_pci_generic.
- It can work with any device compliant to PCI 2.3 (circa 2002) and
- any compliant PCI Express device. Using this, you only need to
- write the userspace driver, removing the need to write
- a hardware-specific kernel module.
- </para>
-
-<sect1 id="uio_pci_generic_binding">
-<title>Making the driver recognize the device</title>
- <para>
-Since the driver does not declare any device ids, it will not get loaded
-automatically and will not automatically bind to any devices, you must load it
-and allocate id to the driver yourself. For example:
- <programlisting>
- modprobe uio_pci_generic
- echo &quot;8086 10f5&quot; &gt; /sys/bus/pci/drivers/uio_pci_generic/new_id
- </programlisting>
- </para>
- <para>
-If there already is a hardware specific kernel driver for your device, the
-generic driver still won't bind to it, in this case if you want to use the
-generic driver (why would you?) you'll have to manually unbind the hardware
-specific driver and bind the generic driver, like this:
- <programlisting>
- echo -n 0000:00:19.0 &gt; /sys/bus/pci/drivers/e1000e/unbind
- echo -n 0000:00:19.0 &gt; /sys/bus/pci/drivers/uio_pci_generic/bind
- </programlisting>
- </para>
- <para>
-You can verify that the device has been bound to the driver
-by looking for it in sysfs, for example like the following:
- <programlisting>
- ls -l /sys/bus/pci/devices/0000:00:19.0/driver
- </programlisting>
-Which if successful should print
- <programlisting>
- .../0000:00:19.0/driver -&gt; ../../../bus/pci/drivers/uio_pci_generic
- </programlisting>
-Note that the generic driver will not bind to old PCI 2.2 devices.
-If binding the device failed, run the following command:
- <programlisting>
- dmesg
- </programlisting>
-and look in the output for failure reasons
- </para>
-</sect1>
-
-<sect1 id="uio_pci_generic_internals">
-<title>Things to know about uio_pci_generic</title>
- <para>
-Interrupts are handled using the Interrupt Disable bit in the PCI command
-register and Interrupt Status bit in the PCI status register. All devices
-compliant to PCI 2.3 (circa 2002) and all compliant PCI Express devices should
-support these bits. uio_pci_generic detects this support, and won't bind to
-devices which do not support the Interrupt Disable Bit in the command register.
- </para>
- <para>
-On each interrupt, uio_pci_generic sets the Interrupt Disable bit.
-This prevents the device from generating further interrupts
-until the bit is cleared. The userspace driver should clear this
-bit before blocking and waiting for more interrupts.
- </para>
-</sect1>
-<sect1 id="uio_pci_generic_userspace">
-<title>Writing userspace driver using uio_pci_generic</title>
- <para>
-Userspace driver can use pci sysfs interface, or the
-libpci libray that wraps it, to talk to the device and to
-re-enable interrupts by writing to the command register.
- </para>
-</sect1>
-<sect1 id="uio_pci_generic_example">
-<title>Example code using uio_pci_generic</title>
- <para>
-Here is some sample userspace driver code using uio_pci_generic:
-<programlisting>
-#include &lt;stdlib.h&gt;
-#include &lt;stdio.h&gt;
-#include &lt;unistd.h&gt;
-#include &lt;sys/types.h&gt;
-#include &lt;sys/stat.h&gt;
-#include &lt;fcntl.h&gt;
-#include &lt;errno.h&gt;
-
-int main()
-{
- int uiofd;
- int configfd;
- int err;
- int i;
- unsigned icount;
- unsigned char command_high;
-
- uiofd = open(&quot;/dev/uio0&quot;, O_RDONLY);
- if (uiofd &lt; 0) {
- perror(&quot;uio open:&quot;);
- return errno;
- }
- configfd = open(&quot;/sys/class/uio/uio0/device/config&quot;, O_RDWR);
- if (configfd &lt; 0) {
- perror(&quot;config open:&quot;);
- return errno;
- }
-
- /* Read and cache command value */
- err = pread(configfd, &amp;command_high, 1, 5);
- if (err != 1) {
- perror(&quot;command config read:&quot;);
- return errno;
- }
- command_high &amp;= ~0x4;
-
- for(i = 0;; ++i) {
- /* Print out a message, for debugging. */
- if (i == 0)
- fprintf(stderr, &quot;Started uio test driver.\n&quot;);
- else
- fprintf(stderr, &quot;Interrupts: %d\n&quot;, icount);
-
- /****************************************/
- /* Here we got an interrupt from the
- device. Do something to it. */
- /****************************************/
-
- /* Re-enable interrupts. */
- err = pwrite(configfd, &amp;command_high, 1, 5);
- if (err != 1) {
- perror(&quot;config write:&quot;);
- break;
- }
-
- /* Wait for next interrupt. */
- err = read(uiofd, &amp;icount, 4);
- if (err != 4) {
- perror(&quot;uio read:&quot;);
- break;
- }
-
- }
- return errno;
-}
-
-</programlisting>
- </para>
-</sect1>
-
-</chapter>
-
-<chapter id="uio_hv_generic" xreflabel="Using Generic driver for Hyper-V VMBUS">
-<?dbhtml filename="uio_hv_generic.html"?>
-<title>Generic Hyper-V UIO driver</title>
- <para>
- The generic driver is a kernel module named uio_hv_generic.
- It supports devices on the Hyper-V VMBus similar to uio_pci_generic
- on PCI bus.
- </para>
-
-<sect1 id="uio_hv_generic_binding">
-<title>Making the driver recognize the device</title>
- <para>
-Since the driver does not declare any device GUID's, it will not get loaded
-automatically and will not automatically bind to any devices, you must load it
-and allocate id to the driver yourself. For example, to use the network device
-GUID:
- <programlisting>
- modprobe uio_hv_generic
- echo &quot;f8615163-df3e-46c5-913f-f2d2f965ed0e&quot; &gt; /sys/bus/vmbus/drivers/uio_hv_generic/new_id
- </programlisting>
- </para>
- <para>
-If there already is a hardware specific kernel driver for the device, the
-generic driver still won't bind to it, in this case if you want to use the
-generic driver (why would you?) you'll have to manually unbind the hardware
-specific driver and bind the generic driver, like this:
- <programlisting>
- echo -n vmbus-ed963694-e847-4b2a-85af-bc9cfc11d6f3 &gt; /sys/bus/vmbus/drivers/hv_netvsc/unbind
- echo -n vmbus-ed963694-e847-4b2a-85af-bc9cfc11d6f3 &gt; /sys/bus/vmbus/drivers/uio_hv_generic/bind
- </programlisting>
- </para>
- <para>
-You can verify that the device has been bound to the driver
-by looking for it in sysfs, for example like the following:
- <programlisting>
- ls -l /sys/bus/vmbus/devices/vmbus-ed963694-e847-4b2a-85af-bc9cfc11d6f3/driver
- </programlisting>
-Which if successful should print
- <programlisting>
- .../vmbus-ed963694-e847-4b2a-85af-bc9cfc11d6f3/driver -&gt; ../../../bus/vmbus/drivers/uio_hv_generic
- </programlisting>
- </para>
-</sect1>
-
-<sect1 id="uio_hv_generic_internals">
-<title>Things to know about uio_hv_generic</title>
- <para>
-On each interrupt, uio_hv_generic sets the Interrupt Disable bit.
-This prevents the device from generating further interrupts
-until the bit is cleared. The userspace driver should clear this
-bit before blocking and waiting for more interrupts.
- </para>
-</sect1>
-</chapter>
-
-<appendix id="app1">
-<title>Further information</title>
-<itemizedlist>
- <listitem><para>
- <ulink url="http://www.osadl.org">
- OSADL homepage.</ulink>
- </para></listitem>
- <listitem><para>
- <ulink url="http://www.linutronix.de">
- Linutronix homepage.</ulink>
- </para></listitem>
-</itemizedlist>
-</appendix>
-
-</book>