| 1 | /* |
|---|
| 2 | * device.h - generic, centralized driver model |
|---|
| 3 | * |
|---|
| 4 | * Copyright (c) 2001-2003 Patrick Mochel <mochel@osdl.org> |
|---|
| 5 | * |
|---|
| 6 | * This file is released under the GPLv2 |
|---|
| 7 | * |
|---|
| 8 | * See Documentation/driver-model/ for more information. |
|---|
| 9 | */ |
|---|
| 10 | |
|---|
| 11 | #ifndef _DEVICE_H_ |
|---|
| 12 | #define _DEVICE_H_ |
|---|
| 13 | |
|---|
| 14 | #include <linux/ioport.h> |
|---|
| 15 | #include <linux/types.h> |
|---|
| 16 | #include <linux/module.h> |
|---|
| 17 | #include <asm/semaphore.h> |
|---|
| 18 | #include <asm/atomic.h> |
|---|
| 19 | |
|---|
| 20 | #define DEVICE_NAME_SIZE 50 |
|---|
| 21 | #define DEVICE_NAME_HALF __stringify(20) /* Less than half to accommodate slop */ |
|---|
| 22 | #define DEVICE_ID_SIZE 32 |
|---|
| 23 | #define BUS_ID_SIZE KOBJ_NAME_LEN |
|---|
| 24 | |
|---|
| 25 | |
|---|
| 26 | enum { |
|---|
| 27 | SUSPEND_NOTIFY, |
|---|
| 28 | SUSPEND_SAVE_STATE, |
|---|
| 29 | SUSPEND_DISABLE, |
|---|
| 30 | SUSPEND_POWER_DOWN, |
|---|
| 31 | }; |
|---|
| 32 | |
|---|
| 33 | enum { |
|---|
| 34 | RESUME_POWER_ON, |
|---|
| 35 | RESUME_RESTORE_STATE, |
|---|
| 36 | RESUME_ENABLE, |
|---|
| 37 | }; |
|---|
| 38 | |
|---|
| 39 | struct device; |
|---|
| 40 | struct device_driver; |
|---|
| 41 | struct class; |
|---|
| 42 | struct class_device; |
|---|
| 43 | struct class_simple; |
|---|
| 44 | |
|---|
| 45 | struct bus_type { |
|---|
| 46 | char * name; |
|---|
| 47 | |
|---|
| 48 | struct subsystem subsys; |
|---|
| 49 | struct kset drivers; |
|---|
| 50 | struct kset devices; |
|---|
| 51 | |
|---|
| 52 | struct bus_attribute * bus_attrs; |
|---|
| 53 | struct device_attribute * dev_attrs; |
|---|
| 54 | struct driver_attribute * drv_attrs; |
|---|
| 55 | |
|---|
| 56 | int (*match)(struct device * dev, struct device_driver * drv); |
|---|
| 57 | int (*hotplug) (struct device *dev, char **envp, |
|---|
| 58 | int num_envp, char *buffer, int buffer_size); |
|---|
| 59 | int (*suspend)(struct device * dev, pm_message_t state); |
|---|
| 60 | int (*resume)(struct device * dev); |
|---|
| 61 | }; |
|---|
| 62 | |
|---|
| 63 | extern int bus_register(struct bus_type * bus); |
|---|
| 64 | extern void bus_unregister(struct bus_type * bus); |
|---|
| 65 | |
|---|
| 66 | extern int bus_rescan_devices(struct bus_type * bus); |
|---|
| 67 | |
|---|
| 68 | extern struct bus_type * get_bus(struct bus_type * bus); |
|---|
| 69 | extern void put_bus(struct bus_type * bus); |
|---|
| 70 | |
|---|
| 71 | extern struct bus_type * find_bus(char * name); |
|---|
| 72 | |
|---|
| 73 | /* iterator helpers for buses */ |
|---|
| 74 | |
|---|
| 75 | int bus_for_each_dev(struct bus_type * bus, struct device * start, void * data, |
|---|
| 76 | int (*fn)(struct device *, void *)); |
|---|
| 77 | |
|---|
| 78 | int bus_for_each_drv(struct bus_type * bus, struct device_driver * start, |
|---|
| 79 | void * data, int (*fn)(struct device_driver *, void *)); |
|---|
| 80 | |
|---|
| 81 | |
|---|
| 82 | /* driverfs interface for exporting bus attributes */ |
|---|
| 83 | |
|---|
| 84 | struct bus_attribute { |
|---|
| 85 | struct attribute attr; |
|---|
| 86 | ssize_t (*show)(struct bus_type *, char * buf); |
|---|
| 87 | ssize_t (*store)(struct bus_type *, const char * buf, size_t count); |
|---|
| 88 | }; |
|---|
| 89 | |
|---|
| 90 | #define BUS_ATTR(_name,_mode,_show,_store) \ |
|---|
| 91 | struct bus_attribute bus_attr_##_name = __ATTR(_name,_mode,_show,_store) |
|---|
| 92 | |
|---|
| 93 | extern int bus_create_file(struct bus_type *, struct bus_attribute *); |
|---|
| 94 | extern void bus_remove_file(struct bus_type *, struct bus_attribute *); |
|---|
| 95 | |
|---|
| 96 | struct device_driver { |
|---|
| 97 | char * name; |
|---|
| 98 | struct bus_type * bus; |
|---|
| 99 | |
|---|
| 100 | struct completion unloaded; |
|---|
| 101 | struct kobject kobj; |
|---|
| 102 | struct list_head devices; |
|---|
| 103 | |
|---|
| 104 | struct module * owner; |
|---|
| 105 | |
|---|
| 106 | int (*probe) (struct device * dev); |
|---|
| 107 | int (*remove) (struct device * dev); |
|---|
| 108 | void (*shutdown) (struct device * dev); |
|---|
| 109 | int (*suspend) (struct device * dev, pm_message_t state, __u32 level); |
|---|
| 110 | int (*resume) (struct device * dev, __u32 level); |
|---|
| 111 | }; |
|---|
| 112 | |
|---|
| 113 | |
|---|
| 114 | extern int driver_register(struct device_driver * drv); |
|---|
| 115 | extern void driver_unregister(struct device_driver * drv); |
|---|
| 116 | |
|---|
| 117 | extern struct device_driver * get_driver(struct device_driver * drv); |
|---|
| 118 | extern void put_driver(struct device_driver * drv); |
|---|
| 119 | extern struct device_driver *driver_find(const char *name, struct bus_type *bus); |
|---|
| 120 | |
|---|
| 121 | |
|---|
| 122 | /* driverfs interface for exporting driver attributes */ |
|---|
| 123 | |
|---|
| 124 | struct driver_attribute { |
|---|
| 125 | struct attribute attr; |
|---|
| 126 | ssize_t (*show)(struct device_driver *, char * buf); |
|---|
| 127 | ssize_t (*store)(struct device_driver *, const char * buf, size_t count); |
|---|
| 128 | }; |
|---|
| 129 | |
|---|
| 130 | #define DRIVER_ATTR(_name,_mode,_show,_store) \ |
|---|
| 131 | struct driver_attribute driver_attr_##_name = __ATTR(_name,_mode,_show,_store) |
|---|
| 132 | |
|---|
| 133 | extern int driver_create_file(struct device_driver *, struct driver_attribute *); |
|---|
| 134 | extern void driver_remove_file(struct device_driver *, struct driver_attribute *); |
|---|
| 135 | |
|---|
| 136 | |
|---|
| 137 | /* |
|---|
| 138 | * device classes |
|---|
| 139 | */ |
|---|
| 140 | struct class { |
|---|
| 141 | char * name; |
|---|
| 142 | |
|---|
| 143 | struct subsystem subsys; |
|---|
| 144 | struct list_head children; |
|---|
| 145 | struct list_head interfaces; |
|---|
| 146 | struct semaphore sem; /* locks both the children and interfaces lists */ |
|---|
| 147 | |
|---|
| 148 | struct class_attribute * class_attrs; |
|---|
| 149 | struct class_device_attribute * class_dev_attrs; |
|---|
| 150 | |
|---|
| 151 | int (*hotplug)(struct class_device *dev, char **envp, |
|---|
| 152 | int num_envp, char *buffer, int buffer_size); |
|---|
| 153 | |
|---|
| 154 | void (*release)(struct class_device *dev); |
|---|
| 155 | void (*class_release)(struct class *class); |
|---|
| 156 | }; |
|---|
| 157 | |
|---|
| 158 | extern int class_register(struct class *); |
|---|
| 159 | extern void class_unregister(struct class *); |
|---|
| 160 | |
|---|
| 161 | extern struct class * class_get(struct class *); |
|---|
| 162 | extern void class_put(struct class *); |
|---|
| 163 | |
|---|
| 164 | |
|---|
| 165 | struct class_attribute { |
|---|
| 166 | struct attribute attr; |
|---|
| 167 | ssize_t (*show)(struct class *, char * buf); |
|---|
| 168 | ssize_t (*store)(struct class *, const char * buf, size_t count); |
|---|
| 169 | }; |
|---|
| 170 | |
|---|
| 171 | #define CLASS_ATTR(_name,_mode,_show,_store) \ |
|---|
| 172 | struct class_attribute class_attr_##_name = __ATTR(_name,_mode,_show,_store) |
|---|
| 173 | |
|---|
| 174 | extern int class_create_file(struct class *, const struct class_attribute *); |
|---|
| 175 | extern void class_remove_file(struct class *, const struct class_attribute *); |
|---|
| 176 | |
|---|
| 177 | |
|---|
| 178 | struct class_device { |
|---|
| 179 | struct list_head node; |
|---|
| 180 | |
|---|
| 181 | struct kobject kobj; |
|---|
| 182 | struct class * class; /* required */ |
|---|
| 183 | dev_t devt; /* dev_t, creates the sysfs "dev" */ |
|---|
| 184 | struct device * dev; /* not necessary, but nice to have */ |
|---|
| 185 | void * class_data; /* class-specific data */ |
|---|
| 186 | |
|---|
| 187 | char class_id[BUS_ID_SIZE]; /* unique to this class */ |
|---|
| 188 | }; |
|---|
| 189 | |
|---|
| 190 | static inline void * |
|---|
| 191 | class_get_devdata (struct class_device *dev) |
|---|
| 192 | { |
|---|
| 193 | return dev->class_data; |
|---|
| 194 | } |
|---|
| 195 | |
|---|
| 196 | static inline void |
|---|
| 197 | class_set_devdata (struct class_device *dev, void *data) |
|---|
| 198 | { |
|---|
| 199 | dev->class_data = data; |
|---|
| 200 | } |
|---|
| 201 | |
|---|
| 202 | |
|---|
| 203 | extern int class_device_register(struct class_device *); |
|---|
| 204 | extern void class_device_unregister(struct class_device *); |
|---|
| 205 | extern void class_device_initialize(struct class_device *); |
|---|
| 206 | extern int class_device_add(struct class_device *); |
|---|
| 207 | extern void class_device_del(struct class_device *); |
|---|
| 208 | |
|---|
| 209 | extern int class_device_rename(struct class_device *, char *); |
|---|
| 210 | |
|---|
| 211 | extern struct class_device * class_device_get(struct class_device *); |
|---|
| 212 | extern void class_device_put(struct class_device *); |
|---|
| 213 | |
|---|
| 214 | struct class_device_attribute { |
|---|
| 215 | struct attribute attr; |
|---|
| 216 | ssize_t (*show)(struct class_device *, char * buf); |
|---|
| 217 | ssize_t (*store)(struct class_device *, const char * buf, size_t count); |
|---|
| 218 | }; |
|---|
| 219 | |
|---|
| 220 | #define CLASS_DEVICE_ATTR(_name,_mode,_show,_store) \ |
|---|
| 221 | struct class_device_attribute class_device_attr_##_name = \ |
|---|
| 222 | __ATTR(_name,_mode,_show,_store) |
|---|
| 223 | |
|---|
| 224 | extern int class_device_create_file(struct class_device *, |
|---|
| 225 | const struct class_device_attribute *); |
|---|
| 226 | extern void class_device_remove_file(struct class_device *, |
|---|
| 227 | const struct class_device_attribute *); |
|---|
| 228 | extern int class_device_create_bin_file(struct class_device *, |
|---|
| 229 | struct bin_attribute *); |
|---|
| 230 | extern void class_device_remove_bin_file(struct class_device *, |
|---|
| 231 | struct bin_attribute *); |
|---|
| 232 | |
|---|
| 233 | struct class_interface { |
|---|
| 234 | struct list_head node; |
|---|
| 235 | struct class *class; |
|---|
| 236 | |
|---|
| 237 | int (*add) (struct class_device *); |
|---|
| 238 | void (*remove) (struct class_device *); |
|---|
| 239 | }; |
|---|
| 240 | |
|---|
| 241 | extern int class_interface_register(struct class_interface *); |
|---|
| 242 | extern void class_interface_unregister(struct class_interface *); |
|---|
| 243 | |
|---|
| 244 | /* interface for class simple stuff */ |
|---|
| 245 | extern struct class_simple *class_simple_create(struct module *owner, char *name); |
|---|
| 246 | extern void class_simple_destroy(struct class_simple *cs); |
|---|
| 247 | extern struct class_device *class_simple_device_add(struct class_simple *cs, dev_t dev, struct device *device, const char *fmt, ...) |
|---|
| 248 | __attribute__((format(printf,4,5))); |
|---|
| 249 | extern int class_simple_set_hotplug(struct class_simple *, |
|---|
| 250 | int (*hotplug)(struct class_device *dev, char **envp, int num_envp, char *buffer, int buffer_size)); |
|---|
| 251 | extern void class_simple_device_remove(dev_t dev); |
|---|
| 252 | |
|---|
| 253 | |
|---|
| 254 | struct device { |
|---|
| 255 | struct list_head node; /* node in sibling list */ |
|---|
| 256 | struct list_head bus_list; /* node in bus's list */ |
|---|
| 257 | struct list_head driver_list; |
|---|
| 258 | struct list_head children; |
|---|
| 259 | struct device * parent; |
|---|
| 260 | |
|---|
| 261 | struct kobject kobj; |
|---|
| 262 | char bus_id[BUS_ID_SIZE]; /* position on parent bus */ |
|---|
| 263 | |
|---|
| 264 | struct bus_type * bus; /* type of bus device is on */ |
|---|
| 265 | struct device_driver *driver; /* which driver has allocated this |
|---|
| 266 | device */ |
|---|
| 267 | void *driver_data; /* data private to the driver */ |
|---|
| 268 | void *platform_data; /* Platform specific data (e.g. ACPI, |
|---|
| 269 | BIOS data relevant to device) */ |
|---|
| 270 | struct dev_pm_info power; |
|---|
| 271 | |
|---|
| 272 | __u64 *dma_mask; /* dma mask (if dma'able device) */ |
|---|
| 273 | __u64 coherent_dma_mask;/* Like dma_mask, but for |
|---|
| 274 | alloc_coherent mappings as |
|---|
| 275 | not all hardware supports |
|---|
| 276 | 64 bit addresses for consistent |
|---|
| 277 | allocations such descriptors. */ |
|---|
| 278 | |
|---|
| 279 | struct list_head dma_pools; /* dma pools (if dma'ble) */ |
|---|
| 280 | |
|---|
| 281 | struct dma_coherent_mem *dma_mem; /* internal for coherent mem |
|---|
| 282 | override */ |
|---|
| 283 | |
|---|
| 284 | void (*release)(struct device * dev); |
|---|
| 285 | }; |
|---|
| 286 | |
|---|
| 287 | static inline struct device * |
|---|
| 288 | list_to_dev(struct list_head *node) |
|---|
| 289 | { |
|---|
| 290 | return list_entry(node, struct device, node); |
|---|
| 291 | } |
|---|
| 292 | |
|---|
| 293 | static inline void * |
|---|
| 294 | dev_get_drvdata (struct device *dev) |
|---|
| 295 | { |
|---|
| 296 | return dev->driver_data; |
|---|
| 297 | } |
|---|
| 298 | |
|---|
| 299 | static inline void |
|---|
| 300 | dev_set_drvdata (struct device *dev, void *data) |
|---|
| 301 | { |
|---|
| 302 | dev->driver_data = data; |
|---|
| 303 | } |
|---|
| 304 | |
|---|
| 305 | /* |
|---|
| 306 | * High level routines for use by the bus drivers |
|---|
| 307 | */ |
|---|
| 308 | extern int device_register(struct device * dev); |
|---|
| 309 | extern void device_unregister(struct device * dev); |
|---|
| 310 | extern void device_initialize(struct device * dev); |
|---|
| 311 | extern int device_add(struct device * dev); |
|---|
| 312 | extern void device_del(struct device * dev); |
|---|
| 313 | extern int device_for_each_child(struct device *, void *, |
|---|
| 314 | int (*fn)(struct device *, void *)); |
|---|
| 315 | |
|---|
| 316 | /* |
|---|
| 317 | * Manual binding of a device to driver. See drivers/base/bus.c |
|---|
| 318 | * for information on use. |
|---|
| 319 | */ |
|---|
| 320 | extern int driver_probe_device(struct device_driver * drv, struct device * dev); |
|---|
| 321 | extern void device_bind_driver(struct device * dev); |
|---|
| 322 | extern void device_release_driver(struct device * dev); |
|---|
| 323 | extern int device_attach(struct device * dev); |
|---|
| 324 | extern void driver_attach(struct device_driver * drv); |
|---|
| 325 | |
|---|
| 326 | |
|---|
| 327 | /* driverfs interface for exporting device attributes */ |
|---|
| 328 | |
|---|
| 329 | struct device_attribute { |
|---|
| 330 | struct attribute attr; |
|---|
| 331 | ssize_t (*show)(struct device * dev, char * buf); |
|---|
| 332 | ssize_t (*store)(struct device * dev, const char * buf, size_t count); |
|---|
| 333 | }; |
|---|
| 334 | |
|---|
| 335 | #define DEVICE_ATTR(_name,_mode,_show,_store) \ |
|---|
| 336 | struct device_attribute dev_attr_##_name = __ATTR(_name,_mode,_show,_store) |
|---|
| 337 | |
|---|
| 338 | |
|---|
| 339 | extern int device_create_file(struct device *device, struct device_attribute * entry); |
|---|
| 340 | extern void device_remove_file(struct device * dev, struct device_attribute * attr); |
|---|
| 341 | |
|---|
| 342 | /* |
|---|
| 343 | * Platform "fixup" functions - allow the platform to have their say |
|---|
| 344 | * about devices and actions that the general device layer doesn't |
|---|
| 345 | * know about. |
|---|
| 346 | */ |
|---|
| 347 | /* Notify platform of device discovery */ |
|---|
| 348 | extern int (*platform_notify)(struct device * dev); |
|---|
| 349 | |
|---|
| 350 | extern int (*platform_notify_remove)(struct device * dev); |
|---|
| 351 | |
|---|
| 352 | |
|---|
| 353 | /** |
|---|
| 354 | * get_device - atomically increment the reference count for the device. |
|---|
| 355 | * |
|---|
| 356 | */ |
|---|
| 357 | extern struct device * get_device(struct device * dev); |
|---|
| 358 | extern void put_device(struct device * dev); |
|---|
| 359 | extern struct device *device_find(const char *name, struct bus_type *bus); |
|---|
| 360 | |
|---|
| 361 | |
|---|
| 362 | /* drivers/base/platform.c */ |
|---|
| 363 | |
|---|
| 364 | struct platform_device { |
|---|
| 365 | char * name; |
|---|
| 366 | __u32 id; |
|---|
| 367 | struct device dev; |
|---|
| 368 | __u32 num_resources; |
|---|
| 369 | struct resource * resource; |
|---|
| 370 | }; |
|---|
| 371 | |
|---|
| 372 | #define to_platform_device(x) container_of((x), struct platform_device, dev) |
|---|
| 373 | |
|---|
| 374 | extern int platform_device_register(struct platform_device *); |
|---|
| 375 | extern void platform_device_unregister(struct platform_device *); |
|---|
| 376 | |
|---|
| 377 | extern struct bus_type platform_bus_type; |
|---|
| 378 | extern struct device platform_bus; |
|---|
| 379 | |
|---|
| 380 | extern struct resource *platform_get_resource(struct platform_device *, unsigned int, unsigned int); |
|---|
| 381 | extern int platform_get_irq(struct platform_device *, unsigned int); |
|---|
| 382 | extern struct resource *platform_get_resource_byname(struct platform_device *, unsigned int, char *); |
|---|
| 383 | extern int platform_get_irq_byname(struct platform_device *, char *); |
|---|
| 384 | extern int platform_add_devices(struct platform_device **, int); |
|---|
| 385 | |
|---|
| 386 | extern struct platform_device *platform_device_register_simple(char *, unsigned int, struct resource *, unsigned int); |
|---|
| 387 | |
|---|
| 388 | /* drivers/base/power.c */ |
|---|
| 389 | extern void device_shutdown(void); |
|---|
| 390 | |
|---|
| 391 | |
|---|
| 392 | /* drivers/base/firmware.c */ |
|---|
| 393 | extern int firmware_register(struct subsystem *); |
|---|
| 394 | extern void firmware_unregister(struct subsystem *); |
|---|
| 395 | |
|---|
| 396 | /* debugging and troubleshooting/diagnostic helpers. */ |
|---|
| 397 | #define dev_printk(level, dev, format, arg...) \ |
|---|
| 398 | printk(level "%s %s: " format , (dev)->driver ? (dev)->driver->name : "" , (dev)->bus_id , ## arg) |
|---|
| 399 | |
|---|
| 400 | #ifdef DEBUG |
|---|
| 401 | #define dev_dbg(dev, format, arg...) \ |
|---|
| 402 | dev_printk(KERN_DEBUG , dev , format , ## arg) |
|---|
| 403 | #else |
|---|
| 404 | #define dev_dbg(dev, format, arg...) do { (void)(dev); } while (0) |
|---|
| 405 | #endif |
|---|
| 406 | |
|---|
| 407 | #define dev_err(dev, format, arg...) \ |
|---|
| 408 | dev_printk(KERN_ERR , dev , format , ## arg) |
|---|
| 409 | #define dev_info(dev, format, arg...) \ |
|---|
| 410 | dev_printk(KERN_INFO , dev , format , ## arg) |
|---|
| 411 | #define dev_warn(dev, format, arg...) \ |
|---|
| 412 | dev_printk(KERN_WARNING , dev , format , ## arg) |
|---|
| 413 | |
|---|
| 414 | /* Create alias, so I can be autoloaded. */ |
|---|
| 415 | #define MODULE_ALIAS_CHARDEV(major,minor) \ |
|---|
| 416 | MODULE_ALIAS("char-major-" __stringify(major) "-" __stringify(minor)) |
|---|
| 417 | #define MODULE_ALIAS_CHARDEV_MAJOR(major) \ |
|---|
| 418 | MODULE_ALIAS("char-major-" __stringify(major) "-*") |
|---|
| 419 | #endif /* _DEVICE_H_ */ |
|---|