2 * class_simple.c - a "simple" interface for classes for simple char devices.
4 * Copyright (c) 2003-2004 Greg Kroah-Hartman <greg@kroah.com>
5 * Copyright (c) 2003-2004 IBM Corp.
7 * This file is released under the GPLv2
11 #include <linux/config.h>
12 #include <linux/device.h>
13 #include <linux/kdev_t.h>
14 #include <linux/err.h>
17 struct class_device_attribute attr
;
20 #define to_class_simple(d) container_of(d, struct class_simple, class)
23 struct list_head node
;
25 struct class_device class_dev
;
27 #define to_simple_dev(d) container_of(d, struct simple_dev, class_dev)
29 static LIST_HEAD(simple_dev_list
);
30 static spinlock_t simple_dev_list_lock
= SPIN_LOCK_UNLOCKED
;
32 static void release_simple_dev(struct class_device
*class_dev
)
34 struct simple_dev
*s_dev
= to_simple_dev(class_dev
);
38 static ssize_t
show_dev(struct class_device
*class_dev
, char *buf
)
40 struct simple_dev
*s_dev
= to_simple_dev(class_dev
);
41 return print_dev_t(buf
, s_dev
->dev
);
44 static void class_simple_release(struct class *class)
46 struct class_simple
*cs
= to_class_simple(class);
51 * class_simple_create - create a struct class_simple structure
52 * @owner: pointer to the module that is to "own" this struct class_simple
53 * @name: pointer to a string for the name of this class.
55 * This is used to create a struct class_simple pointer that can then be used
56 * in calls to class_simple_device_add(). This is used when you do not wish to
57 * create a full blown class support for a type of char devices.
59 * Note, the pointer created here is to be destroyed when finished by making a
60 * call to class_simple_destroy().
62 struct class_simple
*class_simple_create(struct module
*owner
, char *name
)
64 struct class_simple
*cs
;
67 cs
= kmalloc(sizeof(*cs
), GFP_KERNEL
);
72 memset(cs
, 0x00, sizeof(*cs
));
74 cs
->class.name
= name
;
75 cs
->class.class_release
= class_simple_release
;
76 cs
->class.release
= release_simple_dev
;
78 cs
->attr
.attr
.name
= "dev";
79 cs
->attr
.attr
.mode
= S_IRUGO
;
80 cs
->attr
.attr
.owner
= owner
;
81 cs
->attr
.show
= show_dev
;
82 cs
->attr
.store
= NULL
;
84 retval
= class_register(&cs
->class);
92 return ERR_PTR(retval
);
94 EXPORT_SYMBOL(class_simple_create
);
97 * class_simple_destroy - destroys a struct class_simple structure
98 * @cs: pointer to the struct class_simple that is to be destroyed
100 * Note, the pointer to be destroyed must have been created with a call to
101 * class_simple_create().
103 void class_simple_destroy(struct class_simple
*cs
)
105 if ((cs
== NULL
) || (IS_ERR(cs
)))
108 class_unregister(&cs
->class);
110 EXPORT_SYMBOL(class_simple_destroy
);
113 * class_simple_device_add - adds a class device to sysfs for a character driver
114 * @cs: pointer to the struct class_simple that this device should be registered to.
115 * @dev: the dev_t for the device to be added.
116 * @device: a pointer to a struct device that is assiociated with this class device.
117 * @fmt: string for the class device's name
119 * This function can be used by simple char device classes that do not
120 * implement their own class device registration. A struct class_device will
121 * be created in sysfs, registered to the specified class. A "dev" file will
122 * be created, showing the dev_t for the device. The pointer to the struct
123 * class_device will be returned from the call. Any further sysfs files that
124 * might be required can be created using this pointer.
125 * Note: the struct class_device passed to this function must have previously been
126 * created with a call to class_simple_create().
128 struct class_device
*class_simple_device_add(struct class_simple
*cs
, dev_t dev
, struct device
*device
, const char *fmt
, ...)
131 struct simple_dev
*s_dev
= NULL
;
134 if ((cs
== NULL
) || (IS_ERR(cs
))) {
139 s_dev
= kmalloc(sizeof(*s_dev
), GFP_KERNEL
);
144 memset(s_dev
, 0x00, sizeof(*s_dev
));
147 s_dev
->class_dev
.dev
= device
;
148 s_dev
->class_dev
.class = &cs
->class;
151 vsnprintf(s_dev
->class_dev
.class_id
, BUS_ID_SIZE
, fmt
, args
);
153 retval
= class_device_register(&s_dev
->class_dev
);
157 class_device_create_file(&s_dev
->class_dev
, &cs
->attr
);
159 spin_lock(&simple_dev_list_lock
);
160 list_add(&s_dev
->node
, &simple_dev_list
);
161 spin_unlock(&simple_dev_list_lock
);
163 return &s_dev
->class_dev
;
167 return ERR_PTR(retval
);
169 EXPORT_SYMBOL(class_simple_device_add
);
172 * class_simple_set_hotplug - set the hotplug callback in the embedded struct class
173 * @cs: pointer to the struct class_simple to hold the pointer
174 * @hotplug: function pointer to the hotplug function
176 * Implement and set a hotplug function to add environment variables specific to this
177 * class on the hotplug event.
179 int class_simple_set_hotplug(struct class_simple
*cs
,
180 int (*hotplug
)(struct class_device
*dev
, char **envp
, int num_envp
, char *buffer
, int buffer_size
))
182 if ((cs
== NULL
) || (IS_ERR(cs
)))
184 cs
->class.hotplug
= hotplug
;
187 EXPORT_SYMBOL(class_simple_set_hotplug
);
190 * class_simple_device_remove - removes a class device that was created with class_simple_device_add()
191 * @dev: the dev_t of the device that was previously registered.
193 * This call unregisters and cleans up a class device that was created with a
194 * call to class_device_simple_add()
196 void class_simple_device_remove(dev_t dev
)
198 struct simple_dev
*s_dev
= NULL
;
201 spin_lock(&simple_dev_list_lock
);
202 list_for_each_entry(s_dev
, &simple_dev_list
, node
) {
203 if (s_dev
->dev
== dev
) {
209 list_del(&s_dev
->node
);
210 spin_unlock(&simple_dev_list_lock
);
211 class_device_unregister(&s_dev
->class_dev
);
213 spin_unlock(&simple_dev_list_lock
);
216 EXPORT_SYMBOL(class_simple_device_remove
);