diff options
Diffstat (limited to 'Documentation/driver-api/driver-model')
-rw-r--r-- | Documentation/driver-api/driver-model/bus.rst | 4 | ||||
-rw-r--r-- | Documentation/driver-api/driver-model/class.rst | 149 | ||||
-rw-r--r-- | Documentation/driver-api/driver-model/device.rst | 27 | ||||
-rw-r--r-- | Documentation/driver-api/driver-model/devres.rst | 90 | ||||
-rw-r--r-- | Documentation/driver-api/driver-model/driver.rst | 32 | ||||
-rw-r--r-- | Documentation/driver-api/driver-model/index.rst | 1 | ||||
-rw-r--r-- | Documentation/driver-api/driver-model/overview.rst | 2 | ||||
-rw-r--r-- | Documentation/driver-api/driver-model/platform.rst | 2 |
8 files changed, 117 insertions, 190 deletions
diff --git a/Documentation/driver-api/driver-model/bus.rst b/Documentation/driver-api/driver-model/bus.rst index 016b15a6e8ea..9709ab62a468 100644 --- a/Documentation/driver-api/driver-model/bus.rst +++ b/Documentation/driver-api/driver-model/bus.rst @@ -125,8 +125,8 @@ Exporting Attributes 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); + ssize_t (*show)(const struct bus_type *, char * buf); + ssize_t (*store)(const struct bus_type *, const char * buf, size_t count); }; Bus drivers can export attributes using the BUS_ATTR_RW macro that works diff --git a/Documentation/driver-api/driver-model/class.rst b/Documentation/driver-api/driver-model/class.rst deleted file mode 100644 index fff55b80e86a..000000000000 --- a/Documentation/driver-api/driver-model/class.rst +++ /dev/null @@ -1,149 +0,0 @@ -============== -Device Classes -============== - -Introduction -~~~~~~~~~~~~ -A device class describes a type of device, like an audio or network -device. The following device classes have been identified: - -<Insert List of Device Classes Here> - - -Each device class defines a set of semantics and a programming interface -that devices of that class adhere to. Device drivers are the -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 -on. - - -Programming Interface -~~~~~~~~~~~~~~~~~~~~~ -The device class structure looks like:: - - - 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:: - - 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:: - - int devclass_register(struct device_class * cls); - void devclass_unregister(struct device_class * cls); - - -Devices -~~~~~~~ -As devices are bound to drivers, they are added to the device class -that the driver belongs to. Before the driver model core, this would -typically happen during the driver's probe() callback, once the device -has been initialized. It now happens after the probe() callback -finishes from the core. - -The device is enumerated in the class. Each time a device is added to -the class, the class's devnum field is incremented and assigned to the -device. The field is never decremented, so if the device is removed -from the class and re-added, it will receive a different enumerated -value. - -The class is allowed to create a class-specific structure for the -device and store it in the device's class_data pointer. - -There is no list of devices in the device class. Each driver has a -list of devices that it supports. The device class has a list of -drivers of that particular class. To access all of the devices in the -class, iterate over the device lists of each driver in the class. - - -Device Drivers -~~~~~~~~~~~~~~ -Device drivers are added to device classes when they are registered -with the core. A driver specifies the class it belongs to by setting -the struct device_driver::devclass field. - - -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:: - - class/ - `-- input - |-- devices - `-- drivers - - -Drivers registered with the class get a symlink in the drivers/ directory -that points to the driver's directory (under its bus directory):: - - class/ - `-- input - |-- devices - `-- drivers - `-- usb:usb_mouse -> ../../../bus/drivers/usb_mouse/ - - -Each device gets a symlink in the devices/ directory 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 - - -Exporting Attributes -~~~~~~~~~~~~~~~~~~~~ - -:: - - 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:: - - static DEVCLASS_ATTR(debug,0644,show_debug,store_debug); - -is equivalent to declaring:: - - static devclass_attribute devclass_attr_debug; - -The bus driver can add and remove the attribute from the class's -sysfs directory using:: - - 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. - - -Interfaces -~~~~~~~~~~ -There may exist multiple mechanisms for accessing the same device of a -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. diff --git a/Documentation/driver-api/driver-model/device.rst b/Documentation/driver-api/driver-model/device.rst index 2b868d49d349..0833be568b06 100644 --- a/Documentation/driver-api/driver-model/device.rst +++ b/Documentation/driver-api/driver-model/device.rst @@ -50,10 +50,10 @@ Attributes Attributes of devices can be exported by a device driver through sysfs. -Please see Documentation/filesystems/sysfs.txt for more information +Please see Documentation/filesystems/sysfs.rst for more information on how sysfs works. -As explained in Documentation/kobject.txt, device attributes must be +As explained in Documentation/core-api/kobject.rst, device attributes must be created before the KOBJ_ADD uevent is generated. The only way to realize that is by defining an attribute group. @@ -63,8 +63,14 @@ Attributes are declared using a macro called DEVICE_ATTR:: Example::: - static DEVICE_ATTR(type, 0444, show_type, NULL); - static DEVICE_ATTR(power, 0644, show_power, store_power); + static DEVICE_ATTR(type, 0444, type_show, NULL); + static DEVICE_ATTR(power, 0644, power_show, power_store); + +Helper macros are available for common values of mode, so the above examples +can be simplified to::: + + static DEVICE_ATTR_RO(type); + static DEVICE_ATTR_RW(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 @@ -76,19 +82,24 @@ organized as follows into a group:: NULL, }; - static struct attribute_group dev_attr_group = { + static struct attribute_group dev_group = { .attrs = dev_attrs, }; - static const struct attribute_group *dev_attr_groups[] = { - &dev_attr_group, + static const struct attribute_group *dev_groups[] = { + &dev_group, NULL, }; +A helper macro is available for the common case of a single group, so the +above two structures can be declared using::: + + ATTRIBUTE_GROUPS(dev); + 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; + dev->groups = dev_groups; device_register(dev); The device_register() function will use the 'groups' pointer to create the diff --git a/Documentation/driver-api/driver-model/devres.rst b/Documentation/driver-api/driver-model/devres.rst index 13046fcf0a5d..7be8b8dd5f00 100644 --- a/Documentation/driver-api/driver-model/devres.rst +++ b/Documentation/driver-api/driver-model/devres.rst @@ -249,7 +249,7 @@ CLOCK devm_clk_bulk_get() devm_clk_bulk_get_all() devm_clk_bulk_get_optional() - devm_get_clk_from_childl() + devm_get_clk_from_child() devm_clk_hw_register() devm_of_clk_add_hw_provider() devm_clk_hw_register_clkdev() @@ -263,10 +263,12 @@ DMA dmam_pool_destroy() DRM - devm_drm_dev_init() + devm_drm_dev_alloc() GPIO devm_gpiod_get() + devm_gpiod_get_array() + devm_gpiod_get_array_optional() devm_gpiod_get_index() devm_gpiod_get_index_optional() devm_gpiod_get_optional() @@ -275,28 +277,26 @@ GPIO devm_gpiochip_add_data() devm_gpio_request() devm_gpio_request_one() - devm_gpio_free() I2C + devm_i2c_add_adapter() devm_i2c_new_dummy_device() IIO devm_iio_device_alloc() - devm_iio_device_free() devm_iio_device_register() - devm_iio_device_unregister() - devm_iio_kfifo_allocate() - devm_iio_kfifo_free() + devm_iio_dmaengine_buffer_setup() + devm_iio_kfifo_buffer_setup() + devm_iio_kfifo_buffer_setup_ext() + devm_iio_map_array_register() devm_iio_triggered_buffer_setup() - devm_iio_triggered_buffer_cleanup() + devm_iio_triggered_buffer_setup_ext() devm_iio_trigger_alloc() - devm_iio_trigger_free() devm_iio_trigger_register() - devm_iio_trigger_unregister() devm_iio_channel_get() - devm_iio_channel_release() devm_iio_channel_get_all() - devm_iio_channel_release_all() + devm_iio_hw_consumer_alloc() + devm_fwnode_iio_channel_get_by_name() INPUT devm_input_allocate_device() @@ -306,6 +306,7 @@ IO region devm_release_region() devm_release_resource() devm_request_mem_region() + devm_request_free_mem_region() devm_request_region() devm_request_resource() @@ -313,19 +314,16 @@ IOMAP devm_ioport_map() devm_ioport_unmap() devm_ioremap() - devm_ioremap_nocache() devm_ioremap_uc() devm_ioremap_wc() devm_ioremap_resource() : checks resource, requests memory region, ioremaps devm_ioremap_resource_wc() devm_platform_ioremap_resource() : calls devm_ioremap_resource() for platform device - devm_platform_ioremap_resource_wc() devm_platform_ioremap_resource_byname() + devm_platform_get_and_ioremap_resource() devm_iounmap() - pcim_iomap() - pcim_iomap_regions() : do request_region() and iomap() on multiple BARs - pcim_iomap_table() : array of mapped addresses indexed by BAR - pcim_iounmap() + + Note: For the PCI devices the specific pcim_*() functions may be used, see below. IRQ devm_free_irq() @@ -339,16 +337,20 @@ IRQ devm_irq_alloc_descs_from() devm_irq_alloc_generic_chip() devm_irq_setup_generic_chip() - devm_irq_sim_init() + devm_irq_domain_create_sim() LED devm_led_classdev_register() + devm_led_classdev_register_ext() devm_led_classdev_unregister() + devm_led_trigger_register() + devm_of_led_get() MDIO devm_mdiobus_alloc() devm_mdiobus_alloc_size() - devm_mdiobus_free() + devm_mdiobus_register() + devm_of_mdiobus_register() MEM devm_free_pages() @@ -359,7 +361,10 @@ MEM devm_kmalloc() devm_kmalloc_array() devm_kmemdup() + devm_krealloc() + devm_krealloc_array() devm_kstrdup() + devm_kstrdup_const() devm_kvasprintf() devm_kzalloc() @@ -370,6 +375,12 @@ MUX devm_mux_chip_alloc() devm_mux_chip_register() devm_mux_control_get() + devm_mux_state_get() + +NET + devm_alloc_etherdev() + devm_alloc_etherdev_mqs() + devm_register_netdev() PER-CPU MEM devm_alloc_percpu() @@ -379,17 +390,29 @@ PCI devm_pci_alloc_host_bridge() : managed PCI host bridge allocation devm_pci_remap_cfgspace() : ioremap PCI configuration space devm_pci_remap_cfg_resource() : ioremap PCI configuration space resource + pcim_enable_device() : after success, all PCI ops become managed + pcim_iomap() : do iomap() on a single BAR + pcim_iomap_regions() : do request_region() and iomap() on multiple BARs + pcim_iomap_regions_request_all() : do request_region() on all and iomap() on multiple BARs + pcim_iomap_table() : array of mapped addresses indexed by BAR + pcim_iounmap() : do iounmap() on a single BAR + pcim_iounmap_regions() : do iounmap() and release_region() on multiple BARs pcim_pin_device() : keep PCI device enabled after release + pcim_set_mwi() : enable Memory-Write-Invalidate PCI transaction PHY devm_usb_get_phy() + devm_usb_get_phy_by_node() + devm_usb_get_phy_by_phandle() devm_usb_put_phy() PINCTRL devm_pinctrl_get() devm_pinctrl_put() + devm_pinctrl_get_select() devm_pinctrl_register() + devm_pinctrl_register_and_init() devm_pinctrl_unregister() POWER @@ -397,27 +420,50 @@ POWER devm_reboot_mode_unregister() PWM + devm_pwmchip_alloc() + devm_pwmchip_add() devm_pwm_get() - devm_pwm_put() + devm_fwnode_pwm_get() REGULATOR + devm_regulator_bulk_register_supply_alias() devm_regulator_bulk_get() + devm_regulator_bulk_get_const() + devm_regulator_bulk_get_enable() + devm_regulator_bulk_put() devm_regulator_get() + devm_regulator_get_enable() + devm_regulator_get_enable_optional() + devm_regulator_get_exclusive() + devm_regulator_get_optional() + devm_regulator_irq_helper() devm_regulator_put() devm_regulator_register() + devm_regulator_register_notifier() + devm_regulator_register_supply_alias() + devm_regulator_unregister_notifier() RESET devm_reset_control_get() devm_reset_controller_register() +RTC + devm_rtc_device_register() + devm_rtc_allocate_device() + devm_rtc_register_device() + devm_rtc_nvmem_register() + SERDEV devm_serdev_device_open() SLAVE DMA ENGINE devm_acpi_dma_controller_register() + devm_acpi_dma_controller_free() SPI - devm_spi_register_master() + devm_spi_alloc_master() + devm_spi_alloc_slave() + devm_spi_register_controller() WATCHDOG devm_watchdog_register_device() diff --git a/Documentation/driver-api/driver-model/driver.rst b/Documentation/driver-api/driver-model/driver.rst index baa6a85c8287..06f818b1d622 100644 --- a/Documentation/driver-api/driver-model/driver.rst +++ b/Documentation/driver-api/driver-model/driver.rst @@ -4,7 +4,6 @@ Device Drivers See the kerneldoc for the struct device_driver. - Allocation ~~~~~~~~~~ @@ -167,9 +166,26 @@ 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. + +Optionally, probe() may return -EPROBE_DEFER if the driver depends on +resources that are not yet available (e.g., supplied by a driver that +hasn't initialized yet). The driver core will put the device onto the +deferred probe list and will try to call it again later. If a driver +must defer, it should return -EPROBE_DEFER as early as possible to +reduce the amount of time spent on setup work that will need to be +unwound and reexecuted at a later time. + +.. warning:: + -EPROBE_DEFER must not be returned if probe() has already created + child devices, even if those child devices are removed again + in a cleanup path. If -EPROBE_DEFER is returned after a child + device has been registered, it may result in an infinite loop of + .probe() calls to the same driver. + +:: - void (*sync_state)(struct device *dev); + void (*sync_state) (struct device *dev); sync_state is called only once for a device. It's called when all the consumer devices of the device have successfully probed. The list of consumers of the @@ -210,7 +226,7 @@ probed. While the typical use case for sync_state() is to have the kernel cleanly take over management of devices from the bootloader, the usage of sync_state() is not restricted to that. Use it whenever it makes sense to take an action after -all the consumers of a device have probed. +all the consumers of a device have probed:: int (*remove) (struct device *dev); @@ -224,11 +240,15 @@ 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); -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); diff --git a/Documentation/driver-api/driver-model/index.rst b/Documentation/driver-api/driver-model/index.rst index 755016422269..4831bdd92e5c 100644 --- a/Documentation/driver-api/driver-model/index.rst +++ b/Documentation/driver-api/driver-model/index.rst @@ -7,7 +7,6 @@ Driver Model binding bus - class design-patterns device devres diff --git a/Documentation/driver-api/driver-model/overview.rst b/Documentation/driver-api/driver-model/overview.rst index d4d1e9b40e0c..e98d0ab4a9b6 100644 --- a/Documentation/driver-api/driver-model/overview.rst +++ b/Documentation/driver-api/driver-model/overview.rst @@ -121,4 +121,4 @@ 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. +Documentation/filesystems/sysfs.rst. diff --git a/Documentation/driver-api/driver-model/platform.rst b/Documentation/driver-api/driver-model/platform.rst index 334dd4071ae4..1fe5c6c6199c 100644 --- a/Documentation/driver-api/driver-model/platform.rst +++ b/Documentation/driver-api/driver-model/platform.rst @@ -108,7 +108,7 @@ 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 +System setup also associates those clocks with the device, so that calls to clk_get(&pdev->dev, clock_name) return them as needed. |