linux/include/linux/sysdev.h
<<
>>
Prefs
   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 auxiliary 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 * Auxiliary 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
  28struct sys_device;
  29struct sysdev_class_attribute;
  30
  31struct sysdev_class {
  32        const char *name;
  33        struct list_head        drivers;
  34        struct sysdev_class_attribute **attrs;
  35        struct kset             kset;
  36};
  37
  38struct sysdev_class_attribute {
  39        struct attribute attr;
  40        ssize_t (*show)(struct sysdev_class *, struct sysdev_class_attribute *,
  41                        char *);
  42        ssize_t (*store)(struct sysdev_class *, struct sysdev_class_attribute *,
  43                         const char *, size_t);
  44};
  45
  46#define _SYSDEV_CLASS_ATTR(_name,_mode,_show,_store)            \
  47{                                                               \
  48        .attr = {.name = __stringify(_name), .mode = _mode },   \
  49        .show   = _show,                                        \
  50        .store  = _store,                                       \
  51}
  52
  53#define SYSDEV_CLASS_ATTR(_name,_mode,_show,_store)             \
  54        struct sysdev_class_attribute attr_##_name =            \
  55                _SYSDEV_CLASS_ATTR(_name,_mode,_show,_store)
  56
  57
  58extern int sysdev_class_register(struct sysdev_class *);
  59extern void sysdev_class_unregister(struct sysdev_class *);
  60
  61extern int sysdev_class_create_file(struct sysdev_class *,
  62        struct sysdev_class_attribute *);
  63extern void sysdev_class_remove_file(struct sysdev_class *,
  64        struct sysdev_class_attribute *);
  65/**
  66 * Auxiliary system device drivers.
  67 */
  68
  69struct sysdev_driver {
  70        struct list_head        entry;
  71        int     (*add)(struct sys_device *);
  72        int     (*remove)(struct sys_device *);
  73};
  74
  75
  76extern int sysdev_driver_register(struct sysdev_class *, struct sysdev_driver *);
  77extern void sysdev_driver_unregister(struct sysdev_class *, struct sysdev_driver *);
  78
  79
  80/**
  81 * sys_devices can be simplified a lot from regular devices, because they're
  82 * simply not as versatile. 
  83 */
  84
  85struct sys_device {
  86        u32             id;
  87        struct sysdev_class     * cls;
  88        struct kobject          kobj;
  89};
  90
  91extern int sysdev_register(struct sys_device *);
  92extern void sysdev_unregister(struct sys_device *);
  93
  94
  95struct sysdev_attribute { 
  96        struct attribute        attr;
  97        ssize_t (*show)(struct sys_device *, struct sysdev_attribute *, char *);
  98        ssize_t (*store)(struct sys_device *, struct sysdev_attribute *,
  99                         const char *, size_t);
 100};
 101
 102
 103#define _SYSDEV_ATTR(_name, _mode, _show, _store)               \
 104{                                                               \
 105        .attr = { .name = __stringify(_name), .mode = _mode },  \
 106        .show   = _show,                                        \
 107        .store  = _store,                                       \
 108}
 109
 110#define SYSDEV_ATTR(_name, _mode, _show, _store)                \
 111        struct sysdev_attribute attr_##_name =                  \
 112                _SYSDEV_ATTR(_name, _mode, _show, _store);
 113
 114extern int sysdev_create_file(struct sys_device *, struct sysdev_attribute *);
 115extern void sysdev_remove_file(struct sys_device *, struct sysdev_attribute *);
 116
 117/* Create/remove NULL terminated attribute list */
 118static inline int
 119sysdev_create_files(struct sys_device *d, struct sysdev_attribute **a)
 120{
 121        return sysfs_create_files(&d->kobj, (const struct attribute **)a);
 122}
 123
 124static inline void
 125sysdev_remove_files(struct sys_device *d, struct sysdev_attribute **a)
 126{
 127        return sysfs_remove_files(&d->kobj, (const struct attribute **)a);
 128}
 129
 130struct sysdev_ext_attribute {
 131        struct sysdev_attribute attr;
 132        void *var;
 133};
 134
 135/*
 136 * Support for simple variable sysdev attributes.
 137 * The pointer to the variable is stored in a sysdev_ext_attribute
 138 */
 139
 140/* Add more types as needed */
 141
 142extern ssize_t sysdev_show_ulong(struct sys_device *, struct sysdev_attribute *,
 143                                char *);
 144extern ssize_t sysdev_store_ulong(struct sys_device *,
 145                        struct sysdev_attribute *, const char *, size_t);
 146extern ssize_t sysdev_show_int(struct sys_device *, struct sysdev_attribute *,
 147                                char *);
 148extern ssize_t sysdev_store_int(struct sys_device *,
 149                        struct sysdev_attribute *, const char *, size_t);
 150
 151#define _SYSDEV_ULONG_ATTR(_name, _mode, _var)                          \
 152        { _SYSDEV_ATTR(_name, _mode, sysdev_show_ulong, sysdev_store_ulong), \
 153          &(_var) }
 154#define SYSDEV_ULONG_ATTR(_name, _mode, _var)                   \
 155        struct sysdev_ext_attribute attr_##_name =              \
 156                _SYSDEV_ULONG_ATTR(_name, _mode, _var);
 157#define _SYSDEV_INT_ATTR(_name, _mode, _var)                            \
 158        { _SYSDEV_ATTR(_name, _mode, sysdev_show_int, sysdev_store_int), \
 159          &(_var) }
 160#define SYSDEV_INT_ATTR(_name, _mode, _var)                     \
 161        struct sysdev_ext_attribute attr_##_name =              \
 162                _SYSDEV_INT_ATTR(_name, _mode, _var);
 163
 164#endif /* _SYSDEV_H_ */
 165