diff options
Diffstat (limited to 'Documentation/driver-model')
| -rw-r--r-- | Documentation/driver-model/binding.txt | 4 | ||||
| -rw-r--r-- | Documentation/driver-model/bus.txt | 19 | ||||
| -rw-r--r-- | Documentation/driver-model/class.txt | 19 | ||||
| -rw-r--r-- | Documentation/driver-model/design-patterns.txt | 116 | ||||
| -rw-r--r-- | Documentation/driver-model/device.txt | 154 | ||||
| -rw-r--r-- | Documentation/driver-model/devres.txt | 325 | ||||
| -rw-r--r-- | Documentation/driver-model/driver.txt | 92 | ||||
| -rw-r--r-- | Documentation/driver-model/interface.txt | 129 | ||||
| -rw-r--r-- | Documentation/driver-model/overview.txt | 103 | ||||
| -rw-r--r-- | Documentation/driver-model/platform.txt | 301 | ||||
| -rw-r--r-- | Documentation/driver-model/porting.txt | 4 |
11 files changed, 777 insertions, 489 deletions
diff --git a/Documentation/driver-model/binding.txt b/Documentation/driver-model/binding.txt index f7ec9d625bf..abfc8e290d5 100644 --- a/Documentation/driver-model/binding.txt +++ b/Documentation/driver-model/binding.txt @@ -48,10 +48,6 @@ devclass_add_device is called to enumerate the device within the class and actually register it with the class, which happens with the class's register_dev callback. -NOTE: The device class structures and core routines to manipulate them -are not in the mainline kernel, so the discussion is still a bit -speculative. - Driver ~~~~~~ diff --git a/Documentation/driver-model/bus.txt b/Documentation/driver-model/bus.txt index 5001b751162..6754b2df8aa 100644 --- a/Documentation/driver-model/bus.txt +++ b/Documentation/driver-model/bus.txt @@ -3,24 +3,7 @@ Bus Types Definition ~~~~~~~~~~ - -struct bus_type { - char * name; - - struct subsystem subsys; - struct kset drivers; - struct kset devices; - - struct bus_attribute * bus_attrs; - struct device_attribute * dev_attrs; - struct driver_attribute * drv_attrs; - - int (*match)(struct device * dev, struct device_driver * drv); - int (*hotplug) (struct device *dev, char **envp, - int num_envp, char *buffer, int buffer_size); - int (*suspend)(struct device * dev, pm_message_t state); - int (*resume)(struct device * dev); -}; +See the kerneldoc for the struct bus_type. int bus_register(struct bus_type * bus); diff --git a/Documentation/driver-model/class.txt b/Documentation/driver-model/class.txt index 2d1d893a5e5..1fefc480a80 100644 --- a/Documentation/driver-model/class.txt +++ b/Documentation/driver-model/class.txt @@ -12,7 +12,7 @@ device. The following device classes have been identified: Each device class defines a set of semantics and a programming interface that devices of that class adhere to. Device drivers are the -implemention of that programming interface for a particular device on +implementation of that programming interface for a particular device on a particular bus. Device classes are agnostic with respect to what bus a device resides @@ -27,22 +27,7 @@ The device class structure looks like: typedef int (*devclass_add)(struct device *); typedef void (*devclass_remove)(struct device *); -struct device_class { - char * name; - rwlock_t lock; - u32 devnum; - struct list_head node; - - struct list_head drivers; - struct list_head intf_list; - - struct driver_dir_entry dir; - struct driver_dir_entry device_dir; - struct driver_dir_entry driver_dir; - - devclass_add add_device; - devclass_remove remove_device; -}; +See the kerneldoc for the struct class. A typical device class definition would look like: diff --git a/Documentation/driver-model/design-patterns.txt b/Documentation/driver-model/design-patterns.txt new file mode 100644 index 00000000000..ba7b2df6490 --- /dev/null +++ b/Documentation/driver-model/design-patterns.txt @@ -0,0 +1,116 @@ + +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 +conform to these design patterns. + +1. State Container +2. container_of() + + +1. State Container +~~~~~~~~~~~~~~~~~~ + +While the kernel contains a few device drivers that assume that they will +only be probed() once on a certain system (singletons), it is custom to assume +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: + +struct foo { + spinlock_t lock; /* Example member */ + (...) +}; + +static int foo_probe(...) +{ + struct foo *foo; + + 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. +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: + +static irqreturn_t foo_handler(int irq, void *arg) +{ + struct foo *foo = arg; + (...) +} + +static int foo_probe(...) +{ + struct 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. + + +2. container_of() +~~~~~~~~~~~~~~~~~ + +Continuing on the above example we add an offloaded work: + +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 irqreturn_t foo_handler(int irq, void *arg) +{ + struct foo *foo = arg; + + queue_work(foo->wq, &foo->offload); + (...) +} + +static int foo_probe(...) +{ + struct foo *foo; + + 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 +callback. + +container_of() is a macro defined in <linux/kernel.h> + +What container_of() does is to obtain a pointer to the containing struct from +a pointer to a member by a simple subtraction using the offsetof() macro from +standard C, which allows something similar to object oriented behaviours. +Notice that the contained member must not be a pointer, but an actual member +for this to work. + +We can see here that we avoid having global pointers to our struct foo * +instance this way, while still keeping the number of parameters passed to the +work function to a single pointer. diff --git a/Documentation/driver-model/device.txt b/Documentation/driver-model/device.txt index a05ec50f800..1e70220d20f 100644 --- a/Documentation/driver-model/device.txt +++ b/Documentation/driver-model/device.txt @@ -2,96 +2,7 @@ The Basic Device Structure ~~~~~~~~~~~~~~~~~~~~~~~~~~ -struct device { - struct list_head g_list; - struct list_head node; - struct list_head bus_list; - struct list_head driver_list; - struct list_head intf_list; - struct list_head children; - struct device * parent; - - char name[DEVICE_NAME_SIZE]; - char bus_id[BUS_ID_SIZE]; - - spinlock_t lock; - atomic_t refcount; - - struct bus_type * bus; - struct driver_dir_entry dir; - - u32 class_num; - - struct device_driver *driver; - void *driver_data; - void *platform_data; - - u32 current_state; - unsigned char *saved_state; - - void (*release)(struct device * dev); -}; - -Fields -~~~~~~ -g_list: Node in the global device list. - -node: Node in device's parent's children list. - -bus_list: Node in device's bus's devices list. - -driver_list: Node in device's driver's devices list. - -intf_list: List of intf_data. There is one structure allocated for - each interface that the device supports. - -children: List of child devices. - -parent: *** FIXME *** - -name: ASCII description of device. - Example: " 3Com Corporation 3c905 100BaseTX [Boomerang]" - -bus_id: ASCII representation of device's bus position. This - field should be a name unique across all devices on the - bus type the device belongs to. - - Example: PCI bus_ids are in the form of - <bus number>:<slot number>.<function number> - This name is unique across all PCI devices in the system. - -lock: Spinlock for the device. - -refcount: Reference count on the device. - -bus: Pointer to struct bus_type that device belongs to. - -dir: Device's sysfs directory. - -class_num: Class-enumerated value of the device. - -driver: Pointer to struct device_driver that controls the device. - -driver_data: Driver-specific data. - -platform_data: Platform data specific to the device. - - Example: for devices on custom boards, as typical of embedded - and SOC based hardware, Linux often uses platform_data to point - to board-specific structures describing devices and how they - are wired. That can include what ports are available, chip - variants, which GPIO pins act in what additional roles, and so - on. This shrinks the "Board Support Packages" (BSPs) and - minimizes board-specific #ifdefs in drivers. - -current_state: Current power state of the device. - -saved_state: Pointer to saved state of the device. This is usable by - the device driver controlling the device. - -release: Callback to free the device after all references have - gone away. This should be set by the allocator of the - device (i.e. the bus driver that discovered the device). +See the kerneldoc for the struct device. Programming Interface @@ -127,36 +38,69 @@ void unlock_device(struct device * dev); Attributes ~~~~~~~~~~ struct device_attribute { - struct attribute attr; - ssize_t (*show)(struct device * dev, char * buf, size_t count, loff_t off); - ssize_t (*store)(struct device * dev, const char * buf, size_t count, loff_t off); + 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 via drivers using a simple -procfs-like interface. +Attributes of devices can be exported by a device driver through sysfs. Please see Documentation/filesystems/sysfs.txt for more information on how sysfs works. +As explained in Documentation/kobject.txt, device attributes must be 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: #define DEVICE_ATTR(name,mode,show,store) Example: -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 a structure of type struct device_attribute named -'dev_attr_power'. This can then be added and removed to the device's -directory using: +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: -int device_create_file(struct device *device, struct device_attribute * entry); -void device_remove_file(struct device * dev, struct device_attribute * attr); +static struct attribute *dev_attrs[] = { + &dev_attr_type.attr, + &dev_attr_power.attr, + NULL, +}; -Example: +static struct attribute_group dev_attr_group = { + .attrs = dev_attrs, +}; + +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: + + dev->groups = dev_attr_groups; + device_register(dev); -device_create_file(dev,&dev_attr_power); -device_remove_file(dev,&dev_attr_power); +The device_register() function will use the 'groups' pointer to create the +device attributes and the device_unregister() function will use this pointer +to remove the device attributes. -The file name will be 'power' with a mode of 0644 (-rw-r--r--). +Word of warning: While the kernel allows device_create_file() and +device_remove_file() to be called on a device at any time, userspace has +strict expectations on when attributes get created. When a new device is +registered in the kernel, a uevent is generated to notify userspace (like +udev) that a new device is available. If attributes are added after the +device is registered, then userspace won't get notified and userspace will +not know about the new attributes. +This is important for device driver that need to publish additional +attributes for a device at driver probe time. If the device driver simply +calls device_create_file() on the device structure passed to it, then +userspace will never be notified of the new attributes. diff --git a/Documentation/driver-model/devres.txt b/Documentation/driver-model/devres.txt new file mode 100644 index 00000000000..1525e30483f --- /dev/null +++ b/Documentation/driver-model/devres.txt @@ -0,0 +1,325 @@ +Devres - Managed Device Resource +================================ + +Tejun Heo <teheo@suse.de> + +First draft 10 January 2007 + + +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 + -------- + +devres came up while trying to convert libata to use iomap. Each +iomapped address should be kept and unmapped on driver detach. For +example, a plain SFF ATA controller (that is, good old PCI IDE) in +native mode makes use of 5 PCI BARs and all of them should be +maintained. + +As with many other device drivers, libata low level drivers have +sufficient bugs in ->remove and ->probe failure path. Well, yes, +that's probably because libata low level driver developers are lazy +bunch, but aren't all low level driver developers? After spending a +day fiddling with braindamaged hardware with no document or +braindamaged document, if it's finally working, well, it's working. + +For one reason or another, low level drivers don't receive as much +attention or testing as core code, and bugs on driver detach or +initialization failure don't happen often enough to be noticeable. +Init failure path is worse because it's much less travelled while +needs to handle multiple entry points. + +So, many low level drivers end up leaking resources on driver detach +and having half broken failure path implementation in ->probe() which +would leak resources or even cause oops when failure occurs. iomap +adds more to this mix. So do msi and msix. + + + 2. Devres + --------- + +devres is basically linked list of arbitrarily sized memory areas +associated with a struct device. Each devres entry is associated with +a release function. A devres can be released in several ways. No +matter what, all devres entries are released on driver detach. On +release, the associated release function is invoked and then the +devres entry is freed. + +Managed interface is created for resources commonly used by device +drivers using devres. For example, coherent DMA memory is acquired +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. + + struct dma_devres { + size_t size; + void *vaddr; + dma_addr_t dma_handle; + }; + + static void dmam_coherent_release(struct device *dev, void *res) + { + struct dma_devres *this = res; + + dma_free_coherent(dev, this->size, this->vaddr, this->dma_handle); + } + + dmam_alloc_coherent(dev, size, dma_handle, gfp) + { + struct dma_devres *dr; + void *vaddr; + + dr = devres_alloc(dmam_coherent_release, sizeof(*dr), gfp); + ... + + /* alloc DMA memory as usual */ + vaddr = dma_alloc_coherent(...); + ... + + /* record size, vaddr, dma_handle in dr */ + dr->vaddr = vaddr; + ... + + devres_add(dev, dr); + + return vaddr; + } + +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. + + my_init_one() + { + struct mydev *d; + + d = devm_kzalloc(dev, sizeof(*d), GFP_KERNEL); + if (!d) + return -ENOMEM; + + d->ring = dmam_alloc_coherent(...); + if (!d->ring) + return -ENOMEM; + + if (check something) + return -EINVAL; + ... + + return register_to_upper_layer(d); + } + +And exit path, + + my_remove_one() + { + unregister_from_upper_layer(d); + shutdown_my_hardware(); + } + +As shown above, low level drivers can be simplified a lot by using +devres. Complexity is shifted from less maintained low level drivers +to better maintained higher layer. Also, as init failure path is +shared with exit path, both can get more testing. + + + 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, + + if (!devres_open_group(dev, NULL, GFP_KERNEL)) + return -ENOMEM; + + acquire A; + if (failed) + goto err; + + acquire B; + if (failed) + goto err; + ... + + devres_remove_group(dev, NULL); + return 0; + + err: + devres_release_group(dev, NULL); + return err_code; + +As resource acquisition failure usually means probe failure, constructs +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 +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 +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. + + int my_midlayer_create_something() + { + if (!devres_open_group(dev, my_midlayer_create_something, GFP_KERNEL)) + return -ENOMEM; + + ... + + devres_close_group(dev, my_midlayer_create_something); + return 0; + } + + void my_midlayer_destroy_something() + { + devres_release_group(dev, my_midlayer_create_something); + } + + + 4. Details + ---------- + +Lifetime of a devres entry begins on devres allocation and finishes +when it is released or destroyed (removed and freed) - no reference +counting. + +devres core guarantees atomicity to all basic devres operations and +has support for single-instance devres types (atomic +lookup-and-add-if-not-found). Other than that, synchronizing +concurrent accesses to allocated devres data is caller's +responsibility. This is usually non-issue because bus ops and +resource allocations already do the job. + +For an example of single-instance devres type, read pcim_iomap_table() +in lib/devres.c. + +All devres interface functions can be called without context if the +right gfp mask is given. + + + 5. Overhead + ----------- + +Each devres bookkeeping info is allocated together with requested data +area. With debug option turned off, bookkeeping info occupies 16 +bytes on 32bit machines and 24 bytes on 64bit (three pointers rounded +up to ull alignment). If singly linked list is used, it can be +reduced to two pointers (8 bytes on 32bit, 16 bytes on 64bit). + +Each devres group occupies 8 pointers. It can be reduced to 6 if +singly linked list is used. + +Memory space overhead on ahci controller with two ports is between 300 +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 + ----------------------------- + +MEM + devm_kzalloc() + devm_kfree() + devm_kmemdup() + devm_get_free_pages() + devm_free_pages() + +IIO + devm_iio_device_alloc() + devm_iio_device_free() + devm_iio_trigger_alloc() + devm_iio_trigger_free() + devm_iio_device_register() + devm_iio_device_unregister() + +IO region + devm_request_region() + devm_request_mem_region() + devm_release_region() + devm_release_mem_region() + +IRQ + devm_request_irq() + devm_free_irq() + +DMA + dmam_alloc_coherent() + dmam_free_coherent() + dmam_alloc_noncoherent() + dmam_free_noncoherent() + dmam_declare_coherent_memory() + dmam_pool_create() + dmam_pool_destroy() + +PCI + pcim_enable_device() : after success, all PCI ops become managed + pcim_pin_device() : keep PCI device enabled after release + +IOMAP + devm_ioport_map() + devm_ioport_unmap() + devm_ioremap() + devm_ioremap_nocache() + devm_iounmap() + devm_ioremap_resource() : checks resource, requests memory region, ioremaps + devm_request_and_ioremap() : obsoleted by devm_ioremap_resource() + pcim_iomap() + pcim_iounmap() + pcim_iomap_table() : array of mapped addresses indexed by BAR + pcim_iomap_regions() : do request_region() and iomap() on multiple BARs + +REGULATOR + devm_regulator_get() + devm_regulator_put() + devm_regulator_bulk_get() + devm_regulator_register() + +CLOCK + devm_clk_get() + devm_clk_put() + +PINCTRL + devm_pinctrl_get() + devm_pinctrl_put() + +PWM + devm_pwm_get() + devm_pwm_put() + +PHY + devm_usb_get_phy() + devm_usb_put_phy() + +SLAVE DMA ENGINE + devm_acpi_dma_controller_register() + +SPI + devm_spi_register_master() + +GPIO + devm_gpiod_get() + devm_gpiod_get_index() + devm_gpiod_get_optional() + devm_gpiod_get_index_optional() + devm_gpiod_put() + +MDIO + devm_mdiobus_alloc() + devm_mdiobus_alloc_size() + devm_mdiobus_free() diff --git a/Documentation/driver-model/driver.txt b/Documentation/driver-model/driver.txt index fabaca1ab1b..4421135826a 100644 --- a/Documentation/driver-model/driver.txt +++ b/Documentation/driver-model/driver.txt @@ -1,23 +1,7 @@ Device Drivers -struct device_driver { - char * name; - struct bus_type * bus; - - struct completion unloaded; - struct kobject kobj; - list_t devices; - - struct module *owner; - - int (*probe) (struct device * dev); - int (*remove) (struct device * dev); - - int (*suspend) (struct device * dev, pm_message_t state, u32 level); - int (*resume) (struct device * dev, u32 level); -}; - +See the kerneldoc for the struct device_driver. Allocation @@ -178,7 +162,7 @@ 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 reasources it allocated. +released all resources it allocated. int (*remove) (struct device * dev); @@ -194,77 +178,21 @@ 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. - int (*suspend) (struct device * dev, pm_message_t state, u32 level); - -suspend is called to put the device in a low power state. There are -several stages to successfully suspending a device, which is denoted in -the @level parameter. Breaking the suspend transition into several -stages affords the platform flexibility in performing device power -management based on the requirements of the system and the -user-defined policy. - -SUSPEND_NOTIFY notifies the device that a suspend transition is about -to happen. This happens on system power state transitions to verify -that all devices can successfully suspend. - -A driver may choose to fail on this call, which should cause the -entire suspend transition to fail. A driver should fail only if it -knows that the device will not be able to be resumed properly when the -system wakes up again. It could also fail if it somehow determines it -is in the middle of an operation too important to stop. - -SUSPEND_DISABLE tells the device to stop I/O transactions. When it -stops transactions, or what it should do with unfinished transactions -is a policy of the driver. After this call, the driver should not -accept any other I/O requests. - -SUSPEND_SAVE_STATE tells the device to save the context of the -hardware. This includes any bus-specific hardware state and -device-specific hardware state. A pointer to this saved state can be -stored in the device's saved_state field. - -SUSPEND_POWER_DOWN tells the driver to place the device in the low -power state requested. - -Whether suspend is called with a given level is a policy of the -platform. Some levels may be omitted; drivers must not assume the -reception of any level. However, all levels must be called in the -order above; i.e. notification will always come before disabling; -disabling the device will come before suspending the device. - -All calls are made with interrupts enabled, except for the -SUSPEND_POWER_DOWN level. - - int (*resume) (struct device * dev, u32 level); - -Resume is used to bring a device back from a low power state. Like the -suspend transition, it happens in several stages. - -RESUME_POWER_ON tells the driver to set the power state to the state -before the suspend call (The device could have already been in a low -power state before the suspend call to put in a lower power state). - -RESUME_RESTORE_STATE tells the driver to restore the state saved by -the SUSPEND_SAVE_STATE suspend call. + int (*suspend) (struct device * dev, pm_message_t state); -RESUME_ENABLE tells the driver to start accepting I/O transactions -again. Depending on driver policy, the device may already have pending -I/O requests. +suspend is called to put the device in a low power state. -RESUME_POWER_ON is called with interrupts disabled. The other resume -levels are called with interrupts enabled. + int (*resume) (struct device * dev); -As with the various suspend stages, the driver must not assume that -any other resume calls have been or will be made. Each call should be -self-contained and not dependent on any external state. +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 *, char * buf, size_t count, loff_t off); - ssize_t (*store)(struct device_driver *, const char * buf, size_t count, loff_t off); + 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. @@ -282,5 +210,5 @@ struct driver_attribute driver_attr_debug; This can then be used to add and remove the attribute from the driver's directory using: -int driver_create_file(struct device_driver *, struct driver_attribute *); -void driver_remove_file(struct device_driver *, 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 *); diff --git a/Documentation/driver-model/interface.txt b/Documentation/driver-model/interface.txt deleted file mode 100644 index c66912bfe86..00000000000 --- a/Documentation/driver-model/interface.txt +++ /dev/null @@ -1,129 +0,0 @@ - -Device Interfaces - -Introduction -~~~~~~~~~~~~ - -Device interfaces are the logical interfaces of device classes that correlate -directly to userspace interfaces, like device nodes. - -Each device class may have multiple interfaces through which you can -access the same device. An input device may support the mouse interface, -the 'evdev' interface, and the touchscreen interface. A SCSI disk would -support the disk interface, the SCSI generic interface, and possibly a raw -device interface. - -Device interfaces are registered with the class they belong to. As devices -are added to the class, they are added to each interface registered with -the class. The interface is responsible for determining whether the device -supports the interface or not. - - -Programming Interface -~~~~~~~~~~~~~~~~~~~~~ - -struct device_interface { - char * name; - rwlock_t lock; - u32 devnum; - struct device_class * devclass; - - struct list_head node; - struct driver_dir_entry dir; - - int (*add_device)(struct device *); - int (*add_device)(struct intf_data *); -}; - -int interface_register(struct device_interface *); -void interface_unregister(struct device_interface *); - - -An interface must specify the device class it belongs to. It is added -to that class's list of interfaces on registration. - - -Interfaces can be added to a device class at any time. Whenever it is -added, each device in the class is passed to the interface's -add_device callback. When an interface is removed, each device is -removed from the interface. - - -Devices -~~~~~~~ -Once a device is added to a device class, it is added to each -interface that is registered with the device class. The class -is expected to place a class-specific data structure in -struct device::class_data. The interface can use that (along with -other fields of struct device) to determine whether or not the driver -and/or device support that particular interface. - - -Data -~~~~ - -struct intf_data { - struct list_head node; - struct device_interface * intf; - struct device * dev; - u32 intf_num; -}; - -int interface_add_data(struct interface_data *); - -The interface is responsible for allocating and initializing a struct -intf_data and calling interface_add_data() to add it to the device's list -of interfaces it belongs to. This list will be iterated over when the device -is removed from the class (instead of all possible interfaces for a class). -This structure should probably be embedded in whatever per-device data -structure the interface is allocating anyway. - -Devices are enumerated within the interface. This happens in interface_add_data() -and the enumerated value is stored in the struct intf_data for that device. - -sysfs -~~~~~ -Each interface is given a directory in the directory of the device -class it belongs to: - -Interfaces get a directory in the class's directory as well: - - class/ - `-- input - |-- devices - |-- drivers - |-- mouse - `-- evdev - -When a device is added to the interface, a symlink is created that points -to the device's directory in the physical hierarchy: - - class/ - `-- input - |-- devices - | `-- 1 -> ../../../root/pci0/00:1f.0/usb_bus/00:1f.2-1:0/ - |-- drivers - | `-- usb:usb_mouse -> ../../../bus/drivers/usb_mouse/ - |-- mouse - | `-- 1 -> ../../../root/pci0/00:1f.0/usb_bus/00:1f.2-1:0/ - `-- evdev - `-- 1 -> ../../../root/pci0/00:1f.0/usb_bus/00:1f.2-1:0/ - - -Future Plans -~~~~~~~~~~~~ -A device interface is correlated directly with a userspace interface -for a device, specifically a device node. For instance, a SCSI disk -exposes at least two interfaces to userspace: the standard SCSI disk -interface and the SCSI generic interface. It might also export a raw -device interface. - -Many interfaces have a major number associated with them and each -device gets a minor number. Or, multiple interfaces might share one -major number, and each will receive a range of minor numbers (like in -the case of input devices). - -These major and minor numbers could be stored in the interface -structure. Major and minor allocations could happen when the interface -is registered with the class, or via a helper function. - diff --git a/Documentation/driver-model/overview.txt b/Documentation/driver-model/overview.txt index 44662735cf8..6a8f9a8075d 100644 --- a/Documentation/driver-model/overview.txt +++ b/Documentation/driver-model/overview.txt @@ -1,50 +1,43 @@ The Linux Kernel Device Model -Patrick Mochel <mochel@osdl.org> +Patrick Mochel <mochel@digitalimplant.org> -26 August 2002 +Drafted 26 August 2002 +Updated 31 January 2006 Overview ~~~~~~~~ -This driver model is a unification of all the current, disparate driver models -that are currently in the kernel. It is intended to augment the +The Linux Kernel Driver Model is a unification of all the disparate driver +models that were previously used in the kernel. It is intended to augment the bus-specific drivers for bridges and devices by consolidating a set of data and operations into globally accessible data structures. -Current driver models implement some sort of tree-like structure (sometimes -just a list) for the devices they control. But, there is no linkage between -the different bus types. +Traditional driver models implemented some sort of tree-like structure +(sometimes just a list) for the devices they control. There wasn't any +uniformity across the different bus types. -A common data structure can provide this linkage with little overhead: when a -bus driver discovers a particular device, it can insert it into the global -tree as well as its local tree. In fact, the local tree becomes just a subset -of the global tree. - -Common data fields can also be moved out of the local bus models into the -global model. Some of the manipulations of these fields can also be -consolidated. Most likely, manipulation functions will become a set -of helper functions, which the bus drivers wrap around to include any -bus-specific items. - -The common device and bridge interface currently reflects the goals of the -modern PC: namely the ability to do seamless Plug and Play, power management, -and hot plug. (The model dictated by Intel and Microsoft (read: ACPI) ensures -us that any device in the system may fit any of these criteria.) - -In reality, not every bus will be able to support such operations. But, most -buses will support a majority of those operations, and all future buses will. -In other words, a bus that doesn't support an operation is the exception, -instead of the other way around. +The current driver model provides a common, uniform data model for describing +a bus and the devices that can appear under the bus. The unified bus +model includes a set of common attributes which all busses carry, and a set +of common callbacks, such as device discovery during bus probing, bus +shutdown, bus power management, etc. +The common device and bridge interface reflects the goals of the modern +computer: namely the ability to do seamless device "plug and play", power +management, and hot plug. In particular, the model dictated by Intel and +Microsoft (namely ACPI) ensures that almost every device on almost any bus +on an x86-compatible system can work within this paradigm. Of course, +not every bus is able to support all such operations, although most +buses support most of those operations. Downstream Access ~~~~~~~~~~~~~~~~~ Common data fields have been moved out of individual bus layers into a common -data structure. But, these fields must still be accessed by the bus layers, +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. @@ -53,25 +46,29 @@ struct pci_dev now looks like this: struct pci_dev { ... - struct device device; + struct device dev; /* Generic device interface */ + ... }; -Note first that it is statically allocated. This means only one allocation on -device discovery. Note also that it is at the _end_ of struct pci_dev. This is -to make people think about what they're doing when switching between the bus -driver and the global driver; and to prevent against mindless casts between -the two. +Note first that the struct device dev within the struct pci_dev is +statically allocated. This means only one allocation on device discovery. + +Note also that that struct device dev is not necessarily defined at the +front of the pci_dev structure. This is to make people think about what +they're doing when switching between the bus driver and the global driver, +and to discourage meaningless and incorrect casts between the two. The PCI bus layer freely accesses the fields of struct device. It knows about the structure of struct pci_dev, and it should know the structure of struct -device. PCI devices that have been converted generally do not touch the fields -of struct device. More precisely, device-specific drivers should not touch -fields of struct device unless there is a strong compelling reason to do so. +device. Individual PCI device drivers that have been converted to the current +driver model generally do not and should not touch the fields of struct device, +unless there is a compelling reason to do so. -This abstraction is prevention of unnecessary pain during transitional phases. -If the name of the field changes or is removed, then every downstream driver -will break. On the other hand, if only the bus layer (and not the device -layer) accesses struct device, it is only that layer that needs to change. +The above abstraction prevents unnecessary pain during transitional phases. +If it were not done this way, then when a field was renamed or removed, every +downstream driver would break. On the other hand, if only the bus layer +(and not the device layer) accesses the struct device, it is only the bus +layer that needs to change. User Interface @@ -80,15 +77,27 @@ User Interface By virtue of having a complete hierarchical view of all the devices in the system, exporting a complete hierarchical view to userspace becomes relatively easy. This has been accomplished by implementing a special purpose virtual -file system named sysfs. It is hence possible for the user to mount the -whole sysfs filesystem anywhere in userspace. +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: + +$ 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: + +none /sys sysfs defaults 0 0 -This can be done permanently by providing the following entry into the -/etc/fstab (under the provision that the mount point does exist, of course): +or something similar in the /lib/init/fstab file on Debian-based systems: -none /sys sysfs defaults 0 0 +none /sys sysfs nodev,noexec,nosuid 0 0 -Or by hand on the command line: +If sysfs is not automatically mounted, you can always do it manually with: # mount -t sysfs sysfs /sys diff --git a/Documentation/driver-model/platform.txt b/Documentation/driver-model/platform.txt index 5eee3e0bfc4..07795ec51cd 100644 --- a/Documentation/driver-model/platform.txt +++ b/Documentation/driver-model/platform.txt @@ -1,99 +1,230 @@ 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, +like those used to integrate peripherals on many system-on-chip +processors, or some "legacy" PC interconnects; as opposed to large +formally specified ones like PCI or USB. + Platform devices ~~~~~~~~~~~~~~~~ Platform devices are devices that typically appear as autonomous entities in the system. This includes legacy port-based devices and -host bridges to peripheral buses. - - -Platform drivers -~~~~~~~~~~~~~~~~ -Drivers for platform devices are typically very simple and -unstructured. Either the device was present at a particular I/O port -and the driver was loaded, or it was not. There was no possibility -of hotplugging or alternative discovery besides probing at a specific -I/O address and expecting a specific response. +host bridges to peripheral buses, and most controllers integrated +into system-on-chip platforms. What they usually have in common +is direct addressing from a CPU bus. Rarely, a platform_device will +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. -Other Architectures, Modern Firmware, and new Platforms -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -These devices are not always at the legacy I/O ports. This is true on -other architectures and on some modern architectures. In most cases, -the drivers are modified to discover the devices at other well-known -ports for the given platform. However, the firmware in these systems -does usually know where exactly these devices reside, and in some -cases, it's the only way of discovering them. +struct platform_device { + const char *name; + u32 id; + struct device dev; + u32 num_resources; + struct resource *resource; +}; -The Platform Bus +Platform drivers ~~~~~~~~~~~~~~~~ -A platform bus has been created to deal with these issues. First and -foremost, it groups all the legacy devices under a common bus, and -gives them a common parent if they don't already have one. - -But, besides the organizational benefits, the platform bus can also -accommodate firmware-based enumeration. +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. + +struct platform_driver { + int (*probe)(struct platform_device *); + int (*remove)(struct platform_device *); + void (*shutdown)(struct platform_device *); + int (*suspend)(struct platform_device *, pm_message_t state); + int (*suspend_late)(struct platform_device *, pm_message_t state); + 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: + + 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: + + int platform_driver_probe(struct platform_driver *drv, + int (*probe)(struct platform_device *)) + + +Device Enumeration +~~~~~~~~~~~~~~~~~~ +As a rule, platform specific (and often board-specific) setup code will +register platform devices: + + int platform_device_register(struct platform_device *pdev); + int platform_add_devices(struct platform_device **pdevs, int ndev); + +The general rule is to register only those devices that actually exist, +but in some cases extra devices might be registered. For example, a kernel +might be configured to work with an external network adapter that might not +be populated on all boards, or likewise to work with an integrated controller +that some boards might not hook up to any peripherals. -Device Discovery -~~~~~~~~~~~~~~~~ -The platform bus has no concept of probing for devices. Devices -discovery is left up to either the legacy drivers or the -firmware. These entities are expected to notify the platform of -devices that it discovers via the bus's add() callback: - - platform_bus.add(parent,bus_id). - - -Bus IDs -~~~~~~~ -Bus IDs are the canonical names for the devices. There is no globally -standard addressing mechanism for legacy devices. In the IA-32 world, -we have Pnp IDs to use, as well as the legacy I/O ports. However, -neither tell what the device really is or have any meaning on other -platforms. - -Since both PnP IDs and the legacy I/O ports (and other standard I/O -ports for specific devices) have a 1:1 mapping, we map the -platform-specific name or identifier to a generic name (at least -within the scope of the kernel). - -For example, a serial driver might find a device at I/O 0x3f8. The -ACPI firmware might also discover a device with PnP ID (_HID) -PNP0501. Both correspond to the same device and should be mapped to the -canonical name 'serial'. - -The bus_id field should be a concatenation of the canonical name and -the instance of that type of device. For example, the device at I/O -port 0x3f8 should have a bus_id of "serial0". This places the -responsibility of enumerating devices of a particular type up to the -discovery mechanism. But, they are the entity that should know best -(as opposed to the platform bus driver). - - -Drivers -~~~~~~~ -Drivers for platform devices should have a name that is the same as -the canonical name of the devices they support. This allows the -platform bus driver to do simple matching with the basic data -structures to determine if a driver supports a certain device. - -For example, a legacy serial driver should have a name of 'serial' and -register itself with the platform bus. - - -Driver Binding -~~~~~~~~~~~~~~ -Legacy drivers assume they are bound to the device once they start up -and probe an I/O port. Divorcing them from this will be a difficult -process. However, that shouldn't prevent us from implementing -firmware-based enumeration. - -The firmware should notify the platform bus about devices before the -legacy drivers have had a chance to load. Once the drivers are loaded, -they driver model core will attempt to bind the driver to any -previously-discovered devices. Once that has happened, it will be free -to discover any other devices it pleases. - +In some cases, boot firmware will export tables describing the devices +that are populated on a given board. Without such tables, often the +only way for system setup code to set up the correct devices is to build +a kernel for a specific target board. Such board-specific kernels are +common with embedded and custom systems development. + +In many cases, the memory and IRQ resources associated with the platform +device are not enough to let the device's driver work. Board setup code +will often provide additional information using the device's platform_data +field to hold additional information. + +Embedded systems frequently need one or more clocks for platform devices, +which are normally kept off until they're actively needed (to save power). +System setup also associates those clocks with the device, so that that +calls to clk_get(&pdev->dev, clock_name) return them as needed. + + +Legacy Drivers: Device Probing +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Some drivers are not fully converted to the driver model, because they take +on a non-driver role: the driver registers its platform device, rather than +leaving that for system infrastructure. Such drivers can't be hotplugged +or coldplugged, since those mechanisms require device creation to be in a +different system component than the driver. + +The only "good" reason for this is to handle older system designs which, like +original IBM PCs, rely on error-prone "probe-the-hardware" models for hardware +configuration. Newer systems have largely abandoned that model, in favor of +bus-level support for dynamic configuration (PCI, USB), or device tables +provided by the boot firmware (e.g. PNPACPI on x86). There are too many +conflicting options about what might be where, and even educated guesses by +an operating system will be wrong often enough to make trouble. + +This style of driver is discouraged. If you're updating such a driver, +please try to move the device enumeration to a more appropriate location, +outside the driver. This will usually be cleanup, since such drivers +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. + + 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: + + struct platform_device *platform_device_register_simple( + const char *name, int id, + struct resource *res, unsigned int nres); + +You can use platform_device_register_simple() as a one-step call to allocate +and register a device. + + +Device Naming and Driver Binding +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +The platform_device.dev.bus_id is the canonical name for the devices. +It's built from two components: + + * platform_device.name ... which is also used to for driver matching. + + * platform_device.id ... the device instance number, or else "-1" + to indicate there's only one. + +These are concatenated, so name/id "serial"/0 indicates bus_id "serial.0", and +"serial/3" indicates bus_id "serial.3"; both would use the platform_driver +named "serial". While "my_rtc"/-1 would be bus_id "my_rtc" (no instance id) +and use the platform_driver called "my_rtc". + +Driver binding is performed automatically by the driver core, invoking +driver probe() after finding a match between device and driver. If the +probe() succeeds, the driver and device are bound as usual. There are +three different ways to find such a match: + + - Whenever a device is registered, the drivers for that bus are + checked for matches. Platform devices should be registered very + early during system boot. + + - When a driver is registered using platform_driver_register(), all + unbound devices on that bus are checked for matches. Drivers + usually register later during booting, or by module loading. + + - Registering a driver using platform_driver_probe() works just like + using platform_driver_register(), except that the driver won't + be probed later if another device registers. (Which is OK, since + this interface is only for use with non-hotpluggable devices.) + + +Early Platform Devices and Drivers +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +The early platform interfaces provide platform data to platform device +drivers early on during the system boot. The code is built on top of the +early_param() command line parsing and can be executed very early on. + +Example: "earlyprintk" class early serial console in 6 steps + +1. Registering early platform device data +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +The architecture code registers platform device data using the function +early_platform_add_devices(). In the case of early serial console this +should be hardware configuration for the serial port. Devices registered +at this point will later on be matched against early platform drivers. + +2. Parsing kernel command line +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +The architecture code calls parse_early_param() to parse the kernel +command line. This will execute all matching early_param() callbacks. +User specified early platform devices will be registered at this point. +For the early serial console case the user can specify port on the +kernel command line as "earlyprintk=serial.0" where "earlyprintk" is +the class string, "serial" is the name of the platform driver and +0 is the platform device id. If the id is -1 then the dot and the +id can be omitted. + +3. Installing early platform drivers belonging to a certain class +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +The architecture code may optionally force registration of all early +platform drivers belonging to a certain class using the function +early_platform_driver_register_all(). User specified devices from +step 2 have priority over these. This step is omitted by the serial +driver example since the early serial driver code should be disabled +unless the user has specified port on the kernel command line. + +4. Early platform driver registration +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Compiled-in platform drivers making use of early_platform_init() are +automatically registered during step 2 or 3. The serial driver example +should use early_platform_init("earlyprintk", &platform_driver). + +5. Probing of early platform drivers belonging to a certain class +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +The architecture code calls early_platform_driver_probe() to match +registered early platform devices associated with a certain class with +registered early platform drivers. Matched devices will get probed(). +This step can be executed at any point during the early boot. As soon +as possible may be good for the serial port case. + +6. Inside the early platform driver probe() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +The driver code needs to take special care during early boot, especially +when it comes to memory allocation and interrupt registration. The code +in the probe() function can use is_early_platform_device() to check if +it is called at early platform device or at the regular platform device +time. The early serial driver performs register_console() at this point. + +For further information, see <linux/platform_device.h>. diff --git a/Documentation/driver-model/porting.txt b/Documentation/driver-model/porting.txt index ff2fef2107f..92d86f7271b 100644 --- a/Documentation/driver-model/porting.txt +++ b/Documentation/driver-model/porting.txt @@ -92,7 +92,7 @@ struct device represents a single device. It mainly contains metadata describing the relationship the device has to other entities. -- Embedd a struct device in the bus-specific device type. +- Embed a struct device in the bus-specific device type. struct pci_dev { @@ -350,7 +350,7 @@ When a driver is registered, the bus's list of devices is iterated over. bus->match() is called for each device that is not already claimed by a driver. -When a device is successfully bound to a device, device->driver is +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: |
