]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/commitdiff
Merge branch 'next' into for-linus
authorDmitry Torokhov <dmitry.torokhov@gmail.com>
Thu, 3 Apr 2014 16:26:49 +0000 (09:26 -0700)
committerDmitry Torokhov <dmitry.torokhov@gmail.com>
Thu, 3 Apr 2014 16:26:49 +0000 (09:26 -0700)
First round of input updates for 3.15.

drivers/input/evdev.c
drivers/input/keyboard/adp5588-keys.c
drivers/input/mouse/cypress_ps2.c
drivers/input/mouse/synaptics.c
drivers/input/mousedev.c

index a06e12552886fa57ffbe1731eb744762666cd787..ce953d895f5b2b92d3bbb0d1a19be8a86d563d6b 100644 (file)
@@ -954,11 +954,13 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd,
                        return -EFAULT;
 
                error = input_ff_upload(dev, &effect, file);
+               if (error)
+                       return error;
 
                if (put_user(effect.id, &(((struct ff_effect __user *)p)->id)))
                        return -EFAULT;
 
-               return error;
+               return 0;
        }
 
        /* Multi-number variable-length handlers */
index bb3b57bea8ba4578df5d29c72230882ac29bd62a..5ef7fcf0e2509b8196cf69a993247febae4c20b7 100644 (file)
@@ -76,8 +76,18 @@ static int adp5588_gpio_get_value(struct gpio_chip *chip, unsigned off)
        struct adp5588_kpad *kpad = container_of(chip, struct adp5588_kpad, gc);
        unsigned int bank = ADP5588_BANK(kpad->gpiomap[off]);
        unsigned int bit = ADP5588_BIT(kpad->gpiomap[off]);
+       int val;
 
-       return !!(adp5588_read(kpad->client, GPIO_DAT_STAT1 + bank) & bit);
+       mutex_lock(&kpad->gpio_lock);
+
+       if (kpad->dir[bank] & bit)
+               val = kpad->dat_out[bank];
+       else
+               val = adp5588_read(kpad->client, GPIO_DAT_STAT1 + bank);
+
+       mutex_unlock(&kpad->gpio_lock);
+
+       return !!(val & bit);
 }
 
 static void adp5588_gpio_set_value(struct gpio_chip *chip,
index 87095e2f5153c7dedeae38a18cd10efaa62a9e0c..8af34ffe208b16eff1ab240de45967fb84b6610f 100644 (file)
@@ -409,7 +409,6 @@ static int cypress_set_input_params(struct input_dev *input,
        __clear_bit(REL_X, input->relbit);
        __clear_bit(REL_Y, input->relbit);
 
-       __set_bit(INPUT_PROP_BUTTONPAD, input->propbit);
        __set_bit(EV_KEY, input->evbit);
        __set_bit(BTN_LEFT, input->keybit);
        __set_bit(BTN_RIGHT, input->keybit);
index 26386f9d25696841584f4b7f698a3cc8727fdc54..d8d49d10f9bb60d477124bba603fb9f61be1efdb 100644 (file)
@@ -265,11 +265,22 @@ static int synaptics_identify(struct psmouse *psmouse)
  * Read touchpad resolution and maximum reported coordinates
  * Resolution is left zero if touchpad does not support the query
  */
+
+static const int *quirk_min_max;
+
 static int synaptics_resolution(struct psmouse *psmouse)
 {
        struct synaptics_data *priv = psmouse->private;
        unsigned char resp[3];
 
+       if (quirk_min_max) {
+               priv->x_min = quirk_min_max[0];
+               priv->x_max = quirk_min_max[1];
+               priv->y_min = quirk_min_max[2];
+               priv->y_max = quirk_min_max[3];
+               return 0;
+       }
+
        if (SYN_ID_MAJOR(priv->identity) < 4)
                return 0;
 
@@ -1485,10 +1496,54 @@ static const struct dmi_system_id olpc_dmi_table[] __initconst = {
        { }
 };
 
+static const struct dmi_system_id min_max_dmi_table[] __initconst = {
+#if defined(CONFIG_DMI)
+       {
+               /* Lenovo ThinkPad Helix */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+                       DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad Helix"),
+               },
+               .driver_data = (int []){1024, 5052, 2258, 4832},
+       },
+       {
+               /* Lenovo ThinkPad X240 */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+                       DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X240"),
+               },
+               .driver_data = (int []){1232, 5710, 1156, 4696},
+       },
+       {
+               /* Lenovo ThinkPad T440s */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+                       DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T440"),
+               },
+               .driver_data = (int []){1024, 5112, 2024, 4832},
+       },
+       {
+               /* Lenovo ThinkPad T540p */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+                       DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T540"),
+               },
+               .driver_data = (int []){1024, 5056, 2058, 4832},
+       },
+#endif
+       { }
+};
+
 void __init synaptics_module_init(void)
 {
+       const struct dmi_system_id *min_max_dmi;
+
        impaired_toshiba_kbc = dmi_check_system(toshiba_dmi_table);
        broken_olpc_ec = dmi_check_system(olpc_dmi_table);
+
+       min_max_dmi = dmi_first_match(min_max_dmi_table);
+       if (min_max_dmi)
+               quirk_min_max = min_max_dmi->driver_data;
 }
 
 static int __synaptics_init(struct psmouse *psmouse, bool absolute_mode)
