Commit 4db61c2a authored by Wolfram Sang's avatar Wolfram Sang Committed by Wolfram Sang

i2c: core: ratelimit 'transfer when suspended' errors

There are two problems with WARN_ON() here. One: It is not ratelimited.
Two: We don't see which adapter was used when trying to transfer
something when already suspended. Implement a custom ratelimit once per
adapter and use dev_WARN there. This fixes both issues. Drawback is that
we don't see if multiple drivers are trying to transfer with the same
adapter 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.

Fixes: 9ac6cb5f ("i2c: add suspended flag and accessors for i2c adapters")
Signed-off-by: default avatarWolfram Sang <wsa+renesas@sang-engineering.com>
Reviewed-by: default avatarSimon Horman <horms+renesas@verge.net.au>
Signed-off-by: default avatarWolfram Sang <wsa@the-dreams.de>
Cc: stable@vger.kernel.org # v5.1+
parent d00afd5e
...@@ -1867,8 +1867,11 @@ int __i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) ...@@ -1867,8 +1867,11 @@ int __i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
if (WARN_ON(!msgs || num < 1)) if (WARN_ON(!msgs || num < 1))
return -EINVAL; return -EINVAL;
if (WARN_ON(test_bit(I2C_ALF_IS_SUSPENDED, &adap->locked_flags))) if (test_bit(I2C_ALF_IS_SUSPENDED, &adap->locked_flags)) {
if (!test_and_set_bit(I2C_ALF_SUSPEND_REPORTED, &adap->locked_flags))
dev_WARN(&adap->dev, "Transfer while suspended\n");
return -ESHUTDOWN; return -ESHUTDOWN;
}
if (adap->quirks && i2c_check_for_quirks(adap, msgs, num)) if (adap->quirks && i2c_check_for_quirks(adap, msgs, num))
return -EOPNOTSUPP; return -EOPNOTSUPP;
......
...@@ -694,7 +694,8 @@ struct i2c_adapter { ...@@ -694,7 +694,8 @@ struct i2c_adapter {
int retries; int retries;
struct device dev; /* the adapter device */ struct device dev; /* the adapter device */
unsigned long locked_flags; /* owned by the I2C core */ unsigned long locked_flags; /* owned by the I2C core */
#define I2C_ALF_IS_SUSPENDED 0 #define I2C_ALF_IS_SUSPENDED 0
#define I2C_ALF_SUSPEND_REPORTED 1
int nr; int nr;
char name[48]; char name[48];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment