[PATCH linux dev-5.10 33/35] pmbus: (core) Add a one-shot retry in pmbus_set_page()

Joel Stanley joel at jms.id.au
Fri Mar 12 11:35:57 AEDT 2021


On Mon, 8 Mar 2021 at 22:56, Eddie James <eajames at linux.ibm.com> wrote:
>
> From: Andrew Jeffery <andrew at aj.id.au>
>
> From extensive testing and tracing it was discovered that the MAX31785
> occasionally fails to switch pages despite ACK'ing the PAGE PMBus data
> write. I suspect this behaviour had been seen on other devices as well,
> as pmbus_set_page() already read-back the freshly set value and errored
> out if it wasn't what we requested.
>
> In the case of the MAX31785 it was shown that a one-shot retry was
> enough to get the PAGE write to stick if the inital command failed. To
> improve robustness, only error out if the one-shot retry also fails to
> stick.
>
> OpenBMC-Staging-Count: 1
> Signed-off-by: Andrew Jeffery <andrew at aj.id.au>
> Signed-off-by: Joel Stanley <joel at jms.id.au>

Andrew, please review the pmbus related changes and let me know how
you would like to proceed.

> ---
>  drivers/hwmon/pmbus/pmbus_core.c | 31 ++++++++++++++++++++-----------
>  1 file changed, 20 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c
> index 44c1a0a07509..dd4a09d18730 100644
> --- a/drivers/hwmon/pmbus/pmbus_core.c
> +++ b/drivers/hwmon/pmbus/pmbus_core.c
> @@ -151,25 +151,34 @@ int pmbus_set_page(struct i2c_client *client, int page, int phase)
>
>         if (!(data->info->func[page] & PMBUS_PAGE_VIRTUAL) &&
>             data->info->pages > 1 && page != data->currpage) {
> +               int i;
> +
>                 dev_dbg(&client->dev, "Want page %u, %u cached\n", page,
>                         data->currpage);
>
> -               rv = i2c_smbus_write_byte_data(client, PMBUS_PAGE, page);
> -               if (rv < 0) {
> +               for (i = 0; i < 2; i++) {
>                         rv = i2c_smbus_write_byte_data(client, PMBUS_PAGE,
>                                                        page);
> -                       dev_dbg(&client->dev,
> -                               "Failed to set page %u, performed one-shot retry %s: %d\n",
> -                               page, rv ? "and failed" : "with success", rv);
> +                       if (rv)
> +                               continue;
> +
> +                       rv = i2c_smbus_read_byte_data(client, PMBUS_PAGE);
>                         if (rv < 0)
> -                               return rv;
> -               }
> +                               continue;
>
> -               rv = i2c_smbus_read_byte_data(client, PMBUS_PAGE);
> -               if (rv < 0)
> -                       return rv;
> +                       /* Success, exit loop */
> +                       if (rv == page)
> +                               break;
> +
> +                       rv = i2c_smbus_read_byte_data(client, PMBUS_STATUS_CML);
> +                       if (rv < 0)
> +                               continue;
> +
> +                       if (rv & PB_CML_FAULT_INVALID_DATA)
> +                               return -EIO;
> +               }
>
> -               if (rv != page)
> +               if (i == 2)
>                         return -EIO;
>         }
>         data->currpage = page;
> --
> 2.27.0
>


More information about the openbmc mailing list