[PATCH] Input: prepare to sysfs integration
Input: prepare to sysfs integration Add struct class_device to input_dev; add input_allocate_dev() to dynamically allocate input devices; dynamically allocated devices are automatically registered with sysfs. Signed-off-by: Dmitry Torokhov <dtor@mail.ru> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
4f00469c16
commit
d19fbe8a76
|
@ -27,6 +27,7 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
|
||||||
MODULE_DESCRIPTION("Input core");
|
MODULE_DESCRIPTION("Input core");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
|
||||||
|
EXPORT_SYMBOL(input_allocate_device);
|
||||||
EXPORT_SYMBOL(input_register_device);
|
EXPORT_SYMBOL(input_register_device);
|
||||||
EXPORT_SYMBOL(input_unregister_device);
|
EXPORT_SYMBOL(input_unregister_device);
|
||||||
EXPORT_SYMBOL(input_register_handler);
|
EXPORT_SYMBOL(input_register_handler);
|
||||||
|
@ -605,6 +606,56 @@ static inline int input_proc_init(void) { return 0; }
|
||||||
static inline void input_proc_exit(void) { }
|
static inline void input_proc_exit(void) { }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static void input_dev_release(struct class_device *class_dev)
|
||||||
|
{
|
||||||
|
struct input_dev *dev = to_input_dev(class_dev);
|
||||||
|
|
||||||
|
kfree(dev);
|
||||||
|
module_put(THIS_MODULE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct class input_dev_class = {
|
||||||
|
.name = "input_dev",
|
||||||
|
.release = input_dev_release,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct input_dev *input_allocate_device(void)
|
||||||
|
{
|
||||||
|
struct input_dev *dev;
|
||||||
|
|
||||||
|
dev = kzalloc(sizeof(struct input_dev), GFP_KERNEL);
|
||||||
|
if (dev) {
|
||||||
|
dev->dynalloc = 1;
|
||||||
|
dev->cdev.class = &input_dev_class;
|
||||||
|
class_device_initialize(&dev->cdev);
|
||||||
|
INIT_LIST_HEAD(&dev->h_list);
|
||||||
|
INIT_LIST_HEAD(&dev->node);
|
||||||
|
}
|
||||||
|
|
||||||
|
return dev;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void input_register_classdevice(struct input_dev *dev)
|
||||||
|
{
|
||||||
|
static atomic_t input_no = ATOMIC_INIT(0);
|
||||||
|
const char *path;
|
||||||
|
|
||||||
|
__module_get(THIS_MODULE);
|
||||||
|
|
||||||
|
dev->dev = dev->cdev.dev;
|
||||||
|
|
||||||
|
snprintf(dev->cdev.class_id, sizeof(dev->cdev.class_id),
|
||||||
|
"input%ld", (unsigned long) atomic_inc_return(&input_no) - 1);
|
||||||
|
|
||||||
|
path = kobject_get_path(&dev->cdev.class->subsys.kset.kobj, GFP_KERNEL);
|
||||||
|
printk(KERN_INFO "input: %s/%s as %s\n",
|
||||||
|
dev->name ? dev->name : "Unspecified device",
|
||||||
|
path ? path : "", dev->cdev.class_id);
|
||||||
|
kfree(path);
|
||||||
|
|
||||||
|
class_device_add(&dev->cdev);
|
||||||
|
}
|
||||||
|
|
||||||
void input_register_device(struct input_dev *dev)
|
void input_register_device(struct input_dev *dev)
|
||||||
{
|
{
|
||||||
struct input_handle *handle;
|
struct input_handle *handle;
|
||||||
|
@ -637,6 +688,10 @@ void input_register_device(struct input_dev *dev)
|
||||||
if ((handle = handler->connect(handler, dev, id)))
|
if ((handle = handler->connect(handler, dev, id)))
|
||||||
input_link_handle(handle);
|
input_link_handle(handle);
|
||||||
|
|
||||||
|
|
||||||
|
if (dev->dynalloc)
|
||||||
|
input_register_classdevice(dev);
|
||||||
|
|
||||||
#ifdef CONFIG_HOTPLUG
|
#ifdef CONFIG_HOTPLUG
|
||||||
input_call_hotplug("add", dev);
|
input_call_hotplug("add", dev);
|
||||||
#endif
|
#endif
|
||||||
|
@ -665,6 +720,9 @@ void input_unregister_device(struct input_dev *dev)
|
||||||
|
|
||||||
list_del_init(&dev->node);
|
list_del_init(&dev->node);
|
||||||
|
|
||||||
|
if (dev->dynalloc)
|
||||||
|
class_device_unregister(&dev->cdev);
|
||||||
|
|
||||||
input_wakeup_procfs_readers();
|
input_wakeup_procfs_readers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -753,26 +811,34 @@ static int __init input_init(void)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
err = class_register(&input_dev_class);
|
||||||
|
if (err) {
|
||||||
|
printk(KERN_ERR "input: unable to register input_dev class\n");
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
input_class = class_create(THIS_MODULE, "input");
|
input_class = class_create(THIS_MODULE, "input");
|
||||||
if (IS_ERR(input_class)) {
|
if (IS_ERR(input_class)) {
|
||||||
printk(KERN_ERR "input: unable to register input class\n");
|
printk(KERN_ERR "input: unable to register input class\n");
|
||||||
return PTR_ERR(input_class);
|
err = PTR_ERR(input_class);
|
||||||
|
goto fail1;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = input_proc_init();
|
err = input_proc_init();
|
||||||
if (err)
|
if (err)
|
||||||
goto fail1;
|
goto fail2;
|
||||||
|
|
||||||
err = register_chrdev(INPUT_MAJOR, "input", &input_fops);
|
err = register_chrdev(INPUT_MAJOR, "input", &input_fops);
|
||||||
if (err) {
|
if (err) {
|
||||||
printk(KERN_ERR "input: unable to register char major %d", INPUT_MAJOR);
|
printk(KERN_ERR "input: unable to register char major %d", INPUT_MAJOR);
|
||||||
goto fail2;
|
goto fail3;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail2: input_proc_exit();
|
fail3: input_proc_exit();
|
||||||
fail1: class_destroy(input_class);
|
fail2: class_destroy(input_class);
|
||||||
|
fail1: class_unregister(&input_dev_class);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -781,6 +847,7 @@ static void __exit input_exit(void)
|
||||||
input_proc_exit();
|
input_proc_exit();
|
||||||
unregister_chrdev(INPUT_MAJOR, "input");
|
unregister_chrdev(INPUT_MAJOR, "input");
|
||||||
class_destroy(input_class);
|
class_destroy(input_class);
|
||||||
|
class_unregister(&input_dev_class);
|
||||||
}
|
}
|
||||||
|
|
||||||
subsys_initcall(input_init);
|
subsys_initcall(input_init);
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#ifdef __KERNEL__
|
#ifdef __KERNEL__
|
||||||
#include <linux/time.h>
|
#include <linux/time.h>
|
||||||
#include <linux/list.h>
|
#include <linux/list.h>
|
||||||
|
#include <linux/device.h>
|
||||||
#else
|
#else
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
|
@ -889,11 +890,15 @@ struct input_dev {
|
||||||
struct semaphore sem; /* serializes open and close operations */
|
struct semaphore sem; /* serializes open and close operations */
|
||||||
unsigned int users;
|
unsigned int users;
|
||||||
|
|
||||||
struct device *dev;
|
struct class_device cdev;
|
||||||
|
struct device *dev; /* will be removed soon */
|
||||||
|
|
||||||
|
int dynalloc; /* temporarily */
|
||||||
|
|
||||||
struct list_head h_list;
|
struct list_head h_list;
|
||||||
struct list_head node;
|
struct list_head node;
|
||||||
};
|
};
|
||||||
|
#define to_input_dev(d) container_of(d, struct input_dev, cdev)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Structure for hotplug & device<->driver matching.
|
* Structure for hotplug & device<->driver matching.
|
||||||
|
@ -984,6 +989,23 @@ static inline void init_input_dev(struct input_dev *dev)
|
||||||
INIT_LIST_HEAD(&dev->node);
|
INIT_LIST_HEAD(&dev->node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct input_dev *input_allocate_device(void);
|
||||||
|
|
||||||
|
static inline void input_free_device(struct input_dev *dev)
|
||||||
|
{
|
||||||
|
kfree(dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline struct input_dev *input_get_device(struct input_dev *dev)
|
||||||
|
{
|
||||||
|
return to_input_dev(class_device_get(&dev->cdev));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void input_put_device(struct input_dev *dev)
|
||||||
|
{
|
||||||
|
class_device_put(&dev->cdev);
|
||||||
|
}
|
||||||
|
|
||||||
void input_register_device(struct input_dev *);
|
void input_register_device(struct input_dev *);
|
||||||
void input_unregister_device(struct input_dev *);
|
void input_unregister_device(struct input_dev *);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue