* [PATCH] iio: imu: st_lsm6dsx: deselect shub page before reading whoami
@ 2026-06-04 13:27 Andreas Kempe
2026-06-04 14:13 ` Lorenzo Bianconi
0 siblings, 1 reply; 7+ messages in thread
From: Andreas Kempe @ 2026-06-04 13:27 UTC (permalink / raw)
To: Lorenzo Bianconi, Jonathan Cameron
Cc: David Lechner, Nuno Sá, Andy Shevchenko,
linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org,
John Ernberg, Andreas Kempe
As part of driver initialisation, e.g. st_lsm6dsx_init_shub() selects
the shub register page using st_lsm6dsx_set_page(). Selecting the shub
register page shadows the regular register space so whoami, among other
registers, is no longer accessible.
In applications where the IMU is permanently powered separately from the
processor, there is a window where a reset of the CPU leaves the IMU in
the shub register page. Once this occurs, any subsequent probe attempt
fails because of the register shadowing.
Using the ism330dlc, the error typically looks like
st_lsm6dsx_i2c 3-006a: unsupported whoami [10]
with the unknown whoami read from a reserved register in the shub page.
The reset register is also shadowed by the page select, preventing a
simple reset from recovering the chip.
Add a readout of the shub register page selection and deselect the page
if needed before reading whoami. This allows the driver to recover and
probe correctly.
Signed-off-by: Andreas Kempe <andreas.kempe@actia.se>
---
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 42 +++++++++++++++++++-
1 file changed, 41 insertions(+), 1 deletion(-)
diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
index 630e2cae6f19..6fef99f2e9f1 100644
--- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
+++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
@@ -1692,10 +1692,27 @@ int st_lsm6dsx_set_page(struct st_lsm6dsx_hw *hw, bool enable)
return err;
}
+static int st_lsm6dsx_get_page(struct st_lsm6dsx_hw *hw, bool *enable)
+{
+ const struct st_lsm6dsx_shub_settings *hub_settings;
+ unsigned int data;
+ int err;
+
+ hub_settings = &hw->settings->shub_settings;
+ err = regmap_read(hw->regmap, hub_settings->page_mux.addr, &data);
+ if (err < 0)
+ return err;
+
+ *enable = data & hub_settings->page_mux.mask;
+
+ return 0;
+}
+
static int st_lsm6dsx_check_whoami(struct st_lsm6dsx_hw *hw, int id,
const char **name)
{
int err, i, j, data;
+ bool enable;
for (i = 0; i < ARRAY_SIZE(st_lsm6dsx_sensor_settings); i++) {
for (j = 0; j < ST_LSM6DSX_MAX_ID; j++) {
@@ -1712,6 +1729,30 @@ static int st_lsm6dsx_check_whoami(struct st_lsm6dsx_hw *hw, int id,
return -ENODEV;
}
+ hw->settings = &st_lsm6dsx_sensor_settings[i];
+
+ if (hw->settings->shub_settings.page_mux.addr) {
+ /*
+ * whoami is not available in the shub register page.
+ * Deselect the shub page if needed so whoami can be
+ * correctly read.
+ */
+ err = st_lsm6dsx_get_page(hw, &enable);
+ if (err < 0) {
+ dev_err(hw->dev, "failed to get shub page\n");
+ return err;
+ }
+
+ if (enable) {
+ dev_warn(hw->dev, "shub page selected; clearing it\n");
+ err = st_lsm6dsx_set_page(hw, false);
+ if (err < 0) {
+ dev_err(hw->dev, "failed to clear shub page\n");
+ return err;
+ }
+ }
+ }
+
err = regmap_read(hw->regmap, ST_LSM6DSX_REG_WHOAMI_ADDR, &data);
if (err < 0) {
dev_err(hw->dev, "failed to read whoami register\n");
@@ -1724,7 +1765,6 @@ static int st_lsm6dsx_check_whoami(struct st_lsm6dsx_hw *hw, int id,
}
*name = st_lsm6dsx_sensor_settings[i].id[j].name;
- hw->settings = &st_lsm6dsx_sensor_settings[i];
return 0;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH] iio: imu: st_lsm6dsx: deselect shub page before reading whoami
2026-06-04 13:27 [PATCH] iio: imu: st_lsm6dsx: deselect shub page before reading whoami Andreas Kempe
@ 2026-06-04 14:13 ` Lorenzo Bianconi
2026-06-04 14:25 ` Andreas Kempe
0 siblings, 1 reply; 7+ messages in thread
From: Lorenzo Bianconi @ 2026-06-04 14:13 UTC (permalink / raw)
To: Andreas Kempe
Cc: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org,
John Ernberg
[-- Attachment #1: Type: text/plain, Size: 3741 bytes --]
> As part of driver initialisation, e.g. st_lsm6dsx_init_shub() selects
> the shub register page using st_lsm6dsx_set_page(). Selecting the shub
> register page shadows the regular register space so whoami, among other
> registers, is no longer accessible.
>
> In applications where the IMU is permanently powered separately from the
> processor, there is a window where a reset of the CPU leaves the IMU in
> the shub register page. Once this occurs, any subsequent probe attempt
> fails because of the register shadowing.
Hi Andreas,
can you please provide more details about how this issue can occur?
Is it enough, if the shub is available, to just always run
st_lsm6dsx_set_page(, false) before checking the whoami?
Regards,
Lorenzo
>
> Using the ism330dlc, the error typically looks like
>
> st_lsm6dsx_i2c 3-006a: unsupported whoami [10]
>
> with the unknown whoami read from a reserved register in the shub page.
>
> The reset register is also shadowed by the page select, preventing a
> simple reset from recovering the chip.
>
> Add a readout of the shub register page selection and deselect the page
> if needed before reading whoami. This allows the driver to recover and
> probe correctly.
>
> Signed-off-by: Andreas Kempe <andreas.kempe@actia.se>
> ---
> drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 42 +++++++++++++++++++-
> 1 file changed, 41 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
> index 630e2cae6f19..6fef99f2e9f1 100644
> --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
> +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
> @@ -1692,10 +1692,27 @@ int st_lsm6dsx_set_page(struct st_lsm6dsx_hw *hw, bool enable)
> return err;
> }
>
> +static int st_lsm6dsx_get_page(struct st_lsm6dsx_hw *hw, bool *enable)
> +{
> + const struct st_lsm6dsx_shub_settings *hub_settings;
> + unsigned int data;
> + int err;
> +
> + hub_settings = &hw->settings->shub_settings;
> + err = regmap_read(hw->regmap, hub_settings->page_mux.addr, &data);
> + if (err < 0)
> + return err;
> +
> + *enable = data & hub_settings->page_mux.mask;
> +
> + return 0;
> +}
> +
> static int st_lsm6dsx_check_whoami(struct st_lsm6dsx_hw *hw, int id,
> const char **name)
> {
> int err, i, j, data;
> + bool enable;
>
> for (i = 0; i < ARRAY_SIZE(st_lsm6dsx_sensor_settings); i++) {
> for (j = 0; j < ST_LSM6DSX_MAX_ID; j++) {
> @@ -1712,6 +1729,30 @@ static int st_lsm6dsx_check_whoami(struct st_lsm6dsx_hw *hw, int id,
> return -ENODEV;
> }
>
> + hw->settings = &st_lsm6dsx_sensor_settings[i];
> +
> + if (hw->settings->shub_settings.page_mux.addr) {
> + /*
> + * whoami is not available in the shub register page.
> + * Deselect the shub page if needed so whoami can be
> + * correctly read.
> + */
> + err = st_lsm6dsx_get_page(hw, &enable);
> + if (err < 0) {
> + dev_err(hw->dev, "failed to get shub page\n");
> + return err;
> + }
> +
> + if (enable) {
> + dev_warn(hw->dev, "shub page selected; clearing it\n");
> + err = st_lsm6dsx_set_page(hw, false);
> + if (err < 0) {
> + dev_err(hw->dev, "failed to clear shub page\n");
> + return err;
> + }
> + }
> + }
> +
> err = regmap_read(hw->regmap, ST_LSM6DSX_REG_WHOAMI_ADDR, &data);
> if (err < 0) {
> dev_err(hw->dev, "failed to read whoami register\n");
> @@ -1724,7 +1765,6 @@ static int st_lsm6dsx_check_whoami(struct st_lsm6dsx_hw *hw, int id,
> }
>
> *name = st_lsm6dsx_sensor_settings[i].id[j].name;
> - hw->settings = &st_lsm6dsx_sensor_settings[i];
>
> return 0;
> }
> --
> 2.53.0
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] iio: imu: st_lsm6dsx: deselect shub page before reading whoami
2026-06-04 14:13 ` Lorenzo Bianconi
@ 2026-06-04 14:25 ` Andreas Kempe
2026-06-04 14:36 ` Lorenzo Bianconi
0 siblings, 1 reply; 7+ messages in thread
From: Andreas Kempe @ 2026-06-04 14:25 UTC (permalink / raw)
To: Lorenzo Bianconi
Cc: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org,
John Ernberg
On Thu, Jun 04, 2026 at 04:13:03PM +0200, Lorenzo Bianconi wrote:
> CAUTION: This email originated from outside of the organization. Do not click links or open attachments unless you recognize the sender and know the content is safe.
>
> Date: Thu, 4 Jun 2026 16:13:03 +0200
> From: Lorenzo Bianconi <lorenzo@kernel.org>
> To: Andreas Kempe <andreas.kempe@actia.se>
> Cc: Jonathan Cameron <jic23@kernel.org>, David Lechner
> <dlechner@baylibre.com>, Nuno Sá <nuno.sa@analog.com>, Andy Shevchenko
> <andy@kernel.org>, "linux-iio@vger.kernel.org"
> <linux-iio@vger.kernel.org>, "linux-kernel@vger.kernel.org"
> <linux-kernel@vger.kernel.org>, John Ernberg <john.ernberg@actia.se>
> Subject: Re: [PATCH] iio: imu: st_lsm6dsx: deselect shub page before
> reading whoami
>
> > As part of driver initialisation, e.g. st_lsm6dsx_init_shub() selects
> > the shub register page using st_lsm6dsx_set_page(). Selecting the shub
> > register page shadows the regular register space so whoami, among other
> > registers, is no longer accessible.
> >
> > In applications where the IMU is permanently powered separately from the
> > processor, there is a window where a reset of the CPU leaves the IMU in
> > the shub register page. Once this occurs, any subsequent probe attempt
> > fails because of the register shadowing.
>
> Hi Andreas,
>
Hello Lorenzo,
> can you please provide more details about how this issue can occur?
In our specific case, we have gotten field returns that we can see are
caused by our ism330dlc being stuck with its register file switched to
the shub one. This causes the driver to permanently fail to probe.
The IMU is permanently powered because we need to use it as a wakeup
source.
We don't have definitive proof, but we think this has been caused by
either our watchdog biting or the CPU browning out while the init
sequence has the shub file selected. When Linux comes back up, the
current driver implementation can't handle it.
> Is it enough, if the shub is available, to just always run
> st_lsm6dsx_set_page(, false) before checking the whoami?
>
I think that should be fine, yes. I only added the readout to lessen
the risk of unnecessary writes to potentially unknown devices.
Best regards,
Andreas Kempe
> Regards,
> Lorenzo
>
> >
> > Using the ism330dlc, the error typically looks like
> >
> > st_lsm6dsx_i2c 3-006a: unsupported whoami [10]
> >
> > with the unknown whoami read from a reserved register in the shub page.
> >
> > The reset register is also shadowed by the page select, preventing a
> > simple reset from recovering the chip.
> >
> > Add a readout of the shub register page selection and deselect the page
> > if needed before reading whoami. This allows the driver to recover and
> > probe correctly.
> >
> > Signed-off-by: Andreas Kempe <andreas.kempe@actia.se>
> > ---
> > drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 42 +++++++++++++++++++-
> > 1 file changed, 41 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
> > index 630e2cae6f19..6fef99f2e9f1 100644
> > --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
> > +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
> > @@ -1692,10 +1692,27 @@ int st_lsm6dsx_set_page(struct st_lsm6dsx_hw *hw, bool enable)
> > return err;
> > }
> >
> > +static int st_lsm6dsx_get_page(struct st_lsm6dsx_hw *hw, bool *enable)
> > +{
> > + const struct st_lsm6dsx_shub_settings *hub_settings;
> > + unsigned int data;
> > + int err;
> > +
> > + hub_settings = &hw->settings->shub_settings;
> > + err = regmap_read(hw->regmap, hub_settings->page_mux.addr, &data);
> > + if (err < 0)
> > + return err;
> > +
> > + *enable = data & hub_settings->page_mux.mask;
> > +
> > + return 0;
> > +}
> > +
> > static int st_lsm6dsx_check_whoami(struct st_lsm6dsx_hw *hw, int id,
> > const char **name)
> > {
> > int err, i, j, data;
> > + bool enable;
> >
> > for (i = 0; i < ARRAY_SIZE(st_lsm6dsx_sensor_settings); i++) {
> > for (j = 0; j < ST_LSM6DSX_MAX_ID; j++) {
> > @@ -1712,6 +1729,30 @@ static int st_lsm6dsx_check_whoami(struct st_lsm6dsx_hw *hw, int id,
> > return -ENODEV;
> > }
> >
> > + hw->settings = &st_lsm6dsx_sensor_settings[i];
> > +
> > + if (hw->settings->shub_settings.page_mux.addr) {
> > + /*
> > + * whoami is not available in the shub register page.
> > + * Deselect the shub page if needed so whoami can be
> > + * correctly read.
> > + */
> > + err = st_lsm6dsx_get_page(hw, &enable);
> > + if (err < 0) {
> > + dev_err(hw->dev, "failed to get shub page\n");
> > + return err;
> > + }
> > +
> > + if (enable) {
> > + dev_warn(hw->dev, "shub page selected; clearing it\n");
> > + err = st_lsm6dsx_set_page(hw, false);
> > + if (err < 0) {
> > + dev_err(hw->dev, "failed to clear shub page\n");
> > + return err;
> > + }
> > + }
> > + }
> > +
> > err = regmap_read(hw->regmap, ST_LSM6DSX_REG_WHOAMI_ADDR, &data);
> > if (err < 0) {
> > dev_err(hw->dev, "failed to read whoami register\n");
> > @@ -1724,7 +1765,6 @@ static int st_lsm6dsx_check_whoami(struct st_lsm6dsx_hw *hw, int id,
> > }
> >
> > *name = st_lsm6dsx_sensor_settings[i].id[j].name;
> > - hw->settings = &st_lsm6dsx_sensor_settings[i];
> >
> > return 0;
> > }
> > --
> > 2.53.0
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] iio: imu: st_lsm6dsx: deselect shub page before reading whoami
2026-06-04 14:25 ` Andreas Kempe
@ 2026-06-04 14:36 ` Lorenzo Bianconi
2026-06-04 15:29 ` Andreas Kempe
0 siblings, 1 reply; 7+ messages in thread
From: Lorenzo Bianconi @ 2026-06-04 14:36 UTC (permalink / raw)
To: Andreas Kempe
Cc: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org,
John Ernberg
[-- Attachment #1: Type: text/plain, Size: 6072 bytes --]
> On Thu, Jun 04, 2026 at 04:13:03PM +0200, Lorenzo Bianconi wrote:
> > CAUTION: This email originated from outside of the organization. Do not click links or open attachments unless you recognize the sender and know the content is safe.
> >
>
> > Date: Thu, 4 Jun 2026 16:13:03 +0200
> > From: Lorenzo Bianconi <lorenzo@kernel.org>
> > To: Andreas Kempe <andreas.kempe@actia.se>
> > Cc: Jonathan Cameron <jic23@kernel.org>, David Lechner
> > <dlechner@baylibre.com>, Nuno Sá <nuno.sa@analog.com>, Andy Shevchenko
> > <andy@kernel.org>, "linux-iio@vger.kernel.org"
> > <linux-iio@vger.kernel.org>, "linux-kernel@vger.kernel.org"
> > <linux-kernel@vger.kernel.org>, John Ernberg <john.ernberg@actia.se>
> > Subject: Re: [PATCH] iio: imu: st_lsm6dsx: deselect shub page before
> > reading whoami
> >
> > > As part of driver initialisation, e.g. st_lsm6dsx_init_shub() selects
> > > the shub register page using st_lsm6dsx_set_page(). Selecting the shub
> > > register page shadows the regular register space so whoami, among other
> > > registers, is no longer accessible.
> > >
> > > In applications where the IMU is permanently powered separately from the
> > > processor, there is a window where a reset of the CPU leaves the IMU in
> > > the shub register page. Once this occurs, any subsequent probe attempt
> > > fails because of the register shadowing.
> >
> > Hi Andreas,
> >
>
> Hello Lorenzo,
>
> > can you please provide more details about how this issue can occur?
>
> In our specific case, we have gotten field returns that we can see are
> caused by our ism330dlc being stuck with its register file switched to
> the shub one. This causes the driver to permanently fail to probe.
>
> The IMU is permanently powered because we need to use it as a wakeup
> source.
>
> We don't have definitive proof, but we think this has been caused by
> either our watchdog biting or the CPU browning out while the init
> sequence has the shub file selected. When Linux comes back up, the
> current driver implementation can't handle it.
If we have this issue, are you sure all the other functionalities are working
properly?
>
> > Is it enough, if the shub is available, to just always run
> > st_lsm6dsx_set_page(, false) before checking the whoami?
> >
>
> I think that should be fine, yes. I only added the readout to lessen
> the risk of unnecessary writes to potentially unknown devices.
I guess you just need to check the shub is supported, then it is fine to
disable shub register access at that point (it is supposed to be that way).
Regards,
Lorenzo
>
> Best regards,
> Andreas Kempe
>
> > Regards,
> > Lorenzo
> >
> > >
> > > Using the ism330dlc, the error typically looks like
> > >
> > > st_lsm6dsx_i2c 3-006a: unsupported whoami [10]
> > >
> > > with the unknown whoami read from a reserved register in the shub page.
> > >
> > > The reset register is also shadowed by the page select, preventing a
> > > simple reset from recovering the chip.
> > >
> > > Add a readout of the shub register page selection and deselect the page
> > > if needed before reading whoami. This allows the driver to recover and
> > > probe correctly.
> > >
> > > Signed-off-by: Andreas Kempe <andreas.kempe@actia.se>
> > > ---
> > > drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 42 +++++++++++++++++++-
> > > 1 file changed, 41 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
> > > index 630e2cae6f19..6fef99f2e9f1 100644
> > > --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
> > > +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
> > > @@ -1692,10 +1692,27 @@ int st_lsm6dsx_set_page(struct st_lsm6dsx_hw *hw, bool enable)
> > > return err;
> > > }
> > >
> > > +static int st_lsm6dsx_get_page(struct st_lsm6dsx_hw *hw, bool *enable)
> > > +{
> > > + const struct st_lsm6dsx_shub_settings *hub_settings;
> > > + unsigned int data;
> > > + int err;
> > > +
> > > + hub_settings = &hw->settings->shub_settings;
> > > + err = regmap_read(hw->regmap, hub_settings->page_mux.addr, &data);
> > > + if (err < 0)
> > > + return err;
> > > +
> > > + *enable = data & hub_settings->page_mux.mask;
> > > +
> > > + return 0;
> > > +}
> > > +
> > > static int st_lsm6dsx_check_whoami(struct st_lsm6dsx_hw *hw, int id,
> > > const char **name)
> > > {
> > > int err, i, j, data;
> > > + bool enable;
> > >
> > > for (i = 0; i < ARRAY_SIZE(st_lsm6dsx_sensor_settings); i++) {
> > > for (j = 0; j < ST_LSM6DSX_MAX_ID; j++) {
> > > @@ -1712,6 +1729,30 @@ static int st_lsm6dsx_check_whoami(struct st_lsm6dsx_hw *hw, int id,
> > > return -ENODEV;
> > > }
> > >
> > > + hw->settings = &st_lsm6dsx_sensor_settings[i];
> > > +
> > > + if (hw->settings->shub_settings.page_mux.addr) {
> > > + /*
> > > + * whoami is not available in the shub register page.
> > > + * Deselect the shub page if needed so whoami can be
> > > + * correctly read.
> > > + */
> > > + err = st_lsm6dsx_get_page(hw, &enable);
> > > + if (err < 0) {
> > > + dev_err(hw->dev, "failed to get shub page\n");
> > > + return err;
> > > + }
> > > +
> > > + if (enable) {
> > > + dev_warn(hw->dev, "shub page selected; clearing it\n");
> > > + err = st_lsm6dsx_set_page(hw, false);
> > > + if (err < 0) {
> > > + dev_err(hw->dev, "failed to clear shub page\n");
> > > + return err;
> > > + }
> > > + }
> > > + }
> > > +
> > > err = regmap_read(hw->regmap, ST_LSM6DSX_REG_WHOAMI_ADDR, &data);
> > > if (err < 0) {
> > > dev_err(hw->dev, "failed to read whoami register\n");
> > > @@ -1724,7 +1765,6 @@ static int st_lsm6dsx_check_whoami(struct st_lsm6dsx_hw *hw, int id,
> > > }
> > >
> > > *name = st_lsm6dsx_sensor_settings[i].id[j].name;
> > > - hw->settings = &st_lsm6dsx_sensor_settings[i];
> > >
> > > return 0;
> > > }
> > > --
> > > 2.53.0
>
>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] iio: imu: st_lsm6dsx: deselect shub page before reading whoami
2026-06-04 14:36 ` Lorenzo Bianconi
@ 2026-06-04 15:29 ` Andreas Kempe
2026-06-04 16:14 ` David Lechner
0 siblings, 1 reply; 7+ messages in thread
From: Andreas Kempe @ 2026-06-04 15:29 UTC (permalink / raw)
To: Lorenzo Bianconi
Cc: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org,
John Ernberg
On Thu, Jun 04, 2026 at 04:36:40PM +0200, Lorenzo Bianconi wrote:
> CAUTION: This email originated from outside of the organization. Do not click links or open attachments unless you recognize the sender and know the content is safe.
>
> Date: Thu, 4 Jun 2026 16:36:40 +0200
> From: Lorenzo Bianconi <lorenzo@kernel.org>
> To: Andreas Kempe <andreas.kempe@actia.se>
> Cc: Jonathan Cameron <jic23@kernel.org>, David Lechner
> <dlechner@baylibre.com>, Nuno Sá <nuno.sa@analog.com>, Andy Shevchenko
> <andy@kernel.org>, "linux-iio@vger.kernel.org"
> <linux-iio@vger.kernel.org>, "linux-kernel@vger.kernel.org"
> <linux-kernel@vger.kernel.org>, John Ernberg <john.ernberg@actia.se>
> Subject: Re: [PATCH] iio: imu: st_lsm6dsx: deselect shub page before
> reading whoami
>
> > On Thu, Jun 04, 2026 at 04:13:03PM +0200, Lorenzo Bianconi wrote:
> > > CAUTION: This email originated from outside of the organization. Do not click links or open attachments unless you recognize the sender and know the content is safe.
> > >
> >
> > > Date: Thu, 4 Jun 2026 16:13:03 +0200
> > > From: Lorenzo Bianconi <lorenzo@kernel.org>
> > > To: Andreas Kempe <andreas.kempe@actia.se>
> > > Cc: Jonathan Cameron <jic23@kernel.org>, David Lechner
> > > <dlechner@baylibre.com>, Nuno Sá <nuno.sa@analog.com>, Andy Shevchenko
> > > <andy@kernel.org>, "linux-iio@vger.kernel.org"
> > > <linux-iio@vger.kernel.org>, "linux-kernel@vger.kernel.org"
> > > <linux-kernel@vger.kernel.org>, John Ernberg <john.ernberg@actia.se>
> > > Subject: Re: [PATCH] iio: imu: st_lsm6dsx: deselect shub page before
> > > reading whoami
> > >
> > > > As part of driver initialisation, e.g. st_lsm6dsx_init_shub() selects
> > > > the shub register page using st_lsm6dsx_set_page(). Selecting the shub
> > > > register page shadows the regular register space so whoami, among other
> > > > registers, is no longer accessible.
> > > >
> > > > In applications where the IMU is permanently powered separately from the
> > > > processor, there is a window where a reset of the CPU leaves the IMU in
> > > > the shub register page. Once this occurs, any subsequent probe attempt
> > > > fails because of the register shadowing.
> > >
> > > Hi Andreas,
> > >
> >
> > Hello Lorenzo,
> >
> > > can you please provide more details about how this issue can occur?
> >
> > In our specific case, we have gotten field returns that we can see are
> > caused by our ism330dlc being stuck with its register file switched to
> > the shub one. This causes the driver to permanently fail to probe.
> >
> > The IMU is permanently powered because we need to use it as a wakeup
> > source.
> >
> > We don't have definitive proof, but we think this has been caused by
> > either our watchdog biting or the CPU browning out while the init
> > sequence has the shub file selected. When Linux comes back up, the
> > current driver implementation can't handle it.
>
> If we have this issue, are you sure all the other functionalities are working
> properly?
>
I'm not entirely sure what you mean by other functionalities so I'm
giving you a rundown of our analysis. If you need something else/more,
please feel free to clarify.
We got a field return where the IMU was reporting whoami 10 as per the
log in the commit message of the patch. We read out a number of
registers from the IMU.
Register=value
0x01=0x80
0x0f=0x10
0x10=0x7a
0x11=0x69
0x12=0x32
0x13=0x06
0x80 in register 0x1 indicates that the shub register file is
selected. 0x0f is the whoami returning 0x10, the same value the error
log gave.
Unfortunately, we power cycled the entire system after this so we
didn't test just changing the register file. After the power cycle,
the IMU was back to full functionality as far as we can tell with the
self-test sequence from the data sheet passing and human inspection of
returned values looking correct.
If we reproduce the symptoms by unbinding the IMU from the driver and
manually select the shub using i2cset, we get an identical readout
from the chip and behaviour of the driver as when the chip was in the
fault condition. With my patch, the driver recovers and everything
goes back to normal.
I apologise that I can't test my patch on a real malfunctioning board
as they, luckily, are few and far between.
> >
> > > Is it enough, if the shub is available, to just always run
> > > st_lsm6dsx_set_page(, false) before checking the whoami?
> > >
> >
> > I think that should be fine, yes. I only added the readout to lessen
> > the risk of unnecessary writes to potentially unknown devices.
>
> I guess you just need to check the shub is supported, then it is fine to
> disable shub register access at that point (it is supposed to be that way).
>
You are thinking of gating st_lsm6dsx_set_page() on
shub_settings.page_mux.addr like I do, but without the read? Or do you
want to gate on something else?
I'm willing to submit a v2 if you want it.
Best regards,
Andreas Kempe
> > >
> > > >
> > > > Using the ism330dlc, the error typically looks like
> > > >
> > > > st_lsm6dsx_i2c 3-006a: unsupported whoami [10]
> > > >
> > > > with the unknown whoami read from a reserved register in the shub page.
> > > >
> > > > The reset register is also shadowed by the page select, preventing a
> > > > simple reset from recovering the chip.
> > > >
> > > > Add a readout of the shub register page selection and deselect the page
> > > > if needed before reading whoami. This allows the driver to recover and
> > > > probe correctly.
> > > >
> > > > Signed-off-by: Andreas Kempe <andreas.kempe@actia.se>
> > > > ---
> > > > drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 42 +++++++++++++++++++-
> > > > 1 file changed, 41 insertions(+), 1 deletion(-)
> > > >
> > > > diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
> > > > index 630e2cae6f19..6fef99f2e9f1 100644
> > > > --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
> > > > +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
> > > > @@ -1692,10 +1692,27 @@ int st_lsm6dsx_set_page(struct st_lsm6dsx_hw *hw, bool enable)
> > > > return err;
> > > > }
> > > >
> > > > +static int st_lsm6dsx_get_page(struct st_lsm6dsx_hw *hw, bool *enable)
> > > > +{
> > > > + const struct st_lsm6dsx_shub_settings *hub_settings;
> > > > + unsigned int data;
> > > > + int err;
> > > > +
> > > > + hub_settings = &hw->settings->shub_settings;
> > > > + err = regmap_read(hw->regmap, hub_settings->page_mux.addr, &data);
> > > > + if (err < 0)
> > > > + return err;
> > > > +
> > > > + *enable = data & hub_settings->page_mux.mask;
> > > > +
> > > > + return 0;
> > > > +}
> > > > +
> > > > static int st_lsm6dsx_check_whoami(struct st_lsm6dsx_hw *hw, int id,
> > > > const char **name)
> > > > {
> > > > int err, i, j, data;
> > > > + bool enable;
> > > >
> > > > for (i = 0; i < ARRAY_SIZE(st_lsm6dsx_sensor_settings); i++) {
> > > > for (j = 0; j < ST_LSM6DSX_MAX_ID; j++) {
> > > > @@ -1712,6 +1729,30 @@ static int st_lsm6dsx_check_whoami(struct st_lsm6dsx_hw *hw, int id,
> > > > return -ENODEV;
> > > > }
> > > >
> > > > + hw->settings = &st_lsm6dsx_sensor_settings[i];
> > > > +
> > > > + if (hw->settings->shub_settings.page_mux.addr) {
> > > > + /*
> > > > + * whoami is not available in the shub register page.
> > > > + * Deselect the shub page if needed so whoami can be
> > > > + * correctly read.
> > > > + */
> > > > + err = st_lsm6dsx_get_page(hw, &enable);
> > > > + if (err < 0) {
> > > > + dev_err(hw->dev, "failed to get shub page\n");
> > > > + return err;
> > > > + }
> > > > +
> > > > + if (enable) {
> > > > + dev_warn(hw->dev, "shub page selected; clearing it\n");
> > > > + err = st_lsm6dsx_set_page(hw, false);
> > > > + if (err < 0) {
> > > > + dev_err(hw->dev, "failed to clear shub page\n");
> > > > + return err;
> > > > + }
> > > > + }
> > > > + }
> > > > +
> > > > err = regmap_read(hw->regmap, ST_LSM6DSX_REG_WHOAMI_ADDR, &data);
> > > > if (err < 0) {
> > > > dev_err(hw->dev, "failed to read whoami register\n");
> > > > @@ -1724,7 +1765,6 @@ static int st_lsm6dsx_check_whoami(struct st_lsm6dsx_hw *hw, int id,
> > > > }
> > > >
> > > > *name = st_lsm6dsx_sensor_settings[i].id[j].name;
> > > > - hw->settings = &st_lsm6dsx_sensor_settings[i];
> > > >
> > > > return 0;
> > > > }
> > > > --
> > > > 2.53.0
> >
> >
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] iio: imu: st_lsm6dsx: deselect shub page before reading whoami
2026-06-04 15:29 ` Andreas Kempe
@ 2026-06-04 16:14 ` David Lechner
2026-06-04 16:23 ` Andreas Kempe
0 siblings, 1 reply; 7+ messages in thread
From: David Lechner @ 2026-06-04 16:14 UTC (permalink / raw)
To: Andreas Kempe
Cc: Lorenzo Bianconi, Jonathan Cameron, Nuno Sá, Andy Shevchenko,
linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org,
John Ernberg
On Thu, Jun 4, 2026 at 5:29 PM Andreas Kempe <andreas.kempe@actia.se> wrote:
>
> On Thu, Jun 04, 2026 at 04:36:40PM +0200, Lorenzo Bianconi wrote:
> > CAUTION: This email originated from outside of the organization. Do not click links or open attachments unless you recognize the sender and know the content is safe.
> >
> > >
> > > > Is it enough, if the shub is available, to just always run
> > > > st_lsm6dsx_set_page(, false) before checking the whoami?
> > > >
> > >
> > > I think that should be fine, yes. I only added the readout to lessen
> > > the risk of unnecessary writes to potentially unknown devices.
> >
> > I guess you just need to check the shub is supported, then it is fine to
> > disable shub register access at that point (it is supposed to be that way).
> >
>
> You are thinking of gating st_lsm6dsx_set_page() on
> shub_settings.page_mux.addr like I do, but without the read? Or do you
> want to gate on something else?
How about setting the SW_RESET bit in the CTRL3_C register during
probe too to ensure the rest of the registers are in a known state?
>
> I'm willing to submit a v2 if you want it.
>
>
> Best regards,
> Andreas Kempe
>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] iio: imu: st_lsm6dsx: deselect shub page before reading whoami
2026-06-04 16:14 ` David Lechner
@ 2026-06-04 16:23 ` Andreas Kempe
0 siblings, 0 replies; 7+ messages in thread
From: Andreas Kempe @ 2026-06-04 16:23 UTC (permalink / raw)
To: David Lechner
Cc: Lorenzo Bianconi, Jonathan Cameron, Nuno Sá, Andy Shevchenko,
linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org,
John Ernberg
On Thu, Jun 04, 2026 at 06:14:11PM +0200, David Lechner wrote:
> On Thu, Jun 4, 2026 at 5:29 PM Andreas Kempe <andreas.kempe@actia.se> wrote:
> >
> > On Thu, Jun 04, 2026 at 04:36:40PM +0200, Lorenzo Bianconi wrote:
> > > CAUTION: This email originated from outside of the organization. Do not click links or open attachments unless you recognize the sender and know the content is safe.
> > >
> > > >
> > > > > Is it enough, if the shub is available, to just always run
> > > > > st_lsm6dsx_set_page(, false) before checking the whoami?
> > > > >
> > > >
> > > > I think that should be fine, yes. I only added the readout to lessen
> > > > the risk of unnecessary writes to potentially unknown devices.
> > >
> > > I guess you just need to check the shub is supported, then it is fine to
> > > disable shub register access at that point (it is supposed to be that way).
> > >
> >
> > You are thinking of gating st_lsm6dsx_set_page() on
> > shub_settings.page_mux.addr like I do, but without the read? Or do you
> > want to gate on something else?
>
> How about setting the SW_RESET bit in the CTRL3_C register during
> probe too to ensure the rest of the registers are in a known state?
>
While the shub register file is selected, the reset register is
shadowed so it can't be written without first selecting the normal
register file. A reset is already called from probe in
st_lsm6dsx_init_device() after the whoami check has passed.
> >
> > I'm willing to submit a v2 if you want it.
> >
> >
> > Best regards,
> > Andreas Kempe
> >
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-06-04 16:23 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-04 13:27 [PATCH] iio: imu: st_lsm6dsx: deselect shub page before reading whoami Andreas Kempe
2026-06-04 14:13 ` Lorenzo Bianconi
2026-06-04 14:25 ` Andreas Kempe
2026-06-04 14:36 ` Lorenzo Bianconi
2026-06-04 15:29 ` Andreas Kempe
2026-06-04 16:14 ` David Lechner
2026-06-04 16:23 ` Andreas Kempe
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.