From: Greg KH Hi, Here's a single patch against 2.6.1-rc2 (should apply cleanly to 2.6.0) that adds input device class support to sysfs. This patch require the sysfs simple class patch that is currently in the -mm tree. Only USB mice end up creating a symlink to the device that the input device is assigned to at this time. I'll add the other one-line changes to the input drivers at a later time. Andrew, can you please add this patch to your -mm tree to get some testing? Note, Al Viro has pointed out a race condition with unloading modules that use the simple class code to add sysfs support. I'll work on fixing that up properly. Until then, these patches are good to play with, just be careful when unloading modules that you don't have any sysfs files open (a very rare occurrence in the wild, but very easy to duplicate if you want to.) Thanks a lot to Hanna Linder for early versions of this patch, on which this is based. --- drivers/input/evdev.c | 4 ++++ drivers/input/joydev.c | 4 ++++ drivers/input/mousedev.c | 8 +++++++- drivers/input/tsdev.c | 4 ++++ drivers/usb/input/hid-input.c | 1 + include/linux/input.h | 1 + 6 files changed, 21 insertions(+), 1 deletion(-) diff -puN drivers/input/evdev.c~sysfs-add-input-class-support drivers/input/evdev.c --- 25/drivers/input/evdev.c~sysfs-add-input-class-support 2004-01-07 19:32:29.000000000 -0800 +++ 25-akpm/drivers/input/evdev.c 2004-01-07 19:32:30.000000000 -0800 @@ -92,6 +92,7 @@ static int evdev_flush(struct file * fil static void evdev_free(struct evdev *evdev) { devfs_remove("input/event%d", evdev->minor); + simple_remove_class_device(MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + evdev->minor)); evdev_table[evdev->minor] = NULL; kfree(evdev); } @@ -426,6 +427,9 @@ static struct input_handle *evdev_connec devfs_mk_cdev(MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor), S_IFCHR|S_IRUGO|S_IWUSR, "input/event%d", minor); + simple_add_class_device(&input_class, + MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor), + dev->dev, "event%d", minor); return &evdev->handle; } diff -puN drivers/input/joydev.c~sysfs-add-input-class-support drivers/input/joydev.c --- 25/drivers/input/joydev.c~sysfs-add-input-class-support 2004-01-07 19:32:29.000000000 -0800 +++ 25-akpm/drivers/input/joydev.c 2004-01-07 19:32:30.000000000 -0800 @@ -145,6 +145,7 @@ static void joydev_free(struct joydev *j { devfs_remove("js%d", joydev->minor); joydev_table[joydev->minor] = NULL; + simple_remove_class_device(MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + joydev->minor)); kfree(joydev); } @@ -444,6 +445,9 @@ static struct input_handle *joydev_conne devfs_mk_cdev(MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor), S_IFCHR|S_IRUGO|S_IWUSR, "js%d", minor); + simple_add_class_device(&input_class, + MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor), + dev->dev, "js%d", minor); return &joydev->handle; } diff -puN drivers/input/mousedev.c~sysfs-add-input-class-support drivers/input/mousedev.c --- 25/drivers/input/mousedev.c~sysfs-add-input-class-support 2004-01-07 19:32:29.000000000 -0800 +++ 25-akpm/drivers/input/mousedev.c 2004-01-07 19:32:30.000000000 -0800 @@ -225,6 +225,7 @@ static int mousedev_fasync(int fd, struc static void mousedev_free(struct mousedev *mousedev) { devfs_remove("input/mouse%d", mousedev->minor); + simple_remove_class_device(MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + mousedev->minor)); mousedev_table[mousedev->minor] = NULL; kfree(mousedev); } @@ -486,6 +487,9 @@ static struct input_handle *mousedev_con devfs_mk_cdev(MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + minor), S_IFCHR|S_IRUGO|S_IWUSR, "input/mouse%d", minor); + simple_add_class_device(&input_class, + MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + minor), + dev->dev, "mouse%d", minor); return &mousedev->handle; } @@ -564,7 +568,8 @@ static int __init mousedev_init(void) devfs_mk_cdev(MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + MOUSEDEV_MIX), S_IFCHR|S_IRUGO|S_IWUSR, "input/mice"); - + simple_add_class_device(&input_class, MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + MOUSEDEV_MIX), + NULL, "mice"); #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX if (!(mousedev_mix.misc = !misc_register(&psaux_mouse))) @@ -583,6 +588,7 @@ static void __exit mousedev_exit(void) misc_deregister(&psaux_mouse); #endif devfs_remove("input/mice"); + simple_remove_class_device(MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + MOUSEDEV_MIX)); input_unregister_handler(&mousedev_handler); } diff -puN drivers/input/tsdev.c~sysfs-add-input-class-support drivers/input/tsdev.c --- 25/drivers/input/tsdev.c~sysfs-add-input-class-support 2004-01-07 19:32:30.000000000 -0800 +++ 25-akpm/drivers/input/tsdev.c 2004-01-07 19:32:30.000000000 -0800 @@ -129,6 +129,7 @@ static int tsdev_open(struct inode *inod static void tsdev_free(struct tsdev *tsdev) { devfs_remove("input/ts%d", tsdev->minor); + simple_remove_class_device(MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + tsdev->minor)); tsdev_table[tsdev->minor] = NULL; kfree(tsdev); } @@ -343,6 +344,9 @@ static struct input_handle *tsdev_connec devfs_mk_cdev(MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + minor), S_IFCHR|S_IRUGO|S_IWUSR, "input/ts%d", minor); + simple_add_class_device(&input_class, + MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + minor), + dev->dev, "ts%d", minor); return &tsdev->handle; } diff -puN drivers/usb/input/hid-input.c~sysfs-add-input-class-support drivers/usb/input/hid-input.c --- 25/drivers/usb/input/hid-input.c~sysfs-add-input-class-support 2004-01-07 19:32:30.000000000 -0800 +++ 25-akpm/drivers/usb/input/hid-input.c 2004-01-07 19:32:30.000000000 -0800 @@ -592,6 +592,7 @@ int hidinput_connect(struct hid_device * hidinput->input.id.vendor = dev->descriptor.idVendor; hidinput->input.id.product = dev->descriptor.idProduct; hidinput->input.id.version = dev->descriptor.bcdDevice; + hidinput->input.dev = &dev->dev; } for (i = 0; i < report->maxfield; i++) diff -puN include/linux/input.h~sysfs-add-input-class-support include/linux/input.h --- 25/include/linux/input.h~sysfs-add-input-class-support 2004-01-07 19:32:30.000000000 -0800 +++ 25-akpm/include/linux/input.h 2004-01-07 19:32:30.000000000 -0800 @@ -809,6 +809,7 @@ struct input_dev { int (*erase_effect)(struct input_dev *dev, int effect_id); struct input_handle *grab; + struct device *dev; struct list_head h_list; struct list_head node; _