--- x/drivers/input/misc/uinput.c +++ y/drivers/input/misc/uinput.c @@ -35,7 +35,7 @@ #define UINPUT_NUM_REQUESTS 16 #define UINPUT_TIMESTAMP_ALLOWED_OFFSET_SECS 10 -enum uinput_state { UIST_NEW_DEVICE, UIST_SETUP_COMPLETE, UIST_CREATED }; +enum uinput_state { UIST_NEW_DEVICE, UIST_SETUP_COMPLETE, UIST_REGISTERING, UIST_CREATED }; struct uinput_request { unsigned int id; @@ -289,6 +289,8 @@ static void uinput_destroy_device(struct struct input_dev *dev = udev->dev; enum uinput_state old_state = udev->state; + if (udev->state == UIST_REGISTERING) + return; udev->state = UIST_NEW_DEVICE; if (dev) { @@ -309,8 +311,10 @@ static void uinput_destroy_device(struct static int uinput_create_device(struct uinput_device *udev) { struct input_dev *dev = udev->dev; + enum uinput_state old_state = udev->state; int error, nslot; + lockdep_assert_held(&udev->mutex); if (udev->state != UIST_SETUP_COMPLETE) { printk(KERN_DEBUG "%s: write device info first\n", UINPUT_NAME); return -EINVAL; @@ -362,7 +366,11 @@ static int uinput_create_device(struct u input_set_drvdata(udev->dev, udev); + udev->state = UIST_REGISTERING; + mutex_unlock(&udev->mutex); error = input_register_device(udev->dev); + mutex_lock(&udev->mutex); + udev->state = old_state; if (error) goto fail2;