i2c: designware: ratelimit ‘transfer when suspended’ errors [Linux 5.1]

i2c: designware: ratelimit ‘transfer when suspended’ errors [Linux 5.1]

This Linux kernel change "i2c: designware: ratelimit ‘transfer when suspended’ errors" is included in the Linux 5.1 release. This change is authored by Wolfram Sang <wsa+renesas [at] sang-engineering.com> on Wed Apr 24 18:16:32 2019 +0200. The commit for this change in Linux stable tree is 6bac9bc (patch).

i2c: designware: ratelimit 'transfer when suspended' errors

There are two problems with dev_err() here. One: It is not ratelimited.
Two: We don't see which driver tried to transfer something with a
suspended adapter. Switch to dev_WARN_ONCE to fix both issues. Drawback
is that we don't see if multiple drivers are trying to transfer while
suspended. They need to be discovered one after the other now. This is
better than a high CPU load because a really broken driver might try to
resend endlessly.

Link: https://bugs.archlinux.org/task/62391
Fixes: 275154155538 ("i2c: designware: Do not allow i2c_dw_xfer() calls while suspended")
Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Reported-by: skidnik <skidnik@gmail.com>
Acked-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Tested-by: skidnik <skidnik@gmail.com>
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>

There are 3 lines of Linux source code added/deleted in this change. Code changes to Linux kernel are as follows.

 drivers/i2c/busses/i2c-designware-master.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/i2c/busses/i2c-designware-master.c b/drivers/i2c/busses/i2c-designware-master.c
index bb8e3f1..d464799 100644
--- a/drivers/i2c/busses/i2c-designware-master.c
+++ b/drivers/i2c/busses/i2c-designware-master.c
@@ -426,8 +426,7 @@ static void i2c_dw_xfer_init(struct dw_i2c_dev *dev)

    pm_runtime_get_sync(dev->dev);

-   if (dev->suspended) {
-       dev_err(dev->dev, "Error %s call while suspended\n", __func__);
+   if (dev_WARN_ONCE(dev->dev, dev->suspended, "Transfer while suspended\n")) {
        ret = -ESHUTDOWN;
        goto done_nolock;
    }

Leave a Reply

Your email address will not be published. Required fields are marked *