Merge branches 'upstream-fixes', 'bkl-removal', 'debugfs-fixes' and 'hid-suspend...
authorJiri Kosina <jkosina@suse.cz>
Wed, 19 May 2010 12:05:06 +0000 (14:05 +0200)
committerJiri Kosina <jkosina@suse.cz>
Wed, 19 May 2010 12:05:06 +0000 (14:05 +0200)
1  2  3  4  5 
drivers/hid/hid-core.c
drivers/hid/hidraw.c
drivers/hid/usbhid/hid-core.c
include/linux/hid.h

diff --combined drivers/hid/hid-core.c
@@@@@@ -653,9 -653,10 -653,10 -653,10 -653,10 +653,9 @@@@@@ int hid_parse_report(struct hid_device 
        if (device->driver->report_fixup)
                device->driver->report_fixup(device, start, size);
     
 ----   device->rdesc = kmalloc(size, GFP_KERNEL);
 ++++   device->rdesc = kmemdup(start, size, GFP_KERNEL);
        if (device->rdesc == NULL)
                return -ENOMEM;
 ----   memcpy(device->rdesc, start, size);
        device->rsize = size;
     
        parser = vmalloc(sizeof(struct hid_parser));
@@@@@@ -939,8 -940,13 -940,13 -940,13 -940,13 +939,8 @@@@@@ static void hid_output_field(struct hid
        unsigned count = field->report_count;
        unsigned offset = field->report_offset;
        unsigned size = field->report_size;
 ----   unsigned bitsused = offset + count * size;
        unsigned n;
     
 ----   /* make sure the unused bits in the last byte are zeros */
 ----   if (count > 0 && size > 0 && (bitsused % 8) != 0)
 ----           data[(bitsused-1)/8] &= (1 << (bitsused % 8)) - 1;
 ----
        for (n = 0; n < count; n++) {
                if (field->logical_minimum < 0) /* signed values */
                        implement(data, offset + n * size, size, s32ton(field->value[n], size));
@@@@@@ -960,7 -966,6 -966,6 -966,6 -966,6 +960,7 @@@@@@ void hid_output_report(struct hid_repor
        if (report->id > 0)
                *data++ = report->id;
     
 ++++   memset(data, 0, ((report->size - 1) >> 3) + 1);
        for (n = 0; n < report->maxfield; n++)
                hid_output_field(report->field[n], data);
     }
@@@@@@ -1038,8 -1043,8 -1043,13 -1043,13 -1043,13 +1038,8 @@@@@@ void hid_report_raw_event(struct hid_de
     
        if ((hid->claimed & HID_CLAIMED_HIDDEV) && hid->hiddev_report_event)
                hid->hiddev_report_event(hid, report);
  ---   if (hid->claimed & HID_CLAIMED_HIDRAW) {
  ---           /* numbered reports need to be passed with the report num */
  ---           if (report_enum->numbered)
  ---                   hidraw_report_event(hid, data - 1, size + 1);
  ---           else
  ---                   hidraw_report_event(hid, data, size);
  ---   }
  +++   if (hid->claimed & HID_CLAIMED_HIDRAW)
  +++           hidraw_report_event(hid, data, size);
     
        for (a = 0; a < report->maxfield; a++)
                hid_input_field(hid, report->field[a], cdata, interrupt);
@@@@@@ -1081,35 -1086,35 -1091,35 -1091,28 -1091,35 +1081,28 @@@@@@ int hid_input_report(struct hid_device 
     
        buf = kmalloc(sizeof(char) * HID_DEBUG_BUFSIZE, GFP_ATOMIC);
     
--- -   if (!buf) {
--- -           report = hid_get_report(report_enum, data);
+++ +   if (!buf)
                goto nomem;
--- -   }
--- -
--- -   snprintf(buf, HID_DEBUG_BUFSIZE - 1,
--- -                   "\nreport (size %u) (%snumbered)\n", size, report_enum->numbered ? "" : "un");
--- -   hid_debug_event(hid, buf);
--- -
--- -   report = hid_get_report(report_enum, data);
--- -   if (!report) {
--- -           kfree(buf);
--- -           return -1;
--- -   }
     
        /* dump the report */
        snprintf(buf, HID_DEBUG_BUFSIZE - 1,
--- -                   "report %d (size %u) = ", report->id, size);
+++ +                   "\nreport (size %u) (%snumbered) = ", size, report_enum->numbered ? "" : "un");
        hid_debug_event(hid, buf);
+++ +
        for (i = 0; i < size; i++) {
                snprintf(buf, HID_DEBUG_BUFSIZE - 1,
                                " %02x", data[i]);
                hid_debug_event(hid, buf);
        }
        hid_debug_event(hid, "\n");
--- -
        kfree(buf);
     
     nomem:
+++ +   report = hid_get_report(report_enum, data);
+++ +
+++ +   if (!report)
+++ +           return -1;
+++ +
        if (hdrv && hdrv->raw_event && hid_match_report(hid, report)) {
                ret = hdrv->raw_event(hid, report, data, size);
                if (ret != 0)
@@@@@@ -1162,8 -1167,6 -1172,6 -1165,6 -1172,6 +1155,8 @@@@@@ int hid_connect(struct hid_device *hdev
        unsigned int i;
        int len;
     
 ++++   if (hdev->quirks & HID_QUIRK_HIDDEV_FORCE)
 ++++           connect_mask |= (HID_CONNECT_HIDDEV_FORCE | HID_CONNECT_HIDDEV);
        if (hdev->bus != BUS_USB)
                connect_mask &= ~HID_CONNECT_HIDDEV;
        if (hid_hiddev(hdev))
@@@@@@ -1243,7 -1246,6 -1251,6 -1244,6 -1251,6 +1236,7 @@@@@@ EXPORT_SYMBOL_GPL(hid_disconnect)
     /* a list of devices for which there is a specialized driver on HID bus */
     static const struct hid_device_id hid_blacklist[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_3M, USB_DEVICE_ID_3M1968) },
 ++++   { HID_USB_DEVICE(USB_VENDOR_ID_3M, USB_DEVICE_ID_3M2256) },
        { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU) },
        { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D) },
        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ATV_IRCONTROL) },
        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) },
        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) },
        { HID_USB_DEVICE(USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM) },
 ++++   { HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE) },
        { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) },
  +++   { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION_SOLAR) },
        { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) },
        { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1) },
        { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2) },
        { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH) },
        { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN) },
        { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) },
 ++++   { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE) },
        { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
        { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
        { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE) },
        { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb323) },
        { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb324) },
        { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb651) },
   +    { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb653) },
        { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654) },
        { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) },
        { HID_USB_DEVICE(USB_VENDOR_ID_TWINHAN, USB_DEVICE_ID_TWINHAN_IR_REMOTE) },
        { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SMARTJOY_PLUS) },
        { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH) },
 ++++   { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH) },
        { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) },
        { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) },
 ++++   { HID_USB_DEVICE(USB_VENDOR_ID_ZYDACRON, USB_DEVICE_ID_ZYDACRON_REMOTE_CONTROL) },
     
        { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT) },
        { }
