1*4882a593Smuzhiyun========================== 2*4882a593SmuzhiyunThe Basic Device Structure 3*4882a593Smuzhiyun========================== 4*4882a593Smuzhiyun 5*4882a593SmuzhiyunSee the kerneldoc for the struct device. 6*4882a593Smuzhiyun 7*4882a593Smuzhiyun 8*4882a593SmuzhiyunProgramming Interface 9*4882a593Smuzhiyun~~~~~~~~~~~~~~~~~~~~~ 10*4882a593SmuzhiyunThe bus driver that discovers the device uses this to register the 11*4882a593Smuzhiyundevice with the core:: 12*4882a593Smuzhiyun 13*4882a593Smuzhiyun int device_register(struct device * dev); 14*4882a593Smuzhiyun 15*4882a593SmuzhiyunThe bus should initialize the following fields: 16*4882a593Smuzhiyun 17*4882a593Smuzhiyun - parent 18*4882a593Smuzhiyun - name 19*4882a593Smuzhiyun - bus_id 20*4882a593Smuzhiyun - bus 21*4882a593Smuzhiyun 22*4882a593SmuzhiyunA device is removed from the core when its reference count goes to 23*4882a593Smuzhiyun0. The reference count can be adjusted using:: 24*4882a593Smuzhiyun 25*4882a593Smuzhiyun struct device * get_device(struct device * dev); 26*4882a593Smuzhiyun void put_device(struct device * dev); 27*4882a593Smuzhiyun 28*4882a593Smuzhiyunget_device() will return a pointer to the struct device passed to it 29*4882a593Smuzhiyunif the reference is not already 0 (if it's in the process of being 30*4882a593Smuzhiyunremoved already). 31*4882a593Smuzhiyun 32*4882a593SmuzhiyunA driver can access the lock in the device structure using:: 33*4882a593Smuzhiyun 34*4882a593Smuzhiyun void lock_device(struct device * dev); 35*4882a593Smuzhiyun void unlock_device(struct device * dev); 36*4882a593Smuzhiyun 37*4882a593Smuzhiyun 38*4882a593SmuzhiyunAttributes 39*4882a593Smuzhiyun~~~~~~~~~~ 40*4882a593Smuzhiyun 41*4882a593Smuzhiyun:: 42*4882a593Smuzhiyun 43*4882a593Smuzhiyun struct device_attribute { 44*4882a593Smuzhiyun struct attribute attr; 45*4882a593Smuzhiyun ssize_t (*show)(struct device *dev, struct device_attribute *attr, 46*4882a593Smuzhiyun char *buf); 47*4882a593Smuzhiyun ssize_t (*store)(struct device *dev, struct device_attribute *attr, 48*4882a593Smuzhiyun const char *buf, size_t count); 49*4882a593Smuzhiyun }; 50*4882a593Smuzhiyun 51*4882a593SmuzhiyunAttributes of devices can be exported by a device driver through sysfs. 52*4882a593Smuzhiyun 53*4882a593SmuzhiyunPlease see Documentation/filesystems/sysfs.rst for more information 54*4882a593Smuzhiyunon how sysfs works. 55*4882a593Smuzhiyun 56*4882a593SmuzhiyunAs explained in Documentation/core-api/kobject.rst, device attributes must be 57*4882a593Smuzhiyuncreated before the KOBJ_ADD uevent is generated. The only way to realize 58*4882a593Smuzhiyunthat is by defining an attribute group. 59*4882a593Smuzhiyun 60*4882a593SmuzhiyunAttributes are declared using a macro called DEVICE_ATTR:: 61*4882a593Smuzhiyun 62*4882a593Smuzhiyun #define DEVICE_ATTR(name,mode,show,store) 63*4882a593Smuzhiyun 64*4882a593SmuzhiyunExample::: 65*4882a593Smuzhiyun 66*4882a593Smuzhiyun static DEVICE_ATTR(type, 0444, show_type, NULL); 67*4882a593Smuzhiyun static DEVICE_ATTR(power, 0644, show_power, store_power); 68*4882a593Smuzhiyun 69*4882a593SmuzhiyunThis declares two structures of type struct device_attribute with respective 70*4882a593Smuzhiyunnames 'dev_attr_type' and 'dev_attr_power'. These two attributes can be 71*4882a593Smuzhiyunorganized as follows into a group:: 72*4882a593Smuzhiyun 73*4882a593Smuzhiyun static struct attribute *dev_attrs[] = { 74*4882a593Smuzhiyun &dev_attr_type.attr, 75*4882a593Smuzhiyun &dev_attr_power.attr, 76*4882a593Smuzhiyun NULL, 77*4882a593Smuzhiyun }; 78*4882a593Smuzhiyun 79*4882a593Smuzhiyun static struct attribute_group dev_attr_group = { 80*4882a593Smuzhiyun .attrs = dev_attrs, 81*4882a593Smuzhiyun }; 82*4882a593Smuzhiyun 83*4882a593Smuzhiyun static const struct attribute_group *dev_attr_groups[] = { 84*4882a593Smuzhiyun &dev_attr_group, 85*4882a593Smuzhiyun NULL, 86*4882a593Smuzhiyun }; 87*4882a593Smuzhiyun 88*4882a593SmuzhiyunThis array of groups can then be associated with a device by setting the 89*4882a593Smuzhiyungroup pointer in struct device before device_register() is invoked:: 90*4882a593Smuzhiyun 91*4882a593Smuzhiyun dev->groups = dev_attr_groups; 92*4882a593Smuzhiyun device_register(dev); 93*4882a593Smuzhiyun 94*4882a593SmuzhiyunThe device_register() function will use the 'groups' pointer to create the 95*4882a593Smuzhiyundevice attributes and the device_unregister() function will use this pointer 96*4882a593Smuzhiyunto remove the device attributes. 97*4882a593Smuzhiyun 98*4882a593SmuzhiyunWord of warning: While the kernel allows device_create_file() and 99*4882a593Smuzhiyundevice_remove_file() to be called on a device at any time, userspace has 100*4882a593Smuzhiyunstrict expectations on when attributes get created. When a new device is 101*4882a593Smuzhiyunregistered in the kernel, a uevent is generated to notify userspace (like 102*4882a593Smuzhiyunudev) that a new device is available. If attributes are added after the 103*4882a593Smuzhiyundevice is registered, then userspace won't get notified and userspace will 104*4882a593Smuzhiyunnot know about the new attributes. 105*4882a593Smuzhiyun 106*4882a593SmuzhiyunThis is important for device driver that need to publish additional 107*4882a593Smuzhiyunattributes for a device at driver probe time. If the device driver simply 108*4882a593Smuzhiyuncalls device_create_file() on the device structure passed to it, then 109*4882a593Smuzhiyunuserspace will never be notified of the new attributes. 110