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