docs: driver-model: convert docs to ReST and rename to *.rst

Convert the various documents at the driver-model, preparing
them to be part of the driver-api book.

The conversion is actually:
  - add blank lines and identation in order to identify paragraphs;
  - fix tables markups;
  - add some lists markups;
  - mark literal blocks;
  - adjust title markups.

At its new index.rst, let's add a :orphan: while this is not linked to
the main index.rst file, in order to avoid build warnings.

Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
Acked-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> # ice
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Mauro Carvalho Chehab 2019-06-18 17:53:27 -03:00 committed by Greg Kroah-Hartman
parent 58cb346c71
commit 4489f161b7
18 changed files with 489 additions and 441 deletions

View file

@ -399,7 +399,7 @@ symbol:
will pass the struct gpio_chip* for the chip to all IRQ callbacks, so the
callbacks need to embed the gpio_chip in its state container and obtain a
pointer to the container using container_of().
(See Documentation/driver-model/design-patterns.txt)
(See Documentation/driver-model/design-patterns.rst)
- gpiochip_irqchip_add_nested(): adds a nested cascaded irqchip to a gpiochip,
as discussed above regarding different types of cascaded irqchips. The

View file

@ -1,5 +1,6 @@
==============
Driver Binding
==============
Driver binding is the process of associating a device with a device
driver that can control it. Bus drivers have typically handled this
@ -95,4 +96,3 @@ of the driver is decremented. All symlinks between the two are removed.
When a driver is removed, the list of devices that it supports is
iterated over, and the driver's remove callback is called for each
one. The device is removed from that list and the symlinks removed.

View file

@ -1,5 +1,6 @@
=========
Bus Types
=========
Definition
~~~~~~~~~~
@ -13,12 +14,12 @@ Declaration
Each bus type in the kernel (PCI, USB, etc) should declare one static
object of this type. They must initialize the name field, and may
optionally initialize the match callback.
optionally initialize the match callback::
struct bus_type pci_bus_type = {
.name = "pci",
.match = pci_bus_match,
};
struct bus_type pci_bus_type = {
.name = "pci",
.match = pci_bus_match,
};
The structure should be exported to drivers in a header file:
@ -66,13 +67,14 @@ struct device_drivers, respectively. Bus drivers are free to use the
lists as they please, but conversion to the bus-specific type may be
necessary.
The LDM core provides helper functions for iterating over each list.
The LDM core provides helper functions for iterating over each list::
int bus_for_each_dev(struct bus_type * bus, struct device * start, void * data,
int (*fn)(struct device *, void *));
int bus_for_each_dev(struct bus_type * bus, struct device * start,
void * data,
int (*fn)(struct device *, void *));
int bus_for_each_drv(struct bus_type * bus, struct device_driver * start,
void * data, int (*fn)(struct device_driver *, void *));
int bus_for_each_drv(struct bus_type * bus, struct device_driver * start,
void * data, int (*fn)(struct device_driver *, void *));
These helpers iterate over the respective list, and call the callback
for each device or driver in the list. All list accesses are
@ -87,14 +89,14 @@ sysfs
There is a top-level directory named 'bus'.
Each bus gets a directory in the bus directory, along with two default
directories:
directories::
/sys/bus/pci/
|-- devices
`-- drivers
Drivers registered with the bus get a directory in the bus's drivers
directory:
directory::
/sys/bus/pci/
|-- devices
@ -106,7 +108,7 @@ directory:
Each device that is discovered on a bus of that type gets a symlink in
the bus's devices directory to the device's directory in the physical
hierarchy:
hierarchy::
/sys/bus/pci/
|-- devices
@ -118,26 +120,27 @@ hierarchy:
Exporting Attributes
~~~~~~~~~~~~~~~~~~~~
struct bus_attribute {
::
struct bus_attribute {
struct attribute attr;
ssize_t (*show)(struct bus_type *, char * buf);
ssize_t (*store)(struct bus_type *, const char * buf, size_t count);
};
};
Bus drivers can export attributes using the BUS_ATTR_RW macro that works
similarly to the DEVICE_ATTR_RW macro for devices. For example, a
definition like this:
definition like this::
static BUS_ATTR_RW(debug);
static BUS_ATTR_RW(debug);
is equivalent to declaring:
is equivalent to declaring::
static bus_attribute bus_attr_debug;
static bus_attribute bus_attr_debug;
This can then be used to add and remove the attribute from the bus's
sysfs directory using:
int bus_create_file(struct bus_type *, struct bus_attribute *);
void bus_remove_file(struct bus_type *, struct bus_attribute *);
sysfs directory using::
int bus_create_file(struct bus_type *, struct bus_attribute *);
void bus_remove_file(struct bus_type *, struct bus_attribute *);

View file

@ -1,6 +1,6 @@
==============
Device Classes
==============
Introduction
~~~~~~~~~~~~
@ -21,29 +21,29 @@ on.
Programming Interface
~~~~~~~~~~~~~~~~~~~~~
The device class structure looks like:
The device class structure looks like::
typedef int (*devclass_add)(struct device *);
typedef void (*devclass_remove)(struct device *);
typedef int (*devclass_add)(struct device *);
typedef void (*devclass_remove)(struct device *);
See the kerneldoc for the struct class.
A typical device class definition would look like:
A typical device class definition would look like::
struct device_class input_devclass = {
struct device_class input_devclass = {
.name = "input",
.add_device = input_add_device,
.remove_device = input_remove_device,
};
};
Each device class structure should be exported in a header file so it
can be used by drivers, extensions and interfaces.
Device classes are registered and unregistered with the core using:
Device classes are registered and unregistered with the core using::
int devclass_register(struct device_class * cls);
void devclass_unregister(struct device_class * cls);
int devclass_register(struct device_class * cls);
void devclass_unregister(struct device_class * cls);
Devices
@ -81,7 +81,7 @@ sysfs directory structure
There is a top-level sysfs directory named 'class'.
Each class gets a directory in the class directory, along with two
default subdirectories:
default subdirectories::
class/
`-- input
@ -90,7 +90,7 @@ default subdirectories:
Drivers registered with the class get a symlink in the drivers/ directory
that points to the driver's directory (under its bus directory):
that points to the driver's directory (under its bus directory)::
class/
`-- input
@ -100,7 +100,7 @@ that points to the driver's directory (under its bus directory):
Each device gets a symlink in the devices/ directory that points to the
device's directory in the physical hierarchy:
device's directory in the physical hierarchy::
class/
`-- input
@ -111,27 +111,30 @@ device's directory in the physical hierarchy:
Exporting Attributes
~~~~~~~~~~~~~~~~~~~~
struct devclass_attribute {
::
struct devclass_attribute {
struct attribute attr;
ssize_t (*show)(struct device_class *, char * buf, size_t count, loff_t off);
ssize_t (*store)(struct device_class *, const char * buf, size_t count, loff_t off);
};
};
Class drivers can export attributes using the DEVCLASS_ATTR macro that works
similarly to the DEVICE_ATTR macro for devices. For example, a definition
like this:
like this::
static DEVCLASS_ATTR(debug,0644,show_debug,store_debug);
static DEVCLASS_ATTR(debug,0644,show_debug,store_debug);
is equivalent to declaring:
is equivalent to declaring::
static devclass_attribute devclass_attr_debug;
static devclass_attribute devclass_attr_debug;
The bus driver can add and remove the attribute from the class's
sysfs directory using:
sysfs directory using::
int devclass_create_file(struct device_class *, struct devclass_attribute *);
void devclass_remove_file(struct device_class *, struct devclass_attribute *);
int devclass_create_file(struct device_class *, struct devclass_attribute *);
void devclass_remove_file(struct device_class *, struct devclass_attribute *);
In the example above, the file will be named 'debug' in placed in the
class's directory in sysfs.
@ -144,4 +147,3 @@ particular class type. Device interfaces describe these mechanisms.
When a device is added to a device class, the core attempts to add it
to every interface that is registered with the device class.

