Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 | /* * device.h - generic, centralized driver model * * Copyright (c) 2001 Patrick Mochel <mochel@osdl.org> * * This is a relatively simple centralized driver model. * The data structures were mainly lifted directly from the PCI * driver model. These are thought to be the common fields that * are relevant to all device buses. * * All the devices are arranged in a tree. All devices should * have some sort of parent bus of whom they are children of. * Devices should not be direct children of the system root. * * Device drivers should not directly call the device_* routines * or access the contents of struct device directly. Instead, * abstract that from the drivers and write bus-specific wrappers * that do it for you. * * See Documentation/driver-model.txt for more information. */ #ifndef _DEVICE_H_ #define _DEVICE_H_ #include <linux/types.h> #include <linux/config.h> #include <linux/ioport.h> #include <linux/list.h> #include <linux/sched.h> #include <linux/kobject.h> #define DEVICE_NAME_SIZE 80 #define DEVICE_ID_SIZE 32 #define BUS_ID_SIZE 16 enum { SUSPEND_NOTIFY, SUSPEND_SAVE_STATE, SUSPEND_DISABLE, SUSPEND_POWER_DOWN, }; enum { RESUME_POWER_ON, RESUME_RESTORE_STATE, RESUME_ENABLE, }; enum device_state { DEVICE_UNINITIALIZED = 0, DEVICE_INITIALIZED = 1, DEVICE_REGISTERED = 2, DEVICE_GONE = 3, }; struct device; struct device_driver; struct device_class; struct bus_type { char * name; struct rw_semaphore rwsem; atomic_t refcount; u32 present; struct subsystem subsys; struct subsystem drvsubsys; struct subsystem devsubsys; struct list_head node; struct list_head devices; struct list_head drivers; int (*match)(struct device * dev, struct device_driver * drv); struct device * (*add) (struct device * parent, char * bus_id); int (*hotplug) (struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size); }; extern int bus_register(struct bus_type * bus); extern void bus_unregister(struct bus_type * bus); extern struct bus_type * get_bus(struct bus_type * bus); extern void put_bus(struct bus_type * bus); extern int bus_for_each_dev(struct bus_type * bus, void * data, int (*callback)(struct device * dev, void * data)); extern int bus_for_each_drv(struct bus_type * bus, void * data, int (*callback)(struct device_driver * drv, void * data)); /* driverfs interface for exporting bus attributes */ struct bus_attribute { struct attribute attr; ssize_t (*show)(struct bus_type *, char * buf, size_t count, loff_t off); ssize_t (*store)(struct bus_type *, const char * buf, size_t count, loff_t off); }; #define BUS_ATTR(_name,_mode,_show,_store) \ struct bus_attribute bus_attr_##_name = { \ .attr = {.name = __stringify(_name), .mode = _mode }, \ .show = _show, \ .store = _store, \ }; extern int bus_create_file(struct bus_type *, struct bus_attribute *); extern void bus_remove_file(struct bus_type *, struct bus_attribute *); struct device_driver { char * name; struct bus_type * bus; struct device_class * devclass; rwlock_t lock; atomic_t refcount; u32 present; struct kobject kobj; struct list_head bus_list; struct list_head class_list; struct list_head devices; int (*probe) (struct device * dev); int (*remove) (struct device * dev); void (*shutdown) (struct device * dev); int (*suspend) (struct device * dev, u32 state, u32 level); int (*resume) (struct device * dev, u32 level); void (*release) (struct device_driver * drv); }; extern int driver_register(struct device_driver * drv); extern void driver_unregister(struct device_driver * drv); extern struct device_driver * get_driver(struct device_driver * drv); extern void put_driver(struct device_driver * drv); extern void remove_driver(struct device_driver * drv); extern int driver_for_each_dev(struct device_driver * drv, void * data, int (*callback)(struct device * dev, void * data)); /* driverfs interface for exporting driver attributes */ struct driver_attribute { struct attribute attr; ssize_t (*show)(struct device_driver *, char * buf, size_t count, loff_t off); ssize_t (*store)(struct device_driver *, const char * buf, size_t count, loff_t off); }; #define DRIVER_ATTR(_name,_mode,_show,_store) \ struct driver_attribute driver_attr_##_name = { \ .attr = {.name = __stringify(_name), .mode = _mode }, \ .show = _show, \ .store = _store, \ }; extern int driver_create_file(struct device_driver *, struct driver_attribute *); extern void driver_remove_file(struct device_driver *, struct driver_attribute *); /* * device classes */ struct device_class { char * name; struct rw_semaphore rwsem; atomic_t refcount; u32 present; u32 devnum; struct subsystem subsys; struct subsystem devsubsys; struct subsystem drvsubsys; struct list_head node; struct list_head drivers; struct list_head intf_list; int (*add_device)(struct device *); void (*remove_device)(struct device *); int (*hotplug)(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size); }; extern int devclass_register(struct device_class *); extern void devclass_unregister(struct device_class *); extern struct device_class * get_devclass(struct device_class *); extern void put_devclass(struct device_class *); struct devclass_attribute { struct attribute attr; ssize_t (*show)(struct device_class *, char * buf, size_t count, loff_t off); ssize_t (*store)(struct device_class *, const char * buf, size_t count, loff_t off); }; #define DEVCLASS_ATTR(_name,_str,_mode,_show,_store) \ struct devclass_attribute devclass_attr_##_name = { \ .attr = {.name = _str, .mode = _mode }, \ .show = _show, \ .store = _store, \ }; extern int devclass_create_file(struct device_class *, struct devclass_attribute *); extern void devclass_remove_file(struct device_class *, struct devclass_attribute *); /* * device interfaces * These are the logical interfaces of device classes. * These entities map directly to specific userspace interfaces, like * device nodes. * Interfaces are registered with the device class they belong to. When * a device is registered with the class, each interface's add_device * callback is called. It is up to the interface to decide whether or not * it supports the device. */ struct intf_data; struct device_interface { char * name; struct device_class * devclass; struct kobject kobj; struct list_head node; struct list_head devices; u32 devnum; int (*add_device) (struct device *); int (*remove_device) (struct intf_data *); }; extern int interface_register(struct device_interface *); extern void interface_unregister(struct device_interface *); /* * intf_data - per-device data for an interface * Each interface typically has a per-device data structure * that it allocates. It should embed one of these structures * in that structure and call interface_add_data() to add it * to the device's list. * That will also enumerate the device within the interface * and create a driverfs symlink for it. */ struct intf_data { struct list_head node; struct device_interface * intf; struct device * dev; u32 intf_num; }; extern int interface_add_data(struct intf_data *); struct device { struct list_head g_list; /* node in depth-first order list */ struct list_head node; /* node in sibling list */ struct list_head bus_list; /* node in bus's list */ struct list_head driver_list; struct list_head children; struct list_head intf_list; struct device * parent; struct kobject kobj; char name[DEVICE_NAME_SIZE]; /* descriptive ascii string */ char bus_id[BUS_ID_SIZE]; /* position on parent bus */ spinlock_t lock; /* lock for the device to ensure two different layers don't access it at the same time. */ atomic_t refcount; /* refcount to make sure the device * persists for the right amount of time */ struct bus_type * bus; /* type of bus device is on */ struct device_driver *driver; /* which driver has allocated this device */ void *driver_data; /* data private to the driver */ u32 class_num; /* class-enumerated value */ void * class_data; /* class-specific data */ void *platform_data; /* Platform specific data (e.g. ACPI, BIOS data relevant to device) */ enum device_state state; u32 power_state; /* Current operating state. In ACPI-speak, this is D0-D3, D0 being fully functional, and D3 being off. */ unsigned char *saved_state; /* saved device state */ void (*release)(struct device * dev); }; static inline struct device * list_to_dev(struct list_head *node) { return list_entry(node, struct device, node); } static inline struct device * g_list_to_dev(struct list_head *g_list) { return list_entry(g_list, struct device, g_list); } static inline void * dev_get_drvdata (struct device *dev) { return dev->driver_data; } static inline void dev_set_drvdata (struct device *dev, void *data) { dev->driver_data = data; } /* * High level routines for use by the bus drivers */ extern int device_register(struct device * dev); extern void device_unregister(struct device * dev); extern void device_initialize(struct device * dev); extern int device_add(struct device * dev); extern void device_del(struct device * dev); /* driverfs interface for exporting device attributes */ struct device_attribute { struct attribute attr; ssize_t (*show)(struct device * dev, char * buf, size_t count, loff_t off); ssize_t (*store)(struct device * dev, const char * buf, size_t count, loff_t off); }; #define DEVICE_ATTR(_name,_mode,_show,_store) \ struct device_attribute dev_attr_##_name = { \ .attr = {.name = __stringify(_name), .mode = _mode }, \ .show = _show, \ .store = _store, \ }; extern int device_create_file(struct device *device, struct device_attribute * entry); extern void device_remove_file(struct device * dev, struct device_attribute * attr); /* * Platform "fixup" functions - allow the platform to have their say * about devices and actions that the general device layer doesn't * know about. */ /* Notify platform of device discovery */ extern int (*platform_notify)(struct device * dev); extern int (*platform_notify_remove)(struct device * dev); static inline int device_present(struct device * dev) { return (dev && (dev->state == DEVICE_INITIALIZED || dev->state == DEVICE_REGISTERED)); } /* device and bus locking helpers. * * FIXME: Is there anything else we need to do? */ static inline void lock_device(struct device * dev) { spin_lock(&dev->lock); } static inline void unlock_device(struct device * dev) { spin_unlock(&dev->lock); } /** * get_device - atomically increment the reference count for the device. * */ extern struct device * get_device(struct device * dev); extern void put_device(struct device * dev); /* drivers/base/sys.c */ struct sys_root { u32 id; struct device dev; struct device sysdev; }; extern int sys_register_root(struct sys_root *); extern void sys_unregister_root(struct sys_root *); struct sys_device { char * name; u32 id; struct sys_root * root; struct device dev; }; extern int sys_device_register(struct sys_device *); extern void sys_device_unregister(struct sys_device *); extern struct bus_type system_bus_type; /* drivers/base/platform.c */ struct platform_device { char * name; u32 id; struct device dev; }; extern int platform_device_register(struct platform_device *); extern void platform_device_unregister(struct platform_device *); extern struct bus_type platform_bus_type; /* drivers/base/power.c */ extern int device_suspend(u32 state, u32 level); extern void device_resume(u32 level); extern void device_shutdown(void); /* drivrs/base/firmware.c */ extern int firmware_register(struct subsystem *); extern void firmware_uregister(struct subsystem *); /* debugging and troubleshooting/diagnostic helpers. */ #ifdef DEBUG #define dev_dbg(dev, format, arg...) \ printk (KERN_DEBUG "%s %s: " format , \ dev.driver->name , dev.bus_id , ## arg) #else #define dev_dbg(dev, format, arg...) do {} while (0) #endif #define dev_err(dev, format, arg...) \ printk (KERN_ERR "%s %s: " format , \ dev.driver->name , dev.bus_id , ## arg) #define dev_info(dev, format, arg...) \ printk (KERN_INFO "%s %s: " format , \ dev.driver->name , dev.bus_id , ## arg) #define dev_warn(dev, format, arg...) \ printk (KERN_WARN "%s %s: " format , \ dev.driver->name , dev.bus_id , ## arg) #endif /* _DEVICE_H_ */ |