]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/hid/usbhid/hiddev.c
Merge branch 'omap-pool'
[linux-2.6-omap-h63xx.git] / drivers / hid / usbhid / hiddev.c
index aa214170baf414c0b9e1459415dd537be32325a8..e9b436d2d94434c17fb1030d50528341edd71659 100644 (file)
@@ -246,10 +246,12 @@ static int hiddev_release(struct inode * inode, struct file * file)
        spin_unlock_irqrestore(&list->hiddev->list_lock, flags);
 
        if (!--list->hiddev->open) {
-               if (list->hiddev->exist)
+               if (list->hiddev->exist) {
                        usbhid_close(list->hiddev->hid);
-               else
+                       usbhid_put_power(list->hiddev->hid);
+               } else {
                        kfree(list->hiddev);
+               }
        }
 
        kfree(list);
@@ -300,6 +302,17 @@ static int hiddev_open(struct inode *inode, struct file *file)
        list_add_tail(&list->node, &hiddev_table[i]->list);
        spin_unlock_irq(&list->hiddev->list_lock);
 
+       if (!list->hiddev->open++)
+               if (list->hiddev->exist) {
+                       struct hid_device *hid = hiddev_table[i]->hid;
+                       res = usbhid_get_power(hid);
+                       if (res < 0) {
+                               res = -EIO;
+                               goto bail;
+                       }
+                       usbhid_open(hid);
+               }
+
        return 0;
 bail:
        file->private_data = NULL;
@@ -875,16 +888,21 @@ int hiddev_connect(struct hid_device *hid, unsigned int force)
        hiddev->hid = hid;
        hiddev->exist = 1;
 
+       /* when lock_kernel() usage is fixed in usb_open(),
+        * we could also fix it here */
+       lock_kernel();
        retval = usb_register_dev(usbhid->intf, &hiddev_class);
        if (retval) {
                err_hid("Not able to get a minor for this device.");
                hid->hiddev = NULL;
+               unlock_kernel();
                kfree(hiddev);
                return -1;
        } else {
                hid->minor = usbhid->intf->minor;
                hiddev_table[usbhid->intf->minor - HIDDEV_MINOR_BASE] = hiddev;
        }
+       unlock_kernel();
 
        return 0;
 }