Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | |
2 | The Basic Device Structure | |
3 | ~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
4 | ||
5 | struct device { | |
6 | struct list_head g_list; | |
7 | struct list_head node; | |
8 | struct list_head bus_list; | |
9 | struct list_head driver_list; | |
10 | struct list_head intf_list; | |
11 | struct list_head children; | |
12 | struct device * parent; | |
13 | ||
14 | char name[DEVICE_NAME_SIZE]; | |
15 | char bus_id[BUS_ID_SIZE]; | |
16 | ||
17 | spinlock_t lock; | |
18 | atomic_t refcount; | |
19 | ||
20 | struct bus_type * bus; | |
21 | struct driver_dir_entry dir; | |
22 | ||
23 | u32 class_num; | |
24 | ||
25 | struct device_driver *driver; | |
26 | void *driver_data; | |
27 | void *platform_data; | |
28 | ||
29 | u32 current_state; | |
30 | unsigned char *saved_state; | |
31 | ||
32 | void (*release)(struct device * dev); | |
33 | }; | |
34 | ||
35 | Fields | |
36 | ~~~~~~ | |
37 | g_list: Node in the global device list. | |
38 | ||
39 | node: Node in device's parent's children list. | |
40 | ||
41 | bus_list: Node in device's bus's devices list. | |
42 | ||
43 | driver_list: Node in device's driver's devices list. | |
44 | ||
45 | intf_list: List of intf_data. There is one structure allocated for | |
46 | each interface that the device supports. | |
47 | ||
48 | children: List of child devices. | |
49 | ||
50 | parent: *** FIXME *** | |
51 | ||
52 | name: ASCII description of device. | |
53 | Example: " 3Com Corporation 3c905 100BaseTX [Boomerang]" | |
54 | ||
55 | bus_id: ASCII representation of device's bus position. This | |
56 | field should be a name unique across all devices on the | |
57 | bus type the device belongs to. | |
58 | ||
59 | Example: PCI bus_ids are in the form of | |
60 | <bus number>:<slot number>.<function number> | |
61 | This name is unique across all PCI devices in the system. | |
62 | ||
63 | lock: Spinlock for the device. | |
64 | ||
65 | refcount: Reference count on the device. | |
66 | ||
67 | bus: Pointer to struct bus_type that device belongs to. | |
68 | ||
69 | dir: Device's sysfs directory. | |
70 | ||
71 | class_num: Class-enumerated value of the device. | |
72 | ||
73 | driver: Pointer to struct device_driver that controls the device. | |
74 | ||
75 | driver_data: Driver-specific data. | |
76 | ||
77 | platform_data: Platform data specific to the device. | |
78 | ||
4109aca0 DB |
79 | Example: for devices on custom boards, as typical of embedded |
80 | and SOC based hardware, Linux often uses platform_data to point | |
81 | to board-specific structures describing devices and how they | |
82 | are wired. That can include what ports are available, chip | |
83 | variants, which GPIO pins act in what additional roles, and so | |
84 | on. This shrinks the "Board Support Packages" (BSPs) and | |
85 | minimizes board-specific #ifdefs in drivers. | |
86 | ||
1da177e4 LT |
87 | current_state: Current power state of the device. |
88 | ||
89 | saved_state: Pointer to saved state of the device. This is usable by | |
90 | the device driver controlling the device. | |
91 | ||
92 | release: Callback to free the device after all references have | |
93 | gone away. This should be set by the allocator of the | |
94 | device (i.e. the bus driver that discovered the device). | |
95 | ||
96 | ||
97 | Programming Interface | |
98 | ~~~~~~~~~~~~~~~~~~~~~ | |
99 | The bus driver that discovers the device uses this to register the | |
100 | device with the core: | |
101 | ||
102 | int device_register(struct device * dev); | |
103 | ||
104 | The bus should initialize the following fields: | |
105 | ||
106 | - parent | |
107 | - name | |
108 | - bus_id | |
109 | - bus | |
110 | ||
111 | A device is removed from the core when its reference count goes to | |
112 | 0. The reference count can be adjusted using: | |
113 | ||
114 | struct device * get_device(struct device * dev); | |
115 | void put_device(struct device * dev); | |
116 | ||
117 | get_device() will return a pointer to the struct device passed to it | |
118 | if the reference is not already 0 (if it's in the process of being | |
119 | removed already). | |
120 | ||
121 | A driver can access the lock in the device structure using: | |
122 | ||
123 | void lock_device(struct device * dev); | |
124 | void unlock_device(struct device * dev); | |
125 | ||
126 | ||
127 | Attributes | |
128 | ~~~~~~~~~~ | |
129 | struct device_attribute { | |
245127db MM |
130 | struct attribute attr; |
131 | ssize_t (*show)(struct device *dev, struct device_attribute *attr, | |
132 | char *buf); | |
133 | ssize_t (*store)(struct device *dev, struct device_attribute *attr, | |
134 | const char *buf, size_t count); | |
1da177e4 LT |
135 | }; |
136 | ||
137 | Attributes of devices can be exported via drivers using a simple | |
138 | procfs-like interface. | |
139 | ||
140 | Please see Documentation/filesystems/sysfs.txt for more information | |
141 | on how sysfs works. | |
142 | ||
143 | Attributes are declared using a macro called DEVICE_ATTR: | |
144 | ||
145 | #define DEVICE_ATTR(name,mode,show,store) | |
146 | ||
147 | Example: | |
148 | ||
149 | DEVICE_ATTR(power,0644,show_power,store_power); | |
150 | ||
151 | This declares a structure of type struct device_attribute named | |
152 | 'dev_attr_power'. This can then be added and removed to the device's | |
153 | directory using: | |
154 | ||
155 | int device_create_file(struct device *device, struct device_attribute * entry); | |
156 | void device_remove_file(struct device * dev, struct device_attribute * attr); | |
157 | ||
158 | Example: | |
159 | ||
160 | device_create_file(dev,&dev_attr_power); | |
161 | device_remove_file(dev,&dev_attr_power); | |
162 | ||
163 | The file name will be 'power' with a mode of 0644 (-rw-r--r--). | |
164 |