diff options
Diffstat (limited to 'Documentation/driver-model/device.txt')
-rw-r--r-- | Documentation/driver-model/device.txt | 154 |
1 files changed, 154 insertions, 0 deletions
diff --git a/Documentation/driver-model/device.txt b/Documentation/driver-model/device.txt new file mode 100644 index 000000000000..58cc5dc8fd3e --- /dev/null +++ b/Documentation/driver-model/device.txt | |||
@@ -0,0 +1,154 @@ | |||
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 | |||
79 | current_state: Current power state of the device. | ||
80 | |||
81 | saved_state: Pointer to saved state of the device. This is usable by | ||
82 | the device driver controlling the device. | ||
83 | |||
84 | release: Callback to free the device after all references have | ||
85 | gone away. This should be set by the allocator of the | ||
86 | device (i.e. the bus driver that discovered the device). | ||
87 | |||
88 | |||
89 | Programming Interface | ||
90 | ~~~~~~~~~~~~~~~~~~~~~ | ||
91 | The bus driver that discovers the device uses this to register the | ||
92 | device with the core: | ||
93 | |||
94 | int device_register(struct device * dev); | ||
95 | |||
96 | The bus should initialize the following fields: | ||
97 | |||
98 | - parent | ||
99 | - name | ||
100 | - bus_id | ||
101 | - bus | ||
102 | |||
103 | A device is removed from the core when its reference count goes to | ||
104 | 0. The reference count can be adjusted using: | ||
105 | |||
106 | struct device * get_device(struct device * dev); | ||
107 | void put_device(struct device * dev); | ||
108 | |||
109 | get_device() will return a pointer to the struct device passed to it | ||
110 | if the reference is not already 0 (if it's in the process of being | ||
111 | removed already). | ||
112 | |||
113 | A driver can access the lock in the device structure using: | ||
114 | |||
115 | void lock_device(struct device * dev); | ||
116 | void unlock_device(struct device * dev); | ||
117 | |||
118 | |||
119 | Attributes | ||
120 | ~~~~~~~~~~ | ||
121 | struct device_attribute { | ||
122 | struct attribute attr; | ||
123 | ssize_t (*show)(struct device * dev, char * buf, size_t count, loff_t off); | ||
124 | ssize_t (*store)(struct device * dev, const char * buf, size_t count, loff_t off); | ||
125 | }; | ||
126 | |||
127 | Attributes of devices can be exported via drivers using a simple | ||
128 | procfs-like interface. | ||
129 | |||
130 | Please see Documentation/filesystems/sysfs.txt for more information | ||
131 | on how sysfs works. | ||
132 | |||
133 | Attributes are declared using a macro called DEVICE_ATTR: | ||
134 | |||
135 | #define DEVICE_ATTR(name,mode,show,store) | ||
136 | |||
137 | Example: | ||
138 | |||
139 | DEVICE_ATTR(power,0644,show_power,store_power); | ||
140 | |||
141 | This declares a structure of type struct device_attribute named | ||
142 | 'dev_attr_power'. This can then be added and removed to the device's | ||
143 | directory using: | ||
144 | |||
145 | int device_create_file(struct device *device, struct device_attribute * entry); | ||
146 | void device_remove_file(struct device * dev, struct device_attribute * attr); | ||
147 | |||
148 | Example: | ||
149 | |||
150 | device_create_file(dev,&dev_attr_power); | ||
151 | device_remove_file(dev,&dev_attr_power); | ||
152 | |||
153 | The file name will be 'power' with a mode of 0644 (-rw-r--r--). | ||
154 | |||