@@@@@@ -1759,7 -1757,7 -1761,7 -1753,7 -1761,7 +1752,7 @@@@@@ int hid_add_device(struct hid_device *h
     
        /* we need to kill them here, otherwise they will stay allocated to
         * wait for coming driver */
 ----   if (hid_ignore(hdev))
 ++++   if (!(hdev->quirks & HID_QUIRK_NO_IGNORE) && hid_ignore(hdev))
                return -ENODEV;
     
        /* XXX hack, any other cleaner solution after the driver core
        dev_set_name(&hdev->dev, "%04X:%04X:%04X.%04X", hdev->bus,
                     hdev->vendor, hdev->product, atomic_inc_return(&id));
     
 ++++   hid_debug_register(hdev, dev_name(&hdev->dev));
        ret = device_add(&hdev->dev);
        if (!ret)
                hdev->status |= HID_STAT_ADDED;
 ----
 ----   hid_debug_register(hdev, dev_name(&hdev->dev));
 ++++   else
 ++++           hid_debug_unregister(hdev);
     
        return ret;
     }
diff --combined drivers/hid/hidraw.c
     #include <linux/poll.h>
     #include <linux/device.h>
     #include <linux/major.h>
  ++ #include <linux/slab.h>
     #include <linux/hid.h>
     #include <linux/mutex.h>
     #include <linux/sched.h>
     static ssize_t hidraw_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
     {
        unsigned int minor = iminor(file->f_path.dentry->d_inode);
-- --   /* FIXME: What stops hidraw_table going NULL */
-- --   struct hid_device *dev = hidraw_table[minor]->hid;
++ ++   struct hid_device *dev;
        __u8 *buf;
        int ret = 0;
     
-- --   if (!dev->hid_output_raw_report)
-- --           return -ENODEV;
++ ++   mutex_lock(&minors_lock);
++ ++   dev = hidraw_table[minor]->hid;
++ ++
++ ++   if (!dev->hid_output_raw_report) {
++ ++           ret = -ENODEV;
++ ++           goto out;
++ ++   }
     
        if (count > HID_MAX_BUFFER_SIZE) {
                printk(KERN_WARNING "hidraw: pid %d passed too large report\n",
                                task_pid_nr(current));
-- --           return -EINVAL;
++ ++           ret = -EINVAL;
++ ++           goto out;
        }
     
        if (count < 2) {
                printk(KERN_WARNING "hidraw: pid %d passed too short report\n",
                                task_pid_nr(current));
-- --           return -EINVAL;
++ ++           ret = -EINVAL;
++ ++           goto out;
        }
     
        buf = kmalloc(count * sizeof(__u8), GFP_KERNEL);
-- --   if (!buf)
-- --           return -ENOMEM;
++ ++   if (!buf) {
++ ++           ret = -ENOMEM;
++ ++           goto out;
++ ++   }
     
        if (copy_from_user(buf, buffer, count)) {
                ret = -EFAULT;
-- --           goto out;
++ ++           goto out_free;
        }
     
        ret = dev->hid_output_raw_report(dev, buf, count, HID_OUTPUT_REPORT);
-- --out:
++ ++out_free:
        kfree(buf);
++ ++out:
++ ++   mutex_unlock(&minors_lock);
        return ret;
     }
     
@@@@@@ -165,11 -165,11 -174,8 -164,11 -165,11 +175,8 @@@@@@ static int hidraw_open(struct inode *in
                goto out;
        }
     
-- --   lock_kernel();
        mutex_lock(&minors_lock);
        if (!hidraw_table[minor]) {
-- --           printk(KERN_EMERG "hidraw device with minor %d doesn't exist\n",
-- --                           minor);
                kfree(list);
                err = -ENODEV;
                goto out_unlock;
     
     out_unlock:
        mutex_unlock(&minors_lock);
-- --   unlock_kernel();
     out:
        return err;
     
@@@@@@ -209,11 -209,11 -214,8 -208,11 -209,11 +215,8 @@@@@@ static int hidraw_release(struct inode 
        struct hidraw *dev;
        struct hidraw_list *list = file->private_data;
     
-- --   if (!hidraw_table[minor]) {
-- --           printk(KERN_EMERG "hidraw device with minor %d doesn't exist\n",
-- --                           minor);
++ ++   if (!hidraw_table[minor])
                return -ENODEV;
-- --   }
     
        list_del(&list->node);
        dev = hidraw_table[minor];
@@@@@@ -238,11 -238,11 -240,12 -237,11 -238,11 +241,12 @@@@@@ static long hidraw_ioctl(struct file *f
        struct inode *inode = file->f_path.dentry->d_inode;
        unsigned int minor = iminor(inode);
        long ret = 0;
-- --   /* FIXME: What stops hidraw_table going NULL */
-- --   struct hidraw *dev = hidraw_table[minor];
++ ++   struct hidraw *dev;
        void __user *user_arg = (void __user*) arg;
     
-- --   lock_kernel();
++ ++   mutex_lock(&minors_lock);
++ ++   dev = hidraw_table[minor];
++ ++
        switch (cmd) {
                case HIDIOCGRDESCSIZE:
                        if (put_user(dev->hid->rsize, (int __user *)arg))
                                                -EFAULT : len;
                                        break;
                                }
 ----                }
 ++++           }
     
                ret = -ENOTTY;
        }
-- --   unlock_kernel();
++ ++   mutex_unlock(&minors_lock);
        return ret;
     }
     
