Merge branch 'for-4.20/core' into for-linus
[linux-2.6-microblaze.git] / drivers / hid / hid-input.c
index ab93dd5..ad823a0 100644 (file)
@@ -758,6 +758,11 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
                break;
 
        case HID_UP_DIGITIZER:
+               if ((field->application & 0xff) == 0x01) /* Digitizer */
+                       __set_bit(INPUT_PROP_POINTER, input->propbit);
+               else if ((field->application & 0xff) == 0x02) /* Pen */
+                       __set_bit(INPUT_PROP_DIRECT, input->propbit);
+
                switch (usage->hid & 0xff) {
                case 0x00: /* Undefined */
                        goto ignore;
@@ -1516,6 +1521,7 @@ static struct hid_input *hidinput_allocate(struct hid_device *hid,
        struct hid_input *hidinput = kzalloc(sizeof(*hidinput), GFP_KERNEL);
        struct input_dev *input_dev = input_allocate_device();
        const char *suffix = NULL;
+       size_t suffix_len, name_len;
 
        if (!hidinput || !input_dev)
                goto fail;
@@ -1550,16 +1556,24 @@ static struct hid_input *hidinput_allocate(struct hid_device *hid,
                case HID_GD_WIRELESS_RADIO_CTLS:
                        suffix = "Wireless Radio Control";
                        break;
+               case HID_GD_SYSTEM_MULTIAXIS:
+                       suffix = "System Multi Axis";
+                       break;
                default:
                        break;
                }
        }
 
        if (suffix) {
-               hidinput->name = kasprintf(GFP_KERNEL, "%s %s",
-                                          hid->name, suffix);
-               if (!hidinput->name)
-                       goto fail;
+               name_len = strlen(hid->name);
+               suffix_len = strlen(suffix);
+               if ((name_len < suffix_len) ||
+                   strcmp(hid->name + name_len - suffix_len, suffix)) {
+                       hidinput->name = kasprintf(GFP_KERNEL, "%s %s",
+                                                  hid->name, suffix);
+                       if (!hidinput->name)
+                               goto fail;
+               }
        }
 
        input_set_drvdata(input_dev, hid);
@@ -1579,6 +1593,7 @@ static struct hid_input *hidinput_allocate(struct hid_device *hid,
        input_dev->dev.parent = &hid->dev;
 
        hidinput->input = input_dev;
+       hidinput->application = application;
        list_add_tail(&hidinput->list, &hid->inputs);
 
        INIT_LIST_HEAD(&hidinput->reports);
@@ -1674,8 +1689,7 @@ static struct hid_input *hidinput_match_application(struct hid_report *report)
        struct hid_input *hidinput;
 
        list_for_each_entry(hidinput, &hid->inputs, list) {
-               if (hidinput->report &&
-                   hidinput->report->application == report->application)
+               if (hidinput->application == report->application)
                        return hidinput;
        }
 
@@ -1812,6 +1826,7 @@ void hidinput_disconnect(struct hid_device *hid)
                        input_unregister_device(hidinput->input);
                else
                        input_free_device(hidinput->input);
+               kfree(hidinput->name);
                kfree(hidinput);
        }