diff options
author | Manoj Chourasia <mchourasia@nvidia.com> | 2013-10-01 15:59:02 +0530 |
---|---|---|
committer | Mandar Padmawar <mpadmawar@nvidia.com> | 2014-05-20 02:26:48 -0700 |
commit | 24d60adcdfb4656817c437208e7618ad4c750371 (patch) | |
tree | bf8db3ea9a6fa2edf96a9bf674b9a9604da8c7e1 /drivers/hid | |
parent | 73e864303da82c1606005a48c3d6f4cf52bf3b25 (diff) |
HID: hidraw: close underlying device at removal of last reader
Even though device exist bit is set the underlying
HW device should be closed when the last reader
of the device is closed i.e. open count drops to zero.
bug 1307434
bug 200004331
Change-Id: Ibdbf0cac829135b8bf1c462197f3a24a69cd69e1
Signed-off-by: Manoj Chourasia <mchourasia@nvidia.com>
Reviewed-on: http://git-master/r/376328
(cherry picked from commit c2dadc835dab7a3e05810ec8e666b195f3df8e08)
Reviewed-on: http://git-master/r/408781
GVS: Gerrit_Virtual_Submit
Reviewed-by: Mark Kuo <mkuo@nvidia.com>
Tested-by: Mark Kuo <mkuo@nvidia.com>
Reviewed-by: BH Hsieh <bhsieh@nvidia.com>
Reviewed-by: WK Tsai <wtsai@nvidia.com>
Reviewed-by: Laxman Dewangan <ldewangan@nvidia.com>
Diffstat (limited to 'drivers/hid')
-rw-r--r-- | drivers/hid/hidraw.c | 21 |
1 files changed, 15 insertions, 6 deletions
diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c index 612a655bc9f0..07e35d94b472 100644 --- a/drivers/hid/hidraw.c +++ b/drivers/hid/hidraw.c @@ -7,6 +7,7 @@ * use a transport-specific userspace libhid/libusb libraries. * * Copyright (c) 2007 Jiri Kosina + * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. */ /* @@ -305,18 +306,26 @@ static int hidraw_fasync(int fd, struct file *file, int on) static void drop_ref(struct hidraw *hidraw, int exists_bit) { if (exists_bit) { - hid_hw_close(hidraw->hid); hidraw->exist = 0; - if (hidraw->open) + if (hidraw->open) { + hid_hw_close(hidraw->hid); wake_up_interruptible(&hidraw->wait); + } } else { --hidraw->open; } - if (!hidraw->open && !hidraw->exist) { - device_destroy(hidraw_class, MKDEV(hidraw_major, hidraw->minor)); - hidraw_table[hidraw->minor] = NULL; - kfree(hidraw); + if (!hidraw->open) { + if (!hidraw->exist) { + device_destroy(hidraw_class, + MKDEV(hidraw_major, hidraw->minor)); + hidraw_table[hidraw->minor] = NULL; + kfree(hidraw); + } else { + /* close device for last reader */ + hid_hw_power(hidraw->hid, PM_HINT_NORMAL); + hid_hw_close(hidraw->hid); + } } } |