diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2008-04-01 00:22:53 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2008-04-01 00:22:53 -0400 |
commit | a7097ff89c3204737a07eecbc83f9ae6002cc534 (patch) | |
tree | 11fe55cbfb3651fc57e59fc838d1e084f5e63749 /drivers | |
parent | 399f486286f44d55c4fff0e9cc5d712f2b443489 (diff) |
Input: make sure input interfaces pin parent input devices
Recent driver core change causes references to parent devices being
dropped early, at device_del() time, as opposed to when all children
are freed. This causes oops in evdev with grabbed devices. Take the
reference to the parent input device ourselves to ensure that it
stays around long enough.
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/input/evdev.c | 6 | ||||
-rw-r--r-- | drivers/input/joydev.c | 3 | ||||
-rw-r--r-- | drivers/input/mousedev.c | 3 |
3 files changed, 6 insertions, 6 deletions
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 99562cee827e..b32984bc516f 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c | |||
@@ -124,6 +124,7 @@ static void evdev_free(struct device *dev) | |||
124 | { | 124 | { |
125 | struct evdev *evdev = container_of(dev, struct evdev, dev); | 125 | struct evdev *evdev = container_of(dev, struct evdev, dev); |
126 | 126 | ||
127 | input_put_device(evdev->handle.dev); | ||
127 | kfree(evdev); | 128 | kfree(evdev); |
128 | } | 129 | } |
129 | 130 | ||
@@ -853,9 +854,6 @@ static void evdev_cleanup(struct evdev *evdev) | |||
853 | evdev_hangup(evdev); | 854 | evdev_hangup(evdev); |
854 | evdev_remove_chrdev(evdev); | 855 | evdev_remove_chrdev(evdev); |
855 | 856 | ||
856 | if (evdev->grab) | ||
857 | evdev_ungrab(evdev, evdev->grab); | ||
858 | |||
859 | /* evdev is marked dead so no one else accesses evdev->open */ | 857 | /* evdev is marked dead so no one else accesses evdev->open */ |
860 | if (evdev->open) { | 858 | if (evdev->open) { |
861 | input_flush_device(handle, NULL); | 859 | input_flush_device(handle, NULL); |
@@ -896,7 +894,7 @@ static int evdev_connect(struct input_handler *handler, struct input_dev *dev, | |||
896 | evdev->exist = 1; | 894 | evdev->exist = 1; |
897 | evdev->minor = minor; | 895 | evdev->minor = minor; |
898 | 896 | ||
899 | evdev->handle.dev = dev; | 897 | evdev->handle.dev = input_get_device(dev); |
900 | evdev->handle.name = evdev->name; | 898 | evdev->handle.name = evdev->name; |
901 | evdev->handle.handler = handler; | 899 | evdev->handle.handler = handler; |
902 | evdev->handle.private = evdev; | 900 | evdev->handle.private = evdev; |
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c index 22b2789ef58a..65d7077a75a1 100644 --- a/drivers/input/joydev.c +++ b/drivers/input/joydev.c | |||
@@ -171,6 +171,7 @@ static void joydev_free(struct device *dev) | |||
171 | { | 171 | { |
172 | struct joydev *joydev = container_of(dev, struct joydev, dev); | 172 | struct joydev *joydev = container_of(dev, struct joydev, dev); |
173 | 173 | ||
174 | input_put_device(joydev->handle.dev); | ||
174 | kfree(joydev); | 175 | kfree(joydev); |
175 | } | 176 | } |
176 | 177 | ||
@@ -750,7 +751,7 @@ static int joydev_connect(struct input_handler *handler, struct input_dev *dev, | |||
750 | joydev->minor = minor; | 751 | joydev->minor = minor; |
751 | 752 | ||
752 | joydev->exist = 1; | 753 | joydev->exist = 1; |
753 | joydev->handle.dev = dev; | 754 | joydev->handle.dev = input_get_device(dev); |
754 | joydev->handle.name = joydev->name; | 755 | joydev->handle.name = joydev->name; |
755 | joydev->handle.handler = handler; | 756 | joydev->handle.handler = handler; |
756 | joydev->handle.private = joydev; | 757 | joydev->handle.private = joydev; |
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c index bbbe5e81adc1..b989748598ae 100644 --- a/drivers/input/mousedev.c +++ b/drivers/input/mousedev.c | |||
@@ -414,6 +414,7 @@ static void mousedev_free(struct device *dev) | |||
414 | { | 414 | { |
415 | struct mousedev *mousedev = container_of(dev, struct mousedev, dev); | 415 | struct mousedev *mousedev = container_of(dev, struct mousedev, dev); |
416 | 416 | ||
417 | input_put_device(mousedev->handle.dev); | ||
417 | kfree(mousedev); | 418 | kfree(mousedev); |
418 | } | 419 | } |
419 | 420 | ||
@@ -865,7 +866,7 @@ static struct mousedev *mousedev_create(struct input_dev *dev, | |||
865 | 866 | ||
866 | mousedev->minor = minor; | 867 | mousedev->minor = minor; |
867 | mousedev->exist = 1; | 868 | mousedev->exist = 1; |
868 | mousedev->handle.dev = dev; | 869 | mousedev->handle.dev = input_get_device(dev); |
869 | mousedev->handle.name = mousedev->name; | 870 | mousedev->handle.name = mousedev->name; |
870 | mousedev->handle.handler = handler; | 871 | mousedev->handle.handler = handler; |
871 | mousedev->handle.private = mousedev; | 872 | mousedev->handle.private = mousedev; |