diff options
author | Yunhong Jiang <yunhong.jiang@linux.intel.com> | 2017-03-08 23:13:28 -0800 |
---|---|---|
committer | Yunhong Jiang <yunhong.jiang@linux.intel.com> | 2017-03-08 23:36:15 -0800 |
commit | 52f993b8e89487ec9ee15a7fb4979e0f09a45b27 (patch) | |
tree | d65304486afe0bea4a311c783c0d72791c8c0aa2 /kernel/drivers/hid/uhid.c | |
parent | c189ccac5702322ed843fe17057035b7222a59b6 (diff) |
Upgrade to 4.4.50-rt62
The current kernel is based on rt kernel v4.4.6-rt14. We will upgrade it
to 4.4.50-rt62.
The command to achieve it is:
a) Clone a git repo from
git://git.kernel.org/pub/scm/linux/kernel/git/rt/linux-stable-rt.git
b) Get the diff between this two changesets:
git diff 640eca2901f3435e616157b11379d3223a44b391
705619beeea1b0b48219a683fd1a901a86fdaf5e
where the two commits are:
[yjiang5@jnakajim-build linux-stable-rt]$ git show --oneline --name-only
640eca2901f3435e616157b11379d3223a44b391
640eca2901f3 v4.4.6-rt14
localversion-rt
[yjiang5@jnakajim-build linux-stable-rt]$ git show --oneline --name-only
705619beeea1b0b48219a683fd1a901a86fdaf5e
705619beeea1 Linux 4.4.50-rt62
localversion-rt
c) One patch has been backported thus revert the patch before applying.
filterdiff -p1 -x scripts/package/Makefile
~/tmp/v4.4.6-rt14-4.4.50-rt62.diff |patch -p1 --dry-run
Upstream status: backport
Change-Id: I244d57a32f6066e5a5b9915f9fbf99e7bbca6e01
Signed-off-by: Yunhong Jiang <yunhong.jiang@linux.intel.com>
Diffstat (limited to 'kernel/drivers/hid/uhid.c')
-rw-r--r-- | kernel/drivers/hid/uhid.c | 33 |
1 files changed, 24 insertions, 9 deletions
diff --git a/kernel/drivers/hid/uhid.c b/kernel/drivers/hid/uhid.c index e094c572b..1a2032c2c 100644 --- a/kernel/drivers/hid/uhid.c +++ b/kernel/drivers/hid/uhid.c @@ -51,10 +51,26 @@ struct uhid_device { u32 report_id; u32 report_type; struct uhid_event report_buf; + struct work_struct worker; }; static struct miscdevice uhid_misc; +static void uhid_device_add_worker(struct work_struct *work) +{ + struct uhid_device *uhid = container_of(work, struct uhid_device, worker); + int ret; + + ret = hid_add_device(uhid->hid); + if (ret) { + hid_err(uhid->hid, "Cannot register HID device: error %d\n", ret); + + hid_destroy_device(uhid->hid); + uhid->hid = NULL; + uhid->running = false; + } +} + static void uhid_queue(struct uhid_device *uhid, struct uhid_event *ev) { __u8 newhead; @@ -498,18 +514,14 @@ static int uhid_dev_create2(struct uhid_device *uhid, uhid->hid = hid; uhid->running = true; - ret = hid_add_device(hid); - if (ret) { - hid_err(hid, "Cannot register HID device\n"); - goto err_hid; - } + /* Adding of a HID device is done through a worker, to allow HID drivers + * which use feature requests during .probe to work, without they would + * be blocked on devlock, which is held by uhid_char_write. + */ + schedule_work(&uhid->worker); return 0; -err_hid: - hid_destroy_device(hid); - uhid->hid = NULL; - uhid->running = false; err_free: kfree(uhid->rd_data); uhid->rd_data = NULL; @@ -550,6 +562,8 @@ static int uhid_dev_destroy(struct uhid_device *uhid) uhid->running = false; wake_up_interruptible(&uhid->report_wait); + cancel_work_sync(&uhid->worker); + hid_destroy_device(uhid->hid); kfree(uhid->rd_data); @@ -612,6 +626,7 @@ static int uhid_char_open(struct inode *inode, struct file *file) init_waitqueue_head(&uhid->waitq); init_waitqueue_head(&uhid->report_wait); uhid->running = false; + INIT_WORK(&uhid->worker, uhid_device_add_worker); file->private_data = uhid; nonseekable_open(inode, file); |