From: Karl Georg Esser <kgesser@xxxxxxxx> Date: Fri, 9 Dec 2022 16:17:59 +0100 Subject: [PATCH] HID: mcp2221: fix probing of the I2C bus added by hid_mcp2221 As soon as the I2C driver part will be enabled in mcp2221_probe(), the first HID reports might be exchanged with the chip due to other drivers probing for their devices on the just added I2C bus. HID I/O has to be enabled explicitly during mcp2221_probe() to receive response reports. In addition, the I2C bus' adapdata has to be set before any use of the bus, otherwise mcp_{i2c,smbus}_xfer will attempt to dereference a NULL pointer. Fixes: 67a95c21463d ("HID: mcp2221: add usb to i2c-smbus host bridge") Signed-off-by: Karl Georg Esser <kgesser@xxxxxxxx> Signed-off-by: Sven Zühlsdorf <sven.zuehlsdorf@xxxxxxxx> --- drivers/hid/hid-mcp2221.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/hid/hid-mcp2221.c b/drivers/hid/hid-mcp2221.c index 5886543b17f3..35b7d6939b38 100644 --- a/drivers/hid/hid-mcp2221.c +++ b/drivers/hid/hid-mcp2221.c @@ -324,6 +324,9 @@ static int mcp_i2c_xfer(struct i2c_adapter *adapter, int ret; struct mcp2221 *mcp = i2c_get_adapdata(adapter); + if(!mcp) + return -ECONNREFUSED; + hid_hw_power(mcp->hdev, PM_HINT_FULLON); mutex_lock(&mcp->lock); @@ -433,6 +436,9 @@ static int mcp_smbus_xfer(struct i2c_adapter *adapter, u16 addr, int ret; struct mcp2221 *mcp = i2c_get_adapdata(adapter); + if(!mcp) + return -ECONNREFUSED; + hid_hw_power(mcp->hdev, PM_HINT_FULLON); mutex_lock(&mcp->lock); @@ -1148,12 +1154,14 @@ static int mcp2221_probe(struct hid_device *hdev, "MCP2221 usb-i2c bridge on hidraw%d", ((struct hidraw *)hdev->hidraw)->minor); + i2c_set_adapdata(&mcp->adapter, mcp); + hid_device_io_start(hdev); + ret = devm_i2c_add_adapter(&hdev->dev, &mcp->adapter); if (ret) { hid_err(hdev, "can't add usb-i2c adapter: %d\n", ret); return ret; } - i2c_set_adapdata(&mcp->adapter, mcp); #if IS_REACHABLE(CONFIG_GPIOLIB) /* Setup GPIO chip */ -- 2.38.1