Skip to content

Commit f023605

Browse files
jwrdegoedeJiri Kosina
authored andcommitted
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 <[email protected]> Signed-off-by: Hans de Goede <[email protected]> Signed-off-by: Jiri Kosina <[email protected]>
1 parent 1f34279 commit f023605

File tree

1 file changed

+30
-43
lines changed

1 file changed

+30
-43
lines changed

drivers/hid/i2c-hid/i2c-hid-core.c

Lines changed: 30 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -426,12 +426,23 @@ static int i2c_hid_set_power(struct i2c_hid *ihid, int power_state)
426426
return ret;
427427
}
428428

429-
static int i2c_hid_execute_reset(struct i2c_hid *ihid)
429+
static int i2c_hid_hwreset(struct i2c_hid *ihid)
430430
{
431431
size_t length = 0;
432432
int ret;
433433

434-
i2c_hid_dbg(ihid, "resetting...\n");
434+
i2c_hid_dbg(ihid, "%s\n", __func__);
435+
436+
/*
437+
* This prevents sending feature reports while the device is
438+
* being reset. Otherwise we may lose the reset complete
439+
* interrupt.
440+
*/
441+
mutex_lock(&ihid->reset_lock);
442+
443+
ret = i2c_hid_set_power(ihid, I2C_HID_PWR_ON);
444+
if (ret)
445+
goto err_unlock;
435446

436447
/* Prepare reset command. Command register goes first. */
437448
*(__le16 *)ihid->cmdbuf = ihid->hdesc.wCommandRegister;
@@ -444,59 +455,35 @@ static int i2c_hid_execute_reset(struct i2c_hid *ihid)
444455

445456
ret = i2c_hid_xfer(ihid, ihid->cmdbuf, length, NULL, 0);
446457
if (ret) {
447-
dev_err(&ihid->client->dev, "failed to reset device.\n");
448-
goto out;
458+
dev_err(&ihid->client->dev,
459+
"failed to reset device: %d\n", ret);
460+
goto err_clear_reset;
449461
}
450462

463+
i2c_hid_dbg(ihid, "%s: waiting...\n", __func__);
464+
451465
if (ihid->quirks & I2C_HID_QUIRK_NO_IRQ_AFTER_RESET) {
452466
msleep(100);
453-
goto out;
454-
}
455-
456-
i2c_hid_dbg(ihid, "%s: waiting...\n", __func__);
457-
if (!wait_event_timeout(ihid->wait,
458-
!test_bit(I2C_HID_RESET_PENDING, &ihid->flags),
459-
msecs_to_jiffies(5000))) {
467+
clear_bit(I2C_HID_RESET_PENDING, &ihid->flags);
468+
} else if (!wait_event_timeout(ihid->wait,
469+
!test_bit(I2C_HID_RESET_PENDING, &ihid->flags),
470+
msecs_to_jiffies(5000))) {
460471
ret = -ENODATA;
461-
goto out;
472+
goto err_clear_reset;
462473
}
463474
i2c_hid_dbg(ihid, "%s: finished.\n", __func__);
464475

465-
out:
466-
clear_bit(I2C_HID_RESET_PENDING, &ihid->flags);
467-
return ret;
468-
}
469-
470-
static int i2c_hid_hwreset(struct i2c_hid *ihid)
471-
{
472-
int ret;
473-
474-
i2c_hid_dbg(ihid, "%s\n", __func__);
475-
476-
/*
477-
* This prevents sending feature reports while the device is
478-
* being reset. Otherwise we may lose the reset complete
479-
* interrupt.
480-
*/
481-
mutex_lock(&ihid->reset_lock);
482-
483-
ret = i2c_hid_set_power(ihid, I2C_HID_PWR_ON);
484-
if (ret)
485-
goto out_unlock;
486-
487-
ret = i2c_hid_execute_reset(ihid);
488-
if (ret) {
489-
dev_err(&ihid->client->dev,
490-
"failed to reset device: %d\n", ret);
491-
i2c_hid_set_power(ihid, I2C_HID_PWR_SLEEP);
492-
goto out_unlock;
493-
}
494-
495476
/* At least some SIS devices need this after reset */
496477
if (!(ihid->quirks & I2C_HID_QUIRK_NO_WAKEUP_AFTER_RESET))
497478
ret = i2c_hid_set_power(ihid, I2C_HID_PWR_ON);
498479

499-
out_unlock:
480+
mutex_unlock(&ihid->reset_lock);
481+
return ret;
482+
483+
err_clear_reset:
484+
clear_bit(I2C_HID_RESET_PENDING, &ihid->flags);
485+
i2c_hid_set_power(ihid, I2C_HID_PWR_SLEEP);
486+
err_unlock:
500487
mutex_unlock(&ihid->reset_lock);
501488
return ret;
502489
}

0 commit comments

Comments
 (0)