Home | History | Annotate | Download | only in linux
      1 /**
      2  * System devices follow a slightly different driver model.
      3  * They don't need to do dynammic driver binding, can't be probed,
      4  * and don't reside on any type of peripheral bus.
      5  * So, we represent and treat them a little differently.
      6  *
      7  * We still have a notion of a driver for a system device, because we still
      8  * want to perform basic operations on these devices.
      9  *
     10  * We also support auxillary drivers binding to devices of a certain class.
     11  *
     12  * This allows configurable drivers to register themselves for devices of
     13  * a certain type. And, it allows class definitions to reside in generic
     14  * code while arch-specific code can register specific drivers.
     15  *
     16  * Auxillary drivers registered with a NULL cls are registered as drivers
     17  * for all system devices, and get notification calls for each device.
     18  */
     19 
     20 
     21 #ifndef _SYSDEV_H_
     22 #define _SYSDEV_H_
     23 
     24 #include <linux/kobject.h>
     25 #include <linux/pm.h>
     26 
     27 
     28 struct sys_device;
     29 
     30 struct sysdev_class {
     31 	struct list_head	drivers;
     32 
     33 	/* Default operations for these types of devices */
     34 	int	(*shutdown)(struct sys_device *);
     35 	int	(*suspend)(struct sys_device *, pm_message_t state);
     36 	int	(*resume)(struct sys_device *);
     37 	struct kset		kset;
     38 };
     39 
     40 struct sysdev_class_attribute {
     41 	struct attribute attr;
     42 	ssize_t (*show)(struct sysdev_class *, char *);
     43 	ssize_t (*store)(struct sysdev_class *, const char *, size_t);
     44 };
     45 
     46 #define SYSDEV_CLASS_ATTR(_name,_mode,_show,_store) 		\
     47 struct sysdev_class_attribute attr_##_name = { 			\
     48 	.attr = {.name = __stringify(_name), .mode = _mode },	\
     49 	.show	= _show,					\
     50 	.store	= _store,					\
     51 };
     52 
     53 
     54 extern int sysdev_class_register(struct sysdev_class *);
     55 extern void sysdev_class_unregister(struct sysdev_class *);
     56 
     57 extern int sysdev_class_create_file(struct sysdev_class *,
     58 	struct sysdev_class_attribute *);
     59 extern void sysdev_class_remove_file(struct sysdev_class *,
     60 	struct sysdev_class_attribute *);
     61 /**
     62  * Auxillary system device drivers.
     63  */
     64 
     65 struct sysdev_driver {
     66 	struct list_head	entry;
     67 	int	(*add)(struct sys_device *);
     68 	int	(*remove)(struct sys_device *);
     69 	int	(*shutdown)(struct sys_device *);
     70 	int	(*suspend)(struct sys_device *, pm_message_t state);
     71 	int	(*resume)(struct sys_device *);
     72 };
     73 
     74 
     75 extern int sysdev_driver_register(struct sysdev_class *, struct sysdev_driver *);
     76 extern void sysdev_driver_unregister(struct sysdev_class *, struct sysdev_driver *);
     77 
     78 
     79 /**
     80  * sys_devices can be simplified a lot from regular devices, because they're
     81  * simply not as versatile.
     82  */
     83 
     84 struct sys_device {
     85 	u32		id;
     86 	struct sysdev_class	* cls;
     87 	struct kobject		kobj;
     88 };
     89 
     90 extern int sysdev_register(struct sys_device *);
     91 extern void sysdev_unregister(struct sys_device *);
     92 
     93 
     94 struct sysdev_attribute {
     95 	struct attribute	attr;
     96 	ssize_t (*show)(struct sys_device *, char *);
     97 	ssize_t (*store)(struct sys_device *, const char *, size_t);
     98 };
     99 
    100 
    101 #define SYSDEV_ATTR(_name,_mode,_show,_store) 		\
    102 struct sysdev_attribute attr_##_name = { 			\
    103 	.attr = {.name = __stringify(_name), .mode = _mode },	\
    104 	.show	= _show,					\
    105 	.store	= _store,					\
    106 };
    107 
    108 extern int sysdev_create_file(struct sys_device *, struct sysdev_attribute *);
    109 extern void sysdev_remove_file(struct sys_device *, struct sysdev_attribute *);
    110 
    111 #endif /* _SYSDEV_H_ */
    112