View file

@ -1,6 +1,6 @@
=============================
Device Driver Design Patterns
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
=============================
This document describes a few common design patterns found in device drivers.
It is likely that subsystem maintainers will ask driver developers to
@ -19,23 +19,23 @@ that the device the driver binds to will appear in several instances. This
means that the probe() function and all callbacks need to be reentrant.
The most common way to achieve this is to use the state container design
pattern. It usually has this form:
pattern. It usually has this form::
struct foo {
spinlock_t lock; /* Example member */
(...)
};
struct foo {
spinlock_t lock; /* Example member */
(...)
};
static int foo_probe(...)
{
struct foo *foo;
static int foo_probe(...)
{
struct foo *foo;
foo = devm_kzalloc(dev, sizeof(*foo), GFP_KERNEL);
if (!foo)
return -ENOMEM;
spin_lock_init(&foo->lock);
(...)
}
foo = devm_kzalloc(dev, sizeof(*foo), GFP_KERNEL);
if (!foo)
return -ENOMEM;
spin_lock_init(&foo->lock);
(...)
}
This will create an instance of struct foo in memory every time probe() is
called. This is our state container for this instance of the device driver.
@ -43,21 +43,21 @@ Of course it is then necessary to always pass this instance of the
state around to all functions that need access to the state and its members.
For example, if the driver is registering an interrupt handler, you would
pass around a pointer to struct foo like this:
pass around a pointer to struct foo like this::
static irqreturn_t foo_handler(int irq, void *arg)
{
struct foo *foo = arg;
(...)
}
static irqreturn_t foo_handler(int irq, void *arg)
{
struct foo *foo = arg;
(...)
}
static int foo_probe(...)
{
struct foo *foo;
static int foo_probe(...)
{
struct foo *foo;
(...)
ret = request_irq(irq, foo_handler, 0, "foo", foo);
}
(...)
ret = request_irq(irq, foo_handler, 0, "foo", foo);
}
This way you always get a pointer back to the correct instance of foo in
your interrupt handler.
@ -66,38 +66,38 @@ your interrupt handler.
2. container_of()
~~~~~~~~~~~~~~~~~
Continuing on the above example we add an offloaded work:
Continuing on the above example we add an offloaded work::
struct foo {
spinlock_t lock;
struct workqueue_struct *wq;
struct work_struct offload;
(...)
};
struct foo {
spinlock_t lock;
struct workqueue_struct *wq;
struct work_struct offload;
(...)
};
static void foo_work(struct work_struct *work)
{
struct foo *foo = container_of(work, struct foo, offload);
static void foo_work(struct work_struct *work)
{
struct foo *foo = container_of(work, struct foo, offload);
(...)
}
(...)
}
static irqreturn_t foo_handler(int irq, void *arg)
{
struct foo *foo = arg;
static irqreturn_t foo_handler(int irq, void *arg)
{
struct foo *foo = arg;
queue_work(foo->wq, &foo->offload);
(...)
}
queue_work(foo->wq, &foo->offload);
(...)
}
static int foo_probe(...)
{
struct foo *foo;
static int foo_probe(...)
{
struct foo *foo;
foo->wq = create_singlethread_workqueue("foo-wq");
INIT_WORK(&foo->offload, foo_work);
(...)
}
foo->wq = create_singlethread_workqueue("foo-wq");
INIT_WORK(&foo->offload, foo_work);
(...)
}
The design pattern is the same for an hrtimer or something similar that will
return a single argument which is a pointer to a struct member in the

