diff options
Diffstat (limited to 'drivers/hid')
-rw-r--r-- | drivers/hid/hid-axff.c | 11 | ||||
-rw-r--r-- | drivers/hid/hid-core.c | 7 | ||||
-rw-r--r-- | drivers/hid/hid-dr.c | 12 | ||||
-rw-r--r-- | drivers/hid/hid-emsff.c | 12 | ||||
-rw-r--r-- | drivers/hid/hid-gaff.c | 12 | ||||
-rw-r--r-- | drivers/hid/hid-google-hammer.c | 4 | ||||
-rw-r--r-- | drivers/hid/hid-holtekff.c | 12 | ||||
-rw-r--r-- | drivers/hid/hid-ids.h | 2 | ||||
-rw-r--r-- | drivers/hid/hid-lg2ff.c | 12 | ||||
-rw-r--r-- | drivers/hid/hid-lg3ff.c | 11 | ||||
-rw-r--r-- | drivers/hid/hid-lg4ff.c | 11 | ||||
-rw-r--r-- | drivers/hid/hid-lgff.c | 11 | ||||
-rw-r--r-- | drivers/hid/hid-logitech-hidpp.c | 248 | ||||
-rw-r--r-- | drivers/hid/hid-microsoft.c | 12 | ||||
-rw-r--r-- | drivers/hid/hid-prodikeys.c | 4 | ||||
-rw-r--r-- | drivers/hid/hid-sony.c | 12 | ||||
-rw-r--r-- | drivers/hid/hid-tmff.c | 12 | ||||
-rw-r--r-- | drivers/hid/hid-zpff.c | 12 | ||||
-rw-r--r-- | drivers/hid/i2c-hid/i2c-hid-core.c | 118 | ||||
-rw-r--r-- | drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c | 19 | ||||
-rw-r--r-- | drivers/hid/intel-ish-hid/ishtp/client-buffers.c | 2 |
21 files changed, 297 insertions, 259 deletions
diff --git a/drivers/hid/hid-axff.c b/drivers/hid/hid-axff.c index 6654c1550e2e..fbe4e16ab029 100644 --- a/drivers/hid/hid-axff.c +++ b/drivers/hid/hid-axff.c | |||
@@ -63,13 +63,20 @@ static int axff_init(struct hid_device *hid) | |||
63 | { | 63 | { |
64 | struct axff_device *axff; | 64 | struct axff_device *axff; |
65 | struct hid_report *report; | 65 | struct hid_report *report; |
66 | struct hid_input *hidinput = list_first_entry(&hid->inputs, struct hid_input, list); | 66 | struct hid_input *hidinput; |
67 | struct list_head *report_list =&hid->report_enum[HID_OUTPUT_REPORT].report_list; | 67 | struct list_head *report_list =&hid->report_enum[HID_OUTPUT_REPORT].report_list; |
68 | struct input_dev *dev = hidinput->input; | 68 | struct input_dev *dev; |
69 | int field_count = 0; | 69 | int field_count = 0; |
70 | int i, j; | 70 | int i, j; |
71 | int error; | 71 | int error; |
72 | 72 | ||
73 | if (list_empty(&hid->inputs)) { | ||
74 | hid_err(hid, "no inputs found\n"); | ||
75 | return -ENODEV; | ||
76 | } | ||
77 | hidinput = list_first_entry(&hid->inputs, struct hid_input, list); | ||
78 | dev = hidinput->input; | ||
79 | |||
73 | if (list_empty(report_list)) { | 80 | if (list_empty(report_list)) { |
74 | hid_err(hid, "no output reports found\n"); | 81 | hid_err(hid, "no output reports found\n"); |
75 | return -ENODEV; | 82 | return -ENODEV; |
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 3eaee2c37931..63fdbf09b044 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
@@ -1139,6 +1139,7 @@ int hid_open_report(struct hid_device *device) | |||
1139 | __u8 *start; | 1139 | __u8 *start; |
1140 | __u8 *buf; | 1140 | __u8 *buf; |
1141 | __u8 *end; | 1141 | __u8 *end; |
1142 | __u8 *next; | ||
1142 | int ret; | 1143 | int ret; |
1143 | static int (*dispatch_type[])(struct hid_parser *parser, | 1144 | static int (*dispatch_type[])(struct hid_parser *parser, |
1144 | struct hid_item *item) = { | 1145 | struct hid_item *item) = { |
@@ -1192,7 +1193,8 @@ int hid_open_report(struct hid_device *device) | |||
1192 | device->collection_size = HID_DEFAULT_NUM_COLLECTIONS; | 1193 | device->collection_size = HID_DEFAULT_NUM_COLLECTIONS; |
1193 | 1194 | ||
1194 | ret = -EINVAL; | 1195 | ret = -EINVAL; |
1195 | while ((start = fetch_item(start, end, &item)) != NULL) { | 1196 | while ((next = fetch_item(start, end, &item)) != NULL) { |
1197 | start = next; | ||
1196 | 1198 | ||
1197 | if (item.format != HID_ITEM_FORMAT_SHORT) { | 1199 | if (item.format != HID_ITEM_FORMAT_SHORT) { |
1198 | hid_err(device, "unexpected long global item\n"); | 1200 | hid_err(device, "unexpected long global item\n"); |
@@ -1230,7 +1232,8 @@ int hid_open_report(struct hid_device *device) | |||
1230 | } | 1232 | } |
1231 | } | 1233 | } |
1232 | 1234 | ||
1233 | hid_err(device, "item fetching failed at offset %d\n", (int)(end - start)); | 1235 | hid_err(device, "item fetching failed at offset %u/%u\n", |
1236 | size - (unsigned int)(end - start), size); | ||
1234 | err: | 1237 | err: |
1235 | kfree(parser->collection_stack); | 1238 | kfree(parser->collection_stack); |
1236 | alloc_err: | 1239 | alloc_err: |
diff --git a/drivers/hid/hid-dr.c b/drivers/hid/hid-dr.c index 17e17f9a597b..947f19f8685f 100644 --- a/drivers/hid/hid-dr.c +++ b/drivers/hid/hid-dr.c | |||
@@ -75,13 +75,19 @@ static int drff_init(struct hid_device *hid) | |||
75 | { | 75 | { |
76 | struct drff_device *drff; | 76 | struct drff_device *drff; |
77 | struct hid_report *report; | 77 | struct hid_report *report; |
78 | struct hid_input *hidinput = list_first_entry(&hid->inputs, | 78 | struct hid_input *hidinput; |
79 | struct hid_input, list); | ||
80 | struct list_head *report_list = | 79 | struct list_head *report_list = |
81 | &hid->report_enum[HID_OUTPUT_REPORT].report_list; | 80 | &hid->report_enum[HID_OUTPUT_REPORT].report_list; |
82 | struct input_dev *dev = hidinput->input; | 81 | struct input_dev *dev; |
83 | int error; | 82 | int error; |
84 | 83 | ||
84 | if (list_empty(&hid->inputs)) { | ||
85 | hid_err(hid, "no inputs found\n"); | ||
86 | return -ENODEV; | ||
87 | } | ||
88 | hidinput = list_first_entry(&hid->inputs, struct hid_input, list); | ||
89 | dev = hidinput->input; | ||
90 | |||
85 | if (list_empty(report_list)) { | 91 | if (list_empty(report_list)) { |
86 | hid_err(hid, "no output reports found\n"); | 92 | hid_err(hid, "no output reports found\n"); |
87 | return -ENODEV; | 93 | return -ENODEV; |
diff --git a/drivers/hid/hid-emsff.c b/drivers/hid/hid-emsff.c index 7cd5651872d3..c34f2e5a049f 100644 --- a/drivers/hid/hid-emsff.c +++ b/drivers/hid/hid-emsff.c | |||
@@ -47,13 +47,19 @@ static int emsff_init(struct hid_device *hid) | |||
47 | { | 47 | { |
48 | struct emsff_device *emsff; | 48 | struct emsff_device *emsff; |
49 | struct hid_report *report; | 49 | struct hid_report *report; |
50 | struct hid_input *hidinput = list_first_entry(&hid->inputs, | 50 | struct hid_input *hidinput; |
51 | struct hid_input, list); | ||
52 | struct list_head *report_list = | 51 | struct list_head *report_list = |
53 | &hid->report_enum[HID_OUTPUT_REPORT].report_list; | 52 | &hid->report_enum[HID_OUTPUT_REPORT].report_list; |
54 | struct input_dev *dev = hidinput->input; | 53 | struct input_dev *dev; |
55 | int error; | 54 | int error; |
56 | 55 | ||
56 | if (list_empty(&hid->inputs)) { | ||
57 | hid_err(hid, "no inputs found\n"); | ||
58 | return -ENODEV; | ||
59 | } | ||
60 | hidinput = list_first_entry(&hid->inputs, struct hid_input, list); | ||
61 | dev = hidinput->input; | ||
62 | |||
57 | if (list_empty(report_list)) { | 63 | if (list_empty(report_list)) { |
58 | hid_err(hid, "no output reports found\n"); | 64 | hid_err(hid, "no output reports found\n"); |
59 | return -ENODEV; | 65 | return -ENODEV; |
diff --git a/drivers/hid/hid-gaff.c b/drivers/hid/hid-gaff.c index 0f95c96b70f8..ecbd3995a4eb 100644 --- a/drivers/hid/hid-gaff.c +++ b/drivers/hid/hid-gaff.c | |||
@@ -64,14 +64,20 @@ static int gaff_init(struct hid_device *hid) | |||
64 | { | 64 | { |
65 | struct gaff_device *gaff; | 65 | struct gaff_device *gaff; |
66 | struct hid_report *report; | 66 | struct hid_report *report; |
67 | struct hid_input *hidinput = list_entry(hid->inputs.next, | 67 | struct hid_input *hidinput; |
68 | struct hid_input, list); | ||
69 | struct list_head *report_list = | 68 | struct list_head *report_list = |
70 | &hid->report_enum[HID_OUTPUT_REPORT].report_list; | 69 | &hid->report_enum[HID_OUTPUT_REPORT].report_list; |
71 | struct list_head *report_ptr = report_list; | 70 | struct list_head *report_ptr = report_list; |
72 | struct input_dev *dev = hidinput->input; | 71 | struct input_dev *dev; |
73 | int error; | 72 | int error; |
74 | 73 | ||
74 | if (list_empty(&hid->inputs)) { | ||
75 | hid_err(hid, "no inputs found\n"); | ||
76 | return -ENODEV; | ||
77 | } | ||
78 | hidinput = list_entry(hid->inputs.next, struct hid_input, list); | ||
79 | dev = hidinput->input; | ||
80 | |||
75 | if (list_empty(report_list)) { | 81 | if (list_empty(report_list)) { |
76 | hid_err(hid, "no output reports found\n"); | 82 | hid_err(hid, "no output reports found\n"); |
77 | return -ENODEV; | 83 | return -ENODEV; |
diff --git a/drivers/hid/hid-google-hammer.c b/drivers/hid/hid-google-hammer.c index 84f8c127ebdc..d86a9189e88f 100644 --- a/drivers/hid/hid-google-hammer.c +++ b/drivers/hid/hid-google-hammer.c | |||
@@ -470,6 +470,10 @@ static const struct hid_device_id hammer_devices[] = { | |||
470 | { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, | 470 | { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, |
471 | USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_HAMMER) }, | 471 | USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_HAMMER) }, |
472 | { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, | 472 | { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, |
473 | USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_MAGNEMITE) }, | ||
474 | { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, | ||
475 | USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_MASTERBALL) }, | ||
476 | { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, | ||
473 | USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_STAFF) }, | 477 | USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_STAFF) }, |
474 | { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, | 478 | { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, |
475 | USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_WAND) }, | 479 | USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_WAND) }, |
diff --git a/drivers/hid/hid-holtekff.c b/drivers/hid/hid-holtekff.c index 10a720558830..8619b80c834c 100644 --- a/drivers/hid/hid-holtekff.c +++ b/drivers/hid/hid-holtekff.c | |||
@@ -124,13 +124,19 @@ static int holtekff_init(struct hid_device *hid) | |||
124 | { | 124 | { |
125 | struct holtekff_device *holtekff; | 125 | struct holtekff_device *holtekff; |
126 | struct hid_report *report; | 126 | struct hid_report *report; |
127 | struct hid_input *hidinput = list_entry(hid->inputs.next, | 127 | struct hid_input *hidinput; |
128 | struct hid_input, list); | ||
129 | struct list_head *report_list = | 128 | struct list_head *report_list = |
130 | &hid->report_enum[HID_OUTPUT_REPORT].report_list; | 129 | &hid->report_enum[HID_OUTPUT_REPORT].report_list; |
131 | struct input_dev *dev = hidinput->input; | 130 | struct input_dev *dev; |
132 | int error; | 131 | int error; |
133 | 132 | ||
133 | if (list_empty(&hid->inputs)) { | ||
134 | hid_err(hid, "no inputs found\n"); | ||
135 | return -ENODEV; | ||
136 | } | ||
137 | hidinput = list_entry(hid->inputs.next, struct hid_input, list); | ||
138 | dev = hidinput->input; | ||
139 | |||
134 | if (list_empty(report_list)) { | 140 | if (list_empty(report_list)) { |
135 | hid_err(hid, "no output report found\n"); | 141 | hid_err(hid, "no output report found\n"); |
136 | return -ENODEV; | 142 | return -ENODEV; |
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 76969a22b0f2..447e8db21174 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h | |||
@@ -476,6 +476,8 @@ | |||
476 | #define USB_DEVICE_ID_GOOGLE_STAFF 0x502b | 476 | #define USB_DEVICE_ID_GOOGLE_STAFF 0x502b |
477 | #define USB_DEVICE_ID_GOOGLE_WAND 0x502d | 477 | #define USB_DEVICE_ID_GOOGLE_WAND 0x502d |
478 | #define USB_DEVICE_ID_GOOGLE_WHISKERS 0x5030 | 478 | #define USB_DEVICE_ID_GOOGLE_WHISKERS 0x5030 |
479 | #define USB_DEVICE_ID_GOOGLE_MASTERBALL 0x503c | ||
480 | #define USB_DEVICE_ID_GOOGLE_MAGNEMITE 0x503d | ||
479 | 481 | ||
480 | #define USB_VENDOR_ID_GOTOP 0x08f2 | 482 | #define USB_VENDOR_ID_GOTOP 0x08f2 |
481 | #define USB_DEVICE_ID_SUPER_Q2 0x007f | 483 | #define USB_DEVICE_ID_SUPER_Q2 0x007f |
diff --git a/drivers/hid/hid-lg2ff.c b/drivers/hid/hid-lg2ff.c index dd1a6c3a7de6..73d07e35f12a 100644 --- a/drivers/hid/hid-lg2ff.c +++ b/drivers/hid/hid-lg2ff.c | |||
@@ -50,11 +50,17 @@ int lg2ff_init(struct hid_device *hid) | |||
50 | { | 50 | { |
51 | struct lg2ff_device *lg2ff; | 51 | struct lg2ff_device *lg2ff; |
52 | struct hid_report *report; | 52 | struct hid_report *report; |
53 | struct hid_input *hidinput = list_entry(hid->inputs.next, | 53 | struct hid_input *hidinput; |
54 | struct hid_input, list); | 54 | struct input_dev *dev; |
55 | struct input_dev *dev = hidinput->input; | ||
56 | int error; | 55 | int error; |
57 | 56 | ||
57 | if (list_empty(&hid->inputs)) { | ||
58 | hid_err(hid, "no inputs found\n"); | ||
59 | return -ENODEV; | ||
60 | } | ||
61 | hidinput = list_entry(hid->inputs.next, struct hid_input, list); | ||
62 | dev = hidinput->input; | ||
63 | |||
58 | /* Check that the report looks ok */ | 64 | /* Check that the report looks ok */ |
59 | report = hid_validate_values(hid, HID_OUTPUT_REPORT, 0, 0, 7); | 65 | report = hid_validate_values(hid, HID_OUTPUT_REPORT, 0, 0, 7); |
60 | if (!report) | 66 | if (!report) |
diff --git a/drivers/hid/hid-lg3ff.c b/drivers/hid/hid-lg3ff.c index 9ecb6fd06203..b7e1949f3cf7 100644 --- a/drivers/hid/hid-lg3ff.c +++ b/drivers/hid/hid-lg3ff.c | |||
@@ -117,12 +117,19 @@ static const signed short ff3_joystick_ac[] = { | |||
117 | 117 | ||
118 | int lg3ff_init(struct hid_device *hid) | 118 | int lg3ff_init(struct hid_device *hid) |
119 | { | 119 | { |
120 | struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list); | 120 | struct hid_input *hidinput; |
121 | struct input_dev *dev = hidinput->input; | 121 | struct input_dev *dev; |
122 | const signed short *ff_bits = ff3_joystick_ac; | 122 | const signed short *ff_bits = ff3_joystick_ac; |
123 | int error; | 123 | int error; |
124 | int i; | 124 | int i; |
125 | 125 | ||
126 | if (list_empty(&hid->inputs)) { | ||
127 | hid_err(hid, "no inputs found\n"); | ||
128 | return -ENODEV; | ||
129 | } | ||
130 | hidinput = list_entry(hid->inputs.next, struct hid_input, list); | ||
131 | dev = hidinput->input; | ||
132 | |||
126 | /* Check that the report looks ok */ | 133 | /* Check that the report looks ok */ |
127 | if (!hid_validate_values(hid, HID_OUTPUT_REPORT, 0, 0, 35)) | 134 | if (!hid_validate_values(hid, HID_OUTPUT_REPORT, 0, 0, 35)) |
128 | return -ENODEV; | 135 | return -ENODEV; |
diff --git a/drivers/hid/hid-lg4ff.c b/drivers/hid/hid-lg4ff.c index 03f0220062ca..5e6a0cef2a06 100644 --- a/drivers/hid/hid-lg4ff.c +++ b/drivers/hid/hid-lg4ff.c | |||
@@ -1253,8 +1253,8 @@ static int lg4ff_handle_multimode_wheel(struct hid_device *hid, u16 *real_produc | |||
1253 | 1253 | ||
1254 | int lg4ff_init(struct hid_device *hid) | 1254 | int lg4ff_init(struct hid_device *hid) |
1255 | { | 1255 | { |
1256 | struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list); | 1256 | struct hid_input *hidinput; |
1257 | struct input_dev *dev = hidinput->input; | 1257 | struct input_dev *dev; |
1258 | struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list; | 1258 | struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list; |
1259 | struct hid_report *report = list_entry(report_list->next, struct hid_report, list); | 1259 | struct hid_report *report = list_entry(report_list->next, struct hid_report, list); |
1260 | const struct usb_device_descriptor *udesc = &(hid_to_usb_dev(hid)->descriptor); | 1260 | const struct usb_device_descriptor *udesc = &(hid_to_usb_dev(hid)->descriptor); |
@@ -1266,6 +1266,13 @@ int lg4ff_init(struct hid_device *hid) | |||
1266 | int mmode_ret, mmode_idx = -1; | 1266 | int mmode_ret, mmode_idx = -1; |
1267 | u16 real_product_id; | 1267 | u16 real_product_id; |
1268 | 1268 | ||
1269 | if (list_empty(&hid->inputs)) { | ||
1270 | hid_err(hid, "no inputs found\n"); | ||
1271 | return -ENODEV; | ||
1272 | } | ||
1273 | hidinput = list_entry(hid->inputs.next, struct hid_input, list); | ||
1274 | dev = hidinput->input; | ||
1275 | |||
1269 | /* Check that the report looks ok */ | 1276 | /* Check that the report looks ok */ |
1270 | if (!hid_validate_values(hid, HID_OUTPUT_REPORT, 0, 0, 7)) | 1277 | if (!hid_validate_values(hid, HID_OUTPUT_REPORT, 0, 0, 7)) |
1271 | return -1; | 1278 | return -1; |
diff --git a/drivers/hid/hid-lgff.c b/drivers/hid/hid-lgff.c index c79a6ec43745..aed4ddc397a9 100644 --- a/drivers/hid/hid-lgff.c +++ b/drivers/hid/hid-lgff.c | |||
@@ -115,12 +115,19 @@ static void hid_lgff_set_autocenter(struct input_dev *dev, u16 magnitude) | |||
115 | 115 | ||
116 | int lgff_init(struct hid_device* hid) | 116 | int lgff_init(struct hid_device* hid) |
117 | { | 117 | { |
118 | struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list); | 118 | struct hid_input *hidinput; |
119 | struct input_dev *dev = hidinput->input; | 119 | struct input_dev *dev; |
120 | const signed short *ff_bits = ff_joystick; | 120 | const signed short *ff_bits = ff_joystick; |
121 | int error; | 121 | int error; |
122 | int i; | 122 | int i; |
123 | 123 | ||
124 | if (list_empty(&hid->inputs)) { | ||
125 | hid_err(hid, "no inputs found\n"); | ||
126 | return -ENODEV; | ||
127 | } | ||
128 | hidinput = list_entry(hid->inputs.next, struct hid_input, list); | ||
129 | dev = hidinput->input; | ||
130 | |||
124 | /* Check that the report looks ok */ | 131 | /* Check that the report looks ok */ |
125 | if (!hid_validate_values(hid, HID_OUTPUT_REPORT, 0, 0, 7)) | 132 | if (!hid_validate_values(hid, HID_OUTPUT_REPORT, 0, 0, 7)) |
126 | return -ENODEV; | 133 | return -ENODEV; |
diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c index 0179f7ed77e5..8e91e2f06cb4 100644 --- a/drivers/hid/hid-logitech-hidpp.c +++ b/drivers/hid/hid-logitech-hidpp.c | |||
@@ -1669,6 +1669,7 @@ static void hidpp_touchpad_raw_xy_event(struct hidpp_device *hidpp_dev, | |||
1669 | 1669 | ||
1670 | #define HIDPP_FF_EFFECTID_NONE -1 | 1670 | #define HIDPP_FF_EFFECTID_NONE -1 |
1671 | #define HIDPP_FF_EFFECTID_AUTOCENTER -2 | 1671 | #define HIDPP_FF_EFFECTID_AUTOCENTER -2 |
1672 | #define HIDPP_AUTOCENTER_PARAMS_LENGTH 18 | ||
1672 | 1673 | ||
1673 | #define HIDPP_FF_MAX_PARAMS 20 | 1674 | #define HIDPP_FF_MAX_PARAMS 20 |
1674 | #define HIDPP_FF_RESERVED_SLOTS 1 | 1675 | #define HIDPP_FF_RESERVED_SLOTS 1 |
@@ -2009,7 +2010,7 @@ static int hidpp_ff_erase_effect(struct input_dev *dev, int effect_id) | |||
2009 | static void hidpp_ff_set_autocenter(struct input_dev *dev, u16 magnitude) | 2010 | static void hidpp_ff_set_autocenter(struct input_dev *dev, u16 magnitude) |
2010 | { | 2011 | { |
2011 | struct hidpp_ff_private_data *data = dev->ff->private; | 2012 | struct hidpp_ff_private_data *data = dev->ff->private; |
2012 | u8 params[18]; | 2013 | u8 params[HIDPP_AUTOCENTER_PARAMS_LENGTH]; |
2013 | 2014 | ||
2014 | dbg_hid("Setting autocenter to %d.\n", magnitude); | 2015 | dbg_hid("Setting autocenter to %d.\n", magnitude); |
2015 | 2016 | ||
@@ -2077,23 +2078,34 @@ static DEVICE_ATTR(range, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH, hidpp | |||
2077 | static void hidpp_ff_destroy(struct ff_device *ff) | 2078 | static void hidpp_ff_destroy(struct ff_device *ff) |
2078 | { | 2079 | { |
2079 | struct hidpp_ff_private_data *data = ff->private; | 2080 | struct hidpp_ff_private_data *data = ff->private; |
2081 | struct hid_device *hid = data->hidpp->hid_dev; | ||
2080 | 2082 | ||
2083 | hid_info(hid, "Unloading HID++ force feedback.\n"); | ||
2084 | |||
2085 | device_remove_file(&hid->dev, &dev_attr_range); | ||
2086 | destroy_workqueue(data->wq); | ||
2081 | kfree(data->effect_ids); | 2087 | kfree(data->effect_ids); |
2082 | } | 2088 | } |
2083 | 2089 | ||
2084 | static int hidpp_ff_init(struct hidpp_device *hidpp, u8 feature_index) | 2090 | static int hidpp_ff_init(struct hidpp_device *hidpp, |
2091 | struct hidpp_ff_private_data *data) | ||
2085 | { | 2092 | { |
2086 | struct hid_device *hid = hidpp->hid_dev; | 2093 | struct hid_device *hid = hidpp->hid_dev; |
2087 | struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list); | 2094 | struct hid_input *hidinput; |
2088 | struct input_dev *dev = hidinput->input; | 2095 | struct input_dev *dev; |
2089 | const struct usb_device_descriptor *udesc = &(hid_to_usb_dev(hid)->descriptor); | 2096 | const struct usb_device_descriptor *udesc = &(hid_to_usb_dev(hid)->descriptor); |
2090 | const u16 bcdDevice = le16_to_cpu(udesc->bcdDevice); | 2097 | const u16 bcdDevice = le16_to_cpu(udesc->bcdDevice); |
2091 | struct ff_device *ff; | 2098 | struct ff_device *ff; |
2092 | struct hidpp_report response; | 2099 | int error, j, num_slots = data->num_effects; |
2093 | struct hidpp_ff_private_data *data; | ||
2094 | int error, j, num_slots; | ||
2095 | u8 version; | 2100 | u8 version; |
2096 | 2101 | ||
2102 | if (list_empty(&hid->inputs)) { | ||
2103 | hid_err(hid, "no inputs found\n"); | ||
2104 | return -ENODEV; | ||
2105 | } | ||
2106 | hidinput = list_entry(hid->inputs.next, struct hid_input, list); | ||
2107 | dev = hidinput->input; | ||
2108 | |||
2097 | if (!dev) { | 2109 | if (!dev) { |
2098 | hid_err(hid, "Struct input_dev not set!\n"); | 2110 | hid_err(hid, "Struct input_dev not set!\n"); |
2099 | return -EINVAL; | 2111 | return -EINVAL; |
@@ -2109,27 +2121,17 @@ static int hidpp_ff_init(struct hidpp_device *hidpp, u8 feature_index) | |||
2109 | for (j = 0; hidpp_ff_effects_v2[j] >= 0; j++) | 2121 | for (j = 0; hidpp_ff_effects_v2[j] >= 0; j++) |
2110 | set_bit(hidpp_ff_effects_v2[j], dev->ffbit); | 2122 | set_bit(hidpp_ff_effects_v2[j], dev->ffbit); |
2111 | 2123 | ||
2112 | /* Read number of slots available in device */ | ||
2113 | error = hidpp_send_fap_command_sync(hidpp, feature_index, | ||
2114 | HIDPP_FF_GET_INFO, NULL, 0, &response); | ||
2115 | if (error) { | ||
2116 | if (error < 0) | ||
2117 | return error; | ||
2118 | hid_err(hidpp->hid_dev, "%s: received protocol error 0x%02x\n", | ||
2119 | __func__, error); | ||
2120 | return -EPROTO; | ||
2121 | } | ||
2122 | |||
2123 | num_slots = response.fap.params[0] - HIDPP_FF_RESERVED_SLOTS; | ||
2124 | |||
2125 | error = input_ff_create(dev, num_slots); | 2124 | error = input_ff_create(dev, num_slots); |
2126 | 2125 | ||
2127 | if (error) { | 2126 | if (error) { |
2128 | hid_err(dev, "Failed to create FF device!\n"); | 2127 | hid_err(dev, "Failed to create FF device!\n"); |
2129 | return error; | 2128 | return error; |
2130 | } | 2129 | } |
2131 | 2130 | /* | |
2132 | data = kzalloc(sizeof(*data), GFP_KERNEL); | 2131 | * Create a copy of passed data, so we can transfer memory |
2132 | * ownership to FF core | ||
2133 | */ | ||
2134 | data = kmemdup(data, sizeof(*data), GFP_KERNEL); | ||
2133 | if (!data) | 2135 | if (!data) |
2134 | return -ENOMEM; | 2136 | return -ENOMEM; |
2135 | data->effect_ids = kcalloc(num_slots, sizeof(int), GFP_KERNEL); | 2137 | data->effect_ids = kcalloc(num_slots, sizeof(int), GFP_KERNEL); |
@@ -2145,10 +2147,7 @@ static int hidpp_ff_init(struct hidpp_device *hidpp, u8 feature_index) | |||
2145 | } | 2147 | } |
2146 | 2148 | ||
2147 | data->hidpp = hidpp; | 2149 | data->hidpp = hidpp; |
2148 | data->feature_index = feature_index; | ||
2149 | data->version = version; | 2150 | data->version = version; |
2150 | data->slot_autocenter = 0; | ||
2151 | data->num_effects = num_slots; | ||
2152 | for (j = 0; j < num_slots; j++) | 2151 | for (j = 0; j < num_slots; j++) |
2153 | data->effect_ids[j] = -1; | 2152 | data->effect_ids[j] = -1; |
2154 | 2153 | ||
@@ -2162,68 +2161,20 @@ static int hidpp_ff_init(struct hidpp_device *hidpp, u8 feature_index) | |||
2162 | ff->set_autocenter = hidpp_ff_set_autocenter; | 2161 | ff->set_autocenter = hidpp_ff_set_autocenter; |
2163 | ff->destroy = hidpp_ff_destroy; | 2162 | ff->destroy = hidpp_ff_destroy; |
2164 | 2163 | ||
2165 | |||
2166 | /* reset all forces */ | ||
2167 | error = hidpp_send_fap_command_sync(hidpp, feature_index, | ||
2168 | HIDPP_FF_RESET_ALL, NULL, 0, &response); | ||
2169 | |||
2170 | /* Read current Range */ | ||
2171 | error = hidpp_send_fap_command_sync(hidpp, feature_index, | ||
2172 | HIDPP_FF_GET_APERTURE, NULL, 0, &response); | ||
2173 | if (error) | ||
2174 | hid_warn(hidpp->hid_dev, "Failed to read range from device!\n"); | ||
2175 | data->range = error ? 900 : get_unaligned_be16(&response.fap.params[0]); | ||
2176 | |||
2177 | /* Create sysfs interface */ | 2164 | /* Create sysfs interface */ |
2178 | error = device_create_file(&(hidpp->hid_dev->dev), &dev_attr_range); | 2165 | error = device_create_file(&(hidpp->hid_dev->dev), &dev_attr_range); |
2179 | if (error) | 2166 | if (error) |
2180 | hid_warn(hidpp->hid_dev, "Unable to create sysfs interface for \"range\", errno %d!\n", error); | 2167 | hid_warn(hidpp->hid_dev, "Unable to create sysfs interface for \"range\", errno %d!\n", error); |
2181 | 2168 | ||
2182 | /* Read the current gain values */ | ||
2183 | error = hidpp_send_fap_command_sync(hidpp, feature_index, | ||
2184 | HIDPP_FF_GET_GLOBAL_GAINS, NULL, 0, &response); | ||
2185 | if (error) | ||
2186 | hid_warn(hidpp->hid_dev, "Failed to read gain values from device!\n"); | ||
2187 | data->gain = error ? 0xffff : get_unaligned_be16(&response.fap.params[0]); | ||
2188 | /* ignore boost value at response.fap.params[2] */ | ||
2189 | |||
2190 | /* init the hardware command queue */ | 2169 | /* init the hardware command queue */ |
2191 | atomic_set(&data->workqueue_size, 0); | 2170 | atomic_set(&data->workqueue_size, 0); |
2192 | 2171 | ||
2193 | /* initialize with zero autocenter to get wheel in usable state */ | ||
2194 | hidpp_ff_set_autocenter(dev, 0); | ||
2195 | |||
2196 | hid_info(hid, "Force feedback support loaded (firmware release %d).\n", | 2172 | hid_info(hid, "Force feedback support loaded (firmware release %d).\n", |
2197 | version); | 2173 | version); |
2198 | 2174 | ||
2199 | return 0; | 2175 | return 0; |
2200 | } | 2176 | } |
2201 | 2177 | ||
2202 | static int hidpp_ff_deinit(struct hid_device *hid) | ||
2203 | { | ||
2204 | struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list); | ||
2205 | struct input_dev *dev = hidinput->input; | ||
2206 | struct hidpp_ff_private_data *data; | ||
2207 | |||
2208 | if (!dev) { | ||
2209 | hid_err(hid, "Struct input_dev not found!\n"); | ||
2210 | return -EINVAL; | ||
2211 | } | ||
2212 | |||
2213 | hid_info(hid, "Unloading HID++ force feedback.\n"); | ||
2214 | data = dev->ff->private; | ||
2215 | if (!data) { | ||
2216 | hid_err(hid, "Private data not found!\n"); | ||
2217 | return -EINVAL; | ||
2218 | } | ||
2219 | |||
2220 | destroy_workqueue(data->wq); | ||
2221 | device_remove_file(&hid->dev, &dev_attr_range); | ||
2222 | |||
2223 | return 0; | ||
2224 | } | ||
2225 | |||
2226 | |||
2227 | /* ************************************************************************** */ | 2178 | /* ************************************************************************** */ |
2228 | /* */ | 2179 | /* */ |
2229 | /* Device Support */ | 2180 | /* Device Support */ |
@@ -2725,24 +2676,93 @@ static int k400_connect(struct hid_device *hdev, bool connected) | |||
2725 | 2676 | ||
2726 | #define HIDPP_PAGE_G920_FORCE_FEEDBACK 0x8123 | 2677 | #define HIDPP_PAGE_G920_FORCE_FEEDBACK 0x8123 |
2727 | 2678 | ||
2728 | static int g920_get_config(struct hidpp_device *hidpp) | 2679 | static int g920_ff_set_autocenter(struct hidpp_device *hidpp, |
2680 | struct hidpp_ff_private_data *data) | ||
2729 | { | 2681 | { |
2682 | struct hidpp_report response; | ||
2683 | u8 params[HIDPP_AUTOCENTER_PARAMS_LENGTH] = { | ||
2684 | [1] = HIDPP_FF_EFFECT_SPRING | HIDPP_FF_EFFECT_AUTOSTART, | ||
2685 | }; | ||
2686 | int ret; | ||
2687 | |||
2688 | /* initialize with zero autocenter to get wheel in usable state */ | ||
2689 | |||
2690 | dbg_hid("Setting autocenter to 0.\n"); | ||
2691 | ret = hidpp_send_fap_command_sync(hidpp, data->feature_index, | ||
2692 | HIDPP_FF_DOWNLOAD_EFFECT, | ||
2693 | params, ARRAY_SIZE(params), | ||
2694 | &response); | ||
2695 | if (ret) | ||
2696 | hid_warn(hidpp->hid_dev, "Failed to autocenter device!\n"); | ||
2697 | else | ||
2698 | data->slot_autocenter = response.fap.params[0]; | ||
2699 | |||
2700 | return ret; | ||
2701 | } | ||
2702 | |||
2703 | static int g920_get_config(struct hidpp_device *hidpp, | ||
2704 | struct hidpp_ff_private_data *data) | ||
2705 | { | ||
2706 | struct hidpp_report response; | ||
2730 | u8 feature_type; | 2707 | u8 feature_type; |
2731 | u8 feature_index; | ||
2732 | int ret; | 2708 | int ret; |
2733 | 2709 | ||
2710 | memset(data, 0, sizeof(*data)); | ||
2711 | |||
2734 | /* Find feature and store for later use */ | 2712 | /* Find feature and store for later use */ |
2735 | ret = hidpp_root_get_feature(hidpp, HIDPP_PAGE_G920_FORCE_FEEDBACK, | 2713 | ret = hidpp_root_get_feature(hidpp, HIDPP_PAGE_G920_FORCE_FEEDBACK, |
2736 | &feature_index, &feature_type); | 2714 | &data->feature_index, &feature_type); |
2737 | if (ret) | 2715 | if (ret) |
2738 | return ret; | 2716 | return ret; |
2739 | 2717 | ||
2740 | ret = hidpp_ff_init(hidpp, feature_index); | 2718 | /* Read number of slots available in device */ |
2719 | ret = hidpp_send_fap_command_sync(hidpp, data->feature_index, | ||
2720 | HIDPP_FF_GET_INFO, | ||
2721 | NULL, 0, | ||
2722 | &response); | ||
2723 | if (ret) { | ||
2724 | if (ret < 0) | ||
2725 | return ret; | ||
2726 | hid_err(hidpp->hid_dev, | ||
2727 | "%s: received protocol error 0x%02x\n", __func__, ret); | ||
2728 | return -EPROTO; | ||
2729 | } | ||
2730 | |||
2731 | data->num_effects = response.fap.params[0] - HIDPP_FF_RESERVED_SLOTS; | ||
2732 | |||
2733 | /* reset all forces */ | ||
2734 | ret = hidpp_send_fap_command_sync(hidpp, data->feature_index, | ||
2735 | HIDPP_FF_RESET_ALL, | ||
2736 | NULL, 0, | ||
2737 | &response); | ||
2741 | if (ret) | 2738 | if (ret) |
2742 | hid_warn(hidpp->hid_dev, "Unable to initialize force feedback support, errno %d\n", | 2739 | hid_warn(hidpp->hid_dev, "Failed to reset all forces!\n"); |
2743 | ret); | ||
2744 | 2740 | ||
2745 | return 0; | 2741 | ret = hidpp_send_fap_command_sync(hidpp, data->feature_index, |
2742 | HIDPP_FF_GET_APERTURE, | ||
2743 | NULL, 0, | ||
2744 | &response); | ||
2745 | if (ret) { | ||
2746 | hid_warn(hidpp->hid_dev, | ||
2747 | "Failed to read range from device!\n"); | ||
2748 | } | ||
2749 | data->range = ret ? | ||
2750 | 900 : get_unaligned_be16(&response.fap.params[0]); | ||
2751 | |||
2752 | /* Read the current gain values */ | ||
2753 | ret = hidpp_send_fap_command_sync(hidpp, data->feature_index, | ||
2754 | HIDPP_FF_GET_GLOBAL_GAINS, | ||
2755 | NULL, 0, | ||
2756 | &response); | ||
2757 | if (ret) | ||
2758 | hid_warn(hidpp->hid_dev, | ||
2759 | "Failed to read gain values from device!\n"); | ||
2760 | data->gain = ret ? | ||
2761 | 0xffff : get_unaligned_be16(&response.fap.params[0]); | ||
2762 | |||
2763 | /* ignore boost value at response.fap.params[2] */ | ||
2764 | |||
2765 | return g920_ff_set_autocenter(hidpp, data); | ||
2746 | } | 2766 | } |
2747 | 2767 | ||
2748 | /* -------------------------------------------------------------------------- */ | 2768 | /* -------------------------------------------------------------------------- */ |
@@ -3458,34 +3478,45 @@ static int hidpp_get_report_length(struct hid_device *hdev, int id) | |||
3458 | return report->field[0]->report_count + 1; | 3478 | return report->field[0]->report_count + 1; |
3459 | } | 3479 | } |
3460 | 3480 | ||
3461 | static bool hidpp_validate_report(struct hid_device *hdev, int id, | 3481 | static bool hidpp_validate_device(struct hid_device *hdev) |
3462 | int expected_length, bool optional) | ||
3463 | { | 3482 | { |
3464 | int report_length; | 3483 | struct hidpp_device *hidpp = hid_get_drvdata(hdev); |
3484 | int id, report_length, supported_reports = 0; | ||
3465 | 3485 | ||
3466 | if (id >= HID_MAX_IDS || id < 0) { | 3486 | id = REPORT_ID_HIDPP_SHORT; |
3467 | hid_err(hdev, "invalid HID report id %u\n", id); | 3487 | report_length = hidpp_get_report_length(hdev, id); |
3468 | return false; | 3488 | if (report_length) { |
3489 | if (report_length < HIDPP_REPORT_SHORT_LENGTH) | ||
3490 | goto bad_device; | ||
3491 | |||
3492 | supported_reports++; | ||
3469 | } | 3493 | } |
3470 | 3494 | ||
3495 | id = REPORT_ID_HIDPP_LONG; | ||
3471 | report_length = hidpp_get_report_length(hdev, id); | 3496 | report_length = hidpp_get_report_length(hdev, id); |
3472 | if (!report_length) | 3497 | if (report_length) { |
3473 | return optional; | 3498 | if (report_length < HIDPP_REPORT_LONG_LENGTH) |
3499 | goto bad_device; | ||
3474 | 3500 | ||
3475 | if (report_length < expected_length) { | 3501 | supported_reports++; |
3476 | hid_warn(hdev, "not enough values in hidpp report %d\n", id); | ||
3477 | return false; | ||
3478 | } | 3502 | } |
3479 | 3503 | ||
3480 | return true; | 3504 | id = REPORT_ID_HIDPP_VERY_LONG; |
3481 | } | 3505 | report_length = hidpp_get_report_length(hdev, id); |
3506 | if (report_length) { | ||
3507 | if (report_length < HIDPP_REPORT_LONG_LENGTH || | ||
3508 | report_length > HIDPP_REPORT_VERY_LONG_MAX_LENGTH) | ||
3509 | goto bad_device; | ||
3482 | 3510 | ||
3483 | static bool hidpp_validate_device(struct hid_device *hdev) | 3511 | supported_reports++; |
3484 | { | 3512 | hidpp->very_long_report_length = report_length; |
3485 | return hidpp_validate_report(hdev, REPORT_ID_HIDPP_SHORT, | 3513 | } |
3486 | HIDPP_REPORT_SHORT_LENGTH, false) && | 3514 | |
3487 | hidpp_validate_report(hdev, REPORT_ID_HIDPP_LONG, | 3515 | return supported_reports; |
3488 | HIDPP_REPORT_LONG_LENGTH, true); | 3516 | |
3517 | bad_device: | ||
3518 | hid_warn(hdev, "not enough values in hidpp report %d\n", id); | ||
3519 | return false; | ||
3489 | } | 3520 | } |
3490 | 3521 | ||
3491 | static bool hidpp_application_equals(struct hid_device *hdev, | 3522 | static bool hidpp_application_equals(struct hid_device *hdev, |
@@ -3505,6 +3536,7 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
3505 | int ret; | 3536 | int ret; |
3506 | bool connected; | 3537 | bool connected; |
3507 | unsigned int connect_mask = HID_CONNECT_DEFAULT; | 3538 | unsigned int connect_mask = HID_CONNECT_DEFAULT; |
3539 | struct hidpp_ff_private_data data; | ||
3508 | 3540 | ||
3509 | /* report_fixup needs drvdata to be set before we call hid_parse */ | 3541 | /* report_fixup needs drvdata to be set before we call hid_parse */ |
3510 | hidpp = devm_kzalloc(&hdev->dev, sizeof(*hidpp), GFP_KERNEL); | 3542 | hidpp = devm_kzalloc(&hdev->dev, sizeof(*hidpp), GFP_KERNEL); |
@@ -3531,11 +3563,6 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
3531 | return hid_hw_start(hdev, HID_CONNECT_DEFAULT); | 3563 | return hid_hw_start(hdev, HID_CONNECT_DEFAULT); |
3532 | } | 3564 | } |
3533 | 3565 | ||
3534 | hidpp->very_long_report_length = | ||
3535 | hidpp_get_report_length(hdev, REPORT_ID_HIDPP_VERY_LONG); | ||
3536 | if (hidpp->very_long_report_length > HIDPP_REPORT_VERY_LONG_MAX_LENGTH) | ||
3537 | hidpp->very_long_report_length = HIDPP_REPORT_VERY_LONG_MAX_LENGTH; | ||
3538 | |||
3539 | if (id->group == HID_GROUP_LOGITECH_DJ_DEVICE) | 3566 | if (id->group == HID_GROUP_LOGITECH_DJ_DEVICE) |
3540 | hidpp->quirks |= HIDPP_QUIRK_UNIFYING; | 3567 | hidpp->quirks |= HIDPP_QUIRK_UNIFYING; |
3541 | 3568 | ||
@@ -3614,7 +3641,7 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
3614 | if (ret) | 3641 | if (ret) |
3615 | goto hid_hw_init_fail; | 3642 | goto hid_hw_init_fail; |
3616 | } else if (connected && (hidpp->quirks & HIDPP_QUIRK_CLASS_G920)) { | 3643 | } else if (connected && (hidpp->quirks & HIDPP_QUIRK_CLASS_G920)) { |
3617 | ret = g920_get_config(hidpp); | 3644 | ret = g920_get_config(hidpp, &data); |
3618 | if (ret) | 3645 | if (ret) |
3619 | goto hid_hw_init_fail; | 3646 | goto hid_hw_init_fail; |
3620 | } | 3647 | } |
@@ -3636,6 +3663,14 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
3636 | goto hid_hw_start_fail; | 3663 | goto hid_hw_start_fail; |
3637 | } | 3664 | } |
3638 | 3665 | ||
3666 | if (hidpp->quirks & HIDPP_QUIRK_CLASS_G920) { | ||
3667 | ret = hidpp_ff_init(hidpp, &data); | ||
3668 | if (ret) | ||
3669 | hid_warn(hidpp->hid_dev, | ||
3670 | "Unable to initialize force feedback support, errno %d\n", | ||
3671 | ret); | ||
3672 | } | ||
3673 | |||
3639 | return ret; | 3674 | return ret; |
3640 | 3675 | ||
3641 | hid_hw_init_fail: | 3676 | hid_hw_init_fail: |
@@ -3658,9 +3693,6 @@ static void hidpp_remove(struct hid_device *hdev) | |||
3658 | 3693 | ||
3659 | sysfs_remove_group(&hdev->dev.kobj, &ps_attribute_group); | 3694 | sysfs_remove_group(&hdev->dev.kobj, &ps_attribute_group); |
3660 | 3695 | ||
3661 | if (hidpp->quirks & HIDPP_QUIRK_CLASS_G920) | ||
3662 | hidpp_ff_deinit(hdev); | ||
3663 | |||
3664 | hid_hw_stop(hdev); | 3696 | hid_hw_stop(hdev); |
3665 | cancel_work_sync(&hidpp->work); | 3697 | cancel_work_sync(&hidpp->work); |
3666 | mutex_destroy(&hidpp->send_mutex); | 3698 | mutex_destroy(&hidpp->send_mutex); |
diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c index 2cf83856f2e4..2d8b589201a4 100644 --- a/drivers/hid/hid-microsoft.c +++ b/drivers/hid/hid-microsoft.c | |||
@@ -328,11 +328,17 @@ static int ms_play_effect(struct input_dev *dev, void *data, | |||
328 | 328 | ||
329 | static int ms_init_ff(struct hid_device *hdev) | 329 | static int ms_init_ff(struct hid_device *hdev) |
330 | { | 330 | { |
331 | struct hid_input *hidinput = list_entry(hdev->inputs.next, | 331 | struct hid_input *hidinput; |
332 | struct hid_input, list); | 332 | struct input_dev *input_dev; |
333 | struct input_dev *input_dev = hidinput->input; | ||
334 | struct ms_data *ms = hid_get_drvdata(hdev); | 333 | struct ms_data *ms = hid_get_drvdata(hdev); |
335 | 334 | ||
335 | if (list_empty(&hdev->inputs)) { | ||
336 | hid_err(hdev, "no inputs found\n"); | ||
337 | return -ENODEV; | ||
338 | } | ||
339 | hidinput = list_entry(hdev->inputs.next, struct hid_input, list); | ||
340 | input_dev = hidinput->input; | ||
341 | |||
336 | if (!(ms->quirks & MS_QUIRK_FF)) | 342 | if (!(ms->quirks & MS_QUIRK_FF)) |
337 | return 0; | 343 | return 0; |
338 | 344 | ||
diff --git a/drivers/hid/hid-prodikeys.c b/drivers/hid/hid-prodikeys.c index 5a3b3d974d84..2666af02d5c1 100644 --- a/drivers/hid/hid-prodikeys.c +++ b/drivers/hid/hid-prodikeys.c | |||
@@ -516,7 +516,7 @@ static void pcmidi_setup_extra_keys( | |||
516 | MY PICTURES => KEY_WORDPROCESSOR | 516 | MY PICTURES => KEY_WORDPROCESSOR |
517 | MY MUSIC=> KEY_SPREADSHEET | 517 | MY MUSIC=> KEY_SPREADSHEET |
518 | */ | 518 | */ |
519 | unsigned int keys[] = { | 519 | static const unsigned int keys[] = { |
520 | KEY_FN, | 520 | KEY_FN, |
521 | KEY_MESSENGER, KEY_CALENDAR, | 521 | KEY_MESSENGER, KEY_CALENDAR, |
522 | KEY_ADDRESSBOOK, KEY_DOCUMENTS, | 522 | KEY_ADDRESSBOOK, KEY_DOCUMENTS, |
@@ -532,7 +532,7 @@ static void pcmidi_setup_extra_keys( | |||
532 | 0 | 532 | 0 |
533 | }; | 533 | }; |
534 | 534 | ||
535 | unsigned int *pkeys = &keys[0]; | 535 | const unsigned int *pkeys = &keys[0]; |
536 | unsigned short i; | 536 | unsigned short i; |
537 | 537 | ||
538 | if (pm->ifnum != 1) /* only set up ONCE for interace 1 */ | 538 | if (pm->ifnum != 1) /* only set up ONCE for interace 1 */ |
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index 73c0f7a95e2d..4c6ed6ef31f1 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c | |||
@@ -2254,9 +2254,15 @@ static int sony_play_effect(struct input_dev *dev, void *data, | |||
2254 | 2254 | ||
2255 | static int sony_init_ff(struct sony_sc *sc) | 2255 | static int sony_init_ff(struct sony_sc *sc) |
2256 | { | 2256 | { |
2257 | struct hid_input *hidinput = list_entry(sc->hdev->inputs.next, | 2257 | struct hid_input *hidinput; |
2258 | struct hid_input, list); | 2258 | struct input_dev *input_dev; |
2259 | struct input_dev *input_dev = hidinput->input; | 2259 | |
2260 | if (list_empty(&sc->hdev->inputs)) { | ||
2261 | hid_err(sc->hdev, "no inputs found\n"); | ||
2262 | return -ENODEV; | ||
2263 | } | ||
2264 | hidinput = list_entry(sc->hdev->inputs.next, struct hid_input, list); | ||
2265 | input_dev = hidinput->input; | ||
2260 | 2266 | ||
2261 | input_set_capability(input_dev, EV_FF, FF_RUMBLE); | 2267 | input_set_capability(input_dev, EV_FF, FF_RUMBLE); |
2262 | return input_ff_create_memless(input_dev, NULL, sony_play_effect); | 2268 | return input_ff_create_memless(input_dev, NULL, sony_play_effect); |
diff --git a/drivers/hid/hid-tmff.c b/drivers/hid/hid-tmff.c index bdfc5ff3b2c5..90acef304536 100644 --- a/drivers/hid/hid-tmff.c +++ b/drivers/hid/hid-tmff.c | |||
@@ -124,12 +124,18 @@ static int tmff_init(struct hid_device *hid, const signed short *ff_bits) | |||
124 | struct tmff_device *tmff; | 124 | struct tmff_device *tmff; |
125 | struct hid_report *report; | 125 | struct hid_report *report; |
126 | struct list_head *report_list; | 126 | struct list_head *report_list; |
127 | struct hid_input *hidinput = list_entry(hid->inputs.next, | 127 | struct hid_input *hidinput; |
128 | struct hid_input, list); | 128 | struct input_dev *input_dev; |
129 | struct input_dev *input_dev = hidinput->input; | ||
130 | int error; | 129 | int error; |
131 | int i; | 130 | int i; |
132 | 131 | ||
132 | if (list_empty(&hid->inputs)) { | ||
133 | hid_err(hid, "no inputs found\n"); | ||
134 | return -ENODEV; | ||
135 | } | ||
136 | hidinput = list_entry(hid->inputs.next, struct hid_input, list); | ||
137 | input_dev = hidinput->input; | ||
138 | |||
133 | tmff = kzalloc(sizeof(struct tmff_device), GFP_KERNEL); | 139 | tmff = kzalloc(sizeof(struct tmff_device), GFP_KERNEL); |
134 | if (!tmff) | 140 | if (!tmff) |
135 | return -ENOMEM; | 141 | return -ENOMEM; |
diff --git a/drivers/hid/hid-zpff.c b/drivers/hid/hid-zpff.c index f90959e94028..3abaca045869 100644 --- a/drivers/hid/hid-zpff.c +++ b/drivers/hid/hid-zpff.c | |||
@@ -54,11 +54,17 @@ static int zpff_init(struct hid_device *hid) | |||
54 | { | 54 | { |
55 | struct zpff_device *zpff; | 55 | struct zpff_device *zpff; |
56 | struct hid_report *report; | 56 | struct hid_report *report; |
57 | struct hid_input *hidinput = list_entry(hid->inputs.next, | 57 | struct hid_input *hidinput; |
58 | struct hid_input, list); | 58 | struct input_dev *dev; |
59 | struct input_dev *dev = hidinput->input; | ||
60 | int i, error; | 59 | int i, error; |
61 | 60 | ||
61 | if (list_empty(&hid->inputs)) { | ||
62 | hid_err(hid, "no inputs found\n"); | ||
63 | return -ENODEV; | ||
64 | } | ||
65 | hidinput = list_entry(hid->inputs.next, struct hid_input, list); | ||
66 | dev = hidinput->input; | ||
67 | |||
62 | for (i = 0; i < 4; i++) { | 68 | for (i = 0; i < 4; i++) { |
63 | report = hid_validate_values(hid, HID_OUTPUT_REPORT, 0, i, 1); | 69 | report = hid_validate_values(hid, HID_OUTPUT_REPORT, 0, i, 1); |
64 | if (!report) | 70 | if (!report) |
diff --git a/drivers/hid/i2c-hid/i2c-hid-core.c b/drivers/hid/i2c-hid/i2c-hid-core.c index 2a7c6e33bb1c..d9c55e30f986 100644 --- a/drivers/hid/i2c-hid/i2c-hid-core.c +++ b/drivers/hid/i2c-hid/i2c-hid-core.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include <linux/delay.h> | 26 | #include <linux/delay.h> |
27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | #include <linux/pm.h> | 28 | #include <linux/pm.h> |
29 | #include <linux/pm_runtime.h> | ||
30 | #include <linux/device.h> | 29 | #include <linux/device.h> |
31 | #include <linux/wait.h> | 30 | #include <linux/wait.h> |
32 | #include <linux/err.h> | 31 | #include <linux/err.h> |
@@ -48,8 +47,6 @@ | |||
48 | /* quirks to control the device */ | 47 | /* quirks to control the device */ |
49 | #define I2C_HID_QUIRK_SET_PWR_WAKEUP_DEV BIT(0) | 48 | #define I2C_HID_QUIRK_SET_PWR_WAKEUP_DEV BIT(0) |
50 | #define I2C_HID_QUIRK_NO_IRQ_AFTER_RESET BIT(1) | 49 | #define I2C_HID_QUIRK_NO_IRQ_AFTER_RESET BIT(1) |
51 | #define I2C_HID_QUIRK_NO_RUNTIME_PM BIT(2) | ||
52 | #define I2C_HID_QUIRK_DELAY_AFTER_SLEEP BIT(3) | ||
53 | #define I2C_HID_QUIRK_BOGUS_IRQ BIT(4) | 50 | #define I2C_HID_QUIRK_BOGUS_IRQ BIT(4) |
54 | 51 | ||
55 | /* flags */ | 52 | /* flags */ |
@@ -172,14 +169,7 @@ static const struct i2c_hid_quirks { | |||
172 | { USB_VENDOR_ID_WEIDA, HID_ANY_ID, | 169 | { USB_VENDOR_ID_WEIDA, HID_ANY_ID, |
173 | I2C_HID_QUIRK_SET_PWR_WAKEUP_DEV }, | 170 | I2C_HID_QUIRK_SET_PWR_WAKEUP_DEV }, |
174 | { I2C_VENDOR_ID_HANTICK, I2C_PRODUCT_ID_HANTICK_5288, | 171 | { I2C_VENDOR_ID_HANTICK, I2C_PRODUCT_ID_HANTICK_5288, |
175 | I2C_HID_QUIRK_NO_IRQ_AFTER_RESET | | 172 | I2C_HID_QUIRK_NO_IRQ_AFTER_RESET }, |
176 | I2C_HID_QUIRK_NO_RUNTIME_PM }, | ||
177 | { I2C_VENDOR_ID_RAYDIUM, I2C_PRODUCT_ID_RAYDIUM_4B33, | ||
178 | I2C_HID_QUIRK_DELAY_AFTER_SLEEP }, | ||
179 | { USB_VENDOR_ID_LG, I2C_DEVICE_ID_LG_8001, | ||
180 | I2C_HID_QUIRK_NO_RUNTIME_PM }, | ||
181 | { I2C_VENDOR_ID_GOODIX, I2C_DEVICE_ID_GOODIX_01F0, | ||
182 | I2C_HID_QUIRK_NO_RUNTIME_PM }, | ||
183 | { USB_VENDOR_ID_ELAN, HID_ANY_ID, | 173 | { USB_VENDOR_ID_ELAN, HID_ANY_ID, |
184 | I2C_HID_QUIRK_BOGUS_IRQ }, | 174 | I2C_HID_QUIRK_BOGUS_IRQ }, |
185 | { 0, 0 } | 175 | { 0, 0 } |
@@ -397,7 +387,6 @@ static int i2c_hid_set_power(struct i2c_client *client, int power_state) | |||
397 | { | 387 | { |
398 | struct i2c_hid *ihid = i2c_get_clientdata(client); | 388 | struct i2c_hid *ihid = i2c_get_clientdata(client); |
399 | int ret; | 389 | int ret; |
400 | unsigned long now, delay; | ||
401 | 390 | ||
402 | i2c_hid_dbg(ihid, "%s\n", __func__); | 391 | i2c_hid_dbg(ihid, "%s\n", __func__); |
403 | 392 | ||
@@ -415,22 +404,9 @@ static int i2c_hid_set_power(struct i2c_client *client, int power_state) | |||
415 | goto set_pwr_exit; | 404 | goto set_pwr_exit; |
416 | } | 405 | } |
417 | 406 | ||
418 | if (ihid->quirks & I2C_HID_QUIRK_DELAY_AFTER_SLEEP && | ||
419 | power_state == I2C_HID_PWR_ON) { | ||
420 | now = jiffies; | ||
421 | if (time_after(ihid->sleep_delay, now)) { | ||
422 | delay = jiffies_to_usecs(ihid->sleep_delay - now); | ||
423 | usleep_range(delay, delay + 1); | ||
424 | } | ||
425 | } | ||
426 | |||
427 | ret = __i2c_hid_command(client, &hid_set_power_cmd, power_state, | 407 | ret = __i2c_hid_command(client, &hid_set_power_cmd, power_state, |
428 | 0, NULL, 0, NULL, 0); | 408 | 0, NULL, 0, NULL, 0); |
429 | 409 | ||
430 | if (ihid->quirks & I2C_HID_QUIRK_DELAY_AFTER_SLEEP && | ||
431 | power_state == I2C_HID_PWR_SLEEP) | ||
432 | ihid->sleep_delay = jiffies + msecs_to_jiffies(20); | ||
433 | |||
434 | if (ret) | 410 | if (ret) |
435 | dev_err(&client->dev, "failed to change power setting.\n"); | 411 | dev_err(&client->dev, "failed to change power setting.\n"); |
436 | 412 | ||
@@ -791,11 +767,6 @@ static int i2c_hid_open(struct hid_device *hid) | |||
791 | { | 767 | { |
792 | struct i2c_client *client = hid->driver_data; | 768 | struct i2c_client *client = hid->driver_data; |
793 | struct i2c_hid *ihid = i2c_get_clientdata(client); | 769 | struct i2c_hid *ihid = i2c_get_clientdata(client); |
794 | int ret = 0; | ||
795 | |||
796 | ret = pm_runtime_get_sync(&client->dev); | ||
797 | if (ret < 0) | ||
798 | return ret; | ||
799 | 770 | ||
800 | set_bit(I2C_HID_STARTED, &ihid->flags); | 771 | set_bit(I2C_HID_STARTED, &ihid->flags); |
801 | return 0; | 772 | return 0; |
@@ -807,27 +778,6 @@ static void i2c_hid_close(struct hid_device *hid) | |||
807 | struct i2c_hid *ihid = i2c_get_clientdata(client); | 778 | struct i2c_hid *ihid = i2c_get_clientdata(client); |
808 | 779 | ||
809 | clear_bit(I2C_HID_STARTED, &ihid->flags); | 780 | clear_bit(I2C_HID_STARTED, &ihid->flags); |
810 | |||
811 | /* Save some power */ | ||
812 | pm_runtime_put(&client->dev); | ||
813 | } | ||
814 | |||
815 | static int i2c_hid_power(struct hid_device *hid, int lvl) | ||
816 | { | ||
817 | struct i2c_client *client = hid->driver_data; | ||
818 | struct i2c_hid *ihid = i2c_get_clientdata(client); | ||
819 | |||
820 | i2c_hid_dbg(ihid, "%s lvl:%d\n", __func__, lvl); | ||
821 | |||
822 | switch (lvl) { | ||
823 | case PM_HINT_FULLON: | ||
824 | pm_runtime_get_sync(&client->dev); | ||
825 | break; | ||
826 | case PM_HINT_NORMAL: | ||
827 | pm_runtime_put(&client->dev); | ||
828 | break; | ||
829 | } | ||
830 | return 0; | ||
831 | } | 781 | } |
832 | 782 | ||
833 | struct hid_ll_driver i2c_hid_ll_driver = { | 783 | struct hid_ll_driver i2c_hid_ll_driver = { |
@@ -836,7 +786,6 @@ struct hid_ll_driver i2c_hid_ll_driver = { | |||
836 | .stop = i2c_hid_stop, | 786 | .stop = i2c_hid_stop, |
837 | .open = i2c_hid_open, | 787 | .open = i2c_hid_open, |
838 | .close = i2c_hid_close, | 788 | .close = i2c_hid_close, |
839 | .power = i2c_hid_power, | ||
840 | .output_report = i2c_hid_output_report, | 789 | .output_report = i2c_hid_output_report, |
841 | .raw_request = i2c_hid_raw_request, | 790 | .raw_request = i2c_hid_raw_request, |
842 | }; | 791 | }; |
@@ -1104,9 +1053,6 @@ static int i2c_hid_probe(struct i2c_client *client, | |||
1104 | 1053 | ||
1105 | i2c_hid_acpi_fix_up_power(&client->dev); | 1054 | i2c_hid_acpi_fix_up_power(&client->dev); |
1106 | 1055 | ||
1107 | pm_runtime_get_noresume(&client->dev); | ||
1108 | pm_runtime_set_active(&client->dev); | ||
1109 | pm_runtime_enable(&client->dev); | ||
1110 | device_enable_async_suspend(&client->dev); | 1056 | device_enable_async_suspend(&client->dev); |
1111 | 1057 | ||
1112 | /* Make sure there is something at this address */ | 1058 | /* Make sure there is something at this address */ |
@@ -1114,16 +1060,16 @@ static int i2c_hid_probe(struct i2c_client *client, | |||
1114 | if (ret < 0) { | 1060 | if (ret < 0) { |
1115 | dev_dbg(&client->dev, "nothing at this address: %d\n", ret); | 1061 | dev_dbg(&client->dev, "nothing at this address: %d\n", ret); |
1116 | ret = -ENXIO; | 1062 | ret = -ENXIO; |
1117 | goto err_pm; | 1063 | goto err_regulator; |
1118 | } | 1064 | } |
1119 | 1065 | ||
1120 | ret = i2c_hid_fetch_hid_descriptor(ihid); | 1066 | ret = i2c_hid_fetch_hid_descriptor(ihid); |
1121 | if (ret < 0) | 1067 | if (ret < 0) |
1122 | goto err_pm; | 1068 | goto err_regulator; |
1123 | 1069 | ||
1124 | ret = i2c_hid_init_irq(client); | 1070 | ret = i2c_hid_init_irq(client); |
1125 | if (ret < 0) | 1071 | if (ret < 0) |
1126 | goto err_pm; | 1072 | goto err_regulator; |
1127 | 1073 | ||
1128 | hid = hid_allocate_device(); | 1074 | hid = hid_allocate_device(); |
1129 | if (IS_ERR(hid)) { | 1075 | if (IS_ERR(hid)) { |
@@ -1154,9 +1100,6 @@ static int i2c_hid_probe(struct i2c_client *client, | |||
1154 | goto err_mem_free; | 1100 | goto err_mem_free; |
1155 | } | 1101 | } |
1156 | 1102 | ||
1157 | if (!(ihid->quirks & I2C_HID_QUIRK_NO_RUNTIME_PM)) | ||
1158 | pm_runtime_put(&client->dev); | ||
1159 | |||
1160 | return 0; | 1103 | return 0; |
1161 | 1104 | ||
1162 | err_mem_free: | 1105 | err_mem_free: |
@@ -1165,10 +1108,6 @@ err_mem_free: | |||
1165 | err_irq: | 1108 | err_irq: |
1166 | free_irq(client->irq, ihid); | 1109 | free_irq(client->irq, ihid); |
1167 | 1110 | ||
1168 | err_pm: | ||
1169 | pm_runtime_put_noidle(&client->dev); | ||
1170 | pm_runtime_disable(&client->dev); | ||
1171 | |||
1172 | err_regulator: | 1111 | err_regulator: |
1173 | regulator_bulk_disable(ARRAY_SIZE(ihid->pdata.supplies), | 1112 | regulator_bulk_disable(ARRAY_SIZE(ihid->pdata.supplies), |
1174 | ihid->pdata.supplies); | 1113 | ihid->pdata.supplies); |
@@ -1181,12 +1120,6 @@ static int i2c_hid_remove(struct i2c_client *client) | |||
1181 | struct i2c_hid *ihid = i2c_get_clientdata(client); | 1120 | struct i2c_hid *ihid = i2c_get_clientdata(client); |
1182 | struct hid_device *hid; | 1121 | struct hid_device *hid; |
1183 | 1122 | ||
1184 | if (!(ihid->quirks & I2C_HID_QUIRK_NO_RUNTIME_PM)) | ||
1185 | pm_runtime_get_sync(&client->dev); | ||
1186 | pm_runtime_disable(&client->dev); | ||
1187 | pm_runtime_set_suspended(&client->dev); | ||
1188 | pm_runtime_put_noidle(&client->dev); | ||
1189 | |||
1190 | hid = ihid->hid; | 1123 | hid = ihid->hid; |
1191 | hid_destroy_device(hid); | 1124 | hid_destroy_device(hid); |
1192 | 1125 | ||
@@ -1219,25 +1152,15 @@ static int i2c_hid_suspend(struct device *dev) | |||
1219 | int wake_status; | 1152 | int wake_status; |
1220 | 1153 | ||
1221 | if (hid->driver && hid->driver->suspend) { | 1154 | if (hid->driver && hid->driver->suspend) { |
1222 | /* | ||
1223 | * Wake up the device so that IO issues in | ||
1224 | * HID driver's suspend code can succeed. | ||
1225 | */ | ||
1226 | ret = pm_runtime_resume(dev); | ||
1227 | if (ret < 0) | ||
1228 | return ret; | ||
1229 | |||
1230 | ret = hid->driver->suspend(hid, PMSG_SUSPEND); | 1155 | ret = hid->driver->suspend(hid, PMSG_SUSPEND); |
1231 | if (ret < 0) | 1156 | if (ret < 0) |
1232 | return ret; | 1157 | return ret; |
1233 | } | 1158 | } |
1234 | 1159 | ||
1235 | if (!pm_runtime_suspended(dev)) { | 1160 | /* Save some power */ |
1236 | /* Save some power */ | 1161 | i2c_hid_set_power(client, I2C_HID_PWR_SLEEP); |
1237 | i2c_hid_set_power(client, I2C_HID_PWR_SLEEP); | ||
1238 | 1162 | ||
1239 | disable_irq(client->irq); | 1163 | disable_irq(client->irq); |
1240 | } | ||
1241 | 1164 | ||
1242 | if (device_may_wakeup(&client->dev)) { | 1165 | if (device_may_wakeup(&client->dev)) { |
1243 | wake_status = enable_irq_wake(client->irq); | 1166 | wake_status = enable_irq_wake(client->irq); |
@@ -1279,11 +1202,6 @@ static int i2c_hid_resume(struct device *dev) | |||
1279 | wake_status); | 1202 | wake_status); |
1280 | } | 1203 | } |
1281 | 1204 | ||
1282 | /* We'll resume to full power */ | ||
1283 | pm_runtime_disable(dev); | ||
1284 | pm_runtime_set_active(dev); | ||
1285 | pm_runtime_enable(dev); | ||
1286 | |||
1287 | enable_irq(client->irq); | 1205 | enable_irq(client->irq); |
1288 | 1206 | ||
1289 | /* Instead of resetting device, simply powers the device on. This | 1207 | /* Instead of resetting device, simply powers the device on. This |
@@ -1304,30 +1222,8 @@ static int i2c_hid_resume(struct device *dev) | |||
1304 | } | 1222 | } |
1305 | #endif | 1223 | #endif |
1306 | 1224 | ||
1307 | #ifdef CONFIG_PM | ||
1308 | static int i2c_hid_runtime_suspend(struct device *dev) | ||
1309 | { | ||
1310 | struct i2c_client *client = to_i2c_client(dev); | ||
1311 | |||
1312 | i2c_hid_set_power(client, I2C_HID_PWR_SLEEP); | ||
1313 | disable_irq(client->irq); | ||
1314 | return 0; | ||
1315 | } | ||
1316 | |||
1317 | static int i2c_hid_runtime_resume(struct device *dev) | ||
1318 | { | ||
1319 | struct i2c_client *client = to_i2c_client(dev); | ||
1320 | |||
1321 | enable_irq(client->irq); | ||
1322 | i2c_hid_set_power(client, I2C_HID_PWR_ON); | ||
1323 | return 0; | ||
1324 | } | ||
1325 | #endif | ||
1326 | |||
1327 | static const struct dev_pm_ops i2c_hid_pm = { | 1225 | static const struct dev_pm_ops i2c_hid_pm = { |
1328 | SET_SYSTEM_SLEEP_PM_OPS(i2c_hid_suspend, i2c_hid_resume) | 1226 | SET_SYSTEM_SLEEP_PM_OPS(i2c_hid_suspend, i2c_hid_resume) |
1329 | SET_RUNTIME_PM_OPS(i2c_hid_runtime_suspend, i2c_hid_runtime_resume, | ||
1330 | NULL) | ||
1331 | }; | 1227 | }; |
1332 | 1228 | ||
1333 | static const struct i2c_device_id i2c_hid_id_table[] = { | 1229 | static const struct i2c_device_id i2c_hid_id_table[] = { |
diff --git a/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c b/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c index 75078c83be1a..d31ea82b84c1 100644 --- a/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c +++ b/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c | |||
@@ -323,6 +323,25 @@ static const struct dmi_system_id i2c_hid_dmi_desc_override_table[] = { | |||
323 | .driver_data = (void *)&sipodev_desc | 323 | .driver_data = (void *)&sipodev_desc |
324 | }, | 324 | }, |
325 | { | 325 | { |
326 | /* | ||
327 | * There are at least 2 Primebook C11B versions, the older | ||
328 | * version has a product-name of "Primebook C11B", and a | ||
329 | * bios version / release / firmware revision of: | ||
330 | * V2.1.2 / 05/03/2018 / 18.2 | ||
331 | * The new version has "PRIMEBOOK C11B" as product-name and a | ||
332 | * bios version / release / firmware revision of: | ||
333 | * CFALKSW05_BIOS_V1.1.2 / 11/19/2018 / 19.2 | ||
334 | * Only the older version needs this quirk, note the newer | ||
335 | * version will not match as it has a different product-name. | ||
336 | */ | ||
337 | .ident = "Trekstor Primebook C11B", | ||
338 | .matches = { | ||
339 | DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TREKSTOR"), | ||
340 | DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Primebook C11B"), | ||
341 | }, | ||
342 | .driver_data = (void *)&sipodev_desc | ||
343 | }, | ||
344 | { | ||
326 | .ident = "Direkt-Tek DTLAPY116-2", | 345 | .ident = "Direkt-Tek DTLAPY116-2", |
327 | .matches = { | 346 | .matches = { |
328 | DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Direkt-Tek"), | 347 | DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Direkt-Tek"), |
diff --git a/drivers/hid/intel-ish-hid/ishtp/client-buffers.c b/drivers/hid/intel-ish-hid/ishtp/client-buffers.c index 1b0a0cc605e7..513d7a4a1b8a 100644 --- a/drivers/hid/intel-ish-hid/ishtp/client-buffers.c +++ b/drivers/hid/intel-ish-hid/ishtp/client-buffers.c | |||
@@ -84,7 +84,7 @@ int ishtp_cl_alloc_tx_ring(struct ishtp_cl *cl) | |||
84 | return 0; | 84 | return 0; |
85 | out: | 85 | out: |
86 | dev_err(&cl->device->dev, "error in allocating Tx pool\n"); | 86 | dev_err(&cl->device->dev, "error in allocating Tx pool\n"); |
87 | ishtp_cl_free_rx_ring(cl); | 87 | ishtp_cl_free_tx_ring(cl); |
88 | return -ENOMEM; | 88 | return -ENOMEM; |
89 | } | 89 | } |
90 | 90 | ||