Merge ../linux-2.6-watchdog-mm
[sfrench/cifs-2.6.git] / drivers / input / input.c
index 9cb4b9a54f01ffa38dd0f803785f190dae1f8adb..1c8c8a5bc4a91c0076c9af4539ef3a768102afed 100644 (file)
@@ -176,6 +176,10 @@ void input_event(struct input_dev *dev, unsigned int type, unsigned int code, in
                        break;
 
                case EV_FF:
+
+                       if (value < 0)
+                               return;
+
                        if (dev->event)
                                dev->event(dev, type, code, value);
                        break;
@@ -309,7 +313,8 @@ static void input_link_handle(struct input_handle *handle)
                if (i != NBITS(max)) \
                        continue;
 
-static struct input_device_id *input_match_device(struct input_device_id *id, struct input_dev *dev)
+static const struct input_device_id *input_match_device(const struct input_device_id *id,
+                                                       struct input_dev *dev)
 {
        int i;
 
@@ -762,7 +767,9 @@ static void input_dev_release(struct class_device *class_dev)
 {
        struct input_dev *dev = to_input_dev(class_dev);
 
+       input_ff_destroy(dev);
        kfree(dev);
+
        module_put(THIS_MODULE);
 }
 
@@ -899,12 +906,13 @@ struct input_dev *input_allocate_device(void)
 
        dev = kzalloc(sizeof(struct input_dev), GFP_KERNEL);
        if (dev) {
-               dev->dynalloc = 1;
                dev->cdev.class = &input_class;
                class_device_initialize(&dev->cdev);
                mutex_init(&dev->mutex);
                INIT_LIST_HEAD(&dev->h_list);
                INIT_LIST_HEAD(&dev->node);
+
+               __module_get(THIS_MODULE);
        }
 
        return dev;
@@ -929,17 +937,10 @@ int input_register_device(struct input_dev *dev)
        static atomic_t input_no = ATOMIC_INIT(0);
        struct input_handle *handle;
        struct input_handler *handler;
-       struct input_device_id *id;
+       const struct input_device_id *id;
        const char *path;
        int error;
 
-       if (!dev->dynalloc) {
-               printk(KERN_WARNING "input: device %s is statically allocated, will not register\n"
-                       "Please convert to input_allocate_device() or contact dtor_core@ameritech.net\n",
-                       dev->name ? dev->name : "<Unknown>");
-               return -EINVAL;
-       }
-
        set_bit(EV_SYN, dev->evbit);
 
        /*
@@ -955,10 +956,8 @@ int input_register_device(struct input_dev *dev)
                dev->rep[REP_PERIOD] = 33;
        }
 
-       INIT_LIST_HEAD(&dev->h_list);
        list_add_tail(&dev->node, &input_dev_list);
 
-       dev->cdev.class = &input_class;
        snprintf(dev->cdev.class_id, sizeof(dev->cdev.class_id),
                 "input%ld", (unsigned long) atomic_inc_return(&input_no) - 1);
 
@@ -978,8 +977,6 @@ int input_register_device(struct input_dev *dev)
        if (error)
                goto fail3;
 
-       __module_get(THIS_MODULE);
-
        path = kobject_get_path(&dev->cdev.kobj, GFP_KERNEL);
        printk(KERN_INFO "input: %s as %s\n",
                dev->name ? dev->name : "Unspecified device", path ? path : "N/A");
@@ -1008,9 +1005,12 @@ EXPORT_SYMBOL(input_register_device);
 void input_unregister_device(struct input_dev *dev)
 {
        struct list_head *node, *next;
+       int code;
 
-       if (!dev)
-               return;
+       for (code = 0; code <= KEY_MAX; code++)
+               if (test_bit(code, dev->key))
+                       input_report_key(dev, code, 0);
+       input_sync(dev);
 
        del_timer_sync(&dev->timer);
 
@@ -1037,19 +1037,20 @@ void input_unregister_device(struct input_dev *dev)
 }
 EXPORT_SYMBOL(input_unregister_device);
 
-void input_register_handler(struct input_handler *handler)
+int input_register_handler(struct input_handler *handler)
 {
        struct input_dev *dev;
        struct input_handle *handle;
-       struct input_device_id *id;
-
-       if (!handler)
-               return;
+       const struct input_device_id *id;
 
        INIT_LIST_HEAD(&handler->h_list);
 
-       if (handler->fops != NULL)
+       if (handler->fops != NULL) {
+               if (input_table[handler->minor >> 5])
+                       return -EBUSY;
+
                input_table[handler->minor >> 5] = handler;
+       }
 
        list_add_tail(&handler->node, &input_handler_list);
 
@@ -1063,6 +1064,7 @@ void input_register_handler(struct input_handler *handler)
                                }
 
        input_wakeup_procfs_readers();
+       return 0;
 }
 EXPORT_SYMBOL(input_register_handler);