View file

@ -1,6 +1,6 @@
==========================
The Basic Device Structure
~~~~~~~~~~~~~~~~~~~~~~~~~~
==========================
See the kerneldoc for the struct device.
@ -8,9 +8,9 @@ See the kerneldoc for the struct device.
Programming Interface
~~~~~~~~~~~~~~~~~~~~~
The bus driver that discovers the device uses this to register the
device with the core:
device with the core::
int device_register(struct device * dev);
int device_register(struct device * dev);
The bus should initialize the following fields:
@ -20,30 +20,33 @@ The bus should initialize the following fields:
- bus
A device is removed from the core when its reference count goes to
0. The reference count can be adjusted using:
0. The reference count can be adjusted using::
struct device * get_device(struct device * dev);
void put_device(struct device * dev);
struct device * get_device(struct device * dev);
void put_device(struct device * dev);
get_device() will return a pointer to the struct device passed to it
if the reference is not already 0 (if it's in the process of being
removed already).
A driver can access the lock in the device structure using:
A driver can access the lock in the device structure using::
void lock_device(struct device * dev);
void unlock_device(struct device * dev);
void lock_device(struct device * dev);
void unlock_device(struct device * dev);
Attributes
~~~~~~~~~~
struct device_attribute {
::
struct device_attribute {
struct attribute attr;
ssize_t (*show)(struct device *dev, struct device_attribute *attr,
char *buf);
ssize_t (*store)(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count);
};
};
Attributes of devices can be exported by a device driver through sysfs.
@ -54,39 +57,39 @@ As explained in Documentation/kobject.txt, device attributes must be
created before the KOBJ_ADD uevent is generated. The only way to realize
that is by defining an attribute group.
Attributes are declared using a macro called DEVICE_ATTR:
Attributes are declared using a macro called DEVICE_ATTR::
#define DEVICE_ATTR(name,mode,show,store)
#define DEVICE_ATTR(name,mode,show,store)
Example:
Example:::
static DEVICE_ATTR(type, 0444, show_type, NULL);
static DEVICE_ATTR(power, 0644, show_power, store_power);
static DEVICE_ATTR(type, 0444, show_type, NULL);
static DEVICE_ATTR(power, 0644, show_power, store_power);
This declares two structures of type struct device_attribute with respective
names 'dev_attr_type' and 'dev_attr_power'. These two attributes can be
organized as follows into a group:
organized as follows into a group::
static struct attribute *dev_attrs[] = {
static struct attribute *dev_attrs[] = {
&dev_attr_type.attr,
&dev_attr_power.attr,
NULL,
};
};
static struct attribute_group dev_attr_group = {
static struct attribute_group dev_attr_group = {
.attrs = dev_attrs,
};
};
static const struct attribute_group *dev_attr_groups[] = {
static const struct attribute_group *dev_attr_groups[] = {
&dev_attr_group,
NULL,
};
};
This array of groups can then be associated with a device by setting the
group pointer in struct device before device_register() is invoked:
group pointer in struct device before device_register() is invoked::
dev->groups = dev_attr_groups;
device_register(dev);
dev->groups = dev_attr_groups;
device_register(dev);
The device_register() function will use the 'groups' pointer to create the
device attributes and the device_unregister() function will use this pointer

View file

