* [PATCH] iio: light: stk3310: Deal with the ps interrupt issue in PM
@ 2026-04-27 9:43 Miao Li
2026-04-27 9:56 ` Andy Shevchenko
` (2 more replies)
0 siblings, 3 replies; 12+ messages in thread
From: Miao Li @ 2026-04-27 9:43 UTC (permalink / raw)
To: jic23
Cc: dlechner, nuno.sa, andy, waqar.hameed, dixitparmar19, linux-iio,
linux-kernel, limiao870622, Miao Li
From: Miao Li <limiao@kylinos.cn>
On the Huawei hisi platform, if the STK3311-X chip's PS interrupt
is configured in "Recommended interrupt mode", the interrupt cannot
be triggered normally after waking from suspend or hibernation.
In this case, neither disabling and re-enabling the interrupt nor
resetting the PS threshold register can restore the interrupt to
normal operation.
if we disable the interrupt in suspend(), then reset the PS threshold
register and enable the interrupt in resume(), this issue can be fixed.
Signed-off-by: Miao Li <limiao@kylinos.cn>
---
drivers/iio/light/stk3310.c | 71 ++++++++++++++++++++++++++++++++++---
1 file changed, 67 insertions(+), 4 deletions(-)
diff --git a/drivers/iio/light/stk3310.c b/drivers/iio/light/stk3310.c
index a75a83594..367657920 100644
--- a/drivers/iio/light/stk3310.c
+++ b/drivers/iio/light/stk3310.c
@@ -117,6 +117,9 @@ struct stk3310_data {
struct mutex lock;
bool als_enabled;
bool ps_enabled;
+ bool ps_int_enabled;
+ uint32_t ps_thdl;
+ uint32_t ps_thdh;
uint32_t ps_near_level;
u64 timestamp;
struct regmap *regmap;
@@ -296,8 +299,15 @@ static int stk3310_write_event(struct iio_dev *indio_dev,
buf = cpu_to_be16(val);
ret = regmap_bulk_write(data->regmap, reg, &buf, 2);
- if (ret < 0)
+ if (ret < 0) {
dev_err(&client->dev, "failed to set PS threshold!\n");
+ return ret;
+ }
+
+ if (reg == STK3310_REG_THDH_PS)
+ data->ps_thdh = val;
+ else
+ data->ps_thdl = val;
return ret;
}
@@ -331,8 +341,17 @@ static int stk3310_write_event_config(struct iio_dev *indio_dev,
/* Set INT_PS value */
mutex_lock(&data->lock);
ret = regmap_field_write(data->reg_int_ps, state);
- if (ret < 0)
+ if (ret < 0) {
dev_err(&client->dev, "failed to set interrupt mode\n");
+ mutex_unlock(&data->lock);
+ return ret;
+ }
+
+ if (state == false)
+ data->ps_int_enabled = false;
+ else
+ data->ps_int_enabled = true;
+
mutex_unlock(&data->lock);
return ret;
@@ -504,8 +523,13 @@ static int stk3310_init(struct iio_dev *indio_dev)
/* Enable PS interrupts */
ret = regmap_field_write(data->reg_int_ps, STK3310_PSINT_EN);
- if (ret < 0)
+ if (ret < 0) {
dev_err(&client->dev, "failed to enable interrupts!\n");
+ return ret;
+ }
+
+ data->ps_int_enabled = true;
+ data->ps_thdh = STK3310_PS_MAX_VAL;
return ret;
}
@@ -671,9 +695,18 @@ static void stk3310_remove(struct i2c_client *client)
static int stk3310_suspend(struct device *dev)
{
struct stk3310_data *data;
+ int ret;
data = iio_priv(i2c_get_clientdata(to_i2c_client(dev)));
+ if (data->ps_int_enabled) {
+ ret = regmap_field_write(data->reg_int_ps, 0x0);
+ if (ret < 0) {
+ dev_err(dev, "failed to disable ps int at suspend.\n");
+ return ret;
+ }
+ }
+
return stk3310_set_state(data, STK3310_STATE_STANDBY);
}
@@ -681,6 +714,8 @@ static int stk3310_resume(struct device *dev)
{
u8 state = 0;
struct stk3310_data *data;
+ __be16 buf;
+ int ret;
data = iio_priv(i2c_get_clientdata(to_i2c_client(dev)));
if (data->ps_enabled)
@@ -688,7 +723,35 @@ static int stk3310_resume(struct device *dev)
if (data->als_enabled)
state |= STK3310_STATE_EN_ALS;
- return stk3310_set_state(data, state);
+ ret = stk3310_set_state(data, state);
+ if (ret < 0)
+ return ret;
+
+ if (data->ps_thdl != 0x0) {
+ buf = cpu_to_be16(data->ps_thdl);
+ ret = regmap_bulk_write(data->regmap, STK3310_REG_THDL_PS, &buf, 2);
+ if (ret < 0) {
+ dev_err(dev, "failed to set reg THDL_PS at resume.\n");
+ return ret;
+ }
+ }
+
+ if (data->ps_thdh != STK3310_PS_MAX_VAL) {
+ buf = cpu_to_be16(data->ps_thdh);
+ ret = regmap_bulk_write(data->regmap, STK3310_REG_THDH_PS, &buf, 2);
+ if (ret < 0) {
+ dev_err(dev, "failed to set reg THDH_PS at resume.\n");
+ return ret;
+ }
+ }
+
+ if (data->ps_int_enabled) {
+ ret = regmap_field_write(data->reg_int_ps, STK3310_PSINT_EN);
+ if (ret < 0)
+ dev_err(dev, "failed to enable ps int at resume.\n");
+ }
+
+ return ret;
}
static DEFINE_SIMPLE_DEV_PM_OPS(stk3310_pm_ops, stk3310_suspend,
--
2.25.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH] iio: light: stk3310: Deal with the ps interrupt issue in PM
2026-04-27 9:43 [PATCH] iio: light: stk3310: Deal with the ps interrupt issue in PM Miao Li
@ 2026-04-27 9:56 ` Andy Shevchenko
2026-04-27 10:13 ` Joshua Crofts
2026-04-28 18:22 ` Jonathan Cameron
2 siblings, 0 replies; 12+ messages in thread
From: Andy Shevchenko @ 2026-04-27 9:56 UTC (permalink / raw)
To: Miao Li
Cc: jic23, dlechner, nuno.sa, andy, waqar.hameed, dixitparmar19,
linux-iio, linux-kernel, Miao Li
On Mon, Apr 27, 2026 at 05:43:13PM +0800, Miao Li wrote:
> On the Huawei hisi platform, if the STK3311-X chip's PS interrupt
Is it officially spelled form of 'hisi'? I was under impression it should be
spelled as 'HiSi'.
> is configured in "Recommended interrupt mode", the interrupt cannot
> be triggered normally after waking from suspend or hibernation.
>
> In this case, neither disabling and re-enabling the interrupt nor
> resetting the PS threshold register can restore the interrupt to
> normal operation.
>
> if we disable the interrupt in suspend(), then reset the PS threshold
> register and enable the interrupt in resume(), this issue can be fixed.
Sounds like a fix with the Fixes tag being missed.
...
> bool als_enabled;
> bool ps_enabled;
> + bool ps_int_enabled;
> + uint32_t ps_thdl;
> + uint32_t ps_thdh;
> uint32_t ps_near_level;
Use u32 in the fix and add a new (refactoring) change that moves from uintXX_t
to uXX, and all the same to intXX_t to sXX.
> u64 timestamp;
> struct regmap *regmap;
Another potential patch (third one), may be derived from what `pahole` thinks
of all this. I mean that the layout maybe suboptimal, and one can rearrange
the members of the data types to reduce memory footprint.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] iio: light: stk3310: Deal with the ps interrupt issue in PM
2026-04-27 9:43 [PATCH] iio: light: stk3310: Deal with the ps interrupt issue in PM Miao Li
2026-04-27 9:56 ` Andy Shevchenko
@ 2026-04-27 10:13 ` Joshua Crofts
2026-04-28 18:22 ` Jonathan Cameron
2 siblings, 0 replies; 12+ messages in thread
From: Joshua Crofts @ 2026-04-27 10:13 UTC (permalink / raw)
To: Miao Li
Cc: jic23, dlechner, nuno.sa, andy, waqar.hameed, dixitparmar19,
linux-iio, linux-kernel, Miao Li
On Mon, 27 Apr 2026 at 11:48, Miao Li <limiao870622@163.com> wrote:
> @@ -296,8 +299,15 @@ static int stk3310_write_event(struct iio_dev *indio_dev,
>
> buf = cpu_to_be16(val);
> ret = regmap_bulk_write(data->regmap, reg, &buf, 2);
> - if (ret < 0)
> + if (ret < 0) {
> dev_err(&client->dev, "failed to set PS threshold!\n");
> + return ret;
> + }
> +
> + if (reg == STK3310_REG_THDH_PS)
> + data->ps_thdh = val;
> + else
> + data->ps_thdl = val;
>
> return ret;
> }
Maybe add mutex_lock() and mutex_unlock() here as well? Just
as stk3310_write_event_config().
--
Kind regards
CJD
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] iio: light: stk3310: Deal with the ps interrupt issue in PM
2026-04-27 9:43 [PATCH] iio: light: stk3310: Deal with the ps interrupt issue in PM Miao Li
2026-04-27 9:56 ` Andy Shevchenko
2026-04-27 10:13 ` Joshua Crofts
@ 2026-04-28 18:22 ` Jonathan Cameron
2026-04-29 6:18 ` Miao Li
` (3 more replies)
2 siblings, 4 replies; 12+ messages in thread
From: Jonathan Cameron @ 2026-04-28 18:22 UTC (permalink / raw)
To: Miao Li
Cc: dlechner, nuno.sa, andy, waqar.hameed, dixitparmar19, linux-iio,
linux-kernel, Miao Li
On Mon, 27 Apr 2026 17:43:13 +0800
Miao Li <limiao870622@163.com> wrote:
> From: Miao Li <limiao@kylinos.cn>
Hi Miao Li
A few (possibly additional) things inline.
>
> On the Huawei hisi platform, if the STK3311-X chip's PS interrupt
I'm curious. What HiSilicon platform is this?
Good to have that recorded as part of the description for anyone
else who encounters this bug.
> is configured in "Recommended interrupt mode", the interrupt cannot
> be triggered normally after waking from suspend or hibernation.
>
> In this case, neither disabling and re-enabling the interrupt nor
> resetting the PS threshold register can restore the interrupt to
> normal operation.
>
> if we disable the interrupt in suspend(), then reset the PS threshold
> register and enable the interrupt in resume(), this issue can be fixed.
Switch text to imperative.
If the interrupt is disabled in suspend() then rest the PS threshold
register and enable the interrupt in resume(). This resolves the issue.
Or something like that.
>
> Signed-off-by: Miao Li <limiao@kylinos.cn>
> @@ -504,8 +523,13 @@ static int stk3310_init(struct iio_dev *indio_dev)
>
> /* Enable PS interrupts */
> ret = regmap_field_write(data->reg_int_ps, STK3310_PSINT_EN);
> - if (ret < 0)
> + if (ret < 0) {
> dev_err(&client->dev, "failed to enable interrupts!\n");
> + return ret;
> + }
> +
> + data->ps_int_enabled = true;
> + data->ps_thdh = STK3310_PS_MAX_VAL;
>
> return ret;
return 0;
...
> @@ -681,6 +714,8 @@ static int stk3310_resume(struct device *dev)
> {
> u8 state = 0;
> struct stk3310_data *data;
> + __be16 buf;
> + int ret;
>
> data = iio_priv(i2c_get_clientdata(to_i2c_client(dev)));
> if (data->ps_enabled)
> @@ -688,7 +723,35 @@ static int stk3310_resume(struct device *dev)
> if (data->als_enabled)
> state |= STK3310_STATE_EN_ALS;
>
> - return stk3310_set_state(data, state);
> + ret = stk3310_set_state(data, state);
> + if (ret < 0)
> + return ret;
> +
> + if (data->ps_thdl != 0x0) {
> + buf = cpu_to_be16(data->ps_thdl);
> + ret = regmap_bulk_write(data->regmap, STK3310_REG_THDL_PS, &buf, 2);
sizeof(buf) rather than 2. here and below.
> + if (ret < 0) {
> + dev_err(dev, "failed to set reg THDL_PS at resume.\n");
> + return ret;
> + }
> + }
> +
> + if (data->ps_thdh != STK3310_PS_MAX_VAL) {
> + buf = cpu_to_be16(data->ps_thdh);
> + ret = regmap_bulk_write(data->regmap, STK3310_REG_THDH_PS, &buf, 2);
> + if (ret < 0) {
> + dev_err(dev, "failed to set reg THDH_PS at resume.\n");
> + return ret;
> + }
> + }
> +
> + if (data->ps_int_enabled) {
> + ret = regmap_field_write(data->reg_int_ps, STK3310_PSINT_EN);
> + if (ret < 0)
> + dev_err(dev, "failed to enable ps int at resume.\n");
Keep return ret in here so we have consistent pattern with the above .
> + }
> +
> + return ret;
Then
return 0;
> }
>
> static DEFINE_SIMPLE_DEV_PM_OPS(stk3310_pm_ops, stk3310_suspend,
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH] iio: light: stk3310: Deal with the ps interrupt issue in PM
2026-04-28 18:22 ` Jonathan Cameron
@ 2026-04-29 6:18 ` Miao Li
2026-04-29 6:45 ` Miao Li
` (2 subsequent siblings)
3 siblings, 0 replies; 12+ messages in thread
From: Miao Li @ 2026-04-29 6:18 UTC (permalink / raw)
To: jic23
Cc: andy, dixitparmar19, dlechner, nuno.sa, waqar.hameed,
limiao870622, linux-iio, linux-kernel, Miao Li
From: Miao Li <limiao@kylinos.cn>
On the Inspur HS326 laptop(which integrated with HiSilicon M900
processor), if the STK3311-X chip's PS interrupt is configured
in "Recommended interrupt mode", the interrupt cannot be triggered
normally after waking from suspend or hibernation.
In this case, neither disabling and re-enabling the interrupt nor
resetting the PS threshold register can restore the interrupt to
normal operation.
If the interrupt is disabled in suspend() then reset the PS threshold
register and enable the interrupt in resume(). This resolves the issue.
Signed-off-by: Miao Li <limiao@kylinos.cn>
---
drivers/iio/light/stk3310.c | 74 ++++++++++++++++++++++++++++++++++---
1 file changed, 69 insertions(+), 5 deletions(-)
diff --git a/drivers/iio/light/stk3310.c b/drivers/iio/light/stk3310.c
index a75a83594..af1c28c84 100644
--- a/drivers/iio/light/stk3310.c
+++ b/drivers/iio/light/stk3310.c
@@ -117,6 +117,9 @@ struct stk3310_data {
struct mutex lock;
bool als_enabled;
bool ps_enabled;
+ bool ps_int_enabled;
+ uint32_t ps_thdl;
+ uint32_t ps_thdh;
uint32_t ps_near_level;
u64 timestamp;
struct regmap *regmap;
@@ -296,8 +299,15 @@ static int stk3310_write_event(struct iio_dev *indio_dev,
buf = cpu_to_be16(val);
ret = regmap_bulk_write(data->regmap, reg, &buf, 2);
- if (ret < 0)
+ if (ret < 0) {
dev_err(&client->dev, "failed to set PS threshold!\n");
+ return ret;
+ }
+
+ if (reg == STK3310_REG_THDH_PS)
+ data->ps_thdh = val;
+ else
+ data->ps_thdl = val;
return ret;
}
@@ -331,8 +341,17 @@ static int stk3310_write_event_config(struct iio_dev *indio_dev,
/* Set INT_PS value */
mutex_lock(&data->lock);
ret = regmap_field_write(data->reg_int_ps, state);
- if (ret < 0)
+ if (ret < 0) {
dev_err(&client->dev, "failed to set interrupt mode\n");
+ mutex_unlock(&data->lock);
+ return ret;
+ }
+
+ if (state == false)
+ data->ps_int_enabled = false;
+ else
+ data->ps_int_enabled = true;
+
mutex_unlock(&data->lock);
return ret;
@@ -504,10 +523,15 @@ static int stk3310_init(struct iio_dev *indio_dev)
/* Enable PS interrupts */
ret = regmap_field_write(data->reg_int_ps, STK3310_PSINT_EN);
- if (ret < 0)
+ if (ret < 0) {
dev_err(&client->dev, "failed to enable interrupts!\n");
+ return ret;
+ }
- return ret;
+ data->ps_int_enabled = true;
+ data->ps_thdh = STK3310_PS_MAX_VAL;
+
+ return 0;
}
static bool stk3310_is_volatile_reg(struct device *dev, unsigned int reg)
@@ -671,9 +695,18 @@ static void stk3310_remove(struct i2c_client *client)
static int stk3310_suspend(struct device *dev)
{
struct stk3310_data *data;
+ int ret;
data = iio_priv(i2c_get_clientdata(to_i2c_client(dev)));
+ if (data->ps_int_enabled) {
+ ret = regmap_field_write(data->reg_int_ps, 0x0);
+ if (ret < 0) {
+ dev_err(dev, "failed to disable ps int at suspend.\n");
+ return ret;
+ }
+ }
+
return stk3310_set_state(data, STK3310_STATE_STANDBY);
}
@@ -681,6 +714,8 @@ static int stk3310_resume(struct device *dev)
{
u8 state = 0;
struct stk3310_data *data;
+ __be16 buf;
+ int ret;
data = iio_priv(i2c_get_clientdata(to_i2c_client(dev)));
if (data->ps_enabled)
@@ -688,7 +723,36 @@ static int stk3310_resume(struct device *dev)
if (data->als_enabled)
state |= STK3310_STATE_EN_ALS;
- return stk3310_set_state(data, state);
+ ret = stk3310_set_state(data, state);
+ if (ret < 0)
+ return ret;
+
+ if (data->ps_thdl != 0x0) {
+ buf = cpu_to_be16(data->ps_thdl);
+ ret = regmap_bulk_write(data->regmap, STK3310_REG_THDL_PS, &buf, sizeof(buf));
+ if (ret < 0) {
+ dev_err(dev, "failed to set reg THDL_PS at resume.\n");
+ return ret;
+ }
+ }
+
+ if (data->ps_thdh != STK3310_PS_MAX_VAL) {
+ buf = cpu_to_be16(data->ps_thdh);
+ ret = regmap_bulk_write(data->regmap, STK3310_REG_THDH_PS, &buf, sizeof(buf));
+ if (ret < 0) {
+ dev_err(dev, "failed to set reg THDH_PS at resume.\n");
+ return ret;
+ }
+ }
+
+ if (data->ps_int_enabled) {
+ ret = regmap_field_write(data->reg_int_ps, STK3310_PSINT_EN);
+ if (ret < 0)
+ dev_err(dev, "failed to enable ps int at resume.\n");
+ return ret;
+ }
+
+ return 0;
}
static DEFINE_SIMPLE_DEV_PM_OPS(stk3310_pm_ops, stk3310_suspend,
--
2.25.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH] iio: light: stk3310: Deal with the ps interrupt issue in PM
2026-04-28 18:22 ` Jonathan Cameron
2026-04-29 6:18 ` Miao Li
@ 2026-04-29 6:45 ` Miao Li
2026-04-29 6:51 ` [PATCH v2] " Miao Li
2026-04-29 7:14 ` [PATCH v3] " Miao Li
3 siblings, 0 replies; 12+ messages in thread
From: Miao Li @ 2026-04-29 6:45 UTC (permalink / raw)
To: jic23
Cc: andy, dixitparmar19, dlechner, nuno.sa, waqar.hameed,
limiao870622, linux-iio, linux-kernel
> On the Inspur HS326 laptop(which integrated with HiSilicon M900
> processor), if the STK3311-X chip's PS interrupt is configured
> in "Recommended interrupt mode", the interrupt cannot be triggered
> normally after waking from suspend or hibernation.
>
> In this case, neither disabling and re-enabling the interrupt nor
> resetting the PS threshold register can restore the interrupt to
> normal operation.
>
> If the interrupt is disabled in suspend() then reset the PS threshold
> register and enable the interrupt in resume(). This resolves the issue.
Hi, Jonathan
I'm sorry that I forgot to add 'v2' to this patch title,
sending it again with 'v2' added to the subject.
Best regard
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v2] iio: light: stk3310: Deal with the ps interrupt issue in PM
2026-04-28 18:22 ` Jonathan Cameron
2026-04-29 6:18 ` Miao Li
2026-04-29 6:45 ` Miao Li
@ 2026-04-29 6:51 ` Miao Li
2026-04-29 6:59 ` Andy Shevchenko
2026-04-29 7:14 ` [PATCH v3] " Miao Li
3 siblings, 1 reply; 12+ messages in thread
From: Miao Li @ 2026-04-29 6:51 UTC (permalink / raw)
To: jic23
Cc: andy, dixitparmar19, dlechner, nuno.sa, waqar.hameed,
limiao870622, linux-iio, linux-kernel, Miao Li
From: Miao Li <limiao@kylinos.cn>
On the Inspur HS326 laptop(which integrated with HiSilicon M900
processor), if the STK3311-X chip's PS interrupt is configured
in "Recommended interrupt mode", the interrupt cannot be triggered
normally after waking from suspend or hibernation.
In this case, neither disabling and re-enabling the interrupt nor
resetting the PS threshold register can restore the interrupt to
normal operation.
If the interrupt is disabled in suspend() then reset the PS threshold
register and enable the interrupt in resume(). This resolves the issue.
Signed-off-by: Miao Li <limiao@kylinos.cn>
---
drivers/iio/light/stk3310.c | 74 ++++++++++++++++++++++++++++++++++---
1 file changed, 69 insertions(+), 5 deletions(-)
diff --git a/drivers/iio/light/stk3310.c b/drivers/iio/light/stk3310.c
index a75a83594..af1c28c84 100644
--- a/drivers/iio/light/stk3310.c
+++ b/drivers/iio/light/stk3310.c
@@ -117,6 +117,9 @@ struct stk3310_data {
struct mutex lock;
bool als_enabled;
bool ps_enabled;
+ bool ps_int_enabled;
+ uint32_t ps_thdl;
+ uint32_t ps_thdh;
uint32_t ps_near_level;
u64 timestamp;
struct regmap *regmap;
@@ -296,8 +299,15 @@ static int stk3310_write_event(struct iio_dev *indio_dev,
buf = cpu_to_be16(val);
ret = regmap_bulk_write(data->regmap, reg, &buf, 2);
- if (ret < 0)
+ if (ret < 0) {
dev_err(&client->dev, "failed to set PS threshold!\n");
+ return ret;
+ }
+
+ if (reg == STK3310_REG_THDH_PS)
+ data->ps_thdh = val;
+ else
+ data->ps_thdl = val;
return ret;
}
@@ -331,8 +341,17 @@ static int stk3310_write_event_config(struct iio_dev *indio_dev,
/* Set INT_PS value */
mutex_lock(&data->lock);
ret = regmap_field_write(data->reg_int_ps, state);
- if (ret < 0)
+ if (ret < 0) {
dev_err(&client->dev, "failed to set interrupt mode\n");
+ mutex_unlock(&data->lock);
+ return ret;
+ }
+
+ if (state == false)
+ data->ps_int_enabled = false;
+ else
+ data->ps_int_enabled = true;
+
mutex_unlock(&data->lock);
return ret;
@@ -504,10 +523,15 @@ static int stk3310_init(struct iio_dev *indio_dev)
/* Enable PS interrupts */
ret = regmap_field_write(data->reg_int_ps, STK3310_PSINT_EN);
- if (ret < 0)
+ if (ret < 0) {
dev_err(&client->dev, "failed to enable interrupts!\n");
+ return ret;
+ }
- return ret;
+ data->ps_int_enabled = true;
+ data->ps_thdh = STK3310_PS_MAX_VAL;
+
+ return 0;
}
static bool stk3310_is_volatile_reg(struct device *dev, unsigned int reg)
@@ -671,9 +695,18 @@ static void stk3310_remove(struct i2c_client *client)
static int stk3310_suspend(struct device *dev)
{
struct stk3310_data *data;
+ int ret;
data = iio_priv(i2c_get_clientdata(to_i2c_client(dev)));
+ if (data->ps_int_enabled) {
+ ret = regmap_field_write(data->reg_int_ps, 0x0);
+ if (ret < 0) {
+ dev_err(dev, "failed to disable ps int at suspend.\n");
+ return ret;
+ }
+ }
+
return stk3310_set_state(data, STK3310_STATE_STANDBY);
}
@@ -681,6 +714,8 @@ static int stk3310_resume(struct device *dev)
{
u8 state = 0;
struct stk3310_data *data;
+ __be16 buf;
+ int ret;
data = iio_priv(i2c_get_clientdata(to_i2c_client(dev)));
if (data->ps_enabled)
@@ -688,7 +723,36 @@ static int stk3310_resume(struct device *dev)
if (data->als_enabled)
state |= STK3310_STATE_EN_ALS;
- return stk3310_set_state(data, state);
+ ret = stk3310_set_state(data, state);
+ if (ret < 0)
+ return ret;
+
+ if (data->ps_thdl != 0x0) {
+ buf = cpu_to_be16(data->ps_thdl);
+ ret = regmap_bulk_write(data->regmap, STK3310_REG_THDL_PS, &buf, sizeof(buf));
+ if (ret < 0) {
+ dev_err(dev, "failed to set reg THDL_PS at resume.\n");
+ return ret;
+ }
+ }
+
+ if (data->ps_thdh != STK3310_PS_MAX_VAL) {
+ buf = cpu_to_be16(data->ps_thdh);
+ ret = regmap_bulk_write(data->regmap, STK3310_REG_THDH_PS, &buf, sizeof(buf));
+ if (ret < 0) {
+ dev_err(dev, "failed to set reg THDH_PS at resume.\n");
+ return ret;
+ }
+ }
+
+ if (data->ps_int_enabled) {
+ ret = regmap_field_write(data->reg_int_ps, STK3310_PSINT_EN);
+ if (ret < 0)
+ dev_err(dev, "failed to enable ps int at resume.\n");
+ return ret;
+ }
+
+ return 0;
}
static DEFINE_SIMPLE_DEV_PM_OPS(stk3310_pm_ops, stk3310_suspend,
--
2.25.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH v2] iio: light: stk3310: Deal with the ps interrupt issue in PM
2026-04-29 6:51 ` [PATCH v2] " Miao Li
@ 2026-04-29 6:59 ` Andy Shevchenko
2026-04-29 7:50 ` Miao Li
0 siblings, 1 reply; 12+ messages in thread
From: Andy Shevchenko @ 2026-04-29 6:59 UTC (permalink / raw)
To: Miao Li
Cc: jic23, andy, dixitparmar19, dlechner, nuno.sa, waqar.hameed,
linux-iio, linux-kernel, Miao Li
On Wed, Apr 29, 2026 at 02:51:23PM +0800, Miao Li wrote:
> On the Inspur HS326 laptop(which integrated with HiSilicon M900
> processor), if the STK3311-X chip's PS interrupt is configured
> in "Recommended interrupt mode", the interrupt cannot be triggered
> normally after waking from suspend or hibernation.
>
> In this case, neither disabling and re-enabling the interrupt nor
> resetting the PS threshold register can restore the interrupt to
> normal operation.
>
> If the interrupt is disabled in suspend() then reset the PS threshold
> register and enable the interrupt in resume(). This resolves the issue.
...
> struct mutex lock;
> bool als_enabled;
> bool ps_enabled;
> + bool ps_int_enabled;
> + uint32_t ps_thdl;
> + uint32_t ps_thdh;
I still think we shouldn't add more {u}intXX_t into the drivers.
Just add a patch on top of this to clean up those types to use
kernel regular ones (uXX/sXX) instead.
> uint32_t ps_near_level;
> u64 timestamp;
> struct regmap *regmap;
I also haven't seen the response on `pahole` run. Is that tool happy with
the proposed layout?
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v3] iio: light: stk3310: Deal with the ps interrupt issue in PM
2026-04-28 18:22 ` Jonathan Cameron
` (2 preceding siblings ...)
2026-04-29 6:51 ` [PATCH v2] " Miao Li
@ 2026-04-29 7:14 ` Miao Li
2026-04-29 9:03 ` Andy Shevchenko
2026-04-29 9:19 ` Jonathan Cameron
3 siblings, 2 replies; 12+ messages in thread
From: Miao Li @ 2026-04-29 7:14 UTC (permalink / raw)
To: jic23
Cc: andy, dixitparmar19, dlechner, nuno.sa, waqar.hameed,
limiao870622, linux-iio, linux-kernel, Miao Li
From: Miao Li <limiao@kylinos.cn>
On the Inspur HS326 laptop(which integrated with HiSilicon M900
processor), if the STK3311-X chip's PS interrupt is configured
in "Recommended interrupt mode", the interrupt cannot be triggered
normally after waking from suspend or hibernation.
In this case, neither disabling and re-enabling the interrupt nor
resetting the PS threshold register can restore the interrupt to
normal operation.
If the interrupt is disabled in suspend() then reset the PS threshold
register and enable the interrupt in resume(). This resolves the issue.
Signed-off-by: Miao Li <limiao@kylinos.cn>
---
drivers/iio/light/stk3310.c | 75 ++++++++++++++++++++++++++++++++++---
1 file changed, 70 insertions(+), 5 deletions(-)
diff --git a/drivers/iio/light/stk3310.c b/drivers/iio/light/stk3310.c
index a75a83594..f7c4e5014 100644
--- a/drivers/iio/light/stk3310.c
+++ b/drivers/iio/light/stk3310.c
@@ -117,6 +117,9 @@ struct stk3310_data {
struct mutex lock;
bool als_enabled;
bool ps_enabled;
+ bool ps_int_enabled;
+ uint32_t ps_thdl;
+ uint32_t ps_thdh;
uint32_t ps_near_level;
u64 timestamp;
struct regmap *regmap;
@@ -296,8 +299,15 @@ static int stk3310_write_event(struct iio_dev *indio_dev,
buf = cpu_to_be16(val);
ret = regmap_bulk_write(data->regmap, reg, &buf, 2);
- if (ret < 0)
+ if (ret < 0) {
dev_err(&client->dev, "failed to set PS threshold!\n");
+ return ret;
+ }
+
+ if (reg == STK3310_REG_THDH_PS)
+ data->ps_thdh = val;
+ else
+ data->ps_thdl = val;
return ret;
}
@@ -331,8 +341,17 @@ static int stk3310_write_event_config(struct iio_dev *indio_dev,
/* Set INT_PS value */
mutex_lock(&data->lock);
ret = regmap_field_write(data->reg_int_ps, state);
- if (ret < 0)
+ if (ret < 0) {
dev_err(&client->dev, "failed to set interrupt mode\n");
+ mutex_unlock(&data->lock);
+ return ret;
+ }
+
+ if (state == false)
+ data->ps_int_enabled = false;
+ else
+ data->ps_int_enabled = true;
+
mutex_unlock(&data->lock);
return ret;
@@ -504,10 +523,15 @@ static int stk3310_init(struct iio_dev *indio_dev)
/* Enable PS interrupts */
ret = regmap_field_write(data->reg_int_ps, STK3310_PSINT_EN);
- if (ret < 0)
+ if (ret < 0) {
dev_err(&client->dev, "failed to enable interrupts!\n");
+ return ret;
+ }
- return ret;
+ data->ps_int_enabled = true;
+ data->ps_thdh = STK3310_PS_MAX_VAL;
+
+ return 0;
}
static bool stk3310_is_volatile_reg(struct device *dev, unsigned int reg)
@@ -671,9 +695,18 @@ static void stk3310_remove(struct i2c_client *client)
static int stk3310_suspend(struct device *dev)
{
struct stk3310_data *data;
+ int ret;
data = iio_priv(i2c_get_clientdata(to_i2c_client(dev)));
+ if (data->ps_int_enabled) {
+ ret = regmap_field_write(data->reg_int_ps, 0x0);
+ if (ret < 0) {
+ dev_err(dev, "failed to disable ps int at suspend.\n");
+ return ret;
+ }
+ }
+
return stk3310_set_state(data, STK3310_STATE_STANDBY);
}
@@ -681,6 +714,8 @@ static int stk3310_resume(struct device *dev)
{
u8 state = 0;
struct stk3310_data *data;
+ __be16 buf;
+ int ret;
data = iio_priv(i2c_get_clientdata(to_i2c_client(dev)));
if (data->ps_enabled)
@@ -688,7 +723,37 @@ static int stk3310_resume(struct device *dev)
if (data->als_enabled)
state |= STK3310_STATE_EN_ALS;
- return stk3310_set_state(data, state);
+ ret = stk3310_set_state(data, state);
+ if (ret < 0)
+ return ret;
+
+ if (data->ps_thdl != 0x0) {
+ buf = cpu_to_be16(data->ps_thdl);
+ ret = regmap_bulk_write(data->regmap, STK3310_REG_THDL_PS, &buf, sizeof(buf));
+ if (ret < 0) {
+ dev_err(dev, "failed to set reg THDL_PS at resume.\n");
+ return ret;
+ }
+ }
+
+ if (data->ps_thdh != STK3310_PS_MAX_VAL) {
+ buf = cpu_to_be16(data->ps_thdh);
+ ret = regmap_bulk_write(data->regmap, STK3310_REG_THDH_PS, &buf, sizeof(buf));
+ if (ret < 0) {
+ dev_err(dev, "failed to set reg THDH_PS at resume.\n");
+ return ret;
+ }
+ }
+
+ if (data->ps_int_enabled) {
+ ret = regmap_field_write(data->reg_int_ps, STK3310_PSINT_EN);
+ if (ret < 0) {
+ dev_err(dev, "failed to enable ps int at resume.\n");
+ return ret;
+ }
+ }
+
+ return 0;
}
static DEFINE_SIMPLE_DEV_PM_OPS(stk3310_pm_ops, stk3310_suspend,
--
2.25.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: Re: [PATCH v2] iio: light: stk3310: Deal with the ps interrupt issue in PM
2026-04-29 6:59 ` Andy Shevchenko
@ 2026-04-29 7:50 ` Miao Li
0 siblings, 0 replies; 12+ messages in thread
From: Miao Li @ 2026-04-29 7:50 UTC (permalink / raw)
To: jic23, andy
Cc: dixitparmar19, dlechner, nuno.sa, waqar.hameed, limiao870622,
linux-iio, linux-kernel
> > struct mutex lock;
> > bool als_enabled;
> > bool ps_enabled;
> > + bool ps_int_enabled;
> > + uint32_t ps_thdl;
> > + uint32_t ps_thdh;
>
> I still think we shouldn't add more {u}intXX_t into the drivers.
> Just add a patch on top of this to clean up those types to use
> kernel regular ones (uXX/sXX) instead.
>
> > uint32_t ps_near_level;
> > u64 timestamp;
> > struct regmap *regmap;
>
> I also haven't seen the response on `pahole` run. Is that tool happy with
> the proposed layout?
Hi, Andy
Patch v3 only fixes a few syntax errors in the function resume()
that were introduced by patch v2,
what you said I will revise at patch v4.
Best Regards.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v3] iio: light: stk3310: Deal with the ps interrupt issue in PM
2026-04-29 7:14 ` [PATCH v3] " Miao Li
@ 2026-04-29 9:03 ` Andy Shevchenko
2026-04-29 9:19 ` Jonathan Cameron
1 sibling, 0 replies; 12+ messages in thread
From: Andy Shevchenko @ 2026-04-29 9:03 UTC (permalink / raw)
To: Miao Li
Cc: jic23, andy, dixitparmar19, dlechner, nuno.sa, waqar.hameed,
linux-iio, linux-kernel, Miao Li
On Wed, Apr 29, 2026 at 03:14:02PM +0800, Miao Li wrote:
> On the Inspur HS326 laptop(which integrated with HiSilicon M900
'...laptop (which...'
> processor), if the STK3311-X chip's PS interrupt is configured
> in "Recommended interrupt mode", the interrupt cannot be triggered
> normally after waking from suspend or hibernation.
>
> In this case, neither disabling and re-enabling the interrupt nor
> resetting the PS threshold register can restore the interrupt to
> normal operation.
>
> If the interrupt is disabled in suspend() then reset the PS threshold
> register and enable the interrupt in resume(). This resolves the issue.
...
> + if (state == false)
> + data->ps_int_enabled = false;
> + else
> + data->ps_int_enabled = true;
data->ps_int_enabled = state;
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v3] iio: light: stk3310: Deal with the ps interrupt issue in PM
2026-04-29 7:14 ` [PATCH v3] " Miao Li
2026-04-29 9:03 ` Andy Shevchenko
@ 2026-04-29 9:19 ` Jonathan Cameron
1 sibling, 0 replies; 12+ messages in thread
From: Jonathan Cameron @ 2026-04-29 9:19 UTC (permalink / raw)
To: Miao Li
Cc: andy, dixitparmar19, dlechner, nuno.sa, waqar.hameed, linux-iio,
linux-kernel, Miao Li
On Wed, 29 Apr 2026 15:14:02 +0800
Miao Li <limiao870622@163.com> wrote:
> From: Miao Li <limiao@kylinos.cn>
>
> On the Inspur HS326 laptop(which integrated with HiSilicon M900
> processor), if the STK3311-X chip's PS interrupt is configured
> in "Recommended interrupt mode", the interrupt cannot be triggered
> normally after waking from suspend or hibernation.
>
> In this case, neither disabling and re-enabling the interrupt nor
> resetting the PS threshold register can restore the interrupt to
> normal operation.
>
> If the interrupt is disabled in suspend() then reset the PS threshold
> register and enable the interrupt in resume(). This resolves the issue.
>
> Signed-off-by: Miao Li <limiao@kylinos.cn>
Hi.
Please do not send a new version in reply to an old one. A few reasons
that most kernel maintainers ask for new threads for each version.
1. Threads can get very complex if there are lots of versions.
2. Many reviewers who find themselves with a few minutes look at most recent
emails. In a threaded email client, a reply like this one ends up pages
back so attracts fewer reviews.
I don't have anything else to add to Andy's review. However please
slow down a bit on new versions to allow people to respond to earlier
ones. If there is a known problem you have noticed after sending it
out feel free to review your own patch on the list and point that problem out.
Jonathan
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2026-04-29 9:19 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-27 9:43 [PATCH] iio: light: stk3310: Deal with the ps interrupt issue in PM Miao Li
2026-04-27 9:56 ` Andy Shevchenko
2026-04-27 10:13 ` Joshua Crofts
2026-04-28 18:22 ` Jonathan Cameron
2026-04-29 6:18 ` Miao Li
2026-04-29 6:45 ` Miao Li
2026-04-29 6:51 ` [PATCH v2] " Miao Li
2026-04-29 6:59 ` Andy Shevchenko
2026-04-29 7:50 ` Miao Li
2026-04-29 7:14 ` [PATCH v3] " Miao Li
2026-04-29 9:03 ` Andy Shevchenko
2026-04-29 9:19 ` Jonathan Cameron
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox