]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - include/linux/device.h
driver-core: remove legacy iSeries hack
[karo-tx-linux.git] / include / linux / device.h
index 3136ede5a1e1bb8434a0e2d52840f84de39647de..46baa1fec34c1075b62387aaaec9558d5ef0514b 100644 (file)
@@ -53,6 +53,8 @@ extern void bus_remove_file(struct bus_type *, struct bus_attribute *);
  * struct bus_type - The bus type of the device
  *
  * @name:      The name of the bus.
+ * @dev_name:  Used for subsystems to enumerate devices like ("foo%u", dev->id).
+ * @dev_root:  Default device to use as the parent.
  * @bus_attrs: Default attributes of the bus.
  * @dev_attrs: Default attributes of the devices on the bus.
  * @drv_attrs: Default attributes of the device drivers on the bus.
@@ -86,6 +88,8 @@ extern void bus_remove_file(struct bus_type *, struct bus_attribute *);
  */
 struct bus_type {
        const char              *name;
+       const char              *dev_name;
+       struct device           *dev_root;
        struct bus_attribute    *bus_attrs;
        struct device_attribute *dev_attrs;
        struct driver_attribute *drv_attrs;
@@ -106,12 +110,30 @@ struct bus_type {
        struct subsys_private *p;
 };
 
-extern int __must_check bus_register(struct bus_type *bus);
+/* This is a #define to keep the compiler from merging different
+ * instances of the __key variable */
+#define bus_register(subsys)                   \
+({                                             \
+       static struct lock_class_key __key;     \
+       __bus_register(subsys, &__key); \
+})
+extern int __must_check __bus_register(struct bus_type *bus,
+                                      struct lock_class_key *key);
 extern void bus_unregister(struct bus_type *bus);
 
 extern int __must_check bus_rescan_devices(struct bus_type *bus);
 
 /* iterator helpers for buses */
+struct subsys_dev_iter {
+       struct klist_iter               ki;
+       const struct device_type        *type;
+};
+void subsys_dev_iter_init(struct subsys_dev_iter *iter,
+                        struct bus_type *subsys,
+                        struct device *start,
+                        const struct device_type *type);
+struct device *subsys_dev_iter_next(struct subsys_dev_iter *iter);
+void subsys_dev_iter_exit(struct subsys_dev_iter *iter);
 
 int bus_for_each_dev(struct bus_type *bus, struct device *start, void *data,
                     int (*fn)(struct device *dev, void *data));
@@ -121,10 +143,10 @@ struct device *bus_find_device(struct bus_type *bus, struct device *start,
 struct device *bus_find_device_by_name(struct bus_type *bus,
                                       struct device *start,
                                       const char *name);
-
+struct device *subsys_find_device_by_id(struct bus_type *bus, unsigned int id,
+                                       struct device *hint);
 int bus_for_each_drv(struct bus_type *bus, struct device_driver *start,
                     void *data, int (*fn)(struct device_driver *, void *));
-
 void bus_sort_breadthfirst(struct bus_type *bus,
                           int (*compare)(const struct device *a,
                                          const struct device *b));
@@ -242,10 +264,6 @@ extern int __must_check driver_create_file(struct device_driver *driver,
 extern void driver_remove_file(struct device_driver *driver,
                               const struct driver_attribute *attr);
 
-extern int __must_check driver_add_kobj(struct device_driver *drv,
-                                       struct kobject *kobj,
-                                       const char *fmt, ...);
-
 extern int __must_check driver_for_each_device(struct device_driver *drv,
                                               struct device *start,
                                               void *data,
@@ -255,6 +273,33 @@ struct device *driver_find_device(struct device_driver *drv,
                                  struct device *start, void *data,
                                  int (*match)(struct device *dev, void *data));
 
+/**
+ * struct subsys_interface - interfaces to device functions
+ * @name:       name of the device function
+ * @subsys:     subsytem of the devices to attach to
+ * @node:       the list of functions registered at the subsystem
+ * @add_dev:    device hookup to device function handler
+ * @remove_dev: device hookup to device function handler
+ *
+ * Simple interfaces attached to a subsystem. Multiple interfaces can
+ * attach to a subsystem and its devices. Unlike drivers, they do not
+ * exclusively claim or control devices. Interfaces usually represent
+ * a specific functionality of a subsystem/class of devices.
+ */
+struct subsys_interface {
+       const char *name;
+       struct bus_type *subsys;
+       struct list_head node;
+       int (*add_dev)(struct device *dev, struct subsys_interface *sif);
+       int (*remove_dev)(struct device *dev, struct subsys_interface *sif);
+};
+
+int subsys_interface_register(struct subsys_interface *sif);
+void subsys_interface_unregister(struct subsys_interface *sif);
+
+int subsys_system_register(struct bus_type *subsys,
+                          const struct attribute_group **groups);
+
 /**
  * struct class - device classes
  * @name:      Name of the class.
@@ -294,7 +339,7 @@ struct class {
        struct kobject                  *dev_kobj;
 
        int (*dev_uevent)(struct device *dev, struct kobj_uevent_env *env);
-       char *(*devnode)(struct device *dev, mode_t *mode);
+       char *(*devnode)(struct device *dev, umode_t *mode);
 
        void (*class_release)(struct class *class);
        void (*dev_release)(struct device *dev);
@@ -423,7 +468,7 @@ struct device_type {
        const char *name;
        const struct attribute_group **groups;
        int (*uevent)(struct device *dev, struct kobj_uevent_env *env);
-       char *(*devnode)(struct device *dev, mode_t *mode);
+       char *(*devnode)(struct device *dev, umode_t *mode);
        void (*release)(struct device *dev);
 
        const struct dev_pm_ops *pm;
@@ -438,11 +483,31 @@ struct device_attribute {
                         const char *buf, size_t count);
 };
 
-#define DEVICE_ATTR(_name, _mode, _show, _store) \
-struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store)
+struct dev_ext_attribute {
+       struct device_attribute attr;
+       void *var;
+};
+
+ssize_t device_show_ulong(struct device *dev, struct device_attribute *attr,
+                         char *buf);
+ssize_t device_store_ulong(struct device *dev, struct device_attribute *attr,
+                          const char *buf, size_t count);
+ssize_t device_show_int(struct device *dev, struct device_attribute *attr,
+                       char *buf);
+ssize_t device_store_int(struct device *dev, struct device_attribute *attr,
+                        const char *buf, size_t count);
 
-extern int __must_check device_create_file(struct device *device,
-                                       const struct device_attribute *entry);
+#define DEVICE_ATTR(_name, _mode, _show, _store) \
+       struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store)
+#define DEVICE_ULONG_ATTR(_name, _mode, _var) \
+       struct dev_ext_attribute dev_attr_##_name = \
+               { __ATTR(_name, _mode, device_show_ulong, device_store_ulong), &(_var) }
+#define DEVICE_INT_ATTR(_name, _mode, _var) \
+       struct dev_ext_attribute dev_attr_##_name = \
+               { __ATTR(_name, _mode, device_show_ulong, device_store_ulong), &(_var) }
+
+extern int device_create_file(struct device *device,
+                             const struct device_attribute *entry);
 extern void device_remove_file(struct device *dev,
                               const struct device_attribute *attr);
 extern int __must_check device_create_bin_file(struct device *dev,
@@ -490,6 +555,9 @@ extern int devres_release_group(struct device *dev, void *id);
 extern void *devm_kzalloc(struct device *dev, size_t size, gfp_t gfp);
 extern void devm_kfree(struct device *dev, void *p);
 
+void __iomem *devm_request_and_ioremap(struct device *dev,
+                       struct resource *res);
+
 struct device_dma_parameters {
        /*
         * a low level driver may set these to teach IOMMU code about
@@ -540,6 +608,7 @@ struct device_dma_parameters {
  * @archdata:  For arch-specific additions.
  * @of_node:   Associated device tree node.
  * @devt:      For creating the sysfs "dev".
+ * @id:                device instance
  * @devres_lock: Spinlock to protect the resource of the device.
  * @devres_head: The resources list of the device.
  * @knode_class: The node used to add the device to the class list.
@@ -600,6 +669,7 @@ struct device {
        struct device_node      *of_node; /* associated device tree node */
 
        dev_t                   devt;   /* dev_t, creates the sysfs "dev" */
+       u32                     id;     /* device instance */
 
        spinlock_t              devres_lock;
        struct list_head        devres_head;
@@ -720,7 +790,7 @@ extern int device_rename(struct device *dev, const char *new_name);
 extern int device_move(struct device *dev, struct device *new_parent,
                       enum dpm_order dpm_order);
 extern const char *device_get_devnode(struct device *dev,
-                                     mode_t *mode, const char **tmp);
+                                     umode_t *mode, const char **tmp);
 extern void *dev_get_drvdata(const struct device *dev);
 extern int dev_set_drvdata(struct device *dev, void *data);
 
@@ -924,4 +994,29 @@ extern long sysfs_deprecated;
 #define sysfs_deprecated 0
 #endif
 
+/**
+ * module_driver() - Helper macro for drivers that don't do anything
+ * special in module init/exit. This eliminates a lot of boilerplate.
+ * Each module may only use this macro once, and calling it replaces
+ * module_init() and module_exit().
+ *
+ * @__driver: driver name
+ * @__register: register function for this driver type
+ * @__unregister: unregister function for this driver type
+ *
+ * Use this macro to construct bus specific macros for registering
+ * drivers, and do not use it on its own.
+ */
+#define module_driver(__driver, __register, __unregister) \
+static int __init __driver##_init(void) \
+{ \
+       return __register(&(__driver)); \
+} \
+module_init(__driver##_init); \
+static void __exit __driver##_exit(void) \
+{ \
+       __unregister(&(__driver)); \
+} \
+module_exit(__driver##_exit);
+
 #endif /* _DEVICE_H_ */