sysdev.h 3.3 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
/**
 * System devices follow a slightly different driver model. 
 * They don't need to do dynammic driver binding, can't be probed, 
 * and don't reside on any type of peripheral bus. 
 * So, we represent and treat them a little differently.
 * 
 * We still have a notion of a driver for a system device, because we still
 * want to perform basic operations on these devices. 
 *
 * We also support auxillary drivers binding to devices of a certain class.
 * 
 * This allows configurable drivers to register themselves for devices of
 * a certain type. And, it allows class definitions to reside in generic
 * code while arch-specific code can register specific drivers.
 *
 * Auxillary drivers registered with a NULL cls are registered as drivers
 * for all system devices, and get notification calls for each device. 
 */


#ifndef _SYSDEV_H_
#define _SYSDEV_H_

#include <linux/kobject.h>
25
#include <linux/module.h>
26
#include <linux/pm.h>
L
Linus Torvalds 已提交
27 28 29 30 31


struct sys_device;

struct sysdev_class {
32
	const char *name;
L
Linus Torvalds 已提交
33 34 35 36
	struct list_head	drivers;

	/* Default operations for these types of devices */
	int	(*shutdown)(struct sys_device *);
37
	int	(*suspend)(struct sys_device *, pm_message_t state);
L
Linus Torvalds 已提交
38 39 40 41
	int	(*resume)(struct sys_device *);
	struct kset		kset;
};

42 43 44 45 46 47 48 49 50 51 52 53 54
struct sysdev_class_attribute {
	struct attribute attr;
	ssize_t (*show)(struct sysdev_class *, char *);
	ssize_t (*store)(struct sysdev_class *, const char *, size_t);
};

#define SYSDEV_CLASS_ATTR(_name,_mode,_show,_store) 		\
struct sysdev_class_attribute attr_##_name = { 			\
	.attr = {.name = __stringify(_name), .mode = _mode },	\
	.show	= _show,					\
	.store	= _store,					\
};

L
Linus Torvalds 已提交
55 56 57 58

extern int sysdev_class_register(struct sysdev_class *);
extern void sysdev_class_unregister(struct sysdev_class *);

59 60 61 62
extern int sysdev_class_create_file(struct sysdev_class *,
	struct sysdev_class_attribute *);
extern void sysdev_class_remove_file(struct sysdev_class *,
	struct sysdev_class_attribute *);
L
Linus Torvalds 已提交
63 64 65 66 67 68 69 70 71
/**
 * Auxillary system device drivers.
 */

struct sysdev_driver {
	struct list_head	entry;
	int	(*add)(struct sys_device *);
	int	(*remove)(struct sys_device *);
	int	(*shutdown)(struct sys_device *);
72
	int	(*suspend)(struct sys_device *, pm_message_t state);
L
Linus Torvalds 已提交
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
	int	(*resume)(struct sys_device *);
};


extern int sysdev_driver_register(struct sysdev_class *, struct sysdev_driver *);
extern void sysdev_driver_unregister(struct sysdev_class *, struct sysdev_driver *);


/**
 * sys_devices can be simplified a lot from regular devices, because they're
 * simply not as versatile. 
 */

struct sys_device {
	u32		id;
	struct sysdev_class	* cls;
	struct kobject		kobj;
};

extern int sysdev_register(struct sys_device *);
extern void sysdev_unregister(struct sys_device *);


struct sysdev_attribute { 
	struct attribute	attr;
	ssize_t (*show)(struct sys_device *, char *);
	ssize_t (*store)(struct sys_device *, const char *, size_t);
};


103 104
#define _SYSDEV_ATTR(_name,_mode,_show,_store)			\
{								\
105
	.attr = { .name = __stringify(_name), .mode = _mode },	\
L
Linus Torvalds 已提交
106 107
	.show	= _show,					\
	.store	= _store,					\
108 109 110 111
}

#define SYSDEV_ATTR(_name,_mode,_show,_store)		\
struct sysdev_attribute attr_##_name = _SYSDEV_ATTR(_name,_mode,_show,_store);
L
Linus Torvalds 已提交
112 113 114 115 116

extern int sysdev_create_file(struct sys_device *, struct sysdev_attribute *);
extern void sysdev_remove_file(struct sys_device *, struct sysdev_attribute *);

#endif /* _SYSDEV_H_ */