Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid

Pull HID fixes from Jiri Kosina:
"Two fixes for the HID subsystem:

- regression fix for i2c-hid power management (Hans de Goede)

- signed vs unsigned API fix for Wacom driver (Jason Gerecke)"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid:
HID: wacom: generic: Treat serial number and related fields as unsigned
HID: i2c-hid: Send power-on command after reset

+25 -4
+4
drivers/hid/i2c-hid/i2c-hid-core.c
··· 447 447 if (ret) { 448 448 dev_err(&client->dev, "failed to reset device.\n"); 449 449 i2c_hid_set_power(client, I2C_HID_PWR_SLEEP); 450 + goto out_unlock; 450 451 } 452 + 453 + /* At least some SIS devices need this after reset */ 454 + ret = i2c_hid_set_power(client, I2C_HID_PWR_ON); 451 455 452 456 out_unlock: 453 457 mutex_unlock(&ihid->reset_lock);
+15
drivers/hid/wacom.h
··· 202 202 } 203 203 } 204 204 205 + /* 206 + * Convert a signed 32-bit integer to an unsigned n-bit integer. Undoes 207 + * the normally-helpful work of 'hid_snto32' for fields that use signed 208 + * ranges for questionable reasons. 209 + */ 210 + static inline __u32 wacom_s32tou(s32 value, __u8 n) 211 + { 212 + switch (n) { 213 + case 8: return ((__u8)value); 214 + case 16: return ((__u16)value); 215 + case 32: return ((__u32)value); 216 + } 217 + return value & (1 << (n - 1)) ? value & (~(~0U << n)) : value; 218 + } 219 + 205 220 extern const struct hid_device_id wacom_ids[]; 206 221 207 222 void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len);
+6 -4
drivers/hid/wacom_wac.c
··· 2303 2303 case HID_DG_TOOLSERIALNUMBER: 2304 2304 if (value) { 2305 2305 wacom_wac->serial[0] = (wacom_wac->serial[0] & ~0xFFFFFFFFULL); 2306 - wacom_wac->serial[0] |= (__u32)value; 2306 + wacom_wac->serial[0] |= wacom_s32tou(value, field->report_size); 2307 2307 } 2308 2308 return; 2309 2309 case HID_DG_TWIST: ··· 2319 2319 return; 2320 2320 case WACOM_HID_WD_SERIALHI: 2321 2321 if (value) { 2322 + __u32 raw_value = wacom_s32tou(value, field->report_size); 2323 + 2322 2324 wacom_wac->serial[0] = (wacom_wac->serial[0] & 0xFFFFFFFF); 2323 - wacom_wac->serial[0] |= ((__u64)value) << 32; 2325 + wacom_wac->serial[0] |= ((__u64)raw_value) << 32; 2324 2326 /* 2325 2327 * Non-USI EMR devices may contain additional tool type 2326 2328 * information here. See WACOM_HID_WD_TOOLTYPE case for 2327 2329 * more details. 2328 2330 */ 2329 2331 if (value >> 20 == 1) { 2330 - wacom_wac->id[0] |= value & 0xFFFFF; 2332 + wacom_wac->id[0] |= raw_value & 0xFFFFF; 2331 2333 } 2332 2334 } 2333 2335 return; ··· 2341 2339 * bitwise OR so the complete value can be built 2342 2340 * up over time :( 2343 2341 */ 2344 - wacom_wac->id[0] |= value; 2342 + wacom_wac->id[0] |= wacom_s32tou(value, field->report_size); 2345 2343 return; 2346 2344 case WACOM_HID_WD_OFFSETLEFT: 2347 2345 if (features->offset_left && value != features->offset_left)