index 4c842c320c2ede9f2bf42d507ee5c91f00eef7e3..b604564dec5c9a5d8d154ac18a61c02341f77e5d 100644 (file)
@@ -67,7 +67,6 @@ struct mousedev {
        struct device dev;
        struct cdev cdev;
        bool exist;
-       bool is_mixdev;
 
        struct list_head mixdev_node;
        bool opened_by_mixdev;
@@ -77,6 +76,9 @@ struct mousedev {
        int old_x[4], old_y[4];
        int frac_dx, frac_dy;
        unsigned long touch;
+
+       int (*open_device)(struct mousedev *mousedev);
+       void (*close_device)(struct mousedev *mousedev);
 };
 
 enum mousedev_emul {
@@ -116,9 +118,6 @@ static unsigned char mousedev_imex_seq[] = { 0xf3, 200, 0xf3, 200, 0xf3, 80 };
 static struct mousedev *mousedev_mix;
 static LIST_HEAD(mousedev_mix_list);
 
-static void mixdev_open_devices(void);
-static void mixdev_close_devices(void);
-
 #define fx(i)  (mousedev->old_x[(mousedev->pkt_count - (i)) & 03])
 #define fy(i)  (mousedev->old_y[(mousedev->pkt_count - (i)) & 03])
 
@@ -428,9 +427,7 @@ static int mousedev_open_device(struct mousedev *mousedev)
        if (retval)
                return retval;
 
-       if (mousedev->is_mixdev)
-               mixdev_open_devices();
-       else if (!mousedev->exist)
+       if (!mousedev->exist)
                retval = -ENODEV;
        else if (!mousedev->open++) {
                retval = input_open_device(&mousedev->handle);
@@ -446,9 +443,7 @@ static void mousedev_close_device(struct mousedev *mousedev)
 {
        mutex_lock(&mousedev->mutex);
 
-       if (mousedev->is_mixdev)
-               mixdev_close_devices();
-       else if (mousedev->exist && !--mousedev->open)
+       if (mousedev->exist && !--mousedev->open)
                input_close_device(&mousedev->handle);
 
        mutex_unlock(&mousedev->mutex);
@@ -459,21 +454,29 @@ static void mousedev_close_device(struct mousedev *mousedev)
  * stream. Note that this function is called with mousedev_mix->mutex
  * held.
  */
-static void mixdev_open_devices(void)
+static int mixdev_open_devices(struct mousedev *mixdev)
 {
-       struct mousedev *mousedev;
+       int error;
+
+       error = mutex_lock_interruptible(&mixdev->mutex);
+       if (error)
+               return error;
 
-       if (mousedev_mix->open++)
-               return;
+       if (!mixdev->open++) {
+               struct mousedev *mousedev;
 
-       list_for_each_entry(mousedev, &mousedev_mix_list, mixdev_node) {
-               if (!mousedev->opened_by_mixdev) {
-                       if (mousedev_open_device(mousedev))
-                               continue;
+               list_for_each_entry(mousedev, &mousedev_mix_list, mixdev_node) {
+                       if (!mousedev->opened_by_mixdev) {
+                               if (mousedev_open_device(mousedev))
+                                       continue;
 
-                       mousedev->opened_by_mixdev = true;
+                               mousedev->opened_by_mixdev = true;
+                       }
                }
        }
+
+       mutex_unlock(&mixdev->mutex);
+       return 0;
 }
 
 /*
@@ -481,19 +484,22 @@ static void mixdev_open_devices(void)
  * device. Note that this function is called with mousedev_mix->mutex
  * held.
  */
-static void mixdev_close_devices(void)
+static void mixdev_close_devices(struct mousedev *mixdev)
 {
-       struct mousedev *mousedev;
+       mutex_lock(&mixdev->mutex);
 
-       if (--mousedev_mix->open)
-               return;
+       if (!--mixdev->open) {
+               struct mousedev *mousedev;
 
-       list_for_each_entry(mousedev, &mousedev_mix_list, mixdev_node) {
-               if (mousedev->opened_by_mixdev) {
-                       mousedev->opened_by_mixdev = false;
-                       mousedev_close_device(mousedev);
+               list_for_each_entry(mousedev, &mousedev_mix_list, mixdev_node) {
+                       if (mousedev->opened_by_mixdev) {
+                               mousedev->opened_by_mixdev = false;
+                               mousedev_close_device(mousedev);
+                       }
                }
        }
+
+       mutex_unlock(&mixdev->mutex);
 }
 
 
@@ -522,7 +528,7 @@ static int mousedev_release(struct inode *inode, struct file *file)
        mousedev_detach_client(mousedev, client);
        kfree(client);
 
-       mousedev_close_device(mousedev);
+       mousedev->close_device(mousedev);
 
        return 0;
 }
@@ -550,7 +556,7 @@ static int mousedev_open(struct inode *inode, struct file *file)
        client->mousedev = mousedev;
        mousedev_attach_client(mousedev, client);
 
-       error = mousedev_open_device(mousedev);
+       error = mousedev->open_device(mousedev);
        if (error)
                goto err_free_client;
 
@@ -861,16 +867,21 @@ static struct mousedev *mousedev_create(struct input_dev *dev,
 
        if (mixdev) {
                dev_set_name(&mousedev->dev, "mice");
+
+               mousedev->open_device = mixdev_open_devices;
+               mousedev->close_device = mixdev_close_devices;
        } else {
                int dev_no = minor;
                /* Normalize device number if it falls into legacy range */
                if (dev_no < MOUSEDEV_MINOR_BASE + MOUSEDEV_MINORS)
                        dev_no -= MOUSEDEV_MINOR_BASE;
                dev_set_name(&mousedev->dev, "mouse%d", dev_no);
+
+               mousedev->open_device = mousedev_open_device;
+               mousedev->close_device = mousedev_close_device;
        }
 
        mousedev->exist = true;
-       mousedev->is_mixdev = mixdev;
        mousedev->handle.dev = input_get_device(dev);
        mousedev->handle.name = dev_name(&mousedev->dev);
        mousedev->handle.handler = handler;
@@ -919,7 +930,7 @@ static void mousedev_destroy(struct mousedev *mousedev)
        device_del(&mousedev->dev);
        mousedev_cleanup(mousedev);
        input_free_minor(MINOR(mousedev->dev.devt));
-       if (!mousedev->is_mixdev)
+       if (mousedev != mousedev_mix)
                input_unregister_handle(&mousedev->handle);
        put_device(&mousedev->dev);
 }