]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/hid/usbhid/hid-core.c
Merge branch 'autosuspend' into for-next
[linux-2.6-omap-h63xx.git] / drivers / hid / usbhid / hid-core.c
index 625e7e8eb3733c6046a8f89e85c7cacec8f5e65c..4306cb1b8ce5c91275be6566825ce02ec6f210fb 100644 (file)
@@ -841,6 +841,9 @@ static int usbhid_parse(struct hid_device *hid)
        quirks = usbhid_lookup_quirk(le16_to_cpu(dev->descriptor.idVendor),
                        le16_to_cpu(dev->descriptor.idProduct));
 
+       if (quirks & HID_QUIRK_IGNORE)
+               return -ENODEV;
+
        /* Many keyboards and mice don't like to be polled for reports,
         * so we will always set the HID_QUIRK_NOGET flag for them. */
        if (interface->desc.bInterfaceSubClass == USB_INTERFACE_SUBCLASS_BOOT) {
@@ -1207,9 +1210,60 @@ static void hid_cease_io(struct usbhid_device *usbhid)
        usb_kill_urb(usbhid->urbin);
        usb_kill_urb(usbhid->urbctrl);
        usb_kill_urb(usbhid->urbout);
-       flush_scheduled_work();
 }
 
+/* Treat USB reset pretty much the same as suspend/resume */
+static int hid_pre_reset(struct usb_interface *intf)
+{
+       struct hid_device *hid = usb_get_intfdata(intf);
+       struct usbhid_device *usbhid = hid->driver_data;
+
+       spin_lock_irq(&usbhid->lock);
+       set_bit(HID_RESET_PENDING, &usbhid->iofl);
+       spin_unlock_irq(&usbhid->lock);
+       cancel_work_sync(&usbhid->restart_work);
+       hid_cease_io(usbhid);
+
+       return 0;
+}
+
+/* Same routine used for post_reset and reset_resume */
+static int hid_post_reset(struct usb_interface *intf)
+{
+       struct usb_device *dev = interface_to_usbdev (intf);
+       struct hid_device *hid = usb_get_intfdata(intf);
+       struct usbhid_device *usbhid = hid->driver_data;
+       int status;
+       spin_lock_irq(&usbhid->lock);
+       clear_bit(HID_RESET_PENDING, &usbhid->iofl);
+       spin_unlock_irq(&usbhid->lock);
+       hid_set_idle(dev, intf->cur_altsetting->desc.bInterfaceNumber, 0, 0);
+       /* FIXME: Any more reinitialization needed? */
+       status = hid_start_in(hid);
+       if (status < 0)
+               hid_io_error(hid);
+       usbhid_restart_queues(usbhid);
+
+       return 0;
+}
+
+int usbhid_get_power(struct hid_device *hid)
+{
+       struct usbhid_device *usbhid = hid->driver_data;
+       return usb_autopm_get_interface(usbhid->intf);
+}
+
+void usbhid_put_power(struct hid_device *hid)
+{
+       struct usbhid_device *usbhid = hid->driver_data;
+       usb_autopm_put_interface(usbhid->intf);
+}
+
+
+#ifdef CONFIG_PM
 static int hid_suspend(struct usb_interface *intf, pm_message_t message)
 {
        struct hid_device *hid = usb_get_intfdata(intf);
@@ -1292,54 +1346,16 @@ static int hid_resume(struct usb_interface *intf)
        return 0;
 }
 
-/* Treat USB reset pretty much the same as suspend/resume */
-static int hid_pre_reset(struct usb_interface *intf)
-{
-       struct hid_device *hid = usb_get_intfdata(intf);
-       struct usbhid_device *usbhid = hid->driver_data;
-
-       spin_lock_irq(&usbhid->lock);
-       set_bit(HID_RESET_PENDING, &usbhid->iofl);
-       spin_unlock_irq(&usbhid->lock);
-       hid_cease_io(usbhid);
-
-       return 0;
-}
-
-/* Same routine used for post_reset and reset_resume */
-static int hid_post_reset(struct usb_interface *intf)
+static int hid_reset_resume(struct usb_interface *intf)
 {
-       struct usb_device *dev = interface_to_usbdev (intf);
        struct hid_device *hid = usb_get_intfdata(intf);
        struct usbhid_device *usbhid = hid->driver_data;
-       int status;
-       spin_lock_irq(&usbhid->lock);
-       clear_bit(HID_RESET_PENDING, &usbhid->iofl);
-       spin_unlock_irq(&usbhid->lock);
-       hid_set_idle(dev, intf->cur_altsetting->desc.bInterfaceNumber, 0, 0);
-       /* FIXME: Any more reinitialization needed? */
-       status = hid_start_in(hid);
-       if (status < 0)
-               hid_io_error(hid);
-       usbhid_restart_queues(usbhid);
-
-       return 0;
-}
 
-int usbhid_get_power(struct hid_device *hid)
-{
-       struct usbhid_device *usbhid = hid->driver_data;
-       return usb_autopm_get_interface(usbhid->intf);
+       clear_bit(HID_REPORTED_IDLE, &usbhid->iofl);
+       return hid_post_reset(intf);
 }
 
-void usbhid_put_power(struct hid_device *hid)
-{
-       struct usbhid_device *usbhid = hid->driver_data;
-       usb_autopm_put_interface(usbhid->intf);
-}
+#endif /* CONFIG_PM */
 
 static struct usb_device_id hid_usb_ids [] = {
        { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS,
@@ -1353,9 +1369,11 @@ static struct usb_driver hid_driver = {
        .name =         "usbhid",
        .probe =        hid_probe,
        .disconnect =   hid_disconnect,
+#ifdef CONFIG_PM
        .suspend =      hid_suspend,
        .resume =       hid_resume,
-       .reset_resume = hid_post_reset,
+       .reset_resume = hid_reset_resume,
+#endif
        .pre_reset =    hid_pre_reset,
        .post_reset =   hid_post_reset,
        .id_table =     hid_usb_ids,