aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/input.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-06-27 17:47:31 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-06-27 17:47:31 -0400
commit3e0777b8fa96f7073ed5d13d3bc1d573b766bef9 (patch)
tree3849e8457dd8f038ab7da025c708e275b43ea9c1 /drivers/input/input.c
parenta94130e00038ebeb2f66901a4a4a9e05a03051c1 (diff)
parente5119885f00874453e837e3407014b73de2f4741 (diff)
Merge rsync://rsync.kernel.org/pub/scm/linux/kernel/git/dtor/input.git manually
Some manual fixups required due to clashes with the PF_FREEZE cleanups.
Diffstat (limited to 'drivers/input/input.c')
-rw-r--r--drivers/input/input.c37
1 files changed, 32 insertions, 5 deletions
diff --git a/drivers/input/input.c b/drivers/input/input.c
index 83c77c990dda..7c4b4d37b3e6 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -219,10 +219,24 @@ void input_release_device(struct input_handle *handle)
219 219
220int input_open_device(struct input_handle *handle) 220int input_open_device(struct input_handle *handle)
221{ 221{
222 struct input_dev *dev = handle->dev;
223 int err;
224
225 err = down_interruptible(&dev->sem);
226 if (err)
227 return err;
228
222 handle->open++; 229 handle->open++;
223 if (handle->dev->open) 230
224 return handle->dev->open(handle->dev); 231 if (!dev->users++ && dev->open)
225 return 0; 232 err = dev->open(dev);
233
234 if (err)
235 handle->open--;
236
237 up(&dev->sem);
238
239 return err;
226} 240}
227 241
228int input_flush_device(struct input_handle* handle, struct file* file) 242int input_flush_device(struct input_handle* handle, struct file* file)
@@ -235,10 +249,17 @@ int input_flush_device(struct input_handle* handle, struct file* file)
235 249
236void input_close_device(struct input_handle *handle) 250void input_close_device(struct input_handle *handle)
237{ 251{
252 struct input_dev *dev = handle->dev;
253
238 input_release_device(handle); 254 input_release_device(handle);
239 if (handle->dev->close) 255
240 handle->dev->close(handle->dev); 256 down(&dev->sem);
257
258 if (!--dev->users && dev->close)
259 dev->close(dev);
241 handle->open--; 260 handle->open--;
261
262 up(&dev->sem);
242} 263}
243 264
244static void input_link_handle(struct input_handle *handle) 265static void input_link_handle(struct input_handle *handle)
@@ -415,6 +436,8 @@ void input_register_device(struct input_dev *dev)
415 436
416 set_bit(EV_SYN, dev->evbit); 437 set_bit(EV_SYN, dev->evbit);
417 438
439 init_MUTEX(&dev->sem);
440
418 /* 441 /*
419 * If delay and period are pre-set by the driver, then autorepeating 442 * If delay and period are pre-set by the driver, then autorepeating
420 * is handled by the driver itself and we don't do it in input.c. 443 * is handled by the driver itself and we don't do it in input.c.
@@ -674,6 +697,8 @@ static int input_handlers_read(char *buf, char **start, off_t pos, int count, in
674 return (count > cnt) ? cnt : count; 697 return (count > cnt) ? cnt : count;
675} 698}
676 699
700static struct file_operations input_fileops;
701
677static int __init input_proc_init(void) 702static int __init input_proc_init(void)
678{ 703{
679 struct proc_dir_entry *entry; 704 struct proc_dir_entry *entry;
@@ -688,6 +713,8 @@ static int __init input_proc_init(void)
688 return -ENOMEM; 713 return -ENOMEM;
689 } 714 }
690 entry->owner = THIS_MODULE; 715 entry->owner = THIS_MODULE;
716 input_fileops = *entry->proc_fops;
717 entry->proc_fops = &input_fileops;
691 entry->proc_fops->poll = input_devices_poll; 718 entry->proc_fops->poll = input_devices_poll;
692 entry = create_proc_read_entry("handlers", 0, proc_bus_input_dir, input_handlers_read, NULL); 719 entry = create_proc_read_entry("handlers", 0, proc_bus_input_dir, input_handlers_read, NULL);
693 if (entry == NULL) { 720 if (entry == NULL) {