aboutsummaryrefslogtreecommitdiff
path: root/drivers/hid
diff options
context:
space:
mode:
authorManoj Chourasia <mchourasia@nvidia.com>2013-10-01 15:39:00 +0530
committerJiri Kosina <jkosina@suse.cz>2013-10-02 17:02:08 +0200
commit0f5a24c6602063e014ee48892ebf56093241106e (patch)
tree70180aac5b8c0d12d1e2793167dbdf2d2a5039c7 /drivers/hid
parent550dbf47819239c7ceb27bbd9879e2feb0633aab (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. Signed-off-by: Manoj Chourasia <mchourasia@nvidia.com> Reported-by: mika.westerberg@linux.intel.com Tested-by: mika.westerberg@linux.intel.com Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid')
-rw-r--r--drivers/hid/hidraw.c21
1 files changed, 14 insertions, 7 deletions
diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c
index 8918dd12bb6..6a6dd5cd783 100644
--- a/drivers/hid/hidraw.c
+++ b/drivers/hid/hidraw.c
@@ -308,18 +308,25 @@ 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);
+ }
}
}