* [PATCH v3 0/3] iio: proximity: sx93xx: keep the IRQ balanced across suspend and resume
@ 2026-10-28 22:04 Arnav Kapoor
2026-10-28 22:04 ` [PATCH v3 1/3] iio: proximity: sx9310: " Arnav Kapoor
` (2 more replies)
0 siblings, 3 replies; 5+ messages in thread
From: Arnav Kapoor @ 2026-10-28 22:04 UTC (permalink / raw)
To: Jonathan Cameron
Cc: David Lechner, Nuno Sá,
Andy Shevchenko, Andy Shevchenko, Gwendal Grignou, Joshua Crofts,
linux-iio, linux-kernel, Arnav Kapoor
sx9310, sx9324 and sx9360 disable the interrupt in suspend before
anything that can fail, and don't enable it again when suspend or resume
fails. Without an interrupt line they also act on IRQ 0. One patch per
driver, as the Fixes tags differ.
Changes in v3:
- sx9310: blank line after guard(), and a local regmap pointer in
sx9310_wake_up() (Andy)
- Add Joshua's Reviewed-by to all three patches
v2: https://lore.kernel.org/all/20261026112342.65917-1-kapoorarnav43@gmail.com/
Changes in v2:
- Send as a series with a cover letter (Joshua)
- sx9310: move the wake-up register writes into a helper that uses
guard(), so resume can use the usual early returns (Andy)
- sx9324, sx9360: no changes
v1:
https://lore.kernel.org/all/20261026100322.16720-1-kapoorarnav43@gmail.com/
https://lore.kernel.org/all/20261026100408.16874-1-kapoorarnav43@gmail.com/
https://lore.kernel.org/all/20261026100450.17023-1-kapoorarnav43@gmail.com/
Compile-tested only (W=1); I don't have the hardware and haven't
reproduced a failing suspend.
Arnav Kapoor (3):
iio: proximity: sx9310: keep the IRQ balanced across suspend and
resume
iio: proximity: sx9324: keep the IRQ balanced across suspend and
resume
iio: proximity: sx9360: keep the IRQ balanced across suspend and
resume
drivers/iio/proximity/sx9310.c | 42 ++++++++++++++++++++++------------
drivers/iio/proximity/sx9324.c | 31 +++++++++++++++----------
drivers/iio/proximity/sx9360.c | 33 +++++++++++++++-----------
3 files changed, 67 insertions(+), 39 deletions(-)
base-commit: 2ef6f5c4ee56e90c237c5f7687f09e635f7d30a9
--
2.53.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v3 1/3] iio: proximity: sx9310: keep the IRQ balanced across suspend and resume
2026-10-28 22:04 [PATCH v3 0/3] iio: proximity: sx93xx: keep the IRQ balanced across suspend and resume Arnav Kapoor
@ 2026-10-28 22:04 ` Arnav Kapoor
2026-11-01 1:54 ` Jonathan Cameron
2026-10-28 22:04 ` [PATCH v3 2/3] iio: proximity: sx9324: " Arnav Kapoor
2026-10-28 22:04 ` [PATCH v3 3/3] iio: proximity: sx9360: " Arnav Kapoor
2 siblings, 1 reply; 5+ messages in thread
From: Arnav Kapoor @ 2026-10-28 22:04 UTC (permalink / raw)
To: Jonathan Cameron
Cc: David Lechner, Nuno Sá,
Andy Shevchenko, Andy Shevchenko, Gwendal Grignou, Joshua Crofts,
linux-iio, linux-kernel, Arnav Kapoor
sx9310_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. sx9310_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: 72ad02b15d63 ("iio: Add SEMTECH SX9310/9311 sensor driver")
Reviewed-by: Joshua Crofts <joshua.crofts1@gmail.com>
Signed-off-by: Arnav Kapoor <kapoorarnav43@gmail.com>
---
drivers/iio/proximity/sx9310.c | 42 ++++++++++++++++++++++------------
1 file changed, 28 insertions(+), 14 deletions(-)
diff --git a/drivers/iio/proximity/sx9310.c b/drivers/iio/proximity/sx9310.c
index 79ba46d8a0aa..f824d00f1174 100644
--- a/drivers/iio/proximity/sx9310.c
+++ b/drivers/iio/proximity/sx9310.c
@@ -943,8 +943,6 @@ static int sx9310_suspend(struct device *dev)
u8 ctrl0;
int ret;
- disable_irq_nosync(data->client->irq);
-
guard(mutex)(&data->mutex);
ret = regmap_read(data->regmap, SX9310_REG_PROX_CTRL0,
&data->suspend_ctrl);
@@ -956,7 +954,29 @@ static int sx9310_suspend(struct device *dev)
if (ret)
return ret;
- return regmap_write(data->regmap, SX9310_REG_PAUSE, 0);
+ ret = regmap_write(data->regmap, SX9310_REG_PAUSE, 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 sx9310_wake_up(struct sx_common_data *data)
+{
+ struct regmap *map = data->regmap;
+ int ret;
+
+ guard(mutex)(&data->mutex);
+
+ ret = regmap_write(map, SX9310_REG_PAUSE, 1);
+ if (ret)
+ return ret;
+
+ return regmap_write(map, SX9310_REG_PROX_CTRL0, data->suspend_ctrl);
}
static int sx9310_resume(struct device *dev)
@@ -964,19 +984,13 @@ static int sx9310_resume(struct device *dev)
struct sx_common_data *data = iio_priv(dev_get_drvdata(dev));
int ret;
- scoped_guard(mutex, &data->mutex) {
- ret = regmap_write(data->regmap, SX9310_REG_PAUSE, 1);
- if (ret)
- return ret;
+ ret = sx9310_wake_up(data);
- ret = regmap_write(data->regmap, SX9310_REG_PROX_CTRL0,
- data->suspend_ctrl);
- if (ret)
- return ret;
- }
+ /* Balance the suspend even if the device couldn't be woken up. */
+ if (data->client->irq)
+ enable_irq(data->client->irq);
- enable_irq(data->client->irq);
- return 0;
+ return ret;
}
static DEFINE_SIMPLE_DEV_PM_OPS(sx9310_pm_ops, sx9310_suspend, sx9310_resume);
--
2.53.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v3 2/3] iio: proximity: sx9324: keep the IRQ balanced across suspend and resume
2026-10-28 22:04 [PATCH v3 0/3] iio: proximity: sx93xx: keep the IRQ balanced across suspend and resume Arnav Kapoor
2026-10-28 22:04 ` [PATCH v3 1/3] iio: proximity: sx9310: " Arnav Kapoor
@ 2026-10-28 22:04 ` Arnav Kapoor
2026-10-28 22:04 ` [PATCH v3 3/3] iio: proximity: sx9360: " Arnav Kapoor
2 siblings, 0 replies; 5+ messages in thread
From: Arnav Kapoor @ 2026-10-28 22:04 UTC (permalink / raw)
To: Jonathan Cameron
Cc: David Lechner, Nuno Sá,
Andy Shevchenko, Andy Shevchenko, Gwendal Grignou, Joshua Crofts,
linux-iio, linux-kernel, Arnav Kapoor
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")
Reviewed-by: Joshua Crofts <joshua.crofts1@gmail.com>
Signed-off-by: Arnav Kapoor <kapoorarnav43@gmail.com>
---
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);
--
2.53.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v3 3/3] iio: proximity: sx9360: keep the IRQ balanced across suspend and resume
2026-10-28 22:04 [PATCH v3 0/3] iio: proximity: sx93xx: keep the IRQ balanced across suspend and resume Arnav Kapoor
2026-10-28 22:04 ` [PATCH v3 1/3] iio: proximity: sx9310: " Arnav Kapoor
2026-10-28 22:04 ` [PATCH v3 2/3] iio: proximity: sx9324: " Arnav Kapoor
@ 2026-10-28 22:04 ` Arnav Kapoor
2 siblings, 0 replies; 5+ messages in thread
From: Arnav Kapoor @ 2026-10-28 22:04 UTC (permalink / raw)
To: Jonathan Cameron
Cc: David Lechner, Nuno Sá,
Andy Shevchenko, Andy Shevchenko, Gwendal Grignou, Joshua Crofts,
linux-iio, linux-kernel, Arnav Kapoor
sx9360_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. sx9360_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: 1cdb4c47f7f5 ("iio:proximity:sx9360: Add sx9360 support")
Reviewed-by: Joshua Crofts <joshua.crofts1@gmail.com>
Signed-off-by: Arnav Kapoor <kapoorarnav43@gmail.com>
---
drivers/iio/proximity/sx9360.c | 33 ++++++++++++++++++++-------------
1 file changed, 20 insertions(+), 13 deletions(-)
diff --git a/drivers/iio/proximity/sx9360.c b/drivers/iio/proximity/sx9360.c
index ed83d809ecf5..85b83d86a433 100644
--- a/drivers/iio/proximity/sx9360.c
+++ b/drivers/iio/proximity/sx9360.c
@@ -797,8 +797,6 @@ static int sx9360_suspend(struct device *dev)
unsigned int regval;
int ret;
- disable_irq_nosync(data->client->irq);
-
guard(mutex)(&data->mutex);
ret = regmap_read(data->regmap, SX9360_REG_GNRL_CTRL0, ®val);
if (ret < 0)
@@ -809,23 +807,32 @@ static int sx9360_suspend(struct device *dev)
/* Disable all phases, send the device to sleep. */
- return regmap_write(data->regmap, SX9360_REG_GNRL_CTRL0, 0);
+ ret = regmap_write(data->regmap, SX9360_REG_GNRL_CTRL0, 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 sx9360_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_update_bits(data->regmap,
- SX9360_REG_GNRL_CTRL0,
- SX9360_REG_GNRL_CTRL0_PHEN_MASK,
- data->suspend_ctrl);
- if (ret)
- return ret;
- }
- enable_irq(data->client->irq);
- return 0;
+ scoped_guard(mutex, &data->mutex)
+ ret = regmap_update_bits(data->regmap, SX9360_REG_GNRL_CTRL0,
+ SX9360_REG_GNRL_CTRL0_PHEN_MASK,
+ data->suspend_ctrl);
+
+ /* 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(sx9360_pm_ops, sx9360_suspend, sx9360_resume);
--
2.53.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v3 1/3] iio: proximity: sx9310: keep the IRQ balanced across suspend and resume
2026-10-28 22:04 ` [PATCH v3 1/3] iio: proximity: sx9310: " Arnav Kapoor
@ 2026-11-01 1:54 ` Jonathan Cameron
0 siblings, 0 replies; 5+ messages in thread
From: Jonathan Cameron @ 2026-11-01 1:54 UTC (permalink / raw)
To: Arnav Kapoor
Cc: David Lechner, Nuno Sá,
Andy Shevchenko, Andy Shevchenko, Gwendal Grignou, Joshua Crofts,
linux-iio, linux-kernel
On Thu, 29 Oct 2026 03:34:37 +0530
Arnav Kapoor <kapoorarnav43@gmail.com> wrote:
> sx9310_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. sx9310_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.
irq 0 doesn't exist any more on any architectures I think..
It did once, long ago. Today it means no interrupt.
>
> Disable the interrupt only once the device is asleep, always enable it
> in resume, and skip both when there is no interrupt.
>
> Fixes: 72ad02b15d63 ("iio: Add SEMTECH SX9310/9311 sensor driver")
> Reviewed-by: Joshua Crofts <joshua.crofts1@gmail.com>
> Signed-off-by: Arnav Kapoor <kapoorarnav43@gmail.com>
I'm not keen on suspend and resume not being mirror images of each
other with respect to ordering.
> ---
> drivers/iio/proximity/sx9310.c | 42 ++++++++++++++++++++++------------
> 1 file changed, 28 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/iio/proximity/sx9310.c b/drivers/iio/proximity/sx9310.c
> index 79ba46d8a0aa..f824d00f1174 100644
> --- a/drivers/iio/proximity/sx9310.c
> +++ b/drivers/iio/proximity/sx9310.c
> @@ -943,8 +943,6 @@ static int sx9310_suspend(struct device *dev)
> u8 ctrl0;
> int ret;
>
> - disable_irq_nosync(data->client->irq);
> -
> guard(mutex)(&data->mutex);
> ret = regmap_read(data->regmap, SX9310_REG_PROX_CTRL0,
> &data->suspend_ctrl);
> @@ -956,7 +954,29 @@ static int sx9310_suspend(struct device *dev)
> if (ret)
> return ret;
>
> - return regmap_write(data->regmap, SX9310_REG_PAUSE, 0);
> + ret = regmap_write(data->regmap, SX9310_REG_PAUSE, 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 sx9310_wake_up(struct sx_common_data *data)
> +{
> + struct regmap *map = data->regmap;
> + int ret;
> +
> + guard(mutex)(&data->mutex);
> +
> + ret = regmap_write(map, SX9310_REG_PAUSE, 1);
> + if (ret)
> + return ret;
> +
> + return regmap_write(map, SX9310_REG_PROX_CTRL0, data->suspend_ctrl);
> }
>
> static int sx9310_resume(struct device *dev)
> @@ -964,19 +984,13 @@ static int sx9310_resume(struct device *dev)
> struct sx_common_data *data = iio_priv(dev_get_drvdata(dev));
> int ret;
>
> - scoped_guard(mutex, &data->mutex) {
> - ret = regmap_write(data->regmap, SX9310_REG_PAUSE, 1);
> - if (ret)
> - return ret;
> + ret = sx9310_wake_up(data);
>
> - ret = regmap_write(data->regmap, SX9310_REG_PROX_CTRL0,
> - data->suspend_ctrl);
> - if (ret)
> - return ret;
> - }
> + /* Balance the suspend even if the device couldn't be woken up. */
> + if (data->client->irq)
> + enable_irq(data->client->irq);
If we are going to reorder suspend, I'd expect this to also move
and be done before the wake up. I think that should be safe enough?
>
> - enable_irq(data->client->irq);
> - return 0;
> + return ret;
> }
>
> static DEFINE_SIMPLE_DEV_PM_OPS(sx9310_pm_ops, sx9310_suspend, sx9310_resume);
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-11-01 1:54 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-28 22:04 [PATCH v3 0/3] iio: proximity: sx93xx: keep the IRQ balanced across suspend and resume Arnav Kapoor
2026-10-28 22:04 ` [PATCH v3 1/3] iio: proximity: sx9310: " Arnav Kapoor
2026-11-01 1:54 ` Jonathan Cameron
2026-10-28 22:04 ` [PATCH v3 2/3] iio: proximity: sx9324: " Arnav Kapoor
2026-10-28 22:04 ` [PATCH v3 3/3] iio: proximity: sx9360: " Arnav Kapoor
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®