* [PATCH 1/2] i2c: mux: pca954x: Make sure the mux remains configured the same as before resume
@ 2023-08-31 18:17 Marek Vasut
2023-08-31 18:17 ` [PATCH 2/2] i2c: mux: pca954x: Resume the mux early Marek Vasut
2023-08-31 21:24 ` [PATCH 1/2] i2c: mux: pca954x: Make sure the mux remains configured the same as before resume Peter Rosin
0 siblings, 2 replies; 6+ messages in thread
From: Marek Vasut @ 2023-08-31 18:17 UTC (permalink / raw)
To: linux-i2c; +Cc: Marek Vasut, Peter Rosin, Wolfram Sang
The current implementation of pca954x_init() rewrites content of data->last_chan
which is then populated into the mux select register. Skip this part, so that the
mux is populated with content of data->last_chan as it was set before suspend.
This way, the mux state is retained across suspend/resume cycle.
Fixes: e65e228eb096 ("i2c: mux: pca954x: support property idle-state")
Signed-off-by: Marek Vasut <marex@denx.de>
---
Cc: Peter Rosin <peda@axentia.se>
Cc: Wolfram Sang <wsa@kernel.org>
Cc: linux-i2c@vger.kernel.org
---
drivers/i2c/muxes/i2c-mux-pca954x.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/i2c/muxes/i2c-mux-pca954x.c b/drivers/i2c/muxes/i2c-mux-pca954x.c
index 2219062104fbc..97cf475dde0f4 100644
--- a/drivers/i2c/muxes/i2c-mux-pca954x.c
+++ b/drivers/i2c/muxes/i2c-mux-pca954x.c
@@ -620,9 +620,9 @@ static int pca954x_resume(struct device *dev)
struct pca954x *data = i2c_mux_priv(muxc);
int ret;
- ret = pca954x_init(client, data);
+ ret = i2c_smbus_write_byte(client, data->last_chan);
if (ret < 0)
- dev_err(&client->dev, "failed to verify mux presence\n");
+ dev_err(&client->dev, "failed to restore mux state\n");
return ret;
}
--
2.40.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 2/2] i2c: mux: pca954x: Resume the mux early
2023-08-31 18:17 [PATCH 1/2] i2c: mux: pca954x: Make sure the mux remains configured the same as before resume Marek Vasut
@ 2023-08-31 18:17 ` Marek Vasut
2023-08-31 21:24 ` [PATCH 1/2] i2c: mux: pca954x: Make sure the mux remains configured the same as before resume Peter Rosin
1 sibling, 0 replies; 6+ messages in thread
From: Marek Vasut @ 2023-08-31 18:17 UTC (permalink / raw)
To: linux-i2c; +Cc: Marek Vasut, Peter Rosin, Wolfram Sang
The mux resumes alongside its subdevices, which means the subdevices may
resume while the mux is not yet fully configured and those subdevices may
fail to access I2C registers through the mux. Use resume_early to resume
the mux before any of the other i2c devices.
Signed-off-by: Marek Vasut <marex@denx.de>
---
NOTE: This might be wrong approach
---
Cc: Peter Rosin <peda@axentia.se>
Cc: Wolfram Sang <wsa@kernel.org>
Cc: linux-i2c@vger.kernel.org
---
drivers/i2c/muxes/i2c-mux-pca954x.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/i2c/muxes/i2c-mux-pca954x.c b/drivers/i2c/muxes/i2c-mux-pca954x.c
index 97cf475dde0f4..87fd8d3ba56b2 100644
--- a/drivers/i2c/muxes/i2c-mux-pca954x.c
+++ b/drivers/i2c/muxes/i2c-mux-pca954x.c
@@ -627,12 +627,14 @@ static int pca954x_resume(struct device *dev)
return ret;
}
-static DEFINE_SIMPLE_DEV_PM_OPS(pca954x_pm, NULL, pca954x_resume);
+static const struct dev_pm_ops pca954x_pm = {
+ .resume_early = pca954x_resume,
+};
static struct i2c_driver pca954x_driver = {
.driver = {
.name = "pca954x",
- .pm = pm_sleep_ptr(&pca954x_pm),
+ .pm = &pca954x_pm,
.of_match_table = pca954x_of_match,
},
.probe = pca954x_probe,
--
2.40.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 1/2] i2c: mux: pca954x: Make sure the mux remains configured the same as before resume
2023-08-31 18:17 [PATCH 1/2] i2c: mux: pca954x: Make sure the mux remains configured the same as before resume Marek Vasut
2023-08-31 18:17 ` [PATCH 2/2] i2c: mux: pca954x: Resume the mux early Marek Vasut
@ 2023-08-31 21:24 ` Peter Rosin
2023-08-31 21:50 ` Marek Vasut
1 sibling, 1 reply; 6+ messages in thread
From: Peter Rosin @ 2023-08-31 21:24 UTC (permalink / raw)
To: Marek Vasut, linux-i2c; +Cc: Wolfram Sang
Hi!
2023-08-31 at 20:17, Marek Vasut wrote:
> The current implementation of pca954x_init() rewrites content of data->last_chan
> which is then populated into the mux select register. Skip this part, so that the
> mux is populated with content of data->last_chan as it was set before suspend.
> This way, the mux state is retained across suspend/resume cycle.
I fail to see in what situation this change makes a significant
difference? For me, it's a nice conservative thing to initialize
to the default state after something comparatively heavy such as
a suspend/resume cycle. If there is a significant difference,
then maybe it's not the usual access patterns after resume since
there are probably other chips initializing as well, in which
case this change might make things worse depending on what
devices you do have and what idle-state you have configured.
> Fixes: e65e228eb096 ("i2c: mux: pca954x: support property idle-state")
> Signed-off-by: Marek Vasut <marex@denx.de>
> ---
> Cc: Peter Rosin <peda@axentia.se>
> Cc: Wolfram Sang <wsa@kernel.org>
> Cc: linux-i2c@vger.kernel.org
> ---
> drivers/i2c/muxes/i2c-mux-pca954x.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/i2c/muxes/i2c-mux-pca954x.c b/drivers/i2c/muxes/i2c-mux-pca954x.c
> index 2219062104fbc..97cf475dde0f4 100644
> --- a/drivers/i2c/muxes/i2c-mux-pca954x.c
> +++ b/drivers/i2c/muxes/i2c-mux-pca954x.c
> @@ -620,9 +620,9 @@ static int pca954x_resume(struct device *dev)
> struct pca954x *data = i2c_mux_priv(muxc);
> int ret;
>
> - ret = pca954x_init(client, data);
> + ret = i2c_smbus_write_byte(client, data->last_chan);
> if (ret < 0)
> - dev_err(&client->dev, "failed to verify mux presence\n");
> + dev_err(&client->dev, "failed to restore mux state\n");
data->last_chan is no longer cleared in case the write fails. Is that a
problem?
Cheers,
Peter
>
> return ret;
> }
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 1/2] i2c: mux: pca954x: Make sure the mux remains configured the same as before resume
2023-08-31 21:24 ` [PATCH 1/2] i2c: mux: pca954x: Make sure the mux remains configured the same as before resume Peter Rosin
@ 2023-08-31 21:50 ` Marek Vasut
2023-09-01 8:07 ` Peter Rosin
0 siblings, 1 reply; 6+ messages in thread
From: Marek Vasut @ 2023-08-31 21:50 UTC (permalink / raw)
To: Peter Rosin, linux-i2c; +Cc: Wolfram Sang
On 8/31/23 23:24, Peter Rosin wrote:
> Hi!
Hi,
> 2023-08-31 at 20:17, Marek Vasut wrote:
>> The current implementation of pca954x_init() rewrites content of data->last_chan
>> which is then populated into the mux select register. Skip this part, so that the
>> mux is populated with content of data->last_chan as it was set before suspend.
>> This way, the mux state is retained across suspend/resume cycle.
>
> I fail to see in what situation this change makes a significant
> difference? For me, it's a nice conservative thing to initialize
> to the default state after something comparatively heavy such as
> a suspend/resume cycle. If there is a significant difference,
> then maybe it's not the usual access patterns after resume since
> there are probably other chips initializing as well, in which
> case this change might make things worse depending on what
> devices you do have and what idle-state you have configured.
Isn't it better to keep the hardware in the same state it was before it
entered suspend ? For me, that's the behavior I would expect from
suspend/resume .
>> Fixes: e65e228eb096 ("i2c: mux: pca954x: support property idle-state")
>> Signed-off-by: Marek Vasut <marex@denx.de>
>> ---
>> Cc: Peter Rosin <peda@axentia.se>
>> Cc: Wolfram Sang <wsa@kernel.org>
>> Cc: linux-i2c@vger.kernel.org
>> ---
>> drivers/i2c/muxes/i2c-mux-pca954x.c | 4 ++--
>> 1 file changed, 2 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/i2c/muxes/i2c-mux-pca954x.c b/drivers/i2c/muxes/i2c-mux-pca954x.c
>> index 2219062104fbc..97cf475dde0f4 100644
>> --- a/drivers/i2c/muxes/i2c-mux-pca954x.c
>> +++ b/drivers/i2c/muxes/i2c-mux-pca954x.c
>> @@ -620,9 +620,9 @@ static int pca954x_resume(struct device *dev)
>> struct pca954x *data = i2c_mux_priv(muxc);
>> int ret;
>>
>> - ret = pca954x_init(client, data);
>> + ret = i2c_smbus_write_byte(client, data->last_chan);
>> if (ret < 0)
>> - dev_err(&client->dev, "failed to verify mux presence\n");
>> + dev_err(&client->dev, "failed to restore mux state\n");
>
> data->last_chan is no longer cleared in case the write fails. Is that a
> problem?
If the write fails here, the hardware is in undefined state anyway .
Either the next attempt to flip the switch would help bring it back, or,
the system is in undefined state.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 1/2] i2c: mux: pca954x: Make sure the mux remains configured the same as before resume
2023-08-31 21:50 ` Marek Vasut
@ 2023-09-01 8:07 ` Peter Rosin
2023-09-01 17:36 ` Marek Vasut
0 siblings, 1 reply; 6+ messages in thread
From: Peter Rosin @ 2023-09-01 8:07 UTC (permalink / raw)
To: Marek Vasut, linux-i2c; +Cc: Wolfram Sang
Hi!
2023-08-31 at 23:50, Marek Vasut wrote:
> On 8/31/23 23:24, Peter Rosin wrote:
>> Hi!
>
> Hi,
>
>> 2023-08-31 at 20:17, Marek Vasut wrote:
>>> The current implementation of pca954x_init() rewrites content of data->last_chan
>>> which is then populated into the mux select register. Skip this part, so that the
>>> mux is populated with content of data->last_chan as it was set before suspend.
>>> This way, the mux state is retained across suspend/resume cycle.
>>
>> I fail to see in what situation this change makes a significant
>> difference? For me, it's a nice conservative thing to initialize
>> to the default state after something comparatively heavy such as
>> a suspend/resume cycle. If there is a significant difference,
>> then maybe it's not the usual access patterns after resume since
>> there are probably other chips initializing as well, in which
>> case this change might make things worse depending on what
>> devices you do have and what idle-state you have configured.
>
> Isn't it better to keep the hardware in the same state it was before it entered suspend ? For me, that's the behavior I would expect from suspend/resume .
Ok, in either case the current behavior isn't a bug. Please drop
the Fixes-tag.
>
>>> Fixes: e65e228eb096 ("i2c: mux: pca954x: support property idle-state")
>>> Signed-off-by: Marek Vasut <marex@denx.de>
>>> ---
>>> Cc: Peter Rosin <peda@axentia.se>
>>> Cc: Wolfram Sang <wsa@kernel.org>
>>> Cc: linux-i2c@vger.kernel.org
>>> ---
>>> drivers/i2c/muxes/i2c-mux-pca954x.c | 4 ++--
>>> 1 file changed, 2 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/drivers/i2c/muxes/i2c-mux-pca954x.c b/drivers/i2c/muxes/i2c-mux-pca954x.c
>>> index 2219062104fbc..97cf475dde0f4 100644
>>> --- a/drivers/i2c/muxes/i2c-mux-pca954x.c
>>> +++ b/drivers/i2c/muxes/i2c-mux-pca954x.c
>>> @@ -620,9 +620,9 @@ static int pca954x_resume(struct device *dev)
>>> struct pca954x *data = i2c_mux_priv(muxc);
>>> int ret;
>>> - ret = pca954x_init(client, data);
>>> + ret = i2c_smbus_write_byte(client, data->last_chan);
>>> if (ret < 0)
>>> - dev_err(&client->dev, "failed to verify mux presence\n");
>>> + dev_err(&client->dev, "failed to restore mux state\n");
>>
>> data->last_chan is no longer cleared in case the write fails. Is that a
>> problem?
>
> If the write fails here, the hardware is in undefined state anyway .
> Either the next attempt to flip the switch would help bring it back, or, the system is in undefined state.
Being in an undefined state with last_chan being zero is better than
being in an undefined state with last_chan holding some other value,
so that writing the register isn't skipped in the following call to
pca954x_select_chan(). This is the whole point of clearing last_chan
on error. Notice how pca954x_select_chan() also clears last_chan on
error.
Cheers,
Peter
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 1/2] i2c: mux: pca954x: Make sure the mux remains configured the same as before resume
2023-09-01 8:07 ` Peter Rosin
@ 2023-09-01 17:36 ` Marek Vasut
0 siblings, 0 replies; 6+ messages in thread
From: Marek Vasut @ 2023-09-01 17:36 UTC (permalink / raw)
To: Peter Rosin, linux-i2c; +Cc: Wolfram Sang
On 9/1/23 10:07, Peter Rosin wrote:
> Hi!
>
> 2023-08-31 at 23:50, Marek Vasut wrote:
>> On 8/31/23 23:24, Peter Rosin wrote:
>>> Hi!
>>
>> Hi,
>>
>>> 2023-08-31 at 20:17, Marek Vasut wrote:
>>>> The current implementation of pca954x_init() rewrites content of data->last_chan
>>>> which is then populated into the mux select register. Skip this part, so that the
>>>> mux is populated with content of data->last_chan as it was set before suspend.
>>>> This way, the mux state is retained across suspend/resume cycle.
>>>
>>> I fail to see in what situation this change makes a significant
>>> difference? For me, it's a nice conservative thing to initialize
>>> to the default state after something comparatively heavy such as
>>> a suspend/resume cycle. If there is a significant difference,
>>> then maybe it's not the usual access patterns after resume since
>>> there are probably other chips initializing as well, in which
>>> case this change might make things worse depending on what
>>> devices you do have and what idle-state you have configured.
>>
>> Isn't it better to keep the hardware in the same state it was before it entered suspend ? For me, that's the behavior I would expect from suspend/resume .
>
> Ok, in either case the current behavior isn't a bug. Please drop
> the Fixes-tag.
>
>>
>>>> Fixes: e65e228eb096 ("i2c: mux: pca954x: support property idle-state")
>>>> Signed-off-by: Marek Vasut <marex@denx.de>
>>>> ---
>>>> Cc: Peter Rosin <peda@axentia.se>
>>>> Cc: Wolfram Sang <wsa@kernel.org>
>>>> Cc: linux-i2c@vger.kernel.org
>>>> ---
>>>> drivers/i2c/muxes/i2c-mux-pca954x.c | 4 ++--
>>>> 1 file changed, 2 insertions(+), 2 deletions(-)
>>>>
>>>> diff --git a/drivers/i2c/muxes/i2c-mux-pca954x.c b/drivers/i2c/muxes/i2c-mux-pca954x.c
>>>> index 2219062104fbc..97cf475dde0f4 100644
>>>> --- a/drivers/i2c/muxes/i2c-mux-pca954x.c
>>>> +++ b/drivers/i2c/muxes/i2c-mux-pca954x.c
>>>> @@ -620,9 +620,9 @@ static int pca954x_resume(struct device *dev)
>>>> struct pca954x *data = i2c_mux_priv(muxc);
>>>> int ret;
>>>> - ret = pca954x_init(client, data);
>>>> + ret = i2c_smbus_write_byte(client, data->last_chan);
>>>> if (ret < 0)
>>>> - dev_err(&client->dev, "failed to verify mux presence\n");
>>>> + dev_err(&client->dev, "failed to restore mux state\n");
>>>
>>> data->last_chan is no longer cleared in case the write fails. Is that a
>>> problem?
>>
>> If the write fails here, the hardware is in undefined state anyway .
>> Either the next attempt to flip the switch would help bring it back, or, the system is in undefined state.
>
> Being in an undefined state with last_chan being zero is better than
> being in an undefined state with last_chan holding some other value,
> so that writing the register isn't skipped in the following call to
> pca954x_select_chan(). This is the whole point of clearing last_chan
> on error. Notice how pca954x_select_chan() also clears last_chan on
> error.
OK, then just drop this patch.
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2023-09-01 17:37 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-08-31 18:17 [PATCH 1/2] i2c: mux: pca954x: Make sure the mux remains configured the same as before resume Marek Vasut
2023-08-31 18:17 ` [PATCH 2/2] i2c: mux: pca954x: Resume the mux early Marek Vasut
2023-08-31 21:24 ` [PATCH 1/2] i2c: mux: pca954x: Make sure the mux remains configured the same as before resume Peter Rosin
2023-08-31 21:50 ` Marek Vasut
2023-09-01 8:07 ` Peter Rosin
2023-09-01 17:36 ` Marek Vasut
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox