1fe34c89dSMauro Carvalho Chehab==========================
2fe34c89dSMauro Carvalho ChehabThe Basic Device Structure
3fe34c89dSMauro Carvalho Chehab==========================
4fe34c89dSMauro Carvalho Chehab
5fe34c89dSMauro Carvalho ChehabSee the kerneldoc for the struct device.
6fe34c89dSMauro Carvalho Chehab
7fe34c89dSMauro Carvalho Chehab
8fe34c89dSMauro Carvalho ChehabProgramming Interface
9fe34c89dSMauro Carvalho Chehab~~~~~~~~~~~~~~~~~~~~~
10fe34c89dSMauro Carvalho ChehabThe bus driver that discovers the device uses this to register the
11fe34c89dSMauro Carvalho Chehabdevice with the core::
12fe34c89dSMauro Carvalho Chehab
13fe34c89dSMauro Carvalho Chehab  int device_register(struct device * dev);
14fe34c89dSMauro Carvalho Chehab
15fe34c89dSMauro Carvalho ChehabThe bus should initialize the following fields:
16fe34c89dSMauro Carvalho Chehab
17fe34c89dSMauro Carvalho Chehab    - parent
18fe34c89dSMauro Carvalho Chehab    - name
19fe34c89dSMauro Carvalho Chehab    - bus_id
20fe34c89dSMauro Carvalho Chehab    - bus
21fe34c89dSMauro Carvalho Chehab
22fe34c89dSMauro Carvalho ChehabA device is removed from the core when its reference count goes to
23fe34c89dSMauro Carvalho Chehab0. The reference count can be adjusted using::
24fe34c89dSMauro Carvalho Chehab
25fe34c89dSMauro Carvalho Chehab  struct device * get_device(struct device * dev);
26fe34c89dSMauro Carvalho Chehab  void put_device(struct device * dev);
27fe34c89dSMauro Carvalho Chehab
28fe34c89dSMauro Carvalho Chehabget_device() will return a pointer to the struct device passed to it
29fe34c89dSMauro Carvalho Chehabif the reference is not already 0 (if it's in the process of being
30fe34c89dSMauro Carvalho Chehabremoved already).
31fe34c89dSMauro Carvalho Chehab
32fe34c89dSMauro Carvalho ChehabA driver can access the lock in the device structure using::
33fe34c89dSMauro Carvalho Chehab
34fe34c89dSMauro Carvalho Chehab  void lock_device(struct device * dev);
35fe34c89dSMauro Carvalho Chehab  void unlock_device(struct device * dev);
36fe34c89dSMauro Carvalho Chehab
37fe34c89dSMauro Carvalho Chehab
38fe34c89dSMauro Carvalho ChehabAttributes
39fe34c89dSMauro Carvalho Chehab~~~~~~~~~~
40fe34c89dSMauro Carvalho Chehab
41fe34c89dSMauro Carvalho Chehab::
42fe34c89dSMauro Carvalho Chehab
43fe34c89dSMauro Carvalho Chehab  struct device_attribute {
44fe34c89dSMauro Carvalho Chehab	struct attribute	attr;
45fe34c89dSMauro Carvalho Chehab	ssize_t (*show)(struct device *dev, struct device_attribute *attr,
46fe34c89dSMauro Carvalho Chehab			char *buf);
47fe34c89dSMauro Carvalho Chehab	ssize_t (*store)(struct device *dev, struct device_attribute *attr,
48fe34c89dSMauro Carvalho Chehab			 const char *buf, size_t count);
49fe34c89dSMauro Carvalho Chehab  };
50fe34c89dSMauro Carvalho Chehab
51fe34c89dSMauro Carvalho ChehabAttributes of devices can be exported by a device driver through sysfs.
52fe34c89dSMauro Carvalho Chehab
530c1bc6b8SMauro Carvalho ChehabPlease see Documentation/filesystems/sysfs.rst for more information
54fe34c89dSMauro Carvalho Chehabon how sysfs works.
55fe34c89dSMauro Carvalho Chehab
560c1bc6b8SMauro Carvalho ChehabAs explained in Documentation/core-api/kobject.rst, device attributes must be
57fe34c89dSMauro Carvalho Chehabcreated before the KOBJ_ADD uevent is generated. The only way to realize
58fe34c89dSMauro Carvalho Chehabthat is by defining an attribute group.
59fe34c89dSMauro Carvalho Chehab
60fe34c89dSMauro Carvalho ChehabAttributes are declared using a macro called DEVICE_ATTR::
61fe34c89dSMauro Carvalho Chehab
62fe34c89dSMauro Carvalho Chehab  #define DEVICE_ATTR(name,mode,show,store)
63fe34c89dSMauro Carvalho Chehab
64fe34c89dSMauro Carvalho ChehabExample:::
65fe34c89dSMauro Carvalho Chehab
66d944f0b1SGeert Uytterhoeven  static DEVICE_ATTR(type, 0444, type_show, NULL);
67d944f0b1SGeert Uytterhoeven  static DEVICE_ATTR(power, 0644, power_show, power_store);
68d944f0b1SGeert Uytterhoeven
69d944f0b1SGeert UytterhoevenHelper macros are available for common values of mode, so the above examples
70d944f0b1SGeert Uytterhoevencan be simplified to:::
71d944f0b1SGeert Uytterhoeven
72d944f0b1SGeert Uytterhoeven  static DEVICE_ATTR_RO(type);
73d944f0b1SGeert Uytterhoeven  static DEVICE_ATTR_RW(power);
74fe34c89dSMauro Carvalho Chehab
75fe34c89dSMauro Carvalho ChehabThis declares two structures of type struct device_attribute with respective
76fe34c89dSMauro Carvalho Chehabnames 'dev_attr_type' and 'dev_attr_power'. These two attributes can be
77fe34c89dSMauro Carvalho Chehaborganized as follows into a group::
78fe34c89dSMauro Carvalho Chehab
79fe34c89dSMauro Carvalho Chehab  static struct attribute *dev_attrs[] = {
80fe34c89dSMauro Carvalho Chehab	&dev_attr_type.attr,
81fe34c89dSMauro Carvalho Chehab	&dev_attr_power.attr,
82fe34c89dSMauro Carvalho Chehab	NULL,
83fe34c89dSMauro Carvalho Chehab  };
84fe34c89dSMauro Carvalho Chehab
85*459d7ed8SGeert Uytterhoeven  static struct attribute_group dev_group = {
86fe34c89dSMauro Carvalho Chehab	.attrs = dev_attrs,
87fe34c89dSMauro Carvalho Chehab  };
88fe34c89dSMauro Carvalho Chehab
89*459d7ed8SGeert Uytterhoeven  static const struct attribute_group *dev_groups[] = {
90*459d7ed8SGeert Uytterhoeven	&dev_group,
91fe34c89dSMauro Carvalho Chehab	NULL,
92fe34c89dSMauro Carvalho Chehab  };
93fe34c89dSMauro Carvalho Chehab
94*459d7ed8SGeert UytterhoevenA helper macro is available for the common case of a single group, so the
95*459d7ed8SGeert Uytterhoevenabove two structures can be declared using:::
96*459d7ed8SGeert Uytterhoeven
97*459d7ed8SGeert Uytterhoeven  ATTRIBUTE_GROUPS(dev);
98*459d7ed8SGeert Uytterhoeven
99fe34c89dSMauro Carvalho ChehabThis array of groups can then be associated with a device by setting the
100fe34c89dSMauro Carvalho Chehabgroup pointer in struct device before device_register() is invoked::
101fe34c89dSMauro Carvalho Chehab
102*459d7ed8SGeert Uytterhoeven        dev->groups = dev_groups;
103fe34c89dSMauro Carvalho Chehab        device_register(dev);
104fe34c89dSMauro Carvalho Chehab
105fe34c89dSMauro Carvalho ChehabThe device_register() function will use the 'groups' pointer to create the
106fe34c89dSMauro Carvalho Chehabdevice attributes and the device_unregister() function will use this pointer
107fe34c89dSMauro Carvalho Chehabto remove the device attributes.
108fe34c89dSMauro Carvalho Chehab
109fe34c89dSMauro Carvalho ChehabWord of warning:  While the kernel allows device_create_file() and
110fe34c89dSMauro Carvalho Chehabdevice_remove_file() to be called on a device at any time, userspace has
111fe34c89dSMauro Carvalho Chehabstrict expectations on when attributes get created.  When a new device is
112fe34c89dSMauro Carvalho Chehabregistered in the kernel, a uevent is generated to notify userspace (like
113fe34c89dSMauro Carvalho Chehabudev) that a new device is available.  If attributes are added after the
114fe34c89dSMauro Carvalho Chehabdevice is registered, then userspace won't get notified and userspace will
115fe34c89dSMauro Carvalho Chehabnot know about the new attributes.
116fe34c89dSMauro Carvalho Chehab
117fe34c89dSMauro Carvalho ChehabThis is important for device driver that need to publish additional
118fe34c89dSMauro Carvalho Chehabattributes for a device at driver probe time.  If the device driver simply
119fe34c89dSMauro Carvalho Chehabcalls device_create_file() on the device structure passed to it, then
120fe34c89dSMauro Carvalho Chehabuserspace will never be notified of the new attributes.
121