Commit 672bb0fa authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input

Pull input fixes from Dmitry Torokhov:

 - a fix for use-after-free in Synaptics RMI4 driver

 - correction to multitouch contact tracking on certain ALPS touchpads
   (which got broken when we tried to fix the 2-finger scrolling)

 - touchpad on Lenovo T640p is switched over to SMbus/RMI

 - a few device node refcount fixes

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input:
  Input: synaptics-rmi4 - prevent UAF reported by KASAN
  Input: ALPS - fix multi-touch decoding on SS4 plus touchpads
  Input: synaptics - Lenovo Thinkpad T460p devices should use RMI
  Input: of_touchscreen - add MODULE_LICENSE
  Input: 88pm860x-ts - fix child-node lookup
  Input: twl6040-vibra - fix child-node lookup
  Input: twl4030-vibra - fix sibling-node lookup
parents 9bdbaeba 55edde9f
...@@ -178,12 +178,14 @@ static SIMPLE_DEV_PM_OPS(twl4030_vibra_pm_ops, ...@@ -178,12 +178,14 @@ static SIMPLE_DEV_PM_OPS(twl4030_vibra_pm_ops,
twl4030_vibra_suspend, twl4030_vibra_resume); twl4030_vibra_suspend, twl4030_vibra_resume);
static bool twl4030_vibra_check_coexist(struct twl4030_vibra_data *pdata, static bool twl4030_vibra_check_coexist(struct twl4030_vibra_data *pdata,
struct device_node *node) struct device_node *parent)
{ {
struct device_node *node;
if (pdata && pdata->coexist) if (pdata && pdata->coexist)
return true; return true;
node = of_find_node_by_name(node, "codec"); node = of_get_child_by_name(parent, "codec");
if (node) { if (node) {
of_node_put(node); of_node_put(node);
return true; return true;
......
...@@ -248,8 +248,7 @@ static int twl6040_vibra_probe(struct platform_device *pdev) ...@@ -248,8 +248,7 @@ static int twl6040_vibra_probe(struct platform_device *pdev)
int vddvibr_uV = 0; int vddvibr_uV = 0;
int error; int error;
of_node_get(twl6040_core_dev->of_node); twl6040_core_node = of_get_child_by_name(twl6040_core_dev->of_node,
twl6040_core_node = of_find_node_by_name(twl6040_core_dev->of_node,
"vibra"); "vibra");
if (!twl6040_core_node) { if (!twl6040_core_node) {
dev_err(&pdev->dev, "parent of node is missing?\n"); dev_err(&pdev->dev, "parent of node is missing?\n");
......
...@@ -1250,29 +1250,32 @@ static int alps_decode_ss4_v2(struct alps_fields *f, ...@@ -1250,29 +1250,32 @@ static int alps_decode_ss4_v2(struct alps_fields *f,
case SS4_PACKET_ID_MULTI: case SS4_PACKET_ID_MULTI:
if (priv->flags & ALPS_BUTTONPAD) { if (priv->flags & ALPS_BUTTONPAD) {
if (IS_SS4PLUS_DEV(priv->dev_id)) { if (IS_SS4PLUS_DEV(priv->dev_id)) {
f->mt[0].x = SS4_PLUS_BTL_MF_X_V2(p, 0); f->mt[2].x = SS4_PLUS_BTL_MF_X_V2(p, 0);
f->mt[1].x = SS4_PLUS_BTL_MF_X_V2(p, 1); f->mt[3].x = SS4_PLUS_BTL_MF_X_V2(p, 1);
no_data_x = SS4_PLUS_MFPACKET_NO_AX_BL;
} else { } else {
f->mt[2].x = SS4_BTL_MF_X_V2(p, 0); f->mt[2].x = SS4_BTL_MF_X_V2(p, 0);
f->mt[3].x = SS4_BTL_MF_X_V2(p, 1); f->mt[3].x = SS4_BTL_MF_X_V2(p, 1);
no_data_x = SS4_MFPACKET_NO_AX_BL;
} }
no_data_y = SS4_MFPACKET_NO_AY_BL;
f->mt[2].y = SS4_BTL_MF_Y_V2(p, 0); f->mt[2].y = SS4_BTL_MF_Y_V2(p, 0);
f->mt[3].y = SS4_BTL_MF_Y_V2(p, 1); f->mt[3].y = SS4_BTL_MF_Y_V2(p, 1);
no_data_x = SS4_MFPACKET_NO_AX_BL;
no_data_y = SS4_MFPACKET_NO_AY_BL;
} else { } else {
if (IS_SS4PLUS_DEV(priv->dev_id)) { if (IS_SS4PLUS_DEV(priv->dev_id)) {
f->mt[0].x = SS4_PLUS_STD_MF_X_V2(p, 0); f->mt[2].x = SS4_PLUS_STD_MF_X_V2(p, 0);
f->mt[1].x = SS4_PLUS_STD_MF_X_V2(p, 1); f->mt[3].x = SS4_PLUS_STD_MF_X_V2(p, 1);
no_data_x = SS4_PLUS_MFPACKET_NO_AX;
} else { } else {
f->mt[0].x = SS4_STD_MF_X_V2(p, 0); f->mt[2].x = SS4_STD_MF_X_V2(p, 0);
f->mt[1].x = SS4_STD_MF_X_V2(p, 1); f->mt[3].x = SS4_STD_MF_X_V2(p, 1);
no_data_x = SS4_MFPACKET_NO_AX;
} }
no_data_y = SS4_MFPACKET_NO_AY;
f->mt[2].y = SS4_STD_MF_Y_V2(p, 0); f->mt[2].y = SS4_STD_MF_Y_V2(p, 0);
f->mt[3].y = SS4_STD_MF_Y_V2(p, 1); f->mt[3].y = SS4_STD_MF_Y_V2(p, 1);
no_data_x = SS4_MFPACKET_NO_AX;
no_data_y = SS4_MFPACKET_NO_AY;
} }
f->first_mp = 0; f->first_mp = 0;
......
...@@ -141,10 +141,12 @@ enum SS4_PACKET_ID { ...@@ -141,10 +141,12 @@ enum SS4_PACKET_ID {
#define SS4_TS_Z_V2(_b) (s8)(_b[4] & 0x7F) #define SS4_TS_Z_V2(_b) (s8)(_b[4] & 0x7F)
#define SS4_MFPACKET_NO_AX 8160 /* X-Coordinate value */ #define SS4_MFPACKET_NO_AX 8160 /* X-Coordinate value */
#define SS4_MFPACKET_NO_AY 4080 /* Y-Coordinate value */ #define SS4_MFPACKET_NO_AY 4080 /* Y-Coordinate value */
#define SS4_MFPACKET_NO_AX_BL 8176 /* Buttonless X-Coordinate value */ #define SS4_MFPACKET_NO_AX_BL 8176 /* Buttonless X-Coord value */
#define SS4_MFPACKET_NO_AY_BL 4088 /* Buttonless Y-Coordinate value */ #define SS4_MFPACKET_NO_AY_BL 4088 /* Buttonless Y-Coord value */
#define SS4_PLUS_MFPACKET_NO_AX 4080 /* SS4 PLUS, X */
#define SS4_PLUS_MFPACKET_NO_AX_BL 4088 /* Buttonless SS4 PLUS, X */
/* /*
* enum V7_PACKET_ID - defines the packet type for V7 * enum V7_PACKET_ID - defines the packet type for V7
......
...@@ -173,6 +173,7 @@ static const char * const smbus_pnp_ids[] = { ...@@ -173,6 +173,7 @@ static const char * const smbus_pnp_ids[] = {
"LEN0046", /* X250 */ "LEN0046", /* X250 */
"LEN004a", /* W541 */ "LEN004a", /* W541 */
"LEN200f", /* T450s */ "LEN200f", /* T450s */
"LEN2018", /* T460p */
NULL NULL
}; };
......
...@@ -230,8 +230,10 @@ static irqreturn_t rmi_irq_fn(int irq, void *dev_id) ...@@ -230,8 +230,10 @@ static irqreturn_t rmi_irq_fn(int irq, void *dev_id)
rmi_dbg(RMI_DEBUG_CORE, &rmi_dev->dev, rmi_dbg(RMI_DEBUG_CORE, &rmi_dev->dev,
"Failed to process interrupt request: %d\n", ret); "Failed to process interrupt request: %d\n", ret);
if (count) if (count) {
kfree(attn_data.data); kfree(attn_data.data);
attn_data.data = NULL;
}
if (!kfifo_is_empty(&drvdata->attn_fifo)) if (!kfifo_is_empty(&drvdata->attn_fifo))
return rmi_irq_fn(irq, dev_id); return rmi_irq_fn(irq, dev_id);
......
...@@ -126,7 +126,7 @@ static int pm860x_touch_dt_init(struct platform_device *pdev, ...@@ -126,7 +126,7 @@ static int pm860x_touch_dt_init(struct platform_device *pdev,
int data, n, ret; int data, n, ret;
if (!np) if (!np)
return -ENODEV; return -ENODEV;
np = of_find_node_by_name(np, "touch"); np = of_get_child_by_name(np, "touch");
if (!np) { if (!np) {
dev_err(&pdev->dev, "Can't find touch node\n"); dev_err(&pdev->dev, "Can't find touch node\n");
return -EINVAL; return -EINVAL;
...@@ -144,13 +144,13 @@ static int pm860x_touch_dt_init(struct platform_device *pdev, ...@@ -144,13 +144,13 @@ static int pm860x_touch_dt_init(struct platform_device *pdev,
if (data) { if (data) {
ret = pm860x_reg_write(i2c, PM8607_GPADC_MISC1, data); ret = pm860x_reg_write(i2c, PM8607_GPADC_MISC1, data);
if (ret < 0) if (ret < 0)
return -EINVAL; goto err_put_node;
} }
/* set tsi prebias time */ /* set tsi prebias time */
if (!of_property_read_u32(np, "marvell,88pm860x-tsi-prebias", &data)) { if (!of_property_read_u32(np, "marvell,88pm860x-tsi-prebias", &data)) {
ret = pm860x_reg_write(i2c, PM8607_TSI_PREBIAS, data); ret = pm860x_reg_write(i2c, PM8607_TSI_PREBIAS, data);
if (ret < 0) if (ret < 0)
return -EINVAL; goto err_put_node;
} }
/* set prebias & prechg time of pen detect */ /* set prebias & prechg time of pen detect */
data = 0; data = 0;
...@@ -161,10 +161,18 @@ static int pm860x_touch_dt_init(struct platform_device *pdev, ...@@ -161,10 +161,18 @@ static int pm860x_touch_dt_init(struct platform_device *pdev,
if (data) { if (data) {
ret = pm860x_reg_write(i2c, PM8607_PD_PREBIAS, data); ret = pm860x_reg_write(i2c, PM8607_PD_PREBIAS, data);
if (ret < 0) if (ret < 0)
return -EINVAL; goto err_put_node;
} }
of_property_read_u32(np, "marvell,88pm860x-resistor-X", res_x); of_property_read_u32(np, "marvell,88pm860x-resistor-X", res_x);
of_node_put(np);
return 0; return 0;
err_put_node:
of_node_put(np);
return -EINVAL;
} }
#else #else
#define pm860x_touch_dt_init(x, y, z) (-1) #define pm860x_touch_dt_init(x, y, z) (-1)
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <linux/input.h> #include <linux/input.h>
#include <linux/input/mt.h> #include <linux/input/mt.h>
#include <linux/input/touchscreen.h> #include <linux/input/touchscreen.h>
#include <linux/module.h>
static bool touchscreen_get_prop_u32(struct device *dev, static bool touchscreen_get_prop_u32(struct device *dev,
const char *property, const char *property,
...@@ -185,3 +186,6 @@ void touchscreen_report_pos(struct input_dev *input, ...@@ -185,3 +186,6 @@ void touchscreen_report_pos(struct input_dev *input,
input_report_abs(input, multitouch ? ABS_MT_POSITION_Y : ABS_Y, y); input_report_abs(input, multitouch ? ABS_MT_POSITION_Y : ABS_Y, y);
} }
EXPORT_SYMBOL(touchscreen_report_pos); EXPORT_SYMBOL(touchscreen_report_pos);
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("Device-tree helpers functions for touchscreen devices");
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment