diff options
Diffstat (limited to 'drivers/input/input.c')
| -rw-r--r-- | drivers/input/input.c | 46 | 
1 files changed, 27 insertions, 19 deletions
diff --git a/drivers/input/input.c b/drivers/input/input.c index 41168d5f8c1..9c79bd56b51 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -14,6 +14,7 @@  #include <linux/types.h>  #include <linux/input.h>  #include <linux/module.h> +#include <linux/slab.h>  #include <linux/random.h>  #include <linux/major.h>  #include <linux/proc_fs.h> @@ -582,7 +583,8 @@ static int input_fetch_keycode(struct input_dev *dev, int scancode)  }  static int input_default_getkeycode(struct input_dev *dev, -				    int scancode, int *keycode) +				    unsigned int scancode, +				    unsigned int *keycode)  {  	if (!dev->keycodesize)  		return -EINVAL; @@ -596,7 +598,8 @@ static int input_default_getkeycode(struct input_dev *dev,  }  static int input_default_setkeycode(struct input_dev *dev, -				    int scancode, int keycode) +				    unsigned int scancode, +				    unsigned int keycode)  {  	int old_keycode;  	int i; @@ -654,12 +657,17 @@ static int input_default_setkeycode(struct input_dev *dev,   * This function should be called by anyone interested in retrieving current   * keymap. Presently keyboard and evdev handlers use it.   */ -int input_get_keycode(struct input_dev *dev, int scancode, int *keycode) +int input_get_keycode(struct input_dev *dev, +		      unsigned int scancode, unsigned int *keycode)  { -	if (scancode < 0) -		return -EINVAL; +	unsigned long flags; +	int retval; + +	spin_lock_irqsave(&dev->event_lock, flags); +	retval = dev->getkeycode(dev, scancode, keycode); +	spin_unlock_irqrestore(&dev->event_lock, flags); -	return dev->getkeycode(dev, scancode, keycode); +	return retval;  }  EXPORT_SYMBOL(input_get_keycode); @@ -672,16 +680,14 @@ EXPORT_SYMBOL(input_get_keycode);   * This function should be called by anyone needing to update current   * keymap. Presently keyboard and evdev handlers use it.   */ -int input_set_keycode(struct input_dev *dev, int scancode, int keycode) +int input_set_keycode(struct input_dev *dev, +		      unsigned int scancode, unsigned int keycode)  {  	unsigned long flags;  	int old_keycode;  	int retval; -	if (scancode < 0) -		return -EINVAL; - -	if (keycode < 0 || keycode > KEY_MAX) +	if (keycode > KEY_MAX)  		return -EINVAL;  	spin_lock_irqsave(&dev->event_lock, flags); @@ -1881,35 +1887,37 @@ static int input_open_file(struct inode *inode, struct file *file)  	const struct file_operations *old_fops, *new_fops = NULL;  	int err; -	lock_kernel(); +	err = mutex_lock_interruptible(&input_mutex); +	if (err) +		return err; +  	/* No load-on-demand here? */  	handler = input_table[iminor(inode) >> 5]; -	if (!handler || !(new_fops = fops_get(handler->fops))) { -		err = -ENODEV; -		goto out; -	} +	if (handler) +		new_fops = fops_get(handler->fops); + +	mutex_unlock(&input_mutex);  	/*  	 * That's _really_ odd. Usually NULL ->open means "nothing special",  	 * not "no device". Oh, well...  	 */ -	if (!new_fops->open) { +	if (!new_fops || !new_fops->open) {  		fops_put(new_fops);  		err = -ENODEV;  		goto out;  	} +  	old_fops = file->f_op;  	file->f_op = new_fops;  	err = new_fops->open(inode, file); -  	if (err) {  		fops_put(file->f_op);  		file->f_op = fops_get(old_fops);  	}  	fops_put(old_fops);  out: -	unlock_kernel();  	return err;  }  |