[PATCH] iio: proximity: sx9324: keep the IRQ balanced across suspend and resume
From: Arnav Kapoor
Date: Mon Oct 26 2026 - 06:21:56 EST
sx9324_suspend() disables the interrupt first and returns with it still
disabled if a register access fails. Resume isn't called after a failed
suspend, so the interrupt is never enabled again. sx9324_resume() also
returns without enabling it on error. Without an interrupt line,
client->irq is 0 and both callbacks act on IRQ 0, which the driver
doesn't own.
Disable the interrupt only once the device is asleep, always enable it
in resume, and skip both when there is no interrupt.
Fixes: 4c18a890dff8 ("iio:proximity:sx9324: Add SX9324 support")
Signed-off-by: Arnav Kapoor <kapoorarnav43@xxxxxxxxx>
---
I'm sending the same fix for sx9310, sx9324 and sx9360 as separate
patches, as the Fixes tags differ.
Compile-tested only (W=1); I don't have SX9324 hardware and haven't
reproduced a failing suspend.
drivers/iio/proximity/sx9324.c | 31 +++++++++++++++++++------------
1 file changed, 19 insertions(+), 12 deletions(-)
diff --git a/drivers/iio/proximity/sx9324.c b/drivers/iio/proximity/sx9324.c
index 255a36976ac4..ced415747a98 100644
--- a/drivers/iio/proximity/sx9324.c
+++ b/drivers/iio/proximity/sx9324.c
@@ -1088,8 +1088,6 @@ static int sx9324_suspend(struct device *dev)
unsigned int regval;
int ret;
- disable_irq_nosync(data->client->irq);
-
guard(mutex)(&data->mutex);
ret = regmap_read(data->regmap, SX9324_REG_GNRL_CTRL1, ®val);
if (ret < 0)
@@ -1100,23 +1098,32 @@ static int sx9324_suspend(struct device *dev)
/* Disable all phases, send the device to sleep. */
- return regmap_write(data->regmap, SX9324_REG_GNRL_CTRL1, 0);
+ ret = regmap_write(data->regmap, SX9324_REG_GNRL_CTRL1, 0);
+ if (ret)
+ return ret;
+
+ /* Only once nothing can fail, as resume isn't called on failure. */
+ if (data->client->irq)
+ disable_irq_nosync(data->client->irq);
+
+ return 0;
}
static int sx9324_resume(struct device *dev)
{
struct sx_common_data *data = iio_priv(dev_get_drvdata(dev));
+ int ret;
- scoped_guard(mutex, &data->mutex) {
- int ret = regmap_write(data->regmap, SX9324_REG_GNRL_CTRL1,
- data->suspend_ctrl |
- SX9324_REG_GNRL_CTRL1_PAUSECTRL);
- if (ret)
- return ret;
- }
+ scoped_guard(mutex, &data->mutex)
+ ret = regmap_write(data->regmap, SX9324_REG_GNRL_CTRL1,
+ data->suspend_ctrl |
+ SX9324_REG_GNRL_CTRL1_PAUSECTRL);
- enable_irq(data->client->irq);
- return 0;
+ /* Balance the suspend even if the device couldn't be woken up. */
+ if (data->client->irq)
+ enable_irq(data->client->irq);
+
+ return ret;
}
static DEFINE_SIMPLE_DEV_PM_OPS(sx9324_pm_ops, sx9324_suspend, sx9324_resume);
base-commit: 2ef6f5c4ee56e90c237c5f7687f09e635f7d30a9
--
2.53.0