]> git.itanic.dy.fi Git - linux-stable/commitdiff
HID: i2c-hid: Fold i2c_hid_execute_reset() into i2c_hid_hwreset()
authorHans de Goede <hdegoede@redhat.com>
Sat, 2 Dec 2023 22:46:08 +0000 (23:46 +0100)
committerJiri Kosina <jkosina@suse.com>
Wed, 6 Dec 2023 10:48:39 +0000 (11:48 +0100)
i2c_hid_hwreset() is the only caller of i2c_hid_execute_reset(),
fold the latter into the former.

This is a preparation patch for removing the need for
I2C_HID_QUIRK_NO_IRQ_AFTER_RESET by making i2c-hid behave
more like Windows.

No functional changes intended.

Reviewed-by: Douglas Anderson <dianders@chromium.org>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
drivers/hid/i2c-hid/i2c-hid-core.c

index 2735cd585af0df846d7430bac643cfd0ce81fc9b..ca2a4ccb9abfed5e6346f82722d419fd8887a161 100644 (file)
@@ -426,12 +426,23 @@ static int i2c_hid_set_power(struct i2c_hid *ihid, int power_state)
        return ret;
 }
 
-static int i2c_hid_execute_reset(struct i2c_hid *ihid)
+static int i2c_hid_hwreset(struct i2c_hid *ihid)
 {
        size_t length = 0;
        int ret;
 
-       i2c_hid_dbg(ihid, "resetting...\n");
+       i2c_hid_dbg(ihid, "%s\n", __func__);
+
+       /*
+        * This prevents sending feature reports while the device is
+        * being reset. Otherwise we may lose the reset complete
+        * interrupt.
+        */
+       mutex_lock(&ihid->reset_lock);
+
+       ret = i2c_hid_set_power(ihid, I2C_HID_PWR_ON);
+       if (ret)
+               goto err_unlock;
 
        /* Prepare reset command. Command register goes first. */
        *(__le16 *)ihid->cmdbuf = ihid->hdesc.wCommandRegister;
@@ -444,59 +455,35 @@ static int i2c_hid_execute_reset(struct i2c_hid *ihid)
 
        ret = i2c_hid_xfer(ihid, ihid->cmdbuf, length, NULL, 0);
        if (ret) {
-               dev_err(&ihid->client->dev, "failed to reset device.\n");
-               goto out;
+               dev_err(&ihid->client->dev,
+                       "failed to reset device: %d\n", ret);
+               goto err_clear_reset;
        }
 
+       i2c_hid_dbg(ihid, "%s: waiting...\n", __func__);
+
        if (ihid->quirks & I2C_HID_QUIRK_NO_IRQ_AFTER_RESET) {
                msleep(100);
-               goto out;
-       }
-
-       i2c_hid_dbg(ihid, "%s: waiting...\n", __func__);
-       if (!wait_event_timeout(ihid->wait,
-                               !test_bit(I2C_HID_RESET_PENDING, &ihid->flags),
-                               msecs_to_jiffies(5000))) {
+               clear_bit(I2C_HID_RESET_PENDING, &ihid->flags);
+       } else if (!wait_event_timeout(ihid->wait,
+                                      !test_bit(I2C_HID_RESET_PENDING, &ihid->flags),
+                                      msecs_to_jiffies(5000))) {
                ret = -ENODATA;
-               goto out;
+               goto err_clear_reset;
        }
        i2c_hid_dbg(ihid, "%s: finished.\n", __func__);
 
-out:
-       clear_bit(I2C_HID_RESET_PENDING, &ihid->flags);
-       return ret;
-}
-
-static int i2c_hid_hwreset(struct i2c_hid *ihid)
-{
-       int ret;
-
-       i2c_hid_dbg(ihid, "%s\n", __func__);
-
-       /*
-        * This prevents sending feature reports while the device is
-        * being reset. Otherwise we may lose the reset complete
-        * interrupt.
-        */
-       mutex_lock(&ihid->reset_lock);
-
-       ret = i2c_hid_set_power(ihid, I2C_HID_PWR_ON);
-       if (ret)
-               goto out_unlock;
-
-       ret = i2c_hid_execute_reset(ihid);
-       if (ret) {
-               dev_err(&ihid->client->dev,
-                       "failed to reset device: %d\n", ret);
-               i2c_hid_set_power(ihid, I2C_HID_PWR_SLEEP);
-               goto out_unlock;
-       }
-
        /* At least some SIS devices need this after reset */
        if (!(ihid->quirks & I2C_HID_QUIRK_NO_WAKEUP_AFTER_RESET))
                ret = i2c_hid_set_power(ihid, I2C_HID_PWR_ON);
 
-out_unlock:
+       mutex_unlock(&ihid->reset_lock);
+       return ret;
+
+err_clear_reset:
+       clear_bit(I2C_HID_RESET_PENDING, &ihid->flags);
+       i2c_hid_set_power(ihid, I2C_HID_PWR_SLEEP);
+err_unlock:
        mutex_unlock(&ihid->reset_lock);
        return ret;
 }