diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-12-14 22:08:25 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-12-14 22:08:25 +0300 |
commit | f39fdf2ab846ecc636d6272b47f28a05a2052a14 (patch) | |
tree | dfe4cd1ade490e1218660780d422045631ea96a4 /drivers/hid/intel-ish-hid | |
parent | 775a2e29c3bbcf853432f47d3caa9ff8808807ad (diff) | |
parent | 96e132ebc0a162c643e0e6e6f1f85c3be3355715 (diff) | |
download | linux-f39fdf2ab846ecc636d6272b47f28a05a2052a14.tar.xz |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid
Pull HID updates from Jiri Kosina:
- support for new Wacom "MobileStudio Pro" class of tablets from Jason
Gerecke
- Microsoft Surface 3 support from Benjamin Tissoires and Microsoft
Surface 4 support from Daniel Keller
- uDraw PS3 tablet support from Bastien Nocera
- timeout scheduling fixes for intel-ish-hid from Even Xu
- HID_QUIRK_MULTI_INPUT in order to simplify LED handling from Benjamin
Tissoires
- support for Sony DS4 dongle and various other fixes to Sony driver
from Roderick Colenbrander
- other assorted smaller fixes and device ID additions
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid: (63 commits)
HID: fix missing irq field
HID: i2c-hid: fix build
HID: i2c-hid: Disable IRQ before freeing buffers
HID: usbhid: fix improper return value
HID: wacom: generic: Don't sync input on empty input packets
HID: wacom: generic: Pad supports more than buttons
HID: wacom: generic: Send data only when the interface is defined
HID: wacom: generic: Don't return a value for wacom_wac_event
HID: intel_ish-hid: use %pUL for uuid formatting
HID: cp2112: explicitly require irqchip support in gpiolib
HID: asus: Add i2c touchpad support
HID: intel-ish-hid: Fix potential race condition
HID: sony: Support DS4 dongle
HID: sony: Comply to Linux gamepad spec for DS4
HID: sony: Make the DS4 touchpad a separate device
HID: sony: Fix memory issue when connecting device using both Bluetooth and USB
HID: cp2112: add IRQ chip handling
HID: i2c-hid: force the IRQ level trigger only when not set
HID: multitouch: do not retrieve all reports for all devices
HID: multitouch: enable the Surface 3 Type Cover to report multitouch data
...
Diffstat (limited to 'drivers/hid/intel-ish-hid')
-rw-r--r-- | drivers/hid/intel-ish-hid/ipc/ipc.c | 67 | ||||
-rw-r--r-- | drivers/hid/intel-ish-hid/ipc/utils.h | 64 | ||||
-rw-r--r-- | drivers/hid/intel-ish-hid/ishtp/bus.c | 9 | ||||
-rw-r--r-- | drivers/hid/intel-ish-hid/ishtp/hbm.c | 6 |
4 files changed, 64 insertions, 82 deletions
diff --git a/drivers/hid/intel-ish-hid/ipc/ipc.c b/drivers/hid/intel-ish-hid/ipc/ipc.c index 0c9ac4d5d850..842d8416a7a6 100644 --- a/drivers/hid/intel-ish-hid/ipc/ipc.c +++ b/drivers/hid/intel-ish-hid/ipc/ipc.c @@ -19,7 +19,6 @@ #include <linux/jiffies.h> #include "client.h" #include "hw-ish.h" -#include "utils.h" #include "hbm.h" /* For FW reset flow */ @@ -310,6 +309,7 @@ static int write_ipc_from_queue(struct ishtp_device *dev) ((uint32_t)tv_utc.tv_usec); ts_format.ts1_source = HOST_SYSTEM_TIME_USEC; ts_format.ts2_source = HOST_UTC_TIME_USEC; + ts_format.reserved = 0; time_update.primary_host_time = usec_system; time_update.secondary_host_time = usec_utc; @@ -427,6 +427,59 @@ static int ipc_send_mng_msg(struct ishtp_device *dev, uint32_t msg_code, sizeof(uint32_t) + size); } +#define WAIT_FOR_FW_RDY 0x1 +#define WAIT_FOR_INPUT_RDY 0x2 + +/** + * timed_wait_for_timeout() - wait special event with timeout + * @dev: ISHTP device pointer + * @condition: indicate the condition for waiting + * @timeinc: time slice for every wait cycle, in ms + * @timeout: time in ms for timeout + * + * This function will check special event to be ready in a loop, the loop + * period is specificd in timeinc. Wait timeout will causes failure. + * + * Return: 0 for success else failure code + */ +static int timed_wait_for_timeout(struct ishtp_device *dev, int condition, + unsigned int timeinc, unsigned int timeout) +{ + bool complete = false; + int ret; + + do { + if (condition == WAIT_FOR_FW_RDY) { + complete = ishtp_fw_is_ready(dev); + } else if (condition == WAIT_FOR_INPUT_RDY) { + complete = ish_is_input_ready(dev); + } else { + ret = -EINVAL; + goto out; + } + + if (!complete) { + unsigned long left_time; + + left_time = msleep_interruptible(timeinc); + timeout -= (timeinc - left_time); + } + } while (!complete && timeout > 0); + + if (complete) + ret = 0; + else + ret = -EBUSY; + +out: + return ret; +} + +#define TIME_SLICE_FOR_FW_RDY_MS 100 +#define TIME_SLICE_FOR_INPUT_RDY_MS 100 +#define TIMEOUT_FOR_FW_RDY_MS 2000 +#define TIMEOUT_FOR_INPUT_RDY_MS 2000 + /** * ish_fw_reset_handler() - FW reset handler * @dev: ishtp device pointer @@ -456,8 +509,8 @@ static int ish_fw_reset_handler(struct ishtp_device *dev) ishtp_reset_handler(dev); if (!ish_is_input_ready(dev)) - timed_wait_for_timeout(WAIT_FOR_SEND_SLICE, - ish_is_input_ready(dev), (2 * HZ)); + timed_wait_for_timeout(dev, WAIT_FOR_INPUT_RDY, + TIME_SLICE_FOR_INPUT_RDY_MS, TIMEOUT_FOR_INPUT_RDY_MS); /* ISH FW is dead */ if (!ish_is_input_ready(dev)) @@ -472,8 +525,8 @@ static int ish_fw_reset_handler(struct ishtp_device *dev) sizeof(uint32_t)); /* Wait for ISH FW'es ILUP and ISHTP_READY */ - timed_wait_for_timeout(WAIT_FOR_SEND_SLICE, ishtp_fw_is_ready(dev), - (2 * HZ)); + timed_wait_for_timeout(dev, WAIT_FOR_FW_RDY, + TIME_SLICE_FOR_FW_RDY_MS, TIMEOUT_FOR_FW_RDY_MS); if (!ishtp_fw_is_ready(dev)) { /* ISH FW is dead */ uint32_t ish_status; @@ -487,6 +540,8 @@ static int ish_fw_reset_handler(struct ishtp_device *dev) return 0; } +#define TIMEOUT_FOR_HW_RDY_MS 300 + /** * ish_fw_reset_work_fn() - FW reset worker function * @unused: not used @@ -500,7 +555,7 @@ static void fw_reset_work_fn(struct work_struct *unused) rv = ish_fw_reset_handler(ishtp_dev); if (!rv) { /* ISH is ILUP & ISHTP-ready. Restart ISHTP */ - schedule_timeout(HZ / 3); + msleep_interruptible(TIMEOUT_FOR_HW_RDY_MS); ishtp_dev->recvd_hw_ready = 1; wake_up_interruptible(&ishtp_dev->wait_hw_ready); diff --git a/drivers/hid/intel-ish-hid/ipc/utils.h b/drivers/hid/intel-ish-hid/ipc/utils.h deleted file mode 100644 index 5a82123dc7b4..000000000000 --- a/drivers/hid/intel-ish-hid/ipc/utils.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Utility macros of ISH - * - * Copyright (c) 2014-2016, Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - */ -#ifndef UTILS__H -#define UTILS__H - -#define WAIT_FOR_SEND_SLICE (HZ / 10) -#define WAIT_FOR_CONNECT_SLICE (HZ / 10) - -/* - * Waits for specified event when a thread that triggers event can't signal - * Also, waits *at_least* `timeinc` after condition is satisfied - */ -#define timed_wait_for(timeinc, condition) \ - do { \ - int completed = 0; \ - do { \ - unsigned long j; \ - int done = 0; \ - \ - completed = (condition); \ - for (j = jiffies, done = 0; !done; ) { \ - schedule_timeout(timeinc); \ - if (time_is_before_eq_jiffies(j + timeinc)) \ - done = 1; \ - } \ - } while (!(completed)); \ - } while (0) - - -/* - * Waits for specified event when a thread that triggers event - * can't signal with timeout (use whenever we may hang) - */ -#define timed_wait_for_timeout(timeinc, condition, timeout) \ - do { \ - int t = timeout; \ - do { \ - unsigned long j; \ - int done = 0; \ - \ - for (j = jiffies, done = 0; !done; ) { \ - schedule_timeout(timeinc); \ - if (time_is_before_eq_jiffies(j + timeinc)) \ - done = 1; \ - } \ - t -= timeinc; \ - if (t <= 0) \ - break; \ - } while (!(condition)); \ - } while (0) - -#endif /* UTILS__H */ diff --git a/drivers/hid/intel-ish-hid/ishtp/bus.c b/drivers/hid/intel-ish-hid/ishtp/bus.c index 256521509d20..f4cbc744e657 100644 --- a/drivers/hid/intel-ish-hid/ishtp/bus.c +++ b/drivers/hid/intel-ish-hid/ishtp/bus.c @@ -585,14 +585,7 @@ int ishtp_bus_new_client(struct ishtp_device *dev) */ i = dev->fw_client_presentation_num - 1; device_uuid = dev->fw_clients[i].props.protocol_name; - dev_name = kasprintf(GFP_KERNEL, - "{%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X}", - device_uuid.b[3], device_uuid.b[2], device_uuid.b[1], - device_uuid.b[0], device_uuid.b[5], device_uuid.b[4], - device_uuid.b[7], device_uuid.b[6], device_uuid.b[8], - device_uuid.b[9], device_uuid.b[10], device_uuid.b[11], - device_uuid.b[12], device_uuid.b[13], device_uuid.b[14], - device_uuid.b[15]); + dev_name = kasprintf(GFP_KERNEL, "{%pUL}", device_uuid.b); if (!dev_name) return -ENOMEM; diff --git a/drivers/hid/intel-ish-hid/ishtp/hbm.c b/drivers/hid/intel-ish-hid/ishtp/hbm.c index 74bffee60774..59460b66e689 100644 --- a/drivers/hid/intel-ish-hid/ishtp/hbm.c +++ b/drivers/hid/intel-ish-hid/ishtp/hbm.c @@ -378,11 +378,10 @@ static void ishtp_hbm_cl_disconnect_res(struct ishtp_device *dev, list_for_each_entry(cl, &dev->cl_list, link) { if (!rs->status && ishtp_hbm_cl_addr_equal(cl, rs)) { cl->state = ISHTP_CL_DISCONNECTED; + wake_up_interruptible(&cl->wait_ctrl_res); break; } } - if (cl) - wake_up_interruptible(&cl->wait_ctrl_res); spin_unlock_irqrestore(&dev->cl_list_lock, flags); } @@ -431,11 +430,10 @@ static void ishtp_hbm_cl_connect_res(struct ishtp_device *dev, cl->state = ISHTP_CL_DISCONNECTED; cl->status = -ENODEV; } + wake_up_interruptible(&cl->wait_ctrl_res); break; } } - if (cl) - wake_up_interruptible(&cl->wait_ctrl_res); spin_unlock_irqrestore(&dev->cl_list_lock, flags); } |