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