@ -1,3 +1,4 @@
================================
Devres - Managed Device Resource
================================
@ -5,17 +6,18 @@ Tejun Heo <teheo@suse.de>
First draft 10 January 2007
.. contents
1. Intro : Huh? Devres?
2. Devres : Devres in a nutshell
3. Devres Group : Group devres'es and release them together
4. Details : Life time rules, calling context, ...
5. Overhead : How much do we have to pay for this?
6. List of managed interfaces : Currently implemented managed interfaces
1. Intro : Huh? Devres?
2. Devres : Devres in a nutshell
3. Devres Group : Group devres'es and release them together
4. Details : Life time rules, calling context, ...
5. Overhead : How much do we have to pay for this?
6. List of managed interfaces: Currently implemented managed interfaces
1. Intro
--------
1. Intro
--------
devres came up while trying to convert libata to use iomap. Each
iomapped address should be kept and unmapped on driver detach. For
@ -42,8 +44,8 @@ would leak resources or even cause oops when failure occurs. iomap
adds more to this mix. So do msi and msix.
2. Devres
---------
2. Devres
---------
devres is basically linked list of arbitrarily sized memory areas
associated with a struct device. Each devres entry is associated with
@ -58,7 +60,7 @@ using dma_alloc_coherent(). The managed version is called
dmam_alloc_coherent(). It is identical to dma_alloc_coherent() except
for the DMA memory allocated using it is managed and will be
automatically released on driver detach. Implementation looks like
the following.
the following::
struct dma_devres {
size_t size;
@ -98,7 +100,7 @@ If a driver uses dmam_alloc_coherent(), the area is guaranteed to be
freed whether initialization fails half-way or the device gets
detached. If most resources are acquired using managed interface, a
driver can have much simpler init and exit code. Init path basically
looks like the following.
looks like the following::
my_init_one()
{
@ -119,7 +121,7 @@ looks like the following.
return register_to_upper_layer(d);
}
And exit path,
And exit path::
my_remove_one()
{
@ -140,13 +142,13 @@ on you. In some cases this may mean introducing checks that were not
necessary before moving to the managed devm_* calls.
3. Devres group
---------------
3. Devres group
---------------
Devres entries can be grouped using devres group. When a group is
released, all contained normal devres entries and properly nested
groups are released. One usage is to rollback series of acquired
resources on failure. For example,
resources on failure. For example::
if (!devres_open_group(dev, NULL, GFP_KERNEL))
return -ENOMEM;
@ -172,7 +174,7 @@ like above are usually useful in midlayer driver (e.g. libata core
layer) where interface function shouldn't have side effect on failure.
For LLDs, just returning error code suffices in most cases.
Each group is identified by void *id. It can either be explicitly
Each group is identified by `void *id`. It can either be explicitly
specified by @id argument to devres_open_group() or automatically
created by passing NULL as @id as in the above example. In both
cases, devres_open_group() returns the group's id. The returned id
@ -180,7 +182,7 @@ can be passed to other devres functions to select the target group.
If NULL is given to those functions, the latest open group is
selected.
For example, you can do something like the following.
For example, you can do something like the following::
int my_midlayer_create_something()
{
@ -199,8 +201,8 @@ For example, you can do something like the following.
}
4. Details
----------
4. Details
----------
Lifetime of a devres entry begins on devres allocation and finishes
when it is released or destroyed (removed and freed) - no reference
@ -220,8 +222,8 @@ All devres interface functions can be called without context if the
right gfp mask is given.
5. Overhead
-----------
5. Overhead
-----------
Each devres bookkeeping info is allocated together with requested data
area. With debug option turned off, bookkeeping info occupies 16
@ -237,8 +239,8 @@ and 400 bytes on 32bit machine after naive conversion (we can
certainly invest a bit more effort into libata core layer).
6. List of managed interfaces
-----------------------------
6. List of managed interfaces
-----------------------------
CLOCK
devm_clk_get()

View file

@ -1,5 +1,6 @@
==============
Device Drivers
==============
See the kerneldoc for the struct device_driver.
@ -26,17 +27,17 @@ Declaration
As stated above, struct device_driver objects are statically
allocated. Below is an example declaration of the eepro100
driver. This declaration is hypothetical only; it relies on the driver
being converted completely to the new model.
being converted completely to the new model::
static struct device_driver eepro100_driver = {
.name = "eepro100",
.bus = &pci_bus_type,
static struct device_driver eepro100_driver = {
.name = "eepro100",
.bus = &pci_bus_type,
.probe = eepro100_probe,
.remove = eepro100_remove,
.suspend = eepro100_suspend,
.resume = eepro100_resume,
};
.probe = eepro100_probe,
.remove = eepro100_remove,
.suspend = eepro100_suspend,
.resume = eepro100_resume,
};
Most drivers will not be able to be converted completely to the new
model because the bus they belong to has a bus-specific structure with
@ -49,27 +50,27 @@ completely bus-specific. Defining them as bus-specific entities would
sacrifice type-safety, so we keep bus-specific structures around.
Bus-specific drivers should include a generic struct device_driver in
the definition of the bus-specific driver. Like this:
the definition of the bus-specific driver. Like this::
struct pci_driver {
const struct pci_device_id *id_table;
struct device_driver driver;
};
struct pci_driver {
const struct pci_device_id *id_table;
struct device_driver driver;
};
A definition that included bus-specific fields would look like
(using the eepro100 driver again):
(using the eepro100 driver again)::
static struct pci_driver eepro100_driver = {
.id_table = eepro100_pci_tbl,
.driver = {
static struct pci_driver eepro100_driver = {
.id_table = eepro100_pci_tbl,
.driver = {
.name = "eepro100",
.bus = &pci_bus_type,
.probe = eepro100_probe,
.remove = eepro100_remove,
.suspend = eepro100_suspend,
.resume = eepro100_resume,
},
};
},
};
Some may find the syntax of embedded struct initialization awkward or
even a bit ugly. So far, it's the best way we've found to do what we want...
@ -77,7 +78,9 @@ even a bit ugly. So far, it's the best way we've found to do what we want...
Registration
~~~~~~~~~~~~
int driver_register(struct device_driver * drv);
::
int driver_register(struct device_driver *drv);
The driver registers the structure on startup. For drivers that have
no bus-specific fields (i.e. don't have a bus-specific driver
@ -113,10 +116,10 @@ Access
~~~~~~
Once the object has been registered, it may access the common fields of
the object, like the lock and the list of devices.
the object, like the lock and the list of devices::
int driver_for_each_dev(struct device_driver * drv, void * data,
int (*callback)(struct device * dev, void * data));
int driver_for_each_dev(struct device_driver *drv, void *data,
int (*callback)(struct device *dev, void *data));
The devices field is a list of all the devices that have been bound to
the driver. The LDM core provides a helper function to operate on all
@ -142,7 +145,9 @@ supports.
Callbacks
~~~~~~~~~
int (*probe) (struct device * dev);
::
int (*probe) (struct device *dev);
The probe() entry is called in task context, with the bus's rwsem locked
and the driver partially bound to the device. Drivers commonly use
@ -162,9 +167,9 @@ the driver to that device.
A driver's probe() may return a negative errno value to indicate that
the driver did not bind to this device, in which case it should have
released all resources it allocated.
released all resources it allocated::
int (*remove) (struct device * dev);
int (*remove) (struct device *dev);
remove is called to unbind a driver from a device. This may be
called if a device is physically removed from the system, if the
@ -176,40 +181,43 @@ not. It should free any resources allocated specifically for the
device; i.e. anything in the device's driver_data field.
If the device is still present, it should quiesce the device and place
it into a supported low-power state.
it into a supported low-power state::
int (*suspend) (struct device * dev, pm_message_t state);
int (*suspend) (struct device *dev, pm_message_t state);
suspend is called to put the device in a low power state.
suspend is called to put the device in a low power state::
int (*resume) (struct device * dev);
int (*resume) (struct device *dev);
Resume is used to bring a device back from a low power state.
Attributes
~~~~~~~~~~
struct driver_attribute {
struct attribute attr;
ssize_t (*show)(struct device_driver *driver, char *buf);
ssize_t (*store)(struct device_driver *, const char * buf, size_t count);
};
::
struct driver_attribute {
struct attribute attr;
ssize_t (*show)(struct device_driver *driver, char *buf);
ssize_t (*store)(struct device_driver *, const char *buf, size_t count);
};
Device drivers can export attributes via their sysfs directories.
Drivers can declare attributes using a DRIVER_ATTR_RW and DRIVER_ATTR_RO
macro that works identically to the DEVICE_ATTR_RW and DEVICE_ATTR_RO
macros.
Example:
Example::
DRIVER_ATTR_RW(debug);
DRIVER_ATTR_RW(debug);
This is equivalent to declaring:
This is equivalent to declaring::
struct driver_attribute driver_attr_debug;
struct driver_attribute driver_attr_debug;
This can then be used to add and remove the attribute from the
driver's directory using:
driver's directory using::
int driver_create_file(struct device_driver *, const struct driver_attribute *);
void driver_remove_file(struct device_driver *, const struct driver_attribute *);
int driver_create_file(struct device_driver *, const struct driver_attribute *);
void driver_remove_file(struct device_driver *, const struct driver_attribute *);

View file

@ -0,0 +1,26 @@
:orphan:
============
Driver Model
============
.. toctree::
:maxdepth: 1
binding
bus
class
design-patterns
device
devres
driver
overview
platform
porting
.. only:: subproject and html
Indices
=======
* :ref:`genindex`

View file

@ -1,4 +1,6 @@
=============================
The Linux Kernel Device Model
=============================
Patrick Mochel <mochel@digitalimplant.org>
@ -41,14 +43,14 @@ data structure. These fields must still be accessed by the bus layers,
and sometimes by the device-specific drivers.
Other bus layers are encouraged to do what has been done for the PCI layer.
struct pci_dev now looks like this:
struct pci_dev now looks like this::
struct pci_dev {
struct pci_dev {
...
struct device dev; /* Generic device interface */
...
};
};
Note first that the struct device dev within the struct pci_dev is
statically allocated. This means only one allocation on device discovery.
@ -80,26 +82,26 @@ easy. This has been accomplished by implementing a special purpose virtual
file system named sysfs.
Almost all mainstream Linux distros mount this filesystem automatically; you
can see some variation of the following in the output of the "mount" command:
can see some variation of the following in the output of the "mount" command::
$ mount
...
none on /sys type sysfs (rw,noexec,nosuid,nodev)
...
$
$ mount
...
none on /sys type sysfs (rw,noexec,nosuid,nodev)
...
$
The auto-mounting of sysfs is typically accomplished by an entry similar to
the following in the /etc/fstab file:
the following in the /etc/fstab file::
none /sys sysfs defaults 0 0
none /sys sysfs defaults 0 0
or something similar in the /lib/init/fstab file on Debian-based systems:
or something similar in the /lib/init/fstab file on Debian-based systems::
none /sys sysfs nodev,noexec,nosuid 0 0
none /sys sysfs nodev,noexec,nosuid 0 0
If sysfs is not automatically mounted, you can always do it manually with:
If sysfs is not automatically mounted, you can always do it manually with::
# mount -t sysfs sysfs /sys
# mount -t sysfs sysfs /sys
Whenever a device is inserted into the tree, a directory is created for it.
This directory may be populated at each layer of discovery - the global layer,
@ -120,4 +122,3 @@ device-specific data or tunable interfaces.
More information about the sysfs directory layout can be found in
the other documents in this directory and in the file
Documentation/filesystems/sysfs.txt.

View file

@ -1,5 +1,7 @@
============================
Platform Devices and Drivers
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
============================
See <linux/platform_device.h> for the driver model interface to the
platform bus: platform_device, and platform_driver. This pseudo-bus
is used to connect devices on busses with minimal infrastructure,
@ -19,15 +21,15 @@ be connected through a segment of some other kind of bus; but its
registers will still be directly addressable.
Platform devices are given a name, used in driver binding, and a
list of resources such as addresses and IRQs.
list of resources such as addresses and IRQs::
struct platform_device {
struct platform_device {
const char *name;
u32 id;
struct device dev;
u32 num_resources;
struct resource *resource;
};
};
Platform drivers
@ -35,9 +37,9 @@ Platform drivers
Platform drivers follow the standard driver model convention, where
discovery/enumeration is handled outside the drivers, and drivers
provide probe() and remove() methods. They support power management
and shutdown notifications using the standard conventions.
and shutdown notifications using the standard conventions::
struct platform_driver {
struct platform_driver {
int (*probe)(struct platform_device *);
int (*remove)(struct platform_device *);
void (*shutdown)(struct platform_device *);
@ -46,25 +48,25 @@ struct platform_driver {
int (*resume_early)(struct platform_device *);
int (*resume)(struct platform_device *);
struct device_driver driver;
};
};
Note that probe() should in general verify that the specified device hardware
actually exists; sometimes platform setup code can't be sure. The probing
can use device resources, including clocks, and device platform_data.
Platform drivers register themselves the normal way:
Platform drivers register themselves the normal way::
int platform_driver_register(struct platform_driver *drv);
Or, in common situations where the device is known not to be hot-pluggable,
the probe() routine can live in an init section to reduce the driver's
runtime memory footprint:
runtime memory footprint::
int platform_driver_probe(struct platform_driver *drv,
int (*probe)(struct platform_device *))
Kernel modules can be composed of several platform drivers. The platform core
provides helpers to register and unregister an array of drivers:
provides helpers to register and unregister an array of drivers::
int __platform_register_drivers(struct platform_driver * const *drivers,
unsigned int count, struct module *owner);
@ -73,7 +75,7 @@ provides helpers to register and unregister an array of drivers:
If one of the drivers fails to register, all drivers registered up to that
point will be unregistered in reverse order. Note that there is a convenience
macro that passes THIS_MODULE as owner parameter:
macro that passes THIS_MODULE as owner parameter::
#define platform_register_drivers(drivers, count)
@ -81,7 +83,7 @@ macro that passes THIS_MODULE as owner parameter:
Device Enumeration
~~~~~~~~~~~~~~~~~~
As a rule, platform specific (and often board-specific) setup code will
register platform devices:
register platform devices::
int platform_device_register(struct platform_device *pdev);
@ -133,14 +135,14 @@ tend to already have "normal" modes, such as ones using device nodes that
were created by PNP or by platform device setup.
None the less, there are some APIs to support such legacy drivers. Avoid
using these calls except with such hotplug-deficient drivers.
using these calls except with such hotplug-deficient drivers::
struct platform_device *platform_device_alloc(
const char *name, int id);
You can use platform_device_alloc() to dynamically allocate a device, which
you will then initialize with resources and platform_device_register().
A better solution is usually:
A better solution is usually::
struct platform_device *platform_device_register_simple(
const char *name, int id,

View file

@ -1,5 +1,6 @@
=======================================
Porting Drivers to the New Driver Model
=======================================
Patrick Mochel
@ -8,7 +9,7 @@ Patrick Mochel
Overview
Please refer to Documentation/driver-model/*.txt for definitions of
Please refer to `Documentation/driver-model/*.rst` for definitions of
various driver types and concepts.
Most of the work of porting devices drivers to the new model happens
@ -22,7 +23,7 @@ objects can replace fields in the bus-specific objects.
The generic objects must be registered with the driver model core. By
doing so, they will exported via the sysfs filesystem. sysfs can be
mounted by doing
mounted by doing::
# mount -t sysfs sysfs /sys
@ -35,27 +36,28 @@ Step 0: Read include/linux/device.h for object and function definitions.
Step 1: Registering the bus driver.
- Define a struct bus_type for the bus driver.
- Define a struct bus_type for the bus driver::
struct bus_type pci_bus_type = {
.name = "pci",
};
struct bus_type pci_bus_type = {
.name = "pci",
};
- Register the bus type.
This should be done in the initialization function for the bus type,
which is usually the module_init(), or equivalent, function.
which is usually the module_init(), or equivalent, function::
static int __init pci_driver_init(void)
{
return bus_register(&pci_bus_type);
}
static int __init pci_driver_init(void)
{
return bus_register(&pci_bus_type);
}
subsys_initcall(pci_driver_init);
subsys_initcall(pci_driver_init);
The bus type may be unregistered (if the bus driver may be compiled
as a module) by doing:
as a module) by doing::
bus_unregister(&pci_bus_type);
@ -65,24 +67,24 @@ subsys_initcall(pci_driver_init);
Other code may wish to reference the bus type, so declare it in a
shared header file and export the symbol.
From include/linux/pci.h:
From include/linux/pci.h::
extern struct bus_type pci_bus_type;
extern struct bus_type pci_bus_type;
From file the above code appears in:
From file the above code appears in::
EXPORT_SYMBOL(pci_bus_type);
EXPORT_SYMBOL(pci_bus_type);
- This will cause the bus to show up in /sys/bus/pci/ with two
subdirectories: 'devices' and 'drivers'.
subdirectories: 'devices' and 'drivers'::
# tree -d /sys/bus/pci/
/sys/bus/pci/
|-- devices
`-- drivers
# tree -d /sys/bus/pci/
/sys/bus/pci/
|-- devices
`-- drivers
@ -92,29 +94,29 @@ struct device represents a single device. It mainly contains metadata
describing the relationship the device has to other entities.
- Embed a struct device in the bus-specific device type.
- Embed a struct device in the bus-specific device type::
struct pci_dev {
...
struct device dev; /* Generic device interface */
...
};
struct pci_dev {
...
struct device dev; /* Generic device interface */
...
};
It is recommended that the generic device not be the first item in
the struct to discourage programmers from doing mindless casts
between the object types. Instead macros, or inline functions,
should be created to convert from the generic object type.
should be created to convert from the generic object type::
#define to_pci_dev(n) container_of(n, struct pci_dev, dev)
#define to_pci_dev(n) container_of(n, struct pci_dev, dev)
or
or
static inline struct pci_dev * to_pci_dev(struct kobject * kobj)
{
static inline struct pci_dev * to_pci_dev(struct kobject * kobj)
{
return container_of(n, struct pci_dev, dev);
}
}
This allows the compiler to verify type-safety of the operations
that are performed (which is Good).
@ -163,11 +165,11 @@ static inline struct pci_dev * to_pci_dev(struct kobject * kobj)
- Register the device.
Once the generic device has been initialized, it can be registered
with the driver model core by doing:
with the driver model core by doing::
device_register(&dev->dev);
It can later be unregistered by doing:
It can later be unregistered by doing::
device_unregister(&dev->dev);
@ -181,45 +183,45 @@ static inline struct pci_dev * to_pci_dev(struct kobject * kobj)
When the device is registered, a directory in sysfs is created.
The PCI tree in sysfs looks like:
The PCI tree in sysfs looks like::
/sys/devices/pci0/
|-- 00:00.0
|-- 00:01.0
| `-- 01:00.0
|-- 00:02.0
| `-- 02:1f.0
| `-- 03:00.0
|-- 00:1e.0
| `-- 04:04.0
|-- 00:1f.0
|-- 00:1f.1
| |-- ide0
| | |-- 0.0
| | `-- 0.1
| `-- ide1
| `-- 1.0
|-- 00:1f.2
|-- 00:1f.3
`-- 00:1f.5
/sys/devices/pci0/
|-- 00:00.0
|-- 00:01.0
| `-- 01:00.0
|-- 00:02.0
| `-- 02:1f.0
| `-- 03:00.0
|-- 00:1e.0
| `-- 04:04.0
|-- 00:1f.0
|-- 00:1f.1
| |-- ide0
| | |-- 0.0
| | `-- 0.1
| `-- ide1
| `-- 1.0
|-- 00:1f.2
|-- 00:1f.3
`-- 00:1f.5
Also, symlinks are created in the bus's 'devices' directory
that point to the device's directory in the physical hierarchy.
that point to the device's directory in the physical hierarchy::
/sys/bus/pci/devices/
|-- 00:00.0 -> ../../../devices/pci0/00:00.0
|-- 00:01.0 -> ../../../devices/pci0/00:01.0
|-- 00:02.0 -> ../../../devices/pci0/00:02.0
|-- 00:1e.0 -> ../../../devices/pci0/00:1e.0
|-- 00:1f.0 -> ../../../devices/pci0/00:1f.0
|-- 00:1f.1 -> ../../../devices/pci0/00:1f.1
|-- 00:1f.2 -> ../../../devices/pci0/00:1f.2
|-- 00:1f.3 -> ../../../devices/pci0/00:1f.3
|-- 00:1f.5 -> ../../../devices/pci0/00:1f.5
|-- 01:00.0 -> ../../../devices/pci0/00:01.0/01:00.0
|-- 02:1f.0 -> ../../../devices/pci0/00:02.0/02:1f.0
|-- 03:00.0 -> ../../../devices/pci0/00:02.0/02:1f.0/03:00.0
`-- 04:04.0 -> ../../../devices/pci0/00:1e.0/04:04.0
/sys/bus/pci/devices/
|-- 00:00.0 -> ../../../devices/pci0/00:00.0
|-- 00:01.0 -> ../../../devices/pci0/00:01.0
|-- 00:02.0 -> ../../../devices/pci0/00:02.0
|-- 00:1e.0 -> ../../../devices/pci0/00:1e.0
|-- 00:1f.0 -> ../../../devices/pci0/00:1f.0
|-- 00:1f.1 -> ../../../devices/pci0/00:1f.1
|-- 00:1f.2 -> ../../../devices/pci0/00:1f.2
|-- 00:1f.3 -> ../../../devices/pci0/00:1f.3
|-- 00:1f.5 -> ../../../devices/pci0/00:1f.5
|-- 01:00.0 -> ../../../devices/pci0/00:01.0/01:00.0
|-- 02:1f.0 -> ../../../devices/pci0/00:02.0/02:1f.0
|-- 03:00.0 -> ../../../devices/pci0/00:02.0/02:1f.0/03:00.0
`-- 04:04.0 -> ../../../devices/pci0/00:1e.0/04:04.0
@ -231,12 +233,12 @@ of operations that the driver model core may call.
- Embed a struct device_driver in the bus-specific driver.
Just like with devices, do something like:
Just like with devices, do something like::
struct pci_driver {
...
struct device_driver driver;
};
struct pci_driver {
...
struct device_driver driver;
};
- Initialize the generic driver structure.
@ -248,14 +250,14 @@ struct pci_driver {
- Register the driver.
After the generic driver has been initialized, call
After the generic driver has been initialized, call::
driver_register(&drv->driver);
to register the driver with the core.
When the driver is unregistered from the bus, unregister it from the
core by doing:
core by doing::
driver_unregister(&drv->driver);
@ -266,14 +268,14 @@ struct pci_driver {
- Sysfs representation.
Drivers are exported via sysfs in their bus's 'driver's directory.
For example:
For example::
/sys/bus/pci/drivers/
|-- 3c59x
|-- Ensoniq AudioPCI
|-- agpgart-amdk7
|-- e100
`-- serial
/sys/bus/pci/drivers/
|-- 3c59x
|-- Ensoniq AudioPCI
|-- agpgart-amdk7
|-- e100
`-- serial
Step 4: Define Generic Methods for Drivers.
@ -286,25 +288,25 @@ parameters.
It would be difficult and tedious to force every driver on a bus to
simultaneously convert their drivers to generic format. Instead, the
bus driver should define single instances of the generic methods that
forward call to the bus-specific drivers. For instance:
forward call to the bus-specific drivers. For instance::
static int pci_device_remove(struct device * dev)
{
struct pci_dev * pci_dev = to_pci_dev(dev);
struct pci_driver * drv = pci_dev->driver;
static int pci_device_remove(struct device * dev)
{
struct pci_dev * pci_dev = to_pci_dev(dev);
struct pci_driver * drv = pci_dev->driver;
if (drv) {
if (drv->remove)
drv->remove(pci_dev);
pci_dev->driver = NULL;
}
return 0;
}
if (drv) {
if (drv->remove)
drv->remove(pci_dev);
pci_dev->driver = NULL;
}
return 0;
}
The generic driver should be initialized with these methods before it
is registered.
is registered::
/* initialize common driver fields */
drv->driver.name = drv->name;
@ -336,7 +338,7 @@ The format of the device IDs, and the semantics for comparing them are
bus-specific, so the generic model does attempt to generalize them.
Instead, a bus may supply a method in struct bus_type that does the
comparison:
comparison::
int (*match)(struct device * dev, struct device_driver * drv);
@ -355,17 +357,17 @@ claimed by a driver.
When a device is successfully bound to a driver, device->driver is
set, the device is added to a per-driver list of devices, and a
symlink is created in the driver's sysfs directory that points to the
device's physical directory:
device's physical directory::
/sys/bus/pci/drivers/
|-- 3c59x
| `-- 00:0b.0 -> ../../../../devices/pci0/00:0b.0
|-- Ensoniq AudioPCI
|-- agpgart-amdk7
| `-- 00:00.0 -> ../../../../devices/pci0/00:00.0
|-- e100
| `-- 00:0c.0 -> ../../../../devices/pci0/00:0c.0
`-- serial
/sys/bus/pci/drivers/
|-- 3c59x
| `-- 00:0b.0 -> ../../../../devices/pci0/00:0b.0
|-- Ensoniq AudioPCI
|-- agpgart-amdk7
| `-- 00:00.0 -> ../../../../devices/pci0/00:00.0
|-- e100
| `-- 00:0c.0 -> ../../../../devices/pci0/00:0c.0
`-- serial
This driver binding should replace the existing driver binding
@ -387,7 +389,7 @@ environment variables, including
A bus driver may also supply additional parameters for userspace to
consume. To do this, a bus must implement the 'hotplug' method in
struct bus_type:
struct bus_type::
int (*hotplug) (struct device *dev, char **envp,
int num_envp, char *buffer, int buffer_size);
@ -407,10 +409,10 @@ type. This includes all devices on all instances of that bus type.
An internal list that the bus uses may be removed, in favor of using
this one.
The core provides an iterator to access these devices.
The core provides an iterator to access these devices::
int bus_for_each_dev(struct bus_type * bus, struct device * start,
void * data, int (*fn)(struct device *, void *));
int bus_for_each_dev(struct bus_type * bus, struct device * start,
void * data, int (*fn)(struct device *, void *));
- Driver list.
@ -419,10 +421,10 @@ struct bus_type also contains a list of all drivers registered with
it. An internal list of drivers that the bus driver maintains may
be removed in favor of using the generic one.
The drivers may be iterated over, like devices:
The drivers may be iterated over, like devices::
int bus_for_each_drv(struct bus_type * bus, struct device_driver * start,
void * data, int (*fn)(struct device_driver *, void *));
int bus_for_each_drv(struct bus_type * bus, struct device_driver * start,
void * data, int (*fn)(struct device_driver *, void *));
Please see drivers/base/bus.c for more information.
@ -444,4 +446,3 @@ to remove the bus-specific ones and favor the generic ones. Note
though, that this will likely mean fixing up all the drivers that
reference the bus-specific fields (though those should all be 1-line
changes).

View file

@ -103,7 +103,7 @@ id_table an array of NULL terminated EISA id strings,
(driver_data).
driver a generic driver, such as described in
Documentation/driver-model/driver.txt. Only .name,
Documentation/driver-model/driver.rst. Only .name,
.probe and .remove members are mandatory.
=============== ====================================================
@ -152,7 +152,7 @@ state set of flags indicating the state of the device. Current
flags are EISA_CONFIG_ENABLED and EISA_CONFIG_FORCED.
res set of four 256 bytes I/O regions allocated to this device
dma_mask DMA mask set from the parent device.
dev generic device (see Documentation/driver-model/device.txt)
dev generic device (see Documentation/driver-model/device.rst)
======== ============================================================
You can get the 'struct eisa_device' from 'struct device' using the

View file

@ -89,7 +89,7 @@ increase the chances of your change being accepted.
console. Excessive logging can seriously affect system performance.
* Use devres functions whenever possible to allocate resources. For rationale
and supported functions, please see Documentation/driver-model/devres.txt.
and supported functions, please see Documentation/driver-model/devres.rst.
If a function is not supported by devres, consider using devm_add_action().
* If the driver has a detect function, make sure it is silent. Debug messages

View file

@ -5,7 +5,7 @@
* Copyright (c) 2002-3 Patrick Mochel
* Copyright (c) 2002-3 Open Source Development Labs
*
* Please see Documentation/driver-model/platform.txt for more
* Please see Documentation/driver-model/platform.rst for more
* information.
*/

View file

@ -41,7 +41,7 @@ MODULE_PARM_DESC(mask, "GPIO channel mask.");
/*
* FIXME: convert this singleton driver to use the state container
* design pattern, see Documentation/driver-model/design-patterns.txt
* design pattern, see Documentation/driver-model/design-patterns.rst
*/
static struct cs5535_gpio_chip {
struct gpio_chip chip;

View file

@ -2237,7 +2237,7 @@ ice_probe(struct pci_dev *pdev, const struct pci_device_id __always_unused *ent)
struct ice_hw *hw;
int err;
/* this driver uses devres, see Documentation/driver-model/devres.txt */
/* this driver uses devres, see Documentation/driver-model/devres.rst */
err = pcim_enable_device(pdev);
if (err)
return err;

View file

@ -2,7 +2,7 @@
/// functions. Values allocated using the devm_functions are freed when
/// the device is detached, and thus the use of the standard freeing
/// function would cause a double free.
/// See Documentation/driver-model/devres.txt for more information.
/// See Documentation/driver-model/devres.rst for more information.
///
/// A difficulty of detecting this problem is that the standard freeing
/// function might be called from a different function than the one