blob: 0833be568b06cacefbeb39e200103946d6f68b2b [file] [log] [blame]
Mauro Carvalho Chehab4489f1612019-06-18 17:53:27 -03001==========================
Linus Torvalds1da177e2005-04-16 15:20:36 -07002The Basic Device Structure
Mauro Carvalho Chehab4489f1612019-06-18 17:53:27 -03003==========================
Linus Torvalds1da177e2005-04-16 15:20:36 -07004
Wanlong Gao63dc3552011-05-05 07:55:37 +08005See the kerneldoc for the struct device.
Linus Torvalds1da177e2005-04-16 15:20:36 -07006
7
8Programming Interface
9~~~~~~~~~~~~~~~~~~~~~
10The bus driver that discovers the device uses this to register the
Mauro Carvalho Chehab4489f1612019-06-18 17:53:27 -030011device with the core::
Linus Torvalds1da177e2005-04-16 15:20:36 -070012
Mauro Carvalho Chehab4489f1612019-06-18 17:53:27 -030013 int device_register(struct device * dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -070014
15The bus should initialize the following fields:
16
17 - parent
18 - name
19 - bus_id
20 - bus
21
22A device is removed from the core when its reference count goes to
Mauro Carvalho Chehab4489f1612019-06-18 17:53:27 -0300230. The reference count can be adjusted using::
Linus Torvalds1da177e2005-04-16 15:20:36 -070024
Mauro Carvalho Chehab4489f1612019-06-18 17:53:27 -030025 struct device * get_device(struct device * dev);
26 void put_device(struct device * dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -070027
28get_device() will return a pointer to the struct device passed to it
29if the reference is not already 0 (if it's in the process of being
30removed already).
31
Mauro Carvalho Chehab4489f1612019-06-18 17:53:27 -030032A driver can access the lock in the device structure using::
Linus Torvalds1da177e2005-04-16 15:20:36 -070033
Mauro Carvalho Chehab4489f1612019-06-18 17:53:27 -030034 void lock_device(struct device * dev);
35 void unlock_device(struct device * dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -070036
37
38Attributes
39~~~~~~~~~~
Mauro Carvalho Chehab4489f1612019-06-18 17:53:27 -030040
41::
42
43 struct device_attribute {
Mike Murphy245127d2009-02-22 01:17:14 -050044 struct attribute attr;
45 ssize_t (*show)(struct device *dev, struct device_attribute *attr,
46 char *buf);
47 ssize_t (*store)(struct device *dev, struct device_attribute *attr,
48 const char *buf, size_t count);
Mauro Carvalho Chehab4489f1612019-06-18 17:53:27 -030049 };
Linus Torvalds1da177e2005-04-16 15:20:36 -070050
Bart Van Assched58cb9c2011-08-23 19:27:27 +020051Attributes of devices can be exported by a device driver through sysfs.
Linus Torvalds1da177e2005-04-16 15:20:36 -070052
Mauro Carvalho Chehab0c1bc6b2020-04-14 18:48:37 +020053Please see Documentation/filesystems/sysfs.rst for more information
Linus Torvalds1da177e2005-04-16 15:20:36 -070054on how sysfs works.
55
Mauro Carvalho Chehab0c1bc6b2020-04-14 18:48:37 +020056As explained in Documentation/core-api/kobject.rst, device attributes must be
Bart Van Assched58cb9c2011-08-23 19:27:27 +020057created before the KOBJ_ADD uevent is generated. The only way to realize
58that is by defining an attribute group.
59
Mauro Carvalho Chehab4489f1612019-06-18 17:53:27 -030060Attributes are declared using a macro called DEVICE_ATTR::
Linus Torvalds1da177e2005-04-16 15:20:36 -070061
Mauro Carvalho Chehab4489f1612019-06-18 17:53:27 -030062 #define DEVICE_ATTR(name,mode,show,store)
Linus Torvalds1da177e2005-04-16 15:20:36 -070063
Mauro Carvalho Chehab4489f1612019-06-18 17:53:27 -030064Example:::
Linus Torvalds1da177e2005-04-16 15:20:36 -070065
Geert Uytterhoevend944f0b2021-03-03 14:38:44 +010066 static DEVICE_ATTR(type, 0444, type_show, NULL);
67 static DEVICE_ATTR(power, 0644, power_show, power_store);
68
69Helper macros are available for common values of mode, so the above examples
70can be simplified to:::
71
72 static DEVICE_ATTR_RO(type);
73 static DEVICE_ATTR_RW(power);
Linus Torvalds1da177e2005-04-16 15:20:36 -070074
Bart Van Assched58cb9c2011-08-23 19:27:27 +020075This declares two structures of type struct device_attribute with respective
76names 'dev_attr_type' and 'dev_attr_power'. These two attributes can be
Mauro Carvalho Chehab4489f1612019-06-18 17:53:27 -030077organized as follows into a group::
Linus Torvalds1da177e2005-04-16 15:20:36 -070078
Mauro Carvalho Chehab4489f1612019-06-18 17:53:27 -030079 static struct attribute *dev_attrs[] = {
Bart Van Assched58cb9c2011-08-23 19:27:27 +020080 &dev_attr_type.attr,
81 &dev_attr_power.attr,
82 NULL,
Mauro Carvalho Chehab4489f1612019-06-18 17:53:27 -030083 };
Linus Torvalds1da177e2005-04-16 15:20:36 -070084
Geert Uytterhoeven459d7ed2021-03-03 14:38:45 +010085 static struct attribute_group dev_group = {
Bart Van Assched58cb9c2011-08-23 19:27:27 +020086 .attrs = dev_attrs,
Mauro Carvalho Chehab4489f1612019-06-18 17:53:27 -030087 };
Linus Torvalds1da177e2005-04-16 15:20:36 -070088
Geert Uytterhoeven459d7ed2021-03-03 14:38:45 +010089 static const struct attribute_group *dev_groups[] = {
90 &dev_group,
Bart Van Assched58cb9c2011-08-23 19:27:27 +020091 NULL,
Mauro Carvalho Chehab4489f1612019-06-18 17:53:27 -030092 };
Linus Torvalds1da177e2005-04-16 15:20:36 -070093
Geert Uytterhoeven459d7ed2021-03-03 14:38:45 +010094A helper macro is available for the common case of a single group, so the
95above two structures can be declared using:::
96
97 ATTRIBUTE_GROUPS(dev);
98
Bart Van Assched58cb9c2011-08-23 19:27:27 +020099This array of groups can then be associated with a device by setting the
Mauro Carvalho Chehab4489f1612019-06-18 17:53:27 -0300100group pointer in struct device before device_register() is invoked::
Bart Van Assched58cb9c2011-08-23 19:27:27 +0200101
Geert Uytterhoeven459d7ed2021-03-03 14:38:45 +0100102 dev->groups = dev_groups;
Mauro Carvalho Chehab4489f1612019-06-18 17:53:27 -0300103 device_register(dev);
Bart Van Assched58cb9c2011-08-23 19:27:27 +0200104
105The device_register() function will use the 'groups' pointer to create the
106device attributes and the device_unregister() function will use this pointer
107to remove the device attributes.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700108
Grant Likelyb22813b2009-03-06 14:05:39 -0700109Word of warning: While the kernel allows device_create_file() and
110device_remove_file() to be called on a device at any time, userspace has
111strict expectations on when attributes get created. When a new device is
112registered in the kernel, a uevent is generated to notify userspace (like
113udev) that a new device is available. If attributes are added after the
114device is registered, then userspace won't get notified and userspace will
115not know about the new attributes.
116
117This is important for device driver that need to publish additional
118attributes for a device at driver probe time. If the device driver simply
119calls device_create_file() on the device structure passed to it, then
Bart Van Assched58cb9c2011-08-23 19:27:27 +0200120userspace will never be notified of the new attributes.