Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d19fbe8a authored by Dmitry Torokhov's avatar Dmitry Torokhov Committed by Greg Kroah-Hartman
Browse files

[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: default avatarDmitry Torokhov <dtor@mail.ru>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 4f00469c
Loading
Loading
Loading
Loading
+72 −5
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
MODULE_DESCRIPTION("Input core");
MODULE_LICENSE("GPL");

EXPORT_SYMBOL(input_allocate_device);
EXPORT_SYMBOL(input_register_device);
EXPORT_SYMBOL(input_unregister_device);
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) { }
#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)
{
	struct input_handle *handle;
@@ -637,6 +688,10 @@ void input_register_device(struct input_dev *dev)
				if ((handle = handler->connect(handler, dev, id)))
					input_link_handle(handle);


	if (dev->dynalloc)
		input_register_classdevice(dev);

#ifdef CONFIG_HOTPLUG
	input_call_hotplug("add", dev);
#endif
@@ -665,6 +720,9 @@ void input_unregister_device(struct input_dev *dev)

	list_del_init(&dev->node);

	if (dev->dynalloc)
		class_device_unregister(&dev->cdev);

	input_wakeup_procfs_readers();
}

@@ -753,26 +811,34 @@ static int __init input_init(void)
{
	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");
	if (IS_ERR(input_class)) {
		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();
	if (err)
		goto fail1;
		goto fail2;

	err = register_chrdev(INPUT_MAJOR, "input", &input_fops);
	if (err) {
		printk(KERN_ERR "input: unable to register char major %d", INPUT_MAJOR);
		goto fail2;
		goto fail3;
	}

	return 0;

 fail2:	input_proc_exit();
 fail1:	class_destroy(input_class);
 fail3:	input_proc_exit();
 fail2:	class_destroy(input_class);
 fail1:	class_unregister(&input_dev_class);
	return err;
}

@@ -781,6 +847,7 @@ static void __exit input_exit(void)
	input_proc_exit();
	unregister_chrdev(INPUT_MAJOR, "input");
	class_destroy(input_class);
	class_unregister(&input_dev_class);
}

subsys_initcall(input_init);
+23 −1
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@
#ifdef __KERNEL__
#include <linux/time.h>
#include <linux/list.h>
#include <linux/device.h>
#else
#include <sys/time.h>
#include <sys/ioctl.h>
@@ -889,11 +890,15 @@ struct input_dev {
	struct semaphore sem;	/* serializes open and close operations */
	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	node;
};
#define to_input_dev(d) container_of(d, struct input_dev, cdev)

/*
 * 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);
}

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_unregister_device(struct input_dev *);