From 67767a5f7c6d8b48e2f43475bd4d47bb58397d6d Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 3 Apr 2018 15:16:33 +0200 Subject: [PATCH 1/4] HID: i2c-hid: Move i2c_hid_acpi_pdata error reporting to inside the function Log an error in all error paths of i2c_hid_acpi_pdata() instead of having the caller log a generic error. This is a preparation patch for allowing i2c_hid_acpi_pdata() to fail silently under certain conditions. Signed-off-by: Hans de Goede Signed-off-by: Jiri Kosina --- drivers/hid/i2c-hid/i2c-hid.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c index 97689e98e53f..78ca994e6254 100644 --- a/drivers/hid/i2c-hid/i2c-hid.c +++ b/drivers/hid/i2c-hid/i2c-hid.c @@ -874,13 +874,15 @@ static int i2c_hid_acpi_pdata(struct i2c_client *client, acpi_handle handle; handle = ACPI_HANDLE(&client->dev); - if (!handle || acpi_bus_get_device(handle, &adev)) + if (!handle || acpi_bus_get_device(handle, &adev)) { + dev_err(&client->dev, "Error could not get ACPI device\n"); return -ENODEV; + } obj = acpi_evaluate_dsm_typed(handle, &i2c_hid_guid, 1, 1, NULL, ACPI_TYPE_INTEGER); if (!obj) { - dev_err(&client->dev, "device _DSM execution failed\n"); + dev_err(&client->dev, "Error _DSM call to get HID descriptor address failed\n"); return -ENODEV; } @@ -995,11 +997,8 @@ static int i2c_hid_probe(struct i2c_client *client, goto err; } else if (!platform_data) { ret = i2c_hid_acpi_pdata(client, &ihid->pdata); - if (ret) { - dev_err(&client->dev, - "HID register address not provided\n"); + if (ret) goto err; - } } else { ihid->pdata = *platform_data; } From 2dcc8197fefc7eb1d255f1856fc0f642c38cf78d Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 3 Apr 2018 15:16:34 +0200 Subject: [PATCH 2/4] HID: i2c-hid: Silently fail probe for CHPN0001 touchscreen The CHPN0001 ACPI device has a _CID of PNP0C50 and even has the _DSM to get the HID descriptor address, but it is not a HID device at all. It uses its own protocol which is handled by the (still being upstreamed) chipone_icn8505 driver. I guess the _CID and the _DSM are the result of a copy and paste job when the vendor was building the ACPI tables. Before this patch the i2c_hid_driver's probe function will fail with a "hid_descr_cmd failed" error. This commit makes the i2c_hid_driver's probe function instead silently ignored devices with an ACPI id of CHPN0001. Signed-off-by: Hans de Goede Signed-off-by: Jiri Kosina --- drivers/hid/i2c-hid/i2c-hid.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c index 78ca994e6254..cf71c33ac2b2 100644 --- a/drivers/hid/i2c-hid/i2c-hid.c +++ b/drivers/hid/i2c-hid/i2c-hid.c @@ -863,6 +863,15 @@ static int i2c_hid_fetch_hid_descriptor(struct i2c_hid *ihid) } #ifdef CONFIG_ACPI +static const struct acpi_device_id i2c_hid_acpi_blacklist[] = { + /* + * The CHPN0001 ACPI device, which is used to describe the Chipone + * ICN8505 controller, has a _CID of PNP0C50 but is not HID compatible. + */ + {"CHPN0001", 0 }, + { }, +}; + static int i2c_hid_acpi_pdata(struct i2c_client *client, struct i2c_hid_platform_data *pdata) { @@ -879,6 +888,9 @@ static int i2c_hid_acpi_pdata(struct i2c_client *client, return -ENODEV; } + if (acpi_match_device_ids(adev, i2c_hid_acpi_blacklist) == 0) + return -ENODEV; + obj = acpi_evaluate_dsm_typed(handle, &i2c_hid_guid, 1, 1, NULL, ACPI_TYPE_INTEGER); if (!obj) { From b3a81b6c4fc6730ac49e20d789a93c0faabafc98 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 9 May 2018 12:12:15 -0700 Subject: [PATCH 3/4] HID: i2c-hid: check if device is there before really probing On many Chromebooks touch devices are multi-sourced; the components are electrically compatible and one can be freely swapped for another without changing the OS image or firmware. To avoid bunch of scary messages when device is not actually present in the system let's try testing basic communication with it and if there is no response terminate probe early with -ENXIO. Signed-off-by: Dmitry Torokhov Reviewed-by: Benjamin Tissoires Signed-off-by: Jiri Kosina --- drivers/hid/i2c-hid/i2c-hid.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c index cf71c33ac2b2..c5ad918e36e3 100644 --- a/drivers/hid/i2c-hid/i2c-hid.c +++ b/drivers/hid/i2c-hid/i2c-hid.c @@ -1060,6 +1060,14 @@ static int i2c_hid_probe(struct i2c_client *client, pm_runtime_enable(&client->dev); device_enable_async_suspend(&client->dev); + /* Make sure there is something at this address */ + ret = i2c_smbus_read_byte(client); + if (ret < 0) { + dev_dbg(&client->dev, "nothing at this address: %d\n", ret); + ret = -ENXIO; + goto err_pm; + } + ret = i2c_hid_fetch_hid_descriptor(ihid); if (ret < 0) goto err_pm; From d44c2816ac403125277f50994589a963036fb9b3 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Tue, 29 May 2018 14:03:21 +0200 Subject: [PATCH 4/4] HID: i2c-hid: remove i2c_hid_open_mut Since commit 85ae91133152 ("HID: i2c-hid: remove custom locking from i2c_hid_open/close") there are no more users of i2c_hid_open_mut. Remove the unused mutex. Cc: Dmitry Torokhov Cc: Jiri Kosina Signed-off-by: Sebastian Andrzej Siewior Reviewed-by: Dmitry Torokhov Signed-off-by: Jiri Kosina --- drivers/hid/i2c-hid/i2c-hid.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c index c5ad918e36e3..4025ffb05a20 100644 --- a/drivers/hid/i2c-hid/i2c-hid.c +++ b/drivers/hid/i2c-hid/i2c-hid.c @@ -130,8 +130,6 @@ static const struct i2c_hid_cmd hid_no_cmd = { .length = 0 }; * static const struct i2c_hid_cmd hid_set_protocol_cmd = { I2C_HID_CMD(0x07) }; */ -static DEFINE_MUTEX(i2c_hid_open_mut); - /* The main device structure */ struct i2c_hid { struct i2c_client *client; /* i2c client */