diff options
author | Dmitry Torokhov <dtor_core@ameritech.net> | 2005-09-15 03:01:39 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2005-10-28 12:52:52 -0400 |
commit | d19fbe8a763634395d4bef40fc88cdb61c4a6274 (patch) | |
tree | 476cedefc829d1523507aebb2093b0d3b58469b0 | |
parent | 4f00469c16b86a3dd6ed66b28c605c8430d58eeb (diff) |
[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>
-rw-r--r-- | drivers/input/input.c | 77 | ||||
-rw-r--r-- | include/linux/input.h | 24 |
2 files changed, 95 insertions, 6 deletions
diff --git a/drivers/input/input.c b/drivers/input/input.c index 072bbf528151..0e2e890c0988 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c | |||
@@ -27,6 +27,7 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>"); | |||
27 | MODULE_DESCRIPTION("Input core"); | 27 | MODULE_DESCRIPTION("Input core"); |
28 | MODULE_LICENSE("GPL"); | 28 | MODULE_LICENSE("GPL"); |
29 | 29 | ||
30 | EXPORT_SYMBOL(input_allocate_device); | ||
30 | EXPORT_SYMBOL(input_register_device); | 31 | EXPORT_SYMBOL(input_register_device); |
31 | EXPORT_SYMBOL(input_unregister_device); | 32 | EXPORT_SYMBOL(input_unregister_device); |
32 | EXPORT_SYMBOL(input_register_handler); | 33 | EXPORT_SYMBOL(input_register_handler); |
@@ -605,6 +606,56 @@ static inline int input_proc_init(void) { return 0; } | |||
605 | static inline void input_proc_exit(void) { } | 606 | static inline void input_proc_exit(void) { } |
606 | #endif | 607 | #endif |
607 | 608 | ||
609 | static void input_dev_release(struct class_device *class_dev) | ||
610 | { | ||
611 | struct input_dev *dev = to_input_dev(class_dev); | ||
612 | |||
613 | kfree(dev); | ||
614 | module_put(THIS_MODULE); | ||
615 | } | ||
616 | |||
617 | static struct class input_dev_class = { | ||
618 | .name = "input_dev", | ||
619 | .release = input_dev_release, | ||
620 | }; | ||
621 | |||
622 | struct input_dev *input_allocate_device(void) | ||
623 | { | ||
624 | struct input_dev *dev; | ||
625 | |||
626 | dev = kzalloc(sizeof(struct input_dev), GFP_KERNEL); | ||
627 | if (dev) { | ||
628 | dev->dynalloc = 1; | ||
629 | dev->cdev.class = &input_dev_class; | ||
630 | class_device_initialize(&dev->cdev); | ||
631 | INIT_LIST_HEAD(&dev->h_list); | ||
632 | INIT_LIST_HEAD(&dev->node); | ||
633 | } | ||
634 | |||
635 | return dev; | ||
636 | } | ||
637 | |||
638 | static void input_register_classdevice(struct input_dev *dev) | ||
639 | { | ||
640 | static atomic_t input_no = ATOMIC_INIT(0); | ||
641 | const char *path; | ||
642 | |||
643 | __module_get(THIS_MODULE); | ||
644 | |||
645 | dev->dev = dev->cdev.dev; | ||
646 | |||
647 | snprintf(dev->cdev.class_id, sizeof(dev->cdev.class_id), | ||
648 | "input%ld", (unsigned long) atomic_inc_return(&input_no) - 1); | ||
649 | |||
650 | path = kobject_get_path(&dev->cdev.class->subsys.kset.kobj, GFP_KERNEL); | ||
651 | printk(KERN_INFO "input: %s/%s as %s\n", | ||
652 | dev->name ? dev->name : "Unspecified device", | ||
653 | path ? path : "", dev->cdev.class_id); | ||
654 | kfree(path); | ||
655 | |||
656 | class_device_add(&dev->cdev); | ||
657 | } | ||
658 | |||
608 | void input_register_device(struct input_dev *dev) | 659 | void input_register_device(struct input_dev *dev) |
609 | { | 660 | { |
610 | struct input_handle *handle; | 661 | struct input_handle *handle; |
@@ -637,6 +688,10 @@ void input_register_device(struct input_dev *dev) | |||
637 | if ((handle = handler->connect(handler, dev, id))) | 688 | if ((handle = handler->connect(handler, dev, id))) |
638 | input_link_handle(handle); | 689 | input_link_handle(handle); |
639 | 690 | ||
691 | |||
692 | if (dev->dynalloc) | ||
693 | input_register_classdevice(dev); | ||
694 | |||
640 | #ifdef CONFIG_HOTPLUG | 695 | #ifdef CONFIG_HOTPLUG |
641 | input_call_hotplug("add", dev); | 696 | input_call_hotplug("add", dev); |
642 | #endif | 697 | #endif |
@@ -665,6 +720,9 @@ void input_unregister_device(struct input_dev *dev) | |||
665 | 720 | ||
666 | list_del_init(&dev->node); | 721 | list_del_init(&dev->node); |
667 | 722 | ||
723 | if (dev->dynalloc) | ||
724 | class_device_unregister(&dev->cdev); | ||
725 | |||
668 | input_wakeup_procfs_readers(); | 726 | input_wakeup_procfs_readers(); |
669 | } | 727 | } |
670 | 728 | ||
@@ -753,26 +811,34 @@ static int __init input_init(void) | |||
753 | { | 811 | { |
754 | int err; | 812 | int err; |
755 | 813 | ||
814 | err = class_register(&input_dev_class); | ||
815 | if (err) { | ||
816 | printk(KERN_ERR "input: unable to register input_dev class\n"); | ||
817 | return err; | ||
818 | } | ||
819 | |||
756 | input_class = class_create(THIS_MODULE, "input"); | 820 | input_class = class_create(THIS_MODULE, "input"); |
757 | if (IS_ERR(input_class)) { | 821 | if (IS_ERR(input_class)) { |
758 | printk(KERN_ERR "input: unable to register input class\n"); | 822 | printk(KERN_ERR "input: unable to register input class\n"); |
759 | return PTR_ERR(input_class); | 823 | err = PTR_ERR(input_class); |
824 | goto fail1; | ||
760 | } | 825 | } |
761 | 826 | ||
762 | err = input_proc_init(); | 827 | err = input_proc_init(); |
763 | if (err) | 828 | if (err) |
764 | goto fail1; | 829 | goto fail2; |
765 | 830 | ||
766 | err = register_chrdev(INPUT_MAJOR, "input", &input_fops); | 831 | err = register_chrdev(INPUT_MAJOR, "input", &input_fops); |
767 | if (err) { | 832 | if (err) { |
768 | printk(KERN_ERR "input: unable to register char major %d", INPUT_MAJOR); | 833 | printk(KERN_ERR "input: unable to register char major %d", INPUT_MAJOR); |
769 | goto fail2; | 834 | goto fail3; |
770 | } | 835 | } |
771 | 836 | ||
772 | return 0; | 837 | return 0; |
773 | 838 | ||
774 | fail2: input_proc_exit(); | 839 | fail3: input_proc_exit(); |
775 | fail1: class_destroy(input_class); | 840 | fail2: class_destroy(input_class); |
841 | fail1: class_unregister(&input_dev_class); | ||
776 | return err; | 842 | return err; |
777 | } | 843 | } |
778 | 844 | ||
@@ -781,6 +847,7 @@ static void __exit input_exit(void) | |||
781 | input_proc_exit(); | 847 | input_proc_exit(); |
782 | unregister_chrdev(INPUT_MAJOR, "input"); | 848 | unregister_chrdev(INPUT_MAJOR, "input"); |
783 | class_destroy(input_class); | 849 | class_destroy(input_class); |
850 | class_unregister(&input_dev_class); | ||
784 | } | 851 | } |
785 | 852 | ||
786 | subsys_initcall(input_init); | 853 | subsys_initcall(input_init); |
diff --git a/include/linux/input.h b/include/linux/input.h index e8c296ff6257..3defa29a17d3 100644 --- a/include/linux/input.h +++ b/include/linux/input.h | |||
@@ -12,6 +12,7 @@ | |||
12 | #ifdef __KERNEL__ | 12 | #ifdef __KERNEL__ |
13 | #include <linux/time.h> | 13 | #include <linux/time.h> |
14 | #include <linux/list.h> | 14 | #include <linux/list.h> |
15 | #include <linux/device.h> | ||
15 | #else | 16 | #else |
16 | #include <sys/time.h> | 17 | #include <sys/time.h> |
17 | #include <sys/ioctl.h> | 18 | #include <sys/ioctl.h> |
@@ -889,11 +890,15 @@ struct input_dev { | |||
889 | struct semaphore sem; /* serializes open and close operations */ | 890 | struct semaphore sem; /* serializes open and close operations */ |
890 | unsigned int users; | 891 | unsigned int users; |
891 | 892 | ||
892 | struct device *dev; | 893 | struct class_device cdev; |
894 | struct device *dev; /* will be removed soon */ | ||
895 | |||
896 | int dynalloc; /* temporarily */ | ||
893 | 897 | ||
894 | struct list_head h_list; | 898 | struct list_head h_list; |
895 | struct list_head node; | 899 | struct list_head node; |
896 | }; | 900 | }; |
901 | #define to_input_dev(d) container_of(d, struct input_dev, cdev) | ||
897 | 902 | ||
898 | /* | 903 | /* |
899 | * Structure for hotplug & device<->driver matching. | 904 | * Structure for hotplug & device<->driver matching. |
@@ -984,6 +989,23 @@ static inline void init_input_dev(struct input_dev *dev) | |||
984 | INIT_LIST_HEAD(&dev->node); | 989 | INIT_LIST_HEAD(&dev->node); |
985 | } | 990 | } |
986 | 991 | ||
992 | struct input_dev *input_allocate_device(void); | ||
993 | |||
994 | static inline void input_free_device(struct input_dev *dev) | ||
995 | { | ||
996 | kfree(dev); | ||
997 | } | ||
998 | |||
999 | static inline struct input_dev *input_get_device(struct input_dev *dev) | ||
1000 | { | ||
1001 | return to_input_dev(class_device_get(&dev->cdev)); | ||
1002 | } | ||
1003 | |||
1004 | static inline void input_put_device(struct input_dev *dev) | ||
1005 | { | ||
1006 | class_device_put(&dev->cdev); | ||
1007 | } | ||
1008 | |||
987 | void input_register_device(struct input_dev *); | 1009 | void input_register_device(struct input_dev *); |
988 | void input_unregister_device(struct input_dev *); | 1010 | void input_unregister_device(struct input_dev *); |
989 | 1011 | ||