diff options
Diffstat (limited to 'drivers/hid/usbhid/hiddev.c')
-rw-r--r-- | drivers/hid/usbhid/hiddev.c | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c index 1f5b5d4c3c34..fd7375627e5d 100644 --- a/drivers/hid/usbhid/hiddev.c +++ b/drivers/hid/usbhid/hiddev.c | |||
@@ -249,10 +249,12 @@ static int hiddev_release(struct inode * inode, struct file * file) | |||
249 | spin_unlock_irqrestore(&list->hiddev->list_lock, flags); | 249 | spin_unlock_irqrestore(&list->hiddev->list_lock, flags); |
250 | 250 | ||
251 | if (!--list->hiddev->open) { | 251 | if (!--list->hiddev->open) { |
252 | if (list->hiddev->exist) | 252 | if (list->hiddev->exist) { |
253 | usbhid_close(list->hiddev->hid); | 253 | usbhid_close(list->hiddev->hid); |
254 | else | 254 | usbhid_put_power(list->hiddev->hid); |
255 | } else { | ||
255 | kfree(list->hiddev); | 256 | kfree(list->hiddev); |
257 | } | ||
256 | } | 258 | } |
257 | 259 | ||
258 | kfree(list); | 260 | kfree(list); |
@@ -303,6 +305,17 @@ static int hiddev_open(struct inode *inode, struct file *file) | |||
303 | list_add_tail(&list->node, &hiddev_table[i]->list); | 305 | list_add_tail(&list->node, &hiddev_table[i]->list); |
304 | spin_unlock_irq(&list->hiddev->list_lock); | 306 | spin_unlock_irq(&list->hiddev->list_lock); |
305 | 307 | ||
308 | if (!list->hiddev->open++) | ||
309 | if (list->hiddev->exist) { | ||
310 | struct hid_device *hid = hiddev_table[i]->hid; | ||
311 | res = usbhid_get_power(hid); | ||
312 | if (res < 0) { | ||
313 | res = -EIO; | ||
314 | goto bail; | ||
315 | } | ||
316 | usbhid_open(hid); | ||
317 | } | ||
318 | |||
306 | return 0; | 319 | return 0; |
307 | bail: | 320 | bail: |
308 | file->private_data = NULL; | 321 | file->private_data = NULL; |