From: Guenter Roeck <linux@roeck-us.net>
To: Wolfram Sang <wsa@kernel.org>
Cc: Jean Delvare <khali@linux-fr.org>,
linux-i2c@vger.kernel.org, linux-kernel@vger.kernel.org,
Guenter Roeck <linux@roeck-us.net>
Subject: [PATCH 2/2] i2c: smbus: Send alert notifications to all devices if source not found
Date: Mon, 10 Jan 2022 09:28:57 -0800 [thread overview]
Message-ID: <20220110172857.2980523-3-linux@roeck-us.net> (raw)
In-Reply-To: <20220110172857.2980523-1-linux@roeck-us.net>
If a SMBUs alert is received and the originating device is not found,
the reason may be that the address reported on the SMBus alert address
is corrupted, for example because multiple devices asserted alert and
do not correctly implement SMBus arbitration.
If this happens, call alert handlers on all devices connected to the
given I2C bus, in the hope that this cleans up the situation. Retry
twice before giving up.
This change reliably fixed the problem on a system with multiple devices
on a single bus. Example log where the device on address 0x18 (ADM1021)
and on address 0x4c (ADM7461A) both had the alert line asserted:
smbus_alert 3-000c: SMBALERT# from dev 0x0c, flag 0
smbus_alert 3-000c: no driver alert()!
smbus_alert 3-000c: SMBALERT# from dev 0x0c, flag 0
smbus_alert 3-000c: no driver alert()!
lm90 3-0018: temp1 out of range, please check!
lm90 3-0018: Disabling ALERT#
lm90 3-0029: Everything OK
lm90 3-002a: Everything OK
lm90 3-004c: temp1 out of range, please check!
lm90 3-004c: temp2 out of range, please check!
lm90 3-004c: Disabling ALERT#
Fixes: b5527a7766f0 ("i2c: Add SMBus alert support")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/i2c/i2c-smbus.c | 38 ++++++++++++++++++++++++++++++++++++--
1 file changed, 36 insertions(+), 2 deletions(-)
diff --git a/drivers/i2c/i2c-smbus.c b/drivers/i2c/i2c-smbus.c
index 533c885b99ac..f48cec19db41 100644
--- a/drivers/i2c/i2c-smbus.c
+++ b/drivers/i2c/i2c-smbus.c
@@ -65,6 +65,32 @@ static int smbus_do_alert(struct device *dev, void *addrp)
return ret;
}
+/* Same as above, but call back all drivers with alert handler */
+
+static int smbus_do_alert_force(struct device *dev, void *addrp)
+{
+ struct i2c_client *client = i2c_verify_client(dev);
+ struct alert_data *data = addrp;
+ struct i2c_driver *driver;
+
+ if (!client || (client->flags & I2C_CLIENT_TEN))
+ return 0;
+
+ /*
+ * Drivers should either disable alerts, or provide at least
+ * a minimal handler. Lock so the driver won't change.
+ */
+ device_lock(dev);
+ if (client->dev.driver) {
+ driver = to_i2c_driver(client->dev.driver);
+ if (driver->alert)
+ driver->alert(client, data->type, data->data);
+ }
+ device_unlock(dev);
+
+ return 0;
+}
+
/*
* The alert IRQ handler needs to hand work off to a task which can issue
* SMBus calls, because those sleeping calls can't be made in IRQ context.
@@ -74,6 +100,7 @@ static irqreturn_t smbus_alert(int irq, void *d)
struct i2c_smbus_alert *alert = d;
struct i2c_client *ara;
unsigned short prev_addr = 0; /* Not a valid address */
+ int retries = 0;
ara = alert->ara;
@@ -111,8 +138,15 @@ static irqreturn_t smbus_alert(int irq, void *d)
* Note: This assumes that a driver with alert handler handles
* the alert properly and clears it if necessary.
*/
- if (data.addr == prev_addr && status != -EBUSY)
- break;
+ if (data.addr == prev_addr && status != -EBUSY) {
+ /* retry once */
+ if (retries++)
+ break;
+ device_for_each_child(&ara->adapter->dev, &data,
+ smbus_do_alert_force);
+ } else {
+ retries = 0;
+ }
prev_addr = data.addr;
}
--
2.33.0
next prev parent reply other threads:[~2022-01-10 17:29 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-01-10 17:28 [PATCH 0/2] i2c: smbus: Handle stuck alerts Guenter Roeck
2022-01-10 17:28 ` [PATCH 1/2] i2c: smbus: Improve handling of " Guenter Roeck
2024-07-28 20:01 ` Wolfram Sang
2024-07-29 7:49 ` Wolfram Sang
2022-01-10 17:28 ` Guenter Roeck [this message]
2024-07-28 20:04 ` [PATCH 2/2] i2c: smbus: Send alert notifications to all devices if source not found Wolfram Sang
2024-07-29 0:31 ` Guenter Roeck
2024-07-29 7:57 ` Wolfram Sang
2024-07-29 14:23 ` Guenter Roeck
2024-07-29 18:36 ` Wolfram Sang
2024-07-29 18:44 ` Guenter Roeck
2024-07-29 20:52 ` Wolfram Sang
2024-07-29 21:39 ` Guenter Roeck
2024-06-12 17:49 ` [PATCH 0/2] i2c: smbus: Handle stuck alerts Guenter Roeck
2024-06-12 20:21 ` Wolfram Sang
2024-06-12 20:29 ` Guenter Roeck
2024-07-28 19:59 ` Wolfram Sang
2024-07-29 0:31 ` Guenter Roeck
2024-07-29 8:04 ` Wolfram Sang
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220110172857.2980523-3-linux@roeck-us.net \
--to=linux@roeck-us.net \
--cc=khali@linux-fr.org \
--cc=linux-i2c@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=wsa@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).