mirror of
https://github.com/torvalds/linux.git
synced 2026-05-31 18:43:33 +02:00
HID: i2c-hid: Fold i2c_hid_execute_reset() into i2c_hid_hwreset()
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>
This commit is contained in:
parent
1f342790ad
commit
f023605d1d
|
|
@ -426,49 +426,9 @@ 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)
|
||||
{
|
||||
size_t length = 0;
|
||||
int ret;
|
||||
|
||||
i2c_hid_dbg(ihid, "resetting...\n");
|
||||
|
||||
/* Prepare reset command. Command register goes first. */
|
||||
*(__le16 *)ihid->cmdbuf = ihid->hdesc.wCommandRegister;
|
||||
length += sizeof(__le16);
|
||||
/* Next is RESET command itself */
|
||||
length += i2c_hid_encode_command(ihid->cmdbuf + length,
|
||||
I2C_HID_OPCODE_RESET, 0, 0);
|
||||
|
||||
set_bit(I2C_HID_RESET_PENDING, &ihid->flags);
|
||||
|
||||
ret = i2c_hid_xfer(ihid, ihid->cmdbuf, length, NULL, 0);
|
||||
if (ret) {
|
||||
dev_err(&ihid->client->dev, "failed to reset device.\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
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))) {
|
||||
ret = -ENODATA;
|
||||
goto out;
|
||||
}
|
||||
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)
|
||||
{
|
||||
size_t length = 0;
|
||||
int ret;
|
||||
|
||||
i2c_hid_dbg(ihid, "%s\n", __func__);
|
||||
|
|
@ -482,21 +442,48 @@ static int i2c_hid_hwreset(struct i2c_hid *ihid)
|
|||
|
||||
ret = i2c_hid_set_power(ihid, I2C_HID_PWR_ON);
|
||||
if (ret)
|
||||
goto out_unlock;
|
||||
goto err_unlock;
|
||||
|
||||
ret = i2c_hid_execute_reset(ihid);
|
||||
/* Prepare reset command. Command register goes first. */
|
||||
*(__le16 *)ihid->cmdbuf = ihid->hdesc.wCommandRegister;
|
||||
length += sizeof(__le16);
|
||||
/* Next is RESET command itself */
|
||||
length += i2c_hid_encode_command(ihid->cmdbuf + length,
|
||||
I2C_HID_OPCODE_RESET, 0, 0);
|
||||
|
||||
set_bit(I2C_HID_RESET_PENDING, &ihid->flags);
|
||||
|
||||
ret = i2c_hid_xfer(ihid, ihid->cmdbuf, length, NULL, 0);
|
||||
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;
|
||||
goto err_clear_reset;
|
||||
}
|
||||
|
||||
i2c_hid_dbg(ihid, "%s: waiting...\n", __func__);
|
||||
|
||||
if (ihid->quirks & I2C_HID_QUIRK_NO_IRQ_AFTER_RESET) {
|
||||
msleep(100);
|
||||
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 err_clear_reset;
|
||||
}
|
||||
i2c_hid_dbg(ihid, "%s: finished.\n", __func__);
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user