| From foo@baz Mon Apr 9 17:09:24 CEST 2018 |
| From: Hans de Goede <hdegoede@redhat.com> |
| Date: Tue, 9 May 2017 10:04:36 +0200 |
| Subject: HID: i2c: Call acpi_device_fix_up_power for ACPI-enumerated devices |
| |
| From: Hans de Goede <hdegoede@redhat.com> |
| |
| |
| [ Upstream commit f3d3eab667de62572376abb1aa26316191c39929 ] |
| |
| For ACPI devices which do not have a _PSC method, the ACPI subsys cannot |
| query their initial state at boot, so these devices are assumed to have |
| been put in D0 by the BIOS, but for touchscreens that is not always true. |
| |
| This commit adds a call to acpi_device_fix_up_power to explicitly put |
| devices without a _PSC method into D0 state (for devices with a _PSC |
| method it is a nop). Note we only need to do this on probe, after a |
| resume the ACPI subsys knows the device is in D3 and will properly |
| put it in D0. |
| |
| This fixes the SIS0817 i2c-hid touchscreen on a Peaq C1010 2-in-1 |
| device failing to probe with a "hid_descr_cmd failed" error. |
| |
| Acked-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> |
| Signed-off-by: Hans de Goede <hdegoede@redhat.com> |
| Signed-off-by: Jiri Kosina <jkosina@suse.cz> |
| Signed-off-by: Sasha Levin <alexander.levin@microsoft.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/hid/i2c-hid/i2c-hid.c | 13 +++++++++++++ |
| 1 file changed, 13 insertions(+) |
| |
| --- a/drivers/hid/i2c-hid/i2c-hid.c |
| +++ b/drivers/hid/i2c-hid/i2c-hid.c |
| @@ -968,6 +968,15 @@ static int i2c_hid_acpi_pdata(struct i2c |
| return ret < 0 && ret != -ENXIO ? ret : 0; |
| } |
| |
| +static void i2c_hid_acpi_fix_up_power(struct device *dev) |
| +{ |
| + acpi_handle handle = ACPI_HANDLE(dev); |
| + struct acpi_device *adev; |
| + |
| + if (handle && acpi_bus_get_device(handle, &adev) == 0) |
| + acpi_device_fix_up_power(adev); |
| +} |
| + |
| static const struct acpi_device_id i2c_hid_acpi_match[] = { |
| {"ACPI0C50", 0 }, |
| {"PNP0C50", 0 }, |
| @@ -980,6 +989,8 @@ static inline int i2c_hid_acpi_pdata(str |
| { |
| return -ENODEV; |
| } |
| + |
| +static inline void i2c_hid_acpi_fix_up_power(struct device *dev) {} |
| #endif |
| |
| #ifdef CONFIG_OF |
| @@ -1082,6 +1093,8 @@ static int i2c_hid_probe(struct i2c_clie |
| if (ret < 0) |
| goto err; |
| |
| + i2c_hid_acpi_fix_up_power(&client->dev); |
| + |
| pm_runtime_get_noresume(&client->dev); |
| pm_runtime_set_active(&client->dev); |
| pm_runtime_enable(&client->dev); |