@@@@@@ -807,36 -807,16 -807,16 -807,16 -807,16 +807,36 @@@@@@ static int usbhid_output_raw_report(str
        struct usb_host_interface *interface = intf->cur_altsetting;
        int ret;
     
 ----   ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
 ----           HID_REQ_SET_REPORT,
 ----           USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
 ----           ((report_type + 1) << 8) | *buf,
 ----           interface->desc.bInterfaceNumber, buf + 1, count - 1,
 ----           USB_CTRL_SET_TIMEOUT);
 ----
 ----   /* count also the report id */
 ----   if (ret > 0)
 ----           ret++;
 ++++   if (usbhid->urbout) {
 ++++           int actual_length;
 ++++           int skipped_report_id = 0;
 ++++           if (buf[0] == 0x0) {
 ++++                   /* Don't send the Report ID */
 ++++                   buf++;
 ++++                   count--;
 ++++                   skipped_report_id = 1;
 ++++           }
 ++++           ret = usb_interrupt_msg(dev, usbhid->urbout->pipe,
 ++++                   buf, count, &actual_length,
 ++++                   USB_CTRL_SET_TIMEOUT);
 ++++           /* return the number of bytes transferred */
 ++++           if (ret == 0) {
 ++++                   ret = actual_length;
 ++++                   /* count also the report id */
 ++++                   if (skipped_report_id)
 ++++                           ret++;
 ++++           }
 ++++   } else {
 ++++           ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
 ++++                   HID_REQ_SET_REPORT,
 ++++                   USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
 ++++                   ((report_type + 1) << 8) | *buf,
 ++++                   interface->desc.bInterfaceNumber, buf + 1, count - 1,
 ++++                   USB_CTRL_SET_TIMEOUT);
 ++++           /* count also the report id */
 ++++           if (ret > 0)
 ++++                   ret++;
 ++++   }
     
        return ret;
     }
@@@@@@ -1019,6 -999,6 -999,13 -999,13 -999,13 +1019,6 @@@@@@ static int usbhid_start(struct hid_devi
                }
        }
     
  ---   init_waitqueue_head(&usbhid->wait);
  ---   INIT_WORK(&usbhid->reset_work, hid_reset);
  ---   INIT_WORK(&usbhid->restart_work, __usbhid_restart_queues);
  ---   setup_timer(&usbhid->io_retry, hid_retry_timeout, (unsigned long) hid);
  ---
  ---   spin_lock_init(&usbhid->lock);
  ---
        usbhid->urbctrl = usb_alloc_urb(0, GFP_KERNEL);
        if (!usbhid->urbctrl) {
                ret = -ENOMEM;
        /* Some keyboards don't work until their LEDs have been set.
         * Since BIOSes do set the LEDs, it must be safe for any device
         * that supports the keyboard boot protocol.
 ++++    * In addition, enable remote wakeup by default for all keyboard
 ++++    * devices supporting the boot protocol.
         */
        if (interface->desc.bInterfaceSubClass == USB_INTERFACE_SUBCLASS_BOOT &&
                        interface->desc.bInterfaceProtocol ==
 ----                           USB_INTERFACE_PROTOCOL_KEYBOARD)
 ++++                           USB_INTERFACE_PROTOCOL_KEYBOARD) {
                usbhid_set_leds(hid);
 ----
 ++++           device_set_wakeup_enable(&dev->dev, 1);
 ++++   }
        return 0;
     
     fail:
