summaryrefslogtreecommitdiffstats
path: root/drivers/hid
diff options
context:
space:
mode:
authorHamish Martin <hamish.martin@alliedtelesis.co.nz>2023-10-25 16:55:11 +1300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2023-12-20 17:01:58 +0100
commitd4b50ac06ea6e47bdd2b04e97d1090c673c80645 (patch)
treef00c9ba0117e7e31aa9f3ace1cfacf6099b462c0 /drivers/hid
parent2afe67cfe8f121b1b9dd244a0edc01b89cd65813 (diff)
downloadlinux-stable-d4b50ac06ea6e47bdd2b04e97d1090c673c80645.tar.gz
linux-stable-d4b50ac06ea6e47bdd2b04e97d1090c673c80645.tar.bz2
linux-stable-d4b50ac06ea6e47bdd2b04e97d1090c673c80645.zip
HID: mcp2221: Allow IO to start during probe
[ Upstream commit 73ce9f1f2741a38f5d27393e627702ae2c46e6f2 ] During the probe we add an I2C adapter and as soon as we add that adapter it may be used for a transfer (e.g via the code in i2cdetect()). Those transfers are not able to complete and time out. This is because the HID raw_event callback (mcp2221_raw_event) will not be invoked until the HID device's 'driver_input_lock' is marked up at the completion of the probe in hid_device_probe(). This starves the driver of the responses it is waiting for. In order to allow the I2C transfers to complete while we are still in the probe, start the IO once we have completed init of the HID device. This issue seems to have been seen before and a patch was submitted but it seems it was never accepted. See: https://lore.kernel.org/all/20221103222714.21566-3-Enrik.Berkhan@inka.de/ Signed-off-by: Hamish Martin <hamish.martin@alliedtelesis.co.nz> Signed-off-by: Jiri Kosina <jkosina@suse.cz> Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'drivers/hid')
-rw-r--r--drivers/hid/hid-mcp2221.c2
1 files changed, 2 insertions, 0 deletions
diff --git a/drivers/hid/hid-mcp2221.c b/drivers/hid/hid-mcp2221.c
index b95f31cf0fa2..aef0785c91cc 100644
--- a/drivers/hid/hid-mcp2221.c
+++ b/drivers/hid/hid-mcp2221.c
@@ -1142,6 +1142,8 @@ static int mcp2221_probe(struct hid_device *hdev,
if (ret)
return ret;
+ hid_device_io_start(hdev);
+
/* Set I2C bus clock diviser */
if (i2c_clk_freq > 400)
i2c_clk_freq = 400;