[PATCH] HID: mcp2221: fix probing of the I2C bus added by hid_mcp2221

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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

[Index of Archives]     [Linux GPIO]     [Linux SPI]     [Linux Hardward Monitoring]     [LM Sensors]     [Linux USB Devel]     [Linux Media]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux