Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

HID: i2c: Call acpi_device_fix_up_power for ACPI-enumerated devices

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>

authored by

Hans de Goede and committed by
Jiri Kosina
f3d3eab6 76dd1fbe

+13
+13
drivers/hid/i2c-hid/i2c-hid.c
··· 897 897 return 0; 898 898 } 899 899 900 + static void i2c_hid_acpi_fix_up_power(struct device *dev) 901 + { 902 + acpi_handle handle = ACPI_HANDLE(dev); 903 + struct acpi_device *adev; 904 + 905 + if (handle && acpi_bus_get_device(handle, &adev) == 0) 906 + acpi_device_fix_up_power(adev); 907 + } 908 + 900 909 static const struct acpi_device_id i2c_hid_acpi_match[] = { 901 910 {"ACPI0C50", 0 }, 902 911 {"PNP0C50", 0 }, ··· 918 909 { 919 910 return -ENODEV; 920 911 } 912 + 913 + static inline void i2c_hid_acpi_fix_up_power(struct device *dev) {} 921 914 #endif 922 915 923 916 #ifdef CONFIG_OF ··· 1040 1029 ret = i2c_hid_alloc_buffers(ihid, HID_MIN_BUFFER_SIZE); 1041 1030 if (ret < 0) 1042 1031 goto err_regulator; 1032 + 1033 + i2c_hid_acpi_fix_up_power(&client->dev); 1043 1034 1044 1035 pm_runtime_get_noresume(&client->dev); 1045 1036 pm_runtime_set_active(&client->dev);