Merge branches 'for-3.12/devm', 'for-3.12/i2c-hid', 'for-3.12/i2c-hid-dt', 'for-3...
authorJiri Kosina <jkosina@suse.cz>
Fri, 6 Sep 2013 09:58:37 +0000 (11:58 +0200)
committerJiri Kosina <jkosina@suse.cz>
Fri, 6 Sep 2013 09:58:37 +0000 (11:58 +0200)
1  2  3  4  5  6  7  8 
drivers/hid/hid-apple.c
drivers/hid/hid-core.c
drivers/hid/hid-input.c
drivers/hid/hid-logitech-dj.c
drivers/hid/hid-magicmouse.c
drivers/hid/hid-sony.c
drivers/hid/i2c-hid/i2c-hid.c
drivers/hid/uhid.c
drivers/hid/usbhid/hid-core.c
include/linux/hid.h
include/linux/mod_devicetable.h

diff --combined drivers/hid/hid-apple.c
index c7710b5c69afbf009d0e9f2d727668e6cdae5045,feae88b53fcd7597bc477aeef4dae7182f8f05ed,feae88b53fcd7597bc477aeef4dae7182f8f05ed,bad40b9315b2353edfef6294592c3de0de247d49,feae88b53fcd7597bc477aeef4dae7182f8f05ed,c7710b5c69afbf009d0e9f2d727668e6cdae5045,c7710b5c69afbf009d0e9f2d727668e6cdae5045,feae88b53fcd7597bc477aeef4dae7182f8f05ed..881cf7b4f9a433f8ae3e0f6721b3789aa66731f7
@@@@@@@@@ -349,7 -349,7 -349,7 -349,7 -349,7 -349,7 -349,7 -349,7 +349,7 @@@@@@@@@ static int apple_probe(struct hid_devic
                unsigned int connect_mask = HID_CONNECT_DEFAULT;
                int ret;
        
--- ----        asc = kzalloc(sizeof(*asc), GFP_KERNEL);
+++ ++++        asc = devm_kzalloc(&hdev->dev, sizeof(*asc), GFP_KERNEL);
                if (asc == NULL) {
                        hid_err(hdev, "can't alloc apple descriptor\n");
                        return -ENOMEM;
                ret = hid_parse(hdev);
                if (ret) {
                        hid_err(hdev, "parse failed\n");
--- ----                goto err_free;
+++ ++++                return ret;
                }
        
                if (quirks & APPLE_HIDDEV)
                ret = hid_hw_start(hdev, connect_mask);
                if (ret) {
                        hid_err(hdev, "hw start failed\n");
--- ----                goto err_free;
+++ ++++                return ret;
                }
        
                return 0;
--- ----err_free:
--- ----        kfree(asc);
--- ----        return ret;
--- ----}
--- ----
--- ----static void apple_remove(struct hid_device *hdev)
--- ----{
--- ----        hid_hw_stop(hdev);
--- ----        kfree(hid_get_drvdata(hdev));
        }
        
        static const struct hid_device_id apple_devices[] = {
                        .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD },
                { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS),
                        .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
 ++++  +        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI),
 ++++  +                .driver_data = APPLE_HAS_FN },
 ++++  +        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING8_ISO),
 ++++  +                .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD },
 ++++  +        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING8_JIS),
 ++++  +                .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
                { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI),
                        .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
                { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO),
@@@@@@@@@ -551,7 -545,7 -545,7 -536,6 -545,7 -551,7 -551,7 -545,7 +542,6 @@@@@@@@@ static struct hid_driver apple_driver 
                .id_table = apple_devices,
                .report_fixup = apple_report_fixup,
                .probe = apple_probe,
--- ----        .remove = apple_remove,
                .event = apple_event,
                .input_mapping = apple_input_mapping,
                .input_mapped = apple_input_mapped,
diff --combined drivers/hid/hid-core.c
index 36668d1aca8fc2133299e93cf994857d78cbea2e,e39dac68063cdb2d8cc4816f890d7f45eae9e1f3,e39dac68063cdb2d8cc4816f890d7f45eae9e1f3,660dce9641626a2b2361e78777143415d59b911e,e39dac68063cdb2d8cc4816f890d7f45eae9e1f3,36668d1aca8fc2133299e93cf994857d78cbea2e,2ac13ca6edaa8324856fa48adbfa84ac1530f7e5,627fea6593a372fd58066f34cb43989e1bd4d243..2c778542e40ddf3bb71de1f967076cb38aac41a6
@@@@@@@@@ -63,6 -63,6 -63,6 -63,6 -63,6 -63,6 -63,8 -63,6 +63,8 @@@@@@@@@ struct hid_report *hid_register_report(
                struct hid_report_enum *report_enum = device->report_enum + type;
                struct hid_report *report;
        
++++++ +        if (id >= HID_MAX_IDS)
++++++ +                return NULL;
                if (report_enum->report_id_hash[id])
                        return report_enum->report_id_hash[id];
        
@@@@@@@@@ -404,8 -404,8 -404,8 -404,8 -404,8 -404,8 -406,10 -404,8 +406,10 @@@@@@@@@ static int hid_parser_global(struct hid
        
                case HID_GLOBAL_ITEM_TAG_REPORT_ID:
                        parser->global.report_id = item_udata(item);
------ -                if (parser->global.report_id == 0) {
------ -                        hid_err(parser->device, "report_id 0 is invalid\n");
++++++ +                if (parser->global.report_id == 0 ||
++++++ +                    parser->global.report_id >= HID_MAX_IDS) {
++++++ +                        hid_err(parser->device, "report_id %u is invalid\n",
++++++ +                                parser->global.report_id);
                                return -1;
                        }
                        return 0;
@@@@@@@@@ -450,7 -450,7 -450,7 -450,7 -450,7 -450,7 -454,7 -450,7 +454,7 @@@@@@@@@ static int hid_parser_local(struct hid_
                                }
                                parser->local.delimiter_depth--;
                        }
------                  return 1;
++++++                  return 0;
        
                case HID_LOCAL_ITEM_TAG_USAGE:
        
@@@@@@@@@ -575,7 -575,7 -575,7 -575,7 -575,7 -575,7 -579,7 -575,7 +579,7 @@@@@@@@@ static void hid_close_report(struct hid
                for (i = 0; i < HID_REPORT_TYPES; i++) {
                        struct hid_report_enum *report_enum = device->report_enum + i;
        
------ -                for (j = 0; j < 256; j++) {
++++++ +                for (j = 0; j < HID_MAX_IDS; j++) {
                                struct hid_report *report = report_enum->report_id_hash[j];
                                if (report)
                                        hid_free_report(report);
@@@@@@@@@ -677,12 -677,12 -677,12 -677,61 -677,12 -677,12 -681,12 -677,12 +681,61 @@@@@@@@@ static u8 *fetch_item(__u8 *start, __u
                return NULL;
        }
        
--- ----static void hid_scan_usage(struct hid_device *hid, u32 usage)
+++ ++++static void hid_scan_input_usage(struct hid_parser *parser, u32 usage)
        {
+++ ++++        struct hid_device *hid = parser->device;
+++ ++++
                if (usage == HID_DG_CONTACTID)
                        hid->group = HID_GROUP_MULTITOUCH;
        }
        
+++ ++++static void hid_scan_feature_usage(struct hid_parser *parser, u32 usage)
+++ ++++{
+++ ++++        if (usage == 0xff0000c5 && parser->global.report_count == 256 &&
+++ ++++            parser->global.report_size == 8)
+++ ++++                parser->scan_flags |= HID_SCAN_FLAG_MT_WIN_8;
+++ ++++}
+++ ++++
+++ ++++static void hid_scan_collection(struct hid_parser *parser, unsigned type)
+++ ++++{
+++ ++++        struct hid_device *hid = parser->device;
+++ ++++
+++ ++++        if (((parser->global.usage_page << 16) == HID_UP_SENSOR) &&
+++ ++++            type == HID_COLLECTION_PHYSICAL)
+++ ++++                hid->group = HID_GROUP_SENSOR_HUB;
+++ ++++}
+++ ++++
+++ ++++static int hid_scan_main(struct hid_parser *parser, struct hid_item *item)
+++ ++++{
+++ ++++        __u32 data;
+++ ++++        int i;
+++ ++++
+++ ++++        data = item_udata(item);
+++ ++++
+++ ++++        switch (item->tag) {
+++ ++++        case HID_MAIN_ITEM_TAG_BEGIN_COLLECTION:
+++ ++++                hid_scan_collection(parser, data & 0xff);
+++ ++++                break;
+++ ++++        case HID_MAIN_ITEM_TAG_END_COLLECTION:
+++ ++++                break;
+++ ++++        case HID_MAIN_ITEM_TAG_INPUT:
+++ ++++                for (i = 0; i < parser->local.usage_index; i++)
+++ ++++                        hid_scan_input_usage(parser, parser->local.usage[i]);
+++ ++++                break;
+++ ++++        case HID_MAIN_ITEM_TAG_OUTPUT:
+++ ++++                break;
+++ ++++        case HID_MAIN_ITEM_TAG_FEATURE:
+++ ++++                for (i = 0; i < parser->local.usage_index; i++)
+++ ++++                        hid_scan_feature_usage(parser, parser->local.usage[i]);
+++ ++++                break;
+++ ++++        }
+++ ++++
+++ ++++        /* Reset the local parser environment */
+++ ++++        memset(&parser->local, 0, sizeof(parser->local));
+++ ++++
+++ ++++        return 0;
+++ ++++}
+++ ++++
        /*
         * Scan a report descriptor before the device is added to the bus.
         * Sets device groups and other properties that determine what driver
         */
        static int hid_scan_report(struct hid_device *hid)
        {
--- ----        unsigned int page = 0, delim = 0;
+++ ++++        struct hid_parser *parser;
+++ ++++        struct hid_item item;
                __u8 *start = hid->dev_rdesc;
                __u8 *end = start + hid->dev_rsize;
--- ----        unsigned int u, u_min = 0, u_max = 0;
--- ----        struct hid_item item;
+++ ++++        static int (*dispatch_type[])(struct hid_parser *parser,
+++ ++++                                      struct hid_item *item) = {
+++ ++++                hid_scan_main,
+++ ++++                hid_parser_global,
+++ ++++                hid_parser_local,
+++ ++++                hid_parser_reserved
+++ ++++        };
+++ +++ 
+++ ++++        parser = vzalloc(sizeof(struct hid_parser));
+++ ++++        if (!parser)
+++ ++++                return -ENOMEM;
       +
+++ ++++        parser->device = hid;
                hid->group = HID_GROUP_GENERIC;
--- ----        while ((start = fetch_item(start, end, &item)) != NULL) {
--- ----                if (item.format != HID_ITEM_FORMAT_SHORT)
--- ----                        return -EINVAL;
--- ----                if (item.type == HID_ITEM_TYPE_GLOBAL) {
--- ----                        if (item.tag == HID_GLOBAL_ITEM_TAG_USAGE_PAGE)
--- ----                                page = item_udata(&item) << 16;
--- ----                } else if (item.type == HID_ITEM_TYPE_LOCAL) {
--- ----                        if (delim > 1)
--- ----                                break;
--- ----                        u = item_udata(&item);
--- ----                        if (item.size <= 2)
--- ----                                u += page;
--- ----                        switch (item.tag) {
--- ----                        case HID_LOCAL_ITEM_TAG_DELIMITER:
--- ----                                delim += !!u;
--- ----                                break;
--- ----                        case HID_LOCAL_ITEM_TAG_USAGE:
--- ----                                hid_scan_usage(hid, u);
--- ----                                break;
--- ----                        case HID_LOCAL_ITEM_TAG_USAGE_MINIMUM:
--- ----                                u_min = u;
--- ----                                break;
--- ----                        case HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM:
--- ----                                u_max = u;
--- ----                                for (u = u_min; u <= u_max; u++)
--- ----                                        hid_scan_usage(hid, u);
--- ----                                break;
--- ----                        }
--- ----                } else if (page == HID_UP_SENSOR &&
--- ----                        item.type == HID_ITEM_TYPE_MAIN &&
--- ----                        item.tag == HID_MAIN_ITEM_TAG_BEGIN_COLLECTION &&
--- ----                        (item_udata(&item) & 0xff) == HID_COLLECTION_PHYSICAL)
--- ----                        hid->group = HID_GROUP_SENSOR_HUB;
--- ----        }
        
+++ ++++        /*
+++ ++++         * The parsing is simpler than the one in hid_open_report() as we should
+++ ++++         * be robust against hid errors. Those errors will be raised by
+++ ++++         * hid_open_report() anyway.
+++ ++++         */
+++ ++++        while ((start = fetch_item(start, end, &item)) != NULL)
+++ ++++                dispatch_type[item.type](parser, &item);
+++ ++++
+++ ++++        /*
+++ ++++         * Handle special flags set during scanning.
+++ ++++         */
+++ ++++        if ((parser->scan_flags & HID_SCAN_FLAG_MT_WIN_8) &&
+++ ++++            (hid->group == HID_GROUP_MULTITOUCH))
+++ ++++                hid->group = HID_GROUP_MULTITOUCH_WIN_8;
+++ ++++
+++ ++++        vfree(parser);
                return 0;
        }
        
@@@@@@@@@ -1128,7 -1128,7 -1128,7 -1170,7 -1128,7 -1128,7 -1132,8 -1128,8 +1174,8 @@@@@@@@@ static void hid_output_field(const stru
        }
        
        /*
------   * Create a report.
++++++   * Create a report. 'data' has to be allocated using
++++++   * hid_alloc_report_buf() so that it has proper size.
         */
        
        void hid_output_report(struct hid_report *report, __u8 *data)
        }
        EXPORT_SYMBOL_GPL(hid_output_report);
        
++++++  /*
++++++   * Allocator for buffer that is going to be passed to hid_output_report()
++++++   */
++++++  u8 *hid_alloc_report_buf(struct hid_report *report, gfp_t flags)
++++++  {
++++++          /*
++++++           * 7 extra bytes are necessary to achieve proper functionality
++++++           * of implement() working on 8 byte chunks
++++++           */
++++++  
++++++          int len = ((report->size - 1) >> 3) + 1 + (report->id > 0) + 7;
++++++  
++++++          return kmalloc(len, flags);
++++++  }
++++++  EXPORT_SYMBOL_GPL(hid_alloc_report_buf);
++++++  
        /*
         * Set a field value. The report this field belongs to has to be
         * created and transferred to the device, to set this value in the
        
        int hid_set_field(struct hid_field *field, unsigned offset, __s32 value)
        {
------ -        unsigned size = field->report_size;
++++++ +        unsigned size;
++++++ +
++++++ +        if (!field)
++++++ +                return -1;
++++++ +
++++++ +        size = field->report_size;
        
                hid_dump_input(field->report->device, field->usage + offset, value);
        
@@@@@@@@@ -1547,9 -1547,6 -1547,6 -1589,6 -1547,6 -1547,9 -1573,9 -1564,6 +1615,9 @@@@@@@@@ static const struct hid_device_id hid_h
                { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI) },
                { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO) },
                { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS) },
 ++++  +        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI) },
 ++++  +        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING8_ISO) },
 ++++  +        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING8_JIS) },
                { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI) },
                { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO) },
                { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS) },
                { HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) },
                { HID_USB_DEVICE(USB_VENDOR_ID_KEYTOUCH, USB_DEVICE_ID_KEYTOUCH_IEC) },
                { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_GENIUS_GILA_GAMING_MOUSE) },
++++++          { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_GENIUS_GX_IMPERATOR) },
                { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) },
                { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_I405X) },
                { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X) },
                { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ISKU) },
                { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONEPLUS) },
                { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONEPURE) },
++++++ +        { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONEPURE_OPTICAL) },
                { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KOVAPLUS) },
                { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_LUA) },
                { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_PYRA_WIRED) },
                { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH) },
                { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SIRIUS_BATTERY_FREE_TABLET) },
                { HID_USB_DEVICE(USB_VENDOR_ID_X_TENSIONS, USB_DEVICE_ID_SPEEDLINK_VAD_CEZANNE) },
++++++          { HID_USB_DEVICE(USB_VENDOR_ID_XIN_MO, USB_DEVICE_ID_XIN_MO_DUAL_ARCADE) },
                { 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) },
@@@@@@@@@ -2192,9 -2189,6 -2189,6 -2231,6 -2189,6 -2192,9 -2221,9 -2208,6 +2263,9 @@@@@@@@@ static const struct hid_device_id hid_m
                { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI) },
                { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO) },
                { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS) },
 ++++  +        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI) },
 ++++  +        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING8_ISO) },
 ++++  +        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING8_JIS) },
                { 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) },
                { }
diff --combined drivers/hid/hid-input.c
index 7480799e535cb229a8bae89cf3795d1a5e91b738,7480799e535cb229a8bae89cf3795d1a5e91b738,7480799e535cb229a8bae89cf3795d1a5e91b738,7480799e535cb229a8bae89cf3795d1a5e91b738,308eee8fc7c3b1145b62b5508404d24655c355f9,7480799e535cb229a8bae89cf3795d1a5e91b738,3fc4034a43678e0282b8e9c4bba42bd3648eeee6,7480799e535cb229a8bae89cf3795d1a5e91b738..b420f4a0fd28101e0e697a48e581fe31826f9a56
@@@@@@@@@ -340,7 -340,7 -340,7 -340,7 -340,7 -340,7 -340,7 -340,7 +340,7 @@@@@@@@@ static int hidinput_get_battery_propert
        {
                struct hid_device *dev = container_of(psy, struct hid_device, battery);
                int ret = 0;
------ -        __u8 buf[2] = {};
++++++ +        __u8 *buf;
        
                switch (prop) {
                case POWER_SUPPLY_PROP_PRESENT:
                        break;
        
                case POWER_SUPPLY_PROP_CAPACITY:
++++++ +
++++++ +                buf = kmalloc(2 * sizeof(__u8), GFP_KERNEL);
++++++ +                if (!buf) {
++++++ +                        ret = -ENOMEM;
++++++ +                        break;
++++++ +                }
                        ret = dev->hid_get_raw_report(dev, dev->battery_report_id,
------ -                                              buf, sizeof(buf),
++++++ +                                              buf, 2,
                                                      dev->battery_report_type);
        
                        if (ret != 2) {
                                ret = -ENODATA;
++++++ +                        kfree(buf);
                                break;
                        }
                        ret = 0;
                            buf[1] <= dev->battery_max)
                                val->intval = (100 * (buf[1] - dev->battery_min)) /
                                        (dev->battery_max - dev->battery_min);
++++++ +                kfree(buf);
                        break;
        
                case POWER_SUPPLY_PROP_MODEL_NAME:
@@@@@@@@@ -1137,6 -1137,6 -1137,6 -1137,6 -1137,74 -1137,6 -1145,6 -1137,6 +1145,74 @@@@@@@@@ unsigned int hidinput_count_leds(struc
        }
        EXPORT_SYMBOL_GPL(hidinput_count_leds);
        
++++ +++static void hidinput_led_worker(struct work_struct *work)
++++ +++{
++++ +++        struct hid_device *hid = container_of(work, struct hid_device,
++++ +++                                              led_work);
++++ +++        struct hid_field *field;
++++ +++        struct hid_report *report;
++++ +++        int len;
++++ +++        __u8 *buf;
++++ +++
++++ +++        field = hidinput_get_led_field(hid);
++++ +++        if (!field)
++++ +++                return;
++++ +++
++++ +++        /*
++++ +++         * field->report is accessed unlocked regarding HID core. So there might
++++ +++         * be another incoming SET-LED request from user-space, which changes
++++ +++         * the LED state while we assemble our outgoing buffer. However, this
++++ +++         * doesn't matter as hid_output_report() correctly converts it into a
++++ +++         * boolean value no matter what information is currently set on the LED
++++ +++         * field (even garbage). So the remote device will always get a valid
++++ +++         * request.
++++ +++         * And in case we send a wrong value, a next led worker is spawned
++++ +++         * for every SET-LED request so the following worker will send the
++++ +++         * correct value, guaranteed!
++++ +++         */
++++ +++
++++ +++        report = field->report;
++++ +++
++++ +++        /* use custom SET_REPORT request if possible (asynchronous) */
++++ +++        if (hid->ll_driver->request)
++++ +++                return hid->ll_driver->request(hid, report, HID_REQ_SET_REPORT);
++++ +++
++++ +++        /* fall back to generic raw-output-report */
++++ +++        len = ((report->size - 1) >> 3) + 1 + (report->id > 0);
++++ +++        buf = kmalloc(len, GFP_KERNEL);
++++ +++        if (!buf)
++++ +++                return;
++++ +++
++++ +++        hid_output_report(report, buf);
++++ +++        /* synchronous output report */
++++ +++        hid->hid_output_raw_report(hid, buf, len, HID_OUTPUT_REPORT);
++++ +++        kfree(buf);
++++ +++}
++++ +++
++++ +++static int hidinput_input_event(struct input_dev *dev, unsigned int type,
++++ +++                                unsigned int code, int value)
++++ +++{
++++ +++        struct hid_device *hid = input_get_drvdata(dev);
++++ +++        struct hid_field *field;
++++ +++        int offset;
++++ +++
++++ +++        if (type == EV_FF)
++++ +++                return input_ff_event(dev, type, code, value);
++++ +++
++++ +++        if (type != EV_LED)
++++ +++                return -1;
++++ +++
++++ +++        if ((offset = hidinput_find_field(hid, type, code, &field)) == -1) {
++++ +++                hid_warn(dev, "event field not found\n");
++++ +++                return -1;
++++ +++        }
++++ +++
++++ +++        hid_set_field(field, offset, value);
++++ +++
++++ +++        schedule_work(&hid->led_work);
++++ +++        return 0;
++++ +++}
++++ +++
        static int hidinput_open(struct input_dev *dev)
        {
                struct hid_device *hid = input_get_drvdata(dev);
@@@@@@@@@ -1183,7 -1183,7 -1183,7 -1183,7 -1251,10 -1183,7 -1191,7 -1183,7 +1259,10 @@@@@@@@@ static struct hid_input *hidinput_alloc
                }
        
                input_set_drvdata(input_dev, hid);
---- ---        input_dev->event = hid->ll_driver->hidinput_input_event;
++++ +++        if (hid->ll_driver->hidinput_input_event)
++++ +++                input_dev->event = hid->ll_driver->hidinput_input_event;
++++ +++        else if (hid->ll_driver->request || hid->hid_output_raw_report)
++++ +++                input_dev->event = hidinput_input_event;
                input_dev->open = hidinput_open;
                input_dev->close = hidinput_close;
                input_dev->setkeycode = hidinput_setkeycode;
@@@@@@@@@ -1278,6 -1278,6 -1278,6 -1278,6 -1349,7 -1278,6 -1286,6 -1278,6 +1357,7 @@@@@@@@@ int hidinput_connect(struct hid_device 
                int i, j, k;
        
                INIT_LIST_HEAD(&hid->inputs);
++++ +++        INIT_WORK(&hid->led_work, hidinput_led_worker);
        
                if (!force) {
                        for (i = 0; i < hid->maxcollection; i++) {
@@@@@@@@@ -1379,6 -1379,6 -1379,6 -1379,6 -1451,12 -1379,6 -1387,6 -1379,6 +1459,12 @@@@@@@@@ void hidinput_disconnect(struct hid_dev
                        input_unregister_device(hidinput->input);
                        kfree(hidinput);
                }
++++ +++
++++ +++        /* led_work is spawned by input_dev callbacks, but doesn't access the
++++ +++         * parent input_dev at all. Once all input devices are removed, we
++++ +++         * know that led_work will never get restarted, so we can cancel it
++++ +++         * synchronously and are safe. */
++++ +++        cancel_work_sync(&hid->led_work);
        }
        EXPORT_SYMBOL_GPL(hidinput_disconnect);
        
index cd33084c78602146d42efca60e358d08f00da219,5207591a598c05944a348be2252c4a346e0e5cfa,db3192b24e6e5700fc2b75b4c87e42450a1aacd5,5207591a598c05944a348be2252c4a346e0e5cfa,5207591a598c05944a348be2252c4a346e0e5cfa,cd33084c78602146d42efca60e358d08f00da219,d0e5963c1ba189a877ece23123839d8f3a29df8c,d318222c63157e80a1e4b39155f15d95683a28a1..7800b141056243400bfa316b7289e2c8431aa82a
@@@@@@@@@ -192,7 -192,6 -192,6 -192,6 -192,6 -192,7 -192,7 -192,6 +192,7 @@@@@@@@@ static struct hid_ll_driver logi_dj_ll_
        static int logi_dj_output_hidraw_report(struct hid_device *hid, u8 * buf,
                                                size_t count,
                                                unsigned char report_type);
 ++++  +static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev);
        
        static void logi_dj_recv_destroy_djhid_device(struct dj_receiver_dev *djrcv_dev,
                                                        struct dj_report *dj_report)
@@@@@@@@@ -233,7 -232,6 -232,6 -232,6 -232,6 -233,7 -233,7 -232,6 +233,7 @@@@@@@@@ static void logi_dj_recv_add_djhid_devi
                if (dj_report->report_params[DEVICE_PAIRED_PARAM_SPFUNCTION] &
                    SPFUNCTION_DEVICE_LIST_EMPTY) {
                        dbg_hid("%s: device list is empty\n", __func__);
 ++++  +                djrcv_dev->querying_devices = false;
                        return;
                }
        
                        return;
                }
        
 ++++  +        if (djrcv_dev->paired_dj_devices[dj_report->device_index]) {
 ++++  +                /* The device is already known. No need to reallocate it. */
 ++++  +                dbg_hid("%s: device is already known\n", __func__);
 ++++  +                return;
 ++++  +        }
 ++++  +
                dj_hiddev = hid_allocate_device();
                if (IS_ERR(dj_hiddev)) {
                        dev_err(&djrcv_hdev->dev, "%s: hid_allocate_device failed\n",
@@@@@@@@@ -313,7 -305,6 -305,6 -305,6 -305,6 -313,7 -313,7 -305,6 +313,7 @@@@@@@@@ static void delayedwork_callback(struc
                struct dj_report dj_report;
                unsigned long flags;
                int count;
 ++++  +        int retval;
        
                dbg_hid("%s\n", __func__);
        
                        logi_dj_recv_destroy_djhid_device(djrcv_dev, &dj_report);
                        break;
                default:
 ++++  +        /* A normal report (i. e. not belonging to a pair/unpair notification)
 ++++  +         * arriving here, means that the report arrived but we did not have a
 ++++  +         * paired dj_device associated to the report's device_index, this
 ++++  +         * means that the original "device paired" notification corresponding
 ++++  +         * to this dj_device never arrived to this driver. The reason is that
 ++++  +         * hid-core discards all packets coming from a device while probe() is
 ++++  +         * executing. */
 ++++  +        if (!djrcv_dev->paired_dj_devices[dj_report.device_index]) {
 ++++  +                /* ok, we don't know the device, just re-ask the
 ++++  +                 * receiver for the list of connected devices. */
 ++++  +                retval = logi_dj_recv_query_paired_devices(djrcv_dev);
 ++++  +                if (!retval) {
 ++++  +                        /* everything went fine, so just leave */
 ++++  +                        break;
 ++++  +                }
 ++++  +                dev_err(&djrcv_dev->hdev->dev,
 ++++  +                        "%s:logi_dj_recv_query_paired_devices "
 ++++  +                        "error:%d\n", __func__, retval);
 ++++  +                }
                        dbg_hid("%s: unexpected report type\n", __func__);
                }
        }
@@@@@@@@@ -395,12 -367,6 -367,6 -367,6 -367,6 -395,12 -395,12 -367,6 +395,12 @@@@@@@@@ static void logi_dj_recv_forward_null_r
                if (!djdev) {
                        dbg_hid("djrcv_dev->paired_dj_devices[dj_report->device_index]"
                                " is NULL, index %d\n", dj_report->device_index);
 ++++  +                kfifo_in(&djrcv_dev->notif_fifo, dj_report, sizeof(struct dj_report));
 ++++  +
 ++++  +                if (schedule_work(&djrcv_dev->work) == 0) {
 ++++  +                        dbg_hid("%s: did not schedule the work item, was already "
 ++++  +                        "queued\n", __func__);
 ++++  +                }
                        return;
                }
        
@@@@@@@@@ -431,12 -397,6 -397,6 -397,6 -397,6 -431,12 -431,12 -397,6 +431,12 @@@@@@@@@ static void logi_dj_recv_forward_report
                if (dj_device == NULL) {
                        dbg_hid("djrcv_dev->paired_dj_devices[dj_report->device_index]"
                                " is NULL, index %d\n", dj_report->device_index);
 ++++  +                kfifo_in(&djrcv_dev->notif_fifo, dj_report, sizeof(struct dj_report));
 ++++  +
 ++++  +                if (schedule_work(&djrcv_dev->work) == 0) {
 ++++  +                        dbg_hid("%s: did not schedule the work item, was already "
 ++++  +                        "queued\n", __func__);
 ++++  +                }
                        return;
                }
        
@@@@@@@@@ -484,10 -444,6 -444,6 -444,6 -444,6 -484,10 -484,10 -444,6 +484,10 @@@@@@@@@ static int logi_dj_recv_query_paired_de
                struct dj_report *dj_report;
                int retval;
        
 ++++  +        /* no need to protect djrcv_dev->querying_devices */
 ++++  +        if (djrcv_dev->querying_devices)
 ++++  +                return 0;
 ++++  +
                dj_report = kzalloc(sizeof(struct dj_report), GFP_KERNEL);
                if (!dj_report)
                        return -ENOMEM;
                return retval;
        }
        
 ++++  +
        static int logi_dj_recv_switch_to_dj_mode(struct dj_receiver_dev *djrcv_dev,
                                                  unsigned timeout)
        {
@@@@@@@@@ -619,7 -574,7 -574,7 -574,7 -574,7 -619,7 -619,7 -574,7 +619,7 @@@@@@@@@ static int logi_dj_ll_input_event(struc
        
                struct hid_field *field;
                struct hid_report *report;
------          unsigned char data[8];
++++++          unsigned char *data;
                int offset;
        
                dbg_hid("%s: %s, type:%d | code:%d | value:%d\n",
                        return -1;
                }
                hid_set_field(field, offset, value);
++++++  
++++++          data = hid_alloc_report_buf(field->report, GFP_ATOMIC);
++++++          if (!data) {
++++++                  dev_warn(&dev->dev, "failed to allocate report buf memory\n");
++++++                  return -1;
++++++          }
++++++  
                hid_output_report(field->report, &data[0]);
        
                output_report_enum = &dj_rcv_hiddev->report_enum[HID_OUTPUT_REPORT];
        
                hid_hw_request(dj_rcv_hiddev, report, HID_REQ_SET_REPORT);
        
------          return 0;
++++++          kfree(data);
        
++++++          return 0;
        }
        
        static int logi_dj_ll_start(struct hid_device *hid)
@@@@@@@@@ -801,10 -756,10 -756,10 -756,10 -756,10 -801,10 -809,10 -764,10 +809,10 @@@@@@@@@ static int logi_dj_probe(struct hid_dev
                }
        
                /* This is enabling the polling urb on the IN endpoint */
-- -----        retval = hdev->ll_driver->open(hdev);
++ +++++        retval = hid_hw_open(hdev);
                if (retval < 0) {
-- -----                dev_err(&hdev->dev, "%s:hdev->ll_driver->open returned "
-- -----                        "error:%d\n", __func__, retval);
++ +++++                dev_err(&hdev->dev, "%s:hid_hw_open returned error:%d\n",
++ +++++                        __func__, retval);
                        goto llopen_failed;
                }
        
                return retval;
        
        logi_dj_recv_query_paired_devices_failed:
-- -----        hdev->ll_driver->close(hdev);
++ +++++        hid_hw_close(hdev);
        
        llopen_failed:
        switch_to_dj_mode_fail:
@@@@@@@@@ -863,7 -818,7 -818,7 -818,7 -818,7 -863,7 -871,7 -826,7 +871,7 @@@@@@@@@ static void logi_dj_remove(struct hid_d
        
                cancel_work_sync(&djrcv_dev->work);
        
-- -----        hdev->ll_driver->close(hdev);
++ +++++        hid_hw_close(hdev);
                hid_hw_stop(hdev);
        
                /* I suppose that at this point the only context that can access
index 5bc37343eb22b3de7f3cca6163c6f1fd9a10dd4b,5bc37343eb22b3de7f3cca6163c6f1fd9a10dd4b,5bc37343eb22b3de7f3cca6163c6f1fd9a10dd4b,d393eb7ddaf0ef15e4ffeea4451e0d3c801fe37b,5bc37343eb22b3de7f3cca6163c6f1fd9a10dd4b,5bc37343eb22b3de7f3cca6163c6f1fd9a10dd4b,a32f5a24b27ceadcdfe33e05a8fe9715eed4d38a,a32f5a24b27ceadcdfe33e05a8fe9715eed4d38a..3b43d1cfa9368609302de46a73658779199d446f
@@@@@@@@@ -36,7 -36,7 -36,7 -36,7 -36,7 -36,7 -36,7 -36,7 +36,7 @@@@@@@@@ MODULE_PARM_DESC(emulate_scroll_wheel, 
        static unsigned int scroll_speed = 32;
        static int param_set_scroll_speed(const char *val, struct kernel_param *kp) {
                unsigned long speed;
------          if (!val || strict_strtoul(val, 0, &speed) || speed > 63)
++++++          if (!val || kstrtoul(val, 0, &speed) || speed > 63)
                        return -EINVAL;
                scroll_speed = speed;
                return 0;
@@@@@@@@@ -484,7 -484,7 -484,7 -484,7 -484,7 -484,7 -484,7 -484,7 +484,7 @@@@@@@@@ static int magicmouse_probe(struct hid_
                struct hid_report *report;
                int ret;
        
--- ----        msc = kzalloc(sizeof(*msc), GFP_KERNEL);
+++ ++++        msc = devm_kzalloc(&hdev->dev, sizeof(*msc), GFP_KERNEL);
                if (msc == NULL) {
                        hid_err(hdev, "can't alloc magicmouse descriptor\n");
                        return -ENOMEM;
                ret = hid_parse(hdev);
                if (ret) {
                        hid_err(hdev, "magicmouse hid parse failed\n");
--- ----                goto err_free;
+++ ++++                return ret;
                }
        
                ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
                if (ret) {
                        hid_err(hdev, "magicmouse hw start failed\n");
--- ----                goto err_free;
+++ ++++                return ret;
                }
        
                if (!msc->input) {
                return 0;
        err_stop_hw:
                hid_hw_stop(hdev);
--- ----err_free:
--- ----        kfree(msc);
                return ret;
        }
        
--- ----static void magicmouse_remove(struct hid_device *hdev)
--- ----{
--- ----        struct magicmouse_sc *msc = hid_get_drvdata(hdev);
--- ----
--- ----        hid_hw_stop(hdev);
--- ----        kfree(msc);
--- ----}
--- ----
        static const struct hid_device_id magic_mice[] = {
                { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
                        USB_DEVICE_ID_APPLE_MAGICMOUSE), .driver_data = 0 },
@@@@@@@@@ -574,7 -574,7 -574,7 -564,6 -574,7 -574,7 -574,7 -574,7 +564,6 @@@@@@@@@ static struct hid_driver magicmouse_dri
                .name = "magicmouse",
                .id_table = magic_mice,
                .probe = magicmouse_probe,
--- ----        .remove = magicmouse_remove,
                .raw_event = magicmouse_raw_event,
                .input_mapping = magicmouse_input_mapping,
                .input_configured = magicmouse_input_configured,
diff --combined drivers/hid/hid-sony.c
index 87fbe2924cfac3852ee8b202b8aaeb8500de0080,ecbc74923d063d6494aaa4648f08d91a6c44e686,ecbc74923d063d6494aaa4648f08d91a6c44e686,f9898aad72fa324b5c00fcbecbceeb5cbfee6e9b,ecbc74923d063d6494aaa4648f08d91a6c44e686,87fbe2924cfac3852ee8b202b8aaeb8500de0080,87fbe2924cfac3852ee8b202b8aaeb8500de0080,ecbc74923d063d6494aaa4648f08d91a6c44e686..30dbb6b40bbf17e93c63b2bd6d3eb3b7f8111593
@@@@@@@@@ -369,8 -369,7 -369,7 -369,7 -369,7 -369,8 -369,8 -369,7 +369,8 @@@@@@@@@ static int sony_mapping(struct hid_devi
                if (sc->quirks & PS3REMOTE)
                        return ps3remote_mapping(hdev, hi, field, usage, bit, max);
        
 ----  -        return -1;
 ++++  +        /* Let hid-core decide for the others */
 ++++  +        return 0;
        }
        
        /*
@@@@@@@@@ -624,7 -623,7 -623,7 -623,7 -623,7 -624,7 -624,7 -623,7 +624,7 @@@@@@@@@ static int sony_probe(struct hid_devic
                struct sony_sc *sc;
                unsigned int connect_mask = HID_CONNECT_DEFAULT;
        
--- ----        sc = kzalloc(sizeof(*sc), GFP_KERNEL);
+++ ++++        sc = devm_kzalloc(&hdev->dev, sizeof(*sc), GFP_KERNEL);
                if (sc == NULL) {
                        hid_err(hdev, "can't alloc sony descriptor\n");
                        return -ENOMEM;
                ret = hid_parse(hdev);
                if (ret) {
                        hid_err(hdev, "parse failed\n");
--- ----                goto err_free;
+++ ++++                return ret;
                }
        
                if (sc->quirks & VAIO_RDESC_CONSTANT)
                ret = hid_hw_start(hdev, connect_mask);
                if (ret) {
                        hid_err(hdev, "hw start failed\n");
--- ----                goto err_free;
+++ ++++                return ret;
                }
        
                if (sc->quirks & SIXAXIS_CONTROLLER_USB) {
                return 0;
        err_stop:
                hid_hw_stop(hdev);
--- ----err_free:
--- ----        kfree(sc);
                return ret;
        }
        
@@@@@@@@@ -682,7 -681,7 -681,7 -679,6 -681,7 -682,7 -682,7 -681,7 +680,6 @@@@@@@@@ static void sony_remove(struct hid_devi
                        buzz_remove(hdev);
        
                hid_hw_stop(hdev);
--- ----        kfree(sc);
        }
        
        static const struct hid_device_id sony_devices[] = {
index d2e0eea2bf7975352292b9f95a92c6f8bef0c31f,fc9d92cb3f3951d37224ef3d03e8e0f1987a93cf,879b0ed701a3fb4109243a2642857c16518185b8,879b0ed701a3fb4109243a2642857c16518185b8,db2253b5193a24c2070ffdba7d51e358565c8347,879b0ed701a3fb4109243a2642857c16518185b8,3cb7d966da9ee50f38651f3c055a7d8eff7f0189,3cb7d966da9ee50f38651f3c055a7d8eff7f0189..c1336193b04ba3deb92c3edf2468551f3f6933a9
        #include <linux/hid.h>
        #include <linux/mutex.h>
        #include <linux/acpi.h>
+ ++++++#include <linux/of.h>
        
        #include <linux/i2c/i2c-hid.h>
        
@@@@@@@@@ -756,29 -757,29 -756,29 -756,29 -756,6 -756,29 -756,29 -756,29 +757,6 @@@@@@@@@ static int i2c_hid_power(struct hid_dev
                return ret;
        }
        
---- ---static int i2c_hid_hidinput_input_event(struct input_dev *dev,
---- ---                unsigned int type, unsigned int code, int value)
---- ---{
---- ---        struct hid_device *hid = input_get_drvdata(dev);
---- ---        struct hid_field *field;
---- ---        int offset;
---- ---
---- ---        if (type == EV_FF)
---- ---                return input_ff_event(dev, type, code, value);
---- ---
---- ---        if (type != EV_LED)
---- ---                return -1;
---- ---
---- ---        offset = hidinput_find_field(hid, type, code, &field);
---- ---
---- ---        if (offset == -1) {
---- ---                hid_warn(dev, "event field not found\n");
---- ---                return -1;
---- ---        }
---- ---
---- ---        return hid_set_field(field, offset, value);
---- ---}
---- ---
        static struct hid_ll_driver i2c_hid_ll_driver = {
                .parse = i2c_hid_parse,
                .start = i2c_hid_start,
                .close = i2c_hid_close,
                .power = i2c_hid_power,
                .request = i2c_hid_request,
---- ---        .hidinput_input_event = i2c_hid_hidinput_input_event,
        };
        
        static int i2c_hid_init_irq(struct i2c_client *client)
@@@@@@@@@ -824,8 -825,8 -824,8 -824,8 -800,8 -824,8 -824,8 -824,8 +801,8 @@@@@@@@@ static int i2c_hid_fetch_hid_descriptor
                 * bytes 2-3 -> bcdVersion (has to be 1.00) */
                ret = i2c_hid_command(client, &hid_descr_cmd, ihid->hdesc_buffer, 4);
        
------          i2c_hid_dbg(ihid, "%s, ihid->hdesc_buffer: %*ph\n",
------                          __func__, 4, ihid->hdesc_buffer);
++++++          i2c_hid_dbg(ihid, "%s, ihid->hdesc_buffer: %4ph\n", __func__,
++++++                          ihid->hdesc_buffer);
        
                if (ret) {
                        dev_err(&client->dev,
@@@@@@@@@ -897,9 -898,8 -897,8 -897,8 -873,8 -897,8 -897,8 -897,8 +874,9 @@@@@@@@@ static int i2c_hid_acpi_pdata(struct i2
                params[1].integer.value = 1;
                params[2].type = ACPI_TYPE_INTEGER;
                params[2].integer.value = 1; /* HID function */
 -------        params[3].type = ACPI_TYPE_INTEGER;
 -------        params[3].integer.value = 0;
 +++++++        params[3].type = ACPI_TYPE_PACKAGE;
 +++++++        params[3].package.count = 0;
 +++++++        params[3].package.elements = NULL;
        
                if (ACPI_FAILURE(acpi_evaluate_object(handle, "_DSM", &input, &buf))) {
                        dev_err(&client->dev, "device _DSM execution failed\n");
@@@@@@@@@ -934,6 -934,42 -933,6 -933,6 -909,6 -933,6 -933,6 -933,6 +911,42 @@@@@@@@@ static inline int i2c_hid_acpi_pdata(st
        }
        #endif
        
+ ++++++#ifdef CONFIG_OF
+ ++++++static int i2c_hid_of_probe(struct i2c_client *client,
+ ++++++                struct i2c_hid_platform_data *pdata)
+ ++++++{
+ ++++++        struct device *dev = &client->dev;
+ ++++++        u32 val;
+ ++++++        int ret;
+ ++++++
+ ++++++        ret = of_property_read_u32(dev->of_node, "hid-descr-addr", &val);
+ ++++++        if (ret) {
+ ++++++                dev_err(&client->dev, "HID register address not provided\n");
+ ++++++                return -ENODEV;
+ ++++++        }
+ ++++++        if (val >> 16) {
+ ++++++                dev_err(&client->dev, "Bad HID register address: 0x%08x\n",
+ ++++++                        val);
+ ++++++                return -EINVAL;
+ ++++++        }
+ ++++++        pdata->hid_descriptor_address = val;
+ ++++++
+ ++++++        return 0;
+ ++++++}
+ ++++++
+ ++++++static const struct of_device_id i2c_hid_of_match[] = {
+ ++++++        { .compatible = "hid-over-i2c" },
+ ++++++        {},
+ ++++++};
+ ++++++MODULE_DEVICE_TABLE(of, i2c_hid_of_match);
+ ++++++#else
+ ++++++static inline int i2c_hid_of_probe(struct i2c_client *client,
+ ++++++                struct i2c_hid_platform_data *pdata)
+ ++++++{
+ ++++++        return -ENODEV;
+ ++++++}
+ ++++++#endif
+ ++++++
        static int i2c_hid_probe(struct i2c_client *client,
                                 const struct i2c_device_id *dev_id)
        {
                if (!ihid)
                        return -ENOMEM;
        
- ------        if (!platform_data) {
+ ++++++        if (client->dev.of_node) {
+ ++++++                ret = i2c_hid_of_probe(client, &ihid->pdata);
+ ++++++                if (ret)
+ ++++++                        goto err;
+ ++++++        } else if (!platform_data) {
                        ret = i2c_hid_acpi_pdata(client, &ihid->pdata);
                        if (ret) {
                                dev_err(&client->dev,
@@@@@@@@@ -1096,6 -1136,7 -1095,6 -1095,6 -1071,6 -1095,6 -1095,6 -1095,6 +1113,7 @@@@@@@@@ static struct i2c_driver i2c_hid_drive
                        .owner  = THIS_MODULE,
                        .pm     = &i2c_hid_pm,
                        .acpi_match_table = ACPI_PTR(i2c_hid_acpi_match),
+ ++++++                .of_match_table = of_match_ptr(i2c_hid_of_match),
                },
        
                .probe          = i2c_hid_probe,
diff --combined drivers/hid/uhid.c
index fc307e0422afc92c31bfac65d410244d5859e804,fc307e0422afc92c31bfac65d410244d5859e804,fc307e0422afc92c31bfac65d410244d5859e804,fc307e0422afc92c31bfac65d410244d5859e804,f53f2d52e677b4f80b1bd454e673f2ec0a7ce816,fc307e0422afc92c31bfac65d410244d5859e804,9ab7dfc6c72cf129d5445c7531563d9119c1cf87,fc307e0422afc92c31bfac65d410244d5859e804..5bf2fb785844919bbc27ad20160b98a998102aa5
@@@@@@@@@ -116,30 -116,30 -116,30 -116,30 -116,6 -116,30 -116,30 -116,30 +116,6 @@@@@@@@@ static void uhid_hid_close(struct hid_d
                uhid_queue_event(uhid, UHID_CLOSE);
        }
        
---- ---static int uhid_hid_input(struct input_dev *input, unsigned int type,
---- ---                          unsigned int code, int value)
---- ---{
---- ---        struct hid_device *hid = input_get_drvdata(input);
---- ---        struct uhid_device *uhid = hid->driver_data;
---- ---        unsigned long flags;
---- ---        struct uhid_event *ev;
---- ---
---- ---        ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
---- ---        if (!ev)
---- ---                return -ENOMEM;
---- ---
---- ---        ev->type = UHID_OUTPUT_EV;
---- ---        ev->u.output_ev.type = type;
---- ---        ev->u.output_ev.code = code;
---- ---        ev->u.output_ev.value = value;
---- ---
---- ---        spin_lock_irqsave(&uhid->qlock, flags);
---- ---        uhid_queue(uhid, ev);
---- ---        spin_unlock_irqrestore(&uhid->qlock, flags);
---- ---
---- ---        return 0;
---- ---}
---- ---
        static int uhid_hid_parse(struct hid_device *hid)
        {
                struct uhid_device *uhid = hid->driver_data;
@@@@@@@@@ -273,7 -273,7 -273,7 -273,7 -249,6 -273,7 -273,7 -273,7 +249,6 @@@@@@@@@ static struct hid_ll_driver uhid_hid_dr
                .stop = uhid_hid_stop,
                .open = uhid_hid_open,
                .close = uhid_hid_close,
---- ---        .hidinput_input_event = uhid_hid_input,
                .parse = uhid_hid_parse,
        };
        
@@@@@@@@@ -659,3 -659,3 -659,3 -659,3 -634,3 -659,3 -659,4 -659,3 +634,4 @@@@@@@@@ module_exit(uhid_exit)
        MODULE_LICENSE("GPL");
        MODULE_AUTHOR("David Herrmann <dh.herrmann@gmail.com>");
        MODULE_DESCRIPTION("User-space I/O driver support for HID subsystem");
++++++ +MODULE_ALIAS("devname:" UHID_NAME);
index 99418285222cf118cbc09e4d9029c80ba3493fcf,99418285222cf118cbc09e4d9029c80ba3493fcf,99418285222cf118cbc09e4d9029c80ba3493fcf,55ea9c40140e45c5a1c902601e8aebd948b2ee54,8c3235705679222d7e74051b6a43ab853f4bb60c,99418285222cf118cbc09e4d9029c80ba3493fcf,ada164e1b3a1fd909c8c6a437dc2cc5cb424a845,ada164e1b3a1fd909c8c6a437dc2cc5cb424a845..44df131d390a0e5cbb92d5701cab2f01a872fc9a
@@@@@@@@@ -535,7 -535,7 -535,7 -535,7 -535,7 -535,7 -535,6 -535,6 +535,6 @@@@@@@@@ static void __usbhid_submit_report(stru
        {
                int head;
                struct usbhid_device *usbhid = hid->driver_data;
------          int len = ((report->size - 1) >> 3) + 1 + (report->id > 0);
        
                if ((hid->quirks & HID_QUIRK_NOGET) && dir == USB_DIR_IN)
                        return;
                                return;
                        }
        
------                  usbhid->out[usbhid->outhead].raw_report = kmalloc(len, GFP_ATOMIC);
++++++                  usbhid->out[usbhid->outhead].raw_report = hid_alloc_report_buf(report, GFP_ATOMIC);
                        if (!usbhid->out[usbhid->outhead].raw_report) {
                                hid_warn(hid, "output queueing failed\n");
                                return;
                }
        
                if (dir == USB_DIR_OUT) {
------                  usbhid->ctrl[usbhid->ctrlhead].raw_report = kmalloc(len, GFP_ATOMIC);
++++++                  usbhid->ctrl[usbhid->ctrlhead].raw_report = hid_alloc_report_buf(report, GFP_ATOMIC);
                        if (!usbhid->ctrl[usbhid->ctrlhead].raw_report) {
                                hid_warn(hid, "control queueing failed\n");
                                return;
@@@@@@@@@ -649,62 -649,62 -649,62 -649,62 -649,6 -649,62 -648,62 -648,62 +648,6 @@@@@@@@@ static void usbhid_submit_report(struc
                spin_unlock_irqrestore(&usbhid->lock, flags);
        }
        
---- ---/* Workqueue routine to send requests to change LEDs */
---- ---static void hid_led(struct work_struct *work)
---- ---{
---- ---        struct usbhid_device *usbhid =
---- ---                container_of(work, struct usbhid_device, led_work);
---- ---        struct hid_device *hid = usbhid->hid;
---- ---        struct hid_field *field;
---- ---        unsigned long flags;
---- ---
---- ---        field = hidinput_get_led_field(hid);
---- ---        if (!field) {
---- ---                hid_warn(hid, "LED event field not found\n");
---- ---                return;
---- ---        }
---- ---
---- ---        spin_lock_irqsave(&usbhid->lock, flags);
---- ---        if (!test_bit(HID_DISCONNECTED, &usbhid->iofl)) {
---- ---                usbhid->ledcount = hidinput_count_leds(hid);
---- ---                hid_dbg(usbhid->hid, "New ledcount = %u\n", usbhid->ledcount);
---- ---                __usbhid_submit_report(hid, field->report, USB_DIR_OUT);
---- ---        }
---- ---        spin_unlock_irqrestore(&usbhid->lock, flags);
---- ---}
---- ---
---- ---static int usb_hidinput_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
---- ---{
---- ---        struct hid_device *hid = input_get_drvdata(dev);
---- ---        struct usbhid_device *usbhid = hid->driver_data;
---- ---        struct hid_field *field;
---- ---        unsigned long flags;
---- ---        int offset;
---- ---
---- ---        if (type == EV_FF)
---- ---                return input_ff_event(dev, type, code, value);
---- ---
---- ---        if (type != EV_LED)
---- ---                return -1;
---- ---
---- ---        if ((offset = hidinput_find_field(hid, type, code, &field)) == -1) {
---- ---                hid_warn(dev, "event field not found\n");
---- ---                return -1;
---- ---        }
---- ---
---- ---        spin_lock_irqsave(&usbhid->lock, flags);
---- ---        hid_set_field(field, offset, value);
---- ---        spin_unlock_irqrestore(&usbhid->lock, flags);
---- ---
---- ---        /*
---- ---         * Defer performing requested LED action.
---- ---         * This is more likely gather all LED changes into a single URB.
---- ---         */
---- ---        schedule_work(&usbhid->led_work);
---- ---
---- ---        return 0;
---- ---}
---- ---
        static int usbhid_wait_io(struct hid_device *hid)
        {
                struct usbhid_device *usbhid = hid->driver_data;
@@@@@@@@@ -807,12 -807,12 -807,12 -807,17 -751,12 -807,12 -806,12 -806,12 +750,17 @@@@@@@@@ void usbhid_init_reports(struct hid_dev
        {
                struct hid_report *report;
                struct usbhid_device *usbhid = hid->driver_data;
+++ ++++        struct hid_report_enum *report_enum;
                int err, ret;
        
--- ----        list_for_each_entry(report, &hid->report_enum[HID_INPUT_REPORT].report_list, list)
--- ----                usbhid_submit_report(hid, report, USB_DIR_IN);
+++ ++++        if (!(hid->quirks & HID_QUIRK_NO_INIT_INPUT_REPORTS)) {
+++ ++++                report_enum = &hid->report_enum[HID_INPUT_REPORT];
+++ ++++                list_for_each_entry(report, &report_enum->report_list, list)
+++ ++++                        usbhid_submit_report(hid, report, USB_DIR_IN);
+++ ++++        }
        
--- ----        list_for_each_entry(report, &hid->report_enum[HID_FEATURE_REPORT].report_list, list)
+++ ++++        report_enum = &hid->report_enum[HID_FEATURE_REPORT];
+++ ++++        list_for_each_entry(report, &report_enum->report_list, list)
                        usbhid_submit_report(hid, report, USB_DIR_IN);
        
                err = 0;
@@@@@@@@@ -857,7 -857,7 -857,7 -862,7 -801,7 -857,7 -856,7 -856,7 +805,7 @@@@@@@@@ static int hid_find_field_early(struct 
                return -1;
        }
        
---- ---void usbhid_set_leds(struct hid_device *hid)
++++ +++static void usbhid_set_leds(struct hid_device *hid)
        {
                struct hid_field *field;
                int offset;
                        usbhid_submit_report(hid, field->report, USB_DIR_OUT);
                }
        }
---- ---EXPORT_SYMBOL_GPL(usbhid_set_leds);
        
        /*
         * Traverse the supplied list of reports and find the longest
@@@@@@@@@ -1274,7 -1274,7 -1274,7 -1279,7 -1217,6 -1274,7 -1273,7 -1273,7 +1221,6 @@@@@@@@@ static struct hid_ll_driver usb_hid_dri
                .open = usbhid_open,
                .close = usbhid_close,
                .power = usbhid_power,
---- ---        .hidinput_input_event = usb_hidinput_input_event,
                .request = usbhid_request,
                .wait = usbhid_wait_io,
                .idle = usbhid_idle,
@@@@@@@@@ -1368,8 -1368,8 -1368,8 -1373,8 -1310,6 -1368,8 -1367,8 -1367,8 +1314,6 @@@@@@@@@ static int usbhid_probe(struct usb_inte
                setup_timer(&usbhid->io_retry, hid_retry_timeout, (unsigned long) hid);
                spin_lock_init(&usbhid->lock);
        
---- ---        INIT_WORK(&usbhid->led_work, hid_led);
---- ---
                ret = hid_add_device(hid);
                if (ret) {
                        if (ret != -ENODEV)
@@@@@@@@@ -1402,7 -1402,7 -1402,7 -1407,7 -1342,6 -1402,7 -1401,7 -1401,7 +1346,6 @@@@@@@@@ static void hid_cancel_delayed_stuff(st
        {
                del_timer_sync(&usbhid->io_retry);
                cancel_work_sync(&usbhid->reset_work);
---- ---        cancel_work_sync(&usbhid->led_work);
        }
        
        static void hid_cease_io(struct usbhid_device *usbhid)
@@@@@@@@@ -1522,15 -1522,15 -1522,15 -1527,15 -1461,17 -1522,15 -1521,15 -1521,15 +1465,17 @@@@@@@@@ static int hid_suspend(struct usb_inter
                struct usbhid_device *usbhid = hid->driver_data;
                int status = 0;
                bool driver_suspended = false;
++++ +++        unsigned int ledcount;
        
                if (PMSG_IS_AUTO(message)) {
++++ +++                ledcount = hidinput_count_leds(hid);
                        spin_lock_irq(&usbhid->lock);   /* Sync with error handler */
                        if (!test_bit(HID_RESET_PENDING, &usbhid->iofl)
                            && !test_bit(HID_CLEAR_HALT, &usbhid->iofl)
                            && !test_bit(HID_OUT_RUNNING, &usbhid->iofl)
                            && !test_bit(HID_CTRL_RUNNING, &usbhid->iofl)
                            && !test_bit(HID_KEYS_PRESSED, &usbhid->iofl)
---- ---                    && (!usbhid->ledcount || ignoreled))
++++ +++                    && (!ledcount || ignoreled))
                        {
                                set_bit(HID_SUSPENDED, &usbhid->iofl);
                                spin_unlock_irq(&usbhid->lock);
diff --combined include/linux/hid.h
index 0c48991b0402d0d93110b8a4fa9cd42d615279c2,0c48991b0402d0d93110b8a4fa9cd42d615279c2,0c48991b0402d0d93110b8a4fa9cd42d615279c2,bc132d2a20aad8333f7140e55575ce827df59a57,ea4b828cb9cdce746ad4332ccc5cf4367e653722,0c48991b0402d0d93110b8a4fa9cd42d615279c2,729bf27aac8fff7515ad7f2e4f42db2690ba916a,acccdf4eb48598240064e00011594cd54a5254a8..ee1ffc5e19c9fd3d8b2c9ab4c481953455417d4c
@@@@@@@@@ -252,6 -252,6 -252,6 -252,6 -252,6 -252,6 -252,8 -252,6 +252,8 @@@@@@@@@ struct hid_item 
        #define HID_OUTPUT_REPORT       1
        #define HID_FEATURE_REPORT      2
        
++++++ +#define HID_REPORT_TYPES        3
++++++ +
        /*
         * HID connect requests
         */
        #define HID_QUIRK_MULTI_INPUT                   0x00000040
        #define HID_QUIRK_HIDINPUT_FORCE                0x00000080
        #define HID_QUIRK_NO_EMPTY_INPUT                0x00000100
+++ ++++#define HID_QUIRK_NO_INIT_INPUT_REPORTS         0x00000200
        #define HID_QUIRK_SKIP_OUTPUT_REPORTS           0x00010000
        #define HID_QUIRK_FULLSPEED_INTERVAL            0x10000000
        #define HID_QUIRK_NO_INIT_REPORTS               0x20000000
        #define HID_GROUP_GENERIC                       0x0001
        #define HID_GROUP_MULTITOUCH                    0x0002
        #define HID_GROUP_SENSOR_HUB                    0x0003
+++ ++++#define HID_GROUP_MULTITOUCH_WIN_8              0x0004
        
        /*
         * This is the global environment of the parser. This information is
@@@@@@@@@ -393,14 -393,14 -393,14 -395,14 -393,14 -393,14 -395,14 -393,14 +397,14 @@@@@@@@@ struct hid_report 
                struct hid_device *device;                      /* associated device */
        };
        
++++++ +#define HID_MAX_IDS 256
++++++ +
        struct hid_report_enum {
                unsigned numbered;
                struct list_head report_list;
------ -        struct hid_report *report_id_hash[256];
++++++ +        struct hid_report *report_id_hash[HID_MAX_IDS];
        };
        
------ -#define HID_REPORT_TYPES 3
------ -
        #define HID_MIN_BUFFER_SIZE     64              /* make sure there is at least a packet size of space */
        #define HID_MAX_BUFFER_SIZE     4096            /* 4kb */
        #define HID_CONTROL_FIFO_SIZE   256             /* to init devices with >100 reports */
@@@@@@@@@ -456,6 -456,6 -456,6 -458,6 -456,7 -456,6 -458,6 -456,6 +460,7 @@@@@@@@@ struct hid_device {                                                  /* device rep
                enum hid_type type;                                             /* device type (mouse, kbd, ...) */
                unsigned country;                                               /* HID country */
                struct hid_report_enum report_enum[HID_REPORT_TYPES];
++++ +++        struct work_struct led_work;                                    /* delayed LED worker */
        
                struct semaphore driver_lock;                                   /* protects the current driver, except during input */
                struct semaphore driver_input_lock;                             /* protects the current driver */
@@@@@@@@@ -532,6 -532,6 -532,6 -534,8 -533,6 -532,6 -534,6 -532,6 +537,8 @@@@@@@@@ static inline void hid_set_drvdata(stru
        #define HID_GLOBAL_STACK_SIZE 4
        #define HID_COLLECTION_STACK_SIZE 4
        
+++ ++++#define HID_SCAN_FLAG_MT_WIN_8                  0x00000001
+++ ++++
        struct hid_parser {
                struct hid_global     global;
                struct hid_global     global_stack[HID_GLOBAL_STACK_SIZE];
                unsigned              collection_stack[HID_COLLECTION_STACK_SIZE];
                unsigned              collection_stack_ptr;
                struct hid_device    *device;
+++ ++++        unsigned              scan_flags;
        };
        
        struct hid_class_descriptor {
@@@@@@@@@ -744,6 -744,6 -744,6 -749,6 -745,6 -744,6 -746,7 -744,7 +752,7 @@@@@@@@@ struct hid_field *hidinput_get_led_fiel
        unsigned int hidinput_count_leds(struct hid_device *hid);
        __s32 hidinput_calc_abs_res(const struct hid_field *field, __u16 code);
        void hid_output_report(struct hid_report *report, __u8 *data);
++++++  u8 *hid_alloc_report_buf(struct hid_report *report, gfp_t flags);
        struct hid_device *hid_allocate_device(void);
        struct hid_report *hid_register_report(struct hid_device *device, unsigned type, unsigned id);
        int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size);
@@@@@@@@@ -989,7 -989,7 -989,7 -994,7 -990,6 -989,7 -992,7 -990,7 +998,6 @@@@@@@@@ int hid_report_raw_event(struct hid_dev
        u32 usbhid_lookup_quirk(const u16 idVendor, const u16 idProduct);
        int usbhid_quirks_init(char **quirks_param);
        void usbhid_quirks_exit(void);
---- ---void usbhid_set_leds(struct hid_device *hid);
        
        #ifdef CONFIG_HID_PID
        int hid_pidff_init(struct hid_device *hid);
index 45e921401b067b68c9912f82af1c19a1a8c6d048,b62d4af6c667c27bbbd3620fde9813c9d6b529b8,b62d4af6c667c27bbbd3620fde9813c9d6b529b8,b62d4af6c667c27bbbd3620fde9813c9d6b529b8,b62d4af6c667c27bbbd3620fde9813c9d6b529b8,45e921401b067b68c9912f82af1c19a1a8c6d048,45e921401b067b68c9912f82af1c19a1a8c6d048,65f8a8c4ebbc9d3dc324ebb96aee1207b01929a9..329aa307cb7727ad3a593aadb99f30e3f77e027b
@@@@@@@@@ -277,7 -277,7 -277,7 -277,7 -277,7 -277,7 -277,7 -277,7 +277,7 @@@@@@@@@ struct pcmcia_device_id 
        #define INPUT_DEVICE_ID_KEY_MIN_INTERESTING     0x71
        #define INPUT_DEVICE_ID_KEY_MAX         0x2ff
        #define INPUT_DEVICE_ID_REL_MAX         0x0f
------- #define INPUT_DEVICE_ID_ABS_MAX         0x3f
+++++++ #define INPUT_DEVICE_ID_ABS_MAX         0x4f
        #define INPUT_DEVICE_ID_MSC_MAX         0x07
        #define INPUT_DEVICE_ID_LED_MAX         0x0f
        #define INPUT_DEVICE_ID_SND_MAX         0x07
@@@@@@@@@ -361,8 -361,7 -361,7 -361,7 -361,7 -361,8 -361,8 -361,7 +361,8 @@@@@@@@@ struct ssb_device_id 
                __u16   vendor;
                __u16   coreid;
                __u8    revision;
 ----  -};
 ++++  +        __u8    __pad;
 ++++  +} __attribute__((packed, aligned(2)));
        #define SSB_DEVICE(_vendor, _coreid, _revision)  \
                { .vendor = _vendor, .coreid = _coreid, .revision = _revision, }
        #define SSB_DEVTABLE_END  \
@@@@@@@@@ -378,7 -377,7 -377,7 -377,7 -377,7 -378,7 -378,7 -377,7 +378,7 @@@@@@@@@ struct bcma_device_id 
                __u16   id;
                __u8    rev;
                __u8    class;
 ----  -};
 ++++  +} __attribute__((packed,aligned(2)));
        #define BCMA_CORE(_manuf, _id, _rev, _class)  \
                { .manuf = _manuf, .id = _id, .rev = _rev, .class = _class, }
        #define BCMA_CORETABLE_END  \
This page took 0.067011 seconds and 5 git commands to generate.