[PATCH v3 2/2] HID: spi-hid: propagate reset GPIO errors from resume
From: Jizhou Tong
Date: Thu Nov 05 2026 - 14:21:50 EST
Stop before powering up if reset assertion fails, balancing the IRQ
disabled by suspend. If reset deassertion fails after power-up, return
that error and queue the existing recovery worker. Otherwise resume may
report success although the device remains held in reset.
Signed-off-by: Jizhou Tong <fqwqf@xxxxxxxxx>
---
drivers/hid/spi-hid/spi-hid-core.c | 18 ++++++++++++++----
1 file changed, 14 insertions(+), 4 deletions(-)
diff --git a/drivers/hid/spi-hid/spi-hid-core.c b/drivers/hid/spi-hid/spi-hid-core.c
index fd64d2d2cb..f2b2106600 100644
--- a/drivers/hid/spi-hid/spi-hid-core.c
+++ b/drivers/hid/spi-hid/spi-hid-core.c
@@ -316,7 +316,7 @@ static int spi_hid_suspend(struct spi_hid *shid)
static int spi_hid_resume(struct spi_hid *shid)
{
- int error;
+ int error = 0;
struct device *dev = &shid->spi->dev;
bool was_reset = false;
@@ -333,7 +333,12 @@ static int spi_hid_resume(struct spi_hid *shid)
* while the device is off.
*/
if (shid->power_state == HIDSPI_OFF) {
- shid->ops->assert_reset(shid->ops);
+ error = shid->ops->assert_reset(shid->ops);
+ if (error) {
+ dev_err(dev, "failed to assert reset: %d\n", error);
+ enable_irq(shid->spi->irq);
+ return error;
+ }
shid->ops->sleep_minimal_reset_delay(shid->ops);
@@ -347,11 +352,13 @@ static int spi_hid_resume(struct spi_hid *shid)
shid->power_state = HIDSPI_ON;
reinit_completion(&shid->reset_done);
error = shid->ops->deassert_reset(shid->ops);
- if (error)
+ if (error) {
dev_err(dev, "%s: failed to deassert reset: %d\n",
__func__, error);
- else
+ set_bit(SPI_HID_ERROR, &shid->flags);
+ } else {
was_reset = true;
+ }
}
enable_irq(shid->spi->irq);
@@ -365,6 +372,9 @@ static int spi_hid_resume(struct spi_hid *shid)
test_bit(SPI_HID_ERROR, &shid->flags))
schedule_work(&shid->reset_work);
+ if (error)
+ return error;
+
if (shid->hid) {
if (was_reset && spi_hid_wait_for_reset(shid)) {
/* No reset response: let recovery retry. */