@@@@@@ -1156,7 -1133,6 -1140,6 -1140,6 -1140,6 +1156,7 @@@@@@ static int usbhid_probe(struct usb_inte
        hid->vendor = le16_to_cpu(dev->descriptor.idVendor);
        hid->product = le16_to_cpu(dev->descriptor.idProduct);
        hid->name[0] = 0;
 ++++   hid->quirks = usbhid_lookup_quirk(hid->vendor, hid->product);
        if (intf->cur_altsetting->desc.bInterfaceProtocol ==
                        USB_INTERFACE_PROTOCOL_MOUSE)
                hid->type = HID_TYPE_USBMOUSE;
        usbhid->intf = intf;
        usbhid->ifnum = interface->desc.bInterfaceNumber;
     
  +++   init_waitqueue_head(&usbhid->wait);
  +++   INIT_WORK(&usbhid->reset_work, hid_reset);
  +++   INIT_WORK(&usbhid->restart_work, __usbhid_restart_queues);
  +++   setup_timer(&usbhid->io_retry, hid_retry_timeout, (unsigned long) hid);
  +++   spin_lock_init(&usbhid->lock);
  +++
        ret = hid_add_device(hid);
        if (ret) {
                if (ret != -ENODEV)
@@@@@@ -1313,6 -1289,6 -1290,6 -1290,6 -1290,11 +1313,11 @@@@@@ static int hid_suspend(struct usb_inter
                {
                        set_bit(HID_REPORTED_IDLE, &usbhid->iofl);
                        spin_unlock_irq(&usbhid->lock);
++++                    if (hid->driver && hid->driver->suspend) {
++++                            status = hid->driver->suspend(hid, message);
++++                            if (status < 0)
++++                                    return status;
++++                    }
                } else {
                        usbhid_mark_busy(usbhid);
                        spin_unlock_irq(&usbhid->lock);
                }
     
        } else {
++++            if (hid->driver && hid->driver->suspend) {
++++                    status = hid->driver->suspend(hid, message);
++++                    if (status < 0)
++++                            return status;
++++            }
                spin_lock_irq(&usbhid->lock);
                set_bit(HID_REPORTED_IDLE, &usbhid->iofl);
                spin_unlock_irq(&usbhid->lock);
@@@@@@ -1374,6 -1350,6 -1351,6 -1351,6 -1361,11 +1384,11 @@@@@@ static int hid_resume(struct usb_interf
                hid_io_error(hid);
        usbhid_restart_queues(usbhid);
     
++++    if (status >= 0 && hid->driver && hid->driver->resume) {
++++            int ret = hid->driver->resume(hid);
++++            if (ret < 0)
++++                    status = ret;
++++    }
        dev_dbg(&intf->dev, "resume status %d\n", status);
        return 0;
     }
@@@@@@ -1382,9 -1358,9 -1359,9 -1359,9 -1374,16 +1397,16 @@@@@@ static int hid_reset_resume(struct usb_
     {
        struct hid_device *hid = usb_get_intfdata(intf);
        struct usbhid_device *usbhid = hid->driver_data;
++++    int status;
     
        clear_bit(HID_REPORTED_IDLE, &usbhid->iofl);
----    return hid_post_reset(intf);
++++    status = hid_post_reset(intf);
++++    if (status >= 0 && hid->driver && hid->driver->reset_resume) {
++++            int ret = hid->driver->reset_resume(hid);
++++            if (ret < 0)
++++                    status = ret;
++++    }
++++    return status;
     }
     
     #endif /* CONFIG_PM */
diff --combined include/linux/hid.h
@@@@@@ -308,13 -308,11 -308,11 -308,11 -308,11 +308,13 @@@@@@ struct hid_item 
     #define HID_QUIRK_NOTOUCH                  0x00000002
     #define HID_QUIRK_IGNORE                   0x00000004
     #define HID_QUIRK_NOGET                            0x00000008
 ++++#define HID_QUIRK_HIDDEV_FORCE                     0x00000010
     #define HID_QUIRK_BADPAD                   0x00000020
     #define HID_QUIRK_MULTI_INPUT                      0x00000040
     #define HID_QUIRK_SKIP_OUTPUT_REPORTS              0x00010000
     #define HID_QUIRK_FULLSPEED_INTERVAL               0x10000000
     #define HID_QUIRK_NO_INIT_REPORTS          0x20000000
 ++++#define HID_QUIRK_NO_IGNORE                        0x40000000
     
     /*
      * This is the global environment of the parser. This information is
@@@@@@ -591,6 -589,6 -589,6 -589,6 -589,9 +591,9 @@@@@@ struct hid_usage_id 
      * @report_fixup: called before report descriptor parsing (NULL means nop)
      * @input_mapping: invoked on input registering before mapping an usage
      * @input_mapped: invoked on input registering after mapping an usage
++++  * @suspend: invoked on suspend (NULL means nop)
++++  * @resume: invoked on resume if device was not reset (NULL means nop)
++++  * @reset_resume: invoked on resume if device was reset (NULL means nop)
      *
      * raw_event and event should return 0 on no action performed, 1 when no
      * further processing should be done and negative on error
@@@@@@ -631,6 -629,6 -629,6 -629,6 -632,11 +634,11 @@@@@@ struct hid_driver 
        int (*input_mapped)(struct hid_device *hdev,
                        struct hid_input *hidinput, struct hid_field *field,
                        struct hid_usage *usage, unsigned long **bit, int *max);
++++ #ifdef CONFIG_PM
++++    int (*suspend)(struct hid_device *hdev, pm_message_t message);
++++    int (*resume)(struct hid_device *hdev);
++++    int (*reset_resume)(struct hid_device *hdev);
++++ #endif
     /* private: */
        struct device_driver driver;
     };