summaryrefslogtreecommitdiff
path: root/drivers/hid
diff options
context:
space:
mode:
authorManoj Chourasia <mchourasia@nvidia.com>2013-10-01 15:59:02 +0530
committerMandar Padmawar <mpadmawar@nvidia.com>2014-05-20 02:26:48 -0700
commit24d60adcdfb4656817c437208e7618ad4c750371 (patch)
treebf8db3ea9a6fa2edf96a9bf674b9a9604da8c7e1 /drivers/hid
parent73e864303da82c1606005a48c3d6f4cf52bf3b25 (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.c21
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);
+ }
}
}